1*5ffd83dbSDimitry Andric //===- SymbolTable.cpp ----------------------------------------------------===// 2*5ffd83dbSDimitry Andric // 3*5ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*5ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*5ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*5ffd83dbSDimitry Andric // 7*5ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 8*5ffd83dbSDimitry Andric 9*5ffd83dbSDimitry Andric #include "SymbolTable.h" 10*5ffd83dbSDimitry Andric #include "InputFiles.h" 11*5ffd83dbSDimitry Andric #include "Symbols.h" 12*5ffd83dbSDimitry Andric #include "lld/Common/ErrorHandler.h" 13*5ffd83dbSDimitry Andric #include "lld/Common/Memory.h" 14*5ffd83dbSDimitry Andric 15*5ffd83dbSDimitry Andric using namespace llvm; 16*5ffd83dbSDimitry Andric using namespace lld; 17*5ffd83dbSDimitry Andric using namespace lld::macho; 18*5ffd83dbSDimitry Andric 19*5ffd83dbSDimitry Andric Symbol *SymbolTable::find(StringRef name) { 20*5ffd83dbSDimitry Andric auto it = symMap.find(llvm::CachedHashStringRef(name)); 21*5ffd83dbSDimitry Andric if (it == symMap.end()) 22*5ffd83dbSDimitry Andric return nullptr; 23*5ffd83dbSDimitry Andric return symVector[it->second]; 24*5ffd83dbSDimitry Andric } 25*5ffd83dbSDimitry Andric 26*5ffd83dbSDimitry Andric std::pair<Symbol *, bool> SymbolTable::insert(StringRef name) { 27*5ffd83dbSDimitry Andric auto p = symMap.insert({CachedHashStringRef(name), (int)symVector.size()}); 28*5ffd83dbSDimitry Andric 29*5ffd83dbSDimitry Andric // Name already present in the symbol table. 30*5ffd83dbSDimitry Andric if (!p.second) 31*5ffd83dbSDimitry Andric return {symVector[p.first->second], false}; 32*5ffd83dbSDimitry Andric 33*5ffd83dbSDimitry Andric // Name is a new symbol. 34*5ffd83dbSDimitry Andric Symbol *sym = reinterpret_cast<Symbol *>(make<SymbolUnion>()); 35*5ffd83dbSDimitry Andric symVector.push_back(sym); 36*5ffd83dbSDimitry Andric return {sym, true}; 37*5ffd83dbSDimitry Andric } 38*5ffd83dbSDimitry Andric 39*5ffd83dbSDimitry Andric Symbol *SymbolTable::addDefined(StringRef name, InputSection *isec, 40*5ffd83dbSDimitry Andric uint32_t value) { 41*5ffd83dbSDimitry Andric Symbol *s; 42*5ffd83dbSDimitry Andric bool wasInserted; 43*5ffd83dbSDimitry Andric std::tie(s, wasInserted) = insert(name); 44*5ffd83dbSDimitry Andric 45*5ffd83dbSDimitry Andric if (!wasInserted && isa<Defined>(s)) 46*5ffd83dbSDimitry Andric error("duplicate symbol: " + name); 47*5ffd83dbSDimitry Andric 48*5ffd83dbSDimitry Andric replaceSymbol<Defined>(s, name, isec, value); 49*5ffd83dbSDimitry Andric return s; 50*5ffd83dbSDimitry Andric } 51*5ffd83dbSDimitry Andric 52*5ffd83dbSDimitry Andric Symbol *SymbolTable::addUndefined(StringRef name) { 53*5ffd83dbSDimitry Andric Symbol *s; 54*5ffd83dbSDimitry Andric bool wasInserted; 55*5ffd83dbSDimitry Andric std::tie(s, wasInserted) = insert(name); 56*5ffd83dbSDimitry Andric 57*5ffd83dbSDimitry Andric if (wasInserted) 58*5ffd83dbSDimitry Andric replaceSymbol<Undefined>(s, name); 59*5ffd83dbSDimitry Andric else if (LazySymbol *lazy = dyn_cast<LazySymbol>(s)) 60*5ffd83dbSDimitry Andric lazy->fetchArchiveMember(); 61*5ffd83dbSDimitry Andric return s; 62*5ffd83dbSDimitry Andric } 63*5ffd83dbSDimitry Andric 64*5ffd83dbSDimitry Andric Symbol *SymbolTable::addDylib(StringRef name, DylibFile *file) { 65*5ffd83dbSDimitry Andric Symbol *s; 66*5ffd83dbSDimitry Andric bool wasInserted; 67*5ffd83dbSDimitry Andric std::tie(s, wasInserted) = insert(name); 68*5ffd83dbSDimitry Andric 69*5ffd83dbSDimitry Andric if (wasInserted || isa<Undefined>(s)) 70*5ffd83dbSDimitry Andric replaceSymbol<DylibSymbol>(s, file, name); 71*5ffd83dbSDimitry Andric return s; 72*5ffd83dbSDimitry Andric } 73*5ffd83dbSDimitry Andric 74*5ffd83dbSDimitry Andric Symbol *SymbolTable::addLazy(StringRef name, ArchiveFile *file, 75*5ffd83dbSDimitry Andric const llvm::object::Archive::Symbol &sym) { 76*5ffd83dbSDimitry Andric Symbol *s; 77*5ffd83dbSDimitry Andric bool wasInserted; 78*5ffd83dbSDimitry Andric std::tie(s, wasInserted) = insert(name); 79*5ffd83dbSDimitry Andric 80*5ffd83dbSDimitry Andric if (wasInserted) 81*5ffd83dbSDimitry Andric replaceSymbol<LazySymbol>(s, file, sym); 82*5ffd83dbSDimitry Andric else if (isa<Undefined>(s)) 83*5ffd83dbSDimitry Andric file->fetch(sym); 84*5ffd83dbSDimitry Andric return s; 85*5ffd83dbSDimitry Andric } 86*5ffd83dbSDimitry Andric 87*5ffd83dbSDimitry Andric SymbolTable *macho::symtab; 88