1 // symtab.cc -- the gold symbol table
19 // Initialize the fields in the base class Symbol.
21 template<int size
, bool big_endian
>
23 Symbol::init_base(const char* name
, const char* version
, Object
* object
,
24 const elfcpp::Sym
<size
, big_endian
>& sym
)
27 this->version_
= version
;
28 this->object_
= object
;
29 this->shnum_
= sym
.get_st_shndx(); // FIXME: Handle SHN_XINDEX.
30 this->type_
= sym
.get_st_type();
31 this->binding_
= sym
.get_st_bind();
32 this->visibility_
= sym
.get_st_visibility();
33 this->other_
= sym
.get_st_nonvis();
34 this->is_special_
= false;
35 this->is_def_
= false;
36 this->is_forwarder_
= false;
37 this->in_dyn_
= object
->is_dynamic();
40 // Initialize the fields in Sized_symbol.
43 template<bool big_endian
>
45 Sized_symbol
<size
>::init(const char* name
, const char* version
, Object
* object
,
46 const elfcpp::Sym
<size
, big_endian
>& sym
)
48 this->init_base(name
, version
, object
, sym
);
49 this->value_
= sym
.get_st_value();
50 this->size_
= sym
.get_st_size();
53 // Class Symbol_table.
55 Symbol_table::Symbol_table()
56 : size_(0), offset_(0), table_(), namepool_(), forwarders_()
60 Symbol_table::~Symbol_table()
64 // The hash function. The key is always canonicalized, so we use a
65 // simple combination of the pointers.
68 Symbol_table::Symbol_table_hash::operator()(const Symbol_table_key
& key
) const
70 return (reinterpret_cast<size_t>(key
.first
)
71 ^ reinterpret_cast<size_t>(key
.second
));
74 // The symbol table key equality function. This is only called with
75 // canonicalized name and version strings, so we can use pointer
79 Symbol_table::Symbol_table_eq::operator()(const Symbol_table_key
& k1
,
80 const Symbol_table_key
& k2
) const
82 return k1
.first
== k2
.first
&& k1
.second
== k2
.second
;
85 // Make TO a symbol which forwards to FROM.
88 Symbol_table::make_forwarder(Symbol
* from
, Symbol
* to
)
90 assert(!from
->is_forwarder() && !to
->is_forwarder());
91 this->forwarders_
[from
] = to
;
92 from
->set_forwarder();
96 Symbol_table::resolve_forwards(Symbol
* from
) const
98 assert(from
->is_forwarder());
99 Unordered_map
<Symbol
*, Symbol
*>::const_iterator p
=
100 this->forwarders_
.find(from
);
101 assert(p
!= this->forwarders_
.end());
105 // Resolve a Symbol with another Symbol. This is only used in the
106 // unusual case where there are references to both an unversioned
107 // symbol and a symbol with a version, and we then discover that that
108 // version is the default version. Because this is unusual, we do
109 // this the slow way, by converting back to an ELF symbol.
111 #ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS
113 template<int size
, bool big_endian
>
115 Symbol_table::resolve(Sized_symbol
<size
>* to
, const Sized_symbol
<size
>* from
)
117 unsigned char buf
[elfcpp::Elf_sizes
<size
>::sym_size
];
118 elfcpp::Sym_write
<size
, big_endian
> esym(buf
);
119 // We don't bother to set the st_name field.
120 esym
.put_st_value(from
->value());
121 esym
.put_st_size(from
->symsize());
122 esym
.put_st_info(from
->binding(), from
->type());
123 esym
.put_st_other(from
->visibility(), from
->other());
124 esym
.put_st_shndx(from
->shnum());
125 Symbol_table::resolve(to
, esym
.sym(), from
->object());
132 Symbol_table::resolve(Sized_symbol
<size
>* to
, const Sized_symbol
<size
>* from
,
135 unsigned char buf
[elfcpp::Elf_sizes
<size
>::sym_size
];
138 elfcpp::Sym_write
<size
, true> esym(buf
);
139 // We don't bother to set the st_name field.
140 esym
.put_st_value(from
->value());
141 esym
.put_st_size(from
->symsize());
142 esym
.put_st_info(from
->binding(), from
->type());
143 esym
.put_st_other(from
->visibility(), from
->other());
144 esym
.put_st_shndx(from
->shnum());
145 Symbol_table::resolve(to
, esym
.sym(), from
->object());
149 elfcpp::Sym_write
<size
, false> esym(buf
);
150 // We don't bother to set the st_name field.
151 esym
.put_st_value(from
->value());
152 esym
.put_st_size(from
->symsize());
153 esym
.put_st_info(from
->binding(), from
->type());
154 esym
.put_st_other(from
->visibility(), from
->other());
155 esym
.put_st_shndx(from
->shnum());
156 Symbol_table::resolve(to
, esym
.sym(), from
->object());
162 // Add one symbol from OBJECT to the symbol table. NAME is symbol
163 // name and VERSION is the version; both are canonicalized. DEF is
164 // whether this is the default version.
166 // If DEF is true, then this is the definition of a default version of
167 // a symbol. That means that any lookup of NAME/NULL and any lookup
168 // of NAME/VERSION should always return the same symbol. This is
169 // obvious for references, but in particular we want to do this for
170 // definitions: overriding NAME/NULL should also override
171 // NAME/VERSION. If we don't do that, it would be very hard to
172 // override functions in a shared library which uses versioning.
174 // We implement this by simply making both entries in the hash table
175 // point to the same Symbol structure. That is easy enough if this is
176 // the first time we see NAME/NULL or NAME/VERSION, but it is possible
177 // that we have seen both already, in which case they will both have
178 // independent entries in the symbol table. We can't simply change
179 // the symbol table entry, because we have pointers to the entries
180 // attached to the object files. So we mark the entry attached to the
181 // object file as a forwarder, and record it in the forwarders_ map.
182 // Note that entries in the hash table will never be marked as
185 template<int size
, bool big_endian
>
187 Symbol_table::add_from_object(Sized_object
<size
, big_endian
>* object
,
189 const char *version
, bool def
,
190 const elfcpp::Sym
<size
, big_endian
>& sym
)
192 Symbol
* const snull
= NULL
;
193 std::pair
<typename
Symbol_table_type::iterator
, bool> ins
=
194 this->table_
.insert(std::make_pair(std::make_pair(name
, version
), snull
));
196 std::pair
<typename
Symbol_table_type::iterator
, bool> insdef
=
197 std::make_pair(this->table_
.end(), false);
200 const char* const vnull
= NULL
;
201 insdef
= this->table_
.insert(std::make_pair(std::make_pair(name
, vnull
),
205 // ins.first: an iterator, which is a pointer to a pair.
206 // ins.first->first: the key (a pair of name and version).
207 // ins.first->second: the value (Symbol*).
208 // ins.second: true if new entry was inserted, false if not.
210 Sized_symbol
<size
>* ret
;
213 // We already have an entry for NAME/VERSION.
214 #ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS
215 ret
= this->get_sized_symbol
<size
>(ins
.first
->second
);
217 assert(size
== this->get_size());
218 ret
= static_cast<Sized_symbol
<size
>*>(ins
.first
->second
);
221 Symbol_table::resolve(ret
, sym
, object
);
227 // This is the first time we have seen NAME/NULL. Make
228 // NAME/NULL point to NAME/VERSION.
229 insdef
.first
->second
= ret
;
233 // This is the unfortunate case where we already have
234 // entries for both NAME/VERSION and NAME/NULL.
235 const Sized_symbol
<size
>* sym2
;
236 #ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS
237 sym2
= this->get_sized_symbol
<size
>(insdef
.first
->second
);
238 Symbol_table::resolve
<size
, big_endian
>(ret
, sym2
);
240 sym2
= static_cast<Sized_symbol
<size
>*>(insdef
.first
->second
);
241 Symbol_table::resolve(ret
, sym2
, big_endian
);
243 this->make_forwarder(insdef
.first
->second
, ret
);
244 insdef
.first
->second
= ret
;
250 // This is the first time we have seen NAME/VERSION.
251 assert(ins
.first
->second
== NULL
);
252 if (def
&& !insdef
.second
)
254 // We already have an entry for NAME/NULL. Make
255 // NAME/VERSION point to it.
256 #ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS
257 ret
= this->get_sized_symbol
<size
>(insdef
.first
->second
);
259 ret
= static_cast<Sized_symbol
<size
>*>(insdef
.first
->second
);
261 Symbol_table::resolve(ret
, sym
, object
);
262 ins
.first
->second
= ret
;
266 Sized_target
<size
, big_endian
>* target
= object
->sized_target();
267 if (!target
->has_make_symbol())
268 ret
= new Sized_symbol
<size
>();
271 ret
= target
->make_symbol();
274 // This means that we don't want a symbol table
277 this->table_
.erase(ins
.first
);
280 this->table_
.erase(insdef
.first
);
281 // Inserting insdef invalidated ins.
282 this->table_
.erase(std::make_pair(name
, version
));
288 ret
->init(name
, version
, object
, sym
);
290 ins
.first
->second
= ret
;
293 // This is the first time we have seen NAME/NULL. Point
294 // it at the new entry for NAME/VERSION.
295 assert(insdef
.second
);
296 insdef
.first
->second
= ret
;
304 // Add all the symbols in an object to the hash table.
306 template<int size
, bool big_endian
>
308 Symbol_table::add_from_object(
309 Sized_object
<size
, big_endian
>* object
,
310 const elfcpp::Sym
<size
, big_endian
>* syms
,
312 const char* sym_names
,
313 size_t sym_name_size
,
314 Symbol
** sympointers
)
316 // We take the size from the first object we see.
317 if (this->get_size() == 0)
318 this->set_size(size
);
320 if (size
!= this->get_size() || size
!= object
->target()->get_size())
322 fprintf(stderr
, _("%s: %s: mixing 32-bit and 64-bit ELF objects\n"),
323 program_name
, object
->name().c_str());
327 const unsigned char* p
= reinterpret_cast<const unsigned char*>(syms
);
328 for (size_t i
= 0; i
< count
; ++i
)
330 elfcpp::Sym
<size
, big_endian
> sym(p
);
332 unsigned int st_name
= sym
.get_st_name();
333 if (st_name
>= sym_name_size
)
336 _("%s: %s: bad global symbol name offset %u at %lu\n"),
337 program_name
, object
->name().c_str(), st_name
,
338 static_cast<unsigned long>(i
));
342 const char* name
= sym_names
+ st_name
;
344 // In an object file, an '@' in the name separates the symbol
345 // name from the version name. If there are two '@' characters,
346 // this is the default version.
347 const char* ver
= strchr(name
, '@');
352 name
= this->namepool_
.add(name
);
353 res
= this->add_from_object(object
, name
, NULL
, false, sym
);
357 name
= this->namepool_
.add(name
, ver
- name
);
365 ver
= this->namepool_
.add(ver
);
366 res
= this->add_from_object(object
, name
, ver
, def
, sym
);
369 *sympointers
++ = res
;
371 p
+= elfcpp::Elf_sizes
<size
>::sym_size
;
375 // Set the final values for all the symbols. Record the file offset
376 // OFF. Add their names to POOL. Return the new file offset.
379 Symbol_table::finalize(off_t off
, Stringpool
* pool
)
381 if (this->size_
== 32)
382 return this->sized_finalize
<32>(off
, pool
);
384 return this->sized_finalize
<64>(off
, pool
);
387 // Set the final value for all the symbols.
391 Symbol_table::sized_finalize(off_t off
, Stringpool
* pool
)
393 off
= (off
+ size
- 1) & ~ (size
- 1);
396 const int sym_size
= elfcpp::Elf_sizes
<size
>::sym_size
;
397 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 const Object::Map_to_output
* mo
=
406 sym
->object()->section_output_info(sym
->shnum());
408 if (mo
->output_section
== NULL
)
410 // We should be able to erase this symbol from the symbol
411 // table, but at least with gcc 4.0.2
412 // std::unordered_map::erase doesn't appear to return the
414 // p = this->table_.erase(p);
419 sym
->set_value(mo
->output_section
->address() + mo
->offset
);
420 pool
->add(sym
->name());
429 // Instantiate the templates we need. We could use the configure
430 // script to restrict this to only the ones needed for implemented
435 Symbol_table::add_from_object
<32, true>(
436 Sized_object
<32, true>* object
,
437 const elfcpp::Sym
<32, true>* syms
,
439 const char* sym_names
,
440 size_t sym_name_size
,
441 Symbol
** sympointers
);
445 Symbol_table::add_from_object
<32, false>(
446 Sized_object
<32, false>* object
,
447 const elfcpp::Sym
<32, false>* syms
,
449 const char* sym_names
,
450 size_t sym_name_size
,
451 Symbol
** sympointers
);
455 Symbol_table::add_from_object
<64, true>(
456 Sized_object
<64, true>* object
,
457 const elfcpp::Sym
<64, true>* syms
,
459 const char* sym_names
,
460 size_t sym_name_size
,
461 Symbol
** sympointers
);
465 Symbol_table::add_from_object
<64, false>(
466 Sized_object
<64, false>* object
,
467 const elfcpp::Sym
<64, false>* syms
,
469 const char* sym_names
,
470 size_t sym_name_size
,
471 Symbol
** sympointers
);
473 } // End namespace gold.