1
/* 32-bit ELF support for S+core.
2
Copyright 2009, 2010, 2011, 2012 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
/* The SCORE ELF linker needs additional information for each symbol in
38
the global hash table. */
39
struct score_elf_link_hash_entry
41
struct elf_link_hash_entry root;
43
/* Number of R_SCORE_ABS32, R_SCORE_REL32 relocs against this symbol. */
44
unsigned int possibly_dynamic_relocs;
46
/* If the R_SCORE_ABS32, R_SCORE_REL32 reloc is against a readonly section. */
47
bfd_boolean readonly_reloc;
49
/* We must not create a stub for a symbol that has relocations related to
50
taking the function's address, i.e. any but R_SCORE_CALL15 ones. */
51
bfd_boolean no_fn_stub;
53
/* Are we forced local? This will only be set if we have converted
54
the initial global GOT entry to a local GOT entry. */
55
bfd_boolean forced_local;
58
/* Traverse a score ELF linker hash table. */
59
#define score_elf_link_hash_traverse(table, func, info) \
60
(elf_link_hash_traverse \
62
(bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \
65
/* This structure is used to hold .got entries while estimating got sizes. */
66
struct score_got_entry
68
/* The input bfd in which the symbol is defined. */
70
/* The index of the symbol, as stored in the relocation r_info, if
71
we have a local symbol; -1 otherwise. */
75
/* If abfd == NULL, an address that must be stored in the got. */
77
/* If abfd != NULL && symndx != -1, the addend of the relocation
78
that should be added to the symbol value. */
80
/* If abfd != NULL && symndx == -1, the hash table entry
81
corresponding to a global symbol in the got (or, local, if
83
struct score_elf_link_hash_entry *h;
86
/* The offset from the beginning of the .got section to the entry
87
corresponding to this symbol+addend. If it's a global symbol
88
whose offset is yet to be decided, it's going to be -1. */
92
/* This structure is passed to score_elf_sort_hash_table_f when sorting
93
the dynamic symbols. */
94
struct score_elf_hash_sort_data
96
/* The symbol in the global GOT with the lowest dynamic symbol table index. */
97
struct elf_link_hash_entry *low;
98
/* The least dynamic symbol table index corresponding to a symbol with a GOT entry. */
100
/* The greatest dynamic symbol table index corresponding to a symbol
101
with a GOT entry that is not referenced (e.g., a dynamic symbol
102
with dynamic relocations pointing to it from non-primary GOTs). */
103
long max_unref_got_dynindx;
104
/* The greatest dynamic symbol table index not corresponding to a
105
symbol without a GOT entry. */
106
long max_non_got_dynindx;
109
struct score_got_info
111
/* The global symbol in the GOT with the lowest index in the dynamic
113
struct elf_link_hash_entry *global_gotsym;
114
/* The number of global .got entries. */
115
unsigned int global_gotno;
116
/* The number of local .got entries. */
117
unsigned int local_gotno;
118
/* The number of local .got entries we have used. */
119
unsigned int assigned_gotno;
120
/* A hash table holding members of the got. */
121
struct htab *got_entries;
122
/* In multi-got links, a pointer to the next got (err, rather, most
123
of the time, it points to the previous got). */
124
struct score_got_info *next;
127
/* A structure used to count GOT entries, for GOT entry or ELF symbol table traversal. */
128
struct _score_elf_section_data
130
struct bfd_elf_section_data elf;
133
struct score_got_info *got_info;
139
#define score_elf_section_data(sec) \
140
((struct _score_elf_section_data *) elf_section_data (sec))
142
/* The size of a symbol-table entry. */
143
#define SCORE_ELF_SYM_SIZE(abfd) \
144
(get_elf_backend_data (abfd)->s->sizeof_sym)
146
/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
147
from smaller values. Start with zero, widen, *then* decrement. */
148
#define MINUS_ONE (((bfd_vma)0) - 1)
149
#define MINUS_TWO (((bfd_vma)0) - 2)
154
/* The number of local .got entries we reserve. */
155
#define SCORE_RESERVED_GOTNO (2)
156
#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
158
/* The offset of $gp from the beginning of the .got section. */
159
#define ELF_SCORE_GP_OFFSET(abfd) (0x3ff0)
161
/* The maximum size of the GOT for it to be addressable using 15-bit offsets from $gp. */
162
#define SCORE_ELF_GOT_MAX_SIZE(abfd) (ELF_SCORE_GP_OFFSET(abfd) + 0x3fff)
164
#define SCORE_ELF_STUB_SECTION_NAME (".SCORE.stub")
165
#define SCORE_FUNCTION_STUB_SIZE (16)
167
#define STUB_LW 0xc3bcc010 /* lw r29, [r28, -0x3ff0] */
168
#define STUB_MOVE 0x8323bc56 /* mv r25, r3 */
169
#define STUB_LI16 0x87548000 /* ori r26, .dynsym_index */
170
#define STUB_BRL 0x801dbc09 /* brl r29 */
172
#define SCORE_ELF_GOT_SIZE(abfd) \
173
(get_elf_backend_data (abfd)->s->arch_size / 8)
175
#define SCORE_ELF_ADD_DYNAMIC_ENTRY(info, tag, val) \
176
(_bfd_elf_add_dynamic_entry (info, (bfd_vma) tag, (bfd_vma) val))
178
/* The size of an external dynamic table entry. */
179
#define SCORE_ELF_DYN_SIZE(abfd) \
180
(get_elf_backend_data (abfd)->s->sizeof_dyn)
182
/* The size of an external REL relocation. */
183
#define SCORE_ELF_REL_SIZE(abfd) \
184
(get_elf_backend_data (abfd)->s->sizeof_rel)
186
/* The default alignment for sections, as a power of two. */
187
#define SCORE_ELF_LOG_FILE_ALIGN(abfd)\
188
(get_elf_backend_data (abfd)->s->log_file_align)
190
static bfd_byte *hi16_rel_addr;
192
/* This will be used when we sort the dynamic relocation records. */
193
static bfd *reldyn_sorting_bfd;
195
/* SCORE ELF uses two common sections. One is the usual one, and the
196
other is for small objects. All the small objects are kept
197
together, and then referenced via the gp pointer, which yields
198
faster assembler code. This is what we use for the small common
199
section. This approach is copied from ecoff.c. */
200
static asection score_elf_scom_section;
201
static asymbol score_elf_scom_symbol;
202
static asymbol * score_elf_scom_symbol_ptr;
204
static bfd_reloc_status_type
205
score_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED,
206
arelent *reloc_entry,
207
asymbol *symbol ATTRIBUTE_UNUSED,
209
asection *input_section ATTRIBUTE_UNUSED,
210
bfd *output_bfd ATTRIBUTE_UNUSED,
211
char **error_message ATTRIBUTE_UNUSED)
213
hi16_rel_addr = (bfd_byte *) data + reloc_entry->address;
217
static bfd_reloc_status_type
218
score_elf_lo16_reloc (bfd *abfd,
219
arelent *reloc_entry,
220
asymbol *symbol ATTRIBUTE_UNUSED,
222
asection *input_section,
223
bfd *output_bfd ATTRIBUTE_UNUSED,
224
char **error_message ATTRIBUTE_UNUSED)
226
bfd_vma addend = 0, offset = 0;
228
unsigned long hi16_offset, hi16_value, uvalue;
230
hi16_value = bfd_get_32 (abfd, hi16_rel_addr);
231
hi16_offset = ((((hi16_value >> 16) & 0x3) << 15) | (hi16_value & 0x7fff)) >> 1;
232
addend = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
233
offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
234
val = reloc_entry->addend;
235
if (reloc_entry->address > input_section->size)
236
return bfd_reloc_outofrange;
237
uvalue = ((hi16_offset << 16) | (offset & 0xffff)) + val;
238
hi16_offset = (uvalue >> 16) << 1;
239
hi16_value = (hi16_value & ~0x37fff) | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
240
bfd_put_32 (abfd, hi16_value, hi16_rel_addr);
241
offset = (uvalue & 0xffff) << 1;
242
addend = (addend & ~0x37fff) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
243
bfd_put_32 (abfd, addend, (bfd_byte *) data + reloc_entry->address);
247
/* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
248
dangerous relocation. */
251
score_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
257
/* If we've already figured out what GP will be, just return it. */
258
*pgp = _bfd_get_gp_value (output_bfd);
262
count = bfd_get_symcount (output_bfd);
263
sym = bfd_get_outsymbols (output_bfd);
265
/* The linker script will have created a symbol named `_gp' with the
266
appropriate value. */
271
for (i = 0; i < count; i++, sym++)
275
name = bfd_asymbol_name (*sym);
276
if (*name == '_' && strcmp (name, "_gp") == 0)
278
*pgp = bfd_asymbol_value (*sym);
279
_bfd_set_gp_value (output_bfd, *pgp);
287
/* Only get the error once. */
289
_bfd_set_gp_value (output_bfd, *pgp);
296
/* We have to figure out the gp value, so that we can adjust the
297
symbol value correctly. We look up the symbol _gp in the output
298
BFD. If we can't find it, we're stuck. We cache it in the ELF
299
target data. We don't need to adjust the symbol value for an
300
external symbol if we are producing relocatable output. */
302
static bfd_reloc_status_type
303
score_elf_final_gp (bfd *output_bfd,
305
bfd_boolean relocatable,
306
char **error_message,
309
if (bfd_is_und_section (symbol->section)
313
return bfd_reloc_undefined;
316
*pgp = _bfd_get_gp_value (output_bfd);
319
|| (symbol->flags & BSF_SECTION_SYM) != 0))
323
/* Make up a value. */
324
*pgp = symbol->section->output_section->vma + 0x4000;
325
_bfd_set_gp_value (output_bfd, *pgp);
327
else if (!score_elf_assign_gp (output_bfd, pgp))
330
(char *) _("GP relative relocation when _gp not defined");
331
return bfd_reloc_dangerous;
338
static bfd_reloc_status_type
339
score_elf_gprel15_with_gp (bfd *abfd,
341
arelent *reloc_entry,
342
asection *input_section,
343
bfd_boolean relocateable,
345
bfd_vma gp ATTRIBUTE_UNUSED)
350
if (bfd_is_com_section (symbol->section))
353
relocation = symbol->value;
355
relocation += symbol->section->output_section->vma;
356
relocation += symbol->section->output_offset;
357
if (reloc_entry->address > input_section->size)
358
return bfd_reloc_outofrange;
360
insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
361
if (((reloc_entry->addend & 0xffffc000) != 0)
362
&& ((reloc_entry->addend & 0xffffc000) != 0xffffc000))
363
return bfd_reloc_overflow;
365
insn = (insn & ~0x7fff) | (reloc_entry->addend & 0x7fff);
366
bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
368
reloc_entry->address += input_section->output_offset;
373
static bfd_reloc_status_type
374
gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
375
asection *input_section, bfd_boolean relocatable,
376
void *data, bfd_vma gp)
381
if (bfd_is_com_section (symbol->section))
384
relocation = symbol->value;
386
relocation += symbol->section->output_section->vma;
387
relocation += symbol->section->output_offset;
389
if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
390
return bfd_reloc_outofrange;
392
/* Set val to the offset into the section or symbol. */
393
val = reloc_entry->addend;
395
if (reloc_entry->howto->partial_inplace)
396
val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
398
/* Adjust val for the final section location and GP value. If we
399
are producing relocatable output, we don't want to do this for
400
an external symbol. */
402
|| (symbol->flags & BSF_SECTION_SYM) != 0)
403
val += relocation - gp;
405
if (reloc_entry->howto->partial_inplace)
406
bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
408
reloc_entry->addend = val;
411
reloc_entry->address += input_section->output_offset;
416
static bfd_reloc_status_type
417
score_elf_gprel15_reloc (bfd *abfd,
418
arelent *reloc_entry,
421
asection *input_section,
423
char **error_message)
425
bfd_boolean relocateable;
426
bfd_reloc_status_type ret;
429
if (output_bfd != NULL
430
&& (symbol->flags & BSF_SECTION_SYM) == 0 && reloc_entry->addend == 0)
432
reloc_entry->address += input_section->output_offset;
435
if (output_bfd != NULL)
439
relocateable = FALSE;
440
output_bfd = symbol->section->output_section->owner;
443
ret = score_elf_final_gp (output_bfd, symbol, relocateable, error_message, &gp);
444
if (ret != bfd_reloc_ok)
447
return score_elf_gprel15_with_gp (abfd, symbol, reloc_entry,
448
input_section, relocateable, data, gp);
451
/* Do a R_SCORE_GPREL32 relocation. This is a 32 bit value which must
452
become the offset from the gp register. */
454
static bfd_reloc_status_type
455
score_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
456
void *data, asection *input_section, bfd *output_bfd,
457
char **error_message)
459
bfd_boolean relocatable;
460
bfd_reloc_status_type ret;
463
/* R_SCORE_GPREL32 relocations are defined for local symbols only. */
464
if (output_bfd != NULL
465
&& (symbol->flags & BSF_SECTION_SYM) == 0
466
&& (symbol->flags & BSF_LOCAL) != 0)
468
*error_message = (char *)
469
_("32bits gp relative relocation occurs for an external symbol");
470
return bfd_reloc_outofrange;
473
if (output_bfd != NULL)
478
output_bfd = symbol->section->output_section->owner;
481
ret = score_elf_final_gp (output_bfd, symbol, relocatable, error_message, &gp);
482
if (ret != bfd_reloc_ok)
486
return gprel32_with_gp (abfd, symbol, reloc_entry, input_section,
487
relocatable, data, gp);
490
/* A howto special_function for R_SCORE_GOT15 relocations. This is just
491
like any other 16-bit relocation when applied to global symbols, but is
492
treated in the same as R_SCORE_HI16 when applied to local symbols. */
494
static bfd_reloc_status_type
495
score_elf_got15_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
496
void *data, asection *input_section,
497
bfd *output_bfd, char **error_message)
499
if ((symbol->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
500
|| bfd_is_und_section (bfd_get_section (symbol))
501
|| bfd_is_com_section (bfd_get_section (symbol)))
502
/* The relocation is against a global symbol. */
503
return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
504
input_section, output_bfd,
507
return score_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
508
input_section, output_bfd, error_message);
511
static bfd_reloc_status_type
512
score_elf_got_lo16_reloc (bfd *abfd,
513
arelent *reloc_entry,
514
asymbol *symbol ATTRIBUTE_UNUSED,
516
asection *input_section,
517
bfd *output_bfd ATTRIBUTE_UNUSED,
518
char **error_message ATTRIBUTE_UNUSED)
520
bfd_vma addend = 0, offset = 0;
522
signed long hi16_offset, hi16_value, uvalue;
524
hi16_value = bfd_get_32 (abfd, hi16_rel_addr);
525
hi16_offset = ((((hi16_value >> 16) & 0x3) << 15) | (hi16_value & 0x7fff)) >> 1;
526
addend = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
527
offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
528
val = reloc_entry->addend;
529
if (reloc_entry->address > input_section->size)
530
return bfd_reloc_outofrange;
531
uvalue = ((hi16_offset << 16) | (offset & 0xffff)) + val;
532
if ((uvalue > -0x8000) && (uvalue < 0x7fff))
535
hi16_offset = (uvalue >> 16) & 0x7fff;
536
hi16_value = (hi16_value & ~0x37fff) | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
537
bfd_put_32 (abfd, hi16_value, hi16_rel_addr);
538
offset = (uvalue & 0xffff) << 1;
539
addend = (addend & ~0x37fff) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
540
bfd_put_32 (abfd, addend, (bfd_byte *) data + reloc_entry->address);
544
static reloc_howto_type elf32_score_howto_table[] =
547
HOWTO (R_SCORE_NONE, /* type */
549
0, /* size (0 = byte, 1 = short, 2 = long) */
551
FALSE, /* pc_relative */
553
complain_overflow_dont,/* complain_on_overflow */
554
bfd_elf_generic_reloc, /* special_function */
555
"R_SCORE_NONE", /* name */
556
FALSE, /* partial_inplace */
559
FALSE), /* pcrel_offset */
562
HOWTO (R_SCORE_HI16, /* type */
564
2, /* size (0 = byte, 1 = short, 2 = long) */
566
FALSE, /* pc_relative */
568
complain_overflow_dont,/* complain_on_overflow */
569
score_elf_hi16_reloc, /* special_function */
570
"R_SCORE_HI16", /* name */
571
TRUE, /* partial_inplace */
572
0x37fff, /* src_mask */
573
0x37fff, /* dst_mask */
574
FALSE), /* pcrel_offset */
577
HOWTO (R_SCORE_LO16, /* type */
579
2, /* size (0 = byte, 1 = short, 2 = long) */
581
FALSE, /* pc_relative */
583
complain_overflow_dont,/* complain_on_overflow */
584
score_elf_lo16_reloc, /* special_function */
585
"R_SCORE_LO16", /* name */
586
TRUE, /* partial_inplace */
587
0x37fff, /* src_mask */
588
0x37fff, /* dst_mask */
589
FALSE), /* pcrel_offset */
592
HOWTO (R_SCORE_BCMP, /* type */
594
2, /* size (0 = byte, 1 = short, 2 = long) */
596
FALSE, /* pc_relative */
598
complain_overflow_dont,/* complain_on_overflow */
599
bfd_elf_generic_reloc, /* special_function */
600
"R_SCORE_BCMP", /* name */
601
TRUE, /* partial_inplace */
602
0x0000ffff, /* src_mask */
603
0x0000ffff, /* dst_mask */
604
FALSE), /* pcrel_offset */
606
HOWTO (R_SCORE_24, /* type */
608
2, /* size (0 = byte, 1 = short, 2 = long) */
610
FALSE, /* pc_relative */
612
complain_overflow_dont,/* complain_on_overflow */
613
bfd_elf_generic_reloc, /* special_function */
614
"R_SCORE_24", /* name */
615
FALSE, /* partial_inplace */
616
0x3ff7fff, /* src_mask */
617
0x3ff7fff, /* dst_mask */
618
FALSE), /* pcrel_offset */
621
HOWTO (R_SCORE_PC19, /* type */
623
2, /* size (0 = byte, 1 = short, 2 = long) */
625
TRUE, /* pc_relative */
627
complain_overflow_dont,/* complain_on_overflow */
628
bfd_elf_generic_reloc, /* special_function */
629
"R_SCORE_PC19", /* name */
630
FALSE, /* partial_inplace */
631
0x3ff03fe, /* src_mask */
632
0x3ff03fe, /* dst_mask */
633
FALSE), /* pcrel_offset */
636
HOWTO (R_SCORE16_11, /* type */
638
1, /* size (0 = byte, 1 = short, 2 = long) */
640
FALSE, /* pc_relative */
642
complain_overflow_dont,/* complain_on_overflow */
643
bfd_elf_generic_reloc, /* special_function */
644
"R_SCORE16_11", /* name */
645
FALSE, /* partial_inplace */
646
0x000000ffe, /* src_mask */
647
0x000000ffe, /* dst_mask */
648
FALSE), /* pcrel_offset */
651
HOWTO (R_SCORE16_PC8, /* type */
653
1, /* size (0 = byte, 1 = short, 2 = long) */
655
TRUE, /* pc_relative */
657
complain_overflow_dont,/* complain_on_overflow */
658
bfd_elf_generic_reloc, /* special_function */
659
"R_SCORE16_PC8", /* name */
660
FALSE, /* partial_inplace */
661
0x000000ff, /* src_mask */
662
0x000000ff, /* dst_mask */
663
FALSE), /* pcrel_offset */
665
/* 32 bit absolute */
666
HOWTO (R_SCORE_ABS32, /* type 8 */
668
2, /* size (0 = byte, 1 = short, 2 = long) */
670
FALSE, /* pc_relative */
672
complain_overflow_bitfield, /* complain_on_overflow */
673
bfd_elf_generic_reloc, /* special_function */
674
"R_SCORE_ABS32", /* name */
675
FALSE, /* partial_inplace */
676
0xffffffff, /* src_mask */
677
0xffffffff, /* dst_mask */
678
FALSE), /* pcrel_offset */
680
/* 16 bit absolute */
681
HOWTO (R_SCORE_ABS16, /* type 11 */
683
1, /* size (0 = byte, 1 = short, 2 = long) */
685
FALSE, /* pc_relative */
687
complain_overflow_bitfield, /* complain_on_overflow */
688
bfd_elf_generic_reloc, /* special_function */
689
"R_SCORE_ABS16", /* name */
690
FALSE, /* partial_inplace */
691
0x0000ffff, /* src_mask */
692
0x0000ffff, /* dst_mask */
693
FALSE), /* pcrel_offset */
696
HOWTO (R_SCORE_DUMMY2, /* type */
698
2, /* size (0 = byte, 1 = short, 2 = long) */
700
FALSE, /* pc_relative */
702
complain_overflow_dont,/* complain_on_overflow */
703
bfd_elf_generic_reloc, /* special_function */
704
"R_SCORE_DUMMY2", /* name */
705
TRUE, /* partial_inplace */
706
0x00007fff, /* src_mask */
707
0x00007fff, /* dst_mask */
708
FALSE), /* pcrel_offset */
711
HOWTO (R_SCORE_GP15, /* type */
713
2, /* size (0 = byte, 1 = short, 2 = long) */
715
FALSE, /* pc_relative */
717
complain_overflow_dont,/* complain_on_overflow */
718
score_elf_gprel15_reloc,/* special_function */
719
"R_SCORE_GP15", /* name */
720
TRUE, /* partial_inplace */
721
0x00007fff, /* src_mask */
722
0x00007fff, /* dst_mask */
723
FALSE), /* pcrel_offset */
725
/* GNU extension to record C++ vtable hierarchy. */
726
HOWTO (R_SCORE_GNU_VTINHERIT, /* type */
728
2, /* size (0 = byte, 1 = short, 2 = long) */
730
FALSE, /* pc_relative */
732
complain_overflow_dont,/* complain_on_overflow */
733
NULL, /* special_function */
734
"R_SCORE_GNU_VTINHERIT", /* name */
735
FALSE, /* partial_inplace */
738
FALSE), /* pcrel_offset */
740
/* GNU extension to record C++ vtable member usage */
741
HOWTO (R_SCORE_GNU_VTENTRY, /* type */
743
2, /* size (0 = byte, 1 = short, 2 = long) */
745
FALSE, /* pc_relative */
747
complain_overflow_dont,/* complain_on_overflow */
748
_bfd_elf_rel_vtable_reloc_fn, /* special_function */
749
"R_SCORE_GNU_VTENTRY", /* name */
750
FALSE, /* partial_inplace */
753
FALSE), /* pcrel_offset */
755
/* Reference to global offset table. */
756
HOWTO (R_SCORE_GOT15, /* type */
758
2, /* size (0 = byte, 1 = short, 2 = long) */
760
FALSE, /* pc_relative */
762
complain_overflow_signed, /* complain_on_overflow */
763
score_elf_got15_reloc, /* special_function */
764
"R_SCORE_GOT15", /* name */
765
TRUE, /* partial_inplace */
766
0x00007fff, /* src_mask */
767
0x00007fff, /* dst_mask */
768
FALSE), /* pcrel_offset */
770
/* Low 16 bits of displacement in global offset table. */
771
HOWTO (R_SCORE_GOT_LO16, /* type */
773
2, /* size (0 = byte, 1 = short, 2 = long) */
775
FALSE, /* pc_relative */
777
complain_overflow_dont,/* complain_on_overflow */
778
score_elf_got_lo16_reloc, /* special_function */
779
"R_SCORE_GOT_LO16", /* name */
780
TRUE, /* partial_inplace */
781
0x37ffe, /* src_mask */
782
0x37ffe, /* dst_mask */
783
FALSE), /* pcrel_offset */
785
/* 15 bit call through global offset table. */
786
HOWTO (R_SCORE_CALL15, /* type */
788
2, /* size (0 = byte, 1 = short, 2 = long) */
790
FALSE, /* pc_relative */
792
complain_overflow_signed, /* complain_on_overflow */
793
bfd_elf_generic_reloc, /* special_function */
794
"R_SCORE_CALL15", /* name */
795
TRUE, /* partial_inplace */
796
0x00007fff, /* src_mask */
797
0x00007fff, /* dst_mask */
798
FALSE), /* pcrel_offset */
800
/* 32 bit GP relative reference. */
801
HOWTO (R_SCORE_GPREL32, /* type */
803
2, /* size (0 = byte, 1 = short, 2 = long) */
805
FALSE, /* pc_relative */
807
complain_overflow_dont,/* complain_on_overflow */
808
score_elf_gprel32_reloc, /* special_function */
809
"R_SCORE_GPREL32", /* name */
810
TRUE, /* partial_inplace */
811
0xffffffff, /* src_mask */
812
0xffffffff, /* dst_mask */
813
FALSE), /* pcrel_offset */
815
/* 32 bit symbol relative relocation. */
816
HOWTO (R_SCORE_REL32, /* type */
818
2, /* size (0 = byte, 1 = short, 2 = long) */
820
FALSE, /* pc_relative */
822
complain_overflow_dont,/* complain_on_overflow */
823
bfd_elf_generic_reloc, /* special_function */
824
"R_SCORE_REL32", /* name */
825
TRUE, /* partial_inplace */
826
0xffffffff, /* src_mask */
827
0xffffffff, /* dst_mask */
828
FALSE), /* pcrel_offset */
830
/* R_SCORE_DUMMY_HI16 */
831
HOWTO (R_SCORE_DUMMY_HI16, /* type */
833
2, /* size (0 = byte, 1 = short, 2 = long) */
835
FALSE, /* pc_relative */
837
complain_overflow_dont,/* complain_on_overflow */
838
score_elf_hi16_reloc, /* special_function */
839
"R_SCORE_DUMMY_HI16", /* name */
840
TRUE, /* partial_inplace */
841
0x37fff, /* src_mask */
842
0x37fff, /* dst_mask */
843
FALSE), /* pcrel_offset */
846
struct score_reloc_map
848
bfd_reloc_code_real_type bfd_reloc_val;
849
unsigned char elf_reloc_val;
852
static const struct score_reloc_map elf32_score_reloc_map[] =
854
{BFD_RELOC_NONE, R_SCORE_NONE},
855
{BFD_RELOC_HI16_S, R_SCORE_HI16},
856
{BFD_RELOC_LO16, R_SCORE_LO16},
857
{BFD_RELOC_SCORE_BCMP, R_SCORE_BCMP},
858
{BFD_RELOC_SCORE_JMP, R_SCORE_24},
859
{BFD_RELOC_SCORE_BRANCH, R_SCORE_PC19},
860
{BFD_RELOC_SCORE16_JMP, R_SCORE16_11},
861
{BFD_RELOC_SCORE16_BRANCH, R_SCORE16_PC8},
862
{BFD_RELOC_32, R_SCORE_ABS32},
863
{BFD_RELOC_16, R_SCORE_ABS16},
864
{BFD_RELOC_SCORE_DUMMY2, R_SCORE_DUMMY2},
865
{BFD_RELOC_SCORE_GPREL15, R_SCORE_GP15},
866
{BFD_RELOC_VTABLE_INHERIT, R_SCORE_GNU_VTINHERIT},
867
{BFD_RELOC_VTABLE_ENTRY, R_SCORE_GNU_VTENTRY},
868
{BFD_RELOC_SCORE_GOT15, R_SCORE_GOT15},
869
{BFD_RELOC_SCORE_GOT_LO16, R_SCORE_GOT_LO16},
870
{BFD_RELOC_SCORE_CALL15, R_SCORE_CALL15},
871
{BFD_RELOC_GPREL32, R_SCORE_GPREL32},
872
{BFD_RELOC_32_PCREL, R_SCORE_REL32},
873
{BFD_RELOC_SCORE_DUMMY_HI16, R_SCORE_DUMMY_HI16},
876
static INLINE hashval_t
877
score_elf_hash_bfd_vma (bfd_vma addr)
880
return addr + (addr >> 32);
886
/* got_entries only match if they're identical, except for gotidx, so
887
use all fields to compute the hash, and compare the appropriate
891
score_elf_got_entry_hash (const void *entry_)
893
const struct score_got_entry *entry = (struct score_got_entry *) entry_;
896
+ (! entry->abfd ? score_elf_hash_bfd_vma (entry->d.address)
898
+ (entry->symndx >= 0 ? score_elf_hash_bfd_vma (entry->d.addend)
899
: entry->d.h->root.root.root.hash));
903
score_elf_got_entry_eq (const void *entry1, const void *entry2)
905
const struct score_got_entry *e1 = (struct score_got_entry *) entry1;
906
const struct score_got_entry *e2 = (struct score_got_entry *) entry2;
908
return e1->abfd == e2->abfd && e1->symndx == e2->symndx
909
&& (! e1->abfd ? e1->d.address == e2->d.address
910
: e1->symndx >= 0 ? e1->d.addend == e2->d.addend
911
: e1->d.h == e2->d.h);
914
/* If H needs a GOT entry, assign it the highest available dynamic
915
index. Otherwise, assign it the lowest available dynamic
919
score_elf_sort_hash_table_f (struct score_elf_link_hash_entry *h, void *data)
921
struct score_elf_hash_sort_data *hsd = data;
923
/* Symbols without dynamic symbol table entries aren't interesting at all. */
924
if (h->root.dynindx == -1)
927
/* Global symbols that need GOT entries that are not explicitly
928
referenced are marked with got offset 2. Those that are
929
referenced get a 1, and those that don't need GOT entries get
931
if (h->root.got.offset == 2)
933
if (hsd->max_unref_got_dynindx == hsd->min_got_dynindx)
934
hsd->low = (struct elf_link_hash_entry *) h;
935
h->root.dynindx = hsd->max_unref_got_dynindx++;
937
else if (h->root.got.offset != 1)
938
h->root.dynindx = hsd->max_non_got_dynindx++;
941
h->root.dynindx = --hsd->min_got_dynindx;
942
hsd->low = (struct elf_link_hash_entry *) h;
949
score_elf_got_section (bfd *abfd, bfd_boolean maybe_excluded)
951
asection *sgot = bfd_get_linker_section (abfd, ".got");
953
if (sgot == NULL || (! maybe_excluded && (sgot->flags & SEC_EXCLUDE) != 0))
958
/* Returns the GOT information associated with the link indicated by
959
INFO. If SGOTP is non-NULL, it is filled in with the GOT section. */
961
static struct score_got_info *
962
score_elf_got_info (bfd *abfd, asection **sgotp)
965
struct score_got_info *g;
967
sgot = score_elf_got_section (abfd, TRUE);
968
BFD_ASSERT (sgot != NULL);
969
BFD_ASSERT (elf_section_data (sgot) != NULL);
970
g = score_elf_section_data (sgot)->u.got_info;
971
BFD_ASSERT (g != NULL);
978
/* Sort the dynamic symbol table so that symbols that need GOT entries
979
appear towards the end. This reduces the amount of GOT space
980
required. MAX_LOCAL is used to set the number of local symbols
981
known to be in the dynamic symbol table. During
982
s7_bfd_score_elf_size_dynamic_sections, this value is 1. Afterward, the
983
section symbols are added and the count is higher. */
986
score_elf_sort_hash_table (struct bfd_link_info *info,
987
unsigned long max_local)
989
struct score_elf_hash_sort_data hsd;
990
struct score_got_info *g;
993
dynobj = elf_hash_table (info)->dynobj;
995
g = score_elf_got_info (dynobj, NULL);
998
hsd.max_unref_got_dynindx =
999
hsd.min_got_dynindx = elf_hash_table (info)->dynsymcount
1000
/* In the multi-got case, assigned_gotno of the master got_info
1001
indicate the number of entries that aren't referenced in the
1002
primary GOT, but that must have entries because there are
1003
dynamic relocations that reference it. Since they aren't
1004
referenced, we move them to the end of the GOT, so that they
1005
don't prevent other entries that are referenced from getting
1006
too large offsets. */
1007
- (g->next ? g->assigned_gotno : 0);
1008
hsd.max_non_got_dynindx = max_local;
1009
score_elf_link_hash_traverse (elf_hash_table (info),
1010
score_elf_sort_hash_table_f,
1013
/* There should have been enough room in the symbol table to
1014
accommodate both the GOT and non-GOT symbols. */
1015
BFD_ASSERT (hsd.max_non_got_dynindx <= hsd.min_got_dynindx);
1016
BFD_ASSERT ((unsigned long) hsd.max_unref_got_dynindx
1017
<= elf_hash_table (info)->dynsymcount);
1019
/* Now we know which dynamic symbol has the lowest dynamic symbol
1020
table index in the GOT. */
1021
g->global_gotsym = hsd.low;
1026
/* Returns the first relocation of type r_type found, beginning with
1027
RELOCATION. RELEND is one-past-the-end of the relocation table. */
1029
static const Elf_Internal_Rela *
1030
score_elf_next_relocation (bfd *abfd ATTRIBUTE_UNUSED, unsigned int r_type,
1031
const Elf_Internal_Rela *relocation,
1032
const Elf_Internal_Rela *relend)
1034
while (relocation < relend)
1036
if (ELF32_R_TYPE (relocation->r_info) == r_type)
1042
/* We didn't find it. */
1043
bfd_set_error (bfd_error_bad_value);
1047
/* This function is called via qsort() to sort the dynamic relocation
1048
entries by increasing r_symndx value. */
1050
score_elf_sort_dynamic_relocs (const void *arg1, const void *arg2)
1052
Elf_Internal_Rela int_reloc1;
1053
Elf_Internal_Rela int_reloc2;
1055
bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg1, &int_reloc1);
1056
bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg2, &int_reloc2);
1058
return (ELF32_R_SYM (int_reloc1.r_info) - ELF32_R_SYM (int_reloc2.r_info));
1061
/* Return whether a relocation is against a local symbol. */
1063
score_elf_local_relocation_p (bfd *input_bfd,
1064
const Elf_Internal_Rela *relocation,
1065
asection **local_sections,
1066
bfd_boolean check_forced)
1068
unsigned long r_symndx;
1069
Elf_Internal_Shdr *symtab_hdr;
1070
struct score_elf_link_hash_entry *h;
1073
r_symndx = ELF32_R_SYM (relocation->r_info);
1074
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1075
extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
1077
if (r_symndx < extsymoff)
1079
if (elf_bad_symtab (input_bfd) && local_sections[r_symndx] != NULL)
1084
/* Look up the hash table to check whether the symbol was forced local. */
1085
h = (struct score_elf_link_hash_entry *)
1086
elf_sym_hashes (input_bfd) [r_symndx - extsymoff];
1087
/* Find the real hash-table entry for this symbol. */
1088
while (h->root.root.type == bfd_link_hash_indirect
1089
|| h->root.root.type == bfd_link_hash_warning)
1090
h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
1091
if (h->root.forced_local)
1098
/* Returns the dynamic relocation section for DYNOBJ. */
1101
score_elf_rel_dyn_section (bfd *dynobj, bfd_boolean create_p)
1103
static const char dname[] = ".rel.dyn";
1106
sreloc = bfd_get_linker_section (dynobj, dname);
1107
if (sreloc == NULL && create_p)
1109
sreloc = bfd_make_section_anyway_with_flags (dynobj, dname,
1114
| SEC_LINKER_CREATED
1117
|| ! bfd_set_section_alignment (dynobj, sreloc,
1118
SCORE_ELF_LOG_FILE_ALIGN (dynobj)))
1125
score_elf_allocate_dynamic_relocations (bfd *abfd, unsigned int n)
1129
s = score_elf_rel_dyn_section (abfd, FALSE);
1130
BFD_ASSERT (s != NULL);
1134
/* Make room for a null element. */
1135
s->size += SCORE_ELF_REL_SIZE (abfd);
1138
s->size += n * SCORE_ELF_REL_SIZE (abfd);
1141
/* Create a rel.dyn relocation for the dynamic linker to resolve. REL
1142
is the original relocation, which is now being transformed into a
1143
dynamic relocation. The ADDENDP is adjusted if necessary; the
1144
caller should store the result in place of the original addend. */
1147
score_elf_create_dynamic_relocation (bfd *output_bfd,
1148
struct bfd_link_info *info,
1149
const Elf_Internal_Rela *rel,
1150
struct score_elf_link_hash_entry *h,
1152
bfd_vma *addendp, asection *input_section)
1154
Elf_Internal_Rela outrel[3];
1159
bfd_boolean defined_p;
1161
r_type = ELF32_R_TYPE (rel->r_info);
1162
dynobj = elf_hash_table (info)->dynobj;
1163
sreloc = score_elf_rel_dyn_section (dynobj, FALSE);
1164
BFD_ASSERT (sreloc != NULL);
1165
BFD_ASSERT (sreloc->contents != NULL);
1166
BFD_ASSERT (sreloc->reloc_count * SCORE_ELF_REL_SIZE (output_bfd) < sreloc->size);
1168
outrel[0].r_offset =
1169
_bfd_elf_section_offset (output_bfd, info, input_section, rel[0].r_offset);
1170
outrel[1].r_offset =
1171
_bfd_elf_section_offset (output_bfd, info, input_section, rel[1].r_offset);
1172
outrel[2].r_offset =
1173
_bfd_elf_section_offset (output_bfd, info, input_section, rel[2].r_offset);
1175
if (outrel[0].r_offset == MINUS_ONE)
1176
/* The relocation field has been deleted. */
1179
if (outrel[0].r_offset == MINUS_TWO)
1181
/* The relocation field has been converted into a relative value of
1182
some sort. Functions like _bfd_elf_write_section_eh_frame expect
1183
the field to be fully relocated, so add in the symbol's value. */
1188
/* We must now calculate the dynamic symbol table index to use
1189
in the relocation. */
1191
&& (! info->symbolic || !h->root.def_regular)
1192
/* h->root.dynindx may be -1 if this symbol was marked to
1194
&& h->root.dynindx != -1)
1196
indx = h->root.dynindx;
1197
/* ??? glibc's ld.so just adds the final GOT entry to the
1198
relocation field. It therefore treats relocs against
1199
defined symbols in the same way as relocs against
1200
undefined symbols. */
1209
/* If the relocation was previously an absolute relocation and
1210
this symbol will not be referred to by the relocation, we must
1211
adjust it by the value we give it in the dynamic symbol table.
1212
Otherwise leave the job up to the dynamic linker. */
1213
if (defined_p && r_type != R_SCORE_REL32)
1216
/* The relocation is always an REL32 relocation because we don't
1217
know where the shared library will wind up at load-time. */
1218
outrel[0].r_info = ELF32_R_INFO ((unsigned long) indx, R_SCORE_REL32);
1220
/* For strict adherence to the ABI specification, we should
1221
generate a R_SCORE_64 relocation record by itself before the
1222
_REL32/_64 record as well, such that the addend is read in as
1223
a 64-bit value (REL32 is a 32-bit relocation, after all).
1224
However, since none of the existing ELF64 SCORE dynamic
1225
loaders seems to care, we don't waste space with these
1226
artificial relocations. If this turns out to not be true,
1227
score_elf_allocate_dynamic_relocations() should be tweaked so
1228
as to make room for a pair of dynamic relocations per
1229
invocation if ABI_64_P, and here we should generate an
1230
additional relocation record with R_SCORE_64 by itself for a
1231
NULL symbol before this relocation record. */
1232
outrel[1].r_info = ELF32_R_INFO (0, R_SCORE_NONE);
1233
outrel[2].r_info = ELF32_R_INFO (0, R_SCORE_NONE);
1235
/* Adjust the output offset of the relocation to reference the
1236
correct location in the output file. */
1237
outrel[0].r_offset += (input_section->output_section->vma
1238
+ input_section->output_offset);
1239
outrel[1].r_offset += (input_section->output_section->vma
1240
+ input_section->output_offset);
1241
outrel[2].r_offset += (input_section->output_section->vma
1242
+ input_section->output_offset);
1244
/* Put the relocation back out. We have to use the special
1245
relocation outputter in the 64-bit case since the 64-bit
1246
relocation format is non-standard. */
1247
bfd_elf32_swap_reloc_out
1248
(output_bfd, &outrel[0],
1249
(sreloc->contents + sreloc->reloc_count * sizeof (Elf32_External_Rel)));
1251
/* We've now added another relocation. */
1252
++sreloc->reloc_count;
1254
/* Make sure the output section is writable. The dynamic linker
1255
will be writing to it. */
1256
elf_section_data (input_section->output_section)->this_hdr.sh_flags |= SHF_WRITE;
1262
score_elf_create_got_section (bfd *abfd,
1263
struct bfd_link_info *info,
1264
bfd_boolean maybe_exclude)
1268
struct elf_link_hash_entry *h;
1269
struct bfd_link_hash_entry *bh;
1270
struct score_got_info *g;
1273
/* This function may be called more than once. */
1274
s = score_elf_got_section (abfd, TRUE);
1277
if (! maybe_exclude)
1278
s->flags &= ~SEC_EXCLUDE;
1282
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
1285
flags |= SEC_EXCLUDE;
1287
/* We have to use an alignment of 2**4 here because this is hardcoded
1288
in the function stub generation and in the linker script. */
1289
s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
1291
|| ! bfd_set_section_alignment (abfd, s, 4))
1294
/* Define the symbol _GLOBAL_OFFSET_TABLE_. We don't do this in the
1295
linker script because we don't want to define the symbol if we
1296
are not creating a global offset table. */
1298
if (! (_bfd_generic_link_add_one_symbol
1299
(info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s,
1300
0, NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
1303
h = (struct elf_link_hash_entry *) bh;
1306
h->type = STT_OBJECT;
1308
if (info->shared && ! bfd_elf_link_record_dynamic_symbol (info, h))
1311
amt = sizeof (struct score_got_info);
1312
g = bfd_alloc (abfd, amt);
1316
g->global_gotsym = NULL;
1317
g->global_gotno = 0;
1319
g->local_gotno = SCORE_RESERVED_GOTNO;
1320
g->assigned_gotno = SCORE_RESERVED_GOTNO;
1323
g->got_entries = htab_try_create (1, score_elf_got_entry_hash,
1324
score_elf_got_entry_eq, NULL);
1325
if (g->got_entries == NULL)
1327
score_elf_section_data (s)->u.got_info = g;
1328
score_elf_section_data (s)->elf.this_hdr.sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
1333
/* Calculate the %high function. */
1336
score_elf_high (bfd_vma value)
1338
return ((value + (bfd_vma) 0x8000) >> 16) & 0xffff;
1341
/* Create a local GOT entry for VALUE. Return the index of the entry,
1342
or -1 if it could not be created. */
1344
static struct score_got_entry *
1345
score_elf_create_local_got_entry (bfd *abfd,
1346
bfd *ibfd ATTRIBUTE_UNUSED,
1347
struct score_got_info *gg,
1348
asection *sgot, bfd_vma value,
1349
unsigned long r_symndx ATTRIBUTE_UNUSED,
1350
struct score_elf_link_hash_entry *h ATTRIBUTE_UNUSED,
1351
int r_type ATTRIBUTE_UNUSED)
1353
struct score_got_entry entry, **loc;
1354
struct score_got_info *g;
1358
entry.d.address = value;
1361
loc = (struct score_got_entry **) htab_find_slot (g->got_entries, &entry, INSERT);
1365
entry.gotidx = SCORE_ELF_GOT_SIZE (abfd) * g->assigned_gotno++;
1367
*loc = bfd_alloc (abfd, sizeof entry);
1372
memcpy (*loc, &entry, sizeof entry);
1374
if (g->assigned_gotno >= g->local_gotno)
1376
(*loc)->gotidx = -1;
1377
/* We didn't allocate enough space in the GOT. */
1378
(*_bfd_error_handler)
1379
(_("not enough GOT space for local GOT entries"));
1380
bfd_set_error (bfd_error_bad_value);
1384
bfd_put_32 (abfd, value, (sgot->contents + entry.gotidx));
1389
/* Find a GOT entry whose higher-order 16 bits are the same as those
1390
for value. Return the index into the GOT for this entry. */
1393
score_elf_got16_entry (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
1394
bfd_vma value, bfd_boolean external)
1397
struct score_got_info *g;
1398
struct score_got_entry *entry;
1402
/* Although the ABI says that it is "the high-order 16 bits" that we
1403
want, it is really the %high value. The complete value is
1404
calculated with a `addiu' of a LO16 relocation, just as with a
1406
value = score_elf_high (value) << 16;
1409
g = score_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
1411
entry = score_elf_create_local_got_entry (abfd, ibfd, g, sgot, value, 0, NULL,
1414
return entry->gotidx;
1420
s7_bfd_score_elf_hide_symbol (struct bfd_link_info *info,
1421
struct elf_link_hash_entry *entry,
1422
bfd_boolean force_local)
1426
struct score_got_info *g;
1427
struct score_elf_link_hash_entry *h;
1429
h = (struct score_elf_link_hash_entry *) entry;
1430
if (h->forced_local)
1432
h->forced_local = TRUE;
1434
dynobj = elf_hash_table (info)->dynobj;
1435
if (dynobj != NULL && force_local)
1437
got = score_elf_got_section (dynobj, FALSE);
1440
g = score_elf_section_data (got)->u.got_info;
1444
struct score_got_entry e;
1445
struct score_got_info *gg = g;
1447
/* Since we're turning what used to be a global symbol into a
1448
local one, bump up the number of local entries of each GOT
1449
that had an entry for it. This will automatically decrease
1450
the number of global entries, since global_gotno is actually
1451
the upper limit of global entries. */
1456
for (g = g->next; g != gg; g = g->next)
1457
if (htab_find (g->got_entries, &e))
1459
BFD_ASSERT (g->global_gotno > 0);
1464
/* If this was a global symbol forced into the primary GOT, we
1465
no longer need an entry for it. We can't release the entry
1466
at this point, but we must at least stop counting it as one
1467
of the symbols that required a forced got entry. */
1468
if (h->root.got.offset == 2)
1470
BFD_ASSERT (gg->assigned_gotno > 0);
1471
gg->assigned_gotno--;
1474
else if (g->global_gotno == 0 && g->global_gotsym == NULL)
1475
/* If we haven't got through GOT allocation yet, just bump up the
1476
number of local entries, as this symbol won't be counted as
1479
else if (h->root.got.offset == 1)
1481
/* If we're past non-multi-GOT allocation and this symbol had
1482
been marked for a global got entry, give it a local entry
1484
BFD_ASSERT (g->global_gotno > 0);
1490
_bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
1493
/* If H is a symbol that needs a global GOT entry, but has a dynamic
1494
symbol table index lower than any we've seen to date, record it for
1498
score_elf_record_global_got_symbol (struct elf_link_hash_entry *h,
1500
struct bfd_link_info *info,
1501
struct score_got_info *g)
1503
struct score_got_entry entry, **loc;
1505
/* A global symbol in the GOT must also be in the dynamic symbol table. */
1506
if (h->dynindx == -1)
1508
switch (ELF_ST_VISIBILITY (h->other))
1512
s7_bfd_score_elf_hide_symbol (info, h, TRUE);
1515
if (!bfd_elf_link_record_dynamic_symbol (info, h))
1521
entry.d.h = (struct score_elf_link_hash_entry *) h;
1523
loc = (struct score_got_entry **) htab_find_slot (g->got_entries, &entry, INSERT);
1525
/* If we've already marked this entry as needing GOT space, we don't
1526
need to do it again. */
1530
*loc = bfd_alloc (abfd, sizeof entry);
1536
memcpy (*loc, &entry, sizeof (entry));
1538
if (h->got.offset != MINUS_ONE)
1541
/* By setting this to a value other than -1, we are indicating that
1542
there needs to be a GOT entry for H. Avoid using zero, as the
1543
generic ELF copy_indirect_symbol tests for <= 0. */
1549
/* Reserve space in G for a GOT entry containing the value of symbol
1550
SYMNDX in input bfd ABDF, plus ADDEND. */
1553
score_elf_record_local_got_symbol (bfd *abfd,
1556
struct score_got_info *g)
1558
struct score_got_entry entry, **loc;
1561
entry.symndx = symndx;
1562
entry.d.addend = addend;
1563
loc = (struct score_got_entry **) htab_find_slot (g->got_entries, &entry, INSERT);
1568
entry.gotidx = g->local_gotno++;
1570
*loc = bfd_alloc (abfd, sizeof(entry));
1574
memcpy (*loc, &entry, sizeof (entry));
1579
/* Returns the GOT offset at which the indicated address can be found.
1580
If there is not yet a GOT entry for this value, create one.
1581
Returns -1 if no satisfactory GOT offset can be found. */
1584
score_elf_local_got_index (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
1585
bfd_vma value, unsigned long r_symndx,
1586
struct score_elf_link_hash_entry *h, int r_type)
1589
struct score_got_info *g;
1590
struct score_got_entry *entry;
1592
g = score_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
1594
entry = score_elf_create_local_got_entry (abfd, ibfd, g, sgot, value,
1595
r_symndx, h, r_type);
1600
return entry->gotidx;
1603
/* Returns the GOT index for the global symbol indicated by H. */
1606
score_elf_global_got_index (bfd *abfd, struct elf_link_hash_entry *h)
1610
struct score_got_info *g;
1611
long global_got_dynindx = 0;
1613
g = score_elf_got_info (abfd, &sgot);
1614
if (g->global_gotsym != NULL)
1615
global_got_dynindx = g->global_gotsym->dynindx;
1617
/* Once we determine the global GOT entry with the lowest dynamic
1618
symbol table index, we must put all dynamic symbols with greater
1619
indices into the GOT. That makes it easy to calculate the GOT
1621
BFD_ASSERT (h->dynindx >= global_got_dynindx);
1622
got_index = ((h->dynindx - global_got_dynindx + g->local_gotno) * SCORE_ELF_GOT_SIZE (abfd));
1623
BFD_ASSERT (got_index < sgot->size);
1628
/* Returns the offset for the entry at the INDEXth position in the GOT. */
1631
score_elf_got_offset_from_index (bfd *dynobj,
1633
bfd *input_bfd ATTRIBUTE_UNUSED,
1639
score_elf_got_info (dynobj, &sgot);
1640
gp = _bfd_get_gp_value (output_bfd);
1642
return sgot->output_section->vma + sgot->output_offset + got_index - gp;
1645
/* Follow indirect and warning hash entries so that each got entry
1646
points to the final symbol definition. P must point to a pointer
1647
to the hash table we're traversing. Since this traversal may
1648
modify the hash table, we set this pointer to NULL to indicate
1649
we've made a potentially-destructive change to the hash table, so
1650
the traversal must be restarted. */
1653
score_elf_resolve_final_got_entry (void **entryp, void *p)
1655
struct score_got_entry *entry = (struct score_got_entry *) *entryp;
1656
htab_t got_entries = *(htab_t *) p;
1658
if (entry->abfd != NULL && entry->symndx == -1)
1660
struct score_elf_link_hash_entry *h = entry->d.h;
1662
while (h->root.root.type == bfd_link_hash_indirect
1663
|| h->root.root.type == bfd_link_hash_warning)
1664
h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
1666
if (entry->d.h == h)
1671
/* If we can't find this entry with the new bfd hash, re-insert
1672
it, and get the traversal restarted. */
1673
if (! htab_find (got_entries, entry))
1675
htab_clear_slot (got_entries, entryp);
1676
entryp = htab_find_slot (got_entries, entry, INSERT);
1679
/* Abort the traversal, since the whole table may have
1680
moved, and leave it up to the parent to restart the
1682
*(htab_t *) p = NULL;
1685
/* We might want to decrement the global_gotno count, but it's
1686
either too early or too late for that at this point. */
1692
/* Turn indirect got entries in a got_entries table into their final locations. */
1695
score_elf_resolve_final_got_entries (struct score_got_info *g)
1701
got_entries = g->got_entries;
1703
htab_traverse (got_entries,
1704
score_elf_resolve_final_got_entry,
1707
while (got_entries == NULL);
1710
/* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS. for -r */
1713
score_elf_add_to_rel (bfd *abfd,
1715
reloc_howto_type *howto,
1716
bfd_signed_vma increment)
1718
bfd_signed_vma addend;
1720
unsigned long offset;
1721
unsigned long r_type = howto->type;
1722
unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
1724
contents = bfd_get_32 (abfd, address);
1725
/* Get the (signed) value from the instruction. */
1726
addend = contents & howto->src_mask;
1727
if (addend & ((howto->src_mask + 1) >> 1))
1729
bfd_signed_vma mask;
1732
mask &= ~howto->src_mask;
1735
/* Add in the increment, (which is a byte value). */
1740
(((contents & howto->src_mask) & 0x3ff0000) >> 6) | ((contents & howto->src_mask) & 0x3ff);
1741
offset += increment;
1743
(contents & ~howto->
1744
src_mask) | (((offset << 6) & howto->src_mask) & 0x3ff0000) | (offset & 0x3ff);
1745
bfd_put_32 (abfd, contents, address);
1750
hi16_addend = bfd_get_32 (abfd, address - 4);
1751
hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
1752
offset = ((((contents >> 16) & 0x3) << 15) | (contents & 0x7fff)) >> 1;
1753
offset = (hi16_offset << 16) | (offset & 0xffff);
1754
uvalue = increment + offset;
1755
hi16_offset = (uvalue >> 16) << 1;
1756
hi16_value = (hi16_addend & (~(howto->dst_mask)))
1757
| (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
1758
bfd_put_32 (abfd, hi16_value, address - 4);
1759
offset = (uvalue & 0xffff) << 1;
1760
contents = (contents & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
1761
bfd_put_32 (abfd, contents, address);
1765
(((contents & howto->src_mask) >> 1) & 0x1ff8000) | ((contents & howto->src_mask) & 0x7fff);
1766
offset += increment;
1768
(contents & ~howto->
1769
src_mask) | (((offset << 1) & howto->src_mask) & 0x3ff0000) | (offset & 0x7fff);
1770
bfd_put_32 (abfd, contents, address);
1774
contents = bfd_get_16 (abfd, address);
1775
offset = contents & howto->src_mask;
1776
offset += increment;
1777
contents = (contents & ~howto->src_mask) | (offset & howto->src_mask);
1778
bfd_put_16 (abfd, contents, address);
1783
contents = bfd_get_16 (abfd, address);
1784
offset = (contents & howto->src_mask) + ((increment >> 1) & 0xff);
1785
contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask);
1786
bfd_put_16 (abfd, contents, address);
1790
case R_SCORE_GOT_LO16:
1794
addend += increment;
1795
contents = (contents & ~howto->dst_mask) | (addend & howto->dst_mask);
1796
bfd_put_32 (abfd, contents, address);
1801
/* Perform a relocation as part of a final link. */
1803
static bfd_reloc_status_type
1804
score_elf_final_link_relocate (reloc_howto_type *howto,
1807
asection *input_section,
1809
Elf_Internal_Rela *rel,
1810
Elf_Internal_Rela *relocs,
1812
struct bfd_link_info *info,
1813
const char *sym_name ATTRIBUTE_UNUSED,
1814
int sym_flags ATTRIBUTE_UNUSED,
1815
struct score_elf_link_hash_entry *h,
1816
Elf_Internal_Sym *local_syms,
1817
asection **local_sections,
1818
bfd_boolean gp_disp_p)
1820
unsigned long r_type;
1821
unsigned long r_symndx;
1822
bfd_byte *hit_data = contents + rel->r_offset;
1824
/* The final GP value to be used for the relocatable, executable, or
1825
shared object file being produced. */
1826
bfd_vma gp = MINUS_ONE;
1827
/* The place (section offset or address) of the storage unit being relocated. */
1829
/* The value of GP used to create the relocatable object. */
1830
bfd_vma gp0 = MINUS_ONE;
1831
/* The offset into the global offset table at which the address of the relocation entry
1832
symbol, adjusted by the addend, resides during execution. */
1833
bfd_vma g = MINUS_ONE;
1834
/* TRUE if the symbol referred to by this relocation is a local symbol. */
1835
bfd_boolean local_p;
1836
/* The eventual value we will relocate. */
1837
bfd_vma value = symbol;
1838
unsigned long hi16_addend, hi16_offset, hi16_value, uvalue, offset, abs_value = 0;
1840
Elf_Internal_Sym *sym = 0;
1841
asection *sec = NULL;
1842
bfd_boolean merge_p = 0;
1845
if (elf_gp (output_bfd) == 0)
1847
struct bfd_link_hash_entry *bh;
1850
bh = bfd_link_hash_lookup (info->hash, "_gp", 0, 0, 1);
1851
if (bh != NULL && bh->type == bfd_link_hash_defined)
1852
elf_gp (output_bfd) = (bh->u.def.value
1853
+ bh->u.def.section->output_section->vma
1854
+ bh->u.def.section->output_offset);
1855
else if (info->relocatable)
1859
/* Find the GP-relative section with the lowest offset. */
1860
for (o = output_bfd->sections; o != NULL; o = o->next)
1863
/* And calculate GP relative to that. */
1864
elf_gp (output_bfd) = lo + ELF_SCORE_GP_OFFSET (input_bfd);
1868
/* If the relocate_section function needs to do a reloc
1869
involving the GP value, it should make a reloc_dangerous
1870
callback to warn that GP is not defined. */
1874
/* Parse the relocation. */
1875
r_symndx = ELF32_R_SYM (rel->r_info);
1876
r_type = ELF32_R_TYPE (rel->r_info);
1877
rel_addr = (input_section->output_section->vma + input_section->output_offset + rel->r_offset);
1879
/* For hidden symbol. */
1880
local_p = score_elf_local_relocation_p (input_bfd, rel, local_sections, FALSE);
1883
sym = local_syms + r_symndx;
1884
sec = local_sections[r_symndx];
1886
symbol = sec->output_section->vma + sec->output_offset;
1887
if (ELF_ST_TYPE (sym->st_info) != STT_SECTION
1888
|| (sec->flags & SEC_MERGE))
1889
symbol += sym->st_value;
1890
if ((sec->flags & SEC_MERGE)
1891
&& ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1895
if (r_type == R_SCORE_GOT15)
1897
const Elf_Internal_Rela *relend;
1898
const Elf_Internal_Rela *lo16_rel;
1899
const struct elf_backend_data *bed;
1900
bfd_vma lo_value = 0;
1902
bed = get_elf_backend_data (output_bfd);
1903
relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
1904
lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
1905
if ((local_p) && (lo16_rel != NULL))
1908
tmp = bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
1909
lo_value = (((tmp >> 16) & 0x3) << 14) | ((tmp & 0x7fff) >> 1);
1912
asection *msec = sec;
1913
lo_value = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, lo_value);
1915
lo_value += msec->output_section->vma + msec->output_offset;
1922
addend = (bfd_get_32 (input_bfd, hit_data) >> howto->bitpos) & howto->src_mask;
1925
/* Figure out the value of the symbol. */
1926
if (local_p && !merge_p)
1928
if (r_type == R_SCORE_GOT15)
1930
const Elf_Internal_Rela *relend;
1931
const Elf_Internal_Rela *lo16_rel;
1932
const struct elf_backend_data *bed;
1933
bfd_vma lo_value = 0;
1935
value = bfd_get_32 (input_bfd, contents + rel->r_offset);
1936
addend = value & 0x7fff;
1937
if ((addend & 0x4000) == 0x4000)
1938
addend |= 0xffffc000;
1940
bed = get_elf_backend_data (output_bfd);
1941
relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
1942
lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
1943
if ((local_p) && (lo16_rel != NULL))
1946
tmp = bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
1947
lo_value = (((tmp >> 16) & 0x3) << 14) | ((tmp & 0x7fff) >> 1);
1955
local_p = score_elf_local_relocation_p (input_bfd, rel, local_sections, TRUE);
1957
/* If we haven't already determined the GOT offset, or the GP value,
1958
and we're going to need it, get it now. */
1961
case R_SCORE_CALL15:
1965
g = score_elf_global_got_index (elf_hash_table (info)->dynobj,
1966
(struct elf_link_hash_entry *) h);
1967
if ((! elf_hash_table(info)->dynamic_sections_created
1969
&& (info->symbolic || h->root.dynindx == -1)
1970
&& h->root.def_regular)))
1972
/* This is a static link or a -Bsymbolic link. The
1973
symbol is defined locally, or was forced to be local.
1974
We must initialize this entry in the GOT. */
1975
bfd *tmpbfd = elf_hash_table (info)->dynobj;
1976
asection *sgot = score_elf_got_section (tmpbfd, FALSE);
1977
bfd_put_32 (tmpbfd, value, sgot->contents + g);
1980
else if (r_type == R_SCORE_GOT15 || r_type == R_SCORE_CALL15)
1982
/* There's no need to create a local GOT entry here; the
1983
calculation for a local GOT15 entry does not involve G. */
1988
g = score_elf_local_got_index (output_bfd, input_bfd, info,
1989
symbol + addend, r_symndx, h, r_type);
1991
return bfd_reloc_outofrange;
1994
/* Convert GOT indices to actual offsets. */
1995
g = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
1996
output_bfd, input_bfd, g);
2001
case R_SCORE_GPREL32:
2002
gp0 = _bfd_get_gp_value (input_bfd);
2003
gp = _bfd_get_gp_value (output_bfd);
2007
gp = _bfd_get_gp_value (output_bfd);
2016
return bfd_reloc_ok;
2021
|| (elf_hash_table (info)->dynamic_sections_created
2023
&& h->root.def_dynamic
2024
&& !h->root.def_regular))
2025
&& r_symndx != STN_UNDEF
2026
&& (input_section->flags & SEC_ALLOC) != 0)
2028
/* If we're creating a shared library, or this relocation is against a symbol
2029
in a shared library, then we can't know where the symbol will end up.
2030
So, we create a relocation record in the output, and leave the job up
2031
to the dynamic linker. */
2033
if (!score_elf_create_dynamic_relocation (output_bfd, info, rel, h,
2036
return bfd_reloc_undefined;
2038
else if (r_symndx == STN_UNDEF)
2039
/* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
2040
from removed linkonce sections, or sections discarded by
2045
if (r_type != R_SCORE_REL32)
2046
value = symbol + addend;
2050
value &= howto->dst_mask;
2051
bfd_put_32 (input_bfd, value, hit_data);
2052
return bfd_reloc_ok;
2056
if ((long) value > 0x7fff || (long) value < -0x8000)
2057
return bfd_reloc_overflow;
2058
bfd_put_16 (input_bfd, value, hit_data);
2059
return bfd_reloc_ok;
2062
addend = bfd_get_32 (input_bfd, hit_data);
2063
offset = (((addend & howto->src_mask) >> 1) & 0x1ff8000) | ((addend & howto->src_mask) & 0x7fff);
2064
if ((offset & 0x1000000) != 0)
2065
offset |= 0xfe000000;
2067
abs_value = abs (value - rel_addr);
2068
if ((abs_value & 0xfe000000) != 0)
2069
return bfd_reloc_overflow;
2070
addend = (addend & ~howto->src_mask)
2071
| (((value << 1) & howto->src_mask) & 0x3ff0000) | (value & 0x7fff);
2072
bfd_put_32 (input_bfd, addend, hit_data);
2073
return bfd_reloc_ok;
2076
addend = bfd_get_32 (input_bfd, hit_data);
2077
offset = (((addend & howto->src_mask) & 0x3ff0000) >> 6) | ((addend & howto->src_mask) & 0x3ff);
2078
if ((offset & 0x80000) != 0)
2079
offset |= 0xfff00000;
2080
abs_value = value = value - rel_addr + offset;
2081
/* exceed 20 bit : overflow. */
2082
if ((abs_value & 0x80000000) == 0x80000000)
2083
abs_value = 0xffffffff - value + 1;
2084
if ((abs_value & 0xfff80000) != 0)
2085
return bfd_reloc_overflow;
2086
addend = (addend & ~howto->src_mask)
2087
| (((value << 6) & howto->src_mask) & 0x3ff0000) | (value & 0x3ff);
2088
bfd_put_32 (input_bfd, addend, hit_data);
2089
return bfd_reloc_ok;
2092
addend = bfd_get_16 (input_bfd, hit_data);
2093
offset = addend & howto->src_mask;
2094
if ((offset & 0x800) != 0) /* Offset is negative. */
2095
offset |= 0xfffff000;
2097
abs_value = abs (value - rel_addr);
2098
if ((abs_value & 0xfffff000) != 0)
2099
return bfd_reloc_overflow;
2100
addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
2101
bfd_put_16 (input_bfd, addend, hit_data);
2102
return bfd_reloc_ok;
2105
addend = bfd_get_16 (input_bfd, hit_data);
2106
offset = (addend & howto->src_mask) << 1;
2107
if ((offset & 0x100) != 0) /* Offset is negative. */
2108
offset |= 0xfffffe00;
2109
abs_value = value = value - rel_addr + offset;
2110
/* Sign bit + exceed 9 bit. */
2111
if (((value & 0xffffff00) != 0) && ((value & 0xffffff00) != 0xffffff00))
2112
return bfd_reloc_overflow;
2114
addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
2115
bfd_put_16 (input_bfd, addend, hit_data);
2116
return bfd_reloc_ok;
2119
return bfd_reloc_ok;
2122
hi16_addend = bfd_get_32 (input_bfd, hit_data - 4);
2123
hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
2124
addend = bfd_get_32 (input_bfd, hit_data);
2125
offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
2126
offset = (hi16_offset << 16) | (offset & 0xffff);
2129
uvalue = value + offset;
2131
uvalue = offset + gp - rel_addr + 4;
2133
hi16_offset = (uvalue >> 16) << 1;
2134
hi16_value = (hi16_addend & (~(howto->dst_mask)))
2135
| (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
2136
bfd_put_32 (input_bfd, hi16_value, hit_data - 4);
2137
offset = (uvalue & 0xffff) << 1;
2138
value = (addend & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
2139
bfd_put_32 (input_bfd, value, hit_data);
2140
return bfd_reloc_ok;
2143
addend = bfd_get_32 (input_bfd, hit_data);
2144
offset = addend & 0x7fff;
2145
if ((offset & 0x4000) == 0x4000)
2146
offset |= 0xffffc000;
2147
value = value + offset - gp;
2148
if (((value & 0xffffc000) != 0) && ((value & 0xffffc000) != 0xffffc000))
2149
return bfd_reloc_overflow;
2150
value = (addend & ~howto->src_mask) | (value & howto->src_mask);
2151
bfd_put_32 (input_bfd, value, hit_data);
2152
return bfd_reloc_ok;
2155
case R_SCORE_CALL15:
2160
/* The special case is when the symbol is forced to be local. We need the
2161
full address in the GOT since no R_SCORE_GOT_LO16 relocation follows. */
2162
forced = ! score_elf_local_relocation_p (input_bfd, rel,
2163
local_sections, FALSE);
2164
value = score_elf_got16_entry (output_bfd, input_bfd, info,
2165
symbol + addend, forced);
2166
if (value == MINUS_ONE)
2167
return bfd_reloc_outofrange;
2168
value = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
2169
output_bfd, input_bfd, value);
2176
if ((long) value > 0x3fff || (long) value < -0x4000)
2177
return bfd_reloc_overflow;
2179
addend = bfd_get_32 (input_bfd, hit_data);
2180
value = (addend & ~howto->dst_mask) | (value & howto->dst_mask);
2181
bfd_put_32 (input_bfd, value, hit_data);
2182
return bfd_reloc_ok;
2184
case R_SCORE_GPREL32:
2185
value = (addend + symbol + gp0 - gp);
2186
value &= howto->dst_mask;
2187
bfd_put_32 (input_bfd, value, hit_data);
2188
return bfd_reloc_ok;
2190
case R_SCORE_GOT_LO16:
2191
addend = bfd_get_32 (input_bfd, hit_data);
2192
value = (((addend >> 16) & 0x3) << 14) | ((addend & 0x7fff) >> 1);
2194
value = (addend & (~(howto->dst_mask))) | ((value & 0x3fff) << 1)
2195
| (((value >> 14) & 0x3) << 16);
2197
bfd_put_32 (input_bfd, value, hit_data);
2198
return bfd_reloc_ok;
2200
case R_SCORE_DUMMY_HI16:
2201
return bfd_reloc_ok;
2203
case R_SCORE_GNU_VTINHERIT:
2204
case R_SCORE_GNU_VTENTRY:
2205
/* We don't do anything with these at present. */
2206
return bfd_reloc_continue;
2209
return bfd_reloc_notsupported;
2213
/* Score backend functions. */
2216
s7_bfd_score_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
2218
Elf_Internal_Rela *elf_reloc)
2220
unsigned int r_type;
2222
r_type = ELF32_R_TYPE (elf_reloc->r_info);
2223
if (r_type >= ARRAY_SIZE (elf32_score_howto_table))
2224
bfd_reloc->howto = NULL;
2226
bfd_reloc->howto = &elf32_score_howto_table[r_type];
2229
/* Relocate an score ELF section. */
2232
s7_bfd_score_elf_relocate_section (bfd *output_bfd,
2233
struct bfd_link_info *info,
2235
asection *input_section,
2237
Elf_Internal_Rela *relocs,
2238
Elf_Internal_Sym *local_syms,
2239
asection **local_sections)
2241
Elf_Internal_Shdr *symtab_hdr;
2242
Elf_Internal_Rela *rel;
2243
Elf_Internal_Rela *relend;
2245
unsigned long offset;
2246
unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
2248
bfd_boolean gp_disp_p = FALSE;
2251
if (elf_hash_table (info)->dynamic_sections_created)
2253
bfd_size_type dynsecsymcount = 0;
2257
const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
2259
for (p = output_bfd->sections; p ; p = p->next)
2260
if ((p->flags & SEC_EXCLUDE) == 0
2261
&& (p->flags & SEC_ALLOC) != 0
2262
&& !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p))
2266
if (!score_elf_sort_hash_table (info, dynsecsymcount + 1))
2270
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
2271
extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
2273
relend = relocs + input_section->reloc_count;
2274
for (; rel < relend; rel++)
2277
reloc_howto_type *howto;
2278
unsigned long r_symndx;
2279
Elf_Internal_Sym *sym;
2281
struct score_elf_link_hash_entry *h;
2282
bfd_vma relocation = 0;
2283
bfd_reloc_status_type r;
2286
r_symndx = ELF32_R_SYM (rel->r_info);
2287
r_type = ELF32_R_TYPE (rel->r_info);
2289
s7_bfd_score_info_to_howto (input_bfd, &bfd_reloc, (Elf_Internal_Rela *) rel);
2290
howto = bfd_reloc.howto;
2296
if (r_symndx < extsymoff)
2298
sym = local_syms + r_symndx;
2299
sec = local_sections[r_symndx];
2300
relocation = sec->output_section->vma + sec->output_offset;
2301
name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, sec);
2303
if (!info->relocatable)
2305
if (ELF_ST_TYPE (sym->st_info) != STT_SECTION
2306
|| (sec->flags & SEC_MERGE))
2308
relocation += sym->st_value;
2311
if ((sec->flags & SEC_MERGE)
2312
&& ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2315
bfd_vma addend, value;
2322
hi16_addend = bfd_get_32 (input_bfd, contents + rel->r_offset - 4);
2323
hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
2324
value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2325
offset = ((((value >> 16) & 0x3) << 15) | (value & 0x7fff)) >> 1;
2326
addend = (hi16_offset << 16) | (offset & 0xffff);
2328
addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend);
2329
addend -= relocation;
2330
addend += msec->output_section->vma + msec->output_offset;
2332
hi16_offset = (uvalue >> 16) << 1;
2333
hi16_value = (hi16_addend & (~(howto->dst_mask)))
2334
| (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
2335
bfd_put_32 (input_bfd, hi16_value, contents + rel->r_offset - 4);
2336
offset = (uvalue & 0xffff) << 1;
2337
value = (value & (~(howto->dst_mask)))
2338
| (offset & 0x7fff) | ((offset << 1) & 0x30000);
2339
bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2341
case R_SCORE_GOT_LO16:
2342
value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2343
addend = (((value >> 16) & 0x3) << 14) | ((value & 0x7fff) >> 1);
2345
addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
2346
addend += msec->output_section->vma + msec->output_offset;
2347
value = (value & (~(howto->dst_mask))) | ((addend & 0x3fff) << 1)
2348
| (((addend >> 14) & 0x3) << 16);
2350
bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2353
value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2354
/* Get the (signed) value from the instruction. */
2355
addend = value & howto->src_mask;
2356
if (addend & ((howto->src_mask + 1) >> 1))
2358
bfd_signed_vma mask;
2361
mask &= ~howto->src_mask;
2365
addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
2366
addend += msec->output_section->vma + msec->output_offset;
2367
value = (value & ~howto->dst_mask) | (addend & howto->dst_mask);
2368
bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2376
/* For global symbols we look up the symbol in the hash-table. */
2377
h = ((struct score_elf_link_hash_entry *)
2378
elf_sym_hashes (input_bfd) [r_symndx - extsymoff]);
2379
/* Find the real hash-table entry for this symbol. */
2380
while (h->root.root.type == bfd_link_hash_indirect
2381
|| h->root.root.type == bfd_link_hash_warning)
2382
h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
2384
/* Record the name of this symbol, for our caller. */
2385
name = h->root.root.root.string;
2387
/* See if this is the special GP_DISP_LABEL symbol. Note that such a
2388
symbol must always be a global symbol. */
2389
if (strcmp (name, GP_DISP_LABEL) == 0)
2391
/* Relocations against GP_DISP_LABEL are permitted only with
2392
R_SCORE_HI16 and R_SCORE_LO16 relocations. */
2393
if (r_type != R_SCORE_HI16 && r_type != R_SCORE_LO16)
2394
return bfd_reloc_notsupported;
2399
/* If this symbol is defined, calculate its address. Note that
2400
GP_DISP_LABEL is a magic symbol, always implicitly defined by the
2401
linker, so it's inappropriate to check to see whether or not
2403
else if ((h->root.root.type == bfd_link_hash_defined
2404
|| h->root.root.type == bfd_link_hash_defweak)
2405
&& h->root.root.u.def.section)
2407
sec = h->root.root.u.def.section;
2408
if (sec->output_section)
2409
relocation = (h->root.root.u.def.value
2410
+ sec->output_section->vma
2411
+ sec->output_offset);
2414
relocation = h->root.root.u.def.value;
2417
else if (h->root.root.type == bfd_link_hash_undefweak)
2418
/* We allow relocations against undefined weak symbols, giving
2419
it the value zero, so that you can undefined weak functions
2420
and check to see if they exist by looking at their addresses. */
2422
else if (info->unresolved_syms_in_objects == RM_IGNORE
2423
&& ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
2425
else if (strcmp (name, "_DYNAMIC_LINK") == 0)
2427
/* If this is a dynamic link, we should have created a _DYNAMIC_LINK symbol
2428
in s7_bfd_score_elf_create_dynamic_sections. Otherwise, we should define
2429
the symbol with a value of 0. */
2430
BFD_ASSERT (! info->shared);
2431
BFD_ASSERT (bfd_get_section_by_name (output_bfd, ".dynamic") == NULL);
2434
else if (!info->relocatable)
2436
if (! ((*info->callbacks->undefined_symbol)
2437
(info, h->root.root.root.string, input_bfd,
2438
input_section, rel->r_offset,
2439
(info->unresolved_syms_in_objects == RM_GENERATE_ERROR)
2440
|| ELF_ST_VISIBILITY (h->root.other))))
2441
return bfd_reloc_undefined;
2446
if (sec != NULL && discarded_section (sec))
2447
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
2448
rel, 1, relend, howto, 0, contents);
2450
if (info->relocatable)
2452
/* This is a relocatable link. We don't have to change
2453
anything, unless the reloc is against a section symbol,
2454
in which case we have to adjust according to where the
2455
section symbol winds up in the output section. */
2456
if (r_symndx < symtab_hdr->sh_info)
2458
sym = local_syms + r_symndx;
2460
if (r_type == R_SCORE_GOT15)
2462
const Elf_Internal_Rela *lo16_rel;
2463
const struct elf_backend_data *bed;
2464
bfd_vma lo_addend = 0, lo_value = 0;
2465
bfd_vma addend, value;
2467
value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2468
addend = value & 0x7fff;
2469
if ((addend & 0x4000) == 0x4000)
2470
addend |= 0xffffc000;
2472
bed = get_elf_backend_data (output_bfd);
2473
relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
2474
lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
2475
if (lo16_rel != NULL)
2477
lo_value = bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
2478
lo_addend = (((lo_value >> 16) & 0x3) << 14) | ((lo_value & 0x7fff) >> 1);
2482
addend += lo_addend;
2484
if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2485
addend += local_sections[r_symndx]->output_offset;
2487
lo_addend = addend & 0xffff;
2488
lo_value = (lo_value & (~(howto->dst_mask))) | ((lo_addend & 0x3fff) << 1)
2489
| (((lo_addend >> 14) & 0x3) << 16);
2490
bfd_put_32 (input_bfd, lo_value, contents + lo16_rel->r_offset);
2492
addend = addend >> 16;
2493
value = (value & ~howto->src_mask) | (addend & howto->src_mask);
2494
bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2496
else if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2498
sec = local_sections[r_symndx];
2499
score_elf_add_to_rel (input_bfd, contents + rel->r_offset,
2500
howto, (bfd_signed_vma) (sec->output_offset + sym->st_value));
2506
/* This is a final link. */
2507
r = score_elf_final_link_relocate (howto, input_bfd, output_bfd,
2508
input_section, contents, rel, relocs,
2509
relocation, info, name,
2510
(h ? ELF_ST_TYPE ((unsigned int) h->root.root.type) :
2511
ELF_ST_TYPE ((unsigned int) sym->st_info)), h, local_syms,
2512
local_sections, gp_disp_p);
2514
if (r != bfd_reloc_ok)
2516
const char *msg = (const char *)0;
2520
case bfd_reloc_overflow:
2521
/* If the overflowing reloc was to an undefined symbol,
2522
we have already printed one error message and there
2523
is no point complaining again. */
2524
if (((!h) || (h->root.root.type != bfd_link_hash_undefined))
2525
&& (!((*info->callbacks->reloc_overflow)
2526
(info, NULL, name, howto->name, (bfd_vma) 0,
2527
input_bfd, input_section, rel->r_offset))))
2530
case bfd_reloc_undefined:
2531
if (!((*info->callbacks->undefined_symbol)
2532
(info, name, input_bfd, input_section, rel->r_offset, TRUE)))
2536
case bfd_reloc_outofrange:
2537
msg = _("internal error: out of range error");
2540
case bfd_reloc_notsupported:
2541
msg = _("internal error: unsupported relocation error");
2544
case bfd_reloc_dangerous:
2545
msg = _("internal error: dangerous error");
2549
msg = _("internal error: unknown error");
2553
if (!((*info->callbacks->warning)
2554
(info, msg, name, input_bfd, input_section, rel->r_offset)))
2564
/* Look through the relocs for a section during the first phase, and
2565
allocate space in the global offset table. */
2568
s7_bfd_score_elf_check_relocs (bfd *abfd,
2569
struct bfd_link_info *info,
2571
const Elf_Internal_Rela *relocs)
2575
Elf_Internal_Shdr *symtab_hdr;
2576
struct elf_link_hash_entry **sym_hashes;
2577
struct score_got_info *g;
2579
const Elf_Internal_Rela *rel;
2580
const Elf_Internal_Rela *rel_end;
2583
const struct elf_backend_data *bed;
2585
if (info->relocatable)
2588
dynobj = elf_hash_table (info)->dynobj;
2589
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2590
sym_hashes = elf_sym_hashes (abfd);
2591
extsymoff = (elf_bad_symtab (abfd)) ? 0 : symtab_hdr->sh_info;
2593
name = bfd_get_section_name (abfd, sec);
2602
sgot = score_elf_got_section (dynobj, FALSE);
2607
BFD_ASSERT (score_elf_section_data (sgot) != NULL);
2608
g = score_elf_section_data (sgot)->u.got_info;
2609
BFD_ASSERT (g != NULL);
2614
bed = get_elf_backend_data (abfd);
2615
rel_end = relocs + sec->reloc_count * bed->s->int_rels_per_ext_rel;
2616
for (rel = relocs; rel < rel_end; ++rel)
2618
unsigned long r_symndx;
2619
unsigned int r_type;
2620
struct elf_link_hash_entry *h;
2622
r_symndx = ELF32_R_SYM (rel->r_info);
2623
r_type = ELF32_R_TYPE (rel->r_info);
2625
if (r_symndx < extsymoff)
2629
else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr))
2631
(*_bfd_error_handler) (_("%s: Malformed reloc detected for section %s"), abfd, name);
2632
bfd_set_error (bfd_error_bad_value);
2637
h = sym_hashes[r_symndx - extsymoff];
2639
/* This may be an indirect symbol created because of a version. */
2642
while (h->root.type == bfd_link_hash_indirect)
2643
h = (struct elf_link_hash_entry *) h->root.u.i.link;
2645
/* PR15323, ref flags aren't set for references in the
2647
h->root.non_ir_ref = 1;
2651
/* Some relocs require a global offset table. */
2652
if (dynobj == NULL || sgot == NULL)
2657
case R_SCORE_CALL15:
2659
elf_hash_table (info)->dynobj = dynobj = abfd;
2660
if (!score_elf_create_got_section (dynobj, info, FALSE))
2662
g = score_elf_got_info (dynobj, &sgot);
2666
if (dynobj == NULL && (info->shared || h != NULL) && (sec->flags & SEC_ALLOC) != 0)
2667
elf_hash_table (info)->dynobj = dynobj = abfd;
2674
if (!h && (r_type == R_SCORE_GOT_LO16))
2676
if (! score_elf_record_local_got_symbol (abfd, r_symndx, rel->r_addend, g))
2682
case R_SCORE_CALL15:
2685
(*_bfd_error_handler)
2686
(_("%B: CALL15 reloc at 0x%lx not against global symbol"),
2687
abfd, (unsigned long) rel->r_offset);
2688
bfd_set_error (bfd_error_bad_value);
2693
/* This symbol requires a global offset table entry. */
2694
if (! score_elf_record_global_got_symbol (h, abfd, info, g))
2697
/* We need a stub, not a plt entry for the undefined function. But we record
2698
it as if it needs plt. See _bfd_elf_adjust_dynamic_symbol. */
2704
if (h && ! score_elf_record_global_got_symbol (h, abfd, info, g))
2709
if ((info->shared || h != NULL) && (sec->flags & SEC_ALLOC) != 0)
2713
sreloc = score_elf_rel_dyn_section (dynobj, TRUE);
2717
#define SCORE_READONLY_SECTION (SEC_ALLOC | SEC_LOAD | SEC_READONLY)
2720
/* When creating a shared object, we must copy these reloc types into
2721
the output file as R_SCORE_REL32 relocs. We make room for this reloc
2722
in the .rel.dyn reloc section. */
2723
score_elf_allocate_dynamic_relocations (dynobj, 1);
2724
if ((sec->flags & SCORE_READONLY_SECTION)
2725
== SCORE_READONLY_SECTION)
2726
/* We tell the dynamic linker that there are
2727
relocations against the text segment. */
2728
info->flags |= DF_TEXTREL;
2732
struct score_elf_link_hash_entry *hscore;
2734
/* We only need to copy this reloc if the symbol is
2735
defined in a dynamic object. */
2736
hscore = (struct score_elf_link_hash_entry *) h;
2737
++hscore->possibly_dynamic_relocs;
2738
if ((sec->flags & SCORE_READONLY_SECTION)
2739
== SCORE_READONLY_SECTION)
2740
/* We need it to tell the dynamic linker if there
2741
are relocations against the text segment. */
2742
hscore->readonly_reloc = TRUE;
2745
/* Even though we don't directly need a GOT entry for this symbol,
2746
a symbol must have a dynamic symbol table index greater that
2747
DT_SCORE_GOTSYM if there are dynamic relocations against it. */
2751
elf_hash_table (info)->dynobj = dynobj = abfd;
2752
if (! score_elf_create_got_section (dynobj, info, TRUE))
2754
g = score_elf_got_info (dynobj, &sgot);
2755
if (! score_elf_record_global_got_symbol (h, abfd, info, g))
2761
/* This relocation describes the C++ object vtable hierarchy.
2762
Reconstruct it for later use during GC. */
2763
case R_SCORE_GNU_VTINHERIT:
2764
if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
2768
/* This relocation describes which C++ vtable entries are actually
2769
used. Record for later use during GC. */
2770
case R_SCORE_GNU_VTENTRY:
2771
if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
2778
/* We must not create a stub for a symbol that has relocations
2779
related to taking the function's address. */
2785
struct score_elf_link_hash_entry *sh;
2787
sh = (struct score_elf_link_hash_entry *) h;
2788
sh->no_fn_stub = TRUE;
2791
case R_SCORE_CALL15:
2800
s7_bfd_score_elf_add_symbol_hook (bfd *abfd,
2801
struct bfd_link_info *info ATTRIBUTE_UNUSED,
2802
Elf_Internal_Sym *sym,
2803
const char **namep ATTRIBUTE_UNUSED,
2804
flagword *flagsp ATTRIBUTE_UNUSED,
2808
switch (sym->st_shndx)
2811
if (sym->st_size > elf_gp_size (abfd))
2814
case SHN_SCORE_SCOMMON:
2815
*secp = bfd_make_section_old_way (abfd, ".scommon");
2816
(*secp)->flags |= SEC_IS_COMMON;
2817
*valp = sym->st_size;
2825
s7_bfd_score_elf_symbol_processing (bfd *abfd, asymbol *asym)
2827
elf_symbol_type *elfsym;
2829
elfsym = (elf_symbol_type *) asym;
2830
switch (elfsym->internal_elf_sym.st_shndx)
2833
if (asym->value > elf_gp_size (abfd))
2836
case SHN_SCORE_SCOMMON:
2837
if (score_elf_scom_section.name == NULL)
2839
/* Initialize the small common section. */
2840
score_elf_scom_section.name = ".scommon";
2841
score_elf_scom_section.flags = SEC_IS_COMMON;
2842
score_elf_scom_section.output_section = &score_elf_scom_section;
2843
score_elf_scom_section.symbol = &score_elf_scom_symbol;
2844
score_elf_scom_section.symbol_ptr_ptr = &score_elf_scom_symbol_ptr;
2845
score_elf_scom_symbol.name = ".scommon";
2846
score_elf_scom_symbol.flags = BSF_SECTION_SYM;
2847
score_elf_scom_symbol.section = &score_elf_scom_section;
2848
score_elf_scom_symbol_ptr = &score_elf_scom_symbol;
2850
asym->section = &score_elf_scom_section;
2851
asym->value = elfsym->internal_elf_sym.st_size;
2857
s7_bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
2858
const char *name ATTRIBUTE_UNUSED,
2859
Elf_Internal_Sym *sym,
2860
asection *input_sec,
2861
struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
2863
/* If we see a common symbol, which implies a relocatable link, then
2864
if a symbol was small common in an input file, mark it as small
2865
common in the output file. */
2866
if (sym->st_shndx == SHN_COMMON && strcmp (input_sec->name, ".scommon") == 0)
2867
sym->st_shndx = SHN_SCORE_SCOMMON;
2873
s7_bfd_score_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
2877
if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
2879
*retval = SHN_SCORE_SCOMMON;
2886
/* Adjust a symbol defined by a dynamic object and referenced by a
2887
regular object. The current definition is in some section of the
2888
dynamic object, but we're not including those sections. We have to
2889
change the definition to something the rest of the link can understand. */
2892
s7_bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
2893
struct elf_link_hash_entry *h)
2896
struct score_elf_link_hash_entry *hscore;
2899
dynobj = elf_hash_table (info)->dynobj;
2901
/* Make sure we know what is going on here. */
2902
BFD_ASSERT (dynobj != NULL
2904
|| h->u.weakdef != NULL
2905
|| (h->def_dynamic && h->ref_regular && !h->def_regular)));
2907
/* If this symbol is defined in a dynamic object, we need to copy
2908
any R_SCORE_ABS32 or R_SCORE_REL32 relocs against it into the output
2910
hscore = (struct score_elf_link_hash_entry *) h;
2911
if (!info->relocatable
2912
&& hscore->possibly_dynamic_relocs != 0
2913
&& (h->root.type == bfd_link_hash_defweak || !h->def_regular))
2915
score_elf_allocate_dynamic_relocations (dynobj, hscore->possibly_dynamic_relocs);
2916
if (hscore->readonly_reloc)
2917
/* We tell the dynamic linker that there are relocations
2918
against the text segment. */
2919
info->flags |= DF_TEXTREL;
2922
/* For a function, create a stub, if allowed. */
2923
if (!hscore->no_fn_stub && h->needs_plt)
2925
if (!elf_hash_table (info)->dynamic_sections_created)
2928
/* If this symbol is not defined in a regular file, then set
2929
the symbol to the stub location. This is required to make
2930
function pointers compare as equal between the normal
2931
executable and the shared library. */
2932
if (!h->def_regular)
2934
/* We need .stub section. */
2935
s = bfd_get_linker_section (dynobj, SCORE_ELF_STUB_SECTION_NAME);
2936
BFD_ASSERT (s != NULL);
2938
h->root.u.def.section = s;
2939
h->root.u.def.value = s->size;
2941
/* XXX Write this stub address somewhere. */
2942
h->plt.offset = s->size;
2944
/* Make room for this stub code. */
2945
s->size += SCORE_FUNCTION_STUB_SIZE;
2947
/* The last half word of the stub will be filled with the index
2948
of this symbol in .dynsym section. */
2952
else if ((h->type == STT_FUNC) && !h->needs_plt)
2954
/* This will set the entry for this symbol in the GOT to 0, and
2955
the dynamic linker will take care of this. */
2956
h->root.u.def.value = 0;
2960
/* If this is a weak symbol, and there is a real definition, the
2961
processor independent code will have arranged for us to see the
2962
real definition first, and we can just use the same value. */
2963
if (h->u.weakdef != NULL)
2965
BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2966
|| h->u.weakdef->root.type == bfd_link_hash_defweak);
2967
h->root.u.def.section = h->u.weakdef->root.u.def.section;
2968
h->root.u.def.value = h->u.weakdef->root.u.def.value;
2972
/* This is a reference to a symbol defined by a dynamic object which
2973
is not a function. */
2977
/* This function is called after all the input files have been read,
2978
and the input sections have been assigned to output sections. */
2981
s7_bfd_score_elf_always_size_sections (bfd *output_bfd,
2982
struct bfd_link_info *info)
2986
struct score_got_info *g;
2988
bfd_size_type loadable_size = 0;
2989
bfd_size_type local_gotno;
2992
dynobj = elf_hash_table (info)->dynobj;
2994
/* Relocatable links don't have it. */
2997
g = score_elf_got_info (dynobj, &s);
3001
/* Calculate the total loadable size of the output. That will give us the
3002
maximum number of GOT_PAGE entries required. */
3003
for (sub = info->input_bfds; sub; sub = sub->link_next)
3005
asection *subsection;
3007
for (subsection = sub->sections;
3009
subsection = subsection->next)
3011
if ((subsection->flags & SEC_ALLOC) == 0)
3013
loadable_size += ((subsection->size + 0xf)
3014
&~ (bfd_size_type) 0xf);
3018
/* There has to be a global GOT entry for every symbol with
3019
a dynamic symbol table index of DT_SCORE_GOTSYM or
3020
higher. Therefore, it make sense to put those symbols
3021
that need GOT entries at the end of the symbol table. We
3023
if (! score_elf_sort_hash_table (info, 1))
3026
if (g->global_gotsym != NULL)
3027
i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx;
3029
/* If there are no global symbols, or none requiring
3030
relocations, then GLOBAL_GOTSYM will be NULL. */
3033
/* In the worst case, we'll get one stub per dynamic symbol. */
3034
loadable_size += SCORE_FUNCTION_STUB_SIZE * i;
3036
/* Assume there are two loadable segments consisting of
3037
contiguous sections. Is 5 enough? */
3038
local_gotno = (loadable_size >> 16) + 5;
3040
g->local_gotno += local_gotno;
3041
s->size += g->local_gotno * SCORE_ELF_GOT_SIZE (output_bfd);
3043
g->global_gotno = i;
3044
s->size += i * SCORE_ELF_GOT_SIZE (output_bfd);
3046
score_elf_resolve_final_got_entries (g);
3048
if (s->size > SCORE_ELF_GOT_MAX_SIZE (output_bfd))
3050
/* Fixme. Error message or Warning message should be issued here. */
3056
/* Set the sizes of the dynamic sections. */
3059
s7_bfd_score_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
3063
bfd_boolean reltext;
3065
dynobj = elf_hash_table (info)->dynobj;
3066
BFD_ASSERT (dynobj != NULL);
3068
if (elf_hash_table (info)->dynamic_sections_created)
3070
/* Set the contents of the .interp section to the interpreter. */
3073
s = bfd_get_linker_section (dynobj, ".interp");
3074
BFD_ASSERT (s != NULL);
3075
s->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
3076
s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
3080
/* The check_relocs and adjust_dynamic_symbol entry points have
3081
determined the sizes of the various dynamic sections. Allocate
3084
for (s = dynobj->sections; s != NULL; s = s->next)
3088
if ((s->flags & SEC_LINKER_CREATED) == 0)
3091
/* It's OK to base decisions on the section name, because none
3092
of the dynobj section names depend upon the input files. */
3093
name = bfd_get_section_name (dynobj, s);
3095
if (CONST_STRNEQ (name, ".rel"))
3099
/* We only strip the section if the output section name
3100
has the same name. Otherwise, there might be several
3101
input sections for this output section. FIXME: This
3102
code is probably not needed these days anyhow, since
3103
the linker now does not create empty output sections. */
3104
if (s->output_section != NULL
3106
bfd_get_section_name (s->output_section->owner,
3107
s->output_section)) == 0)
3108
s->flags |= SEC_EXCLUDE;
3112
const char *outname;
3115
/* If this relocation section applies to a read only
3116
section, then we probably need a DT_TEXTREL entry.
3117
If the relocation section is .rel.dyn, we always
3118
assert a DT_TEXTREL entry rather than testing whether
3119
there exists a relocation to a read only section or
3121
outname = bfd_get_section_name (output_bfd, s->output_section);
3122
target = bfd_get_section_by_name (output_bfd, outname + 4);
3124
&& (target->flags & SEC_READONLY) != 0
3125
&& (target->flags & SEC_ALLOC) != 0) || strcmp (outname, ".rel.dyn") == 0)
3128
/* We use the reloc_count field as a counter if we need
3129
to copy relocs into the output file. */
3130
if (strcmp (name, ".rel.dyn") != 0)
3134
else if (CONST_STRNEQ (name, ".got"))
3136
/* s7_bfd_score_elf_always_size_sections() has already done
3137
most of the work, but some symbols may have been mapped
3138
to versions that we must now resolve in the got_entries
3141
else if (strcmp (name, SCORE_ELF_STUB_SECTION_NAME) == 0)
3143
/* IRIX rld assumes that the function stub isn't at the end
3144
of .text section. So put a dummy. XXX */
3145
s->size += SCORE_FUNCTION_STUB_SIZE;
3147
else if (! CONST_STRNEQ (name, ".init"))
3149
/* It's not one of our sections, so don't allocate space. */
3153
/* Allocate memory for the section contents. */
3154
s->contents = bfd_zalloc (dynobj, s->size);
3155
if (s->contents == NULL && s->size != 0)
3157
bfd_set_error (bfd_error_no_memory);
3162
if (elf_hash_table (info)->dynamic_sections_created)
3164
/* Add some entries to the .dynamic section. We fill in the
3165
values later, in s7_bfd_score_elf_finish_dynamic_sections, but we
3166
must add the entries now so that we get the correct size for
3167
the .dynamic section. The DT_DEBUG entry is filled in by the
3168
dynamic linker and used by the debugger. */
3170
if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0))
3174
info->flags |= DF_TEXTREL;
3176
if ((info->flags & DF_TEXTREL) != 0)
3178
if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0))
3182
if (! SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTGOT, 0))
3185
if (score_elf_rel_dyn_section (dynobj, FALSE))
3187
if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_REL, 0))
3190
if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELSZ, 0))
3193
if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELENT, 0))
3197
if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_BASE_ADDRESS, 0))
3200
if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_LOCAL_GOTNO, 0))
3203
if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_SYMTABNO, 0))
3206
if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_UNREFEXTNO, 0))
3209
if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_GOTSYM, 0))
3212
if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_HIPAGENO, 0))
3220
s7_bfd_score_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
3222
struct elf_link_hash_entry *h;
3223
struct bfd_link_hash_entry *bh;
3227
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
3228
| SEC_LINKER_CREATED | SEC_READONLY);
3230
/* ABI requests the .dynamic section to be read only. */
3231
s = bfd_get_linker_section (abfd, ".dynamic");
3234
if (!bfd_set_section_flags (abfd, s, flags))
3238
/* We need to create .got section. */
3239
if (!score_elf_create_got_section (abfd, info, FALSE))
3242
if (!score_elf_rel_dyn_section (elf_hash_table (info)->dynobj, TRUE))
3245
/* Create .stub section. */
3246
if (bfd_get_linker_section (abfd, SCORE_ELF_STUB_SECTION_NAME) == NULL)
3248
s = bfd_make_section_anyway_with_flags (abfd, SCORE_ELF_STUB_SECTION_NAME,
3251
|| !bfd_set_section_alignment (abfd, s, 2))
3260
name = "_DYNAMIC_LINK";
3262
if (!(_bfd_generic_link_add_one_symbol
3263
(info, abfd, name, BSF_GLOBAL, bfd_abs_section_ptr,
3264
(bfd_vma) 0, NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
3267
h = (struct elf_link_hash_entry *) bh;
3270
h->type = STT_SECTION;
3272
if (!bfd_elf_link_record_dynamic_symbol (info, h))
3280
/* Finish up dynamic symbol handling. We set the contents of various
3281
dynamic sections here. */
3284
s7_bfd_score_elf_finish_dynamic_symbol (bfd *output_bfd,
3285
struct bfd_link_info *info,
3286
struct elf_link_hash_entry *h,
3287
Elf_Internal_Sym *sym)
3291
struct score_got_info *g;
3294
dynobj = elf_hash_table (info)->dynobj;
3296
if (h->plt.offset != MINUS_ONE)
3299
bfd_byte stub[SCORE_FUNCTION_STUB_SIZE];
3301
/* This symbol has a stub. Set it up. */
3302
BFD_ASSERT (h->dynindx != -1);
3304
s = bfd_get_linker_section (dynobj, SCORE_ELF_STUB_SECTION_NAME);
3305
BFD_ASSERT (s != NULL);
3307
/* FIXME: Can h->dynindex be more than 64K? */
3308
if (h->dynindx & 0xffff0000)
3311
/* Fill the stub. */
3312
bfd_put_32 (output_bfd, STUB_LW, stub);
3313
bfd_put_32 (output_bfd, STUB_MOVE, stub + 4);
3314
bfd_put_32 (output_bfd, STUB_LI16 | (h->dynindx << 1), stub + 8);
3315
bfd_put_32 (output_bfd, STUB_BRL, stub + 12);
3317
BFD_ASSERT (h->plt.offset <= s->size);
3318
memcpy (s->contents + h->plt.offset, stub, SCORE_FUNCTION_STUB_SIZE);
3320
/* Mark the symbol as undefined. plt.offset != -1 occurs
3321
only for the referenced symbol. */
3322
sym->st_shndx = SHN_UNDEF;
3324
/* The run-time linker uses the st_value field of the symbol
3325
to reset the global offset table entry for this external
3326
to its stub address when unlinking a shared object. */
3327
sym->st_value = (s->output_section->vma + s->output_offset + h->plt.offset);
3330
BFD_ASSERT (h->dynindx != -1 || h->forced_local);
3332
sgot = score_elf_got_section (dynobj, FALSE);
3333
BFD_ASSERT (sgot != NULL);
3334
BFD_ASSERT (score_elf_section_data (sgot) != NULL);
3335
g = score_elf_section_data (sgot)->u.got_info;
3336
BFD_ASSERT (g != NULL);
3338
/* Run through the global symbol table, creating GOT entries for all
3339
the symbols that need them. */
3340
if (g->global_gotsym != NULL && h->dynindx >= g->global_gotsym->dynindx)
3345
value = sym->st_value;
3346
offset = score_elf_global_got_index (dynobj, h);
3347
bfd_put_32 (output_bfd, value, sgot->contents + offset);
3350
/* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
3351
name = h->root.root.string;
3352
if (h == elf_hash_table (info)->hdynamic
3353
|| h == elf_hash_table (info)->hgot)
3354
sym->st_shndx = SHN_ABS;
3355
else if (strcmp (name, "_DYNAMIC_LINK") == 0)
3357
sym->st_shndx = SHN_ABS;
3358
sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
3361
else if (strcmp (name, GP_DISP_LABEL) == 0)
3363
sym->st_shndx = SHN_ABS;
3364
sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
3365
sym->st_value = elf_gp (output_bfd);
3371
/* Finish up the dynamic sections. */
3374
s7_bfd_score_elf_finish_dynamic_sections (bfd *output_bfd,
3375
struct bfd_link_info *info)
3381
struct score_got_info *g;
3383
dynobj = elf_hash_table (info)->dynobj;
3385
sdyn = bfd_get_linker_section (dynobj, ".dynamic");
3387
sgot = score_elf_got_section (dynobj, FALSE);
3392
BFD_ASSERT (score_elf_section_data (sgot) != NULL);
3393
g = score_elf_section_data (sgot)->u.got_info;
3394
BFD_ASSERT (g != NULL);
3397
if (elf_hash_table (info)->dynamic_sections_created)
3401
BFD_ASSERT (sdyn != NULL);
3402
BFD_ASSERT (g != NULL);
3404
for (b = sdyn->contents;
3405
b < sdyn->contents + sdyn->size;
3406
b += SCORE_ELF_DYN_SIZE (dynobj))
3408
Elf_Internal_Dyn dyn;
3411
bfd_boolean swap_out_p;
3413
/* Read in the current dynamic entry. */
3414
(*get_elf_backend_data (dynobj)->s->swap_dyn_in) (dynobj, b, &dyn);
3416
/* Assume that we're going to modify it and write it out. */
3422
s = score_elf_rel_dyn_section (dynobj, FALSE);
3423
BFD_ASSERT (s != NULL);
3424
dyn.d_un.d_val = SCORE_ELF_REL_SIZE (dynobj);
3428
/* Rewrite DT_STRSZ. */
3429
dyn.d_un.d_val = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
3434
s = bfd_get_section_by_name (output_bfd, name);
3435
BFD_ASSERT (s != NULL);
3436
dyn.d_un.d_ptr = s->vma;
3439
case DT_SCORE_BASE_ADDRESS:
3440
s = output_bfd->sections;
3441
BFD_ASSERT (s != NULL);
3442
dyn.d_un.d_ptr = s->vma & ~(bfd_vma) 0xffff;
3445
case DT_SCORE_LOCAL_GOTNO:
3446
dyn.d_un.d_val = g->local_gotno;
3449
case DT_SCORE_UNREFEXTNO:
3450
/* The index into the dynamic symbol table which is the
3451
entry of the first external symbol that is not
3452
referenced within the same object. */
3453
dyn.d_un.d_val = bfd_count_sections (output_bfd) + 1;
3456
case DT_SCORE_GOTSYM:
3457
if (g->global_gotsym)
3459
dyn.d_un.d_val = g->global_gotsym->dynindx;
3462
/* In case if we don't have global got symbols we default
3463
to setting DT_SCORE_GOTSYM to the same value as
3464
DT_SCORE_SYMTABNO, so we just fall through. */
3466
case DT_SCORE_SYMTABNO:
3468
elemsize = SCORE_ELF_SYM_SIZE (output_bfd);
3469
s = bfd_get_section_by_name (output_bfd, name);
3470
BFD_ASSERT (s != NULL);
3472
dyn.d_un.d_val = s->size / elemsize;
3475
case DT_SCORE_HIPAGENO:
3476
dyn.d_un.d_val = g->local_gotno - SCORE_RESERVED_GOTNO;
3485
(*get_elf_backend_data (dynobj)->s->swap_dyn_out) (dynobj, &dyn, b);
3489
/* The first entry of the global offset table will be filled at
3490
runtime. The second entry will be used by some runtime loaders.
3491
This isn't the case of IRIX rld. */
3492
if (sgot != NULL && sgot->size > 0)
3494
bfd_put_32 (output_bfd, 0, sgot->contents);
3495
bfd_put_32 (output_bfd, 0x80000000, sgot->contents + SCORE_ELF_GOT_SIZE (output_bfd));
3499
elf_section_data (sgot->output_section)->this_hdr.sh_entsize
3500
= SCORE_ELF_GOT_SIZE (output_bfd);
3503
/* We need to sort the entries of the dynamic relocation section. */
3504
s = score_elf_rel_dyn_section (dynobj, FALSE);
3506
if (s != NULL && s->size > (bfd_vma)2 * SCORE_ELF_REL_SIZE (output_bfd))
3508
reldyn_sorting_bfd = output_bfd;
3509
qsort ((Elf32_External_Rel *) s->contents + 1, s->reloc_count - 1,
3510
sizeof (Elf32_External_Rel), score_elf_sort_dynamic_relocs);
3516
/* This function set up the ELF section header for a BFD section in preparation for writing
3517
it out. This is where the flags and type fields are set for unusual sections. */
3520
s7_bfd_score_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
3521
Elf_Internal_Shdr *hdr,
3526
name = bfd_get_section_name (abfd, sec);
3528
if (strcmp (name, ".got") == 0
3529
|| strcmp (name, ".srdata") == 0
3530
|| strcmp (name, ".sdata") == 0
3531
|| strcmp (name, ".sbss") == 0)
3532
hdr->sh_flags |= SHF_SCORE_GPREL;
3537
/* This function do additional processing on the ELF section header before writing
3538
it out. This is used to set the flags and type fields for some sections. */
3540
/* assign_file_positions_except_relocs() check section flag and if it is allocatable,
3541
warning message will be issued. backend_fake_section is called before
3542
assign_file_positions_except_relocs(); backend_section_processing after it. so, we
3543
modify section flag there, but not backend_fake_section. */
3546
s7_bfd_score_elf_section_processing (bfd *abfd ATTRIBUTE_UNUSED, Elf_Internal_Shdr *hdr)
3548
if (hdr->bfd_section != NULL)
3550
const char *name = bfd_get_section_name (abfd, hdr->bfd_section);
3552
if (strcmp (name, ".sdata") == 0)
3554
hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
3555
hdr->sh_type = SHT_PROGBITS;
3557
else if (strcmp (name, ".sbss") == 0)
3559
hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
3560
hdr->sh_type = SHT_NOBITS;
3562
else if (strcmp (name, ".srdata") == 0)
3564
hdr->sh_flags |= SHF_ALLOC | SHF_SCORE_GPREL;
3565
hdr->sh_type = SHT_PROGBITS;
3573
s7_bfd_score_elf_write_section (bfd *output_bfd, asection *sec, bfd_byte *contents)
3575
bfd_byte *to, *from, *end;
3578
if (strcmp (sec->name, ".pdr") != 0)
3581
if (score_elf_section_data (sec)->u.tdata == NULL)
3585
end = contents + sec->size;
3586
for (from = contents, i = 0; from < end; from += PDR_SIZE, i++)
3588
if ((score_elf_section_data (sec)->u.tdata)[i] == 1)
3592
memcpy (to, from, PDR_SIZE);
3596
bfd_set_section_contents (output_bfd, sec->output_section, contents,
3597
(file_ptr) sec->output_offset, sec->size);
3602
/* Copy data from a SCORE ELF indirect symbol to its direct symbol, hiding the old
3603
indirect symbol. Process additional relocation information. */
3606
s7_bfd_score_elf_copy_indirect_symbol (struct bfd_link_info *info,
3607
struct elf_link_hash_entry *dir,
3608
struct elf_link_hash_entry *ind)
3610
struct score_elf_link_hash_entry *dirscore, *indscore;
3612
_bfd_elf_link_hash_copy_indirect (info, dir, ind);
3614
if (ind->root.type != bfd_link_hash_indirect)
3617
dirscore = (struct score_elf_link_hash_entry *) dir;
3618
indscore = (struct score_elf_link_hash_entry *) ind;
3619
dirscore->possibly_dynamic_relocs += indscore->possibly_dynamic_relocs;
3621
if (indscore->readonly_reloc)
3622
dirscore->readonly_reloc = TRUE;
3624
if (indscore->no_fn_stub)
3625
dirscore->no_fn_stub = TRUE;
3628
/* Remove information about discarded functions from other sections which mention them. */
3631
s7_bfd_score_elf_discard_info (bfd *abfd,
3632
struct elf_reloc_cookie *cookie,
3633
struct bfd_link_info *info)
3636
bfd_boolean ret = FALSE;
3637
unsigned char *tdata;
3640
o = bfd_get_section_by_name (abfd, ".pdr");
3641
if ((!o) || (o->size == 0) || (o->size % PDR_SIZE != 0)
3642
|| (o->output_section != NULL && bfd_is_abs_section (o->output_section)))
3645
tdata = bfd_zmalloc (o->size / PDR_SIZE);
3649
cookie->rels = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, info->keep_memory);
3656
cookie->rel = cookie->rels;
3657
cookie->relend = cookie->rels + o->reloc_count;
3659
for (i = 0, skip = 0; i < o->size; i++)
3661
if (bfd_elf_reloc_symbol_deleted_p (i * PDR_SIZE, cookie))
3670
score_elf_section_data (o)->u.tdata = tdata;
3671
o->size -= skip * PDR_SIZE;
3677
if (!info->keep_memory)
3678
free (cookie->rels);
3683
/* Signal that discard_info() has removed the discarded relocations for this section. */
3686
s7_bfd_score_elf_ignore_discarded_relocs (asection *sec)
3688
if (strcmp (sec->name, ".pdr") == 0)
3693
/* Return the section that should be marked against GC for a given
3697
s7_bfd_score_elf_gc_mark_hook (asection *sec,
3698
struct bfd_link_info *info,
3699
Elf_Internal_Rela *rel,
3700
struct elf_link_hash_entry *h,
3701
Elf_Internal_Sym *sym)
3704
switch (ELF32_R_TYPE (rel->r_info))
3706
case R_SCORE_GNU_VTINHERIT:
3707
case R_SCORE_GNU_VTENTRY:
3711
return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
3714
/* Support for core dump NOTE sections. */
3717
s7_bfd_score_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
3720
unsigned int raw_size;
3722
switch (note->descsz)
3726
case 272: /* Linux/Score elf_prstatus */
3729
elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
3732
elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
3737
/* sizeof(elf_gregset_t) */
3743
/* Make a ".reg/999" section. */
3744
return _bfd_elfcore_make_pseudosection (abfd, ".reg", raw_size,
3745
note->descpos + offset);
3749
s7_bfd_score_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
3751
switch (note->descsz)
3756
case 128: /* Linux/Score elf_prpsinfo. */
3758
elf_tdata (abfd)->core->program
3759
= _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
3762
elf_tdata (abfd)->core->command
3763
= _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
3767
/* Note that for some reason, a spurious space is tacked
3768
onto the end of the args in some (at least one anyway)
3769
implementations, so strip it off if it exists. */
3772
char *command = elf_tdata (abfd)->core->command;
3773
int n = strlen (command);
3775
if (0 < n && command[n - 1] == ' ')
3776
command[n - 1] = '\0';
3783
/* Score BFD functions. */
3786
s7_elf32_score_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
3790
for (i = 0; i < ARRAY_SIZE (elf32_score_reloc_map); i++)
3791
if (elf32_score_reloc_map[i].bfd_reloc_val == code)
3792
return &elf32_score_howto_table[elf32_score_reloc_map[i].elf_reloc_val];
3798
s7_elf32_score_print_private_bfd_data (bfd *abfd, void * ptr)
3800
FILE *file = (FILE *) ptr;
3802
BFD_ASSERT (abfd != NULL && ptr != NULL);
3804
/* Print normal ELF private data. */
3805
_bfd_elf_print_private_bfd_data (abfd, ptr);
3807
/* xgettext:c-format */
3808
fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
3809
if (elf_elfheader (abfd)->e_flags & EF_SCORE_PIC)
3811
fprintf (file, _(" [pic]"));
3813
if (elf_elfheader (abfd)->e_flags & EF_SCORE_FIXDEP)
3815
fprintf (file, _(" [fix dep]"));
3823
s7_elf32_score_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
3828
if (!_bfd_generic_verify_endian_match (ibfd, obfd))
3831
in_flags = elf_elfheader (ibfd)->e_flags;
3832
out_flags = elf_elfheader (obfd)->e_flags;
3834
if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
3835
|| bfd_get_flavour (obfd) != bfd_target_elf_flavour)
3838
in_flags = elf_elfheader (ibfd)->e_flags;
3839
out_flags = elf_elfheader (obfd)->e_flags;
3841
if (! elf_flags_init (obfd))
3843
elf_flags_init (obfd) = TRUE;
3844
elf_elfheader (obfd)->e_flags = in_flags;
3846
if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
3847
&& bfd_get_arch_info (obfd)->the_default)
3849
return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
3855
if (((in_flags & EF_SCORE_PIC) != 0) != ((out_flags & EF_SCORE_PIC) != 0))
3857
(*_bfd_error_handler) (_("%B: warning: linking PIC files with non-PIC files"), ibfd);
3860
/* Maybe dependency fix compatibility should be checked here. */
3865
s7_elf32_score_new_section_hook (bfd *abfd, asection *sec)
3867
struct _score_elf_section_data *sdata;
3868
bfd_size_type amt = sizeof (*sdata);
3870
sdata = bfd_zalloc (abfd, amt);
3873
sec->used_by_bfd = sdata;
3875
return _bfd_elf_new_section_hook (abfd, sec);
3878
#define elf_backend_omit_section_dynsym \
3879
((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)