annotate lld/wasm/InputChunks.cpp @ 259:011663b4a808

remove duplicate setjmp in return continuation
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Thu, 12 Oct 2023 15:52:37 +0900
parents 1f2b6ac9f198
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 //===- InputChunks.cpp ----------------------------------------------------===//
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
8
anatofuz
parents:
diff changeset
9 #include "InputChunks.h"
anatofuz
parents:
diff changeset
10 #include "Config.h"
anatofuz
parents:
diff changeset
11 #include "OutputSegment.h"
anatofuz
parents:
diff changeset
12 #include "WriterUtils.h"
anatofuz
parents:
diff changeset
13 #include "lld/Common/ErrorHandler.h"
anatofuz
parents:
diff changeset
14 #include "lld/Common/LLVM.h"
anatofuz
parents:
diff changeset
15 #include "llvm/Support/LEB128.h"
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
16 #include "llvm/Support/xxhash.h"
150
anatofuz
parents:
diff changeset
17
anatofuz
parents:
diff changeset
18 #define DEBUG_TYPE "lld"
anatofuz
parents:
diff changeset
19
anatofuz
parents:
diff changeset
20 using namespace llvm;
anatofuz
parents:
diff changeset
21 using namespace llvm::wasm;
anatofuz
parents:
diff changeset
22 using namespace llvm::support::endian;
anatofuz
parents:
diff changeset
23
anatofuz
parents:
diff changeset
24 namespace lld {
anatofuz
parents:
diff changeset
25 StringRef relocTypeToString(uint8_t relocType) {
anatofuz
parents:
diff changeset
26 switch (relocType) {
anatofuz
parents:
diff changeset
27 #define WASM_RELOC(NAME, REL) \
anatofuz
parents:
diff changeset
28 case REL: \
anatofuz
parents:
diff changeset
29 return #NAME;
anatofuz
parents:
diff changeset
30 #include "llvm/BinaryFormat/WasmRelocs.def"
anatofuz
parents:
diff changeset
31 #undef WASM_RELOC
anatofuz
parents:
diff changeset
32 }
anatofuz
parents:
diff changeset
33 llvm_unreachable("unknown reloc type");
anatofuz
parents:
diff changeset
34 }
anatofuz
parents:
diff changeset
35
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
36 bool relocIs64(uint8_t relocType) {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
37 switch (relocType) {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
38 case R_WASM_MEMORY_ADDR_LEB64:
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
39 case R_WASM_MEMORY_ADDR_SLEB64:
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
40 case R_WASM_MEMORY_ADDR_REL_SLEB64:
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
41 case R_WASM_MEMORY_ADDR_I64:
223
5f17cb93ff66 LLVM13 (2021/7/18)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 221
diff changeset
42 case R_WASM_TABLE_INDEX_SLEB64:
5f17cb93ff66 LLVM13 (2021/7/18)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 221
diff changeset
43 case R_WASM_TABLE_INDEX_I64:
5f17cb93ff66 LLVM13 (2021/7/18)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 221
diff changeset
44 case R_WASM_FUNCTION_OFFSET_I64:
5f17cb93ff66 LLVM13 (2021/7/18)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 221
diff changeset
45 case R_WASM_TABLE_INDEX_REL_SLEB64:
232
70dce7da266c llvm original Jul 20 16:41:34 2021
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 223
diff changeset
46 case R_WASM_MEMORY_ADDR_TLS_SLEB64:
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
47 return true;
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
48 default:
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
49 return false;
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
50 }
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
51 }
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
52
150
anatofuz
parents:
diff changeset
53 std::string toString(const wasm::InputChunk *c) {
236
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
54 return (toString(c->file) + ":(" + c->name + ")").str();
150
anatofuz
parents:
diff changeset
55 }
anatofuz
parents:
diff changeset
56
anatofuz
parents:
diff changeset
57 namespace wasm {
anatofuz
parents:
diff changeset
58 StringRef InputChunk::getComdatName() const {
anatofuz
parents:
diff changeset
59 uint32_t index = getComdat();
anatofuz
parents:
diff changeset
60 if (index == UINT32_MAX)
anatofuz
parents:
diff changeset
61 return StringRef();
anatofuz
parents:
diff changeset
62 return file->getWasmObj()->linkingData().Comdats[index];
anatofuz
parents:
diff changeset
63 }
anatofuz
parents:
diff changeset
64
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
65 uint32_t InputChunk::getSize() const {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
66 if (const auto *ms = dyn_cast<SyntheticMergedChunk>(this))
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
67 return ms->builder.getSize();
150
anatofuz
parents:
diff changeset
68
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
69 if (const auto *f = dyn_cast<InputFunction>(this)) {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
70 if (config->compressRelocations && f->file) {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
71 return f->getCompressedSize();
150
anatofuz
parents:
diff changeset
72 }
anatofuz
parents:
diff changeset
73 }
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
74
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
75 return data().size();
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
76 }
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
77
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
78 uint32_t InputChunk::getInputSize() const {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
79 if (const auto *f = dyn_cast<InputFunction>(this))
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
80 return f->function->Size;
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
81 return getSize();
150
anatofuz
parents:
diff changeset
82 }
anatofuz
parents:
diff changeset
83
anatofuz
parents:
diff changeset
84 // Copy this input chunk to an mmap'ed output file and apply relocations.
anatofuz
parents:
diff changeset
85 void InputChunk::writeTo(uint8_t *buf) const {
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
86 if (const auto *f = dyn_cast<InputFunction>(this)) {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
87 if (file && config->compressRelocations)
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
88 return f->writeCompressed(buf);
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
89 } else if (const auto *ms = dyn_cast<SyntheticMergedChunk>(this)) {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
90 ms->builder.write(buf + outSecOff);
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
91 // Apply relocations
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
92 ms->relocate(buf + outSecOff);
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
93 return;
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
94 }
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
95
150
anatofuz
parents:
diff changeset
96 // Copy contents
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
97 memcpy(buf + outSecOff, data().data(), data().size());
150
anatofuz
parents:
diff changeset
98
anatofuz
parents:
diff changeset
99 // Apply relocations
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
100 relocate(buf + outSecOff);
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
101 }
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
102
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
103 void InputChunk::relocate(uint8_t *buf) const {
150
anatofuz
parents:
diff changeset
104 if (relocations.empty())
anatofuz
parents:
diff changeset
105 return;
anatofuz
parents:
diff changeset
106
anatofuz
parents:
diff changeset
107 LLVM_DEBUG(dbgs() << "applying relocations: " << toString(this)
anatofuz
parents:
diff changeset
108 << " count=" << relocations.size() << "\n");
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
109 int32_t inputSectionOffset = getInputSectionOffset();
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
110 uint64_t tombstone = getTombstone();
150
anatofuz
parents:
diff changeset
111
anatofuz
parents:
diff changeset
112 for (const WasmRelocation &rel : relocations) {
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
113 uint8_t *loc = buf + rel.Offset - inputSectionOffset;
150
anatofuz
parents:
diff changeset
114 LLVM_DEBUG(dbgs() << "apply reloc: type=" << relocTypeToString(rel.Type));
anatofuz
parents:
diff changeset
115 if (rel.Type != R_WASM_TYPE_INDEX_LEB)
anatofuz
parents:
diff changeset
116 LLVM_DEBUG(dbgs() << " sym=" << file->getSymbols()[rel.Index]->getName());
anatofuz
parents:
diff changeset
117 LLVM_DEBUG(dbgs() << " addend=" << rel.Addend << " index=" << rel.Index
223
5f17cb93ff66 LLVM13 (2021/7/18)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 221
diff changeset
118 << " offset=" << rel.Offset << "\n");
236
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
119 // TODO(sbc): Check that the value is within the range of the
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
120 // relocation type below. Most likely we must error out here
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
121 // if its not with range.
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
122 uint64_t value = file->calcNewValue(rel, tombstone, this);
150
anatofuz
parents:
diff changeset
123
anatofuz
parents:
diff changeset
124 switch (rel.Type) {
anatofuz
parents:
diff changeset
125 case R_WASM_TYPE_INDEX_LEB:
anatofuz
parents:
diff changeset
126 case R_WASM_FUNCTION_INDEX_LEB:
anatofuz
parents:
diff changeset
127 case R_WASM_GLOBAL_INDEX_LEB:
223
5f17cb93ff66 LLVM13 (2021/7/18)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 221
diff changeset
128 case R_WASM_TAG_INDEX_LEB:
150
anatofuz
parents:
diff changeset
129 case R_WASM_MEMORY_ADDR_LEB:
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
130 case R_WASM_TABLE_NUMBER_LEB:
236
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
131 encodeULEB128(static_cast<uint32_t>(value), loc, 5);
150
anatofuz
parents:
diff changeset
132 break;
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
133 case R_WASM_MEMORY_ADDR_LEB64:
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
134 encodeULEB128(value, loc, 10);
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
135 break;
150
anatofuz
parents:
diff changeset
136 case R_WASM_TABLE_INDEX_SLEB:
anatofuz
parents:
diff changeset
137 case R_WASM_TABLE_INDEX_REL_SLEB:
anatofuz
parents:
diff changeset
138 case R_WASM_MEMORY_ADDR_SLEB:
anatofuz
parents:
diff changeset
139 case R_WASM_MEMORY_ADDR_REL_SLEB:
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
140 case R_WASM_MEMORY_ADDR_TLS_SLEB:
150
anatofuz
parents:
diff changeset
141 encodeSLEB128(static_cast<int32_t>(value), loc, 5);
anatofuz
parents:
diff changeset
142 break;
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
143 case R_WASM_TABLE_INDEX_SLEB64:
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
144 case R_WASM_TABLE_INDEX_REL_SLEB64:
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
145 case R_WASM_MEMORY_ADDR_SLEB64:
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
146 case R_WASM_MEMORY_ADDR_REL_SLEB64:
232
70dce7da266c llvm original Jul 20 16:41:34 2021
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 223
diff changeset
147 case R_WASM_MEMORY_ADDR_TLS_SLEB64:
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
148 encodeSLEB128(static_cast<int64_t>(value), loc, 10);
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
149 break;
150
anatofuz
parents:
diff changeset
150 case R_WASM_TABLE_INDEX_I32:
anatofuz
parents:
diff changeset
151 case R_WASM_MEMORY_ADDR_I32:
anatofuz
parents:
diff changeset
152 case R_WASM_FUNCTION_OFFSET_I32:
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
153 case R_WASM_FUNCTION_INDEX_I32:
150
anatofuz
parents:
diff changeset
154 case R_WASM_SECTION_OFFSET_I32:
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
155 case R_WASM_GLOBAL_INDEX_I32:
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
156 case R_WASM_MEMORY_ADDR_LOCREL_I32:
150
anatofuz
parents:
diff changeset
157 write32le(loc, value);
anatofuz
parents:
diff changeset
158 break;
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
159 case R_WASM_TABLE_INDEX_I64:
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
160 case R_WASM_MEMORY_ADDR_I64:
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
161 case R_WASM_FUNCTION_OFFSET_I64:
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
162 write64le(loc, value);
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
163 break;
150
anatofuz
parents:
diff changeset
164 default:
anatofuz
parents:
diff changeset
165 llvm_unreachable("unknown relocation type");
anatofuz
parents:
diff changeset
166 }
anatofuz
parents:
diff changeset
167 }
anatofuz
parents:
diff changeset
168 }
anatofuz
parents:
diff changeset
169
anatofuz
parents:
diff changeset
170 // Copy relocation entries to a given output stream.
anatofuz
parents:
diff changeset
171 // This function is used only when a user passes "-r". For a regular link,
anatofuz
parents:
diff changeset
172 // we consume relocations instead of copying them to an output file.
anatofuz
parents:
diff changeset
173 void InputChunk::writeRelocations(raw_ostream &os) const {
anatofuz
parents:
diff changeset
174 if (relocations.empty())
anatofuz
parents:
diff changeset
175 return;
anatofuz
parents:
diff changeset
176
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
177 int32_t off = outSecOff - getInputSectionOffset();
150
anatofuz
parents:
diff changeset
178 LLVM_DEBUG(dbgs() << "writeRelocations: " << file->getName()
anatofuz
parents:
diff changeset
179 << " offset=" << Twine(off) << "\n");
anatofuz
parents:
diff changeset
180
anatofuz
parents:
diff changeset
181 for (const WasmRelocation &rel : relocations) {
anatofuz
parents:
diff changeset
182 writeUleb128(os, rel.Type, "reloc type");
anatofuz
parents:
diff changeset
183 writeUleb128(os, rel.Offset + off, "reloc offset");
anatofuz
parents:
diff changeset
184 writeUleb128(os, file->calcNewIndex(rel), "reloc index");
anatofuz
parents:
diff changeset
185
anatofuz
parents:
diff changeset
186 if (relocTypeHasAddend(rel.Type))
anatofuz
parents:
diff changeset
187 writeSleb128(os, file->calcNewAddend(rel), "reloc addend");
anatofuz
parents:
diff changeset
188 }
anatofuz
parents:
diff changeset
189 }
anatofuz
parents:
diff changeset
190
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
191 uint64_t InputChunk::getTombstone() const {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
192 if (const auto *s = dyn_cast<InputSection>(this)) {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
193 return s->tombstoneValue;
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
194 }
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
195
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
196 return 0;
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
197 }
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
198
150
anatofuz
parents:
diff changeset
199 void InputFunction::setFunctionIndex(uint32_t index) {
236
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
200 LLVM_DEBUG(dbgs() << "InputFunction::setFunctionIndex: " << name << " -> "
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
201 << index << "\n");
150
anatofuz
parents:
diff changeset
202 assert(!hasFunctionIndex());
anatofuz
parents:
diff changeset
203 functionIndex = index;
anatofuz
parents:
diff changeset
204 }
anatofuz
parents:
diff changeset
205
anatofuz
parents:
diff changeset
206 void InputFunction::setTableIndex(uint32_t index) {
236
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
207 LLVM_DEBUG(dbgs() << "InputFunction::setTableIndex: " << name << " -> "
150
anatofuz
parents:
diff changeset
208 << index << "\n");
anatofuz
parents:
diff changeset
209 assert(!hasTableIndex());
anatofuz
parents:
diff changeset
210 tableIndex = index;
anatofuz
parents:
diff changeset
211 }
anatofuz
parents:
diff changeset
212
anatofuz
parents:
diff changeset
213 // Write a relocation value without padding and return the number of bytes
anatofuz
parents:
diff changeset
214 // witten.
anatofuz
parents:
diff changeset
215 static unsigned writeCompressedReloc(uint8_t *buf, const WasmRelocation &rel,
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
216 uint64_t value) {
150
anatofuz
parents:
diff changeset
217 switch (rel.Type) {
anatofuz
parents:
diff changeset
218 case R_WASM_TYPE_INDEX_LEB:
anatofuz
parents:
diff changeset
219 case R_WASM_FUNCTION_INDEX_LEB:
anatofuz
parents:
diff changeset
220 case R_WASM_GLOBAL_INDEX_LEB:
223
5f17cb93ff66 LLVM13 (2021/7/18)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 221
diff changeset
221 case R_WASM_TAG_INDEX_LEB:
150
anatofuz
parents:
diff changeset
222 case R_WASM_MEMORY_ADDR_LEB:
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
223 case R_WASM_MEMORY_ADDR_LEB64:
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
224 case R_WASM_TABLE_NUMBER_LEB:
150
anatofuz
parents:
diff changeset
225 return encodeULEB128(value, buf);
anatofuz
parents:
diff changeset
226 case R_WASM_TABLE_INDEX_SLEB:
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
227 case R_WASM_TABLE_INDEX_SLEB64:
150
anatofuz
parents:
diff changeset
228 case R_WASM_MEMORY_ADDR_SLEB:
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
229 case R_WASM_MEMORY_ADDR_SLEB64:
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
230 return encodeSLEB128(static_cast<int64_t>(value), buf);
150
anatofuz
parents:
diff changeset
231 default:
anatofuz
parents:
diff changeset
232 llvm_unreachable("unexpected relocation type");
anatofuz
parents:
diff changeset
233 }
anatofuz
parents:
diff changeset
234 }
anatofuz
parents:
diff changeset
235
anatofuz
parents:
diff changeset
236 static unsigned getRelocWidthPadded(const WasmRelocation &rel) {
anatofuz
parents:
diff changeset
237 switch (rel.Type) {
anatofuz
parents:
diff changeset
238 case R_WASM_TYPE_INDEX_LEB:
anatofuz
parents:
diff changeset
239 case R_WASM_FUNCTION_INDEX_LEB:
anatofuz
parents:
diff changeset
240 case R_WASM_GLOBAL_INDEX_LEB:
223
5f17cb93ff66 LLVM13 (2021/7/18)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 221
diff changeset
241 case R_WASM_TAG_INDEX_LEB:
150
anatofuz
parents:
diff changeset
242 case R_WASM_MEMORY_ADDR_LEB:
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
243 case R_WASM_TABLE_NUMBER_LEB:
150
anatofuz
parents:
diff changeset
244 case R_WASM_TABLE_INDEX_SLEB:
anatofuz
parents:
diff changeset
245 case R_WASM_MEMORY_ADDR_SLEB:
anatofuz
parents:
diff changeset
246 return 5;
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
247 case R_WASM_TABLE_INDEX_SLEB64:
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
248 case R_WASM_MEMORY_ADDR_LEB64:
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
249 case R_WASM_MEMORY_ADDR_SLEB64:
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
250 return 10;
150
anatofuz
parents:
diff changeset
251 default:
anatofuz
parents:
diff changeset
252 llvm_unreachable("unexpected relocation type");
anatofuz
parents:
diff changeset
253 }
anatofuz
parents:
diff changeset
254 }
anatofuz
parents:
diff changeset
255
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
256 static unsigned getRelocWidth(const WasmRelocation &rel, uint64_t value) {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
257 uint8_t buf[10];
150
anatofuz
parents:
diff changeset
258 return writeCompressedReloc(buf, rel, value);
anatofuz
parents:
diff changeset
259 }
anatofuz
parents:
diff changeset
260
anatofuz
parents:
diff changeset
261 // Relocations of type LEB and SLEB in the code section are padded to 5 bytes
anatofuz
parents:
diff changeset
262 // so that a fast linker can blindly overwrite them without needing to worry
anatofuz
parents:
diff changeset
263 // about the number of bytes needed to encode the values.
anatofuz
parents:
diff changeset
264 // However, for optimal output the code section can be compressed to remove
anatofuz
parents:
diff changeset
265 // the padding then outputting non-relocatable files.
anatofuz
parents:
diff changeset
266 // In this case we need to perform a size calculation based on the value at each
anatofuz
parents:
diff changeset
267 // relocation. At best we end up saving 4 bytes for each relocation entry.
anatofuz
parents:
diff changeset
268 //
anatofuz
parents:
diff changeset
269 // This function only computes the final output size. It must be called
anatofuz
parents:
diff changeset
270 // before getSize() is used to calculate of layout of the code section.
anatofuz
parents:
diff changeset
271 void InputFunction::calculateSize() {
anatofuz
parents:
diff changeset
272 if (!file || !config->compressRelocations)
anatofuz
parents:
diff changeset
273 return;
anatofuz
parents:
diff changeset
274
236
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
275 LLVM_DEBUG(dbgs() << "calculateSize: " << name << "\n");
150
anatofuz
parents:
diff changeset
276
anatofuz
parents:
diff changeset
277 const uint8_t *secStart = file->codeSection->Content.data();
anatofuz
parents:
diff changeset
278 const uint8_t *funcStart = secStart + getInputSectionOffset();
anatofuz
parents:
diff changeset
279 uint32_t functionSizeLength;
anatofuz
parents:
diff changeset
280 decodeULEB128(funcStart, &functionSizeLength);
anatofuz
parents:
diff changeset
281
anatofuz
parents:
diff changeset
282 uint32_t start = getInputSectionOffset();
anatofuz
parents:
diff changeset
283 uint32_t end = start + function->Size;
anatofuz
parents:
diff changeset
284
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
285 uint64_t tombstone = getTombstone();
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
286
150
anatofuz
parents:
diff changeset
287 uint32_t lastRelocEnd = start + functionSizeLength;
anatofuz
parents:
diff changeset
288 for (const WasmRelocation &rel : relocations) {
anatofuz
parents:
diff changeset
289 LLVM_DEBUG(dbgs() << " region: " << (rel.Offset - lastRelocEnd) << "\n");
anatofuz
parents:
diff changeset
290 compressedFuncSize += rel.Offset - lastRelocEnd;
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
291 compressedFuncSize +=
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
292 getRelocWidth(rel, file->calcNewValue(rel, tombstone, this));
150
anatofuz
parents:
diff changeset
293 lastRelocEnd = rel.Offset + getRelocWidthPadded(rel);
anatofuz
parents:
diff changeset
294 }
anatofuz
parents:
diff changeset
295 LLVM_DEBUG(dbgs() << " final region: " << (end - lastRelocEnd) << "\n");
anatofuz
parents:
diff changeset
296 compressedFuncSize += end - lastRelocEnd;
anatofuz
parents:
diff changeset
297
anatofuz
parents:
diff changeset
298 // Now we know how long the resulting function is we can add the encoding
anatofuz
parents:
diff changeset
299 // of its length
anatofuz
parents:
diff changeset
300 uint8_t buf[5];
anatofuz
parents:
diff changeset
301 compressedSize = compressedFuncSize + encodeULEB128(compressedFuncSize, buf);
anatofuz
parents:
diff changeset
302
anatofuz
parents:
diff changeset
303 LLVM_DEBUG(dbgs() << " calculateSize orig: " << function->Size << "\n");
anatofuz
parents:
diff changeset
304 LLVM_DEBUG(dbgs() << " calculateSize new: " << compressedSize << "\n");
anatofuz
parents:
diff changeset
305 }
anatofuz
parents:
diff changeset
306
anatofuz
parents:
diff changeset
307 // Override the default writeTo method so that we can (optionally) write the
anatofuz
parents:
diff changeset
308 // compressed version of the function.
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
309 void InputFunction::writeCompressed(uint8_t *buf) const {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
310 buf += outSecOff;
150
anatofuz
parents:
diff changeset
311 uint8_t *orig = buf;
anatofuz
parents:
diff changeset
312 (void)orig;
anatofuz
parents:
diff changeset
313
anatofuz
parents:
diff changeset
314 const uint8_t *secStart = file->codeSection->Content.data();
anatofuz
parents:
diff changeset
315 const uint8_t *funcStart = secStart + getInputSectionOffset();
anatofuz
parents:
diff changeset
316 const uint8_t *end = funcStart + function->Size;
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
317 uint64_t tombstone = getTombstone();
150
anatofuz
parents:
diff changeset
318 uint32_t count;
anatofuz
parents:
diff changeset
319 decodeULEB128(funcStart, &count);
anatofuz
parents:
diff changeset
320 funcStart += count;
anatofuz
parents:
diff changeset
321
236
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
322 LLVM_DEBUG(dbgs() << "write func: " << name << "\n");
150
anatofuz
parents:
diff changeset
323 buf += encodeULEB128(compressedFuncSize, buf);
anatofuz
parents:
diff changeset
324 const uint8_t *lastRelocEnd = funcStart;
anatofuz
parents:
diff changeset
325 for (const WasmRelocation &rel : relocations) {
anatofuz
parents:
diff changeset
326 unsigned chunkSize = (secStart + rel.Offset) - lastRelocEnd;
anatofuz
parents:
diff changeset
327 LLVM_DEBUG(dbgs() << " write chunk: " << chunkSize << "\n");
anatofuz
parents:
diff changeset
328 memcpy(buf, lastRelocEnd, chunkSize);
anatofuz
parents:
diff changeset
329 buf += chunkSize;
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
330 buf += writeCompressedReloc(buf, rel,
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
331 file->calcNewValue(rel, tombstone, this));
150
anatofuz
parents:
diff changeset
332 lastRelocEnd = secStart + rel.Offset + getRelocWidthPadded(rel);
anatofuz
parents:
diff changeset
333 }
anatofuz
parents:
diff changeset
334
anatofuz
parents:
diff changeset
335 unsigned chunkSize = end - lastRelocEnd;
anatofuz
parents:
diff changeset
336 LLVM_DEBUG(dbgs() << " write final chunk: " << chunkSize << "\n");
anatofuz
parents:
diff changeset
337 memcpy(buf, lastRelocEnd, chunkSize);
anatofuz
parents:
diff changeset
338 LLVM_DEBUG(dbgs() << " total: " << (buf + chunkSize - orig) << "\n");
anatofuz
parents:
diff changeset
339 }
anatofuz
parents:
diff changeset
340
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
341 uint64_t InputChunk::getChunkOffset(uint64_t offset) const {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
342 if (const auto *ms = dyn_cast<MergeInputChunk>(this)) {
236
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
343 LLVM_DEBUG(dbgs() << "getChunkOffset(merged): " << name << "\n");
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
344 LLVM_DEBUG(dbgs() << "offset: " << offset << "\n");
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
345 LLVM_DEBUG(dbgs() << "parentOffset: " << ms->getParentOffset(offset)
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
346 << "\n");
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
347 assert(ms->parent);
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
348 return ms->parent->getChunkOffset(ms->getParentOffset(offset));
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
349 }
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
350 return outputSegmentOffset + offset;
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
351 }
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
352
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
353 uint64_t InputChunk::getOffset(uint64_t offset) const {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
354 return outSecOff + getChunkOffset(offset);
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
355 }
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
356
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
357 uint64_t InputChunk::getVA(uint64_t offset) const {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
358 return (outputSeg ? outputSeg->startVA : 0) + getChunkOffset(offset);
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
359 }
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
360
150
anatofuz
parents:
diff changeset
361 // Generate code to apply relocations to the data section at runtime.
236
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
362 // This is only called when generating shared libraries (PIC) where address are
150
anatofuz
parents:
diff changeset
363 // not known at static link time.
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
364 void InputChunk::generateRelocationCode(raw_ostream &os) const {
236
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
365 LLVM_DEBUG(dbgs() << "generating runtime relocations: " << name
150
anatofuz
parents:
diff changeset
366 << " count=" << relocations.size() << "\n");
anatofuz
parents:
diff changeset
367
236
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
368 bool is64 = config->is64.value_or(false);
223
5f17cb93ff66 LLVM13 (2021/7/18)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 221
diff changeset
369 unsigned opcode_ptr_const = is64 ? WASM_OPCODE_I64_CONST
5f17cb93ff66 LLVM13 (2021/7/18)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 221
diff changeset
370 : WASM_OPCODE_I32_CONST;
5f17cb93ff66 LLVM13 (2021/7/18)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 221
diff changeset
371 unsigned opcode_ptr_add = is64 ? WASM_OPCODE_I64_ADD
5f17cb93ff66 LLVM13 (2021/7/18)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 221
diff changeset
372 : WASM_OPCODE_I32_ADD;
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
373
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
374 uint64_t tombstone = getTombstone();
150
anatofuz
parents:
diff changeset
375 // TODO(sbc): Encode the relocations in the data section and write a loop
anatofuz
parents:
diff changeset
376 // here to apply them.
anatofuz
parents:
diff changeset
377 for (const WasmRelocation &rel : relocations) {
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
378 uint64_t offset = getVA(rel.Offset) - getInputSectionOffset();
150
anatofuz
parents:
diff changeset
379
236
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
380 Symbol *sym = file->getSymbol(rel);
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
381 if (!config->isPic && sym->isDefined())
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
382 continue;
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
383
150
anatofuz
parents:
diff changeset
384 LLVM_DEBUG(dbgs() << "gen reloc: type=" << relocTypeToString(rel.Type)
anatofuz
parents:
diff changeset
385 << " addend=" << rel.Addend << " index=" << rel.Index
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
386 << " output offset=" << offset << "\n");
150
anatofuz
parents:
diff changeset
387
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
388 // Calculate the address at which to apply the relocation
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
389 writeU8(os, opcode_ptr_const, "CONST");
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
390 writeSleb128(os, offset, "offset");
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
391
236
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
392 // In PIC mode we need to add the __memory_base
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
393 if (config->isPic) {
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
394 writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
395 if (isTLS())
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
396 writeUleb128(os, WasmSym::tlsBase->getGlobalIndex(), "tls_base");
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
397 else
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
398 writeUleb128(os, WasmSym::memoryBase->getGlobalIndex(), "memory_base");
236
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
399 writeU8(os, opcode_ptr_add, "ADD");
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
400 }
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
401
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
402 // Now figure out what we want to store at this location
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
403 bool is64 = relocIs64(rel.Type);
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
404 unsigned opcode_reloc_const =
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
405 is64 ? WASM_OPCODE_I64_CONST : WASM_OPCODE_I32_CONST;
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
406 unsigned opcode_reloc_add =
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
407 is64 ? WASM_OPCODE_I64_ADD : WASM_OPCODE_I32_ADD;
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
408 unsigned opcode_reloc_store =
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
409 is64 ? WASM_OPCODE_I64_STORE : WASM_OPCODE_I32_STORE;
150
anatofuz
parents:
diff changeset
410
anatofuz
parents:
diff changeset
411 if (sym->hasGOTIndex()) {
anatofuz
parents:
diff changeset
412 writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");
anatofuz
parents:
diff changeset
413 writeUleb128(os, sym->getGOTIndex(), "global index");
anatofuz
parents:
diff changeset
414 if (rel.Addend) {
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
415 writeU8(os, opcode_reloc_const, "CONST");
150
anatofuz
parents:
diff changeset
416 writeSleb128(os, rel.Addend, "addend");
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
417 writeU8(os, opcode_reloc_add, "ADD");
150
anatofuz
parents:
diff changeset
418 }
anatofuz
parents:
diff changeset
419 } else {
236
c4bab56944e8 LLVM 16
kono
parents: 232
diff changeset
420 assert(config->isPic);
150
anatofuz
parents:
diff changeset
421 const GlobalSymbol* baseSymbol = WasmSym::memoryBase;
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
422 if (rel.Type == R_WASM_TABLE_INDEX_I32 ||
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
423 rel.Type == R_WASM_TABLE_INDEX_I64)
150
anatofuz
parents:
diff changeset
424 baseSymbol = WasmSym::tableBase;
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
425 else if (sym->isTLS())
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
426 baseSymbol = WasmSym::tlsBase;
150
anatofuz
parents:
diff changeset
427 writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");
anatofuz
parents:
diff changeset
428 writeUleb128(os, baseSymbol->getGlobalIndex(), "base");
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
429 writeU8(os, opcode_reloc_const, "CONST");
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
430 writeSleb128(os, file->calcNewValue(rel, tombstone, this), "offset");
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
431 writeU8(os, opcode_reloc_add, "ADD");
150
anatofuz
parents:
diff changeset
432 }
anatofuz
parents:
diff changeset
433
anatofuz
parents:
diff changeset
434 // Store that value at the virtual address
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
435 writeU8(os, opcode_reloc_store, "I32_STORE");
150
anatofuz
parents:
diff changeset
436 writeUleb128(os, 2, "align");
anatofuz
parents:
diff changeset
437 writeUleb128(os, 0, "offset");
anatofuz
parents:
diff changeset
438 }
anatofuz
parents:
diff changeset
439 }
anatofuz
parents:
diff changeset
440
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
441 // Split WASM_SEG_FLAG_STRINGS section. Such a section is a sequence of
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
442 // null-terminated strings.
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
443 void MergeInputChunk::splitStrings(ArrayRef<uint8_t> data) {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
444 LLVM_DEBUG(llvm::dbgs() << "splitStrings\n");
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
445 size_t off = 0;
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
446 StringRef s = toStringRef(data);
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
447
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
448 while (!s.empty()) {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
449 size_t end = s.find(0);
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
450 if (end == StringRef::npos)
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
451 fatal(toString(this) + ": string is not null terminated");
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
452 size_t size = end + 1;
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
453
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
454 pieces.emplace_back(off, xxh3_64bits(s.substr(0, size)), true);
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
455 s = s.substr(size);
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
456 off += size;
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
457 }
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
458 }
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
459
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
460 // This function is called after we obtain a complete list of input sections
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
461 // that need to be linked. This is responsible to split section contents
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
462 // into small chunks for further processing.
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
463 //
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
464 // Note that this function is called from parallelForEach. This must be
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
465 // thread-safe (i.e. no memory allocation from the pools).
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
466 void MergeInputChunk::splitIntoPieces() {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
467 assert(pieces.empty());
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
468 // As of now we only support WASM_SEG_FLAG_STRINGS but in the future we
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
469 // could add other types of splitting (see ELF's splitIntoPieces).
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
470 assert(flags & WASM_SEG_FLAG_STRINGS);
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
471 splitStrings(data());
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
472 }
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
473
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
474 SectionPiece *MergeInputChunk::getSectionPiece(uint64_t offset) {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
475 if (this->data().size() <= offset)
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
476 fatal(toString(this) + ": offset is outside the section");
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
477
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
478 // If Offset is not at beginning of a section piece, it is not in the map.
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
479 // In that case we need to do a binary search of the original section piece
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
480 // vector.
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
481 auto it = partition_point(
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
482 pieces, [=](SectionPiece p) { return p.inputOff <= offset; });
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
483 return &it[-1];
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
484 }
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
485
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
486 // Returns the offset in an output section for a given input offset.
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
487 // Because contents of a mergeable section is not contiguous in output,
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
488 // it is not just an addition to a base output offset.
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
489 uint64_t MergeInputChunk::getParentOffset(uint64_t offset) const {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
490 // If Offset is not at beginning of a section piece, it is not in the map.
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
491 // In that case we need to search from the original section piece vector.
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
492 const SectionPiece *piece = getSectionPiece(offset);
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
493 uint64_t addend = offset - piece->inputOff;
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
494 return piece->outputOff + addend;
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
495 }
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
496
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
497 void SyntheticMergedChunk::finalizeContents() {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
498 // Add all string pieces to the string table builder to create section
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
499 // contents.
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
500 for (MergeInputChunk *sec : chunks)
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
501 for (size_t i = 0, e = sec->pieces.size(); i != e; ++i)
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
502 if (sec->pieces[i].live)
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
503 builder.add(sec->getData(i));
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
504
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
505 // Fix the string table content. After this, the contents will never change.
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
506 builder.finalize();
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
507
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
508 // finalize() fixed tail-optimized strings, so we can now get
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
509 // offsets of strings. Get an offset for each string and save it
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
510 // to a corresponding SectionPiece for easy access.
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
511 for (MergeInputChunk *sec : chunks)
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
512 for (size_t i = 0, e = sec->pieces.size(); i != e; ++i)
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
513 if (sec->pieces[i].live)
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
514 sec->pieces[i].outputOff = builder.getOffset(sec->getData(i));
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
515 }
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
516
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
517 uint64_t InputSection::getTombstoneForSection(StringRef name) {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
518 // When a function is not live we need to update relocations referring to it.
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
519 // If they occur in DWARF debug symbols, we want to change the pc of the
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
520 // function to -1 to avoid overlapping with a valid range. However for the
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
521 // debug_ranges and debug_loc sections that would conflict with the existing
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
522 // meaning of -1 so we use -2.
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
523 if (name.equals(".debug_ranges") || name.equals(".debug_loc"))
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
524 return UINT64_C(-2);
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
525 if (name.starts_with(".debug_"))
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
526 return UINT64_C(-1);
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
527 // If the function occurs in an function attribute section change it to -1 since
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
528 // 0 is a valid function index.
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
529 if (name.starts_with("llvm.func_attr."))
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
530 return UINT64_C(-1);
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
531 // Returning 0 means there is no tombstone value for this section, and relocation
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
532 // will just use the addend.
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
533 return 0;
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
534 }
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
535
150
anatofuz
parents:
diff changeset
536 } // namespace wasm
anatofuz
parents:
diff changeset
537 } // namespace lld