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/dwarf/dwarf2reader.cc | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'src/common/dwarf/dwarf2reader.cc') diff --git a/src/common/dwarf/dwarf2reader.cc b/src/common/dwarf/dwarf2reader.cc index f2dc4afe..27f3a83e 100644 --- a/src/common/dwarf/dwarf2reader.cc +++ b/src/common/dwarf/dwarf2reader.cc @@ -1247,6 +1247,41 @@ void LineInfo::ReadLines() { after_header_ = lengthstart + header_.total_length; } +RangeListReader::RangeListReader(const uint8_t *buffer, uint64 size, + ByteReader *reader, RangeListHandler *handler) + : buffer_(buffer), size_(size), reader_(reader), handler_(handler) { } + +bool RangeListReader::ReadRangeList(uint64 offset) { + const uint64 max_address = + (reader_->AddressSize() == 4) ? 0xffffffffUL + : 0xffffffffffffffffULL; + const uint64 entry_size = reader_->AddressSize() * 2; + bool list_end = false; + + do { + if (offset > size_ - entry_size) { + return false; // Invalid range detected + } + + uint64 start_address = reader_->ReadAddress(buffer_ + offset); + uint64 end_address = + reader_->ReadAddress(buffer_ + offset + reader_->AddressSize()); + + if (start_address == max_address) { // Base address selection + handler_->SetBaseAddress(end_address); + } else if (start_address == 0 && end_address == 0) { // End-of-list + handler_->Finish(); + list_end = true; + } else { // Add a range entry + handler_->AddRange(start_address, end_address); + } + + offset += entry_size; + } while (!list_end); + + return true; +} + // A DWARF rule for recovering the address or value of a register, or // computing the canonical frame address. There is one subclass of this for // each '*Rule' member function in CallFrameInfo::Handler. -- cgit v1.2.1