118eafb6cSDan Gohman //===-- WebAssemblyWasmObjectWriter.cpp - WebAssembly Wasm Writer ---------===// 218eafb6cSDan Gohman // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 618eafb6cSDan Gohman // 718eafb6cSDan Gohman //===----------------------------------------------------------------------===// 818eafb6cSDan Gohman /// 918eafb6cSDan Gohman /// \file 105f8f34e4SAdrian Prantl /// This file handles Wasm-specific object emission, converting LLVM's 1118eafb6cSDan Gohman /// internal fixups into the appropriate relocations. 1218eafb6cSDan Gohman /// 1318eafb6cSDan Gohman //===----------------------------------------------------------------------===// 1418eafb6cSDan Gohman 15d934cb88SDan Gohman #include "MCTargetDesc/WebAssemblyFixupKinds.h" 166bda14b3SChandler Carruth #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 17264b5d9eSZachary Turner #include "llvm/BinaryFormat/Wasm.h" 18ae03c1e7SSam Clegg #include "llvm/MC/MCAsmBackend.h" 1918eafb6cSDan Gohman #include "llvm/MC/MCFixup.h" 20ae03c1e7SSam Clegg #include "llvm/MC/MCFixupKindInfo.h" 21669300dbSDerek Schuff #include "llvm/MC/MCObjectWriter.h" 226a31a0d6SSam Clegg #include "llvm/MC/MCSectionWasm.h" 23d934cb88SDan Gohman #include "llvm/MC/MCSymbolWasm.h" 24ae03c1e7SSam Clegg #include "llvm/MC/MCValue.h" 256a31a0d6SSam Clegg #include "llvm/MC/MCWasmObjectWriter.h" 26d934cb88SDan Gohman #include "llvm/Support/Casting.h" 2718eafb6cSDan Gohman #include "llvm/Support/ErrorHandling.h" 28ae03c1e7SSam Clegg 2918eafb6cSDan Gohman using namespace llvm; 3018eafb6cSDan Gohman 3118eafb6cSDan Gohman namespace { 3218eafb6cSDan Gohman class WebAssemblyWasmObjectWriter final : public MCWasmObjectTargetWriter { 3318eafb6cSDan Gohman public: 3418eafb6cSDan Gohman explicit WebAssemblyWasmObjectWriter(bool Is64Bit); 3518eafb6cSDan Gohman 3618eafb6cSDan Gohman private: 37ae03c1e7SSam Clegg unsigned getRelocType(const MCValue &Target, 38ae03c1e7SSam Clegg const MCFixup &Fixup) const override; 3918eafb6cSDan Gohman }; 4018eafb6cSDan Gohman } // end anonymous namespace 4118eafb6cSDan Gohman 4218eafb6cSDan Gohman WebAssemblyWasmObjectWriter::WebAssemblyWasmObjectWriter(bool Is64Bit) 4318eafb6cSDan Gohman : MCWasmObjectTargetWriter(Is64Bit) {} 4418eafb6cSDan Gohman 45*8fffa1dfSSam Clegg static bool isFunctionSignatureRef(const MCSymbolRefExpr *Ref) { 46*8fffa1dfSSam Clegg return Ref->getKind() == MCSymbolRefExpr::VK_WebAssembly_TYPEINDEX; 47acd7d2b0SSam Clegg } 48acd7d2b0SSam Clegg 4918c56a07SHeejin Ahn static const MCSection *getFixupSection(const MCExpr *Expr) { 506a31a0d6SSam Clegg if (auto SyExp = dyn_cast<MCSymbolRefExpr>(Expr)) { 516a31a0d6SSam Clegg if (SyExp->getSymbol().isInSection()) 526a31a0d6SSam Clegg return &SyExp->getSymbol().getSection(); 536a31a0d6SSam Clegg return nullptr; 546a31a0d6SSam Clegg } 556a31a0d6SSam Clegg 566a31a0d6SSam Clegg if (auto BinOp = dyn_cast<MCBinaryExpr>(Expr)) { 5718c56a07SHeejin Ahn auto SectionLHS = getFixupSection(BinOp->getLHS()); 5818c56a07SHeejin Ahn auto SectionRHS = getFixupSection(BinOp->getRHS()); 596a31a0d6SSam Clegg return SectionLHS == SectionRHS ? nullptr : SectionLHS; 606a31a0d6SSam Clegg } 616a31a0d6SSam Clegg 626a31a0d6SSam Clegg if (auto UnOp = dyn_cast<MCUnaryExpr>(Expr)) 6318c56a07SHeejin Ahn return getFixupSection(UnOp->getSubExpr()); 646a31a0d6SSam Clegg 656a31a0d6SSam Clegg return nullptr; 666a31a0d6SSam Clegg } 676a31a0d6SSam Clegg 68f208f631SHeejin Ahn unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target, 69ae03c1e7SSam Clegg const MCFixup &Fixup) const { 70*8fffa1dfSSam Clegg const MCSymbolRefExpr *RefA = Target.getSymA(); 71*8fffa1dfSSam Clegg assert(RefA); 72*8fffa1dfSSam Clegg auto& SymA = cast<MCSymbolWasm>(RefA->getSymbol()); 73d934cb88SDan Gohman 74d934cb88SDan Gohman switch (unsigned(Fixup.getKind())) { 75d934cb88SDan Gohman case WebAssembly::fixup_code_sleb128_i32: 76*8fffa1dfSSam Clegg if (SymA.isFunction()) 77d1152a26SSam Clegg return wasm::R_WASM_TABLE_INDEX_SLEB; 78d1152a26SSam Clegg return wasm::R_WASM_MEMORY_ADDR_SLEB; 79d934cb88SDan Gohman case WebAssembly::fixup_code_sleb128_i64: 80d934cb88SDan Gohman llvm_unreachable("fixup_sleb128_i64 not implemented yet"); 81d934cb88SDan Gohman case WebAssembly::fixup_code_uleb128_i32: 82*8fffa1dfSSam Clegg if (SymA.isFunction()) { 83*8fffa1dfSSam Clegg if (isFunctionSignatureRef(RefA)) 84d1152a26SSam Clegg return wasm::R_WASM_TYPE_INDEX_LEB; 85*8fffa1dfSSam Clegg else 86d1152a26SSam Clegg return wasm::R_WASM_FUNCTION_INDEX_LEB; 87*8fffa1dfSSam Clegg } 88*8fffa1dfSSam Clegg if (SymA.isGlobal()) 89*8fffa1dfSSam Clegg return wasm::R_WASM_GLOBAL_INDEX_LEB; 90*8fffa1dfSSam Clegg if (SymA.isEvent()) 91d1152a26SSam Clegg return wasm::R_WASM_EVENT_INDEX_LEB; 92d1152a26SSam Clegg return wasm::R_WASM_MEMORY_ADDR_LEB; 93d934cb88SDan Gohman case FK_Data_4: 94*8fffa1dfSSam Clegg if (SymA.isFunction()) 95d1152a26SSam Clegg return wasm::R_WASM_TABLE_INDEX_I32; 966a31a0d6SSam Clegg if (auto Section = static_cast<const MCSectionWasm *>( 9718c56a07SHeejin Ahn getFixupSection(Fixup.getValue()))) { 986a31a0d6SSam Clegg if (Section->getKind().isText()) 99d1152a26SSam Clegg return wasm::R_WASM_FUNCTION_OFFSET_I32; 1006a31a0d6SSam Clegg else if (!Section->isWasmData()) 101d1152a26SSam Clegg return wasm::R_WASM_SECTION_OFFSET_I32; 1026a31a0d6SSam Clegg } 103d1152a26SSam Clegg return wasm::R_WASM_MEMORY_ADDR_I32; 104d934cb88SDan Gohman case FK_Data_8: 105d934cb88SDan Gohman llvm_unreachable("FK_Data_8 not implemented yet"); 106d934cb88SDan Gohman default: 107d934cb88SDan Gohman llvm_unreachable("unimplemented fixup kind"); 108d934cb88SDan Gohman } 10918eafb6cSDan Gohman } 11018eafb6cSDan Gohman 111dcd7d6c3SPeter Collingbourne std::unique_ptr<MCObjectTargetWriter> 112dcd7d6c3SPeter Collingbourne llvm::createWebAssemblyWasmObjectWriter(bool Is64Bit) { 113dcd7d6c3SPeter Collingbourne return llvm::make_unique<WebAssemblyWasmObjectWriter>(Is64Bit); 11418eafb6cSDan Gohman } 115