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) { 41 Symbol *s; 42 bool wasInserted; 43 std::tie(s, wasInserted) = insert(name); 44 45 if (!wasInserted && isa<Defined>(s)) 46 error("duplicate symbol: " + name); 47 48 replaceSymbol<Defined>(s, name, isec, value); 49 return s; 50 } 51 52 Symbol *SymbolTable::addUndefined(StringRef name) { 53 Symbol *s; 54 bool wasInserted; 55 std::tie(s, wasInserted) = insert(name); 56 57 if (wasInserted) 58 replaceSymbol<Undefined>(s, name); 59 else if (LazySymbol *lazy = dyn_cast<LazySymbol>(s)) 60 lazy->fetchArchiveMember(); 61 return s; 62 } 63 64 Symbol *SymbolTable::addDylib(StringRef name, DylibFile *file) { 65 Symbol *s; 66 bool wasInserted; 67 std::tie(s, wasInserted) = insert(name); 68 69 if (wasInserted || isa<Undefined>(s)) 70 replaceSymbol<DylibSymbol>(s, file, name); 71 return s; 72 } 73 74 Symbol *SymbolTable::addLazy(StringRef name, ArchiveFile *file, 75 const llvm::object::Archive::Symbol &sym) { 76 Symbol *s; 77 bool wasInserted; 78 std::tie(s, wasInserted) = insert(name); 79 80 if (wasInserted) 81 replaceSymbol<LazySymbol>(s, file, sym); 82 else if (isa<Undefined>(s)) 83 file->fetch(sym); 84 return s; 85 } 86 87 SymbolTable *macho::symtab; 88