1 // symtab.cc -- the gold symbol table
18 // Initialize the fields in the base class Symbol.
20 template<int size
, bool big_endian
>
22 Symbol::init_base(const char* name
, const char* version
, Object
* object
,
23 const elfcpp::Sym
<size
, big_endian
>& sym
)
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();
39 // Initialize the fields in Sized_symbol.
42 template<bool big_endian
>
44 Sized_symbol
<size
>::init(const char* name
, const char* version
, Object
* object
,
45 const elfcpp::Sym
<size
, big_endian
>& sym
)
47 this->init_base(name
, version
, object
, sym
);
48 this->value_
= sym
.get_st_value();
49 this->size_
= sym
.get_st_size();
52 // Class Symbol_table.
54 Symbol_table::Symbol_table()
55 : size_(0), table_(), namepool_(), output_pool_(), forwarders_()
59 Symbol_table::~Symbol_table()
63 // The hash function. The key is always canonicalized, so we use a
64 // simple combination of the pointers.
67 Symbol_table::Symbol_table_hash::operator()(const Symbol_table_key
& key
) const
69 return (reinterpret_cast<size_t>(key
.first
)
70 ^ reinterpret_cast<size_t>(key
.second
));
73 // The symbol table key equality function. This is only called with
74 // canonicalized name and version strings, so we can use pointer
78 Symbol_table::Symbol_table_eq::operator()(const Symbol_table_key
& k1
,
79 const Symbol_table_key
& k2
) const
81 return k1
.first
== k2
.first
&& k1
.second
== k2
.second
;
84 // Make TO a symbol which forwards to FROM.
87 Symbol_table::make_forwarder(Symbol
* from
, Symbol
* to
)
89 assert(!from
->is_forwarder() && !to
->is_forwarder());
90 this->forwarders_
[from
] = to
;
91 from
->set_forwarder();
95 Symbol_table::resolve_forwards(Symbol
* from
) const
97 assert(from
->is_forwarder());
98 Unordered_map
<Symbol
*, Symbol
*>::const_iterator p
=
99 this->forwarders_
.find(from
);
100 assert(p
!= this->forwarders_
.end());
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.
110 template<int size
, bool big_endian
>
112 Symbol_table::resolve(Sized_symbol
<size
>* to
, const Sized_symbol
<size
>* from
)
114 unsigned char buf
[elfcpp::Elf_sizes
<size
>::sym_size
];
115 elfcpp::Sym_write
<size
, big_endian
> esym(buf
);
116 // We don't bother to set the st_name field.
117 esym
.put_st_value(from
->value());
118 esym
.put_st_size(from
->symsize());
119 esym
.put_st_info(from
->binding(), from
->type());
120 esym
.put_st_other(from
->visibility(), from
->other());
121 esym
.put_st_shndx(from
->shnum());
122 Symbol_table::resolve(to
, esym
.sym(), from
->object());
125 // Add one symbol from OBJECT to the symbol table. NAME is symbol
126 // name and VERSION is the version; both are canonicalized. DEF is
127 // whether this is the default version.
129 // If DEF is true, then this is the definition of a default version of
130 // a symbol. That means that any lookup of NAME/NULL and any lookup
131 // of NAME/VERSION should always return the same symbol. This is
132 // obvious for references, but in particular we want to do this for
133 // definitions: overriding NAME/NULL should also override
134 // NAME/VERSION. If we don't do that, it would be very hard to
135 // override functions in a shared library which uses versioning.
137 // We implement this by simply making both entries in the hash table
138 // point to the same Symbol structure. That is easy enough if this is
139 // the first time we see NAME/NULL or NAME/VERSION, but it is possible
140 // that we have seen both already, in which case they will both have
141 // independent entries in the symbol table. We can't simply change
142 // the symbol table entry, because we have pointers to the entries
143 // attached to the object files. So we mark the entry attached to the
144 // object file as a forwarder, and record it in the forwarders_ map.
145 // Note that entries in the hash table will never be marked as
148 template<int size
, bool big_endian
>
150 Symbol_table::add_from_object(Sized_object
<size
, big_endian
>* object
,
152 const char *version
, bool def
,
153 const elfcpp::Sym
<size
, big_endian
>& sym
)
155 Symbol
* const snull
= NULL
;
156 std::pair
<typename
Symbol_table_type::iterator
, bool> ins
=
157 this->table_
.insert(std::make_pair(std::make_pair(name
, version
), snull
));
159 std::pair
<typename
Symbol_table_type::iterator
, bool> insdef
=
160 std::make_pair(this->table_
.end(), false);
163 const char* const vnull
= NULL
;
164 insdef
= this->table_
.insert(std::make_pair(std::make_pair(name
, vnull
),
168 // ins.first: an iterator, which is a pointer to a pair.
169 // ins.first->first: the key (a pair of name and version).
170 // ins.first->second: the value (Symbol*).
171 // ins.second: true if new entry was inserted, false if not.
173 Sized_symbol
<size
>* ret
;
176 // We already have an entry for NAME/VERSION.
177 ret
= this->get_sized_symbol
<size
>(ins
.first
->second
);
179 Symbol_table::resolve(ret
, sym
, object
);
185 // This is the first time we have seen NAME/NULL. Make
186 // NAME/NULL point to NAME/VERSION.
187 insdef
.first
->second
= ret
;
191 // This is the unfortunate case where we already have
192 // entries for both NAME/VERSION and NAME/NULL.
193 const Sized_symbol
<size
>* sym2
=
194 this->get_sized_symbol
<size
>(insdef
.first
->second
);
195 Symbol_table::resolve
<size
, big_endian
>(ret
, sym2
);
196 this->make_forwarder(insdef
.first
->second
, ret
);
197 insdef
.first
->second
= ret
;
203 // This is the first time we have seen NAME/VERSION.
204 assert(ins
.first
->second
== NULL
);
205 if (def
&& !insdef
.second
)
207 // We already have an entry for NAME/NULL. Make
208 // NAME/VERSION point to it.
209 ret
= this->get_sized_symbol
<size
>(insdef
.first
->second
);
210 Symbol_table::resolve(ret
, sym
, object
);
211 ins
.first
->second
= ret
;
215 Sized_target
<size
, big_endian
>* target
= object
->sized_target();
216 if (!target
->has_make_symbol())
217 ret
= new Sized_symbol
<size
>();
220 ret
= target
->make_symbol();
223 // This means that we don't want a symbol table
226 this->table_
.erase(ins
.first
);
229 this->table_
.erase(insdef
.first
);
230 // Inserting insdef invalidated ins.
231 this->table_
.erase(std::make_pair(name
, version
));
237 ret
->init(name
, version
, object
, sym
);
239 ins
.first
->second
= ret
;
242 // This is the first time we have seen NAME/NULL. Point
243 // it at the new entry for NAME/VERSION.
244 assert(insdef
.second
);
245 insdef
.first
->second
= ret
;
253 // Add all the symbols in an object to the hash table.
255 template<int size
, bool big_endian
>
257 Symbol_table::add_from_object(
258 Sized_object
<size
, big_endian
>* object
,
259 const elfcpp::Sym
<size
, big_endian
>* syms
,
261 const char* sym_names
,
262 size_t sym_name_size
,
263 Symbol
** sympointers
)
265 // We take the size from the first object we see.
266 if (this->get_size() == 0)
267 this->set_size(size
);
269 if (size
!= this->get_size() || size
!= object
->target()->get_size())
271 fprintf(stderr
, _("%s: %s: mixing 32-bit and 64-bit ELF objects\n"),
272 program_name
, object
->name().c_str());
276 const unsigned char* p
= reinterpret_cast<const unsigned char*>(syms
);
277 for (size_t i
= 0; i
< count
; ++i
)
279 elfcpp::Sym
<size
, big_endian
> sym(p
);
281 unsigned int st_name
= sym
.get_st_name();
282 if (st_name
>= sym_name_size
)
285 _("%s: %s: bad global symbol name offset %u at %lu\n"),
286 program_name
, object
->name().c_str(), st_name
,
287 static_cast<unsigned long>(i
));
291 const char* name
= sym_names
+ st_name
;
293 // In an object file, an '@' in the name separates the symbol
294 // name from the version name. If there are two '@' characters,
295 // this is the default version.
296 const char* ver
= strchr(name
, '@');
301 name
= this->namepool_
.add(name
);
302 res
= this->add_from_object(object
, name
, NULL
, false, sym
);
306 name
= this->namepool_
.add(name
, ver
- name
);
314 ver
= this->namepool_
.add(ver
);
315 res
= this->add_from_object(object
, name
, ver
, def
, sym
);
318 *sympointers
++ = res
;
320 p
+= elfcpp::Elf_sizes
<size
>::sym_size
;
324 // Record the names of the local symbols for an object.
326 template<int size
, bool big_endian
>
328 Symbol_table::add_local_symbol_names(Sized_object
<size
, big_endian
>* object
,
329 const elfcpp::Sym
<size
, big_endian
>* syms
,
330 size_t count
, const char* sym_names
,
331 size_t sym_name_size
)
333 const unsigned char* p
= reinterpret_cast<const unsigned char*>(syms
);
334 for (size_t i
= 0; i
< count
; ++i
)
336 elfcpp::Sym
<size
, big_endian
> sym(p
);
338 unsigned int st_name
= sym
.get_st_name();
339 if (st_name
>= sym_name_size
)
342 _("%s: %s: bad local symbol name offset %u at %lu\n"),
343 program_name
, object
->name().c_str(), st_name
,
344 static_cast<unsigned long>(i
));
348 this->output_pool_
.add(sym_names
+ st_name
);
352 // Instantiate the templates we need. We could use the configure
353 // script to restrict this to only the ones needed for implemented
358 Symbol_table::add_from_object
<32, true>(
359 Sized_object
<32, true>* object
,
360 const elfcpp::Sym
<32, true>* syms
,
362 const char* sym_names
,
363 size_t sym_name_size
,
364 Symbol
** sympointers
);
368 Symbol_table::add_from_object
<32, false>(
369 Sized_object
<32, false>* object
,
370 const elfcpp::Sym
<32, false>* syms
,
372 const char* sym_names
,
373 size_t sym_name_size
,
374 Symbol
** sympointers
);
378 Symbol_table::add_from_object
<64, true>(
379 Sized_object
<64, true>* object
,
380 const elfcpp::Sym
<64, true>* syms
,
382 const char* sym_names
,
383 size_t sym_name_size
,
384 Symbol
** sympointers
);
388 Symbol_table::add_from_object
<64, false>(
389 Sized_object
<64, false>* object
,
390 const elfcpp::Sym
<64, false>* syms
,
392 const char* sym_names
,
393 size_t sym_name_size
,
394 Symbol
** sympointers
);
398 Symbol_table::add_local_symbol_names
<32, true>(
399 Sized_object
<32, true>* object
,
400 const elfcpp::Sym
<32, true>* syms
,
402 const char* sym_names
,
403 size_t sym_name_size
);
407 Symbol_table::add_local_symbol_names
<32, false>(
408 Sized_object
<32, false>* object
,
409 const elfcpp::Sym
<32, false>* syms
,
411 const char* sym_names
,
412 size_t sym_name_size
);
416 Symbol_table::add_local_symbol_names
<64, true>(
417 Sized_object
<64, true>* object
,
418 const elfcpp::Sym
<64, true>* syms
,
420 const char* sym_names
,
421 size_t sym_name_size
);
425 Symbol_table::add_local_symbol_names
<64, false>(
426 Sized_object
<64, false>* object
,
427 const elfcpp::Sym
<64, false>* syms
,
429 const char* sym_names
,
430 size_t sym_name_size
);
432 } // End namespace gold.