Line 263... |
Line 263... |
// The class which implements relocation.
|
// The class which implements relocation.
|
class Relocate
|
class Relocate
|
{
|
{
|
public:
|
public:
|
Relocate()
|
Relocate()
|
: ignore_gd_add_(false)
|
: ignore_gd_add_(false), reloc_adjust_addr_(NULL)
|
{ }
|
{ }
|
|
|
~Relocate()
|
~Relocate()
|
{
|
{
|
if (this->ignore_gd_add_)
|
if (this->ignore_gd_add_)
|
Line 300... |
Line 300... |
typename elfcpp::Elf_types<size>::Elf_Addr,
|
typename elfcpp::Elf_types<size>::Elf_Addr,
|
section_size_type);
|
section_size_type);
|
|
|
// Ignore the next relocation which should be R_SPARC_TLS_GD_ADD
|
// Ignore the next relocation which should be R_SPARC_TLS_GD_ADD
|
bool ignore_gd_add_;
|
bool ignore_gd_add_;
|
|
|
|
// If we hit a reloc at this view address, adjust it back by 4 bytes.
|
|
unsigned char *reloc_adjust_addr_;
|
};
|
};
|
|
|
// A class which returns the size required for a relocation type,
|
// A class which returns the size required for a relocation type,
|
// used while scanning relocs during a relocatable link.
|
// used while scanning relocs during a relocatable link.
|
class Relocatable_size_for_reloc
|
class Relocatable_size_for_reloc
|
Line 1850... |
Line 1853... |
Reloc_section* rela_dyn = target->rela_dyn_section(layout);
|
Reloc_section* rela_dyn = target->rela_dyn_section(layout);
|
unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
|
unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
|
rela_dyn->add_local_relative(object, r_sym, elfcpp::R_SPARC_RELATIVE,
|
rela_dyn->add_local_relative(object, r_sym, elfcpp::R_SPARC_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(), false);
|
}
|
}
|
break;
|
break;
|
|
|
case elfcpp::R_SPARC_HIX22:
|
case elfcpp::R_SPARC_HIX22:
|
case elfcpp::R_SPARC_LOX10:
|
case elfcpp::R_SPARC_LOX10:
|
Line 1941... |
Line 1944... |
|
|
off = got->add_constant(0);
|
off = got->add_constant(0);
|
object->set_local_got_offset(r_sym, GOT_TYPE_STANDARD, off);
|
object->set_local_got_offset(r_sym, GOT_TYPE_STANDARD, off);
|
rela_dyn->add_local_relative(object, r_sym,
|
rela_dyn->add_local_relative(object, r_sym,
|
elfcpp::R_SPARC_RELATIVE,
|
elfcpp::R_SPARC_RELATIVE,
|
got, off, 0);
|
got, off, 0, false);
|
}
|
}
|
}
|
}
|
else
|
else
|
got->add_local(object, r_sym, GOT_TYPE_STANDARD);
|
got->add_local(object, r_sym, GOT_TYPE_STANDARD);
|
}
|
}
|
Line 2620... |
Line 2623... |
{
|
{
|
this->ignore_gd_add_ = false;
|
this->ignore_gd_add_ = false;
|
return false;
|
return false;
|
}
|
}
|
}
|
}
|
|
if (this->reloc_adjust_addr_ == view)
|
|
view -= 4;
|
|
|
typedef Sparc_relocate_functions<size, big_endian> Reloc;
|
typedef Sparc_relocate_functions<size, big_endian> Reloc;
|
|
|
// Pick the value to use for symbols defined in shared objects.
|
// Pick the value to use for symbols defined in shared objects.
|
Symbol_value<size> symval;
|
Symbol_value<size> symval;
|
Line 3099... |
Line 3104... |
elfcpp::Swap<32, true>::writeval(wv, val);
|
elfcpp::Swap<32, true>::writeval(wv, val);
|
|
|
wv += 1;
|
wv += 1;
|
this->ignore_gd_add_ = true;
|
this->ignore_gd_add_ = true;
|
}
|
}
|
|
else
|
|
{
|
|
// Even if the delay slot isn't the TLS_GD_ADD
|
|
// instruction, we still have to handle the case
|
|
// where it sets up %o0 in some other way.
|
|
elfcpp::Swap<32, true>::writeval(wv, val);
|
|
wv += 1;
|
|
this->reloc_adjust_addr_ = view + 4;
|
|
}
|
// call __tls_get_addr --> add %g7, %o0, %o0
|
// call __tls_get_addr --> add %g7, %o0, %o0
|
elfcpp::Swap<32, true>::writeval(wv, 0x9001c008);
|
elfcpp::Swap<32, true>::writeval(wv, 0x9001c008);
|
break;
|
break;
|
}
|
}
|
break;
|
break;
|