Back to index

cell-binutils  2.17cvs20070401
elf32-score.c
Go to the documentation of this file.
00001 /* 32-bit ELF support for S+core.
00002    Copyright 2006, 2007 Free Software Foundation, Inc.
00003    Contributed by
00004    Mei Ligang (ligang@sunnorth.com.cn)
00005    Pei-Lin Tsai (pltsai@sunplus.com)
00006 
00007    This file is part of BFD, the Binary File Descriptor library.
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 2 of the License, or
00012    (at your option) any later version.
00013 
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018 
00019    You should have received a copy of the GNU General Public License
00020    along with this program; if not, write to the Free Software
00021    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00022 
00023 #include "bfd.h"
00024 #include "sysdep.h"
00025 #include "libbfd.h"
00026 #include "libiberty.h"
00027 #include "elf-bfd.h"
00028 #include "elf/score.h"
00029 #include "elf/common.h"
00030 #include "elf/internal.h"
00031 #include "hashtab.h"
00032 
00033 
00034 /* Score ELF linker hash table.  */
00035 
00036 struct score_elf_link_hash_table
00037 {
00038   /* The main hash table.  */
00039   struct elf_link_hash_table root;
00040 };
00041 
00042 /* The SCORE ELF linker needs additional information for each symbol in
00043    the global hash table.  */
00044 
00045 struct score_elf_link_hash_entry
00046 {
00047   struct elf_link_hash_entry root;
00048 
00049   /* Number of R_SCORE_ABS32, R_SCORE_REL32 relocs against this symbol.  */
00050   unsigned int possibly_dynamic_relocs;
00051 
00052   /* If the R_SCORE_ABS32, R_SCORE_REL32 reloc is against a readonly section.  */
00053   bfd_boolean readonly_reloc;
00054 
00055   /* We must not create a stub for a symbol that has relocations related to
00056      taking the function's address, i.e. any but R_SCORE_CALL15 ones.  */
00057   bfd_boolean no_fn_stub;
00058 
00059   /* Are we forced local?  This will only be set if we have converted
00060      the initial global GOT entry to a local GOT entry.  */
00061   bfd_boolean forced_local;
00062 };
00063 
00064 /* Traverse a score ELF linker hash table.  */
00065 #define score_elf_link_hash_traverse(table, func, info) \
00066   (elf_link_hash_traverse \
00067    (&(table)->root, \
00068     (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \
00069     (info)))
00070 
00071 /* Get the SCORE elf linker hash table from a link_info structure.  */
00072 #define score_elf_hash_table(info) \
00073   ((struct score_elf_link_hash_table *) ((info)->hash))
00074 
00075 /* This structure is used to hold .got entries while estimating got sizes.  */
00076 struct score_got_entry
00077 {
00078   /* The input bfd in which the symbol is defined.  */
00079   bfd *abfd;
00080   /* The index of the symbol, as stored in the relocation r_info, if
00081      we have a local symbol; -1 otherwise.  */
00082   long symndx;
00083   union
00084   {
00085     /* If abfd == NULL, an address that must be stored in the got.  */
00086     bfd_vma address;
00087     /* If abfd != NULL && symndx != -1, the addend of the relocation
00088        that should be added to the symbol value.  */
00089     bfd_vma addend;
00090     /* If abfd != NULL && symndx == -1, the hash table entry
00091        corresponding to a global symbol in the got (or, local, if
00092        h->forced_local).  */
00093     struct score_elf_link_hash_entry *h;
00094   } d;
00095 
00096   /* The offset from the beginning of the .got section to the entry
00097      corresponding to this symbol+addend.  If it's a global symbol
00098      whose offset is yet to be decided, it's going to be -1.  */
00099   long gotidx;
00100 };
00101 
00102 /* This structure is passed to score_elf_sort_hash_table_f when sorting
00103    the dynamic symbols.  */
00104 
00105 struct score_elf_hash_sort_data
00106 {
00107   /* The symbol in the global GOT with the lowest dynamic symbol table index.  */
00108   struct elf_link_hash_entry *low;
00109   /* The least dynamic symbol table index corresponding to a symbol with a GOT entry.  */
00110   long min_got_dynindx;
00111   /* The greatest dynamic symbol table index corresponding to a symbol
00112      with a GOT entry that is not referenced (e.g., a dynamic symbol
00113      with dynamic relocations pointing to it from non-primary GOTs).  */
00114   long max_unref_got_dynindx;
00115   /* The greatest dynamic symbol table index not corresponding to a
00116      symbol without a GOT entry.  */
00117   long max_non_got_dynindx;
00118 };
00119 
00120 struct score_got_info
00121 {
00122   /* The global symbol in the GOT with the lowest index in the dynamic
00123      symbol table.  */
00124   struct elf_link_hash_entry *global_gotsym;
00125   /* The number of global .got entries.  */
00126   unsigned int global_gotno;
00127   /* The number of local .got entries.  */
00128   unsigned int local_gotno;
00129   /* The number of local .got entries we have used.  */
00130   unsigned int assigned_gotno;
00131   /* A hash table holding members of the got.  */
00132   struct htab *got_entries;
00133   /* In multi-got links, a pointer to the next got (err, rather, most
00134      of the time, it points to the previous got).  */
00135   struct score_got_info *next;
00136 };
00137 
00138 /* A structure used to count GOT entries, for GOT entry or ELF symbol table traversal.  */
00139 struct _score_elf_section_data
00140 {
00141   struct bfd_elf_section_data elf;
00142   union
00143   {
00144     struct score_got_info *got_info;
00145     bfd_byte *tdata;
00146   }
00147   u;
00148 };
00149 
00150 #define score_elf_section_data(sec) \
00151   ((struct _score_elf_section_data *) elf_section_data (sec))
00152 
00153 /* The size of a symbol-table entry.  */
00154 #define SCORE_ELF_SYM_SIZE(abfd)  \
00155   (get_elf_backend_data (abfd)->s->sizeof_sym)
00156 
00157 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
00158    from smaller values.  Start with zero, widen, *then* decrement.  */
00159 #define MINUS_ONE (((bfd_vma)0) - 1)
00160 #define MINUS_TWO (((bfd_vma)0) - 2)
00161 
00162 #define PDR_SIZE 32
00163 
00164 
00165 /* The number of local .got entries we reserve.  */
00166 #define SCORE_RESERVED_GOTNO (2)
00167 #define ELF_DYNAMIC_INTERPRETER     "/usr/lib/ld.so.1"
00168 
00169 /* The offset of $gp from the beginning of the .got section.  */
00170 #define ELF_SCORE_GP_OFFSET(abfd) (0x3ff0)
00171 /* The maximum size of the GOT for it to be addressable using 15-bit offsets from $gp.  */
00172 #define SCORE_ELF_GOT_MAX_SIZE(abfd) (ELF_SCORE_GP_OFFSET(abfd) + 0x3fff)
00173 
00174 #define SCORE_ELF_STUB_SECTION_NAME  (".SCORE.stub")
00175 #define SCORE_FUNCTION_STUB_SIZE (16)
00176 
00177 #define STUB_LW           0xc3bcc010     /* lw r29, [r28, -0x3ff0]  */
00178 #define STUB_MOVE    0x8363bc56     /* mv r27, r3  */
00179 #define STUB_LI16    0x87548000     /* ori r26, .dynsym_index  */
00180 #define STUB_BRL     0x801dbc09     /* brl r29  */
00181 
00182 #define SCORE_ELF_GOT_SIZE(abfd)   \
00183   (get_elf_backend_data (abfd)->s->arch_size / 8)
00184 
00185 #define SCORE_ELF_ADD_DYNAMIC_ENTRY(info, tag, val) \
00186         (_bfd_elf_add_dynamic_entry (info, (bfd_vma) tag, (bfd_vma) val))
00187 
00188 /* The size of an external dynamic table entry.  */
00189 #define SCORE_ELF_DYN_SIZE(abfd) \
00190   (get_elf_backend_data (abfd)->s->sizeof_dyn)
00191 
00192 /* The size of an external REL relocation.  */
00193 #define SCORE_ELF_REL_SIZE(abfd) \
00194   (get_elf_backend_data (abfd)->s->sizeof_rel)
00195 
00196 /* The default alignment for sections, as a power of two.  */
00197 #define SCORE_ELF_LOG_FILE_ALIGN(abfd)\
00198   (get_elf_backend_data (abfd)->s->log_file_align)
00199 
00200 #ifndef NUM_ELEM
00201 #define NUM_ELEM(a)  (sizeof (a) / (sizeof (a)[0]))
00202 #endif
00203 
00204 static bfd_byte *hi16_rel_addr;
00205 
00206 /* This will be used when we sort the dynamic relocation records.  */
00207 static bfd *reldyn_sorting_bfd;
00208 
00209 /* SCORE ELF uses two common sections.  One is the usual one, and the
00210    other is for small objects.  All the small objects are kept
00211    together, and then referenced via the gp pointer, which yields
00212    faster assembler code.  This is what we use for the small common
00213    section.  This approach is copied from ecoff.c.  */
00214 static asection score_elf_scom_section;
00215 static asymbol  score_elf_scom_symbol;
00216 static asymbol  *score_elf_scom_symbol_ptr;
00217 
00218 static bfd_reloc_status_type
00219 score_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED,
00220                     arelent *reloc_entry,
00221                     asymbol *symbol ATTRIBUTE_UNUSED,
00222                     void * data,
00223                     asection *input_section ATTRIBUTE_UNUSED,
00224                     bfd *output_bfd ATTRIBUTE_UNUSED,
00225                     char **error_message ATTRIBUTE_UNUSED)
00226 {
00227   hi16_rel_addr = (bfd_byte *) data + reloc_entry->address;
00228   return bfd_reloc_ok;
00229 }
00230 
00231 static bfd_reloc_status_type
00232 score_elf_lo16_reloc (bfd *abfd,
00233                     arelent *reloc_entry,
00234                     asymbol *symbol ATTRIBUTE_UNUSED,
00235                     void * data,
00236                     asection *input_section,
00237                     bfd *output_bfd ATTRIBUTE_UNUSED,
00238                     char **error_message ATTRIBUTE_UNUSED)
00239 {
00240   bfd_vma addend = 0, offset = 0;
00241   unsigned long val;
00242   unsigned long hi16_offset, hi16_value, uvalue;
00243 
00244   hi16_value = bfd_get_32 (abfd, hi16_rel_addr);
00245   hi16_offset = ((((hi16_value >> 16) & 0x3) << 15) | (hi16_value & 0x7fff)) >> 1;
00246   addend = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
00247   offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
00248   val = reloc_entry->addend;
00249   if (reloc_entry->address > input_section->size)
00250     return bfd_reloc_outofrange;
00251   uvalue = ((hi16_offset << 16) | (offset & 0xffff)) + val;
00252   hi16_offset = (uvalue >> 16) << 1;
00253   hi16_value = (hi16_value & ~0x37fff) | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
00254   bfd_put_32 (abfd, hi16_value, hi16_rel_addr);
00255   offset = (uvalue & 0xffff) << 1;
00256   addend = (addend & ~0x37fff) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
00257   bfd_put_32 (abfd, addend, (bfd_byte *) data + reloc_entry->address);
00258   return bfd_reloc_ok;
00259 }
00260 
00261 /* Set the GP value for OUTPUT_BFD.  Returns FALSE if this is a
00262    dangerous relocation.  */
00263 
00264 static bfd_boolean
00265 score_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
00266 {
00267   unsigned int count;
00268   asymbol **sym;
00269   unsigned int i;
00270 
00271   /* If we've already figured out what GP will be, just return it.  */
00272   *pgp = _bfd_get_gp_value (output_bfd);
00273   if (*pgp)
00274     return TRUE;
00275 
00276   count = bfd_get_symcount (output_bfd);
00277   sym = bfd_get_outsymbols (output_bfd);
00278 
00279   /* The linker script will have created a symbol named `_gp' with the
00280      appropriate value.  */
00281   if (sym == NULL)
00282     i = count;
00283   else
00284     {
00285       for (i = 0; i < count; i++, sym++)
00286        {
00287          const char *name;
00288 
00289          name = bfd_asymbol_name (*sym);
00290          if (*name == '_' && strcmp (name, "_gp") == 0)
00291            {
00292              *pgp = bfd_asymbol_value (*sym);
00293              _bfd_set_gp_value (output_bfd, *pgp);
00294              break;
00295            }
00296        }
00297     }
00298 
00299   if (i >= count)
00300     {
00301       /* Only get the error once.  */
00302       *pgp = 4;
00303       _bfd_set_gp_value (output_bfd, *pgp);
00304       return FALSE;
00305     }
00306 
00307   return TRUE;
00308 }
00309 
00310 /* We have to figure out the gp value, so that we can adjust the
00311    symbol value correctly.  We look up the symbol _gp in the output
00312    BFD.  If we can't find it, we're stuck.  We cache it in the ELF
00313    target data.  We don't need to adjust the symbol value for an
00314    external symbol if we are producing relocatable output.  */
00315 
00316 static bfd_reloc_status_type
00317 score_elf_final_gp (bfd *output_bfd,
00318                   asymbol *symbol,
00319                   bfd_boolean relocatable,
00320                   char **error_message,
00321                   bfd_vma *pgp)
00322 {
00323   if (bfd_is_und_section (symbol->section)
00324       && ! relocatable)
00325     {
00326       *pgp = 0;
00327       return bfd_reloc_undefined;
00328     }
00329 
00330   *pgp = _bfd_get_gp_value (output_bfd);
00331   if (*pgp == 0
00332       && (! relocatable
00333          || (symbol->flags & BSF_SECTION_SYM) != 0))
00334     {
00335       if (relocatable)
00336        {
00337          /* Make up a value.  */
00338          *pgp = symbol->section->output_section->vma + 0x4000;
00339          _bfd_set_gp_value (output_bfd, *pgp);
00340        }
00341       else if (!score_elf_assign_gp (output_bfd, pgp))
00342        {
00343            *error_message =
00344              (char *) _("GP relative relocation when _gp not defined");
00345            return bfd_reloc_dangerous;
00346        }
00347     }
00348 
00349   return bfd_reloc_ok;
00350 }
00351 
00352 static bfd_reloc_status_type
00353 score_elf_gprel15_with_gp (bfd *abfd,
00354                         asymbol *symbol,
00355                         arelent *reloc_entry,
00356                         asection *input_section,
00357                         bfd_boolean relocateable,
00358                         void * data,
00359                         bfd_vma gp ATTRIBUTE_UNUSED)
00360 {
00361   bfd_vma relocation;
00362   unsigned long insn;
00363 
00364   if (bfd_is_com_section (symbol->section))
00365     relocation = 0;
00366   else
00367     relocation = symbol->value;
00368 
00369   relocation += symbol->section->output_section->vma;
00370   relocation += symbol->section->output_offset;
00371   if (reloc_entry->address > input_section->size)
00372     return bfd_reloc_outofrange;
00373 
00374   insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
00375   if (((reloc_entry->addend & 0xffffc000) != 0)
00376       && ((reloc_entry->addend & 0xffffc000) != 0xffffc000))
00377     return bfd_reloc_overflow;
00378 
00379   insn = (insn & ~0x7fff) | (reloc_entry->addend & 0x7fff);
00380   bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
00381   if (relocateable)
00382     reloc_entry->address += input_section->output_offset;
00383 
00384   return bfd_reloc_ok;
00385 }
00386 
00387 static bfd_reloc_status_type
00388 gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
00389                asection *input_section, bfd_boolean relocatable,
00390                void *data, bfd_vma gp)
00391 {
00392   bfd_vma relocation;
00393   bfd_vma val;
00394 
00395   if (bfd_is_com_section (symbol->section))
00396     relocation = 0;
00397   else
00398     relocation = symbol->value;
00399 
00400   relocation += symbol->section->output_section->vma;
00401   relocation += symbol->section->output_offset;
00402 
00403   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
00404     return bfd_reloc_outofrange;
00405 
00406   /* Set val to the offset into the section or symbol.  */
00407   val = reloc_entry->addend;
00408 
00409   if (reloc_entry->howto->partial_inplace)
00410     val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
00411 
00412   /* Adjust val for the final section location and GP value.  If we
00413      are producing relocatable output, we don't want to do this for
00414      an external symbol.  */
00415   if (! relocatable
00416       || (symbol->flags & BSF_SECTION_SYM) != 0)
00417     val += relocation - gp;
00418 
00419   if (reloc_entry->howto->partial_inplace)
00420     bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
00421   else
00422     reloc_entry->addend = val;
00423 
00424   if (relocatable)
00425     reloc_entry->address += input_section->output_offset;
00426 
00427   return bfd_reloc_ok;
00428 }
00429 
00430 static bfd_reloc_status_type
00431 score_elf_gprel15_reloc (bfd *abfd,
00432                       arelent *reloc_entry,
00433                       asymbol *symbol,
00434                       void * data,
00435                       asection *input_section,
00436                       bfd *output_bfd,
00437                       char **error_message)
00438 {
00439   bfd_boolean relocateable;
00440   bfd_reloc_status_type ret;
00441   bfd_vma gp;
00442 
00443   if (output_bfd != (bfd *) NULL
00444       && (symbol->flags & BSF_SECTION_SYM) == 0 && reloc_entry->addend == 0)
00445     {
00446       reloc_entry->address += input_section->output_offset;
00447       return bfd_reloc_ok;
00448     }
00449   if (output_bfd != (bfd *) NULL)
00450     relocateable = TRUE;
00451   else
00452     {
00453       relocateable = FALSE;
00454       output_bfd = symbol->section->output_section->owner;
00455     }
00456 
00457   ret = score_elf_final_gp (output_bfd, symbol, relocateable, error_message, &gp);
00458   if (ret != bfd_reloc_ok)
00459     return ret;
00460 
00461   return score_elf_gprel15_with_gp (abfd, symbol, reloc_entry,
00462                                          input_section, relocateable, data, gp);
00463 }
00464 
00465 /* Do a R_SCORE_GPREL32 relocation.  This is a 32 bit value which must
00466    become the offset from the gp register.  */
00467 
00468 static bfd_reloc_status_type
00469 score_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
00470                      void *data, asection *input_section, bfd *output_bfd,
00471                      char **error_message)
00472 {
00473   bfd_boolean relocatable;
00474   bfd_reloc_status_type ret;
00475   bfd_vma gp;
00476 
00477   /* R_SCORE_GPREL32 relocations are defined for local symbols only.  */
00478   if (output_bfd != NULL
00479       && (symbol->flags & BSF_SECTION_SYM) == 0
00480       && (symbol->flags & BSF_LOCAL) != 0)
00481     {
00482       *error_message = (char *)
00483        _("32bits gp relative relocation occurs for an external symbol");
00484       return bfd_reloc_outofrange;
00485     }
00486 
00487   if (output_bfd != NULL)
00488     relocatable = TRUE;
00489   else
00490     {
00491       relocatable = FALSE;
00492       output_bfd = symbol->section->output_section->owner;
00493     }
00494 
00495   ret = score_elf_final_gp (output_bfd, symbol, relocatable, error_message, &gp);
00496   if (ret != bfd_reloc_ok)
00497     return ret;
00498 
00499   gp = 0;   /* FIXME.  */
00500   return gprel32_with_gp (abfd, symbol, reloc_entry, input_section,
00501                        relocatable, data, gp);
00502 }
00503 
00504 /* A howto special_function for R_SCORE_GOT15 relocations.  This is just
00505    like any other 16-bit relocation when applied to global symbols, but is
00506    treated in the same as R_SCORE_HI16 when applied to local symbols.  */
00507 
00508 static bfd_reloc_status_type
00509 score_elf_got15_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
00510                      void *data, asection *input_section,
00511                      bfd *output_bfd, char **error_message)
00512 {
00513   if ((symbol->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
00514       || bfd_is_und_section (bfd_get_section (symbol))
00515       || bfd_is_com_section (bfd_get_section (symbol)))
00516     /* The relocation is against a global symbol.  */
00517     return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
00518                               input_section, output_bfd,
00519                               error_message);
00520 
00521   return score_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
00522                             input_section, output_bfd, error_message);
00523 }
00524 
00525 static bfd_reloc_status_type
00526 score_elf_got_lo16_reloc (bfd *abfd,
00527                         arelent *reloc_entry,
00528                         asymbol *symbol ATTRIBUTE_UNUSED,
00529                         void * data,
00530                         asection *input_section,
00531                         bfd *output_bfd ATTRIBUTE_UNUSED,
00532                         char **error_message ATTRIBUTE_UNUSED)
00533 {
00534   bfd_vma addend = 0, offset = 0;
00535   signed long val;
00536   signed long hi16_offset, hi16_value, uvalue;
00537 
00538   hi16_value = bfd_get_32 (abfd, hi16_rel_addr);
00539   hi16_offset = ((((hi16_value >> 16) & 0x3) << 15) | (hi16_value & 0x7fff)) >> 1;
00540   addend = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
00541   offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
00542   val = reloc_entry->addend;
00543   if (reloc_entry->address > input_section->size)
00544     return bfd_reloc_outofrange;
00545   uvalue = ((hi16_offset << 16) | (offset & 0xffff)) + val;
00546   if ((uvalue > -0x8000) && (uvalue < 0x7fff))
00547     hi16_offset = 0;
00548   else
00549     hi16_offset = (uvalue >> 16) & 0x7fff;
00550   hi16_value = (hi16_value & ~0x37fff) | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
00551   bfd_put_32 (abfd, hi16_value, hi16_rel_addr);
00552   offset = (uvalue & 0xffff) << 1;
00553   addend = (addend & ~0x37fff) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
00554   bfd_put_32 (abfd, addend, (bfd_byte *) data + reloc_entry->address);
00555   return bfd_reloc_ok;
00556 }
00557 
00558 static reloc_howto_type elf32_score_howto_table[] =
00559 {
00560   /* No relocation.  */
00561   HOWTO (R_SCORE_NONE,          /* type */
00562          0,                     /* rightshift */
00563          0,                     /* size (0 = byte, 1 = short, 2 = long) */
00564          0,                     /* bitsize */
00565          FALSE,                 /* pc_relative */
00566          0,                     /* bitpos */
00567          complain_overflow_dont,/* complain_on_overflow */
00568          bfd_elf_generic_reloc, /* special_function */
00569          "R_SCORE_NONE",        /* name */
00570          FALSE,                 /* partial_inplace */
00571          0,                     /* src_mask */
00572          0,                     /* dst_mask */
00573          FALSE),                /* pcrel_offset */
00574 
00575   /* R_SCORE_HI16 */
00576   HOWTO (R_SCORE_HI16,          /* type */
00577          0,                     /* rightshift */
00578          2,                     /* size (0 = byte, 1 = short, 2 = long) */
00579          16,                    /* bitsize */
00580          FALSE,                 /* pc_relative */
00581          1,                     /* bitpos */
00582          complain_overflow_dont,/* complain_on_overflow */
00583         score_elf_hi16_reloc,  /* special_function */
00584          "R_SCORE_HI16",        /* name */
00585          TRUE,                  /* partial_inplace */
00586          0x37fff,               /* src_mask */
00587          0x37fff,               /* dst_mask */
00588          FALSE),                /* pcrel_offset */
00589 
00590   /* R_SCORE_LO16 */
00591   HOWTO (R_SCORE_LO16,          /* type */
00592          0,                     /* rightshift */
00593          2,                     /* size (0 = byte, 1 = short, 2 = long) */
00594          16,                    /* bitsize */
00595          FALSE,                 /* pc_relative */
00596          1,                     /* bitpos */
00597          complain_overflow_dont,/* complain_on_overflow */
00598          score_elf_lo16_reloc,  /* special_function */
00599          "R_SCORE_LO16",        /* name */
00600          TRUE,                  /* partial_inplace */
00601          0x37fff,               /* src_mask */
00602          0x37fff,               /* dst_mask */
00603          FALSE),                /* pcrel_offset */
00604 
00605   /*  R_SCORE_DUMMY1 */
00606   HOWTO (R_SCORE_DUMMY1,        /* type */
00607          0,                     /* rightshift */
00608          2,                     /* size (0 = byte, 1 = short, 2 = long) */
00609          16,                    /* bitsize */
00610          FALSE,                 /* pc_relative */
00611          1,                     /* bitpos */
00612          complain_overflow_dont,/* complain_on_overflow */
00613          bfd_elf_generic_reloc, /* special_function */
00614          "R_SCORE_DUMMY1",      /* name */
00615          TRUE,                  /* partial_inplace */
00616          0x0000ffff,            /* src_mask */
00617          0x0000ffff,            /* dst_mask */
00618          FALSE),                /* pcrel_offset */
00619 
00620   /*R_SCORE_24 */
00621   HOWTO (R_SCORE_24,            /* type */
00622          1,                     /* rightshift */
00623          2,                     /* size (0 = byte, 1 = short, 2 = long) */
00624          24,                    /* bitsize */
00625          FALSE,                 /* pc_relative */
00626          1,                     /* bitpos */
00627          complain_overflow_dont,/* complain_on_overflow */
00628          bfd_elf_generic_reloc, /* special_function */
00629          "R_SCORE_24",          /* name */
00630          FALSE,                 /* partial_inplace */
00631          0x3ff7fff,             /* src_mask */
00632          0x3ff7fff,             /* dst_mask */
00633          FALSE),                /* pcrel_offset */
00634 
00635   /*R_SCORE_PC19 */
00636   HOWTO (R_SCORE_PC19,          /* type */
00637          1,                     /* rightshift */
00638          2,                     /* size (0 = byte, 1 = short, 2 = long) */
00639          19,                    /* bitsize */
00640          TRUE,                  /* pc_relative */
00641          1,                     /* bitpos */
00642          complain_overflow_dont,/* complain_on_overflow */
00643          bfd_elf_generic_reloc, /* special_function */
00644          "R_SCORE_PC19",        /* name */
00645          FALSE,                 /* partial_inplace */
00646          0x3ff03fe,             /* src_mask */
00647          0x3ff03fe,             /* dst_mask */
00648          FALSE),                /* pcrel_offset */
00649 
00650   /*R_SCORE16_11 */
00651   HOWTO (R_SCORE16_11,          /* type */
00652          1,                     /* rightshift */
00653          1,                     /* size (0 = byte, 1 = short, 2 = long) */
00654          11,                    /* bitsize */
00655          FALSE,                 /* pc_relative */
00656          1,                     /* bitpos */
00657          complain_overflow_dont,/* complain_on_overflow */
00658          bfd_elf_generic_reloc, /* special_function */
00659          "R_SCORE16_11",        /* name */
00660          FALSE,                 /* partial_inplace */
00661          0x000000ffe,           /* src_mask */
00662          0x000000ffe,           /* dst_mask */
00663          FALSE),                /* pcrel_offset */
00664 
00665   /* R_SCORE16_PC8 */
00666   HOWTO (R_SCORE16_PC8,         /* type */
00667          1,                     /* rightshift */
00668          1,                     /* size (0 = byte, 1 = short, 2 = long) */
00669          8,                     /* bitsize */
00670          TRUE,                  /* pc_relative */
00671          0,                     /* bitpos */
00672          complain_overflow_dont,/* complain_on_overflow */
00673          bfd_elf_generic_reloc, /* special_function */
00674          "R_SCORE16_PC8",       /* name */
00675          FALSE,                 /* partial_inplace */
00676          0x000000ff,            /* src_mask */
00677          0x000000ff,            /* dst_mask */
00678          FALSE),                /* pcrel_offset */
00679 
00680   /* 32 bit absolute */
00681   HOWTO (R_SCORE_ABS32,         /* type  8 */
00682          0,                     /* rightshift */
00683          2,                     /* size (0 = byte, 1 = short, 2 = long) */
00684          32,                    /* bitsize */
00685          FALSE,                 /* pc_relative */
00686          0,                     /* bitpos */
00687          complain_overflow_bitfield,    /* complain_on_overflow */
00688          bfd_elf_generic_reloc, /* special_function */
00689          "R_SCORE_ABS32",       /* name */
00690          FALSE,                 /* partial_inplace */
00691          0xffffffff,            /* src_mask */
00692          0xffffffff,            /* dst_mask */
00693          FALSE),                /* pcrel_offset */
00694 
00695   /* 16 bit absolute */
00696   HOWTO (R_SCORE_ABS16,         /* type 11 */
00697          0,                     /* rightshift */
00698          1,                     /* size (0 = byte, 1 = short, 2 = long) */
00699          16,                    /* bitsize */
00700          FALSE,                 /* pc_relative */
00701          0,                     /* bitpos */
00702          complain_overflow_bitfield,    /* complain_on_overflow */
00703          bfd_elf_generic_reloc, /* special_function */
00704          "R_SCORE_ABS16",       /* name */
00705          FALSE,                 /* partial_inplace */
00706          0x0000ffff,            /* src_mask */
00707          0x0000ffff,            /* dst_mask */
00708          FALSE),                /* pcrel_offset */
00709 
00710   /* R_SCORE_DUMMY2 */
00711   HOWTO (R_SCORE_DUMMY2,        /* type */
00712          0,                     /* rightshift */
00713          2,                     /* size (0 = byte, 1 = short, 2 = long) */
00714          16,                    /* bitsize */
00715          FALSE,                 /* pc_relative */
00716          0,                     /* bitpos */
00717          complain_overflow_dont,/* complain_on_overflow */
00718          bfd_elf_generic_reloc, /* special_function */
00719          "R_SCORE_DUMMY2",      /* name */
00720          TRUE,                  /* partial_inplace */
00721          0x00007fff,            /* src_mask */
00722          0x00007fff,            /* dst_mask */
00723          FALSE),                /* pcrel_offset */
00724 
00725   /* R_SCORE_GP15 */
00726   HOWTO (R_SCORE_GP15,          /* type */
00727          0,                     /* rightshift */
00728          2,                     /* size (0 = byte, 1 = short, 2 = long) */
00729          16,                    /* bitsize */
00730          FALSE,                 /* pc_relative */
00731          0,                     /* bitpos */
00732          complain_overflow_dont,/* complain_on_overflow */
00733          score_elf_gprel15_reloc,/* special_function */
00734          "R_SCORE_GP15",        /* name */
00735          TRUE,                  /* partial_inplace */
00736          0x00007fff,            /* src_mask */
00737          0x00007fff,            /* dst_mask */
00738          FALSE),                /* pcrel_offset */
00739 
00740   /* GNU extension to record C++ vtable hierarchy.  */
00741   HOWTO (R_SCORE_GNU_VTINHERIT, /* type */
00742          0,                     /* rightshift */
00743          2,                     /* size (0 = byte, 1 = short, 2 = long) */
00744          0,                     /* bitsize */
00745          FALSE,                 /* pc_relative */
00746          0,                     /* bitpos */
00747          complain_overflow_dont,/* complain_on_overflow */
00748          NULL,                  /* special_function */
00749          "R_SCORE_GNU_VTINHERIT",       /* name */
00750          FALSE,                 /* partial_inplace */
00751          0,                     /* src_mask */
00752          0,                     /* dst_mask */
00753          FALSE),                /* pcrel_offset */
00754 
00755   /* GNU extension to record C++ vtable member usage */
00756   HOWTO (R_SCORE_GNU_VTENTRY,   /* type */
00757          0,                     /* rightshift */
00758          2,                     /* size (0 = byte, 1 = short, 2 = long) */
00759          0,                     /* bitsize */
00760          FALSE,                 /* pc_relative */
00761          0,                     /* bitpos */
00762          complain_overflow_dont,/* complain_on_overflow */
00763          _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
00764          "R_SCORE_GNU_VTENTRY", /* name */
00765          FALSE,                 /* partial_inplace */
00766          0,                     /* src_mask */
00767          0,                     /* dst_mask */
00768          FALSE),                /* pcrel_offset */
00769 
00770   /* Reference to global offset table.  */
00771   HOWTO (R_SCORE_GOT15,         /* type */
00772          0,                     /* rightshift */
00773          2,                     /* size (0 = byte, 1 = short, 2 = long) */
00774          16,                    /* bitsize */
00775          FALSE,                 /* pc_relative */
00776          0,                     /* bitpos */
00777          complain_overflow_signed,      /* complain_on_overflow */
00778          score_elf_got15_reloc, /* special_function */
00779          "R_SCORE_GOT15",       /* name */
00780          TRUE,                  /* partial_inplace */
00781          0x00007fff,            /* src_mask */
00782          0x00007fff,            /* dst_mask */
00783          FALSE),                /* pcrel_offset */
00784 
00785   /* Low 16 bits of displacement in global offset table.  */
00786   HOWTO (R_SCORE_GOT_LO16,      /* type */
00787          0,                     /* rightshift */
00788          2,                     /* size (0 = byte, 1 = short, 2 = long) */
00789          16,                    /* bitsize */
00790          FALSE,                 /* pc_relative */
00791          1,                     /* bitpos */
00792          complain_overflow_dont,/* complain_on_overflow */
00793          score_elf_got_lo16_reloc, /* special_function */
00794          "R_SCORE_GOT_LO16",    /* name */
00795          TRUE,                  /* partial_inplace */
00796          0x37ffe,               /* src_mask */
00797          0x37ffe,               /* dst_mask */
00798          FALSE),                /* pcrel_offset */
00799 
00800   /* 15 bit call through global offset table.  */
00801   HOWTO (R_SCORE_CALL15,        /* type */
00802          0,                     /* rightshift */
00803          2,                     /* size (0 = byte, 1 = short, 2 = long) */
00804          16,                    /* bitsize */
00805          FALSE,                 /* pc_relative */
00806          0,                     /* bitpos */
00807          complain_overflow_signed, /* complain_on_overflow */
00808          bfd_elf_generic_reloc, /* special_function */
00809          "R_SCORE_CALL15",      /* name */
00810          TRUE,                  /* partial_inplace */
00811          0x0000ffff,            /* src_mask */
00812          0x0000ffff,            /* dst_mask */
00813          FALSE),                /* pcrel_offset */
00814 
00815   /* 32 bit GP relative reference.  */
00816   HOWTO (R_SCORE_GPREL32,       /* type */
00817          0,                     /* rightshift */
00818          2,                     /* size (0 = byte, 1 = short, 2 = long) */
00819          32,                    /* bitsize */
00820          FALSE,                 /* pc_relative */
00821          0,                     /* bitpos */
00822          complain_overflow_dont,/* complain_on_overflow */
00823          score_elf_gprel32_reloc, /* special_function */
00824          "R_SCORE_GPREL32",     /* name */
00825          TRUE,                  /* partial_inplace */
00826          0xffffffff,            /* src_mask */
00827          0xffffffff,            /* dst_mask */
00828          FALSE),                /* pcrel_offset */
00829 
00830   /* 32 bit symbol relative relocation.  */
00831   HOWTO (R_SCORE_REL32,         /* type */
00832         0,                     /* rightshift */
00833         2,                     /* size (0 = byte, 1 = short, 2 = long) */
00834         32,                    /* bitsize */
00835         FALSE,                 /* pc_relative */
00836         0,                     /* bitpos */
00837         complain_overflow_dont,/* complain_on_overflow */
00838         bfd_elf_generic_reloc, /* special_function */
00839         "R_SCORE_REL32",       /* name */
00840         TRUE,                  /* partial_inplace */
00841         0xffffffff,            /* src_mask */
00842         0xffffffff,            /* dst_mask */
00843         FALSE),                /* pcrel_offset */
00844 
00845   /* R_SCORE_DUMMY_HI16 */
00846   HOWTO (R_SCORE_DUMMY_HI16,    /* type */
00847          0,                     /* rightshift */
00848          2,                     /* size (0 = byte, 1 = short, 2 = long) */
00849          16,                    /* bitsize */
00850          FALSE,                 /* pc_relative */
00851          1,                     /* bitpos */
00852          complain_overflow_dont,/* complain_on_overflow */
00853         score_elf_hi16_reloc,  /* special_function */
00854          "R_SCORE_DUMMY_HI16",  /* name */
00855          TRUE,                  /* partial_inplace */
00856          0x37fff,               /* src_mask */
00857          0x37fff,               /* dst_mask */
00858          FALSE),                /* pcrel_offset */
00859 };
00860 
00861 struct score_reloc_map
00862 {
00863   bfd_reloc_code_real_type bfd_reloc_val;
00864   unsigned char elf_reloc_val;
00865 };
00866 
00867 static const struct score_reloc_map elf32_score_reloc_map[] =
00868 {
00869   {BFD_RELOC_NONE,               R_SCORE_NONE},
00870   {BFD_RELOC_HI16_S,             R_SCORE_HI16},
00871   {BFD_RELOC_LO16,               R_SCORE_LO16},
00872   {BFD_RELOC_SCORE_DUMMY1,       R_SCORE_DUMMY1},
00873   {BFD_RELOC_SCORE_JMP,          R_SCORE_24},
00874   {BFD_RELOC_SCORE_BRANCH,       R_SCORE_PC19},
00875   {BFD_RELOC_SCORE16_JMP,        R_SCORE16_11},
00876   {BFD_RELOC_SCORE16_BRANCH,     R_SCORE16_PC8},
00877   {BFD_RELOC_32,                 R_SCORE_ABS32},
00878   {BFD_RELOC_16,                 R_SCORE_ABS16},
00879   {BFD_RELOC_SCORE_DUMMY2,       R_SCORE_DUMMY2},
00880   {BFD_RELOC_SCORE_GPREL15,      R_SCORE_GP15},
00881   {BFD_RELOC_VTABLE_INHERIT,     R_SCORE_GNU_VTINHERIT},
00882   {BFD_RELOC_VTABLE_ENTRY,       R_SCORE_GNU_VTENTRY},
00883   {BFD_RELOC_SCORE_GOT15,        R_SCORE_GOT15},
00884   {BFD_RELOC_SCORE_GOT_LO16,     R_SCORE_GOT_LO16},
00885   {BFD_RELOC_SCORE_CALL15,       R_SCORE_CALL15},
00886   {BFD_RELOC_GPREL32,            R_SCORE_GPREL32},
00887   {BFD_RELOC_32_PCREL,           R_SCORE_REL32},
00888   {BFD_RELOC_SCORE_DUMMY_HI16,   R_SCORE_DUMMY_HI16},
00889 };
00890 
00891 /* got_entries only match if they're identical, except for gotidx, so
00892    use all fields to compute the hash, and compare the appropriate
00893    union members.  */
00894 
00895 static hashval_t
00896 score_elf_got_entry_hash (const void *entry_)
00897 {
00898   const struct score_got_entry *entry = (struct score_got_entry *)entry_;
00899 
00900   return entry->symndx
00901     + (!entry->abfd ? entry->d.address : entry->abfd->id);
00902 }
00903 
00904 static int
00905 score_elf_got_entry_eq (const void *entry1, const void *entry2)
00906 {
00907   const struct score_got_entry *e1 = (struct score_got_entry *)entry1;
00908   const struct score_got_entry *e2 = (struct score_got_entry *)entry2;
00909 
00910   return e1->abfd == e2->abfd && e1->symndx == e2->symndx
00911     && (! e1->abfd ? e1->d.address == e2->d.address
00912        : e1->symndx >= 0 ? e1->d.addend == e2->d.addend
00913        : e1->d.h == e2->d.h);
00914 }
00915 
00916 /* If H needs a GOT entry, assign it the highest available dynamic
00917    index.  Otherwise, assign it the lowest available dynamic
00918    index.  */
00919 
00920 static bfd_boolean
00921 score_elf_sort_hash_table_f (struct score_elf_link_hash_entry *h, void *data)
00922 {
00923   struct score_elf_hash_sort_data *hsd = data;
00924 
00925   if (h->root.root.type == bfd_link_hash_warning)
00926     h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
00927 
00928   /* Symbols without dynamic symbol table entries aren't interesting at all.  */
00929   if (h->root.dynindx == -1)
00930     return TRUE;
00931 
00932   /* Global symbols that need GOT entries that are not explicitly
00933      referenced are marked with got offset 2.  Those that are
00934      referenced get a 1, and those that don't need GOT entries get
00935      -1.  */
00936   if (h->root.got.offset == 2)
00937     {
00938       if (hsd->max_unref_got_dynindx == hsd->min_got_dynindx)
00939        hsd->low = (struct elf_link_hash_entry *) h;
00940       h->root.dynindx = hsd->max_unref_got_dynindx++;
00941     }
00942   else if (h->root.got.offset != 1)
00943     h->root.dynindx = hsd->max_non_got_dynindx++;
00944   else
00945     {
00946       h->root.dynindx = --hsd->min_got_dynindx;
00947       hsd->low = (struct elf_link_hash_entry *) h;
00948     }
00949 
00950   return TRUE;
00951 }
00952 
00953 static asection *
00954 score_elf_got_section (bfd *abfd, bfd_boolean maybe_excluded)
00955 {
00956   asection *sgot = bfd_get_section_by_name (abfd, ".got");
00957 
00958   if (sgot == NULL || (! maybe_excluded && (sgot->flags & SEC_EXCLUDE) != 0))
00959     return NULL;
00960   return sgot;
00961 }
00962 
00963 /* Returns the GOT information associated with the link indicated by
00964    INFO.  If SGOTP is non-NULL, it is filled in with the GOT section.  */
00965 
00966 static struct score_got_info *
00967 score_elf_got_info (bfd *abfd, asection **sgotp)
00968 {
00969   asection *sgot;
00970   struct score_got_info *g;
00971 
00972   sgot = score_elf_got_section (abfd, TRUE);
00973   BFD_ASSERT (sgot != NULL);
00974   BFD_ASSERT (elf_section_data (sgot) != NULL);
00975   g = score_elf_section_data (sgot)->u.got_info;
00976   BFD_ASSERT (g != NULL);
00977 
00978   if (sgotp)
00979     *sgotp = sgot;
00980   return g;
00981 }
00982 
00983 /* Sort the dynamic symbol table so that symbols that need GOT entries
00984    appear towards the end.  This reduces the amount of GOT space
00985    required.  MAX_LOCAL is used to set the number of local symbols
00986    known to be in the dynamic symbol table.  During
00987    _bfd_score_elf_size_dynamic_sections, this value is 1.  Afterward, the
00988    section symbols are added and the count is higher.  */
00989 
00990 static bfd_boolean
00991 score_elf_sort_hash_table (struct bfd_link_info *info,
00992                         unsigned long max_local)
00993 {
00994   struct score_elf_hash_sort_data hsd;
00995   struct score_got_info *g;
00996   bfd *dynobj;
00997 
00998   dynobj = elf_hash_table (info)->dynobj;
00999 
01000   g = score_elf_got_info (dynobj, NULL);
01001 
01002   hsd.low = NULL;
01003   hsd.max_unref_got_dynindx =
01004     hsd.min_got_dynindx = elf_hash_table (info)->dynsymcount
01005     /* In the multi-got case, assigned_gotno of the master got_info
01006        indicate the number of entries that aren't referenced in the
01007        primary GOT, but that must have entries because there are
01008        dynamic relocations that reference it.  Since they aren't
01009        referenced, we move them to the end of the GOT, so that they
01010        don't prevent other entries that are referenced from getting
01011        too large offsets.  */
01012     - (g->next ? g->assigned_gotno : 0);
01013   hsd.max_non_got_dynindx = max_local;
01014   score_elf_link_hash_traverse (((struct score_elf_link_hash_table *)
01015                              elf_hash_table (info)),
01016                               score_elf_sort_hash_table_f,
01017                               &hsd);
01018 
01019   /* There should have been enough room in the symbol table to
01020      accommodate both the GOT and non-GOT symbols.  */
01021   BFD_ASSERT (hsd.max_non_got_dynindx <= hsd.min_got_dynindx);
01022   BFD_ASSERT ((unsigned long)hsd.max_unref_got_dynindx
01023              <= elf_hash_table (info)->dynsymcount);
01024 
01025   /* Now we know which dynamic symbol has the lowest dynamic symbol
01026      table index in the GOT.  */
01027   g->global_gotsym = hsd.low;
01028 
01029   return TRUE;
01030 }
01031 
01032 /* Create an entry in an score ELF linker hash table.  */
01033 
01034 static struct bfd_hash_entry *
01035 score_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
01036                           struct bfd_hash_table *table,
01037                           const char *string)
01038 {
01039   struct score_elf_link_hash_entry *ret = (struct score_elf_link_hash_entry *)entry;
01040 
01041   /* Allocate the structure if it has not already been allocated by a subclass.  */
01042   if (ret == NULL)
01043     ret = bfd_hash_allocate (table, sizeof (struct score_elf_link_hash_entry));
01044   if (ret == NULL)
01045     return (struct bfd_hash_entry *)ret;
01046 
01047   /* Call the allocation method of the superclass.  */
01048   ret = ((struct score_elf_link_hash_entry *)
01049          _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *)ret, table, string));
01050 
01051   if (ret != NULL)
01052     {
01053       ret->possibly_dynamic_relocs = 0;
01054       ret->readonly_reloc = FALSE;
01055       ret->no_fn_stub = FALSE;
01056       ret->forced_local = FALSE;
01057     }
01058 
01059   return (struct bfd_hash_entry *)ret;
01060 }
01061 
01062 /* Returns the first relocation of type r_type found, beginning with
01063    RELOCATION.  RELEND is one-past-the-end of the relocation table.  */
01064 
01065 static const Elf_Internal_Rela *
01066 score_elf_next_relocation (bfd *abfd ATTRIBUTE_UNUSED, unsigned int r_type,
01067                         const Elf_Internal_Rela *relocation,
01068                         const Elf_Internal_Rela *relend)
01069 {
01070   while (relocation < relend)
01071     {
01072       if (ELF32_R_TYPE (relocation->r_info) == r_type)
01073        return relocation;
01074 
01075       ++relocation;
01076     }
01077 
01078   /* We didn't find it.  */
01079   bfd_set_error (bfd_error_bad_value);
01080   return NULL;
01081 }
01082 
01083 /* This function is called via qsort() to sort the dynamic relocation
01084    entries by increasing r_symndx value.  */
01085 
01086 static int
01087 score_elf_sort_dynamic_relocs (const void *arg1, const void *arg2)
01088 {
01089   Elf_Internal_Rela int_reloc1;
01090   Elf_Internal_Rela int_reloc2;
01091 
01092   bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg1, &int_reloc1);
01093   bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg2, &int_reloc2);
01094 
01095   return (ELF32_R_SYM (int_reloc1.r_info) - ELF32_R_SYM (int_reloc2.r_info));
01096 }
01097 
01098 /* Return whether a relocation is against a local symbol.  */
01099 
01100 static bfd_boolean
01101 score_elf_local_relocation_p (bfd *input_bfd,
01102                            const Elf_Internal_Rela *relocation,
01103                            asection **local_sections,
01104                            bfd_boolean check_forced)
01105 {
01106   unsigned long r_symndx;
01107   Elf_Internal_Shdr *symtab_hdr;
01108   struct score_elf_link_hash_entry *h;
01109   size_t extsymoff;
01110 
01111   r_symndx = ELF32_R_SYM (relocation->r_info);
01112   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
01113   extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
01114 
01115   if (r_symndx < extsymoff)
01116     return TRUE;
01117   if (elf_bad_symtab (input_bfd) && local_sections[r_symndx] != NULL)
01118     return TRUE;
01119 
01120   if (check_forced)
01121     {
01122       /* Look up the hash table to check whether the symbol was forced local.  */
01123       h = (struct score_elf_link_hash_entry *)
01124        elf_sym_hashes (input_bfd) [r_symndx - extsymoff];
01125       /* Find the real hash-table entry for this symbol.  */
01126       while (h->root.root.type == bfd_link_hash_indirect
01127             || h->root.root.type == bfd_link_hash_warning)
01128        h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
01129       if (h->root.forced_local)
01130        return TRUE;
01131     }
01132 
01133   return FALSE;
01134 }
01135 
01136 /* Returns the dynamic relocation section for DYNOBJ.  */
01137 
01138 static asection *
01139 score_elf_rel_dyn_section (bfd *dynobj, bfd_boolean create_p)
01140 {
01141   static const char dname[] = ".rel.dyn";
01142   asection *sreloc;
01143 
01144   sreloc = bfd_get_section_by_name (dynobj, dname);
01145   if (sreloc == NULL && create_p)
01146     {
01147       sreloc = bfd_make_section_with_flags (dynobj, dname,
01148                                             (SEC_ALLOC
01149                                              | SEC_LOAD
01150                                              | SEC_HAS_CONTENTS
01151                                              | SEC_IN_MEMORY
01152                                              | SEC_LINKER_CREATED
01153                                              | SEC_READONLY));
01154       if (sreloc == NULL
01155          || ! bfd_set_section_alignment (dynobj, sreloc,
01156                                      SCORE_ELF_LOG_FILE_ALIGN (dynobj)))
01157        return NULL;
01158     }
01159   return sreloc; 
01160 }
01161 
01162 static void
01163 score_elf_allocate_dynamic_relocations (bfd *abfd, unsigned int n)
01164 {
01165   asection *s;
01166 
01167   s = score_elf_rel_dyn_section (abfd, FALSE);
01168   BFD_ASSERT (s != NULL);
01169 
01170   if (s->size == 0)
01171     {
01172       /* Make room for a null element.  */
01173       s->size += SCORE_ELF_REL_SIZE (abfd);
01174       ++s->reloc_count;
01175     }
01176   s->size += n * SCORE_ELF_REL_SIZE (abfd);
01177 }
01178 
01179 /* Create a rel.dyn relocation for the dynamic linker to resolve.  REL
01180    is the original relocation, which is now being transformed into a
01181    dynamic relocation.  The ADDENDP is adjusted if necessary; the
01182    caller should store the result in place of the original addend.  */
01183 
01184 static bfd_boolean
01185 score_elf_create_dynamic_relocation (bfd *output_bfd,
01186                                  struct bfd_link_info *info,
01187                                  const Elf_Internal_Rela *rel,
01188                                  struct score_elf_link_hash_entry *h,
01189                                  bfd_vma symbol,
01190                                  bfd_vma *addendp, asection *input_section)
01191 {
01192   Elf_Internal_Rela outrel[3];
01193   asection *sreloc;
01194   bfd *dynobj;
01195   int r_type;
01196   long indx;
01197   bfd_boolean defined_p;
01198 
01199   r_type = ELF32_R_TYPE (rel->r_info);
01200   dynobj = elf_hash_table (info)->dynobj;
01201   sreloc = score_elf_rel_dyn_section (dynobj, FALSE);
01202   BFD_ASSERT (sreloc != NULL);
01203   BFD_ASSERT (sreloc->contents != NULL);
01204   BFD_ASSERT (sreloc->reloc_count * SCORE_ELF_REL_SIZE (output_bfd) < sreloc->size);
01205 
01206   outrel[0].r_offset =
01207     _bfd_elf_section_offset (output_bfd, info, input_section, rel[0].r_offset);
01208   outrel[1].r_offset =
01209     _bfd_elf_section_offset (output_bfd, info, input_section, rel[1].r_offset);
01210   outrel[2].r_offset =
01211     _bfd_elf_section_offset (output_bfd, info, input_section, rel[2].r_offset);
01212 
01213   if (outrel[0].r_offset == MINUS_ONE)
01214     /* The relocation field has been deleted.  */
01215     return TRUE;
01216 
01217   if (outrel[0].r_offset == MINUS_TWO)
01218     {
01219       /* The relocation field has been converted into a relative value of
01220         some sort.  Functions like _bfd_elf_write_section_eh_frame expect
01221         the field to be fully relocated, so add in the symbol's value.  */
01222       *addendp += symbol;
01223       return TRUE;
01224     }
01225 
01226   /* We must now calculate the dynamic symbol table index to use
01227      in the relocation.  */
01228   if (h != NULL
01229       && (! info->symbolic || !h->root.def_regular)
01230       /* h->root.dynindx may be -1 if this symbol was marked to
01231         become local.  */
01232       && h->root.dynindx != -1)
01233     {
01234       indx = h->root.dynindx;
01235        /* ??? glibc's ld.so just adds the final GOT entry to the
01236           relocation field.  It therefore treats relocs against
01237           defined symbols in the same way as relocs against
01238           undefined symbols.  */
01239       defined_p = FALSE;
01240     }
01241   else
01242     {
01243       indx = 0;
01244       defined_p = TRUE;
01245     }
01246 
01247   /* If the relocation was previously an absolute relocation and
01248      this symbol will not be referred to by the relocation, we must
01249      adjust it by the value we give it in the dynamic symbol table.
01250      Otherwise leave the job up to the dynamic linker.  */
01251   if (defined_p && r_type != R_SCORE_REL32)
01252     *addendp += symbol;
01253 
01254   /* The relocation is always an REL32 relocation because we don't
01255      know where the shared library will wind up at load-time.  */
01256   outrel[0].r_info = ELF32_R_INFO ((unsigned long) indx, R_SCORE_REL32);
01257 
01258   /* For strict adherence to the ABI specification, we should
01259      generate a R_SCORE_64 relocation record by itself before the
01260      _REL32/_64 record as well, such that the addend is read in as
01261      a 64-bit value (REL32 is a 32-bit relocation, after all).
01262      However, since none of the existing ELF64 SCORE dynamic
01263      loaders seems to care, we don't waste space with these
01264      artificial relocations.  If this turns out to not be true,
01265      score_elf_allocate_dynamic_relocations() should be tweaked so
01266      as to make room for a pair of dynamic relocations per
01267      invocation if ABI_64_P, and here we should generate an
01268      additional relocation record with R_SCORE_64 by itself for a
01269      NULL symbol before this relocation record.  */
01270   outrel[1].r_info = ELF32_R_INFO (0, R_SCORE_NONE);
01271   outrel[2].r_info = ELF32_R_INFO (0, R_SCORE_NONE);
01272 
01273   /* Adjust the output offset of the relocation to reference the
01274      correct location in the output file.  */
01275   outrel[0].r_offset += (input_section->output_section->vma
01276                       + input_section->output_offset);
01277   outrel[1].r_offset += (input_section->output_section->vma
01278                       + input_section->output_offset);
01279   outrel[2].r_offset += (input_section->output_section->vma
01280                       + input_section->output_offset);
01281 
01282   /* Put the relocation back out.  We have to use the special
01283      relocation outputter in the 64-bit case since the 64-bit
01284      relocation format is non-standard.  */
01285   bfd_elf32_swap_reloc_out
01286       (output_bfd, &outrel[0],
01287        (sreloc->contents + sreloc->reloc_count * sizeof (Elf32_External_Rel)));
01288 
01289   /* We've now added another relocation.  */
01290   ++sreloc->reloc_count;
01291 
01292   /* Make sure the output section is writable.  The dynamic linker
01293      will be writing to it.  */
01294   elf_section_data (input_section->output_section)->this_hdr.sh_flags |= SHF_WRITE;
01295 
01296   return TRUE;
01297 }
01298 
01299 static bfd_boolean
01300 score_elf_create_got_section (bfd *abfd,
01301                               struct bfd_link_info *info,
01302                            bfd_boolean maybe_exclude)
01303 {
01304   flagword flags;
01305   asection *s;
01306   struct elf_link_hash_entry *h;
01307   struct bfd_link_hash_entry *bh;
01308   struct score_got_info *g;
01309   bfd_size_type amt;
01310 
01311   /* This function may be called more than once.  */
01312   s = score_elf_got_section (abfd, TRUE);
01313   if (s)
01314     {
01315       if (! maybe_exclude)
01316        s->flags &= ~SEC_EXCLUDE;
01317       return TRUE;
01318     }
01319 
01320   flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
01321 
01322   if (maybe_exclude)
01323     flags |= SEC_EXCLUDE;
01324 
01325   /* We have to use an alignment of 2**4 here because this is hardcoded
01326      in the function stub generation and in the linker script.  */
01327   s = bfd_make_section_with_flags (abfd, ".got", flags);
01328    if (s == NULL
01329       || ! bfd_set_section_alignment (abfd, s, 4))
01330     return FALSE;
01331 
01332   /* Define the symbol _GLOBAL_OFFSET_TABLE_.  We don't do this in the
01333      linker script because we don't want to define the symbol if we
01334      are not creating a global offset table.  */
01335   bh = NULL;
01336   if (! (_bfd_generic_link_add_one_symbol
01337         (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s,
01338          0, NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
01339     return FALSE;
01340 
01341   h = (struct elf_link_hash_entry *) bh;
01342   h->non_elf = 0;
01343   h->def_regular = 1;
01344   h->type = STT_OBJECT;
01345 
01346   if (info->shared && ! bfd_elf_link_record_dynamic_symbol (info, h))
01347     return FALSE;
01348 
01349   amt = sizeof (struct score_got_info);
01350   g = bfd_alloc (abfd, amt);
01351   if (g == NULL)
01352     return FALSE;
01353 
01354   g->global_gotsym = NULL;
01355   g->global_gotno = 0;
01356 
01357   g->local_gotno = SCORE_RESERVED_GOTNO;
01358   g->assigned_gotno = SCORE_RESERVED_GOTNO;
01359   g->next = NULL;
01360 
01361   g->got_entries = htab_try_create (1, score_elf_got_entry_hash,
01362                                 score_elf_got_entry_eq, NULL);
01363   if (g->got_entries == NULL)
01364     return FALSE;
01365   score_elf_section_data (s)->u.got_info = g;
01366   score_elf_section_data (s)->elf.this_hdr.sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
01367 
01368   return TRUE;
01369 }
01370 
01371 /* Calculate the %high function.  */
01372 
01373 static bfd_vma
01374 score_elf_high (bfd_vma value)
01375 {
01376   return ((value + (bfd_vma) 0x8000) >> 16) & 0xffff;
01377 }
01378 
01379 /* Create a local GOT entry for VALUE.  Return the index of the entry,
01380    or -1 if it could not be created.  */
01381 
01382 static struct score_got_entry *
01383 score_elf_create_local_got_entry (bfd *abfd,
01384                                   bfd *ibfd ATTRIBUTE_UNUSED,
01385                               struct score_got_info *gg,
01386                               asection *sgot, bfd_vma value,
01387                               unsigned long r_symndx ATTRIBUTE_UNUSED,
01388                               struct score_elf_link_hash_entry *h ATTRIBUTE_UNUSED,
01389                               int r_type ATTRIBUTE_UNUSED)
01390 {
01391   struct score_got_entry entry, **loc;
01392   struct score_got_info *g;
01393 
01394   entry.abfd = NULL;
01395   entry.symndx = -1;
01396   entry.d.address = value;
01397 
01398   g = gg;
01399   loc = (struct score_got_entry **) htab_find_slot (g->got_entries, &entry, INSERT);
01400   if (*loc)
01401     return *loc;
01402 
01403   entry.gotidx = SCORE_ELF_GOT_SIZE (abfd) * g->assigned_gotno++;
01404 
01405   *loc = bfd_alloc (abfd, sizeof entry);
01406 
01407   if (! *loc)
01408     return NULL;
01409 
01410   memcpy (*loc, &entry, sizeof entry);
01411 
01412   if (g->assigned_gotno >= g->local_gotno)
01413     {
01414       (*loc)->gotidx = -1;
01415       /* We didn't allocate enough space in the GOT.  */
01416       (*_bfd_error_handler)
01417        (_("not enough GOT space for local GOT entries"));
01418       bfd_set_error (bfd_error_bad_value);
01419       return NULL;
01420     }
01421 
01422   bfd_put_32 (abfd, value, (sgot->contents + entry.gotidx));
01423 
01424   return *loc;
01425 }
01426 
01427 /* Find a GOT entry whose higher-order 16 bits are the same as those
01428    for value.  Return the index into the GOT for this entry.  */
01429 
01430 static bfd_vma
01431 score_elf_got16_entry (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
01432                     bfd_vma value, bfd_boolean external)
01433 {
01434   asection *sgot;
01435   struct score_got_info *g;
01436   struct score_got_entry *entry;
01437 
01438   if (!external)
01439     {
01440       /* Although the ABI says that it is "the high-order 16 bits" that we
01441         want, it is really the %high value.  The complete value is
01442         calculated with a `addiu' of a LO16 relocation, just as with a
01443         HI16/LO16 pair.  */
01444       value = score_elf_high (value) << 16;
01445     }
01446 
01447   g = score_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
01448 
01449   entry = score_elf_create_local_got_entry (abfd, ibfd, g, sgot, value, 0, NULL,
01450                                        R_SCORE_GOT15);
01451   if (entry)
01452     return entry->gotidx;
01453   else
01454     return MINUS_ONE;
01455 }
01456 
01457 static void
01458 _bfd_score_elf_hide_symbol (struct bfd_link_info *info,
01459                          struct elf_link_hash_entry *entry,
01460                          bfd_boolean force_local)
01461 {
01462   bfd *dynobj;
01463   asection *got;
01464   struct score_got_info *g;
01465   struct score_elf_link_hash_entry *h;
01466 
01467   h = (struct score_elf_link_hash_entry *) entry;
01468   if (h->forced_local)
01469     return;
01470   h->forced_local = TRUE;
01471 
01472   dynobj = elf_hash_table (info)->dynobj;
01473   if (dynobj != NULL && force_local)
01474     {
01475       got = score_elf_got_section (dynobj, FALSE);
01476       if (got == NULL)
01477        return;
01478       g = score_elf_section_data (got)->u.got_info;
01479 
01480       if (g->next)
01481        {
01482          struct score_got_entry e;
01483          struct score_got_info *gg = g;
01484 
01485          /* Since we're turning what used to be a global symbol into a
01486             local one, bump up the number of local entries of each GOT
01487             that had an entry for it.  This will automatically decrease
01488             the number of global entries, since global_gotno is actually
01489             the upper limit of global entries.  */
01490          e.abfd = dynobj;
01491          e.symndx = -1;
01492          e.d.h = h;
01493 
01494          for (g = g->next; g != gg; g = g->next)
01495            if (htab_find (g->got_entries, &e))
01496              {
01497               BFD_ASSERT (g->global_gotno > 0);
01498               g->local_gotno++;
01499               g->global_gotno--;
01500              }
01501 
01502          /* If this was a global symbol forced into the primary GOT, we
01503             no longer need an entry for it.  We can't release the entry
01504             at this point, but we must at least stop counting it as one
01505             of the symbols that required a forced got entry.  */
01506          if (h->root.got.offset == 2)
01507            {
01508              BFD_ASSERT (gg->assigned_gotno > 0);
01509              gg->assigned_gotno--;
01510            }
01511        }
01512       else if (g->global_gotno == 0 && g->global_gotsym == NULL)
01513        /* If we haven't got through GOT allocation yet, just bump up the
01514              number of local entries, as this symbol won't be counted as
01515              global.  */
01516        g->local_gotno++;
01517       else if (h->root.got.offset == 1)
01518        {
01519          /* If we're past non-multi-GOT allocation and this symbol had
01520                  been marked for a global got entry, give it a local entry
01521                 instead.  */
01522          BFD_ASSERT (g->global_gotno > 0);
01523          g->local_gotno++;
01524          g->global_gotno--;
01525        }
01526     }
01527 
01528   _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
01529 }
01530 
01531 /* If H is a symbol that needs a global GOT entry, but has a dynamic
01532    symbol table index lower than any we've seen to date, record it for
01533    posterity.  */
01534 
01535 static bfd_boolean
01536 score_elf_record_global_got_symbol (struct elf_link_hash_entry *h,
01537                                 bfd *abfd,
01538                                     struct bfd_link_info *info,
01539                                 struct score_got_info *g)
01540 {
01541   struct score_got_entry entry, **loc;
01542 
01543   /* A global symbol in the GOT must also be in the dynamic symbol table.  */
01544   if (h->dynindx == -1)
01545     {
01546       switch (ELF_ST_VISIBILITY (h->other))
01547        {
01548        case STV_INTERNAL:
01549        case STV_HIDDEN:
01550          _bfd_score_elf_hide_symbol (info, h, TRUE);
01551          break;
01552        }
01553       if (!bfd_elf_link_record_dynamic_symbol (info, h))
01554        return FALSE;
01555     }
01556 
01557   entry.abfd = abfd;
01558   entry.symndx = -1;
01559   entry.d.h = (struct score_elf_link_hash_entry *)h;
01560 
01561   loc = (struct score_got_entry **)htab_find_slot (g->got_entries, &entry, INSERT);
01562 
01563   /* If we've already marked this entry as needing GOT space, we don't
01564      need to do it again.  */
01565   if (*loc)
01566     return TRUE;
01567 
01568   *loc = bfd_alloc (abfd, sizeof entry);
01569   if (! *loc)
01570     return FALSE;
01571 
01572   entry.gotidx = -1;
01573 
01574   memcpy (*loc, &entry, sizeof (entry));
01575 
01576   if (h->got.offset != MINUS_ONE)
01577     return TRUE;
01578 
01579   /* By setting this to a value other than -1, we are indicating that
01580      there needs to be a GOT entry for H.  Avoid using zero, as the
01581      generic ELF copy_indirect_symbol tests for <= 0.  */
01582   h->got.offset = 1;
01583 
01584   return TRUE;
01585 }
01586 
01587 /* Reserve space in G for a GOT entry containing the value of symbol
01588    SYMNDX in input bfd ABDF, plus ADDEND.  */
01589 
01590 static bfd_boolean
01591 score_elf_record_local_got_symbol (bfd *abfd,
01592                                    long symndx,
01593                                    bfd_vma addend,
01594                                struct score_got_info *g)
01595 {
01596   struct score_got_entry entry, **loc;
01597 
01598   entry.abfd = abfd;
01599   entry.symndx = symndx;
01600   entry.d.addend = addend;
01601   loc = (struct score_got_entry **)htab_find_slot (g->got_entries, &entry, INSERT);
01602 
01603   if (*loc)
01604     return TRUE;
01605 
01606   entry.gotidx = g->local_gotno++;
01607 
01608   *loc = bfd_alloc (abfd, sizeof(entry));
01609   if (! *loc)
01610     return FALSE;
01611 
01612   memcpy (*loc, &entry, sizeof (entry));
01613 
01614   return TRUE;
01615 }
01616 
01617 /* Returns the GOT offset at which the indicated address can be found.
01618    If there is not yet a GOT entry for this value, create one.
01619    Returns -1 if no satisfactory GOT offset can be found.  */
01620 
01621 static bfd_vma
01622 score_elf_local_got_index (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
01623                        bfd_vma value, unsigned long r_symndx,
01624                        struct score_elf_link_hash_entry *h, int r_type)
01625 {
01626   asection *sgot;
01627   struct score_got_info *g;
01628   struct score_got_entry *entry;
01629 
01630   g = score_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
01631 
01632   entry = score_elf_create_local_got_entry (abfd, ibfd, g, sgot, value,
01633                                        r_symndx, h, r_type);
01634   if (!entry)
01635     return MINUS_ONE;
01636 
01637   else
01638     return entry->gotidx;
01639 }
01640 
01641 /* Returns the GOT index for the global symbol indicated by H.  */
01642 
01643 static bfd_vma
01644 score_elf_global_got_index (bfd *abfd, struct elf_link_hash_entry *h)
01645 {
01646   bfd_vma index;
01647   asection *sgot;
01648   struct score_got_info *g;
01649   long global_got_dynindx = 0;
01650 
01651   g = score_elf_got_info (abfd, &sgot);
01652   if (g->global_gotsym != NULL)
01653     global_got_dynindx = g->global_gotsym->dynindx;
01654 
01655   /* Once we determine the global GOT entry with the lowest dynamic
01656      symbol table index, we must put all dynamic symbols with greater
01657      indices into the GOT.  That makes it easy to calculate the GOT
01658      offset.  */
01659   BFD_ASSERT (h->dynindx >= global_got_dynindx);
01660   index = ((h->dynindx - global_got_dynindx + g->local_gotno) * SCORE_ELF_GOT_SIZE (abfd));
01661   BFD_ASSERT (index < sgot->size);
01662 
01663   return index;
01664 }
01665 
01666 /* Returns the offset for the entry at the INDEXth position in the GOT.  */
01667 
01668 static bfd_vma
01669 score_elf_got_offset_from_index (bfd *dynobj, bfd *output_bfd,
01670                              bfd *input_bfd ATTRIBUTE_UNUSED, bfd_vma index)
01671 {
01672   asection *sgot;
01673   bfd_vma gp;
01674   struct score_got_info *g;
01675 
01676   g = score_elf_got_info (dynobj, &sgot);
01677   gp = _bfd_get_gp_value (output_bfd);
01678 
01679   return sgot->output_section->vma + sgot->output_offset + index - gp;
01680 }
01681 
01682 /* Follow indirect and warning hash entries so that each got entry
01683    points to the final symbol definition.  P must point to a pointer
01684    to the hash table we're traversing.  Since this traversal may
01685    modify the hash table, we set this pointer to NULL to indicate
01686    we've made a potentially-destructive change to the hash table, so
01687    the traversal must be restarted.  */
01688 static int
01689 score_elf_resolve_final_got_entry (void **entryp, void *p)
01690 {
01691   struct score_got_entry *entry = (struct score_got_entry *)*entryp;
01692   htab_t got_entries = *(htab_t *)p;
01693 
01694   if (entry->abfd != NULL && entry->symndx == -1)
01695     {
01696       struct score_elf_link_hash_entry *h = entry->d.h;
01697 
01698       while (h->root.root.type == bfd_link_hash_indirect
01699             || h->root.root.type == bfd_link_hash_warning)
01700        h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
01701 
01702       if (entry->d.h == h)
01703        return 1;
01704 
01705       entry->d.h = h;
01706 
01707       /* If we can't find this entry with the new bfd hash, re-insert
01708         it, and get the traversal restarted.  */
01709       if (! htab_find (got_entries, entry))
01710        {
01711          htab_clear_slot (got_entries, entryp);
01712          entryp = htab_find_slot (got_entries, entry, INSERT);
01713          if (! *entryp)
01714            *entryp = entry;
01715          /* Abort the traversal, since the whole table may have
01716             moved, and leave it up to the parent to restart the
01717             process.  */
01718          *(htab_t *)p = NULL;
01719          return 0;
01720        }
01721       /* We might want to decrement the global_gotno count, but it's
01722         either too early or too late for that at this point.  */
01723     }
01724 
01725   return 1;
01726 }
01727 
01728 /* Turn indirect got entries in a got_entries table into their final locations.  */
01729 static void
01730 score_elf_resolve_final_got_entries (struct score_got_info *g)
01731 {
01732   htab_t got_entries;
01733 
01734   do
01735     {
01736       got_entries = g->got_entries;
01737 
01738       htab_traverse (got_entries,
01739                    score_elf_resolve_final_got_entry,
01740                    &got_entries);
01741     }
01742   while (got_entries == NULL);
01743 }
01744 
01745 /* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS. for -r  */
01746 
01747 static void
01748 score_elf_add_to_rel (bfd *abfd,
01749                     bfd_byte *address,
01750                     reloc_howto_type *howto,
01751                     bfd_signed_vma increment)
01752 {
01753   bfd_signed_vma addend;
01754   bfd_vma contents;
01755   unsigned long offset;
01756   unsigned long r_type = howto->type;
01757   unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
01758 
01759   contents = bfd_get_32 (abfd, address);
01760   /* Get the (signed) value from the instruction.  */
01761   addend = contents & howto->src_mask;
01762   if (addend & ((howto->src_mask + 1) >> 1))
01763     {
01764       bfd_signed_vma mask;
01765 
01766       mask = -1;
01767       mask &= ~howto->src_mask;
01768       addend |= mask;
01769     }
01770   /* Add in the increment, (which is a byte value).  */
01771   switch (r_type)
01772     {
01773     case R_SCORE_PC19:
01774       offset =
01775         (((contents & howto->src_mask) & 0x3ff0000) >> 6) | ((contents & howto->src_mask) & 0x3ff);
01776       offset += increment;
01777       contents =
01778         (contents & ~howto->
01779          src_mask) | (((offset << 6) & howto->src_mask) & 0x3ff0000) | (offset & 0x3ff);
01780       bfd_put_32 (abfd, contents, address);
01781       break;
01782     case R_SCORE_HI16:
01783       break;
01784     case R_SCORE_LO16:
01785       hi16_addend = bfd_get_32 (abfd, address - 4);
01786       hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
01787       offset = ((((contents >> 16) & 0x3) << 15) | (contents & 0x7fff)) >> 1;
01788       offset = (hi16_offset << 16) | (offset & 0xffff);
01789       uvalue = increment + offset;
01790       hi16_offset = (uvalue >> 16) << 1;
01791       hi16_value = (hi16_addend & (~(howto->dst_mask)))
01792         | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
01793       bfd_put_32 (abfd, hi16_value, address - 4);
01794       offset = (uvalue & 0xffff) << 1;
01795       contents = (contents & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
01796       bfd_put_32 (abfd, contents, address);
01797       break;
01798     case R_SCORE_24:
01799       offset =
01800         (((contents & howto->src_mask) >> 1) & 0x1ff8000) | ((contents & howto->src_mask) & 0x7fff);
01801       offset += increment;
01802       contents =
01803         (contents & ~howto->
01804          src_mask) | (((offset << 1) & howto->src_mask) & 0x3ff0000) | (offset & 0x7fff);
01805       bfd_put_32 (abfd, contents, address);
01806       break;
01807     case R_SCORE16_11:
01808 
01809       contents = bfd_get_16 (abfd, address);
01810       offset = contents & howto->src_mask;
01811       offset += increment;
01812       contents = (contents & ~howto->src_mask) | (offset & howto->src_mask);
01813       bfd_put_16 (abfd, contents, address);
01814 
01815       break;
01816     case R_SCORE16_PC8:
01817 
01818       contents = bfd_get_16 (abfd, address);
01819       offset = (contents & howto->src_mask) + ((increment >> 1) & 0xff);
01820       contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask);
01821       bfd_put_16 (abfd, contents, address);
01822 
01823       break;
01824     default:
01825       addend += increment;
01826       contents = (contents & ~howto->dst_mask) | (addend & howto->dst_mask);
01827       bfd_put_32 (abfd, contents, address);
01828       break;
01829     }
01830 }
01831 
01832 /* Perform a relocation as part of a final link.  */
01833 
01834 static bfd_reloc_status_type
01835 score_elf_final_link_relocate (reloc_howto_type *howto,
01836                             bfd *input_bfd,
01837                             bfd *output_bfd,
01838                             asection *input_section,
01839                             bfd_byte *contents,
01840                             Elf_Internal_Rela *rel,
01841                             Elf_Internal_Rela *relocs,
01842                             bfd_vma symbol,
01843                             struct bfd_link_info *info,
01844                             const char *sym_name ATTRIBUTE_UNUSED,
01845                             int sym_flags ATTRIBUTE_UNUSED,
01846                             struct score_elf_link_hash_entry *h,
01847                               asection **local_sections,
01848                                bfd_boolean gp_disp_p)
01849 {
01850   unsigned long r_type;
01851   unsigned long r_symndx;
01852   bfd_byte *hit_data = contents + rel->r_offset;
01853   bfd_vma addend;
01854   /* The final GP value to be used for the relocatable, executable, or
01855      shared object file being produced.  */
01856   bfd_vma gp = MINUS_ONE;
01857   /* The place (section offset or address) of the storage unit being relocated.  */
01858   bfd_vma rel_addr;
01859   /* The value of GP used to create the relocatable object.  */
01860   bfd_vma gp0 = MINUS_ONE;
01861   /* The offset into the global offset table at which the address of the relocation entry
01862      symbol, adjusted by the addend, resides during execution.  */
01863   bfd_vma g = MINUS_ONE;
01864   /* TRUE if the symbol referred to by this relocation is a local symbol.  */
01865   bfd_boolean local_p;
01866   /* The eventual value we will relocate.  */
01867   bfd_vma value = symbol;
01868   unsigned long hi16_addend, hi16_offset, hi16_value, uvalue, offset, abs_value = 0;
01869 
01870   if (elf_gp (output_bfd) == 0)
01871     {
01872       struct bfd_link_hash_entry *bh;
01873       asection *o;
01874 
01875       bh = bfd_link_hash_lookup (info->hash, "_gp", 0, 0, 1);
01876       if (bh != (struct bfd_link_hash_entry *)NULL && bh->type == bfd_link_hash_defined)
01877         elf_gp (output_bfd) = (bh->u.def.value
01878                                + bh->u.def.section->output_section->vma
01879                                + bh->u.def.section->output_offset);
01880       else if (info->relocatable)
01881         {
01882           bfd_vma lo = -1;
01883 
01884           /* Find the GP-relative section with the lowest offset.  */
01885           for (o = output_bfd->sections; o != (asection *) NULL; o = o->next)
01886             if (o->vma < lo)
01887               lo = o->vma;
01888           /* And calculate GP relative to that.  */
01889           elf_gp (output_bfd) = lo + ELF_SCORE_GP_OFFSET (input_bfd);
01890         }
01891       else
01892         {
01893           /* If the relocate_section function needs to do a reloc
01894              involving the GP value, it should make a reloc_dangerous
01895              callback to warn that GP is not defined.  */
01896         }
01897     }
01898 
01899   /* Parse the relocation.  */
01900   r_symndx = ELF32_R_SYM (rel->r_info);
01901   r_type = ELF32_R_TYPE (rel->r_info);
01902   rel_addr = (input_section->output_section->vma + input_section->output_offset + rel->r_offset);
01903   local_p = score_elf_local_relocation_p (input_bfd, rel, local_sections, TRUE);
01904 
01905   if (r_type == R_SCORE_GOT15)
01906     {
01907       const Elf_Internal_Rela *relend;
01908       const Elf_Internal_Rela *lo16_rel;
01909       const struct elf_backend_data *bed;
01910       bfd_vma lo_value = 0;
01911 
01912       bed = get_elf_backend_data (output_bfd);
01913       relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
01914       lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
01915       if ((local_p) && (lo16_rel != NULL))
01916        {
01917          bfd_vma tmp = 0;
01918          tmp = bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
01919          lo_value = (((tmp >> 16) & 0x3) << 14) | ((tmp & 0x7fff) >> 1);
01920        }
01921       addend = lo_value;
01922     }
01923   else
01924     {
01925       addend = (bfd_get_32 (input_bfd, hit_data) >> howto->bitpos) & howto->src_mask;
01926     }
01927 
01928   /* If we haven't already determined the GOT offset, or the GP value,
01929      and we're going to need it, get it now.  */
01930   switch (r_type)
01931     {
01932     case R_SCORE_CALL15:
01933     case R_SCORE_GOT15:
01934       if (!local_p)
01935         {
01936           g = score_elf_global_got_index (elf_hash_table (info)->dynobj,
01937                                           (struct elf_link_hash_entry *) h);
01938           if ((! elf_hash_table(info)->dynamic_sections_created
01939                || (info->shared
01940                    && (info->symbolic || h->root.dynindx == -1)
01941                    && h->root.def_regular)))
01942             {
01943               /* This is a static link or a -Bsymbolic link.  The
01944                  symbol is defined locally, or was forced to be local.
01945                  We must initialize this entry in the GOT.  */
01946               bfd *tmpbfd = elf_hash_table (info)->dynobj;
01947               asection *sgot = score_elf_got_section (tmpbfd, FALSE);
01948               bfd_put_32 (tmpbfd, value, sgot->contents + g);
01949             }
01950         }
01951       else if (r_type == R_SCORE_GOT15 || r_type == R_SCORE_CALL15)
01952         {
01953          /* There's no need to create a local GOT entry here; the
01954             calculation for a local GOT15 entry does not involve G.  */
01955          ;
01956        }
01957       else
01958         {
01959          g = score_elf_local_got_index (output_bfd, input_bfd, info,
01960                                          symbol + addend, r_symndx, h, r_type);
01961          if (g == MINUS_ONE)
01962            return bfd_reloc_outofrange;
01963         }
01964 
01965       /* Convert GOT indices to actual offsets.  */
01966       g = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
01967                                       output_bfd, input_bfd, g);
01968       break;
01969 
01970     case R_SCORE_HI16:
01971     case R_SCORE_LO16:
01972     case R_SCORE_GPREL32:
01973       gp0 = _bfd_get_gp_value (input_bfd);
01974       gp = _bfd_get_gp_value (output_bfd);
01975       break;
01976 
01977     case R_SCORE_GP15:
01978       gp = _bfd_get_gp_value (output_bfd);
01979 
01980     default:
01981       break;
01982     }
01983 
01984   switch (r_type)
01985     {
01986     case R_SCORE_NONE:
01987       return bfd_reloc_ok;
01988 
01989     case R_SCORE_ABS32:
01990     case R_SCORE_REL32:
01991       if ((info->shared
01992           || (elf_hash_table (info)->dynamic_sections_created
01993               && h != NULL
01994               && h->root.def_dynamic
01995               && !h->root.def_regular))
01996           && r_symndx != 0
01997           && (input_section->flags & SEC_ALLOC) != 0)
01998        {
01999          /* If we're creating a shared library, or this relocation is against a symbol
02000              in a shared library, then we can't know where the symbol will end up.
02001              So, we create a relocation record in the output, and leave the job up
02002              to the dynamic linker.  */
02003          value = addend;
02004          if (!score_elf_create_dynamic_relocation (output_bfd, info, rel, h,
02005                                               symbol, &value,
02006                                               input_section))
02007            return bfd_reloc_undefined;
02008        }
02009       else
02010        {
02011          if (r_type != R_SCORE_REL32)
02012            value = symbol + addend;
02013          else
02014            value = addend;
02015        }
02016       value &= howto->dst_mask;
02017       bfd_put_32 (input_bfd, value, hit_data);
02018       return bfd_reloc_ok;
02019 
02020     case R_SCORE_ABS16:
02021       value += addend;
02022       if ((long)value > 0x7fff || (long)value < -0x8000)
02023         return bfd_reloc_overflow;
02024       bfd_put_16 (input_bfd, value, hit_data);
02025       return bfd_reloc_ok;
02026 
02027     case R_SCORE_24:
02028       addend = bfd_get_32 (input_bfd, hit_data);
02029       offset = (((addend & howto->src_mask) >> 1) & 0x1ff8000) | ((addend & howto->src_mask) & 0x7fff);
02030       if ((offset & 0x1000000) != 0)
02031         offset |= 0xfe000000;
02032       value += offset;
02033       addend = (addend & ~howto->src_mask)
02034                 | (((value << 1) & howto->src_mask) & 0x3ff0000) | (value & 0x7fff);
02035       bfd_put_32 (input_bfd, addend, hit_data);
02036       return bfd_reloc_ok;
02037 
02038     case R_SCORE_PC19:
02039       addend = bfd_get_32 (input_bfd, hit_data);
02040       offset = (((addend & howto->src_mask) & 0x3ff0000) >> 6) | ((addend & howto->src_mask) & 0x3ff);
02041       if ((offset & 0x80000) != 0)
02042         offset |= 0xfff00000;
02043       abs_value = value = value - rel_addr + offset;
02044       /* exceed 20 bit : overflow.  */
02045       if ((abs_value & 0x80000000) == 0x80000000)
02046         abs_value = 0xffffffff - value + 1;
02047       if ((abs_value & 0xfff80000) != 0)
02048         return bfd_reloc_overflow;
02049       addend = (addend & ~howto->src_mask)
02050                 | (((value << 6) & howto->src_mask) & 0x3ff0000) | (value & 0x3ff);
02051       bfd_put_32 (input_bfd, addend, hit_data);
02052       return bfd_reloc_ok;
02053 
02054     case R_SCORE16_11:
02055       addend = bfd_get_16 (input_bfd, hit_data);
02056       offset = addend & howto->src_mask;
02057       if ((offset & 0x800) != 0)        /* Offset is negative.  */
02058         offset |= 0xfffff000;
02059       value += offset;
02060       addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
02061       bfd_put_16 (input_bfd, addend, hit_data);
02062       return bfd_reloc_ok;
02063 
02064     case R_SCORE16_PC8:
02065       addend = bfd_get_16 (input_bfd, hit_data);
02066       offset = (addend & howto->src_mask) << 1;
02067       if ((offset & 0x100) != 0)        /* Offset is negative.  */
02068         offset |= 0xfffffe00;
02069       abs_value = value = value - rel_addr + offset;
02070       /* Sign bit + exceed 9 bit.  */
02071       if (((value & 0xffffff00) != 0) && ((value & 0xffffff00) != 0xffffff00))
02072         return bfd_reloc_overflow;
02073       value >>= 1;
02074       addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
02075       bfd_put_16 (input_bfd, addend, hit_data);
02076       return bfd_reloc_ok;
02077 
02078     case R_SCORE_HI16:
02079       return bfd_reloc_ok;
02080 
02081     case R_SCORE_LO16:
02082       hi16_addend = bfd_get_32 (input_bfd, hit_data - 4);
02083       hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
02084       addend = bfd_get_32 (input_bfd, hit_data);
02085       offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
02086       offset = (hi16_offset << 16) | (offset & 0xffff);
02087 
02088       if (!gp_disp_p)
02089        uvalue = value + offset;
02090       else
02091        uvalue = offset + gp - rel_addr + 4;
02092 
02093       hi16_offset = (uvalue >> 16) << 1;
02094       hi16_value = (hi16_addend & (~(howto->dst_mask)))
02095                         | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
02096       bfd_put_32 (input_bfd, hi16_value, hit_data - 4);
02097       offset = (uvalue & 0xffff) << 1;
02098       value = (addend & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
02099       bfd_put_32 (input_bfd, value, hit_data);
02100       return bfd_reloc_ok;
02101 
02102     case R_SCORE_GP15:
02103       addend = bfd_get_32 (input_bfd, hit_data);
02104       offset = addend & 0x7fff;
02105       if ((offset & 0x4000) == 0x4000)
02106         offset |= 0xffffc000;
02107       value = value + offset - gp;
02108       if (((value & 0xffffc000) != 0) && ((value & 0xffffc000) != 0xffffc000))
02109         return bfd_reloc_overflow;
02110       value = (addend & ~howto->src_mask) | (value & howto->src_mask);
02111       bfd_put_32 (input_bfd, value, hit_data);
02112       return bfd_reloc_ok;
02113 
02114     case R_SCORE_GOT15:
02115     case R_SCORE_CALL15:
02116       if (local_p)
02117        {
02118          bfd_boolean forced;
02119 
02120          /* The special case is when the symbol is forced to be local.  We need the
02121              full address in the GOT since no R_SCORE_GOT_LO16 relocation follows.  */
02122          forced = ! score_elf_local_relocation_p (input_bfd, rel,
02123                                              local_sections, FALSE);
02124          value = score_elf_got16_entry (output_bfd, input_bfd, info,
02125                                     symbol + addend, forced);
02126          if (value == MINUS_ONE)
02127            return bfd_reloc_outofrange;
02128          value = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
02129                                              output_bfd, input_bfd, value);
02130        }
02131       else
02132        {
02133          value = g;
02134        }
02135 
02136       if ((long) value > 0x3fff || (long) value < -0x4000)
02137         return bfd_reloc_overflow;
02138 
02139       addend = bfd_get_32 (input_bfd, hit_data);
02140       value = (addend & ~howto->dst_mask) | (value & howto->dst_mask);
02141       bfd_put_32 (input_bfd, value, hit_data);
02142       return bfd_reloc_ok;
02143 
02144     case R_SCORE_GPREL32:
02145       value = (addend + symbol - gp);
02146       value &= howto->dst_mask;
02147       bfd_put_32 (input_bfd, value, hit_data);
02148       return bfd_reloc_ok;
02149 
02150     case R_SCORE_GOT_LO16:
02151       addend = bfd_get_32 (input_bfd, hit_data);
02152       value = (((addend >> 16) & 0x3) << 14) | ((addend & 0x7fff) >> 1);
02153       value += symbol;
02154       value = (addend & (~(howto->dst_mask))) | ((value & 0x3fff) << 1)  
02155                | (((value >> 14) & 0x3) << 16);
02156 
02157       bfd_put_32 (input_bfd, value, hit_data);
02158       return bfd_reloc_ok;
02159 
02160     case R_SCORE_DUMMY_HI16:
02161       return bfd_reloc_ok;
02162 
02163     case R_SCORE_GNU_VTINHERIT:
02164     case R_SCORE_GNU_VTENTRY:
02165       /* We don't do anything with these at present.  */
02166       return bfd_reloc_continue;
02167 
02168     default:
02169       return bfd_reloc_notsupported;
02170     }
02171 }
02172 
02173 /* Score backend functions.  */
02174 
02175 static void
02176 _bfd_score_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
02177                        arelent *bfd_reloc,
02178                        Elf_Internal_Rela *elf_reloc)
02179 {
02180   unsigned int r_type;
02181 
02182   r_type = ELF32_R_TYPE (elf_reloc->r_info);
02183   if (r_type >= NUM_ELEM (elf32_score_howto_table))
02184     bfd_reloc->howto = NULL;
02185   else
02186     bfd_reloc->howto = &elf32_score_howto_table[r_type];
02187 }
02188 
02189 /* Relocate an score ELF section.  */
02190 
02191 static bfd_boolean
02192 _bfd_score_elf_relocate_section (bfd *output_bfd,
02193                               struct bfd_link_info *info,
02194                               bfd *input_bfd,
02195                               asection *input_section,
02196                               bfd_byte *contents,
02197                               Elf_Internal_Rela *relocs,
02198                               Elf_Internal_Sym *local_syms,
02199                               asection **local_sections)
02200 {
02201   Elf_Internal_Shdr *symtab_hdr;
02202   struct elf_link_hash_entry **sym_hashes;
02203   Elf_Internal_Rela *rel;
02204   Elf_Internal_Rela *relend;
02205   const char *name;
02206   unsigned long offset;
02207   unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
02208   size_t extsymoff;
02209   bfd_boolean gp_disp_p = FALSE;
02210 
02211   /* Sort dynsym.  */
02212   if (elf_hash_table (info)->dynamic_sections_created)
02213     {
02214       bfd_size_type dynsecsymcount = 0;
02215       if (info->shared)
02216        {
02217          asection * p;
02218          const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
02219 
02220          for (p = output_bfd->sections; p ; p = p->next)
02221            if ((p->flags & SEC_EXCLUDE) == 0
02222               && (p->flags & SEC_ALLOC) != 0
02223               && !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p))
02224              ++ dynsecsymcount;
02225        }
02226 
02227       if (!score_elf_sort_hash_table (info, dynsecsymcount + 1))
02228        return FALSE;
02229     }
02230 
02231   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
02232   extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
02233   sym_hashes = elf_sym_hashes (input_bfd);
02234   rel = relocs;
02235   relend = relocs + input_section->reloc_count;
02236   for (; rel < relend; rel++)
02237     {
02238       int r_type;
02239       reloc_howto_type *howto;
02240       unsigned long r_symndx;
02241       Elf_Internal_Sym *sym;
02242       asection *sec;
02243       struct score_elf_link_hash_entry *h;
02244       bfd_vma relocation = 0;
02245       bfd_reloc_status_type r;
02246       arelent bfd_reloc;
02247 
02248       r_symndx = ELF32_R_SYM (rel->r_info);
02249       r_type = ELF32_R_TYPE (rel->r_info);
02250 
02251       _bfd_score_info_to_howto (input_bfd, &bfd_reloc, (Elf_Internal_Rela *) rel);
02252       howto = bfd_reloc.howto;
02253 
02254       h = NULL;
02255       sym = NULL;
02256       sec = NULL;
02257 
02258       if (r_symndx < extsymoff)
02259         {
02260           sym = local_syms + r_symndx;
02261           sec = local_sections[r_symndx];
02262           relocation = (sec->output_section->vma
02263                      + sec->output_offset
02264                      + sym->st_value);
02265           name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, sec);
02266 
02267           if (!info->relocatable
02268              && (sec->flags & SEC_MERGE) != 0
02269              && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
02270             {
02271               asection *msec;
02272               bfd_vma addend, value;
02273 
02274               switch (r_type)
02275                 {
02276                 case R_SCORE_HI16:
02277                   break;
02278                 case R_SCORE_LO16:
02279                   hi16_addend = bfd_get_32 (input_bfd, contents + rel->r_offset - 4);
02280                   hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
02281                   value = bfd_get_32 (input_bfd, contents + rel->r_offset);
02282                   offset = ((((value >> 16) & 0x3) << 15) | (value & 0x7fff)) >> 1;
02283                   addend = (hi16_offset << 16) | (offset & 0xffff);
02284                   msec = sec;
02285                   addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend);
02286                   addend -= relocation;
02287                   addend += msec->output_section->vma + msec->output_offset;
02288                   uvalue = addend;
02289                   hi16_offset = (uvalue >> 16) << 1;
02290                   hi16_value = (hi16_addend & (~(howto->dst_mask)))
02291                     | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
02292                   bfd_put_32 (input_bfd, hi16_value, contents + rel->r_offset - 4);
02293                   offset = (uvalue & 0xffff) << 1;
02294                   value = (value & (~(howto->dst_mask)))
02295                     | (offset & 0x7fff) | ((offset << 1) & 0x30000);
02296                   bfd_put_32 (input_bfd, value, contents + rel->r_offset);
02297                   break;
02298                 case R_SCORE_GOT_LO16:
02299                   value = bfd_get_32 (input_bfd, contents + rel->r_offset);
02300                   addend = (((value >> 16) & 0x3) << 14) | ((value & 0x7fff) >> 1);
02301                   msec = sec;
02302                   addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
02303                   addend += msec->output_section->vma + msec->output_offset;
02304                   value = (value & (~(howto->dst_mask))) | ((addend & 0x3fff) << 1)
02305                            | (((addend >> 14) & 0x3) << 16);
02306 
02307                   bfd_put_32 (input_bfd, value, contents + rel->r_offset);
02308                   break;
02309                 default:
02310                   value = bfd_get_32 (input_bfd, contents + rel->r_offset);
02311                   /* Get the (signed) value from the instruction.  */
02312                   addend = value & howto->src_mask;
02313                   if (addend & ((howto->src_mask + 1) >> 1))
02314                     {
02315                       bfd_signed_vma mask;
02316 
02317                       mask = -1;
02318                       mask &= ~howto->src_mask;
02319                       addend |= mask;
02320                     }
02321                   msec = sec;
02322                   addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
02323                   addend += msec->output_section->vma + msec->output_offset;
02324                   value = (value & ~howto->dst_mask) | (addend & howto->dst_mask);
02325                   bfd_put_32 (input_bfd, value, contents + rel->r_offset);
02326                   break;
02327                 }
02328             }
02329         }
02330       else
02331         {
02332          /* For global symbols we look up the symbol in the hash-table.  */
02333          h = ((struct score_elf_link_hash_entry *)
02334               elf_sym_hashes (input_bfd) [r_symndx - extsymoff]);
02335          /* Find the real hash-table entry for this symbol.  */
02336          while (h->root.root.type == bfd_link_hash_indirect
02337                || h->root.root.type == bfd_link_hash_warning)
02338            h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
02339 
02340          /* Record the name of this symbol, for our caller.  */
02341          name = h->root.root.root.string;
02342 
02343          /* See if this is the special GP_DISP_LABEL symbol.  Note that such a
02344             symbol must always be a global symbol.  */
02345          if (strcmp (name, GP_DISP_LABEL) == 0)
02346            {
02347              /* Relocations against GP_DISP_LABEL are permitted only with
02348                R_SCORE_HI16 and R_SCORE_LO16 relocations.  */
02349              if (r_type != R_SCORE_HI16 && r_type != R_SCORE_LO16)
02350               return bfd_reloc_notsupported;
02351 
02352              gp_disp_p = TRUE;
02353            }
02354 
02355          /* If this symbol is defined, calculate its address.  Note that
02356              GP_DISP_LABEL is a magic symbol, always implicitly defined by the
02357              linker, so it's inappropriate to check to see whether or not
02358              its defined.  */
02359          else if ((h->root.root.type == bfd_link_hash_defined
02360                   || h->root.root.type == bfd_link_hash_defweak)
02361                  && h->root.root.u.def.section)
02362            {
02363              sec = h->root.root.u.def.section;
02364              if (sec->output_section)
02365               relocation = (h->root.root.u.def.value
02366                            + sec->output_section->vma
02367                            + sec->output_offset);
02368              else
02369               {
02370                 relocation = h->root.root.u.def.value;
02371               }
02372            }
02373          else if (h->root.root.type == bfd_link_hash_undefweak)
02374            /* We allow relocations against undefined weak symbols, giving
02375               it the value zero, so that you can undefined weak functions
02376               and check to see if they exist by looking at their addresses.  */
02377            relocation = 0;
02378          else if (info->unresolved_syms_in_objects == RM_IGNORE
02379                  && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
02380            relocation = 0;
02381          else if (strcmp (name, "_DYNAMIC_LINK") == 0)
02382            {
02383              /* If this is a dynamic link, we should have created a _DYNAMIC_LINK symbol
02384                 in _bfd_score_elf_create_dynamic_sections.  Otherwise, we should define
02385                  the symbol with a value of 0.  */
02386              BFD_ASSERT (! info->shared);
02387              BFD_ASSERT (bfd_get_section_by_name (output_bfd, ".dynamic") == NULL);
02388              relocation = 0;
02389            }
02390          else if (!info->relocatable)
02391            {
02392              if (! ((*info->callbacks->undefined_symbol)
02393                    (info, h->root.root.root.string, input_bfd,
02394                     input_section, rel->r_offset,
02395                     (info->unresolved_syms_in_objects == RM_GENERATE_ERROR)
02396                     || ELF_ST_VISIBILITY (h->root.other))))
02397               return bfd_reloc_undefined;
02398              relocation = 0;
02399            }
02400         }
02401 
02402       if (sec != NULL && elf_discarded_section (sec))
02403        {
02404          /* For relocs against symbols from removed linkonce sections,
02405             or sections discarded by a linker script, we just want the
02406             section contents zeroed.  Avoid any special processing.  */
02407          _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
02408          rel->r_info = 0;
02409          rel->r_addend = 0;
02410          continue;
02411        }
02412 
02413       if (info->relocatable)
02414         {
02415           /* This is a relocatable link.  We don't have to change
02416              anything, unless the reloc is against a section symbol,
02417              in which case we have to adjust according to where the
02418              section symbol winds up in the output section.  */
02419           if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
02420            score_elf_add_to_rel (input_bfd, contents + rel->r_offset,
02421                               howto, (bfd_signed_vma) sec->output_offset);
02422           continue;
02423         }
02424 
02425       r = score_elf_final_link_relocate (howto, input_bfd, output_bfd,
02426                                          input_section, contents, rel, relocs,
02427                                          relocation, info, name,
02428                                          (h ? ELF_ST_TYPE ((unsigned int)h->root.root.type) :
02429                                     ELF_ST_TYPE ((unsigned int)sym->st_info)), h, local_sections,
02430                                          gp_disp_p);
02431 
02432       if (r != bfd_reloc_ok)
02433         {
02434           const char *msg = (const char *)0;
02435 
02436           switch (r)
02437             {
02438             case bfd_reloc_overflow:
02439               /* If the overflowing reloc was to an undefined symbol,
02440                  we have already printed one error message and there
02441                  is no point complaining again.  */
02442               if (((!h) || (h->root.root.type != bfd_link_hash_undefined))
02443                   && (!((*info->callbacks->reloc_overflow)
02444                         (info, NULL, name, howto->name, (bfd_vma) 0,
02445                          input_bfd, input_section, rel->r_offset))))
02446                 return FALSE;
02447               break;
02448             case bfd_reloc_undefined:
02449               if (!((*info->callbacks->undefined_symbol)
02450                     (info, name, input_bfd, input_section, rel->r_offset, TRUE)))
02451                 return FALSE;
02452               break;
02453 
02454             case bfd_reloc_outofrange:
02455               msg = _("internal error: out of range error");
02456               goto common_error;
02457 
02458             case bfd_reloc_notsupported:
02459               msg = _("internal error: unsupported relocation error");
02460               goto common_error;
02461 
02462             case bfd_reloc_dangerous:
02463               msg = _("internal error: dangerous error");
02464               goto common_error;
02465 
02466             default:
02467               msg = _("internal error: unknown error");
02468               /* fall through */
02469 
02470             common_error:
02471               if (!((*info->callbacks->warning)
02472                     (info, msg, name, input_bfd, input_section, rel->r_offset)))
02473                 return FALSE;
02474               break;
02475             }
02476         }
02477     }
02478 
02479   return TRUE;
02480 }
02481 
02482 /* Look through the relocs for a section during the first phase, and
02483    allocate space in the global offset table.  */
02484 
02485 static bfd_boolean
02486 _bfd_score_elf_check_relocs (bfd *abfd,
02487                           struct bfd_link_info *info,
02488                           asection *sec,
02489                           const Elf_Internal_Rela *relocs)
02490 {
02491   const char *name;
02492   bfd *dynobj;
02493   Elf_Internal_Shdr *symtab_hdr;
02494   struct elf_link_hash_entry **sym_hashes;
02495   struct score_got_info *g;
02496   size_t extsymoff;
02497   const Elf_Internal_Rela *rel;
02498   const Elf_Internal_Rela *rel_end;
02499   asection *sgot;
02500   asection *sreloc;
02501   const struct elf_backend_data *bed;
02502 
02503   if (info->relocatable)
02504     return TRUE;
02505 
02506   dynobj = elf_hash_table (info)->dynobj;
02507   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
02508   sym_hashes = elf_sym_hashes (abfd);
02509   extsymoff = (elf_bad_symtab (abfd)) ? 0 : symtab_hdr->sh_info;
02510 
02511   name = bfd_get_section_name (abfd, sec);
02512 
02513   if (dynobj == NULL)
02514     {
02515       sgot = NULL;
02516       g = NULL;
02517     }
02518   else
02519     {
02520       sgot = score_elf_got_section (dynobj, FALSE);
02521       if (sgot == NULL)
02522         g = NULL;
02523       else
02524         {
02525           BFD_ASSERT (score_elf_section_data (sgot) != NULL);
02526           g = score_elf_section_data (sgot)->u.got_info;
02527           BFD_ASSERT (g != NULL);
02528         }
02529     }
02530 
02531   sreloc = NULL;
02532   bed = get_elf_backend_data (abfd);
02533   rel_end = relocs + sec->reloc_count * bed->s->int_rels_per_ext_rel;
02534   for (rel = relocs; rel < rel_end; ++rel)
02535     {
02536       unsigned long r_symndx;
02537       unsigned int r_type;
02538       struct elf_link_hash_entry *h;
02539 
02540       r_symndx = ELF32_R_SYM (rel->r_info);
02541       r_type = ELF32_R_TYPE (rel->r_info);
02542 
02543       if (r_symndx < extsymoff)
02544        {
02545           h = NULL;
02546        }
02547       else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr))
02548         {
02549           (*_bfd_error_handler) (_("%s: Malformed reloc detected for section %s"), abfd, name);
02550           bfd_set_error (bfd_error_bad_value);
02551           return FALSE;
02552         }
02553       else
02554         {
02555           h = sym_hashes[r_symndx - extsymoff];
02556 
02557           /* This may be an indirect symbol created because of a version.  */
02558           if (h != NULL)
02559             {
02560               while (h->root.type == bfd_link_hash_indirect)
02561                 h = (struct elf_link_hash_entry *)h->root.u.i.link;
02562             }
02563         }
02564 
02565       /* Some relocs require a global offset table.  */
02566       if (dynobj == NULL || sgot == NULL)
02567         {
02568           switch (r_type)
02569             {
02570             case R_SCORE_GOT15:
02571             case R_SCORE_CALL15:
02572               if (dynobj == NULL)
02573                 elf_hash_table (info)->dynobj = dynobj = abfd;
02574               if (!score_elf_create_got_section (dynobj, info, FALSE))
02575                 return FALSE;
02576               g = score_elf_got_info (dynobj, &sgot);
02577               break;
02578             case R_SCORE_ABS32:
02579             case R_SCORE_REL32:
02580               if (dynobj == NULL && (info->shared || h != NULL) && (sec->flags & SEC_ALLOC) != 0)
02581                 elf_hash_table (info)->dynobj = dynobj = abfd;
02582               break;
02583             default:
02584               break;
02585             }
02586         }
02587 
02588       if (!h && (r_type == R_SCORE_GOT_LO16))
02589         {
02590          if (! score_elf_record_local_got_symbol (abfd, r_symndx, rel->r_addend, g))
02591            return FALSE;
02592         }
02593 
02594       switch (r_type)
02595         {
02596         case R_SCORE_CALL15:
02597          if (h == NULL)
02598            {
02599              (*_bfd_error_handler)
02600               (_("%B: CALL15 reloc at 0x%lx not against global symbol"),
02601                abfd, (unsigned long) rel->r_offset);
02602              bfd_set_error (bfd_error_bad_value);
02603              return FALSE;
02604            }
02605          else
02606            {
02607              /* This symbol requires a global offset table entry.  */
02608              if (! score_elf_record_global_got_symbol (h, abfd, info, g))
02609               return FALSE;
02610 
02611              /* We need a stub, not a plt entry for the undefined function.  But we record
02612                  it as if it needs plt.  See _bfd_elf_adjust_dynamic_symbol.  */
02613              h->needs_plt = 1;
02614              h->type = STT_FUNC;
02615            }
02616           break;
02617        case R_SCORE_GOT15:
02618          if (h && ! score_elf_record_global_got_symbol (h, abfd, info, g))
02619            return FALSE;
02620          break;
02621         case R_SCORE_ABS32:
02622         case R_SCORE_REL32:
02623          if ((info->shared || h != NULL) && (sec->flags & SEC_ALLOC) != 0)
02624            {
02625              if (sreloc == NULL)
02626               {
02627                 sreloc = score_elf_rel_dyn_section (dynobj, TRUE);
02628                 if (sreloc == NULL)
02629                   return FALSE;
02630               }
02631 #define SCORE_READONLY_SECTION (SEC_ALLOC | SEC_LOAD | SEC_READONLY)
02632              if (info->shared)
02633               {
02634                 /* When creating a shared object, we must copy these reloc types into
02635                      the output file as R_SCORE_REL32 relocs.  We make room for this reloc
02636                      in the .rel.dyn reloc section.  */
02637                 score_elf_allocate_dynamic_relocations (dynobj, 1);
02638                 if ((sec->flags & SCORE_READONLY_SECTION)
02639                     == SCORE_READONLY_SECTION)
02640                   /* We tell the dynamic linker that there are
02641                      relocations against the text segment.  */
02642                   info->flags |= DF_TEXTREL;
02643               }
02644              else
02645               {
02646                 struct score_elf_link_hash_entry *hscore;
02647 
02648                 /* We only need to copy this reloc if the symbol is
02649                      defined in a dynamic object.  */
02650                 hscore = (struct score_elf_link_hash_entry *)h;
02651                 ++hscore->possibly_dynamic_relocs;
02652                 if ((sec->flags & SCORE_READONLY_SECTION)
02653                     == SCORE_READONLY_SECTION)
02654                   /* We need it to tell the dynamic linker if there
02655                      are relocations against the text segment.  */
02656                   hscore->readonly_reloc = TRUE;
02657               }
02658 
02659              /* Even though we don't directly need a GOT entry for this symbol,
02660                  a symbol must have a dynamic symbol table index greater that
02661                  DT_SCORE_GOTSYM if there are dynamic relocations against it.  */
02662              if (h != NULL)
02663               {
02664                 if (dynobj == NULL)
02665                   elf_hash_table (info)->dynobj = dynobj = abfd;
02666                 if (! score_elf_create_got_section (dynobj, info, TRUE))
02667                   return FALSE;
02668                 g = score_elf_got_info (dynobj, &sgot);
02669                 if (! score_elf_record_global_got_symbol (h, abfd, info, g))
02670                   return FALSE;
02671               }
02672            }
02673          break;
02674 
02675           /* This relocation describes the C++ object vtable hierarchy.
02676              Reconstruct it for later use during GC.  */
02677         case R_SCORE_GNU_VTINHERIT:
02678           if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
02679             return FALSE;
02680           break;
02681 
02682           /* This relocation describes which C++ vtable entries are actually
02683              used.  Record for later use during GC.  */
02684         case R_SCORE_GNU_VTENTRY:
02685           if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
02686             return FALSE;
02687           break;
02688         default:
02689           break;
02690         }
02691 
02692       /* We must not create a stub for a symbol that has relocations
02693          related to taking the function's address.  */
02694       switch (r_type)
02695        {
02696        default:
02697          if (h != NULL)
02698            {
02699              struct score_elf_link_hash_entry *sh;
02700 
02701              sh = (struct score_elf_link_hash_entry *) h;
02702              sh->no_fn_stub = TRUE;
02703            }
02704          break;
02705        case R_SCORE_CALL15:
02706          break;
02707        }
02708     }
02709 
02710   return TRUE;
02711 }
02712 
02713 static bfd_boolean
02714 _bfd_score_elf_add_symbol_hook (bfd *abfd,
02715                             struct bfd_link_info *info ATTRIBUTE_UNUSED,
02716                             Elf_Internal_Sym *sym,
02717                             const char **namep ATTRIBUTE_UNUSED,
02718                             flagword *flagsp ATTRIBUTE_UNUSED,
02719                             asection **secp,
02720                             bfd_vma *valp)
02721 {
02722   switch (sym->st_shndx)
02723     {
02724     case SHN_COMMON:
02725       if (sym->st_size > elf_gp_size (abfd))
02726         break;
02727       /* Fall through.  */
02728     case SHN_SCORE_SCOMMON:
02729       *secp = bfd_make_section_old_way (abfd, ".scommon");
02730       (*secp)->flags |= SEC_IS_COMMON;
02731       *valp = sym->st_size;
02732       break;
02733     }
02734 
02735   return TRUE;
02736 }
02737 
02738 static void
02739 _bfd_score_elf_symbol_processing (bfd *abfd, asymbol *asym)
02740 {
02741   elf_symbol_type *elfsym;
02742 
02743   elfsym = (elf_symbol_type *) asym;
02744   switch (elfsym->internal_elf_sym.st_shndx)
02745     {
02746     case SHN_COMMON:
02747       if (asym->value > elf_gp_size (abfd))
02748         break;
02749       /* Fall through.  */
02750     case SHN_SCORE_SCOMMON:
02751       if (score_elf_scom_section.name == NULL)
02752         {
02753           /* Initialize the small common section.  */
02754           score_elf_scom_section.name = ".scommon";
02755           score_elf_scom_section.flags = SEC_IS_COMMON;
02756           score_elf_scom_section.output_section = &score_elf_scom_section;
02757           score_elf_scom_section.symbol = &score_elf_scom_symbol;
02758           score_elf_scom_section.symbol_ptr_ptr = &score_elf_scom_symbol_ptr;
02759           score_elf_scom_symbol.name = ".scommon";
02760           score_elf_scom_symbol.flags = BSF_SECTION_SYM;
02761           score_elf_scom_symbol.section = &score_elf_scom_section;
02762           score_elf_scom_symbol_ptr = &score_elf_scom_symbol;
02763         }
02764       asym->section = &score_elf_scom_section;
02765       asym->value = elfsym->internal_elf_sym.st_size;
02766       break;
02767     }
02768 }
02769 
02770 static bfd_boolean
02771 _bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
02772      const char *name ATTRIBUTE_UNUSED,
02773      Elf_Internal_Sym *sym,
02774      asection *input_sec,
02775      struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
02776 {
02777   /* If we see a common symbol, which implies a relocatable link, then
02778      if a symbol was small common in an input file, mark it as small
02779      common in the output file.  */
02780   if (sym->st_shndx == SHN_COMMON && strcmp (input_sec->name, ".scommon") == 0)
02781     sym->st_shndx = SHN_SCORE_SCOMMON;
02782 
02783   return TRUE;
02784 }
02785 
02786 static bfd_boolean
02787 _bfd_score_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
02788                                     asection *sec,
02789                                     int *retval)
02790 {
02791   if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
02792     {
02793       *retval = SHN_SCORE_SCOMMON;
02794       return TRUE;
02795     }
02796 
02797   return FALSE;
02798 }
02799 
02800 /* Adjust a symbol defined by a dynamic object and referenced by a
02801    regular object.  The current definition is in some section of the
02802    dynamic object, but we're not including those sections.  We have to
02803    change the definition to something the rest of the link can understand.  */
02804 
02805 static bfd_boolean
02806 _bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
02807                                   struct elf_link_hash_entry *h)
02808 {
02809   bfd *dynobj;
02810   struct score_elf_link_hash_entry *hscore;
02811   asection *s;
02812 
02813   dynobj = elf_hash_table (info)->dynobj;
02814 
02815   /* Make sure we know what is going on here.  */
02816   BFD_ASSERT (dynobj != NULL
02817               && (h->needs_plt
02818                   || h->u.weakdef != NULL
02819                   || (h->def_dynamic && h->ref_regular && !h->def_regular)));
02820 
02821   /* If this symbol is defined in a dynamic object, we need to copy
02822      any R_SCORE_ABS32 or R_SCORE_REL32 relocs against it into the output
02823      file.  */
02824   hscore = (struct score_elf_link_hash_entry *)h;
02825   if (!info->relocatable
02826       && hscore->possibly_dynamic_relocs != 0
02827       && (h->root.type == bfd_link_hash_defweak || !h->def_regular))
02828     {
02829       score_elf_allocate_dynamic_relocations (dynobj, hscore->possibly_dynamic_relocs);
02830       if (hscore->readonly_reloc)
02831         /* We tell the dynamic linker that there are relocations
02832            against the text segment.  */
02833         info->flags |= DF_TEXTREL;
02834     }
02835 
02836   /* For a function, create a stub, if allowed.  */
02837   if (!hscore->no_fn_stub && h->needs_plt)
02838     {
02839       if (!elf_hash_table (info)->dynamic_sections_created)
02840         return TRUE;
02841 
02842       /* If this symbol is not defined in a regular file, then set
02843          the symbol to the stub location.  This is required to make
02844          function pointers compare as equal between the normal
02845          executable and the shared library.  */
02846       if (!h->def_regular)
02847         {
02848           /* We need .stub section.  */
02849           s = bfd_get_section_by_name (dynobj, SCORE_ELF_STUB_SECTION_NAME);
02850           BFD_ASSERT (s != NULL);
02851 
02852           h->root.u.def.section = s;
02853           h->root.u.def.value = s->size;
02854 
02855           /* XXX Write this stub address somewhere.  */
02856           h->plt.offset = s->size;
02857 
02858           /* Make room for this stub code.  */
02859           s->size += SCORE_FUNCTION_STUB_SIZE;
02860 
02861           /* The last half word of the stub will be filled with the index
02862              of this symbol in .dynsym section.  */
02863           return TRUE;
02864         }
02865     }
02866   else if ((h->type == STT_FUNC) && !h->needs_plt)
02867     {
02868       /* This will set the entry for this symbol in the GOT to 0, and
02869          the dynamic linker will take care of this.  */
02870       h->root.u.def.value = 0;
02871       return TRUE;
02872     }
02873 
02874   /* If this is a weak symbol, and there is a real definition, the
02875      processor independent code will have arranged for us to see the
02876      real definition first, and we can just use the same value.  */
02877   if (h->u.weakdef != NULL)
02878     {
02879       BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
02880                   || h->u.weakdef->root.type == bfd_link_hash_defweak);
02881       h->root.u.def.section = h->u.weakdef->root.u.def.section;
02882       h->root.u.def.value = h->u.weakdef->root.u.def.value;
02883       return TRUE;
02884     }
02885 
02886   /* This is a reference to a symbol defined by a dynamic object which
02887      is not a function.  */
02888   return TRUE;
02889 }
02890 
02891 /* This function is called after all the input files have been read,
02892    and the input sections have been assigned to output sections.  */
02893 
02894 static bfd_boolean
02895 _bfd_score_elf_always_size_sections (bfd *output_bfd,
02896                                  struct bfd_link_info *info)
02897 {
02898   bfd *dynobj;
02899   asection *s;
02900   struct score_got_info *g;
02901   int i;
02902   bfd_size_type loadable_size = 0;
02903   bfd_size_type local_gotno;
02904   bfd *sub;
02905 
02906   dynobj = elf_hash_table (info)->dynobj;
02907   if (dynobj == NULL)
02908     /* Relocatable links don't have it.  */
02909     return TRUE;
02910 
02911   g = score_elf_got_info (dynobj, &s);
02912   if (s == NULL)
02913     return TRUE;
02914 
02915   /* Calculate the total loadable size of the output.  That will give us the
02916      maximum number of GOT_PAGE entries required.  */
02917   for (sub = info->input_bfds; sub; sub = sub->link_next)
02918     {
02919       asection *subsection;
02920 
02921       for (subsection = sub->sections;
02922           subsection;
02923           subsection = subsection->next)
02924        {
02925          if ((subsection->flags & SEC_ALLOC) == 0)
02926            continue;
02927          loadable_size += ((subsection->size + 0xf)
02928                          &~ (bfd_size_type) 0xf);
02929        }
02930     }
02931 
02932   /* There has to be a global GOT entry for every symbol with
02933      a dynamic symbol table index of DT_SCORE_GOTSYM or
02934      higher.  Therefore, it make sense to put those symbols
02935      that need GOT entries at the end of the symbol table.  We
02936      do that here.  */
02937   if (! score_elf_sort_hash_table (info, 1))
02938     return FALSE;
02939 
02940   if (g->global_gotsym != NULL)
02941     i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx;
02942   else
02943     /* If there are no global symbols, or none requiring
02944        relocations, then GLOBAL_GOTSYM will be NULL.  */
02945     i = 0;
02946 
02947   /* In the worst case, we'll get one stub per dynamic symbol.  */
02948   loadable_size += SCORE_FUNCTION_STUB_SIZE * i;
02949 
02950   /* Assume there are two loadable segments consisting of
02951      contiguous sections.  Is 5 enough?  */
02952   local_gotno = (loadable_size >> 16) + 5;
02953 
02954   g->local_gotno += local_gotno;
02955   s->size += g->local_gotno * SCORE_ELF_GOT_SIZE (output_bfd);
02956 
02957   g->global_gotno = i;
02958   s->size += i * SCORE_ELF_GOT_SIZE (output_bfd);
02959 
02960   score_elf_resolve_final_got_entries (g);
02961 
02962   if (s->size > SCORE_ELF_GOT_MAX_SIZE (output_bfd))
02963     {
02964       /* Fixme. Error message or Warning message should be issued here.  */
02965     }
02966 
02967   return TRUE;
02968 }
02969 
02970 /* Set the sizes of the dynamic sections.  */
02971 
02972 static bfd_boolean
02973 _bfd_score_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
02974 {
02975   bfd *dynobj;
02976   asection *s;
02977   bfd_boolean reltext;
02978 
02979   dynobj = elf_hash_table (info)->dynobj;
02980   BFD_ASSERT (dynobj != NULL);
02981 
02982   if (elf_hash_table (info)->dynamic_sections_created)
02983     {
02984       /* Set the contents of the .interp section to the interpreter.  */
02985       if (!info->shared)
02986         {
02987           s = bfd_get_section_by_name (dynobj, ".interp");
02988           BFD_ASSERT (s != NULL);
02989           s->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
02990           s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
02991         }
02992     }
02993 
02994   /* The check_relocs and adjust_dynamic_symbol entry points have
02995      determined the sizes of the various dynamic sections.  Allocate
02996      memory for them.  */
02997   reltext = FALSE;
02998   for (s = dynobj->sections; s != NULL; s = s->next)
02999     {
03000       const char *name;
03001 
03002       if ((s->flags & SEC_LINKER_CREATED) == 0)
03003         continue;
03004 
03005       /* It's OK to base decisions on the section name, because none
03006          of the dynobj section names depend upon the input files.  */
03007       name = bfd_get_section_name (dynobj, s);
03008 
03009       if (CONST_STRNEQ (name, ".rel"))
03010         {
03011           if (s->size == 0)
03012             {
03013               /* We only strip the section if the output section name
03014                  has the same name.  Otherwise, there might be several
03015                  input sections for this output section.  FIXME: This
03016                  code is probably not needed these days anyhow, since
03017                  the linker now does not create empty output sections.  */
03018               if (s->output_section != NULL
03019                   && strcmp (name,
03020                              bfd_get_section_name (s->output_section->owner,
03021                                                    s->output_section)) == 0)
03022                 s->flags |= SEC_EXCLUDE;
03023             }
03024           else
03025             {
03026               const char *outname;
03027               asection *target;
03028 
03029               /* If this relocation section applies to a read only
03030                  section, then we probably need a DT_TEXTREL entry.
03031                  If the relocation section is .rel.dyn, we always
03032                  assert a DT_TEXTREL entry rather than testing whether
03033                  there exists a relocation to a read only section or
03034                  not.  */
03035               outname = bfd_get_section_name (output_bfd, s->output_section);
03036               target = bfd_get_section_by_name (output_bfd, outname + 4);
03037               if ((target != NULL
03038                    && (target->flags & SEC_READONLY) != 0
03039                    && (target->flags & SEC_ALLOC) != 0) || strcmp (outname, ".rel.dyn") == 0)
03040                 reltext = TRUE;
03041 
03042               /* We use the reloc_count field as a counter if we need
03043                  to copy relocs into the output file.  */
03044               if (strcmp (name, ".rel.dyn") != 0)
03045                 s->reloc_count = 0;
03046             }
03047         }
03048       else if (CONST_STRNEQ (name, ".got"))
03049         {
03050          /* _bfd_score_elf_always_size_sections() has already done
03051             most of the work, but some symbols may have been mapped
03052             to versions that we must now resolve in the got_entries
03053             hash tables.  */
03054         }
03055       else if (strcmp (name, SCORE_ELF_STUB_SECTION_NAME) == 0)
03056         {
03057           /* IRIX rld assumes that the function stub isn't at the end
03058              of .text section. So put a dummy. XXX  */
03059           s->size += SCORE_FUNCTION_STUB_SIZE;
03060         }
03061       else if (! CONST_STRNEQ (name, ".init"))
03062         {
03063           /* It's not one of our sections, so don't allocate space.  */
03064           continue;
03065         }
03066 
03067       /* Allocate memory for the section contents.  */
03068       s->contents = bfd_zalloc (dynobj, s->size);
03069       if (s->contents == NULL && s->size != 0)
03070         {
03071           bfd_set_error (bfd_error_no_memory);
03072           return FALSE;
03073         }
03074     }
03075 
03076   if (elf_hash_table (info)->dynamic_sections_created)
03077     {
03078       /* Add some entries to the .dynamic section.  We fill in the
03079         values later, in _bfd_score_elf_finish_dynamic_sections, but we
03080         must add the entries now so that we get the correct size for
03081         the .dynamic section.  The DT_DEBUG entry is filled in by the
03082         dynamic linker and used by the debugger.  */
03083 
03084       if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0))
03085        return FALSE;
03086 
03087       if (reltext)
03088        info->flags |= DF_TEXTREL;
03089 
03090       if ((info->flags & DF_TEXTREL) != 0)
03091        {
03092          if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0))
03093            return FALSE;
03094        }
03095 
03096       if (! SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTGOT, 0))
03097        return FALSE;
03098 
03099       if (score_elf_rel_dyn_section (dynobj, FALSE))
03100        {
03101          if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_REL, 0))
03102            return FALSE;
03103 
03104          if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELSZ, 0))
03105            return FALSE;
03106 
03107          if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELENT, 0))
03108            return FALSE;
03109        }
03110 
03111       if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_BASE_ADDRESS, 0))
03112         return FALSE;
03113 
03114       if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_LOCAL_GOTNO, 0))
03115         return FALSE;
03116 
03117       if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_SYMTABNO, 0))
03118         return FALSE;
03119 
03120       if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_UNREFEXTNO, 0))
03121         return FALSE;
03122 
03123       if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_GOTSYM, 0))
03124         return FALSE;
03125 
03126       if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_HIPAGENO, 0))
03127        return FALSE;
03128     }
03129 
03130   return TRUE;
03131 }
03132 
03133 static bfd_boolean
03134 _bfd_score_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
03135 {
03136   struct elf_link_hash_entry *h;
03137   struct bfd_link_hash_entry *bh;
03138   flagword flags;
03139   asection *s;
03140 
03141   flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
03142            | SEC_LINKER_CREATED | SEC_READONLY);
03143 
03144   /* ABI requests the .dynamic section to be read only.  */
03145   s = bfd_get_section_by_name (abfd, ".dynamic");
03146   if (s != NULL)
03147     {
03148       if (!bfd_set_section_flags (abfd, s, flags))
03149         return FALSE;
03150     }
03151 
03152   /* We need to create .got section.  */
03153   if (!score_elf_create_got_section (abfd, info, FALSE))
03154     return FALSE;
03155 
03156   if (!score_elf_rel_dyn_section (elf_hash_table (info)->dynobj, TRUE))
03157     return FALSE;
03158 
03159   /* Create .stub section.  */
03160   if (bfd_get_section_by_name (abfd, SCORE_ELF_STUB_SECTION_NAME) == NULL)
03161     {
03162       s = bfd_make_section_with_flags (abfd, SCORE_ELF_STUB_SECTION_NAME,
03163                                        flags | SEC_CODE);
03164       if (s == NULL
03165           || !bfd_set_section_alignment (abfd, s, 2))
03166 
03167         return FALSE;
03168     }
03169 
03170   if (!info->shared)
03171     {
03172       const char *name;
03173 
03174       name = "_DYNAMIC_LINK";
03175       bh = NULL;
03176       if (!(_bfd_generic_link_add_one_symbol
03177             (info, abfd, name, BSF_GLOBAL, bfd_abs_section_ptr,
03178              (bfd_vma) 0, (const char *)NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
03179         return FALSE;
03180 
03181       h = (struct elf_link_hash_entry *)bh;
03182       h->non_elf = 0;
03183       h->def_regular = 1;
03184       h->type = STT_SECTION;
03185 
03186       if (!bfd_elf_link_record_dynamic_symbol (info, h))
03187         return FALSE;
03188     }
03189 
03190   return TRUE;
03191 }
03192 
03193 
03194 /* Finish up dynamic symbol handling.  We set the contents of various
03195    dynamic sections here.  */
03196 
03197 static bfd_boolean
03198 _bfd_score_elf_finish_dynamic_symbol (bfd *output_bfd,
03199                                   struct bfd_link_info *info,
03200                                   struct elf_link_hash_entry *h,
03201                                   Elf_Internal_Sym *sym)
03202 {
03203   bfd *dynobj;
03204   asection *sgot;
03205   struct score_got_info *g;
03206   const char *name;
03207 
03208   dynobj = elf_hash_table (info)->dynobj;
03209 
03210   if (h->plt.offset != MINUS_ONE)
03211     {
03212       asection *s;
03213       bfd_byte stub[SCORE_FUNCTION_STUB_SIZE];
03214 
03215       /* This symbol has a stub.  Set it up.  */
03216       BFD_ASSERT (h->dynindx != -1);
03217 
03218       s = bfd_get_section_by_name (dynobj, SCORE_ELF_STUB_SECTION_NAME);
03219       BFD_ASSERT (s != NULL);
03220 
03221       /* FIXME: Can h->dynindex be more than 64K?  */
03222       if (h->dynindx & 0xffff0000)
03223        return FALSE;
03224 
03225       /* Fill the stub.  */
03226       bfd_put_32 (output_bfd, STUB_LW, stub);
03227       bfd_put_32 (output_bfd, STUB_MOVE, stub + 4);
03228       bfd_put_32 (output_bfd, STUB_LI16 | (h->dynindx << 1), stub + 8);
03229       bfd_put_32 (output_bfd, STUB_BRL, stub + 12);
03230 
03231       BFD_ASSERT (h->plt.offset <= s->size);
03232       memcpy (s->contents + h->plt.offset, stub, SCORE_FUNCTION_STUB_SIZE);
03233 
03234       /* Mark the symbol as undefined.  plt.offset != -1 occurs
03235         only for the referenced symbol.  */
03236       sym->st_shndx = SHN_UNDEF;
03237 
03238       /* The run-time linker uses the st_value field of the symbol
03239          to reset the global offset table entry for this external
03240          to its stub address when unlinking a shared object.  */
03241       sym->st_value = (s->output_section->vma + s->output_offset + h->plt.offset);
03242     }
03243 
03244   BFD_ASSERT (h->dynindx != -1 || h->forced_local);
03245 
03246   sgot = score_elf_got_section (dynobj, FALSE);
03247   BFD_ASSERT (sgot != NULL);
03248   BFD_ASSERT (score_elf_section_data (sgot) != NULL);
03249   g = score_elf_section_data (sgot)->u.got_info;
03250   BFD_ASSERT (g != NULL);
03251 
03252   /* Run through the global symbol table, creating GOT entries for all
03253      the symbols that need them.  */
03254   if (g->global_gotsym != NULL && h->dynindx >= g->global_gotsym->dynindx)
03255     {
03256       bfd_vma offset;
03257       bfd_vma value;
03258 
03259       value = sym->st_value;
03260       offset = score_elf_global_got_index (dynobj, h);
03261       bfd_put_32 (output_bfd, value, sgot->contents + offset);
03262     }
03263 
03264   /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
03265   name = h->root.root.string;
03266   if (strcmp (name, "_DYNAMIC") == 0 || strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
03267     sym->st_shndx = SHN_ABS;
03268   else if (strcmp (name, "_DYNAMIC_LINK") == 0)
03269     {
03270       sym->st_shndx = SHN_ABS;
03271       sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
03272       sym->st_value = 1;
03273     }
03274   else if (strcmp (name, GP_DISP_LABEL) == 0)
03275     {
03276       sym->st_shndx = SHN_ABS;
03277       sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
03278       sym->st_value = elf_gp (output_bfd);
03279     }
03280 
03281   return TRUE;
03282 }
03283 
03284 /* Finish up the dynamic sections.  */
03285 
03286 static bfd_boolean
03287 _bfd_score_elf_finish_dynamic_sections (bfd *output_bfd,
03288                                     struct bfd_link_info *info)
03289 {
03290   bfd *dynobj;
03291   asection *sdyn;
03292   asection *sgot;
03293   asection *s;
03294   struct score_got_info *g;
03295 
03296   dynobj = elf_hash_table (info)->dynobj;
03297 
03298   sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
03299 
03300   sgot = score_elf_got_section (dynobj, FALSE);
03301   if (sgot == NULL)
03302     g = NULL;
03303   else
03304     {
03305       BFD_ASSERT (score_elf_section_data (sgot) != NULL);
03306       g = score_elf_section_data (sgot)->u.got_info;
03307       BFD_ASSERT (g != NULL);
03308     }
03309 
03310   if (elf_hash_table (info)->dynamic_sections_created)
03311     {
03312       bfd_byte *b;
03313 
03314       BFD_ASSERT (sdyn != NULL);
03315       BFD_ASSERT (g != NULL);
03316 
03317       for (b = sdyn->contents;
03318           b < sdyn->contents + sdyn->size;
03319           b += SCORE_ELF_DYN_SIZE (dynobj))
03320        {
03321          Elf_Internal_Dyn dyn;
03322          const char *name;
03323          size_t elemsize;
03324          bfd_boolean swap_out_p;
03325 
03326          /* Read in the current dynamic entry.  */
03327          (*get_elf_backend_data (dynobj)->s->swap_dyn_in) (dynobj, b, &dyn);
03328 
03329          /* Assume that we're going to modify it and write it out.  */
03330          swap_out_p = TRUE;
03331 
03332          switch (dyn.d_tag)
03333            {
03334            case DT_RELENT:
03335              s = score_elf_rel_dyn_section (dynobj, FALSE);
03336              BFD_ASSERT (s != NULL);
03337              dyn.d_un.d_val = SCORE_ELF_REL_SIZE (dynobj);
03338              break;
03339 
03340            case DT_STRSZ:
03341              /* Rewrite DT_STRSZ.  */
03342              dyn.d_un.d_val = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
03343                   break;
03344 
03345            case DT_PLTGOT:
03346              name = ".got";
03347              s = bfd_get_section_by_name (output_bfd, name);
03348              BFD_ASSERT (s != NULL);
03349              dyn.d_un.d_ptr = s->vma;
03350              break;
03351 
03352            case DT_SCORE_BASE_ADDRESS:
03353              s = output_bfd->sections;
03354              BFD_ASSERT (s != NULL);
03355              dyn.d_un.d_ptr = s->vma & ~(bfd_vma) 0xffff;
03356              break;
03357 
03358            case DT_SCORE_LOCAL_GOTNO:
03359              dyn.d_un.d_val = g->local_gotno;
03360              break;
03361 
03362            case DT_SCORE_UNREFEXTNO:
03363              /* The index into the dynamic symbol table which is the
03364                entry of the first external symbol that is not
03365                referenced within the same object.  */
03366              dyn.d_un.d_val = bfd_count_sections (output_bfd) + 1;
03367              break;
03368 
03369            case DT_SCORE_GOTSYM:
03370              if (g->global_gotsym)
03371               {
03372                 dyn.d_un.d_val = g->global_gotsym->dynindx;
03373                 break;
03374               }
03375              /* In case if we don't have global got symbols we default
03376                 to setting DT_SCORE_GOTSYM to the same value as
03377                 DT_SCORE_SYMTABNO, so we just fall through.  */
03378 
03379            case DT_SCORE_SYMTABNO:
03380              name = ".dynsym";
03381              elemsize = SCORE_ELF_SYM_SIZE (output_bfd);
03382              s = bfd_get_section_by_name (output_bfd, name);
03383              BFD_ASSERT (s != NULL);
03384 
03385              dyn.d_un.d_val = s->size / elemsize;
03386              break;
03387 
03388            case DT_SCORE_HIPAGENO:
03389              dyn.d_un.d_val = g->local_gotno - SCORE_RESERVED_GOTNO;
03390              break;
03391 
03392            default:
03393              swap_out_p = FALSE;
03394              break;
03395            }
03396 
03397          if (swap_out_p)
03398            (*get_elf_backend_data (dynobj)->s->swap_dyn_out) (dynobj, &dyn, b);
03399        }
03400     }
03401 
03402   /* The first entry of the global offset table will be filled at
03403      runtime. The second entry will be used by some runtime loaders.
03404      This isn't the case of IRIX rld.  */
03405   if (sgot != NULL && sgot->size > 0)
03406     {
03407       bfd_put_32 (output_bfd, 0, sgot->contents);
03408       bfd_put_32 (output_bfd, 0x80000000, sgot->contents + SCORE_ELF_GOT_SIZE (output_bfd));
03409     }
03410 
03411   if (sgot != NULL)
03412     elf_section_data (sgot->output_section)->this_hdr.sh_entsize
03413       = SCORE_ELF_GOT_SIZE (output_bfd);
03414 
03415 
03416   /* We need to sort the entries of the dynamic relocation section.  */
03417   s = score_elf_rel_dyn_section (dynobj, FALSE);
03418 
03419   if (s != NULL && s->size > (bfd_vma)2 * SCORE_ELF_REL_SIZE (output_bfd))
03420     {
03421       reldyn_sorting_bfd = output_bfd;
03422       qsort ((Elf32_External_Rel *) s->contents + 1, s->reloc_count - 1,
03423             sizeof (Elf32_External_Rel), score_elf_sort_dynamic_relocs);
03424     }
03425 
03426   return TRUE;
03427 }
03428 
03429 /* This function set up the ELF section header for a BFD section in preparation for writing
03430    it out.  This is where the flags and type fields are set for unusual sections.  */
03431 
03432 static bfd_boolean
03433 _bfd_score_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
03434                            Elf_Internal_Shdr *hdr,
03435                            asection *sec)
03436 {
03437   const char *name;
03438 
03439   name = bfd_get_section_name (abfd, sec);
03440 
03441   if (strcmp (name, ".got") == 0
03442       || strcmp (name, ".srdata") == 0
03443       || strcmp (name, ".sdata") == 0
03444       || strcmp (name, ".sbss") == 0)
03445     hdr->sh_flags |= SHF_SCORE_GPREL;
03446 
03447   return TRUE;
03448 }
03449 
03450 /* This function do additional processing on the ELF section header before writing
03451    it out.  This is used to set the flags and type fields for some sections.  */
03452 
03453 /* assign_file_positions_except_relocs() check section flag and if it is allocatable,
03454    warning message will be issued.  backend_fake_section is called before
03455    assign_file_positions_except_relocs(); backend_section_processing after it.  so, we
03456    modify section flag there, but not backend_fake_section.  */
03457 
03458 static bfd_boolean
03459 _bfd_score_elf_section_processing (bfd *abfd ATTRIBUTE_UNUSED, Elf_Internal_Shdr *hdr)
03460 {
03461   if (hdr->bfd_section != NULL)
03462     {
03463       const char *name = bfd_get_section_name (abfd, hdr->bfd_section);
03464 
03465       if (strcmp (name, ".sdata") == 0)
03466        {
03467          hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
03468          hdr->sh_type = SHT_PROGBITS;
03469        }
03470       else if (strcmp (name, ".sbss") == 0)
03471        {
03472          hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
03473          hdr->sh_type = SHT_NOBITS;
03474        }
03475       else if (strcmp (name, ".srdata") == 0)
03476        {
03477          hdr->sh_flags |= SHF_ALLOC | SHF_SCORE_GPREL;
03478          hdr->sh_type = SHT_PROGBITS;
03479        }
03480     }
03481 
03482   return TRUE;
03483 }
03484 
03485 static bfd_boolean
03486 _bfd_score_elf_write_section (bfd *output_bfd,
03487                            struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
03488                               asection *sec, bfd_byte *contents)
03489 {
03490   bfd_byte *to, *from, *end;
03491   int i;
03492 
03493   if (strcmp (sec->name, ".pdr") != 0)
03494     return FALSE;
03495 
03496   if (score_elf_section_data (sec)->u.tdata == NULL)
03497     return FALSE;
03498 
03499   to = contents;
03500   end = contents + sec->size;
03501   for (from = contents, i = 0; from < end; from += PDR_SIZE, i++)
03502     {
03503       if ((score_elf_section_data (sec)->u.tdata)[i] == 1)
03504         continue;
03505 
03506       if (to != from)
03507         memcpy (to, from, PDR_SIZE);
03508 
03509       to += PDR_SIZE;
03510     }
03511   bfd_set_section_contents (output_bfd, sec->output_section, contents,
03512                             (file_ptr) sec->output_offset, sec->size);
03513 
03514   return TRUE;
03515 }
03516 
03517 /* Copy data from a SCORE ELF indirect symbol to its direct symbol, hiding the old
03518    indirect symbol.  Process additional relocation information.  */
03519 
03520 static void
03521 _bfd_score_elf_copy_indirect_symbol (struct bfd_link_info *info,
03522                                  struct elf_link_hash_entry *dir,
03523                                  struct elf_link_hash_entry *ind)
03524 {
03525   struct score_elf_link_hash_entry *dirscore, *indscore;
03526 
03527   _bfd_elf_link_hash_copy_indirect (info, dir, ind);
03528 
03529   if (ind->root.type != bfd_link_hash_indirect)
03530     return;
03531 
03532   dirscore = (struct score_elf_link_hash_entry *) dir;
03533   indscore = (struct score_elf_link_hash_entry *) ind;
03534   dirscore->possibly_dynamic_relocs += indscore->possibly_dynamic_relocs;
03535 
03536   if (indscore->readonly_reloc)
03537     dirscore->readonly_reloc = TRUE;
03538 
03539   if (indscore->no_fn_stub)
03540     dirscore->no_fn_stub = TRUE;
03541 }
03542 
03543 /* Remove information about discarded functions from other sections which mention them.  */
03544 
03545 static bfd_boolean
03546 _bfd_score_elf_discard_info (bfd *abfd, struct elf_reloc_cookie *cookie,
03547                          struct bfd_link_info *info)
03548 {
03549   asection *o;
03550   bfd_boolean ret = FALSE;
03551   unsigned char *tdata;
03552   size_t i, skip;
03553 
03554   o = bfd_get_section_by_name (abfd, ".pdr");
03555   if ((!o) || (o->size == 0) || (o->size % PDR_SIZE != 0)
03556       || (o->output_section != NULL && bfd_is_abs_section (o->output_section)))
03557     return FALSE;
03558 
03559   tdata = bfd_zmalloc (o->size / PDR_SIZE);
03560   if (!tdata)
03561     return FALSE;
03562 
03563   cookie->rels = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, info->keep_memory);
03564   if (!cookie->rels)
03565     {
03566       free (tdata);
03567       return FALSE;
03568     }
03569 
03570   cookie->rel = cookie->rels;
03571   cookie->relend = cookie->rels + o->reloc_count;
03572 
03573   for (i = 0, skip = 0; i < o->size; i++)
03574     {
03575       if (bfd_elf_reloc_symbol_deleted_p (i * PDR_SIZE, cookie))
03576         {
03577           tdata[i] = 1;
03578           skip++;
03579         }
03580     }
03581 
03582   if (skip != 0)
03583     {
03584       score_elf_section_data (o)->u.tdata = tdata;
03585       o->size -= skip * PDR_SIZE;
03586       ret = TRUE;
03587     }
03588   else
03589     free (tdata);
03590 
03591   if (!info->keep_memory)
03592     free (cookie->rels);
03593 
03594   return ret;
03595 }
03596 
03597 /* Signal that discard_info() has removed the discarded relocations for this section.  */
03598 
03599 static bfd_boolean
03600 _bfd_score_elf_ignore_discarded_relocs (asection *sec)
03601 {
03602   if (strcmp (sec->name, ".pdr") == 0)
03603     return TRUE;
03604   return FALSE;
03605 }
03606 
03607 /* Return the section that should be marked against GC for a given
03608    relocation.  */
03609 
03610 static asection *
03611 _bfd_score_elf_gc_mark_hook (asection *sec,
03612                           struct bfd_link_info *info,
03613                           Elf_Internal_Rela *rel,
03614                           struct elf_link_hash_entry *h,
03615                           Elf_Internal_Sym *sym)
03616 {
03617   if (h != NULL)
03618     switch (ELF32_R_TYPE (rel->r_info))
03619       {
03620       case R_SCORE_GNU_VTINHERIT:
03621       case R_SCORE_GNU_VTENTRY:
03622        return NULL;
03623       }
03624 
03625   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
03626 }
03627 
03628 /* Support for core dump NOTE sections.  */
03629 
03630 static bfd_boolean
03631 _bfd_score_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
03632 {
03633   int offset;
03634   unsigned int raw_size;
03635 
03636   switch (note->descsz)
03637     {
03638     default:
03639       return FALSE;
03640 
03641     case 148:                  /* Linux/Score 32-bit.  */
03642       /* pr_cursig */
03643       elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
03644 
03645       /* pr_pid */
03646       elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
03647 
03648       /* pr_reg */
03649       offset = 72;
03650       raw_size = 72;
03651 
03652       break;
03653     }
03654 
03655   /* Make a ".reg/999" section.  */
03656   return _bfd_elfcore_make_pseudosection (abfd, ".reg", raw_size, note->descpos + offset);
03657 }
03658 
03659 static bfd_boolean
03660 _bfd_score_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
03661 {
03662   switch (note->descsz)
03663     {
03664     default:
03665       return FALSE;
03666 
03667     case 124:                  /* Linux/Score elf_prpsinfo.  */
03668       elf_tdata (abfd)->core_program = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
03669       elf_tdata (abfd)->core_command = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
03670     }
03671 
03672   /* Note that for some reason, a spurious space is tacked
03673      onto the end of the args in some (at least one anyway)
03674      implementations, so strip it off if it exists.  */
03675 
03676   {
03677     char *command = elf_tdata (abfd)->core_command;
03678     int n = strlen (command);
03679 
03680     if (0 < n && command[n - 1] == ' ')
03681       command[n - 1] = '\0';
03682   }
03683 
03684   return TRUE;
03685 }
03686 
03687 
03688 /* Score BFD functions.  */
03689 
03690 static reloc_howto_type *
03691 elf32_score_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
03692 {
03693   unsigned int i;
03694 
03695   for (i = 0; i < NUM_ELEM (elf32_score_reloc_map); i++)
03696     if (elf32_score_reloc_map[i].bfd_reloc_val == code)
03697       return &elf32_score_howto_table[elf32_score_reloc_map[i].elf_reloc_val];
03698 
03699   return NULL;
03700 }
03701 
03702 static reloc_howto_type *
03703 elf32_score_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
03704                             const char *r_name)
03705 {
03706   unsigned int i;
03707 
03708   for (i = 0;
03709        i < (sizeof (elf32_score_howto_table)
03710            / sizeof (elf32_score_howto_table[0]));
03711        i++)
03712     if (elf32_score_howto_table[i].name != NULL
03713        && strcasecmp (elf32_score_howto_table[i].name, r_name) == 0)
03714       return &elf32_score_howto_table[i];
03715 
03716   return NULL;
03717 }
03718 
03719 /* Create a score elf linker hash table.  */
03720 
03721 static struct bfd_link_hash_table *
03722 elf32_score_link_hash_table_create (bfd *abfd)
03723 {
03724   struct score_elf_link_hash_table *ret;
03725   bfd_size_type amt = sizeof (struct score_elf_link_hash_table);
03726 
03727   ret = bfd_malloc (amt);
03728   if (ret == NULL)
03729     return NULL;
03730 
03731   if (!_bfd_elf_link_hash_table_init (&ret->root, abfd, score_elf_link_hash_newfunc,
03732                                   sizeof (struct score_elf_link_hash_entry)))
03733     {
03734       free (ret);
03735       return NULL;
03736     }
03737 
03738   return &ret->root.root;
03739 }
03740 
03741 static bfd_boolean
03742 elf32_score_print_private_bfd_data (bfd *abfd, void * ptr)
03743 {
03744   FILE *file = (FILE *) ptr;
03745 
03746   BFD_ASSERT (abfd != NULL && ptr != NULL);
03747 
03748   /* Print normal ELF private data.  */
03749   _bfd_elf_print_private_bfd_data (abfd, ptr);
03750 
03751   /* xgettext:c-format */
03752   fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
03753   if (elf_elfheader (abfd)->e_flags & EF_SCORE_PIC)
03754     {
03755       fprintf (file, _(" [pic]"));
03756     }
03757   if (elf_elfheader (abfd)->e_flags & EF_SCORE_FIXDEP)
03758     {
03759       fprintf (file, _(" [fix dep]"));
03760     }
03761   fputc ('\n', file);
03762 
03763   return TRUE;
03764 }
03765 
03766 static bfd_boolean
03767 elf32_score_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
03768 {
03769   flagword in_flags;
03770   flagword out_flags;
03771 
03772   if (!_bfd_generic_verify_endian_match (ibfd, obfd))
03773     return FALSE;
03774 
03775   in_flags  = elf_elfheader (ibfd)->e_flags;
03776   out_flags = elf_elfheader (obfd)->e_flags;
03777 
03778   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
03779       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
03780     return TRUE;
03781 
03782   in_flags = elf_elfheader (ibfd)->e_flags;
03783   out_flags = elf_elfheader (obfd)->e_flags;
03784 
03785   if (! elf_flags_init (obfd))
03786     {
03787       elf_flags_init (obfd) = TRUE;
03788       elf_elfheader (obfd)->e_flags = in_flags;
03789 
03790       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
03791          && bfd_get_arch_info (obfd)->the_default)
03792        {
03793          return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
03794        }
03795 
03796       return TRUE;
03797     }
03798 
03799   if (((in_flags & EF_SCORE_PIC) != 0) != ((out_flags & EF_SCORE_PIC) != 0))
03800     {
03801       (*_bfd_error_handler) (_("%B: warning: linking PIC files with non-PIC files"), ibfd);
03802     }
03803 
03804   /* FIXME: Maybe dependency fix compatibility should be checked here.  */
03805 
03806   return TRUE;
03807 }
03808 
03809 static bfd_boolean
03810 elf32_score_new_section_hook (bfd *abfd, asection *sec)
03811 {
03812   struct _score_elf_section_data *sdata;
03813   bfd_size_type amt = sizeof (*sdata);
03814 
03815   sdata = bfd_zalloc (abfd, amt);
03816   if (sdata == NULL)
03817     return FALSE;
03818   sec->used_by_bfd = sdata;
03819 
03820   return _bfd_elf_new_section_hook (abfd, sec);
03821 }
03822 
03823 
03824 #define USE_REL                         1
03825 #define TARGET_LITTLE_SYM               bfd_elf32_littlescore_vec
03826 #define TARGET_LITTLE_NAME              "elf32-littlescore"
03827 #define TARGET_BIG_SYM                  bfd_elf32_bigscore_vec
03828 #define TARGET_BIG_NAME                 "elf32-bigscore"
03829 #define ELF_ARCH                        bfd_arch_score
03830 #define ELF_MACHINE_CODE                EM_SCORE
03831 #define ELF_MAXPAGESIZE                 0x8000
03832 
03833 #define elf_info_to_howto               0
03834 #define elf_info_to_howto_rel           _bfd_score_info_to_howto
03835 #define elf_backend_relocate_section    _bfd_score_elf_relocate_section
03836 #define elf_backend_check_relocs        _bfd_score_elf_check_relocs
03837 #define elf_backend_add_symbol_hook     _bfd_score_elf_add_symbol_hook
03838 #define elf_backend_symbol_processing   _bfd_score_elf_symbol_processing
03839 #define elf_backend_link_output_symbol_hook \
03840   _bfd_score_elf_link_output_symbol_hook
03841 #define elf_backend_section_from_bfd_section \
03842   _bfd_score_elf_section_from_bfd_section
03843 #define elf_backend_adjust_dynamic_symbol \
03844   _bfd_score_elf_adjust_dynamic_symbol
03845 #define elf_backend_always_size_sections \
03846   _bfd_score_elf_always_size_sections
03847 #define elf_backend_size_dynamic_sections \
03848   _bfd_score_elf_size_dynamic_sections
03849 #define elf_backend_omit_section_dynsym \
03850   ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
03851 #define elf_backend_create_dynamic_sections \
03852   _bfd_score_elf_create_dynamic_sections
03853 #define elf_backend_finish_dynamic_symbol \
03854   _bfd_score_elf_finish_dynamic_symbol
03855 #define elf_backend_finish_dynamic_sections \
03856   _bfd_score_elf_finish_dynamic_sections
03857 #define elf_backend_fake_sections         _bfd_score_elf_fake_sections
03858 #define elf_backend_section_processing    _bfd_score_elf_section_processing
03859 #define elf_backend_write_section         _bfd_score_elf_write_section
03860 #define elf_backend_copy_indirect_symbol  _bfd_score_elf_copy_indirect_symbol
03861 #define elf_backend_hide_symbol           _bfd_score_elf_hide_symbol
03862 #define elf_backend_discard_info          _bfd_score_elf_discard_info
03863 #define elf_backend_ignore_discarded_relocs \
03864   _bfd_score_elf_ignore_discarded_relocs
03865 #define elf_backend_gc_mark_hook          _bfd_score_elf_gc_mark_hook
03866 #define elf_backend_grok_prstatus         _bfd_score_elf_grok_prstatus
03867 #define elf_backend_grok_psinfo           _bfd_score_elf_grok_psinfo
03868 #define elf_backend_can_gc_sections       1
03869 #define elf_backend_want_plt_sym          0
03870 #define elf_backend_got_header_size       (4 * SCORE_RESERVED_GOTNO)
03871 #define elf_backend_plt_header_size       0
03872 #define elf_backend_collect               TRUE
03873 #define elf_backend_type_change_ok        TRUE
03874 
03875 #define bfd_elf32_bfd_reloc_type_lookup      elf32_score_reloc_type_lookup
03876 #define bfd_elf32_bfd_reloc_name_lookup \
03877   elf32_score_reloc_name_lookup
03878 #define bfd_elf32_bfd_link_hash_table_create elf32_score_link_hash_table_create
03879 #define bfd_elf32_bfd_print_private_bfd_data elf32_score_print_private_bfd_data
03880 #define bfd_elf32_bfd_merge_private_bfd_data elf32_score_merge_private_bfd_data
03881 #define bfd_elf32_new_section_hook           elf32_score_new_section_hook
03882 
03883 #include "elf32-target.h"