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