aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/dwarf/dwarf2reader.cc13
-rw-r--r--src/common/dwarf/dwarf2reader.h6
-rw-r--r--src/common/dwarf_cu_to_module.cc15
-rw-r--r--src/common/dwarf_cu_to_module.h25
-rw-r--r--src/common/linux/dump_symbols.cc24
-rw-r--r--src/common/mac/dump_syms.cc24
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.