1 //===- SymbolTable.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 "SymbolTable.h" 11 #include "Error.h" 12 #include "Symbols.h" 13 14 using namespace llvm; 15 16 using namespace lld; 17 using namespace lld::elf2; 18 19 SymbolTable::SymbolTable() { 20 resolve(new (Alloc) SyntheticUndefined("_start")); 21 } 22 23 void SymbolTable::addFile(std::unique_ptr<InputFile> File) { 24 File->parse(); 25 InputFile *FileP = File.release(); 26 auto *P = cast<ObjectFileBase>(FileP); 27 addObject(P); 28 } 29 30 void SymbolTable::addObject(ObjectFileBase *File) { 31 if (!ObjectFiles.empty()) { 32 ObjectFileBase &Old = *ObjectFiles[0]; 33 if (!Old.isCompatibleWith(*File)) 34 error(Twine(Old.getName() + " is incompatible with " + File->getName())); 35 } 36 37 ObjectFiles.emplace_back(File); 38 for (SymbolBody *Body : File->getSymbols()) 39 resolve(Body); 40 } 41 42 void SymbolTable::reportRemainingUndefines() { 43 for (auto &I : Symtab) { 44 SymbolBody *Body = I.second->Body; 45 if (Body->isStrongUndefined()) 46 error(Twine("undefined symbol: ") + Body->getName()); 47 } 48 } 49 50 // This function resolves conflicts if there's an existing symbol with 51 // the same name. Decisions are made based on symbol type. 52 void SymbolTable::resolve(SymbolBody *New) { 53 // Find an existing Symbol or create and insert a new one. 54 StringRef Name = New->getName(); 55 Builder.add(Name); 56 Symbol *&Sym = Symtab[Name]; 57 if (!Sym) { 58 Sym = new (Alloc) Symbol(New); 59 New->setBackref(Sym); 60 return; 61 } 62 New->setBackref(Sym); 63 64 // compare() returns -1, 0, or 1 if the lhs symbol is less preferable, 65 // equivalent (conflicting), or more preferable, respectively. 66 SymbolBody *Existing = Sym->Body; 67 int comp = Existing->compare(New); 68 if (comp < 0) 69 Sym->Body = New; 70 if (comp == 0) 71 error(Twine("duplicate symbol: ") + Name); 72 } 73