Index: llvm/include/llvm/BinaryFormat/Dwarf.def =================================================================== --- llvm/include/llvm/BinaryFormat/Dwarf.def +++ llvm/include/llvm/BinaryFormat/Dwarf.def @@ -660,6 +660,7 @@ HANDLE_DW_OP(0xe0, GNU_push_tls_address, 0, GNU) // Extensions for WebAssembly. HANDLE_DW_OP(0xed, WASM_location, 0, WASM) +HANDLE_DW_OP(0xee, WASM_location_int, 0, WASM) // The GNU entry value extension. HANDLE_DW_OP(0xf3, GNU_entry_value, 0, GNU) // Extensions for Fission proposal. Index: llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -421,13 +421,28 @@ break; } case TargetFrameLowering::DwarfFrameBase::WasmFrameBase: { - DIELoc *Loc = new (DIEValueAllocator) DIELoc; - DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); - DIExpressionCursor Cursor({}); - DwarfExpr.addWasmLocation(FrameBase.Location.WasmLoc.Kind, - FrameBase.Location.WasmLoc.Index); - DwarfExpr.addExpression(std::move(Cursor)); - addBlock(*SPDie, dwarf::DW_AT_frame_base, DwarfExpr.finalize()); + // FIXME: don't want to depend on target specific headers? + 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 = Asm->GetExternalSymbolSymbol("__stack_pointer"); + DIELoc *Loc = new (DIEValueAllocator) DIELoc; + addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_WASM_location_int); + addSInt(*Loc, dwarf::DW_FORM_sdata, FrameBase.Location.WasmLoc.Kind); + addLabel(*Loc, dwarf::DW_FORM_udata, SPSym); + DD->addArangeLabel(SymbolCU(this, SPSym)); + addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value); + addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc); + } else { + DIELoc *Loc = new (DIEValueAllocator) DIELoc; + DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); + DIExpressionCursor Cursor({}); + DwarfExpr.addWasmLocation(FrameBase.Location.WasmLoc.Kind, + FrameBase.Location.WasmLoc.Index); + DwarfExpr.addExpression(std::move(Cursor)); + addBlock(*SPDie, dwarf::DW_AT_frame_base, DwarfExpr.finalize()); + } break; } } Index: llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp @@ -95,6 +95,8 @@ Descriptions[DW_OP_stack_value] = Desc(Op::Dwarf3); Descriptions[DW_OP_WASM_location] = Desc(Op::Dwarf4, Op::SizeLEB, Op::SignedSizeLEB); + Descriptions[DW_OP_WASM_location_int] = + Desc(Op::Dwarf4, Op::SizeLEB, Op::SignedSize4); Descriptions[DW_OP_GNU_push_tls_address] = Desc(Op::Dwarf3); Descriptions[DW_OP_addrx] = Desc(Op::Dwarf4, Op::SizeLEB); Descriptions[DW_OP_GNU_addr_index] = Desc(Op::Dwarf4, Op::SizeLEB); Index: llvm/lib/Object/WasmObjectFile.cpp =================================================================== --- llvm/lib/Object/WasmObjectFile.cpp +++ llvm/lib/Object/WasmObjectFile.cpp @@ -807,7 +807,7 @@ case wasm::R_WASM_MEMORY_ADDR_SLEB: case wasm::R_WASM_MEMORY_ADDR_I32: case wasm::R_WASM_MEMORY_ADDR_REL_SLEB: - if (!isValidDataSymbol(Reloc.Index)) + if (!isValidDataSymbol(Reloc.Index) && !isValidGlobalSymbol(Reloc.Index)) return make_error("Bad relocation data index", object_error::parse_failed); Reloc.Addend = readVarint32(Ctx); Index: llvm/lib/Target/WebAssembly/WebAssembly.h =================================================================== --- llvm/lib/Target/WebAssembly/WebAssembly.h +++ llvm/lib/Target/WebAssembly/WebAssembly.h @@ -78,7 +78,16 @@ void initializeWebAssemblyPeepholePass(PassRegistry &); namespace WebAssembly { -enum TargetIndex { TI_LOCAL_START, TI_GLOBAL_START, TI_OPERAND_STACK_START }; +enum TargetIndex { + // Followed by a local index (LEB). + TI_LOCAL, + // Followed by an absolute global index (LEB). DEPRECATED. + TI_GLOBAL_FIXED, + TI_OPERAND_STACK, + // Followed by a compilation unit relative global index (int32_t) + // that will have an associated relocation. + TI_GLOBAL_RELOC +}; } // end namespace WebAssembly } // end namespace llvm Index: llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp =================================================================== --- llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp +++ llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp @@ -48,6 +48,6 @@ void WebAssemblyDebugValueManager::replaceWithLocal(unsigned LocalId) { for (auto *DBI : DbgValues) { MachineOperand &Op = DBI->getOperand(0); - Op.ChangeToTargetIndex(llvm::WebAssembly::TI_LOCAL_START, LocalId); + Op.ChangeToTargetIndex(llvm::WebAssembly::TI_LOCAL, LocalId); } } Index: llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp =================================================================== --- llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp +++ llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp @@ -268,12 +268,11 @@ const WebAssemblyFunctionInfo &MFI = *MF.getInfo(); if (needsSP(MF) && MFI.isFrameBaseVirtual()) { unsigned LocalNum = MFI.getFrameBaseLocal(); - Loc.Location.WasmLoc = {WebAssembly::TI_LOCAL_START, LocalNum}; + Loc.Location.WasmLoc = {WebAssembly::TI_LOCAL, LocalNum}; } else { // TODO: This should work on a breakpoint at a function with no frame, // but probably won't work for traversing up the stack. - // TODO: This needs a relocation for correct __stack_pointer - Loc.Location.WasmLoc = {WebAssembly::TI_GLOBAL_START, 0}; + Loc.Location.WasmLoc = {WebAssembly::TI_GLOBAL_RELOC, 0}; } return Loc; } Index: llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp =================================================================== --- llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp +++ llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp @@ -235,8 +235,9 @@ ArrayRef> WebAssemblyInstrInfo::getSerializableTargetIndices() const { static const std::pair TargetIndices[] = { - {WebAssembly::TI_LOCAL_START, "wasm-local-start"}, - {WebAssembly::TI_GLOBAL_START, "wasm-global-start"}, - {WebAssembly::TI_OPERAND_STACK_START, "wasm-operator-stack-start"}}; + {WebAssembly::TI_LOCAL, "wasm-local-start"}, + {WebAssembly::TI_GLOBAL_FIXED, "wasm-global-start"}, + {WebAssembly::TI_OPERAND_STACK, "wasm-operator-stack-start"}, + {WebAssembly::TI_GLOBAL_RELOC, "wasm-global-start-reloc"}}; return makeArrayRef(TargetIndices); } Index: llvm/test/CodeGen/WebAssembly/debugtest-opt.ll =================================================================== --- llvm/test/CodeGen/WebAssembly/debugtest-opt.ll +++ llvm/test/CodeGen/WebAssembly/debugtest-opt.ll @@ -11,7 +11,7 @@ ; CHECK-NEXT: DW_AT_low_pc ; CHECK-NEXT: DW_AT_high_pc ;; Check that we fall back to the default frame base (the global) -; CHECK-NEXT: DW_AT_frame_base (DW_OP_WASM_location 0x1 +0, DW_OP_stack_value) +; CHECK-NEXT: DW_AT_frame_base (DW_OP_WASM_location_int 0x3 +0, DW_OP_stack_value) ; TODO: Find a more-reduced test case for The fix in WebAssemblyRegColoring Index: llvm/test/MC/WebAssembly/dwarfdump.ll =================================================================== --- llvm/test/MC/WebAssembly/dwarfdump.ll +++ llvm/test/MC/WebAssembly/dwarfdump.ll @@ -46,7 +46,7 @@ ; CHECK: 0x0000005a: DW_TAG_subprogram ; CHECK-NEXT: DW_AT_low_pc (0x0000000000000002) ; CHECK-NEXT: DW_AT_high_pc (0x0000000000000004) -; CHECK-NEXT: DW_AT_frame_base (DW_OP_WASM_location 0x1 +0, DW_OP_stack_value) +; CHECK-NEXT: DW_AT_frame_base (DW_OP_WASM_location_int 0x3 +0, DW_OP_stack_value) ; CHECK-NEXT: DW_AT_name ("f2") ; CHECK-NEXT: DW_AT_decl_file ("/usr/local/google/home/sbc/dev/wasm/simple{{[/\\]}}test.c") ; CHECK-NEXT: DW_AT_decl_line (2)