diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp index 17b32a5f67b49..3c078d8ee74b8 100644 --- a/llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp +++ b/llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp @@ -156,7 +156,7 @@ std::string LVOperation::getOperandsDWARFInfo() { Stream << "push_object_address"; break; case dwarf::DW_OP_form_tls_address: - Stream << "form_tls_address " << hexString(Operands[0]); + Stream << "form_tls_address"; break; case dwarf::DW_OP_call_frame_cfa: Stream << "call_frame_cfa"; @@ -308,7 +308,7 @@ std::string LVOperation::getOperandsDWARFInfo() { PrintRegisterInfo(dwarf::DW_OP_reg0); break; case dwarf::DW_OP_GNU_push_tls_address: - Stream << "gnu_push_tls_address " << hexString(Operands[0]); + Stream << "gnu_push_tls_address"; break; case dwarf::DW_OP_GNU_addr_index: Stream << "gnu_addr_index " << unsigned(Operands[0]); diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/Inputs/ThreadLocalStorage.ll b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/Inputs/ThreadLocalStorage.ll new file mode 100644 index 0000000000000..45b7574f1843e --- /dev/null +++ b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/Inputs/ThreadLocalStorage.ll @@ -0,0 +1,42 @@ +source_filename = "ThreadLocalStorage.cpp" +target triple = "x86_64-pc-linux-gnu" + +@TGlobal = dso_local thread_local global i32 0, align 4, !dbg !0 +@NGlobal = dso_local global i32 1, align 4, !dbg !5 +@_ZZ4testvE6TLocal = internal thread_local global i32 0, align 4, !dbg !8 + +define dso_local void @_Z4testv() !dbg !10 { +entry: + %NLocal = alloca i32, align 4 + %0 = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @TGlobal), !dbg !22 + store i32 1, ptr %0, align 4 + #dbg_declare(ptr %NLocal, !24, !DIExpression(), !25) + store i32 0, ptr %NLocal, align 4, !dbg !25 + store i32 2, ptr @NGlobal, align 4 + ret void +} + +declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!14, !15} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "TGlobal", scope: !2, file: !3, line: 1, type: !7, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, emissionKind: FullDebug, globals: !4) +!3 = !DIFile(filename: "ThreadLocalStorage.cpp", directory: "") +!4 = !{!0, !5, !8} +!5 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression()) +!6 = distinct !DIGlobalVariable(name: "NGlobal", scope: !2, file: !3, line: 2, type: !7, isLocal: false, isDefinition: true) +!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!8 = !DIGlobalVariableExpression(var: !9, expr: !DIExpression()) +!9 = distinct !DIGlobalVariable(name: "TLocal", scope: !10, file: !3, line: 4, type: !7, isLocal: true, isDefinition: true) +!10 = distinct !DISubprogram(name: "test", scope: !3, file: !3, line: 3, type: !11, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !13) +!11 = !DISubroutineType(types: !12) +!12 = !{null} +!13 = !{} +!14 = !{i32 7, !"Dwarf Version", i32 5} +!15 = !{i32 2, !"Debug Info Version", i32 3} +!22 = !DILocation(line: 5, scope: !10) +!24 = !DILocalVariable(name: "NLocal", scope: !10, file: !3, line: 7, type: !7) +!25 = !DILocation(line: 7, scope: !10) diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/crash-thread-local-storage.test b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/crash-thread-local-storage.test new file mode 100644 index 0000000000000..5f2b3f9e824ab --- /dev/null +++ b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/crash-thread-local-storage.test @@ -0,0 +1,51 @@ +; REQUIRES: x86-registered-target + +; For the given test case: + +; // ThreadLocalStorage.cpp +; 1 thread_local int TGlobal = 0; +; 2 int NGlobal = 1; +; 3 void test() { +; 4 thread_local int TLocal = 0; +; 5 TGlobal = 1; +; 6 +; 7 int NLocal = 0; +; 8 NGlobal = 2; +; 9 } + +; The llvm-debuginfo-analyzer crashes when producing a logical view for +; the object file generated using the following commands: +; +; clang++ -Xclang -disable-O0-optnone -Xclang -disable-llvm-passes +; -fno-discard-value-names -emit-llvm -S -g -O0 +; ThreadLocalStorage.cpp -o ThreadLocalStorage.ll +; llc --filetype=obj ThreadLocalStorage.ll -o ThreadLocalStorage.o +; +; llvm-debuginfo-analyzer --attribute=location --print=symbols +; ThreadLocalStorage.o + +; RUN: llc --filetype=obj \ +; RUN: %p/Inputs/ThreadLocalStorage.ll -o %t.ThreadLocalStorage.o + +; RUN: llvm-debuginfo-analyzer --attribute=location \ +; RUN: --print=symbols \ +; RUN: %t.ThreadLocalStorage.o 2>&1 | \ +; RUN: FileCheck --strict-whitespace %s + +; CHECK: Logical View: +; CHECK: {File} '{{.*}}threadlocalstorage.o' +; CHECK-EMPTY: +; CHECK: {CompileUnit} 'threadlocalstorage.cpp' +; CHECK: 1 {Variable} extern 'TGlobal' -> 'int' +; CHECK: {Location} +; CHECK: {Entry} const_u 0, gnu_push_tls_address +; CHECK: 2 {Variable} extern 'NGlobal' -> 'int' +; CHECK: {Location} +; CHECK: {Entry} addrx 0 +; CHECK: 3 {Function} extern not_inlined 'test' -> 'void' +; CHECK: 4 {Variable} 'TLocal' -> 'int' +; CHECK: {Location} +; CHECK: {Entry} const_u 0, gnu_push_tls_address +; CHECK: 7 {Variable} 'NLocal' -> 'int' +; CHECK: {Location} +; CHECK: {Entry} fbreg -4