More symbol resolution code.
[binutils.git] / gold / symtab.h
bloba90ba5db8abfebc81fba5a8fe7fcf87b33765fb8
1 // symtab.h -- the gold symbol table -*- C++ -*-
3 // Symbol_table
4 // The symbol table.
6 #include <string>
7 #include <utility>
9 #include "elfcpp.h"
10 #include "targetsize.h"
11 #include "stringpool.h"
13 #ifndef GOLD_SYMTAB_H
14 #define GOLD_SYMTAB_H
16 namespace gold
19 class Object;
21 template<int size, bool big_endian>
22 class Sized_object;
24 template<int size, bool big_endian>
25 class Sized_target;
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.
32 class Symbol
34 public:
35 // Return the symbol name.
36 const char*
37 name() const
38 { return this->name_; }
40 // Return the symbol version. This will return NULL for an
41 // unversioned symbol.
42 const char*
43 version() const
44 { return this->version_; }
46 // Return the object with which this symbol is associated.
47 Object*
48 object() const
49 { return this->object_; }
51 // Return the symbol binding.
52 elfcpp::STB
53 binding() const
54 { return this->binding_; }
56 // Return the symbol type.
57 elfcpp::STT
58 type() const
59 { return this->type_; }
61 // Return the symbol visibility.
62 elfcpp::STV
63 visibility() const
64 { return this->visibility_; }
66 // Return the non-visibility part of the st_other field.
67 unsigned char
68 other() const
69 { return this->other_; }
71 // Return the section index.
72 unsigned int
73 shnum() const
74 { return this->shnum_; }
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_; }
83 // Mark this symbol as a forwarder.
84 void
85 set_forwarder()
86 { this->is_forwarder_ = true; }
88 // Return whether this symbol was seen in a dynamic object.
89 bool
90 in_dyn() const
91 { return this->in_dyn_; }
93 // Mark this symbol as seen in a dynamic object.
94 void
95 set_in_dyn()
96 { this->in_dyn_ = true; }
98 protected:
99 // Instances of this class should always be created at a specific
100 // size.
101 Symbol()
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>&);
110 // Override existing symbol.
111 template<int size, bool big_endian>
112 void
113 override_base(const elfcpp::Sym<size, big_endian>&, Object* object);
115 private:
116 Symbol(const Symbol&);
117 Symbol& operator=(const Symbol&);
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;
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.
156 template<int size>
157 class Sized_symbol : public Symbol
159 public:
160 typedef typename elfcpp::Elf_types<size>::Elf_Addr Value_type;
161 typedef typename elfcpp::Elf_types<size>::Elf_WXword Size_type;
163 Sized_symbol()
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>&);
172 // Override existing symbol.
173 template<bool big_endian>
174 void
175 override(const elfcpp::Sym<size, big_endian>&, Object* object);
177 // Return the symbol's value.
178 Value_type
179 value() const
180 { return this->value_; }
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_; }
188 private:
189 Sized_symbol(const Sized_symbol&);
190 Sized_symbol& operator=(const Sized_symbol&);
192 // Symbol value.
193 Value_type value_;
194 // Symbol size.
195 Size_type size_;
198 // The main linker symbol table.
200 class Symbol_table
202 public:
203 Symbol_table();
205 ~Symbol_table();
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);
218 // Return the real symbol associated with the forwarder symbol FROM.
219 Symbol*
220 resolve_forwards(Symbol* from) const;
222 // Return the size of the symbols in the table.
224 get_size() const
225 { return this->size_; }
227 // Return the sized version of a symbol in this table.
228 template<int size>
229 Sized_symbol<size>*
230 get_sized_symbol(Symbol*);
232 template<int size>
233 const Sized_symbol<size>*
234 get_sized_symbol(const Symbol*);
236 private:
237 Symbol_table(const Symbol_table&);
238 Symbol_table& operator=(const Symbol_table&);
240 // Set the size of the symbols in the table.
241 void
242 set_size(int size)
243 { this->size_ = size; }
245 // Make FROM a forwarder symbol to TO.
246 void
247 make_forwarder(Symbol* from, Symbol* to);
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);
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*);
263 template<int size, bool big_endian>
264 static void
265 resolve(Sized_symbol<size>* to, const Sized_symbol<size>* from);
267 typedef std::pair<const char*, const char*> Symbol_table_key;
269 struct Symbol_table_hash
271 size_t
272 operator()(const Symbol_table_key&) const;
275 struct Symbol_table_eq
277 bool
278 operator()(const Symbol_table_key&, const Symbol_table_key&) const;
281 typedef Unordered_map<Symbol_table_key, Symbol*, Symbol_table_hash,
282 Symbol_table_eq> Symbol_table_type;
284 // The size of the symbols in the symbol table (32 or 64).
285 int size_;
287 // The symbol table itself.
288 Symbol_table_type table_;
290 // A pool of symbol names.
291 Stringpool namepool_;
293 // Forwarding symbols.
294 Unordered_map<Symbol*, Symbol*> forwarders_;
297 // We inline get_sized_symbol for efficiency.
299 template<int size>
300 Sized_symbol<size>*
301 Symbol_table::get_sized_symbol(Symbol* sym)
303 assert(size == this->get_size());
304 return static_cast<Sized_symbol<size>*>(sym);
307 template<int size>
308 const Sized_symbol<size>*
309 Symbol_table::get_sized_symbol(const Symbol* sym)
311 assert(size == this->get_size());
312 return static_cast<const Sized_symbol<size>*>(sym);
315 } // End namespace gold.
317 #endif // !defined(GOLD_SYMTAB_H)