// sparc.cc -- sparc target support for gold.
-// Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
+// Copyright 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
// Written by David S. Miller <davem@davemloft.net>.
// This file is part of gold.
void
gc_process_relocs(Symbol_table* symtab,
Layout* layout,
- Sized_relobj<size, big_endian>* object,
+ Sized_relobj_file<size, big_endian>* object,
unsigned int data_shndx,
unsigned int sh_type,
const unsigned char* prelocs,
void
scan_relocs(Symbol_table* symtab,
Layout* layout,
- Sized_relobj<size, big_endian>* object,
+ Sized_relobj_file<size, big_endian>* object,
unsigned int data_shndx,
unsigned int sh_type,
const unsigned char* prelocs,
void
scan_relocatable_relocs(Symbol_table* symtab,
Layout* layout,
- Sized_relobj<size, big_endian>* object,
+ Sized_relobj_file<size, big_endian>* object,
unsigned int data_shndx,
unsigned int sh_type,
const unsigned char* prelocs,
inline void
local(Symbol_table* symtab, Layout* layout, Target_sparc* target,
- Sized_relobj<size, big_endian>* object,
+ Sized_relobj_file<size, big_endian>* object,
unsigned int data_shndx,
Output_section* output_section,
const elfcpp::Rela<size, big_endian>& reloc, unsigned int r_type,
inline void
global(Symbol_table* symtab, Layout* layout, Target_sparc* target,
- Sized_relobj<size, big_endian>* object,
+ Sized_relobj_file<size, big_endian>* object,
unsigned int data_shndx,
Output_section* output_section,
const elfcpp::Rela<size, big_endian>& reloc, unsigned int r_type,
inline bool
local_reloc_may_be_function_pointer(Symbol_table* , Layout* ,
Target_sparc* ,
- Sized_relobj<size, big_endian>* ,
+ Sized_relobj_file<size, big_endian>* ,
unsigned int ,
Output_section* ,
const elfcpp::Rela<size, big_endian>& ,
inline bool
global_reloc_may_be_function_pointer(Symbol_table* , Layout* ,
Target_sparc* ,
- Sized_relobj<size, big_endian>* ,
+ Sized_relobj_file<size, big_endian>* ,
unsigned int ,
Output_section* ,
const elfcpp::Rela<size,
private:
static void
- unsupported_reloc_local(Sized_relobj<size, big_endian>*,
+ unsupported_reloc_local(Sized_relobj_file<size, big_endian>*,
unsigned int r_type);
static void
- unsupported_reloc_global(Sized_relobj<size, big_endian>*,
+ unsupported_reloc_global(Sized_relobj_file<size, big_endian>*,
unsigned int r_type, Symbol*);
static void
{
public:
Relocate()
- : ignore_gd_add_(false)
+ : ignore_gd_add_(false), reloc_adjust_addr_(NULL)
{ }
~Relocate()
// Ignore the next relocation which should be R_SPARC_TLS_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,
// Create a GOT entry for the TLS module index.
unsigned int
got_mod_index_entry(Symbol_table* symtab, Layout* layout,
- Sized_relobj<size, big_endian>* object);
+ Sized_relobj_file<size, big_endian>* object);
// Return the gsym for "__tls_get_addr". Cache if not already
// cached.
// Copy a relocation against a global symbol.
void
copy_reloc(Symbol_table* symtab, Layout* layout,
- Sized_relobj<size, big_endian>* object,
+ Sized_relobj_file<size, big_endian>* object,
unsigned int shndx, Output_section* output_section,
Symbol* sym, const elfcpp::Rela<size, big_endian>& reloc)
{
false, // has_resolve
false, // has_code_fill
true, // is_default_stack_executable
+ false, // can_icf_inline_merge_sections
'\0', // wrap_char
"/usr/lib/ld.so.1", // dynamic_linker
0x00010000, // default_text_segment_address
false, // has_resolve
false, // has_code_fill
true, // is_default_stack_executable
+ false, // can_icf_inline_merge_sections
'\0', // wrap_char
"/usr/lib/sparcv9/ld.so.1", // dynamic_linker
0x100000, // default_text_segment_address
rela(unsigned char* view,
unsigned int right_shift,
typename elfcpp::Elf_types<valsize>::Elf_Addr dst_mask,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Swap<valsize, big_endian>::Valtype addend)
{
static inline void
rela_ua(unsigned char* view,
unsigned int right_shift, elfcpp::Elf_Xword dst_mask,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Swap<size, big_endian>::Valtype addend)
{
pcrela(unsigned char* view,
unsigned int right_shift,
typename elfcpp::Elf_types<valsize>::Elf_Addr dst_mask,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Swap<size, big_endian>::Valtype addend,
typename elfcpp::Elf_types<size>::Elf_Addr address)
template<int valsize>
static inline void
pcrela_unaligned(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Swap<size, big_endian>::Valtype addend,
typename elfcpp::Elf_types<size>::Elf_Addr address)
// R_SPARC_WDISP30: (Symbol + Addend - Address) >> 2
static inline void
wdisp30(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend,
typename elfcpp::Elf_types<size>::Elf_Addr address)
// R_SPARC_WDISP22: (Symbol + Addend - Address) >> 2
static inline void
wdisp22(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend,
typename elfcpp::Elf_types<size>::Elf_Addr address)
// R_SPARC_WDISP19: (Symbol + Addend - Address) >> 2
static inline void
wdisp19(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend,
typename elfcpp::Elf_types<size>::Elf_Addr address)
// R_SPARC_WDISP16: (Symbol + Addend - Address) >> 2
static inline void
wdisp16(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend,
typename elfcpp::Elf_types<size>::Elf_Addr address)
// R_SPARC_PC22: (Symbol + Addend - Address) >> 10
static inline void
pc22(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend,
typename elfcpp::Elf_types<size>::Elf_Addr address)
// R_SPARC_PC10: (Symbol + Addend - Address) & 0x3ff
static inline void
pc10(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend,
typename elfcpp::Elf_types<size>::Elf_Addr address)
// R_SPARC_HI22: (Symbol + Addend) >> 10
static inline void
hi22(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend)
{
// R_SPARC_PCPLT22: (Symbol + Addend - Address) >> 10
static inline void
pcplt22(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend,
typename elfcpp::Elf_types<size>::Elf_Addr address)
// R_SPARC_LO10: (Symbol + Addend) & 0x3ff
static inline void
lo10(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend)
{
// R_SPARC_LO10: (Symbol + Addend) & 0x3ff
static inline void
lo10(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend,
typename elfcpp::Elf_types<size>::Elf_Addr address)
// R_SPARC_OLO10: ((Symbol + Addend) & 0x3ff) + Addend2
static inline void
olo10(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend,
typename elfcpp::Elf_types<size>::Elf_Addr addend2)
// R_SPARC_22: (Symbol + Addend)
static inline void
rela32_22(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend)
{
// R_SPARC_13: (Symbol + Addend)
static inline void
rela32_13(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend)
{
// R_SPARC_UA16: (Symbol + Addend)
static inline void
ua16(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend)
{
// R_SPARC_UA32: (Symbol + Addend)
static inline void
ua32(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend)
{
// R_SPARC_UA64: (Symbol + Addend)
static inline void
ua64(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend)
{
// R_SPARC_DISP8: (Symbol + Addend - Address)
static inline void
disp8(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend,
typename elfcpp::Elf_types<size>::Elf_Addr address)
// R_SPARC_DISP16: (Symbol + Addend - Address)
static inline void
disp16(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend,
typename elfcpp::Elf_types<size>::Elf_Addr address)
// R_SPARC_DISP32: (Symbol + Addend - Address)
static inline void
disp32(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend,
typename elfcpp::Elf_types<size>::Elf_Addr address)
// R_SPARC_DISP64: (Symbol + Addend - Address)
static inline void
disp64(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
elfcpp::Elf_Xword addend,
typename elfcpp::Elf_types<size>::Elf_Addr address)
// R_SPARC_H44: (Symbol + Addend) >> 22
static inline void
h44(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend)
{
// R_SPARC_M44: ((Symbol + Addend) >> 12) & 0x3ff
static inline void
m44(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend)
{
// R_SPARC_L44: (Symbol + Addend) & 0xfff
static inline void
l44(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend)
{
// R_SPARC_HH22: (Symbol + Addend) >> 42
static inline void
hh22(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend)
{
// R_SPARC_PC_HH22: (Symbol + Addend - Address) >> 42
static inline void
pc_hh22(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend,
typename elfcpp::Elf_types<size>::Elf_Addr address)
// R_SPARC_HM10: ((Symbol + Addend) >> 32) & 0x3ff
static inline void
hm10(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend)
{
// R_SPARC_PC_HM10: ((Symbol + Addend - Address) >> 32) & 0x3ff
static inline void
pc_hm10(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend,
typename elfcpp::Elf_types<size>::Elf_Addr address)
// R_SPARC_11: (Symbol + Addend)
static inline void
rela32_11(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend)
{
// R_SPARC_10: (Symbol + Addend)
static inline void
rela32_10(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend)
{
// R_SPARC_7: (Symbol + Addend)
static inline void
rela32_7(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend)
{
// R_SPARC_6: (Symbol + Addend)
static inline void
rela32_6(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend)
{
// R_SPARC_5: (Symbol + Addend)
static inline void
rela32_5(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend)
{
// R_SPARC_HIX22: ((Symbol + Addend) ^ 0xffffffffffffffff) >> 10
static inline void
hix22(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend)
{
// R_SPARC_LOX10: ((Symbol + Addend) & 0x3ff) | 0x1c00
static inline void
lox10(unsigned char* view,
- const Sized_relobj<size, big_endian>* object,
+ const Sized_relobj_file<size, big_endian>* object,
const Symbol_value<size>* psymval,
typename elfcpp::Elf_types<size>::Elf_Addr addend)
{
template<int size, bool big_endian>
unsigned int
-Target_sparc<size, big_endian>::got_mod_index_entry(Symbol_table* symtab,
- Layout* layout,
- Sized_relobj<size, big_endian>* object)
+Target_sparc<size, big_endian>::got_mod_index_entry(
+ Symbol_table* symtab,
+ Layout* layout,
+ Sized_relobj_file<size, big_endian>* object)
{
if (this->got_mod_index_offset_ == -1U)
{
template<int size, bool big_endian>
void
Target_sparc<size, big_endian>::Scan::unsupported_reloc_local(
- Sized_relobj<size, big_endian>* object,
+ Sized_relobj_file<size, big_endian>* object,
unsigned int r_type)
{
gold_error(_("%s: unsupported reloc %u against local symbol"),
Symbol_table* symtab,
Layout* layout,
Target_sparc<size, big_endian>* target,
- Sized_relobj<size, big_endian>* object,
+ Sized_relobj_file<size, big_endian>* object,
unsigned int data_shndx,
Output_section* output_section,
const elfcpp::Rela<size, big_endian>& reloc,
rela_dyn->add_local_relative(object, r_sym, elfcpp::R_SPARC_RELATIVE,
output_section, data_shndx,
reloc.get_r_offset(),
- reloc.get_r_addend());
+ reloc.get_r_addend(), false);
}
break;
object->set_local_got_offset(r_sym, GOT_TYPE_STANDARD, off);
rela_dyn->add_local_relative(object, r_sym,
elfcpp::R_SPARC_RELATIVE,
- got, off, 0);
+ got, off, 0, false);
}
}
else
object->error(_("local symbol %u has bad shndx %u"),
r_sym, shndx);
else
- got->add_local_pair_with_rela(object, r_sym,
- lsym.get_st_shndx(),
- GOT_TYPE_TLS_PAIR,
- target->rela_dyn_section(layout),
- (size == 64
- ? elfcpp::R_SPARC_TLS_DTPMOD64
- : elfcpp::R_SPARC_TLS_DTPMOD32),
- 0);
+ got->add_local_pair_with_rel(object, r_sym,
+ lsym.get_st_shndx(),
+ GOT_TYPE_TLS_PAIR,
+ target->rela_dyn_section(layout),
+ (size == 64
+ ? elfcpp::R_SPARC_TLS_DTPMOD64
+ : elfcpp::R_SPARC_TLS_DTPMOD32),
+ 0);
if (r_type == elfcpp::R_SPARC_TLS_GD_CALL)
generate_tls_call(symtab, layout, target);
}
template<int size, bool big_endian>
void
Target_sparc<size, big_endian>::Scan::unsupported_reloc_global(
- Sized_relobj<size, big_endian>* object,
+ Sized_relobj_file<size, big_endian>* object,
unsigned int r_type,
Symbol* gsym)
{
Symbol_table* symtab,
Layout* layout,
Target_sparc<size, big_endian>* target,
- Sized_relobj<size, big_endian>* object,
+ Sized_relobj_file<size, big_endian>* object,
unsigned int data_shndx,
Output_section* output_section,
const elfcpp::Rela<size, big_endian>& reloc,
if (gsym->is_from_dynobj()
|| gsym->is_undefined()
|| gsym->is_preemptible())
- got->add_global_with_rela(gsym, GOT_TYPE_STANDARD, rela_dyn,
- elfcpp::R_SPARC_GLOB_DAT);
+ got->add_global_with_rel(gsym, GOT_TYPE_STANDARD, rela_dyn,
+ elfcpp::R_SPARC_GLOB_DAT);
else if (!gsym->has_got_offset(GOT_TYPE_STANDARD))
{
unsigned int off = got->add_constant(0);
// dtv-relative offset.
Output_data_got<size, big_endian>* got
= target->got_section(symtab, layout);
- got->add_global_pair_with_rela(gsym, GOT_TYPE_TLS_PAIR,
- target->rela_dyn_section(layout),
- (size == 64 ?
- elfcpp::R_SPARC_TLS_DTPMOD64 :
- elfcpp::R_SPARC_TLS_DTPMOD32),
- (size == 64 ?
- elfcpp::R_SPARC_TLS_DTPOFF64 :
- elfcpp::R_SPARC_TLS_DTPOFF32));
+ got->add_global_pair_with_rel(gsym, GOT_TYPE_TLS_PAIR,
+ target->rela_dyn_section(layout),
+ (size == 64
+ ? elfcpp::R_SPARC_TLS_DTPMOD64
+ : elfcpp::R_SPARC_TLS_DTPMOD32),
+ (size == 64
+ ? elfcpp::R_SPARC_TLS_DTPOFF64
+ : elfcpp::R_SPARC_TLS_DTPOFF32));
// Emit R_SPARC_WPLT30 against "__tls_get_addr"
if (r_type == elfcpp::R_SPARC_TLS_GD_CALL)
// Create a GOT entry for the tp-relative offset.
Output_data_got<size, big_endian>* got
= target->got_section(symtab, layout);
- got->add_global_with_rela(gsym, GOT_TYPE_TLS_OFFSET,
- target->rela_dyn_section(layout),
- (size == 64 ?
- elfcpp::R_SPARC_TLS_TPOFF64 :
- elfcpp::R_SPARC_TLS_TPOFF32));
+ got->add_global_with_rel(gsym, GOT_TYPE_TLS_OFFSET,
+ target->rela_dyn_section(layout),
+ (size == 64 ?
+ elfcpp::R_SPARC_TLS_TPOFF64 :
+ elfcpp::R_SPARC_TLS_TPOFF32));
}
else if (optimized_type != tls::TLSOPT_TO_LE)
unsupported_reloc_global(object, r_type, gsym);
// Create a GOT entry for the tp-relative offset.
Output_data_got<size, big_endian>* got
= target->got_section(symtab, layout);
- got->add_global_with_rela(gsym, GOT_TYPE_TLS_OFFSET,
- target->rela_dyn_section(layout),
- (size == 64 ?
- elfcpp::R_SPARC_TLS_TPOFF64 :
- elfcpp::R_SPARC_TLS_TPOFF32));
+ got->add_global_with_rel(gsym, GOT_TYPE_TLS_OFFSET,
+ target->rela_dyn_section(layout),
+ (size == 64
+ ? elfcpp::R_SPARC_TLS_TPOFF64
+ : elfcpp::R_SPARC_TLS_TPOFF32));
}
else if (optimized_type != tls::TLSOPT_TO_LE)
unsupported_reloc_global(object, r_type, gsym);
Target_sparc<size, big_endian>::gc_process_relocs(
Symbol_table* symtab,
Layout* layout,
- Sized_relobj<size, big_endian>* object,
+ Sized_relobj_file<size, big_endian>* object,
unsigned int data_shndx,
unsigned int,
const unsigned char* prelocs,
Target_sparc<size, big_endian>::scan_relocs(
Symbol_table* symtab,
Layout* layout,
- Sized_relobj<size, big_endian>* object,
+ Sized_relobj_file<size, big_endian>* object,
unsigned int data_shndx,
unsigned int sh_type,
const unsigned char* prelocs,
return false;
}
}
+ if (this->reloc_adjust_addr_ == view)
+ view -= 4;
typedef Sparc_relocate_functions<size, big_endian> Reloc;
psymval = &symval;
}
- const Sized_relobj<size, big_endian>* object = relinfo->object;
+ const Sized_relobj_file<size, big_endian>* object = relinfo->object;
const elfcpp::Elf_Xword addend = rela.get_r_addend();
// Get the GOT offset if needed. Unlike i386 and x86_64, our GOT
{
Output_segment* tls_segment = relinfo->layout->tls_segment();
typedef Sparc_relocate_functions<size, big_endian> Reloc;
- const Sized_relobj<size, big_endian>* object = relinfo->object;
+ const Sized_relobj_file<size, big_endian>* object = relinfo->object;
typedef typename elfcpp::Swap<32, true>::Valtype Insntype;
const elfcpp::Elf_Xword addend = rela.get_r_addend();
wv += 1;
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
elfcpp::Swap<32, true>::writeval(wv, 0x9001c008);
break;
Target_sparc<size, big_endian>::scan_relocatable_relocs(
Symbol_table* symtab,
Layout* layout,
- Sized_relobj<size, big_endian>* object,
+ Sized_relobj_file<size, big_endian>* object,
unsigned int data_shndx,
unsigned int sh_type,
const unsigned char* prelocs,
public:
Target_selector_sparc()
: Target_selector(elfcpp::EM_NONE, size, big_endian,
- (size == 64 ? "elf64-sparc" : "elf32-sparc"))
+ (size == 64 ? "elf64-sparc" : "elf32-sparc"),
+ (size == 64 ? "elf64_sparc" : "elf32_sparc"))
{ }
Target* do_recognize(int machine, int, int)