blob: 296fd40a6ab65baf8228f367f762e2cdee5575c8 [file] [log] [blame]
Rafael Espindolabeee25e2015-08-14 14:12:54 +00001//===- Symbols.h ------------------------------------------------*- C++ -*-===//
Michael J. Spencer84487f12015-07-24 21:03:07 +00002//
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#ifndef LLD_ELF_SYMBOLS_H
11#define LLD_ELF_SYMBOLS_H
12
Rafael Espindola832b93f2015-08-24 20:06:32 +000013#include "Chunks.h"
14
Michael J. Spencer84487f12015-07-24 21:03:07 +000015#include "lld/Core/LLVM.h"
16#include "llvm/Object/ELF.h"
17
18namespace lld {
19namespace elf2 {
20
21using llvm::object::ELFFile;
22
23class Chunk;
24class InputFile;
25class SymbolBody;
Michael J. Spencercdae0a42015-07-28 22:58:25 +000026template <class ELFT> class ObjectFile;
Michael J. Spencer84487f12015-07-24 21:03:07 +000027
28// A real symbol object, SymbolBody, is usually accessed indirectly
29// through a Symbol. There's always one Symbol for each symbol name.
30// The resolver updates SymbolBody pointers as it resolves symbols.
31struct Symbol {
32 explicit Symbol(SymbolBody *P) : Body(P) {}
33 SymbolBody *Body;
34};
35
36// The base class for real symbol classes.
37class SymbolBody {
38public:
39 enum Kind {
Rafael Espindolaae1b23b2015-08-11 17:10:02 +000040 DefinedFirst = 0,
41 DefinedRegularKind = 0,
Rafael Espindolab13df652015-08-11 17:33:02 +000042 DefinedWeakKind = 1,
43 DefinedLast = 1,
Rafael Espindola76e24ea2015-08-11 17:57:05 +000044 UndefinedWeakKind = 2,
Rafael Espindola1bd885a2015-08-14 16:46:28 +000045 UndefinedKind = 3,
46 UndefinedSyntheticKind = 4
Michael J. Spencer84487f12015-07-24 21:03:07 +000047 };
48
Michael J. Spencercdae0a42015-07-28 22:58:25 +000049 Kind kind() const { return static_cast<Kind>(SymbolKind); }
Michael J. Spencer84487f12015-07-24 21:03:07 +000050
Rafael Espindola1bd885a2015-08-14 16:46:28 +000051 bool isStrongUndefined() {
52 return SymbolKind == UndefinedKind || SymbolKind == UndefinedSyntheticKind;
53 }
54
Michael J. Spencer84487f12015-07-24 21:03:07 +000055 // Returns the symbol name.
Michael J. Spencercdae0a42015-07-28 22:58:25 +000056 StringRef getName() const { return Name; }
Michael J. Spencer84487f12015-07-24 21:03:07 +000057
58 // A SymbolBody has a backreference to a Symbol. Originally they are
59 // doubly-linked. A backreference will never change. But the pointer
60 // in the Symbol may be mutated by the resolver. If you have a
61 // pointer P to a SymbolBody and are not sure whether the resolver
62 // has chosen the object among other objects having the same name,
63 // you can access P->Backref->Body to get the resolver's result.
64 void setBackref(Symbol *P) { Backref = P; }
Michael J. Spencer84487f12015-07-24 21:03:07 +000065
66 // Decides which symbol should "win" in the symbol table, this or
67 // the Other. Returns 1 if this wins, -1 if the Other wins, or 0 if
68 // they are duplicate (conflicting) symbols.
Rui Ueyamaa7ccb292015-07-27 20:39:01 +000069 int compare(SymbolBody *Other);
Michael J. Spencer84487f12015-07-24 21:03:07 +000070
71protected:
Rafael Espindola3bf356e2015-08-14 14:38:44 +000072 SymbolBody(Kind K, StringRef Name) : SymbolKind(K), Name(Name) {}
Michael J. Spencer84487f12015-07-24 21:03:07 +000073
Michael J. Spencercdae0a42015-07-28 22:58:25 +000074protected:
75 const unsigned SymbolKind : 8;
Michael J. Spencercdae0a42015-07-28 22:58:25 +000076 StringRef Name;
Michael J. Spencer84487f12015-07-24 21:03:07 +000077 Symbol *Backref = nullptr;
78};
79
Rafael Espindola1bd885a2015-08-14 16:46:28 +000080// This is for symbols created from elf files and not from the command line.
81// Since they come from object files, they have a Elf_Sym.
82//
83// FIXME: Another alternative is to give every symbol an Elf_Sym. To do that
84// we have to delay creating the symbol table until the output format is
85// known and some of its methods will be templated. We should experiment with
86// that once we have a bit more code.
87template <class ELFT> class ELFSymbolBody : public SymbolBody {
88protected:
Rafael Espindolac44d17a2015-08-14 15:10:49 +000089 typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
Rafael Espindola1bd885a2015-08-14 16:46:28 +000090 ELFSymbolBody(Kind K, StringRef Name, const Elf_Sym &Sym)
91 : SymbolBody(K, Name), Sym(Sym) {}
Rafael Espindolac44d17a2015-08-14 15:10:49 +000092
Rafael Espindola1bd885a2015-08-14 16:46:28 +000093public:
94 const Elf_Sym &Sym;
Michael J. Spencer84487f12015-07-24 21:03:07 +000095
96 static bool classof(const SymbolBody *S) {
97 Kind K = S->kind();
Rafael Espindola1bd885a2015-08-14 16:46:28 +000098 return K >= DefinedFirst && K <= UndefinedKind;
99 }
100};
101
102// The base class for any defined symbols, including absolute symbols,
103// etc.
104template <class ELFT> class Defined : public ELFSymbolBody<ELFT> {
105 typedef ELFSymbolBody<ELFT> Base;
106 typedef typename Base::Kind Kind;
107
108public:
109 typedef typename Base::Elf_Sym Elf_Sym;
110
Rafael Espindola832b93f2015-08-24 20:06:32 +0000111 explicit Defined(Kind K, StringRef N, const Elf_Sym &Sym,
112 SectionChunk<ELFT> &Section)
113 : ELFSymbolBody<ELFT>(K, N, Sym), Section(Section) {}
Rafael Espindola1bd885a2015-08-14 16:46:28 +0000114
115 static bool classof(const SymbolBody *S) {
116 Kind K = S->kind();
117 return Base::DefinedFirst <= K && K <= Base::DefinedLast;
Michael J. Spencer84487f12015-07-24 21:03:07 +0000118 }
Rafael Espindola832b93f2015-08-24 20:06:32 +0000119
120 const SectionChunk<ELFT> &Section;
Michael J. Spencer84487f12015-07-24 21:03:07 +0000121};
122
123// Regular defined symbols read from object file symbol tables.
Rafael Espindolac44d17a2015-08-14 15:10:49 +0000124template <class ELFT> class DefinedRegular : public Defined<ELFT> {
125 typedef Defined<ELFT> Base;
126 typedef typename Base::Elf_Sym Elf_Sym;
127
Michael J. Spencer84487f12015-07-24 21:03:07 +0000128public:
Rafael Espindola832b93f2015-08-24 20:06:32 +0000129 explicit DefinedRegular(StringRef N, const Elf_Sym &Sym,
130 SectionChunk<ELFT> &Section)
131 : Defined<ELFT>(Base::DefinedRegularKind, N, Sym, Section) {}
Michael J. Spencer84487f12015-07-24 21:03:07 +0000132
133 static bool classof(const SymbolBody *S) {
Rafael Espindolac44d17a2015-08-14 15:10:49 +0000134 return S->kind() == Base::DefinedRegularKind;
Michael J. Spencer84487f12015-07-24 21:03:07 +0000135 }
Michael J. Spencer84487f12015-07-24 21:03:07 +0000136};
137
Rafael Espindolac44d17a2015-08-14 15:10:49 +0000138template <class ELFT> class DefinedWeak : public Defined<ELFT> {
139 typedef Defined<ELFT> Base;
140 typedef typename Base::Elf_Sym Elf_Sym;
141
Rafael Espindolab13df652015-08-11 17:33:02 +0000142public:
Rafael Espindola832b93f2015-08-24 20:06:32 +0000143 explicit DefinedWeak(StringRef N, const Elf_Sym &Sym,
144 SectionChunk<ELFT> &Section)
145 : Defined<ELFT>(Base::DefinedWeakKind, N, Sym, Section) {}
Rafael Espindolab13df652015-08-11 17:33:02 +0000146
147 static bool classof(const SymbolBody *S) {
Rafael Espindolac44d17a2015-08-14 15:10:49 +0000148 return S->kind() == Base::DefinedWeakKind;
Rafael Espindolab13df652015-08-11 17:33:02 +0000149 }
150};
151
Michael J. Spencer84487f12015-07-24 21:03:07 +0000152// Undefined symbols.
Rafael Espindola1bd885a2015-08-14 16:46:28 +0000153class SyntheticUndefined : public SymbolBody {
Michael J. Spencer84487f12015-07-24 21:03:07 +0000154public:
Rafael Espindola1bd885a2015-08-14 16:46:28 +0000155 explicit SyntheticUndefined(StringRef N) : SymbolBody(UndefinedKind, N) {}
Michael J. Spencer84487f12015-07-24 21:03:07 +0000156
157 static bool classof(const SymbolBody *S) {
158 return S->kind() == UndefinedKind;
159 }
Michael J. Spencer84487f12015-07-24 21:03:07 +0000160};
161
Rafael Espindola1bd885a2015-08-14 16:46:28 +0000162template <class ELFT> class Undefined : public ELFSymbolBody<ELFT> {
163 typedef ELFSymbolBody<ELFT> Base;
164 typedef typename Base::Elf_Sym Elf_Sym;
165
Rafael Espindola76e24ea2015-08-11 17:57:05 +0000166public:
Rafael Espindola1bd885a2015-08-14 16:46:28 +0000167 explicit Undefined(StringRef N, const Elf_Sym &Sym)
168 : ELFSymbolBody<ELFT>(Base::UndefinedKind, N, Sym) {}
Rafael Espindola76e24ea2015-08-11 17:57:05 +0000169
170 static bool classof(const SymbolBody *S) {
Rafael Espindola1bd885a2015-08-14 16:46:28 +0000171 return S->kind() == Base::UndefinedKind;
172 }
173};
174
175template <class ELFT> class UndefinedWeak : public ELFSymbolBody<ELFT> {
176 typedef ELFSymbolBody<ELFT> Base;
177 typedef typename Base::Elf_Sym Elf_Sym;
178
179public:
180 explicit UndefinedWeak(StringRef N, const Elf_Sym &Sym)
181 : ELFSymbolBody<ELFT>(Base::UndefinedWeakKind, N, Sym) {}
182
183 static bool classof(const SymbolBody *S) {
184 return S->kind() == Base::UndefinedWeakKind;
Rafael Espindola76e24ea2015-08-11 17:57:05 +0000185 }
186};
187
Michael J. Spencer84487f12015-07-24 21:03:07 +0000188} // namespace elf2
189} // namespace lld
190
191#endif