1 //===-- WebAssemblyWasmObjectWriter.cpp - WebAssembly Wasm Writer ---------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 /// This file handles Wasm-specific object emission, converting LLVM's
11 /// internal fixups into the appropriate relocations.
13 //===----------------------------------------------------------------------===//
15 #include "MCTargetDesc/WebAssemblyFixupKinds.h"
16 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
17 #include "llvm/BinaryFormat/Wasm.h"
18 #include "llvm/MC/MCAsmBackend.h"
19 #include "llvm/MC/MCFixup.h"
20 #include "llvm/MC/MCFixupKindInfo.h"
21 #include "llvm/MC/MCObjectWriter.h"
22 #include "llvm/MC/MCSectionWasm.h"
23 #include "llvm/MC/MCSymbolWasm.h"
24 #include "llvm/MC/MCValue.h"
25 #include "llvm/MC/MCWasmObjectWriter.h"
26 #include "llvm/Support/Casting.h"
27 #include "llvm/Support/ErrorHandling.h"
32 class WebAssemblyWasmObjectWriter final
: public MCWasmObjectTargetWriter
{
34 explicit WebAssemblyWasmObjectWriter(bool Is64Bit
);
37 unsigned getRelocType(const MCValue
&Target
,
38 const MCFixup
&Fixup
) const override
;
40 } // end anonymous namespace
42 WebAssemblyWasmObjectWriter::WebAssemblyWasmObjectWriter(bool Is64Bit
)
43 : MCWasmObjectTargetWriter(Is64Bit
) {}
45 static const MCSection
*getFixupSection(const MCExpr
*Expr
) {
46 if (auto SyExp
= dyn_cast
<MCSymbolRefExpr
>(Expr
)) {
47 if (SyExp
->getSymbol().isInSection())
48 return &SyExp
->getSymbol().getSection();
52 if (auto BinOp
= dyn_cast
<MCBinaryExpr
>(Expr
)) {
53 auto SectionLHS
= getFixupSection(BinOp
->getLHS());
54 auto SectionRHS
= getFixupSection(BinOp
->getRHS());
55 return SectionLHS
== SectionRHS
? nullptr : SectionLHS
;
58 if (auto UnOp
= dyn_cast
<MCUnaryExpr
>(Expr
))
59 return getFixupSection(UnOp
->getSubExpr());
64 unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue
&Target
,
65 const MCFixup
&Fixup
) const {
66 const MCSymbolRefExpr
*RefA
= Target
.getSymA();
68 auto& SymA
= cast
<MCSymbolWasm
>(RefA
->getSymbol());
70 MCSymbolRefExpr::VariantKind Modifier
= Target
.getAccessVariant();
73 case MCSymbolRefExpr::VK_GOT
:
74 return wasm::R_WASM_GLOBAL_INDEX_LEB
;
75 case MCSymbolRefExpr::VK_WASM_TBREL
:
76 assert(SymA
.isFunction());
77 return wasm::R_WASM_TABLE_INDEX_REL_SLEB
;
78 case MCSymbolRefExpr::VK_WASM_MBREL
:
79 assert(SymA
.isData());
80 return wasm::R_WASM_MEMORY_ADDR_REL_SLEB
;
81 case MCSymbolRefExpr::VK_WASM_TYPEINDEX
:
82 return wasm::R_WASM_TYPE_INDEX_LEB
;
87 switch (unsigned(Fixup
.getKind())) {
88 case WebAssembly::fixup_sleb128_i32
:
89 if (SymA
.isFunction())
90 return wasm::R_WASM_TABLE_INDEX_SLEB
;
91 return wasm::R_WASM_MEMORY_ADDR_SLEB
;
92 case WebAssembly::fixup_sleb128_i64
:
93 llvm_unreachable("fixup_sleb128_i64 not implemented yet");
94 case WebAssembly::fixup_uleb128_i32
:
96 return wasm::R_WASM_GLOBAL_INDEX_LEB
;
97 if (SymA
.isFunction())
98 return wasm::R_WASM_FUNCTION_INDEX_LEB
;
100 return wasm::R_WASM_EVENT_INDEX_LEB
;
101 return wasm::R_WASM_MEMORY_ADDR_LEB
;
103 if (SymA
.isFunction())
104 return wasm::R_WASM_TABLE_INDEX_I32
;
105 if (auto Section
= static_cast<const MCSectionWasm
*>(
106 getFixupSection(Fixup
.getValue()))) {
107 if (Section
->getKind().isText())
108 return wasm::R_WASM_FUNCTION_OFFSET_I32
;
109 else if (!Section
->isWasmData())
110 return wasm::R_WASM_SECTION_OFFSET_I32
;
112 return wasm::R_WASM_MEMORY_ADDR_I32
;
114 llvm_unreachable("unimplemented fixup kind");
118 std::unique_ptr
<MCObjectTargetWriter
>
119 llvm::createWebAssemblyWasmObjectWriter(bool Is64Bit
) {
120 return llvm::make_unique
<WebAssemblyWasmObjectWriter
>(Is64Bit
);