Skip to content

Commit 20c692a

Browse files
committed
[dsymutil] Support and relocate base address selection entries for debug_loc
Since r374600 clang emits base address selection entries. Currently dsymutil does not support these entries and incorrectly interprets them as location list entries. This patch adds support for base address selection entries in dsymutil and makes sure they are relocated correctly. Thanks to Dave for coming up with the test case! Differential revision: https://reviews.llvm.org/D69005 llvm-svn: 374957
1 parent 2170354 commit 20c692a

File tree

4 files changed

+41
-0
lines changed

4 files changed

+41
-0
lines changed
Binary file not shown.
Binary file not shown.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/baseaddr/loc1.x86_64 -f -o - | llvm-dwarfdump -debug-loc - | FileCheck %s
2+
3+
The test was compiled from a single source:
4+
$ cat loc1.cpp
5+
int f1(int i, int j) {
6+
int x = 5;
7+
int y = 3;
8+
int r = i + j;
9+
int undef;
10+
x = undef;
11+
y = 4;
12+
return r;
13+
}
14+
__attribute__((nodebug)) void f2() {
15+
}
16+
int main() {
17+
return 0;
18+
}
19+
20+
CHECK: .debug_loc contents:
21+
CHECK: [0xffffffffffffffff, 0x0000000100000f90):
22+
CHECK: [0x0000000000000004, 0x0000000000000007): DW_OP_consts +3, DW_OP_stack_value
23+
CHECK: [0x0000000000000007, 0x0000000000000009): DW_OP_consts +4, DW_OP_stack_value
24+
25+
CHECK: [0xffffffffffffffff, 0x0000000100000f90):
26+
CHECK: [0x0000000000000004, 0x0000000000000007): DW_OP_consts +5, DW_OP_stack_value
27+
28+
CHECK: [0xffffffffffffffff, 0x0000000100000f90):
29+
CHECK: [0x0000000000000007, 0x0000000000000009): DW_OP_reg0 RAX

llvm/tools/dsymutil/DwarfStreamer.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,9 @@ void DwarfStreamer::emitLocationsForUnit(
399399
MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLocSection());
400400

401401
unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
402+
uint64_t BaseAddressMarker = (AddressSize == 8)
403+
? std::numeric_limits<uint64_t>::max()
404+
: std::numeric_limits<uint32_t>::max();
402405
const DWARFSection &InputSec = Dwarf.getDWARFObj().getLocSection();
403406
DataExtractor Data(InputSec.Data, Dwarf.isLittleEndian(), AddressSize);
404407
DWARFUnit &OrigUnit = Unit.getOrigUnit();
@@ -418,11 +421,20 @@ void DwarfStreamer::emitLocationsForUnit(
418421
uint64_t Low = Data.getUnsigned(&Offset, AddressSize);
419422
uint64_t High = Data.getUnsigned(&Offset, AddressSize);
420423
LocSectionSize += 2 * AddressSize;
424+
// End of list entry.
421425
if (Low == 0 && High == 0) {
422426
Asm->OutStreamer->EmitIntValue(0, AddressSize);
423427
Asm->OutStreamer->EmitIntValue(0, AddressSize);
424428
break;
425429
}
430+
// Base address selection entry.
431+
if (Low == BaseAddressMarker) {
432+
Asm->OutStreamer->EmitIntValue(BaseAddressMarker, AddressSize);
433+
Asm->OutStreamer->EmitIntValue(High + Attr.second, AddressSize);
434+
LocPcOffset = 0;
435+
continue;
436+
}
437+
// Location list entry.
426438
Asm->OutStreamer->EmitIntValue(Low + LocPcOffset, AddressSize);
427439
Asm->OutStreamer->EmitIntValue(High + LocPcOffset, AddressSize);
428440
uint64_t Length = Data.getU16(&Offset);

0 commit comments

Comments
 (0)