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