OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.18.50/] [bfd/] [elf32-sh64.c] - Blame information for rev 281

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.