1 //===- 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 #include "Config.h"
12 #include "InputChunks.h"
13 #include "InputGlobal.h"
14 #include "SymbolTable.h"
15 #include "lld/Common/ErrorHandler.h"
16 #include "lld/Common/Memory.h"
17 #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 
23 using namespace lld;
24 using namespace lld::wasm;
25 
26 using namespace llvm;
27 using namespace llvm::object;
28 using namespace llvm::wasm;
29 
30 Optional<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 
45 void ObjFile::dumpInfo() const {
46   log("info for: " + getName() +
47       "\n              Symbols : " + Twine(Symbols.size()) +
48       "\n     Function Imports : " + Twine(WasmObj->getNumImportedFunctions()) +
49       "\n       Global Imports : " + Twine(WasmObj->getNumImportedGlobals()));
50 }
51 
52 // 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).
56 uint32_t ObjFile::calcNewIndex(const WasmRelocation &Reloc) const {
57   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();
62 }
63 
64 // Translate from the relocation's index into the final linked output value.
65 uint32_t ObjFile::calcNewValue(const WasmRelocation &Reloc) const {
66   switch (Reloc.Type) {
67   case R_WEBASSEMBLY_TABLE_INDEX_I32:
68   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   }
76   case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
77   case R_WEBASSEMBLY_MEMORY_ADDR_I32:
78   case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
79     if (auto *Sym = dyn_cast<DefinedData>(getDataSymbol(Reloc.Index)))
80       return Sym->getVirtualAddress() + Reloc.Addend;
81     return Reloc.Addend;
82   case R_WEBASSEMBLY_TYPE_INDEX_LEB:
83     return TypeMap[Reloc.Index];
84   case R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
85     return getFunctionSymbol(Reloc.Index)->getOutputIndex();
86   case R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
87     return getGlobalSymbol(Reloc.Index)->getOutputIndex();
88   default:
89     llvm_unreachable("unknown relocation type");
90   }
91 }
92 
93 void ObjFile::parse() {
94   // Parse a memory buffer as a wasm file.
95   DEBUG(dbgs() << "Parsing object: " << toString(this) << "\n");
96   std::unique_ptr<Binary> Bin = CHECK(createBinary(MB), toString(this));
97 
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 
117   TypeMap.resize(getWasmObj()->types().size());
118   TypeIsUsed.resize(getWasmObj()->types().size(), false);
119 
120   // 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   }
126 
127   // 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());
132 
133   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   }
153 }
154 
155 bool ObjFile::isExcludedByComdat(InputChunk *Chunk) const {
156   StringRef S = Chunk->getComdat();
157   if (S.empty())
158     return false;
159   return !Symtab->addComdat(S, this);
160 }
161 
162 FunctionSymbol *ObjFile::getFunctionSymbol(uint32_t Index) const {
163   return cast<FunctionSymbol>(Symbols[Index]);
164 }
165 
166 GlobalSymbol *ObjFile::getGlobalSymbol(uint32_t Index) const {
167   return cast<GlobalSymbol>(Symbols[Index]);
168 }
169 
170 DataSymbol *ObjFile::getDataSymbol(uint32_t Index) const {
171   return cast<DataSymbol>(Symbols[Index]);
172 }
173 
174 Symbol *ObjFile::createDefined(const WasmSymbol &Sym) {
175   if (!Sym.isDefined())
176     return nullptr;
177 
178   StringRef Name = Sym.Info.Name;
179   uint32_t Flags = Sym.Info.Flags;
180 
181   switch (Sym.Info.Kind) {
182   case WASM_SYMBOL_TYPE_FUNCTION: {
183     InputFunction *Func =
184         Functions[Sym.Info.ElementIndex - WasmObj->getNumImportedFunctions()];
185     if (isExcludedByComdat(Func)) {
186       Func->Live = false;
187       return nullptr;
188     }
189 
190     if (Sym.isBindingLocal())
191       return make<DefinedFunction>(Name, Flags, this, Func);
192     return Symtab->addDefinedFunction(Name, Flags, this, Func);
193   }
194   case WASM_SYMBOL_TYPE_DATA: {
195     InputSegment *Seg = Segments[Sym.Info.DataRef.Segment];
196     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())
205       return make<DefinedData>(Name, Flags, this, Seg, Offset, Size);
206     return Symtab->addDefinedData(Name, Flags, this, Seg, Offset, Size);
207   }
208   case WASM_SYMBOL_TYPE_GLOBAL:
209     InputGlobal *Global =
210         Globals[Sym.Info.ElementIndex - WasmObj->getNumImportedGlobals()];
211     if (Sym.isBindingLocal())
212       return make<DefinedGlobal>(Name, Flags, this, Global);
213     return Symtab->addDefinedGlobal(Name, Flags, this, Global);
214   }
215   llvm_unreachable("unkown symbol kind");
216 }
217 
218 Symbol *ObjFile::createUndefined(const WasmSymbol &Sym) {
219   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");
231 }
232 
233 void ArchiveFile::parse() {
234   // Parse a MemoryBufferRef as an archive file.
235   DEBUG(dbgs() << "Parsing library: " << toString(this) << "\n");
236   File = CHECK(Archive::create(MB), toString(this));
237 
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 
247 void ArchiveFile::addMember(const Archive::Symbol *Sym) {
248   const Archive::Child &C =
249       CHECK(Sym->getMember(),
250             "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 
257   DEBUG(dbgs() << "loading lazy: " << Sym->getName() << "\n");
258   DEBUG(dbgs() << "from archive: " << toString(this) << "\n");
259 
260   MemoryBufferRef MB =
261       CHECK(C.getMemoryBufferRef(),
262             "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)".
276 std::string lld::toString(const wasm::InputFile *File) {
277   if (!File)
278     return "<internal>";
279 
280   if (File->ParentName.empty())
281     return File->getName();
282 
283   return (File->ParentName + "(" + File->getName() + ")").str();
284 }
285