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