1/* SuperH SH64-specific support for 32-bit ELF
2   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010
3   Free Software Foundation, Inc.
4
5   This file is part of BFD, the Binary File Descriptor library.
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 3 of the License, or
10   (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program; if not, write to the Free Software
19   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20   MA 02110-1301, USA.  */
21
22#define SH64_ELF
23
24#include "sysdep.h"
25#include "bfd.h"
26#include "elf-bfd.h"
27#include "../opcodes/sh64-opc.h"
28#include "elf32-sh64.h"
29
30/* Add a suffix for datalabel indirection symbols.  It must not match any
31   other symbols; user symbols with or without version or other
32   decoration.  It must only be used internally and not emitted by any
33   means.  */
34#define DATALABEL_SUFFIX " DL"
35
36/* Used to hold data for function called through bfd_map_over_sections.  */
37struct sh64_find_section_vma_data
38 {
39   asection *section;
40   bfd_vma addr;
41 };
42
43static bfd_boolean sh64_elf_new_section_hook
44  (bfd *, asection *);
45static bfd_boolean sh64_elf_copy_private_data
46  (bfd *, bfd *);
47static bfd_boolean sh64_elf_merge_private_data
48  (bfd *, bfd *);
49static bfd_boolean sh64_elf_fake_sections
50  (bfd *, Elf_Internal_Shdr *, asection *);
51static bfd_boolean sh64_elf_set_private_flags
52  (bfd *, flagword);
53static bfd_boolean sh64_elf_set_mach_from_flags
54  (bfd *);
55static bfd_boolean shmedia_prepare_reloc
56  (struct bfd_link_info *, bfd *, asection *, bfd_byte *,
57   const Elf_Internal_Rela *, bfd_vma *);
58static int sh64_elf_get_symbol_type
59  (Elf_Internal_Sym *, int);
60static bfd_boolean sh64_elf_add_symbol_hook
61  (bfd *, struct bfd_link_info *, Elf_Internal_Sym *, const char **,
62   flagword *, asection **, bfd_vma *);
63static int sh64_elf_link_output_symbol_hook
64  (struct bfd_link_info *, const char *, Elf_Internal_Sym *, asection *,
65   struct elf_link_hash_entry *);
66static bfd_boolean sh64_backend_section_from_shdr
67  (bfd *, Elf_Internal_Shdr *, const char *, int);
68static void sh64_elf_final_write_processing
69  (bfd *, bfd_boolean);
70static bfd_boolean sh64_bfd_elf_copy_private_section_data
71  (bfd *, asection *, bfd *, asection *);
72static void sh64_find_section_for_address
73  (bfd *, asection *, void *);
74
75/* Let elf32-sh.c handle the "bfd_" definitions, so we only have to
76   intrude with an #ifndef around the function definition.  */
77#define sh_elf_copy_private_data		sh64_elf_copy_private_data
78#define sh_elf_merge_private_data		sh64_elf_merge_private_data
79#define sh_elf_set_private_flags		sh64_elf_set_private_flags
80/* Typo in elf32-sh.c (and unlinear name).  */
81#define bfd_elf32_bfd_set_private_flags		sh64_elf_set_private_flags
82#define sh_elf_set_mach_from_flags		sh64_elf_set_mach_from_flags
83
84#define elf_backend_sign_extend_vma		1
85#define elf_backend_fake_sections		sh64_elf_fake_sections
86#define elf_backend_get_symbol_type		sh64_elf_get_symbol_type
87#define elf_backend_add_symbol_hook		sh64_elf_add_symbol_hook
88#define elf_backend_link_output_symbol_hook \
89	sh64_elf_link_output_symbol_hook
90#define elf_backend_merge_symbol_attribute	sh64_elf_merge_symbol_attribute
91#define elf_backend_final_write_processing 	sh64_elf_final_write_processing
92#define elf_backend_section_from_shdr		sh64_backend_section_from_shdr
93#define elf_backend_special_sections		sh64_elf_special_sections
94#define elf_backend_section_flags		sh64_elf_section_flags
95
96#define bfd_elf32_new_section_hook		sh64_elf_new_section_hook
97
98/* For objcopy, we need to set up sh64_elf_section_data (asection *) from
99   incoming section flags.  This is otherwise done in sh64elf.em when
100   linking or tc-sh64.c when assembling.  */
101#define bfd_elf32_bfd_copy_private_section_data \
102	sh64_bfd_elf_copy_private_section_data
103
104/* This COFF-only function (only compiled with COFF support, making
105   ELF-only chains problematic) returns TRUE early for SH4, so let's just
106   define it TRUE here.  */
107#define _bfd_sh_align_load_span(a,b,c,d,e,f,g,h,i,j) \
108  ((void) f, (void) h, (void) i, TRUE)
109
110#define GOT_BIAS (-((long)-32768))
111#define INCLUDE_SHMEDIA
112#define SH_TARGET_ALREADY_DEFINED
113#include "elf32-sh.c"
114
115/* Tack some extra info on struct bfd_elf_section_data.  */
116
117static bfd_boolean
118sh64_elf_new_section_hook (bfd *abfd, asection *sec)
119{
120  if (!sec->used_by_bfd)
121    {
122      struct _sh64_elf_section_data *sdata;
123      bfd_size_type amt = sizeof (*sdata);
124
125      sdata = bfd_zalloc (abfd, amt);
126      if (sdata == NULL)
127	return FALSE;
128      sec->used_by_bfd = sdata;
129    }
130
131  return _bfd_elf_new_section_hook (abfd, sec);
132}
133
134/* Set the SHF_SH5_ISA32 flag for ISA SHmedia code sections, and pass
135   through SHT_SH5_CR_SORTED on a sorted .cranges section.  */
136
137bfd_boolean
138sh64_elf_fake_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
139			Elf_Internal_Shdr *elf_section_hdr,
140			asection *asect)
141{
142  if (sh64_elf_section_data (asect)->sh64_info != NULL)
143    elf_section_hdr->sh_flags
144      |= sh64_elf_section_data (asect)->sh64_info->contents_flags;
145
146  /* If this section has the SEC_SORT_ENTRIES flag set, it is a sorted
147     .cranges section passing through objcopy.  */
148  if ((bfd_get_section_flags (output_bfd, asect) & SEC_SORT_ENTRIES) != 0
149      && strcmp (bfd_get_section_name (output_bfd, asect),
150		 SH64_CRANGES_SECTION_NAME) == 0)
151    elf_section_hdr->sh_type = SHT_SH5_CR_SORTED;
152
153  return TRUE;
154}
155
156static bfd_boolean
157sh64_elf_set_mach_from_flags (bfd *abfd)
158{
159  flagword flags = elf_elfheader (abfd)->e_flags;
160
161  switch (flags & EF_SH_MACH_MASK)
162    {
163    case EF_SH5:
164      /* These are fit to execute on SH5.  Just one but keep the switch
165	 construct to make additions easy.  */
166      bfd_default_set_arch_mach (abfd, bfd_arch_sh, bfd_mach_sh5);
167      break;
168
169    default:
170      bfd_set_error (bfd_error_wrong_format);
171      return FALSE;
172    }
173
174  return TRUE;
175}
176
177static bfd_boolean
178sh64_elf_section_flags (flagword *flags,
179			const Elf_Internal_Shdr *hdr)
180{
181  if (hdr->bfd_section == NULL)
182    return FALSE;
183
184  if (strcmp (hdr->bfd_section->name, SH64_CRANGES_SECTION_NAME) == 0)
185    *flags |= SEC_DEBUGGING;
186
187  return TRUE;
188}
189
190static bfd_boolean
191sh64_elf_copy_private_data (bfd * ibfd, bfd * obfd)
192{
193  if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
194      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
195    return TRUE;
196
197  BFD_ASSERT (!elf_flags_init (obfd)
198	      || (elf_elfheader (obfd)->e_flags
199		  == elf_elfheader (ibfd)->e_flags));
200
201  elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
202  return TRUE;
203}
204
205static bfd_boolean
206sh64_elf_merge_private_data (bfd *ibfd, bfd *obfd)
207{
208  flagword old_flags, new_flags;
209
210  if (! _bfd_generic_verify_endian_match (ibfd, obfd))
211    return FALSE;
212
213  if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
214      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
215    return TRUE;
216
217  if (bfd_get_arch_size (ibfd) != bfd_get_arch_size (obfd))
218    {
219      const char *msg;
220
221      if (bfd_get_arch_size (ibfd) == 32
222	  && bfd_get_arch_size (obfd) == 64)
223	msg = _("%s: compiled as 32-bit object and %s is 64-bit");
224      else if (bfd_get_arch_size (ibfd) == 64
225	       && bfd_get_arch_size (obfd) == 32)
226	msg = _("%s: compiled as 64-bit object and %s is 32-bit");
227      else
228	msg = _("%s: object size does not match that of target %s");
229
230      (*_bfd_error_handler) (msg, bfd_get_filename (ibfd),
231			     bfd_get_filename (obfd));
232      bfd_set_error (bfd_error_wrong_format);
233      return FALSE;
234    }
235
236  old_flags = elf_elfheader (obfd)->e_flags;
237  new_flags = elf_elfheader (ibfd)->e_flags;
238  if (! elf_flags_init (obfd))
239    {
240      /* This happens when ld starts out with a 'blank' output file.  */
241      elf_flags_init (obfd) = TRUE;
242      elf_elfheader (obfd)->e_flags = old_flags = new_flags;
243    }
244  /* We don't allow linking in non-SH64 code.  */
245  else if ((new_flags & EF_SH_MACH_MASK) != EF_SH5)
246    {
247      (*_bfd_error_handler)
248	("%s: uses non-SH64 instructions while previous modules use SH64 instructions",
249	 bfd_get_filename (ibfd));
250      bfd_set_error (bfd_error_bad_value);
251      return FALSE;
252    }
253
254  /* I can't think of anything sane other than old_flags being EF_SH5 and
255     that we need to preserve that.  */
256  elf_elfheader (obfd)->e_flags = old_flags;
257  return sh64_elf_set_mach_from_flags (obfd);
258}
259
260/* Handle a SH64-specific section when reading an object file.  This
261   is called when bfd_section_from_shdr finds a section with an unknown
262   type.
263
264   We only recognize SHT_SH5_CR_SORTED, on the .cranges section.  */
265
266bfd_boolean
267sh64_backend_section_from_shdr (bfd *abfd, Elf_Internal_Shdr *hdr,
268				const char *name, int shindex)
269{
270  flagword flags = 0;
271
272  /* We do like MIPS with a bit switch for recognized types, and returning
273     FALSE for a recognized section type with an unexpected name.  Right
274     now we only have one recognized type, but that might change.  */
275  switch (hdr->sh_type)
276    {
277    case SHT_SH5_CR_SORTED:
278      if (strcmp (name, SH64_CRANGES_SECTION_NAME) != 0)
279	return FALSE;
280
281      /* We set the SEC_SORT_ENTRIES flag so it can be passed on to
282	 sh64_elf_fake_sections, keeping SHT_SH5_CR_SORTED if this object
283	 passes through objcopy.  Perhaps it is brittle; the flag can
284	 suddenly be used by other BFD parts, but it seems not really used
285	 anywhere at the moment.  */
286      flags = SEC_DEBUGGING | SEC_SORT_ENTRIES;
287      break;
288
289    default:
290      return FALSE;
291    }
292
293  if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
294    return FALSE;
295
296  if (flags
297      && ! bfd_set_section_flags (abfd, hdr->bfd_section,
298				  bfd_get_section_flags (abfd,
299							 hdr->bfd_section)
300				  | flags))
301    return FALSE;
302
303  return TRUE;
304}
305
306/* In contrast to sh64_backend_section_from_shdr, this is called for all
307   sections, but only when copying sections, not when linking or
308   assembling.  We need to set up the sh64_elf_section_data (asection *)
309   structure for the SH64 ELF section flags to be copied correctly.  */
310
311bfd_boolean
312sh64_bfd_elf_copy_private_section_data (bfd *ibfd, asection *isec,
313					bfd *obfd, asection *osec)
314{
315  struct sh64_section_data *sh64_sec_data;
316
317  if (ibfd->xvec->flavour != bfd_target_elf_flavour
318      || obfd->xvec->flavour != bfd_target_elf_flavour)
319    return TRUE;
320
321  if (! _bfd_elf_copy_private_section_data (ibfd, isec, obfd, osec))
322    return FALSE;
323
324  sh64_sec_data = sh64_elf_section_data (isec)->sh64_info;
325  if (sh64_sec_data == NULL)
326    {
327      sh64_sec_data = bfd_zmalloc (sizeof (struct sh64_section_data));
328
329      if (sh64_sec_data == NULL)
330	return FALSE;
331
332      sh64_sec_data->contents_flags
333	= (elf_section_data (isec)->this_hdr.sh_flags
334	   & (SHF_SH5_ISA32 | SHF_SH5_ISA32_MIXED));
335
336      sh64_elf_section_data (osec)->sh64_info = sh64_sec_data;
337    }
338
339  return TRUE;
340}
341
342/* Function to keep SH64 specific file flags.  */
343
344static bfd_boolean
345sh64_elf_set_private_flags (bfd *abfd, flagword flags)
346{
347  BFD_ASSERT (! elf_flags_init (abfd)
348	      || elf_elfheader (abfd)->e_flags == flags);
349
350  elf_elfheader (abfd)->e_flags = flags;
351  elf_flags_init (abfd) = TRUE;
352  return sh64_elf_set_mach_from_flags (abfd);
353}
354
355/* Called when writing out an object file to decide the type of a symbol.  */
356
357static int
358sh64_elf_get_symbol_type (Elf_Internal_Sym *elf_sym, int type)
359{
360  if (ELF_ST_TYPE (elf_sym->st_info) == STT_DATALABEL)
361    return STT_DATALABEL;
362
363  return type;
364}
365
366/* Hook called by the linker routine which adds symbols from an object
367   file.  We must make indirect symbols for undefined symbols marked with
368   STT_DATALABEL, so relocations passing them will pick up that attribute
369   and neutralize STO_SH5_ISA32 found on the symbol definition.
370
371   There is a problem, though: We want to fill in the hash-table entry for
372   this symbol and signal to the caller that no further processing is
373   needed.  But we don't have the index for this hash-table entry.  We
374   rely here on that the current entry is the first hash-entry with NULL,
375   which seems brittle.  Also, iterating over the hash-table to find that
376   entry is a linear operation on the number of symbols in this input
377   file, and this function should take constant time, so that's not good
378   too.  Only comfort is that DataLabel references should only be found in
379   hand-written assembly code and thus be rare.  FIXME: Talk maintainers
380   into adding an option to elf_add_symbol_hook (preferably) for the index
381   or the hash entry, alternatively adding the index to Elf_Internal_Sym
382   (not so good).  */
383
384static bfd_boolean
385sh64_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
386			  Elf_Internal_Sym *sym, const char **namep,
387			  flagword *flagsp ATTRIBUTE_UNUSED,
388			  asection **secp, bfd_vma *valp)
389{
390  /* We want to do this for relocatable as well as final linking.  */
391  if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL
392      && is_elf_hash_table (info->hash))
393    {
394      struct elf_link_hash_entry *h;
395
396      /* For relocatable links, we register the DataLabel sym in its own
397	 right, and tweak the name when it's output.  Otherwise, we make
398	 an indirect symbol of it.  */
399      flagword flags
400	= info->relocatable || info->emitrelocations
401	? BSF_GLOBAL : BSF_GLOBAL | BSF_INDIRECT;
402
403      char *dl_name
404	= bfd_malloc (strlen (*namep) + sizeof (DATALABEL_SUFFIX));
405      struct elf_link_hash_entry ** sym_hash = elf_sym_hashes (abfd);
406
407      BFD_ASSERT (sym_hash != NULL);
408
409      /* Allocation may fail.  */
410      if (dl_name == NULL)
411	return FALSE;
412
413      strcpy (dl_name, *namep);
414      strcat (dl_name, DATALABEL_SUFFIX);
415
416      h = (struct elf_link_hash_entry *)
417	bfd_link_hash_lookup (info->hash, dl_name, FALSE, FALSE, FALSE);
418
419      if (h == NULL)
420	{
421	  /* No previous datalabel symbol.  Make one.  */
422	  struct bfd_link_hash_entry *bh = NULL;
423	  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
424
425	  if (! _bfd_generic_link_add_one_symbol (info, abfd, dl_name,
426						  flags, *secp, *valp,
427						  *namep, FALSE,
428						  bed->collect, &bh))
429	    {
430	      free (dl_name);
431	      return FALSE;
432	    }
433
434	  h = (struct elf_link_hash_entry *) bh;
435	  h->non_elf = 0;
436	  h->type = STT_DATALABEL;
437	}
438      else
439	/* If a new symbol was created, it holds the allocated name.
440	   Otherwise, we don't need it anymore and should deallocate it.  */
441	free (dl_name);
442
443      if (h->type != STT_DATALABEL
444	  || ((info->relocatable || info->emitrelocations)
445	      && h->root.type != bfd_link_hash_undefined)
446	  || (! info->relocatable && !info->emitrelocations
447	      && h->root.type != bfd_link_hash_indirect))
448	{
449	  /* Make sure we don't get confused on invalid input.  */
450	  (*_bfd_error_handler)
451	    (_("%s: encountered datalabel symbol in input"),
452	     bfd_get_filename (abfd));
453	  bfd_set_error (bfd_error_bad_value);
454	  return FALSE;
455	}
456
457      /* Now find the hash-table slot for this entry and fill it in.  */
458      while (*sym_hash != NULL)
459	sym_hash++;
460      *sym_hash = h;
461
462      /* Signal to caller to skip this symbol - we've handled it.  */
463      *namep = NULL;
464    }
465
466  return TRUE;
467}
468
469/* This hook function is called before the linker writes out a global
470   symbol.  For relocatable links, DataLabel symbols will be present in
471   linker output.  We cut off the special suffix on those symbols, so the
472   right name appears in the output.
473
474   When linking and emitting relocations, there can appear global symbols
475   that are not referenced by relocs, but rather only implicitly through
476   DataLabel references, a relation that is not visible to the linker.
477   Since no stripping of global symbols in done when doing such linking,
478   we don't need to look up and make sure to emit the main symbol for each
479   DataLabel symbol.  */
480
481static int
482sh64_elf_link_output_symbol_hook (struct bfd_link_info *info,
483				  const char *cname,
484				  Elf_Internal_Sym *sym,
485				  asection *input_sec ATTRIBUTE_UNUSED,
486				  struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
487{
488  char *name = (char *) cname;
489
490  if (info->relocatable || info->emitrelocations)
491    {
492      if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL)
493	name[strlen (name) - strlen (DATALABEL_SUFFIX)] = 0;
494    }
495
496  return 1;
497}
498
499/* Check a SH64-specific reloc and put the value to relocate to into
500   RELOCATION, ready to pass to _bfd_final_link_relocate.  Return FALSE if
501   bad value, TRUE if ok.  */
502
503static bfd_boolean
504shmedia_prepare_reloc (struct bfd_link_info *info, bfd *abfd,
505		       asection *input_section, bfd_byte *contents,
506		       const Elf_Internal_Rela *rel, bfd_vma *relocation)
507{
508  bfd_vma disp, dropped;
509
510  switch (ELF32_R_TYPE (rel->r_info))
511    {
512    case R_SH_PT_16:
513      /* Check the lowest bit of the destination field.  If it is 1, we
514	 check the ISA type of the destination (i.e. the low bit of the
515	 "relocation" value, and emit an error if the instruction does not
516	 match).  If it is 0, we change a PTA to PTB.  There should never
517	 be a PTB that should change to a PTA; that indicates a toolchain
518	 error; a mismatch with GAS.  */
519      {
520	char *msg = NULL;
521	bfd_vma insn = bfd_get_32 (abfd, contents + rel->r_offset);
522
523	if (insn & (1 << 10))
524	  {
525	    /* Check matching insn and ISA (address of target).  */
526	    if ((insn & SHMEDIA_PTB_BIT) != 0
527		&& ((*relocation + rel->r_addend) & 1) != 0)
528	      msg = _("PTB mismatch: a SHmedia address (bit 0 == 1)");
529	    else if ((insn & SHMEDIA_PTB_BIT) == 0
530		     && ((*relocation + rel->r_addend) & 1) == 0)
531	      msg = _("PTA mismatch: a SHcompact address (bit 0 == 0)");
532
533	    if (msg != NULL
534		&& ! ((*info->callbacks->reloc_dangerous)
535		      (info, msg, abfd, input_section,
536		       rel->r_offset)))
537	      return FALSE;
538	  }
539	else
540	  {
541	    /* We shouldn't get here with a PTB insn and a R_SH_PT_16.  It
542	       means GAS output does not match expectations; a PTA or PTB
543	       expressed as such (or a PT found at assembly to be PTB)
544	       would match the test above, and PT expansion with an
545	       unknown destination (or when relaxing) will get us here.  */
546	    if ((insn & SHMEDIA_PTB_BIT) != 0)
547	      {
548		(*_bfd_error_handler)
549		  (_("%s: GAS error: unexpected PTB insn with R_SH_PT_16"),
550		   bfd_get_filename (input_section->owner));
551		return FALSE;
552	      }
553
554	    /* Change the PTA to a PTB, if destination indicates so.  */
555	    if (((*relocation + rel->r_addend) & 1) == 0)
556	      bfd_put_32 (abfd, insn | SHMEDIA_PTB_BIT,
557			  contents + rel->r_offset);
558	  }
559      }
560
561    case R_SH_SHMEDIA_CODE:
562    case R_SH_DIR5U:
563    case R_SH_DIR6S:
564    case R_SH_DIR6U:
565    case R_SH_DIR10S:
566    case R_SH_DIR10SW:
567    case R_SH_DIR10SL:
568    case R_SH_DIR10SQ:
569    case R_SH_IMMS16:
570    case R_SH_IMMU16:
571    case R_SH_IMM_LOW16:
572    case R_SH_IMM_LOW16_PCREL:
573    case R_SH_IMM_MEDLOW16:
574    case R_SH_IMM_MEDLOW16_PCREL:
575    case R_SH_IMM_MEDHI16:
576    case R_SH_IMM_MEDHI16_PCREL:
577    case R_SH_IMM_HI16:
578    case R_SH_IMM_HI16_PCREL:
579    case R_SH_64:
580    case R_SH_64_PCREL:
581      break;
582
583    default:
584      return FALSE;
585    }
586
587  disp = (*relocation & 0xf);
588  dropped = 0;
589  switch (ELF32_R_TYPE (rel->r_info))
590    {
591    case R_SH_DIR10SW: dropped = disp & 1; break;
592    case R_SH_DIR10SL: dropped = disp & 3; break;
593    case R_SH_DIR10SQ: dropped = disp & 7; break;
594    }
595  if (dropped != 0)
596    {
597      (*_bfd_error_handler)
598	(_("%B: error: unaligned relocation type %d at %08x reloc %p\n"),
599	 input_section->owner, ELF32_R_TYPE (rel->r_info),
600	 (unsigned) rel->r_offset, relocation);
601      return FALSE;
602    }
603
604  return TRUE;
605}
606
607/* Helper function to locate the section holding a certain address.  This
608   is called via bfd_map_over_sections.  */
609
610static void
611sh64_find_section_for_address (bfd *abfd ATTRIBUTE_UNUSED,
612			       asection *section, void *data)
613{
614  bfd_vma vma;
615  bfd_size_type size;
616
617  struct sh64_find_section_vma_data *fsec_datap
618    = (struct sh64_find_section_vma_data *) data;
619
620  /* Return if already found.  */
621  if (fsec_datap->section)
622    return;
623
624  /* If this section isn't part of the addressable contents, skip it.  */
625  if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0)
626    return;
627
628  vma = bfd_get_section_vma (abfd, section);
629  if (fsec_datap->addr < vma)
630    return;
631
632  size = section->size;
633  if (fsec_datap->addr >= vma + size)
634    return;
635
636  fsec_datap->section = section;
637}
638
639/* Make sure to write out the generated entries in the .cranges section
640   when doing partial linking, and set bit 0 on the entry address if it
641   points to SHmedia code and write sorted .cranges entries when writing
642   executables (final linking and objcopy).  */
643
644static void
645sh64_elf_final_write_processing (bfd *abfd,
646				 bfd_boolean linker ATTRIBUTE_UNUSED)
647{
648  bfd_vma ld_generated_cranges_size;
649  asection *cranges
650    = bfd_get_section_by_name (abfd, SH64_CRANGES_SECTION_NAME);
651
652  /* If no new .cranges were added, the generic ELF linker parts will
653     write it all out.  If not, we need to write them out when doing
654     partial linking.  For a final link, we will sort them and write them
655     all out further below.  */
656  if (linker
657      && cranges != NULL
658      && elf_elfheader (abfd)->e_type != ET_EXEC
659      && (ld_generated_cranges_size
660	  = sh64_elf_section_data (cranges)->sh64_info->cranges_growth) != 0)
661    {
662      bfd_vma incoming_cranges_size
663	= cranges->size - ld_generated_cranges_size;
664
665      if (! bfd_set_section_contents (abfd, cranges,
666				      cranges->contents
667				      + incoming_cranges_size,
668				      cranges->output_offset
669				      + incoming_cranges_size,
670				      ld_generated_cranges_size))
671	{
672	  bfd_set_error (bfd_error_file_truncated);
673	  (*_bfd_error_handler)
674	    (_("%s: could not write out added .cranges entries"),
675	     bfd_get_filename (abfd));
676	}
677    }
678
679  /* Only set entry address bit 0 and sort .cranges when linking to an
680     executable; never with objcopy or strip.  */
681  if (linker && elf_elfheader (abfd)->e_type == ET_EXEC)
682    {
683      struct sh64_find_section_vma_data fsec_data;
684      sh64_elf_crange dummy;
685
686      /* For a final link, set the low bit of the entry address to
687	 reflect whether or not it is a SHmedia address.
688	 FIXME: Perhaps we shouldn't do this if the entry address was
689	 supplied numerically, but we currently lack the infrastructure to
690	 recognize that: The entry symbol, and info whether it is numeric
691	 or a symbol name is kept private in the linker.  */
692      fsec_data.addr = elf_elfheader (abfd)->e_entry;
693      fsec_data.section = NULL;
694
695      bfd_map_over_sections (abfd, sh64_find_section_for_address,
696			     &fsec_data);
697      if (fsec_data.section
698	  && (sh64_get_contents_type (fsec_data.section,
699				      elf_elfheader (abfd)->e_entry,
700				      &dummy) == CRT_SH5_ISA32))
701	elf_elfheader (abfd)->e_entry |= 1;
702
703      /* If we have a .cranges section, sort the entries.  */
704      if (cranges != NULL)
705	{
706	  bfd_size_type cranges_size = cranges->size;
707
708	  /* We know we always have these in memory at this time.  */
709	  BFD_ASSERT (cranges->contents != NULL);
710
711	  /* The .cranges may already have been sorted in the process of
712	     finding out the ISA-type of the entry address.  If not, we do
713	     it here.  */
714	  if (elf_section_data (cranges)->this_hdr.sh_type
715	      != SHT_SH5_CR_SORTED)
716	    {
717	      qsort (cranges->contents, cranges_size / SH64_CRANGE_SIZE,
718		     SH64_CRANGE_SIZE,
719		     bfd_big_endian (cranges->owner)
720		     ? _bfd_sh64_crange_qsort_cmpb
721		     : _bfd_sh64_crange_qsort_cmpl);
722	      elf_section_data (cranges)->this_hdr.sh_type
723		= SHT_SH5_CR_SORTED;
724	    }
725
726	  /* We need to write it out in whole as sorted.  */
727	  if (! bfd_set_section_contents (abfd, cranges,
728					  cranges->contents,
729					  cranges->output_offset,
730					  cranges_size))
731	    {
732	      bfd_set_error (bfd_error_file_truncated);
733	      (*_bfd_error_handler)
734		(_("%s: could not write out sorted .cranges entries"),
735		 bfd_get_filename (abfd));
736	    }
737	}
738    }
739}
740
741/* Merge non visibility st_other attribute when the symbol comes from
742   a dynamic object.  */
743static void
744sh64_elf_merge_symbol_attribute (struct elf_link_hash_entry *h,
745				 const Elf_Internal_Sym *isym,
746				 bfd_boolean definition,
747				 bfd_boolean dynamic ATTRIBUTE_UNUSED)
748{
749  if ((isym->st_other & ~ELF_ST_VISIBILITY (-1)) != 0)
750    {
751      unsigned char other;
752
753      /* Take the balance of OTHER from the definition.  */
754      other = (definition ? isym->st_other : h->other);
755      other &= ~ ELF_ST_VISIBILITY (-1);
756      h->other = other | ELF_ST_VISIBILITY (h->other);
757    }
758
759  return;
760}
761
762static const struct bfd_elf_special_section sh64_elf_special_sections[] =
763{
764  { STRING_COMMA_LEN (".cranges"), 0, SHT_PROGBITS, 0 },
765  { NULL,                       0, 0, 0,            0 }
766};
767
768#undef	TARGET_BIG_SYM
769#define	TARGET_BIG_SYM		bfd_elf32_sh64_vec
770#undef	TARGET_BIG_NAME
771#define	TARGET_BIG_NAME		"elf32-sh64"
772#undef	TARGET_LITTLE_SYM
773#define	TARGET_LITTLE_SYM	bfd_elf32_sh64l_vec
774#undef	TARGET_LITTLE_NAME
775#define	TARGET_LITTLE_NAME	"elf32-sh64l"
776
777#include "elf32-target.h"
778
779/* NetBSD support.  */
780#undef	TARGET_BIG_SYM
781#define	TARGET_BIG_SYM		bfd_elf32_sh64nbsd_vec
782#undef	TARGET_BIG_NAME
783#define	TARGET_BIG_NAME		"elf32-sh64-nbsd"
784#undef	TARGET_LITTLE_SYM
785#define	TARGET_LITTLE_SYM	bfd_elf32_sh64lnbsd_vec
786#undef	TARGET_LITTLE_NAME
787#define	TARGET_LITTLE_NAME	"elf32-sh64l-nbsd"
788#undef	ELF_MAXPAGESIZE
789#define	ELF_MAXPAGESIZE		0x10000
790#undef	ELF_COMMONPAGESIZE
791#undef	elf_symbol_leading_char
792#define	elf_symbol_leading_char	0
793#undef	elf32_bed
794#define	elf32_bed		elf32_sh64_nbsd_bed
795
796#include "elf32-target.h"
797
798/* Linux support.  */
799#undef	TARGET_BIG_SYM
800#define	TARGET_BIG_SYM		bfd_elf32_sh64blin_vec
801#undef	TARGET_BIG_NAME
802#define	TARGET_BIG_NAME		"elf32-sh64big-linux"
803#undef	TARGET_LITTLE_SYM
804#define	TARGET_LITTLE_SYM	bfd_elf32_sh64lin_vec
805#undef	TARGET_LITTLE_NAME
806#define	TARGET_LITTLE_NAME	"elf32-sh64-linux"
807#undef	elf32_bed
808#define	elf32_bed		elf32_sh64_lin_bed
809#undef	ELF_COMMONPAGESIZE
810#define	ELF_COMMONPAGESIZE	0x1000
811
812#include "elf32-target.h"
813
814