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 #include <iterator> | 8 #include <iterator> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 if (default_string_section_[default_string_section_size_ - 1] != '\0') | 156 if (default_string_section_[default_string_section_size_ - 1] != '\0') |
157 return Bad("String section does not terminate"); | 157 return Bad("String section does not terminate"); |
158 } | 158 } |
159 | 159 |
160 if (!UpdateLength()) | 160 if (!UpdateLength()) |
161 return Bad("Out of bounds section or segment"); | 161 return Bad("Out of bounds section or segment"); |
162 | 162 |
163 return Good(); | 163 return Good(); |
164 } | 164 } |
165 | 165 |
166 bool DisassemblerElf32::Disassemble(AssemblyProgram* program) { | |
167 if (!ok()) | |
168 return false; | |
169 | |
170 if (!ParseAbs32Relocs()) | |
171 return false; | |
172 | |
173 if (!ParseRel32RelocsFromSections()) // Does not sort rel32 locations. | |
174 return false; | |
175 | |
176 PrecomputeLabels(program); | |
177 RemoveUnusedRel32Locations(program); | |
178 | |
179 if (!program->GenerateInstructions( | |
180 base::Bind(&DisassemblerElf32::ParseFile, base::Unretained(this)))) { | |
181 return false; | |
182 } | |
183 | |
184 program->DefaultAssignIndexes(); | |
185 return true; | |
186 } | |
187 | |
188 CheckBool DisassemblerElf32::IsValidTargetRVA(RVA rva) const { | 166 CheckBool DisassemblerElf32::IsValidTargetRVA(RVA rva) const { |
189 if (rva == kUnassignedRVA) | 167 if (rva == kUnassignedRVA) |
190 return false; | 168 return false; |
191 | 169 |
192 // |rva| is valid if it's contained in any program segment. | 170 // |rva| is valid if it's contained in any program segment. |
193 for (Elf32_Half segment_id = 0; segment_id < ProgramSegmentHeaderCount(); | 171 for (Elf32_Half segment_id = 0; segment_id < ProgramSegmentHeaderCount(); |
194 ++segment_id) { | 172 ++segment_id) { |
195 const Elf32_Phdr* segment_header = ProgramSegmentHeader(segment_id); | 173 const Elf32_Phdr* segment_header = ProgramSegmentHeader(segment_id); |
196 | 174 |
197 if (segment_header->p_type != PT_LOAD) | 175 if (segment_header->p_type != PT_LOAD) |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 std::vector<std::unique_ptr<TypedRVA>>* typed_rvas) const { | 287 std::vector<std::unique_ptr<TypedRVA>>* typed_rvas) const { |
310 for (auto& typed_rva : *typed_rvas) { | 288 for (auto& typed_rva : *typed_rvas) { |
311 FileOffset file_offset = RVAToFileOffset(typed_rva->rva()); | 289 FileOffset file_offset = RVAToFileOffset(typed_rva->rva()); |
312 if (file_offset == kNoFileOffset) | 290 if (file_offset == kNoFileOffset) |
313 return false; | 291 return false; |
314 typed_rva->set_file_offset(file_offset); | 292 typed_rva->set_file_offset(file_offset); |
315 } | 293 } |
316 return true; | 294 return true; |
317 } | 295 } |
318 | 296 |
319 CheckBool DisassemblerElf32::ParseAbs32Relocs() { | 297 bool DisassemblerElf32::ExtractAbs32Locations() { |
320 abs32_locations_.clear(); | 298 abs32_locations_.clear(); |
321 | 299 |
322 // Loop through sections for relocation sections | 300 // Loop through sections for relocation sections |
323 for (Elf32_Half section_id = 0; section_id < SectionHeaderCount(); | 301 for (Elf32_Half section_id = 0; section_id < SectionHeaderCount(); |
324 ++section_id) { | 302 ++section_id) { |
325 const Elf32_Shdr* section_header = SectionHeader(section_id); | 303 const Elf32_Shdr* section_header = SectionHeader(section_id); |
326 | 304 |
327 if (section_header->sh_type == SHT_REL) { | 305 if (section_header->sh_type == SHT_REL) { |
328 const Elf32_Rel* relocs_table = | 306 const Elf32_Rel* relocs_table = |
329 reinterpret_cast<const Elf32_Rel*>(SectionBody(section_id)); | 307 reinterpret_cast<const Elf32_Rel*>(SectionBody(section_id)); |
(...skipping 13 matching lines...) Expand all Loading... |
343 abs32_locations_.push_back(rva); | 321 abs32_locations_.push_back(rva); |
344 } | 322 } |
345 } | 323 } |
346 } | 324 } |
347 | 325 |
348 std::sort(abs32_locations_.begin(), abs32_locations_.end()); | 326 std::sort(abs32_locations_.begin(), abs32_locations_.end()); |
349 DCHECK(abs32_locations_.empty() || abs32_locations_.back() != kUnassignedRVA); | 327 DCHECK(abs32_locations_.empty() || abs32_locations_.back() != kUnassignedRVA); |
350 return true; | 328 return true; |
351 } | 329 } |
352 | 330 |
353 CheckBool DisassemblerElf32::ParseRel32RelocsFromSections() { | 331 bool DisassemblerElf32::ExtractRel32Locations() { |
354 rel32_locations_.clear(); | 332 rel32_locations_.clear(); |
355 bool found_rel32 = false; | 333 bool found_rel32 = false; |
356 | 334 |
357 // Loop through sections for relocation sections | 335 // Loop through sections for relocation sections |
358 for (Elf32_Half section_id = 0; section_id < SectionHeaderCount(); | 336 for (Elf32_Half section_id = 0; section_id < SectionHeaderCount(); |
359 ++section_id) { | 337 ++section_id) { |
360 const Elf32_Shdr* section_header = SectionHeader(section_id); | 338 const Elf32_Shdr* section_header = SectionHeader(section_id); |
361 | 339 |
362 // Some debug sections can have sh_type=SHT_PROGBITS but sh_addr=0. | 340 // Some debug sections can have sh_type=SHT_PROGBITS but sh_addr=0. |
363 if (section_header->sh_type != SHT_PROGBITS || section_header->sh_addr == 0) | 341 if (section_header->sh_type != SHT_PROGBITS || section_header->sh_addr == 0) |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 } else { | 382 } else { |
405 // Else squeeze nullptr to end to compactify. | 383 // Else squeeze nullptr to end to compactify. |
406 if (tail_it != head_it) | 384 if (tail_it != head_it) |
407 (*tail_it).swap(*head_it); | 385 (*tail_it).swap(*head_it); |
408 ++tail_it; | 386 ++tail_it; |
409 } | 387 } |
410 } | 388 } |
411 rel32_locations_.resize(std::distance(rel32_locations_.begin(), tail_it)); | 389 rel32_locations_.resize(std::distance(rel32_locations_.begin(), tail_it)); |
412 } | 390 } |
413 | 391 |
| 392 InstructionGenerator DisassemblerElf32::GetInstructionGenerator( |
| 393 AssemblyProgram* program) { |
| 394 return base::Bind(&DisassemblerElf32::ParseFile, base::Unretained(this), |
| 395 program); |
| 396 } |
| 397 |
414 CheckBool DisassemblerElf32::ParseFile(AssemblyProgram* program, | 398 CheckBool DisassemblerElf32::ParseFile(AssemblyProgram* program, |
415 InstructionReceptor* receptor) const { | 399 InstructionReceptor* receptor) const { |
416 // Walk all the bytes in the file, whether or not in a section. | 400 // Walk all the bytes in the file, whether or not in a section. |
417 FileOffset file_offset = 0; | 401 FileOffset file_offset = 0; |
418 | 402 |
419 // File parsing follows file offset order, and we visit abs32 and rel32 | 403 // File parsing follows file offset order, and we visit abs32 and rel32 |
420 // locations in lockstep. Therefore we need to extract and sort file offsets | 404 // locations in lockstep. Therefore we need to extract and sort file offsets |
421 // of all abs32 and rel32 locations. For abs32, we copy the offsets to a new | 405 // of all abs32 and rel32 locations. For abs32, we copy the offsets to a new |
422 // array. | 406 // array. |
423 std::vector<FileOffset> abs_offsets; | 407 std::vector<FileOffset> abs_offsets; |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
626 case SHT_PROGBITS: | 610 case SHT_PROGBITS: |
627 return true; | 611 return true; |
628 } | 612 } |
629 } | 613 } |
630 } | 614 } |
631 | 615 |
632 return false; | 616 return false; |
633 } | 617 } |
634 | 618 |
635 } // namespace courgette | 619 } // namespace courgette |
OLD | NEW |