Skip to content

Commit a0f4526

Browse files
committed
[WebAssembly] Fix split-dwarf not emitting DW_OP_WASM_location correctly
It was using the regular path for target indices that uses uleb, but TI_GLOBAL_RELOC needs to be uint32_t. Introduced here: https://reviews.llvm.org/D85685 Fixes: emscripten-core/emscripten#13240 Differential Revision: https://reviews.llvm.org/D97564
1 parent 011e7bc commit a0f4526

File tree

2 files changed

+67
-6
lines changed

2 files changed

+67
-6
lines changed

llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -447,10 +447,7 @@ DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) {
447447
// FIXME: duplicated from Target/WebAssembly/WebAssembly.h
448448
// don't want to depend on target specific headers in this code?
449449
const unsigned TI_GLOBAL_RELOC = 3;
450-
// FIXME: when writing dwo, we need to avoid relocations. Probably
451-
// the "right" solution is to treat globals the way func and data symbols
452-
// are (with entries in .debug_addr).
453-
if (FrameBase.Location.WasmLoc.Kind == TI_GLOBAL_RELOC && !isDwoUnit()) {
450+
if (FrameBase.Location.WasmLoc.Kind == TI_GLOBAL_RELOC) {
454451
// These need to be relocatable.
455452
assert(FrameBase.Location.WasmLoc.Index == 0); // Only SP so far.
456453
auto SPSym = cast<MCSymbolWasm>(
@@ -468,8 +465,16 @@ DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) {
468465
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
469466
addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_WASM_location);
470467
addSInt(*Loc, dwarf::DW_FORM_sdata, TI_GLOBAL_RELOC);
471-
addLabel(*Loc, dwarf::DW_FORM_data4, SPSym);
472-
DD->addArangeLabel(SymbolCU(this, SPSym));
468+
if (!isDwoUnit()) {
469+
addLabel(*Loc, dwarf::DW_FORM_data4, SPSym);
470+
DD->addArangeLabel(SymbolCU(this, SPSym));
471+
} else {
472+
// FIXME: when writing dwo, we need to avoid relocations. Probably
473+
// the "right" solution is to treat globals the way func and data
474+
// symbols are (with entries in .debug_addr).
475+
// For now, since we only ever use index 0, this should work as-is.
476+
addUInt(*Loc, dwarf::DW_FORM_data4, FrameBase.Location.WasmLoc.Index);
477+
}
473478
addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value);
474479
addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);
475480
} else {

llvm/test/MC/WebAssembly/dwarfdump.ll

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
; RUN: llc -filetype=obj %s -o - | llvm-dwarfdump - | FileCheck %s
2+
; RUN: llc -filetype=obj --split-dwarf-file=%t.dwo --split-dwarf-output=%t.dwo %s -o %t.o
3+
; RUN: llvm-dwarfdump %t.dwo | FileCheck %s -check-prefix=SPLIT
24

35
; CHECK: .debug_info contents:
46
; CHECK-NEXT: 0x00000000: Compile Unit: length = 0x0000006e, format = DWARF32, version = 0x0004, abbr_offset = 0x0000, addr_size = 0x04 (next unit at 0x00000072)
@@ -55,6 +57,60 @@
5557

5658
; CHECK: 0x00000071: NULL
5759

60+
61+
; SPLIT: .debug_info.dwo contents:
62+
; SPLIT-NEXT: 0x00000000: Compile Unit: length = 0x0000004c, format = DWARF32, version = 0x0004, abbr_offset = 0x0000, addr_size = 0x04 (next unit at 0x00000050)
63+
64+
; SPLIT: 0x0000000b: DW_TAG_compile_unit
65+
; SPLIT-NEXT: DW_AT_producer ("clang version 6.0.0 (trunk 315924) (llvm/trunk 315960)")
66+
; SPLIT-NEXT: DW_AT_language (DW_LANG_C99)
67+
; SPLIT-NEXT: DW_AT_name ("test.c")
68+
; SPLIT-NEXT: DW_AT_GNU_dwo_name ("{{.*}}dwarfdump.ll.tmp.dwo")
69+
; SPLIT-NEXT: DW_AT_GNU_dwo_id (0xad3151f12153fa17)
70+
71+
; SPLIT: 0x00000019: DW_TAG_variable
72+
; SPLIT-NEXT: DW_AT_name ("foo")
73+
; SPLIT-NEXT: DW_AT_type (0x00000024 "int*")
74+
; SPLIT-NEXT: DW_AT_external (true)
75+
; SPLIT-NEXT: DW_AT_decl_file (0x01)
76+
; SPLIT-NEXT: DW_AT_decl_line (4)
77+
; SPLIT-NEXT: DW_AT_location (DW_OP_GNU_addr_index 0x0)
78+
79+
; SPLIT: 0x00000024: DW_TAG_pointer_type
80+
; SPLIT-NEXT: DW_AT_type (0x00000029 "int")
81+
82+
; SPLIT: 0x00000029: DW_TAG_base_type
83+
; SPLIT-NEXT: DW_AT_name ("int")
84+
; SPLIT-NEXT: DW_AT_encoding (DW_ATE_signed)
85+
; SPLIT-NEXT: DW_AT_byte_size (0x04)
86+
87+
; SPLIT: 0x0000002d: DW_TAG_variable
88+
; SPLIT-NEXT: DW_AT_name ("ptr2")
89+
; SPLIT-NEXT: DW_AT_type (0x00000038 "void()*")
90+
; SPLIT-NEXT: DW_AT_external (true)
91+
; SPLIT-NEXT: DW_AT_decl_file (0x01)
92+
; SPLIT-NEXT: DW_AT_decl_line (5)
93+
; SPLIT-NEXT: DW_AT_location (DW_OP_GNU_addr_index 0x1)
94+
95+
; SPLIT: 0x00000038: DW_TAG_pointer_type
96+
; SPLIT-NEXT: DW_AT_type (0x0000003d "void()")
97+
98+
; SPLIT: 0x0000003d: DW_TAG_subroutine_type
99+
; SPLIT-NEXT: DW_AT_prototyped (true)
100+
101+
; SPLIT: 0x0000003e: DW_TAG_subprogram
102+
; SPLIT-NEXT: DW_AT_low_pc (indexed (00000002) address = <unresolved>)
103+
; SPLIT-NEXT: DW_AT_high_pc (0x00000002)
104+
; SPLIT-NEXT: DW_AT_frame_base (DW_OP_WASM_location 0x3 0x0, DW_OP_stack_value)
105+
; SPLIT-NEXT: DW_AT_name ("f2")
106+
; SPLIT-NEXT: DW_AT_decl_file (0x01)
107+
; SPLIT-NEXT: DW_AT_decl_line (2)
108+
; SPLIT-NEXT: DW_AT_prototyped (true)
109+
; SPLIT-NEXT: DW_AT_external (true)
110+
111+
; SPLIT: 0x0000004f: NULL
112+
113+
58114
target triple = "wasm32-unknown-unknown"
59115

60116
source_filename = "test.c"

0 commit comments

Comments
 (0)