Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
35293 views
1
//===-- WebAssemblyWasmObjectWriter.cpp - WebAssembly Wasm Writer ---------===//
2
//
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
6
//
7
//===----------------------------------------------------------------------===//
8
///
9
/// \file
10
/// This file handles Wasm-specific object emission, converting LLVM's
11
/// internal fixups into the appropriate relocations.
12
///
13
//===----------------------------------------------------------------------===//
14
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"
28
29
using namespace llvm;
30
31
namespace {
32
class WebAssemblyWasmObjectWriter final : public MCWasmObjectTargetWriter {
33
public:
34
explicit WebAssemblyWasmObjectWriter(bool Is64Bit, bool IsEmscripten);
35
36
private:
37
unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
38
const MCSectionWasm &FixupSection,
39
bool IsLocRel) const override;
40
};
41
} // end anonymous namespace
42
43
WebAssemblyWasmObjectWriter::WebAssemblyWasmObjectWriter(bool Is64Bit,
44
bool IsEmscripten)
45
: MCWasmObjectTargetWriter(Is64Bit, IsEmscripten) {}
46
47
static const MCSection *getTargetSection(const MCExpr *Expr) {
48
if (auto SyExp = dyn_cast<MCSymbolRefExpr>(Expr)) {
49
if (SyExp->getSymbol().isInSection())
50
return &SyExp->getSymbol().getSection();
51
return nullptr;
52
}
53
54
if (auto BinOp = dyn_cast<MCBinaryExpr>(Expr)) {
55
auto SectionLHS = getTargetSection(BinOp->getLHS());
56
auto SectionRHS = getTargetSection(BinOp->getRHS());
57
return SectionLHS == SectionRHS ? nullptr : SectionLHS;
58
}
59
60
if (auto UnOp = dyn_cast<MCUnaryExpr>(Expr))
61
return getTargetSection(UnOp->getSubExpr());
62
63
return nullptr;
64
}
65
66
unsigned WebAssemblyWasmObjectWriter::getRelocType(
67
const MCValue &Target, const MCFixup &Fixup,
68
const MCSectionWasm &FixupSection, bool IsLocRel) const {
69
const MCSymbolRefExpr *RefA = Target.getSymA();
70
assert(RefA);
71
auto& SymA = cast<MCSymbolWasm>(RefA->getSymbol());
72
73
MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
74
75
switch (Modifier) {
76
case MCSymbolRefExpr::VK_GOT:
77
case MCSymbolRefExpr::VK_WASM_GOT_TLS:
78
return wasm::R_WASM_GLOBAL_INDEX_LEB;
79
case MCSymbolRefExpr::VK_WASM_TBREL:
80
assert(SymA.isFunction());
81
return is64Bit() ? wasm::R_WASM_TABLE_INDEX_REL_SLEB64
82
: wasm::R_WASM_TABLE_INDEX_REL_SLEB;
83
case MCSymbolRefExpr::VK_WASM_TLSREL:
84
return is64Bit() ? wasm::R_WASM_MEMORY_ADDR_TLS_SLEB64
85
: wasm::R_WASM_MEMORY_ADDR_TLS_SLEB;
86
case MCSymbolRefExpr::VK_WASM_MBREL:
87
assert(SymA.isData());
88
return is64Bit() ? wasm::R_WASM_MEMORY_ADDR_REL_SLEB64
89
: wasm::R_WASM_MEMORY_ADDR_REL_SLEB;
90
case MCSymbolRefExpr::VK_WASM_TYPEINDEX:
91
return wasm::R_WASM_TYPE_INDEX_LEB;
92
case MCSymbolRefExpr::VK_None:
93
break;
94
case MCSymbolRefExpr::VK_WASM_FUNCINDEX:
95
return wasm::R_WASM_FUNCTION_INDEX_I32;
96
default:
97
report_fatal_error("unknown VariantKind");
98
break;
99
}
100
101
switch (unsigned(Fixup.getKind())) {
102
case WebAssembly::fixup_sleb128_i32:
103
if (SymA.isFunction())
104
return wasm::R_WASM_TABLE_INDEX_SLEB;
105
return wasm::R_WASM_MEMORY_ADDR_SLEB;
106
case WebAssembly::fixup_sleb128_i64:
107
if (SymA.isFunction())
108
return wasm::R_WASM_TABLE_INDEX_SLEB64;
109
return wasm::R_WASM_MEMORY_ADDR_SLEB64;
110
case WebAssembly::fixup_uleb128_i32:
111
if (SymA.isGlobal())
112
return wasm::R_WASM_GLOBAL_INDEX_LEB;
113
if (SymA.isFunction())
114
return wasm::R_WASM_FUNCTION_INDEX_LEB;
115
if (SymA.isTag())
116
return wasm::R_WASM_TAG_INDEX_LEB;
117
if (SymA.isTable())
118
return wasm::R_WASM_TABLE_NUMBER_LEB;
119
return wasm::R_WASM_MEMORY_ADDR_LEB;
120
case WebAssembly::fixup_uleb128_i64:
121
assert(SymA.isData());
122
return wasm::R_WASM_MEMORY_ADDR_LEB64;
123
case FK_Data_4:
124
if (SymA.isFunction()) {
125
if (FixupSection.isMetadata())
126
return wasm::R_WASM_FUNCTION_OFFSET_I32;
127
assert(FixupSection.isWasmData());
128
return wasm::R_WASM_TABLE_INDEX_I32;
129
}
130
if (SymA.isGlobal())
131
return wasm::R_WASM_GLOBAL_INDEX_I32;
132
if (auto Section = static_cast<const MCSectionWasm *>(
133
getTargetSection(Fixup.getValue()))) {
134
if (Section->isText())
135
return wasm::R_WASM_FUNCTION_OFFSET_I32;
136
else if (!Section->isWasmData())
137
return wasm::R_WASM_SECTION_OFFSET_I32;
138
}
139
return IsLocRel ? wasm::R_WASM_MEMORY_ADDR_LOCREL_I32
140
: wasm::R_WASM_MEMORY_ADDR_I32;
141
case FK_Data_8:
142
if (SymA.isFunction()) {
143
if (FixupSection.isMetadata())
144
return wasm::R_WASM_FUNCTION_OFFSET_I64;
145
return wasm::R_WASM_TABLE_INDEX_I64;
146
}
147
if (SymA.isGlobal())
148
llvm_unreachable("unimplemented R_WASM_GLOBAL_INDEX_I64");
149
if (auto Section = static_cast<const MCSectionWasm *>(
150
getTargetSection(Fixup.getValue()))) {
151
if (Section->isText())
152
return wasm::R_WASM_FUNCTION_OFFSET_I64;
153
else if (!Section->isWasmData())
154
llvm_unreachable("unimplemented R_WASM_SECTION_OFFSET_I64");
155
}
156
assert(SymA.isData());
157
return wasm::R_WASM_MEMORY_ADDR_I64;
158
default:
159
llvm_unreachable("unimplemented fixup kind");
160
}
161
}
162
163
std::unique_ptr<MCObjectTargetWriter>
164
llvm::createWebAssemblyWasmObjectWriter(bool Is64Bit, bool IsEmscripten) {
165
return std::make_unique<WebAssemblyWasmObjectWriter>(Is64Bit, IsEmscripten);
166
}
167
168