merge from gcc
[external/binutils.git] / bfd / elf32-score7.c
1 /* 32-bit ELF support for S+core.
2    Copyright 2009, 2010 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 "bfd.h"
26 #include "sysdep.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.  */
39 struct 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.  */
66 struct 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.  */
94 struct 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
109 struct 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.  */
128 struct _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
190 static bfd_byte *hi16_rel_addr;
191
192 /* This will be used when we sort the dynamic relocation records.  */
193 static 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.  */
200 static asection  score_elf_scom_section;
201 static asymbol   score_elf_scom_symbol;
202 static asymbol * score_elf_scom_symbol_ptr;
203
204 static bfd_reloc_status_type
205 score_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
217 static bfd_reloc_status_type
218 score_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
250 static bfd_boolean
251 score_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
302 static bfd_reloc_status_type
303 score_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
338 static bfd_reloc_status_type
339 score_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
373 static bfd_reloc_status_type
374 gprel32_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
416 static bfd_reloc_status_type
417 score_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
454 static bfd_reloc_status_type
455 score_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
494 static bfd_reloc_status_type
495 score_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
511 static bfd_reloc_status_type
512 score_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
544 static reloc_howto_type elf32_score_howto_table[] =
545 {
546   /* No relocation.  */
547   HOWTO (R_SCORE_NONE,          /* type */
548          0,                     /* rightshift */
549          0,                     /* 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
846 struct score_reloc_map
847 {
848   bfd_reloc_code_real_type bfd_reloc_val;
849   unsigned char elf_reloc_val;
850 };
851
852 static 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
876 static INLINE hashval_t
877 score_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
890 static hashval_t
891 score_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
902 static int
903 score_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
918 static bfd_boolean
919 score_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   if (h->root.root.type == bfd_link_hash_warning)
924     h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
925
926   /* Symbols without dynamic symbol table entries aren't interesting at all.  */
927   if (h->root.dynindx == -1)
928     return TRUE;
929
930   /* Global symbols that need GOT entries that are not explicitly
931      referenced are marked with got offset 2.  Those that are
932      referenced get a 1, and those that don't need GOT entries get
933      -1.  */
934   if (h->root.got.offset == 2)
935     {
936       if (hsd->max_unref_got_dynindx == hsd->min_got_dynindx)
937         hsd->low = (struct elf_link_hash_entry *) h;
938       h->root.dynindx = hsd->max_unref_got_dynindx++;
939     }
940   else if (h->root.got.offset != 1)
941     h->root.dynindx = hsd->max_non_got_dynindx++;
942   else
943     {
944       h->root.dynindx = --hsd->min_got_dynindx;
945       hsd->low = (struct elf_link_hash_entry *) h;
946     }
947
948   return TRUE;
949 }
950
951 static asection *
952 score_elf_got_section (bfd *abfd, bfd_boolean maybe_excluded)
953 {
954   asection *sgot = bfd_get_section_by_name (abfd, ".got");
955
956   if (sgot == NULL || (! maybe_excluded && (sgot->flags & SEC_EXCLUDE) != 0))
957     return NULL;
958   return sgot;
959 }
960
961 /* Returns the GOT information associated with the link indicated by
962    INFO.  If SGOTP is non-NULL, it is filled in with the GOT section.  */
963
964 static struct score_got_info *
965 score_elf_got_info (bfd *abfd, asection **sgotp)
966 {
967   asection *sgot;
968   struct score_got_info *g;
969
970   sgot = score_elf_got_section (abfd, TRUE);
971   BFD_ASSERT (sgot != NULL);
972   BFD_ASSERT (elf_section_data (sgot) != NULL);
973   g = score_elf_section_data (sgot)->u.got_info;
974   BFD_ASSERT (g != NULL);
975
976   if (sgotp)
977     *sgotp = sgot;
978   return g;
979 }
980
981 /* Sort the dynamic symbol table so that symbols that need GOT entries
982    appear towards the end.  This reduces the amount of GOT space
983    required.  MAX_LOCAL is used to set the number of local symbols
984    known to be in the dynamic symbol table.  During
985    s7_bfd_score_elf_size_dynamic_sections, this value is 1.  Afterward, the
986    section symbols are added and the count is higher.  */
987
988 static bfd_boolean
989 score_elf_sort_hash_table (struct bfd_link_info *info,
990                            unsigned long max_local)
991 {
992   struct score_elf_hash_sort_data hsd;
993   struct score_got_info *g;
994   bfd *dynobj;
995
996   dynobj = elf_hash_table (info)->dynobj;
997
998   g = score_elf_got_info (dynobj, NULL);
999
1000   hsd.low = NULL;
1001   hsd.max_unref_got_dynindx =
1002     hsd.min_got_dynindx = elf_hash_table (info)->dynsymcount
1003     /* In the multi-got case, assigned_gotno of the master got_info
1004        indicate the number of entries that aren't referenced in the
1005        primary GOT, but that must have entries because there are
1006        dynamic relocations that reference it.  Since they aren't
1007        referenced, we move them to the end of the GOT, so that they
1008        don't prevent other entries that are referenced from getting
1009        too large offsets.  */
1010     - (g->next ? g->assigned_gotno : 0);
1011   hsd.max_non_got_dynindx = max_local;
1012   score_elf_link_hash_traverse (elf_hash_table (info),
1013                                 score_elf_sort_hash_table_f,
1014                                 &hsd);
1015
1016   /* There should have been enough room in the symbol table to
1017      accommodate both the GOT and non-GOT symbols.  */
1018   BFD_ASSERT (hsd.max_non_got_dynindx <= hsd.min_got_dynindx);
1019   BFD_ASSERT ((unsigned long) hsd.max_unref_got_dynindx
1020               <= elf_hash_table (info)->dynsymcount);
1021
1022   /* Now we know which dynamic symbol has the lowest dynamic symbol
1023      table index in the GOT.  */
1024   g->global_gotsym = hsd.low;
1025
1026   return TRUE;
1027 }
1028
1029 /* Returns the first relocation of type r_type found, beginning with
1030    RELOCATION.  RELEND is one-past-the-end of the relocation table.  */
1031
1032 static const Elf_Internal_Rela *
1033 score_elf_next_relocation (bfd *abfd ATTRIBUTE_UNUSED, unsigned int r_type,
1034                            const Elf_Internal_Rela *relocation,
1035                            const Elf_Internal_Rela *relend)
1036 {
1037   while (relocation < relend)
1038     {
1039       if (ELF32_R_TYPE (relocation->r_info) == r_type)
1040         return relocation;
1041
1042       ++relocation;
1043     }
1044
1045   /* We didn't find it.  */
1046   bfd_set_error (bfd_error_bad_value);
1047   return NULL;
1048 }
1049
1050 /* This function is called via qsort() to sort the dynamic relocation
1051    entries by increasing r_symndx value.  */
1052 static int
1053 score_elf_sort_dynamic_relocs (const void *arg1, const void *arg2)
1054 {
1055   Elf_Internal_Rela int_reloc1;
1056   Elf_Internal_Rela int_reloc2;
1057
1058   bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg1, &int_reloc1);
1059   bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg2, &int_reloc2);
1060
1061   return (ELF32_R_SYM (int_reloc1.r_info) - ELF32_R_SYM (int_reloc2.r_info));
1062 }
1063
1064 /* Return whether a relocation is against a local symbol.  */
1065 static bfd_boolean
1066 score_elf_local_relocation_p (bfd *input_bfd,
1067                               const Elf_Internal_Rela *relocation,
1068                               asection **local_sections,
1069                               bfd_boolean check_forced)
1070 {
1071   unsigned long r_symndx;
1072   Elf_Internal_Shdr *symtab_hdr;
1073   struct score_elf_link_hash_entry *h;
1074   size_t extsymoff;
1075
1076   r_symndx = ELF32_R_SYM (relocation->r_info);
1077   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1078   extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
1079
1080   if (r_symndx < extsymoff)
1081     return TRUE;
1082   if (elf_bad_symtab (input_bfd) && local_sections[r_symndx] != NULL)
1083     return TRUE;
1084
1085   if (check_forced)
1086     {
1087       /* Look up the hash table to check whether the symbol was forced local.  */
1088       h = (struct score_elf_link_hash_entry *)
1089         elf_sym_hashes (input_bfd) [r_symndx - extsymoff];
1090       /* Find the real hash-table entry for this symbol.  */
1091       while (h->root.root.type == bfd_link_hash_indirect
1092              || h->root.root.type == bfd_link_hash_warning)
1093         h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
1094       if (h->root.forced_local)
1095         return TRUE;
1096     }
1097
1098   return FALSE;
1099 }
1100
1101 /* Returns the dynamic relocation section for DYNOBJ.  */
1102
1103 static asection *
1104 score_elf_rel_dyn_section (bfd *dynobj, bfd_boolean create_p)
1105 {
1106   static const char dname[] = ".rel.dyn";
1107   asection *sreloc;
1108
1109   sreloc = bfd_get_section_by_name (dynobj, dname);
1110   if (sreloc == NULL && create_p)
1111     {
1112       sreloc = bfd_make_section_with_flags (dynobj, dname,
1113                                             (SEC_ALLOC
1114                                              | SEC_LOAD
1115                                              | SEC_HAS_CONTENTS
1116                                              | SEC_IN_MEMORY
1117                                              | SEC_LINKER_CREATED
1118                                              | SEC_READONLY));
1119       if (sreloc == NULL
1120           || ! bfd_set_section_alignment (dynobj, sreloc,
1121                                           SCORE_ELF_LOG_FILE_ALIGN (dynobj)))
1122         return NULL;
1123     }
1124   return sreloc;
1125 }
1126
1127 static void
1128 score_elf_allocate_dynamic_relocations (bfd *abfd, unsigned int n)
1129 {
1130   asection *s;
1131
1132   s = score_elf_rel_dyn_section (abfd, FALSE);
1133   BFD_ASSERT (s != NULL);
1134
1135   if (s->size == 0)
1136     {
1137       /* Make room for a null element.  */
1138       s->size += SCORE_ELF_REL_SIZE (abfd);
1139       ++s->reloc_count;
1140     }
1141   s->size += n * SCORE_ELF_REL_SIZE (abfd);
1142 }
1143
1144 /* Create a rel.dyn relocation for the dynamic linker to resolve.  REL
1145    is the original relocation, which is now being transformed into a
1146    dynamic relocation.  The ADDENDP is adjusted if necessary; the
1147    caller should store the result in place of the original addend.  */
1148
1149 static bfd_boolean
1150 score_elf_create_dynamic_relocation (bfd *output_bfd,
1151                                      struct bfd_link_info *info,
1152                                      const Elf_Internal_Rela *rel,
1153                                      struct score_elf_link_hash_entry *h,
1154                                      bfd_vma symbol,
1155                                      bfd_vma *addendp, asection *input_section)
1156 {
1157   Elf_Internal_Rela outrel[3];
1158   asection *sreloc;
1159   bfd *dynobj;
1160   int r_type;
1161   long indx;
1162   bfd_boolean defined_p;
1163
1164   r_type = ELF32_R_TYPE (rel->r_info);
1165   dynobj = elf_hash_table (info)->dynobj;
1166   sreloc = score_elf_rel_dyn_section (dynobj, FALSE);
1167   BFD_ASSERT (sreloc != NULL);
1168   BFD_ASSERT (sreloc->contents != NULL);
1169   BFD_ASSERT (sreloc->reloc_count * SCORE_ELF_REL_SIZE (output_bfd) < sreloc->size);
1170
1171   outrel[0].r_offset =
1172     _bfd_elf_section_offset (output_bfd, info, input_section, rel[0].r_offset);
1173   outrel[1].r_offset =
1174     _bfd_elf_section_offset (output_bfd, info, input_section, rel[1].r_offset);
1175   outrel[2].r_offset =
1176     _bfd_elf_section_offset (output_bfd, info, input_section, rel[2].r_offset);
1177
1178   if (outrel[0].r_offset == MINUS_ONE)
1179     /* The relocation field has been deleted.  */
1180     return TRUE;
1181
1182   if (outrel[0].r_offset == MINUS_TWO)
1183     {
1184       /* The relocation field has been converted into a relative value of
1185          some sort.  Functions like _bfd_elf_write_section_eh_frame expect
1186          the field to be fully relocated, so add in the symbol's value.  */
1187       *addendp += symbol;
1188       return TRUE;
1189     }
1190
1191   /* We must now calculate the dynamic symbol table index to use
1192      in the relocation.  */
1193   if (h != NULL
1194       && (! info->symbolic || !h->root.def_regular)
1195       /* h->root.dynindx may be -1 if this symbol was marked to
1196          become local.  */
1197       && h->root.dynindx != -1)
1198     {
1199       indx = h->root.dynindx;
1200         /* ??? glibc's ld.so just adds the final GOT entry to the
1201            relocation field.  It therefore treats relocs against
1202            defined symbols in the same way as relocs against
1203            undefined symbols.  */
1204       defined_p = FALSE;
1205     }
1206   else
1207     {
1208       indx = 0;
1209       defined_p = TRUE;
1210     }
1211
1212   /* If the relocation was previously an absolute relocation and
1213      this symbol will not be referred to by the relocation, we must
1214      adjust it by the value we give it in the dynamic symbol table.
1215      Otherwise leave the job up to the dynamic linker.  */
1216   if (defined_p && r_type != R_SCORE_REL32)
1217     *addendp += symbol;
1218
1219   /* The relocation is always an REL32 relocation because we don't
1220      know where the shared library will wind up at load-time.  */
1221   outrel[0].r_info = ELF32_R_INFO ((unsigned long) indx, R_SCORE_REL32);
1222
1223   /* For strict adherence to the ABI specification, we should
1224      generate a R_SCORE_64 relocation record by itself before the
1225      _REL32/_64 record as well, such that the addend is read in as
1226      a 64-bit value (REL32 is a 32-bit relocation, after all).
1227      However, since none of the existing ELF64 SCORE dynamic
1228      loaders seems to care, we don't waste space with these
1229      artificial relocations.  If this turns out to not be true,
1230      score_elf_allocate_dynamic_relocations() should be tweaked so
1231      as to make room for a pair of dynamic relocations per
1232      invocation if ABI_64_P, and here we should generate an
1233      additional relocation record with R_SCORE_64 by itself for a
1234      NULL symbol before this relocation record.  */
1235   outrel[1].r_info = ELF32_R_INFO (0, R_SCORE_NONE);
1236   outrel[2].r_info = ELF32_R_INFO (0, R_SCORE_NONE);
1237
1238   /* Adjust the output offset of the relocation to reference the
1239      correct location in the output file.  */
1240   outrel[0].r_offset += (input_section->output_section->vma
1241                          + input_section->output_offset);
1242   outrel[1].r_offset += (input_section->output_section->vma
1243                          + input_section->output_offset);
1244   outrel[2].r_offset += (input_section->output_section->vma
1245                          + input_section->output_offset);
1246
1247   /* Put the relocation back out.  We have to use the special
1248      relocation outputter in the 64-bit case since the 64-bit
1249      relocation format is non-standard.  */
1250   bfd_elf32_swap_reloc_out
1251       (output_bfd, &outrel[0],
1252        (sreloc->contents + sreloc->reloc_count * sizeof (Elf32_External_Rel)));
1253
1254   /* We've now added another relocation.  */
1255   ++sreloc->reloc_count;
1256
1257   /* Make sure the output section is writable.  The dynamic linker
1258      will be writing to it.  */
1259   elf_section_data (input_section->output_section)->this_hdr.sh_flags |= SHF_WRITE;
1260
1261   return TRUE;
1262 }
1263
1264 static bfd_boolean
1265 score_elf_create_got_section (bfd *abfd,
1266                               struct bfd_link_info *info,
1267                               bfd_boolean maybe_exclude)
1268 {
1269   flagword flags;
1270   asection *s;
1271   struct elf_link_hash_entry *h;
1272   struct bfd_link_hash_entry *bh;
1273   struct score_got_info *g;
1274   bfd_size_type amt;
1275
1276   /* This function may be called more than once.  */
1277   s = score_elf_got_section (abfd, TRUE);
1278   if (s)
1279     {
1280       if (! maybe_exclude)
1281         s->flags &= ~SEC_EXCLUDE;
1282       return TRUE;
1283     }
1284
1285   flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
1286
1287   if (maybe_exclude)
1288     flags |= SEC_EXCLUDE;
1289
1290   /* We have to use an alignment of 2**4 here because this is hardcoded
1291      in the function stub generation and in the linker script.  */
1292   s = bfd_make_section_with_flags (abfd, ".got", flags);
1293    if (s == NULL
1294       || ! bfd_set_section_alignment (abfd, s, 4))
1295     return FALSE;
1296
1297   /* Define the symbol _GLOBAL_OFFSET_TABLE_.  We don't do this in the
1298      linker script because we don't want to define the symbol if we
1299      are not creating a global offset table.  */
1300   bh = NULL;
1301   if (! (_bfd_generic_link_add_one_symbol
1302          (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s,
1303           0, NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
1304     return FALSE;
1305
1306   h = (struct elf_link_hash_entry *) bh;
1307   h->non_elf = 0;
1308   h->def_regular = 1;
1309   h->type = STT_OBJECT;
1310
1311   if (info->shared && ! 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
1338 static bfd_vma
1339 score_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
1347 static struct score_got_entry *
1348 score_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
1395 static bfd_vma
1396 score_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
1422 void
1423 s7_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
1500 static bfd_boolean
1501 score_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
1555 static bfd_boolean
1556 score_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
1586 static bfd_vma
1587 score_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
1608 static bfd_vma
1609 score_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
1633 static bfd_vma
1634 score_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   struct score_got_info *g;
1642
1643   g = score_elf_got_info (dynobj, &sgot);
1644   gp = _bfd_get_gp_value (output_bfd);
1645
1646   return sgot->output_section->vma + sgot->output_offset + got_index - gp;
1647 }
1648
1649 /* Follow indirect and warning hash entries so that each got entry
1650    points to the final symbol definition.  P must point to a pointer
1651    to the hash table we're traversing.  Since this traversal may
1652    modify the hash table, we set this pointer to NULL to indicate
1653    we've made a potentially-destructive change to the hash table, so
1654    the traversal must be restarted.  */
1655
1656 static int
1657 score_elf_resolve_final_got_entry (void **entryp, void *p)
1658 {
1659   struct score_got_entry *entry = (struct score_got_entry *) *entryp;
1660   htab_t got_entries = *(htab_t *) p;
1661
1662   if (entry->abfd != NULL && entry->symndx == -1)
1663     {
1664       struct score_elf_link_hash_entry *h = entry->d.h;
1665
1666       while (h->root.root.type == bfd_link_hash_indirect
1667              || h->root.root.type == bfd_link_hash_warning)
1668         h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
1669
1670       if (entry->d.h == h)
1671         return 1;
1672
1673       entry->d.h = h;
1674
1675       /* If we can't find this entry with the new bfd hash, re-insert
1676          it, and get the traversal restarted.  */
1677       if (! htab_find (got_entries, entry))
1678         {
1679           htab_clear_slot (got_entries, entryp);
1680           entryp = htab_find_slot (got_entries, entry, INSERT);
1681           if (! *entryp)
1682             *entryp = entry;
1683           /* Abort the traversal, since the whole table may have
1684              moved, and leave it up to the parent to restart the
1685              process.  */
1686           *(htab_t *) p = NULL;
1687           return 0;
1688         }
1689       /* We might want to decrement the global_gotno count, but it's
1690          either too early or too late for that at this point.  */
1691     }
1692
1693   return 1;
1694 }
1695
1696 /* Turn indirect got entries in a got_entries table into their final locations.  */
1697
1698 static void
1699 score_elf_resolve_final_got_entries (struct score_got_info *g)
1700 {
1701   htab_t got_entries;
1702
1703   do
1704     {
1705       got_entries = g->got_entries;
1706
1707       htab_traverse (got_entries,
1708                      score_elf_resolve_final_got_entry,
1709                      &got_entries);
1710     }
1711   while (got_entries == NULL);
1712 }
1713
1714 /* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS. for -r  */
1715
1716 static void
1717 score_elf_add_to_rel (bfd *abfd,
1718                       bfd_byte *address,
1719                       reloc_howto_type *howto,
1720                       bfd_signed_vma increment)
1721 {
1722   bfd_signed_vma addend;
1723   bfd_vma contents;
1724   unsigned long offset;
1725   unsigned long r_type = howto->type;
1726   unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
1727
1728   contents = bfd_get_32 (abfd, address);
1729   /* Get the (signed) value from the instruction.  */
1730   addend = contents & howto->src_mask;
1731   if (addend & ((howto->src_mask + 1) >> 1))
1732     {
1733       bfd_signed_vma mask;
1734
1735       mask = -1;
1736       mask &= ~howto->src_mask;
1737       addend |= mask;
1738     }
1739   /* Add in the increment, (which is a byte value).  */
1740   switch (r_type)
1741     {
1742     case R_SCORE_PC19:
1743       offset =
1744         (((contents & howto->src_mask) & 0x3ff0000) >> 6) | ((contents & howto->src_mask) & 0x3ff);
1745       offset += increment;
1746       contents =
1747         (contents & ~howto->
1748          src_mask) | (((offset << 6) & howto->src_mask) & 0x3ff0000) | (offset & 0x3ff);
1749       bfd_put_32 (abfd, contents, address);
1750       break;
1751     case R_SCORE_HI16:
1752       break;
1753     case R_SCORE_LO16:
1754       hi16_addend = bfd_get_32 (abfd, address - 4);
1755       hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
1756       offset = ((((contents >> 16) & 0x3) << 15) | (contents & 0x7fff)) >> 1;
1757       offset = (hi16_offset << 16) | (offset & 0xffff);
1758       uvalue = increment + offset;
1759       hi16_offset = (uvalue >> 16) << 1;
1760       hi16_value = (hi16_addend & (~(howto->dst_mask)))
1761         | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
1762       bfd_put_32 (abfd, hi16_value, address - 4);
1763       offset = (uvalue & 0xffff) << 1;
1764       contents = (contents & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
1765       bfd_put_32 (abfd, contents, address);
1766       break;
1767     case R_SCORE_24:
1768       offset =
1769         (((contents & howto->src_mask) >> 1) & 0x1ff8000) | ((contents & howto->src_mask) & 0x7fff);
1770       offset += increment;
1771       contents =
1772         (contents & ~howto->
1773          src_mask) | (((offset << 1) & howto->src_mask) & 0x3ff0000) | (offset & 0x7fff);
1774       bfd_put_32 (abfd, contents, address);
1775       break;
1776     case R_SCORE16_11:
1777
1778       contents = bfd_get_16 (abfd, address);
1779       offset = contents & howto->src_mask;
1780       offset += increment;
1781       contents = (contents & ~howto->src_mask) | (offset & howto->src_mask);
1782       bfd_put_16 (abfd, contents, address);
1783
1784       break;
1785     case R_SCORE16_PC8:
1786
1787       contents = bfd_get_16 (abfd, address);
1788       offset = (contents & howto->src_mask) + ((increment >> 1) & 0xff);
1789       contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask);
1790       bfd_put_16 (abfd, contents, address);
1791
1792       break;
1793     case R_SCORE_GOT15:
1794     case R_SCORE_GOT_LO16:
1795       break;
1796
1797     default:
1798       addend += increment;
1799       contents = (contents & ~howto->dst_mask) | (addend & howto->dst_mask);
1800       bfd_put_32 (abfd, contents, address);
1801       break;
1802     }
1803 }
1804
1805 /* Perform a relocation as part of a final link.  */
1806
1807 static bfd_reloc_status_type
1808 score_elf_final_link_relocate (reloc_howto_type *howto,
1809                                bfd *input_bfd,
1810                                bfd *output_bfd,
1811                                asection *input_section,
1812                                bfd_byte *contents,
1813                                Elf_Internal_Rela *rel,
1814                                Elf_Internal_Rela *relocs,
1815                                bfd_vma symbol,
1816                                struct bfd_link_info *info,
1817                                const char *sym_name ATTRIBUTE_UNUSED,
1818                                int sym_flags ATTRIBUTE_UNUSED,
1819                                struct score_elf_link_hash_entry *h,
1820                                Elf_Internal_Sym *local_syms,
1821                                asection **local_sections,
1822                                bfd_boolean gp_disp_p)
1823 {
1824   unsigned long r_type;
1825   unsigned long r_symndx;
1826   bfd_byte *hit_data = contents + rel->r_offset;
1827   bfd_vma addend;
1828   /* The final GP value to be used for the relocatable, executable, or
1829      shared object file being produced.  */
1830   bfd_vma gp = MINUS_ONE;
1831   /* The place (section offset or address) of the storage unit being relocated.  */
1832   bfd_vma rel_addr;
1833   /* The value of GP used to create the relocatable object.  */
1834   bfd_vma gp0 = MINUS_ONE;
1835   /* The offset into the global offset table at which the address of the relocation entry
1836      symbol, adjusted by the addend, resides during execution.  */
1837   bfd_vma g = MINUS_ONE;
1838   /* TRUE if the symbol referred to by this relocation is a local symbol.  */
1839   bfd_boolean local_p;
1840   /* The eventual value we will relocate.  */
1841   bfd_vma value = symbol;
1842   unsigned long hi16_addend, hi16_offset, hi16_value, uvalue, offset, abs_value = 0;
1843
1844   Elf_Internal_Sym *sym = 0;
1845   asection *sec = NULL;
1846   bfd_boolean merge_p = 0;
1847
1848
1849   if (elf_gp (output_bfd) == 0)
1850     {
1851       struct bfd_link_hash_entry *bh;
1852       asection *o;
1853
1854       bh = bfd_link_hash_lookup (info->hash, "_gp", 0, 0, 1);
1855       if (bh != NULL && bh->type == bfd_link_hash_defined)
1856         elf_gp (output_bfd) = (bh->u.def.value
1857                                + bh->u.def.section->output_section->vma
1858                                + bh->u.def.section->output_offset);
1859       else if (info->relocatable)
1860         {
1861           bfd_vma lo = -1;
1862
1863           /* Find the GP-relative section with the lowest offset.  */
1864           for (o = output_bfd->sections; o != NULL; o = o->next)
1865             if (o->vma < lo)
1866               lo = o->vma;
1867           /* And calculate GP relative to that.  */
1868           elf_gp (output_bfd) = lo + ELF_SCORE_GP_OFFSET (input_bfd);
1869         }
1870       else
1871         {
1872           /* If the relocate_section function needs to do a reloc
1873              involving the GP value, it should make a reloc_dangerous
1874              callback to warn that GP is not defined.  */
1875         }
1876     }
1877
1878   /* Parse the relocation.  */
1879   r_symndx = ELF32_R_SYM (rel->r_info);
1880   r_type = ELF32_R_TYPE (rel->r_info);
1881   rel_addr = (input_section->output_section->vma + input_section->output_offset + rel->r_offset);
1882
1883   /* For hidden symbol.  */
1884   local_p = score_elf_local_relocation_p (input_bfd, rel, local_sections, FALSE);
1885   if (local_p)
1886     {
1887       sym = local_syms + r_symndx;
1888       sec = local_sections[r_symndx];
1889
1890       symbol = sec->output_section->vma + sec->output_offset;
1891       if (ELF_ST_TYPE (sym->st_info) != STT_SECTION
1892           || (sec->flags & SEC_MERGE))
1893         symbol += sym->st_value;
1894       if ((sec->flags & SEC_MERGE)
1895           && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1896         merge_p = 1;
1897     }
1898
1899   if (r_type == R_SCORE_GOT15)
1900     {
1901       const Elf_Internal_Rela *relend;
1902       const Elf_Internal_Rela *lo16_rel;
1903       const struct elf_backend_data *bed;
1904       bfd_vma lo_value = 0;
1905
1906       bed = get_elf_backend_data (output_bfd);
1907       relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
1908       lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
1909       if ((local_p) && (lo16_rel != NULL))
1910         {
1911           bfd_vma tmp = 0;
1912           tmp = bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
1913           lo_value = (((tmp >> 16) & 0x3) << 14) | ((tmp & 0x7fff) >> 1);
1914           if (merge_p)
1915             {
1916               asection *msec = sec;
1917               lo_value = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, lo_value);
1918               lo_value -= symbol;
1919               lo_value += msec->output_section->vma + msec->output_offset;
1920             }
1921         }
1922       addend = lo_value;
1923     }
1924   else
1925     {
1926       addend = (bfd_get_32 (input_bfd, hit_data) >> howto->bitpos) & howto->src_mask;
1927     }
1928
1929   /* Figure out the value of the symbol.  */
1930   if (local_p && !merge_p)
1931     {
1932       if (r_type == R_SCORE_GOT15)
1933         {
1934           const Elf_Internal_Rela *relend;
1935           const Elf_Internal_Rela *lo16_rel;
1936           const struct elf_backend_data *bed;
1937           bfd_vma lo_value = 0;
1938
1939           value = bfd_get_32 (input_bfd, contents + rel->r_offset);
1940           addend = value & 0x7fff;
1941           if ((addend & 0x4000) == 0x4000)
1942             addend |= 0xffffc000;
1943
1944           bed = get_elf_backend_data (output_bfd);
1945           relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
1946           lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
1947           if ((local_p) && (lo16_rel != NULL))
1948             {
1949               bfd_vma tmp = 0;
1950               tmp = bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
1951               lo_value = (((tmp >> 16) & 0x3) << 14) | ((tmp & 0x7fff) >> 1);
1952             }
1953
1954           addend <<= 16;
1955           addend += lo_value;
1956         }
1957     }
1958
1959   local_p = score_elf_local_relocation_p (input_bfd, rel, local_sections, TRUE);
1960
1961   /* If we haven't already determined the GOT offset, or the GP value,
1962      and we're going to need it, get it now.  */
1963   switch (r_type)
1964     {
1965     case R_SCORE_CALL15:
1966     case R_SCORE_GOT15:
1967       if (!local_p)
1968         {
1969           g = score_elf_global_got_index (elf_hash_table (info)->dynobj,
1970                                           (struct elf_link_hash_entry *) h);
1971           if ((! elf_hash_table(info)->dynamic_sections_created
1972                || (info->shared
1973                    && (info->symbolic || h->root.dynindx == -1)
1974                    && h->root.def_regular)))
1975             {
1976               /* This is a static link or a -Bsymbolic link.  The
1977                  symbol is defined locally, or was forced to be local.
1978                  We must initialize this entry in the GOT.  */
1979               bfd *tmpbfd = elf_hash_table (info)->dynobj;
1980               asection *sgot = score_elf_got_section (tmpbfd, FALSE);
1981               bfd_put_32 (tmpbfd, value, sgot->contents + g);
1982             }
1983         }
1984       else if (r_type == R_SCORE_GOT15 || r_type == R_SCORE_CALL15)
1985         {
1986           /* There's no need to create a local GOT entry here; the
1987              calculation for a local GOT15 entry does not involve G.  */
1988           ;
1989         }
1990       else
1991         {
1992           g = score_elf_local_got_index (output_bfd, input_bfd, info,
1993                                          symbol + addend, r_symndx, h, r_type);
1994             if (g == MINUS_ONE)
1995             return bfd_reloc_outofrange;
1996         }
1997
1998       /* Convert GOT indices to actual offsets.  */
1999       g = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
2000                                            output_bfd, input_bfd, g);
2001       break;
2002
2003     case R_SCORE_HI16:
2004     case R_SCORE_LO16:
2005     case R_SCORE_GPREL32:
2006       gp0 = _bfd_get_gp_value (input_bfd);
2007       gp = _bfd_get_gp_value (output_bfd);
2008       break;
2009
2010     case R_SCORE_GP15:
2011       gp = _bfd_get_gp_value (output_bfd);
2012
2013     default:
2014       break;
2015     }
2016
2017   switch (r_type)
2018     {
2019     case R_SCORE_NONE:
2020       return bfd_reloc_ok;
2021
2022     case R_SCORE_ABS32:
2023     case R_SCORE_REL32:
2024       if ((info->shared
2025            || (elf_hash_table (info)->dynamic_sections_created
2026                && h != NULL
2027                && h->root.def_dynamic
2028                && !h->root.def_regular))
2029            && r_symndx != 0
2030            && (input_section->flags & SEC_ALLOC) != 0)
2031         {
2032           /* If we're creating a shared library, or this relocation is against a symbol
2033              in a shared library, then we can't know where the symbol will end up.
2034              So, we create a relocation record in the output, and leave the job up
2035              to the dynamic linker.  */
2036           value = addend;
2037           if (!score_elf_create_dynamic_relocation (output_bfd, info, rel, h,
2038                                                     symbol, &value,
2039                                                     input_section))
2040             return bfd_reloc_undefined;
2041         }
2042       else if (r_symndx == 0)
2043         /* r_symndx will be zero only for relocs against symbols
2044            from removed linkonce sections, or sections discarded by
2045            a linker script.  */
2046         value = 0;
2047       else
2048         {
2049           if (r_type != R_SCORE_REL32)
2050             value = symbol + addend;
2051           else
2052             value = addend;
2053         }
2054       value &= howto->dst_mask;
2055       bfd_put_32 (input_bfd, value, hit_data);
2056       return bfd_reloc_ok;
2057
2058     case R_SCORE_ABS16:
2059       value += addend;
2060       if ((long) value > 0x7fff || (long) value < -0x8000)
2061         return bfd_reloc_overflow;
2062       bfd_put_16 (input_bfd, value, hit_data);
2063       return bfd_reloc_ok;
2064
2065     case R_SCORE_24:
2066       addend = bfd_get_32 (input_bfd, hit_data);
2067       offset = (((addend & howto->src_mask) >> 1) & 0x1ff8000) | ((addend & howto->src_mask) & 0x7fff);
2068       if ((offset & 0x1000000) != 0)
2069         offset |= 0xfe000000;
2070       value += offset;
2071       abs_value = abs (value - rel_addr);
2072       if ((abs_value & 0xfe000000) != 0)
2073         return bfd_reloc_overflow;
2074       addend = (addend & ~howto->src_mask)
2075                 | (((value << 1) & howto->src_mask) & 0x3ff0000) | (value & 0x7fff);
2076       bfd_put_32 (input_bfd, addend, hit_data);
2077       return bfd_reloc_ok;
2078
2079     case R_SCORE_PC19:
2080       addend = bfd_get_32 (input_bfd, hit_data);
2081       offset = (((addend & howto->src_mask) & 0x3ff0000) >> 6) | ((addend & howto->src_mask) & 0x3ff);
2082       if ((offset & 0x80000) != 0)
2083         offset |= 0xfff00000;
2084       abs_value = value = value - rel_addr + offset;
2085       /* exceed 20 bit : overflow.  */
2086       if ((abs_value & 0x80000000) == 0x80000000)
2087         abs_value = 0xffffffff - value + 1;
2088       if ((abs_value & 0xfff80000) != 0)
2089         return bfd_reloc_overflow;
2090       addend = (addend & ~howto->src_mask)
2091                 | (((value << 6) & howto->src_mask) & 0x3ff0000) | (value & 0x3ff);
2092       bfd_put_32 (input_bfd, addend, hit_data);
2093       return bfd_reloc_ok;
2094
2095     case R_SCORE16_11:
2096       addend = bfd_get_16 (input_bfd, hit_data);
2097       offset = addend & howto->src_mask;
2098       if ((offset & 0x800) != 0)        /* Offset is negative.  */
2099         offset |= 0xfffff000;
2100       value += offset;
2101       abs_value = abs (value - rel_addr);
2102       if ((abs_value & 0xfffff000) != 0)
2103         return bfd_reloc_overflow;
2104       addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
2105       bfd_put_16 (input_bfd, addend, hit_data);
2106       return bfd_reloc_ok;
2107
2108     case R_SCORE16_PC8:
2109       addend = bfd_get_16 (input_bfd, hit_data);
2110       offset = (addend & howto->src_mask) << 1;
2111       if ((offset & 0x100) != 0)        /* Offset is negative.  */
2112         offset |= 0xfffffe00;
2113       abs_value = value = value - rel_addr + offset;
2114       /* Sign bit + exceed 9 bit.  */
2115       if (((value & 0xffffff00) != 0) && ((value & 0xffffff00) != 0xffffff00))
2116         return bfd_reloc_overflow;
2117       value >>= 1;
2118       addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
2119       bfd_put_16 (input_bfd, addend, hit_data);
2120       return bfd_reloc_ok;
2121
2122     case R_SCORE_HI16:
2123       return bfd_reloc_ok;
2124
2125     case R_SCORE_LO16:
2126       hi16_addend = bfd_get_32 (input_bfd, hit_data - 4);
2127       hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
2128       addend = bfd_get_32 (input_bfd, hit_data);
2129       offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
2130       offset = (hi16_offset << 16) | (offset & 0xffff);
2131
2132       if (!gp_disp_p)
2133         uvalue = value + offset;
2134       else
2135         uvalue = offset + gp - rel_addr + 4;
2136
2137       hi16_offset = (uvalue >> 16) << 1;
2138       hi16_value = (hi16_addend & (~(howto->dst_mask)))
2139                         | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
2140       bfd_put_32 (input_bfd, hi16_value, hit_data - 4);
2141       offset = (uvalue & 0xffff) << 1;
2142       value = (addend & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
2143       bfd_put_32 (input_bfd, value, hit_data);
2144       return bfd_reloc_ok;
2145
2146     case R_SCORE_GP15:
2147       addend = bfd_get_32 (input_bfd, hit_data);
2148       offset = addend & 0x7fff;
2149       if ((offset & 0x4000) == 0x4000)
2150         offset |= 0xffffc000;
2151       value = value + offset - gp;
2152       if (((value & 0xffffc000) != 0) && ((value & 0xffffc000) != 0xffffc000))
2153         return bfd_reloc_overflow;
2154       value = (addend & ~howto->src_mask) | (value & howto->src_mask);
2155       bfd_put_32 (input_bfd, value, hit_data);
2156       return bfd_reloc_ok;
2157
2158     case R_SCORE_GOT15:
2159     case R_SCORE_CALL15:
2160       if (local_p)
2161         {
2162           bfd_boolean forced;
2163
2164           /* The special case is when the symbol is forced to be local.  We need the
2165              full address in the GOT since no R_SCORE_GOT_LO16 relocation follows.  */
2166           forced = ! score_elf_local_relocation_p (input_bfd, rel,
2167                                                    local_sections, FALSE);
2168           value = score_elf_got16_entry (output_bfd, input_bfd, info,
2169                                          symbol + addend, forced);
2170           if (value == MINUS_ONE)
2171             return bfd_reloc_outofrange;
2172           value = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
2173                                                    output_bfd, input_bfd, value);
2174         }
2175       else
2176         {
2177           value = g;
2178         }
2179
2180       if ((long) value > 0x3fff || (long) value < -0x4000)
2181         return bfd_reloc_overflow;
2182
2183       addend = bfd_get_32 (input_bfd, hit_data);
2184       value = (addend & ~howto->dst_mask) | (value & howto->dst_mask);
2185       bfd_put_32 (input_bfd, value, hit_data);
2186       return bfd_reloc_ok;
2187
2188     case R_SCORE_GPREL32:
2189       value = (addend + symbol + gp0 - gp);
2190       value &= howto->dst_mask;
2191       bfd_put_32 (input_bfd, value, hit_data);
2192       return bfd_reloc_ok;
2193
2194     case R_SCORE_GOT_LO16:
2195       addend = bfd_get_32 (input_bfd, hit_data);
2196       value = (((addend >> 16) & 0x3) << 14) | ((addend & 0x7fff) >> 1);
2197       value += symbol;
2198       value = (addend & (~(howto->dst_mask))) | ((value & 0x3fff) << 1)
2199                | (((value >> 14) & 0x3) << 16);
2200
2201       bfd_put_32 (input_bfd, value, hit_data);
2202       return bfd_reloc_ok;
2203
2204     case R_SCORE_DUMMY_HI16:
2205       return bfd_reloc_ok;
2206
2207     case R_SCORE_GNU_VTINHERIT:
2208     case R_SCORE_GNU_VTENTRY:
2209       /* We don't do anything with these at present.  */
2210       return bfd_reloc_continue;
2211
2212     default:
2213       return bfd_reloc_notsupported;
2214     }
2215 }
2216
2217 /* Score backend functions.  */
2218
2219 void
2220 s7_bfd_score_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
2221                             arelent *bfd_reloc,
2222                             Elf_Internal_Rela *elf_reloc)
2223 {
2224   unsigned int r_type;
2225
2226   r_type = ELF32_R_TYPE (elf_reloc->r_info);
2227   if (r_type >= ARRAY_SIZE (elf32_score_howto_table))
2228     bfd_reloc->howto = NULL;
2229   else
2230     bfd_reloc->howto = &elf32_score_howto_table[r_type];
2231 }
2232
2233 /* Relocate an score ELF section.  */
2234
2235 bfd_boolean
2236 s7_bfd_score_elf_relocate_section (bfd *output_bfd,
2237                                    struct bfd_link_info *info,
2238                                    bfd *input_bfd,
2239                                    asection *input_section,
2240                                    bfd_byte *contents,
2241                                    Elf_Internal_Rela *relocs,
2242                                    Elf_Internal_Sym *local_syms,
2243                                    asection **local_sections)
2244 {
2245   Elf_Internal_Shdr *symtab_hdr;
2246   struct elf_link_hash_entry **sym_hashes;
2247   Elf_Internal_Rela *rel;
2248   Elf_Internal_Rela *relend;
2249   const char *name;
2250   unsigned long offset;
2251   unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
2252   size_t extsymoff;
2253   bfd_boolean gp_disp_p = FALSE;
2254
2255   /* Sort dynsym.  */
2256   if (elf_hash_table (info)->dynamic_sections_created)
2257     {
2258       bfd_size_type dynsecsymcount = 0;
2259       if (info->shared)
2260         {
2261           asection * p;
2262           const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
2263
2264           for (p = output_bfd->sections; p ; p = p->next)
2265             if ((p->flags & SEC_EXCLUDE) == 0
2266                 && (p->flags & SEC_ALLOC) != 0
2267                 && !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p))
2268               ++ dynsecsymcount;
2269         }
2270
2271       if (!score_elf_sort_hash_table (info, dynsecsymcount + 1))
2272         return FALSE;
2273     }
2274
2275   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
2276   extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
2277   sym_hashes = elf_sym_hashes (input_bfd);
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 (!info->relocatable)
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           /* Find the real hash-table entry for this symbol.  */
2386           while (h->root.root.type == bfd_link_hash_indirect
2387                  || h->root.root.type == bfd_link_hash_warning)
2388             h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
2389
2390           /* Record the name of this symbol, for our caller.  */
2391           name = h->root.root.root.string;
2392
2393           /* See if this is the special GP_DISP_LABEL symbol.  Note that such a
2394              symbol must always be a global symbol.  */
2395           if (strcmp (name, GP_DISP_LABEL) == 0)
2396             {
2397               /* Relocations against GP_DISP_LABEL are permitted only with
2398                  R_SCORE_HI16 and R_SCORE_LO16 relocations.  */
2399               if (r_type != R_SCORE_HI16 && r_type != R_SCORE_LO16)
2400                 return bfd_reloc_notsupported;
2401
2402               gp_disp_p = TRUE;
2403             }
2404
2405           /* If this symbol is defined, calculate its address.  Note that
2406               GP_DISP_LABEL is a magic symbol, always implicitly defined by the
2407               linker, so it's inappropriate to check to see whether or not
2408               its defined.  */
2409           else if ((h->root.root.type == bfd_link_hash_defined
2410                     || h->root.root.type == bfd_link_hash_defweak)
2411                    && h->root.root.u.def.section)
2412             {
2413               sec = h->root.root.u.def.section;
2414               if (sec->output_section)
2415                 relocation = (h->root.root.u.def.value
2416                               + sec->output_section->vma
2417                               + sec->output_offset);
2418               else
2419                 {
2420                   relocation = h->root.root.u.def.value;
2421                 }
2422             }
2423           else if (h->root.root.type == bfd_link_hash_undefweak)
2424             /* We allow relocations against undefined weak symbols, giving
2425                it the value zero, so that you can undefined weak functions
2426                and check to see if they exist by looking at their addresses.  */
2427             relocation = 0;
2428           else if (info->unresolved_syms_in_objects == RM_IGNORE
2429                    && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
2430             relocation = 0;
2431           else if (strcmp (name, "_DYNAMIC_LINK") == 0)
2432             {
2433               /* If this is a dynamic link, we should have created a _DYNAMIC_LINK symbol
2434                  in s7_bfd_score_elf_create_dynamic_sections.  Otherwise, we should define
2435                  the symbol with a value of 0.  */
2436               BFD_ASSERT (! info->shared);
2437               BFD_ASSERT (bfd_get_section_by_name (output_bfd, ".dynamic") == NULL);
2438               relocation = 0;
2439             }
2440           else if (!info->relocatable)
2441             {
2442               if (! ((*info->callbacks->undefined_symbol)
2443                      (info, h->root.root.root.string, input_bfd,
2444                       input_section, rel->r_offset,
2445                       (info->unresolved_syms_in_objects == RM_GENERATE_ERROR)
2446                       || ELF_ST_VISIBILITY (h->root.other))))
2447                 return bfd_reloc_undefined;
2448               relocation = 0;
2449             }
2450         }
2451
2452       if (sec != NULL && elf_discarded_section (sec))
2453         {
2454           /* For relocs against symbols from removed linkonce sections,
2455              or sections discarded by a linker script, we just want the
2456              section contents zeroed.  Avoid any special processing.  */
2457           _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
2458           rel->r_info = 0;
2459           rel->r_addend = 0;
2460           continue;
2461         }
2462
2463       if (info->relocatable)
2464         {
2465           /* This is a relocatable link.  We don't have to change
2466              anything, unless the reloc is against a section symbol,
2467              in which case we have to adjust according to where the
2468              section symbol winds up in the output section.  */
2469           if (r_symndx < symtab_hdr->sh_info)
2470             {
2471               sym = local_syms + r_symndx;
2472
2473               if (r_type == R_SCORE_GOT15)
2474                 {
2475                   const Elf_Internal_Rela *lo16_rel;
2476                   const struct elf_backend_data *bed;
2477                   bfd_vma lo_addend = 0, lo_value = 0;
2478                   bfd_vma addend, value;
2479
2480                   value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2481                   addend = value & 0x7fff;
2482                   if ((addend & 0x4000) == 0x4000)
2483                     addend |= 0xffffc000;
2484
2485                   bed = get_elf_backend_data (output_bfd);
2486                   relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
2487                   lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
2488                   if (lo16_rel != NULL)
2489                     {
2490                       lo_value = bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
2491                       lo_addend = (((lo_value >> 16) & 0x3) << 14) | ((lo_value & 0x7fff) >> 1);
2492                     }
2493
2494                   addend <<= 16;
2495                   addend += lo_addend;
2496
2497                   if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2498                     addend += local_sections[r_symndx]->output_offset;
2499
2500                   lo_addend = addend & 0xffff;
2501                   lo_value = (lo_value & (~(howto->dst_mask))) | ((lo_addend & 0x3fff) << 1)
2502                               | (((lo_addend >> 14) & 0x3) << 16);
2503                   bfd_put_32 (input_bfd, lo_value, contents + lo16_rel->r_offset);
2504
2505                   addend = addend >> 16;
2506                   value = (value & ~howto->src_mask) | (addend & howto->src_mask);
2507                   bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2508                 }
2509               else if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2510                 {
2511                   sec = local_sections[r_symndx];
2512                   score_elf_add_to_rel (input_bfd, contents + rel->r_offset,
2513                                         howto, (bfd_signed_vma) (sec->output_offset + sym->st_value));
2514                 }
2515             }
2516           continue;
2517         }
2518
2519       /* This is a final link.  */
2520       r = score_elf_final_link_relocate (howto, input_bfd, output_bfd,
2521                                          input_section, contents, rel, relocs,
2522                                          relocation, info, name,
2523                                          (h ? ELF_ST_TYPE ((unsigned int) h->root.root.type) :
2524                                          ELF_ST_TYPE ((unsigned int) sym->st_info)), h, local_syms,
2525                                          local_sections, gp_disp_p);
2526
2527       if (r != bfd_reloc_ok)
2528         {
2529           const char *msg = (const char *)0;
2530
2531           switch (r)
2532             {
2533             case bfd_reloc_overflow:
2534               /* If the overflowing reloc was to an undefined symbol,
2535                  we have already printed one error message and there
2536                  is no point complaining again.  */
2537               if (((!h) || (h->root.root.type != bfd_link_hash_undefined))
2538                   && (!((*info->callbacks->reloc_overflow)
2539                         (info, NULL, name, howto->name, (bfd_vma) 0,
2540                          input_bfd, input_section, rel->r_offset))))
2541                 return FALSE;
2542               break;
2543             case bfd_reloc_undefined:
2544               if (!((*info->callbacks->undefined_symbol)
2545                     (info, name, input_bfd, input_section, rel->r_offset, TRUE)))
2546                 return FALSE;
2547               break;
2548
2549             case bfd_reloc_outofrange:
2550               msg = _("internal error: out of range error");
2551               goto common_error;
2552
2553             case bfd_reloc_notsupported:
2554               msg = _("internal error: unsupported relocation error");
2555               goto common_error;
2556
2557             case bfd_reloc_dangerous:
2558               msg = _("internal error: dangerous error");
2559               goto common_error;
2560
2561             default:
2562               msg = _("internal error: unknown error");
2563               /* fall through */
2564
2565             common_error:
2566               if (!((*info->callbacks->warning)
2567                     (info, msg, name, input_bfd, input_section, rel->r_offset)))
2568                 return FALSE;
2569               break;
2570             }
2571         }
2572     }
2573
2574   return TRUE;
2575 }
2576
2577 /* Look through the relocs for a section during the first phase, and
2578    allocate space in the global offset table.  */
2579
2580 bfd_boolean
2581 s7_bfd_score_elf_check_relocs (bfd *abfd,
2582                                struct bfd_link_info *info,
2583                                asection *sec,
2584                                const Elf_Internal_Rela *relocs)
2585 {
2586   const char *name;
2587   bfd *dynobj;
2588   Elf_Internal_Shdr *symtab_hdr;
2589   struct elf_link_hash_entry **sym_hashes;
2590   struct score_got_info *g;
2591   size_t extsymoff;
2592   const Elf_Internal_Rela *rel;
2593   const Elf_Internal_Rela *rel_end;
2594   asection *sgot;
2595   asection *sreloc;
2596   const struct elf_backend_data *bed;
2597
2598   if (info->relocatable)
2599     return TRUE;
2600
2601   dynobj = elf_hash_table (info)->dynobj;
2602   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2603   sym_hashes = elf_sym_hashes (abfd);
2604   extsymoff = (elf_bad_symtab (abfd)) ? 0 : symtab_hdr->sh_info;
2605
2606   name = bfd_get_section_name (abfd, sec);
2607
2608   if (dynobj == NULL)
2609     {
2610       sgot = NULL;
2611       g = NULL;
2612     }
2613   else
2614     {
2615       sgot = score_elf_got_section (dynobj, FALSE);
2616       if (sgot == NULL)
2617         g = NULL;
2618       else
2619         {
2620           BFD_ASSERT (score_elf_section_data (sgot) != NULL);
2621           g = score_elf_section_data (sgot)->u.got_info;
2622           BFD_ASSERT (g != NULL);
2623         }
2624     }
2625
2626   sreloc = NULL;
2627   bed = get_elf_backend_data (abfd);
2628   rel_end = relocs + sec->reloc_count * bed->s->int_rels_per_ext_rel;
2629   for (rel = relocs; rel < rel_end; ++rel)
2630     {
2631       unsigned long r_symndx;
2632       unsigned int r_type;
2633       struct elf_link_hash_entry *h;
2634
2635       r_symndx = ELF32_R_SYM (rel->r_info);
2636       r_type = ELF32_R_TYPE (rel->r_info);
2637
2638       if (r_symndx < extsymoff)
2639         {
2640           h = NULL;
2641         }
2642       else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr))
2643         {
2644           (*_bfd_error_handler) (_("%s: Malformed reloc detected for section %s"), abfd, name);
2645           bfd_set_error (bfd_error_bad_value);
2646           return FALSE;
2647         }
2648       else
2649         {
2650           h = sym_hashes[r_symndx - extsymoff];
2651
2652           /* This may be an indirect symbol created because of a version.  */
2653           if (h != NULL)
2654             {
2655               while (h->root.type == bfd_link_hash_indirect)
2656                 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2657             }
2658         }
2659
2660       /* Some relocs require a global offset table.  */
2661       if (dynobj == NULL || sgot == NULL)
2662         {
2663           switch (r_type)
2664             {
2665             case R_SCORE_GOT15:
2666             case R_SCORE_CALL15:
2667               if (dynobj == NULL)
2668                 elf_hash_table (info)->dynobj = dynobj = abfd;
2669               if (!score_elf_create_got_section (dynobj, info, FALSE))
2670                 return FALSE;
2671               g = score_elf_got_info (dynobj, &sgot);
2672               break;
2673             case R_SCORE_ABS32:
2674             case R_SCORE_REL32:
2675               if (dynobj == NULL && (info->shared || h != NULL) && (sec->flags & SEC_ALLOC) != 0)
2676                 elf_hash_table (info)->dynobj = dynobj = abfd;
2677               break;
2678             default:
2679               break;
2680             }
2681         }
2682
2683       if (!h && (r_type == R_SCORE_GOT_LO16))
2684         {
2685           if (! score_elf_record_local_got_symbol (abfd, r_symndx, rel->r_addend, g))
2686             return FALSE;
2687         }
2688
2689       switch (r_type)
2690         {
2691         case R_SCORE_CALL15:
2692           if (h == NULL)
2693             {
2694               (*_bfd_error_handler)
2695                 (_("%B: CALL15 reloc at 0x%lx not against global symbol"),
2696                  abfd, (unsigned long) rel->r_offset);
2697               bfd_set_error (bfd_error_bad_value);
2698               return FALSE;
2699             }
2700           else
2701             {
2702               /* This symbol requires a global offset table entry.  */
2703               if (! score_elf_record_global_got_symbol (h, abfd, info, g))
2704                 return FALSE;
2705
2706               /* We need a stub, not a plt entry for the undefined function.  But we record
2707                  it as if it needs plt.  See _bfd_elf_adjust_dynamic_symbol.  */
2708               h->needs_plt = 1;
2709               h->type = STT_FUNC;
2710             }
2711           break;
2712         case R_SCORE_GOT15:
2713           if (h && ! score_elf_record_global_got_symbol (h, abfd, info, g))
2714             return FALSE;
2715           break;
2716         case R_SCORE_ABS32:
2717         case R_SCORE_REL32:
2718           if ((info->shared || h != NULL) && (sec->flags & SEC_ALLOC) != 0)
2719             {
2720               if (sreloc == NULL)
2721                 {
2722                   sreloc = score_elf_rel_dyn_section (dynobj, TRUE);
2723                   if (sreloc == NULL)
2724                     return FALSE;
2725                 }
2726 #define SCORE_READONLY_SECTION (SEC_ALLOC | SEC_LOAD | SEC_READONLY)
2727               if (info->shared)
2728                 {
2729                   /* When creating a shared object, we must copy these reloc types into
2730                      the output file as R_SCORE_REL32 relocs.  We make room for this reloc
2731                      in the .rel.dyn reloc section.  */
2732                   score_elf_allocate_dynamic_relocations (dynobj, 1);
2733                   if ((sec->flags & SCORE_READONLY_SECTION)
2734                       == SCORE_READONLY_SECTION)
2735                     /* We tell the dynamic linker that there are
2736                        relocations against the text segment.  */
2737                     info->flags |= DF_TEXTREL;
2738                 }
2739               else
2740                 {
2741                   struct score_elf_link_hash_entry *hscore;
2742
2743                   /* We only need to copy this reloc if the symbol is
2744                      defined in a dynamic object.  */
2745                   hscore = (struct score_elf_link_hash_entry *) h;
2746                   ++hscore->possibly_dynamic_relocs;
2747                   if ((sec->flags & SCORE_READONLY_SECTION)
2748                       == SCORE_READONLY_SECTION)
2749                     /* We need it to tell the dynamic linker if there
2750                        are relocations against the text segment.  */
2751                     hscore->readonly_reloc = TRUE;
2752                 }
2753
2754               /* Even though we don't directly need a GOT entry for this symbol,
2755                  a symbol must have a dynamic symbol table index greater that
2756                  DT_SCORE_GOTSYM if there are dynamic relocations against it.  */
2757               if (h != NULL)
2758                 {
2759                   if (dynobj == NULL)
2760                     elf_hash_table (info)->dynobj = dynobj = abfd;
2761                   if (! score_elf_create_got_section (dynobj, info, TRUE))
2762                     return FALSE;
2763                   g = score_elf_got_info (dynobj, &sgot);
2764                   if (! score_elf_record_global_got_symbol (h, abfd, info, g))
2765                     return FALSE;
2766                 }
2767             }
2768           break;
2769
2770           /* This relocation describes the C++ object vtable hierarchy.
2771              Reconstruct it for later use during GC.  */
2772         case R_SCORE_GNU_VTINHERIT:
2773           if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
2774             return FALSE;
2775           break;
2776
2777           /* This relocation describes which C++ vtable entries are actually
2778              used.  Record for later use during GC.  */
2779         case R_SCORE_GNU_VTENTRY:
2780           if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
2781             return FALSE;
2782           break;
2783         default:
2784           break;
2785         }
2786
2787       /* We must not create a stub for a symbol that has relocations
2788          related to taking the function's address.  */
2789       switch (r_type)
2790         {
2791         default:
2792           if (h != NULL)
2793             {
2794               struct score_elf_link_hash_entry *sh;
2795
2796               sh = (struct score_elf_link_hash_entry *) h;
2797               sh->no_fn_stub = TRUE;
2798             }
2799           break;
2800         case R_SCORE_CALL15:
2801           break;
2802         }
2803     }
2804
2805   return TRUE;
2806 }
2807
2808 bfd_boolean
2809 s7_bfd_score_elf_add_symbol_hook (bfd *abfd,
2810                                   struct bfd_link_info *info ATTRIBUTE_UNUSED,
2811                                   Elf_Internal_Sym *sym,
2812                                   const char **namep ATTRIBUTE_UNUSED,
2813                                   flagword *flagsp ATTRIBUTE_UNUSED,
2814                                   asection **secp,
2815                                   bfd_vma *valp)
2816 {
2817   switch (sym->st_shndx)
2818     {
2819     case SHN_COMMON:
2820       if (sym->st_size > elf_gp_size (abfd))
2821         break;
2822       /* Fall through.  */
2823     case SHN_SCORE_SCOMMON:
2824       *secp = bfd_make_section_old_way (abfd, ".scommon");
2825       (*secp)->flags |= SEC_IS_COMMON;
2826       *valp = sym->st_size;
2827       break;
2828     }
2829
2830   return TRUE;
2831 }
2832
2833 void
2834 s7_bfd_score_elf_symbol_processing (bfd *abfd, asymbol *asym)
2835 {
2836   elf_symbol_type *elfsym;
2837
2838   elfsym = (elf_symbol_type *) asym;
2839   switch (elfsym->internal_elf_sym.st_shndx)
2840     {
2841     case SHN_COMMON:
2842       if (asym->value > elf_gp_size (abfd))
2843         break;
2844       /* Fall through.  */
2845     case SHN_SCORE_SCOMMON:
2846       if (score_elf_scom_section.name == NULL)
2847         {
2848           /* Initialize the small common section.  */
2849           score_elf_scom_section.name = ".scommon";
2850           score_elf_scom_section.flags = SEC_IS_COMMON;
2851           score_elf_scom_section.output_section = &score_elf_scom_section;
2852           score_elf_scom_section.symbol = &score_elf_scom_symbol;
2853           score_elf_scom_section.symbol_ptr_ptr = &score_elf_scom_symbol_ptr;
2854           score_elf_scom_symbol.name = ".scommon";
2855           score_elf_scom_symbol.flags = BSF_SECTION_SYM;
2856           score_elf_scom_symbol.section = &score_elf_scom_section;
2857           score_elf_scom_symbol_ptr = &score_elf_scom_symbol;
2858         }
2859       asym->section = &score_elf_scom_section;
2860       asym->value = elfsym->internal_elf_sym.st_size;
2861       break;
2862     }
2863 }
2864
2865 int
2866 s7_bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
2867                                           const char *name ATTRIBUTE_UNUSED,
2868                                           Elf_Internal_Sym *sym,
2869                                           asection *input_sec,
2870                                           struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
2871 {
2872   /* If we see a common symbol, which implies a relocatable link, then
2873      if a symbol was small common in an input file, mark it as small
2874      common in the output file.  */
2875   if (sym->st_shndx == SHN_COMMON && strcmp (input_sec->name, ".scommon") == 0)
2876     sym->st_shndx = SHN_SCORE_SCOMMON;
2877
2878   return 1;
2879 }
2880
2881 bfd_boolean
2882 s7_bfd_score_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
2883                                          asection *sec,
2884                                          int *retval)
2885 {
2886   if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
2887     {
2888       *retval = SHN_SCORE_SCOMMON;
2889       return TRUE;
2890     }
2891
2892   return FALSE;
2893 }
2894
2895 /* Adjust a symbol defined by a dynamic object and referenced by a
2896    regular object.  The current definition is in some section of the
2897    dynamic object, but we're not including those sections.  We have to
2898    change the definition to something the rest of the link can understand.  */
2899
2900 bfd_boolean
2901 s7_bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
2902                                         struct elf_link_hash_entry *h)
2903 {
2904   bfd *dynobj;
2905   struct score_elf_link_hash_entry *hscore;
2906   asection *s;
2907
2908   dynobj = elf_hash_table (info)->dynobj;
2909
2910   /* Make sure we know what is going on here.  */
2911   BFD_ASSERT (dynobj != NULL
2912               && (h->needs_plt
2913                   || h->u.weakdef != NULL
2914                   || (h->def_dynamic && h->ref_regular && !h->def_regular)));
2915
2916   /* If this symbol is defined in a dynamic object, we need to copy
2917      any R_SCORE_ABS32 or R_SCORE_REL32 relocs against it into the output
2918      file.  */
2919   hscore = (struct score_elf_link_hash_entry *) h;
2920   if (!info->relocatable
2921       && hscore->possibly_dynamic_relocs != 0
2922       && (h->root.type == bfd_link_hash_defweak || !h->def_regular))
2923     {
2924       score_elf_allocate_dynamic_relocations (dynobj, hscore->possibly_dynamic_relocs);
2925       if (hscore->readonly_reloc)
2926         /* We tell the dynamic linker that there are relocations
2927            against the text segment.  */
2928         info->flags |= DF_TEXTREL;
2929     }
2930
2931   /* For a function, create a stub, if allowed.  */
2932   if (!hscore->no_fn_stub && h->needs_plt)
2933     {
2934       if (!elf_hash_table (info)->dynamic_sections_created)
2935         return TRUE;
2936
2937       /* If this symbol is not defined in a regular file, then set
2938          the symbol to the stub location.  This is required to make
2939          function pointers compare as equal between the normal
2940          executable and the shared library.  */
2941       if (!h->def_regular)
2942         {
2943           /* We need .stub section.  */
2944           s = bfd_get_section_by_name (dynobj, SCORE_ELF_STUB_SECTION_NAME);
2945           BFD_ASSERT (s != NULL);
2946
2947           h->root.u.def.section = s;
2948           h->root.u.def.value = s->size;
2949
2950           /* XXX Write this stub address somewhere.  */
2951           h->plt.offset = s->size;
2952
2953           /* Make room for this stub code.  */
2954           s->size += SCORE_FUNCTION_STUB_SIZE;
2955
2956           /* The last half word of the stub will be filled with the index
2957              of this symbol in .dynsym section.  */
2958           return TRUE;
2959         }
2960     }
2961   else if ((h->type == STT_FUNC) && !h->needs_plt)
2962     {
2963       /* This will set the entry for this symbol in the GOT to 0, and
2964          the dynamic linker will take care of this.  */
2965       h->root.u.def.value = 0;
2966       return TRUE;
2967     }
2968
2969   /* If this is a weak symbol, and there is a real definition, the
2970      processor independent code will have arranged for us to see the
2971      real definition first, and we can just use the same value.  */
2972   if (h->u.weakdef != NULL)
2973     {
2974       BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2975                   || h->u.weakdef->root.type == bfd_link_hash_defweak);
2976       h->root.u.def.section = h->u.weakdef->root.u.def.section;
2977       h->root.u.def.value = h->u.weakdef->root.u.def.value;
2978       return TRUE;
2979     }
2980
2981   /* This is a reference to a symbol defined by a dynamic object which
2982      is not a function.  */
2983   return TRUE;
2984 }
2985
2986 /* This function is called after all the input files have been read,
2987    and the input sections have been assigned to output sections.  */
2988
2989 bfd_boolean
2990 s7_bfd_score_elf_always_size_sections (bfd *output_bfd,
2991                                        struct bfd_link_info *info)
2992 {
2993   bfd *dynobj;
2994   asection *s;
2995   struct score_got_info *g;
2996   int i;
2997   bfd_size_type loadable_size = 0;
2998   bfd_size_type local_gotno;
2999   bfd *sub;
3000
3001   dynobj = elf_hash_table (info)->dynobj;
3002   if (dynobj == NULL)
3003     /* Relocatable links don't have it.  */
3004     return TRUE;
3005
3006   g = score_elf_got_info (dynobj, &s);
3007   if (s == NULL)
3008     return TRUE;
3009
3010   /* Calculate the total loadable size of the output.  That will give us the
3011      maximum number of GOT_PAGE entries required.  */
3012   for (sub = info->input_bfds; sub; sub = sub->link_next)
3013     {
3014       asection *subsection;
3015
3016       for (subsection = sub->sections;
3017            subsection;
3018            subsection = subsection->next)
3019         {
3020           if ((subsection->flags & SEC_ALLOC) == 0)
3021             continue;
3022           loadable_size += ((subsection->size + 0xf)
3023                             &~ (bfd_size_type) 0xf);
3024         }
3025     }
3026
3027   /* There has to be a global GOT entry for every symbol with
3028      a dynamic symbol table index of DT_SCORE_GOTSYM or
3029      higher.  Therefore, it make sense to put those symbols
3030      that need GOT entries at the end of the symbol table.  We
3031      do that here.  */
3032   if (! score_elf_sort_hash_table (info, 1))
3033     return FALSE;
3034
3035   if (g->global_gotsym != NULL)
3036     i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx;
3037   else
3038     /* If there are no global symbols, or none requiring
3039        relocations, then GLOBAL_GOTSYM will be NULL.  */
3040     i = 0;
3041
3042   /* In the worst case, we'll get one stub per dynamic symbol.  */
3043   loadable_size += SCORE_FUNCTION_STUB_SIZE * i;
3044
3045   /* Assume there are two loadable segments consisting of
3046      contiguous sections.  Is 5 enough?  */
3047   local_gotno = (loadable_size >> 16) + 5;
3048
3049   g->local_gotno += local_gotno;
3050   s->size += g->local_gotno * SCORE_ELF_GOT_SIZE (output_bfd);
3051
3052   g->global_gotno = i;
3053   s->size += i * SCORE_ELF_GOT_SIZE (output_bfd);
3054
3055   score_elf_resolve_final_got_entries (g);
3056
3057   if (s->size > SCORE_ELF_GOT_MAX_SIZE (output_bfd))
3058     {
3059       /* Fixme. Error message or Warning message should be issued here.  */
3060     }
3061
3062   return TRUE;
3063 }
3064
3065 /* Set the sizes of the dynamic sections.  */
3066
3067 bfd_boolean
3068 s7_bfd_score_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
3069 {
3070   bfd *dynobj;
3071   asection *s;
3072   bfd_boolean reltext;
3073
3074   dynobj = elf_hash_table (info)->dynobj;
3075   BFD_ASSERT (dynobj != NULL);
3076
3077   if (elf_hash_table (info)->dynamic_sections_created)
3078     {
3079       /* Set the contents of the .interp section to the interpreter.  */
3080       if (!info->shared)
3081         {
3082           s = bfd_get_section_by_name (dynobj, ".interp");
3083           BFD_ASSERT (s != NULL);
3084           s->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
3085           s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
3086         }
3087     }
3088
3089   /* The check_relocs and adjust_dynamic_symbol entry points have
3090      determined the sizes of the various dynamic sections.  Allocate
3091      memory for them.  */
3092   reltext = FALSE;
3093   for (s = dynobj->sections; s != NULL; s = s->next)
3094     {
3095       const char *name;
3096
3097       if ((s->flags & SEC_LINKER_CREATED) == 0)
3098         continue;
3099
3100       /* It's OK to base decisions on the section name, because none
3101          of the dynobj section names depend upon the input files.  */
3102       name = bfd_get_section_name (dynobj, s);
3103
3104       if (CONST_STRNEQ (name, ".rel"))
3105         {
3106           if (s->size == 0)
3107             {
3108               /* We only strip the section if the output section name
3109                  has the same name.  Otherwise, there might be several
3110                  input sections for this output section.  FIXME: This
3111                  code is probably not needed these days anyhow, since
3112                  the linker now does not create empty output sections.  */
3113               if (s->output_section != NULL
3114                   && strcmp (name,
3115                              bfd_get_section_name (s->output_section->owner,
3116                                                    s->output_section)) == 0)
3117                 s->flags |= SEC_EXCLUDE;
3118             }
3119           else
3120             {
3121               const char *outname;
3122               asection *target;
3123
3124               /* If this relocation section applies to a read only
3125                  section, then we probably need a DT_TEXTREL entry.
3126                  If the relocation section is .rel.dyn, we always
3127                  assert a DT_TEXTREL entry rather than testing whether
3128                  there exists a relocation to a read only section or
3129                  not.  */
3130               outname = bfd_get_section_name (output_bfd, s->output_section);
3131               target = bfd_get_section_by_name (output_bfd, outname + 4);
3132               if ((target != NULL
3133                    && (target->flags & SEC_READONLY) != 0
3134                    && (target->flags & SEC_ALLOC) != 0) || strcmp (outname, ".rel.dyn") == 0)
3135                 reltext = TRUE;
3136
3137               /* We use the reloc_count field as a counter if we need
3138                  to copy relocs into the output file.  */
3139               if (strcmp (name, ".rel.dyn") != 0)
3140                 s->reloc_count = 0;
3141             }
3142         }
3143       else if (CONST_STRNEQ (name, ".got"))
3144         {
3145           /* s7_bfd_score_elf_always_size_sections() has already done
3146              most of the work, but some symbols may have been mapped
3147              to versions that we must now resolve in the got_entries
3148              hash tables.  */
3149         }
3150       else if (strcmp (name, SCORE_ELF_STUB_SECTION_NAME) == 0)
3151         {
3152           /* IRIX rld assumes that the function stub isn't at the end
3153              of .text section. So put a dummy. XXX  */
3154           s->size += SCORE_FUNCTION_STUB_SIZE;
3155         }
3156       else if (! CONST_STRNEQ (name, ".init"))
3157         {
3158           /* It's not one of our sections, so don't allocate space.  */
3159           continue;
3160         }
3161
3162       /* Allocate memory for the section contents.  */
3163       s->contents = bfd_zalloc (dynobj, s->size);
3164       if (s->contents == NULL && s->size != 0)
3165         {
3166           bfd_set_error (bfd_error_no_memory);
3167           return FALSE;
3168         }
3169     }
3170
3171   if (elf_hash_table (info)->dynamic_sections_created)
3172     {
3173       /* Add some entries to the .dynamic section.  We fill in the
3174          values later, in s7_bfd_score_elf_finish_dynamic_sections, but we
3175          must add the entries now so that we get the correct size for
3176          the .dynamic section.  The DT_DEBUG entry is filled in by the
3177          dynamic linker and used by the debugger.  */
3178
3179       if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0))
3180         return FALSE;
3181
3182       if (reltext)
3183         info->flags |= DF_TEXTREL;
3184
3185       if ((info->flags & DF_TEXTREL) != 0)
3186         {
3187           if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0))
3188             return FALSE;
3189         }
3190
3191       if (! SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTGOT, 0))
3192         return FALSE;
3193
3194       if (score_elf_rel_dyn_section (dynobj, FALSE))
3195         {
3196           if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_REL, 0))
3197             return FALSE;
3198
3199           if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELSZ, 0))
3200             return FALSE;
3201
3202           if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELENT, 0))
3203             return FALSE;
3204         }
3205
3206       if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_BASE_ADDRESS, 0))
3207         return FALSE;
3208
3209       if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_LOCAL_GOTNO, 0))
3210         return FALSE;
3211
3212       if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_SYMTABNO, 0))
3213         return FALSE;
3214
3215       if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_UNREFEXTNO, 0))
3216         return FALSE;
3217
3218       if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_GOTSYM, 0))
3219         return FALSE;
3220
3221       if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_HIPAGENO, 0))
3222         return FALSE;
3223     }
3224
3225   return TRUE;
3226 }
3227
3228 bfd_boolean
3229 s7_bfd_score_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
3230 {
3231   struct elf_link_hash_entry *h;
3232   struct bfd_link_hash_entry *bh;
3233   flagword flags;
3234   asection *s;
3235
3236   flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
3237            | SEC_LINKER_CREATED | SEC_READONLY);
3238
3239   /* ABI requests the .dynamic section to be read only.  */
3240   s = bfd_get_section_by_name (abfd, ".dynamic");
3241   if (s != NULL)
3242     {
3243       if (!bfd_set_section_flags (abfd, s, flags))
3244         return FALSE;
3245     }
3246
3247   /* We need to create .got section.  */
3248   if (!score_elf_create_got_section (abfd, info, FALSE))
3249     return FALSE;
3250
3251   if (!score_elf_rel_dyn_section (elf_hash_table (info)->dynobj, TRUE))
3252     return FALSE;
3253
3254   /* Create .stub section.  */
3255   if (bfd_get_section_by_name (abfd, SCORE_ELF_STUB_SECTION_NAME) == NULL)
3256     {
3257       s = bfd_make_section_with_flags (abfd, SCORE_ELF_STUB_SECTION_NAME,
3258                                        flags | SEC_CODE);
3259       if (s == NULL
3260           || !bfd_set_section_alignment (abfd, s, 2))
3261
3262         return FALSE;
3263     }
3264
3265   if (!info->shared)
3266     {
3267       const char *name;
3268
3269       name = "_DYNAMIC_LINK";
3270       bh = NULL;
3271       if (!(_bfd_generic_link_add_one_symbol
3272             (info, abfd, name, BSF_GLOBAL, bfd_abs_section_ptr,
3273              (bfd_vma) 0, NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
3274         return FALSE;
3275
3276       h = (struct elf_link_hash_entry *) bh;
3277       h->non_elf = 0;
3278       h->def_regular = 1;
3279       h->type = STT_SECTION;
3280
3281       if (!bfd_elf_link_record_dynamic_symbol (info, h))
3282         return FALSE;
3283     }
3284
3285   return TRUE;
3286 }
3287
3288
3289 /* Finish up dynamic symbol handling.  We set the contents of various
3290    dynamic sections here.  */
3291
3292 bfd_boolean
3293 s7_bfd_score_elf_finish_dynamic_symbol (bfd *output_bfd,
3294                                         struct bfd_link_info *info,
3295                                         struct elf_link_hash_entry *h,
3296                                         Elf_Internal_Sym *sym)
3297 {
3298   bfd *dynobj;
3299   asection *sgot;
3300   struct score_got_info *g;
3301   const char *name;
3302
3303   dynobj = elf_hash_table (info)->dynobj;
3304
3305   if (h->plt.offset != MINUS_ONE)
3306     {
3307       asection *s;
3308       bfd_byte stub[SCORE_FUNCTION_STUB_SIZE];
3309
3310       /* This symbol has a stub.  Set it up.  */
3311       BFD_ASSERT (h->dynindx != -1);
3312
3313       s = bfd_get_section_by_name (dynobj, SCORE_ELF_STUB_SECTION_NAME);
3314       BFD_ASSERT (s != NULL);
3315
3316       /* FIXME: Can h->dynindex be more than 64K?  */
3317       if (h->dynindx & 0xffff0000)
3318         return FALSE;
3319
3320       /* Fill the stub.  */
3321       bfd_put_32 (output_bfd, STUB_LW, stub);
3322       bfd_put_32 (output_bfd, STUB_MOVE, stub + 4);
3323       bfd_put_32 (output_bfd, STUB_LI16 | (h->dynindx << 1), stub + 8);
3324       bfd_put_32 (output_bfd, STUB_BRL, stub + 12);
3325
3326       BFD_ASSERT (h->plt.offset <= s->size);
3327       memcpy (s->contents + h->plt.offset, stub, SCORE_FUNCTION_STUB_SIZE);
3328
3329       /* Mark the symbol as undefined.  plt.offset != -1 occurs
3330          only for the referenced symbol.  */
3331       sym->st_shndx = SHN_UNDEF;
3332
3333       /* The run-time linker uses the st_value field of the symbol
3334           to reset the global offset table entry for this external
3335           to its stub address when unlinking a shared object.  */
3336       sym->st_value = (s->output_section->vma + s->output_offset + h->plt.offset);
3337     }
3338
3339   BFD_ASSERT (h->dynindx != -1 || h->forced_local);
3340
3341   sgot = score_elf_got_section (dynobj, FALSE);
3342   BFD_ASSERT (sgot != NULL);
3343   BFD_ASSERT (score_elf_section_data (sgot) != NULL);
3344   g = score_elf_section_data (sgot)->u.got_info;
3345   BFD_ASSERT (g != NULL);
3346
3347   /* Run through the global symbol table, creating GOT entries for all
3348      the symbols that need them.  */
3349   if (g->global_gotsym != NULL && h->dynindx >= g->global_gotsym->dynindx)
3350     {
3351       bfd_vma offset;
3352       bfd_vma value;
3353
3354       value = sym->st_value;
3355       offset = score_elf_global_got_index (dynobj, h);
3356       bfd_put_32 (output_bfd, value, sgot->contents + offset);
3357     }
3358
3359   /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
3360   name = h->root.root.string;
3361   if (strcmp (name, "_DYNAMIC") == 0 || strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
3362     sym->st_shndx = SHN_ABS;
3363   else if (strcmp (name, "_DYNAMIC_LINK") == 0)
3364     {
3365       sym->st_shndx = SHN_ABS;
3366       sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
3367       sym->st_value = 1;
3368     }
3369   else if (strcmp (name, GP_DISP_LABEL) == 0)
3370     {
3371       sym->st_shndx = SHN_ABS;
3372       sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
3373       sym->st_value = elf_gp (output_bfd);
3374     }
3375
3376   return TRUE;
3377 }
3378
3379 /* Finish up the dynamic sections.  */
3380
3381 bfd_boolean
3382 s7_bfd_score_elf_finish_dynamic_sections (bfd *output_bfd,
3383                                           struct bfd_link_info *info)
3384 {
3385   bfd *dynobj;
3386   asection *sdyn;
3387   asection *sgot;
3388   asection *s;
3389   struct score_got_info *g;
3390
3391   dynobj = elf_hash_table (info)->dynobj;
3392
3393   sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
3394
3395   sgot = score_elf_got_section (dynobj, FALSE);
3396   if (sgot == NULL)
3397     g = NULL;
3398   else
3399     {
3400       BFD_ASSERT (score_elf_section_data (sgot) != NULL);
3401       g = score_elf_section_data (sgot)->u.got_info;
3402       BFD_ASSERT (g != NULL);
3403     }
3404
3405   if (elf_hash_table (info)->dynamic_sections_created)
3406     {
3407       bfd_byte *b;
3408
3409       BFD_ASSERT (sdyn != NULL);
3410       BFD_ASSERT (g != NULL);
3411
3412       for (b = sdyn->contents;
3413            b < sdyn->contents + sdyn->size;
3414            b += SCORE_ELF_DYN_SIZE (dynobj))
3415         {
3416           Elf_Internal_Dyn dyn;
3417           const char *name;
3418           size_t elemsize;
3419           bfd_boolean swap_out_p;
3420
3421           /* Read in the current dynamic entry.  */
3422           (*get_elf_backend_data (dynobj)->s->swap_dyn_in) (dynobj, b, &dyn);
3423
3424           /* Assume that we're going to modify it and write it out.  */
3425           swap_out_p = TRUE;
3426
3427           switch (dyn.d_tag)
3428             {
3429             case DT_RELENT:
3430               s = score_elf_rel_dyn_section (dynobj, FALSE);
3431               BFD_ASSERT (s != NULL);
3432               dyn.d_un.d_val = SCORE_ELF_REL_SIZE (dynobj);
3433               break;
3434
3435             case DT_STRSZ:
3436               /* Rewrite DT_STRSZ.  */
3437               dyn.d_un.d_val = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
3438                     break;
3439
3440             case DT_PLTGOT:
3441               name = ".got";
3442               s = bfd_get_section_by_name (output_bfd, name);
3443               BFD_ASSERT (s != NULL);
3444               dyn.d_un.d_ptr = s->vma;
3445               break;
3446
3447             case DT_SCORE_BASE_ADDRESS:
3448               s = output_bfd->sections;
3449               BFD_ASSERT (s != NULL);
3450               dyn.d_un.d_ptr = s->vma & ~(bfd_vma) 0xffff;
3451               break;
3452
3453             case DT_SCORE_LOCAL_GOTNO:
3454               dyn.d_un.d_val = g->local_gotno;
3455               break;
3456
3457             case DT_SCORE_UNREFEXTNO:
3458               /* The index into the dynamic symbol table which is the
3459                  entry of the first external symbol that is not
3460                  referenced within the same object.  */
3461               dyn.d_un.d_val = bfd_count_sections (output_bfd) + 1;
3462               break;
3463
3464             case DT_SCORE_GOTSYM:
3465               if (g->global_gotsym)
3466                 {
3467                   dyn.d_un.d_val = g->global_gotsym->dynindx;
3468                   break;
3469                 }
3470               /* In case if we don't have global got symbols we default
3471                   to setting DT_SCORE_GOTSYM to the same value as
3472                   DT_SCORE_SYMTABNO, so we just fall through.  */
3473
3474             case DT_SCORE_SYMTABNO:
3475               name = ".dynsym";
3476               elemsize = SCORE_ELF_SYM_SIZE (output_bfd);
3477               s = bfd_get_section_by_name (output_bfd, name);
3478               BFD_ASSERT (s != NULL);
3479
3480               dyn.d_un.d_val = s->size / elemsize;
3481               break;
3482
3483             case DT_SCORE_HIPAGENO:
3484               dyn.d_un.d_val = g->local_gotno - SCORE_RESERVED_GOTNO;
3485               break;
3486
3487             default:
3488               swap_out_p = FALSE;
3489               break;
3490             }
3491
3492           if (swap_out_p)
3493             (*get_elf_backend_data (dynobj)->s->swap_dyn_out) (dynobj, &dyn, b);
3494         }
3495     }
3496
3497   /* The first entry of the global offset table will be filled at
3498      runtime. The second entry will be used by some runtime loaders.
3499      This isn't the case of IRIX rld.  */
3500   if (sgot != NULL && sgot->size > 0)
3501     {
3502       bfd_put_32 (output_bfd, 0, sgot->contents);
3503       bfd_put_32 (output_bfd, 0x80000000, sgot->contents + SCORE_ELF_GOT_SIZE (output_bfd));
3504     }
3505
3506   if (sgot != NULL)
3507     elf_section_data (sgot->output_section)->this_hdr.sh_entsize
3508       = SCORE_ELF_GOT_SIZE (output_bfd);
3509
3510
3511   /* We need to sort the entries of the dynamic relocation section.  */
3512   s = score_elf_rel_dyn_section (dynobj, FALSE);
3513
3514   if (s != NULL && s->size > (bfd_vma)2 * SCORE_ELF_REL_SIZE (output_bfd))
3515     {
3516       reldyn_sorting_bfd = output_bfd;
3517       qsort ((Elf32_External_Rel *) s->contents + 1, s->reloc_count - 1,
3518              sizeof (Elf32_External_Rel), score_elf_sort_dynamic_relocs);
3519     }
3520
3521   return TRUE;
3522 }
3523
3524 /* This function set up the ELF section header for a BFD section in preparation for writing
3525    it out.  This is where the flags and type fields are set for unusual sections.  */
3526
3527 bfd_boolean
3528 s7_bfd_score_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
3529                                 Elf_Internal_Shdr *hdr,
3530                                 asection *sec)
3531 {
3532   const char *name;
3533
3534   name = bfd_get_section_name (abfd, sec);
3535
3536   if (strcmp (name, ".got") == 0
3537       || strcmp (name, ".srdata") == 0
3538       || strcmp (name, ".sdata") == 0
3539       || strcmp (name, ".sbss") == 0)
3540     hdr->sh_flags |= SHF_SCORE_GPREL;
3541
3542   return TRUE;
3543 }
3544
3545 /* This function do additional processing on the ELF section header before writing
3546    it out.  This is used to set the flags and type fields for some sections.  */
3547
3548 /* assign_file_positions_except_relocs() check section flag and if it is allocatable,
3549    warning message will be issued.  backend_fake_section is called before
3550    assign_file_positions_except_relocs(); backend_section_processing after it.  so, we
3551    modify section flag there, but not backend_fake_section.  */
3552
3553 bfd_boolean
3554 s7_bfd_score_elf_section_processing (bfd *abfd ATTRIBUTE_UNUSED, Elf_Internal_Shdr *hdr)
3555 {
3556   if (hdr->bfd_section != NULL)
3557     {
3558       const char *name = bfd_get_section_name (abfd, hdr->bfd_section);
3559
3560       if (strcmp (name, ".sdata") == 0)
3561         {
3562           hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
3563           hdr->sh_type = SHT_PROGBITS;
3564         }
3565       else if (strcmp (name, ".sbss") == 0)
3566         {
3567           hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
3568           hdr->sh_type = SHT_NOBITS;
3569         }
3570       else if (strcmp (name, ".srdata") == 0)
3571         {
3572           hdr->sh_flags |= SHF_ALLOC | SHF_SCORE_GPREL;
3573           hdr->sh_type = SHT_PROGBITS;
3574         }
3575     }
3576
3577   return TRUE;
3578 }
3579
3580 bfd_boolean
3581 s7_bfd_score_elf_write_section (bfd *output_bfd, asection *sec, bfd_byte *contents)
3582 {
3583   bfd_byte *to, *from, *end;
3584   int i;
3585
3586   if (strcmp (sec->name, ".pdr") != 0)
3587     return FALSE;
3588
3589   if (score_elf_section_data (sec)->u.tdata == NULL)
3590     return FALSE;
3591
3592   to = contents;
3593   end = contents + sec->size;
3594   for (from = contents, i = 0; from < end; from += PDR_SIZE, i++)
3595     {
3596       if ((score_elf_section_data (sec)->u.tdata)[i] == 1)
3597         continue;
3598
3599       if (to != from)
3600         memcpy (to, from, PDR_SIZE);
3601
3602       to += PDR_SIZE;
3603     }
3604   bfd_set_section_contents (output_bfd, sec->output_section, contents,
3605                             (file_ptr) sec->output_offset, sec->size);
3606
3607   return TRUE;
3608 }
3609
3610 /* Copy data from a SCORE ELF indirect symbol to its direct symbol, hiding the old
3611    indirect symbol.  Process additional relocation information.  */
3612
3613 void
3614 s7_bfd_score_elf_copy_indirect_symbol (struct bfd_link_info *info,
3615                                        struct elf_link_hash_entry *dir,
3616                                        struct elf_link_hash_entry *ind)
3617 {
3618   struct score_elf_link_hash_entry *dirscore, *indscore;
3619
3620   _bfd_elf_link_hash_copy_indirect (info, dir, ind);
3621
3622   if (ind->root.type != bfd_link_hash_indirect)
3623     return;
3624
3625   dirscore = (struct score_elf_link_hash_entry *) dir;
3626   indscore = (struct score_elf_link_hash_entry *) ind;
3627   dirscore->possibly_dynamic_relocs += indscore->possibly_dynamic_relocs;
3628
3629   if (indscore->readonly_reloc)
3630     dirscore->readonly_reloc = TRUE;
3631
3632   if (indscore->no_fn_stub)
3633     dirscore->no_fn_stub = TRUE;
3634 }
3635
3636 /* Remove information about discarded functions from other sections which mention them.  */
3637
3638 bfd_boolean
3639 s7_bfd_score_elf_discard_info (bfd *abfd,
3640                                struct elf_reloc_cookie *cookie,
3641                                struct bfd_link_info *info)
3642 {
3643   asection *o;
3644   bfd_boolean ret = FALSE;
3645   unsigned char *tdata;
3646   size_t i, skip;
3647
3648   o = bfd_get_section_by_name (abfd, ".pdr");
3649   if ((!o) || (o->size == 0) || (o->size % PDR_SIZE != 0)
3650       || (o->output_section != NULL && bfd_is_abs_section (o->output_section)))
3651     return FALSE;
3652
3653   tdata = bfd_zmalloc (o->size / PDR_SIZE);
3654   if (!tdata)
3655     return FALSE;
3656
3657   cookie->rels = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, info->keep_memory);
3658   if (!cookie->rels)
3659     {
3660       free (tdata);
3661       return FALSE;
3662     }
3663
3664   cookie->rel = cookie->rels;
3665   cookie->relend = cookie->rels + o->reloc_count;
3666
3667   for (i = 0, skip = 0; i < o->size; i++)
3668     {
3669       if (bfd_elf_reloc_symbol_deleted_p (i * PDR_SIZE, cookie))
3670         {
3671           tdata[i] = 1;
3672           skip++;
3673         }
3674     }
3675
3676   if (skip != 0)
3677     {
3678       score_elf_section_data (o)->u.tdata = tdata;
3679       o->size -= skip * PDR_SIZE;
3680       ret = TRUE;
3681     }
3682   else
3683     free (tdata);
3684
3685   if (!info->keep_memory)
3686     free (cookie->rels);
3687
3688   return ret;
3689 }
3690
3691 /* Signal that discard_info() has removed the discarded relocations for this section.  */
3692
3693 bfd_boolean
3694 s7_bfd_score_elf_ignore_discarded_relocs (asection *sec)
3695 {
3696   if (strcmp (sec->name, ".pdr") == 0)
3697     return TRUE;
3698   return FALSE;
3699 }
3700
3701 /* Return the section that should be marked against GC for a given
3702    relocation.  */
3703
3704 asection *
3705 s7_bfd_score_elf_gc_mark_hook (asection *sec,
3706                                struct bfd_link_info *info,
3707                                Elf_Internal_Rela *rel,
3708                                struct elf_link_hash_entry *h,
3709                                Elf_Internal_Sym *sym)
3710 {
3711   if (h != NULL)
3712     switch (ELF32_R_TYPE (rel->r_info))
3713       {
3714       case R_SCORE_GNU_VTINHERIT:
3715       case R_SCORE_GNU_VTENTRY:
3716         return NULL;
3717       }
3718
3719   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
3720 }
3721
3722 /* Support for core dump NOTE sections.  */
3723
3724 bfd_boolean
3725 s7_bfd_score_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
3726 {
3727   int offset;
3728   unsigned int raw_size;
3729
3730   switch (note->descsz)
3731     {
3732     default:
3733       return FALSE;
3734     case 272:                  /* Linux/Score elf_prstatus */
3735
3736       /* pr_cursig */
3737       elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
3738
3739       /* pr_pid */
3740       elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
3741
3742       /* pr_reg */
3743       offset = 72;
3744
3745       /* sizeof(elf_gregset_t) */
3746       raw_size = 196;
3747
3748       break;
3749     }
3750
3751   /* Make a ".reg/999" section.  */
3752   return _bfd_elfcore_make_pseudosection (abfd, ".reg", raw_size, note->descpos + offset);
3753 }
3754
3755 bfd_boolean
3756 s7_bfd_score_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
3757 {
3758   switch (note->descsz)
3759     {
3760     default:
3761       return FALSE;
3762
3763     case 128:                  /* Linux/Score elf_prpsinfo.  */
3764       /* pr_fname */
3765       elf_tdata (abfd)->core_program = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
3766
3767       /* pr_psargs */
3768       elf_tdata (abfd)->core_command = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
3769       break;
3770     }
3771
3772   /* Note that for some reason, a spurious space is tacked
3773      onto the end of the args in some (at least one anyway)
3774      implementations, so strip it off if it exists.  */
3775
3776   {
3777     char *command = elf_tdata (abfd)->core_command;
3778     int n = strlen (command);
3779
3780     if (0 < n && command[n - 1] == ' ')
3781       command[n - 1] = '\0';
3782   }
3783
3784   return TRUE;
3785 }
3786
3787
3788 /* Score BFD functions.  */
3789
3790 reloc_howto_type *
3791 s7_elf32_score_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
3792 {
3793   unsigned int i;
3794
3795   for (i = 0; i < ARRAY_SIZE (elf32_score_reloc_map); i++)
3796     if (elf32_score_reloc_map[i].bfd_reloc_val == code)
3797       return &elf32_score_howto_table[elf32_score_reloc_map[i].elf_reloc_val];
3798
3799   return NULL;
3800 }
3801
3802 bfd_boolean
3803 s7_elf32_score_print_private_bfd_data (bfd *abfd, void * ptr)
3804 {
3805   FILE *file = (FILE *) ptr;
3806
3807   BFD_ASSERT (abfd != NULL && ptr != NULL);
3808
3809   /* Print normal ELF private data.  */
3810   _bfd_elf_print_private_bfd_data (abfd, ptr);
3811
3812   /* xgettext:c-format */
3813   fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
3814   if (elf_elfheader (abfd)->e_flags & EF_SCORE_PIC)
3815     {
3816       fprintf (file, _(" [pic]"));
3817     }
3818   if (elf_elfheader (abfd)->e_flags & EF_SCORE_FIXDEP)
3819     {
3820       fprintf (file, _(" [fix dep]"));
3821     }
3822   fputc ('\n', file);
3823
3824   return TRUE;
3825 }
3826
3827 bfd_boolean
3828 s7_elf32_score_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
3829 {
3830   flagword in_flags;
3831   flagword out_flags;
3832
3833   if (!_bfd_generic_verify_endian_match (ibfd, obfd))
3834     return FALSE;
3835
3836   in_flags  = elf_elfheader (ibfd)->e_flags;
3837   out_flags = elf_elfheader (obfd)->e_flags;
3838
3839   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
3840       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
3841     return TRUE;
3842
3843   in_flags = elf_elfheader (ibfd)->e_flags;
3844   out_flags = elf_elfheader (obfd)->e_flags;
3845
3846   if (! elf_flags_init (obfd))
3847     {
3848       elf_flags_init (obfd) = TRUE;
3849       elf_elfheader (obfd)->e_flags = in_flags;
3850
3851       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
3852           && bfd_get_arch_info (obfd)->the_default)
3853         {
3854           return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
3855         }
3856
3857       return TRUE;
3858     }
3859
3860   if (((in_flags & EF_SCORE_PIC) != 0) != ((out_flags & EF_SCORE_PIC) != 0))
3861     {
3862       (*_bfd_error_handler) (_("%B: warning: linking PIC files with non-PIC files"), ibfd);
3863     }
3864
3865   /* Maybe dependency fix compatibility should be checked here.  */
3866   return TRUE;
3867 }
3868
3869 bfd_boolean
3870 s7_elf32_score_new_section_hook (bfd *abfd, asection *sec)
3871 {
3872   struct _score_elf_section_data *sdata;
3873   bfd_size_type amt = sizeof (*sdata);
3874
3875   sdata = bfd_zalloc (abfd, amt);
3876   if (sdata == NULL)
3877     return FALSE;
3878   sec->used_by_bfd = sdata;
3879
3880   return _bfd_elf_new_section_hook (abfd, sec);
3881 }
3882
3883 #define elf_backend_omit_section_dynsym \
3884   ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)