From cc55b738670ea73ece2bb0a3be025f09e5917fa9 Mon Sep 17 00:00:00 2001 From: Frederic Riss Date: Mon, 22 Sep 2014 12:35:53 +0000 Subject: [PATCH] Allow DWARFDebugInfoEntryMinimal::getSubroutineName to resolve cross-unit references. Summary: getSubroutineName is currently only used by llvm-symbolizer, thus add a binary test containing a cross-cu inlining example. Reviewers: samsonov, dblaikie Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D5394 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218245 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/DebugInfo/DWARFDebugInfoEntry.cpp | 20 ++++++++++++++---- test/DebugInfo/Inputs/cross-cu-inlining.c | 18 ++++++++++++++++ .../Inputs/cross-cu-inlining.x86_64-macho.o | Bin 0 -> 2648 bytes test/DebugInfo/llvm-symbolizer.test | 8 +++++++ 4 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 test/DebugInfo/Inputs/cross-cu-inlining.c create mode 100644 test/DebugInfo/Inputs/cross-cu-inlining.x86_64-macho.o diff --git a/lib/DebugInfo/DWARFDebugInfoEntry.cpp b/lib/DebugInfo/DWARFDebugInfoEntry.cpp index aaca666be84..192cd3cdacf 100644 --- a/lib/DebugInfo/DWARFDebugInfoEntry.cpp +++ b/lib/DebugInfo/DWARFDebugInfoEntry.cpp @@ -20,6 +20,17 @@ using namespace llvm; using namespace dwarf; typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind; +// Small helper to extract a DIE pointed by a reference +// attribute. It looks up the Unit containing the DIE and calls +// DIE.extractFast with the right unit. Returns new unit on success, +// nullptr otherwise. +static const DWARFUnit *findUnitAndExtractFast(DWARFDebugInfoEntryMinimal &DIE, + const DWARFUnit *Unit, + uint32_t *Offset) { + Unit = Unit->getUnitSection().getUnitForOffset(*Offset); + return (Unit && DIE.extractFast(Unit, Offset)) ? Unit : nullptr; +} + void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, const DWARFUnit *u, unsigned recurseDepth, unsigned indent) const { @@ -315,8 +326,8 @@ DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U, getAttributeValueAsReference(U, DW_AT_specification, -1U); if (spec_ref != -1U) { DWARFDebugInfoEntryMinimal spec_die; - if (spec_die.extractFast(U, &spec_ref)) { - if (const char *name = spec_die.getSubroutineName(U, Kind)) + if (const DWARFUnit *RefU = findUnitAndExtractFast(spec_die, U, &spec_ref)) { + if (const char *name = spec_die.getSubroutineName(RefU, Kind)) return name; } } @@ -325,8 +336,9 @@ DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U, getAttributeValueAsReference(U, DW_AT_abstract_origin, -1U); if (abs_origin_ref != -1U) { DWARFDebugInfoEntryMinimal abs_origin_die; - if (abs_origin_die.extractFast(U, &abs_origin_ref)) { - if (const char *name = abs_origin_die.getSubroutineName(U, Kind)) + if (const DWARFUnit *RefU = findUnitAndExtractFast(abs_origin_die, U, + &abs_origin_ref)) { + if (const char *name = abs_origin_die.getSubroutineName(RefU, Kind)) return name; } } diff --git a/test/DebugInfo/Inputs/cross-cu-inlining.c b/test/DebugInfo/Inputs/cross-cu-inlining.c new file mode 100644 index 00000000000..05535811aa6 --- /dev/null +++ b/test/DebugInfo/Inputs/cross-cu-inlining.c @@ -0,0 +1,18 @@ +// To generate the test file: +// clang cross-cu-inlining.c -DA_C -g -emit-llvm -S -o a.ll +// clang cross-cu-inlining.c -DB_C -g -emit-llvm -S -o b.ll +// llvm-link a.ll b.ll -o ab.bc +// opt -inline ab.bc -o cross-cu-inlining.bc +// clang -c cross-cu-inlining.bc -o cross-cu-inlining.o +#ifdef A_C +int i; +int func(int); +int main() { + return func(i); +} +#endif +#ifdef B_C +int __attribute__((always_inline)) func(int x) { + return x * 2; +} +#endif diff --git a/test/DebugInfo/Inputs/cross-cu-inlining.x86_64-macho.o b/test/DebugInfo/Inputs/cross-cu-inlining.x86_64-macho.o new file mode 100644 index 0000000000000000000000000000000000000000..052d4c92f909b2330e53bf6f645c2a7f49b6742a GIT binary patch literal 2648 zcmbVNO>7%Q6rNdo9sk8~8W11|I8p$C6qAVZTcEaRz!fbj!IW@_7RPatt>U%uPYG2j zdO!#(2S7+1kT`OO0~OqedLTEDxNrms1P73MjA+#GeY0=t#CAl>liq&s&Aj>My|**F zKm7Ce^&zEnNZ|nuLx1EW1BKiLou_|@tjgR~!N3Qnq7KVC$7xm8TU`>zDbCIpyMAEh z#ULLk=VN|ea4rQgM8{dGEVfr1*ITan{)yM~b1&Qo33$RR3NmB+_$K%gzG?a3KLftf z;$ow6p8N;-W`*YyS@c+B|7v3o-y~n_o%+Cf+rsyv z-Ok>ZKW*MVJuay(Eh3av|lT9elKjA zkHPn|I}G29c24hZp5ER1Rd==*t}GkLj@@C=oJA6>%f;thgKHm6A zJU|uNpVAygnG*M+M`7p@%}prC>?y)XFrZ?+OY~Wm5y!4MAYw=L{i!iKluAeL zPL1j#XoPiCg;FQSjwhc^97|YyiIW(3E|I_s3}><6h|a}BDb6wq<&W!`G>7LCZy+XO zD=R*e#!n-w{jdj~`k@zltQM?|Y~ zqt zB)SFUosmRfFmWwoxVCD&7hSMvo{!vjP``;7P% z`ky=6EGKo@Qs>_NY~!u#pKkDt@*ledo&vY*P`*c4k;V|cf4uH^ra6H%!PeqENhsA_Q-_q2btZN4cb3?$b7K1zA&fs zdRnKGL(z}G!Y%HB{&I~)?d=Iau1zZazV-ZY@VjRmQ~FclWS_n`{w~qZXa53%KJuI3 zw}M{@UJ&G8opD9MQ-aR`!IOGG{CfpEf=>wMfcWGV1;boNUoiZn_<~{f2@Nj_hBNTF jKfoYvuo}TY&`+4g=RAe=Vay5}4-dzjRL510Il2D=qZAHf literal 0 HcmV?d00001 diff --git a/test/DebugInfo/llvm-symbolizer.test b/test/DebugInfo/llvm-symbolizer.test index 40a051e327a..4a62de8e0ff 100644 --- a/test/DebugInfo/llvm-symbolizer.test +++ b/test/DebugInfo/llvm-symbolizer.test @@ -22,6 +22,7 @@ RUN: echo "%p/Inputs/arange-overlap.elf-x86_64 0x714" >> %t.input RUN: cp %p/Inputs/split-dwarf-test.dwo %T RUN: echo "%p/Inputs/split-dwarf-test 0x4004d0" >> %t.input RUN: echo "%p/Inputs/split-dwarf-test 0x4004c0" >> %t.input +RUN: echo "%p/Inputs/cross-cu-inlining.x86_64-macho.o 0x17" >> %t.input RUN: llvm-symbolizer --functions=linkage --inlining --demangle=false \ RUN: --default-arch=i386 < %t.input | FileCheck %s @@ -111,6 +112,13 @@ CHECK-NEXT: {{.*}}split-dwarf-test.cc CHECK: _Z3fooi CHECK-NEXT: {{.*}}split-dwarf-test.cc +; func has been inlined into main by LTO. Check that the symbolizer is able +; to resolve the cross-cu reference and retrieve func's name +CHECK: func +CHECK-NEXT: /tmp{{[/\\]}}cross-cu-inlining.c:16:3 +CHECK-NEXT: main +CHECK-NEXT: /tmp{{[/\\]}}cross-cu-inlining.c:11:0 + RUN: echo "unexisting-file 0x1234" > %t.input2 RUN: llvm-symbolizer < %t.input2