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(StringRef 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 identicalCodeFoldingKind(ICFFoldKind::None
),
64 referencedDynamically(isReferencedDynamically
), noDeadStrip(noDeadStrip
),
65 interposable(interposable
), weakDefCanBeHidden(isWeakDefCanBeHidden
),
66 weakDef(isWeakDef
), external(isExternal
), originalIsec(isec
),
67 value(value
), size(size
) {
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(originalIsec
->getFlags());
88 uint64_t Defined::getVA() const {
89 assert(isLive() && "this should only be called for live symbols");
94 if (!isec()->isFinal
) {
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 originalIsec
? dyn_cast_or_null
<ObjFile
>(originalIsec
->getFile())
113 std::string
Defined::getSourceLocation() {
116 return originalIsec
->getSourceLocation(value
);
119 // Get the canonical InputSection of the symbol.
120 InputSection
*Defined::isec() const {
121 return originalIsec
? originalIsec
->canonical() : nullptr;
124 // Get the canonical unwind entry of the symbol.
125 ConcatInputSection
*Defined::unwindEntry() const {
126 return originalUnwindEntry
? originalUnwindEntry
->canonical() : nullptr;
129 uint64_t DylibSymbol::getVA() const {
130 return isInStubs() ? getStubVA() : Symbol::getVA();
133 void LazyArchive::fetchArchiveMember() { getFile()->fetch(sym
); }