diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/dwarf/dwarf2reader.cc | 13 | ||||
-rw-r--r-- | src/common/dwarf/dwarf2reader.h | 6 | ||||
-rw-r--r-- | src/common/dwarf_cu_to_module.cc | 15 | ||||
-rw-r--r-- | src/common/dwarf_cu_to_module.h | 25 | ||||
-rw-r--r-- | src/common/linux/dump_symbols.cc | 24 | ||||
-rw-r--r-- | src/common/mac/dump_syms.cc | 24 |
6 files changed, 59 insertions, 48 deletions
diff --git a/src/common/dwarf/dwarf2reader.cc b/src/common/dwarf/dwarf2reader.cc index aca83677..ab31a980 100644 --- a/src/common/dwarf/dwarf2reader.cc +++ b/src/common/dwarf/dwarf2reader.cc @@ -1569,10 +1569,11 @@ void LineInfo::ReadLines() { } RangeListReader::RangeListReader(const uint8_t* buffer, uint64_t size, - ByteReader* reader, RangeListHandler* handler) - : buffer_(buffer), size_(size), reader_(reader), handler_(handler) { } + ByteReader* reader) + : buffer_(buffer), size_(size), reader_(reader) { } -bool RangeListReader::ReadRangeList(uint64_t offset) { +bool RangeListReader::ReadRangeList(uint64_t offset, + RangeListHandler* handler) { const uint64_t max_address = (reader_->AddressSize() == 4) ? 0xffffffffUL : 0xffffffffffffffffULL; @@ -1589,12 +1590,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; diff --git a/src/common/dwarf/dwarf2reader.h b/src/common/dwarf/dwarf2reader.h index e405e3a7..aa9e270d 100644 --- a/src/common/dwarf/dwarf2reader.h +++ b/src/common/dwarf/dwarf2reader.h @@ -243,16 +243,14 @@ class RangeListHandler { class RangeListReader { public: - RangeListReader(const uint8_t* buffer, uint64_t size, ByteReader* reader, - RangeListHandler* handler); + RangeListReader(const uint8_t* buffer, uint64_t size, ByteReader* reader); - bool ReadRangeList(uint64_t offset); + bool ReadRangeList(uint64_t offset, RangeListHandler* handler); private: const uint8_t* buffer_; uint64_t size_; ByteReader* reader_; - RangeListHandler* handler_; }; // This class is the main interface between the reader and the diff --git a/src/common/dwarf_cu_to_module.cc b/src/common/dwarf_cu_to_module.cc index a5bc7d6c..589f8bb2 100644 --- a/src/common/dwarf_cu_to_module.cc +++ b/src/common/dwarf_cu_to_module.cc @@ -134,6 +134,7 @@ 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()) { } @@ -193,7 +194,7 @@ struct DwarfCUToModule::CUContext { // For printing error messages. WarningReporter* reporter; - // For reading ranges from the .debug_ranges section + // For handling ranges, however they may be specified. RangesHandler* ranges_handler; // The source language of this compilation unit. @@ -206,6 +207,9 @@ 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. @@ -512,6 +516,15 @@ 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: diff --git a/src/common/dwarf_cu_to_module.h b/src/common/dwarf_cu_to_module.h index 3e15b667..e71c3e77 100644 --- a/src/common/dwarf_cu_to_module.h +++ b/src/common/dwarf_cu_to_module.h @@ -89,6 +89,11 @@ 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(); @@ -119,6 +124,9 @@ 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_; }; @@ -127,16 +135,23 @@ class DwarfCUToModule: public dwarf2reader::RootDIEHandler { // DwarfCUToModule. class RangesHandler { public: - RangesHandler() { } + RangesHandler() : reader_(nullptr) { } virtual ~RangesHandler() { } // Called when finishing a function to populate the function's ranges. - // 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. + // base_address holds the base PC the range list values are offsets + // off. Return false if the rangelist falls out of the relevant 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 diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc index 8ecf0bc4..ac2559cd 100644 --- a/src/common/linux/dump_symbols.cc +++ b/src/common/linux/dump_symbols.cc @@ -232,23 +232,14 @@ bool LoadStabs(const typename ElfClass::Ehdr* elf_header, // owned by a function) with the results. class DumperRangesHandler : public DwarfCUToModule::RangesHandler { public: - DumperRangesHandler(const uint8_t* buffer, uint64_t size, - dwarf2reader::ByteReader* reader) - : buffer_(buffer), size_(size), reader_(reader) { } + DumperRangesHandler() { } 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 rangelist_reader.ReadRangeList(offset); + return reader_->ReadRangeList(offset, &handler); } - - private: - const uint8_t* buffer_; - uint64_t size_; - dwarf2reader::ByteReader* reader_; }; // A line-to-module loader that accepts line number info parsed by @@ -314,17 +305,18 @@ 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; - ranges_handler.reset( - new DumperRangesHandler(ranges_section.first, ranges_section.second, - &byte_reader)); + file_context.SetDebugRangeInfo(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 = @@ -341,7 +333,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.get(), &reporter); + &ranges_handler, &reporter); // Make a Dwarf2Handler that drives the DIEHandler. dwarf2reader::DIEDispatcher die_dispatcher(&root_handler); // Make a DWARF parser for the compilation unit at OFFSET. diff --git a/src/common/mac/dump_syms.cc b/src/common/mac/dump_syms.cc index 24bcd653..9ee6e006 100644 --- a/src/common/mac/dump_syms.cc +++ b/src/common/mac/dump_syms.cc @@ -311,23 +311,14 @@ string DumpSymbols::Identifier() { class DumpSymbols::DumperRangesHandler: public DwarfCUToModule::RangesHandler { public: - DumperRangesHandler(const uint8_t* buffer, uint64_t size, - dwarf2reader::ByteReader* reader) - : buffer_(buffer), size_(size), reader_(reader) { } + DumperRangesHandler() { } 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 rangelist_reader.ReadRangeList(offset); + return reader_->ReadRangeList(offset, &handler); } - - private: - const uint8_t* buffer_; - uint64_t size_; - dwarf2reader::ByteReader* reader_; }; // A line-to-module loader that accepts line number info parsed by @@ -457,17 +448,18 @@ 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; - ranges_handler.reset( - new DumperRangesHandler(ranges_section.first, ranges_section.second, - &byte_reader)); + file_context.SetDebugRangeInfo(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;) { @@ -476,7 +468,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.get(), &reporter); + &ranges_handler, &reporter); // Make a Dwarf2Handler that drives our DIEHandler. dwarf2reader::DIEDispatcher die_dispatcher(&root_handler); // Make a DWARF parser for the compilation unit at OFFSET. |