diff options
Diffstat (limited to 'lld/MachO/SymbolTable.cpp')
-rw-r--r-- | lld/MachO/SymbolTable.cpp | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/lld/MachO/SymbolTable.cpp b/lld/MachO/SymbolTable.cpp new file mode 100644 index 000000000000..80e870d79890 --- /dev/null +++ b/lld/MachO/SymbolTable.cpp @@ -0,0 +1,87 @@ +//===- SymbolTable.cpp ----------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "SymbolTable.h" +#include "InputFiles.h" +#include "Symbols.h" +#include "lld/Common/ErrorHandler.h" +#include "lld/Common/Memory.h" + +using namespace llvm; +using namespace lld; +using namespace lld::macho; + +Symbol *SymbolTable::find(StringRef name) { + auto it = symMap.find(llvm::CachedHashStringRef(name)); + if (it == symMap.end()) + return nullptr; + return symVector[it->second]; +} + +std::pair<Symbol *, bool> SymbolTable::insert(StringRef name) { + auto p = symMap.insert({CachedHashStringRef(name), (int)symVector.size()}); + + // Name already present in the symbol table. + if (!p.second) + return {symVector[p.first->second], false}; + + // Name is a new symbol. + Symbol *sym = reinterpret_cast<Symbol *>(make<SymbolUnion>()); + symVector.push_back(sym); + return {sym, true}; +} + +Symbol *SymbolTable::addDefined(StringRef name, InputSection *isec, + uint32_t value) { + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(name); + + if (!wasInserted && isa<Defined>(s)) + error("duplicate symbol: " + name); + + replaceSymbol<Defined>(s, name, isec, value); + return s; +} + +Symbol *SymbolTable::addUndefined(StringRef name) { + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(name); + + if (wasInserted) + replaceSymbol<Undefined>(s, name); + else if (LazySymbol *lazy = dyn_cast<LazySymbol>(s)) + lazy->fetchArchiveMember(); + return s; +} + +Symbol *SymbolTable::addDylib(StringRef name, DylibFile *file) { + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(name); + + if (wasInserted || isa<Undefined>(s)) + replaceSymbol<DylibSymbol>(s, file, name); + return s; +} + +Symbol *SymbolTable::addLazy(StringRef name, ArchiveFile *file, + const llvm::object::Archive::Symbol &sym) { + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(name); + + if (wasInserted) + replaceSymbol<LazySymbol>(s, file, sym); + else if (isa<Undefined>(s)) + file->fetch(sym); + return s; +} + +SymbolTable *macho::symtab; |