1/* 32-bit ELF support for S+core.
2   Copyright 2006 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 "bfd.h"
24#include "sysdep.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 if (r_symndx == 0)
2010        /* r_symndx will be zero only for relocs against symbols
2011           from removed linkonce sections, or sections discarded by
2012           a linker script.  */
2013        value = 0;
2014      else
2015	{
2016	  if (r_type != R_SCORE_REL32)
2017	    value = symbol + addend;
2018	  else
2019	    value = addend;
2020	}
2021      value &= howto->dst_mask;
2022      bfd_put_32 (input_bfd, value, hit_data);
2023      return bfd_reloc_ok;
2024
2025    case R_SCORE_ABS16:
2026      value += addend;
2027      if ((long)value > 0x7fff || (long)value < -0x8000)
2028        return bfd_reloc_overflow;
2029      bfd_put_16 (input_bfd, value, hit_data);
2030      return bfd_reloc_ok;
2031
2032    case R_SCORE_24:
2033      addend = bfd_get_32 (input_bfd, hit_data);
2034      offset = (((addend & howto->src_mask) >> 1) & 0x1ff8000) | ((addend & howto->src_mask) & 0x7fff);
2035      if ((offset & 0x1000000) != 0)
2036        offset |= 0xfe000000;
2037      value += offset;
2038      addend = (addend & ~howto->src_mask)
2039                | (((value << 1) & howto->src_mask) & 0x3ff0000) | (value & 0x7fff);
2040      bfd_put_32 (input_bfd, addend, hit_data);
2041      return bfd_reloc_ok;
2042
2043    case R_SCORE_PC19:
2044      addend = bfd_get_32 (input_bfd, hit_data);
2045      offset = (((addend & howto->src_mask) & 0x3ff0000) >> 6) | ((addend & howto->src_mask) & 0x3ff);
2046      if ((offset & 0x80000) != 0)
2047        offset |= 0xfff00000;
2048      abs_value = value = value - rel_addr + offset;
2049      /* exceed 20 bit : overflow.  */
2050      if ((abs_value & 0x80000000) == 0x80000000)
2051        abs_value = 0xffffffff - value + 1;
2052      if ((abs_value & 0xfff80000) != 0)
2053        return bfd_reloc_overflow;
2054      addend = (addend & ~howto->src_mask)
2055                | (((value << 6) & howto->src_mask) & 0x3ff0000) | (value & 0x3ff);
2056      bfd_put_32 (input_bfd, addend, hit_data);
2057      return bfd_reloc_ok;
2058
2059    case R_SCORE16_11:
2060      addend = bfd_get_16 (input_bfd, hit_data);
2061      offset = addend & howto->src_mask;
2062      if ((offset & 0x800) != 0)        /* Offset is negative.  */
2063        offset |= 0xfffff000;
2064      value += offset;
2065      addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
2066      bfd_put_16 (input_bfd, addend, hit_data);
2067      return bfd_reloc_ok;
2068
2069    case R_SCORE16_PC8:
2070      addend = bfd_get_16 (input_bfd, hit_data);
2071      offset = (addend & howto->src_mask) << 1;
2072      if ((offset & 0x100) != 0)        /* Offset is negative.  */
2073        offset |= 0xfffffe00;
2074      abs_value = value = value - rel_addr + offset;
2075      /* Sign bit + exceed 9 bit.  */
2076      if (((value & 0xffffff00) != 0) && ((value & 0xffffff00) != 0xffffff00))
2077        return bfd_reloc_overflow;
2078      value >>= 1;
2079      addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
2080      bfd_put_16 (input_bfd, addend, hit_data);
2081      return bfd_reloc_ok;
2082
2083    case R_SCORE_HI16:
2084      return bfd_reloc_ok;
2085
2086    case R_SCORE_LO16:
2087      hi16_addend = bfd_get_32 (input_bfd, hit_data - 4);
2088      hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
2089      addend = bfd_get_32 (input_bfd, hit_data);
2090      offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
2091      offset = (hi16_offset << 16) | (offset & 0xffff);
2092
2093      if (!gp_disp_p)
2094	uvalue = value + offset;
2095      else
2096	uvalue = offset + gp - rel_addr + 4;
2097
2098      hi16_offset = (uvalue >> 16) << 1;
2099      hi16_value = (hi16_addend & (~(howto->dst_mask)))
2100                        | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
2101      bfd_put_32 (input_bfd, hi16_value, hit_data - 4);
2102      offset = (uvalue & 0xffff) << 1;
2103      value = (addend & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
2104      bfd_put_32 (input_bfd, value, hit_data);
2105      return bfd_reloc_ok;
2106
2107    case R_SCORE_GP15:
2108      addend = bfd_get_32 (input_bfd, hit_data);
2109      offset = addend & 0x7fff;
2110      if ((offset & 0x4000) == 0x4000)
2111        offset |= 0xffffc000;
2112      value = value + offset - gp;
2113      if (((value & 0xffffc000) != 0) && ((value & 0xffffc000) != 0xffffc000))
2114        return bfd_reloc_overflow;
2115      value = (addend & ~howto->src_mask) | (value & howto->src_mask);
2116      bfd_put_32 (input_bfd, value, hit_data);
2117      return bfd_reloc_ok;
2118
2119    case R_SCORE_GOT15:
2120    case R_SCORE_CALL15:
2121      if (local_p)
2122	{
2123	  bfd_boolean forced;
2124
2125	  /* The special case is when the symbol is forced to be local.  We need the
2126             full address in the GOT since no R_SCORE_GOT_LO16 relocation follows.  */
2127	  forced = ! score_elf_local_relocation_p (input_bfd, rel,
2128						   local_sections, FALSE);
2129	  value = score_elf_got16_entry (output_bfd, input_bfd, info,
2130					 symbol + addend, forced);
2131	  if (value == MINUS_ONE)
2132	    return bfd_reloc_outofrange;
2133	  value = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
2134						   output_bfd, input_bfd, value);
2135	}
2136      else
2137	{
2138	  value = g;
2139	}
2140
2141      if ((long) value > 0x3fff || (long) value < -0x4000)
2142        return bfd_reloc_overflow;
2143
2144      addend = bfd_get_32 (input_bfd, hit_data);
2145      value = (addend & ~howto->dst_mask) | (value & howto->dst_mask);
2146      bfd_put_32 (input_bfd, value, hit_data);
2147      return bfd_reloc_ok;
2148
2149    case R_SCORE_GPREL32:
2150      value = (addend + symbol - gp);
2151      value &= howto->dst_mask;
2152      bfd_put_32 (input_bfd, value, hit_data);
2153      return bfd_reloc_ok;
2154
2155    case R_SCORE_GOT_LO16:
2156      addend = bfd_get_32 (input_bfd, hit_data);
2157      value = (((addend >> 16) & 0x3) << 14) | ((addend & 0x7fff) >> 1);
2158      value += symbol;
2159      value = (addend & (~(howto->dst_mask))) | ((value & 0x3fff) << 1)
2160               | (((value >> 14) & 0x3) << 16);
2161
2162      bfd_put_32 (input_bfd, value, hit_data);
2163      return bfd_reloc_ok;
2164
2165    case R_SCORE_DUMMY_HI16:
2166      return bfd_reloc_ok;
2167
2168    case R_SCORE_GNU_VTINHERIT:
2169    case R_SCORE_GNU_VTENTRY:
2170      /* We don't do anything with these at present.  */
2171      return bfd_reloc_continue;
2172
2173    default:
2174      return bfd_reloc_notsupported;
2175    }
2176}
2177
2178/* Score backend functions.  */
2179
2180static void
2181_bfd_score_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
2182			  arelent *bfd_reloc,
2183			  Elf_Internal_Rela *elf_reloc)
2184{
2185  unsigned int r_type;
2186
2187  r_type = ELF32_R_TYPE (elf_reloc->r_info);
2188  if (r_type >= NUM_ELEM (elf32_score_howto_table))
2189    bfd_reloc->howto = NULL;
2190  else
2191    bfd_reloc->howto = &elf32_score_howto_table[r_type];
2192}
2193
2194/* Relocate an score ELF section.  */
2195
2196static bfd_boolean
2197_bfd_score_elf_relocate_section (bfd *output_bfd,
2198			         struct bfd_link_info *info,
2199			         bfd *input_bfd,
2200			         asection *input_section,
2201			         bfd_byte *contents,
2202			         Elf_Internal_Rela *relocs,
2203			         Elf_Internal_Sym *local_syms,
2204			         asection **local_sections)
2205{
2206  Elf_Internal_Shdr *symtab_hdr;
2207  struct elf_link_hash_entry **sym_hashes;
2208  Elf_Internal_Rela *rel;
2209  Elf_Internal_Rela *relend;
2210  const char *name;
2211  unsigned long offset;
2212  unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
2213  size_t extsymoff;
2214  bfd_boolean gp_disp_p = FALSE;
2215
2216#ifndef USE_REL
2217  if (info->relocatable)
2218    return TRUE;
2219#endif
2220
2221  /* Sort dynsym.  */
2222  if (elf_hash_table (info)->dynamic_sections_created)
2223    {
2224      bfd_size_type dynsecsymcount = 0;
2225      if (info->shared)
2226	{
2227	  asection * p;
2228	  const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
2229
2230	  for (p = output_bfd->sections; p ; p = p->next)
2231	    if ((p->flags & SEC_EXCLUDE) == 0
2232		&& (p->flags & SEC_ALLOC) != 0
2233		&& !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p))
2234	      ++ dynsecsymcount;
2235	}
2236
2237      if (!score_elf_sort_hash_table (info, dynsecsymcount + 1))
2238	return FALSE;
2239    }
2240
2241  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
2242  extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
2243  sym_hashes = elf_sym_hashes (input_bfd);
2244  rel = relocs;
2245  relend = relocs + input_section->reloc_count;
2246  for (; rel < relend; rel++)
2247    {
2248      int r_type;
2249      reloc_howto_type *howto;
2250      unsigned long r_symndx;
2251      Elf_Internal_Sym *sym;
2252      asection *sec;
2253      struct score_elf_link_hash_entry *h;
2254      bfd_vma relocation = 0;
2255      bfd_reloc_status_type r;
2256      arelent bfd_reloc;
2257
2258      r_symndx = ELF32_R_SYM (rel->r_info);
2259      r_type = ELF32_R_TYPE (rel->r_info);
2260
2261      _bfd_score_info_to_howto (input_bfd, &bfd_reloc, (Elf_Internal_Rela *) rel);
2262      howto = bfd_reloc.howto;
2263
2264      if (info->relocatable)
2265        {
2266          /* This is a relocatable link.  We don't have to change
2267             anything, unless the reloc is against a section symbol,
2268             in which case we have to adjust according to where the
2269             section symbol winds up in the output section.  */
2270          if (r_symndx < symtab_hdr->sh_info)
2271            {
2272              sym = local_syms + r_symndx;
2273              if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2274                {
2275                  sec = local_sections[r_symndx];
2276                  score_elf_add_to_rel (input_bfd, contents + rel->r_offset,
2277                                    howto, (bfd_signed_vma) (sec->output_offset + sym->st_value));
2278                }
2279            }
2280          continue;
2281        }
2282
2283      /* This is a final link.  */
2284      h = NULL;
2285      sym = NULL;
2286      sec = NULL;
2287
2288      if (r_symndx < extsymoff)
2289        {
2290          sym = local_syms + r_symndx;
2291          sec = local_sections[r_symndx];
2292          relocation = (sec->output_section->vma
2293			+ sec->output_offset
2294			+ sym->st_value);
2295          name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, sec);
2296
2297          if ((sec->flags & SEC_MERGE)
2298	      && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2299            {
2300              asection *msec;
2301              bfd_vma addend, value;
2302
2303              switch (r_type)
2304                {
2305                case R_SCORE_HI16:
2306                  break;
2307                case R_SCORE_LO16:
2308                  hi16_addend = bfd_get_32 (input_bfd, contents + rel->r_offset - 4);
2309                  hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
2310                  value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2311                  offset = ((((value >> 16) & 0x3) << 15) | (value & 0x7fff)) >> 1;
2312                  addend = (hi16_offset << 16) | (offset & 0xffff);
2313                  msec = sec;
2314                  addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend);
2315                  addend -= relocation;
2316                  addend += msec->output_section->vma + msec->output_offset;
2317                  uvalue = addend;
2318                  hi16_offset = (uvalue >> 16) << 1;
2319                  hi16_value = (hi16_addend & (~(howto->dst_mask)))
2320                    | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
2321                  bfd_put_32 (input_bfd, hi16_value, contents + rel->r_offset - 4);
2322                  offset = (uvalue & 0xffff) << 1;
2323                  value = (value & (~(howto->dst_mask)))
2324                    | (offset & 0x7fff) | ((offset << 1) & 0x30000);
2325                  bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2326                  break;
2327                case R_SCORE_GOT_LO16:
2328                  value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2329                  addend = (((value >> 16) & 0x3) << 14) | ((value & 0x7fff) >> 1);
2330                  msec = sec;
2331                  addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
2332                  addend += msec->output_section->vma + msec->output_offset;
2333                  value = (value & (~(howto->dst_mask))) | ((addend & 0x3fff) << 1)
2334                           | (((addend >> 14) & 0x3) << 16);
2335
2336                  bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2337                  break;
2338                default:
2339                  value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2340                  /* Get the (signed) value from the instruction.  */
2341                  addend = value & howto->src_mask;
2342                  if (addend & ((howto->src_mask + 1) >> 1))
2343                    {
2344                      bfd_signed_vma mask;
2345
2346                      mask = -1;
2347                      mask &= ~howto->src_mask;
2348                      addend |= mask;
2349                    }
2350                  msec = sec;
2351                  addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
2352                  addend += msec->output_section->vma + msec->output_offset;
2353                  value = (value & ~howto->dst_mask) | (addend & howto->dst_mask);
2354                  bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2355                  break;
2356                }
2357            }
2358        }
2359      else
2360        {
2361	  /* For global symbols we look up the symbol in the hash-table.  */
2362	  h = ((struct score_elf_link_hash_entry *)
2363	       elf_sym_hashes (input_bfd) [r_symndx - extsymoff]);
2364	  /* Find the real hash-table entry for this symbol.  */
2365	  while (h->root.root.type == bfd_link_hash_indirect
2366		 || h->root.root.type == bfd_link_hash_warning)
2367	    h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
2368
2369	  /* Record the name of this symbol, for our caller.  */
2370	  name = h->root.root.root.string;
2371
2372	  /* See if this is the special GP_DISP_LABEL symbol.  Note that such a
2373	     symbol must always be a global symbol.  */
2374	  if (strcmp (name, GP_DISP_LABEL) == 0)
2375	    {
2376	      /* Relocations against GP_DISP_LABEL are permitted only with
2377		 R_SCORE_HI16 and R_SCORE_LO16 relocations.  */
2378	      if (r_type != R_SCORE_HI16 && r_type != R_SCORE_LO16)
2379		return bfd_reloc_notsupported;
2380
2381	      gp_disp_p = TRUE;
2382	    }
2383
2384	  /* If this symbol is defined, calculate its address.  Note that
2385	      GP_DISP_LABEL is a magic symbol, always implicitly defined by the
2386	      linker, so it's inappropriate to check to see whether or not
2387	      its defined.  */
2388	  else if ((h->root.root.type == bfd_link_hash_defined
2389		    || h->root.root.type == bfd_link_hash_defweak)
2390		   && h->root.root.u.def.section)
2391	    {
2392	      sec = h->root.root.u.def.section;
2393	      if (sec->output_section)
2394		relocation = (h->root.root.u.def.value
2395			      + sec->output_section->vma
2396			      + sec->output_offset);
2397	      else
2398		{
2399		  relocation = h->root.root.u.def.value;
2400		}
2401	    }
2402	  else if (h->root.root.type == bfd_link_hash_undefweak)
2403	    /* We allow relocations against undefined weak symbols, giving
2404	       it the value zero, so that you can undefined weak functions
2405	       and check to see if they exist by looking at their addresses.  */
2406	    relocation = 0;
2407	  else if (info->unresolved_syms_in_objects == RM_IGNORE
2408		   && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
2409	    relocation = 0;
2410	  else if (strcmp (name, "_DYNAMIC_LINK") == 0)
2411	    {
2412	      /* If this is a dynamic link, we should have created a _DYNAMIC_LINK symbol
2413	         in _bfd_score_elf_create_dynamic_sections.  Otherwise, we should define
2414                 the symbol with a value of 0.  */
2415	      BFD_ASSERT (! info->shared);
2416	      BFD_ASSERT (bfd_get_section_by_name (output_bfd, ".dynamic") == NULL);
2417	      relocation = 0;
2418	    }
2419	  else
2420	    {
2421	      if (! ((*info->callbacks->undefined_symbol)
2422		     (info, h->root.root.root.string, input_bfd,
2423		      input_section, rel->r_offset,
2424		      (info->unresolved_syms_in_objects == RM_GENERATE_ERROR)
2425		      || ELF_ST_VISIBILITY (h->root.other))))
2426		return bfd_reloc_undefined;
2427	      relocation = 0;
2428	    }
2429        }
2430
2431      r = score_elf_final_link_relocate (howto, input_bfd, output_bfd,
2432                                         input_section, contents, rel, relocs,
2433                                         relocation, info, name,
2434                                         (h ? ELF_ST_TYPE ((unsigned int)h->root.root.type) :
2435					 ELF_ST_TYPE ((unsigned int)sym->st_info)), h, local_sections,
2436                                         gp_disp_p);
2437
2438      if (r != bfd_reloc_ok)
2439        {
2440          const char *msg = (const char *)0;
2441
2442          switch (r)
2443            {
2444            case bfd_reloc_overflow:
2445              /* If the overflowing reloc was to an undefined symbol,
2446                 we have already printed one error message and there
2447                 is no point complaining again.  */
2448              if (((!h) || (h->root.root.type != bfd_link_hash_undefined))
2449                  && (!((*info->callbacks->reloc_overflow)
2450                        (info, NULL, name, howto->name, (bfd_vma) 0,
2451                         input_bfd, input_section, rel->r_offset))))
2452                return FALSE;
2453              break;
2454            case bfd_reloc_undefined:
2455              if (!((*info->callbacks->undefined_symbol)
2456                    (info, name, input_bfd, input_section, rel->r_offset, TRUE)))
2457                return FALSE;
2458              break;
2459
2460            case bfd_reloc_outofrange:
2461              msg = _("internal error: out of range error");
2462              goto common_error;
2463
2464            case bfd_reloc_notsupported:
2465              msg = _("internal error: unsupported relocation error");
2466              goto common_error;
2467
2468            case bfd_reloc_dangerous:
2469              msg = _("internal error: dangerous error");
2470              goto common_error;
2471
2472            default:
2473              msg = _("internal error: unknown error");
2474              /* fall through */
2475
2476            common_error:
2477              if (!((*info->callbacks->warning)
2478                    (info, msg, name, input_bfd, input_section, rel->r_offset)))
2479                return FALSE;
2480              break;
2481            }
2482        }
2483    }
2484
2485  return TRUE;
2486}
2487
2488/* Look through the relocs for a section during the first phase, and
2489   allocate space in the global offset table.  */
2490
2491static bfd_boolean
2492_bfd_score_elf_check_relocs (bfd *abfd,
2493			     struct bfd_link_info *info,
2494			     asection *sec,
2495			     const Elf_Internal_Rela *relocs)
2496{
2497  const char *name;
2498  bfd *dynobj;
2499  Elf_Internal_Shdr *symtab_hdr;
2500  struct elf_link_hash_entry **sym_hashes;
2501  struct score_got_info *g;
2502  size_t extsymoff;
2503  const Elf_Internal_Rela *rel;
2504  const Elf_Internal_Rela *rel_end;
2505  asection *sgot;
2506  asection *sreloc;
2507  const struct elf_backend_data *bed;
2508
2509  if (info->relocatable)
2510    return TRUE;
2511
2512  dynobj = elf_hash_table (info)->dynobj;
2513  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2514  sym_hashes = elf_sym_hashes (abfd);
2515  extsymoff = (elf_bad_symtab (abfd)) ? 0 : symtab_hdr->sh_info;
2516
2517  name = bfd_get_section_name (abfd, sec);
2518
2519  if (dynobj == NULL)
2520    {
2521      sgot = NULL;
2522      g = NULL;
2523    }
2524  else
2525    {
2526      sgot = score_elf_got_section (dynobj, FALSE);
2527      if (sgot == NULL)
2528        g = NULL;
2529      else
2530        {
2531          BFD_ASSERT (score_elf_section_data (sgot) != NULL);
2532          g = score_elf_section_data (sgot)->u.got_info;
2533          BFD_ASSERT (g != NULL);
2534        }
2535    }
2536
2537  sreloc = NULL;
2538  bed = get_elf_backend_data (abfd);
2539  rel_end = relocs + sec->reloc_count * bed->s->int_rels_per_ext_rel;
2540  for (rel = relocs; rel < rel_end; ++rel)
2541    {
2542      unsigned long r_symndx;
2543      unsigned int r_type;
2544      struct elf_link_hash_entry *h;
2545
2546      r_symndx = ELF32_R_SYM (rel->r_info);
2547      r_type = ELF32_R_TYPE (rel->r_info);
2548
2549      if (r_symndx < extsymoff)
2550	{
2551          h = NULL;
2552	}
2553      else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr))
2554        {
2555          (*_bfd_error_handler) (_("%s: Malformed reloc detected for section %s"), abfd, name);
2556          bfd_set_error (bfd_error_bad_value);
2557          return FALSE;
2558        }
2559      else
2560        {
2561          h = sym_hashes[r_symndx - extsymoff];
2562
2563          /* This may be an indirect symbol created because of a version.  */
2564          if (h != NULL)
2565            {
2566              while (h->root.type == bfd_link_hash_indirect)
2567                h = (struct elf_link_hash_entry *)h->root.u.i.link;
2568            }
2569        }
2570
2571      /* Some relocs require a global offset table.  */
2572      if (dynobj == NULL || sgot == NULL)
2573        {
2574          switch (r_type)
2575            {
2576            case R_SCORE_GOT15:
2577            case R_SCORE_CALL15:
2578              if (dynobj == NULL)
2579                elf_hash_table (info)->dynobj = dynobj = abfd;
2580              if (!score_elf_create_got_section (dynobj, info, FALSE))
2581                return FALSE;
2582              g = score_elf_got_info (dynobj, &sgot);
2583              break;
2584            case R_SCORE_ABS32:
2585            case R_SCORE_REL32:
2586              if (dynobj == NULL && (info->shared || h != NULL) && (sec->flags & SEC_ALLOC) != 0)
2587                elf_hash_table (info)->dynobj = dynobj = abfd;
2588              break;
2589            default:
2590              break;
2591            }
2592        }
2593
2594      if (!h && (r_type == R_SCORE_GOT_LO16))
2595        {
2596	  if (! score_elf_record_local_got_symbol (abfd, r_symndx, rel->r_addend, g))
2597	    return FALSE;
2598        }
2599
2600      switch (r_type)
2601        {
2602        case R_SCORE_CALL15:
2603	  if (h == NULL)
2604	    {
2605	      (*_bfd_error_handler)
2606		(_("%B: CALL15 reloc at 0x%lx not against global symbol"),
2607		 abfd, (unsigned long) rel->r_offset);
2608	      bfd_set_error (bfd_error_bad_value);
2609	      return FALSE;
2610	    }
2611	  else
2612	    {
2613	      /* This symbol requires a global offset table entry.  */
2614	      if (! score_elf_record_global_got_symbol (h, abfd, info, g))
2615		return FALSE;
2616
2617	      /* We need a stub, not a plt entry for the undefined function.  But we record
2618                 it as if it needs plt.  See _bfd_elf_adjust_dynamic_symbol.  */
2619	      h->needs_plt = 1;
2620	      h->type = STT_FUNC;
2621	    }
2622          break;
2623	case R_SCORE_GOT15:
2624	  if (h && ! score_elf_record_global_got_symbol (h, abfd, info, g))
2625	    return FALSE;
2626	  break;
2627        case R_SCORE_ABS32:
2628        case R_SCORE_REL32:
2629	  if ((info->shared || h != NULL) && (sec->flags & SEC_ALLOC) != 0)
2630	    {
2631	      if (sreloc == NULL)
2632		{
2633		  sreloc = score_elf_rel_dyn_section (dynobj, TRUE);
2634		  if (sreloc == NULL)
2635		    return FALSE;
2636		}
2637#define SCORE_READONLY_SECTION (SEC_ALLOC | SEC_LOAD | SEC_READONLY)
2638	      if (info->shared)
2639		{
2640		  /* When creating a shared object, we must copy these reloc types into
2641                     the output file as R_SCORE_REL32 relocs.  We make room for this reloc
2642                     in the .rel.dyn reloc section.  */
2643		  score_elf_allocate_dynamic_relocations (dynobj, 1);
2644		  if ((sec->flags & SCORE_READONLY_SECTION)
2645		      == SCORE_READONLY_SECTION)
2646		    /* We tell the dynamic linker that there are
2647		       relocations against the text segment.  */
2648		    info->flags |= DF_TEXTREL;
2649		}
2650	      else
2651		{
2652		  struct score_elf_link_hash_entry *hscore;
2653
2654		  /* We only need to copy this reloc if the symbol is
2655                     defined in a dynamic object.  */
2656		  hscore = (struct score_elf_link_hash_entry *)h;
2657		  ++hscore->possibly_dynamic_relocs;
2658		  if ((sec->flags & SCORE_READONLY_SECTION)
2659		      == SCORE_READONLY_SECTION)
2660		    /* We need it to tell the dynamic linker if there
2661		       are relocations against the text segment.  */
2662		    hscore->readonly_reloc = TRUE;
2663		}
2664
2665	      /* Even though we don't directly need a GOT entry for this symbol,
2666                 a symbol must have a dynamic symbol table index greater that
2667                 DT_SCORE_GOTSYM if there are dynamic relocations against it.  */
2668	      if (h != NULL)
2669		{
2670		  if (dynobj == NULL)
2671		    elf_hash_table (info)->dynobj = dynobj = abfd;
2672		  if (! score_elf_create_got_section (dynobj, info, TRUE))
2673		    return FALSE;
2674		  g = score_elf_got_info (dynobj, &sgot);
2675		  if (! score_elf_record_global_got_symbol (h, abfd, info, g))
2676		    return FALSE;
2677		}
2678	    }
2679	  break;
2680
2681          /* This relocation describes the C++ object vtable hierarchy.
2682             Reconstruct it for later use during GC.  */
2683        case R_SCORE_GNU_VTINHERIT:
2684          if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
2685            return FALSE;
2686          break;
2687
2688          /* This relocation describes which C++ vtable entries are actually
2689             used.  Record for later use during GC.  */
2690        case R_SCORE_GNU_VTENTRY:
2691          if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
2692            return FALSE;
2693          break;
2694        default:
2695          break;
2696        }
2697
2698      /* We must not create a stub for a symbol that has relocations
2699         related to taking the function's address.  */
2700      switch (r_type)
2701	{
2702	default:
2703	  if (h != NULL)
2704	    {
2705	      struct score_elf_link_hash_entry *sh;
2706
2707	      sh = (struct score_elf_link_hash_entry *) h;
2708	      sh->no_fn_stub = TRUE;
2709	    }
2710	  break;
2711	case R_SCORE_CALL15:
2712	  break;
2713	}
2714    }
2715
2716  return TRUE;
2717}
2718
2719static bfd_boolean
2720_bfd_score_elf_add_symbol_hook (bfd *abfd,
2721				struct bfd_link_info *info ATTRIBUTE_UNUSED,
2722				Elf_Internal_Sym *sym,
2723				const char **namep ATTRIBUTE_UNUSED,
2724				flagword *flagsp ATTRIBUTE_UNUSED,
2725				asection **secp,
2726				bfd_vma *valp)
2727{
2728  switch (sym->st_shndx)
2729    {
2730    case SHN_COMMON:
2731      if (sym->st_size > elf_gp_size (abfd))
2732        break;
2733      /* Fall through.  */
2734    case SHN_SCORE_SCOMMON:
2735      *secp = bfd_make_section_old_way (abfd, ".scommon");
2736      (*secp)->flags |= SEC_IS_COMMON;
2737      *valp = sym->st_size;
2738      break;
2739    }
2740
2741  return TRUE;
2742}
2743
2744static void
2745_bfd_score_elf_symbol_processing (bfd *abfd, asymbol *asym)
2746{
2747  elf_symbol_type *elfsym;
2748
2749  elfsym = (elf_symbol_type *) asym;
2750  switch (elfsym->internal_elf_sym.st_shndx)
2751    {
2752    case SHN_COMMON:
2753      if (asym->value > elf_gp_size (abfd))
2754        break;
2755      /* Fall through.  */
2756    case SHN_SCORE_SCOMMON:
2757      if (score_elf_scom_section.name == NULL)
2758        {
2759          /* Initialize the small common section.  */
2760          score_elf_scom_section.name = ".scommon";
2761          score_elf_scom_section.flags = SEC_IS_COMMON;
2762          score_elf_scom_section.output_section = &score_elf_scom_section;
2763          score_elf_scom_section.symbol = &score_elf_scom_symbol;
2764          score_elf_scom_section.symbol_ptr_ptr = &score_elf_scom_symbol_ptr;
2765          score_elf_scom_symbol.name = ".scommon";
2766          score_elf_scom_symbol.flags = BSF_SECTION_SYM;
2767          score_elf_scom_symbol.section = &score_elf_scom_section;
2768          score_elf_scom_symbol_ptr = &score_elf_scom_symbol;
2769        }
2770      asym->section = &score_elf_scom_section;
2771      asym->value = elfsym->internal_elf_sym.st_size;
2772      break;
2773    }
2774}
2775
2776static bfd_boolean
2777_bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
2778     const char *name ATTRIBUTE_UNUSED,
2779     Elf_Internal_Sym *sym,
2780     asection *input_sec,
2781     struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
2782{
2783  /* If we see a common symbol, which implies a relocatable link, then
2784     if a symbol was small common in an input file, mark it as small
2785     common in the output file.  */
2786  if (sym->st_shndx == SHN_COMMON && strcmp (input_sec->name, ".scommon") == 0)
2787    sym->st_shndx = SHN_SCORE_SCOMMON;
2788
2789  return TRUE;
2790}
2791
2792static bfd_boolean
2793_bfd_score_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
2794					 asection *sec,
2795					 int *retval)
2796{
2797  if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
2798    {
2799      *retval = SHN_SCORE_SCOMMON;
2800      return TRUE;
2801    }
2802
2803  return FALSE;
2804}
2805
2806/* Adjust a symbol defined by a dynamic object and referenced by a
2807   regular object.  The current definition is in some section of the
2808   dynamic object, but we're not including those sections.  We have to
2809   change the definition to something the rest of the link can understand.  */
2810
2811static bfd_boolean
2812_bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
2813				      struct elf_link_hash_entry *h)
2814{
2815  bfd *dynobj;
2816  struct score_elf_link_hash_entry *hscore;
2817  asection *s;
2818
2819  dynobj = elf_hash_table (info)->dynobj;
2820
2821  /* Make sure we know what is going on here.  */
2822  BFD_ASSERT (dynobj != NULL
2823              && (h->needs_plt
2824                  || h->u.weakdef != NULL
2825                  || (h->def_dynamic && h->ref_regular && !h->def_regular)));
2826
2827  /* If this symbol is defined in a dynamic object, we need to copy
2828     any R_SCORE_ABS32 or R_SCORE_REL32 relocs against it into the output
2829     file.  */
2830  hscore = (struct score_elf_link_hash_entry *)h;
2831  if (!info->relocatable
2832      && hscore->possibly_dynamic_relocs != 0
2833      && (h->root.type == bfd_link_hash_defweak || !h->def_regular))
2834    {
2835      score_elf_allocate_dynamic_relocations (dynobj, hscore->possibly_dynamic_relocs);
2836      if (hscore->readonly_reloc)
2837        /* We tell the dynamic linker that there are relocations
2838           against the text segment.  */
2839        info->flags |= DF_TEXTREL;
2840    }
2841
2842  /* For a function, create a stub, if allowed.  */
2843  if (!hscore->no_fn_stub && h->needs_plt)
2844    {
2845      if (!elf_hash_table (info)->dynamic_sections_created)
2846        return TRUE;
2847
2848      /* If this symbol is not defined in a regular file, then set
2849         the symbol to the stub location.  This is required to make
2850         function pointers compare as equal between the normal
2851         executable and the shared library.  */
2852      if (!h->def_regular)
2853        {
2854          /* We need .stub section.  */
2855          s = bfd_get_section_by_name (dynobj, SCORE_ELF_STUB_SECTION_NAME);
2856          BFD_ASSERT (s != NULL);
2857
2858          h->root.u.def.section = s;
2859          h->root.u.def.value = s->size;
2860
2861          /* XXX Write this stub address somewhere.  */
2862          h->plt.offset = s->size;
2863
2864          /* Make room for this stub code.  */
2865          s->size += SCORE_FUNCTION_STUB_SIZE;
2866
2867          /* The last half word of the stub will be filled with the index
2868             of this symbol in .dynsym section.  */
2869          return TRUE;
2870        }
2871    }
2872  else if ((h->type == STT_FUNC) && !h->needs_plt)
2873    {
2874      /* This will set the entry for this symbol in the GOT to 0, and
2875         the dynamic linker will take care of this.  */
2876      h->root.u.def.value = 0;
2877      return TRUE;
2878    }
2879
2880  /* If this is a weak symbol, and there is a real definition, the
2881     processor independent code will have arranged for us to see the
2882     real definition first, and we can just use the same value.  */
2883  if (h->u.weakdef != NULL)
2884    {
2885      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2886                  || h->u.weakdef->root.type == bfd_link_hash_defweak);
2887      h->root.u.def.section = h->u.weakdef->root.u.def.section;
2888      h->root.u.def.value = h->u.weakdef->root.u.def.value;
2889      return TRUE;
2890    }
2891
2892  /* This is a reference to a symbol defined by a dynamic object which
2893     is not a function.  */
2894  return TRUE;
2895}
2896
2897/* This function is called after all the input files have been read,
2898   and the input sections have been assigned to output sections.  */
2899
2900static bfd_boolean
2901_bfd_score_elf_always_size_sections (bfd *output_bfd,
2902				     struct bfd_link_info *info)
2903{
2904  bfd *dynobj;
2905  asection *s;
2906  struct score_got_info *g;
2907  int i;
2908  bfd_size_type loadable_size = 0;
2909  bfd_size_type local_gotno;
2910  bfd *sub;
2911
2912  dynobj = elf_hash_table (info)->dynobj;
2913  if (dynobj == NULL)
2914    /* Relocatable links don't have it.  */
2915    return TRUE;
2916
2917  g = score_elf_got_info (dynobj, &s);
2918  if (s == NULL)
2919    return TRUE;
2920
2921  /* Calculate the total loadable size of the output.  That will give us the
2922     maximum number of GOT_PAGE entries required.  */
2923  for (sub = info->input_bfds; sub; sub = sub->link_next)
2924    {
2925      asection *subsection;
2926
2927      for (subsection = sub->sections;
2928	   subsection;
2929	   subsection = subsection->next)
2930	{
2931	  if ((subsection->flags & SEC_ALLOC) == 0)
2932	    continue;
2933	  loadable_size += ((subsection->size + 0xf)
2934			    &~ (bfd_size_type) 0xf);
2935	}
2936    }
2937
2938  /* There has to be a global GOT entry for every symbol with
2939     a dynamic symbol table index of DT_SCORE_GOTSYM or
2940     higher.  Therefore, it make sense to put those symbols
2941     that need GOT entries at the end of the symbol table.  We
2942     do that here.  */
2943  if (! score_elf_sort_hash_table (info, 1))
2944    return FALSE;
2945
2946  if (g->global_gotsym != NULL)
2947    i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx;
2948  else
2949    /* If there are no global symbols, or none requiring
2950       relocations, then GLOBAL_GOTSYM will be NULL.  */
2951    i = 0;
2952
2953  /* In the worst case, we'll get one stub per dynamic symbol.  */
2954  loadable_size += SCORE_FUNCTION_STUB_SIZE * i;
2955
2956  /* Assume there are two loadable segments consisting of
2957     contiguous sections.  Is 5 enough?  */
2958  local_gotno = (loadable_size >> 16) + 5;
2959
2960  g->local_gotno += local_gotno;
2961  s->size += g->local_gotno * SCORE_ELF_GOT_SIZE (output_bfd);
2962
2963  g->global_gotno = i;
2964  s->size += i * SCORE_ELF_GOT_SIZE (output_bfd);
2965
2966  score_elf_resolve_final_got_entries (g);
2967
2968  if (s->size > SCORE_ELF_GOT_MAX_SIZE (output_bfd))
2969    {
2970      /* Fixme. Error message or Warning message should be issued here.  */
2971    }
2972
2973  return TRUE;
2974}
2975
2976/* Set the sizes of the dynamic sections.  */
2977
2978static bfd_boolean
2979_bfd_score_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
2980{
2981  bfd *dynobj;
2982  asection *s;
2983  bfd_boolean reltext;
2984
2985  dynobj = elf_hash_table (info)->dynobj;
2986  BFD_ASSERT (dynobj != NULL);
2987
2988  if (elf_hash_table (info)->dynamic_sections_created)
2989    {
2990      /* Set the contents of the .interp section to the interpreter.  */
2991      if (!info->shared)
2992        {
2993          s = bfd_get_section_by_name (dynobj, ".interp");
2994          BFD_ASSERT (s != NULL);
2995          s->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
2996          s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
2997        }
2998    }
2999
3000  /* The check_relocs and adjust_dynamic_symbol entry points have
3001     determined the sizes of the various dynamic sections.  Allocate
3002     memory for them.  */
3003  reltext = FALSE;
3004  for (s = dynobj->sections; s != NULL; s = s->next)
3005    {
3006      const char *name;
3007
3008      if ((s->flags & SEC_LINKER_CREATED) == 0)
3009        continue;
3010
3011      /* It's OK to base decisions on the section name, because none
3012         of the dynobj section names depend upon the input files.  */
3013      name = bfd_get_section_name (dynobj, s);
3014
3015      if (CONST_STRNEQ (name, ".rel"))
3016        {
3017          if (s->size == 0)
3018            {
3019              /* We only strip the section if the output section name
3020                 has the same name.  Otherwise, there might be several
3021                 input sections for this output section.  FIXME: This
3022                 code is probably not needed these days anyhow, since
3023                 the linker now does not create empty output sections.  */
3024              if (s->output_section != NULL
3025                  && strcmp (name,
3026                             bfd_get_section_name (s->output_section->owner,
3027                                                   s->output_section)) == 0)
3028                s->flags |= SEC_EXCLUDE;
3029            }
3030          else
3031            {
3032              const char *outname;
3033              asection *target;
3034
3035              /* If this relocation section applies to a read only
3036                 section, then we probably need a DT_TEXTREL entry.
3037                 If the relocation section is .rel.dyn, we always
3038                 assert a DT_TEXTREL entry rather than testing whether
3039                 there exists a relocation to a read only section or
3040                 not.  */
3041              outname = bfd_get_section_name (output_bfd, s->output_section);
3042              target = bfd_get_section_by_name (output_bfd, outname + 4);
3043              if ((target != NULL
3044                   && (target->flags & SEC_READONLY) != 0
3045                   && (target->flags & SEC_ALLOC) != 0) || strcmp (outname, ".rel.dyn") == 0)
3046                reltext = TRUE;
3047
3048              /* We use the reloc_count field as a counter if we need
3049                 to copy relocs into the output file.  */
3050              if (strcmp (name, ".rel.dyn") != 0)
3051                s->reloc_count = 0;
3052            }
3053        }
3054      else if (CONST_STRNEQ (name, ".got"))
3055        {
3056	  /* _bfd_score_elf_always_size_sections() has already done
3057	     most of the work, but some symbols may have been mapped
3058	     to versions that we must now resolve in the got_entries
3059	     hash tables.  */
3060        }
3061      else if (strcmp (name, SCORE_ELF_STUB_SECTION_NAME) == 0)
3062        {
3063          /* IRIX rld assumes that the function stub isn't at the end
3064             of .text section. So put a dummy. XXX  */
3065          s->size += SCORE_FUNCTION_STUB_SIZE;
3066        }
3067      else if (! CONST_STRNEQ (name, ".init"))
3068        {
3069          /* It's not one of our sections, so don't allocate space.  */
3070          continue;
3071        }
3072
3073      /* Allocate memory for the section contents.  */
3074      s->contents = bfd_zalloc (dynobj, s->size);
3075      if (s->contents == NULL && s->size != 0)
3076        {
3077          bfd_set_error (bfd_error_no_memory);
3078          return FALSE;
3079        }
3080    }
3081
3082  if (elf_hash_table (info)->dynamic_sections_created)
3083    {
3084      /* Add some entries to the .dynamic section.  We fill in the
3085	 values later, in _bfd_score_elf_finish_dynamic_sections, but we
3086	 must add the entries now so that we get the correct size for
3087	 the .dynamic section.  The DT_DEBUG entry is filled in by the
3088	 dynamic linker and used by the debugger.  */
3089
3090      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0))
3091	return FALSE;
3092
3093      if (reltext)
3094	info->flags |= DF_TEXTREL;
3095
3096      if ((info->flags & DF_TEXTREL) != 0)
3097	{
3098	  if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0))
3099	    return FALSE;
3100	}
3101
3102      if (! SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTGOT, 0))
3103	return FALSE;
3104
3105      if (score_elf_rel_dyn_section (dynobj, FALSE))
3106	{
3107	  if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_REL, 0))
3108	    return FALSE;
3109
3110	  if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELSZ, 0))
3111	    return FALSE;
3112
3113	  if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELENT, 0))
3114	    return FALSE;
3115	}
3116
3117      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_BASE_ADDRESS, 0))
3118        return FALSE;
3119
3120      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_LOCAL_GOTNO, 0))
3121        return FALSE;
3122
3123      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_SYMTABNO, 0))
3124        return FALSE;
3125
3126      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_UNREFEXTNO, 0))
3127        return FALSE;
3128
3129      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_GOTSYM, 0))
3130        return FALSE;
3131
3132      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_HIPAGENO, 0))
3133	return FALSE;
3134    }
3135
3136  return TRUE;
3137}
3138
3139static bfd_boolean
3140_bfd_score_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
3141{
3142  struct elf_link_hash_entry *h;
3143  struct bfd_link_hash_entry *bh;
3144  flagword flags;
3145  asection *s;
3146
3147  flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
3148           | SEC_LINKER_CREATED | SEC_READONLY);
3149
3150  /* ABI requests the .dynamic section to be read only.  */
3151  s = bfd_get_section_by_name (abfd, ".dynamic");
3152  if (s != NULL)
3153    {
3154      if (!bfd_set_section_flags (abfd, s, flags))
3155        return FALSE;
3156    }
3157
3158  /* We need to create .got section.  */
3159  if (!score_elf_create_got_section (abfd, info, FALSE))
3160    return FALSE;
3161
3162  if (!score_elf_rel_dyn_section (elf_hash_table (info)->dynobj, TRUE))
3163    return FALSE;
3164
3165  /* Create .stub section.  */
3166  if (bfd_get_section_by_name (abfd, SCORE_ELF_STUB_SECTION_NAME) == NULL)
3167    {
3168      s = bfd_make_section_with_flags (abfd, SCORE_ELF_STUB_SECTION_NAME,
3169                                       flags | SEC_CODE);
3170      if (s == NULL
3171          || !bfd_set_section_alignment (abfd, s, 2))
3172
3173        return FALSE;
3174    }
3175
3176  if (!info->shared)
3177    {
3178      const char *name;
3179
3180      name = "_DYNAMIC_LINK";
3181      bh = NULL;
3182      if (!(_bfd_generic_link_add_one_symbol
3183            (info, abfd, name, BSF_GLOBAL, bfd_abs_section_ptr,
3184             (bfd_vma) 0, (const char *)NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
3185        return FALSE;
3186
3187      h = (struct elf_link_hash_entry *)bh;
3188      h->non_elf = 0;
3189      h->def_regular = 1;
3190      h->type = STT_SECTION;
3191
3192      if (!bfd_elf_link_record_dynamic_symbol (info, h))
3193        return FALSE;
3194    }
3195
3196  return TRUE;
3197}
3198
3199
3200/* Finish up dynamic symbol handling.  We set the contents of various
3201   dynamic sections here.  */
3202
3203static bfd_boolean
3204_bfd_score_elf_finish_dynamic_symbol (bfd *output_bfd,
3205				      struct bfd_link_info *info,
3206				      struct elf_link_hash_entry *h,
3207				      Elf_Internal_Sym *sym)
3208{
3209  bfd *dynobj;
3210  asection *sgot;
3211  struct score_got_info *g;
3212  const char *name;
3213
3214  dynobj = elf_hash_table (info)->dynobj;
3215
3216  if (h->plt.offset != MINUS_ONE)
3217    {
3218      asection *s;
3219      bfd_byte stub[SCORE_FUNCTION_STUB_SIZE];
3220
3221      /* This symbol has a stub.  Set it up.  */
3222      BFD_ASSERT (h->dynindx != -1);
3223
3224      s = bfd_get_section_by_name (dynobj, SCORE_ELF_STUB_SECTION_NAME);
3225      BFD_ASSERT (s != NULL);
3226
3227      /* FIXME: Can h->dynindex be more than 64K?  */
3228      if (h->dynindx & 0xffff0000)
3229	return FALSE;
3230
3231      /* Fill the stub.  */
3232      bfd_put_32 (output_bfd, STUB_LW, stub);
3233      bfd_put_32 (output_bfd, STUB_MOVE, stub + 4);
3234      bfd_put_32 (output_bfd, STUB_LI16 | (h->dynindx << 1), stub + 8);
3235      bfd_put_32 (output_bfd, STUB_BRL, stub + 12);
3236
3237      BFD_ASSERT (h->plt.offset <= s->size);
3238      memcpy (s->contents + h->plt.offset, stub, SCORE_FUNCTION_STUB_SIZE);
3239
3240      /* Mark the symbol as undefined.  plt.offset != -1 occurs
3241	 only for the referenced symbol.  */
3242      sym->st_shndx = SHN_UNDEF;
3243
3244      /* The run-time linker uses the st_value field of the symbol
3245	  to reset the global offset table entry for this external
3246	  to its stub address when unlinking a shared object.  */
3247      sym->st_value = (s->output_section->vma + s->output_offset + h->plt.offset);
3248    }
3249
3250  BFD_ASSERT (h->dynindx != -1 || h->forced_local);
3251
3252  sgot = score_elf_got_section (dynobj, FALSE);
3253  BFD_ASSERT (sgot != NULL);
3254  BFD_ASSERT (score_elf_section_data (sgot) != NULL);
3255  g = score_elf_section_data (sgot)->u.got_info;
3256  BFD_ASSERT (g != NULL);
3257
3258  /* Run through the global symbol table, creating GOT entries for all
3259     the symbols that need them.  */
3260  if (g->global_gotsym != NULL && h->dynindx >= g->global_gotsym->dynindx)
3261    {
3262      bfd_vma offset;
3263      bfd_vma value;
3264
3265      value = sym->st_value;
3266      offset = score_elf_global_got_index (dynobj, h);
3267      bfd_put_32 (output_bfd, value, sgot->contents + offset);
3268    }
3269
3270  /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
3271  name = h->root.root.string;
3272  if (strcmp (name, "_DYNAMIC") == 0 || strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
3273    sym->st_shndx = SHN_ABS;
3274  else if (strcmp (name, "_DYNAMIC_LINK") == 0)
3275    {
3276      sym->st_shndx = SHN_ABS;
3277      sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
3278      sym->st_value = 1;
3279    }
3280  else if (strcmp (name, GP_DISP_LABEL) == 0)
3281    {
3282      sym->st_shndx = SHN_ABS;
3283      sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
3284      sym->st_value = elf_gp (output_bfd);
3285    }
3286
3287  return TRUE;
3288}
3289
3290/* Finish up the dynamic sections.  */
3291
3292static bfd_boolean
3293_bfd_score_elf_finish_dynamic_sections (bfd *output_bfd,
3294				        struct bfd_link_info *info)
3295{
3296  bfd *dynobj;
3297  asection *sdyn;
3298  asection *sgot;
3299  asection *s;
3300  struct score_got_info *g;
3301
3302  dynobj = elf_hash_table (info)->dynobj;
3303
3304  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
3305
3306  sgot = score_elf_got_section (dynobj, FALSE);
3307  if (sgot == NULL)
3308    g = NULL;
3309  else
3310    {
3311      BFD_ASSERT (score_elf_section_data (sgot) != NULL);
3312      g = score_elf_section_data (sgot)->u.got_info;
3313      BFD_ASSERT (g != NULL);
3314    }
3315
3316  if (elf_hash_table (info)->dynamic_sections_created)
3317    {
3318      bfd_byte *b;
3319
3320      BFD_ASSERT (sdyn != NULL);
3321      BFD_ASSERT (g != NULL);
3322
3323      for (b = sdyn->contents;
3324	   b < sdyn->contents + sdyn->size;
3325	   b += SCORE_ELF_DYN_SIZE (dynobj))
3326	{
3327	  Elf_Internal_Dyn dyn;
3328	  const char *name;
3329	  size_t elemsize;
3330	  bfd_boolean swap_out_p;
3331
3332	  /* Read in the current dynamic entry.  */
3333	  (*get_elf_backend_data (dynobj)->s->swap_dyn_in) (dynobj, b, &dyn);
3334
3335	  /* Assume that we're going to modify it and write it out.  */
3336	  swap_out_p = TRUE;
3337
3338	  switch (dyn.d_tag)
3339	    {
3340	    case DT_RELENT:
3341	      s = score_elf_rel_dyn_section (dynobj, FALSE);
3342	      BFD_ASSERT (s != NULL);
3343	      dyn.d_un.d_val = SCORE_ELF_REL_SIZE (dynobj);
3344	      break;
3345
3346	    case DT_STRSZ:
3347	      /* Rewrite DT_STRSZ.  */
3348	      dyn.d_un.d_val = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
3349		    break;
3350
3351	    case DT_PLTGOT:
3352	      name = ".got";
3353	      s = bfd_get_section_by_name (output_bfd, name);
3354	      BFD_ASSERT (s != NULL);
3355	      dyn.d_un.d_ptr = s->vma;
3356	      break;
3357
3358	    case DT_SCORE_BASE_ADDRESS:
3359	      s = output_bfd->sections;
3360	      BFD_ASSERT (s != NULL);
3361	      dyn.d_un.d_ptr = s->vma & ~(bfd_vma) 0xffff;
3362	      break;
3363
3364	    case DT_SCORE_LOCAL_GOTNO:
3365	      dyn.d_un.d_val = g->local_gotno;
3366	      break;
3367
3368	    case DT_SCORE_UNREFEXTNO:
3369	      /* The index into the dynamic symbol table which is the
3370		 entry of the first external symbol that is not
3371		 referenced within the same object.  */
3372	      dyn.d_un.d_val = bfd_count_sections (output_bfd) + 1;
3373	      break;
3374
3375	    case DT_SCORE_GOTSYM:
3376	      if (g->global_gotsym)
3377		{
3378		  dyn.d_un.d_val = g->global_gotsym->dynindx;
3379		  break;
3380		}
3381	      /* In case if we don't have global got symbols we default
3382		  to setting DT_SCORE_GOTSYM to the same value as
3383		  DT_SCORE_SYMTABNO, so we just fall through.  */
3384
3385	    case DT_SCORE_SYMTABNO:
3386	      name = ".dynsym";
3387	      elemsize = SCORE_ELF_SYM_SIZE (output_bfd);
3388	      s = bfd_get_section_by_name (output_bfd, name);
3389	      BFD_ASSERT (s != NULL);
3390
3391	      dyn.d_un.d_val = s->size / elemsize;
3392	      break;
3393
3394	    case DT_SCORE_HIPAGENO:
3395	      dyn.d_un.d_val = g->local_gotno - SCORE_RESERVED_GOTNO;
3396	      break;
3397
3398	    default:
3399	      swap_out_p = FALSE;
3400	      break;
3401	    }
3402
3403	  if (swap_out_p)
3404	    (*get_elf_backend_data (dynobj)->s->swap_dyn_out) (dynobj, &dyn, b);
3405	}
3406    }
3407
3408  /* The first entry of the global offset table will be filled at
3409     runtime. The second entry will be used by some runtime loaders.
3410     This isn't the case of IRIX rld.  */
3411  if (sgot != NULL && sgot->size > 0)
3412    {
3413      bfd_put_32 (output_bfd, 0, sgot->contents);
3414      bfd_put_32 (output_bfd, 0x80000000, sgot->contents + SCORE_ELF_GOT_SIZE (output_bfd));
3415    }
3416
3417  if (sgot != NULL)
3418    elf_section_data (sgot->output_section)->this_hdr.sh_entsize
3419      = SCORE_ELF_GOT_SIZE (output_bfd);
3420
3421
3422  /* We need to sort the entries of the dynamic relocation section.  */
3423  s = score_elf_rel_dyn_section (dynobj, FALSE);
3424
3425  if (s != NULL && s->size > (bfd_vma)2 * SCORE_ELF_REL_SIZE (output_bfd))
3426    {
3427      reldyn_sorting_bfd = output_bfd;
3428      qsort ((Elf32_External_Rel *) s->contents + 1, s->reloc_count - 1,
3429	     sizeof (Elf32_External_Rel), score_elf_sort_dynamic_relocs);
3430    }
3431
3432  return TRUE;
3433}
3434
3435/* This function set up the ELF section header for a BFD section in preparation for writing
3436   it out.  This is where the flags and type fields are set for unusual sections.  */
3437
3438static bfd_boolean
3439_bfd_score_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
3440			      Elf_Internal_Shdr *hdr,
3441			      asection *sec)
3442{
3443  const char *name;
3444
3445  name = bfd_get_section_name (abfd, sec);
3446
3447  if (strcmp (name, ".got") == 0
3448      || strcmp (name, ".srdata") == 0
3449      || strcmp (name, ".sdata") == 0
3450      || strcmp (name, ".sbss") == 0)
3451    hdr->sh_flags |= SHF_SCORE_GPREL;
3452
3453  return TRUE;
3454}
3455
3456/* This function do additional processing on the ELF section header before writing
3457   it out.  This is used to set the flags and type fields for some sections.  */
3458
3459/* assign_file_positions_except_relocs() check section flag and if it is allocatable,
3460   warning message will be issued.  backend_fake_section is called before
3461   assign_file_positions_except_relocs(); backend_section_processing after it.  so, we
3462   modify section flag there, but not backend_fake_section.  */
3463
3464static bfd_boolean
3465_bfd_score_elf_section_processing (bfd *abfd ATTRIBUTE_UNUSED, Elf_Internal_Shdr *hdr)
3466{
3467  if (hdr->bfd_section != NULL)
3468    {
3469      const char *name = bfd_get_section_name (abfd, hdr->bfd_section);
3470
3471      if (strcmp (name, ".sdata") == 0)
3472	{
3473	  hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
3474	  hdr->sh_type = SHT_PROGBITS;
3475	}
3476      else if (strcmp (name, ".sbss") == 0)
3477	{
3478	  hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
3479	  hdr->sh_type = SHT_NOBITS;
3480	}
3481      else if (strcmp (name, ".srdata") == 0)
3482	{
3483	  hdr->sh_flags |= SHF_ALLOC | SHF_SCORE_GPREL;
3484	  hdr->sh_type = SHT_PROGBITS;
3485	}
3486    }
3487
3488  return TRUE;
3489}
3490
3491static bfd_boolean
3492_bfd_score_elf_write_section (bfd *output_bfd,
3493			      struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
3494                              asection *sec, bfd_byte *contents)
3495{
3496  bfd_byte *to, *from, *end;
3497  int i;
3498
3499  if (strcmp (sec->name, ".pdr") != 0)
3500    return FALSE;
3501
3502  if (score_elf_section_data (sec)->u.tdata == NULL)
3503    return FALSE;
3504
3505  to = contents;
3506  end = contents + sec->size;
3507  for (from = contents, i = 0; from < end; from += PDR_SIZE, i++)
3508    {
3509      if ((score_elf_section_data (sec)->u.tdata)[i] == 1)
3510        continue;
3511
3512      if (to != from)
3513        memcpy (to, from, PDR_SIZE);
3514
3515      to += PDR_SIZE;
3516    }
3517  bfd_set_section_contents (output_bfd, sec->output_section, contents,
3518                            (file_ptr) sec->output_offset, sec->size);
3519
3520  return TRUE;
3521}
3522
3523/* Copy data from a SCORE ELF indirect symbol to its direct symbol, hiding the old
3524   indirect symbol.  Process additional relocation information.  */
3525
3526static void
3527_bfd_score_elf_copy_indirect_symbol (struct bfd_link_info *info,
3528				     struct elf_link_hash_entry *dir,
3529				     struct elf_link_hash_entry *ind)
3530{
3531  struct score_elf_link_hash_entry *dirscore, *indscore;
3532
3533  _bfd_elf_link_hash_copy_indirect (info, dir, ind);
3534
3535  if (ind->root.type != bfd_link_hash_indirect)
3536    return;
3537
3538  dirscore = (struct score_elf_link_hash_entry *) dir;
3539  indscore = (struct score_elf_link_hash_entry *) ind;
3540  dirscore->possibly_dynamic_relocs += indscore->possibly_dynamic_relocs;
3541
3542  if (indscore->readonly_reloc)
3543    dirscore->readonly_reloc = TRUE;
3544
3545  if (indscore->no_fn_stub)
3546    dirscore->no_fn_stub = TRUE;
3547}
3548
3549/* Remove information about discarded functions from other sections which mention them.  */
3550
3551static bfd_boolean
3552_bfd_score_elf_discard_info (bfd *abfd, struct elf_reloc_cookie *cookie,
3553                         struct bfd_link_info *info)
3554{
3555  asection *o;
3556  bfd_boolean ret = FALSE;
3557  unsigned char *tdata;
3558  size_t i, skip;
3559
3560  o = bfd_get_section_by_name (abfd, ".pdr");
3561  if ((!o) || (o->size == 0) || (o->size % PDR_SIZE != 0)
3562      || (o->output_section != NULL && bfd_is_abs_section (o->output_section)))
3563    return FALSE;
3564
3565  tdata = bfd_zmalloc (o->size / PDR_SIZE);
3566  if (!tdata)
3567    return FALSE;
3568
3569  cookie->rels = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, info->keep_memory);
3570  if (!cookie->rels)
3571    {
3572      free (tdata);
3573      return FALSE;
3574    }
3575
3576  cookie->rel = cookie->rels;
3577  cookie->relend = cookie->rels + o->reloc_count;
3578
3579  for (i = 0, skip = 0; i < o->size; i++)
3580    {
3581      if (bfd_elf_reloc_symbol_deleted_p (i * PDR_SIZE, cookie))
3582        {
3583          tdata[i] = 1;
3584          skip++;
3585        }
3586    }
3587
3588  if (skip != 0)
3589    {
3590      score_elf_section_data (o)->u.tdata = tdata;
3591      o->size -= skip * PDR_SIZE;
3592      ret = TRUE;
3593    }
3594  else
3595    free (tdata);
3596
3597  if (!info->keep_memory)
3598    free (cookie->rels);
3599
3600  return ret;
3601}
3602
3603/* Signal that discard_info() has removed the discarded relocations for this section.  */
3604
3605static bfd_boolean
3606_bfd_score_elf_ignore_discarded_relocs (asection *sec)
3607{
3608  if (strcmp (sec->name, ".pdr") == 0)
3609    return TRUE;
3610  return FALSE;
3611}
3612
3613/* Return the section that should be marked against GC for a given
3614   relocation.  */
3615
3616static asection *
3617_bfd_score_elf_gc_mark_hook (asection *sec,
3618			     struct bfd_link_info *info,
3619			     Elf_Internal_Rela *rel,
3620			     struct elf_link_hash_entry *h,
3621			     Elf_Internal_Sym *sym)
3622{
3623  if (h != NULL)
3624    switch (ELF32_R_TYPE (rel->r_info))
3625      {
3626      case R_SCORE_GNU_VTINHERIT:
3627      case R_SCORE_GNU_VTENTRY:
3628	return NULL;
3629      }
3630
3631  return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
3632}
3633
3634/* Support for core dump NOTE sections.  */
3635
3636static bfd_boolean
3637_bfd_score_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
3638{
3639  int offset;
3640  unsigned int raw_size;
3641
3642  switch (note->descsz)
3643    {
3644    default:
3645      return FALSE;
3646
3647    case 148:                  /* Linux/Score 32-bit.  */
3648      /* pr_cursig */
3649      elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
3650
3651      /* pr_pid */
3652      elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
3653
3654      /* pr_reg */
3655      offset = 72;
3656      raw_size = 72;
3657
3658      break;
3659    }
3660
3661  /* Make a ".reg/999" section.  */
3662  return _bfd_elfcore_make_pseudosection (abfd, ".reg", raw_size, note->descpos + offset);
3663}
3664
3665static bfd_boolean
3666_bfd_score_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
3667{
3668  switch (note->descsz)
3669    {
3670    default:
3671      return FALSE;
3672
3673    case 124:                  /* Linux/Score elf_prpsinfo.  */
3674      elf_tdata (abfd)->core_program = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
3675      elf_tdata (abfd)->core_command = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
3676    }
3677
3678  /* Note that for some reason, a spurious space is tacked
3679     onto the end of the args in some (at least one anyway)
3680     implementations, so strip it off if it exists.  */
3681
3682  {
3683    char *command = elf_tdata (abfd)->core_command;
3684    int n = strlen (command);
3685
3686    if (0 < n && command[n - 1] == ' ')
3687      command[n - 1] = '\0';
3688  }
3689
3690  return TRUE;
3691}
3692
3693
3694/* Score BFD functions.  */
3695
3696static reloc_howto_type *
3697elf32_score_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
3698{
3699  unsigned int i;
3700
3701  for (i = 0; i < NUM_ELEM (elf32_score_reloc_map); i++)
3702    if (elf32_score_reloc_map[i].bfd_reloc_val == code)
3703      return &elf32_score_howto_table[elf32_score_reloc_map[i].elf_reloc_val];
3704
3705  return NULL;
3706}
3707
3708/* Create a score elf linker hash table.  */
3709
3710static struct bfd_link_hash_table *
3711elf32_score_link_hash_table_create (bfd *abfd)
3712{
3713  struct score_elf_link_hash_table *ret;
3714  bfd_size_type amt = sizeof (struct score_elf_link_hash_table);
3715
3716  ret = bfd_malloc (amt);
3717  if (ret == NULL)
3718    return NULL;
3719
3720  if (!_bfd_elf_link_hash_table_init (&ret->root, abfd, score_elf_link_hash_newfunc,
3721				      sizeof (struct score_elf_link_hash_entry)))
3722    {
3723      free (ret);
3724      return NULL;
3725    }
3726
3727  return &ret->root.root;
3728}
3729
3730static bfd_boolean
3731elf32_score_print_private_bfd_data (bfd *abfd, void * ptr)
3732{
3733  FILE *file = (FILE *) ptr;
3734
3735  BFD_ASSERT (abfd != NULL && ptr != NULL);
3736
3737  /* Print normal ELF private data.  */
3738  _bfd_elf_print_private_bfd_data (abfd, ptr);
3739
3740  /* xgettext:c-format */
3741  fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
3742  if (elf_elfheader (abfd)->e_flags & EF_SCORE_PIC)
3743    {
3744      fprintf (file, _(" [pic]"));
3745    }
3746  if (elf_elfheader (abfd)->e_flags & EF_SCORE_FIXDEP)
3747    {
3748      fprintf (file, _(" [fix dep]"));
3749    }
3750  fputc ('\n', file);
3751
3752  return TRUE;
3753}
3754
3755static bfd_boolean
3756elf32_score_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
3757{
3758  flagword in_flags;
3759  flagword out_flags;
3760
3761  if (!_bfd_generic_verify_endian_match (ibfd, obfd))
3762    return FALSE;
3763
3764  in_flags  = elf_elfheader (ibfd)->e_flags;
3765  out_flags = elf_elfheader (obfd)->e_flags;
3766
3767  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
3768      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
3769    return TRUE;
3770
3771  in_flags = elf_elfheader (ibfd)->e_flags;
3772  out_flags = elf_elfheader (obfd)->e_flags;
3773
3774  if (! elf_flags_init (obfd))
3775    {
3776      elf_flags_init (obfd) = TRUE;
3777      elf_elfheader (obfd)->e_flags = in_flags;
3778
3779      if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
3780	  && bfd_get_arch_info (obfd)->the_default)
3781	{
3782	  return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
3783	}
3784
3785      return TRUE;
3786    }
3787
3788  if (((in_flags & EF_SCORE_PIC) != 0) != ((out_flags & EF_SCORE_PIC) != 0))
3789    {
3790      (*_bfd_error_handler) (_("%B: warning: linking PIC files with non-PIC files"), ibfd);
3791    }
3792
3793  /* FIXME: Maybe dependency fix compatibility should be checked here.  */
3794
3795  return TRUE;
3796}
3797
3798static bfd_boolean
3799elf32_score_new_section_hook (bfd *abfd, asection *sec)
3800{
3801  struct _score_elf_section_data *sdata;
3802  bfd_size_type amt = sizeof (*sdata);
3803
3804  sdata = bfd_zalloc (abfd, amt);
3805  if (sdata == NULL)
3806    return FALSE;
3807  sec->used_by_bfd = sdata;
3808
3809  return _bfd_elf_new_section_hook (abfd, sec);
3810}
3811
3812
3813#define USE_REL                         1
3814#define TARGET_LITTLE_SYM               bfd_elf32_littlescore_vec
3815#define TARGET_LITTLE_NAME              "elf32-littlescore"
3816#define TARGET_BIG_SYM                  bfd_elf32_bigscore_vec
3817#define TARGET_BIG_NAME                 "elf32-bigscore"
3818#define ELF_ARCH                        bfd_arch_score
3819#define ELF_MACHINE_CODE                EM_SCORE
3820#define ELF_MAXPAGESIZE                 0x8000
3821
3822#define elf_info_to_howto               0
3823#define elf_info_to_howto_rel           _bfd_score_info_to_howto
3824#define elf_backend_relocate_section    _bfd_score_elf_relocate_section
3825#define elf_backend_check_relocs        _bfd_score_elf_check_relocs
3826#define elf_backend_add_symbol_hook     _bfd_score_elf_add_symbol_hook
3827#define elf_backend_symbol_processing   _bfd_score_elf_symbol_processing
3828#define elf_backend_link_output_symbol_hook \
3829  _bfd_score_elf_link_output_symbol_hook
3830#define elf_backend_section_from_bfd_section \
3831  _bfd_score_elf_section_from_bfd_section
3832#define elf_backend_adjust_dynamic_symbol \
3833  _bfd_score_elf_adjust_dynamic_symbol
3834#define elf_backend_always_size_sections \
3835  _bfd_score_elf_always_size_sections
3836#define elf_backend_size_dynamic_sections \
3837  _bfd_score_elf_size_dynamic_sections
3838#define elf_backend_omit_section_dynsym \
3839  ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
3840#define elf_backend_create_dynamic_sections \
3841  _bfd_score_elf_create_dynamic_sections
3842#define elf_backend_finish_dynamic_symbol \
3843  _bfd_score_elf_finish_dynamic_symbol
3844#define elf_backend_finish_dynamic_sections \
3845  _bfd_score_elf_finish_dynamic_sections
3846#define elf_backend_fake_sections         _bfd_score_elf_fake_sections
3847#define elf_backend_section_processing    _bfd_score_elf_section_processing
3848#define elf_backend_write_section         _bfd_score_elf_write_section
3849#define elf_backend_copy_indirect_symbol  _bfd_score_elf_copy_indirect_symbol
3850#define elf_backend_hide_symbol           _bfd_score_elf_hide_symbol
3851#define elf_backend_discard_info          _bfd_score_elf_discard_info
3852#define elf_backend_ignore_discarded_relocs \
3853  _bfd_score_elf_ignore_discarded_relocs
3854#define elf_backend_gc_mark_hook          _bfd_score_elf_gc_mark_hook
3855#define elf_backend_grok_prstatus         _bfd_score_elf_grok_prstatus
3856#define elf_backend_grok_psinfo           _bfd_score_elf_grok_psinfo
3857#define elf_backend_can_gc_sections       1
3858#define elf_backend_want_plt_sym          0
3859#define elf_backend_got_header_size       (4 * SCORE_RESERVED_GOTNO)
3860#define elf_backend_plt_header_size       0
3861#define elf_backend_collect               TRUE
3862#define elf_backend_type_change_ok        TRUE
3863
3864#define bfd_elf32_bfd_reloc_type_lookup      elf32_score_reloc_type_lookup
3865#define bfd_elf32_bfd_link_hash_table_create elf32_score_link_hash_table_create
3866#define bfd_elf32_bfd_print_private_bfd_data elf32_score_print_private_bfd_data
3867#define bfd_elf32_bfd_merge_private_bfd_data elf32_score_merge_private_bfd_data
3868#define bfd_elf32_new_section_hook           elf32_score_new_section_hook
3869
3870#include "elf32-target.h"
3871