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:
Sterling Augustine 2020-10-02 07:44:24 -07:00
parent 2b936b06c1
commit f6669d6df4
6 changed files with 48 additions and 59 deletions

View file

@ -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;

View file

@ -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

View file

@ -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:

View file

@ -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

View file

@ -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.

View file

@ -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.