Home | History | Annotate | Line # | Download | only in bfd
      1   1.1  christos /* 32-bit ELF support for S+core.
      2  1.11  christos    Copyright (C) 2006-2024 Free Software Foundation, Inc.
      3   1.1  christos    Contributed by
      4   1.1  christos    Brain.lin (brain.lin (at) sunplusct.com)
      5   1.1  christos    Mei Ligang (ligang (at) sunnorth.com.cn)
      6   1.1  christos    Pei-Lin Tsai (pltsai (at) sunplus.com)
      7   1.1  christos 
      8   1.1  christos    This file is part of BFD, the Binary File Descriptor library.
      9   1.1  christos 
     10   1.1  christos    This program is free software; you can redistribute it and/or modify
     11   1.1  christos    it under the terms of the GNU General Public License as published by
     12   1.1  christos    the Free Software Foundation; either version 3 of the License, or
     13   1.1  christos    (at your option) any later version.
     14   1.1  christos 
     15   1.1  christos    This program is distributed in the hope that it will be useful,
     16   1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     17   1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18   1.1  christos    GNU General Public License for more details.
     19   1.1  christos 
     20   1.1  christos    You should have received a copy of the GNU General Public License
     21   1.1  christos    along with this program; if not, write to the Free Software
     22   1.1  christos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     23   1.1  christos    MA 02110-1301, USA.  */
     24   1.1  christos 
     25   1.1  christos #include "sysdep.h"
     26   1.1  christos #include "bfd.h"
     27   1.1  christos #include "libbfd.h"
     28   1.1  christos #include "libiberty.h"
     29   1.1  christos #include "elf-bfd.h"
     30   1.1  christos #include "elf/score.h"
     31   1.1  christos #include "elf/common.h"
     32   1.1  christos #include "elf/internal.h"
     33   1.1  christos #include "hashtab.h"
     34   1.1  christos #include "elf32-score.h"
     35   1.1  christos 
     36   1.1  christos 
     37   1.1  christos int score3 = 0;
     38   1.1  christos int score7 = 1;
     39   1.1  christos 
     40   1.1  christos /* The SCORE ELF linker needs additional information for each symbol in
     41   1.1  christos    the global hash table.  */
     42   1.1  christos struct score_elf_link_hash_entry
     43   1.1  christos {
     44   1.1  christos   struct elf_link_hash_entry root;
     45   1.1  christos 
     46   1.1  christos   /* Number of R_SCORE_ABS32, R_SCORE_REL32 relocs against this symbol.  */
     47   1.1  christos   unsigned int possibly_dynamic_relocs;
     48   1.1  christos 
     49   1.1  christos   /* If the R_SCORE_ABS32, R_SCORE_REL32 reloc is against a readonly section.  */
     50  1.10  christos   bool readonly_reloc;
     51   1.1  christos 
     52   1.1  christos   /* We must not create a stub for a symbol that has relocations related to
     53   1.1  christos      taking the function's address, i.e. any but R_SCORE_CALL15 ones.  */
     54  1.10  christos   bool no_fn_stub;
     55   1.1  christos 
     56   1.1  christos   /* Are we forced local?  This will only be set if we have converted
     57   1.1  christos      the initial global GOT entry to a local GOT entry.  */
     58  1.10  christos   bool forced_local;
     59   1.1  christos };
     60   1.1  christos 
     61   1.1  christos /* Traverse a score ELF linker hash table.  */
     62   1.1  christos #define score_elf_link_hash_traverse(table, func, info) \
     63  1.10  christos   (elf_link_hash_traverse					\
     64  1.10  christos    ((table),							\
     65  1.10  christos     (bool (*) (struct elf_link_hash_entry *, void *)) (func),	\
     66   1.1  christos     (info)))
     67   1.1  christos 
     68   1.1  christos /* This structure is used to hold .got entries while estimating got sizes.  */
     69   1.1  christos struct score_got_entry
     70   1.1  christos {
     71   1.1  christos   /* The input bfd in which the symbol is defined.  */
     72   1.1  christos   bfd *abfd;
     73   1.1  christos   /* The index of the symbol, as stored in the relocation r_info, if
     74   1.1  christos      we have a local symbol; -1 otherwise.  */
     75   1.1  christos   long symndx;
     76   1.1  christos   union
     77   1.1  christos   {
     78   1.1  christos     /* If abfd == NULL, an address that must be stored in the got.  */
     79   1.1  christos     bfd_vma address;
     80   1.1  christos     /* If abfd != NULL && symndx != -1, the addend of the relocation
     81   1.1  christos        that should be added to the symbol value.  */
     82   1.1  christos     bfd_vma addend;
     83   1.1  christos     /* If abfd != NULL && symndx == -1, the hash table entry
     84   1.1  christos        corresponding to a global symbol in the got (or, local, if
     85   1.1  christos        h->forced_local).  */
     86   1.1  christos     struct score_elf_link_hash_entry *h;
     87   1.1  christos   } d;
     88   1.1  christos 
     89   1.1  christos   /* The offset from the beginning of the .got section to the entry
     90   1.1  christos      corresponding to this symbol+addend.  If it's a global symbol
     91   1.1  christos      whose offset is yet to be decided, it's going to be -1.  */
     92   1.1  christos   long gotidx;
     93   1.1  christos };
     94   1.1  christos 
     95   1.1  christos /* This structure is passed to score_elf_sort_hash_table_f when sorting
     96   1.1  christos    the dynamic symbols.  */
     97   1.1  christos 
     98   1.1  christos struct score_elf_hash_sort_data
     99   1.1  christos {
    100   1.1  christos   /* The symbol in the global GOT with the lowest dynamic symbol table index.  */
    101   1.1  christos   struct elf_link_hash_entry *low;
    102   1.1  christos   /* The least dynamic symbol table index corresponding to a symbol with a GOT entry.  */
    103   1.1  christos   long min_got_dynindx;
    104   1.1  christos   /* The greatest dynamic symbol table index corresponding to a symbol
    105   1.1  christos      with a GOT entry that is not referenced (e.g., a dynamic symbol
    106   1.1  christos      with dynamic relocations pointing to it from non-primary GOTs).  */
    107   1.1  christos   long max_unref_got_dynindx;
    108   1.1  christos   /* The greatest dynamic symbol table index not corresponding to a
    109   1.1  christos      symbol without a GOT entry.  */
    110   1.1  christos   long max_non_got_dynindx;
    111   1.1  christos };
    112   1.1  christos 
    113   1.1  christos struct score_got_info
    114   1.1  christos {
    115   1.1  christos   /* The global symbol in the GOT with the lowest index in the dynamic
    116   1.1  christos      symbol table.  */
    117   1.1  christos   struct elf_link_hash_entry *global_gotsym;
    118   1.1  christos   /* The number of global .got entries.  */
    119   1.1  christos   unsigned int global_gotno;
    120   1.1  christos   /* The number of local .got entries.  */
    121   1.1  christos   unsigned int local_gotno;
    122   1.1  christos   /* The number of local .got entries we have used.  */
    123   1.1  christos   unsigned int assigned_gotno;
    124   1.1  christos   /* A hash table holding members of the got.  */
    125   1.1  christos   struct htab *got_entries;
    126   1.1  christos   /* In multi-got links, a pointer to the next got (err, rather, most
    127   1.1  christos      of the time, it points to the previous got).  */
    128   1.1  christos   struct score_got_info *next;
    129   1.1  christos };
    130   1.1  christos 
    131   1.1  christos /* A structure used to count GOT entries, for GOT entry or ELF symbol table traversal.  */
    132   1.1  christos struct _score_elf_section_data
    133   1.1  christos {
    134   1.1  christos   struct bfd_elf_section_data elf;
    135   1.1  christos   union
    136   1.1  christos   {
    137   1.1  christos     struct score_got_info *got_info;
    138   1.1  christos     bfd_byte *tdata;
    139   1.1  christos   }
    140   1.1  christos   u;
    141   1.1  christos };
    142   1.1  christos 
    143   1.1  christos #define score_elf_section_data(sec) \
    144   1.1  christos   ((struct _score_elf_section_data *) elf_section_data (sec))
    145   1.1  christos 
    146   1.1  christos /* The size of a symbol-table entry.  */
    147   1.1  christos #define SCORE_ELF_SYM_SIZE(abfd)  \
    148   1.1  christos   (get_elf_backend_data (abfd)->s->sizeof_sym)
    149   1.1  christos 
    150   1.1  christos /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
    151   1.1  christos    from smaller values.  Start with zero, widen, *then* decrement.  */
    152   1.1  christos #define MINUS_ONE (((bfd_vma)0) - 1)
    153   1.1  christos #define MINUS_TWO (((bfd_vma)0) - 2)
    154   1.1  christos 
    155   1.1  christos #define PDR_SIZE 32
    156   1.1  christos 
    157   1.1  christos 
    158   1.1  christos /* The number of local .got entries we reserve.  */
    159   1.1  christos #define SCORE_RESERVED_GOTNO (2)
    160   1.1  christos #define ELF_DYNAMIC_INTERPRETER     "/usr/lib/ld.so.1"
    161   1.1  christos 
    162   1.1  christos /* The offset of $gp from the beginning of the .got section.  */
    163   1.1  christos #define ELF_SCORE_GP_OFFSET(abfd) (0x3ff0)
    164   1.1  christos /* The maximum size of the GOT for it to be addressable using 15-bit offsets from $gp.  */
    165   1.1  christos #define SCORE_ELF_GOT_MAX_SIZE(abfd) (ELF_SCORE_GP_OFFSET(abfd) + 0x3fff)
    166   1.1  christos 
    167   1.1  christos #define SCORE_ELF_STUB_SECTION_NAME  (".SCORE.stub")
    168   1.1  christos #define SCORE_FUNCTION_STUB_SIZE (16)
    169   1.1  christos 
    170   1.1  christos #define STUB_LW      0xc3bcc010     /* lw r29, [r28, -0x3ff0]  */
    171   1.1  christos #define STUB_MOVE    0x8363bc56     /* mv r27, r3  */
    172   1.1  christos #define STUB_LI16    0x87548000     /* ori r26, .dynsym_index  */
    173   1.1  christos #define STUB_BRL     0x801dbc09     /* brl r29  */
    174   1.1  christos 
    175   1.1  christos #define SCORE_ELF_GOT_SIZE(abfd)   \
    176   1.1  christos   (get_elf_backend_data (abfd)->s->arch_size / 8)
    177   1.1  christos 
    178   1.1  christos #define SCORE_ELF_ADD_DYNAMIC_ENTRY(info, tag, val) \
    179   1.8  christos 	(_bfd_elf_add_dynamic_entry (info, (bfd_vma) tag, (bfd_vma) val))
    180   1.1  christos 
    181   1.1  christos /* The size of an external dynamic table entry.  */
    182   1.1  christos #define SCORE_ELF_DYN_SIZE(abfd) \
    183   1.1  christos   (get_elf_backend_data (abfd)->s->sizeof_dyn)
    184   1.1  christos 
    185   1.1  christos /* The size of an external REL relocation.  */
    186   1.1  christos #define SCORE_ELF_REL_SIZE(abfd) \
    187   1.1  christos   (get_elf_backend_data (abfd)->s->sizeof_rel)
    188   1.1  christos 
    189   1.1  christos /* The default alignment for sections, as a power of two.  */
    190   1.1  christos #define SCORE_ELF_LOG_FILE_ALIGN(abfd)\
    191   1.1  christos   (get_elf_backend_data (abfd)->s->log_file_align)
    192   1.1  christos 
    193   1.1  christos static bfd_byte *hi16_rel_addr;
    194   1.1  christos 
    195   1.1  christos /* This will be used when we sort the dynamic relocation records.  */
    196   1.1  christos static bfd *reldyn_sorting_bfd;
    197   1.1  christos 
    198   1.1  christos /* SCORE ELF uses two common sections.  One is the usual one, and the
    199   1.1  christos    other is for small objects.  All the small objects are kept
    200   1.1  christos    together, and then referenced via the gp pointer, which yields
    201   1.1  christos    faster assembler code.  This is what we use for the small common
    202   1.1  christos    section.  This approach is copied from ecoff.c.  */
    203   1.1  christos static asection score_elf_scom_section;
    204  1.10  christos static const asymbol score_elf_scom_symbol =
    205  1.10  christos   GLOBAL_SYM_INIT (".scommon", &score_elf_scom_section);
    206  1.10  christos static asection score_elf_scom_section =
    207  1.10  christos   BFD_FAKE_SECTION (score_elf_scom_section, &score_elf_scom_symbol,
    208  1.10  christos 		    ".scommon", 0, SEC_IS_COMMON | SEC_SMALL_DATA);
    209   1.1  christos 
    210   1.1  christos static bfd_vma
    211   1.1  christos score_bfd_get_16 (bfd *abfd, const void *data)
    212   1.1  christos {
    213   1.1  christos   return bfd_get_16 (abfd, data);
    214   1.1  christos }
    215   1.1  christos 
    216   1.1  christos static bfd_vma
    217   1.1  christos score3_bfd_getl32 (const void *p)
    218   1.1  christos {
    219   1.1  christos   const bfd_byte *addr = p;
    220   1.1  christos   unsigned long v;
    221   1.1  christos 
    222   1.1  christos   v = (unsigned long) addr[2];
    223   1.1  christos   v |= (unsigned long) addr[3] << 8;
    224   1.1  christos   v |= (unsigned long) addr[0] << 16;
    225   1.1  christos   v |= (unsigned long) addr[1] << 24;
    226   1.1  christos   return v;
    227   1.1  christos }
    228   1.1  christos 
    229   1.1  christos static bfd_vma
    230   1.1  christos score3_bfd_getl48 (const void *p)
    231   1.1  christos {
    232   1.1  christos   const bfd_byte *addr = p;
    233  1.10  christos   uint64_t v;
    234   1.1  christos 
    235  1.10  christos   v = (uint64_t) addr[4];
    236  1.10  christos   v |= (uint64_t) addr[5] << 8;
    237  1.10  christos   v |= (uint64_t) addr[2] << 16;
    238  1.10  christos   v |= (uint64_t) addr[3] << 24;
    239  1.10  christos   v |= (uint64_t) addr[0] << 32;
    240  1.10  christos   v |= (uint64_t) addr[1] << 40;
    241   1.1  christos   return v;
    242   1.1  christos }
    243   1.1  christos 
    244   1.1  christos static bfd_vma
    245   1.1  christos score_bfd_get_32 (bfd *abfd, const void *data)
    246   1.1  christos {
    247   1.1  christos   if (/* score3 && */ abfd->xvec->byteorder == BFD_ENDIAN_LITTLE)
    248   1.1  christos     return score3_bfd_getl32 (data);
    249   1.1  christos   else
    250   1.1  christos     return bfd_get_32 (abfd, data);
    251   1.1  christos }
    252   1.1  christos 
    253   1.1  christos static bfd_vma
    254   1.1  christos score_bfd_get_48 (bfd *abfd, const void *p)
    255   1.1  christos {
    256   1.1  christos   if (/* score3 && */ abfd->xvec->byteorder == BFD_ENDIAN_LITTLE)
    257   1.1  christos     return score3_bfd_getl48 (p);
    258   1.1  christos   else
    259   1.1  christos     return bfd_get_bits (p, 48, 1);
    260   1.1  christos }
    261   1.1  christos 
    262   1.1  christos static void
    263   1.1  christos score_bfd_put_16 (bfd *abfd, bfd_vma addr, void *data)
    264   1.1  christos {
    265   1.1  christos   return bfd_put_16 (abfd, addr, data);
    266   1.1  christos }
    267   1.1  christos 
    268   1.1  christos static void
    269   1.1  christos score3_bfd_putl32 (bfd_vma data, void *p)
    270   1.1  christos {
    271   1.1  christos   bfd_byte *addr = p;
    272   1.1  christos   addr[0] = (data >> 16) & 0xff;
    273   1.1  christos   addr[1] = (data >> 24) & 0xff;
    274   1.1  christos   addr[2] = data & 0xff;
    275   1.1  christos   addr[3] = (data >>  8) & 0xff;
    276   1.1  christos }
    277   1.1  christos 
    278   1.1  christos static void
    279   1.1  christos score3_bfd_putl48 (bfd_vma data, void *p)
    280   1.1  christos {
    281   1.1  christos   bfd_byte *addr = p;
    282   1.1  christos   addr[0] = (data >> 32) & 0xff;
    283   1.1  christos   addr[1] = (data >> 40) & 0xff;
    284   1.1  christos   addr[2] = (data >> 16) & 0xff;
    285   1.1  christos   addr[3] = (data >> 24) & 0xff;
    286   1.1  christos   addr[4] = data & 0xff;
    287   1.1  christos   addr[5] = (data >>  8) & 0xff;
    288   1.1  christos }
    289   1.1  christos 
    290   1.1  christos static void
    291   1.1  christos score_bfd_put_32 (bfd *abfd, bfd_vma addr, void *data)
    292   1.1  christos {
    293   1.1  christos   if (/* score3 && */ abfd->xvec->byteorder == BFD_ENDIAN_LITTLE)
    294   1.1  christos     return score3_bfd_putl32 (addr, data);
    295   1.1  christos   else
    296   1.1  christos     return bfd_put_32 (abfd, addr, data);
    297   1.1  christos }
    298   1.1  christos 
    299   1.1  christos static void
    300   1.1  christos score_bfd_put_48 (bfd *abfd, bfd_vma val, void *p)
    301   1.1  christos {
    302   1.1  christos   if (/* score3 && */ abfd->xvec->byteorder == BFD_ENDIAN_LITTLE)
    303   1.1  christos     return score3_bfd_putl48 (val, p);
    304   1.1  christos   else
    305   1.1  christos     return bfd_put_bits (val, p, 48, 1);
    306   1.1  christos }
    307   1.1  christos 
    308   1.1  christos static bfd_reloc_status_type
    309   1.1  christos score_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED,
    310   1.8  christos 		      arelent *reloc_entry,
    311   1.8  christos 		      asymbol *symbol ATTRIBUTE_UNUSED,
    312   1.8  christos 		      void * data,
    313   1.8  christos 		      asection *input_section ATTRIBUTE_UNUSED,
    314   1.8  christos 		      bfd *output_bfd ATTRIBUTE_UNUSED,
    315   1.8  christos 		      char **error_message ATTRIBUTE_UNUSED)
    316   1.1  christos {
    317   1.1  christos   hi16_rel_addr = (bfd_byte *) data + reloc_entry->address;
    318   1.1  christos   return bfd_reloc_ok;
    319   1.1  christos }
    320   1.1  christos 
    321   1.1  christos static bfd_reloc_status_type
    322   1.1  christos score_elf_lo16_reloc (bfd *abfd,
    323   1.8  christos 		      arelent *reloc_entry,
    324   1.8  christos 		      asymbol *symbol ATTRIBUTE_UNUSED,
    325   1.8  christos 		      void * data,
    326   1.8  christos 		      asection *input_section,
    327   1.8  christos 		      bfd *output_bfd ATTRIBUTE_UNUSED,
    328   1.8  christos 		      char **error_message ATTRIBUTE_UNUSED)
    329   1.1  christos {
    330   1.1  christos   bfd_vma addend = 0, offset = 0;
    331   1.1  christos   unsigned long val;
    332   1.1  christos   unsigned long hi16_offset, hi16_value, uvalue;
    333   1.1  christos 
    334   1.1  christos   hi16_value = score_bfd_get_32 (abfd, hi16_rel_addr);
    335   1.1  christos   hi16_offset = ((((hi16_value >> 16) & 0x3) << 15) | (hi16_value & 0x7fff)) >> 1;
    336   1.1  christos   addend = score_bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
    337   1.1  christos   offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
    338   1.1  christos   val = reloc_entry->addend;
    339   1.1  christos   if (reloc_entry->address > input_section->size)
    340   1.1  christos     return bfd_reloc_outofrange;
    341   1.1  christos   uvalue = ((hi16_offset << 16) | (offset & 0xffff)) + val;
    342   1.1  christos   hi16_offset = (uvalue >> 16) << 1;
    343   1.1  christos   hi16_value = (hi16_value & ~0x37fff) | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
    344   1.1  christos   score_bfd_put_32 (abfd, hi16_value, hi16_rel_addr);
    345   1.1  christos   offset = (uvalue & 0xffff) << 1;
    346   1.1  christos   addend = (addend & ~0x37fff) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
    347   1.1  christos   score_bfd_put_32 (abfd, addend, (bfd_byte *) data + reloc_entry->address);
    348   1.1  christos   return bfd_reloc_ok;
    349   1.1  christos }
    350   1.1  christos 
    351   1.1  christos /* Set the GP value for OUTPUT_BFD.  Returns FALSE if this is a
    352   1.1  christos    dangerous relocation.  */
    353   1.1  christos 
    354  1.10  christos static bool
    355   1.1  christos score_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
    356   1.1  christos {
    357   1.1  christos   unsigned int count;
    358   1.1  christos   asymbol **sym;
    359   1.1  christos   unsigned int i;
    360   1.1  christos 
    361   1.1  christos   /* If we've already figured out what GP will be, just return it.  */
    362   1.1  christos   *pgp = _bfd_get_gp_value (output_bfd);
    363   1.1  christos   if (*pgp)
    364  1.10  christos     return true;
    365   1.1  christos 
    366   1.1  christos   count = bfd_get_symcount (output_bfd);
    367   1.1  christos   sym = bfd_get_outsymbols (output_bfd);
    368   1.1  christos 
    369   1.1  christos   /* The linker script will have created a symbol named `_gp' with the
    370   1.1  christos      appropriate value.  */
    371   1.1  christos   if (sym == NULL)
    372   1.1  christos     i = count;
    373   1.1  christos   else
    374   1.1  christos     {
    375   1.1  christos       for (i = 0; i < count; i++, sym++)
    376   1.8  christos 	{
    377   1.8  christos 	  const char *name;
    378   1.1  christos 
    379   1.8  christos 	  name = bfd_asymbol_name (*sym);
    380   1.8  christos 	  if (*name == '_' && strcmp (name, "_gp") == 0)
    381   1.8  christos 	    {
    382   1.8  christos 	      *pgp = bfd_asymbol_value (*sym);
    383   1.8  christos 	      _bfd_set_gp_value (output_bfd, *pgp);
    384   1.8  christos 	      break;
    385   1.8  christos 	    }
    386   1.8  christos 	}
    387   1.1  christos     }
    388   1.1  christos 
    389   1.1  christos   if (i >= count)
    390   1.1  christos     {
    391   1.1  christos       /* Only get the error once.  */
    392   1.1  christos       *pgp = 4;
    393   1.1  christos       _bfd_set_gp_value (output_bfd, *pgp);
    394  1.10  christos       return false;
    395   1.1  christos     }
    396   1.1  christos 
    397  1.10  christos   return true;
    398   1.1  christos }
    399   1.1  christos 
    400   1.1  christos /* We have to figure out the gp value, so that we can adjust the
    401   1.1  christos    symbol value correctly.  We look up the symbol _gp in the output
    402   1.1  christos    BFD.  If we can't find it, we're stuck.  We cache it in the ELF
    403   1.1  christos    target data.  We don't need to adjust the symbol value for an
    404   1.1  christos    external symbol if we are producing relocatable output.  */
    405   1.1  christos static bfd_reloc_status_type
    406   1.1  christos score_elf_final_gp (bfd *output_bfd,
    407   1.8  christos 		    asymbol *symbol,
    408  1.10  christos 		    bool relocatable,
    409   1.8  christos 		     char **error_message,
    410   1.8  christos 		    bfd_vma *pgp)
    411   1.1  christos {
    412   1.1  christos   if (bfd_is_und_section (symbol->section)
    413   1.1  christos       && ! relocatable)
    414   1.1  christos     {
    415   1.1  christos       *pgp = 0;
    416   1.1  christos       return bfd_reloc_undefined;
    417   1.1  christos     }
    418   1.1  christos 
    419   1.1  christos   *pgp = _bfd_get_gp_value (output_bfd);
    420   1.1  christos   if (*pgp == 0
    421   1.1  christos       && (! relocatable
    422   1.8  christos 	  || (symbol->flags & BSF_SECTION_SYM) != 0))
    423   1.1  christos     {
    424   1.1  christos       if (relocatable)
    425   1.8  christos 	{
    426   1.8  christos 	  /* Make up a value.  */
    427   1.8  christos 	  *pgp = symbol->section->output_section->vma + 0x4000;
    428   1.8  christos 	  _bfd_set_gp_value (output_bfd, *pgp);
    429   1.8  christos 	}
    430   1.1  christos       else if (!score_elf_assign_gp (output_bfd, pgp))
    431   1.8  christos 	{
    432   1.8  christos 	    *error_message =
    433   1.8  christos 	      (char *) _("GP relative relocation when _gp not defined");
    434   1.8  christos 	    return bfd_reloc_dangerous;
    435   1.8  christos 	}
    436   1.1  christos     }
    437   1.1  christos 
    438   1.1  christos   return bfd_reloc_ok;
    439   1.1  christos }
    440   1.1  christos 
    441   1.1  christos static bfd_reloc_status_type
    442   1.1  christos score_elf_gprel15_with_gp (bfd *abfd,
    443   1.8  christos 			   arelent *reloc_entry,
    444   1.8  christos 			   asection *input_section,
    445  1.10  christos 			   bool relocateable,
    446   1.8  christos 			   void * data,
    447   1.8  christos 			   bfd_vma gp ATTRIBUTE_UNUSED)
    448   1.1  christos {
    449   1.1  christos   unsigned long insn;
    450   1.1  christos 
    451   1.1  christos   if (reloc_entry->address > input_section->size)
    452   1.1  christos     return bfd_reloc_outofrange;
    453   1.1  christos 
    454   1.1  christos   insn = score_bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
    455   1.1  christos   if (((reloc_entry->addend & 0xffffc000) != 0)
    456   1.1  christos       && ((reloc_entry->addend & 0xffffc000) != 0xffffc000))
    457   1.1  christos     return bfd_reloc_overflow;
    458   1.1  christos 
    459   1.1  christos   insn = (insn & ~0x7fff) | (reloc_entry->addend & 0x7fff);
    460   1.1  christos   score_bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
    461   1.1  christos   if (relocateable)
    462   1.1  christos     reloc_entry->address += input_section->output_offset;
    463   1.1  christos 
    464   1.1  christos   return bfd_reloc_ok;
    465   1.1  christos }
    466   1.1  christos 
    467   1.1  christos static bfd_reloc_status_type
    468   1.1  christos gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
    469  1.10  christos 		 asection *input_section, bool relocatable,
    470   1.8  christos 		 void *data, bfd_vma gp)
    471   1.1  christos {
    472   1.1  christos   bfd_vma relocation;
    473   1.1  christos   bfd_vma val;
    474   1.1  christos 
    475   1.1  christos   if (bfd_is_com_section (symbol->section))
    476   1.1  christos     relocation = 0;
    477   1.1  christos   else
    478   1.1  christos     relocation = symbol->value;
    479   1.1  christos 
    480   1.1  christos   relocation += symbol->section->output_section->vma;
    481   1.1  christos   relocation += symbol->section->output_offset;
    482   1.1  christos 
    483   1.1  christos   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
    484   1.1  christos     return bfd_reloc_outofrange;
    485   1.1  christos 
    486   1.1  christos   /* Set val to the offset into the section or symbol.  */
    487   1.1  christos   val = reloc_entry->addend;
    488   1.1  christos 
    489   1.1  christos   if (reloc_entry->howto->partial_inplace)
    490   1.1  christos     val += score_bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
    491   1.1  christos 
    492   1.1  christos   /* Adjust val for the final section location and GP value.  If we
    493   1.1  christos      are producing relocatable output, we don't want to do this for
    494   1.1  christos      an external symbol.  */
    495   1.1  christos   if (! relocatable
    496   1.1  christos       || (symbol->flags & BSF_SECTION_SYM) != 0)
    497   1.1  christos     val += relocation - gp;
    498   1.1  christos 
    499   1.1  christos   if (reloc_entry->howto->partial_inplace)
    500   1.1  christos     score_bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
    501   1.1  christos   else
    502   1.1  christos     reloc_entry->addend = val;
    503   1.1  christos 
    504   1.1  christos   if (relocatable)
    505   1.1  christos     reloc_entry->address += input_section->output_offset;
    506   1.1  christos 
    507   1.1  christos   return bfd_reloc_ok;
    508   1.1  christos }
    509   1.1  christos 
    510   1.1  christos static bfd_reloc_status_type
    511   1.1  christos score_elf_gprel15_reloc (bfd *abfd,
    512   1.8  christos 			 arelent *reloc_entry,
    513   1.8  christos 			 asymbol *symbol,
    514   1.8  christos 			 void * data,
    515   1.8  christos 			 asection *input_section,
    516   1.8  christos 			 bfd *output_bfd,
    517   1.8  christos 			 char **error_message)
    518   1.1  christos {
    519  1.10  christos   bool relocateable;
    520   1.1  christos   bfd_reloc_status_type ret;
    521   1.1  christos   bfd_vma gp;
    522   1.1  christos 
    523   1.1  christos   if (output_bfd != NULL
    524   1.1  christos       && (symbol->flags & BSF_SECTION_SYM) == 0 && reloc_entry->addend == 0)
    525   1.1  christos     {
    526   1.1  christos       reloc_entry->address += input_section->output_offset;
    527   1.1  christos       return bfd_reloc_ok;
    528   1.1  christos     }
    529   1.1  christos   if (output_bfd != NULL)
    530  1.10  christos     relocateable = true;
    531   1.1  christos   else
    532   1.1  christos     {
    533  1.10  christos       relocateable = false;
    534   1.1  christos       output_bfd = symbol->section->output_section->owner;
    535   1.1  christos     }
    536   1.1  christos 
    537   1.1  christos   ret = score_elf_final_gp (output_bfd, symbol, relocateable, error_message, &gp);
    538   1.1  christos   if (ret != bfd_reloc_ok)
    539   1.1  christos     return ret;
    540   1.1  christos 
    541  1.10  christos   return score_elf_gprel15_with_gp (abfd, reloc_entry,
    542  1.10  christos 				    input_section, relocateable, data, gp);
    543   1.1  christos }
    544   1.1  christos 
    545   1.1  christos /* Do a R_SCORE_GPREL32 relocation.  This is a 32 bit value which must
    546   1.1  christos    become the offset from the gp register.  */
    547   1.1  christos 
    548   1.1  christos static bfd_reloc_status_type
    549   1.1  christos score_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
    550   1.8  christos 			void *data, asection *input_section, bfd *output_bfd,
    551   1.8  christos 			char **error_message)
    552   1.1  christos {
    553  1.10  christos   bool relocatable;
    554   1.1  christos   bfd_reloc_status_type ret;
    555   1.1  christos   bfd_vma gp;
    556   1.1  christos 
    557   1.1  christos   /* R_SCORE_GPREL32 relocations are defined for local symbols only.  */
    558   1.1  christos   if (output_bfd != NULL
    559   1.1  christos       && (symbol->flags & BSF_SECTION_SYM) == 0
    560   1.1  christos       && (symbol->flags & BSF_LOCAL) != 0)
    561   1.1  christos     {
    562   1.1  christos       *error_message = (char *)
    563   1.8  christos 	_("32bits gp relative relocation occurs for an external symbol");
    564   1.1  christos       return bfd_reloc_outofrange;
    565   1.1  christos     }
    566   1.1  christos 
    567   1.1  christos   if (output_bfd != NULL)
    568  1.10  christos     relocatable = true;
    569   1.1  christos   else
    570   1.1  christos     {
    571  1.10  christos       relocatable = false;
    572   1.1  christos       output_bfd = symbol->section->output_section->owner;
    573   1.1  christos     }
    574   1.1  christos 
    575   1.1  christos   ret = score_elf_final_gp (output_bfd, symbol, relocatable, error_message, &gp);
    576   1.1  christos   if (ret != bfd_reloc_ok)
    577   1.1  christos     return ret;
    578   1.1  christos 
    579   1.1  christos   gp = 0;
    580   1.1  christos   return gprel32_with_gp (abfd, symbol, reloc_entry, input_section,
    581   1.8  christos 			  relocatable, data, gp);
    582   1.1  christos }
    583   1.1  christos 
    584   1.1  christos /* A howto special_function for R_SCORE_GOT15 relocations.  This is just
    585   1.1  christos    like any other 16-bit relocation when applied to global symbols, but is
    586   1.1  christos    treated in the same as R_SCORE_HI16 when applied to local symbols.  */
    587   1.1  christos static bfd_reloc_status_type
    588   1.1  christos score_elf_got15_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
    589   1.8  christos 		       void *data, asection *input_section,
    590   1.8  christos 		       bfd *output_bfd, char **error_message)
    591   1.1  christos {
    592   1.1  christos   if ((symbol->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
    593   1.9  christos       || bfd_is_und_section (bfd_asymbol_section (symbol))
    594   1.9  christos       || bfd_is_com_section (bfd_asymbol_section (symbol)))
    595   1.1  christos     /* The relocation is against a global symbol.  */
    596   1.1  christos     return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
    597   1.8  christos 				  input_section, output_bfd,
    598   1.8  christos 				  error_message);
    599   1.1  christos 
    600   1.1  christos   return score_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
    601   1.8  christos 			       input_section, output_bfd, error_message);
    602   1.1  christos }
    603   1.1  christos 
    604   1.1  christos static bfd_reloc_status_type
    605   1.1  christos score_elf_got_lo16_reloc (bfd *abfd,
    606   1.8  christos 			  arelent *reloc_entry,
    607   1.8  christos 			  asymbol *symbol ATTRIBUTE_UNUSED,
    608   1.8  christos 			  void * data,
    609   1.8  christos 			  asection *input_section,
    610   1.8  christos 			  bfd *output_bfd ATTRIBUTE_UNUSED,
    611   1.8  christos 			  char **error_message ATTRIBUTE_UNUSED)
    612   1.1  christos {
    613   1.1  christos   bfd_vma addend = 0, offset = 0;
    614   1.1  christos   signed long val;
    615   1.1  christos   signed long hi16_offset, hi16_value, uvalue;
    616   1.1  christos 
    617   1.1  christos   hi16_value = score_bfd_get_32 (abfd, hi16_rel_addr);
    618   1.1  christos   hi16_offset = ((((hi16_value >> 16) & 0x3) << 15) | (hi16_value & 0x7fff)) >> 1;
    619   1.1  christos   addend = score_bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
    620   1.1  christos   offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
    621   1.1  christos   val = reloc_entry->addend;
    622   1.1  christos   if (reloc_entry->address > input_section->size)
    623   1.1  christos     return bfd_reloc_outofrange;
    624   1.1  christos   uvalue = ((hi16_offset << 16) | (offset & 0xffff)) + val;
    625   1.1  christos   if ((uvalue > -0x8000) && (uvalue < 0x7fff))
    626   1.1  christos     hi16_offset = 0;
    627   1.1  christos   else
    628   1.1  christos     hi16_offset = (uvalue >> 16) & 0x7fff;
    629   1.1  christos   hi16_value = (hi16_value & ~0x37fff) | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
    630   1.1  christos   score_bfd_put_32 (abfd, hi16_value, hi16_rel_addr);
    631   1.1  christos   offset = (uvalue & 0xffff) << 1;
    632   1.1  christos   addend = (addend & ~0x37fff) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
    633   1.1  christos   score_bfd_put_32 (abfd, addend, (bfd_byte *) data + reloc_entry->address);
    634   1.1  christos   return bfd_reloc_ok;
    635   1.1  christos }
    636   1.1  christos 
    637   1.1  christos static reloc_howto_type elf32_score_howto_table[] =
    638   1.1  christos {
    639   1.1  christos   /* No relocation.  */
    640   1.8  christos   HOWTO (R_SCORE_NONE,		/* type */
    641   1.8  christos 	 0,			/* rightshift */
    642  1.10  christos 	 0,			/* size */
    643   1.8  christos 	 0,			/* bitsize */
    644  1.10  christos 	 false,			/* pc_relative */
    645   1.8  christos 	 0,			/* bitpos */
    646   1.8  christos 	 complain_overflow_dont,/* complain_on_overflow */
    647   1.8  christos 	 bfd_elf_generic_reloc, /* special_function */
    648   1.8  christos 	 "R_SCORE_NONE",	/* name */
    649  1.10  christos 	 false,			/* partial_inplace */
    650   1.8  christos 	 0,			/* src_mask */
    651   1.8  christos 	 0,			/* dst_mask */
    652  1.10  christos 	 false),		/* pcrel_offset */
    653   1.1  christos 
    654   1.1  christos   /* R_SCORE_HI16 */
    655   1.8  christos   HOWTO (R_SCORE_HI16,		/* type */
    656   1.8  christos 	 0,			/* rightshift */
    657  1.10  christos 	 4,			/* size */
    658   1.8  christos 	 16,			/* bitsize */
    659  1.10  christos 	 false,			/* pc_relative */
    660   1.8  christos 	 1,			/* bitpos */
    661   1.8  christos 	 complain_overflow_dont,/* complain_on_overflow */
    662   1.8  christos 	 score_elf_hi16_reloc,	/* special_function */
    663   1.8  christos 	 "R_SCORE_HI16",	/* name */
    664  1.10  christos 	 true,			/* partial_inplace */
    665   1.8  christos 	 0x37fff,		/* src_mask */
    666   1.8  christos 	 0x37fff,		/* dst_mask */
    667  1.10  christos 	 false),		/* pcrel_offset */
    668   1.1  christos 
    669   1.1  christos   /* R_SCORE_LO16 */
    670   1.8  christos   HOWTO (R_SCORE_LO16,		/* type */
    671   1.8  christos 	 0,			/* rightshift */
    672  1.10  christos 	 4,			/* size */
    673   1.8  christos 	 16,			/* bitsize */
    674  1.10  christos 	 false,			/* pc_relative */
    675   1.8  christos 	 1,			/* bitpos */
    676   1.8  christos 	 complain_overflow_dont,/* complain_on_overflow */
    677   1.8  christos 	 score_elf_lo16_reloc,	/* special_function */
    678   1.8  christos 	 "R_SCORE_LO16",	/* name */
    679  1.10  christos 	 true,			/* partial_inplace */
    680   1.8  christos 	 0x37fff,		/* src_mask */
    681   1.8  christos 	 0x37fff,		/* dst_mask */
    682  1.10  christos 	 false),		/* pcrel_offset */
    683   1.1  christos 
    684   1.1  christos   /*  R_SCORE_BCMP */
    685   1.8  christos   HOWTO (R_SCORE_BCMP,		/* type */
    686   1.8  christos 	 1,			/* rightshift */
    687  1.10  christos 	 4,			/* size */
    688   1.8  christos 	 16,			/* bitsize */
    689  1.10  christos 	 true,			/* pc_relative */
    690   1.8  christos 	 1,			/* bitpos */
    691   1.8  christos 	 complain_overflow_dont,/* complain_on_overflow */
    692   1.8  christos 	 bfd_elf_generic_reloc, /* special_function */
    693   1.8  christos 	 "R_SCORE_BCMP",	/* name */
    694  1.10  christos 	 false,			/* partial_inplace */
    695   1.8  christos 	 0x03e00381,		/* src_mask */
    696   1.8  christos 	 0x03e00381,		/* dst_mask */
    697  1.10  christos 	 false),		/* pcrel_offset */
    698   1.1  christos 
    699   1.1  christos   /*R_SCORE_24 */
    700   1.8  christos   HOWTO (R_SCORE_24,		/* type */
    701   1.8  christos 	 1,			/* rightshift */
    702  1.10  christos 	 4,			/* size */
    703   1.8  christos 	 24,			/* bitsize */
    704  1.10  christos 	 false,			/* pc_relative */
    705   1.8  christos 	 1,			/* bitpos */
    706   1.8  christos 	 complain_overflow_dont,/* complain_on_overflow */
    707   1.8  christos 	 bfd_elf_generic_reloc, /* special_function */
    708   1.8  christos 	 "R_SCORE_24",		/* name */
    709  1.10  christos 	 false,			/* partial_inplace */
    710   1.8  christos 	 0x3ff7fff,		/* src_mask */
    711   1.8  christos 	 0x3ff7fff,		/* dst_mask */
    712  1.10  christos 	 false),		/* pcrel_offset */
    713   1.1  christos 
    714   1.1  christos   /*R_SCORE_PC19 */
    715   1.8  christos   HOWTO (R_SCORE_PC19,		/* type */
    716   1.8  christos 	 1,			/* rightshift */
    717  1.10  christos 	 4,			/* size */
    718   1.8  christos 	 19,			/* bitsize */
    719  1.10  christos 	 true,			/* pc_relative */
    720   1.8  christos 	 1,			/* bitpos */
    721   1.8  christos 	 complain_overflow_dont,/* complain_on_overflow */
    722   1.8  christos 	 bfd_elf_generic_reloc, /* special_function */
    723   1.8  christos 	 "R_SCORE_PC19",	/* name */
    724  1.10  christos 	 false,			/* partial_inplace */
    725   1.8  christos 	 0x3ff03fe,		/* src_mask */
    726   1.8  christos 	 0x3ff03fe,		/* dst_mask */
    727  1.10  christos 	 false),		/* pcrel_offset */
    728   1.1  christos 
    729   1.1  christos   /*R_SCORE16_11 */
    730   1.8  christos   HOWTO (R_SCORE16_11,		/* type */
    731   1.8  christos 	 1,			/* rightshift */
    732  1.10  christos 	 2,			/* size */
    733   1.8  christos 	 11,			/* bitsize */
    734  1.10  christos 	 false,			/* pc_relative */
    735   1.8  christos 	 1,			/* bitpos */
    736   1.8  christos 	 complain_overflow_dont,/* complain_on_overflow */
    737   1.8  christos 	 bfd_elf_generic_reloc, /* special_function */
    738   1.8  christos 	 "R_SCORE16_11",	/* name */
    739  1.10  christos 	 false,			/* partial_inplace */
    740   1.8  christos 	 0x000000ffe,		/* src_mask */
    741   1.8  christos 	 0x000000ffe,		/* dst_mask */
    742  1.10  christos 	 false),		/* pcrel_offset */
    743   1.1  christos 
    744   1.1  christos   /* R_SCORE16_PC8 */
    745   1.8  christos   HOWTO (R_SCORE16_PC8,		/* type */
    746   1.8  christos 	 1,			/* rightshift */
    747  1.10  christos 	 2,			/* size */
    748   1.8  christos 	 9,			/* bitsize */
    749  1.10  christos 	 true,			/* pc_relative */
    750   1.8  christos 	 0,			/* bitpos */
    751   1.8  christos 	 complain_overflow_dont,/* complain_on_overflow */
    752   1.8  christos 	 bfd_elf_generic_reloc, /* special_function */
    753   1.8  christos 	 "R_SCORE16_PC8",	/* name */
    754  1.10  christos 	 false,			/* partial_inplace */
    755   1.8  christos 	 0x000001ff,		/* src_mask */
    756   1.8  christos 	 0x000001ff,		/* dst_mask */
    757  1.10  christos 	 false),		/* pcrel_offset */
    758   1.1  christos 
    759   1.1  christos   /* 32 bit absolute */
    760   1.8  christos   HOWTO (R_SCORE_ABS32,		/* type	 8 */
    761   1.8  christos 	 0,			/* rightshift */
    762  1.10  christos 	 4,			/* size */
    763   1.8  christos 	 32,			/* bitsize */
    764  1.10  christos 	 false,			/* pc_relative */
    765   1.8  christos 	 0,			/* bitpos */
    766   1.8  christos 	 complain_overflow_bitfield,	/* complain_on_overflow */
    767   1.8  christos 	 bfd_elf_generic_reloc, /* special_function */
    768   1.8  christos 	 "R_SCORE_ABS32",	/* name */
    769  1.10  christos 	 false,			/* partial_inplace */
    770   1.8  christos 	 0xffffffff,		/* src_mask */
    771   1.8  christos 	 0xffffffff,		/* dst_mask */
    772  1.10  christos 	 false),		/* pcrel_offset */
    773   1.1  christos 
    774   1.1  christos   /* 16 bit absolute */
    775   1.8  christos   HOWTO (R_SCORE_ABS16,		/* type 11 */
    776   1.8  christos 	 0,			/* rightshift */
    777  1.10  christos 	 2,			/* size */
    778   1.8  christos 	 16,			/* bitsize */
    779  1.10  christos 	 false,			/* pc_relative */
    780   1.8  christos 	 0,			/* bitpos */
    781   1.8  christos 	 complain_overflow_bitfield,	/* complain_on_overflow */
    782   1.8  christos 	 bfd_elf_generic_reloc, /* special_function */
    783   1.8  christos 	 "R_SCORE_ABS16",	/* name */
    784  1.10  christos 	 false,			/* partial_inplace */
    785   1.8  christos 	 0x0000ffff,		/* src_mask */
    786   1.8  christos 	 0x0000ffff,		/* dst_mask */
    787  1.10  christos 	 false),		/* pcrel_offset */
    788   1.1  christos 
    789   1.1  christos   /* R_SCORE_DUMMY2 */
    790   1.8  christos   HOWTO (R_SCORE_DUMMY2,	/* type */
    791   1.8  christos 	 0,			/* rightshift */
    792  1.10  christos 	 4,			/* size */
    793   1.8  christos 	 16,			/* bitsize */
    794  1.10  christos 	 false,			/* pc_relative */
    795   1.8  christos 	 0,			/* bitpos */
    796   1.8  christos 	 complain_overflow_dont,/* complain_on_overflow */
    797   1.8  christos 	 bfd_elf_generic_reloc, /* special_function */
    798   1.8  christos 	 "R_SCORE_DUMMY2",	/* name */
    799  1.10  christos 	 true,			/* partial_inplace */
    800   1.8  christos 	 0x00007fff,		/* src_mask */
    801   1.8  christos 	 0x00007fff,		/* dst_mask */
    802  1.10  christos 	 false),		/* pcrel_offset */
    803   1.1  christos 
    804   1.1  christos   /* R_SCORE_GP15 */
    805   1.8  christos   HOWTO (R_SCORE_GP15,		/* type */
    806   1.8  christos 	 0,			/* rightshift */
    807  1.10  christos 	 4,			/* size */
    808   1.8  christos 	 16,			/* bitsize */
    809  1.10  christos 	 false,			/* pc_relative */
    810   1.8  christos 	 0,			/* bitpos */
    811   1.8  christos 	 complain_overflow_dont,/* complain_on_overflow */
    812   1.8  christos 	 score_elf_gprel15_reloc,/* special_function */
    813   1.8  christos 	 "R_SCORE_GP15",	/* name */
    814  1.10  christos 	 true,			/* partial_inplace */
    815   1.8  christos 	 0x00007fff,		/* src_mask */
    816   1.8  christos 	 0x00007fff,		/* dst_mask */
    817  1.10  christos 	 false),		/* pcrel_offset */
    818   1.1  christos 
    819   1.1  christos   /* GNU extension to record C++ vtable hierarchy.  */
    820   1.1  christos   HOWTO (R_SCORE_GNU_VTINHERIT, /* type */
    821   1.8  christos 	 0,			/* rightshift */
    822  1.10  christos 	 4,			/* size */
    823   1.8  christos 	 0,			/* bitsize */
    824  1.10  christos 	 false,			/* pc_relative */
    825   1.8  christos 	 0,			/* bitpos */
    826   1.8  christos 	 complain_overflow_dont,/* complain_on_overflow */
    827   1.8  christos 	 NULL,			/* special_function */
    828   1.8  christos 	 "R_SCORE_GNU_VTINHERIT",	/* name */
    829  1.10  christos 	 false,			/* partial_inplace */
    830   1.8  christos 	 0,			/* src_mask */
    831   1.8  christos 	 0,			/* dst_mask */
    832  1.10  christos 	 false),		/* pcrel_offset */
    833   1.1  christos 
    834   1.1  christos   /* GNU extension to record C++ vtable member usage */
    835   1.8  christos   HOWTO (R_SCORE_GNU_VTENTRY,	/* type */
    836   1.8  christos 	 0,			/* rightshift */
    837  1.10  christos 	 4,			/* size */
    838   1.8  christos 	 0,			/* bitsize */
    839  1.10  christos 	 false,			/* pc_relative */
    840   1.8  christos 	 0,			/* bitpos */
    841   1.8  christos 	 complain_overflow_dont,/* complain_on_overflow */
    842   1.8  christos 	 _bfd_elf_rel_vtable_reloc_fn,	/* special_function */
    843   1.8  christos 	 "R_SCORE_GNU_VTENTRY", /* name */
    844  1.10  christos 	 false,			/* partial_inplace */
    845   1.8  christos 	 0,			/* src_mask */
    846   1.8  christos 	 0,			/* dst_mask */
    847  1.10  christos 	 false),		/* pcrel_offset */
    848   1.1  christos 
    849   1.1  christos   /* Reference to global offset table.  */
    850   1.8  christos   HOWTO (R_SCORE_GOT15,		/* type */
    851   1.8  christos 	 0,			/* rightshift */
    852  1.10  christos 	 4,			/* size */
    853   1.8  christos 	 16,			/* bitsize */
    854  1.10  christos 	 false,			/* pc_relative */
    855   1.8  christos 	 0,			/* bitpos */
    856   1.8  christos 	 complain_overflow_signed,	/* complain_on_overflow */
    857   1.8  christos 	 score_elf_got15_reloc, /* special_function */
    858   1.8  christos 	 "R_SCORE_GOT15",	/* name */
    859  1.10  christos 	 true,			/* partial_inplace */
    860   1.8  christos 	 0x00007fff,		/* src_mask */
    861   1.8  christos 	 0x00007fff,		/* dst_mask */
    862  1.10  christos 	 false),		/* pcrel_offset */
    863   1.1  christos 
    864   1.1  christos   /* Low 16 bits of displacement in global offset table.  */
    865   1.8  christos   HOWTO (R_SCORE_GOT_LO16,	/* type */
    866   1.8  christos 	 0,			/* rightshift */
    867  1.10  christos 	 4,			/* size */
    868   1.8  christos 	 16,			/* bitsize */
    869  1.10  christos 	 false,			/* pc_relative */
    870   1.8  christos 	 1,			/* bitpos */
    871   1.8  christos 	 complain_overflow_dont,/* complain_on_overflow */
    872   1.8  christos 	 score_elf_got_lo16_reloc, /* special_function */
    873   1.8  christos 	 "R_SCORE_GOT_LO16",	/* name */
    874  1.10  christos 	 true,			/* partial_inplace */
    875   1.8  christos 	 0x37ffe,		/* src_mask */
    876   1.8  christos 	 0x37ffe,		/* dst_mask */
    877  1.10  christos 	 false),		/* pcrel_offset */
    878   1.1  christos 
    879   1.1  christos   /* 15 bit call through global offset table.  */
    880   1.8  christos   HOWTO (R_SCORE_CALL15,	/* type */
    881   1.8  christos 	 0,			/* rightshift */
    882  1.10  christos 	 4,			/* size */
    883   1.8  christos 	 16,			/* bitsize */
    884  1.10  christos 	 false,			/* pc_relative */
    885   1.8  christos 	 0,			/* bitpos */
    886   1.8  christos 	 complain_overflow_signed, /* complain_on_overflow */
    887   1.8  christos 	 bfd_elf_generic_reloc, /* special_function */
    888   1.8  christos 	 "R_SCORE_CALL15",	/* name */
    889  1.10  christos 	 true,			/* partial_inplace */
    890   1.8  christos 	 0x0000ffff,		/* src_mask */
    891   1.8  christos 	 0x0000ffff,		/* dst_mask */
    892  1.10  christos 	 false),		/* pcrel_offset */
    893   1.1  christos 
    894   1.1  christos   /* 32 bit GP relative reference.  */
    895   1.8  christos   HOWTO (R_SCORE_GPREL32,	/* type */
    896   1.8  christos 	 0,			/* rightshift */
    897  1.10  christos 	 4,			/* size */
    898   1.8  christos 	 32,			/* bitsize */
    899  1.10  christos 	 false,			/* pc_relative */
    900   1.8  christos 	 0,			/* bitpos */
    901   1.8  christos 	 complain_overflow_dont,/* complain_on_overflow */
    902   1.8  christos 	 score_elf_gprel32_reloc, /* special_function */
    903   1.8  christos 	 "R_SCORE_GPREL32",	/* name */
    904  1.10  christos 	 true,			/* partial_inplace */
    905   1.8  christos 	 0xffffffff,		/* src_mask */
    906   1.8  christos 	 0xffffffff,		/* dst_mask */
    907  1.10  christos 	 false),		/* pcrel_offset */
    908   1.1  christos 
    909   1.1  christos   /* 32 bit symbol relative relocation.  */
    910   1.8  christos   HOWTO (R_SCORE_REL32,		/* type */
    911   1.8  christos 	 0,			/* rightshift */
    912  1.10  christos 	 4,			/* size */
    913   1.8  christos 	 32,			/* bitsize */
    914  1.10  christos 	 false,			/* pc_relative */
    915   1.8  christos 	 0,			/* bitpos */
    916   1.8  christos 	 complain_overflow_dont,/* complain_on_overflow */
    917   1.8  christos 	 bfd_elf_generic_reloc, /* special_function */
    918   1.8  christos 	 "R_SCORE_REL32",	/* name */
    919  1.10  christos 	 true,			/* partial_inplace */
    920   1.8  christos 	 0xffffffff,		/* src_mask */
    921   1.8  christos 	 0xffffffff,		/* dst_mask */
    922  1.10  christos 	 false),		/* pcrel_offset */
    923   1.1  christos 
    924   1.1  christos   /* R_SCORE_DUMMY_HI16 */
    925   1.8  christos   HOWTO (R_SCORE_DUMMY_HI16,	/* type */
    926   1.8  christos 	 0,			/* rightshift */
    927  1.10  christos 	 4,			/* size */
    928   1.8  christos 	 16,			/* bitsize */
    929  1.10  christos 	 false,			/* pc_relative */
    930   1.8  christos 	 1,			/* bitpos */
    931   1.8  christos 	 complain_overflow_dont,/* complain_on_overflow */
    932   1.8  christos 	 score_elf_hi16_reloc,	/* special_function */
    933   1.8  christos 	 "R_SCORE_DUMMY_HI16",	/* name */
    934  1.10  christos 	 true,			/* partial_inplace */
    935   1.8  christos 	 0x37fff,		/* src_mask */
    936   1.8  christos 	 0x37fff,		/* dst_mask */
    937  1.10  christos 	 false),		/* pcrel_offset */
    938   1.1  christos 
    939   1.1  christos   /* R_SCORE_IMM30 */
    940   1.8  christos   HOWTO (R_SCORE_IMM30,		/* type */
    941   1.8  christos 	 2,			/* rightshift */
    942  1.10  christos 	 4,			/* size */
    943   1.8  christos 	 30,			/* bitsize */
    944  1.10  christos 	 false,			/* pc_relative */
    945   1.8  christos 	 7,			/* bitpos */
    946   1.8  christos 	 complain_overflow_dont,/* complain_on_overflow */
    947   1.8  christos 	 bfd_elf_generic_reloc, /* special_function */
    948   1.8  christos 	 "R_SCORE_IMM30",	/* name */
    949  1.10  christos 	 false,			/* partial_inplace */
    950   1.8  christos 	 0x7f7fff7f80LL,	/* src_mask */
    951   1.8  christos 	 0x7f7fff7f80LL,	/* dst_mask */
    952  1.10  christos 	 false),		/* pcrel_offset */
    953   1.1  christos 
    954   1.1  christos   /* R_SCORE_IMM32 */
    955   1.8  christos   HOWTO (R_SCORE_IMM32,		/* type */
    956   1.8  christos 	 0,			/* rightshift */
    957  1.10  christos 	 4,			/* size */
    958   1.8  christos 	 32,			/* bitsize */
    959  1.10  christos 	 false,			/* pc_relative */
    960   1.8  christos 	 5,			/* bitpos */
    961   1.8  christos 	 complain_overflow_dont,/* complain_on_overflow */
    962   1.8  christos 	 bfd_elf_generic_reloc, /* special_function */
    963   1.8  christos 	 "R_SCORE_IMM32",	/* name */
    964  1.10  christos 	 false,			/* partial_inplace */
    965   1.8  christos 	 0x7f7fff7fe0LL,	/* src_mask */
    966   1.8  christos 	 0x7f7fff7fe0LL,	/* dst_mask */
    967  1.10  christos 	 false),		/* pcrel_offset */
    968   1.1  christos };
    969   1.1  christos 
    970   1.1  christos struct score_reloc_map
    971   1.1  christos {
    972   1.1  christos   bfd_reloc_code_real_type bfd_reloc_val;
    973   1.1  christos   unsigned char elf_reloc_val;
    974   1.1  christos };
    975   1.1  christos 
    976   1.1  christos static const struct score_reloc_map elf32_score_reloc_map[] =
    977   1.1  christos {
    978   1.8  christos   {BFD_RELOC_NONE,		 R_SCORE_NONE},
    979   1.8  christos   {BFD_RELOC_HI16_S,		 R_SCORE_HI16},
    980   1.8  christos   {BFD_RELOC_LO16,		 R_SCORE_LO16},
    981   1.8  christos   {BFD_RELOC_SCORE_BCMP,	 R_SCORE_BCMP},
    982   1.8  christos   {BFD_RELOC_SCORE_JMP,		 R_SCORE_24},
    983   1.8  christos   {BFD_RELOC_SCORE_BRANCH,	 R_SCORE_PC19},
    984   1.8  christos   {BFD_RELOC_SCORE16_JMP,	 R_SCORE16_11},
    985   1.8  christos   {BFD_RELOC_SCORE16_BRANCH,	 R_SCORE16_PC8},
    986   1.8  christos   {BFD_RELOC_32,		 R_SCORE_ABS32},
    987   1.8  christos   {BFD_RELOC_16,		 R_SCORE_ABS16},
    988   1.8  christos   {BFD_RELOC_SCORE_DUMMY2,	 R_SCORE_DUMMY2},
    989   1.8  christos   {BFD_RELOC_SCORE_GPREL15,	 R_SCORE_GP15},
    990   1.8  christos   {BFD_RELOC_VTABLE_INHERIT,	 R_SCORE_GNU_VTINHERIT},
    991   1.8  christos   {BFD_RELOC_VTABLE_ENTRY,	 R_SCORE_GNU_VTENTRY},
    992   1.8  christos   {BFD_RELOC_SCORE_GOT15,	 R_SCORE_GOT15},
    993   1.8  christos   {BFD_RELOC_SCORE_GOT_LO16,	 R_SCORE_GOT_LO16},
    994   1.8  christos   {BFD_RELOC_SCORE_CALL15,	 R_SCORE_CALL15},
    995   1.8  christos   {BFD_RELOC_GPREL32,		 R_SCORE_GPREL32},
    996   1.8  christos   {BFD_RELOC_32_PCREL,		 R_SCORE_REL32},
    997   1.8  christos   {BFD_RELOC_SCORE_DUMMY_HI16,	 R_SCORE_DUMMY_HI16},
    998   1.8  christos   {BFD_RELOC_SCORE_IMM30,	 R_SCORE_IMM30},
    999   1.8  christos   {BFD_RELOC_SCORE_IMM32,	 R_SCORE_IMM32},
   1000   1.1  christos };
   1001   1.1  christos 
   1002   1.1  christos /* got_entries only match if they're identical, except for gotidx, so
   1003   1.1  christos    use all fields to compute the hash, and compare the appropriate
   1004   1.1  christos    union members.  */
   1005   1.1  christos static hashval_t
   1006   1.1  christos score_elf_got_entry_hash (const void *entry_)
   1007   1.1  christos {
   1008   1.1  christos   const struct score_got_entry *entry = (struct score_got_entry *)entry_;
   1009   1.1  christos 
   1010   1.1  christos   return entry->symndx
   1011   1.1  christos     + (!entry->abfd ? entry->d.address : entry->abfd->id);
   1012   1.1  christos }
   1013   1.1  christos 
   1014   1.1  christos static int
   1015   1.1  christos score_elf_got_entry_eq (const void *entry1, const void *entry2)
   1016   1.1  christos {
   1017   1.1  christos   const struct score_got_entry *e1 = (struct score_got_entry *)entry1;
   1018   1.1  christos   const struct score_got_entry *e2 = (struct score_got_entry *)entry2;
   1019   1.1  christos 
   1020   1.1  christos   return e1->abfd == e2->abfd && e1->symndx == e2->symndx
   1021   1.1  christos     && (! e1->abfd ? e1->d.address == e2->d.address
   1022   1.8  christos 	: e1->symndx >= 0 ? e1->d.addend == e2->d.addend
   1023   1.8  christos 	: e1->d.h == e2->d.h);
   1024   1.1  christos }
   1025   1.1  christos 
   1026   1.1  christos /* If H needs a GOT entry, assign it the highest available dynamic
   1027   1.1  christos    index.  Otherwise, assign it the lowest available dynamic
   1028   1.1  christos    index.  */
   1029  1.10  christos static bool
   1030   1.1  christos score_elf_sort_hash_table_f (struct score_elf_link_hash_entry *h, void *data)
   1031   1.1  christos {
   1032   1.1  christos   struct score_elf_hash_sort_data *hsd = data;
   1033   1.1  christos 
   1034   1.1  christos   /* Symbols without dynamic symbol table entries aren't interesting at all.  */
   1035   1.1  christos   if (h->root.dynindx == -1)
   1036  1.10  christos     return true;
   1037   1.1  christos 
   1038   1.1  christos   /* Global symbols that need GOT entries that are not explicitly
   1039   1.1  christos      referenced are marked with got offset 2.  Those that are
   1040   1.1  christos      referenced get a 1, and those that don't need GOT entries get
   1041   1.1  christos      -1.  */
   1042   1.1  christos   if (h->root.got.offset == 2)
   1043   1.1  christos     {
   1044   1.1  christos       if (hsd->max_unref_got_dynindx == hsd->min_got_dynindx)
   1045   1.8  christos 	hsd->low = (struct elf_link_hash_entry *) h;
   1046   1.1  christos       h->root.dynindx = hsd->max_unref_got_dynindx++;
   1047   1.1  christos     }
   1048   1.1  christos   else if (h->root.got.offset != 1)
   1049   1.1  christos     h->root.dynindx = hsd->max_non_got_dynindx++;
   1050   1.1  christos   else
   1051   1.1  christos     {
   1052   1.1  christos       h->root.dynindx = --hsd->min_got_dynindx;
   1053   1.1  christos       hsd->low = (struct elf_link_hash_entry *) h;
   1054   1.1  christos     }
   1055   1.1  christos 
   1056  1.10  christos   return true;
   1057   1.1  christos }
   1058   1.1  christos 
   1059   1.1  christos static asection *
   1060  1.10  christos score_elf_got_section (bfd *abfd, bool maybe_excluded)
   1061   1.1  christos {
   1062   1.1  christos   asection *sgot = bfd_get_linker_section (abfd, ".got");
   1063   1.1  christos 
   1064   1.1  christos   if (sgot == NULL || (! maybe_excluded && (sgot->flags & SEC_EXCLUDE) != 0))
   1065   1.1  christos     return NULL;
   1066   1.1  christos   return sgot;
   1067   1.1  christos }
   1068   1.1  christos 
   1069   1.1  christos /* Returns the GOT information associated with the link indicated by
   1070   1.1  christos    INFO.  If SGOTP is non-NULL, it is filled in with the GOT section.  */
   1071   1.1  christos static struct score_got_info *
   1072   1.1  christos score_elf_got_info (bfd *abfd, asection **sgotp)
   1073   1.1  christos {
   1074   1.1  christos   asection *sgot;
   1075   1.1  christos   struct score_got_info *g;
   1076   1.1  christos 
   1077  1.10  christos   sgot = score_elf_got_section (abfd, true);
   1078   1.1  christos   BFD_ASSERT (sgot != NULL);
   1079   1.1  christos   BFD_ASSERT (elf_section_data (sgot) != NULL);
   1080   1.1  christos   g = score_elf_section_data (sgot)->u.got_info;
   1081   1.1  christos   BFD_ASSERT (g != NULL);
   1082   1.1  christos 
   1083   1.1  christos   if (sgotp)
   1084   1.1  christos     *sgotp = sgot;
   1085   1.1  christos   return g;
   1086   1.1  christos }
   1087   1.1  christos 
   1088   1.1  christos /* Sort the dynamic symbol table so that symbols that need GOT entries
   1089   1.1  christos    appear towards the end.  This reduces the amount of GOT space
   1090   1.1  christos    required.  MAX_LOCAL is used to set the number of local symbols
   1091   1.1  christos    known to be in the dynamic symbol table.  During
   1092  1.11  christos    s3_bfd_score_elf_late_size_sections, this value is 1.  Afterward, the
   1093   1.1  christos    section symbols are added and the count is higher.  */
   1094  1.10  christos static bool
   1095   1.1  christos score_elf_sort_hash_table (struct bfd_link_info *info,
   1096   1.8  christos 			   unsigned long max_local)
   1097   1.1  christos {
   1098   1.1  christos   struct score_elf_hash_sort_data hsd;
   1099   1.1  christos   struct score_got_info *g;
   1100   1.1  christos   bfd *dynobj;
   1101   1.1  christos 
   1102   1.1  christos   dynobj = elf_hash_table (info)->dynobj;
   1103   1.1  christos 
   1104   1.1  christos   g = score_elf_got_info (dynobj, NULL);
   1105   1.1  christos 
   1106   1.1  christos   hsd.low = NULL;
   1107   1.1  christos   hsd.max_unref_got_dynindx =
   1108   1.1  christos     hsd.min_got_dynindx = elf_hash_table (info)->dynsymcount
   1109   1.1  christos     /* In the multi-got case, assigned_gotno of the master got_info
   1110   1.1  christos        indicate the number of entries that aren't referenced in the
   1111   1.1  christos        primary GOT, but that must have entries because there are
   1112   1.1  christos        dynamic relocations that reference it.  Since they aren't
   1113   1.1  christos        referenced, we move them to the end of the GOT, so that they
   1114   1.1  christos        don't prevent other entries that are referenced from getting
   1115   1.1  christos        too large offsets.  */
   1116   1.1  christos     - (g->next ? g->assigned_gotno : 0);
   1117   1.1  christos   hsd.max_non_got_dynindx = max_local;
   1118   1.1  christos   score_elf_link_hash_traverse (elf_hash_table (info),
   1119   1.1  christos 				score_elf_sort_hash_table_f,
   1120   1.1  christos 				&hsd);
   1121   1.1  christos 
   1122   1.1  christos   /* There should have been enough room in the symbol table to
   1123   1.1  christos      accommodate both the GOT and non-GOT symbols.  */
   1124   1.1  christos   BFD_ASSERT (hsd.max_non_got_dynindx <= hsd.min_got_dynindx);
   1125   1.1  christos   BFD_ASSERT ((unsigned long)hsd.max_unref_got_dynindx
   1126   1.8  christos 	      <= elf_hash_table (info)->dynsymcount);
   1127   1.1  christos 
   1128   1.1  christos   /* Now we know which dynamic symbol has the lowest dynamic symbol
   1129   1.1  christos      table index in the GOT.  */
   1130   1.1  christos   g->global_gotsym = hsd.low;
   1131   1.1  christos 
   1132  1.10  christos   return true;
   1133   1.1  christos }
   1134   1.1  christos 
   1135   1.1  christos /* Create an entry in an score ELF linker hash table.  */
   1136   1.1  christos 
   1137   1.1  christos static struct bfd_hash_entry *
   1138   1.1  christos score_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
   1139   1.8  christos 			     struct bfd_hash_table *table,
   1140   1.8  christos 			     const char *string)
   1141   1.1  christos {
   1142   1.1  christos   struct score_elf_link_hash_entry *ret = (struct score_elf_link_hash_entry *) entry;
   1143   1.1  christos 
   1144   1.1  christos   /* Allocate the structure if it has not already been allocated by a subclass.  */
   1145   1.1  christos   if (ret == NULL)
   1146   1.1  christos     ret = bfd_hash_allocate (table, sizeof (struct score_elf_link_hash_entry));
   1147   1.1  christos   if (ret == NULL)
   1148   1.1  christos     return (struct bfd_hash_entry *) ret;
   1149   1.1  christos 
   1150   1.1  christos   /* Call the allocation method of the superclass.  */
   1151   1.1  christos   ret = ((struct score_elf_link_hash_entry *)
   1152   1.8  christos 	 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
   1153   1.1  christos 
   1154   1.1  christos   if (ret != NULL)
   1155   1.1  christos     {
   1156   1.1  christos       ret->possibly_dynamic_relocs = 0;
   1157  1.10  christos       ret->readonly_reloc = false;
   1158  1.10  christos       ret->no_fn_stub = false;
   1159  1.10  christos       ret->forced_local = false;
   1160   1.1  christos     }
   1161   1.1  christos 
   1162   1.1  christos   return (struct bfd_hash_entry *) ret;
   1163   1.1  christos }
   1164   1.1  christos 
   1165   1.1  christos /* Returns the first relocation of type r_type found, beginning with
   1166   1.1  christos    RELOCATION.  RELEND is one-past-the-end of the relocation table.  */
   1167   1.1  christos static const Elf_Internal_Rela *
   1168   1.1  christos score_elf_next_relocation (bfd *abfd ATTRIBUTE_UNUSED, unsigned int r_type,
   1169   1.8  christos 			    const Elf_Internal_Rela *relocation,
   1170   1.8  christos 			   const Elf_Internal_Rela *relend)
   1171   1.1  christos {
   1172   1.1  christos   while (relocation < relend)
   1173   1.1  christos     {
   1174   1.1  christos       if (ELF32_R_TYPE (relocation->r_info) == r_type)
   1175   1.8  christos 	return relocation;
   1176   1.1  christos 
   1177   1.1  christos       ++relocation;
   1178   1.1  christos     }
   1179   1.1  christos 
   1180   1.1  christos   /* We didn't find it.  */
   1181   1.1  christos   bfd_set_error (bfd_error_bad_value);
   1182   1.1  christos   return NULL;
   1183   1.1  christos }
   1184   1.1  christos 
   1185   1.1  christos /* This function is called via qsort() to sort the dynamic relocation
   1186   1.1  christos    entries by increasing r_symndx value.  */
   1187   1.1  christos static int
   1188   1.1  christos score_elf_sort_dynamic_relocs (const void *arg1, const void *arg2)
   1189   1.1  christos {
   1190   1.1  christos   Elf_Internal_Rela int_reloc1;
   1191   1.1  christos   Elf_Internal_Rela int_reloc2;
   1192   1.1  christos 
   1193   1.1  christos   bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg1, &int_reloc1);
   1194   1.1  christos   bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg2, &int_reloc2);
   1195   1.1  christos 
   1196   1.1  christos   return (ELF32_R_SYM (int_reloc1.r_info) - ELF32_R_SYM (int_reloc2.r_info));
   1197   1.1  christos }
   1198   1.1  christos 
   1199   1.1  christos /* Return whether a relocation is against a local symbol.  */
   1200  1.10  christos static bool
   1201   1.1  christos score_elf_local_relocation_p (bfd *input_bfd,
   1202   1.8  christos 			      const Elf_Internal_Rela *relocation,
   1203   1.8  christos 			      asection **local_sections,
   1204  1.10  christos 			      bool check_forced)
   1205   1.1  christos {
   1206   1.1  christos   unsigned long r_symndx;
   1207   1.1  christos   Elf_Internal_Shdr *symtab_hdr;
   1208   1.1  christos   struct score_elf_link_hash_entry *h;
   1209   1.1  christos   size_t extsymoff;
   1210   1.1  christos 
   1211   1.1  christos   r_symndx = ELF32_R_SYM (relocation->r_info);
   1212   1.1  christos   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   1213   1.1  christos   extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
   1214   1.1  christos 
   1215   1.1  christos   if (r_symndx < extsymoff)
   1216  1.10  christos     return true;
   1217   1.1  christos   if (elf_bad_symtab (input_bfd) && local_sections[r_symndx] != NULL)
   1218  1.10  christos     return true;
   1219   1.1  christos 
   1220   1.1  christos   if (check_forced)
   1221   1.1  christos     {
   1222   1.1  christos       /* Look up the hash table to check whether the symbol was forced local.  */
   1223   1.1  christos       h = (struct score_elf_link_hash_entry *)
   1224   1.8  christos 	elf_sym_hashes (input_bfd) [r_symndx - extsymoff];
   1225   1.1  christos       /* Find the real hash-table entry for this symbol.  */
   1226   1.1  christos       while (h->root.root.type == bfd_link_hash_indirect
   1227   1.8  christos 	     || h->root.root.type == bfd_link_hash_warning)
   1228   1.8  christos 	h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
   1229   1.1  christos       if (h->root.forced_local)
   1230  1.10  christos 	return true;
   1231   1.1  christos     }
   1232   1.1  christos 
   1233  1.10  christos   return false;
   1234   1.1  christos }
   1235   1.1  christos 
   1236   1.1  christos /* Returns the dynamic relocation section for DYNOBJ.  */
   1237   1.1  christos static asection *
   1238  1.10  christos score_elf_rel_dyn_section (bfd *dynobj, bool create_p)
   1239   1.1  christos {
   1240   1.1  christos   static const char dname[] = ".rel.dyn";
   1241   1.1  christos   asection *sreloc;
   1242   1.1  christos 
   1243   1.1  christos   sreloc = bfd_get_linker_section (dynobj, dname);
   1244   1.1  christos   if (sreloc == NULL && create_p)
   1245   1.1  christos     {
   1246   1.1  christos       sreloc = bfd_make_section_anyway_with_flags (dynobj, dname,
   1247   1.1  christos 						   (SEC_ALLOC
   1248   1.1  christos 						    | SEC_LOAD
   1249   1.1  christos 						    | SEC_HAS_CONTENTS
   1250   1.1  christos 						    | SEC_IN_MEMORY
   1251   1.1  christos 						    | SEC_LINKER_CREATED
   1252   1.1  christos 						    | SEC_READONLY));
   1253   1.1  christos       if (sreloc == NULL
   1254   1.9  christos 	  || !bfd_set_section_alignment (sreloc,
   1255   1.9  christos 					 SCORE_ELF_LOG_FILE_ALIGN (dynobj)))
   1256   1.8  christos 	return NULL;
   1257   1.1  christos     }
   1258   1.1  christos   return sreloc;
   1259   1.1  christos }
   1260   1.1  christos 
   1261   1.1  christos static void
   1262   1.1  christos score_elf_allocate_dynamic_relocations (bfd *abfd, unsigned int n)
   1263   1.1  christos {
   1264   1.1  christos   asection *s;
   1265   1.1  christos 
   1266  1.10  christos   s = score_elf_rel_dyn_section (abfd, false);
   1267   1.1  christos   BFD_ASSERT (s != NULL);
   1268   1.1  christos 
   1269   1.1  christos   if (s->size == 0)
   1270   1.1  christos     {
   1271   1.1  christos       /* Make room for a null element.  */
   1272   1.1  christos       s->size += SCORE_ELF_REL_SIZE (abfd);
   1273   1.1  christos       ++s->reloc_count;
   1274   1.1  christos     }
   1275   1.1  christos   s->size += n * SCORE_ELF_REL_SIZE (abfd);
   1276   1.1  christos }
   1277   1.1  christos 
   1278   1.1  christos /* Create a rel.dyn relocation for the dynamic linker to resolve.  REL
   1279   1.1  christos    is the original relocation, which is now being transformed into a
   1280   1.1  christos    dynamic relocation.  The ADDENDP is adjusted if necessary; the
   1281   1.1  christos    caller should store the result in place of the original addend.  */
   1282  1.10  christos static bool
   1283   1.1  christos score_elf_create_dynamic_relocation (bfd *output_bfd,
   1284   1.8  christos 				     struct bfd_link_info *info,
   1285   1.8  christos 				     const Elf_Internal_Rela *rel,
   1286   1.8  christos 				     struct score_elf_link_hash_entry *h,
   1287   1.8  christos 				     bfd_vma symbol,
   1288   1.8  christos 				     bfd_vma *addendp, asection *input_section)
   1289   1.1  christos {
   1290   1.1  christos   Elf_Internal_Rela outrel[3];
   1291   1.1  christos   asection *sreloc;
   1292   1.1  christos   bfd *dynobj;
   1293   1.1  christos   int r_type;
   1294   1.1  christos   long indx;
   1295  1.10  christos   bool defined_p;
   1296   1.1  christos 
   1297   1.1  christos   r_type = ELF32_R_TYPE (rel->r_info);
   1298   1.1  christos   dynobj = elf_hash_table (info)->dynobj;
   1299  1.10  christos   sreloc = score_elf_rel_dyn_section (dynobj, false);
   1300   1.1  christos   BFD_ASSERT (sreloc != NULL);
   1301   1.1  christos   BFD_ASSERT (sreloc->contents != NULL);
   1302   1.1  christos   BFD_ASSERT (sreloc->reloc_count * SCORE_ELF_REL_SIZE (output_bfd) < sreloc->size);
   1303   1.1  christos 
   1304   1.1  christos   outrel[0].r_offset =
   1305   1.1  christos     _bfd_elf_section_offset (output_bfd, info, input_section, rel[0].r_offset);
   1306   1.1  christos   outrel[1].r_offset =
   1307   1.1  christos     _bfd_elf_section_offset (output_bfd, info, input_section, rel[1].r_offset);
   1308   1.1  christos   outrel[2].r_offset =
   1309   1.1  christos     _bfd_elf_section_offset (output_bfd, info, input_section, rel[2].r_offset);
   1310   1.1  christos 
   1311   1.1  christos   if (outrel[0].r_offset == MINUS_ONE)
   1312   1.1  christos     /* The relocation field has been deleted.  */
   1313  1.10  christos     return true;
   1314   1.1  christos 
   1315   1.1  christos   if (outrel[0].r_offset == MINUS_TWO)
   1316   1.1  christos     {
   1317   1.1  christos       /* The relocation field has been converted into a relative value of
   1318   1.8  christos 	 some sort.  Functions like _bfd_elf_write_section_eh_frame expect
   1319   1.8  christos 	 the field to be fully relocated, so add in the symbol's value.  */
   1320   1.1  christos       *addendp += symbol;
   1321  1.10  christos       return true;
   1322   1.1  christos     }
   1323   1.1  christos 
   1324   1.1  christos   /* We must now calculate the dynamic symbol table index to use
   1325   1.1  christos      in the relocation.  */
   1326   1.1  christos   if (h != NULL
   1327   1.1  christos       && (! info->symbolic || !h->root.def_regular)
   1328   1.1  christos       /* h->root.dynindx may be -1 if this symbol was marked to
   1329   1.8  christos 	 become local.  */
   1330   1.1  christos       && h->root.dynindx != -1)
   1331   1.1  christos     {
   1332   1.1  christos       indx = h->root.dynindx;
   1333   1.8  christos 	/* ??? glibc's ld.so just adds the final GOT entry to the
   1334   1.8  christos 	   relocation field.  It therefore treats relocs against
   1335   1.8  christos 	   defined symbols in the same way as relocs against
   1336   1.8  christos 	   undefined symbols.  */
   1337  1.10  christos       defined_p = false;
   1338   1.1  christos     }
   1339   1.1  christos   else
   1340   1.1  christos     {
   1341   1.1  christos       indx = 0;
   1342  1.10  christos       defined_p = true;
   1343   1.1  christos     }
   1344   1.1  christos 
   1345   1.1  christos   /* If the relocation was previously an absolute relocation and
   1346   1.1  christos      this symbol will not be referred to by the relocation, we must
   1347   1.1  christos      adjust it by the value we give it in the dynamic symbol table.
   1348   1.1  christos      Otherwise leave the job up to the dynamic linker.  */
   1349   1.1  christos   if (defined_p && r_type != R_SCORE_REL32)
   1350   1.1  christos     *addendp += symbol;
   1351   1.1  christos 
   1352   1.1  christos   /* The relocation is always an REL32 relocation because we don't
   1353   1.1  christos      know where the shared library will wind up at load-time.  */
   1354   1.1  christos   outrel[0].r_info = ELF32_R_INFO ((unsigned long) indx, R_SCORE_REL32);
   1355   1.1  christos 
   1356   1.1  christos   /* For strict adherence to the ABI specification, we should
   1357   1.1  christos      generate a R_SCORE_64 relocation record by itself before the
   1358   1.1  christos      _REL32/_64 record as well, such that the addend is read in as
   1359   1.1  christos      a 64-bit value (REL32 is a 32-bit relocation, after all).
   1360   1.1  christos      However, since none of the existing ELF64 SCORE dynamic
   1361   1.1  christos      loaders seems to care, we don't waste space with these
   1362   1.1  christos      artificial relocations.  If this turns out to not be true,
   1363   1.1  christos      score_elf_allocate_dynamic_relocations() should be tweaked so
   1364   1.1  christos      as to make room for a pair of dynamic relocations per
   1365   1.1  christos      invocation if ABI_64_P, and here we should generate an
   1366   1.1  christos      additional relocation record with R_SCORE_64 by itself for a
   1367   1.1  christos      NULL symbol before this relocation record.  */
   1368   1.1  christos   outrel[1].r_info = ELF32_R_INFO (0, R_SCORE_NONE);
   1369   1.1  christos   outrel[2].r_info = ELF32_R_INFO (0, R_SCORE_NONE);
   1370   1.1  christos 
   1371   1.1  christos   /* Adjust the output offset of the relocation to reference the
   1372   1.1  christos      correct location in the output file.  */
   1373   1.1  christos   outrel[0].r_offset += (input_section->output_section->vma
   1374   1.8  christos 			 + input_section->output_offset);
   1375   1.1  christos   outrel[1].r_offset += (input_section->output_section->vma
   1376   1.8  christos 			 + input_section->output_offset);
   1377   1.1  christos   outrel[2].r_offset += (input_section->output_section->vma
   1378   1.8  christos 			 + input_section->output_offset);
   1379   1.1  christos 
   1380   1.1  christos   /* Put the relocation back out.  We have to use the special
   1381   1.1  christos      relocation outputter in the 64-bit case since the 64-bit
   1382   1.1  christos      relocation format is non-standard.  */
   1383   1.1  christos   bfd_elf32_swap_reloc_out
   1384   1.1  christos       (output_bfd, &outrel[0],
   1385   1.1  christos        (sreloc->contents + sreloc->reloc_count * sizeof (Elf32_External_Rel)));
   1386   1.1  christos 
   1387   1.1  christos   /* We've now added another relocation.  */
   1388   1.1  christos   ++sreloc->reloc_count;
   1389   1.1  christos 
   1390   1.1  christos   /* Make sure the output section is writable.  The dynamic linker
   1391   1.1  christos      will be writing to it.  */
   1392   1.1  christos   elf_section_data (input_section->output_section)->this_hdr.sh_flags |= SHF_WRITE;
   1393   1.1  christos 
   1394  1.10  christos   return true;
   1395   1.1  christos }
   1396   1.1  christos 
   1397  1.10  christos static bool
   1398   1.1  christos score_elf_create_got_section (bfd *abfd,
   1399   1.8  christos 			      struct bfd_link_info *info,
   1400  1.10  christos 			      bool maybe_exclude)
   1401   1.1  christos {
   1402   1.1  christos   flagword flags;
   1403   1.1  christos   asection *s;
   1404   1.1  christos   struct elf_link_hash_entry *h;
   1405   1.1  christos   struct bfd_link_hash_entry *bh;
   1406   1.1  christos   struct score_got_info *g;
   1407   1.9  christos   size_t amt;
   1408   1.1  christos 
   1409   1.1  christos   /* This function may be called more than once.  */
   1410  1.10  christos   s = score_elf_got_section (abfd, true);
   1411   1.1  christos   if (s)
   1412   1.1  christos     {
   1413   1.1  christos       if (! maybe_exclude)
   1414   1.8  christos 	s->flags &= ~SEC_EXCLUDE;
   1415  1.10  christos       return true;
   1416   1.1  christos     }
   1417   1.1  christos 
   1418   1.1  christos   flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
   1419   1.1  christos 
   1420   1.1  christos   if (maybe_exclude)
   1421   1.1  christos     flags |= SEC_EXCLUDE;
   1422   1.1  christos 
   1423   1.1  christos   /* We have to use an alignment of 2**4 here because this is hardcoded
   1424   1.1  christos      in the function stub generation and in the linker script.  */
   1425   1.1  christos   s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
   1426   1.7  christos   elf_hash_table (info)->sgot = s;
   1427   1.7  christos   if (s == NULL
   1428   1.9  christos       || !bfd_set_section_alignment (s, 4))
   1429  1.10  christos     return false;
   1430   1.1  christos 
   1431   1.1  christos   /* Define the symbol _GLOBAL_OFFSET_TABLE_.  We don't do this in the
   1432   1.1  christos      linker script because we don't want to define the symbol if we
   1433   1.1  christos      are not creating a global offset table.  */
   1434   1.1  christos   bh = NULL;
   1435   1.1  christos   if (! (_bfd_generic_link_add_one_symbol
   1436   1.8  christos 	 (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s,
   1437  1.10  christos 	  0, NULL, false, get_elf_backend_data (abfd)->collect, &bh)))
   1438  1.10  christos     return false;
   1439   1.1  christos 
   1440   1.1  christos   h = (struct elf_link_hash_entry *) bh;
   1441   1.1  christos   h->non_elf = 0;
   1442   1.1  christos   h->def_regular = 1;
   1443   1.1  christos   h->type = STT_OBJECT;
   1444   1.7  christos   elf_hash_table (info)->hgot = h;
   1445   1.1  christos 
   1446   1.6  christos   if (bfd_link_pic (info) && ! bfd_elf_link_record_dynamic_symbol (info, h))
   1447  1.10  christos     return false;
   1448   1.1  christos 
   1449   1.1  christos   amt = sizeof (struct score_got_info);
   1450   1.1  christos   g = bfd_alloc (abfd, amt);
   1451   1.1  christos   if (g == NULL)
   1452  1.10  christos     return false;
   1453   1.1  christos 
   1454   1.1  christos   g->global_gotsym = NULL;
   1455   1.1  christos   g->global_gotno = 0;
   1456   1.1  christos 
   1457   1.1  christos   g->local_gotno = SCORE_RESERVED_GOTNO;
   1458   1.1  christos   g->assigned_gotno = SCORE_RESERVED_GOTNO;
   1459   1.1  christos   g->next = NULL;
   1460   1.1  christos 
   1461   1.1  christos   g->got_entries = htab_try_create (1, score_elf_got_entry_hash,
   1462   1.8  christos 				    score_elf_got_entry_eq, NULL);
   1463   1.1  christos   if (g->got_entries == NULL)
   1464  1.10  christos     return false;
   1465   1.1  christos   score_elf_section_data (s)->u.got_info = g;
   1466   1.1  christos   score_elf_section_data (s)->elf.this_hdr.sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
   1467   1.1  christos 
   1468  1.10  christos   return true;
   1469   1.1  christos }
   1470   1.1  christos 
   1471   1.1  christos /* Calculate the %high function.  */
   1472   1.1  christos static bfd_vma
   1473   1.1  christos score_elf_high (bfd_vma value)
   1474   1.1  christos {
   1475   1.1  christos   return ((value + (bfd_vma) 0x8000) >> 16) & 0xffff;
   1476   1.1  christos }
   1477   1.1  christos 
   1478   1.1  christos /* Create a local GOT entry for VALUE.  Return the index of the entry,
   1479   1.1  christos    or -1 if it could not be created.  */
   1480   1.1  christos static struct score_got_entry *
   1481   1.1  christos score_elf_create_local_got_entry (bfd *abfd,
   1482   1.8  christos 				  bfd *ibfd ATTRIBUTE_UNUSED,
   1483   1.8  christos 				  struct score_got_info *gg,
   1484   1.8  christos 				  asection *sgot, bfd_vma value,
   1485   1.8  christos 				  unsigned long r_symndx ATTRIBUTE_UNUSED,
   1486   1.8  christos 				  struct score_elf_link_hash_entry *h ATTRIBUTE_UNUSED,
   1487   1.8  christos 				  int r_type ATTRIBUTE_UNUSED)
   1488   1.1  christos {
   1489   1.1  christos   struct score_got_entry entry, **loc;
   1490   1.1  christos   struct score_got_info *g;
   1491   1.1  christos 
   1492   1.1  christos   entry.abfd = NULL;
   1493   1.1  christos   entry.symndx = -1;
   1494   1.1  christos   entry.d.address = value;
   1495   1.1  christos 
   1496   1.1  christos   g = gg;
   1497   1.1  christos   loc = (struct score_got_entry **) htab_find_slot (g->got_entries, &entry, INSERT);
   1498   1.1  christos   if (*loc)
   1499   1.1  christos     return *loc;
   1500   1.1  christos 
   1501   1.1  christos   entry.gotidx = SCORE_ELF_GOT_SIZE (abfd) * g->assigned_gotno++;
   1502   1.1  christos 
   1503   1.1  christos   *loc = bfd_alloc (abfd, sizeof entry);
   1504   1.1  christos 
   1505   1.1  christos   if (! *loc)
   1506   1.1  christos     return NULL;
   1507   1.1  christos 
   1508   1.1  christos   memcpy (*loc, &entry, sizeof entry);
   1509   1.1  christos 
   1510   1.1  christos   if (g->assigned_gotno >= g->local_gotno)
   1511   1.1  christos     {
   1512   1.1  christos       (*loc)->gotidx = -1;
   1513   1.1  christos       /* We didn't allocate enough space in the GOT.  */
   1514   1.7  christos       _bfd_error_handler
   1515   1.8  christos 	(_("not enough GOT space for local GOT entries"));
   1516   1.1  christos       bfd_set_error (bfd_error_bad_value);
   1517   1.1  christos       return NULL;
   1518   1.1  christos     }
   1519   1.1  christos 
   1520   1.1  christos   score_bfd_put_32 (abfd, value, (sgot->contents + entry.gotidx));
   1521   1.1  christos 
   1522   1.1  christos   return *loc;
   1523   1.1  christos }
   1524   1.1  christos 
   1525   1.1  christos /* Find a GOT entry whose higher-order 16 bits are the same as those
   1526   1.1  christos    for value.  Return the index into the GOT for this entry.  */
   1527   1.1  christos static bfd_vma
   1528   1.1  christos score_elf_got16_entry (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
   1529  1.10  christos 		       bfd_vma value, bool external)
   1530   1.1  christos {
   1531   1.1  christos   asection *sgot;
   1532   1.1  christos   struct score_got_info *g;
   1533   1.1  christos   struct score_got_entry *entry;
   1534   1.1  christos 
   1535   1.1  christos   if (!external)
   1536   1.1  christos     {
   1537   1.1  christos       /* Although the ABI says that it is "the high-order 16 bits" that we
   1538   1.8  christos 	 want, it is really the %high value.  The complete value is
   1539   1.8  christos 	 calculated with a `addiu' of a LO16 relocation, just as with a
   1540   1.8  christos 	 HI16/LO16 pair.  */
   1541   1.1  christos       value = score_elf_high (value) << 16;
   1542   1.1  christos     }
   1543   1.1  christos 
   1544   1.1  christos   g = score_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
   1545   1.1  christos 
   1546   1.1  christos   entry = score_elf_create_local_got_entry (abfd, ibfd, g, sgot, value, 0, NULL,
   1547   1.8  christos 					    R_SCORE_GOT15);
   1548   1.1  christos   if (entry)
   1549   1.1  christos     return entry->gotidx;
   1550   1.1  christos   else
   1551   1.1  christos     return MINUS_ONE;
   1552   1.1  christos }
   1553   1.1  christos 
   1554   1.1  christos static void
   1555   1.1  christos s3_bfd_score_elf_hide_symbol (struct bfd_link_info *info,
   1556   1.8  christos 			      struct elf_link_hash_entry *entry,
   1557  1.10  christos 			      bool force_local)
   1558   1.1  christos {
   1559   1.1  christos   bfd *dynobj;
   1560   1.1  christos   asection *got;
   1561   1.1  christos   struct score_got_info *g;
   1562   1.1  christos   struct score_elf_link_hash_entry *h;
   1563   1.1  christos 
   1564   1.1  christos   h = (struct score_elf_link_hash_entry *) entry;
   1565   1.1  christos   if (h->forced_local)
   1566   1.1  christos     return;
   1567  1.10  christos   h->forced_local = true;
   1568   1.1  christos 
   1569   1.1  christos   dynobj = elf_hash_table (info)->dynobj;
   1570   1.1  christos   if (dynobj != NULL && force_local)
   1571   1.1  christos     {
   1572  1.10  christos       got = score_elf_got_section (dynobj, false);
   1573   1.1  christos       if (got == NULL)
   1574   1.8  christos 	return;
   1575   1.1  christos       g = score_elf_section_data (got)->u.got_info;
   1576   1.1  christos 
   1577   1.1  christos       if (g->next)
   1578   1.8  christos 	{
   1579   1.8  christos 	  struct score_got_entry e;
   1580   1.8  christos 	  struct score_got_info *gg = g;
   1581   1.8  christos 
   1582   1.8  christos 	  /* Since we're turning what used to be a global symbol into a
   1583   1.8  christos 	     local one, bump up the number of local entries of each GOT
   1584   1.8  christos 	     that had an entry for it.  This will automatically decrease
   1585   1.8  christos 	     the number of global entries, since global_gotno is actually
   1586   1.8  christos 	     the upper limit of global entries.  */
   1587   1.8  christos 	  e.abfd = dynobj;
   1588   1.8  christos 	  e.symndx = -1;
   1589   1.8  christos 	  e.d.h = h;
   1590   1.8  christos 
   1591   1.8  christos 	  for (g = g->next; g != gg; g = g->next)
   1592   1.8  christos 	    if (htab_find (g->got_entries, &e))
   1593   1.8  christos 	      {
   1594   1.8  christos 		BFD_ASSERT (g->global_gotno > 0);
   1595   1.8  christos 		g->local_gotno++;
   1596   1.8  christos 		g->global_gotno--;
   1597   1.8  christos 	      }
   1598   1.8  christos 
   1599   1.8  christos 	  /* If this was a global symbol forced into the primary GOT, we
   1600   1.8  christos 	     no longer need an entry for it.  We can't release the entry
   1601   1.8  christos 	     at this point, but we must at least stop counting it as one
   1602   1.8  christos 	     of the symbols that required a forced got entry.  */
   1603   1.8  christos 	  if (h->root.got.offset == 2)
   1604   1.8  christos 	    {
   1605   1.8  christos 	      BFD_ASSERT (gg->assigned_gotno > 0);
   1606   1.8  christos 	      gg->assigned_gotno--;
   1607   1.8  christos 	    }
   1608   1.8  christos 	}
   1609   1.1  christos       else if (g->global_gotno == 0 && g->global_gotsym == NULL)
   1610   1.8  christos 	/* If we haven't got through GOT allocation yet, just bump up the
   1611   1.8  christos 	      number of local entries, as this symbol won't be counted as
   1612   1.8  christos 	      global.  */
   1613   1.8  christos 	g->local_gotno++;
   1614   1.1  christos       else if (h->root.got.offset == 1)
   1615   1.8  christos 	{
   1616   1.8  christos 	  /* If we're past non-multi-GOT allocation and this symbol had
   1617   1.8  christos 		  been marked for a global got entry, give it a local entry
   1618   1.8  christos 		  instead.  */
   1619   1.8  christos 	  BFD_ASSERT (g->global_gotno > 0);
   1620   1.8  christos 	  g->local_gotno++;
   1621   1.8  christos 	  g->global_gotno--;
   1622   1.8  christos 	}
   1623   1.1  christos     }
   1624   1.1  christos 
   1625   1.1  christos   _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
   1626   1.1  christos }
   1627   1.1  christos 
   1628   1.1  christos /* If H is a symbol that needs a global GOT entry, but has a dynamic
   1629   1.1  christos    symbol table index lower than any we've seen to date, record it for
   1630   1.1  christos    posterity.  */
   1631  1.10  christos static bool
   1632   1.1  christos score_elf_record_global_got_symbol (struct elf_link_hash_entry *h,
   1633   1.8  christos 				    bfd *abfd,
   1634   1.8  christos 				    struct bfd_link_info *info,
   1635   1.8  christos 				    struct score_got_info *g)
   1636   1.1  christos {
   1637   1.1  christos   struct score_got_entry entry, **loc;
   1638   1.1  christos 
   1639   1.1  christos   /* A global symbol in the GOT must also be in the dynamic symbol table.  */
   1640   1.1  christos   if (h->dynindx == -1)
   1641   1.1  christos     {
   1642   1.1  christos       switch (ELF_ST_VISIBILITY (h->other))
   1643   1.8  christos 	{
   1644   1.8  christos 	case STV_INTERNAL:
   1645   1.8  christos 	case STV_HIDDEN:
   1646  1.10  christos 	  s3_bfd_score_elf_hide_symbol (info, h, true);
   1647   1.8  christos 	  break;
   1648   1.8  christos 	}
   1649   1.1  christos       if (!bfd_elf_link_record_dynamic_symbol (info, h))
   1650  1.10  christos 	return false;
   1651   1.1  christos     }
   1652   1.1  christos 
   1653   1.1  christos   entry.abfd = abfd;
   1654   1.1  christos   entry.symndx = -1;
   1655   1.1  christos   entry.d.h = (struct score_elf_link_hash_entry *)h;
   1656   1.1  christos 
   1657   1.1  christos   loc = (struct score_got_entry **)htab_find_slot (g->got_entries, &entry, INSERT);
   1658   1.1  christos 
   1659   1.1  christos   /* If we've already marked this entry as needing GOT space, we don't
   1660   1.1  christos      need to do it again.  */
   1661   1.1  christos   if (*loc)
   1662  1.10  christos     return true;
   1663   1.1  christos 
   1664   1.1  christos   *loc = bfd_alloc (abfd, sizeof entry);
   1665   1.1  christos   if (! *loc)
   1666  1.10  christos     return false;
   1667   1.1  christos 
   1668   1.1  christos   entry.gotidx = -1;
   1669   1.1  christos 
   1670   1.1  christos   memcpy (*loc, &entry, sizeof (entry));
   1671   1.1  christos 
   1672   1.1  christos   if (h->got.offset != MINUS_ONE)
   1673  1.10  christos     return true;
   1674   1.1  christos 
   1675   1.1  christos   /* By setting this to a value other than -1, we are indicating that
   1676   1.1  christos      there needs to be a GOT entry for H.  Avoid using zero, as the
   1677   1.1  christos      generic ELF copy_indirect_symbol tests for <= 0.  */
   1678   1.1  christos   h->got.offset = 1;
   1679   1.1  christos 
   1680  1.10  christos   return true;
   1681   1.1  christos }
   1682   1.1  christos 
   1683   1.1  christos /* Reserve space in G for a GOT entry containing the value of symbol
   1684   1.1  christos    SYMNDX in input bfd ABDF, plus ADDEND.  */
   1685  1.10  christos static bool
   1686   1.1  christos score_elf_record_local_got_symbol (bfd *abfd,
   1687   1.8  christos 				   long symndx,
   1688   1.8  christos 				   bfd_vma addend,
   1689   1.8  christos 				   struct score_got_info *g)
   1690   1.1  christos {
   1691   1.1  christos   struct score_got_entry entry, **loc;
   1692   1.1  christos 
   1693   1.1  christos   entry.abfd = abfd;
   1694   1.1  christos   entry.symndx = symndx;
   1695   1.1  christos   entry.d.addend = addend;
   1696   1.1  christos   loc = (struct score_got_entry **)htab_find_slot (g->got_entries, &entry, INSERT);
   1697   1.1  christos 
   1698   1.1  christos   if (*loc)
   1699  1.10  christos     return true;
   1700   1.1  christos 
   1701   1.1  christos   entry.gotidx = g->local_gotno++;
   1702   1.1  christos 
   1703   1.1  christos   *loc = bfd_alloc (abfd, sizeof(entry));
   1704   1.1  christos   if (! *loc)
   1705  1.10  christos     return false;
   1706   1.1  christos 
   1707   1.1  christos   memcpy (*loc, &entry, sizeof (entry));
   1708   1.1  christos 
   1709  1.10  christos   return true;
   1710   1.1  christos }
   1711   1.1  christos 
   1712   1.1  christos /* Returns the GOT offset at which the indicated address can be found.
   1713   1.1  christos    If there is not yet a GOT entry for this value, create one.
   1714   1.1  christos    Returns -1 if no satisfactory GOT offset can be found.  */
   1715   1.1  christos static bfd_vma
   1716   1.1  christos score_elf_local_got_index (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
   1717   1.8  christos 			   bfd_vma value, unsigned long r_symndx,
   1718   1.8  christos 			   struct score_elf_link_hash_entry *h, int r_type)
   1719   1.1  christos {
   1720   1.1  christos   asection *sgot;
   1721   1.1  christos   struct score_got_info *g;
   1722   1.1  christos   struct score_got_entry *entry;
   1723   1.1  christos 
   1724   1.1  christos   g = score_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
   1725   1.1  christos 
   1726   1.1  christos   entry = score_elf_create_local_got_entry (abfd, ibfd, g, sgot, value,
   1727   1.8  christos 					     r_symndx, h, r_type);
   1728   1.1  christos   if (!entry)
   1729   1.1  christos     return MINUS_ONE;
   1730   1.1  christos 
   1731   1.1  christos   else
   1732   1.1  christos     return entry->gotidx;
   1733   1.1  christos }
   1734   1.1  christos 
   1735   1.1  christos /* Returns the GOT index for the global symbol indicated by H.  */
   1736   1.1  christos 
   1737   1.1  christos static bfd_vma
   1738   1.1  christos score_elf_global_got_index (bfd *abfd, struct elf_link_hash_entry *h)
   1739   1.1  christos {
   1740   1.1  christos   bfd_vma got_index;
   1741   1.1  christos   asection *sgot;
   1742   1.1  christos   struct score_got_info *g;
   1743   1.1  christos   long global_got_dynindx = 0;
   1744   1.1  christos 
   1745   1.1  christos   g = score_elf_got_info (abfd, &sgot);
   1746   1.1  christos   if (g->global_gotsym != NULL)
   1747   1.1  christos     global_got_dynindx = g->global_gotsym->dynindx;
   1748   1.1  christos 
   1749   1.1  christos   /* Once we determine the global GOT entry with the lowest dynamic
   1750   1.1  christos      symbol table index, we must put all dynamic symbols with greater
   1751   1.1  christos      indices into the GOT.  That makes it easy to calculate the GOT
   1752   1.1  christos      offset.  */
   1753   1.1  christos   BFD_ASSERT (h->dynindx >= global_got_dynindx);
   1754   1.1  christos   got_index = ((h->dynindx - global_got_dynindx + g->local_gotno) * SCORE_ELF_GOT_SIZE (abfd));
   1755   1.1  christos   BFD_ASSERT (got_index < sgot->size);
   1756   1.1  christos 
   1757   1.1  christos   return got_index;
   1758   1.1  christos }
   1759   1.1  christos 
   1760   1.1  christos /* Returns the offset for the entry at the INDEXth position in the GOT.  */
   1761   1.1  christos 
   1762   1.1  christos static bfd_vma
   1763   1.1  christos score_elf_got_offset_from_index (bfd *dynobj,
   1764   1.1  christos 				 bfd *output_bfd,
   1765   1.8  christos 				 bfd *input_bfd ATTRIBUTE_UNUSED,
   1766   1.1  christos 				 bfd_vma got_index)
   1767   1.1  christos {
   1768   1.1  christos   asection *sgot;
   1769   1.1  christos   bfd_vma gp;
   1770   1.1  christos 
   1771   1.1  christos   score_elf_got_info (dynobj, &sgot);
   1772   1.1  christos   gp = _bfd_get_gp_value (output_bfd);
   1773   1.1  christos 
   1774   1.1  christos   return sgot->output_section->vma + sgot->output_offset + got_index - gp;
   1775   1.1  christos }
   1776   1.1  christos 
   1777   1.1  christos /* Follow indirect and warning hash entries so that each got entry
   1778   1.1  christos    points to the final symbol definition.  P must point to a pointer
   1779   1.1  christos    to the hash table we're traversing.  Since this traversal may
   1780   1.1  christos    modify the hash table, we set this pointer to NULL to indicate
   1781   1.1  christos    we've made a potentially-destructive change to the hash table, so
   1782   1.1  christos    the traversal must be restarted.  */
   1783   1.1  christos static int
   1784   1.1  christos score_elf_resolve_final_got_entry (void **entryp, void *p)
   1785   1.1  christos {
   1786   1.1  christos   struct score_got_entry *entry = (struct score_got_entry *)*entryp;
   1787   1.1  christos   htab_t got_entries = *(htab_t *)p;
   1788   1.1  christos 
   1789   1.1  christos   if (entry->abfd != NULL && entry->symndx == -1)
   1790   1.1  christos     {
   1791   1.1  christos       struct score_elf_link_hash_entry *h = entry->d.h;
   1792   1.1  christos 
   1793   1.1  christos       while (h->root.root.type == bfd_link_hash_indirect
   1794   1.8  christos 	     || h->root.root.type == bfd_link_hash_warning)
   1795   1.8  christos 	h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
   1796   1.1  christos 
   1797   1.1  christos       if (entry->d.h == h)
   1798   1.8  christos 	return 1;
   1799   1.1  christos 
   1800   1.1  christos       entry->d.h = h;
   1801   1.1  christos 
   1802   1.1  christos       /* If we can't find this entry with the new bfd hash, re-insert
   1803   1.8  christos 	 it, and get the traversal restarted.  */
   1804   1.1  christos       if (! htab_find (got_entries, entry))
   1805   1.8  christos 	{
   1806   1.8  christos 	  htab_clear_slot (got_entries, entryp);
   1807   1.8  christos 	  entryp = htab_find_slot (got_entries, entry, INSERT);
   1808   1.8  christos 	  if (! *entryp)
   1809   1.8  christos 	    *entryp = entry;
   1810   1.8  christos 	  /* Abort the traversal, since the whole table may have
   1811   1.8  christos 	     moved, and leave it up to the parent to restart the
   1812   1.8  christos 	     process.  */
   1813   1.8  christos 	  *(htab_t *)p = NULL;
   1814   1.8  christos 	  return 0;
   1815   1.8  christos 	}
   1816   1.1  christos       /* We might want to decrement the global_gotno count, but it's
   1817   1.8  christos 	 either too early or too late for that at this point.  */
   1818   1.1  christos     }
   1819   1.1  christos 
   1820   1.1  christos   return 1;
   1821   1.1  christos }
   1822   1.1  christos 
   1823   1.1  christos /* Turn indirect got entries in a got_entries table into their final locations.  */
   1824   1.1  christos static void
   1825   1.1  christos score_elf_resolve_final_got_entries (struct score_got_info *g)
   1826   1.1  christos {
   1827   1.1  christos   htab_t got_entries;
   1828   1.1  christos 
   1829   1.1  christos   do
   1830   1.1  christos     {
   1831   1.1  christos       got_entries = g->got_entries;
   1832   1.1  christos 
   1833   1.1  christos       htab_traverse (got_entries,
   1834   1.8  christos 		     score_elf_resolve_final_got_entry,
   1835   1.8  christos 		     &got_entries);
   1836   1.1  christos     }
   1837   1.1  christos   while (got_entries == NULL);
   1838   1.1  christos }
   1839   1.1  christos 
   1840   1.1  christos /* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS. for -r  */
   1841   1.1  christos static void
   1842   1.1  christos score_elf_add_to_rel (bfd *abfd,
   1843   1.8  christos 		      bfd_byte *address,
   1844   1.8  christos 		      reloc_howto_type *howto,
   1845   1.8  christos 		      bfd_signed_vma increment)
   1846   1.1  christos {
   1847   1.1  christos   bfd_signed_vma addend;
   1848   1.1  christos   bfd_vma contents;
   1849   1.1  christos   unsigned long offset;
   1850   1.1  christos   unsigned long r_type = howto->type;
   1851   1.1  christos   unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
   1852   1.1  christos 
   1853   1.1  christos   contents = score_bfd_get_32 (abfd, address);
   1854   1.1  christos   /* Get the (signed) value from the instruction.  */
   1855   1.1  christos   addend = contents & howto->src_mask;
   1856   1.1  christos   if (addend & ((howto->src_mask + 1) >> 1))
   1857   1.1  christos     {
   1858   1.1  christos       bfd_signed_vma mask;
   1859   1.1  christos 
   1860   1.1  christos       mask = -1;
   1861   1.1  christos       mask &= ~howto->src_mask;
   1862   1.1  christos       addend |= mask;
   1863   1.1  christos     }
   1864   1.1  christos   /* Add in the increment, (which is a byte value).  */
   1865   1.1  christos   switch (r_type)
   1866   1.1  christos     {
   1867   1.1  christos     case R_SCORE_PC19:
   1868   1.1  christos       offset =
   1869   1.8  christos 	(((contents & howto->src_mask) & 0x3ff0000) >> 6) | ((contents & howto->src_mask) & 0x3ff);
   1870   1.1  christos       offset += increment;
   1871   1.1  christos       contents =
   1872   1.8  christos 	(contents & ~howto->
   1873   1.8  christos 	 src_mask) | (((offset << 6) & howto->src_mask) & 0x3ff0000) | (offset & 0x3ff);
   1874   1.1  christos       score_bfd_put_32 (abfd, contents, address);
   1875   1.1  christos       break;
   1876   1.1  christos     case R_SCORE_HI16:
   1877   1.1  christos       break;
   1878   1.1  christos     case R_SCORE_LO16:
   1879   1.1  christos       hi16_addend = score_bfd_get_32 (abfd, address - 4);
   1880   1.1  christos       hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
   1881   1.1  christos       offset = ((((contents >> 16) & 0x3) << 15) | (contents & 0x7fff)) >> 1;
   1882   1.1  christos       offset = (hi16_offset << 16) | (offset & 0xffff);
   1883   1.1  christos       uvalue = increment + offset;
   1884   1.1  christos       hi16_offset = (uvalue >> 16) << 1;
   1885   1.1  christos       hi16_value = (hi16_addend & (~(howto->dst_mask)))
   1886   1.8  christos 	| (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
   1887   1.1  christos       score_bfd_put_32 (abfd, hi16_value, address - 4);
   1888   1.1  christos       offset = (uvalue & 0xffff) << 1;
   1889   1.1  christos       contents = (contents & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
   1890   1.1  christos       score_bfd_put_32 (abfd, contents, address);
   1891   1.1  christos       break;
   1892   1.1  christos     case R_SCORE_24:
   1893   1.1  christos       offset =
   1894   1.8  christos 	(((contents & howto->src_mask) >> 1) & 0x1ff8000) | ((contents & howto->src_mask) & 0x7fff);
   1895   1.1  christos       offset += increment;
   1896   1.1  christos       contents =
   1897   1.8  christos 	(contents & ~howto->
   1898   1.8  christos 	 src_mask) | (((offset << 1) & howto->src_mask) & 0x3ff0000) | (offset & 0x7fff);
   1899   1.1  christos       score_bfd_put_32 (abfd, contents, address);
   1900   1.1  christos       break;
   1901   1.1  christos 
   1902   1.1  christos     case R_SCORE16_11:
   1903   1.1  christos 
   1904   1.1  christos       contents = score_bfd_get_16 (abfd, address);
   1905   1.1  christos       offset = contents & howto->src_mask;
   1906   1.1  christos       offset += increment;
   1907   1.1  christos       contents = (contents & ~howto->src_mask) | (offset & howto->src_mask);
   1908   1.1  christos       score_bfd_put_16 (abfd, contents, address);
   1909   1.1  christos 
   1910   1.1  christos       break;
   1911   1.1  christos     case R_SCORE16_PC8:
   1912   1.1  christos 
   1913   1.1  christos       contents = score_bfd_get_16 (abfd, address);
   1914   1.1  christos       offset = (contents & howto->src_mask) + ((increment >> 1) & 0x1ff);
   1915   1.1  christos       contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask);
   1916   1.1  christos       score_bfd_put_16 (abfd, contents, address);
   1917   1.1  christos 
   1918   1.1  christos       break;
   1919   1.1  christos 
   1920   1.1  christos     case R_SCORE_BCMP:
   1921   1.1  christos       contents = score_bfd_get_32 (abfd, address);
   1922   1.1  christos       offset = (contents & howto->src_mask);
   1923   1.1  christos       offset <<= howto->rightshift;
   1924   1.1  christos       offset += increment;
   1925   1.1  christos       offset >>= howto->rightshift;
   1926   1.1  christos       contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask);
   1927   1.1  christos       score_bfd_put_32 (abfd, contents, address);
   1928   1.1  christos       break;
   1929   1.1  christos 
   1930   1.1  christos     case R_SCORE_IMM30:
   1931   1.1  christos       contents = score_bfd_get_48 (abfd, address);
   1932   1.1  christos       offset = (contents & howto->src_mask);
   1933   1.1  christos       offset <<= howto->rightshift;
   1934   1.1  christos       offset += increment;
   1935   1.1  christos       offset >>= howto->rightshift;
   1936   1.1  christos       contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask);
   1937   1.1  christos       score_bfd_put_48 (abfd, contents, address);
   1938   1.1  christos       break;
   1939   1.1  christos 
   1940   1.1  christos     case R_SCORE_IMM32:
   1941   1.1  christos       contents = score_bfd_get_48 (abfd, address);
   1942   1.1  christos       offset = (contents & howto->src_mask);
   1943   1.1  christos       offset += increment;
   1944   1.1  christos       contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask);
   1945   1.1  christos       score_bfd_put_48 (abfd, contents, address);
   1946   1.1  christos       break;
   1947   1.1  christos 
   1948   1.1  christos     default:
   1949   1.1  christos       addend += increment;
   1950   1.1  christos       contents = (contents & ~howto->dst_mask) | (addend & howto->dst_mask);
   1951   1.1  christos       score_bfd_put_32 (abfd, contents, address);
   1952   1.1  christos       break;
   1953   1.1  christos     }
   1954   1.1  christos }
   1955   1.1  christos 
   1956   1.1  christos /* Perform a relocation as part of a final link.  */
   1957   1.1  christos static bfd_reloc_status_type
   1958   1.1  christos score_elf_final_link_relocate (reloc_howto_type *howto,
   1959   1.8  christos 			       bfd *input_bfd,
   1960   1.8  christos 			       bfd *output_bfd,
   1961   1.8  christos 			       asection *input_section,
   1962   1.8  christos 			       bfd_byte *contents,
   1963   1.8  christos 			       Elf_Internal_Rela *rel,
   1964   1.8  christos 			       Elf_Internal_Rela *relocs,
   1965   1.8  christos 			       bfd_vma symbol,
   1966   1.8  christos 			       struct bfd_link_info *info,
   1967   1.8  christos 			       const char *sym_name ATTRIBUTE_UNUSED,
   1968   1.8  christos 			       int sym_flags ATTRIBUTE_UNUSED,
   1969   1.8  christos 			       struct score_elf_link_hash_entry *h,
   1970   1.8  christos 			       asection **local_sections,
   1971  1.10  christos 			       bool gp_disp_p)
   1972   1.1  christos {
   1973   1.1  christos   unsigned long r_type;
   1974   1.1  christos   unsigned long r_symndx;
   1975   1.1  christos   bfd_byte *hit_data = contents + rel->r_offset;
   1976   1.1  christos   bfd_vma addend;
   1977   1.1  christos   /* The final GP value to be used for the relocatable, executable, or
   1978   1.1  christos      shared object file being produced.  */
   1979   1.1  christos   bfd_vma gp = MINUS_ONE;
   1980   1.1  christos   /* The place (section offset or address) of the storage unit being relocated.  */
   1981   1.1  christos   bfd_vma rel_addr;
   1982   1.1  christos   /* The offset into the global offset table at which the address of the relocation entry
   1983   1.1  christos      symbol, adjusted by the addend, resides during execution.  */
   1984   1.1  christos   bfd_vma g = MINUS_ONE;
   1985   1.1  christos   /* TRUE if the symbol referred to by this relocation is a local symbol.  */
   1986  1.10  christos   bool local_p;
   1987   1.1  christos   /* The eventual value we will relocate.  */
   1988   1.1  christos   bfd_vma value = symbol;
   1989   1.1  christos   unsigned long hi16_addend, hi16_offset, hi16_value, uvalue, offset, abs_value = 0;
   1990   1.1  christos 
   1991   1.1  christos 
   1992   1.1  christos   if (elf_gp (output_bfd) == 0)
   1993   1.1  christos     {
   1994   1.1  christos       struct bfd_link_hash_entry *bh;
   1995   1.1  christos       asection *o;
   1996   1.1  christos 
   1997   1.1  christos       bh = bfd_link_hash_lookup (info->hash, "_gp", 0, 0, 1);
   1998   1.1  christos       if (bh != NULL && bh->type == bfd_link_hash_defined)
   1999   1.8  christos 	elf_gp (output_bfd) = (bh->u.def.value
   2000   1.8  christos 			       + bh->u.def.section->output_section->vma
   2001   1.8  christos 			       + bh->u.def.section->output_offset);
   2002   1.6  christos       else if (bfd_link_relocatable (info))
   2003   1.8  christos 	{
   2004   1.8  christos 	  bfd_vma lo = -1;
   2005   1.1  christos 
   2006   1.8  christos 	  /* Find the GP-relative section with the lowest offset.  */
   2007   1.8  christos 	  for (o = output_bfd->sections; o != NULL; o = o->next)
   2008   1.8  christos 	    if (o->vma < lo)
   2009   1.8  christos 	      lo = o->vma;
   2010   1.8  christos 	  /* And calculate GP relative to that.  */
   2011   1.8  christos 	  elf_gp (output_bfd) = lo + ELF_SCORE_GP_OFFSET (input_bfd);
   2012   1.8  christos 	}
   2013   1.1  christos       else
   2014   1.8  christos 	{
   2015   1.8  christos 	  /* If the relocate_section function needs to do a reloc
   2016   1.8  christos 	     involving the GP value, it should make a reloc_dangerous
   2017   1.8  christos 	     callback to warn that GP is not defined.  */
   2018   1.8  christos 	}
   2019   1.1  christos     }
   2020   1.1  christos 
   2021   1.1  christos   /* Parse the relocation.  */
   2022   1.1  christos   r_symndx = ELF32_R_SYM (rel->r_info);
   2023   1.1  christos   r_type = ELF32_R_TYPE (rel->r_info);
   2024   1.1  christos   rel_addr = (input_section->output_section->vma + input_section->output_offset + rel->r_offset);
   2025  1.10  christos   local_p = score_elf_local_relocation_p (input_bfd, rel, local_sections, true);
   2026   1.1  christos 
   2027   1.1  christos   if (r_type == R_SCORE_GOT15)
   2028   1.1  christos     {
   2029   1.1  christos       const Elf_Internal_Rela *relend;
   2030   1.1  christos       const Elf_Internal_Rela *lo16_rel;
   2031   1.1  christos       bfd_vma lo_value = 0;
   2032   1.1  christos 
   2033   1.8  christos       relend = relocs + input_section->reloc_count;
   2034   1.1  christos       lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
   2035   1.1  christos       if ((local_p) && (lo16_rel != NULL))
   2036   1.8  christos 	{
   2037   1.8  christos 	  bfd_vma tmp = 0;
   2038   1.8  christos 	  tmp = score_bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
   2039   1.8  christos 	  lo_value = (((tmp >> 16) & 0x3) << 14) | ((tmp & 0x7fff) >> 1);
   2040   1.8  christos 	}
   2041   1.1  christos       addend = lo_value;
   2042   1.1  christos     }
   2043   1.1  christos   /* For score3 R_SCORE_ABS32.  */
   2044   1.1  christos   else if (r_type == R_SCORE_ABS32 || r_type == R_SCORE_REL32)
   2045   1.1  christos     {
   2046   1.1  christos       addend = (bfd_get_32 (input_bfd, hit_data) >> howto->bitpos) & howto->src_mask;
   2047   1.1  christos     }
   2048   1.1  christos   else
   2049   1.1  christos     {
   2050   1.1  christos       addend = (score_bfd_get_32 (input_bfd, hit_data) >> howto->bitpos) & howto->src_mask;
   2051   1.1  christos     }
   2052   1.1  christos 
   2053   1.1  christos   /* If we haven't already determined the GOT offset, or the GP value,
   2054   1.1  christos      and we're going to need it, get it now.  */
   2055   1.1  christos   switch (r_type)
   2056   1.1  christos     {
   2057   1.1  christos     case R_SCORE_CALL15:
   2058   1.1  christos     case R_SCORE_GOT15:
   2059   1.1  christos       if (!local_p)
   2060   1.8  christos 	{
   2061   1.8  christos 	  g = score_elf_global_got_index (elf_hash_table (info)->dynobj,
   2062   1.8  christos 					  (struct elf_link_hash_entry *) h);
   2063   1.8  christos 	  if ((! elf_hash_table (info)->dynamic_sections_created
   2064   1.8  christos 	       || (bfd_link_pic (info)
   2065   1.8  christos 		   && (info->symbolic || h->root.dynindx == -1)
   2066   1.8  christos 		   && h->root.def_regular)))
   2067   1.8  christos 	    {
   2068   1.8  christos 	      /* This is a static link or a -Bsymbolic link.  The
   2069   1.8  christos 		 symbol is defined locally, or was forced to be local.
   2070   1.8  christos 		 We must initialize this entry in the GOT.  */
   2071   1.8  christos 	      bfd *tmpbfd = elf_hash_table (info)->dynobj;
   2072  1.10  christos 	      asection *sgot = score_elf_got_section (tmpbfd, false);
   2073   1.8  christos 	      score_bfd_put_32 (tmpbfd, value, sgot->contents + g);
   2074   1.8  christos 	    }
   2075   1.8  christos 	}
   2076   1.1  christos       else if (r_type == R_SCORE_GOT15 || r_type == R_SCORE_CALL15)
   2077   1.8  christos 	{
   2078   1.8  christos 	  /* There's no need to create a local GOT entry here; the
   2079   1.8  christos 	     calculation for a local GOT15 entry does not involve G.  */
   2080   1.8  christos 	  ;
   2081   1.8  christos 	}
   2082   1.1  christos       else
   2083   1.8  christos 	{
   2084   1.8  christos 	  g = score_elf_local_got_index (output_bfd, input_bfd, info,
   2085   1.8  christos 					 symbol + addend, r_symndx, h, r_type);
   2086   1.8  christos 	    if (g == MINUS_ONE)
   2087   1.8  christos 	    return bfd_reloc_outofrange;
   2088   1.8  christos 	}
   2089   1.1  christos 
   2090   1.1  christos       /* Convert GOT indices to actual offsets.  */
   2091   1.1  christos       g = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
   2092   1.8  christos 					   output_bfd, input_bfd, g);
   2093   1.1  christos       break;
   2094   1.1  christos 
   2095   1.1  christos     case R_SCORE_HI16:
   2096   1.1  christos     case R_SCORE_LO16:
   2097   1.1  christos     case R_SCORE_GPREL32:
   2098   1.1  christos       gp = _bfd_get_gp_value (output_bfd);
   2099   1.1  christos       break;
   2100   1.1  christos 
   2101   1.1  christos     case R_SCORE_GP15:
   2102   1.1  christos       gp = _bfd_get_gp_value (output_bfd);
   2103   1.1  christos 
   2104   1.1  christos     default:
   2105   1.1  christos       break;
   2106   1.1  christos     }
   2107   1.1  christos 
   2108   1.1  christos   switch (r_type)
   2109   1.1  christos     {
   2110   1.1  christos     case R_SCORE_NONE:
   2111   1.1  christos       return bfd_reloc_ok;
   2112   1.1  christos 
   2113   1.1  christos     case R_SCORE_ABS32:
   2114   1.1  christos     case R_SCORE_REL32:
   2115   1.6  christos       if ((bfd_link_pic (info)
   2116   1.8  christos 	   || (elf_hash_table (info)->dynamic_sections_created
   2117   1.8  christos 	       && h != NULL
   2118   1.8  christos 	       && h->root.def_dynamic
   2119   1.8  christos 	       && !h->root.def_regular))
   2120   1.8  christos 	   && r_symndx != STN_UNDEF
   2121   1.8  christos 	   && (input_section->flags & SEC_ALLOC) != 0)
   2122   1.8  christos 	{
   2123   1.8  christos 	  /* If we're creating a shared library, or this relocation is against a symbol
   2124   1.8  christos 	     in a shared library, then we can't know where the symbol will end up.
   2125   1.8  christos 	     So, we create a relocation record in the output, and leave the job up
   2126   1.8  christos 	     to the dynamic linker.  */
   2127   1.8  christos 	  value = addend;
   2128   1.8  christos 	  if (!score_elf_create_dynamic_relocation (output_bfd, info, rel, h,
   2129   1.8  christos 						    symbol, &value,
   2130   1.8  christos 						    input_section))
   2131   1.8  christos 	    return bfd_reloc_undefined;
   2132   1.8  christos 	}
   2133   1.1  christos       else if (r_symndx == STN_UNDEF)
   2134   1.8  christos 	/* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
   2135   1.8  christos 	   from removed linkonce sections, or sections discarded by
   2136   1.8  christos 	   a linker script.  */
   2137   1.8  christos 	value = 0;
   2138   1.1  christos       else
   2139   1.8  christos 	{
   2140   1.8  christos 	  if (r_type != R_SCORE_REL32)
   2141   1.8  christos 	    value = symbol + addend;
   2142   1.8  christos 	  else
   2143   1.8  christos 	    value = addend;
   2144   1.8  christos 	}
   2145   1.1  christos       value &= howto->dst_mask;
   2146   1.1  christos       bfd_put_32 (input_bfd, value, hit_data);
   2147   1.1  christos       return bfd_reloc_ok;
   2148   1.1  christos 
   2149   1.1  christos     case R_SCORE_ABS16:
   2150   1.1  christos       value += addend;
   2151   1.1  christos       if ((long)value > 0x7fff || (long)value < -0x8000)
   2152   1.8  christos 	return bfd_reloc_overflow;
   2153   1.1  christos       score_bfd_put_16 (input_bfd, value, hit_data);
   2154   1.1  christos       return bfd_reloc_ok;
   2155   1.1  christos 
   2156   1.1  christos     case R_SCORE_24:
   2157   1.1  christos       addend = score_bfd_get_32 (input_bfd, hit_data);
   2158   1.1  christos       offset = (((addend & howto->src_mask) >> 1) & 0x1ff8000) | ((addend & howto->src_mask) & 0x7fff);
   2159   1.1  christos       if ((offset & 0x1000000) != 0)
   2160   1.8  christos 	offset |= 0xfe000000;
   2161   1.1  christos       value += offset;
   2162   1.6  christos       abs_value = value - rel_addr;
   2163   1.1  christos       if ((abs_value & 0xfe000000) != 0)
   2164   1.8  christos 	return bfd_reloc_overflow;
   2165   1.1  christos       addend = (addend & ~howto->src_mask)
   2166   1.8  christos 		| (((value << 1) & howto->src_mask) & 0x3ff0000) | (value & 0x7fff);
   2167   1.1  christos       score_bfd_put_32 (input_bfd, addend, hit_data);
   2168   1.1  christos       return bfd_reloc_ok;
   2169   1.1  christos 
   2170   1.1  christos     /* signed imm32.  */
   2171   1.1  christos     case R_SCORE_IMM30:
   2172   1.1  christos       {
   2173   1.8  christos 	int not_word_align_p = 0;
   2174   1.8  christos 	bfd_vma imm_offset = 0;
   2175   1.8  christos 	addend = score_bfd_get_48 (input_bfd, hit_data);
   2176   1.8  christos 	imm_offset = ((addend >> 7) & 0xff)
   2177   1.8  christos 		     | (((addend >> 16) & 0x7fff) << 8)
   2178   1.8  christos 		     | (((addend >> 32) & 0x7f) << 23);
   2179   1.8  christos 	imm_offset <<= howto->rightshift;
   2180   1.8  christos 	value += imm_offset;
   2181   1.8  christos 	value &= 0xffffffff;
   2182   1.8  christos 
   2183   1.8  christos 	/* Check lw48/sw48 rd, value/label word align.  */
   2184   1.8  christos 	if ((value & 0x3) != 0)
   2185   1.8  christos 	  not_word_align_p = 1;
   2186   1.8  christos 
   2187   1.8  christos 	value >>= howto->rightshift;
   2188   1.8  christos 	addend = (addend & ~howto->src_mask)
   2189   1.8  christos 		 | (((value & 0xff) >> 0) << 7)
   2190   1.8  christos 		 | (((value & 0x7fff00) >> 8) << 16)
   2191   1.8  christos 		 | (((value & 0x3f800000) >> 23) << 32);
   2192   1.8  christos 	score_bfd_put_48 (input_bfd, addend, hit_data);
   2193   1.8  christos 	if (not_word_align_p)
   2194   1.8  christos 	  return bfd_reloc_other;
   2195   1.8  christos 	else
   2196   1.8  christos 	  return bfd_reloc_ok;
   2197   1.1  christos       }
   2198   1.1  christos 
   2199   1.1  christos     case R_SCORE_IMM32:
   2200   1.1  christos       {
   2201   1.8  christos 	bfd_vma imm_offset = 0;
   2202   1.8  christos 	addend = score_bfd_get_48 (input_bfd, hit_data);
   2203   1.8  christos 	imm_offset = ((addend >> 5) & 0x3ff)
   2204   1.8  christos 		     | (((addend >> 16) & 0x7fff) << 10)
   2205   1.8  christos 		     | (((addend >> 32) & 0x7f) << 25);
   2206   1.8  christos 	value += imm_offset;
   2207   1.8  christos 	value &= 0xffffffff;
   2208   1.8  christos 	addend = (addend & ~howto->src_mask)
   2209   1.8  christos 		 | ((value & 0x3ff) << 5)
   2210   1.8  christos 		 | (((value >> 10) & 0x7fff) << 16)
   2211   1.8  christos 		 | (((value >> 25) & 0x7f) << 32);
   2212   1.8  christos 	score_bfd_put_48 (input_bfd, addend, hit_data);
   2213   1.8  christos 	return bfd_reloc_ok;
   2214   1.1  christos       }
   2215   1.1  christos 
   2216   1.1  christos     case R_SCORE_PC19:
   2217   1.1  christos       addend = score_bfd_get_32 (input_bfd, hit_data);
   2218   1.1  christos       offset = (((addend & howto->src_mask) & 0x3ff0000) >> 6) | ((addend & howto->src_mask) & 0x3ff);
   2219   1.1  christos       if ((offset & 0x80000) != 0)
   2220   1.8  christos 	offset |= 0xfff00000;
   2221   1.1  christos       abs_value = value = value - rel_addr + offset;
   2222   1.1  christos       /* exceed 20 bit : overflow.  */
   2223   1.1  christos       if ((abs_value & 0x80000000) == 0x80000000)
   2224   1.8  christos 	abs_value = 0xffffffff - value + 1;
   2225   1.1  christos       if ((abs_value & 0xfff80000) != 0)
   2226   1.8  christos 	return bfd_reloc_overflow;
   2227   1.1  christos       addend = (addend & ~howto->src_mask)
   2228   1.8  christos 		| (((value << 6) & howto->src_mask) & 0x3ff0000) | (value & 0x3ff);
   2229   1.1  christos       score_bfd_put_32 (input_bfd, addend, hit_data);
   2230   1.1  christos       return bfd_reloc_ok;
   2231   1.1  christos 
   2232   1.1  christos     case R_SCORE16_11:
   2233   1.1  christos       addend = score_bfd_get_16 (input_bfd, hit_data);
   2234   1.1  christos       offset = addend & howto->src_mask;
   2235   1.8  christos       if ((offset & 0x800) != 0)	/* Offset is negative.  */
   2236   1.8  christos 	offset |= 0xfffff000;
   2237   1.1  christos       value += offset;
   2238   1.6  christos       abs_value = value - rel_addr;
   2239   1.1  christos       if ((abs_value & 0xfffff000) != 0)
   2240   1.8  christos 	return bfd_reloc_overflow;
   2241   1.1  christos       addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
   2242   1.1  christos       score_bfd_put_16 (input_bfd, addend, hit_data);
   2243   1.1  christos       return bfd_reloc_ok;
   2244   1.1  christos 
   2245   1.1  christos     case R_SCORE16_PC8:
   2246   1.1  christos       addend = score_bfd_get_16 (input_bfd, hit_data);
   2247   1.1  christos       offset = (addend & howto->src_mask) << 1;
   2248   1.8  christos       if ((offset & 0x200) != 0)	/* Offset is negative.  */
   2249   1.8  christos 	offset |= 0xfffffe00;
   2250   1.1  christos       abs_value = value = value - rel_addr + offset;
   2251   1.1  christos       /* Sign bit + exceed 9 bit.  */
   2252   1.1  christos       if (((value & 0xfffffe00) != 0) && ((value & 0xfffffe00) != 0xfffffe00))
   2253   1.8  christos 	return bfd_reloc_overflow;
   2254   1.1  christos       value >>= 1;
   2255   1.1  christos       addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
   2256   1.1  christos       score_bfd_put_16 (input_bfd, addend, hit_data);
   2257   1.1  christos       return bfd_reloc_ok;
   2258   1.1  christos 
   2259   1.1  christos     case R_SCORE_BCMP:
   2260   1.1  christos       addend = score_bfd_get_32 (input_bfd, hit_data);
   2261   1.1  christos       offset = (addend & howto->src_mask) << howto->rightshift;
   2262   1.8  christos       if ((offset & 0x200) != 0)	/* Offset is negative.  */
   2263   1.8  christos 	offset |= 0xfffffe00;
   2264   1.1  christos       value = value - rel_addr + offset;
   2265   1.1  christos       /* Sign bit + exceed 9 bit.  */
   2266   1.1  christos       if (((value & 0xfffffe00) != 0) && ((value & 0xfffffe00) != 0xfffffe00))
   2267   1.8  christos 	return bfd_reloc_overflow;
   2268   1.1  christos       value >>= howto->rightshift;
   2269   1.1  christos       addend = (addend & ~howto->src_mask)
   2270   1.8  christos 	       | (value & 0x1)
   2271   1.8  christos 	       | (((value >> 1) & 0x7) << 7)
   2272   1.8  christos 	       | (((value >> 4) & 0x1f) << 21);
   2273   1.1  christos       score_bfd_put_32 (input_bfd, addend, hit_data);
   2274   1.1  christos       return bfd_reloc_ok;
   2275   1.1  christos 
   2276   1.1  christos     case R_SCORE_HI16:
   2277   1.1  christos       return bfd_reloc_ok;
   2278   1.1  christos 
   2279   1.1  christos     case R_SCORE_LO16:
   2280   1.1  christos       hi16_addend = score_bfd_get_32 (input_bfd, hit_data - 4);
   2281   1.1  christos       hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
   2282   1.1  christos       addend = score_bfd_get_32 (input_bfd, hit_data);
   2283   1.1  christos       offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
   2284   1.1  christos       offset = (hi16_offset << 16) | (offset & 0xffff);
   2285   1.1  christos 
   2286   1.1  christos       if (!gp_disp_p)
   2287   1.8  christos 	uvalue = value + offset;
   2288   1.1  christos       else
   2289   1.8  christos 	uvalue = offset + gp - rel_addr + 4;
   2290   1.1  christos 
   2291   1.1  christos       hi16_offset = (uvalue >> 16) << 1;
   2292   1.1  christos       hi16_value = (hi16_addend & (~(howto->dst_mask)))
   2293   1.8  christos 			| (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
   2294   1.1  christos       score_bfd_put_32 (input_bfd, hi16_value, hit_data - 4);
   2295   1.1  christos       offset = (uvalue & 0xffff) << 1;
   2296   1.1  christos       value = (addend & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
   2297   1.1  christos       score_bfd_put_32 (input_bfd, value, hit_data);
   2298   1.1  christos       return bfd_reloc_ok;
   2299   1.1  christos 
   2300   1.1  christos     case R_SCORE_GP15:
   2301   1.1  christos       addend = score_bfd_get_32 (input_bfd, hit_data);
   2302   1.1  christos       offset = addend & 0x7fff;
   2303   1.1  christos       if ((offset & 0x4000) == 0x4000)
   2304   1.8  christos 	offset |= 0xffffc000;
   2305   1.1  christos       value = value + offset - gp;
   2306   1.1  christos       if (((value & 0xffffc000) != 0) && ((value & 0xffffc000) != 0xffffc000))
   2307   1.8  christos 	return bfd_reloc_overflow;
   2308   1.1  christos       value = (addend & ~howto->src_mask) | (value & howto->src_mask);
   2309   1.1  christos       score_bfd_put_32 (input_bfd, value, hit_data);
   2310   1.1  christos       return bfd_reloc_ok;
   2311   1.1  christos 
   2312   1.1  christos     case R_SCORE_GOT15:
   2313   1.1  christos     case R_SCORE_CALL15:
   2314   1.1  christos       if (local_p)
   2315   1.8  christos 	{
   2316  1.10  christos 	  bool forced;
   2317   1.1  christos 
   2318   1.8  christos 	  /* The special case is when the symbol is forced to be local.  We need the
   2319   1.8  christos 	     full address in the GOT since no R_SCORE_GOT_LO16 relocation follows.  */
   2320   1.8  christos 	  forced = ! score_elf_local_relocation_p (input_bfd, rel,
   2321  1.10  christos 						   local_sections, false);
   2322   1.8  christos 	  value = score_elf_got16_entry (output_bfd, input_bfd, info,
   2323   1.8  christos 					 symbol + addend, forced);
   2324   1.8  christos 	  if (value == MINUS_ONE)
   2325   1.8  christos 	    return bfd_reloc_outofrange;
   2326   1.8  christos 	  value = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
   2327   1.8  christos 						   output_bfd, input_bfd, value);
   2328   1.8  christos 	}
   2329   1.1  christos       else
   2330   1.8  christos 	{
   2331   1.8  christos 	  value = g;
   2332   1.8  christos 	}
   2333   1.1  christos 
   2334   1.1  christos       if ((long) value > 0x3fff || (long) value < -0x4000)
   2335   1.8  christos 	return bfd_reloc_overflow;
   2336   1.1  christos 
   2337   1.1  christos       addend = score_bfd_get_32 (input_bfd, hit_data);
   2338   1.1  christos       value = (addend & ~howto->dst_mask) | (value & howto->dst_mask);
   2339   1.1  christos       score_bfd_put_32 (input_bfd, value, hit_data);
   2340   1.1  christos       return bfd_reloc_ok;
   2341   1.1  christos 
   2342   1.1  christos     case R_SCORE_GPREL32:
   2343   1.1  christos       value = (addend + symbol - gp);
   2344   1.1  christos       value &= howto->dst_mask;
   2345   1.1  christos       score_bfd_put_32 (input_bfd, value, hit_data);
   2346   1.1  christos       return bfd_reloc_ok;
   2347   1.1  christos 
   2348   1.1  christos     case R_SCORE_GOT_LO16:
   2349   1.1  christos       addend = score_bfd_get_32 (input_bfd, hit_data);
   2350   1.1  christos       value = (((addend >> 16) & 0x3) << 14) | ((addend & 0x7fff) >> 1);
   2351   1.1  christos       value += symbol;
   2352   1.1  christos       value = (addend & (~(howto->dst_mask))) | ((value & 0x3fff) << 1)
   2353   1.8  christos 	       | (((value >> 14) & 0x3) << 16);
   2354   1.1  christos 
   2355   1.1  christos       score_bfd_put_32 (input_bfd, value, hit_data);
   2356   1.1  christos       return bfd_reloc_ok;
   2357   1.1  christos 
   2358   1.1  christos     case R_SCORE_DUMMY_HI16:
   2359   1.1  christos       return bfd_reloc_ok;
   2360   1.1  christos 
   2361   1.1  christos     case R_SCORE_GNU_VTINHERIT:
   2362   1.1  christos     case R_SCORE_GNU_VTENTRY:
   2363   1.1  christos       /* We don't do anything with these at present.  */
   2364   1.1  christos       return bfd_reloc_continue;
   2365   1.1  christos 
   2366   1.1  christos     default:
   2367   1.1  christos       return bfd_reloc_notsupported;
   2368   1.1  christos     }
   2369   1.1  christos }
   2370   1.1  christos 
   2371   1.1  christos /* Score backend functions.  */
   2372  1.10  christos static bool
   2373  1.10  christos s3_bfd_score_info_to_howto (bfd *abfd,
   2374   1.8  christos 			    arelent *bfd_reloc,
   2375   1.8  christos 			    Elf_Internal_Rela *elf_reloc)
   2376   1.1  christos {
   2377   1.1  christos   unsigned int r_type;
   2378   1.1  christos 
   2379   1.1  christos   r_type = ELF32_R_TYPE (elf_reloc->r_info);
   2380   1.1  christos   if (r_type >= ARRAY_SIZE (elf32_score_howto_table))
   2381  1.10  christos     {
   2382  1.10  christos       /* xgettext:c-format */
   2383  1.10  christos       _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
   2384  1.10  christos 			  abfd, r_type);
   2385  1.10  christos       bfd_set_error (bfd_error_bad_value);
   2386  1.10  christos       return false;
   2387  1.10  christos     }
   2388   1.8  christos 
   2389   1.8  christos   bfd_reloc->howto = &elf32_score_howto_table[r_type];
   2390  1.10  christos   return true;
   2391   1.1  christos }
   2392   1.1  christos 
   2393   1.1  christos /* Relocate an score ELF section.  */
   2394  1.10  christos static int
   2395   1.1  christos s3_bfd_score_elf_relocate_section (bfd *output_bfd,
   2396   1.8  christos 				   struct bfd_link_info *info,
   2397   1.8  christos 				   bfd *input_bfd,
   2398   1.8  christos 				   asection *input_section,
   2399   1.8  christos 				   bfd_byte *contents,
   2400   1.8  christos 				   Elf_Internal_Rela *relocs,
   2401   1.8  christos 				   Elf_Internal_Sym *local_syms,
   2402   1.8  christos 				   asection **local_sections)
   2403   1.1  christos {
   2404   1.1  christos   Elf_Internal_Shdr *symtab_hdr;
   2405   1.1  christos   Elf_Internal_Rela *rel;
   2406   1.1  christos   Elf_Internal_Rela *relend;
   2407   1.1  christos   const char *name;
   2408   1.1  christos   unsigned long offset;
   2409   1.1  christos   unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
   2410   1.1  christos   size_t extsymoff;
   2411  1.10  christos   bool gp_disp_p = false;
   2412   1.1  christos 
   2413   1.1  christos   /* Sort dynsym.  */
   2414   1.1  christos   if (elf_hash_table (info)->dynamic_sections_created)
   2415   1.1  christos     {
   2416   1.1  christos       bfd_size_type dynsecsymcount = 0;
   2417   1.6  christos       if (bfd_link_pic (info))
   2418   1.8  christos 	{
   2419   1.8  christos 	  asection * p;
   2420   1.8  christos 	  const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
   2421   1.8  christos 
   2422   1.8  christos 	  for (p = output_bfd->sections; p ; p = p->next)
   2423   1.8  christos 	    if ((p->flags & SEC_EXCLUDE) == 0
   2424   1.8  christos 		&& (p->flags & SEC_ALLOC) != 0
   2425   1.8  christos 		&& !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p))
   2426   1.8  christos 	      ++ dynsecsymcount;
   2427   1.8  christos 	}
   2428   1.1  christos 
   2429   1.1  christos       if (!score_elf_sort_hash_table (info, dynsecsymcount + 1))
   2430  1.10  christos 	return false;
   2431   1.1  christos     }
   2432   1.1  christos 
   2433   1.1  christos   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   2434   1.1  christos   extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
   2435   1.1  christos   rel = relocs;
   2436   1.1  christos   relend = relocs + input_section->reloc_count;
   2437   1.1  christos   for (; rel < relend; rel++)
   2438   1.1  christos     {
   2439   1.1  christos       int r_type;
   2440   1.1  christos       reloc_howto_type *howto;
   2441   1.1  christos       unsigned long r_symndx;
   2442   1.1  christos       Elf_Internal_Sym *sym;
   2443   1.1  christos       asection *sec;
   2444   1.1  christos       struct score_elf_link_hash_entry *h;
   2445   1.1  christos       bfd_vma relocation = 0;
   2446   1.1  christos       bfd_reloc_status_type r;
   2447   1.1  christos       arelent bfd_reloc;
   2448   1.1  christos 
   2449   1.1  christos       r_symndx = ELF32_R_SYM (rel->r_info);
   2450   1.1  christos       r_type = ELF32_R_TYPE (rel->r_info);
   2451   1.1  christos 
   2452   1.8  christos       if (! s3_bfd_score_info_to_howto (input_bfd, &bfd_reloc, (Elf_Internal_Rela *) rel))
   2453   1.8  christos 	continue;
   2454   1.1  christos       howto = bfd_reloc.howto;
   2455   1.1  christos 
   2456   1.1  christos       h = NULL;
   2457   1.1  christos       sym = NULL;
   2458   1.1  christos       sec = NULL;
   2459   1.1  christos 
   2460   1.1  christos       if (r_symndx < extsymoff)
   2461   1.8  christos 	{
   2462   1.8  christos 	  sym = local_syms + r_symndx;
   2463   1.8  christos 	  sec = local_sections[r_symndx];
   2464   1.8  christos 	  relocation = (sec->output_section->vma
   2465   1.8  christos 			+ sec->output_offset
   2466   1.8  christos 			+ sym->st_value);
   2467   1.8  christos 	  name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, sec);
   2468   1.8  christos 
   2469   1.8  christos 	  if (!bfd_link_relocatable (info)
   2470   1.8  christos 	      && (sec->flags & SEC_MERGE)
   2471   1.8  christos 	      && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
   2472   1.8  christos 	    {
   2473   1.8  christos 	      asection *msec;
   2474   1.8  christos 	      bfd_vma addend, value;
   2475   1.8  christos 
   2476   1.8  christos 	      switch (r_type)
   2477   1.8  christos 		{
   2478   1.8  christos 		case R_SCORE_HI16:
   2479   1.8  christos 		  break;
   2480   1.8  christos 		case R_SCORE_LO16:
   2481   1.8  christos 		  hi16_addend = score_bfd_get_32 (input_bfd, contents + rel->r_offset - 4);
   2482   1.8  christos 		  hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
   2483   1.8  christos 		  value = score_bfd_get_32 (input_bfd, contents + rel->r_offset);
   2484   1.8  christos 		  offset = ((((value >> 16) & 0x3) << 15) | (value & 0x7fff)) >> 1;
   2485   1.8  christos 		  addend = (hi16_offset << 16) | (offset & 0xffff);
   2486   1.8  christos 		  msec = sec;
   2487   1.8  christos 		  addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend);
   2488   1.8  christos 		  addend -= relocation;
   2489   1.8  christos 		  addend += msec->output_section->vma + msec->output_offset;
   2490   1.8  christos 		  uvalue = addend;
   2491   1.8  christos 		  hi16_offset = (uvalue >> 16) << 1;
   2492   1.8  christos 		  hi16_value = (hi16_addend & (~(howto->dst_mask)))
   2493   1.8  christos 		    | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
   2494   1.8  christos 		  score_bfd_put_32 (input_bfd, hi16_value, contents + rel->r_offset - 4);
   2495   1.8  christos 		  offset = (uvalue & 0xffff) << 1;
   2496   1.8  christos 		  value = (value & (~(howto->dst_mask)))
   2497   1.8  christos 		    | (offset & 0x7fff) | ((offset << 1) & 0x30000);
   2498   1.8  christos 		  score_bfd_put_32 (input_bfd, value, contents + rel->r_offset);
   2499   1.8  christos 		  break;
   2500   1.8  christos 
   2501   1.8  christos 		case R_SCORE_IMM32:
   2502   1.8  christos 		  {
   2503   1.8  christos 		    value = score_bfd_get_48 (input_bfd, contents + rel->r_offset);
   2504   1.8  christos 		    addend = ((value >> 5) & 0x3ff)
   2505   1.8  christos 			      | (((value >> 16) & 0x7fff) << 10)
   2506   1.8  christos 			      | (((value >> 32) & 0x7f) << 25);
   2507   1.8  christos 		    msec = sec;
   2508   1.8  christos 		    addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend);
   2509   1.8  christos 		    addend -= relocation;
   2510   1.8  christos 		    addend += msec->output_section->vma + msec->output_offset;
   2511   1.8  christos 		    addend &= 0xffffffff;
   2512   1.8  christos 		    value = (value & ~howto->src_mask)
   2513   1.8  christos 			     | ((addend & 0x3ff) << 5)
   2514   1.8  christos 			     | (((addend >> 10) & 0x7fff) << 16)
   2515   1.8  christos 			     | (((addend >> 25) & 0x7f) << 32);
   2516   1.8  christos 		    score_bfd_put_48 (input_bfd, value, contents + rel->r_offset);
   2517   1.8  christos 		    break;
   2518   1.8  christos 		  }
   2519   1.8  christos 
   2520   1.8  christos 		case R_SCORE_IMM30:
   2521   1.8  christos 		  {
   2522   1.8  christos 		    int not_word_align_p = 0;
   2523   1.8  christos 		    value = score_bfd_get_48 (input_bfd, contents + rel->r_offset);
   2524   1.8  christos 		    addend = ((value >> 7) & 0xff)
   2525   1.8  christos 			      | (((value >> 16) & 0x7fff) << 8)
   2526   1.8  christos 			      | (((value >> 32) & 0x7f) << 23);
   2527   1.8  christos 		    addend <<= howto->rightshift;
   2528   1.8  christos 		    msec = sec;
   2529   1.8  christos 		    addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend);
   2530   1.8  christos 		    addend -= relocation;
   2531   1.8  christos 		    addend += msec->output_section->vma + msec->output_offset;
   2532   1.8  christos 		    addend &= 0xffffffff;
   2533   1.8  christos 
   2534   1.8  christos 		    /* Check lw48/sw48 rd, value/label word align.  */
   2535   1.8  christos 		    if ((addend & 0x3) != 0)
   2536   1.8  christos 		      not_word_align_p = 1;
   2537   1.8  christos 
   2538   1.8  christos 		    addend >>= howto->rightshift;
   2539   1.8  christos 		    value = (value & ~howto->src_mask)
   2540   1.8  christos 			     | (((addend & 0xff) >> 0) << 7)
   2541   1.8  christos 			     | (((addend & 0x7fff00) >> 8) << 16)
   2542   1.8  christos 			     | (((addend & 0x3f800000) >> 23) << 32);
   2543   1.8  christos 		    score_bfd_put_48 (input_bfd, value, contents + rel->r_offset);
   2544   1.8  christos 
   2545   1.8  christos 		    if (not_word_align_p)
   2546   1.8  christos 		      return bfd_reloc_other;
   2547   1.8  christos 		    else
   2548   1.8  christos 		      break;
   2549   1.8  christos 		  }
   2550   1.8  christos 
   2551   1.8  christos 		case R_SCORE_GOT_LO16:
   2552   1.8  christos 		  value = score_bfd_get_32 (input_bfd, contents + rel->r_offset);
   2553   1.8  christos 		  addend = (((value >> 16) & 0x3) << 14) | ((value & 0x7fff) >> 1);
   2554   1.8  christos 		  msec = sec;
   2555   1.8  christos 		  addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
   2556   1.8  christos 		  addend += msec->output_section->vma + msec->output_offset;
   2557   1.8  christos 		  value = (value & (~(howto->dst_mask))) | ((addend & 0x3fff) << 1)
   2558   1.8  christos 			   | (((addend >> 14) & 0x3) << 16);
   2559   1.8  christos 
   2560   1.8  christos 		  score_bfd_put_32 (input_bfd, value, contents + rel->r_offset);
   2561   1.8  christos 		  break;
   2562   1.8  christos 
   2563   1.8  christos 		case R_SCORE_ABS32:
   2564   1.8  christos 		case R_SCORE_REL32:
   2565   1.8  christos 		  value = bfd_get_32 (input_bfd, contents + rel->r_offset);
   2566   1.8  christos 		  /* Get the (signed) value from the instruction.  */
   2567   1.8  christos 		  addend = value & howto->src_mask;
   2568   1.8  christos 		  if (addend & ((howto->src_mask + 1) >> 1))
   2569   1.8  christos 		    {
   2570   1.8  christos 		      bfd_signed_vma mask;
   2571   1.8  christos 
   2572   1.8  christos 		      mask = -1;
   2573   1.8  christos 		      mask &= ~howto->src_mask;
   2574   1.8  christos 		      addend |= mask;
   2575   1.8  christos 		    }
   2576   1.8  christos 		  msec = sec;
   2577   1.8  christos 		  addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
   2578   1.8  christos 		  addend += msec->output_section->vma + msec->output_offset;
   2579   1.8  christos 		  value = (value & ~howto->dst_mask) | (addend & howto->dst_mask);
   2580   1.8  christos 		  bfd_put_32 (input_bfd, value, contents + rel->r_offset);
   2581   1.8  christos 		  break;
   2582   1.8  christos 
   2583   1.8  christos 		default:
   2584   1.8  christos 		  value = score_bfd_get_32 (input_bfd, contents + rel->r_offset);
   2585   1.8  christos 		  /* Get the (signed) value from the instruction.  */
   2586   1.8  christos 		  addend = value & howto->src_mask;
   2587   1.8  christos 		  if (addend & ((howto->src_mask + 1) >> 1))
   2588   1.8  christos 		    {
   2589   1.8  christos 		      bfd_signed_vma mask;
   2590   1.8  christos 
   2591   1.8  christos 		      mask = -1;
   2592   1.8  christos 		      mask &= ~howto->src_mask;
   2593   1.8  christos 		      addend |= mask;
   2594   1.8  christos 		    }
   2595   1.8  christos 		  msec = sec;
   2596   1.8  christos 		  addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
   2597   1.8  christos 		  addend += msec->output_section->vma + msec->output_offset;
   2598   1.8  christos 		  value = (value & ~howto->dst_mask) | (addend & howto->dst_mask);
   2599   1.8  christos 		  score_bfd_put_32 (input_bfd, value, contents + rel->r_offset);
   2600   1.8  christos 		  break;
   2601   1.8  christos 		}
   2602   1.8  christos 	    }
   2603   1.8  christos 	}
   2604   1.1  christos       else
   2605   1.8  christos 	{
   2606   1.8  christos 	  /* For global symbols we look up the symbol in the hash-table.  */
   2607   1.8  christos 	  h = ((struct score_elf_link_hash_entry *)
   2608   1.8  christos 	       elf_sym_hashes (input_bfd) [r_symndx - extsymoff]);
   2609   1.3  christos 
   2610   1.3  christos 	  if (info->wrap_hash != NULL
   2611   1.3  christos 	      && (input_section->flags & SEC_DEBUGGING) != 0)
   2612   1.3  christos 	    h = ((struct score_elf_link_hash_entry *)
   2613   1.3  christos 		 unwrap_hash_lookup (info, input_bfd, &h->root.root));
   2614   1.3  christos 
   2615   1.8  christos 	  /* Find the real hash-table entry for this symbol.  */
   2616   1.8  christos 	  while (h->root.root.type == bfd_link_hash_indirect
   2617   1.8  christos 		 || h->root.root.type == bfd_link_hash_warning)
   2618   1.8  christos 	    h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
   2619   1.8  christos 
   2620   1.8  christos 	  /* Record the name of this symbol, for our caller.  */
   2621   1.8  christos 	  name = h->root.root.root.string;
   2622   1.8  christos 
   2623   1.8  christos 	  /* See if this is the special GP_DISP_LABEL symbol.  Note that such a
   2624   1.8  christos 	     symbol must always be a global symbol.  */
   2625   1.8  christos 	  if (strcmp (name, GP_DISP_LABEL) == 0)
   2626   1.8  christos 	    {
   2627   1.8  christos 	      /* Relocations against GP_DISP_LABEL are permitted only with
   2628   1.8  christos 		 R_SCORE_HI16 and R_SCORE_LO16 relocations.  */
   2629   1.8  christos 	      if (r_type != R_SCORE_HI16 && r_type != R_SCORE_LO16)
   2630   1.8  christos 		return bfd_reloc_notsupported;
   2631   1.8  christos 
   2632  1.10  christos 	      gp_disp_p = true;
   2633   1.8  christos 	    }
   2634   1.8  christos 
   2635   1.8  christos 	  /* If this symbol is defined, calculate its address.  Note that
   2636   1.8  christos 	      GP_DISP_LABEL is a magic symbol, always implicitly defined by the
   2637   1.8  christos 	      linker, so it's inappropriate to check to see whether or not
   2638   1.8  christos 	      its defined.  */
   2639   1.8  christos 	  else if ((h->root.root.type == bfd_link_hash_defined
   2640   1.8  christos 		    || h->root.root.type == bfd_link_hash_defweak)
   2641   1.8  christos 		   && h->root.root.u.def.section)
   2642   1.8  christos 	    {
   2643   1.8  christos 	      sec = h->root.root.u.def.section;
   2644   1.8  christos 	      if (sec->output_section)
   2645   1.8  christos 		relocation = (h->root.root.u.def.value
   2646   1.8  christos 			      + sec->output_section->vma
   2647   1.8  christos 			      + sec->output_offset);
   2648   1.8  christos 	      else
   2649   1.8  christos 		{
   2650   1.8  christos 		  relocation = h->root.root.u.def.value;
   2651   1.8  christos 		}
   2652   1.8  christos 	    }
   2653   1.8  christos 	  else if (h->root.root.type == bfd_link_hash_undefweak)
   2654   1.8  christos 	    /* We allow relocations against undefined weak symbols, giving
   2655   1.8  christos 	       it the value zero, so that you can undefined weak functions
   2656   1.8  christos 	       and check to see if they exist by looking at their addresses.  */
   2657   1.8  christos 	    relocation = 0;
   2658   1.8  christos 	  else if (info->unresolved_syms_in_objects == RM_IGNORE
   2659   1.8  christos 		   && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
   2660   1.8  christos 	    relocation = 0;
   2661   1.8  christos 	  else if (strcmp (name, "_DYNAMIC_LINK") == 0)
   2662   1.8  christos 	    {
   2663   1.8  christos 	      /* If this is a dynamic link, we should have created a _DYNAMIC_LINK symbol
   2664   1.8  christos 		 in s3_bfd_score_elf_create_dynamic_sections.  Otherwise, we should define
   2665   1.8  christos 		 the symbol with a value of 0.  */
   2666   1.8  christos 	      BFD_ASSERT (! bfd_link_pic (info));
   2667   1.8  christos 	      BFD_ASSERT (bfd_get_section_by_name (output_bfd, ".dynamic") == NULL);
   2668   1.8  christos 	      relocation = 0;
   2669   1.8  christos 	    }
   2670   1.8  christos 	  else if (!bfd_link_relocatable (info))
   2671   1.8  christos 	    {
   2672   1.9  christos               info->callbacks->undefined_symbol
   2673   1.9  christos 		(info, h->root.root.root.string, input_bfd, input_section,
   2674   1.9  christos 		 rel->r_offset,
   2675   1.9  christos 		 (info->unresolved_syms_in_objects == RM_DIAGNOSE
   2676   1.9  christos 		  && !info->warn_unresolved_syms)
   2677   1.6  christos 		 || ELF_ST_VISIBILITY (h->root.other));
   2678   1.9  christos               relocation = 0;
   2679   1.9  christos             }
   2680   1.8  christos 	}
   2681   1.1  christos 
   2682   1.1  christos       if (sec != NULL && discarded_section (sec))
   2683   1.1  christos 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
   2684   1.1  christos 					 rel, 1, relend, howto, 0, contents);
   2685   1.1  christos 
   2686   1.6  christos       if (bfd_link_relocatable (info))
   2687   1.8  christos 	{
   2688   1.8  christos 	  /* This is a relocatable link.  We don't have to change
   2689   1.8  christos 	     anything, unless the reloc is against a section symbol,
   2690   1.8  christos 	     in which case we have to adjust according to where the
   2691   1.8  christos 	     section symbol winds up in the output section.  */
   2692   1.8  christos 	  if (r_symndx < symtab_hdr->sh_info)
   2693   1.8  christos 	    {
   2694   1.8  christos 	      sym = local_syms + r_symndx;
   2695   1.8  christos 	      if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
   2696   1.8  christos 		{
   2697   1.8  christos 		  sec = local_sections[r_symndx];
   2698   1.8  christos 		  score_elf_add_to_rel (input_bfd, contents + rel->r_offset,
   2699   1.8  christos 				    howto, (bfd_signed_vma) (sec->output_offset + sym->st_value));
   2700   1.8  christos 		}
   2701   1.8  christos 	    }
   2702   1.8  christos 	  continue;
   2703   1.8  christos 	}
   2704   1.1  christos 
   2705   1.1  christos       /* This is a final link.  */
   2706   1.1  christos       r = score_elf_final_link_relocate (howto, input_bfd, output_bfd,
   2707   1.8  christos 					 input_section, contents, rel, relocs,
   2708   1.8  christos 					 relocation, info, name,
   2709   1.8  christos 					 (h ? ELF_ST_TYPE ((unsigned int)h->root.root.type) :
   2710   1.8  christos 					 ELF_ST_TYPE ((unsigned int)sym->st_info)), h, local_sections,
   2711   1.8  christos 					 gp_disp_p);
   2712   1.1  christos 
   2713   1.1  christos       if (r != bfd_reloc_ok)
   2714   1.8  christos 	{
   2715   1.8  christos 	  const char *msg = (const char *)0;
   2716   1.1  christos 
   2717   1.8  christos 	  switch (r)
   2718   1.8  christos 	    {
   2719   1.8  christos 	    case bfd_reloc_overflow:
   2720   1.8  christos 	      /* If the overflowing reloc was to an undefined symbol,
   2721   1.8  christos 		 we have already printed one error message and there
   2722   1.8  christos 		 is no point complaining again.  */
   2723   1.6  christos 	      if (!h || h->root.root.type != bfd_link_hash_undefined)
   2724   1.6  christos 		(*info->callbacks->reloc_overflow)
   2725   1.6  christos 		  (info, NULL, name, howto->name, (bfd_vma) 0,
   2726   1.6  christos 		   input_bfd, input_section, rel->r_offset);
   2727   1.8  christos 	      break;
   2728   1.8  christos 	    case bfd_reloc_undefined:
   2729   1.6  christos 	      (*info->callbacks->undefined_symbol)
   2730  1.10  christos 		(info, name, input_bfd, input_section, rel->r_offset, true);
   2731   1.8  christos 	      break;
   2732   1.8  christos 
   2733   1.8  christos 	    case bfd_reloc_outofrange:
   2734   1.8  christos 	      msg = _("internal error: out of range error");
   2735   1.8  christos 	      goto common_error;
   2736   1.8  christos 
   2737   1.8  christos 	    case bfd_reloc_notsupported:
   2738   1.8  christos 	      msg = _("internal error: unsupported relocation error");
   2739   1.8  christos 	      goto common_error;
   2740   1.8  christos 
   2741   1.8  christos 	    case bfd_reloc_dangerous:
   2742   1.8  christos 	      msg = _("internal error: dangerous error");
   2743   1.8  christos 	      goto common_error;
   2744   1.8  christos 
   2745   1.8  christos 	    /* Use bfd_reloc_other to check lw48, sw48 word align.  */
   2746   1.8  christos 	    case bfd_reloc_other:
   2747   1.8  christos 	      msg = _("address not word aligned");
   2748   1.8  christos 	      goto common_error;
   2749   1.1  christos 
   2750   1.8  christos 	    default:
   2751   1.8  christos 	      msg = _("internal error: unknown error");
   2752   1.8  christos 	      /* Fall through.  */
   2753   1.1  christos 
   2754   1.8  christos 	    common_error:
   2755   1.6  christos 	      (*info->callbacks->warning) (info, msg, name, input_bfd,
   2756   1.6  christos 					   input_section, rel->r_offset);
   2757   1.8  christos 	      break;
   2758   1.8  christos 	    }
   2759   1.8  christos 	}
   2760   1.1  christos     }
   2761   1.1  christos 
   2762  1.10  christos   return true;
   2763   1.1  christos }
   2764   1.1  christos 
   2765   1.1  christos /* Look through the relocs for a section during the first phase, and
   2766   1.1  christos    allocate space in the global offset table.  */
   2767  1.10  christos static bool
   2768   1.1  christos s3_bfd_score_elf_check_relocs (bfd *abfd,
   2769   1.8  christos 			       struct bfd_link_info *info,
   2770   1.8  christos 			       asection *sec,
   2771   1.8  christos 			       const Elf_Internal_Rela *relocs)
   2772   1.1  christos {
   2773   1.1  christos   bfd *dynobj;
   2774   1.1  christos   Elf_Internal_Shdr *symtab_hdr;
   2775   1.1  christos   struct elf_link_hash_entry **sym_hashes;
   2776   1.1  christos   struct score_got_info *g;
   2777   1.1  christos   size_t extsymoff;
   2778   1.1  christos   const Elf_Internal_Rela *rel;
   2779   1.1  christos   const Elf_Internal_Rela *rel_end;
   2780   1.1  christos   asection *sgot;
   2781   1.1  christos   asection *sreloc;
   2782   1.1  christos 
   2783   1.6  christos   if (bfd_link_relocatable (info))
   2784  1.10  christos     return true;
   2785   1.1  christos 
   2786   1.1  christos   dynobj = elf_hash_table (info)->dynobj;
   2787   1.1  christos   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   2788   1.1  christos   sym_hashes = elf_sym_hashes (abfd);
   2789   1.1  christos   extsymoff = (elf_bad_symtab (abfd)) ? 0 : symtab_hdr->sh_info;
   2790   1.1  christos 
   2791   1.1  christos   if (dynobj == NULL)
   2792   1.1  christos     {
   2793   1.1  christos       sgot = NULL;
   2794   1.1  christos       g = NULL;
   2795   1.1  christos     }
   2796   1.1  christos   else
   2797   1.1  christos     {
   2798  1.10  christos       sgot = score_elf_got_section (dynobj, false);
   2799   1.1  christos       if (sgot == NULL)
   2800   1.8  christos 	g = NULL;
   2801   1.1  christos       else
   2802   1.8  christos 	{
   2803   1.8  christos 	  BFD_ASSERT (score_elf_section_data (sgot) != NULL);
   2804   1.8  christos 	  g = score_elf_section_data (sgot)->u.got_info;
   2805   1.8  christos 	  BFD_ASSERT (g != NULL);
   2806   1.8  christos 	}
   2807   1.1  christos     }
   2808   1.1  christos 
   2809   1.1  christos   sreloc = NULL;
   2810   1.8  christos   rel_end = relocs + sec->reloc_count;
   2811   1.1  christos   for (rel = relocs; rel < rel_end; ++rel)
   2812   1.1  christos     {
   2813   1.1  christos       unsigned long r_symndx;
   2814   1.1  christos       unsigned int r_type;
   2815   1.1  christos       struct elf_link_hash_entry *h;
   2816   1.1  christos 
   2817   1.1  christos       r_symndx = ELF32_R_SYM (rel->r_info);
   2818   1.1  christos       r_type = ELF32_R_TYPE (rel->r_info);
   2819   1.1  christos 
   2820   1.1  christos       if (r_symndx < extsymoff)
   2821   1.8  christos 	{
   2822   1.8  christos 	  h = NULL;
   2823   1.8  christos 	}
   2824   1.1  christos       else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr))
   2825   1.8  christos 	{
   2826   1.7  christos 	  _bfd_error_handler
   2827   1.7  christos 	    /* xgettext:c-format */
   2828   1.8  christos 	    (_("%pB: malformed reloc detected for section %pA"), abfd, sec);
   2829   1.8  christos 	  bfd_set_error (bfd_error_bad_value);
   2830  1.10  christos 	  return false;
   2831   1.8  christos 	}
   2832   1.1  christos       else
   2833   1.8  christos 	{
   2834   1.8  christos 	  h = sym_hashes[r_symndx - extsymoff];
   2835   1.1  christos 
   2836   1.8  christos 	  /* This may be an indirect symbol created because of a version.  */
   2837   1.8  christos 	  if (h != NULL)
   2838   1.8  christos 	    {
   2839   1.8  christos 	      while (h->root.type == bfd_link_hash_indirect)
   2840   1.8  christos 		h = (struct elf_link_hash_entry *)h->root.u.i.link;
   2841   1.8  christos 	    }
   2842   1.8  christos 	}
   2843   1.1  christos 
   2844   1.1  christos       /* Some relocs require a global offset table.  */
   2845   1.1  christos       if (dynobj == NULL || sgot == NULL)
   2846   1.8  christos 	{
   2847   1.8  christos 	  switch (r_type)
   2848   1.8  christos 	    {
   2849   1.8  christos 	    case R_SCORE_GOT15:
   2850   1.8  christos 	    case R_SCORE_CALL15:
   2851   1.8  christos 	      if (dynobj == NULL)
   2852   1.8  christos 		elf_hash_table (info)->dynobj = dynobj = abfd;
   2853  1.10  christos 	      if (!score_elf_create_got_section (dynobj, info, false))
   2854  1.10  christos 		return false;
   2855   1.8  christos 	      g = score_elf_got_info (dynobj, &sgot);
   2856   1.8  christos 	      break;
   2857   1.8  christos 	    case R_SCORE_ABS32:
   2858   1.8  christos 	    case R_SCORE_REL32:
   2859   1.8  christos 	      if (dynobj == NULL
   2860   1.6  christos 		  && (bfd_link_pic (info) || h != NULL)
   2861   1.6  christos 		  && (sec->flags & SEC_ALLOC) != 0)
   2862   1.8  christos 		elf_hash_table (info)->dynobj = dynobj = abfd;
   2863   1.8  christos 	      break;
   2864   1.8  christos 	    default:
   2865   1.8  christos 	      break;
   2866   1.8  christos 	    }
   2867   1.8  christos 	}
   2868   1.1  christos 
   2869   1.1  christos       if (!h && (r_type == R_SCORE_GOT_LO16))
   2870   1.8  christos 	{
   2871   1.8  christos 	  if (! score_elf_record_local_got_symbol (abfd, r_symndx, rel->r_addend, g))
   2872  1.10  christos 	    return false;
   2873   1.8  christos 	}
   2874   1.1  christos 
   2875   1.1  christos       switch (r_type)
   2876   1.8  christos 	{
   2877   1.8  christos 	case R_SCORE_CALL15:
   2878   1.8  christos 	  if (h == NULL)
   2879   1.8  christos 	    {
   2880   1.7  christos 	      _bfd_error_handler
   2881   1.7  christos 		/* xgettext:c-format */
   2882   1.8  christos 		(_("%pB: CALL15 reloc at %#" PRIx64 " not against global symbol"),
   2883   1.8  christos 		 abfd, (uint64_t) rel->r_offset);
   2884   1.8  christos 	      bfd_set_error (bfd_error_bad_value);
   2885  1.10  christos 	      return false;
   2886   1.8  christos 	    }
   2887   1.8  christos 	  else
   2888   1.8  christos 	    {
   2889   1.8  christos 	      /* This symbol requires a global offset table entry.  */
   2890   1.8  christos 	      if (! score_elf_record_global_got_symbol (h, abfd, info, g))
   2891  1.10  christos 		return false;
   2892   1.8  christos 
   2893   1.8  christos 	      /* We need a stub, not a plt entry for the undefined function.  But we record
   2894   1.8  christos 		 it as if it needs plt.  See _bfd_elf_adjust_dynamic_symbol.  */
   2895   1.8  christos 	      h->needs_plt = 1;
   2896   1.8  christos 	      h->type = STT_FUNC;
   2897   1.8  christos 	    }
   2898   1.8  christos 	  break;
   2899   1.8  christos 	case R_SCORE_GOT15:
   2900   1.8  christos 	  if (h && ! score_elf_record_global_got_symbol (h, abfd, info, g))
   2901  1.10  christos 	    return false;
   2902   1.8  christos 	  break;
   2903   1.8  christos 	case R_SCORE_ABS32:
   2904   1.8  christos 	case R_SCORE_REL32:
   2905   1.8  christos 	  if ((bfd_link_pic (info) || h != NULL)
   2906   1.6  christos 	      && (sec->flags & SEC_ALLOC) != 0)
   2907   1.8  christos 	    {
   2908   1.8  christos 	      if (sreloc == NULL)
   2909   1.8  christos 		{
   2910  1.10  christos 		  sreloc = score_elf_rel_dyn_section (dynobj, true);
   2911   1.8  christos 		  if (sreloc == NULL)
   2912  1.10  christos 		    return false;
   2913   1.8  christos 		}
   2914   1.1  christos #define SCORE_READONLY_SECTION (SEC_ALLOC | SEC_LOAD | SEC_READONLY)
   2915   1.8  christos 	      if (bfd_link_pic (info))
   2916   1.8  christos 		{
   2917   1.8  christos 		  /* When creating a shared object, we must copy these reloc types into
   2918   1.8  christos 		     the output file as R_SCORE_REL32 relocs.  We make room for this reloc
   2919   1.8  christos 		     in the .rel.dyn reloc section.  */
   2920   1.8  christos 		  score_elf_allocate_dynamic_relocations (dynobj, 1);
   2921   1.8  christos 		  if ((sec->flags & SCORE_READONLY_SECTION)
   2922   1.8  christos 		      == SCORE_READONLY_SECTION)
   2923   1.8  christos 		    /* We tell the dynamic linker that there are
   2924   1.8  christos 		       relocations against the text segment.  */
   2925   1.8  christos 		    info->flags |= DF_TEXTREL;
   2926   1.8  christos 		}
   2927   1.8  christos 	      else
   2928   1.8  christos 		{
   2929   1.8  christos 		  struct score_elf_link_hash_entry *hscore;
   2930   1.8  christos 
   2931   1.8  christos 		  /* We only need to copy this reloc if the symbol is
   2932   1.8  christos 		     defined in a dynamic object.  */
   2933   1.8  christos 		  hscore = (struct score_elf_link_hash_entry *)h;
   2934   1.8  christos 		  ++hscore->possibly_dynamic_relocs;
   2935   1.8  christos 		  if ((sec->flags & SCORE_READONLY_SECTION)
   2936   1.8  christos 		      == SCORE_READONLY_SECTION)
   2937   1.8  christos 		    /* We need it to tell the dynamic linker if there
   2938   1.8  christos 		       are relocations against the text segment.  */
   2939  1.10  christos 		    hscore->readonly_reloc = true;
   2940   1.8  christos 		}
   2941   1.8  christos 
   2942   1.8  christos 	      /* Even though we don't directly need a GOT entry for this symbol,
   2943   1.8  christos 		 a symbol must have a dynamic symbol table index greater that
   2944   1.8  christos 		 DT_SCORE_GOTSYM if there are dynamic relocations against it.  */
   2945   1.8  christos 	      if (h != NULL)
   2946   1.8  christos 		{
   2947   1.8  christos 		  if (dynobj == NULL)
   2948   1.8  christos 		    elf_hash_table (info)->dynobj = dynobj = abfd;
   2949  1.10  christos 		  if (! score_elf_create_got_section (dynobj, info, true))
   2950  1.10  christos 		    return false;
   2951   1.8  christos 		  g = score_elf_got_info (dynobj, &sgot);
   2952   1.8  christos 		  if (! score_elf_record_global_got_symbol (h, abfd, info, g))
   2953  1.10  christos 		    return false;
   2954   1.8  christos 		}
   2955   1.8  christos 	    }
   2956   1.8  christos 	  break;
   2957   1.8  christos 
   2958   1.8  christos 	  /* This relocation describes the C++ object vtable hierarchy.
   2959   1.8  christos 	     Reconstruct it for later use during GC.  */
   2960   1.8  christos 	case R_SCORE_GNU_VTINHERIT:
   2961   1.8  christos 	  if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
   2962  1.10  christos 	    return false;
   2963   1.8  christos 	  break;
   2964   1.8  christos 
   2965   1.8  christos 	  /* This relocation describes which C++ vtable entries are actually
   2966   1.8  christos 	     used.  Record for later use during GC.  */
   2967   1.8  christos 	case R_SCORE_GNU_VTENTRY:
   2968   1.8  christos 	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
   2969  1.10  christos 	    return false;
   2970   1.8  christos 	  break;
   2971   1.8  christos 	default:
   2972   1.8  christos 	  break;
   2973   1.8  christos 	}
   2974   1.1  christos 
   2975   1.1  christos       /* We must not create a stub for a symbol that has relocations
   2976   1.8  christos 	 related to taking the function's address.  */
   2977   1.1  christos       switch (r_type)
   2978   1.8  christos 	{
   2979   1.8  christos 	default:
   2980   1.8  christos 	  if (h != NULL)
   2981   1.8  christos 	    {
   2982   1.8  christos 	      struct score_elf_link_hash_entry *sh;
   2983   1.8  christos 
   2984   1.8  christos 	      sh = (struct score_elf_link_hash_entry *) h;
   2985  1.10  christos 	      sh->no_fn_stub = true;
   2986   1.8  christos 	    }
   2987   1.8  christos 	  break;
   2988   1.8  christos 	case R_SCORE_CALL15:
   2989   1.8  christos 	  break;
   2990   1.8  christos 	}
   2991   1.1  christos     }
   2992   1.1  christos 
   2993  1.10  christos   return true;
   2994   1.1  christos }
   2995   1.1  christos 
   2996  1.10  christos static bool
   2997   1.1  christos s3_bfd_score_elf_add_symbol_hook (bfd *abfd,
   2998   1.8  christos 				  struct bfd_link_info *info ATTRIBUTE_UNUSED,
   2999   1.8  christos 				  Elf_Internal_Sym *sym,
   3000   1.8  christos 				  const char **namep ATTRIBUTE_UNUSED,
   3001   1.8  christos 				  flagword *flagsp ATTRIBUTE_UNUSED,
   3002   1.8  christos 				  asection **secp,
   3003   1.8  christos 				  bfd_vma *valp)
   3004   1.1  christos {
   3005   1.1  christos   switch (sym->st_shndx)
   3006   1.1  christos     {
   3007   1.1  christos     case SHN_COMMON:
   3008   1.1  christos       if (sym->st_size > elf_gp_size (abfd))
   3009   1.8  christos 	break;
   3010   1.1  christos       /* Fall through.  */
   3011   1.1  christos     case SHN_SCORE_SCOMMON:
   3012   1.1  christos       *secp = bfd_make_section_old_way (abfd, ".scommon");
   3013   1.9  christos       (*secp)->flags |= SEC_IS_COMMON | SEC_SMALL_DATA;
   3014   1.1  christos       *valp = sym->st_size;
   3015   1.1  christos       break;
   3016   1.1  christos     }
   3017   1.1  christos 
   3018  1.10  christos   return true;
   3019   1.1  christos }
   3020   1.1  christos 
   3021   1.1  christos static void
   3022   1.1  christos s3_bfd_score_elf_symbol_processing (bfd *abfd, asymbol *asym)
   3023   1.1  christos {
   3024   1.1  christos   elf_symbol_type *elfsym;
   3025   1.1  christos 
   3026   1.1  christos   elfsym = (elf_symbol_type *) asym;
   3027   1.1  christos   switch (elfsym->internal_elf_sym.st_shndx)
   3028   1.1  christos     {
   3029   1.1  christos     case SHN_COMMON:
   3030   1.1  christos       if (asym->value > elf_gp_size (abfd))
   3031   1.8  christos 	break;
   3032   1.1  christos       /* Fall through.  */
   3033   1.1  christos     case SHN_SCORE_SCOMMON:
   3034   1.1  christos       asym->section = &score_elf_scom_section;
   3035   1.1  christos       asym->value = elfsym->internal_elf_sym.st_size;
   3036   1.1  christos       break;
   3037   1.1  christos     }
   3038   1.1  christos }
   3039   1.1  christos 
   3040   1.1  christos static int
   3041   1.1  christos s3_bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
   3042   1.8  christos 					  const char *name ATTRIBUTE_UNUSED,
   3043   1.8  christos 					  Elf_Internal_Sym *sym,
   3044   1.8  christos 					  asection *input_sec,
   3045   1.8  christos 					  struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
   3046   1.1  christos {
   3047   1.1  christos   /* If we see a common symbol, which implies a relocatable link, then
   3048   1.1  christos      if a symbol was small common in an input file, mark it as small
   3049   1.1  christos      common in the output file.  */
   3050   1.1  christos   if (sym->st_shndx == SHN_COMMON && strcmp (input_sec->name, ".scommon") == 0)
   3051   1.1  christos     sym->st_shndx = SHN_SCORE_SCOMMON;
   3052   1.1  christos 
   3053   1.1  christos   return 1;
   3054   1.1  christos }
   3055   1.1  christos 
   3056  1.10  christos static bool
   3057   1.1  christos s3_bfd_score_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
   3058   1.8  christos 					   asection *sec,
   3059   1.8  christos 					   int *retval)
   3060   1.1  christos {
   3061   1.9  christos   if (strcmp (bfd_section_name (sec), ".scommon") == 0)
   3062   1.1  christos     {
   3063   1.1  christos       *retval = SHN_SCORE_SCOMMON;
   3064  1.10  christos       return true;
   3065   1.1  christos     }
   3066   1.1  christos 
   3067  1.10  christos   return false;
   3068   1.1  christos }
   3069   1.1  christos 
   3070   1.1  christos /* Adjust a symbol defined by a dynamic object and referenced by a
   3071   1.1  christos    regular object.  The current definition is in some section of the
   3072   1.1  christos    dynamic object, but we're not including those sections.  We have to
   3073   1.1  christos    change the definition to something the rest of the link can understand.  */
   3074  1.10  christos static bool
   3075   1.1  christos s3_bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   3076   1.8  christos 					struct elf_link_hash_entry *h)
   3077   1.1  christos {
   3078   1.1  christos   bfd *dynobj;
   3079   1.1  christos   struct score_elf_link_hash_entry *hscore;
   3080   1.1  christos   asection *s;
   3081   1.1  christos 
   3082   1.1  christos   dynobj = elf_hash_table (info)->dynobj;
   3083   1.1  christos 
   3084   1.1  christos   /* Make sure we know what is going on here.  */
   3085   1.1  christos   BFD_ASSERT (dynobj != NULL
   3086   1.8  christos 	      && (h->needs_plt
   3087   1.8  christos 		  || h->is_weakalias
   3088   1.8  christos 		  || (h->def_dynamic && h->ref_regular && !h->def_regular)));
   3089   1.1  christos 
   3090   1.1  christos   /* If this symbol is defined in a dynamic object, we need to copy
   3091   1.1  christos      any R_SCORE_ABS32 or R_SCORE_REL32 relocs against it into the output
   3092   1.1  christos      file.  */
   3093   1.1  christos   hscore = (struct score_elf_link_hash_entry *)h;
   3094   1.6  christos   if (!bfd_link_relocatable (info)
   3095   1.1  christos       && hscore->possibly_dynamic_relocs != 0
   3096   1.1  christos       && (h->root.type == bfd_link_hash_defweak || !h->def_regular))
   3097   1.1  christos     {
   3098   1.1  christos       score_elf_allocate_dynamic_relocations (dynobj, hscore->possibly_dynamic_relocs);
   3099   1.1  christos       if (hscore->readonly_reloc)
   3100   1.8  christos 	/* We tell the dynamic linker that there are relocations
   3101   1.8  christos 	   against the text segment.  */
   3102   1.8  christos 	info->flags |= DF_TEXTREL;
   3103   1.1  christos     }
   3104   1.1  christos 
   3105   1.1  christos   /* For a function, create a stub, if allowed.  */
   3106   1.1  christos   if (!hscore->no_fn_stub && h->needs_plt)
   3107   1.1  christos     {
   3108   1.1  christos       if (!elf_hash_table (info)->dynamic_sections_created)
   3109  1.10  christos 	return true;
   3110   1.1  christos 
   3111   1.1  christos       /* If this symbol is not defined in a regular file, then set
   3112   1.8  christos 	 the symbol to the stub location.  This is required to make
   3113   1.8  christos 	 function pointers compare as equal between the normal
   3114   1.8  christos 	 executable and the shared library.  */
   3115   1.1  christos       if (!h->def_regular)
   3116   1.8  christos 	{
   3117   1.8  christos 	  /* We need .stub section.  */
   3118   1.8  christos 	  s = bfd_get_linker_section (dynobj, SCORE_ELF_STUB_SECTION_NAME);
   3119   1.8  christos 	  BFD_ASSERT (s != NULL);
   3120   1.8  christos 
   3121   1.8  christos 	  h->root.u.def.section = s;
   3122   1.8  christos 	  h->root.u.def.value = s->size;
   3123   1.8  christos 
   3124   1.8  christos 	  /* XXX Write this stub address somewhere.  */
   3125   1.8  christos 	  h->plt.offset = s->size;
   3126   1.8  christos 
   3127   1.8  christos 	  /* Make room for this stub code.  */
   3128   1.8  christos 	  s->size += SCORE_FUNCTION_STUB_SIZE;
   3129   1.8  christos 
   3130   1.8  christos 	  /* The last half word of the stub will be filled with the index
   3131   1.8  christos 	     of this symbol in .dynsym section.  */
   3132  1.10  christos 	  return true;
   3133   1.8  christos 	}
   3134   1.1  christos     }
   3135   1.1  christos   else if ((h->type == STT_FUNC) && !h->needs_plt)
   3136   1.1  christos     {
   3137   1.1  christos       /* This will set the entry for this symbol in the GOT to 0, and
   3138   1.8  christos 	 the dynamic linker will take care of this.  */
   3139   1.1  christos       h->root.u.def.value = 0;
   3140  1.10  christos       return true;
   3141   1.1  christos     }
   3142   1.1  christos 
   3143   1.1  christos   /* If this is a weak symbol, and there is a real definition, the
   3144   1.1  christos      processor independent code will have arranged for us to see the
   3145   1.1  christos      real definition first, and we can just use the same value.  */
   3146   1.8  christos   if (h->is_weakalias)
   3147   1.1  christos     {
   3148   1.8  christos       struct elf_link_hash_entry *def = weakdef (h);
   3149   1.8  christos       BFD_ASSERT (def->root.type == bfd_link_hash_defined);
   3150   1.8  christos       h->root.u.def.section = def->root.u.def.section;
   3151   1.8  christos       h->root.u.def.value = def->root.u.def.value;
   3152  1.10  christos       return true;
   3153   1.1  christos     }
   3154   1.1  christos 
   3155   1.1  christos   /* This is a reference to a symbol defined by a dynamic object which
   3156   1.1  christos      is not a function.  */
   3157  1.10  christos   return true;
   3158   1.1  christos }
   3159   1.1  christos 
   3160   1.1  christos /* This function is called after all the input files have been read,
   3161   1.1  christos    and the input sections have been assigned to output sections.  */
   3162  1.10  christos static bool
   3163  1.11  christos s3_bfd_score_elf_early_size_sections (bfd *output_bfd,
   3164  1.11  christos 				      struct bfd_link_info *info)
   3165   1.1  christos {
   3166   1.1  christos   bfd *dynobj;
   3167   1.1  christos   asection *s;
   3168   1.1  christos   struct score_got_info *g;
   3169   1.1  christos   int i;
   3170   1.1  christos   bfd_size_type loadable_size = 0;
   3171   1.1  christos   bfd_size_type local_gotno;
   3172   1.1  christos   bfd *sub;
   3173   1.1  christos 
   3174   1.1  christos   dynobj = elf_hash_table (info)->dynobj;
   3175   1.1  christos   if (dynobj == NULL)
   3176   1.1  christos     /* Relocatable links don't have it.  */
   3177  1.10  christos     return true;
   3178   1.1  christos 
   3179   1.1  christos   g = score_elf_got_info (dynobj, &s);
   3180   1.1  christos   if (s == NULL)
   3181  1.10  christos     return true;
   3182   1.1  christos 
   3183   1.1  christos   /* Calculate the total loadable size of the output.  That will give us the
   3184   1.1  christos      maximum number of GOT_PAGE entries required.  */
   3185   1.3  christos   for (sub = info->input_bfds; sub; sub = sub->link.next)
   3186   1.1  christos     {
   3187   1.1  christos       asection *subsection;
   3188   1.1  christos 
   3189   1.1  christos       for (subsection = sub->sections;
   3190   1.8  christos 	   subsection;
   3191   1.8  christos 	   subsection = subsection->next)
   3192   1.8  christos 	{
   3193   1.8  christos 	  if ((subsection->flags & SEC_ALLOC) == 0)
   3194   1.8  christos 	    continue;
   3195   1.8  christos 	  loadable_size += ((subsection->size + 0xf)
   3196   1.8  christos 			    &~ (bfd_size_type) 0xf);
   3197   1.8  christos 	}
   3198   1.1  christos     }
   3199   1.1  christos 
   3200   1.1  christos   /* There has to be a global GOT entry for every symbol with
   3201   1.1  christos      a dynamic symbol table index of DT_SCORE_GOTSYM or
   3202   1.1  christos      higher.  Therefore, it make sense to put those symbols
   3203   1.1  christos      that need GOT entries at the end of the symbol table.  We
   3204   1.1  christos      do that here.  */
   3205   1.1  christos   if (! score_elf_sort_hash_table (info, 1))
   3206  1.10  christos     return false;
   3207   1.1  christos 
   3208   1.1  christos   if (g->global_gotsym != NULL)
   3209   1.1  christos     i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx;
   3210   1.1  christos   else
   3211   1.1  christos     /* If there are no global symbols, or none requiring
   3212   1.1  christos        relocations, then GLOBAL_GOTSYM will be NULL.  */
   3213   1.1  christos     i = 0;
   3214   1.1  christos 
   3215   1.1  christos   /* In the worst case, we'll get one stub per dynamic symbol.  */
   3216   1.1  christos   loadable_size += SCORE_FUNCTION_STUB_SIZE * i;
   3217   1.1  christos 
   3218   1.1  christos   /* Assume there are two loadable segments consisting of
   3219   1.1  christos      contiguous sections.  Is 5 enough?  */
   3220   1.1  christos   local_gotno = (loadable_size >> 16) + 5;
   3221   1.1  christos 
   3222   1.1  christos   g->local_gotno += local_gotno;
   3223   1.1  christos   s->size += g->local_gotno * SCORE_ELF_GOT_SIZE (output_bfd);
   3224   1.1  christos 
   3225   1.1  christos   g->global_gotno = i;
   3226   1.1  christos   s->size += i * SCORE_ELF_GOT_SIZE (output_bfd);
   3227   1.1  christos 
   3228   1.1  christos   score_elf_resolve_final_got_entries (g);
   3229   1.1  christos 
   3230   1.1  christos   if (s->size > SCORE_ELF_GOT_MAX_SIZE (output_bfd))
   3231   1.1  christos     {
   3232   1.1  christos       /* Fixme. Error message or Warning message should be issued here.  */
   3233   1.1  christos     }
   3234   1.1  christos 
   3235  1.10  christos   return true;
   3236   1.1  christos }
   3237   1.1  christos 
   3238   1.1  christos /* Set the sizes of the dynamic sections.  */
   3239  1.10  christos static bool
   3240  1.11  christos s3_bfd_score_elf_late_size_sections (bfd *output_bfd, struct bfd_link_info *info)
   3241   1.1  christos {
   3242   1.1  christos   bfd *dynobj;
   3243   1.1  christos   asection *s;
   3244  1.10  christos   bool reltext;
   3245   1.1  christos 
   3246   1.1  christos   dynobj = elf_hash_table (info)->dynobj;
   3247  1.11  christos   if (dynobj == NULL)
   3248  1.11  christos     return true;
   3249   1.1  christos 
   3250   1.1  christos   if (elf_hash_table (info)->dynamic_sections_created)
   3251   1.1  christos     {
   3252   1.1  christos       /* Set the contents of the .interp section to the interpreter.  */
   3253   1.8  christos       if (bfd_link_executable (info) && !info->nointerp)
   3254   1.8  christos 	{
   3255   1.8  christos 	  s = bfd_get_linker_section (dynobj, ".interp");
   3256   1.8  christos 	  BFD_ASSERT (s != NULL);
   3257   1.8  christos 	  s->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
   3258   1.8  christos 	  s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
   3259   1.8  christos 	}
   3260   1.1  christos     }
   3261   1.1  christos 
   3262   1.1  christos   /* The check_relocs and adjust_dynamic_symbol entry points have
   3263   1.1  christos      determined the sizes of the various dynamic sections.  Allocate
   3264   1.1  christos      memory for them.  */
   3265  1.10  christos   reltext = false;
   3266   1.1  christos   for (s = dynobj->sections; s != NULL; s = s->next)
   3267   1.1  christos     {
   3268   1.1  christos       const char *name;
   3269   1.1  christos 
   3270   1.1  christos       if ((s->flags & SEC_LINKER_CREATED) == 0)
   3271   1.8  christos 	continue;
   3272   1.1  christos 
   3273   1.1  christos       /* It's OK to base decisions on the section name, because none
   3274   1.8  christos 	 of the dynobj section names depend upon the input files.  */
   3275   1.9  christos       name = bfd_section_name (s);
   3276   1.1  christos 
   3277  1.10  christos       if (startswith (name, ".rel"))
   3278   1.8  christos 	{
   3279   1.8  christos 	  if (s->size == 0)
   3280   1.8  christos 	    {
   3281   1.8  christos 	      /* We only strip the section if the output section name
   3282   1.8  christos 		 has the same name.  Otherwise, there might be several
   3283   1.8  christos 		 input sections for this output section.  FIXME: This
   3284   1.8  christos 		 code is probably not needed these days anyhow, since
   3285   1.8  christos 		 the linker now does not create empty output sections.  */
   3286   1.8  christos 	      if (s->output_section != NULL
   3287   1.8  christos 		  && strcmp (name,
   3288   1.9  christos 			     bfd_section_name (s->output_section)) == 0)
   3289   1.8  christos 		s->flags |= SEC_EXCLUDE;
   3290   1.8  christos 	    }
   3291   1.8  christos 	  else
   3292   1.8  christos 	    {
   3293   1.8  christos 	      const char *outname;
   3294   1.8  christos 	      asection *target;
   3295   1.8  christos 
   3296   1.8  christos 	      /* If this relocation section applies to a read only
   3297   1.8  christos 		 section, then we probably need a DT_TEXTREL entry.
   3298   1.8  christos 		 If the relocation section is .rel.dyn, we always
   3299   1.8  christos 		 assert a DT_TEXTREL entry rather than testing whether
   3300   1.8  christos 		 there exists a relocation to a read only section or
   3301   1.8  christos 		 not.  */
   3302   1.9  christos 	      outname = bfd_section_name (s->output_section);
   3303   1.8  christos 	      target = bfd_get_section_by_name (output_bfd, outname + 4);
   3304   1.8  christos 	      if ((target != NULL
   3305   1.8  christos 		   && (target->flags & SEC_READONLY) != 0
   3306   1.8  christos 		   && (target->flags & SEC_ALLOC) != 0) || strcmp (outname, ".rel.dyn") == 0)
   3307  1.10  christos 		reltext = true;
   3308   1.8  christos 
   3309   1.8  christos 	      /* We use the reloc_count field as a counter if we need
   3310   1.8  christos 		 to copy relocs into the output file.  */
   3311   1.8  christos 	      if (strcmp (name, ".rel.dyn") != 0)
   3312   1.8  christos 		s->reloc_count = 0;
   3313   1.8  christos 	    }
   3314   1.8  christos 	}
   3315  1.10  christos       else if (startswith (name, ".got"))
   3316   1.8  christos 	{
   3317  1.11  christos 	  /* s3_bfd_score_elf_early_size_sections() has already done
   3318   1.8  christos 	     most of the work, but some symbols may have been mapped
   3319   1.8  christos 	     to versions that we must now resolve in the got_entries
   3320   1.8  christos 	     hash tables.  */
   3321   1.8  christos 	}
   3322   1.1  christos       else if (strcmp (name, SCORE_ELF_STUB_SECTION_NAME) == 0)
   3323   1.8  christos 	{
   3324   1.8  christos 	  /* IRIX rld assumes that the function stub isn't at the end
   3325   1.8  christos 	     of .text section. So put a dummy. XXX  */
   3326   1.8  christos 	  s->size += SCORE_FUNCTION_STUB_SIZE;
   3327   1.8  christos 	}
   3328  1.10  christos       else if (! startswith (name, ".init"))
   3329   1.8  christos 	{
   3330   1.8  christos 	  /* It's not one of our sections, so don't allocate space.  */
   3331   1.8  christos 	  continue;
   3332   1.8  christos 	}
   3333   1.1  christos 
   3334   1.1  christos       /* Allocate memory for the section contents.  */
   3335   1.1  christos       s->contents = bfd_zalloc (dynobj, s->size);
   3336   1.1  christos       if (s->contents == NULL && s->size != 0)
   3337   1.8  christos 	{
   3338   1.8  christos 	  bfd_set_error (bfd_error_no_memory);
   3339  1.10  christos 	  return false;
   3340   1.8  christos 	}
   3341   1.1  christos     }
   3342   1.1  christos 
   3343   1.1  christos   if (elf_hash_table (info)->dynamic_sections_created)
   3344   1.1  christos     {
   3345   1.1  christos       /* Add some entries to the .dynamic section.  We fill in the
   3346   1.8  christos 	 values later, in s3_bfd_score_elf_finish_dynamic_sections, but we
   3347   1.8  christos 	 must add the entries now so that we get the correct size for
   3348   1.8  christos 	 the .dynamic section.  The DT_DEBUG entry is filled in by the
   3349   1.8  christos 	 dynamic linker and used by the debugger.  */
   3350   1.1  christos 
   3351   1.1  christos       if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0))
   3352  1.10  christos 	return false;
   3353   1.1  christos 
   3354   1.1  christos       if (reltext)
   3355   1.8  christos 	info->flags |= DF_TEXTREL;
   3356   1.1  christos 
   3357   1.1  christos       if ((info->flags & DF_TEXTREL) != 0)
   3358   1.8  christos 	{
   3359   1.8  christos 	  if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0))
   3360  1.10  christos 	    return false;
   3361   1.8  christos 	}
   3362   1.1  christos 
   3363   1.1  christos       if (! SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTGOT, 0))
   3364  1.10  christos 	return false;
   3365   1.1  christos 
   3366  1.10  christos       if (score_elf_rel_dyn_section (dynobj, false))
   3367   1.8  christos 	{
   3368   1.8  christos 	  if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_REL, 0))
   3369  1.10  christos 	    return false;
   3370   1.8  christos 
   3371   1.8  christos 	  if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELSZ, 0))
   3372  1.10  christos 	    return false;
   3373   1.8  christos 
   3374   1.8  christos 	  if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELENT, 0))
   3375  1.10  christos 	    return false;
   3376   1.8  christos 	}
   3377   1.1  christos 
   3378   1.1  christos       if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_BASE_ADDRESS, 0))
   3379  1.10  christos 	return false;
   3380   1.1  christos 
   3381   1.1  christos       if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_LOCAL_GOTNO, 0))
   3382  1.10  christos 	return false;
   3383   1.1  christos 
   3384   1.1  christos       if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_SYMTABNO, 0))
   3385  1.10  christos 	return false;
   3386   1.1  christos 
   3387   1.1  christos       if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_UNREFEXTNO, 0))
   3388  1.10  christos 	return false;
   3389   1.1  christos 
   3390   1.1  christos       if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_GOTSYM, 0))
   3391  1.10  christos 	return false;
   3392   1.1  christos 
   3393   1.1  christos       if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_HIPAGENO, 0))
   3394  1.10  christos 	return false;
   3395   1.1  christos     }
   3396   1.1  christos 
   3397  1.10  christos   return true;
   3398   1.1  christos }
   3399   1.1  christos 
   3400  1.10  christos static bool
   3401   1.1  christos s3_bfd_score_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
   3402   1.1  christos {
   3403   1.1  christos   struct elf_link_hash_entry *h;
   3404   1.1  christos   struct bfd_link_hash_entry *bh;
   3405   1.1  christos   flagword flags;
   3406   1.1  christos   asection *s;
   3407   1.1  christos 
   3408   1.1  christos   flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
   3409   1.8  christos 	   | SEC_LINKER_CREATED | SEC_READONLY);
   3410   1.1  christos 
   3411   1.1  christos   /* ABI requests the .dynamic section to be read only.  */
   3412   1.1  christos   s = bfd_get_linker_section (abfd, ".dynamic");
   3413   1.1  christos   if (s != NULL)
   3414   1.1  christos     {
   3415   1.9  christos       if (!bfd_set_section_flags (s, flags))
   3416  1.10  christos 	return false;
   3417   1.1  christos     }
   3418   1.1  christos 
   3419   1.1  christos   /* We need to create .got section.  */
   3420  1.10  christos   if (!score_elf_create_got_section (abfd, info, false))
   3421  1.10  christos     return false;
   3422   1.1  christos 
   3423  1.10  christos   if (!score_elf_rel_dyn_section (elf_hash_table (info)->dynobj, true))
   3424  1.10  christos     return false;
   3425   1.1  christos 
   3426   1.1  christos   /* Create .stub section.  */
   3427   1.1  christos   if (bfd_get_linker_section (abfd, SCORE_ELF_STUB_SECTION_NAME) == NULL)
   3428   1.1  christos     {
   3429   1.1  christos       s = bfd_make_section_anyway_with_flags (abfd, SCORE_ELF_STUB_SECTION_NAME,
   3430   1.1  christos 					      flags | SEC_CODE);
   3431   1.1  christos       if (s == NULL
   3432   1.9  christos 	  || !bfd_set_section_alignment (s, 2))
   3433   1.1  christos 
   3434  1.10  christos 	return false;
   3435   1.1  christos     }
   3436   1.1  christos 
   3437   1.6  christos   if (!bfd_link_pic (info))
   3438   1.1  christos     {
   3439   1.1  christos       const char *name;
   3440   1.1  christos 
   3441   1.1  christos       name = "_DYNAMIC_LINK";
   3442   1.1  christos       bh = NULL;
   3443   1.1  christos       if (!(_bfd_generic_link_add_one_symbol
   3444   1.8  christos 	    (info, abfd, name, BSF_GLOBAL, bfd_abs_section_ptr,
   3445  1.10  christos 	     (bfd_vma) 0, NULL, false, get_elf_backend_data (abfd)->collect, &bh)))
   3446  1.10  christos 	return false;
   3447   1.1  christos 
   3448   1.1  christos       h = (struct elf_link_hash_entry *)bh;
   3449   1.1  christos       h->non_elf = 0;
   3450   1.1  christos       h->def_regular = 1;
   3451   1.1  christos       h->type = STT_SECTION;
   3452   1.1  christos 
   3453   1.1  christos       if (!bfd_elf_link_record_dynamic_symbol (info, h))
   3454  1.10  christos 	return false;
   3455   1.1  christos     }
   3456   1.1  christos 
   3457  1.10  christos   return true;
   3458   1.1  christos }
   3459   1.1  christos 
   3460   1.1  christos 
   3461   1.1  christos /* Finish up dynamic symbol handling.  We set the contents of various
   3462   1.1  christos    dynamic sections here.  */
   3463  1.10  christos static bool
   3464   1.1  christos s3_bfd_score_elf_finish_dynamic_symbol (bfd *output_bfd,
   3465   1.8  christos 					struct bfd_link_info *info,
   3466   1.8  christos 					struct elf_link_hash_entry *h,
   3467   1.8  christos 					Elf_Internal_Sym *sym)
   3468   1.1  christos {
   3469   1.1  christos   bfd *dynobj;
   3470   1.1  christos   asection *sgot;
   3471   1.1  christos   struct score_got_info *g;
   3472   1.1  christos   const char *name;
   3473   1.1  christos 
   3474   1.1  christos   dynobj = elf_hash_table (info)->dynobj;
   3475   1.1  christos 
   3476   1.1  christos   if (h->plt.offset != MINUS_ONE)
   3477   1.1  christos     {
   3478   1.1  christos       asection *s;
   3479   1.1  christos       bfd_byte stub[SCORE_FUNCTION_STUB_SIZE];
   3480   1.1  christos 
   3481   1.1  christos       /* This symbol has a stub.  Set it up.  */
   3482   1.1  christos       BFD_ASSERT (h->dynindx != -1);
   3483   1.1  christos 
   3484   1.1  christos       s = bfd_get_linker_section (dynobj, SCORE_ELF_STUB_SECTION_NAME);
   3485   1.1  christos       BFD_ASSERT (s != NULL);
   3486   1.1  christos 
   3487   1.1  christos       /* FIXME: Can h->dynindex be more than 64K?  */
   3488   1.1  christos       if (h->dynindx & 0xffff0000)
   3489  1.11  christos 	{
   3490  1.11  christos 	  _bfd_error_handler
   3491  1.11  christos 	    (_("%pB: cannot handle more than %d dynamic symbols"),
   3492  1.11  christos 	     output_bfd, 0xffff);
   3493  1.11  christos 	  bfd_set_error (bfd_error_bad_value);
   3494  1.11  christos 	  return false;
   3495  1.11  christos 	}
   3496   1.1  christos 
   3497   1.1  christos       /* Fill the stub.  */
   3498   1.1  christos       score_bfd_put_32 (output_bfd, STUB_LW, stub);
   3499   1.1  christos       score_bfd_put_32 (output_bfd, STUB_MOVE, stub + 4);
   3500   1.1  christos       score_bfd_put_32 (output_bfd, STUB_LI16 | (h->dynindx << 1), stub + 8);
   3501   1.1  christos       score_bfd_put_32 (output_bfd, STUB_BRL, stub + 12);
   3502   1.1  christos 
   3503   1.1  christos       BFD_ASSERT (h->plt.offset <= s->size);
   3504   1.1  christos       memcpy (s->contents + h->plt.offset, stub, SCORE_FUNCTION_STUB_SIZE);
   3505   1.1  christos 
   3506   1.1  christos       /* Mark the symbol as undefined.  plt.offset != -1 occurs
   3507   1.8  christos 	 only for the referenced symbol.  */
   3508   1.1  christos       sym->st_shndx = SHN_UNDEF;
   3509   1.1  christos 
   3510   1.1  christos       /* The run-time linker uses the st_value field of the symbol
   3511   1.8  christos 	  to reset the global offset table entry for this external
   3512   1.8  christos 	  to its stub address when unlinking a shared object.  */
   3513   1.1  christos       sym->st_value = (s->output_section->vma + s->output_offset + h->plt.offset);
   3514   1.1  christos     }
   3515   1.1  christos 
   3516   1.1  christos   BFD_ASSERT (h->dynindx != -1 || h->forced_local);
   3517   1.1  christos 
   3518  1.10  christos   sgot = score_elf_got_section (dynobj, false);
   3519   1.1  christos   BFD_ASSERT (sgot != NULL);
   3520   1.1  christos   BFD_ASSERT (score_elf_section_data (sgot) != NULL);
   3521   1.1  christos   g = score_elf_section_data (sgot)->u.got_info;
   3522   1.1  christos   BFD_ASSERT (g != NULL);
   3523   1.1  christos 
   3524   1.1  christos   /* Run through the global symbol table, creating GOT entries for all
   3525   1.1  christos      the symbols that need them.  */
   3526   1.1  christos   if (g->global_gotsym != NULL && h->dynindx >= g->global_gotsym->dynindx)
   3527   1.1  christos     {
   3528   1.1  christos       bfd_vma offset;
   3529   1.1  christos       bfd_vma value;
   3530   1.1  christos 
   3531   1.1  christos       value = sym->st_value;
   3532   1.1  christos       offset = score_elf_global_got_index (dynobj, h);
   3533   1.1  christos       score_bfd_put_32 (output_bfd, value, sgot->contents + offset);
   3534   1.1  christos     }
   3535   1.1  christos 
   3536   1.1  christos   /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
   3537   1.1  christos   name = h->root.root.string;
   3538   1.1  christos   if (h == elf_hash_table (info)->hdynamic
   3539   1.1  christos       || h == elf_hash_table (info)->hgot)
   3540   1.1  christos     sym->st_shndx = SHN_ABS;
   3541   1.1  christos   else if (strcmp (name, "_DYNAMIC_LINK") == 0)
   3542   1.1  christos     {
   3543   1.1  christos       sym->st_shndx = SHN_ABS;
   3544   1.1  christos       sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
   3545   1.1  christos       sym->st_value = 1;
   3546   1.1  christos     }
   3547   1.1  christos   else if (strcmp (name, GP_DISP_LABEL) == 0)
   3548   1.1  christos     {
   3549   1.1  christos       sym->st_shndx = SHN_ABS;
   3550   1.1  christos       sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
   3551   1.1  christos       sym->st_value = elf_gp (output_bfd);
   3552   1.1  christos     }
   3553   1.1  christos 
   3554  1.10  christos   return true;
   3555   1.1  christos }
   3556   1.1  christos 
   3557   1.1  christos /* Finish up the dynamic sections.  */
   3558  1.10  christos static bool
   3559   1.1  christos s3_bfd_score_elf_finish_dynamic_sections (bfd *output_bfd,
   3560   1.8  christos 					  struct bfd_link_info *info)
   3561   1.1  christos {
   3562   1.1  christos   bfd *dynobj;
   3563   1.1  christos   asection *sdyn;
   3564   1.1  christos   asection *sgot;
   3565   1.1  christos   asection *s;
   3566   1.1  christos   struct score_got_info *g;
   3567   1.1  christos 
   3568   1.1  christos   dynobj = elf_hash_table (info)->dynobj;
   3569   1.1  christos 
   3570   1.1  christos   sdyn = bfd_get_linker_section (dynobj, ".dynamic");
   3571   1.1  christos 
   3572  1.10  christos   sgot = score_elf_got_section (dynobj, false);
   3573   1.1  christos   if (sgot == NULL)
   3574   1.1  christos     g = NULL;
   3575   1.1  christos   else
   3576   1.1  christos     {
   3577   1.1  christos       BFD_ASSERT (score_elf_section_data (sgot) != NULL);
   3578   1.1  christos       g = score_elf_section_data (sgot)->u.got_info;
   3579   1.1  christos       BFD_ASSERT (g != NULL);
   3580   1.1  christos     }
   3581   1.1  christos 
   3582   1.1  christos   if (elf_hash_table (info)->dynamic_sections_created)
   3583   1.1  christos     {
   3584   1.1  christos       bfd_byte *b;
   3585   1.1  christos 
   3586   1.1  christos       BFD_ASSERT (sdyn != NULL);
   3587   1.1  christos       BFD_ASSERT (g != NULL);
   3588   1.1  christos 
   3589   1.1  christos       for (b = sdyn->contents;
   3590   1.8  christos 	   b < sdyn->contents + sdyn->size;
   3591   1.8  christos 	   b += SCORE_ELF_DYN_SIZE (dynobj))
   3592   1.8  christos 	{
   3593   1.8  christos 	  Elf_Internal_Dyn dyn;
   3594   1.8  christos 	  const char *name;
   3595   1.8  christos 	  size_t elemsize;
   3596  1.10  christos 	  bool swap_out_p;
   3597   1.8  christos 
   3598   1.8  christos 	  /* Read in the current dynamic entry.  */
   3599   1.8  christos 	  (*get_elf_backend_data (dynobj)->s->swap_dyn_in) (dynobj, b, &dyn);
   3600   1.8  christos 
   3601   1.8  christos 	  /* Assume that we're going to modify it and write it out.  */
   3602  1.10  christos 	  swap_out_p = true;
   3603   1.8  christos 
   3604   1.8  christos 	  switch (dyn.d_tag)
   3605   1.8  christos 	    {
   3606   1.8  christos 	    case DT_RELENT:
   3607   1.8  christos 	      dyn.d_un.d_val = SCORE_ELF_REL_SIZE (dynobj);
   3608   1.8  christos 	      break;
   3609   1.8  christos 
   3610   1.8  christos 	    case DT_STRSZ:
   3611   1.8  christos 	      /* Rewrite DT_STRSZ.  */
   3612   1.8  christos 	      dyn.d_un.d_val
   3613   1.8  christos 		= _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
   3614   1.8  christos 	      break;
   3615   1.8  christos 
   3616   1.8  christos 	    case DT_PLTGOT:
   3617   1.8  christos 	      s = elf_hash_table (info)->sgot;
   3618   1.8  christos 	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
   3619   1.8  christos 	      break;
   3620   1.8  christos 
   3621   1.8  christos 	    case DT_SCORE_BASE_ADDRESS:
   3622   1.8  christos 	      s = output_bfd->sections;
   3623   1.8  christos 	      BFD_ASSERT (s != NULL);
   3624   1.8  christos 	      dyn.d_un.d_ptr = s->vma & ~(bfd_vma) 0xffff;
   3625   1.8  christos 	      break;
   3626   1.8  christos 
   3627   1.8  christos 	    case DT_SCORE_LOCAL_GOTNO:
   3628   1.8  christos 	      dyn.d_un.d_val = g->local_gotno;
   3629   1.8  christos 	      break;
   3630   1.8  christos 
   3631   1.8  christos 	    case DT_SCORE_UNREFEXTNO:
   3632   1.8  christos 	      /* The index into the dynamic symbol table which is the
   3633   1.8  christos 		 entry of the first external symbol that is not
   3634   1.8  christos 		 referenced within the same object.  */
   3635   1.8  christos 	      dyn.d_un.d_val = bfd_count_sections (output_bfd) + 1;
   3636   1.8  christos 	      break;
   3637   1.8  christos 
   3638   1.8  christos 	    case DT_SCORE_GOTSYM:
   3639   1.8  christos 	      if (g->global_gotsym)
   3640   1.8  christos 		{
   3641   1.8  christos 		  dyn.d_un.d_val = g->global_gotsym->dynindx;
   3642   1.8  christos 		  break;
   3643   1.8  christos 		}
   3644   1.8  christos 	      /* In case if we don't have global got symbols we default
   3645   1.8  christos 		  to setting DT_SCORE_GOTSYM to the same value as
   3646   1.8  christos 		  DT_SCORE_SYMTABNO.  */
   3647   1.7  christos 	      /* Fall through.  */
   3648   1.1  christos 
   3649   1.8  christos 	    case DT_SCORE_SYMTABNO:
   3650   1.8  christos 	      name = ".dynsym";
   3651   1.8  christos 	      elemsize = SCORE_ELF_SYM_SIZE (output_bfd);
   3652   1.8  christos 	      s = bfd_get_linker_section (dynobj, name);
   3653   1.8  christos 	      dyn.d_un.d_val = s->size / elemsize;
   3654   1.8  christos 	      break;
   3655   1.8  christos 
   3656   1.8  christos 	    case DT_SCORE_HIPAGENO:
   3657   1.8  christos 	      dyn.d_un.d_val = g->local_gotno - SCORE_RESERVED_GOTNO;
   3658   1.8  christos 	      break;
   3659   1.8  christos 
   3660   1.8  christos 	    default:
   3661  1.10  christos 	      swap_out_p = false;
   3662   1.8  christos 	      break;
   3663   1.8  christos 	    }
   3664   1.8  christos 
   3665   1.8  christos 	  if (swap_out_p)
   3666   1.8  christos 	    (*get_elf_backend_data (dynobj)->s->swap_dyn_out) (dynobj, &dyn, b);
   3667   1.8  christos 	}
   3668   1.1  christos     }
   3669   1.1  christos 
   3670   1.1  christos   /* The first entry of the global offset table will be filled at
   3671   1.1  christos      runtime. The second entry will be used by some runtime loaders.
   3672   1.1  christos      This isn't the case of IRIX rld.  */
   3673   1.1  christos   if (sgot != NULL && sgot->size > 0)
   3674   1.1  christos     {
   3675   1.1  christos       score_bfd_put_32 (output_bfd, 0, sgot->contents);
   3676   1.1  christos       score_bfd_put_32 (output_bfd, 0x80000000, sgot->contents + SCORE_ELF_GOT_SIZE (output_bfd));
   3677   1.1  christos     }
   3678   1.1  christos 
   3679   1.1  christos   if (sgot != NULL)
   3680   1.1  christos     elf_section_data (sgot->output_section)->this_hdr.sh_entsize
   3681   1.1  christos       = SCORE_ELF_GOT_SIZE (output_bfd);
   3682   1.1  christos 
   3683   1.1  christos 
   3684   1.1  christos   /* We need to sort the entries of the dynamic relocation section.  */
   3685  1.10  christos   s = score_elf_rel_dyn_section (dynobj, false);
   3686   1.1  christos 
   3687   1.1  christos   if (s != NULL && s->size > (bfd_vma)2 * SCORE_ELF_REL_SIZE (output_bfd))
   3688   1.1  christos     {
   3689   1.1  christos       reldyn_sorting_bfd = output_bfd;
   3690   1.1  christos       qsort ((Elf32_External_Rel *) s->contents + 1, s->reloc_count - 1,
   3691   1.8  christos 	     sizeof (Elf32_External_Rel), score_elf_sort_dynamic_relocs);
   3692   1.1  christos     }
   3693   1.1  christos 
   3694  1.10  christos   return true;
   3695   1.1  christos }
   3696   1.1  christos 
   3697   1.1  christos /* This function set up the ELF section header for a BFD section in preparation for writing
   3698   1.1  christos    it out.  This is where the flags and type fields are set for unusual sections.  */
   3699  1.10  christos static bool
   3700   1.1  christos s3_bfd_score_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
   3701   1.8  christos 				Elf_Internal_Shdr *hdr,
   3702   1.8  christos 				asection *sec)
   3703   1.1  christos {
   3704   1.1  christos   const char *name;
   3705   1.1  christos 
   3706   1.9  christos   name = bfd_section_name (sec);
   3707   1.1  christos 
   3708   1.1  christos   if (strcmp (name, ".got") == 0
   3709   1.1  christos       || strcmp (name, ".srdata") == 0
   3710   1.1  christos       || strcmp (name, ".sdata") == 0
   3711   1.1  christos       || strcmp (name, ".sbss") == 0)
   3712   1.1  christos     hdr->sh_flags |= SHF_SCORE_GPREL;
   3713   1.1  christos 
   3714  1.10  christos   return true;
   3715   1.1  christos }
   3716   1.1  christos 
   3717   1.1  christos /* This function do additional processing on the ELF section header before writing
   3718   1.1  christos    it out.  This is used to set the flags and type fields for some sections.  */
   3719   1.1  christos 
   3720   1.1  christos /* assign_file_positions_except_relocs() check section flag and if it is allocatable,
   3721   1.1  christos    warning message will be issued.  backend_fake_section is called before
   3722   1.1  christos    assign_file_positions_except_relocs(); backend_section_processing after it.  so, we
   3723   1.1  christos    modify section flag there, but not backend_fake_section.  */
   3724  1.10  christos static bool
   3725   1.1  christos s3_bfd_score_elf_section_processing (bfd *abfd ATTRIBUTE_UNUSED, Elf_Internal_Shdr *hdr)
   3726   1.1  christos {
   3727   1.1  christos   if (hdr->bfd_section != NULL)
   3728   1.1  christos     {
   3729   1.9  christos       const char *name = bfd_section_name (hdr->bfd_section);
   3730   1.1  christos 
   3731   1.1  christos       if (strcmp (name, ".sdata") == 0)
   3732   1.8  christos 	{
   3733   1.8  christos 	  hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
   3734   1.8  christos 	  hdr->sh_type = SHT_PROGBITS;
   3735   1.8  christos 	}
   3736   1.1  christos       else if (strcmp (name, ".sbss") == 0)
   3737   1.8  christos 	{
   3738   1.8  christos 	  hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
   3739   1.8  christos 	  hdr->sh_type = SHT_NOBITS;
   3740   1.8  christos 	}
   3741   1.1  christos       else if (strcmp (name, ".srdata") == 0)
   3742   1.8  christos 	{
   3743   1.8  christos 	  hdr->sh_flags |= SHF_ALLOC | SHF_SCORE_GPREL;
   3744   1.8  christos 	  hdr->sh_type = SHT_PROGBITS;
   3745   1.8  christos 	}
   3746   1.1  christos     }
   3747   1.1  christos 
   3748  1.10  christos   return true;
   3749   1.1  christos }
   3750   1.1  christos 
   3751  1.10  christos static bool
   3752   1.1  christos s3_bfd_score_elf_write_section (bfd *output_bfd, asection *sec, bfd_byte *contents)
   3753   1.1  christos {
   3754   1.1  christos   bfd_byte *to, *from, *end;
   3755   1.1  christos   int i;
   3756   1.1  christos 
   3757   1.1  christos   if (strcmp (sec->name, ".pdr") != 0)
   3758  1.10  christos     return false;
   3759   1.1  christos 
   3760   1.1  christos   if (score_elf_section_data (sec)->u.tdata == NULL)
   3761  1.10  christos     return false;
   3762   1.1  christos 
   3763   1.1  christos   to = contents;
   3764   1.1  christos   end = contents + sec->size;
   3765   1.1  christos   for (from = contents, i = 0; from < end; from += PDR_SIZE, i++)
   3766   1.1  christos     {
   3767   1.1  christos       if ((score_elf_section_data (sec)->u.tdata)[i] == 1)
   3768   1.8  christos 	continue;
   3769   1.1  christos 
   3770   1.1  christos       if (to != from)
   3771   1.8  christos 	memcpy (to, from, PDR_SIZE);
   3772   1.1  christos 
   3773   1.1  christos       to += PDR_SIZE;
   3774   1.1  christos     }
   3775   1.1  christos   bfd_set_section_contents (output_bfd, sec->output_section, contents,
   3776   1.8  christos 			    (file_ptr) sec->output_offset, sec->size);
   3777   1.1  christos 
   3778  1.10  christos   return true;
   3779   1.1  christos }
   3780   1.1  christos 
   3781   1.1  christos /* Copy data from a SCORE ELF indirect symbol to its direct symbol, hiding the old
   3782   1.1  christos    indirect symbol.  Process additional relocation information.  */
   3783   1.1  christos static void
   3784   1.1  christos s3_bfd_score_elf_copy_indirect_symbol (struct bfd_link_info *info,
   3785   1.8  christos 				       struct elf_link_hash_entry *dir,
   3786   1.8  christos 				       struct elf_link_hash_entry *ind)
   3787   1.1  christos {
   3788   1.1  christos   struct score_elf_link_hash_entry *dirscore, *indscore;
   3789   1.1  christos 
   3790   1.1  christos   _bfd_elf_link_hash_copy_indirect (info, dir, ind);
   3791   1.1  christos 
   3792   1.1  christos   if (ind->root.type != bfd_link_hash_indirect)
   3793   1.1  christos     return;
   3794   1.1  christos 
   3795   1.1  christos   dirscore = (struct score_elf_link_hash_entry *) dir;
   3796   1.1  christos   indscore = (struct score_elf_link_hash_entry *) ind;
   3797   1.1  christos   dirscore->possibly_dynamic_relocs += indscore->possibly_dynamic_relocs;
   3798   1.1  christos 
   3799   1.1  christos   if (indscore->readonly_reloc)
   3800  1.10  christos     dirscore->readonly_reloc = true;
   3801   1.1  christos 
   3802   1.1  christos   if (indscore->no_fn_stub)
   3803  1.10  christos     dirscore->no_fn_stub = true;
   3804   1.1  christos }
   3805   1.1  christos 
   3806   1.1  christos /* Remove information about discarded functions from other sections which mention them.  */
   3807  1.10  christos static bool
   3808   1.1  christos s3_bfd_score_elf_discard_info (bfd *abfd, struct elf_reloc_cookie *cookie,
   3809   1.8  christos 			       struct bfd_link_info *info)
   3810   1.1  christos {
   3811   1.1  christos   asection *o;
   3812  1.10  christos   bool ret = false;
   3813   1.1  christos   unsigned char *tdata;
   3814   1.1  christos   size_t i, skip;
   3815   1.1  christos 
   3816   1.1  christos   o = bfd_get_section_by_name (abfd, ".pdr");
   3817   1.1  christos   if ((!o) || (o->size == 0) || (o->size % PDR_SIZE != 0)
   3818   1.1  christos       || (o->output_section != NULL && bfd_is_abs_section (o->output_section)))
   3819  1.10  christos     return false;
   3820   1.1  christos 
   3821   1.1  christos   tdata = bfd_zmalloc (o->size / PDR_SIZE);
   3822   1.1  christos   if (!tdata)
   3823  1.10  christos     return false;
   3824   1.1  christos 
   3825   1.1  christos   cookie->rels = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, info->keep_memory);
   3826   1.1  christos   if (!cookie->rels)
   3827   1.1  christos     {
   3828   1.1  christos       free (tdata);
   3829  1.10  christos       return false;
   3830   1.1  christos     }
   3831   1.1  christos 
   3832   1.1  christos   cookie->rel = cookie->rels;
   3833   1.1  christos   cookie->relend = cookie->rels + o->reloc_count;
   3834   1.1  christos 
   3835   1.1  christos   for (i = 0, skip = 0; i < o->size; i++)
   3836   1.1  christos     {
   3837   1.1  christos       if (bfd_elf_reloc_symbol_deleted_p (i * PDR_SIZE, cookie))
   3838   1.8  christos 	{
   3839   1.8  christos 	  tdata[i] = 1;
   3840   1.8  christos 	  skip++;
   3841   1.8  christos 	}
   3842   1.1  christos     }
   3843   1.1  christos 
   3844   1.1  christos   if (skip != 0)
   3845   1.1  christos     {
   3846   1.1  christos       score_elf_section_data (o)->u.tdata = tdata;
   3847   1.1  christos       o->size -= skip * PDR_SIZE;
   3848  1.10  christos       ret = true;
   3849   1.1  christos     }
   3850   1.1  christos   else
   3851   1.1  christos     free (tdata);
   3852   1.1  christos 
   3853   1.1  christos   if (!info->keep_memory)
   3854   1.1  christos     free (cookie->rels);
   3855   1.1  christos 
   3856   1.1  christos   return ret;
   3857   1.1  christos }
   3858   1.1  christos 
   3859   1.1  christos /* Signal that discard_info() has removed the discarded relocations for this section.  */
   3860  1.10  christos static bool
   3861   1.1  christos s3_bfd_score_elf_ignore_discarded_relocs (asection *sec)
   3862   1.1  christos {
   3863   1.1  christos   if (strcmp (sec->name, ".pdr") == 0)
   3864  1.10  christos     return true;
   3865  1.10  christos   return false;
   3866   1.1  christos }
   3867   1.1  christos 
   3868   1.1  christos /* Return the section that should be marked against GC for a given
   3869   1.1  christos    relocation.  */
   3870   1.1  christos static asection *
   3871   1.1  christos s3_bfd_score_elf_gc_mark_hook (asection *sec,
   3872   1.8  christos 			       struct bfd_link_info *info,
   3873   1.8  christos 			       Elf_Internal_Rela *rel,
   3874   1.8  christos 			       struct elf_link_hash_entry *h,
   3875   1.8  christos 			       Elf_Internal_Sym *sym)
   3876   1.1  christos {
   3877   1.1  christos   if (h != NULL)
   3878   1.1  christos     switch (ELF32_R_TYPE (rel->r_info))
   3879   1.1  christos       {
   3880   1.1  christos       case R_SCORE_GNU_VTINHERIT:
   3881   1.1  christos       case R_SCORE_GNU_VTENTRY:
   3882   1.8  christos 	return NULL;
   3883   1.1  christos       }
   3884   1.1  christos 
   3885   1.1  christos   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
   3886   1.1  christos }
   3887   1.1  christos 
   3888   1.1  christos /* Support for core dump NOTE sections.  */
   3889   1.1  christos 
   3890  1.10  christos static bool
   3891   1.1  christos s3_bfd_score_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
   3892   1.1  christos {
   3893   1.1  christos   int offset;
   3894   1.1  christos   unsigned int raw_size;
   3895   1.1  christos 
   3896   1.1  christos   switch (note->descsz)
   3897   1.1  christos     {
   3898   1.1  christos     default:
   3899  1.10  christos       return false;
   3900   1.1  christos 
   3901   1.8  christos     case 148:		       /* Linux/Score 32-bit.  */
   3902   1.1  christos       /* pr_cursig */
   3903   1.1  christos       elf_tdata (abfd)->core->signal
   3904   1.1  christos 	= score_bfd_get_16 (abfd, note->descdata + 12);
   3905   1.1  christos 
   3906   1.1  christos       /* pr_pid */
   3907   1.1  christos       elf_tdata (abfd)->core->lwpid
   3908   1.1  christos 	= score_bfd_get_32 (abfd, note->descdata + 24);
   3909   1.1  christos 
   3910   1.1  christos       /* pr_reg */
   3911   1.1  christos       offset = 72;
   3912   1.1  christos       raw_size = 72;
   3913   1.1  christos 
   3914   1.1  christos       break;
   3915   1.1  christos     }
   3916   1.1  christos 
   3917   1.1  christos   /* Make a ".reg/999" section.  */
   3918   1.1  christos   return _bfd_elfcore_make_pseudosection (abfd, ".reg", raw_size,
   3919   1.1  christos 					  note->descpos + offset);
   3920   1.1  christos }
   3921   1.1  christos 
   3922  1.10  christos static bool
   3923   1.1  christos s3_bfd_score_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
   3924   1.1  christos {
   3925   1.1  christos   switch (note->descsz)
   3926   1.1  christos     {
   3927   1.1  christos     default:
   3928  1.10  christos       return false;
   3929   1.1  christos 
   3930   1.8  christos     case 124:		       /* Linux/Score elf_prpsinfo.  */
   3931   1.1  christos       elf_tdata (abfd)->core->program
   3932   1.1  christos 	= _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
   3933   1.1  christos       elf_tdata (abfd)->core->command
   3934   1.1  christos 	= _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
   3935   1.1  christos     }
   3936   1.1  christos 
   3937   1.1  christos   /* Note that for some reason, a spurious space is tacked
   3938   1.1  christos      onto the end of the args in some (at least one anyway)
   3939   1.1  christos      implementations, so strip it off if it exists.  */
   3940   1.1  christos 
   3941   1.1  christos   {
   3942   1.1  christos     char *command = elf_tdata (abfd)->core->command;
   3943   1.1  christos     int n = strlen (command);
   3944   1.1  christos 
   3945   1.1  christos     if (0 < n && command[n - 1] == ' ')
   3946   1.1  christos       command[n - 1] = '\0';
   3947   1.1  christos   }
   3948   1.1  christos 
   3949  1.10  christos   return true;
   3950   1.1  christos }
   3951   1.1  christos 
   3952   1.1  christos 
   3953   1.1  christos /* Score BFD functions.  */
   3954   1.1  christos static reloc_howto_type *
   3955   1.1  christos s3_elf32_score_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
   3956   1.1  christos {
   3957   1.1  christos   unsigned int i;
   3958   1.1  christos 
   3959   1.1  christos   for (i = 0; i < ARRAY_SIZE (elf32_score_reloc_map); i++)
   3960   1.1  christos     if (elf32_score_reloc_map[i].bfd_reloc_val == code)
   3961   1.1  christos       return &elf32_score_howto_table[elf32_score_reloc_map[i].elf_reloc_val];
   3962   1.1  christos 
   3963   1.1  christos   return NULL;
   3964   1.1  christos }
   3965   1.1  christos 
   3966   1.1  christos static reloc_howto_type *
   3967   1.1  christos elf32_score_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
   3968   1.8  christos 			       const char *r_name)
   3969   1.1  christos {
   3970   1.1  christos   unsigned int i;
   3971   1.1  christos 
   3972   1.1  christos   for (i = 0;
   3973   1.1  christos        i < (sizeof (elf32_score_howto_table)
   3974   1.8  christos 	    / sizeof (elf32_score_howto_table[0]));
   3975   1.1  christos        i++)
   3976   1.1  christos     if (elf32_score_howto_table[i].name != NULL
   3977   1.8  christos 	&& strcasecmp (elf32_score_howto_table[i].name, r_name) == 0)
   3978   1.1  christos       return &elf32_score_howto_table[i];
   3979   1.1  christos 
   3980   1.1  christos   return NULL;
   3981   1.1  christos }
   3982   1.1  christos 
   3983  1.10  christos static bool
   3984   1.1  christos s3_elf32_score_print_private_bfd_data (bfd *abfd, void * ptr)
   3985   1.1  christos {
   3986   1.1  christos   FILE *file = (FILE *) ptr;
   3987   1.1  christos 
   3988   1.1  christos   BFD_ASSERT (abfd != NULL && ptr != NULL);
   3989   1.1  christos 
   3990   1.1  christos   /* Print normal ELF private data.  */
   3991   1.1  christos   _bfd_elf_print_private_bfd_data (abfd, ptr);
   3992   1.1  christos 
   3993   1.1  christos   /* xgettext:c-format */
   3994   1.1  christos   fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
   3995   1.1  christos   if (elf_elfheader (abfd)->e_flags & EF_SCORE_PIC)
   3996   1.1  christos     {
   3997   1.1  christos       fprintf (file, _(" [pic]"));
   3998   1.1  christos     }
   3999   1.1  christos   if (elf_elfheader (abfd)->e_flags & EF_SCORE_FIXDEP)
   4000   1.1  christos     {
   4001   1.1  christos       fprintf (file, _(" [fix dep]"));
   4002   1.1  christos     }
   4003   1.1  christos   fputc ('\n', file);
   4004   1.1  christos 
   4005  1.10  christos   return true;
   4006   1.1  christos }
   4007   1.1  christos 
   4008  1.10  christos static bool
   4009   1.7  christos s3_elf32_score_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
   4010   1.1  christos {
   4011   1.7  christos   bfd *obfd = info->output_bfd;
   4012   1.1  christos   flagword in_flags;
   4013   1.1  christos   flagword out_flags;
   4014   1.1  christos 
   4015   1.7  christos   if (!_bfd_generic_verify_endian_match (ibfd, info))
   4016  1.10  christos     return false;
   4017   1.1  christos 
   4018   1.9  christos   /* FIXME: What should be checked when linking shared libraries?  */
   4019   1.9  christos   if ((ibfd->flags & DYNAMIC) != 0)
   4020  1.10  christos     return true;
   4021   1.9  christos 
   4022   1.1  christos   in_flags  = elf_elfheader (ibfd)->e_flags;
   4023   1.1  christos   out_flags = elf_elfheader (obfd)->e_flags;
   4024   1.1  christos 
   4025   1.1  christos   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
   4026   1.1  christos       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
   4027  1.10  christos     return true;
   4028   1.1  christos 
   4029   1.1  christos   in_flags = elf_elfheader (ibfd)->e_flags;
   4030   1.1  christos   out_flags = elf_elfheader (obfd)->e_flags;
   4031   1.1  christos 
   4032   1.1  christos   if (! elf_flags_init (obfd))
   4033   1.1  christos     {
   4034  1.10  christos       elf_flags_init (obfd) = true;
   4035   1.1  christos       elf_elfheader (obfd)->e_flags = in_flags;
   4036   1.1  christos 
   4037   1.1  christos       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
   4038   1.8  christos 	  && bfd_get_arch_info (obfd)->the_default)
   4039   1.8  christos 	{
   4040   1.8  christos 	  return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
   4041   1.8  christos 	}
   4042   1.1  christos 
   4043  1.10  christos       return true;
   4044   1.1  christos     }
   4045   1.1  christos 
   4046   1.1  christos   if (((in_flags & EF_SCORE_PIC) != 0) != ((out_flags & EF_SCORE_PIC) != 0))
   4047   1.7  christos     _bfd_error_handler
   4048   1.8  christos       (_("%pB: warning: linking PIC files with non-PIC files"), ibfd);
   4049   1.1  christos 
   4050   1.1  christos   /* FIXME: Maybe dependency fix compatibility should be checked here.  */
   4051   1.1  christos 
   4052  1.10  christos   return true;
   4053   1.1  christos }
   4054   1.1  christos 
   4055  1.10  christos static bool
   4056   1.1  christos s3_elf32_score_new_section_hook (bfd *abfd, asection *sec)
   4057   1.1  christos {
   4058   1.1  christos   struct _score_elf_section_data *sdata;
   4059   1.1  christos 
   4060  1.12  christos   sdata = bfd_zalloc (abfd, sizeof (*sdata));
   4061   1.1  christos   if (sdata == NULL)
   4062  1.10  christos     return false;
   4063   1.1  christos   sec->used_by_bfd = sdata;
   4064   1.1  christos 
   4065   1.1  christos   return _bfd_elf_new_section_hook (abfd, sec);
   4066   1.1  christos }
   4067   1.1  christos 
   4068   1.1  christos /*****************************************************************************/
   4069   1.1  christos 
   4070   1.1  christos /* s3_s7: backend hooks.  */
   4071  1.10  christos static bool
   4072   1.1  christos _bfd_score_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
   4073   1.8  christos 			  arelent *bfd_reloc,
   4074   1.8  christos 			  Elf_Internal_Rela *elf_reloc)
   4075   1.1  christos {
   4076   1.1  christos   if (bfd_get_mach (abfd) == bfd_mach_score3)
   4077   1.1  christos     return s3_bfd_score_info_to_howto (abfd, bfd_reloc, elf_reloc);
   4078   1.1  christos   else
   4079   1.1  christos     return s7_bfd_score_info_to_howto (abfd, bfd_reloc, elf_reloc);
   4080   1.1  christos }
   4081   1.1  christos 
   4082  1.10  christos static int
   4083   1.1  christos _bfd_score_elf_relocate_section (bfd *output_bfd,
   4084   1.8  christos 				 struct bfd_link_info *info,
   4085   1.8  christos 				 bfd *input_bfd,
   4086   1.8  christos 				 asection *input_section,
   4087   1.8  christos 				 bfd_byte *contents,
   4088   1.8  christos 				 Elf_Internal_Rela *relocs,
   4089   1.8  christos 				 Elf_Internal_Sym *local_syms,
   4090   1.8  christos 				 asection **local_sections)
   4091   1.1  christos {
   4092   1.1  christos   if (bfd_get_mach (output_bfd) == bfd_mach_score3)
   4093   1.1  christos     return s3_bfd_score_elf_relocate_section (output_bfd,
   4094   1.8  christos 	     info, input_bfd, input_section, contents, relocs,
   4095   1.8  christos 	     local_syms, local_sections);
   4096   1.1  christos   else
   4097   1.1  christos     return s7_bfd_score_elf_relocate_section (output_bfd,
   4098   1.8  christos 	     info, input_bfd, input_section, contents, relocs,
   4099   1.8  christos 	     local_syms, local_sections);
   4100   1.1  christos }
   4101   1.1  christos 
   4102  1.10  christos static bool
   4103   1.1  christos _bfd_score_elf_check_relocs (bfd *abfd,
   4104   1.8  christos 			     struct bfd_link_info *info,
   4105   1.8  christos 			     asection *sec,
   4106   1.8  christos 			     const Elf_Internal_Rela *relocs)
   4107   1.1  christos {
   4108   1.1  christos   if (bfd_get_mach (abfd) == bfd_mach_score3)
   4109   1.1  christos     return s3_bfd_score_elf_check_relocs (abfd, info, sec, relocs);
   4110   1.1  christos   else
   4111   1.1  christos     return s7_bfd_score_elf_check_relocs (abfd, info, sec, relocs);
   4112   1.1  christos }
   4113   1.1  christos 
   4114  1.10  christos static bool
   4115   1.1  christos _bfd_score_elf_add_symbol_hook (bfd *abfd,
   4116   1.8  christos 				struct bfd_link_info *info ATTRIBUTE_UNUSED,
   4117   1.8  christos 				Elf_Internal_Sym *sym,
   4118   1.8  christos 				const char **namep ATTRIBUTE_UNUSED,
   4119   1.8  christos 				flagword *flagsp ATTRIBUTE_UNUSED,
   4120   1.8  christos 				asection **secp,
   4121   1.8  christos 				bfd_vma *valp)
   4122   1.1  christos {
   4123   1.1  christos   if (bfd_get_mach (abfd) == bfd_mach_score3)
   4124   1.1  christos     return s3_bfd_score_elf_add_symbol_hook (abfd, info, sym, namep, flagsp,
   4125   1.8  christos 					     secp, valp);
   4126   1.1  christos   else
   4127   1.1  christos     return s7_bfd_score_elf_add_symbol_hook (abfd, info, sym, namep, flagsp,
   4128   1.8  christos 					     secp, valp);
   4129   1.1  christos }
   4130   1.1  christos 
   4131   1.1  christos static void
   4132   1.1  christos _bfd_score_elf_symbol_processing (bfd *abfd, asymbol *asym)
   4133   1.1  christos {
   4134   1.1  christos   if (bfd_get_mach (abfd) == bfd_mach_score3)
   4135   1.1  christos     return s3_bfd_score_elf_symbol_processing (abfd, asym);
   4136   1.1  christos   else
   4137   1.1  christos     return s7_bfd_score_elf_symbol_processing (abfd, asym);
   4138   1.1  christos }
   4139   1.1  christos 
   4140   1.1  christos static int
   4141   1.1  christos _bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
   4142   1.1  christos      const char *name ATTRIBUTE_UNUSED,
   4143   1.1  christos      Elf_Internal_Sym *sym,
   4144   1.1  christos      asection *input_sec,
   4145   1.1  christos      struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
   4146   1.1  christos {
   4147   1.1  christos   /* If link a empty .o, then this filed is NULL.  */
   4148   1.1  christos   if (info->input_bfds == NULL)
   4149   1.1  christos     {
   4150   1.1  christos       /* If we see a common symbol, which implies a relocatable link, then
   4151   1.8  christos 	 if a symbol was small common in an input file, mark it as small
   4152   1.8  christos 	 common in the output file.  */
   4153   1.1  christos       if (sym->st_shndx == SHN_COMMON && strcmp (input_sec->name, ".scommon") == 0)
   4154   1.8  christos 	sym->st_shndx = SHN_SCORE_SCOMMON;
   4155   1.1  christos       return 1;
   4156   1.1  christos     }
   4157   1.1  christos 
   4158   1.1  christos   if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
   4159   1.1  christos     return s3_bfd_score_elf_link_output_symbol_hook (info, name, sym, input_sec, h);
   4160   1.1  christos   else
   4161   1.1  christos     return s7_bfd_score_elf_link_output_symbol_hook (info, name, sym, input_sec, h);
   4162   1.1  christos }
   4163   1.1  christos 
   4164  1.10  christos static bool
   4165   1.1  christos _bfd_score_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
   4166   1.8  christos 					 asection *sec,
   4167   1.8  christos 					 int *retval)
   4168   1.1  christos {
   4169   1.1  christos   if (bfd_get_mach (abfd) == bfd_mach_score3)
   4170   1.1  christos     return s3_bfd_score_elf_section_from_bfd_section (abfd, sec, retval);
   4171   1.1  christos   else
   4172   1.1  christos     return s7_bfd_score_elf_section_from_bfd_section (abfd, sec, retval);
   4173   1.1  christos }
   4174   1.1  christos 
   4175  1.10  christos static bool
   4176   1.1  christos _bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   4177   1.8  christos 				      struct elf_link_hash_entry *h)
   4178   1.1  christos {
   4179   1.1  christos   if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
   4180   1.1  christos     return s3_bfd_score_elf_adjust_dynamic_symbol (info, h);
   4181   1.1  christos   else
   4182   1.1  christos     return s7_bfd_score_elf_adjust_dynamic_symbol (info, h);
   4183   1.1  christos }
   4184   1.1  christos 
   4185  1.10  christos static bool
   4186  1.11  christos _bfd_score_elf_early_size_sections (bfd *output_bfd,
   4187  1.11  christos 				    struct bfd_link_info *info)
   4188   1.1  christos {
   4189   1.1  christos   if (bfd_get_mach (output_bfd) == bfd_mach_score3)
   4190  1.11  christos     return s3_bfd_score_elf_early_size_sections (output_bfd, info);
   4191   1.1  christos   else
   4192  1.11  christos     return s7_bfd_score_elf_early_size_sections (output_bfd, info);
   4193   1.1  christos }
   4194   1.1  christos 
   4195  1.10  christos static bool
   4196  1.11  christos _bfd_score_elf_late_size_sections (bfd *output_bfd, struct bfd_link_info *info)
   4197   1.1  christos {
   4198   1.1  christos   if (bfd_get_mach (output_bfd) == bfd_mach_score3)
   4199  1.11  christos     return s3_bfd_score_elf_late_size_sections (output_bfd, info);
   4200   1.1  christos   else
   4201  1.11  christos     return s7_bfd_score_elf_late_size_sections (output_bfd, info);
   4202   1.1  christos }
   4203   1.1  christos 
   4204  1.10  christos static bool
   4205   1.1  christos _bfd_score_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
   4206   1.1  christos {
   4207   1.1  christos   if (bfd_get_mach (abfd) == bfd_mach_score3)
   4208   1.1  christos     return s3_bfd_score_elf_create_dynamic_sections (abfd, info);
   4209   1.1  christos   else
   4210   1.1  christos     return s7_bfd_score_elf_create_dynamic_sections (abfd, info);
   4211   1.1  christos }
   4212   1.1  christos 
   4213  1.10  christos static bool
   4214   1.1  christos _bfd_score_elf_finish_dynamic_symbol (bfd *output_bfd,
   4215   1.8  christos 				      struct bfd_link_info *info,
   4216   1.8  christos 				      struct elf_link_hash_entry *h,
   4217   1.8  christos 				      Elf_Internal_Sym *sym)
   4218   1.1  christos {
   4219   1.1  christos   if (bfd_get_mach (output_bfd) == bfd_mach_score3)
   4220   1.1  christos     return s3_bfd_score_elf_finish_dynamic_symbol (output_bfd, info, h, sym);
   4221   1.1  christos   else
   4222   1.1  christos     return s7_bfd_score_elf_finish_dynamic_symbol (output_bfd, info, h, sym);
   4223   1.1  christos }
   4224   1.1  christos 
   4225  1.10  christos static bool
   4226   1.1  christos _bfd_score_elf_finish_dynamic_sections (bfd *output_bfd,
   4227   1.8  christos 					struct bfd_link_info *info)
   4228   1.1  christos {
   4229   1.1  christos   if (bfd_get_mach (output_bfd) == bfd_mach_score3)
   4230   1.1  christos     return s3_bfd_score_elf_finish_dynamic_sections (output_bfd, info);
   4231   1.1  christos   else
   4232   1.1  christos     return s7_bfd_score_elf_finish_dynamic_sections (output_bfd, info);
   4233   1.1  christos }
   4234   1.1  christos 
   4235  1.10  christos static bool
   4236   1.1  christos _bfd_score_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
   4237   1.8  christos 			      Elf_Internal_Shdr *hdr,
   4238   1.8  christos 			      asection *sec)
   4239   1.1  christos {
   4240   1.1  christos   if (bfd_get_mach (abfd) == bfd_mach_score3)
   4241   1.1  christos     return s3_bfd_score_elf_fake_sections (abfd, hdr, sec);
   4242   1.1  christos   else
   4243   1.1  christos     return s7_bfd_score_elf_fake_sections (abfd, hdr, sec);
   4244   1.1  christos }
   4245   1.1  christos 
   4246  1.10  christos static bool
   4247   1.1  christos _bfd_score_elf_section_processing (bfd *abfd ATTRIBUTE_UNUSED, Elf_Internal_Shdr *hdr)
   4248   1.1  christos {
   4249   1.1  christos   if (bfd_get_mach (abfd) == bfd_mach_score3)
   4250   1.1  christos     return s3_bfd_score_elf_section_processing (abfd, hdr);
   4251   1.1  christos   else
   4252   1.1  christos     return s7_bfd_score_elf_section_processing (abfd, hdr);
   4253   1.1  christos }
   4254   1.1  christos 
   4255  1.10  christos static bool
   4256   1.1  christos _bfd_score_elf_write_section (bfd *output_bfd,
   4257   1.8  christos 			      struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
   4258   1.8  christos 			      asection *sec, bfd_byte *contents)
   4259   1.1  christos {
   4260   1.1  christos   if (bfd_get_mach (output_bfd) == bfd_mach_score3)
   4261   1.1  christos     return s3_bfd_score_elf_write_section (output_bfd, sec, contents);
   4262   1.1  christos   else
   4263   1.1  christos     return s7_bfd_score_elf_write_section (output_bfd, sec, contents);
   4264   1.1  christos }
   4265   1.1  christos 
   4266   1.1  christos static void
   4267   1.1  christos _bfd_score_elf_copy_indirect_symbol (struct bfd_link_info *info,
   4268   1.8  christos 				     struct elf_link_hash_entry *dir,
   4269   1.8  christos 				     struct elf_link_hash_entry *ind)
   4270   1.1  christos {
   4271   1.1  christos   if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
   4272   1.1  christos     return s3_bfd_score_elf_copy_indirect_symbol (info, dir, ind);
   4273   1.1  christos   else
   4274   1.1  christos     return s7_bfd_score_elf_copy_indirect_symbol (info, dir, ind);
   4275   1.1  christos }
   4276   1.1  christos 
   4277   1.1  christos static void
   4278   1.1  christos _bfd_score_elf_hide_symbol (struct bfd_link_info *info,
   4279   1.8  christos 			    struct elf_link_hash_entry *entry,
   4280  1.10  christos 			    bool force_local)
   4281   1.1  christos {
   4282   1.1  christos   if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
   4283   1.1  christos     return s3_bfd_score_elf_hide_symbol (info, entry, force_local);
   4284   1.1  christos   else
   4285   1.1  christos     return s7_bfd_score_elf_hide_symbol (info, entry, force_local);
   4286   1.1  christos }
   4287   1.1  christos 
   4288  1.10  christos static bool
   4289   1.1  christos _bfd_score_elf_discard_info (bfd *abfd, struct elf_reloc_cookie *cookie,
   4290   1.8  christos 			 struct bfd_link_info *info)
   4291   1.1  christos {
   4292   1.1  christos   if (bfd_get_mach (abfd) == bfd_mach_score3)
   4293   1.1  christos     return s3_bfd_score_elf_discard_info (abfd, cookie, info);
   4294   1.1  christos   else
   4295   1.1  christos     return s7_bfd_score_elf_discard_info (abfd, cookie, info);
   4296   1.1  christos }
   4297   1.1  christos 
   4298  1.10  christos static bool
   4299   1.1  christos _bfd_score_elf_ignore_discarded_relocs (asection *sec)
   4300   1.1  christos {
   4301   1.1  christos   if (bfd_get_mach (sec->owner) == bfd_mach_score3)
   4302   1.1  christos     return s3_bfd_score_elf_ignore_discarded_relocs (sec);
   4303   1.1  christos   else
   4304   1.1  christos     return s7_bfd_score_elf_ignore_discarded_relocs (sec);
   4305   1.1  christos }
   4306   1.1  christos 
   4307   1.1  christos static asection *
   4308   1.1  christos _bfd_score_elf_gc_mark_hook (asection *sec,
   4309   1.8  christos 			     struct bfd_link_info *info,
   4310   1.8  christos 			     Elf_Internal_Rela *rel,
   4311   1.8  christos 			     struct elf_link_hash_entry *h,
   4312   1.8  christos 			     Elf_Internal_Sym *sym)
   4313   1.1  christos {
   4314   1.1  christos   if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
   4315   1.1  christos     return s3_bfd_score_elf_gc_mark_hook (sec, info, rel, h, sym);
   4316   1.1  christos   else
   4317   1.1  christos     return s7_bfd_score_elf_gc_mark_hook (sec, info, rel, h, sym);
   4318   1.1  christos }
   4319   1.1  christos 
   4320  1.10  christos static bool
   4321   1.1  christos _bfd_score_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
   4322   1.1  christos {
   4323   1.1  christos   if (bfd_get_mach (abfd) == bfd_mach_score3)
   4324   1.1  christos     return s3_bfd_score_elf_grok_prstatus (abfd, note);
   4325   1.1  christos   else
   4326   1.1  christos     return s7_bfd_score_elf_grok_prstatus (abfd, note);
   4327   1.1  christos }
   4328   1.1  christos 
   4329  1.10  christos static bool
   4330   1.1  christos _bfd_score_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
   4331   1.1  christos {
   4332   1.1  christos   if (bfd_get_mach (abfd) == bfd_mach_score3)
   4333   1.1  christos     return s3_bfd_score_elf_grok_psinfo (abfd, note);
   4334   1.1  christos   else
   4335   1.1  christos     return s7_bfd_score_elf_grok_psinfo (abfd, note);
   4336   1.1  christos }
   4337   1.1  christos 
   4338   1.1  christos static reloc_howto_type *
   4339   1.1  christos elf32_score_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
   4340   1.1  christos {
   4341   1.1  christos   /* s3: NOTE!!!
   4342   1.1  christos      gas will call elf32_score_reloc_type_lookup, and don't write elf file.
   4343   1.1  christos      So just using score3, but we don't know ld will call this or not.
   4344   1.1  christos      If so, this way can't work.  */
   4345   1.1  christos 
   4346   1.1  christos   if (score3)
   4347   1.1  christos     return s3_elf32_score_reloc_type_lookup (abfd, code);
   4348   1.1  christos   else
   4349   1.1  christos     return s7_elf32_score_reloc_type_lookup (abfd, code);
   4350   1.1  christos }
   4351   1.1  christos 
   4352   1.1  christos /* Create a score elf linker hash table.
   4353   1.1  christos    This is a copy of _bfd_elf_link_hash_table_create() except with a
   4354   1.1  christos    different hash table entry creation function.  */
   4355   1.1  christos 
   4356   1.1  christos static struct bfd_link_hash_table *
   4357   1.1  christos elf32_score_link_hash_table_create (bfd *abfd)
   4358   1.1  christos {
   4359   1.1  christos   struct elf_link_hash_table *ret;
   4360   1.9  christos   size_t amt = sizeof (struct elf_link_hash_table);
   4361   1.1  christos 
   4362   1.1  christos   ret = (struct elf_link_hash_table *) bfd_zmalloc (amt);
   4363   1.1  christos   if (ret == NULL)
   4364   1.1  christos     return NULL;
   4365   1.1  christos 
   4366   1.1  christos   if (!_bfd_elf_link_hash_table_init (ret, abfd, score_elf_link_hash_newfunc,
   4367  1.12  christos 				      sizeof (struct score_elf_link_hash_entry)))
   4368   1.1  christos     {
   4369   1.1  christos       free (ret);
   4370   1.1  christos       return NULL;
   4371   1.1  christos     }
   4372   1.1  christos 
   4373   1.1  christos   return &ret->root;
   4374   1.1  christos }
   4375   1.1  christos 
   4376  1.10  christos static bool
   4377   1.1  christos elf32_score_print_private_bfd_data (bfd *abfd, void * ptr)
   4378   1.1  christos {
   4379   1.1  christos   if (bfd_get_mach (abfd) == bfd_mach_score3)
   4380   1.1  christos     return s3_elf32_score_print_private_bfd_data (abfd, ptr);
   4381   1.1  christos   else
   4382   1.1  christos     return s7_elf32_score_print_private_bfd_data (abfd, ptr);
   4383   1.1  christos }
   4384   1.1  christos 
   4385  1.10  christos static bool
   4386   1.7  christos elf32_score_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
   4387   1.1  christos {
   4388   1.7  christos   if (bfd_get_mach (info->output_bfd) == bfd_mach_score3)
   4389   1.7  christos     return s3_elf32_score_merge_private_bfd_data (ibfd, info);
   4390   1.1  christos   else
   4391   1.7  christos     return s7_elf32_score_merge_private_bfd_data (ibfd, info);
   4392   1.1  christos }
   4393   1.1  christos 
   4394  1.10  christos static bool
   4395   1.1  christos elf32_score_new_section_hook (bfd *abfd, asection *sec)
   4396   1.1  christos {
   4397   1.1  christos   if (bfd_get_mach (abfd) == bfd_mach_score3)
   4398   1.1  christos     return s3_elf32_score_new_section_hook (abfd, sec);
   4399   1.1  christos   else
   4400   1.1  christos     return s7_elf32_score_new_section_hook (abfd, sec);
   4401   1.1  christos }
   4402   1.1  christos 
   4403   1.1  christos 
   4404   1.1  christos /* s3_s7: don't need to split.  */
   4405   1.1  christos 
   4406   1.1  christos /* Set the right machine number.  */
   4407  1.10  christos static bool
   4408   1.1  christos _bfd_score_elf_score_object_p (bfd * abfd)
   4409   1.1  christos {
   4410   1.1  christos   int e_set = bfd_mach_score7;
   4411   1.1  christos 
   4412   1.1  christos   if (elf_elfheader (abfd)->e_machine == EM_SCORE)
   4413   1.1  christos     {
   4414   1.1  christos       int e_mach = elf_elfheader (abfd)->e_flags & EF_SCORE_MACH & EF_OMIT_PIC_FIXDD;
   4415   1.1  christos       switch (e_mach)
   4416   1.8  christos 	{
   4417   1.8  christos 	/* Set default target is score7.  */
   4418   1.8  christos 	default:
   4419   1.8  christos 	case E_SCORE_MACH_SCORE7:
   4420   1.8  christos 	  e_set = bfd_mach_score7;
   4421   1.8  christos 	  break;
   4422   1.8  christos 
   4423   1.8  christos 	case E_SCORE_MACH_SCORE3:
   4424   1.8  christos 	  e_set = bfd_mach_score3;
   4425   1.8  christos 	  break;
   4426   1.8  christos 	}
   4427   1.1  christos     }
   4428   1.1  christos 
   4429   1.1  christos   return bfd_default_set_arch_mach (abfd, bfd_arch_score, e_set);
   4430   1.1  christos }
   4431   1.1  christos 
   4432  1.10  christos bool
   4433   1.1  christos _bfd_score_elf_common_definition (Elf_Internal_Sym *sym)
   4434   1.1  christos {
   4435   1.1  christos   return (sym->st_shndx == SHN_COMMON || sym->st_shndx == SHN_SCORE_SCOMMON);
   4436   1.1  christos }
   4437   1.1  christos 
   4438   1.1  christos /*****************************************************************************/
   4439   1.1  christos 
   4440   1.1  christos 
   4441   1.8  christos #define USE_REL				1
   4442   1.8  christos #define TARGET_LITTLE_SYM		score_elf32_le_vec
   4443   1.8  christos #define TARGET_LITTLE_NAME		"elf32-littlescore"
   4444   1.8  christos #define TARGET_BIG_SYM			score_elf32_be_vec
   4445   1.8  christos #define TARGET_BIG_NAME			"elf32-bigscore"
   4446   1.8  christos #define ELF_ARCH			bfd_arch_score
   4447   1.8  christos #define ELF_MACHINE_CODE		EM_SCORE
   4448   1.8  christos #define ELF_MACHINE_ALT1		EM_SCORE_OLD
   4449  1.12  christos #define ELF_TARGET_ID			SCORE_ELF_DATA
   4450   1.8  christos #define ELF_MAXPAGESIZE			0x8000
   4451   1.8  christos 
   4452   1.8  christos #define elf_info_to_howto		NULL
   4453   1.8  christos #define elf_info_to_howto_rel		_bfd_score_info_to_howto
   4454   1.8  christos #define elf_backend_relocate_section	_bfd_score_elf_relocate_section
   4455   1.8  christos #define elf_backend_check_relocs	_bfd_score_elf_check_relocs
   4456   1.8  christos #define elf_backend_add_symbol_hook	_bfd_score_elf_add_symbol_hook
   4457   1.8  christos #define elf_backend_symbol_processing	_bfd_score_elf_symbol_processing
   4458   1.1  christos #define elf_backend_link_output_symbol_hook \
   4459   1.1  christos   _bfd_score_elf_link_output_symbol_hook
   4460   1.1  christos #define elf_backend_section_from_bfd_section \
   4461   1.1  christos   _bfd_score_elf_section_from_bfd_section
   4462   1.1  christos #define elf_backend_adjust_dynamic_symbol \
   4463   1.1  christos   _bfd_score_elf_adjust_dynamic_symbol
   4464  1.11  christos #define elf_backend_early_size_sections \
   4465  1.11  christos   _bfd_score_elf_early_size_sections
   4466  1.11  christos #define elf_backend_late_size_sections \
   4467  1.11  christos   _bfd_score_elf_late_size_sections
   4468   1.8  christos #define elf_backend_omit_section_dynsym   _bfd_elf_omit_section_dynsym_all
   4469   1.1  christos #define elf_backend_create_dynamic_sections \
   4470   1.1  christos   _bfd_score_elf_create_dynamic_sections
   4471   1.1  christos #define elf_backend_finish_dynamic_symbol \
   4472   1.1  christos   _bfd_score_elf_finish_dynamic_symbol
   4473   1.1  christos #define elf_backend_finish_dynamic_sections \
   4474   1.1  christos   _bfd_score_elf_finish_dynamic_sections
   4475   1.8  christos #define elf_backend_fake_sections	  _bfd_score_elf_fake_sections
   4476   1.8  christos #define elf_backend_section_processing	  _bfd_score_elf_section_processing
   4477   1.8  christos #define elf_backend_write_section	  _bfd_score_elf_write_section
   4478   1.1  christos #define elf_backend_copy_indirect_symbol  _bfd_score_elf_copy_indirect_symbol
   4479   1.8  christos #define elf_backend_hide_symbol		  _bfd_score_elf_hide_symbol
   4480   1.8  christos #define elf_backend_discard_info	  _bfd_score_elf_discard_info
   4481   1.1  christos #define elf_backend_ignore_discarded_relocs \
   4482   1.1  christos   _bfd_score_elf_ignore_discarded_relocs
   4483   1.8  christos #define elf_backend_gc_mark_hook	  _bfd_score_elf_gc_mark_hook
   4484   1.8  christos #define elf_backend_grok_prstatus	  _bfd_score_elf_grok_prstatus
   4485   1.8  christos #define elf_backend_grok_psinfo		  _bfd_score_elf_grok_psinfo
   4486   1.8  christos #define elf_backend_can_gc_sections	  1
   4487   1.8  christos #define elf_backend_want_plt_sym	  0
   4488   1.8  christos #define elf_backend_got_header_size	  (4 * SCORE_RESERVED_GOTNO)
   4489   1.8  christos #define elf_backend_plt_header_size	  0
   4490  1.10  christos #define elf_backend_collect		  true
   4491  1.10  christos #define elf_backend_type_change_ok	  true
   4492   1.8  christos #define elf_backend_object_p		      _bfd_score_elf_score_object_p
   4493   1.1  christos 
   4494   1.8  christos #define bfd_elf32_bfd_reloc_type_lookup	     elf32_score_reloc_type_lookup
   4495   1.1  christos #define bfd_elf32_bfd_reloc_name_lookup \
   4496   1.1  christos   elf32_score_reloc_name_lookup
   4497   1.1  christos #define bfd_elf32_bfd_link_hash_table_create elf32_score_link_hash_table_create
   4498   1.1  christos #define bfd_elf32_bfd_print_private_bfd_data elf32_score_print_private_bfd_data
   4499   1.1  christos #define bfd_elf32_bfd_merge_private_bfd_data elf32_score_merge_private_bfd_data
   4500   1.8  christos #define bfd_elf32_new_section_hook	     elf32_score_new_section_hook
   4501   1.1  christos 
   4502   1.1  christos #include "elf32-target.h"
   4503