aboutsummaryrefslogtreecommitdiff
path: root/src/common/dwarf
diff options
context:
space:
mode:
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 {