1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include "linker_mapped_file_fragment.h" 30 #include "linker_debug.h" 31 #include "linker_utils.h" 32 33 #include <inttypes.h> 34 #include <stdlib.h> 35 #include <sys/mman.h> 36 #include <unistd.h> 37 38 MappedFileFragment::MappedFileFragment() : map_start_(nullptr), map_size_(0), 39 data_(nullptr), size_ (0) 40 { } 41 42 MappedFileFragment::~MappedFileFragment() { 43 if (map_start_ != nullptr) { 44 munmap(map_start_, map_size_); 45 } 46 } 47 48 bool MappedFileFragment::Map(int fd, off64_t base_offset, size_t elf_offset, size_t size) { 49 off64_t offset; 50 CHECK(safe_add(&offset, base_offset, elf_offset)); 51 52 off64_t page_min = page_start(offset); 53 off64_t end_offset; 54 55 CHECK(safe_add(&end_offset, offset, size)); 56 CHECK(safe_add(&end_offset, end_offset, page_offset(offset))); 57 58 size_t map_size = static_cast<size_t>(end_offset - page_min); 59 CHECK(map_size >= size); 60 61 uint8_t* map_start = static_cast<uint8_t*>( 62 mmap64(nullptr, map_size, PROT_READ, MAP_PRIVATE, fd, page_min)); 63 64 if (map_start == MAP_FAILED) { 65 return false; 66 } 67 68 map_start_ = map_start; 69 map_size_ = map_size; 70 71 data_ = map_start + page_offset(offset); 72 size_ = size; 73 74 return true; 75 } 76