1 //===- SymbolTable.cpp ----------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "SymbolTable.h"
10 #include "InputFiles.h"
12 #include "lld/Common/ErrorHandler.h"
13 #include "lld/Common/Memory.h"
17 using namespace lld::macho
;
19 Symbol
*SymbolTable::find(StringRef name
) {
20 auto it
= symMap
.find(llvm::CachedHashStringRef(name
));
21 if (it
== symMap
.end())
23 return symVector
[it
->second
];
26 std::pair
<Symbol
*, bool> SymbolTable::insert(StringRef name
) {
27 auto p
= symMap
.insert({CachedHashStringRef(name
), (int)symVector
.size()});
29 // Name already present in the symbol table.
31 return {symVector
[p
.first
->second
], false};
33 // Name is a new symbol.
34 Symbol
*sym
= reinterpret_cast<Symbol
*>(make
<SymbolUnion
>());
35 symVector
.push_back(sym
);
39 Symbol
*SymbolTable::addDefined(StringRef name
, InputSection
*isec
,
40 uint32_t value
, bool isWeakDef
) {
43 bool overridesWeakDef
= false;
44 std::tie(s
, wasInserted
) = insert(name
);
47 if (auto *defined
= dyn_cast
<Defined
>(s
)) {
50 if (!defined
->isWeakDef())
51 error("duplicate symbol: " + name
);
52 } else if (auto *dysym
= dyn_cast
<DylibSymbol
>(s
)) {
53 overridesWeakDef
= !isWeakDef
&& dysym
->isWeakDef();
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.
59 Defined
*defined
= replaceSymbol
<Defined
>(s
, name
, isec
, value
, isWeakDef
,
61 defined
->overridesWeakDef
= overridesWeakDef
;
65 Symbol
*SymbolTable::addUndefined(StringRef name
) {
68 std::tie(s
, wasInserted
) = insert(name
);
71 replaceSymbol
<Undefined
>(s
, name
);
72 else if (LazySymbol
*lazy
= dyn_cast
<LazySymbol
>(s
))
73 lazy
->fetchArchiveMember();
77 Symbol
*SymbolTable::addCommon(StringRef name
, InputFile
*file
, uint64_t size
,
81 std::tie(s
, wasInserted
) = insert(name
);
84 if (auto *common
= dyn_cast
<CommonSymbol
>(s
)) {
85 if (size
< common
->size
)
87 } else if (isa
<Defined
>(s
)) {
90 // Common symbols take priority over all non-Defined symbols, so in case of
91 // a name conflict, we fall through to the replaceSymbol() call below.
94 replaceSymbol
<CommonSymbol
>(s
, name
, file
, size
, align
);
98 Symbol
*SymbolTable::addDylib(StringRef name
, DylibFile
*file
, bool isWeakDef
,
102 std::tie(s
, wasInserted
) = insert(name
);
104 if (!wasInserted
&& isWeakDef
)
105 if (auto *defined
= dyn_cast
<Defined
>(s
))
106 if (!defined
->isWeakDef())
107 defined
->overridesWeakDef
= true;
109 if (wasInserted
|| isa
<Undefined
>(s
) ||
110 (isa
<DylibSymbol
>(s
) && !isWeakDef
&& s
->isWeakDef()))
111 replaceSymbol
<DylibSymbol
>(s
, file
, name
, isWeakDef
, isTlv
);
116 Symbol
*SymbolTable::addLazy(StringRef name
, ArchiveFile
*file
,
117 const llvm::object::Archive::Symbol
&sym
) {
120 std::tie(s
, wasInserted
) = insert(name
);
123 replaceSymbol
<LazySymbol
>(s
, file
, sym
);
124 else if (isa
<Undefined
>(s
) || (isa
<DylibSymbol
>(s
) && s
->isWeakDef()))
129 Symbol
*SymbolTable::addDSOHandle(const MachHeaderSection
*header
) {
132 std::tie(s
, wasInserted
) = insert(DSOHandle::name
);
134 // FIXME: Make every symbol (including absolute symbols) contain a
135 // reference to their originating file, then add that file name to this
137 if (auto *defined
= dyn_cast
<Defined
>(s
))
138 error("found defined symbol with illegal name " + DSOHandle::name
);
140 replaceSymbol
<DSOHandle
>(s
, header
);
144 SymbolTable
*macho::symtab
;