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