mirror of
https://git.suyu.dev/suyu/breakpad.git
synced 2026-02-19 00:39:38 +00:00
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>
This commit is contained in:
committed by
Ted Mielczarek
parent
7b98edabb6
commit
16e08520e6
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -58,6 +58,8 @@ struct FunctionInfo {
|
||||
uint64 lowpc;
|
||||
// End address for this function.
|
||||
uint64 highpc;
|
||||
// Ranges offset
|
||||
uint64 ranges;
|
||||
};
|
||||
|
||||
struct SourceFileInfo {
|
||||
|
||||
Reference in New Issue
Block a user