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 <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 Elf32_Addr begin = segment_header->p_vaddr; | 155 Elf32_Addr begin = segment_header->p_vaddr; |
156 Elf32_Addr end = segment_header->p_vaddr + segment_header->p_memsz; | 156 Elf32_Addr end = segment_header->p_vaddr + segment_header->p_memsz; |
157 | 157 |
158 if (rva >= begin && rva < end) | 158 if (rva >= begin && rva < end) |
159 return true; | 159 return true; |
160 } | 160 } |
161 | 161 |
162 return false; | 162 return false; |
163 } | 163 } |
164 | 164 |
165 // Returns RVA for an in memory address, or NULL. | 165 CheckBool DisassemblerElf32::RVAToFileOffset(RVA rva, |
166 CheckBool DisassemblerElf32::RVAToFileOffset(Elf32_Addr addr, | 166 size_t* result) const { |
167 size_t* result) const { | 167 for (int i = 0; i < SectionHeaderCount(); i++) { |
| 168 const Elf32_Shdr *section_header = SectionHeader(i); |
| 169 // These can appear to have a size in the file, but don't. |
| 170 if (section_header->sh_type == SHT_NOBITS) |
| 171 continue; |
| 172 Elf32_Addr begin = section_header->sh_addr; |
| 173 Elf32_Addr end = begin + section_header->sh_size; |
168 | 174 |
169 for (int i = 0; i < ProgramSegmentHeaderCount(); i++) { | 175 if (rva >= begin && rva < end) { |
170 Elf32_Addr begin = ProgramSegmentMemoryBegin(i); | 176 *result = section_header->sh_offset + (rva - begin); |
171 Elf32_Addr end = begin + ProgramSegmentMemorySize(i); | 177 return true; |
172 | |
173 if (addr >= begin && addr < end) { | |
174 Elf32_Addr offset = addr - begin; | |
175 | |
176 if (offset < ProgramSegmentFileSize(i)) { | |
177 *result = ProgramSegmentFileOffset(i) + offset; | |
178 return true; | |
179 } | |
180 } | 178 } |
181 } | 179 } |
182 | |
183 return false; | 180 return false; |
184 } | 181 } |
185 | 182 |
186 RVA DisassemblerElf32::FileOffsetToRVA(size_t offset) const { | 183 RVA DisassemblerElf32::FileOffsetToRVA(size_t offset) const { |
187 // File offsets can be 64 bit values, but we are dealing with 32 | 184 // File offsets can be 64 bit values, but we are dealing with 32 |
188 // bit executables and so only need to support 32bit file sizes. | 185 // bit executables and so only need to support 32bit file sizes. |
189 uint32_t offset32 = (uint32_t)offset; | 186 uint32_t offset32 = (uint32_t)offset; |
190 | 187 |
191 for (int i = 0; i < SectionHeaderCount(); i++) { | 188 for (int i = 0; i < SectionHeaderCount(); i++) { |
192 | 189 |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 | 481 |
485 rel32_locations_.clear(); | 482 rel32_locations_.clear(); |
486 | 483 |
487 // Loop through sections for relocation sections | 484 // Loop through sections for relocation sections |
488 for (int section_id = 0; | 485 for (int section_id = 0; |
489 section_id < SectionHeaderCount(); | 486 section_id < SectionHeaderCount(); |
490 section_id++) { | 487 section_id++) { |
491 | 488 |
492 const Elf32_Shdr *section_header = SectionHeader(section_id); | 489 const Elf32_Shdr *section_header = SectionHeader(section_id); |
493 | 490 |
494 if (section_header->sh_type != SHT_PROGBITS) | 491 // Some debug sections can have sh_type=SHT_PROGBITS but sh_addr=0. |
| 492 if (section_header->sh_type != SHT_PROGBITS || |
| 493 section_header->sh_addr == 0) |
495 continue; | 494 continue; |
496 | 495 |
497 if (!ParseRel32RelocsFromSection(section_header)) | 496 if (!ParseRel32RelocsFromSection(section_header)) |
498 return false; | 497 return false; |
499 } | 498 } |
500 | 499 |
501 std::sort(rel32_locations_.begin(), | 500 std::sort(rel32_locations_.begin(), |
502 rel32_locations_.end(), | 501 rel32_locations_.end(), |
503 TypedRVA::IsLessThan); | 502 TypedRVA::IsLessThan); |
504 DCHECK(rel32_locations_.empty() || | 503 DCHECK(rel32_locations_.empty() || |
505 rel32_locations_.back()->rva() != kUnassignedRVA); | 504 rel32_locations_.back()->rva() != kUnassignedRVA); |
506 return true; | 505 return true; |
507 } | 506 } |
508 | 507 |
509 } // namespace courgette | 508 } // namespace courgette |
OLD | NEW |