Revert "Refactor rangelist handling to prepare for dwarf5 .debug_rngslist"
This reverts commit 2b936b06c1
.
After getting deep into the dwarf5 range reader, I realized that this
should be done a somewhat different way. So reverting in favor or
a better design, coming in a few minutes.
Change-Id: Ie0b2846e70b3df1e637831e96ea69fe093f4e712
Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/2446011
Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
parent
2b936b06c1
commit
f6669d6df4
6 changed files with 48 additions and 59 deletions
|
@ -1569,11 +1569,10 @@ void LineInfo::ReadLines() {
|
|||
}
|
||||
|
||||
RangeListReader::RangeListReader(const uint8_t* buffer, uint64_t size,
|
||||
ByteReader* reader)
|
||||
: buffer_(buffer), size_(size), reader_(reader) { }
|
||||
ByteReader* reader, RangeListHandler* handler)
|
||||
: buffer_(buffer), size_(size), reader_(reader), handler_(handler) { }
|
||||
|
||||
bool RangeListReader::ReadRangeList(uint64_t offset,
|
||||
RangeListHandler* handler) {
|
||||
bool RangeListReader::ReadRangeList(uint64_t offset) {
|
||||
const uint64_t max_address =
|
||||
(reader_->AddressSize() == 4) ? 0xffffffffUL
|
||||
: 0xffffffffffffffffULL;
|
||||
|
@ -1590,12 +1589,12 @@ bool RangeListReader::ReadRangeList(uint64_t offset,
|
|||
reader_->ReadAddress(buffer_ + offset + reader_->AddressSize());
|
||||
|
||||
if (start_address == max_address) { // Base address selection
|
||||
handler->SetBaseAddress(end_address);
|
||||
handler_->SetBaseAddress(end_address);
|
||||
} else if (start_address == 0 && end_address == 0) { // End-of-list
|
||||
handler->Finish();
|
||||
handler_->Finish();
|
||||
list_end = true;
|
||||
} else { // Add a range entry
|
||||
handler->AddRange(start_address, end_address);
|
||||
handler_->AddRange(start_address, end_address);
|
||||
}
|
||||
|
||||
offset += entry_size;
|
||||
|
|
|
@ -243,14 +243,16 @@ class RangeListHandler {
|
|||
|
||||
class RangeListReader {
|
||||
public:
|
||||
RangeListReader(const uint8_t* buffer, uint64_t size, ByteReader* reader);
|
||||
RangeListReader(const uint8_t* buffer, uint64_t size, ByteReader* reader,
|
||||
RangeListHandler* handler);
|
||||
|
||||
bool ReadRangeList(uint64_t offset, RangeListHandler* handler);
|
||||
bool ReadRangeList(uint64_t offset);
|
||||
|
||||
private:
|
||||
const uint8_t* buffer_;
|
||||
uint64_t size_;
|
||||
ByteReader* reader_;
|
||||
RangeListHandler* handler_;
|
||||
};
|
||||
|
||||
// This class is the main interface between the reader and the
|
||||
|
|
|
@ -134,7 +134,6 @@ DwarfCUToModule::FileContext::FileContext(const string& filename,
|
|||
: filename_(filename),
|
||||
module_(module),
|
||||
handle_inter_cu_refs_(handle_inter_cu_refs),
|
||||
range_list_reader_(nullptr, 0, nullptr),
|
||||
file_private_(new FilePrivate()) {
|
||||
}
|
||||
|
||||
|
@ -194,7 +193,7 @@ struct DwarfCUToModule::CUContext {
|
|||
// For printing error messages.
|
||||
WarningReporter* reporter;
|
||||
|
||||
// For handling ranges, however they may be specified.
|
||||
// For reading ranges from the .debug_ranges section
|
||||
RangesHandler* ranges_handler;
|
||||
|
||||
// The source language of this compilation unit.
|
||||
|
@ -207,9 +206,6 @@ struct DwarfCUToModule::CUContext {
|
|||
uint64_t high_pc;
|
||||
uint64_t ranges;
|
||||
|
||||
// For reading dwarf4 ranges.
|
||||
scoped_ptr<dwarf2reader::RangeListReader> range_list_reader_;
|
||||
|
||||
// The functions defined in this compilation unit. We accumulate
|
||||
// them here during parsing. Then, in DwarfCUToModule::Finish, we
|
||||
// assign them lines and add them to file_context->module.
|
||||
|
@ -516,15 +512,6 @@ void DwarfCUToModule::FuncHandler::ProcessAttributeUnsigned(
|
|||
break;
|
||||
case dwarf2reader::DW_AT_ranges:
|
||||
ranges_ = data;
|
||||
if (cu_context_->ranges_handler) {
|
||||
cu_context_->ranges_handler->SetRangesReader(
|
||||
&cu_context_->file_context->range_list_reader_);
|
||||
} else {
|
||||
cu_context_->reporter->MissingRanges();
|
||||
// The rest of the code will fall back to low-pc, which is better than
|
||||
// nothing.
|
||||
ranges_ = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -89,11 +89,6 @@ class DwarfCUToModule: public dwarf2reader::RootDIEHandler {
|
|||
const uint8_t* contents,
|
||||
uint64_t length);
|
||||
|
||||
void SetDebugRangeInfo(const uint8_t* contents, uint64_t size,
|
||||
dwarf2reader::ByteReader* reader) {
|
||||
range_list_reader_ = dwarf2reader::RangeListReader(contents, size, reader);
|
||||
}
|
||||
|
||||
// Clear the section map for testing.
|
||||
void ClearSectionMapForTest();
|
||||
|
||||
|
@ -124,9 +119,6 @@ class DwarfCUToModule: public dwarf2reader::RootDIEHandler {
|
|||
// True if we are handling references between compilation units.
|
||||
const bool handle_inter_cu_refs_;
|
||||
|
||||
// Reader for .debug_ranges section, which is global to the file.
|
||||
dwarf2reader::RangeListReader range_list_reader_;
|
||||
|
||||
// Inter-compilation unit data used internally by the handlers.
|
||||
scoped_ptr<FilePrivate> file_private_;
|
||||
};
|
||||
|
@ -135,23 +127,16 @@ class DwarfCUToModule: public dwarf2reader::RootDIEHandler {
|
|||
// DwarfCUToModule.
|
||||
class RangesHandler {
|
||||
public:
|
||||
RangesHandler() : reader_(nullptr) { }
|
||||
RangesHandler() { }
|
||||
virtual ~RangesHandler() { }
|
||||
|
||||
// Called when finishing a function to populate the function's ranges.
|
||||
// base_address holds the base PC the range list values are offsets
|
||||
// off. Return false if the rangelist falls out of the relevant section.
|
||||
// The ranges' entries are read starting from offset in the .debug_ranges
|
||||
// section, base_address holds the base PC the range list values are
|
||||
// offsets off. Return false if the rangelist falls out of the
|
||||
// .debug_ranges section.
|
||||
virtual bool ReadRanges(uint64_t offset, Module::Address base_address,
|
||||
vector<Module::Range>* ranges) = 0;
|
||||
|
||||
// Read ranges from this buffer and interpret them according to attr. Called
|
||||
// upon seeing a DW_AT_ranges or DW_AT_rngslist attribute.
|
||||
void SetRangesReader(dwarf2reader::RangeListReader* reader) {
|
||||
reader_ = reader;
|
||||
}
|
||||
|
||||
protected:
|
||||
dwarf2reader::RangeListReader* reader_;
|
||||
};
|
||||
|
||||
// An abstract base class for handlers that handle DWARF line data
|
||||
|
|
|
@ -232,14 +232,23 @@ bool LoadStabs(const typename ElfClass::Ehdr* elf_header,
|
|||
// owned by a function) with the results.
|
||||
class DumperRangesHandler : public DwarfCUToModule::RangesHandler {
|
||||
public:
|
||||
DumperRangesHandler() { }
|
||||
DumperRangesHandler(const uint8_t* buffer, uint64_t size,
|
||||
dwarf2reader::ByteReader* reader)
|
||||
: buffer_(buffer), size_(size), reader_(reader) { }
|
||||
|
||||
bool ReadRanges(uint64_t offset, Module::Address base_address,
|
||||
vector<Module::Range>* ranges) {
|
||||
DwarfRangeListHandler handler(base_address, ranges);
|
||||
dwarf2reader::RangeListReader rangelist_reader(buffer_, size_, reader_,
|
||||
&handler);
|
||||
|
||||
return reader_->ReadRangeList(offset, &handler);
|
||||
return rangelist_reader.ReadRangeList(offset);
|
||||
}
|
||||
|
||||
private:
|
||||
const uint8_t* buffer_;
|
||||
uint64_t size_;
|
||||
dwarf2reader::ByteReader* reader_;
|
||||
};
|
||||
|
||||
// A line-to-module loader that accepts line number info parsed by
|
||||
|
@ -305,18 +314,17 @@ bool LoadDwarf(const string& dwarf_filename,
|
|||
}
|
||||
|
||||
// Optional .debug_ranges reader
|
||||
scoped_ptr<DumperRangesHandler> ranges_handler;
|
||||
dwarf2reader::SectionMap::const_iterator ranges_entry =
|
||||
file_context.section_map().find(".debug_ranges");
|
||||
if (ranges_entry != file_context.section_map().end()) {
|
||||
const std::pair<const uint8_t*, uint64_t>& ranges_section =
|
||||
ranges_entry->second;
|
||||
file_context.SetDebugRangeInfo(ranges_section.first,
|
||||
ranges_section.second,
|
||||
&byte_reader);
|
||||
ranges_handler.reset(
|
||||
new DumperRangesHandler(ranges_section.first, ranges_section.second,
|
||||
&byte_reader));
|
||||
}
|
||||
|
||||
DumperRangesHandler ranges_handler;
|
||||
|
||||
// Parse all the compilation units in the .debug_info section.
|
||||
DumperLineToModule line_to_module(&byte_reader);
|
||||
dwarf2reader::SectionMap::const_iterator debug_info_entry =
|
||||
|
@ -333,7 +341,7 @@ bool LoadDwarf(const string& dwarf_filename,
|
|||
// data that was found.
|
||||
DwarfCUToModule::WarningReporter reporter(dwarf_filename, offset);
|
||||
DwarfCUToModule root_handler(&file_context, &line_to_module,
|
||||
&ranges_handler, &reporter);
|
||||
ranges_handler.get(), &reporter);
|
||||
// Make a Dwarf2Handler that drives the DIEHandler.
|
||||
dwarf2reader::DIEDispatcher die_dispatcher(&root_handler);
|
||||
// Make a DWARF parser for the compilation unit at OFFSET.
|
||||
|
|
|
@ -311,14 +311,23 @@ string DumpSymbols::Identifier() {
|
|||
class DumpSymbols::DumperRangesHandler:
|
||||
public DwarfCUToModule::RangesHandler {
|
||||
public:
|
||||
DumperRangesHandler() { }
|
||||
DumperRangesHandler(const uint8_t* buffer, uint64_t size,
|
||||
dwarf2reader::ByteReader* reader)
|
||||
: buffer_(buffer), size_(size), reader_(reader) { }
|
||||
|
||||
bool ReadRanges(uint64_t offset, Module::Address base_address,
|
||||
vector<Module::Range>* ranges) {
|
||||
DwarfRangeListHandler handler(base_address, ranges);
|
||||
dwarf2reader::RangeListReader rangelist_reader(buffer_, size_, reader_,
|
||||
&handler);
|
||||
|
||||
return reader_->ReadRangeList(offset, &handler);
|
||||
return rangelist_reader.ReadRangeList(offset);
|
||||
}
|
||||
|
||||
private:
|
||||
const uint8_t* buffer_;
|
||||
uint64_t size_;
|
||||
dwarf2reader::ByteReader* reader_;
|
||||
};
|
||||
|
||||
// A line-to-module loader that accepts line number info parsed by
|
||||
|
@ -448,18 +457,17 @@ void DumpSymbols::ReadDwarf(google_breakpad::Module* module,
|
|||
DumperLineToModule line_to_module(&byte_reader);
|
||||
|
||||
// Optional .debug_ranges reader
|
||||
scoped_ptr<DumperRangesHandler> ranges_handler;
|
||||
dwarf2reader::SectionMap::const_iterator ranges_entry =
|
||||
file_context.section_map().find("__debug_ranges");
|
||||
if (ranges_entry != file_context.section_map().end()) {
|
||||
const std::pair<const uint8_t*, uint64_t>& ranges_section =
|
||||
ranges_entry->second;
|
||||
file_context.SetDebugRangeInfo(ranges_section.first,
|
||||
ranges_section.second,
|
||||
&byte_reader);
|
||||
ranges_handler.reset(
|
||||
new DumperRangesHandler(ranges_section.first, ranges_section.second,
|
||||
&byte_reader));
|
||||
}
|
||||
|
||||
DumperRangesHandler ranges_handler;
|
||||
|
||||
// Walk the __debug_info section, one compilation unit at a time.
|
||||
uint64_t debug_info_length = debug_info_section.second;
|
||||
for (uint64_t offset = 0; offset < debug_info_length;) {
|
||||
|
@ -468,7 +476,7 @@ void DumpSymbols::ReadDwarf(google_breakpad::Module* module,
|
|||
DwarfCUToModule::WarningReporter reporter(selected_object_name_,
|
||||
offset);
|
||||
DwarfCUToModule root_handler(&file_context, &line_to_module,
|
||||
&ranges_handler, &reporter);
|
||||
ranges_handler.get(), &reporter);
|
||||
// Make a Dwarf2Handler that drives our DIEHandler.
|
||||
dwarf2reader::DIEDispatcher die_dispatcher(&root_handler);
|
||||
// Make a DWARF parser for the compilation unit at OFFSET.
|
||||
|
|
Loading…
Reference in a new issue