[BACK]Return to elf32-sh64.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / gpl3 / binutils.old / dist / bfd

Annotation of src/external/gpl3/binutils.old/dist/bfd/elf32-sh64.c, Revision 1.1.1.2

1.1       christos    1: /* SuperH SH64-specific support for 32-bit ELF
1.1.1.2 ! christos    2:    Copyright (C) 2000-2015 Free Software Foundation, Inc.
1.1       christos    3:
                      4:    This file is part of BFD, the Binary File Descriptor library.
                      5:
                      6:    This program is free software; you can redistribute it and/or modify
                      7:    it under the terms of the GNU General Public License as published by
                      8:    the Free Software Foundation; either version 3 of the License, or
                      9:    (at your option) any later version.
                     10:
                     11:    This program is distributed in the hope that it will be useful,
                     12:    but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     14:    GNU General Public License for more details.
                     15:
                     16:    You should have received a copy of the GNU General Public License
                     17:    along with this program; if not, write to the Free Software
                     18:    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
                     19:    MA 02110-1301, USA.  */
                     20:
                     21: #define SH64_ELF
                     22:
                     23: #include "sysdep.h"
                     24: #include "bfd.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.  */
                     36: struct sh64_find_section_vma_data
                     37:  {
                     38:    asection *section;
                     39:    bfd_vma addr;
                     40:  };
                     41:
                     42: static bfd_boolean sh64_elf_new_section_hook
                     43:   (bfd *, asection *);
                     44: static bfd_boolean sh64_elf_copy_private_data
                     45:   (bfd *, bfd *);
                     46: static bfd_boolean sh64_elf_merge_private_data
                     47:   (bfd *, bfd *);
                     48: static bfd_boolean sh64_elf_fake_sections
                     49:   (bfd *, Elf_Internal_Shdr *, asection *);
                     50: static bfd_boolean sh64_elf_set_private_flags
                     51:   (bfd *, flagword);
                     52: static bfd_boolean sh64_elf_set_mach_from_flags
                     53:   (bfd *);
                     54: static bfd_boolean shmedia_prepare_reloc
                     55:   (struct bfd_link_info *, bfd *, asection *, bfd_byte *,
                     56:    const Elf_Internal_Rela *, bfd_vma *);
                     57: static int sh64_elf_get_symbol_type
                     58:   (Elf_Internal_Sym *, int);
                     59: static bfd_boolean sh64_elf_add_symbol_hook
                     60:   (bfd *, struct bfd_link_info *, Elf_Internal_Sym *, const char **,
                     61:    flagword *, asection **, bfd_vma *);
                     62: static int sh64_elf_link_output_symbol_hook
                     63:   (struct bfd_link_info *, const char *, Elf_Internal_Sym *, asection *,
                     64:    struct elf_link_hash_entry *);
                     65: static bfd_boolean sh64_backend_section_from_shdr
                     66:   (bfd *, Elf_Internal_Shdr *, const char *, int);
                     67: static void sh64_elf_final_write_processing
                     68:   (bfd *, bfd_boolean);
                     69: static bfd_boolean sh64_bfd_elf_copy_private_section_data
                     70:   (bfd *, asection *, bfd *, asection *);
                     71: static 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) \
                    107:   ((void) f, (void) h, (void) i, 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;
1.1.1.2 ! christos  201:
        !           202:   return _bfd_elf_copy_private_bfd_data (ibfd, obfd);
1.1       christos  203: }
                    204:
                    205: static bfd_boolean
                    206: sh64_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:
                    266: bfd_boolean
                    267: sh64_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:
                    311: bfd_boolean
                    312: sh64_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:
                    344: static bfd_boolean
                    345: sh64_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:
                    357: static int
                    358: sh64_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:
                    384: static bfd_boolean
                    385: sh64_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
1.1.1.2 ! christos  400:        = bfd_link_relocatable (info) || info->emitrelocations
1.1       christos  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
1.1.1.2 ! christos  444:          || ((bfd_link_relocatable (info) || info->emitrelocations)
1.1       christos  445:              && h->root.type != bfd_link_hash_undefined)
1.1.1.2 ! christos  446:          || (! bfd_link_relocatable (info) && !info->emitrelocations
1.1       christos  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:
                    481: static int
                    482: sh64_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:
1.1.1.2 ! christos  490:   if (bfd_link_relocatable (info) || info->emitrelocations)
1.1       christos  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:
                    503: static bfd_boolean
                    504: shmedia_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:
                    610: static void
                    611: sh64_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:
                    644: static void
                    645: sh64_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.  */
                    743: static void
                    744: sh64_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:
                    762: static 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
1.1.1.2 ! christos  769: #define        TARGET_BIG_SYM          sh64_elf32_vec
1.1       christos  770: #undef TARGET_BIG_NAME
                    771: #define        TARGET_BIG_NAME         "elf32-sh64"
                    772: #undef TARGET_LITTLE_SYM
1.1.1.2 ! christos  773: #define        TARGET_LITTLE_SYM       sh64_elf32_le_vec
1.1       christos  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
1.1.1.2 ! christos  781: #define        TARGET_BIG_SYM          sh64_elf32_nbsd_vec
1.1       christos  782: #undef TARGET_BIG_NAME
                    783: #define        TARGET_BIG_NAME         "elf32-sh64-nbsd"
                    784: #undef TARGET_LITTLE_SYM
1.1.1.2 ! christos  785: #define        TARGET_LITTLE_SYM       sh64_elf32_nbsd_le_vec
1.1       christos  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
1.1.1.2 ! christos  800: #define        TARGET_BIG_SYM          sh64_elf32_linux_be_vec
1.1       christos  801: #undef TARGET_BIG_NAME
                    802: #define        TARGET_BIG_NAME         "elf32-sh64big-linux"
                    803: #undef TARGET_LITTLE_SYM
1.1.1.2 ! christos  804: #define        TARGET_LITTLE_SYM       sh64_elf32_linux_vec
1.1       christos  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:

CVSweb <webmaster@jp.NetBSD.org>