[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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@374957 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jonas Devlieghere
2019-10-15 23:43:37 +00:00
parent b46098e73d
commit cd6834c109
4 changed files with 41 additions and 0 deletions
Binary file not shown.
@@ -0,0 +1,29 @@
RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/baseaddr/loc1.x86_64 -f -o - | llvm-dwarfdump -debug-loc - | FileCheck %s
The test was compiled from a single source:
$ cat loc1.cpp
int f1(int i, int j) {
int x = 5;
int y = 3;
int r = i + j;
int undef;
x = undef;
y = 4;
return r;
}
__attribute__((nodebug)) void f2() {
}
int main() {
return 0;
}
CHECK: .debug_loc contents:
CHECK: [0xffffffffffffffff, 0x0000000100000f90):
CHECK: [0x0000000000000004, 0x0000000000000007): DW_OP_consts +3, DW_OP_stack_value
CHECK: [0x0000000000000007, 0x0000000000000009): DW_OP_consts +4, DW_OP_stack_value
CHECK: [0xffffffffffffffff, 0x0000000100000f90):
CHECK: [0x0000000000000004, 0x0000000000000007): DW_OP_consts +5, DW_OP_stack_value
CHECK: [0xffffffffffffffff, 0x0000000100000f90):
CHECK: [0x0000000000000007, 0x0000000000000009): DW_OP_reg0 RAX
+12
View File
@@ -399,6 +399,9 @@ void DwarfStreamer::emitLocationsForUnit(
MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLocSection());
unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
uint64_t BaseAddressMarker = (AddressSize == 8)
? std::numeric_limits<uint64_t>::max()
: std::numeric_limits<uint32_t>::max();
const DWARFSection &InputSec = Dwarf.getDWARFObj().getLocSection();
DataExtractor Data(InputSec.Data, Dwarf.isLittleEndian(), AddressSize);
DWARFUnit &OrigUnit = Unit.getOrigUnit();
@@ -418,11 +421,20 @@ void DwarfStreamer::emitLocationsForUnit(
uint64_t Low = Data.getUnsigned(&Offset, AddressSize);
uint64_t High = Data.getUnsigned(&Offset, AddressSize);
LocSectionSize += 2 * AddressSize;
// End of list entry.
if (Low == 0 && High == 0) {
Asm->OutStreamer->EmitIntValue(0, AddressSize);
Asm->OutStreamer->EmitIntValue(0, AddressSize);
break;
}
// Base address selection entry.
if (Low == BaseAddressMarker) {
Asm->OutStreamer->EmitIntValue(BaseAddressMarker, AddressSize);
Asm->OutStreamer->EmitIntValue(High + Attr.second, AddressSize);
LocPcOffset = 0;
continue;
}
// Location list entry.
Asm->OutStreamer->EmitIntValue(Low + LocPcOffset, AddressSize);
Asm->OutStreamer->EmitIntValue(High + LocPcOffset, AddressSize);
uint64_t Length = Data.getU16(&Offset);