Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(478)

Side by Side Diff: courgette/disassembler_elf_32.cc

Issue 2771753004: [Courgette] Refactor: Unify Disassembler::Disassemble() and instantiate AssemblyProgram there. (Closed)
Patch Set: Fix signed/unsigned comparison issue in test. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « courgette/disassembler_elf_32.h ('k') | courgette/disassembler_elf_32_arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « courgette/disassembler_elf_32.h ('k') | courgette/disassembler_elf_32_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698