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 got_index
= ((h
->dynindx
- global_got_dynindx
+ g
->local_gotno
) * SCORE_ELF_GOT_SIZE (abfd
));
1668 BFD_ASSERT (got_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
,
1678 bfd
*input_bfd ATTRIBUTE_UNUSED
,
1683 struct score_got_info
*g
;
1685 g
= score_elf_got_info (dynobj
, &sgot
);
1686 gp
= _bfd_get_gp_value (output_bfd
);
1688 return sgot
->output_section
->vma
+ sgot
->output_offset
+ got_index
- gp
;
1691 /* Follow indirect and warning hash entries so that each got entry
1692 points to the final symbol definition. P must point to a pointer
1693 to the hash table we're traversing. Since this traversal may
1694 modify the hash table, we set this pointer to NULL to indicate
1695 we've made a potentially-destructive change to the hash table, so
1696 the traversal must be restarted. */
1699 score_elf_resolve_final_got_entry (void **entryp
, void *p
)
1701 struct score_got_entry
*entry
= (struct score_got_entry
*) *entryp
;
1702 htab_t got_entries
= *(htab_t
*) p
;
1704 if (entry
->abfd
!= NULL
&& entry
->symndx
== -1)
1706 struct score_elf_link_hash_entry
*h
= entry
->d
.h
;
1708 while (h
->root
.root
.type
== bfd_link_hash_indirect
1709 || h
->root
.root
.type
== bfd_link_hash_warning
)
1710 h
= (struct score_elf_link_hash_entry
*) h
->root
.root
.u
.i
.link
;
1712 if (entry
->d
.h
== h
)
1717 /* If we can't find this entry with the new bfd hash, re-insert
1718 it, and get the traversal restarted. */
1719 if (! htab_find (got_entries
, entry
))
1721 htab_clear_slot (got_entries
, entryp
);
1722 entryp
= htab_find_slot (got_entries
, entry
, INSERT
);
1725 /* Abort the traversal, since the whole table may have
1726 moved, and leave it up to the parent to restart the
1728 *(htab_t
*) p
= NULL
;
1731 /* We might want to decrement the global_gotno count, but it's
1732 either too early or too late for that at this point. */
1738 /* Turn indirect got entries in a got_entries table into their final locations. */
1741 score_elf_resolve_final_got_entries (struct score_got_info
*g
)
1747 got_entries
= g
->got_entries
;
1749 htab_traverse (got_entries
,
1750 score_elf_resolve_final_got_entry
,
1753 while (got_entries
== NULL
);
1756 /* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS. for -r */
1759 score_elf_add_to_rel (bfd
*abfd
,
1761 reloc_howto_type
*howto
,
1762 bfd_signed_vma increment
)
1764 bfd_signed_vma addend
;
1766 unsigned long offset
;
1767 unsigned long r_type
= howto
->type
;
1768 unsigned long hi16_addend
, hi16_offset
, hi16_value
, uvalue
;
1770 contents
= bfd_get_32 (abfd
, address
);
1771 /* Get the (signed) value from the instruction. */
1772 addend
= contents
& howto
->src_mask
;
1773 if (addend
& ((howto
->src_mask
+ 1) >> 1))
1775 bfd_signed_vma mask
;
1778 mask
&= ~howto
->src_mask
;
1781 /* Add in the increment, (which is a byte value). */
1786 (((contents
& howto
->src_mask
) & 0x3ff0000) >> 6) | ((contents
& howto
->src_mask
) & 0x3ff);
1787 offset
+= increment
;
1789 (contents
& ~howto
->
1790 src_mask
) | (((offset
<< 6) & howto
->src_mask
) & 0x3ff0000) | (offset
& 0x3ff);
1791 bfd_put_32 (abfd
, contents
, address
);
1796 hi16_addend
= bfd_get_32 (abfd
, address
- 4);
1797 hi16_offset
= ((((hi16_addend
>> 16) & 0x3) << 15) | (hi16_addend
& 0x7fff)) >> 1;
1798 offset
= ((((contents
>> 16) & 0x3) << 15) | (contents
& 0x7fff)) >> 1;
1799 offset
= (hi16_offset
<< 16) | (offset
& 0xffff);
1800 uvalue
= increment
+ offset
;
1801 hi16_offset
= (uvalue
>> 16) << 1;
1802 hi16_value
= (hi16_addend
& (~(howto
->dst_mask
)))
1803 | (hi16_offset
& 0x7fff) | ((hi16_offset
<< 1) & 0x30000);
1804 bfd_put_32 (abfd
, hi16_value
, address
- 4);
1805 offset
= (uvalue
& 0xffff) << 1;
1806 contents
= (contents
& (~(howto
->dst_mask
))) | (offset
& 0x7fff) | ((offset
<< 1) & 0x30000);
1807 bfd_put_32 (abfd
, contents
, address
);
1811 (((contents
& howto
->src_mask
) >> 1) & 0x1ff8000) | ((contents
& howto
->src_mask
) & 0x7fff);
1812 offset
+= increment
;
1814 (contents
& ~howto
->
1815 src_mask
) | (((offset
<< 1) & howto
->src_mask
) & 0x3ff0000) | (offset
& 0x7fff);
1816 bfd_put_32 (abfd
, contents
, address
);
1820 contents
= bfd_get_16 (abfd
, address
);
1821 offset
= contents
& howto
->src_mask
;
1822 offset
+= increment
;
1823 contents
= (contents
& ~howto
->src_mask
) | (offset
& howto
->src_mask
);
1824 bfd_put_16 (abfd
, contents
, address
);
1829 contents
= bfd_get_16 (abfd
, address
);
1830 offset
= (contents
& howto
->src_mask
) + ((increment
>> 1) & 0xff);
1831 contents
= (contents
& (~howto
->src_mask
)) | (offset
& howto
->src_mask
);
1832 bfd_put_16 (abfd
, contents
, address
);
1836 case R_SCORE_GOT_LO16
:
1840 addend
+= increment
;
1841 contents
= (contents
& ~howto
->dst_mask
) | (addend
& howto
->dst_mask
);
1842 bfd_put_32 (abfd
, contents
, address
);
1847 /* Perform a relocation as part of a final link. */
1849 static bfd_reloc_status_type
1850 score_elf_final_link_relocate (reloc_howto_type
*howto
,
1853 asection
*input_section
,
1855 Elf_Internal_Rela
*rel
,
1856 Elf_Internal_Rela
*relocs
,
1858 struct bfd_link_info
*info
,
1859 const char *sym_name ATTRIBUTE_UNUSED
,
1860 int sym_flags ATTRIBUTE_UNUSED
,
1861 struct score_elf_link_hash_entry
*h
,
1862 Elf_Internal_Sym
*local_syms
,
1863 asection
**local_sections
,
1864 bfd_boolean gp_disp_p
)
1866 unsigned long r_type
;
1867 unsigned long r_symndx
;
1868 bfd_byte
*hit_data
= contents
+ rel
->r_offset
;
1870 /* The final GP value to be used for the relocatable, executable, or
1871 shared object file being produced. */
1872 bfd_vma gp
= MINUS_ONE
;
1873 /* The place (section offset or address) of the storage unit being relocated. */
1875 /* The value of GP used to create the relocatable object. */
1876 bfd_vma gp0
= MINUS_ONE
;
1877 /* The offset into the global offset table at which the address of the relocation entry
1878 symbol, adjusted by the addend, resides during execution. */
1879 bfd_vma g
= MINUS_ONE
;
1880 /* TRUE if the symbol referred to by this relocation is a local symbol. */
1881 bfd_boolean local_p
;
1882 /* The eventual value we will relocate. */
1883 bfd_vma value
= symbol
;
1884 unsigned long hi16_addend
, hi16_offset
, hi16_value
, uvalue
, offset
, abs_value
= 0;
1886 Elf_Internal_Sym
*sym
= 0;
1887 asection
*sec
= NULL
;
1888 bfd_boolean merge_p
= 0;
1891 if (elf_gp (output_bfd
) == 0)
1893 struct bfd_link_hash_entry
*bh
;
1896 bh
= bfd_link_hash_lookup (info
->hash
, "_gp", 0, 0, 1);
1897 if (bh
!= NULL
&& bh
->type
== bfd_link_hash_defined
)
1898 elf_gp (output_bfd
) = (bh
->u
.def
.value
1899 + bh
->u
.def
.section
->output_section
->vma
1900 + bh
->u
.def
.section
->output_offset
);
1901 else if (info
->relocatable
)
1905 /* Find the GP-relative section with the lowest offset. */
1906 for (o
= output_bfd
->sections
; o
!= NULL
; o
= o
->next
)
1909 /* And calculate GP relative to that. */
1910 elf_gp (output_bfd
) = lo
+ ELF_SCORE_GP_OFFSET (input_bfd
);
1914 /* If the relocate_section function needs to do a reloc
1915 involving the GP value, it should make a reloc_dangerous
1916 callback to warn that GP is not defined. */
1920 /* Parse the relocation. */
1921 r_symndx
= ELF32_R_SYM (rel
->r_info
);
1922 r_type
= ELF32_R_TYPE (rel
->r_info
);
1923 rel_addr
= (input_section
->output_section
->vma
+ input_section
->output_offset
+ rel
->r_offset
);
1925 /* For hidden symbol. */
1926 local_p
= score_elf_local_relocation_p (input_bfd
, rel
, local_sections
, FALSE
);
1929 sym
= local_syms
+ r_symndx
;
1930 sec
= local_sections
[r_symndx
];
1932 symbol
= sec
->output_section
->vma
+ sec
->output_offset
;
1933 if (ELF_ST_TYPE (sym
->st_info
) != STT_SECTION
1934 || (sec
->flags
& SEC_MERGE
))
1935 symbol
+= sym
->st_value
;
1936 if ((sec
->flags
& SEC_MERGE
)
1937 && ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
1941 if (r_type
== R_SCORE_GOT15
)
1943 const Elf_Internal_Rela
*relend
;
1944 const Elf_Internal_Rela
*lo16_rel
;
1945 const struct elf_backend_data
*bed
;
1946 bfd_vma lo_value
= 0;
1948 bed
= get_elf_backend_data (output_bfd
);
1949 relend
= relocs
+ input_section
->reloc_count
* bed
->s
->int_rels_per_ext_rel
;
1950 lo16_rel
= score_elf_next_relocation (input_bfd
, R_SCORE_GOT_LO16
, rel
, relend
);
1951 if ((local_p
) && (lo16_rel
!= NULL
))
1954 tmp
= bfd_get_32 (input_bfd
, contents
+ lo16_rel
->r_offset
);
1955 lo_value
= (((tmp
>> 16) & 0x3) << 14) | ((tmp
& 0x7fff) >> 1);
1958 asection
*msec
= sec
;
1959 lo_value
= _bfd_elf_rel_local_sym (output_bfd
, sym
, &msec
, lo_value
);
1961 lo_value
+= msec
->output_section
->vma
+ msec
->output_offset
;
1968 addend
= (bfd_get_32 (input_bfd
, hit_data
) >> howto
->bitpos
) & howto
->src_mask
;
1971 /* Figure out the value of the symbol. */
1972 if (local_p
&& !merge_p
)
1974 if (r_type
== R_SCORE_GOT15
)
1976 const Elf_Internal_Rela
*relend
;
1977 const Elf_Internal_Rela
*lo16_rel
;
1978 const struct elf_backend_data
*bed
;
1979 bfd_vma lo_value
= 0;
1981 value
= bfd_get_32 (input_bfd
, contents
+ rel
->r_offset
);
1982 addend
= value
& 0x7fff;
1983 if ((addend
& 0x4000) == 0x4000)
1984 addend
|= 0xffffc000;
1986 bed
= get_elf_backend_data (output_bfd
);
1987 relend
= relocs
+ input_section
->reloc_count
* bed
->s
->int_rels_per_ext_rel
;
1988 lo16_rel
= score_elf_next_relocation (input_bfd
, R_SCORE_GOT_LO16
, rel
, relend
);
1989 if ((local_p
) && (lo16_rel
!= NULL
))
1992 tmp
= bfd_get_32 (input_bfd
, contents
+ lo16_rel
->r_offset
);
1993 lo_value
= (((tmp
>> 16) & 0x3) << 14) | ((tmp
& 0x7fff) >> 1);
2001 local_p
= score_elf_local_relocation_p (input_bfd
, rel
, local_sections
, TRUE
);
2003 /* If we haven't already determined the GOT offset, or the GP value,
2004 and we're going to need it, get it now. */
2007 case R_SCORE_CALL15
:
2011 g
= score_elf_global_got_index (elf_hash_table (info
)->dynobj
,
2012 (struct elf_link_hash_entry
*) h
);
2013 if ((! elf_hash_table(info
)->dynamic_sections_created
2015 && (info
->symbolic
|| h
->root
.dynindx
== -1)
2016 && h
->root
.def_regular
)))
2018 /* This is a static link or a -Bsymbolic link. The
2019 symbol is defined locally, or was forced to be local.
2020 We must initialize this entry in the GOT. */
2021 bfd
*tmpbfd
= elf_hash_table (info
)->dynobj
;
2022 asection
*sgot
= score_elf_got_section (tmpbfd
, FALSE
);
2023 bfd_put_32 (tmpbfd
, value
, sgot
->contents
+ g
);
2026 else if (r_type
== R_SCORE_GOT15
|| r_type
== R_SCORE_CALL15
)
2028 /* There's no need to create a local GOT entry here; the
2029 calculation for a local GOT15 entry does not involve G. */
2034 g
= score_elf_local_got_index (output_bfd
, input_bfd
, info
,
2035 symbol
+ addend
, r_symndx
, h
, r_type
);
2037 return bfd_reloc_outofrange
;
2040 /* Convert GOT indices to actual offsets. */
2041 g
= score_elf_got_offset_from_index (elf_hash_table (info
)->dynobj
,
2042 output_bfd
, input_bfd
, g
);
2047 case R_SCORE_GPREL32
:
2048 gp0
= _bfd_get_gp_value (input_bfd
);
2049 gp
= _bfd_get_gp_value (output_bfd
);
2053 gp
= _bfd_get_gp_value (output_bfd
);
2062 return bfd_reloc_ok
;
2067 || (elf_hash_table (info
)->dynamic_sections_created
2069 && h
->root
.def_dynamic
2070 && !h
->root
.def_regular
))
2072 && (input_section
->flags
& SEC_ALLOC
) != 0)
2074 /* If we're creating a shared library, or this relocation is against a symbol
2075 in a shared library, then we can't know where the symbol will end up.
2076 So, we create a relocation record in the output, and leave the job up
2077 to the dynamic linker. */
2079 if (!score_elf_create_dynamic_relocation (output_bfd
, info
, rel
, h
,
2082 return bfd_reloc_undefined
;
2084 else if (r_symndx
== 0)
2085 /* r_symndx will be zero only for relocs against symbols
2086 from removed linkonce sections, or sections discarded by
2091 if (r_type
!= R_SCORE_REL32
)
2092 value
= symbol
+ addend
;
2096 value
&= howto
->dst_mask
;
2097 bfd_put_32 (input_bfd
, value
, hit_data
);
2098 return bfd_reloc_ok
;
2102 if ((long) value
> 0x7fff || (long) value
< -0x8000)
2103 return bfd_reloc_overflow
;
2104 bfd_put_16 (input_bfd
, value
, hit_data
);
2105 return bfd_reloc_ok
;
2108 addend
= bfd_get_32 (input_bfd
, hit_data
);
2109 offset
= (((addend
& howto
->src_mask
) >> 1) & 0x1ff8000) | ((addend
& howto
->src_mask
) & 0x7fff);
2110 if ((offset
& 0x1000000) != 0)
2111 offset
|= 0xfe000000;
2113 abs_value
= abs (value
- rel_addr
);
2114 if ((abs_value
& 0xfe000000) != 0)
2115 return bfd_reloc_overflow
;
2116 addend
= (addend
& ~howto
->src_mask
)
2117 | (((value
<< 1) & howto
->src_mask
) & 0x3ff0000) | (value
& 0x7fff);
2118 bfd_put_32 (input_bfd
, addend
, hit_data
);
2119 return bfd_reloc_ok
;
2122 addend
= bfd_get_32 (input_bfd
, hit_data
);
2123 offset
= (((addend
& howto
->src_mask
) & 0x3ff0000) >> 6) | ((addend
& howto
->src_mask
) & 0x3ff);
2124 if ((offset
& 0x80000) != 0)
2125 offset
|= 0xfff00000;
2126 abs_value
= value
= value
- rel_addr
+ offset
;
2127 /* exceed 20 bit : overflow. */
2128 if ((abs_value
& 0x80000000) == 0x80000000)
2129 abs_value
= 0xffffffff - value
+ 1;
2130 if ((abs_value
& 0xfff80000) != 0)
2131 return bfd_reloc_overflow
;
2132 addend
= (addend
& ~howto
->src_mask
)
2133 | (((value
<< 6) & howto
->src_mask
) & 0x3ff0000) | (value
& 0x3ff);
2134 bfd_put_32 (input_bfd
, addend
, hit_data
);
2135 return bfd_reloc_ok
;
2138 addend
= bfd_get_16 (input_bfd
, hit_data
);
2139 offset
= addend
& howto
->src_mask
;
2140 if ((offset
& 0x800) != 0) /* Offset is negative. */
2141 offset
|= 0xfffff000;
2143 abs_value
= abs (value
- rel_addr
);
2144 if ((abs_value
& 0xfffff000) != 0)
2145 return bfd_reloc_overflow
;
2146 addend
= (addend
& ~howto
->src_mask
) | (value
& howto
->src_mask
);
2147 bfd_put_16 (input_bfd
, addend
, hit_data
);
2148 return bfd_reloc_ok
;
2151 addend
= bfd_get_16 (input_bfd
, hit_data
);
2152 offset
= (addend
& howto
->src_mask
) << 1;
2153 if ((offset
& 0x100) != 0) /* Offset is negative. */
2154 offset
|= 0xfffffe00;
2155 abs_value
= value
= value
- rel_addr
+ offset
;
2156 /* Sign bit + exceed 9 bit. */
2157 if (((value
& 0xffffff00) != 0) && ((value
& 0xffffff00) != 0xffffff00))
2158 return bfd_reloc_overflow
;
2160 addend
= (addend
& ~howto
->src_mask
) | (value
& howto
->src_mask
);
2161 bfd_put_16 (input_bfd
, addend
, hit_data
);
2162 return bfd_reloc_ok
;
2165 return bfd_reloc_ok
;
2168 hi16_addend
= bfd_get_32 (input_bfd
, hit_data
- 4);
2169 hi16_offset
= ((((hi16_addend
>> 16) & 0x3) << 15) | (hi16_addend
& 0x7fff)) >> 1;
2170 addend
= bfd_get_32 (input_bfd
, hit_data
);
2171 offset
= ((((addend
>> 16) & 0x3) << 15) | (addend
& 0x7fff)) >> 1;
2172 offset
= (hi16_offset
<< 16) | (offset
& 0xffff);
2175 uvalue
= value
+ offset
;
2177 uvalue
= offset
+ gp
- rel_addr
+ 4;
2179 hi16_offset
= (uvalue
>> 16) << 1;
2180 hi16_value
= (hi16_addend
& (~(howto
->dst_mask
)))
2181 | (hi16_offset
& 0x7fff) | ((hi16_offset
<< 1) & 0x30000);
2182 bfd_put_32 (input_bfd
, hi16_value
, hit_data
- 4);
2183 offset
= (uvalue
& 0xffff) << 1;
2184 value
= (addend
& (~(howto
->dst_mask
))) | (offset
& 0x7fff) | ((offset
<< 1) & 0x30000);
2185 bfd_put_32 (input_bfd
, value
, hit_data
);
2186 return bfd_reloc_ok
;
2189 addend
= bfd_get_32 (input_bfd
, hit_data
);
2190 offset
= addend
& 0x7fff;
2191 if ((offset
& 0x4000) == 0x4000)
2192 offset
|= 0xffffc000;
2193 value
= value
+ offset
- gp
;
2194 if (((value
& 0xffffc000) != 0) && ((value
& 0xffffc000) != 0xffffc000))
2195 return bfd_reloc_overflow
;
2196 value
= (addend
& ~howto
->src_mask
) | (value
& howto
->src_mask
);
2197 bfd_put_32 (input_bfd
, value
, hit_data
);
2198 return bfd_reloc_ok
;
2201 case R_SCORE_CALL15
:
2206 /* The special case is when the symbol is forced to be local. We need the
2207 full address in the GOT since no R_SCORE_GOT_LO16 relocation follows. */
2208 forced
= ! score_elf_local_relocation_p (input_bfd
, rel
,
2209 local_sections
, FALSE
);
2210 value
= score_elf_got16_entry (output_bfd
, input_bfd
, info
,
2211 symbol
+ addend
, forced
);
2212 if (value
== MINUS_ONE
)
2213 return bfd_reloc_outofrange
;
2214 value
= score_elf_got_offset_from_index (elf_hash_table (info
)->dynobj
,
2215 output_bfd
, input_bfd
, value
);
2222 if ((long) value
> 0x3fff || (long) value
< -0x4000)
2223 return bfd_reloc_overflow
;
2225 addend
= bfd_get_32 (input_bfd
, hit_data
);
2226 value
= (addend
& ~howto
->dst_mask
) | (value
& howto
->dst_mask
);
2227 bfd_put_32 (input_bfd
, value
, hit_data
);
2228 return bfd_reloc_ok
;
2230 case R_SCORE_GPREL32
:
2231 value
= (addend
+ symbol
+ gp0
- gp
);
2232 value
&= howto
->dst_mask
;
2233 bfd_put_32 (input_bfd
, value
, hit_data
);
2234 return bfd_reloc_ok
;
2236 case R_SCORE_GOT_LO16
:
2237 addend
= bfd_get_32 (input_bfd
, hit_data
);
2238 value
= (((addend
>> 16) & 0x3) << 14) | ((addend
& 0x7fff) >> 1);
2240 value
= (addend
& (~(howto
->dst_mask
))) | ((value
& 0x3fff) << 1)
2241 | (((value
>> 14) & 0x3) << 16);
2243 bfd_put_32 (input_bfd
, value
, hit_data
);
2244 return bfd_reloc_ok
;
2246 case R_SCORE_DUMMY_HI16
:
2247 return bfd_reloc_ok
;
2249 case R_SCORE_GNU_VTINHERIT
:
2250 case R_SCORE_GNU_VTENTRY
:
2251 /* We don't do anything with these at present. */
2252 return bfd_reloc_continue
;
2255 return bfd_reloc_notsupported
;
2259 /* Score backend functions. */
2262 s7_bfd_score_info_to_howto (bfd
*abfd ATTRIBUTE_UNUSED
,
2264 Elf_Internal_Rela
*elf_reloc
)
2266 unsigned int r_type
;
2268 r_type
= ELF32_R_TYPE (elf_reloc
->r_info
);
2269 if (r_type
>= ARRAY_SIZE (elf32_score_howto_table
))
2270 bfd_reloc
->howto
= NULL
;
2272 bfd_reloc
->howto
= &elf32_score_howto_table
[r_type
];
2275 /* Relocate an score ELF section. */
2278 s7_bfd_score_elf_relocate_section (bfd
*output_bfd
,
2279 struct bfd_link_info
*info
,
2281 asection
*input_section
,
2283 Elf_Internal_Rela
*relocs
,
2284 Elf_Internal_Sym
*local_syms
,
2285 asection
**local_sections
)
2287 Elf_Internal_Shdr
*symtab_hdr
;
2288 struct elf_link_hash_entry
**sym_hashes
;
2289 Elf_Internal_Rela
*rel
;
2290 Elf_Internal_Rela
*relend
;
2292 unsigned long offset
;
2293 unsigned long hi16_addend
, hi16_offset
, hi16_value
, uvalue
;
2295 bfd_boolean gp_disp_p
= FALSE
;
2298 if (elf_hash_table (info
)->dynamic_sections_created
)
2300 bfd_size_type dynsecsymcount
= 0;
2304 const struct elf_backend_data
*bed
= get_elf_backend_data (output_bfd
);
2306 for (p
= output_bfd
->sections
; p
; p
= p
->next
)
2307 if ((p
->flags
& SEC_EXCLUDE
) == 0
2308 && (p
->flags
& SEC_ALLOC
) != 0
2309 && !(*bed
->elf_backend_omit_section_dynsym
) (output_bfd
, info
, p
))
2313 if (!score_elf_sort_hash_table (info
, dynsecsymcount
+ 1))
2317 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
2318 extsymoff
= (elf_bad_symtab (input_bfd
)) ? 0 : symtab_hdr
->sh_info
;
2319 sym_hashes
= elf_sym_hashes (input_bfd
);
2321 relend
= relocs
+ input_section
->reloc_count
;
2322 for (; rel
< relend
; rel
++)
2325 reloc_howto_type
*howto
;
2326 unsigned long r_symndx
;
2327 Elf_Internal_Sym
*sym
;
2329 struct score_elf_link_hash_entry
*h
;
2330 bfd_vma relocation
= 0;
2331 bfd_reloc_status_type r
;
2334 r_symndx
= ELF32_R_SYM (rel
->r_info
);
2335 r_type
= ELF32_R_TYPE (rel
->r_info
);
2337 s7_bfd_score_info_to_howto (input_bfd
, &bfd_reloc
, (Elf_Internal_Rela
*) rel
);
2338 howto
= bfd_reloc
.howto
;
2344 if (r_symndx
< extsymoff
)
2346 sym
= local_syms
+ r_symndx
;
2347 sec
= local_sections
[r_symndx
];
2348 relocation
= sec
->output_section
->vma
+ sec
->output_offset
;
2349 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
, sec
);
2351 if (!info
->relocatable
)
2353 if (ELF_ST_TYPE (sym
->st_info
) != STT_SECTION
2354 || (sec
->flags
& SEC_MERGE
))
2356 relocation
+= sym
->st_value
;
2359 if ((sec
->flags
& SEC_MERGE
)
2360 && ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
2363 bfd_vma addend
, value
;
2370 hi16_addend
= bfd_get_32 (input_bfd
, contents
+ rel
->r_offset
- 4);
2371 hi16_offset
= ((((hi16_addend
>> 16) & 0x3) << 15) | (hi16_addend
& 0x7fff)) >> 1;
2372 value
= bfd_get_32 (input_bfd
, contents
+ rel
->r_offset
);
2373 offset
= ((((value
>> 16) & 0x3) << 15) | (value
& 0x7fff)) >> 1;
2374 addend
= (hi16_offset
<< 16) | (offset
& 0xffff);
2376 addend
= _bfd_elf_rel_local_sym (output_bfd
, sym
, &msec
, addend
);
2377 addend
-= relocation
;
2378 addend
+= msec
->output_section
->vma
+ msec
->output_offset
;
2380 hi16_offset
= (uvalue
>> 16) << 1;
2381 hi16_value
= (hi16_addend
& (~(howto
->dst_mask
)))
2382 | (hi16_offset
& 0x7fff) | ((hi16_offset
<< 1) & 0x30000);
2383 bfd_put_32 (input_bfd
, hi16_value
, contents
+ rel
->r_offset
- 4);
2384 offset
= (uvalue
& 0xffff) << 1;
2385 value
= (value
& (~(howto
->dst_mask
)))
2386 | (offset
& 0x7fff) | ((offset
<< 1) & 0x30000);
2387 bfd_put_32 (input_bfd
, value
, contents
+ rel
->r_offset
);
2389 case R_SCORE_GOT_LO16
:
2390 value
= bfd_get_32 (input_bfd
, contents
+ rel
->r_offset
);
2391 addend
= (((value
>> 16) & 0x3) << 14) | ((value
& 0x7fff) >> 1);
2393 addend
= _bfd_elf_rel_local_sym (output_bfd
, sym
, &msec
, addend
) - relocation
;
2394 addend
+= msec
->output_section
->vma
+ msec
->output_offset
;
2395 value
= (value
& (~(howto
->dst_mask
))) | ((addend
& 0x3fff) << 1)
2396 | (((addend
>> 14) & 0x3) << 16);
2398 bfd_put_32 (input_bfd
, value
, contents
+ rel
->r_offset
);
2401 value
= bfd_get_32 (input_bfd
, contents
+ rel
->r_offset
);
2402 /* Get the (signed) value from the instruction. */
2403 addend
= value
& howto
->src_mask
;
2404 if (addend
& ((howto
->src_mask
+ 1) >> 1))
2406 bfd_signed_vma mask
;
2409 mask
&= ~howto
->src_mask
;
2413 addend
= _bfd_elf_rel_local_sym (output_bfd
, sym
, &msec
, addend
) - relocation
;
2414 addend
+= msec
->output_section
->vma
+ msec
->output_offset
;
2415 value
= (value
& ~howto
->dst_mask
) | (addend
& howto
->dst_mask
);
2416 bfd_put_32 (input_bfd
, value
, contents
+ rel
->r_offset
);
2424 /* For global symbols we look up the symbol in the hash-table. */
2425 h
= ((struct score_elf_link_hash_entry
*)
2426 elf_sym_hashes (input_bfd
) [r_symndx
- extsymoff
]);
2427 /* Find the real hash-table entry for this symbol. */
2428 while (h
->root
.root
.type
== bfd_link_hash_indirect
2429 || h
->root
.root
.type
== bfd_link_hash_warning
)
2430 h
= (struct score_elf_link_hash_entry
*) h
->root
.root
.u
.i
.link
;
2432 /* Record the name of this symbol, for our caller. */
2433 name
= h
->root
.root
.root
.string
;
2435 /* See if this is the special GP_DISP_LABEL symbol. Note that such a
2436 symbol must always be a global symbol. */
2437 if (strcmp (name
, GP_DISP_LABEL
) == 0)
2439 /* Relocations against GP_DISP_LABEL are permitted only with
2440 R_SCORE_HI16 and R_SCORE_LO16 relocations. */
2441 if (r_type
!= R_SCORE_HI16
&& r_type
!= R_SCORE_LO16
)
2442 return bfd_reloc_notsupported
;
2447 /* If this symbol is defined, calculate its address. Note that
2448 GP_DISP_LABEL is a magic symbol, always implicitly defined by the
2449 linker, so it's inappropriate to check to see whether or not
2451 else if ((h
->root
.root
.type
== bfd_link_hash_defined
2452 || h
->root
.root
.type
== bfd_link_hash_defweak
)
2453 && h
->root
.root
.u
.def
.section
)
2455 sec
= h
->root
.root
.u
.def
.section
;
2456 if (sec
->output_section
)
2457 relocation
= (h
->root
.root
.u
.def
.value
2458 + sec
->output_section
->vma
2459 + sec
->output_offset
);
2462 relocation
= h
->root
.root
.u
.def
.value
;
2465 else if (h
->root
.root
.type
== bfd_link_hash_undefweak
)
2466 /* We allow relocations against undefined weak symbols, giving
2467 it the value zero, so that you can undefined weak functions
2468 and check to see if they exist by looking at their addresses. */
2470 else if (info
->unresolved_syms_in_objects
== RM_IGNORE
2471 && ELF_ST_VISIBILITY (h
->root
.other
) == STV_DEFAULT
)
2473 else if (strcmp (name
, "_DYNAMIC_LINK") == 0)
2475 /* If this is a dynamic link, we should have created a _DYNAMIC_LINK symbol
2476 in s7_bfd_score_elf_create_dynamic_sections. Otherwise, we should define
2477 the symbol with a value of 0. */
2478 BFD_ASSERT (! info
->shared
);
2479 BFD_ASSERT (bfd_get_section_by_name (output_bfd
, ".dynamic") == NULL
);
2482 else if (!info
->relocatable
)
2484 if (! ((*info
->callbacks
->undefined_symbol
)
2485 (info
, h
->root
.root
.root
.string
, input_bfd
,
2486 input_section
, rel
->r_offset
,
2487 (info
->unresolved_syms_in_objects
== RM_GENERATE_ERROR
)
2488 || ELF_ST_VISIBILITY (h
->root
.other
))))
2489 return bfd_reloc_undefined
;
2494 if (sec
!= NULL
&& elf_discarded_section (sec
))
2496 /* For relocs against symbols from removed linkonce sections,
2497 or sections discarded by a linker script, we just want the
2498 section contents zeroed. Avoid any special processing. */
2499 _bfd_clear_contents (howto
, input_bfd
, contents
+ rel
->r_offset
);
2505 if (info
->relocatable
)
2507 /* This is a relocatable link. We don't have to change
2508 anything, unless the reloc is against a section symbol,
2509 in which case we have to adjust according to where the
2510 section symbol winds up in the output section. */
2511 if (r_symndx
< symtab_hdr
->sh_info
)
2513 sym
= local_syms
+ r_symndx
;
2515 if (r_type
== R_SCORE_GOT15
)
2517 const Elf_Internal_Rela
*lo16_rel
;
2518 const struct elf_backend_data
*bed
;
2519 bfd_vma lo_addend
= 0, lo_value
= 0;
2520 bfd_vma addend
, value
;
2522 value
= bfd_get_32 (input_bfd
, contents
+ rel
->r_offset
);
2523 addend
= value
& 0x7fff;
2524 if ((addend
& 0x4000) == 0x4000)
2525 addend
|= 0xffffc000;
2527 bed
= get_elf_backend_data (output_bfd
);
2528 relend
= relocs
+ input_section
->reloc_count
* bed
->s
->int_rels_per_ext_rel
;
2529 lo16_rel
= score_elf_next_relocation (input_bfd
, R_SCORE_GOT_LO16
, rel
, relend
);
2530 if (lo16_rel
!= NULL
)
2532 lo_value
= bfd_get_32 (input_bfd
, contents
+ lo16_rel
->r_offset
);
2533 lo_addend
= (((lo_value
>> 16) & 0x3) << 14) | ((lo_value
& 0x7fff) >> 1);
2537 addend
+= lo_addend
;
2539 if (ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
2540 addend
+= local_sections
[r_symndx
]->output_offset
;
2542 lo_addend
= addend
& 0xffff;
2543 lo_value
= (lo_value
& (~(howto
->dst_mask
))) | ((lo_addend
& 0x3fff) << 1)
2544 | (((lo_addend
>> 14) & 0x3) << 16);
2545 bfd_put_32 (input_bfd
, lo_value
, contents
+ lo16_rel
->r_offset
);
2547 addend
= addend
>> 16;
2548 value
= (value
& ~howto
->src_mask
) | (addend
& howto
->src_mask
);
2549 bfd_put_32 (input_bfd
, value
, contents
+ rel
->r_offset
);
2551 else if (ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
2553 sec
= local_sections
[r_symndx
];
2554 score_elf_add_to_rel (input_bfd
, contents
+ rel
->r_offset
,
2555 howto
, (bfd_signed_vma
) (sec
->output_offset
+ sym
->st_value
));
2561 /* This is a final link. */
2562 r
= score_elf_final_link_relocate (howto
, input_bfd
, output_bfd
,
2563 input_section
, contents
, rel
, relocs
,
2564 relocation
, info
, name
,
2565 (h
? ELF_ST_TYPE ((unsigned int) h
->root
.root
.type
) :
2566 ELF_ST_TYPE ((unsigned int) sym
->st_info
)), h
, local_syms
,
2567 local_sections
, gp_disp_p
);
2569 if (r
!= bfd_reloc_ok
)
2571 const char *msg
= (const char *)0;
2575 case bfd_reloc_overflow
:
2576 /* If the overflowing reloc was to an undefined symbol,
2577 we have already printed one error message and there
2578 is no point complaining again. */
2579 if (((!h
) || (h
->root
.root
.type
!= bfd_link_hash_undefined
))
2580 && (!((*info
->callbacks
->reloc_overflow
)
2581 (info
, NULL
, name
, howto
->name
, (bfd_vma
) 0,
2582 input_bfd
, input_section
, rel
->r_offset
))))
2585 case bfd_reloc_undefined
:
2586 if (!((*info
->callbacks
->undefined_symbol
)
2587 (info
, name
, input_bfd
, input_section
, rel
->r_offset
, TRUE
)))
2591 case bfd_reloc_outofrange
:
2592 msg
= _("internal error: out of range error");
2595 case bfd_reloc_notsupported
:
2596 msg
= _("internal error: unsupported relocation error");
2599 case bfd_reloc_dangerous
:
2600 msg
= _("internal error: dangerous error");
2604 msg
= _("internal error: unknown error");
2608 if (!((*info
->callbacks
->warning
)
2609 (info
, msg
, name
, input_bfd
, input_section
, rel
->r_offset
)))
2619 /* Look through the relocs for a section during the first phase, and
2620 allocate space in the global offset table. */
2623 s7_bfd_score_elf_check_relocs (bfd
*abfd
,
2624 struct bfd_link_info
*info
,
2626 const Elf_Internal_Rela
*relocs
)
2630 Elf_Internal_Shdr
*symtab_hdr
;
2631 struct elf_link_hash_entry
**sym_hashes
;
2632 struct score_got_info
*g
;
2634 const Elf_Internal_Rela
*rel
;
2635 const Elf_Internal_Rela
*rel_end
;
2638 const struct elf_backend_data
*bed
;
2640 if (info
->relocatable
)
2643 dynobj
= elf_hash_table (info
)->dynobj
;
2644 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
2645 sym_hashes
= elf_sym_hashes (abfd
);
2646 extsymoff
= (elf_bad_symtab (abfd
)) ? 0 : symtab_hdr
->sh_info
;
2648 name
= bfd_get_section_name (abfd
, sec
);
2657 sgot
= score_elf_got_section (dynobj
, FALSE
);
2662 BFD_ASSERT (score_elf_section_data (sgot
) != NULL
);
2663 g
= score_elf_section_data (sgot
)->u
.got_info
;
2664 BFD_ASSERT (g
!= NULL
);
2669 bed
= get_elf_backend_data (abfd
);
2670 rel_end
= relocs
+ sec
->reloc_count
* bed
->s
->int_rels_per_ext_rel
;
2671 for (rel
= relocs
; rel
< rel_end
; ++rel
)
2673 unsigned long r_symndx
;
2674 unsigned int r_type
;
2675 struct elf_link_hash_entry
*h
;
2677 r_symndx
= ELF32_R_SYM (rel
->r_info
);
2678 r_type
= ELF32_R_TYPE (rel
->r_info
);
2680 if (r_symndx
< extsymoff
)
2684 else if (r_symndx
>= extsymoff
+ NUM_SHDR_ENTRIES (symtab_hdr
))
2686 (*_bfd_error_handler
) (_("%s: Malformed reloc detected for section %s"), abfd
, name
);
2687 bfd_set_error (bfd_error_bad_value
);
2692 h
= sym_hashes
[r_symndx
- extsymoff
];
2694 /* This may be an indirect symbol created because of a version. */
2697 while (h
->root
.type
== bfd_link_hash_indirect
)
2698 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2702 /* Some relocs require a global offset table. */
2703 if (dynobj
== NULL
|| sgot
== NULL
)
2708 case R_SCORE_CALL15
:
2710 elf_hash_table (info
)->dynobj
= dynobj
= abfd
;
2711 if (!score_elf_create_got_section (dynobj
, info
, FALSE
))
2713 g
= score_elf_got_info (dynobj
, &sgot
);
2717 if (dynobj
== NULL
&& (info
->shared
|| h
!= NULL
) && (sec
->flags
& SEC_ALLOC
) != 0)
2718 elf_hash_table (info
)->dynobj
= dynobj
= abfd
;
2725 if (!h
&& (r_type
== R_SCORE_GOT_LO16
))
2727 if (! score_elf_record_local_got_symbol (abfd
, r_symndx
, rel
->r_addend
, g
))
2733 case R_SCORE_CALL15
:
2736 (*_bfd_error_handler
)
2737 (_("%B: CALL15 reloc at 0x%lx not against global symbol"),
2738 abfd
, (unsigned long) rel
->r_offset
);
2739 bfd_set_error (bfd_error_bad_value
);
2744 /* This symbol requires a global offset table entry. */
2745 if (! score_elf_record_global_got_symbol (h
, abfd
, info
, g
))
2748 /* We need a stub, not a plt entry for the undefined function. But we record
2749 it as if it needs plt. See _bfd_elf_adjust_dynamic_symbol. */
2755 if (h
&& ! score_elf_record_global_got_symbol (h
, abfd
, info
, g
))
2760 if ((info
->shared
|| h
!= NULL
) && (sec
->flags
& SEC_ALLOC
) != 0)
2764 sreloc
= score_elf_rel_dyn_section (dynobj
, TRUE
);
2768 #define SCORE_READONLY_SECTION (SEC_ALLOC | SEC_LOAD | SEC_READONLY)
2771 /* When creating a shared object, we must copy these reloc types into
2772 the output file as R_SCORE_REL32 relocs. We make room for this reloc
2773 in the .rel.dyn reloc section. */
2774 score_elf_allocate_dynamic_relocations (dynobj
, 1);
2775 if ((sec
->flags
& SCORE_READONLY_SECTION
)
2776 == SCORE_READONLY_SECTION
)
2777 /* We tell the dynamic linker that there are
2778 relocations against the text segment. */
2779 info
->flags
|= DF_TEXTREL
;
2783 struct score_elf_link_hash_entry
*hscore
;
2785 /* We only need to copy this reloc if the symbol is
2786 defined in a dynamic object. */
2787 hscore
= (struct score_elf_link_hash_entry
*) h
;
2788 ++hscore
->possibly_dynamic_relocs
;
2789 if ((sec
->flags
& SCORE_READONLY_SECTION
)
2790 == SCORE_READONLY_SECTION
)
2791 /* We need it to tell the dynamic linker if there
2792 are relocations against the text segment. */
2793 hscore
->readonly_reloc
= TRUE
;
2796 /* Even though we don't directly need a GOT entry for this symbol,
2797 a symbol must have a dynamic symbol table index greater that
2798 DT_SCORE_GOTSYM if there are dynamic relocations against it. */
2802 elf_hash_table (info
)->dynobj
= dynobj
= abfd
;
2803 if (! score_elf_create_got_section (dynobj
, info
, TRUE
))
2805 g
= score_elf_got_info (dynobj
, &sgot
);
2806 if (! score_elf_record_global_got_symbol (h
, abfd
, info
, g
))
2812 /* This relocation describes the C++ object vtable hierarchy.
2813 Reconstruct it for later use during GC. */
2814 case R_SCORE_GNU_VTINHERIT
:
2815 if (!bfd_elf_gc_record_vtinherit (abfd
, sec
, h
, rel
->r_offset
))
2819 /* This relocation describes which C++ vtable entries are actually
2820 used. Record for later use during GC. */
2821 case R_SCORE_GNU_VTENTRY
:
2822 if (!bfd_elf_gc_record_vtentry (abfd
, sec
, h
, rel
->r_offset
))
2829 /* We must not create a stub for a symbol that has relocations
2830 related to taking the function's address. */
2836 struct score_elf_link_hash_entry
*sh
;
2838 sh
= (struct score_elf_link_hash_entry
*) h
;
2839 sh
->no_fn_stub
= TRUE
;
2842 case R_SCORE_CALL15
:
2851 s7_bfd_score_elf_add_symbol_hook (bfd
*abfd
,
2852 struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
2853 Elf_Internal_Sym
*sym
,
2854 const char **namep ATTRIBUTE_UNUSED
,
2855 flagword
*flagsp ATTRIBUTE_UNUSED
,
2859 switch (sym
->st_shndx
)
2862 if (sym
->st_size
> elf_gp_size (abfd
))
2865 case SHN_SCORE_SCOMMON
:
2866 *secp
= bfd_make_section_old_way (abfd
, ".scommon");
2867 (*secp
)->flags
|= SEC_IS_COMMON
;
2868 *valp
= sym
->st_size
;
2876 s7_bfd_score_elf_symbol_processing (bfd
*abfd
, asymbol
*asym
)
2878 elf_symbol_type
*elfsym
;
2880 elfsym
= (elf_symbol_type
*) asym
;
2881 switch (elfsym
->internal_elf_sym
.st_shndx
)
2884 if (asym
->value
> elf_gp_size (abfd
))
2887 case SHN_SCORE_SCOMMON
:
2888 if (score_elf_scom_section
.name
== NULL
)
2890 /* Initialize the small common section. */
2891 score_elf_scom_section
.name
= ".scommon";
2892 score_elf_scom_section
.flags
= SEC_IS_COMMON
;
2893 score_elf_scom_section
.output_section
= &score_elf_scom_section
;
2894 score_elf_scom_section
.symbol
= &score_elf_scom_symbol
;
2895 score_elf_scom_section
.symbol_ptr_ptr
= &score_elf_scom_symbol_ptr
;
2896 score_elf_scom_symbol
.name
= ".scommon";
2897 score_elf_scom_symbol
.flags
= BSF_SECTION_SYM
;
2898 score_elf_scom_symbol
.section
= &score_elf_scom_section
;
2899 score_elf_scom_symbol_ptr
= &score_elf_scom_symbol
;
2901 asym
->section
= &score_elf_scom_section
;
2902 asym
->value
= elfsym
->internal_elf_sym
.st_size
;
2908 s7_bfd_score_elf_link_output_symbol_hook (struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
2909 const char *name ATTRIBUTE_UNUSED
,
2910 Elf_Internal_Sym
*sym
,
2911 asection
*input_sec
,
2912 struct elf_link_hash_entry
*h ATTRIBUTE_UNUSED
)
2914 /* If we see a common symbol, which implies a relocatable link, then
2915 if a symbol was small common in an input file, mark it as small
2916 common in the output file. */
2917 if (sym
->st_shndx
== SHN_COMMON
&& strcmp (input_sec
->name
, ".scommon") == 0)
2918 sym
->st_shndx
= SHN_SCORE_SCOMMON
;
2924 s7_bfd_score_elf_section_from_bfd_section (bfd
*abfd ATTRIBUTE_UNUSED
,
2928 if (strcmp (bfd_get_section_name (abfd
, sec
), ".scommon") == 0)
2930 *retval
= SHN_SCORE_SCOMMON
;
2937 /* Adjust a symbol defined by a dynamic object and referenced by a
2938 regular object. The current definition is in some section of the
2939 dynamic object, but we're not including those sections. We have to
2940 change the definition to something the rest of the link can understand. */
2943 s7_bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info
*info
,
2944 struct elf_link_hash_entry
*h
)
2947 struct score_elf_link_hash_entry
*hscore
;
2950 dynobj
= elf_hash_table (info
)->dynobj
;
2952 /* Make sure we know what is going on here. */
2953 BFD_ASSERT (dynobj
!= NULL
2955 || h
->u
.weakdef
!= NULL
2956 || (h
->def_dynamic
&& h
->ref_regular
&& !h
->def_regular
)));
2958 /* If this symbol is defined in a dynamic object, we need to copy
2959 any R_SCORE_ABS32 or R_SCORE_REL32 relocs against it into the output
2961 hscore
= (struct score_elf_link_hash_entry
*) h
;
2962 if (!info
->relocatable
2963 && hscore
->possibly_dynamic_relocs
!= 0
2964 && (h
->root
.type
== bfd_link_hash_defweak
|| !h
->def_regular
))
2966 score_elf_allocate_dynamic_relocations (dynobj
, hscore
->possibly_dynamic_relocs
);
2967 if (hscore
->readonly_reloc
)
2968 /* We tell the dynamic linker that there are relocations
2969 against the text segment. */
2970 info
->flags
|= DF_TEXTREL
;
2973 /* For a function, create a stub, if allowed. */
2974 if (!hscore
->no_fn_stub
&& h
->needs_plt
)
2976 if (!elf_hash_table (info
)->dynamic_sections_created
)
2979 /* If this symbol is not defined in a regular file, then set
2980 the symbol to the stub location. This is required to make
2981 function pointers compare as equal between the normal
2982 executable and the shared library. */
2983 if (!h
->def_regular
)
2985 /* We need .stub section. */
2986 s
= bfd_get_section_by_name (dynobj
, SCORE_ELF_STUB_SECTION_NAME
);
2987 BFD_ASSERT (s
!= NULL
);
2989 h
->root
.u
.def
.section
= s
;
2990 h
->root
.u
.def
.value
= s
->size
;
2992 /* XXX Write this stub address somewhere. */
2993 h
->plt
.offset
= s
->size
;
2995 /* Make room for this stub code. */
2996 s
->size
+= SCORE_FUNCTION_STUB_SIZE
;
2998 /* The last half word of the stub will be filled with the index
2999 of this symbol in .dynsym section. */
3003 else if ((h
->type
== STT_FUNC
) && !h
->needs_plt
)
3005 /* This will set the entry for this symbol in the GOT to 0, and
3006 the dynamic linker will take care of this. */
3007 h
->root
.u
.def
.value
= 0;
3011 /* If this is a weak symbol, and there is a real definition, the
3012 processor independent code will have arranged for us to see the
3013 real definition first, and we can just use the same value. */
3014 if (h
->u
.weakdef
!= NULL
)
3016 BFD_ASSERT (h
->u
.weakdef
->root
.type
== bfd_link_hash_defined
3017 || h
->u
.weakdef
->root
.type
== bfd_link_hash_defweak
);
3018 h
->root
.u
.def
.section
= h
->u
.weakdef
->root
.u
.def
.section
;
3019 h
->root
.u
.def
.value
= h
->u
.weakdef
->root
.u
.def
.value
;
3023 /* This is a reference to a symbol defined by a dynamic object which
3024 is not a function. */
3028 /* This function is called after all the input files have been read,
3029 and the input sections have been assigned to output sections. */
3032 s7_bfd_score_elf_always_size_sections (bfd
*output_bfd
,
3033 struct bfd_link_info
*info
)
3037 struct score_got_info
*g
;
3039 bfd_size_type loadable_size
= 0;
3040 bfd_size_type local_gotno
;
3043 dynobj
= elf_hash_table (info
)->dynobj
;
3045 /* Relocatable links don't have it. */
3048 g
= score_elf_got_info (dynobj
, &s
);
3052 /* Calculate the total loadable size of the output. That will give us the
3053 maximum number of GOT_PAGE entries required. */
3054 for (sub
= info
->input_bfds
; sub
; sub
= sub
->link_next
)
3056 asection
*subsection
;
3058 for (subsection
= sub
->sections
;
3060 subsection
= subsection
->next
)
3062 if ((subsection
->flags
& SEC_ALLOC
) == 0)
3064 loadable_size
+= ((subsection
->size
+ 0xf)
3065 &~ (bfd_size_type
) 0xf);
3069 /* There has to be a global GOT entry for every symbol with
3070 a dynamic symbol table index of DT_SCORE_GOTSYM or
3071 higher. Therefore, it make sense to put those symbols
3072 that need GOT entries at the end of the symbol table. We
3074 if (! score_elf_sort_hash_table (info
, 1))
3077 if (g
->global_gotsym
!= NULL
)
3078 i
= elf_hash_table (info
)->dynsymcount
- g
->global_gotsym
->dynindx
;
3080 /* If there are no global symbols, or none requiring
3081 relocations, then GLOBAL_GOTSYM will be NULL. */
3084 /* In the worst case, we'll get one stub per dynamic symbol. */
3085 loadable_size
+= SCORE_FUNCTION_STUB_SIZE
* i
;
3087 /* Assume there are two loadable segments consisting of
3088 contiguous sections. Is 5 enough? */
3089 local_gotno
= (loadable_size
>> 16) + 5;
3091 g
->local_gotno
+= local_gotno
;
3092 s
->size
+= g
->local_gotno
* SCORE_ELF_GOT_SIZE (output_bfd
);
3094 g
->global_gotno
= i
;
3095 s
->size
+= i
* SCORE_ELF_GOT_SIZE (output_bfd
);
3097 score_elf_resolve_final_got_entries (g
);
3099 if (s
->size
> SCORE_ELF_GOT_MAX_SIZE (output_bfd
))
3101 /* Fixme. Error message or Warning message should be issued here. */
3107 /* Set the sizes of the dynamic sections. */
3110 s7_bfd_score_elf_size_dynamic_sections (bfd
*output_bfd
, struct bfd_link_info
*info
)
3114 bfd_boolean reltext
;
3116 dynobj
= elf_hash_table (info
)->dynobj
;
3117 BFD_ASSERT (dynobj
!= NULL
);
3119 if (elf_hash_table (info
)->dynamic_sections_created
)
3121 /* Set the contents of the .interp section to the interpreter. */
3124 s
= bfd_get_section_by_name (dynobj
, ".interp");
3125 BFD_ASSERT (s
!= NULL
);
3126 s
->size
= strlen (ELF_DYNAMIC_INTERPRETER
) + 1;
3127 s
->contents
= (bfd_byte
*) ELF_DYNAMIC_INTERPRETER
;
3131 /* The check_relocs and adjust_dynamic_symbol entry points have
3132 determined the sizes of the various dynamic sections. Allocate
3135 for (s
= dynobj
->sections
; s
!= NULL
; s
= s
->next
)
3139 if ((s
->flags
& SEC_LINKER_CREATED
) == 0)
3142 /* It's OK to base decisions on the section name, because none
3143 of the dynobj section names depend upon the input files. */
3144 name
= bfd_get_section_name (dynobj
, s
);
3146 if (CONST_STRNEQ (name
, ".rel"))
3150 /* We only strip the section if the output section name
3151 has the same name. Otherwise, there might be several
3152 input sections for this output section. FIXME: This
3153 code is probably not needed these days anyhow, since
3154 the linker now does not create empty output sections. */
3155 if (s
->output_section
!= NULL
3157 bfd_get_section_name (s
->output_section
->owner
,
3158 s
->output_section
)) == 0)
3159 s
->flags
|= SEC_EXCLUDE
;
3163 const char *outname
;
3166 /* If this relocation section applies to a read only
3167 section, then we probably need a DT_TEXTREL entry.
3168 If the relocation section is .rel.dyn, we always
3169 assert a DT_TEXTREL entry rather than testing whether
3170 there exists a relocation to a read only section or
3172 outname
= bfd_get_section_name (output_bfd
, s
->output_section
);
3173 target
= bfd_get_section_by_name (output_bfd
, outname
+ 4);
3175 && (target
->flags
& SEC_READONLY
) != 0
3176 && (target
->flags
& SEC_ALLOC
) != 0) || strcmp (outname
, ".rel.dyn") == 0)
3179 /* We use the reloc_count field as a counter if we need
3180 to copy relocs into the output file. */
3181 if (strcmp (name
, ".rel.dyn") != 0)
3185 else if (CONST_STRNEQ (name
, ".got"))
3187 /* s7_bfd_score_elf_always_size_sections() has already done
3188 most of the work, but some symbols may have been mapped
3189 to versions that we must now resolve in the got_entries
3192 else if (strcmp (name
, SCORE_ELF_STUB_SECTION_NAME
) == 0)
3194 /* IRIX rld assumes that the function stub isn't at the end
3195 of .text section. So put a dummy. XXX */
3196 s
->size
+= SCORE_FUNCTION_STUB_SIZE
;
3198 else if (! CONST_STRNEQ (name
, ".init"))
3200 /* It's not one of our sections, so don't allocate space. */
3204 /* Allocate memory for the section contents. */
3205 s
->contents
= bfd_zalloc (dynobj
, s
->size
);
3206 if (s
->contents
== NULL
&& s
->size
!= 0)
3208 bfd_set_error (bfd_error_no_memory
);
3213 if (elf_hash_table (info
)->dynamic_sections_created
)
3215 /* Add some entries to the .dynamic section. We fill in the
3216 values later, in s7_bfd_score_elf_finish_dynamic_sections, but we
3217 must add the entries now so that we get the correct size for
3218 the .dynamic section. The DT_DEBUG entry is filled in by the
3219 dynamic linker and used by the debugger. */
3221 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info
, DT_DEBUG
, 0))
3225 info
->flags
|= DF_TEXTREL
;
3227 if ((info
->flags
& DF_TEXTREL
) != 0)
3229 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info
, DT_TEXTREL
, 0))
3233 if (! SCORE_ELF_ADD_DYNAMIC_ENTRY (info
, DT_PLTGOT
, 0))
3236 if (score_elf_rel_dyn_section (dynobj
, FALSE
))
3238 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info
, DT_REL
, 0))
3241 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info
, DT_RELSZ
, 0))
3244 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info
, DT_RELENT
, 0))
3248 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info
, DT_SCORE_BASE_ADDRESS
, 0))
3251 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info
, DT_SCORE_LOCAL_GOTNO
, 0))
3254 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info
, DT_SCORE_SYMTABNO
, 0))
3257 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info
, DT_SCORE_UNREFEXTNO
, 0))
3260 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info
, DT_SCORE_GOTSYM
, 0))
3263 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info
, DT_SCORE_HIPAGENO
, 0))
3271 s7_bfd_score_elf_create_dynamic_sections (bfd
*abfd
, struct bfd_link_info
*info
)
3273 struct elf_link_hash_entry
*h
;
3274 struct bfd_link_hash_entry
*bh
;
3278 flags
= (SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
| SEC_IN_MEMORY
3279 | SEC_LINKER_CREATED
| SEC_READONLY
);
3281 /* ABI requests the .dynamic section to be read only. */
3282 s
= bfd_get_section_by_name (abfd
, ".dynamic");
3285 if (!bfd_set_section_flags (abfd
, s
, flags
))
3289 /* We need to create .got section. */
3290 if (!score_elf_create_got_section (abfd
, info
, FALSE
))
3293 if (!score_elf_rel_dyn_section (elf_hash_table (info
)->dynobj
, TRUE
))
3296 /* Create .stub section. */
3297 if (bfd_get_section_by_name (abfd
, SCORE_ELF_STUB_SECTION_NAME
) == NULL
)
3299 s
= bfd_make_section_with_flags (abfd
, SCORE_ELF_STUB_SECTION_NAME
,
3302 || !bfd_set_section_alignment (abfd
, s
, 2))
3311 name
= "_DYNAMIC_LINK";
3313 if (!(_bfd_generic_link_add_one_symbol
3314 (info
, abfd
, name
, BSF_GLOBAL
, bfd_abs_section_ptr
,
3315 (bfd_vma
) 0, NULL
, FALSE
, get_elf_backend_data (abfd
)->collect
, &bh
)))
3318 h
= (struct elf_link_hash_entry
*) bh
;
3321 h
->type
= STT_SECTION
;
3323 if (!bfd_elf_link_record_dynamic_symbol (info
, h
))
3331 /* Finish up dynamic symbol handling. We set the contents of various
3332 dynamic sections here. */
3335 s7_bfd_score_elf_finish_dynamic_symbol (bfd
*output_bfd
,
3336 struct bfd_link_info
*info
,
3337 struct elf_link_hash_entry
*h
,
3338 Elf_Internal_Sym
*sym
)
3342 struct score_got_info
*g
;
3345 dynobj
= elf_hash_table (info
)->dynobj
;
3347 if (h
->plt
.offset
!= MINUS_ONE
)
3350 bfd_byte stub
[SCORE_FUNCTION_STUB_SIZE
];
3352 /* This symbol has a stub. Set it up. */
3353 BFD_ASSERT (h
->dynindx
!= -1);
3355 s
= bfd_get_section_by_name (dynobj
, SCORE_ELF_STUB_SECTION_NAME
);
3356 BFD_ASSERT (s
!= NULL
);
3358 /* FIXME: Can h->dynindex be more than 64K? */
3359 if (h
->dynindx
& 0xffff0000)
3362 /* Fill the stub. */
3363 bfd_put_32 (output_bfd
, STUB_LW
, stub
);
3364 bfd_put_32 (output_bfd
, STUB_MOVE
, stub
+ 4);
3365 bfd_put_32 (output_bfd
, STUB_LI16
| (h
->dynindx
<< 1), stub
+ 8);
3366 bfd_put_32 (output_bfd
, STUB_BRL
, stub
+ 12);
3368 BFD_ASSERT (h
->plt
.offset
<= s
->size
);
3369 memcpy (s
->contents
+ h
->plt
.offset
, stub
, SCORE_FUNCTION_STUB_SIZE
);
3371 /* Mark the symbol as undefined. plt.offset != -1 occurs
3372 only for the referenced symbol. */
3373 sym
->st_shndx
= SHN_UNDEF
;
3375 /* The run-time linker uses the st_value field of the symbol
3376 to reset the global offset table entry for this external
3377 to its stub address when unlinking a shared object. */
3378 sym
->st_value
= (s
->output_section
->vma
+ s
->output_offset
+ h
->plt
.offset
);
3381 BFD_ASSERT (h
->dynindx
!= -1 || h
->forced_local
);
3383 sgot
= score_elf_got_section (dynobj
, FALSE
);
3384 BFD_ASSERT (sgot
!= NULL
);
3385 BFD_ASSERT (score_elf_section_data (sgot
) != NULL
);
3386 g
= score_elf_section_data (sgot
)->u
.got_info
;
3387 BFD_ASSERT (g
!= NULL
);
3389 /* Run through the global symbol table, creating GOT entries for all
3390 the symbols that need them. */
3391 if (g
->global_gotsym
!= NULL
&& h
->dynindx
>= g
->global_gotsym
->dynindx
)
3396 value
= sym
->st_value
;
3397 offset
= score_elf_global_got_index (dynobj
, h
);
3398 bfd_put_32 (output_bfd
, value
, sgot
->contents
+ offset
);
3401 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
3402 name
= h
->root
.root
.string
;
3403 if (strcmp (name
, "_DYNAMIC") == 0 || strcmp (name
, "_GLOBAL_OFFSET_TABLE_") == 0)
3404 sym
->st_shndx
= SHN_ABS
;
3405 else if (strcmp (name
, "_DYNAMIC_LINK") == 0)
3407 sym
->st_shndx
= SHN_ABS
;
3408 sym
->st_info
= ELF_ST_INFO (STB_GLOBAL
, STT_SECTION
);
3411 else if (strcmp (name
, GP_DISP_LABEL
) == 0)
3413 sym
->st_shndx
= SHN_ABS
;
3414 sym
->st_info
= ELF_ST_INFO (STB_GLOBAL
, STT_SECTION
);
3415 sym
->st_value
= elf_gp (output_bfd
);
3421 /* Finish up the dynamic sections. */
3424 s7_bfd_score_elf_finish_dynamic_sections (bfd
*output_bfd
,
3425 struct bfd_link_info
*info
)
3431 struct score_got_info
*g
;
3433 dynobj
= elf_hash_table (info
)->dynobj
;
3435 sdyn
= bfd_get_section_by_name (dynobj
, ".dynamic");
3437 sgot
= score_elf_got_section (dynobj
, FALSE
);
3442 BFD_ASSERT (score_elf_section_data (sgot
) != NULL
);
3443 g
= score_elf_section_data (sgot
)->u
.got_info
;
3444 BFD_ASSERT (g
!= NULL
);
3447 if (elf_hash_table (info
)->dynamic_sections_created
)
3451 BFD_ASSERT (sdyn
!= NULL
);
3452 BFD_ASSERT (g
!= NULL
);
3454 for (b
= sdyn
->contents
;
3455 b
< sdyn
->contents
+ sdyn
->size
;
3456 b
+= SCORE_ELF_DYN_SIZE (dynobj
))
3458 Elf_Internal_Dyn dyn
;
3461 bfd_boolean swap_out_p
;
3463 /* Read in the current dynamic entry. */
3464 (*get_elf_backend_data (dynobj
)->s
->swap_dyn_in
) (dynobj
, b
, &dyn
);
3466 /* Assume that we're going to modify it and write it out. */
3472 s
= score_elf_rel_dyn_section (dynobj
, FALSE
);
3473 BFD_ASSERT (s
!= NULL
);
3474 dyn
.d_un
.d_val
= SCORE_ELF_REL_SIZE (dynobj
);
3478 /* Rewrite DT_STRSZ. */
3479 dyn
.d_un
.d_val
= _bfd_elf_strtab_size (elf_hash_table (info
)->dynstr
);
3484 s
= bfd_get_section_by_name (output_bfd
, name
);
3485 BFD_ASSERT (s
!= NULL
);
3486 dyn
.d_un
.d_ptr
= s
->vma
;
3489 case DT_SCORE_BASE_ADDRESS
:
3490 s
= output_bfd
->sections
;
3491 BFD_ASSERT (s
!= NULL
);
3492 dyn
.d_un
.d_ptr
= s
->vma
& ~(bfd_vma
) 0xffff;
3495 case DT_SCORE_LOCAL_GOTNO
:
3496 dyn
.d_un
.d_val
= g
->local_gotno
;
3499 case DT_SCORE_UNREFEXTNO
:
3500 /* The index into the dynamic symbol table which is the
3501 entry of the first external symbol that is not
3502 referenced within the same object. */
3503 dyn
.d_un
.d_val
= bfd_count_sections (output_bfd
) + 1;
3506 case DT_SCORE_GOTSYM
:
3507 if (g
->global_gotsym
)
3509 dyn
.d_un
.d_val
= g
->global_gotsym
->dynindx
;
3512 /* In case if we don't have global got symbols we default
3513 to setting DT_SCORE_GOTSYM to the same value as
3514 DT_SCORE_SYMTABNO, so we just fall through. */
3516 case DT_SCORE_SYMTABNO
:
3518 elemsize
= SCORE_ELF_SYM_SIZE (output_bfd
);
3519 s
= bfd_get_section_by_name (output_bfd
, name
);
3520 BFD_ASSERT (s
!= NULL
);
3522 dyn
.d_un
.d_val
= s
->size
/ elemsize
;
3525 case DT_SCORE_HIPAGENO
:
3526 dyn
.d_un
.d_val
= g
->local_gotno
- SCORE_RESERVED_GOTNO
;
3535 (*get_elf_backend_data (dynobj
)->s
->swap_dyn_out
) (dynobj
, &dyn
, b
);
3539 /* The first entry of the global offset table will be filled at
3540 runtime. The second entry will be used by some runtime loaders.
3541 This isn't the case of IRIX rld. */
3542 if (sgot
!= NULL
&& sgot
->size
> 0)
3544 bfd_put_32 (output_bfd
, 0, sgot
->contents
);
3545 bfd_put_32 (output_bfd
, 0x80000000, sgot
->contents
+ SCORE_ELF_GOT_SIZE (output_bfd
));
3549 elf_section_data (sgot
->output_section
)->this_hdr
.sh_entsize
3550 = SCORE_ELF_GOT_SIZE (output_bfd
);
3553 /* We need to sort the entries of the dynamic relocation section. */
3554 s
= score_elf_rel_dyn_section (dynobj
, FALSE
);
3556 if (s
!= NULL
&& s
->size
> (bfd_vma
)2 * SCORE_ELF_REL_SIZE (output_bfd
))
3558 reldyn_sorting_bfd
= output_bfd
;
3559 qsort ((Elf32_External_Rel
*) s
->contents
+ 1, s
->reloc_count
- 1,
3560 sizeof (Elf32_External_Rel
), score_elf_sort_dynamic_relocs
);
3566 /* This function set up the ELF section header for a BFD section in preparation for writing
3567 it out. This is where the flags and type fields are set for unusual sections. */
3570 s7_bfd_score_elf_fake_sections (bfd
*abfd ATTRIBUTE_UNUSED
,
3571 Elf_Internal_Shdr
*hdr
,
3576 name
= bfd_get_section_name (abfd
, sec
);
3578 if (strcmp (name
, ".got") == 0
3579 || strcmp (name
, ".srdata") == 0
3580 || strcmp (name
, ".sdata") == 0
3581 || strcmp (name
, ".sbss") == 0)
3582 hdr
->sh_flags
|= SHF_SCORE_GPREL
;
3587 /* This function do additional processing on the ELF section header before writing
3588 it out. This is used to set the flags and type fields for some sections. */
3590 /* assign_file_positions_except_relocs() check section flag and if it is allocatable,
3591 warning message will be issued. backend_fake_section is called before
3592 assign_file_positions_except_relocs(); backend_section_processing after it. so, we
3593 modify section flag there, but not backend_fake_section. */
3596 s7_bfd_score_elf_section_processing (bfd
*abfd ATTRIBUTE_UNUSED
, Elf_Internal_Shdr
*hdr
)
3598 if (hdr
->bfd_section
!= NULL
)
3600 const char *name
= bfd_get_section_name (abfd
, hdr
->bfd_section
);
3602 if (strcmp (name
, ".sdata") == 0)
3604 hdr
->sh_flags
|= SHF_ALLOC
| SHF_WRITE
| SHF_SCORE_GPREL
;
3605 hdr
->sh_type
= SHT_PROGBITS
;
3607 else if (strcmp (name
, ".sbss") == 0)
3609 hdr
->sh_flags
|= SHF_ALLOC
| SHF_WRITE
| SHF_SCORE_GPREL
;
3610 hdr
->sh_type
= SHT_NOBITS
;
3612 else if (strcmp (name
, ".srdata") == 0)
3614 hdr
->sh_flags
|= SHF_ALLOC
| SHF_SCORE_GPREL
;
3615 hdr
->sh_type
= SHT_PROGBITS
;
3623 s7_bfd_score_elf_write_section (bfd
*output_bfd
, asection
*sec
, bfd_byte
*contents
)
3625 bfd_byte
*to
, *from
, *end
;
3628 if (strcmp (sec
->name
, ".pdr") != 0)
3631 if (score_elf_section_data (sec
)->u
.tdata
== NULL
)
3635 end
= contents
+ sec
->size
;
3636 for (from
= contents
, i
= 0; from
< end
; from
+= PDR_SIZE
, i
++)
3638 if ((score_elf_section_data (sec
)->u
.tdata
)[i
] == 1)
3642 memcpy (to
, from
, PDR_SIZE
);
3646 bfd_set_section_contents (output_bfd
, sec
->output_section
, contents
,
3647 (file_ptr
) sec
->output_offset
, sec
->size
);
3652 /* Copy data from a SCORE ELF indirect symbol to its direct symbol, hiding the old
3653 indirect symbol. Process additional relocation information. */
3656 s7_bfd_score_elf_copy_indirect_symbol (struct bfd_link_info
*info
,
3657 struct elf_link_hash_entry
*dir
,
3658 struct elf_link_hash_entry
*ind
)
3660 struct score_elf_link_hash_entry
*dirscore
, *indscore
;
3662 _bfd_elf_link_hash_copy_indirect (info
, dir
, ind
);
3664 if (ind
->root
.type
!= bfd_link_hash_indirect
)
3667 dirscore
= (struct score_elf_link_hash_entry
*) dir
;
3668 indscore
= (struct score_elf_link_hash_entry
*) ind
;
3669 dirscore
->possibly_dynamic_relocs
+= indscore
->possibly_dynamic_relocs
;
3671 if (indscore
->readonly_reloc
)
3672 dirscore
->readonly_reloc
= TRUE
;
3674 if (indscore
->no_fn_stub
)
3675 dirscore
->no_fn_stub
= TRUE
;
3678 /* Remove information about discarded functions from other sections which mention them. */
3681 s7_bfd_score_elf_discard_info (bfd
*abfd
,
3682 struct elf_reloc_cookie
*cookie
,
3683 struct bfd_link_info
*info
)
3686 bfd_boolean ret
= FALSE
;
3687 unsigned char *tdata
;
3690 o
= bfd_get_section_by_name (abfd
, ".pdr");
3691 if ((!o
) || (o
->size
== 0) || (o
->size
% PDR_SIZE
!= 0)
3692 || (o
->output_section
!= NULL
&& bfd_is_abs_section (o
->output_section
)))
3695 tdata
= bfd_zmalloc (o
->size
/ PDR_SIZE
);
3699 cookie
->rels
= _bfd_elf_link_read_relocs (abfd
, o
, NULL
, NULL
, info
->keep_memory
);
3706 cookie
->rel
= cookie
->rels
;
3707 cookie
->relend
= cookie
->rels
+ o
->reloc_count
;
3709 for (i
= 0, skip
= 0; i
< o
->size
; i
++)
3711 if (bfd_elf_reloc_symbol_deleted_p (i
* PDR_SIZE
, cookie
))
3720 score_elf_section_data (o
)->u
.tdata
= tdata
;
3721 o
->size
-= skip
* PDR_SIZE
;
3727 if (!info
->keep_memory
)
3728 free (cookie
->rels
);
3733 /* Signal that discard_info() has removed the discarded relocations for this section. */
3736 s7_bfd_score_elf_ignore_discarded_relocs (asection
*sec
)
3738 if (strcmp (sec
->name
, ".pdr") == 0)
3743 /* Return the section that should be marked against GC for a given
3747 s7_bfd_score_elf_gc_mark_hook (asection
*sec
,
3748 struct bfd_link_info
*info
,
3749 Elf_Internal_Rela
*rel
,
3750 struct elf_link_hash_entry
*h
,
3751 Elf_Internal_Sym
*sym
)
3754 switch (ELF32_R_TYPE (rel
->r_info
))
3756 case R_SCORE_GNU_VTINHERIT
:
3757 case R_SCORE_GNU_VTENTRY
:
3761 return _bfd_elf_gc_mark_hook (sec
, info
, rel
, h
, sym
);
3764 /* Support for core dump NOTE sections. */
3767 s7_bfd_score_elf_grok_prstatus (bfd
*abfd
, Elf_Internal_Note
*note
)
3770 unsigned int raw_size
;
3772 switch (note
->descsz
)
3776 case 272: /* Linux/Score elf_prstatus */
3779 elf_tdata (abfd
)->core_signal
= bfd_get_16 (abfd
, note
->descdata
+ 12);
3782 elf_tdata (abfd
)->core_pid
= bfd_get_32 (abfd
, note
->descdata
+ 24);
3787 /* sizeof(elf_gregset_t) */
3793 /* Make a ".reg/999" section. */
3794 return _bfd_elfcore_make_pseudosection (abfd
, ".reg", raw_size
, note
->descpos
+ offset
);
3798 s7_bfd_score_elf_grok_psinfo (bfd
*abfd
, Elf_Internal_Note
*note
)
3800 switch (note
->descsz
)
3805 case 128: /* Linux/Score elf_prpsinfo. */
3807 elf_tdata (abfd
)->core_program
= _bfd_elfcore_strndup (abfd
, note
->descdata
+ 32, 16);
3810 elf_tdata (abfd
)->core_command
= _bfd_elfcore_strndup (abfd
, note
->descdata
+ 48, 80);
3814 /* Note that for some reason, a spurious space is tacked
3815 onto the end of the args in some (at least one anyway)
3816 implementations, so strip it off if it exists. */
3819 char *command
= elf_tdata (abfd
)->core_command
;
3820 int n
= strlen (command
);
3822 if (0 < n
&& command
[n
- 1] == ' ')
3823 command
[n
- 1] = '\0';
3830 /* Score BFD functions. */
3833 s7_elf32_score_reloc_type_lookup (bfd
*abfd ATTRIBUTE_UNUSED
, bfd_reloc_code_real_type code
)
3837 for (i
= 0; i
< ARRAY_SIZE (elf32_score_reloc_map
); i
++)
3838 if (elf32_score_reloc_map
[i
].bfd_reloc_val
== code
)
3839 return &elf32_score_howto_table
[elf32_score_reloc_map
[i
].elf_reloc_val
];
3844 /* Create a score elf linker hash table. */
3846 struct bfd_link_hash_table
*
3847 s7_elf32_score_link_hash_table_create (bfd
*abfd
)
3849 struct score_elf_link_hash_table
*ret
;
3850 bfd_size_type amt
= sizeof (struct score_elf_link_hash_table
);
3852 ret
= bfd_malloc (amt
);
3856 if (!_bfd_elf_link_hash_table_init (&ret
->root
, abfd
, score_elf_link_hash_newfunc
,
3857 sizeof (struct score_elf_link_hash_entry
)))
3863 return &ret
->root
.root
;
3867 s7_elf32_score_print_private_bfd_data (bfd
*abfd
, void * ptr
)
3869 FILE *file
= (FILE *) ptr
;
3871 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
3873 /* Print normal ELF private data. */
3874 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
3876 /* xgettext:c-format */
3877 fprintf (file
, _("private flags = %lx:"), elf_elfheader (abfd
)->e_flags
);
3878 if (elf_elfheader (abfd
)->e_flags
& EF_SCORE_PIC
)
3880 fprintf (file
, _(" [pic]"));
3882 if (elf_elfheader (abfd
)->e_flags
& EF_SCORE_FIXDEP
)
3884 fprintf (file
, _(" [fix dep]"));
3892 s7_elf32_score_merge_private_bfd_data (bfd
*ibfd
, bfd
*obfd
)
3897 if (!_bfd_generic_verify_endian_match (ibfd
, obfd
))
3900 in_flags
= elf_elfheader (ibfd
)->e_flags
;
3901 out_flags
= elf_elfheader (obfd
)->e_flags
;
3903 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
3904 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
3907 in_flags
= elf_elfheader (ibfd
)->e_flags
;
3908 out_flags
= elf_elfheader (obfd
)->e_flags
;
3910 if (! elf_flags_init (obfd
))
3912 elf_flags_init (obfd
) = TRUE
;
3913 elf_elfheader (obfd
)->e_flags
= in_flags
;
3915 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
3916 && bfd_get_arch_info (obfd
)->the_default
)
3918 return bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
), bfd_get_mach (ibfd
));
3924 if (((in_flags
& EF_SCORE_PIC
) != 0) != ((out_flags
& EF_SCORE_PIC
) != 0))
3926 (*_bfd_error_handler
) (_("%B: warning: linking PIC files with non-PIC files"), ibfd
);
3929 /* Maybe dependency fix compatibility should be checked here. */
3934 s7_elf32_score_new_section_hook (bfd
*abfd
, asection
*sec
)
3936 struct _score_elf_section_data
*sdata
;
3937 bfd_size_type amt
= sizeof (*sdata
);
3939 sdata
= bfd_zalloc (abfd
, amt
);
3942 sec
->used_by_bfd
= sdata
;
3944 return _bfd_elf_new_section_hook (abfd
, sec
);
3947 #define elf_backend_omit_section_dynsym \
3948 ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)