aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/dwarf/bytereader-inl.h11
-rw-r--r--src/common/dwarf/bytereader.h5
-rw-r--r--src/common/dwarf/dwarf2enums.h6
-rw-r--r--src/common/dwarf/dwarf2reader.cc35
-rw-r--r--src/common/dwarf/dwarf2reader.h12
-rw-r--r--src/common/dwarf_cu_to_module.cc7
6 files changed, 66 insertions, 10 deletions
diff --git a/src/common/dwarf/bytereader-inl.h b/src/common/dwarf/bytereader-inl.h
index f4c068a2..235d75ee 100644
--- a/src/common/dwarf/bytereader-inl.h
+++ b/src/common/dwarf/bytereader-inl.h
@@ -50,6 +50,17 @@ inline uint16_t ByteReader::ReadTwoBytes(const uint8_t *buffer) const {
}
}
+inline uint64_t ByteReader::ReadThreeBytes(const uint8_t* buffer) const {
+ const uint32_t buffer0 = buffer[0];
+ const uint32_t buffer1 = buffer[1];
+ const uint32_t buffer2 = buffer[2];
+ if (endian_ == ENDIANNESS_LITTLE) {
+ return buffer0 | buffer1 << 8 | buffer2 << 16;
+ } else {
+ return buffer2 | buffer1 << 8 | buffer0 << 16;
+ }
+}
+
inline uint64_t ByteReader::ReadFourBytes(const uint8_t *buffer) const {
const uint32_t buffer0 = buffer[0];
const uint32_t buffer1 = buffer[1];
diff --git a/src/common/dwarf/bytereader.h b/src/common/dwarf/bytereader.h
index 2b37a12d..d0c3b964 100644
--- a/src/common/dwarf/bytereader.h
+++ b/src/common/dwarf/bytereader.h
@@ -68,6 +68,11 @@ class ByteReader {
// number, using this ByteReader's endianness.
uint16_t ReadTwoBytes(const uint8_t *buffer) const;
+ // Read three bytes from BUFFER and return them as an unsigned 64 bit
+ // number, using this ByteReader's endianness. DWARF 5 uses this encoding
+ // for various index-related DW_FORMs.
+ uint64_t ReadThreeBytes(const uint8_t* buffer) const;
+
// Read four bytes from BUFFER and return them as an unsigned 32 bit
// number, using this ByteReader's endianness. This function returns
// a uint64_t so that it is compatible with ReadAddress and
diff --git a/src/common/dwarf/dwarf2enums.h b/src/common/dwarf/dwarf2enums.h
index f5ccce94..bed70327 100644
--- a/src/common/dwarf/dwarf2enums.h
+++ b/src/common/dwarf/dwarf2enums.h
@@ -164,6 +164,12 @@ enum DwarfForm {
DW_FORM_strx3 = 0x27,
DW_FORM_strx4 = 0x28,
+ DW_FORM_addrx = 0x1b,
+ DW_FORM_addrx1 = 0x29,
+ DW_FORM_addrx2 = 0x2a,
+ DW_FORM_addrx3 = 0x2b,
+ DW_FORM_addrx4 = 0x2c,
+
// Extensions for Fission. See http://gcc.gnu.org/wiki/DebugFission.
DW_FORM_GNU_addr_index = 0x1f01,
DW_FORM_GNU_str_index = 0x1f02
diff --git a/src/common/dwarf/dwarf2reader.cc b/src/common/dwarf/dwarf2reader.cc
index 4f0c31dd..fbfff275 100644
--- a/src/common/dwarf/dwarf2reader.cc
+++ b/src/common/dwarf/dwarf2reader.cc
@@ -182,17 +182,21 @@ const uint8_t *CompilationUnit::SkipAttribute(const uint8_t *start,
case DW_FORM_flag_present:
return start;
+ case DW_FORM_addrx1:
case DW_FORM_data1:
case DW_FORM_flag:
case DW_FORM_ref1:
case DW_FORM_strx1:
return start + 1;
+ case DW_FORM_addrx2:
case DW_FORM_ref2:
case DW_FORM_data2:
case DW_FORM_strx2:
return start + 2;
+ case DW_FORM_addrx3:
case DW_FORM_strx3:
return start + 3;
+ case DW_FORM_addrx4:
case DW_FORM_ref4:
case DW_FORM_data4:
case DW_FORM_strx4:
@@ -208,6 +212,7 @@ const uint8_t *CompilationUnit::SkipAttribute(const uint8_t *start,
case DW_FORM_strx:
case DW_FORM_GNU_str_index:
case DW_FORM_GNU_addr_index:
+ case DW_FORM_addrx:
reader_->ReadUnsignedLEB128(start, &len);
return start + len;
@@ -549,8 +554,7 @@ const uint8_t *CompilationUnit::ProcessAttribute(
return start + 2;
}
case DW_FORM_strx3: {
- uint64_t str_index = reader_->ReadTwoBytes(start);
- str_index *= reader_->ReadOneByte(start + 2);
+ uint64_t str_index = reader_->ReadThreeBytes(start);
ProcessFormStringIndex(dieoffset, attr, form, str_index);
return start + 3;
}
@@ -560,14 +564,27 @@ const uint8_t *CompilationUnit::ProcessAttribute(
return start + 4;
}
- case DW_FORM_GNU_addr_index: {
- uint64_t addr_index = reader_->ReadUnsignedLEB128(start, &len);
- const uint8_t* addr_ptr =
- addr_buffer_ + addr_base_ + addr_index * reader_->AddressSize();
- ProcessAttributeUnsigned(dieoffset, attr, form,
- reader_->ReadAddress(addr_ptr));
+ case DW_FORM_addrx:
+ case DW_FORM_GNU_addr_index:
+ ProcessAttributeAddrIndex(
+ dieoffset, attr, form, reader_->ReadUnsignedLEB128(start, &len));
return start + len;
- }
+ case DW_FORM_addrx1:
+ ProcessAttributeAddrIndex(
+ dieoffset, attr, form, reader_->ReadOneByte(start));
+ return start + 1;
+ case DW_FORM_addrx2:
+ ProcessAttributeAddrIndex(
+ dieoffset, attr, form, reader_->ReadTwoBytes(start));
+ return start + 2;
+ case DW_FORM_addrx3:
+ ProcessAttributeAddrIndex(
+ dieoffset, attr, form, reader_->ReadThreeBytes(start));
+ return start + 3;
+ case DW_FORM_addrx4:
+ ProcessAttributeAddrIndex(
+ dieoffset, attr, form, reader_->ReadFourBytes(start));
+ return start + 4;
}
fprintf(stderr, "Unhandled form type\n");
return NULL;
diff --git a/src/common/dwarf/dwarf2reader.h b/src/common/dwarf/dwarf2reader.h
index 51d92285..593f5c0c 100644
--- a/src/common/dwarf/dwarf2reader.h
+++ b/src/common/dwarf/dwarf2reader.h
@@ -499,6 +499,18 @@ class CompilationUnit {
handler_->ProcessAttributeString(offset, attr, form, data);
}
+ // Called to handle common portions of DW_FORM_addrx and variations, as well
+ // as DW_FORM_GNU_addr_index.
+ void ProcessAttributeAddrIndex(uint64_t offset,
+ enum DwarfAttribute attr,
+ enum DwarfForm form,
+ uint64_t addr_index) {
+ const uint8_t* addr_ptr =
+ addr_buffer_ + addr_base_ + addr_index * reader_->AddressSize();
+ ProcessAttributeUnsigned(
+ offset, attr, form, reader_->ReadAddress(addr_ptr));
+ }
+
// Processes all DIEs for this compilation unit
void ProcessDIEs();
diff --git a/src/common/dwarf_cu_to_module.cc b/src/common/dwarf_cu_to_module.cc
index d6e79769..24bbf83b 100644
--- a/src/common/dwarf_cu_to_module.cc
+++ b/src/common/dwarf_cu_to_module.cc
@@ -593,7 +593,12 @@ void DwarfCUToModule::FuncHandler::Finish() {
if (!ranges_) {
// Make high_pc_ an address, if it isn't already.
if (high_pc_form_ != dwarf2reader::DW_FORM_addr &&
- high_pc_form_ != dwarf2reader::DW_FORM_GNU_addr_index) {
+ high_pc_form_ != dwarf2reader::DW_FORM_GNU_addr_index &&
+ high_pc_form_ != dwarf2reader::DW_FORM_addrx &&
+ high_pc_form_ != dwarf2reader::DW_FORM_addrx1 &&
+ high_pc_form_ != dwarf2reader::DW_FORM_addrx2 &&
+ high_pc_form_ != dwarf2reader::DW_FORM_addrx3 &&
+ high_pc_form_ != dwarf2reader::DW_FORM_addrx4) {
high_pc_ += low_pc_;
}