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