1 //===- SymbolTable.cpp ----------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "SymbolTable.h" 10 #include "InputFiles.h" 11 #include "Symbols.h" 12 #include "lld/Common/ErrorHandler.h" 13 #include "lld/Common/Memory.h" 14 15 using namespace llvm; 16 using namespace lld; 17 using namespace lld::macho; 18 19 Symbol *SymbolTable::find(StringRef name) { 20 auto it = symMap.find(llvm::CachedHashStringRef(name)); 21 if (it == symMap.end()) 22 return nullptr; 23 return symVector[it->second]; 24 } 25 26 std::pair<Symbol *, bool> SymbolTable::insert(StringRef name) { 27 auto p = symMap.insert({CachedHashStringRef(name), (int)symVector.size()}); 28 29 // Name already present in the symbol table. 30 if (!p.second) 31 return {symVector[p.first->second], false}; 32 33 // Name is a new symbol. 34 Symbol *sym = reinterpret_cast<Symbol *>(make<SymbolUnion>()); 35 symVector.push_back(sym); 36 return {sym, true}; 37 } 38 39 Symbol *SymbolTable::addDefined(StringRef name, InputSection *isec, 40 uint32_t value, bool isWeakDef) { 41 Symbol *s; 42 bool wasInserted; 43 bool overridesWeakDef = false; 44 std::tie(s, wasInserted) = insert(name); 45 46 if (!wasInserted) { 47 if (auto *defined = dyn_cast<Defined>(s)) { 48 if (isWeakDef) 49 return s; 50 if (!defined->isWeakDef()) 51 error("duplicate symbol: " + name); 52 } else if (auto *dysym = dyn_cast<DylibSymbol>(s)) { 53 overridesWeakDef = !isWeakDef && dysym->isWeakDef(); 54 } 55 // Defined symbols take priority over other types of symbols, so in case 56 // of a name conflict, we fall through to the replaceSymbol() call below. 57 } 58 59 Defined *defined = replaceSymbol<Defined>(s, name, isec, value, isWeakDef, 60 /*isExternal=*/true); 61 defined->overridesWeakDef = overridesWeakDef; 62 return s; 63 } 64 65 Symbol *SymbolTable::addUndefined(StringRef name) { 66 Symbol *s; 67 bool wasInserted; 68 std::tie(s, wasInserted) = insert(name); 69 70 if (wasInserted) 71 replaceSymbol<Undefined>(s, name); 72 else if (LazySymbol *lazy = dyn_cast<LazySymbol>(s)) 73 lazy->fetchArchiveMember(); 74 return s; 75 } 76 77 Symbol *SymbolTable::addDylib(StringRef name, DylibFile *file, bool isWeakDef, 78 bool isTlv) { 79 Symbol *s; 80 bool wasInserted; 81 std::tie(s, wasInserted) = insert(name); 82 83 if (!wasInserted && isWeakDef) 84 if (auto *defined = dyn_cast<Defined>(s)) 85 if (!defined->isWeakDef()) 86 defined->overridesWeakDef = true; 87 88 if (wasInserted || isa<Undefined>(s) || 89 (isa<DylibSymbol>(s) && !isWeakDef && s->isWeakDef())) 90 replaceSymbol<DylibSymbol>(s, file, name, isWeakDef, isTlv); 91 92 return s; 93 } 94 95 Symbol *SymbolTable::addLazy(StringRef name, ArchiveFile *file, 96 const llvm::object::Archive::Symbol &sym) { 97 Symbol *s; 98 bool wasInserted; 99 std::tie(s, wasInserted) = insert(name); 100 101 if (wasInserted) 102 replaceSymbol<LazySymbol>(s, file, sym); 103 else if (isa<Undefined>(s) || (isa<DylibSymbol>(s) && s->isWeakDef())) 104 file->fetch(sym); 105 return s; 106 } 107 108 Symbol *SymbolTable::addDSOHandle(const MachHeaderSection *header) { 109 Symbol *s; 110 bool wasInserted; 111 std::tie(s, wasInserted) = insert(DSOHandle::name); 112 if (!wasInserted) { 113 if (auto *defined = dyn_cast<Defined>(s)) 114 error("found defined symbol from " + defined->isec->file->getName() + 115 " with illegal name " + DSOHandle::name); 116 } 117 replaceSymbol<DSOHandle>(s, header); 118 return s; 119 } 120 121 SymbolTable *macho::symtab; 122