summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h4
-rw-r--r--llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h14
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp2
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp25
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp9
-rw-r--r--llvm/test/DebugInfo/Inputs/dwarfdump-ranges-baseaddr-exe.elf-x86-64bin0 -> 1128 bytes
-rw-r--r--llvm/test/DebugInfo/X86/dwarfdump-ranges-baseaddr-exe.s13
-rw-r--r--llvm/test/DebugInfo/X86/dwarfdump-ranges-baseaddr.s82
8 files changed, 133 insertions, 16 deletions
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
index bcba14b1630..421b6a4b561 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
@@ -18,6 +18,7 @@
namespace llvm {
+struct BaseAddress;
class raw_ostream;
struct DWARFAddressRange {
@@ -85,7 +86,8 @@ public:
/// getAbsoluteRanges - Returns absolute address ranges defined by this range
/// list. Has to be passed base address of the compile unit referencing this
/// range list.
- DWARFAddressRangesVector getAbsoluteRanges(uint64_t BaseAddress) const;
+ DWARFAddressRangesVector
+ getAbsoluteRanges(llvm::Optional<BaseAddress> BaseAddr) const;
};
} // end namespace llvm
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
index c39fc4c9744..6e85e71e5b3 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
@@ -110,6 +110,12 @@ private:
}
};
+/// Represents base address of the CU.
+struct BaseAddress {
+ uint64_t Address;
+ uint64_t SectionIndex;
+};
+
class DWARFUnit {
DWARFContext &Context;
/// Section containing this DWARFUnit.
@@ -135,7 +141,7 @@ class DWARFUnit {
uint32_t Length;
const DWARFAbbreviationDeclarationSet *Abbrevs;
uint8_t UnitType;
- uint64_t BaseAddr;
+ llvm::Optional<BaseAddress> BaseAddr;
/// The compile unit debug information entry items.
std::vector<DWARFDebugInfoEntry> DieArray;
@@ -259,11 +265,9 @@ public:
llvm_unreachable("Invalid UnitType.");
}
- uint64_t getBaseAddress() const { return BaseAddr; }
+ llvm::Optional<BaseAddress> getBaseAddress() const { return BaseAddr; }
- void setBaseAddress(uint64_t base_addr) {
- BaseAddr = base_addr;
- }
+ void setBaseAddress(BaseAddress BaseAddr) { this->BaseAddr = BaseAddr; }
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly = true) {
extractDIEsIfNeeded(ExtractUnitDIEOnly);
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
index a40635568cd..861dd313fb0 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
@@ -14,6 +14,8 @@ using namespace llvm;
uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint32_t *Off,
uint64_t *SecNdx) const {
+ if (SecNdx)
+ *SecNdx = -1ULL;
if (!Section)
return getUnsigned(Off, Size);
Optional<RelocAddrEntry> Rel = Obj->find(*Section, *Off);
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
index aa1f17934b5..62bd5af4e64 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
@@ -63,16 +63,29 @@ void DWARFDebugRangeList::dump(raw_ostream &OS) const {
OS << format("%08x <End of list>\n", Offset);
}
-DWARFAddressRangesVector
-DWARFDebugRangeList::getAbsoluteRanges(uint64_t BaseAddress) const {
+DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges(
+ llvm::Optional<BaseAddress> BaseAddr) const {
DWARFAddressRangesVector Res;
for (const RangeListEntry &RLE : Entries) {
if (RLE.isBaseAddressSelectionEntry(AddressSize)) {
- BaseAddress = RLE.EndAddress;
- } else {
- Res.push_back({BaseAddress + RLE.StartAddress,
- BaseAddress + RLE.EndAddress, RLE.SectionIndex});
+ BaseAddr = {RLE.EndAddress, RLE.SectionIndex};
+ continue;
}
+
+ DWARFAddressRange E;
+ E.LowPC = RLE.StartAddress;
+ E.HighPC = RLE.EndAddress;
+ E.SectionIndex = RLE.SectionIndex;
+ // Base address of a range list entry is determined by the closest preceding
+ // base address selection entry in the same range list. It defaults to the
+ // base address of the compilation unit if there is no such entry.
+ if (BaseAddr) {
+ E.LowPC += BaseAddr->Address;
+ E.HighPC += BaseAddr->Address;
+ if (E.SectionIndex == -1ULL)
+ E.SectionIndex = BaseAddr->SectionIndex;
+ }
+ Res.push_back(E);
}
return Res;
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index 5b0b3f65f6c..813960ca95d 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -160,7 +160,7 @@ void DWARFUnit::clear() {
Length = 0;
Abbrevs = nullptr;
FormParams = DWARFFormParams({0, 0, DWARF32});
- BaseAddr = 0;
+ BaseAddr.reset();
RangeSectionBase = 0;
AddrOffsetSectionBase = 0;
clearDIEs(false);
@@ -242,9 +242,10 @@ size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
// If CU DIE was just parsed, copy several attribute values from it.
if (!HasCUDie) {
DWARFDie UnitDie = getUnitDIE();
- auto BaseAddr = toAddress(UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc}));
- if (BaseAddr)
- setBaseAddress(*BaseAddr);
+ Optional<DWARFFormValue> PC = UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc});
+ if (Optional<uint64_t> Addr = toAddress(PC))
+ setBaseAddress({*Addr, PC->getSectionIndex()});
+
if (!isDWO) {
assert(AddrOffsetSectionBase == 0);
assert(RangeSectionBase == 0);
diff --git a/llvm/test/DebugInfo/Inputs/dwarfdump-ranges-baseaddr-exe.elf-x86-64 b/llvm/test/DebugInfo/Inputs/dwarfdump-ranges-baseaddr-exe.elf-x86-64
new file mode 100644
index 00000000000..ab9960bd30c
--- /dev/null
+++ b/llvm/test/DebugInfo/Inputs/dwarfdump-ranges-baseaddr-exe.elf-x86-64
Binary files differ
diff --git a/llvm/test/DebugInfo/X86/dwarfdump-ranges-baseaddr-exe.s b/llvm/test/DebugInfo/X86/dwarfdump-ranges-baseaddr-exe.s
new file mode 100644
index 00000000000..64f7009c8f5
--- /dev/null
+++ b/llvm/test/DebugInfo/X86/dwarfdump-ranges-baseaddr-exe.s
@@ -0,0 +1,13 @@
+# RUN: llvm-dwarfdump %S/../Inputs/dwarfdump-ranges-baseaddr-exe.elf-x86-64 \
+# RUN: | FileCheck %s
+
+## Executable binary for test produced from object built in
+## dwarfdump-ranges-baseaddr.s testcase.
+
+# CHECK: .debug_info contents:
+# CHECK: 0x0000000b: DW_TAG_compile_unit [1]
+# CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000400078)
+# CHECK-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000000
+# CHECK-NEXT: [0x0000000000400078 - 0x0000000000400079)
+# CHECK-NEXT: [0x000000000040007b - 0x000000000040007e)
+# CHECK-NEXT: [0x000000000040007f - 0x0000000000400080))
diff --git a/llvm/test/DebugInfo/X86/dwarfdump-ranges-baseaddr.s b/llvm/test/DebugInfo/X86/dwarfdump-ranges-baseaddr.s
new file mode 100644
index 00000000000..23776799e79
--- /dev/null
+++ b/llvm/test/DebugInfo/X86/dwarfdump-ranges-baseaddr.s
@@ -0,0 +1,82 @@
+# RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %s -o %t
+# RUN: llvm-dwarfdump %t | FileCheck %s
+
+# CHECK: .debug_info contents:
+# CHECK: 0x0000000b: DW_TAG_compile_unit [1]
+# CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
+# CHECK-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x00000000
+# CHECK-NEXT: [0x0000000000000000 - 0x0000000000000001) ".text"
+# CHECK-NEXT: [0x0000000000000003 - 0x0000000000000006) ".text"
+# CHECK-NEXT: [0x0000000000000001 - 0x0000000000000002) ".text.foo1")
+
+.text
+.globl foo
+.type foo,@function
+foo:
+.Lfunc_begin0:
+ nop
+.Ltmp0:
+ nop
+ nop
+.Ltmp1:
+ nop
+ nop
+ nop
+.Ltmp2:
+
+.section .text.foo1,"ax",@progbits
+.Ltmp3:
+ nop
+.Ltmp4:
+ nop
+.Ltmp5:
+
+.section .debug_abbrev,"",@progbits
+.byte 1 # Abbreviation Code
+.byte 17 # DW_TAG_compile_unit
+.byte 0 # DW_CHILDREN_no
+.byte 37 # DW_AT_producer
+.byte 14 # DW_FORM_strp
+.byte 19 # DW_AT_language
+.byte 5 # DW_FORM_data2
+.byte 3 # DW_AT_name
+.byte 14 # DW_FORM_strp
+.byte 16 # DW_AT_stmt_list
+.byte 23 # DW_FORM_sec_offset
+.byte 27 # DW_AT_comp_dir
+.byte 14 # DW_FORM_strp
+.byte 17 # DW_AT_low_pc
+.byte 1 # DW_FORM_addr
+.byte 85 # DW_AT_ranges
+.byte 23 # DW_FORM_sec_offset
+.byte 0 # EOM(1)
+.byte 0 # EOM(2)
+.byte 0 # EOM(3)
+
+.section .debug_info,"",@progbits
+.Lcu_begin0:
+.long 38 # Length of Unit
+.short 4 # DWARF version number
+.long .debug_abbrev # Offset Into Abbrev. Section
+.byte 8 # Address Size (in bytes)
+.byte 1 # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit
+.long 0 # DW_AT_producer
+.short 4 # DW_AT_language
+.long 0 # DW_AT_name
+.long 0 # DW_AT_stmt_list
+.long 0 # DW_AT_comp_dir
+.quad .Lfunc_begin0 # DW_AT_low_pc
+.long .Ldebug_ranges0 # DW_AT_ranges
+
+.section .debug_ranges,"",@progbits
+.Ldebug_ranges0:
+ .quad .Lfunc_begin0-.Lfunc_begin0
+ .quad .Ltmp0-.Lfunc_begin0
+ .quad .Ltmp1-.Lfunc_begin0
+ .quad .Ltmp2-.Lfunc_begin0
+ .quad 0xFFFFFFFFFFFFFFFF
+ .quad .text.foo1
+ .quad .Ltmp4-.text.foo1
+ .quad .Ltmp5-.text.foo1
+ .quad 0
+ .quad 0
OpenPOWER on IntegriCloud