]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - ELF/Symbols.h
Vendor import of lld trunk r257626:
[FreeBSD/FreeBSD.git] / ELF / Symbols.h
1 //===- Symbols.h ------------------------------------------------*- C++ -*-===//
2 //
3 //                             The LLVM Linker
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // All symbols are handled as SymbolBodies regardless of their types.
11 // This file defines various types of SymbolBodies.
12 //
13 // File-scope symbols in ELF objects are the only exception of SymbolBody
14 // instantiation. We will never create SymbolBodies for them for performance
15 // reason. They are often represented as nullptrs. This is fine for symbol
16 // resolution because the symbol table naturally cares only about
17 // externally-visible symbols. For relocations, you have to deal with both
18 // local and non-local functions, and we have two different functions
19 // where we need them.
20 //
21 //===----------------------------------------------------------------------===//
22
23 #ifndef LLD_ELF_SYMBOLS_H
24 #define LLD_ELF_SYMBOLS_H
25
26 #include "InputSection.h"
27
28 #include "lld/Core/LLVM.h"
29 #include "llvm/Object/Archive.h"
30 #include "llvm/Object/ELF.h"
31
32 namespace lld {
33 namespace elf2 {
34
35 class ArchiveFile;
36 class InputFile;
37 class SymbolBody;
38 template <class ELFT> class ObjectFile;
39 template <class ELFT> class OutputSection;
40 template <class ELFT> class OutputSectionBase;
41 template <class ELFT> class SharedFile;
42
43 // Initializes global objects defined in this file.
44 // Called at the beginning of main().
45 void initSymbols();
46
47 // A real symbol object, SymbolBody, is usually accessed indirectly
48 // through a Symbol. There's always one Symbol for each symbol name.
49 // The resolver updates SymbolBody pointers as it resolves symbols.
50 struct Symbol {
51   SymbolBody *Body;
52 };
53
54 // The base class for real symbol classes.
55 class SymbolBody {
56 public:
57   enum Kind {
58     DefinedFirst,
59     DefinedRegularKind = DefinedFirst,
60     SharedKind,
61     DefinedElfLast = SharedKind,
62     DefinedCommonKind,
63     DefinedSyntheticKind,
64     DefinedLast = DefinedSyntheticKind,
65     UndefinedElfKind,
66     UndefinedKind,
67     LazyKind
68   };
69
70   Kind kind() const { return static_cast<Kind>(SymbolKind); }
71
72   bool isWeak() const { return IsWeak; }
73   bool isUndefined() const {
74     return SymbolKind == UndefinedKind || SymbolKind == UndefinedElfKind;
75   }
76   bool isDefined() const { return SymbolKind <= DefinedLast; }
77   bool isCommon() const { return SymbolKind == DefinedCommonKind; }
78   bool isLazy() const { return SymbolKind == LazyKind; }
79   bool isShared() const { return SymbolKind == SharedKind; }
80   bool isUsedInRegularObj() const { return IsUsedInRegularObj; }
81   bool isUsedInDynamicReloc() const { return IsUsedInDynamicReloc; }
82   void setUsedInDynamicReloc() { IsUsedInDynamicReloc = true; }
83   bool isTls() const { return IsTls; }
84
85   // Returns the symbol name.
86   StringRef getName() const { return Name; }
87
88   uint8_t getVisibility() const { return Visibility; }
89
90   unsigned DynamicSymbolTableIndex = 0;
91   uint32_t GlobalDynIndex = -1;
92   uint32_t GotIndex = -1;
93   uint32_t GotPltIndex = -1;
94   uint32_t PltIndex = -1;
95   bool hasGlobalDynIndex() { return GlobalDynIndex != uint32_t(-1); }
96   bool isInGot() const { return GotIndex != -1U; }
97   bool isInGotPlt() const { return GotPltIndex != -1U; }
98   bool isInPlt() const { return PltIndex != -1U; }
99
100   // A SymbolBody has a backreference to a Symbol. Originally they are
101   // doubly-linked. A backreference will never change. But the pointer
102   // in the Symbol may be mutated by the resolver. If you have a
103   // pointer P to a SymbolBody and are not sure whether the resolver
104   // has chosen the object among other objects having the same name,
105   // you can access P->Backref->Body to get the resolver's result.
106   void setBackref(Symbol *P) { Backref = P; }
107   SymbolBody *repl() { return Backref ? Backref->Body : this; }
108   Symbol *getSymbol() { return Backref; }
109
110   // Decides which symbol should "win" in the symbol table, this or
111   // the Other. Returns 1 if this wins, -1 if the Other wins, or 0 if
112   // they are duplicate (conflicting) symbols.
113   template <class ELFT> int compare(SymbolBody *Other);
114
115 protected:
116   SymbolBody(Kind K, StringRef Name, bool IsWeak, uint8_t Visibility,
117              bool IsTls)
118       : SymbolKind(K), IsWeak(IsWeak), Visibility(Visibility), IsTls(IsTls),
119         Name(Name) {
120     IsUsedInRegularObj = K != SharedKind && K != LazyKind;
121     IsUsedInDynamicReloc = 0;
122   }
123
124   const unsigned SymbolKind : 8;
125   unsigned IsWeak : 1;
126   unsigned Visibility : 2;
127
128   // True if the symbol was used for linking and thus need to be
129   // added to the output file's symbol table. It is usually true,
130   // but if it is a shared symbol that were not referenced by anyone,
131   // it can be false.
132   unsigned IsUsedInRegularObj : 1;
133
134   // If true, the symbol is added to .dynsym symbol table.
135   unsigned IsUsedInDynamicReloc : 1;
136
137   unsigned IsTls : 1;
138   StringRef Name;
139   Symbol *Backref = nullptr;
140 };
141
142 // The base class for any defined symbols.
143 class Defined : public SymbolBody {
144 public:
145   Defined(Kind K, StringRef Name, bool IsWeak, uint8_t Visibility, bool IsTls);
146   static bool classof(const SymbolBody *S) { return S->isDefined(); }
147 };
148
149 // Any defined symbol from an ELF file.
150 template <class ELFT> class DefinedElf : public Defined {
151 protected:
152   typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
153
154 public:
155   DefinedElf(Kind K, StringRef N, const Elf_Sym &Sym)
156       : Defined(K, N, Sym.getBinding() == llvm::ELF::STB_WEAK,
157                 Sym.getVisibility(), Sym.getType() == llvm::ELF::STT_TLS),
158         Sym(Sym) {}
159
160   const Elf_Sym &Sym;
161   static bool classof(const SymbolBody *S) {
162     return S->kind() <= DefinedElfLast;
163   }
164 };
165
166 class DefinedCommon : public Defined {
167 public:
168   DefinedCommon(StringRef N, uint64_t Size, uint64_t Alignment, bool IsWeak,
169                 uint8_t Visibility);
170
171   static bool classof(const SymbolBody *S) {
172     return S->kind() == SymbolBody::DefinedCommonKind;
173   }
174
175   // The output offset of this common symbol in the output bss. Computed by the
176   // writer.
177   uint64_t OffsetInBss;
178
179   // The maximum alignment we have seen for this symbol.
180   uint64_t MaxAlignment;
181
182   uint64_t Size;
183 };
184
185 // Regular defined symbols read from object file symbol tables.
186 template <class ELFT> class DefinedRegular : public DefinedElf<ELFT> {
187   typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
188
189 public:
190   DefinedRegular(StringRef N, const Elf_Sym &Sym,
191                  InputSectionBase<ELFT> *Section)
192       : DefinedElf<ELFT>(SymbolBody::DefinedRegularKind, N, Sym),
193         Section(Section) {}
194
195   static bool classof(const SymbolBody *S) {
196     return S->kind() == SymbolBody::DefinedRegularKind;
197   }
198
199   // If this is null, the symbol is absolute.
200   InputSectionBase<ELFT> *Section;
201 };
202
203 // DefinedSynthetic is a class to represent linker-generated ELF symbols.
204 // The difference from the regular symbol is that DefinedSynthetic symbols
205 // don't belong to any input files or sections. Thus, its constructor
206 // takes an output section to calculate output VA, etc.
207 template <class ELFT> class DefinedSynthetic : public Defined {
208 public:
209   typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
210   typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
211   DefinedSynthetic(StringRef N, uintX_t Value,
212                    OutputSectionBase<ELFT> &Section);
213
214   static bool classof(const SymbolBody *S) {
215     return S->kind() == SymbolBody::DefinedSyntheticKind;
216   }
217
218   uintX_t Value;
219   const OutputSectionBase<ELFT> &Section;
220 };
221
222 // Undefined symbol.
223 class Undefined : public SymbolBody {
224   typedef SymbolBody::Kind Kind;
225   bool CanKeepUndefined;
226
227 protected:
228   Undefined(Kind K, StringRef N, bool IsWeak, uint8_t Visibility, bool IsTls);
229
230 public:
231   Undefined(StringRef N, bool IsWeak, uint8_t Visibility,
232             bool CanKeepUndefined);
233
234   static bool classof(const SymbolBody *S) { return S->isUndefined(); }
235
236   bool canKeepUndefined() const { return CanKeepUndefined; }
237 };
238
239 template <class ELFT> class UndefinedElf : public Undefined {
240   typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
241
242 public:
243   UndefinedElf(StringRef N, const Elf_Sym &Sym);
244   const Elf_Sym &Sym;
245
246   static bool classof(const SymbolBody *S) {
247     return S->kind() == SymbolBody::UndefinedElfKind;
248   }
249 };
250
251 template <class ELFT> class SharedSymbol : public DefinedElf<ELFT> {
252   typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
253   typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
254
255 public:
256   static bool classof(const SymbolBody *S) {
257     return S->kind() == SymbolBody::SharedKind;
258   }
259
260   SharedSymbol(SharedFile<ELFT> *F, StringRef Name, const Elf_Sym &Sym)
261       : DefinedElf<ELFT>(SymbolBody::SharedKind, Name, Sym), File(F) {}
262
263   SharedFile<ELFT> *File;
264
265   // True if the linker has to generate a copy relocation for this shared
266   // symbol. OffsetInBss is significant only when NeedsCopy is true.
267   bool NeedsCopy = false;
268   uintX_t OffsetInBss = 0;
269 };
270
271 // This class represents a symbol defined in an archive file. It is
272 // created from an archive file header, and it knows how to load an
273 // object file from an archive to replace itself with a defined
274 // symbol. If the resolver finds both Undefined and Lazy for
275 // the same name, it will ask the Lazy to load a file.
276 class Lazy : public SymbolBody {
277 public:
278   Lazy(ArchiveFile *F, const llvm::object::Archive::Symbol S)
279       : SymbolBody(LazyKind, S.getName(), false, llvm::ELF::STV_DEFAULT, false),
280         File(F), Sym(S) {}
281
282   static bool classof(const SymbolBody *S) { return S->kind() == LazyKind; }
283
284   // Returns an object file for this symbol, or a nullptr if the file
285   // was already returned.
286   std::unique_ptr<InputFile> getMember();
287
288   void setWeak() { IsWeak = true; }
289   void setUsedInRegularObj() { IsUsedInRegularObj = true; }
290
291 private:
292   ArchiveFile *File;
293   const llvm::object::Archive::Symbol Sym;
294 };
295
296 // Some linker-generated symbols need to be created as
297 // DefinedRegular symbols, so they need Elf_Sym symbols.
298 // Here we allocate such Elf_Sym symbols statically.
299 template <class ELFT> struct ElfSym {
300   typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
301
302   // Used to represent an undefined symbol which we don't want
303   // to add to the output file's symbol table. The `IgnoredWeak`
304   // has weak binding and can be substituted. The `Ignore` has
305   // global binding and gets priority over symbols from shared libs.
306   static Elf_Sym IgnoredWeak;
307   static Elf_Sym Ignored;
308
309   // The content for _end and end symbols.
310   static Elf_Sym End;
311
312   // The content for _gp symbol for MIPS target.
313   static Elf_Sym MipsGp;
314
315   // __rel_iplt_start/__rel_iplt_end for signaling
316   // where R_[*]_IRELATIVE relocations do live.
317   static Elf_Sym RelaIpltStart;
318   static Elf_Sym RelaIpltEnd;
319 };
320
321 template <class ELFT> typename ElfSym<ELFT>::Elf_Sym ElfSym<ELFT>::IgnoredWeak;
322 template <class ELFT> typename ElfSym<ELFT>::Elf_Sym ElfSym<ELFT>::Ignored;
323 template <class ELFT> typename ElfSym<ELFT>::Elf_Sym ElfSym<ELFT>::End;
324 template <class ELFT> typename ElfSym<ELFT>::Elf_Sym ElfSym<ELFT>::MipsGp;
325 template <class ELFT>
326 typename ElfSym<ELFT>::Elf_Sym ElfSym<ELFT>::RelaIpltStart;
327 template <class ELFT> typename ElfSym<ELFT>::Elf_Sym ElfSym<ELFT>::RelaIpltEnd;
328
329 } // namespace elf2
330 } // namespace lld
331
332 #endif