1 /* 32-bit ELF support for S+core.
2 Copyright 2009 Free Software Foundation, Inc.
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. */
28 #include "libiberty.h"
30 #include "elf/score.h"
31 #include "elf/common.h"
32 #include "elf/internal.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 \
69 (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \
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. */
81 /* The index of the symbol, as stored in the relocation r_info, if
82 we have a local symbol; -1 otherwise. */
86 /* If abfd == NULL, an address that must be stored in the got. */
88 /* If abfd != NULL && symndx != -1, the addend of the relocation
89 that should be added to the symbol value. */
91 /* If abfd != NULL && symndx == -1, the hash table entry
92 corresponding to a global symbol in the got (or, local, if
94 struct score_elf_link_hash_entry
*h
;
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. */
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
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
;
144 struct score_got_info
*got_info
;
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)
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
,
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
;
228 static bfd_reloc_status_type
229 score_elf_lo16_reloc (bfd
*abfd
,
230 arelent
*reloc_entry
,
231 asymbol
*symbol ATTRIBUTE_UNUSED
,
233 asection
*input_section
,
234 bfd
*output_bfd ATTRIBUTE_UNUSED
,
235 char **error_message ATTRIBUTE_UNUSED
)
237 bfd_vma addend
= 0, offset
= 0;
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
);
258 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
259 dangerous relocation. */
262 score_elf_assign_gp (bfd
*output_bfd
, bfd_vma
*pgp
)
268 /* If we've already figured out what GP will be, just return it. */
269 *pgp
= _bfd_get_gp_value (output_bfd
);
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. */
282 for (i
= 0; i
< count
; i
++, sym
++)
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
);
298 /* Only get the error once. */
300 _bfd_set_gp_value (output_bfd
, *pgp
);
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
,
316 bfd_boolean relocatable
,
317 char **error_message
,
320 if (bfd_is_und_section (symbol
->section
)
324 return bfd_reloc_undefined
;
327 *pgp
= _bfd_get_gp_value (output_bfd
);
330 || (symbol
->flags
& BSF_SECTION_SYM
) != 0))
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
))
341 (char *) _("GP relative relocation when _gp not defined");
342 return bfd_reloc_dangerous
;
349 static bfd_reloc_status_type
350 score_elf_gprel15_with_gp (bfd
*abfd
,
352 arelent
*reloc_entry
,
353 asection
*input_section
,
354 bfd_boolean relocateable
,
356 bfd_vma gp ATTRIBUTE_UNUSED
)
361 if (bfd_is_com_section (symbol
->section
))
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
);
379 reloc_entry
->address
+= input_section
->output_offset
;
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
)
392 if (bfd_is_com_section (symbol
->section
))
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. */
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
);
419 reloc_entry
->addend
= val
;
422 reloc_entry
->address
+= input_section
->output_offset
;
427 static bfd_reloc_status_type
428 score_elf_gprel15_reloc (bfd
*abfd
,
429 arelent
*reloc_entry
,
432 asection
*input_section
,
434 char **error_message
)
436 bfd_boolean relocateable
;
437 bfd_reloc_status_type ret
;
440 if (output_bfd
!= NULL
441 && (symbol
->flags
& BSF_SECTION_SYM
) == 0 && reloc_entry
->addend
== 0)
443 reloc_entry
->address
+= input_section
->output_offset
;
446 if (output_bfd
!= NULL
)
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
)
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
;
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
)
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
)
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
,
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
,
527 asection
*input_section
,
528 bfd
*output_bfd ATTRIBUTE_UNUSED
,
529 char **error_message ATTRIBUTE_UNUSED
)
531 bfd_vma addend
= 0, offset
= 0;
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))
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
);
555 static reloc_howto_type elf32_score_howto_table
[] =
558 HOWTO (R_SCORE_NONE
, /* type */
560 0, /* size (0 = byte, 1 = short, 2 = long) */
562 FALSE
, /* pc_relative */
564 complain_overflow_dont
,/* complain_on_overflow */
565 bfd_elf_generic_reloc
, /* special_function */
566 "R_SCORE_NONE", /* name */
567 FALSE
, /* partial_inplace */
570 FALSE
), /* pcrel_offset */
573 HOWTO (R_SCORE_HI16
, /* type */
575 2, /* size (0 = byte, 1 = short, 2 = long) */
577 FALSE
, /* pc_relative */
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 */
588 HOWTO (R_SCORE_LO16
, /* type */
590 2, /* size (0 = byte, 1 = short, 2 = long) */
592 FALSE
, /* pc_relative */
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 */
603 HOWTO (R_SCORE_BCMP
, /* type */
605 2, /* size (0 = byte, 1 = short, 2 = long) */
607 FALSE
, /* pc_relative */
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 */
619 2, /* size (0 = byte, 1 = short, 2 = long) */
621 FALSE
, /* pc_relative */
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 */
632 HOWTO (R_SCORE_PC19
, /* type */
634 2, /* size (0 = byte, 1 = short, 2 = long) */
636 TRUE
, /* pc_relative */
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 */
647 HOWTO (R_SCORE16_11
, /* type */
649 1, /* size (0 = byte, 1 = short, 2 = long) */
651 FALSE
, /* pc_relative */
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 */
662 HOWTO (R_SCORE16_PC8
, /* type */
664 1, /* size (0 = byte, 1 = short, 2 = long) */
666 TRUE
, /* pc_relative */
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 */
679 2, /* size (0 = byte, 1 = short, 2 = long) */
681 FALSE
, /* pc_relative */
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 */
694 1, /* size (0 = byte, 1 = short, 2 = long) */
696 FALSE
, /* pc_relative */
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 */
707 HOWTO (R_SCORE_DUMMY2
, /* type */
709 2, /* size (0 = byte, 1 = short, 2 = long) */
711 FALSE
, /* pc_relative */
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 */
722 HOWTO (R_SCORE_GP15
, /* type */
724 2, /* size (0 = byte, 1 = short, 2 = long) */
726 FALSE
, /* pc_relative */
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 */
739 2, /* size (0 = byte, 1 = short, 2 = long) */
741 FALSE
, /* pc_relative */
743 complain_overflow_dont
,/* complain_on_overflow */
744 NULL
, /* special_function */
745 "R_SCORE_GNU_VTINHERIT", /* name */
746 FALSE
, /* partial_inplace */
749 FALSE
), /* pcrel_offset */
751 /* GNU extension to record C++ vtable member usage */
752 HOWTO (R_SCORE_GNU_VTENTRY
, /* type */
754 2, /* size (0 = byte, 1 = short, 2 = long) */
756 FALSE
, /* pc_relative */
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 */
764 FALSE
), /* pcrel_offset */
766 /* Reference to global offset table. */
767 HOWTO (R_SCORE_GOT15
, /* type */
769 2, /* size (0 = byte, 1 = short, 2 = long) */
771 FALSE
, /* pc_relative */
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 */
784 2, /* size (0 = byte, 1 = short, 2 = long) */
786 FALSE
, /* pc_relative */
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 */
799 2, /* size (0 = byte, 1 = short, 2 = long) */
801 FALSE
, /* pc_relative */
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 */
814 2, /* size (0 = byte, 1 = short, 2 = long) */
816 FALSE
, /* pc_relative */
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 */
829 2, /* size (0 = byte, 1 = short, 2 = long) */
831 FALSE
, /* pc_relative */
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 */
844 2, /* size (0 = byte, 1 = short, 2 = long) */
846 FALSE
, /* pc_relative */
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
)
891 return addr
+ (addr
>> 32);
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
902 score_elf_got_entry_hash (const void *entry_
)
904 const struct score_got_entry
*entry
= (struct score_got_entry
*) entry_
;
907 + (! entry
->abfd
? score_elf_hash_bfd_vma (entry
->d
.address
)
909 + (entry
->symndx
>= 0 ? score_elf_hash_bfd_vma (entry
->d
.addend
)
910 : entry
->d
.h
->root
.root
.root
.hash
));
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
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)
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
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
++;
955 h
->root
.dynindx
= --hsd
->min_got_dynindx
;
956 hsd
->low
= (struct elf_link_hash_entry
*) h
;
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))
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
)
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
);
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. */
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
;
1007 dynobj
= elf_hash_table (info
)->dynobj
;
1009 g
= score_elf_got_info (dynobj
, 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
,
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
;
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
,
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. */
1052 ret
= bfd_hash_allocate (table
, sizeof (struct score_elf_link_hash_entry
));
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
));
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
)
1087 /* We didn't find it. */
1088 bfd_set_error (bfd_error_bad_value
);
1092 /* This function is called via qsort() to sort the dynamic relocation
1093 entries by increasing r_symndx value. */
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. */
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
;
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
)
1124 if (elf_bad_symtab (input_bfd
) && local_sections
[r_symndx
] != NULL
)
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
)
1143 /* Returns the dynamic relocation section for DYNOBJ. */
1146 score_elf_rel_dyn_section (bfd
*dynobj
, bfd_boolean create_p
)
1148 static const char dname
[] = ".rel.dyn";
1151 sreloc
= bfd_get_section_by_name (dynobj
, dname
);
1152 if (sreloc
== NULL
&& create_p
)
1154 sreloc
= bfd_make_section_with_flags (dynobj
, dname
,
1159 | SEC_LINKER_CREATED
1162 || ! bfd_set_section_alignment (dynobj
, sreloc
,
1163 SCORE_ELF_LOG_FILE_ALIGN (dynobj
)))
1170 score_elf_allocate_dynamic_relocations (bfd
*abfd
, unsigned int n
)
1174 s
= score_elf_rel_dyn_section (abfd
, FALSE
);
1175 BFD_ASSERT (s
!= NULL
);
1179 /* Make room for a null element. */
1180 s
->size
+= SCORE_ELF_REL_SIZE (abfd
);
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. */
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
,
1197 bfd_vma
*addendp
, asection
*input_section
)
1199 Elf_Internal_Rela outrel
[3];
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. */
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. */
1233 /* We must now calculate the dynamic symbol table index to use
1234 in the relocation. */
1236 && (! info
->symbolic
|| !h
->root
.def_regular
)
1237 /* h->root.dynindx may be -1 if this symbol was marked to
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. */
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
)
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
;
1307 score_elf_create_got_section (bfd
*abfd
,
1308 struct bfd_link_info
*info
,
1309 bfd_boolean maybe_exclude
)
1313 struct elf_link_hash_entry
*h
;
1314 struct bfd_link_hash_entry
*bh
;
1315 struct score_got_info
*g
;
1318 /* This function may be called more than once. */
1319 s
= score_elf_got_section (abfd
, TRUE
);
1322 if (! maybe_exclude
)
1323 s
->flags
&= ~SEC_EXCLUDE
;
1327 flags
= (SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
| SEC_IN_MEMORY
| SEC_LINKER_CREATED
);
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
);
1336 || ! bfd_set_section_alignment (abfd
, s
, 4))
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. */
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
)))
1348 h
= (struct elf_link_hash_entry
*) bh
;
1351 h
->type
= STT_OBJECT
;
1353 if (info
->shared
&& ! bfd_elf_link_record_dynamic_symbol (info
, h
))
1356 amt
= sizeof (struct score_got_info
);
1357 g
= bfd_alloc (abfd
, amt
);
1361 g
->global_gotsym
= NULL
;
1362 g
->global_gotno
= 0;
1364 g
->local_gotno
= SCORE_RESERVED_GOTNO
;
1365 g
->assigned_gotno
= SCORE_RESERVED_GOTNO
;
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
)
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
;
1378 /* Calculate the %high function. */
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
;
1403 entry
.d
.address
= value
;
1406 loc
= (struct score_got_entry
**) htab_find_slot (g
->got_entries
, &entry
, INSERT
);
1410 entry
.gotidx
= SCORE_ELF_GOT_SIZE (abfd
) * g
->assigned_gotno
++;
1412 *loc
= bfd_alloc (abfd
, sizeof entry
);
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
);
1429 bfd_put_32 (abfd
, value
, (sgot
->contents
+ entry
.gotidx
));
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. */
1438 score_elf_got16_entry (bfd
*abfd
, bfd
*ibfd
, struct bfd_link_info
*info
,
1439 bfd_vma value
, bfd_boolean external
)
1442 struct score_got_info
*g
;
1443 struct score_got_entry
*entry
;
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
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
,
1459 return entry
->gotidx
;
1465 s7_bfd_score_elf_hide_symbol (struct bfd_link_info
*info
,
1466 struct elf_link_hash_entry
*entry
,
1467 bfd_boolean force_local
)
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
)
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
);
1485 g
= score_elf_section_data (got
)->u
.got_info
;
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. */
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);
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
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
1529 BFD_ASSERT (g
->global_gotno
> 0);
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
1543 score_elf_record_global_got_symbol (struct elf_link_hash_entry
*h
,
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
))
1557 s7_bfd_score_elf_hide_symbol (info
, h
, TRUE
);
1560 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
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. */
1575 *loc
= bfd_alloc (abfd
, sizeof entry
);
1581 memcpy (*loc
, &entry
, sizeof (entry
));
1583 if (h
->got
.offset
!= MINUS_ONE
)
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. */
1594 /* Reserve space in G for a GOT entry containing the value of symbol
1595 SYMNDX in input bfd ABDF, plus ADDEND. */
1598 score_elf_record_local_got_symbol (bfd
*abfd
,
1601 struct score_got_info
*g
)
1603 struct score_got_entry entry
, **loc
;
1606 entry
.symndx
= symndx
;
1607 entry
.d
.addend
= addend
;
1608 loc
= (struct score_got_entry
**) htab_find_slot (g
->got_entries
, &entry
, INSERT
);
1613 entry
.gotidx
= g
->local_gotno
++;
1615 *loc
= bfd_alloc (abfd
, sizeof(entry
));
1619 memcpy (*loc
, &entry
, sizeof (entry
));
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. */
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
)
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
);
1645 return entry
->gotidx
;
1648 /* Returns the GOT index for the global symbol indicated by H. */
1651 score_elf_global_got_index (bfd
*abfd
, struct elf_link_hash_entry
*h
)
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
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
);
1673 /* Returns the offset for the entry at the INDEXth position in the GOT. */
1676 score_elf_got_offset_from_index (bfd
*dynobj
, bfd
*output_bfd
,
1677 bfd
*input_bfd ATTRIBUTE_UNUSED
, bfd_vma index
)
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. */
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
)
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
);
1723 /* Abort the traversal, since the whole table may have
1724 moved, and leave it up to the parent to restart the
1726 *(htab_t
*) p
= NULL
;
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. */
1736 /* Turn indirect got entries in a got_entries table into their final locations. */
1739 score_elf_resolve_final_got_entries (struct score_got_info
*g
)
1745 got_entries
= g
->got_entries
;
1747 htab_traverse (got_entries
,
1748 score_elf_resolve_final_got_entry
,
1751 while (got_entries
== NULL
);
1754 /* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS. for -r */
1757 score_elf_add_to_rel (bfd
*abfd
,
1759 reloc_howto_type
*howto
,
1760 bfd_signed_vma increment
)
1762 bfd_signed_vma addend
;
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
;
1776 mask
&= ~howto
->src_mask
;
1779 /* Add in the increment, (which is a byte value). */
1784 (((contents
& howto
->src_mask
) & 0x3ff0000) >> 6) | ((contents
& howto
->src_mask
) & 0x3ff);
1785 offset
+= increment
;
1787 (contents
& ~howto
->
1788 src_mask
) | (((offset
<< 6) & howto
->src_mask
) & 0x3ff0000) | (offset
& 0x3ff);
1789 bfd_put_32 (abfd
, contents
, address
);
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
);
1809 (((contents
& howto
->src_mask
) >> 1) & 0x1ff8000) | ((contents
& howto
->src_mask
) & 0x7fff);
1810 offset
+= increment
;
1812 (contents
& ~howto
->
1813 src_mask
) | (((offset
<< 1) & howto
->src_mask
) & 0x3ff0000) | (offset
& 0x7fff);
1814 bfd_put_32 (abfd
, contents
, address
);
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
);
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
);
1834 case R_SCORE_GOT_LO16
:
1838 addend
+= increment
;
1839 contents
= (contents
& ~howto
->dst_mask
) | (addend
& howto
->dst_mask
);
1840 bfd_put_32 (abfd
, contents
, address
);
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
,
1851 asection
*input_section
,
1853 Elf_Internal_Rela
*rel
,
1854 Elf_Internal_Rela
*relocs
,
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
;
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. */
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
;
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
)
1903 /* Find the GP-relative section with the lowest offset. */
1904 for (o
= output_bfd
->sections
; o
!= NULL
; o
= o
->next
)
1907 /* And calculate GP relative to that. */
1908 elf_gp (output_bfd
) = lo
+ ELF_SCORE_GP_OFFSET (input_bfd
);
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
);
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
)
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
))
1952 tmp
= bfd_get_32 (input_bfd
, contents
+ lo16_rel
->r_offset
);
1953 lo_value
= (((tmp
>> 16) & 0x3) << 14) | ((tmp
& 0x7fff) >> 1);
1956 asection
*msec
= sec
;
1957 lo_value
= _bfd_elf_rel_local_sym (output_bfd
, sym
, &msec
, lo_value
);
1959 lo_value
+= msec
->output_section
->vma
+ msec
->output_offset
;
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
))
1990 tmp
= bfd_get_32 (input_bfd
, contents
+ lo16_rel
->r_offset
);
1991 lo_value
= (((tmp
>> 16) & 0x3) << 14) | ((tmp
& 0x7fff) >> 1);
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. */
2005 case R_SCORE_CALL15
:
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
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. */
2032 g
= score_elf_local_got_index (output_bfd
, input_bfd
, info
,
2033 symbol
+ addend
, r_symndx
, h
, r_type
);
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
);
2045 case R_SCORE_GPREL32
:
2046 gp0
= _bfd_get_gp_value (input_bfd
);
2047 gp
= _bfd_get_gp_value (output_bfd
);
2051 gp
= _bfd_get_gp_value (output_bfd
);
2060 return bfd_reloc_ok
;
2065 || (elf_hash_table (info
)->dynamic_sections_created
2067 && h
->root
.def_dynamic
2068 && !h
->root
.def_regular
))
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. */
2077 if (!score_elf_create_dynamic_relocation (output_bfd
, info
, rel
, h
,
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
2089 if (r_type
!= R_SCORE_REL32
)
2090 value
= symbol
+ addend
;
2094 value
&= howto
->dst_mask
;
2095 bfd_put_32 (input_bfd
, value
, hit_data
);
2096 return bfd_reloc_ok
;
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
;
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;
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
;
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
;
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;
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
;
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
;
2158 addend
= (addend
& ~howto
->src_mask
) | (value
& howto
->src_mask
);
2159 bfd_put_16 (input_bfd
, addend
, hit_data
);
2160 return bfd_reloc_ok
;
2163 return bfd_reloc_ok
;
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);
2173 uvalue
= value
+ offset
;
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
;
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
;
2199 case R_SCORE_CALL15
:
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
);
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);
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
;
2253 return bfd_reloc_notsupported
;
2257 /* Score backend functions. */
2260 s7_bfd_score_info_to_howto (bfd
*abfd ATTRIBUTE_UNUSED
,
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
;
2270 bfd_reloc
->howto
= &elf32_score_howto_table
[r_type
];
2273 /* Relocate an score ELF section. */
2276 s7_bfd_score_elf_relocate_section (bfd
*output_bfd
,
2277 struct bfd_link_info
*info
,
2279 asection
*input_section
,
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
;
2290 unsigned long offset
;
2291 unsigned long hi16_addend
, hi16_offset
, hi16_value
, uvalue
;
2293 bfd_boolean gp_disp_p
= FALSE
;
2296 if (elf_hash_table (info
)->dynamic_sections_created
)
2298 bfd_size_type dynsecsymcount
= 0;
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
))
2311 if (!score_elf_sort_hash_table (info
, dynsecsymcount
+ 1))
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
);
2319 relend
= relocs
+ input_section
->reloc_count
;
2320 for (; rel
< relend
; rel
++)
2323 reloc_howto_type
*howto
;
2324 unsigned long r_symndx
;
2325 Elf_Internal_Sym
*sym
;
2327 struct score_elf_link_hash_entry
*h
;
2328 bfd_vma relocation
= 0;
2329 bfd_reloc_status_type r
;
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
;
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
)
2361 bfd_vma addend
, value
;
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);
2374 addend
= _bfd_elf_rel_local_sym (output_bfd
, sym
, &msec
, addend
);
2375 addend
-= relocation
;
2376 addend
+= msec
->output_section
->vma
+ msec
->output_offset
;
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
);
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);
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
);
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
;
2407 mask
&= ~howto
->src_mask
;
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
);
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
;
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
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
);
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. */
2468 else if (info
->unresolved_syms_in_objects
== RM_IGNORE
2469 && ELF_ST_VISIBILITY (h
->root
.other
) == STV_DEFAULT
)
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
);
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
;
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
);
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);
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
));
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;
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
))))
2584 case bfd_reloc_undefined
:
2585 if (!((*info
->callbacks
->undefined_symbol
)
2586 (info
, name
, input_bfd
, input_section
, rel
->r_offset
, TRUE
)))
2590 case bfd_reloc_outofrange
:
2591 msg
= _("internal error: out of range error");
2594 case bfd_reloc_notsupported
:
2595 msg
= _("internal error: unsupported relocation error");
2598 case bfd_reloc_dangerous
:
2599 msg
= _("internal error: dangerous error");
2603 msg
= _("internal error: unknown error");
2607 if (!((*info
->callbacks
->warning
)
2608 (info
, msg
, name
, input_bfd
, input_section
, rel
->r_offset
)))
2618 /* Look through the relocs for a section during the first phase, and
2619 allocate space in the global offset table. */
2622 s7_bfd_score_elf_check_relocs (bfd
*abfd
,
2623 struct bfd_link_info
*info
,
2625 const Elf_Internal_Rela
*relocs
)
2629 Elf_Internal_Shdr
*symtab_hdr
;
2630 struct elf_link_hash_entry
**sym_hashes
;
2631 struct score_got_info
*g
;
2633 const Elf_Internal_Rela
*rel
;
2634 const Elf_Internal_Rela
*rel_end
;
2637 const struct elf_backend_data
*bed
;
2639 if (info
->relocatable
)
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
);
2656 sgot
= score_elf_got_section (dynobj
, FALSE
);
2661 BFD_ASSERT (score_elf_section_data (sgot
) != NULL
);
2662 g
= score_elf_section_data (sgot
)->u
.got_info
;
2663 BFD_ASSERT (g
!= 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
)
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
);
2691 h
= sym_hashes
[r_symndx
- extsymoff
];
2693 /* This may be an indirect symbol created because of a version. */
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
)
2707 case R_SCORE_CALL15
:
2709 elf_hash_table (info
)->dynobj
= dynobj
= abfd
;
2710 if (!score_elf_create_got_section (dynobj
, info
, FALSE
))
2712 g
= score_elf_got_info (dynobj
, &sgot
);
2716 if (dynobj
== NULL
&& (info
->shared
|| h
!= NULL
) && (sec
->flags
& SEC_ALLOC
) != 0)
2717 elf_hash_table (info
)->dynobj
= dynobj
= abfd
;
2724 if (!h
&& (r_type
== R_SCORE_GOT_LO16
))
2726 if (! score_elf_record_local_got_symbol (abfd
, r_symndx
, rel
->r_addend
, g
))
2732 case R_SCORE_CALL15
:
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
);
2743 /* This symbol requires a global offset table entry. */
2744 if (! score_elf_record_global_got_symbol (h
, abfd
, info
, g
))
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. */
2754 if (h
&& ! score_elf_record_global_got_symbol (h
, abfd
, info
, g
))
2759 if ((info
->shared
|| h
!= NULL
) && (sec
->flags
& SEC_ALLOC
) != 0)
2763 sreloc
= score_elf_rel_dyn_section (dynobj
, TRUE
);
2767 #define SCORE_READONLY_SECTION (SEC_ALLOC | SEC_LOAD | SEC_READONLY)
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
;
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. */
2801 elf_hash_table (info
)->dynobj
= dynobj
= abfd
;
2802 if (! score_elf_create_got_section (dynobj
, info
, TRUE
))
2804 g
= score_elf_got_info (dynobj
, &sgot
);
2805 if (! score_elf_record_global_got_symbol (h
, abfd
, info
, g
))
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
))
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
))
2828 /* We must not create a stub for a symbol that has relocations
2829 related to taking the function's address. */
2835 struct score_elf_link_hash_entry
*sh
;
2837 sh
= (struct score_elf_link_hash_entry
*) h
;
2838 sh
->no_fn_stub
= TRUE
;
2841 case R_SCORE_CALL15
:
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
,
2858 switch (sym
->st_shndx
)
2861 if (sym
->st_size
> elf_gp_size (abfd
))
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
;
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
)
2883 if (asym
->value
> elf_gp_size (abfd
))
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
;
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
;
2923 s7_bfd_score_elf_section_from_bfd_section (bfd
*abfd ATTRIBUTE_UNUSED
,
2927 if (strcmp (bfd_get_section_name (abfd
, sec
), ".scommon") == 0)
2929 *retval
= SHN_SCORE_SCOMMON
;
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. */
2942 s7_bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info
*info
,
2943 struct elf_link_hash_entry
*h
)
2946 struct score_elf_link_hash_entry
*hscore
;
2949 dynobj
= elf_hash_table (info
)->dynobj
;
2951 /* Make sure we know what is going on here. */
2952 BFD_ASSERT (dynobj
!= NULL
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
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
)
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. */
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;
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
;
3022 /* This is a reference to a symbol defined by a dynamic object which
3023 is not a function. */
3027 /* This function is called after all the input files have been read,
3028 and the input sections have been assigned to output sections. */
3031 s7_bfd_score_elf_always_size_sections (bfd
*output_bfd
,
3032 struct bfd_link_info
*info
)
3036 struct score_got_info
*g
;
3038 bfd_size_type loadable_size
= 0;
3039 bfd_size_type local_gotno
;
3042 dynobj
= elf_hash_table (info
)->dynobj
;
3044 /* Relocatable links don't have it. */
3047 g
= score_elf_got_info (dynobj
, &s
);
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
;
3059 subsection
= subsection
->next
)
3061 if ((subsection
->flags
& SEC_ALLOC
) == 0)
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
3073 if (! score_elf_sort_hash_table (info
, 1))
3076 if (g
->global_gotsym
!= NULL
)
3077 i
= elf_hash_table (info
)->dynsymcount
- g
->global_gotsym
->dynindx
;
3079 /* If there are no global symbols, or none requiring
3080 relocations, then GLOBAL_GOTSYM will be NULL. */
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. */
3106 /* Set the sizes of the dynamic sections. */
3109 s7_bfd_score_elf_size_dynamic_sections (bfd
*output_bfd
, struct bfd_link_info
*info
)
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. */
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
3134 for (s
= dynobj
->sections
; s
!= NULL
; s
= s
->next
)
3138 if ((s
->flags
& SEC_LINKER_CREATED
) == 0)
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"))
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
3156 bfd_get_section_name (s
->output_section
->owner
,
3157 s
->output_section
)) == 0)
3158 s
->flags
|= SEC_EXCLUDE
;
3162 const char *outname
;
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
3171 outname
= bfd_get_section_name (output_bfd
, s
->output_section
);
3172 target
= bfd_get_section_by_name (output_bfd
, outname
+ 4);
3174 && (target
->flags
& SEC_READONLY
) != 0
3175 && (target
->flags
& SEC_ALLOC
) != 0) || strcmp (outname
, ".rel.dyn") == 0)
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)
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
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. */
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
);
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))
3224 info
->flags
|= DF_TEXTREL
;
3226 if ((info
->flags
& DF_TEXTREL
) != 0)
3228 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info
, DT_TEXTREL
, 0))
3232 if (! SCORE_ELF_ADD_DYNAMIC_ENTRY (info
, DT_PLTGOT
, 0))
3235 if (score_elf_rel_dyn_section (dynobj
, FALSE
))
3237 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info
, DT_REL
, 0))
3240 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info
, DT_RELSZ
, 0))
3243 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info
, DT_RELENT
, 0))
3247 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info
, DT_SCORE_BASE_ADDRESS
, 0))
3250 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info
, DT_SCORE_LOCAL_GOTNO
, 0))
3253 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info
, DT_SCORE_SYMTABNO
, 0))
3256 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info
, DT_SCORE_UNREFEXTNO
, 0))
3259 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info
, DT_SCORE_GOTSYM
, 0))
3262 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info
, DT_SCORE_HIPAGENO
, 0))
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
;
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");
3284 if (!bfd_set_section_flags (abfd
, s
, flags
))
3288 /* We need to create .got section. */
3289 if (!score_elf_create_got_section (abfd
, info
, FALSE
))
3292 if (!score_elf_rel_dyn_section (elf_hash_table (info
)->dynobj
, TRUE
))
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
,
3301 || !bfd_set_section_alignment (abfd
, s
, 2))
3310 name
= "_DYNAMIC_LINK";
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
)))
3317 h
= (struct elf_link_hash_entry
*) bh
;
3320 h
->type
= STT_SECTION
;
3322 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
3330 /* Finish up dynamic symbol handling. We set the contents of various
3331 dynamic sections here. */
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
)
3341 struct score_got_info
*g
;
3344 dynobj
= elf_hash_table (info
)->dynobj
;
3346 if (h
->plt
.offset
!= MINUS_ONE
)
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)
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
)
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
);
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
);
3420 /* Finish up the dynamic sections. */
3423 s7_bfd_score_elf_finish_dynamic_sections (bfd
*output_bfd
,
3424 struct bfd_link_info
*info
)
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
);
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
)
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
;
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. */
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
);
3477 /* Rewrite DT_STRSZ. */
3478 dyn
.d_un
.d_val
= _bfd_elf_strtab_size (elf_hash_table (info
)->dynstr
);
3483 s
= bfd_get_section_by_name (output_bfd
, name
);
3484 BFD_ASSERT (s
!= NULL
);
3485 dyn
.d_un
.d_ptr
= s
->vma
;
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;
3494 case DT_SCORE_LOCAL_GOTNO
:
3495 dyn
.d_un
.d_val
= g
->local_gotno
;
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;
3505 case DT_SCORE_GOTSYM
:
3506 if (g
->global_gotsym
)
3508 dyn
.d_un
.d_val
= g
->global_gotsym
->dynindx
;
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
:
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
;
3524 case DT_SCORE_HIPAGENO
:
3525 dyn
.d_un
.d_val
= g
->local_gotno
- SCORE_RESERVED_GOTNO
;
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
));
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
);
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. */
3569 s7_bfd_score_elf_fake_sections (bfd
*abfd ATTRIBUTE_UNUSED
,
3570 Elf_Internal_Shdr
*hdr
,
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
;
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. */
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
;
3622 s7_bfd_score_elf_write_section (bfd
*output_bfd
, asection
*sec
, bfd_byte
*contents
)
3624 bfd_byte
*to
, *from
, *end
;
3627 if (strcmp (sec
->name
, ".pdr") != 0)
3630 if (score_elf_section_data (sec
)->u
.tdata
== NULL
)
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)
3641 memcpy (to
, from
, PDR_SIZE
);
3645 bfd_set_section_contents (output_bfd
, sec
->output_section
, contents
,
3646 (file_ptr
) sec
->output_offset
, sec
->size
);
3651 /* Copy data from a SCORE ELF indirect symbol to its direct symbol, hiding the old
3652 indirect symbol. Process additional relocation information. */
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
)
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. */
3680 s7_bfd_score_elf_discard_info (bfd
*abfd
,
3681 struct elf_reloc_cookie
*cookie
,
3682 struct bfd_link_info
*info
)
3685 bfd_boolean ret
= FALSE
;
3686 unsigned char *tdata
;
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
)))
3694 tdata
= bfd_zmalloc (o
->size
/ PDR_SIZE
);
3698 cookie
->rels
= _bfd_elf_link_read_relocs (abfd
, o
, NULL
, NULL
, info
->keep_memory
);
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
))
3719 score_elf_section_data (o
)->u
.tdata
= tdata
;
3720 o
->size
-= skip
* PDR_SIZE
;
3726 if (!info
->keep_memory
)
3727 free (cookie
->rels
);
3732 /* Signal that discard_info() has removed the discarded relocations for this section. */
3735 s7_bfd_score_elf_ignore_discarded_relocs (asection
*sec
)
3737 if (strcmp (sec
->name
, ".pdr") == 0)
3742 /* Return the section that should be marked against GC for a given
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
)
3753 switch (ELF32_R_TYPE (rel
->r_info
))
3755 case R_SCORE_GNU_VTINHERIT
:
3756 case R_SCORE_GNU_VTENTRY
:
3760 return _bfd_elf_gc_mark_hook (sec
, info
, rel
, h
, sym
);
3763 /* Support for core dump NOTE sections. */
3766 s7_bfd_score_elf_grok_prstatus (bfd
*abfd
, Elf_Internal_Note
*note
)
3769 unsigned int raw_size
;
3771 switch (note
->descsz
)
3775 case 272: /* Linux/Score elf_prstatus */
3778 elf_tdata (abfd
)->core_signal
= bfd_get_16 (abfd
, note
->descdata
+ 12);
3781 elf_tdata (abfd
)->core_pid
= bfd_get_32 (abfd
, note
->descdata
+ 24);
3786 /* sizeof(elf_gregset_t) */
3792 /* Make a ".reg/999" section. */
3793 return _bfd_elfcore_make_pseudosection (abfd
, ".reg", raw_size
, note
->descpos
+ offset
);
3797 s7_bfd_score_elf_grok_psinfo (bfd
*abfd
, Elf_Internal_Note
*note
)
3799 switch (note
->descsz
)
3804 case 128: /* Linux/Score elf_prpsinfo. */
3806 elf_tdata (abfd
)->core_program
= _bfd_elfcore_strndup (abfd
, note
->descdata
+ 32, 16);
3809 elf_tdata (abfd
)->core_command
= _bfd_elfcore_strndup (abfd
, note
->descdata
+ 48, 80);
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';
3829 /* Score BFD functions. */
3832 s7_elf32_score_reloc_type_lookup (bfd
*abfd ATTRIBUTE_UNUSED
, bfd_reloc_code_real_type code
)
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
];
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
);
3855 if (!_bfd_elf_link_hash_table_init (&ret
->root
, abfd
, score_elf_link_hash_newfunc
,
3856 sizeof (struct score_elf_link_hash_entry
)))
3862 return &ret
->root
.root
;
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]"));
3891 s7_elf32_score_merge_private_bfd_data (bfd
*ibfd
, bfd
*obfd
)
3896 if (!_bfd_generic_verify_endian_match (ibfd
, obfd
))
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
)
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
));
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. */
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
);
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)