blob: 34cade914f2f21b32ee937dcc3c8659fc607b0bf [file] [log] [blame]
Sam Cleggc94d3932017-11-17 18:14:09 +00001//===- InputFiles.cpp -----------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "InputFiles.h"
11
12#include "Config.h"
Sam Clegg5fa274b2018-01-10 01:13:34 +000013#include "InputChunks.h"
Sam Cleggc94d3932017-11-17 18:14:09 +000014#include "SymbolTable.h"
15#include "lld/Common/ErrorHandler.h"
Rui Ueyama2017d522017-11-28 20:39:17 +000016#include "lld/Common/Memory.h"
Sam Cleggc94d3932017-11-17 18:14:09 +000017#include "llvm/Object/Binary.h"
18#include "llvm/Object/Wasm.h"
19#include "llvm/Support/raw_ostream.h"
20
21#define DEBUG_TYPE "lld"
22
23using namespace lld;
24using namespace lld::wasm;
25
26using namespace llvm;
27using namespace llvm::object;
28using namespace llvm::wasm;
29
30Optional<MemoryBufferRef> lld::wasm::readFile(StringRef Path) {
31 log("Loading: " + Path);
32
33 auto MBOrErr = MemoryBuffer::getFile(Path);
34 if (auto EC = MBOrErr.getError()) {
35 error("cannot open " + Path + ": " + EC.message());
36 return None;
37 }
38 std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
39 MemoryBufferRef MBRef = MB->getMemBufferRef();
40 make<std::unique_ptr<MemoryBuffer>>(std::move(MB)); // take MB ownership
41
42 return MBRef;
43}
44
45void ObjFile::dumpInfo() const {
Sam Clegg8d146bb2018-01-09 23:56:44 +000046 log("info for: " + getName() + "\n" +
47 " Total Functions : " + Twine(FunctionSymbols.size()) + "\n" +
48 " Total Globals : " + Twine(GlobalSymbols.size()) + "\n" +
49 " Function Imports : " + Twine(NumFunctionImports) + "\n" +
50 " Global Imports : " + Twine(NumGlobalImports) + "\n" +
51 " Table Entries : " + Twine(TableSymbols.size()) + "\n");
Sam Cleggc94d3932017-11-17 18:14:09 +000052}
53
Sam Clegg8d146bb2018-01-09 23:56:44 +000054uint32_t ObjFile::getRelocatedAddress(uint32_t GlobalIndex) const {
55 return GlobalSymbols[GlobalIndex]->getVirtualAddress();
Sam Cleggc94d3932017-11-17 18:14:09 +000056}
57
58uint32_t ObjFile::relocateFunctionIndex(uint32_t Original) const {
Sam Clegg8d146bb2018-01-09 23:56:44 +000059 Symbol *Sym = FunctionSymbols[Original];
Sam Clegg74fe0ba2017-12-07 01:51:24 +000060 uint32_t Index = Sym->getOutputIndex();
61 DEBUG(dbgs() << "relocateFunctionIndex: " << toString(*Sym) << ": "
62 << Original << " -> " << Index << "\n");
Sam Cleggc94d3932017-11-17 18:14:09 +000063 return Index;
64}
65
66uint32_t ObjFile::relocateTypeIndex(uint32_t Original) const {
67 return TypeMap[Original];
68}
69
70uint32_t ObjFile::relocateTableIndex(uint32_t Original) const {
Sam Clegg8d146bb2018-01-09 23:56:44 +000071 Symbol *Sym = TableSymbols[Original];
Sam Clegg87e61922018-01-08 23:39:11 +000072 uint32_t Index = Sym->hasTableIndex() ? Sym->getTableIndex() : 0;
Sam Cleggfc1a9122017-12-11 22:00:56 +000073 DEBUG(dbgs() << "relocateTableIndex: " << toString(*Sym) << ": " << Original
74 << " -> " << Index << "\n");
75 return Index;
Sam Cleggc94d3932017-11-17 18:14:09 +000076}
77
78uint32_t ObjFile::relocateGlobalIndex(uint32_t Original) const {
Sam Clegg8d146bb2018-01-09 23:56:44 +000079 Symbol *Sym = GlobalSymbols[Original];
Sam Clegg87e61922018-01-08 23:39:11 +000080 uint32_t Index = Sym->hasOutputIndex() ? Sym->getOutputIndex() : 0;
Sam Clegg74fe0ba2017-12-07 01:51:24 +000081 DEBUG(dbgs() << "relocateGlobalIndex: " << toString(*Sym) << ": " << Original
82 << " -> " << Index << "\n");
Sam Cleggc94d3932017-11-17 18:14:09 +000083 return Index;
84}
85
Sam Cleggd96d9352018-01-10 19:22:42 +000086// Relocations contain an index into the function, global or table index
87// space of the input file. This function takes a relocation and returns the
88// relocated index (i.e. translates from the input index space to the output
89// index space).
90uint32_t ObjFile::calcNewIndex(const WasmRelocation &Reloc) const {
91 switch (Reloc.Type) {
92 case R_WEBASSEMBLY_TYPE_INDEX_LEB:
93 return relocateTypeIndex(Reloc.Index);
94 case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
95 return relocateFunctionIndex(Reloc.Index);
96 case R_WEBASSEMBLY_TABLE_INDEX_I32:
97 case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
98 return relocateTableIndex(Reloc.Index);
99 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
100 case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
101 case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
102 case R_WEBASSEMBLY_MEMORY_ADDR_I32:
103 return relocateGlobalIndex(Reloc.Index);
104 default:
105 llvm_unreachable("unknown relocation type");
106 }
107}
108
Sam Cleggc94d3932017-11-17 18:14:09 +0000109void ObjFile::parse() {
110 // Parse a memory buffer as a wasm file.
111 DEBUG(dbgs() << "Parsing object: " << toString(this) << "\n");
Rui Ueyamabdc51502017-12-06 22:08:17 +0000112 std::unique_ptr<Binary> Bin = CHECK(createBinary(MB), toString(this));
Sam Cleggc94d3932017-11-17 18:14:09 +0000113
114 auto *Obj = dyn_cast<WasmObjectFile>(Bin.get());
115 if (!Obj)
116 fatal(toString(this) + ": not a wasm file");
117 if (!Obj->isRelocatableObject())
118 fatal(toString(this) + ": not a relocatable wasm file");
119
120 Bin.release();
121 WasmObj.reset(Obj);
122
123 // Find the code and data sections. Wasm objects can have at most one code
124 // and one data section.
125 for (const SectionRef &Sec : WasmObj->sections()) {
126 const WasmSection &Section = WasmObj->getWasmSection(Sec);
127 if (Section.Type == WASM_SEC_CODE)
128 CodeSection = &Section;
129 else if (Section.Type == WASM_SEC_DATA)
130 DataSection = &Section;
131 }
132
133 initializeSymbols();
134}
135
136// Return the InputSegment in which a given symbol is defined.
Sam Clegg8d146bb2018-01-09 23:56:44 +0000137InputSegment *ObjFile::getSegment(const WasmSymbol &WasmSym) const {
Sam Cleggc94d3932017-11-17 18:14:09 +0000138 uint32_t Address = WasmObj->getWasmSymbolValue(WasmSym);
139 for (InputSegment *Segment : Segments) {
140 if (Address >= Segment->startVA() && Address < Segment->endVA()) {
141 DEBUG(dbgs() << "Found symbol in segment: " << WasmSym.Name << " -> "
142 << Segment->getName() << "\n");
143
144 return Segment;
145 }
146 }
Rui Ueyama29ceba72017-12-15 00:07:15 +0000147 error("symbol not found in any segment: " + WasmSym.Name);
Sam Cleggc94d3932017-11-17 18:14:09 +0000148 return nullptr;
149}
150
Sam Clegg20db3812018-01-10 00:52:20 +0000151// Get the value stored in the wasm global represented by this symbol.
152// This represents the virtual address of the symbol in the input file.
153uint32_t ObjFile::getGlobalValue(const WasmSymbol &Sym) const {
154 const WasmGlobal &Global =
155 getWasmObj()->globals()[Sym.ElementIndex - NumGlobalImports];
156 assert(Global.Type == llvm::wasm::WASM_TYPE_I32);
157 return Global.InitExpr.Value.Int32;
158}
159
Sam Clegg8d146bb2018-01-09 23:56:44 +0000160// Get the signature for a given function symbol, either by looking
161// it up in function sections (for defined functions), of the imports section
162// (for imported functions).
163const WasmSignature *ObjFile::getFunctionSig(const WasmSymbol &Sym) const {
164 DEBUG(dbgs() << "getFunctionSig: " << Sym.Name << "\n");
165 return &WasmObj->types()[Sym.FunctionType];
166}
167
168InputFunction *ObjFile::getFunction(const WasmSymbol &Sym) const {
169 uint32_t FunctionIndex = Sym.ElementIndex - NumFunctionImports;
170 return Functions[FunctionIndex];
171}
172
Sam Cleggc94d3932017-11-17 18:14:09 +0000173void ObjFile::initializeSymbols() {
174 Symbols.reserve(WasmObj->getNumberOfSymbols());
175
176 for (const WasmImport &Import : WasmObj->imports()) {
177 switch (Import.Kind) {
178 case WASM_EXTERNAL_FUNCTION:
Sam Clegg8d146bb2018-01-09 23:56:44 +0000179 ++NumFunctionImports;
Sam Cleggc94d3932017-11-17 18:14:09 +0000180 break;
181 case WASM_EXTERNAL_GLOBAL:
Sam Clegg8d146bb2018-01-09 23:56:44 +0000182 ++NumGlobalImports;
Sam Cleggc94d3932017-11-17 18:14:09 +0000183 break;
184 }
185 }
186
Sam Clegg8d146bb2018-01-09 23:56:44 +0000187 FunctionSymbols.resize(NumFunctionImports + WasmObj->functions().size());
188 GlobalSymbols.resize(NumGlobalImports + WasmObj->globals().size());
Sam Cleggc94d3932017-11-17 18:14:09 +0000189
Sam Cleggf61676a2017-12-17 17:52:01 +0000190 for (const WasmSegment &S : WasmObj->dataSegments()) {
Sam Clegg50686852018-01-12 18:35:13 +0000191 InputSegment *Seg = make<InputSegment>(S, this);
Sam Clegg5fa274b2018-01-10 01:13:34 +0000192 Seg->copyRelocations(*DataSection);
Sam Cleggf61676a2017-12-17 17:52:01 +0000193 Segments.emplace_back(Seg);
194 }
Sam Cleggc94d3932017-11-17 18:14:09 +0000195
Sam Clegg8d146bb2018-01-09 23:56:44 +0000196 ArrayRef<WasmFunction> Funcs = WasmObj->functions();
197 ArrayRef<uint32_t> FuncTypes = WasmObj->functionTypes();
198 ArrayRef<WasmSignature> Types = WasmObj->types();
199 for (size_t I = 0; I < Funcs.size(); ++I) {
200 const WasmFunction &Func = Funcs[I];
201 const WasmSignature &Sig = Types[FuncTypes[I]];
Sam Clegg50686852018-01-12 18:35:13 +0000202 InputFunction *F = make<InputFunction>(Sig, &Func, this);
Sam Clegg5fa274b2018-01-10 01:13:34 +0000203 F->copyRelocations(*CodeSection);
204 Functions.emplace_back(F);
Sam Clegg8d146bb2018-01-09 23:56:44 +0000205 }
206
Sam Cleggfc1a9122017-12-11 22:00:56 +0000207 // Populate `FunctionSymbols` and `GlobalSymbols` based on the WasmSymbols
208 // in the object
Sam Cleggc94d3932017-11-17 18:14:09 +0000209 for (const SymbolRef &Sym : WasmObj->symbols()) {
210 const WasmSymbol &WasmSym = WasmObj->getWasmSymbol(Sym.getRawDataRefImpl());
Sam Cleggfc1a9122017-12-11 22:00:56 +0000211 Symbol *S;
Sam Cleggc94d3932017-11-17 18:14:09 +0000212 switch (WasmSym.Type) {
213 case WasmSymbol::SymbolType::FUNCTION_IMPORT:
Sam Clegg20db3812018-01-10 00:52:20 +0000214 S = createUndefined(WasmSym, Symbol::Kind::UndefinedFunctionKind,
215 getFunctionSig(WasmSym));
Sam Clegg8d146bb2018-01-09 23:56:44 +0000216 break;
Sam Cleggc94d3932017-11-17 18:14:09 +0000217 case WasmSymbol::SymbolType::GLOBAL_IMPORT:
Sam Clegg20db3812018-01-10 00:52:20 +0000218 S = createUndefined(WasmSym, Symbol::Kind::UndefinedGlobalKind);
Sam Cleggc94d3932017-11-17 18:14:09 +0000219 break;
220 case WasmSymbol::SymbolType::GLOBAL_EXPORT:
Sam Clegg20db3812018-01-10 00:52:20 +0000221 S = createDefined(WasmSym, Symbol::Kind::DefinedGlobalKind,
222 getSegment(WasmSym), nullptr, getGlobalValue(WasmSym));
Sam Cleggc94d3932017-11-17 18:14:09 +0000223 break;
224 case WasmSymbol::SymbolType::FUNCTION_EXPORT:
Sam Clegg20db3812018-01-10 00:52:20 +0000225 S = createDefined(WasmSym, Symbol::Kind::DefinedFunctionKind, nullptr,
226 getFunction(WasmSym));
Sam Cleggc94d3932017-11-17 18:14:09 +0000227 break;
228 case WasmSymbol::SymbolType::DEBUG_FUNCTION_NAME:
229 // These are for debugging only, no need to create linker symbols for them
230 continue;
231 }
232
233 Symbols.push_back(S);
234 if (WasmSym.isFunction()) {
Sam Cleggc94d3932017-11-17 18:14:09 +0000235 FunctionSymbols[WasmSym.ElementIndex] = S;
Sam Clegg1cf31bb2017-12-21 02:43:39 +0000236 if (WasmSym.HasAltIndex)
237 FunctionSymbols[WasmSym.AltIndex] = S;
Sam Cleggc94d3932017-11-17 18:14:09 +0000238 } else {
Sam Cleggc94d3932017-11-17 18:14:09 +0000239 GlobalSymbols[WasmSym.ElementIndex] = S;
Sam Clegg1cf31bb2017-12-21 02:43:39 +0000240 if (WasmSym.HasAltIndex)
241 GlobalSymbols[WasmSym.AltIndex] = S;
Sam Cleggc94d3932017-11-17 18:14:09 +0000242 }
243 }
244
Sam Clegg1cf31bb2017-12-21 02:43:39 +0000245 DEBUG(for (size_t I = 0; I < FunctionSymbols.size(); ++I)
246 assert(FunctionSymbols[I] != nullptr);
247 for (size_t I = 0; I < GlobalSymbols.size(); ++I)
248 assert(GlobalSymbols[I] != nullptr););
249
Sam Cleggfc1a9122017-12-11 22:00:56 +0000250 // Populate `TableSymbols` with all symbols that are called indirectly
251 uint32_t SegmentCount = WasmObj->elements().size();
252 if (SegmentCount) {
253 if (SegmentCount > 1)
254 fatal(getName() + ": contains more than one element segment");
255 const WasmElemSegment &Segment = WasmObj->elements()[0];
256 if (Segment.Offset.Opcode != WASM_OPCODE_I32_CONST)
257 fatal(getName() + ": unsupported element segment");
258 if (Segment.TableIndex != 0)
259 fatal(getName() + ": unsupported table index in elem segment");
260 if (Segment.Offset.Value.Int32 != 0)
261 fatal(getName() + ": unsupported element segment offset");
262 TableSymbols.reserve(Segment.Functions.size());
263 for (uint64_t FunctionIndex : Segment.Functions)
Sam Clegg8d146bb2018-01-09 23:56:44 +0000264 TableSymbols.push_back(FunctionSymbols[FunctionIndex]);
Sam Cleggfc1a9122017-12-11 22:00:56 +0000265 }
266
267 DEBUG(dbgs() << "TableSymbols: " << TableSymbols.size() << "\n");
268 DEBUG(dbgs() << "Functions : " << FunctionSymbols.size() << "\n");
269 DEBUG(dbgs() << "Globals : " << GlobalSymbols.size() << "\n");
Sam Cleggc94d3932017-11-17 18:14:09 +0000270}
271
Sam Clegg20db3812018-01-10 00:52:20 +0000272Symbol *ObjFile::createUndefined(const WasmSymbol &Sym, Symbol::Kind Kind,
Sam Clegg8d146bb2018-01-09 23:56:44 +0000273 const WasmSignature *Signature) {
Sam Clegg20db3812018-01-10 00:52:20 +0000274 return Symtab->addUndefined(Sym.Name, Kind, Sym.Flags, this, Signature);
Sam Cleggc94d3932017-11-17 18:14:09 +0000275}
276
Sam Clegg20db3812018-01-10 00:52:20 +0000277Symbol *ObjFile::createDefined(const WasmSymbol &Sym, Symbol::Kind Kind,
Sam Clegg8d146bb2018-01-09 23:56:44 +0000278 const InputSegment *Segment,
Sam Clegg20db3812018-01-10 00:52:20 +0000279 InputFunction *Function, uint32_t Address) {
Sam Cleggc94d3932017-11-17 18:14:09 +0000280 Symbol *S;
281 if (Sym.isLocal()) {
282 S = make<Symbol>(Sym.Name, true);
Sam Clegg20db3812018-01-10 00:52:20 +0000283 S->update(Kind, this, Sym.Flags, Segment, Function, Address);
Sam Cleggc94d3932017-11-17 18:14:09 +0000284 return S;
285 }
Sam Clegg20db3812018-01-10 00:52:20 +0000286 return Symtab->addDefined(Sym.Name, Kind, Sym.Flags, this, Segment, Function,
287 Address);
Sam Cleggc94d3932017-11-17 18:14:09 +0000288}
289
290void ArchiveFile::parse() {
291 // Parse a MemoryBufferRef as an archive file.
292 DEBUG(dbgs() << "Parsing library: " << toString(this) << "\n");
Rui Ueyamabdc51502017-12-06 22:08:17 +0000293 File = CHECK(Archive::create(MB), toString(this));
Sam Cleggc94d3932017-11-17 18:14:09 +0000294
295 // Read the symbol table to construct Lazy symbols.
296 int Count = 0;
297 for (const Archive::Symbol &Sym : File->symbols()) {
298 Symtab->addLazy(this, &Sym);
299 ++Count;
300 }
301 DEBUG(dbgs() << "Read " << Count << " symbols\n");
302}
303
304void ArchiveFile::addMember(const Archive::Symbol *Sym) {
305 const Archive::Child &C =
Rui Ueyamabdc51502017-12-06 22:08:17 +0000306 CHECK(Sym->getMember(),
Sam Cleggc94d3932017-11-17 18:14:09 +0000307 "could not get the member for symbol " + Sym->getName());
308
309 // Don't try to load the same member twice (this can happen when members
310 // mutually reference each other).
311 if (!Seen.insert(C.getChildOffset()).second)
312 return;
313
Sam Clegga681a112017-12-06 03:10:39 +0000314 DEBUG(dbgs() << "loading lazy: " << Sym->getName() << "\n");
Sam Cleggc94d3932017-11-17 18:14:09 +0000315 DEBUG(dbgs() << "from archive: " << toString(this) << "\n");
316
317 MemoryBufferRef MB =
Rui Ueyamabdc51502017-12-06 22:08:17 +0000318 CHECK(C.getMemoryBufferRef(),
Sam Cleggc94d3932017-11-17 18:14:09 +0000319 "could not get the buffer for the member defining symbol " +
320 Sym->getName());
321
322 if (identify_magic(MB.getBuffer()) != file_magic::wasm_object) {
323 error("unknown file type: " + MB.getBufferIdentifier());
324 return;
325 }
326
327 InputFile *Obj = make<ObjFile>(MB);
328 Obj->ParentName = ParentName;
329 Symtab->addFile(Obj);
330}
331
332// Returns a string in the format of "foo.o" or "foo.a(bar.o)".
Sam Clegg7e756632017-12-05 16:50:46 +0000333std::string lld::toString(const wasm::InputFile *File) {
Sam Cleggc94d3932017-11-17 18:14:09 +0000334 if (!File)
335 return "<internal>";
336
337 if (File->ParentName.empty())
338 return File->getName();
339
340 return (File->ParentName + "(" + File->getName() + ")").str();
341}