Fix indent for --symbols in "readelf -h"
[binutils.git] / bfd / elf32-score7.c
blobbb74f28c2f59df8d9dae1133accf9c205b3b2092
1 /* 32-bit ELF support for S+core.
2 Copyright 2009 Free Software Foundation, Inc.
3 Contributed by
4 Brain.lin (brain.lin@sunplusct.com)
5 Mei Ligang (ligang@sunnorth.com.cn)
6 Pei-Lin Tsai (pltsai@sunplus.com)
8 This file is part of BFD, the Binary File Descriptor library.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
23 MA 02110-1301, USA. */
25 #include "bfd.h"
26 #include "sysdep.h"
27 #include "libbfd.h"
28 #include "libiberty.h"
29 #include "elf-bfd.h"
30 #include "elf/score.h"
31 #include "elf/common.h"
32 #include "elf/internal.h"
33 #include "hashtab.h"
34 #include "elf32-score.h"
37 /* Score ELF linker hash table. */
38 struct score_elf_link_hash_table
40 /* The main hash table. */
41 struct elf_link_hash_table root;
44 /* The SCORE ELF linker needs additional information for each symbol in
45 the global hash table. */
46 struct score_elf_link_hash_entry
48 struct elf_link_hash_entry root;
50 /* Number of R_SCORE_ABS32, R_SCORE_REL32 relocs against this symbol. */
51 unsigned int possibly_dynamic_relocs;
53 /* If the R_SCORE_ABS32, R_SCORE_REL32 reloc is against a readonly section. */
54 bfd_boolean readonly_reloc;
56 /* We must not create a stub for a symbol that has relocations related to
57 taking the function's address, i.e. any but R_SCORE_CALL15 ones. */
58 bfd_boolean no_fn_stub;
60 /* Are we forced local? This will only be set if we have converted
61 the initial global GOT entry to a local GOT entry. */
62 bfd_boolean forced_local;
65 /* Traverse a score ELF linker hash table. */
66 #define score_elf_link_hash_traverse(table, func, info) \
67 (elf_link_hash_traverse \
68 (&(table)->root, \
69 (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \
70 (info)))
72 /* Get the SCORE elf linker hash table from a link_info structure. */
73 #define score_elf_hash_table(info) \
74 ((struct score_elf_link_hash_table *) ((info)->hash))
76 /* This structure is used to hold .got entries while estimating got sizes. */
77 struct score_got_entry
79 /* The input bfd in which the symbol is defined. */
80 bfd *abfd;
81 /* The index of the symbol, as stored in the relocation r_info, if
82 we have a local symbol; -1 otherwise. */
83 long symndx;
84 union
86 /* If abfd == NULL, an address that must be stored in the got. */
87 bfd_vma address;
88 /* If abfd != NULL && symndx != -1, the addend of the relocation
89 that should be added to the symbol value. */
90 bfd_vma addend;
91 /* If abfd != NULL && symndx == -1, the hash table entry
92 corresponding to a global symbol in the got (or, local, if
93 h->forced_local). */
94 struct score_elf_link_hash_entry *h;
95 } d;
97 /* The offset from the beginning of the .got section to the entry
98 corresponding to this symbol+addend. If it's a global symbol
99 whose offset is yet to be decided, it's going to be -1. */
100 long gotidx;
103 /* This structure is passed to score_elf_sort_hash_table_f when sorting
104 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)
172 /* The maximum size of the GOT for it to be addressable using 15-bit offsets from $gp. */
173 #define SCORE_ELF_GOT_MAX_SIZE(abfd) (ELF_SCORE_GP_OFFSET(abfd) + 0x3fff)
175 #define SCORE_ELF_STUB_SECTION_NAME (".SCORE.stub")
176 #define SCORE_FUNCTION_STUB_SIZE (16)
178 #define STUB_LW 0xc3bcc010 /* lw r29, [r28, -0x3ff0] */
179 #define STUB_MOVE 0x8323bc56 /* mv r25, r3 */
180 #define STUB_LI16 0x87548000 /* ori r26, .dynsym_index */
181 #define STUB_BRL 0x801dbc09 /* brl r29 */
183 #define SCORE_ELF_GOT_SIZE(abfd) \
184 (get_elf_backend_data (abfd)->s->arch_size / 8)
186 #define SCORE_ELF_ADD_DYNAMIC_ENTRY(info, tag, val) \
187 (_bfd_elf_add_dynamic_entry (info, (bfd_vma) tag, (bfd_vma) val))
189 /* The size of an external dynamic table entry. */
190 #define SCORE_ELF_DYN_SIZE(abfd) \
191 (get_elf_backend_data (abfd)->s->sizeof_dyn)
193 /* The size of an external REL relocation. */
194 #define SCORE_ELF_REL_SIZE(abfd) \
195 (get_elf_backend_data (abfd)->s->sizeof_rel)
197 /* The default alignment for sections, as a power of two. */
198 #define SCORE_ELF_LOG_FILE_ALIGN(abfd)\
199 (get_elf_backend_data (abfd)->s->log_file_align)
201 static bfd_byte *hi16_rel_addr;
203 /* This will be used when we sort the dynamic relocation records. */
204 static bfd *reldyn_sorting_bfd;
206 /* SCORE ELF uses two common sections. One is the usual one, and the
207 other is for small objects. All the small objects are kept
208 together, and then referenced via the gp pointer, which yields
209 faster assembler code. This is what we use for the small common
210 section. This approach is copied from ecoff.c. */
211 static asection score_elf_scom_section;
212 static asymbol score_elf_scom_symbol;
213 static asymbol * score_elf_scom_symbol_ptr;
215 static bfd_reloc_status_type
216 score_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED,
217 arelent *reloc_entry,
218 asymbol *symbol ATTRIBUTE_UNUSED,
219 void * data,
220 asection *input_section ATTRIBUTE_UNUSED,
221 bfd *output_bfd ATTRIBUTE_UNUSED,
222 char **error_message ATTRIBUTE_UNUSED)
224 hi16_rel_addr = (bfd_byte *) data + reloc_entry->address;
225 return bfd_reloc_ok;
228 static bfd_reloc_status_type
229 score_elf_lo16_reloc (bfd *abfd,
230 arelent *reloc_entry,
231 asymbol *symbol ATTRIBUTE_UNUSED,
232 void * data,
233 asection *input_section,
234 bfd *output_bfd ATTRIBUTE_UNUSED,
235 char **error_message ATTRIBUTE_UNUSED)
237 bfd_vma addend = 0, offset = 0;
238 unsigned long val;
239 unsigned long hi16_offset, hi16_value, uvalue;
241 hi16_value = bfd_get_32 (abfd, hi16_rel_addr);
242 hi16_offset = ((((hi16_value >> 16) & 0x3) << 15) | (hi16_value & 0x7fff)) >> 1;
243 addend = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
244 offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
245 val = reloc_entry->addend;
246 if (reloc_entry->address > input_section->size)
247 return bfd_reloc_outofrange;
248 uvalue = ((hi16_offset << 16) | (offset & 0xffff)) + val;
249 hi16_offset = (uvalue >> 16) << 1;
250 hi16_value = (hi16_value & ~0x37fff) | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
251 bfd_put_32 (abfd, hi16_value, hi16_rel_addr);
252 offset = (uvalue & 0xffff) << 1;
253 addend = (addend & ~0x37fff) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
254 bfd_put_32 (abfd, addend, (bfd_byte *) data + reloc_entry->address);
255 return bfd_reloc_ok;
258 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
259 dangerous relocation. */
261 static bfd_boolean
262 score_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
264 unsigned int count;
265 asymbol **sym;
266 unsigned int i;
268 /* If we've already figured out what GP will be, just return it. */
269 *pgp = _bfd_get_gp_value (output_bfd);
270 if (*pgp)
271 return TRUE;
273 count = bfd_get_symcount (output_bfd);
274 sym = bfd_get_outsymbols (output_bfd);
276 /* The linker script will have created a symbol named `_gp' with the
277 appropriate value. */
278 if (sym == NULL)
279 i = count;
280 else
282 for (i = 0; i < count; i++, sym++)
284 const char *name;
286 name = bfd_asymbol_name (*sym);
287 if (*name == '_' && strcmp (name, "_gp") == 0)
289 *pgp = bfd_asymbol_value (*sym);
290 _bfd_set_gp_value (output_bfd, *pgp);
291 break;
296 if (i >= count)
298 /* Only get the error once. */
299 *pgp = 4;
300 _bfd_set_gp_value (output_bfd, *pgp);
301 return FALSE;
304 return TRUE;
307 /* We have to figure out the gp value, so that we can adjust the
308 symbol value correctly. We look up the symbol _gp in the output
309 BFD. If we can't find it, we're stuck. We cache it in the ELF
310 target data. We don't need to adjust the symbol value for an
311 external symbol if we are producing relocatable output. */
313 static bfd_reloc_status_type
314 score_elf_final_gp (bfd *output_bfd,
315 asymbol *symbol,
316 bfd_boolean relocatable,
317 char **error_message,
318 bfd_vma *pgp)
320 if (bfd_is_und_section (symbol->section)
321 && ! relocatable)
323 *pgp = 0;
324 return bfd_reloc_undefined;
327 *pgp = _bfd_get_gp_value (output_bfd);
328 if (*pgp == 0
329 && (! relocatable
330 || (symbol->flags & BSF_SECTION_SYM) != 0))
332 if (relocatable)
334 /* Make up a value. */
335 *pgp = symbol->section->output_section->vma + 0x4000;
336 _bfd_set_gp_value (output_bfd, *pgp);
338 else if (!score_elf_assign_gp (output_bfd, pgp))
340 *error_message =
341 (char *) _("GP relative relocation when _gp not defined");
342 return bfd_reloc_dangerous;
346 return bfd_reloc_ok;
349 static bfd_reloc_status_type
350 score_elf_gprel15_with_gp (bfd *abfd,
351 asymbol *symbol,
352 arelent *reloc_entry,
353 asection *input_section,
354 bfd_boolean relocateable,
355 void * data,
356 bfd_vma gp ATTRIBUTE_UNUSED)
358 bfd_vma relocation;
359 unsigned long insn;
361 if (bfd_is_com_section (symbol->section))
362 relocation = 0;
363 else
364 relocation = symbol->value;
366 relocation += symbol->section->output_section->vma;
367 relocation += symbol->section->output_offset;
368 if (reloc_entry->address > input_section->size)
369 return bfd_reloc_outofrange;
371 insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
372 if (((reloc_entry->addend & 0xffffc000) != 0)
373 && ((reloc_entry->addend & 0xffffc000) != 0xffffc000))
374 return bfd_reloc_overflow;
376 insn = (insn & ~0x7fff) | (reloc_entry->addend & 0x7fff);
377 bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
378 if (relocateable)
379 reloc_entry->address += input_section->output_offset;
381 return bfd_reloc_ok;
384 static bfd_reloc_status_type
385 gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
386 asection *input_section, bfd_boolean relocatable,
387 void *data, bfd_vma gp)
389 bfd_vma relocation;
390 bfd_vma val;
392 if (bfd_is_com_section (symbol->section))
393 relocation = 0;
394 else
395 relocation = symbol->value;
397 relocation += symbol->section->output_section->vma;
398 relocation += symbol->section->output_offset;
400 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
401 return bfd_reloc_outofrange;
403 /* Set val to the offset into the section or symbol. */
404 val = reloc_entry->addend;
406 if (reloc_entry->howto->partial_inplace)
407 val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
409 /* Adjust val for the final section location and GP value. If we
410 are producing relocatable output, we don't want to do this for
411 an external symbol. */
412 if (! relocatable
413 || (symbol->flags & BSF_SECTION_SYM) != 0)
414 val += relocation - gp;
416 if (reloc_entry->howto->partial_inplace)
417 bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
418 else
419 reloc_entry->addend = val;
421 if (relocatable)
422 reloc_entry->address += input_section->output_offset;
424 return bfd_reloc_ok;
427 static bfd_reloc_status_type
428 score_elf_gprel15_reloc (bfd *abfd,
429 arelent *reloc_entry,
430 asymbol *symbol,
431 void * data,
432 asection *input_section,
433 bfd *output_bfd,
434 char **error_message)
436 bfd_boolean relocateable;
437 bfd_reloc_status_type ret;
438 bfd_vma gp;
440 if (output_bfd != NULL
441 && (symbol->flags & BSF_SECTION_SYM) == 0 && reloc_entry->addend == 0)
443 reloc_entry->address += input_section->output_offset;
444 return bfd_reloc_ok;
446 if (output_bfd != NULL)
447 relocateable = TRUE;
448 else
450 relocateable = FALSE;
451 output_bfd = symbol->section->output_section->owner;
454 ret = score_elf_final_gp (output_bfd, symbol, relocateable, error_message, &gp);
455 if (ret != bfd_reloc_ok)
456 return ret;
458 return score_elf_gprel15_with_gp (abfd, symbol, reloc_entry,
459 input_section, relocateable, data, gp);
462 /* Do a R_SCORE_GPREL32 relocation. This is a 32 bit value which must
463 become the offset from the gp register. */
465 static bfd_reloc_status_type
466 score_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
467 void *data, asection *input_section, bfd *output_bfd,
468 char **error_message)
470 bfd_boolean relocatable;
471 bfd_reloc_status_type ret;
472 bfd_vma gp;
474 /* R_SCORE_GPREL32 relocations are defined for local symbols only. */
475 if (output_bfd != NULL
476 && (symbol->flags & BSF_SECTION_SYM) == 0
477 && (symbol->flags & BSF_LOCAL) != 0)
479 *error_message = (char *)
480 _("32bits gp relative relocation occurs for an external symbol");
481 return bfd_reloc_outofrange;
484 if (output_bfd != NULL)
485 relocatable = TRUE;
486 else
488 relocatable = FALSE;
489 output_bfd = symbol->section->output_section->owner;
492 ret = score_elf_final_gp (output_bfd, symbol, relocatable, error_message, &gp);
493 if (ret != bfd_reloc_ok)
494 return ret;
496 gp = 0;
497 return gprel32_with_gp (abfd, symbol, reloc_entry, input_section,
498 relocatable, data, gp);
501 /* A howto special_function for R_SCORE_GOT15 relocations. This is just
502 like any other 16-bit relocation when applied to global symbols, but is
503 treated in the same as R_SCORE_HI16 when applied to local symbols. */
505 static bfd_reloc_status_type
506 score_elf_got15_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
507 void *data, asection *input_section,
508 bfd *output_bfd, char **error_message)
510 if ((symbol->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
511 || bfd_is_und_section (bfd_get_section (symbol))
512 || bfd_is_com_section (bfd_get_section (symbol)))
513 /* The relocation is against a global symbol. */
514 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
515 input_section, output_bfd,
516 error_message);
518 return score_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
519 input_section, output_bfd, error_message);
522 static bfd_reloc_status_type
523 score_elf_got_lo16_reloc (bfd *abfd,
524 arelent *reloc_entry,
525 asymbol *symbol ATTRIBUTE_UNUSED,
526 void * data,
527 asection *input_section,
528 bfd *output_bfd ATTRIBUTE_UNUSED,
529 char **error_message ATTRIBUTE_UNUSED)
531 bfd_vma addend = 0, offset = 0;
532 signed long val;
533 signed long hi16_offset, hi16_value, uvalue;
535 hi16_value = bfd_get_32 (abfd, hi16_rel_addr);
536 hi16_offset = ((((hi16_value >> 16) & 0x3) << 15) | (hi16_value & 0x7fff)) >> 1;
537 addend = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
538 offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
539 val = reloc_entry->addend;
540 if (reloc_entry->address > input_section->size)
541 return bfd_reloc_outofrange;
542 uvalue = ((hi16_offset << 16) | (offset & 0xffff)) + val;
543 if ((uvalue > -0x8000) && (uvalue < 0x7fff))
544 hi16_offset = 0;
545 else
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_BCMP */
603 HOWTO (R_SCORE_BCMP, /* 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_BCMP", /* name */
612 TRUE, /* partial_inplace */
613 0x0000ffff, /* src_mask */
614 0x0000ffff, /* dst_mask */
615 FALSE), /* pcrel_offset */
617 HOWTO (R_SCORE_24, /* type */
618 1, /* rightshift */
619 2, /* size (0 = byte, 1 = short, 2 = long) */
620 24, /* bitsize */
621 FALSE, /* pc_relative */
622 1, /* bitpos */
623 complain_overflow_dont,/* complain_on_overflow */
624 bfd_elf_generic_reloc, /* special_function */
625 "R_SCORE_24", /* name */
626 FALSE, /* partial_inplace */
627 0x3ff7fff, /* src_mask */
628 0x3ff7fff, /* dst_mask */
629 FALSE), /* pcrel_offset */
631 /*R_SCORE_PC19 */
632 HOWTO (R_SCORE_PC19, /* type */
633 1, /* rightshift */
634 2, /* size (0 = byte, 1 = short, 2 = long) */
635 19, /* bitsize */
636 TRUE, /* pc_relative */
637 1, /* bitpos */
638 complain_overflow_dont,/* complain_on_overflow */
639 bfd_elf_generic_reloc, /* special_function */
640 "R_SCORE_PC19", /* name */
641 FALSE, /* partial_inplace */
642 0x3ff03fe, /* src_mask */
643 0x3ff03fe, /* dst_mask */
644 FALSE), /* pcrel_offset */
646 /*R_SCORE16_11 */
647 HOWTO (R_SCORE16_11, /* type */
648 1, /* rightshift */
649 1, /* size (0 = byte, 1 = short, 2 = long) */
650 11, /* bitsize */
651 FALSE, /* pc_relative */
652 1, /* bitpos */
653 complain_overflow_dont,/* complain_on_overflow */
654 bfd_elf_generic_reloc, /* special_function */
655 "R_SCORE16_11", /* name */
656 FALSE, /* partial_inplace */
657 0x000000ffe, /* src_mask */
658 0x000000ffe, /* dst_mask */
659 FALSE), /* pcrel_offset */
661 /* R_SCORE16_PC8 */
662 HOWTO (R_SCORE16_PC8, /* type */
663 1, /* rightshift */
664 1, /* size (0 = byte, 1 = short, 2 = long) */
665 8, /* bitsize */
666 TRUE, /* pc_relative */
667 0, /* bitpos */
668 complain_overflow_dont,/* complain_on_overflow */
669 bfd_elf_generic_reloc, /* special_function */
670 "R_SCORE16_PC8", /* name */
671 FALSE, /* partial_inplace */
672 0x000000ff, /* src_mask */
673 0x000000ff, /* dst_mask */
674 FALSE), /* pcrel_offset */
676 /* 32 bit absolute */
677 HOWTO (R_SCORE_ABS32, /* type 8 */
678 0, /* rightshift */
679 2, /* size (0 = byte, 1 = short, 2 = long) */
680 32, /* bitsize */
681 FALSE, /* pc_relative */
682 0, /* bitpos */
683 complain_overflow_bitfield, /* complain_on_overflow */
684 bfd_elf_generic_reloc, /* special_function */
685 "R_SCORE_ABS32", /* name */
686 FALSE, /* partial_inplace */
687 0xffffffff, /* src_mask */
688 0xffffffff, /* dst_mask */
689 FALSE), /* pcrel_offset */
691 /* 16 bit absolute */
692 HOWTO (R_SCORE_ABS16, /* type 11 */
693 0, /* rightshift */
694 1, /* size (0 = byte, 1 = short, 2 = long) */
695 16, /* bitsize */
696 FALSE, /* pc_relative */
697 0, /* bitpos */
698 complain_overflow_bitfield, /* complain_on_overflow */
699 bfd_elf_generic_reloc, /* special_function */
700 "R_SCORE_ABS16", /* name */
701 FALSE, /* partial_inplace */
702 0x0000ffff, /* src_mask */
703 0x0000ffff, /* dst_mask */
704 FALSE), /* pcrel_offset */
706 /* R_SCORE_DUMMY2 */
707 HOWTO (R_SCORE_DUMMY2, /* type */
708 0, /* rightshift */
709 2, /* size (0 = byte, 1 = short, 2 = long) */
710 16, /* bitsize */
711 FALSE, /* pc_relative */
712 0, /* bitpos */
713 complain_overflow_dont,/* complain_on_overflow */
714 bfd_elf_generic_reloc, /* special_function */
715 "R_SCORE_DUMMY2", /* name */
716 TRUE, /* partial_inplace */
717 0x00007fff, /* src_mask */
718 0x00007fff, /* dst_mask */
719 FALSE), /* pcrel_offset */
721 /* R_SCORE_GP15 */
722 HOWTO (R_SCORE_GP15, /* type */
723 0, /* rightshift */
724 2, /* size (0 = byte, 1 = short, 2 = long) */
725 16, /* bitsize */
726 FALSE, /* pc_relative */
727 0, /* bitpos */
728 complain_overflow_dont,/* complain_on_overflow */
729 score_elf_gprel15_reloc,/* special_function */
730 "R_SCORE_GP15", /* name */
731 TRUE, /* partial_inplace */
732 0x00007fff, /* src_mask */
733 0x00007fff, /* dst_mask */
734 FALSE), /* pcrel_offset */
736 /* GNU extension to record C++ vtable hierarchy. */
737 HOWTO (R_SCORE_GNU_VTINHERIT, /* type */
738 0, /* rightshift */
739 2, /* size (0 = byte, 1 = short, 2 = long) */
740 0, /* bitsize */
741 FALSE, /* pc_relative */
742 0, /* bitpos */
743 complain_overflow_dont,/* complain_on_overflow */
744 NULL, /* special_function */
745 "R_SCORE_GNU_VTINHERIT", /* name */
746 FALSE, /* partial_inplace */
747 0, /* src_mask */
748 0, /* dst_mask */
749 FALSE), /* pcrel_offset */
751 /* GNU extension to record C++ vtable member usage */
752 HOWTO (R_SCORE_GNU_VTENTRY, /* type */
753 0, /* rightshift */
754 2, /* size (0 = byte, 1 = short, 2 = long) */
755 0, /* bitsize */
756 FALSE, /* pc_relative */
757 0, /* bitpos */
758 complain_overflow_dont,/* complain_on_overflow */
759 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
760 "R_SCORE_GNU_VTENTRY", /* name */
761 FALSE, /* partial_inplace */
762 0, /* src_mask */
763 0, /* dst_mask */
764 FALSE), /* pcrel_offset */
766 /* Reference to global offset table. */
767 HOWTO (R_SCORE_GOT15, /* type */
768 0, /* rightshift */
769 2, /* size (0 = byte, 1 = short, 2 = long) */
770 16, /* bitsize */
771 FALSE, /* pc_relative */
772 0, /* bitpos */
773 complain_overflow_signed, /* complain_on_overflow */
774 score_elf_got15_reloc, /* special_function */
775 "R_SCORE_GOT15", /* name */
776 TRUE, /* partial_inplace */
777 0x00007fff, /* src_mask */
778 0x00007fff, /* dst_mask */
779 FALSE), /* pcrel_offset */
781 /* Low 16 bits of displacement in global offset table. */
782 HOWTO (R_SCORE_GOT_LO16, /* type */
783 0, /* rightshift */
784 2, /* size (0 = byte, 1 = short, 2 = long) */
785 16, /* bitsize */
786 FALSE, /* pc_relative */
787 1, /* bitpos */
788 complain_overflow_dont,/* complain_on_overflow */
789 score_elf_got_lo16_reloc, /* special_function */
790 "R_SCORE_GOT_LO16", /* name */
791 TRUE, /* partial_inplace */
792 0x37ffe, /* src_mask */
793 0x37ffe, /* dst_mask */
794 FALSE), /* pcrel_offset */
796 /* 15 bit call through global offset table. */
797 HOWTO (R_SCORE_CALL15, /* type */
798 0, /* rightshift */
799 2, /* size (0 = byte, 1 = short, 2 = long) */
800 16, /* bitsize */
801 FALSE, /* pc_relative */
802 0, /* bitpos */
803 complain_overflow_signed, /* complain_on_overflow */
804 bfd_elf_generic_reloc, /* special_function */
805 "R_SCORE_CALL15", /* name */
806 TRUE, /* partial_inplace */
807 0x00007fff, /* src_mask */
808 0x00007fff, /* dst_mask */
809 FALSE), /* pcrel_offset */
811 /* 32 bit GP relative reference. */
812 HOWTO (R_SCORE_GPREL32, /* type */
813 0, /* rightshift */
814 2, /* size (0 = byte, 1 = short, 2 = long) */
815 32, /* bitsize */
816 FALSE, /* pc_relative */
817 0, /* bitpos */
818 complain_overflow_dont,/* complain_on_overflow */
819 score_elf_gprel32_reloc, /* special_function */
820 "R_SCORE_GPREL32", /* name */
821 TRUE, /* partial_inplace */
822 0xffffffff, /* src_mask */
823 0xffffffff, /* dst_mask */
824 FALSE), /* pcrel_offset */
826 /* 32 bit symbol relative relocation. */
827 HOWTO (R_SCORE_REL32, /* type */
828 0, /* rightshift */
829 2, /* size (0 = byte, 1 = short, 2 = long) */
830 32, /* bitsize */
831 FALSE, /* pc_relative */
832 0, /* bitpos */
833 complain_overflow_dont,/* complain_on_overflow */
834 bfd_elf_generic_reloc, /* special_function */
835 "R_SCORE_REL32", /* name */
836 TRUE, /* partial_inplace */
837 0xffffffff, /* src_mask */
838 0xffffffff, /* dst_mask */
839 FALSE), /* pcrel_offset */
841 /* R_SCORE_DUMMY_HI16 */
842 HOWTO (R_SCORE_DUMMY_HI16, /* type */
843 0, /* rightshift */
844 2, /* size (0 = byte, 1 = short, 2 = long) */
845 16, /* bitsize */
846 FALSE, /* pc_relative */
847 1, /* bitpos */
848 complain_overflow_dont,/* complain_on_overflow */
849 score_elf_hi16_reloc, /* special_function */
850 "R_SCORE_DUMMY_HI16", /* name */
851 TRUE, /* partial_inplace */
852 0x37fff, /* src_mask */
853 0x37fff, /* dst_mask */
854 FALSE), /* pcrel_offset */
857 struct score_reloc_map
859 bfd_reloc_code_real_type bfd_reloc_val;
860 unsigned char elf_reloc_val;
863 static const struct score_reloc_map elf32_score_reloc_map[] =
865 {BFD_RELOC_NONE, R_SCORE_NONE},
866 {BFD_RELOC_HI16_S, R_SCORE_HI16},
867 {BFD_RELOC_LO16, R_SCORE_LO16},
868 {BFD_RELOC_SCORE_BCMP, R_SCORE_BCMP},
869 {BFD_RELOC_SCORE_JMP, R_SCORE_24},
870 {BFD_RELOC_SCORE_BRANCH, R_SCORE_PC19},
871 {BFD_RELOC_SCORE16_JMP, R_SCORE16_11},
872 {BFD_RELOC_SCORE16_BRANCH, R_SCORE16_PC8},
873 {BFD_RELOC_32, R_SCORE_ABS32},
874 {BFD_RELOC_16, R_SCORE_ABS16},
875 {BFD_RELOC_SCORE_DUMMY2, R_SCORE_DUMMY2},
876 {BFD_RELOC_SCORE_GPREL15, R_SCORE_GP15},
877 {BFD_RELOC_VTABLE_INHERIT, R_SCORE_GNU_VTINHERIT},
878 {BFD_RELOC_VTABLE_ENTRY, R_SCORE_GNU_VTENTRY},
879 {BFD_RELOC_SCORE_GOT15, R_SCORE_GOT15},
880 {BFD_RELOC_SCORE_GOT_LO16, R_SCORE_GOT_LO16},
881 {BFD_RELOC_SCORE_CALL15, R_SCORE_CALL15},
882 {BFD_RELOC_GPREL32, R_SCORE_GPREL32},
883 {BFD_RELOC_32_PCREL, R_SCORE_REL32},
884 {BFD_RELOC_SCORE_DUMMY_HI16, R_SCORE_DUMMY_HI16},
887 static INLINE hashval_t
888 score_elf_hash_bfd_vma (bfd_vma addr)
890 #ifdef BFD64
891 return addr + (addr >> 32);
892 #else
893 return addr;
894 #endif
897 /* got_entries only match if they're identical, except for gotidx, so
898 use all fields to compute the hash, and compare the appropriate
899 union members. */
901 static hashval_t
902 score_elf_got_entry_hash (const void *entry_)
904 const struct score_got_entry *entry = (struct score_got_entry *) entry_;
906 return entry->symndx
907 + (! entry->abfd ? score_elf_hash_bfd_vma (entry->d.address)
908 : entry->abfd->id
909 + (entry->symndx >= 0 ? score_elf_hash_bfd_vma (entry->d.addend)
910 : entry->d.h->root.root.root.hash));
913 static int
914 score_elf_got_entry_eq (const void *entry1, const void *entry2)
916 const struct score_got_entry *e1 = (struct score_got_entry *) entry1;
917 const struct score_got_entry *e2 = (struct score_got_entry *) entry2;
919 return e1->abfd == e2->abfd && e1->symndx == e2->symndx
920 && (! e1->abfd ? e1->d.address == e2->d.address
921 : e1->symndx >= 0 ? e1->d.addend == e2->d.addend
922 : e1->d.h == e2->d.h);
925 /* If H needs a GOT entry, assign it the highest available dynamic
926 index. Otherwise, assign it the lowest available dynamic
927 index. */
929 static bfd_boolean
930 score_elf_sort_hash_table_f (struct score_elf_link_hash_entry *h, void *data)
932 struct score_elf_hash_sort_data *hsd = data;
934 if (h->root.root.type == bfd_link_hash_warning)
935 h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
937 /* Symbols without dynamic symbol table entries aren't interesting at all. */
938 if (h->root.dynindx == -1)
939 return TRUE;
941 /* Global symbols that need GOT entries that are not explicitly
942 referenced are marked with got offset 2. Those that are
943 referenced get a 1, and those that don't need GOT entries get
944 -1. */
945 if (h->root.got.offset == 2)
947 if (hsd->max_unref_got_dynindx == hsd->min_got_dynindx)
948 hsd->low = (struct elf_link_hash_entry *) h;
949 h->root.dynindx = hsd->max_unref_got_dynindx++;
951 else if (h->root.got.offset != 1)
952 h->root.dynindx = hsd->max_non_got_dynindx++;
953 else
955 h->root.dynindx = --hsd->min_got_dynindx;
956 hsd->low = (struct elf_link_hash_entry *) h;
959 return TRUE;
962 static asection *
963 score_elf_got_section (bfd *abfd, bfd_boolean maybe_excluded)
965 asection *sgot = bfd_get_section_by_name (abfd, ".got");
967 if (sgot == NULL || (! maybe_excluded && (sgot->flags & SEC_EXCLUDE) != 0))
968 return NULL;
969 return sgot;
972 /* Returns the GOT information associated with the link indicated by
973 INFO. If SGOTP is non-NULL, it is filled in with the GOT section. */
975 static struct score_got_info *
976 score_elf_got_info (bfd *abfd, asection **sgotp)
978 asection *sgot;
979 struct score_got_info *g;
981 sgot = score_elf_got_section (abfd, TRUE);
982 BFD_ASSERT (sgot != NULL);
983 BFD_ASSERT (elf_section_data (sgot) != NULL);
984 g = score_elf_section_data (sgot)->u.got_info;
985 BFD_ASSERT (g != NULL);
987 if (sgotp)
988 *sgotp = sgot;
989 return g;
992 /* Sort the dynamic symbol table so that symbols that need GOT entries
993 appear towards the end. This reduces the amount of GOT space
994 required. MAX_LOCAL is used to set the number of local symbols
995 known to be in the dynamic symbol table. During
996 s7_bfd_score_elf_size_dynamic_sections, this value is 1. Afterward, the
997 section symbols are added and the count is higher. */
999 static bfd_boolean
1000 score_elf_sort_hash_table (struct bfd_link_info *info,
1001 unsigned long max_local)
1003 struct score_elf_hash_sort_data hsd;
1004 struct score_got_info *g;
1005 bfd *dynobj;
1007 dynobj = elf_hash_table (info)->dynobj;
1009 g = score_elf_got_info (dynobj, NULL);
1011 hsd.low = NULL;
1012 hsd.max_unref_got_dynindx =
1013 hsd.min_got_dynindx = elf_hash_table (info)->dynsymcount
1014 /* In the multi-got case, assigned_gotno of the master got_info
1015 indicate the number of entries that aren't referenced in the
1016 primary GOT, but that must have entries because there are
1017 dynamic relocations that reference it. Since they aren't
1018 referenced, we move them to the end of the GOT, so that they
1019 don't prevent other entries that are referenced from getting
1020 too large offsets. */
1021 - (g->next ? g->assigned_gotno : 0);
1022 hsd.max_non_got_dynindx = max_local;
1023 score_elf_link_hash_traverse (((struct score_elf_link_hash_table *)
1024 elf_hash_table (info)),
1025 score_elf_sort_hash_table_f,
1026 &hsd);
1028 /* There should have been enough room in the symbol table to
1029 accommodate both the GOT and non-GOT symbols. */
1030 BFD_ASSERT (hsd.max_non_got_dynindx <= hsd.min_got_dynindx);
1031 BFD_ASSERT ((unsigned long) hsd.max_unref_got_dynindx
1032 <= elf_hash_table (info)->dynsymcount);
1034 /* Now we know which dynamic symbol has the lowest dynamic symbol
1035 table index in the GOT. */
1036 g->global_gotsym = hsd.low;
1038 return TRUE;
1041 /* Create an entry in an score ELF linker hash table. */
1043 static struct bfd_hash_entry *
1044 score_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
1045 struct bfd_hash_table *table,
1046 const char *string)
1048 struct score_elf_link_hash_entry *ret = (struct score_elf_link_hash_entry *) entry;
1050 /* Allocate the structure if it has not already been allocated by a subclass. */
1051 if (ret == NULL)
1052 ret = bfd_hash_allocate (table, sizeof (struct score_elf_link_hash_entry));
1053 if (ret == NULL)
1054 return (struct bfd_hash_entry *) ret;
1056 /* Call the allocation method of the superclass. */
1057 ret = ((struct score_elf_link_hash_entry *)
1058 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
1060 if (ret != NULL)
1062 ret->possibly_dynamic_relocs = 0;
1063 ret->readonly_reloc = FALSE;
1064 ret->no_fn_stub = FALSE;
1065 ret->forced_local = FALSE;
1068 return (struct bfd_hash_entry *) ret;
1071 /* Returns the first relocation of type r_type found, beginning with
1072 RELOCATION. RELEND is one-past-the-end of the relocation table. */
1074 static const Elf_Internal_Rela *
1075 score_elf_next_relocation (bfd *abfd ATTRIBUTE_UNUSED, unsigned int r_type,
1076 const Elf_Internal_Rela *relocation,
1077 const Elf_Internal_Rela *relend)
1079 while (relocation < relend)
1081 if (ELF32_R_TYPE (relocation->r_info) == r_type)
1082 return relocation;
1084 ++relocation;
1087 /* We didn't find it. */
1088 bfd_set_error (bfd_error_bad_value);
1089 return NULL;
1092 /* This function is called via qsort() to sort the dynamic relocation
1093 entries by increasing r_symndx value. */
1094 static int
1095 score_elf_sort_dynamic_relocs (const void *arg1, const void *arg2)
1097 Elf_Internal_Rela int_reloc1;
1098 Elf_Internal_Rela int_reloc2;
1100 bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg1, &int_reloc1);
1101 bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg2, &int_reloc2);
1103 return (ELF32_R_SYM (int_reloc1.r_info) - ELF32_R_SYM (int_reloc2.r_info));
1106 /* Return whether a relocation is against a local symbol. */
1107 static bfd_boolean
1108 score_elf_local_relocation_p (bfd *input_bfd,
1109 const Elf_Internal_Rela *relocation,
1110 asection **local_sections,
1111 bfd_boolean check_forced)
1113 unsigned long r_symndx;
1114 Elf_Internal_Shdr *symtab_hdr;
1115 struct score_elf_link_hash_entry *h;
1116 size_t extsymoff;
1118 r_symndx = ELF32_R_SYM (relocation->r_info);
1119 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1120 extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
1122 if (r_symndx < extsymoff)
1123 return TRUE;
1124 if (elf_bad_symtab (input_bfd) && local_sections[r_symndx] != NULL)
1125 return TRUE;
1127 if (check_forced)
1129 /* Look up the hash table to check whether the symbol was forced local. */
1130 h = (struct score_elf_link_hash_entry *)
1131 elf_sym_hashes (input_bfd) [r_symndx - extsymoff];
1132 /* Find the real hash-table entry for this symbol. */
1133 while (h->root.root.type == bfd_link_hash_indirect
1134 || h->root.root.type == bfd_link_hash_warning)
1135 h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
1136 if (h->root.forced_local)
1137 return TRUE;
1140 return FALSE;
1143 /* Returns the dynamic relocation section for DYNOBJ. */
1145 static asection *
1146 score_elf_rel_dyn_section (bfd *dynobj, bfd_boolean create_p)
1148 static const char dname[] = ".rel.dyn";
1149 asection *sreloc;
1151 sreloc = bfd_get_section_by_name (dynobj, dname);
1152 if (sreloc == NULL && create_p)
1154 sreloc = bfd_make_section_with_flags (dynobj, dname,
1155 (SEC_ALLOC
1156 | SEC_LOAD
1157 | SEC_HAS_CONTENTS
1158 | SEC_IN_MEMORY
1159 | SEC_LINKER_CREATED
1160 | SEC_READONLY));
1161 if (sreloc == NULL
1162 || ! bfd_set_section_alignment (dynobj, sreloc,
1163 SCORE_ELF_LOG_FILE_ALIGN (dynobj)))
1164 return NULL;
1166 return sreloc;
1169 static void
1170 score_elf_allocate_dynamic_relocations (bfd *abfd, unsigned int n)
1172 asection *s;
1174 s = score_elf_rel_dyn_section (abfd, FALSE);
1175 BFD_ASSERT (s != NULL);
1177 if (s->size == 0)
1179 /* Make room for a null element. */
1180 s->size += SCORE_ELF_REL_SIZE (abfd);
1181 ++s->reloc_count;
1183 s->size += n * SCORE_ELF_REL_SIZE (abfd);
1186 /* Create a rel.dyn relocation for the dynamic linker to resolve. REL
1187 is the original relocation, which is now being transformed into a
1188 dynamic relocation. The ADDENDP is adjusted if necessary; the
1189 caller should store the result in place of the original addend. */
1191 static bfd_boolean
1192 score_elf_create_dynamic_relocation (bfd *output_bfd,
1193 struct bfd_link_info *info,
1194 const Elf_Internal_Rela *rel,
1195 struct score_elf_link_hash_entry *h,
1196 bfd_vma symbol,
1197 bfd_vma *addendp, asection *input_section)
1199 Elf_Internal_Rela outrel[3];
1200 asection *sreloc;
1201 bfd *dynobj;
1202 int r_type;
1203 long indx;
1204 bfd_boolean defined_p;
1206 r_type = ELF32_R_TYPE (rel->r_info);
1207 dynobj = elf_hash_table (info)->dynobj;
1208 sreloc = score_elf_rel_dyn_section (dynobj, FALSE);
1209 BFD_ASSERT (sreloc != NULL);
1210 BFD_ASSERT (sreloc->contents != NULL);
1211 BFD_ASSERT (sreloc->reloc_count * SCORE_ELF_REL_SIZE (output_bfd) < sreloc->size);
1213 outrel[0].r_offset =
1214 _bfd_elf_section_offset (output_bfd, info, input_section, rel[0].r_offset);
1215 outrel[1].r_offset =
1216 _bfd_elf_section_offset (output_bfd, info, input_section, rel[1].r_offset);
1217 outrel[2].r_offset =
1218 _bfd_elf_section_offset (output_bfd, info, input_section, rel[2].r_offset);
1220 if (outrel[0].r_offset == MINUS_ONE)
1221 /* The relocation field has been deleted. */
1222 return TRUE;
1224 if (outrel[0].r_offset == MINUS_TWO)
1226 /* The relocation field has been converted into a relative value of
1227 some sort. Functions like _bfd_elf_write_section_eh_frame expect
1228 the field to be fully relocated, so add in the symbol's value. */
1229 *addendp += symbol;
1230 return TRUE;
1233 /* We must now calculate the dynamic symbol table index to use
1234 in the relocation. */
1235 if (h != NULL
1236 && (! info->symbolic || !h->root.def_regular)
1237 /* h->root.dynindx may be -1 if this symbol was marked to
1238 become local. */
1239 && h->root.dynindx != -1)
1241 indx = h->root.dynindx;
1242 /* ??? glibc's ld.so just adds the final GOT entry to the
1243 relocation field. It therefore treats relocs against
1244 defined symbols in the same way as relocs against
1245 undefined symbols. */
1246 defined_p = FALSE;
1248 else
1250 indx = 0;
1251 defined_p = TRUE;
1254 /* If the relocation was previously an absolute relocation and
1255 this symbol will not be referred to by the relocation, we must
1256 adjust it by the value we give it in the dynamic symbol table.
1257 Otherwise leave the job up to the dynamic linker. */
1258 if (defined_p && r_type != R_SCORE_REL32)
1259 *addendp += symbol;
1261 /* The relocation is always an REL32 relocation because we don't
1262 know where the shared library will wind up at load-time. */
1263 outrel[0].r_info = ELF32_R_INFO ((unsigned long) indx, R_SCORE_REL32);
1265 /* For strict adherence to the ABI specification, we should
1266 generate a R_SCORE_64 relocation record by itself before the
1267 _REL32/_64 record as well, such that the addend is read in as
1268 a 64-bit value (REL32 is a 32-bit relocation, after all).
1269 However, since none of the existing ELF64 SCORE dynamic
1270 loaders seems to care, we don't waste space with these
1271 artificial relocations. If this turns out to not be true,
1272 score_elf_allocate_dynamic_relocations() should be tweaked so
1273 as to make room for a pair of dynamic relocations per
1274 invocation if ABI_64_P, and here we should generate an
1275 additional relocation record with R_SCORE_64 by itself for a
1276 NULL symbol before this relocation record. */
1277 outrel[1].r_info = ELF32_R_INFO (0, R_SCORE_NONE);
1278 outrel[2].r_info = ELF32_R_INFO (0, R_SCORE_NONE);
1280 /* Adjust the output offset of the relocation to reference the
1281 correct location in the output file. */
1282 outrel[0].r_offset += (input_section->output_section->vma
1283 + input_section->output_offset);
1284 outrel[1].r_offset += (input_section->output_section->vma
1285 + input_section->output_offset);
1286 outrel[2].r_offset += (input_section->output_section->vma
1287 + input_section->output_offset);
1289 /* Put the relocation back out. We have to use the special
1290 relocation outputter in the 64-bit case since the 64-bit
1291 relocation format is non-standard. */
1292 bfd_elf32_swap_reloc_out
1293 (output_bfd, &outrel[0],
1294 (sreloc->contents + sreloc->reloc_count * sizeof (Elf32_External_Rel)));
1296 /* We've now added another relocation. */
1297 ++sreloc->reloc_count;
1299 /* Make sure the output section is writable. The dynamic linker
1300 will be writing to it. */
1301 elf_section_data (input_section->output_section)->this_hdr.sh_flags |= SHF_WRITE;
1303 return TRUE;
1306 static bfd_boolean
1307 score_elf_create_got_section (bfd *abfd,
1308 struct bfd_link_info *info,
1309 bfd_boolean maybe_exclude)
1311 flagword flags;
1312 asection *s;
1313 struct elf_link_hash_entry *h;
1314 struct bfd_link_hash_entry *bh;
1315 struct score_got_info *g;
1316 bfd_size_type amt;
1318 /* This function may be called more than once. */
1319 s = score_elf_got_section (abfd, TRUE);
1320 if (s)
1322 if (! maybe_exclude)
1323 s->flags &= ~SEC_EXCLUDE;
1324 return TRUE;
1327 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
1329 if (maybe_exclude)
1330 flags |= SEC_EXCLUDE;
1332 /* We have to use an alignment of 2**4 here because this is hardcoded
1333 in the function stub generation and in the linker script. */
1334 s = bfd_make_section_with_flags (abfd, ".got", flags);
1335 if (s == NULL
1336 || ! bfd_set_section_alignment (abfd, s, 4))
1337 return FALSE;
1339 /* Define the symbol _GLOBAL_OFFSET_TABLE_. We don't do this in the
1340 linker script because we don't want to define the symbol if we
1341 are not creating a global offset table. */
1342 bh = NULL;
1343 if (! (_bfd_generic_link_add_one_symbol
1344 (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s,
1345 0, NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
1346 return FALSE;
1348 h = (struct elf_link_hash_entry *) bh;
1349 h->non_elf = 0;
1350 h->def_regular = 1;
1351 h->type = STT_OBJECT;
1353 if (info->shared && ! bfd_elf_link_record_dynamic_symbol (info, h))
1354 return FALSE;
1356 amt = sizeof (struct score_got_info);
1357 g = bfd_alloc (abfd, amt);
1358 if (g == NULL)
1359 return FALSE;
1361 g->global_gotsym = NULL;
1362 g->global_gotno = 0;
1364 g->local_gotno = SCORE_RESERVED_GOTNO;
1365 g->assigned_gotno = SCORE_RESERVED_GOTNO;
1366 g->next = NULL;
1368 g->got_entries = htab_try_create (1, score_elf_got_entry_hash,
1369 score_elf_got_entry_eq, NULL);
1370 if (g->got_entries == NULL)
1371 return FALSE;
1372 score_elf_section_data (s)->u.got_info = g;
1373 score_elf_section_data (s)->elf.this_hdr.sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
1375 return TRUE;
1378 /* Calculate the %high function. */
1380 static bfd_vma
1381 score_elf_high (bfd_vma value)
1383 return ((value + (bfd_vma) 0x8000) >> 16) & 0xffff;
1386 /* Create a local GOT entry for VALUE. Return the index of the entry,
1387 or -1 if it could not be created. */
1389 static struct score_got_entry *
1390 score_elf_create_local_got_entry (bfd *abfd,
1391 bfd *ibfd ATTRIBUTE_UNUSED,
1392 struct score_got_info *gg,
1393 asection *sgot, bfd_vma value,
1394 unsigned long r_symndx ATTRIBUTE_UNUSED,
1395 struct score_elf_link_hash_entry *h ATTRIBUTE_UNUSED,
1396 int r_type ATTRIBUTE_UNUSED)
1398 struct score_got_entry entry, **loc;
1399 struct score_got_info *g;
1401 entry.abfd = NULL;
1402 entry.symndx = -1;
1403 entry.d.address = value;
1405 g = gg;
1406 loc = (struct score_got_entry **) htab_find_slot (g->got_entries, &entry, INSERT);
1407 if (*loc)
1408 return *loc;
1410 entry.gotidx = SCORE_ELF_GOT_SIZE (abfd) * g->assigned_gotno++;
1412 *loc = bfd_alloc (abfd, sizeof entry);
1414 if (! *loc)
1415 return NULL;
1417 memcpy (*loc, &entry, sizeof entry);
1419 if (g->assigned_gotno >= g->local_gotno)
1421 (*loc)->gotidx = -1;
1422 /* We didn't allocate enough space in the GOT. */
1423 (*_bfd_error_handler)
1424 (_("not enough GOT space for local GOT entries"));
1425 bfd_set_error (bfd_error_bad_value);
1426 return NULL;
1429 bfd_put_32 (abfd, value, (sgot->contents + entry.gotidx));
1431 return *loc;
1434 /* Find a GOT entry whose higher-order 16 bits are the same as those
1435 for value. Return the index into the GOT for this entry. */
1437 static bfd_vma
1438 score_elf_got16_entry (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
1439 bfd_vma value, bfd_boolean external)
1441 asection *sgot;
1442 struct score_got_info *g;
1443 struct score_got_entry *entry;
1445 if (!external)
1447 /* Although the ABI says that it is "the high-order 16 bits" that we
1448 want, it is really the %high value. The complete value is
1449 calculated with a `addiu' of a LO16 relocation, just as with a
1450 HI16/LO16 pair. */
1451 value = score_elf_high (value) << 16;
1454 g = score_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
1456 entry = score_elf_create_local_got_entry (abfd, ibfd, g, sgot, value, 0, NULL,
1457 R_SCORE_GOT15);
1458 if (entry)
1459 return entry->gotidx;
1460 else
1461 return MINUS_ONE;
1464 void
1465 s7_bfd_score_elf_hide_symbol (struct bfd_link_info *info,
1466 struct elf_link_hash_entry *entry,
1467 bfd_boolean force_local)
1469 bfd *dynobj;
1470 asection *got;
1471 struct score_got_info *g;
1472 struct score_elf_link_hash_entry *h;
1474 h = (struct score_elf_link_hash_entry *) entry;
1475 if (h->forced_local)
1476 return;
1477 h->forced_local = TRUE;
1479 dynobj = elf_hash_table (info)->dynobj;
1480 if (dynobj != NULL && force_local)
1482 got = score_elf_got_section (dynobj, FALSE);
1483 if (got == NULL)
1484 return;
1485 g = score_elf_section_data (got)->u.got_info;
1487 if (g->next)
1489 struct score_got_entry e;
1490 struct score_got_info *gg = g;
1492 /* Since we're turning what used to be a global symbol into a
1493 local one, bump up the number of local entries of each GOT
1494 that had an entry for it. This will automatically decrease
1495 the number of global entries, since global_gotno is actually
1496 the upper limit of global entries. */
1497 e.abfd = dynobj;
1498 e.symndx = -1;
1499 e.d.h = h;
1501 for (g = g->next; g != gg; g = g->next)
1502 if (htab_find (g->got_entries, &e))
1504 BFD_ASSERT (g->global_gotno > 0);
1505 g->local_gotno++;
1506 g->global_gotno--;
1509 /* If this was a global symbol forced into the primary GOT, we
1510 no longer need an entry for it. We can't release the entry
1511 at this point, but we must at least stop counting it as one
1512 of the symbols that required a forced got entry. */
1513 if (h->root.got.offset == 2)
1515 BFD_ASSERT (gg->assigned_gotno > 0);
1516 gg->assigned_gotno--;
1519 else if (g->global_gotno == 0 && g->global_gotsym == NULL)
1520 /* If we haven't got through GOT allocation yet, just bump up the
1521 number of local entries, as this symbol won't be counted as
1522 global. */
1523 g->local_gotno++;
1524 else if (h->root.got.offset == 1)
1526 /* If we're past non-multi-GOT allocation and this symbol had
1527 been marked for a global got entry, give it a local entry
1528 instead. */
1529 BFD_ASSERT (g->global_gotno > 0);
1530 g->local_gotno++;
1531 g->global_gotno--;
1535 _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
1538 /* If H is a symbol that needs a global GOT entry, but has a dynamic
1539 symbol table index lower than any we've seen to date, record it for
1540 posterity. */
1542 static bfd_boolean
1543 score_elf_record_global_got_symbol (struct elf_link_hash_entry *h,
1544 bfd *abfd,
1545 struct bfd_link_info *info,
1546 struct score_got_info *g)
1548 struct score_got_entry entry, **loc;
1550 /* A global symbol in the GOT must also be in the dynamic symbol table. */
1551 if (h->dynindx == -1)
1553 switch (ELF_ST_VISIBILITY (h->other))
1555 case STV_INTERNAL:
1556 case STV_HIDDEN:
1557 s7_bfd_score_elf_hide_symbol (info, h, TRUE);
1558 break;
1560 if (!bfd_elf_link_record_dynamic_symbol (info, h))
1561 return FALSE;
1564 entry.abfd = abfd;
1565 entry.symndx = -1;
1566 entry.d.h = (struct score_elf_link_hash_entry *) h;
1568 loc = (struct score_got_entry **) htab_find_slot (g->got_entries, &entry, INSERT);
1570 /* If we've already marked this entry as needing GOT space, we don't
1571 need to do it again. */
1572 if (*loc)
1573 return TRUE;
1575 *loc = bfd_alloc (abfd, sizeof entry);
1576 if (! *loc)
1577 return FALSE;
1579 entry.gotidx = -1;
1581 memcpy (*loc, &entry, sizeof (entry));
1583 if (h->got.offset != MINUS_ONE)
1584 return TRUE;
1586 /* By setting this to a value other than -1, we are indicating that
1587 there needs to be a GOT entry for H. Avoid using zero, as the
1588 generic ELF copy_indirect_symbol tests for <= 0. */
1589 h->got.offset = 1;
1591 return TRUE;
1594 /* Reserve space in G for a GOT entry containing the value of symbol
1595 SYMNDX in input bfd ABDF, plus ADDEND. */
1597 static bfd_boolean
1598 score_elf_record_local_got_symbol (bfd *abfd,
1599 long symndx,
1600 bfd_vma addend,
1601 struct score_got_info *g)
1603 struct score_got_entry entry, **loc;
1605 entry.abfd = abfd;
1606 entry.symndx = symndx;
1607 entry.d.addend = addend;
1608 loc = (struct score_got_entry **) htab_find_slot (g->got_entries, &entry, INSERT);
1610 if (*loc)
1611 return TRUE;
1613 entry.gotidx = g->local_gotno++;
1615 *loc = bfd_alloc (abfd, sizeof(entry));
1616 if (! *loc)
1617 return FALSE;
1619 memcpy (*loc, &entry, sizeof (entry));
1621 return TRUE;
1624 /* Returns the GOT offset at which the indicated address can be found.
1625 If there is not yet a GOT entry for this value, create one.
1626 Returns -1 if no satisfactory GOT offset can be found. */
1628 static bfd_vma
1629 score_elf_local_got_index (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
1630 bfd_vma value, unsigned long r_symndx,
1631 struct score_elf_link_hash_entry *h, int r_type)
1633 asection *sgot;
1634 struct score_got_info *g;
1635 struct score_got_entry *entry;
1637 g = score_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
1639 entry = score_elf_create_local_got_entry (abfd, ibfd, g, sgot, value,
1640 r_symndx, h, r_type);
1641 if (!entry)
1642 return MINUS_ONE;
1644 else
1645 return entry->gotidx;
1648 /* Returns the GOT index for the global symbol indicated by H. */
1650 static bfd_vma
1651 score_elf_global_got_index (bfd *abfd, struct elf_link_hash_entry *h)
1653 bfd_vma got_index;
1654 asection *sgot;
1655 struct score_got_info *g;
1656 long global_got_dynindx = 0;
1658 g = score_elf_got_info (abfd, &sgot);
1659 if (g->global_gotsym != NULL)
1660 global_got_dynindx = g->global_gotsym->dynindx;
1662 /* Once we determine the global GOT entry with the lowest dynamic
1663 symbol table index, we must put all dynamic symbols with greater
1664 indices into the GOT. That makes it easy to calculate the GOT
1665 offset. */
1666 BFD_ASSERT (h->dynindx >= global_got_dynindx);
1667 got_index = ((h->dynindx - global_got_dynindx + g->local_gotno) * SCORE_ELF_GOT_SIZE (abfd));
1668 BFD_ASSERT (got_index < sgot->size);
1670 return got_index;
1673 /* Returns the offset for the entry at the INDEXth position in the GOT. */
1675 static bfd_vma
1676 score_elf_got_offset_from_index (bfd *dynobj,
1677 bfd *output_bfd,
1678 bfd *input_bfd ATTRIBUTE_UNUSED,
1679 bfd_vma got_index)
1681 asection *sgot;
1682 bfd_vma gp;
1683 struct score_got_info *g;
1685 g = score_elf_got_info (dynobj, &sgot);
1686 gp = _bfd_get_gp_value (output_bfd);
1688 return sgot->output_section->vma + sgot->output_offset + got_index - gp;
1691 /* Follow indirect and warning hash entries so that each got entry
1692 points to the final symbol definition. P must point to a pointer
1693 to the hash table we're traversing. Since this traversal may
1694 modify the hash table, we set this pointer to NULL to indicate
1695 we've made a potentially-destructive change to the hash table, so
1696 the traversal must be restarted. */
1698 static int
1699 score_elf_resolve_final_got_entry (void **entryp, void *p)
1701 struct score_got_entry *entry = (struct score_got_entry *) *entryp;
1702 htab_t got_entries = *(htab_t *) p;
1704 if (entry->abfd != NULL && entry->symndx == -1)
1706 struct score_elf_link_hash_entry *h = entry->d.h;
1708 while (h->root.root.type == bfd_link_hash_indirect
1709 || h->root.root.type == bfd_link_hash_warning)
1710 h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
1712 if (entry->d.h == h)
1713 return 1;
1715 entry->d.h = h;
1717 /* If we can't find this entry with the new bfd hash, re-insert
1718 it, and get the traversal restarted. */
1719 if (! htab_find (got_entries, entry))
1721 htab_clear_slot (got_entries, entryp);
1722 entryp = htab_find_slot (got_entries, entry, INSERT);
1723 if (! *entryp)
1724 *entryp = entry;
1725 /* Abort the traversal, since the whole table may have
1726 moved, and leave it up to the parent to restart the
1727 process. */
1728 *(htab_t *) p = NULL;
1729 return 0;
1731 /* We might want to decrement the global_gotno count, but it's
1732 either too early or too late for that at this point. */
1735 return 1;
1738 /* Turn indirect got entries in a got_entries table into their final locations. */
1740 static void
1741 score_elf_resolve_final_got_entries (struct score_got_info *g)
1743 htab_t got_entries;
1747 got_entries = g->got_entries;
1749 htab_traverse (got_entries,
1750 score_elf_resolve_final_got_entry,
1751 &got_entries);
1753 while (got_entries == NULL);
1756 /* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS. for -r */
1758 static void
1759 score_elf_add_to_rel (bfd *abfd,
1760 bfd_byte *address,
1761 reloc_howto_type *howto,
1762 bfd_signed_vma increment)
1764 bfd_signed_vma addend;
1765 bfd_vma contents;
1766 unsigned long offset;
1767 unsigned long r_type = howto->type;
1768 unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
1770 contents = bfd_get_32 (abfd, address);
1771 /* Get the (signed) value from the instruction. */
1772 addend = contents & howto->src_mask;
1773 if (addend & ((howto->src_mask + 1) >> 1))
1775 bfd_signed_vma mask;
1777 mask = -1;
1778 mask &= ~howto->src_mask;
1779 addend |= mask;
1781 /* Add in the increment, (which is a byte value). */
1782 switch (r_type)
1784 case R_SCORE_PC19:
1785 offset =
1786 (((contents & howto->src_mask) & 0x3ff0000) >> 6) | ((contents & howto->src_mask) & 0x3ff);
1787 offset += increment;
1788 contents =
1789 (contents & ~howto->
1790 src_mask) | (((offset << 6) & howto->src_mask) & 0x3ff0000) | (offset & 0x3ff);
1791 bfd_put_32 (abfd, contents, address);
1792 break;
1793 case R_SCORE_HI16:
1794 break;
1795 case R_SCORE_LO16:
1796 hi16_addend = bfd_get_32 (abfd, address - 4);
1797 hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
1798 offset = ((((contents >> 16) & 0x3) << 15) | (contents & 0x7fff)) >> 1;
1799 offset = (hi16_offset << 16) | (offset & 0xffff);
1800 uvalue = increment + offset;
1801 hi16_offset = (uvalue >> 16) << 1;
1802 hi16_value = (hi16_addend & (~(howto->dst_mask)))
1803 | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
1804 bfd_put_32 (abfd, hi16_value, address - 4);
1805 offset = (uvalue & 0xffff) << 1;
1806 contents = (contents & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
1807 bfd_put_32 (abfd, contents, address);
1808 break;
1809 case R_SCORE_24:
1810 offset =
1811 (((contents & howto->src_mask) >> 1) & 0x1ff8000) | ((contents & howto->src_mask) & 0x7fff);
1812 offset += increment;
1813 contents =
1814 (contents & ~howto->
1815 src_mask) | (((offset << 1) & howto->src_mask) & 0x3ff0000) | (offset & 0x7fff);
1816 bfd_put_32 (abfd, contents, address);
1817 break;
1818 case R_SCORE16_11:
1820 contents = bfd_get_16 (abfd, address);
1821 offset = contents & howto->src_mask;
1822 offset += increment;
1823 contents = (contents & ~howto->src_mask) | (offset & howto->src_mask);
1824 bfd_put_16 (abfd, contents, address);
1826 break;
1827 case R_SCORE16_PC8:
1829 contents = bfd_get_16 (abfd, address);
1830 offset = (contents & howto->src_mask) + ((increment >> 1) & 0xff);
1831 contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask);
1832 bfd_put_16 (abfd, contents, address);
1834 break;
1835 case R_SCORE_GOT15:
1836 case R_SCORE_GOT_LO16:
1837 break;
1839 default:
1840 addend += increment;
1841 contents = (contents & ~howto->dst_mask) | (addend & howto->dst_mask);
1842 bfd_put_32 (abfd, contents, address);
1843 break;
1847 /* Perform a relocation as part of a final link. */
1849 static bfd_reloc_status_type
1850 score_elf_final_link_relocate (reloc_howto_type *howto,
1851 bfd *input_bfd,
1852 bfd *output_bfd,
1853 asection *input_section,
1854 bfd_byte *contents,
1855 Elf_Internal_Rela *rel,
1856 Elf_Internal_Rela *relocs,
1857 bfd_vma symbol,
1858 struct bfd_link_info *info,
1859 const char *sym_name ATTRIBUTE_UNUSED,
1860 int sym_flags ATTRIBUTE_UNUSED,
1861 struct score_elf_link_hash_entry *h,
1862 Elf_Internal_Sym *local_syms,
1863 asection **local_sections,
1864 bfd_boolean gp_disp_p)
1866 unsigned long r_type;
1867 unsigned long r_symndx;
1868 bfd_byte *hit_data = contents + rel->r_offset;
1869 bfd_vma addend;
1870 /* The final GP value to be used for the relocatable, executable, or
1871 shared object file being produced. */
1872 bfd_vma gp = MINUS_ONE;
1873 /* The place (section offset or address) of the storage unit being relocated. */
1874 bfd_vma rel_addr;
1875 /* The value of GP used to create the relocatable object. */
1876 bfd_vma gp0 = MINUS_ONE;
1877 /* The offset into the global offset table at which the address of the relocation entry
1878 symbol, adjusted by the addend, resides during execution. */
1879 bfd_vma g = MINUS_ONE;
1880 /* TRUE if the symbol referred to by this relocation is a local symbol. */
1881 bfd_boolean local_p;
1882 /* The eventual value we will relocate. */
1883 bfd_vma value = symbol;
1884 unsigned long hi16_addend, hi16_offset, hi16_value, uvalue, offset, abs_value = 0;
1886 Elf_Internal_Sym *sym = 0;
1887 asection *sec = NULL;
1888 bfd_boolean merge_p = 0;
1891 if (elf_gp (output_bfd) == 0)
1893 struct bfd_link_hash_entry *bh;
1894 asection *o;
1896 bh = bfd_link_hash_lookup (info->hash, "_gp", 0, 0, 1);
1897 if (bh != NULL && bh->type == bfd_link_hash_defined)
1898 elf_gp (output_bfd) = (bh->u.def.value
1899 + bh->u.def.section->output_section->vma
1900 + bh->u.def.section->output_offset);
1901 else if (info->relocatable)
1903 bfd_vma lo = -1;
1905 /* Find the GP-relative section with the lowest offset. */
1906 for (o = output_bfd->sections; o != NULL; o = o->next)
1907 if (o->vma < lo)
1908 lo = o->vma;
1909 /* And calculate GP relative to that. */
1910 elf_gp (output_bfd) = lo + ELF_SCORE_GP_OFFSET (input_bfd);
1912 else
1914 /* If the relocate_section function needs to do a reloc
1915 involving the GP value, it should make a reloc_dangerous
1916 callback to warn that GP is not defined. */
1920 /* Parse the relocation. */
1921 r_symndx = ELF32_R_SYM (rel->r_info);
1922 r_type = ELF32_R_TYPE (rel->r_info);
1923 rel_addr = (input_section->output_section->vma + input_section->output_offset + rel->r_offset);
1925 /* For hidden symbol. */
1926 local_p = score_elf_local_relocation_p (input_bfd, rel, local_sections, FALSE);
1927 if (local_p)
1929 sym = local_syms + r_symndx;
1930 sec = local_sections[r_symndx];
1932 symbol = sec->output_section->vma + sec->output_offset;
1933 if (ELF_ST_TYPE (sym->st_info) != STT_SECTION
1934 || (sec->flags & SEC_MERGE))
1935 symbol += sym->st_value;
1936 if ((sec->flags & SEC_MERGE)
1937 && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1938 merge_p = 1;
1941 if (r_type == R_SCORE_GOT15)
1943 const Elf_Internal_Rela *relend;
1944 const Elf_Internal_Rela *lo16_rel;
1945 const struct elf_backend_data *bed;
1946 bfd_vma lo_value = 0;
1948 bed = get_elf_backend_data (output_bfd);
1949 relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
1950 lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
1951 if ((local_p) && (lo16_rel != NULL))
1953 bfd_vma tmp = 0;
1954 tmp = bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
1955 lo_value = (((tmp >> 16) & 0x3) << 14) | ((tmp & 0x7fff) >> 1);
1956 if (merge_p)
1958 asection *msec = sec;
1959 lo_value = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, lo_value);
1960 lo_value -= symbol;
1961 lo_value += msec->output_section->vma + msec->output_offset;
1964 addend = lo_value;
1966 else
1968 addend = (bfd_get_32 (input_bfd, hit_data) >> howto->bitpos) & howto->src_mask;
1971 /* Figure out the value of the symbol. */
1972 if (local_p && !merge_p)
1974 if (r_type == R_SCORE_GOT15)
1976 const Elf_Internal_Rela *relend;
1977 const Elf_Internal_Rela *lo16_rel;
1978 const struct elf_backend_data *bed;
1979 bfd_vma lo_value = 0;
1981 value = bfd_get_32 (input_bfd, contents + rel->r_offset);
1982 addend = value & 0x7fff;
1983 if ((addend & 0x4000) == 0x4000)
1984 addend |= 0xffffc000;
1986 bed = get_elf_backend_data (output_bfd);
1987 relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
1988 lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
1989 if ((local_p) && (lo16_rel != NULL))
1991 bfd_vma tmp = 0;
1992 tmp = bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
1993 lo_value = (((tmp >> 16) & 0x3) << 14) | ((tmp & 0x7fff) >> 1);
1996 addend <<= 16;
1997 addend += lo_value;
2001 local_p = score_elf_local_relocation_p (input_bfd, rel, local_sections, TRUE);
2003 /* If we haven't already determined the GOT offset, or the GP value,
2004 and we're going to need it, get it now. */
2005 switch (r_type)
2007 case R_SCORE_CALL15:
2008 case R_SCORE_GOT15:
2009 if (!local_p)
2011 g = score_elf_global_got_index (elf_hash_table (info)->dynobj,
2012 (struct elf_link_hash_entry *) h);
2013 if ((! elf_hash_table(info)->dynamic_sections_created
2014 || (info->shared
2015 && (info->symbolic || h->root.dynindx == -1)
2016 && h->root.def_regular)))
2018 /* This is a static link or a -Bsymbolic link. The
2019 symbol is defined locally, or was forced to be local.
2020 We must initialize this entry in the GOT. */
2021 bfd *tmpbfd = elf_hash_table (info)->dynobj;
2022 asection *sgot = score_elf_got_section (tmpbfd, FALSE);
2023 bfd_put_32 (tmpbfd, value, sgot->contents + g);
2026 else if (r_type == R_SCORE_GOT15 || r_type == R_SCORE_CALL15)
2028 /* There's no need to create a local GOT entry here; the
2029 calculation for a local GOT15 entry does not involve G. */
2032 else
2034 g = score_elf_local_got_index (output_bfd, input_bfd, info,
2035 symbol + addend, r_symndx, h, r_type);
2036 if (g == MINUS_ONE)
2037 return bfd_reloc_outofrange;
2040 /* Convert GOT indices to actual offsets. */
2041 g = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
2042 output_bfd, input_bfd, g);
2043 break;
2045 case R_SCORE_HI16:
2046 case R_SCORE_LO16:
2047 case R_SCORE_GPREL32:
2048 gp0 = _bfd_get_gp_value (input_bfd);
2049 gp = _bfd_get_gp_value (output_bfd);
2050 break;
2052 case R_SCORE_GP15:
2053 gp = _bfd_get_gp_value (output_bfd);
2055 default:
2056 break;
2059 switch (r_type)
2061 case R_SCORE_NONE:
2062 return bfd_reloc_ok;
2064 case R_SCORE_ABS32:
2065 case R_SCORE_REL32:
2066 if ((info->shared
2067 || (elf_hash_table (info)->dynamic_sections_created
2068 && h != NULL
2069 && h->root.def_dynamic
2070 && !h->root.def_regular))
2071 && r_symndx != 0
2072 && (input_section->flags & SEC_ALLOC) != 0)
2074 /* If we're creating a shared library, or this relocation is against a symbol
2075 in a shared library, then we can't know where the symbol will end up.
2076 So, we create a relocation record in the output, and leave the job up
2077 to the dynamic linker. */
2078 value = addend;
2079 if (!score_elf_create_dynamic_relocation (output_bfd, info, rel, h,
2080 symbol, &value,
2081 input_section))
2082 return bfd_reloc_undefined;
2084 else if (r_symndx == 0)
2085 /* r_symndx will be zero only for relocs against symbols
2086 from removed linkonce sections, or sections discarded by
2087 a linker script. */
2088 value = 0;
2089 else
2091 if (r_type != R_SCORE_REL32)
2092 value = symbol + addend;
2093 else
2094 value = addend;
2096 value &= howto->dst_mask;
2097 bfd_put_32 (input_bfd, value, hit_data);
2098 return bfd_reloc_ok;
2100 case R_SCORE_ABS16:
2101 value += addend;
2102 if ((long) value > 0x7fff || (long) value < -0x8000)
2103 return bfd_reloc_overflow;
2104 bfd_put_16 (input_bfd, value, hit_data);
2105 return bfd_reloc_ok;
2107 case R_SCORE_24:
2108 addend = bfd_get_32 (input_bfd, hit_data);
2109 offset = (((addend & howto->src_mask) >> 1) & 0x1ff8000) | ((addend & howto->src_mask) & 0x7fff);
2110 if ((offset & 0x1000000) != 0)
2111 offset |= 0xfe000000;
2112 value += offset;
2113 abs_value = abs (value - rel_addr);
2114 if ((abs_value & 0xfe000000) != 0)
2115 return bfd_reloc_overflow;
2116 addend = (addend & ~howto->src_mask)
2117 | (((value << 1) & howto->src_mask) & 0x3ff0000) | (value & 0x7fff);
2118 bfd_put_32 (input_bfd, addend, hit_data);
2119 return bfd_reloc_ok;
2121 case R_SCORE_PC19:
2122 addend = bfd_get_32 (input_bfd, hit_data);
2123 offset = (((addend & howto->src_mask) & 0x3ff0000) >> 6) | ((addend & howto->src_mask) & 0x3ff);
2124 if ((offset & 0x80000) != 0)
2125 offset |= 0xfff00000;
2126 abs_value = value = value - rel_addr + offset;
2127 /* exceed 20 bit : overflow. */
2128 if ((abs_value & 0x80000000) == 0x80000000)
2129 abs_value = 0xffffffff - value + 1;
2130 if ((abs_value & 0xfff80000) != 0)
2131 return bfd_reloc_overflow;
2132 addend = (addend & ~howto->src_mask)
2133 | (((value << 6) & howto->src_mask) & 0x3ff0000) | (value & 0x3ff);
2134 bfd_put_32 (input_bfd, addend, hit_data);
2135 return bfd_reloc_ok;
2137 case R_SCORE16_11:
2138 addend = bfd_get_16 (input_bfd, hit_data);
2139 offset = addend & howto->src_mask;
2140 if ((offset & 0x800) != 0) /* Offset is negative. */
2141 offset |= 0xfffff000;
2142 value += offset;
2143 abs_value = abs (value - rel_addr);
2144 if ((abs_value & 0xfffff000) != 0)
2145 return bfd_reloc_overflow;
2146 addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
2147 bfd_put_16 (input_bfd, addend, hit_data);
2148 return bfd_reloc_ok;
2150 case R_SCORE16_PC8:
2151 addend = bfd_get_16 (input_bfd, hit_data);
2152 offset = (addend & howto->src_mask) << 1;
2153 if ((offset & 0x100) != 0) /* Offset is negative. */
2154 offset |= 0xfffffe00;
2155 abs_value = value = value - rel_addr + offset;
2156 /* Sign bit + exceed 9 bit. */
2157 if (((value & 0xffffff00) != 0) && ((value & 0xffffff00) != 0xffffff00))
2158 return bfd_reloc_overflow;
2159 value >>= 1;
2160 addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
2161 bfd_put_16 (input_bfd, addend, hit_data);
2162 return bfd_reloc_ok;
2164 case R_SCORE_HI16:
2165 return bfd_reloc_ok;
2167 case R_SCORE_LO16:
2168 hi16_addend = bfd_get_32 (input_bfd, hit_data - 4);
2169 hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
2170 addend = bfd_get_32 (input_bfd, hit_data);
2171 offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
2172 offset = (hi16_offset << 16) | (offset & 0xffff);
2174 if (!gp_disp_p)
2175 uvalue = value + offset;
2176 else
2177 uvalue = offset + gp - rel_addr + 4;
2179 hi16_offset = (uvalue >> 16) << 1;
2180 hi16_value = (hi16_addend & (~(howto->dst_mask)))
2181 | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
2182 bfd_put_32 (input_bfd, hi16_value, hit_data - 4);
2183 offset = (uvalue & 0xffff) << 1;
2184 value = (addend & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
2185 bfd_put_32 (input_bfd, value, hit_data);
2186 return bfd_reloc_ok;
2188 case R_SCORE_GP15:
2189 addend = bfd_get_32 (input_bfd, hit_data);
2190 offset = addend & 0x7fff;
2191 if ((offset & 0x4000) == 0x4000)
2192 offset |= 0xffffc000;
2193 value = value + offset - gp;
2194 if (((value & 0xffffc000) != 0) && ((value & 0xffffc000) != 0xffffc000))
2195 return bfd_reloc_overflow;
2196 value = (addend & ~howto->src_mask) | (value & howto->src_mask);
2197 bfd_put_32 (input_bfd, value, hit_data);
2198 return bfd_reloc_ok;
2200 case R_SCORE_GOT15:
2201 case R_SCORE_CALL15:
2202 if (local_p)
2204 bfd_boolean forced;
2206 /* The special case is when the symbol is forced to be local. We need the
2207 full address in the GOT since no R_SCORE_GOT_LO16 relocation follows. */
2208 forced = ! score_elf_local_relocation_p (input_bfd, rel,
2209 local_sections, FALSE);
2210 value = score_elf_got16_entry (output_bfd, input_bfd, info,
2211 symbol + addend, forced);
2212 if (value == MINUS_ONE)
2213 return bfd_reloc_outofrange;
2214 value = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
2215 output_bfd, input_bfd, value);
2217 else
2219 value = g;
2222 if ((long) value > 0x3fff || (long) value < -0x4000)
2223 return bfd_reloc_overflow;
2225 addend = bfd_get_32 (input_bfd, hit_data);
2226 value = (addend & ~howto->dst_mask) | (value & howto->dst_mask);
2227 bfd_put_32 (input_bfd, value, hit_data);
2228 return bfd_reloc_ok;
2230 case R_SCORE_GPREL32:
2231 value = (addend + symbol + gp0 - gp);
2232 value &= howto->dst_mask;
2233 bfd_put_32 (input_bfd, value, hit_data);
2234 return bfd_reloc_ok;
2236 case R_SCORE_GOT_LO16:
2237 addend = bfd_get_32 (input_bfd, hit_data);
2238 value = (((addend >> 16) & 0x3) << 14) | ((addend & 0x7fff) >> 1);
2239 value += symbol;
2240 value = (addend & (~(howto->dst_mask))) | ((value & 0x3fff) << 1)
2241 | (((value >> 14) & 0x3) << 16);
2243 bfd_put_32 (input_bfd, value, hit_data);
2244 return bfd_reloc_ok;
2246 case R_SCORE_DUMMY_HI16:
2247 return bfd_reloc_ok;
2249 case R_SCORE_GNU_VTINHERIT:
2250 case R_SCORE_GNU_VTENTRY:
2251 /* We don't do anything with these at present. */
2252 return bfd_reloc_continue;
2254 default:
2255 return bfd_reloc_notsupported;
2259 /* Score backend functions. */
2261 void
2262 s7_bfd_score_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
2263 arelent *bfd_reloc,
2264 Elf_Internal_Rela *elf_reloc)
2266 unsigned int r_type;
2268 r_type = ELF32_R_TYPE (elf_reloc->r_info);
2269 if (r_type >= ARRAY_SIZE (elf32_score_howto_table))
2270 bfd_reloc->howto = NULL;
2271 else
2272 bfd_reloc->howto = &elf32_score_howto_table[r_type];
2275 /* Relocate an score ELF section. */
2277 bfd_boolean
2278 s7_bfd_score_elf_relocate_section (bfd *output_bfd,
2279 struct bfd_link_info *info,
2280 bfd *input_bfd,
2281 asection *input_section,
2282 bfd_byte *contents,
2283 Elf_Internal_Rela *relocs,
2284 Elf_Internal_Sym *local_syms,
2285 asection **local_sections)
2287 Elf_Internal_Shdr *symtab_hdr;
2288 struct elf_link_hash_entry **sym_hashes;
2289 Elf_Internal_Rela *rel;
2290 Elf_Internal_Rela *relend;
2291 const char *name;
2292 unsigned long offset;
2293 unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
2294 size_t extsymoff;
2295 bfd_boolean gp_disp_p = FALSE;
2297 /* Sort dynsym. */
2298 if (elf_hash_table (info)->dynamic_sections_created)
2300 bfd_size_type dynsecsymcount = 0;
2301 if (info->shared)
2303 asection * p;
2304 const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
2306 for (p = output_bfd->sections; p ; p = p->next)
2307 if ((p->flags & SEC_EXCLUDE) == 0
2308 && (p->flags & SEC_ALLOC) != 0
2309 && !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p))
2310 ++ dynsecsymcount;
2313 if (!score_elf_sort_hash_table (info, dynsecsymcount + 1))
2314 return FALSE;
2317 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
2318 extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
2319 sym_hashes = elf_sym_hashes (input_bfd);
2320 rel = relocs;
2321 relend = relocs + input_section->reloc_count;
2322 for (; rel < relend; rel++)
2324 int r_type;
2325 reloc_howto_type *howto;
2326 unsigned long r_symndx;
2327 Elf_Internal_Sym *sym;
2328 asection *sec;
2329 struct score_elf_link_hash_entry *h;
2330 bfd_vma relocation = 0;
2331 bfd_reloc_status_type r;
2332 arelent bfd_reloc;
2334 r_symndx = ELF32_R_SYM (rel->r_info);
2335 r_type = ELF32_R_TYPE (rel->r_info);
2337 s7_bfd_score_info_to_howto (input_bfd, &bfd_reloc, (Elf_Internal_Rela *) rel);
2338 howto = bfd_reloc.howto;
2340 h = NULL;
2341 sym = NULL;
2342 sec = NULL;
2344 if (r_symndx < extsymoff)
2346 sym = local_syms + r_symndx;
2347 sec = local_sections[r_symndx];
2348 relocation = sec->output_section->vma + sec->output_offset;
2349 name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, sec);
2351 if (!info->relocatable)
2353 if (ELF_ST_TYPE (sym->st_info) != STT_SECTION
2354 || (sec->flags & SEC_MERGE))
2356 relocation += sym->st_value;
2359 if ((sec->flags & SEC_MERGE)
2360 && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2362 asection *msec;
2363 bfd_vma addend, value;
2365 switch (r_type)
2367 case R_SCORE_HI16:
2368 break;
2369 case R_SCORE_LO16:
2370 hi16_addend = bfd_get_32 (input_bfd, contents + rel->r_offset - 4);
2371 hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
2372 value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2373 offset = ((((value >> 16) & 0x3) << 15) | (value & 0x7fff)) >> 1;
2374 addend = (hi16_offset << 16) | (offset & 0xffff);
2375 msec = sec;
2376 addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend);
2377 addend -= relocation;
2378 addend += msec->output_section->vma + msec->output_offset;
2379 uvalue = addend;
2380 hi16_offset = (uvalue >> 16) << 1;
2381 hi16_value = (hi16_addend & (~(howto->dst_mask)))
2382 | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
2383 bfd_put_32 (input_bfd, hi16_value, contents + rel->r_offset - 4);
2384 offset = (uvalue & 0xffff) << 1;
2385 value = (value & (~(howto->dst_mask)))
2386 | (offset & 0x7fff) | ((offset << 1) & 0x30000);
2387 bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2388 break;
2389 case R_SCORE_GOT_LO16:
2390 value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2391 addend = (((value >> 16) & 0x3) << 14) | ((value & 0x7fff) >> 1);
2392 msec = sec;
2393 addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
2394 addend += msec->output_section->vma + msec->output_offset;
2395 value = (value & (~(howto->dst_mask))) | ((addend & 0x3fff) << 1)
2396 | (((addend >> 14) & 0x3) << 16);
2398 bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2399 break;
2400 default:
2401 value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2402 /* Get the (signed) value from the instruction. */
2403 addend = value & howto->src_mask;
2404 if (addend & ((howto->src_mask + 1) >> 1))
2406 bfd_signed_vma mask;
2408 mask = -1;
2409 mask &= ~howto->src_mask;
2410 addend |= mask;
2412 msec = sec;
2413 addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
2414 addend += msec->output_section->vma + msec->output_offset;
2415 value = (value & ~howto->dst_mask) | (addend & howto->dst_mask);
2416 bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2417 break;
2422 else
2424 /* For global symbols we look up the symbol in the hash-table. */
2425 h = ((struct score_elf_link_hash_entry *)
2426 elf_sym_hashes (input_bfd) [r_symndx - extsymoff]);
2427 /* Find the real hash-table entry for this symbol. */
2428 while (h->root.root.type == bfd_link_hash_indirect
2429 || h->root.root.type == bfd_link_hash_warning)
2430 h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
2432 /* Record the name of this symbol, for our caller. */
2433 name = h->root.root.root.string;
2435 /* See if this is the special GP_DISP_LABEL symbol. Note that such a
2436 symbol must always be a global symbol. */
2437 if (strcmp (name, GP_DISP_LABEL) == 0)
2439 /* Relocations against GP_DISP_LABEL are permitted only with
2440 R_SCORE_HI16 and R_SCORE_LO16 relocations. */
2441 if (r_type != R_SCORE_HI16 && r_type != R_SCORE_LO16)
2442 return bfd_reloc_notsupported;
2444 gp_disp_p = TRUE;
2447 /* If this symbol is defined, calculate its address. Note that
2448 GP_DISP_LABEL is a magic symbol, always implicitly defined by the
2449 linker, so it's inappropriate to check to see whether or not
2450 its defined. */
2451 else if ((h->root.root.type == bfd_link_hash_defined
2452 || h->root.root.type == bfd_link_hash_defweak)
2453 && h->root.root.u.def.section)
2455 sec = h->root.root.u.def.section;
2456 if (sec->output_section)
2457 relocation = (h->root.root.u.def.value
2458 + sec->output_section->vma
2459 + sec->output_offset);
2460 else
2462 relocation = h->root.root.u.def.value;
2465 else if (h->root.root.type == bfd_link_hash_undefweak)
2466 /* We allow relocations against undefined weak symbols, giving
2467 it the value zero, so that you can undefined weak functions
2468 and check to see if they exist by looking at their addresses. */
2469 relocation = 0;
2470 else if (info->unresolved_syms_in_objects == RM_IGNORE
2471 && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
2472 relocation = 0;
2473 else if (strcmp (name, "_DYNAMIC_LINK") == 0)
2475 /* If this is a dynamic link, we should have created a _DYNAMIC_LINK symbol
2476 in s7_bfd_score_elf_create_dynamic_sections. Otherwise, we should define
2477 the symbol with a value of 0. */
2478 BFD_ASSERT (! info->shared);
2479 BFD_ASSERT (bfd_get_section_by_name (output_bfd, ".dynamic") == NULL);
2480 relocation = 0;
2482 else if (!info->relocatable)
2484 if (! ((*info->callbacks->undefined_symbol)
2485 (info, h->root.root.root.string, input_bfd,
2486 input_section, rel->r_offset,
2487 (info->unresolved_syms_in_objects == RM_GENERATE_ERROR)
2488 || ELF_ST_VISIBILITY (h->root.other))))
2489 return bfd_reloc_undefined;
2490 relocation = 0;
2494 if (sec != NULL && elf_discarded_section (sec))
2496 /* For relocs against symbols from removed linkonce sections,
2497 or sections discarded by a linker script, we just want the
2498 section contents zeroed. Avoid any special processing. */
2499 _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
2500 rel->r_info = 0;
2501 rel->r_addend = 0;
2502 continue;
2505 if (info->relocatable)
2507 /* This is a relocatable link. We don't have to change
2508 anything, unless the reloc is against a section symbol,
2509 in which case we have to adjust according to where the
2510 section symbol winds up in the output section. */
2511 if (r_symndx < symtab_hdr->sh_info)
2513 sym = local_syms + r_symndx;
2515 if (r_type == R_SCORE_GOT15)
2517 const Elf_Internal_Rela *lo16_rel;
2518 const struct elf_backend_data *bed;
2519 bfd_vma lo_addend = 0, lo_value = 0;
2520 bfd_vma addend, value;
2522 value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2523 addend = value & 0x7fff;
2524 if ((addend & 0x4000) == 0x4000)
2525 addend |= 0xffffc000;
2527 bed = get_elf_backend_data (output_bfd);
2528 relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
2529 lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
2530 if (lo16_rel != NULL)
2532 lo_value = bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
2533 lo_addend = (((lo_value >> 16) & 0x3) << 14) | ((lo_value & 0x7fff) >> 1);
2536 addend <<= 16;
2537 addend += lo_addend;
2539 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2540 addend += local_sections[r_symndx]->output_offset;
2542 lo_addend = addend & 0xffff;
2543 lo_value = (lo_value & (~(howto->dst_mask))) | ((lo_addend & 0x3fff) << 1)
2544 | (((lo_addend >> 14) & 0x3) << 16);
2545 bfd_put_32 (input_bfd, lo_value, contents + lo16_rel->r_offset);
2547 addend = addend >> 16;
2548 value = (value & ~howto->src_mask) | (addend & howto->src_mask);
2549 bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2551 else if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2553 sec = local_sections[r_symndx];
2554 score_elf_add_to_rel (input_bfd, contents + rel->r_offset,
2555 howto, (bfd_signed_vma) (sec->output_offset + sym->st_value));
2558 continue;
2561 /* This is a final link. */
2562 r = score_elf_final_link_relocate (howto, input_bfd, output_bfd,
2563 input_section, contents, rel, relocs,
2564 relocation, info, name,
2565 (h ? ELF_ST_TYPE ((unsigned int) h->root.root.type) :
2566 ELF_ST_TYPE ((unsigned int) sym->st_info)), h, local_syms,
2567 local_sections, gp_disp_p);
2569 if (r != bfd_reloc_ok)
2571 const char *msg = (const char *)0;
2573 switch (r)
2575 case bfd_reloc_overflow:
2576 /* If the overflowing reloc was to an undefined symbol,
2577 we have already printed one error message and there
2578 is no point complaining again. */
2579 if (((!h) || (h->root.root.type != bfd_link_hash_undefined))
2580 && (!((*info->callbacks->reloc_overflow)
2581 (info, NULL, name, howto->name, (bfd_vma) 0,
2582 input_bfd, input_section, rel->r_offset))))
2583 return FALSE;
2584 break;
2585 case bfd_reloc_undefined:
2586 if (!((*info->callbacks->undefined_symbol)
2587 (info, name, input_bfd, input_section, rel->r_offset, TRUE)))
2588 return FALSE;
2589 break;
2591 case bfd_reloc_outofrange:
2592 msg = _("internal error: out of range error");
2593 goto common_error;
2595 case bfd_reloc_notsupported:
2596 msg = _("internal error: unsupported relocation error");
2597 goto common_error;
2599 case bfd_reloc_dangerous:
2600 msg = _("internal error: dangerous error");
2601 goto common_error;
2603 default:
2604 msg = _("internal error: unknown error");
2605 /* fall through */
2607 common_error:
2608 if (!((*info->callbacks->warning)
2609 (info, msg, name, input_bfd, input_section, rel->r_offset)))
2610 return FALSE;
2611 break;
2616 return TRUE;
2619 /* Look through the relocs for a section during the first phase, and
2620 allocate space in the global offset table. */
2622 bfd_boolean
2623 s7_bfd_score_elf_check_relocs (bfd *abfd,
2624 struct bfd_link_info *info,
2625 asection *sec,
2626 const Elf_Internal_Rela *relocs)
2628 const char *name;
2629 bfd *dynobj;
2630 Elf_Internal_Shdr *symtab_hdr;
2631 struct elf_link_hash_entry **sym_hashes;
2632 struct score_got_info *g;
2633 size_t extsymoff;
2634 const Elf_Internal_Rela *rel;
2635 const Elf_Internal_Rela *rel_end;
2636 asection *sgot;
2637 asection *sreloc;
2638 const struct elf_backend_data *bed;
2640 if (info->relocatable)
2641 return TRUE;
2643 dynobj = elf_hash_table (info)->dynobj;
2644 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2645 sym_hashes = elf_sym_hashes (abfd);
2646 extsymoff = (elf_bad_symtab (abfd)) ? 0 : symtab_hdr->sh_info;
2648 name = bfd_get_section_name (abfd, sec);
2650 if (dynobj == NULL)
2652 sgot = NULL;
2653 g = NULL;
2655 else
2657 sgot = score_elf_got_section (dynobj, FALSE);
2658 if (sgot == NULL)
2659 g = NULL;
2660 else
2662 BFD_ASSERT (score_elf_section_data (sgot) != NULL);
2663 g = score_elf_section_data (sgot)->u.got_info;
2664 BFD_ASSERT (g != NULL);
2668 sreloc = NULL;
2669 bed = get_elf_backend_data (abfd);
2670 rel_end = relocs + sec->reloc_count * bed->s->int_rels_per_ext_rel;
2671 for (rel = relocs; rel < rel_end; ++rel)
2673 unsigned long r_symndx;
2674 unsigned int r_type;
2675 struct elf_link_hash_entry *h;
2677 r_symndx = ELF32_R_SYM (rel->r_info);
2678 r_type = ELF32_R_TYPE (rel->r_info);
2680 if (r_symndx < extsymoff)
2682 h = NULL;
2684 else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr))
2686 (*_bfd_error_handler) (_("%s: Malformed reloc detected for section %s"), abfd, name);
2687 bfd_set_error (bfd_error_bad_value);
2688 return FALSE;
2690 else
2692 h = sym_hashes[r_symndx - extsymoff];
2694 /* This may be an indirect symbol created because of a version. */
2695 if (h != NULL)
2697 while (h->root.type == bfd_link_hash_indirect)
2698 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2702 /* Some relocs require a global offset table. */
2703 if (dynobj == NULL || sgot == NULL)
2705 switch (r_type)
2707 case R_SCORE_GOT15:
2708 case R_SCORE_CALL15:
2709 if (dynobj == NULL)
2710 elf_hash_table (info)->dynobj = dynobj = abfd;
2711 if (!score_elf_create_got_section (dynobj, info, FALSE))
2712 return FALSE;
2713 g = score_elf_got_info (dynobj, &sgot);
2714 break;
2715 case R_SCORE_ABS32:
2716 case R_SCORE_REL32:
2717 if (dynobj == NULL && (info->shared || h != NULL) && (sec->flags & SEC_ALLOC) != 0)
2718 elf_hash_table (info)->dynobj = dynobj = abfd;
2719 break;
2720 default:
2721 break;
2725 if (!h && (r_type == R_SCORE_GOT_LO16))
2727 if (! score_elf_record_local_got_symbol (abfd, r_symndx, rel->r_addend, g))
2728 return FALSE;
2731 switch (r_type)
2733 case R_SCORE_CALL15:
2734 if (h == NULL)
2736 (*_bfd_error_handler)
2737 (_("%B: CALL15 reloc at 0x%lx not against global symbol"),
2738 abfd, (unsigned long) rel->r_offset);
2739 bfd_set_error (bfd_error_bad_value);
2740 return FALSE;
2742 else
2744 /* This symbol requires a global offset table entry. */
2745 if (! score_elf_record_global_got_symbol (h, abfd, info, g))
2746 return FALSE;
2748 /* We need a stub, not a plt entry for the undefined function. But we record
2749 it as if it needs plt. See _bfd_elf_adjust_dynamic_symbol. */
2750 h->needs_plt = 1;
2751 h->type = STT_FUNC;
2753 break;
2754 case R_SCORE_GOT15:
2755 if (h && ! score_elf_record_global_got_symbol (h, abfd, info, g))
2756 return FALSE;
2757 break;
2758 case R_SCORE_ABS32:
2759 case R_SCORE_REL32:
2760 if ((info->shared || h != NULL) && (sec->flags & SEC_ALLOC) != 0)
2762 if (sreloc == NULL)
2764 sreloc = score_elf_rel_dyn_section (dynobj, TRUE);
2765 if (sreloc == NULL)
2766 return FALSE;
2768 #define SCORE_READONLY_SECTION (SEC_ALLOC | SEC_LOAD | SEC_READONLY)
2769 if (info->shared)
2771 /* When creating a shared object, we must copy these reloc types into
2772 the output file as R_SCORE_REL32 relocs. We make room for this reloc
2773 in the .rel.dyn reloc section. */
2774 score_elf_allocate_dynamic_relocations (dynobj, 1);
2775 if ((sec->flags & SCORE_READONLY_SECTION)
2776 == SCORE_READONLY_SECTION)
2777 /* We tell the dynamic linker that there are
2778 relocations against the text segment. */
2779 info->flags |= DF_TEXTREL;
2781 else
2783 struct score_elf_link_hash_entry *hscore;
2785 /* We only need to copy this reloc if the symbol is
2786 defined in a dynamic object. */
2787 hscore = (struct score_elf_link_hash_entry *) h;
2788 ++hscore->possibly_dynamic_relocs;
2789 if ((sec->flags & SCORE_READONLY_SECTION)
2790 == SCORE_READONLY_SECTION)
2791 /* We need it to tell the dynamic linker if there
2792 are relocations against the text segment. */
2793 hscore->readonly_reloc = TRUE;
2796 /* Even though we don't directly need a GOT entry for this symbol,
2797 a symbol must have a dynamic symbol table index greater that
2798 DT_SCORE_GOTSYM if there are dynamic relocations against it. */
2799 if (h != NULL)
2801 if (dynobj == NULL)
2802 elf_hash_table (info)->dynobj = dynobj = abfd;
2803 if (! score_elf_create_got_section (dynobj, info, TRUE))
2804 return FALSE;
2805 g = score_elf_got_info (dynobj, &sgot);
2806 if (! score_elf_record_global_got_symbol (h, abfd, info, g))
2807 return FALSE;
2810 break;
2812 /* This relocation describes the C++ object vtable hierarchy.
2813 Reconstruct it for later use during GC. */
2814 case R_SCORE_GNU_VTINHERIT:
2815 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
2816 return FALSE;
2817 break;
2819 /* This relocation describes which C++ vtable entries are actually
2820 used. Record for later use during GC. */
2821 case R_SCORE_GNU_VTENTRY:
2822 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
2823 return FALSE;
2824 break;
2825 default:
2826 break;
2829 /* We must not create a stub for a symbol that has relocations
2830 related to taking the function's address. */
2831 switch (r_type)
2833 default:
2834 if (h != NULL)
2836 struct score_elf_link_hash_entry *sh;
2838 sh = (struct score_elf_link_hash_entry *) h;
2839 sh->no_fn_stub = TRUE;
2841 break;
2842 case R_SCORE_CALL15:
2843 break;
2847 return TRUE;
2850 bfd_boolean
2851 s7_bfd_score_elf_add_symbol_hook (bfd *abfd,
2852 struct bfd_link_info *info ATTRIBUTE_UNUSED,
2853 Elf_Internal_Sym *sym,
2854 const char **namep ATTRIBUTE_UNUSED,
2855 flagword *flagsp ATTRIBUTE_UNUSED,
2856 asection **secp,
2857 bfd_vma *valp)
2859 switch (sym->st_shndx)
2861 case SHN_COMMON:
2862 if (sym->st_size > elf_gp_size (abfd))
2863 break;
2864 /* Fall through. */
2865 case SHN_SCORE_SCOMMON:
2866 *secp = bfd_make_section_old_way (abfd, ".scommon");
2867 (*secp)->flags |= SEC_IS_COMMON;
2868 *valp = sym->st_size;
2869 break;
2872 return TRUE;
2875 void
2876 s7_bfd_score_elf_symbol_processing (bfd *abfd, asymbol *asym)
2878 elf_symbol_type *elfsym;
2880 elfsym = (elf_symbol_type *) asym;
2881 switch (elfsym->internal_elf_sym.st_shndx)
2883 case SHN_COMMON:
2884 if (asym->value > elf_gp_size (abfd))
2885 break;
2886 /* Fall through. */
2887 case SHN_SCORE_SCOMMON:
2888 if (score_elf_scom_section.name == NULL)
2890 /* Initialize the small common section. */
2891 score_elf_scom_section.name = ".scommon";
2892 score_elf_scom_section.flags = SEC_IS_COMMON;
2893 score_elf_scom_section.output_section = &score_elf_scom_section;
2894 score_elf_scom_section.symbol = &score_elf_scom_symbol;
2895 score_elf_scom_section.symbol_ptr_ptr = &score_elf_scom_symbol_ptr;
2896 score_elf_scom_symbol.name = ".scommon";
2897 score_elf_scom_symbol.flags = BSF_SECTION_SYM;
2898 score_elf_scom_symbol.section = &score_elf_scom_section;
2899 score_elf_scom_symbol_ptr = &score_elf_scom_symbol;
2901 asym->section = &score_elf_scom_section;
2902 asym->value = elfsym->internal_elf_sym.st_size;
2903 break;
2908 s7_bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
2909 const char *name ATTRIBUTE_UNUSED,
2910 Elf_Internal_Sym *sym,
2911 asection *input_sec,
2912 struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
2914 /* If we see a common symbol, which implies a relocatable link, then
2915 if a symbol was small common in an input file, mark it as small
2916 common in the output file. */
2917 if (sym->st_shndx == SHN_COMMON && strcmp (input_sec->name, ".scommon") == 0)
2918 sym->st_shndx = SHN_SCORE_SCOMMON;
2920 return 1;
2923 bfd_boolean
2924 s7_bfd_score_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
2925 asection *sec,
2926 int *retval)
2928 if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
2930 *retval = SHN_SCORE_SCOMMON;
2931 return TRUE;
2934 return FALSE;
2937 /* Adjust a symbol defined by a dynamic object and referenced by a
2938 regular object. The current definition is in some section of the
2939 dynamic object, but we're not including those sections. We have to
2940 change the definition to something the rest of the link can understand. */
2942 bfd_boolean
2943 s7_bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
2944 struct elf_link_hash_entry *h)
2946 bfd *dynobj;
2947 struct score_elf_link_hash_entry *hscore;
2948 asection *s;
2950 dynobj = elf_hash_table (info)->dynobj;
2952 /* Make sure we know what is going on here. */
2953 BFD_ASSERT (dynobj != NULL
2954 && (h->needs_plt
2955 || h->u.weakdef != NULL
2956 || (h->def_dynamic && h->ref_regular && !h->def_regular)));
2958 /* If this symbol is defined in a dynamic object, we need to copy
2959 any R_SCORE_ABS32 or R_SCORE_REL32 relocs against it into the output
2960 file. */
2961 hscore = (struct score_elf_link_hash_entry *) h;
2962 if (!info->relocatable
2963 && hscore->possibly_dynamic_relocs != 0
2964 && (h->root.type == bfd_link_hash_defweak || !h->def_regular))
2966 score_elf_allocate_dynamic_relocations (dynobj, hscore->possibly_dynamic_relocs);
2967 if (hscore->readonly_reloc)
2968 /* We tell the dynamic linker that there are relocations
2969 against the text segment. */
2970 info->flags |= DF_TEXTREL;
2973 /* For a function, create a stub, if allowed. */
2974 if (!hscore->no_fn_stub && h->needs_plt)
2976 if (!elf_hash_table (info)->dynamic_sections_created)
2977 return TRUE;
2979 /* If this symbol is not defined in a regular file, then set
2980 the symbol to the stub location. This is required to make
2981 function pointers compare as equal between the normal
2982 executable and the shared library. */
2983 if (!h->def_regular)
2985 /* We need .stub section. */
2986 s = bfd_get_section_by_name (dynobj, SCORE_ELF_STUB_SECTION_NAME);
2987 BFD_ASSERT (s != NULL);
2989 h->root.u.def.section = s;
2990 h->root.u.def.value = s->size;
2992 /* XXX Write this stub address somewhere. */
2993 h->plt.offset = s->size;
2995 /* Make room for this stub code. */
2996 s->size += SCORE_FUNCTION_STUB_SIZE;
2998 /* The last half word of the stub will be filled with the index
2999 of this symbol in .dynsym section. */
3000 return TRUE;
3003 else if ((h->type == STT_FUNC) && !h->needs_plt)
3005 /* This will set the entry for this symbol in the GOT to 0, and
3006 the dynamic linker will take care of this. */
3007 h->root.u.def.value = 0;
3008 return TRUE;
3011 /* If this is a weak symbol, and there is a real definition, the
3012 processor independent code will have arranged for us to see the
3013 real definition first, and we can just use the same value. */
3014 if (h->u.weakdef != NULL)
3016 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
3017 || h->u.weakdef->root.type == bfd_link_hash_defweak);
3018 h->root.u.def.section = h->u.weakdef->root.u.def.section;
3019 h->root.u.def.value = h->u.weakdef->root.u.def.value;
3020 return TRUE;
3023 /* This is a reference to a symbol defined by a dynamic object which
3024 is not a function. */
3025 return TRUE;
3028 /* This function is called after all the input files have been read,
3029 and the input sections have been assigned to output sections. */
3031 bfd_boolean
3032 s7_bfd_score_elf_always_size_sections (bfd *output_bfd,
3033 struct bfd_link_info *info)
3035 bfd *dynobj;
3036 asection *s;
3037 struct score_got_info *g;
3038 int i;
3039 bfd_size_type loadable_size = 0;
3040 bfd_size_type local_gotno;
3041 bfd *sub;
3043 dynobj = elf_hash_table (info)->dynobj;
3044 if (dynobj == NULL)
3045 /* Relocatable links don't have it. */
3046 return TRUE;
3048 g = score_elf_got_info (dynobj, &s);
3049 if (s == NULL)
3050 return TRUE;
3052 /* Calculate the total loadable size of the output. That will give us the
3053 maximum number of GOT_PAGE entries required. */
3054 for (sub = info->input_bfds; sub; sub = sub->link_next)
3056 asection *subsection;
3058 for (subsection = sub->sections;
3059 subsection;
3060 subsection = subsection->next)
3062 if ((subsection->flags & SEC_ALLOC) == 0)
3063 continue;
3064 loadable_size += ((subsection->size + 0xf)
3065 &~ (bfd_size_type) 0xf);
3069 /* There has to be a global GOT entry for every symbol with
3070 a dynamic symbol table index of DT_SCORE_GOTSYM or
3071 higher. Therefore, it make sense to put those symbols
3072 that need GOT entries at the end of the symbol table. We
3073 do that here. */
3074 if (! score_elf_sort_hash_table (info, 1))
3075 return FALSE;
3077 if (g->global_gotsym != NULL)
3078 i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx;
3079 else
3080 /* If there are no global symbols, or none requiring
3081 relocations, then GLOBAL_GOTSYM will be NULL. */
3082 i = 0;
3084 /* In the worst case, we'll get one stub per dynamic symbol. */
3085 loadable_size += SCORE_FUNCTION_STUB_SIZE * i;
3087 /* Assume there are two loadable segments consisting of
3088 contiguous sections. Is 5 enough? */
3089 local_gotno = (loadable_size >> 16) + 5;
3091 g->local_gotno += local_gotno;
3092 s->size += g->local_gotno * SCORE_ELF_GOT_SIZE (output_bfd);
3094 g->global_gotno = i;
3095 s->size += i * SCORE_ELF_GOT_SIZE (output_bfd);
3097 score_elf_resolve_final_got_entries (g);
3099 if (s->size > SCORE_ELF_GOT_MAX_SIZE (output_bfd))
3101 /* Fixme. Error message or Warning message should be issued here. */
3104 return TRUE;
3107 /* Set the sizes of the dynamic sections. */
3109 bfd_boolean
3110 s7_bfd_score_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
3112 bfd *dynobj;
3113 asection *s;
3114 bfd_boolean reltext;
3116 dynobj = elf_hash_table (info)->dynobj;
3117 BFD_ASSERT (dynobj != NULL);
3119 if (elf_hash_table (info)->dynamic_sections_created)
3121 /* Set the contents of the .interp section to the interpreter. */
3122 if (!info->shared)
3124 s = bfd_get_section_by_name (dynobj, ".interp");
3125 BFD_ASSERT (s != NULL);
3126 s->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
3127 s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
3131 /* The check_relocs and adjust_dynamic_symbol entry points have
3132 determined the sizes of the various dynamic sections. Allocate
3133 memory for them. */
3134 reltext = FALSE;
3135 for (s = dynobj->sections; s != NULL; s = s->next)
3137 const char *name;
3139 if ((s->flags & SEC_LINKER_CREATED) == 0)
3140 continue;
3142 /* It's OK to base decisions on the section name, because none
3143 of the dynobj section names depend upon the input files. */
3144 name = bfd_get_section_name (dynobj, s);
3146 if (CONST_STRNEQ (name, ".rel"))
3148 if (s->size == 0)
3150 /* We only strip the section if the output section name
3151 has the same name. Otherwise, there might be several
3152 input sections for this output section. FIXME: This
3153 code is probably not needed these days anyhow, since
3154 the linker now does not create empty output sections. */
3155 if (s->output_section != NULL
3156 && strcmp (name,
3157 bfd_get_section_name (s->output_section->owner,
3158 s->output_section)) == 0)
3159 s->flags |= SEC_EXCLUDE;
3161 else
3163 const char *outname;
3164 asection *target;
3166 /* If this relocation section applies to a read only
3167 section, then we probably need a DT_TEXTREL entry.
3168 If the relocation section is .rel.dyn, we always
3169 assert a DT_TEXTREL entry rather than testing whether
3170 there exists a relocation to a read only section or
3171 not. */
3172 outname = bfd_get_section_name (output_bfd, s->output_section);
3173 target = bfd_get_section_by_name (output_bfd, outname + 4);
3174 if ((target != NULL
3175 && (target->flags & SEC_READONLY) != 0
3176 && (target->flags & SEC_ALLOC) != 0) || strcmp (outname, ".rel.dyn") == 0)
3177 reltext = TRUE;
3179 /* We use the reloc_count field as a counter if we need
3180 to copy relocs into the output file. */
3181 if (strcmp (name, ".rel.dyn") != 0)
3182 s->reloc_count = 0;
3185 else if (CONST_STRNEQ (name, ".got"))
3187 /* s7_bfd_score_elf_always_size_sections() has already done
3188 most of the work, but some symbols may have been mapped
3189 to versions that we must now resolve in the got_entries
3190 hash tables. */
3192 else if (strcmp (name, SCORE_ELF_STUB_SECTION_NAME) == 0)
3194 /* IRIX rld assumes that the function stub isn't at the end
3195 of .text section. So put a dummy. XXX */
3196 s->size += SCORE_FUNCTION_STUB_SIZE;
3198 else if (! CONST_STRNEQ (name, ".init"))
3200 /* It's not one of our sections, so don't allocate space. */
3201 continue;
3204 /* Allocate memory for the section contents. */
3205 s->contents = bfd_zalloc (dynobj, s->size);
3206 if (s->contents == NULL && s->size != 0)
3208 bfd_set_error (bfd_error_no_memory);
3209 return FALSE;
3213 if (elf_hash_table (info)->dynamic_sections_created)
3215 /* Add some entries to the .dynamic section. We fill in the
3216 values later, in s7_bfd_score_elf_finish_dynamic_sections, but we
3217 must add the entries now so that we get the correct size for
3218 the .dynamic section. The DT_DEBUG entry is filled in by the
3219 dynamic linker and used by the debugger. */
3221 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0))
3222 return FALSE;
3224 if (reltext)
3225 info->flags |= DF_TEXTREL;
3227 if ((info->flags & DF_TEXTREL) != 0)
3229 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0))
3230 return FALSE;
3233 if (! SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTGOT, 0))
3234 return FALSE;
3236 if (score_elf_rel_dyn_section (dynobj, FALSE))
3238 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_REL, 0))
3239 return FALSE;
3241 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELSZ, 0))
3242 return FALSE;
3244 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELENT, 0))
3245 return FALSE;
3248 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_BASE_ADDRESS, 0))
3249 return FALSE;
3251 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_LOCAL_GOTNO, 0))
3252 return FALSE;
3254 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_SYMTABNO, 0))
3255 return FALSE;
3257 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_UNREFEXTNO, 0))
3258 return FALSE;
3260 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_GOTSYM, 0))
3261 return FALSE;
3263 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_HIPAGENO, 0))
3264 return FALSE;
3267 return TRUE;
3270 bfd_boolean
3271 s7_bfd_score_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
3273 struct elf_link_hash_entry *h;
3274 struct bfd_link_hash_entry *bh;
3275 flagword flags;
3276 asection *s;
3278 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
3279 | SEC_LINKER_CREATED | SEC_READONLY);
3281 /* ABI requests the .dynamic section to be read only. */
3282 s = bfd_get_section_by_name (abfd, ".dynamic");
3283 if (s != NULL)
3285 if (!bfd_set_section_flags (abfd, s, flags))
3286 return FALSE;
3289 /* We need to create .got section. */
3290 if (!score_elf_create_got_section (abfd, info, FALSE))
3291 return FALSE;
3293 if (!score_elf_rel_dyn_section (elf_hash_table (info)->dynobj, TRUE))
3294 return FALSE;
3296 /* Create .stub section. */
3297 if (bfd_get_section_by_name (abfd, SCORE_ELF_STUB_SECTION_NAME) == NULL)
3299 s = bfd_make_section_with_flags (abfd, SCORE_ELF_STUB_SECTION_NAME,
3300 flags | SEC_CODE);
3301 if (s == NULL
3302 || !bfd_set_section_alignment (abfd, s, 2))
3304 return FALSE;
3307 if (!info->shared)
3309 const char *name;
3311 name = "_DYNAMIC_LINK";
3312 bh = NULL;
3313 if (!(_bfd_generic_link_add_one_symbol
3314 (info, abfd, name, BSF_GLOBAL, bfd_abs_section_ptr,
3315 (bfd_vma) 0, NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
3316 return FALSE;
3318 h = (struct elf_link_hash_entry *) bh;
3319 h->non_elf = 0;
3320 h->def_regular = 1;
3321 h->type = STT_SECTION;
3323 if (!bfd_elf_link_record_dynamic_symbol (info, h))
3324 return FALSE;
3327 return TRUE;
3331 /* Finish up dynamic symbol handling. We set the contents of various
3332 dynamic sections here. */
3334 bfd_boolean
3335 s7_bfd_score_elf_finish_dynamic_symbol (bfd *output_bfd,
3336 struct bfd_link_info *info,
3337 struct elf_link_hash_entry *h,
3338 Elf_Internal_Sym *sym)
3340 bfd *dynobj;
3341 asection *sgot;
3342 struct score_got_info *g;
3343 const char *name;
3345 dynobj = elf_hash_table (info)->dynobj;
3347 if (h->plt.offset != MINUS_ONE)
3349 asection *s;
3350 bfd_byte stub[SCORE_FUNCTION_STUB_SIZE];
3352 /* This symbol has a stub. Set it up. */
3353 BFD_ASSERT (h->dynindx != -1);
3355 s = bfd_get_section_by_name (dynobj, SCORE_ELF_STUB_SECTION_NAME);
3356 BFD_ASSERT (s != NULL);
3358 /* FIXME: Can h->dynindex be more than 64K? */
3359 if (h->dynindx & 0xffff0000)
3360 return FALSE;
3362 /* Fill the stub. */
3363 bfd_put_32 (output_bfd, STUB_LW, stub);
3364 bfd_put_32 (output_bfd, STUB_MOVE, stub + 4);
3365 bfd_put_32 (output_bfd, STUB_LI16 | (h->dynindx << 1), stub + 8);
3366 bfd_put_32 (output_bfd, STUB_BRL, stub + 12);
3368 BFD_ASSERT (h->plt.offset <= s->size);
3369 memcpy (s->contents + h->plt.offset, stub, SCORE_FUNCTION_STUB_SIZE);
3371 /* Mark the symbol as undefined. plt.offset != -1 occurs
3372 only for the referenced symbol. */
3373 sym->st_shndx = SHN_UNDEF;
3375 /* The run-time linker uses the st_value field of the symbol
3376 to reset the global offset table entry for this external
3377 to its stub address when unlinking a shared object. */
3378 sym->st_value = (s->output_section->vma + s->output_offset + h->plt.offset);
3381 BFD_ASSERT (h->dynindx != -1 || h->forced_local);
3383 sgot = score_elf_got_section (dynobj, FALSE);
3384 BFD_ASSERT (sgot != NULL);
3385 BFD_ASSERT (score_elf_section_data (sgot) != NULL);
3386 g = score_elf_section_data (sgot)->u.got_info;
3387 BFD_ASSERT (g != NULL);
3389 /* Run through the global symbol table, creating GOT entries for all
3390 the symbols that need them. */
3391 if (g->global_gotsym != NULL && h->dynindx >= g->global_gotsym->dynindx)
3393 bfd_vma offset;
3394 bfd_vma value;
3396 value = sym->st_value;
3397 offset = score_elf_global_got_index (dynobj, h);
3398 bfd_put_32 (output_bfd, value, sgot->contents + offset);
3401 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
3402 name = h->root.root.string;
3403 if (strcmp (name, "_DYNAMIC") == 0 || strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
3404 sym->st_shndx = SHN_ABS;
3405 else if (strcmp (name, "_DYNAMIC_LINK") == 0)
3407 sym->st_shndx = SHN_ABS;
3408 sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
3409 sym->st_value = 1;
3411 else if (strcmp (name, GP_DISP_LABEL) == 0)
3413 sym->st_shndx = SHN_ABS;
3414 sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
3415 sym->st_value = elf_gp (output_bfd);
3418 return TRUE;
3421 /* Finish up the dynamic sections. */
3423 bfd_boolean
3424 s7_bfd_score_elf_finish_dynamic_sections (bfd *output_bfd,
3425 struct bfd_link_info *info)
3427 bfd *dynobj;
3428 asection *sdyn;
3429 asection *sgot;
3430 asection *s;
3431 struct score_got_info *g;
3433 dynobj = elf_hash_table (info)->dynobj;
3435 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
3437 sgot = score_elf_got_section (dynobj, FALSE);
3438 if (sgot == NULL)
3439 g = NULL;
3440 else
3442 BFD_ASSERT (score_elf_section_data (sgot) != NULL);
3443 g = score_elf_section_data (sgot)->u.got_info;
3444 BFD_ASSERT (g != NULL);
3447 if (elf_hash_table (info)->dynamic_sections_created)
3449 bfd_byte *b;
3451 BFD_ASSERT (sdyn != NULL);
3452 BFD_ASSERT (g != NULL);
3454 for (b = sdyn->contents;
3455 b < sdyn->contents + sdyn->size;
3456 b += SCORE_ELF_DYN_SIZE (dynobj))
3458 Elf_Internal_Dyn dyn;
3459 const char *name;
3460 size_t elemsize;
3461 bfd_boolean swap_out_p;
3463 /* Read in the current dynamic entry. */
3464 (*get_elf_backend_data (dynobj)->s->swap_dyn_in) (dynobj, b, &dyn);
3466 /* Assume that we're going to modify it and write it out. */
3467 swap_out_p = TRUE;
3469 switch (dyn.d_tag)
3471 case DT_RELENT:
3472 s = score_elf_rel_dyn_section (dynobj, FALSE);
3473 BFD_ASSERT (s != NULL);
3474 dyn.d_un.d_val = SCORE_ELF_REL_SIZE (dynobj);
3475 break;
3477 case DT_STRSZ:
3478 /* Rewrite DT_STRSZ. */
3479 dyn.d_un.d_val = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
3480 break;
3482 case DT_PLTGOT:
3483 name = ".got";
3484 s = bfd_get_section_by_name (output_bfd, name);
3485 BFD_ASSERT (s != NULL);
3486 dyn.d_un.d_ptr = s->vma;
3487 break;
3489 case DT_SCORE_BASE_ADDRESS:
3490 s = output_bfd->sections;
3491 BFD_ASSERT (s != NULL);
3492 dyn.d_un.d_ptr = s->vma & ~(bfd_vma) 0xffff;
3493 break;
3495 case DT_SCORE_LOCAL_GOTNO:
3496 dyn.d_un.d_val = g->local_gotno;
3497 break;
3499 case DT_SCORE_UNREFEXTNO:
3500 /* The index into the dynamic symbol table which is the
3501 entry of the first external symbol that is not
3502 referenced within the same object. */
3503 dyn.d_un.d_val = bfd_count_sections (output_bfd) + 1;
3504 break;
3506 case DT_SCORE_GOTSYM:
3507 if (g->global_gotsym)
3509 dyn.d_un.d_val = g->global_gotsym->dynindx;
3510 break;
3512 /* In case if we don't have global got symbols we default
3513 to setting DT_SCORE_GOTSYM to the same value as
3514 DT_SCORE_SYMTABNO, so we just fall through. */
3516 case DT_SCORE_SYMTABNO:
3517 name = ".dynsym";
3518 elemsize = SCORE_ELF_SYM_SIZE (output_bfd);
3519 s = bfd_get_section_by_name (output_bfd, name);
3520 BFD_ASSERT (s != NULL);
3522 dyn.d_un.d_val = s->size / elemsize;
3523 break;
3525 case DT_SCORE_HIPAGENO:
3526 dyn.d_un.d_val = g->local_gotno - SCORE_RESERVED_GOTNO;
3527 break;
3529 default:
3530 swap_out_p = FALSE;
3531 break;
3534 if (swap_out_p)
3535 (*get_elf_backend_data (dynobj)->s->swap_dyn_out) (dynobj, &dyn, b);
3539 /* The first entry of the global offset table will be filled at
3540 runtime. The second entry will be used by some runtime loaders.
3541 This isn't the case of IRIX rld. */
3542 if (sgot != NULL && sgot->size > 0)
3544 bfd_put_32 (output_bfd, 0, sgot->contents);
3545 bfd_put_32 (output_bfd, 0x80000000, sgot->contents + SCORE_ELF_GOT_SIZE (output_bfd));
3548 if (sgot != NULL)
3549 elf_section_data (sgot->output_section)->this_hdr.sh_entsize
3550 = SCORE_ELF_GOT_SIZE (output_bfd);
3553 /* We need to sort the entries of the dynamic relocation section. */
3554 s = score_elf_rel_dyn_section (dynobj, FALSE);
3556 if (s != NULL && s->size > (bfd_vma)2 * SCORE_ELF_REL_SIZE (output_bfd))
3558 reldyn_sorting_bfd = output_bfd;
3559 qsort ((Elf32_External_Rel *) s->contents + 1, s->reloc_count - 1,
3560 sizeof (Elf32_External_Rel), score_elf_sort_dynamic_relocs);
3563 return TRUE;
3566 /* This function set up the ELF section header for a BFD section in preparation for writing
3567 it out. This is where the flags and type fields are set for unusual sections. */
3569 bfd_boolean
3570 s7_bfd_score_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
3571 Elf_Internal_Shdr *hdr,
3572 asection *sec)
3574 const char *name;
3576 name = bfd_get_section_name (abfd, sec);
3578 if (strcmp (name, ".got") == 0
3579 || strcmp (name, ".srdata") == 0
3580 || strcmp (name, ".sdata") == 0
3581 || strcmp (name, ".sbss") == 0)
3582 hdr->sh_flags |= SHF_SCORE_GPREL;
3584 return TRUE;
3587 /* This function do additional processing on the ELF section header before writing
3588 it out. This is used to set the flags and type fields for some sections. */
3590 /* assign_file_positions_except_relocs() check section flag and if it is allocatable,
3591 warning message will be issued. backend_fake_section is called before
3592 assign_file_positions_except_relocs(); backend_section_processing after it. so, we
3593 modify section flag there, but not backend_fake_section. */
3595 bfd_boolean
3596 s7_bfd_score_elf_section_processing (bfd *abfd ATTRIBUTE_UNUSED, Elf_Internal_Shdr *hdr)
3598 if (hdr->bfd_section != NULL)
3600 const char *name = bfd_get_section_name (abfd, hdr->bfd_section);
3602 if (strcmp (name, ".sdata") == 0)
3604 hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
3605 hdr->sh_type = SHT_PROGBITS;
3607 else if (strcmp (name, ".sbss") == 0)
3609 hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
3610 hdr->sh_type = SHT_NOBITS;
3612 else if (strcmp (name, ".srdata") == 0)
3614 hdr->sh_flags |= SHF_ALLOC | SHF_SCORE_GPREL;
3615 hdr->sh_type = SHT_PROGBITS;
3619 return TRUE;
3622 bfd_boolean
3623 s7_bfd_score_elf_write_section (bfd *output_bfd, asection *sec, bfd_byte *contents)
3625 bfd_byte *to, *from, *end;
3626 int i;
3628 if (strcmp (sec->name, ".pdr") != 0)
3629 return FALSE;
3631 if (score_elf_section_data (sec)->u.tdata == NULL)
3632 return FALSE;
3634 to = contents;
3635 end = contents + sec->size;
3636 for (from = contents, i = 0; from < end; from += PDR_SIZE, i++)
3638 if ((score_elf_section_data (sec)->u.tdata)[i] == 1)
3639 continue;
3641 if (to != from)
3642 memcpy (to, from, PDR_SIZE);
3644 to += PDR_SIZE;
3646 bfd_set_section_contents (output_bfd, sec->output_section, contents,
3647 (file_ptr) sec->output_offset, sec->size);
3649 return TRUE;
3652 /* Copy data from a SCORE ELF indirect symbol to its direct symbol, hiding the old
3653 indirect symbol. Process additional relocation information. */
3655 void
3656 s7_bfd_score_elf_copy_indirect_symbol (struct bfd_link_info *info,
3657 struct elf_link_hash_entry *dir,
3658 struct elf_link_hash_entry *ind)
3660 struct score_elf_link_hash_entry *dirscore, *indscore;
3662 _bfd_elf_link_hash_copy_indirect (info, dir, ind);
3664 if (ind->root.type != bfd_link_hash_indirect)
3665 return;
3667 dirscore = (struct score_elf_link_hash_entry *) dir;
3668 indscore = (struct score_elf_link_hash_entry *) ind;
3669 dirscore->possibly_dynamic_relocs += indscore->possibly_dynamic_relocs;
3671 if (indscore->readonly_reloc)
3672 dirscore->readonly_reloc = TRUE;
3674 if (indscore->no_fn_stub)
3675 dirscore->no_fn_stub = TRUE;
3678 /* Remove information about discarded functions from other sections which mention them. */
3680 bfd_boolean
3681 s7_bfd_score_elf_discard_info (bfd *abfd,
3682 struct elf_reloc_cookie *cookie,
3683 struct bfd_link_info *info)
3685 asection *o;
3686 bfd_boolean ret = FALSE;
3687 unsigned char *tdata;
3688 size_t i, skip;
3690 o = bfd_get_section_by_name (abfd, ".pdr");
3691 if ((!o) || (o->size == 0) || (o->size % PDR_SIZE != 0)
3692 || (o->output_section != NULL && bfd_is_abs_section (o->output_section)))
3693 return FALSE;
3695 tdata = bfd_zmalloc (o->size / PDR_SIZE);
3696 if (!tdata)
3697 return FALSE;
3699 cookie->rels = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, info->keep_memory);
3700 if (!cookie->rels)
3702 free (tdata);
3703 return FALSE;
3706 cookie->rel = cookie->rels;
3707 cookie->relend = cookie->rels + o->reloc_count;
3709 for (i = 0, skip = 0; i < o->size; i++)
3711 if (bfd_elf_reloc_symbol_deleted_p (i * PDR_SIZE, cookie))
3713 tdata[i] = 1;
3714 skip++;
3718 if (skip != 0)
3720 score_elf_section_data (o)->u.tdata = tdata;
3721 o->size -= skip * PDR_SIZE;
3722 ret = TRUE;
3724 else
3725 free (tdata);
3727 if (!info->keep_memory)
3728 free (cookie->rels);
3730 return ret;
3733 /* Signal that discard_info() has removed the discarded relocations for this section. */
3735 bfd_boolean
3736 s7_bfd_score_elf_ignore_discarded_relocs (asection *sec)
3738 if (strcmp (sec->name, ".pdr") == 0)
3739 return TRUE;
3740 return FALSE;
3743 /* Return the section that should be marked against GC for a given
3744 relocation. */
3746 asection *
3747 s7_bfd_score_elf_gc_mark_hook (asection *sec,
3748 struct bfd_link_info *info,
3749 Elf_Internal_Rela *rel,
3750 struct elf_link_hash_entry *h,
3751 Elf_Internal_Sym *sym)
3753 if (h != NULL)
3754 switch (ELF32_R_TYPE (rel->r_info))
3756 case R_SCORE_GNU_VTINHERIT:
3757 case R_SCORE_GNU_VTENTRY:
3758 return NULL;
3761 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
3764 /* Support for core dump NOTE sections. */
3766 bfd_boolean
3767 s7_bfd_score_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
3769 int offset;
3770 unsigned int raw_size;
3772 switch (note->descsz)
3774 default:
3775 return FALSE;
3776 case 272: /* Linux/Score elf_prstatus */
3778 /* pr_cursig */
3779 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
3781 /* pr_pid */
3782 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
3784 /* pr_reg */
3785 offset = 72;
3787 /* sizeof(elf_gregset_t) */
3788 raw_size = 196;
3790 break;
3793 /* Make a ".reg/999" section. */
3794 return _bfd_elfcore_make_pseudosection (abfd, ".reg", raw_size, note->descpos + offset);
3797 bfd_boolean
3798 s7_bfd_score_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
3800 switch (note->descsz)
3802 default:
3803 return FALSE;
3805 case 128: /* Linux/Score elf_prpsinfo. */
3806 /* pr_fname */
3807 elf_tdata (abfd)->core_program = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
3809 /* pr_psargs */
3810 elf_tdata (abfd)->core_command = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
3811 break;
3814 /* Note that for some reason, a spurious space is tacked
3815 onto the end of the args in some (at least one anyway)
3816 implementations, so strip it off if it exists. */
3819 char *command = elf_tdata (abfd)->core_command;
3820 int n = strlen (command);
3822 if (0 < n && command[n - 1] == ' ')
3823 command[n - 1] = '\0';
3826 return TRUE;
3830 /* Score BFD functions. */
3832 reloc_howto_type *
3833 s7_elf32_score_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
3835 unsigned int i;
3837 for (i = 0; i < ARRAY_SIZE (elf32_score_reloc_map); i++)
3838 if (elf32_score_reloc_map[i].bfd_reloc_val == code)
3839 return &elf32_score_howto_table[elf32_score_reloc_map[i].elf_reloc_val];
3841 return NULL;
3844 /* Create a score elf linker hash table. */
3846 struct bfd_link_hash_table *
3847 s7_elf32_score_link_hash_table_create (bfd *abfd)
3849 struct score_elf_link_hash_table *ret;
3850 bfd_size_type amt = sizeof (struct score_elf_link_hash_table);
3852 ret = bfd_malloc (amt);
3853 if (ret == NULL)
3854 return NULL;
3856 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd, score_elf_link_hash_newfunc,
3857 sizeof (struct score_elf_link_hash_entry)))
3859 free (ret);
3860 return NULL;
3863 return &ret->root.root;
3866 bfd_boolean
3867 s7_elf32_score_print_private_bfd_data (bfd *abfd, void * ptr)
3869 FILE *file = (FILE *) ptr;
3871 BFD_ASSERT (abfd != NULL && ptr != NULL);
3873 /* Print normal ELF private data. */
3874 _bfd_elf_print_private_bfd_data (abfd, ptr);
3876 /* xgettext:c-format */
3877 fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
3878 if (elf_elfheader (abfd)->e_flags & EF_SCORE_PIC)
3880 fprintf (file, _(" [pic]"));
3882 if (elf_elfheader (abfd)->e_flags & EF_SCORE_FIXDEP)
3884 fprintf (file, _(" [fix dep]"));
3886 fputc ('\n', file);
3888 return TRUE;
3891 bfd_boolean
3892 s7_elf32_score_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
3894 flagword in_flags;
3895 flagword out_flags;
3897 if (!_bfd_generic_verify_endian_match (ibfd, obfd))
3898 return FALSE;
3900 in_flags = elf_elfheader (ibfd)->e_flags;
3901 out_flags = elf_elfheader (obfd)->e_flags;
3903 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
3904 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
3905 return TRUE;
3907 in_flags = elf_elfheader (ibfd)->e_flags;
3908 out_flags = elf_elfheader (obfd)->e_flags;
3910 if (! elf_flags_init (obfd))
3912 elf_flags_init (obfd) = TRUE;
3913 elf_elfheader (obfd)->e_flags = in_flags;
3915 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
3916 && bfd_get_arch_info (obfd)->the_default)
3918 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
3921 return TRUE;
3924 if (((in_flags & EF_SCORE_PIC) != 0) != ((out_flags & EF_SCORE_PIC) != 0))
3926 (*_bfd_error_handler) (_("%B: warning: linking PIC files with non-PIC files"), ibfd);
3929 /* Maybe dependency fix compatibility should be checked here. */
3930 return TRUE;
3933 bfd_boolean
3934 s7_elf32_score_new_section_hook (bfd *abfd, asection *sec)
3936 struct _score_elf_section_data *sdata;
3937 bfd_size_type amt = sizeof (*sdata);
3939 sdata = bfd_zalloc (abfd, amt);
3940 if (sdata == NULL)
3941 return FALSE;
3942 sec->used_by_bfd = sdata;
3944 return _bfd_elf_new_section_hook (abfd, sec);
3947 #define elf_backend_omit_section_dynsym \
3948 ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)