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