13d8817e4Smiod /* SPARC-specific support for 64-bit ELF
23d8817e4Smiod Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
33d8817e4Smiod 2003, 2004, 2005 Free Software Foundation, Inc.
43d8817e4Smiod
53d8817e4Smiod This file is part of BFD, the Binary File Descriptor library.
63d8817e4Smiod
73d8817e4Smiod This program is free software; you can redistribute it and/or modify
83d8817e4Smiod it under the terms of the GNU General Public License as published by
93d8817e4Smiod the Free Software Foundation; either version 2 of the License, or
103d8817e4Smiod (at your option) any later version.
113d8817e4Smiod
123d8817e4Smiod This program is distributed in the hope that it will be useful,
133d8817e4Smiod but WITHOUT ANY WARRANTY; without even the implied warranty of
143d8817e4Smiod MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
153d8817e4Smiod GNU General Public License for more details.
163d8817e4Smiod
173d8817e4Smiod You should have received a copy of the GNU General Public License
183d8817e4Smiod along with this program; if not, write to the Free Software
193d8817e4Smiod Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
203d8817e4Smiod
213d8817e4Smiod #include "bfd.h"
223d8817e4Smiod #include "sysdep.h"
233d8817e4Smiod #include "libbfd.h"
243d8817e4Smiod #include "elf-bfd.h"
253d8817e4Smiod #include "elf/sparc.h"
263d8817e4Smiod #include "opcode/sparc.h"
273d8817e4Smiod #include "elfxx-sparc.h"
283d8817e4Smiod
293d8817e4Smiod /* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
303d8817e4Smiod #define MINUS_ONE (~ (bfd_vma) 0)
313d8817e4Smiod
323d8817e4Smiod /* Due to the way how we handle R_SPARC_OLO10, each entry in a SHT_RELA
333d8817e4Smiod section can represent up to two relocs, we must tell the user to allocate
343d8817e4Smiod more space. */
353d8817e4Smiod
363d8817e4Smiod static long
elf64_sparc_get_reloc_upper_bound(bfd * abfd ATTRIBUTE_UNUSED,asection * sec)373d8817e4Smiod elf64_sparc_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
383d8817e4Smiod {
393d8817e4Smiod return (sec->reloc_count * 2 + 1) * sizeof (arelent *);
403d8817e4Smiod }
413d8817e4Smiod
423d8817e4Smiod static long
elf64_sparc_get_dynamic_reloc_upper_bound(bfd * abfd)433d8817e4Smiod elf64_sparc_get_dynamic_reloc_upper_bound (bfd *abfd)
443d8817e4Smiod {
453d8817e4Smiod return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 2;
463d8817e4Smiod }
473d8817e4Smiod
483d8817e4Smiod /* Read relocations for ASECT from REL_HDR. There are RELOC_COUNT of
493d8817e4Smiod them. We cannot use generic elf routines for this, because R_SPARC_OLO10
503d8817e4Smiod has secondary addend in ELF64_R_TYPE_DATA. We handle it as two relocations
513d8817e4Smiod for the same location, R_SPARC_LO10 and R_SPARC_13. */
523d8817e4Smiod
533d8817e4Smiod static bfd_boolean
elf64_sparc_slurp_one_reloc_table(bfd * abfd,asection * asect,Elf_Internal_Shdr * rel_hdr,asymbol ** symbols,bfd_boolean dynamic)543d8817e4Smiod elf64_sparc_slurp_one_reloc_table (bfd *abfd, asection *asect,
553d8817e4Smiod Elf_Internal_Shdr *rel_hdr,
563d8817e4Smiod asymbol **symbols, bfd_boolean dynamic)
573d8817e4Smiod {
583d8817e4Smiod PTR allocated = NULL;
593d8817e4Smiod bfd_byte *native_relocs;
603d8817e4Smiod arelent *relent;
613d8817e4Smiod unsigned int i;
623d8817e4Smiod int entsize;
633d8817e4Smiod bfd_size_type count;
643d8817e4Smiod arelent *relents;
653d8817e4Smiod
663d8817e4Smiod allocated = (PTR) bfd_malloc (rel_hdr->sh_size);
673d8817e4Smiod if (allocated == NULL)
683d8817e4Smiod goto error_return;
693d8817e4Smiod
703d8817e4Smiod if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
713d8817e4Smiod || bfd_bread (allocated, rel_hdr->sh_size, abfd) != rel_hdr->sh_size)
723d8817e4Smiod goto error_return;
733d8817e4Smiod
743d8817e4Smiod native_relocs = (bfd_byte *) allocated;
753d8817e4Smiod
763d8817e4Smiod relents = asect->relocation + canon_reloc_count (asect);
773d8817e4Smiod
783d8817e4Smiod entsize = rel_hdr->sh_entsize;
793d8817e4Smiod BFD_ASSERT (entsize == sizeof (Elf64_External_Rela));
803d8817e4Smiod
813d8817e4Smiod count = rel_hdr->sh_size / entsize;
823d8817e4Smiod
833d8817e4Smiod for (i = 0, relent = relents; i < count;
843d8817e4Smiod i++, relent++, native_relocs += entsize)
853d8817e4Smiod {
863d8817e4Smiod Elf_Internal_Rela rela;
873d8817e4Smiod unsigned int r_type;
883d8817e4Smiod
893d8817e4Smiod bfd_elf64_swap_reloca_in (abfd, native_relocs, &rela);
903d8817e4Smiod
913d8817e4Smiod /* The address of an ELF reloc is section relative for an object
923d8817e4Smiod file, and absolute for an executable file or shared library.
933d8817e4Smiod The address of a normal BFD reloc is always section relative,
943d8817e4Smiod and the address of a dynamic reloc is absolute.. */
953d8817e4Smiod if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
963d8817e4Smiod relent->address = rela.r_offset;
973d8817e4Smiod else
983d8817e4Smiod relent->address = rela.r_offset - asect->vma;
993d8817e4Smiod
1003d8817e4Smiod if (ELF64_R_SYM (rela.r_info) == 0)
1013d8817e4Smiod relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1023d8817e4Smiod else
1033d8817e4Smiod {
1043d8817e4Smiod asymbol **ps, *s;
1053d8817e4Smiod
1063d8817e4Smiod ps = symbols + ELF64_R_SYM (rela.r_info) - 1;
1073d8817e4Smiod s = *ps;
1083d8817e4Smiod
1093d8817e4Smiod /* Canonicalize ELF section symbols. FIXME: Why? */
1103d8817e4Smiod if ((s->flags & BSF_SECTION_SYM) == 0)
1113d8817e4Smiod relent->sym_ptr_ptr = ps;
1123d8817e4Smiod else
1133d8817e4Smiod relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
1143d8817e4Smiod }
1153d8817e4Smiod
1163d8817e4Smiod relent->addend = rela.r_addend;
1173d8817e4Smiod
1183d8817e4Smiod r_type = ELF64_R_TYPE_ID (rela.r_info);
1193d8817e4Smiod if (r_type == R_SPARC_OLO10)
1203d8817e4Smiod {
1213d8817e4Smiod relent->howto = _bfd_sparc_elf_info_to_howto_ptr (R_SPARC_LO10);
1223d8817e4Smiod relent[1].address = relent->address;
1233d8817e4Smiod relent++;
1243d8817e4Smiod relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1253d8817e4Smiod relent->addend = ELF64_R_TYPE_DATA (rela.r_info);
1263d8817e4Smiod relent->howto = _bfd_sparc_elf_info_to_howto_ptr (R_SPARC_13);
1273d8817e4Smiod }
1283d8817e4Smiod else
1293d8817e4Smiod relent->howto = _bfd_sparc_elf_info_to_howto_ptr (r_type);
1303d8817e4Smiod }
1313d8817e4Smiod
1323d8817e4Smiod canon_reloc_count (asect) += relent - relents;
1333d8817e4Smiod
1343d8817e4Smiod if (allocated != NULL)
1353d8817e4Smiod free (allocated);
1363d8817e4Smiod
1373d8817e4Smiod return TRUE;
1383d8817e4Smiod
1393d8817e4Smiod error_return:
1403d8817e4Smiod if (allocated != NULL)
1413d8817e4Smiod free (allocated);
1423d8817e4Smiod return FALSE;
1433d8817e4Smiod }
1443d8817e4Smiod
1453d8817e4Smiod /* Read in and swap the external relocs. */
1463d8817e4Smiod
1473d8817e4Smiod static bfd_boolean
elf64_sparc_slurp_reloc_table(bfd * abfd,asection * asect,asymbol ** symbols,bfd_boolean dynamic)1483d8817e4Smiod elf64_sparc_slurp_reloc_table (bfd *abfd, asection *asect,
1493d8817e4Smiod asymbol **symbols, bfd_boolean dynamic)
1503d8817e4Smiod {
1513d8817e4Smiod struct bfd_elf_section_data * const d = elf_section_data (asect);
1523d8817e4Smiod Elf_Internal_Shdr *rel_hdr;
1533d8817e4Smiod Elf_Internal_Shdr *rel_hdr2;
1543d8817e4Smiod bfd_size_type amt;
1553d8817e4Smiod
1563d8817e4Smiod if (asect->relocation != NULL)
1573d8817e4Smiod return TRUE;
1583d8817e4Smiod
1593d8817e4Smiod if (! dynamic)
1603d8817e4Smiod {
1613d8817e4Smiod if ((asect->flags & SEC_RELOC) == 0
1623d8817e4Smiod || asect->reloc_count == 0)
1633d8817e4Smiod return TRUE;
1643d8817e4Smiod
1653d8817e4Smiod rel_hdr = &d->rel_hdr;
1663d8817e4Smiod rel_hdr2 = d->rel_hdr2;
1673d8817e4Smiod
1683d8817e4Smiod BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
1693d8817e4Smiod || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
1703d8817e4Smiod }
1713d8817e4Smiod else
1723d8817e4Smiod {
1733d8817e4Smiod /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
1743d8817e4Smiod case because relocations against this section may use the
1753d8817e4Smiod dynamic symbol table, and in that case bfd_section_from_shdr
1763d8817e4Smiod in elf.c does not update the RELOC_COUNT. */
1773d8817e4Smiod if (asect->size == 0)
1783d8817e4Smiod return TRUE;
1793d8817e4Smiod
1803d8817e4Smiod rel_hdr = &d->this_hdr;
1813d8817e4Smiod asect->reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
1823d8817e4Smiod rel_hdr2 = NULL;
1833d8817e4Smiod }
1843d8817e4Smiod
1853d8817e4Smiod amt = asect->reloc_count;
1863d8817e4Smiod amt *= 2 * sizeof (arelent);
1873d8817e4Smiod asect->relocation = (arelent *) bfd_alloc (abfd, amt);
1883d8817e4Smiod if (asect->relocation == NULL)
1893d8817e4Smiod return FALSE;
1903d8817e4Smiod
1913d8817e4Smiod /* The elf64_sparc_slurp_one_reloc_table routine increments
1923d8817e4Smiod canon_reloc_count. */
1933d8817e4Smiod canon_reloc_count (asect) = 0;
1943d8817e4Smiod
1953d8817e4Smiod if (!elf64_sparc_slurp_one_reloc_table (abfd, asect, rel_hdr, symbols,
1963d8817e4Smiod dynamic))
1973d8817e4Smiod return FALSE;
1983d8817e4Smiod
1993d8817e4Smiod if (rel_hdr2
2003d8817e4Smiod && !elf64_sparc_slurp_one_reloc_table (abfd, asect, rel_hdr2, symbols,
2013d8817e4Smiod dynamic))
2023d8817e4Smiod return FALSE;
2033d8817e4Smiod
2043d8817e4Smiod return TRUE;
2053d8817e4Smiod }
2063d8817e4Smiod
2073d8817e4Smiod /* Canonicalize the relocs. */
2083d8817e4Smiod
2093d8817e4Smiod static long
elf64_sparc_canonicalize_reloc(bfd * abfd,sec_ptr section,arelent ** relptr,asymbol ** symbols)2103d8817e4Smiod elf64_sparc_canonicalize_reloc (bfd *abfd, sec_ptr section,
2113d8817e4Smiod arelent **relptr, asymbol **symbols)
2123d8817e4Smiod {
2133d8817e4Smiod arelent *tblptr;
2143d8817e4Smiod unsigned int i;
2153d8817e4Smiod const struct elf_backend_data *bed = get_elf_backend_data (abfd);
2163d8817e4Smiod
2173d8817e4Smiod if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
2183d8817e4Smiod return -1;
2193d8817e4Smiod
2203d8817e4Smiod tblptr = section->relocation;
2213d8817e4Smiod for (i = 0; i < canon_reloc_count (section); i++)
2223d8817e4Smiod *relptr++ = tblptr++;
2233d8817e4Smiod
2243d8817e4Smiod *relptr = NULL;
2253d8817e4Smiod
2263d8817e4Smiod return canon_reloc_count (section);
2273d8817e4Smiod }
2283d8817e4Smiod
2293d8817e4Smiod
2303d8817e4Smiod /* Canonicalize the dynamic relocation entries. Note that we return
2313d8817e4Smiod the dynamic relocations as a single block, although they are
2323d8817e4Smiod actually associated with particular sections; the interface, which
2333d8817e4Smiod was designed for SunOS style shared libraries, expects that there
2343d8817e4Smiod is only one set of dynamic relocs. Any section that was actually
2353d8817e4Smiod installed in the BFD, and has type SHT_REL or SHT_RELA, and uses
2363d8817e4Smiod the dynamic symbol table, is considered to be a dynamic reloc
2373d8817e4Smiod section. */
2383d8817e4Smiod
2393d8817e4Smiod static long
elf64_sparc_canonicalize_dynamic_reloc(bfd * abfd,arelent ** storage,asymbol ** syms)2403d8817e4Smiod elf64_sparc_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage,
2413d8817e4Smiod asymbol **syms)
2423d8817e4Smiod {
2433d8817e4Smiod asection *s;
2443d8817e4Smiod long ret;
2453d8817e4Smiod
2463d8817e4Smiod if (elf_dynsymtab (abfd) == 0)
2473d8817e4Smiod {
2483d8817e4Smiod bfd_set_error (bfd_error_invalid_operation);
2493d8817e4Smiod return -1;
2503d8817e4Smiod }
2513d8817e4Smiod
2523d8817e4Smiod ret = 0;
2533d8817e4Smiod for (s = abfd->sections; s != NULL; s = s->next)
2543d8817e4Smiod {
2553d8817e4Smiod if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
2563d8817e4Smiod && (elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
2573d8817e4Smiod {
2583d8817e4Smiod arelent *p;
2593d8817e4Smiod long count, i;
2603d8817e4Smiod
2613d8817e4Smiod if (! elf64_sparc_slurp_reloc_table (abfd, s, syms, TRUE))
2623d8817e4Smiod return -1;
2633d8817e4Smiod count = canon_reloc_count (s);
2643d8817e4Smiod p = s->relocation;
2653d8817e4Smiod for (i = 0; i < count; i++)
2663d8817e4Smiod *storage++ = p++;
2673d8817e4Smiod ret += count;
2683d8817e4Smiod }
2693d8817e4Smiod }
2703d8817e4Smiod
2713d8817e4Smiod *storage = NULL;
2723d8817e4Smiod
2733d8817e4Smiod return ret;
2743d8817e4Smiod }
2753d8817e4Smiod
2763d8817e4Smiod /* Write out the relocs. */
2773d8817e4Smiod
2783d8817e4Smiod static void
elf64_sparc_write_relocs(bfd * abfd,asection * sec,PTR data)2793d8817e4Smiod elf64_sparc_write_relocs (bfd *abfd, asection *sec, PTR data)
2803d8817e4Smiod {
2813d8817e4Smiod bfd_boolean *failedp = (bfd_boolean *) data;
2823d8817e4Smiod Elf_Internal_Shdr *rela_hdr;
2833d8817e4Smiod bfd_vma addr_offset;
2843d8817e4Smiod Elf64_External_Rela *outbound_relocas, *src_rela;
2853d8817e4Smiod unsigned int idx, count;
2863d8817e4Smiod asymbol *last_sym = 0;
2873d8817e4Smiod int last_sym_idx = 0;
2883d8817e4Smiod
2893d8817e4Smiod /* If we have already failed, don't do anything. */
2903d8817e4Smiod if (*failedp)
2913d8817e4Smiod return;
2923d8817e4Smiod
2933d8817e4Smiod if ((sec->flags & SEC_RELOC) == 0)
2943d8817e4Smiod return;
2953d8817e4Smiod
2963d8817e4Smiod /* The linker backend writes the relocs out itself, and sets the
2973d8817e4Smiod reloc_count field to zero to inhibit writing them here. Also,
2983d8817e4Smiod sometimes the SEC_RELOC flag gets set even when there aren't any
2993d8817e4Smiod relocs. */
3003d8817e4Smiod if (sec->reloc_count == 0)
3013d8817e4Smiod return;
3023d8817e4Smiod
3033d8817e4Smiod /* We can combine two relocs that refer to the same address
3043d8817e4Smiod into R_SPARC_OLO10 if first one is R_SPARC_LO10 and the
3053d8817e4Smiod latter is R_SPARC_13 with no associated symbol. */
3063d8817e4Smiod count = 0;
3073d8817e4Smiod for (idx = 0; idx < sec->reloc_count; idx++)
3083d8817e4Smiod {
3093d8817e4Smiod bfd_vma addr;
3103d8817e4Smiod
3113d8817e4Smiod ++count;
3123d8817e4Smiod
3133d8817e4Smiod addr = sec->orelocation[idx]->address;
3143d8817e4Smiod if (sec->orelocation[idx]->howto->type == R_SPARC_LO10
3153d8817e4Smiod && idx < sec->reloc_count - 1)
3163d8817e4Smiod {
3173d8817e4Smiod arelent *r = sec->orelocation[idx + 1];
3183d8817e4Smiod
3193d8817e4Smiod if (r->howto->type == R_SPARC_13
3203d8817e4Smiod && r->address == addr
3213d8817e4Smiod && bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
3223d8817e4Smiod && (*r->sym_ptr_ptr)->value == 0)
3233d8817e4Smiod ++idx;
3243d8817e4Smiod }
3253d8817e4Smiod }
3263d8817e4Smiod
3273d8817e4Smiod rela_hdr = &elf_section_data (sec)->rel_hdr;
3283d8817e4Smiod
3293d8817e4Smiod rela_hdr->sh_size = rela_hdr->sh_entsize * count;
3303d8817e4Smiod rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size);
3313d8817e4Smiod if (rela_hdr->contents == NULL)
3323d8817e4Smiod {
3333d8817e4Smiod *failedp = TRUE;
3343d8817e4Smiod return;
3353d8817e4Smiod }
3363d8817e4Smiod
3373d8817e4Smiod /* Figure out whether the relocations are RELA or REL relocations. */
3383d8817e4Smiod if (rela_hdr->sh_type != SHT_RELA)
3393d8817e4Smiod abort ();
3403d8817e4Smiod
3413d8817e4Smiod /* The address of an ELF reloc is section relative for an object
3423d8817e4Smiod file, and absolute for an executable file or shared library.
3433d8817e4Smiod The address of a BFD reloc is always section relative. */
3443d8817e4Smiod addr_offset = 0;
3453d8817e4Smiod if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
3463d8817e4Smiod addr_offset = sec->vma;
3473d8817e4Smiod
3483d8817e4Smiod /* orelocation has the data, reloc_count has the count... */
3493d8817e4Smiod outbound_relocas = (Elf64_External_Rela *) rela_hdr->contents;
3503d8817e4Smiod src_rela = outbound_relocas;
3513d8817e4Smiod
3523d8817e4Smiod for (idx = 0; idx < sec->reloc_count; idx++)
3533d8817e4Smiod {
3543d8817e4Smiod Elf_Internal_Rela dst_rela;
3553d8817e4Smiod arelent *ptr;
3563d8817e4Smiod asymbol *sym;
3573d8817e4Smiod int n;
3583d8817e4Smiod
3593d8817e4Smiod ptr = sec->orelocation[idx];
3603d8817e4Smiod sym = *ptr->sym_ptr_ptr;
3613d8817e4Smiod if (sym == last_sym)
3623d8817e4Smiod n = last_sym_idx;
3633d8817e4Smiod else if (bfd_is_abs_section (sym->section) && sym->value == 0)
3643d8817e4Smiod n = STN_UNDEF;
3653d8817e4Smiod else
3663d8817e4Smiod {
3673d8817e4Smiod last_sym = sym;
3683d8817e4Smiod n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
3693d8817e4Smiod if (n < 0)
3703d8817e4Smiod {
3713d8817e4Smiod *failedp = TRUE;
3723d8817e4Smiod return;
3733d8817e4Smiod }
3743d8817e4Smiod last_sym_idx = n;
3753d8817e4Smiod }
3763d8817e4Smiod
3773d8817e4Smiod if ((*ptr->sym_ptr_ptr)->the_bfd != NULL
3783d8817e4Smiod && (*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
3793d8817e4Smiod && ! _bfd_elf_validate_reloc (abfd, ptr))
3803d8817e4Smiod {
3813d8817e4Smiod *failedp = TRUE;
3823d8817e4Smiod return;
3833d8817e4Smiod }
3843d8817e4Smiod
3853d8817e4Smiod if (ptr->howto->type == R_SPARC_LO10
3863d8817e4Smiod && idx < sec->reloc_count - 1)
3873d8817e4Smiod {
3883d8817e4Smiod arelent *r = sec->orelocation[idx + 1];
3893d8817e4Smiod
3903d8817e4Smiod if (r->howto->type == R_SPARC_13
3913d8817e4Smiod && r->address == ptr->address
3923d8817e4Smiod && bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
3933d8817e4Smiod && (*r->sym_ptr_ptr)->value == 0)
3943d8817e4Smiod {
3953d8817e4Smiod idx++;
3963d8817e4Smiod dst_rela.r_info
3973d8817e4Smiod = ELF64_R_INFO (n, ELF64_R_TYPE_INFO (r->addend,
3983d8817e4Smiod R_SPARC_OLO10));
3993d8817e4Smiod }
4003d8817e4Smiod else
4013d8817e4Smiod dst_rela.r_info = ELF64_R_INFO (n, R_SPARC_LO10);
4023d8817e4Smiod }
4033d8817e4Smiod else
4043d8817e4Smiod dst_rela.r_info = ELF64_R_INFO (n, ptr->howto->type);
4053d8817e4Smiod
4063d8817e4Smiod dst_rela.r_offset = ptr->address + addr_offset;
4073d8817e4Smiod dst_rela.r_addend = ptr->addend;
4083d8817e4Smiod
4093d8817e4Smiod bfd_elf64_swap_reloca_out (abfd, &dst_rela, (bfd_byte *) src_rela);
4103d8817e4Smiod ++src_rela;
4113d8817e4Smiod }
4123d8817e4Smiod }
4133d8817e4Smiod
4143d8817e4Smiod /* Hook called by the linker routine which adds symbols from an object
4153d8817e4Smiod file. We use it for STT_REGISTER symbols. */
4163d8817e4Smiod
4173d8817e4Smiod static bfd_boolean
elf64_sparc_add_symbol_hook(bfd * abfd,struct bfd_link_info * info,Elf_Internal_Sym * sym,const char ** namep,flagword * flagsp ATTRIBUTE_UNUSED,asection ** secp ATTRIBUTE_UNUSED,bfd_vma * valp ATTRIBUTE_UNUSED)4183d8817e4Smiod elf64_sparc_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
4193d8817e4Smiod Elf_Internal_Sym *sym, const char **namep,
4203d8817e4Smiod flagword *flagsp ATTRIBUTE_UNUSED,
4213d8817e4Smiod asection **secp ATTRIBUTE_UNUSED,
4223d8817e4Smiod bfd_vma *valp ATTRIBUTE_UNUSED)
4233d8817e4Smiod {
4243d8817e4Smiod static const char *const stt_types[] = { "NOTYPE", "OBJECT", "FUNCTION" };
4253d8817e4Smiod
4263d8817e4Smiod if (ELF_ST_TYPE (sym->st_info) == STT_REGISTER)
4273d8817e4Smiod {
4283d8817e4Smiod int reg;
4293d8817e4Smiod struct _bfd_sparc_elf_app_reg *p;
4303d8817e4Smiod
4313d8817e4Smiod reg = (int)sym->st_value;
4323d8817e4Smiod switch (reg & ~1)
4333d8817e4Smiod {
4343d8817e4Smiod case 2: reg -= 2; break;
4353d8817e4Smiod case 6: reg -= 4; break;
4363d8817e4Smiod default:
4373d8817e4Smiod (*_bfd_error_handler)
4383d8817e4Smiod (_("%B: Only registers %%g[2367] can be declared using STT_REGISTER"),
4393d8817e4Smiod abfd);
4403d8817e4Smiod return FALSE;
4413d8817e4Smiod }
4423d8817e4Smiod
4433d8817e4Smiod if (info->hash->creator != abfd->xvec
4443d8817e4Smiod || (abfd->flags & DYNAMIC) != 0)
4453d8817e4Smiod {
4463d8817e4Smiod /* STT_REGISTER only works when linking an elf64_sparc object.
4473d8817e4Smiod If STT_REGISTER comes from a dynamic object, don't put it into
4483d8817e4Smiod the output bfd. The dynamic linker will recheck it. */
4493d8817e4Smiod *namep = NULL;
4503d8817e4Smiod return TRUE;
4513d8817e4Smiod }
4523d8817e4Smiod
4533d8817e4Smiod p = _bfd_sparc_elf_hash_table(info)->app_regs + reg;
4543d8817e4Smiod
4553d8817e4Smiod if (p->name != NULL && strcmp (p->name, *namep))
4563d8817e4Smiod {
4573d8817e4Smiod (*_bfd_error_handler)
4583d8817e4Smiod (_("Register %%g%d used incompatibly: %s in %B, previously %s in %B"),
4593d8817e4Smiod abfd, p->abfd, (int) sym->st_value,
4603d8817e4Smiod **namep ? *namep : "#scratch",
4613d8817e4Smiod *p->name ? p->name : "#scratch");
4623d8817e4Smiod return FALSE;
4633d8817e4Smiod }
4643d8817e4Smiod
4653d8817e4Smiod if (p->name == NULL)
4663d8817e4Smiod {
4673d8817e4Smiod if (**namep)
4683d8817e4Smiod {
4693d8817e4Smiod struct elf_link_hash_entry *h;
4703d8817e4Smiod
4713d8817e4Smiod h = (struct elf_link_hash_entry *)
4723d8817e4Smiod bfd_link_hash_lookup (info->hash, *namep, FALSE, FALSE, FALSE);
4733d8817e4Smiod
4743d8817e4Smiod if (h != NULL)
4753d8817e4Smiod {
4763d8817e4Smiod unsigned char type = h->type;
4773d8817e4Smiod
4783d8817e4Smiod if (type > STT_FUNC)
4793d8817e4Smiod type = 0;
4803d8817e4Smiod (*_bfd_error_handler)
4813d8817e4Smiod (_("Symbol `%s' has differing types: REGISTER in %B, previously %s in %B"),
4823d8817e4Smiod abfd, p->abfd, *namep, stt_types[type]);
4833d8817e4Smiod return FALSE;
4843d8817e4Smiod }
4853d8817e4Smiod
4863d8817e4Smiod p->name = bfd_hash_allocate (&info->hash->table,
4873d8817e4Smiod strlen (*namep) + 1);
4883d8817e4Smiod if (!p->name)
4893d8817e4Smiod return FALSE;
4903d8817e4Smiod
4913d8817e4Smiod strcpy (p->name, *namep);
4923d8817e4Smiod }
4933d8817e4Smiod else
4943d8817e4Smiod p->name = "";
4953d8817e4Smiod p->bind = ELF_ST_BIND (sym->st_info);
4963d8817e4Smiod p->abfd = abfd;
4973d8817e4Smiod p->shndx = sym->st_shndx;
4983d8817e4Smiod }
4993d8817e4Smiod else
5003d8817e4Smiod {
5013d8817e4Smiod if (p->bind == STB_WEAK
5023d8817e4Smiod && ELF_ST_BIND (sym->st_info) == STB_GLOBAL)
5033d8817e4Smiod {
5043d8817e4Smiod p->bind = STB_GLOBAL;
5053d8817e4Smiod p->abfd = abfd;
5063d8817e4Smiod }
5073d8817e4Smiod }
5083d8817e4Smiod *namep = NULL;
5093d8817e4Smiod return TRUE;
5103d8817e4Smiod }
5113d8817e4Smiod else if (*namep && **namep
5123d8817e4Smiod && info->hash->creator == abfd->xvec)
5133d8817e4Smiod {
5143d8817e4Smiod int i;
5153d8817e4Smiod struct _bfd_sparc_elf_app_reg *p;
5163d8817e4Smiod
5173d8817e4Smiod p = _bfd_sparc_elf_hash_table(info)->app_regs;
5183d8817e4Smiod for (i = 0; i < 4; i++, p++)
5193d8817e4Smiod if (p->name != NULL && ! strcmp (p->name, *namep))
5203d8817e4Smiod {
5213d8817e4Smiod unsigned char type = ELF_ST_TYPE (sym->st_info);
5223d8817e4Smiod
5233d8817e4Smiod if (type > STT_FUNC)
5243d8817e4Smiod type = 0;
5253d8817e4Smiod (*_bfd_error_handler)
5263d8817e4Smiod (_("Symbol `%s' has differing types: %s in %B, previously REGISTER in %B"),
5273d8817e4Smiod abfd, p->abfd, *namep, stt_types[type]);
5283d8817e4Smiod return FALSE;
5293d8817e4Smiod }
5303d8817e4Smiod }
5313d8817e4Smiod return TRUE;
5323d8817e4Smiod }
5333d8817e4Smiod
5343d8817e4Smiod /* This function takes care of emitting STT_REGISTER symbols
5353d8817e4Smiod which we cannot easily keep in the symbol hash table. */
5363d8817e4Smiod
5373d8817e4Smiod static bfd_boolean
elf64_sparc_output_arch_syms(bfd * output_bfd ATTRIBUTE_UNUSED,struct bfd_link_info * info,PTR finfo,bfd_boolean (* func)(PTR,const char *,Elf_Internal_Sym *,asection *,struct elf_link_hash_entry *))5383d8817e4Smiod elf64_sparc_output_arch_syms (bfd *output_bfd ATTRIBUTE_UNUSED,
5393d8817e4Smiod struct bfd_link_info *info,
5403d8817e4Smiod PTR finfo, bfd_boolean (*func) (PTR, const char *,
5413d8817e4Smiod Elf_Internal_Sym *,
5423d8817e4Smiod asection *,
5433d8817e4Smiod struct elf_link_hash_entry *))
5443d8817e4Smiod {
5453d8817e4Smiod int reg;
5463d8817e4Smiod struct _bfd_sparc_elf_app_reg *app_regs =
5473d8817e4Smiod _bfd_sparc_elf_hash_table(info)->app_regs;
5483d8817e4Smiod Elf_Internal_Sym sym;
5493d8817e4Smiod
5503d8817e4Smiod /* We arranged in size_dynamic_sections to put the STT_REGISTER entries
5513d8817e4Smiod at the end of the dynlocal list, so they came at the end of the local
5523d8817e4Smiod symbols in the symtab. Except that they aren't STB_LOCAL, so we need
5533d8817e4Smiod to back up symtab->sh_info. */
5543d8817e4Smiod if (elf_hash_table (info)->dynlocal)
5553d8817e4Smiod {
5563d8817e4Smiod bfd * dynobj = elf_hash_table (info)->dynobj;
5573d8817e4Smiod asection *dynsymsec = bfd_get_section_by_name (dynobj, ".dynsym");
5583d8817e4Smiod struct elf_link_local_dynamic_entry *e;
5593d8817e4Smiod
5603d8817e4Smiod for (e = elf_hash_table (info)->dynlocal; e ; e = e->next)
5613d8817e4Smiod if (e->input_indx == -1)
5623d8817e4Smiod break;
5633d8817e4Smiod if (e)
5643d8817e4Smiod {
5653d8817e4Smiod elf_section_data (dynsymsec->output_section)->this_hdr.sh_info
5663d8817e4Smiod = e->dynindx;
5673d8817e4Smiod }
5683d8817e4Smiod }
5693d8817e4Smiod
5703d8817e4Smiod if (info->strip == strip_all)
5713d8817e4Smiod return TRUE;
5723d8817e4Smiod
5733d8817e4Smiod for (reg = 0; reg < 4; reg++)
5743d8817e4Smiod if (app_regs [reg].name != NULL)
5753d8817e4Smiod {
5763d8817e4Smiod if (info->strip == strip_some
5773d8817e4Smiod && bfd_hash_lookup (info->keep_hash,
5783d8817e4Smiod app_regs [reg].name,
5793d8817e4Smiod FALSE, FALSE) == NULL)
5803d8817e4Smiod continue;
5813d8817e4Smiod
5823d8817e4Smiod sym.st_value = reg < 2 ? reg + 2 : reg + 4;
5833d8817e4Smiod sym.st_size = 0;
5843d8817e4Smiod sym.st_other = 0;
5853d8817e4Smiod sym.st_info = ELF_ST_INFO (app_regs [reg].bind, STT_REGISTER);
5863d8817e4Smiod sym.st_shndx = app_regs [reg].shndx;
5873d8817e4Smiod if (! (*func) (finfo, app_regs [reg].name, &sym,
5883d8817e4Smiod sym.st_shndx == SHN_ABS
5893d8817e4Smiod ? bfd_abs_section_ptr : bfd_und_section_ptr,
5903d8817e4Smiod NULL))
5913d8817e4Smiod return FALSE;
5923d8817e4Smiod }
5933d8817e4Smiod
5943d8817e4Smiod return TRUE;
5953d8817e4Smiod }
5963d8817e4Smiod
5973d8817e4Smiod static int
elf64_sparc_get_symbol_type(Elf_Internal_Sym * elf_sym,int type)5983d8817e4Smiod elf64_sparc_get_symbol_type (Elf_Internal_Sym *elf_sym, int type)
5993d8817e4Smiod {
6003d8817e4Smiod if (ELF_ST_TYPE (elf_sym->st_info) == STT_REGISTER)
6013d8817e4Smiod return STT_REGISTER;
6023d8817e4Smiod else
6033d8817e4Smiod return type;
6043d8817e4Smiod }
6053d8817e4Smiod
6063d8817e4Smiod /* A STB_GLOBAL,STT_REGISTER symbol should be BSF_GLOBAL
6073d8817e4Smiod even in SHN_UNDEF section. */
6083d8817e4Smiod
6093d8817e4Smiod static void
elf64_sparc_symbol_processing(bfd * abfd ATTRIBUTE_UNUSED,asymbol * asym)6103d8817e4Smiod elf64_sparc_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED, asymbol *asym)
6113d8817e4Smiod {
6123d8817e4Smiod elf_symbol_type *elfsym;
6133d8817e4Smiod
6143d8817e4Smiod elfsym = (elf_symbol_type *) asym;
6153d8817e4Smiod if (elfsym->internal_elf_sym.st_info
6163d8817e4Smiod == ELF_ST_INFO (STB_GLOBAL, STT_REGISTER))
6173d8817e4Smiod {
6183d8817e4Smiod asym->flags |= BSF_GLOBAL;
6193d8817e4Smiod }
6203d8817e4Smiod }
6213d8817e4Smiod
6223d8817e4Smiod
6233d8817e4Smiod /* Functions for dealing with the e_flags field. */
6243d8817e4Smiod
6253d8817e4Smiod /* Merge backend specific data from an object file to the output
6263d8817e4Smiod object file when linking. */
6273d8817e4Smiod
6283d8817e4Smiod static bfd_boolean
elf64_sparc_merge_private_bfd_data(bfd * ibfd,bfd * obfd)6293d8817e4Smiod elf64_sparc_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
6303d8817e4Smiod {
6313d8817e4Smiod bfd_boolean error;
6323d8817e4Smiod flagword new_flags, old_flags;
6333d8817e4Smiod int new_mm, old_mm;
6343d8817e4Smiod
6353d8817e4Smiod if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
6363d8817e4Smiod || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
6373d8817e4Smiod return TRUE;
6383d8817e4Smiod
6393d8817e4Smiod new_flags = elf_elfheader (ibfd)->e_flags;
6403d8817e4Smiod old_flags = elf_elfheader (obfd)->e_flags;
6413d8817e4Smiod
6423d8817e4Smiod if (!elf_flags_init (obfd)) /* First call, no flags set */
6433d8817e4Smiod {
6443d8817e4Smiod elf_flags_init (obfd) = TRUE;
6453d8817e4Smiod elf_elfheader (obfd)->e_flags = new_flags;
6463d8817e4Smiod }
6473d8817e4Smiod
6483d8817e4Smiod else if (new_flags == old_flags) /* Compatible flags are ok */
6493d8817e4Smiod ;
6503d8817e4Smiod
6513d8817e4Smiod else /* Incompatible flags */
6523d8817e4Smiod {
6533d8817e4Smiod error = FALSE;
6543d8817e4Smiod
6553d8817e4Smiod #define EF_SPARC_ISA_EXTENSIONS \
6563d8817e4Smiod (EF_SPARC_SUN_US1 | EF_SPARC_SUN_US3 | EF_SPARC_HAL_R1)
6573d8817e4Smiod
6583d8817e4Smiod if ((ibfd->flags & DYNAMIC) != 0)
6593d8817e4Smiod {
6603d8817e4Smiod /* We don't want dynamic objects memory ordering and
6613d8817e4Smiod architecture to have any role. That's what dynamic linker
6623d8817e4Smiod should do. */
6633d8817e4Smiod new_flags &= ~(EF_SPARCV9_MM | EF_SPARC_ISA_EXTENSIONS);
6643d8817e4Smiod new_flags |= (old_flags
6653d8817e4Smiod & (EF_SPARCV9_MM | EF_SPARC_ISA_EXTENSIONS));
6663d8817e4Smiod }
6673d8817e4Smiod else
6683d8817e4Smiod {
6693d8817e4Smiod /* Choose the highest architecture requirements. */
6703d8817e4Smiod old_flags |= (new_flags & EF_SPARC_ISA_EXTENSIONS);
6713d8817e4Smiod new_flags |= (old_flags & EF_SPARC_ISA_EXTENSIONS);
6723d8817e4Smiod if ((old_flags & (EF_SPARC_SUN_US1 | EF_SPARC_SUN_US3))
6733d8817e4Smiod && (old_flags & EF_SPARC_HAL_R1))
6743d8817e4Smiod {
6753d8817e4Smiod error = TRUE;
6763d8817e4Smiod (*_bfd_error_handler)
6773d8817e4Smiod (_("%B: linking UltraSPARC specific with HAL specific code"),
6783d8817e4Smiod ibfd);
6793d8817e4Smiod }
6803d8817e4Smiod /* Choose the most restrictive memory ordering. */
6813d8817e4Smiod old_mm = (old_flags & EF_SPARCV9_MM);
6823d8817e4Smiod new_mm = (new_flags & EF_SPARCV9_MM);
6833d8817e4Smiod old_flags &= ~EF_SPARCV9_MM;
6843d8817e4Smiod new_flags &= ~EF_SPARCV9_MM;
6853d8817e4Smiod if (new_mm < old_mm)
6863d8817e4Smiod old_mm = new_mm;
6873d8817e4Smiod old_flags |= old_mm;
6883d8817e4Smiod new_flags |= old_mm;
6893d8817e4Smiod }
6903d8817e4Smiod
6913d8817e4Smiod /* Warn about any other mismatches */
6923d8817e4Smiod if (new_flags != old_flags)
6933d8817e4Smiod {
6943d8817e4Smiod error = TRUE;
6953d8817e4Smiod (*_bfd_error_handler)
6963d8817e4Smiod (_("%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
6973d8817e4Smiod ibfd, (long) new_flags, (long) old_flags);
6983d8817e4Smiod }
6993d8817e4Smiod
7003d8817e4Smiod elf_elfheader (obfd)->e_flags = old_flags;
7013d8817e4Smiod
7023d8817e4Smiod if (error)
7033d8817e4Smiod {
7043d8817e4Smiod bfd_set_error (bfd_error_bad_value);
7053d8817e4Smiod return FALSE;
7063d8817e4Smiod }
7073d8817e4Smiod }
7083d8817e4Smiod return TRUE;
7093d8817e4Smiod }
7103d8817e4Smiod
7113d8817e4Smiod /* MARCO: Set the correct entry size for the .stab section. */
7123d8817e4Smiod
7133d8817e4Smiod static bfd_boolean
elf64_sparc_fake_sections(bfd * abfd ATTRIBUTE_UNUSED,Elf_Internal_Shdr * hdr ATTRIBUTE_UNUSED,asection * sec)7143d8817e4Smiod elf64_sparc_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
7153d8817e4Smiod Elf_Internal_Shdr *hdr ATTRIBUTE_UNUSED,
7163d8817e4Smiod asection *sec)
7173d8817e4Smiod {
7183d8817e4Smiod const char *name;
7193d8817e4Smiod
7203d8817e4Smiod name = bfd_get_section_name (abfd, sec);
7213d8817e4Smiod
7223d8817e4Smiod if (strcmp (name, ".stab") == 0)
7233d8817e4Smiod {
7243d8817e4Smiod /* Even in the 64bit case the stab entries are only 12 bytes long. */
7253d8817e4Smiod elf_section_data (sec)->this_hdr.sh_entsize = 12;
7263d8817e4Smiod }
7273d8817e4Smiod
7283d8817e4Smiod return TRUE;
7293d8817e4Smiod }
7303d8817e4Smiod
7313d8817e4Smiod /* Print a STT_REGISTER symbol to file FILE. */
7323d8817e4Smiod
7333d8817e4Smiod static const char *
elf64_sparc_print_symbol_all(bfd * abfd ATTRIBUTE_UNUSED,PTR filep,asymbol * symbol)7343d8817e4Smiod elf64_sparc_print_symbol_all (bfd *abfd ATTRIBUTE_UNUSED, PTR filep,
7353d8817e4Smiod asymbol *symbol)
7363d8817e4Smiod {
7373d8817e4Smiod FILE *file = (FILE *) filep;
7383d8817e4Smiod int reg, type;
7393d8817e4Smiod
7403d8817e4Smiod if (ELF_ST_TYPE (((elf_symbol_type *) symbol)->internal_elf_sym.st_info)
7413d8817e4Smiod != STT_REGISTER)
7423d8817e4Smiod return NULL;
7433d8817e4Smiod
7443d8817e4Smiod reg = ((elf_symbol_type *) symbol)->internal_elf_sym.st_value;
7453d8817e4Smiod type = symbol->flags;
7463d8817e4Smiod fprintf (file, "REG_%c%c%11s%c%c R", "GOLI" [reg / 8], '0' + (reg & 7), "",
7473d8817e4Smiod ((type & BSF_LOCAL)
7483d8817e4Smiod ? (type & BSF_GLOBAL) ? '!' : 'l'
7493d8817e4Smiod : (type & BSF_GLOBAL) ? 'g' : ' '),
7503d8817e4Smiod (type & BSF_WEAK) ? 'w' : ' ');
7513d8817e4Smiod if (symbol->name == NULL || symbol->name [0] == '\0')
7523d8817e4Smiod return "#scratch";
7533d8817e4Smiod else
7543d8817e4Smiod return symbol->name;
7553d8817e4Smiod }
7563d8817e4Smiod
7573d8817e4Smiod static enum elf_reloc_type_class
elf64_sparc_reloc_type_class(const Elf_Internal_Rela * rela)7583d8817e4Smiod elf64_sparc_reloc_type_class (const Elf_Internal_Rela *rela)
7593d8817e4Smiod {
7603d8817e4Smiod switch ((int) ELF64_R_TYPE (rela->r_info))
7613d8817e4Smiod {
7623d8817e4Smiod case R_SPARC_RELATIVE:
7633d8817e4Smiod return reloc_class_relative;
7643d8817e4Smiod case R_SPARC_JMP_SLOT:
7653d8817e4Smiod return reloc_class_plt;
7663d8817e4Smiod case R_SPARC_COPY:
7673d8817e4Smiod return reloc_class_copy;
7683d8817e4Smiod default:
7693d8817e4Smiod return reloc_class_normal;
7703d8817e4Smiod }
7713d8817e4Smiod }
7723d8817e4Smiod
7733d8817e4Smiod /* Relocations in the 64 bit SPARC ELF ABI are more complex than in
7743d8817e4Smiod standard ELF, because R_SPARC_OLO10 has secondary addend in
7753d8817e4Smiod ELF64_R_TYPE_DATA field. This structure is used to redirect the
7763d8817e4Smiod relocation handling routines. */
7773d8817e4Smiod
7783d8817e4Smiod const struct elf_size_info elf64_sparc_size_info =
7793d8817e4Smiod {
7803d8817e4Smiod sizeof (Elf64_External_Ehdr),
7813d8817e4Smiod sizeof (Elf64_External_Phdr),
7823d8817e4Smiod sizeof (Elf64_External_Shdr),
7833d8817e4Smiod sizeof (Elf64_External_Rel),
7843d8817e4Smiod sizeof (Elf64_External_Rela),
7853d8817e4Smiod sizeof (Elf64_External_Sym),
7863d8817e4Smiod sizeof (Elf64_External_Dyn),
7873d8817e4Smiod sizeof (Elf_External_Note),
7883d8817e4Smiod 4, /* hash-table entry size. */
7893d8817e4Smiod /* Internal relocations per external relocations.
7903d8817e4Smiod For link purposes we use just 1 internal per
7913d8817e4Smiod 1 external, for assembly and slurp symbol table
7923d8817e4Smiod we use 2. */
7933d8817e4Smiod 1,
7943d8817e4Smiod 64, /* arch_size. */
7953d8817e4Smiod 3, /* log_file_align. */
7963d8817e4Smiod ELFCLASS64,
7973d8817e4Smiod EV_CURRENT,
7983d8817e4Smiod bfd_elf64_write_out_phdrs,
7993d8817e4Smiod bfd_elf64_write_shdrs_and_ehdr,
8003d8817e4Smiod elf64_sparc_write_relocs,
8013d8817e4Smiod bfd_elf64_swap_symbol_in,
8023d8817e4Smiod bfd_elf64_swap_symbol_out,
8033d8817e4Smiod elf64_sparc_slurp_reloc_table,
8043d8817e4Smiod bfd_elf64_slurp_symbol_table,
8053d8817e4Smiod bfd_elf64_swap_dyn_in,
8063d8817e4Smiod bfd_elf64_swap_dyn_out,
8073d8817e4Smiod bfd_elf64_swap_reloc_in,
8083d8817e4Smiod bfd_elf64_swap_reloc_out,
8093d8817e4Smiod bfd_elf64_swap_reloca_in,
8103d8817e4Smiod bfd_elf64_swap_reloca_out
8113d8817e4Smiod };
8123d8817e4Smiod
8133d8817e4Smiod #define TARGET_BIG_SYM bfd_elf64_sparc_vec
8143d8817e4Smiod #define TARGET_BIG_NAME "elf64-sparc"
8153d8817e4Smiod #define ELF_ARCH bfd_arch_sparc
8163d8817e4Smiod #define ELF_MAXPAGESIZE 0x100000
8173d8817e4Smiod
8183d8817e4Smiod /* This is the official ABI value. */
8193d8817e4Smiod #define ELF_MACHINE_CODE EM_SPARCV9
8203d8817e4Smiod
8213d8817e4Smiod /* This is the value that we used before the ABI was released. */
8223d8817e4Smiod #define ELF_MACHINE_ALT1 EM_OLD_SPARCV9
8233d8817e4Smiod
8243d8817e4Smiod #define elf_backend_reloc_type_class \
8253d8817e4Smiod elf64_sparc_reloc_type_class
8263d8817e4Smiod #define bfd_elf64_get_reloc_upper_bound \
8273d8817e4Smiod elf64_sparc_get_reloc_upper_bound
8283d8817e4Smiod #define bfd_elf64_get_dynamic_reloc_upper_bound \
8293d8817e4Smiod elf64_sparc_get_dynamic_reloc_upper_bound
8303d8817e4Smiod #define bfd_elf64_canonicalize_reloc \
8313d8817e4Smiod elf64_sparc_canonicalize_reloc
8323d8817e4Smiod #define bfd_elf64_canonicalize_dynamic_reloc \
8333d8817e4Smiod elf64_sparc_canonicalize_dynamic_reloc
8343d8817e4Smiod #define elf_backend_add_symbol_hook \
8353d8817e4Smiod elf64_sparc_add_symbol_hook
8363d8817e4Smiod #define elf_backend_get_symbol_type \
8373d8817e4Smiod elf64_sparc_get_symbol_type
8383d8817e4Smiod #define elf_backend_symbol_processing \
8393d8817e4Smiod elf64_sparc_symbol_processing
8403d8817e4Smiod #define elf_backend_print_symbol_all \
8413d8817e4Smiod elf64_sparc_print_symbol_all
8423d8817e4Smiod #define elf_backend_output_arch_syms \
8433d8817e4Smiod elf64_sparc_output_arch_syms
8443d8817e4Smiod #define bfd_elf64_bfd_merge_private_bfd_data \
8453d8817e4Smiod elf64_sparc_merge_private_bfd_data
8463d8817e4Smiod #define elf_backend_fake_sections \
8473d8817e4Smiod elf64_sparc_fake_sections
8483d8817e4Smiod #define elf_backend_size_info \
8493d8817e4Smiod elf64_sparc_size_info
8503d8817e4Smiod
8513d8817e4Smiod #define elf_backend_plt_sym_val \
8523d8817e4Smiod _bfd_sparc_elf_plt_sym_val
8533d8817e4Smiod #define bfd_elf64_bfd_link_hash_table_create \
8543d8817e4Smiod _bfd_sparc_elf_link_hash_table_create
8553d8817e4Smiod #define elf_info_to_howto \
8563d8817e4Smiod _bfd_sparc_elf_info_to_howto
8573d8817e4Smiod #define elf_backend_copy_indirect_symbol \
8583d8817e4Smiod _bfd_sparc_elf_copy_indirect_symbol
8593d8817e4Smiod #define bfd_elf64_bfd_reloc_type_lookup \
8603d8817e4Smiod _bfd_sparc_elf_reloc_type_lookup
8613d8817e4Smiod #define bfd_elf64_bfd_relax_section \
8623d8817e4Smiod _bfd_sparc_elf_relax_section
8633d8817e4Smiod #define bfd_elf64_new_section_hook \
8643d8817e4Smiod _bfd_sparc_elf_new_section_hook
8653d8817e4Smiod
8663d8817e4Smiod #define elf_backend_create_dynamic_sections \
8673d8817e4Smiod _bfd_sparc_elf_create_dynamic_sections
8683d8817e4Smiod #define elf_backend_check_relocs \
8693d8817e4Smiod _bfd_sparc_elf_check_relocs
8703d8817e4Smiod #define elf_backend_adjust_dynamic_symbol \
8713d8817e4Smiod _bfd_sparc_elf_adjust_dynamic_symbol
8723d8817e4Smiod #define elf_backend_omit_section_dynsym \
8733d8817e4Smiod _bfd_sparc_elf_omit_section_dynsym
8743d8817e4Smiod #define elf_backend_size_dynamic_sections \
8753d8817e4Smiod _bfd_sparc_elf_size_dynamic_sections
8763d8817e4Smiod #define elf_backend_relocate_section \
8773d8817e4Smiod _bfd_sparc_elf_relocate_section
8783d8817e4Smiod #define elf_backend_finish_dynamic_symbol \
8793d8817e4Smiod _bfd_sparc_elf_finish_dynamic_symbol
8803d8817e4Smiod #define elf_backend_finish_dynamic_sections \
8813d8817e4Smiod _bfd_sparc_elf_finish_dynamic_sections
8823d8817e4Smiod
8833d8817e4Smiod #define bfd_elf64_mkobject \
8843d8817e4Smiod _bfd_sparc_elf_mkobject
8853d8817e4Smiod #define elf_backend_object_p \
8863d8817e4Smiod _bfd_sparc_elf_object_p
8873d8817e4Smiod #define elf_backend_gc_mark_hook \
8883d8817e4Smiod _bfd_sparc_elf_gc_mark_hook
8893d8817e4Smiod #define elf_backend_gc_sweep_hook \
8903d8817e4Smiod _bfd_sparc_elf_gc_sweep_hook
8913d8817e4Smiod
8923d8817e4Smiod #define elf_backend_can_gc_sections 1
8933d8817e4Smiod #define elf_backend_can_refcount 1
8943d8817e4Smiod #define elf_backend_want_got_plt 0
895*4f14f31bSkettenis #define elf_backend_plt_readonly 0
8963d8817e4Smiod #define elf_backend_want_plt_sym 1
8973d8817e4Smiod #define elf_backend_got_header_size 8
8983d8817e4Smiod #define elf_backend_rela_normal 1
8993d8817e4Smiod
9003d8817e4Smiod /* Section 5.2.4 of the ABI specifies a 256-byte boundary for the table. */
9013d8817e4Smiod #define elf_backend_plt_alignment 8
9023d8817e4Smiod
9033d8817e4Smiod #include "elf64-target.h"
904