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