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,10 +284,7 @@ VK_Hexagon_IE, VK_Hexagon_IE_GOT, - VK_WebAssembly_FUNCTION, // Function table index, rather than virtual addr - VK_WebAssembly_GLOBAL, // Global object index VK_WebAssembly_TYPEINDEX,// Type table index - VK_WebAssembly_EVENT, // Event index 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,10 +302,7 @@ case VK_Hexagon_LD_PLT: return "LDPLT"; case VK_Hexagon_IE: return "IE"; case VK_Hexagon_IE_GOT: return "IEGOT"; - case VK_WebAssembly_FUNCTION: return "FUNCTION"; - case VK_WebAssembly_GLOBAL: return "GLOBAL"; case VK_WebAssembly_TYPEINDEX: return "TYPEINDEX"; - case VK_WebAssembly_EVENT: return "EVENT"; case VK_AMDGPU_GOTPCREL32_LO: return "gotpcrel32@lo"; case VK_AMDGPU_GOTPCREL32_HI: return "gotpcrel32@hi"; case VK_AMDGPU_REL32_LO: return "rel32@lo"; @@ -418,10 +415,7 @@ .Case("lo8", VK_AVR_LO8) .Case("hi8", VK_AVR_HI8) .Case("hlo8", VK_AVR_HLO8) - .Case("function", VK_WebAssembly_FUNCTION) - .Case("global", VK_WebAssembly_GLOBAL) .Case("typeindex", VK_WebAssembly_TYPEINDEX) - .Case("event", VK_WebAssembly_EVENT) .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 @@ -438,63 +438,27 @@ const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue) { MCAsmBackend &Backend = Asm.getBackend(); - bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags & - MCFixupKindInfo::FKF_IsPCRel; const auto &FixupSection = cast(*Fragment->getParent()); - uint64_t C = Target.getConstant(); uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); MCContext &Ctx = Asm.getContext(); + assert(!(Backend.getFixupKindInfo(Fixup.getKind()).Flags & + MCFixupKindInfo::FKF_IsPCRel) && + "Wasm doesn't support PC relative relocations"); // The .init_array isn't translated as data, so don't do relocations in it. if (FixupSection.getSectionName().startswith(".init_array")) return; - if (const MCSymbolRefExpr *RefB = Target.getSymB()) { - assert(RefB->getKind() == MCSymbolRefExpr::VK_None && - "Should not have constructed this"); - - // Let A, B and C being the components of Target and R be the location of - // the fixup. If the fixup is not pcrel, we want to compute (A - B + C). - // If it is pcrel, we want to compute (A - B + C - R). - - // In general, Wasm has no relocations for -B. It can only represent (A + C) - // or (A + C - R). If B = R + K and the relocation is not pcrel, we can - // replace B to implement it: (A - R - K + C) - if (IsPCRel) { - Ctx.reportError( - Fixup.getLoc(), - "No relocation available to represent this relative expression"); - return; - } - - const auto &SymB = cast(RefB->getSymbol()); - - if (SymB.isUndefined()) { - Ctx.reportError(Fixup.getLoc(), - Twine("symbol '") + SymB.getName() + - "' can not be undefined in a subtraction expression"); - return; - } - - assert(!SymB.isAbsolute() && "Should have been folded"); - const MCSection &SecB = SymB.getSection(); - if (&SecB != &FixupSection) { - Ctx.reportError(Fixup.getLoc(), - "Cannot represent a difference across sections"); - return; - } - - uint64_t SymBOffset = Layout.getSymbolOffset(SymB); - uint64_t K = SymBOffset - FixupOffset; - IsPCRel = true; - C -= K; + if (Target.getSymB()) { + Ctx.reportError(Fixup.getLoc(), "Unsupported relocation"); + return; } - // We either rejected the fixup or folded B into C at this point. const MCSymbolRefExpr *RefA = Target.getSymA(); - const auto *SymA = RefA ? cast(&RefA->getSymbol()) : nullptr; + assert(RefA); + const auto *SymA = cast(&RefA->getSymbol()); - if (SymA && SymA->isVariable()) { + if (SymA->isVariable()) { const MCExpr *Expr = SymA->getVariableValue(); const auto *Inner = cast(Expr); if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) @@ -507,8 +471,8 @@ FixedValue = 0; unsigned Type = getRelocType(Target, Fixup); - assert(!IsPCRel); - assert(SymA); + + uint64_t C = Target.getConstant(); // Absolute offset within a section or a function. // Currently only supported for for metadata sections. @@ -1555,15 +1519,16 @@ assert(Fixup.getKind() == MCFixup::getKindForSize(is64Bit() ? 8 : 4, false)); const MCExpr *Expr = Fixup.getValue(); - auto *Sym = dyn_cast(Expr); - if (!Sym) + auto *SymRef = dyn_cast(Expr); + const auto &TargetSym = cast(SymRef->getSymbol()); + if (!SymRef) report_fatal_error("fixups in .init_array should be symbol references"); - if (Sym->getKind() != MCSymbolRefExpr::VK_WebAssembly_FUNCTION) - report_fatal_error("symbols in .init_array should be for functions"); - if (Sym->getSymbol().getIndex() == InvalidIndex) + if (TargetSym.getIndex() == InvalidIndex) report_fatal_error("symbols in .init_array should exist in symbtab"); + if (!TargetSym.isFunction()) + report_fatal_error("symbols in .init_array should be for functions"); InitFuncs.push_back( - std::make_pair(Priority, Sym->getSymbol().getIndex())); + std::make_pair(Priority, TargetSym.getIndex())); } } 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,23 +42,8 @@ WebAssemblyWasmObjectWriter::WebAssemblyWasmObjectWriter(bool Is64Bit) : MCWasmObjectTargetWriter(Is64Bit) {} -// Test whether the given expression computes a function address. -static bool isFunctionExpr(const MCExpr *Expr) { - if (auto SyExp = dyn_cast(Expr)) - return cast(SyExp->getSymbol()).isFunction(); - - if (auto BinOp = dyn_cast(Expr)) - return isFunctionExpr(BinOp->getLHS()) != isFunctionExpr(BinOp->getRHS()); - - if (auto UnOp = dyn_cast(Expr)) - return isFunctionExpr(UnOp->getSubExpr()); - - return false; -} - -static bool isFunctionType(const MCValue &Target) { - const MCSymbolRefExpr *RefA = Target.getSymA(); - return RefA && RefA->getKind() == MCSymbolRefExpr::VK_WebAssembly_TYPEINDEX; +static bool isFunctionSignatureRef(const MCSymbolRefExpr *Ref) { + return Ref->getKind() == MCSymbolRefExpr::VK_WebAssembly_TYPEINDEX; } static const MCSection *getFixupSection(const MCExpr *Expr) { @@ -80,41 +65,33 @@ return nullptr; } -static bool isGlobalType(const MCValue &Target) { - const MCSymbolRefExpr *RefA = Target.getSymA(); - return RefA && RefA->getKind() == MCSymbolRefExpr::VK_WebAssembly_GLOBAL; -} - -static bool isEventType(const MCValue &Target) { - const MCSymbolRefExpr *RefA = Target.getSymA(); - return RefA && RefA->getKind() == MCSymbolRefExpr::VK_WebAssembly_EVENT; -} - unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target, const MCFixup &Fixup) const { - // WebAssembly functions are not allocated in the data address space. To - // resolve a pointer to a function, we must use a special relocation type. - bool IsFunction = isFunctionExpr(Fixup.getValue()); + const MCSymbolRefExpr *RefA = Target.getSymA(); + assert(RefA); + auto& SymA = cast(RefA->getSymbol()); switch (unsigned(Fixup.getKind())) { case WebAssembly::fixup_code_sleb128_i32: - if (IsFunction) + if (SymA.isFunction()) return wasm::R_WASM_TABLE_INDEX_SLEB; return wasm::R_WASM_MEMORY_ADDR_SLEB; case WebAssembly::fixup_code_sleb128_i64: llvm_unreachable("fixup_sleb128_i64 not implemented yet"); case WebAssembly::fixup_code_uleb128_i32: - if (isGlobalType(Target)) + if (SymA.isFunction()) { + if (isFunctionSignatureRef(RefA)) + return wasm::R_WASM_TYPE_INDEX_LEB; + else + return wasm::R_WASM_FUNCTION_INDEX_LEB; + } + if (SymA.isGlobal()) return wasm::R_WASM_GLOBAL_INDEX_LEB; - if (isFunctionType(Target)) - return wasm::R_WASM_TYPE_INDEX_LEB; - if (IsFunction) - return wasm::R_WASM_FUNCTION_INDEX_LEB; - if (isEventType(Target)) + if (SymA.isEvent()) return wasm::R_WASM_EVENT_INDEX_LEB; return wasm::R_WASM_MEMORY_ADDR_LEB; case FK_Data_4: - if (IsFunction) + if (SymA.isFunction()) return wasm::R_WASM_TABLE_INDEX_I32; if (auto Section = static_cast( getFixupSection(Fixup.getValue()))) { diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h --- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h +++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h @@ -63,7 +63,6 @@ void EmitConstantPool() override; void EmitFunctionBodyStart() override; void EmitInstruction(const MachineInstr *MI) override; - const MCExpr *lowerConstant(const Constant *CV) override; bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &OS) override; diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp --- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp @@ -331,15 +331,6 @@ } } -const MCExpr *WebAssemblyAsmPrinter::lowerConstant(const Constant *CV) { - if (const auto *GV = dyn_cast(CV)) - if (GV->getValueType()->isFunctionTy()) { - return MCSymbolRefExpr::create( - getSymbol(GV), MCSymbolRefExpr::VK_WebAssembly_FUNCTION, OutContext); - } - return AsmPrinter::lowerConstant(CV); -} - bool WebAssemblyAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, 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 @@ -122,13 +122,8 @@ int64_t Offset, bool IsFunc, bool IsGlob, bool IsEvent) const { - MCSymbolRefExpr::VariantKind VK = - IsFunc ? MCSymbolRefExpr::VK_WebAssembly_FUNCTION - : IsGlob ? MCSymbolRefExpr::VK_WebAssembly_GLOBAL - : IsEvent ? MCSymbolRefExpr::VK_WebAssembly_EVENT - : MCSymbolRefExpr::VK_None; - - const MCExpr *Expr = MCSymbolRefExpr::create(Sym, VK, Ctx); + const MCExpr *Expr = + MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx); if (Offset != 0) { if (IsFunc) diff --git a/llvm/test/MC/WebAssembly/annotations.s b/llvm/test/MC/WebAssembly/annotations.s --- a/llvm/test/MC/WebAssembly/annotations.s +++ b/llvm/test/MC/WebAssembly/annotations.s @@ -28,7 +28,7 @@ local.set 0 block i32 local.get 0 - br_on_exn 0, __cpp_exception@EVENT + br_on_exn 0, __cpp_exception rethrow end_block end_try @@ -59,7 +59,7 @@ # CHECK-NEXT: local.set 0 # CHECK-NEXT: block i32 # CHECK-NEXT: local.get 0 -# CHECK-NEXT: br_on_exn 0, __cpp_exception@EVENT # 0: down to label6 +# CHECK-NEXT: br_on_exn 0, __cpp_exception # 0: down to label6 # CHECK-NEXT: rethrow # to caller # CHECK-NEXT: end_block # label6: # CHECK-NEXT: end_try # label5: diff --git a/llvm/test/MC/WebAssembly/assembler-binary.ll b/llvm/test/MC/WebAssembly/assembler-binary.ll --- a/llvm/test/MC/WebAssembly/assembler-binary.ll +++ b/llvm/test/MC/WebAssembly/assembler-binary.ll @@ -26,7 +26,7 @@ ; ASM: .globl foo ; ASM: foo: ; ASM-NEXT: .functype foo (i32) -> () -; ASM-NEXT: call bar@FUNCTION +; ASM-NEXT: call bar ; ASM-NEXT: end_function ; ASM: .functype bar () -> () diff --git a/llvm/test/MC/WebAssembly/basic-assembly.s b/llvm/test/MC/WebAssembly/basic-assembly.s --- a/llvm/test/MC/WebAssembly/basic-assembly.s +++ b/llvm/test/MC/WebAssembly/basic-assembly.s @@ -26,9 +26,9 @@ br_if 0 # 0: down to label0 .LBB0_1: loop i32 # label1: - call something1@FUNCTION + call something1 i64.const 1234 - i32.call something2@FUNCTION + i32.call something2 i32.const 0 call_indirect 0 i32.const 1 @@ -72,7 +72,7 @@ local.set 0 block i32 local.get 0 - br_on_exn 0, __cpp_exception@EVENT + br_on_exn 0, __cpp_exception rethrow .LBB0_4: end_block @@ -81,7 +81,7 @@ throw 0 .LBB0_5: #i32.trunc_sat_f32_s - global.get __stack_pointer@GLOBAL + global.get __stack_pointer end_function .globaltype __stack_pointer, i32 @@ -105,9 +105,9 @@ # CHECK-NEXT: br_if 0 # 0: down to label0 # CHECK-NEXT: .LBB0_1: # CHECK-NEXT: loop i32 # label1: -# CHECK-NEXT: call something1@FUNCTION +# CHECK-NEXT: call something1 # CHECK-NEXT: i64.const 1234 -# CHECK-NEXT: i32.call something2@FUNCTION +# CHECK-NEXT: i32.call something2 # CHECK-NEXT: i32.const 0 # CHECK-NEXT: call_indirect 0 # CHECK-NEXT: i32.const 1 @@ -149,7 +149,7 @@ # CHECK-NEXT: local.set 0 # CHECK-NEXT: block i32 # CHECK-NEXT: local.get 0 -# CHECK-NEXT: br_on_exn 0, __cpp_exception@EVENT +# CHECK-NEXT: br_on_exn 0, __cpp_exception # CHECK-NEXT: rethrow # CHECK-NEXT: .LBB0_4: # CHECK-NEXT: end_block @@ -157,7 +157,7 @@ # CHECK-NEXT: i32.const 0 # CHECK-NEXT: throw 0 # CHECK-NEXT: .LBB0_5: -# CHECK-NEXT: global.get __stack_pointer@GLOBAL +# CHECK-NEXT: global.get __stack_pointer # CHECK-NEXT: end_function # CHECK: .globaltype __stack_pointer, i32