blob: 65a557b6bb7e750dd1f774b2dbedcb7b2b4bc3f9 [file] [log] [blame]
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001/*
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
Nicolas Geoffraya7f198c2014-03-10 11:12:54 +000019#include <sys/types.h>
20#include <unistd.h>
21
Brian Carlstrom700c8d32012-11-05 10:42:02 -080022#include "base/logging.h"
Ian Rogers576ca0c2014-06-06 15:58:22 -070023#include "base/stringprintf.h"
Brian Carlstrom700c8d32012-11-05 10:42:02 -080024#include "base/stl_util.h"
Alex Light3470ab42014-06-18 10:35:45 -070025#include "dwarf.h"
26#include "leb128.h"
Brian Carlstrom700c8d32012-11-05 10:42:02 -080027#include "utils.h"
Andreas Gampe91268c12014-04-03 17:50:24 -070028#include "instruction_set.h"
Brian Carlstrom700c8d32012-11-05 10:42:02 -080029
30namespace art {
31
Mark Mendellae9fd932014-02-10 16:14:35 -080032// -------------------------------------------------------------------
33// Binary GDB JIT Interface as described in
34// http://sourceware.org/gdb/onlinedocs/gdb/Declarations.html
35extern "C" {
36 typedef enum {
37 JIT_NOACTION = 0,
38 JIT_REGISTER_FN,
39 JIT_UNREGISTER_FN
40 } JITAction;
41
42 struct JITCodeEntry {
43 JITCodeEntry* next_;
44 JITCodeEntry* prev_;
45 const byte *symfile_addr_;
46 uint64_t symfile_size_;
47 };
48
49 struct JITDescriptor {
50 uint32_t version_;
51 uint32_t action_flag_;
52 JITCodeEntry* relevant_entry_;
53 JITCodeEntry* first_entry_;
54 };
55
56 // GDB will place breakpoint into this function.
57 // To prevent GCC from inlining or removing it we place noinline attribute
58 // and inline assembler statement inside.
59 void __attribute__((noinline)) __jit_debug_register_code() {
60 __asm__("");
61 }
62
63 // GDB will inspect contents of this descriptor.
64 // Static initialization is necessary to prevent GDB from seeing
65 // uninitialized descriptor.
66 JITDescriptor __jit_debug_descriptor = { 1, JIT_NOACTION, nullptr, nullptr };
67}
68
69
70static JITCodeEntry* CreateCodeEntry(const byte *symfile_addr,
71 uintptr_t symfile_size) {
72 JITCodeEntry* entry = new JITCodeEntry;
73 entry->symfile_addr_ = symfile_addr;
74 entry->symfile_size_ = symfile_size;
75 entry->prev_ = nullptr;
76
77 // TODO: Do we need a lock here?
78 entry->next_ = __jit_debug_descriptor.first_entry_;
79 if (entry->next_ != nullptr) {
80 entry->next_->prev_ = entry;
81 }
82 __jit_debug_descriptor.first_entry_ = entry;
83 __jit_debug_descriptor.relevant_entry_ = entry;
84
85 __jit_debug_descriptor.action_flag_ = JIT_REGISTER_FN;
86 __jit_debug_register_code();
87 return entry;
88}
89
90
91static void UnregisterCodeEntry(JITCodeEntry* entry) {
92 // TODO: Do we need a lock here?
93 if (entry->prev_ != nullptr) {
94 entry->prev_->next_ = entry->next_;
95 } else {
96 __jit_debug_descriptor.first_entry_ = entry->next_;
97 }
98
99 if (entry->next_ != nullptr) {
100 entry->next_->prev_ = entry->prev_;
101 }
102
103 __jit_debug_descriptor.relevant_entry_ = entry;
104 __jit_debug_descriptor.action_flag_ = JIT_UNREGISTER_FN;
105 __jit_debug_register_code();
106 delete entry;
107}
108
Brian Carlstromc1409452014-02-26 14:06:23 -0800109ElfFile::ElfFile(File* file, bool writable, bool program_header_only)
110 : file_(file),
111 writable_(writable),
112 program_header_only_(program_header_only),
Alex Light3470ab42014-06-18 10:35:45 -0700113 header_(nullptr),
114 base_address_(nullptr),
115 program_headers_start_(nullptr),
116 section_headers_start_(nullptr),
117 dynamic_program_header_(nullptr),
118 dynamic_section_start_(nullptr),
119 symtab_section_start_(nullptr),
120 dynsym_section_start_(nullptr),
121 strtab_section_start_(nullptr),
122 dynstr_section_start_(nullptr),
123 hash_section_start_(nullptr),
124 symtab_symbol_table_(nullptr),
125 dynsym_symbol_table_(nullptr),
126 jit_elf_image_(nullptr),
127 jit_gdb_entry_(nullptr) {
128 CHECK(file != nullptr);
Brian Carlstromc1409452014-02-26 14:06:23 -0800129}
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800130
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700131ElfFile* ElfFile::Open(File* file, bool writable, bool program_header_only,
132 std::string* error_msg) {
Ian Rogers700a4022014-05-19 16:49:03 -0700133 std::unique_ptr<ElfFile> elf_file(new ElfFile(file, writable, program_header_only));
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800134 int prot;
135 int flags;
Alex Light3470ab42014-06-18 10:35:45 -0700136 if (writable) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800137 prot = PROT_READ | PROT_WRITE;
138 flags = MAP_SHARED;
139 } else {
140 prot = PROT_READ;
141 flags = MAP_PRIVATE;
142 }
Alex Light3470ab42014-06-18 10:35:45 -0700143 if (!elf_file->Setup(prot, flags, error_msg)) {
144 return nullptr;
145 }
146 return elf_file.release();
147}
148
149ElfFile* ElfFile::Open(File* file, int prot, int flags, std::string* error_msg) {
150 std::unique_ptr<ElfFile> elf_file(new ElfFile(file, (prot & PROT_WRITE) == PROT_WRITE, false));
151 if (!elf_file->Setup(prot, flags, error_msg)) {
152 return nullptr;
153 }
154 return elf_file.release();
155}
156
157bool ElfFile::Setup(int prot, int flags, std::string* error_msg) {
Ian Rogerscdfcf372014-01-23 20:38:36 -0800158 int64_t temp_file_length = file_->GetLength();
159 if (temp_file_length < 0) {
160 errno = -temp_file_length;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700161 *error_msg = StringPrintf("Failed to get length of file: '%s' fd=%d: %s",
162 file_->GetPath().c_str(), file_->Fd(), strerror(errno));
Brian Carlstrom265091e2013-01-30 14:08:26 -0800163 return false;
164 }
Ian Rogerscdfcf372014-01-23 20:38:36 -0800165 size_t file_length = static_cast<size_t>(temp_file_length);
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000166 if (file_length < sizeof(Elf32_Ehdr)) {
Ian Rogerscdfcf372014-01-23 20:38:36 -0800167 *error_msg = StringPrintf("File size of %zd bytes not large enough to contain ELF header of "
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000168 "%zd bytes: '%s'", file_length, sizeof(Elf32_Ehdr),
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700169 file_->GetPath().c_str());
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800170 return false;
171 }
172
Brian Carlstromc1409452014-02-26 14:06:23 -0800173 if (program_header_only_) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800174 // first just map ELF header to get program header size information
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000175 size_t elf_header_size = sizeof(Elf32_Ehdr);
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700176 if (!SetMap(MemMap::MapFile(elf_header_size, prot, flags, file_->Fd(), 0,
Brian Carlstromd0c09dc2013-11-06 18:25:35 -0800177 file_->GetPath().c_str(), error_msg),
178 error_msg)) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800179 return false;
180 }
181 // then remap to cover program header
182 size_t program_header_size = header_->e_phoff + (header_->e_phentsize * header_->e_phnum);
Brian Carlstrom3a223612013-10-10 17:18:24 -0700183 if (file_length < program_header_size) {
Ian Rogerscdfcf372014-01-23 20:38:36 -0800184 *error_msg = StringPrintf("File size of %zd bytes not large enough to contain ELF program "
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700185 "header of %zd bytes: '%s'", file_length,
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000186 sizeof(Elf32_Ehdr), file_->GetPath().c_str());
Brian Carlstrom3a223612013-10-10 17:18:24 -0700187 return false;
188 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700189 if (!SetMap(MemMap::MapFile(program_header_size, prot, flags, file_->Fd(), 0,
Brian Carlstromd0c09dc2013-11-06 18:25:35 -0800190 file_->GetPath().c_str(), error_msg),
191 error_msg)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700192 *error_msg = StringPrintf("Failed to map ELF program headers: %s", error_msg->c_str());
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800193 return false;
194 }
195 } else {
196 // otherwise map entire file
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700197 if (!SetMap(MemMap::MapFile(file_->GetLength(), prot, flags, file_->Fd(), 0,
Brian Carlstromd0c09dc2013-11-06 18:25:35 -0800198 file_->GetPath().c_str(), error_msg),
199 error_msg)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700200 *error_msg = StringPrintf("Failed to map ELF file: %s", error_msg->c_str());
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800201 return false;
202 }
203 }
204
Andreas Gampedaab38c2014-09-12 18:38:24 -0700205 if (program_header_only_) {
206 program_headers_start_ = Begin() + GetHeader().e_phoff;
207 } else {
208 if (!CheckAndSet(GetHeader().e_phoff, "program headers", &program_headers_start_, error_msg)) {
209 return false;
210 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800211
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800212 // Setup section headers.
Andreas Gampedaab38c2014-09-12 18:38:24 -0700213 if (!CheckAndSet(GetHeader().e_shoff, "section headers", &section_headers_start_, error_msg)) {
214 return false;
215 }
216
217 // Find shstrtab.
218 Elf32_Shdr* shstrtab_section_header = GetSectionNameStringSection();
219 if (shstrtab_section_header == nullptr) {
220 *error_msg = StringPrintf("Failed to find shstrtab section header in ELF file: '%s'",
221 file_->GetPath().c_str());
222 return false;
223 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800224
225 // Find .dynamic section info from program header
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000226 dynamic_program_header_ = FindProgamHeaderByType(PT_DYNAMIC);
Alex Light3470ab42014-06-18 10:35:45 -0700227 if (dynamic_program_header_ == nullptr) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700228 *error_msg = StringPrintf("Failed to find PT_DYNAMIC program header in ELF file: '%s'",
229 file_->GetPath().c_str());
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800230 return false;
231 }
232
Andreas Gampedaab38c2014-09-12 18:38:24 -0700233 if (!CheckAndSet(GetDynamicProgramHeader().p_offset, "dynamic section",
234 reinterpret_cast<byte**>(&dynamic_section_start_), error_msg)) {
235 return false;
236 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800237
238 // Find other sections from section headers
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000239 for (Elf32_Word i = 0; i < GetSectionHeaderNum(); i++) {
Andreas Gampedaab38c2014-09-12 18:38:24 -0700240 Elf32_Shdr* section_header = GetSectionHeader(i);
241 if (section_header == nullptr) {
242 *error_msg = StringPrintf("Failed to find section header for section %d in ELF file: '%s'",
243 i, file_->GetPath().c_str());
244 return false;
245 }
246 switch (section_header->sh_type) {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000247 case SHT_SYMTAB: {
Andreas Gampedaab38c2014-09-12 18:38:24 -0700248 if (!CheckAndSet(section_header->sh_offset, "symtab",
249 reinterpret_cast<byte**>(&symtab_section_start_), error_msg)) {
250 return false;
251 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800252 break;
253 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000254 case SHT_DYNSYM: {
Andreas Gampedaab38c2014-09-12 18:38:24 -0700255 if (!CheckAndSet(section_header->sh_offset, "dynsym",
256 reinterpret_cast<byte**>(&dynsym_section_start_), error_msg)) {
257 return false;
258 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800259 break;
260 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000261 case SHT_STRTAB: {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800262 // TODO: base these off of sh_link from .symtab and .dynsym above
Andreas Gampedaab38c2014-09-12 18:38:24 -0700263 if ((section_header->sh_flags & SHF_ALLOC) != 0) {
264 // Check that this is named ".dynstr" and ignore otherwise.
265 const char* header_name = GetString(*shstrtab_section_header, section_header->sh_name);
266 if (strncmp(".dynstr", header_name, 8) == 0) {
267 if (!CheckAndSet(section_header->sh_offset, "dynstr",
268 reinterpret_cast<byte**>(&dynstr_section_start_), error_msg)) {
269 return false;
270 }
271 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800272 } else {
Andreas Gampedaab38c2014-09-12 18:38:24 -0700273 // Check that this is named ".strtab" and ignore otherwise.
274 const char* header_name = GetString(*shstrtab_section_header, section_header->sh_name);
275 if (strncmp(".strtab", header_name, 8) == 0) {
276 if (!CheckAndSet(section_header->sh_offset, "strtab",
277 reinterpret_cast<byte**>(&strtab_section_start_), error_msg)) {
278 return false;
279 }
280 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800281 }
282 break;
283 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000284 case SHT_DYNAMIC: {
Andreas Gampedaab38c2014-09-12 18:38:24 -0700285 if (reinterpret_cast<byte*>(dynamic_section_start_) !=
286 Begin() + section_header->sh_offset) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800287 LOG(WARNING) << "Failed to find matching SHT_DYNAMIC for PT_DYNAMIC in "
Brian Carlstrom265091e2013-01-30 14:08:26 -0800288 << file_->GetPath() << ": " << std::hex
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800289 << reinterpret_cast<void*>(dynamic_section_start_)
Andreas Gampedaab38c2014-09-12 18:38:24 -0700290 << " != " << reinterpret_cast<void*>(Begin() + section_header->sh_offset);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800291 return false;
292 }
293 break;
294 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000295 case SHT_HASH: {
Andreas Gampedaab38c2014-09-12 18:38:24 -0700296 if (!CheckAndSet(section_header->sh_offset, "hash section",
297 reinterpret_cast<byte**>(&hash_section_start_), error_msg)) {
298 return false;
299 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800300 break;
301 }
302 }
303 }
Andreas Gampedaab38c2014-09-12 18:38:24 -0700304
305 // Check for the existence of some sections.
306 if (!CheckSectionsExist(error_msg)) {
307 return false;
308 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800309 }
Andreas Gampedaab38c2014-09-12 18:38:24 -0700310
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800311 return true;
312}
313
314ElfFile::~ElfFile() {
315 STLDeleteElements(&segments_);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800316 delete symtab_symbol_table_;
317 delete dynsym_symbol_table_;
Mark Mendellae9fd932014-02-10 16:14:35 -0800318 delete jit_elf_image_;
319 if (jit_gdb_entry_) {
320 UnregisterCodeEntry(jit_gdb_entry_);
321 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800322}
323
Andreas Gampedaab38c2014-09-12 18:38:24 -0700324bool ElfFile::CheckAndSet(Elf32_Off offset, const char* label,
325 byte** target, std::string* error_msg) {
326 if (Begin() + offset >= End()) {
327 *error_msg = StringPrintf("Offset %d is out of range for %s in ELF file: '%s'", offset, label,
328 file_->GetPath().c_str());
329 return false;
330 }
331 *target = Begin() + offset;
332 return true;
333}
334
335bool ElfFile::CheckSectionsLinked(const byte* source, const byte* target) const {
336 // Only works in whole-program mode, as we need to iterate over the sections.
337 // Note that we normally can't search by type, as duplicates are allowed for most section types.
338 if (program_header_only_) {
339 return true;
340 }
341
342 Elf32_Shdr* source_section = nullptr;
343 Elf32_Word target_index = 0;
344 bool target_found = false;
345 for (Elf32_Word i = 0; i < GetSectionHeaderNum(); i++) {
346 Elf32_Shdr* section_header = GetSectionHeader(i);
347
348 if (Begin() + section_header->sh_offset == source) {
349 // Found the source.
350 source_section = section_header;
351 if (target_index) {
352 break;
353 }
354 } else if (Begin() + section_header->sh_offset == target) {
355 target_index = i;
356 target_found = true;
357 if (source_section != nullptr) {
358 break;
359 }
360 }
361 }
362
363 return target_found && source_section != nullptr && source_section->sh_link == target_index;
364}
365
366bool ElfFile::CheckSectionsExist(std::string* error_msg) const {
367 if (!program_header_only_) {
368 // If in full mode, need section headers.
369 if (section_headers_start_ == nullptr) {
370 *error_msg = StringPrintf("No section headers in ELF file: '%s'", file_->GetPath().c_str());
371 return false;
372 }
373 }
374
375 // This is redundant, but defensive.
376 if (dynamic_program_header_ == nullptr) {
377 *error_msg = StringPrintf("Failed to find PT_DYNAMIC program header in ELF file: '%s'",
378 file_->GetPath().c_str());
379 return false;
380 }
381
382 // Need a dynamic section. This is redundant, but defensive.
383 if (dynamic_section_start_ == nullptr) {
384 *error_msg = StringPrintf("Failed to find dynamic section in ELF file: '%s'",
385 file_->GetPath().c_str());
386 return false;
387 }
388
389 // Symtab validation. These is not really a hard failure, as we are currently not using the
390 // symtab internally, but it's nice to be defensive.
391 if (symtab_section_start_ != nullptr) {
392 // When there's a symtab, there should be a strtab.
393 if (strtab_section_start_ == nullptr) {
394 *error_msg = StringPrintf("No strtab for symtab in ELF file: '%s'", file_->GetPath().c_str());
395 return false;
396 }
397
398 // The symtab should link to the strtab.
399 if (!CheckSectionsLinked(reinterpret_cast<const byte*>(symtab_section_start_),
400 reinterpret_cast<const byte*>(strtab_section_start_))) {
401 *error_msg = StringPrintf("Symtab is not linked to the strtab in ELF file: '%s'",
402 file_->GetPath().c_str());
403 return false;
404 }
405 }
406
407 // We always need a dynstr & dynsym.
408 if (dynstr_section_start_ == nullptr) {
409 *error_msg = StringPrintf("No dynstr in ELF file: '%s'", file_->GetPath().c_str());
410 return false;
411 }
412 if (dynsym_section_start_ == nullptr) {
413 *error_msg = StringPrintf("No dynsym in ELF file: '%s'", file_->GetPath().c_str());
414 return false;
415 }
416
417 // Need a hash section for dynamic symbol lookup.
418 if (hash_section_start_ == nullptr) {
419 *error_msg = StringPrintf("Failed to find hash section in ELF file: '%s'",
420 file_->GetPath().c_str());
421 return false;
422 }
423
424 // And the hash section should be linking to the dynsym.
425 if (!CheckSectionsLinked(reinterpret_cast<const byte*>(hash_section_start_),
426 reinterpret_cast<const byte*>(dynsym_section_start_))) {
427 *error_msg = StringPrintf("Hash section is not linked to the dynstr in ELF file: '%s'",
428 file_->GetPath().c_str());
429 return false;
430 }
431
432 return true;
433}
434
Brian Carlstromd0c09dc2013-11-06 18:25:35 -0800435bool ElfFile::SetMap(MemMap* map, std::string* error_msg) {
Alex Light3470ab42014-06-18 10:35:45 -0700436 if (map == nullptr) {
Brian Carlstromd0c09dc2013-11-06 18:25:35 -0800437 // MemMap::Open should have already set an error.
438 DCHECK(!error_msg->empty());
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800439 return false;
440 }
441 map_.reset(map);
Alex Light3470ab42014-06-18 10:35:45 -0700442 CHECK(map_.get() != nullptr) << file_->GetPath();
443 CHECK(map_->Begin() != nullptr) << file_->GetPath();
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800444
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000445 header_ = reinterpret_cast<Elf32_Ehdr*>(map_->Begin());
446 if ((ELFMAG0 != header_->e_ident[EI_MAG0])
447 || (ELFMAG1 != header_->e_ident[EI_MAG1])
448 || (ELFMAG2 != header_->e_ident[EI_MAG2])
449 || (ELFMAG3 != header_->e_ident[EI_MAG3])) {
Brian Carlstromc1409452014-02-26 14:06:23 -0800450 *error_msg = StringPrintf("Failed to find ELF magic value %d %d %d %d in %s, found %d %d %d %d",
451 ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3,
Brian Carlstromd0c09dc2013-11-06 18:25:35 -0800452 file_->GetPath().c_str(),
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000453 header_->e_ident[EI_MAG0],
454 header_->e_ident[EI_MAG1],
455 header_->e_ident[EI_MAG2],
456 header_->e_ident[EI_MAG3]);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800457 return false;
458 }
Brian Carlstromc1409452014-02-26 14:06:23 -0800459 if (ELFCLASS32 != header_->e_ident[EI_CLASS]) {
460 *error_msg = StringPrintf("Failed to find expected EI_CLASS value %d in %s, found %d",
461 ELFCLASS32,
462 file_->GetPath().c_str(),
463 header_->e_ident[EI_CLASS]);
464 return false;
465 }
466 if (ELFDATA2LSB != header_->e_ident[EI_DATA]) {
467 *error_msg = StringPrintf("Failed to find expected EI_DATA value %d in %s, found %d",
468 ELFDATA2LSB,
469 file_->GetPath().c_str(),
470 header_->e_ident[EI_CLASS]);
471 return false;
472 }
473 if (EV_CURRENT != header_->e_ident[EI_VERSION]) {
474 *error_msg = StringPrintf("Failed to find expected EI_VERSION value %d in %s, found %d",
475 EV_CURRENT,
476 file_->GetPath().c_str(),
477 header_->e_ident[EI_CLASS]);
478 return false;
479 }
480 if (ET_DYN != header_->e_type) {
481 *error_msg = StringPrintf("Failed to find expected e_type value %d in %s, found %d",
482 ET_DYN,
483 file_->GetPath().c_str(),
484 header_->e_type);
485 return false;
486 }
487 if (EV_CURRENT != header_->e_version) {
488 *error_msg = StringPrintf("Failed to find expected e_version value %d in %s, found %d",
489 EV_CURRENT,
490 file_->GetPath().c_str(),
491 header_->e_version);
492 return false;
493 }
494 if (0 != header_->e_entry) {
495 *error_msg = StringPrintf("Failed to find expected e_entry value %d in %s, found %d",
496 0,
497 file_->GetPath().c_str(),
498 header_->e_entry);
499 return false;
500 }
501 if (0 == header_->e_phoff) {
502 *error_msg = StringPrintf("Failed to find non-zero e_phoff value in %s",
503 file_->GetPath().c_str());
504 return false;
505 }
506 if (0 == header_->e_shoff) {
507 *error_msg = StringPrintf("Failed to find non-zero e_shoff value in %s",
508 file_->GetPath().c_str());
509 return false;
510 }
511 if (0 == header_->e_ehsize) {
512 *error_msg = StringPrintf("Failed to find non-zero e_ehsize value in %s",
513 file_->GetPath().c_str());
514 return false;
515 }
516 if (0 == header_->e_phentsize) {
517 *error_msg = StringPrintf("Failed to find non-zero e_phentsize value in %s",
518 file_->GetPath().c_str());
519 return false;
520 }
521 if (0 == header_->e_phnum) {
522 *error_msg = StringPrintf("Failed to find non-zero e_phnum value in %s",
523 file_->GetPath().c_str());
524 return false;
525 }
526 if (0 == header_->e_shentsize) {
527 *error_msg = StringPrintf("Failed to find non-zero e_shentsize value in %s",
528 file_->GetPath().c_str());
529 return false;
530 }
531 if (0 == header_->e_shnum) {
532 *error_msg = StringPrintf("Failed to find non-zero e_shnum value in %s",
533 file_->GetPath().c_str());
534 return false;
535 }
536 if (0 == header_->e_shstrndx) {
537 *error_msg = StringPrintf("Failed to find non-zero e_shstrndx value in %s",
538 file_->GetPath().c_str());
539 return false;
540 }
541 if (header_->e_shstrndx >= header_->e_shnum) {
542 *error_msg = StringPrintf("Failed to find e_shnum value %d less than %d in %s",
543 header_->e_shstrndx,
544 header_->e_shnum,
545 file_->GetPath().c_str());
546 return false;
547 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800548
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800549 if (!program_header_only_) {
Brian Carlstromc1409452014-02-26 14:06:23 -0800550 if (header_->e_phoff >= Size()) {
Dmitry Petrochenko659d87d2014-02-27 14:23:11 +0700551 *error_msg = StringPrintf("Failed to find e_phoff value %d less than %zd in %s",
Brian Carlstromc1409452014-02-26 14:06:23 -0800552 header_->e_phoff,
553 Size(),
554 file_->GetPath().c_str());
555 return false;
556 }
557 if (header_->e_shoff >= Size()) {
Dmitry Petrochenko659d87d2014-02-27 14:23:11 +0700558 *error_msg = StringPrintf("Failed to find e_shoff value %d less than %zd in %s",
Brian Carlstromc1409452014-02-26 14:06:23 -0800559 header_->e_shoff,
560 Size(),
561 file_->GetPath().c_str());
562 return false;
563 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800564 }
565 return true;
566}
567
568
Brian Carlstromc1409452014-02-26 14:06:23 -0800569Elf32_Ehdr& ElfFile::GetHeader() const {
Andreas Gampedaab38c2014-09-12 18:38:24 -0700570 CHECK(header_ != nullptr); // Header has been checked in SetMap. This is a sanity check.
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800571 return *header_;
572}
573
Brian Carlstromc1409452014-02-26 14:06:23 -0800574byte* ElfFile::GetProgramHeadersStart() const {
Andreas Gampedaab38c2014-09-12 18:38:24 -0700575 CHECK(program_headers_start_ != nullptr); // Header has been set in Setup. This is a sanity
576 // check.
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800577 return program_headers_start_;
578}
579
Brian Carlstromc1409452014-02-26 14:06:23 -0800580byte* ElfFile::GetSectionHeadersStart() const {
Andreas Gampedaab38c2014-09-12 18:38:24 -0700581 CHECK(!program_header_only_); // Only used in "full" mode.
582 CHECK(section_headers_start_ != nullptr); // Is checked in CheckSectionsExist. Sanity check.
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800583 return section_headers_start_;
584}
585
Brian Carlstromc1409452014-02-26 14:06:23 -0800586Elf32_Phdr& ElfFile::GetDynamicProgramHeader() const {
Andreas Gampedaab38c2014-09-12 18:38:24 -0700587 CHECK(dynamic_program_header_ != nullptr); // Is checked in CheckSectionsExist. Sanity check.
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800588 return *dynamic_program_header_;
589}
590
Brian Carlstromc1409452014-02-26 14:06:23 -0800591Elf32_Dyn* ElfFile::GetDynamicSectionStart() const {
Andreas Gampedaab38c2014-09-12 18:38:24 -0700592 CHECK(dynamic_section_start_ != nullptr); // Is checked in CheckSectionsExist. Sanity check.
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800593 return dynamic_section_start_;
594}
595
Andreas Gampedaab38c2014-09-12 18:38:24 -0700596static bool IsSymbolSectionType(Elf32_Word section_type) {
597 return ((section_type == SHT_SYMTAB) || (section_type == SHT_DYNSYM));
598}
599
Brian Carlstromc1409452014-02-26 14:06:23 -0800600Elf32_Sym* ElfFile::GetSymbolSectionStart(Elf32_Word section_type) const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800601 CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800602 switch (section_type) {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000603 case SHT_SYMTAB: {
Andreas Gampedaab38c2014-09-12 18:38:24 -0700604 return symtab_section_start_;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800605 break;
606 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000607 case SHT_DYNSYM: {
Andreas Gampedaab38c2014-09-12 18:38:24 -0700608 return dynsym_section_start_;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800609 break;
610 }
611 default: {
612 LOG(FATAL) << section_type;
Andreas Gampedaab38c2014-09-12 18:38:24 -0700613 return nullptr;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800614 }
615 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800616}
617
Brian Carlstromc1409452014-02-26 14:06:23 -0800618const char* ElfFile::GetStringSectionStart(Elf32_Word section_type) const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800619 CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800620 switch (section_type) {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000621 case SHT_SYMTAB: {
Andreas Gampedaab38c2014-09-12 18:38:24 -0700622 return strtab_section_start_;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800623 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000624 case SHT_DYNSYM: {
Andreas Gampedaab38c2014-09-12 18:38:24 -0700625 return dynstr_section_start_;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800626 }
627 default: {
628 LOG(FATAL) << section_type;
Andreas Gampedaab38c2014-09-12 18:38:24 -0700629 return nullptr;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800630 }
631 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800632}
633
Brian Carlstromc1409452014-02-26 14:06:23 -0800634const char* ElfFile::GetString(Elf32_Word section_type, Elf32_Word i) const {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800635 CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type;
636 if (i == 0) {
Alex Light3470ab42014-06-18 10:35:45 -0700637 return nullptr;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800638 }
639 const char* string_section_start = GetStringSectionStart(section_type);
Andreas Gampedaab38c2014-09-12 18:38:24 -0700640 if (string_section_start == nullptr) {
641 return nullptr;
642 }
643 return string_section_start + i;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800644}
645
Andreas Gampedaab38c2014-09-12 18:38:24 -0700646// WARNING: The following methods do not check for an error condition (non-existent hash section).
647// It is the caller's job to do this.
648
Brian Carlstromc1409452014-02-26 14:06:23 -0800649Elf32_Word* ElfFile::GetHashSectionStart() const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800650 return hash_section_start_;
651}
652
Brian Carlstromc1409452014-02-26 14:06:23 -0800653Elf32_Word ElfFile::GetHashBucketNum() const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800654 return GetHashSectionStart()[0];
655}
656
Brian Carlstromc1409452014-02-26 14:06:23 -0800657Elf32_Word ElfFile::GetHashChainNum() const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800658 return GetHashSectionStart()[1];
659}
660
Andreas Gampedaab38c2014-09-12 18:38:24 -0700661Elf32_Word ElfFile::GetHashBucket(size_t i, bool* ok) const {
662 if (i >= GetHashBucketNum()) {
663 *ok = false;
664 return 0;
665 }
666 *ok = true;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800667 // 0 is nbucket, 1 is nchain
668 return GetHashSectionStart()[2 + i];
669}
670
Andreas Gampedaab38c2014-09-12 18:38:24 -0700671Elf32_Word ElfFile::GetHashChain(size_t i, bool* ok) const {
672 if (i >= GetHashBucketNum()) {
673 *ok = false;
674 return 0;
675 }
676 *ok = true;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800677 // 0 is nbucket, 1 is nchain, & chains are after buckets
678 return GetHashSectionStart()[2 + GetHashBucketNum() + i];
679}
680
Brian Carlstromc1409452014-02-26 14:06:23 -0800681Elf32_Word ElfFile::GetProgramHeaderNum() const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800682 return GetHeader().e_phnum;
683}
684
Andreas Gampedaab38c2014-09-12 18:38:24 -0700685Elf32_Phdr* ElfFile::GetProgramHeader(Elf32_Word i) const {
686 CHECK_LT(i, GetProgramHeaderNum()) << file_->GetPath(); // Sanity check for caller.
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800687 byte* program_header = GetProgramHeadersStart() + (i * GetHeader().e_phentsize);
Andreas Gampedaab38c2014-09-12 18:38:24 -0700688 if (program_header >= End()) {
689 return nullptr; // Failure condition.
690 }
691 return reinterpret_cast<Elf32_Phdr*>(program_header);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800692}
693
Brian Carlstromc1409452014-02-26 14:06:23 -0800694Elf32_Phdr* ElfFile::FindProgamHeaderByType(Elf32_Word type) const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000695 for (Elf32_Word i = 0; i < GetProgramHeaderNum(); i++) {
Andreas Gampedaab38c2014-09-12 18:38:24 -0700696 Elf32_Phdr* program_header = GetProgramHeader(i);
697 if (program_header->p_type == type) {
698 return program_header;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800699 }
700 }
Alex Light3470ab42014-06-18 10:35:45 -0700701 return nullptr;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800702}
703
Brian Carlstromc1409452014-02-26 14:06:23 -0800704Elf32_Word ElfFile::GetSectionHeaderNum() const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800705 return GetHeader().e_shnum;
706}
707
Andreas Gampedaab38c2014-09-12 18:38:24 -0700708Elf32_Shdr* ElfFile::GetSectionHeader(Elf32_Word i) const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800709 // Can only access arbitrary sections when we have the whole file, not just program header.
710 // Even if we Load(), it doesn't bring in all the sections.
711 CHECK(!program_header_only_) << file_->GetPath();
Andreas Gampedaab38c2014-09-12 18:38:24 -0700712 if (i >= GetSectionHeaderNum()) {
713 return nullptr; // Failure condition.
714 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800715 byte* section_header = GetSectionHeadersStart() + (i * GetHeader().e_shentsize);
Andreas Gampedaab38c2014-09-12 18:38:24 -0700716 if (section_header >= End()) {
717 return nullptr; // Failure condition.
718 }
719 return reinterpret_cast<Elf32_Shdr*>(section_header);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800720}
721
Brian Carlstromc1409452014-02-26 14:06:23 -0800722Elf32_Shdr* ElfFile::FindSectionByType(Elf32_Word type) const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800723 // Can only access arbitrary sections when we have the whole file, not just program header.
724 // We could change this to switch on known types if they were detected during loading.
725 CHECK(!program_header_only_) << file_->GetPath();
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000726 for (Elf32_Word i = 0; i < GetSectionHeaderNum(); i++) {
Andreas Gampedaab38c2014-09-12 18:38:24 -0700727 Elf32_Shdr* section_header = GetSectionHeader(i);
728 if (section_header->sh_type == type) {
729 return section_header;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800730 }
731 }
Alex Light3470ab42014-06-18 10:35:45 -0700732 return nullptr;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800733}
734
735// from bionic
Brian Carlstrom265091e2013-01-30 14:08:26 -0800736static unsigned elfhash(const char *_name) {
737 const unsigned char *name = (const unsigned char *) _name;
738 unsigned h = 0, g;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800739
Brian Carlstromdf629502013-07-17 22:39:56 -0700740 while (*name) {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800741 h = (h << 4) + *name++;
742 g = h & 0xf0000000;
743 h ^= g;
744 h ^= g >> 24;
745 }
746 return h;
747}
748
Andreas Gampedaab38c2014-09-12 18:38:24 -0700749Elf32_Shdr* ElfFile::GetSectionNameStringSection() const {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800750 return GetSectionHeader(GetHeader().e_shstrndx);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800751}
752
Brian Carlstromc1409452014-02-26 14:06:23 -0800753const byte* ElfFile::FindDynamicSymbolAddress(const std::string& symbol_name) const {
Andreas Gampedaab38c2014-09-12 18:38:24 -0700754 // Check that we have a hash section.
755 if (GetHashSectionStart() == nullptr) {
756 return nullptr; // Failure condition.
757 }
Alex Light3470ab42014-06-18 10:35:45 -0700758 const Elf32_Sym* sym = FindDynamicSymbol(symbol_name);
759 if (sym != nullptr) {
760 return base_address_ + sym->st_value;
761 } else {
762 return nullptr;
763 }
764}
765
Andreas Gampedaab38c2014-09-12 18:38:24 -0700766// WARNING: Only called from FindDynamicSymbolAddress. Elides check for hash section.
Alex Light3470ab42014-06-18 10:35:45 -0700767const Elf32_Sym* ElfFile::FindDynamicSymbol(const std::string& symbol_name) const {
Andreas Gampec48b2062014-09-08 23:39:45 -0700768 if (GetHashBucketNum() == 0) {
769 // No dynamic symbols at all.
770 return nullptr;
771 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000772 Elf32_Word hash = elfhash(symbol_name.c_str());
773 Elf32_Word bucket_index = hash % GetHashBucketNum();
Andreas Gampedaab38c2014-09-12 18:38:24 -0700774 bool ok;
775 Elf32_Word symbol_and_chain_index = GetHashBucket(bucket_index, &ok);
776 if (!ok) {
777 return nullptr;
778 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800779 while (symbol_and_chain_index != 0 /* STN_UNDEF */) {
Andreas Gampedaab38c2014-09-12 18:38:24 -0700780 Elf32_Sym* symbol = GetSymbol(SHT_DYNSYM, symbol_and_chain_index);
781 if (symbol == nullptr) {
782 return nullptr; // Failure condition.
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800783 }
Andreas Gampedaab38c2014-09-12 18:38:24 -0700784 const char* name = GetString(SHT_DYNSYM, symbol->st_name);
785 if (symbol_name == name) {
786 return symbol;
787 }
788 symbol_and_chain_index = GetHashChain(symbol_and_chain_index, &ok);
789 if (!ok) {
790 return nullptr;
791 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800792 }
Alex Light3470ab42014-06-18 10:35:45 -0700793 return nullptr;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800794}
795
Brian Carlstromc1409452014-02-26 14:06:23 -0800796Elf32_Word ElfFile::GetSymbolNum(Elf32_Shdr& section_header) const {
797 CHECK(IsSymbolSectionType(section_header.sh_type))
798 << file_->GetPath() << " " << section_header.sh_type;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800799 CHECK_NE(0U, section_header.sh_entsize) << file_->GetPath();
800 return section_header.sh_size / section_header.sh_entsize;
801}
802
Andreas Gampedaab38c2014-09-12 18:38:24 -0700803Elf32_Sym* ElfFile::GetSymbol(Elf32_Word section_type,
Brian Carlstromc1409452014-02-26 14:06:23 -0800804 Elf32_Word i) const {
Andreas Gampedaab38c2014-09-12 18:38:24 -0700805 Elf32_Sym* sym_start = GetSymbolSectionStart(section_type);
806 if (sym_start == nullptr) {
807 return nullptr;
808 }
809 return sym_start + i;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800810}
811
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000812ElfFile::SymbolTable** ElfFile::GetSymbolTable(Elf32_Word section_type) {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800813 CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type;
814 switch (section_type) {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000815 case SHT_SYMTAB: {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800816 return &symtab_symbol_table_;
817 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000818 case SHT_DYNSYM: {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800819 return &dynsym_symbol_table_;
820 }
821 default: {
822 LOG(FATAL) << section_type;
Alex Light3470ab42014-06-18 10:35:45 -0700823 return nullptr;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800824 }
825 }
826}
827
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000828Elf32_Sym* ElfFile::FindSymbolByName(Elf32_Word section_type,
829 const std::string& symbol_name,
830 bool build_map) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800831 CHECK(!program_header_only_) << file_->GetPath();
832 CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800833
834 SymbolTable** symbol_table = GetSymbolTable(section_type);
Alex Light3470ab42014-06-18 10:35:45 -0700835 if (*symbol_table != nullptr || build_map) {
836 if (*symbol_table == nullptr) {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800837 DCHECK(build_map);
838 *symbol_table = new SymbolTable;
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000839 Elf32_Shdr* symbol_section = FindSectionByType(section_type);
Andreas Gampedaab38c2014-09-12 18:38:24 -0700840 if (symbol_section == nullptr) {
841 return nullptr; // Failure condition.
842 }
843 Elf32_Shdr* string_section = GetSectionHeader(symbol_section->sh_link);
844 if (string_section == nullptr) {
845 return nullptr; // Failure condition.
846 }
Brian Carlstrom265091e2013-01-30 14:08:26 -0800847 for (uint32_t i = 0; i < GetSymbolNum(*symbol_section); i++) {
Andreas Gampedaab38c2014-09-12 18:38:24 -0700848 Elf32_Sym* symbol = GetSymbol(section_type, i);
849 if (symbol == nullptr) {
850 return nullptr; // Failure condition.
851 }
852 unsigned char type = ELF32_ST_TYPE(symbol->st_info);
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000853 if (type == STT_NOTYPE) {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800854 continue;
855 }
Andreas Gampedaab38c2014-09-12 18:38:24 -0700856 const char* name = GetString(*string_section, symbol->st_name);
Alex Light3470ab42014-06-18 10:35:45 -0700857 if (name == nullptr) {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800858 continue;
859 }
Brian Carlstromc1409452014-02-26 14:06:23 -0800860 std::pair<SymbolTable::iterator, bool> result =
Andreas Gampedaab38c2014-09-12 18:38:24 -0700861 (*symbol_table)->insert(std::make_pair(name, symbol));
Brian Carlstrom265091e2013-01-30 14:08:26 -0800862 if (!result.second) {
863 // If a duplicate, make sure it has the same logical value. Seen on x86.
Andreas Gampedaab38c2014-09-12 18:38:24 -0700864 if ((symbol->st_value != result.first->second->st_value) ||
865 (symbol->st_size != result.first->second->st_size) ||
866 (symbol->st_info != result.first->second->st_info) ||
867 (symbol->st_other != result.first->second->st_other) ||
868 (symbol->st_shndx != result.first->second->st_shndx)) {
869 return nullptr; // Failure condition.
870 }
Brian Carlstrom265091e2013-01-30 14:08:26 -0800871 }
872 }
873 }
Alex Light3470ab42014-06-18 10:35:45 -0700874 CHECK(*symbol_table != nullptr);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800875 SymbolTable::const_iterator it = (*symbol_table)->find(symbol_name);
876 if (it == (*symbol_table)->end()) {
Alex Light3470ab42014-06-18 10:35:45 -0700877 return nullptr;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800878 }
879 return it->second;
880 }
881
882 // Fall back to linear search
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000883 Elf32_Shdr* symbol_section = FindSectionByType(section_type);
Andreas Gampedaab38c2014-09-12 18:38:24 -0700884 if (symbol_section == nullptr) {
885 return nullptr;
886 }
887 Elf32_Shdr* string_section = GetSectionHeader(symbol_section->sh_link);
888 if (string_section == nullptr) {
889 return nullptr;
890 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800891 for (uint32_t i = 0; i < GetSymbolNum(*symbol_section); i++) {
Andreas Gampedaab38c2014-09-12 18:38:24 -0700892 Elf32_Sym* symbol = GetSymbol(section_type, i);
893 if (symbol == nullptr) {
894 return nullptr; // Failure condition.
895 }
896 const char* name = GetString(*string_section, symbol->st_name);
Alex Light3470ab42014-06-18 10:35:45 -0700897 if (name == nullptr) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800898 continue;
899 }
900 if (symbol_name == name) {
Andreas Gampedaab38c2014-09-12 18:38:24 -0700901 return symbol;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800902 }
903 }
Alex Light3470ab42014-06-18 10:35:45 -0700904 return nullptr;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800905}
906
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000907Elf32_Addr ElfFile::FindSymbolAddress(Elf32_Word section_type,
Brian Carlstromc1409452014-02-26 14:06:23 -0800908 const std::string& symbol_name,
909 bool build_map) {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000910 Elf32_Sym* symbol = FindSymbolByName(section_type, symbol_name, build_map);
Alex Light3470ab42014-06-18 10:35:45 -0700911 if (symbol == nullptr) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800912 return 0;
913 }
914 return symbol->st_value;
915}
916
Brian Carlstromc1409452014-02-26 14:06:23 -0800917const char* ElfFile::GetString(Elf32_Shdr& string_section, Elf32_Word i) const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800918 CHECK(!program_header_only_) << file_->GetPath();
919 // TODO: remove this static_cast from enum when using -std=gnu++0x
Andreas Gampedaab38c2014-09-12 18:38:24 -0700920 if (static_cast<Elf32_Word>(SHT_STRTAB) != string_section.sh_type) {
921 return nullptr; // Failure condition.
922 }
923 if (i >= string_section.sh_size) {
924 return nullptr;
925 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800926 if (i == 0) {
Alex Light3470ab42014-06-18 10:35:45 -0700927 return nullptr;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800928 }
929 byte* strings = Begin() + string_section.sh_offset;
930 byte* string = strings + i;
Andreas Gampedaab38c2014-09-12 18:38:24 -0700931 if (string >= End()) {
932 return nullptr;
933 }
Brian Carlstrom265091e2013-01-30 14:08:26 -0800934 return reinterpret_cast<const char*>(string);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800935}
936
Brian Carlstromc1409452014-02-26 14:06:23 -0800937Elf32_Word ElfFile::GetDynamicNum() const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000938 return GetDynamicProgramHeader().p_filesz / sizeof(Elf32_Dyn);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800939}
940
Brian Carlstromc1409452014-02-26 14:06:23 -0800941Elf32_Dyn& ElfFile::GetDynamic(Elf32_Word i) const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800942 CHECK_LT(i, GetDynamicNum()) << file_->GetPath();
943 return *(GetDynamicSectionStart() + i);
944}
945
Alex Light53cb16b2014-06-12 11:26:29 -0700946Elf32_Dyn* ElfFile::FindDynamicByType(Elf32_Sword type) const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000947 for (Elf32_Word i = 0; i < GetDynamicNum(); i++) {
Alex Light53cb16b2014-06-12 11:26:29 -0700948 Elf32_Dyn* dyn = &GetDynamic(i);
949 if (dyn->d_tag == type) {
950 return dyn;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800951 }
952 }
Alex Light53cb16b2014-06-12 11:26:29 -0700953 return NULL;
954}
955
956Elf32_Word ElfFile::FindDynamicValueByType(Elf32_Sword type) const {
957 Elf32_Dyn* dyn = FindDynamicByType(type);
958 if (dyn == NULL) {
959 return 0;
960 } else {
961 return dyn->d_un.d_val;
962 }
Brian Carlstrom265091e2013-01-30 14:08:26 -0800963}
964
Brian Carlstromc1409452014-02-26 14:06:23 -0800965Elf32_Rel* ElfFile::GetRelSectionStart(Elf32_Shdr& section_header) const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000966 CHECK(SHT_REL == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
967 return reinterpret_cast<Elf32_Rel*>(Begin() + section_header.sh_offset);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800968}
969
Brian Carlstromc1409452014-02-26 14:06:23 -0800970Elf32_Word ElfFile::GetRelNum(Elf32_Shdr& section_header) const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000971 CHECK(SHT_REL == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800972 CHECK_NE(0U, section_header.sh_entsize) << file_->GetPath();
973 return section_header.sh_size / section_header.sh_entsize;
974}
975
Brian Carlstromc1409452014-02-26 14:06:23 -0800976Elf32_Rel& ElfFile::GetRel(Elf32_Shdr& section_header, Elf32_Word i) const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000977 CHECK(SHT_REL == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800978 CHECK_LT(i, GetRelNum(section_header)) << file_->GetPath();
979 return *(GetRelSectionStart(section_header) + i);
980}
981
Brian Carlstromc1409452014-02-26 14:06:23 -0800982Elf32_Rela* ElfFile::GetRelaSectionStart(Elf32_Shdr& section_header) const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000983 CHECK(SHT_RELA == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
984 return reinterpret_cast<Elf32_Rela*>(Begin() + section_header.sh_offset);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800985}
986
Brian Carlstromc1409452014-02-26 14:06:23 -0800987Elf32_Word ElfFile::GetRelaNum(Elf32_Shdr& section_header) const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000988 CHECK(SHT_RELA == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800989 return section_header.sh_size / section_header.sh_entsize;
990}
991
Brian Carlstromc1409452014-02-26 14:06:23 -0800992Elf32_Rela& ElfFile::GetRela(Elf32_Shdr& section_header, Elf32_Word i) const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000993 CHECK(SHT_RELA == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800994 CHECK_LT(i, GetRelaNum(section_header)) << file_->GetPath();
995 return *(GetRelaSectionStart(section_header) + i);
996}
997
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800998// Base on bionic phdr_table_get_load_size
Brian Carlstromc1409452014-02-26 14:06:23 -0800999size_t ElfFile::GetLoadedSize() const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +00001000 Elf32_Addr min_vaddr = 0xFFFFFFFFu;
1001 Elf32_Addr max_vaddr = 0x00000000u;
1002 for (Elf32_Word i = 0; i < GetProgramHeaderNum(); i++) {
Andreas Gampedaab38c2014-09-12 18:38:24 -07001003 Elf32_Phdr* program_header = GetProgramHeader(i);
1004 if (program_header->p_type != PT_LOAD) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001005 continue;
1006 }
Andreas Gampedaab38c2014-09-12 18:38:24 -07001007 Elf32_Addr begin_vaddr = program_header->p_vaddr;
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001008 if (begin_vaddr < min_vaddr) {
1009 min_vaddr = begin_vaddr;
1010 }
Andreas Gampedaab38c2014-09-12 18:38:24 -07001011 Elf32_Addr end_vaddr = program_header->p_vaddr + program_header->p_memsz;
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001012 if (end_vaddr > max_vaddr) {
1013 max_vaddr = end_vaddr;
1014 }
1015 }
1016 min_vaddr = RoundDown(min_vaddr, kPageSize);
1017 max_vaddr = RoundUp(max_vaddr, kPageSize);
1018 CHECK_LT(min_vaddr, max_vaddr) << file_->GetPath();
1019 size_t loaded_size = max_vaddr - min_vaddr;
1020 return loaded_size;
1021}
1022
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001023bool ElfFile::Load(bool executable, std::string* error_msg) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001024 CHECK(program_header_only_) << file_->GetPath();
Andreas Gampe91268c12014-04-03 17:50:24 -07001025
1026 if (executable) {
1027 InstructionSet elf_ISA = kNone;
1028 switch (GetHeader().e_machine) {
1029 case EM_ARM: {
1030 elf_ISA = kArm;
1031 break;
1032 }
1033 case EM_AARCH64: {
1034 elf_ISA = kArm64;
1035 break;
1036 }
1037 case EM_386: {
1038 elf_ISA = kX86;
1039 break;
1040 }
1041 case EM_X86_64: {
1042 elf_ISA = kX86_64;
1043 break;
1044 }
1045 case EM_MIPS: {
1046 elf_ISA = kMips;
1047 break;
1048 }
1049 }
1050
1051 if (elf_ISA != kRuntimeISA) {
1052 std::ostringstream oss;
1053 oss << "Expected ISA " << kRuntimeISA << " but found " << elf_ISA;
1054 *error_msg = oss.str();
1055 return false;
1056 }
1057 }
1058
Jim_Guoa62a5882014-04-28 11:11:57 +08001059 bool reserved = false;
Nicolas Geoffray50cfe742014-02-19 13:27:42 +00001060 for (Elf32_Word i = 0; i < GetProgramHeaderNum(); i++) {
Andreas Gampedaab38c2014-09-12 18:38:24 -07001061 Elf32_Phdr* program_header = GetProgramHeader(i);
1062 if (program_header == nullptr) {
1063 *error_msg = StringPrintf("No program header for entry %d in ELF file %s.",
1064 i, file_->GetPath().c_str());
1065 return false;
1066 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001067
1068 // Record .dynamic header information for later use
Andreas Gampedaab38c2014-09-12 18:38:24 -07001069 if (program_header->p_type == PT_DYNAMIC) {
1070 dynamic_program_header_ = program_header;
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001071 continue;
1072 }
1073
1074 // Not something to load, move on.
Andreas Gampedaab38c2014-09-12 18:38:24 -07001075 if (program_header->p_type != PT_LOAD) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001076 continue;
1077 }
1078
1079 // Found something to load.
1080
Jim_Guoa62a5882014-04-28 11:11:57 +08001081 // Before load the actual segments, reserve a contiguous chunk
1082 // of required size and address for all segments, but with no
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001083 // permissions. We'll then carve that up with the proper
1084 // permissions as we load the actual segments. If p_vaddr is
1085 // non-zero, the segments require the specific address specified,
1086 // which either was specified in the file because we already set
1087 // base_address_ after the first zero segment).
Ian Rogerscdfcf372014-01-23 20:38:36 -08001088 int64_t temp_file_length = file_->GetLength();
1089 if (temp_file_length < 0) {
1090 errno = -temp_file_length;
1091 *error_msg = StringPrintf("Failed to get length of file: '%s' fd=%d: %s",
1092 file_->GetPath().c_str(), file_->Fd(), strerror(errno));
1093 return false;
1094 }
1095 size_t file_length = static_cast<size_t>(temp_file_length);
Jim_Guoa62a5882014-04-28 11:11:57 +08001096 if (!reserved) {
Andreas Gampedaab38c2014-09-12 18:38:24 -07001097 byte* reserve_base = ((program_header->p_vaddr != 0) ?
1098 reinterpret_cast<byte*>(program_header->p_vaddr) : nullptr);
Brian Carlstrom6a47b9d2013-05-17 10:58:25 -07001099 std::string reservation_name("ElfFile reservation for ");
1100 reservation_name += file_->GetPath();
Ian Rogers700a4022014-05-19 16:49:03 -07001101 std::unique_ptr<MemMap> reserve(MemMap::MapAnonymous(reservation_name.c_str(),
Jim_Guoa62a5882014-04-28 11:11:57 +08001102 reserve_base,
1103 GetLoadedSize(), PROT_NONE, false,
1104 error_msg));
Brian Carlstromc1409452014-02-26 14:06:23 -08001105 if (reserve.get() == nullptr) {
1106 *error_msg = StringPrintf("Failed to allocate %s: %s",
1107 reservation_name.c_str(), error_msg->c_str());
1108 return false;
1109 }
Jim_Guoa62a5882014-04-28 11:11:57 +08001110 reserved = true;
1111 if (reserve_base == nullptr) {
1112 base_address_ = reserve->Begin();
1113 }
Brian Carlstrom6a47b9d2013-05-17 10:58:25 -07001114 segments_.push_back(reserve.release());
1115 }
1116 // empty segment, nothing to map
Andreas Gampedaab38c2014-09-12 18:38:24 -07001117 if (program_header->p_memsz == 0) {
Brian Carlstrom6a47b9d2013-05-17 10:58:25 -07001118 continue;
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001119 }
Andreas Gampedaab38c2014-09-12 18:38:24 -07001120 byte* p_vaddr = base_address_ + program_header->p_vaddr;
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001121 int prot = 0;
Andreas Gampedaab38c2014-09-12 18:38:24 -07001122 if (executable && ((program_header->p_flags & PF_X) != 0)) {
Brian Carlstrom6a47b9d2013-05-17 10:58:25 -07001123 prot |= PROT_EXEC;
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001124 }
Andreas Gampedaab38c2014-09-12 18:38:24 -07001125 if ((program_header->p_flags & PF_W) != 0) {
Brian Carlstrom6a47b9d2013-05-17 10:58:25 -07001126 prot |= PROT_WRITE;
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001127 }
Andreas Gampedaab38c2014-09-12 18:38:24 -07001128 if ((program_header->p_flags & PF_R) != 0) {
Brian Carlstrom6a47b9d2013-05-17 10:58:25 -07001129 prot |= PROT_READ;
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001130 }
Hiroshi Yamauchi4fb5df82014-03-13 15:10:27 -07001131 int flags = 0;
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001132 if (writable_) {
1133 prot |= PROT_WRITE;
1134 flags |= MAP_SHARED;
1135 } else {
1136 flags |= MAP_PRIVATE;
1137 }
Andreas Gampedaab38c2014-09-12 18:38:24 -07001138 if (file_length < (program_header->p_offset + program_header->p_memsz)) {
Ian Rogerscdfcf372014-01-23 20:38:36 -08001139 *error_msg = StringPrintf("File size of %zd bytes not large enough to contain ELF segment "
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001140 "%d of %d bytes: '%s'", file_length, i,
Andreas Gampedaab38c2014-09-12 18:38:24 -07001141 program_header->p_offset + program_header->p_memsz,
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001142 file_->GetPath().c_str());
Brian Carlstrom3a223612013-10-10 17:18:24 -07001143 return false;
1144 }
Ian Rogers700a4022014-05-19 16:49:03 -07001145 std::unique_ptr<MemMap> segment(MemMap::MapFileAtAddress(p_vaddr,
Andreas Gampedaab38c2014-09-12 18:38:24 -07001146 program_header->p_memsz,
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001147 prot, flags, file_->Fd(),
Andreas Gampedaab38c2014-09-12 18:38:24 -07001148 program_header->p_offset,
Hiroshi Yamauchi4fb5df82014-03-13 15:10:27 -07001149 true, // implies MAP_FIXED
Ian Rogers8d31bbd2013-10-13 10:44:14 -07001150 file_->GetPath().c_str(),
1151 error_msg));
Brian Carlstromc1409452014-02-26 14:06:23 -08001152 if (segment.get() == nullptr) {
1153 *error_msg = StringPrintf("Failed to map ELF file segment %d from %s: %s",
1154 i, file_->GetPath().c_str(), error_msg->c_str());
1155 return false;
1156 }
1157 if (segment->Begin() != p_vaddr) {
1158 *error_msg = StringPrintf("Failed to map ELF file segment %d from %s at expected address %p, "
1159 "instead mapped to %p",
1160 i, file_->GetPath().c_str(), p_vaddr, segment->Begin());
1161 return false;
1162 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001163 segments_.push_back(segment.release());
1164 }
Brian Carlstrom265091e2013-01-30 14:08:26 -08001165
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001166 // Now that we are done loading, .dynamic should be in memory to find .dynstr, .dynsym, .hash
Andreas Gampedaab38c2014-09-12 18:38:24 -07001167 byte* dsptr = base_address_ + GetDynamicProgramHeader().p_vaddr;
1168 if ((dsptr < Begin() || dsptr >= End()) && !ValidPointer(dsptr)) {
1169 *error_msg = StringPrintf("dynamic section address invalid in ELF file %s",
1170 file_->GetPath().c_str());
1171 return false;
1172 }
1173 dynamic_section_start_ = reinterpret_cast<Elf32_Dyn*>(dsptr);
1174
Nicolas Geoffray50cfe742014-02-19 13:27:42 +00001175 for (Elf32_Word i = 0; i < GetDynamicNum(); i++) {
1176 Elf32_Dyn& elf_dyn = GetDynamic(i);
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001177 byte* d_ptr = base_address_ + elf_dyn.d_un.d_ptr;
1178 switch (elf_dyn.d_tag) {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +00001179 case DT_HASH: {
Brian Carlstromc1409452014-02-26 14:06:23 -08001180 if (!ValidPointer(d_ptr)) {
1181 *error_msg = StringPrintf("DT_HASH value %p does not refer to a loaded ELF segment of %s",
1182 d_ptr, file_->GetPath().c_str());
1183 return false;
1184 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +00001185 hash_section_start_ = reinterpret_cast<Elf32_Word*>(d_ptr);
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001186 break;
1187 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +00001188 case DT_STRTAB: {
Brian Carlstromc1409452014-02-26 14:06:23 -08001189 if (!ValidPointer(d_ptr)) {
1190 *error_msg = StringPrintf("DT_HASH value %p does not refer to a loaded ELF segment of %s",
1191 d_ptr, file_->GetPath().c_str());
1192 return false;
1193 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001194 dynstr_section_start_ = reinterpret_cast<char*>(d_ptr);
1195 break;
1196 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +00001197 case DT_SYMTAB: {
Brian Carlstromc1409452014-02-26 14:06:23 -08001198 if (!ValidPointer(d_ptr)) {
1199 *error_msg = StringPrintf("DT_HASH value %p does not refer to a loaded ELF segment of %s",
1200 d_ptr, file_->GetPath().c_str());
1201 return false;
1202 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +00001203 dynsym_section_start_ = reinterpret_cast<Elf32_Sym*>(d_ptr);
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001204 break;
1205 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +00001206 case DT_NULL: {
Brian Carlstromc1409452014-02-26 14:06:23 -08001207 if (GetDynamicNum() != i+1) {
1208 *error_msg = StringPrintf("DT_NULL found after %d .dynamic entries, "
1209 "expected %d as implied by size of PT_DYNAMIC segment in %s",
1210 i + 1, GetDynamicNum(), file_->GetPath().c_str());
1211 return false;
1212 }
Brian Carlstrom265091e2013-01-30 14:08:26 -08001213 break;
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001214 }
1215 }
1216 }
1217
Andreas Gampedaab38c2014-09-12 18:38:24 -07001218 // Check for the existence of some sections.
1219 if (!CheckSectionsExist(error_msg)) {
1220 return false;
1221 }
1222
Mark Mendellae9fd932014-02-10 16:14:35 -08001223 // Use GDB JIT support to do stack backtrace, etc.
1224 if (executable) {
1225 GdbJITSupport();
1226 }
1227
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001228 return true;
1229}
1230
Brian Carlstromc1409452014-02-26 14:06:23 -08001231bool ElfFile::ValidPointer(const byte* start) const {
1232 for (size_t i = 0; i < segments_.size(); ++i) {
1233 const MemMap* segment = segments_[i];
1234 if (segment->Begin() <= start && start < segment->End()) {
1235 return true;
1236 }
1237 }
1238 return false;
1239}
1240
Alex Light3470ab42014-06-18 10:35:45 -07001241
1242Elf32_Shdr* ElfFile::FindSectionByName(const std::string& name) const {
1243 CHECK(!program_header_only_);
Andreas Gampedaab38c2014-09-12 18:38:24 -07001244 Elf32_Shdr* shstrtab_sec = GetSectionNameStringSection();
1245 if (shstrtab_sec == nullptr) {
1246 return nullptr;
1247 }
Alex Light3470ab42014-06-18 10:35:45 -07001248 for (uint32_t i = 0; i < GetSectionHeaderNum(); i++) {
Andreas Gampedaab38c2014-09-12 18:38:24 -07001249 Elf32_Shdr* shdr = GetSectionHeader(i);
1250 if (shdr == nullptr) {
1251 return nullptr;
1252 }
1253 const char* sec_name = GetString(*shstrtab_sec, shdr->sh_name);
Alex Light3470ab42014-06-18 10:35:45 -07001254 if (sec_name == nullptr) {
1255 continue;
1256 }
1257 if (name == sec_name) {
Andreas Gampedaab38c2014-09-12 18:38:24 -07001258 return shdr;
Alex Light3470ab42014-06-18 10:35:45 -07001259 }
1260 }
1261 return nullptr;
Mark Mendellae9fd932014-02-10 16:14:35 -08001262}
1263
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001264struct PACKED(1) FDE32 {
Alex Light3470ab42014-06-18 10:35:45 -07001265 uint32_t raw_length_;
1266 uint32_t GetLength() {
1267 return raw_length_ + sizeof(raw_length_);
1268 }
1269 uint32_t CIE_pointer;
1270 uint32_t initial_location;
1271 uint32_t address_range;
1272 uint8_t instructions[0];
1273};
1274
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001275static FDE32* NextFDE(FDE32* frame) {
Alex Light3470ab42014-06-18 10:35:45 -07001276 byte* fde_bytes = reinterpret_cast<byte*>(frame);
1277 fde_bytes += frame->GetLength();
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001278 return reinterpret_cast<FDE32*>(fde_bytes);
Mark Mendellae9fd932014-02-10 16:14:35 -08001279}
1280
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001281static bool IsFDE(FDE32* frame) {
Tong Shen35e1e6a2014-07-30 09:31:22 -07001282 return frame->CIE_pointer != 0;
Alex Light3470ab42014-06-18 10:35:45 -07001283}
1284
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001285struct PACKED(1) FDE64 {
1286 uint32_t raw_length_;
1287 uint64_t extended_length_;
1288 uint64_t GetLength() {
1289 return extended_length_ + sizeof(raw_length_) + sizeof(extended_length_);
1290 }
1291 uint64_t CIE_pointer;
1292 uint64_t initial_location;
1293 uint64_t address_range;
1294 uint8_t instructions[0];
1295};
1296
1297static FDE64* NextFDE(FDE64* frame) {
1298 byte* fde_bytes = reinterpret_cast<byte*>(frame);
1299 fde_bytes += frame->GetLength();
1300 return reinterpret_cast<FDE64*>(fde_bytes);
1301}
1302
1303static bool IsFDE(FDE64* frame) {
1304 return frame->CIE_pointer != 0;
1305}
1306
1307static bool FixupEHFrame(off_t base_address_delta,
1308 byte* eh_frame, size_t eh_frame_size) {
1309 if (*(reinterpret_cast<uint32_t*>(eh_frame)) == 0xffffffff) {
1310 FDE64* last_frame = reinterpret_cast<FDE64*>(eh_frame + eh_frame_size);
1311 FDE64* frame = NextFDE(reinterpret_cast<FDE64*>(eh_frame));
1312 for (; frame < last_frame; frame = NextFDE(frame)) {
1313 if (!IsFDE(frame)) {
1314 return false;
1315 }
1316 frame->initial_location += base_address_delta;
1317 }
1318 return true;
1319 } else {
1320 FDE32* last_frame = reinterpret_cast<FDE32*>(eh_frame + eh_frame_size);
1321 FDE32* frame = NextFDE(reinterpret_cast<FDE32*>(eh_frame));
1322 for (; frame < last_frame; frame = NextFDE(frame)) {
1323 if (!IsFDE(frame)) {
1324 return false;
1325 }
1326 frame->initial_location += base_address_delta;
1327 }
1328 return true;
1329 }
1330}
1331
1332static uint8_t* NextLeb128(uint8_t* current) {
1333 DecodeUnsignedLeb128(const_cast<const uint8_t**>(&current));
1334 return current;
1335}
1336
1337struct PACKED(1) DebugLineHeader {
1338 uint32_t unit_length_; // TODO 32-bit specific size
1339 uint16_t version_;
1340 uint32_t header_length_; // TODO 32-bit specific size
1341 uint8_t minimum_instruction_lenght_;
1342 uint8_t maximum_operations_per_instruction_;
1343 uint8_t default_is_stmt_;
1344 int8_t line_base_;
1345 uint8_t line_range_;
1346 uint8_t opcode_base_;
1347 uint8_t remaining_[0];
1348
1349 bool IsStandardOpcode(const uint8_t* op) const {
1350 return *op != 0 && *op < opcode_base_;
1351 }
1352
1353 bool IsExtendedOpcode(const uint8_t* op) const {
1354 return *op == 0;
1355 }
1356
1357 const uint8_t* GetStandardOpcodeLengths() const {
1358 return remaining_;
1359 }
1360
1361 uint8_t* GetNextOpcode(uint8_t* op) const {
1362 if (IsExtendedOpcode(op)) {
1363 uint8_t* length_field = op + 1;
1364 uint32_t length = DecodeUnsignedLeb128(const_cast<const uint8_t**>(&length_field));
1365 return length_field + length;
1366 } else if (!IsStandardOpcode(op)) {
1367 return op + 1;
1368 } else if (*op == DW_LNS_fixed_advance_pc) {
1369 return op + 1 + sizeof(uint16_t);
1370 } else {
1371 uint8_t num_args = GetStandardOpcodeLengths()[*op - 1];
1372 op += 1;
1373 for (int i = 0; i < num_args; i++) {
1374 op = NextLeb128(op);
1375 }
1376 return op;
1377 }
1378 }
1379
1380 uint8_t* GetDebugLineData() const {
1381 const uint8_t* hdr_start =
1382 reinterpret_cast<const uint8_t*>(&header_length_) + sizeof(header_length_);
1383 return const_cast<uint8_t*>(hdr_start + header_length_);
1384 }
1385};
1386
1387class DebugLineInstructionIterator {
1388 public:
1389 static DebugLineInstructionIterator* Create(DebugLineHeader* header, size_t section_size) {
1390 std::unique_ptr<DebugLineInstructionIterator> line_iter(
1391 new DebugLineInstructionIterator(header, section_size));
1392 if (line_iter.get() == nullptr) {
1393 return nullptr;
1394 } else {
1395 return line_iter.release();
1396 }
1397 }
1398
1399 ~DebugLineInstructionIterator() {}
1400
1401 bool Next() {
1402 if (current_instruction_ == nullptr) {
Alex Light3470ab42014-06-18 10:35:45 -07001403 return false;
1404 }
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001405 current_instruction_ = header_->GetNextOpcode(current_instruction_);
1406 if (current_instruction_ >= last_instruction_) {
1407 current_instruction_ = nullptr;
1408 return false;
1409 } else {
1410 return true;
1411 }
1412 }
1413
1414 uint8_t* GetInstruction() {
1415 return current_instruction_;
1416 }
1417
1418 bool IsExtendedOpcode() {
1419 return header_->IsExtendedOpcode(current_instruction_);
1420 }
1421
1422 uint8_t GetOpcode() {
1423 if (!IsExtendedOpcode()) {
1424 return *current_instruction_;
1425 } else {
1426 uint8_t* len_ptr = current_instruction_ + 1;
1427 return *NextLeb128(len_ptr);
1428 }
1429 }
1430
1431 uint8_t* GetArguments() {
1432 if (!IsExtendedOpcode()) {
1433 return current_instruction_ + 1;
1434 } else {
1435 uint8_t* len_ptr = current_instruction_ + 1;
1436 return NextLeb128(len_ptr) + 1;
1437 }
1438 }
1439
1440 private:
1441 DebugLineInstructionIterator(DebugLineHeader* header, size_t size)
1442 : header_(header), last_instruction_(reinterpret_cast<uint8_t*>(header) + size),
1443 current_instruction_(header->GetDebugLineData()) {}
1444
1445 DebugLineHeader* header_;
1446 uint8_t* last_instruction_;
1447 uint8_t* current_instruction_;
1448};
1449
1450static bool FixupDebugLine(off_t base_offset_delta, DebugLineInstructionIterator* iter) {
1451 while (iter->Next()) {
1452 if (iter->IsExtendedOpcode() && iter->GetOpcode() == DW_LNE_set_address) {
1453 *reinterpret_cast<uint32_t*>(iter->GetArguments()) += base_offset_delta;
1454 }
Alex Light3470ab42014-06-18 10:35:45 -07001455 }
1456 return true;
1457}
1458
1459struct PACKED(1) DebugInfoHeader {
1460 uint32_t unit_length; // TODO 32-bit specific size
1461 uint16_t version;
1462 uint32_t debug_abbrev_offset; // TODO 32-bit specific size
1463 uint8_t address_size;
1464};
1465
1466// Returns -1 if it is variable length, which we will just disallow for now.
1467static int32_t FormLength(uint32_t att) {
1468 switch (att) {
1469 case DW_FORM_data1:
1470 case DW_FORM_flag:
1471 case DW_FORM_flag_present:
1472 case DW_FORM_ref1:
1473 return 1;
1474
1475 case DW_FORM_data2:
1476 case DW_FORM_ref2:
1477 return 2;
1478
1479 case DW_FORM_addr: // TODO 32-bit only
1480 case DW_FORM_ref_addr: // TODO 32-bit only
1481 case DW_FORM_sec_offset: // TODO 32-bit only
1482 case DW_FORM_strp: // TODO 32-bit only
1483 case DW_FORM_data4:
1484 case DW_FORM_ref4:
1485 return 4;
1486
1487 case DW_FORM_data8:
1488 case DW_FORM_ref8:
1489 case DW_FORM_ref_sig8:
1490 return 8;
1491
1492 case DW_FORM_block:
1493 case DW_FORM_block1:
1494 case DW_FORM_block2:
1495 case DW_FORM_block4:
1496 case DW_FORM_exprloc:
1497 case DW_FORM_indirect:
1498 case DW_FORM_ref_udata:
1499 case DW_FORM_sdata:
1500 case DW_FORM_string:
1501 case DW_FORM_udata:
1502 default:
1503 return -1;
Mark Mendellae9fd932014-02-10 16:14:35 -08001504 }
1505}
1506
Alex Light3470ab42014-06-18 10:35:45 -07001507class DebugTag {
1508 public:
1509 const uint32_t index_;
1510 ~DebugTag() {}
1511 // Creates a new tag and moves data pointer up to the start of the next one.
1512 // nullptr means error.
1513 static DebugTag* Create(const byte** data_pointer) {
1514 const byte* data = *data_pointer;
1515 uint32_t index = DecodeUnsignedLeb128(&data);
1516 std::unique_ptr<DebugTag> tag(new DebugTag(index));
1517 tag->size_ = static_cast<uint32_t>(
1518 reinterpret_cast<uintptr_t>(data) - reinterpret_cast<uintptr_t>(*data_pointer));
1519 // skip the abbrev
1520 tag->tag_ = DecodeUnsignedLeb128(&data);
1521 tag->has_child_ = (*data == 0);
1522 data++;
1523 while (true) {
1524 uint32_t attr = DecodeUnsignedLeb128(&data);
1525 uint32_t form = DecodeUnsignedLeb128(&data);
1526 if (attr == 0 && form == 0) {
1527 break;
1528 } else if (attr == 0 || form == 0) {
1529 // Bad abbrev.
1530 return nullptr;
1531 }
1532 int32_t size = FormLength(form);
1533 if (size == -1) {
1534 return nullptr;
1535 }
1536 tag->AddAttribute(attr, static_cast<uint32_t>(size));
1537 }
1538 *data_pointer = data;
1539 return tag.release();
1540 }
1541
1542 uint32_t GetSize() const {
1543 return size_;
1544 }
1545
1546 bool HasChild() {
1547 return has_child_;
1548 }
1549
1550 uint32_t GetTagNumber() {
1551 return tag_;
1552 }
1553
1554 // Gets the offset of a particular attribute in this tag structure.
1555 // Interpretation of the data is left to the consumer. 0 is returned if the
1556 // tag does not contain the attribute.
1557 uint32_t GetOffsetOf(uint32_t dwarf_attribute) const {
1558 auto it = off_map_.find(dwarf_attribute);
1559 if (it == off_map_.end()) {
1560 return 0;
1561 } else {
1562 return it->second;
1563 }
1564 }
1565
1566 // Gets the size of attribute
1567 uint32_t GetAttrSize(uint32_t dwarf_attribute) const {
1568 auto it = size_map_.find(dwarf_attribute);
1569 if (it == size_map_.end()) {
1570 return 0;
1571 } else {
1572 return it->second;
1573 }
1574 }
1575
1576 private:
Andreas Gampedaab38c2014-09-12 18:38:24 -07001577 explicit DebugTag(uint32_t index) : index_(index), size_(0), tag_(0), has_child_(false) {}
Alex Light3470ab42014-06-18 10:35:45 -07001578 void AddAttribute(uint32_t type, uint32_t attr_size) {
1579 off_map_.insert(std::pair<uint32_t, uint32_t>(type, size_));
1580 size_map_.insert(std::pair<uint32_t, uint32_t>(type, attr_size));
1581 size_ += attr_size;
1582 }
1583 std::map<uint32_t, uint32_t> off_map_;
1584 std::map<uint32_t, uint32_t> size_map_;
1585 uint32_t size_;
1586 uint32_t tag_;
1587 bool has_child_;
1588};
1589
1590class DebugAbbrev {
1591 public:
1592 ~DebugAbbrev() {}
1593 static DebugAbbrev* Create(const byte* dbg_abbrev, size_t dbg_abbrev_size) {
Alex Lightd338ae02014-08-13 17:15:38 -07001594 std::unique_ptr<DebugAbbrev> abbrev(new DebugAbbrev(dbg_abbrev, dbg_abbrev + dbg_abbrev_size));
1595 if (!abbrev->ReadAtOffset(0)) {
1596 return nullptr;
Alex Light3470ab42014-06-18 10:35:45 -07001597 }
1598 return abbrev.release();
1599 }
1600
Alex Lightd338ae02014-08-13 17:15:38 -07001601 bool ReadAtOffset(uint32_t abbrev_offset) {
1602 tags_.clear();
1603 tag_list_.clear();
1604 const byte* dbg_abbrev = begin_ + abbrev_offset;
1605 while (dbg_abbrev < end_ && *dbg_abbrev != 0) {
1606 std::unique_ptr<DebugTag> tag(DebugTag::Create(&dbg_abbrev));
1607 if (tag.get() == nullptr) {
1608 return false;
1609 } else {
1610 tags_.insert(std::pair<uint32_t, uint32_t>(tag->index_, tag_list_.size()));
1611 tag_list_.push_back(std::move(tag));
1612 }
1613 }
1614 return true;
1615 }
1616
Alex Light3470ab42014-06-18 10:35:45 -07001617 DebugTag* ReadTag(const byte* entry) {
1618 uint32_t tag_num = DecodeUnsignedLeb128(&entry);
1619 auto it = tags_.find(tag_num);
1620 if (it == tags_.end()) {
1621 return nullptr;
1622 } else {
1623 CHECK_GT(tag_list_.size(), it->second);
1624 return tag_list_.at(it->second).get();
1625 }
1626 }
1627
1628 private:
Alex Lightd338ae02014-08-13 17:15:38 -07001629 DebugAbbrev(const byte* begin, const byte* end) : begin_(begin), end_(end) {}
1630 const byte* begin_;
1631 const byte* end_;
Alex Light3470ab42014-06-18 10:35:45 -07001632 std::map<uint32_t, uint32_t> tags_;
1633 std::vector<std::unique_ptr<DebugTag>> tag_list_;
1634};
1635
1636class DebugInfoIterator {
1637 public:
1638 static DebugInfoIterator* Create(DebugInfoHeader* header, size_t frame_size,
1639 DebugAbbrev* abbrev) {
1640 std::unique_ptr<DebugInfoIterator> iter(new DebugInfoIterator(header, frame_size, abbrev));
1641 if (iter->GetCurrentTag() == nullptr) {
1642 return nullptr;
1643 } else {
1644 return iter.release();
1645 }
1646 }
1647 ~DebugInfoIterator() {}
1648
1649 // Moves to the next DIE. Returns false if at last entry.
1650 // TODO Handle variable length attributes.
1651 bool next() {
1652 if (current_entry_ == nullptr || current_tag_ == nullptr) {
1653 return false;
1654 }
Alex Lightd338ae02014-08-13 17:15:38 -07001655 bool reread_abbrev = false;
Alex Light3470ab42014-06-18 10:35:45 -07001656 current_entry_ += current_tag_->GetSize();
Alex Lightd338ae02014-08-13 17:15:38 -07001657 if (reinterpret_cast<DebugInfoHeader*>(current_entry_) >= next_cu_) {
1658 current_cu_ = next_cu_;
1659 next_cu_ = GetNextCu(current_cu_);
1660 current_entry_ = reinterpret_cast<byte*>(current_cu_) + sizeof(DebugInfoHeader);
1661 reread_abbrev = true;
1662 }
Alex Light3470ab42014-06-18 10:35:45 -07001663 if (current_entry_ >= last_entry_) {
1664 current_entry_ = nullptr;
1665 return false;
1666 }
Alex Lightd338ae02014-08-13 17:15:38 -07001667 if (reread_abbrev) {
1668 abbrev_->ReadAtOffset(current_cu_->debug_abbrev_offset);
1669 }
Alex Light3470ab42014-06-18 10:35:45 -07001670 current_tag_ = abbrev_->ReadTag(current_entry_);
1671 if (current_tag_ == nullptr) {
1672 current_entry_ = nullptr;
1673 return false;
1674 } else {
1675 return true;
1676 }
1677 }
1678
1679 const DebugTag* GetCurrentTag() {
1680 return const_cast<DebugTag*>(current_tag_);
1681 }
1682 byte* GetPointerToField(uint8_t dwarf_field) {
1683 if (current_tag_ == nullptr || current_entry_ == nullptr || current_entry_ >= last_entry_) {
1684 return nullptr;
1685 }
1686 uint32_t off = current_tag_->GetOffsetOf(dwarf_field);
1687 if (off == 0) {
1688 // tag does not have that field.
1689 return nullptr;
1690 } else {
1691 DCHECK_LT(off, current_tag_->GetSize());
1692 return current_entry_ + off;
1693 }
1694 }
1695
1696 private:
Alex Lightd338ae02014-08-13 17:15:38 -07001697 static DebugInfoHeader* GetNextCu(DebugInfoHeader* hdr) {
1698 byte* hdr_byte = reinterpret_cast<byte*>(hdr);
1699 return reinterpret_cast<DebugInfoHeader*>(hdr_byte + sizeof(uint32_t) + hdr->unit_length);
1700 }
1701
Alex Light3470ab42014-06-18 10:35:45 -07001702 DebugInfoIterator(DebugInfoHeader* header, size_t frame_size, DebugAbbrev* abbrev)
1703 : abbrev_(abbrev),
Alex Lightd338ae02014-08-13 17:15:38 -07001704 current_cu_(header),
1705 next_cu_(GetNextCu(header)),
Alex Light3470ab42014-06-18 10:35:45 -07001706 last_entry_(reinterpret_cast<byte*>(header) + frame_size),
1707 current_entry_(reinterpret_cast<byte*>(header) + sizeof(DebugInfoHeader)),
1708 current_tag_(abbrev_->ReadTag(current_entry_)) {}
1709 DebugAbbrev* abbrev_;
Alex Lightd338ae02014-08-13 17:15:38 -07001710 DebugInfoHeader* current_cu_;
1711 DebugInfoHeader* next_cu_;
Alex Light3470ab42014-06-18 10:35:45 -07001712 byte* last_entry_;
1713 byte* current_entry_;
1714 DebugTag* current_tag_;
1715};
1716
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001717static bool FixupDebugInfo(off_t base_address_delta, DebugInfoIterator* iter) {
Alex Light3470ab42014-06-18 10:35:45 -07001718 do {
1719 if (iter->GetCurrentTag()->GetAttrSize(DW_AT_low_pc) != sizeof(int32_t) ||
1720 iter->GetCurrentTag()->GetAttrSize(DW_AT_high_pc) != sizeof(int32_t)) {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001721 LOG(ERROR) << "DWARF information with 64 bit pointers is not supported yet.";
Alex Light3470ab42014-06-18 10:35:45 -07001722 return false;
1723 }
1724 uint32_t* PC_low = reinterpret_cast<uint32_t*>(iter->GetPointerToField(DW_AT_low_pc));
1725 uint32_t* PC_high = reinterpret_cast<uint32_t*>(iter->GetPointerToField(DW_AT_high_pc));
1726 if (PC_low != nullptr && PC_high != nullptr) {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001727 *PC_low += base_address_delta;
1728 *PC_high += base_address_delta;
Alex Light3470ab42014-06-18 10:35:45 -07001729 }
1730 } while (iter->next());
1731 return true;
1732}
1733
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001734bool ElfFile::FixupDebugSections(off_t base_address_delta) {
1735 const Elf32_Shdr* debug_info = FindSectionByName(".debug_info");
1736 const Elf32_Shdr* debug_abbrev = FindSectionByName(".debug_abbrev");
1737 const Elf32_Shdr* eh_frame = FindSectionByName(".eh_frame");
1738 const Elf32_Shdr* debug_str = FindSectionByName(".debug_str");
1739 const Elf32_Shdr* debug_line = FindSectionByName(".debug_line");
1740 const Elf32_Shdr* strtab_sec = FindSectionByName(".strtab");
1741 const Elf32_Shdr* symtab_sec = FindSectionByName(".symtab");
1742
1743 if (debug_info == nullptr || debug_abbrev == nullptr ||
1744 debug_str == nullptr || strtab_sec == nullptr || symtab_sec == nullptr) {
1745 // Release version of ART does not generate debug info.
1746 return true;
1747 }
1748 if (base_address_delta == 0) {
1749 return true;
1750 }
1751 if (eh_frame != nullptr &&
1752 !FixupEHFrame(base_address_delta, Begin() + eh_frame->sh_offset, eh_frame->sh_size)) {
1753 return false;
1754 }
1755
1756 std::unique_ptr<DebugAbbrev> abbrev(DebugAbbrev::Create(Begin() + debug_abbrev->sh_offset,
1757 debug_abbrev->sh_size));
Alex Light3470ab42014-06-18 10:35:45 -07001758 if (abbrev.get() == nullptr) {
1759 return false;
1760 }
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001761 DebugInfoHeader* info_header =
1762 reinterpret_cast<DebugInfoHeader*>(Begin() + debug_info->sh_offset);
1763 std::unique_ptr<DebugInfoIterator> info_iter(DebugInfoIterator::Create(info_header,
1764 debug_info->sh_size,
1765 abbrev.get()));
1766 if (info_iter.get() == nullptr) {
Alex Light3470ab42014-06-18 10:35:45 -07001767 return false;
1768 }
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001769 if (debug_line != nullptr) {
1770 DebugLineHeader* line_header =
1771 reinterpret_cast<DebugLineHeader*>(Begin() + debug_line->sh_offset);
1772 std::unique_ptr<DebugLineInstructionIterator> line_iter(
1773 DebugLineInstructionIterator::Create(line_header, debug_line->sh_size));
1774 if (line_iter.get() == nullptr) {
1775 return false;
1776 }
1777 if (!FixupDebugLine(base_address_delta, line_iter.get())) {
1778 return false;
1779 }
1780 }
1781 return FixupDebugInfo(base_address_delta, info_iter.get());
Alex Light3470ab42014-06-18 10:35:45 -07001782}
Mark Mendellae9fd932014-02-10 16:14:35 -08001783
1784void ElfFile::GdbJITSupport() {
1785 // We only get here if we only are mapping the program header.
1786 DCHECK(program_header_only_);
1787
1788 // Well, we need the whole file to do this.
1789 std::string error_msg;
Alex Light3470ab42014-06-18 10:35:45 -07001790 // Make it MAP_PRIVATE so we can just give it to gdb if all the necessary
1791 // sections are there.
1792 std::unique_ptr<ElfFile> all_ptr(Open(const_cast<File*>(file_), PROT_READ | PROT_WRITE,
1793 MAP_PRIVATE, &error_msg));
1794 if (all_ptr.get() == nullptr) {
Mark Mendellae9fd932014-02-10 16:14:35 -08001795 return;
1796 }
Alex Light3470ab42014-06-18 10:35:45 -07001797 ElfFile& all = *all_ptr;
1798
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001799 // We need the eh_frame for gdb but debug info might be present without it.
Tong Shen35e1e6a2014-07-30 09:31:22 -07001800 const Elf32_Shdr* eh_frame = all.FindSectionByName(".eh_frame");
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001801 if (eh_frame == nullptr) {
Mark Mendellae9fd932014-02-10 16:14:35 -08001802 return;
1803 }
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001804
1805 // Do we have interesting sections?
Alex Light3470ab42014-06-18 10:35:45 -07001806 // We need to add in a strtab and symtab to the image.
1807 // all is MAP_PRIVATE so it can be written to freely.
1808 // We also already have strtab and symtab so we are fine there.
1809 Elf32_Ehdr& elf_hdr = all.GetHeader();
Mark Mendellae9fd932014-02-10 16:14:35 -08001810 elf_hdr.e_entry = 0;
1811 elf_hdr.e_phoff = 0;
1812 elf_hdr.e_phnum = 0;
1813 elf_hdr.e_phentsize = 0;
1814 elf_hdr.e_type = ET_EXEC;
1815
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001816 // Since base_address_ is 0 if we are actually loaded at a known address (i.e. this is boot.oat)
1817 // and the actual address stuff starts at in regular files this is good.
1818 if (!all.FixupDebugSections(reinterpret_cast<intptr_t>(base_address_))) {
Alex Light3470ab42014-06-18 10:35:45 -07001819 LOG(ERROR) << "Failed to load GDB data";
1820 return;
Mark Mendellae9fd932014-02-10 16:14:35 -08001821 }
1822
Alex Light3470ab42014-06-18 10:35:45 -07001823 jit_gdb_entry_ = CreateCodeEntry(all.Begin(), all.Size());
1824 gdb_file_mapping_.reset(all_ptr.release());
Mark Mendellae9fd932014-02-10 16:14:35 -08001825}
1826
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001827} // namespace art