OSDN Git Service

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