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