summaryrefslogtreecommitdiffstats
path: root/contrib/binutils/bfd/elf64-sparc.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/binutils/bfd/elf64-sparc.c')
-rw-r--r--contrib/binutils/bfd/elf64-sparc.c274
1 files changed, 200 insertions, 74 deletions
diff --git a/contrib/binutils/bfd/elf64-sparc.c b/contrib/binutils/bfd/elf64-sparc.c
index c9e8626..0627913 100644
--- a/contrib/binutils/bfd/elf64-sparc.c
+++ b/contrib/binutils/bfd/elf64-sparc.c
@@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "sysdep.h"
#include "libbfd.h"
#include "elf-bfd.h"
+#include "opcode/sparc.h"
/* This is defined if one wants to build upward compatible binaries
with the original sparc64-elf toolchain. The support is kept in for
@@ -65,6 +66,8 @@ static void sparc64_elf_symbol_processing
static boolean sparc64_elf_merge_private_bfd_data
PARAMS ((bfd *, bfd *));
+static boolean sparc64_elf_relax_section
+ PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *));
static boolean sparc64_elf_relocate_section
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
@@ -212,7 +215,7 @@ static CONST struct elf_reloc_map sparc_reloc_map[] =
static reloc_howto_type *
sparc64_elf_reloc_type_lookup (abfd, code)
- bfd *abfd;
+ bfd *abfd ATTRIBUTE_UNUSED;
bfd_reloc_code_real_type code;
{
unsigned int i;
@@ -226,7 +229,7 @@ sparc64_elf_reloc_type_lookup (abfd, code)
static void
sparc64_elf_info_to_howto (abfd, cache_ptr, dst)
- bfd *abfd;
+ bfd *abfd ATTRIBUTE_UNUSED;
arelent *cache_ptr;
Elf64_Internal_Rela *dst;
{
@@ -237,10 +240,10 @@ sparc64_elf_info_to_howto (abfd, cache_ptr, dst)
/* Due to the way how we handle R_SPARC_OLO10, each entry in a SHT_RELA
section can represent up to two relocs, we must tell the user to allocate
more space. */
-
+
static long
sparc64_elf_get_reloc_upper_bound (abfd, sec)
- bfd *abfd;
+ bfd *abfd ATTRIBUTE_UNUSED;
asection *sec;
{
return (sec->reloc_count * 2 + 1) * sizeof (arelent *);
@@ -253,7 +256,7 @@ sparc64_elf_get_dynamic_reloc_upper_bound (abfd)
return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 2;
}
-/* Read relocations for ASECT from REL_HDR. There are RELOC_COUNT of
+/* Read relocations for ASECT from REL_HDR. There are RELOC_COUNT of
them. We cannot use generic elf routines for this, because R_SPARC_OLO10
has secondary addend in ELF64_R_TYPE_DATA. We handle it as two relocations
for the same location, R_SPARC_LO10 and R_SPARC_13. */
@@ -266,7 +269,6 @@ sparc64_elf_slurp_one_reloc_table (abfd, asect, rel_hdr, symbols, dynamic)
asymbol **symbols;
boolean dynamic;
{
- struct elf_backend_data * const ebd = get_elf_backend_data (abfd);
PTR allocated = NULL;
bfd_byte *native_relocs;
arelent *relent;
@@ -290,7 +292,7 @@ sparc64_elf_slurp_one_reloc_table (abfd, asect, rel_hdr, symbols, dynamic)
entsize = rel_hdr->sh_entsize;
BFD_ASSERT (entsize == sizeof (Elf64_External_Rela));
-
+
count = rel_hdr->sh_size / entsize;
for (i = 0, relent = relents; i < count;
@@ -396,20 +398,20 @@ sparc64_elf_slurp_reloc_table (abfd, asect, symbols, dynamic)
rel_hdr2 = NULL;
}
- asect->relocation = ((arelent *)
- bfd_alloc (abfd,
+ asect->relocation = ((arelent *)
+ bfd_alloc (abfd,
asect->reloc_count * 2 * sizeof (arelent)));
if (asect->relocation == NULL)
return false;
/* The sparc64_elf_slurp_one_reloc_table routine increments reloc_count. */
asect->reloc_count = 0;
-
+
if (!sparc64_elf_slurp_one_reloc_table (abfd, asect, rel_hdr, symbols,
dynamic))
return false;
-
- if (rel_hdr2
+
+ if (rel_hdr2
&& !sparc64_elf_slurp_one_reloc_table (abfd, asect, rel_hdr2, symbols,
dynamic))
return false;
@@ -501,7 +503,6 @@ sparc64_elf_write_relocs (abfd, sec, data)
for (idx = 0; idx < sec->reloc_count; idx++)
{
bfd_vma addr;
- unsigned int i;
++count;
@@ -533,7 +534,7 @@ sparc64_elf_write_relocs (abfd, sec, data)
if (rela_hdr->sh_type != SHT_RELA)
abort ();
- /* orelocation has the data, reloc_count has the count... */
+ /* orelocation has the data, reloc_count has the count... */
outbound_relocas = (Elf64_External_Rela *) rela_hdr->contents;
src_rela = outbound_relocas;
@@ -627,7 +628,7 @@ struct sparc64_elf_link_hash_table
#define sparc64_elf_hash_table(p) \
((struct sparc64_elf_link_hash_table *) ((p)->hash))
-
+
/* Create a Sparc64 ELF linker hash table. */
static struct bfd_link_hash_table *
@@ -650,7 +651,6 @@ sparc64_elf_bfd_link_hash_table_create (abfd)
return &ret->root.root;
}
-
/* Utility for performing the standard initial work of an instruction
relocation.
@@ -723,13 +723,13 @@ sparc_elf_notsup_reloc (abfd,
input_section,
output_bfd,
error_message)
- bfd *abfd;
- arelent *reloc_entry;
- asymbol *symbol;
- PTR data;
- asection *input_section;
- bfd *output_bfd;
- char **error_message;
+ bfd *abfd ATTRIBUTE_UNUSED;
+ arelent *reloc_entry ATTRIBUTE_UNUSED;
+ asymbol *symbol ATTRIBUTE_UNUSED;
+ PTR data ATTRIBUTE_UNUSED;
+ asection *input_section ATTRIBUTE_UNUSED;
+ bfd *output_bfd ATTRIBUTE_UNUSED;
+ char **error_message ATTRIBUTE_UNUSED;
{
return bfd_reloc_notsupported;
}
@@ -745,7 +745,7 @@ sparc_elf_wdisp16_reloc (abfd, reloc_entry, symbol, data, input_section,
PTR data;
asection *input_section;
bfd *output_bfd;
- char **error_message;
+ char **error_message ATTRIBUTE_UNUSED;
{
bfd_vma relocation;
bfd_vma insn;
@@ -783,7 +783,7 @@ sparc_elf_hix22_reloc (abfd,
PTR data;
asection *input_section;
bfd *output_bfd;
- char **error_message;
+ char **error_message ATTRIBUTE_UNUSED;
{
bfd_vma relocation;
bfd_vma insn;
@@ -820,7 +820,7 @@ sparc_elf_lox10_reloc (abfd,
PTR data;
asection *input_section;
bfd *output_bfd;
- char **error_message;
+ char **error_message ATTRIBUTE_UNUSED;
{
bfd_vma relocation;
bfd_vma insn;
@@ -847,7 +847,6 @@ sparc_elf_lox10_reloc (abfd,
#define ELF_DYNAMIC_INTERPRETER "/usr/lib/sparcv9/ld.so.1"
-
/* Fill in the .plt section. */
static void
@@ -858,7 +857,7 @@ sparc64_elf_build_plt (output_bfd, contents, nentries)
{
const unsigned int nop = 0x01000000;
int i, j;
-
+
/* The first four entries are reserved, and are initially undefined.
We fill them with `illtrap 0' to force ld.so to do something. */
@@ -892,7 +891,7 @@ sparc64_elf_build_plt (output_bfd, contents, nentries)
/* Now the tricky bit. Entries 32768 and higher are grouped in blocks of
160: 160 entries and 160 pointers. This is to separate code from data,
which is much friendlier on the cache. */
-
+
for (; i < nentries; i += 160)
{
int block = (i + 160 <= nentries ? 160 : nentries - i);
@@ -935,7 +934,7 @@ sparc64_elf_plt_entry_offset (index)
block = (index - LARGE_PLT_THRESHOLD) / 160;
ofs = (index - LARGE_PLT_THRESHOLD) % 160;
- return ((bfd_vma)(LARGE_PLT_THRESHOLD + block*160) * PLT_ENTRY_SIZE
+ return ((bfd_vma) (LARGE_PLT_THRESHOLD + block*160) * PLT_ENTRY_SIZE
+ ofs * 6*4);
}
@@ -961,8 +960,6 @@ sparc64_elf_plt_ptr_offset (index, max)
+ last * 6*4
+ ofs * 8);
}
-
-
/* Look through the relocs for a section during the first phase, and
allocate space in the global offset table or procedure linkage
@@ -1197,7 +1194,7 @@ sparc64_elf_check_relocs (abfd, info, sec, relocs)
case R_SPARC_UA16:
/* When creating a shared object, we must copy these relocs
into the output file. We create a reloc section in
- dynobj and make room for the reloc.
+ dynobj and make room for the reloc.
But don't do this for debugging sections -- this shows up
with DWARF2 -- first because they are not loaded, and
@@ -1246,7 +1243,7 @@ sparc64_elf_check_relocs (abfd, info, sec, relocs)
break;
default:
- (*_bfd_error_handler)(_("%s: check_relocs: unhandled reloc type %d"),
+ (*_bfd_error_handler) (_("%s: check_relocs: unhandled reloc type %d"),
bfd_get_filename(abfd),
ELF64_R_TYPE_ID (rel->r_info));
return false;
@@ -1265,9 +1262,9 @@ sparc64_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
struct bfd_link_info *info;
const Elf_Internal_Sym *sym;
const char **namep;
- flagword *flagsp;
- asection **secp;
- bfd_vma *valp;
+ flagword *flagsp ATTRIBUTE_UNUSED;
+ asection **secp ATTRIBUTE_UNUSED;
+ bfd_vma *valp ATTRIBUTE_UNUSED;
{
static char *stt_types[] = { "NOTYPE", "OBJECT", "FUNCTION" };
@@ -1275,7 +1272,7 @@ sparc64_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
{
int reg;
struct sparc64_elf_app_reg *p;
-
+
reg = (int)sym->st_value;
switch (reg & ~1)
{
@@ -1316,7 +1313,7 @@ sparc64_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
if (**namep)
{
struct elf_link_hash_entry *h;
-
+
h = (struct elf_link_hash_entry *)
bfd_link_hash_lookup (info->hash, *namep, false, false, false);
@@ -1387,7 +1384,7 @@ sparc64_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
static boolean
sparc64_elf_output_arch_syms (output_bfd, info, finfo, func)
- bfd *output_bfd;
+ bfd *output_bfd ATTRIBUTE_UNUSED;
struct bfd_link_info *info;
PTR finfo;
boolean (*func) PARAMS ((PTR, const char *,
@@ -1460,7 +1457,7 @@ sparc64_elf_get_symbol_type (elf_sym, type)
static void
sparc64_elf_symbol_processing (abfd, asym)
- bfd *abfd;
+ bfd *abfd ATTRIBUTE_UNUSED;
asymbol *asym;
{
elf_symbol_type *elfsym;
@@ -1556,12 +1553,6 @@ sparc64_elf_adjust_dynamic_symbol (info, h)
s = bfd_get_section_by_name (dynobj, ".rela.plt");
BFD_ASSERT (s != NULL);
- /* The first plt entries are reserved, and the relocations must
- pair up exactly. */
- if (s->_raw_size == 0)
- s->_raw_size += (PLT_HEADER_SIZE/PLT_ENTRY_SIZE
- * sizeof (Elf64_External_Rela));
-
s->_raw_size += sizeof (Elf64_External_Rela);
/* The procedure linkage table size is bounded by the magnitude
@@ -1802,6 +1793,7 @@ sparc64_elf_size_dynamic_sections (output_bfd, info)
{
if (! bfd_elf64_add_dynamic_entry (info, DT_TEXTREL, 0))
return false;
+ info->flags |= DF_TEXTREL;
}
/* Add dynamic STT_REGISTER symbols and corresponding DT_SPARC_REGISTER
@@ -1813,7 +1805,7 @@ sparc64_elf_size_dynamic_sections (output_bfd, info)
if (app_regs [reg].name != NULL)
{
struct elf_link_local_dynamic_entry *entry, *e;
-
+
if (! bfd_elf64_add_dynamic_entry (info, DT_SPARC_REGISTER, 0))
return false;
@@ -1855,6 +1847,21 @@ sparc64_elf_size_dynamic_sections (output_bfd, info)
return true;
}
+#define SET_SEC_DO_RELAX(section) do { elf_section_data(section)->tdata = (void *)1; } while (0)
+#define SEC_DO_RELAX(section) (elf_section_data(section)->tdata == (void *)1)
+
+static boolean
+sparc64_elf_relax_section (abfd, section, link_info, again)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ asection *section ATTRIBUTE_UNUSED;
+ struct bfd_link_info *link_info ATTRIBUTE_UNUSED;
+ boolean *again;
+{
+ *again = false;
+ SET_SEC_DO_RELAX (section);
+ return true;
+}
+
/* Relocate a SPARC64 ELF section. */
static boolean
@@ -1898,7 +1905,7 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
{
int r_type;
reloc_howto_type *howto;
- long r_symndx;
+ unsigned long r_symndx;
struct elf_link_hash_entry *h;
Elf_Internal_Sym *sym;
asection *sec;
@@ -2061,7 +2068,15 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
(!info->shared || info->no_undefined
|| ELF_ST_VISIBILITY (h->other)))))
return false;
- relocation = 0;
+
+ /* To avoid generating warning messages about truncated
+ relocations, set the relocation's address to be the same as
+ the start of this section. */
+
+ if (input_section->output_section != NULL)
+ relocation = input_section->output_section->vma;
+ else
+ relocation = 0;
}
}
@@ -2338,7 +2353,6 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
off &= ~1;
else
{
- bfd_put_64 (output_bfd, relocation, sgot->contents + off);
local_got_offsets[r_symndx] |= 1;
if (info->shared)
@@ -2346,6 +2360,13 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
asection *srelgot;
Elf_Internal_Rela outrel;
+ /* The Solaris 2.7 64-bit linker adds the contents
+ of the location to the value of the reloc.
+ Note this is different behaviour to the
+ 32-bit linker, which both adds the contents
+ and ignores the addend. So clear the location. */
+ bfd_put_64 (output_bfd, 0, sgot->contents + off);
+
/* We need to generate a R_SPARC_RELATIVE reloc
for the dynamic linker. */
srelgot = bfd_get_section_by_name(dynobj, ".rela.got");
@@ -2362,6 +2383,8 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
+ srelgot->reloc_count));
++srelgot->reloc_count;
}
+ else
+ bfd_put_64 (output_bfd, relocation, sgot->contents + off);
}
relocation = sgot->output_offset + off - got_base;
}
@@ -2396,6 +2419,8 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
relocation = (splt->output_section->vma
+ splt->output_offset
+ sparc64_elf_plt_entry_offset (h->plt.offset));
+ if (r_type == R_SPARC_WPLT30)
+ goto do_wplt30;
goto do_default;
case R_SPARC_OLO10:
@@ -2471,6 +2496,97 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
}
break;
+ case R_SPARC_WDISP30:
+ do_wplt30:
+ if (SEC_DO_RELAX (input_section)
+ && rel->r_offset + 4 < input_section->_raw_size)
+ {
+#define G0 0
+#define O7 15
+#define XCC (2 << 20)
+#define COND(x) (((x)&0xf)<<25)
+#define CONDA COND(0x8)
+#define INSN_BPA (F2(0,1) | CONDA | BPRED | XCC)
+#define INSN_BA (F2(0,2) | CONDA)
+#define INSN_OR F3(2, 0x2, 0)
+#define INSN_NOP F2(0,4)
+
+ bfd_vma x, y;
+
+ /* If the instruction is a call with either:
+ restore
+ arithmetic instruction with rd == %o7
+ where rs1 != %o7 and rs2 if it is register != %o7
+ then we can optimize if the call destination is near
+ by changing the call into a branch always. */
+ x = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ y = bfd_get_32 (input_bfd, contents + rel->r_offset + 4);
+ if ((x & OP(~0)) == OP(1) && (y & OP(~0)) == OP(2))
+ {
+ if (((y & OP3(~0)) == OP3(0x3d) /* restore */
+ || ((y & OP3(0x28)) == 0 /* arithmetic */
+ && (y & RD(~0)) == RD(O7)))
+ && (y & RS1(~0)) != RS1(O7)
+ && ((y & F3I(~0))
+ || (y & RS2(~0)) != RS2(O7)))
+ {
+ bfd_vma reloc;
+
+ reloc = relocation + rel->r_addend - rel->r_offset;
+ reloc -= (input_section->output_section->vma
+ + input_section->output_offset);
+ if (reloc & 3)
+ goto do_default;
+
+ /* Ensure the branch fits into simm22. */
+ if ((reloc & ~(bfd_vma)0x7fffff)
+ && ((reloc | 0x7fffff) != MINUS_ONE))
+ goto do_default;
+ reloc >>= 2;
+
+ /* Check whether it fits into simm19. */
+ if ((reloc & 0x3c0000) == 0
+ || (reloc & 0x3c0000) == 0x3c0000)
+ x = INSN_BPA | (reloc & 0x7ffff); /* ba,pt %xcc */
+ else
+ x = INSN_BA | (reloc & 0x3fffff); /* ba */
+ bfd_put_32 (input_bfd, x, contents + rel->r_offset);
+ r = bfd_reloc_ok;
+ if (rel->r_offset >= 4
+ && (y & (0xffffffff ^ RS1(~0)))
+ == (INSN_OR | RD(O7) | RS2(G0)))
+ {
+ bfd_vma z;
+ unsigned int reg;
+
+ z = bfd_get_32 (input_bfd,
+ contents + rel->r_offset - 4);
+ if ((z & (0xffffffff ^ RD(~0)))
+ != (INSN_OR | RS1(O7) | RS2(G0)))
+ break;
+
+ /* The sequence was
+ or %o7, %g0, %rN
+ call foo
+ or %rN, %g0, %o7
+
+ If call foo was replaced with ba, replace
+ or %rN, %g0, %o7 with nop. */
+
+ reg = (y & RS1(~0)) >> 14;
+ if (reg != ((z & RD(~0)) >> 25)
+ || reg == G0 || reg == O7)
+ break;
+
+ bfd_put_32 (input_bfd, INSN_NOP,
+ contents + rel->r_offset + 4);
+ }
+ break;
+ }
+ }
+ }
+ /* FALLTHROUGH */
+
default:
do_default:
r = _bfd_final_link_relocate (howto, input_bfd, input_section,
@@ -2499,12 +2615,12 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
{
/* Assume this is a call protected by other code that
detect the symbol is undefined. If this is the case,
- we can safely ignore the overflow. If not, the
+ we can safely ignore the overflow. If not, the
program is hosed anyway, and a little warning isn't
going to help. */
break;
}
-
+
name = h->root.root.string;
}
else
@@ -2550,7 +2666,7 @@ sparc64_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
asection *srela;
Elf_Internal_Rela rela;
- /* This symbol has an entry in the PLT. Set it up. */
+ /* This symbol has an entry in the PLT. Set it up. */
BFD_ASSERT (h->dynindx != -1);
@@ -2575,9 +2691,14 @@ sparc64_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
rela.r_offset += (splt->output_section->vma + splt->output_offset);
rela.r_info = ELF64_R_INFO (h->dynindx, R_SPARC_JMP_SLOT);
+ /* Adjust for the first 4 reserved elements in the .plt section
+ when setting the offset in the .rela.plt section.
+ Sun forgot to read their own ABI and copied elf32-sparc behaviour,
+ thus .plt[4] has corresponding .rela.plt[0] and so on. */
+
bfd_elf64_swap_reloca_out (output_bfd, &rela,
((Elf64_External_Rela *) srela->contents
- + h->plt.offset));
+ + (h->plt.offset - 4)));
if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
{
@@ -2770,7 +2891,7 @@ sparc64_elf_finish_dynamic_sections (output_bfd, info)
return true;
}
-/* Functions for dealing with the e_flags field. */
+/* Functions for dealing with the e_flags field. */
/* Merge backend specific data from an object file to the output
object file when linking. */
@@ -2796,32 +2917,33 @@ sparc64_elf_merge_private_bfd_data (ibfd, obfd)
elf_flags_init (obfd) = true;
elf_elfheader (obfd)->e_flags = new_flags;
}
-
+
else if (new_flags == old_flags) /* Compatible flags are ok */
;
-
+
else /* Incompatible flags */
{
error = false;
-
+
+#define EF_SPARC_ISA_EXTENSIONS \
+ (EF_SPARC_SUN_US1 | EF_SPARC_SUN_US3 | EF_SPARC_HAL_R1)
+
if ((ibfd->flags & DYNAMIC) != 0)
{
/* We don't want dynamic objects memory ordering and
architecture to have any role. That's what dynamic linker
should do. */
- old_flags &= ~(EF_SPARCV9_MM | EF_SPARC_SUN_US1 | EF_SPARC_HAL_R1);
- old_flags |= (new_flags
- & (EF_SPARCV9_MM
- | EF_SPARC_SUN_US1
- | EF_SPARC_HAL_R1));
+ new_flags &= ~(EF_SPARCV9_MM | EF_SPARC_ISA_EXTENSIONS);
+ new_flags |= (old_flags
+ & (EF_SPARCV9_MM | EF_SPARC_ISA_EXTENSIONS));
}
else
{
/* Choose the highest architecture requirements. */
- old_flags |= (new_flags & (EF_SPARC_SUN_US1 | EF_SPARC_HAL_R1));
- new_flags |= (old_flags & (EF_SPARC_SUN_US1 | EF_SPARC_HAL_R1));
- if ((old_flags & (EF_SPARC_SUN_US1 | EF_SPARC_HAL_R1))
- == (EF_SPARC_SUN_US1 | EF_SPARC_HAL_R1))
+ old_flags |= (new_flags & EF_SPARC_ISA_EXTENSIONS);
+ new_flags |= (old_flags & EF_SPARC_ISA_EXTENSIONS);
+ if ((old_flags & (EF_SPARC_SUN_US1 | EF_SPARC_SUN_US3))
+ && (old_flags & EF_SPARC_HAL_R1))
{
error = true;
(*_bfd_error_handler)
@@ -2863,13 +2985,13 @@ sparc64_elf_merge_private_bfd_data (ibfd, obfd)
static const char *
sparc64_elf_print_symbol_all (abfd, filep, symbol)
- bfd *abfd;
+ bfd *abfd ATTRIBUTE_UNUSED;
PTR filep;
asymbol *symbol;
{
FILE *file = (FILE *) filep;
int reg, type;
-
+
if (ELF_ST_TYPE (((elf_symbol_type *) symbol)->internal_elf_sym.st_info)
!= STT_REGISTER)
return NULL;
@@ -2894,8 +3016,10 @@ sparc64_elf_object_p (abfd)
bfd *abfd;
{
unsigned long mach = bfd_mach_sparc_v9;
-
- if (elf_elfheader (abfd)->e_flags & EF_SPARC_SUN_US1)
+
+ if (elf_elfheader (abfd)->e_flags & EF_SPARC_SUN_US3)
+ mach = bfd_mach_sparc_v9b;
+ else if (elf_elfheader (abfd)->e_flags & EF_SPARC_SUN_US1)
mach = bfd_mach_sparc_v9a;
return bfd_default_set_arch_mach (abfd, bfd_arch_sparc, mach);
}
@@ -2919,7 +3043,7 @@ const struct elf_size_info sparc64_elf_size_info =
/* internal relocations per external relocations.
For link purposes we use just 1 internal per
1 external, for assembly and slurp symbol table
- we use 2. */
+ we use 2. */
1,
64, /* arch_size */
8, /* file_align */
@@ -2952,7 +3076,7 @@ const struct elf_size_info sparc64_elf_size_info =
#define bfd_elf64_bfd_link_hash_table_create \
sparc64_elf_bfd_link_hash_table_create
-
+
#define elf_info_to_howto \
sparc64_elf_info_to_howto
#define bfd_elf64_get_reloc_upper_bound \
@@ -2963,6 +3087,8 @@ const struct elf_size_info sparc64_elf_size_info =
sparc64_elf_canonicalize_dynamic_reloc
#define bfd_elf64_bfd_reloc_type_lookup \
sparc64_elf_reloc_type_lookup
+#define bfd_elf64_bfd_relax_section \
+ sparc64_elf_relax_section
#define elf_backend_create_dynamic_sections \
_bfd_elf_create_dynamic_sections
OpenPOWER on IntegriCloud