[llvm] e1f830b - [WebAssembly] Support debug info for TLS + global in PIC mode

Heejin Ahn via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 17 20:17:18 PDT 2023


Author: Heejin Ahn
Date: 2023-03-17T20:16:48-07:00
New Revision: e1f830bde8bad22d375bc92f2084e9055059cc77

URL: https://github.com/llvm/llvm-project/commit/e1f830bde8bad22d375bc92f2084e9055059cc77
DIFF: https://github.com/llvm/llvm-project/commit/e1f830bde8bad22d375bc92f2084e9055059cc77.diff

LOG: [WebAssembly] Support debug info for TLS + global in PIC mode

This adds debug info support for
- `thread_local` global variables, both in non-PIC and PIC modes
- (non-thread_local) Global variables in PIC mode

The former needs to read the value from an offset relative to
`__tls_base` and the latter an offset from `__memory_base`. The code for
doing this overlaps with some of the existing code to add
`__stack_pointer` global, so this adds a new member function to add a
a global in `TI_GLOBAL_RELOC` mode and use it in all three places.

Split DWARF support is currently patchy at best, because the index for
`__tls_base` is not fixed after dynamic linking. The preexisting split
DWARF support for `__stack_pointer` relies on that in practice it is
always index 0. This does similar hardcoding for `__tls_base` and
`__memory_base`, but `__tls_base`'s index in dynamic linking is not
fixed now (See
https://github.com/llvm/llvm-project/blob/19afbfe33156d211fa959dadeea46cd17b9c723c/lld/wasm/Driver.cpp#L786-L823
for details), TLS + dynamic linking will not work at the moment.

Fixes https://bugs.chromium.org/p/chromium/issues/detail?id=1416702.

Reviewed By: dschuff

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

Added: 
    llvm/test/DebugInfo/WebAssembly/tls_pic_globals.ll

