diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:50:12 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:50:12 +0000 |
commit | e6d1592492a3a379186bfb02bd0f4eda0669c0d5 (patch) | |
tree | 599ab169a01f1c86eda9adc774edaedde2f2db5b /lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp | |
parent | 1a56a5ead7a2e84bee8240f5f6b033b5f1707154 (diff) |
Diffstat (limited to 'lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp')
-rw-r--r-- | lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp | 109 |
1 files changed, 46 insertions, 63 deletions
diff --git a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp index 763e30be8e02..a1cc3e268e8f 100644 --- a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp +++ b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp @@ -1,9 +1,8 @@ //===-- WebAssemblyWasmObjectWriter.cpp - WebAssembly Wasm Writer ---------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -43,26 +42,7 @@ private: 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<MCSymbolRefExpr>(Expr)) - return cast<MCSymbolWasm>(SyExp->getSymbol()).isFunction(); - - if (auto BinOp = dyn_cast<MCBinaryExpr>(Expr)) - return IsFunctionExpr(BinOp->getLHS()) != IsFunctionExpr(BinOp->getRHS()); - - if (auto UnOp = dyn_cast<MCUnaryExpr>(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 const MCSection *GetFixupSection(const MCExpr *Expr) { +static const MCSection *getFixupSection(const MCExpr *Expr) { if (auto SyExp = dyn_cast<MCSymbolRefExpr>(Expr)) { if (SyExp->getSymbol().isInSection()) return &SyExp->getSymbol().getSection(); @@ -70,63 +50,66 @@ static const MCSection *GetFixupSection(const MCExpr *Expr) { } if (auto BinOp = dyn_cast<MCBinaryExpr>(Expr)) { - auto SectionLHS = GetFixupSection(BinOp->getLHS()); - auto SectionRHS = GetFixupSection(BinOp->getRHS()); + auto SectionLHS = getFixupSection(BinOp->getLHS()); + auto SectionRHS = getFixupSection(BinOp->getRHS()); return SectionLHS == SectionRHS ? nullptr : SectionLHS; } if (auto UnOp = dyn_cast<MCUnaryExpr>(Expr)) - return GetFixupSection(UnOp->getSubExpr()); + return getFixupSection(UnOp->getSubExpr()); 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<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_code_sleb128_i32: - if (IsFunction) - return wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB; - return wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB; - case WebAssembly::fixup_code_sleb128_i64: + 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_sleb128_i64: llvm_unreachable("fixup_sleb128_i64 not implemented yet"); - case WebAssembly::fixup_code_uleb128_i32: - if (IsGlobalType(Target)) - return wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB; - if (IsFunctionType(Target)) - return wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB; - if (IsFunction) - return wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB; - if (IsEventType(Target)) - return wasm::R_WEBASSEMBLY_EVENT_INDEX_LEB; - return wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB; + case WebAssembly::fixup_uleb128_i32: + if (SymA.isGlobal()) + return wasm::R_WASM_GLOBAL_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; case FK_Data_4: - if (IsFunction) - return wasm::R_WEBASSEMBLY_TABLE_INDEX_I32; + if (SymA.isFunction()) + return wasm::R_WASM_TABLE_INDEX_I32; if (auto Section = static_cast<const MCSectionWasm *>( - GetFixupSection(Fixup.getValue()))) { + getFixupSection(Fixup.getValue()))) { if (Section->getKind().isText()) - return wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32; + return wasm::R_WASM_FUNCTION_OFFSET_I32; else if (!Section->isWasmData()) - return wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32; + return wasm::R_WASM_SECTION_OFFSET_I32; } - return wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32; - case FK_Data_8: - llvm_unreachable("FK_Data_8 not implemented yet"); + return wasm::R_WASM_MEMORY_ADDR_I32; default: llvm_unreachable("unimplemented fixup kind"); } |