159024Sobrien/* SPARC-specific support for 64-bit ELF
2130561Sobrien   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3218822Sdim   2003, 2004, 2005, 2007 Free Software Foundation, Inc.
459024Sobrien
5130561Sobrien   This file is part of BFD, the Binary File Descriptor library.
659024Sobrien
7130561Sobrien   This program is free software; you can redistribute it and/or modify
8130561Sobrien   it under the terms of the GNU General Public License as published by
9130561Sobrien   the Free Software Foundation; either version 2 of the License, or
10130561Sobrien   (at your option) any later version.
1159024Sobrien
12130561Sobrien   This program is distributed in the hope that it will be useful,
13130561Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
14130561Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15130561Sobrien   GNU General Public License for more details.
1659024Sobrien
17130561Sobrien   You should have received a copy of the GNU General Public License
18130561Sobrien   along with this program; if not, write to the Free Software
19218822Sdim   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
2059024Sobrien
21218822Sdim#include "sysdep.h"
2259024Sobrien#include "bfd.h"
2359024Sobrien#include "libbfd.h"
2459024Sobrien#include "elf-bfd.h"
25218822Sdim#include "elf/sparc.h"
2677298Sobrien#include "opcode/sparc.h"
27218822Sdim#include "elfxx-sparc.h"
2859024Sobrien
2959024Sobrien/* In case we're on a 32-bit machine, construct a 64-bit "-1" value.  */
3059024Sobrien#define MINUS_ONE (~ (bfd_vma) 0)
3159024Sobrien
3260484Sobrien/* Due to the way how we handle R_SPARC_OLO10, each entry in a SHT_RELA
3360484Sobrien   section can represent up to two relocs, we must tell the user to allocate
3460484Sobrien   more space.  */
3577298Sobrien
3660484Sobrienstatic long
37218822Sdimelf64_sparc_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
3860484Sobrien{
3960484Sobrien  return (sec->reloc_count * 2 + 1) * sizeof (arelent *);
4060484Sobrien}
4160484Sobrien
4260484Sobrienstatic long
43218822Sdimelf64_sparc_get_dynamic_reloc_upper_bound (bfd *abfd)
4460484Sobrien{
4560484Sobrien  return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 2;
4660484Sobrien}
4760484Sobrien
4877298Sobrien/* Read  relocations for ASECT from REL_HDR.  There are RELOC_COUNT of
4960484Sobrien   them.  We cannot use generic elf routines for this,  because R_SPARC_OLO10
5060484Sobrien   has secondary addend in ELF64_R_TYPE_DATA.  We handle it as two relocations
5160484Sobrien   for the same location,  R_SPARC_LO10 and R_SPARC_13.  */
5260484Sobrien
53130561Sobrienstatic bfd_boolean
54218822Sdimelf64_sparc_slurp_one_reloc_table (bfd *abfd, asection *asect,
55218822Sdim				   Elf_Internal_Shdr *rel_hdr,
56218822Sdim				   asymbol **symbols, bfd_boolean dynamic)
5760484Sobrien{
5860484Sobrien  PTR allocated = NULL;
5960484Sobrien  bfd_byte *native_relocs;
6060484Sobrien  arelent *relent;
6160484Sobrien  unsigned int i;
6260484Sobrien  int entsize;
6360484Sobrien  bfd_size_type count;
6460484Sobrien  arelent *relents;
6560484Sobrien
6689857Sobrien  allocated = (PTR) bfd_malloc (rel_hdr->sh_size);
6760484Sobrien  if (allocated == NULL)
6860484Sobrien    goto error_return;
6960484Sobrien
7060484Sobrien  if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
7189857Sobrien      || bfd_bread (allocated, rel_hdr->sh_size, abfd) != rel_hdr->sh_size)
7260484Sobrien    goto error_return;
7360484Sobrien
7460484Sobrien  native_relocs = (bfd_byte *) allocated;
7560484Sobrien
76130561Sobrien  relents = asect->relocation + canon_reloc_count (asect);
7760484Sobrien
7860484Sobrien  entsize = rel_hdr->sh_entsize;
7960484Sobrien  BFD_ASSERT (entsize == sizeof (Elf64_External_Rela));
8077298Sobrien
8160484Sobrien  count = rel_hdr->sh_size / entsize;
8260484Sobrien
8360484Sobrien  for (i = 0, relent = relents; i < count;
8460484Sobrien       i++, relent++, native_relocs += entsize)
8560484Sobrien    {
8660484Sobrien      Elf_Internal_Rela rela;
87218822Sdim      unsigned int r_type;
8860484Sobrien
89130561Sobrien      bfd_elf64_swap_reloca_in (abfd, native_relocs, &rela);
9060484Sobrien
9160484Sobrien      /* The address of an ELF reloc is section relative for an object
9260484Sobrien	 file, and absolute for an executable file or shared library.
9360484Sobrien	 The address of a normal BFD reloc is always section relative,
9460484Sobrien	 and the address of a dynamic reloc is absolute..  */
9560484Sobrien      if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
9660484Sobrien	relent->address = rela.r_offset;
9760484Sobrien      else
9860484Sobrien	relent->address = rela.r_offset - asect->vma;
9960484Sobrien
10060484Sobrien      if (ELF64_R_SYM (rela.r_info) == 0)
10160484Sobrien	relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
10260484Sobrien      else
10360484Sobrien	{
10460484Sobrien	  asymbol **ps, *s;
10560484Sobrien
10660484Sobrien	  ps = symbols + ELF64_R_SYM (rela.r_info) - 1;
10760484Sobrien	  s = *ps;
10860484Sobrien
10960484Sobrien	  /* Canonicalize ELF section symbols.  FIXME: Why?  */
11060484Sobrien	  if ((s->flags & BSF_SECTION_SYM) == 0)
11160484Sobrien	    relent->sym_ptr_ptr = ps;
11260484Sobrien	  else
11360484Sobrien	    relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
11460484Sobrien	}
11560484Sobrien
11660484Sobrien      relent->addend = rela.r_addend;
11760484Sobrien
118218822Sdim      r_type = ELF64_R_TYPE_ID (rela.r_info);
119218822Sdim      if (r_type == R_SPARC_OLO10)
12060484Sobrien	{
121218822Sdim	  relent->howto = _bfd_sparc_elf_info_to_howto_ptr (R_SPARC_LO10);
12260484Sobrien	  relent[1].address = relent->address;
12360484Sobrien	  relent++;
12460484Sobrien	  relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
12560484Sobrien	  relent->addend = ELF64_R_TYPE_DATA (rela.r_info);
126218822Sdim	  relent->howto = _bfd_sparc_elf_info_to_howto_ptr (R_SPARC_13);
12760484Sobrien	}
12860484Sobrien      else
129218822Sdim	relent->howto = _bfd_sparc_elf_info_to_howto_ptr (r_type);
13060484Sobrien    }
13160484Sobrien
132130561Sobrien  canon_reloc_count (asect) += relent - relents;
13360484Sobrien
13460484Sobrien  if (allocated != NULL)
13560484Sobrien    free (allocated);
13660484Sobrien
137130561Sobrien  return TRUE;
13860484Sobrien
13960484Sobrien error_return:
14060484Sobrien  if (allocated != NULL)
14160484Sobrien    free (allocated);
142130561Sobrien  return FALSE;
14360484Sobrien}
14460484Sobrien
14560484Sobrien/* Read in and swap the external relocs.  */
14660484Sobrien
147130561Sobrienstatic bfd_boolean
148218822Sdimelf64_sparc_slurp_reloc_table (bfd *abfd, asection *asect,
149218822Sdim			       asymbol **symbols, bfd_boolean dynamic)
15060484Sobrien{
15160484Sobrien  struct bfd_elf_section_data * const d = elf_section_data (asect);
15260484Sobrien  Elf_Internal_Shdr *rel_hdr;
15360484Sobrien  Elf_Internal_Shdr *rel_hdr2;
15489857Sobrien  bfd_size_type amt;
15560484Sobrien
15660484Sobrien  if (asect->relocation != NULL)
157130561Sobrien    return TRUE;
15860484Sobrien
15960484Sobrien  if (! dynamic)
16060484Sobrien    {
16160484Sobrien      if ((asect->flags & SEC_RELOC) == 0
16260484Sobrien	  || asect->reloc_count == 0)
163130561Sobrien	return TRUE;
16460484Sobrien
16560484Sobrien      rel_hdr = &d->rel_hdr;
16660484Sobrien      rel_hdr2 = d->rel_hdr2;
16760484Sobrien
16860484Sobrien      BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
16960484Sobrien		  || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
17060484Sobrien    }
17160484Sobrien  else
17260484Sobrien    {
17360484Sobrien      /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
17460484Sobrien	 case because relocations against this section may use the
17560484Sobrien	 dynamic symbol table, and in that case bfd_section_from_shdr
17660484Sobrien	 in elf.c does not update the RELOC_COUNT.  */
177218822Sdim      if (asect->size == 0)
178130561Sobrien	return TRUE;
17960484Sobrien
18060484Sobrien      rel_hdr = &d->this_hdr;
18178828Sobrien      asect->reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
18260484Sobrien      rel_hdr2 = NULL;
18360484Sobrien    }
18460484Sobrien
18589857Sobrien  amt = asect->reloc_count;
18689857Sobrien  amt *= 2 * sizeof (arelent);
18789857Sobrien  asect->relocation = (arelent *) bfd_alloc (abfd, amt);
18860484Sobrien  if (asect->relocation == NULL)
189130561Sobrien    return FALSE;
19060484Sobrien
191218822Sdim  /* The elf64_sparc_slurp_one_reloc_table routine increments
192130561Sobrien     canon_reloc_count.  */
193130561Sobrien  canon_reloc_count (asect) = 0;
19477298Sobrien
195218822Sdim  if (!elf64_sparc_slurp_one_reloc_table (abfd, asect, rel_hdr, symbols,
19660484Sobrien					  dynamic))
197130561Sobrien    return FALSE;
19877298Sobrien
19977298Sobrien  if (rel_hdr2
200218822Sdim      && !elf64_sparc_slurp_one_reloc_table (abfd, asect, rel_hdr2, symbols,
20160484Sobrien					     dynamic))
202130561Sobrien    return FALSE;
20360484Sobrien
204130561Sobrien  return TRUE;
20560484Sobrien}
20660484Sobrien
207130561Sobrien/* Canonicalize the relocs.  */
208130561Sobrien
209130561Sobrienstatic long
210218822Sdimelf64_sparc_canonicalize_reloc (bfd *abfd, sec_ptr section,
211218822Sdim				arelent **relptr, asymbol **symbols)
212130561Sobrien{
213130561Sobrien  arelent *tblptr;
214130561Sobrien  unsigned int i;
215130561Sobrien  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
216130561Sobrien
217130561Sobrien  if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
218130561Sobrien    return -1;
219130561Sobrien
220130561Sobrien  tblptr = section->relocation;
221130561Sobrien  for (i = 0; i < canon_reloc_count (section); i++)
222130561Sobrien    *relptr++ = tblptr++;
223130561Sobrien
224130561Sobrien  *relptr = NULL;
225130561Sobrien
226130561Sobrien  return canon_reloc_count (section);
227130561Sobrien}
228130561Sobrien
229130561Sobrien
23060484Sobrien/* Canonicalize the dynamic relocation entries.  Note that we return
23160484Sobrien   the dynamic relocations as a single block, although they are
23260484Sobrien   actually associated with particular sections; the interface, which
23360484Sobrien   was designed for SunOS style shared libraries, expects that there
23460484Sobrien   is only one set of dynamic relocs.  Any section that was actually
23560484Sobrien   installed in the BFD, and has type SHT_REL or SHT_RELA, and uses
23660484Sobrien   the dynamic symbol table, is considered to be a dynamic reloc
23760484Sobrien   section.  */
23860484Sobrien
23960484Sobrienstatic long
240218822Sdimelf64_sparc_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage,
241218822Sdim					asymbol **syms)
24260484Sobrien{
24360484Sobrien  asection *s;
24460484Sobrien  long ret;
24560484Sobrien
24660484Sobrien  if (elf_dynsymtab (abfd) == 0)
24760484Sobrien    {
24860484Sobrien      bfd_set_error (bfd_error_invalid_operation);
24960484Sobrien      return -1;
25060484Sobrien    }
25160484Sobrien
25260484Sobrien  ret = 0;
25360484Sobrien  for (s = abfd->sections; s != NULL; s = s->next)
25460484Sobrien    {
25560484Sobrien      if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
25660484Sobrien	  && (elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
25760484Sobrien	{
25860484Sobrien	  arelent *p;
25960484Sobrien	  long count, i;
26060484Sobrien
261218822Sdim	  if (! elf64_sparc_slurp_reloc_table (abfd, s, syms, TRUE))
26260484Sobrien	    return -1;
263130561Sobrien	  count = canon_reloc_count (s);
26460484Sobrien	  p = s->relocation;
26560484Sobrien	  for (i = 0; i < count; i++)
26660484Sobrien	    *storage++ = p++;
26760484Sobrien	  ret += count;
26860484Sobrien	}
26960484Sobrien    }
27060484Sobrien
27160484Sobrien  *storage = NULL;
27260484Sobrien
27360484Sobrien  return ret;
27460484Sobrien}
27560484Sobrien
27660484Sobrien/* Write out the relocs.  */
27760484Sobrien
27860484Sobrienstatic void
279218822Sdimelf64_sparc_write_relocs (bfd *abfd, asection *sec, PTR data)
28060484Sobrien{
281130561Sobrien  bfd_boolean *failedp = (bfd_boolean *) data;
28260484Sobrien  Elf_Internal_Shdr *rela_hdr;
283218822Sdim  bfd_vma addr_offset;
28460484Sobrien  Elf64_External_Rela *outbound_relocas, *src_rela;
28560484Sobrien  unsigned int idx, count;
28660484Sobrien  asymbol *last_sym = 0;
28760484Sobrien  int last_sym_idx = 0;
28860484Sobrien
28960484Sobrien  /* If we have already failed, don't do anything.  */
29060484Sobrien  if (*failedp)
29160484Sobrien    return;
29260484Sobrien
29360484Sobrien  if ((sec->flags & SEC_RELOC) == 0)
29460484Sobrien    return;
29560484Sobrien
29660484Sobrien  /* The linker backend writes the relocs out itself, and sets the
29760484Sobrien     reloc_count field to zero to inhibit writing them here.  Also,
29860484Sobrien     sometimes the SEC_RELOC flag gets set even when there aren't any
29960484Sobrien     relocs.  */
30060484Sobrien  if (sec->reloc_count == 0)
30160484Sobrien    return;
30260484Sobrien
30360484Sobrien  /* We can combine two relocs that refer to the same address
30460484Sobrien     into R_SPARC_OLO10 if first one is R_SPARC_LO10 and the
30560484Sobrien     latter is R_SPARC_13 with no associated symbol.  */
30660484Sobrien  count = 0;
30760484Sobrien  for (idx = 0; idx < sec->reloc_count; idx++)
30860484Sobrien    {
30960484Sobrien      bfd_vma addr;
31060484Sobrien
31160484Sobrien      ++count;
31260484Sobrien
31360484Sobrien      addr = sec->orelocation[idx]->address;
31460484Sobrien      if (sec->orelocation[idx]->howto->type == R_SPARC_LO10
31560484Sobrien	  && idx < sec->reloc_count - 1)
31660484Sobrien	{
31760484Sobrien	  arelent *r = sec->orelocation[idx + 1];
31860484Sobrien
31960484Sobrien	  if (r->howto->type == R_SPARC_13
32060484Sobrien	      && r->address == addr
32160484Sobrien	      && bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
32260484Sobrien	      && (*r->sym_ptr_ptr)->value == 0)
32360484Sobrien	    ++idx;
32460484Sobrien	}
32560484Sobrien    }
32660484Sobrien
32760484Sobrien  rela_hdr = &elf_section_data (sec)->rel_hdr;
32860484Sobrien
32960484Sobrien  rela_hdr->sh_size = rela_hdr->sh_entsize * count;
33060484Sobrien  rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size);
33160484Sobrien  if (rela_hdr->contents == NULL)
33260484Sobrien    {
333130561Sobrien      *failedp = TRUE;
33460484Sobrien      return;
33560484Sobrien    }
33660484Sobrien
33760484Sobrien  /* Figure out whether the relocations are RELA or REL relocations.  */
33860484Sobrien  if (rela_hdr->sh_type != SHT_RELA)
33960484Sobrien    abort ();
34060484Sobrien
341218822Sdim  /* The address of an ELF reloc is section relative for an object
342218822Sdim     file, and absolute for an executable file or shared library.
343218822Sdim     The address of a BFD reloc is always section relative.  */
344218822Sdim  addr_offset = 0;
345218822Sdim  if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
346218822Sdim    addr_offset = sec->vma;
347218822Sdim
34877298Sobrien  /* orelocation has the data, reloc_count has the count...  */
34960484Sobrien  outbound_relocas = (Elf64_External_Rela *) rela_hdr->contents;
35060484Sobrien  src_rela = outbound_relocas;
35160484Sobrien
35260484Sobrien  for (idx = 0; idx < sec->reloc_count; idx++)
35360484Sobrien    {
35460484Sobrien      Elf_Internal_Rela dst_rela;
35560484Sobrien      arelent *ptr;
35660484Sobrien      asymbol *sym;
35760484Sobrien      int n;
35860484Sobrien
35960484Sobrien      ptr = sec->orelocation[idx];
36060484Sobrien      sym = *ptr->sym_ptr_ptr;
36160484Sobrien      if (sym == last_sym)
36260484Sobrien	n = last_sym_idx;
36360484Sobrien      else if (bfd_is_abs_section (sym->section) && sym->value == 0)
36460484Sobrien	n = STN_UNDEF;
36560484Sobrien      else
36660484Sobrien	{
36760484Sobrien	  last_sym = sym;
36860484Sobrien	  n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
36960484Sobrien	  if (n < 0)
37060484Sobrien	    {
371130561Sobrien	      *failedp = TRUE;
37260484Sobrien	      return;
37360484Sobrien	    }
37460484Sobrien	  last_sym_idx = n;
37560484Sobrien	}
37660484Sobrien
37760484Sobrien      if ((*ptr->sym_ptr_ptr)->the_bfd != NULL
37860484Sobrien	  && (*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
37960484Sobrien	  && ! _bfd_elf_validate_reloc (abfd, ptr))
38060484Sobrien	{
381130561Sobrien	  *failedp = TRUE;
38260484Sobrien	  return;
38360484Sobrien	}
38460484Sobrien
38560484Sobrien      if (ptr->howto->type == R_SPARC_LO10
38660484Sobrien	  && idx < sec->reloc_count - 1)
38760484Sobrien	{
38860484Sobrien	  arelent *r = sec->orelocation[idx + 1];
38960484Sobrien
39060484Sobrien	  if (r->howto->type == R_SPARC_13
39160484Sobrien	      && r->address == ptr->address
39260484Sobrien	      && bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
39360484Sobrien	      && (*r->sym_ptr_ptr)->value == 0)
39460484Sobrien	    {
39560484Sobrien	      idx++;
39660484Sobrien	      dst_rela.r_info
39760484Sobrien		= ELF64_R_INFO (n, ELF64_R_TYPE_INFO (r->addend,
39860484Sobrien						      R_SPARC_OLO10));
39960484Sobrien	    }
40060484Sobrien	  else
40160484Sobrien	    dst_rela.r_info = ELF64_R_INFO (n, R_SPARC_LO10);
40260484Sobrien	}
40360484Sobrien      else
40460484Sobrien	dst_rela.r_info = ELF64_R_INFO (n, ptr->howto->type);
40560484Sobrien
406218822Sdim      dst_rela.r_offset = ptr->address + addr_offset;
40760484Sobrien      dst_rela.r_addend = ptr->addend;
408218822Sdim
409130561Sobrien      bfd_elf64_swap_reloca_out (abfd, &dst_rela, (bfd_byte *) src_rela);
41060484Sobrien      ++src_rela;
41160484Sobrien    }
41260484Sobrien}
41360484Sobrien
41460484Sobrien/* Hook called by the linker routine which adds symbols from an object
41560484Sobrien   file.  We use it for STT_REGISTER symbols.  */
41660484Sobrien
417130561Sobrienstatic bfd_boolean
418218822Sdimelf64_sparc_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
419218822Sdim			     Elf_Internal_Sym *sym, const char **namep,
420218822Sdim			     flagword *flagsp ATTRIBUTE_UNUSED,
421218822Sdim			     asection **secp ATTRIBUTE_UNUSED,
422218822Sdim			     bfd_vma *valp ATTRIBUTE_UNUSED)
42360484Sobrien{
42489857Sobrien  static const char *const stt_types[] = { "NOTYPE", "OBJECT", "FUNCTION" };
42560484Sobrien
42660484Sobrien  if (ELF_ST_TYPE (sym->st_info) == STT_REGISTER)
42760484Sobrien    {
42860484Sobrien      int reg;
429218822Sdim      struct _bfd_sparc_elf_app_reg *p;
43077298Sobrien
43160484Sobrien      reg = (int)sym->st_value;
43260484Sobrien      switch (reg & ~1)
43360484Sobrien	{
43460484Sobrien	case 2: reg -= 2; break;
43560484Sobrien	case 6: reg -= 4; break;
43660484Sobrien	default:
43760484Sobrien          (*_bfd_error_handler)
438218822Sdim            (_("%B: Only registers %%g[2367] can be declared using STT_REGISTER"),
439218822Sdim             abfd);
440130561Sobrien	  return FALSE;
44160484Sobrien	}
44260484Sobrien
44360484Sobrien      if (info->hash->creator != abfd->xvec
44460484Sobrien	  || (abfd->flags & DYNAMIC) != 0)
44560484Sobrien        {
44660484Sobrien	  /* STT_REGISTER only works when linking an elf64_sparc object.
44760484Sobrien	     If STT_REGISTER comes from a dynamic object, don't put it into
44860484Sobrien	     the output bfd.  The dynamic linker will recheck it.  */
44960484Sobrien	  *namep = NULL;
450130561Sobrien	  return TRUE;
45160484Sobrien        }
45260484Sobrien
453218822Sdim      p = _bfd_sparc_elf_hash_table(info)->app_regs + reg;
45460484Sobrien
45560484Sobrien      if (p->name != NULL && strcmp (p->name, *namep))
45660484Sobrien	{
45760484Sobrien          (*_bfd_error_handler)
458218822Sdim            (_("Register %%g%d used incompatibly: %s in %B, previously %s in %B"),
459218822Sdim             abfd, p->abfd, (int) sym->st_value,
460218822Sdim             **namep ? *namep : "#scratch",
461218822Sdim             *p->name ? p->name : "#scratch");
462130561Sobrien	  return FALSE;
46360484Sobrien	}
46460484Sobrien
46560484Sobrien      if (p->name == NULL)
46660484Sobrien	{
46760484Sobrien	  if (**namep)
46860484Sobrien	    {
46960484Sobrien	      struct elf_link_hash_entry *h;
47077298Sobrien
47160484Sobrien	      h = (struct elf_link_hash_entry *)
472130561Sobrien		bfd_link_hash_lookup (info->hash, *namep, FALSE, FALSE, FALSE);
47360484Sobrien
47460484Sobrien	      if (h != NULL)
47560484Sobrien		{
47660484Sobrien		  unsigned char type = h->type;
47760484Sobrien
47889857Sobrien		  if (type > STT_FUNC)
47989857Sobrien		    type = 0;
48060484Sobrien		  (*_bfd_error_handler)
481218822Sdim		    (_("Symbol `%s' has differing types: REGISTER in %B, previously %s in %B"),
482218822Sdim		     abfd, p->abfd, *namep, stt_types[type]);
483130561Sobrien		  return FALSE;
48460484Sobrien		}
48560484Sobrien
48660484Sobrien	      p->name = bfd_hash_allocate (&info->hash->table,
48760484Sobrien					   strlen (*namep) + 1);
48860484Sobrien	      if (!p->name)
489130561Sobrien		return FALSE;
49060484Sobrien
49160484Sobrien	      strcpy (p->name, *namep);
49260484Sobrien	    }
49360484Sobrien	  else
49460484Sobrien	    p->name = "";
49560484Sobrien	  p->bind = ELF_ST_BIND (sym->st_info);
49660484Sobrien	  p->abfd = abfd;
49760484Sobrien	  p->shndx = sym->st_shndx;
49860484Sobrien	}
49960484Sobrien      else
50060484Sobrien	{
50160484Sobrien	  if (p->bind == STB_WEAK
50260484Sobrien	      && ELF_ST_BIND (sym->st_info) == STB_GLOBAL)
50360484Sobrien	    {
50460484Sobrien	      p->bind = STB_GLOBAL;
50560484Sobrien	      p->abfd = abfd;
50660484Sobrien	    }
50760484Sobrien	}
50860484Sobrien      *namep = NULL;
509130561Sobrien      return TRUE;
51060484Sobrien    }
51199461Sobrien  else if (*namep && **namep
512104834Sobrien	   && info->hash->creator == abfd->xvec)
51360484Sobrien    {
51460484Sobrien      int i;
515218822Sdim      struct _bfd_sparc_elf_app_reg *p;
51660484Sobrien
517218822Sdim      p = _bfd_sparc_elf_hash_table(info)->app_regs;
51860484Sobrien      for (i = 0; i < 4; i++, p++)
51960484Sobrien	if (p->name != NULL && ! strcmp (p->name, *namep))
52060484Sobrien	  {
52160484Sobrien	    unsigned char type = ELF_ST_TYPE (sym->st_info);
52260484Sobrien
52389857Sobrien	    if (type > STT_FUNC)
52489857Sobrien	      type = 0;
52560484Sobrien	    (*_bfd_error_handler)
526218822Sdim	      (_("Symbol `%s' has differing types: %s in %B, previously REGISTER in %B"),
527218822Sdim	       abfd, p->abfd, *namep, stt_types[type]);
528130561Sobrien	    return FALSE;
52960484Sobrien	  }
53060484Sobrien    }
531130561Sobrien  return TRUE;
53260484Sobrien}
53360484Sobrien
534130561Sobrien/* This function takes care of emitting STT_REGISTER symbols
53560484Sobrien   which we cannot easily keep in the symbol hash table.  */
53660484Sobrien
537130561Sobrienstatic bfd_boolean
538218822Sdimelf64_sparc_output_arch_syms (bfd *output_bfd ATTRIBUTE_UNUSED,
539218822Sdim			      struct bfd_link_info *info,
540218822Sdim			      PTR finfo, bfd_boolean (*func) (PTR, const char *,
541218822Sdim							      Elf_Internal_Sym *,
542218822Sdim							      asection *,
543218822Sdim							      struct elf_link_hash_entry *))
54460484Sobrien{
54560484Sobrien  int reg;
546218822Sdim  struct _bfd_sparc_elf_app_reg *app_regs =
547218822Sdim    _bfd_sparc_elf_hash_table(info)->app_regs;
54860484Sobrien  Elf_Internal_Sym sym;
54960484Sobrien
55060484Sobrien  /* We arranged in size_dynamic_sections to put the STT_REGISTER entries
55160484Sobrien     at the end of the dynlocal list, so they came at the end of the local
55260484Sobrien     symbols in the symtab.  Except that they aren't STB_LOCAL, so we need
55360484Sobrien     to back up symtab->sh_info.  */
55460484Sobrien  if (elf_hash_table (info)->dynlocal)
55560484Sobrien    {
55660484Sobrien      bfd * dynobj = elf_hash_table (info)->dynobj;
55760484Sobrien      asection *dynsymsec = bfd_get_section_by_name (dynobj, ".dynsym");
55860484Sobrien      struct elf_link_local_dynamic_entry *e;
55960484Sobrien
56060484Sobrien      for (e = elf_hash_table (info)->dynlocal; e ; e = e->next)
56160484Sobrien	if (e->input_indx == -1)
56260484Sobrien	  break;
56360484Sobrien      if (e)
56460484Sobrien	{
56560484Sobrien	  elf_section_data (dynsymsec->output_section)->this_hdr.sh_info
56660484Sobrien	    = e->dynindx;
56760484Sobrien	}
56860484Sobrien    }
56960484Sobrien
57060484Sobrien  if (info->strip == strip_all)
571130561Sobrien    return TRUE;
57260484Sobrien
57360484Sobrien  for (reg = 0; reg < 4; reg++)
57460484Sobrien    if (app_regs [reg].name != NULL)
57560484Sobrien      {
57660484Sobrien	if (info->strip == strip_some
57760484Sobrien	    && bfd_hash_lookup (info->keep_hash,
57860484Sobrien				app_regs [reg].name,
579130561Sobrien				FALSE, FALSE) == NULL)
58060484Sobrien	  continue;
58160484Sobrien
58260484Sobrien	sym.st_value = reg < 2 ? reg + 2 : reg + 4;
58360484Sobrien	sym.st_size = 0;
58460484Sobrien	sym.st_other = 0;
58560484Sobrien	sym.st_info = ELF_ST_INFO (app_regs [reg].bind, STT_REGISTER);
58660484Sobrien	sym.st_shndx = app_regs [reg].shndx;
58760484Sobrien	if (! (*func) (finfo, app_regs [reg].name, &sym,
58860484Sobrien		       sym.st_shndx == SHN_ABS
589130561Sobrien			 ? bfd_abs_section_ptr : bfd_und_section_ptr,
590130561Sobrien		       NULL))
591130561Sobrien	  return FALSE;
59260484Sobrien      }
59360484Sobrien
594130561Sobrien  return TRUE;
59560484Sobrien}
59660484Sobrien
59760484Sobrienstatic int
598218822Sdimelf64_sparc_get_symbol_type (Elf_Internal_Sym *elf_sym, int type)
59960484Sobrien{
60060484Sobrien  if (ELF_ST_TYPE (elf_sym->st_info) == STT_REGISTER)
60160484Sobrien    return STT_REGISTER;
60260484Sobrien  else
60360484Sobrien    return type;
60460484Sobrien}
60560484Sobrien
60660484Sobrien/* A STB_GLOBAL,STT_REGISTER symbol should be BSF_GLOBAL
60760484Sobrien   even in SHN_UNDEF section.  */
60860484Sobrien
60960484Sobrienstatic void
610218822Sdimelf64_sparc_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED, asymbol *asym)
61160484Sobrien{
61260484Sobrien  elf_symbol_type *elfsym;
61360484Sobrien
61460484Sobrien  elfsym = (elf_symbol_type *) asym;
61560484Sobrien  if (elfsym->internal_elf_sym.st_info
61660484Sobrien      == ELF_ST_INFO (STB_GLOBAL, STT_REGISTER))
61760484Sobrien    {
61860484Sobrien      asym->flags |= BSF_GLOBAL;
61960484Sobrien    }
62060484Sobrien}
62160484Sobrien
62259024Sobrien
62389857Sobrien/* Functions for dealing with the e_flags field.  */
62478828Sobrien
62559024Sobrien/* Merge backend specific data from an object file to the output
62659024Sobrien   object file when linking.  */
62759024Sobrien
628130561Sobrienstatic bfd_boolean
629218822Sdimelf64_sparc_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
63059024Sobrien{
631130561Sobrien  bfd_boolean error;
63259024Sobrien  flagword new_flags, old_flags;
63359024Sobrien  int new_mm, old_mm;
63459024Sobrien
63559024Sobrien  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
63659024Sobrien      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
637130561Sobrien    return TRUE;
63859024Sobrien
63959024Sobrien  new_flags = elf_elfheader (ibfd)->e_flags;
64059024Sobrien  old_flags = elf_elfheader (obfd)->e_flags;
64159024Sobrien
64259024Sobrien  if (!elf_flags_init (obfd))   /* First call, no flags set */
64359024Sobrien    {
644130561Sobrien      elf_flags_init (obfd) = TRUE;
64559024Sobrien      elf_elfheader (obfd)->e_flags = new_flags;
64659024Sobrien    }
64777298Sobrien
64859024Sobrien  else if (new_flags == old_flags)      /* Compatible flags are ok */
64959024Sobrien    ;
65077298Sobrien
65159024Sobrien  else                                  /* Incompatible flags */
65259024Sobrien    {
653130561Sobrien      error = FALSE;
65477298Sobrien
65577298Sobrien#define EF_SPARC_ISA_EXTENSIONS \
65677298Sobrien  (EF_SPARC_SUN_US1 | EF_SPARC_SUN_US3 | EF_SPARC_HAL_R1)
65777298Sobrien
65860484Sobrien      if ((ibfd->flags & DYNAMIC) != 0)
65960484Sobrien	{
66060484Sobrien	  /* We don't want dynamic objects memory ordering and
66160484Sobrien	     architecture to have any role. That's what dynamic linker
66260484Sobrien	     should do.  */
66377298Sobrien	  new_flags &= ~(EF_SPARCV9_MM | EF_SPARC_ISA_EXTENSIONS);
66477298Sobrien	  new_flags |= (old_flags
66577298Sobrien			& (EF_SPARCV9_MM | EF_SPARC_ISA_EXTENSIONS));
66660484Sobrien	}
66760484Sobrien      else
66860484Sobrien	{
66960484Sobrien	  /* Choose the highest architecture requirements.  */
67077298Sobrien	  old_flags |= (new_flags & EF_SPARC_ISA_EXTENSIONS);
67177298Sobrien	  new_flags |= (old_flags & EF_SPARC_ISA_EXTENSIONS);
67277298Sobrien	  if ((old_flags & (EF_SPARC_SUN_US1 | EF_SPARC_SUN_US3))
67377298Sobrien	      && (old_flags & EF_SPARC_HAL_R1))
67460484Sobrien	    {
675130561Sobrien	      error = TRUE;
67660484Sobrien	      (*_bfd_error_handler)
677218822Sdim		(_("%B: linking UltraSPARC specific with HAL specific code"),
678218822Sdim		 ibfd);
67960484Sobrien	    }
68060484Sobrien	  /* Choose the most restrictive memory ordering.  */
68160484Sobrien	  old_mm = (old_flags & EF_SPARCV9_MM);
68260484Sobrien	  new_mm = (new_flags & EF_SPARCV9_MM);
68360484Sobrien	  old_flags &= ~EF_SPARCV9_MM;
68460484Sobrien	  new_flags &= ~EF_SPARCV9_MM;
68560484Sobrien	  if (new_mm < old_mm)
68660484Sobrien	    old_mm = new_mm;
68760484Sobrien	  old_flags |= old_mm;
68860484Sobrien	  new_flags |= old_mm;
68960484Sobrien	}
69059024Sobrien
69159024Sobrien      /* Warn about any other mismatches */
69259024Sobrien      if (new_flags != old_flags)
69359024Sobrien        {
694130561Sobrien          error = TRUE;
69559024Sobrien          (*_bfd_error_handler)
696218822Sdim            (_("%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
697218822Sdim             ibfd, (long) new_flags, (long) old_flags);
69859024Sobrien        }
69959024Sobrien
70059024Sobrien      elf_elfheader (obfd)->e_flags = old_flags;
70159024Sobrien
70259024Sobrien      if (error)
70359024Sobrien        {
70459024Sobrien          bfd_set_error (bfd_error_bad_value);
705130561Sobrien          return FALSE;
70659024Sobrien        }
70759024Sobrien    }
708130561Sobrien  return TRUE;
70959024Sobrien}
710104834Sobrien
711104834Sobrien/* MARCO: Set the correct entry size for the .stab section.  */
712104834Sobrien
713130561Sobrienstatic bfd_boolean
714218822Sdimelf64_sparc_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
715218822Sdim			   Elf_Internal_Shdr *hdr ATTRIBUTE_UNUSED,
716218822Sdim			   asection *sec)
717104834Sobrien{
718104834Sobrien  const char *name;
719104834Sobrien
720104834Sobrien  name = bfd_get_section_name (abfd, sec);
721104834Sobrien
722104834Sobrien  if (strcmp (name, ".stab") == 0)
723104834Sobrien    {
724104834Sobrien      /* Even in the 64bit case the stab entries are only 12 bytes long.  */
725104834Sobrien      elf_section_data (sec)->this_hdr.sh_entsize = 12;
726104834Sobrien    }
727130561Sobrien
728130561Sobrien  return TRUE;
729104834Sobrien}
73060484Sobrien
73160484Sobrien/* Print a STT_REGISTER symbol to file FILE.  */
73259024Sobrien
73360484Sobrienstatic const char *
734218822Sdimelf64_sparc_print_symbol_all (bfd *abfd ATTRIBUTE_UNUSED, PTR filep,
735218822Sdim			      asymbol *symbol)
73660484Sobrien{
73760484Sobrien  FILE *file = (FILE *) filep;
73860484Sobrien  int reg, type;
73977298Sobrien
74060484Sobrien  if (ELF_ST_TYPE (((elf_symbol_type *) symbol)->internal_elf_sym.st_info)
74160484Sobrien      != STT_REGISTER)
74260484Sobrien    return NULL;
74360484Sobrien
74460484Sobrien  reg = ((elf_symbol_type *) symbol)->internal_elf_sym.st_value;
74560484Sobrien  type = symbol->flags;
74660484Sobrien  fprintf (file, "REG_%c%c%11s%c%c    R", "GOLI" [reg / 8], '0' + (reg & 7), "",
74760484Sobrien		 ((type & BSF_LOCAL)
74860484Sobrien		  ? (type & BSF_GLOBAL) ? '!' : 'l'
74989857Sobrien	          : (type & BSF_GLOBAL) ? 'g' : ' '),
75089857Sobrien	         (type & BSF_WEAK) ? 'w' : ' ');
75160484Sobrien  if (symbol->name == NULL || symbol->name [0] == '\0')
75260484Sobrien    return "#scratch";
75360484Sobrien  else
75460484Sobrien    return symbol->name;
75560484Sobrien}
75659024Sobrien
757218822Sdimstatic enum elf_reloc_type_class
758218822Sdimelf64_sparc_reloc_type_class (const Elf_Internal_Rela *rela)
75959024Sobrien{
760218822Sdim  switch ((int) ELF64_R_TYPE (rela->r_info))
761218822Sdim    {
762218822Sdim    case R_SPARC_RELATIVE:
763218822Sdim      return reloc_class_relative;
764218822Sdim    case R_SPARC_JMP_SLOT:
765218822Sdim      return reloc_class_plt;
766218822Sdim    case R_SPARC_COPY:
767218822Sdim      return reloc_class_copy;
768218822Sdim    default:
769218822Sdim      return reloc_class_normal;
770218822Sdim    }
77159024Sobrien}
77259024Sobrien
77360484Sobrien/* Relocations in the 64 bit SPARC ELF ABI are more complex than in
77460484Sobrien   standard ELF, because R_SPARC_OLO10 has secondary addend in
77560484Sobrien   ELF64_R_TYPE_DATA field.  This structure is used to redirect the
77660484Sobrien   relocation handling routines.  */
77760484Sobrien
778218822Sdimconst struct elf_size_info elf64_sparc_size_info =
77960484Sobrien{
78060484Sobrien  sizeof (Elf64_External_Ehdr),
78160484Sobrien  sizeof (Elf64_External_Phdr),
78260484Sobrien  sizeof (Elf64_External_Shdr),
78360484Sobrien  sizeof (Elf64_External_Rel),
78460484Sobrien  sizeof (Elf64_External_Rela),
78560484Sobrien  sizeof (Elf64_External_Sym),
78660484Sobrien  sizeof (Elf64_External_Dyn),
78760484Sobrien  sizeof (Elf_External_Note),
788130561Sobrien  4,		/* hash-table entry size.  */
789130561Sobrien  /* Internal relocations per external relocations.
79060484Sobrien     For link purposes we use just 1 internal per
79160484Sobrien     1 external, for assembly and slurp symbol table
79277298Sobrien     we use 2.  */
79360484Sobrien  1,
794130561Sobrien  64,		/* arch_size.  */
795130561Sobrien  3,		/* log_file_align.  */
79660484Sobrien  ELFCLASS64,
79760484Sobrien  EV_CURRENT,
79860484Sobrien  bfd_elf64_write_out_phdrs,
79960484Sobrien  bfd_elf64_write_shdrs_and_ehdr,
800218822Sdim  elf64_sparc_write_relocs,
801104834Sobrien  bfd_elf64_swap_symbol_in,
80260484Sobrien  bfd_elf64_swap_symbol_out,
803218822Sdim  elf64_sparc_slurp_reloc_table,
80460484Sobrien  bfd_elf64_slurp_symbol_table,
80560484Sobrien  bfd_elf64_swap_dyn_in,
80660484Sobrien  bfd_elf64_swap_dyn_out,
807130561Sobrien  bfd_elf64_swap_reloc_in,
808130561Sobrien  bfd_elf64_swap_reloc_out,
809130561Sobrien  bfd_elf64_swap_reloca_in,
810130561Sobrien  bfd_elf64_swap_reloca_out
81160484Sobrien};
81260484Sobrien
81359024Sobrien#define TARGET_BIG_SYM	bfd_elf64_sparc_vec
81459024Sobrien#define TARGET_BIG_NAME	"elf64-sparc"
81559024Sobrien#define ELF_ARCH	bfd_arch_sparc
81659024Sobrien#define ELF_MAXPAGESIZE 0x100000
817218822Sdim#define ELF_COMMONPAGESIZE 0x2000
81859024Sobrien
81960484Sobrien/* This is the official ABI value.  */
82060484Sobrien#define ELF_MACHINE_CODE EM_SPARCV9
82160484Sobrien
82260484Sobrien/* This is the value that we used before the ABI was released.  */
82360484Sobrien#define ELF_MACHINE_ALT1 EM_OLD_SPARCV9
82460484Sobrien
825218822Sdim#define elf_backend_reloc_type_class \
826218822Sdim  elf64_sparc_reloc_type_class
82760484Sobrien#define bfd_elf64_get_reloc_upper_bound \
828218822Sdim  elf64_sparc_get_reloc_upper_bound
82960484Sobrien#define bfd_elf64_get_dynamic_reloc_upper_bound \
830218822Sdim  elf64_sparc_get_dynamic_reloc_upper_bound
831130561Sobrien#define bfd_elf64_canonicalize_reloc \
832218822Sdim  elf64_sparc_canonicalize_reloc
83360484Sobrien#define bfd_elf64_canonicalize_dynamic_reloc \
834218822Sdim  elf64_sparc_canonicalize_dynamic_reloc
835218822Sdim#define elf_backend_add_symbol_hook \
836218822Sdim  elf64_sparc_add_symbol_hook
837218822Sdim#define elf_backend_get_symbol_type \
838218822Sdim  elf64_sparc_get_symbol_type
839218822Sdim#define elf_backend_symbol_processing \
840218822Sdim  elf64_sparc_symbol_processing
841218822Sdim#define elf_backend_print_symbol_all \
842218822Sdim  elf64_sparc_print_symbol_all
843218822Sdim#define elf_backend_output_arch_syms \
844218822Sdim  elf64_sparc_output_arch_syms
845218822Sdim#define bfd_elf64_bfd_merge_private_bfd_data \
846218822Sdim  elf64_sparc_merge_private_bfd_data
847218822Sdim#define elf_backend_fake_sections \
848218822Sdim  elf64_sparc_fake_sections
849218822Sdim#define elf_backend_size_info \
850218822Sdim  elf64_sparc_size_info
851218822Sdim
852218822Sdim#define elf_backend_plt_sym_val	\
853218822Sdim  _bfd_sparc_elf_plt_sym_val
854218822Sdim#define bfd_elf64_bfd_link_hash_table_create \
855218822Sdim  _bfd_sparc_elf_link_hash_table_create
856218822Sdim#define elf_info_to_howto \
857218822Sdim  _bfd_sparc_elf_info_to_howto
858218822Sdim#define elf_backend_copy_indirect_symbol \
859218822Sdim  _bfd_sparc_elf_copy_indirect_symbol
86059024Sobrien#define bfd_elf64_bfd_reloc_type_lookup \
861218822Sdim  _bfd_sparc_elf_reloc_type_lookup
862218822Sdim#define bfd_elf64_bfd_reloc_name_lookup \
863218822Sdim  _bfd_sparc_elf_reloc_name_lookup
86477298Sobrien#define bfd_elf64_bfd_relax_section \
865218822Sdim  _bfd_sparc_elf_relax_section
866130561Sobrien#define bfd_elf64_new_section_hook \
867218822Sdim  _bfd_sparc_elf_new_section_hook
86859024Sobrien
86959024Sobrien#define elf_backend_create_dynamic_sections \
870218822Sdim  _bfd_sparc_elf_create_dynamic_sections
871218822Sdim#define elf_backend_relocs_compatible \
872218822Sdim  _bfd_elf_relocs_compatible
87359024Sobrien#define elf_backend_check_relocs \
874218822Sdim  _bfd_sparc_elf_check_relocs
87559024Sobrien#define elf_backend_adjust_dynamic_symbol \
876218822Sdim  _bfd_sparc_elf_adjust_dynamic_symbol
877218822Sdim#define elf_backend_omit_section_dynsym \
878218822Sdim  _bfd_sparc_elf_omit_section_dynsym
87959024Sobrien#define elf_backend_size_dynamic_sections \
880218822Sdim  _bfd_sparc_elf_size_dynamic_sections
88159024Sobrien#define elf_backend_relocate_section \
882218822Sdim  _bfd_sparc_elf_relocate_section
88359024Sobrien#define elf_backend_finish_dynamic_symbol \
884218822Sdim  _bfd_sparc_elf_finish_dynamic_symbol
88559024Sobrien#define elf_backend_finish_dynamic_sections \
886218822Sdim  _bfd_sparc_elf_finish_dynamic_sections
88759024Sobrien
888218822Sdim#define bfd_elf64_mkobject \
889218822Sdim  _bfd_sparc_elf_mkobject
89059024Sobrien#define elf_backend_object_p \
891218822Sdim  _bfd_sparc_elf_object_p
892218822Sdim#define elf_backend_gc_mark_hook \
893218822Sdim  _bfd_sparc_elf_gc_mark_hook
894218822Sdim#define elf_backend_gc_sweep_hook \
895218822Sdim  _bfd_sparc_elf_gc_sweep_hook
896218822Sdim#define elf_backend_init_index_section \
897218822Sdim  _bfd_elf_init_1_index_section
89859024Sobrien
899218822Sdim#define elf_backend_can_gc_sections 1
900218822Sdim#define elf_backend_can_refcount 1
90159024Sobrien#define elf_backend_want_got_plt 0
90259024Sobrien#define elf_backend_plt_readonly 0
90359024Sobrien#define elf_backend_want_plt_sym 1
904218822Sdim#define elf_backend_got_header_size 8
905130561Sobrien#define elf_backend_rela_normal 1
90659024Sobrien
90759024Sobrien/* Section 5.2.4 of the ABI specifies a 256-byte boundary for the table.  */
90859024Sobrien#define elf_backend_plt_alignment 8
90959024Sobrien
910218822Sdim#include "elf64-target.h"
91160484Sobrien
912218822Sdim/* FreeBSD support */
913218822Sdim#undef  TARGET_BIG_SYM
914218822Sdim#define TARGET_BIG_SYM bfd_elf64_sparc_freebsd_vec
915218822Sdim#undef  TARGET_BIG_NAME
916218822Sdim#define TARGET_BIG_NAME "elf64-sparc-freebsd"
917218822Sdim#undef	ELF_OSABI
918218822Sdim#define	ELF_OSABI ELFOSABI_FREEBSD
919218822Sdim
920218822Sdim#undef  elf_backend_post_process_headers
921218822Sdim#define elf_backend_post_process_headers	_bfd_elf_set_osabi
922218822Sdim#undef  elf64_bed
923218822Sdim#define elf64_bed				elf64_sparc_fbsd_bed
924218822Sdim
92559024Sobrien#include "elf64-target.h"
926218822Sdim
927