Skip to content

Commit f6c1796

Browse files
committed
[DWARFLinker] add DWARFUnit::getIndexedAddressOffset().
This patch is a followup for D153162. It cures one more place where indexed address was incorrectly read. It also moves handling of indexed address into DWARFUnit. Differential Revision: https://reviews.llvm.org/D153297
1 parent e2b19ef commit f6c1796

File tree

5 files changed

+99
-21
lines changed

5 files changed

+99
-21
lines changed

llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,15 @@ class DWARFUnit {
355355
return AddrOffsetSectionBase;
356356
}
357357

358+
/// Returns offset to the indexed address value inside .debug_addr section.
359+
std::optional<uint64_t> getIndexedAddressOffset(uint64_t Index) {
360+
if (std::optional<uint64_t> AddrOffsetSectionBase =
361+
getAddrOffsetSectionBase())
362+
return *AddrOffsetSectionBase + Index * getAddressByteSize();
363+
364+
return std::nullopt;
365+
}
366+
358367
/// Recursively update address to Die map.
359368
void updateAddressDieMap(DWARFDie Die);
360369

llvm/lib/DWARFLinker/DWARFLinker.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -489,16 +489,14 @@ DWARFLinker::getVariableRelocAdjustment(AddressesMap &RelocMgr,
489489
} break;
490490
case dwarf::DW_OP_constx:
491491
case dwarf::DW_OP_addrx: {
492-
if (std::optional<uint64_t> AddrOffsetSectionBase =
493-
DIE.getDwarfUnit()->getAddrOffsetSectionBase()) {
494-
uint64_t StartOffset = *AddrOffsetSectionBase + Op.getRawOperand(0);
495-
uint64_t EndOffset =
496-
StartOffset + DIE.getDwarfUnit()->getAddressByteSize();
497-
492+
if (std::optional<uint64_t> AddressOffset =
493+
DIE.getDwarfUnit()->getIndexedAddressOffset(
494+
Op.getRawOperand(0))) {
498495
// Check relocation for the address.
499496
if (std::optional<int64_t> RelocAdjustment =
500-
RelocMgr.getExprOpAddressRelocAdjustment(*U, Op, StartOffset,
501-
EndOffset))
497+
RelocMgr.getExprOpAddressRelocAdjustment(
498+
*U, Op, *AddressOffset,
499+
*AddressOffset + DIE.getDwarfUnit()->getAddressByteSize()))
502500
return *RelocAdjustment;
503501
}
504502
} break;
Binary file not shown.

llvm/test/tools/dsymutil/X86/dwarf5-dw-op-addrx.test

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@
44

55
## cat dwarf5-dw-op-addrx.c
66

7+
## char arr[40];
8+
## char arr2[40];
9+
## char arr3[40];
10+
## char arr4[40];
11+
## char arr5[40];
12+
## char arr6[40];
13+
## char arr7[40];
14+
## char arr8[40];
15+
## char arr9[40];
16+
## int main() { return 0;}
17+
718
## $ clang -gdwarf-5 dwarf5-dw-op-addrx.c -c -O2 -o dwarf5-dw-op-addrx.o
819