Modified: 
    llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
    llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 4c6a5bb5bf0dd..f336eae12518f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -278,7 +278,16 @@ void DwarfCompileUnit::addLocationAttribute(
                    : FormAndOp{dwarf::DW_FORM_data8, dwarf::DW_OP_const8u};
       };
       if (Global->isThreadLocal()) {
-        if (Asm->TM.useEmulatedTLS()) {
+        if (Asm->TM.getTargetTriple().isWasm()) {
+          // FIXME This is not guaranteed, but in practice, in static linking,
+          // if present, __tls_base's index is 1. This doesn't hold for dynamic
+          // linking, so TLS variables used in dynamic linking won't have
+          // correct debug info for now. See
+          // https://github.com/llvm/llvm-project/blob/19afbfe33156d211fa959dadeea46cd17b9c723c/lld/wasm/Driver.cpp#L786-L823
+          addWasmRelocBaseGlobal(Loc, "__tls_base", 1);
+          addOpAddress(*Loc, Sym);
+          addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
+        } else if (Asm->TM.useEmulatedTLS()) {
           // TODO: add debug info for emulated thread local mode.
         } else {
           // FIXME: Make this work with -gsplit-dwarf.
@@ -301,6 +310,14 @@ void DwarfCompileUnit::addLocationAttribute(
                   DD->useGNUTLSOpcode() ? dwarf::DW_OP_GNU_push_tls_address
                                         : dwarf::DW_OP_form_tls_address);
         }
+      } else if (Asm->TM.getTargetTriple().isWasm() &&
+                 Asm->TM.getRelocationModel() == Reloc::PIC_) {
+        // FIXME This is not guaranteed, but in practice, if present,
+        // __memory_base's index is 1. See
+        // https://github.com/llvm/llvm-project/blob/19afbfe33156d211fa959dadeea46cd17b9c723c/lld/wasm/Driver.cpp#L786-L823
+        addWasmRelocBaseGlobal(Loc, "__memory_base", 1);
+        addOpAddress(*Loc, Sym);
+        addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
       } else if ((Asm->TM.getRelocationModel() == Reloc::RWPI ||
                   Asm->TM.getRelocationModel() == Reloc::ROPI_RWPI) &&
                  !Asm->getObjFileLowering()
@@ -449,6 +466,39 @@ DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) {
   return ContextCU->updateSubprogramScopeDIEImpl(SP, SPDie);
 }
 
+// Add info for Wasm-global-based relocation.
+// 'GlobalIndex' is used for split dwarf, which currently relies on a few
+// assumptions that are not guaranteed in a formal way but work in practice.
+void DwarfCompileUnit::addWasmRelocBaseGlobal(DIELoc *Loc, StringRef GlobalName,
+                                              uint64_t GlobalIndex) {
+  // FIXME: duplicated from Target/WebAssembly/WebAssembly.h
+  // don't want to depend on target specific headers in this code?
+  const unsigned TI_GLOBAL_RELOC = 3;
+  unsigned PointerSize = Asm->getDataLayout().getPointerSize();
+  auto *Sym = cast<MCSymbolWasm>(Asm->GetExternalSymbolSymbol(GlobalName));
+  // FIXME: this repeats what WebAssemblyMCInstLower::
+  // GetExternalSymbolSymbol does, since if there's no code that
+  // refers to this symbol, we have to set it here.
+  Sym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
+  Sym->setGlobalType(wasm::WasmGlobalType{
+      static_cast<uint8_t>(PointerSize == 4 ? wasm::WASM_TYPE_I32
+                                            : wasm::WASM_TYPE_I64),
+      true});
+  addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_WASM_location);
+  addSInt(*Loc, dwarf::DW_FORM_sdata, TI_GLOBAL_RELOC);
+  if (!isDwoUnit()) {
+    addLabel(*Loc, dwarf::DW_FORM_data4, Sym);
+  } else {
+    // FIXME: when writing dwo, we need to avoid relocations. Probably
+    // the "right" solution is to treat globals the way func and data
+    // symbols are (with entries in .debug_addr).
+    // For now we hardcode the indices in the callsites. Global indices are not
+    // fixed, but in practice a few are fixed; for example, __stack_pointer is
+    // always index 0.
+    addUInt(*Loc, dwarf::DW_FORM_data4, GlobalIndex);
+  }
+}
+
 DIE &DwarfCompileUnit::updateSubprogramScopeDIEImpl(const DISubprogram *SP,
                                                     DIE *SPDie) {
   SmallVector<RangeSpan, 2> BB_List;
@@ -485,35 +535,14 @@ DIE &DwarfCompileUnit::updateSubprogramScopeDIEImpl(const DISubprogram *SP,
     }
     case TargetFrameLowering::DwarfFrameBase::WasmFrameBase: {
       // FIXME: duplicated from Target/WebAssembly/WebAssembly.h
-      // don't want to depend on target specific headers in this code?
       const unsigned TI_GLOBAL_RELOC = 3;
       if (FrameBase.Location.WasmLoc.Kind == TI_GLOBAL_RELOC) {
         // These need to be relocatable.
-        assert(FrameBase.Location.WasmLoc.Index == 0);  // Only SP so far.
-        auto SPSym = cast<MCSymbolWasm>(
-          Asm->GetExternalSymbolSymbol("__stack_pointer"));
-        // FIXME: this repeats what WebAssemblyMCInstLower::
-        // GetExternalSymbolSymbol does, since if there's no code that
-        // refers to this symbol, we have to set it here.
-        SPSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
-        SPSym->setGlobalType(wasm::WasmGlobalType{
-            uint8_t(Asm->getSubtargetInfo().getTargetTriple().getArch() ==
-                            Triple::wasm64
-                        ? wasm::WASM_TYPE_I64
-                        : wasm::WASM_TYPE_I32),
-            true});
         DIELoc *Loc = new (DIEValueAllocator) DIELoc;
-        addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_WASM_location);
-        addSInt(*Loc, dwarf::DW_FORM_sdata, TI_GLOBAL_RELOC);
-        if (!isDwoUnit()) {
-          addLabel(*Loc, dwarf::DW_FORM_data4, SPSym);
-        } else {
-          // FIXME: when writing dwo, we need to avoid relocations. Probably
-          // the "right" solution is to treat globals the way func and data
-          // symbols are (with entries in .debug_addr).
-          // For now, since we only ever use index 0, this should work as-is.
-          addUInt(*Loc, dwarf::DW_FORM_data4, FrameBase.Location.WasmLoc.Index);
-        }
+        assert(FrameBase.Location.WasmLoc.Index == 0); // Only SP so far.
+        // For now, since we only ever use index 0, this should work as-is.
+        addWasmRelocBaseGlobal(Loc, "__stack_pointer",
+                               FrameBase.Location.WasmLoc.Index);
         addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value);
         addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);
       } else {

diff  --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
index 7d87f35021bb4..5581b9144bab7 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
@@ -108,6 +108,10 @@ class DwarfCompileUnit final : public DwarfUnit {
 
   void finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) override;
 
+  /// Add info for Wasm-global-based relocation.
+  void addWasmRelocBaseGlobal(DIELoc *Loc, StringRef GlobalName,
+                              uint64_t GlobalIndex);
+
 public:
   DwarfCompileUnit(unsigned UID, const DICompileUnit *Node, AsmPrinter *A,
                    DwarfDebug *DW, DwarfFile *DWU,

diff  --git a/llvm/test/DebugInfo/WebAssembly/tls_pic_globals.ll b/llvm/test/DebugInfo/WebAssembly/tls_pic_globals.ll
new file mode 100644
index 0000000000000..cd837107ecc0b
--- /dev/null
+++ b/llvm/test/DebugInfo/WebAssembly/tls_pic_globals.ll
@@ -0,0 +1,182 @@
+; Non-PIC tests
+; RUN: sed -e 's/\[\[TLS_MODE\]\]/(localexec)/' %s | llc -filetype=obj -mattr=+bulk-memory,atomics - -o %t.localexec.o
+; RUN: sed -e 's/\[\[TLS_MODE\]\]//' %s | llc -filetype=obj -mattr=+bulk-memory,atomics - -o %t.generaldynamic.o
+; RUN: llvm-dwarfdump %t.localexec.o | FileCheck %s --check-prefixes=CHECK,NOPIC
+; RUN: llvm-dwarfdump %t.generaldynamic.o | FileCheck %s --check-prefixes=CHECK,NOPIC
+; RUN: llvm-readobj -r %t.localexec.o | FileCheck %s --check-prefixes=RELOCS-NOSPLIT
+; RUN: llvm-readobj -r %t.generaldynamic.o | FileCheck %s --check-prefixes=RELOCS-NOSPLIT
+
+; PIC tests
+; RUN: sed -e 's/\[\[TLS_MODE\]\]/(localexec)/' %s | llc -filetype=obj -mattr=+bulk-memory,atomics -relocation-model=pic - -o %t.localexec.pic.o
+; RUN: sed -e 's/\[\[TLS_MODE\]\]//' %s | llc -filetype=obj -mattr=+bulk-memory,atomics -relocation-model=pic - -o %t.generaldynamic.pic.o
+; RUN: llvm-dwarfdump %t.localexec.pic.o | FileCheck %s --check-prefixes=CHECK,PIC
+; RUN: llvm-dwarfdump %t.generaldynamic.pic.o | FileCheck %s --check-prefixes=CHECK,PIC
+; RUN: llvm-readobj -r %t.localexec.pic.o | FileCheck %s --check-prefixes=RELOCS-NOSPLIT,RELOCS-PIC-NOSPLIT
+; RUN: llvm-readobj -r %t.generaldynamic.pic.o | FileCheck %s --check-prefixes=RELOCS-NOSPLIT,RELOCS-PIC-NOSPLIT
+
+; Non-PIC + split DWARF tests
+; RUN: sed -e 's/\[\[TLS_MODE\]\]/(localexec)/' %s | llc -filetype=obj -mattr=+bulk-memory,atomics -split-dwarf-file=%t.localexec.split.dwo -split-dwarf-output=%t.localexec.split.dwo - -o %t.localexec.split.o
+; RUN: sed -e 's/\[\[TLS_MODE\]\]//' %s | llc -filetype=obj -mattr=+bulk-memory,atomics -split-dwarf-file=%t.generaldynamic.split.dwo -split-dwarf-output=%t.generaldynamic.split.dwo - -o %t.generaldynamic.split.o
+; RUN: llvm-dwarfdump %t.localexec.split.dwo | FileCheck %s --check-prefixes=CHECK,NOPIC
+; RUN: llvm-dwarfdump %t.generaldynamic.split.dwo | FileCheck %s --check-prefixes=CHECK,NOPIC
+; RUN: llvm-readobj -r %t.localexec.split.dwo | FileCheck %s --check-prefixes=RELOCS-SPLIT
+; RUN: llvm-readobj -r %t.generaldynamic.split.dwo | FileCheck %s --check-prefixes=RELOCS-SPLIT
+
+; PIC + split DWARF tests
+; RUN: sed -e 's/\[\[TLS_MODE\]\]/(localexec)/' %s | llc -filetype=obj -mattr=+bulk-memory,atomics -relocation-model=pic -split-dwarf-file=%t.localexec.pic.split.dwo -split-dwarf-output=%t.localexec.pic.split.dwo - -o %t.localexec.pic.split.o
+; RUN: sed -e 's/\[\[TLS_MODE\]\]//' %s | llc -filetype=obj -mattr=+bulk-memory,atomics -relocation-model=pic -split-dwarf-file=%t.generaldynamic.pic.split.dwo -split-dwarf-output=%t.generaldynamic.pic.split.dwo - -o %t.generaldynamic.pic.split.o
+; RUN: llvm-dwarfdump %t.localexec.pic.split.dwo | FileCheck %s --check-prefixes=CHECK,PIC
+; RUN: llvm-dwarfdump %t.generaldynamic.pic.split.dwo | FileCheck %s --check-prefixes=CHECK,PIC
+; RUN: llvm-readobj -r %t.localexec.pic.split.dwo | FileCheck %s --check-prefixes=RELOCS-SPLIT
+; RUN: llvm-readobj -r %t.generaldynamic.pic.split.dwo | FileCheck %s --check-prefixes=RELOCS-SPLIT
+
+; This test is generated from the following C code, after which some unnecessary
+; debug info is removed.
+
+; int external_var0 = 111;
+; int external_var1 = 222;
+; static int internal_var0 = 333;
+; static int internal_var1 = 444;
+; _Thread_local int external_tls_var0 = 555;
+; _Thread_local int external_tls_var1 = 666;
+; _Thread_local int internal_tls_var0 = 777;
+; _Thread_local int internal_tls_var1 = 888;
+;
+; void foo(int, int, int, int, int, int, int, int);
+;
+; void test_tls_pic_globals() {
+;   foo(external_var0, external_var1, internal_var0, internal_var1,
+;       external_tls_var0, external_tls_var1, internal_tls_var0,
+;       internal_tls_var1);
+; }
+
+target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-f128:64-n32:64-S128-ni:1:10:20"
+target triple = "wasm32-unknown-emscripten"
+
+ at external_var0 = global i32 111, align 4, !dbg !0
+ at external_var1 = global i32 222, align 4, !dbg !5
+ at internal_var0 = internal global i32 333, align 4, !dbg !8
+ at internal_var1 = internal global i32 444, align 4, !dbg !10
+ at external_tls_var0 = thread_local[[TLS_MODE]] global i32 555, align 4, !dbg !12
+ at external_tls_var1 = thread_local[[TLS_MODE]] global i32 666, align 4, !dbg !14
+ at internal_tls_var0 = internal thread_local[[TLS_MODE]] global i32 777, align 4, !dbg !16
+ at internal_tls_var1 = internal thread_local[[TLS_MODE]] global i32 888, align 4, !dbg !18
+
+define void @foo(i32, i32, i32, i32, i32, i32, i32, i32) {
+  ret void
+}
+
+define void @test_tls_pic_globals() !dbg !24 {
+entry:
+  %0 = load i32, ptr @external_var0, align 4
+  %1 = load i32, ptr @external_var1, align 4
+  %2 = load i32, ptr @internal_var0, align 4
+  %3 = load i32, ptr @internal_var1, align 4
+  %4 = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @external_tls_var0)
+  %5 = load i32, ptr %4, align 4
+  %6 = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @external_tls_var1)
+  %7 = load i32, ptr %6, align 4
+  %8 = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @internal_tls_var0)
+  %9 = load i32, ptr %8, align 4
+  %10 = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @internal_tls_var1)
+  %11 = load i32, ptr %10, align 4
+  call void @foo(i32 %0, i32 %1, i32 %2, i32 %3, i32 %5, i32 %7, i32 %9, i32 %11)
+  ret void
+}
+
+; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
+declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) #0
+
+attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!20, !21, !22, !23}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "external_var0", scope: !2, file: !3, line: 4, type: !7, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C11, file: !3, isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4)
+!3 = !DIFile(filename: "test.c", directory: "")
+!4 = !{!0, !5, !8, !10, !12, !14, !16, !18}
+!5 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression())
+!6 = distinct !DIGlobalVariable(name: "external_var1", scope: !2, file: !3, line: 4, 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: "internal_var0", scope: !2, file: !3, line: 6, type: !7, isLocal: true, isDefinition: true)
+!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression())
+!11 = distinct !DIGlobalVariable(name: "internal_var1", scope: !2, file: !3, line: 7, type: !7, isLocal: true, isDefinition: true)
+!12 = !DIGlobalVariableExpression(var: !13, expr: !DIExpression())
+!13 = distinct !DIGlobalVariable(name: "external_tls_var0", scope: !2, file: !3, line: 8, type: !7, isLocal: false, isDefinition: true)
+!14 = !DIGlobalVariableExpression(var: !15, expr: !DIExpression())
+!15 = distinct !DIGlobalVariable(name: "external_tls_var1", scope: !2, file: !3, line: 9, type: !7, isLocal: false, isDefinition: true)
+!16 = !DIGlobalVariableExpression(var: !17, expr: !DIExpression())
+!17 = distinct !DIGlobalVariable(name: "internal_tls_var0", scope: !2, file: !3, line: 9, type: !7, isLocal: true, isDefinition: true)
+!18 = !DIGlobalVariableExpression(var: !19, expr: !DIExpression())
+!19 = distinct !DIGlobalVariable(name: "internal_tls_var1", scope: !2, file: !3, line: 9, type: !7, isLocal: true, isDefinition: true)
+!20 = !{i32 7, !"Dwarf Version", i32 5}
+!21 = !{i32 2, !"Debug Info Version", i32 3}
+!22 = !{i32 1, !"wchar_size", i32 4}
+!23 = !{i32 8, !"PIC Level", i32 2}
+!24 = distinct !DISubprogram(name: "main", scope: !3, file: !3, line: 16, type: !25, spFlags: DISPFlagDefinition, unit: !2)
+!25 = !DISubroutineType(types: !26)
+!26 = !{null}
+
+; Tests if TLS variables and global variables in PIC mode have a correct debug
+; info location. TLS variables should have their location relative to __tls_base
+; global, and global variables in PIC objects should have their location
+; relative to __memory_base global.
+
+; CHECK:      DW_TAG_variable
+; CHECK-NEXT:   DW_AT_name  ("external_var0")
+; CHECK:        DW_AT_external  (true)
+; NOPIC:        DW_AT_location  (DW_OP_addrx 0x0)
+; PIC:          DW_AT_location  (DW_OP_WASM_location 0x3 0x{{[0-9]+}}, DW_OP_addrx 0x0, DW_OP_plus)
+
+; CHECK:      DW_TAG_variable
+; CHECK-NEXT:   DW_AT_name  ("external_var1")
+; CHECK:        DW_AT_external  (true)
+; NOPIC:        DW_AT_location  (DW_OP_addrx 0x1)
+; PIC:          DW_AT_location  (DW_OP_WASM_location 0x3 0x{{[0-9]+}}, DW_OP_addrx 0x1, DW_OP_plus)
+
+; CHECK:      DW_TAG_variable
+; CHECK-NEXT:   DW_AT_name  ("internal_var0")
+; NOPIC:        DW_AT_location  (DW_OP_addrx 0x2)
+; PIC:          DW_AT_location  (DW_OP_WASM_location 0x3 0x{{[0-9]+}}, DW_OP_addrx 0x2, DW_OP_plus)
+
+; CHECK:      DW_TAG_variable
+; CHECK-NEXT:   DW_AT_name  ("internal_var1")
+; NOPIC:        DW_AT_location  (DW_OP_addrx 0x3)
+; PIC:          DW_AT_location  (DW_OP_WASM_location 0x3 0x{{[0-9]+}}, DW_OP_addrx 0x3, DW_OP_plus)
+
+; CHECK:      DW_TAG_variable
+; CHECK-NEXT:   DW_AT_name  ("external_tls_var0")
+; CHECK:        DW_AT_external  (true)
+; CHECK:        DW_AT_location  (DW_OP_WASM_location 0x3 0x{{[0-9]+}}, DW_OP_addrx 0x4, DW_OP_plus)
+
+; CHECK:      DW_TAG_variable
+; CHECK-NEXT:   DW_AT_name  ("external_tls_var1")
+; CHECK:        DW_AT_external  (true)
+; CHECK:        DW_AT_location  (DW_OP_WASM_location 0x3 0x{{[0-9]+}}, DW_OP_addrx 0x5, DW_OP_plus)
+
+; CHECK:      DW_TAG_variable
+; CHECK-NEXT:   DW_AT_name  ("internal_tls_var0")
+; CHECK:        DW_AT_location  (DW_OP_WASM_location 0x3 0x{{[0-9]+}}, DW_OP_addrx 0x6, DW_OP_plus)
+
+; CHECK:      DW_TAG_variable
+; CHECK-NEXT:   DW_AT_name  ("internal_tls_var1")
+; CHECK:        DW_AT_location  (DW_OP_WASM_location 0x3 0x{{[0-9]+}}, DW_OP_addrx 0x7, DW_OP_plus)
+
+; In non-split DWARF, .debug_info section contains relocations referring to
+; __stack_pointer, __tls_base, and __memory_base (if used)
+
+; RELOCS-NOSPLIT:         Relocations [
+; RELOCS-NOSPLIT:           Section (8) .debug_info {
+; RELOCS-NOSPLIT-DAG:         0x{{.*}} R_WASM_GLOBAL_INDEX_I32 __tls_base
+; RELOCS-NOSPLIT-DAG:         0x{{.*}} R_WASM_GLOBAL_INDEX_I32 __stack_pointer
+; RELOCS-PIC-NOSPLIT-DAG:     0x{{.*}} R_WASM_GLOBAL_INDEX_I32 __memory_base
+; RELOCS-NOSPLIT:           }
+; RELOCS-NOSPLIT:           Section (9) .debug_str_offsets {
+
+; In split DWARF, there should be no relocations in .dwo files.
+
+; RELOCS-SPLIT:           Relocations [
+; RELOCS-SPLIT-NEXT:      ]


        


More information about the llvm-commits mailing list