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,
|
RangeListReader::RangeListReader(const uint8_t* buffer, uint64_t size,
|
||||||
ByteReader* reader)
|
ByteReader* reader, RangeListHandler* handler)
|
||||||
: buffer_(buffer), size_(size), reader_(reader) { }
|
: buffer_(buffer), size_(size), reader_(reader), handler_(handler) { }
|
||||||
|
|
||||||
bool RangeListReader::ReadRangeList(uint64_t offset,
|
bool RangeListReader::ReadRangeList(uint64_t offset) {
|
||||||
RangeListHandler* handler) {
|
|
||||||
const uint64_t max_address =
|
const uint64_t max_address =
|
||||||
(reader_->AddressSize() == 4) ? 0xffffffffUL
|
(reader_->AddressSize() == 4) ? 0xffffffffUL
|
||||||
: 0xffffffffffffffffULL;
|
: 0xffffffffffffffffULL;
|
||||||
|
@ -1590,12 +1589,12 @@ bool RangeListReader::ReadRangeList(uint64_t offset,
|
||||||
reader_->ReadAddress(buffer_ + offset + reader_->AddressSize());
|
reader_->ReadAddress(buffer_ + offset + reader_->AddressSize());
|
||||||
|
|
||||||
if (start_address == max_address) { // Base address selection
|
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
|
} else if (start_address == 0 && end_address == 0) { // End-of-list
|
||||||
handler->Finish();
|
handler_->Finish();
|
||||||
list_end = true;
|
list_end = true;
|
||||||
} else { // Add a range entry
|
} else { // Add a range entry
|
||||||
handler->AddRange(start_address, end_address);
|
handler_->AddRange(start_address, end_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
offset += entry_size;
|
offset += entry_size;
|
||||||
|
|
|
@ -243,14 +243,16 @@ class RangeListHandler {
|
||||||
|
|
||||||
class RangeListReader {
|
class RangeListReader {
|
||||||
public:
|
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:
|
private:
|
||||||
const uint8_t* buffer_;
|
const uint8_t* buffer_;
|
||||||
uint64_t size_;
|
uint64_t size_;
|
||||||
ByteReader* reader_;
|
ByteReader* reader_;
|
||||||
|
RangeListHandler* handler_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// This class is the main interface between the reader and the
|
// This class is the main interface between the reader and the
|
||||||
|
|
|
@ -134,7 +134,6 @@ DwarfCUToModule::FileContext::FileContext(const string& filename,
|
||||||
: filename_(filename),
|
: filename_(filename),
|
||||||
module_(module),
|
module_(module),
|
||||||
handle_inter_cu_refs_(handle_inter_cu_refs),
|
handle_inter_cu_refs_(handle_inter_cu_refs),
|
||||||
range_list_reader_(nullptr, 0, nullptr),
|
|
||||||
file_private_(new FilePrivate()) {
|
file_private_(new FilePrivate()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +193,7 @@ struct DwarfCUToModule::CUContext {
|
||||||
// For printing error messages.
|
// For printing error messages.
|
||||||
WarningReporter* reporter;
|
WarningReporter* reporter;
|
||||||
|
|
||||||
// For handling ranges, however they may be specified.
|
// For reading ranges from the .debug_ranges section
|
||||||
RangesHandler* ranges_handler;
|
RangesHandler* ranges_handler;
|
||||||
|
|
||||||
// The source language of this compilation unit.
|
// The source language of this compilation unit.
|
||||||
|
@ -207,9 +206,6 @@ struct DwarfCUToModule::CUContext {
|
||||||
uint64_t high_pc;
|
uint64_t high_pc;
|
||||||
uint64_t ranges;
|
uint64_t ranges;
|
||||||
|
|
||||||
// For reading dwarf4 ranges.
|
|
||||||
scoped_ptr<dwarf2reader::RangeListReader> range_list_reader_;
|
|
||||||
|
|
||||||
// The functions defined in this compilation unit. We accumulate
|
// The functions defined in this compilation unit. We accumulate
|
||||||
// them here during parsing. Then, in DwarfCUToModule::Finish, we
|
// them here during parsing. Then, in DwarfCUToModule::Finish, we
|
||||||
// assign them lines and add them to file_context->module.
|
// assign them lines and add them to file_context->module.
|
||||||
|
@ -516,15 +512,6 @@ void DwarfCUToModule::FuncHandler::ProcessAttributeUnsigned(
|
||||||
break;
|
break;
|
||||||
case dwarf2reader::DW_AT_ranges:
|
case dwarf2reader::DW_AT_ranges:
|
||||||
ranges_ = data;
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -89,11 +89,6 @@ class DwarfCUToModule: public dwarf2reader::RootDIEHandler {
|
||||||
const uint8_t* contents,
|
const uint8_t* contents,
|
||||||
uint64_t length);
|
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.
|
// Clear the section map for testing.
|
||||||
void ClearSectionMapForTest();
|
void ClearSectionMapForTest();
|
||||||
|
|
||||||
|
@ -124,9 +119,6 @@ class DwarfCUToModule: public dwarf2reader::RootDIEHandler {
|
||||||
// True if we are handling references between compilation units.
|
// True if we are handling references between compilation units.
|
||||||
const bool handle_inter_cu_refs_;
|
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.
|
// Inter-compilation unit data used internally by the handlers.
|
||||||
scoped_ptr<FilePrivate> file_private_;
|
scoped_ptr<FilePrivate> file_private_;
|
||||||
};
|
};
|
||||||
|
@ -135,23 +127,16 @@ class DwarfCUToModule: public dwarf2reader::RootDIEHandler {
|
||||||
// DwarfCUToModule.
|
// DwarfCUToModule.
|
||||||
class RangesHandler {
|
class RangesHandler {
|
||||||
public:
|
public:
|
||||||
RangesHandler() : reader_(nullptr) { }
|
RangesHandler() { }
|
||||||
virtual ~RangesHandler() { }
|
virtual ~RangesHandler() { }
|
||||||
|
|
||||||
// Called when finishing a function to populate the function's ranges.
|
// Called when finishing a function to populate the function's ranges.
|
||||||
// base_address holds the base PC the range list values are offsets
|
// The ranges' entries are read starting from offset in the .debug_ranges
|
||||||
// off. Return false if the rangelist falls out of the relevant section.
|
// 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,
|
virtual bool ReadRanges(uint64_t offset, Module::Address base_address,
|
||||||
vector<Module::Range>* ranges) = 0;
|
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
|
// 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.
|
// owned by a function) with the results.
|
||||||
class DumperRangesHandler : public DwarfCUToModule::RangesHandler {
|
class DumperRangesHandler : public DwarfCUToModule::RangesHandler {
|
||||||
public:
|
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,
|
bool ReadRanges(uint64_t offset, Module::Address base_address,
|
||||||
vector<Module::Range>* ranges) {
|
vector<Module::Range>* ranges) {
|
||||||
DwarfRangeListHandler handler(base_address, 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
|
// 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
|
// Optional .debug_ranges reader
|
||||||
|
scoped_ptr<DumperRangesHandler> ranges_handler;
|
||||||
dwarf2reader::SectionMap::const_iterator ranges_entry =
|
dwarf2reader::SectionMap::const_iterator ranges_entry =
|
||||||
file_context.section_map().find(".debug_ranges");
|
file_context.section_map().find(".debug_ranges");
|
||||||
if (ranges_entry != file_context.section_map().end()) {
|
if (ranges_entry != file_context.section_map().end()) {
|
||||||
const std::pair<const uint8_t*, uint64_t>& ranges_section =
|
const std::pair<const uint8_t*, uint64_t>& ranges_section =
|
||||||
ranges_entry->second;
|
ranges_entry->second;
|
||||||
file_context.SetDebugRangeInfo(ranges_section.first,
|
ranges_handler.reset(
|
||||||
ranges_section.second,
|
new DumperRangesHandler(ranges_section.first, ranges_section.second,
|
||||||
&byte_reader);
|
&byte_reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
DumperRangesHandler ranges_handler;
|
|
||||||
|
|
||||||
// Parse all the compilation units in the .debug_info section.
|
// Parse all the compilation units in the .debug_info section.
|
||||||
DumperLineToModule line_to_module(&byte_reader);
|
DumperLineToModule line_to_module(&byte_reader);
|
||||||
dwarf2reader::SectionMap::const_iterator debug_info_entry =
|
dwarf2reader::SectionMap::const_iterator debug_info_entry =
|
||||||
|
@ -333,7 +341,7 @@ bool LoadDwarf(const string& dwarf_filename,
|
||||||
// data that was found.
|
// data that was found.
|
||||||
DwarfCUToModule::WarningReporter reporter(dwarf_filename, offset);
|
DwarfCUToModule::WarningReporter reporter(dwarf_filename, offset);
|
||||||
DwarfCUToModule root_handler(&file_context, &line_to_module,
|
DwarfCUToModule root_handler(&file_context, &line_to_module,
|
||||||
&ranges_handler, &reporter);
|
ranges_handler.get(), &reporter);
|
||||||
// Make a Dwarf2Handler that drives the DIEHandler.
|
// Make a Dwarf2Handler that drives the DIEHandler.
|
||||||
dwarf2reader::DIEDispatcher die_dispatcher(&root_handler);
|
dwarf2reader::DIEDispatcher die_dispatcher(&root_handler);
|
||||||
// Make a DWARF parser for the compilation unit at OFFSET.
|
// Make a DWARF parser for the compilation unit at OFFSET.
|
||||||
|
|
|
@ -311,14 +311,23 @@ string DumpSymbols::Identifier() {
|
||||||
class DumpSymbols::DumperRangesHandler:
|
class DumpSymbols::DumperRangesHandler:
|
||||||
public DwarfCUToModule::RangesHandler {
|
public DwarfCUToModule::RangesHandler {
|
||||||
public:
|
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,
|
bool ReadRanges(uint64_t offset, Module::Address base_address,
|
||||||
vector<Module::Range>* ranges) {
|
vector<Module::Range>* ranges) {
|
||||||
DwarfRangeListHandler handler(base_address, 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
|
// 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);
|
DumperLineToModule line_to_module(&byte_reader);
|
||||||
|
|
||||||
// Optional .debug_ranges reader
|
// Optional .debug_ranges reader
|
||||||
|
scoped_ptr<DumperRangesHandler> ranges_handler;
|
||||||
dwarf2reader::SectionMap::const_iterator ranges_entry =
|
dwarf2reader::SectionMap::const_iterator ranges_entry =
|
||||||
file_context.section_map().find("__debug_ranges");
|
file_context.section_map().find("__debug_ranges");
|
||||||
if (ranges_entry != file_context.section_map().end()) {
|
if (ranges_entry != file_context.section_map().end()) {
|
||||||
const std::pair<const uint8_t*, uint64_t>& ranges_section =
|
const std::pair<const uint8_t*, uint64_t>& ranges_section =
|
||||||
ranges_entry->second;
|
ranges_entry->second;
|
||||||
file_context.SetDebugRangeInfo(ranges_section.first,
|
ranges_handler.reset(
|
||||||
ranges_section.second,
|
new DumperRangesHandler(ranges_section.first, ranges_section.second,
|
||||||
&byte_reader);
|
&byte_reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
DumperRangesHandler ranges_handler;
|
|
||||||
|
|
||||||
// Walk the __debug_info section, one compilation unit at a time.
|
// Walk the __debug_info section, one compilation unit at a time.
|
||||||
uint64_t debug_info_length = debug_info_section.second;
|
uint64_t debug_info_length = debug_info_section.second;
|
||||||
for (uint64_t offset = 0; offset < debug_info_length;) {
|
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_,
|
DwarfCUToModule::WarningReporter reporter(selected_object_name_,
|
||||||
offset);
|
offset);
|
||||||
DwarfCUToModule root_handler(&file_context, &line_to_module,
|
DwarfCUToModule root_handler(&file_context, &line_to_module,
|
||||||
&ranges_handler, &reporter);
|
ranges_handler.get(), &reporter);
|
||||||
// Make a Dwarf2Handler that drives our DIEHandler.
|
// Make a Dwarf2Handler that drives our DIEHandler.
|
||||||
dwarf2reader::DIEDispatcher die_dispatcher(&root_handler);
|
dwarf2reader::DIEDispatcher die_dispatcher(&root_handler);
|
||||||
// Make a DWARF parser for the compilation unit at OFFSET.
|
// Make a DWARF parser for the compilation unit at OFFSET.
|
||||||
|
|
Loading…
Reference in a new issue