2 * Copyright (C) 2012 The Android Open Source Project
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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
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
29 #include "linker_phdr.h"
34 #include <sys/types.h>
39 #include "linker_dlwarning.h"
40 #include "linker_globals.h"
41 #include "linker_debug.h"
42 #include "linker_utils.h"
44 #include "private/bionic_prctl.h"
45 #include "private/CFIShadow.h" // For kLibraryAlignment
47 static int GetTargetElfMachine() {
50 #elif defined(__aarch64__)
52 #elif defined(__i386__)
54 #elif defined(__mips__)
56 #elif defined(__x86_64__)
62 TECHNICAL NOTE ON ELF LOADING.
64 An ELF file's program header table contains one or more PT_LOAD
65 segments, which corresponds to portions of the file that need to
66 be mapped into the process' address space.
68 Each loadable segment has the following important properties:
70 p_offset -> segment file offset
71 p_filesz -> segment file size
72 p_memsz -> segment memory size (always >= p_filesz)
73 p_vaddr -> segment's virtual address
74 p_flags -> segment flags (e.g. readable, writable, executable)
76 We will ignore the p_paddr and p_align fields of ElfW(Phdr) for now.
78 The loadable segments can be seen as a list of [p_vaddr ... p_vaddr+p_memsz)
79 ranges of virtual addresses. A few rules apply:
81 - the virtual address ranges should not overlap.
83 - if a segment's p_filesz is smaller than its p_memsz, the extra bytes
84 between them should always be initialized to 0.
86 - ranges do not necessarily start or end at page boundaries. Two distinct
87 segments can have their start and end on the same page. In this case, the
88 page inherits the mapping flags of the latter segment.
90 Finally, the real load addrs of each segment is not p_vaddr. Instead the
91 loader decides where to load the first segment, then will load all others
92 relative to the first one to respect the initial range layout.
94 For example, consider the following list:
96 [ offset:0, filesz:0x4000, memsz:0x4000, vaddr:0x30000 ],
97 [ offset:0x4000, filesz:0x2000, memsz:0x8000, vaddr:0x40000 ],
99 This corresponds to two segments that cover these virtual address ranges:
104 If the loader decides to load the first segment at address 0xa0000000
105 then the segments' load address ranges will be:
107 0xa0030000...0xa0034000
108 0xa0040000...0xa0048000
110 In other words, all segments must be loaded at an address that has the same
111 constant offset from their p_vaddr value. This offset is computed as the
112 difference between the first segment's load address, and its p_vaddr value.
114 However, in practice, segments do _not_ start at page boundaries. Since we
115 can only memory-map at page boundaries, this means that the bias is
118 load_bias = phdr0_load_address - PAGE_START(phdr0->p_vaddr)
120 (NOTE: The value must be used as a 32-bit unsigned integer, to deal with
121 possible wrap around UINT32_MAX for possible large p_vaddr values).
123 And that the phdr0_load_address must start at a page boundary, with
124 the segment's real content starting at:
126 phdr0_load_address + PAGE_OFFSET(phdr0->p_vaddr)
128 Note that ELF requires the following condition to make the mmap()-ing work:
130 PAGE_OFFSET(phdr0->p_vaddr) == PAGE_OFFSET(phdr0->p_offset)
132 The load_bias must be added to any p_vaddr value read from the ELF file to
133 determine the corresponding memory address.
137 #define MAYBE_MAP_FLAG(x, from, to) (((x) & (from)) ? (to) : 0)
138 #define PFLAGS_TO_PROT(x) (MAYBE_MAP_FLAG((x), PF_X, PROT_EXEC) | \
139 MAYBE_MAP_FLAG((x), PF_R, PROT_READ) | \
140 MAYBE_MAP_FLAG((x), PF_W, PROT_WRITE))
142 ElfReader::ElfReader()
143 : did_read_(false), did_load_(false), fd_(-1), file_offset_(0), file_size_(0), phdr_num_(0),
144 phdr_table_(nullptr), shdr_table_(nullptr), shdr_num_(0), dynamic_(nullptr), strtab_(nullptr),
145 strtab_size_(0), load_start_(nullptr), load_size_(0), load_bias_(0), loaded_phdr_(nullptr),
146 mapped_by_caller_(false) {
149 bool ElfReader::Read(const char* name, int fd, off64_t file_offset, off64_t file_size) {
154 file_offset_ = file_offset;
155 file_size_ = file_size;
157 if (ReadElfHeader() &&
159 ReadProgramHeaders() &&
160 ReadSectionHeaders() &&
161 ReadDynamicSection()) {
168 bool ElfReader::Load(const android_dlextinfo* extinfo) {
171 if (ReserveAddressSpace(extinfo) &&
180 const char* ElfReader::get_string(ElfW(Word) index) const {
181 CHECK(strtab_ != nullptr);
182 CHECK(index < strtab_size_);
184 return strtab_ + index;
187 bool ElfReader::ReadElfHeader() {
188 ssize_t rc = TEMP_FAILURE_RETRY(pread64(fd_, &header_, sizeof(header_), file_offset_));
190 DL_ERR("can't read file \"%s\": %s", name_.c_str(), strerror(errno));
194 if (rc != sizeof(header_)) {
195 DL_ERR("\"%s\" is too small to be an ELF executable: only found %zd bytes", name_.c_str(),
196 static_cast<size_t>(rc));
202 static const char* EM_to_string(int em) {
203 if (em == EM_386) return "EM_386";
204 if (em == EM_AARCH64) return "EM_AARCH64";
205 if (em == EM_ARM) return "EM_ARM";
206 if (em == EM_MIPS) return "EM_MIPS";
207 if (em == EM_X86_64) return "EM_X86_64";
211 bool ElfReader::VerifyElfHeader() {
212 if (memcmp(header_.e_ident, ELFMAG, SELFMAG) != 0) {
213 DL_ERR("\"%s\" has bad ELF magic", name_.c_str());
217 // Try to give a clear diagnostic for ELF class mismatches, since they're
218 // an easy mistake to make during the 32-bit/64-bit transition period.
219 int elf_class = header_.e_ident[EI_CLASS];
220 #if defined(__LP64__)
221 if (elf_class != ELFCLASS64) {
222 if (elf_class == ELFCLASS32) {
223 DL_ERR("\"%s\" is 32-bit instead of 64-bit", name_.c_str());
225 DL_ERR("\"%s\" has unknown ELF class: %d", name_.c_str(), elf_class);
230 if (elf_class != ELFCLASS32) {
231 if (elf_class == ELFCLASS64) {
232 DL_ERR("\"%s\" is 64-bit instead of 32-bit", name_.c_str());
234 DL_ERR("\"%s\" has unknown ELF class: %d", name_.c_str(), elf_class);
240 if (header_.e_ident[EI_DATA] != ELFDATA2LSB) {
241 DL_ERR("\"%s\" not little-endian: %d", name_.c_str(), header_.e_ident[EI_DATA]);
245 if (header_.e_type != ET_DYN) {
246 DL_ERR("\"%s\" has unexpected e_type: %d", name_.c_str(), header_.e_type);
250 if (header_.e_version != EV_CURRENT) {
251 DL_ERR("\"%s\" has unexpected e_version: %d", name_.c_str(), header_.e_version);
255 if (header_.e_machine != GetTargetElfMachine()) {
256 DL_ERR("\"%s\" has unexpected e_machine: %d (%s)", name_.c_str(), header_.e_machine,
257 EM_to_string(header_.e_machine));
261 if (header_.e_shentsize != sizeof(ElfW(Shdr))) {
262 // Fail if app is targeting Android O or above
263 if (get_application_target_sdk_version() >= __ANDROID_API_O__) {
264 DL_ERR_AND_LOG("\"%s\" has unsupported e_shentsize: 0x%x (expected 0x%zx)",
265 name_.c_str(), header_.e_shentsize, sizeof(ElfW(Shdr)));
268 DL_WARN("\"%s\" has unsupported e_shentsize: 0x%x (expected 0x%zx)",
269 name_.c_str(), header_.e_shentsize, sizeof(ElfW(Shdr)));
270 add_dlwarning(name_.c_str(), "has invalid ELF header");
273 if (header_.e_shstrndx == 0) {
274 // Fail if app is targeting Android O or above
275 if (get_application_target_sdk_version() >= __ANDROID_API_O__) {
276 DL_ERR_AND_LOG("\"%s\" has invalid e_shstrndx", name_.c_str());
280 DL_WARN("\"%s\" has invalid e_shstrndx", name_.c_str());
281 add_dlwarning(name_.c_str(), "has invalid ELF header");
287 bool ElfReader::CheckFileRange(ElfW(Addr) offset, size_t size, size_t alignment) {
291 // Only header can be located at the 0 offset... This function called to
292 // check DYNSYM and DYNAMIC sections and phdr/shdr - none of them can be
296 safe_add(&range_start, file_offset_, offset) &&
297 safe_add(&range_end, range_start, size) &&
298 (range_start < file_size_) &&
299 (range_end <= file_size_) &&
300 ((offset % alignment) == 0);
303 // Loads the program header table from an ELF file into a read-only private
304 // anonymous mmap-ed block.
305 bool ElfReader::ReadProgramHeaders() {
306 phdr_num_ = header_.e_phnum;
308 // Like the kernel, we only accept program header tables that
309 // are smaller than 64KiB.
310 if (phdr_num_ < 1 || phdr_num_ > 65536/sizeof(ElfW(Phdr))) {
311 DL_ERR("\"%s\" has invalid e_phnum: %zd", name_.c_str(), phdr_num_);
316 size_t size = phdr_num_ * sizeof(ElfW(Phdr));
317 if (!CheckFileRange(header_.e_phoff, size, alignof(ElfW(Phdr)))) {
318 DL_ERR_AND_LOG("\"%s\" has invalid phdr offset/size: %zu/%zu",
320 static_cast<size_t>(header_.e_phoff),
325 if (!phdr_fragment_.Map(fd_, file_offset_, header_.e_phoff, size)) {
326 DL_ERR("\"%s\" phdr mmap failed: %s", name_.c_str(), strerror(errno));
330 phdr_table_ = static_cast<ElfW(Phdr)*>(phdr_fragment_.data());
334 bool ElfReader::ReadSectionHeaders() {
335 shdr_num_ = header_.e_shnum;
337 if (shdr_num_ == 0) {
338 DL_ERR_AND_LOG("\"%s\" has no section headers", name_.c_str());
342 size_t size = shdr_num_ * sizeof(ElfW(Shdr));
343 if (!CheckFileRange(header_.e_shoff, size, alignof(const ElfW(Shdr)))) {
344 DL_ERR_AND_LOG("\"%s\" has invalid shdr offset/size: %zu/%zu",
346 static_cast<size_t>(header_.e_shoff),
351 if (!shdr_fragment_.Map(fd_, file_offset_, header_.e_shoff, size)) {
352 DL_ERR("\"%s\" shdr mmap failed: %s", name_.c_str(), strerror(errno));
356 shdr_table_ = static_cast<const ElfW(Shdr)*>(shdr_fragment_.data());
360 bool ElfReader::ReadDynamicSection() {
361 // 1. Find .dynamic section (in section headers)
362 const ElfW(Shdr)* dynamic_shdr = nullptr;
363 for (size_t i = 0; i < shdr_num_; ++i) {
364 if (shdr_table_[i].sh_type == SHT_DYNAMIC) {
365 dynamic_shdr = &shdr_table_ [i];
370 if (dynamic_shdr == nullptr) {
371 DL_ERR_AND_LOG("\"%s\" .dynamic section header was not found", name_.c_str());
375 // Make sure dynamic_shdr offset and size matches PT_DYNAMIC phdr
376 size_t pt_dynamic_offset = 0;
377 size_t pt_dynamic_filesz = 0;
378 for (size_t i = 0; i < phdr_num_; ++i) {
379 const ElfW(Phdr)* phdr = &phdr_table_[i];
380 if (phdr->p_type == PT_DYNAMIC) {
381 pt_dynamic_offset = phdr->p_offset;
382 pt_dynamic_filesz = phdr->p_filesz;
386 if (pt_dynamic_offset != dynamic_shdr->sh_offset) {
387 if (get_application_target_sdk_version() >= __ANDROID_API_O__) {
388 DL_ERR_AND_LOG("\"%s\" .dynamic section has invalid offset: 0x%zx, "
389 "expected to match PT_DYNAMIC offset: 0x%zx",
391 static_cast<size_t>(dynamic_shdr->sh_offset),
395 DL_WARN("\"%s\" .dynamic section has invalid offset: 0x%zx, "
396 "expected to match PT_DYNAMIC offset: 0x%zx",
398 static_cast<size_t>(dynamic_shdr->sh_offset),
400 add_dlwarning(name_.c_str(), "invalid .dynamic section");
403 if (pt_dynamic_filesz != dynamic_shdr->sh_size) {
404 if (get_application_target_sdk_version() >= __ANDROID_API_O__) {
405 DL_ERR_AND_LOG("\"%s\" .dynamic section has invalid size: 0x%zx, "
406 "expected to match PT_DYNAMIC filesz: 0x%zx",
408 static_cast<size_t>(dynamic_shdr->sh_size),
412 DL_WARN("\"%s\" .dynamic section has invalid size: 0x%zx, "
413 "expected to match PT_DYNAMIC filesz: 0x%zx",
415 static_cast<size_t>(dynamic_shdr->sh_size),
417 add_dlwarning(name_.c_str(), "invalid .dynamic section");
420 if (dynamic_shdr->sh_link >= shdr_num_) {
421 DL_ERR_AND_LOG("\"%s\" .dynamic section has invalid sh_link: %d",
423 dynamic_shdr->sh_link);
427 const ElfW(Shdr)* strtab_shdr = &shdr_table_[dynamic_shdr->sh_link];
429 if (strtab_shdr->sh_type != SHT_STRTAB) {
430 DL_ERR_AND_LOG("\"%s\" .dynamic section has invalid link(%d) sh_type: %d (expected SHT_STRTAB)",
431 name_.c_str(), dynamic_shdr->sh_link, strtab_shdr->sh_type);
435 if (!CheckFileRange(dynamic_shdr->sh_offset, dynamic_shdr->sh_size, alignof(const ElfW(Dyn)))) {
436 DL_ERR_AND_LOG("\"%s\" has invalid offset/size of .dynamic section", name_.c_str());
440 if (!dynamic_fragment_.Map(fd_, file_offset_, dynamic_shdr->sh_offset, dynamic_shdr->sh_size)) {
441 DL_ERR("\"%s\" dynamic section mmap failed: %s", name_.c_str(), strerror(errno));
445 dynamic_ = static_cast<const ElfW(Dyn)*>(dynamic_fragment_.data());
447 if (!CheckFileRange(strtab_shdr->sh_offset, strtab_shdr->sh_size, alignof(const char))) {
448 DL_ERR_AND_LOG("\"%s\" has invalid offset/size of the .strtab section linked from .dynamic section",
453 if (!strtab_fragment_.Map(fd_, file_offset_, strtab_shdr->sh_offset, strtab_shdr->sh_size)) {
454 DL_ERR("\"%s\" strtab section mmap failed: %s", name_.c_str(), strerror(errno));
458 strtab_ = static_cast<const char*>(strtab_fragment_.data());
459 strtab_size_ = strtab_fragment_.size();
463 /* Returns the size of the extent of all the possibly non-contiguous
464 * loadable segments in an ELF program header table. This corresponds
465 * to the page-aligned size in bytes that needs to be reserved in the
466 * process' address space. If there are no loadable segments, 0 is
469 * If out_min_vaddr or out_max_vaddr are not null, they will be
470 * set to the minimum and maximum addresses of pages to be reserved,
471 * or 0 if there is nothing to load.
473 size_t phdr_table_get_load_size(const ElfW(Phdr)* phdr_table, size_t phdr_count,
474 ElfW(Addr)* out_min_vaddr,
475 ElfW(Addr)* out_max_vaddr) {
476 ElfW(Addr) min_vaddr = UINTPTR_MAX;
477 ElfW(Addr) max_vaddr = 0;
479 bool found_pt_load = false;
480 for (size_t i = 0; i < phdr_count; ++i) {
481 const ElfW(Phdr)* phdr = &phdr_table[i];
483 if (phdr->p_type != PT_LOAD) {
486 found_pt_load = true;
488 if (phdr->p_vaddr < min_vaddr) {
489 min_vaddr = phdr->p_vaddr;
492 if (phdr->p_vaddr + phdr->p_memsz > max_vaddr) {
493 max_vaddr = phdr->p_vaddr + phdr->p_memsz;
496 if (!found_pt_load) {
500 min_vaddr = PAGE_START(min_vaddr);
501 max_vaddr = PAGE_END(max_vaddr);
503 if (out_min_vaddr != nullptr) {
504 *out_min_vaddr = min_vaddr;
506 if (out_max_vaddr != nullptr) {
507 *out_max_vaddr = max_vaddr;
509 return max_vaddr - min_vaddr;
512 // Reserve a virtual address range such that if it's limits were extended to the next 2**align
513 // boundary, it would not overlap with any existing mappings.
514 static void* ReserveAligned(void* hint, size_t size, size_t align) {
515 int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS;
516 // Address hint is only used in Art for the image mapping, and it is pretty important. Don't mess
518 // FIXME: try an aligned allocation and fall back to plain mmap() if the former does not provide a
519 // mapping at the requested address?
520 if (align == PAGE_SIZE || hint != nullptr) {
521 void* mmap_ptr = mmap(hint, size, PROT_NONE, mmap_flags, -1, 0);
522 if (mmap_ptr == MAP_FAILED) {
528 // Allocate enough space so that the end of the desired region aligned up is still inside the
530 size_t mmap_size = align_up(size, align) + align - PAGE_SIZE;
532 reinterpret_cast<uint8_t*>(mmap(nullptr, mmap_size, PROT_NONE, mmap_flags, -1, 0));
533 if (mmap_ptr == MAP_FAILED) {
537 uint8_t* first = align_up(mmap_ptr, align);
538 uint8_t* last = align_down(mmap_ptr + mmap_size, align) - size;
539 size_t n = arc4random_uniform((last - first) / PAGE_SIZE + 1);
540 uint8_t* start = first + n * PAGE_SIZE;
541 munmap(mmap_ptr, start - mmap_ptr);
542 munmap(start + size, mmap_ptr + mmap_size - (start + size));
546 // Reserve a virtual address range big enough to hold all loadable
547 // segments of a program header table. This is done by creating a
548 // private anonymous mmap() with PROT_NONE.
549 bool ElfReader::ReserveAddressSpace(const android_dlextinfo* extinfo) {
550 ElfW(Addr) min_vaddr;
551 load_size_ = phdr_table_get_load_size(phdr_table_, phdr_num_, &min_vaddr);
552 if (load_size_ == 0) {
553 DL_ERR("\"%s\" has no loadable segments", name_.c_str());
557 uint8_t* addr = reinterpret_cast<uint8_t*>(min_vaddr);
559 size_t reserved_size = 0;
560 bool reserved_hint = true;
561 bool strict_hint = false;
562 // Assume position independent executable by default.
563 void* mmap_hint = nullptr;
565 if (extinfo != nullptr) {
566 if (extinfo->flags & ANDROID_DLEXT_RESERVED_ADDRESS) {
567 reserved_size = extinfo->reserved_size;
568 reserved_hint = false;
569 } else if (extinfo->flags & ANDROID_DLEXT_RESERVED_ADDRESS_HINT) {
570 reserved_size = extinfo->reserved_size;
573 if (addr != nullptr && (extinfo->flags & ANDROID_DLEXT_FORCE_FIXED_VADDR) != 0) {
575 } else if ((extinfo->flags & ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS) != 0) {
576 mmap_hint = extinfo->reserved_addr;
581 if (load_size_ > reserved_size) {
582 if (!reserved_hint) {
583 DL_ERR("reserved address space %zd smaller than %zd bytes needed for \"%s\"",
584 reserved_size - load_size_, load_size_, name_.c_str());
587 start = ReserveAligned(mmap_hint, load_size_, kLibraryAlignment);
588 if (start == nullptr) {
589 DL_ERR("couldn't reserve %zd bytes of address space for \"%s\"", load_size_, name_.c_str());
592 if (strict_hint && (start != mmap_hint)) {
593 munmap(start, load_size_);
594 DL_ERR("couldn't reserve %zd bytes of address space at %p for \"%s\"",
595 load_size_, mmap_hint, name_.c_str());
599 start = extinfo->reserved_addr;
600 mapped_by_caller_ = true;
604 load_bias_ = reinterpret_cast<uint8_t*>(start) - addr;
608 bool ElfReader::LoadSegments() {
609 for (size_t i = 0; i < phdr_num_; ++i) {
610 const ElfW(Phdr)* phdr = &phdr_table_[i];
612 if (phdr->p_type != PT_LOAD) {
616 // Segment addresses in memory.
617 ElfW(Addr) seg_start = phdr->p_vaddr + load_bias_;
618 ElfW(Addr) seg_end = seg_start + phdr->p_memsz;
620 ElfW(Addr) seg_page_start = PAGE_START(seg_start);
621 ElfW(Addr) seg_page_end = PAGE_END(seg_end);
623 ElfW(Addr) seg_file_end = seg_start + phdr->p_filesz;
626 ElfW(Addr) file_start = phdr->p_offset;
627 ElfW(Addr) file_end = file_start + phdr->p_filesz;
629 ElfW(Addr) file_page_start = PAGE_START(file_start);
630 ElfW(Addr) file_length = file_end - file_page_start;
632 if (file_size_ <= 0) {
633 DL_ERR("\"%s\" invalid file size: %" PRId64, name_.c_str(), file_size_);
637 if (file_end > static_cast<size_t>(file_size_)) {
638 DL_ERR("invalid ELF file \"%s\" load segment[%zd]:"
639 " p_offset (%p) + p_filesz (%p) ( = %p) past end of file (0x%" PRIx64 ")",
640 name_.c_str(), i, reinterpret_cast<void*>(phdr->p_offset),
641 reinterpret_cast<void*>(phdr->p_filesz),
642 reinterpret_cast<void*>(file_end), file_size_);
646 if (file_length != 0) {
647 int prot = PFLAGS_TO_PROT(phdr->p_flags);
648 if ((prot & (PROT_EXEC | PROT_WRITE)) == (PROT_EXEC | PROT_WRITE)) {
649 // W + E PT_LOAD segments are not allowed in O.
650 if (get_application_target_sdk_version() >= __ANDROID_API_O__) {
651 DL_ERR_AND_LOG("\"%s\": W + E load segments are not allowed", name_.c_str());
654 DL_WARN("\"%s\": W + E load segments are not allowed", name_.c_str());
655 add_dlwarning(name_.c_str(), "W+E load segments");
658 void* seg_addr = mmap64(reinterpret_cast<void*>(seg_page_start),
661 MAP_FIXED|MAP_PRIVATE,
663 file_offset_ + file_page_start);
664 if (seg_addr == MAP_FAILED) {
665 DL_ERR("couldn't map \"%s\" segment %zd: %s", name_.c_str(), i, strerror(errno));
670 // if the segment is writable, and does not end on a page boundary,
671 // zero-fill it until the page limit.
672 if ((phdr->p_flags & PF_W) != 0 && PAGE_OFFSET(seg_file_end) > 0) {
673 memset(reinterpret_cast<void*>(seg_file_end), 0, PAGE_SIZE - PAGE_OFFSET(seg_file_end));
676 seg_file_end = PAGE_END(seg_file_end);
678 // seg_file_end is now the first page address after the file
679 // content. If seg_end is larger, we need to zero anything
680 // between them. This is done by using a private anonymous
681 // map for all extra pages.
682 if (seg_page_end > seg_file_end) {
683 size_t zeromap_size = seg_page_end - seg_file_end;
684 void* zeromap = mmap(reinterpret_cast<void*>(seg_file_end),
686 PFLAGS_TO_PROT(phdr->p_flags),
687 MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE,
690 if (zeromap == MAP_FAILED) {
691 DL_ERR("couldn't zero fill \"%s\" gap: %s", name_.c_str(), strerror(errno));
695 prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, zeromap, zeromap_size, ".bss");
701 /* Used internally. Used to set the protection bits of all loaded segments
702 * with optional extra flags (i.e. really PROT_WRITE). Used by
703 * phdr_table_protect_segments and phdr_table_unprotect_segments.
705 static int _phdr_table_set_load_prot(const ElfW(Phdr)* phdr_table, size_t phdr_count,
706 ElfW(Addr) load_bias, int extra_prot_flags) {
707 const ElfW(Phdr)* phdr = phdr_table;
708 const ElfW(Phdr)* phdr_limit = phdr + phdr_count;
710 for (; phdr < phdr_limit; phdr++) {
711 if (phdr->p_type != PT_LOAD || (phdr->p_flags & PF_W) != 0) {
715 ElfW(Addr) seg_page_start = PAGE_START(phdr->p_vaddr) + load_bias;
716 ElfW(Addr) seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz) + load_bias;
718 int prot = PFLAGS_TO_PROT(phdr->p_flags);
719 if ((extra_prot_flags & PROT_WRITE) != 0) {
720 // make sure we're never simultaneously writable / executable
724 int ret = mprotect(reinterpret_cast<void*>(seg_page_start),
725 seg_page_end - seg_page_start,
726 prot | extra_prot_flags);
734 /* Restore the original protection modes for all loadable segments.
735 * You should only call this after phdr_table_unprotect_segments and
736 * applying all relocations.
739 * phdr_table -> program header table
740 * phdr_count -> number of entries in tables
741 * load_bias -> load bias
743 * 0 on error, -1 on failure (error code in errno).
745 int phdr_table_protect_segments(const ElfW(Phdr)* phdr_table,
746 size_t phdr_count, ElfW(Addr) load_bias) {
747 return _phdr_table_set_load_prot(phdr_table, phdr_count, load_bias, 0);
750 /* Change the protection of all loaded segments in memory to writable.
751 * This is useful before performing relocations. Once completed, you
752 * will have to call phdr_table_protect_segments to restore the original
753 * protection flags on all segments.
755 * Note that some writable segments can also have their content turned
756 * to read-only by calling phdr_table_protect_gnu_relro. This is no
760 * phdr_table -> program header table
761 * phdr_count -> number of entries in tables
762 * load_bias -> load bias
764 * 0 on error, -1 on failure (error code in errno).
766 int phdr_table_unprotect_segments(const ElfW(Phdr)* phdr_table,
767 size_t phdr_count, ElfW(Addr) load_bias) {
768 return _phdr_table_set_load_prot(phdr_table, phdr_count, load_bias, PROT_WRITE);
771 /* Used internally by phdr_table_protect_gnu_relro and
772 * phdr_table_unprotect_gnu_relro.
774 static int _phdr_table_set_gnu_relro_prot(const ElfW(Phdr)* phdr_table, size_t phdr_count,
775 ElfW(Addr) load_bias, int prot_flags) {
776 const ElfW(Phdr)* phdr = phdr_table;
777 const ElfW(Phdr)* phdr_limit = phdr + phdr_count;
779 for (phdr = phdr_table; phdr < phdr_limit; phdr++) {
780 if (phdr->p_type != PT_GNU_RELRO) {
784 // Tricky: what happens when the relro segment does not start
785 // or end at page boundaries? We're going to be over-protective
786 // here and put every page touched by the segment as read-only.
788 // This seems to match Ian Lance Taylor's description of the
789 // feature at http://www.airs.com/blog/archives/189.
792 // Note that the current dynamic linker code will only work
793 // correctly if the PT_GNU_RELRO segment starts on a page
794 // boundary. This is because the dynamic linker rounds the
795 // p_vaddr field down to the previous page boundary. If
796 // there is anything on the page which should not be read-only,
797 // the program is likely to fail at runtime. So in effect the
798 // linker must only emit a PT_GNU_RELRO segment if it ensures
799 // that it starts on a page boundary.
800 ElfW(Addr) seg_page_start = PAGE_START(phdr->p_vaddr) + load_bias;
801 ElfW(Addr) seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz) + load_bias;
803 int ret = mprotect(reinterpret_cast<void*>(seg_page_start),
804 seg_page_end - seg_page_start,
813 /* Apply GNU relro protection if specified by the program header. This will
814 * turn some of the pages of a writable PT_LOAD segment to read-only, as
815 * specified by one or more PT_GNU_RELRO segments. This must be always
816 * performed after relocations.
818 * The areas typically covered are .got and .data.rel.ro, these are
819 * read-only from the program's POV, but contain absolute addresses
820 * that need to be relocated before use.
823 * phdr_table -> program header table
824 * phdr_count -> number of entries in tables
825 * load_bias -> load bias
827 * 0 on error, -1 on failure (error code in errno).
829 int phdr_table_protect_gnu_relro(const ElfW(Phdr)* phdr_table,
830 size_t phdr_count, ElfW(Addr) load_bias) {
831 return _phdr_table_set_gnu_relro_prot(phdr_table, phdr_count, load_bias, PROT_READ);
834 /* Serialize the GNU relro segments to the given file descriptor. This can be
835 * performed after relocations to allow another process to later share the
836 * relocated segment, if it was loaded at the same address.
839 * phdr_table -> program header table
840 * phdr_count -> number of entries in tables
841 * load_bias -> load bias
842 * fd -> writable file descriptor to use
844 * 0 on error, -1 on failure (error code in errno).
846 int phdr_table_serialize_gnu_relro(const ElfW(Phdr)* phdr_table,
848 ElfW(Addr) load_bias,
850 const ElfW(Phdr)* phdr = phdr_table;
851 const ElfW(Phdr)* phdr_limit = phdr + phdr_count;
852 ssize_t file_offset = 0;
854 for (phdr = phdr_table; phdr < phdr_limit; phdr++) {
855 if (phdr->p_type != PT_GNU_RELRO) {
859 ElfW(Addr) seg_page_start = PAGE_START(phdr->p_vaddr) + load_bias;
860 ElfW(Addr) seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz) + load_bias;
861 ssize_t size = seg_page_end - seg_page_start;
863 ssize_t written = TEMP_FAILURE_RETRY(write(fd, reinterpret_cast<void*>(seg_page_start), size));
864 if (written != size) {
867 void* map = mmap(reinterpret_cast<void*>(seg_page_start), size, PROT_READ,
868 MAP_PRIVATE|MAP_FIXED, fd, file_offset);
869 if (map == MAP_FAILED) {
877 /* Where possible, replace the GNU relro segments with mappings of the given
878 * file descriptor. This can be performed after relocations to allow a file
879 * previously created by phdr_table_serialize_gnu_relro in another process to
880 * replace the dirty relocated pages, saving memory, if it was loaded at the
881 * same address. We have to compare the data before we map over it, since some
882 * parts of the relro segment may not be identical due to other libraries in
883 * the process being loaded at different addresses.
886 * phdr_table -> program header table
887 * phdr_count -> number of entries in tables
888 * load_bias -> load bias
889 * fd -> readable file descriptor to use
891 * 0 on error, -1 on failure (error code in errno).
893 int phdr_table_map_gnu_relro(const ElfW(Phdr)* phdr_table,
895 ElfW(Addr) load_bias,
897 // Map the file at a temporary location so we can compare its contents.
898 struct stat file_stat;
899 if (TEMP_FAILURE_RETRY(fstat(fd, &file_stat)) != 0) {
902 off_t file_size = file_stat.st_size;
903 void* temp_mapping = nullptr;
905 temp_mapping = mmap(nullptr, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
906 if (temp_mapping == MAP_FAILED) {
910 size_t file_offset = 0;
912 // Iterate over the relro segments and compare/remap the pages.
913 const ElfW(Phdr)* phdr = phdr_table;
914 const ElfW(Phdr)* phdr_limit = phdr + phdr_count;
916 for (phdr = phdr_table; phdr < phdr_limit; phdr++) {
917 if (phdr->p_type != PT_GNU_RELRO) {
921 ElfW(Addr) seg_page_start = PAGE_START(phdr->p_vaddr) + load_bias;
922 ElfW(Addr) seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz) + load_bias;
924 char* file_base = static_cast<char*>(temp_mapping) + file_offset;
925 char* mem_base = reinterpret_cast<char*>(seg_page_start);
926 size_t match_offset = 0;
927 size_t size = seg_page_end - seg_page_start;
929 if (file_size - file_offset < size) {
930 // File is too short to compare to this segment. The contents are likely
931 // different as well (it's probably for a different library version) so
932 // just don't bother checking.
936 while (match_offset < size) {
937 // Skip over dissimilar pages.
938 while (match_offset < size &&
939 memcmp(mem_base + match_offset, file_base + match_offset, PAGE_SIZE) != 0) {
940 match_offset += PAGE_SIZE;
943 // Count similar pages.
944 size_t mismatch_offset = match_offset;
945 while (mismatch_offset < size &&
946 memcmp(mem_base + mismatch_offset, file_base + mismatch_offset, PAGE_SIZE) == 0) {
947 mismatch_offset += PAGE_SIZE;
950 // Map over similar pages.
951 if (mismatch_offset > match_offset) {
952 void* map = mmap(mem_base + match_offset, mismatch_offset - match_offset,
953 PROT_READ, MAP_PRIVATE|MAP_FIXED, fd, match_offset);
954 if (map == MAP_FAILED) {
955 munmap(temp_mapping, file_size);
960 match_offset = mismatch_offset;
963 // Add to the base file offset in case there are multiple relro segments.
966 munmap(temp_mapping, file_size);
973 # ifndef PT_ARM_EXIDX
974 # define PT_ARM_EXIDX 0x70000001 /* .ARM.exidx segment */
977 /* Return the address and size of the .ARM.exidx section in memory,
981 * phdr_table -> program header table
982 * phdr_count -> number of entries in tables
983 * load_bias -> load bias
985 * arm_exidx -> address of table in memory (null on failure).
986 * arm_exidx_count -> number of items in table (0 on failure).
988 * 0 on error, -1 on failure (_no_ error code in errno)
990 int phdr_table_get_arm_exidx(const ElfW(Phdr)* phdr_table, size_t phdr_count,
991 ElfW(Addr) load_bias,
992 ElfW(Addr)** arm_exidx, size_t* arm_exidx_count) {
993 const ElfW(Phdr)* phdr = phdr_table;
994 const ElfW(Phdr)* phdr_limit = phdr + phdr_count;
996 for (phdr = phdr_table; phdr < phdr_limit; phdr++) {
997 if (phdr->p_type != PT_ARM_EXIDX) {
1001 *arm_exidx = reinterpret_cast<ElfW(Addr)*>(load_bias + phdr->p_vaddr);
1002 *arm_exidx_count = phdr->p_memsz / 8;
1005 *arm_exidx = nullptr;
1006 *arm_exidx_count = 0;
1011 /* Return the address and size of the ELF file's .dynamic section in memory,
1012 * or null if missing.
1015 * phdr_table -> program header table
1016 * phdr_count -> number of entries in tables
1017 * load_bias -> load bias
1019 * dynamic -> address of table in memory (null on failure).
1020 * dynamic_flags -> protection flags for section (unset on failure)
1024 void phdr_table_get_dynamic_section(const ElfW(Phdr)* phdr_table, size_t phdr_count,
1025 ElfW(Addr) load_bias, ElfW(Dyn)** dynamic,
1026 ElfW(Word)* dynamic_flags) {
1028 for (size_t i = 0; i<phdr_count; ++i) {
1029 const ElfW(Phdr)& phdr = phdr_table[i];
1030 if (phdr.p_type == PT_DYNAMIC) {
1031 *dynamic = reinterpret_cast<ElfW(Dyn)*>(load_bias + phdr.p_vaddr);
1032 if (dynamic_flags) {
1033 *dynamic_flags = phdr.p_flags;
1040 /* Return the program interpreter string, or nullptr if missing.
1043 * phdr_table -> program header table
1044 * phdr_count -> number of entries in tables
1045 * load_bias -> load bias
1047 * pointer to the program interpreter string.
1049 const char* phdr_table_get_interpreter_name(const ElfW(Phdr) * phdr_table, size_t phdr_count,
1050 ElfW(Addr) load_bias) {
1051 for (size_t i = 0; i<phdr_count; ++i) {
1052 const ElfW(Phdr)& phdr = phdr_table[i];
1053 if (phdr.p_type == PT_INTERP) {
1054 return reinterpret_cast<const char*>(load_bias + phdr.p_vaddr);
1060 // Sets loaded_phdr_ to the address of the program header table as it appears
1061 // in the loaded segments in memory. This is in contrast with phdr_table_,
1062 // which is temporary and will be released before the library is relocated.
1063 bool ElfReader::FindPhdr() {
1064 const ElfW(Phdr)* phdr_limit = phdr_table_ + phdr_num_;
1066 // If there is a PT_PHDR, use it directly.
1067 for (const ElfW(Phdr)* phdr = phdr_table_; phdr < phdr_limit; ++phdr) {
1068 if (phdr->p_type == PT_PHDR) {
1069 return CheckPhdr(load_bias_ + phdr->p_vaddr);
1073 // Otherwise, check the first loadable segment. If its file offset
1074 // is 0, it starts with the ELF header, and we can trivially find the
1075 // loaded program header from it.
1076 for (const ElfW(Phdr)* phdr = phdr_table_; phdr < phdr_limit; ++phdr) {
1077 if (phdr->p_type == PT_LOAD) {
1078 if (phdr->p_offset == 0) {
1079 ElfW(Addr) elf_addr = load_bias_ + phdr->p_vaddr;
1080 const ElfW(Ehdr)* ehdr = reinterpret_cast<const ElfW(Ehdr)*>(elf_addr);
1081 ElfW(Addr) offset = ehdr->e_phoff;
1082 return CheckPhdr(reinterpret_cast<ElfW(Addr)>(ehdr) + offset);
1088 DL_ERR("can't find loaded phdr for \"%s\"", name_.c_str());
1092 // Ensures that our program header is actually within a loadable
1093 // segment. This should help catch badly-formed ELF files that
1094 // would cause the linker to crash later when trying to access it.
1095 bool ElfReader::CheckPhdr(ElfW(Addr) loaded) {
1096 const ElfW(Phdr)* phdr_limit = phdr_table_ + phdr_num_;
1097 ElfW(Addr) loaded_end = loaded + (phdr_num_ * sizeof(ElfW(Phdr)));
1098 for (const ElfW(Phdr)* phdr = phdr_table_; phdr < phdr_limit; ++phdr) {
1099 if (phdr->p_type != PT_LOAD) {
1102 ElfW(Addr) seg_start = phdr->p_vaddr + load_bias_;
1103 ElfW(Addr) seg_end = phdr->p_filesz + seg_start;
1104 if (seg_start <= loaded && loaded_end <= seg_end) {
1105 loaded_phdr_ = reinterpret_cast<const ElfW(Phdr)*>(loaded);
1109 DL_ERR("\"%s\" loaded phdr %p not in loadable segment",
1110 name_.c_str(), reinterpret_cast<void*>(loaded));