More symbol resolution code.
[external/binutils.git] / gold / symtab.h
1 // symtab.h -- the gold symbol table   -*- C++ -*-
2
3 // Symbol_table
4 //   The symbol table.
5
6 #include <string>
7 #include <utility>
8
9 #include "elfcpp.h"
10 #include "targetsize.h"
11 #include "stringpool.h"
12
13 #ifndef GOLD_SYMTAB_H
14 #define GOLD_SYMTAB_H
15
16 namespace gold
17 {
18
19 class Object;
20
21 template<int size, bool big_endian>
22 class Sized_object;
23
24 template<int size, bool big_endian>
25 class Sized_target;
26
27 // The base class of an entry in the symbol table.  The symbol table
28 // can have a lot of entries, so we don't want this class to big.
29 // Size dependent fields can be found in the template class
30 // Sized_symbol.  Targets may support their own derived classes.
31
32 class Symbol
33 {
34  public:
35   // Return the symbol name.
36   const char*
37   name() const
38   { return this->name_; }
39
40   // Return the symbol version.  This will return NULL for an
41   // unversioned symbol.
42   const char*
43   version() const
44   { return this->version_; }
45
46   // Return the object with which this symbol is associated.
47   Object*
48   object() const
49   { return this->object_; }
50
51   // Return the symbol binding.
52   elfcpp::STB
53   binding() const
54   { return this->binding_; }
55
56   // Return the symbol type.
57   elfcpp::STT
58   type() const
59   { return this->type_; }
60
61   // Return the symbol visibility.
62   elfcpp::STV
63   visibility() const
64   { return this->visibility_; }
65
66   // Return the non-visibility part of the st_other field.
67   unsigned char
68   other() const
69   { return this->other_; }
70
71   // Return the section index.
72   unsigned int
73   shnum() const
74   { return this->shnum_; }
75
76   // Return whether this symbol is a forwarder.  This will never be
77   // true of a symbol found in the hash table, but may be true of
78   // symbol pointers attached to object files.
79   bool
80   is_forwarder() const
81   { return this->is_forwarder_; }
82
83   // Mark this symbol as a forwarder.
84   void
85   set_forwarder()
86   { this->is_forwarder_ = true; }
87
88   // Return whether this symbol was seen in a dynamic object.
89   bool
90   in_dyn() const
91   { return this->in_dyn_; }
92
93   // Mark this symbol as seen in a dynamic object.
94   void
95   set_in_dyn()
96   { this->in_dyn_ = true; }
97
98  protected:
99   // Instances of this class should always be created at a specific
100   // size.
101   Symbol()
102   { }
103
104   // Initialize fields from an ELF symbol in OBJECT.
105   template<int size, bool big_endian>
106   void
107   init_base(const char *name, const char* version, Object* object,
108             const elfcpp::Sym<size, big_endian>&);
109
110   // Override existing symbol.
111   template<int size, bool big_endian>
112   void
113   override_base(const elfcpp::Sym<size, big_endian>&, Object* object);
114
115  private:
116   Symbol(const Symbol&);
117   Symbol& operator=(const Symbol&);
118
119   // Symbol name (expected to point into a Stringpool).
120   const char* name_;
121   // Symbol version (expected to point into a Stringpool).  This may
122   // be NULL.
123   const char* version_;
124   // Object in which symbol is defined, or in which it was first seen.
125   Object* object_;
126   // Section number in object_ in which symbol is defined.
127   unsigned int shnum_;
128   // Symbol type.
129   elfcpp::STT type_ : 4;
130   // Symbol binding.
131   elfcpp::STB binding_ : 4;
132   // Symbol visibility.
133   elfcpp::STV visibility_ : 2;
134   // Rest of symbol st_other field.
135   unsigned int other_ : 6;
136   // True if this symbol always requires special target-specific
137   // handling.
138   bool is_special_ : 1;
139   // True if this is the default version of the symbol.
140   bool is_def_ : 1;
141   // True if this symbol really forwards to another symbol.  This is
142   // used when we discover after the fact that two different entries
143   // in the hash table really refer to the same symbol.  This will
144   // never be set for a symbol found in the hash table, but may be set
145   // for a symbol found in the list of symbols attached to an Object.
146   // It forwards to the symbol found in the forwarders_ map of
147   // Symbol_table.
148   bool is_forwarder_ : 1;
149   // True if we've seen this symbol in a dynamic object.
150   bool in_dyn_ : 1;
151 };
152
153 // The parts of a symbol which are size specific.  Using a template
154 // derived class like this helps us use less space on a 32-bit system.
155
156 template<int size>
157 class Sized_symbol : public Symbol
158 {
159  public:
160   typedef typename elfcpp::Elf_types<size>::Elf_Addr Value_type;
161   typedef typename elfcpp::Elf_types<size>::Elf_WXword Size_type;
162
163   Sized_symbol()
164   { }
165
166   // Initialize fields from an ELF symbol in OBJECT.
167   template<bool big_endian>
168   void
169   init(const char *name, const char* version, Object* object,
170        const elfcpp::Sym<size, big_endian>&);
171
172   // Override existing symbol.
173   template<bool big_endian>
174   void
175   override(const elfcpp::Sym<size, big_endian>&, Object* object);
176
177   // Return the symbol's value.
178   Value_type
179   value() const
180   { return this->value_; }
181
182   // Return the symbol's size (we can't call this 'size' because that
183   // is a template parameter).
184   Size_type
185   symsize() const
186   { return this->size_; }
187
188  private:
189   Sized_symbol(const Sized_symbol&);
190   Sized_symbol& operator=(const Sized_symbol&);
191
192   // Symbol value.
193   Value_type value_;
194   // Symbol size.
195   Size_type size_;
196 };
197
198 // The main linker symbol table.
199
200 class Symbol_table
201 {
202  public:
203   Symbol_table();
204
205   ~Symbol_table();
206
207   // Add COUNT external symbols from OBJECT to the symbol table.  SYMS
208   // is the symbols, SYM_NAMES is their names, SYM_NAME_SIZE is the
209   // size of SYM_NAMES.  This sets SYMPOINTERS to point to the symbols
210   // in the symbol table.
211   template<int size, bool big_endian>
212   void
213   add_from_object(Sized_object<size, big_endian>* object,
214                   const elfcpp::Sym<size, big_endian>* syms,
215                   size_t count, const char* sym_names, size_t sym_name_size,
216                   Symbol** sympointers);
217
218   // Return the real symbol associated with the forwarder symbol FROM.
219   Symbol*
220   resolve_forwards(Symbol* from) const;
221
222   // Return the size of the symbols in the table.
223   int
224   get_size() const
225   { return this->size_; }
226
227   // Return the sized version of a symbol in this table.
228   template<int size>
229   Sized_symbol<size>*
230   get_sized_symbol(Symbol*);
231
232   template<int size>
233   const Sized_symbol<size>*
234   get_sized_symbol(const Symbol*);
235
236  private:
237   Symbol_table(const Symbol_table&);
238   Symbol_table& operator=(const Symbol_table&);
239
240   // Set the size of the symbols in the table.
241   void
242   set_size(int size)
243   { this->size_ = size; }
244
245   // Make FROM a forwarder symbol to TO.
246   void
247   make_forwarder(Symbol* from, Symbol* to);
248
249   // Add a symbol.
250   template<int size, bool big_endian>
251   Symbol*
252   add_from_object(Sized_object<size, big_endian>*, const char *name,
253                   const char *version, bool def,
254                   const elfcpp::Sym<size, big_endian>& sym);
255
256   // Resolve symbols.
257   template<int size, bool big_endian>
258   static void
259   resolve(Sized_symbol<size>* to,
260           const elfcpp::Sym<size, big_endian>& sym,
261           Object*);
262
263   template<int size, bool big_endian>
264   static void
265   resolve(Sized_symbol<size>* to, const Sized_symbol<size>* from);
266
267   typedef std::pair<const char*, const char*> Symbol_table_key;
268
269   struct Symbol_table_hash
270   {
271     size_t
272     operator()(const Symbol_table_key&) const;
273   };
274
275   struct Symbol_table_eq
276   {
277     bool
278     operator()(const Symbol_table_key&, const Symbol_table_key&) const;
279   };
280
281   typedef Unordered_map<Symbol_table_key, Symbol*, Symbol_table_hash,
282                         Symbol_table_eq> Symbol_table_type;
283
284   // The size of the symbols in the symbol table (32 or 64).
285   int size_;
286
287   // The symbol table itself.
288   Symbol_table_type table_;
289
290   // A pool of symbol names.
291   Stringpool namepool_;
292
293   // Forwarding symbols.
294   Unordered_map<Symbol*, Symbol*> forwarders_;
295 };
296
297 // We inline get_sized_symbol for efficiency.
298
299 template<int size>
300 Sized_symbol<size>*
301 Symbol_table::get_sized_symbol(Symbol* sym)
302 {
303   assert(size == this->get_size());
304   return static_cast<Sized_symbol<size>*>(sym);
305 }
306
307 template<int size>
308 const Sized_symbol<size>*
309 Symbol_table::get_sized_symbol(const Symbol* sym)
310 {
311   assert(size == this->get_size());
312   return static_cast<const Sized_symbol<size>*>(sym);
313 }
314
315 } // End namespace gold.
316
317 #endif // !defined(GOLD_SYMTAB_H)