| 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 |