Line 1385... |
Line 1385... |
val = this->u_.constant;
|
val = this->u_.constant;
|
break;
|
break;
|
|
|
default:
|
default:
|
{
|
{
|
const Sized_relobj_file<size, big_endian>* object = this->u_.object;
|
const Relobj* object = this->u_.object;
|
const unsigned int lsi = this->local_sym_index_;
|
const unsigned int lsi = this->local_sym_index_;
|
const Symbol_value<size>* symval = object->local_symbol(lsi);
|
|
if (!this->use_plt_offset_)
|
if (!this->use_plt_offset_)
|
val = symval->value(this->u_.object, 0);
|
{
|
|
uint64_t lval = object->local_symbol_value(lsi, 0);
|
|
val = convert_types<Valtype, uint64_t>(lval);
|
|
}
|
else
|
else
|
{
|
{
|
uint64_t plt_address =
|
uint64_t plt_address =
|
parameters->target().plt_address_for_local(object, lsi);
|
parameters->target().plt_address_for_local(object, lsi);
|
val = plt_address + object->local_plt_offset(lsi);
|
val = plt_address + object->local_plt_offset(lsi);
|
Line 1446... |
Line 1448... |
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
void
|
void
|
Output_data_got<size, big_endian>::add_global_with_rel(
|
Output_data_got<size, big_endian>::add_global_with_rel(
|
Symbol* gsym,
|
Symbol* gsym,
|
unsigned int got_type,
|
unsigned int got_type,
|
Rel_dyn* rel_dyn,
|
Output_data_reloc_generic* rel_dyn,
|
unsigned int r_type)
|
|
{
|
|
if (gsym->has_got_offset(got_type))
|
|
return;
|
|
|
|
unsigned int got_offset = this->add_got_entry(Got_entry());
|
|
gsym->set_got_offset(got_type, got_offset);
|
|
rel_dyn->add_global(gsym, r_type, this, got_offset);
|
|
}
|
|
|
|
template<int size, bool big_endian>
|
|
void
|
|
Output_data_got<size, big_endian>::add_global_with_rela(
|
|
Symbol* gsym,
|
|
unsigned int got_type,
|
|
Rela_dyn* rela_dyn,
|
|
unsigned int r_type)
|
unsigned int r_type)
|
{
|
{
|
if (gsym->has_got_offset(got_type))
|
if (gsym->has_got_offset(got_type))
|
return;
|
return;
|
|
|
unsigned int got_offset = this->add_got_entry(Got_entry());
|
unsigned int got_offset = this->add_got_entry(Got_entry());
|
gsym->set_got_offset(got_type, got_offset);
|
gsym->set_got_offset(got_type, got_offset);
|
rela_dyn->add_global(gsym, r_type, this, got_offset, 0);
|
rel_dyn->add_global_generic(gsym, r_type, this, got_offset, 0);
|
}
|
}
|
|
|
// 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.
|
// If R_TYPE_2 == 0, add the second entry with no relocation.
|
// If R_TYPE_2 == 0, add the second entry with no relocation.
|
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
void
|
void
|
Output_data_got<size, big_endian>::add_global_pair_with_rel(
|
Output_data_got<size, big_endian>::add_global_pair_with_rel(
|
Symbol* gsym,
|
Symbol* gsym,
|
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)
|
|
{
|
|
if (gsym->has_got_offset(got_type))
|
|
return;
|
|
|
|
unsigned int got_offset = this->add_got_entry_pair(Got_entry(), Got_entry());
|
|
gsym->set_got_offset(got_type, got_offset);
|
|
rel_dyn->add_global(gsym, r_type_1, this, got_offset);
|
|
|
|
if (r_type_2 != 0)
|
|
rel_dyn->add_global(gsym, r_type_2, this, got_offset + size / 8);
|
|
}
|
|
|
|
template<int size, bool big_endian>
|
|
void
|
|
Output_data_got<size, big_endian>::add_global_pair_with_rela(
|
|
Symbol* gsym,
|
|
unsigned int got_type,
|
|
Rela_dyn* rela_dyn,
|
|
unsigned int r_type_1,
|
unsigned int r_type_1,
|
unsigned int r_type_2)
|
unsigned int r_type_2)
|
{
|
{
|
if (gsym->has_got_offset(got_type))
|
if (gsym->has_got_offset(got_type))
|
return;
|
return;
|
|
|
unsigned int got_offset = this->add_got_entry_pair(Got_entry(), Got_entry());
|
unsigned int got_offset = this->add_got_entry_pair(Got_entry(), Got_entry());
|
gsym->set_got_offset(got_type, got_offset);
|
gsym->set_got_offset(got_type, got_offset);
|
rela_dyn->add_global(gsym, r_type_1, this, got_offset, 0);
|
rel_dyn->add_global_generic(gsym, r_type_1, this, got_offset, 0);
|
|
|
if (r_type_2 != 0)
|
if (r_type_2 != 0)
|
rela_dyn->add_global(gsym, r_type_2, this, got_offset + size / 8, 0);
|
rel_dyn->add_global_generic(gsym, r_type_2, this,
|
|
got_offset + size / 8, 0);
|
}
|
}
|
|
|
// 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.
|
|
|
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
bool
|
bool
|
Output_data_got<size, big_endian>::add_local(
|
Output_data_got<size, big_endian>::add_local(
|
Sized_relobj_file<size, big_endian>* object,
|
Relobj* object,
|
unsigned int symndx,
|
unsigned int symndx,
|
unsigned int got_type)
|
unsigned int got_type)
|
{
|
{
|
if (object->local_has_got_offset(symndx, got_type))
|
if (object->local_has_got_offset(symndx, got_type))
|
return false;
|
return false;
|
Line 1541... |
Line 1508... |
// Like add_local, but use the PLT offset.
|
// Like add_local, but use the PLT offset.
|
|
|
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
bool
|
bool
|
Output_data_got<size, big_endian>::add_local_plt(
|
Output_data_got<size, big_endian>::add_local_plt(
|
Sized_relobj_file<size, big_endian>* object,
|
Relobj* object,
|
unsigned int symndx,
|
unsigned int symndx,
|
unsigned int got_type)
|
unsigned int got_type)
|
{
|
{
|
if (object->local_has_got_offset(symndx, got_type))
|
if (object->local_has_got_offset(symndx, got_type))
|
return false;
|
return false;
|
Line 1560... |
Line 1527... |
// relocation of type R_TYPE for the GOT entry.
|
// relocation of type R_TYPE for the GOT entry.
|
|
|
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
void
|
void
|
Output_data_got<size, big_endian>::add_local_with_rel(
|
Output_data_got<size, big_endian>::add_local_with_rel(
|
Sized_relobj_file<size, big_endian>* object,
|
Relobj* object,
|
unsigned int symndx,
|
|
unsigned int got_type,
|
|
Rel_dyn* rel_dyn,
|
|
unsigned int r_type)
|
|
{
|
|
if (object->local_has_got_offset(symndx, got_type))
|
|
return;
|
|
|
|
unsigned int got_offset = this->add_got_entry(Got_entry());
|
|
object->set_local_got_offset(symndx, got_type, got_offset);
|
|
rel_dyn->add_local(object, symndx, r_type, this, got_offset);
|
|
}
|
|
|
|
template<int size, bool big_endian>
|
|
void
|
|
Output_data_got<size, big_endian>::add_local_with_rela(
|
|
Sized_relobj_file<size, big_endian>* object,
|
|
unsigned int symndx,
|
unsigned int symndx,
|
unsigned int got_type,
|
unsigned int got_type,
|
Rela_dyn* rela_dyn,
|
Output_data_reloc_generic* rel_dyn,
|
unsigned int r_type)
|
unsigned int r_type)
|
{
|
{
|
if (object->local_has_got_offset(symndx, got_type))
|
if (object->local_has_got_offset(symndx, got_type))
|
return;
|
return;
|
|
|
unsigned int got_offset = this->add_got_entry(Got_entry());
|
unsigned int got_offset = this->add_got_entry(Got_entry());
|
object->set_local_got_offset(symndx, got_type, got_offset);
|
object->set_local_got_offset(symndx, got_type, got_offset);
|
rela_dyn->add_local(object, symndx, r_type, this, got_offset, 0);
|
rel_dyn->add_local_generic(object, symndx, r_type, this, got_offset, 0);
|
}
|
}
|
|
|
// 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.
|
// If R_TYPE_2 == 0, add the second entry with no relocation.
|
// If R_TYPE_2 == 0, add the second entry with no relocation.
|
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
void
|
void
|
Output_data_got<size, big_endian>::add_local_pair_with_rel(
|
Output_data_got<size, big_endian>::add_local_pair_with_rel(
|
Sized_relobj_file<size, big_endian>* object,
|
Relobj* object,
|
unsigned int symndx,
|
|
unsigned int shndx,
|
|
unsigned int got_type,
|
|
Rel_dyn* rel_dyn,
|
|
unsigned int r_type_1,
|
|
unsigned int r_type_2)
|
|
{
|
|
if (object->local_has_got_offset(symndx, got_type))
|
|
return;
|
|
|
|
unsigned int got_offset =
|
|
this->add_got_entry_pair(Got_entry(),
|
|
Got_entry(object, symndx, false));
|
|
object->set_local_got_offset(symndx, got_type, got_offset);
|
|
Output_section* os = object->output_section(shndx);
|
|
rel_dyn->add_output_section(os, r_type_1, this, got_offset);
|
|
|
|
if (r_type_2 != 0)
|
|
rel_dyn->add_output_section(os, r_type_2, this, got_offset + size / 8);
|
|
}
|
|
|
|
template<int size, bool big_endian>
|
|
void
|
|
Output_data_got<size, big_endian>::add_local_pair_with_rela(
|
|
Sized_relobj_file<size, big_endian>* object,
|
|
unsigned int symndx,
|
unsigned int symndx,
|
unsigned int shndx,
|
unsigned int shndx,
|
unsigned int got_type,
|
unsigned int got_type,
|
Rela_dyn* rela_dyn,
|
Output_data_reloc_generic* rel_dyn,
|
unsigned int r_type_1,
|
unsigned int r_type_1,
|
unsigned int r_type_2)
|
unsigned int r_type_2)
|
{
|
{
|
if (object->local_has_got_offset(symndx, got_type))
|
if (object->local_has_got_offset(symndx, got_type))
|
return;
|
return;
|
Line 1638... |
Line 1563... |
unsigned int got_offset =
|
unsigned int got_offset =
|
this->add_got_entry_pair(Got_entry(),
|
this->add_got_entry_pair(Got_entry(),
|
Got_entry(object, symndx, false));
|
Got_entry(object, symndx, false));
|
object->set_local_got_offset(symndx, got_type, got_offset);
|
object->set_local_got_offset(symndx, got_type, got_offset);
|
Output_section* os = object->output_section(shndx);
|
Output_section* os = object->output_section(shndx);
|
rela_dyn->add_output_section(os, r_type_1, this, got_offset, 0);
|
rel_dyn->add_output_section_generic(os, r_type_1, this, got_offset, 0);
|
|
|
if (r_type_2 != 0)
|
if (r_type_2 != 0)
|
rela_dyn->add_output_section(os, r_type_2, this, got_offset + size / 8, 0);
|
rel_dyn->add_output_section_generic(os, r_type_2, this,
|
|
got_offset + size / 8, 0);
|
}
|
}
|
|
|
// Reserve a slot in the GOT for a local symbol or the second slot of a pair.
|
// Reserve a slot in the GOT for a local symbol or the second slot of a pair.
|
|
|
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
void
|
void
|
Output_data_got<size, big_endian>::reserve_local(
|
Output_data_got<size, big_endian>::reserve_local(
|
unsigned int i,
|
unsigned int i,
|
Sized_relobj<size, big_endian>* object,
|
Relobj* object,
|
unsigned int sym_index,
|
unsigned int sym_index,
|
unsigned int got_type)
|
unsigned int got_type)
|
{
|
{
|
this->reserve_slot(i);
|
this->do_reserve_slot(i);
|
object->set_local_got_offset(sym_index, got_type, this->got_offset(i));
|
object->set_local_got_offset(sym_index, got_type, this->got_offset(i));
|
}
|
}
|
|
|
// Reserve a slot in the GOT for a global symbol.
|
// Reserve a slot in the GOT for a global symbol.
|
|
|
Line 1667... |
Line 1593... |
Output_data_got<size, big_endian>::reserve_global(
|
Output_data_got<size, big_endian>::reserve_global(
|
unsigned int i,
|
unsigned int i,
|
Symbol* gsym,
|
Symbol* gsym,
|
unsigned int got_type)
|
unsigned int got_type)
|
{
|
{
|
this->reserve_slot(i);
|
this->do_reserve_slot(i);
|
gsym->set_got_offset(got_type, this->got_offset(i));
|
gsym->set_got_offset(got_type, this->got_offset(i));
|
}
|
}
|
|
|
// Write out the GOT.
|
// Write out the GOT.
|
|
|