gas/
[binutils.git] / bfd / elf32-score.c
blob17c4aa974f9bb84db43f23dfa89d58125180502b
1 /* 32-bit ELF support for S+core.
2 Copyright 2006 Free Software Foundation, Inc.
3 Contributed by
4 Mei Ligang (ligang@sunnorth.com.cn)
5 Pei-Lin Tsai (pltsai@sunplus.com)
7 This file is part of BFD, the Binary File Descriptor library.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
23 #include "bfd.h"
24 #include "sysdep.h"
25 #include "libbfd.h"
26 #include "libiberty.h"
27 #include "elf-bfd.h"
28 #include "elf/score.h"
29 #include "elf/common.h"
30 #include "elf/internal.h"
31 #include "hashtab.h"
34 /* Score ELF linker hash table. */
36 struct score_elf_link_hash_table
38 /* The main hash table. */
39 struct elf_link_hash_table root;
42 /* The SCORE ELF linker needs additional information for each symbol in
43 the global hash table. */
45 struct score_elf_link_hash_entry
47 struct elf_link_hash_entry root;
49 /* Number of R_SCORE_ABS32, R_SCORE_REL32 relocs against this symbol. */
50 unsigned int possibly_dynamic_relocs;
52 /* If the R_SCORE_ABS32, R_SCORE_REL32 reloc is against a readonly section. */
53 bfd_boolean readonly_reloc;
55 /* We must not create a stub for a symbol that has relocations related to
56 taking the function's address, i.e. any but R_SCORE_CALL15 ones. */
57 bfd_boolean no_fn_stub;
59 /* Are we forced local? This will only be set if we have converted
60 the initial global GOT entry to a local GOT entry. */
61 bfd_boolean forced_local;
64 /* Traverse a score ELF linker hash table. */
65 #define score_elf_link_hash_traverse(table, func, info) \
66 (elf_link_hash_traverse \
67 (&(table)->root, \
68 (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \
69 (info)))
71 /* Get the SCORE elf linker hash table from a link_info structure. */
72 #define score_elf_hash_table(info) \
73 ((struct score_elf_link_hash_table *) ((info)->hash))
75 /* This structure is used to hold .got entries while estimating got sizes. */
76 struct score_got_entry
78 /* The input bfd in which the symbol is defined. */
79 bfd *abfd;
80 /* The index of the symbol, as stored in the relocation r_info, if
81 we have a local symbol; -1 otherwise. */
82 long symndx;
83 union
85 /* If abfd == NULL, an address that must be stored in the got. */
86 bfd_vma address;
87 /* If abfd != NULL && symndx != -1, the addend of the relocation
88 that should be added to the symbol value. */
89 bfd_vma addend;
90 /* If abfd != NULL && symndx == -1, the hash table entry
91 corresponding to a global symbol in the got (or, local, if
92 h->forced_local). */
93 struct score_elf_link_hash_entry *h;
94 } d;
96 /* The offset from the beginning of the .got section to the entry
97 corresponding to this symbol+addend. If it's a global symbol
98 whose offset is yet to be decided, it's going to be -1. */
99 long gotidx;
102 /* This structure is passed to score_elf_sort_hash_table_f when sorting
103 the dynamic symbols. */
105 struct score_elf_hash_sort_data
107 /* The symbol in the global GOT with the lowest dynamic symbol table index. */
108 struct elf_link_hash_entry *low;
109 /* The least dynamic symbol table index corresponding to a symbol with a GOT entry. */
110 long min_got_dynindx;
111 /* The greatest dynamic symbol table index corresponding to a symbol
112 with a GOT entry that is not referenced (e.g., a dynamic symbol
113 with dynamic relocations pointing to it from non-primary GOTs). */
114 long max_unref_got_dynindx;
115 /* The greatest dynamic symbol table index not corresponding to a
116 symbol without a GOT entry. */
117 long max_non_got_dynindx;
120 struct score_got_info
122 /* The global symbol in the GOT with the lowest index in the dynamic
123 symbol table. */
124 struct elf_link_hash_entry *global_gotsym;
125 /* The number of global .got entries. */
126 unsigned int global_gotno;
127 /* The number of local .got entries. */
128 unsigned int local_gotno;
129 /* The number of local .got entries we have used. */
130 unsigned int assigned_gotno;
131 /* A hash table holding members of the got. */
132 struct htab *got_entries;
133 /* In multi-got links, a pointer to the next got (err, rather, most
134 of the time, it points to the previous got). */
135 struct score_got_info *next;
138 /* A structure used to count GOT entries, for GOT entry or ELF symbol table traversal. */
139 struct _score_elf_section_data
141 struct bfd_elf_section_data elf;
142 union
144 struct score_got_info *got_info;
145 bfd_byte *tdata;
150 #define score_elf_section_data(sec) \
151 ((struct _score_elf_section_data *) elf_section_data (sec))
153 /* The size of a symbol-table entry. */
154 #define SCORE_ELF_SYM_SIZE(abfd) \
155 (get_elf_backend_data (abfd)->s->sizeof_sym)
157 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
158 from smaller values. Start with zero, widen, *then* decrement. */
159 #define MINUS_ONE (((bfd_vma)0) - 1)
160 #define MINUS_TWO (((bfd_vma)0) - 2)
162 #define PDR_SIZE 32
165 /* The number of local .got entries we reserve. */
166 #define SCORE_RESERVED_GOTNO (2)
167 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
169 /* The offset of $gp from the beginning of the .got section. */
170 #define ELF_SCORE_GP_OFFSET(abfd) (0x3ff0)
171 /* The maximum size of the GOT for it to be addressable using 15-bit offsets from $gp. */
172 #define SCORE_ELF_GOT_MAX_SIZE(abfd) (ELF_SCORE_GP_OFFSET(abfd) + 0x3fff)
174 #define SCORE_ELF_STUB_SECTION_NAME (".SCORE.stub")
175 #define SCORE_FUNCTION_STUB_SIZE (16)
177 #define STUB_LW 0xc3bcc010 /* lw r29, [r28, -0x3ff0] */
178 #define STUB_MOVE 0x8363bc56 /* mv r27, r3 */
179 #define STUB_LI16 0x87548000 /* ori r26, .dynsym_index */
180 #define STUB_BRL 0x801dbc09 /* brl r29 */
182 #define SCORE_ELF_GOT_SIZE(abfd) \
183 (get_elf_backend_data (abfd)->s->arch_size / 8)
185 #define SCORE_ELF_ADD_DYNAMIC_ENTRY(info, tag, val) \
186 (_bfd_elf_add_dynamic_entry (info, (bfd_vma) tag, (bfd_vma) val))
188 /* The size of an external dynamic table entry. */
189 #define SCORE_ELF_DYN_SIZE(abfd) \
190 (get_elf_backend_data (abfd)->s->sizeof_dyn)
192 /* The size of an external REL relocation. */
193 #define SCORE_ELF_REL_SIZE(abfd) \
194 (get_elf_backend_data (abfd)->s->sizeof_rel)
196 /* The default alignment for sections, as a power of two. */
197 #define SCORE_ELF_LOG_FILE_ALIGN(abfd)\
198 (get_elf_backend_data (abfd)->s->log_file_align)
200 #ifndef NUM_ELEM
201 #define NUM_ELEM(a) (sizeof (a) / (sizeof (a)[0]))
202 #endif
204 static bfd_byte *hi16_rel_addr;
206 /* This will be used when we sort the dynamic relocation records. */
207 static bfd *reldyn_sorting_bfd;
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;
218 static bfd_reloc_status_type
219 score_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED,
220 arelent *reloc_entry,
221 asymbol *symbol ATTRIBUTE_UNUSED,
222 void * data,
223 asection *input_section ATTRIBUTE_UNUSED,
224 bfd *output_bfd ATTRIBUTE_UNUSED,
225 char **error_message ATTRIBUTE_UNUSED)
227 hi16_rel_addr = (bfd_byte *) data + reloc_entry->address;
228 return bfd_reloc_ok;
231 static bfd_reloc_status_type
232 score_elf_lo16_reloc (bfd *abfd,
233 arelent *reloc_entry,
234 asymbol *symbol ATTRIBUTE_UNUSED,
235 void * data,
236 asection *input_section,
237 bfd *output_bfd ATTRIBUTE_UNUSED,
238 char **error_message ATTRIBUTE_UNUSED)
240 bfd_vma addend = 0, offset = 0;
241 unsigned long val;
242 unsigned long hi16_offset, hi16_value, uvalue;
244 hi16_value = bfd_get_32 (abfd, hi16_rel_addr);
245 hi16_offset = ((((hi16_value >> 16) & 0x3) << 15) | (hi16_value & 0x7fff)) >> 1;
246 addend = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
247 offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
248 val = reloc_entry->addend;
249 if (reloc_entry->address > input_section->size)
250 return bfd_reloc_outofrange;
251 uvalue = ((hi16_offset << 16) | (offset & 0xffff)) + val;
252 hi16_offset = (uvalue >> 16) << 1;
253 hi16_value = (hi16_value & ~0x37fff) | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
254 bfd_put_32 (abfd, hi16_value, hi16_rel_addr);
255 offset = (uvalue & 0xffff) << 1;
256 addend = (addend & ~0x37fff) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
257 bfd_put_32 (abfd, addend, (bfd_byte *) data + reloc_entry->address);
258 return bfd_reloc_ok;
261 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
262 dangerous relocation. */
264 static bfd_boolean
265 score_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
267 unsigned int count;
268 asymbol **sym;
269 unsigned int i;
271 /* If we've already figured out what GP will be, just return it. */
272 *pgp = _bfd_get_gp_value (output_bfd);
273 if (*pgp)
274 return TRUE;
276 count = bfd_get_symcount (output_bfd);
277 sym = bfd_get_outsymbols (output_bfd);
279 /* The linker script will have created a symbol named `_gp' with the
280 appropriate value. */
281 if (sym == NULL)
282 i = count;
283 else
285 for (i = 0; i < count; i++, sym++)
287 const char *name;
289 name = bfd_asymbol_name (*sym);
290 if (*name == '_' && strcmp (name, "_gp") == 0)
292 *pgp = bfd_asymbol_value (*sym);
293 _bfd_set_gp_value (output_bfd, *pgp);
294 break;
299 if (i >= count)
301 /* Only get the error once. */
302 *pgp = 4;
303 _bfd_set_gp_value (output_bfd, *pgp);
304 return FALSE;
307 return TRUE;
310 /* We have to figure out the gp value, so that we can adjust the
311 symbol value correctly. We look up the symbol _gp in the output
312 BFD. If we can't find it, we're stuck. We cache it in the ELF
313 target data. We don't need to adjust the symbol value for an
314 external symbol if we are producing relocatable output. */
316 static bfd_reloc_status_type
317 score_elf_final_gp (bfd *output_bfd,
318 asymbol *symbol,
319 bfd_boolean relocatable,
320 char **error_message,
321 bfd_vma *pgp)
323 if (bfd_is_und_section (symbol->section)
324 && ! relocatable)
326 *pgp = 0;
327 return bfd_reloc_undefined;
330 *pgp = _bfd_get_gp_value (output_bfd);
331 if (*pgp == 0
332 && (! relocatable
333 || (symbol->flags & BSF_SECTION_SYM) != 0))
335 if (relocatable)
337 /* Make up a value. */
338 *pgp = symbol->section->output_section->vma + 0x4000;
339 _bfd_set_gp_value (output_bfd, *pgp);
341 else if (!score_elf_assign_gp (output_bfd, pgp))
343 *error_message =
344 (char *) _("GP relative relocation when _gp not defined");
345 return bfd_reloc_dangerous;
349 return bfd_reloc_ok;
352 static bfd_reloc_status_type
353 score_elf_gprel15_with_gp (bfd *abfd,
354 asymbol *symbol,
355 arelent *reloc_entry,
356 asection *input_section,
357 bfd_boolean relocateable,
358 void * data,
359 bfd_vma gp ATTRIBUTE_UNUSED)
361 bfd_vma relocation;
362 unsigned long insn;
364 if (bfd_is_com_section (symbol->section))
365 relocation = 0;
366 else
367 relocation = symbol->value;
369 relocation += symbol->section->output_section->vma;
370 relocation += symbol->section->output_offset;
371 if (reloc_entry->address > input_section->size)
372 return bfd_reloc_outofrange;
374 insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
375 if (((reloc_entry->addend & 0xffffc000) != 0)
376 && ((reloc_entry->addend & 0xffffc000) != 0xffffc000))
377 return bfd_reloc_overflow;
379 insn = (insn & ~0x7fff) | (reloc_entry->addend & 0x7fff);
380 bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
381 if (relocateable)
382 reloc_entry->address += input_section->output_offset;
384 return bfd_reloc_ok;
387 static bfd_reloc_status_type
388 gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
389 asection *input_section, bfd_boolean relocatable,
390 void *data, bfd_vma gp)
392 bfd_vma relocation;
393 bfd_vma val;
395 if (bfd_is_com_section (symbol->section))
396 relocation = 0;
397 else
398 relocation = symbol->value;
400 relocation += symbol->section->output_section->vma;
401 relocation += symbol->section->output_offset;
403 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
404 return bfd_reloc_outofrange;
406 /* Set val to the offset into the section or symbol. */
407 val = reloc_entry->addend;
409 if (reloc_entry->howto->partial_inplace)
410 val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
412 /* Adjust val for the final section location and GP value. If we
413 are producing relocatable output, we don't want to do this for
414 an external symbol. */
415 if (! relocatable
416 || (symbol->flags & BSF_SECTION_SYM) != 0)
417 val += relocation - gp;
419 if (reloc_entry->howto->partial_inplace)
420 bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
421 else
422 reloc_entry->addend = val;
424 if (relocatable)
425 reloc_entry->address += input_section->output_offset;
427 return bfd_reloc_ok;
430 static bfd_reloc_status_type
431 score_elf_gprel15_reloc (bfd *abfd,
432 arelent *reloc_entry,
433 asymbol *symbol,
434 void * data,
435 asection *input_section,
436 bfd *output_bfd,
437 char **error_message)
439 bfd_boolean relocateable;
440 bfd_reloc_status_type ret;
441 bfd_vma gp;
443 if (output_bfd != (bfd *) NULL
444 && (symbol->flags & BSF_SECTION_SYM) == 0 && reloc_entry->addend == 0)
446 reloc_entry->address += input_section->output_offset;
447 return bfd_reloc_ok;
449 if (output_bfd != (bfd *) NULL)
450 relocateable = TRUE;
451 else
453 relocateable = FALSE;
454 output_bfd = symbol->section->output_section->owner;
457 ret = score_elf_final_gp (output_bfd, symbol, relocateable, error_message, &gp);
458 if (ret != bfd_reloc_ok)
459 return ret;
461 return score_elf_gprel15_with_gp (abfd, symbol, reloc_entry,
462 input_section, relocateable, data, gp);
465 /* Do a R_SCORE_GPREL32 relocation. This is a 32 bit value which must
466 become the offset from the gp register. */
468 static bfd_reloc_status_type
469 score_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
470 void *data, asection *input_section, bfd *output_bfd,
471 char **error_message)
473 bfd_boolean relocatable;
474 bfd_reloc_status_type ret;
475 bfd_vma gp;
477 /* R_SCORE_GPREL32 relocations are defined for local symbols only. */
478 if (output_bfd != NULL
479 && (symbol->flags & BSF_SECTION_SYM) == 0
480 && (symbol->flags & BSF_LOCAL) != 0)
482 *error_message = (char *)
483 _("32bits gp relative relocation occurs for an external symbol");
484 return bfd_reloc_outofrange;
487 if (output_bfd != NULL)
488 relocatable = TRUE;
489 else
491 relocatable = FALSE;
492 output_bfd = symbol->section->output_section->owner;
495 ret = score_elf_final_gp (output_bfd, symbol, relocatable, error_message, &gp);
496 if (ret != bfd_reloc_ok)
497 return ret;
499 gp = 0; /* FIXME. */
500 return gprel32_with_gp (abfd, symbol, reloc_entry, input_section,
501 relocatable, data, gp);
504 /* A howto special_function for R_SCORE_GOT15 relocations. This is just
505 like any other 16-bit relocation when applied to global symbols, but is
506 treated in the same as R_SCORE_HI16 when applied to local symbols. */
508 static bfd_reloc_status_type
509 score_elf_got15_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
510 void *data, asection *input_section,
511 bfd *output_bfd, char **error_message)
513 if ((symbol->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
514 || bfd_is_und_section (bfd_get_section (symbol))
515 || bfd_is_com_section (bfd_get_section (symbol)))
516 /* The relocation is against a global symbol. */
517 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
518 input_section, output_bfd,
519 error_message);
521 return score_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
522 input_section, output_bfd, error_message);
525 static bfd_reloc_status_type
526 score_elf_got_lo16_reloc (bfd *abfd,
527 arelent *reloc_entry,
528 asymbol *symbol ATTRIBUTE_UNUSED,
529 void * data,
530 asection *input_section,
531 bfd *output_bfd ATTRIBUTE_UNUSED,
532 char **error_message ATTRIBUTE_UNUSED)
534 bfd_vma addend = 0, offset = 0;
535 unsigned long val;
536 unsigned long hi16_offset, hi16_value, uvalue;
538 hi16_value = bfd_get_32 (abfd, hi16_rel_addr);
539 hi16_offset = ((((hi16_value >> 16) & 0x3) << 15) | (hi16_value & 0x7fff)) >> 1;
540 addend = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
541 offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
542 val = reloc_entry->addend;
543 if (reloc_entry->address > input_section->size)
544 return bfd_reloc_outofrange;
545 uvalue = ((hi16_offset << 16) | (offset & 0xffff)) + val;
546 hi16_offset = (uvalue >> 16) & 0x7fff;
547 hi16_value = (hi16_value & ~0x37fff) | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
548 bfd_put_32 (abfd, hi16_value, hi16_rel_addr);
549 offset = (uvalue & 0xffff) << 1;
550 addend = (addend & ~0x37fff) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
551 bfd_put_32 (abfd, addend, (bfd_byte *) data + reloc_entry->address);
552 return bfd_reloc_ok;
555 static reloc_howto_type elf32_score_howto_table[] =
557 /* No relocation. */
558 HOWTO (R_SCORE_NONE, /* type */
559 0, /* rightshift */
560 0, /* size (0 = byte, 1 = short, 2 = long) */
561 0, /* bitsize */
562 FALSE, /* pc_relative */
563 0, /* bitpos */
564 complain_overflow_dont,/* complain_on_overflow */
565 bfd_elf_generic_reloc, /* special_function */
566 "R_SCORE_NONE", /* name */
567 FALSE, /* partial_inplace */
568 0, /* src_mask */
569 0, /* dst_mask */
570 FALSE), /* pcrel_offset */
572 /* R_SCORE_HI16 */
573 HOWTO (R_SCORE_HI16, /* type */
574 0, /* rightshift */
575 2, /* size (0 = byte, 1 = short, 2 = long) */
576 16, /* bitsize */
577 FALSE, /* pc_relative */
578 1, /* bitpos */
579 complain_overflow_dont,/* complain_on_overflow */
580 score_elf_hi16_reloc, /* special_function */
581 "R_SCORE_HI16", /* name */
582 TRUE, /* partial_inplace */
583 0x37fff, /* src_mask */
584 0x37fff, /* dst_mask */
585 FALSE), /* pcrel_offset */
587 /* R_SCORE_LO16 */
588 HOWTO (R_SCORE_LO16, /* type */
589 0, /* rightshift */
590 2, /* size (0 = byte, 1 = short, 2 = long) */
591 16, /* bitsize */
592 FALSE, /* pc_relative */
593 1, /* bitpos */
594 complain_overflow_dont,/* complain_on_overflow */
595 score_elf_lo16_reloc, /* special_function */
596 "R_SCORE_LO16", /* name */
597 TRUE, /* partial_inplace */
598 0x37fff, /* src_mask */
599 0x37fff, /* dst_mask */
600 FALSE), /* pcrel_offset */
602 /* R_SCORE_DUMMY1 */
603 HOWTO (R_SCORE_DUMMY1, /* type */
604 0, /* rightshift */
605 2, /* size (0 = byte, 1 = short, 2 = long) */
606 16, /* bitsize */
607 FALSE, /* pc_relative */
608 1, /* bitpos */
609 complain_overflow_dont,/* complain_on_overflow */
610 bfd_elf_generic_reloc, /* special_function */
611 "R_SCORE_DUMMY1", /* name */
612 TRUE, /* partial_inplace */
613 0x0000ffff, /* src_mask */
614 0x0000ffff, /* dst_mask */
615 FALSE), /* pcrel_offset */
617 /*R_SCORE_24 */
618 HOWTO (R_SCORE_24, /* type */
619 1, /* rightshift */
620 2, /* size (0 = byte, 1 = short, 2 = long) */
621 24, /* bitsize */
622 FALSE, /* pc_relative */
623 1, /* bitpos */
624 complain_overflow_dont,/* complain_on_overflow */
625 bfd_elf_generic_reloc, /* special_function */
626 "R_SCORE_24", /* name */
627 FALSE, /* partial_inplace */
628 0x3ff7fff, /* src_mask */
629 0x3ff7fff, /* dst_mask */
630 FALSE), /* pcrel_offset */
632 /*R_SCORE_PC19 */
633 HOWTO (R_SCORE_PC19, /* type */
634 1, /* rightshift */
635 2, /* size (0 = byte, 1 = short, 2 = long) */
636 19, /* bitsize */
637 TRUE, /* pc_relative */
638 1, /* bitpos */
639 complain_overflow_dont,/* complain_on_overflow */
640 bfd_elf_generic_reloc, /* special_function */
641 "R_SCORE_PC19", /* name */
642 FALSE, /* partial_inplace */
643 0x3ff03fe, /* src_mask */
644 0x3ff03fe, /* dst_mask */
645 FALSE), /* pcrel_offset */
647 /*R_SCORE16_11 */
648 HOWTO (R_SCORE16_11, /* type */
649 1, /* rightshift */
650 1, /* size (0 = byte, 1 = short, 2 = long) */
651 11, /* bitsize */
652 FALSE, /* pc_relative */
653 1, /* bitpos */
654 complain_overflow_dont,/* complain_on_overflow */
655 bfd_elf_generic_reloc, /* special_function */
656 "R_SCORE16_11", /* name */
657 FALSE, /* partial_inplace */
658 0x000000ffe, /* src_mask */
659 0x000000ffe, /* dst_mask */
660 FALSE), /* pcrel_offset */
662 /* R_SCORE16_PC8 */
663 HOWTO (R_SCORE16_PC8, /* type */
664 1, /* rightshift */
665 1, /* size (0 = byte, 1 = short, 2 = long) */
666 8, /* bitsize */
667 TRUE, /* pc_relative */
668 0, /* bitpos */
669 complain_overflow_dont,/* complain_on_overflow */
670 bfd_elf_generic_reloc, /* special_function */
671 "R_SCORE16_PC8", /* name */
672 FALSE, /* partial_inplace */
673 0x000000ff, /* src_mask */
674 0x000000ff, /* dst_mask */
675 FALSE), /* pcrel_offset */
677 /* 32 bit absolute */
678 HOWTO (R_SCORE_ABS32, /* type 8 */
679 0, /* rightshift */
680 2, /* size (0 = byte, 1 = short, 2 = long) */
681 32, /* bitsize */
682 FALSE, /* pc_relative */
683 0, /* bitpos */
684 complain_overflow_bitfield, /* complain_on_overflow */
685 bfd_elf_generic_reloc, /* special_function */
686 "R_SCORE_ABS32", /* name */
687 FALSE, /* partial_inplace */
688 0xffffffff, /* src_mask */
689 0xffffffff, /* dst_mask */
690 FALSE), /* pcrel_offset */
692 /* 16 bit absolute */
693 HOWTO (R_SCORE_ABS16, /* type 11 */
694 0, /* rightshift */
695 1, /* size (0 = byte, 1 = short, 2 = long) */
696 16, /* bitsize */
697 FALSE, /* pc_relative */
698 0, /* bitpos */
699 complain_overflow_bitfield, /* complain_on_overflow */
700 bfd_elf_generic_reloc, /* special_function */
701 "R_SCORE_ABS16", /* name */
702 FALSE, /* partial_inplace */
703 0x0000ffff, /* src_mask */
704 0x0000ffff, /* dst_mask */
705 FALSE), /* pcrel_offset */
707 /* R_SCORE_DUMMY2 */
708 HOWTO (R_SCORE_DUMMY2, /* type */
709 0, /* rightshift */
710 2, /* size (0 = byte, 1 = short, 2 = long) */
711 16, /* bitsize */
712 FALSE, /* pc_relative */
713 0, /* bitpos */
714 complain_overflow_dont,/* complain_on_overflow */
715 bfd_elf_generic_reloc, /* special_function */
716 "R_SCORE_DUMMY2", /* name */
717 TRUE, /* partial_inplace */
718 0x00007fff, /* src_mask */
719 0x00007fff, /* dst_mask */
720 FALSE), /* pcrel_offset */
722 /* R_SCORE_GP15 */
723 HOWTO (R_SCORE_GP15, /* type */
724 0, /* rightshift */
725 2, /* size (0 = byte, 1 = short, 2 = long) */
726 16, /* bitsize */
727 FALSE, /* pc_relative */
728 0, /* bitpos */
729 complain_overflow_dont,/* complain_on_overflow */
730 score_elf_gprel15_reloc,/* special_function */
731 "R_SCORE_GP15", /* name */
732 TRUE, /* partial_inplace */
733 0x00007fff, /* src_mask */
734 0x00007fff, /* dst_mask */
735 FALSE), /* pcrel_offset */
737 /* GNU extension to record C++ vtable hierarchy. */
738 HOWTO (R_SCORE_GNU_VTINHERIT, /* type */
739 0, /* rightshift */
740 2, /* size (0 = byte, 1 = short, 2 = long) */
741 0, /* bitsize */
742 FALSE, /* pc_relative */
743 0, /* bitpos */
744 complain_overflow_dont,/* complain_on_overflow */
745 NULL, /* special_function */
746 "R_SCORE_GNU_VTINHERIT", /* name */
747 FALSE, /* partial_inplace */
748 0, /* src_mask */
749 0, /* dst_mask */
750 FALSE), /* pcrel_offset */
752 /* GNU extension to record C++ vtable member usage */
753 HOWTO (R_SCORE_GNU_VTENTRY, /* type */
754 0, /* rightshift */
755 2, /* size (0 = byte, 1 = short, 2 = long) */
756 0, /* bitsize */
757 FALSE, /* pc_relative */
758 0, /* bitpos */
759 complain_overflow_dont,/* complain_on_overflow */
760 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
761 "R_SCORE_GNU_VTENTRY", /* name */
762 FALSE, /* partial_inplace */
763 0, /* src_mask */
764 0, /* dst_mask */
765 FALSE), /* pcrel_offset */
767 /* Reference to global offset table. */
768 HOWTO (R_SCORE_GOT15, /* type */
769 0, /* rightshift */
770 2, /* size (0 = byte, 1 = short, 2 = long) */
771 16, /* bitsize */
772 FALSE, /* pc_relative */
773 0, /* bitpos */
774 complain_overflow_signed, /* complain_on_overflow */
775 score_elf_got15_reloc, /* special_function */
776 "R_SCORE_GOT15", /* name */
777 TRUE, /* partial_inplace */
778 0x00007fff, /* src_mask */
779 0x00007fff, /* dst_mask */
780 FALSE), /* pcrel_offset */
782 /* Low 16 bits of displacement in global offset table. */
783 HOWTO (R_SCORE_GOT_LO16, /* type */
784 0, /* rightshift */
785 2, /* size (0 = byte, 1 = short, 2 = long) */
786 16, /* bitsize */
787 FALSE, /* pc_relative */
788 1, /* bitpos */
789 complain_overflow_dont,/* complain_on_overflow */
790 score_elf_got_lo16_reloc, /* special_function */
791 "R_SCORE_GOT_LO16", /* name */
792 TRUE, /* partial_inplace */
793 0x37ffe, /* src_mask */
794 0x37ffe, /* dst_mask */
795 FALSE), /* pcrel_offset */
797 /* 15 bit call through global offset table. */
798 HOWTO (R_SCORE_CALL15, /* type */
799 0, /* rightshift */
800 2, /* size (0 = byte, 1 = short, 2 = long) */
801 16, /* bitsize */
802 FALSE, /* pc_relative */
803 0, /* bitpos */
804 complain_overflow_signed, /* complain_on_overflow */
805 bfd_elf_generic_reloc, /* special_function */
806 "R_SCORE_CALL15", /* name */
807 TRUE, /* partial_inplace */
808 0x0000ffff, /* src_mask */
809 0x0000ffff, /* dst_mask */
810 FALSE), /* pcrel_offset */
812 /* 32 bit GP relative reference. */
813 HOWTO (R_SCORE_GPREL32, /* type */
814 0, /* rightshift */
815 2, /* size (0 = byte, 1 = short, 2 = long) */
816 32, /* bitsize */
817 FALSE, /* pc_relative */
818 0, /* bitpos */
819 complain_overflow_dont,/* complain_on_overflow */
820 score_elf_gprel32_reloc, /* special_function */
821 "R_SCORE_GPREL32", /* name */
822 TRUE, /* partial_inplace */
823 0xffffffff, /* src_mask */
824 0xffffffff, /* dst_mask */
825 FALSE), /* pcrel_offset */
827 /* 32 bit symbol relative relocation. */
828 HOWTO (R_SCORE_REL32, /* type */
829 0, /* rightshift */
830 2, /* size (0 = byte, 1 = short, 2 = long) */
831 32, /* bitsize */
832 FALSE, /* pc_relative */
833 0, /* bitpos */
834 complain_overflow_dont,/* complain_on_overflow */
835 bfd_elf_generic_reloc, /* special_function */
836 "R_SCORE_REL32", /* name */
837 TRUE, /* partial_inplace */
838 0xffffffff, /* src_mask */
839 0xffffffff, /* dst_mask */
840 FALSE), /* pcrel_offset */
842 /* R_SCORE_DUMMY_HI16 */
843 HOWTO (R_SCORE_DUMMY_HI16, /* type */
844 0, /* rightshift */
845 2, /* size (0 = byte, 1 = short, 2 = long) */
846 16, /* bitsize */
847 FALSE, /* pc_relative */
848 1, /* bitpos */
849 complain_overflow_dont,/* complain_on_overflow */
850 score_elf_hi16_reloc, /* special_function */
851 "R_SCORE_DUMMY_HI16", /* name */
852 TRUE, /* partial_inplace */
853 0x37fff, /* src_mask */
854 0x37fff, /* dst_mask */
855 FALSE), /* pcrel_offset */
858 struct score_reloc_map
860 bfd_reloc_code_real_type bfd_reloc_val;
861 unsigned char elf_reloc_val;
864 static const struct score_reloc_map elf32_score_reloc_map[] =
866 {BFD_RELOC_NONE, R_SCORE_NONE},
867 {BFD_RELOC_HI16_S, R_SCORE_HI16},
868 {BFD_RELOC_LO16, R_SCORE_LO16},
869 {BFD_RELOC_SCORE_DUMMY1, R_SCORE_DUMMY1},
870 {BFD_RELOC_SCORE_JMP, R_SCORE_24},
871 {BFD_RELOC_SCORE_BRANCH, R_SCORE_PC19},
872 {BFD_RELOC_SCORE16_JMP, R_SCORE16_11},
873 {BFD_RELOC_SCORE16_BRANCH, R_SCORE16_PC8},
874 {BFD_RELOC_32, R_SCORE_ABS32},
875 {BFD_RELOC_16, R_SCORE_ABS16},
876 {BFD_RELOC_SCORE_DUMMY2, R_SCORE_DUMMY2},
877 {BFD_RELOC_SCORE_GPREL15, R_SCORE_GP15},
878 {BFD_RELOC_VTABLE_INHERIT, R_SCORE_GNU_VTINHERIT},
879 {BFD_RELOC_VTABLE_ENTRY, R_SCORE_GNU_VTENTRY},
880 {BFD_RELOC_SCORE_GOT15, R_SCORE_GOT15},
881 {BFD_RELOC_SCORE_GOT_LO16, R_SCORE_GOT_LO16},
882 {BFD_RELOC_SCORE_CALL15, R_SCORE_CALL15},
883 {BFD_RELOC_GPREL32, R_SCORE_GPREL32},
884 {BFD_RELOC_32_PCREL, R_SCORE_REL32},
885 {BFD_RELOC_SCORE_DUMMY_HI16, R_SCORE_DUMMY_HI16},
888 /* got_entries only match if they're identical, except for gotidx, so
889 use all fields to compute the hash, and compare the appropriate
890 union members. */
892 static hashval_t
893 score_elf_got_entry_hash (const void *entry_)
895 const struct score_got_entry *entry = (struct score_got_entry *)entry_;
897 return entry->symndx
898 + (!entry->abfd ? entry->d.address : entry->abfd->id);
901 static int
902 score_elf_got_entry_eq (const void *entry1, const void *entry2)
904 const struct score_got_entry *e1 = (struct score_got_entry *)entry1;
905 const struct score_got_entry *e2 = (struct score_got_entry *)entry2;
907 return e1->abfd == e2->abfd && e1->symndx == e2->symndx
908 && (! e1->abfd ? e1->d.address == e2->d.address
909 : e1->symndx >= 0 ? e1->d.addend == e2->d.addend
910 : e1->d.h == e2->d.h);
913 /* If H needs a GOT entry, assign it the highest available dynamic
914 index. Otherwise, assign it the lowest available dynamic
915 index. */
917 static bfd_boolean
918 score_elf_sort_hash_table_f (struct score_elf_link_hash_entry *h, void *data)
920 struct score_elf_hash_sort_data *hsd = data;
922 if (h->root.root.type == bfd_link_hash_warning)
923 h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
925 /* Symbols without dynamic symbol table entries aren't interesting at all. */
926 if (h->root.dynindx == -1)
927 return TRUE;
929 /* Global symbols that need GOT entries that are not explicitly
930 referenced are marked with got offset 2. Those that are
931 referenced get a 1, and those that don't need GOT entries get
932 -1. */
933 if (h->root.got.offset == 2)
935 if (hsd->max_unref_got_dynindx == hsd->min_got_dynindx)
936 hsd->low = (struct elf_link_hash_entry *) h;
937 h->root.dynindx = hsd->max_unref_got_dynindx++;
939 else if (h->root.got.offset != 1)
940 h->root.dynindx = hsd->max_non_got_dynindx++;
941 else
943 h->root.dynindx = --hsd->min_got_dynindx;
944 hsd->low = (struct elf_link_hash_entry *) h;
947 return TRUE;
950 static asection *
951 score_elf_got_section (bfd *abfd, bfd_boolean maybe_excluded)
953 asection *sgot = bfd_get_section_by_name (abfd, ".got");
955 if (sgot == NULL || (! maybe_excluded && (sgot->flags & SEC_EXCLUDE) != 0))
956 return NULL;
957 return sgot;
960 /* Returns the GOT information associated with the link indicated by
961 INFO. If SGOTP is non-NULL, it is filled in with the GOT section. */
963 static struct score_got_info *
964 score_elf_got_info (bfd *abfd, asection **sgotp)
966 asection *sgot;
967 struct score_got_info *g;
969 sgot = score_elf_got_section (abfd, TRUE);
970 BFD_ASSERT (sgot != NULL);
971 BFD_ASSERT (elf_section_data (sgot) != NULL);
972 g = score_elf_section_data (sgot)->u.got_info;
973 BFD_ASSERT (g != NULL);
975 if (sgotp)
976 *sgotp = sgot;
977 return g;
980 /* Sort the dynamic symbol table so that symbols that need GOT entries
981 appear towards the end. This reduces the amount of GOT space
982 required. MAX_LOCAL is used to set the number of local symbols
983 known to be in the dynamic symbol table. During
984 _bfd_score_elf_size_dynamic_sections, this value is 1. Afterward, the
985 section symbols are added and the count is higher. */
987 static bfd_boolean
988 score_elf_sort_hash_table (struct bfd_link_info *info,
989 unsigned long max_local)
991 struct score_elf_hash_sort_data hsd;
992 struct score_got_info *g;
993 bfd *dynobj;
995 dynobj = elf_hash_table (info)->dynobj;
997 g = score_elf_got_info (dynobj, NULL);
999 hsd.low = NULL;
1000 hsd.max_unref_got_dynindx =
1001 hsd.min_got_dynindx = elf_hash_table (info)->dynsymcount
1002 /* In the multi-got case, assigned_gotno of the master got_info
1003 indicate the number of entries that aren't referenced in the
1004 primary GOT, but that must have entries because there are
1005 dynamic relocations that reference it. Since they aren't
1006 referenced, we move them to the end of the GOT, so that they
1007 don't prevent other entries that are referenced from getting
1008 too large offsets. */
1009 - (g->next ? g->assigned_gotno : 0);
1010 hsd.max_non_got_dynindx = max_local;
1011 score_elf_link_hash_traverse (((struct score_elf_link_hash_table *)
1012 elf_hash_table (info)),
1013 score_elf_sort_hash_table_f,
1014 &hsd);
1016 /* There should have been enough room in the symbol table to
1017 accommodate both the GOT and non-GOT symbols. */
1018 BFD_ASSERT (hsd.max_non_got_dynindx <= hsd.min_got_dynindx);
1019 BFD_ASSERT ((unsigned long)hsd.max_unref_got_dynindx
1020 <= elf_hash_table (info)->dynsymcount);
1022 /* Now we know which dynamic symbol has the lowest dynamic symbol
1023 table index in the GOT. */
1024 g->global_gotsym = hsd.low;
1026 return TRUE;
1029 /* Create an entry in an score ELF linker hash table. */
1031 static struct bfd_hash_entry *
1032 score_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
1033 struct bfd_hash_table *table,
1034 const char *string)
1036 struct score_elf_link_hash_entry *ret = (struct score_elf_link_hash_entry *)entry;
1038 /* Allocate the structure if it has not already been allocated by a subclass. */
1039 if (ret == NULL)
1040 ret = bfd_hash_allocate (table, sizeof (struct score_elf_link_hash_entry));
1041 if (ret == NULL)
1042 return (struct bfd_hash_entry *)ret;
1044 /* Call the allocation method of the superclass. */
1045 ret = ((struct score_elf_link_hash_entry *)
1046 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *)ret, table, string));
1048 if (ret != NULL)
1050 ret->possibly_dynamic_relocs = 0;
1051 ret->readonly_reloc = FALSE;
1052 ret->no_fn_stub = FALSE;
1053 ret->forced_local = FALSE;
1056 return (struct bfd_hash_entry *)ret;
1059 /* Returns the first relocation of type r_type found, beginning with
1060 RELOCATION. RELEND is one-past-the-end of the relocation table. */
1062 static const Elf_Internal_Rela *
1063 score_elf_next_relocation (bfd *abfd ATTRIBUTE_UNUSED, unsigned int r_type,
1064 const Elf_Internal_Rela *relocation,
1065 const Elf_Internal_Rela *relend)
1067 while (relocation < relend)
1069 if (ELF32_R_TYPE (relocation->r_info) == r_type)
1070 return relocation;
1072 ++relocation;
1075 /* We didn't find it. */
1076 bfd_set_error (bfd_error_bad_value);
1077 return NULL;
1080 /* This function is called via qsort() to sort the dynamic relocation
1081 entries by increasing r_symndx value. */
1083 static int
1084 score_elf_sort_dynamic_relocs (const void *arg1, const void *arg2)
1086 Elf_Internal_Rela int_reloc1;
1087 Elf_Internal_Rela int_reloc2;
1089 bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg1, &int_reloc1);
1090 bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg2, &int_reloc2);
1092 return (ELF32_R_SYM (int_reloc1.r_info) - ELF32_R_SYM (int_reloc2.r_info));
1095 /* Return whether a relocation is against a local symbol. */
1097 static bfd_boolean
1098 score_elf_local_relocation_p (bfd *input_bfd,
1099 const Elf_Internal_Rela *relocation,
1100 asection **local_sections,
1101 bfd_boolean check_forced)
1103 unsigned long r_symndx;
1104 Elf_Internal_Shdr *symtab_hdr;
1105 struct score_elf_link_hash_entry *h;
1106 size_t extsymoff;
1108 r_symndx = ELF32_R_SYM (relocation->r_info);
1109 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1110 extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
1112 if (r_symndx < extsymoff)
1113 return TRUE;
1114 if (elf_bad_symtab (input_bfd) && local_sections[r_symndx] != NULL)
1115 return TRUE;
1117 if (check_forced)
1119 /* Look up the hash table to check whether the symbol was forced local. */
1120 h = (struct score_elf_link_hash_entry *)
1121 elf_sym_hashes (input_bfd) [r_symndx - extsymoff];
1122 /* Find the real hash-table entry for this symbol. */
1123 while (h->root.root.type == bfd_link_hash_indirect
1124 || h->root.root.type == bfd_link_hash_warning)
1125 h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
1126 if (h->root.forced_local)
1127 return TRUE;
1130 return FALSE;
1133 /* Returns the dynamic relocation section for DYNOBJ. */
1135 static asection *
1136 score_elf_rel_dyn_section (bfd *dynobj, bfd_boolean create_p)
1138 static const char dname[] = ".rel.dyn";
1139 asection *sreloc;
1141 sreloc = bfd_get_section_by_name (dynobj, dname);
1142 if (sreloc == NULL && create_p)
1144 sreloc = bfd_make_section_with_flags (dynobj, dname,
1145 (SEC_ALLOC
1146 | SEC_LOAD
1147 | SEC_HAS_CONTENTS
1148 | SEC_IN_MEMORY
1149 | SEC_LINKER_CREATED
1150 | SEC_READONLY));
1151 if (sreloc == NULL
1152 || ! bfd_set_section_alignment (dynobj, sreloc,
1153 SCORE_ELF_LOG_FILE_ALIGN (dynobj)))
1154 return NULL;
1156 return sreloc;
1159 static void
1160 score_elf_allocate_dynamic_relocations (bfd *abfd, unsigned int n)
1162 asection *s;
1164 s = score_elf_rel_dyn_section (abfd, FALSE);
1165 BFD_ASSERT (s != NULL);
1167 if (s->size == 0)
1169 /* Make room for a null element. */
1170 s->size += SCORE_ELF_REL_SIZE (abfd);
1171 ++s->reloc_count;
1173 s->size += n * SCORE_ELF_REL_SIZE (abfd);
1176 /* Create a rel.dyn relocation for the dynamic linker to resolve. REL
1177 is the original relocation, which is now being transformed into a
1178 dynamic relocation. The ADDENDP is adjusted if necessary; the
1179 caller should store the result in place of the original addend. */
1181 static bfd_boolean
1182 score_elf_create_dynamic_relocation (bfd *output_bfd,
1183 struct bfd_link_info *info,
1184 const Elf_Internal_Rela *rel,
1185 struct score_elf_link_hash_entry *h,
1186 bfd_vma symbol,
1187 bfd_vma *addendp, asection *input_section)
1189 Elf_Internal_Rela outrel[3];
1190 asection *sreloc;
1191 bfd *dynobj;
1192 int r_type;
1193 long indx;
1194 bfd_boolean defined_p;
1196 r_type = ELF32_R_TYPE (rel->r_info);
1197 dynobj = elf_hash_table (info)->dynobj;
1198 sreloc = score_elf_rel_dyn_section (dynobj, FALSE);
1199 BFD_ASSERT (sreloc != NULL);
1200 BFD_ASSERT (sreloc->contents != NULL);
1201 BFD_ASSERT (sreloc->reloc_count * SCORE_ELF_REL_SIZE (output_bfd) < sreloc->size);
1203 outrel[0].r_offset =
1204 _bfd_elf_section_offset (output_bfd, info, input_section, rel[0].r_offset);
1205 outrel[1].r_offset =
1206 _bfd_elf_section_offset (output_bfd, info, input_section, rel[1].r_offset);
1207 outrel[2].r_offset =
1208 _bfd_elf_section_offset (output_bfd, info, input_section, rel[2].r_offset);
1210 if (outrel[0].r_offset == MINUS_ONE)
1211 /* The relocation field has been deleted. */
1212 return TRUE;
1214 if (outrel[0].r_offset == MINUS_TWO)
1216 /* The relocation field has been converted into a relative value of
1217 some sort. Functions like _bfd_elf_write_section_eh_frame expect
1218 the field to be fully relocated, so add in the symbol's value. */
1219 *addendp += symbol;
1220 return TRUE;
1223 /* We must now calculate the dynamic symbol table index to use
1224 in the relocation. */
1225 if (h != NULL
1226 && (! info->symbolic || !h->root.def_regular)
1227 /* h->root.dynindx may be -1 if this symbol was marked to
1228 become local. */
1229 && h->root.dynindx != -1)
1231 indx = h->root.dynindx;
1232 /* ??? glibc's ld.so just adds the final GOT entry to the
1233 relocation field. It therefore treats relocs against
1234 defined symbols in the same way as relocs against
1235 undefined symbols. */
1236 defined_p = FALSE;
1238 else
1240 indx = 0;
1241 defined_p = TRUE;
1244 /* If the relocation was previously an absolute relocation and
1245 this symbol will not be referred to by the relocation, we must
1246 adjust it by the value we give it in the dynamic symbol table.
1247 Otherwise leave the job up to the dynamic linker. */
1248 if (defined_p && r_type != R_SCORE_REL32)
1249 *addendp += symbol;
1251 /* The relocation is always an REL32 relocation because we don't
1252 know where the shared library will wind up at load-time. */
1253 outrel[0].r_info = ELF32_R_INFO ((unsigned long) indx, R_SCORE_REL32);
1255 /* For strict adherence to the ABI specification, we should
1256 generate a R_SCORE_64 relocation record by itself before the
1257 _REL32/_64 record as well, such that the addend is read in as
1258 a 64-bit value (REL32 is a 32-bit relocation, after all).
1259 However, since none of the existing ELF64 SCORE dynamic
1260 loaders seems to care, we don't waste space with these
1261 artificial relocations. If this turns out to not be true,
1262 score_elf_allocate_dynamic_relocations() should be tweaked so
1263 as to make room for a pair of dynamic relocations per
1264 invocation if ABI_64_P, and here we should generate an
1265 additional relocation record with R_SCORE_64 by itself for a
1266 NULL symbol before this relocation record. */
1267 outrel[1].r_info = ELF32_R_INFO (0, R_SCORE_NONE);
1268 outrel[2].r_info = ELF32_R_INFO (0, R_SCORE_NONE);
1270 /* Adjust the output offset of the relocation to reference the
1271 correct location in the output file. */
1272 outrel[0].r_offset += (input_section->output_section->vma
1273 + input_section->output_offset);
1274 outrel[1].r_offset += (input_section->output_section->vma
1275 + input_section->output_offset);
1276 outrel[2].r_offset += (input_section->output_section->vma
1277 + input_section->output_offset);
1279 /* Put the relocation back out. We have to use the special
1280 relocation outputter in the 64-bit case since the 64-bit
1281 relocation format is non-standard. */
1282 bfd_elf32_swap_reloc_out
1283 (output_bfd, &outrel[0],
1284 (sreloc->contents + sreloc->reloc_count * sizeof (Elf32_External_Rel)));
1286 /* We've now added another relocation. */
1287 ++sreloc->reloc_count;
1289 /* Make sure the output section is writable. The dynamic linker
1290 will be writing to it. */
1291 elf_section_data (input_section->output_section)->this_hdr.sh_flags |= SHF_WRITE;
1293 return TRUE;
1296 static bfd_boolean
1297 score_elf_create_got_section (bfd *abfd,
1298 struct bfd_link_info *info,
1299 bfd_boolean maybe_exclude)
1301 flagword flags;
1302 asection *s;
1303 struct elf_link_hash_entry *h;
1304 struct bfd_link_hash_entry *bh;
1305 struct score_got_info *g;
1306 bfd_size_type amt;
1308 /* This function may be called more than once. */
1309 s = score_elf_got_section (abfd, TRUE);
1310 if (s)
1312 if (! maybe_exclude)
1313 s->flags &= ~SEC_EXCLUDE;
1314 return TRUE;
1317 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
1319 if (maybe_exclude)
1320 flags |= SEC_EXCLUDE;
1322 /* We have to use an alignment of 2**4 here because this is hardcoded
1323 in the function stub generation and in the linker script. */
1324 s = bfd_make_section_with_flags (abfd, ".got", flags);
1325 if (s == NULL
1326 || ! bfd_set_section_alignment (abfd, s, 4))
1327 return FALSE;
1329 /* Define the symbol _GLOBAL_OFFSET_TABLE_. We don't do this in the
1330 linker script because we don't want to define the symbol if we
1331 are not creating a global offset table. */
1332 bh = NULL;
1333 if (! (_bfd_generic_link_add_one_symbol
1334 (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s,
1335 0, NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
1336 return FALSE;
1338 h = (struct elf_link_hash_entry *) bh;
1339 h->non_elf = 0;
1340 h->def_regular = 1;
1341 h->type = STT_OBJECT;
1343 if (info->shared && ! bfd_elf_link_record_dynamic_symbol (info, h))
1344 return FALSE;
1346 amt = sizeof (struct score_got_info);
1347 g = bfd_alloc (abfd, amt);
1348 if (g == NULL)
1349 return FALSE;
1351 g->global_gotsym = NULL;
1352 g->global_gotno = 0;
1354 g->local_gotno = SCORE_RESERVED_GOTNO;
1355 g->assigned_gotno = SCORE_RESERVED_GOTNO;
1356 g->next = NULL;
1358 g->got_entries = htab_try_create (1, score_elf_got_entry_hash,
1359 score_elf_got_entry_eq, NULL);
1360 if (g->got_entries == NULL)
1361 return FALSE;
1362 score_elf_section_data (s)->u.got_info = g;
1363 score_elf_section_data (s)->elf.this_hdr.sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
1365 return TRUE;
1368 /* Calculate the %high function. */
1370 static bfd_vma
1371 score_elf_high (bfd_vma value)
1373 return ((value + (bfd_vma) 0x8000) >> 16) & 0xffff;
1376 /* Create a local GOT entry for VALUE. Return the index of the entry,
1377 or -1 if it could not be created. */
1379 static struct score_got_entry *
1380 score_elf_create_local_got_entry (bfd *abfd,
1381 bfd *ibfd ATTRIBUTE_UNUSED,
1382 struct score_got_info *gg,
1383 asection *sgot, bfd_vma value,
1384 unsigned long r_symndx ATTRIBUTE_UNUSED,
1385 struct score_elf_link_hash_entry *h ATTRIBUTE_UNUSED,
1386 int r_type ATTRIBUTE_UNUSED)
1388 struct score_got_entry entry, **loc;
1389 struct score_got_info *g;
1391 entry.abfd = NULL;
1392 entry.symndx = -1;
1393 entry.d.address = value;
1395 g = gg;
1396 loc = (struct score_got_entry **) htab_find_slot (g->got_entries, &entry, INSERT);
1397 if (*loc)
1398 return *loc;
1400 entry.gotidx = SCORE_ELF_GOT_SIZE (abfd) * g->assigned_gotno++;
1402 *loc = bfd_alloc (abfd, sizeof entry);
1404 if (! *loc)
1405 return NULL;
1407 memcpy (*loc, &entry, sizeof entry);
1409 if (g->assigned_gotno >= g->local_gotno)
1411 (*loc)->gotidx = -1;
1412 /* We didn't allocate enough space in the GOT. */
1413 (*_bfd_error_handler)
1414 (_("not enough GOT space for local GOT entries"));
1415 bfd_set_error (bfd_error_bad_value);
1416 return NULL;
1419 bfd_put_32 (abfd, value, (sgot->contents + entry.gotidx));
1421 return *loc;
1424 /* Find a GOT entry whose higher-order 16 bits are the same as those
1425 for value. Return the index into the GOT for this entry. */
1427 static bfd_vma
1428 score_elf_got16_entry (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
1429 bfd_vma value, bfd_boolean external)
1431 asection *sgot;
1432 struct score_got_info *g;
1433 struct score_got_entry *entry;
1435 if (!external)
1437 /* Although the ABI says that it is "the high-order 16 bits" that we
1438 want, it is really the %high value. The complete value is
1439 calculated with a `addiu' of a LO16 relocation, just as with a
1440 HI16/LO16 pair. */
1441 value = score_elf_high (value) << 16;
1444 g = score_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
1446 entry = score_elf_create_local_got_entry (abfd, ibfd, g, sgot, value, 0, NULL,
1447 R_SCORE_GOT15);
1448 if (entry)
1449 return entry->gotidx;
1450 else
1451 return MINUS_ONE;
1454 static void
1455 _bfd_score_elf_hide_symbol (struct bfd_link_info *info,
1456 struct elf_link_hash_entry *entry,
1457 bfd_boolean force_local)
1459 bfd *dynobj;
1460 asection *got;
1461 struct score_got_info *g;
1462 struct score_elf_link_hash_entry *h;
1464 h = (struct score_elf_link_hash_entry *) entry;
1465 if (h->forced_local)
1466 return;
1467 h->forced_local = TRUE;
1469 dynobj = elf_hash_table (info)->dynobj;
1470 if (dynobj != NULL && force_local)
1472 got = score_elf_got_section (dynobj, FALSE);
1473 if (got == NULL)
1474 return;
1475 g = score_elf_section_data (got)->u.got_info;
1477 if (g->next)
1479 struct score_got_entry e;
1480 struct score_got_info *gg = g;
1482 /* Since we're turning what used to be a global symbol into a
1483 local one, bump up the number of local entries of each GOT
1484 that had an entry for it. This will automatically decrease
1485 the number of global entries, since global_gotno is actually
1486 the upper limit of global entries. */
1487 e.abfd = dynobj;
1488 e.symndx = -1;
1489 e.d.h = h;
1491 for (g = g->next; g != gg; g = g->next)
1492 if (htab_find (g->got_entries, &e))
1494 BFD_ASSERT (g->global_gotno > 0);
1495 g->local_gotno++;
1496 g->global_gotno--;
1499 /* If this was a global symbol forced into the primary GOT, we
1500 no longer need an entry for it. We can't release the entry
1501 at this point, but we must at least stop counting it as one
1502 of the symbols that required a forced got entry. */
1503 if (h->root.got.offset == 2)
1505 BFD_ASSERT (gg->assigned_gotno > 0);
1506 gg->assigned_gotno--;
1509 else if (g->global_gotno == 0 && g->global_gotsym == NULL)
1510 /* If we haven't got through GOT allocation yet, just bump up the
1511 number of local entries, as this symbol won't be counted as
1512 global. */
1513 g->local_gotno++;
1514 else if (h->root.got.offset == 1)
1516 /* If we're past non-multi-GOT allocation and this symbol had
1517 been marked for a global got entry, give it a local entry
1518 instead. */
1519 BFD_ASSERT (g->global_gotno > 0);
1520 g->local_gotno++;
1521 g->global_gotno--;
1525 _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
1528 /* If H is a symbol that needs a global GOT entry, but has a dynamic
1529 symbol table index lower than any we've seen to date, record it for
1530 posterity. */
1532 static bfd_boolean
1533 score_elf_record_global_got_symbol (struct elf_link_hash_entry *h,
1534 bfd *abfd,
1535 struct bfd_link_info *info,
1536 struct score_got_info *g)
1538 struct score_got_entry entry, **loc;
1540 /* A global symbol in the GOT must also be in the dynamic symbol table. */
1541 if (h->dynindx == -1)
1543 switch (ELF_ST_VISIBILITY (h->other))
1545 case STV_INTERNAL:
1546 case STV_HIDDEN:
1547 _bfd_score_elf_hide_symbol (info, h, TRUE);
1548 break;
1550 if (!bfd_elf_link_record_dynamic_symbol (info, h))
1551 return FALSE;
1554 entry.abfd = abfd;
1555 entry.symndx = -1;
1556 entry.d.h = (struct score_elf_link_hash_entry *)h;
1558 loc = (struct score_got_entry **)htab_find_slot (g->got_entries, &entry, INSERT);
1560 /* If we've already marked this entry as needing GOT space, we don't
1561 need to do it again. */
1562 if (*loc)
1563 return TRUE;
1565 *loc = bfd_alloc (abfd, sizeof entry);
1566 if (! *loc)
1567 return FALSE;
1569 entry.gotidx = -1;
1571 memcpy (*loc, &entry, sizeof (entry));
1573 if (h->got.offset != MINUS_ONE)
1574 return TRUE;
1576 /* By setting this to a value other than -1, we are indicating that
1577 there needs to be a GOT entry for H. Avoid using zero, as the
1578 generic ELF copy_indirect_symbol tests for <= 0. */
1579 h->got.offset = 1;
1581 return TRUE;
1584 /* Reserve space in G for a GOT entry containing the value of symbol
1585 SYMNDX in input bfd ABDF, plus ADDEND. */
1587 static bfd_boolean
1588 score_elf_record_local_got_symbol (bfd *abfd,
1589 long symndx,
1590 bfd_vma addend,
1591 struct score_got_info *g)
1593 struct score_got_entry entry, **loc;
1595 entry.abfd = abfd;
1596 entry.symndx = symndx;
1597 entry.d.addend = addend;
1598 loc = (struct score_got_entry **)htab_find_slot (g->got_entries, &entry, INSERT);
1600 if (*loc)
1601 return TRUE;
1603 entry.gotidx = g->local_gotno++;
1605 *loc = bfd_alloc (abfd, sizeof(entry));
1606 if (! *loc)
1607 return FALSE;
1609 memcpy (*loc, &entry, sizeof (entry));
1611 return TRUE;
1614 /* Returns the GOT offset at which the indicated address can be found.
1615 If there is not yet a GOT entry for this value, create one.
1616 Returns -1 if no satisfactory GOT offset can be found. */
1618 static bfd_vma
1619 score_elf_local_got_index (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
1620 bfd_vma value, unsigned long r_symndx,
1621 struct score_elf_link_hash_entry *h, int r_type)
1623 asection *sgot;
1624 struct score_got_info *g;
1625 struct score_got_entry *entry;
1627 g = score_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
1629 entry = score_elf_create_local_got_entry (abfd, ibfd, g, sgot, value,
1630 r_symndx, h, r_type);
1631 if (!entry)
1632 return MINUS_ONE;
1634 else
1635 return entry->gotidx;
1638 /* Returns the GOT index for the global symbol indicated by H. */
1640 static bfd_vma
1641 score_elf_global_got_index (bfd *abfd, struct elf_link_hash_entry *h)
1643 bfd_vma index;
1644 asection *sgot;
1645 struct score_got_info *g;
1646 long global_got_dynindx = 0;
1648 g = score_elf_got_info (abfd, &sgot);
1649 if (g->global_gotsym != NULL)
1650 global_got_dynindx = g->global_gotsym->dynindx;
1652 /* Once we determine the global GOT entry with the lowest dynamic
1653 symbol table index, we must put all dynamic symbols with greater
1654 indices into the GOT. That makes it easy to calculate the GOT
1655 offset. */
1656 BFD_ASSERT (h->dynindx >= global_got_dynindx);
1657 index = ((h->dynindx - global_got_dynindx + g->local_gotno) * SCORE_ELF_GOT_SIZE (abfd));
1658 BFD_ASSERT (index < sgot->size);
1660 return index;
1663 /* Returns the offset for the entry at the INDEXth position in the GOT. */
1665 static bfd_vma
1666 score_elf_got_offset_from_index (bfd *dynobj, bfd *output_bfd,
1667 bfd *input_bfd ATTRIBUTE_UNUSED, bfd_vma index)
1669 asection *sgot;
1670 bfd_vma gp;
1671 struct score_got_info *g;
1673 g = score_elf_got_info (dynobj, &sgot);
1674 gp = _bfd_get_gp_value (output_bfd);
1676 return sgot->output_section->vma + sgot->output_offset + index - gp;
1679 /* Follow indirect and warning hash entries so that each got entry
1680 points to the final symbol definition. P must point to a pointer
1681 to the hash table we're traversing. Since this traversal may
1682 modify the hash table, we set this pointer to NULL to indicate
1683 we've made a potentially-destructive change to the hash table, so
1684 the traversal must be restarted. */
1685 static int
1686 score_elf_resolve_final_got_entry (void **entryp, void *p)
1688 struct score_got_entry *entry = (struct score_got_entry *)*entryp;
1689 htab_t got_entries = *(htab_t *)p;
1691 if (entry->abfd != NULL && entry->symndx == -1)
1693 struct score_elf_link_hash_entry *h = entry->d.h;
1695 while (h->root.root.type == bfd_link_hash_indirect
1696 || h->root.root.type == bfd_link_hash_warning)
1697 h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
1699 if (entry->d.h == h)
1700 return 1;
1702 entry->d.h = h;
1704 /* If we can't find this entry with the new bfd hash, re-insert
1705 it, and get the traversal restarted. */
1706 if (! htab_find (got_entries, entry))
1708 htab_clear_slot (got_entries, entryp);
1709 entryp = htab_find_slot (got_entries, entry, INSERT);
1710 if (! *entryp)
1711 *entryp = entry;
1712 /* Abort the traversal, since the whole table may have
1713 moved, and leave it up to the parent to restart the
1714 process. */
1715 *(htab_t *)p = NULL;
1716 return 0;
1718 /* We might want to decrement the global_gotno count, but it's
1719 either too early or too late for that at this point. */
1722 return 1;
1725 /* Turn indirect got entries in a got_entries table into their final locations. */
1726 static void
1727 score_elf_resolve_final_got_entries (struct score_got_info *g)
1729 htab_t got_entries;
1733 got_entries = g->got_entries;
1735 htab_traverse (got_entries,
1736 score_elf_resolve_final_got_entry,
1737 &got_entries);
1739 while (got_entries == NULL);
1742 /* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS. for -r */
1744 static void
1745 score_elf_add_to_rel (bfd *abfd,
1746 bfd_byte *address,
1747 reloc_howto_type *howto,
1748 bfd_signed_vma increment)
1750 bfd_signed_vma addend;
1751 bfd_vma contents;
1752 unsigned long offset;
1753 unsigned long r_type = howto->type;
1754 unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
1756 contents = bfd_get_32 (abfd, address);
1757 /* Get the (signed) value from the instruction. */
1758 addend = contents & howto->src_mask;
1759 if (addend & ((howto->src_mask + 1) >> 1))
1761 bfd_signed_vma mask;
1763 mask = -1;
1764 mask &= ~howto->src_mask;
1765 addend |= mask;
1767 /* Add in the increment, (which is a byte value). */
1768 switch (r_type)
1770 case R_SCORE_PC19:
1771 offset =
1772 (((contents & howto->src_mask) & 0x3ff0000) >> 6) | ((contents & howto->src_mask) & 0x3ff);
1773 offset += increment;
1774 contents =
1775 (contents & ~howto->
1776 src_mask) | (((offset << 6) & howto->src_mask) & 0x3ff0000) | (offset & 0x3ff);
1777 bfd_put_32 (abfd, contents, address);
1778 break;
1779 case R_SCORE_HI16:
1780 break;
1781 case R_SCORE_LO16:
1782 hi16_addend = bfd_get_32 (abfd, address - 4);
1783 hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
1784 offset = ((((contents >> 16) & 0x3) << 15) | (contents & 0x7fff)) >> 1;
1785 offset = (hi16_offset << 16) | (offset & 0xffff);
1786 uvalue = increment + offset;
1787 hi16_offset = (uvalue >> 16) << 1;
1788 hi16_value = (hi16_addend & (~(howto->dst_mask)))
1789 | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
1790 bfd_put_32 (abfd, hi16_value, address - 4);
1791 offset = (uvalue & 0xffff) << 1;
1792 contents = (contents & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
1793 bfd_put_32 (abfd, contents, address);
1794 break;
1795 case R_SCORE_24:
1796 offset =
1797 (((contents & howto->src_mask) >> 1) & 0x1ff8000) | ((contents & howto->src_mask) & 0x7fff);
1798 offset += increment;
1799 contents =
1800 (contents & ~howto->
1801 src_mask) | (((offset << 1) & howto->src_mask) & 0x3ff0000) | (offset & 0x7fff);
1802 bfd_put_32 (abfd, contents, address);
1803 break;
1804 case R_SCORE16_11:
1806 contents = bfd_get_16 (abfd, address);
1807 offset = contents & howto->src_mask;
1808 offset += increment;
1809 contents = (contents & ~howto->src_mask) | (offset & howto->src_mask);
1810 bfd_put_16 (abfd, contents, address);
1812 break;
1813 case R_SCORE16_PC8:
1815 contents = bfd_get_16 (abfd, address);
1816 offset = (contents & howto->src_mask) + ((increment >> 1) & 0xff);
1817 contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask);
1818 bfd_put_16 (abfd, contents, address);
1820 break;
1821 default:
1822 addend += increment;
1823 contents = (contents & ~howto->dst_mask) | (addend & howto->dst_mask);
1824 bfd_put_32 (abfd, contents, address);
1825 break;
1829 /* Perform a relocation as part of a final link. */
1831 static bfd_reloc_status_type
1832 score_elf_final_link_relocate (reloc_howto_type *howto,
1833 bfd *input_bfd,
1834 bfd *output_bfd,
1835 asection *input_section,
1836 bfd_byte *contents,
1837 Elf_Internal_Rela *rel,
1838 Elf_Internal_Rela *relocs,
1839 bfd_vma symbol,
1840 struct bfd_link_info *info,
1841 const char *sym_name ATTRIBUTE_UNUSED,
1842 int sym_flags ATTRIBUTE_UNUSED,
1843 struct score_elf_link_hash_entry *h,
1844 asection **local_sections,
1845 bfd_boolean gp_disp_p)
1847 unsigned long r_type;
1848 unsigned long r_symndx;
1849 bfd_byte *hit_data = contents + rel->r_offset;
1850 bfd_vma addend;
1851 /* The final GP value to be used for the relocatable, executable, or
1852 shared object file being produced. */
1853 bfd_vma gp = MINUS_ONE;
1854 /* The place (section offset or address) of the storage unit being relocated. */
1855 bfd_vma rel_addr;
1856 /* The value of GP used to create the relocatable object. */
1857 bfd_vma gp0 = MINUS_ONE;
1858 /* The offset into the global offset table at which the address of the relocation entry
1859 symbol, adjusted by the addend, resides during execution. */
1860 bfd_vma g = MINUS_ONE;
1861 /* TRUE if the symbol referred to by this relocation is a local symbol. */
1862 bfd_boolean local_p;
1863 /* The eventual value we will relocate. */
1864 bfd_vma value = symbol;
1865 unsigned long hi16_addend, hi16_offset, hi16_value, uvalue, offset, abs_value = 0;
1867 if (elf_gp (output_bfd) == 0)
1869 struct bfd_link_hash_entry *bh;
1870 asection *o;
1872 bh = bfd_link_hash_lookup (info->hash, "_gp", 0, 0, 1);
1873 if (bh != (struct bfd_link_hash_entry *)NULL && bh->type == bfd_link_hash_defined)
1874 elf_gp (output_bfd) = (bh->u.def.value
1875 + bh->u.def.section->output_section->vma
1876 + bh->u.def.section->output_offset);
1877 else if (info->relocatable)
1879 bfd_vma lo = -1;
1881 /* Find the GP-relative section with the lowest offset. */
1882 for (o = output_bfd->sections; o != (asection *) NULL; o = o->next)
1883 if (o->vma < lo)
1884 lo = o->vma;
1885 /* And calculate GP relative to that. */
1886 elf_gp (output_bfd) = lo + ELF_SCORE_GP_OFFSET (input_bfd);
1888 else
1890 /* If the relocate_section function needs to do a reloc
1891 involving the GP value, it should make a reloc_dangerous
1892 callback to warn that GP is not defined. */
1896 /* Parse the relocation. */
1897 r_symndx = ELF32_R_SYM (rel->r_info);
1898 r_type = ELF32_R_TYPE (rel->r_info);
1899 rel_addr = (input_section->output_section->vma + input_section->output_offset + rel->r_offset);
1901 if (r_type == R_SCORE_GOT15)
1903 const Elf_Internal_Rela *relend;
1904 const Elf_Internal_Rela *lo16_rel;
1905 const struct elf_backend_data *bed;
1906 bfd_vma lo_value = 0;
1908 addend = (bfd_get_32 (input_bfd, hit_data) >> howto->bitpos) & howto->src_mask;
1910 bed = get_elf_backend_data (output_bfd);
1911 relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
1912 lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
1913 if (lo16_rel != NULL)
1915 lo_value = (bfd_get_32 (input_bfd, contents + lo16_rel->r_offset) >> howto->bitpos)
1916 & howto->src_mask;
1918 addend = (addend << 16) + lo_value;
1920 else
1922 addend = (bfd_get_32 (input_bfd, hit_data) >> howto->bitpos) & howto->src_mask;
1925 local_p = score_elf_local_relocation_p (input_bfd, rel, local_sections, TRUE);
1927 /* If we haven't already determined the GOT offset, or the GP value,
1928 and we're going to need it, get it now. */
1929 switch (r_type)
1931 case R_SCORE_CALL15:
1932 case R_SCORE_GOT15:
1933 if (!local_p)
1935 g = score_elf_global_got_index (elf_hash_table (info)->dynobj,
1936 (struct elf_link_hash_entry *) h);
1938 else if (r_type == R_SCORE_GOT15 || r_type == R_SCORE_CALL15)
1940 /* There's no need to create a local GOT entry here; the
1941 calculation for a local GOT15 entry does not involve G. */
1944 else
1946 g = score_elf_local_got_index (output_bfd, input_bfd, info,
1947 symbol + addend, r_symndx, h, r_type);
1948 if (g == MINUS_ONE)
1949 return bfd_reloc_outofrange;
1952 /* Convert GOT indices to actual offsets. */
1953 g = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
1954 output_bfd, input_bfd, g);
1955 break;
1957 case R_SCORE_HI16:
1958 case R_SCORE_LO16:
1959 case R_SCORE_GPREL32:
1960 gp0 = _bfd_get_gp_value (input_bfd);
1961 gp = _bfd_get_gp_value (output_bfd);
1962 break;
1964 case R_SCORE_GP15:
1965 gp = _bfd_get_gp_value (output_bfd);
1967 default:
1968 break;
1971 switch (r_type)
1973 case R_SCORE_NONE:
1974 return bfd_reloc_ok;
1976 case R_SCORE_ABS32:
1977 case R_SCORE_REL32:
1978 if ((info->shared
1979 || (elf_hash_table (info)->dynamic_sections_created
1980 && h != NULL
1981 && h->root.def_dynamic
1982 && !h->root.def_regular))
1983 && r_symndx != 0
1984 && (input_section->flags & SEC_ALLOC) != 0)
1986 /* If we're creating a shared library, or this relocation is against a symbol
1987 in a shared library, then we can't know where the symbol will end up.
1988 So, we create a relocation record in the output, and leave the job up
1989 to the dynamic linker. */
1990 value = addend;
1991 if (!score_elf_create_dynamic_relocation (output_bfd, info, rel, h,
1992 symbol, &value,
1993 input_section))
1994 return bfd_reloc_undefined;
1996 else
1998 if (r_type != R_SCORE_REL32)
1999 value = symbol + addend;
2000 else
2001 value = addend;
2003 value &= howto->dst_mask;
2004 bfd_put_32 (input_bfd, value, hit_data);
2005 return bfd_reloc_ok;
2007 case R_SCORE_ABS16:
2008 value += addend;
2009 if ((long)value > 0x7fff || (long)value < -0x8000)
2010 return bfd_reloc_overflow;
2011 bfd_put_16 (input_bfd, value, hit_data);
2012 return bfd_reloc_ok;
2014 case R_SCORE_24:
2015 addend = bfd_get_32 (input_bfd, hit_data);
2016 offset = (((addend & howto->src_mask) >> 1) & 0x1ff8000) | ((addend & howto->src_mask) & 0x7fff);
2017 if ((offset & 0x1000000) != 0)
2018 offset |= 0xfe000000;
2019 value += offset;
2020 addend = (addend & ~howto->src_mask)
2021 | (((value << 1) & howto->src_mask) & 0x3ff0000) | (value & 0x7fff);
2022 bfd_put_32 (input_bfd, addend, hit_data);
2023 return bfd_reloc_ok;
2025 case R_SCORE_PC19:
2026 addend = bfd_get_32 (input_bfd, hit_data);
2027 offset = (((addend & howto->src_mask) & 0x3ff0000) >> 6) | ((addend & howto->src_mask) & 0x3ff);
2028 if ((offset & 0x80000) != 0)
2029 offset |= 0xfff00000;
2030 abs_value = value = value - rel_addr + offset;
2031 /* exceed 20 bit : overflow. */
2032 if ((abs_value & 0x80000000) == 0x80000000)
2033 abs_value = 0xffffffff - value + 1;
2034 if ((abs_value & 0xfff80000) != 0)
2035 return bfd_reloc_overflow;
2036 addend = (addend & ~howto->src_mask)
2037 | (((value << 6) & howto->src_mask) & 0x3ff0000) | (value & 0x3ff);
2038 bfd_put_32 (input_bfd, addend, hit_data);
2039 return bfd_reloc_ok;
2041 case R_SCORE16_11:
2042 addend = bfd_get_16 (input_bfd, hit_data);
2043 offset = addend & howto->src_mask;
2044 if ((offset & 0x800) != 0) /* Offset is negative. */
2045 offset |= 0xfffff000;
2046 value += offset;
2047 addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
2048 bfd_put_16 (input_bfd, addend, hit_data);
2049 return bfd_reloc_ok;
2051 case R_SCORE16_PC8:
2052 addend = bfd_get_16 (input_bfd, hit_data);
2053 offset = (addend & howto->src_mask) << 1;
2054 if ((offset & 0x100) != 0) /* Offset is negative. */
2055 offset |= 0xfffffe00;
2056 abs_value = value = value - rel_addr + offset;
2057 /* Sign bit + exceed 9 bit. */
2058 if (((value & 0xffffff00) != 0) && ((value & 0xffffff00) != 0xffffff00))
2059 return bfd_reloc_overflow;
2060 value >>= 1;
2061 addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
2062 bfd_put_16 (input_bfd, addend, hit_data);
2063 return bfd_reloc_ok;
2065 case R_SCORE_HI16:
2066 return bfd_reloc_ok;
2068 case R_SCORE_LO16:
2069 hi16_addend = bfd_get_32 (input_bfd, hit_data - 4);
2070 hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
2071 addend = bfd_get_32 (input_bfd, hit_data);
2072 offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
2073 offset = (hi16_offset << 16) | (offset & 0xffff);
2075 if (!gp_disp_p)
2076 uvalue = value + offset;
2077 else
2078 uvalue = offset + gp - rel_addr + 4;
2080 hi16_offset = (uvalue >> 16) << 1;
2081 hi16_value = (hi16_addend & (~(howto->dst_mask)))
2082 | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
2083 bfd_put_32 (input_bfd, hi16_value, hit_data - 4);
2084 offset = (uvalue & 0xffff) << 1;
2085 value = (addend & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
2086 bfd_put_32 (input_bfd, value, hit_data);
2087 return bfd_reloc_ok;
2089 case R_SCORE_GP15:
2090 addend = bfd_get_32 (input_bfd, hit_data);
2091 offset = addend & 0x7fff;
2092 if ((offset & 0x4000) == 0x4000)
2093 offset |= 0xffffc000;
2094 value = value + offset - gp;
2095 if (((value & 0xffffc000) != 0) && ((value & 0xffffc000) != 0xffffc000))
2096 return bfd_reloc_overflow;
2097 value = (addend & ~howto->src_mask) | (value & howto->src_mask);
2098 bfd_put_32 (input_bfd, value, hit_data);
2099 return bfd_reloc_ok;
2101 case R_SCORE_GOT15:
2102 case R_SCORE_CALL15:
2103 if (local_p)
2105 bfd_boolean forced;
2107 /* The special case is when the symbol is forced to be local. We need the
2108 full address in the GOT since no R_SCORE_GOT_LO16 relocation follows. */
2109 forced = ! score_elf_local_relocation_p (input_bfd, rel,
2110 local_sections, FALSE);
2111 value = score_elf_got16_entry (output_bfd, input_bfd, info,
2112 symbol + addend, forced);
2113 if (value == MINUS_ONE)
2114 return bfd_reloc_outofrange;
2115 value = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
2116 output_bfd, input_bfd, value);
2118 else
2120 value = g;
2123 if ((long) value > 0x3fff || (long) value < -0x4000)
2124 return bfd_reloc_overflow;
2125 bfd_put_16 (input_bfd, value, hit_data + 2);
2126 return bfd_reloc_ok;
2128 case R_SCORE_GPREL32:
2129 value = (addend + symbol - gp);
2130 value &= howto->dst_mask;
2131 bfd_put_32 (input_bfd, value, hit_data);
2132 return bfd_reloc_ok;
2134 case R_SCORE_GOT_LO16:
2135 addend = bfd_get_32 (input_bfd, hit_data);
2136 value = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
2137 value += symbol;
2138 offset = (value & 0xffff) << 1;
2139 value = (addend & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
2141 bfd_put_32 (input_bfd, value, hit_data);
2142 return bfd_reloc_ok;
2144 case R_SCORE_DUMMY_HI16:
2145 return bfd_reloc_ok;
2147 case R_SCORE_GNU_VTINHERIT:
2148 case R_SCORE_GNU_VTENTRY:
2149 /* We don't do anything with these at present. */
2150 return bfd_reloc_continue;
2152 default:
2153 return bfd_reloc_notsupported;
2157 /* Score backend functions. */
2159 static void
2160 _bfd_score_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
2161 arelent *bfd_reloc,
2162 Elf_Internal_Rela *elf_reloc)
2164 unsigned int r_type;
2166 r_type = ELF32_R_TYPE (elf_reloc->r_info);
2167 if (r_type >= NUM_ELEM (elf32_score_howto_table))
2168 bfd_reloc->howto = NULL;
2169 else
2170 bfd_reloc->howto = &elf32_score_howto_table[r_type];
2173 /* Relocate an score ELF section. */
2175 static bfd_boolean
2176 _bfd_score_elf_relocate_section (bfd *output_bfd,
2177 struct bfd_link_info *info,
2178 bfd *input_bfd,
2179 asection *input_section,
2180 bfd_byte *contents,
2181 Elf_Internal_Rela *relocs,
2182 Elf_Internal_Sym *local_syms,
2183 asection **local_sections)
2185 Elf_Internal_Shdr *symtab_hdr;
2186 struct elf_link_hash_entry **sym_hashes;
2187 Elf_Internal_Rela *rel;
2188 Elf_Internal_Rela *relend;
2189 const char *name;
2190 unsigned long offset;
2191 unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
2192 size_t extsymoff;
2193 bfd_boolean gp_disp_p = FALSE;
2195 #ifndef USE_REL
2196 if (info->relocatable)
2197 return TRUE;
2198 #endif
2200 /* Sort dynsym. */
2201 if (elf_hash_table (info)->dynamic_sections_created)
2203 bfd_size_type dynsecsymcount = 0;
2204 if (info->shared)
2206 asection * p;
2207 const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
2209 for (p = output_bfd->sections; p ; p = p->next)
2210 if ((p->flags & SEC_EXCLUDE) == 0
2211 && (p->flags & SEC_ALLOC) != 0
2212 && !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p))
2213 ++ dynsecsymcount;
2216 if (!score_elf_sort_hash_table (info, dynsecsymcount + 1))
2217 return FALSE;
2220 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
2221 extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
2222 sym_hashes = elf_sym_hashes (input_bfd);
2223 rel = relocs;
2224 relend = relocs + input_section->reloc_count;
2225 for (; rel < relend; rel++)
2227 int r_type;
2228 reloc_howto_type *howto;
2229 unsigned long r_symndx;
2230 Elf_Internal_Sym *sym;
2231 asection *sec;
2232 struct score_elf_link_hash_entry *h;
2233 bfd_vma relocation = 0;
2234 bfd_reloc_status_type r;
2235 arelent bfd_reloc;
2237 r_symndx = ELF32_R_SYM (rel->r_info);
2238 r_type = ELF32_R_TYPE (rel->r_info);
2240 _bfd_score_info_to_howto (input_bfd, &bfd_reloc, (Elf_Internal_Rela *) rel);
2241 howto = bfd_reloc.howto;
2243 if (info->relocatable)
2245 /* This is a relocatable link. We don't have to change
2246 anything, unless the reloc is against a section symbol,
2247 in which case we have to adjust according to where the
2248 section symbol winds up in the output section. */
2249 if (r_symndx < symtab_hdr->sh_info)
2251 sym = local_syms + r_symndx;
2252 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2254 sec = local_sections[r_symndx];
2255 score_elf_add_to_rel (input_bfd, contents + rel->r_offset,
2256 howto, (bfd_signed_vma) (sec->output_offset + sym->st_value));
2259 continue;
2262 /* This is a final link. */
2263 h = NULL;
2264 sym = NULL;
2265 sec = NULL;
2267 if (r_symndx < extsymoff)
2269 sym = local_syms + r_symndx;
2270 sec = local_sections[r_symndx];
2271 relocation = (sec->output_section->vma
2272 + sec->output_offset
2273 + sym->st_value);
2274 name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, sec);
2276 if ((sec->flags & SEC_MERGE)
2277 && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2279 asection *msec;
2280 bfd_vma addend, value;
2282 switch (r_type)
2284 case R_SCORE_HI16:
2285 break;
2286 case R_SCORE_LO16:
2287 hi16_addend = bfd_get_32 (input_bfd, contents + rel->r_offset - 4);
2288 hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
2289 value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2290 offset = ((((value >> 16) & 0x3) << 15) | (value & 0x7fff)) >> 1;
2291 addend = (hi16_offset << 16) | (offset & 0xffff);
2292 msec = sec;
2293 addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend);
2294 addend -= relocation;
2295 addend += msec->output_section->vma + msec->output_offset;
2296 uvalue = addend;
2297 hi16_offset = (uvalue >> 16) << 1;
2298 hi16_value = (hi16_addend & (~(howto->dst_mask)))
2299 | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
2300 bfd_put_32 (input_bfd, hi16_value, contents + rel->r_offset - 4);
2301 offset = (uvalue & 0xffff) << 1;
2302 value = (value & (~(howto->dst_mask)))
2303 | (offset & 0x7fff) | ((offset << 1) & 0x30000);
2304 bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2305 break;
2306 default:
2307 value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2308 /* Get the (signed) value from the instruction. */
2309 addend = value & howto->src_mask;
2310 if (addend & ((howto->src_mask + 1) >> 1))
2312 bfd_signed_vma mask;
2314 mask = -1;
2315 mask &= ~howto->src_mask;
2316 addend |= mask;
2318 msec = sec;
2319 addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
2320 addend += msec->output_section->vma + msec->output_offset;
2321 value = (value & ~howto->dst_mask) | (addend & howto->dst_mask);
2322 bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2323 break;
2327 else
2329 /* For global symbols we look up the symbol in the hash-table. */
2330 h = ((struct score_elf_link_hash_entry *)
2331 elf_sym_hashes (input_bfd) [r_symndx - extsymoff]);
2332 /* Find the real hash-table entry for this symbol. */
2333 while (h->root.root.type == bfd_link_hash_indirect
2334 || h->root.root.type == bfd_link_hash_warning)
2335 h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
2337 /* Record the name of this symbol, for our caller. */
2338 name = h->root.root.root.string;
2340 /* See if this is the special GP_DISP_LABEL symbol. Note that such a
2341 symbol must always be a global symbol. */
2342 if (strcmp (name, GP_DISP_LABEL) == 0)
2344 /* Relocations against GP_DISP_LABEL are permitted only with
2345 R_SCORE_HI16 and R_SCORE_LO16 relocations. */
2346 if (r_type != R_SCORE_HI16 && r_type != R_SCORE_LO16)
2347 return bfd_reloc_notsupported;
2349 gp_disp_p = TRUE;
2352 /* If this symbol is defined, calculate its address. Note that
2353 GP_DISP_LABEL is a magic symbol, always implicitly defined by the
2354 linker, so it's inappropriate to check to see whether or not
2355 its defined. */
2356 else if ((h->root.root.type == bfd_link_hash_defined
2357 || h->root.root.type == bfd_link_hash_defweak)
2358 && h->root.root.u.def.section)
2360 sec = h->root.root.u.def.section;
2361 if (sec->output_section)
2362 relocation = (h->root.root.u.def.value
2363 + sec->output_section->vma
2364 + sec->output_offset);
2365 else
2367 relocation = h->root.root.u.def.value;
2370 else if (h->root.root.type == bfd_link_hash_undefweak)
2371 /* We allow relocations against undefined weak symbols, giving
2372 it the value zero, so that you can undefined weak functions
2373 and check to see if they exist by looking at their addresses. */
2374 relocation = 0;
2375 else if (info->unresolved_syms_in_objects == RM_IGNORE
2376 && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
2377 relocation = 0;
2378 else if (strcmp (name, "_DYNAMIC_LINK") == 0)
2380 /* If this is a dynamic link, we should have created a _DYNAMIC_LINK symbol
2381 in _bfd_score_elf_create_dynamic_sections. Otherwise, we should define
2382 the symbol with a value of 0. */
2383 BFD_ASSERT (! info->shared);
2384 BFD_ASSERT (bfd_get_section_by_name (output_bfd, ".dynamic") == NULL);
2385 relocation = 0;
2387 else
2389 if (! ((*info->callbacks->undefined_symbol)
2390 (info, h->root.root.root.string, input_bfd,
2391 input_section, rel->r_offset,
2392 (info->unresolved_syms_in_objects == RM_GENERATE_ERROR)
2393 || ELF_ST_VISIBILITY (h->root.other))))
2394 return bfd_reloc_undefined;
2395 relocation = 0;
2399 r = score_elf_final_link_relocate (howto, input_bfd, output_bfd,
2400 input_section, contents, rel, relocs,
2401 relocation, info, name,
2402 (h ? ELF_ST_TYPE ((unsigned int)h->root.root.type) :
2403 ELF_ST_TYPE ((unsigned int)sym->st_info)), h, local_sections,
2404 gp_disp_p);
2406 if (r != bfd_reloc_ok)
2408 const char *msg = (const char *)0;
2410 switch (r)
2412 case bfd_reloc_overflow:
2413 /* If the overflowing reloc was to an undefined symbol,
2414 we have already printed one error message and there
2415 is no point complaining again. */
2416 if (((!h) || (h->root.root.type != bfd_link_hash_undefined))
2417 && (!((*info->callbacks->reloc_overflow)
2418 (info, NULL, name, howto->name, (bfd_vma) 0,
2419 input_bfd, input_section, rel->r_offset))))
2420 return FALSE;
2421 break;
2422 case bfd_reloc_undefined:
2423 if (!((*info->callbacks->undefined_symbol)
2424 (info, name, input_bfd, input_section, rel->r_offset, TRUE)))
2425 return FALSE;
2426 break;
2428 case bfd_reloc_outofrange:
2429 msg = _("internal error: out of range error");
2430 goto common_error;
2432 case bfd_reloc_notsupported:
2433 msg = _("internal error: unsupported relocation error");
2434 goto common_error;
2436 case bfd_reloc_dangerous:
2437 msg = _("internal error: dangerous error");
2438 goto common_error;
2440 default:
2441 msg = _("internal error: unknown error");
2442 /* fall through */
2444 common_error:
2445 if (!((*info->callbacks->warning)
2446 (info, msg, name, input_bfd, input_section, rel->r_offset)))
2447 return FALSE;
2448 break;
2453 return TRUE;
2456 /* Look through the relocs for a section during the first phase, and
2457 allocate space in the global offset table. */
2459 static bfd_boolean
2460 _bfd_score_elf_check_relocs (bfd *abfd,
2461 struct bfd_link_info *info,
2462 asection *sec,
2463 const Elf_Internal_Rela *relocs)
2465 const char *name;
2466 bfd *dynobj;
2467 Elf_Internal_Shdr *symtab_hdr;
2468 struct elf_link_hash_entry **sym_hashes;
2469 struct score_got_info *g;
2470 size_t extsymoff;
2471 const Elf_Internal_Rela *rel;
2472 const Elf_Internal_Rela *rel_end;
2473 asection *sgot;
2474 asection *sreloc;
2475 const struct elf_backend_data *bed;
2477 if (info->relocatable)
2478 return TRUE;
2480 dynobj = elf_hash_table (info)->dynobj;
2481 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2482 sym_hashes = elf_sym_hashes (abfd);
2483 extsymoff = (elf_bad_symtab (abfd)) ? 0 : symtab_hdr->sh_info;
2485 name = bfd_get_section_name (abfd, sec);
2487 if (dynobj == NULL)
2489 sgot = NULL;
2490 g = NULL;
2492 else
2494 sgot = score_elf_got_section (dynobj, FALSE);
2495 if (sgot == NULL)
2496 g = NULL;
2497 else
2499 BFD_ASSERT (score_elf_section_data (sgot) != NULL);
2500 g = score_elf_section_data (sgot)->u.got_info;
2501 BFD_ASSERT (g != NULL);
2505 sreloc = NULL;
2506 bed = get_elf_backend_data (abfd);
2507 rel_end = relocs + sec->reloc_count * bed->s->int_rels_per_ext_rel;
2508 for (rel = relocs; rel < rel_end; ++rel)
2510 unsigned long r_symndx;
2511 unsigned int r_type;
2512 struct elf_link_hash_entry *h;
2514 r_symndx = ELF32_R_SYM (rel->r_info);
2515 r_type = ELF32_R_TYPE (rel->r_info);
2517 if (r_symndx < extsymoff)
2519 h = NULL;
2521 else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr))
2523 (*_bfd_error_handler) (_("%s: Malformed reloc detected for section %s"), abfd, name);
2524 bfd_set_error (bfd_error_bad_value);
2525 return FALSE;
2527 else
2529 h = sym_hashes[r_symndx - extsymoff];
2531 /* This may be an indirect symbol created because of a version. */
2532 if (h != NULL)
2534 while (h->root.type == bfd_link_hash_indirect)
2535 h = (struct elf_link_hash_entry *)h->root.u.i.link;
2539 /* Some relocs require a global offset table. */
2540 if (dynobj == NULL || sgot == NULL)
2542 switch (r_type)
2544 case R_SCORE_GOT15:
2545 case R_SCORE_CALL15:
2546 if (dynobj == NULL)
2547 elf_hash_table (info)->dynobj = dynobj = abfd;
2548 if (!score_elf_create_got_section (dynobj, info, FALSE))
2549 return FALSE;
2550 g = score_elf_got_info (dynobj, &sgot);
2551 break;
2552 case R_SCORE_ABS32:
2553 case R_SCORE_REL32:
2554 if (dynobj == NULL && (info->shared || h != NULL) && (sec->flags & SEC_ALLOC) != 0)
2555 elf_hash_table (info)->dynobj = dynobj = abfd;
2556 break;
2557 default:
2558 break;
2562 if (!h && (r_type == R_SCORE_GOT_LO16))
2564 if (! score_elf_record_local_got_symbol (abfd, r_symndx, rel->r_addend, g))
2565 return FALSE;
2568 switch (r_type)
2570 case R_SCORE_CALL15:
2571 if (h == NULL)
2573 (*_bfd_error_handler)
2574 (_("%B: CALL15 reloc at 0x%lx not against global symbol"),
2575 abfd, (unsigned long) rel->r_offset);
2576 bfd_set_error (bfd_error_bad_value);
2577 return FALSE;
2579 else
2581 /* This symbol requires a global offset table entry. */
2582 if (! score_elf_record_global_got_symbol (h, abfd, info, g))
2583 return FALSE;
2585 /* We need a stub, not a plt entry for the undefined function. But we record
2586 it as if it needs plt. See _bfd_elf_adjust_dynamic_symbol. */
2587 h->needs_plt = 1;
2588 h->type = STT_FUNC;
2590 break;
2591 case R_SCORE_GOT15:
2592 if (h && ! score_elf_record_global_got_symbol (h, abfd, info, g))
2593 return FALSE;
2594 break;
2595 case R_SCORE_ABS32:
2596 case R_SCORE_REL32:
2597 if ((info->shared || h != NULL) && (sec->flags & SEC_ALLOC) != 0)
2599 if (sreloc == NULL)
2601 sreloc = score_elf_rel_dyn_section (dynobj, TRUE);
2602 if (sreloc == NULL)
2603 return FALSE;
2605 #define SCORE_READONLY_SECTION (SEC_ALLOC | SEC_LOAD | SEC_READONLY)
2606 if (info->shared)
2608 /* When creating a shared object, we must copy these reloc types into
2609 the output file as R_SCORE_REL32 relocs. We make room for this reloc
2610 in the .rel.dyn reloc section. */
2611 score_elf_allocate_dynamic_relocations (dynobj, 1);
2612 if ((sec->flags & SCORE_READONLY_SECTION)
2613 == SCORE_READONLY_SECTION)
2614 /* We tell the dynamic linker that there are
2615 relocations against the text segment. */
2616 info->flags |= DF_TEXTREL;
2618 else
2620 struct score_elf_link_hash_entry *hscore;
2622 /* We only need to copy this reloc if the symbol is
2623 defined in a dynamic object. */
2624 hscore = (struct score_elf_link_hash_entry *)h;
2625 ++hscore->possibly_dynamic_relocs;
2626 if ((sec->flags & SCORE_READONLY_SECTION)
2627 == SCORE_READONLY_SECTION)
2628 /* We need it to tell the dynamic linker if there
2629 are relocations against the text segment. */
2630 hscore->readonly_reloc = TRUE;
2633 /* Even though we don't directly need a GOT entry for this symbol,
2634 a symbol must have a dynamic symbol table index greater that
2635 DT_SCORE_GOTSYM if there are dynamic relocations against it. */
2636 if (h != NULL)
2638 if (dynobj == NULL)
2639 elf_hash_table (info)->dynobj = dynobj = abfd;
2640 if (! score_elf_create_got_section (dynobj, info, TRUE))
2641 return FALSE;
2642 g = score_elf_got_info (dynobj, &sgot);
2643 if (! score_elf_record_global_got_symbol (h, abfd, info, g))
2644 return FALSE;
2647 break;
2649 /* This relocation describes the C++ object vtable hierarchy.
2650 Reconstruct it for later use during GC. */
2651 case R_SCORE_GNU_VTINHERIT:
2652 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
2653 return FALSE;
2654 break;
2656 /* This relocation describes which C++ vtable entries are actually
2657 used. Record for later use during GC. */
2658 case R_SCORE_GNU_VTENTRY:
2659 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
2660 return FALSE;
2661 break;
2662 default:
2663 break;
2666 /* We must not create a stub for a symbol that has relocations
2667 related to taking the function's address. */
2668 switch (r_type)
2670 default:
2671 if (h != NULL)
2673 struct score_elf_link_hash_entry *sh;
2675 sh = (struct score_elf_link_hash_entry *) h;
2676 sh->no_fn_stub = TRUE;
2678 break;
2679 case R_SCORE_CALL15:
2680 break;
2684 return TRUE;
2687 static bfd_boolean
2688 _bfd_score_elf_add_symbol_hook (bfd *abfd,
2689 struct bfd_link_info *info ATTRIBUTE_UNUSED,
2690 Elf_Internal_Sym *sym,
2691 const char **namep ATTRIBUTE_UNUSED,
2692 flagword *flagsp ATTRIBUTE_UNUSED,
2693 asection **secp,
2694 bfd_vma *valp)
2696 switch (sym->st_shndx)
2698 case SHN_COMMON:
2699 if (sym->st_size > elf_gp_size (abfd))
2700 break;
2701 /* Fall through. */
2702 case SHN_SCORE_SCOMMON:
2703 *secp = bfd_make_section_old_way (abfd, ".scommon");
2704 (*secp)->flags |= SEC_IS_COMMON;
2705 *valp = sym->st_size;
2706 break;
2709 return TRUE;
2712 static void
2713 _bfd_score_elf_symbol_processing (bfd *abfd, asymbol *asym)
2715 elf_symbol_type *elfsym;
2717 elfsym = (elf_symbol_type *) asym;
2718 switch (elfsym->internal_elf_sym.st_shndx)
2720 case SHN_COMMON:
2721 if (asym->value > elf_gp_size (abfd))
2722 break;
2723 /* Fall through. */
2724 case SHN_SCORE_SCOMMON:
2725 if (score_elf_scom_section.name == NULL)
2727 /* Initialize the small common section. */
2728 score_elf_scom_section.name = ".scommon";
2729 score_elf_scom_section.flags = SEC_IS_COMMON;
2730 score_elf_scom_section.output_section = &score_elf_scom_section;
2731 score_elf_scom_section.symbol = &score_elf_scom_symbol;
2732 score_elf_scom_section.symbol_ptr_ptr = &score_elf_scom_symbol_ptr;
2733 score_elf_scom_symbol.name = ".scommon";
2734 score_elf_scom_symbol.flags = BSF_SECTION_SYM;
2735 score_elf_scom_symbol.section = &score_elf_scom_section;
2736 score_elf_scom_symbol_ptr = &score_elf_scom_symbol;
2738 asym->section = &score_elf_scom_section;
2739 asym->value = elfsym->internal_elf_sym.st_size;
2740 break;
2744 static bfd_boolean
2745 _bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
2746 const char *name ATTRIBUTE_UNUSED,
2747 Elf_Internal_Sym *sym,
2748 asection *input_sec,
2749 struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
2751 /* If we see a common symbol, which implies a relocatable link, then
2752 if a symbol was small common in an input file, mark it as small
2753 common in the output file. */
2754 if (sym->st_shndx == SHN_COMMON && strcmp (input_sec->name, ".scommon") == 0)
2755 sym->st_shndx = SHN_SCORE_SCOMMON;
2757 return TRUE;
2760 static bfd_boolean
2761 _bfd_score_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
2762 asection *sec,
2763 int *retval)
2765 if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
2767 *retval = SHN_SCORE_SCOMMON;
2768 return TRUE;
2771 return FALSE;
2774 /* Adjust a symbol defined by a dynamic object and referenced by a
2775 regular object. The current definition is in some section of the
2776 dynamic object, but we're not including those sections. We have to
2777 change the definition to something the rest of the link can understand. */
2779 static bfd_boolean
2780 _bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
2781 struct elf_link_hash_entry *h)
2783 bfd *dynobj;
2784 struct score_elf_link_hash_entry *hscore;
2785 asection *s;
2787 dynobj = elf_hash_table (info)->dynobj;
2789 /* Make sure we know what is going on here. */
2790 BFD_ASSERT (dynobj != NULL
2791 && (h->needs_plt
2792 || h->u.weakdef != NULL
2793 || (h->def_dynamic && h->ref_regular && !h->def_regular)));
2795 /* If this symbol is defined in a dynamic object, we need to copy
2796 any R_SCORE_ABS32 or R_SCORE_REL32 relocs against it into the output
2797 file. */
2798 hscore = (struct score_elf_link_hash_entry *)h;
2799 if (!info->relocatable
2800 && hscore->possibly_dynamic_relocs != 0
2801 && (h->root.type == bfd_link_hash_defweak || !h->def_regular))
2803 score_elf_allocate_dynamic_relocations (dynobj, hscore->possibly_dynamic_relocs);
2804 if (hscore->readonly_reloc)
2805 /* We tell the dynamic linker that there are relocations
2806 against the text segment. */
2807 info->flags |= DF_TEXTREL;
2810 /* For a function, create a stub, if allowed. */
2811 if (!hscore->no_fn_stub && h->needs_plt)
2813 if (!elf_hash_table (info)->dynamic_sections_created)
2814 return TRUE;
2816 /* If this symbol is not defined in a regular file, then set
2817 the symbol to the stub location. This is required to make
2818 function pointers compare as equal between the normal
2819 executable and the shared library. */
2820 if (!h->def_regular)
2822 /* We need .stub section. */
2823 s = bfd_get_section_by_name (dynobj, SCORE_ELF_STUB_SECTION_NAME);
2824 BFD_ASSERT (s != NULL);
2826 h->root.u.def.section = s;
2827 h->root.u.def.value = s->size;
2829 /* XXX Write this stub address somewhere. */
2830 h->plt.offset = s->size;
2832 /* Make room for this stub code. */
2833 s->size += SCORE_FUNCTION_STUB_SIZE;
2835 /* The last half word of the stub will be filled with the index
2836 of this symbol in .dynsym section. */
2837 return TRUE;
2840 else if ((h->type == STT_FUNC) && !h->needs_plt)
2842 /* This will set the entry for this symbol in the GOT to 0, and
2843 the dynamic linker will take care of this. */
2844 h->root.u.def.value = 0;
2845 return TRUE;
2848 /* If this is a weak symbol, and there is a real definition, the
2849 processor independent code will have arranged for us to see the
2850 real definition first, and we can just use the same value. */
2851 if (h->u.weakdef != NULL)
2853 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2854 || h->u.weakdef->root.type == bfd_link_hash_defweak);
2855 h->root.u.def.section = h->u.weakdef->root.u.def.section;
2856 h->root.u.def.value = h->u.weakdef->root.u.def.value;
2857 return TRUE;
2860 /* This is a reference to a symbol defined by a dynamic object which
2861 is not a function. */
2862 return TRUE;
2865 /* This function is called after all the input files have been read,
2866 and the input sections have been assigned to output sections. */
2868 static bfd_boolean
2869 _bfd_score_elf_always_size_sections (bfd *output_bfd,
2870 struct bfd_link_info *info)
2872 bfd *dynobj;
2873 asection *s;
2874 struct score_got_info *g;
2875 int i;
2876 bfd_size_type loadable_size = 0;
2877 bfd_size_type local_gotno;
2878 bfd *sub;
2880 dynobj = elf_hash_table (info)->dynobj;
2881 if (dynobj == NULL)
2882 /* Relocatable links don't have it. */
2883 return TRUE;
2885 g = score_elf_got_info (dynobj, &s);
2886 if (s == NULL)
2887 return TRUE;
2889 /* Calculate the total loadable size of the output. That will give us the
2890 maximum number of GOT_PAGE entries required. */
2891 for (sub = info->input_bfds; sub; sub = sub->link_next)
2893 asection *subsection;
2895 for (subsection = sub->sections;
2896 subsection;
2897 subsection = subsection->next)
2899 if ((subsection->flags & SEC_ALLOC) == 0)
2900 continue;
2901 loadable_size += ((subsection->size + 0xf)
2902 &~ (bfd_size_type) 0xf);
2906 /* There has to be a global GOT entry for every symbol with
2907 a dynamic symbol table index of DT_SCORE_GOTSYM or
2908 higher. Therefore, it make sense to put those symbols
2909 that need GOT entries at the end of the symbol table. We
2910 do that here. */
2911 if (! score_elf_sort_hash_table (info, 1))
2912 return FALSE;
2914 if (g->global_gotsym != NULL)
2915 i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx;
2916 else
2917 /* If there are no global symbols, or none requiring
2918 relocations, then GLOBAL_GOTSYM will be NULL. */
2919 i = 0;
2921 /* In the worst case, we'll get one stub per dynamic symbol. */
2922 loadable_size += SCORE_FUNCTION_STUB_SIZE * i;
2924 /* Assume there are two loadable segments consisting of
2925 contiguous sections. Is 5 enough? */
2926 local_gotno = (loadable_size >> 16) + 5;
2928 g->local_gotno += local_gotno;
2929 s->size += g->local_gotno * SCORE_ELF_GOT_SIZE (output_bfd);
2931 g->global_gotno = i;
2932 s->size += i * SCORE_ELF_GOT_SIZE (output_bfd);
2934 score_elf_resolve_final_got_entries (g);
2936 if (s->size > SCORE_ELF_GOT_MAX_SIZE (output_bfd))
2938 /* Fixme. Error message or Warning message should be issued here. */
2941 return TRUE;
2944 /* Set the sizes of the dynamic sections. */
2946 static bfd_boolean
2947 _bfd_score_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
2949 bfd *dynobj;
2950 asection *s;
2951 bfd_boolean reltext;
2953 dynobj = elf_hash_table (info)->dynobj;
2954 BFD_ASSERT (dynobj != NULL);
2956 if (elf_hash_table (info)->dynamic_sections_created)
2958 /* Set the contents of the .interp section to the interpreter. */
2959 if (!info->shared)
2961 s = bfd_get_section_by_name (dynobj, ".interp");
2962 BFD_ASSERT (s != NULL);
2963 s->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
2964 s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
2968 /* The check_relocs and adjust_dynamic_symbol entry points have
2969 determined the sizes of the various dynamic sections. Allocate
2970 memory for them. */
2971 reltext = FALSE;
2972 for (s = dynobj->sections; s != NULL; s = s->next)
2974 const char *name;
2976 if ((s->flags & SEC_LINKER_CREATED) == 0)
2977 continue;
2979 /* It's OK to base decisions on the section name, because none
2980 of the dynobj section names depend upon the input files. */
2981 name = bfd_get_section_name (dynobj, s);
2983 if (CONST_STRNEQ (name, ".rel"))
2985 if (s->size == 0)
2987 /* We only strip the section if the output section name
2988 has the same name. Otherwise, there might be several
2989 input sections for this output section. FIXME: This
2990 code is probably not needed these days anyhow, since
2991 the linker now does not create empty output sections. */
2992 if (s->output_section != NULL
2993 && strcmp (name,
2994 bfd_get_section_name (s->output_section->owner,
2995 s->output_section)) == 0)
2996 s->flags |= SEC_EXCLUDE;
2998 else
3000 const char *outname;
3001 asection *target;
3003 /* If this relocation section applies to a read only
3004 section, then we probably need a DT_TEXTREL entry.
3005 If the relocation section is .rel.dyn, we always
3006 assert a DT_TEXTREL entry rather than testing whether
3007 there exists a relocation to a read only section or
3008 not. */
3009 outname = bfd_get_section_name (output_bfd, s->output_section);
3010 target = bfd_get_section_by_name (output_bfd, outname + 4);
3011 if ((target != NULL
3012 && (target->flags & SEC_READONLY) != 0
3013 && (target->flags & SEC_ALLOC) != 0) || strcmp (outname, ".rel.dyn") == 0)
3014 reltext = TRUE;
3016 /* We use the reloc_count field as a counter if we need
3017 to copy relocs into the output file. */
3018 if (strcmp (name, ".rel.dyn") != 0)
3019 s->reloc_count = 0;
3022 else if (CONST_STRNEQ (name, ".got"))
3024 /* _bfd_score_elf_always_size_sections() has already done
3025 most of the work, but some symbols may have been mapped
3026 to versions that we must now resolve in the got_entries
3027 hash tables. */
3029 else if (strcmp (name, SCORE_ELF_STUB_SECTION_NAME) == 0)
3031 /* IRIX rld assumes that the function stub isn't at the end
3032 of .text section. So put a dummy. XXX */
3033 s->size += SCORE_FUNCTION_STUB_SIZE;
3035 else if (! CONST_STRNEQ (name, ".init"))
3037 /* It's not one of our sections, so don't allocate space. */
3038 continue;
3041 /* Allocate memory for the section contents. */
3042 s->contents = bfd_zalloc (dynobj, s->size);
3043 if (s->contents == NULL && s->size != 0)
3045 bfd_set_error (bfd_error_no_memory);
3046 return FALSE;
3050 if (elf_hash_table (info)->dynamic_sections_created)
3052 /* Add some entries to the .dynamic section. We fill in the
3053 values later, in _bfd_score_elf_finish_dynamic_sections, but we
3054 must add the entries now so that we get the correct size for
3055 the .dynamic section. The DT_DEBUG entry is filled in by the
3056 dynamic linker and used by the debugger. */
3058 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0))
3059 return FALSE;
3061 if (reltext)
3062 info->flags |= DF_TEXTREL;
3064 if ((info->flags & DF_TEXTREL) != 0)
3066 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0))
3067 return FALSE;
3070 if (! SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTGOT, 0))
3071 return FALSE;
3073 if (score_elf_rel_dyn_section (dynobj, FALSE))
3075 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_REL, 0))
3076 return FALSE;
3078 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELSZ, 0))
3079 return FALSE;
3081 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELENT, 0))
3082 return FALSE;
3085 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_BASE_ADDRESS, 0))
3086 return FALSE;
3088 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_LOCAL_GOTNO, 0))
3089 return FALSE;
3091 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_SYMTABNO, 0))
3092 return FALSE;
3094 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_UNREFEXTNO, 0))
3095 return FALSE;
3097 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_GOTSYM, 0))
3098 return FALSE;
3100 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_HIPAGENO, 0))
3101 return FALSE;
3104 return TRUE;
3107 static bfd_boolean
3108 _bfd_score_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
3110 struct elf_link_hash_entry *h;
3111 struct bfd_link_hash_entry *bh;
3112 flagword flags;
3113 asection *s;
3115 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
3116 | SEC_LINKER_CREATED | SEC_READONLY);
3118 /* ABI requests the .dynamic section to be read only. */
3119 s = bfd_get_section_by_name (abfd, ".dynamic");
3120 if (s != NULL)
3122 if (!bfd_set_section_flags (abfd, s, flags))
3123 return FALSE;
3126 /* We need to create .got section. */
3127 if (!score_elf_create_got_section (abfd, info, FALSE))
3128 return FALSE;
3130 if (!score_elf_rel_dyn_section (elf_hash_table (info)->dynobj, TRUE))
3131 return FALSE;
3133 /* Create .stub section. */
3134 if (bfd_get_section_by_name (abfd, SCORE_ELF_STUB_SECTION_NAME) == NULL)
3136 s = bfd_make_section_with_flags (abfd, SCORE_ELF_STUB_SECTION_NAME,
3137 flags | SEC_CODE);
3138 if (s == NULL
3139 || !bfd_set_section_alignment (abfd, s, 2))
3141 return FALSE;
3144 if (!info->shared)
3146 const char *name;
3148 name = "_DYNAMIC_LINK";
3149 bh = NULL;
3150 if (!(_bfd_generic_link_add_one_symbol
3151 (info, abfd, name, BSF_GLOBAL, bfd_abs_section_ptr,
3152 (bfd_vma) 0, (const char *)NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
3153 return FALSE;
3155 h = (struct elf_link_hash_entry *)bh;
3156 h->non_elf = 0;
3157 h->def_regular = 1;
3158 h->type = STT_SECTION;
3160 if (!bfd_elf_link_record_dynamic_symbol (info, h))
3161 return FALSE;
3164 return TRUE;
3168 /* Finish up dynamic symbol handling. We set the contents of various
3169 dynamic sections here. */
3171 static bfd_boolean
3172 _bfd_score_elf_finish_dynamic_symbol (bfd *output_bfd,
3173 struct bfd_link_info *info,
3174 struct elf_link_hash_entry *h,
3175 Elf_Internal_Sym *sym)
3177 bfd *dynobj;
3178 asection *sgot;
3179 struct score_got_info *g;
3180 const char *name;
3182 dynobj = elf_hash_table (info)->dynobj;
3184 if (h->plt.offset != MINUS_ONE)
3186 asection *s;
3187 bfd_byte stub[SCORE_FUNCTION_STUB_SIZE];
3189 /* This symbol has a stub. Set it up. */
3190 BFD_ASSERT (h->dynindx != -1);
3192 s = bfd_get_section_by_name (dynobj, SCORE_ELF_STUB_SECTION_NAME);
3193 BFD_ASSERT (s != NULL);
3195 /* FIXME: Can h->dynindex be more than 64K? */
3196 if (h->dynindx & 0xffff0000)
3197 return FALSE;
3199 /* Fill the stub. */
3200 bfd_put_32 (output_bfd, STUB_LW, stub);
3201 bfd_put_32 (output_bfd, STUB_MOVE, stub + 4);
3202 bfd_put_32 (output_bfd, STUB_LI16 | (h->dynindx << 1), stub + 8);
3203 bfd_put_32 (output_bfd, STUB_BRL, stub + 12);
3205 BFD_ASSERT (h->plt.offset <= s->size);
3206 memcpy (s->contents + h->plt.offset, stub, SCORE_FUNCTION_STUB_SIZE);
3208 /* Mark the symbol as undefined. plt.offset != -1 occurs
3209 only for the referenced symbol. */
3210 sym->st_shndx = SHN_UNDEF;
3212 /* The run-time linker uses the st_value field of the symbol
3213 to reset the global offset table entry for this external
3214 to its stub address when unlinking a shared object. */
3215 sym->st_value = (s->output_section->vma + s->output_offset + h->plt.offset);
3218 BFD_ASSERT (h->dynindx != -1 || h->forced_local);
3220 sgot = score_elf_got_section (dynobj, FALSE);
3221 BFD_ASSERT (sgot != NULL);
3222 BFD_ASSERT (score_elf_section_data (sgot) != NULL);
3223 g = score_elf_section_data (sgot)->u.got_info;
3224 BFD_ASSERT (g != NULL);
3226 /* Run through the global symbol table, creating GOT entries for all
3227 the symbols that need them. */
3228 if (g->global_gotsym != NULL && h->dynindx >= g->global_gotsym->dynindx)
3230 bfd_vma offset;
3231 bfd_vma value;
3233 value = sym->st_value;
3234 offset = score_elf_global_got_index (dynobj, h);
3235 bfd_put_32 (output_bfd, value, sgot->contents + offset);
3238 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
3239 name = h->root.root.string;
3240 if (strcmp (name, "_DYNAMIC") == 0 || strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
3241 sym->st_shndx = SHN_ABS;
3242 else if (strcmp (name, "_DYNAMIC_LINK") == 0)
3244 sym->st_shndx = SHN_ABS;
3245 sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
3246 sym->st_value = 1;
3248 else if (strcmp (name, GP_DISP_LABEL) == 0)
3250 sym->st_shndx = SHN_ABS;
3251 sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
3252 sym->st_value = elf_gp (output_bfd);
3255 return TRUE;
3258 /* Finish up the dynamic sections. */
3260 static bfd_boolean
3261 _bfd_score_elf_finish_dynamic_sections (bfd *output_bfd,
3262 struct bfd_link_info *info)
3264 bfd *dynobj;
3265 asection *sdyn;
3266 asection *sgot;
3267 asection *s;
3268 struct score_got_info *g;
3270 dynobj = elf_hash_table (info)->dynobj;
3272 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
3274 sgot = score_elf_got_section (dynobj, FALSE);
3275 if (sgot == NULL)
3276 g = NULL;
3277 else
3279 BFD_ASSERT (score_elf_section_data (sgot) != NULL);
3280 g = score_elf_section_data (sgot)->u.got_info;
3281 BFD_ASSERT (g != NULL);
3284 if (elf_hash_table (info)->dynamic_sections_created)
3286 bfd_byte *b;
3288 BFD_ASSERT (sdyn != NULL);
3289 BFD_ASSERT (g != NULL);
3291 for (b = sdyn->contents;
3292 b < sdyn->contents + sdyn->size;
3293 b += SCORE_ELF_DYN_SIZE (dynobj))
3295 Elf_Internal_Dyn dyn;
3296 const char *name;
3297 size_t elemsize;
3298 bfd_boolean swap_out_p;
3300 /* Read in the current dynamic entry. */
3301 (*get_elf_backend_data (dynobj)->s->swap_dyn_in) (dynobj, b, &dyn);
3303 /* Assume that we're going to modify it and write it out. */
3304 swap_out_p = TRUE;
3306 switch (dyn.d_tag)
3308 case DT_RELENT:
3309 s = score_elf_rel_dyn_section (dynobj, FALSE);
3310 BFD_ASSERT (s != NULL);
3311 dyn.d_un.d_val = SCORE_ELF_REL_SIZE (dynobj);
3312 break;
3314 case DT_STRSZ:
3315 /* Rewrite DT_STRSZ. */
3316 dyn.d_un.d_val = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
3317 break;
3319 case DT_PLTGOT:
3320 name = ".got";
3321 s = bfd_get_section_by_name (output_bfd, name);
3322 BFD_ASSERT (s != NULL);
3323 dyn.d_un.d_ptr = s->vma;
3324 break;
3326 case DT_SCORE_BASE_ADDRESS:
3327 s = output_bfd->sections;
3328 BFD_ASSERT (s != NULL);
3329 dyn.d_un.d_ptr = s->vma & ~(bfd_vma) 0xffff;
3330 break;
3332 case DT_SCORE_LOCAL_GOTNO:
3333 dyn.d_un.d_val = g->local_gotno;
3334 break;
3336 case DT_SCORE_UNREFEXTNO:
3337 /* The index into the dynamic symbol table which is the
3338 entry of the first external symbol that is not
3339 referenced within the same object. */
3340 dyn.d_un.d_val = bfd_count_sections (output_bfd) + 1;
3341 break;
3343 case DT_SCORE_GOTSYM:
3344 if (g->global_gotsym)
3346 dyn.d_un.d_val = g->global_gotsym->dynindx;
3347 break;
3349 /* In case if we don't have global got symbols we default
3350 to setting DT_SCORE_GOTSYM to the same value as
3351 DT_SCORE_SYMTABNO, so we just fall through. */
3353 case DT_SCORE_SYMTABNO:
3354 name = ".dynsym";
3355 elemsize = SCORE_ELF_SYM_SIZE (output_bfd);
3356 s = bfd_get_section_by_name (output_bfd, name);
3357 BFD_ASSERT (s != NULL);
3359 dyn.d_un.d_val = s->size / elemsize;
3360 break;
3362 case DT_SCORE_HIPAGENO:
3363 dyn.d_un.d_val = g->local_gotno - SCORE_RESERVED_GOTNO;
3364 break;
3366 default:
3367 swap_out_p = FALSE;
3368 break;
3371 if (swap_out_p)
3372 (*get_elf_backend_data (dynobj)->s->swap_dyn_out) (dynobj, &dyn, b);
3376 /* The first entry of the global offset table will be filled at
3377 runtime. The second entry will be used by some runtime loaders.
3378 This isn't the case of IRIX rld. */
3379 if (sgot != NULL && sgot->size > 0)
3381 bfd_put_32 (output_bfd, 0, sgot->contents);
3382 bfd_put_32 (output_bfd, 0x80000000, sgot->contents + SCORE_ELF_GOT_SIZE (output_bfd));
3385 if (sgot != NULL)
3386 elf_section_data (sgot->output_section)->this_hdr.sh_entsize
3387 = SCORE_ELF_GOT_SIZE (output_bfd);
3390 /* We need to sort the entries of the dynamic relocation section. */
3391 s = score_elf_rel_dyn_section (dynobj, FALSE);
3393 if (s != NULL && s->size > (bfd_vma)2 * SCORE_ELF_REL_SIZE (output_bfd))
3395 reldyn_sorting_bfd = output_bfd;
3396 qsort ((Elf32_External_Rel *) s->contents + 1, s->reloc_count - 1,
3397 sizeof (Elf32_External_Rel), score_elf_sort_dynamic_relocs);
3400 return TRUE;
3403 /* This function set up the ELF section header for a BFD section in preparation for writing
3404 it out. This is where the flags and type fields are set for unusual sections. */
3406 static bfd_boolean
3407 _bfd_score_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
3408 Elf_Internal_Shdr *hdr,
3409 asection *sec)
3411 const char *name;
3413 name = bfd_get_section_name (abfd, sec);
3415 if (strcmp (name, ".got") == 0
3416 || strcmp (name, ".srdata") == 0
3417 || strcmp (name, ".sdata") == 0
3418 || strcmp (name, ".sbss") == 0)
3419 hdr->sh_flags |= SHF_SCORE_GPREL;
3421 return TRUE;
3424 /* This function do additional processing on the ELF section header before writing
3425 it out. This is used to set the flags and type fields for some sections. */
3427 /* assign_file_positions_except_relocs() check section flag and if it is allocatable,
3428 warning message will be issued. backend_fake_section is called before
3429 assign_file_positions_except_relocs(); backend_section_processing after it. so, we
3430 modify section flag there, but not backend_fake_section. */
3432 static bfd_boolean
3433 _bfd_score_elf_section_processing (bfd *abfd ATTRIBUTE_UNUSED, Elf_Internal_Shdr *hdr)
3435 if (hdr->bfd_section != NULL)
3437 const char *name = bfd_get_section_name (abfd, hdr->bfd_section);
3439 if (strcmp (name, ".sdata") == 0)
3441 hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
3442 hdr->sh_type = SHT_PROGBITS;
3444 else if (strcmp (name, ".sbss") == 0)
3446 hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
3447 hdr->sh_type = SHT_NOBITS;
3449 else if (strcmp (name, ".srdata") == 0)
3451 hdr->sh_flags |= SHF_ALLOC | SHF_SCORE_GPREL;
3452 hdr->sh_type = SHT_PROGBITS;
3456 return TRUE;
3459 static bfd_boolean
3460 _bfd_score_elf_write_section (bfd *output_bfd, asection *sec, bfd_byte *contents)
3462 bfd_byte *to, *from, *end;
3463 int i;
3465 if (strcmp (sec->name, ".pdr") != 0)
3466 return FALSE;
3468 if (score_elf_section_data (sec)->u.tdata == NULL)
3469 return FALSE;
3471 to = contents;
3472 end = contents + sec->size;
3473 for (from = contents, i = 0; from < end; from += PDR_SIZE, i++)
3475 if ((score_elf_section_data (sec)->u.tdata)[i] == 1)
3476 continue;
3478 if (to != from)
3479 memcpy (to, from, PDR_SIZE);
3481 to += PDR_SIZE;
3483 bfd_set_section_contents (output_bfd, sec->output_section, contents,
3484 (file_ptr) sec->output_offset, sec->size);
3486 return TRUE;
3489 /* Copy data from a SCORE ELF indirect symbol to its direct symbol, hiding the old
3490 indirect symbol. Process additional relocation information. */
3492 static void
3493 _bfd_score_elf_copy_indirect_symbol (struct bfd_link_info *info,
3494 struct elf_link_hash_entry *dir,
3495 struct elf_link_hash_entry *ind)
3497 struct score_elf_link_hash_entry *dirscore, *indscore;
3499 _bfd_elf_link_hash_copy_indirect (info, dir, ind);
3501 if (ind->root.type != bfd_link_hash_indirect)
3502 return;
3504 dirscore = (struct score_elf_link_hash_entry *) dir;
3505 indscore = (struct score_elf_link_hash_entry *) ind;
3506 dirscore->possibly_dynamic_relocs += indscore->possibly_dynamic_relocs;
3508 if (indscore->readonly_reloc)
3509 dirscore->readonly_reloc = TRUE;
3511 if (indscore->no_fn_stub)
3512 dirscore->no_fn_stub = TRUE;
3515 /* Remove information about discarded functions from other sections which mention them. */
3517 static bfd_boolean
3518 _bfd_score_elf_discard_info (bfd *abfd, struct elf_reloc_cookie *cookie,
3519 struct bfd_link_info *info)
3521 asection *o;
3522 bfd_boolean ret = FALSE;
3523 unsigned char *tdata;
3524 size_t i, skip;
3526 o = bfd_get_section_by_name (abfd, ".pdr");
3527 if ((!o) || (o->size == 0) || (o->size % PDR_SIZE != 0)
3528 || (o->output_section != NULL && bfd_is_abs_section (o->output_section)))
3529 return FALSE;
3531 tdata = bfd_zmalloc (o->size / PDR_SIZE);
3532 if (!tdata)
3533 return FALSE;
3535 cookie->rels = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, info->keep_memory);
3536 if (!cookie->rels)
3538 free (tdata);
3539 return FALSE;
3542 cookie->rel = cookie->rels;
3543 cookie->relend = cookie->rels + o->reloc_count;
3545 for (i = 0, skip = 0; i < o->size; i++)
3547 if (bfd_elf_reloc_symbol_deleted_p (i * PDR_SIZE, cookie))
3549 tdata[i] = 1;
3550 skip++;
3554 if (skip != 0)
3556 score_elf_section_data (o)->u.tdata = tdata;
3557 o->size -= skip * PDR_SIZE;
3558 ret = TRUE;
3560 else
3561 free (tdata);
3563 if (!info->keep_memory)
3564 free (cookie->rels);
3566 return ret;
3569 /* Signal that discard_info() has removed the discarded relocations for this section. */
3571 static bfd_boolean
3572 _bfd_score_elf_ignore_discarded_relocs (asection *sec)
3574 if (strcmp (sec->name, ".pdr") == 0)
3575 return TRUE;
3576 return FALSE;
3579 /* Return the section that should be marked against GC for a given
3580 relocation. */
3582 static asection *
3583 _bfd_score_elf_gc_mark_hook (asection *sec,
3584 struct bfd_link_info *info,
3585 Elf_Internal_Rela *rel,
3586 struct elf_link_hash_entry *h,
3587 Elf_Internal_Sym *sym)
3589 if (h != NULL)
3590 switch (ELF32_R_TYPE (rel->r_info))
3592 case R_SCORE_GNU_VTINHERIT:
3593 case R_SCORE_GNU_VTENTRY:
3594 return NULL;
3597 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
3600 /* Support for core dump NOTE sections. */
3602 static bfd_boolean
3603 _bfd_score_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
3605 int offset;
3606 unsigned int raw_size;
3608 switch (note->descsz)
3610 default:
3611 return FALSE;
3613 case 148: /* Linux/Score 32-bit. */
3614 /* pr_cursig */
3615 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
3617 /* pr_pid */
3618 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
3620 /* pr_reg */
3621 offset = 72;
3622 raw_size = 72;
3624 break;
3627 /* Make a ".reg/999" section. */
3628 return _bfd_elfcore_make_pseudosection (abfd, ".reg", raw_size, note->descpos + offset);
3631 static bfd_boolean
3632 _bfd_score_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
3634 switch (note->descsz)
3636 default:
3637 return FALSE;
3639 case 124: /* Linux/Score elf_prpsinfo. */
3640 elf_tdata (abfd)->core_program = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
3641 elf_tdata (abfd)->core_command = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
3644 /* Note that for some reason, a spurious space is tacked
3645 onto the end of the args in some (at least one anyway)
3646 implementations, so strip it off if it exists. */
3649 char *command = elf_tdata (abfd)->core_command;
3650 int n = strlen (command);
3652 if (0 < n && command[n - 1] == ' ')
3653 command[n - 1] = '\0';
3656 return TRUE;
3660 /* Score BFD functions. */
3662 static reloc_howto_type *
3663 elf32_score_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
3665 unsigned int i;
3667 for (i = 0; i < NUM_ELEM (elf32_score_reloc_map); i++)
3668 if (elf32_score_reloc_map[i].bfd_reloc_val == code)
3669 return &elf32_score_howto_table[elf32_score_reloc_map[i].elf_reloc_val];
3671 return NULL;
3674 /* Create a score elf linker hash table. */
3676 static struct bfd_link_hash_table *
3677 elf32_score_link_hash_table_create (bfd *abfd)
3679 struct score_elf_link_hash_table *ret;
3680 bfd_size_type amt = sizeof (struct score_elf_link_hash_table);
3682 ret = bfd_malloc (amt);
3683 if (ret == NULL)
3684 return NULL;
3686 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd, score_elf_link_hash_newfunc,
3687 sizeof (struct score_elf_link_hash_entry)))
3689 free (ret);
3690 return NULL;
3693 return &ret->root.root;
3696 static bfd_boolean
3697 elf32_score_print_private_bfd_data (bfd *abfd, void * ptr)
3699 FILE *file = (FILE *) ptr;
3701 BFD_ASSERT (abfd != NULL && ptr != NULL);
3703 /* Print normal ELF private data. */
3704 _bfd_elf_print_private_bfd_data (abfd, ptr);
3706 /* xgettext:c-format */
3707 fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
3708 if (elf_elfheader (abfd)->e_flags & EF_SCORE_PIC)
3710 fprintf (file, _(" [pic]"));
3712 if (elf_elfheader (abfd)->e_flags & EF_SCORE_FIXDEP)
3714 fprintf (file, _(" [fix dep]"));
3716 fputc ('\n', file);
3718 return TRUE;
3721 static bfd_boolean
3722 elf32_score_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
3724 flagword in_flags;
3725 flagword out_flags;
3727 if (!_bfd_generic_verify_endian_match (ibfd, obfd))
3728 return FALSE;
3730 in_flags = elf_elfheader (ibfd)->e_flags;
3731 out_flags = elf_elfheader (obfd)->e_flags;
3733 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
3734 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
3735 return TRUE;
3737 in_flags = elf_elfheader (ibfd)->e_flags;
3738 out_flags = elf_elfheader (obfd)->e_flags;
3740 if (! elf_flags_init (obfd))
3742 elf_flags_init (obfd) = TRUE;
3743 elf_elfheader (obfd)->e_flags = in_flags;
3745 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
3746 && bfd_get_arch_info (obfd)->the_default)
3748 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
3751 return TRUE;
3754 if (((in_flags & EF_SCORE_PIC) != 0) != ((out_flags & EF_SCORE_PIC) != 0))
3756 (*_bfd_error_handler) (_("%B: warning: linking PIC files with non-PIC files"), ibfd);
3759 /* FIXME: Maybe dependency fix compatibility should be checked here. */
3761 return TRUE;
3764 static bfd_boolean
3765 elf32_score_new_section_hook (bfd *abfd, asection *sec)
3767 struct _score_elf_section_data *sdata;
3768 bfd_size_type amt = sizeof (*sdata);
3770 sdata = bfd_zalloc (abfd, amt);
3771 if (sdata == NULL)
3772 return FALSE;
3773 sec->used_by_bfd = sdata;
3775 return _bfd_elf_new_section_hook (abfd, sec);
3779 #define USE_REL 1
3780 #define TARGET_LITTLE_SYM bfd_elf32_littlescore_vec
3781 #define TARGET_LITTLE_NAME "elf32-littlescore"
3782 #define TARGET_BIG_SYM bfd_elf32_bigscore_vec
3783 #define TARGET_BIG_NAME "elf32-bigscore"
3784 #define ELF_ARCH bfd_arch_score
3785 #define ELF_MACHINE_CODE EM_SCORE
3786 #define ELF_MAXPAGESIZE 0x8000
3788 #define elf_info_to_howto 0
3789 #define elf_info_to_howto_rel _bfd_score_info_to_howto
3790 #define elf_backend_relocate_section _bfd_score_elf_relocate_section
3791 #define elf_backend_check_relocs _bfd_score_elf_check_relocs
3792 #define elf_backend_add_symbol_hook _bfd_score_elf_add_symbol_hook
3793 #define elf_backend_symbol_processing _bfd_score_elf_symbol_processing
3794 #define elf_backend_link_output_symbol_hook \
3795 _bfd_score_elf_link_output_symbol_hook
3796 #define elf_backend_section_from_bfd_section \
3797 _bfd_score_elf_section_from_bfd_section
3798 #define elf_backend_adjust_dynamic_symbol \
3799 _bfd_score_elf_adjust_dynamic_symbol
3800 #define elf_backend_always_size_sections \
3801 _bfd_score_elf_always_size_sections
3802 #define elf_backend_size_dynamic_sections \
3803 _bfd_score_elf_size_dynamic_sections
3804 #define elf_backend_omit_section_dynsym \
3805 ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
3806 #define elf_backend_create_dynamic_sections \
3807 _bfd_score_elf_create_dynamic_sections
3808 #define elf_backend_finish_dynamic_symbol \
3809 _bfd_score_elf_finish_dynamic_symbol
3810 #define elf_backend_finish_dynamic_sections \
3811 _bfd_score_elf_finish_dynamic_sections
3812 #define elf_backend_fake_sections _bfd_score_elf_fake_sections
3813 #define elf_backend_section_processing _bfd_score_elf_section_processing
3814 #define elf_backend_write_section _bfd_score_elf_write_section
3815 #define elf_backend_copy_indirect_symbol _bfd_score_elf_copy_indirect_symbol
3816 #define elf_backend_hide_symbol _bfd_score_elf_hide_symbol
3817 #define elf_backend_discard_info _bfd_score_elf_discard_info
3818 #define elf_backend_ignore_discarded_relocs \
3819 _bfd_score_elf_ignore_discarded_relocs
3820 #define elf_backend_gc_mark_hook _bfd_score_elf_gc_mark_hook
3821 #define elf_backend_grok_prstatus _bfd_score_elf_grok_prstatus
3822 #define elf_backend_grok_psinfo _bfd_score_elf_grok_psinfo
3823 #define elf_backend_can_gc_sections 1
3824 #define elf_backend_want_plt_sym 0
3825 #define elf_backend_got_header_size (4 * SCORE_RESERVED_GOTNO)
3826 #define elf_backend_plt_header_size 0
3827 #define elf_backend_collect TRUE
3828 #define elf_backend_type_change_ok TRUE
3830 #define bfd_elf32_bfd_reloc_type_lookup elf32_score_reloc_type_lookup
3831 #define bfd_elf32_bfd_link_hash_table_create elf32_score_link_hash_table_create
3832 #define bfd_elf32_bfd_print_private_bfd_data elf32_score_print_private_bfd_data
3833 #define bfd_elf32_bfd_merge_private_bfd_data elf32_score_merge_private_bfd_data
3834 #define bfd_elf32_new_section_hook elf32_score_new_section_hook
3836 #include "elf32-target.h"