1 // symtab.cc -- the gold symbol table
20 // Initialize the fields in the base class Symbol.
22 template<int size
, bool big_endian
>
24 Symbol::init_base(const char* name
, const char* version
, Object
* object
,
25 const elfcpp::Sym
<size
, big_endian
>& sym
)
28 this->version_
= version
;
29 this->object_
= object
;
30 this->shnum_
= sym
.get_st_shndx(); // FIXME: Handle SHN_XINDEX.
31 this->type_
= sym
.get_st_type();
32 this->binding_
= sym
.get_st_bind();
33 this->visibility_
= sym
.get_st_visibility();
34 this->other_
= sym
.get_st_nonvis();
35 this->is_special_
= false;
36 this->is_def_
= false;
37 this->is_forwarder_
= false;
38 this->in_dyn_
= object
->is_dynamic();
41 // Initialize the fields in Sized_symbol.
44 template<bool big_endian
>
46 Sized_symbol
<size
>::init(const char* name
, const char* version
, Object
* object
,
47 const elfcpp::Sym
<size
, big_endian
>& sym
)
49 this->init_base(name
, version
, object
, sym
);
50 this->value_
= sym
.get_st_value();
51 this->size_
= sym
.get_st_size();
54 // Class Symbol_table.
56 Symbol_table::Symbol_table()
57 : size_(0), offset_(0), table_(), namepool_(), forwarders_()
61 Symbol_table::~Symbol_table()
65 // The hash function. The key is always canonicalized, so we use a
66 // simple combination of the pointers.
69 Symbol_table::Symbol_table_hash::operator()(const Symbol_table_key
& key
) const
71 return (reinterpret_cast<size_t>(key
.first
)
72 ^ reinterpret_cast<size_t>(key
.second
));
75 // The symbol table key equality function. This is only called with
76 // canonicalized name and version strings, so we can use pointer
80 Symbol_table::Symbol_table_eq::operator()(const Symbol_table_key
& k1
,
81 const Symbol_table_key
& k2
) const
83 return k1
.first
== k2
.first
&& k1
.second
== k2
.second
;
86 // Make TO a symbol which forwards to FROM.
89 Symbol_table::make_forwarder(Symbol
* from
, Symbol
* to
)
91 assert(!from
->is_forwarder() && !to
->is_forwarder());
92 this->forwarders_
[from
] = to
;
93 from
->set_forwarder();
96 // Resolve the forwards from FROM, returning the real symbol.
99 Symbol_table::resolve_forwards(Symbol
* from
) const
101 assert(from
->is_forwarder());
102 Unordered_map
<Symbol
*, Symbol
*>::const_iterator p
=
103 this->forwarders_
.find(from
);
104 assert(p
!= this->forwarders_
.end());
108 // Look up a symbol by name.
111 Symbol_table::lookup(const char* name
, const char* version
) const
113 name
= this->namepool_
.find(name
);
118 version
= this->namepool_
.find(version
);
123 Symbol_table_key
key(name
, version
);
124 Symbol_table::Symbol_table_type::const_iterator p
= this->table_
.find(key
);
125 if (p
== this->table_
.end())
130 // Resolve a Symbol with another Symbol. This is only used in the
131 // unusual case where there are references to both an unversioned
132 // symbol and a symbol with a version, and we then discover that that
133 // version is the default version. Because this is unusual, we do
134 // this the slow way, by converting back to an ELF symbol.
136 template<int size
, bool big_endian
>
138 Symbol_table::resolve(Sized_symbol
<size
>* to
, const Sized_symbol
<size
>* from
141 unsigned char buf
[elfcpp::Elf_sizes
<size
>::sym_size
];
142 elfcpp::Sym_write
<size
, big_endian
> esym(buf
);
143 // We don't bother to set the st_name field.
144 esym
.put_st_value(from
->value());
145 esym
.put_st_size(from
->symsize());
146 esym
.put_st_info(from
->binding(), from
->type());
147 esym
.put_st_other(from
->visibility(), from
->other());
148 esym
.put_st_shndx(from
->shnum());
149 Symbol_table::resolve(to
, esym
.sym(), from
->object());
152 // Add one symbol from OBJECT to the symbol table. NAME is symbol
153 // name and VERSION is the version; both are canonicalized. DEF is
154 // whether this is the default version.
156 // If DEF is true, then this is the definition of a default version of
157 // a symbol. That means that any lookup of NAME/NULL and any lookup
158 // of NAME/VERSION should always return the same symbol. This is
159 // obvious for references, but in particular we want to do this for
160 // definitions: overriding NAME/NULL should also override
161 // NAME/VERSION. If we don't do that, it would be very hard to
162 // override functions in a shared library which uses versioning.
164 // We implement this by simply making both entries in the hash table
165 // point to the same Symbol structure. That is easy enough if this is
166 // the first time we see NAME/NULL or NAME/VERSION, but it is possible
167 // that we have seen both already, in which case they will both have
168 // independent entries in the symbol table. We can't simply change
169 // the symbol table entry, because we have pointers to the entries
170 // attached to the object files. So we mark the entry attached to the
171 // object file as a forwarder, and record it in the forwarders_ map.
172 // Note that entries in the hash table will never be marked as
175 template<int size
, bool big_endian
>
177 Symbol_table::add_from_object(Sized_object
<size
, big_endian
>* object
,
179 const char *version
, bool def
,
180 const elfcpp::Sym
<size
, big_endian
>& sym
)
182 Symbol
* const snull
= NULL
;
183 std::pair
<typename
Symbol_table_type::iterator
, bool> ins
=
184 this->table_
.insert(std::make_pair(std::make_pair(name
, version
), snull
));
186 std::pair
<typename
Symbol_table_type::iterator
, bool> insdef
=
187 std::make_pair(this->table_
.end(), false);
190 const char* const vnull
= NULL
;
191 insdef
= this->table_
.insert(std::make_pair(std::make_pair(name
, vnull
),
195 // ins.first: an iterator, which is a pointer to a pair.
196 // ins.first->first: the key (a pair of name and version).
197 // ins.first->second: the value (Symbol*).
198 // ins.second: true if new entry was inserted, false if not.
200 Sized_symbol
<size
>* ret
;
203 // We already have an entry for NAME/VERSION.
204 ret
= this->get_sized_symbol
SELECT_SIZE_NAME (ins
.first
->second
207 Symbol_table::resolve(ret
, sym
, object
);
213 // This is the first time we have seen NAME/NULL. Make
214 // NAME/NULL point to NAME/VERSION.
215 insdef
.first
->second
= ret
;
219 // This is the unfortunate case where we already have
220 // entries for both NAME/VERSION and NAME/NULL.
221 const Sized_symbol
<size
>* sym2
;
222 sym2
= this->get_sized_symbol
SELECT_SIZE_NAME (
225 Symbol_table::resolve
SELECT_SIZE_ENDIAN_NAME (
226 ret
, sym2
SELECT_SIZE_ENDIAN(size
, big_endian
));
227 this->make_forwarder(insdef
.first
->second
, ret
);
228 insdef
.first
->second
= ret
;
234 // This is the first time we have seen NAME/VERSION.
235 assert(ins
.first
->second
== NULL
);
236 if (def
&& !insdef
.second
)
238 // We already have an entry for NAME/NULL. Make
239 // NAME/VERSION point to it.
240 ret
= this->get_sized_symbol
SELECT_SIZE_NAME (insdef
.first
->second
242 Symbol_table::resolve(ret
, sym
, object
);
243 ins
.first
->second
= ret
;
247 Sized_target
<size
, big_endian
>* target
= object
->sized_target();
248 if (!target
->has_make_symbol())
249 ret
= new Sized_symbol
<size
>();
252 ret
= target
->make_symbol();
255 // This means that we don't want a symbol table
258 this->table_
.erase(ins
.first
);
261 this->table_
.erase(insdef
.first
);
262 // Inserting insdef invalidated ins.
263 this->table_
.erase(std::make_pair(name
, version
));
269 ret
->init(name
, version
, object
, sym
);
271 ins
.first
->second
= ret
;
274 // This is the first time we have seen NAME/NULL. Point
275 // it at the new entry for NAME/VERSION.
276 assert(insdef
.second
);
277 insdef
.first
->second
= ret
;
285 // Add all the symbols in an object to the hash table.
287 template<int size
, bool big_endian
>
289 Symbol_table::add_from_object(
290 Sized_object
<size
, big_endian
>* object
,
291 const elfcpp::Sym
<size
, big_endian
>* syms
,
293 const char* sym_names
,
294 size_t sym_name_size
,
295 Symbol
** sympointers
)
297 // We take the size from the first object we see.
298 if (this->get_size() == 0)
299 this->set_size(size
);
301 if (size
!= this->get_size() || size
!= object
->target()->get_size())
303 fprintf(stderr
, _("%s: %s: mixing 32-bit and 64-bit ELF objects\n"),
304 program_name
, object
->name().c_str());
308 const int sym_size
= elfcpp::Elf_sizes
<size
>::sym_size
;
310 const unsigned char* p
= reinterpret_cast<const unsigned char*>(syms
);
311 for (size_t i
= 0; i
< count
; ++i
, p
+= sym_size
)
313 elfcpp::Sym
<size
, big_endian
> sym(p
);
314 elfcpp::Sym
<size
, big_endian
>* psym
= &sym
;
316 unsigned int st_name
= psym
->get_st_name();
317 if (st_name
>= sym_name_size
)
320 _("%s: %s: bad global symbol name offset %u at %lu\n"),
321 program_name
, object
->name().c_str(), st_name
,
322 static_cast<unsigned long>(i
));
326 // A symbol defined in a section which we are not including must
327 // be treated as an undefined symbol.
328 unsigned char symbuf
[sym_size
];
329 elfcpp::Sym
<size
, big_endian
> sym2(symbuf
);
330 unsigned int st_shndx
= psym
->get_st_shndx();
331 if (st_shndx
!= elfcpp::SHN_UNDEF
332 && st_shndx
< elfcpp::SHN_LORESERVE
333 && !object
->is_section_included(st_shndx
))
335 memcpy(symbuf
, p
, sym_size
);
336 elfcpp::Sym_write
<size
, big_endian
> sw(symbuf
);
337 sw
.put_st_shndx(elfcpp::SHN_UNDEF
);
341 const char* name
= sym_names
+ st_name
;
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
, '@');
351 name
= this->namepool_
.add(name
);
352 res
= this->add_from_object(object
, name
, NULL
, false, *psym
);
356 name
= this->namepool_
.add(name
, ver
- name
);
364 ver
= this->namepool_
.add(ver
);
365 res
= this->add_from_object(object
, name
, ver
, def
, *psym
);
368 *sympointers
++ = res
;
372 // Set the final values for all the symbols. Record the file offset
373 // OFF. Add their names to POOL. Return the new file offset.
376 Symbol_table::finalize(off_t off
, Stringpool
* pool
)
378 if (this->size_
== 32)
379 return this->sized_finalize
<32>(off
, pool
);
380 else if (this->size_
== 64)
381 return this->sized_finalize
<64>(off
, pool
);
386 // Set the final value for all the symbols.
390 Symbol_table::sized_finalize(off_t off
, Stringpool
* pool
)
392 off
= (off
+ (size
>> 3) - 1) & ~ ((size
>> 3) - 1);
395 const int sym_size
= elfcpp::Elf_sizes
<size
>::sym_size
;
396 Symbol_table_type::iterator p
= this->table_
.begin();
398 while (p
!= this->table_
.end())
400 Sized_symbol
<size
>* sym
= static_cast<Sized_symbol
<size
>*>(p
->second
);
402 // FIXME: Here we need to decide which symbols should go into
405 // FIXME: This is wrong.
406 if (sym
->shnum() >= elfcpp::SHN_LORESERVE
)
413 Output_section
* os
= sym
->object()->output_section(sym
->shnum(),
418 // We should be able to erase this symbol from the symbol
419 // table, but at least with gcc 4.0.2
420 // std::unordered_map::erase doesn't appear to return the
422 // p = this->table_.erase(p);
427 sym
->set_value(sym
->value() + os
->address() + secoff
);
428 pool
->add(sym
->name());
435 this->output_count_
= count
;
440 // Write out the global symbols.
443 Symbol_table::write_globals(const Target
* target
, const Stringpool
* sympool
,
444 Output_file
* of
) const
446 if (this->size_
== 32)
448 if (target
->is_big_endian())
449 this->sized_write_globals
<32, true>(target
, sympool
, of
);
451 this->sized_write_globals
<32, false>(target
, sympool
, of
);
453 else if (this->size_
== 64)
455 if (target
->is_big_endian())
456 this->sized_write_globals
<64, true>(target
, sympool
, of
);
458 this->sized_write_globals
<64, false>(target
, sympool
, of
);
464 // Write out the global symbols.
466 template<int size
, bool big_endian
>
468 Symbol_table::sized_write_globals(const Target
*,
469 const Stringpool
* sympool
,
470 Output_file
* of
) const
472 const int sym_size
= elfcpp::Elf_sizes
<size
>::sym_size
;
473 unsigned char* psyms
= of
->get_output_view(this->offset_
,
474 this->output_count_
* sym_size
);
475 unsigned char* ps
= psyms
;
476 for (Symbol_table_type::const_iterator p
= this->table_
.begin();
477 p
!= this->table_
.end();
480 Sized_symbol
<size
>* sym
= static_cast<Sized_symbol
<size
>*>(p
->second
);
482 // FIXME: This repeats sized_finalize().
484 // FIXME: This is wrong.
485 if (sym
->shnum() >= elfcpp::SHN_LORESERVE
)
489 Output_section
* os
= sym
->object()->output_section(sym
->shnum(),
494 elfcpp::Sym_write
<size
, big_endian
> osym(ps
);
495 osym
.put_st_name(sympool
->get_offset(sym
->name()));
496 osym
.put_st_value(sym
->value());
497 osym
.put_st_size(sym
->symsize());
498 osym
.put_st_info(elfcpp::elf_st_info(sym
->binding(), sym
->type()));
499 osym
.put_st_other(elfcpp::elf_st_other(sym
->visibility(), sym
->other()));
500 osym
.put_st_shndx(os
->shndx());
505 of
->write_output_view(this->offset_
, this->output_count_
* sym_size
, psyms
);
508 // Instantiate the templates we need. We could use the configure
509 // script to restrict this to only the ones needed for implemented
514 Symbol_table::add_from_object
<32, true>(
515 Sized_object
<32, true>* object
,
516 const elfcpp::Sym
<32, true>* syms
,
518 const char* sym_names
,
519 size_t sym_name_size
,
520 Symbol
** sympointers
);
524 Symbol_table::add_from_object
<32, false>(
525 Sized_object
<32, false>* object
,
526 const elfcpp::Sym
<32, false>* syms
,
528 const char* sym_names
,
529 size_t sym_name_size
,
530 Symbol
** sympointers
);
534 Symbol_table::add_from_object
<64, true>(
535 Sized_object
<64, true>* object
,
536 const elfcpp::Sym
<64, true>* syms
,
538 const char* sym_names
,
539 size_t sym_name_size
,
540 Symbol
** sympointers
);
544 Symbol_table::add_from_object
<64, false>(
545 Sized_object
<64, false>* object
,
546 const elfcpp::Sym
<64, false>* syms
,
548 const char* sym_names
,
549 size_t sym_name_size
,
550 Symbol
** sympointers
);
552 } // End namespace gold.