New drop, with first cut of section layout 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 "stringpool.h"
11
12 #ifndef GOLD_SYMTAB_H
13 #define GOLD_SYMTAB_H
14
15 namespace gold
16 {
17
18 class Object;
19
20 template<int size, bool big_endian>
21 class Sized_object;
22
23 template<int size, bool big_endian>
24 class Sized_target;
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  private:
188   Sized_symbol(const Sized_symbol&);
189   Sized_symbol& operator=(const Sized_symbol&);
190
191   // Symbol value.
192   Value_type value_;
193   // Symbol size.
194   Size_type size_;
195 };
196
197 // The main linker symbol table.
198
199 class Symbol_table
200 {
201  public:
202   Symbol_table();
203
204   ~Symbol_table();
205
206   // Add COUNT external symbols from OBJECT to the symbol table.  SYMS
207   // is the symbols, SYM_NAMES is their names, SYM_NAME_SIZE is the
208   // size of SYM_NAMES.  This sets SYMPOINTERS to point to the symbols
209   // in the symbol table.
210   template<int size, bool big_endian>
211   void
212   add_from_object(Sized_object<size, big_endian>* object,
213                   const elfcpp::Sym<size, big_endian>* syms,
214                   size_t count, const char* sym_names, size_t sym_name_size,
215                   Symbol** sympointers);
216
217   // Return the real symbol associated with the forwarder symbol FROM.
218   Symbol*
219   resolve_forwards(Symbol* from) const;
220
221   // Return the size of the symbols in the table.
222   int
223   get_size() const
224   { return this->size_; }
225
226   // Return the sized version of a symbol in this table.
227   template<int size>
228   Sized_symbol<size>*
229   get_sized_symbol(Symbol*);
230
231   template<int size>
232   const Sized_symbol<size>*
233   get_sized_symbol(const Symbol*);
234
235  private:
236   Symbol_table(const Symbol_table&);
237   Symbol_table& operator=(const Symbol_table&);
238
239   // Set the size of the symbols in the table.
240   void
241   set_size(int size)
242   { this->size_ = size; }
243
244   // Make FROM a forwarder symbol to TO.
245   void
246   make_forwarder(Symbol* from, Symbol* to);
247
248   // Add a symbol.
249   template<int size, bool big_endian>
250   Symbol*
251   add_from_object(Sized_object<size, big_endian>*, const char *name,
252                   const char *version, bool def,
253                   const elfcpp::Sym<size, big_endian>& sym);
254
255   // Resolve symbols.
256   template<int size, bool big_endian>
257   static void
258   resolve(Sized_symbol<size>* to,
259           const elfcpp::Sym<size, big_endian>& sym,
260           Object*);
261
262   template<int size, bool big_endian>
263   static void
264   resolve(Sized_symbol<size>* to, const Sized_symbol<size>* from);
265
266   typedef std::pair<const char*, const char*> Symbol_table_key;
267
268   struct Symbol_table_hash
269   {
270     size_t
271     operator()(const Symbol_table_key&) const;
272   };
273
274   struct Symbol_table_eq
275   {
276     bool
277     operator()(const Symbol_table_key&, const Symbol_table_key&) const;
278   };
279
280   typedef Unordered_map<Symbol_table_key, Symbol*, Symbol_table_hash,
281                         Symbol_table_eq> Symbol_table_type;
282
283   // The size of the symbols in the symbol table (32 or 64).
284   int size_;
285
286   // The symbol table itself.
287   Symbol_table_type table_;
288
289   // A pool of symbol names.
290   Stringpool namepool_;
291
292   // Forwarding symbols.
293   Unordered_map<Symbol*, Symbol*> forwarders_;
294 };
295
296 // We inline get_sized_symbol for efficiency.
297
298 template<int size>
299 Sized_symbol<size>*
300 Symbol_table::get_sized_symbol(Symbol* sym)
301 {
302   assert(size == this->get_size());
303   return static_cast<Sized_symbol<size>*>(sym);
304 }
305
306 template<int size>
307 const Sized_symbol<size>*
308 Symbol_table::get_sized_symbol(const Symbol* sym)
309 {
310   assert(size == this->get_size());
311   return static_cast<const Sized_symbol<size>*>(sym);
312 }
313
314 } // End namespace gold.
315
316 #endif // !defined(GOLD_SYMTAB_H)