1 |
27 |
khays |
// symtab.h -- the gold symbol table -*- C++ -*-
|
2 |
|
|
|
3 |
159 |
khays |
// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
|
4 |
27 |
khays |
// Written by Ian Lance Taylor <iant@google.com>.
|
5 |
|
|
|
6 |
|
|
// This file is part of gold.
|
7 |
|
|
|
8 |
|
|
// This program is free software; you can redistribute it and/or modify
|
9 |
|
|
// it under the terms of the GNU General Public License as published by
|
10 |
|
|
// the Free Software Foundation; either version 3 of the License, or
|
11 |
|
|
// (at your option) any later version.
|
12 |
|
|
|
13 |
|
|
// This program is distributed in the hope that it will be useful,
|
14 |
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15 |
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16 |
|
|
// GNU General Public License for more details.
|
17 |
|
|
|
18 |
|
|
// You should have received a copy of the GNU General Public License
|
19 |
|
|
// along with this program; if not, write to the Free Software
|
20 |
|
|
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
|
21 |
|
|
// MA 02110-1301, USA.
|
22 |
|
|
|
23 |
|
|
// Symbol_table
|
24 |
|
|
// The symbol table.
|
25 |
|
|
|
26 |
|
|
#ifndef GOLD_SYMTAB_H
|
27 |
|
|
#define GOLD_SYMTAB_H
|
28 |
|
|
|
29 |
|
|
#include <string>
|
30 |
|
|
#include <utility>
|
31 |
|
|
#include <vector>
|
32 |
|
|
|
33 |
|
|
#include "elfcpp.h"
|
34 |
|
|
#include "parameters.h"
|
35 |
|
|
#include "stringpool.h"
|
36 |
|
|
#include "object.h"
|
37 |
|
|
|
38 |
|
|
namespace gold
|
39 |
|
|
{
|
40 |
|
|
|
41 |
|
|
class Mapfile;
|
42 |
|
|
class Object;
|
43 |
|
|
class Relobj;
|
44 |
|
|
template<int size, bool big_endian>
|
45 |
|
|
class Sized_relobj_file;
|
46 |
|
|
template<int size, bool big_endian>
|
47 |
|
|
class Sized_pluginobj;
|
48 |
|
|
class Dynobj;
|
49 |
|
|
template<int size, bool big_endian>
|
50 |
|
|
class Sized_dynobj;
|
51 |
|
|
template<int size, bool big_endian>
|
52 |
|
|
class Sized_incrobj;
|
53 |
|
|
class Versions;
|
54 |
|
|
class Version_script_info;
|
55 |
|
|
class Input_objects;
|
56 |
|
|
class Output_data;
|
57 |
|
|
class Output_section;
|
58 |
|
|
class Output_segment;
|
59 |
|
|
class Output_file;
|
60 |
|
|
class Output_symtab_xindex;
|
61 |
|
|
class Garbage_collection;
|
62 |
|
|
class Icf;
|
63 |
|
|
|
64 |
|
|
// The base class of an entry in the symbol table. The symbol table
|
65 |
|
|
// can have a lot of entries, so we don't want this class to big.
|
66 |
|
|
// Size dependent fields can be found in the template class
|
67 |
|
|
// Sized_symbol. Targets may support their own derived classes.
|
68 |
|
|
|
69 |
|
|
class Symbol
|
70 |
|
|
{
|
71 |
|
|
public:
|
72 |
|
|
// Because we want the class to be small, we don't use any virtual
|
73 |
|
|
// functions. But because symbols can be defined in different
|
74 |
|
|
// places, we need to classify them. This enum is the different
|
75 |
|
|
// sources of symbols we support.
|
76 |
|
|
enum Source
|
77 |
|
|
{
|
78 |
|
|
// Symbol defined in a relocatable or dynamic input file--this is
|
79 |
|
|
// the most common case.
|
80 |
|
|
FROM_OBJECT,
|
81 |
|
|
// Symbol defined in an Output_data, a special section created by
|
82 |
|
|
// the target.
|
83 |
|
|
IN_OUTPUT_DATA,
|
84 |
|
|
// Symbol defined in an Output_segment, with no associated
|
85 |
|
|
// section.
|
86 |
|
|
IN_OUTPUT_SEGMENT,
|
87 |
|
|
// Symbol value is constant.
|
88 |
|
|
IS_CONSTANT,
|
89 |
|
|
// Symbol is undefined.
|
90 |
|
|
IS_UNDEFINED
|
91 |
|
|
};
|
92 |
|
|
|
93 |
|
|
// When the source is IN_OUTPUT_SEGMENT, we need to describe what
|
94 |
|
|
// the offset means.
|
95 |
|
|
enum Segment_offset_base
|
96 |
|
|
{
|
97 |
|
|
// From the start of the segment.
|
98 |
|
|
SEGMENT_START,
|
99 |
|
|
// From the end of the segment.
|
100 |
|
|
SEGMENT_END,
|
101 |
|
|
// From the filesz of the segment--i.e., after the loaded bytes
|
102 |
|
|
// but before the bytes which are allocated but zeroed.
|
103 |
|
|
SEGMENT_BSS
|
104 |
|
|
};
|
105 |
|
|
|
106 |
|
|
// Return the symbol name.
|
107 |
|
|
const char*
|
108 |
|
|
name() const
|
109 |
|
|
{ return this->name_; }
|
110 |
|
|
|
111 |
|
|
// Return the (ANSI) demangled version of the name, if
|
112 |
|
|
// parameters.demangle() is true. Otherwise, return the name. This
|
113 |
|
|
// is intended to be used only for logging errors, so it's not
|
114 |
|
|
// super-efficient.
|
115 |
|
|
std::string
|
116 |
|
|
demangled_name() const;
|
117 |
|
|
|
118 |
|
|
// Return the symbol version. This will return NULL for an
|
119 |
|
|
// unversioned symbol.
|
120 |
|
|
const char*
|
121 |
|
|
version() const
|
122 |
|
|
{ return this->version_; }
|
123 |
|
|
|
124 |
|
|
// Return whether this version is the default for this symbol name
|
125 |
|
|
// (eg, "foo@@V2" is a default version; "foo@V1" is not). Only
|
126 |
|
|
// meaningful for versioned symbols.
|
127 |
|
|
bool
|
128 |
|
|
is_default() const
|
129 |
|
|
{
|
130 |
|
|
gold_assert(this->version_ != NULL);
|
131 |
|
|
return this->is_def_;
|
132 |
|
|
}
|
133 |
|
|
|
134 |
|
|
// Set that this version is the default for this symbol name.
|
135 |
|
|
void
|
136 |
|
|
set_is_default()
|
137 |
|
|
{ this->is_def_ = true; }
|
138 |
|
|
|
139 |
159 |
khays |
// Return the symbol's name as name@version (or name@@version).
|
140 |
|
|
std::string
|
141 |
|
|
versioned_name() const;
|
142 |
|
|
|
143 |
27 |
khays |
// Return the symbol source.
|
144 |
|
|
Source
|
145 |
|
|
source() const
|
146 |
|
|
{ return this->source_; }
|
147 |
|
|
|
148 |
|
|
// Return the object with which this symbol is associated.
|
149 |
|
|
Object*
|
150 |
|
|
object() const
|
151 |
|
|
{
|
152 |
|
|
gold_assert(this->source_ == FROM_OBJECT);
|
153 |
|
|
return this->u_.from_object.object;
|
154 |
|
|
}
|
155 |
|
|
|
156 |
|
|
// Return the index of the section in the input relocatable or
|
157 |
|
|
// dynamic object file.
|
158 |
|
|
unsigned int
|
159 |
|
|
shndx(bool* is_ordinary) const
|
160 |
|
|
{
|
161 |
|
|
gold_assert(this->source_ == FROM_OBJECT);
|
162 |
|
|
*is_ordinary = this->is_ordinary_shndx_;
|
163 |
|
|
return this->u_.from_object.shndx;
|
164 |
|
|
}
|
165 |
|
|
|
166 |
|
|
// Return the output data section with which this symbol is
|
167 |
|
|
// associated, if the symbol was specially defined with respect to
|
168 |
|
|
// an output data section.
|
169 |
|
|
Output_data*
|
170 |
|
|
output_data() const
|
171 |
|
|
{
|
172 |
|
|
gold_assert(this->source_ == IN_OUTPUT_DATA);
|
173 |
|
|
return this->u_.in_output_data.output_data;
|
174 |
|
|
}
|
175 |
|
|
|
176 |
|
|
// If this symbol was defined with respect to an output data
|
177 |
|
|
// section, return whether the value is an offset from end.
|
178 |
|
|
bool
|
179 |
|
|
offset_is_from_end() const
|
180 |
|
|
{
|
181 |
|
|
gold_assert(this->source_ == IN_OUTPUT_DATA);
|
182 |
|
|
return this->u_.in_output_data.offset_is_from_end;
|
183 |
|
|
}
|
184 |
|
|
|
185 |
|
|
// Return the output segment with which this symbol is associated,
|
186 |
|
|
// if the symbol was specially defined with respect to an output
|
187 |
|
|
// segment.
|
188 |
|
|
Output_segment*
|
189 |
|
|
output_segment() const
|
190 |
|
|
{
|
191 |
|
|
gold_assert(this->source_ == IN_OUTPUT_SEGMENT);
|
192 |
|
|
return this->u_.in_output_segment.output_segment;
|
193 |
|
|
}
|
194 |
|
|
|
195 |
|
|
// If this symbol was defined with respect to an output segment,
|
196 |
|
|
// return the offset base.
|
197 |
|
|
Segment_offset_base
|
198 |
|
|
offset_base() const
|
199 |
|
|
{
|
200 |
|
|
gold_assert(this->source_ == IN_OUTPUT_SEGMENT);
|
201 |
|
|
return this->u_.in_output_segment.offset_base;
|
202 |
|
|
}
|
203 |
|
|
|
204 |
|
|
// Return the symbol binding.
|
205 |
|
|
elfcpp::STB
|
206 |
|
|
binding() const
|
207 |
|
|
{ return this->binding_; }
|
208 |
|
|
|
209 |
|
|
// Return the symbol type.
|
210 |
|
|
elfcpp::STT
|
211 |
|
|
type() const
|
212 |
|
|
{ return this->type_; }
|
213 |
|
|
|
214 |
|
|
// Return true for function symbol.
|
215 |
|
|
bool
|
216 |
|
|
is_func() const
|
217 |
|
|
{
|
218 |
|
|
return (this->type_ == elfcpp::STT_FUNC
|
219 |
|
|
|| this->type_ == elfcpp::STT_GNU_IFUNC);
|
220 |
|
|
}
|
221 |
|
|
|
222 |
|
|
// Return the symbol visibility.
|
223 |
|
|
elfcpp::STV
|
224 |
|
|
visibility() const
|
225 |
|
|
{ return this->visibility_; }
|
226 |
|
|
|
227 |
|
|
// Set the visibility.
|
228 |
|
|
void
|
229 |
|
|
set_visibility(elfcpp::STV visibility)
|
230 |
|
|
{ this->visibility_ = visibility; }
|
231 |
|
|
|
232 |
|
|
// Override symbol visibility.
|
233 |
|
|
void
|
234 |
|
|
override_visibility(elfcpp::STV);
|
235 |
|
|
|
236 |
|
|
// Set whether the symbol was originally a weak undef or a regular undef
|
237 |
|
|
// when resolved by a dynamic def.
|
238 |
|
|
inline void
|
239 |
|
|
set_undef_binding(elfcpp::STB bind)
|
240 |
|
|
{
|
241 |
|
|
if (!this->undef_binding_set_ || this->undef_binding_weak_)
|
242 |
|
|
{
|
243 |
|
|
this->undef_binding_weak_ = bind == elfcpp::STB_WEAK;
|
244 |
|
|
this->undef_binding_set_ = true;
|
245 |
|
|
}
|
246 |
|
|
}
|
247 |
|
|
|
248 |
|
|
// Return TRUE if a weak undef was resolved by a dynamic def.
|
249 |
|
|
inline bool
|
250 |
|
|
is_undef_binding_weak() const
|
251 |
|
|
{ return this->undef_binding_weak_; }
|
252 |
|
|
|
253 |
|
|
// Return the non-visibility part of the st_other field.
|
254 |
|
|
unsigned char
|
255 |
|
|
nonvis() const
|
256 |
|
|
{ return this->nonvis_; }
|
257 |
|
|
|
258 |
|
|
// Return whether this symbol is a forwarder. This will never be
|
259 |
|
|
// true of a symbol found in the hash table, but may be true of
|
260 |
|
|
// symbol pointers attached to object files.
|
261 |
|
|
bool
|
262 |
|
|
is_forwarder() const
|
263 |
|
|
{ return this->is_forwarder_; }
|
264 |
|
|
|
265 |
|
|
// Mark this symbol as a forwarder.
|
266 |
|
|
void
|
267 |
|
|
set_forwarder()
|
268 |
|
|
{ this->is_forwarder_ = true; }
|
269 |
|
|
|
270 |
|
|
// Return whether this symbol has an alias in the weak aliases table
|
271 |
|
|
// in Symbol_table.
|
272 |
|
|
bool
|
273 |
|
|
has_alias() const
|
274 |
|
|
{ return this->has_alias_; }
|
275 |
|
|
|
276 |
|
|
// Mark this symbol as having an alias.
|
277 |
|
|
void
|
278 |
|
|
set_has_alias()
|
279 |
|
|
{ this->has_alias_ = true; }
|
280 |
|
|
|
281 |
|
|
// Return whether this symbol needs an entry in the dynamic symbol
|
282 |
|
|
// table.
|
283 |
|
|
bool
|
284 |
|
|
needs_dynsym_entry() const
|
285 |
|
|
{
|
286 |
|
|
return (this->needs_dynsym_entry_
|
287 |
|
|
|| (this->in_reg()
|
288 |
|
|
&& this->in_dyn()
|
289 |
|
|
&& this->is_externally_visible()));
|
290 |
|
|
}
|
291 |
|
|
|
292 |
|
|
// Mark this symbol as needing an entry in the dynamic symbol table.
|
293 |
|
|
void
|
294 |
|
|
set_needs_dynsym_entry()
|
295 |
|
|
{ this->needs_dynsym_entry_ = true; }
|
296 |
|
|
|
297 |
|
|
// Return whether this symbol should be added to the dynamic symbol
|
298 |
|
|
// table.
|
299 |
|
|
bool
|
300 |
|
|
should_add_dynsym_entry(Symbol_table*) const;
|
301 |
|
|
|
302 |
|
|
// Return whether this symbol has been seen in a regular object.
|
303 |
|
|
bool
|
304 |
|
|
in_reg() const
|
305 |
|
|
{ return this->in_reg_; }
|
306 |
|
|
|
307 |
|
|
// Mark this symbol as having been seen in a regular object.
|
308 |
|
|
void
|
309 |
|
|
set_in_reg()
|
310 |
|
|
{ this->in_reg_ = true; }
|
311 |
|
|
|
312 |
|
|
// Return whether this symbol has been seen in a dynamic object.
|
313 |
|
|
bool
|
314 |
|
|
in_dyn() const
|
315 |
|
|
{ return this->in_dyn_; }
|
316 |
|
|
|
317 |
|
|
// Mark this symbol as having been seen in a dynamic object.
|
318 |
|
|
void
|
319 |
|
|
set_in_dyn()
|
320 |
|
|
{ this->in_dyn_ = true; }
|
321 |
|
|
|
322 |
|
|
// Return whether this symbol has been seen in a real ELF object.
|
323 |
|
|
// (IN_REG will return TRUE if the symbol has been seen in either
|
324 |
|
|
// a real ELF object or an object claimed by a plugin.)
|
325 |
|
|
bool
|
326 |
|
|
in_real_elf() const
|
327 |
|
|
{ return this->in_real_elf_; }
|
328 |
|
|
|
329 |
|
|
// Mark this symbol as having been seen in a real ELF object.
|
330 |
|
|
void
|
331 |
|
|
set_in_real_elf()
|
332 |
|
|
{ this->in_real_elf_ = true; }
|
333 |
|
|
|
334 |
|
|
// Return whether this symbol was defined in a section that was
|
335 |
|
|
// discarded from the link. This is used to control some error
|
336 |
|
|
// reporting.
|
337 |
|
|
bool
|
338 |
|
|
is_defined_in_discarded_section() const
|
339 |
|
|
{ return this->is_defined_in_discarded_section_; }
|
340 |
|
|
|
341 |
|
|
// Mark this symbol as having been defined in a discarded section.
|
342 |
|
|
void
|
343 |
|
|
set_is_defined_in_discarded_section()
|
344 |
|
|
{ this->is_defined_in_discarded_section_ = true; }
|
345 |
|
|
|
346 |
|
|
// Return the index of this symbol in the output file symbol table.
|
347 |
|
|
// A value of -1U means that this symbol is not going into the
|
348 |
|
|
// output file. This starts out as zero, and is set to a non-zero
|
349 |
|
|
// value by Symbol_table::finalize. It is an error to ask for the
|
350 |
|
|
// symbol table index before it has been set.
|
351 |
|
|
unsigned int
|
352 |
|
|
symtab_index() const
|
353 |
|
|
{
|
354 |
|
|
gold_assert(this->symtab_index_ != 0);
|
355 |
|
|
return this->symtab_index_;
|
356 |
|
|
}
|
357 |
|
|
|
358 |
|
|
// Set the index of the symbol in the output file symbol table.
|
359 |
|
|
void
|
360 |
|
|
set_symtab_index(unsigned int index)
|
361 |
|
|
{
|
362 |
|
|
gold_assert(index != 0);
|
363 |
|
|
this->symtab_index_ = index;
|
364 |
|
|
}
|
365 |
|
|
|
366 |
|
|
// Return whether this symbol already has an index in the output
|
367 |
|
|
// file symbol table.
|
368 |
|
|
bool
|
369 |
|
|
has_symtab_index() const
|
370 |
|
|
{ return this->symtab_index_ != 0; }
|
371 |
|
|
|
372 |
|
|
// Return the index of this symbol in the dynamic symbol table. A
|
373 |
|
|
// value of -1U means that this symbol is not going into the dynamic
|
374 |
|
|
// symbol table. This starts out as zero, and is set to a non-zero
|
375 |
|
|
// during Layout::finalize. It is an error to ask for the dynamic
|
376 |
|
|
// symbol table index before it has been set.
|
377 |
|
|
unsigned int
|
378 |
|
|
dynsym_index() const
|
379 |
|
|
{
|
380 |
|
|
gold_assert(this->dynsym_index_ != 0);
|
381 |
|
|
return this->dynsym_index_;
|
382 |
|
|
}
|
383 |
|
|
|
384 |
|
|
// Set the index of the symbol in the dynamic symbol table.
|
385 |
|
|
void
|
386 |
|
|
set_dynsym_index(unsigned int index)
|
387 |
|
|
{
|
388 |
|
|
gold_assert(index != 0);
|
389 |
|
|
this->dynsym_index_ = index;
|
390 |
|
|
}
|
391 |
|
|
|
392 |
|
|
// Return whether this symbol already has an index in the dynamic
|
393 |
|
|
// symbol table.
|
394 |
|
|
bool
|
395 |
|
|
has_dynsym_index() const
|
396 |
|
|
{ return this->dynsym_index_ != 0; }
|
397 |
|
|
|
398 |
|
|
// Return whether this symbol has an entry in the GOT section.
|
399 |
|
|
// For a TLS symbol, this GOT entry will hold its tp-relative offset.
|
400 |
|
|
bool
|
401 |
|
|
has_got_offset(unsigned int got_type) const
|
402 |
|
|
{ return this->got_offsets_.get_offset(got_type) != -1U; }
|
403 |
|
|
|
404 |
|
|
// Return the offset into the GOT section of this symbol.
|
405 |
|
|
unsigned int
|
406 |
|
|
got_offset(unsigned int got_type) const
|
407 |
|
|
{
|
408 |
|
|
unsigned int got_offset = this->got_offsets_.get_offset(got_type);
|
409 |
|
|
gold_assert(got_offset != -1U);
|
410 |
|
|
return got_offset;
|
411 |
|
|
}
|
412 |
|
|
|
413 |
|
|
// Set the GOT offset of this symbol.
|
414 |
|
|
void
|
415 |
|
|
set_got_offset(unsigned int got_type, unsigned int got_offset)
|
416 |
|
|
{ this->got_offsets_.set_offset(got_type, got_offset); }
|
417 |
|
|
|
418 |
|
|
// Return the GOT offset list.
|
419 |
|
|
const Got_offset_list*
|
420 |
|
|
got_offset_list() const
|
421 |
|
|
{ return this->got_offsets_.get_list(); }
|
422 |
|
|
|
423 |
|
|
// Return whether this symbol has an entry in the PLT section.
|
424 |
|
|
bool
|
425 |
|
|
has_plt_offset() const
|
426 |
|
|
{ return this->plt_offset_ != -1U; }
|
427 |
|
|
|
428 |
|
|
// Return the offset into the PLT section of this symbol.
|
429 |
|
|
unsigned int
|
430 |
|
|
plt_offset() const
|
431 |
|
|
{
|
432 |
|
|
gold_assert(this->has_plt_offset());
|
433 |
|
|
return this->plt_offset_;
|
434 |
|
|
}
|
435 |
|
|
|
436 |
|
|
// Set the PLT offset of this symbol.
|
437 |
|
|
void
|
438 |
|
|
set_plt_offset(unsigned int plt_offset)
|
439 |
|
|
{
|
440 |
|
|
gold_assert(plt_offset != -1U);
|
441 |
|
|
this->plt_offset_ = plt_offset;
|
442 |
|
|
}
|
443 |
|
|
|
444 |
|
|
// Return whether this dynamic symbol needs a special value in the
|
445 |
|
|
// dynamic symbol table.
|
446 |
|
|
bool
|
447 |
|
|
needs_dynsym_value() const
|
448 |
|
|
{ return this->needs_dynsym_value_; }
|
449 |
|
|
|
450 |
|
|
// Set that this dynamic symbol needs a special value in the dynamic
|
451 |
|
|
// symbol table.
|
452 |
|
|
void
|
453 |
|
|
set_needs_dynsym_value()
|
454 |
|
|
{
|
455 |
|
|
gold_assert(this->object()->is_dynamic());
|
456 |
|
|
this->needs_dynsym_value_ = true;
|
457 |
|
|
}
|
458 |
|
|
|
459 |
|
|
// Return true if the final value of this symbol is known at link
|
460 |
|
|
// time.
|
461 |
|
|
bool
|
462 |
|
|
final_value_is_known() const;
|
463 |
|
|
|
464 |
|
|
// Return true if SHNDX represents a common symbol. This depends on
|
465 |
|
|
// the target.
|
466 |
|
|
static bool
|
467 |
|
|
is_common_shndx(unsigned int shndx);
|
468 |
|
|
|
469 |
|
|
// Return whether this is a defined symbol (not undefined or
|
470 |
|
|
// common).
|
471 |
|
|
bool
|
472 |
|
|
is_defined() const
|
473 |
|
|
{
|
474 |
|
|
bool is_ordinary;
|
475 |
|
|
if (this->source_ != FROM_OBJECT)
|
476 |
|
|
return this->source_ != IS_UNDEFINED;
|
477 |
|
|
unsigned int shndx = this->shndx(&is_ordinary);
|
478 |
|
|
return (is_ordinary
|
479 |
|
|
? shndx != elfcpp::SHN_UNDEF
|
480 |
|
|
: !Symbol::is_common_shndx(shndx));
|
481 |
|
|
}
|
482 |
|
|
|
483 |
|
|
// Return true if this symbol is from a dynamic object.
|
484 |
|
|
bool
|
485 |
|
|
is_from_dynobj() const
|
486 |
|
|
{
|
487 |
|
|
return this->source_ == FROM_OBJECT && this->object()->is_dynamic();
|
488 |
|
|
}
|
489 |
|
|
|
490 |
|
|
// Return whether this is a placeholder symbol from a plugin object.
|
491 |
|
|
bool
|
492 |
|
|
is_placeholder() const
|
493 |
|
|
{
|
494 |
|
|
return this->source_ == FROM_OBJECT && this->object()->pluginobj() != NULL;
|
495 |
|
|
}
|
496 |
|
|
|
497 |
|
|
// Return whether this is an undefined symbol.
|
498 |
|
|
bool
|
499 |
|
|
is_undefined() const
|
500 |
|
|
{
|
501 |
|
|
bool is_ordinary;
|
502 |
|
|
return ((this->source_ == FROM_OBJECT
|
503 |
|
|
&& this->shndx(&is_ordinary) == elfcpp::SHN_UNDEF
|
504 |
|
|
&& is_ordinary)
|
505 |
|
|
|| this->source_ == IS_UNDEFINED);
|
506 |
|
|
}
|
507 |
|
|
|
508 |
|
|
// Return whether this is a weak undefined symbol.
|
509 |
|
|
bool
|
510 |
|
|
is_weak_undefined() const
|
511 |
|
|
{ return this->is_undefined() && this->binding() == elfcpp::STB_WEAK; }
|
512 |
|
|
|
513 |
|
|
// Return whether this is an absolute symbol.
|
514 |
|
|
bool
|
515 |
|
|
is_absolute() const
|
516 |
|
|
{
|
517 |
|
|
bool is_ordinary;
|
518 |
|
|
return ((this->source_ == FROM_OBJECT
|
519 |
|
|
&& this->shndx(&is_ordinary) == elfcpp::SHN_ABS
|
520 |
|
|
&& !is_ordinary)
|
521 |
|
|
|| this->source_ == IS_CONSTANT);
|
522 |
|
|
}
|
523 |
|
|
|
524 |
|
|
// Return whether this is a common symbol.
|
525 |
|
|
bool
|
526 |
|
|
is_common() const
|
527 |
|
|
{
|
528 |
|
|
if (this->source_ != FROM_OBJECT)
|
529 |
|
|
return false;
|
530 |
|
|
if (this->type_ == elfcpp::STT_COMMON)
|
531 |
|
|
return true;
|
532 |
|
|
bool is_ordinary;
|
533 |
|
|
unsigned int shndx = this->shndx(&is_ordinary);
|
534 |
|
|
return !is_ordinary && Symbol::is_common_shndx(shndx);
|
535 |
|
|
}
|
536 |
|
|
|
537 |
|
|
// Return whether this symbol can be seen outside this object.
|
538 |
|
|
bool
|
539 |
|
|
is_externally_visible() const
|
540 |
|
|
{
|
541 |
159 |
khays |
return ((this->visibility_ == elfcpp::STV_DEFAULT
|
542 |
|
|
|| this->visibility_ == elfcpp::STV_PROTECTED)
|
543 |
|
|
&& !this->is_forced_local_);
|
544 |
27 |
khays |
}
|
545 |
|
|
|
546 |
|
|
// Return true if this symbol can be preempted by a definition in
|
547 |
|
|
// another link unit.
|
548 |
|
|
bool
|
549 |
|
|
is_preemptible() const
|
550 |
|
|
{
|
551 |
|
|
// It doesn't make sense to ask whether a symbol defined in
|
552 |
|
|
// another object is preemptible.
|
553 |
|
|
gold_assert(!this->is_from_dynobj());
|
554 |
|
|
|
555 |
|
|
// It doesn't make sense to ask whether an undefined symbol
|
556 |
|
|
// is preemptible.
|
557 |
|
|
gold_assert(!this->is_undefined());
|
558 |
|
|
|
559 |
|
|
// If a symbol does not have default visibility, it can not be
|
560 |
|
|
// seen outside this link unit and therefore is not preemptible.
|
561 |
|
|
if (this->visibility_ != elfcpp::STV_DEFAULT)
|
562 |
|
|
return false;
|
563 |
|
|
|
564 |
|
|
// If this symbol has been forced to be a local symbol by a
|
565 |
|
|
// version script, then it is not visible outside this link unit
|
566 |
|
|
// and is not preemptible.
|
567 |
|
|
if (this->is_forced_local_)
|
568 |
|
|
return false;
|
569 |
|
|
|
570 |
|
|
// If we are not producing a shared library, then nothing is
|
571 |
|
|
// preemptible.
|
572 |
|
|
if (!parameters->options().shared())
|
573 |
|
|
return false;
|
574 |
|
|
|
575 |
|
|
// If the user used -Bsymbolic, then nothing is preemptible.
|
576 |
|
|
if (parameters->options().Bsymbolic())
|
577 |
|
|
return false;
|
578 |
|
|
|
579 |
|
|
// If the user used -Bsymbolic-functions, then functions are not
|
580 |
|
|
// preemptible. We explicitly check for not being STT_OBJECT,
|
581 |
|
|
// rather than for being STT_FUNC, because that is what the GNU
|
582 |
|
|
// linker does.
|
583 |
|
|
if (this->type() != elfcpp::STT_OBJECT
|
584 |
|
|
&& parameters->options().Bsymbolic_functions())
|
585 |
|
|
return false;
|
586 |
|
|
|
587 |
|
|
// Otherwise the symbol is preemptible.
|
588 |
|
|
return true;
|
589 |
|
|
}
|
590 |
|
|
|
591 |
|
|
// Return true if this symbol is a function that needs a PLT entry.
|
592 |
|
|
bool
|
593 |
|
|
needs_plt_entry() const
|
594 |
|
|
{
|
595 |
|
|
// An undefined symbol from an executable does not need a PLT entry.
|
596 |
|
|
if (this->is_undefined() && !parameters->options().shared())
|
597 |
|
|
return false;
|
598 |
|
|
|
599 |
|
|
// An STT_GNU_IFUNC symbol always needs a PLT entry, even when
|
600 |
|
|
// doing a static link.
|
601 |
|
|
if (this->type() == elfcpp::STT_GNU_IFUNC)
|
602 |
|
|
return true;
|
603 |
|
|
|
604 |
|
|
// We only need a PLT entry for a function.
|
605 |
|
|
if (!this->is_func())
|
606 |
|
|
return false;
|
607 |
|
|
|
608 |
|
|
// If we're doing a static link or a -pie link, we don't create
|
609 |
|
|
// PLT entries.
|
610 |
|
|
if (parameters->doing_static_link()
|
611 |
|
|
|| parameters->options().pie())
|
612 |
|
|
return false;
|
613 |
|
|
|
614 |
|
|
// We need a PLT entry if the function is defined in a dynamic
|
615 |
|
|
// object, or is undefined when building a shared object, or if it
|
616 |
|
|
// is subject to pre-emption.
|
617 |
|
|
return (this->is_from_dynobj()
|
618 |
|
|
|| this->is_undefined()
|
619 |
|
|
|| this->is_preemptible());
|
620 |
|
|
}
|
621 |
|
|
|
622 |
|
|
// When determining whether a reference to a symbol needs a dynamic
|
623 |
|
|
// relocation, we need to know several things about the reference.
|
624 |
|
|
// These flags may be or'ed together. 0 means that the symbol
|
625 |
|
|
// isn't referenced at all.
|
626 |
|
|
enum Reference_flags
|
627 |
|
|
{
|
628 |
|
|
// A reference to the symbol's absolute address. This includes
|
629 |
|
|
// references that cause an absolute address to be stored in the GOT.
|
630 |
|
|
ABSOLUTE_REF = 1,
|
631 |
|
|
// A reference that calculates the offset of the symbol from some
|
632 |
|
|
// anchor point, such as the PC or GOT.
|
633 |
|
|
RELATIVE_REF = 2,
|
634 |
|
|
// A TLS-related reference.
|
635 |
|
|
TLS_REF = 4,
|
636 |
|
|
// A reference that can always be treated as a function call.
|
637 |
|
|
FUNCTION_CALL = 8
|
638 |
|
|
};
|
639 |
|
|
|
640 |
|
|
// Given a direct absolute or pc-relative static relocation against
|
641 |
|
|
// the global symbol, this function returns whether a dynamic relocation
|
642 |
|
|
// is needed.
|
643 |
|
|
|
644 |
|
|
bool
|
645 |
|
|
needs_dynamic_reloc(int flags) const
|
646 |
|
|
{
|
647 |
|
|
// No dynamic relocations in a static link!
|
648 |
|
|
if (parameters->doing_static_link())
|
649 |
|
|
return false;
|
650 |
|
|
|
651 |
|
|
// A reference to an undefined symbol from an executable should be
|
652 |
|
|
// statically resolved to 0, and does not need a dynamic relocation.
|
653 |
|
|
// This matches gnu ld behavior.
|
654 |
|
|
if (this->is_undefined() && !parameters->options().shared())
|
655 |
|
|
return false;
|
656 |
|
|
|
657 |
|
|
// A reference to an absolute symbol does not need a dynamic relocation.
|
658 |
|
|
if (this->is_absolute())
|
659 |
|
|
return false;
|
660 |
|
|
|
661 |
|
|
// An absolute reference within a position-independent output file
|
662 |
|
|
// will need a dynamic relocation.
|
663 |
|
|
if ((flags & ABSOLUTE_REF)
|
664 |
|
|
&& parameters->options().output_is_position_independent())
|
665 |
|
|
return true;
|
666 |
|
|
|
667 |
|
|
// A function call that can branch to a local PLT entry does not need
|
668 |
|
|
// a dynamic relocation.
|
669 |
|
|
if ((flags & FUNCTION_CALL) && this->has_plt_offset())
|
670 |
|
|
return false;
|
671 |
|
|
|
672 |
|
|
// A reference to any PLT entry in a non-position-independent executable
|
673 |
|
|
// does not need a dynamic relocation.
|
674 |
|
|
if (!parameters->options().output_is_position_independent()
|
675 |
|
|
&& this->has_plt_offset())
|
676 |
|
|
return false;
|
677 |
|
|
|
678 |
|
|
// A reference to a symbol defined in a dynamic object or to a
|
679 |
|
|
// symbol that is preemptible will need a dynamic relocation.
|
680 |
|
|
if (this->is_from_dynobj()
|
681 |
|
|
|| this->is_undefined()
|
682 |
|
|
|| this->is_preemptible())
|
683 |
|
|
return true;
|
684 |
|
|
|
685 |
|
|
// For all other cases, return FALSE.
|
686 |
|
|
return false;
|
687 |
|
|
}
|
688 |
|
|
|
689 |
|
|
// Whether we should use the PLT offset associated with a symbol for
|
690 |
|
|
// a relocation. FLAGS is a set of Reference_flags.
|
691 |
|
|
|
692 |
|
|
bool
|
693 |
|
|
use_plt_offset(int flags) const
|
694 |
|
|
{
|
695 |
|
|
// If the symbol doesn't have a PLT offset, then naturally we
|
696 |
|
|
// don't want to use it.
|
697 |
|
|
if (!this->has_plt_offset())
|
698 |
|
|
return false;
|
699 |
|
|
|
700 |
|
|
// For a STT_GNU_IFUNC symbol we always have to use the PLT entry.
|
701 |
|
|
if (this->type() == elfcpp::STT_GNU_IFUNC)
|
702 |
|
|
return true;
|
703 |
|
|
|
704 |
|
|
// If we are going to generate a dynamic relocation, then we will
|
705 |
|
|
// wind up using that, so no need to use the PLT entry.
|
706 |
|
|
if (this->needs_dynamic_reloc(flags))
|
707 |
|
|
return false;
|
708 |
|
|
|
709 |
|
|
// If the symbol is from a dynamic object, we need to use the PLT
|
710 |
|
|
// entry.
|
711 |
|
|
if (this->is_from_dynobj())
|
712 |
|
|
return true;
|
713 |
|
|
|
714 |
|
|
// If we are generating a shared object, and this symbol is
|
715 |
|
|
// undefined or preemptible, we need to use the PLT entry.
|
716 |
|
|
if (parameters->options().shared()
|
717 |
|
|
&& (this->is_undefined() || this->is_preemptible()))
|
718 |
|
|
return true;
|
719 |
|
|
|
720 |
|
|
// If this is a call to a weak undefined symbol, we need to use
|
721 |
|
|
// the PLT entry; the symbol may be defined by a library loaded
|
722 |
|
|
// at runtime.
|
723 |
|
|
if ((flags & FUNCTION_CALL) && this->is_weak_undefined())
|
724 |
|
|
return true;
|
725 |
|
|
|
726 |
|
|
// Otherwise we can use the regular definition.
|
727 |
|
|
return false;
|
728 |
|
|
}
|
729 |
|
|
|
730 |
|
|
// Given a direct absolute static relocation against
|
731 |
|
|
// the global symbol, where a dynamic relocation is needed, this
|
732 |
|
|
// function returns whether a relative dynamic relocation can be used.
|
733 |
|
|
// The caller must determine separately whether the static relocation
|
734 |
|
|
// is compatible with a relative relocation.
|
735 |
|
|
|
736 |
|
|
bool
|
737 |
|
|
can_use_relative_reloc(bool is_function_call) const
|
738 |
|
|
{
|
739 |
|
|
// A function call that can branch to a local PLT entry can
|
740 |
|
|
// use a RELATIVE relocation.
|
741 |
|
|
if (is_function_call && this->has_plt_offset())
|
742 |
|
|
return true;
|
743 |
|
|
|
744 |
|
|
// A reference to a symbol defined in a dynamic object or to a
|
745 |
|
|
// symbol that is preemptible can not use a RELATIVE relocation.
|
746 |
|
|
if (this->is_from_dynobj()
|
747 |
|
|
|| this->is_undefined()
|
748 |
|
|
|| this->is_preemptible())
|
749 |
|
|
return false;
|
750 |
|
|
|
751 |
|
|
// For all other cases, return TRUE.
|
752 |
|
|
return true;
|
753 |
|
|
}
|
754 |
|
|
|
755 |
|
|
// Return the output section where this symbol is defined. Return
|
756 |
|
|
// NULL if the symbol has an absolute value.
|
757 |
|
|
Output_section*
|
758 |
|
|
output_section() const;
|
759 |
|
|
|
760 |
|
|
// Set the symbol's output section. This is used for symbols
|
761 |
|
|
// defined in scripts. This should only be called after the symbol
|
762 |
|
|
// table has been finalized.
|
763 |
|
|
void
|
764 |
|
|
set_output_section(Output_section*);
|
765 |
|
|
|
766 |
|
|
// Return whether there should be a warning for references to this
|
767 |
|
|
// symbol.
|
768 |
|
|
bool
|
769 |
|
|
has_warning() const
|
770 |
|
|
{ return this->has_warning_; }
|
771 |
|
|
|
772 |
|
|
// Mark this symbol as having a warning.
|
773 |
|
|
void
|
774 |
|
|
set_has_warning()
|
775 |
|
|
{ this->has_warning_ = true; }
|
776 |
|
|
|
777 |
|
|
// Return whether this symbol is defined by a COPY reloc from a
|
778 |
|
|
// dynamic object.
|
779 |
|
|
bool
|
780 |
|
|
is_copied_from_dynobj() const
|
781 |
|
|
{ return this->is_copied_from_dynobj_; }
|
782 |
|
|
|
783 |
|
|
// Mark this symbol as defined by a COPY reloc.
|
784 |
|
|
void
|
785 |
|
|
set_is_copied_from_dynobj()
|
786 |
|
|
{ this->is_copied_from_dynobj_ = true; }
|
787 |
|
|
|
788 |
|
|
// Return whether this symbol is forced to visibility STB_LOCAL
|
789 |
|
|
// by a "local:" entry in a version script.
|
790 |
|
|
bool
|
791 |
|
|
is_forced_local() const
|
792 |
|
|
{ return this->is_forced_local_; }
|
793 |
|
|
|
794 |
|
|
// Mark this symbol as forced to STB_LOCAL visibility.
|
795 |
|
|
void
|
796 |
|
|
set_is_forced_local()
|
797 |
|
|
{ this->is_forced_local_ = true; }
|
798 |
|
|
|
799 |
|
|
// Return true if this may need a COPY relocation.
|
800 |
|
|
// References from an executable object to non-function symbols
|
801 |
|
|
// defined in a dynamic object may need a COPY relocation.
|
802 |
|
|
bool
|
803 |
|
|
may_need_copy_reloc() const
|
804 |
|
|
{
|
805 |
|
|
return (!parameters->options().output_is_position_independent()
|
806 |
|
|
&& parameters->options().copyreloc()
|
807 |
|
|
&& this->is_from_dynobj()
|
808 |
|
|
&& !this->is_func());
|
809 |
|
|
}
|
810 |
|
|
|
811 |
148 |
khays |
// Return true if this symbol was predefined by the linker.
|
812 |
|
|
bool
|
813 |
|
|
is_predefined() const
|
814 |
|
|
{ return this->is_predefined_; }
|
815 |
|
|
|
816 |
27 |
khays |
protected:
|
817 |
|
|
// Instances of this class should always be created at a specific
|
818 |
|
|
// size.
|
819 |
|
|
Symbol()
|
820 |
|
|
{ memset(this, 0, sizeof *this); }
|
821 |
|
|
|
822 |
|
|
// Initialize the general fields.
|
823 |
|
|
void
|
824 |
|
|
init_fields(const char* name, const char* version,
|
825 |
|
|
elfcpp::STT type, elfcpp::STB binding,
|
826 |
|
|
elfcpp::STV visibility, unsigned char nonvis);
|
827 |
|
|
|
828 |
|
|
// Initialize fields from an ELF symbol in OBJECT. ST_SHNDX is the
|
829 |
|
|
// section index, IS_ORDINARY is whether it is a normal section
|
830 |
|
|
// index rather than a special code.
|
831 |
|
|
template<int size, bool big_endian>
|
832 |
|
|
void
|
833 |
|
|
init_base_object(const char* name, const char* version, Object* object,
|
834 |
|
|
const elfcpp::Sym<size, big_endian>&, unsigned int st_shndx,
|
835 |
|
|
bool is_ordinary);
|
836 |
|
|
|
837 |
|
|
// Initialize fields for an Output_data.
|
838 |
|
|
void
|
839 |
|
|
init_base_output_data(const char* name, const char* version, Output_data*,
|
840 |
|
|
elfcpp::STT, elfcpp::STB, elfcpp::STV,
|
841 |
148 |
khays |
unsigned char nonvis, bool offset_is_from_end,
|
842 |
|
|
bool is_predefined);
|
843 |
27 |
khays |
|
844 |
|
|
// Initialize fields for an Output_segment.
|
845 |
|
|
void
|
846 |
|
|
init_base_output_segment(const char* name, const char* version,
|
847 |
|
|
Output_segment* os, elfcpp::STT type,
|
848 |
|
|
elfcpp::STB binding, elfcpp::STV visibility,
|
849 |
|
|
unsigned char nonvis,
|
850 |
148 |
khays |
Segment_offset_base offset_base,
|
851 |
|
|
bool is_predefined);
|
852 |
27 |
khays |
|
853 |
|
|
// Initialize fields for a constant.
|
854 |
|
|
void
|
855 |
|
|
init_base_constant(const char* name, const char* version, elfcpp::STT type,
|
856 |
|
|
elfcpp::STB binding, elfcpp::STV visibility,
|
857 |
148 |
khays |
unsigned char nonvis, bool is_predefined);
|
858 |
27 |
khays |
|
859 |
|
|
// Initialize fields for an undefined symbol.
|
860 |
|
|
void
|
861 |
|
|
init_base_undefined(const char* name, const char* version, elfcpp::STT type,
|
862 |
|
|
elfcpp::STB binding, elfcpp::STV visibility,
|
863 |
|
|
unsigned char nonvis);
|
864 |
|
|
|
865 |
|
|
// Override existing symbol.
|
866 |
|
|
template<int size, bool big_endian>
|
867 |
|
|
void
|
868 |
|
|
override_base(const elfcpp::Sym<size, big_endian>&, unsigned int st_shndx,
|
869 |
|
|
bool is_ordinary, Object* object, const char* version);
|
870 |
|
|
|
871 |
|
|
// Override existing symbol with a special symbol.
|
872 |
|
|
void
|
873 |
|
|
override_base_with_special(const Symbol* from);
|
874 |
|
|
|
875 |
|
|
// Override symbol version.
|
876 |
|
|
void
|
877 |
|
|
override_version(const char* version);
|
878 |
|
|
|
879 |
|
|
// Allocate a common symbol by giving it a location in the output
|
880 |
|
|
// file.
|
881 |
|
|
void
|
882 |
|
|
allocate_base_common(Output_data*);
|
883 |
|
|
|
884 |
|
|
private:
|
885 |
|
|
Symbol(const Symbol&);
|
886 |
|
|
Symbol& operator=(const Symbol&);
|
887 |
|
|
|
888 |
|
|
// Symbol name (expected to point into a Stringpool).
|
889 |
|
|
const char* name_;
|
890 |
|
|
// Symbol version (expected to point into a Stringpool). This may
|
891 |
|
|
// be NULL.
|
892 |
|
|
const char* version_;
|
893 |
|
|
|
894 |
|
|
union
|
895 |
|
|
{
|
896 |
|
|
// This struct is used if SOURCE_ == FROM_OBJECT.
|
897 |
|
|
struct
|
898 |
|
|
{
|
899 |
|
|
// Object in which symbol is defined, or in which it was first
|
900 |
|
|
// seen.
|
901 |
|
|
Object* object;
|
902 |
|
|
// Section number in object_ in which symbol is defined.
|
903 |
|
|
unsigned int shndx;
|
904 |
|
|
} from_object;
|
905 |
|
|
|
906 |
|
|
// This struct is used if SOURCE_ == IN_OUTPUT_DATA.
|
907 |
|
|
struct
|
908 |
|
|
{
|
909 |
|
|
// Output_data in which symbol is defined. Before
|
910 |
|
|
// Layout::finalize the symbol's value is an offset within the
|
911 |
|
|
// Output_data.
|
912 |
|
|
Output_data* output_data;
|
913 |
|
|
// True if the offset is from the end, false if the offset is
|
914 |
|
|
// from the beginning.
|
915 |
|
|
bool offset_is_from_end;
|
916 |
|
|
} in_output_data;
|
917 |
|
|
|
918 |
|
|
// This struct is used if SOURCE_ == IN_OUTPUT_SEGMENT.
|
919 |
|
|
struct
|
920 |
|
|
{
|
921 |
|
|
// Output_segment in which the symbol is defined. Before
|
922 |
|
|
// Layout::finalize the symbol's value is an offset.
|
923 |
|
|
Output_segment* output_segment;
|
924 |
|
|
// The base to use for the offset before Layout::finalize.
|
925 |
|
|
Segment_offset_base offset_base;
|
926 |
|
|
} in_output_segment;
|
927 |
|
|
} u_;
|
928 |
|
|
|
929 |
|
|
// The index of this symbol in the output file. If the symbol is
|
930 |
|
|
// not going into the output file, this value is -1U. This field
|
931 |
|
|
// starts as always holding zero. It is set to a non-zero value by
|
932 |
|
|
// Symbol_table::finalize.
|
933 |
|
|
unsigned int symtab_index_;
|
934 |
|
|
|
935 |
|
|
// The index of this symbol in the dynamic symbol table. If the
|
936 |
|
|
// symbol is not going into the dynamic symbol table, this value is
|
937 |
|
|
// -1U. This field starts as always holding zero. It is set to a
|
938 |
|
|
// non-zero value during Layout::finalize.
|
939 |
|
|
unsigned int dynsym_index_;
|
940 |
|
|
|
941 |
|
|
// The GOT section entries for this symbol. A symbol may have more
|
942 |
|
|
// than one GOT offset (e.g., when mixing modules compiled with two
|
943 |
|
|
// different TLS models), but will usually have at most one.
|
944 |
|
|
Got_offset_list got_offsets_;
|
945 |
|
|
|
946 |
|
|
// If this symbol has an entry in the PLT section, then this is the
|
947 |
|
|
// offset from the start of the PLT section. This is -1U if there
|
948 |
|
|
// is no PLT entry.
|
949 |
|
|
unsigned int plt_offset_;
|
950 |
|
|
|
951 |
|
|
// Symbol type (bits 0 to 3).
|
952 |
|
|
elfcpp::STT type_ : 4;
|
953 |
|
|
// Symbol binding (bits 4 to 7).
|
954 |
|
|
elfcpp::STB binding_ : 4;
|
955 |
|
|
// Symbol visibility (bits 8 to 9).
|
956 |
|
|
elfcpp::STV visibility_ : 2;
|
957 |
|
|
// Rest of symbol st_other field (bits 10 to 15).
|
958 |
|
|
unsigned int nonvis_ : 6;
|
959 |
|
|
// The type of symbol (bits 16 to 18).
|
960 |
|
|
Source source_ : 3;
|
961 |
|
|
// True if this is the default version of the symbol (bit 19).
|
962 |
|
|
bool is_def_ : 1;
|
963 |
|
|
// True if this symbol really forwards to another symbol. This is
|
964 |
|
|
// used when we discover after the fact that two different entries
|
965 |
|
|
// in the hash table really refer to the same symbol. This will
|
966 |
|
|
// never be set for a symbol found in the hash table, but may be set
|
967 |
|
|
// for a symbol found in the list of symbols attached to an Object.
|
968 |
|
|
// It forwards to the symbol found in the forwarders_ map of
|
969 |
|
|
// Symbol_table (bit 20).
|
970 |
|
|
bool is_forwarder_ : 1;
|
971 |
|
|
// True if the symbol has an alias in the weak_aliases table in
|
972 |
|
|
// Symbol_table (bit 21).
|
973 |
|
|
bool has_alias_ : 1;
|
974 |
|
|
// True if this symbol needs to be in the dynamic symbol table (bit
|
975 |
|
|
// 22).
|
976 |
|
|
bool needs_dynsym_entry_ : 1;
|
977 |
|
|
// True if we've seen this symbol in a regular object (bit 23).
|
978 |
|
|
bool in_reg_ : 1;
|
979 |
|
|
// True if we've seen this symbol in a dynamic object (bit 24).
|
980 |
|
|
bool in_dyn_ : 1;
|
981 |
|
|
// True if this is a dynamic symbol which needs a special value in
|
982 |
|
|
// the dynamic symbol table (bit 25).
|
983 |
|
|
bool needs_dynsym_value_ : 1;
|
984 |
|
|
// True if there is a warning for this symbol (bit 26).
|
985 |
|
|
bool has_warning_ : 1;
|
986 |
|
|
// True if we are using a COPY reloc for this symbol, so that the
|
987 |
|
|
// real definition lives in a dynamic object (bit 27).
|
988 |
|
|
bool is_copied_from_dynobj_ : 1;
|
989 |
|
|
// True if this symbol was forced to local visibility by a version
|
990 |
|
|
// script (bit 28).
|
991 |
|
|
bool is_forced_local_ : 1;
|
992 |
|
|
// True if the field u_.from_object.shndx is an ordinary section
|
993 |
|
|
// index, not one of the special codes from SHN_LORESERVE to
|
994 |
|
|
// SHN_HIRESERVE (bit 29).
|
995 |
|
|
bool is_ordinary_shndx_ : 1;
|
996 |
|
|
// True if we've seen this symbol in a real ELF object (bit 30).
|
997 |
|
|
bool in_real_elf_ : 1;
|
998 |
|
|
// True if this symbol is defined in a section which was discarded
|
999 |
|
|
// (bit 31).
|
1000 |
|
|
bool is_defined_in_discarded_section_ : 1;
|
1001 |
|
|
// True if UNDEF_BINDING_WEAK_ has been set (bit 32).
|
1002 |
|
|
bool undef_binding_set_ : 1;
|
1003 |
|
|
// True if this symbol was a weak undef resolved by a dynamic def
|
1004 |
|
|
// (bit 33).
|
1005 |
|
|
bool undef_binding_weak_ : 1;
|
1006 |
148 |
khays |
// True if this symbol is a predefined linker symbol (bit 34).
|
1007 |
|
|
bool is_predefined_ : 1;
|
1008 |
27 |
khays |
};
|
1009 |
|
|
|
1010 |
|
|
// The parts of a symbol which are size specific. Using a template
|
1011 |
|
|
// derived class like this helps us use less space on a 32-bit system.
|
1012 |
|
|
|
1013 |
|
|
template<int size>
|
1014 |
|
|
class Sized_symbol : public Symbol
|
1015 |
|
|
{
|
1016 |
|
|
public:
|
1017 |
|
|
typedef typename elfcpp::Elf_types<size>::Elf_Addr Value_type;
|
1018 |
|
|
typedef typename elfcpp::Elf_types<size>::Elf_WXword Size_type;
|
1019 |
|
|
|
1020 |
|
|
Sized_symbol()
|
1021 |
|
|
{ }
|
1022 |
|
|
|
1023 |
|
|
// Initialize fields from an ELF symbol in OBJECT. ST_SHNDX is the
|
1024 |
|
|
// section index, IS_ORDINARY is whether it is a normal section
|
1025 |
|
|
// index rather than a special code.
|
1026 |
|
|
template<bool big_endian>
|
1027 |
|
|
void
|
1028 |
|
|
init_object(const char* name, const char* version, Object* object,
|
1029 |
|
|
const elfcpp::Sym<size, big_endian>&, unsigned int st_shndx,
|
1030 |
|
|
bool is_ordinary);
|
1031 |
|
|
|
1032 |
|
|
// Initialize fields for an Output_data.
|
1033 |
|
|
void
|
1034 |
|
|
init_output_data(const char* name, const char* version, Output_data*,
|
1035 |
|
|
Value_type value, Size_type symsize, elfcpp::STT,
|
1036 |
|
|
elfcpp::STB, elfcpp::STV, unsigned char nonvis,
|
1037 |
148 |
khays |
bool offset_is_from_end, bool is_predefined);
|
1038 |
27 |
khays |
|
1039 |
|
|
// Initialize fields for an Output_segment.
|
1040 |
|
|
void
|
1041 |
|
|
init_output_segment(const char* name, const char* version, Output_segment*,
|
1042 |
|
|
Value_type value, Size_type symsize, elfcpp::STT,
|
1043 |
|
|
elfcpp::STB, elfcpp::STV, unsigned char nonvis,
|
1044 |
148 |
khays |
Segment_offset_base offset_base, bool is_predefined);
|
1045 |
27 |
khays |
|
1046 |
|
|
// Initialize fields for a constant.
|
1047 |
|
|
void
|
1048 |
|
|
init_constant(const char* name, const char* version, Value_type value,
|
1049 |
|
|
Size_type symsize, elfcpp::STT, elfcpp::STB, elfcpp::STV,
|
1050 |
148 |
khays |
unsigned char nonvis, bool is_predefined);
|
1051 |
27 |
khays |
|
1052 |
|
|
// Initialize fields for an undefined symbol.
|
1053 |
|
|
void
|
1054 |
|
|
init_undefined(const char* name, const char* version, elfcpp::STT,
|
1055 |
|
|
elfcpp::STB, elfcpp::STV, unsigned char nonvis);
|
1056 |
|
|
|
1057 |
|
|
// Override existing symbol.
|
1058 |
|
|
template<bool big_endian>
|
1059 |
|
|
void
|
1060 |
|
|
override(const elfcpp::Sym<size, big_endian>&, unsigned int st_shndx,
|
1061 |
|
|
bool is_ordinary, Object* object, const char* version);
|
1062 |
|
|
|
1063 |
|
|
// Override existing symbol with a special symbol.
|
1064 |
|
|
void
|
1065 |
|
|
override_with_special(const Sized_symbol<size>*);
|
1066 |
|
|
|
1067 |
|
|
// Return the symbol's value.
|
1068 |
|
|
Value_type
|
1069 |
|
|
value() const
|
1070 |
|
|
{ return this->value_; }
|
1071 |
|
|
|
1072 |
|
|
// Return the symbol's size (we can't call this 'size' because that
|
1073 |
|
|
// is a template parameter).
|
1074 |
|
|
Size_type
|
1075 |
|
|
symsize() const
|
1076 |
|
|
{ return this->symsize_; }
|
1077 |
|
|
|
1078 |
|
|
// Set the symbol size. This is used when resolving common symbols.
|
1079 |
|
|
void
|
1080 |
|
|
set_symsize(Size_type symsize)
|
1081 |
|
|
{ this->symsize_ = symsize; }
|
1082 |
|
|
|
1083 |
|
|
// Set the symbol value. This is called when we store the final
|
1084 |
|
|
// values of the symbols into the symbol table.
|
1085 |
|
|
void
|
1086 |
|
|
set_value(Value_type value)
|
1087 |
|
|
{ this->value_ = value; }
|
1088 |
|
|
|
1089 |
|
|
// Allocate a common symbol by giving it a location in the output
|
1090 |
|
|
// file.
|
1091 |
|
|
void
|
1092 |
|
|
allocate_common(Output_data*, Value_type value);
|
1093 |
|
|
|
1094 |
|
|
private:
|
1095 |
|
|
Sized_symbol(const Sized_symbol&);
|
1096 |
|
|
Sized_symbol& operator=(const Sized_symbol&);
|
1097 |
|
|
|
1098 |
|
|
// Symbol value. Before Layout::finalize this is the offset in the
|
1099 |
|
|
// input section. This is set to the final value during
|
1100 |
|
|
// Layout::finalize.
|
1101 |
|
|
Value_type value_;
|
1102 |
|
|
// Symbol size.
|
1103 |
|
|
Size_type symsize_;
|
1104 |
|
|
};
|
1105 |
|
|
|
1106 |
|
|
// A struct describing a symbol defined by the linker, where the value
|
1107 |
|
|
// of the symbol is defined based on an output section. This is used
|
1108 |
|
|
// for symbols defined by the linker, like "_init_array_start".
|
1109 |
|
|
|
1110 |
|
|
struct Define_symbol_in_section
|
1111 |
|
|
{
|
1112 |
|
|
// The symbol name.
|
1113 |
|
|
const char* name;
|
1114 |
|
|
// The name of the output section with which this symbol should be
|
1115 |
|
|
// associated. If there is no output section with that name, the
|
1116 |
|
|
// symbol will be defined as zero.
|
1117 |
|
|
const char* output_section;
|
1118 |
|
|
// The offset of the symbol within the output section. This is an
|
1119 |
|
|
// offset from the start of the output section, unless start_at_end
|
1120 |
|
|
// is true, in which case this is an offset from the end of the
|
1121 |
|
|
// output section.
|
1122 |
|
|
uint64_t value;
|
1123 |
|
|
// The size of the symbol.
|
1124 |
|
|
uint64_t size;
|
1125 |
|
|
// The symbol type.
|
1126 |
|
|
elfcpp::STT type;
|
1127 |
|
|
// The symbol binding.
|
1128 |
|
|
elfcpp::STB binding;
|
1129 |
|
|
// The symbol visibility.
|
1130 |
|
|
elfcpp::STV visibility;
|
1131 |
|
|
// The rest of the st_other field.
|
1132 |
|
|
unsigned char nonvis;
|
1133 |
|
|
// If true, the value field is an offset from the end of the output
|
1134 |
|
|
// section.
|
1135 |
|
|
bool offset_is_from_end;
|
1136 |
|
|
// If true, this symbol is defined only if we see a reference to it.
|
1137 |
|
|
bool only_if_ref;
|
1138 |
|
|
};
|
1139 |
|
|
|
1140 |
|
|
// A struct describing a symbol defined by the linker, where the value
|
1141 |
|
|
// of the symbol is defined based on a segment. This is used for
|
1142 |
|
|
// symbols defined by the linker, like "_end". We describe the
|
1143 |
|
|
// segment with which the symbol should be associated by its
|
1144 |
|
|
// characteristics. If no segment meets these characteristics, the
|
1145 |
|
|
// symbol will be defined as zero. If there is more than one segment
|
1146 |
|
|
// which meets these characteristics, we will use the first one.
|
1147 |
|
|
|
1148 |
|
|
struct Define_symbol_in_segment
|
1149 |
|
|
{
|
1150 |
|
|
// The symbol name.
|
1151 |
|
|
const char* name;
|
1152 |
|
|
// The segment type where the symbol should be defined, typically
|
1153 |
|
|
// PT_LOAD.
|
1154 |
|
|
elfcpp::PT segment_type;
|
1155 |
|
|
// Bitmask of segment flags which must be set.
|
1156 |
|
|
elfcpp::PF segment_flags_set;
|
1157 |
|
|
// Bitmask of segment flags which must be clear.
|
1158 |
|
|
elfcpp::PF segment_flags_clear;
|
1159 |
|
|
// The offset of the symbol within the segment. The offset is
|
1160 |
|
|
// calculated from the position set by offset_base.
|
1161 |
|
|
uint64_t value;
|
1162 |
|
|
// The size of the symbol.
|
1163 |
|
|
uint64_t size;
|
1164 |
|
|
// The symbol type.
|
1165 |
|
|
elfcpp::STT type;
|
1166 |
|
|
// The symbol binding.
|
1167 |
|
|
elfcpp::STB binding;
|
1168 |
|
|
// The symbol visibility.
|
1169 |
|
|
elfcpp::STV visibility;
|
1170 |
|
|
// The rest of the st_other field.
|
1171 |
|
|
unsigned char nonvis;
|
1172 |
|
|
// The base from which we compute the offset.
|
1173 |
|
|
Symbol::Segment_offset_base offset_base;
|
1174 |
|
|
// If true, this symbol is defined only if we see a reference to it.
|
1175 |
|
|
bool only_if_ref;
|
1176 |
|
|
};
|
1177 |
|
|
|
1178 |
|
|
// This class manages warnings. Warnings are a GNU extension. When
|
1179 |
|
|
// we see a section named .gnu.warning.SYM in an object file, and if
|
1180 |
|
|
// we wind using the definition of SYM from that object file, then we
|
1181 |
|
|
// will issue a warning for any relocation against SYM from a
|
1182 |
|
|
// different object file. The text of the warning is the contents of
|
1183 |
|
|
// the section. This is not precisely the definition used by the old
|
1184 |
|
|
// GNU linker; the old GNU linker treated an occurrence of
|
1185 |
|
|
// .gnu.warning.SYM as defining a warning symbol. A warning symbol
|
1186 |
|
|
// would trigger a warning on any reference. However, it was
|
1187 |
|
|
// inconsistent in that a warning in a dynamic object only triggered
|
1188 |
|
|
// if there was no definition in a regular object. This linker is
|
1189 |
|
|
// different in that we only issue a warning if we use the symbol
|
1190 |
|
|
// definition from the same object file as the warning section.
|
1191 |
|
|
|
1192 |
|
|
class Warnings
|
1193 |
|
|
{
|
1194 |
|
|
public:
|
1195 |
|
|
Warnings()
|
1196 |
|
|
: warnings_()
|
1197 |
|
|
{ }
|
1198 |
|
|
|
1199 |
|
|
// Add a warning for symbol NAME in object OBJ. WARNING is the text
|
1200 |
|
|
// of the warning.
|
1201 |
|
|
void
|
1202 |
|
|
add_warning(Symbol_table* symtab, const char* name, Object* obj,
|
1203 |
|
|
const std::string& warning);
|
1204 |
|
|
|
1205 |
|
|
// For each symbol for which we should give a warning, make a note
|
1206 |
|
|
// on the symbol.
|
1207 |
|
|
void
|
1208 |
|
|
note_warnings(Symbol_table* symtab);
|
1209 |
|
|
|
1210 |
|
|
// Issue a warning for a reference to SYM at RELINFO's location.
|
1211 |
|
|
template<int size, bool big_endian>
|
1212 |
|
|
void
|
1213 |
|
|
issue_warning(const Symbol* sym, const Relocate_info<size, big_endian>*,
|
1214 |
|
|
size_t relnum, off_t reloffset) const;
|
1215 |
|
|
|
1216 |
|
|
private:
|
1217 |
|
|
Warnings(const Warnings&);
|
1218 |
|
|
Warnings& operator=(const Warnings&);
|
1219 |
|
|
|
1220 |
|
|
// What we need to know to get the warning text.
|
1221 |
|
|
struct Warning_location
|
1222 |
|
|
{
|
1223 |
|
|
// The object the warning is in.
|
1224 |
|
|
Object* object;
|
1225 |
|
|
// The warning text.
|
1226 |
|
|
std::string text;
|
1227 |
|
|
|
1228 |
|
|
Warning_location()
|
1229 |
|
|
: object(NULL), text()
|
1230 |
|
|
{ }
|
1231 |
|
|
|
1232 |
|
|
void
|
1233 |
|
|
set(Object* o, const std::string& t)
|
1234 |
|
|
{
|
1235 |
|
|
this->object = o;
|
1236 |
|
|
this->text = t;
|
1237 |
|
|
}
|
1238 |
|
|
};
|
1239 |
|
|
|
1240 |
|
|
// A mapping from warning symbol names (canonicalized in
|
1241 |
|
|
// Symbol_table's namepool_ field) to warning information.
|
1242 |
|
|
typedef Unordered_map<const char*, Warning_location> Warning_table;
|
1243 |
|
|
|
1244 |
|
|
Warning_table warnings_;
|
1245 |
|
|
};
|
1246 |
|
|
|
1247 |
|
|
// The main linker symbol table.
|
1248 |
|
|
|
1249 |
|
|
class Symbol_table
|
1250 |
|
|
{
|
1251 |
|
|
public:
|
1252 |
|
|
// The different places where a symbol definition can come from.
|
1253 |
|
|
enum Defined
|
1254 |
|
|
{
|
1255 |
|
|
// Defined in an object file--the normal case.
|
1256 |
|
|
OBJECT,
|
1257 |
|
|
// Defined for a COPY reloc.
|
1258 |
|
|
COPY,
|
1259 |
|
|
// Defined on the command line using --defsym.
|
1260 |
|
|
DEFSYM,
|
1261 |
|
|
// Defined (so to speak) on the command line using -u.
|
1262 |
|
|
UNDEFINED,
|
1263 |
|
|
// Defined in a linker script.
|
1264 |
|
|
SCRIPT,
|
1265 |
|
|
// Predefined by the linker.
|
1266 |
|
|
PREDEFINED,
|
1267 |
148 |
khays |
// Defined by the linker during an incremental base link, but not
|
1268 |
|
|
// a predefined symbol (e.g., common, defined in script).
|
1269 |
|
|
INCREMENTAL_BASE,
|
1270 |
27 |
khays |
};
|
1271 |
|
|
|
1272 |
|
|
// The order in which we sort common symbols.
|
1273 |
|
|
enum Sort_commons_order
|
1274 |
|
|
{
|
1275 |
|
|
SORT_COMMONS_BY_SIZE_DESCENDING,
|
1276 |
|
|
SORT_COMMONS_BY_ALIGNMENT_DESCENDING,
|
1277 |
|
|
SORT_COMMONS_BY_ALIGNMENT_ASCENDING
|
1278 |
|
|
};
|
1279 |
|
|
|
1280 |
|
|
// COUNT is an estimate of how many symbols will be inserted in the
|
1281 |
|
|
// symbol table. It's ok to put 0 if you don't know; a correct
|
1282 |
|
|
// guess will just save some CPU by reducing hashtable resizes.
|
1283 |
|
|
Symbol_table(unsigned int count, const Version_script_info& version_script);
|
1284 |
|
|
|
1285 |
|
|
~Symbol_table();
|
1286 |
|
|
|
1287 |
|
|
void
|
1288 |
|
|
set_icf(Icf* icf)
|
1289 |
|
|
{ this->icf_ = icf;}
|
1290 |
|
|
|
1291 |
|
|
Icf*
|
1292 |
|
|
icf() const
|
1293 |
|
|
{ return this->icf_; }
|
1294 |
|
|
|
1295 |
|
|
// Returns true if ICF determined that this is a duplicate section.
|
1296 |
|
|
bool
|
1297 |
|
|
is_section_folded(Object* obj, unsigned int shndx) const;
|
1298 |
|
|
|
1299 |
|
|
void
|
1300 |
|
|
set_gc(Garbage_collection* gc)
|
1301 |
|
|
{ this->gc_ = gc; }
|
1302 |
|
|
|
1303 |
|
|
Garbage_collection*
|
1304 |
|
|
gc() const
|
1305 |
|
|
{ return this->gc_; }
|
1306 |
|
|
|
1307 |
|
|
// During garbage collection, this keeps undefined symbols.
|
1308 |
|
|
void
|
1309 |
|
|
gc_mark_undef_symbols(Layout*);
|
1310 |
|
|
|
1311 |
|
|
// During garbage collection, this ensures externally visible symbols
|
1312 |
|
|
// are not treated as garbage while building shared objects.
|
1313 |
|
|
void
|
1314 |
|
|
gc_mark_symbol_for_shlib(Symbol* sym);
|
1315 |
|
|
|
1316 |
|
|
// During garbage collection, this keeps sections that correspond to
|
1317 |
|
|
// symbols seen in dynamic objects.
|
1318 |
|
|
inline void
|
1319 |
|
|
gc_mark_dyn_syms(Symbol* sym);
|
1320 |
|
|
|
1321 |
|
|
// Add COUNT external symbols from the relocatable object RELOBJ to
|
1322 |
|
|
// the symbol table. SYMS is the symbols, SYMNDX_OFFSET is the
|
1323 |
|
|
// offset in the symbol table of the first symbol, SYM_NAMES is
|
1324 |
|
|
// their names, SYM_NAME_SIZE is the size of SYM_NAMES. This sets
|
1325 |
|
|
// SYMPOINTERS to point to the symbols in the symbol table. It sets
|
1326 |
|
|
// *DEFINED to the number of defined symbols.
|
1327 |
|
|
template<int size, bool big_endian>
|
1328 |
|
|
void
|
1329 |
|
|
add_from_relobj(Sized_relobj_file<size, big_endian>* relobj,
|
1330 |
|
|
const unsigned char* syms, size_t count,
|
1331 |
|
|
size_t symndx_offset, const char* sym_names,
|
1332 |
|
|
size_t sym_name_size,
|
1333 |
|
|
typename Sized_relobj_file<size, big_endian>::Symbols*,
|
1334 |
|
|
size_t* defined);
|
1335 |
|
|
|
1336 |
|
|
// Add one external symbol from the plugin object OBJ to the symbol table.
|
1337 |
|
|
// Returns a pointer to the resolved symbol in the symbol table.
|
1338 |
|
|
template<int size, bool big_endian>
|
1339 |
|
|
Symbol*
|
1340 |
|
|
add_from_pluginobj(Sized_pluginobj<size, big_endian>* obj,
|
1341 |
|
|
const char* name, const char* ver,
|
1342 |
|
|
elfcpp::Sym<size, big_endian>* sym);
|
1343 |
|
|
|
1344 |
|
|
// Add COUNT dynamic symbols from the dynamic object DYNOBJ to the
|
1345 |
|
|
// symbol table. SYMS is the symbols. SYM_NAMES is their names.
|
1346 |
|
|
// SYM_NAME_SIZE is the size of SYM_NAMES. The other parameters are
|
1347 |
|
|
// symbol version data.
|
1348 |
|
|
template<int size, bool big_endian>
|
1349 |
|
|
void
|
1350 |
|
|
add_from_dynobj(Sized_dynobj<size, big_endian>* dynobj,
|
1351 |
|
|
const unsigned char* syms, size_t count,
|
1352 |
|
|
const char* sym_names, size_t sym_name_size,
|
1353 |
|
|
const unsigned char* versym, size_t versym_size,
|
1354 |
|
|
const std::vector<const char*>*,
|
1355 |
|
|
typename Sized_relobj_file<size, big_endian>::Symbols*,
|
1356 |
|
|
size_t* defined);
|
1357 |
|
|
|
1358 |
|
|
// Add one external symbol from the incremental object OBJ to the symbol
|
1359 |
|
|
// table. Returns a pointer to the resolved symbol in the symbol table.
|
1360 |
|
|
template<int size, bool big_endian>
|
1361 |
148 |
khays |
Sized_symbol<size>*
|
1362 |
27 |
khays |
add_from_incrobj(Object* obj, const char* name,
|
1363 |
|
|
const char* ver, elfcpp::Sym<size, big_endian>* sym);
|
1364 |
|
|
|
1365 |
|
|
// Define a special symbol based on an Output_data. It is a
|
1366 |
|
|
// multiple definition error if this symbol is already defined.
|
1367 |
|
|
Symbol*
|
1368 |
|
|
define_in_output_data(const char* name, const char* version, Defined,
|
1369 |
|
|
Output_data*, uint64_t value, uint64_t symsize,
|
1370 |
|
|
elfcpp::STT type, elfcpp::STB binding,
|
1371 |
|
|
elfcpp::STV visibility, unsigned char nonvis,
|
1372 |
|
|
bool offset_is_from_end, bool only_if_ref);
|
1373 |
|
|
|
1374 |
|
|
// Define a special symbol based on an Output_segment. It is a
|
1375 |
|
|
// multiple definition error if this symbol is already defined.
|
1376 |
|
|
Symbol*
|
1377 |
|
|
define_in_output_segment(const char* name, const char* version, Defined,
|
1378 |
|
|
Output_segment*, uint64_t value, uint64_t symsize,
|
1379 |
|
|
elfcpp::STT type, elfcpp::STB binding,
|
1380 |
|
|
elfcpp::STV visibility, unsigned char nonvis,
|
1381 |
|
|
Symbol::Segment_offset_base, bool only_if_ref);
|
1382 |
|
|
|
1383 |
|
|
// Define a special symbol with a constant value. It is a multiple
|
1384 |
|
|
// definition error if this symbol is already defined.
|
1385 |
|
|
Symbol*
|
1386 |
|
|
define_as_constant(const char* name, const char* version, Defined,
|
1387 |
|
|
uint64_t value, uint64_t symsize, elfcpp::STT type,
|
1388 |
|
|
elfcpp::STB binding, elfcpp::STV visibility,
|
1389 |
|
|
unsigned char nonvis, bool only_if_ref,
|
1390 |
|
|
bool force_override);
|
1391 |
|
|
|
1392 |
|
|
// Define a set of symbols in output sections. If ONLY_IF_REF is
|
1393 |
|
|
// true, only define them if they are referenced.
|
1394 |
|
|
void
|
1395 |
|
|
define_symbols(const Layout*, int count, const Define_symbol_in_section*,
|
1396 |
|
|
bool only_if_ref);
|
1397 |
|
|
|
1398 |
|
|
// Define a set of symbols in output segments. If ONLY_IF_REF is
|
1399 |
|
|
// true, only defined them if they are referenced.
|
1400 |
|
|
void
|
1401 |
|
|
define_symbols(const Layout*, int count, const Define_symbol_in_segment*,
|
1402 |
|
|
bool only_if_ref);
|
1403 |
|
|
|
1404 |
|
|
// Define SYM using a COPY reloc. POSD is the Output_data where the
|
1405 |
|
|
// symbol should be defined--typically a .dyn.bss section. VALUE is
|
1406 |
|
|
// the offset within POSD.
|
1407 |
|
|
template<int size>
|
1408 |
|
|
void
|
1409 |
|
|
define_with_copy_reloc(Sized_symbol<size>* sym, Output_data* posd,
|
1410 |
|
|
typename elfcpp::Elf_types<size>::Elf_Addr);
|
1411 |
|
|
|
1412 |
|
|
// Look up a symbol.
|
1413 |
|
|
Symbol*
|
1414 |
|
|
lookup(const char*, const char* version = NULL) const;
|
1415 |
|
|
|
1416 |
|
|
// Return the real symbol associated with the forwarder symbol FROM.
|
1417 |
|
|
Symbol*
|
1418 |
|
|
resolve_forwards(const Symbol* from) const;
|
1419 |
|
|
|
1420 |
|
|
// Return the sized version of a symbol in this table.
|
1421 |
|
|
template<int size>
|
1422 |
|
|
Sized_symbol<size>*
|
1423 |
|
|
get_sized_symbol(Symbol*) const;
|
1424 |
|
|
|
1425 |
|
|
template<int size>
|
1426 |
|
|
const Sized_symbol<size>*
|
1427 |
|
|
get_sized_symbol(const Symbol*) const;
|
1428 |
|
|
|
1429 |
|
|
// Return the count of undefined symbols seen.
|
1430 |
|
|
size_t
|
1431 |
|
|
saw_undefined() const
|
1432 |
|
|
{ return this->saw_undefined_; }
|
1433 |
|
|
|
1434 |
|
|
// Allocate the common symbols
|
1435 |
|
|
void
|
1436 |
|
|
allocate_commons(Layout*, Mapfile*);
|
1437 |
|
|
|
1438 |
|
|
// Add a warning for symbol NAME in object OBJ. WARNING is the text
|
1439 |
|
|
// of the warning.
|
1440 |
|
|
void
|
1441 |
|
|
add_warning(const char* name, Object* obj, const std::string& warning)
|
1442 |
|
|
{ this->warnings_.add_warning(this, name, obj, warning); }
|
1443 |
|
|
|
1444 |
|
|
// Canonicalize a symbol name for use in the hash table.
|
1445 |
|
|
const char*
|
1446 |
|
|
canonicalize_name(const char* name)
|
1447 |
|
|
{ return this->namepool_.add(name, true, NULL); }
|
1448 |
|
|
|
1449 |
|
|
// Possibly issue a warning for a reference to SYM at LOCATION which
|
1450 |
|
|
// is in OBJ.
|
1451 |
|
|
template<int size, bool big_endian>
|
1452 |
|
|
void
|
1453 |
|
|
issue_warning(const Symbol* sym,
|
1454 |
|
|
const Relocate_info<size, big_endian>* relinfo,
|
1455 |
|
|
size_t relnum, off_t reloffset) const
|
1456 |
|
|
{ this->warnings_.issue_warning(sym, relinfo, relnum, reloffset); }
|
1457 |
|
|
|
1458 |
|
|
// Check candidate_odr_violations_ to find symbols with the same name
|
1459 |
|
|
// but apparently different definitions (different source-file/line-no).
|
1460 |
|
|
void
|
1461 |
|
|
detect_odr_violations(const Task*, const char* output_file_name) const;
|
1462 |
|
|
|
1463 |
|
|
// Add any undefined symbols named on the command line to the symbol
|
1464 |
|
|
// table.
|
1465 |
|
|
void
|
1466 |
|
|
add_undefined_symbols_from_command_line(Layout*);
|
1467 |
|
|
|
1468 |
|
|
// SYM is defined using a COPY reloc. Return the dynamic object
|
1469 |
|
|
// where the original definition was found.
|
1470 |
|
|
Dynobj*
|
1471 |
|
|
get_copy_source(const Symbol* sym) const;
|
1472 |
|
|
|
1473 |
|
|
// Set the dynamic symbol indexes. INDEX is the index of the first
|
1474 |
|
|
// global dynamic symbol. Pointers to the symbols are stored into
|
1475 |
|
|
// the vector. The names are stored into the Stringpool. This
|
1476 |
|
|
// returns an updated dynamic symbol index.
|
1477 |
|
|
unsigned int
|
1478 |
|
|
set_dynsym_indexes(unsigned int index, std::vector<Symbol*>*,
|
1479 |
|
|
Stringpool*, Versions*);
|
1480 |
|
|
|
1481 |
|
|
// Finalize the symbol table after we have set the final addresses
|
1482 |
|
|
// of all the input sections. This sets the final symbol indexes,
|
1483 |
|
|
// values and adds the names to *POOL. *PLOCAL_SYMCOUNT is the
|
1484 |
|
|
// index of the first global symbol. OFF is the file offset of the
|
1485 |
|
|
// global symbol table, DYNOFF is the offset of the globals in the
|
1486 |
|
|
// dynamic symbol table, DYN_GLOBAL_INDEX is the index of the first
|
1487 |
|
|
// global dynamic symbol, and DYNCOUNT is the number of global
|
1488 |
|
|
// dynamic symbols. This records the parameters, and returns the
|
1489 |
|
|
// new file offset. It updates *PLOCAL_SYMCOUNT if it created any
|
1490 |
|
|
// local symbols.
|
1491 |
|
|
off_t
|
1492 |
|
|
finalize(off_t off, off_t dynoff, size_t dyn_global_index, size_t dyncount,
|
1493 |
|
|
Stringpool* pool, unsigned int* plocal_symcount);
|
1494 |
|
|
|
1495 |
|
|
// Set the final file offset of the symbol table.
|
1496 |
|
|
void
|
1497 |
|
|
set_file_offset(off_t off)
|
1498 |
|
|
{ this->offset_ = off; }
|
1499 |
|
|
|
1500 |
|
|
// Status code of Symbol_table::compute_final_value.
|
1501 |
|
|
enum Compute_final_value_status
|
1502 |
|
|
{
|
1503 |
|
|
// No error.
|
1504 |
|
|
CFVS_OK,
|
1505 |
|
|
// Unsupported symbol section.
|
1506 |
|
|
CFVS_UNSUPPORTED_SYMBOL_SECTION,
|
1507 |
|
|
// No output section.
|
1508 |
|
|
CFVS_NO_OUTPUT_SECTION
|
1509 |
|
|
};
|
1510 |
|
|
|
1511 |
|
|
// Compute the final value of SYM and store status in location PSTATUS.
|
1512 |
|
|
// During relaxation, this may be called multiple times for a symbol to
|
1513 |
|
|
// compute its would-be final value in each relaxation pass.
|
1514 |
|
|
|
1515 |
|
|
template<int size>
|
1516 |
|
|
typename Sized_symbol<size>::Value_type
|
1517 |
|
|
compute_final_value(const Sized_symbol<size>* sym,
|
1518 |
|
|
Compute_final_value_status* pstatus) const;
|
1519 |
|
|
|
1520 |
|
|
// Return the index of the first global symbol.
|
1521 |
|
|
unsigned int
|
1522 |
|
|
first_global_index() const
|
1523 |
|
|
{ return this->first_global_index_; }
|
1524 |
|
|
|
1525 |
|
|
// Return the total number of symbols in the symbol table.
|
1526 |
|
|
unsigned int
|
1527 |
|
|
output_count() const
|
1528 |
|
|
{ return this->output_count_; }
|
1529 |
|
|
|
1530 |
|
|
// Write out the global symbols.
|
1531 |
|
|
void
|
1532 |
|
|
write_globals(const Stringpool*, const Stringpool*,
|
1533 |
|
|
Output_symtab_xindex*, Output_symtab_xindex*,
|
1534 |
|
|
Output_file*) const;
|
1535 |
|
|
|
1536 |
|
|
// Write out a section symbol. Return the updated offset.
|
1537 |
|
|
void
|
1538 |
|
|
write_section_symbol(const Output_section*, Output_symtab_xindex*,
|
1539 |
|
|
Output_file*, off_t) const;
|
1540 |
|
|
|
1541 |
|
|
// Loop over all symbols, applying the function F to each.
|
1542 |
|
|
template<int size, typename F>
|
1543 |
|
|
void
|
1544 |
|
|
for_all_symbols(F f) const
|
1545 |
|
|
{
|
1546 |
|
|
for (Symbol_table_type::const_iterator p = this->table_.begin();
|
1547 |
|
|
p != this->table_.end();
|
1548 |
|
|
++p)
|
1549 |
|
|
{
|
1550 |
|
|
Sized_symbol<size>* sym = static_cast<Sized_symbol<size>*>(p->second);
|
1551 |
|
|
f(sym);
|
1552 |
|
|
}
|
1553 |
|
|
}
|
1554 |
|
|
|
1555 |
|
|
// Dump statistical information to stderr.
|
1556 |
|
|
void
|
1557 |
|
|
print_stats() const;
|
1558 |
|
|
|
1559 |
|
|
// Return the version script information.
|
1560 |
|
|
const Version_script_info&
|
1561 |
|
|
version_script() const
|
1562 |
|
|
{ return version_script_; }
|
1563 |
|
|
|
1564 |
|
|
private:
|
1565 |
|
|
Symbol_table(const Symbol_table&);
|
1566 |
|
|
Symbol_table& operator=(const Symbol_table&);
|
1567 |
|
|
|
1568 |
|
|
// The type of the list of common symbols.
|
1569 |
|
|
typedef std::vector<Symbol*> Commons_type;
|
1570 |
|
|
|
1571 |
|
|
// The type of the symbol hash table.
|
1572 |
|
|
|
1573 |
|
|
typedef std::pair<Stringpool::Key, Stringpool::Key> Symbol_table_key;
|
1574 |
|
|
|
1575 |
|
|
// The hash function. The key values are Stringpool keys.
|
1576 |
|
|
struct Symbol_table_hash
|
1577 |
|
|
{
|
1578 |
|
|
inline size_t
|
1579 |
|
|
operator()(const Symbol_table_key& key) const
|
1580 |
|
|
{
|
1581 |
|
|
return key.first ^ key.second;
|
1582 |
|
|
}
|
1583 |
|
|
};
|
1584 |
|
|
|
1585 |
|
|
struct Symbol_table_eq
|
1586 |
|
|
{
|
1587 |
|
|
bool
|
1588 |
|
|
operator()(const Symbol_table_key&, const Symbol_table_key&) const;
|
1589 |
|
|
};
|
1590 |
|
|
|
1591 |
|
|
typedef Unordered_map<Symbol_table_key, Symbol*, Symbol_table_hash,
|
1592 |
|
|
Symbol_table_eq> Symbol_table_type;
|
1593 |
|
|
|
1594 |
|
|
// A map from symbol name (as a pointer into the namepool) to all
|
1595 |
|
|
// the locations the symbols is (weakly) defined (and certain other
|
1596 |
|
|
// conditions are met). This map will be used later to detect
|
1597 |
|
|
// possible One Definition Rule (ODR) violations.
|
1598 |
|
|
struct Symbol_location
|
1599 |
|
|
{
|
1600 |
|
|
Object* object; // Object where the symbol is defined.
|
1601 |
|
|
unsigned int shndx; // Section-in-object where the symbol is defined.
|
1602 |
|
|
off_t offset; // Offset-in-section where the symbol is defined.
|
1603 |
|
|
bool operator==(const Symbol_location& that) const
|
1604 |
|
|
{
|
1605 |
|
|
return (this->object == that.object
|
1606 |
|
|
&& this->shndx == that.shndx
|
1607 |
|
|
&& this->offset == that.offset);
|
1608 |
|
|
}
|
1609 |
|
|
};
|
1610 |
|
|
|
1611 |
|
|
struct Symbol_location_hash
|
1612 |
|
|
{
|
1613 |
|
|
size_t operator()(const Symbol_location& loc) const
|
1614 |
|
|
{ return reinterpret_cast<uintptr_t>(loc.object) ^ loc.offset ^ loc.shndx; }
|
1615 |
|
|
};
|
1616 |
|
|
|
1617 |
|
|
typedef Unordered_map<const char*,
|
1618 |
|
|
Unordered_set<Symbol_location, Symbol_location_hash> >
|
1619 |
|
|
Odr_map;
|
1620 |
|
|
|
1621 |
|
|
// Make FROM a forwarder symbol to TO.
|
1622 |
|
|
void
|
1623 |
|
|
make_forwarder(Symbol* from, Symbol* to);
|
1624 |
|
|
|
1625 |
|
|
// Add a symbol.
|
1626 |
|
|
template<int size, bool big_endian>
|
1627 |
|
|
Sized_symbol<size>*
|
1628 |
|
|
add_from_object(Object*, const char* name, Stringpool::Key name_key,
|
1629 |
|
|
const char* version, Stringpool::Key version_key,
|
1630 |
|
|
bool def, const elfcpp::Sym<size, big_endian>& sym,
|
1631 |
|
|
unsigned int st_shndx, bool is_ordinary,
|
1632 |
|
|
unsigned int orig_st_shndx);
|
1633 |
|
|
|
1634 |
|
|
// Define a default symbol.
|
1635 |
|
|
template<int size, bool big_endian>
|
1636 |
|
|
void
|
1637 |
|
|
define_default_version(Sized_symbol<size>*, bool,
|
1638 |
|
|
Symbol_table_type::iterator);
|
1639 |
|
|
|
1640 |
|
|
// Resolve symbols.
|
1641 |
|
|
template<int size, bool big_endian>
|
1642 |
|
|
void
|
1643 |
|
|
resolve(Sized_symbol<size>* to,
|
1644 |
|
|
const elfcpp::Sym<size, big_endian>& sym,
|
1645 |
|
|
unsigned int st_shndx, bool is_ordinary,
|
1646 |
|
|
unsigned int orig_st_shndx,
|
1647 |
|
|
Object*, const char* version);
|
1648 |
|
|
|
1649 |
|
|
template<int size, bool big_endian>
|
1650 |
|
|
void
|
1651 |
|
|
resolve(Sized_symbol<size>* to, const Sized_symbol<size>* from);
|
1652 |
|
|
|
1653 |
|
|
// Record that a symbol is forced to be local by a version script or
|
1654 |
|
|
// by visibility.
|
1655 |
|
|
void
|
1656 |
|
|
force_local(Symbol*);
|
1657 |
|
|
|
1658 |
|
|
// Adjust NAME and *NAME_KEY for wrapping.
|
1659 |
|
|
const char*
|
1660 |
|
|
wrap_symbol(const char* name, Stringpool::Key* name_key);
|
1661 |
|
|
|
1662 |
|
|
// Whether we should override a symbol, based on flags in
|
1663 |
|
|
// resolve.cc.
|
1664 |
|
|
static bool
|
1665 |
159 |
khays |
should_override(const Symbol*, unsigned int, elfcpp::STT, Defined,
|
1666 |
|
|
Object*, bool*, bool*);
|
1667 |
27 |
khays |
|
1668 |
|
|
// Report a problem in symbol resolution.
|
1669 |
|
|
static void
|
1670 |
|
|
report_resolve_problem(bool is_error, const char* msg, const Symbol* to,
|
1671 |
|
|
Defined, Object* object);
|
1672 |
|
|
|
1673 |
|
|
// Override a symbol.
|
1674 |
|
|
template<int size, bool big_endian>
|
1675 |
|
|
void
|
1676 |
|
|
override(Sized_symbol<size>* tosym,
|
1677 |
|
|
const elfcpp::Sym<size, big_endian>& fromsym,
|
1678 |
|
|
unsigned int st_shndx, bool is_ordinary,
|
1679 |
|
|
Object* object, const char* version);
|
1680 |
|
|
|
1681 |
|
|
// Whether we should override a symbol with a special symbol which
|
1682 |
|
|
// is automatically defined by the linker.
|
1683 |
|
|
static bool
|
1684 |
159 |
khays |
should_override_with_special(const Symbol*, elfcpp::STT, Defined);
|
1685 |
27 |
khays |
|
1686 |
|
|
// Override a symbol with a special symbol.
|
1687 |
|
|
template<int size>
|
1688 |
|
|
void
|
1689 |
|
|
override_with_special(Sized_symbol<size>* tosym,
|
1690 |
|
|
const Sized_symbol<size>* fromsym);
|
1691 |
|
|
|
1692 |
|
|
// Record all weak alias sets for a dynamic object.
|
1693 |
|
|
template<int size>
|
1694 |
|
|
void
|
1695 |
|
|
record_weak_aliases(std::vector<Sized_symbol<size>*>*);
|
1696 |
|
|
|
1697 |
|
|
// Define a special symbol.
|
1698 |
|
|
template<int size, bool big_endian>
|
1699 |
|
|
Sized_symbol<size>*
|
1700 |
|
|
define_special_symbol(const char** pname, const char** pversion,
|
1701 |
|
|
bool only_if_ref, Sized_symbol<size>** poldsym,
|
1702 |
|
|
bool* resolve_oldsym);
|
1703 |
|
|
|
1704 |
|
|
// Define a symbol in an Output_data, sized version.
|
1705 |
|
|
template<int size>
|
1706 |
|
|
Sized_symbol<size>*
|
1707 |
|
|
do_define_in_output_data(const char* name, const char* version, Defined,
|
1708 |
|
|
Output_data*,
|
1709 |
|
|
typename elfcpp::Elf_types<size>::Elf_Addr value,
|
1710 |
|
|
typename elfcpp::Elf_types<size>::Elf_WXword ssize,
|
1711 |
|
|
elfcpp::STT type, elfcpp::STB binding,
|
1712 |
|
|
elfcpp::STV visibility, unsigned char nonvis,
|
1713 |
|
|
bool offset_is_from_end, bool only_if_ref);
|
1714 |
|
|
|
1715 |
|
|
// Define a symbol in an Output_segment, sized version.
|
1716 |
|
|
template<int size>
|
1717 |
|
|
Sized_symbol<size>*
|
1718 |
|
|
do_define_in_output_segment(
|
1719 |
|
|
const char* name, const char* version, Defined, Output_segment* os,
|
1720 |
|
|
typename elfcpp::Elf_types<size>::Elf_Addr value,
|
1721 |
|
|
typename elfcpp::Elf_types<size>::Elf_WXword ssize,
|
1722 |
|
|
elfcpp::STT type, elfcpp::STB binding,
|
1723 |
|
|
elfcpp::STV visibility, unsigned char nonvis,
|
1724 |
|
|
Symbol::Segment_offset_base offset_base, bool only_if_ref);
|
1725 |
|
|
|
1726 |
|
|
// Define a symbol as a constant, sized version.
|
1727 |
|
|
template<int size>
|
1728 |
|
|
Sized_symbol<size>*
|
1729 |
|
|
do_define_as_constant(
|
1730 |
|
|
const char* name, const char* version, Defined,
|
1731 |
|
|
typename elfcpp::Elf_types<size>::Elf_Addr value,
|
1732 |
|
|
typename elfcpp::Elf_types<size>::Elf_WXword ssize,
|
1733 |
|
|
elfcpp::STT type, elfcpp::STB binding,
|
1734 |
|
|
elfcpp::STV visibility, unsigned char nonvis,
|
1735 |
|
|
bool only_if_ref, bool force_override);
|
1736 |
|
|
|
1737 |
|
|
// Add any undefined symbols named on the command line to the symbol
|
1738 |
|
|
// table, sized version.
|
1739 |
|
|
template<int size>
|
1740 |
|
|
void
|
1741 |
|
|
do_add_undefined_symbols_from_command_line(Layout*);
|
1742 |
|
|
|
1743 |
|
|
// Add one undefined symbol.
|
1744 |
|
|
template<int size>
|
1745 |
|
|
void
|
1746 |
|
|
add_undefined_symbol_from_command_line(const char* name);
|
1747 |
|
|
|
1748 |
|
|
// Types of common symbols.
|
1749 |
|
|
|
1750 |
|
|
enum Commons_section_type
|
1751 |
|
|
{
|
1752 |
|
|
COMMONS_NORMAL,
|
1753 |
|
|
COMMONS_TLS,
|
1754 |
|
|
COMMONS_SMALL,
|
1755 |
|
|
COMMONS_LARGE
|
1756 |
|
|
};
|
1757 |
|
|
|
1758 |
|
|
// Allocate the common symbols, sized version.
|
1759 |
|
|
template<int size>
|
1760 |
|
|
void
|
1761 |
|
|
do_allocate_commons(Layout*, Mapfile*, Sort_commons_order);
|
1762 |
|
|
|
1763 |
|
|
// Allocate the common symbols from one list.
|
1764 |
|
|
template<int size>
|
1765 |
|
|
void
|
1766 |
|
|
do_allocate_commons_list(Layout*, Commons_section_type, Commons_type*,
|
1767 |
|
|
Mapfile*, Sort_commons_order);
|
1768 |
|
|
|
1769 |
|
|
// Returns all of the lines attached to LOC, not just the one the
|
1770 |
|
|
// instruction actually came from. This helps the ODR checker avoid
|
1771 |
|
|
// false positives.
|
1772 |
|
|
static std::vector<std::string>
|
1773 |
|
|
linenos_from_loc(const Task* task, const Symbol_location& loc);
|
1774 |
|
|
|
1775 |
|
|
// Implement detect_odr_violations.
|
1776 |
|
|
template<int size, bool big_endian>
|
1777 |
|
|
void
|
1778 |
|
|
sized_detect_odr_violations() const;
|
1779 |
|
|
|
1780 |
|
|
// Finalize symbols specialized for size.
|
1781 |
|
|
template<int size>
|
1782 |
|
|
off_t
|
1783 |
|
|
sized_finalize(off_t, Stringpool*, unsigned int*);
|
1784 |
|
|
|
1785 |
|
|
// Finalize a symbol. Return whether it should be added to the
|
1786 |
|
|
// symbol table.
|
1787 |
|
|
template<int size>
|
1788 |
|
|
bool
|
1789 |
|
|
sized_finalize_symbol(Symbol*);
|
1790 |
|
|
|
1791 |
|
|
// Add a symbol the final symtab by setting its index.
|
1792 |
|
|
template<int size>
|
1793 |
|
|
void
|
1794 |
|
|
add_to_final_symtab(Symbol*, Stringpool*, unsigned int* pindex, off_t* poff);
|
1795 |
|
|
|
1796 |
|
|
// Write globals specialized for size and endianness.
|
1797 |
|
|
template<int size, bool big_endian>
|
1798 |
|
|
void
|
1799 |
|
|
sized_write_globals(const Stringpool*, const Stringpool*,
|
1800 |
|
|
Output_symtab_xindex*, Output_symtab_xindex*,
|
1801 |
|
|
Output_file*) const;
|
1802 |
|
|
|
1803 |
|
|
// Write out a symbol to P.
|
1804 |
|
|
template<int size, bool big_endian>
|
1805 |
|
|
void
|
1806 |
|
|
sized_write_symbol(Sized_symbol<size>*,
|
1807 |
|
|
typename elfcpp::Elf_types<size>::Elf_Addr value,
|
1808 |
|
|
unsigned int shndx, elfcpp::STB,
|
1809 |
|
|
const Stringpool*, unsigned char* p) const;
|
1810 |
|
|
|
1811 |
|
|
// Possibly warn about an undefined symbol from a dynamic object.
|
1812 |
|
|
void
|
1813 |
|
|
warn_about_undefined_dynobj_symbol(Symbol*) const;
|
1814 |
|
|
|
1815 |
|
|
// Write out a section symbol, specialized for size and endianness.
|
1816 |
|
|
template<int size, bool big_endian>
|
1817 |
|
|
void
|
1818 |
|
|
sized_write_section_symbol(const Output_section*, Output_symtab_xindex*,
|
1819 |
|
|
Output_file*, off_t) const;
|
1820 |
|
|
|
1821 |
|
|
// The type of the list of symbols which have been forced local.
|
1822 |
|
|
typedef std::vector<Symbol*> Forced_locals;
|
1823 |
|
|
|
1824 |
|
|
// A map from symbols with COPY relocs to the dynamic objects where
|
1825 |
|
|
// they are defined.
|
1826 |
|
|
typedef Unordered_map<const Symbol*, Dynobj*> Copied_symbol_dynobjs;
|
1827 |
|
|
|
1828 |
|
|
// We increment this every time we see a new undefined symbol, for
|
1829 |
|
|
// use in archive groups.
|
1830 |
|
|
size_t saw_undefined_;
|
1831 |
|
|
// The index of the first global symbol in the output file.
|
1832 |
|
|
unsigned int first_global_index_;
|
1833 |
|
|
// The file offset within the output symtab section where we should
|
1834 |
|
|
// write the table.
|
1835 |
|
|
off_t offset_;
|
1836 |
|
|
// The number of global symbols we want to write out.
|
1837 |
|
|
unsigned int output_count_;
|
1838 |
|
|
// The file offset of the global dynamic symbols, or 0 if none.
|
1839 |
|
|
off_t dynamic_offset_;
|
1840 |
|
|
// The index of the first global dynamic symbol.
|
1841 |
|
|
unsigned int first_dynamic_global_index_;
|
1842 |
|
|
// The number of global dynamic symbols, or 0 if none.
|
1843 |
|
|
unsigned int dynamic_count_;
|
1844 |
|
|
// The symbol hash table.
|
1845 |
|
|
Symbol_table_type table_;
|
1846 |
|
|
// A pool of symbol names. This is used for all global symbols.
|
1847 |
|
|
// Entries in the hash table point into this pool.
|
1848 |
|
|
Stringpool namepool_;
|
1849 |
|
|
// Forwarding symbols.
|
1850 |
|
|
Unordered_map<const Symbol*, Symbol*> forwarders_;
|
1851 |
|
|
// Weak aliases. A symbol in this list points to the next alias.
|
1852 |
|
|
// The aliases point to each other in a circular list.
|
1853 |
|
|
Unordered_map<Symbol*, Symbol*> weak_aliases_;
|
1854 |
|
|
// We don't expect there to be very many common symbols, so we keep
|
1855 |
|
|
// a list of them. When we find a common symbol we add it to this
|
1856 |
|
|
// list. It is possible that by the time we process the list the
|
1857 |
|
|
// symbol is no longer a common symbol. It may also have become a
|
1858 |
|
|
// forwarder.
|
1859 |
|
|
Commons_type commons_;
|
1860 |
|
|
// This is like the commons_ field, except that it holds TLS common
|
1861 |
|
|
// symbols.
|
1862 |
|
|
Commons_type tls_commons_;
|
1863 |
|
|
// This is for small common symbols.
|
1864 |
|
|
Commons_type small_commons_;
|
1865 |
|
|
// This is for large common symbols.
|
1866 |
|
|
Commons_type large_commons_;
|
1867 |
|
|
// A list of symbols which have been forced to be local. We don't
|
1868 |
|
|
// expect there to be very many of them, so we keep a list of them
|
1869 |
|
|
// rather than walking the whole table to find them.
|
1870 |
|
|
Forced_locals forced_locals_;
|
1871 |
|
|
// Manage symbol warnings.
|
1872 |
|
|
Warnings warnings_;
|
1873 |
|
|
// Manage potential One Definition Rule (ODR) violations.
|
1874 |
|
|
Odr_map candidate_odr_violations_;
|
1875 |
|
|
|
1876 |
|
|
// When we emit a COPY reloc for a symbol, we define it in an
|
1877 |
|
|
// Output_data. When it's time to emit version information for it,
|
1878 |
|
|
// we need to know the dynamic object in which we found the original
|
1879 |
|
|
// definition. This maps symbols with COPY relocs to the dynamic
|
1880 |
|
|
// object where they were defined.
|
1881 |
|
|
Copied_symbol_dynobjs copied_symbol_dynobjs_;
|
1882 |
|
|
// Information parsed from the version script, if any.
|
1883 |
|
|
const Version_script_info& version_script_;
|
1884 |
|
|
Garbage_collection* gc_;
|
1885 |
|
|
Icf* icf_;
|
1886 |
|
|
};
|
1887 |
|
|
|
1888 |
|
|
// We inline get_sized_symbol for efficiency.
|
1889 |
|
|
|
1890 |
|
|
template<int size>
|
1891 |
|
|
Sized_symbol<size>*
|
1892 |
|
|
Symbol_table::get_sized_symbol(Symbol* sym) const
|
1893 |
|
|
{
|
1894 |
|
|
gold_assert(size == parameters->target().get_size());
|
1895 |
|
|
return static_cast<Sized_symbol<size>*>(sym);
|
1896 |
|
|
}
|
1897 |
|
|
|
1898 |
|
|
template<int size>
|
1899 |
|
|
const Sized_symbol<size>*
|
1900 |
|
|
Symbol_table::get_sized_symbol(const Symbol* sym) const
|
1901 |
|
|
{
|
1902 |
|
|
gold_assert(size == parameters->target().get_size());
|
1903 |
|
|
return static_cast<const Sized_symbol<size>*>(sym);
|
1904 |
|
|
}
|
1905 |
|
|
|
1906 |
|
|
} // End namespace gold.
|
1907 |
|
|
|
1908 |
|
|
#endif // !defined(GOLD_SYMTAB_H)
|