aboutsummaryrefslogtreecommitdiff
path: root/src/common/dwarf
diff options
context:
space:
mode:
authorGabriele Svelto <gsvelto@mozilla.com>2018-08-04 00:59:34 +0200
committerTed Mielczarek <ted.mielczarek@gmail.com>2018-08-13 19:12:00 +0000
commit16e08520e6027df4bf1934abbfd5e1a088ffb69c (patch)
treee80f0e6a8b46b31a9dd56c12dddebb51e1895795 /src/common/dwarf
parentSet new ARM64 context flags (diff)
downloadbreakpad-16e08520e6027df4bf1934abbfd5e1a088ffb69c.tar.xz
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 <ted.mielczarek@gmail.com>
Diffstat (limited to 'src/common/dwarf')
-rw-r--r--src/common/dwarf/dwarf2reader.cc35
-rw-r--r--src/common/dwarf/dwarf2reader.h30
-rw-r--r--src/common/dwarf/functioninfo.cc3
-rw-r--r--src/common/dwarf/functioninfo.h2
4 files changed, 70 insertions, 0 deletions
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.
diff --git a/src/common/dwarf/dwarf2reader.h b/src/common/dwarf/dwarf2reader.h
index 5d2d7f60..cf3ba3cd 100644
--- a/src/common/dwarf/dwarf2reader.h
+++ b/src/common/dwarf/dwarf2reader.h
@@ -187,6 +187,36 @@ class LineInfoHandler {
uint32 file_num, uint32 line_num, uint32 column_num) { }
};
+class RangeListHandler {
+ public:
+ RangeListHandler() { }
+
+ virtual ~RangeListHandler() { }
+
+ // Add a range.
+ virtual void AddRange(uint64 begin, uint64 end) { };
+
+ // A new base address must be set for computing the ranges' addresses.
+ virtual void SetBaseAddress(uint64 base_address) { };
+
+ // Finish processing the range list.
+ virtual void Finish() { };
+};
+
+class RangeListReader {
+ public:
+ RangeListReader(const uint8_t *buffer, uint64 size, ByteReader *reader,
+ RangeListHandler *handler);
+
+ bool ReadRangeList(uint64 offset);
+
+ private:
+ const uint8_t *buffer_;
+ uint64 size_;
+ ByteReader* reader_;
+ RangeListHandler *handler_;
+};
+
// This class is the main interface between the reader and the
// client. The virtual functions inside this get called for
// interesting events that happen during DWARF2 reading.
diff --git a/src/common/dwarf/functioninfo.cc b/src/common/dwarf/functioninfo.cc
index 55a255ed..a0def62e 100644
--- a/src/common/dwarf/functioninfo.cc
+++ b/src/common/dwarf/functioninfo.cc
@@ -184,6 +184,9 @@ void CUFunctionInfoHandler::ProcessAttributeUnsigned(uint64 offset,
case DW_AT_decl_file:
current_function_info_->file = files_->at(data).name;
break;
+ case DW_AT_ranges:
+ current_function_info->ranges = data;
+ break;
default:
break;
}
diff --git a/src/common/dwarf/functioninfo.h b/src/common/dwarf/functioninfo.h
index 0b08a5fc..9efae6d4 100644
--- a/src/common/dwarf/functioninfo.h
+++ b/src/common/dwarf/functioninfo.h
@@ -58,6 +58,8 @@ struct FunctionInfo {
uint64 lowpc;
// End address for this function.
uint64 highpc;
+ // Ranges offset
+ uint64 ranges;
};
struct SourceFileInfo {