From 16e08520e6027df4bf1934abbfd5e1a088ffb69c Mon Sep 17 00:00:00 2001 From: Gabriele Svelto Date: Sat, 4 Aug 2018 00:59:34 +0200 Subject: Add support for parsing the DW_AT_ranges attributes This enables the DWARF reader to properly parse DW_AT_ranges attributes in compilation units and functions. Code covered by a function is now represented by a vector of ranges instead of a single contiguous range and DW_AT_ranges entries are used to populate it. All the code and tests that assumed functions to be contiguous entities has been updated to reflect the change. DW_AT_ranges attributes found in compilation units are parsed but no data is generated for them as it is not currently needed. BUG=754 Change-Id: I310391b525aaba0dd329f1e3187486f2e0c6d442 Reviewed-on: https://chromium-review.googlesource.com/1124721 Reviewed-by: Ted Mielczarek --- src/common/linux/dump_symbols.cc | 41 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'src/common/linux/dump_symbols.cc') diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc index e7a74ccb..1110cb9d 100644 --- a/src/common/linux/dump_symbols.cc +++ b/src/common/linux/dump_symbols.cc @@ -58,6 +58,7 @@ #include "common/dwarf_cfi_to_module.h" #include "common/dwarf_cu_to_module.h" #include "common/dwarf_line_to_module.h" +#include "common/dwarf_range_list_handler.h" #include "common/linux/crc32.h" #include "common/linux/eintr_wrapper.h" #include "common/linux/elfutils.h" @@ -81,6 +82,7 @@ using google_breakpad::DumpOptions; using google_breakpad::DwarfCFIToModule; using google_breakpad::DwarfCUToModule; using google_breakpad::DwarfLineToModule; +using google_breakpad::DwarfRangeListHandler; using google_breakpad::ElfClass; using google_breakpad::ElfClass32; using google_breakpad::ElfClass64; @@ -207,6 +209,30 @@ bool LoadStabs(const typename ElfClass::Ehdr* elf_header, } #endif // NO_STABS_SUPPORT +// A range handler that accepts rangelist data parsed by +// dwarf2reader::RangeListReader and populates a range vector (typically +// owned by a function) with the results. +class DumperRangesHandler : public DwarfCUToModule::RangesHandler { + public: + DumperRangesHandler(const uint8_t *buffer, uint64 size, + dwarf2reader::ByteReader* reader) + : buffer_(buffer), size_(size), reader_(reader) { } + + bool ReadRanges(uint64 offset, Module::Address base_address, + vector* ranges) { + DwarfRangeListHandler handler(base_address, ranges); + dwarf2reader::RangeListReader rangelist_reader(buffer_, size_, reader_, + &handler); + + return rangelist_reader.ReadRangeList(offset); + } + + private: + const uint8_t *buffer_; + uint64 size_; + dwarf2reader::ByteReader* reader_; +}; + // A line-to-module loader that accepts line number info parsed by // dwarf2reader::LineInfo and populates a Module and a line vector // with the results. @@ -261,6 +287,18 @@ bool LoadDwarf(const string& dwarf_filename, file_context.AddSectionToSectionMap(name, contents, section->sh_size); } + // Optional .debug_ranges reader + scoped_ptr 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& ranges_section = + ranges_entry->second; + ranges_handler.reset( + new DumperRangesHandler(ranges_section.first, ranges_section.second, + &byte_reader)); + } + // Parse all the compilation units in the .debug_info section. DumperLineToModule line_to_module(&byte_reader); dwarf2reader::SectionMap::const_iterator debug_info_entry = @@ -276,7 +314,8 @@ bool LoadDwarf(const string& dwarf_filename, // Make a handler for the root DIE that populates MODULE with the // data that was found. DwarfCUToModule::WarningReporter reporter(dwarf_filename, offset); - DwarfCUToModule root_handler(&file_context, &line_to_module, &reporter); + DwarfCUToModule root_handler(&file_context, &line_to_module, + 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. -- cgit v1.2.1