xref: /netbsd/external/gpl3/gdb/dist/bfd/elf64-sparc.c (revision 1424dfb3)
1377e23a2Schristos /* SPARC-specific support for 64-bit ELF
2*1424dfb3Schristos    Copyright (C) 1993-2020 Free Software Foundation, Inc.
3377e23a2Schristos 
4377e23a2Schristos    This file is part of BFD, the Binary File Descriptor library.
5377e23a2Schristos 
6377e23a2Schristos    This program is free software; you can redistribute it and/or modify
7377e23a2Schristos    it under the terms of the GNU General Public License as published by
8377e23a2Schristos    the Free Software Foundation; either version 3 of the License, or
9377e23a2Schristos    (at your option) any later version.
10377e23a2Schristos 
11377e23a2Schristos    This program is distributed in the hope that it will be useful,
12377e23a2Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
13377e23a2Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14377e23a2Schristos    GNU General Public License for more details.
15377e23a2Schristos 
16377e23a2Schristos    You should have received a copy of the GNU General Public License
17377e23a2Schristos    along with this program; if not, write to the Free Software
18377e23a2Schristos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19377e23a2Schristos    MA 02110-1301, USA.  */
20377e23a2Schristos 
21377e23a2Schristos #include "sysdep.h"
22*1424dfb3Schristos #include <limits.h>
23377e23a2Schristos #include "bfd.h"
24377e23a2Schristos #include "libbfd.h"
25377e23a2Schristos #include "elf-bfd.h"
26377e23a2Schristos #include "elf/sparc.h"
27377e23a2Schristos #include "opcode/sparc.h"
28377e23a2Schristos #include "elfxx-sparc.h"
29377e23a2Schristos 
30377e23a2Schristos /* In case we're on a 32-bit machine, construct a 64-bit "-1" value.  */
31377e23a2Schristos #define MINUS_ONE (~ (bfd_vma) 0)
32377e23a2Schristos 
33377e23a2Schristos /* Due to the way how we handle R_SPARC_OLO10, each entry in a SHT_RELA
34377e23a2Schristos    section can represent up to two relocs, we must tell the user to allocate
35377e23a2Schristos    more space.  */
36377e23a2Schristos 
37377e23a2Schristos static long
elf64_sparc_get_reloc_upper_bound(bfd * abfd ATTRIBUTE_UNUSED,asection * sec)38377e23a2Schristos elf64_sparc_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
39377e23a2Schristos {
40*1424dfb3Schristos #if SIZEOF_LONG == SIZEOF_INT
41*1424dfb3Schristos   if (sec->reloc_count >= LONG_MAX / 2 / sizeof (arelent *))
42*1424dfb3Schristos     {
43*1424dfb3Schristos       bfd_set_error (bfd_error_file_too_big);
44*1424dfb3Schristos       return -1;
45*1424dfb3Schristos     }
46*1424dfb3Schristos #endif
47377e23a2Schristos   return (sec->reloc_count * 2 + 1) * sizeof (arelent *);
48377e23a2Schristos }
49377e23a2Schristos 
50377e23a2Schristos static long
elf64_sparc_get_dynamic_reloc_upper_bound(bfd * abfd)51377e23a2Schristos elf64_sparc_get_dynamic_reloc_upper_bound (bfd *abfd)
52377e23a2Schristos {
53*1424dfb3Schristos   long ret = _bfd_elf_get_dynamic_reloc_upper_bound (abfd);
54*1424dfb3Schristos   if (ret > LONG_MAX / 2)
55*1424dfb3Schristos     {
56*1424dfb3Schristos       bfd_set_error (bfd_error_file_too_big);
57*1424dfb3Schristos       ret = -1;
58*1424dfb3Schristos     }
59*1424dfb3Schristos   else if (ret > 0)
60*1424dfb3Schristos     ret *= 2;
61*1424dfb3Schristos   return ret;
62377e23a2Schristos }
63377e23a2Schristos 
64377e23a2Schristos /* Read  relocations for ASECT from REL_HDR.  There are RELOC_COUNT of
65377e23a2Schristos    them.  We cannot use generic elf routines for this,  because R_SPARC_OLO10
66377e23a2Schristos    has secondary addend in ELF64_R_TYPE_DATA.  We handle it as two relocations
67377e23a2Schristos    for the same location,  R_SPARC_LO10 and R_SPARC_13.  */
68377e23a2Schristos 
69377e23a2Schristos static bfd_boolean
elf64_sparc_slurp_one_reloc_table(bfd * abfd,asection * asect,Elf_Internal_Shdr * rel_hdr,asymbol ** symbols,bfd_boolean dynamic)70377e23a2Schristos elf64_sparc_slurp_one_reloc_table (bfd *abfd, asection *asect,
71377e23a2Schristos 				   Elf_Internal_Shdr *rel_hdr,
72377e23a2Schristos 				   asymbol **symbols, bfd_boolean dynamic)
73377e23a2Schristos {
7448596154Schristos   void * allocated = NULL;
75377e23a2Schristos   bfd_byte *native_relocs;
76377e23a2Schristos   arelent *relent;
77377e23a2Schristos   unsigned int i;
78377e23a2Schristos   int entsize;
79377e23a2Schristos   bfd_size_type count;
80377e23a2Schristos   arelent *relents;
81377e23a2Schristos 
82*1424dfb3Schristos   if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0)
83*1424dfb3Schristos     return FALSE;
84*1424dfb3Schristos   allocated = _bfd_malloc_and_read (abfd, rel_hdr->sh_size, rel_hdr->sh_size);
85377e23a2Schristos   if (allocated == NULL)
86*1424dfb3Schristos     return FALSE;
87377e23a2Schristos 
88377e23a2Schristos   native_relocs = (bfd_byte *) allocated;
89377e23a2Schristos 
90377e23a2Schristos   relents = asect->relocation + canon_reloc_count (asect);
91377e23a2Schristos 
92377e23a2Schristos   entsize = rel_hdr->sh_entsize;
93377e23a2Schristos   BFD_ASSERT (entsize == sizeof (Elf64_External_Rela));
94377e23a2Schristos 
95377e23a2Schristos   count = rel_hdr->sh_size / entsize;
96377e23a2Schristos 
97377e23a2Schristos   for (i = 0, relent = relents; i < count;
98377e23a2Schristos        i++, relent++, native_relocs += entsize)
99377e23a2Schristos     {
100377e23a2Schristos       Elf_Internal_Rela rela;
101377e23a2Schristos       unsigned int r_type;
102377e23a2Schristos 
103377e23a2Schristos       bfd_elf64_swap_reloca_in (abfd, native_relocs, &rela);
104377e23a2Schristos 
105377e23a2Schristos       /* The address of an ELF reloc is section relative for an object
106377e23a2Schristos 	 file, and absolute for an executable file or shared library.
107377e23a2Schristos 	 The address of a normal BFD reloc is always section relative,
108377e23a2Schristos 	 and the address of a dynamic reloc is absolute..  */
109377e23a2Schristos       if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
110377e23a2Schristos 	relent->address = rela.r_offset;
111377e23a2Schristos       else
112377e23a2Schristos 	relent->address = rela.r_offset - asect->vma;
113377e23a2Schristos 
11407163879Schristos       if (ELF64_R_SYM (rela.r_info) == STN_UNDEF)
11507163879Schristos 	relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
11607163879Schristos       else if (/* PR 17512: file: 996185f8.  */
117*1424dfb3Schristos 	       ELF64_R_SYM (rela.r_info) > (dynamic
118*1424dfb3Schristos 					    ? bfd_get_dynamic_symcount (abfd)
119*1424dfb3Schristos 					    : bfd_get_symcount (abfd)))
12007163879Schristos 	{
12107163879Schristos 	  _bfd_error_handler
12207163879Schristos 	    /* xgettext:c-format */
12307163879Schristos 	    (_("%pB(%pA): relocation %d has invalid symbol index %ld"),
12407163879Schristos 	     abfd, asect, i, (long) ELF64_R_SYM (rela.r_info));
12507163879Schristos 	  bfd_set_error (bfd_error_bad_value);
126377e23a2Schristos 	  relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
12707163879Schristos 	}
128377e23a2Schristos       else
129377e23a2Schristos 	{
130377e23a2Schristos 	  asymbol **ps, *s;
131377e23a2Schristos 
132377e23a2Schristos 	  ps = symbols + ELF64_R_SYM (rela.r_info) - 1;
133377e23a2Schristos 	  s = *ps;
134377e23a2Schristos 
135377e23a2Schristos 	  /* Canonicalize ELF section symbols.  FIXME: Why?  */
136377e23a2Schristos 	  if ((s->flags & BSF_SECTION_SYM) == 0)
137377e23a2Schristos 	    relent->sym_ptr_ptr = ps;
138377e23a2Schristos 	  else
139377e23a2Schristos 	    relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
140377e23a2Schristos 	}
141377e23a2Schristos 
142377e23a2Schristos       relent->addend = rela.r_addend;
143377e23a2Schristos 
144377e23a2Schristos       r_type = ELF64_R_TYPE_ID (rela.r_info);
145377e23a2Schristos       if (r_type == R_SPARC_OLO10)
146377e23a2Schristos 	{
14707163879Schristos 	  relent->howto = _bfd_sparc_elf_info_to_howto_ptr (abfd, R_SPARC_LO10);
148377e23a2Schristos 	  relent[1].address = relent->address;
149377e23a2Schristos 	  relent++;
150377e23a2Schristos 	  relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
151377e23a2Schristos 	  relent->addend = ELF64_R_TYPE_DATA (rela.r_info);
15207163879Schristos 	  relent->howto = _bfd_sparc_elf_info_to_howto_ptr (abfd, R_SPARC_13);
153377e23a2Schristos 	}
154377e23a2Schristos       else
15507163879Schristos 	{
15607163879Schristos 	  relent->howto = _bfd_sparc_elf_info_to_howto_ptr (abfd, r_type);
15707163879Schristos 	  if (relent->howto == NULL)
15807163879Schristos 	    goto error_return;
15907163879Schristos 	}
160377e23a2Schristos     }
161377e23a2Schristos 
162377e23a2Schristos   canon_reloc_count (asect) += relent - relents;
163377e23a2Schristos 
164377e23a2Schristos   free (allocated);
165377e23a2Schristos   return TRUE;
166377e23a2Schristos 
167377e23a2Schristos  error_return:
168377e23a2Schristos   free (allocated);
169377e23a2Schristos   return FALSE;
170377e23a2Schristos }
171377e23a2Schristos 
172377e23a2Schristos /* Read in and swap the external relocs.  */
173377e23a2Schristos 
174377e23a2Schristos static bfd_boolean
elf64_sparc_slurp_reloc_table(bfd * abfd,asection * asect,asymbol ** symbols,bfd_boolean dynamic)175377e23a2Schristos elf64_sparc_slurp_reloc_table (bfd *abfd, asection *asect,
176377e23a2Schristos 			       asymbol **symbols, bfd_boolean dynamic)
177377e23a2Schristos {
178377e23a2Schristos   struct bfd_elf_section_data * const d = elf_section_data (asect);
179377e23a2Schristos   Elf_Internal_Shdr *rel_hdr;
180377e23a2Schristos   Elf_Internal_Shdr *rel_hdr2;
181377e23a2Schristos   bfd_size_type amt;
182377e23a2Schristos 
183377e23a2Schristos   if (asect->relocation != NULL)
184377e23a2Schristos     return TRUE;
185377e23a2Schristos 
186377e23a2Schristos   if (! dynamic)
187377e23a2Schristos     {
188377e23a2Schristos       if ((asect->flags & SEC_RELOC) == 0
189377e23a2Schristos 	  || asect->reloc_count == 0)
190377e23a2Schristos 	return TRUE;
191377e23a2Schristos 
192377e23a2Schristos       rel_hdr = d->rel.hdr;
193377e23a2Schristos       rel_hdr2 = d->rela.hdr;
194377e23a2Schristos 
195377e23a2Schristos       BFD_ASSERT ((rel_hdr && asect->rel_filepos == rel_hdr->sh_offset)
196377e23a2Schristos 		  || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
197377e23a2Schristos     }
198377e23a2Schristos   else
199377e23a2Schristos     {
200377e23a2Schristos       /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
201377e23a2Schristos 	 case because relocations against this section may use the
202377e23a2Schristos 	 dynamic symbol table, and in that case bfd_section_from_shdr
203377e23a2Schristos 	 in elf.c does not update the RELOC_COUNT.  */
204377e23a2Schristos       if (asect->size == 0)
205377e23a2Schristos 	return TRUE;
206377e23a2Schristos 
207377e23a2Schristos       rel_hdr = &d->this_hdr;
208377e23a2Schristos       asect->reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
209377e23a2Schristos       rel_hdr2 = NULL;
210377e23a2Schristos     }
211377e23a2Schristos 
212377e23a2Schristos   amt = asect->reloc_count;
213377e23a2Schristos   amt *= 2 * sizeof (arelent);
214377e23a2Schristos   asect->relocation = (arelent *) bfd_alloc (abfd, amt);
215377e23a2Schristos   if (asect->relocation == NULL)
216377e23a2Schristos     return FALSE;
217377e23a2Schristos 
218377e23a2Schristos   /* The elf64_sparc_slurp_one_reloc_table routine increments
219377e23a2Schristos      canon_reloc_count.  */
220377e23a2Schristos   canon_reloc_count (asect) = 0;
221377e23a2Schristos 
222377e23a2Schristos   if (rel_hdr
223377e23a2Schristos       && !elf64_sparc_slurp_one_reloc_table (abfd, asect, rel_hdr, symbols,
224377e23a2Schristos 					     dynamic))
225377e23a2Schristos     return FALSE;
226377e23a2Schristos 
227377e23a2Schristos   if (rel_hdr2
228377e23a2Schristos       && !elf64_sparc_slurp_one_reloc_table (abfd, asect, rel_hdr2, symbols,
229377e23a2Schristos 					     dynamic))
230377e23a2Schristos     return FALSE;
231377e23a2Schristos 
232377e23a2Schristos   return TRUE;
233377e23a2Schristos }
234377e23a2Schristos 
235377e23a2Schristos /* Canonicalize the relocs.  */
236377e23a2Schristos 
237377e23a2Schristos static long
elf64_sparc_canonicalize_reloc(bfd * abfd,sec_ptr section,arelent ** relptr,asymbol ** symbols)238377e23a2Schristos elf64_sparc_canonicalize_reloc (bfd *abfd, sec_ptr section,
239377e23a2Schristos 				arelent **relptr, asymbol **symbols)
240377e23a2Schristos {
241377e23a2Schristos   arelent *tblptr;
242377e23a2Schristos   unsigned int i;
243377e23a2Schristos   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
244377e23a2Schristos 
245377e23a2Schristos   if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
246377e23a2Schristos     return -1;
247377e23a2Schristos 
248377e23a2Schristos   tblptr = section->relocation;
249377e23a2Schristos   for (i = 0; i < canon_reloc_count (section); i++)
250377e23a2Schristos     *relptr++ = tblptr++;
251377e23a2Schristos 
252377e23a2Schristos   *relptr = NULL;
253377e23a2Schristos 
254377e23a2Schristos   return canon_reloc_count (section);
255377e23a2Schristos }
256377e23a2Schristos 
257377e23a2Schristos 
258377e23a2Schristos /* Canonicalize the dynamic relocation entries.  Note that we return
259377e23a2Schristos    the dynamic relocations as a single block, although they are
260377e23a2Schristos    actually associated with particular sections; the interface, which
261377e23a2Schristos    was designed for SunOS style shared libraries, expects that there
262377e23a2Schristos    is only one set of dynamic relocs.  Any section that was actually
263377e23a2Schristos    installed in the BFD, and has type SHT_REL or SHT_RELA, and uses
264377e23a2Schristos    the dynamic symbol table, is considered to be a dynamic reloc
265377e23a2Schristos    section.  */
266377e23a2Schristos 
267377e23a2Schristos static long
elf64_sparc_canonicalize_dynamic_reloc(bfd * abfd,arelent ** storage,asymbol ** syms)268377e23a2Schristos elf64_sparc_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage,
269377e23a2Schristos 					asymbol **syms)
270377e23a2Schristos {
271377e23a2Schristos   asection *s;
272377e23a2Schristos   long ret;
273377e23a2Schristos 
274377e23a2Schristos   if (elf_dynsymtab (abfd) == 0)
275377e23a2Schristos     {
276377e23a2Schristos       bfd_set_error (bfd_error_invalid_operation);
277377e23a2Schristos       return -1;
278377e23a2Schristos     }
279377e23a2Schristos 
280377e23a2Schristos   ret = 0;
281377e23a2Schristos   for (s = abfd->sections; s != NULL; s = s->next)
282377e23a2Schristos     {
283377e23a2Schristos       if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
284377e23a2Schristos 	  && (elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
285377e23a2Schristos 	{
286377e23a2Schristos 	  arelent *p;
287377e23a2Schristos 	  long count, i;
288377e23a2Schristos 
289377e23a2Schristos 	  if (! elf64_sparc_slurp_reloc_table (abfd, s, syms, TRUE))
290377e23a2Schristos 	    return -1;
291377e23a2Schristos 	  count = canon_reloc_count (s);
292377e23a2Schristos 	  p = s->relocation;
293377e23a2Schristos 	  for (i = 0; i < count; i++)
294377e23a2Schristos 	    *storage++ = p++;
295377e23a2Schristos 	  ret += count;
296377e23a2Schristos 	}
297377e23a2Schristos     }
298377e23a2Schristos 
299377e23a2Schristos   *storage = NULL;
300377e23a2Schristos 
301377e23a2Schristos   return ret;
302377e23a2Schristos }
303377e23a2Schristos 
30407163879Schristos /* Install a new set of internal relocs.  */
30507163879Schristos 
30607163879Schristos static void
elf64_sparc_set_reloc(bfd * abfd ATTRIBUTE_UNUSED,asection * asect,arelent ** location,unsigned int count)30707163879Schristos elf64_sparc_set_reloc (bfd *abfd ATTRIBUTE_UNUSED,
30807163879Schristos 		       asection *asect,
30907163879Schristos 		       arelent **location,
31007163879Schristos 		       unsigned int count)
31107163879Schristos {
31207163879Schristos   asect->orelocation = location;
31307163879Schristos   canon_reloc_count (asect) = count;
31407163879Schristos }
31507163879Schristos 
316377e23a2Schristos /* Write out the relocs.  */
317377e23a2Schristos 
318377e23a2Schristos static void
elf64_sparc_write_relocs(bfd * abfd,asection * sec,void * data)31948596154Schristos elf64_sparc_write_relocs (bfd *abfd, asection *sec, void * data)
320377e23a2Schristos {
321377e23a2Schristos   bfd_boolean *failedp = (bfd_boolean *) data;
322377e23a2Schristos   Elf_Internal_Shdr *rela_hdr;
323377e23a2Schristos   bfd_vma addr_offset;
324377e23a2Schristos   Elf64_External_Rela *outbound_relocas, *src_rela;
325377e23a2Schristos   unsigned int idx, count;
326377e23a2Schristos   asymbol *last_sym = 0;
327377e23a2Schristos   int last_sym_idx = 0;
328377e23a2Schristos 
329377e23a2Schristos   /* If we have already failed, don't do anything.  */
330377e23a2Schristos   if (*failedp)
331377e23a2Schristos     return;
332377e23a2Schristos 
333377e23a2Schristos   if ((sec->flags & SEC_RELOC) == 0)
334377e23a2Schristos     return;
335377e23a2Schristos 
336377e23a2Schristos   /* The linker backend writes the relocs out itself, and sets the
337377e23a2Schristos      reloc_count field to zero to inhibit writing them here.  Also,
338377e23a2Schristos      sometimes the SEC_RELOC flag gets set even when there aren't any
339377e23a2Schristos      relocs.  */
34007163879Schristos   if (canon_reloc_count (sec) == 0)
341377e23a2Schristos     return;
342377e23a2Schristos 
343377e23a2Schristos   /* We can combine two relocs that refer to the same address
344377e23a2Schristos      into R_SPARC_OLO10 if first one is R_SPARC_LO10 and the
345377e23a2Schristos      latter is R_SPARC_13 with no associated symbol.  */
346377e23a2Schristos   count = 0;
34707163879Schristos   for (idx = 0; idx < canon_reloc_count (sec); idx++)
348377e23a2Schristos     {
349377e23a2Schristos       bfd_vma addr;
350377e23a2Schristos 
351377e23a2Schristos       ++count;
352377e23a2Schristos 
353377e23a2Schristos       addr = sec->orelocation[idx]->address;
354377e23a2Schristos       if (sec->orelocation[idx]->howto->type == R_SPARC_LO10
35507163879Schristos 	  && idx < canon_reloc_count (sec) - 1)
356377e23a2Schristos 	{
357377e23a2Schristos 	  arelent *r = sec->orelocation[idx + 1];
358377e23a2Schristos 
359377e23a2Schristos 	  if (r->howto->type == R_SPARC_13
360377e23a2Schristos 	      && r->address == addr
361377e23a2Schristos 	      && bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
362377e23a2Schristos 	      && (*r->sym_ptr_ptr)->value == 0)
363377e23a2Schristos 	    ++idx;
364377e23a2Schristos 	}
365377e23a2Schristos     }
366377e23a2Schristos 
367377e23a2Schristos   rela_hdr = elf_section_data (sec)->rela.hdr;
368377e23a2Schristos 
369377e23a2Schristos   rela_hdr->sh_size = rela_hdr->sh_entsize * count;
37048596154Schristos   rela_hdr->contents = bfd_alloc (abfd, rela_hdr->sh_size);
371377e23a2Schristos   if (rela_hdr->contents == NULL)
372377e23a2Schristos     {
373377e23a2Schristos       *failedp = TRUE;
374377e23a2Schristos       return;
375377e23a2Schristos     }
376377e23a2Schristos 
377377e23a2Schristos   /* Figure out whether the relocations are RELA or REL relocations.  */
378377e23a2Schristos   if (rela_hdr->sh_type != SHT_RELA)
379377e23a2Schristos     abort ();
380377e23a2Schristos 
381377e23a2Schristos   /* The address of an ELF reloc is section relative for an object
382377e23a2Schristos      file, and absolute for an executable file or shared library.
383377e23a2Schristos      The address of a BFD reloc is always section relative.  */
384377e23a2Schristos   addr_offset = 0;
385377e23a2Schristos   if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
386377e23a2Schristos     addr_offset = sec->vma;
387377e23a2Schristos 
388377e23a2Schristos   /* orelocation has the data, reloc_count has the count...  */
389377e23a2Schristos   outbound_relocas = (Elf64_External_Rela *) rela_hdr->contents;
390377e23a2Schristos   src_rela = outbound_relocas;
391377e23a2Schristos 
39207163879Schristos   for (idx = 0; idx < canon_reloc_count (sec); idx++)
393377e23a2Schristos     {
394377e23a2Schristos       Elf_Internal_Rela dst_rela;
395377e23a2Schristos       arelent *ptr;
396377e23a2Schristos       asymbol *sym;
397377e23a2Schristos       int n;
398377e23a2Schristos 
399377e23a2Schristos       ptr = sec->orelocation[idx];
400377e23a2Schristos       sym = *ptr->sym_ptr_ptr;
401377e23a2Schristos       if (sym == last_sym)
402377e23a2Schristos 	n = last_sym_idx;
403377e23a2Schristos       else if (bfd_is_abs_section (sym->section) && sym->value == 0)
404377e23a2Schristos 	n = STN_UNDEF;
405377e23a2Schristos       else
406377e23a2Schristos 	{
407377e23a2Schristos 	  last_sym = sym;
408377e23a2Schristos 	  n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
409377e23a2Schristos 	  if (n < 0)
410377e23a2Schristos 	    {
411377e23a2Schristos 	      *failedp = TRUE;
412377e23a2Schristos 	      return;
413377e23a2Schristos 	    }
414377e23a2Schristos 	  last_sym_idx = n;
415377e23a2Schristos 	}
416377e23a2Schristos 
417377e23a2Schristos       if ((*ptr->sym_ptr_ptr)->the_bfd != NULL
418377e23a2Schristos 	  && (*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
419377e23a2Schristos 	  && ! _bfd_elf_validate_reloc (abfd, ptr))
420377e23a2Schristos 	{
421377e23a2Schristos 	  *failedp = TRUE;
422377e23a2Schristos 	  return;
423377e23a2Schristos 	}
424377e23a2Schristos 
425377e23a2Schristos       if (ptr->howto->type == R_SPARC_LO10
42607163879Schristos 	  && idx < canon_reloc_count (sec) - 1)
427377e23a2Schristos 	{
428377e23a2Schristos 	  arelent *r = sec->orelocation[idx + 1];
429377e23a2Schristos 
430377e23a2Schristos 	  if (r->howto->type == R_SPARC_13
431377e23a2Schristos 	      && r->address == ptr->address
432377e23a2Schristos 	      && bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
433377e23a2Schristos 	      && (*r->sym_ptr_ptr)->value == 0)
434377e23a2Schristos 	    {
435377e23a2Schristos 	      idx++;
436377e23a2Schristos 	      dst_rela.r_info
437377e23a2Schristos 		= ELF64_R_INFO (n, ELF64_R_TYPE_INFO (r->addend,
438377e23a2Schristos 						      R_SPARC_OLO10));
439377e23a2Schristos 	    }
440377e23a2Schristos 	  else
441377e23a2Schristos 	    dst_rela.r_info = ELF64_R_INFO (n, R_SPARC_LO10);
442377e23a2Schristos 	}
443377e23a2Schristos       else
444377e23a2Schristos 	dst_rela.r_info = ELF64_R_INFO (n, ptr->howto->type);
445377e23a2Schristos 
446377e23a2Schristos       dst_rela.r_offset = ptr->address + addr_offset;
447377e23a2Schristos       dst_rela.r_addend = ptr->addend;
448377e23a2Schristos 
449377e23a2Schristos       bfd_elf64_swap_reloca_out (abfd, &dst_rela, (bfd_byte *) src_rela);
450377e23a2Schristos       ++src_rela;
451377e23a2Schristos     }
452377e23a2Schristos }
453377e23a2Schristos 
454377e23a2Schristos /* Hook called by the linker routine which adds symbols from an object
455377e23a2Schristos    file.  We use it for STT_REGISTER symbols.  */
456377e23a2Schristos 
457377e23a2Schristos 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)458377e23a2Schristos elf64_sparc_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
459377e23a2Schristos 			     Elf_Internal_Sym *sym, const char **namep,
460377e23a2Schristos 			     flagword *flagsp ATTRIBUTE_UNUSED,
461377e23a2Schristos 			     asection **secp ATTRIBUTE_UNUSED,
462377e23a2Schristos 			     bfd_vma *valp ATTRIBUTE_UNUSED)
463377e23a2Schristos {
464377e23a2Schristos   static const char *const stt_types[] = { "NOTYPE", "OBJECT", "FUNCTION" };
465377e23a2Schristos 
466377e23a2Schristos   if (ELF_ST_TYPE (sym->st_info) == STT_REGISTER)
467377e23a2Schristos     {
468377e23a2Schristos       int reg;
469377e23a2Schristos       struct _bfd_sparc_elf_app_reg *p;
470377e23a2Schristos 
471377e23a2Schristos       reg = (int)sym->st_value;
472377e23a2Schristos       switch (reg & ~1)
473377e23a2Schristos 	{
474377e23a2Schristos 	case 2: reg -= 2; break;
475377e23a2Schristos 	case 6: reg -= 4; break;
476377e23a2Schristos 	default:
4771c468f90Schristos 	  _bfd_error_handler
47807163879Schristos 	    (_("%pB: only registers %%g[2367] can be declared using STT_REGISTER"),
479377e23a2Schristos 	     abfd);
480377e23a2Schristos 	  return FALSE;
481377e23a2Schristos 	}
482377e23a2Schristos 
483377e23a2Schristos       if (info->output_bfd->xvec != abfd->xvec
484377e23a2Schristos 	  || (abfd->flags & DYNAMIC) != 0)
485377e23a2Schristos 	{
486377e23a2Schristos 	  /* STT_REGISTER only works when linking an elf64_sparc object.
487377e23a2Schristos 	     If STT_REGISTER comes from a dynamic object, don't put it into
488377e23a2Schristos 	     the output bfd.  The dynamic linker will recheck it.  */
489377e23a2Schristos 	  *namep = NULL;
490377e23a2Schristos 	  return TRUE;
491377e23a2Schristos 	}
492377e23a2Schristos 
493377e23a2Schristos       p = _bfd_sparc_elf_hash_table(info)->app_regs + reg;
494377e23a2Schristos 
495377e23a2Schristos       if (p->name != NULL && strcmp (p->name, *namep))
496377e23a2Schristos 	{
4971c468f90Schristos 	  _bfd_error_handler
4981c468f90Schristos 	    /* xgettext:c-format */
49907163879Schristos 	    (_("register %%g%d used incompatibly: %s in %pB,"
50007163879Schristos 	       " previously %s in %pB"),
5011c468f90Schristos 	     (int) sym->st_value, **namep ? *namep : "#scratch", abfd,
5021c468f90Schristos 	     *p->name ? p->name : "#scratch", p->abfd);
503377e23a2Schristos 	  return FALSE;
504377e23a2Schristos 	}
505377e23a2Schristos 
506377e23a2Schristos       if (p->name == NULL)
507377e23a2Schristos 	{
508377e23a2Schristos 	  if (**namep)
509377e23a2Schristos 	    {
510377e23a2Schristos 	      struct elf_link_hash_entry *h;
511377e23a2Schristos 
512377e23a2Schristos 	      h = (struct elf_link_hash_entry *)
513377e23a2Schristos 		bfd_link_hash_lookup (info->hash, *namep, FALSE, FALSE, FALSE);
514377e23a2Schristos 
515377e23a2Schristos 	      if (h != NULL)
516377e23a2Schristos 		{
517377e23a2Schristos 		  unsigned char type = h->type;
518377e23a2Schristos 
519377e23a2Schristos 		  if (type > STT_FUNC)
520377e23a2Schristos 		    type = 0;
5211c468f90Schristos 		  _bfd_error_handler
5221c468f90Schristos 		    /* xgettext:c-format */
52307163879Schristos 		    (_("symbol `%s' has differing types: REGISTER in %pB,"
52407163879Schristos 		       " previously %s in %pB"),
5251c468f90Schristos 		     *namep, abfd, stt_types[type], p->abfd);
526377e23a2Schristos 		  return FALSE;
527377e23a2Schristos 		}
528377e23a2Schristos 
529377e23a2Schristos 	      p->name = bfd_hash_allocate (&info->hash->table,
530377e23a2Schristos 					   strlen (*namep) + 1);
531377e23a2Schristos 	      if (!p->name)
532377e23a2Schristos 		return FALSE;
533377e23a2Schristos 
534377e23a2Schristos 	      strcpy (p->name, *namep);
535377e23a2Schristos 	    }
536377e23a2Schristos 	  else
537377e23a2Schristos 	    p->name = "";
538377e23a2Schristos 	  p->bind = ELF_ST_BIND (sym->st_info);
539377e23a2Schristos 	  p->abfd = abfd;
540377e23a2Schristos 	  p->shndx = sym->st_shndx;
541377e23a2Schristos 	}
542377e23a2Schristos       else
543377e23a2Schristos 	{
544377e23a2Schristos 	  if (p->bind == STB_WEAK
545377e23a2Schristos 	      && ELF_ST_BIND (sym->st_info) == STB_GLOBAL)
546377e23a2Schristos 	    {
547377e23a2Schristos 	      p->bind = STB_GLOBAL;
548377e23a2Schristos 	      p->abfd = abfd;
549377e23a2Schristos 	    }
550377e23a2Schristos 	}
551377e23a2Schristos       *namep = NULL;
552377e23a2Schristos       return TRUE;
553377e23a2Schristos     }
554377e23a2Schristos   else if (*namep && **namep
555377e23a2Schristos 	   && info->output_bfd->xvec == abfd->xvec)
556377e23a2Schristos     {
557377e23a2Schristos       int i;
558377e23a2Schristos       struct _bfd_sparc_elf_app_reg *p;
559377e23a2Schristos 
560377e23a2Schristos       p = _bfd_sparc_elf_hash_table(info)->app_regs;
561377e23a2Schristos       for (i = 0; i < 4; i++, p++)
562377e23a2Schristos 	if (p->name != NULL && ! strcmp (p->name, *namep))
563377e23a2Schristos 	  {
564377e23a2Schristos 	    unsigned char type = ELF_ST_TYPE (sym->st_info);
565377e23a2Schristos 
566377e23a2Schristos 	    if (type > STT_FUNC)
567377e23a2Schristos 	      type = 0;
5681c468f90Schristos 	    _bfd_error_handler
5691c468f90Schristos 	      /* xgettext:c-format */
57007163879Schristos 	      (_("Symbol `%s' has differing types: %s in %pB,"
57107163879Schristos 		 " previously REGISTER in %pB"),
5721c468f90Schristos 	       *namep, stt_types[type], abfd, p->abfd);
573377e23a2Schristos 	    return FALSE;
574377e23a2Schristos 	  }
575377e23a2Schristos     }
576377e23a2Schristos   return TRUE;
577377e23a2Schristos }
578377e23a2Schristos 
579377e23a2Schristos /* This function takes care of emitting STT_REGISTER symbols
580377e23a2Schristos    which we cannot easily keep in the symbol hash table.  */
581377e23a2Schristos 
582377e23a2Schristos static bfd_boolean
elf64_sparc_output_arch_syms(bfd * output_bfd ATTRIBUTE_UNUSED,struct bfd_link_info * info,void * flaginfo,int (* func)(void *,const char *,Elf_Internal_Sym *,asection *,struct elf_link_hash_entry *))583377e23a2Schristos elf64_sparc_output_arch_syms (bfd *output_bfd ATTRIBUTE_UNUSED,
584377e23a2Schristos 			      struct bfd_link_info *info,
58548596154Schristos 			      void * flaginfo,
58648596154Schristos 			      int (*func) (void *, const char *,
587377e23a2Schristos 					   Elf_Internal_Sym *,
588377e23a2Schristos 					   asection *,
589377e23a2Schristos 					   struct elf_link_hash_entry *))
590377e23a2Schristos {
591377e23a2Schristos   int reg;
592377e23a2Schristos   struct _bfd_sparc_elf_app_reg *app_regs =
593377e23a2Schristos     _bfd_sparc_elf_hash_table(info)->app_regs;
594377e23a2Schristos   Elf_Internal_Sym sym;
595377e23a2Schristos 
596377e23a2Schristos   for (reg = 0; reg < 4; reg++)
597377e23a2Schristos     if (app_regs [reg].name != NULL)
598377e23a2Schristos       {
599377e23a2Schristos 	if (info->strip == strip_some
600377e23a2Schristos 	    && bfd_hash_lookup (info->keep_hash,
601377e23a2Schristos 				app_regs [reg].name,
602377e23a2Schristos 				FALSE, FALSE) == NULL)
603377e23a2Schristos 	  continue;
604377e23a2Schristos 
605377e23a2Schristos 	sym.st_value = reg < 2 ? reg + 2 : reg + 4;
606377e23a2Schristos 	sym.st_size = 0;
607377e23a2Schristos 	sym.st_other = 0;
608377e23a2Schristos 	sym.st_info = ELF_ST_INFO (app_regs [reg].bind, STT_REGISTER);
609377e23a2Schristos 	sym.st_shndx = app_regs [reg].shndx;
610377e23a2Schristos 	sym.st_target_internal = 0;
61148596154Schristos 	if ((*func) (flaginfo, app_regs [reg].name, &sym,
612377e23a2Schristos 		     sym.st_shndx == SHN_ABS
613377e23a2Schristos 		     ? bfd_abs_section_ptr : bfd_und_section_ptr,
614377e23a2Schristos 		     NULL) != 1)
615377e23a2Schristos 	  return FALSE;
616377e23a2Schristos       }
617377e23a2Schristos 
618377e23a2Schristos   return TRUE;
619377e23a2Schristos }
620377e23a2Schristos 
621377e23a2Schristos static int
elf64_sparc_get_symbol_type(Elf_Internal_Sym * elf_sym,int type)622377e23a2Schristos elf64_sparc_get_symbol_type (Elf_Internal_Sym *elf_sym, int type)
623377e23a2Schristos {
624377e23a2Schristos   if (ELF_ST_TYPE (elf_sym->st_info) == STT_REGISTER)
625377e23a2Schristos     return STT_REGISTER;
626377e23a2Schristos   else
627377e23a2Schristos     return type;
628377e23a2Schristos }
629377e23a2Schristos 
630377e23a2Schristos /* A STB_GLOBAL,STT_REGISTER symbol should be BSF_GLOBAL
631377e23a2Schristos    even in SHN_UNDEF section.  */
632377e23a2Schristos 
633377e23a2Schristos static void
elf64_sparc_symbol_processing(bfd * abfd ATTRIBUTE_UNUSED,asymbol * asym)634377e23a2Schristos elf64_sparc_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED, asymbol *asym)
635377e23a2Schristos {
636377e23a2Schristos   elf_symbol_type *elfsym;
637377e23a2Schristos 
638377e23a2Schristos   elfsym = (elf_symbol_type *) asym;
639377e23a2Schristos   if (elfsym->internal_elf_sym.st_info
640377e23a2Schristos       == ELF_ST_INFO (STB_GLOBAL, STT_REGISTER))
641377e23a2Schristos     {
642377e23a2Schristos       asym->flags |= BSF_GLOBAL;
643377e23a2Schristos     }
644377e23a2Schristos }
645377e23a2Schristos 
646377e23a2Schristos 
647377e23a2Schristos /* Functions for dealing with the e_flags field.  */
648377e23a2Schristos 
649377e23a2Schristos /* Merge backend specific data from an object file to the output
650377e23a2Schristos    object file when linking.  */
651377e23a2Schristos 
652377e23a2Schristos static bfd_boolean
elf64_sparc_merge_private_bfd_data(bfd * ibfd,struct bfd_link_info * info)6531c468f90Schristos elf64_sparc_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
654377e23a2Schristos {
6551c468f90Schristos   bfd *obfd = info->output_bfd;
656377e23a2Schristos   bfd_boolean error;
657377e23a2Schristos   flagword new_flags, old_flags;
658377e23a2Schristos   int new_mm, old_mm;
659377e23a2Schristos 
660377e23a2Schristos   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
661377e23a2Schristos       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
662377e23a2Schristos     return TRUE;
663377e23a2Schristos 
664377e23a2Schristos   new_flags = elf_elfheader (ibfd)->e_flags;
665377e23a2Schristos   old_flags = elf_elfheader (obfd)->e_flags;
666377e23a2Schristos 
667377e23a2Schristos   if (!elf_flags_init (obfd))   /* First call, no flags set */
668377e23a2Schristos     {
669377e23a2Schristos       elf_flags_init (obfd) = TRUE;
670377e23a2Schristos       elf_elfheader (obfd)->e_flags = new_flags;
671377e23a2Schristos     }
672377e23a2Schristos 
673377e23a2Schristos   else if (new_flags == old_flags)      /* Compatible flags are ok */
674377e23a2Schristos     ;
675377e23a2Schristos 
676377e23a2Schristos   else					/* Incompatible flags */
677377e23a2Schristos     {
678377e23a2Schristos       error = FALSE;
679377e23a2Schristos 
680377e23a2Schristos #define EF_SPARC_ISA_EXTENSIONS \
681377e23a2Schristos   (EF_SPARC_SUN_US1 | EF_SPARC_SUN_US3 | EF_SPARC_HAL_R1)
682377e23a2Schristos 
683377e23a2Schristos       if ((ibfd->flags & DYNAMIC) != 0)
684377e23a2Schristos 	{
685377e23a2Schristos 	  /* We don't want dynamic objects memory ordering and
686377e23a2Schristos 	     architecture to have any role. That's what dynamic linker
687377e23a2Schristos 	     should do.  */
688377e23a2Schristos 	  new_flags &= ~(EF_SPARCV9_MM | EF_SPARC_ISA_EXTENSIONS);
689377e23a2Schristos 	  new_flags |= (old_flags
690377e23a2Schristos 			& (EF_SPARCV9_MM | EF_SPARC_ISA_EXTENSIONS));
691377e23a2Schristos 	}
692377e23a2Schristos       else
693377e23a2Schristos 	{
694377e23a2Schristos 	  /* Choose the highest architecture requirements.  */
695377e23a2Schristos 	  old_flags |= (new_flags & EF_SPARC_ISA_EXTENSIONS);
696377e23a2Schristos 	  new_flags |= (old_flags & EF_SPARC_ISA_EXTENSIONS);
697377e23a2Schristos 	  if ((old_flags & (EF_SPARC_SUN_US1 | EF_SPARC_SUN_US3))
698377e23a2Schristos 	      && (old_flags & EF_SPARC_HAL_R1))
699377e23a2Schristos 	    {
700377e23a2Schristos 	      error = TRUE;
7011c468f90Schristos 	      _bfd_error_handler
70207163879Schristos 		(_("%pB: linking UltraSPARC specific with HAL specific code"),
703377e23a2Schristos 		 ibfd);
704377e23a2Schristos 	    }
705377e23a2Schristos 	  /* Choose the most restrictive memory ordering.  */
706377e23a2Schristos 	  old_mm = (old_flags & EF_SPARCV9_MM);
707377e23a2Schristos 	  new_mm = (new_flags & EF_SPARCV9_MM);
708377e23a2Schristos 	  old_flags &= ~EF_SPARCV9_MM;
709377e23a2Schristos 	  new_flags &= ~EF_SPARCV9_MM;
710377e23a2Schristos 	  if (new_mm < old_mm)
711377e23a2Schristos 	    old_mm = new_mm;
712377e23a2Schristos 	  old_flags |= old_mm;
713377e23a2Schristos 	  new_flags |= old_mm;
714377e23a2Schristos 	}
715377e23a2Schristos 
716377e23a2Schristos       /* Warn about any other mismatches */
717377e23a2Schristos       if (new_flags != old_flags)
718377e23a2Schristos 	{
719377e23a2Schristos 	  error = TRUE;
7201c468f90Schristos 	  _bfd_error_handler
7211c468f90Schristos 	    /* xgettext:c-format */
72207163879Schristos 	    (_("%pB: uses different e_flags (%#x) fields than previous modules (%#x)"),
72307163879Schristos 	     ibfd, new_flags, old_flags);
724377e23a2Schristos 	}
725377e23a2Schristos 
726377e23a2Schristos       elf_elfheader (obfd)->e_flags = old_flags;
727377e23a2Schristos 
728377e23a2Schristos       if (error)
729377e23a2Schristos 	{
730377e23a2Schristos 	  bfd_set_error (bfd_error_bad_value);
731377e23a2Schristos 	  return FALSE;
732377e23a2Schristos 	}
733377e23a2Schristos     }
7341c468f90Schristos   return _bfd_sparc_elf_merge_private_bfd_data (ibfd, info);
735377e23a2Schristos }
736377e23a2Schristos 
737377e23a2Schristos /* MARCO: Set the correct entry size for the .stab section.  */
738377e23a2Schristos 
739377e23a2Schristos static bfd_boolean
elf64_sparc_fake_sections(bfd * abfd ATTRIBUTE_UNUSED,Elf_Internal_Shdr * hdr ATTRIBUTE_UNUSED,asection * sec)740377e23a2Schristos elf64_sparc_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
741377e23a2Schristos 			   Elf_Internal_Shdr *hdr ATTRIBUTE_UNUSED,
742377e23a2Schristos 			   asection *sec)
743377e23a2Schristos {
744377e23a2Schristos   const char *name;
745377e23a2Schristos 
746*1424dfb3Schristos   name = bfd_section_name (sec);
747377e23a2Schristos 
748377e23a2Schristos   if (strcmp (name, ".stab") == 0)
749377e23a2Schristos     {
750377e23a2Schristos       /* Even in the 64bit case the stab entries are only 12 bytes long.  */
751377e23a2Schristos       elf_section_data (sec)->this_hdr.sh_entsize = 12;
752377e23a2Schristos     }
753377e23a2Schristos 
754377e23a2Schristos   return TRUE;
755377e23a2Schristos }
756377e23a2Schristos 
757377e23a2Schristos /* Print a STT_REGISTER symbol to file FILE.  */
758377e23a2Schristos 
759377e23a2Schristos static const char *
elf64_sparc_print_symbol_all(bfd * abfd ATTRIBUTE_UNUSED,void * filep,asymbol * symbol)76048596154Schristos elf64_sparc_print_symbol_all (bfd *abfd ATTRIBUTE_UNUSED, void * filep,
761377e23a2Schristos 			      asymbol *symbol)
762377e23a2Schristos {
763377e23a2Schristos   FILE *file = (FILE *) filep;
764377e23a2Schristos   int reg, type;
765377e23a2Schristos 
766377e23a2Schristos   if (ELF_ST_TYPE (((elf_symbol_type *) symbol)->internal_elf_sym.st_info)
767377e23a2Schristos       != STT_REGISTER)
768377e23a2Schristos     return NULL;
769377e23a2Schristos 
770377e23a2Schristos   reg = ((elf_symbol_type *) symbol)->internal_elf_sym.st_value;
771377e23a2Schristos   type = symbol->flags;
772377e23a2Schristos   fprintf (file, "REG_%c%c%11s%c%c    R", "GOLI" [reg / 8], '0' + (reg & 7), "",
773377e23a2Schristos 		 ((type & BSF_LOCAL)
774377e23a2Schristos 		  ? (type & BSF_GLOBAL) ? '!' : 'l'
775377e23a2Schristos 		  : (type & BSF_GLOBAL) ? 'g' : ' '),
776377e23a2Schristos 		 (type & BSF_WEAK) ? 'w' : ' ');
777377e23a2Schristos   if (symbol->name == NULL || symbol->name [0] == '\0')
778377e23a2Schristos     return "#scratch";
779377e23a2Schristos   else
780377e23a2Schristos     return symbol->name;
781377e23a2Schristos }
782377e23a2Schristos 
78307163879Schristos /* Used to decide how to sort relocs in an optimal manner for the
78407163879Schristos    dynamic linker, before writing them out.  */
78507163879Schristos 
786377e23a2Schristos static enum elf_reloc_type_class
elf64_sparc_reloc_type_class(const struct bfd_link_info * info,const asection * rel_sec ATTRIBUTE_UNUSED,const Elf_Internal_Rela * rela)78707163879Schristos elf64_sparc_reloc_type_class (const struct bfd_link_info *info,
7887af5a897Schristos 			      const asection *rel_sec ATTRIBUTE_UNUSED,
7897af5a897Schristos 			      const Elf_Internal_Rela *rela)
790377e23a2Schristos {
79107163879Schristos   bfd *abfd = info->output_bfd;
79207163879Schristos   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
79307163879Schristos   struct _bfd_sparc_elf_link_hash_table *htab
79407163879Schristos     = _bfd_sparc_elf_hash_table (info);
79507163879Schristos   BFD_ASSERT (htab != NULL);
79607163879Schristos 
79707163879Schristos   if (htab->elf.dynsym != NULL
79807163879Schristos       && htab->elf.dynsym->contents != NULL)
79907163879Schristos     {
80007163879Schristos       /* Check relocation against STT_GNU_IFUNC symbol if there are
80107163879Schristos 	 dynamic symbols.  */
80207163879Schristos       unsigned long r_symndx = htab->r_symndx (rela->r_info);
80307163879Schristos       if (r_symndx != STN_UNDEF)
80407163879Schristos 	{
80507163879Schristos 	  Elf_Internal_Sym sym;
80607163879Schristos 	  if (!bed->s->swap_symbol_in (abfd,
80707163879Schristos 				       (htab->elf.dynsym->contents
80807163879Schristos 					+ r_symndx * bed->s->sizeof_sym),
80907163879Schristos 				       0, &sym))
81007163879Schristos 	    abort ();
81107163879Schristos 
81207163879Schristos 	  if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
81307163879Schristos 	    return reloc_class_ifunc;
81407163879Schristos 	}
81507163879Schristos     }
81607163879Schristos 
817377e23a2Schristos   switch ((int) ELF64_R_TYPE (rela->r_info))
818377e23a2Schristos     {
81907163879Schristos     case R_SPARC_IRELATIVE:
82007163879Schristos       return reloc_class_ifunc;
821377e23a2Schristos     case R_SPARC_RELATIVE:
822377e23a2Schristos       return reloc_class_relative;
823377e23a2Schristos     case R_SPARC_JMP_SLOT:
824377e23a2Schristos       return reloc_class_plt;
825377e23a2Schristos     case R_SPARC_COPY:
826377e23a2Schristos       return reloc_class_copy;
827377e23a2Schristos     default:
828377e23a2Schristos       return reloc_class_normal;
829377e23a2Schristos     }
830377e23a2Schristos }
831377e23a2Schristos 
832377e23a2Schristos /* Relocations in the 64 bit SPARC ELF ABI are more complex than in
833377e23a2Schristos    standard ELF, because R_SPARC_OLO10 has secondary addend in
834377e23a2Schristos    ELF64_R_TYPE_DATA field.  This structure is used to redirect the
835377e23a2Schristos    relocation handling routines.  */
836377e23a2Schristos 
837377e23a2Schristos const struct elf_size_info elf64_sparc_size_info =
838377e23a2Schristos {
839377e23a2Schristos   sizeof (Elf64_External_Ehdr),
840377e23a2Schristos   sizeof (Elf64_External_Phdr),
841377e23a2Schristos   sizeof (Elf64_External_Shdr),
842377e23a2Schristos   sizeof (Elf64_External_Rel),
843377e23a2Schristos   sizeof (Elf64_External_Rela),
844377e23a2Schristos   sizeof (Elf64_External_Sym),
845377e23a2Schristos   sizeof (Elf64_External_Dyn),
846377e23a2Schristos   sizeof (Elf_External_Note),
847377e23a2Schristos   4,		/* hash-table entry size.  */
848377e23a2Schristos   /* Internal relocations per external relocations.
849377e23a2Schristos      For link purposes we use just 1 internal per
850377e23a2Schristos      1 external, for assembly and slurp symbol table
851377e23a2Schristos      we use 2.  */
852377e23a2Schristos   1,
853377e23a2Schristos   64,		/* arch_size.  */
854377e23a2Schristos   3,		/* log_file_align.  */
855377e23a2Schristos   ELFCLASS64,
856377e23a2Schristos   EV_CURRENT,
857377e23a2Schristos   bfd_elf64_write_out_phdrs,
858377e23a2Schristos   bfd_elf64_write_shdrs_and_ehdr,
859377e23a2Schristos   bfd_elf64_checksum_contents,
860377e23a2Schristos   elf64_sparc_write_relocs,
861377e23a2Schristos   bfd_elf64_swap_symbol_in,
862377e23a2Schristos   bfd_elf64_swap_symbol_out,
863377e23a2Schristos   elf64_sparc_slurp_reloc_table,
864377e23a2Schristos   bfd_elf64_slurp_symbol_table,
865377e23a2Schristos   bfd_elf64_swap_dyn_in,
866377e23a2Schristos   bfd_elf64_swap_dyn_out,
867377e23a2Schristos   bfd_elf64_swap_reloc_in,
868377e23a2Schristos   bfd_elf64_swap_reloc_out,
869377e23a2Schristos   bfd_elf64_swap_reloca_in,
870377e23a2Schristos   bfd_elf64_swap_reloca_out
871377e23a2Schristos };
872377e23a2Schristos 
8735e098073Schristos #define TARGET_BIG_SYM	sparc_elf64_vec
874377e23a2Schristos #define TARGET_BIG_NAME	"elf64-sparc"
875377e23a2Schristos #define ELF_ARCH	bfd_arch_sparc
876377e23a2Schristos #define ELF_MAXPAGESIZE 0x100000
877377e23a2Schristos #define ELF_COMMONPAGESIZE 0x2000
878377e23a2Schristos 
879377e23a2Schristos /* This is the official ABI value.  */
880377e23a2Schristos #define ELF_MACHINE_CODE EM_SPARCV9
881377e23a2Schristos 
882377e23a2Schristos /* This is the value that we used before the ABI was released.  */
883377e23a2Schristos #define ELF_MACHINE_ALT1 EM_OLD_SPARCV9
884377e23a2Schristos 
885377e23a2Schristos #define elf_backend_reloc_type_class \
886377e23a2Schristos   elf64_sparc_reloc_type_class
887377e23a2Schristos #define bfd_elf64_get_reloc_upper_bound \
888377e23a2Schristos   elf64_sparc_get_reloc_upper_bound
889377e23a2Schristos #define bfd_elf64_get_dynamic_reloc_upper_bound \
890377e23a2Schristos   elf64_sparc_get_dynamic_reloc_upper_bound
891377e23a2Schristos #define bfd_elf64_canonicalize_reloc \
892377e23a2Schristos   elf64_sparc_canonicalize_reloc
893377e23a2Schristos #define bfd_elf64_canonicalize_dynamic_reloc \
894377e23a2Schristos   elf64_sparc_canonicalize_dynamic_reloc
89507163879Schristos #define bfd_elf64_set_reloc \
89607163879Schristos   elf64_sparc_set_reloc
897377e23a2Schristos #define elf_backend_add_symbol_hook \
898377e23a2Schristos   elf64_sparc_add_symbol_hook
899377e23a2Schristos #define elf_backend_get_symbol_type \
900377e23a2Schristos   elf64_sparc_get_symbol_type
901377e23a2Schristos #define elf_backend_symbol_processing \
902377e23a2Schristos   elf64_sparc_symbol_processing
903377e23a2Schristos #define elf_backend_print_symbol_all \
904377e23a2Schristos   elf64_sparc_print_symbol_all
905377e23a2Schristos #define elf_backend_output_arch_syms \
906377e23a2Schristos   elf64_sparc_output_arch_syms
907377e23a2Schristos #define bfd_elf64_bfd_merge_private_bfd_data \
908377e23a2Schristos   elf64_sparc_merge_private_bfd_data
909377e23a2Schristos #define elf_backend_fake_sections \
910377e23a2Schristos   elf64_sparc_fake_sections
911377e23a2Schristos #define elf_backend_size_info \
912377e23a2Schristos   elf64_sparc_size_info
913377e23a2Schristos 
914377e23a2Schristos #define elf_backend_plt_sym_val	\
915377e23a2Schristos   _bfd_sparc_elf_plt_sym_val
916377e23a2Schristos #define bfd_elf64_bfd_link_hash_table_create \
917377e23a2Schristos   _bfd_sparc_elf_link_hash_table_create
918377e23a2Schristos #define elf_info_to_howto \
919377e23a2Schristos   _bfd_sparc_elf_info_to_howto
920377e23a2Schristos #define elf_backend_copy_indirect_symbol \
921377e23a2Schristos   _bfd_sparc_elf_copy_indirect_symbol
922377e23a2Schristos #define bfd_elf64_bfd_reloc_type_lookup \
923377e23a2Schristos   _bfd_sparc_elf_reloc_type_lookup
924377e23a2Schristos #define bfd_elf64_bfd_reloc_name_lookup \
925377e23a2Schristos   _bfd_sparc_elf_reloc_name_lookup
926377e23a2Schristos #define bfd_elf64_bfd_relax_section \
927377e23a2Schristos   _bfd_sparc_elf_relax_section
928377e23a2Schristos #define bfd_elf64_new_section_hook \
929377e23a2Schristos   _bfd_sparc_elf_new_section_hook
930377e23a2Schristos 
931377e23a2Schristos #define elf_backend_create_dynamic_sections \
932377e23a2Schristos   _bfd_sparc_elf_create_dynamic_sections
933377e23a2Schristos #define elf_backend_relocs_compatible \
934377e23a2Schristos   _bfd_elf_relocs_compatible
935377e23a2Schristos #define elf_backend_check_relocs \
936377e23a2Schristos   _bfd_sparc_elf_check_relocs
937377e23a2Schristos #define elf_backend_adjust_dynamic_symbol \
938377e23a2Schristos   _bfd_sparc_elf_adjust_dynamic_symbol
939377e23a2Schristos #define elf_backend_omit_section_dynsym \
940377e23a2Schristos   _bfd_sparc_elf_omit_section_dynsym
941377e23a2Schristos #define elf_backend_size_dynamic_sections \
942377e23a2Schristos   _bfd_sparc_elf_size_dynamic_sections
943377e23a2Schristos #define elf_backend_relocate_section \
944377e23a2Schristos   _bfd_sparc_elf_relocate_section
945377e23a2Schristos #define elf_backend_finish_dynamic_symbol \
946377e23a2Schristos   _bfd_sparc_elf_finish_dynamic_symbol
947377e23a2Schristos #define elf_backend_finish_dynamic_sections \
948377e23a2Schristos   _bfd_sparc_elf_finish_dynamic_sections
9491c468f90Schristos #define elf_backend_fixup_symbol \
9501c468f90Schristos   _bfd_sparc_elf_fixup_symbol
951377e23a2Schristos 
952377e23a2Schristos #define bfd_elf64_mkobject \
953377e23a2Schristos   _bfd_sparc_elf_mkobject
954377e23a2Schristos #define elf_backend_object_p \
955377e23a2Schristos   _bfd_sparc_elf_object_p
956377e23a2Schristos #define elf_backend_gc_mark_hook \
957377e23a2Schristos   _bfd_sparc_elf_gc_mark_hook
958377e23a2Schristos #define elf_backend_init_index_section \
959377e23a2Schristos   _bfd_elf_init_1_index_section
960377e23a2Schristos 
961377e23a2Schristos #define elf_backend_can_gc_sections 1
962377e23a2Schristos #define elf_backend_can_refcount 1
963377e23a2Schristos #define elf_backend_want_got_plt 0
964377e23a2Schristos #define elf_backend_plt_readonly 0
965377e23a2Schristos #define elf_backend_want_plt_sym 1
966377e23a2Schristos #define elf_backend_got_header_size 8
9671c468f90Schristos #define elf_backend_want_dynrelro 1
968377e23a2Schristos #define elf_backend_rela_normal 1
969377e23a2Schristos 
970377e23a2Schristos /* Section 5.2.4 of the ABI specifies a 256-byte boundary for the table.  */
971377e23a2Schristos #define elf_backend_plt_alignment 8
972377e23a2Schristos 
973377e23a2Schristos #include "elf64-target.h"
974377e23a2Schristos 
975377e23a2Schristos /* FreeBSD support */
976377e23a2Schristos #undef  TARGET_BIG_SYM
9775e098073Schristos #define TARGET_BIG_SYM sparc_elf64_fbsd_vec
978377e23a2Schristos #undef  TARGET_BIG_NAME
979377e23a2Schristos #define TARGET_BIG_NAME "elf64-sparc-freebsd"
980377e23a2Schristos #undef	ELF_OSABI
981377e23a2Schristos #define	ELF_OSABI ELFOSABI_FREEBSD
982377e23a2Schristos 
983377e23a2Schristos #undef  elf64_bed
984377e23a2Schristos #define elf64_bed				elf64_sparc_fbsd_bed
985377e23a2Schristos 
986377e23a2Schristos #include "elf64-target.h"
987377e23a2Schristos 
988377e23a2Schristos /* Solaris 2.  */
989377e23a2Schristos 
990377e23a2Schristos #undef	TARGET_BIG_SYM
9915e098073Schristos #define	TARGET_BIG_SYM				sparc_elf64_sol2_vec
992377e23a2Schristos #undef	TARGET_BIG_NAME
993377e23a2Schristos #define	TARGET_BIG_NAME				"elf64-sparc-sol2"
994377e23a2Schristos 
995377e23a2Schristos /* Restore default: we cannot use ELFOSABI_SOLARIS, otherwise ELFOSABI_NONE
996377e23a2Schristos    objects won't be recognized.  */
997377e23a2Schristos #undef	ELF_OSABI
998377e23a2Schristos 
999377e23a2Schristos #undef elf64_bed
1000377e23a2Schristos #define elf64_bed				elf64_sparc_sol2_bed
1001377e23a2Schristos 
1002377e23a2Schristos /* The 64-bit static TLS arena size is rounded to the nearest 16-byte
1003377e23a2Schristos    boundary.  */
1004377e23a2Schristos #undef elf_backend_static_tls_alignment
1005377e23a2Schristos #define elf_backend_static_tls_alignment	16
1006377e23a2Schristos 
1007377e23a2Schristos #include "elf64-target.h"
1008