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/include/llvm/BinaryFormat/WasmRelocs.def =================================================================== --- llvm/include/llvm/BinaryFormat/WasmRelocs.def +++ llvm/include/llvm/BinaryFormat/WasmRelocs.def @@ -15,3 +15,4 @@ WASM_RELOC(R_WASM_EVENT_INDEX_LEB, 10) WASM_RELOC(R_WASM_MEMORY_ADDR_REL_SLEB, 11) WASM_RELOC(R_WASM_TABLE_INDEX_REL_SLEB, 12) +WASM_RELOC(R_WASM_GLOBAL_INDEX_I32, 13) 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/MC/WasmObjectWriter.cpp =================================================================== --- llvm/lib/MC/WasmObjectWriter.cpp +++ llvm/lib/MC/WasmObjectWriter.cpp @@ -535,7 +535,9 @@ // useable. uint32_t WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry) { - if (RelEntry.Type == wasm::R_WASM_GLOBAL_INDEX_LEB && !RelEntry.Symbol->isGlobal()) { + if ((RelEntry.Type == wasm::R_WASM_GLOBAL_INDEX_LEB || + RelEntry.Type == wasm::R_WASM_GLOBAL_INDEX_I32) && + !RelEntry.Symbol->isGlobal()) { assert(GOTIndices.count(RelEntry.Symbol) > 0 && "symbol not found in GOT index space"); return GOTIndices[RelEntry.Symbol]; } @@ -554,6 +556,7 @@ return getRelocationIndexValue(RelEntry); case wasm::R_WASM_FUNCTION_INDEX_LEB: case wasm::R_WASM_GLOBAL_INDEX_LEB: + case wasm::R_WASM_GLOBAL_INDEX_I32: case wasm::R_WASM_EVENT_INDEX_LEB: // Provisional value is function/global/event Wasm index assert(WasmIndices.count(RelEntry.Symbol) > 0 && "symbol not found in wasm index space"); @@ -658,6 +661,7 @@ case wasm::R_WASM_MEMORY_ADDR_I32: case wasm::R_WASM_FUNCTION_OFFSET_I32: case wasm::R_WASM_SECTION_OFFSET_I32: + case wasm::R_WASM_GLOBAL_INDEX_I32: writeI32(Stream, Value, Offset); break; case wasm::R_WASM_TABLE_INDEX_SLEB: Index: llvm/lib/Object/RelocationResolver.cpp =================================================================== --- llvm/lib/Object/RelocationResolver.cpp +++ llvm/lib/Object/RelocationResolver.cpp @@ -498,6 +498,7 @@ case wasm::R_WASM_FUNCTION_OFFSET_I32: case wasm::R_WASM_SECTION_OFFSET_I32: case wasm::R_WASM_EVENT_INDEX_LEB: + case wasm::R_WASM_GLOBAL_INDEX_I32: return true; default: return false; @@ -517,6 +518,7 @@ case wasm::R_WASM_FUNCTION_OFFSET_I32: case wasm::R_WASM_SECTION_OFFSET_I32: case wasm::R_WASM_EVENT_INDEX_LEB: + case wasm::R_WASM_GLOBAL_INDEX_I32: // For wasm section, its offset at 0 -- ignoring Value return A; default: Index: llvm/lib/Object/WasmObjectFile.cpp =================================================================== --- llvm/lib/Object/WasmObjectFile.cpp +++ llvm/lib/Object/WasmObjectFile.cpp @@ -798,6 +798,11 @@ return make_error("Bad relocation global index", object_error::parse_failed); break; + case wasm::R_WASM_GLOBAL_INDEX_I32: + if (!isValidGlobalSymbol(Reloc.Index)) + return make_error("Bad relocation global index", + object_error::parse_failed); + break; case wasm::R_WASM_EVENT_INDEX_LEB: if (!isValidEventSymbol(Reloc.Index)) return make_error("Bad relocation event index", Index: llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp =================================================================== --- llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp +++ llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp @@ -103,6 +103,8 @@ case FK_Data_4: if (SymA.isFunction()) return wasm::R_WASM_TABLE_INDEX_I32; + if (SymA.isGlobal()) + return wasm::R_WASM_GLOBAL_INDEX_I32; if (auto Section = static_cast( getFixupSection(Fixup.getValue()))) { if (Section->getKind().isText()) 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)