blob: 529cd534fa4c202dcde84d4660bc9fcd37c9baff [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
205 // Either way, the program header is relative to the elf header
206 program_headers_start_ = Begin() + GetHeader().e_phoff;
207
Brian Carlstromc1409452014-02-26 14:06:23 -0800208 if (!program_header_only_) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800209 // Setup section headers.
210 section_headers_start_ = Begin() + GetHeader().e_shoff;
211
212 // Find .dynamic section info from program header
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000213 dynamic_program_header_ = FindProgamHeaderByType(PT_DYNAMIC);
Alex Light3470ab42014-06-18 10:35:45 -0700214 if (dynamic_program_header_ == nullptr) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700215 *error_msg = StringPrintf("Failed to find PT_DYNAMIC program header in ELF file: '%s'",
216 file_->GetPath().c_str());
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800217 return false;
218 }
219
220 dynamic_section_start_
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000221 = reinterpret_cast<Elf32_Dyn*>(Begin() + GetDynamicProgramHeader().p_offset);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800222
223 // Find other sections from section headers
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000224 for (Elf32_Word i = 0; i < GetSectionHeaderNum(); i++) {
225 Elf32_Shdr& section_header = GetSectionHeader(i);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800226 byte* section_addr = Begin() + section_header.sh_offset;
227 switch (section_header.sh_type) {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000228 case SHT_SYMTAB: {
229 symtab_section_start_ = reinterpret_cast<Elf32_Sym*>(section_addr);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800230 break;
231 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000232 case SHT_DYNSYM: {
233 dynsym_section_start_ = reinterpret_cast<Elf32_Sym*>(section_addr);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800234 break;
235 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000236 case SHT_STRTAB: {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800237 // TODO: base these off of sh_link from .symtab and .dynsym above
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000238 if ((section_header.sh_flags & SHF_ALLOC) != 0) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800239 dynstr_section_start_ = reinterpret_cast<char*>(section_addr);
240 } else {
241 strtab_section_start_ = reinterpret_cast<char*>(section_addr);
242 }
243 break;
244 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000245 case SHT_DYNAMIC: {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800246 if (reinterpret_cast<byte*>(dynamic_section_start_) != section_addr) {
247 LOG(WARNING) << "Failed to find matching SHT_DYNAMIC for PT_DYNAMIC in "
Brian Carlstrom265091e2013-01-30 14:08:26 -0800248 << file_->GetPath() << ": " << std::hex
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800249 << reinterpret_cast<void*>(dynamic_section_start_)
250 << " != " << reinterpret_cast<void*>(section_addr);
251 return false;
252 }
253 break;
254 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000255 case SHT_HASH: {
256 hash_section_start_ = reinterpret_cast<Elf32_Word*>(section_addr);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800257 break;
258 }
259 }
260 }
261 }
262 return true;
263}
264
265ElfFile::~ElfFile() {
266 STLDeleteElements(&segments_);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800267 delete symtab_symbol_table_;
268 delete dynsym_symbol_table_;
Mark Mendellae9fd932014-02-10 16:14:35 -0800269 delete jit_elf_image_;
270 if (jit_gdb_entry_) {
271 UnregisterCodeEntry(jit_gdb_entry_);
272 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800273}
274
Brian Carlstromd0c09dc2013-11-06 18:25:35 -0800275bool ElfFile::SetMap(MemMap* map, std::string* error_msg) {
Alex Light3470ab42014-06-18 10:35:45 -0700276 if (map == nullptr) {
Brian Carlstromd0c09dc2013-11-06 18:25:35 -0800277 // MemMap::Open should have already set an error.
278 DCHECK(!error_msg->empty());
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800279 return false;
280 }
281 map_.reset(map);
Alex Light3470ab42014-06-18 10:35:45 -0700282 CHECK(map_.get() != nullptr) << file_->GetPath();
283 CHECK(map_->Begin() != nullptr) << file_->GetPath();
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800284
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000285 header_ = reinterpret_cast<Elf32_Ehdr*>(map_->Begin());
286 if ((ELFMAG0 != header_->e_ident[EI_MAG0])
287 || (ELFMAG1 != header_->e_ident[EI_MAG1])
288 || (ELFMAG2 != header_->e_ident[EI_MAG2])
289 || (ELFMAG3 != header_->e_ident[EI_MAG3])) {
Brian Carlstromc1409452014-02-26 14:06:23 -0800290 *error_msg = StringPrintf("Failed to find ELF magic value %d %d %d %d in %s, found %d %d %d %d",
291 ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3,
Brian Carlstromd0c09dc2013-11-06 18:25:35 -0800292 file_->GetPath().c_str(),
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000293 header_->e_ident[EI_MAG0],
294 header_->e_ident[EI_MAG1],
295 header_->e_ident[EI_MAG2],
296 header_->e_ident[EI_MAG3]);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800297 return false;
298 }
Brian Carlstromc1409452014-02-26 14:06:23 -0800299 if (ELFCLASS32 != header_->e_ident[EI_CLASS]) {
300 *error_msg = StringPrintf("Failed to find expected EI_CLASS value %d in %s, found %d",
301 ELFCLASS32,
302 file_->GetPath().c_str(),
303 header_->e_ident[EI_CLASS]);
304 return false;
305 }
306 if (ELFDATA2LSB != header_->e_ident[EI_DATA]) {
307 *error_msg = StringPrintf("Failed to find expected EI_DATA value %d in %s, found %d",
308 ELFDATA2LSB,
309 file_->GetPath().c_str(),
310 header_->e_ident[EI_CLASS]);
311 return false;
312 }
313 if (EV_CURRENT != header_->e_ident[EI_VERSION]) {
314 *error_msg = StringPrintf("Failed to find expected EI_VERSION value %d in %s, found %d",
315 EV_CURRENT,
316 file_->GetPath().c_str(),
317 header_->e_ident[EI_CLASS]);
318 return false;
319 }
320 if (ET_DYN != header_->e_type) {
321 *error_msg = StringPrintf("Failed to find expected e_type value %d in %s, found %d",
322 ET_DYN,
323 file_->GetPath().c_str(),
324 header_->e_type);
325 return false;
326 }
327 if (EV_CURRENT != header_->e_version) {
328 *error_msg = StringPrintf("Failed to find expected e_version value %d in %s, found %d",
329 EV_CURRENT,
330 file_->GetPath().c_str(),
331 header_->e_version);
332 return false;
333 }
334 if (0 != header_->e_entry) {
335 *error_msg = StringPrintf("Failed to find expected e_entry value %d in %s, found %d",
336 0,
337 file_->GetPath().c_str(),
338 header_->e_entry);
339 return false;
340 }
341 if (0 == header_->e_phoff) {
342 *error_msg = StringPrintf("Failed to find non-zero e_phoff value in %s",
343 file_->GetPath().c_str());
344 return false;
345 }
346 if (0 == header_->e_shoff) {
347 *error_msg = StringPrintf("Failed to find non-zero e_shoff value in %s",
348 file_->GetPath().c_str());
349 return false;
350 }
351 if (0 == header_->e_ehsize) {
352 *error_msg = StringPrintf("Failed to find non-zero e_ehsize value in %s",
353 file_->GetPath().c_str());
354 return false;
355 }
356 if (0 == header_->e_phentsize) {
357 *error_msg = StringPrintf("Failed to find non-zero e_phentsize value in %s",
358 file_->GetPath().c_str());
359 return false;
360 }
361 if (0 == header_->e_phnum) {
362 *error_msg = StringPrintf("Failed to find non-zero e_phnum value in %s",
363 file_->GetPath().c_str());
364 return false;
365 }
366 if (0 == header_->e_shentsize) {
367 *error_msg = StringPrintf("Failed to find non-zero e_shentsize value in %s",
368 file_->GetPath().c_str());
369 return false;
370 }
371 if (0 == header_->e_shnum) {
372 *error_msg = StringPrintf("Failed to find non-zero e_shnum value in %s",
373 file_->GetPath().c_str());
374 return false;
375 }
376 if (0 == header_->e_shstrndx) {
377 *error_msg = StringPrintf("Failed to find non-zero e_shstrndx value in %s",
378 file_->GetPath().c_str());
379 return false;
380 }
381 if (header_->e_shstrndx >= header_->e_shnum) {
382 *error_msg = StringPrintf("Failed to find e_shnum value %d less than %d in %s",
383 header_->e_shstrndx,
384 header_->e_shnum,
385 file_->GetPath().c_str());
386 return false;
387 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800388
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800389 if (!program_header_only_) {
Brian Carlstromc1409452014-02-26 14:06:23 -0800390 if (header_->e_phoff >= Size()) {
Dmitry Petrochenko659d87d2014-02-27 14:23:11 +0700391 *error_msg = StringPrintf("Failed to find e_phoff value %d less than %zd in %s",
Brian Carlstromc1409452014-02-26 14:06:23 -0800392 header_->e_phoff,
393 Size(),
394 file_->GetPath().c_str());
395 return false;
396 }
397 if (header_->e_shoff >= Size()) {
Dmitry Petrochenko659d87d2014-02-27 14:23:11 +0700398 *error_msg = StringPrintf("Failed to find e_shoff value %d less than %zd in %s",
Brian Carlstromc1409452014-02-26 14:06:23 -0800399 header_->e_shoff,
400 Size(),
401 file_->GetPath().c_str());
402 return false;
403 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800404 }
405 return true;
406}
407
408
Brian Carlstromc1409452014-02-26 14:06:23 -0800409Elf32_Ehdr& ElfFile::GetHeader() const {
Alex Light3470ab42014-06-18 10:35:45 -0700410 CHECK(header_ != nullptr);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800411 return *header_;
412}
413
Brian Carlstromc1409452014-02-26 14:06:23 -0800414byte* ElfFile::GetProgramHeadersStart() const {
Alex Light3470ab42014-06-18 10:35:45 -0700415 CHECK(program_headers_start_ != nullptr);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800416 return program_headers_start_;
417}
418
Brian Carlstromc1409452014-02-26 14:06:23 -0800419byte* ElfFile::GetSectionHeadersStart() const {
Alex Light3470ab42014-06-18 10:35:45 -0700420 CHECK(section_headers_start_ != nullptr);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800421 return section_headers_start_;
422}
423
Brian Carlstromc1409452014-02-26 14:06:23 -0800424Elf32_Phdr& ElfFile::GetDynamicProgramHeader() const {
Alex Light3470ab42014-06-18 10:35:45 -0700425 CHECK(dynamic_program_header_ != nullptr);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800426 return *dynamic_program_header_;
427}
428
Brian Carlstromc1409452014-02-26 14:06:23 -0800429Elf32_Dyn* ElfFile::GetDynamicSectionStart() const {
Alex Light3470ab42014-06-18 10:35:45 -0700430 CHECK(dynamic_section_start_ != nullptr);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800431 return dynamic_section_start_;
432}
433
Brian Carlstromc1409452014-02-26 14:06:23 -0800434Elf32_Sym* ElfFile::GetSymbolSectionStart(Elf32_Word section_type) const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800435 CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type;
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000436 Elf32_Sym* symbol_section_start;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800437 switch (section_type) {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000438 case SHT_SYMTAB: {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800439 symbol_section_start = symtab_section_start_;
440 break;
441 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000442 case SHT_DYNSYM: {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800443 symbol_section_start = dynsym_section_start_;
444 break;
445 }
446 default: {
447 LOG(FATAL) << section_type;
Alex Light3470ab42014-06-18 10:35:45 -0700448 symbol_section_start = nullptr;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800449 }
450 }
Alex Light3470ab42014-06-18 10:35:45 -0700451 CHECK(symbol_section_start != nullptr);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800452 return symbol_section_start;
453}
454
Brian Carlstromc1409452014-02-26 14:06:23 -0800455const char* ElfFile::GetStringSectionStart(Elf32_Word section_type) const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800456 CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800457 const char* string_section_start;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800458 switch (section_type) {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000459 case SHT_SYMTAB: {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800460 string_section_start = strtab_section_start_;
461 break;
462 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000463 case SHT_DYNSYM: {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800464 string_section_start = dynstr_section_start_;
465 break;
466 }
467 default: {
468 LOG(FATAL) << section_type;
Alex Light3470ab42014-06-18 10:35:45 -0700469 string_section_start = nullptr;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800470 }
471 }
Alex Light3470ab42014-06-18 10:35:45 -0700472 CHECK(string_section_start != nullptr);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800473 return string_section_start;
474}
475
Brian Carlstromc1409452014-02-26 14:06:23 -0800476const char* ElfFile::GetString(Elf32_Word section_type, Elf32_Word i) const {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800477 CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type;
478 if (i == 0) {
Alex Light3470ab42014-06-18 10:35:45 -0700479 return nullptr;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800480 }
481 const char* string_section_start = GetStringSectionStart(section_type);
482 const char* string = string_section_start + i;
483 return string;
484}
485
Brian Carlstromc1409452014-02-26 14:06:23 -0800486Elf32_Word* ElfFile::GetHashSectionStart() const {
Alex Light3470ab42014-06-18 10:35:45 -0700487 CHECK(hash_section_start_ != nullptr);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800488 return hash_section_start_;
489}
490
Brian Carlstromc1409452014-02-26 14:06:23 -0800491Elf32_Word ElfFile::GetHashBucketNum() const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800492 return GetHashSectionStart()[0];
493}
494
Brian Carlstromc1409452014-02-26 14:06:23 -0800495Elf32_Word ElfFile::GetHashChainNum() const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800496 return GetHashSectionStart()[1];
497}
498
Brian Carlstromc1409452014-02-26 14:06:23 -0800499Elf32_Word ElfFile::GetHashBucket(size_t i) const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800500 CHECK_LT(i, GetHashBucketNum());
501 // 0 is nbucket, 1 is nchain
502 return GetHashSectionStart()[2 + i];
503}
504
Brian Carlstromc1409452014-02-26 14:06:23 -0800505Elf32_Word ElfFile::GetHashChain(size_t i) const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800506 CHECK_LT(i, GetHashChainNum());
507 // 0 is nbucket, 1 is nchain, & chains are after buckets
508 return GetHashSectionStart()[2 + GetHashBucketNum() + i];
509}
510
Brian Carlstromc1409452014-02-26 14:06:23 -0800511Elf32_Word ElfFile::GetProgramHeaderNum() const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800512 return GetHeader().e_phnum;
513}
514
Brian Carlstromc1409452014-02-26 14:06:23 -0800515Elf32_Phdr& ElfFile::GetProgramHeader(Elf32_Word i) const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800516 CHECK_LT(i, GetProgramHeaderNum()) << file_->GetPath();
517 byte* program_header = GetProgramHeadersStart() + (i * GetHeader().e_phentsize);
518 CHECK_LT(program_header, End()) << file_->GetPath();
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000519 return *reinterpret_cast<Elf32_Phdr*>(program_header);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800520}
521
Brian Carlstromc1409452014-02-26 14:06:23 -0800522Elf32_Phdr* ElfFile::FindProgamHeaderByType(Elf32_Word type) const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000523 for (Elf32_Word i = 0; i < GetProgramHeaderNum(); i++) {
524 Elf32_Phdr& program_header = GetProgramHeader(i);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800525 if (program_header.p_type == type) {
526 return &program_header;
527 }
528 }
Alex Light3470ab42014-06-18 10:35:45 -0700529 return nullptr;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800530}
531
Brian Carlstromc1409452014-02-26 14:06:23 -0800532Elf32_Word ElfFile::GetSectionHeaderNum() const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800533 return GetHeader().e_shnum;
534}
535
Brian Carlstromc1409452014-02-26 14:06:23 -0800536Elf32_Shdr& ElfFile::GetSectionHeader(Elf32_Word i) const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800537 // Can only access arbitrary sections when we have the whole file, not just program header.
538 // Even if we Load(), it doesn't bring in all the sections.
539 CHECK(!program_header_only_) << file_->GetPath();
540 CHECK_LT(i, GetSectionHeaderNum()) << file_->GetPath();
541 byte* section_header = GetSectionHeadersStart() + (i * GetHeader().e_shentsize);
542 CHECK_LT(section_header, End()) << file_->GetPath();
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000543 return *reinterpret_cast<Elf32_Shdr*>(section_header);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800544}
545
Brian Carlstromc1409452014-02-26 14:06:23 -0800546Elf32_Shdr* ElfFile::FindSectionByType(Elf32_Word type) const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800547 // Can only access arbitrary sections when we have the whole file, not just program header.
548 // We could change this to switch on known types if they were detected during loading.
549 CHECK(!program_header_only_) << file_->GetPath();
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000550 for (Elf32_Word i = 0; i < GetSectionHeaderNum(); i++) {
551 Elf32_Shdr& section_header = GetSectionHeader(i);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800552 if (section_header.sh_type == type) {
553 return &section_header;
554 }
555 }
Alex Light3470ab42014-06-18 10:35:45 -0700556 return nullptr;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800557}
558
559// from bionic
Brian Carlstrom265091e2013-01-30 14:08:26 -0800560static unsigned elfhash(const char *_name) {
561 const unsigned char *name = (const unsigned char *) _name;
562 unsigned h = 0, g;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800563
Brian Carlstromdf629502013-07-17 22:39:56 -0700564 while (*name) {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800565 h = (h << 4) + *name++;
566 g = h & 0xf0000000;
567 h ^= g;
568 h ^= g >> 24;
569 }
570 return h;
571}
572
Brian Carlstromc1409452014-02-26 14:06:23 -0800573Elf32_Shdr& ElfFile::GetSectionNameStringSection() const {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800574 return GetSectionHeader(GetHeader().e_shstrndx);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800575}
576
Brian Carlstromc1409452014-02-26 14:06:23 -0800577const byte* ElfFile::FindDynamicSymbolAddress(const std::string& symbol_name) const {
Alex Light3470ab42014-06-18 10:35:45 -0700578 const Elf32_Sym* sym = FindDynamicSymbol(symbol_name);
579 if (sym != nullptr) {
580 return base_address_ + sym->st_value;
581 } else {
582 return nullptr;
583 }
584}
585
586const Elf32_Sym* ElfFile::FindDynamicSymbol(const std::string& symbol_name) const {
Andreas Gampec48b2062014-09-08 23:39:45 -0700587 if (GetHashBucketNum() == 0) {
588 // No dynamic symbols at all.
589 return nullptr;
590 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000591 Elf32_Word hash = elfhash(symbol_name.c_str());
592 Elf32_Word bucket_index = hash % GetHashBucketNum();
593 Elf32_Word symbol_and_chain_index = GetHashBucket(bucket_index);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800594 while (symbol_and_chain_index != 0 /* STN_UNDEF */) {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000595 Elf32_Sym& symbol = GetSymbol(SHT_DYNSYM, symbol_and_chain_index);
596 const char* name = GetString(SHT_DYNSYM, symbol.st_name);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800597 if (symbol_name == name) {
Alex Light3470ab42014-06-18 10:35:45 -0700598 return &symbol;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800599 }
600 symbol_and_chain_index = GetHashChain(symbol_and_chain_index);
601 }
Alex Light3470ab42014-06-18 10:35:45 -0700602 return nullptr;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800603}
604
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000605bool ElfFile::IsSymbolSectionType(Elf32_Word section_type) {
606 return ((section_type == SHT_SYMTAB) || (section_type == SHT_DYNSYM));
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800607}
608
Brian Carlstromc1409452014-02-26 14:06:23 -0800609Elf32_Word ElfFile::GetSymbolNum(Elf32_Shdr& section_header) const {
610 CHECK(IsSymbolSectionType(section_header.sh_type))
611 << file_->GetPath() << " " << section_header.sh_type;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800612 CHECK_NE(0U, section_header.sh_entsize) << file_->GetPath();
613 return section_header.sh_size / section_header.sh_entsize;
614}
615
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000616Elf32_Sym& ElfFile::GetSymbol(Elf32_Word section_type,
Brian Carlstromc1409452014-02-26 14:06:23 -0800617 Elf32_Word i) const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800618 return *(GetSymbolSectionStart(section_type) + i);
619}
620
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000621ElfFile::SymbolTable** ElfFile::GetSymbolTable(Elf32_Word section_type) {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800622 CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type;
623 switch (section_type) {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000624 case SHT_SYMTAB: {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800625 return &symtab_symbol_table_;
626 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000627 case SHT_DYNSYM: {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800628 return &dynsym_symbol_table_;
629 }
630 default: {
631 LOG(FATAL) << section_type;
Alex Light3470ab42014-06-18 10:35:45 -0700632 return nullptr;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800633 }
634 }
635}
636
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000637Elf32_Sym* ElfFile::FindSymbolByName(Elf32_Word section_type,
638 const std::string& symbol_name,
639 bool build_map) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800640 CHECK(!program_header_only_) << file_->GetPath();
641 CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800642
643 SymbolTable** symbol_table = GetSymbolTable(section_type);
Alex Light3470ab42014-06-18 10:35:45 -0700644 if (*symbol_table != nullptr || build_map) {
645 if (*symbol_table == nullptr) {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800646 DCHECK(build_map);
647 *symbol_table = new SymbolTable;
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000648 Elf32_Shdr* symbol_section = FindSectionByType(section_type);
Alex Light3470ab42014-06-18 10:35:45 -0700649 CHECK(symbol_section != nullptr) << file_->GetPath();
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000650 Elf32_Shdr& string_section = GetSectionHeader(symbol_section->sh_link);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800651 for (uint32_t i = 0; i < GetSymbolNum(*symbol_section); i++) {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000652 Elf32_Sym& symbol = GetSymbol(section_type, i);
653 unsigned char type = ELF32_ST_TYPE(symbol.st_info);
654 if (type == STT_NOTYPE) {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800655 continue;
656 }
657 const char* name = GetString(string_section, symbol.st_name);
Alex Light3470ab42014-06-18 10:35:45 -0700658 if (name == nullptr) {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800659 continue;
660 }
Brian Carlstromc1409452014-02-26 14:06:23 -0800661 std::pair<SymbolTable::iterator, bool> result =
662 (*symbol_table)->insert(std::make_pair(name, &symbol));
Brian Carlstrom265091e2013-01-30 14:08:26 -0800663 if (!result.second) {
664 // If a duplicate, make sure it has the same logical value. Seen on x86.
665 CHECK_EQ(symbol.st_value, result.first->second->st_value);
666 CHECK_EQ(symbol.st_size, result.first->second->st_size);
667 CHECK_EQ(symbol.st_info, result.first->second->st_info);
668 CHECK_EQ(symbol.st_other, result.first->second->st_other);
669 CHECK_EQ(symbol.st_shndx, result.first->second->st_shndx);
670 }
671 }
672 }
Alex Light3470ab42014-06-18 10:35:45 -0700673 CHECK(*symbol_table != nullptr);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800674 SymbolTable::const_iterator it = (*symbol_table)->find(symbol_name);
675 if (it == (*symbol_table)->end()) {
Alex Light3470ab42014-06-18 10:35:45 -0700676 return nullptr;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800677 }
678 return it->second;
679 }
680
681 // Fall back to linear search
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000682 Elf32_Shdr* symbol_section = FindSectionByType(section_type);
Alex Light3470ab42014-06-18 10:35:45 -0700683 CHECK(symbol_section != nullptr) << file_->GetPath();
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000684 Elf32_Shdr& string_section = GetSectionHeader(symbol_section->sh_link);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800685 for (uint32_t i = 0; i < GetSymbolNum(*symbol_section); i++) {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000686 Elf32_Sym& symbol = GetSymbol(section_type, i);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800687 const char* name = GetString(string_section, symbol.st_name);
Alex Light3470ab42014-06-18 10:35:45 -0700688 if (name == nullptr) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800689 continue;
690 }
691 if (symbol_name == name) {
692 return &symbol;
693 }
694 }
Alex Light3470ab42014-06-18 10:35:45 -0700695 return nullptr;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800696}
697
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000698Elf32_Addr ElfFile::FindSymbolAddress(Elf32_Word section_type,
Brian Carlstromc1409452014-02-26 14:06:23 -0800699 const std::string& symbol_name,
700 bool build_map) {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000701 Elf32_Sym* symbol = FindSymbolByName(section_type, symbol_name, build_map);
Alex Light3470ab42014-06-18 10:35:45 -0700702 if (symbol == nullptr) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800703 return 0;
704 }
705 return symbol->st_value;
706}
707
Brian Carlstromc1409452014-02-26 14:06:23 -0800708const char* ElfFile::GetString(Elf32_Shdr& string_section, Elf32_Word i) const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800709 CHECK(!program_header_only_) << file_->GetPath();
710 // TODO: remove this static_cast from enum when using -std=gnu++0x
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000711 CHECK_EQ(static_cast<Elf32_Word>(SHT_STRTAB), string_section.sh_type) << file_->GetPath();
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800712 CHECK_LT(i, string_section.sh_size) << file_->GetPath();
713 if (i == 0) {
Alex Light3470ab42014-06-18 10:35:45 -0700714 return nullptr;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800715 }
716 byte* strings = Begin() + string_section.sh_offset;
717 byte* string = strings + i;
718 CHECK_LT(string, End()) << file_->GetPath();
Brian Carlstrom265091e2013-01-30 14:08:26 -0800719 return reinterpret_cast<const char*>(string);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800720}
721
Brian Carlstromc1409452014-02-26 14:06:23 -0800722Elf32_Word ElfFile::GetDynamicNum() const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000723 return GetDynamicProgramHeader().p_filesz / sizeof(Elf32_Dyn);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800724}
725
Brian Carlstromc1409452014-02-26 14:06:23 -0800726Elf32_Dyn& ElfFile::GetDynamic(Elf32_Word i) const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800727 CHECK_LT(i, GetDynamicNum()) << file_->GetPath();
728 return *(GetDynamicSectionStart() + i);
729}
730
Alex Light53cb16b2014-06-12 11:26:29 -0700731Elf32_Dyn* ElfFile::FindDynamicByType(Elf32_Sword type) const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000732 for (Elf32_Word i = 0; i < GetDynamicNum(); i++) {
Alex Light53cb16b2014-06-12 11:26:29 -0700733 Elf32_Dyn* dyn = &GetDynamic(i);
734 if (dyn->d_tag == type) {
735 return dyn;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800736 }
737 }
Alex Light53cb16b2014-06-12 11:26:29 -0700738 return NULL;
739}
740
741Elf32_Word ElfFile::FindDynamicValueByType(Elf32_Sword type) const {
742 Elf32_Dyn* dyn = FindDynamicByType(type);
743 if (dyn == NULL) {
744 return 0;
745 } else {
746 return dyn->d_un.d_val;
747 }
Brian Carlstrom265091e2013-01-30 14:08:26 -0800748}
749
Brian Carlstromc1409452014-02-26 14:06:23 -0800750Elf32_Rel* ElfFile::GetRelSectionStart(Elf32_Shdr& section_header) const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000751 CHECK(SHT_REL == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
752 return reinterpret_cast<Elf32_Rel*>(Begin() + section_header.sh_offset);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800753}
754
Brian Carlstromc1409452014-02-26 14:06:23 -0800755Elf32_Word ElfFile::GetRelNum(Elf32_Shdr& section_header) const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000756 CHECK(SHT_REL == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800757 CHECK_NE(0U, section_header.sh_entsize) << file_->GetPath();
758 return section_header.sh_size / section_header.sh_entsize;
759}
760
Brian Carlstromc1409452014-02-26 14:06:23 -0800761Elf32_Rel& ElfFile::GetRel(Elf32_Shdr& section_header, Elf32_Word i) const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000762 CHECK(SHT_REL == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800763 CHECK_LT(i, GetRelNum(section_header)) << file_->GetPath();
764 return *(GetRelSectionStart(section_header) + i);
765}
766
Brian Carlstromc1409452014-02-26 14:06:23 -0800767Elf32_Rela* ElfFile::GetRelaSectionStart(Elf32_Shdr& section_header) const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000768 CHECK(SHT_RELA == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
769 return reinterpret_cast<Elf32_Rela*>(Begin() + section_header.sh_offset);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800770}
771
Brian Carlstromc1409452014-02-26 14:06:23 -0800772Elf32_Word ElfFile::GetRelaNum(Elf32_Shdr& section_header) const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000773 CHECK(SHT_RELA == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800774 return section_header.sh_size / section_header.sh_entsize;
775}
776
Brian Carlstromc1409452014-02-26 14:06:23 -0800777Elf32_Rela& ElfFile::GetRela(Elf32_Shdr& section_header, Elf32_Word i) const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000778 CHECK(SHT_RELA == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800779 CHECK_LT(i, GetRelaNum(section_header)) << file_->GetPath();
780 return *(GetRelaSectionStart(section_header) + i);
781}
782
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800783// Base on bionic phdr_table_get_load_size
Brian Carlstromc1409452014-02-26 14:06:23 -0800784size_t ElfFile::GetLoadedSize() const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000785 Elf32_Addr min_vaddr = 0xFFFFFFFFu;
786 Elf32_Addr max_vaddr = 0x00000000u;
787 for (Elf32_Word i = 0; i < GetProgramHeaderNum(); i++) {
788 Elf32_Phdr& program_header = GetProgramHeader(i);
789 if (program_header.p_type != PT_LOAD) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800790 continue;
791 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000792 Elf32_Addr begin_vaddr = program_header.p_vaddr;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800793 if (begin_vaddr < min_vaddr) {
794 min_vaddr = begin_vaddr;
795 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000796 Elf32_Addr end_vaddr = program_header.p_vaddr + program_header.p_memsz;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800797 if (end_vaddr > max_vaddr) {
798 max_vaddr = end_vaddr;
799 }
800 }
801 min_vaddr = RoundDown(min_vaddr, kPageSize);
802 max_vaddr = RoundUp(max_vaddr, kPageSize);
803 CHECK_LT(min_vaddr, max_vaddr) << file_->GetPath();
804 size_t loaded_size = max_vaddr - min_vaddr;
805 return loaded_size;
806}
807
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700808bool ElfFile::Load(bool executable, std::string* error_msg) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800809 CHECK(program_header_only_) << file_->GetPath();
Andreas Gampe91268c12014-04-03 17:50:24 -0700810
811 if (executable) {
812 InstructionSet elf_ISA = kNone;
813 switch (GetHeader().e_machine) {
814 case EM_ARM: {
815 elf_ISA = kArm;
816 break;
817 }
818 case EM_AARCH64: {
819 elf_ISA = kArm64;
820 break;
821 }
822 case EM_386: {
823 elf_ISA = kX86;
824 break;
825 }
826 case EM_X86_64: {
827 elf_ISA = kX86_64;
828 break;
829 }
830 case EM_MIPS: {
831 elf_ISA = kMips;
832 break;
833 }
834 }
835
836 if (elf_ISA != kRuntimeISA) {
837 std::ostringstream oss;
838 oss << "Expected ISA " << kRuntimeISA << " but found " << elf_ISA;
839 *error_msg = oss.str();
840 return false;
841 }
842 }
843
Jim_Guoa62a5882014-04-28 11:11:57 +0800844 bool reserved = false;
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000845 for (Elf32_Word i = 0; i < GetProgramHeaderNum(); i++) {
846 Elf32_Phdr& program_header = GetProgramHeader(i);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800847
848 // Record .dynamic header information for later use
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000849 if (program_header.p_type == PT_DYNAMIC) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800850 dynamic_program_header_ = &program_header;
851 continue;
852 }
853
854 // Not something to load, move on.
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000855 if (program_header.p_type != PT_LOAD) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800856 continue;
857 }
858
859 // Found something to load.
860
Jim_Guoa62a5882014-04-28 11:11:57 +0800861 // Before load the actual segments, reserve a contiguous chunk
862 // of required size and address for all segments, but with no
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800863 // permissions. We'll then carve that up with the proper
864 // permissions as we load the actual segments. If p_vaddr is
865 // non-zero, the segments require the specific address specified,
866 // which either was specified in the file because we already set
867 // base_address_ after the first zero segment).
Ian Rogerscdfcf372014-01-23 20:38:36 -0800868 int64_t temp_file_length = file_->GetLength();
869 if (temp_file_length < 0) {
870 errno = -temp_file_length;
871 *error_msg = StringPrintf("Failed to get length of file: '%s' fd=%d: %s",
872 file_->GetPath().c_str(), file_->Fd(), strerror(errno));
873 return false;
874 }
875 size_t file_length = static_cast<size_t>(temp_file_length);
Jim_Guoa62a5882014-04-28 11:11:57 +0800876 if (!reserved) {
877 byte* reserve_base = ((program_header.p_vaddr != 0) ?
878 reinterpret_cast<byte*>(program_header.p_vaddr) : nullptr);
Brian Carlstrom6a47b9d2013-05-17 10:58:25 -0700879 std::string reservation_name("ElfFile reservation for ");
880 reservation_name += file_->GetPath();
Ian Rogers700a4022014-05-19 16:49:03 -0700881 std::unique_ptr<MemMap> reserve(MemMap::MapAnonymous(reservation_name.c_str(),
Jim_Guoa62a5882014-04-28 11:11:57 +0800882 reserve_base,
883 GetLoadedSize(), PROT_NONE, false,
884 error_msg));
Brian Carlstromc1409452014-02-26 14:06:23 -0800885 if (reserve.get() == nullptr) {
886 *error_msg = StringPrintf("Failed to allocate %s: %s",
887 reservation_name.c_str(), error_msg->c_str());
888 return false;
889 }
Jim_Guoa62a5882014-04-28 11:11:57 +0800890 reserved = true;
891 if (reserve_base == nullptr) {
892 base_address_ = reserve->Begin();
893 }
Brian Carlstrom6a47b9d2013-05-17 10:58:25 -0700894 segments_.push_back(reserve.release());
895 }
896 // empty segment, nothing to map
897 if (program_header.p_memsz == 0) {
898 continue;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800899 }
900 byte* p_vaddr = base_address_ + program_header.p_vaddr;
901 int prot = 0;
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000902 if (executable && ((program_header.p_flags & PF_X) != 0)) {
Brian Carlstrom6a47b9d2013-05-17 10:58:25 -0700903 prot |= PROT_EXEC;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800904 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000905 if ((program_header.p_flags & PF_W) != 0) {
Brian Carlstrom6a47b9d2013-05-17 10:58:25 -0700906 prot |= PROT_WRITE;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800907 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000908 if ((program_header.p_flags & PF_R) != 0) {
Brian Carlstrom6a47b9d2013-05-17 10:58:25 -0700909 prot |= PROT_READ;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800910 }
Hiroshi Yamauchi4fb5df82014-03-13 15:10:27 -0700911 int flags = 0;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800912 if (writable_) {
913 prot |= PROT_WRITE;
914 flags |= MAP_SHARED;
915 } else {
916 flags |= MAP_PRIVATE;
917 }
Brian Carlstrom3a223612013-10-10 17:18:24 -0700918 if (file_length < (program_header.p_offset + program_header.p_memsz)) {
Ian Rogerscdfcf372014-01-23 20:38:36 -0800919 *error_msg = StringPrintf("File size of %zd bytes not large enough to contain ELF segment "
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700920 "%d of %d bytes: '%s'", file_length, i,
921 program_header.p_offset + program_header.p_memsz,
922 file_->GetPath().c_str());
Brian Carlstrom3a223612013-10-10 17:18:24 -0700923 return false;
924 }
Ian Rogers700a4022014-05-19 16:49:03 -0700925 std::unique_ptr<MemMap> segment(MemMap::MapFileAtAddress(p_vaddr,
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800926 program_header.p_memsz,
927 prot, flags, file_->Fd(),
928 program_header.p_offset,
Hiroshi Yamauchi4fb5df82014-03-13 15:10:27 -0700929 true, // implies MAP_FIXED
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700930 file_->GetPath().c_str(),
931 error_msg));
Brian Carlstromc1409452014-02-26 14:06:23 -0800932 if (segment.get() == nullptr) {
933 *error_msg = StringPrintf("Failed to map ELF file segment %d from %s: %s",
934 i, file_->GetPath().c_str(), error_msg->c_str());
935 return false;
936 }
937 if (segment->Begin() != p_vaddr) {
938 *error_msg = StringPrintf("Failed to map ELF file segment %d from %s at expected address %p, "
939 "instead mapped to %p",
940 i, file_->GetPath().c_str(), p_vaddr, segment->Begin());
941 return false;
942 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800943 segments_.push_back(segment.release());
944 }
Brian Carlstrom265091e2013-01-30 14:08:26 -0800945
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800946 // Now that we are done loading, .dynamic should be in memory to find .dynstr, .dynsym, .hash
947 dynamic_section_start_
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000948 = reinterpret_cast<Elf32_Dyn*>(base_address_ + GetDynamicProgramHeader().p_vaddr);
949 for (Elf32_Word i = 0; i < GetDynamicNum(); i++) {
950 Elf32_Dyn& elf_dyn = GetDynamic(i);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800951 byte* d_ptr = base_address_ + elf_dyn.d_un.d_ptr;
952 switch (elf_dyn.d_tag) {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000953 case DT_HASH: {
Brian Carlstromc1409452014-02-26 14:06:23 -0800954 if (!ValidPointer(d_ptr)) {
955 *error_msg = StringPrintf("DT_HASH value %p does not refer to a loaded ELF segment of %s",
956 d_ptr, file_->GetPath().c_str());
957 return false;
958 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000959 hash_section_start_ = reinterpret_cast<Elf32_Word*>(d_ptr);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800960 break;
961 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000962 case DT_STRTAB: {
Brian Carlstromc1409452014-02-26 14:06:23 -0800963 if (!ValidPointer(d_ptr)) {
964 *error_msg = StringPrintf("DT_HASH value %p does not refer to a loaded ELF segment of %s",
965 d_ptr, file_->GetPath().c_str());
966 return false;
967 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800968 dynstr_section_start_ = reinterpret_cast<char*>(d_ptr);
969 break;
970 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000971 case DT_SYMTAB: {
Brian Carlstromc1409452014-02-26 14:06:23 -0800972 if (!ValidPointer(d_ptr)) {
973 *error_msg = StringPrintf("DT_HASH value %p does not refer to a loaded ELF segment of %s",
974 d_ptr, file_->GetPath().c_str());
975 return false;
976 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000977 dynsym_section_start_ = reinterpret_cast<Elf32_Sym*>(d_ptr);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800978 break;
979 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000980 case DT_NULL: {
Brian Carlstromc1409452014-02-26 14:06:23 -0800981 if (GetDynamicNum() != i+1) {
982 *error_msg = StringPrintf("DT_NULL found after %d .dynamic entries, "
983 "expected %d as implied by size of PT_DYNAMIC segment in %s",
984 i + 1, GetDynamicNum(), file_->GetPath().c_str());
985 return false;
986 }
Brian Carlstrom265091e2013-01-30 14:08:26 -0800987 break;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800988 }
989 }
990 }
991
Mark Mendellae9fd932014-02-10 16:14:35 -0800992 // Use GDB JIT support to do stack backtrace, etc.
993 if (executable) {
994 GdbJITSupport();
995 }
996
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800997 return true;
998}
999
Brian Carlstromc1409452014-02-26 14:06:23 -08001000bool ElfFile::ValidPointer(const byte* start) const {
1001 for (size_t i = 0; i < segments_.size(); ++i) {
1002 const MemMap* segment = segments_[i];
1003 if (segment->Begin() <= start && start < segment->End()) {
1004 return true;
1005 }
1006 }
1007 return false;
1008}
1009
Alex Light3470ab42014-06-18 10:35:45 -07001010
1011Elf32_Shdr* ElfFile::FindSectionByName(const std::string& name) const {
1012 CHECK(!program_header_only_);
1013 Elf32_Shdr& shstrtab_sec = GetSectionNameStringSection();
1014 for (uint32_t i = 0; i < GetSectionHeaderNum(); i++) {
1015 Elf32_Shdr& shdr = GetSectionHeader(i);
1016 const char* sec_name = GetString(shstrtab_sec, shdr.sh_name);
1017 if (sec_name == nullptr) {
1018 continue;
1019 }
1020 if (name == sec_name) {
1021 return &shdr;
1022 }
1023 }
1024 return nullptr;
Mark Mendellae9fd932014-02-10 16:14:35 -08001025}
1026
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001027struct PACKED(1) FDE32 {
Alex Light3470ab42014-06-18 10:35:45 -07001028 uint32_t raw_length_;
1029 uint32_t GetLength() {
1030 return raw_length_ + sizeof(raw_length_);
1031 }
1032 uint32_t CIE_pointer;
1033 uint32_t initial_location;
1034 uint32_t address_range;
1035 uint8_t instructions[0];
1036};
1037
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001038static FDE32* NextFDE(FDE32* frame) {
Alex Light3470ab42014-06-18 10:35:45 -07001039 byte* fde_bytes = reinterpret_cast<byte*>(frame);
1040 fde_bytes += frame->GetLength();
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001041 return reinterpret_cast<FDE32*>(fde_bytes);
Mark Mendellae9fd932014-02-10 16:14:35 -08001042}
1043
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001044static bool IsFDE(FDE32* frame) {
Tong Shen35e1e6a2014-07-30 09:31:22 -07001045 return frame->CIE_pointer != 0;
Alex Light3470ab42014-06-18 10:35:45 -07001046}
1047
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001048struct PACKED(1) FDE64 {
1049 uint32_t raw_length_;
1050 uint64_t extended_length_;
1051 uint64_t GetLength() {
1052 return extended_length_ + sizeof(raw_length_) + sizeof(extended_length_);
1053 }
1054 uint64_t CIE_pointer;
1055 uint64_t initial_location;
1056 uint64_t address_range;
1057 uint8_t instructions[0];
1058};
1059
1060static FDE64* NextFDE(FDE64* frame) {
1061 byte* fde_bytes = reinterpret_cast<byte*>(frame);
1062 fde_bytes += frame->GetLength();
1063 return reinterpret_cast<FDE64*>(fde_bytes);
1064}
1065
1066static bool IsFDE(FDE64* frame) {
1067 return frame->CIE_pointer != 0;
1068}
1069
1070static bool FixupEHFrame(off_t base_address_delta,
1071 byte* eh_frame, size_t eh_frame_size) {
1072 if (*(reinterpret_cast<uint32_t*>(eh_frame)) == 0xffffffff) {
1073 FDE64* last_frame = reinterpret_cast<FDE64*>(eh_frame + eh_frame_size);
1074 FDE64* frame = NextFDE(reinterpret_cast<FDE64*>(eh_frame));
1075 for (; frame < last_frame; frame = NextFDE(frame)) {
1076 if (!IsFDE(frame)) {
1077 return false;
1078 }
1079 frame->initial_location += base_address_delta;
1080 }
1081 return true;
1082 } else {
1083 FDE32* last_frame = reinterpret_cast<FDE32*>(eh_frame + eh_frame_size);
1084 FDE32* frame = NextFDE(reinterpret_cast<FDE32*>(eh_frame));
1085 for (; frame < last_frame; frame = NextFDE(frame)) {
1086 if (!IsFDE(frame)) {
1087 return false;
1088 }
1089 frame->initial_location += base_address_delta;
1090 }
1091 return true;
1092 }
1093}
1094
1095static uint8_t* NextLeb128(uint8_t* current) {
1096 DecodeUnsignedLeb128(const_cast<const uint8_t**>(&current));
1097 return current;
1098}
1099
1100struct PACKED(1) DebugLineHeader {
1101 uint32_t unit_length_; // TODO 32-bit specific size
1102 uint16_t version_;
1103 uint32_t header_length_; // TODO 32-bit specific size
1104 uint8_t minimum_instruction_lenght_;
1105 uint8_t maximum_operations_per_instruction_;
1106 uint8_t default_is_stmt_;
1107 int8_t line_base_;
1108 uint8_t line_range_;
1109 uint8_t opcode_base_;
1110 uint8_t remaining_[0];
1111
1112 bool IsStandardOpcode(const uint8_t* op) const {
1113 return *op != 0 && *op < opcode_base_;
1114 }
1115
1116 bool IsExtendedOpcode(const uint8_t* op) const {
1117 return *op == 0;
1118 }
1119
1120 const uint8_t* GetStandardOpcodeLengths() const {
1121 return remaining_;
1122 }
1123
1124 uint8_t* GetNextOpcode(uint8_t* op) const {
1125 if (IsExtendedOpcode(op)) {
1126 uint8_t* length_field = op + 1;
1127 uint32_t length = DecodeUnsignedLeb128(const_cast<const uint8_t**>(&length_field));
1128 return length_field + length;
1129 } else if (!IsStandardOpcode(op)) {
1130 return op + 1;
1131 } else if (*op == DW_LNS_fixed_advance_pc) {
1132 return op + 1 + sizeof(uint16_t);
1133 } else {
1134 uint8_t num_args = GetStandardOpcodeLengths()[*op - 1];
1135 op += 1;
1136 for (int i = 0; i < num_args; i++) {
1137 op = NextLeb128(op);
1138 }
1139 return op;
1140 }
1141 }
1142
1143 uint8_t* GetDebugLineData() const {
1144 const uint8_t* hdr_start =
1145 reinterpret_cast<const uint8_t*>(&header_length_) + sizeof(header_length_);
1146 return const_cast<uint8_t*>(hdr_start + header_length_);
1147 }
1148};
1149
1150class DebugLineInstructionIterator {
1151 public:
1152 static DebugLineInstructionIterator* Create(DebugLineHeader* header, size_t section_size) {
1153 std::unique_ptr<DebugLineInstructionIterator> line_iter(
1154 new DebugLineInstructionIterator(header, section_size));
1155 if (line_iter.get() == nullptr) {
1156 return nullptr;
1157 } else {
1158 return line_iter.release();
1159 }
1160 }
1161
1162 ~DebugLineInstructionIterator() {}
1163
1164 bool Next() {
1165 if (current_instruction_ == nullptr) {
Alex Light3470ab42014-06-18 10:35:45 -07001166 return false;
1167 }
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001168 current_instruction_ = header_->GetNextOpcode(current_instruction_);
1169 if (current_instruction_ >= last_instruction_) {
1170 current_instruction_ = nullptr;
1171 return false;
1172 } else {
1173 return true;
1174 }
1175 }
1176
1177 uint8_t* GetInstruction() {
1178 return current_instruction_;
1179 }
1180
1181 bool IsExtendedOpcode() {
1182 return header_->IsExtendedOpcode(current_instruction_);
1183 }
1184
1185 uint8_t GetOpcode() {
1186 if (!IsExtendedOpcode()) {
1187 return *current_instruction_;
1188 } else {
1189 uint8_t* len_ptr = current_instruction_ + 1;
1190 return *NextLeb128(len_ptr);
1191 }
1192 }
1193
1194 uint8_t* GetArguments() {
1195 if (!IsExtendedOpcode()) {
1196 return current_instruction_ + 1;
1197 } else {
1198 uint8_t* len_ptr = current_instruction_ + 1;
1199 return NextLeb128(len_ptr) + 1;
1200 }
1201 }
1202
1203 private:
1204 DebugLineInstructionIterator(DebugLineHeader* header, size_t size)
1205 : header_(header), last_instruction_(reinterpret_cast<uint8_t*>(header) + size),
1206 current_instruction_(header->GetDebugLineData()) {}
1207
1208 DebugLineHeader* header_;
1209 uint8_t* last_instruction_;
1210 uint8_t* current_instruction_;
1211};
1212
1213static bool FixupDebugLine(off_t base_offset_delta, DebugLineInstructionIterator* iter) {
1214 while (iter->Next()) {
1215 if (iter->IsExtendedOpcode() && iter->GetOpcode() == DW_LNE_set_address) {
1216 *reinterpret_cast<uint32_t*>(iter->GetArguments()) += base_offset_delta;
1217 }
Alex Light3470ab42014-06-18 10:35:45 -07001218 }
1219 return true;
1220}
1221
1222struct PACKED(1) DebugInfoHeader {
1223 uint32_t unit_length; // TODO 32-bit specific size
1224 uint16_t version;
1225 uint32_t debug_abbrev_offset; // TODO 32-bit specific size
1226 uint8_t address_size;
1227};
1228
1229// Returns -1 if it is variable length, which we will just disallow for now.
1230static int32_t FormLength(uint32_t att) {
1231 switch (att) {
1232 case DW_FORM_data1:
1233 case DW_FORM_flag:
1234 case DW_FORM_flag_present:
1235 case DW_FORM_ref1:
1236 return 1;
1237
1238 case DW_FORM_data2:
1239 case DW_FORM_ref2:
1240 return 2;
1241
1242 case DW_FORM_addr: // TODO 32-bit only
1243 case DW_FORM_ref_addr: // TODO 32-bit only
1244 case DW_FORM_sec_offset: // TODO 32-bit only
1245 case DW_FORM_strp: // TODO 32-bit only
1246 case DW_FORM_data4:
1247 case DW_FORM_ref4:
1248 return 4;
1249
1250 case DW_FORM_data8:
1251 case DW_FORM_ref8:
1252 case DW_FORM_ref_sig8:
1253 return 8;
1254
1255 case DW_FORM_block:
1256 case DW_FORM_block1:
1257 case DW_FORM_block2:
1258 case DW_FORM_block4:
1259 case DW_FORM_exprloc:
1260 case DW_FORM_indirect:
1261 case DW_FORM_ref_udata:
1262 case DW_FORM_sdata:
1263 case DW_FORM_string:
1264 case DW_FORM_udata:
1265 default:
1266 return -1;
Mark Mendellae9fd932014-02-10 16:14:35 -08001267 }
1268}
1269
Alex Light3470ab42014-06-18 10:35:45 -07001270class DebugTag {
1271 public:
1272 const uint32_t index_;
1273 ~DebugTag() {}
1274 // Creates a new tag and moves data pointer up to the start of the next one.
1275 // nullptr means error.
1276 static DebugTag* Create(const byte** data_pointer) {
1277 const byte* data = *data_pointer;
1278 uint32_t index = DecodeUnsignedLeb128(&data);
1279 std::unique_ptr<DebugTag> tag(new DebugTag(index));
1280 tag->size_ = static_cast<uint32_t>(
1281 reinterpret_cast<uintptr_t>(data) - reinterpret_cast<uintptr_t>(*data_pointer));
1282 // skip the abbrev
1283 tag->tag_ = DecodeUnsignedLeb128(&data);
1284 tag->has_child_ = (*data == 0);
1285 data++;
1286 while (true) {
1287 uint32_t attr = DecodeUnsignedLeb128(&data);
1288 uint32_t form = DecodeUnsignedLeb128(&data);
1289 if (attr == 0 && form == 0) {
1290 break;
1291 } else if (attr == 0 || form == 0) {
1292 // Bad abbrev.
1293 return nullptr;
1294 }
1295 int32_t size = FormLength(form);
1296 if (size == -1) {
1297 return nullptr;
1298 }
1299 tag->AddAttribute(attr, static_cast<uint32_t>(size));
1300 }
1301 *data_pointer = data;
1302 return tag.release();
1303 }
1304
1305 uint32_t GetSize() const {
1306 return size_;
1307 }
1308
1309 bool HasChild() {
1310 return has_child_;
1311 }
1312
1313 uint32_t GetTagNumber() {
1314 return tag_;
1315 }
1316
1317 // Gets the offset of a particular attribute in this tag structure.
1318 // Interpretation of the data is left to the consumer. 0 is returned if the
1319 // tag does not contain the attribute.
1320 uint32_t GetOffsetOf(uint32_t dwarf_attribute) const {
1321 auto it = off_map_.find(dwarf_attribute);
1322 if (it == off_map_.end()) {
1323 return 0;
1324 } else {
1325 return it->second;
1326 }
1327 }
1328
1329 // Gets the size of attribute
1330 uint32_t GetAttrSize(uint32_t dwarf_attribute) const {
1331 auto it = size_map_.find(dwarf_attribute);
1332 if (it == size_map_.end()) {
1333 return 0;
1334 } else {
1335 return it->second;
1336 }
1337 }
1338
1339 private:
1340 explicit DebugTag(uint32_t index) : index_(index) {}
1341 void AddAttribute(uint32_t type, uint32_t attr_size) {
1342 off_map_.insert(std::pair<uint32_t, uint32_t>(type, size_));
1343 size_map_.insert(std::pair<uint32_t, uint32_t>(type, attr_size));
1344 size_ += attr_size;
1345 }
1346 std::map<uint32_t, uint32_t> off_map_;
1347 std::map<uint32_t, uint32_t> size_map_;
1348 uint32_t size_;
1349 uint32_t tag_;
1350 bool has_child_;
1351};
1352
1353class DebugAbbrev {
1354 public:
1355 ~DebugAbbrev() {}
1356 static DebugAbbrev* Create(const byte* dbg_abbrev, size_t dbg_abbrev_size) {
Alex Lightd338ae02014-08-13 17:15:38 -07001357 std::unique_ptr<DebugAbbrev> abbrev(new DebugAbbrev(dbg_abbrev, dbg_abbrev + dbg_abbrev_size));
1358 if (!abbrev->ReadAtOffset(0)) {
1359 return nullptr;
Alex Light3470ab42014-06-18 10:35:45 -07001360 }
1361 return abbrev.release();
1362 }
1363
Alex Lightd338ae02014-08-13 17:15:38 -07001364 bool ReadAtOffset(uint32_t abbrev_offset) {
1365 tags_.clear();
1366 tag_list_.clear();
1367 const byte* dbg_abbrev = begin_ + abbrev_offset;
1368 while (dbg_abbrev < end_ && *dbg_abbrev != 0) {
1369 std::unique_ptr<DebugTag> tag(DebugTag::Create(&dbg_abbrev));
1370 if (tag.get() == nullptr) {
1371 return false;
1372 } else {
1373 tags_.insert(std::pair<uint32_t, uint32_t>(tag->index_, tag_list_.size()));
1374 tag_list_.push_back(std::move(tag));
1375 }
1376 }
1377 return true;
1378 }
1379
Alex Light3470ab42014-06-18 10:35:45 -07001380 DebugTag* ReadTag(const byte* entry) {
1381 uint32_t tag_num = DecodeUnsignedLeb128(&entry);
1382 auto it = tags_.find(tag_num);
1383 if (it == tags_.end()) {
1384 return nullptr;
1385 } else {
1386 CHECK_GT(tag_list_.size(), it->second);
1387 return tag_list_.at(it->second).get();
1388 }
1389 }
1390
1391 private:
Alex Lightd338ae02014-08-13 17:15:38 -07001392 DebugAbbrev(const byte* begin, const byte* end) : begin_(begin), end_(end) {}
1393 const byte* begin_;
1394 const byte* end_;
Alex Light3470ab42014-06-18 10:35:45 -07001395 std::map<uint32_t, uint32_t> tags_;
1396 std::vector<std::unique_ptr<DebugTag>> tag_list_;
1397};
1398
1399class DebugInfoIterator {
1400 public:
1401 static DebugInfoIterator* Create(DebugInfoHeader* header, size_t frame_size,
1402 DebugAbbrev* abbrev) {
1403 std::unique_ptr<DebugInfoIterator> iter(new DebugInfoIterator(header, frame_size, abbrev));
1404 if (iter->GetCurrentTag() == nullptr) {
1405 return nullptr;
1406 } else {
1407 return iter.release();
1408 }
1409 }
1410 ~DebugInfoIterator() {}
1411
1412 // Moves to the next DIE. Returns false if at last entry.
1413 // TODO Handle variable length attributes.
1414 bool next() {
1415 if (current_entry_ == nullptr || current_tag_ == nullptr) {
1416 return false;
1417 }
Alex Lightd338ae02014-08-13 17:15:38 -07001418 bool reread_abbrev = false;
Alex Light3470ab42014-06-18 10:35:45 -07001419 current_entry_ += current_tag_->GetSize();
Alex Lightd338ae02014-08-13 17:15:38 -07001420 if (reinterpret_cast<DebugInfoHeader*>(current_entry_) >= next_cu_) {
1421 current_cu_ = next_cu_;
1422 next_cu_ = GetNextCu(current_cu_);
1423 current_entry_ = reinterpret_cast<byte*>(current_cu_) + sizeof(DebugInfoHeader);
1424 reread_abbrev = true;
1425 }
Alex Light3470ab42014-06-18 10:35:45 -07001426 if (current_entry_ >= last_entry_) {
1427 current_entry_ = nullptr;
1428 return false;
1429 }
Alex Lightd338ae02014-08-13 17:15:38 -07001430 if (reread_abbrev) {
1431 abbrev_->ReadAtOffset(current_cu_->debug_abbrev_offset);
1432 }
Alex Light3470ab42014-06-18 10:35:45 -07001433 current_tag_ = abbrev_->ReadTag(current_entry_);
1434 if (current_tag_ == nullptr) {
1435 current_entry_ = nullptr;
1436 return false;
1437 } else {
1438 return true;
1439 }
1440 }
1441
1442 const DebugTag* GetCurrentTag() {
1443 return const_cast<DebugTag*>(current_tag_);
1444 }
1445 byte* GetPointerToField(uint8_t dwarf_field) {
1446 if (current_tag_ == nullptr || current_entry_ == nullptr || current_entry_ >= last_entry_) {
1447 return nullptr;
1448 }
1449 uint32_t off = current_tag_->GetOffsetOf(dwarf_field);
1450 if (off == 0) {
1451 // tag does not have that field.
1452 return nullptr;
1453 } else {
1454 DCHECK_LT(off, current_tag_->GetSize());
1455 return current_entry_ + off;
1456 }
1457 }
1458
1459 private:
Alex Lightd338ae02014-08-13 17:15:38 -07001460 static DebugInfoHeader* GetNextCu(DebugInfoHeader* hdr) {
1461 byte* hdr_byte = reinterpret_cast<byte*>(hdr);
1462 return reinterpret_cast<DebugInfoHeader*>(hdr_byte + sizeof(uint32_t) + hdr->unit_length);
1463 }
1464
Alex Light3470ab42014-06-18 10:35:45 -07001465 DebugInfoIterator(DebugInfoHeader* header, size_t frame_size, DebugAbbrev* abbrev)
1466 : abbrev_(abbrev),
Alex Lightd338ae02014-08-13 17:15:38 -07001467 current_cu_(header),
1468 next_cu_(GetNextCu(header)),
Alex Light3470ab42014-06-18 10:35:45 -07001469 last_entry_(reinterpret_cast<byte*>(header) + frame_size),
1470 current_entry_(reinterpret_cast<byte*>(header) + sizeof(DebugInfoHeader)),
1471 current_tag_(abbrev_->ReadTag(current_entry_)) {}
1472 DebugAbbrev* abbrev_;
Alex Lightd338ae02014-08-13 17:15:38 -07001473 DebugInfoHeader* current_cu_;
1474 DebugInfoHeader* next_cu_;
Alex Light3470ab42014-06-18 10:35:45 -07001475 byte* last_entry_;
1476 byte* current_entry_;
1477 DebugTag* current_tag_;
1478};
1479
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001480static bool FixupDebugInfo(off_t base_address_delta, DebugInfoIterator* iter) {
Alex Light3470ab42014-06-18 10:35:45 -07001481 do {
1482 if (iter->GetCurrentTag()->GetAttrSize(DW_AT_low_pc) != sizeof(int32_t) ||
1483 iter->GetCurrentTag()->GetAttrSize(DW_AT_high_pc) != sizeof(int32_t)) {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001484 LOG(ERROR) << "DWARF information with 64 bit pointers is not supported yet.";
Alex Light3470ab42014-06-18 10:35:45 -07001485 return false;
1486 }
1487 uint32_t* PC_low = reinterpret_cast<uint32_t*>(iter->GetPointerToField(DW_AT_low_pc));
1488 uint32_t* PC_high = reinterpret_cast<uint32_t*>(iter->GetPointerToField(DW_AT_high_pc));
1489 if (PC_low != nullptr && PC_high != nullptr) {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001490 *PC_low += base_address_delta;
1491 *PC_high += base_address_delta;
Alex Light3470ab42014-06-18 10:35:45 -07001492 }
1493 } while (iter->next());
1494 return true;
1495}
1496
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001497bool ElfFile::FixupDebugSections(off_t base_address_delta) {
1498 const Elf32_Shdr* debug_info = FindSectionByName(".debug_info");
1499 const Elf32_Shdr* debug_abbrev = FindSectionByName(".debug_abbrev");
1500 const Elf32_Shdr* eh_frame = FindSectionByName(".eh_frame");
1501 const Elf32_Shdr* debug_str = FindSectionByName(".debug_str");
1502 const Elf32_Shdr* debug_line = FindSectionByName(".debug_line");
1503 const Elf32_Shdr* strtab_sec = FindSectionByName(".strtab");
1504 const Elf32_Shdr* symtab_sec = FindSectionByName(".symtab");
1505
1506 if (debug_info == nullptr || debug_abbrev == nullptr ||
1507 debug_str == nullptr || strtab_sec == nullptr || symtab_sec == nullptr) {
1508 // Release version of ART does not generate debug info.
1509 return true;
1510 }
1511 if (base_address_delta == 0) {
1512 return true;
1513 }
1514 if (eh_frame != nullptr &&
1515 !FixupEHFrame(base_address_delta, Begin() + eh_frame->sh_offset, eh_frame->sh_size)) {
1516 return false;
1517 }
1518
1519 std::unique_ptr<DebugAbbrev> abbrev(DebugAbbrev::Create(Begin() + debug_abbrev->sh_offset,
1520 debug_abbrev->sh_size));
Alex Light3470ab42014-06-18 10:35:45 -07001521 if (abbrev.get() == nullptr) {
1522 return false;
1523 }
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001524 DebugInfoHeader* info_header =
1525 reinterpret_cast<DebugInfoHeader*>(Begin() + debug_info->sh_offset);
1526 std::unique_ptr<DebugInfoIterator> info_iter(DebugInfoIterator::Create(info_header,
1527 debug_info->sh_size,
1528 abbrev.get()));
1529 if (info_iter.get() == nullptr) {
Alex Light3470ab42014-06-18 10:35:45 -07001530 return false;
1531 }
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001532 if (debug_line != nullptr) {
1533 DebugLineHeader* line_header =
1534 reinterpret_cast<DebugLineHeader*>(Begin() + debug_line->sh_offset);
1535 std::unique_ptr<DebugLineInstructionIterator> line_iter(
1536 DebugLineInstructionIterator::Create(line_header, debug_line->sh_size));
1537 if (line_iter.get() == nullptr) {
1538 return false;
1539 }
1540 if (!FixupDebugLine(base_address_delta, line_iter.get())) {
1541 return false;
1542 }
1543 }
1544 return FixupDebugInfo(base_address_delta, info_iter.get());
Alex Light3470ab42014-06-18 10:35:45 -07001545}
Mark Mendellae9fd932014-02-10 16:14:35 -08001546
1547void ElfFile::GdbJITSupport() {
1548 // We only get here if we only are mapping the program header.
1549 DCHECK(program_header_only_);
1550
1551 // Well, we need the whole file to do this.
1552 std::string error_msg;
Alex Light3470ab42014-06-18 10:35:45 -07001553 // Make it MAP_PRIVATE so we can just give it to gdb if all the necessary
1554 // sections are there.
1555 std::unique_ptr<ElfFile> all_ptr(Open(const_cast<File*>(file_), PROT_READ | PROT_WRITE,
1556 MAP_PRIVATE, &error_msg));
1557 if (all_ptr.get() == nullptr) {
Mark Mendellae9fd932014-02-10 16:14:35 -08001558 return;
1559 }
Alex Light3470ab42014-06-18 10:35:45 -07001560 ElfFile& all = *all_ptr;
1561
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001562 // We need the eh_frame for gdb but debug info might be present without it.
Tong Shen35e1e6a2014-07-30 09:31:22 -07001563 const Elf32_Shdr* eh_frame = all.FindSectionByName(".eh_frame");
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001564 if (eh_frame == nullptr) {
Mark Mendellae9fd932014-02-10 16:14:35 -08001565 return;
1566 }
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001567
1568 // Do we have interesting sections?
Alex Light3470ab42014-06-18 10:35:45 -07001569 // We need to add in a strtab and symtab to the image.
1570 // all is MAP_PRIVATE so it can be written to freely.
1571 // We also already have strtab and symtab so we are fine there.
1572 Elf32_Ehdr& elf_hdr = all.GetHeader();
Mark Mendellae9fd932014-02-10 16:14:35 -08001573 elf_hdr.e_entry = 0;
1574 elf_hdr.e_phoff = 0;
1575 elf_hdr.e_phnum = 0;
1576 elf_hdr.e_phentsize = 0;
1577 elf_hdr.e_type = ET_EXEC;
1578
Yevgeny Roubane3ea8382014-08-08 16:29:38 +07001579 // Since base_address_ is 0 if we are actually loaded at a known address (i.e. this is boot.oat)
1580 // and the actual address stuff starts at in regular files this is good.
1581 if (!all.FixupDebugSections(reinterpret_cast<intptr_t>(base_address_))) {
Alex Light3470ab42014-06-18 10:35:45 -07001582 LOG(ERROR) << "Failed to load GDB data";
1583 return;
Mark Mendellae9fd932014-02-10 16:14:35 -08001584 }
1585
Alex Light3470ab42014-06-18 10:35:45 -07001586 jit_gdb_entry_ = CreateCodeEntry(all.Begin(), all.Size());
1587 gdb_file_mapping_.reset(all_ptr.release());
Mark Mendellae9fd932014-02-10 16:14:35 -08001588}
1589
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001590} // namespace art