]> granicus.if.org Git - llvm/commitdiff
[dsymutil] Support and relocate base address selection entries for debug_loc
authorJonas Devlieghere <jonas@devlieghere.com>
Tue, 15 Oct 2019 23:43:37 +0000 (23:43 +0000)
committerJonas Devlieghere <jonas@devlieghere.com>
Tue, 15 Oct 2019 23:43:37 +0000 (23:43 +0000)
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

test/tools/dsymutil/Inputs/private/tmp/baseaddr/loc1.o [new file with mode: 0644]
test/tools/dsymutil/Inputs/private/tmp/baseaddr/loc1.x86_64 [new file with mode: 0755]
test/tools/dsymutil/X86/debug-loc-base-addr.test [new file with mode: 0644]
tools/dsymutil/DwarfStreamer.cpp

diff --git a/test/tools/dsymutil/Inputs/private/tmp/baseaddr/loc1.o b/test/tools/dsymutil/Inputs/private/tmp/baseaddr/loc1.o
new file mode 100644 (file)
index 0000000..f92ea7b
Binary files /dev/null and b/test/tools/dsymutil/Inputs/private/tmp/baseaddr/loc1.o differ
diff --git a/test/tools/dsymutil/Inputs/private/tmp/baseaddr/loc1.x86_64 b/test/tools/dsymutil/Inputs/private/tmp/baseaddr/loc1.x86_64
new file mode 100755 (executable)
index 0000000..39921d4
Binary files /dev/null and b/test/tools/dsymutil/Inputs/private/tmp/baseaddr/loc1.x86_64 differ
diff --git a/test/tools/dsymutil/X86/debug-loc-base-addr.test b/test/tools/dsymutil/X86/debug-loc-base-addr.test
new file mode 100644 (file)
index 0000000..de5f30f
--- /dev/null
@@ -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
index 732260f0346f890bfba0580507bff405f3d882a2..88ca4b34a3e77432e7e598298a4eac65a7a3c67d 100644 (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);