1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "elf_file.h"
18 
19 #include <inttypes.h>
20 #include <sys/types.h>
21 #include <unistd.h>
22 
23 #include "arch/instruction_set.h"
24 #include "base/logging.h"
25 #include "base/stringprintf.h"
26 #include "base/stl_util.h"
27 #include "base/unix_file/fd_file.h"
28 #include "elf_file_impl.h"
29 #include "elf_utils.h"
30 #include "leb128.h"
31 #include "utils.h"
32 
33 namespace art {
34 
35 // -------------------------------------------------------------------
36 // Binary GDB JIT Interface as described in
37 //   http://sourceware.org/gdb/onlinedocs/gdb/Declarations.html
38 extern "C" {
39   typedef enum {
40     JIT_NOACTION = 0,
41     JIT_REGISTER_FN,
42     JIT_UNREGISTER_FN
43   } JITAction;
44 
45   struct JITCodeEntry {
46     JITCodeEntry* next_;
47     JITCodeEntry* prev_;
48     const uint8_t *symfile_addr_;
49     uint64_t symfile_size_;
50   };
51 
52   struct JITDescriptor {
53     uint32_t version_;
54     uint32_t action_flag_;
55     JITCodeEntry* relevant_entry_;
56     JITCodeEntry* first_entry_;
57   };
58 
59   // GDB will place breakpoint into this function.
60   // To prevent GCC from inlining or removing it we place noinline attribute
61   // and inline assembler statement inside.
62   void __attribute__((noinline)) __jit_debug_register_code();
__jit_debug_register_code()63   void __attribute__((noinline)) __jit_debug_register_code() {
64     __asm__("");
65   }
66 
67   // GDB will inspect contents of this descriptor.
68   // Static initialization is necessary to prevent GDB from seeing
69   // uninitialized descriptor.
70   JITDescriptor __jit_debug_descriptor = { 1, JIT_NOACTION, nullptr, nullptr };
71 }
72 
73 
CreateCodeEntry(const uint8_t * symfile_addr,uintptr_t symfile_size)74 static JITCodeEntry* CreateCodeEntry(const uint8_t *symfile_addr,
75                                      uintptr_t symfile_size) {
76   JITCodeEntry* entry = new JITCodeEntry;
77   entry->symfile_addr_ = symfile_addr;
78   entry->symfile_size_ = symfile_size;
79   entry->prev_ = nullptr;
80 
81   // TODO: Do we need a lock here?
82   entry->next_ = __jit_debug_descriptor.first_entry_;
83   if (entry->next_ != nullptr) {
84     entry->next_->prev_ = entry;
85   }
86   __jit_debug_descriptor.first_entry_ = entry;
87   __jit_debug_descriptor.relevant_entry_ = entry;
88 
89   __jit_debug_descriptor.action_flag_ = JIT_REGISTER_FN;
90   __jit_debug_register_code();
91   return entry;
92 }
93 
94 
UnregisterCodeEntry(JITCodeEntry * entry)95 static void UnregisterCodeEntry(JITCodeEntry* entry) {
96   // TODO: Do we need a lock here?
97   if (entry->prev_ != nullptr) {
98     entry->prev_->next_ = entry->next_;
99   } else {
100     __jit_debug_descriptor.first_entry_ = entry->next_;
101   }
102 
103   if (entry->next_ != nullptr) {
104     entry->next_->prev_ = entry->prev_;
105   }
106 
107   __jit_debug_descriptor.relevant_entry_ = entry;
108   __jit_debug_descriptor.action_flag_ = JIT_UNREGISTER_FN;
109   __jit_debug_register_code();
110   delete entry;
111 }
112 
113 template <typename ElfTypes>
ElfFileImpl(File * file,bool writable,bool program_header_only,uint8_t * requested_base)114 ElfFileImpl<ElfTypes>::ElfFileImpl(File* file, bool writable,
115                                    bool program_header_only,
116                                    uint8_t* requested_base)
117   : file_(file),
118     writable_(writable),
119     program_header_only_(program_header_only),
120     header_(nullptr),
121     base_address_(nullptr),
122     program_headers_start_(nullptr),
123     section_headers_start_(nullptr),
124     dynamic_program_header_(nullptr),
125     dynamic_section_start_(nullptr),
126     symtab_section_start_(nullptr),
127     dynsym_section_start_(nullptr),
128     strtab_section_start_(nullptr),
129     dynstr_section_start_(nullptr),
130     hash_section_start_(nullptr),
131     symtab_symbol_table_(nullptr),
132     dynsym_symbol_table_(nullptr),
133     jit_elf_image_(nullptr),
134     jit_gdb_entry_(nullptr),
135     requested_base_(requested_base) {
136   CHECK(file != nullptr);
137 }
138 
139 template <typename ElfTypes>
Open(File * file,bool writable,bool program_header_only,std::string * error_msg,uint8_t * requested_base)140 ElfFileImpl<ElfTypes>* ElfFileImpl<ElfTypes>::Open(
141     File* file, bool writable, bool program_header_only,
142     std::string* error_msg, uint8_t* requested_base) {
143   std::unique_ptr<ElfFileImpl<ElfTypes>> elf_file(new ElfFileImpl<ElfTypes>
144       (file, writable, program_header_only, requested_base));
145   int prot;
146   int flags;
147   if (writable) {
148     prot = PROT_READ | PROT_WRITE;
149     flags = MAP_SHARED;
150   } else {
151     prot = PROT_READ;
152     flags = MAP_PRIVATE;
153   }
154   if (!elf_file->Setup(prot, flags, error_msg)) {
155     return nullptr;
156   }
157   return elf_file.release();
158 }
159 
160 template <typename ElfTypes>
Open(File * file,int prot,int flags,std::string * error_msg)161 ElfFileImpl<ElfTypes>* ElfFileImpl<ElfTypes>::Open(
162     File* file, int prot, int flags, std::string* error_msg) {
163   std::unique_ptr<ElfFileImpl<ElfTypes>> elf_file(new ElfFileImpl<ElfTypes>
164       (file, (prot & PROT_WRITE) == PROT_WRITE, /*program_header_only*/false,
165       /*requested_base*/nullptr));
166   if (!elf_file->Setup(prot, flags, error_msg)) {
167     return nullptr;
168   }
169   return elf_file.release();
170 }
171 
172 template <typename ElfTypes>
Setup(int prot,int flags,std::string * error_msg)173 bool ElfFileImpl<ElfTypes>::Setup(int prot, int flags, std::string* error_msg) {
174   int64_t temp_file_length = file_->GetLength();
175   if (temp_file_length < 0) {
176     errno = -temp_file_length;
177     *error_msg = StringPrintf("Failed to get length of file: '%s' fd=%d: %s",
178                               file_->GetPath().c_str(), file_->Fd(), strerror(errno));
179     return false;
180   }
181   size_t file_length = static_cast<size_t>(temp_file_length);
182   if (file_length < sizeof(Elf_Ehdr)) {
183     *error_msg = StringPrintf("File size of %zd bytes not large enough to contain ELF header of "
184                               "%zd bytes: '%s'", file_length, sizeof(Elf_Ehdr),
185                               file_->GetPath().c_str());
186     return false;
187   }
188 
189   if (program_header_only_) {
190     // first just map ELF header to get program header size information
191     size_t elf_header_size = sizeof(Elf_Ehdr);
192     if (!SetMap(MemMap::MapFile(elf_header_size, prot, flags, file_->Fd(), 0,
193                                 file_->GetPath().c_str(), error_msg),
194                 error_msg)) {
195       return false;
196     }
197     // then remap to cover program header
198     size_t program_header_size = header_->e_phoff + (header_->e_phentsize * header_->e_phnum);
199     if (file_length < program_header_size) {
200       *error_msg = StringPrintf("File size of %zd bytes not large enough to contain ELF program "
201                                 "header of %zd bytes: '%s'", file_length,
202                                 sizeof(Elf_Ehdr), file_->GetPath().c_str());
203       return false;
204     }
205     if (!SetMap(MemMap::MapFile(program_header_size, prot, flags, file_->Fd(), 0,
206                                 file_->GetPath().c_str(), error_msg),
207                 error_msg)) {
208       *error_msg = StringPrintf("Failed to map ELF program headers: %s", error_msg->c_str());
209       return false;
210     }
211   } else {
212     // otherwise map entire file
213     if (!SetMap(MemMap::MapFile(file_->GetLength(), prot, flags, file_->Fd(), 0,
214                                 file_->GetPath().c_str(), error_msg),
215                 error_msg)) {
216       *error_msg = StringPrintf("Failed to map ELF file: %s", error_msg->c_str());
217       return false;
218     }
219   }
220 
221   if (program_header_only_) {
222     program_headers_start_ = Begin() + GetHeader().e_phoff;
223   } else {
224     if (!CheckAndSet(GetHeader().e_phoff, "program headers", &program_headers_start_, error_msg)) {
225       return false;
226     }
227 
228     // Setup section headers.
229     if (!CheckAndSet(GetHeader().e_shoff, "section headers", &section_headers_start_, error_msg)) {
230       return false;
231     }
232 
233     // Find shstrtab.
234     Elf_Shdr* shstrtab_section_header = GetSectionNameStringSection();
235     if (shstrtab_section_header == nullptr) {
236       *error_msg = StringPrintf("Failed to find shstrtab section header in ELF file: '%s'",
237                                 file_->GetPath().c_str());
238       return false;
239     }
240 
241     // Find .dynamic section info from program header
242     dynamic_program_header_ = FindProgamHeaderByType(PT_DYNAMIC);
243     if (dynamic_program_header_ == nullptr) {
244       *error_msg = StringPrintf("Failed to find PT_DYNAMIC program header in ELF file: '%s'",
245                                 file_->GetPath().c_str());
246       return false;
247     }
248 
249     if (!CheckAndSet(GetDynamicProgramHeader().p_offset, "dynamic section",
250                      reinterpret_cast<uint8_t**>(&dynamic_section_start_), error_msg)) {
251       return false;
252     }
253 
254     // Find other sections from section headers
255     for (Elf_Word i = 0; i < GetSectionHeaderNum(); i++) {
256       Elf_Shdr* section_header = GetSectionHeader(i);
257       if (section_header == nullptr) {
258         *error_msg = StringPrintf("Failed to find section header for section %d in ELF file: '%s'",
259                                   i, file_->GetPath().c_str());
260         return false;
261       }
262       switch (section_header->sh_type) {
263         case SHT_SYMTAB: {
264           if (!CheckAndSet(section_header->sh_offset, "symtab",
265                            reinterpret_cast<uint8_t**>(&symtab_section_start_), error_msg)) {
266             return false;
267           }
268           break;
269         }
270         case SHT_DYNSYM: {
271           if (!CheckAndSet(section_header->sh_offset, "dynsym",
272                            reinterpret_cast<uint8_t**>(&dynsym_section_start_), error_msg)) {
273             return false;
274           }
275           break;
276         }
277         case SHT_STRTAB: {
278           // TODO: base these off of sh_link from .symtab and .dynsym above
279           if ((section_header->sh_flags & SHF_ALLOC) != 0) {
280             // Check that this is named ".dynstr" and ignore otherwise.
281             const char* header_name = GetString(*shstrtab_section_header, section_header->sh_name);
282             if (strncmp(".dynstr", header_name, 8) == 0) {
283               if (!CheckAndSet(section_header->sh_offset, "dynstr",
284                                reinterpret_cast<uint8_t**>(&dynstr_section_start_), error_msg)) {
285                 return false;
286               }
287             }
288           } else {
289             // Check that this is named ".strtab" and ignore otherwise.
290             const char* header_name = GetString(*shstrtab_section_header, section_header->sh_name);
291             if (strncmp(".strtab", header_name, 8) == 0) {
292               if (!CheckAndSet(section_header->sh_offset, "strtab",
293                                reinterpret_cast<uint8_t**>(&strtab_section_start_), error_msg)) {
294                 return false;
295               }
296             }
297           }
298           break;
299         }
300         case SHT_DYNAMIC: {
301           if (reinterpret_cast<uint8_t*>(dynamic_section_start_) !=
302               Begin() + section_header->sh_offset) {
303             LOG(WARNING) << "Failed to find matching SHT_DYNAMIC for PT_DYNAMIC in "
304                          << file_->GetPath() << ": " << std::hex
305                          << reinterpret_cast<void*>(dynamic_section_start_)
306                          << " != " << reinterpret_cast<void*>(Begin() + section_header->sh_offset);
307             return false;
308           }
309           break;
310         }
311         case SHT_HASH: {
312           if (!CheckAndSet(section_header->sh_offset, "hash section",
313                            reinterpret_cast<uint8_t**>(&hash_section_start_), error_msg)) {
314             return false;
315           }
316           break;
317         }
318       }
319     }
320 
321     // Check for the existence of some sections.
322     if (!CheckSectionsExist(error_msg)) {
323       return false;
324     }
325   }
326 
327   return true;
328 }
329 
330 template <typename ElfTypes>
~ElfFileImpl()331 ElfFileImpl<ElfTypes>::~ElfFileImpl() {
332   STLDeleteElements(&segments_);
333   delete symtab_symbol_table_;
334   delete dynsym_symbol_table_;
335   delete jit_elf_image_;
336   if (jit_gdb_entry_) {
337     UnregisterCodeEntry(jit_gdb_entry_);
338   }
339 }
340 
341 template <typename ElfTypes>
CheckAndSet(Elf32_Off offset,const char * label,uint8_t ** target,std::string * error_msg)342 bool ElfFileImpl<ElfTypes>::CheckAndSet(Elf32_Off offset, const char* label,
343                                         uint8_t** target, std::string* error_msg) {
344   if (Begin() + offset >= End()) {
345     *error_msg = StringPrintf("Offset %d is out of range for %s in ELF file: '%s'", offset, label,
346                               file_->GetPath().c_str());
347     return false;
348   }
349   *target = Begin() + offset;
350   return true;
351 }
352 
353 template <typename ElfTypes>
CheckSectionsLinked(const uint8_t * source,const uint8_t * target) const354 bool ElfFileImpl<ElfTypes>::CheckSectionsLinked(const uint8_t* source,
355                                                 const uint8_t* target) const {
356   // Only works in whole-program mode, as we need to iterate over the sections.
357   // Note that we normally can't search by type, as duplicates are allowed for most section types.
358   if (program_header_only_) {
359     return true;
360   }
361 
362   Elf_Shdr* source_section = nullptr;
363   Elf_Word target_index = 0;
364   bool target_found = false;
365   for (Elf_Word i = 0; i < GetSectionHeaderNum(); i++) {
366     Elf_Shdr* section_header = GetSectionHeader(i);
367 
368     if (Begin() + section_header->sh_offset == source) {
369       // Found the source.
370       source_section = section_header;
371       if (target_index) {
372         break;
373       }
374     } else if (Begin() + section_header->sh_offset == target) {
375       target_index = i;
376       target_found = true;
377       if (source_section != nullptr) {
378         break;
379       }
380     }
381   }
382 
383   return target_found && source_section != nullptr && source_section->sh_link == target_index;
384 }
385 
386 template <typename ElfTypes>
CheckSectionsExist(std::string * error_msg) const387 bool ElfFileImpl<ElfTypes>::CheckSectionsExist(std::string* error_msg) const {
388   if (!program_header_only_) {
389     // If in full mode, need section headers.
390     if (section_headers_start_ == nullptr) {
391       *error_msg = StringPrintf("No section headers in ELF file: '%s'", file_->GetPath().c_str());
392       return false;
393     }
394   }
395 
396   // This is redundant, but defensive.
397   if (dynamic_program_header_ == nullptr) {
398     *error_msg = StringPrintf("Failed to find PT_DYNAMIC program header in ELF file: '%s'",
399                               file_->GetPath().c_str());
400     return false;
401   }
402 
403   // Need a dynamic section. This is redundant, but defensive.
404   if (dynamic_section_start_ == nullptr) {
405     *error_msg = StringPrintf("Failed to find dynamic section in ELF file: '%s'",
406                               file_->GetPath().c_str());
407     return false;
408   }
409 
410   // Symtab validation. These is not really a hard failure, as we are currently not using the
411   // symtab internally, but it's nice to be defensive.
412   if (symtab_section_start_ != nullptr) {
413     // When there's a symtab, there should be a strtab.
414     if (strtab_section_start_ == nullptr) {
415       *error_msg = StringPrintf("No strtab for symtab in ELF file: '%s'", file_->GetPath().c_str());
416       return false;
417     }
418 
419     // The symtab should link to the strtab.
420     if (!CheckSectionsLinked(reinterpret_cast<const uint8_t*>(symtab_section_start_),
421                              reinterpret_cast<const uint8_t*>(strtab_section_start_))) {
422       *error_msg = StringPrintf("Symtab is not linked to the strtab in ELF file: '%s'",
423                                 file_->GetPath().c_str());
424       return false;
425     }
426   }
427 
428   // We always need a dynstr & dynsym.
429   if (dynstr_section_start_ == nullptr) {
430     *error_msg = StringPrintf("No dynstr in ELF file: '%s'", file_->GetPath().c_str());
431     return false;
432   }
433   if (dynsym_section_start_ == nullptr) {
434     *error_msg = StringPrintf("No dynsym in ELF file: '%s'", file_->GetPath().c_str());
435     return false;
436   }
437 
438   // Need a hash section for dynamic symbol lookup.
439   if (hash_section_start_ == nullptr) {
440     *error_msg = StringPrintf("Failed to find hash section in ELF file: '%s'",
441                               file_->GetPath().c_str());
442     return false;
443   }
444 
445   // And the hash section should be linking to the dynsym.
446   if (!CheckSectionsLinked(reinterpret_cast<const uint8_t*>(hash_section_start_),
447                            reinterpret_cast<const uint8_t*>(dynsym_section_start_))) {
448     *error_msg = StringPrintf("Hash section is not linked to the dynstr in ELF file: '%s'",
449                               file_->GetPath().c_str());
450     return false;
451   }
452 
453   // We'd also like to confirm a shstrtab in program_header_only_ mode (else Open() does this for
454   // us). This is usually the last in an oat file, and a good indicator of whether writing was
455   // successful (or the process crashed and left garbage).
456   if (program_header_only_) {
457     // It might not be mapped, but we can compare against the file size.
458     int64_t offset = static_cast<int64_t>(GetHeader().e_shoff +
459                                           (GetHeader().e_shstrndx * GetHeader().e_shentsize));
460     if (offset >= file_->GetLength()) {
461       *error_msg = StringPrintf("Shstrtab is not in the mapped ELF file: '%s'",
462                                 file_->GetPath().c_str());
463       return false;
464     }
465   }
466 
467   return true;
468 }
469 
470 template <typename ElfTypes>
SetMap(MemMap * map,std::string * error_msg)471 bool ElfFileImpl<ElfTypes>::SetMap(MemMap* map, std::string* error_msg) {
472   if (map == nullptr) {
473     // MemMap::Open should have already set an error.
474     DCHECK(!error_msg->empty());
475     return false;
476   }
477   map_.reset(map);
478   CHECK(map_.get() != nullptr) << file_->GetPath();
479   CHECK(map_->Begin() != nullptr) << file_->GetPath();
480 
481   header_ = reinterpret_cast<Elf_Ehdr*>(map_->Begin());
482   if ((ELFMAG0 != header_->e_ident[EI_MAG0])
483       || (ELFMAG1 != header_->e_ident[EI_MAG1])
484       || (ELFMAG2 != header_->e_ident[EI_MAG2])
485       || (ELFMAG3 != header_->e_ident[EI_MAG3])) {
486     *error_msg = StringPrintf("Failed to find ELF magic value %d %d %d %d in %s, found %d %d %d %d",
487                               ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3,
488                               file_->GetPath().c_str(),
489                               header_->e_ident[EI_MAG0],
490                               header_->e_ident[EI_MAG1],
491                               header_->e_ident[EI_MAG2],
492                               header_->e_ident[EI_MAG3]);
493     return false;
494   }
495   uint8_t elf_class = (sizeof(Elf_Addr) == sizeof(Elf64_Addr)) ? ELFCLASS64 : ELFCLASS32;
496   if (elf_class != header_->e_ident[EI_CLASS]) {
497     *error_msg = StringPrintf("Failed to find expected EI_CLASS value %d in %s, found %d",
498                               elf_class,
499                               file_->GetPath().c_str(),
500                               header_->e_ident[EI_CLASS]);
501     return false;
502   }
503   if (ELFDATA2LSB != header_->e_ident[EI_DATA]) {
504     *error_msg = StringPrintf("Failed to find expected EI_DATA value %d in %s, found %d",
505                               ELFDATA2LSB,
506                               file_->GetPath().c_str(),
507                               header_->e_ident[EI_CLASS]);
508     return false;
509   }
510   if (EV_CURRENT != header_->e_ident[EI_VERSION]) {
511     *error_msg = StringPrintf("Failed to find expected EI_VERSION value %d in %s, found %d",
512                               EV_CURRENT,
513                               file_->GetPath().c_str(),
514                               header_->e_ident[EI_CLASS]);
515     return false;
516   }
517   if (ET_DYN != header_->e_type) {
518     *error_msg = StringPrintf("Failed to find expected e_type value %d in %s, found %d",
519                               ET_DYN,
520                               file_->GetPath().c_str(),
521                               header_->e_type);
522     return false;
523   }
524   if (EV_CURRENT != header_->e_version) {
525     *error_msg = StringPrintf("Failed to find expected e_version value %d in %s, found %d",
526                               EV_CURRENT,
527                               file_->GetPath().c_str(),
528                               header_->e_version);
529     return false;
530   }
531   if (0 != header_->e_entry) {
532     *error_msg = StringPrintf("Failed to find expected e_entry value %d in %s, found %d",
533                               0,
534                               file_->GetPath().c_str(),
535                               static_cast<int32_t>(header_->e_entry));
536     return false;
537   }
538   if (0 == header_->e_phoff) {
539     *error_msg = StringPrintf("Failed to find non-zero e_phoff value in %s",
540                               file_->GetPath().c_str());
541     return false;
542   }
543   if (0 == header_->e_shoff) {
544     *error_msg = StringPrintf("Failed to find non-zero e_shoff value in %s",
545                               file_->GetPath().c_str());
546     return false;
547   }
548   if (0 == header_->e_ehsize) {
549     *error_msg = StringPrintf("Failed to find non-zero e_ehsize value in %s",
550                               file_->GetPath().c_str());
551     return false;
552   }
553   if (0 == header_->e_phentsize) {
554     *error_msg = StringPrintf("Failed to find non-zero e_phentsize value in %s",
555                               file_->GetPath().c_str());
556     return false;
557   }
558   if (0 == header_->e_phnum) {
559     *error_msg = StringPrintf("Failed to find non-zero e_phnum value in %s",
560                               file_->GetPath().c_str());
561     return false;
562   }
563   if (0 == header_->e_shentsize) {
564     *error_msg = StringPrintf("Failed to find non-zero e_shentsize value in %s",
565                               file_->GetPath().c_str());
566     return false;
567   }
568   if (0 == header_->e_shnum) {
569     *error_msg = StringPrintf("Failed to find non-zero e_shnum value in %s",
570                               file_->GetPath().c_str());
571     return false;
572   }
573   if (0 == header_->e_shstrndx) {
574     *error_msg = StringPrintf("Failed to find non-zero e_shstrndx value in %s",
575                               file_->GetPath().c_str());
576     return false;
577   }
578   if (header_->e_shstrndx >= header_->e_shnum) {
579     *error_msg = StringPrintf("Failed to find e_shnum value %d less than %d in %s",
580                               header_->e_shstrndx,
581                               header_->e_shnum,
582                               file_->GetPath().c_str());
583     return false;
584   }
585 
586   if (!program_header_only_) {
587     if (header_->e_phoff >= Size()) {
588       *error_msg = StringPrintf("Failed to find e_phoff value %" PRIu64 " less than %zd in %s",
589                                 static_cast<uint64_t>(header_->e_phoff),
590                                 Size(),
591                                 file_->GetPath().c_str());
592       return false;
593     }
594     if (header_->e_shoff >= Size()) {
595       *error_msg = StringPrintf("Failed to find e_shoff value %" PRIu64 " less than %zd in %s",
596                                 static_cast<uint64_t>(header_->e_shoff),
597                                 Size(),
598                                 file_->GetPath().c_str());
599       return false;
600     }
601   }
602   return true;
603 }
604 
605 template <typename ElfTypes>
GetHeader() const606 typename ElfTypes::Ehdr& ElfFileImpl<ElfTypes>::GetHeader() const {
607   CHECK(header_ != nullptr);  // Header has been checked in SetMap. This is a sanity check.
608   return *header_;
609 }
610 
611 template <typename ElfTypes>
GetProgramHeadersStart() const612 uint8_t* ElfFileImpl<ElfTypes>::GetProgramHeadersStart() const {
613   CHECK(program_headers_start_ != nullptr);  // Header has been set in Setup. This is a sanity
614                                              // check.
615   return program_headers_start_;
616 }
617 
618 template <typename ElfTypes>
GetSectionHeadersStart() const619 uint8_t* ElfFileImpl<ElfTypes>::GetSectionHeadersStart() const {
620   CHECK(!program_header_only_);              // Only used in "full" mode.
621   CHECK(section_headers_start_ != nullptr);  // Is checked in CheckSectionsExist. Sanity check.
622   return section_headers_start_;
623 }
624 
625 template <typename ElfTypes>
GetDynamicProgramHeader() const626 typename ElfTypes::Phdr& ElfFileImpl<ElfTypes>::GetDynamicProgramHeader() const {
627   CHECK(dynamic_program_header_ != nullptr);  // Is checked in CheckSectionsExist. Sanity check.
628   return *dynamic_program_header_;
629 }
630 
631 template <typename ElfTypes>
GetDynamicSectionStart() const632 typename ElfTypes::Dyn* ElfFileImpl<ElfTypes>::GetDynamicSectionStart() const {
633   CHECK(dynamic_section_start_ != nullptr);  // Is checked in CheckSectionsExist. Sanity check.
634   return dynamic_section_start_;
635 }
636 
637 template <typename ElfTypes>
GetSymbolSectionStart(Elf_Word section_type) const638 typename ElfTypes::Sym* ElfFileImpl<ElfTypes>::GetSymbolSectionStart(
639     Elf_Word section_type) const {
640   CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type;
641   switch (section_type) {
642     case SHT_SYMTAB: {
643       return symtab_section_start_;
644       break;
645     }
646     case SHT_DYNSYM: {
647       return dynsym_section_start_;
648       break;
649     }
650     default: {
651       LOG(FATAL) << section_type;
652       return nullptr;
653     }
654   }
655 }
656 
657 template <typename ElfTypes>
GetStringSectionStart(Elf_Word section_type) const658 const char* ElfFileImpl<ElfTypes>::GetStringSectionStart(
659     Elf_Word section_type) const {
660   CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type;
661   switch (section_type) {
662     case SHT_SYMTAB: {
663       return strtab_section_start_;
664     }
665     case SHT_DYNSYM: {
666       return dynstr_section_start_;
667     }
668     default: {
669       LOG(FATAL) << section_type;
670       return nullptr;
671     }
672   }
673 }
674 
675 template <typename ElfTypes>
GetString(Elf_Word section_type,Elf_Word i) const676 const char* ElfFileImpl<ElfTypes>::GetString(Elf_Word section_type,
677                                              Elf_Word i) const {
678   CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type;
679   if (i == 0) {
680     return nullptr;
681   }
682   const char* string_section_start = GetStringSectionStart(section_type);
683   if (string_section_start == nullptr) {
684     return nullptr;
685   }
686   return string_section_start + i;
687 }
688 
689 // WARNING: The following methods do not check for an error condition (non-existent hash section).
690 //          It is the caller's job to do this.
691 
692 template <typename ElfTypes>
GetHashSectionStart() const693 typename ElfTypes::Word* ElfFileImpl<ElfTypes>::GetHashSectionStart() const {
694   return hash_section_start_;
695 }
696 
697 template <typename ElfTypes>
GetHashBucketNum() const698 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetHashBucketNum() const {
699   return GetHashSectionStart()[0];
700 }
701 
702 template <typename ElfTypes>
GetHashChainNum() const703 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetHashChainNum() const {
704   return GetHashSectionStart()[1];
705 }
706 
707 template <typename ElfTypes>
GetHashBucket(size_t i,bool * ok) const708 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetHashBucket(size_t i, bool* ok) const {
709   if (i >= GetHashBucketNum()) {
710     *ok = false;
711     return 0;
712   }
713   *ok = true;
714   // 0 is nbucket, 1 is nchain
715   return GetHashSectionStart()[2 + i];
716 }
717 
718 template <typename ElfTypes>
GetHashChain(size_t i,bool * ok) const719 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetHashChain(size_t i, bool* ok) const {
720   if (i >= GetHashChainNum()) {
721     *ok = false;
722     return 0;
723   }
724   *ok = true;
725   // 0 is nbucket, 1 is nchain, & chains are after buckets
726   return GetHashSectionStart()[2 + GetHashBucketNum() + i];
727 }
728 
729 template <typename ElfTypes>
GetProgramHeaderNum() const730 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetProgramHeaderNum() const {
731   return GetHeader().e_phnum;
732 }
733 
734 template <typename ElfTypes>
GetProgramHeader(Elf_Word i) const735 typename ElfTypes::Phdr* ElfFileImpl<ElfTypes>::GetProgramHeader(Elf_Word i) const {
736   CHECK_LT(i, GetProgramHeaderNum()) << file_->GetPath();  // Sanity check for caller.
737   uint8_t* program_header = GetProgramHeadersStart() + (i * GetHeader().e_phentsize);
738   if (program_header >= End()) {
739     return nullptr;  // Failure condition.
740   }
741   return reinterpret_cast<Elf_Phdr*>(program_header);
742 }
743 
744 template <typename ElfTypes>
FindProgamHeaderByType(Elf_Word type) const745 typename ElfTypes::Phdr* ElfFileImpl<ElfTypes>::FindProgamHeaderByType(Elf_Word type) const {
746   for (Elf_Word i = 0; i < GetProgramHeaderNum(); i++) {
747     Elf_Phdr* program_header = GetProgramHeader(i);
748     if (program_header->p_type == type) {
749       return program_header;
750     }
751   }
752   return nullptr;
753 }
754 
755 template <typename ElfTypes>
GetSectionHeaderNum() const756 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetSectionHeaderNum() const {
757   return GetHeader().e_shnum;
758 }
759 
760 template <typename ElfTypes>
GetSectionHeader(Elf_Word i) const761 typename ElfTypes::Shdr* ElfFileImpl<ElfTypes>::GetSectionHeader(Elf_Word i) const {
762   // Can only access arbitrary sections when we have the whole file, not just program header.
763   // Even if we Load(), it doesn't bring in all the sections.
764   CHECK(!program_header_only_) << file_->GetPath();
765   if (i >= GetSectionHeaderNum()) {
766     return nullptr;  // Failure condition.
767   }
768   uint8_t* section_header = GetSectionHeadersStart() + (i * GetHeader().e_shentsize);
769   if (section_header >= End()) {
770     return nullptr;  // Failure condition.
771   }
772   return reinterpret_cast<Elf_Shdr*>(section_header);
773 }
774 
775 template <typename ElfTypes>
FindSectionByType(Elf_Word type) const776 typename ElfTypes::Shdr* ElfFileImpl<ElfTypes>::FindSectionByType(Elf_Word type) const {
777   // Can only access arbitrary sections when we have the whole file, not just program header.
778   // We could change this to switch on known types if they were detected during loading.
779   CHECK(!program_header_only_) << file_->GetPath();
780   for (Elf_Word i = 0; i < GetSectionHeaderNum(); i++) {
781     Elf_Shdr* section_header = GetSectionHeader(i);
782     if (section_header->sh_type == type) {
783       return section_header;
784     }
785   }
786   return nullptr;
787 }
788 
789 // from bionic
elfhash(const char * _name)790 static unsigned elfhash(const char *_name) {
791   const unsigned char *name = (const unsigned char *) _name;
792   unsigned h = 0, g;
793 
794   while (*name) {
795     h = (h << 4) + *name++;
796     g = h & 0xf0000000;
797     h ^= g;
798     h ^= g >> 24;
799   }
800   return h;
801 }
802 
803 template <typename ElfTypes>
GetSectionNameStringSection() const804 typename ElfTypes::Shdr* ElfFileImpl<ElfTypes>::GetSectionNameStringSection() const {
805   return GetSectionHeader(GetHeader().e_shstrndx);
806 }
807 
808 template <typename ElfTypes>
FindDynamicSymbolAddress(const std::string & symbol_name) const809 const uint8_t* ElfFileImpl<ElfTypes>::FindDynamicSymbolAddress(
810     const std::string& symbol_name) const {
811   // Check that we have a hash section.
812   if (GetHashSectionStart() == nullptr) {
813     return nullptr;  // Failure condition.
814   }
815   const Elf_Sym* sym = FindDynamicSymbol(symbol_name);
816   if (sym != nullptr) {
817     // TODO: we need to change this to calculate base_address_ in ::Open,
818     // otherwise it will be wrongly 0 if ::Load has not yet been called.
819     return base_address_ + sym->st_value;
820   } else {
821     return nullptr;
822   }
823 }
824 
825 // WARNING: Only called from FindDynamicSymbolAddress. Elides check for hash section.
826 template <typename ElfTypes>
FindDynamicSymbol(const std::string & symbol_name) const827 const typename ElfTypes::Sym* ElfFileImpl<ElfTypes>::FindDynamicSymbol(
828     const std::string& symbol_name) const {
829   if (GetHashBucketNum() == 0) {
830     // No dynamic symbols at all.
831     return nullptr;
832   }
833   Elf_Word hash = elfhash(symbol_name.c_str());
834   Elf_Word bucket_index = hash % GetHashBucketNum();
835   bool ok;
836   Elf_Word symbol_and_chain_index = GetHashBucket(bucket_index, &ok);
837   if (!ok) {
838     return nullptr;
839   }
840   while (symbol_and_chain_index != 0 /* STN_UNDEF */) {
841     Elf_Sym* symbol = GetSymbol(SHT_DYNSYM, symbol_and_chain_index);
842     if (symbol == nullptr) {
843       return nullptr;  // Failure condition.
844     }
845     const char* name = GetString(SHT_DYNSYM, symbol->st_name);
846     if (symbol_name == name) {
847       return symbol;
848     }
849     symbol_and_chain_index = GetHashChain(symbol_and_chain_index, &ok);
850     if (!ok) {
851       return nullptr;
852     }
853   }
854   return nullptr;
855 }
856 
857 template <typename ElfTypes>
IsSymbolSectionType(Elf_Word section_type)858 bool ElfFileImpl<ElfTypes>::IsSymbolSectionType(Elf_Word section_type) {
859   return ((section_type == SHT_SYMTAB) || (section_type == SHT_DYNSYM));
860 }
861 
862 template <typename ElfTypes>
GetSymbolNum(Elf_Shdr & section_header) const863 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetSymbolNum(Elf_Shdr& section_header) const {
864   CHECK(IsSymbolSectionType(section_header.sh_type))
865       << file_->GetPath() << " " << section_header.sh_type;
866   CHECK_NE(0U, section_header.sh_entsize) << file_->GetPath();
867   return section_header.sh_size / section_header.sh_entsize;
868 }
869 
870 template <typename ElfTypes>
GetSymbol(Elf_Word section_type,Elf_Word i) const871 typename ElfTypes::Sym* ElfFileImpl<ElfTypes>::GetSymbol(Elf_Word section_type, Elf_Word i) const {
872   Elf_Sym* sym_start = GetSymbolSectionStart(section_type);
873   if (sym_start == nullptr) {
874     return nullptr;
875   }
876   return sym_start + i;
877 }
878 
879 template <typename ElfTypes>
880 typename ElfFileImpl<ElfTypes>::SymbolTable**
GetSymbolTable(Elf_Word section_type)881 ElfFileImpl<ElfTypes>::GetSymbolTable(Elf_Word section_type) {
882   CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type;
883   switch (section_type) {
884     case SHT_SYMTAB: {
885       return &symtab_symbol_table_;
886     }
887     case SHT_DYNSYM: {
888       return &dynsym_symbol_table_;
889     }
890     default: {
891       LOG(FATAL) << section_type;
892       return nullptr;
893     }
894   }
895 }
896 
897 template <typename ElfTypes>
FindSymbolByName(Elf_Word section_type,const std::string & symbol_name,bool build_map)898 typename ElfTypes::Sym* ElfFileImpl<ElfTypes>::FindSymbolByName(
899     Elf_Word section_type, const std::string& symbol_name, bool build_map) {
900   CHECK(!program_header_only_) << file_->GetPath();
901   CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type;
902 
903   SymbolTable** symbol_table = GetSymbolTable(section_type);
904   if (*symbol_table != nullptr || build_map) {
905     if (*symbol_table == nullptr) {
906       DCHECK(build_map);
907       *symbol_table = new SymbolTable;
908       Elf_Shdr* symbol_section = FindSectionByType(section_type);
909       if (symbol_section == nullptr) {
910         return nullptr;  // Failure condition.
911       }
912       Elf_Shdr* string_section = GetSectionHeader(symbol_section->sh_link);
913       if (string_section == nullptr) {
914         return nullptr;  // Failure condition.
915       }
916       for (uint32_t i = 0; i < GetSymbolNum(*symbol_section); i++) {
917         Elf_Sym* symbol = GetSymbol(section_type, i);
918         if (symbol == nullptr) {
919           return nullptr;  // Failure condition.
920         }
921         unsigned char type = (sizeof(Elf_Addr) == sizeof(Elf64_Addr))
922                              ? ELF64_ST_TYPE(symbol->st_info)
923                              : ELF32_ST_TYPE(symbol->st_info);
924         if (type == STT_NOTYPE) {
925           continue;
926         }
927         const char* name = GetString(*string_section, symbol->st_name);
928         if (name == nullptr) {
929           continue;
930         }
931         std::pair<typename SymbolTable::iterator, bool> result =
932             (*symbol_table)->insert(std::make_pair(name, symbol));
933         if (!result.second) {
934           // If a duplicate, make sure it has the same logical value. Seen on x86.
935           if ((symbol->st_value != result.first->second->st_value) ||
936               (symbol->st_size != result.first->second->st_size) ||
937               (symbol->st_info != result.first->second->st_info) ||
938               (symbol->st_other != result.first->second->st_other) ||
939               (symbol->st_shndx != result.first->second->st_shndx)) {
940             return nullptr;  // Failure condition.
941           }
942         }
943       }
944     }
945     CHECK(*symbol_table != nullptr);
946     typename SymbolTable::const_iterator it = (*symbol_table)->find(symbol_name);
947     if (it == (*symbol_table)->end()) {
948       return nullptr;
949     }
950     return it->second;
951   }
952 
953   // Fall back to linear search
954   Elf_Shdr* symbol_section = FindSectionByType(section_type);
955   if (symbol_section == nullptr) {
956     return nullptr;
957   }
958   Elf_Shdr* string_section = GetSectionHeader(symbol_section->sh_link);
959   if (string_section == nullptr) {
960     return nullptr;
961   }
962   for (uint32_t i = 0; i < GetSymbolNum(*symbol_section); i++) {
963     Elf_Sym* symbol = GetSymbol(section_type, i);
964     if (symbol == nullptr) {
965       return nullptr;  // Failure condition.
966     }
967     const char* name = GetString(*string_section, symbol->st_name);
968     if (name == nullptr) {
969       continue;
970     }
971     if (symbol_name == name) {
972       return symbol;
973     }
974   }
975   return nullptr;
976 }
977 
978 template <typename ElfTypes>
FindSymbolAddress(Elf_Word section_type,const std::string & symbol_name,bool build_map)979 typename ElfTypes::Addr ElfFileImpl<ElfTypes>::FindSymbolAddress(
980     Elf_Word section_type, const std::string& symbol_name, bool build_map) {
981   Elf_Sym* symbol = FindSymbolByName(section_type, symbol_name, build_map);
982   if (symbol == nullptr) {
983     return 0;
984   }
985   return symbol->st_value;
986 }
987 
988 template <typename ElfTypes>
GetString(Elf_Shdr & string_section,Elf_Word i) const989 const char* ElfFileImpl<ElfTypes>::GetString(Elf_Shdr& string_section,
990                                              Elf_Word i) const {
991   CHECK(!program_header_only_) << file_->GetPath();
992   // TODO: remove this static_cast from enum when using -std=gnu++0x
993   if (static_cast<Elf_Word>(SHT_STRTAB) != string_section.sh_type) {
994     return nullptr;  // Failure condition.
995   }
996   if (i >= string_section.sh_size) {
997     return nullptr;
998   }
999   if (i == 0) {
1000     return nullptr;
1001   }
1002   uint8_t* strings = Begin() + string_section.sh_offset;
1003   uint8_t* string = strings + i;
1004   if (string >= End()) {
1005     return nullptr;
1006   }
1007   return reinterpret_cast<const char*>(string);
1008 }
1009 
1010 template <typename ElfTypes>
GetDynamicNum() const1011 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetDynamicNum() const {
1012   return GetDynamicProgramHeader().p_filesz / sizeof(Elf_Dyn);
1013 }
1014 
1015 template <typename ElfTypes>
GetDynamic(Elf_Word i) const1016 typename ElfTypes::Dyn& ElfFileImpl<ElfTypes>::GetDynamic(Elf_Word i) const {
1017   CHECK_LT(i, GetDynamicNum()) << file_->GetPath();
1018   return *(GetDynamicSectionStart() + i);
1019 }
1020 
1021 template <typename ElfTypes>
FindDynamicByType(Elf_Sword type) const1022 typename ElfTypes::Dyn* ElfFileImpl<ElfTypes>::FindDynamicByType(Elf_Sword type) const {
1023   for (Elf_Word i = 0; i < GetDynamicNum(); i++) {
1024     Elf_Dyn* dyn = &GetDynamic(i);
1025     if (dyn->d_tag == type) {
1026       return dyn;
1027     }
1028   }
1029   return nullptr;
1030 }
1031 
1032 template <typename ElfTypes>
FindDynamicValueByType(Elf_Sword type) const1033 typename ElfTypes::Word ElfFileImpl<ElfTypes>::FindDynamicValueByType(Elf_Sword type) const {
1034   Elf_Dyn* dyn = FindDynamicByType(type);
1035   if (dyn == nullptr) {
1036     return 0;
1037   } else {
1038     return dyn->d_un.d_val;
1039   }
1040 }
1041 
1042 template <typename ElfTypes>
GetRelSectionStart(Elf_Shdr & section_header) const1043 typename ElfTypes::Rel* ElfFileImpl<ElfTypes>::GetRelSectionStart(Elf_Shdr& section_header) const {
1044   CHECK(SHT_REL == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
1045   return reinterpret_cast<Elf_Rel*>(Begin() + section_header.sh_offset);
1046 }
1047 
1048 template <typename ElfTypes>
GetRelNum(Elf_Shdr & section_header) const1049 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetRelNum(Elf_Shdr& section_header) const {
1050   CHECK(SHT_REL == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
1051   CHECK_NE(0U, section_header.sh_entsize) << file_->GetPath();
1052   return section_header.sh_size / section_header.sh_entsize;
1053 }
1054 
1055 template <typename ElfTypes>
GetRel(Elf_Shdr & section_header,Elf_Word i) const1056 typename ElfTypes::Rel& ElfFileImpl<ElfTypes>::GetRel(Elf_Shdr& section_header, Elf_Word i) const {
1057   CHECK(SHT_REL == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
1058   CHECK_LT(i, GetRelNum(section_header)) << file_->GetPath();
1059   return *(GetRelSectionStart(section_header) + i);
1060 }
1061 
1062 template <typename ElfTypes>
GetRelaSectionStart(Elf_Shdr & section_header) const1063 typename ElfTypes::Rela* ElfFileImpl<ElfTypes>::GetRelaSectionStart(Elf_Shdr& section_header) const {
1064   CHECK(SHT_RELA == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
1065   return reinterpret_cast<Elf_Rela*>(Begin() + section_header.sh_offset);
1066 }
1067 
1068 template <typename ElfTypes>
GetRelaNum(Elf_Shdr & section_header) const1069 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetRelaNum(Elf_Shdr& section_header) const {
1070   CHECK(SHT_RELA == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
1071   return section_header.sh_size / section_header.sh_entsize;
1072 }
1073 
1074 template <typename ElfTypes>
GetRela(Elf_Shdr & section_header,Elf_Word i) const1075 typename ElfTypes::Rela& ElfFileImpl<ElfTypes>::GetRela(Elf_Shdr& section_header, Elf_Word i) const {
1076   CHECK(SHT_RELA == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
1077   CHECK_LT(i, GetRelaNum(section_header)) << file_->GetPath();
1078   return *(GetRelaSectionStart(section_header) + i);
1079 }
1080 
1081 // Base on bionic phdr_table_get_load_size
1082 template <typename ElfTypes>
GetLoadedSize(size_t * size,std::string * error_msg) const1083 bool ElfFileImpl<ElfTypes>::GetLoadedSize(size_t* size, std::string* error_msg) const {
1084   Elf_Addr min_vaddr = static_cast<Elf_Addr>(-1);
1085   Elf_Addr max_vaddr = 0u;
1086   for (Elf_Word i = 0; i < GetProgramHeaderNum(); i++) {
1087     Elf_Phdr* program_header = GetProgramHeader(i);
1088     if (program_header->p_type != PT_LOAD) {
1089       continue;
1090     }
1091     Elf_Addr begin_vaddr = program_header->p_vaddr;
1092     if (begin_vaddr < min_vaddr) {
1093        min_vaddr = begin_vaddr;
1094     }
1095     Elf_Addr end_vaddr = program_header->p_vaddr + program_header->p_memsz;
1096     if (UNLIKELY(begin_vaddr > end_vaddr)) {
1097       std::ostringstream oss;
1098       oss << "Program header #" << i << " has overflow in p_vaddr+p_memsz: 0x" << std::hex
1099           << program_header->p_vaddr << "+0x" << program_header->p_memsz << "=0x" << end_vaddr
1100           << " in ELF file \"" << file_->GetPath() << "\"";
1101       *error_msg = oss.str();
1102       *size = static_cast<size_t>(-1);
1103       return false;
1104     }
1105     if (end_vaddr > max_vaddr) {
1106       max_vaddr = end_vaddr;
1107     }
1108   }
1109   min_vaddr = RoundDown(min_vaddr, kPageSize);
1110   max_vaddr = RoundUp(max_vaddr, kPageSize);
1111   CHECK_LT(min_vaddr, max_vaddr) << file_->GetPath();
1112   Elf_Addr loaded_size = max_vaddr - min_vaddr;
1113   // Check that the loaded_size fits in size_t.
1114   if (UNLIKELY(loaded_size > std::numeric_limits<size_t>::max())) {
1115     std::ostringstream oss;
1116     oss << "Loaded size is 0x" << std::hex << loaded_size << " but maximum size_t is 0x"
1117         << std::numeric_limits<size_t>::max() << " for ELF file \"" << file_->GetPath() << "\"";
1118     *error_msg = oss.str();
1119     *size = static_cast<size_t>(-1);
1120     return false;
1121   }
1122   *size = loaded_size;
1123   return true;
1124 }
1125 
1126 template <typename ElfTypes>
Load(bool executable,std::string * error_msg)1127 bool ElfFileImpl<ElfTypes>::Load(bool executable, std::string* error_msg) {
1128   CHECK(program_header_only_) << file_->GetPath();
1129 
1130   if (executable) {
1131     InstructionSet elf_ISA = GetInstructionSetFromELF(GetHeader().e_machine, GetHeader().e_flags);
1132     if (elf_ISA != kRuntimeISA) {
1133       std::ostringstream oss;
1134       oss << "Expected ISA " << kRuntimeISA << " but found " << elf_ISA;
1135       *error_msg = oss.str();
1136       return false;
1137     }
1138   }
1139 
1140   bool reserved = false;
1141   for (Elf_Word i = 0; i < GetProgramHeaderNum(); i++) {
1142     Elf_Phdr* program_header = GetProgramHeader(i);
1143     if (program_header == nullptr) {
1144       *error_msg = StringPrintf("No program header for entry %d in ELF file %s.",
1145                                 i, file_->GetPath().c_str());
1146       return false;
1147     }
1148 
1149     // Record .dynamic header information for later use
1150     if (program_header->p_type == PT_DYNAMIC) {
1151       dynamic_program_header_ = program_header;
1152       continue;
1153     }
1154 
1155     // Not something to load, move on.
1156     if (program_header->p_type != PT_LOAD) {
1157       continue;
1158     }
1159 
1160     // Found something to load.
1161 
1162     // Before load the actual segments, reserve a contiguous chunk
1163     // of required size and address for all segments, but with no
1164     // permissions. We'll then carve that up with the proper
1165     // permissions as we load the actual segments. If p_vaddr is
1166     // non-zero, the segments require the specific address specified,
1167     // which either was specified in the file because we already set
1168     // base_address_ after the first zero segment).
1169     int64_t temp_file_length = file_->GetLength();
1170     if (temp_file_length < 0) {
1171       errno = -temp_file_length;
1172       *error_msg = StringPrintf("Failed to get length of file: '%s' fd=%d: %s",
1173                                 file_->GetPath().c_str(), file_->Fd(), strerror(errno));
1174       return false;
1175     }
1176     size_t file_length = static_cast<size_t>(temp_file_length);
1177     if (!reserved) {
1178       uint8_t* reserve_base = reinterpret_cast<uint8_t*>(program_header->p_vaddr);
1179       uint8_t* reserve_base_override = reserve_base;
1180       // Override the base (e.g. when compiling with --compile-pic)
1181       if (requested_base_ != nullptr) {
1182         reserve_base_override = requested_base_;
1183       }
1184       std::string reservation_name("ElfFile reservation for ");
1185       reservation_name += file_->GetPath();
1186       size_t loaded_size;
1187       if (!GetLoadedSize(&loaded_size, error_msg)) {
1188         DCHECK(!error_msg->empty());
1189         return false;
1190       }
1191       std::unique_ptr<MemMap> reserve(MemMap::MapAnonymous(reservation_name.c_str(),
1192                                                            reserve_base_override,
1193                                                            loaded_size, PROT_NONE, false, false,
1194                                                            error_msg));
1195       if (reserve.get() == nullptr) {
1196         *error_msg = StringPrintf("Failed to allocate %s: %s",
1197                                   reservation_name.c_str(), error_msg->c_str());
1198         return false;
1199       }
1200       reserved = true;
1201 
1202       // Base address is the difference of actual mapped location and the p_vaddr
1203       base_address_ = reinterpret_cast<uint8_t*>(reinterpret_cast<uintptr_t>(reserve->Begin())
1204                        - reinterpret_cast<uintptr_t>(reserve_base));
1205       // By adding the p_vaddr of a section/symbol to base_address_ we will always get the
1206       // dynamic memory address of where that object is actually mapped
1207       //
1208       // TODO: base_address_ needs to be calculated in ::Open, otherwise
1209       // FindDynamicSymbolAddress returns the wrong values until Load is called.
1210       segments_.push_back(reserve.release());
1211     }
1212     // empty segment, nothing to map
1213     if (program_header->p_memsz == 0) {
1214       continue;
1215     }
1216     uint8_t* p_vaddr = base_address_ + program_header->p_vaddr;
1217     int prot = 0;
1218     if (executable && ((program_header->p_flags & PF_X) != 0)) {
1219       prot |= PROT_EXEC;
1220     }
1221     if ((program_header->p_flags & PF_W) != 0) {
1222       prot |= PROT_WRITE;
1223     }
1224     if ((program_header->p_flags & PF_R) != 0) {
1225       prot |= PROT_READ;
1226     }
1227     int flags = 0;
1228     if (writable_) {
1229       prot |= PROT_WRITE;
1230       flags |= MAP_SHARED;
1231     } else {
1232       flags |= MAP_PRIVATE;
1233     }
1234     if (program_header->p_filesz > program_header->p_memsz) {
1235       *error_msg = StringPrintf("Invalid p_filesz > p_memsz (%" PRIu64 " > %" PRIu64 "): %s",
1236                                 static_cast<uint64_t>(program_header->p_filesz),
1237                                 static_cast<uint64_t>(program_header->p_memsz),
1238                                 file_->GetPath().c_str());
1239       return false;
1240     }
1241     if (program_header->p_filesz < program_header->p_memsz &&
1242         !IsAligned<kPageSize>(program_header->p_filesz)) {
1243       *error_msg = StringPrintf("Unsupported unaligned p_filesz < p_memsz (%" PRIu64
1244                                 " < %" PRIu64 "): %s",
1245                                 static_cast<uint64_t>(program_header->p_filesz),
1246                                 static_cast<uint64_t>(program_header->p_memsz),
1247                                 file_->GetPath().c_str());
1248       return false;
1249     }
1250     if (file_length < (program_header->p_offset + program_header->p_filesz)) {
1251       *error_msg = StringPrintf("File size of %zd bytes not large enough to contain ELF segment "
1252                                 "%d of %" PRIu64 " bytes: '%s'", file_length, i,
1253                                 static_cast<uint64_t>(program_header->p_offset + program_header->p_filesz),
1254                                 file_->GetPath().c_str());
1255       return false;
1256     }
1257     if (program_header->p_filesz != 0u) {
1258       std::unique_ptr<MemMap> segment(
1259           MemMap::MapFileAtAddress(p_vaddr,
1260                                    program_header->p_filesz,
1261                                    prot, flags, file_->Fd(),
1262                                    program_header->p_offset,
1263                                    true,  // implies MAP_FIXED
1264                                    file_->GetPath().c_str(),
1265                                    error_msg));
1266       if (segment.get() == nullptr) {
1267         *error_msg = StringPrintf("Failed to map ELF file segment %d from %s: %s",
1268                                   i, file_->GetPath().c_str(), error_msg->c_str());
1269         return false;
1270       }
1271       if (segment->Begin() != p_vaddr) {
1272         *error_msg = StringPrintf("Failed to map ELF file segment %d from %s at expected address %p, "
1273                                   "instead mapped to %p",
1274                                   i, file_->GetPath().c_str(), p_vaddr, segment->Begin());
1275         return false;
1276       }
1277       segments_.push_back(segment.release());
1278     }
1279     if (program_header->p_filesz < program_header->p_memsz) {
1280       std::string name = StringPrintf("Zero-initialized segment %" PRIu64 " of ELF file %s",
1281                                       static_cast<uint64_t>(i), file_->GetPath().c_str());
1282       std::unique_ptr<MemMap> segment(
1283           MemMap::MapAnonymous(name.c_str(),
1284                                p_vaddr + program_header->p_filesz,
1285                                program_header->p_memsz - program_header->p_filesz,
1286                                prot, false, true /* reuse */, error_msg));
1287       if (segment == nullptr) {
1288         *error_msg = StringPrintf("Failed to map zero-initialized ELF file segment %d from %s: %s",
1289                                   i, file_->GetPath().c_str(), error_msg->c_str());
1290         return false;
1291       }
1292       if (segment->Begin() != p_vaddr) {
1293         *error_msg = StringPrintf("Failed to map zero-initialized ELF file segment %d from %s "
1294                                   "at expected address %p, instead mapped to %p",
1295                                   i, file_->GetPath().c_str(), p_vaddr, segment->Begin());
1296         return false;
1297       }
1298       segments_.push_back(segment.release());
1299     }
1300   }
1301 
1302   // Now that we are done loading, .dynamic should be in memory to find .dynstr, .dynsym, .hash
1303   uint8_t* dsptr = base_address_ + GetDynamicProgramHeader().p_vaddr;
1304   if ((dsptr < Begin() || dsptr >= End()) && !ValidPointer(dsptr)) {
1305     *error_msg = StringPrintf("dynamic section address invalid in ELF file %s",
1306                               file_->GetPath().c_str());
1307     return false;
1308   }
1309   dynamic_section_start_ = reinterpret_cast<Elf_Dyn*>(dsptr);
1310 
1311   for (Elf_Word i = 0; i < GetDynamicNum(); i++) {
1312     Elf_Dyn& elf_dyn = GetDynamic(i);
1313     uint8_t* d_ptr = base_address_ + elf_dyn.d_un.d_ptr;
1314     switch (elf_dyn.d_tag) {
1315       case DT_HASH: {
1316         if (!ValidPointer(d_ptr)) {
1317           *error_msg = StringPrintf("DT_HASH value %p does not refer to a loaded ELF segment of %s",
1318                                     d_ptr, file_->GetPath().c_str());
1319           return false;
1320         }
1321         hash_section_start_ = reinterpret_cast<Elf_Word*>(d_ptr);
1322         break;
1323       }
1324       case DT_STRTAB: {
1325         if (!ValidPointer(d_ptr)) {
1326           *error_msg = StringPrintf("DT_HASH value %p does not refer to a loaded ELF segment of %s",
1327                                     d_ptr, file_->GetPath().c_str());
1328           return false;
1329         }
1330         dynstr_section_start_ = reinterpret_cast<char*>(d_ptr);
1331         break;
1332       }
1333       case DT_SYMTAB: {
1334         if (!ValidPointer(d_ptr)) {
1335           *error_msg = StringPrintf("DT_HASH value %p does not refer to a loaded ELF segment of %s",
1336                                     d_ptr, file_->GetPath().c_str());
1337           return false;
1338         }
1339         dynsym_section_start_ = reinterpret_cast<Elf_Sym*>(d_ptr);
1340         break;
1341       }
1342       case DT_NULL: {
1343         if (GetDynamicNum() != i+1) {
1344           *error_msg = StringPrintf("DT_NULL found after %d .dynamic entries, "
1345                                     "expected %d as implied by size of PT_DYNAMIC segment in %s",
1346                                     i + 1, GetDynamicNum(), file_->GetPath().c_str());
1347           return false;
1348         }
1349         break;
1350       }
1351     }
1352   }
1353 
1354   // Check for the existence of some sections.
1355   if (!CheckSectionsExist(error_msg)) {
1356     return false;
1357   }
1358 
1359   // Use GDB JIT support to do stack backtrace, etc.
1360   if (executable) {
1361     GdbJITSupport();
1362   }
1363 
1364   return true;
1365 }
1366 
1367 template <typename ElfTypes>
ValidPointer(const uint8_t * start) const1368 bool ElfFileImpl<ElfTypes>::ValidPointer(const uint8_t* start) const {
1369   for (size_t i = 0; i < segments_.size(); ++i) {
1370     const MemMap* segment = segments_[i];
1371     if (segment->Begin() <= start && start < segment->End()) {
1372       return true;
1373     }
1374   }
1375   return false;
1376 }
1377 
1378 
1379 template <typename ElfTypes>
FindSectionByName(const std::string & name) const1380 typename ElfTypes::Shdr* ElfFileImpl<ElfTypes>::FindSectionByName(
1381     const std::string& name) const {
1382   CHECK(!program_header_only_);
1383   Elf_Shdr* shstrtab_sec = GetSectionNameStringSection();
1384   if (shstrtab_sec == nullptr) {
1385     return nullptr;
1386   }
1387   for (uint32_t i = 0; i < GetSectionHeaderNum(); i++) {
1388     Elf_Shdr* shdr = GetSectionHeader(i);
1389     if (shdr == nullptr) {
1390       return nullptr;
1391     }
1392     const char* sec_name = GetString(*shstrtab_sec, shdr->sh_name);
1393     if (sec_name == nullptr) {
1394       continue;
1395     }
1396     if (name == sec_name) {
1397       return shdr;
1398     }
1399   }
1400   return nullptr;
1401 }
1402 
1403 template <typename ElfTypes>
FixupDebugSections(Elf_Addr base_address_delta)1404 bool ElfFileImpl<ElfTypes>::FixupDebugSections(Elf_Addr base_address_delta) {
1405   if (base_address_delta == 0) {
1406     return true;
1407   }
1408   return ApplyOatPatchesTo(".debug_frame", base_address_delta) &&
1409          ApplyOatPatchesTo(".debug_info", base_address_delta) &&
1410          ApplyOatPatchesTo(".debug_line", base_address_delta);
1411 }
1412 
1413 template <typename ElfTypes>
ApplyOatPatchesTo(const char * target_section_name,Elf_Addr delta)1414 bool ElfFileImpl<ElfTypes>::ApplyOatPatchesTo(
1415     const char* target_section_name, Elf_Addr delta) {
1416   auto target_section = FindSectionByName(target_section_name);
1417   if (target_section == nullptr) {
1418     return true;
1419   }
1420   std::string patches_name = target_section_name + std::string(".oat_patches");
1421   auto patches_section = FindSectionByName(patches_name.c_str());
1422   if (patches_section == nullptr) {
1423     LOG(ERROR) << patches_name << " section not found.";
1424     return false;
1425   }
1426   if (patches_section->sh_type != SHT_OAT_PATCH) {
1427     LOG(ERROR) << "Unexpected type of " << patches_name;
1428     return false;
1429   }
1430   ApplyOatPatches(
1431       Begin() + patches_section->sh_offset,
1432       Begin() + patches_section->sh_offset + patches_section->sh_size,
1433       delta,
1434       Begin() + target_section->sh_offset,
1435       Begin() + target_section->sh_offset + target_section->sh_size);
1436   return true;
1437 }
1438 
1439 // Apply LEB128 encoded patches to given section.
1440 template <typename ElfTypes>
ApplyOatPatches(const uint8_t * patches,const uint8_t * patches_end,Elf_Addr delta,uint8_t * to_patch,const uint8_t * to_patch_end)1441 void ElfFileImpl<ElfTypes>::ApplyOatPatches(
1442     const uint8_t* patches, const uint8_t* patches_end, Elf_Addr delta,
1443     uint8_t* to_patch, const uint8_t* to_patch_end) {
1444   typedef __attribute__((__aligned__(1))) Elf_Addr UnalignedAddress;
1445   while (patches < patches_end) {
1446     to_patch += DecodeUnsignedLeb128(&patches);
1447     DCHECK_LE(patches, patches_end) << "Unexpected end of patch list.";
1448     DCHECK_LT(to_patch, to_patch_end) << "Patch past the end of section.";
1449     *reinterpret_cast<UnalignedAddress*>(to_patch) += delta;
1450   }
1451 }
1452 
1453 template <typename ElfTypes>
GdbJITSupport()1454 void ElfFileImpl<ElfTypes>::GdbJITSupport() {
1455   // We only get here if we only are mapping the program header.
1456   DCHECK(program_header_only_);
1457 
1458   // Well, we need the whole file to do this.
1459   std::string error_msg;
1460   // Make it MAP_PRIVATE so we can just give it to gdb if all the necessary
1461   // sections are there.
1462   std::unique_ptr<ElfFileImpl<ElfTypes>> all_ptr(
1463       Open(const_cast<File*>(file_), PROT_READ | PROT_WRITE, MAP_PRIVATE, &error_msg));
1464   if (all_ptr.get() == nullptr) {
1465     return;
1466   }
1467   ElfFileImpl<ElfTypes>& all = *all_ptr;
1468 
1469   // We need the eh_frame for gdb but debug info might be present without it.
1470   const Elf_Shdr* eh_frame = all.FindSectionByName(".eh_frame");
1471   if (eh_frame == nullptr) {
1472     return;
1473   }
1474 
1475   // Do we have interesting sections?
1476   // We need to add in a strtab and symtab to the image.
1477   // all is MAP_PRIVATE so it can be written to freely.
1478   // We also already have strtab and symtab so we are fine there.
1479   Elf_Ehdr& elf_hdr = all.GetHeader();
1480   elf_hdr.e_entry = 0;
1481   elf_hdr.e_phoff = 0;
1482   elf_hdr.e_phnum = 0;
1483   elf_hdr.e_phentsize = 0;
1484   elf_hdr.e_type = ET_EXEC;
1485 
1486   // Since base_address_ is 0 if we are actually loaded at a known address (i.e. this is boot.oat)
1487   // and the actual address stuff starts at in regular files this is good.
1488   if (!all.FixupDebugSections(reinterpret_cast<intptr_t>(base_address_))) {
1489     LOG(ERROR) << "Failed to load GDB data";
1490     return;
1491   }
1492 
1493   jit_gdb_entry_ = CreateCodeEntry(all.Begin(), all.Size());
1494   gdb_file_mapping_.reset(all_ptr.release());
1495 }
1496 
1497 template <typename ElfTypes>
Strip(std::string * error_msg)1498 bool ElfFileImpl<ElfTypes>::Strip(std::string* error_msg) {
1499   // ELF files produced by MCLinker look roughly like this
1500   //
1501   // +------------+
1502   // | Elf_Ehdr   | contains number of Elf_Shdr and offset to first
1503   // +------------+
1504   // | Elf_Phdr   | program headers
1505   // | Elf_Phdr   |
1506   // | ...        |
1507   // | Elf_Phdr   |
1508   // +------------+
1509   // | section    | mixture of needed and unneeded sections
1510   // +------------+
1511   // | section    |
1512   // +------------+
1513   // | ...        |
1514   // +------------+
1515   // | section    |
1516   // +------------+
1517   // | Elf_Shdr   | section headers
1518   // | Elf_Shdr   |
1519   // | ...        | contains offset to section start
1520   // | Elf_Shdr   |
1521   // +------------+
1522   //
1523   // To strip:
1524   // - leave the Elf_Ehdr and Elf_Phdr values in place.
1525   // - walk the sections making a new set of Elf_Shdr section headers for what we want to keep
1526   // - move the sections are keeping up to fill in gaps of sections we want to strip
1527   // - write new Elf_Shdr section headers to end of file, updating Elf_Ehdr
1528   // - truncate rest of file
1529   //
1530 
1531   std::vector<Elf_Shdr> section_headers;
1532   std::vector<Elf_Word> section_headers_original_indexes;
1533   section_headers.reserve(GetSectionHeaderNum());
1534 
1535 
1536   Elf_Shdr* string_section = GetSectionNameStringSection();
1537   CHECK(string_section != nullptr);
1538   for (Elf_Word i = 0; i < GetSectionHeaderNum(); i++) {
1539     Elf_Shdr* sh = GetSectionHeader(i);
1540     CHECK(sh != nullptr);
1541     const char* name = GetString(*string_section, sh->sh_name);
1542     if (name == nullptr) {
1543       CHECK_EQ(0U, i);
1544       section_headers.push_back(*sh);
1545       section_headers_original_indexes.push_back(0);
1546       continue;
1547     }
1548     if (StartsWith(name, ".debug")
1549         || (strcmp(name, ".strtab") == 0)
1550         || (strcmp(name, ".symtab") == 0)) {
1551       continue;
1552     }
1553     section_headers.push_back(*sh);
1554     section_headers_original_indexes.push_back(i);
1555   }
1556   CHECK_NE(0U, section_headers.size());
1557   CHECK_EQ(section_headers.size(), section_headers_original_indexes.size());
1558 
1559   // section 0 is the null section, sections start at offset of first section
1560   CHECK(GetSectionHeader(1) != nullptr);
1561   Elf_Off offset = GetSectionHeader(1)->sh_offset;
1562   for (size_t i = 1; i < section_headers.size(); i++) {
1563     Elf_Shdr& new_sh = section_headers[i];
1564     Elf_Shdr* old_sh = GetSectionHeader(section_headers_original_indexes[i]);
1565     CHECK(old_sh != nullptr);
1566     CHECK_EQ(new_sh.sh_name, old_sh->sh_name);
1567     if (old_sh->sh_addralign > 1) {
1568       offset = RoundUp(offset, old_sh->sh_addralign);
1569     }
1570     if (old_sh->sh_offset == offset) {
1571       // already in place
1572       offset += old_sh->sh_size;
1573       continue;
1574     }
1575     // shift section earlier
1576     memmove(Begin() + offset,
1577             Begin() + old_sh->sh_offset,
1578             old_sh->sh_size);
1579     new_sh.sh_offset = offset;
1580     offset += old_sh->sh_size;
1581   }
1582 
1583   Elf_Off shoff = offset;
1584   size_t section_headers_size_in_bytes = section_headers.size() * sizeof(Elf_Shdr);
1585   memcpy(Begin() + offset, &section_headers[0], section_headers_size_in_bytes);
1586   offset += section_headers_size_in_bytes;
1587 
1588   GetHeader().e_shnum = section_headers.size();
1589   GetHeader().e_shoff = shoff;
1590   int result = ftruncate(file_->Fd(), offset);
1591   if (result != 0) {
1592     *error_msg = StringPrintf("Failed to truncate while stripping ELF file: '%s': %s",
1593                               file_->GetPath().c_str(), strerror(errno));
1594     return false;
1595   }
1596   return true;
1597 }
1598 
1599 static const bool DEBUG_FIXUP = false;
1600 
1601 template <typename ElfTypes>
Fixup(Elf_Addr base_address)1602 bool ElfFileImpl<ElfTypes>::Fixup(Elf_Addr base_address) {
1603   if (!FixupDynamic(base_address)) {
1604     LOG(WARNING) << "Failed to fixup .dynamic in " << file_->GetPath();
1605     return false;
1606   }
1607   if (!FixupSectionHeaders(base_address)) {
1608     LOG(WARNING) << "Failed to fixup section headers in " << file_->GetPath();
1609     return false;
1610   }
1611   if (!FixupProgramHeaders(base_address)) {
1612     LOG(WARNING) << "Failed to fixup program headers in " << file_->GetPath();
1613     return false;
1614   }
1615   if (!FixupSymbols(base_address, true)) {
1616     LOG(WARNING) << "Failed to fixup .dynsym in " << file_->GetPath();
1617     return false;
1618   }
1619   if (!FixupSymbols(base_address, false)) {
1620     LOG(WARNING) << "Failed to fixup .symtab in " << file_->GetPath();
1621     return false;
1622   }
1623   if (!FixupRelocations(base_address)) {
1624     LOG(WARNING) << "Failed to fixup .rel.dyn in " << file_->GetPath();
1625     return false;
1626   }
1627   static_assert(sizeof(Elf_Off) >= sizeof(base_address), "Potentially losing precision.");
1628   if (!FixupDebugSections(static_cast<Elf_Off>(base_address))) {
1629     LOG(WARNING) << "Failed to fixup debug sections in " << file_->GetPath();
1630     return false;
1631   }
1632   return true;
1633 }
1634 
1635 template <typename ElfTypes>
FixupDynamic(Elf_Addr base_address)1636 bool ElfFileImpl<ElfTypes>::FixupDynamic(Elf_Addr base_address) {
1637   for (Elf_Word i = 0; i < GetDynamicNum(); i++) {
1638     Elf_Dyn& elf_dyn = GetDynamic(i);
1639     Elf_Word d_tag = elf_dyn.d_tag;
1640     if (IsDynamicSectionPointer(d_tag, GetHeader().e_machine)) {
1641       Elf_Addr d_ptr = elf_dyn.d_un.d_ptr;
1642       if (DEBUG_FIXUP) {
1643         LOG(INFO) << StringPrintf("In %s moving Elf_Dyn[%d] from 0x%" PRIx64 " to 0x%" PRIx64,
1644                                   GetFile().GetPath().c_str(), i,
1645                                   static_cast<uint64_t>(d_ptr),
1646                                   static_cast<uint64_t>(d_ptr + base_address));
1647       }
1648       d_ptr += base_address;
1649       elf_dyn.d_un.d_ptr = d_ptr;
1650     }
1651   }
1652   return true;
1653 }
1654 
1655 template <typename ElfTypes>
FixupSectionHeaders(Elf_Addr base_address)1656 bool ElfFileImpl<ElfTypes>::FixupSectionHeaders(Elf_Addr base_address) {
1657   for (Elf_Word i = 0; i < GetSectionHeaderNum(); i++) {
1658     Elf_Shdr* sh = GetSectionHeader(i);
1659     CHECK(sh != nullptr);
1660     // 0 implies that the section will not exist in the memory of the process
1661     if (sh->sh_addr == 0) {
1662       continue;
1663     }
1664     if (DEBUG_FIXUP) {
1665       LOG(INFO) << StringPrintf("In %s moving Elf_Shdr[%d] from 0x%" PRIx64 " to 0x%" PRIx64,
1666                                 GetFile().GetPath().c_str(), i,
1667                                 static_cast<uint64_t>(sh->sh_addr),
1668                                 static_cast<uint64_t>(sh->sh_addr + base_address));
1669     }
1670     sh->sh_addr += base_address;
1671   }
1672   return true;
1673 }
1674 
1675 template <typename ElfTypes>
FixupProgramHeaders(Elf_Addr base_address)1676 bool ElfFileImpl<ElfTypes>::FixupProgramHeaders(Elf_Addr base_address) {
1677   // TODO: ELFObjectFile doesn't have give to Elf_Phdr, so we do that ourselves for now.
1678   for (Elf_Word i = 0; i < GetProgramHeaderNum(); i++) {
1679     Elf_Phdr* ph = GetProgramHeader(i);
1680     CHECK(ph != nullptr);
1681     CHECK_EQ(ph->p_vaddr, ph->p_paddr) << GetFile().GetPath() << " i=" << i;
1682     CHECK((ph->p_align == 0) || (0 == ((ph->p_vaddr - ph->p_offset) & (ph->p_align - 1))))
1683             << GetFile().GetPath() << " i=" << i;
1684     if (DEBUG_FIXUP) {
1685       LOG(INFO) << StringPrintf("In %s moving Elf_Phdr[%d] from 0x%" PRIx64 " to 0x%" PRIx64,
1686                                 GetFile().GetPath().c_str(), i,
1687                                 static_cast<uint64_t>(ph->p_vaddr),
1688                                 static_cast<uint64_t>(ph->p_vaddr + base_address));
1689     }
1690     ph->p_vaddr += base_address;
1691     ph->p_paddr += base_address;
1692     CHECK((ph->p_align == 0) || (0 == ((ph->p_vaddr - ph->p_offset) & (ph->p_align - 1))))
1693             << GetFile().GetPath() << " i=" << i;
1694   }
1695   return true;
1696 }
1697 
1698 template <typename ElfTypes>
FixupSymbols(Elf_Addr base_address,bool dynamic)1699 bool ElfFileImpl<ElfTypes>::FixupSymbols(Elf_Addr base_address, bool dynamic) {
1700   Elf_Word section_type = dynamic ? SHT_DYNSYM : SHT_SYMTAB;
1701   // TODO: Unfortunate ELFObjectFile has protected symbol access, so use ElfFile
1702   Elf_Shdr* symbol_section = FindSectionByType(section_type);
1703   if (symbol_section == nullptr) {
1704     // file is missing optional .symtab
1705     CHECK(!dynamic) << GetFile().GetPath();
1706     return true;
1707   }
1708   for (uint32_t i = 0; i < GetSymbolNum(*symbol_section); i++) {
1709     Elf_Sym* symbol = GetSymbol(section_type, i);
1710     CHECK(symbol != nullptr);
1711     if (symbol->st_value != 0) {
1712       if (DEBUG_FIXUP) {
1713         LOG(INFO) << StringPrintf("In %s moving Elf_Sym[%d] from 0x%" PRIx64 " to 0x%" PRIx64,
1714                                   GetFile().GetPath().c_str(), i,
1715                                   static_cast<uint64_t>(symbol->st_value),
1716                                   static_cast<uint64_t>(symbol->st_value + base_address));
1717       }
1718       symbol->st_value += base_address;
1719     }
1720   }
1721   return true;
1722 }
1723 
1724 template <typename ElfTypes>
FixupRelocations(Elf_Addr base_address)1725 bool ElfFileImpl<ElfTypes>::FixupRelocations(Elf_Addr base_address) {
1726   for (Elf_Word i = 0; i < GetSectionHeaderNum(); i++) {
1727     Elf_Shdr* sh = GetSectionHeader(i);
1728     CHECK(sh != nullptr);
1729     if (sh->sh_type == SHT_REL) {
1730       for (uint32_t j = 0; j < GetRelNum(*sh); j++) {
1731         Elf_Rel& rel = GetRel(*sh, j);
1732         if (DEBUG_FIXUP) {
1733           LOG(INFO) << StringPrintf("In %s moving Elf_Rel[%d] from 0x%" PRIx64 " to 0x%" PRIx64,
1734                                     GetFile().GetPath().c_str(), j,
1735                                     static_cast<uint64_t>(rel.r_offset),
1736                                     static_cast<uint64_t>(rel.r_offset + base_address));
1737         }
1738         rel.r_offset += base_address;
1739       }
1740     } else if (sh->sh_type == SHT_RELA) {
1741       for (uint32_t j = 0; j < GetRelaNum(*sh); j++) {
1742         Elf_Rela& rela = GetRela(*sh, j);
1743         if (DEBUG_FIXUP) {
1744           LOG(INFO) << StringPrintf("In %s moving Elf_Rela[%d] from 0x%" PRIx64 " to 0x%" PRIx64,
1745                                     GetFile().GetPath().c_str(), j,
1746                                     static_cast<uint64_t>(rela.r_offset),
1747                                     static_cast<uint64_t>(rela.r_offset + base_address));
1748         }
1749         rela.r_offset += base_address;
1750       }
1751     }
1752   }
1753   return true;
1754 }
1755 
1756 // Explicit instantiations
1757 template class ElfFileImpl<ElfTypes32>;
1758 template class ElfFileImpl<ElfTypes64>;
1759 
ElfFile(ElfFileImpl32 * elf32)1760 ElfFile::ElfFile(ElfFileImpl32* elf32) : elf32_(elf32), elf64_(nullptr) {
1761 }
1762 
ElfFile(ElfFileImpl64 * elf64)1763 ElfFile::ElfFile(ElfFileImpl64* elf64) : elf32_(nullptr), elf64_(elf64) {
1764 }
1765 
~ElfFile()1766 ElfFile::~ElfFile() {
1767   // Should never have 32 and 64-bit impls.
1768   CHECK_NE(elf32_.get() == nullptr, elf64_.get() == nullptr);
1769 }
1770 
Open(File * file,bool writable,bool program_header_only,std::string * error_msg,uint8_t * requested_base)1771 ElfFile* ElfFile::Open(File* file, bool writable, bool program_header_only, std::string* error_msg,
1772                        uint8_t* requested_base) {
1773   if (file->GetLength() < EI_NIDENT) {
1774     *error_msg = StringPrintf("File %s is too short to be a valid ELF file",
1775                               file->GetPath().c_str());
1776     return nullptr;
1777   }
1778   std::unique_ptr<MemMap> map(MemMap::MapFile(EI_NIDENT, PROT_READ, MAP_PRIVATE, file->Fd(), 0,
1779                                               file->GetPath().c_str(), error_msg));
1780   if (map == nullptr && map->Size() != EI_NIDENT) {
1781     return nullptr;
1782   }
1783   uint8_t* header = map->Begin();
1784   if (header[EI_CLASS] == ELFCLASS64) {
1785     ElfFileImpl64* elf_file_impl = ElfFileImpl64::Open(file, writable, program_header_only,
1786                                                        error_msg, requested_base);
1787     if (elf_file_impl == nullptr)
1788       return nullptr;
1789     return new ElfFile(elf_file_impl);
1790   } else if (header[EI_CLASS] == ELFCLASS32) {
1791     ElfFileImpl32* elf_file_impl = ElfFileImpl32::Open(file, writable, program_header_only,
1792                                                        error_msg, requested_base);
1793     if (elf_file_impl == nullptr) {
1794       return nullptr;
1795     }
1796     return new ElfFile(elf_file_impl);
1797   } else {
1798     *error_msg = StringPrintf("Failed to find expected EI_CLASS value %d or %d in %s, found %d",
1799                               ELFCLASS32, ELFCLASS64,
1800                               file->GetPath().c_str(),
1801                               header[EI_CLASS]);
1802     return nullptr;
1803   }
1804 }
1805 
Open(File * file,int mmap_prot,int mmap_flags,std::string * error_msg)1806 ElfFile* ElfFile::Open(File* file, int mmap_prot, int mmap_flags, std::string* error_msg) {
1807   if (file->GetLength() < EI_NIDENT) {
1808     *error_msg = StringPrintf("File %s is too short to be a valid ELF file",
1809                               file->GetPath().c_str());
1810     return nullptr;
1811   }
1812   std::unique_ptr<MemMap> map(MemMap::MapFile(EI_NIDENT, PROT_READ, MAP_PRIVATE, file->Fd(), 0,
1813                                               file->GetPath().c_str(), error_msg));
1814   if (map == nullptr && map->Size() != EI_NIDENT) {
1815     return nullptr;
1816   }
1817   uint8_t* header = map->Begin();
1818   if (header[EI_CLASS] == ELFCLASS64) {
1819     ElfFileImpl64* elf_file_impl = ElfFileImpl64::Open(file, mmap_prot, mmap_flags, error_msg);
1820     if (elf_file_impl == nullptr) {
1821       return nullptr;
1822     }
1823     return new ElfFile(elf_file_impl);
1824   } else if (header[EI_CLASS] == ELFCLASS32) {
1825     ElfFileImpl32* elf_file_impl = ElfFileImpl32::Open(file, mmap_prot, mmap_flags, error_msg);
1826     if (elf_file_impl == nullptr) {
1827       return nullptr;
1828     }
1829     return new ElfFile(elf_file_impl);
1830   } else {
1831     *error_msg = StringPrintf("Failed to find expected EI_CLASS value %d or %d in %s, found %d",
1832                               ELFCLASS32, ELFCLASS64,
1833                               file->GetPath().c_str(),
1834                               header[EI_CLASS]);
1835     return nullptr;
1836   }
1837 }
1838 
1839 #define DELEGATE_TO_IMPL(func, ...) \
1840   if (elf64_.get() != nullptr) { \
1841     return elf64_->func(__VA_ARGS__); \
1842   } else { \
1843     DCHECK(elf32_.get() != nullptr); \
1844     return elf32_->func(__VA_ARGS__); \
1845   }
1846 
Load(bool executable,std::string * error_msg)1847 bool ElfFile::Load(bool executable, std::string* error_msg) {
1848   DELEGATE_TO_IMPL(Load, executable, error_msg);
1849 }
1850 
FindDynamicSymbolAddress(const std::string & symbol_name) const1851 const uint8_t* ElfFile::FindDynamicSymbolAddress(const std::string& symbol_name) const {
1852   DELEGATE_TO_IMPL(FindDynamicSymbolAddress, symbol_name);
1853 }
1854 
Size() const1855 size_t ElfFile::Size() const {
1856   DELEGATE_TO_IMPL(Size);
1857 }
1858 
Begin() const1859 uint8_t* ElfFile::Begin() const {
1860   DELEGATE_TO_IMPL(Begin);
1861 }
1862 
End() const1863 uint8_t* ElfFile::End() const {
1864   DELEGATE_TO_IMPL(End);
1865 }
1866 
GetFile() const1867 const File& ElfFile::GetFile() const {
1868   DELEGATE_TO_IMPL(GetFile);
1869 }
1870 
GetSectionOffsetAndSize(const char * section_name,uint64_t * offset,uint64_t * size)1871 bool ElfFile::GetSectionOffsetAndSize(const char* section_name, uint64_t* offset, uint64_t* size) {
1872   if (elf32_.get() == nullptr) {
1873     CHECK(elf64_.get() != nullptr);
1874 
1875     Elf64_Shdr *shdr = elf64_->FindSectionByName(section_name);
1876     if (shdr == nullptr) {
1877       return false;
1878     }
1879     if (offset != nullptr) {
1880       *offset = shdr->sh_offset;
1881     }
1882     if (size != nullptr) {
1883       *size = shdr->sh_size;
1884     }
1885     return true;
1886   } else {
1887     Elf32_Shdr *shdr = elf32_->FindSectionByName(section_name);
1888     if (shdr == nullptr) {
1889       return false;
1890     }
1891     if (offset != nullptr) {
1892       *offset = shdr->sh_offset;
1893     }
1894     if (size != nullptr) {
1895       *size = shdr->sh_size;
1896     }
1897     return true;
1898   }
1899 }
1900 
FindSymbolAddress(unsigned section_type,const std::string & symbol_name,bool build_map)1901 uint64_t ElfFile::FindSymbolAddress(unsigned section_type,
1902                                     const std::string& symbol_name,
1903                                     bool build_map) {
1904   DELEGATE_TO_IMPL(FindSymbolAddress, section_type, symbol_name, build_map);
1905 }
1906 
GetLoadedSize(size_t * size,std::string * error_msg) const1907 bool ElfFile::GetLoadedSize(size_t* size, std::string* error_msg) const {
1908   DELEGATE_TO_IMPL(GetLoadedSize, size, error_msg);
1909 }
1910 
Strip(File * file,std::string * error_msg)1911 bool ElfFile::Strip(File* file, std::string* error_msg) {
1912   std::unique_ptr<ElfFile> elf_file(ElfFile::Open(file, true, false, error_msg));
1913   if (elf_file.get() == nullptr) {
1914     return false;
1915   }
1916 
1917   if (elf_file->elf64_.get() != nullptr)
1918     return elf_file->elf64_->Strip(error_msg);
1919   else
1920     return elf_file->elf32_->Strip(error_msg);
1921 }
1922 
Fixup(uint64_t base_address)1923 bool ElfFile::Fixup(uint64_t base_address) {
1924   if (elf64_.get() != nullptr) {
1925     return elf64_->Fixup(static_cast<Elf64_Addr>(base_address));
1926   } else {
1927     DCHECK(elf32_.get() != nullptr);
1928     CHECK(IsUint<32>(base_address)) << std::hex << base_address;
1929     return elf32_->Fixup(static_cast<Elf32_Addr>(base_address));
1930   }
1931   DELEGATE_TO_IMPL(Fixup, base_address);
1932 }
1933 
1934 }  // namespace art
1935