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