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