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