[llvm-symbolizer] Fix parsing DW_AT_ranges in Fission skeleton compile unit DIEs.
authorAlexey Samsonov <vonosmas@gmail.com>
Thu, 12 Jun 2014 18:52:35 +0000 (18:52 +0000)
committerAlexey Samsonov <vonosmas@gmail.com>
Thu, 12 Jun 2014 18:52:35 +0000 (18:52 +0000)
Turns out that DW_AT_ranges_base attribute sets the offset for
DW_AT_ranges values specified in the .dwo file, but not for DW_AT_ranges specified
in the skeleton compile unit DIE in the main executable. This is extremely confusing,
and would hopefully be fixed in DWARF-5 when it's finalized. For now this
behavior makes sense, as otherwise Fission would break DWARF consumers who
doesn't know anything about DW_AT_ranges_base.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@210809 91177308-0d34-0410-b5e6-96231b3b80d8

lib/DebugInfo/DWARFUnit.cpp
test/DebugInfo/Inputs/fission-ranges.cc [new file with mode: 0644]
test/DebugInfo/Inputs/fission-ranges.elf-x86_64 [new file with mode: 0755]
test/DebugInfo/llvm-symbolizer.test

index f5f5072b9d3d06df01951dabadb7fbfba87b59e0..027827735cf65f5c0b120f468942b894c1d85dad 100644 (file)
@@ -225,8 +225,12 @@ size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
     setBaseAddress(BaseAddr);
     AddrOffsetSectionBase = DieArray[0].getAttributeValueAsSectionOffset(
         this, DW_AT_GNU_addr_base, 0);
-    RangeSectionBase = DieArray[0].getAttributeValueAsSectionOffset(
-        this, DW_AT_GNU_ranges_base, 0);
+    // Users of old DWARF may not know about DW_AT_ranges_base, so it is ignored
+    // for skeleton CU DIE (e.g. DW_AT_ranges are *not* relative to it).
+    if (Version > 4) {
+      RangeSectionBase = DieArray[0].getAttributeValueAsSectionOffset(
+          this, DW_AT_GNU_ranges_base, 0);
+    }
   }
 
   setDIERelations();
@@ -272,7 +276,9 @@ bool DWARFUnit::parseDWO() {
   }
   // Share .debug_addr and .debug_ranges section with compile unit in .dwo
   DWOCU->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase);
-  DWOCU->setRangesSection(RangeSection, RangeSectionBase);
+  uint32_t DWORangesBase = DieArray[0].getAttributeValueAsSectionOffset(
+      this, DW_AT_GNU_ranges_base, 0);
+  DWOCU->setRangesSection(RangeSection, DWORangesBase);
   return true;
 }
 
diff --git a/test/DebugInfo/Inputs/fission-ranges.cc b/test/DebugInfo/Inputs/fission-ranges.cc
new file mode 100644 (file)
index 0000000..a585bf9
--- /dev/null
@@ -0,0 +1,17 @@
+static inline int inlined_f() {
+  volatile int x = 2;
+  return x;
+}
+
+int main() {
+  return inlined_f();
+}
+
+// Build instructions:
+// $ mkdir /tmp/dbginfo
+// $ cp fission-ranges.cc /tmp/dbginfo/
+// $ cd /tmp/dbginfo
+// $ gcc -gsplit-dwarf -O2 -fPIC fission-ranges.cc -c -o obj2.o
+// $ clang -gsplit-dwarf -O2 -fsanitize=address -fPIC -Dmain=foo fission-ranges.cc -c -o obj1.o
+// $ gcc obj1.o obj2.o -shared -o <output>
+// $ objcopy --remove-section=.debug_aranges <output>
diff --git a/test/DebugInfo/Inputs/fission-ranges.elf-x86_64 b/test/DebugInfo/Inputs/fission-ranges.elf-x86_64
new file mode 100755 (executable)
index 0000000..3d2fd79
Binary files /dev/null and b/test/DebugInfo/Inputs/fission-ranges.elf-x86_64 differ
index 6aa12876fa553c5caced67e06f8ca81bd15b5033..1ddfd9cf55c5f7869c734a0d69d7ba96c9a7fe35 100644 (file)
@@ -17,6 +17,7 @@ RUN: echo "%p/Inputs/macho-universal 0x1f84" >> %t.input
 RUN: echo "%p/Inputs/macho-universal:i386 0x1f67" >> %t.input
 RUN: echo "%p/Inputs/macho-universal:x86_64 0x100000f05" >> %t.input
 RUN: echo "%p/Inputs/llvm-symbolizer-dwo-test 0x400514" >> %t.input
+RUN: echo "%p/Inputs/fission-ranges.elf-x86_64 0x720" >> %t.input
 
 RUN: llvm-symbolizer --functions=linkage --inlining --demangle=false \
 RUN:    --default-arch=i386 < %t.input | FileCheck %s
@@ -90,6 +91,9 @@ CHECK:      _Z3inci
 CHECK: main
 CHECK-NEXT: llvm-symbolizer-dwo-test.cc:11
 
+CHECK: main
+CHECK-NEXT: {{.*}}fission-ranges.cc:6
+
 RUN: echo "unexisting-file 0x1234" > %t.input2
 RUN: llvm-symbolizer < %t.input2