Add GNU_discriminator support for inline callsites in llvm-symbolizer.
authorDehao Chen <dehao@google.com>
Mon, 17 Apr 2017 20:10:39 +0000 (20:10 +0000)
committerDehao Chen <dehao@google.com>
Mon, 17 Apr 2017 20:10:39 +0000 (20:10 +0000)
Summary: LLVM symbolize cannot recognize GNU_discriminator for inline callsites. This patch adds support for it.

Reviewers: dblaikie

Reviewed By: dblaikie

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D32134

llvm-svn: 300486

llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h
llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
llvm/test/tools/llvm-symbolizer/Inputs/discrim
llvm/test/tools/llvm-symbolizer/Inputs/discrim.c
llvm/test/tools/llvm-symbolizer/Inputs/discrim.inp
llvm/test/tools/llvm-symbolizer/sym-verbose.test

index 33e24fe..9b260c0 100644 (file)
@@ -247,8 +247,10 @@ public:
   /// DW_AT_call_line attribute in this DIE.
   /// \param CallColumn filled in with non-zero if successful, zero if there is
   /// no DW_AT_call_column attribute in this DIE.
+  /// \param CallDiscriminator filled in with non-zero if successful, zero if
+  /// there is no DW_AT_GNU_discriminator attribute in this DIE.
   void getCallerFrame(uint32_t &CallFile, uint32_t &CallLine,
-                      uint32_t &CallColumn) const;
+                      uint32_t &CallColumn, uint32_t &CallDiscriminator) const;
   
   /// Get inlined chain for a given address, rooted at the current DIE.
   /// Returns empty chain if address is not contained in address range
index cbce2dc..bbb19b5 100644 (file)
@@ -579,7 +579,7 @@ DWARFContext::getInliningInfoForAddress(uint64_t Address,
     return InliningInfo;
   }
 
-  uint32_t CallFile = 0, CallLine = 0, CallColumn = 0;
+  uint32_t CallFile = 0, CallLine = 0, CallColumn = 0, CallDiscriminator = 0;
   for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) {
     DWARFDie &FunctionDIE = InlinedChain[i];
     DILineInfo Frame;
@@ -605,10 +605,12 @@ DWARFContext::getInliningInfoForAddress(uint64_t Address,
                                         Spec.FLIKind, Frame.FileName);
         Frame.Line = CallLine;
         Frame.Column = CallColumn;
+        Frame.Discriminator = CallDiscriminator;
       }
       // Get call file/line/column of a current DIE.
       if (i + 1 < n) {
-        FunctionDIE.getCallerFrame(CallFile, CallLine, CallColumn);
+        FunctionDIE.getCallerFrame(CallFile, CallLine, CallColumn,
+                                   CallDiscriminator);
       }
     }
     InliningInfo.addFrame(Frame);
