1 //===- Symbols.h ------------------------------------------------*- C++ -*-===//
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // All symbols are handled as SymbolBodies regardless of their types.
11 // This file defines various types of SymbolBodies.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLD_ELF_SYMBOLS_H
16 #define LLD_ELF_SYMBOLS_H
18 #include "InputSection.h"
21 #include "lld/Common/LLVM.h"
22 #include "llvm/Object/Archive.h"
23 #include "llvm/Object/ELF.h"
33 template <class ELFT> class ObjFile;
35 template <class ELFT> class SharedFile;
37 // The base class for real symbol classes.
48 Kind kind() const { return static_cast<Kind>(SymbolKind); }
50 // Symbol binding. This is not overwritten by replaceSymbol to track
51 // changes during resolution. In particular:
52 // - An undefined weak is still weak when it resolves to a shared library.
53 // - An undefined weak will not fetch archive members, but we have to
54 // remember it is weak.
57 // Version definition index.
60 // Symbol visibility. This is the computed minimum visibility of all
61 // observed non-DSO symbols.
62 unsigned Visibility : 2;
64 // True if the symbol was used for linking and thus need to be added to the
65 // output file's symbol table. This is true for all symbols except for
66 // unreferenced DSO symbols and bitcode symbols that are unreferenced except
67 // by other bitcode objects.
68 unsigned IsUsedInRegularObj : 1;
70 // If this flag is true and the symbol has protected or default visibility, it
71 // will appear in .dynsym. This flag is set by interposable DSO symbols in
72 // executables, by most symbols in DSOs and executables built with
73 // --export-dynamic, and by dynamic lists.
74 unsigned ExportDynamic : 1;
76 // False if LTO shouldn't inline whatever this symbol points to. If a symbol
77 // is overwritten after LTO, LTO shouldn't inline the symbol because it
78 // doesn't know the final contents of the symbol.
79 unsigned CanInline : 1;
81 // True if this symbol is specified by --trace-symbol option.
84 // This symbol version was found in a version script.
85 unsigned InVersionScript : 1;
87 // The file from which this symbol was created.
90 bool includeInDynsym() const;
91 uint8_t computeBinding() const;
92 bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; }
94 bool isUndefined() const { return SymbolKind == UndefinedKind; }
95 bool isDefined() const { return SymbolKind == DefinedKind; }
96 bool isShared() const { return SymbolKind == SharedKind; }
97 bool isLocal() const { return Binding == llvm::ELF::STB_LOCAL; }
100 return SymbolKind == LazyArchiveKind || SymbolKind == LazyObjectKind;
103 // True is this is an undefined weak symbol. This only works once
104 // all input files have been added.
105 bool isUndefWeak() const {
106 // See comment on Lazy the details.
107 return isWeak() && (isUndefined() || isLazy());
110 StringRef getName() const { return Name; }
111 uint8_t getVisibility() const { return StOther & 0x3; }
112 void parseSymbolVersion();
114 bool isInGot() const { return GotIndex != -1U; }
115 bool isInPlt() const { return PltIndex != -1U; }
117 uint64_t getVA(int64_t Addend = 0) const;
119 uint64_t getGotOffset() const;
120 uint64_t getGotVA() const;
121 uint64_t getGotPltOffset() const;
122 uint64_t getGotPltVA() const;
123 uint64_t getPltVA() const;
124 uint64_t getSize() const;
125 OutputSection *getOutputSection() const;
127 uint32_t DynsymIndex = 0;
128 uint32_t GotIndex = -1;
129 uint32_t GotPltIndex = -1;
130 uint32_t PltIndex = -1;
131 uint32_t GlobalDynIndex = -1;
134 Symbol(Kind K, InputFile *File, StringRefZ Name, uint8_t Binding,
135 uint8_t StOther, uint8_t Type)
136 : Binding(Binding), File(File), SymbolKind(K), NeedsPltAddr(false),
137 IsInGlobalMipsGot(false), Is32BitMipsGot(false), IsInIplt(false),
138 IsInIgot(false), IsPreemptible(false), Used(!Config->GcSections),
139 Type(Type), StOther(StOther), Name(Name) {}
141 const unsigned SymbolKind : 8;
144 // True the symbol should point to its PLT entry.
145 // For SharedSymbol only.
146 unsigned NeedsPltAddr : 1;
147 // True if this symbol has an entry in the global part of MIPS GOT.
148 unsigned IsInGlobalMipsGot : 1;
150 // True if this symbol is referenced by 32-bit GOT relocations.
151 unsigned Is32BitMipsGot : 1;
153 // True if this symbol is in the Iplt sub-section of the Plt.
154 unsigned IsInIplt : 1;
156 // True if this symbol is in the Igot sub-section of the .got.plt or .got.
157 unsigned IsInIgot : 1;
159 unsigned IsPreemptible : 1;
161 // True if an undefined or shared symbol is used from a live section.
164 // The following fields have the same meaning as the ELF symbol attributes.
165 uint8_t Type; // symbol type
166 uint8_t StOther; // st_other field value
168 // The Type field may also have this value. It means that we have not yet seen
169 // a non-Lazy symbol with this name, so we don't know what its type is. The
170 // Type field is normally set to this value for Lazy symbols unless we saw a
171 // weak undefined symbol first, in which case we need to remember the original
172 // symbol's type in order to check for TLS mismatches.
173 enum { UnknownType = 255 };
175 bool isSection() const { return Type == llvm::ELF::STT_SECTION; }
176 bool isTls() const { return Type == llvm::ELF::STT_TLS; }
177 bool isFunc() const { return Type == llvm::ELF::STT_FUNC; }
178 bool isGnuIFunc() const { return Type == llvm::ELF::STT_GNU_IFUNC; }
179 bool isObject() const { return Type == llvm::ELF::STT_OBJECT; }
180 bool isFile() const { return Type == llvm::ELF::STT_FILE; }
186 // Represents a symbol that is defined in the current output file.
187 class Defined : public Symbol {
189 Defined(InputFile *File, StringRefZ Name, uint8_t Binding, uint8_t StOther,
190 uint8_t Type, uint64_t Value, uint64_t Size, SectionBase *Section)
191 : Symbol(DefinedKind, File, Name, Binding, StOther, Type), Value(Value),
192 Size(Size), Section(Section) {}
194 static bool classof(const Symbol *S) { return S->isDefined(); }
198 SectionBase *Section;
201 class Undefined : public Symbol {
203 Undefined(InputFile *File, StringRefZ Name, uint8_t Binding, uint8_t StOther,
205 : Symbol(UndefinedKind, File, Name, Binding, StOther, Type) {}
207 static bool classof(const Symbol *S) { return S->kind() == UndefinedKind; }
210 class SharedSymbol : public Symbol {
212 static bool classof(const Symbol *S) { return S->kind() == SharedKind; }
214 SharedSymbol(InputFile &File, StringRef Name, uint8_t Binding,
215 uint8_t StOther, uint8_t Type, uint64_t Value, uint64_t Size,
216 uint32_t Alignment, uint32_t VerdefIndex)
217 : Symbol(SharedKind, &File, Name, Binding, StOther, Type), Value(Value),
218 Size(Size), VerdefIndex(VerdefIndex), Alignment(Alignment) {
219 // GNU ifunc is a mechanism to allow user-supplied functions to
220 // resolve PLT slot values at load-time. This is contrary to the
221 // regular symbol resolution scheme in which symbols are resolved just
222 // by name. Using this hook, you can program how symbols are solved
223 // for you program. For example, you can make "memcpy" to be resolved
224 // to a SSE-enabled version of memcpy only when a machine running the
225 // program supports the SSE instruction set.
227 // Naturally, such symbols should always be called through their PLT
228 // slots. What GNU ifunc symbols point to are resolver functions, and
229 // calling them directly doesn't make sense (unless you are writing a
232 // For DSO symbols, we always call them through PLT slots anyway.
233 // So there's no difference between GNU ifunc and regular function
234 // symbols if they are in DSOs. So we can handle GNU_IFUNC as FUNC.
235 if (this->Type == llvm::ELF::STT_GNU_IFUNC)
236 this->Type = llvm::ELF::STT_FUNC;
239 template <class ELFT> SharedFile<ELFT> &getFile() const {
240 return *cast<SharedFile<ELFT>>(File);
243 // If not null, there is a copy relocation to this section.
244 InputSection *CopyRelSec = nullptr;
246 uint64_t Value; // st_value
247 uint64_t Size; // st_size
249 // This field is a index to the symbol's version definition.
250 uint32_t VerdefIndex;
255 // This represents a symbol that is not yet in the link, but we know where to
256 // find it if needed. If the resolver finds both Undefined and Lazy for the same
257 // name, it will ask the Lazy to load a file.
259 // A special complication is the handling of weak undefined symbols. They should
260 // not load a file, but we have to remember we have seen both the weak undefined
261 // and the lazy. We represent that with a lazy symbol with a weak binding. This
262 // means that code looking for undefined symbols normally also has to take lazy
263 // symbols into consideration.
264 class Lazy : public Symbol {
266 static bool classof(const Symbol *S) { return S->isLazy(); }
268 // Returns an object file for this symbol, or a nullptr if the file
269 // was already returned.
273 Lazy(Kind K, InputFile &File, StringRef Name, uint8_t Type)
274 : Symbol(K, &File, Name, llvm::ELF::STB_GLOBAL, llvm::ELF::STV_DEFAULT,
278 // This class represents a symbol defined in an archive file. It is
279 // created from an archive file header, and it knows how to load an
280 // object file from an archive to replace itself with a defined
282 class LazyArchive : public Lazy {
284 LazyArchive(InputFile &File, const llvm::object::Archive::Symbol S,
286 : Lazy(LazyArchiveKind, File, S.getName(), Type), Sym(S) {}
288 static bool classof(const Symbol *S) { return S->kind() == LazyArchiveKind; }
290 ArchiveFile &getFile();
294 const llvm::object::Archive::Symbol Sym;
297 // LazyObject symbols represents symbols in object files between
298 // --start-lib and --end-lib options.
299 class LazyObject : public Lazy {
301 LazyObject(InputFile &File, StringRef Name, uint8_t Type)
302 : Lazy(LazyObjectKind, File, Name, Type) {}
304 static bool classof(const Symbol *S) { return S->kind() == LazyObjectKind; }
306 LazyObjFile &getFile();
310 // Some linker-generated symbols need to be created as
317 static Defined *Etext1;
318 static Defined *Etext2;
321 static Defined *Edata1;
322 static Defined *Edata2;
325 static Defined *End1;
326 static Defined *End2;
328 // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
329 // be at some offset from the base of the .got section, usually 0 or
330 // the end of the .got.
331 static Defined *GlobalOffsetTable;
333 // _gp, _gp_disp and __gnu_local_gp symbols. Only for MIPS.
334 static Defined *MipsGp;
335 static Defined *MipsGpDisp;
336 static Defined *MipsLocalGp;
339 // A buffer class that is large enough to hold any Symbol-derived
340 // object. We allocate memory using this class and instantiate a symbol
341 // using the placement new.
343 alignas(Defined) char A[sizeof(Defined)];
344 alignas(Undefined) char C[sizeof(Undefined)];
345 alignas(SharedSymbol) char D[sizeof(SharedSymbol)];
346 alignas(LazyArchive) char E[sizeof(LazyArchive)];
347 alignas(LazyObject) char F[sizeof(LazyObject)];
350 void printTraceSymbol(Symbol *Sym);
352 template <typename T, typename... ArgT>
353 void replaceSymbol(Symbol *S, ArgT &&... Arg) {
354 static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
355 static_assert(alignof(T) <= alignof(SymbolUnion),
356 "SymbolUnion not aligned enough");
357 assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
362 new (S) T(std::forward<ArgT>(Arg)...);
364 S->VersionId = Sym.VersionId;
365 S->Visibility = Sym.Visibility;
366 S->IsUsedInRegularObj = Sym.IsUsedInRegularObj;
367 S->ExportDynamic = Sym.ExportDynamic;
368 S->CanInline = Sym.CanInline;
369 S->Traced = Sym.Traced;
370 S->InVersionScript = Sym.InVersionScript;
372 // Print out a log message if --trace-symbol was specified.
373 // This is for debugging.
379 std::string toString(const elf::Symbol &B);