OSDN Git Service

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