binutils/
[binutils.git] / bfd / elf32-score7.c
blob81d0dcb69412eb82baa84ec57e6fb9db549a2ca8
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 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 index = ((h->dynindx - global_got_dynindx + g->local_gotno) * SCORE_ELF_GOT_SIZE (abfd));
1668 BFD_ASSERT (index < sgot->size);
1670 return 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, bfd *output_bfd,
1677 bfd *input_bfd ATTRIBUTE_UNUSED, bfd_vma index)
1679 asection *sgot;
1680 bfd_vma gp;
1681 struct score_got_info *g;
1683 g = score_elf_got_info (dynobj, &sgot);
1684 gp = _bfd_get_gp_value (output_bfd);
1686 return sgot->output_section->vma + sgot->output_offset + index - gp;
1689 /* Follow indirect and warning hash entries so that each got entry
1690 points to the final symbol definition. P must point to a pointer
1691 to the hash table we're traversing. Since this traversal may
1692 modify the hash table, we set this pointer to NULL to indicate
1693 we've made a potentially-destructive change to the hash table, so
1694 the traversal must be restarted. */
1696 static int
1697 score_elf_resolve_final_got_entry (void **entryp, void *p)
1699 struct score_got_entry *entry = (struct score_got_entry *) *entryp;
1700 htab_t got_entries = *(htab_t *) p;
1702 if (entry->abfd != NULL && entry->symndx == -1)
1704 struct score_elf_link_hash_entry *h = entry->d.h;
1706 while (h->root.root.type == bfd_link_hash_indirect
1707 || h->root.root.type == bfd_link_hash_warning)
1708 h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
1710 if (entry->d.h == h)
1711 return 1;
1713 entry->d.h = h;
1715 /* If we can't find this entry with the new bfd hash, re-insert
1716 it, and get the traversal restarted. */
1717 if (! htab_find (got_entries, entry))
1719 htab_clear_slot (got_entries, entryp);
1720 entryp = htab_find_slot (got_entries, entry, INSERT);
1721 if (! *entryp)
1722 *entryp = entry;
1723 /* Abort the traversal, since the whole table may have
1724 moved, and leave it up to the parent to restart the
1725 process. */
1726 *(htab_t *) p = NULL;
1727 return 0;
1729 /* We might want to decrement the global_gotno count, but it's
1730 either too early or too late for that at this point. */
1733 return 1;
1736 /* Turn indirect got entries in a got_entries table into their final locations. */
1738 static void
1739 score_elf_resolve_final_got_entries (struct score_got_info *g)
1741 htab_t got_entries;
1745 got_entries = g->got_entries;
1747 htab_traverse (got_entries,
1748 score_elf_resolve_final_got_entry,
1749 &got_entries);
1751 while (got_entries == NULL);
1754 /* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS. for -r */
1756 static void
1757 score_elf_add_to_rel (bfd *abfd,
1758 bfd_byte *address,
1759 reloc_howto_type *howto,
1760 bfd_signed_vma increment)
1762 bfd_signed_vma addend;
1763 bfd_vma contents;
1764 unsigned long offset;
1765 unsigned long r_type = howto->type;
1766 unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
1768 contents = bfd_get_32 (abfd, address);
1769 /* Get the (signed) value from the instruction. */
1770 addend = contents & howto->src_mask;
1771 if (addend & ((howto->src_mask + 1) >> 1))
1773 bfd_signed_vma mask;
1775 mask = -1;
1776 mask &= ~howto->src_mask;
1777 addend |= mask;
1779 /* Add in the increment, (which is a byte value). */
1780 switch (r_type)
1782 case R_SCORE_PC19:
1783 offset =
1784 (((contents & howto->src_mask) & 0x3ff0000) >> 6) | ((contents & howto->src_mask) & 0x3ff);
1785 offset += increment;
1786 contents =
1787 (contents & ~howto->
1788 src_mask) | (((offset << 6) & howto->src_mask) & 0x3ff0000) | (offset & 0x3ff);
1789 bfd_put_32 (abfd, contents, address);
1790 break;
1791 case R_SCORE_HI16:
1792 break;
1793 case R_SCORE_LO16:
1794 hi16_addend = bfd_get_32 (abfd, address - 4);
1795 hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
1796 offset = ((((contents >> 16) & 0x3) << 15) | (contents & 0x7fff)) >> 1;
1797 offset = (hi16_offset << 16) | (offset & 0xffff);
1798 uvalue = increment + offset;
1799 hi16_offset = (uvalue >> 16) << 1;
1800 hi16_value = (hi16_addend & (~(howto->dst_mask)))
1801 | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
1802 bfd_put_32 (abfd, hi16_value, address - 4);
1803 offset = (uvalue & 0xffff) << 1;
1804 contents = (contents & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
1805 bfd_put_32 (abfd, contents, address);
1806 break;
1807 case R_SCORE_24:
1808 offset =
1809 (((contents & howto->src_mask) >> 1) & 0x1ff8000) | ((contents & howto->src_mask) & 0x7fff);
1810 offset += increment;
1811 contents =
1812 (contents & ~howto->
1813 src_mask) | (((offset << 1) & howto->src_mask) & 0x3ff0000) | (offset & 0x7fff);
1814 bfd_put_32 (abfd, contents, address);
1815 break;
1816 case R_SCORE16_11:
1818 contents = bfd_get_16 (abfd, address);
1819 offset = contents & howto->src_mask;
1820 offset += increment;
1821 contents = (contents & ~howto->src_mask) | (offset & howto->src_mask);
1822 bfd_put_16 (abfd, contents, address);
1824 break;
1825 case R_SCORE16_PC8:
1827 contents = bfd_get_16 (abfd, address);
1828 offset = (contents & howto->src_mask) + ((increment >> 1) & 0xff);
1829 contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask);
1830 bfd_put_16 (abfd, contents, address);
1832 break;
1833 case R_SCORE_GOT15:
1834 case R_SCORE_GOT_LO16:
1835 break;
1837 default:
1838 addend += increment;
1839 contents = (contents & ~howto->dst_mask) | (addend & howto->dst_mask);
1840 bfd_put_32 (abfd, contents, address);
1841 break;
1845 /* Perform a relocation as part of a final link. */
1847 static bfd_reloc_status_type
1848 score_elf_final_link_relocate (reloc_howto_type *howto,
1849 bfd *input_bfd,
1850 bfd *output_bfd,
1851 asection *input_section,
1852 bfd_byte *contents,
1853 Elf_Internal_Rela *rel,
1854 Elf_Internal_Rela *relocs,
1855 bfd_vma symbol,
1856 struct bfd_link_info *info,
1857 const char *sym_name ATTRIBUTE_UNUSED,
1858 int sym_flags ATTRIBUTE_UNUSED,
1859 struct score_elf_link_hash_entry *h,
1860 Elf_Internal_Sym *local_syms,
1861 asection **local_sections,
1862 bfd_boolean gp_disp_p)
1864 unsigned long r_type;
1865 unsigned long r_symndx;
1866 bfd_byte *hit_data = contents + rel->r_offset;
1867 bfd_vma addend;
1868 /* The final GP value to be used for the relocatable, executable, or
1869 shared object file being produced. */
1870 bfd_vma gp = MINUS_ONE;
1871 /* The place (section offset or address) of the storage unit being relocated. */
1872 bfd_vma rel_addr;
1873 /* The value of GP used to create the relocatable object. */
1874 bfd_vma gp0 = MINUS_ONE;
1875 /* The offset into the global offset table at which the address of the relocation entry
1876 symbol, adjusted by the addend, resides during execution. */
1877 bfd_vma g = MINUS_ONE;
1878 /* TRUE if the symbol referred to by this relocation is a local symbol. */
1879 bfd_boolean local_p;
1880 /* The eventual value we will relocate. */
1881 bfd_vma value = symbol;
1882 unsigned long hi16_addend, hi16_offset, hi16_value, uvalue, offset, abs_value = 0;
1884 Elf_Internal_Sym *sym = 0;
1885 asection *sec = NULL;
1886 bfd_boolean merge_p = 0;
1889 if (elf_gp (output_bfd) == 0)
1891 struct bfd_link_hash_entry *bh;
1892 asection *o;
1894 bh = bfd_link_hash_lookup (info->hash, "_gp", 0, 0, 1);
1895 if (bh != NULL && bh->type == bfd_link_hash_defined)
1896 elf_gp (output_bfd) = (bh->u.def.value
1897 + bh->u.def.section->output_section->vma
1898 + bh->u.def.section->output_offset);
1899 else if (info->relocatable)
1901 bfd_vma lo = -1;
1903 /* Find the GP-relative section with the lowest offset. */
1904 for (o = output_bfd->sections; o != NULL; o = o->next)
1905 if (o->vma < lo)
1906 lo = o->vma;
1907 /* And calculate GP relative to that. */
1908 elf_gp (output_bfd) = lo + ELF_SCORE_GP_OFFSET (input_bfd);
1910 else
1912 /* If the relocate_section function needs to do a reloc
1913 involving the GP value, it should make a reloc_dangerous
1914 callback to warn that GP is not defined. */
1918 /* Parse the relocation. */
1919 r_symndx = ELF32_R_SYM (rel->r_info);
1920 r_type = ELF32_R_TYPE (rel->r_info);
1921 rel_addr = (input_section->output_section->vma + input_section->output_offset + rel->r_offset);
1923 /* For hidden symbol. */
1924 local_p = score_elf_local_relocation_p (input_bfd, rel, local_sections, FALSE);
1925 if (local_p)
1927 sym = local_syms + r_symndx;
1928 sec = local_sections[r_symndx];
1930 symbol = sec->output_section->vma + sec->output_offset;
1931 if (ELF_ST_TYPE (sym->st_info) != STT_SECTION
1932 || (sec->flags & SEC_MERGE))
1933 symbol += sym->st_value;
1934 if ((sec->flags & SEC_MERGE)
1935 && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1936 merge_p = 1;
1939 if (r_type == R_SCORE_GOT15)
1941 const Elf_Internal_Rela *relend;
1942 const Elf_Internal_Rela *lo16_rel;
1943 const struct elf_backend_data *bed;
1944 bfd_vma lo_value = 0;
1946 bed = get_elf_backend_data (output_bfd);
1947 relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
1948 lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
1949 if ((local_p) && (lo16_rel != NULL))
1951 bfd_vma tmp = 0;
1952 tmp = bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
1953 lo_value = (((tmp >> 16) & 0x3) << 14) | ((tmp & 0x7fff) >> 1);
1954 if (merge_p)
1956 asection *msec = sec;
1957 lo_value = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, lo_value);
1958 lo_value -= symbol;
1959 lo_value += msec->output_section->vma + msec->output_offset;
1962 addend = lo_value;
1964 else
1966 addend = (bfd_get_32 (input_bfd, hit_data) >> howto->bitpos) & howto->src_mask;
1969 /* Figure out the value of the symbol. */
1970 if (local_p && !merge_p)
1972 if (r_type == R_SCORE_GOT15)
1974 const Elf_Internal_Rela *relend;
1975 const Elf_Internal_Rela *lo16_rel;
1976 const struct elf_backend_data *bed;
1977 bfd_vma lo_value = 0;
1979 value = bfd_get_32 (input_bfd, contents + rel->r_offset);
1980 addend = value & 0x7fff;
1981 if ((addend & 0x4000) == 0x4000)
1982 addend |= 0xffffc000;
1984 bed = get_elf_backend_data (output_bfd);
1985 relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
1986 lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
1987 if ((local_p) && (lo16_rel != NULL))
1989 bfd_vma tmp = 0;
1990 tmp = bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
1991 lo_value = (((tmp >> 16) & 0x3) << 14) | ((tmp & 0x7fff) >> 1);
1994 addend <<= 16;
1995 addend += lo_value;
1999 local_p = score_elf_local_relocation_p (input_bfd, rel, local_sections, TRUE);
2001 /* If we haven't already determined the GOT offset, or the GP value,
2002 and we're going to need it, get it now. */
2003 switch (r_type)
2005 case R_SCORE_CALL15:
2006 case R_SCORE_GOT15:
2007 if (!local_p)
2009 g = score_elf_global_got_index (elf_hash_table (info)->dynobj,
2010 (struct elf_link_hash_entry *) h);
2011 if ((! elf_hash_table(info)->dynamic_sections_created
2012 || (info->shared
2013 && (info->symbolic || h->root.dynindx == -1)
2014 && h->root.def_regular)))
2016 /* This is a static link or a -Bsymbolic link. The
2017 symbol is defined locally, or was forced to be local.
2018 We must initialize this entry in the GOT. */
2019 bfd *tmpbfd = elf_hash_table (info)->dynobj;
2020 asection *sgot = score_elf_got_section (tmpbfd, FALSE);
2021 bfd_put_32 (tmpbfd, value, sgot->contents + g);
2024 else if (r_type == R_SCORE_GOT15 || r_type == R_SCORE_CALL15)
2026 /* There's no need to create a local GOT entry here; the
2027 calculation for a local GOT15 entry does not involve G. */
2030 else
2032 g = score_elf_local_got_index (output_bfd, input_bfd, info,
2033 symbol + addend, r_symndx, h, r_type);
2034 if (g == MINUS_ONE)
2035 return bfd_reloc_outofrange;
2038 /* Convert GOT indices to actual offsets. */
2039 g = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
2040 output_bfd, input_bfd, g);
2041 break;
2043 case R_SCORE_HI16:
2044 case R_SCORE_LO16:
2045 case R_SCORE_GPREL32:
2046 gp0 = _bfd_get_gp_value (input_bfd);
2047 gp = _bfd_get_gp_value (output_bfd);
2048 break;
2050 case R_SCORE_GP15:
2051 gp = _bfd_get_gp_value (output_bfd);
2053 default:
2054 break;
2057 switch (r_type)
2059 case R_SCORE_NONE:
2060 return bfd_reloc_ok;
2062 case R_SCORE_ABS32:
2063 case R_SCORE_REL32:
2064 if ((info->shared
2065 || (elf_hash_table (info)->dynamic_sections_created
2066 && h != NULL
2067 && h->root.def_dynamic
2068 && !h->root.def_regular))
2069 && r_symndx != 0
2070 && (input_section->flags & SEC_ALLOC) != 0)
2072 /* If we're creating a shared library, or this relocation is against a symbol
2073 in a shared library, then we can't know where the symbol will end up.
2074 So, we create a relocation record in the output, and leave the job up
2075 to the dynamic linker. */
2076 value = addend;
2077 if (!score_elf_create_dynamic_relocation (output_bfd, info, rel, h,
2078 symbol, &value,
2079 input_section))
2080 return bfd_reloc_undefined;
2082 else if (r_symndx == 0)
2083 /* r_symndx will be zero only for relocs against symbols
2084 from removed linkonce sections, or sections discarded by
2085 a linker script. */
2086 value = 0;
2087 else
2089 if (r_type != R_SCORE_REL32)
2090 value = symbol + addend;
2091 else
2092 value = addend;
2094 value &= howto->dst_mask;
2095 bfd_put_32 (input_bfd, value, hit_data);
2096 return bfd_reloc_ok;
2098 case R_SCORE_ABS16:
2099 value += addend;
2100 if ((long) value > 0x7fff || (long) value < -0x8000)
2101 return bfd_reloc_overflow;
2102 bfd_put_16 (input_bfd, value, hit_data);
2103 return bfd_reloc_ok;
2105 case R_SCORE_24:
2106 addend = bfd_get_32 (input_bfd, hit_data);
2107 offset = (((addend & howto->src_mask) >> 1) & 0x1ff8000) | ((addend & howto->src_mask) & 0x7fff);
2108 if ((offset & 0x1000000) != 0)
2109 offset |= 0xfe000000;
2110 value += offset;
2111 abs_value = abs (value - rel_addr);
2112 if ((abs_value & 0xfe000000) != 0)
2113 return bfd_reloc_overflow;
2114 addend = (addend & ~howto->src_mask)
2115 | (((value << 1) & howto->src_mask) & 0x3ff0000) | (value & 0x7fff);
2116 bfd_put_32 (input_bfd, addend, hit_data);
2117 return bfd_reloc_ok;
2119 case R_SCORE_PC19:
2120 addend = bfd_get_32 (input_bfd, hit_data);
2121 offset = (((addend & howto->src_mask) & 0x3ff0000) >> 6) | ((addend & howto->src_mask) & 0x3ff);
2122 if ((offset & 0x80000) != 0)
2123 offset |= 0xfff00000;
2124 abs_value = value = value - rel_addr + offset;
2125 /* exceed 20 bit : overflow. */
2126 if ((abs_value & 0x80000000) == 0x80000000)
2127 abs_value = 0xffffffff - value + 1;
2128 if ((abs_value & 0xfff80000) != 0)
2129 return bfd_reloc_overflow;
2130 addend = (addend & ~howto->src_mask)
2131 | (((value << 6) & howto->src_mask) & 0x3ff0000) | (value & 0x3ff);
2132 bfd_put_32 (input_bfd, addend, hit_data);
2133 return bfd_reloc_ok;
2135 case R_SCORE16_11:
2136 addend = bfd_get_16 (input_bfd, hit_data);
2137 offset = addend & howto->src_mask;
2138 if ((offset & 0x800) != 0) /* Offset is negative. */
2139 offset |= 0xfffff000;
2140 value += offset;
2141 abs_value = abs (value - rel_addr);
2142 if ((abs_value & 0xfffff000) != 0)
2143 return bfd_reloc_overflow;
2144 addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
2145 bfd_put_16 (input_bfd, addend, hit_data);
2146 return bfd_reloc_ok;
2148 case R_SCORE16_PC8:
2149 addend = bfd_get_16 (input_bfd, hit_data);
2150 offset = (addend & howto->src_mask) << 1;
2151 if ((offset & 0x100) != 0) /* Offset is negative. */
2152 offset |= 0xfffffe00;
2153 abs_value = value = value - rel_addr + offset;
2154 /* Sign bit + exceed 9 bit. */
2155 if (((value & 0xffffff00) != 0) && ((value & 0xffffff00) != 0xffffff00))
2156 return bfd_reloc_overflow;
2157 value >>= 1;
2158 addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
2159 bfd_put_16 (input_bfd, addend, hit_data);
2160 return bfd_reloc_ok;
2162 case R_SCORE_HI16:
2163 return bfd_reloc_ok;
2165 case R_SCORE_LO16:
2166 hi16_addend = bfd_get_32 (input_bfd, hit_data - 4);
2167 hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
2168 addend = bfd_get_32 (input_bfd, hit_data);
2169 offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
2170 offset = (hi16_offset << 16) | (offset & 0xffff);
2172 if (!gp_disp_p)
2173 uvalue = value + offset;
2174 else
2175 uvalue = offset + gp - rel_addr + 4;
2177 hi16_offset = (uvalue >> 16) << 1;
2178 hi16_value = (hi16_addend & (~(howto->dst_mask)))
2179 | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
2180 bfd_put_32 (input_bfd, hi16_value, hit_data - 4);
2181 offset = (uvalue & 0xffff) << 1;
2182 value = (addend & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
2183 bfd_put_32 (input_bfd, value, hit_data);
2184 return bfd_reloc_ok;
2186 case R_SCORE_GP15:
2187 addend = bfd_get_32 (input_bfd, hit_data);
2188 offset = addend & 0x7fff;
2189 if ((offset & 0x4000) == 0x4000)
2190 offset |= 0xffffc000;
2191 value = value + offset - gp;
2192 if (((value & 0xffffc000) != 0) && ((value & 0xffffc000) != 0xffffc000))
2193 return bfd_reloc_overflow;
2194 value = (addend & ~howto->src_mask) | (value & howto->src_mask);
2195 bfd_put_32 (input_bfd, value, hit_data);
2196 return bfd_reloc_ok;
2198 case R_SCORE_GOT15:
2199 case R_SCORE_CALL15:
2200 if (local_p)
2202 bfd_boolean forced;
2204 /* The special case is when the symbol is forced to be local. We need the
2205 full address in the GOT since no R_SCORE_GOT_LO16 relocation follows. */
2206 forced = ! score_elf_local_relocation_p (input_bfd, rel,
2207 local_sections, FALSE);
2208 value = score_elf_got16_entry (output_bfd, input_bfd, info,
2209 symbol + addend, forced);
2210 if (value == MINUS_ONE)
2211 return bfd_reloc_outofrange;
2212 value = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
2213 output_bfd, input_bfd, value);
2215 else
2217 value = g;
2220 if ((long) value > 0x3fff || (long) value < -0x4000)
2221 return bfd_reloc_overflow;
2223 addend = bfd_get_32 (input_bfd, hit_data);
2224 value = (addend & ~howto->dst_mask) | (value & howto->dst_mask);
2225 bfd_put_32 (input_bfd, value, hit_data);
2226 return bfd_reloc_ok;
2228 case R_SCORE_GPREL32:
2229 value = (addend + symbol + gp0 - gp);
2230 value &= howto->dst_mask;
2231 bfd_put_32 (input_bfd, value, hit_data);
2232 return bfd_reloc_ok;
2234 case R_SCORE_GOT_LO16:
2235 addend = bfd_get_32 (input_bfd, hit_data);
2236 value = (((addend >> 16) & 0x3) << 14) | ((addend & 0x7fff) >> 1);
2237 value += symbol;
2238 value = (addend & (~(howto->dst_mask))) | ((value & 0x3fff) << 1)
2239 | (((value >> 14) & 0x3) << 16);
2241 bfd_put_32 (input_bfd, value, hit_data);
2242 return bfd_reloc_ok;
2244 case R_SCORE_DUMMY_HI16:
2245 return bfd_reloc_ok;
2247 case R_SCORE_GNU_VTINHERIT:
2248 case R_SCORE_GNU_VTENTRY:
2249 /* We don't do anything with these at present. */
2250 return bfd_reloc_continue;
2252 default:
2253 return bfd_reloc_notsupported;
2257 /* Score backend functions. */
2259 void
2260 s7_bfd_score_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
2261 arelent *bfd_reloc,
2262 Elf_Internal_Rela *elf_reloc)
2264 unsigned int r_type;
2266 r_type = ELF32_R_TYPE (elf_reloc->r_info);
2267 if (r_type >= ARRAY_SIZE (elf32_score_howto_table))
2268 bfd_reloc->howto = NULL;
2269 else
2270 bfd_reloc->howto = &elf32_score_howto_table[r_type];
2273 /* Relocate an score ELF section. */
2275 bfd_boolean
2276 s7_bfd_score_elf_relocate_section (bfd *output_bfd,
2277 struct bfd_link_info *info,
2278 bfd *input_bfd,
2279 asection *input_section,
2280 bfd_byte *contents,
2281 Elf_Internal_Rela *relocs,
2282 Elf_Internal_Sym *local_syms,
2283 asection **local_sections)
2285 Elf_Internal_Shdr *symtab_hdr;
2286 struct elf_link_hash_entry **sym_hashes;
2287 Elf_Internal_Rela *rel;
2288 Elf_Internal_Rela *relend;
2289 const char *name;
2290 unsigned long offset;
2291 unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
2292 size_t extsymoff;
2293 bfd_boolean gp_disp_p = FALSE;
2295 /* Sort dynsym. */
2296 if (elf_hash_table (info)->dynamic_sections_created)
2298 bfd_size_type dynsecsymcount = 0;
2299 if (info->shared)
2301 asection * p;
2302 const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
2304 for (p = output_bfd->sections; p ; p = p->next)
2305 if ((p->flags & SEC_EXCLUDE) == 0
2306 && (p->flags & SEC_ALLOC) != 0
2307 && !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p))
2308 ++ dynsecsymcount;
2311 if (!score_elf_sort_hash_table (info, dynsecsymcount + 1))
2312 return FALSE;
2315 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
2316 extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
2317 sym_hashes = elf_sym_hashes (input_bfd);
2318 rel = relocs;
2319 relend = relocs + input_section->reloc_count;
2320 for (; rel < relend; rel++)
2322 int r_type;
2323 reloc_howto_type *howto;
2324 unsigned long r_symndx;
2325 Elf_Internal_Sym *sym;
2326 asection *sec;
2327 struct score_elf_link_hash_entry *h;
2328 bfd_vma relocation = 0;
2329 bfd_reloc_status_type r;
2330 arelent bfd_reloc;
2332 r_symndx = ELF32_R_SYM (rel->r_info);
2333 r_type = ELF32_R_TYPE (rel->r_info);
2335 s7_bfd_score_info_to_howto (input_bfd, &bfd_reloc, (Elf_Internal_Rela *) rel);
2336 howto = bfd_reloc.howto;
2338 h = NULL;
2339 sym = NULL;
2340 sec = NULL;
2342 if (r_symndx < extsymoff)
2344 sym = local_syms + r_symndx;
2345 sec = local_sections[r_symndx];
2346 relocation = sec->output_section->vma + sec->output_offset;
2347 name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, sec);
2349 if (!info->relocatable)
2351 if (ELF_ST_TYPE (sym->st_info) != STT_SECTION
2352 || (sec->flags & SEC_MERGE))
2354 relocation += sym->st_value;
2357 if ((sec->flags & SEC_MERGE)
2358 && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2360 asection *msec;
2361 bfd_vma addend, value;
2363 switch (r_type)
2365 case R_SCORE_HI16:
2366 break;
2367 case R_SCORE_LO16:
2368 hi16_addend = bfd_get_32 (input_bfd, contents + rel->r_offset - 4);
2369 hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
2370 value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2371 offset = ((((value >> 16) & 0x3) << 15) | (value & 0x7fff)) >> 1;
2372 addend = (hi16_offset << 16) | (offset & 0xffff);
2373 msec = sec;
2374 addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend);
2375 addend -= relocation;
2376 addend += msec->output_section->vma + msec->output_offset;
2377 uvalue = addend;
2378 hi16_offset = (uvalue >> 16) << 1;
2379 hi16_value = (hi16_addend & (~(howto->dst_mask)))
2380 | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
2381 bfd_put_32 (input_bfd, hi16_value, contents + rel->r_offset - 4);
2382 offset = (uvalue & 0xffff) << 1;
2383 value = (value & (~(howto->dst_mask)))
2384 | (offset & 0x7fff) | ((offset << 1) & 0x30000);
2385 bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2386 break;
2387 case R_SCORE_GOT_LO16:
2388 value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2389 addend = (((value >> 16) & 0x3) << 14) | ((value & 0x7fff) >> 1);
2390 msec = sec;
2391 addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
2392 addend += msec->output_section->vma + msec->output_offset;
2393 value = (value & (~(howto->dst_mask))) | ((addend & 0x3fff) << 1)
2394 | (((addend >> 14) & 0x3) << 16);
2396 bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2397 break;
2398 default:
2399 value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2400 /* Get the (signed) value from the instruction. */
2401 addend = value & howto->src_mask;
2402 if (addend & ((howto->src_mask + 1) >> 1))
2404 bfd_signed_vma mask;
2406 mask = -1;
2407 mask &= ~howto->src_mask;
2408 addend |= mask;
2410 msec = sec;
2411 addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
2412 addend += msec->output_section->vma + msec->output_offset;
2413 value = (value & ~howto->dst_mask) | (addend & howto->dst_mask);
2414 bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2415 break;
2420 else
2422 /* For global symbols we look up the symbol in the hash-table. */
2423 h = ((struct score_elf_link_hash_entry *)
2424 elf_sym_hashes (input_bfd) [r_symndx - extsymoff]);
2425 /* Find the real hash-table entry for this symbol. */
2426 while (h->root.root.type == bfd_link_hash_indirect
2427 || h->root.root.type == bfd_link_hash_warning)
2428 h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
2430 /* Record the name of this symbol, for our caller. */
2431 name = h->root.root.root.string;
2433 /* See if this is the special GP_DISP_LABEL symbol. Note that such a
2434 symbol must always be a global symbol. */
2435 if (strcmp (name, GP_DISP_LABEL) == 0)
2437 /* Relocations against GP_DISP_LABEL are permitted only with
2438 R_SCORE_HI16 and R_SCORE_LO16 relocations. */
2439 if (r_type != R_SCORE_HI16 && r_type != R_SCORE_LO16)
2440 return bfd_reloc_notsupported;
2442 gp_disp_p = TRUE;
2445 /* If this symbol is defined, calculate its address. Note that
2446 GP_DISP_LABEL is a magic symbol, always implicitly defined by the
2447 linker, so it's inappropriate to check to see whether or not
2448 its defined. */
2449 else if ((h->root.root.type == bfd_link_hash_defined
2450 || h->root.root.type == bfd_link_hash_defweak)
2451 && h->root.root.u.def.section)
2453 sec = h->root.root.u.def.section;
2454 if (sec->output_section)
2455 relocation = (h->root.root.u.def.value
2456 + sec->output_section->vma
2457 + sec->output_offset);
2458 else
2460 relocation = h->root.root.u.def.value;
2463 else if (h->root.root.type == bfd_link_hash_undefweak)
2464 /* We allow relocations against undefined weak symbols, giving
2465 it the value zero, so that you can undefined weak functions
2466 and check to see if they exist by looking at their addresses. */
2467 relocation = 0;
2468 else if (info->unresolved_syms_in_objects == RM_IGNORE
2469 && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
2470 relocation = 0;
2471 else if (strcmp (name, "_DYNAMIC_LINK") == 0)
2473 /* If this is a dynamic link, we should have created a _DYNAMIC_LINK symbol
2474 in s7_bfd_score_elf_create_dynamic_sections. Otherwise, we should define
2475 the symbol with a value of 0. */
2476 BFD_ASSERT (! info->shared);
2477 BFD_ASSERT (bfd_get_section_by_name (output_bfd, ".dynamic") == NULL);
2478 relocation = 0;
2480 else if (!info->relocatable)
2482 if (! ((*info->callbacks->undefined_symbol)
2483 (info, h->root.root.root.string, input_bfd,
2484 input_section, rel->r_offset,
2485 (info->unresolved_syms_in_objects == RM_GENERATE_ERROR)
2486 || ELF_ST_VISIBILITY (h->root.other))))
2487 return bfd_reloc_undefined;
2488 relocation = 0;
2492 if (sec != NULL && elf_discarded_section (sec))
2494 /* For relocs against symbols from removed linkonce sections,
2495 or sections discarded by a linker script, we just want the
2496 section contents zeroed. Avoid any special processing. */
2497 _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
2498 rel->r_info = 0;
2499 rel->r_addend = 0;
2500 continue;
2503 if (info->relocatable)
2505 /* This is a relocatable link. We don't have to change
2506 anything, unless the reloc is against a section symbol,
2507 in which case we have to adjust according to where the
2508 section symbol winds up in the output section. */
2509 if (r_symndx < symtab_hdr->sh_info)
2511 sym = local_syms + r_symndx;
2513 if (r_type == R_SCORE_GOT15)
2515 const Elf_Internal_Rela *relend;
2516 const Elf_Internal_Rela *lo16_rel;
2517 const struct elf_backend_data *bed;
2518 bfd_vma lo_addend = 0, lo_value = 0;
2519 bfd_vma addend, value;
2521 value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2522 addend = value & 0x7fff;
2523 if ((addend & 0x4000) == 0x4000)
2524 addend |= 0xffffc000;
2526 bed = get_elf_backend_data (output_bfd);
2527 relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
2528 lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
2529 if (lo16_rel != NULL)
2531 lo_value = bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
2532 lo_addend = (((lo_value >> 16) & 0x3) << 14) | ((lo_value & 0x7fff) >> 1);
2535 addend <<= 16;
2536 addend += lo_addend;
2538 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2539 addend += local_sections[r_symndx]->output_offset;
2541 lo_addend = addend & 0xffff;
2542 lo_value = (lo_value & (~(howto->dst_mask))) | ((lo_addend & 0x3fff) << 1)
2543 | (((lo_addend >> 14) & 0x3) << 16);
2544 bfd_put_32 (input_bfd, lo_value, contents + lo16_rel->r_offset);
2546 addend = addend >> 16;
2547 value = (value & ~howto->src_mask) | (addend & howto->src_mask);
2548 bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2550 else if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2552 sec = local_sections[r_symndx];
2553 score_elf_add_to_rel (input_bfd, contents + rel->r_offset,
2554 howto, (bfd_signed_vma) (sec->output_offset + sym->st_value));
2557 continue;
2560 /* This is a final link. */
2561 r = score_elf_final_link_relocate (howto, input_bfd, output_bfd,
2562 input_section, contents, rel, relocs,
2563 relocation, info, name,
2564 (h ? ELF_ST_TYPE ((unsigned int) h->root.root.type) :
2565 ELF_ST_TYPE ((unsigned int) sym->st_info)), h, local_syms,
2566 local_sections, gp_disp_p);
2568 if (r != bfd_reloc_ok)
2570 const char *msg = (const char *)0;
2572 switch (r)
2574 case bfd_reloc_overflow:
2575 /* If the overflowing reloc was to an undefined symbol,
2576 we have already printed one error message and there
2577 is no point complaining again. */
2578 if (((!h) || (h->root.root.type != bfd_link_hash_undefined))
2579 && (!((*info->callbacks->reloc_overflow)
2580 (info, NULL, name, howto->name, (bfd_vma) 0,
2581 input_bfd, input_section, rel->r_offset))))
2582 return FALSE;
2583 break;
2584 case bfd_reloc_undefined:
2585 if (!((*info->callbacks->undefined_symbol)
2586 (info, name, input_bfd, input_section, rel->r_offset, TRUE)))
2587 return FALSE;
2588 break;
2590 case bfd_reloc_outofrange:
2591 msg = _("internal error: out of range error");
2592 goto common_error;
2594 case bfd_reloc_notsupported:
2595 msg = _("internal error: unsupported relocation error");
2596 goto common_error;
2598 case bfd_reloc_dangerous:
2599 msg = _("internal error: dangerous error");
2600 goto common_error;
2602 default:
2603 msg = _("internal error: unknown error");
2604 /* fall through */
2606 common_error:
2607 if (!((*info->callbacks->warning)
2608 (info, msg, name, input_bfd, input_section, rel->r_offset)))
2609 return FALSE;
2610 break;
2615 return TRUE;
2618 /* Look through the relocs for a section during the first phase, and
2619 allocate space in the global offset table. */
2621 bfd_boolean
2622 s7_bfd_score_elf_check_relocs (bfd *abfd,
2623 struct bfd_link_info *info,
2624 asection *sec,
2625 const Elf_Internal_Rela *relocs)
2627 const char *name;
2628 bfd *dynobj;
2629 Elf_Internal_Shdr *symtab_hdr;
2630 struct elf_link_hash_entry **sym_hashes;
2631 struct score_got_info *g;
2632 size_t extsymoff;
2633 const Elf_Internal_Rela *rel;
2634 const Elf_Internal_Rela *rel_end;
2635 asection *sgot;
2636 asection *sreloc;
2637 const struct elf_backend_data *bed;
2639 if (info->relocatable)
2640 return TRUE;
2642 dynobj = elf_hash_table (info)->dynobj;
2643 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2644 sym_hashes = elf_sym_hashes (abfd);
2645 extsymoff = (elf_bad_symtab (abfd)) ? 0 : symtab_hdr->sh_info;
2647 name = bfd_get_section_name (abfd, sec);
2649 if (dynobj == NULL)
2651 sgot = NULL;
2652 g = NULL;
2654 else
2656 sgot = score_elf_got_section (dynobj, FALSE);
2657 if (sgot == NULL)
2658 g = NULL;
2659 else
2661 BFD_ASSERT (score_elf_section_data (sgot) != NULL);
2662 g = score_elf_section_data (sgot)->u.got_info;
2663 BFD_ASSERT (g != NULL);
2667 sreloc = NULL;
2668 bed = get_elf_backend_data (abfd);
2669 rel_end = relocs + sec->reloc_count * bed->s->int_rels_per_ext_rel;
2670 for (rel = relocs; rel < rel_end; ++rel)
2672 unsigned long r_symndx;
2673 unsigned int r_type;
2674 struct elf_link_hash_entry *h;
2676 r_symndx = ELF32_R_SYM (rel->r_info);
2677 r_type = ELF32_R_TYPE (rel->r_info);
2679 if (r_symndx < extsymoff)
2681 h = NULL;
2683 else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr))
2685 (*_bfd_error_handler) (_("%s: Malformed reloc detected for section %s"), abfd, name);
2686 bfd_set_error (bfd_error_bad_value);
2687 return FALSE;
2689 else
2691 h = sym_hashes[r_symndx - extsymoff];
2693 /* This may be an indirect symbol created because of a version. */
2694 if (h != NULL)
2696 while (h->root.type == bfd_link_hash_indirect)
2697 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2701 /* Some relocs require a global offset table. */
2702 if (dynobj == NULL || sgot == NULL)
2704 switch (r_type)
2706 case R_SCORE_GOT15:
2707 case R_SCORE_CALL15:
2708 if (dynobj == NULL)
2709 elf_hash_table (info)->dynobj = dynobj = abfd;
2710 if (!score_elf_create_got_section (dynobj, info, FALSE))
2711 return FALSE;
2712 g = score_elf_got_info (dynobj, &sgot);
2713 break;
2714 case R_SCORE_ABS32:
2715 case R_SCORE_REL32:
2716 if (dynobj == NULL && (info->shared || h != NULL) && (sec->flags & SEC_ALLOC) != 0)
2717 elf_hash_table (info)->dynobj = dynobj = abfd;
2718 break;
2719 default:
2720 break;
2724 if (!h && (r_type == R_SCORE_GOT_LO16))
2726 if (! score_elf_record_local_got_symbol (abfd, r_symndx, rel->r_addend, g))
2727 return FALSE;
2730 switch (r_type)
2732 case R_SCORE_CALL15:
2733 if (h == NULL)
2735 (*_bfd_error_handler)
2736 (_("%B: CALL15 reloc at 0x%lx not against global symbol"),
2737 abfd, (unsigned long) rel->r_offset);
2738 bfd_set_error (bfd_error_bad_value);
2739 return FALSE;
2741 else
2743 /* This symbol requires a global offset table entry. */
2744 if (! score_elf_record_global_got_symbol (h, abfd, info, g))
2745 return FALSE;
2747 /* We need a stub, not a plt entry for the undefined function. But we record
2748 it as if it needs plt. See _bfd_elf_adjust_dynamic_symbol. */
2749 h->needs_plt = 1;
2750 h->type = STT_FUNC;
2752 break;
2753 case R_SCORE_GOT15:
2754 if (h && ! score_elf_record_global_got_symbol (h, abfd, info, g))
2755 return FALSE;
2756 break;
2757 case R_SCORE_ABS32:
2758 case R_SCORE_REL32:
2759 if ((info->shared || h != NULL) && (sec->flags & SEC_ALLOC) != 0)
2761 if (sreloc == NULL)
2763 sreloc = score_elf_rel_dyn_section (dynobj, TRUE);
2764 if (sreloc == NULL)
2765 return FALSE;
2767 #define SCORE_READONLY_SECTION (SEC_ALLOC | SEC_LOAD | SEC_READONLY)
2768 if (info->shared)
2770 /* When creating a shared object, we must copy these reloc types into
2771 the output file as R_SCORE_REL32 relocs. We make room for this reloc
2772 in the .rel.dyn reloc section. */
2773 score_elf_allocate_dynamic_relocations (dynobj, 1);
2774 if ((sec->flags & SCORE_READONLY_SECTION)
2775 == SCORE_READONLY_SECTION)
2776 /* We tell the dynamic linker that there are
2777 relocations against the text segment. */
2778 info->flags |= DF_TEXTREL;
2780 else
2782 struct score_elf_link_hash_entry *hscore;
2784 /* We only need to copy this reloc if the symbol is
2785 defined in a dynamic object. */
2786 hscore = (struct score_elf_link_hash_entry *) h;
2787 ++hscore->possibly_dynamic_relocs;
2788 if ((sec->flags & SCORE_READONLY_SECTION)
2789 == SCORE_READONLY_SECTION)
2790 /* We need it to tell the dynamic linker if there
2791 are relocations against the text segment. */
2792 hscore->readonly_reloc = TRUE;
2795 /* Even though we don't directly need a GOT entry for this symbol,
2796 a symbol must have a dynamic symbol table index greater that
2797 DT_SCORE_GOTSYM if there are dynamic relocations against it. */
2798 if (h != NULL)
2800 if (dynobj == NULL)
2801 elf_hash_table (info)->dynobj = dynobj = abfd;
2802 if (! score_elf_create_got_section (dynobj, info, TRUE))
2803 return FALSE;
2804 g = score_elf_got_info (dynobj, &sgot);
2805 if (! score_elf_record_global_got_symbol (h, abfd, info, g))
2806 return FALSE;
2809 break;
2811 /* This relocation describes the C++ object vtable hierarchy.
2812 Reconstruct it for later use during GC. */
2813 case R_SCORE_GNU_VTINHERIT:
2814 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
2815 return FALSE;
2816 break;
2818 /* This relocation describes which C++ vtable entries are actually
2819 used. Record for later use during GC. */
2820 case R_SCORE_GNU_VTENTRY:
2821 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
2822 return FALSE;
2823 break;
2824 default:
2825 break;
2828 /* We must not create a stub for a symbol that has relocations
2829 related to taking the function's address. */
2830 switch (r_type)
2832 default:
2833 if (h != NULL)
2835 struct score_elf_link_hash_entry *sh;
2837 sh = (struct score_elf_link_hash_entry *) h;
2838 sh->no_fn_stub = TRUE;
2840 break;
2841 case R_SCORE_CALL15:
2842 break;
2846 return TRUE;
2849 bfd_boolean
2850 s7_bfd_score_elf_add_symbol_hook (bfd *abfd,
2851 struct bfd_link_info *info ATTRIBUTE_UNUSED,
2852 Elf_Internal_Sym *sym,
2853 const char **namep ATTRIBUTE_UNUSED,
2854 flagword *flagsp ATTRIBUTE_UNUSED,
2855 asection **secp,
2856 bfd_vma *valp)
2858 switch (sym->st_shndx)
2860 case SHN_COMMON:
2861 if (sym->st_size > elf_gp_size (abfd))
2862 break;
2863 /* Fall through. */
2864 case SHN_SCORE_SCOMMON:
2865 *secp = bfd_make_section_old_way (abfd, ".scommon");
2866 (*secp)->flags |= SEC_IS_COMMON;
2867 *valp = sym->st_size;
2868 break;
2871 return TRUE;
2874 void
2875 s7_bfd_score_elf_symbol_processing (bfd *abfd, asymbol *asym)
2877 elf_symbol_type *elfsym;
2879 elfsym = (elf_symbol_type *) asym;
2880 switch (elfsym->internal_elf_sym.st_shndx)
2882 case SHN_COMMON:
2883 if (asym->value > elf_gp_size (abfd))
2884 break;
2885 /* Fall through. */
2886 case SHN_SCORE_SCOMMON:
2887 if (score_elf_scom_section.name == NULL)
2889 /* Initialize the small common section. */
2890 score_elf_scom_section.name = ".scommon";
2891 score_elf_scom_section.flags = SEC_IS_COMMON;
2892 score_elf_scom_section.output_section = &score_elf_scom_section;
2893 score_elf_scom_section.symbol = &score_elf_scom_symbol;
2894 score_elf_scom_section.symbol_ptr_ptr = &score_elf_scom_symbol_ptr;
2895 score_elf_scom_symbol.name = ".scommon";
2896 score_elf_scom_symbol.flags = BSF_SECTION_SYM;
2897 score_elf_scom_symbol.section = &score_elf_scom_section;
2898 score_elf_scom_symbol_ptr = &score_elf_scom_symbol;
2900 asym->section = &score_elf_scom_section;
2901 asym->value = elfsym->internal_elf_sym.st_size;
2902 break;
2906 bfd_boolean
2907 s7_bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
2908 const char *name ATTRIBUTE_UNUSED,
2909 Elf_Internal_Sym *sym,
2910 asection *input_sec,
2911 struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
2913 /* If we see a common symbol, which implies a relocatable link, then
2914 if a symbol was small common in an input file, mark it as small
2915 common in the output file. */
2916 if (sym->st_shndx == SHN_COMMON && strcmp (input_sec->name, ".scommon") == 0)
2917 sym->st_shndx = SHN_SCORE_SCOMMON;
2919 return TRUE;
2922 bfd_boolean
2923 s7_bfd_score_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
2924 asection *sec,
2925 int *retval)
2927 if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
2929 *retval = SHN_SCORE_SCOMMON;
2930 return TRUE;
2933 return FALSE;
2936 /* Adjust a symbol defined by a dynamic object and referenced by a
2937 regular object. The current definition is in some section of the
2938 dynamic object, but we're not including those sections. We have to
2939 change the definition to something the rest of the link can understand. */
2941 bfd_boolean
2942 s7_bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
2943 struct elf_link_hash_entry *h)
2945 bfd *dynobj;
2946 struct score_elf_link_hash_entry *hscore;
2947 asection *s;
2949 dynobj = elf_hash_table (info)->dynobj;
2951 /* Make sure we know what is going on here. */
2952 BFD_ASSERT (dynobj != NULL
2953 && (h->needs_plt
2954 || h->u.weakdef != NULL
2955 || (h->def_dynamic && h->ref_regular && !h->def_regular)));
2957 /* If this symbol is defined in a dynamic object, we need to copy
2958 any R_SCORE_ABS32 or R_SCORE_REL32 relocs against it into the output
2959 file. */
2960 hscore = (struct score_elf_link_hash_entry *) h;
2961 if (!info->relocatable
2962 && hscore->possibly_dynamic_relocs != 0
2963 && (h->root.type == bfd_link_hash_defweak || !h->def_regular))
2965 score_elf_allocate_dynamic_relocations (dynobj, hscore->possibly_dynamic_relocs);
2966 if (hscore->readonly_reloc)
2967 /* We tell the dynamic linker that there are relocations
2968 against the text segment. */
2969 info->flags |= DF_TEXTREL;
2972 /* For a function, create a stub, if allowed. */
2973 if (!hscore->no_fn_stub && h->needs_plt)
2975 if (!elf_hash_table (info)->dynamic_sections_created)
2976 return TRUE;
2978 /* If this symbol is not defined in a regular file, then set
2979 the symbol to the stub location. This is required to make
2980 function pointers compare as equal between the normal
2981 executable and the shared library. */
2982 if (!h->def_regular)
2984 /* We need .stub section. */
2985 s = bfd_get_section_by_name (dynobj, SCORE_ELF_STUB_SECTION_NAME);
2986 BFD_ASSERT (s != NULL);
2988 h->root.u.def.section = s;
2989 h->root.u.def.value = s->size;
2991 /* XXX Write this stub address somewhere. */
2992 h->plt.offset = s->size;
2994 /* Make room for this stub code. */
2995 s->size += SCORE_FUNCTION_STUB_SIZE;
2997 /* The last half word of the stub will be filled with the index
2998 of this symbol in .dynsym section. */
2999 return TRUE;
3002 else if ((h->type == STT_FUNC) && !h->needs_plt)
3004 /* This will set the entry for this symbol in the GOT to 0, and
3005 the dynamic linker will take care of this. */
3006 h->root.u.def.value = 0;
3007 return TRUE;
3010 /* If this is a weak symbol, and there is a real definition, the
3011 processor independent code will have arranged for us to see the
3012 real definition first, and we can just use the same value. */
3013 if (h->u.weakdef != NULL)
3015 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
3016 || h->u.weakdef->root.type == bfd_link_hash_defweak);
3017 h->root.u.def.section = h->u.weakdef->root.u.def.section;
3018 h->root.u.def.value = h->u.weakdef->root.u.def.value;
3019 return TRUE;
3022 /* This is a reference to a symbol defined by a dynamic object which
3023 is not a function. */
3024 return TRUE;
3027 /* This function is called after all the input files have been read,
3028 and the input sections have been assigned to output sections. */
3030 bfd_boolean
3031 s7_bfd_score_elf_always_size_sections (bfd *output_bfd,
3032 struct bfd_link_info *info)
3034 bfd *dynobj;
3035 asection *s;
3036 struct score_got_info *g;
3037 int i;
3038 bfd_size_type loadable_size = 0;
3039 bfd_size_type local_gotno;
3040 bfd *sub;
3042 dynobj = elf_hash_table (info)->dynobj;
3043 if (dynobj == NULL)
3044 /* Relocatable links don't have it. */
3045 return TRUE;
3047 g = score_elf_got_info (dynobj, &s);
3048 if (s == NULL)
3049 return TRUE;
3051 /* Calculate the total loadable size of the output. That will give us the
3052 maximum number of GOT_PAGE entries required. */
3053 for (sub = info->input_bfds; sub; sub = sub->link_next)
3055 asection *subsection;
3057 for (subsection = sub->sections;
3058 subsection;
3059 subsection = subsection->next)
3061 if ((subsection->flags & SEC_ALLOC) == 0)
3062 continue;
3063 loadable_size += ((subsection->size + 0xf)
3064 &~ (bfd_size_type) 0xf);
3068 /* There has to be a global GOT entry for every symbol with
3069 a dynamic symbol table index of DT_SCORE_GOTSYM or
3070 higher. Therefore, it make sense to put those symbols
3071 that need GOT entries at the end of the symbol table. We
3072 do that here. */
3073 if (! score_elf_sort_hash_table (info, 1))
3074 return FALSE;
3076 if (g->global_gotsym != NULL)
3077 i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx;
3078 else
3079 /* If there are no global symbols, or none requiring
3080 relocations, then GLOBAL_GOTSYM will be NULL. */
3081 i = 0;
3083 /* In the worst case, we'll get one stub per dynamic symbol. */
3084 loadable_size += SCORE_FUNCTION_STUB_SIZE * i;
3086 /* Assume there are two loadable segments consisting of
3087 contiguous sections. Is 5 enough? */
3088 local_gotno = (loadable_size >> 16) + 5;
3090 g->local_gotno += local_gotno;
3091 s->size += g->local_gotno * SCORE_ELF_GOT_SIZE (output_bfd);
3093 g->global_gotno = i;
3094 s->size += i * SCORE_ELF_GOT_SIZE (output_bfd);
3096 score_elf_resolve_final_got_entries (g);
3098 if (s->size > SCORE_ELF_GOT_MAX_SIZE (output_bfd))
3100 /* Fixme. Error message or Warning message should be issued here. */
3103 return TRUE;
3106 /* Set the sizes of the dynamic sections. */
3108 bfd_boolean
3109 s7_bfd_score_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
3111 bfd *dynobj;
3112 asection *s;
3113 bfd_boolean reltext;
3115 dynobj = elf_hash_table (info)->dynobj;
3116 BFD_ASSERT (dynobj != NULL);
3118 if (elf_hash_table (info)->dynamic_sections_created)
3120 /* Set the contents of the .interp section to the interpreter. */
3121 if (!info->shared)
3123 s = bfd_get_section_by_name (dynobj, ".interp");
3124 BFD_ASSERT (s != NULL);
3125 s->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
3126 s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
3130 /* The check_relocs and adjust_dynamic_symbol entry points have
3131 determined the sizes of the various dynamic sections. Allocate
3132 memory for them. */
3133 reltext = FALSE;
3134 for (s = dynobj->sections; s != NULL; s = s->next)
3136 const char *name;
3138 if ((s->flags & SEC_LINKER_CREATED) == 0)
3139 continue;
3141 /* It's OK to base decisions on the section name, because none
3142 of the dynobj section names depend upon the input files. */
3143 name = bfd_get_section_name (dynobj, s);
3145 if (CONST_STRNEQ (name, ".rel"))
3147 if (s->size == 0)
3149 /* We only strip the section if the output section name
3150 has the same name. Otherwise, there might be several
3151 input sections for this output section. FIXME: This
3152 code is probably not needed these days anyhow, since
3153 the linker now does not create empty output sections. */
3154 if (s->output_section != NULL
3155 && strcmp (name,
3156 bfd_get_section_name (s->output_section->owner,
3157 s->output_section)) == 0)
3158 s->flags |= SEC_EXCLUDE;
3160 else
3162 const char *outname;
3163 asection *target;
3165 /* If this relocation section applies to a read only
3166 section, then we probably need a DT_TEXTREL entry.
3167 If the relocation section is .rel.dyn, we always
3168 assert a DT_TEXTREL entry rather than testing whether
3169 there exists a relocation to a read only section or
3170 not. */
3171 outname = bfd_get_section_name (output_bfd, s->output_section);
3172 target = bfd_get_section_by_name (output_bfd, outname + 4);
3173 if ((target != NULL
3174 && (target->flags & SEC_READONLY) != 0
3175 && (target->flags & SEC_ALLOC) != 0) || strcmp (outname, ".rel.dyn") == 0)
3176 reltext = TRUE;
3178 /* We use the reloc_count field as a counter if we need
3179 to copy relocs into the output file. */
3180 if (strcmp (name, ".rel.dyn") != 0)
3181 s->reloc_count = 0;
3184 else if (CONST_STRNEQ (name, ".got"))
3186 /* s7_bfd_score_elf_always_size_sections() has already done
3187 most of the work, but some symbols may have been mapped
3188 to versions that we must now resolve in the got_entries
3189 hash tables. */
3191 else if (strcmp (name, SCORE_ELF_STUB_SECTION_NAME) == 0)
3193 /* IRIX rld assumes that the function stub isn't at the end
3194 of .text section. So put a dummy. XXX */
3195 s->size += SCORE_FUNCTION_STUB_SIZE;
3197 else if (! CONST_STRNEQ (name, ".init"))
3199 /* It's not one of our sections, so don't allocate space. */
3200 continue;
3203 /* Allocate memory for the section contents. */
3204 s->contents = bfd_zalloc (dynobj, s->size);
3205 if (s->contents == NULL && s->size != 0)
3207 bfd_set_error (bfd_error_no_memory);
3208 return FALSE;
3212 if (elf_hash_table (info)->dynamic_sections_created)
3214 /* Add some entries to the .dynamic section. We fill in the
3215 values later, in s7_bfd_score_elf_finish_dynamic_sections, but we
3216 must add the entries now so that we get the correct size for
3217 the .dynamic section. The DT_DEBUG entry is filled in by the
3218 dynamic linker and used by the debugger. */
3220 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0))
3221 return FALSE;
3223 if (reltext)
3224 info->flags |= DF_TEXTREL;
3226 if ((info->flags & DF_TEXTREL) != 0)
3228 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0))
3229 return FALSE;
3232 if (! SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTGOT, 0))
3233 return FALSE;
3235 if (score_elf_rel_dyn_section (dynobj, FALSE))
3237 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_REL, 0))
3238 return FALSE;
3240 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELSZ, 0))
3241 return FALSE;
3243 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELENT, 0))
3244 return FALSE;
3247 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_BASE_ADDRESS, 0))
3248 return FALSE;
3250 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_LOCAL_GOTNO, 0))
3251 return FALSE;
3253 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_SYMTABNO, 0))
3254 return FALSE;
3256 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_UNREFEXTNO, 0))
3257 return FALSE;
3259 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_GOTSYM, 0))
3260 return FALSE;
3262 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_HIPAGENO, 0))
3263 return FALSE;
3266 return TRUE;
3269 bfd_boolean
3270 s7_bfd_score_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
3272 struct elf_link_hash_entry *h;
3273 struct bfd_link_hash_entry *bh;
3274 flagword flags;
3275 asection *s;
3277 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
3278 | SEC_LINKER_CREATED | SEC_READONLY);
3280 /* ABI requests the .dynamic section to be read only. */
3281 s = bfd_get_section_by_name (abfd, ".dynamic");
3282 if (s != NULL)
3284 if (!bfd_set_section_flags (abfd, s, flags))
3285 return FALSE;
3288 /* We need to create .got section. */
3289 if (!score_elf_create_got_section (abfd, info, FALSE))
3290 return FALSE;
3292 if (!score_elf_rel_dyn_section (elf_hash_table (info)->dynobj, TRUE))
3293 return FALSE;
3295 /* Create .stub section. */
3296 if (bfd_get_section_by_name (abfd, SCORE_ELF_STUB_SECTION_NAME) == NULL)
3298 s = bfd_make_section_with_flags (abfd, SCORE_ELF_STUB_SECTION_NAME,
3299 flags | SEC_CODE);
3300 if (s == NULL
3301 || !bfd_set_section_alignment (abfd, s, 2))
3303 return FALSE;
3306 if (!info->shared)
3308 const char *name;
3310 name = "_DYNAMIC_LINK";
3311 bh = NULL;
3312 if (!(_bfd_generic_link_add_one_symbol
3313 (info, abfd, name, BSF_GLOBAL, bfd_abs_section_ptr,
3314 (bfd_vma) 0, NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
3315 return FALSE;
3317 h = (struct elf_link_hash_entry *) bh;
3318 h->non_elf = 0;
3319 h->def_regular = 1;
3320 h->type = STT_SECTION;
3322 if (!bfd_elf_link_record_dynamic_symbol (info, h))
3323 return FALSE;
3326 return TRUE;
3330 /* Finish up dynamic symbol handling. We set the contents of various
3331 dynamic sections here. */
3333 bfd_boolean
3334 s7_bfd_score_elf_finish_dynamic_symbol (bfd *output_bfd,
3335 struct bfd_link_info *info,
3336 struct elf_link_hash_entry *h,
3337 Elf_Internal_Sym *sym)
3339 bfd *dynobj;
3340 asection *sgot;
3341 struct score_got_info *g;
3342 const char *name;
3344 dynobj = elf_hash_table (info)->dynobj;
3346 if (h->plt.offset != MINUS_ONE)
3348 asection *s;
3349 bfd_byte stub[SCORE_FUNCTION_STUB_SIZE];
3351 /* This symbol has a stub. Set it up. */
3352 BFD_ASSERT (h->dynindx != -1);
3354 s = bfd_get_section_by_name (dynobj, SCORE_ELF_STUB_SECTION_NAME);
3355 BFD_ASSERT (s != NULL);
3357 /* FIXME: Can h->dynindex be more than 64K? */
3358 if (h->dynindx & 0xffff0000)
3359 return FALSE;
3361 /* Fill the stub. */
3362 bfd_put_32 (output_bfd, STUB_LW, stub);
3363 bfd_put_32 (output_bfd, STUB_MOVE, stub + 4);
3364 bfd_put_32 (output_bfd, STUB_LI16 | (h->dynindx << 1), stub + 8);
3365 bfd_put_32 (output_bfd, STUB_BRL, stub + 12);
3367 BFD_ASSERT (h->plt.offset <= s->size);
3368 memcpy (s->contents + h->plt.offset, stub, SCORE_FUNCTION_STUB_SIZE);
3370 /* Mark the symbol as undefined. plt.offset != -1 occurs
3371 only for the referenced symbol. */
3372 sym->st_shndx = SHN_UNDEF;
3374 /* The run-time linker uses the st_value field of the symbol
3375 to reset the global offset table entry for this external
3376 to its stub address when unlinking a shared object. */
3377 sym->st_value = (s->output_section->vma + s->output_offset + h->plt.offset);
3380 BFD_ASSERT (h->dynindx != -1 || h->forced_local);
3382 sgot = score_elf_got_section (dynobj, FALSE);
3383 BFD_ASSERT (sgot != NULL);
3384 BFD_ASSERT (score_elf_section_data (sgot) != NULL);
3385 g = score_elf_section_data (sgot)->u.got_info;
3386 BFD_ASSERT (g != NULL);
3388 /* Run through the global symbol table, creating GOT entries for all
3389 the symbols that need them. */
3390 if (g->global_gotsym != NULL && h->dynindx >= g->global_gotsym->dynindx)
3392 bfd_vma offset;
3393 bfd_vma value;
3395 value = sym->st_value;
3396 offset = score_elf_global_got_index (dynobj, h);
3397 bfd_put_32 (output_bfd, value, sgot->contents + offset);
3400 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
3401 name = h->root.root.string;
3402 if (strcmp (name, "_DYNAMIC") == 0 || strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
3403 sym->st_shndx = SHN_ABS;
3404 else if (strcmp (name, "_DYNAMIC_LINK") == 0)
3406 sym->st_shndx = SHN_ABS;
3407 sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
3408 sym->st_value = 1;
3410 else if (strcmp (name, GP_DISP_LABEL) == 0)
3412 sym->st_shndx = SHN_ABS;
3413 sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
3414 sym->st_value = elf_gp (output_bfd);
3417 return TRUE;
3420 /* Finish up the dynamic sections. */
3422 bfd_boolean
3423 s7_bfd_score_elf_finish_dynamic_sections (bfd *output_bfd,
3424 struct bfd_link_info *info)
3426 bfd *dynobj;
3427 asection *sdyn;
3428 asection *sgot;
3429 asection *s;
3430 struct score_got_info *g;
3432 dynobj = elf_hash_table (info)->dynobj;
3434 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
3436 sgot = score_elf_got_section (dynobj, FALSE);
3437 if (sgot == NULL)
3438 g = NULL;
3439 else
3441 BFD_ASSERT (score_elf_section_data (sgot) != NULL);
3442 g = score_elf_section_data (sgot)->u.got_info;
3443 BFD_ASSERT (g != NULL);
3446 if (elf_hash_table (info)->dynamic_sections_created)
3448 bfd_byte *b;
3450 BFD_ASSERT (sdyn != NULL);
3451 BFD_ASSERT (g != NULL);
3453 for (b = sdyn->contents;
3454 b < sdyn->contents + sdyn->size;
3455 b += SCORE_ELF_DYN_SIZE (dynobj))
3457 Elf_Internal_Dyn dyn;
3458 const char *name;
3459 size_t elemsize;
3460 bfd_boolean swap_out_p;
3462 /* Read in the current dynamic entry. */
3463 (*get_elf_backend_data (dynobj)->s->swap_dyn_in) (dynobj, b, &dyn);
3465 /* Assume that we're going to modify it and write it out. */
3466 swap_out_p = TRUE;
3468 switch (dyn.d_tag)
3470 case DT_RELENT:
3471 s = score_elf_rel_dyn_section (dynobj, FALSE);
3472 BFD_ASSERT (s != NULL);
3473 dyn.d_un.d_val = SCORE_ELF_REL_SIZE (dynobj);
3474 break;
3476 case DT_STRSZ:
3477 /* Rewrite DT_STRSZ. */
3478 dyn.d_un.d_val = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
3479 break;
3481 case DT_PLTGOT:
3482 name = ".got";
3483 s = bfd_get_section_by_name (output_bfd, name);
3484 BFD_ASSERT (s != NULL);
3485 dyn.d_un.d_ptr = s->vma;
3486 break;
3488 case DT_SCORE_BASE_ADDRESS:
3489 s = output_bfd->sections;
3490 BFD_ASSERT (s != NULL);
3491 dyn.d_un.d_ptr = s->vma & ~(bfd_vma) 0xffff;
3492 break;
3494 case DT_SCORE_LOCAL_GOTNO:
3495 dyn.d_un.d_val = g->local_gotno;
3496 break;
3498 case DT_SCORE_UNREFEXTNO:
3499 /* The index into the dynamic symbol table which is the
3500 entry of the first external symbol that is not
3501 referenced within the same object. */
3502 dyn.d_un.d_val = bfd_count_sections (output_bfd) + 1;
3503 break;
3505 case DT_SCORE_GOTSYM:
3506 if (g->global_gotsym)
3508 dyn.d_un.d_val = g->global_gotsym->dynindx;
3509 break;
3511 /* In case if we don't have global got symbols we default
3512 to setting DT_SCORE_GOTSYM to the same value as
3513 DT_SCORE_SYMTABNO, so we just fall through. */
3515 case DT_SCORE_SYMTABNO:
3516 name = ".dynsym";
3517 elemsize = SCORE_ELF_SYM_SIZE (output_bfd);
3518 s = bfd_get_section_by_name (output_bfd, name);
3519 BFD_ASSERT (s != NULL);
3521 dyn.d_un.d_val = s->size / elemsize;
3522 break;
3524 case DT_SCORE_HIPAGENO:
3525 dyn.d_un.d_val = g->local_gotno - SCORE_RESERVED_GOTNO;
3526 break;
3528 default:
3529 swap_out_p = FALSE;
3530 break;
3533 if (swap_out_p)
3534 (*get_elf_backend_data (dynobj)->s->swap_dyn_out) (dynobj, &dyn, b);
3538 /* The first entry of the global offset table will be filled at
3539 runtime. The second entry will be used by some runtime loaders.
3540 This isn't the case of IRIX rld. */
3541 if (sgot != NULL && sgot->size > 0)
3543 bfd_put_32 (output_bfd, 0, sgot->contents);
3544 bfd_put_32 (output_bfd, 0x80000000, sgot->contents + SCORE_ELF_GOT_SIZE (output_bfd));
3547 if (sgot != NULL)
3548 elf_section_data (sgot->output_section)->this_hdr.sh_entsize
3549 = SCORE_ELF_GOT_SIZE (output_bfd);
3552 /* We need to sort the entries of the dynamic relocation section. */
3553 s = score_elf_rel_dyn_section (dynobj, FALSE);
3555 if (s != NULL && s->size > (bfd_vma)2 * SCORE_ELF_REL_SIZE (output_bfd))
3557 reldyn_sorting_bfd = output_bfd;
3558 qsort ((Elf32_External_Rel *) s->contents + 1, s->reloc_count - 1,
3559 sizeof (Elf32_External_Rel), score_elf_sort_dynamic_relocs);
3562 return TRUE;
3565 /* This function set up the ELF section header for a BFD section in preparation for writing
3566 it out. This is where the flags and type fields are set for unusual sections. */
3568 bfd_boolean
3569 s7_bfd_score_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
3570 Elf_Internal_Shdr *hdr,
3571 asection *sec)
3573 const char *name;
3575 name = bfd_get_section_name (abfd, sec);
3577 if (strcmp (name, ".got") == 0
3578 || strcmp (name, ".srdata") == 0
3579 || strcmp (name, ".sdata") == 0
3580 || strcmp (name, ".sbss") == 0)
3581 hdr->sh_flags |= SHF_SCORE_GPREL;
3583 return TRUE;
3586 /* This function do additional processing on the ELF section header before writing
3587 it out. This is used to set the flags and type fields for some sections. */
3589 /* assign_file_positions_except_relocs() check section flag and if it is allocatable,
3590 warning message will be issued. backend_fake_section is called before
3591 assign_file_positions_except_relocs(); backend_section_processing after it. so, we
3592 modify section flag there, but not backend_fake_section. */
3594 bfd_boolean
3595 s7_bfd_score_elf_section_processing (bfd *abfd ATTRIBUTE_UNUSED, Elf_Internal_Shdr *hdr)
3597 if (hdr->bfd_section != NULL)
3599 const char *name = bfd_get_section_name (abfd, hdr->bfd_section);
3601 if (strcmp (name, ".sdata") == 0)
3603 hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
3604 hdr->sh_type = SHT_PROGBITS;
3606 else if (strcmp (name, ".sbss") == 0)
3608 hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
3609 hdr->sh_type = SHT_NOBITS;
3611 else if (strcmp (name, ".srdata") == 0)
3613 hdr->sh_flags |= SHF_ALLOC | SHF_SCORE_GPREL;
3614 hdr->sh_type = SHT_PROGBITS;
3618 return TRUE;
3621 bfd_boolean
3622 s7_bfd_score_elf_write_section (bfd *output_bfd, asection *sec, bfd_byte *contents)
3624 bfd_byte *to, *from, *end;
3625 int i;
3627 if (strcmp (sec->name, ".pdr") != 0)
3628 return FALSE;
3630 if (score_elf_section_data (sec)->u.tdata == NULL)
3631 return FALSE;
3633 to = contents;
3634 end = contents + sec->size;
3635 for (from = contents, i = 0; from < end; from += PDR_SIZE, i++)
3637 if ((score_elf_section_data (sec)->u.tdata)[i] == 1)
3638 continue;
3640 if (to != from)
3641 memcpy (to, from, PDR_SIZE);
3643 to += PDR_SIZE;
3645 bfd_set_section_contents (output_bfd, sec->output_section, contents,
3646 (file_ptr) sec->output_offset, sec->size);
3648 return TRUE;
3651 /* Copy data from a SCORE ELF indirect symbol to its direct symbol, hiding the old
3652 indirect symbol. Process additional relocation information. */
3654 void
3655 s7_bfd_score_elf_copy_indirect_symbol (struct bfd_link_info *info,
3656 struct elf_link_hash_entry *dir,
3657 struct elf_link_hash_entry *ind)
3659 struct score_elf_link_hash_entry *dirscore, *indscore;
3661 _bfd_elf_link_hash_copy_indirect (info, dir, ind);
3663 if (ind->root.type != bfd_link_hash_indirect)
3664 return;
3666 dirscore = (struct score_elf_link_hash_entry *) dir;
3667 indscore = (struct score_elf_link_hash_entry *) ind;
3668 dirscore->possibly_dynamic_relocs += indscore->possibly_dynamic_relocs;
3670 if (indscore->readonly_reloc)
3671 dirscore->readonly_reloc = TRUE;
3673 if (indscore->no_fn_stub)
3674 dirscore->no_fn_stub = TRUE;
3677 /* Remove information about discarded functions from other sections which mention them. */
3679 bfd_boolean
3680 s7_bfd_score_elf_discard_info (bfd *abfd,
3681 struct elf_reloc_cookie *cookie,
3682 struct bfd_link_info *info)
3684 asection *o;
3685 bfd_boolean ret = FALSE;
3686 unsigned char *tdata;
3687 size_t i, skip;
3689 o = bfd_get_section_by_name (abfd, ".pdr");
3690 if ((!o) || (o->size == 0) || (o->size % PDR_SIZE != 0)
3691 || (o->output_section != NULL && bfd_is_abs_section (o->output_section)))
3692 return FALSE;
3694 tdata = bfd_zmalloc (o->size / PDR_SIZE);
3695 if (!tdata)
3696 return FALSE;
3698 cookie->rels = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, info->keep_memory);
3699 if (!cookie->rels)
3701 free (tdata);
3702 return FALSE;
3705 cookie->rel = cookie->rels;
3706 cookie->relend = cookie->rels + o->reloc_count;
3708 for (i = 0, skip = 0; i < o->size; i++)
3710 if (bfd_elf_reloc_symbol_deleted_p (i * PDR_SIZE, cookie))
3712 tdata[i] = 1;
3713 skip++;
3717 if (skip != 0)
3719 score_elf_section_data (o)->u.tdata = tdata;
3720 o->size -= skip * PDR_SIZE;
3721 ret = TRUE;
3723 else
3724 free (tdata);
3726 if (!info->keep_memory)
3727 free (cookie->rels);
3729 return ret;
3732 /* Signal that discard_info() has removed the discarded relocations for this section. */
3734 bfd_boolean
3735 s7_bfd_score_elf_ignore_discarded_relocs (asection *sec)
3737 if (strcmp (sec->name, ".pdr") == 0)
3738 return TRUE;
3739 return FALSE;
3742 /* Return the section that should be marked against GC for a given
3743 relocation. */
3745 asection *
3746 s7_bfd_score_elf_gc_mark_hook (asection *sec,
3747 struct bfd_link_info *info,
3748 Elf_Internal_Rela *rel,
3749 struct elf_link_hash_entry *h,
3750 Elf_Internal_Sym *sym)
3752 if (h != NULL)
3753 switch (ELF32_R_TYPE (rel->r_info))
3755 case R_SCORE_GNU_VTINHERIT:
3756 case R_SCORE_GNU_VTENTRY:
3757 return NULL;
3760 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
3763 /* Support for core dump NOTE sections. */
3765 bfd_boolean
3766 s7_bfd_score_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
3768 int offset;
3769 unsigned int raw_size;
3771 switch (note->descsz)
3773 default:
3774 return FALSE;
3775 case 272: /* Linux/Score elf_prstatus */
3777 /* pr_cursig */
3778 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
3780 /* pr_pid */
3781 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
3783 /* pr_reg */
3784 offset = 72;
3786 /* sizeof(elf_gregset_t) */
3787 raw_size = 196;
3789 break;
3792 /* Make a ".reg/999" section. */
3793 return _bfd_elfcore_make_pseudosection (abfd, ".reg", raw_size, note->descpos + offset);
3796 bfd_boolean
3797 s7_bfd_score_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
3799 switch (note->descsz)
3801 default:
3802 return FALSE;
3804 case 128: /* Linux/Score elf_prpsinfo. */
3805 /* pr_fname */
3806 elf_tdata (abfd)->core_program = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
3808 /* pr_psargs */
3809 elf_tdata (abfd)->core_command = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
3810 break;
3813 /* Note that for some reason, a spurious space is tacked
3814 onto the end of the args in some (at least one anyway)
3815 implementations, so strip it off if it exists. */
3818 char *command = elf_tdata (abfd)->core_command;
3819 int n = strlen (command);
3821 if (0 < n && command[n - 1] == ' ')
3822 command[n - 1] = '\0';
3825 return TRUE;
3829 /* Score BFD functions. */
3831 reloc_howto_type *
3832 s7_elf32_score_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
3834 unsigned int i;
3836 for (i = 0; i < ARRAY_SIZE (elf32_score_reloc_map); i++)
3837 if (elf32_score_reloc_map[i].bfd_reloc_val == code)
3838 return &elf32_score_howto_table[elf32_score_reloc_map[i].elf_reloc_val];
3840 return NULL;
3843 /* Create a score elf linker hash table. */
3845 struct bfd_link_hash_table *
3846 s7_elf32_score_link_hash_table_create (bfd *abfd)
3848 struct score_elf_link_hash_table *ret;
3849 bfd_size_type amt = sizeof (struct score_elf_link_hash_table);
3851 ret = bfd_malloc (amt);
3852 if (ret == NULL)
3853 return NULL;
3855 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd, score_elf_link_hash_newfunc,
3856 sizeof (struct score_elf_link_hash_entry)))
3858 free (ret);
3859 return NULL;
3862 return &ret->root.root;
3865 bfd_boolean
3866 s7_elf32_score_print_private_bfd_data (bfd *abfd, void * ptr)
3868 FILE *file = (FILE *) ptr;
3870 BFD_ASSERT (abfd != NULL && ptr != NULL);
3872 /* Print normal ELF private data. */
3873 _bfd_elf_print_private_bfd_data (abfd, ptr);
3875 /* xgettext:c-format */
3876 fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
3877 if (elf_elfheader (abfd)->e_flags & EF_SCORE_PIC)
3879 fprintf (file, _(" [pic]"));
3881 if (elf_elfheader (abfd)->e_flags & EF_SCORE_FIXDEP)
3883 fprintf (file, _(" [fix dep]"));
3885 fputc ('\n', file);
3887 return TRUE;
3890 bfd_boolean
3891 s7_elf32_score_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
3893 flagword in_flags;
3894 flagword out_flags;
3896 if (!_bfd_generic_verify_endian_match (ibfd, obfd))
3897 return FALSE;
3899 in_flags = elf_elfheader (ibfd)->e_flags;
3900 out_flags = elf_elfheader (obfd)->e_flags;
3902 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
3903 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
3904 return TRUE;
3906 in_flags = elf_elfheader (ibfd)->e_flags;
3907 out_flags = elf_elfheader (obfd)->e_flags;
3909 if (! elf_flags_init (obfd))
3911 elf_flags_init (obfd) = TRUE;
3912 elf_elfheader (obfd)->e_flags = in_flags;
3914 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
3915 && bfd_get_arch_info (obfd)->the_default)
3917 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
3920 return TRUE;
3923 if (((in_flags & EF_SCORE_PIC) != 0) != ((out_flags & EF_SCORE_PIC) != 0))
3925 (*_bfd_error_handler) (_("%B: warning: linking PIC files with non-PIC files"), ibfd);
3928 /* Maybe dependency fix compatibility should be checked here. */
3929 return TRUE;
3932 bfd_boolean
3933 s7_elf32_score_new_section_hook (bfd *abfd, asection *sec)
3935 struct _score_elf_section_data *sdata;
3936 bfd_size_type amt = sizeof (*sdata);
3938 sdata = bfd_zalloc (abfd, amt);
3939 if (sdata == NULL)
3940 return FALSE;
3941 sec->used_by_bfd = sdata;
3943 return _bfd_elf_new_section_hook (abfd, sec);
3946 #define elf_backend_omit_section_dynsym \
3947 ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)