blob: 4de46e368bb457bac54e5e6d90cb1fb444e86db6 [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"
23#include "base/stl_util.h"
24#include "utils.h"
25
26namespace art {
27
Mark Mendellae9fd932014-02-10 16:14:35 -080028// -------------------------------------------------------------------
29// Binary GDB JIT Interface as described in
30// http://sourceware.org/gdb/onlinedocs/gdb/Declarations.html
31extern "C" {
32 typedef enum {
33 JIT_NOACTION = 0,
34 JIT_REGISTER_FN,
35 JIT_UNREGISTER_FN
36 } JITAction;
37
38 struct JITCodeEntry {
39 JITCodeEntry* next_;
40 JITCodeEntry* prev_;
41 const byte *symfile_addr_;
42 uint64_t symfile_size_;
43 };
44
45 struct JITDescriptor {
46 uint32_t version_;
47 uint32_t action_flag_;
48 JITCodeEntry* relevant_entry_;
49 JITCodeEntry* first_entry_;
50 };
51
52 // GDB will place breakpoint into this function.
53 // To prevent GCC from inlining or removing it we place noinline attribute
54 // and inline assembler statement inside.
55 void __attribute__((noinline)) __jit_debug_register_code() {
56 __asm__("");
57 }
58
59 // GDB will inspect contents of this descriptor.
60 // Static initialization is necessary to prevent GDB from seeing
61 // uninitialized descriptor.
62 JITDescriptor __jit_debug_descriptor = { 1, JIT_NOACTION, nullptr, nullptr };
63}
64
65
66static JITCodeEntry* CreateCodeEntry(const byte *symfile_addr,
67 uintptr_t symfile_size) {
68 JITCodeEntry* entry = new JITCodeEntry;
69 entry->symfile_addr_ = symfile_addr;
70 entry->symfile_size_ = symfile_size;
71 entry->prev_ = nullptr;
72
73 // TODO: Do we need a lock here?
74 entry->next_ = __jit_debug_descriptor.first_entry_;
75 if (entry->next_ != nullptr) {
76 entry->next_->prev_ = entry;
77 }
78 __jit_debug_descriptor.first_entry_ = entry;
79 __jit_debug_descriptor.relevant_entry_ = entry;
80
81 __jit_debug_descriptor.action_flag_ = JIT_REGISTER_FN;
82 __jit_debug_register_code();
83 return entry;
84}
85
86
87static void UnregisterCodeEntry(JITCodeEntry* entry) {
88 // TODO: Do we need a lock here?
89 if (entry->prev_ != nullptr) {
90 entry->prev_->next_ = entry->next_;
91 } else {
92 __jit_debug_descriptor.first_entry_ = entry->next_;
93 }
94
95 if (entry->next_ != nullptr) {
96 entry->next_->prev_ = entry->prev_;
97 }
98
99 __jit_debug_descriptor.relevant_entry_ = entry;
100 __jit_debug_descriptor.action_flag_ = JIT_UNREGISTER_FN;
101 __jit_debug_register_code();
102 delete entry;
103}
104
Brian Carlstromc1409452014-02-26 14:06:23 -0800105ElfFile::ElfFile(File* file, bool writable, bool program_header_only)
106 : file_(file),
107 writable_(writable),
108 program_header_only_(program_header_only),
Brian Carlstrom02c8cc62013-07-18 15:54:44 -0700109 header_(NULL),
110 base_address_(NULL),
111 program_headers_start_(NULL),
112 section_headers_start_(NULL),
113 dynamic_program_header_(NULL),
114 dynamic_section_start_(NULL),
115 symtab_section_start_(NULL),
116 dynsym_section_start_(NULL),
117 strtab_section_start_(NULL),
118 dynstr_section_start_(NULL),
119 hash_section_start_(NULL),
120 symtab_symbol_table_(NULL),
Mark Mendellae9fd932014-02-10 16:14:35 -0800121 dynsym_symbol_table_(NULL),
122 jit_elf_image_(NULL),
123 jit_gdb_entry_(NULL) {
Brian Carlstromc1409452014-02-26 14:06:23 -0800124 CHECK(file != NULL);
125}
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800126
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700127ElfFile* ElfFile::Open(File* file, bool writable, bool program_header_only,
128 std::string* error_msg) {
Brian Carlstromc1409452014-02-26 14:06:23 -0800129 UniquePtr<ElfFile> elf_file(new ElfFile(file, writable, program_header_only));
130 if (!elf_file->Setup(error_msg)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700131 return nullptr;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800132 }
133 return elf_file.release();
134}
135
Brian Carlstromc1409452014-02-26 14:06:23 -0800136bool ElfFile::Setup(std::string* error_msg) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800137 int prot;
138 int flags;
139 if (writable_) {
140 prot = PROT_READ | PROT_WRITE;
141 flags = MAP_SHARED;
142 } else {
143 prot = PROT_READ;
144 flags = MAP_PRIVATE;
145 }
Ian Rogerscdfcf372014-01-23 20:38:36 -0800146 int64_t temp_file_length = file_->GetLength();
147 if (temp_file_length < 0) {
148 errno = -temp_file_length;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700149 *error_msg = StringPrintf("Failed to get length of file: '%s' fd=%d: %s",
150 file_->GetPath().c_str(), file_->Fd(), strerror(errno));
Brian Carlstrom265091e2013-01-30 14:08:26 -0800151 return false;
152 }
Ian Rogerscdfcf372014-01-23 20:38:36 -0800153 size_t file_length = static_cast<size_t>(temp_file_length);
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000154 if (file_length < sizeof(Elf32_Ehdr)) {
Ian Rogerscdfcf372014-01-23 20:38:36 -0800155 *error_msg = StringPrintf("File size of %zd bytes not large enough to contain ELF header of "
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000156 "%zd bytes: '%s'", file_length, sizeof(Elf32_Ehdr),
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700157 file_->GetPath().c_str());
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800158 return false;
159 }
160
Brian Carlstromc1409452014-02-26 14:06:23 -0800161 if (program_header_only_) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800162 // first just map ELF header to get program header size information
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000163 size_t elf_header_size = sizeof(Elf32_Ehdr);
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700164 if (!SetMap(MemMap::MapFile(elf_header_size, prot, flags, file_->Fd(), 0,
Brian Carlstromd0c09dc2013-11-06 18:25:35 -0800165 file_->GetPath().c_str(), error_msg),
166 error_msg)) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800167 return false;
168 }
169 // then remap to cover program header
170 size_t program_header_size = header_->e_phoff + (header_->e_phentsize * header_->e_phnum);
Brian Carlstrom3a223612013-10-10 17:18:24 -0700171 if (file_length < program_header_size) {
Ian Rogerscdfcf372014-01-23 20:38:36 -0800172 *error_msg = StringPrintf("File size of %zd bytes not large enough to contain ELF program "
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700173 "header of %zd bytes: '%s'", file_length,
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000174 sizeof(Elf32_Ehdr), file_->GetPath().c_str());
Brian Carlstrom3a223612013-10-10 17:18:24 -0700175 return false;
176 }
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700177 if (!SetMap(MemMap::MapFile(program_header_size, prot, flags, file_->Fd(), 0,
Brian Carlstromd0c09dc2013-11-06 18:25:35 -0800178 file_->GetPath().c_str(), error_msg),
179 error_msg)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700180 *error_msg = StringPrintf("Failed to map ELF program headers: %s", error_msg->c_str());
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800181 return false;
182 }
183 } else {
184 // otherwise map entire file
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700185 if (!SetMap(MemMap::MapFile(file_->GetLength(), prot, flags, file_->Fd(), 0,
Brian Carlstromd0c09dc2013-11-06 18:25:35 -0800186 file_->GetPath().c_str(), error_msg),
187 error_msg)) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700188 *error_msg = StringPrintf("Failed to map ELF file: %s", error_msg->c_str());
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800189 return false;
190 }
191 }
192
193 // Either way, the program header is relative to the elf header
194 program_headers_start_ = Begin() + GetHeader().e_phoff;
195
Brian Carlstromc1409452014-02-26 14:06:23 -0800196 if (!program_header_only_) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800197 // Setup section headers.
198 section_headers_start_ = Begin() + GetHeader().e_shoff;
199
200 // Find .dynamic section info from program header
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000201 dynamic_program_header_ = FindProgamHeaderByType(PT_DYNAMIC);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800202 if (dynamic_program_header_ == NULL) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700203 *error_msg = StringPrintf("Failed to find PT_DYNAMIC program header in ELF file: '%s'",
204 file_->GetPath().c_str());
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800205 return false;
206 }
207
208 dynamic_section_start_
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000209 = reinterpret_cast<Elf32_Dyn*>(Begin() + GetDynamicProgramHeader().p_offset);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800210
211 // Find other sections from section headers
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000212 for (Elf32_Word i = 0; i < GetSectionHeaderNum(); i++) {
213 Elf32_Shdr& section_header = GetSectionHeader(i);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800214 byte* section_addr = Begin() + section_header.sh_offset;
215 switch (section_header.sh_type) {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000216 case SHT_SYMTAB: {
217 symtab_section_start_ = reinterpret_cast<Elf32_Sym*>(section_addr);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800218 break;
219 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000220 case SHT_DYNSYM: {
221 dynsym_section_start_ = reinterpret_cast<Elf32_Sym*>(section_addr);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800222 break;
223 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000224 case SHT_STRTAB: {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800225 // TODO: base these off of sh_link from .symtab and .dynsym above
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000226 if ((section_header.sh_flags & SHF_ALLOC) != 0) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800227 dynstr_section_start_ = reinterpret_cast<char*>(section_addr);
228 } else {
229 strtab_section_start_ = reinterpret_cast<char*>(section_addr);
230 }
231 break;
232 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000233 case SHT_DYNAMIC: {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800234 if (reinterpret_cast<byte*>(dynamic_section_start_) != section_addr) {
235 LOG(WARNING) << "Failed to find matching SHT_DYNAMIC for PT_DYNAMIC in "
Brian Carlstrom265091e2013-01-30 14:08:26 -0800236 << file_->GetPath() << ": " << std::hex
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800237 << reinterpret_cast<void*>(dynamic_section_start_)
238 << " != " << reinterpret_cast<void*>(section_addr);
239 return false;
240 }
241 break;
242 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000243 case SHT_HASH: {
244 hash_section_start_ = reinterpret_cast<Elf32_Word*>(section_addr);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800245 break;
246 }
247 }
248 }
249 }
250 return true;
251}
252
253ElfFile::~ElfFile() {
254 STLDeleteElements(&segments_);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800255 delete symtab_symbol_table_;
256 delete dynsym_symbol_table_;
Mark Mendellae9fd932014-02-10 16:14:35 -0800257 delete jit_elf_image_;
258 if (jit_gdb_entry_) {
259 UnregisterCodeEntry(jit_gdb_entry_);
260 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800261}
262
Brian Carlstromd0c09dc2013-11-06 18:25:35 -0800263bool ElfFile::SetMap(MemMap* map, std::string* error_msg) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800264 if (map == NULL) {
Brian Carlstromd0c09dc2013-11-06 18:25:35 -0800265 // MemMap::Open should have already set an error.
266 DCHECK(!error_msg->empty());
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800267 return false;
268 }
269 map_.reset(map);
270 CHECK(map_.get() != NULL) << file_->GetPath();
271 CHECK(map_->Begin() != NULL) << file_->GetPath();
272
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000273 header_ = reinterpret_cast<Elf32_Ehdr*>(map_->Begin());
274 if ((ELFMAG0 != header_->e_ident[EI_MAG0])
275 || (ELFMAG1 != header_->e_ident[EI_MAG1])
276 || (ELFMAG2 != header_->e_ident[EI_MAG2])
277 || (ELFMAG3 != header_->e_ident[EI_MAG3])) {
Brian Carlstromc1409452014-02-26 14:06:23 -0800278 *error_msg = StringPrintf("Failed to find ELF magic value %d %d %d %d in %s, found %d %d %d %d",
279 ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3,
Brian Carlstromd0c09dc2013-11-06 18:25:35 -0800280 file_->GetPath().c_str(),
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000281 header_->e_ident[EI_MAG0],
282 header_->e_ident[EI_MAG1],
283 header_->e_ident[EI_MAG2],
284 header_->e_ident[EI_MAG3]);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800285 return false;
286 }
Brian Carlstromc1409452014-02-26 14:06:23 -0800287 if (ELFCLASS32 != header_->e_ident[EI_CLASS]) {
288 *error_msg = StringPrintf("Failed to find expected EI_CLASS value %d in %s, found %d",
289 ELFCLASS32,
290 file_->GetPath().c_str(),
291 header_->e_ident[EI_CLASS]);
292 return false;
293 }
294 if (ELFDATA2LSB != header_->e_ident[EI_DATA]) {
295 *error_msg = StringPrintf("Failed to find expected EI_DATA value %d in %s, found %d",
296 ELFDATA2LSB,
297 file_->GetPath().c_str(),
298 header_->e_ident[EI_CLASS]);
299 return false;
300 }
301 if (EV_CURRENT != header_->e_ident[EI_VERSION]) {
302 *error_msg = StringPrintf("Failed to find expected EI_VERSION value %d in %s, found %d",
303 EV_CURRENT,
304 file_->GetPath().c_str(),
305 header_->e_ident[EI_CLASS]);
306 return false;
307 }
308 if (ET_DYN != header_->e_type) {
309 *error_msg = StringPrintf("Failed to find expected e_type value %d in %s, found %d",
310 ET_DYN,
311 file_->GetPath().c_str(),
312 header_->e_type);
313 return false;
314 }
315 if (EV_CURRENT != header_->e_version) {
316 *error_msg = StringPrintf("Failed to find expected e_version value %d in %s, found %d",
317 EV_CURRENT,
318 file_->GetPath().c_str(),
319 header_->e_version);
320 return false;
321 }
322 if (0 != header_->e_entry) {
323 *error_msg = StringPrintf("Failed to find expected e_entry value %d in %s, found %d",
324 0,
325 file_->GetPath().c_str(),
326 header_->e_entry);
327 return false;
328 }
329 if (0 == header_->e_phoff) {
330 *error_msg = StringPrintf("Failed to find non-zero e_phoff value in %s",
331 file_->GetPath().c_str());
332 return false;
333 }
334 if (0 == header_->e_shoff) {
335 *error_msg = StringPrintf("Failed to find non-zero e_shoff value in %s",
336 file_->GetPath().c_str());
337 return false;
338 }
339 if (0 == header_->e_ehsize) {
340 *error_msg = StringPrintf("Failed to find non-zero e_ehsize value in %s",
341 file_->GetPath().c_str());
342 return false;
343 }
344 if (0 == header_->e_phentsize) {
345 *error_msg = StringPrintf("Failed to find non-zero e_phentsize value in %s",
346 file_->GetPath().c_str());
347 return false;
348 }
349 if (0 == header_->e_phnum) {
350 *error_msg = StringPrintf("Failed to find non-zero e_phnum value in %s",
351 file_->GetPath().c_str());
352 return false;
353 }
354 if (0 == header_->e_shentsize) {
355 *error_msg = StringPrintf("Failed to find non-zero e_shentsize value in %s",
356 file_->GetPath().c_str());
357 return false;
358 }
359 if (0 == header_->e_shnum) {
360 *error_msg = StringPrintf("Failed to find non-zero e_shnum value in %s",
361 file_->GetPath().c_str());
362 return false;
363 }
364 if (0 == header_->e_shstrndx) {
365 *error_msg = StringPrintf("Failed to find non-zero e_shstrndx value in %s",
366 file_->GetPath().c_str());
367 return false;
368 }
369 if (header_->e_shstrndx >= header_->e_shnum) {
370 *error_msg = StringPrintf("Failed to find e_shnum value %d less than %d in %s",
371 header_->e_shstrndx,
372 header_->e_shnum,
373 file_->GetPath().c_str());
374 return false;
375 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800376
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800377 if (!program_header_only_) {
Brian Carlstromc1409452014-02-26 14:06:23 -0800378 if (header_->e_phoff >= Size()) {
Dmitry Petrochenko659d87d2014-02-27 14:23:11 +0700379 *error_msg = StringPrintf("Failed to find e_phoff value %d less than %zd in %s",
Brian Carlstromc1409452014-02-26 14:06:23 -0800380 header_->e_phoff,
381 Size(),
382 file_->GetPath().c_str());
383 return false;
384 }
385 if (header_->e_shoff >= Size()) {
Dmitry Petrochenko659d87d2014-02-27 14:23:11 +0700386 *error_msg = StringPrintf("Failed to find e_shoff value %d less than %zd in %s",
Brian Carlstromc1409452014-02-26 14:06:23 -0800387 header_->e_shoff,
388 Size(),
389 file_->GetPath().c_str());
390 return false;
391 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800392 }
393 return true;
394}
395
396
Brian Carlstromc1409452014-02-26 14:06:23 -0800397Elf32_Ehdr& ElfFile::GetHeader() const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800398 CHECK(header_ != NULL);
399 return *header_;
400}
401
Brian Carlstromc1409452014-02-26 14:06:23 -0800402byte* ElfFile::GetProgramHeadersStart() const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800403 CHECK(program_headers_start_ != NULL);
404 return program_headers_start_;
405}
406
Brian Carlstromc1409452014-02-26 14:06:23 -0800407byte* ElfFile::GetSectionHeadersStart() const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800408 CHECK(section_headers_start_ != NULL);
409 return section_headers_start_;
410}
411
Brian Carlstromc1409452014-02-26 14:06:23 -0800412Elf32_Phdr& ElfFile::GetDynamicProgramHeader() const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800413 CHECK(dynamic_program_header_ != NULL);
414 return *dynamic_program_header_;
415}
416
Brian Carlstromc1409452014-02-26 14:06:23 -0800417Elf32_Dyn* ElfFile::GetDynamicSectionStart() const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800418 CHECK(dynamic_section_start_ != NULL);
419 return dynamic_section_start_;
420}
421
Brian Carlstromc1409452014-02-26 14:06:23 -0800422Elf32_Sym* ElfFile::GetSymbolSectionStart(Elf32_Word section_type) const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800423 CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type;
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000424 Elf32_Sym* symbol_section_start;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800425 switch (section_type) {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000426 case SHT_SYMTAB: {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800427 symbol_section_start = symtab_section_start_;
428 break;
429 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000430 case SHT_DYNSYM: {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800431 symbol_section_start = dynsym_section_start_;
432 break;
433 }
434 default: {
435 LOG(FATAL) << section_type;
436 symbol_section_start = NULL;
437 }
438 }
439 CHECK(symbol_section_start != NULL);
440 return symbol_section_start;
441}
442
Brian Carlstromc1409452014-02-26 14:06:23 -0800443const char* ElfFile::GetStringSectionStart(Elf32_Word section_type) const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800444 CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800445 const char* string_section_start;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800446 switch (section_type) {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000447 case SHT_SYMTAB: {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800448 string_section_start = strtab_section_start_;
449 break;
450 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000451 case SHT_DYNSYM: {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800452 string_section_start = dynstr_section_start_;
453 break;
454 }
455 default: {
456 LOG(FATAL) << section_type;
457 string_section_start = NULL;
458 }
459 }
460 CHECK(string_section_start != NULL);
461 return string_section_start;
462}
463
Brian Carlstromc1409452014-02-26 14:06:23 -0800464const char* ElfFile::GetString(Elf32_Word section_type, Elf32_Word i) const {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800465 CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type;
466 if (i == 0) {
467 return NULL;
468 }
469 const char* string_section_start = GetStringSectionStart(section_type);
470 const char* string = string_section_start + i;
471 return string;
472}
473
Brian Carlstromc1409452014-02-26 14:06:23 -0800474Elf32_Word* ElfFile::GetHashSectionStart() const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800475 CHECK(hash_section_start_ != NULL);
476 return hash_section_start_;
477}
478
Brian Carlstromc1409452014-02-26 14:06:23 -0800479Elf32_Word ElfFile::GetHashBucketNum() const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800480 return GetHashSectionStart()[0];
481}
482
Brian Carlstromc1409452014-02-26 14:06:23 -0800483Elf32_Word ElfFile::GetHashChainNum() const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800484 return GetHashSectionStart()[1];
485}
486
Brian Carlstromc1409452014-02-26 14:06:23 -0800487Elf32_Word ElfFile::GetHashBucket(size_t i) const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800488 CHECK_LT(i, GetHashBucketNum());
489 // 0 is nbucket, 1 is nchain
490 return GetHashSectionStart()[2 + i];
491}
492
Brian Carlstromc1409452014-02-26 14:06:23 -0800493Elf32_Word ElfFile::GetHashChain(size_t i) const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800494 CHECK_LT(i, GetHashChainNum());
495 // 0 is nbucket, 1 is nchain, & chains are after buckets
496 return GetHashSectionStart()[2 + GetHashBucketNum() + i];
497}
498
Brian Carlstromc1409452014-02-26 14:06:23 -0800499Elf32_Word ElfFile::GetProgramHeaderNum() const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800500 return GetHeader().e_phnum;
501}
502
Brian Carlstromc1409452014-02-26 14:06:23 -0800503Elf32_Phdr& ElfFile::GetProgramHeader(Elf32_Word i) const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800504 CHECK_LT(i, GetProgramHeaderNum()) << file_->GetPath();
505 byte* program_header = GetProgramHeadersStart() + (i * GetHeader().e_phentsize);
506 CHECK_LT(program_header, End()) << file_->GetPath();
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000507 return *reinterpret_cast<Elf32_Phdr*>(program_header);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800508}
509
Brian Carlstromc1409452014-02-26 14:06:23 -0800510Elf32_Phdr* ElfFile::FindProgamHeaderByType(Elf32_Word type) const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000511 for (Elf32_Word i = 0; i < GetProgramHeaderNum(); i++) {
512 Elf32_Phdr& program_header = GetProgramHeader(i);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800513 if (program_header.p_type == type) {
514 return &program_header;
515 }
516 }
517 return NULL;
518}
519
Brian Carlstromc1409452014-02-26 14:06:23 -0800520Elf32_Word ElfFile::GetSectionHeaderNum() const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800521 return GetHeader().e_shnum;
522}
523
Brian Carlstromc1409452014-02-26 14:06:23 -0800524Elf32_Shdr& ElfFile::GetSectionHeader(Elf32_Word i) const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800525 // Can only access arbitrary sections when we have the whole file, not just program header.
526 // Even if we Load(), it doesn't bring in all the sections.
527 CHECK(!program_header_only_) << file_->GetPath();
528 CHECK_LT(i, GetSectionHeaderNum()) << file_->GetPath();
529 byte* section_header = GetSectionHeadersStart() + (i * GetHeader().e_shentsize);
530 CHECK_LT(section_header, End()) << file_->GetPath();
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000531 return *reinterpret_cast<Elf32_Shdr*>(section_header);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800532}
533
Brian Carlstromc1409452014-02-26 14:06:23 -0800534Elf32_Shdr* ElfFile::FindSectionByType(Elf32_Word type) const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800535 // Can only access arbitrary sections when we have the whole file, not just program header.
536 // We could change this to switch on known types if they were detected during loading.
537 CHECK(!program_header_only_) << file_->GetPath();
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000538 for (Elf32_Word i = 0; i < GetSectionHeaderNum(); i++) {
539 Elf32_Shdr& section_header = GetSectionHeader(i);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800540 if (section_header.sh_type == type) {
541 return &section_header;
542 }
543 }
544 return NULL;
545}
546
547// from bionic
Brian Carlstrom265091e2013-01-30 14:08:26 -0800548static unsigned elfhash(const char *_name) {
549 const unsigned char *name = (const unsigned char *) _name;
550 unsigned h = 0, g;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800551
Brian Carlstromdf629502013-07-17 22:39:56 -0700552 while (*name) {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800553 h = (h << 4) + *name++;
554 g = h & 0xf0000000;
555 h ^= g;
556 h ^= g >> 24;
557 }
558 return h;
559}
560
Brian Carlstromc1409452014-02-26 14:06:23 -0800561Elf32_Shdr& ElfFile::GetSectionNameStringSection() const {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800562 return GetSectionHeader(GetHeader().e_shstrndx);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800563}
564
Brian Carlstromc1409452014-02-26 14:06:23 -0800565const byte* ElfFile::FindDynamicSymbolAddress(const std::string& symbol_name) const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000566 Elf32_Word hash = elfhash(symbol_name.c_str());
567 Elf32_Word bucket_index = hash % GetHashBucketNum();
568 Elf32_Word symbol_and_chain_index = GetHashBucket(bucket_index);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800569 while (symbol_and_chain_index != 0 /* STN_UNDEF */) {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000570 Elf32_Sym& symbol = GetSymbol(SHT_DYNSYM, symbol_and_chain_index);
571 const char* name = GetString(SHT_DYNSYM, symbol.st_name);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800572 if (symbol_name == name) {
573 return base_address_ + symbol.st_value;
574 }
575 symbol_and_chain_index = GetHashChain(symbol_and_chain_index);
576 }
577 return NULL;
578}
579
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000580bool ElfFile::IsSymbolSectionType(Elf32_Word section_type) {
581 return ((section_type == SHT_SYMTAB) || (section_type == SHT_DYNSYM));
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800582}
583
Brian Carlstromc1409452014-02-26 14:06:23 -0800584Elf32_Word ElfFile::GetSymbolNum(Elf32_Shdr& section_header) const {
585 CHECK(IsSymbolSectionType(section_header.sh_type))
586 << file_->GetPath() << " " << section_header.sh_type;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800587 CHECK_NE(0U, section_header.sh_entsize) << file_->GetPath();
588 return section_header.sh_size / section_header.sh_entsize;
589}
590
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000591Elf32_Sym& ElfFile::GetSymbol(Elf32_Word section_type,
Brian Carlstromc1409452014-02-26 14:06:23 -0800592 Elf32_Word i) const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800593 return *(GetSymbolSectionStart(section_type) + i);
594}
595
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000596ElfFile::SymbolTable** ElfFile::GetSymbolTable(Elf32_Word section_type) {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800597 CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type;
598 switch (section_type) {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000599 case SHT_SYMTAB: {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800600 return &symtab_symbol_table_;
601 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000602 case SHT_DYNSYM: {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800603 return &dynsym_symbol_table_;
604 }
605 default: {
606 LOG(FATAL) << section_type;
607 return NULL;
608 }
609 }
610}
611
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000612Elf32_Sym* ElfFile::FindSymbolByName(Elf32_Word section_type,
613 const std::string& symbol_name,
614 bool build_map) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800615 CHECK(!program_header_only_) << file_->GetPath();
616 CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800617
618 SymbolTable** symbol_table = GetSymbolTable(section_type);
619 if (*symbol_table != NULL || build_map) {
620 if (*symbol_table == NULL) {
621 DCHECK(build_map);
622 *symbol_table = new SymbolTable;
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000623 Elf32_Shdr* symbol_section = FindSectionByType(section_type);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800624 CHECK(symbol_section != NULL) << file_->GetPath();
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000625 Elf32_Shdr& string_section = GetSectionHeader(symbol_section->sh_link);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800626 for (uint32_t i = 0; i < GetSymbolNum(*symbol_section); i++) {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000627 Elf32_Sym& symbol = GetSymbol(section_type, i);
628 unsigned char type = ELF32_ST_TYPE(symbol.st_info);
629 if (type == STT_NOTYPE) {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800630 continue;
631 }
632 const char* name = GetString(string_section, symbol.st_name);
633 if (name == NULL) {
634 continue;
635 }
Brian Carlstromc1409452014-02-26 14:06:23 -0800636 std::pair<SymbolTable::iterator, bool> result =
637 (*symbol_table)->insert(std::make_pair(name, &symbol));
Brian Carlstrom265091e2013-01-30 14:08:26 -0800638 if (!result.second) {
639 // If a duplicate, make sure it has the same logical value. Seen on x86.
640 CHECK_EQ(symbol.st_value, result.first->second->st_value);
641 CHECK_EQ(symbol.st_size, result.first->second->st_size);
642 CHECK_EQ(symbol.st_info, result.first->second->st_info);
643 CHECK_EQ(symbol.st_other, result.first->second->st_other);
644 CHECK_EQ(symbol.st_shndx, result.first->second->st_shndx);
645 }
646 }
647 }
648 CHECK(*symbol_table != NULL);
649 SymbolTable::const_iterator it = (*symbol_table)->find(symbol_name);
650 if (it == (*symbol_table)->end()) {
651 return NULL;
652 }
653 return it->second;
654 }
655
656 // Fall back to linear search
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000657 Elf32_Shdr* symbol_section = FindSectionByType(section_type);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800658 CHECK(symbol_section != NULL) << file_->GetPath();
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000659 Elf32_Shdr& string_section = GetSectionHeader(symbol_section->sh_link);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800660 for (uint32_t i = 0; i < GetSymbolNum(*symbol_section); i++) {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000661 Elf32_Sym& symbol = GetSymbol(section_type, i);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800662 const char* name = GetString(string_section, symbol.st_name);
663 if (name == NULL) {
664 continue;
665 }
666 if (symbol_name == name) {
667 return &symbol;
668 }
669 }
670 return NULL;
671}
672
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000673Elf32_Addr ElfFile::FindSymbolAddress(Elf32_Word section_type,
Brian Carlstromc1409452014-02-26 14:06:23 -0800674 const std::string& symbol_name,
675 bool build_map) {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000676 Elf32_Sym* symbol = FindSymbolByName(section_type, symbol_name, build_map);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800677 if (symbol == NULL) {
678 return 0;
679 }
680 return symbol->st_value;
681}
682
Brian Carlstromc1409452014-02-26 14:06:23 -0800683const char* ElfFile::GetString(Elf32_Shdr& string_section, Elf32_Word i) const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800684 CHECK(!program_header_only_) << file_->GetPath();
685 // TODO: remove this static_cast from enum when using -std=gnu++0x
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000686 CHECK_EQ(static_cast<Elf32_Word>(SHT_STRTAB), string_section.sh_type) << file_->GetPath();
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800687 CHECK_LT(i, string_section.sh_size) << file_->GetPath();
688 if (i == 0) {
689 return NULL;
690 }
691 byte* strings = Begin() + string_section.sh_offset;
692 byte* string = strings + i;
693 CHECK_LT(string, End()) << file_->GetPath();
Brian Carlstrom265091e2013-01-30 14:08:26 -0800694 return reinterpret_cast<const char*>(string);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800695}
696
Brian Carlstromc1409452014-02-26 14:06:23 -0800697Elf32_Word ElfFile::GetDynamicNum() const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000698 return GetDynamicProgramHeader().p_filesz / sizeof(Elf32_Dyn);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800699}
700
Brian Carlstromc1409452014-02-26 14:06:23 -0800701Elf32_Dyn& ElfFile::GetDynamic(Elf32_Word i) const {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800702 CHECK_LT(i, GetDynamicNum()) << file_->GetPath();
703 return *(GetDynamicSectionStart() + i);
704}
705
Brian Carlstromc1409452014-02-26 14:06:23 -0800706Elf32_Word ElfFile::FindDynamicValueByType(Elf32_Sword type) const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000707 for (Elf32_Word i = 0; i < GetDynamicNum(); i++) {
708 Elf32_Dyn& elf_dyn = GetDynamic(i);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800709 if (elf_dyn.d_tag == type) {
710 return elf_dyn.d_un.d_val;
711 }
712 }
713 return 0;
714}
715
Brian Carlstromc1409452014-02-26 14:06:23 -0800716Elf32_Rel* ElfFile::GetRelSectionStart(Elf32_Shdr& section_header) const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000717 CHECK(SHT_REL == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
718 return reinterpret_cast<Elf32_Rel*>(Begin() + section_header.sh_offset);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800719}
720
Brian Carlstromc1409452014-02-26 14:06:23 -0800721Elf32_Word ElfFile::GetRelNum(Elf32_Shdr& section_header) const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000722 CHECK(SHT_REL == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800723 CHECK_NE(0U, section_header.sh_entsize) << file_->GetPath();
724 return section_header.sh_size / section_header.sh_entsize;
725}
726
Brian Carlstromc1409452014-02-26 14:06:23 -0800727Elf32_Rel& ElfFile::GetRel(Elf32_Shdr& section_header, Elf32_Word i) const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000728 CHECK(SHT_REL == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800729 CHECK_LT(i, GetRelNum(section_header)) << file_->GetPath();
730 return *(GetRelSectionStart(section_header) + i);
731}
732
Brian Carlstromc1409452014-02-26 14:06:23 -0800733Elf32_Rela* ElfFile::GetRelaSectionStart(Elf32_Shdr& section_header) const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000734 CHECK(SHT_RELA == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
735 return reinterpret_cast<Elf32_Rela*>(Begin() + section_header.sh_offset);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800736}
737
Brian Carlstromc1409452014-02-26 14:06:23 -0800738Elf32_Word ElfFile::GetRelaNum(Elf32_Shdr& section_header) const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000739 CHECK(SHT_RELA == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800740 return section_header.sh_size / section_header.sh_entsize;
741}
742
Brian Carlstromc1409452014-02-26 14:06:23 -0800743Elf32_Rela& ElfFile::GetRela(Elf32_Shdr& section_header, Elf32_Word i) const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000744 CHECK(SHT_RELA == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type;
Brian Carlstrom265091e2013-01-30 14:08:26 -0800745 CHECK_LT(i, GetRelaNum(section_header)) << file_->GetPath();
746 return *(GetRelaSectionStart(section_header) + i);
747}
748
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800749// Base on bionic phdr_table_get_load_size
Brian Carlstromc1409452014-02-26 14:06:23 -0800750size_t ElfFile::GetLoadedSize() const {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000751 Elf32_Addr min_vaddr = 0xFFFFFFFFu;
752 Elf32_Addr max_vaddr = 0x00000000u;
753 for (Elf32_Word i = 0; i < GetProgramHeaderNum(); i++) {
754 Elf32_Phdr& program_header = GetProgramHeader(i);
755 if (program_header.p_type != PT_LOAD) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800756 continue;
757 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000758 Elf32_Addr begin_vaddr = program_header.p_vaddr;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800759 if (begin_vaddr < min_vaddr) {
760 min_vaddr = begin_vaddr;
761 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000762 Elf32_Addr end_vaddr = program_header.p_vaddr + program_header.p_memsz;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800763 if (end_vaddr > max_vaddr) {
764 max_vaddr = end_vaddr;
765 }
766 }
767 min_vaddr = RoundDown(min_vaddr, kPageSize);
768 max_vaddr = RoundUp(max_vaddr, kPageSize);
769 CHECK_LT(min_vaddr, max_vaddr) << file_->GetPath();
770 size_t loaded_size = max_vaddr - min_vaddr;
771 return loaded_size;
772}
773
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700774bool ElfFile::Load(bool executable, std::string* error_msg) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800775 CHECK(program_header_only_) << file_->GetPath();
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000776 for (Elf32_Word i = 0; i < GetProgramHeaderNum(); i++) {
777 Elf32_Phdr& program_header = GetProgramHeader(i);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800778
779 // Record .dynamic header information for later use
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000780 if (program_header.p_type == PT_DYNAMIC) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800781 dynamic_program_header_ = &program_header;
782 continue;
783 }
784
785 // Not something to load, move on.
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000786 if (program_header.p_type != PT_LOAD) {
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800787 continue;
788 }
789
790 // Found something to load.
791
792 // If p_vaddr is zero, it must be the first loadable segment,
793 // since they must be in order. Since it is zero, there isn't a
794 // specific address requested, so first request a contiguous chunk
795 // of required size for all segments, but with no
796 // permissions. We'll then carve that up with the proper
797 // permissions as we load the actual segments. If p_vaddr is
798 // non-zero, the segments require the specific address specified,
799 // which either was specified in the file because we already set
800 // base_address_ after the first zero segment).
Ian Rogerscdfcf372014-01-23 20:38:36 -0800801 int64_t temp_file_length = file_->GetLength();
802 if (temp_file_length < 0) {
803 errno = -temp_file_length;
804 *error_msg = StringPrintf("Failed to get length of file: '%s' fd=%d: %s",
805 file_->GetPath().c_str(), file_->Fd(), strerror(errno));
806 return false;
807 }
808 size_t file_length = static_cast<size_t>(temp_file_length);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800809 if (program_header.p_vaddr == 0) {
Brian Carlstrom6a47b9d2013-05-17 10:58:25 -0700810 std::string reservation_name("ElfFile reservation for ");
811 reservation_name += file_->GetPath();
812 UniquePtr<MemMap> reserve(MemMap::MapAnonymous(reservation_name.c_str(),
Ian Rogersef7d42f2014-01-06 12:55:46 -0800813 NULL, GetLoadedSize(), PROT_NONE, false,
Brian Carlstromc1409452014-02-26 14:06:23 -0800814 error_msg));
815 if (reserve.get() == nullptr) {
816 *error_msg = StringPrintf("Failed to allocate %s: %s",
817 reservation_name.c_str(), error_msg->c_str());
818 return false;
819 }
Brian Carlstrom6a47b9d2013-05-17 10:58:25 -0700820 base_address_ = reserve->Begin();
821 segments_.push_back(reserve.release());
822 }
823 // empty segment, nothing to map
824 if (program_header.p_memsz == 0) {
825 continue;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800826 }
827 byte* p_vaddr = base_address_ + program_header.p_vaddr;
828 int prot = 0;
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000829 if (executable && ((program_header.p_flags & PF_X) != 0)) {
Brian Carlstrom6a47b9d2013-05-17 10:58:25 -0700830 prot |= PROT_EXEC;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800831 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000832 if ((program_header.p_flags & PF_W) != 0) {
Brian Carlstrom6a47b9d2013-05-17 10:58:25 -0700833 prot |= PROT_WRITE;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800834 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000835 if ((program_header.p_flags & PF_R) != 0) {
Brian Carlstrom6a47b9d2013-05-17 10:58:25 -0700836 prot |= PROT_READ;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800837 }
838 int flags = MAP_FIXED;
839 if (writable_) {
840 prot |= PROT_WRITE;
841 flags |= MAP_SHARED;
842 } else {
843 flags |= MAP_PRIVATE;
844 }
Brian Carlstrom3a223612013-10-10 17:18:24 -0700845 if (file_length < (program_header.p_offset + program_header.p_memsz)) {
Ian Rogerscdfcf372014-01-23 20:38:36 -0800846 *error_msg = StringPrintf("File size of %zd bytes not large enough to contain ELF segment "
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700847 "%d of %d bytes: '%s'", file_length, i,
848 program_header.p_offset + program_header.p_memsz,
849 file_->GetPath().c_str());
Brian Carlstrom3a223612013-10-10 17:18:24 -0700850 return false;
851 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800852 UniquePtr<MemMap> segment(MemMap::MapFileAtAddress(p_vaddr,
853 program_header.p_memsz,
854 prot, flags, file_->Fd(),
855 program_header.p_offset,
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700856 true,
857 file_->GetPath().c_str(),
858 error_msg));
Brian Carlstromc1409452014-02-26 14:06:23 -0800859 if (segment.get() == nullptr) {
860 *error_msg = StringPrintf("Failed to map ELF file segment %d from %s: %s",
861 i, file_->GetPath().c_str(), error_msg->c_str());
862 return false;
863 }
864 if (segment->Begin() != p_vaddr) {
865 *error_msg = StringPrintf("Failed to map ELF file segment %d from %s at expected address %p, "
866 "instead mapped to %p",
867 i, file_->GetPath().c_str(), p_vaddr, segment->Begin());
868 return false;
869 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800870 segments_.push_back(segment.release());
871 }
Brian Carlstrom265091e2013-01-30 14:08:26 -0800872
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800873 // Now that we are done loading, .dynamic should be in memory to find .dynstr, .dynsym, .hash
874 dynamic_section_start_
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000875 = reinterpret_cast<Elf32_Dyn*>(base_address_ + GetDynamicProgramHeader().p_vaddr);
876 for (Elf32_Word i = 0; i < GetDynamicNum(); i++) {
877 Elf32_Dyn& elf_dyn = GetDynamic(i);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800878 byte* d_ptr = base_address_ + elf_dyn.d_un.d_ptr;
879 switch (elf_dyn.d_tag) {
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000880 case DT_HASH: {
Brian Carlstromc1409452014-02-26 14:06:23 -0800881 if (!ValidPointer(d_ptr)) {
882 *error_msg = StringPrintf("DT_HASH value %p does not refer to a loaded ELF segment of %s",
883 d_ptr, file_->GetPath().c_str());
884 return false;
885 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000886 hash_section_start_ = reinterpret_cast<Elf32_Word*>(d_ptr);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800887 break;
888 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000889 case DT_STRTAB: {
Brian Carlstromc1409452014-02-26 14:06:23 -0800890 if (!ValidPointer(d_ptr)) {
891 *error_msg = StringPrintf("DT_HASH value %p does not refer to a loaded ELF segment of %s",
892 d_ptr, file_->GetPath().c_str());
893 return false;
894 }
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800895 dynstr_section_start_ = reinterpret_cast<char*>(d_ptr);
896 break;
897 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000898 case DT_SYMTAB: {
Brian Carlstromc1409452014-02-26 14:06:23 -0800899 if (!ValidPointer(d_ptr)) {
900 *error_msg = StringPrintf("DT_HASH value %p does not refer to a loaded ELF segment of %s",
901 d_ptr, file_->GetPath().c_str());
902 return false;
903 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000904 dynsym_section_start_ = reinterpret_cast<Elf32_Sym*>(d_ptr);
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800905 break;
906 }
Nicolas Geoffray50cfe742014-02-19 13:27:42 +0000907 case DT_NULL: {
Brian Carlstromc1409452014-02-26 14:06:23 -0800908 if (GetDynamicNum() != i+1) {
909 *error_msg = StringPrintf("DT_NULL found after %d .dynamic entries, "
910 "expected %d as implied by size of PT_DYNAMIC segment in %s",
911 i + 1, GetDynamicNum(), file_->GetPath().c_str());
912 return false;
913 }
Brian Carlstrom265091e2013-01-30 14:08:26 -0800914 break;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800915 }
916 }
917 }
918
Mark Mendellae9fd932014-02-10 16:14:35 -0800919 // Use GDB JIT support to do stack backtrace, etc.
920 if (executable) {
921 GdbJITSupport();
922 }
923
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800924 return true;
925}
926
Brian Carlstromc1409452014-02-26 14:06:23 -0800927bool ElfFile::ValidPointer(const byte* start) const {
928 for (size_t i = 0; i < segments_.size(); ++i) {
929 const MemMap* segment = segments_[i];
930 if (segment->Begin() <= start && start < segment->End()) {
931 return true;
932 }
933 }
934 return false;
935}
936
Mark Mendellae9fd932014-02-10 16:14:35 -0800937static bool check_section_name(ElfFile& file, int section_num, const char *name) {
938 Elf32_Shdr& section_header = file.GetSectionHeader(section_num);
939 const char *section_name = file.GetString(SHT_SYMTAB, section_header.sh_name);
940 return strcmp(name, section_name) == 0;
941}
942
943static void IncrementUint32(byte *p, uint32_t increment) {
944 uint32_t *u = reinterpret_cast<uint32_t *>(p);
945 *u += increment;
946}
947
948static void RoundAndClear(byte *image, uint32_t& offset, int pwr2) {
949 uint32_t mask = pwr2 - 1;
950 while (offset & mask) {
951 image[offset++] = 0;
952 }
953}
954
955// Simple macro to bump a point to a section header to the next one.
956#define BUMP_SHENT(sp) \
957 sp = reinterpret_cast<Elf32_Shdr *> (\
958 reinterpret_cast<byte*>(sp) + elf_hdr.e_shentsize);\
959 offset += elf_hdr.e_shentsize
960
961void ElfFile::GdbJITSupport() {
962 // We only get here if we only are mapping the program header.
963 DCHECK(program_header_only_);
964
965 // Well, we need the whole file to do this.
966 std::string error_msg;
967 UniquePtr<ElfFile> ptr(Open(const_cast<File*>(file_), false, false, &error_msg));
968 ElfFile& all = *ptr;
969
970 // Do we have interesting sections?
971 // Is this an OAT file with interesting sections?
972 if (all.GetSectionHeaderNum() != kExpectedSectionsInOATFile) {
973 return;
974 }
975 if (!check_section_name(all, 8, ".debug_info") ||
976 !check_section_name(all, 9, ".debug_abbrev") ||
977 !check_section_name(all, 10, ".debug_frame") ||
978 !check_section_name(all, 11, ".debug_str")) {
979 return;
980 }
Ian Rogers1a570662014-03-12 01:02:21 -0700981#ifdef __LP64__
982 if (true) {
983 return; // No ELF debug support in 64bit.
984 }
985#endif
Kenny Root6243e0e2014-03-03 13:33:48 -0800986 // This is not needed if we have no .text segment.
987 uint32_t text_start_addr = 0;
988 for (uint32_t i = 0; i < segments_.size(); i++) {
989 if (segments_[i]->GetProtect() & PROT_EXEC) {
990 // We found the .text section.
991 text_start_addr = PointerToLowMemUInt32(segments_[i]->Begin());
992 break;
993 }
994 }
995 if (text_start_addr == 0U) {
996 return;
997 }
998
Mark Mendellae9fd932014-02-10 16:14:35 -0800999 // Okay, we are good enough. Fake up an ELF image and tell GDB about it.
1000 // We need some extra space for the debug and string sections, the ELF header, and the
1001 // section header.
1002 uint32_t needed_size = KB;
1003
1004 for (Elf32_Word i = 1; i < all.GetSectionHeaderNum(); i++) {
1005 Elf32_Shdr& section_header = all.GetSectionHeader(i);
1006 if (section_header.sh_addr == 0 && section_header.sh_type != SHT_DYNSYM) {
1007 // Debug section: we need it.
1008 needed_size += section_header.sh_size;
1009 } else if (section_header.sh_type == SHT_STRTAB &&
1010 strcmp(".shstrtab",
1011 all.GetString(SHT_SYMTAB, section_header.sh_name)) == 0) {
1012 // We also need the shared string table.
1013 needed_size += section_header.sh_size;
1014
1015 // We also need the extra strings .symtab\0.strtab\0
1016 needed_size += 16;
1017 }
1018 }
1019
1020 // Start creating our image.
1021 jit_elf_image_ = new byte[needed_size];
1022
1023 // Create the Elf Header by copying the old one
1024 Elf32_Ehdr& elf_hdr =
1025 *reinterpret_cast<Elf32_Ehdr*>(jit_elf_image_);
1026
1027 elf_hdr = all.GetHeader();
1028 elf_hdr.e_entry = 0;
1029 elf_hdr.e_phoff = 0;
1030 elf_hdr.e_phnum = 0;
1031 elf_hdr.e_phentsize = 0;
1032 elf_hdr.e_type = ET_EXEC;
1033
1034 uint32_t offset = sizeof(Elf32_Ehdr);
1035
1036 // Copy the debug sections and string table.
1037 uint32_t debug_offsets[kExpectedSectionsInOATFile];
1038 memset(debug_offsets, '\0', sizeof debug_offsets);
1039 Elf32_Shdr *text_header = nullptr;
1040 int extra_shstrtab_entries = -1;
1041 int text_section_index = -1;
1042 int section_index = 1;
1043 for (Elf32_Word i = 1; i < kExpectedSectionsInOATFile; i++) {
1044 Elf32_Shdr& section_header = all.GetSectionHeader(i);
1045 // Round up to multiple of 4, ensuring zero fill.
1046 RoundAndClear(jit_elf_image_, offset, 4);
1047 if (section_header.sh_addr == 0 && section_header.sh_type != SHT_DYNSYM) {
1048 // Debug section: we need it. Unfortunately, it wasn't mapped in.
1049 debug_offsets[i] = offset;
1050 // Read it from the file.
1051 lseek(file_->Fd(), section_header.sh_offset, SEEK_SET);
1052 read(file_->Fd(), jit_elf_image_ + offset, section_header.sh_size);
1053 offset += section_header.sh_size;
1054 section_index++;
1055 offset += 16;
1056 } else if (section_header.sh_type == SHT_STRTAB &&
1057 strcmp(".shstrtab",
1058 all.GetString(SHT_SYMTAB, section_header.sh_name)) == 0) {
1059 // We also need the shared string table.
1060 debug_offsets[i] = offset;
1061 // Read it from the file.
1062 lseek(file_->Fd(), section_header.sh_offset, SEEK_SET);
1063 read(file_->Fd(), jit_elf_image_ + offset, section_header.sh_size);
1064 offset += section_header.sh_size;
1065 // We also need the extra strings .symtab\0.strtab\0
1066 extra_shstrtab_entries = section_header.sh_size;
1067 memcpy(jit_elf_image_+offset, ".symtab\0.strtab\0", 16);
1068 offset += 16;
1069 section_index++;
1070 } else if (section_header.sh_flags & SHF_EXECINSTR) {
1071 DCHECK(strcmp(".text", all.GetString(SHT_SYMTAB,
1072 section_header.sh_name)) == 0);
1073 text_header = &section_header;
1074 text_section_index = section_index++;
1075 }
1076 }
1077 DCHECK(text_header != nullptr);
1078 DCHECK_NE(extra_shstrtab_entries, -1);
1079
1080 // We now need to update the addresses for debug_info and debug_frame to get to the
1081 // correct offset within the .text section.
Mark Mendellae9fd932014-02-10 16:14:35 -08001082 byte *p = jit_elf_image_+debug_offsets[8];
1083 byte *end = p + all.GetSectionHeader(8).sh_size;
1084
1085 // For debug_info; patch compilation using low_pc @ offset 13, high_pc at offset 17.
1086 IncrementUint32(p + 13, text_start_addr);
1087 IncrementUint32(p + 17, text_start_addr);
1088
1089 // Now fix the low_pc, high_pc for each method address.
1090 // First method starts at offset 0x15, each subsequent method is 1+3*4 bytes further.
1091 for (p += 0x15; p < end; p += 1 /* attr# */ + 3 * sizeof(uint32_t) /* addresses */) {
1092 IncrementUint32(p + 1 + sizeof(uint32_t), text_start_addr);
1093 IncrementUint32(p + 1 + 2 * sizeof(uint32_t), text_start_addr);
1094 }
1095
1096 // Now we have to handle the debug_frame method start addresses
1097 p = jit_elf_image_+debug_offsets[10];
1098 end = p + all.GetSectionHeader(10).sh_size;
1099
1100 // Skip past the CIE.
1101 p += *reinterpret_cast<uint32_t *>(p) + 4;
1102
1103 // And walk the FDEs.
1104 for (; p < end; p += *reinterpret_cast<uint32_t *>(p) + sizeof(uint32_t)) {
1105 IncrementUint32(p + 2 * sizeof(uint32_t), text_start_addr);
1106 }
1107
1108 // Create the data for the symbol table.
1109 const int kSymbtabAlignment = 16;
1110 RoundAndClear(jit_elf_image_, offset, kSymbtabAlignment);
1111 uint32_t symtab_offset = offset;
1112
1113 // First entry is empty.
1114 memset(jit_elf_image_+offset, 0, sizeof(Elf32_Sym));
1115 offset += sizeof(Elf32_Sym);
1116
1117 // Symbol 1 is the real .text section.
1118 Elf32_Sym& sym_ent = *reinterpret_cast<Elf32_Sym*>(jit_elf_image_+offset);
1119 sym_ent.st_name = 1; /* .text */
1120 sym_ent.st_value = text_start_addr;
1121 sym_ent.st_size = text_header->sh_size;
1122 SetBindingAndType(&sym_ent, STB_LOCAL, STT_SECTION);
1123 sym_ent.st_other = 0;
1124 sym_ent.st_shndx = text_section_index;
1125 offset += sizeof(Elf32_Sym);
1126
1127 // Create the data for the string table.
1128 RoundAndClear(jit_elf_image_, offset, kSymbtabAlignment);
1129 const int kTextStringSize = 7;
1130 uint32_t strtab_offset = offset;
1131 memcpy(jit_elf_image_+offset, "\0.text", kTextStringSize);
1132 offset += kTextStringSize;
1133
1134 // Create the section header table.
1135 // Round up to multiple of kSymbtabAlignment, ensuring zero fill.
1136 RoundAndClear(jit_elf_image_, offset, kSymbtabAlignment);
1137 elf_hdr.e_shoff = offset;
1138 Elf32_Shdr *sp =
1139 reinterpret_cast<Elf32_Shdr *>(jit_elf_image_ + offset);
1140
1141 // Copy the first empty index.
1142 *sp = all.GetSectionHeader(0);
1143 BUMP_SHENT(sp);
1144
1145 elf_hdr.e_shnum = 1;
1146 for (Elf32_Word i = 1; i < kExpectedSectionsInOATFile; i++) {
1147 Elf32_Shdr& section_header = all.GetSectionHeader(i);
1148 if (section_header.sh_addr == 0 && section_header.sh_type != SHT_DYNSYM) {
1149 // Debug section: we need it.
1150 *sp = section_header;
1151 sp->sh_offset = debug_offsets[i];
1152 sp->sh_addr = 0;
1153 elf_hdr.e_shnum++;
1154 BUMP_SHENT(sp);
1155 } else if (section_header.sh_type == SHT_STRTAB &&
1156 strcmp(".shstrtab",
1157 all.GetString(SHT_SYMTAB, section_header.sh_name)) == 0) {
1158 // We also need the shared string table.
1159 *sp = section_header;
1160 sp->sh_offset = debug_offsets[i];
1161 sp->sh_size += 16; /* sizeof ".symtab\0.strtab\0" */
1162 sp->sh_addr = 0;
1163 elf_hdr.e_shstrndx = elf_hdr.e_shnum;
1164 elf_hdr.e_shnum++;
1165 BUMP_SHENT(sp);
1166 }
1167 }
1168
1169 // Add a .text section for the matching code section.
1170 *sp = *text_header;
1171 sp->sh_type = SHT_NOBITS;
1172 sp->sh_offset = 0;
1173 sp->sh_addr = text_start_addr;
1174 elf_hdr.e_shnum++;
1175 BUMP_SHENT(sp);
1176
1177 // .symtab section: Need an empty index and the .text entry
1178 sp->sh_name = extra_shstrtab_entries;
1179 sp->sh_type = SHT_SYMTAB;
1180 sp->sh_flags = 0;
1181 sp->sh_addr = 0;
1182 sp->sh_offset = symtab_offset;
1183 sp->sh_size = 2 * sizeof(Elf32_Sym);
1184 sp->sh_link = elf_hdr.e_shnum + 1; // Link to .strtab section.
1185 sp->sh_info = 0;
1186 sp->sh_addralign = 16;
1187 sp->sh_entsize = sizeof(Elf32_Sym);
1188 elf_hdr.e_shnum++;
1189 BUMP_SHENT(sp);
1190
1191 // .strtab section: Enough for .text\0.
1192 sp->sh_name = extra_shstrtab_entries + 8;
1193 sp->sh_type = SHT_STRTAB;
1194 sp->sh_flags = 0;
1195 sp->sh_addr = 0;
1196 sp->sh_offset = strtab_offset;
1197 sp->sh_size = kTextStringSize;
1198 sp->sh_link = 0;
1199 sp->sh_info = 0;
1200 sp->sh_addralign = 16;
1201 sp->sh_entsize = 0;
1202 elf_hdr.e_shnum++;
1203 BUMP_SHENT(sp);
1204
1205 // We now have enough information to tell GDB about our file.
1206 jit_gdb_entry_ = CreateCodeEntry(jit_elf_image_, offset);
1207}
1208
Brian Carlstrom700c8d32012-11-05 10:42:02 -08001209} // namespace art