aboutsummaryrefslogtreecommitdiff
path: root/gold/sparc.cc
diff options
context:
space:
mode:
authorDavid S. Miller <davem@redhat.com>2012-04-12 16:26:06 +0000
committerDavid S. Miller <davem@redhat.com>2012-04-12 16:26:06 +0000
commit2615994e91176ae1a147439f81c452e5f5965920 (patch)
tree39fad336d6e5c3c564bd15e377256d88b737447c /gold/sparc.cc
parent214d508ee1d179d6c9e0e993d68628a0bc477124 (diff)
downloadfsf-binutils-gdb-2615994e91176ae1a147439f81c452e5f5965920.zip
fsf-binutils-gdb-2615994e91176ae1a147439f81c452e5f5965920.tar.gz
fsf-binutils-gdb-2615994e91176ae1a147439f81c452e5f5965920.tar.bz2
Support R_SPARC_WDISP10 and R_SPARC_H34.
include/ * elf/sparc.h (R_SPARC_WDISP10): New reloc. * opcode/sparc.h: Define '=' as generating R_SPARC_WDISP10. opcodes/ * sparc-dis.c (X_DISP10): Define. (print_insn_sparc): Handle '='. bfd/ * reloc.c (BFD_RELOC_SPARC_H34, BFD_RELOC_SPARC_SIZE32, BFD_RELOC_SPARC_SIZE64, BFD_RELOC_SPARC_WDISP10): New relocs. * libbfd.h: Regenerate. * bfd-in2.h: Likewise. * elfxx-sparc.c (sparc_elf_wdisp10_reloc): New function. (_bfd_sparc_elf_howto_table): Add entries for R_SPARC_H34, R_SPARC_SIZE32, R_SPARC_64, and R_SPARC_WDISP10. (_bfd_sparc_elf_reloc_type_lookup): Handle new relocs. (_bfd_sparc_elf_check_relocs): Likewise. (_bfd_sparc_elf_gc_sweep_hook): Likewise. (_bfd_sparc_elf_relocate_section): Likewise. gas/ * config/tc-sparc.c (sparc_ip): Handle '=', "%h34", "%l34", and BFD_RELOC_SPARC_H34. (md_apply_fix): Handle BFD_RELOC_SPARC_WDISP10 and BFD_RELOC_SPARC_H34. (tc_gen_reloc): Likewise. gas/testsuite/ * gas/sparc/reloc64.s: Add abs34 code model tests. * gas/sparc/reloc64.d: Update. elfcpp/ * sparc.h (R_SPARC_WDISP10): New relocation. gold/ * sparc.cc (Reloc::wdisp10): New relocation method. (Reloc::h34): Likewise. (Target_sparc::Scan::check_non_pic): Handle R_SPARC_H34. (Target_sparc::Scan::get_reference_flags): Handle R_SPARC_H34 and R_SPARC_WDISP10. (Target_sparc::Scan::local): Likewise. (Target_sparc::Scan::global): Likewise. (Target_sparc::Relocate::relocate): Likewise.
Diffstat (limited to 'gold/sparc.cc')
-rw-r--r--gold/sparc.cc48
1 files changed, 48 insertions, 0 deletions
diff --git a/gold/sparc.cc b/gold/sparc.cc
index 39c7e7c..ee82367 100644
--- a/gold/sparc.cc
+++ b/gold/sparc.cc
@@ -617,6 +617,29 @@ public:
elfcpp::Swap<32, true>::writeval(wv, val | reloc);
}
+ // R_SPARC_WDISP10: (Symbol + Addend - Address) >> 2
+ static inline void
+ wdisp10(unsigned char* view,
+ 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)
+ {
+ typedef typename elfcpp::Swap<32, true>::Valtype Valtype;
+ Valtype* wv = reinterpret_cast<Valtype*>(view);
+ Valtype val = elfcpp::Swap<32, true>::readval(wv);
+ Valtype reloc = ((psymval->value(object, addend) - address)
+ >> 2);
+
+ // The relocation value is split between the low bits 5-12,
+ // and high bits 19-20.
+ val &= ~((0x3 << 19) | (0xff << 5));
+ reloc = (((reloc & 0x300) << (19 - 8))
+ | ((reloc & 0xff) << (5 - 0)));
+
+ elfcpp::Swap<32, true>::writeval(wv, val | reloc);
+ }
+
// R_SPARC_PC22: (Symbol + Addend - Address) >> 10
static inline void
pc22(unsigned char* view,
@@ -832,6 +855,16 @@ public:
addend, address);
}
+ // R_SPARC_H34: (Symbol + Addend) >> 12
+ static inline void
+ h34(unsigned char* view,
+ const Sized_relobj_file<size, big_endian>* object,
+ const Symbol_value<size>* psymval,
+ typename elfcpp::Elf_types<size>::Elf_Addr addend)
+ {
+ This_insn::template rela<32>(view, 12, 0x003fffff, object, psymval, addend);
+ }
+
// R_SPARC_H44: (Symbol + Addend) >> 22
static inline void
h44(unsigned char* view,
@@ -1605,6 +1638,7 @@ Target_sparc<size, big_endian>::Scan::get_reference_flags(unsigned int r_type)
case elfcpp::R_SPARC_64:
case elfcpp::R_SPARC_HIX22:
case elfcpp::R_SPARC_LOX10:
+ case elfcpp::R_SPARC_H34:
case elfcpp::R_SPARC_H44:
case elfcpp::R_SPARC_M44:
case elfcpp::R_SPARC_L44:
@@ -1639,6 +1673,7 @@ Target_sparc<size, big_endian>::Scan::get_reference_flags(unsigned int r_type)
case elfcpp::R_SPARC_WDISP22:
case elfcpp::R_SPARC_WDISP19:
case elfcpp::R_SPARC_WDISP16:
+ case elfcpp::R_SPARC_WDISP10:
return Symbol::RELATIVE_REF;
case elfcpp::R_SPARC_PLT64:
@@ -1755,6 +1790,7 @@ Target_sparc<size, big_endian>::Scan::check_non_pic(Relobj* object, unsigned int
case elfcpp::R_SPARC_LO10:
case elfcpp::R_SPARC_HI22:
case elfcpp::R_SPARC_OLO10:
+ case elfcpp::R_SPARC_H34:
case elfcpp::R_SPARC_H44:
case elfcpp::R_SPARC_M44:
case elfcpp::R_SPARC_L44:
@@ -1861,6 +1897,7 @@ Target_sparc<size, big_endian>::Scan::local(
case elfcpp::R_SPARC_HIX22:
case elfcpp::R_SPARC_LOX10:
+ case elfcpp::R_SPARC_H34:
case elfcpp::R_SPARC_H44:
case elfcpp::R_SPARC_M44:
case elfcpp::R_SPARC_L44:
@@ -1911,6 +1948,7 @@ Target_sparc<size, big_endian>::Scan::local(
case elfcpp::R_SPARC_WDISP22:
case elfcpp::R_SPARC_WDISP19:
case elfcpp::R_SPARC_WDISP16:
+ case elfcpp::R_SPARC_WDISP10:
case elfcpp::R_SPARC_DISP8:
case elfcpp::R_SPARC_DISP16:
case elfcpp::R_SPARC_DISP32:
@@ -2186,6 +2224,7 @@ Target_sparc<size, big_endian>::Scan::global(
case elfcpp::R_SPARC_WDISP22:
case elfcpp::R_SPARC_WDISP19:
case elfcpp::R_SPARC_WDISP16:
+ case elfcpp::R_SPARC_WDISP10:
{
if (gsym->needs_plt_entry())
target->make_plt_entry(symtab, layout, gsym);
@@ -2214,6 +2253,7 @@ Target_sparc<size, big_endian>::Scan::global(
case elfcpp::R_SPARC_64:
case elfcpp::R_SPARC_HIX22:
case elfcpp::R_SPARC_LOX10:
+ case elfcpp::R_SPARC_H34:
case elfcpp::R_SPARC_H44:
case elfcpp::R_SPARC_M44:
case elfcpp::R_SPARC_L44:
@@ -2749,6 +2789,10 @@ Target_sparc<size, big_endian>::Relocate::relocate(
Reloc::wdisp16(view, object, psymval, addend, address);
break;
+ case elfcpp::R_SPARC_WDISP10:
+ Reloc::wdisp10(view, object, psymval, addend, address);
+ break;
+
case elfcpp::R_SPARC_HI22:
Reloc::hi22(view, object, psymval, addend);
break;
@@ -2900,6 +2944,10 @@ Target_sparc<size, big_endian>::Relocate::relocate(
Reloc::lox10(view, object, psymval, addend);
break;
+ case elfcpp::R_SPARC_H34:
+ Reloc::h34(view, object, psymval, addend);
+ break;
+
case elfcpp::R_SPARC_H44:
Reloc::h44(view, object, psymval, addend);
break;