--- /dev/null
+## Test that DWARF5 DW_FORM_addrx is correctly recognized
+## and converted into the DW_FORM_addr
+
+# RUN: yaml2obj %s -o %t.o
+
+# RUN: llvm-dwarfutil %t.o %t1
+# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s
+# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix DWARF-CHECK
+
+#CHECK: No errors.
+
+#DWARF-CHECK: DW_TAG_compile_unit
+#DWARF-CHECK: DW_AT_name [DW_FORM_strp] {{.*}} "CU1"
+#DWARF-CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000001130)
+#DWARF-CHECK: DW_AT_high_pc [DW_FORM_data8] (0x0000000000000030)
+#DWARF-CHECK: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000008)
+#DWARF-CHECK: DW_TAG_subprogram
+#DWARF-CHECK: DW_AT_name [DW_FORM_strp] {{.*}} "foo1"
+#DWARF-CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000001130)
+#DWARF-CHECK: DW_AT_high_pc [DW_FORM_data8] (0x0000000000000010)
+#DWARF-CHECK: DW_TAG_subprogram
+#DWARF-CHECK: DW_AT_name [DW_FORM_strp] {{.*}} "foo2"
+#DWARF-CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000001140)
+#DWARF-CHECK: DW_AT_high_pc [DW_FORM_data8] (0x0000000000000010)
+#DWARF-CHECK: DW_TAG_subprogram
+#DWARF-CHECK: DW_AT_name [DW_FORM_strp] {{.*}} "foo3"
+#DWARF-CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000001150)
+#DWARF-CHECK: DW_AT_high_pc [DW_FORM_data8] (0x0000000000000010)
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1130
+ Size: 0x30
+DWARF:
+ debug_abbrev:
+ - Table:
+ - Tag: DW_TAG_compile_unit
+ Children: DW_CHILDREN_yes
+ Attributes:
+ - Attribute: DW_AT_producer
+ Form: DW_FORM_string
+ - Attribute: DW_AT_language
+ Form: DW_FORM_data2
+ - Attribute: DW_AT_name
+ Form: DW_FORM_string
+ - Attribute: DW_AT_low_pc
+ Form: DW_FORM_addrx
+ - Attribute: DW_AT_high_pc
+ Form: DW_FORM_data8
+ - Attribute: DW_AT_addr_base
+ Form: DW_FORM_sec_offset
+ - Tag: DW_TAG_subprogram
+ Children: DW_CHILDREN_yes
+ Attributes:
+ - Attribute: DW_AT_name
+ Form: DW_FORM_string
+ - Attribute: DW_AT_low_pc
+ Form: DW_FORM_addrx
+ - Attribute: DW_AT_high_pc
+ Form: DW_FORM_data8
+ - Attribute: DW_AT_type
+ Form: DW_FORM_ref4
+ - Tag: DW_TAG_base_type
+ Children: DW_CHILDREN_no
+ Attributes:
+ - Attribute: DW_AT_name
+ Form: DW_FORM_string
+ debug_info:
+ - Version: 5
+ UnitType: DW_UT_compile
+ Entries:
+ - AbbrCode: 1
+ Values:
+ - CStr: by_hand
+ - Value: 0x04
+ - CStr: CU1
+ - Value: 0x0
+ - Value: 0x30
+ - Value: 0x8
+ - AbbrCode: 2
+ Values:
+ - CStr: foo1
+ - Value: 0x0
+ - Value: 0x10
+ - Value: 0x64
+ - AbbrCode: 0
+ - AbbrCode: 2
+ Values:
+ - CStr: foo2
+ - Value: 0x01
+ - Value: 0x10
+ - Value: 0x64
+ - AbbrCode: 0
+ - AbbrCode: 2
+ Values:
+ - CStr: foo3
+ - Value: 0x02
+ - Value: 0x10
+ - Value: 0x64
+ - AbbrCode: 0
+ - AbbrCode: 3
+ Values:
+ - CStr: int
+ - AbbrCode: 0
+ debug_addr:
+ - Version: 5
+ AddressSize: 0x08
+ Entries:
+ - Address: 0x1130
+ - Address: 0x1140
+ - Address: 0x1150
+...
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Endian.h"
#include <memory>
#include <vector>
public:
ObjFileAddressMap(DWARFContext &Context, const Options &Options,
object::ObjectFile &ObjFile)
- : Opts(Options) {
+ : Opts(Options), Context(Context) {
// Remember addresses of existing text sections.
for (const object::SectionRef &Sect : ObjFile.sections()) {
if (!Sect.isText())
void clear() override { DWARFAddressRanges.clear(); }
- llvm::Expected<uint64_t> relocateIndexedAddr(uint64_t, uint64_t) override {
- // should not be called.
- return object::createError("no relocations in linked binary");
+ llvm::Expected<uint64_t> relocateIndexedAddr(uint64_t StartOffset,
+ uint64_t EndOffset) override {
+ // No relocations in linked binary. Return just address value.
+
+ const char *AddrPtr =
+ Context.getDWARFObj().getAddrSection().Data.data() + StartOffset;
+ support::endianness Endianess =
+ Context.getDWARFObj().isLittleEndian() ? support::little : support::big;
+
+ assert(EndOffset > StartOffset);
+ switch (EndOffset - StartOffset) {
+ case 1:
+ return *AddrPtr;
+ case 2:
+ return support::endian::read16(AddrPtr, Endianess);
+ case 4:
+ return support::endian::read32(AddrPtr, Endianess);
+ case 8:
+ return support::endian::read64(AddrPtr, Endianess);
+ }
+
+ llvm_unreachable("relocateIndexedAddr unhandled case!");
}
protected:
RangesTy DWARFAddressRanges;
AddressRanges TextAddressRanges;
const Options &Opts;
+ DWARFContext &Context;
};
static bool knownByDWARFUtil(StringRef SecName) {