index 4308cc2..b88cc63 100644 (file)
@@ -290,10 +290,12 @@ uint64_t DWARFDie::getDeclLine() const {
 }
 
 void DWARFDie::getCallerFrame(uint32_t &CallFile, uint32_t &CallLine,
-                              uint32_t &CallColumn) const {
+                              uint32_t &CallColumn,
+                              uint32_t &CallDiscriminator) const {
   CallFile = toUnsigned(find(DW_AT_call_file), 0);
   CallLine = toUnsigned(find(DW_AT_call_line), 0);
   CallColumn = toUnsigned(find(DW_AT_call_column), 0);
+  CallDiscriminator = toUnsigned(find(DW_AT_GNU_discriminator), 0);
 }
 
 void DWARFDie::dump(raw_ostream &OS, unsigned RecurseDepth,
index ec61fe9..0e5e847 100644 (file)
Binary files a/llvm/test/tools/llvm-symbolizer/Inputs/discrim and b/llvm/test/tools/llvm-symbolizer/Inputs/discrim differ
index decbce8..e53cbd4 100644 (file)
@@ -1,8 +1,11 @@
 static volatile int do_mul;
-static volatile int do_inc;
+static volatile int x, v;
 
-int main () {
-  int x = 1;
-  if (do_mul) x *= 2; else x /= 2;
-  return do_inc ? ++x : --x;
+int foo () {
+  if (do_mul) x *= v; else x /= v;
+  return x;
+}
+
+int main() {
+  return foo() + foo();
 }
index f8ad601..a5cfcb2 100644 (file)
@@ -1,5 +1,8 @@
 some text\r
-0x4004f2\r
-0x400509\r
-0x40050d\r
+0x400590\r
+0x4005a5\r
+0x4005ad\r
+0x4005b9\r
+0x4005ce\r
+0x4005d4\r
 some more text\r
index ef66db9..dbb1b3f 100644 (file)
@@ -1,39 +1,97 @@
 #static volatile int do_mul;
-#static volatile int do_inc;
+#static volatile int x, v;
 #
-#int main () {
-#  int x = 1;
-#  if (do_mul) x *= 2; else x /= 2;
-#  return do_inc ? ++x : --x;
+#int foo () {
+#  if (do_mul) x *= v; else x /= v;
+#  return x;
 #}
-#Build as : clang -g -O2 discrim.c -o discrim
+#
+#int main() {
+#  return foo() + foo();
+#}
+#Build as : clang -gmlt -fdebug-info-for-profiling -O2 discrim.c -o discrim
 
 RUN: llvm-symbolizer -verbose -print-address -obj=%p/Inputs/discrim < %p/Inputs/discrim.inp | FileCheck %s
 
 #CHECK: some text
 
-#CHECK: 0x4004f2
+#CHECK: 0x400590
+#CHECK-NEXT: foo
+#CHECK-NEXT: Filename: /tmp/discrim.c
+#CHECK-NEXT: Function start line: 4
+#CHECK-NEXT: Line: 9
+#CHECK-NEXT: Column: 0
 #CHECK-NEXT: main
-#CHECK-NEXT: Filename: /tmp{{[\\/]}}discrim.c
+#CHECK-NEXT: Filename: /tmp/discrim.c
+#CHECK-NEXT: Function start line: 9
+#CHECK-NEXT: Line: 10
+#CHECK-NEXT: Column: 0
+
+#CHECK: 0x4005a5
+#CHECK-NEXT: foo
+#CHECK-NEXT: Filename: /tmp/discrim.c
 #CHECK-NEXT: Function start line: 4
-#CHECK-NEXT: Line: 6
-#CHECK-NEXT: Column: 7
-#CHECK-NOT: Discriminator: 0
+#CHECK-NEXT: Line: 5
+#CHECK-NEXT: Column: 17
+#CHECK-NEXT: Discriminator: 2
+#CHECK-NEXT: main
+#CHECK-NEXT: Filename: /tmp/discrim.c
+#CHECK-NEXT: Function start line: 9
+#CHECK-NEXT: Line: 10
+#CHECK-NEXT: Column: 0
 
-#CHECK: 0x400509
+#CHECK: 0x4005ad
+#CHECK-NEXT: foo
+#CHECK-NEXT: Filename: /tmp/discrim.c
+#CHECK-NEXT: Function start line: 4
+#CHECK-NEXT: Line: 0
+#CHECK-NEXT: Column: 30
+#CHECK-NEXT: Discriminator: 4
 #CHECK-NEXT: main
-#CHECK-NEXT: Filename: /tmp{{[\\/]}}discrim.c
+#CHECK-NEXT: Filename: /tmp/discrim.c
+#CHECK-NEXT: Function start line: 9
+#CHECK-NEXT: Line: 10
+#CHECK-NEXT: Column: 0
+
+#CHECK: 0x4005b9
+#CHECK-NEXT: foo
+#CHECK-NEXT: Filename: /tmp/discrim.c
 #CHECK-NEXT: Function start line: 4
-#CHECK-NEXT: Line: 7
-#CHECK-NEXT: Column: 3
-#CHECK-NEXT: Discriminator: 1
+#CHECK-NEXT: Line: 5
+#CHECK-NEXT: Column: 7
+#CHECK-NEXT: main
+#CHECK-NEXT: Filename: /tmp/discrim.c
+#CHECK-NEXT: Function start line: 9
+#CHECK-NEXT: Line: 10
+#CHECK-NEXT: Column: 0
+#CHECK-NEXT: Discriminator: 2
 
-#CHECK: 0x40050d
+#CHECK: 0x4005ce
+#CHECK-NEXT: foo
+#CHECK-NEXT: Filename: /tmp/discrim.c
+#CHECK-NEXT: Function start line: 4
+#CHECK-NEXT: Line: 5
+#CHECK-NEXT: Column: 17
+#CHECK-NEXT: Discriminator: 2
 #CHECK-NEXT: main
-#CHECK-NEXT: Filename: /tmp{{[\\/]}}discrim.c
+#CHECK-NEXT: Filename: /tmp/discrim.c
+#CHECK-NEXT: Function start line: 9
+#CHECK-NEXT: Line: 10
+#CHECK-NEXT: Column: 0
+#CHECK-NEXT: Discriminator: 2
+
+#CHECK: 0x4005d4
+#CHECK-NEXT: foo
+#CHECK-NEXT: Filename: /tmp/discrim.c
 #CHECK-NEXT: Function start line: 4
-#CHECK-NEXT: Line: 7
-#CHECK-NEXT: Column: 3
+#CHECK-NEXT: Line: 5
+#CHECK-NEXT: Column: 30
+#CHECK-NEXT: Discriminator: 4
+#CHECK-NEXT: main
+#CHECK-NEXT: Filename: /tmp/discrim.c
+#CHECK-NEXT: Function start line: 9
+#CHECK-NEXT: Line: 10
+#CHECK-NEXT: Column: 0
 #CHECK-NEXT: Discriminator: 2
 
 #CHECK: some more text