1 //===- Symbols.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 //===----------------------------------------------------------------------===//
10 #include "InputFiles.h"
11 #include "SyntheticSections.h"
12 #include "llvm/Demangle/Demangle.h"
16 using namespace lld::macho
;
18 static_assert(sizeof(void *) != 8 || sizeof(Symbol
) == 56,
19 "Try to minimize Symbol's size; we create many instances");
21 // The Microsoft ABI doesn't support using parent class tail padding for child
22 // members, hence the _MSC_VER check.
23 #if !defined(_MSC_VER)
24 static_assert(sizeof(void *) != 8 || sizeof(Defined
) == 88,
25 "Try to minimize Defined's size; we create many instances");
28 static_assert(sizeof(SymbolUnion
) == sizeof(Defined
),
29 "Defined should be the largest Symbol kind");
31 // Returns a symbol name for an error message.
32 static std::string
maybeDemangleSymbol(StringRef symName
) {
33 if (config
->demangle
) {
34 symName
.consume_front("_");
35 return demangle(symName
);
40 std::string
lld::toString(const Symbol
&sym
) {
41 return maybeDemangleSymbol(sym
.getName());
44 std::string
lld::toMachOString(const object::Archive::Symbol
&b
) {
45 return maybeDemangleSymbol(b
.getName());
48 uint64_t Symbol::getStubVA() const { return in
.stubs
->getVA(stubsIndex
); }
49 uint64_t Symbol::getLazyPtrVA() const {
50 return in
.lazyPointers
->getVA(stubsIndex
);
52 uint64_t Symbol::getGotVA() const { return in
.got
->getVA(gotIndex
); }
53 uint64_t Symbol::getTlvVA() const { return in
.tlvPointers
->getVA(gotIndex
); }
55 Defined::Defined(StringRefZ name
, InputFile
*file
, InputSection
*isec
,
56 uint64_t value
, uint64_t size
, bool isWeakDef
, bool isExternal
,
57 bool isPrivateExtern
, bool includeInSymtab
,
58 bool isReferencedDynamically
, bool noDeadStrip
,
59 bool canOverrideWeakDef
, bool isWeakDefCanBeHidden
,
61 : Symbol(DefinedKind
, name
, file
), overridesWeakDef(canOverrideWeakDef
),
62 privateExtern(isPrivateExtern
), includeInSymtab(includeInSymtab
),
63 wasIdenticalCodeFolded(false),
64 referencedDynamically(isReferencedDynamically
), noDeadStrip(noDeadStrip
),
65 interposable(interposable
), weakDefCanBeHidden(isWeakDefCanBeHidden
),
66 weakDef(isWeakDef
), external(isExternal
), isec(isec
), value(value
),
69 isec
->symbols
.push_back(this);
70 // Maintain sorted order.
71 for (auto it
= isec
->symbols
.rbegin(), rend
= isec
->symbols
.rend();
73 auto next
= std::next(it
);
76 if ((*it
)->value
< (*next
)->value
)
77 std::swap(*next
, *it
);
84 bool Defined::isTlv() const {
85 return !isAbsolute() && isThreadLocalVariables(isec
->getFlags());
88 uint64_t Defined::getVA() const {
89 assert(isLive() && "this should only be called for live symbols");
95 // A target arch that does not use thunks ought never ask for
96 // the address of a function that has not yet been finalized.
97 assert(target
->usesThunks());
99 // ConcatOutputSection::finalize() can seek the address of a
100 // function before its address is assigned. The thunking algorithm
101 // knows that unfinalized functions will be out of range, so it is
102 // expedient to return a contrived out-of-range address.
103 return TargetInfo::outOfRangeVA
;
105 return isec
->getVA(value
);
108 ObjFile
*Defined::getObjectFile() const {
109 return isec
? dyn_cast_or_null
<ObjFile
>(isec
->getFile()) : nullptr;
112 void Defined::canonicalize() {
114 unwindEntry
= unwindEntry
->canonical();
116 isec
= isec
->canonical();
119 std::string
Defined::getSourceLocation() {
122 return isec
->getSourceLocation(value
);
125 uint64_t DylibSymbol::getVA() const {
126 return isInStubs() ? getStubVA() : Symbol::getVA();
129 void LazyArchive::fetchArchiveMember() { getFile()->fetch(sym
); }