blob: 2c65c7bfd5cceb89635a86a7a187202191eb8fd1 [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"
Sam Cleggc94d3932017-11-17 18:14:09 +000011#include "Config.h"
Sam Clegg5fa274b2018-01-10 01:13:34 +000012#include "InputChunks.h"
Sam Clegg93102972018-02-23 05:08:53 +000013#include "InputGlobal.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 {
Rui Ueyama0a9583c2018-02-28 02:57:37 +000046 log("info for: " + getName() +
47 "\n Symbols : " + Twine(Symbols.size()) +
48 "\n Function Imports : " + Twine(WasmObj->getNumImportedFunctions()) +
49 "\n Global Imports : " + Twine(WasmObj->getNumImportedGlobals()));
Sam Cleggc94d3932017-11-17 18:14:09 +000050}
51
Sam Cleggd96d9352018-01-10 19:22:42 +000052// Relocations contain an index into the function, global or table index
53// space of the input file. This function takes a relocation and returns the
54// relocated index (i.e. translates from the input index space to the output
55// index space).
56uint32_t ObjFile::calcNewIndex(const WasmRelocation &Reloc) const {
Rui Ueyamad1063bb2018-02-28 00:26:26 +000057 if (Reloc.Type == R_WEBASSEMBLY_TYPE_INDEX_LEB) {
58 assert(TypeIsUsed[Reloc.Index]);
59 return TypeMap[Reloc.Index];
60 }
61 return Symbols[Reloc.Index]->getOutputSymbolIndex();
Sam Cleggd96d9352018-01-10 19:22:42 +000062}
63
Sam Cleggab604a92018-01-23 01:25:56 +000064// Translate from the relocation's index into the final linked output value.
65uint32_t ObjFile::calcNewValue(const WasmRelocation &Reloc) const {
66 switch (Reloc.Type) {
67 case R_WEBASSEMBLY_TABLE_INDEX_I32:
Rui Ueyamad1063bb2018-02-28 00:26:26 +000068 case R_WEBASSEMBLY_TABLE_INDEX_SLEB: {
69 // The null case is possible, if you take the address of a weak function
70 // that's simply not supplied.
71 FunctionSymbol *Sym = getFunctionSymbol(Reloc.Index);
72 if (Sym->hasTableIndex())
73 return Sym->getTableIndex();
74 return 0;
75 }
Sam Cleggab604a92018-01-23 01:25:56 +000076 case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
77 case R_WEBASSEMBLY_MEMORY_ADDR_I32:
78 case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
Rui Ueyamad1063bb2018-02-28 00:26:26 +000079 if (auto *Sym = dyn_cast<DefinedData>(getDataSymbol(Reloc.Index)))
80 return Sym->getVirtualAddress() + Reloc.Addend;
81 return Reloc.Addend;
Sam Cleggab604a92018-01-23 01:25:56 +000082 case R_WEBASSEMBLY_TYPE_INDEX_LEB:
Rui Ueyamad1063bb2018-02-28 00:26:26 +000083 return TypeMap[Reloc.Index];
Sam Cleggab604a92018-01-23 01:25:56 +000084 case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
Rui Ueyamad1063bb2018-02-28 00:26:26 +000085 return getFunctionSymbol(Reloc.Index)->getOutputIndex();
Sam Cleggab604a92018-01-23 01:25:56 +000086 case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
Rui Ueyamad1063bb2018-02-28 00:26:26 +000087 return getGlobalSymbol(Reloc.Index)->getOutputIndex();
Sam Cleggab604a92018-01-23 01:25:56 +000088 default:
89 llvm_unreachable("unknown relocation type");
90 }
91}
92
Sam Cleggc94d3932017-11-17 18:14:09 +000093void ObjFile::parse() {
94 // Parse a memory buffer as a wasm file.
95 DEBUG(dbgs() << "Parsing object: " << toString(this) << "\n");
Rui Ueyamabdc51502017-12-06 22:08:17 +000096 std::unique_ptr<Binary> Bin = CHECK(createBinary(MB), toString(this));
Sam Cleggc94d3932017-11-17 18:14:09 +000097
98 auto *Obj = dyn_cast<WasmObjectFile>(Bin.get());
99 if (!Obj)
100 fatal(toString(this) + ": not a wasm file");
101 if (!Obj->isRelocatableObject())
102 fatal(toString(this) + ": not a relocatable wasm file");
103
104 Bin.release();
105 WasmObj.reset(Obj);
106
107 // Find the code and data sections. Wasm objects can have at most one code
108 // and one data section.
109 for (const SectionRef &Sec : WasmObj->sections()) {
110 const WasmSection &Section = WasmObj->getWasmSection(Sec);
111 if (Section.Type == WASM_SEC_CODE)
112 CodeSection = &Section;
113 else if (Section.Type == WASM_SEC_DATA)
114 DataSection = &Section;
115 }
116
Sam Clegg8f6d2de2018-01-31 23:48:14 +0000117 TypeMap.resize(getWasmObj()->types().size());
118 TypeIsUsed.resize(getWasmObj()->types().size(), false);
119
Rui Ueyama0a9583c2018-02-28 02:57:37 +0000120 // Populate `Segments`.
121 for (const WasmSegment &S : WasmObj->dataSegments()) {
122 InputSegment *Seg = make<InputSegment>(S, this);
123 Seg->copyRelocations(*DataSection);
124 Segments.emplace_back(Seg);
125 }
Sam Clegg8d146bb2018-01-09 23:56:44 +0000126
Rui Ueyama0a9583c2018-02-28 02:57:37 +0000127 // Populate `Functions`.
128 ArrayRef<WasmFunction> Funcs = WasmObj->functions();
129 ArrayRef<uint32_t> FuncTypes = WasmObj->functionTypes();
130 ArrayRef<WasmSignature> Types = WasmObj->types();
131 Functions.reserve(Funcs.size());
Sam Clegg8d146bb2018-01-09 23:56:44 +0000132
Rui Ueyama0a9583c2018-02-28 02:57:37 +0000133 for (size_t I = 0, E = Funcs.size(); I != E; ++I) {
134 InputFunction *F =
135 make<InputFunction>(Types[FuncTypes[I]], &Funcs[I], this);
136 F->copyRelocations(*CodeSection);
137 Functions.emplace_back(F);
138 }
139
140 // Populate `Globals`.
141 for (const WasmGlobal &G : WasmObj->globals())
142 Globals.emplace_back(make<InputGlobal>(G));
143
144 // Populate `Symbols` based on the WasmSymbols in the object.
145 Symbols.reserve(WasmObj->getNumberOfSymbols());
146 for (const SymbolRef &Sym : WasmObj->symbols()) {
147 const WasmSymbol &WasmSym = WasmObj->getWasmSymbol(Sym.getRawDataRefImpl());
148 if (Symbol *Sym = createDefined(WasmSym))
149 Symbols.push_back(Sym);
150 else
151 Symbols.push_back(createUndefined(WasmSym));
152 }
Sam Clegg93102972018-02-23 05:08:53 +0000153}
154
Sam Clegge0f6fcd2018-01-12 22:25:17 +0000155bool ObjFile::isExcludedByComdat(InputChunk *Chunk) const {
Rui Ueyamadcf62342018-03-01 23:29:05 +0000156 StringRef S = Chunk->getComdat();
157 if (S.empty())
158 return false;
159 return !Symtab->addComdat(S, this);
Sam Clegge0f6fcd2018-01-12 22:25:17 +0000160}
161
Sam Clegg93102972018-02-23 05:08:53 +0000162FunctionSymbol *ObjFile::getFunctionSymbol(uint32_t Index) const {
163 return cast<FunctionSymbol>(Symbols[Index]);
164}
165
166GlobalSymbol *ObjFile::getGlobalSymbol(uint32_t Index) const {
167 return cast<GlobalSymbol>(Symbols[Index]);
168}
169
170DataSymbol *ObjFile::getDataSymbol(uint32_t Index) const {
171 return cast<DataSymbol>(Symbols[Index]);
172}
173
Rui Ueyama4b56adc2018-02-28 00:50:54 +0000174Symbol *ObjFile::createDefined(const WasmSymbol &Sym) {
175 if (!Sym.isDefined())
176 return nullptr;
177
Rui Ueyamae89b0ef2018-03-02 21:19:55 +0000178 StringRef Name = Sym.Info.Name;
179 uint32_t Flags = Sym.Info.Flags;
180
Rui Ueyama4b56adc2018-02-28 00:50:54 +0000181 switch (Sym.Info.Kind) {
182 case WASM_SYMBOL_TYPE_FUNCTION: {
Rui Ueyama0a9583c2018-02-28 02:57:37 +0000183 InputFunction *Func =
184 Functions[Sym.Info.ElementIndex - WasmObj->getNumImportedFunctions()];
Rui Ueyama4b56adc2018-02-28 00:50:54 +0000185 if (isExcludedByComdat(Func)) {
186 Func->Live = false;
187 return nullptr;
188 }
189
190 if (Sym.isBindingLocal())
Rui Ueyamae89b0ef2018-03-02 21:19:55 +0000191 return make<DefinedFunction>(Name, Flags, this, Func);
192 return Symtab->addDefinedFunction(Name, Flags, this, Func);
Rui Ueyama4b56adc2018-02-28 00:50:54 +0000193 }
194 case WASM_SYMBOL_TYPE_DATA: {
Rui Ueyama0a9583c2018-02-28 02:57:37 +0000195 InputSegment *Seg = Segments[Sym.Info.DataRef.Segment];
Rui Ueyama4b56adc2018-02-28 00:50:54 +0000196 if (isExcludedByComdat(Seg)) {
197 Seg->Live = false;
198 return nullptr;
199 }
200
201 uint32_t Offset = Sym.Info.DataRef.Offset;
202 uint32_t Size = Sym.Info.DataRef.Size;
203
204 if (Sym.isBindingLocal())
Rui Ueyamae89b0ef2018-03-02 21:19:55 +0000205 return make<DefinedData>(Name, Flags, this, Seg, Offset, Size);
206 return Symtab->addDefinedData(Name, Flags, this, Seg, Offset, Size);
Rui Ueyama4b56adc2018-02-28 00:50:54 +0000207 }
208 case WASM_SYMBOL_TYPE_GLOBAL:
Rui Ueyama0a9583c2018-02-28 02:57:37 +0000209 InputGlobal *Global =
210 Globals[Sym.Info.ElementIndex - WasmObj->getNumImportedGlobals()];
Rui Ueyama4b56adc2018-02-28 00:50:54 +0000211 if (Sym.isBindingLocal())
Rui Ueyamae89b0ef2018-03-02 21:19:55 +0000212 return make<DefinedGlobal>(Name, Flags, this, Global);
213 return Symtab->addDefinedGlobal(Name, Flags, this, Global);
Rui Ueyama4b56adc2018-02-28 00:50:54 +0000214 }
215 llvm_unreachable("unkown symbol kind");
216}
217
Sam Clegg93102972018-02-23 05:08:53 +0000218Symbol *ObjFile::createUndefined(const WasmSymbol &Sym) {
Rui Ueyamae3498ec2018-02-28 00:09:22 +0000219 StringRef Name = Sym.Info.Name;
220 uint32_t Flags = Sym.Info.Flags;
221
222 switch (Sym.Info.Kind) {
223 case WASM_SYMBOL_TYPE_FUNCTION:
224 return Symtab->addUndefinedFunction(Name, Flags, this, Sym.FunctionType);
225 case WASM_SYMBOL_TYPE_DATA:
226 return Symtab->addUndefinedData(Name, Flags, this);
227 case WASM_SYMBOL_TYPE_GLOBAL:
228 return Symtab->addUndefinedGlobal(Name, Flags, this, Sym.GlobalType);
229 }
230 llvm_unreachable("unkown symbol kind");
Sam Cleggc94d3932017-11-17 18:14:09 +0000231}
232
Sam Cleggc94d3932017-11-17 18:14:09 +0000233void ArchiveFile::parse() {
234 // Parse a MemoryBufferRef as an archive file.
235 DEBUG(dbgs() << "Parsing library: " << toString(this) << "\n");
Rui Ueyamabdc51502017-12-06 22:08:17 +0000236 File = CHECK(Archive::create(MB), toString(this));
Sam Cleggc94d3932017-11-17 18:14:09 +0000237
238 // Read the symbol table to construct Lazy symbols.
239 int Count = 0;
240 for (const Archive::Symbol &Sym : File->symbols()) {
241 Symtab->addLazy(this, &Sym);
242 ++Count;
243 }
244 DEBUG(dbgs() << "Read " << Count << " symbols\n");
245}
246
247void ArchiveFile::addMember(const Archive::Symbol *Sym) {
248 const Archive::Child &C =
Rui Ueyamabdc51502017-12-06 22:08:17 +0000249 CHECK(Sym->getMember(),
Sam Cleggc94d3932017-11-17 18:14:09 +0000250 "could not get the member for symbol " + Sym->getName());
251
252 // Don't try to load the same member twice (this can happen when members
253 // mutually reference each other).
254 if (!Seen.insert(C.getChildOffset()).second)
255 return;
256
Sam Clegga681a112017-12-06 03:10:39 +0000257 DEBUG(dbgs() << "loading lazy: " << Sym->getName() << "\n");
Sam Cleggc94d3932017-11-17 18:14:09 +0000258 DEBUG(dbgs() << "from archive: " << toString(this) << "\n");
259
260 MemoryBufferRef MB =
Rui Ueyamabdc51502017-12-06 22:08:17 +0000261 CHECK(C.getMemoryBufferRef(),
Sam Cleggc94d3932017-11-17 18:14:09 +0000262 "could not get the buffer for the member defining symbol " +
263 Sym->getName());
264
265 if (identify_magic(MB.getBuffer()) != file_magic::wasm_object) {
266 error("unknown file type: " + MB.getBufferIdentifier());
267 return;
268 }
269
270 InputFile *Obj = make<ObjFile>(MB);
271 Obj->ParentName = ParentName;
272 Symtab->addFile(Obj);
273}
274
275// Returns a string in the format of "foo.o" or "foo.a(bar.o)".
Sam Clegg7e756632017-12-05 16:50:46 +0000276std::string lld::toString(const wasm::InputFile *File) {
Sam Cleggc94d3932017-11-17 18:14:09 +0000277 if (!File)
278 return "<internal>";
279
280 if (File->ParentName.empty())
281 return File->getName();
282
283 return (File->ParentName + "(" + File->getName() + ")").str();
284}