gcc 4.1.0 portability fixes.
[deliverable/binutils-gdb.git] / gold / symtab.cc
1 // symtab.cc -- the gold symbol table
2
3 #include "gold.h"
4
5 #include <cassert>
6 #include <stdint.h>
7 #include <string>
8 #include <utility>
9
10 #include "object.h"
11 #include "symtab.h"
12
13 namespace gold
14 {
15
16 // Class Symbol.
17
18 // Initialize the fields in the base class Symbol.
19
20 template<int size, bool big_endian>
21 void
22 Symbol::init_base(const char* name, const char* version, Object* object,
23 const elfcpp::Sym<size, big_endian>& sym)
24 {
25 this->name_ = name;
26 this->version_ = version;
27 this->object_ = object;
28 this->shnum_ = sym.get_st_shndx(); // FIXME: Handle SHN_XINDEX.
29 this->type_ = sym.get_st_type();
30 this->binding_ = sym.get_st_bind();
31 this->visibility_ = sym.get_st_visibility();
32 this->other_ = sym.get_st_nonvis();
33 this->is_special_ = false;
34 this->is_def_ = false;
35 this->is_forwarder_ = false;
36 this->in_dyn_ = object->is_dynamic();
37 }
38
39 // Initialize the fields in Sized_symbol.
40
41 template<int size>
42 template<bool big_endian>
43 void
44 Sized_symbol<size>::init(const char* name, const char* version, Object* object,
45 const elfcpp::Sym<size, big_endian>& sym)
46 {
47 this->init_base(name, version, object, sym);
48 this->value_ = sym.get_st_value();
49 this->size_ = sym.get_st_size();
50 }
51
52 // Class Symbol_table.
53
54 Symbol_table::Symbol_table()
55 : size_(0), table_(), namepool_(), output_pool_(), forwarders_()
56 {
57 }
58
59 Symbol_table::~Symbol_table()
60 {
61 }
62
63 // The hash function. The key is always canonicalized, so we use a
64 // simple combination of the pointers.
65
66 size_t
67 Symbol_table::Symbol_table_hash::operator()(const Symbol_table_key& key) const
68 {
69 return (reinterpret_cast<size_t>(key.first)
70 ^ reinterpret_cast<size_t>(key.second));
71 }
72
73 // The symbol table key equality function. This is only called with
74 // canonicalized name and version strings, so we can use pointer
75 // comparison.
76
77 bool
78 Symbol_table::Symbol_table_eq::operator()(const Symbol_table_key& k1,
79 const Symbol_table_key& k2) const
80 {
81 return k1.first == k2.first && k1.second == k2.second;
82 }
83
84 // Make TO a symbol which forwards to FROM.
85
86 void
87 Symbol_table::make_forwarder(Symbol* from, Symbol* to)
88 {
89 assert(!from->is_forwarder() && !to->is_forwarder());
90 this->forwarders_[from] = to;
91 from->set_forwarder();
92 }
93
94 Symbol*
95 Symbol_table::resolve_forwards(Symbol* from) const
96 {
97 assert(from->is_forwarder());
98 Unordered_map<Symbol*, Symbol*>::const_iterator p =
99 this->forwarders_.find(from);
100 assert(p != this->forwarders_.end());
101 return p->second;
102 }
103
104 // Resolve a Symbol with another Symbol. This is only used in the
105 // unusual case where there are references to both an unversioned
106 // symbol and a symbol with a version, and we then discover that that
107 // version is the default version. Because this is unusual, we do
108 // this the slow way, by converting back to an ELF symbol.
109
110 #ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS
111
112 template<int size, bool big_endian>
113 void
114 Symbol_table::resolve(Sized_symbol<size>* to, const Sized_symbol<size>* from)
115 {
116 unsigned char buf[elfcpp::Elf_sizes<size>::sym_size];
117 elfcpp::Sym_write<size, big_endian> esym(buf);
118 // We don't bother to set the st_name field.
119 esym.put_st_value(from->value());
120 esym.put_st_size(from->symsize());
121 esym.put_st_info(from->binding(), from->type());
122 esym.put_st_other(from->visibility(), from->other());
123 esym.put_st_shndx(from->shnum());
124 Symbol_table::resolve(to, esym.sym(), from->object());
125 }
126
127 #else
128
129 template<int size>
130 void
131 Symbol_table::resolve(Sized_symbol<size>* to, const Sized_symbol<size>* from,
132 bool big_endian)
133 {
134 unsigned char buf[elfcpp::Elf_sizes<size>::sym_size];
135 if (big_endian)
136 {
137 elfcpp::Sym_write<size, true> esym(buf);
138 // We don't bother to set the st_name field.
139 esym.put_st_value(from->value());
140 esym.put_st_size(from->symsize());
141 esym.put_st_info(from->binding(), from->type());
142 esym.put_st_other(from->visibility(), from->other());
143 esym.put_st_shndx(from->shnum());
144 Symbol_table::resolve(to, esym.sym(), from->object());
145 }
146 else
147 {
148 elfcpp::Sym_write<size, false> esym(buf);
149 // We don't bother to set the st_name field.
150 esym.put_st_value(from->value());
151 esym.put_st_size(from->symsize());
152 esym.put_st_info(from->binding(), from->type());
153 esym.put_st_other(from->visibility(), from->other());
154 esym.put_st_shndx(from->shnum());
155 Symbol_table::resolve(to, esym.sym(), from->object());
156 }
157 }
158
159 #endif
160
161 // Add one symbol from OBJECT to the symbol table. NAME is symbol
162 // name and VERSION is the version; both are canonicalized. DEF is
163 // whether this is the default version.
164
165 // If DEF is true, then this is the definition of a default version of
166 // a symbol. That means that any lookup of NAME/NULL and any lookup
167 // of NAME/VERSION should always return the same symbol. This is
168 // obvious for references, but in particular we want to do this for
169 // definitions: overriding NAME/NULL should also override
170 // NAME/VERSION. If we don't do that, it would be very hard to
171 // override functions in a shared library which uses versioning.
172
173 // We implement this by simply making both entries in the hash table
174 // point to the same Symbol structure. That is easy enough if this is
175 // the first time we see NAME/NULL or NAME/VERSION, but it is possible
176 // that we have seen both already, in which case they will both have
177 // independent entries in the symbol table. We can't simply change
178 // the symbol table entry, because we have pointers to the entries
179 // attached to the object files. So we mark the entry attached to the
180 // object file as a forwarder, and record it in the forwarders_ map.
181 // Note that entries in the hash table will never be marked as
182 // forwarders.
183
184 template<int size, bool big_endian>
185 Symbol*
186 Symbol_table::add_from_object(Sized_object<size, big_endian>* object,
187 const char *name,
188 const char *version, bool def,
189 const elfcpp::Sym<size, big_endian>& sym)
190 {
191 Symbol* const snull = NULL;
192 std::pair<typename Symbol_table_type::iterator, bool> ins =
193 this->table_.insert(std::make_pair(std::make_pair(name, version), snull));
194
195 std::pair<typename Symbol_table_type::iterator, bool> insdef =
196 std::make_pair(this->table_.end(), false);
197 if (def)
198 {
199 const char* const vnull = NULL;
200 insdef = this->table_.insert(std::make_pair(std::make_pair(name, vnull),
201 snull));
202 }
203
204 // ins.first: an iterator, which is a pointer to a pair.
205 // ins.first->first: the key (a pair of name and version).
206 // ins.first->second: the value (Symbol*).
207 // ins.second: true if new entry was inserted, false if not.
208
209 Sized_symbol<size>* ret;
210 if (!ins.second)
211 {
212 // We already have an entry for NAME/VERSION.
213 #ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS
214 ret = this->get_sized_symbol<size>(ins.first->second);
215 #else
216 assert(size == this->get_size());
217 ret = static_cast<Sized_symbol<size>*>(ins.first->second);
218 #endif
219 assert(ret != NULL);
220 Symbol_table::resolve(ret, sym, object);
221
222 if (def)
223 {
224 if (insdef.second)
225 {
226 // This is the first time we have seen NAME/NULL. Make
227 // NAME/NULL point to NAME/VERSION.
228 insdef.first->second = ret;
229 }
230 else
231 {
232 // This is the unfortunate case where we already have
233 // entries for both NAME/VERSION and NAME/NULL.
234 const Sized_symbol<size>* sym2;
235 #ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS
236 sym2 = this->get_sized_symbol<size>(insdef.first->second);
237 Symbol_table::resolve<size, big_endian>(ret, sym2);
238 #else
239 sym2 = static_cast<Sized_symbol<size>*>(insdef.first->second);
240 Symbol_table::resolve(ret, sym2, big_endian);
241 #endif
242 this->make_forwarder(insdef.first->second, ret);
243 insdef.first->second = ret;
244 }
245 }
246 }
247 else
248 {
249 // This is the first time we have seen NAME/VERSION.
250 assert(ins.first->second == NULL);
251 if (def && !insdef.second)
252 {
253 // We already have an entry for NAME/NULL. Make
254 // NAME/VERSION point to it.
255 #ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS
256 ret = this->get_sized_symbol<size>(insdef.first->second);
257 #else
258 ret = static_cast<Sized_symbol<size>*>(insdef.first->second);
259 #endif
260 Symbol_table::resolve(ret, sym, object);
261 ins.first->second = ret;
262 }
263 else
264 {
265 Sized_target<size, big_endian>* target = object->sized_target();
266 if (!target->has_make_symbol())
267 ret = new Sized_symbol<size>();
268 else
269 {
270 ret = target->make_symbol();
271 if (ret == NULL)
272 {
273 // This means that we don't want a symbol table
274 // entry after all.
275 if (!def)
276 this->table_.erase(ins.first);
277 else
278 {
279 this->table_.erase(insdef.first);
280 // Inserting insdef invalidated ins.
281 this->table_.erase(std::make_pair(name, version));
282 }
283 return NULL;
284 }
285 }
286
287 ret->init(name, version, object, sym);
288
289 ins.first->second = ret;
290 if (def)
291 {
292 // This is the first time we have seen NAME/NULL. Point
293 // it at the new entry for NAME/VERSION.
294 assert(insdef.second);
295 insdef.first->second = ret;
296 }
297 }
298 }
299
300 return ret;
301 }
302
303 // Add all the symbols in an object to the hash table.
304
305 template<int size, bool big_endian>
306 void
307 Symbol_table::add_from_object(
308 Sized_object<size, big_endian>* object,
309 const elfcpp::Sym<size, big_endian>* syms,
310 size_t count,
311 const char* sym_names,
312 size_t sym_name_size,
313 Symbol** sympointers)
314 {
315 // We take the size from the first object we see.
316 if (this->get_size() == 0)
317 this->set_size(size);
318
319 if (size != this->get_size() || size != object->target()->get_size())
320 {
321 fprintf(stderr, _("%s: %s: mixing 32-bit and 64-bit ELF objects\n"),
322 program_name, object->name().c_str());
323 gold_exit(false);
324 }
325
326 const unsigned char* p = reinterpret_cast<const unsigned char*>(syms);
327 for (size_t i = 0; i < count; ++i)
328 {
329 elfcpp::Sym<size, big_endian> sym(p);
330
331 unsigned int st_name = sym.get_st_name();
332 if (st_name >= sym_name_size)
333 {
334 fprintf(stderr,
335 _("%s: %s: bad global symbol name offset %u at %lu\n"),
336 program_name, object->name().c_str(), st_name,
337 static_cast<unsigned long>(i));
338 gold_exit(false);
339 }
340
341 const char* name = sym_names + st_name;
342
343 // In an object file, an '@' in the name separates the symbol
344 // name from the version name. If there are two '@' characters,
345 // this is the default version.
346 const char* ver = strchr(name, '@');
347
348 Symbol* res;
349 if (ver == NULL)
350 {
351 name = this->namepool_.add(name);
352 res = this->add_from_object(object, name, NULL, false, sym);
353 }
354 else
355 {
356 name = this->namepool_.add(name, ver - name);
357 bool def = false;
358 ++ver;
359 if (*ver == '@')
360 {
361 def = true;
362 ++ver;
363 }
364 ver = this->namepool_.add(ver);
365 res = this->add_from_object(object, name, ver, def, sym);
366 }
367
368 *sympointers++ = res;
369
370 p += elfcpp::Elf_sizes<size>::sym_size;
371 }
372 }
373
374 // Record the names of the local symbols for an object.
375
376 template<int size, bool big_endian>
377 void
378 Symbol_table::add_local_symbol_names(Sized_object<size, big_endian>* object,
379 const elfcpp::Sym<size, big_endian>* syms,
380 size_t count, const char* sym_names,
381 size_t sym_name_size)
382 {
383 const unsigned char* p = reinterpret_cast<const unsigned char*>(syms);
384 for (size_t i = 0; i < count; ++i)
385 {
386 elfcpp::Sym<size, big_endian> sym(p);
387
388 unsigned int st_name = sym.get_st_name();
389 if (st_name >= sym_name_size)
390 {
391 fprintf(stderr,
392 _("%s: %s: bad local symbol name offset %u at %lu\n"),
393 program_name, object->name().c_str(), st_name,
394 static_cast<unsigned long>(i));
395 gold_exit(false);
396 }
397
398 this->output_pool_.add(sym_names + st_name);
399 }
400 }
401
402 // Instantiate the templates we need. We could use the configure
403 // script to restrict this to only the ones needed for implemented
404 // targets.
405
406 template
407 void
408 Symbol_table::add_from_object<32, true>(
409 Sized_object<32, true>* object,
410 const elfcpp::Sym<32, true>* syms,
411 size_t count,
412 const char* sym_names,
413 size_t sym_name_size,
414 Symbol** sympointers);
415
416 template
417 void
418 Symbol_table::add_from_object<32, false>(
419 Sized_object<32, false>* object,
420 const elfcpp::Sym<32, false>* syms,
421 size_t count,
422 const char* sym_names,
423 size_t sym_name_size,
424 Symbol** sympointers);
425
426 template
427 void
428 Symbol_table::add_from_object<64, true>(
429 Sized_object<64, true>* object,
430 const elfcpp::Sym<64, true>* syms,
431 size_t count,
432 const char* sym_names,
433 size_t sym_name_size,
434 Symbol** sympointers);
435
436 template
437 void
438 Symbol_table::add_from_object<64, false>(
439 Sized_object<64, false>* object,
440 const elfcpp::Sym<64, false>* syms,
441 size_t count,
442 const char* sym_names,
443 size_t sym_name_size,
444 Symbol** sympointers);
445
446 template
447 void
448 Symbol_table::add_local_symbol_names<32, true>(
449 Sized_object<32, true>* object,
450 const elfcpp::Sym<32, true>* syms,
451 size_t count,
452 const char* sym_names,
453 size_t sym_name_size);
454
455 template
456 void
457 Symbol_table::add_local_symbol_names<32, false>(
458 Sized_object<32, false>* object,
459 const elfcpp::Sym<32, false>* syms,
460 size_t count,
461 const char* sym_names,
462 size_t sym_name_size);
463
464 template
465 void
466 Symbol_table::add_local_symbol_names<64, true>(
467 Sized_object<64, true>* object,
468 const elfcpp::Sym<64, true>* syms,
469 size_t count,
470 const char* sym_names,
471 size_t sym_name_size);
472
473 template
474 void
475 Symbol_table::add_local_symbol_names<64, false>(
476 Sized_object<64, false>* object,
477 const elfcpp::Sym<64, false>* syms,
478 size_t count,
479 const char* sym_names,
480 size_t sym_name_size);
481
482 } // End namespace gold.
This page took 0.039363 seconds and 4 git commands to generate.