blob: 5e1597540a0112f15cf1fedcbf3faea157d62e61 [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" +
Sam Cleggab604a92018-01-23 01:25:56 +000050 " Global Imports : " + Twine(NumGlobalImports) + "\n");
Sam Cleggc94d3932017-11-17 18:14:09 +000051}
52
Sam Cleggab604a92018-01-23 01:25:56 +000053uint32_t ObjFile::relocateVirtualAddress(uint32_t GlobalIndex) const {
Sam Clegg8d146bb2018-01-09 23:56:44 +000054 return GlobalSymbols[GlobalIndex]->getVirtualAddress();
Sam Cleggc94d3932017-11-17 18:14:09 +000055}
56
57uint32_t ObjFile::relocateFunctionIndex(uint32_t Original) const {
Sam Clegg8d146bb2018-01-09 23:56:44 +000058 Symbol *Sym = FunctionSymbols[Original];
Sam Clegg74fe0ba2017-12-07 01:51:24 +000059 uint32_t Index = Sym->getOutputIndex();
60 DEBUG(dbgs() << "relocateFunctionIndex: " << toString(*Sym) << ": "
61 << Original << " -> " << Index << "\n");
Sam Cleggc94d3932017-11-17 18:14:09 +000062 return Index;
63}
64
65uint32_t ObjFile::relocateTypeIndex(uint32_t Original) const {
66 return TypeMap[Original];
67}
68
69uint32_t ObjFile::relocateTableIndex(uint32_t Original) const {
Sam Cleggab604a92018-01-23 01:25:56 +000070 Symbol *Sym = FunctionSymbols[Original];
Sam Clegg87e61922018-01-08 23:39:11 +000071 uint32_t Index = Sym->hasTableIndex() ? Sym->getTableIndex() : 0;
Sam Cleggfc1a9122017-12-11 22:00:56 +000072 DEBUG(dbgs() << "relocateTableIndex: " << toString(*Sym) << ": " << Original
73 << " -> " << Index << "\n");
74 return Index;
Sam Cleggc94d3932017-11-17 18:14:09 +000075}
76
77uint32_t ObjFile::relocateGlobalIndex(uint32_t Original) const {
Sam Clegg8d146bb2018-01-09 23:56:44 +000078 Symbol *Sym = GlobalSymbols[Original];
Sam Clegg87e61922018-01-08 23:39:11 +000079 uint32_t Index = Sym->hasOutputIndex() ? Sym->getOutputIndex() : 0;
Sam Clegg74fe0ba2017-12-07 01:51:24 +000080 DEBUG(dbgs() << "relocateGlobalIndex: " << toString(*Sym) << ": " << Original
81 << " -> " << Index << "\n");
Sam Cleggc94d3932017-11-17 18:14:09 +000082 return Index;
83}
84
Sam Cleggd96d9352018-01-10 19:22:42 +000085// Relocations contain an index into the function, global or table index
86// space of the input file. This function takes a relocation and returns the
87// relocated index (i.e. translates from the input index space to the output
88// index space).
89uint32_t ObjFile::calcNewIndex(const WasmRelocation &Reloc) const {
90 switch (Reloc.Type) {
91 case R_WEBASSEMBLY_TYPE_INDEX_LEB:
92 return relocateTypeIndex(Reloc.Index);
93 case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
Sam Cleggd96d9352018-01-10 19:22:42 +000094 case R_WEBASSEMBLY_TABLE_INDEX_I32:
95 case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
Sam Cleggab604a92018-01-23 01:25:56 +000096 return relocateFunctionIndex(Reloc.Index);
Sam Cleggd96d9352018-01-10 19:22:42 +000097 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
98 case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
99 case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
100 case R_WEBASSEMBLY_MEMORY_ADDR_I32:
101 return relocateGlobalIndex(Reloc.Index);
102 default:
103 llvm_unreachable("unknown relocation type");
104 }
105}
106
Sam Cleggab604a92018-01-23 01:25:56 +0000107// Translate from the relocation's index into the final linked output value.
108uint32_t ObjFile::calcNewValue(const WasmRelocation &Reloc) const {
109 switch (Reloc.Type) {
110 case R_WEBASSEMBLY_TABLE_INDEX_I32:
111 case R_WEBASSEMBLY_TABLE_INDEX_SLEB:
112 return relocateTableIndex(Reloc.Index);
113 case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
114 case R_WEBASSEMBLY_MEMORY_ADDR_I32:
115 case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
116 return relocateVirtualAddress(Reloc.Index) + Reloc.Addend;
117 case R_WEBASSEMBLY_TYPE_INDEX_LEB:
118 return relocateTypeIndex(Reloc.Index);
119 case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
120 return relocateFunctionIndex(Reloc.Index);
121 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
122 return relocateGlobalIndex(Reloc.Index);
123 default:
124 llvm_unreachable("unknown relocation type");
125 }
126}
127
Sam Cleggc94d3932017-11-17 18:14:09 +0000128void ObjFile::parse() {
129 // Parse a memory buffer as a wasm file.
130 DEBUG(dbgs() << "Parsing object: " << toString(this) << "\n");
Rui Ueyamabdc51502017-12-06 22:08:17 +0000131 std::unique_ptr<Binary> Bin = CHECK(createBinary(MB), toString(this));
Sam Cleggc94d3932017-11-17 18:14:09 +0000132
133 auto *Obj = dyn_cast<WasmObjectFile>(Bin.get());
134 if (!Obj)
135 fatal(toString(this) + ": not a wasm file");
136 if (!Obj->isRelocatableObject())
137 fatal(toString(this) + ": not a relocatable wasm file");
138
139 Bin.release();
140 WasmObj.reset(Obj);
141
142 // Find the code and data sections. Wasm objects can have at most one code
143 // and one data section.
144 for (const SectionRef &Sec : WasmObj->sections()) {
145 const WasmSection &Section = WasmObj->getWasmSection(Sec);
146 if (Section.Type == WASM_SEC_CODE)
147 CodeSection = &Section;
148 else if (Section.Type == WASM_SEC_DATA)
149 DataSection = &Section;
150 }
151
152 initializeSymbols();
153}
154
155// Return the InputSegment in which a given symbol is defined.
Sam Clegg8d146bb2018-01-09 23:56:44 +0000156InputSegment *ObjFile::getSegment(const WasmSymbol &WasmSym) const {
Sam Cleggc94d3932017-11-17 18:14:09 +0000157 uint32_t Address = WasmObj->getWasmSymbolValue(WasmSym);
158 for (InputSegment *Segment : Segments) {
159 if (Address >= Segment->startVA() && Address < Segment->endVA()) {
160 DEBUG(dbgs() << "Found symbol in segment: " << WasmSym.Name << " -> "
161 << Segment->getName() << "\n");
162
163 return Segment;
164 }
165 }
Rui Ueyama29ceba72017-12-15 00:07:15 +0000166 error("symbol not found in any segment: " + WasmSym.Name);
Sam Cleggc94d3932017-11-17 18:14:09 +0000167 return nullptr;
168}
169
Sam Clegg20db3812018-01-10 00:52:20 +0000170// Get the value stored in the wasm global represented by this symbol.
171// This represents the virtual address of the symbol in the input file.
172uint32_t ObjFile::getGlobalValue(const WasmSymbol &Sym) const {
173 const WasmGlobal &Global =
174 getWasmObj()->globals()[Sym.ElementIndex - NumGlobalImports];
175 assert(Global.Type == llvm::wasm::WASM_TYPE_I32);
176 return Global.InitExpr.Value.Int32;
177}
178
Sam Clegg8d146bb2018-01-09 23:56:44 +0000179// Get the signature for a given function symbol, either by looking
180// it up in function sections (for defined functions), of the imports section
181// (for imported functions).
182const WasmSignature *ObjFile::getFunctionSig(const WasmSymbol &Sym) const {
183 DEBUG(dbgs() << "getFunctionSig: " << Sym.Name << "\n");
184 return &WasmObj->types()[Sym.FunctionType];
185}
186
187InputFunction *ObjFile::getFunction(const WasmSymbol &Sym) const {
188 uint32_t FunctionIndex = Sym.ElementIndex - NumFunctionImports;
189 return Functions[FunctionIndex];
190}
191
Sam Clegge0f6fcd2018-01-12 22:25:17 +0000192bool ObjFile::isExcludedByComdat(InputChunk *Chunk) const {
193 StringRef Comdat = Chunk->getComdat();
194 return !Comdat.empty() && Symtab->findComdat(Comdat) != this;
195}
196
Sam Cleggc94d3932017-11-17 18:14:09 +0000197void ObjFile::initializeSymbols() {
198 Symbols.reserve(WasmObj->getNumberOfSymbols());
199
200 for (const WasmImport &Import : WasmObj->imports()) {
201 switch (Import.Kind) {
202 case WASM_EXTERNAL_FUNCTION:
Sam Clegg8d146bb2018-01-09 23:56:44 +0000203 ++NumFunctionImports;
Sam Cleggc94d3932017-11-17 18:14:09 +0000204 break;
205 case WASM_EXTERNAL_GLOBAL:
Sam Clegg8d146bb2018-01-09 23:56:44 +0000206 ++NumGlobalImports;
Sam Cleggc94d3932017-11-17 18:14:09 +0000207 break;
208 }
209 }
210
Sam Clegg8d146bb2018-01-09 23:56:44 +0000211 FunctionSymbols.resize(NumFunctionImports + WasmObj->functions().size());
212 GlobalSymbols.resize(NumGlobalImports + WasmObj->globals().size());
Sam Cleggc94d3932017-11-17 18:14:09 +0000213
Sam Clegge0f6fcd2018-01-12 22:25:17 +0000214 ArrayRef<WasmFunction> Funcs = WasmObj->functions();
215 ArrayRef<uint32_t> FuncTypes = WasmObj->functionTypes();
216 ArrayRef<WasmSignature> Types = WasmObj->types();
217 ArrayRef<WasmGlobal> Globals = WasmObj->globals();
218
219 for (const auto &C : WasmObj->comdats())
220 Symtab->addComdat(C, this);
221
222 FunctionSymbols.resize(NumFunctionImports + Funcs.size());
223 GlobalSymbols.resize(NumGlobalImports + Globals.size());
224
Sam Cleggf61676a2017-12-17 17:52:01 +0000225 for (const WasmSegment &S : WasmObj->dataSegments()) {
Sam Clegg50686852018-01-12 18:35:13 +0000226 InputSegment *Seg = make<InputSegment>(S, this);
Sam Clegg5fa274b2018-01-10 01:13:34 +0000227 Seg->copyRelocations(*DataSection);
Sam Cleggf61676a2017-12-17 17:52:01 +0000228 Segments.emplace_back(Seg);
229 }
Sam Cleggc94d3932017-11-17 18:14:09 +0000230
Sam Clegg8d146bb2018-01-09 23:56:44 +0000231 for (size_t I = 0; I < Funcs.size(); ++I) {
232 const WasmFunction &Func = Funcs[I];
233 const WasmSignature &Sig = Types[FuncTypes[I]];
Sam Clegg50686852018-01-12 18:35:13 +0000234 InputFunction *F = make<InputFunction>(Sig, &Func, this);
Sam Clegg5fa274b2018-01-10 01:13:34 +0000235 F->copyRelocations(*CodeSection);
236 Functions.emplace_back(F);
Sam Clegg8d146bb2018-01-09 23:56:44 +0000237 }
238
Sam Cleggfc1a9122017-12-11 22:00:56 +0000239 // Populate `FunctionSymbols` and `GlobalSymbols` based on the WasmSymbols
240 // in the object
Sam Cleggc94d3932017-11-17 18:14:09 +0000241 for (const SymbolRef &Sym : WasmObj->symbols()) {
242 const WasmSymbol &WasmSym = WasmObj->getWasmSymbol(Sym.getRawDataRefImpl());
Sam Cleggfc1a9122017-12-11 22:00:56 +0000243 Symbol *S;
Sam Cleggc94d3932017-11-17 18:14:09 +0000244 switch (WasmSym.Type) {
Sam Clegge0f6fcd2018-01-12 22:25:17 +0000245 case WasmSymbol::SymbolType::FUNCTION_EXPORT: {
246 InputFunction *Function = getFunction(WasmSym);
247 if (!isExcludedByComdat(Function)) {
248 S = createDefined(WasmSym, Symbol::Kind::DefinedFunctionKind, nullptr,
249 Function);
250 break;
251 } else {
252 Function->Discarded = true;
253 LLVM_FALLTHROUGH; // Exclude function, and add the symbol as undefined
254 }
255 }
Sam Cleggc94d3932017-11-17 18:14:09 +0000256 case WasmSymbol::SymbolType::FUNCTION_IMPORT:
Sam Clegg20db3812018-01-10 00:52:20 +0000257 S = createUndefined(WasmSym, Symbol::Kind::UndefinedFunctionKind,
258 getFunctionSig(WasmSym));
Sam Clegg8d146bb2018-01-09 23:56:44 +0000259 break;
Sam Clegge0f6fcd2018-01-12 22:25:17 +0000260 case WasmSymbol::SymbolType::GLOBAL_EXPORT: {
261 InputSegment *Segment = getSegment(WasmSym);
262 if (!isExcludedByComdat(Segment)) {
263 S = createDefined(WasmSym, Symbol::Kind::DefinedGlobalKind,
264 Segment, nullptr, getGlobalValue(WasmSym));
265 break;
266 } else {
267 Segment->Discarded = true;
268 LLVM_FALLTHROUGH; // Exclude global, and add the symbol as undefined
269 }
270 }
Sam Cleggc94d3932017-11-17 18:14:09 +0000271 case WasmSymbol::SymbolType::GLOBAL_IMPORT:
Sam Clegg20db3812018-01-10 00:52:20 +0000272 S = createUndefined(WasmSym, Symbol::Kind::UndefinedGlobalKind);
Sam Cleggc94d3932017-11-17 18:14:09 +0000273 break;
Sam Cleggc94d3932017-11-17 18:14:09 +0000274 }
275
276 Symbols.push_back(S);
277 if (WasmSym.isFunction()) {
Sam Cleggc94d3932017-11-17 18:14:09 +0000278 FunctionSymbols[WasmSym.ElementIndex] = S;
Sam Clegg1cf31bb2017-12-21 02:43:39 +0000279 if (WasmSym.HasAltIndex)
280 FunctionSymbols[WasmSym.AltIndex] = S;
Sam Cleggc94d3932017-11-17 18:14:09 +0000281 } else {
Sam Cleggc94d3932017-11-17 18:14:09 +0000282 GlobalSymbols[WasmSym.ElementIndex] = S;
Sam Clegg1cf31bb2017-12-21 02:43:39 +0000283 if (WasmSym.HasAltIndex)
284 GlobalSymbols[WasmSym.AltIndex] = S;
Sam Cleggc94d3932017-11-17 18:14:09 +0000285 }
286 }
287
Sam Clegg1cf31bb2017-12-21 02:43:39 +0000288 DEBUG(for (size_t I = 0; I < FunctionSymbols.size(); ++I)
289 assert(FunctionSymbols[I] != nullptr);
290 for (size_t I = 0; I < GlobalSymbols.size(); ++I)
291 assert(GlobalSymbols[I] != nullptr););
292
Sam Cleggfc1a9122017-12-11 22:00:56 +0000293 DEBUG(dbgs() << "Functions : " << FunctionSymbols.size() << "\n");
294 DEBUG(dbgs() << "Globals : " << GlobalSymbols.size() << "\n");
Sam Cleggc94d3932017-11-17 18:14:09 +0000295}
296
Sam Clegg20db3812018-01-10 00:52:20 +0000297Symbol *ObjFile::createUndefined(const WasmSymbol &Sym, Symbol::Kind Kind,
Sam Clegg8d146bb2018-01-09 23:56:44 +0000298 const WasmSignature *Signature) {
Sam Clegg20db3812018-01-10 00:52:20 +0000299 return Symtab->addUndefined(Sym.Name, Kind, Sym.Flags, this, Signature);
Sam Cleggc94d3932017-11-17 18:14:09 +0000300}
301
Sam Clegg20db3812018-01-10 00:52:20 +0000302Symbol *ObjFile::createDefined(const WasmSymbol &Sym, Symbol::Kind Kind,
Sam Clegg8d146bb2018-01-09 23:56:44 +0000303 const InputSegment *Segment,
Sam Clegg20db3812018-01-10 00:52:20 +0000304 InputFunction *Function, uint32_t Address) {
Sam Cleggc94d3932017-11-17 18:14:09 +0000305 Symbol *S;
306 if (Sym.isLocal()) {
307 S = make<Symbol>(Sym.Name, true);
Sam Clegg20db3812018-01-10 00:52:20 +0000308 S->update(Kind, this, Sym.Flags, Segment, Function, Address);
Sam Cleggc94d3932017-11-17 18:14:09 +0000309 return S;
310 }
Sam Clegg20db3812018-01-10 00:52:20 +0000311 return Symtab->addDefined(Sym.Name, Kind, Sym.Flags, this, Segment, Function,
312 Address);
Sam Cleggc94d3932017-11-17 18:14:09 +0000313}
314
315void ArchiveFile::parse() {
316 // Parse a MemoryBufferRef as an archive file.
317 DEBUG(dbgs() << "Parsing library: " << toString(this) << "\n");
Rui Ueyamabdc51502017-12-06 22:08:17 +0000318 File = CHECK(Archive::create(MB), toString(this));
Sam Cleggc94d3932017-11-17 18:14:09 +0000319
320 // Read the symbol table to construct Lazy symbols.
321 int Count = 0;
322 for (const Archive::Symbol &Sym : File->symbols()) {
323 Symtab->addLazy(this, &Sym);
324 ++Count;
325 }
326 DEBUG(dbgs() << "Read " << Count << " symbols\n");
327}
328
329void ArchiveFile::addMember(const Archive::Symbol *Sym) {
330 const Archive::Child &C =
Rui Ueyamabdc51502017-12-06 22:08:17 +0000331 CHECK(Sym->getMember(),
Sam Cleggc94d3932017-11-17 18:14:09 +0000332 "could not get the member for symbol " + Sym->getName());
333
334 // Don't try to load the same member twice (this can happen when members
335 // mutually reference each other).
336 if (!Seen.insert(C.getChildOffset()).second)
337 return;
338
Sam Clegga681a112017-12-06 03:10:39 +0000339 DEBUG(dbgs() << "loading lazy: " << Sym->getName() << "\n");
Sam Cleggc94d3932017-11-17 18:14:09 +0000340 DEBUG(dbgs() << "from archive: " << toString(this) << "\n");
341
342 MemoryBufferRef MB =
Rui Ueyamabdc51502017-12-06 22:08:17 +0000343 CHECK(C.getMemoryBufferRef(),
Sam Cleggc94d3932017-11-17 18:14:09 +0000344 "could not get the buffer for the member defining symbol " +
345 Sym->getName());
346
347 if (identify_magic(MB.getBuffer()) != file_magic::wasm_object) {
348 error("unknown file type: " + MB.getBufferIdentifier());
349 return;
350 }
351
352 InputFile *Obj = make<ObjFile>(MB);
353 Obj->ParentName = ParentName;
354 Symtab->addFile(Obj);
355}
356
357// Returns a string in the format of "foo.o" or "foo.a(bar.o)".
Sam Clegg7e756632017-12-05 16:50:46 +0000358std::string lld::toString(const wasm::InputFile *File) {
Sam Cleggc94d3932017-11-17 18:14:09 +0000359 if (!File)
360 return "<internal>";
361
362 if (File->ParentName.empty())
363 return File->getName();
364
365 return (File->ParentName + "(" + File->getName() + ")").str();
366}