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