OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "courgette/disassembler_elf_32.h" | 5 #include "courgette/disassembler_elf_32.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "courgette/assembly_program.h" | 10 #include "courgette/assembly_program.h" |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
162 | 162 |
163 if (!ParseAbs32Relocs()) | 163 if (!ParseAbs32Relocs()) |
164 return false; | 164 return false; |
165 | 165 |
166 if (!ParseRel32RelocsFromSections()) | 166 if (!ParseRel32RelocsFromSections()) |
167 return false; | 167 return false; |
168 | 168 |
169 if (!ParseFile(target)) | 169 if (!ParseFile(target)) |
170 return false; | 170 return false; |
171 | 171 |
172 std::sort(rel32_locations_.begin(), | |
173 rel32_locations_.end(), | |
174 TypedRVA::IsLessThanByRVA); | |
175 DCHECK(rel32_locations_.empty() || | |
176 rel32_locations_.back()->rva() != kUnassignedRVA); | |
177 | |
172 target->DefaultAssignIndexes(); | 178 target->DefaultAssignIndexes(); |
173 return true; | 179 return true; |
174 } | 180 } |
175 | 181 |
176 bool DisassemblerElf32::UpdateLength() { | 182 bool DisassemblerElf32::UpdateLength() { |
177 Elf32_Off result = 0; | 183 Elf32_Off result = 0; |
178 | 184 |
179 // Find the end of the last section | 185 // Find the end of the last section |
180 for (Elf32_Half section_id = 0; section_id < SectionHeaderCount(); | 186 for (Elf32_Half section_id = 0; section_id < SectionHeaderCount(); |
181 ++section_id) { | 187 ++section_id) { |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
276 } | 282 } |
277 return true; | 283 return true; |
278 } | 284 } |
279 | 285 |
280 CheckBool DisassemblerElf32::ParseFile(AssemblyProgram* program) { | 286 CheckBool DisassemblerElf32::ParseFile(AssemblyProgram* program) { |
281 // Walk all the bytes in the file, whether or not in a section. | 287 // Walk all the bytes in the file, whether or not in a section. |
282 FileOffset file_offset = 0; | 288 FileOffset file_offset = 0; |
283 | 289 |
284 std::vector<FileOffset> abs_offsets; | 290 std::vector<FileOffset> abs_offsets; |
285 | 291 |
292 // File parsing follows file offset order, and we visit abs32 and rel32 | |
293 // locations in lockstep. Therefore we need to extract and sort file offsets | |
294 // of all abs32 and rel32 locations. | |
286 if (!RVAsToFileOffsets(abs32_locations_, &abs_offsets)) | 295 if (!RVAsToFileOffsets(abs32_locations_, &abs_offsets)) |
287 return false; | 296 return false; |
297 std::sort(abs32_locations_.begin(), abs32_locations_.end()); | |
288 | 298 |
289 if (!RVAsToFileOffsets(&rel32_locations_)) | 299 if (!RVAsToFileOffsets(&rel32_locations_)) |
290 return false; | 300 return false; |
301 std::sort(rel32_locations_.begin(), | |
302 rel32_locations_.end(), | |
303 TypedRVA::IsLessThanByFileOffset); | |
291 | 304 |
292 std::vector<FileOffset>::iterator current_abs_offset = abs_offsets.begin(); | 305 std::vector<FileOffset>::iterator current_abs_offset = abs_offsets.begin(); |
306 std::vector<FileOffset>::iterator end_abs_offset = abs_offsets.end(); | |
307 | |
293 ScopedVector<TypedRVA>::iterator current_rel = rel32_locations_.begin(); | 308 ScopedVector<TypedRVA>::iterator current_rel = rel32_locations_.begin(); |
294 | |
295 std::vector<FileOffset>::iterator end_abs_offset = abs_offsets.end(); | |
296 ScopedVector<TypedRVA>::iterator end_rel = rel32_locations_.end(); | 309 ScopedVector<TypedRVA>::iterator end_rel = rel32_locations_.end(); |
297 | 310 |
298 // Visit section headers ordered by file offset. | 311 // Visit section headers ordered by file offset. |
299 for (Elf32_Half section_id : section_header_file_offset_order_) { | 312 for (Elf32_Half section_id : section_header_file_offset_order_) { |
300 const Elf32_Shdr* section_header = SectionHeader(section_id); | 313 const Elf32_Shdr* section_header = SectionHeader(section_id); |
301 | 314 |
302 if (section_header->sh_type == SHT_NOBITS) | 315 if (section_header->sh_type == SHT_NOBITS) |
303 continue; | 316 continue; |
304 | 317 |
305 if (!ParseSimpleRegion(file_offset, section_header->sh_offset, program)) | 318 if (!ParseSimpleRegion(file_offset, section_header->sh_offset, program)) |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
505 return true; | 518 return true; |
506 } | 519 } |
507 } | 520 } |
508 } | 521 } |
509 | 522 |
510 return false; | 523 return false; |
511 } | 524 } |
512 | 525 |
513 CheckBool DisassemblerElf32::ParseRel32RelocsFromSections() { | 526 CheckBool DisassemblerElf32::ParseRel32RelocsFromSections() { |
514 rel32_locations_.clear(); | 527 rel32_locations_.clear(); |
528 bool found_rel32 = false; | |
515 | 529 |
516 // Loop through sections for relocation sections | 530 // Loop through sections for relocation sections |
517 for (Elf32_Half section_id = 0; section_id < SectionHeaderCount(); | 531 for (Elf32_Half section_id = 0; section_id < SectionHeaderCount(); |
518 ++section_id) { | 532 ++section_id) { |
519 const Elf32_Shdr* section_header = SectionHeader(section_id); | 533 const Elf32_Shdr* section_header = SectionHeader(section_id); |
520 | 534 |
521 // TODO(huangs): Add better checks to skip non-code sections. | |
522 // Some debug sections can have sh_type=SHT_PROGBITS but sh_addr=0. | 535 // Some debug sections can have sh_type=SHT_PROGBITS but sh_addr=0. |
523 if (section_header->sh_type != SHT_PROGBITS || | 536 if (section_header->sh_type != SHT_PROGBITS || |
524 section_header->sh_addr == 0) | 537 section_header->sh_addr == 0) |
525 continue; | 538 continue; |
526 | 539 |
540 // Heuristic: Only consider ".text" section. | |
541 std::string section_name; | |
542 if (!SectionName(*section_header, §ion_name)) | |
543 return false; | |
544 if (section_name != ".text") | |
545 continue; | |
546 | |
547 found_rel32 = true; | |
527 if (!ParseRel32RelocsFromSection(section_header)) | 548 if (!ParseRel32RelocsFromSection(section_header)) |
528 return false; | 549 return false; |
529 } | 550 } |
551 if (!found_rel32) | |
552 VLOG(1) << "Warning: Found no rel32 addresses. Missing .text section?"; | |
Will Harris
2016/04/28 19:45:49
what does this warning mean if it's seen? is there
huangs
2016/04/28 19:53:45
The warning says "your ELF file is weird because i
Will Harris
2016/04/28 20:04:02
Acknowledged.
| |
530 | 553 |
531 std::sort(rel32_locations_.begin(), | |
532 rel32_locations_.end(), | |
533 TypedRVA::IsLessThan); | |
534 DCHECK(rel32_locations_.empty() || | |
535 rel32_locations_.back()->rva() != kUnassignedRVA); | |
536 return true; | 554 return true; |
537 } | 555 } |
538 | 556 |
539 } // namespace courgette | 557 } // namespace courgette |
OLD | NEW |