diff --git a/lld/wasm/InputChunks.cpp b/lld/wasm/InputChunks.cpp --- a/lld/wasm/InputChunks.cpp +++ b/lld/wasm/InputChunks.cpp @@ -59,7 +59,9 @@ ExistingValue = decodeULEB128(Loc, &BytesRead); break; case R_WASM_TABLE_INDEX_SLEB: + case R_WASM_TABLE_INDEX_REL_SLEB: case R_WASM_MEMORY_ADDR_SLEB: + case R_WASM_MEMORY_ADDR_REL_SLEB: ExistingValue = static_cast(decodeSLEB128(Loc, &BytesRead)); break; case R_WASM_TABLE_INDEX_I32: @@ -119,7 +121,9 @@ encodeULEB128(Value, Loc, 5); break; case R_WASM_TABLE_INDEX_SLEB: + case R_WASM_TABLE_INDEX_REL_SLEB: case R_WASM_MEMORY_ADDR_SLEB: + case R_WASM_MEMORY_ADDR_REL_SLEB: encodeSLEB128(static_cast(Value), Loc, 5); break; case R_WASM_TABLE_INDEX_I32: diff --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp --- a/lld/wasm/InputFiles.cpp +++ b/lld/wasm/InputFiles.cpp @@ -99,13 +99,15 @@ uint32_t ObjFile::calcExpectedValue(const WasmRelocation &Reloc) const { switch (Reloc.Type) { case R_WASM_TABLE_INDEX_I32: - case R_WASM_TABLE_INDEX_SLEB: { + case R_WASM_TABLE_INDEX_SLEB: + case R_WASM_TABLE_INDEX_REL_SLEB: { const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index]; return TableEntries[Sym.Info.ElementIndex]; } case R_WASM_MEMORY_ADDR_SLEB: case R_WASM_MEMORY_ADDR_I32: - case R_WASM_MEMORY_ADDR_LEB: { + case R_WASM_MEMORY_ADDR_LEB: + case R_WASM_MEMORY_ADDR_REL_SLEB: { const WasmSymbol &Sym = WasmObj->syms()[Reloc.Index]; if (Sym.isUndefined()) return 0; @@ -140,10 +142,12 @@ switch (Reloc.Type) { case R_WASM_TABLE_INDEX_I32: case R_WASM_TABLE_INDEX_SLEB: + case R_WASM_TABLE_INDEX_REL_SLEB: return getFunctionSymbol(Reloc.Index)->getTableIndex(); case R_WASM_MEMORY_ADDR_SLEB: case R_WASM_MEMORY_ADDR_I32: case R_WASM_MEMORY_ADDR_LEB: + case R_WASM_MEMORY_ADDR_REL_SLEB: if (auto *Sym = dyn_cast(getDataSymbol(Reloc.Index))) if (Sym->isLive()) return Sym->getVirtualAddress() + Reloc.Addend; diff --git a/llvm/include/llvm/BinaryFormat/WasmRelocs.def b/llvm/include/llvm/BinaryFormat/WasmRelocs.def --- a/llvm/include/llvm/BinaryFormat/WasmRelocs.def +++ b/llvm/include/llvm/BinaryFormat/WasmRelocs.def @@ -2,14 +2,16 @@ #error "WASM_RELOC must be defined" #endif -WASM_RELOC(R_WASM_FUNCTION_INDEX_LEB, 0) -WASM_RELOC(R_WASM_TABLE_INDEX_SLEB, 1) -WASM_RELOC(R_WASM_TABLE_INDEX_I32, 2) -WASM_RELOC(R_WASM_MEMORY_ADDR_LEB, 3) -WASM_RELOC(R_WASM_MEMORY_ADDR_SLEB, 4) -WASM_RELOC(R_WASM_MEMORY_ADDR_I32, 5) -WASM_RELOC(R_WASM_TYPE_INDEX_LEB, 6) -WASM_RELOC(R_WASM_GLOBAL_INDEX_LEB, 7) -WASM_RELOC(R_WASM_FUNCTION_OFFSET_I32, 8) -WASM_RELOC(R_WASM_SECTION_OFFSET_I32, 9) -WASM_RELOC(R_WASM_EVENT_INDEX_LEB, 10) +WASM_RELOC(R_WASM_FUNCTION_INDEX_LEB, 0) +WASM_RELOC(R_WASM_TABLE_INDEX_SLEB, 1) +WASM_RELOC(R_WASM_TABLE_INDEX_I32, 2) +WASM_RELOC(R_WASM_MEMORY_ADDR_LEB, 3) +WASM_RELOC(R_WASM_MEMORY_ADDR_SLEB, 4) +WASM_RELOC(R_WASM_MEMORY_ADDR_I32, 5) +WASM_RELOC(R_WASM_TYPE_INDEX_LEB, 6) +WASM_RELOC(R_WASM_GLOBAL_INDEX_LEB, 7) +WASM_RELOC(R_WASM_FUNCTION_OFFSET_I32, 8) +WASM_RELOC(R_WASM_SECTION_OFFSET_I32, 9) +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) diff --git a/llvm/include/llvm/MC/MCExpr.h b/llvm/include/llvm/MC/MCExpr.h --- a/llvm/include/llvm/MC/MCExpr.h +++ b/llvm/include/llvm/MC/MCExpr.h @@ -284,7 +284,9 @@ VK_Hexagon_IE, VK_Hexagon_IE_GOT, - VK_WebAssembly_TYPEINDEX,// Reference to a symbol's type (signature) + VK_WASM_TYPEINDEX, // Reference to a symbol's type (signature) + VK_WASM_MBREL, // Memory address relative to memory base + VK_WASM_TBREL, // Table index relative to table bare VK_AMDGPU_GOTPCREL32_LO, // symbol@gotpcrel32@lo VK_AMDGPU_GOTPCREL32_HI, // symbol@gotpcrel32@hi diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp --- a/llvm/lib/MC/MCExpr.cpp +++ b/llvm/lib/MC/MCExpr.cpp @@ -302,7 +302,9 @@ case VK_Hexagon_LD_PLT: return "LDPLT"; case VK_Hexagon_IE: return "IE"; case VK_Hexagon_IE_GOT: return "IEGOT"; - case VK_WebAssembly_TYPEINDEX: return "TYPEINDEX"; + case VK_WASM_TYPEINDEX: return "TYPEINDEX"; + case VK_WASM_MBREL: return "MBREL"; + case VK_WASM_TBREL: return "TBREL"; case VK_AMDGPU_GOTPCREL32_LO: return "gotpcrel32@lo"; case VK_AMDGPU_GOTPCREL32_HI: return "gotpcrel32@hi"; case VK_AMDGPU_REL32_LO: return "rel32@lo"; @@ -415,7 +417,9 @@ .Case("lo8", VK_AVR_LO8) .Case("hi8", VK_AVR_HI8) .Case("hlo8", VK_AVR_HLO8) - .Case("typeindex", VK_WebAssembly_TYPEINDEX) + .Case("typeindex", VK_WASM_TYPEINDEX) + .Case("tbrel", VK_WASM_TBREL) + .Case("mbrel", VK_WASM_MBREL) .Case("gotpcrel32@lo", VK_AMDGPU_GOTPCREL32_LO) .Case("gotpcrel32@hi", VK_AMDGPU_GOTPCREL32_HI) .Case("rel32@lo", VK_AMDGPU_REL32_LO) diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp --- a/llvm/lib/MC/WasmObjectWriter.cpp +++ b/llvm/lib/MC/WasmObjectWriter.cpp @@ -151,6 +151,7 @@ switch (Type) { case wasm::R_WASM_MEMORY_ADDR_LEB: case wasm::R_WASM_MEMORY_ADDR_SLEB: + case wasm::R_WASM_MEMORY_ADDR_REL_SLEB: case wasm::R_WASM_MEMORY_ADDR_I32: case wasm::R_WASM_FUNCTION_OFFSET_I32: case wasm::R_WASM_SECTION_OFFSET_I32: @@ -269,9 +270,6 @@ // TargetObjectWriter wrappers. bool is64Bit() const { return TargetObjectWriter->is64Bit(); } - unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup) const { - return TargetObjectWriter->getRelocType(Target, Fixup); - } void startSection(SectionBookkeeping &Section, unsigned SectionId); void startCustomSection(SectionBookkeeping &Section, StringRef Name); @@ -508,7 +506,7 @@ // be negative and don't wrap. FixedValue = 0; - unsigned Type = getRelocType(Target, Fixup); + unsigned Type = TargetObjectWriter->getRelocType(Target, Fixup); assert(!IsPCRel); assert(SymA); @@ -583,6 +581,7 @@ } switch (RelEntry.Type) { + case wasm::R_WASM_TABLE_INDEX_REL_SLEB: case wasm::R_WASM_TABLE_INDEX_SLEB: case wasm::R_WASM_TABLE_INDEX_I32: { // Provisional value is table address of the resolved symbol itself @@ -607,6 +606,7 @@ } case wasm::R_WASM_MEMORY_ADDR_LEB: case wasm::R_WASM_MEMORY_ADDR_I32: + case wasm::R_WASM_MEMORY_ADDR_REL_SLEB: case wasm::R_WASM_MEMORY_ADDR_SLEB: { // Provisional value is address of the global const MCSymbolWasm *Sym = resolveSymbol(*RelEntry.Symbol); @@ -701,7 +701,9 @@ writeI32(Stream, Value, Offset); break; case wasm::R_WASM_TABLE_INDEX_SLEB: + case wasm::R_WASM_TABLE_INDEX_REL_SLEB: case wasm::R_WASM_MEMORY_ADDR_SLEB: + case wasm::R_WASM_MEMORY_ADDR_REL_SLEB: writePatchableSLEB(Stream, Value, Offset); break; default: diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp --- a/llvm/lib/Object/WasmObjectFile.cpp +++ b/llvm/lib/Object/WasmObjectFile.cpp @@ -767,6 +767,7 @@ case wasm::R_WASM_FUNCTION_INDEX_LEB: case wasm::R_WASM_TABLE_INDEX_SLEB: case wasm::R_WASM_TABLE_INDEX_I32: + case wasm::R_WASM_TABLE_INDEX_REL_SLEB: if (!isValidFunctionSymbol(Reloc.Index)) return make_error("Bad relocation function index", object_error::parse_failed); @@ -793,6 +794,7 @@ case wasm::R_WASM_MEMORY_ADDR_LEB: 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)) return make_error("Bad relocation data index", object_error::parse_failed); diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp @@ -75,9 +75,9 @@ // WebAssemblyFixupKinds.h. // // Name Offset (bits) Size (bits) Flags - {"fixup_code_sleb128_i32", 0, 5 * 8, 0}, - {"fixup_code_sleb128_i64", 0, 10 * 8, 0}, - {"fixup_code_uleb128_i32", 0, 5 * 8, 0}, + {"fixup_sleb128_i32", 0, 5 * 8, 0}, + {"fixup_sleb128_i64", 0, 10 * 8, 0}, + {"fixup_uleb128_i32", 0, 5 * 8, 0}, }; if (Kind < FirstTargetFixupKind) diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyFixupKinds.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyFixupKinds.h --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyFixupKinds.h +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyFixupKinds.h @@ -14,9 +14,9 @@ namespace llvm { namespace WebAssembly { enum Fixups { - fixup_code_sleb128_i32 = FirstTargetFixupKind, // 32-bit signed - fixup_code_sleb128_i64, // 64-bit signed - fixup_code_uleb128_i32, // 32-bit unsigned + fixup_sleb128_i32 = FirstTargetFixupKind, // 32-bit signed + fixup_sleb128_i64, // 64-bit signed + fixup_uleb128_i32, // 32-bit unsigned // Marker LastTargetFixupKind, diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp @@ -144,10 +144,10 @@ size_t PaddedSize = 5; switch (Info.OperandType) { case WebAssembly::OPERAND_I32IMM: - FixupKind = MCFixupKind(WebAssembly::fixup_code_sleb128_i32); + FixupKind = MCFixupKind(WebAssembly::fixup_sleb128_i32); break; case WebAssembly::OPERAND_I64IMM: - FixupKind = MCFixupKind(WebAssembly::fixup_code_sleb128_i64); + FixupKind = MCFixupKind(WebAssembly::fixup_sleb128_i64); PaddedSize = 10; break; case WebAssembly::OPERAND_FUNCTION32: @@ -155,7 +155,7 @@ case WebAssembly::OPERAND_TYPEINDEX: case WebAssembly::OPERAND_GLOBAL: case WebAssembly::OPERAND_EVENT: - FixupKind = MCFixupKind(WebAssembly::fixup_code_uleb128_i32); + FixupKind = MCFixupKind(WebAssembly::fixup_uleb128_i32); break; default: llvm_unreachable("unexpected symbolic operand kind"); diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h @@ -89,15 +89,11 @@ enum TOF { MO_NO_FLAG = 0, - // Flags to indicate the type of the symbol being referenced - MO_SYMBOL_FUNCTION = 0x1, - MO_SYMBOL_GLOBAL = 0x2, - MO_SYMBOL_EVENT = 0x4, - MO_SYMBOL_MASK = 0x7, - // Address of data symbol via a wasm global. This adds a level of indirection // similar to the GOT on native platforms. - MO_GOT = 0x8, + MO_GOT, + MO_MEMORY_BASE_REL, + MO_TABLE_BASE_REL, }; } // end namespace WebAssemblyII diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp @@ -42,14 +42,6 @@ WebAssemblyWasmObjectWriter::WebAssemblyWasmObjectWriter(bool Is64Bit) : MCWasmObjectTargetWriter(Is64Bit) {} -static bool isFunctionSignatureRef(const MCSymbolRefExpr *Ref) { - return Ref->getKind() == MCSymbolRefExpr::VK_WebAssembly_TYPEINDEX; -} - -static bool isGOTRef(const MCSymbolRefExpr *Ref) { - return Ref->getKind() == MCSymbolRefExpr::VK_GOT; -} - static const MCSection *getFixupSection(const MCExpr *Expr) { if (auto SyExp = dyn_cast(Expr)) { if (SyExp->getSymbol().isInSection()) @@ -75,22 +67,35 @@ assert(RefA); auto& SymA = cast(RefA->getSymbol()); + MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant(); + + switch (Modifier) { + case MCSymbolRefExpr::VK_GOT: + return wasm::R_WASM_GLOBAL_INDEX_LEB; + case MCSymbolRefExpr::VK_WASM_TBREL: + assert(SymA.isFunction()); + return wasm::R_WASM_TABLE_INDEX_REL_SLEB; + case MCSymbolRefExpr::VK_WASM_MBREL: + assert(SymA.isData()); + return wasm::R_WASM_MEMORY_ADDR_REL_SLEB; + case MCSymbolRefExpr::VK_WASM_TYPEINDEX: + return wasm::R_WASM_TYPE_INDEX_LEB; + default: + break; + } + switch (unsigned(Fixup.getKind())) { - case WebAssembly::fixup_code_sleb128_i32: + case WebAssembly::fixup_sleb128_i32: if (SymA.isFunction()) return wasm::R_WASM_TABLE_INDEX_SLEB; return wasm::R_WASM_MEMORY_ADDR_SLEB; - case WebAssembly::fixup_code_sleb128_i64: + case WebAssembly::fixup_sleb128_i64: llvm_unreachable("fixup_sleb128_i64 not implemented yet"); - case WebAssembly::fixup_code_uleb128_i32: - if (SymA.isGlobal() || isGOTRef(RefA)) + case WebAssembly::fixup_uleb128_i32: + if (SymA.isGlobal()) return wasm::R_WASM_GLOBAL_INDEX_LEB; - if (SymA.isFunction()) { - if (isFunctionSignatureRef(RefA)) - return wasm::R_WASM_TYPE_INDEX_LEB; - else - return wasm::R_WASM_FUNCTION_INDEX_LEB; - } + if (SymA.isFunction()) + return wasm::R_WASM_FUNCTION_INDEX_LEB; if (SymA.isEvent()) return wasm::R_WASM_EVENT_INDEX_LEB; return wasm::R_WASM_MEMORY_ADDR_LEB; @@ -105,8 +110,6 @@ return wasm::R_WASM_SECTION_OFFSET_I32; } return wasm::R_WASM_MEMORY_ADDR_I32; - case FK_Data_8: - llvm_unreachable("FK_Data_8 not implemented yet"); default: llvm_unreachable("unimplemented fixup kind"); } diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp --- a/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp @@ -130,7 +130,7 @@ const char *ES = "__stack_pointer"; auto *SPSymbol = MF.createExternalSymbolName(ES); BuildMI(MBB, InsertStore, DL, TII->get(WebAssembly::GLOBAL_SET_I32)) - .addExternalSymbol(SPSymbol, WebAssemblyII::MO_SYMBOL_GLOBAL) + .addExternalSymbol(SPSymbol) .addReg(SrcReg); } @@ -177,7 +177,7 @@ const char *ES = "__stack_pointer"; auto *SPSymbol = MF.createExternalSymbolName(ES); BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::GLOBAL_GET_I32), SPReg) - .addExternalSymbol(SPSymbol, WebAssemblyII::MO_SYMBOL_GLOBAL); + .addExternalSymbol(SPSymbol); bool HasBP = hasBP(MF); if (HasBP) { diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -996,34 +996,39 @@ if (GA->getAddressSpace() != 0) fail(DL, DAG, "WebAssembly only expects the 0 address space"); - unsigned Flags = 0; + unsigned OperandFlags = 0; if (isPositionIndependent()) { const GlobalValue *GV = GA->getGlobal(); if (getTargetMachine().shouldAssumeDSOLocal(*GV->getParent(), GV)) { MachineFunction &MF = DAG.getMachineFunction(); MVT PtrVT = getPointerTy(MF.getDataLayout()); const char *BaseName; - if (GV->getValueType()->isFunctionTy()) + if (GV->getValueType()->isFunctionTy()) { BaseName = MF.createExternalSymbolName("__table_base"); - else + OperandFlags = WebAssemblyII::MO_TABLE_BASE_REL; + } + else { BaseName = MF.createExternalSymbolName("__memory_base"); + OperandFlags = WebAssemblyII::MO_MEMORY_BASE_REL; + } SDValue BaseAddr = DAG.getNode(WebAssemblyISD::Wrapper, DL, PtrVT, DAG.getTargetExternalSymbol(BaseName, PtrVT)); SDValue SymAddr = DAG.getNode( WebAssemblyISD::WrapperPIC, DL, VT, - DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT, GA->getOffset())); + DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT, GA->getOffset(), + OperandFlags)); return DAG.getNode(ISD::ADD, DL, VT, BaseAddr, SymAddr); } else { - Flags |= WebAssemblyII::MO_GOT; + OperandFlags = WebAssemblyII::MO_GOT; } } return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT, DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT, - GA->getOffset(), Flags)); + GA->getOffset(), OperandFlags)); } SDValue @@ -1034,15 +1039,8 @@ EVT VT = Op.getValueType(); assert(ES->getTargetFlags() == 0 && "Unexpected target flags on generic ExternalSymbolSDNode"); - // Set the TargetFlags to MO_SYMBOL_FUNCTION which indicates that this is a - // "function" symbol rather than a data symbol. We do this unconditionally - // even though we don't know anything about the symbol other than its name, - // because all external symbols used in target-independent SelectionDAG code - // are for functions. - return DAG.getNode( - WebAssemblyISD::Wrapper, DL, VT, - DAG.getTargetExternalSymbol(ES->getSymbol(), VT, - WebAssemblyII::MO_SYMBOL_FUNCTION)); + return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT, + DAG.getTargetExternalSymbol(ES->getSymbol(), VT)); } SDValue WebAssemblyTargetLowering::LowerJumpTable(SDValue Op, @@ -1136,10 +1134,8 @@ const TargetLowering &TLI = DAG.getTargetLoweringInfo(); MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout()); const char *SymName = MF.createExternalSymbolName("__cpp_exception"); - SDValue SymNode = - DAG.getNode(WebAssemblyISD::Wrapper, DL, PtrVT, - DAG.getTargetExternalSymbol( - SymName, PtrVT, WebAssemblyII::MO_SYMBOL_EVENT)); + SDValue SymNode = DAG.getNode(WebAssemblyISD::Wrapper, DL, PtrVT, + DAG.getTargetExternalSymbol(SymName, PtrVT)); return DAG.getNode(WebAssemblyISD::THROW, DL, MVT::Other, // outchain type { diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp @@ -199,7 +199,7 @@ const char *CPPExnSymbol = MF.createExternalSymbolName("__cpp_exception"); BuildMI(&MBB, DL, get(WebAssembly::BR_ON_EXN)) .addMBB(TBB) - .addExternalSymbol(CPPExnSymbol, WebAssemblyII::MO_SYMBOL_EVENT) + .addExternalSymbol(CPPExnSymbol) .add(Cond[1]); } else BuildMI(&MBB, DL, get(WebAssembly::BR_IF)).addMBB(TBB).add(Cond[1]); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp --- a/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp @@ -307,7 +307,7 @@ const char *CPPExnSymbol = MF.createExternalSymbolName("__cpp_exception"); BuildMI(EHPad, DL, TII.get(WebAssembly::BR_ON_EXN)) .addMBB(ThenMBB) - .addExternalSymbol(CPPExnSymbol, WebAssemblyII::MO_SYMBOL_EVENT) + .addExternalSymbol(CPPExnSymbol) .addReg(ExnReg); BuildMI(EHPad, DL, TII.get(WebAssembly::BR)).addMBB(ElseMBB); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp --- a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp @@ -123,21 +123,31 @@ MCOperand WebAssemblyMCInstLower::lowerSymbolOperand( MCSymbol *Sym, int64_t Offset, bool IsFunc, unsigned TargetFlags) const { MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None; - if (TargetFlags & WebAssemblyII::MO_GOT) - Kind = MCSymbolRefExpr::VK_GOT; + + dbgs() << "lowerSymbolOperand: " << TargetFlags << "\n"; + switch (TargetFlags) { + case WebAssemblyII::MO_NO_FLAG: + break; + case WebAssemblyII::MO_GOT: + Kind = MCSymbolRefExpr::VK_GOT; + break; + case WebAssemblyII::MO_MEMORY_BASE_REL: + Kind = MCSymbolRefExpr::VK_WASM_MBREL; + break; + case WebAssemblyII::MO_TABLE_BASE_REL: + Kind = MCSymbolRefExpr::VK_WASM_TBREL; + break; + default: + llvm_unreachable("Unknown target flag on GV operand"); + } + const MCExpr *Expr = MCSymbolRefExpr::create(Sym, Kind, Ctx); if (Offset != 0) { - if (TargetFlags & WebAssemblyII::MO_GOT) + if (TargetFlags == WebAssemblyII::MO_GOT) report_fatal_error("GOT symbol references do not support offsets"); - unsigned Type = TargetFlags & WebAssemblyII::MO_SYMBOL_MASK; - assert((Type == WebAssemblyII::MO_SYMBOL_FUNCTION) == IsFunc); - if (Type == WebAssemblyII::MO_SYMBOL_FUNCTION || IsFunc) + if (IsFunc) report_fatal_error("Function addresses with offsets not supported"); - if (Type == WebAssemblyII::MO_SYMBOL_GLOBAL) - report_fatal_error("Global indexes with offsets not supported"); - if (Type == WebAssemblyII::MO_SYMBOL_EVENT) - report_fatal_error("Event indexes with offsets not supported"); Expr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(Offset, Ctx), Ctx); } @@ -216,7 +226,7 @@ WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION); const MCExpr *Expr = MCSymbolRefExpr::create( - WasmSym, MCSymbolRefExpr::VK_WebAssembly_TYPEINDEX, Ctx); + WasmSym, MCSymbolRefExpr::VK_WASM_TYPEINDEX, Ctx); MCOp = MCOperand::createExpr(Expr); break; } @@ -243,7 +253,7 @@ case MachineOperand::MO_ExternalSymbol: // The target flag indicates whether this is a symbol for a // variable or a function. - assert((MO.getTargetFlags() & ~WebAssemblyII::MO_SYMBOL_MASK) == 0 && + assert(MO.getTargetFlags() == 0 && "WebAssembly uses only symbol flags on ExternalSymbols"); MCOp = lowerSymbolOperand( GetExternalSymbolSymbol(MO), /*Offset=*/0, false, MO.getTargetFlags()); diff --git a/llvm/test/CodeGen/WebAssembly/call-pic.ll b/llvm/test/CodeGen/WebAssembly/call-pic.ll --- a/llvm/test/CodeGen/WebAssembly/call-pic.ll +++ b/llvm/test/CodeGen/WebAssembly/call-pic.ll @@ -5,14 +5,14 @@ declare i32 @foo() declare i32 @bar() -declare hidden i32 @hidden_function(); +declare hidden i32 @hidden_function() @indirect_func = global i32 ()* @foo define void @call_indirect_func() { ; CHECK-LABEL: call_indirect_func: ; CHECK: global.get $push[[L0:[0-9]+]]=, __memory_base{{$}} -; CHECK-NEXT: i32.const $push[[L1:[0-9]+]]=, indirect_func{{$}} +; CHECK-NEXT: i32.const $push[[L1:[0-9]+]]=, indirect_func@MBREL{{$}} ; CHECK-NEXT: i32.add $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} ; CHECK-NEXT: i32.load $push[[L3:[0-9]+]]=, 0($pop[[L2]]){{$}} ; CHECK-NEXT: i32.call_indirect $push[[L4:[0-9]+]]=, $pop[[L3]]{{$}} @@ -43,7 +43,7 @@ define i8* @get_function_address_hidden() { ; CHECK-LABEL: get_function_address_hidden: ; CHECK: global.get $push[[L0:[0-9]+]]=, __table_base{{$}} -; CHECK-NEXT: i32.const $push[[L1:[0-9]+]]=, hidden_function{{$}} +; CHECK-NEXT: i32.const $push[[L1:[0-9]+]]=, hidden_function@TBREL{{$}} ; CHECK-NEXT: i32.add $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} ; CHECK-NEXT: return $pop[[L2]]{{$}} ; CHECK-NEXT: end_function{{$}} diff --git a/llvm/test/CodeGen/WebAssembly/load-store-pic.ll b/llvm/test/CodeGen/WebAssembly/load-store-pic.ll --- a/llvm/test/CodeGen/WebAssembly/load-store-pic.ll +++ b/llvm/test/CodeGen/WebAssembly/load-store-pic.ll @@ -21,7 +21,7 @@ define i32 @load_hidden_global() { ; CHECK-LABEL: load_hidden_global: ; PIC: global.get $push[[L0:[0-9]+]]=, __memory_base{{$}} -; PIC-NEXT: i32.const $push[[L1:[0-9]+]]=, hidden_global{{$}} +; PIC-NEXT: i32.const $push[[L1:[0-9]+]]=, hidden_global@MBREL{{$}} ; PIC-NEXT: i32.add $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} ; PIC-NEXT: i32.load $push[[L3:[0-9]+]]=, 0($pop[[L2]]){{$}} @@ -36,7 +36,7 @@ define i32 @load_hidden_global_offset() { ; CHECK-LABEL: load_hidden_global_offset: ; PIC: global.get $push[[L0:[0-9]+]]=, __memory_base{{$}} -; PIC-NEXT: i32.const $push[[L1:[0-9]+]]=, hidden_global_array{{$}} +; PIC-NEXT: i32.const $push[[L1:[0-9]+]]=, hidden_global_array@MBREL{{$}} ; PIC-NEXT: i32.add $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1:[0-9]+]]{{$}} ; PIC-NEXT: i32.const $push[[L3:[0-9]+]]=, 20{{$}} ; PIC-NEXT: i32.add $push[[L4:[0-9]+]]=, $pop[[L2]], $pop[[L3]]{{$}} @@ -56,7 +56,7 @@ define void @store_hidden_global(i32 %n) { ; CHECK-LABEL: store_hidden_global: ; PIC: global.get $push[[L0:[0-9]+]]=, __memory_base{{$}} -; PIC-NEXT: i32.const $push[[L1:[0-9]+]]=, hidden_global{{$}} +; PIC-NEXT: i32.const $push[[L1:[0-9]+]]=, hidden_global@MBREL{{$}} ; PIC-NEXT: i32.add $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} ; PIC-NEXT: i32.store 0($pop[[L2]]), $0{{$}} @@ -71,7 +71,7 @@ define void @store_hidden_global_offset(i32 %n) { ; CHECK-LABEL: store_hidden_global_offset: ; PIC: global.get $push[[L0:[0-9]+]]=, __memory_base{{$}} -; PIC-NEXT: i32.const $push[[L1:[0-9]+]]=, hidden_global_array{{$}} +; PIC-NEXT: i32.const $push[[L1:[0-9]+]]=, hidden_global_array@MBREL{{$}} ; PIC-NEXT: i32.add $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} ; PIC-NEXT: i32.const $push[[L3:[0-9]+]]=, 20{{$}} ; PIC-NEXT: i32.add $push[[L4:[0-9]+]]=, $pop[[L2]], $pop[[L3]]{{$}} diff --git a/llvm/test/MC/WebAssembly/reloc-pic.s b/llvm/test/MC/WebAssembly/reloc-pic.s --- a/llvm/test/MC/WebAssembly/reloc-pic.s +++ b/llvm/test/MC/WebAssembly/reloc-pic.s @@ -16,6 +16,32 @@ i32.load 0 end_function +load_hidden_data: + .functype load_hidden_data () -> (i32) + global.get __memory_base + i32.const .L.hidden_data@MBREL + i32.add + end_function + +load_hidden_func: + .functype load_hidden_func () -> (i32) + global.get __table_base + i32.const hidden_func@TBREL + i32.add + end_function + +hidden_func: + .functype hidden_func () -> (i32) + i32.const 0 + end_function + +.section .rodata.hidden_data,"",@ +.L.hidden_data: + .int8 100 + .size .L.hidden_data, 1 + +#.hidden hidden_func +#.hidden hidden_data .size default_data, 4 .functype default_func () -> (i32) @@ -34,7 +60,7 @@ # CHECK-NEXT: Field: __linear_memory # CHECK-NEXT: Kind: MEMORY # CHECK-NEXT: Memory: -# CHECK-NEXT: Initial: 0x00000000 +# CHECK-NEXT: Initial: 0x00000001 # CHECK-NEXT: - Module: env # CHECK-NEXT: Field: __indirect_function_table # CHECK-NEXT: Kind: TABLE @@ -57,7 +83,7 @@ # CHECK-NEXT: GlobalType: I32 # CHECK-NEXT: GlobalMutable: true # CHECK-NEXT: - Type: FUNCTION -# CHECK-NEXT: FunctionTypes: [ 0, 0 ] +# CHECK-NEXT: FunctionTypes: [ 0, 0, 0, 0, 0 ] # CHECK-NEXT: - Type: CODE # CHECK-NEXT: Relocations: # CHECK-NEXT: - Type: R_WASM_GLOBAL_INDEX_LEB @@ -66,6 +92,18 @@ # CHECK-NEXT: - Type: R_WASM_GLOBAL_INDEX_LEB # CHECK-NEXT: Index: 3 # CHECK-NEXT: Offset: 0x00000010 +# CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB +# CHECK-NEXT: Index: 5 +# CHECK-NEXT: Offset: 0x0000001C +# CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_REL_SLEB +# CHECK-NEXT: Index: 6 +# CHECK-NEXT: Offset: 0x00000022 +# CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB +# CHECK-NEXT: Index: 8 +# CHECK-NEXT: Offset: 0x0000002C +# CHECK-NEXT: - Type: R_WASM_TABLE_INDEX_REL_SLEB +# CHECK-NEXT: Index: 9 +# CHECK-NEXT: Offset: 0x00000032 # CHECK-NEXT: Functions: # CHECK-NEXT: - Index: 1 # CHECK-NEXT: Locals: [] @@ -73,6 +111,23 @@ # CHECK-NEXT: - Index: 2 # CHECK-NEXT: Locals: [] # CHECK-NEXT: Body: 2381808080002800000B +# CHECK-NEXT: - Index: 3 +# CHECK-NEXT: Locals: [] +# CHECK-NEXT: Body: 2380808080004180808080006A0B +# CHECK-NEXT: - Index: 4 +# CHECK-NEXT: Locals: [] +# CHECK-NEXT: Body: 2380808080004180808080006A0B +# CHECK-NEXT: - Index: 5 +# CHECK-NEXT: Locals: [] +# CHECK-NEXT: Body: 41000B +# CHECK-NEXT: - Type: DATA +# CHECK-NEXT: Segments: +# CHECK-NEXT: - SectionOffset: 6 +# CHECK-NEXT: InitFlags: 0 +# CHECK-NEXT: Offset: +# CHECK-NEXT: Opcode: I32_CONST +# CHECK-NEXT: Value: 0 +# CHECK-NEXT: Content: '64' # CHECK-NEXT: - Type: CUSTOM # CHECK-NEXT: Name: linking # CHECK-NEXT: Version: 2 @@ -96,4 +151,38 @@ # CHECK-NEXT: Name: default_func # CHECK-NEXT: Flags: [ UNDEFINED ] # CHECK-NEXT: Function: 0 +# CHECK-NEXT: - Index: 4 +# CHECK-NEXT: Kind: FUNCTION +# CHECK-NEXT: Name: load_hidden_data +# CHECK-NEXT: Flags: [ BINDING_LOCAL ] +# CHECK-NEXT: Function: 3 +# CHECK-NEXT: - Index: 5 +# CHECK-NEXT: Kind: DATA +# CHECK-NEXT: Name: __memory_base +# CHECK-NEXT: Flags: [ UNDEFINED ] +# CHECK-NEXT: - Index: 6 +# CHECK-NEXT: Kind: DATA +# CHECK-NEXT: Name: .L.hidden_data +# CHECK-NEXT: Flags: [ BINDING_LOCAL ] +# CHECK-NEXT: Segment: 0 +# CHECK-NEXT: Size: 1 +# CHECK-NEXT: - Index: 7 +# CHECK-NEXT: Kind: FUNCTION +# CHECK-NEXT: Name: load_hidden_func +# CHECK-NEXT: Flags: [ BINDING_LOCAL ] +# CHECK-NEXT: Function: 4 +# CHECK-NEXT: - Index: 8 +# CHECK-NEXT: Kind: DATA +# CHECK-NEXT: Name: __table_base +# CHECK-NEXT: Flags: [ UNDEFINED ] +# CHECK-NEXT: - Index: 9 +# CHECK-NEXT: Kind: FUNCTION +# CHECK-NEXT: Name: hidden_func +# CHECK-NEXT: Flags: [ BINDING_LOCAL ] +# CHECK-NEXT: Function: 5 +# CHECK-NEXT: SegmentInfo: +# CHECK-NEXT: - Index: 0 +# CHECK-NEXT: Name: .rodata.hidden_data +# CHECK-NEXT: Alignment: 0 +# CHECK-NEXT: Flags: [ ] # CHECK-NEXT: ...