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