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