920
#RUN: dsymutil -oso-prepend-path %p/../Inputs -y %s -o %t.dSYM
@@ -21,19 +32,75 @@
2132
#DWARF-CHECK: DW_AT_low_pc {{.*}}0x0000000100000fb0
2233
#DWARF-CHECK: DW_TAG_variable
2334
#DWARF-CHECK: DW_AT_name {{.*}}"arr"
35+
#DWARF-CHECK: DW_AT_location {{.*}}(DW_OP_addr 0x100001000)
36+
#DWARF-CHECK: DW_TAG_variable
37+
#DWARF-CHECK: DW_AT_name {{.*}}"arr2"
2438
#DWARF-CHECK: DW_AT_location {{.*}}(DW_OP_addr 0x100002000)
39+
#DWARF-CHECK: DW_TAG_variable
40+
#DWARF-CHECK: DW_AT_name {{.*}}"arr3"
41+
#DWARF-CHECK: DW_AT_location {{.*}}(DW_OP_addr 0x100003000)
42+
#DWARF-CHECK: DW_TAG_variable
43+
#DWARF-CHECK: DW_AT_name {{.*}}"arr4"
44+
#DWARF-CHECK: DW_AT_location {{.*}}(DW_OP_addr 0x100004000)
45+
#DWARF-CHECK: DW_TAG_variable
46+
#DWARF-CHECK: DW_AT_name {{.*}}"arr5"
47+
#DWARF-CHECK: DW_AT_location {{.*}}(DW_OP_addr 0x100005000)
48+
#DWARF-CHECK: DW_TAG_variable
49+
#DWARF-CHECK: DW_AT_name {{.*}}"arr6"
50+
#DWARF-CHECK: DW_AT_location {{.*}}(DW_OP_addr 0x100006000)
51+
#DWARF-CHECK: DW_TAG_variable
52+
#DWARF-CHECK: DW_AT_name {{.*}}"arr7"
53+
#DWARF-CHECK: DW_AT_location {{.*}}(DW_OP_addr 0x100007000)
54+
#DWARF-CHECK: DW_TAG_variable
55+
#DWARF-CHECK: DW_AT_name {{.*}}"arr8"
56+
#DWARF-CHECK: DW_AT_location {{.*}}(DW_OP_addr 0x100008000)
57+
#DWARF-CHECK: DW_TAG_variable
58+
#DWARF-CHECK: DW_AT_name {{.*}}"arr9"
59+
#DWARF-CHECK: DW_AT_location {{.*}}(DW_OP_addr 0x100009000)
2560
#DWARF-CHECK-NOT: .debug_addr
2661

2762
#UPD-DWARF-CHECK: DW_TAG_compile_unit
2863
#UPD-DWARF-CHECK: DW_AT_name {{.*}}"dwarf5-dw-op-addrx.c"
29-
#UPD-DWARF-CHECK: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000001) address = 0x0000000000000000)
64+
#UPD-DWARF-CHECK: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000009) address = 0x0000000000000000)
3065
#UPD-DWARF-CHECK: DW_AT_high_pc [DW_FORM_data4] (0x00000008)
3166
#UPD-DWARF-CHECK: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000008)
3267
#UPD-DWARF-CHECK: DW_TAG_variable
3368
#UPD-DWARF-CHECK: DW_AT_name {{.*}}"arr"
3469
#UPD-DWARF-CHECK: DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x0)
70+
#UPD-DWARF-CHECK: DW_TAG_variable
71+
#UPD-DWARF-CHECK: DW_AT_name {{.*}}"arr2"
72+
#UPD-DWARF-CHECK: DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x1)
73+
#UPD-DWARF-CHECK: DW_TAG_variable
74+
#UPD-DWARF-CHECK: DW_AT_name {{.*}}"arr3"
75+
#UPD-DWARF-CHECK: DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x2)
76+
#UPD-DWARF-CHECK: DW_TAG_variable
77+
#UPD-DWARF-CHECK: DW_AT_name {{.*}}"arr4"
78+
#UPD-DWARF-CHECK: DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x3)
79+
#UPD-DWARF-CHECK: DW_TAG_variable
80+
#UPD-DWARF-CHECK: DW_AT_name {{.*}}"arr5"
81+
#UPD-DWARF-CHECK: DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x4)
82+
#UPD-DWARF-CHECK: DW_TAG_variable
83+
#UPD-DWARF-CHECK: DW_AT_name {{.*}}"arr6"
84+
#UPD-DWARF-CHECK: DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x5)
85+
#UPD-DWARF-CHECK: DW_TAG_variable
86+
#UPD-DWARF-CHECK: DW_AT_name {{.*}}"arr7"
87+
#UPD-DWARF-CHECK: DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x6)
88+
#UPD-DWARF-CHECK: DW_TAG_variable
89+
#UPD-DWARF-CHECK: DW_AT_name {{.*}}"arr8"
90+
#UPD-DWARF-CHECK: DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x7)
91+
#UPD-DWARF-CHECK: DW_TAG_variable
92+
#UPD-DWARF-CHECK: DW_AT_name {{.*}}"arr9"
93+
#UPD-DWARF-CHECK: DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x8)
3594
#UPD-DWARF-CHECK: .debug_addr contents:
36-
#UPD-DWARF-CHECK: 0x00000000: Address table header: length = 0x00000014, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00
95+
#UPD-DWARF-CHECK: 0x00000000: Address table header: length = 0x00000054, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00
96+
#UPD-DWARF-CHECK: 0x0000000000000000
97+
#UPD-DWARF-CHECK: 0x0000000000000000
98+
#UPD-DWARF-CHECK: 0x0000000000000000
99+
#UPD-DWARF-CHECK: 0x0000000000000000
100+
#UPD-DWARF-CHECK: 0x0000000000000000
101+
#UPD-DWARF-CHECK: 0x0000000000000000
102+
#UPD-DWARF-CHECK: 0x0000000000000000
103+
#UPD-DWARF-CHECK: 0x0000000000000000
37104
#UPD-DWARF-CHECK: 0x0000000000000000
38105
#UPD-DWARF-CHECK: 0x0000000000000000
39106

