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

Side by Side Diff: courgette/disassembler_win32.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_win32.h ('k') | courgette/instruction_utils.h » ('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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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_win32.h" 5 #include "courgette/disassembler_win32.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 // Pretend our in-memory copy is only as long as our detected length. 214 // Pretend our in-memory copy is only as long as our detected length.
215 ReduceLength(detected_length); 215 ReduceLength(detected_length);
216 216
217 if (!has_text_section()) { 217 if (!has_text_section()) {
218 return Bad("Resource-only executables are not yet supported"); 218 return Bad("Resource-only executables are not yet supported");
219 } 219 }
220 220
221 return Good(); 221 return Good();
222 } 222 }
223 223
224 bool DisassemblerWin32::Disassemble(AssemblyProgram* program) {
225 if (!ok())
226 return false;
227
228 if (!ParseAbs32Relocs())
229 return false;
230
231 ParseRel32RelocsFromSections();
232
233 PrecomputeLabels(program);
234 RemoveUnusedRel32Locations(program);
235
236 if (!program->GenerateInstructions(
237 base::Bind(&DisassemblerWin32::ParseFile, base::Unretained(this)))) {
238 return false;
239 }
240
241 program->DefaultAssignIndexes();
242 return true;
243 }
244
245 //////////////////////////////////////////////////////////////////////////////// 224 ////////////////////////////////////////////////////////////////////////////////
246 225
247 bool DisassemblerWin32::ParseRelocs(std::vector<RVA>* relocs) { 226 bool DisassemblerWin32::ParseRelocs(std::vector<RVA>* relocs) {
248 relocs->clear(); 227 relocs->clear();
249 228
250 size_t relocs_size = base_relocation_table_.size_; 229 size_t relocs_size = base_relocation_table_.size_;
251 if (relocs_size == 0) 230 if (relocs_size == 0)
252 return true; 231 return true;
253 232
254 // The format of the base relocation table is a sequence of variable sized 233 // The format of the base relocation table is a sequence of variable sized
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 const uint8_t* optional_header = pe_header + 4 + kSizeOfCoffHeader; 337 const uint8_t* optional_header = pe_header + 4 + kSizeOfCoffHeader;
359 // Check we can read the magic. 338 // Check we can read the magic.
360 if (optional_header + 2 >= start + length) 339 if (optional_header + 2 >= start + length)
361 return false; 340 return false;
362 if (magic != ReadU16(optional_header, 0)) 341 if (magic != ReadU16(optional_header, 0))
363 return false; 342 return false;
364 343
365 return true; 344 return true;
366 } 345 }
367 346
368 bool DisassemblerWin32::ParseAbs32Relocs() { 347 bool DisassemblerWin32::ExtractAbs32Locations() {
369 abs32_locations_.clear(); 348 abs32_locations_.clear();
370 if (!ParseRelocs(&abs32_locations_)) 349 if (!ParseRelocs(&abs32_locations_))
371 return false; 350 return false;
372 351
373 #if COURGETTE_HISTOGRAM_TARGETS 352 #if COURGETTE_HISTOGRAM_TARGETS
374 for (size_t i = 0; i < abs32_locations_.size(); ++i) { 353 for (size_t i = 0; i < abs32_locations_.size(); ++i) {
375 RVA rva = abs32_locations_[i]; 354 RVA rva = abs32_locations_[i];
376 // The 4 bytes at the relocation are a reference to some address. 355 // The 4 bytes at the relocation are a reference to some address.
377 ++abs32_target_rvas_[PointerToTargetRVA(RVAToPointer(rva))]; 356 ++abs32_target_rvas_[PointerToTargetRVA(RVAToPointer(rva))];
378 } 357 }
379 #endif 358 #endif
380 return true; 359 return true;
381 } 360 }
382 361
383 void DisassemblerWin32::ParseRel32RelocsFromSections() { 362 bool DisassemblerWin32::ExtractRel32Locations() {
384 FileOffset file_offset = 0; 363 FileOffset file_offset = 0;
385 while (file_offset < length()) { 364 while (file_offset < length()) {
386 const Section* section = FindNextSection(file_offset); 365 const Section* section = FindNextSection(file_offset);
387 if (section == nullptr) 366 if (section == nullptr)
388 break; 367 break;
389 if (file_offset < section->file_offset_of_raw_data) 368 if (file_offset < section->file_offset_of_raw_data)
390 file_offset = section->file_offset_of_raw_data; 369 file_offset = section->file_offset_of_raw_data;
391 ParseRel32RelocsFromSection(section); 370 ParseRel32RelocsFromSection(section);
392 file_offset += section->size_of_raw_data; 371 file_offset += section->size_of_raw_data;
393 } 372 }
(...skipping 16 matching lines...) Expand all
410 } else if (rel32_iter->first < abs32_iter->first) { 389 } else if (rel32_iter->first < abs32_iter->first) {
411 ++rel32_iter; 390 ++rel32_iter;
412 } else { 391 } else {
413 ++common; 392 ++common;
414 ++abs32_iter; 393 ++abs32_iter;
415 ++rel32_iter; 394 ++rel32_iter;
416 } 395 }
417 } 396 }
418 VLOG(1) << "common " << common; 397 VLOG(1) << "common " << common;
419 #endif 398 #endif
399 return true;
420 } 400 }
421 401
422 RvaVisitor* DisassemblerWin32::CreateAbs32TargetRvaVisitor() { 402 RvaVisitor* DisassemblerWin32::CreateAbs32TargetRvaVisitor() {
423 return new RvaVisitor_Abs32(abs32_locations_, *this); 403 return new RvaVisitor_Abs32(abs32_locations_, *this);
424 } 404 }
425 405
426 RvaVisitor* DisassemblerWin32::CreateRel32TargetRvaVisitor() { 406 RvaVisitor* DisassemblerWin32::CreateRel32TargetRvaVisitor() {
427 return new RvaVisitor_Rel32(rel32_locations_, *this); 407 return new RvaVisitor_Rel32(rel32_locations_, *this);
428 } 408 }
429 409
430 void DisassemblerWin32::RemoveUnusedRel32Locations( 410 void DisassemblerWin32::RemoveUnusedRel32Locations(
431 AssemblyProgram* program) { 411 AssemblyProgram* program) {
432 auto cond = [this, program](RVA rva) -> bool { 412 auto cond = [this, program](RVA rva) -> bool {
433 // + 4 since offset is relative to start of next instruction. 413 // + 4 since offset is relative to start of next instruction.
434 RVA target_rva = rva + 4 + Read32LittleEndian(RVAToPointer(rva)); 414 RVA target_rva = rva + 4 + Read32LittleEndian(RVAToPointer(rva));
435 return program->FindRel32Label(target_rva) == nullptr; 415 return program->FindRel32Label(target_rva) == nullptr;
436 }; 416 };
437 rel32_locations_.erase( 417 rel32_locations_.erase(
438 std::remove_if(rel32_locations_.begin(), rel32_locations_.end(), cond), 418 std::remove_if(rel32_locations_.begin(), rel32_locations_.end(), cond),
439 rel32_locations_.end()); 419 rel32_locations_.end());
440 } 420 }
441 421
422 InstructionGenerator DisassemblerWin32::GetInstructionGenerator(
423 AssemblyProgram* program) {
424 return base::Bind(&DisassemblerWin32::ParseFile, base::Unretained(this),
425 program);
426 }
427
442 CheckBool DisassemblerWin32::ParseFile(AssemblyProgram* program, 428 CheckBool DisassemblerWin32::ParseFile(AssemblyProgram* program,
443 InstructionReceptor* receptor) const { 429 InstructionReceptor* receptor) const {
444 // Walk all the bytes in the file, whether or not in a section. 430 // Walk all the bytes in the file, whether or not in a section.
445 FileOffset file_offset = 0; 431 FileOffset file_offset = 0;
446 while (file_offset < length()) { 432 while (file_offset < length()) {
447 const Section* section = FindNextSection(file_offset); 433 const Section* section = FindNextSection(file_offset);
448 if (section == nullptr) { 434 if (section == nullptr) {
449 // No more sections. There should not be extra stuff following last 435 // No more sections. There should not be extra stuff following last
450 // section. 436 // section.
451 // ParseNonSectionFileRegion(file_offset, pe_info().length(), receptor); 437 // ParseNonSectionFileRegion(file_offset, pe_info().length(), receptor);
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 directory->size_ = static_cast<uint32_t>(size); 663 directory->size_ = static_cast<uint32_t>(size);
678 return true; 664 return true;
679 } else { 665 } else {
680 directory->address_ = 0; 666 directory->address_ = 0;
681 directory->size_ = 0; 667 directory->size_ = 0;
682 return true; 668 return true;
683 } 669 }
684 } 670 }
685 671
686 } // namespace courgette 672 } // namespace courgette
OLDNEW
« no previous file with comments | « courgette/disassembler_win32.h ('k') | courgette/instruction_utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698