Line 1547... |
Line 1547... |
switch (got_type)
|
switch (got_type)
|
{
|
{
|
case GOT_TYPE_STANDARD:
|
case GOT_TYPE_STANDARD:
|
if (parameters->options().output_is_position_independent())
|
if (parameters->options().output_is_position_independent())
|
rela_dyn->add_local_relative(obj, r_sym, elfcpp::R_X86_64_RELATIVE,
|
rela_dyn->add_local_relative(obj, r_sym, elfcpp::R_X86_64_RELATIVE,
|
this->got_, got_offset, 0);
|
this->got_, got_offset, 0, false);
|
break;
|
break;
|
case GOT_TYPE_TLS_OFFSET:
|
case GOT_TYPE_TLS_OFFSET:
|
rela_dyn->add_local(obj, r_sym, elfcpp::R_X86_64_TPOFF64,
|
rela_dyn->add_local(obj, r_sym, elfcpp::R_X86_64_TPOFF64,
|
this->got_, got_offset, 0);
|
this->got_, got_offset, 0);
|
break;
|
break;
|
Line 1951... |
Line 1951... |
const elfcpp::Rela<64, false>& reloc,
|
const elfcpp::Rela<64, false>& reloc,
|
unsigned int r_type,
|
unsigned int r_type,
|
const elfcpp::Sym<64, false>& lsym)
|
const elfcpp::Sym<64, false>& lsym)
|
{
|
{
|
// A local STT_GNU_IFUNC symbol may require a PLT entry.
|
// A local STT_GNU_IFUNC symbol may require a PLT entry.
|
if (lsym.get_st_type() == elfcpp::STT_GNU_IFUNC
|
bool is_ifunc = lsym.get_st_type() == elfcpp::STT_GNU_IFUNC;
|
&& this->reloc_needs_plt_for_ifunc(object, r_type))
|
if (is_ifunc && this->reloc_needs_plt_for_ifunc(object, r_type))
|
{
|
{
|
unsigned int r_sym = elfcpp::elf_r_sym<64>(reloc.get_r_info());
|
unsigned int r_sym = elfcpp::elf_r_sym<64>(reloc.get_r_info());
|
target->make_local_ifunc_plt_entry(symtab, layout, object, r_sym);
|
target->make_local_ifunc_plt_entry(symtab, layout, object, r_sym);
|
}
|
}
|
|
|
Line 1980... |
Line 1980... |
Reloc_section* rela_dyn = target->rela_dyn_section(layout);
|
Reloc_section* rela_dyn = target->rela_dyn_section(layout);
|
rela_dyn->add_local_relative(object, r_sym,
|
rela_dyn->add_local_relative(object, r_sym,
|
elfcpp::R_X86_64_RELATIVE,
|
elfcpp::R_X86_64_RELATIVE,
|
output_section, data_shndx,
|
output_section, data_shndx,
|
reloc.get_r_offset(),
|
reloc.get_r_offset(),
|
reloc.get_r_addend());
|
reloc.get_r_addend(), is_ifunc);
|
}
|
}
|
break;
|
break;
|
|
|
case elfcpp::R_X86_64_32:
|
case elfcpp::R_X86_64_32:
|
case elfcpp::R_X86_64_32S:
|
case elfcpp::R_X86_64_32S:
|
Line 2056... |
Line 2056... |
|
|
// For a STT_GNU_IFUNC symbol we want the PLT offset. That
|
// For a STT_GNU_IFUNC symbol we want the PLT offset. That
|
// lets function pointers compare correctly with shared
|
// lets function pointers compare correctly with shared
|
// libraries. Otherwise we would need an IRELATIVE reloc.
|
// libraries. Otherwise we would need an IRELATIVE reloc.
|
bool is_new;
|
bool is_new;
|
if (lsym.get_st_type() == elfcpp::STT_GNU_IFUNC)
|
if (is_ifunc)
|
is_new = got->add_local_plt(object, r_sym, GOT_TYPE_STANDARD);
|
is_new = got->add_local_plt(object, r_sym, GOT_TYPE_STANDARD);
|
else
|
else
|
is_new = got->add_local(object, r_sym, GOT_TYPE_STANDARD);
|
is_new = got->add_local(object, r_sym, GOT_TYPE_STANDARD);
|
if (is_new)
|
if (is_new)
|
{
|
{
|
Line 2074... |
Line 2074... |
{
|
{
|
unsigned int got_offset =
|
unsigned int got_offset =
|
object->local_got_offset(r_sym, GOT_TYPE_STANDARD);
|
object->local_got_offset(r_sym, GOT_TYPE_STANDARD);
|
rela_dyn->add_local_relative(object, r_sym,
|
rela_dyn->add_local_relative(object, r_sym,
|
elfcpp::R_X86_64_RELATIVE,
|
elfcpp::R_X86_64_RELATIVE,
|
got, got_offset, 0);
|
got, got_offset, 0, is_ifunc);
|
}
|
}
|
else
|
else
|
{
|
{
|
this->check_non_pic(object, r_type, NULL);
|
this->check_non_pic(object, r_type, NULL);
|
|
|
Line 3179... |
Line 3179... |
got_offset = (object->local_got_offset(r_sym, got_type)
|
got_offset = (object->local_got_offset(r_sym, got_type)
|
- target->got_size());
|
- target->got_size());
|
}
|
}
|
if (optimized_type == tls::TLSOPT_TO_IE)
|
if (optimized_type == tls::TLSOPT_TO_IE)
|
{
|
{
|
if (tls_segment == NULL)
|
|
{
|
|
gold_assert(parameters->errors()->error_count() > 0
|
|
|| issue_undefined_symbol_error(gsym));
|
|
return;
|
|
}
|
|
value = target->got_plt_section()->address() + got_offset;
|
value = target->got_plt_section()->address() + got_offset;
|
this->tls_gd_to_ie(relinfo, relnum, tls_segment, rela, r_type,
|
this->tls_gd_to_ie(relinfo, relnum, tls_segment, rela, r_type,
|
value, view, address, view_size);
|
value, view, address, view_size);
|
break;
|
break;
|
}
|
}
|