@@ -44,4 +111,12 @@ objects:
44111
timestamp: 1676048242
45112
symbols:
46113
- { sym: _main, objAddr: 0x0000000000000000, binAddr: 0x0000000100000FB0, size: 0x00000008 }
47-
- { sym: _arr, binAddr: 0x0000000100002000, size: 0x00000000 }
114+
- { sym: _arr, binAddr: 0x0000000100001000, size: 0x00000008 }
115+
- { sym: _arr2, binAddr: 0x0000000100002000, size: 0x00000008 }
116+
- { sym: _arr3, binAddr: 0x0000000100003000, size: 0x00000008 }
117+
- { sym: _arr4, binAddr: 0x0000000100004000, size: 0x00000008 }
118+
- { sym: _arr5, binAddr: 0x0000000100005000, size: 0x00000008 }
119+
- { sym: _arr6, binAddr: 0x0000000100006000, size: 0x00000008 }
120+
- { sym: _arr7, binAddr: 0x0000000100007000, size: 0x00000008 }
121+
- { sym: _arr8, binAddr: 0x0000000100008000, size: 0x00000008 }
122+
- { sym: _arr9, binAddr: 0x0000000100009000, size: 0x00000008 }

llvm/tools/dsymutil/DwarfLinkerForBinary.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,16 +1079,12 @@ std::optional<int64_t> DwarfLinkerForBinary::AddressManager<
10791079
case dwarf::DW_FORM_addrx3:
10801080
case dwarf::DW_FORM_addrx4: {
10811081
std::optional<DWARFFormValue> AddrValue = DIE.find(dwarf::DW_AT_low_pc);
1082-
if (std::optional<uint64_t> AddrOffsetSectionBase =
1083-
DIE.getDwarfUnit()->getAddrOffsetSectionBase()) {
1084-
// Addrx is a index into the debug_addr section, not an offset, so we need
1085-
// to multiply by byte size.
1086-
const uint64_t AddrSize = DIE.getDwarfUnit()->getAddressByteSize();
1087-
const uint64_t StartOffset =
1088-
*AddrOffsetSectionBase + (AddrValue->getRawUValue() * AddrSize);
1089-
const uint64_t EndOffset = StartOffset + AddrSize;
1090-
return hasValidRelocationAt(ValidDebugAddrRelocs, StartOffset, EndOffset);
1091-
}
1082+
if (std::optional<uint64_t> AddressOffset =
1083+
DIE.getDwarfUnit()->getIndexedAddressOffset(
1084+
AddrValue->getRawUValue()))
1085+
return hasValidRelocationAt(ValidDebugAddrRelocs, *AddressOffset,
1086+
*AddressOffset +
1087+
DIE.getDwarfUnit()->getAddressByteSize());
10921088

10931089
Linker.reportWarning("no base offset for address table", SrcFileName);
10941090
return std::nullopt;

0 commit comments

Comments
 (0)