Line 1395... |
Line 1395... |
// Whether we should sort the relocs.
|
// Whether we should sort the relocs.
|
bool
|
bool
|
sort_relocs() const
|
sort_relocs() const
|
{ return this->sort_relocs_; }
|
{ return this->sort_relocs_; }
|
|
|
|
// Add a reloc of type TYPE against the global symbol GSYM. The
|
|
// relocation applies to the data at offset ADDRESS within OD.
|
|
virtual void
|
|
add_global_generic(Symbol* gsym, unsigned int type, Output_data* od,
|
|
uint64_t address, uint64_t addend) = 0;
|
|
|
|
// Add a reloc of type TYPE against the global symbol GSYM. The
|
|
// relocation applies to data at offset ADDRESS within section SHNDX
|
|
// of object file RELOBJ. OD is the associated output section.
|
|
virtual void
|
|
add_global_generic(Symbol* gsym, unsigned int type, Output_data* od,
|
|
Relobj* relobj, unsigned int shndx, uint64_t address,
|
|
uint64_t addend) = 0;
|
|
|
|
// Add a reloc of type TYPE against the local symbol LOCAL_SYM_INDEX
|
|
// in RELOBJ. The relocation applies to the data at offset ADDRESS
|
|
// within OD.
|
|
virtual void
|
|
add_local_generic(Relobj* relobj, unsigned int local_sym_index,
|
|
unsigned int type, Output_data* od, uint64_t address,
|
|
uint64_t addend) = 0;
|
|
|
|
// Add a reloc of type TYPE against the local symbol LOCAL_SYM_INDEX
|
|
// in RELOBJ. The relocation applies to the data at offset ADDRESS
|
|
// within section SHNDX of RELOBJ. OD is the associated output
|
|
// section.
|
|
virtual void
|
|
add_local_generic(Relobj* relobj, unsigned int local_sym_index,
|
|
unsigned int type, Output_data* od, unsigned int shndx,
|
|
uint64_t address, uint64_t addend) = 0;
|
|
|
|
// Add a reloc of type TYPE against the STT_SECTION symbol of the
|
|
// output section OS. The relocation applies to the data at offset
|
|
// ADDRESS within OD.
|
|
virtual void
|
|
add_output_section_generic(Output_section *os, unsigned int type,
|
|
Output_data* od, uint64_t address,
|
|
uint64_t addend) = 0;
|
|
|
|
// Add a reloc of type TYPE against the STT_SECTION symbol of the
|
|
// output section OS. The relocation applies to the data at offset
|
|
// ADDRESS within section SHNDX of RELOBJ. OD is the associated
|
|
// output section.
|
|
virtual void
|
|
add_output_section_generic(Output_section* os, unsigned int type,
|
|
Output_data* od, Relobj* relobj,
|
|
unsigned int shndx, uint64_t address,
|
|
uint64_t addend) = 0;
|
|
|
protected:
|
protected:
|
// Note that we've added another relative reloc.
|
// Note that we've added another relative reloc.
|
void
|
void
|
bump_relative_reloc_count()
|
bump_relative_reloc_count()
|
{ ++this->relative_reloc_count_; }
|
{ ++this->relative_reloc_count_; }
|
Line 1456... |
Line 1505... |
void
|
void
|
add(Output_data* od, const Output_reloc_type& reloc)
|
add(Output_data* od, const Output_reloc_type& reloc)
|
{
|
{
|
this->relocs_.push_back(reloc);
|
this->relocs_.push_back(reloc);
|
this->set_current_data_size(this->relocs_.size() * reloc_size);
|
this->set_current_data_size(this->relocs_.size() * reloc_size);
|
|
if (dynamic)
|
od->add_dynamic_reloc();
|
od->add_dynamic_reloc();
|
if (reloc.is_relative())
|
if (reloc.is_relative())
|
this->bump_relative_reloc_count();
|
this->bump_relative_reloc_count();
|
Sized_relobj<size, big_endian>* relobj = reloc.get_relobj();
|
Sized_relobj<size, big_endian>* relobj = reloc.get_relobj();
|
if (relobj != NULL)
|
if (relobj != NULL)
|
Line 1515... |
Line 1565... |
Sized_relobj<size, big_endian>* relobj,
|
Sized_relobj<size, big_endian>* relobj,
|
unsigned int shndx, Address address)
|
unsigned int shndx, Address address)
|
{ this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
|
{ this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
|
false, false)); }
|
false, false)); }
|
|
|
// These are to simplify the Copy_relocs class.
|
|
|
|
void
|
void
|
add_global(Symbol* gsym, unsigned int type, Output_data* od, Address address,
|
add_global_generic(Symbol* gsym, unsigned int type, Output_data* od,
|
Address addend)
|
uint64_t address, uint64_t addend)
|
{
|
{
|
gold_assert(addend == 0);
|
gold_assert(addend == 0);
|
this->add_global(gsym, type, od, address);
|
this->add(od, Output_reloc_type(gsym, type, od,
|
|
convert_types<Address, uint64_t>(address),
|
|
false, false));
|
}
|
}
|
|
|
void
|
void
|
add_global(Symbol* gsym, unsigned int type, Output_data* od,
|
add_global_generic(Symbol* gsym, unsigned int type, Output_data* od,
|
Sized_relobj<size, big_endian>* relobj,
|
Relobj* relobj, unsigned int shndx, uint64_t address,
|
unsigned int shndx, Address address, Address addend)
|
uint64_t addend)
|
{
|
{
|
gold_assert(addend == 0);
|
gold_assert(addend == 0);
|
this->add_global(gsym, type, od, relobj, shndx, address);
|
Sized_relobj<size, big_endian>* sized_relobj =
|
|
static_cast<Sized_relobj<size, big_endian>*>(relobj);
|
|
this->add(od, Output_reloc_type(gsym, type, sized_relobj, shndx,
|
|
convert_types<Address, uint64_t>(address),
|
|
false, false));
|
}
|
}
|
|
|
// Add a RELATIVE reloc against a global symbol. The final relocation
|
// Add a RELATIVE reloc against a global symbol. The final relocation
|
// will not reference the symbol.
|
// will not reference the symbol.
|
|
|
Line 1589... |
Line 1643... |
{
|
{
|
this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
|
this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
|
address, false, false, false, false));
|
address, false, false, false, false));
|
}
|
}
|
|
|
|
void
|
|
add_local_generic(Relobj* relobj, unsigned int local_sym_index,
|
|
unsigned int type, Output_data* od, uint64_t address,
|
|
uint64_t addend)
|
|
{
|
|
gold_assert(addend == 0);
|
|
Sized_relobj<size, big_endian>* sized_relobj =
|
|
static_cast<Sized_relobj<size, big_endian> *>(relobj);
|
|
this->add(od, Output_reloc_type(sized_relobj, local_sym_index, type, od,
|
|
convert_types<Address, uint64_t>(address),
|
|
false, false, false, false));
|
|
}
|
|
|
|
void
|
|
add_local_generic(Relobj* relobj, unsigned int local_sym_index,
|
|
unsigned int type, Output_data* od, unsigned int shndx,
|
|
uint64_t address, uint64_t addend)
|
|
{
|
|
gold_assert(addend == 0);
|
|
Sized_relobj<size, big_endian>* sized_relobj =
|
|
static_cast<Sized_relobj<size, big_endian>*>(relobj);
|
|
this->add(od, Output_reloc_type(sized_relobj, local_sym_index, type, shndx,
|
|
convert_types<Address, uint64_t>(address),
|
|
false, false, false, false));
|
|
}
|
|
|
// Add a RELATIVE reloc against a local symbol.
|
// Add a RELATIVE reloc against a local symbol.
|
|
|
void
|
void
|
add_local_relative(Sized_relobj<size, big_endian>* relobj,
|
add_local_relative(Sized_relobj<size, big_endian>* relobj,
|
unsigned int local_sym_index, unsigned int type,
|
unsigned int local_sym_index, unsigned int type,
|
Line 1668... |
Line 1748... |
add_output_section(Output_section* os, unsigned int type, Output_data* od,
|
add_output_section(Output_section* os, unsigned int type, Output_data* od,
|
Sized_relobj<size, big_endian>* relobj,
|
Sized_relobj<size, big_endian>* relobj,
|
unsigned int shndx, Address address)
|
unsigned int shndx, Address address)
|
{ this->add(od, Output_reloc_type(os, type, relobj, shndx, address)); }
|
{ this->add(od, Output_reloc_type(os, type, relobj, shndx, address)); }
|
|
|
|
void
|
|
add_output_section_generic(Output_section* os, unsigned int type,
|
|
Output_data* od, uint64_t address,
|
|
uint64_t addend)
|
|
{
|
|
gold_assert(addend == 0);
|
|
this->add(od, Output_reloc_type(os, type, od,
|
|
convert_types<Address, uint64_t>(address)));
|
|
}
|
|
|
|
void
|
|
add_output_section_generic(Output_section* os, unsigned int type,
|
|
Output_data* od, Relobj* relobj,
|
|
unsigned int shndx, uint64_t address,
|
|
uint64_t addend)
|
|
{
|
|
gold_assert(addend == 0);
|
|
Sized_relobj<size, big_endian>* sized_relobj =
|
|
static_cast<Sized_relobj<size, big_endian>*>(relobj);
|
|
this->add(od, Output_reloc_type(os, type, sized_relobj, shndx,
|
|
convert_types<Address, uint64_t>(address)));
|
|
}
|
|
|
// Add an absolute relocation.
|
// Add an absolute relocation.
|
|
|
void
|
void
|
add_absolute(unsigned int type, Output_data* od, Address address)
|
add_absolute(unsigned int type, Output_data* od, Address address)
|
{ this->add(od, Output_reloc_type(type, od, address)); }
|
{ this->add(od, Output_reloc_type(type, od, address)); }
|
Line 1730... |
Line 1833... |
unsigned int shndx, Address address,
|
unsigned int shndx, Address address,
|
Addend addend)
|
Addend addend)
|
{ this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
|
{ this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
|
addend, false, false)); }
|
addend, false, false)); }
|
|
|
|
void
|
|
add_global_generic(Symbol* gsym, unsigned int type, Output_data* od,
|
|
uint64_t address, uint64_t addend)
|
|
{
|
|
this->add(od, Output_reloc_type(gsym, type, od,
|
|
convert_types<Address, uint64_t>(address),
|
|
convert_types<Addend, uint64_t>(addend),
|
|
false, false));
|
|
}
|
|
|
|
void
|
|
add_global_generic(Symbol* gsym, unsigned int type, Output_data* od,
|
|
Relobj* relobj, unsigned int shndx, uint64_t address,
|
|
uint64_t addend)
|
|
{
|
|
Sized_relobj<size, big_endian>* sized_relobj =
|
|
static_cast<Sized_relobj<size, big_endian>*>(relobj);
|
|
this->add(od, Output_reloc_type(gsym, type, sized_relobj, shndx,
|
|
convert_types<Address, uint64_t>(address),
|
|
convert_types<Addend, uint64_t>(addend),
|
|
false, false));
|
|
}
|
|
|
// Add a RELATIVE reloc against a global symbol. The final output
|
// Add a RELATIVE reloc against a global symbol. The final output
|
// relocation will not reference the symbol, but we must keep the symbol
|
// relocation will not reference the symbol, but we must keep the symbol
|
// information long enough to set the addend of the relocation correctly
|
// information long enough to set the addend of the relocation correctly
|
// when it is written.
|
// when it is written.
|
|
|
Line 1787... |
Line 1913... |
this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
|
this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
|
address, addend, false, false, false,
|
address, addend, false, false, false,
|
false));
|
false));
|
}
|
}
|
|
|
|
void
|
|
add_local_generic(Relobj* relobj, unsigned int local_sym_index,
|
|
unsigned int type, Output_data* od, uint64_t address,
|
|
uint64_t addend)
|
|
{
|
|
Sized_relobj<size, big_endian>* sized_relobj =
|
|
static_cast<Sized_relobj<size, big_endian> *>(relobj);
|
|
this->add(od, Output_reloc_type(sized_relobj, local_sym_index, type, od,
|
|
convert_types<Address, uint64_t>(address),
|
|
convert_types<Addend, uint64_t>(addend),
|
|
false, false, false, false));
|
|
}
|
|
|
|
void
|
|
add_local_generic(Relobj* relobj, unsigned int local_sym_index,
|
|
unsigned int type, Output_data* od, unsigned int shndx,
|
|
uint64_t address, uint64_t addend)
|
|
{
|
|
Sized_relobj<size, big_endian>* sized_relobj =
|
|
static_cast<Sized_relobj<size, big_endian>*>(relobj);
|
|
this->add(od, Output_reloc_type(sized_relobj, local_sym_index, type, shndx,
|
|
convert_types<Address, uint64_t>(address),
|
|
convert_types<Addend, uint64_t>(addend),
|
|
false, false, false, false));
|
|
}
|
|
|
// Add a RELATIVE reloc against a local symbol.
|
// Add a RELATIVE reloc against a local symbol.
|
|
|
void
|
void
|
add_local_relative(Sized_relobj<size, big_endian>* relobj,
|
add_local_relative(Sized_relobj<size, big_endian>* relobj,
|
unsigned int local_sym_index, unsigned int type,
|
unsigned int local_sym_index, unsigned int type,
|
Line 1872... |
Line 2024... |
Sized_relobj<size, big_endian>* relobj,
|
Sized_relobj<size, big_endian>* relobj,
|
unsigned int shndx, Address address, Addend addend)
|
unsigned int shndx, Address address, Addend addend)
|
{ this->add(od, Output_reloc_type(os, type, relobj, shndx, address,
|
{ this->add(od, Output_reloc_type(os, type, relobj, shndx, address,
|
addend)); }
|
addend)); }
|
|
|
|
void
|
|
add_output_section_generic(Output_section* os, unsigned int type,
|
|
Output_data* od, uint64_t address,
|
|
uint64_t addend)
|
|
{
|
|
this->add(od, Output_reloc_type(os, type, od,
|
|
convert_types<Address, uint64_t>(address),
|
|
convert_types<Addend, uint64_t>(addend)));
|
|
}
|
|
|
|
void
|
|
add_output_section_generic(Output_section* os, unsigned int type,
|
|
Output_data* od, Relobj* relobj,
|
|
unsigned int shndx, uint64_t address,
|
|
uint64_t addend)
|
|
{
|
|
Sized_relobj<size, big_endian>* sized_relobj =
|
|
static_cast<Sized_relobj<size, big_endian>*>(relobj);
|
|
this->add(od, Output_reloc_type(os, type, sized_relobj, shndx,
|
|
convert_types<Address, uint64_t>(address),
|
|
convert_types<Addend, uint64_t>(addend)));
|
|
}
|
|
|
// Add an absolute relocation.
|
// Add an absolute relocation.
|
|
|
void
|
void
|
add_absolute(unsigned int type, Output_data* od, Address address,
|
add_absolute(unsigned int type, Output_data* od, Address address,
|
Addend addend)
|
Addend addend)
|
Line 1971... |
Line 2146... |
};
|
};
|
|
|
// Output_data_got is used to manage a GOT. Each entry in the GOT is
|
// Output_data_got is used to manage a GOT. Each entry in the GOT is
|
// for one symbol--either a global symbol or a local symbol in an
|
// for one symbol--either a global symbol or a local symbol in an
|
// object. The target specific code adds entries to the GOT as
|
// object. The target specific code adds entries to the GOT as
|
// needed.
|
// needed. The GOT_SIZE template parameter is the size in bits of a
|
|
// GOT entry, typically 32 or 64.
|
|
|
template<int size, bool big_endian>
|
class Output_data_got_base : public Output_section_data_build
|
class Output_data_got : public Output_section_data_build
|
{
|
|
public:
|
|
Output_data_got_base(uint64_t align)
|
|
: Output_section_data_build(align)
|
|
{ }
|
|
|
|
Output_data_got_base(off_t data_size, uint64_t align)
|
|
: Output_section_data_build(data_size, align)
|
|
{ }
|
|
|
|
// Reserve the slot at index I in the GOT.
|
|
void
|
|
reserve_slot(unsigned int i)
|
|
{ this->do_reserve_slot(i); }
|
|
|
|
protected:
|
|
// Reserve the slot at index I in the GOT.
|
|
virtual void
|
|
do_reserve_slot(unsigned int i) = 0;
|
|
};
|
|
|
|
template<int got_size, bool big_endian>
|
|
class Output_data_got : public Output_data_got_base
|
{
|
{
|
public:
|
public:
|
typedef typename elfcpp::Elf_types<size>::Elf_Addr Valtype;
|
typedef typename elfcpp::Elf_types<got_size>::Elf_Addr Valtype;
|
typedef Output_data_reloc<elfcpp::SHT_REL, true, size, big_endian> Rel_dyn;
|
|
typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian> Rela_dyn;
|
|
|
|
Output_data_got()
|
Output_data_got()
|
: Output_section_data_build(Output_data::default_alignment_for_size(size)),
|
: Output_data_got_base(Output_data::default_alignment_for_size(got_size)),
|
entries_(), free_list_()
|
entries_(), free_list_()
|
{ }
|
{ }
|
|
|
Output_data_got(off_t data_size)
|
Output_data_got(off_t data_size)
|
: Output_section_data_build(data_size,
|
: Output_data_got_base(data_size,
|
Output_data::default_alignment_for_size(size)),
|
Output_data::default_alignment_for_size(got_size)),
|
entries_(), free_list_()
|
entries_(), free_list_()
|
{
|
{
|
// For an incremental update, we have an existing GOT section.
|
// For an incremental update, we have an existing GOT section.
|
// Initialize the list of entries and the free list.
|
// Initialize the list of entries and the free list.
|
this->entries_.resize(data_size / (size / 8));
|
this->entries_.resize(data_size / (got_size / 8));
|
this->free_list_.init(data_size, false);
|
this->free_list_.init(data_size, false);
|
}
|
}
|
|
|
// Add an entry for a global symbol to the GOT. Return true if this
|
// Add an entry for a global symbol to the GOT. Return true if this
|
// is a new GOT entry, false if the symbol was already in the GOT.
|
// is a new GOT entry, false if the symbol was already in the GOT.
|
Line 2011... |
Line 2207... |
|
|
// Add an entry for a global symbol to the GOT, and add a dynamic
|
// Add an entry for a global symbol to the GOT, and add a dynamic
|
// relocation of type R_TYPE for the GOT entry.
|
// relocation of type R_TYPE for the GOT entry.
|
void
|
void
|
add_global_with_rel(Symbol* gsym, unsigned int got_type,
|
add_global_with_rel(Symbol* gsym, unsigned int got_type,
|
Rel_dyn* rel_dyn, unsigned int r_type);
|
Output_data_reloc_generic* rel_dyn, unsigned int r_type);
|
|
|
void
|
|
add_global_with_rela(Symbol* gsym, unsigned int got_type,
|
|
Rela_dyn* rela_dyn, unsigned int r_type);
|
|
|
|
// Add a pair of entries for a global symbol to the GOT, and add
|
// Add a pair of entries for a global symbol to the GOT, and add
|
// dynamic relocations of type R_TYPE_1 and R_TYPE_2, respectively.
|
// dynamic relocations of type R_TYPE_1 and R_TYPE_2, respectively.
|
void
|
void
|
add_global_pair_with_rel(Symbol* gsym, unsigned int got_type,
|
add_global_pair_with_rel(Symbol* gsym, unsigned int got_type,
|
Rel_dyn* rel_dyn, unsigned int r_type_1,
|
Output_data_reloc_generic* rel_dyn,
|
unsigned int r_type_2);
|
unsigned int r_type_1, unsigned int r_type_2);
|
|
|
void
|
|
add_global_pair_with_rela(Symbol* gsym, unsigned int got_type,
|
|
Rela_dyn* rela_dyn, unsigned int r_type_1,
|
|
unsigned int r_type_2);
|
|
|
|
// Add an entry for a local symbol to the GOT. This returns true if
|
// Add an entry for a local symbol to the GOT. This returns true if
|
// this is a new GOT entry, false if the symbol already has a GOT
|
// this is a new GOT entry, false if the symbol already has a GOT
|
// entry.
|
// entry.
|
bool
|
bool
|
add_local(Sized_relobj_file<size, big_endian>* object, unsigned int sym_index,
|
add_local(Relobj* object, unsigned int sym_index, unsigned int got_type);
|
unsigned int got_type);
|
|
|
|
// Like add_local, but use the PLT offset of the local symbol if it
|
// Like add_local, but use the PLT offset of the local symbol if it
|
// has one.
|
// has one.
|
bool
|
bool
|
add_local_plt(Sized_relobj_file<size, big_endian>* object,
|
add_local_plt(Relobj* object, unsigned int sym_index, unsigned int got_type);
|
unsigned int sym_index,
|
|
unsigned int got_type);
|
|
|
|
// Add an entry for a local symbol to the GOT, and add a dynamic
|
// Add an entry for a local symbol to the GOT, and add a dynamic
|
// relocation of type R_TYPE for the GOT entry.
|
// relocation of type R_TYPE for the GOT entry.
|
void
|
void
|
add_local_with_rel(Sized_relobj_file<size, big_endian>* object,
|
add_local_with_rel(Relobj* object, unsigned int sym_index,
|
unsigned int sym_index, unsigned int got_type,
|
unsigned int got_type, Output_data_reloc_generic* rel_dyn,
|
Rel_dyn* rel_dyn, unsigned int r_type);
|
unsigned int r_type);
|
|
|
void
|
|
add_local_with_rela(Sized_relobj_file<size, big_endian>* object,
|
|
unsigned int sym_index, unsigned int got_type,
|
|
Rela_dyn* rela_dyn, unsigned int r_type);
|
|
|
|
// Add a pair of entries for a local symbol to the GOT, and add
|
// Add a pair of entries for a local symbol to the GOT, and add
|
// dynamic relocations of type R_TYPE_1 and R_TYPE_2, respectively.
|
// dynamic relocations of type R_TYPE_1 and R_TYPE_2, respectively.
|
void
|
void
|
add_local_pair_with_rel(Sized_relobj_file<size, big_endian>* object,
|
add_local_pair_with_rel(Relobj* object, unsigned int sym_index,
|
unsigned int sym_index, unsigned int shndx,
|
unsigned int shndx, unsigned int got_type,
|
unsigned int got_type, Rel_dyn* rel_dyn,
|
Output_data_reloc_generic* rel_dyn,
|
unsigned int r_type_1, unsigned int r_type_2);
|
|
|
|
void
|
|
add_local_pair_with_rela(Sized_relobj_file<size, big_endian>* object,
|
|
unsigned int sym_index, unsigned int shndx,
|
|
unsigned int got_type, Rela_dyn* rela_dyn,
|
|
unsigned int r_type_1, unsigned int r_type_2);
|
unsigned int r_type_1, unsigned int r_type_2);
|
|
|
// Add a constant to the GOT. This returns the offset of the new
|
// Add a constant to the GOT. This returns the offset of the new
|
// entry from the start of the GOT.
|
// entry from the start of the GOT.
|
unsigned int
|
unsigned int
|
Line 2078... |
Line 2251... |
{
|
{
|
unsigned int got_offset = this->add_got_entry(Got_entry(constant));
|
unsigned int got_offset = this->add_got_entry(Got_entry(constant));
|
return got_offset;
|
return got_offset;
|
}
|
}
|
|
|
// Reserve a slot in the GOT.
|
|
void
|
|
reserve_slot(unsigned int i)
|
|
{ this->free_list_.remove(i * size / 8, (i + 1) * size / 8); }
|
|
|
|
// Reserve a slot in the GOT for a local symbol.
|
// Reserve a slot in the GOT for a local symbol.
|
void
|
void
|
reserve_local(unsigned int i, Sized_relobj<size, big_endian>* object,
|
reserve_local(unsigned int i, Relobj* object, unsigned int sym_index,
|
unsigned int sym_index, unsigned int got_type);
|
unsigned int got_type);
|
|
|
// Reserve a slot in the GOT for a global symbol.
|
// Reserve a slot in the GOT for a global symbol.
|
void
|
void
|
reserve_global(unsigned int i, Symbol* gsym, unsigned int got_type);
|
reserve_global(unsigned int i, Symbol* gsym, unsigned int got_type);
|
|
|
Line 2102... |
Line 2270... |
// Write to a map file.
|
// Write to a map file.
|
void
|
void
|
do_print_to_mapfile(Mapfile* mapfile) const
|
do_print_to_mapfile(Mapfile* mapfile) const
|
{ mapfile->print_output_data(this, _("** GOT")); }
|
{ mapfile->print_output_data(this, _("** GOT")); }
|
|
|
|
// Reserve the slot at index I in the GOT.
|
|
virtual void
|
|
do_reserve_slot(unsigned int i)
|
|
{ this->free_list_.remove(i * got_size / 8, (i + 1) * got_size / 8); }
|
|
|
private:
|
private:
|
// This POD class holds a single GOT entry.
|
// This POD class holds a single GOT entry.
|
class Got_entry
|
class Got_entry
|
{
|
{
|
public:
|
public:
|
Line 2118... |
Line 2291... |
Got_entry(Symbol* gsym, bool use_plt_offset)
|
Got_entry(Symbol* gsym, bool use_plt_offset)
|
: local_sym_index_(GSYM_CODE), use_plt_offset_(use_plt_offset)
|
: local_sym_index_(GSYM_CODE), use_plt_offset_(use_plt_offset)
|
{ this->u_.gsym = gsym; }
|
{ this->u_.gsym = gsym; }
|
|
|
// Create a local symbol entry.
|
// Create a local symbol entry.
|
Got_entry(Sized_relobj_file<size, big_endian>* object,
|
Got_entry(Relobj* object, unsigned int local_sym_index,
|
unsigned int local_sym_index, bool use_plt_offset)
|
bool use_plt_offset)
|
: local_sym_index_(local_sym_index), use_plt_offset_(use_plt_offset)
|
: local_sym_index_(local_sym_index), use_plt_offset_(use_plt_offset)
|
{
|
{
|
gold_assert(local_sym_index != GSYM_CODE
|
gold_assert(local_sym_index != GSYM_CODE
|
&& local_sym_index != CONSTANT_CODE
|
&& local_sym_index != CONSTANT_CODE
|
&& local_sym_index != RESERVED_CODE
|
&& local_sym_index != RESERVED_CODE
|
Line 2150... |
Line 2323... |
};
|
};
|
|
|
union
|
union
|
{
|
{
|
// For a local symbol, the object.
|
// For a local symbol, the object.
|
Sized_relobj_file<size, big_endian>* object;
|
Relobj* object;
|
// For a global symbol, the symbol.
|
// For a global symbol, the symbol.
|
Symbol* gsym;
|
Symbol* gsym;
|
// For a constant, the constant.
|
// For a constant, the constant.
|
Valtype constant;
|
Valtype constant;
|
} u_;
|
} u_;
|
Line 2176... |
Line 2349... |
add_got_entry_pair(Got_entry got_entry_1, Got_entry got_entry_2);
|
add_got_entry_pair(Got_entry got_entry_1, Got_entry got_entry_2);
|
|
|
// Return the offset into the GOT of GOT entry I.
|
// Return the offset into the GOT of GOT entry I.
|
unsigned int
|
unsigned int
|
got_offset(unsigned int i) const
|
got_offset(unsigned int i) const
|
{ return i * (size / 8); }
|
{ return i * (got_size / 8); }
|
|
|
// Return the offset into the GOT of the last entry added.
|
// Return the offset into the GOT of the last entry added.
|
unsigned int
|
unsigned int
|
last_got_offset() const
|
last_got_offset() const
|
{ return this->got_offset(this->entries_.size() - 1); }
|
{ return this->got_offset(this->entries_.size() - 1); }
|