diff options
| author | Sam Clegg <sbc@chromium.org> | 2019-04-04 17:43:50 +0000 |
|---|---|---|
| committer | Sam Clegg <sbc@chromium.org> | 2019-04-04 17:43:50 +0000 |
| commit | 2a7cac932bbca5492e5a42d9dac33e0cb76d0f83 (patch) | |
| tree | 64e21da525922e0a2d7fc39421ecd1d879f963d6 /llvm/lib/Target | |
| parent | 98e3954fe9d6ab74888c8757284136134330e475 (diff) | |
| download | bcm5719-llvm-2a7cac932bbca5492e5a42d9dac33e0cb76d0f83.tar.gz bcm5719-llvm-2a7cac932bbca5492e5a42d9dac33e0cb76d0f83.zip | |
[WebAssembly] Add new explicit relocation types for PIC relocations
See https://github.com/WebAssembly/tool-conventions/pull/106
Differential Revision: https://reviews.llvm.org/D59907
llvm-svn: 357710
Diffstat (limited to 'llvm/lib/Target')
4 files changed, 63 insertions, 26 deletions
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h index 69c477bbbb5..4c7114eea11 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h @@ -90,9 +90,21 @@ namespace WebAssemblyII { enum TOF { MO_NO_FLAG = 0, - // Address of data symbol via a wasm global. This adds a level of indirection - // similar to the GOT on native platforms. + // On a symbol operand this indicates that the immediate is a wasm global + // index. The value of the wasm global will be set to the symbol address at + // runtime. This adds a level of indirection similar to the GOT on native + // platforms. MO_GOT, + + // On a symbol operand this indicates that the immediate is the symbol + // address relative the __memory_base wasm global. + // Only applicable to data symbols. + MO_MEMORY_BASE_REL, + + // On a symbol operand this indicates that the immediate is the symbol + // address relative the __table_base wasm global. + // Only applicable to function symbols. + 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 index 91b356db81d..a1cc3e268e8 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp @@ -42,14 +42,6 @@ private: 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<MCSymbolRefExpr>(Expr)) { if (SyExp->getSymbol().isInSection()) @@ -75,6 +67,23 @@ unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target, assert(RefA); auto& SymA = cast<MCSymbolWasm>(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_sleb128_i32: if (SymA.isFunction()) @@ -83,14 +92,10 @@ unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target, case WebAssembly::fixup_sleb128_i64: llvm_unreachable("fixup_sleb128_i64 not implemented yet"); case WebAssembly::fixup_uleb128_i32: - if (SymA.isGlobal() || isGOTRef(RefA)) + 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; diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp index b5e9d9e9723..7bad4972c4f 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -1003,17 +1003,22 @@ SDValue WebAssemblyTargetLowering::LowerGlobalAddress(SDValue Op, 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 { diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp index fd09b749c73..27f13d9639a 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp @@ -122,16 +122,31 @@ MCSymbol *WebAssemblyMCInstLower::GetExternalSymbolSymbol( MCOperand WebAssemblyMCInstLower::lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const { - bool isGOT = MO.getTargetFlags() == WebAssemblyII::MO_GOT; - MCSymbolRefExpr::VariantKind Kind = - isGOT ? MCSymbolRefExpr::VK_GOT : MCSymbolRefExpr::VK_None; + MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None; + unsigned TargetFlags = MO.getTargetFlags(); + + 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 (MO.getOffset() != 0) { const auto *WasmSym = cast<MCSymbolWasm>(Sym); - if (isGOT) + if (TargetFlags == WebAssemblyII::MO_GOT) report_fatal_error("GOT symbol references do not support offsets"); - if (WasmSym->isFunction()) report_fatal_error("Function addresses with offsets not supported"); if (WasmSym->isGlobal()) @@ -217,7 +232,7 @@ void WebAssemblyMCInstLower::lower(const MachineInstr *MI, 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; } |

