diff options
author | tommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-06 17:42:45 +0000 |
---|---|---|
committer | tommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-06 17:42:45 +0000 |
commit | 43a9e24a52fa867db98fc2195b8db85b4729e7a1 (patch) | |
tree | cad7a14c415542083ac3d1ecc2df1fd86f789557 /courgette/disassembler.cc | |
parent | 6768ac0b06ae36ec7b2d27adfb9b64fc17f57cee (diff) | |
download | chromium_src-43a9e24a52fa867db98fc2195b8db85b4729e7a1.zip chromium_src-43a9e24a52fa867db98fc2195b8db85b4729e7a1.tar.gz chromium_src-43a9e24a52fa867db98fc2195b8db85b4729e7a1.tar.bz2 |
Switch out use of std::string and std::vector for large allocations for a buffer class that doesn't throw exceptions.
The new buffer class is pretty simple and relies on the MemoryAllocator class that I previously to back large
allocations with mapped files when memory is scarce. That reduced the number of crashes quite a bit but we
still crash on machines that are simply out of diskspace as well. So, the right thing to do is to expect and
handle failures which is what this cl is all about. What we should see once this has landed is that crash
dumps due to courgette running out of disk space should disappear from crash/ and instead we should see the
number of users that run into this particular problem in dashboards.
TEST=Courgette out-of-memory/out-of-diskspace errors should disappear from crash/
BUG=74777
Review URL: http://codereview.chromium.org/6677141
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@80648 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'courgette/disassembler.cc')
-rw-r--r-- | courgette/disassembler.cc | 68 |
1 files changed, 42 insertions, 26 deletions
diff --git a/courgette/disassembler.cc b/courgette/disassembler.cc index 2b4db2c..e3dd71a 100644 --- a/courgette/disassembler.cc +++ b/courgette/disassembler.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -36,17 +36,16 @@ class DisassemblerWin32X86 : public Disassembler { protected: PEInfo& pe_info() { return *pe_info_; } - void ParseFile(AssemblyProgram* target); + CheckBool ParseFile(AssemblyProgram* target) WARN_UNUSED_RESULT; bool ParseAbs32Relocs(); void ParseRel32RelocsFromSections(); void ParseRel32RelocsFromSection(const Section* section); - void ParseNonSectionFileRegion(uint32 start_file_offset, - uint32 end_file_offset, - AssemblyProgram* program); - void ParseFileRegion(const Section* section, - uint32 start_file_offset, uint32 end_file_offset, - AssemblyProgram* program); + CheckBool ParseNonSectionFileRegion(uint32 start_file_offset, + uint32 end_file_offset, AssemblyProgram* program) WARN_UNUSED_RESULT; + CheckBool ParseFileRegion(const Section* section, + uint32 start_file_offset, uint32 end_file_offset, + AssemblyProgram* program) WARN_UNUSED_RESULT; #if COURGETTE_HISTOGRAM_TARGETS void HistogramTargets(const char* kind, const std::map<RVA, int>& map); @@ -75,9 +74,11 @@ bool DisassemblerWin32X86::Disassemble(AssemblyProgram* target) { ParseRel32RelocsFromSections(); - ParseFile(target); + if (!ParseFile(target)) + return false; target->DefaultAssignIndexes(); + return true; } @@ -228,10 +229,11 @@ void DisassemblerWin32X86::ParseRel32RelocsFromSection(const Section* section) { } } -void DisassemblerWin32X86::ParseFile(AssemblyProgram* program) { +CheckBool DisassemblerWin32X86::ParseFile(AssemblyProgram* program) { + bool ok = true; // Walk all the bytes in the file, whether or not in a section. uint32 file_offset = 0; - while (file_offset < pe_info().length()) { + while (ok && file_offset < pe_info().length()) { const Section* section = pe_info().FindNextSection(file_offset); if (section == NULL) { // No more sections. There should not be extra stuff following last @@ -241,39 +243,47 @@ void DisassemblerWin32X86::ParseFile(AssemblyProgram* program) { } if (file_offset < section->file_offset_of_raw_data) { uint32 section_start_offset = section->file_offset_of_raw_data; - ParseNonSectionFileRegion(file_offset, section_start_offset, program); + ok = ParseNonSectionFileRegion(file_offset, section_start_offset, + program); file_offset = section_start_offset; } - uint32 end = file_offset + section->size_of_raw_data; - ParseFileRegion(section, file_offset, end, program); - file_offset = end; + if (ok) { + uint32 end = file_offset + section->size_of_raw_data; + ok = ParseFileRegion(section, file_offset, end, program); + file_offset = end; + } } #if COURGETTE_HISTOGRAM_TARGETS HistogramTargets("abs32 relocs", abs32_target_rvas_); HistogramTargets("rel32 relocs", rel32_target_rvas_); #endif + + return ok; } -void DisassemblerWin32X86::ParseNonSectionFileRegion( +CheckBool DisassemblerWin32X86::ParseNonSectionFileRegion( uint32 start_file_offset, uint32 end_file_offset, AssemblyProgram* program) { if (incomplete_disassembly_) - return; + return true; const uint8* start = pe_info().FileOffsetToPointer(start_file_offset); const uint8* end = pe_info().FileOffsetToPointer(end_file_offset); const uint8* p = start; - while (p < end) { - program->EmitByteInstruction(*p); + bool ok = true; + while (p < end && ok) { + ok = program->EmitByteInstruction(*p); ++p; } + + return ok; } -void DisassemblerWin32X86::ParseFileRegion( +CheckBool DisassemblerWin32X86::ParseFileRegion( const Section* section, uint32 start_file_offset, uint32 end_file_offset, AssemblyProgram* program) { @@ -292,18 +302,20 @@ void DisassemblerWin32X86::ParseFileRegion( std::vector<RVA>::iterator rel32_pos = rel32_locations_.begin(); std::vector<RVA>::iterator abs32_pos = abs32_locations_.begin(); - program->EmitOriginInstruction(start_rva); + bool ok = program->EmitOriginInstruction(start_rva); const uint8* p = start_pointer; - while (p < end_pointer) { + while (ok && p < end_pointer) { RVA current_rva = static_cast<RVA>(p - adjust_pointer_to_rva); // The base relocation table is usually in the .relocs section, but it could // actually be anywhere. Make sure we skip it because we will regenerate it // during assembly. if (current_rva == relocs_start_rva) { - program->EmitMakeRelocsInstruction(); + ok = program->EmitMakeRelocsInstruction(); + if (!ok) + break; uint32 relocs_size = pe_info().base_relocation_table().size_; if (relocs_size) { p += relocs_size; @@ -319,7 +331,9 @@ void DisassemblerWin32X86::ParseFileRegion( RVA target_rva = target_address - pe_info().image_base(); // TODO(sra): target could be Label+offset. It is not clear how to guess // which it might be. We assume offset==0. - program->EmitAbs32(program->FindOrMakeAbs32Label(target_rva)); + ok = program->EmitAbs32(program->FindOrMakeAbs32Label(target_rva)); + if (!ok) + break; p += 4; continue; } @@ -329,7 +343,7 @@ void DisassemblerWin32X86::ParseFileRegion( if (rel32_pos != rel32_locations_.end() && *rel32_pos == current_rva) { RVA target_rva = current_rva + 4 + Read32LittleEndian(p); - program->EmitRel32(program->FindOrMakeRel32Label(target_rva)); + ok = program->EmitRel32(program->FindOrMakeRel32Label(target_rva)); p += 4; continue; } @@ -343,9 +357,11 @@ void DisassemblerWin32X86::ParseFileRegion( } } - program->EmitByteInstruction(*p); + ok = program->EmitByteInstruction(*p); p += 1; } + + return ok; } #if COURGETTE_HISTOGRAM_TARGETS |