]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - bfd/elf32-score.c
* linker.c (fix_syms): Choose best of previous and next
[thirdparty/binutils-gdb.git] / bfd / elf32-score.c
CommitLineData
1c0d3aa6
NC
1/* 32-bit ELF support for S+core.
2 Copyright 2006 Free Software Foundation, Inc.
3 Contributed by
4 Mei Ligang (ligang@sunnorth.com.cn)
5 Pei-Lin Tsai (pltsai@sunplus.com)
6
7 This file is part of BFD, the Binary File Descriptor library.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
22
23#include "bfd.h"
24#include "sysdep.h"
25#include "libbfd.h"
26#include "libiberty.h"
27#include "elf-bfd.h"
28#include "elf/score.h"
29#include "elf/common.h"
30#include "elf/internal.h"
31#include "hashtab.h"
32
33
34/* Score ELF linker hash table. */
35
36struct score_elf_link_hash_table
37{
38 /* The main hash table. */
39 struct elf_link_hash_table root;
40};
41
42/* The SCORE ELF linker needs additional information for each symbol in
43 the global hash table. */
44
45struct score_elf_link_hash_entry
46{
47 struct elf_link_hash_entry root;
48
49 /* Number of R_SCORE_ABS32, R_SCORE_REL32 relocs against this symbol. */
50 unsigned int possibly_dynamic_relocs;
51
52 /* If the R_SCORE_ABS32, R_SCORE_REL32 reloc is against a readonly section. */
53 bfd_boolean readonly_reloc;
54
55 /* We must not create a stub for a symbol that has relocations related to
56 taking the function's address, i.e. any but R_SCORE_CALL15 ones. */
57 bfd_boolean no_fn_stub;
58
59 /* Are we forced local? This will only be set if we have converted
60 the initial global GOT entry to a local GOT entry. */
61 bfd_boolean forced_local;
62};
63
64/* Traverse a score ELF linker hash table. */
65#define score_elf_link_hash_traverse(table, func, info) \
66 (elf_link_hash_traverse \
67 (&(table)->root, \
68 (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \
69 (info)))
70
71/* Get the SCORE elf linker hash table from a link_info structure. */
72#define score_elf_hash_table(info) \
73 ((struct score_elf_link_hash_table *) ((info)->hash))
74
75/* This structure is used to hold .got entries while estimating got sizes. */
76struct score_got_entry
77{
78 /* The input bfd in which the symbol is defined. */
79 bfd *abfd;
80 /* The index of the symbol, as stored in the relocation r_info, if
81 we have a local symbol; -1 otherwise. */
82 long symndx;
83 union
84 {
85 /* If abfd == NULL, an address that must be stored in the got. */
86 bfd_vma address;
87 /* If abfd != NULL && symndx != -1, the addend of the relocation
88 that should be added to the symbol value. */
89 bfd_vma addend;
90 /* If abfd != NULL && symndx == -1, the hash table entry
91 corresponding to a global symbol in the got (or, local, if
92 h->forced_local). */
93 struct score_elf_link_hash_entry *h;
94 } d;
95
96 /* The offset from the beginning of the .got section to the entry
97 corresponding to this symbol+addend. If it's a global symbol
98 whose offset is yet to be decided, it's going to be -1. */
99 long gotidx;
100};
101
102/* This structure is passed to score_elf_sort_hash_table_f when sorting
103 the dynamic symbols. */
104
105struct score_elf_hash_sort_data
106{
107 /* The symbol in the global GOT with the lowest dynamic symbol table index. */
108 struct elf_link_hash_entry *low;
109 /* The least dynamic symbol table index corresponding to a symbol with a GOT entry. */
110 long min_got_dynindx;
111 /* The greatest dynamic symbol table index corresponding to a symbol
112 with a GOT entry that is not referenced (e.g., a dynamic symbol
113 with dynamic relocations pointing to it from non-primary GOTs). */
114 long max_unref_got_dynindx;
115 /* The greatest dynamic symbol table index not corresponding to a
116 symbol without a GOT entry. */
117 long max_non_got_dynindx;
118};
119
120struct score_got_info
121{
122 /* The global symbol in the GOT with the lowest index in the dynamic
123 symbol table. */
124 struct elf_link_hash_entry *global_gotsym;
125 /* The number of global .got entries. */
126 unsigned int global_gotno;
127 /* The number of local .got entries. */
128 unsigned int local_gotno;
129 /* The number of local .got entries we have used. */
130 unsigned int assigned_gotno;
131 /* A hash table holding members of the got. */
132 struct htab *got_entries;
133 /* In multi-got links, a pointer to the next got (err, rather, most
134 of the time, it points to the previous got). */
135 struct score_got_info *next;
136};
137
138/* A structure used to count GOT entries, for GOT entry or ELF symbol table traversal. */
139struct _score_elf_section_data
140{
141 struct bfd_elf_section_data elf;
142 union
143 {
144 struct score_got_info *got_info;
145 bfd_byte *tdata;
146 }
147 u;
148};
149
150#define score_elf_section_data(sec) \
151 ((struct _score_elf_section_data *) elf_section_data (sec))
152
153/* The size of a symbol-table entry. */
154#define SCORE_ELF_SYM_SIZE(abfd) \
155 (get_elf_backend_data (abfd)->s->sizeof_sym)
156
157/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
158 from smaller values. Start with zero, widen, *then* decrement. */
159#define MINUS_ONE (((bfd_vma)0) - 1)
160#define MINUS_TWO (((bfd_vma)0) - 2)
161
162#define PDR_SIZE 32
163
164
165/* The number of local .got entries we reserve. */
166#define SCORE_RESERVED_GOTNO (2)
167#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
168
169/* The offset of $gp from the beginning of the .got section. */
170#define ELF_SCORE_GP_OFFSET(abfd) (0x3ff0)
171/* The maximum size of the GOT for it to be addressable using 15-bit offsets from $gp. */
172#define SCORE_ELF_GOT_MAX_SIZE(abfd) (ELF_SCORE_GP_OFFSET(abfd) + 0x3fff)
173
174#define SCORE_ELF_STUB_SECTION_NAME (".SCORE.stub")
175#define SCORE_FUNCTION_STUB_SIZE (16)
176
177#define STUB_LW 0xc3bcc010 /* lw r29, [r28, -0x3ff0] */
178#define STUB_MOVE 0x8363bc56 /* mv r27, r3 */
179#define STUB_LI16 0x87548000 /* ori r26, .dynsym_index */
180#define STUB_BRL 0x801dbc09 /* brl r29 */
181
182#define SCORE_ELF_GOT_SIZE(abfd) \
183 (get_elf_backend_data (abfd)->s->arch_size / 8)
184
185#define SCORE_ELF_ADD_DYNAMIC_ENTRY(info, tag, val) \
186 (_bfd_elf_add_dynamic_entry (info, (bfd_vma) tag, (bfd_vma) val))
187
188/* The size of an external dynamic table entry. */
189#define SCORE_ELF_DYN_SIZE(abfd) \
190 (get_elf_backend_data (abfd)->s->sizeof_dyn)
191
192/* The size of an external REL relocation. */
193#define SCORE_ELF_REL_SIZE(abfd) \
194 (get_elf_backend_data (abfd)->s->sizeof_rel)
195
196/* The default alignment for sections, as a power of two. */
197#define SCORE_ELF_LOG_FILE_ALIGN(abfd)\
198 (get_elf_backend_data (abfd)->s->log_file_align)
199
200#ifndef NUM_ELEM
201#define NUM_ELEM(a) (sizeof (a) / (sizeof (a)[0]))
202#endif
203
204static bfd_byte *hi16_rel_addr;
205
206/* This will be used when we sort the dynamic relocation records. */
207static bfd *reldyn_sorting_bfd;
208
209/* SCORE ELF uses two common sections. One is the usual one, and the
210 other is for small objects. All the small objects are kept
211 together, and then referenced via the gp pointer, which yields
212 faster assembler code. This is what we use for the small common
213 section. This approach is copied from ecoff.c. */
214static asection score_elf_scom_section;
215static asymbol score_elf_scom_symbol;
216static asymbol *score_elf_scom_symbol_ptr;
217
218static bfd_reloc_status_type
219score_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED,
220 arelent *reloc_entry,
221 asymbol *symbol ATTRIBUTE_UNUSED,
222 void * data,
223 asection *input_section ATTRIBUTE_UNUSED,
224 bfd *output_bfd ATTRIBUTE_UNUSED,
225 char **error_message ATTRIBUTE_UNUSED)
226{
227 hi16_rel_addr = (bfd_byte *) data + reloc_entry->address;
228 return bfd_reloc_ok;
229}
230
231static bfd_reloc_status_type
232score_elf_lo16_reloc (bfd *abfd,
233 arelent *reloc_entry,
234 asymbol *symbol ATTRIBUTE_UNUSED,
235 void * data,
236 asection *input_section,
237 bfd *output_bfd ATTRIBUTE_UNUSED,
238 char **error_message ATTRIBUTE_UNUSED)
239{
240 bfd_vma addend = 0, offset = 0;
241 unsigned long val;
242 unsigned long hi16_offset, hi16_value, uvalue;
243
244 hi16_value = bfd_get_32 (abfd, hi16_rel_addr);
245 hi16_offset = ((((hi16_value >> 16) & 0x3) << 15) | (hi16_value & 0x7fff)) >> 1;
246 addend = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
247 offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
248 val = reloc_entry->addend;
249 if (reloc_entry->address > input_section->size)
250 return bfd_reloc_outofrange;
251 uvalue = ((hi16_offset << 16) | (offset & 0xffff)) + val;
252 hi16_offset = (uvalue >> 16) << 1;
253 hi16_value = (hi16_value & ~0x37fff) | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
254 bfd_put_32 (abfd, hi16_value, hi16_rel_addr);
255 offset = (uvalue & 0xffff) << 1;
256 addend = (addend & ~0x37fff) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
257 bfd_put_32 (abfd, addend, (bfd_byte *) data + reloc_entry->address);
258 return bfd_reloc_ok;
259}
260
261/* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
262 dangerous relocation. */
263
264static bfd_boolean
265score_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
266{
267 unsigned int count;
268 asymbol **sym;
269 unsigned int i;
270
271 /* If we've already figured out what GP will be, just return it. */
272 *pgp = _bfd_get_gp_value (output_bfd);
273 if (*pgp)
274 return TRUE;
275
276 count = bfd_get_symcount (output_bfd);
277 sym = bfd_get_outsymbols (output_bfd);
278
279 /* The linker script will have created a symbol named `_gp' with the
280 appropriate value. */
281 if (sym == NULL)
282 i = count;
283 else
284 {
285 for (i = 0; i < count; i++, sym++)
286 {
287 const char *name;
288
289 name = bfd_asymbol_name (*sym);
290 if (*name == '_' && strcmp (name, "_gp") == 0)
291 {
292 *pgp = bfd_asymbol_value (*sym);
293 _bfd_set_gp_value (output_bfd, *pgp);
294 break;
295 }
296 }
297 }
298
299 if (i >= count)
300 {
301 /* Only get the error once. */
302 *pgp = 4;
303 _bfd_set_gp_value (output_bfd, *pgp);
304 return FALSE;
305 }
306
307 return TRUE;
308}
309
310/* We have to figure out the gp value, so that we can adjust the
311 symbol value correctly. We look up the symbol _gp in the output
312 BFD. If we can't find it, we're stuck. We cache it in the ELF
313 target data. We don't need to adjust the symbol value for an
314 external symbol if we are producing relocatable output. */
315
316static bfd_reloc_status_type
317score_elf_final_gp (bfd *output_bfd,
318 asymbol *symbol,
319 bfd_boolean relocatable,
320 char **error_message,
321 bfd_vma *pgp)
322{
323 if (bfd_is_und_section (symbol->section)
324 && ! relocatable)
325 {
326 *pgp = 0;
327 return bfd_reloc_undefined;
328 }
329
330 *pgp = _bfd_get_gp_value (output_bfd);
331 if (*pgp == 0
332 && (! relocatable
333 || (symbol->flags & BSF_SECTION_SYM) != 0))
334 {
335 if (relocatable)
336 {
337 /* Make up a value. */
338 *pgp = symbol->section->output_section->vma + 0x4000;
339 _bfd_set_gp_value (output_bfd, *pgp);
340 }
341 else if (!score_elf_assign_gp (output_bfd, pgp))
342 {
343 *error_message =
344 (char *) _("GP relative relocation when _gp not defined");
345 return bfd_reloc_dangerous;
346 }
347 }
348
349 return bfd_reloc_ok;
350}
351
352static bfd_reloc_status_type
353score_elf_gprel15_with_gp (bfd *abfd,
354 asymbol *symbol,
355 arelent *reloc_entry,
356 asection *input_section,
357 bfd_boolean relocateable,
358 void * data,
359 bfd_vma gp ATTRIBUTE_UNUSED)
360{
361 bfd_vma relocation;
362 unsigned long insn;
363
364 if (bfd_is_com_section (symbol->section))
365 relocation = 0;
366 else
367 relocation = symbol->value;
368
369 relocation += symbol->section->output_section->vma;
370 relocation += symbol->section->output_offset;
371 if (reloc_entry->address > input_section->size)
372 return bfd_reloc_outofrange;
373
374 insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
375 if (((reloc_entry->addend & 0xffffc000) != 0)
376 && ((reloc_entry->addend & 0xffffc000) != 0xffffc000))
377 return bfd_reloc_overflow;
378
379 insn = (insn & ~0x7fff) | (reloc_entry->addend & 0x7fff);
380 bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
381 if (relocateable)
382 reloc_entry->address += input_section->output_offset;
383
384 return bfd_reloc_ok;
385}
386
387static bfd_reloc_status_type
388gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
389 asection *input_section, bfd_boolean relocatable,
390 void *data, bfd_vma gp)
391{
392 bfd_vma relocation;
393 bfd_vma val;
394
395 if (bfd_is_com_section (symbol->section))
396 relocation = 0;
397 else
398 relocation = symbol->value;
399
400 relocation += symbol->section->output_section->vma;
401 relocation += symbol->section->output_offset;
402
403 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
404 return bfd_reloc_outofrange;
405
406 /* Set val to the offset into the section or symbol. */
407 val = reloc_entry->addend;
408
409 if (reloc_entry->howto->partial_inplace)
410 val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
411
412 /* Adjust val for the final section location and GP value. If we
413 are producing relocatable output, we don't want to do this for
414 an external symbol. */
415 if (! relocatable
416 || (symbol->flags & BSF_SECTION_SYM) != 0)
417 val += relocation - gp;
418
419 if (reloc_entry->howto->partial_inplace)
420 bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
421 else
422 reloc_entry->addend = val;
423
424 if (relocatable)
425 reloc_entry->address += input_section->output_offset;
426
427 return bfd_reloc_ok;
428}
429
430static bfd_reloc_status_type
431score_elf_gprel15_reloc (bfd *abfd,
432 arelent *reloc_entry,
433 asymbol *symbol,
434 void * data,
435 asection *input_section,
436 bfd *output_bfd,
437 char **error_message)
438{
439 bfd_boolean relocateable;
440 bfd_reloc_status_type ret;
441 bfd_vma gp;
442
443 if (output_bfd != (bfd *) NULL
444 && (symbol->flags & BSF_SECTION_SYM) == 0 && reloc_entry->addend == 0)
445 {
446 reloc_entry->address += input_section->output_offset;
447 return bfd_reloc_ok;
448 }
449 if (output_bfd != (bfd *) NULL)
450 relocateable = TRUE;
451 else
452 {
453 relocateable = FALSE;
454 output_bfd = symbol->section->output_section->owner;
455 }
456
457 ret = score_elf_final_gp (output_bfd, symbol, relocateable, error_message, &gp);
458 if (ret != bfd_reloc_ok)
459 return ret;
460
461 return score_elf_gprel15_with_gp (abfd, symbol, reloc_entry,
462 input_section, relocateable, data, gp);
463}
464
465/* Do a R_SCORE_GPREL32 relocation. This is a 32 bit value which must
466 become the offset from the gp register. */
467
468static bfd_reloc_status_type
469score_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
470 void *data, asection *input_section, bfd *output_bfd,
471 char **error_message)
472{
473 bfd_boolean relocatable;
474 bfd_reloc_status_type ret;
475 bfd_vma gp;
476
477 /* R_SCORE_GPREL32 relocations are defined for local symbols only. */
478 if (output_bfd != NULL
479 && (symbol->flags & BSF_SECTION_SYM) == 0
480 && (symbol->flags & BSF_LOCAL) != 0)
481 {
482 *error_message = (char *)
483 _("32bits gp relative relocation occurs for an external symbol");
484 return bfd_reloc_outofrange;
485 }
486
487 if (output_bfd != NULL)
488 relocatable = TRUE;
489 else
490 {
491 relocatable = FALSE;
492 output_bfd = symbol->section->output_section->owner;
493 }
494
495 ret = score_elf_final_gp (output_bfd, symbol, relocatable, error_message, &gp);
496 if (ret != bfd_reloc_ok)
497 return ret;
498
499 gp = 0; /* FIXME. */
500 return gprel32_with_gp (abfd, symbol, reloc_entry, input_section,
501 relocatable, data, gp);
502}
503
504/* A howto special_function for R_SCORE_GOT15 relocations. This is just
505 like any other 16-bit relocation when applied to global symbols, but is
506 treated in the same as R_SCORE_HI16 when applied to local symbols. */
507
508static bfd_reloc_status_type
509score_elf_got15_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
510 void *data, asection *input_section,
511 bfd *output_bfd, char **error_message)
512{
513 if ((symbol->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
514 || bfd_is_und_section (bfd_get_section (symbol))
515 || bfd_is_com_section (bfd_get_section (symbol)))
516 /* The relocation is against a global symbol. */
517 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
518 input_section, output_bfd,
519 error_message);
520
521 return score_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
522 input_section, output_bfd, error_message);
523}
524
525static bfd_reloc_status_type
526score_elf_got_lo16_reloc (bfd *abfd,
527 arelent *reloc_entry,
528 asymbol *symbol ATTRIBUTE_UNUSED,
529 void * data,
530 asection *input_section,
531 bfd *output_bfd ATTRIBUTE_UNUSED,
532 char **error_message ATTRIBUTE_UNUSED)
533{
534 bfd_vma addend = 0, offset = 0;
535 unsigned long val;
536 unsigned long hi16_offset, hi16_value, uvalue;
537
538 hi16_value = bfd_get_32 (abfd, hi16_rel_addr);
539 hi16_offset = ((((hi16_value >> 16) & 0x3) << 15) | (hi16_value & 0x7fff)) >> 1;
540 addend = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
541 offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
542 val = reloc_entry->addend;
543 if (reloc_entry->address > input_section->size)
544 return bfd_reloc_outofrange;
545 uvalue = ((hi16_offset << 16) | (offset & 0xffff)) + val;
546 hi16_offset = (uvalue >> 16) & 0x7fff;
547 hi16_value = (hi16_value & ~0x37fff) | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
548 bfd_put_32 (abfd, hi16_value, hi16_rel_addr);
549 offset = (uvalue & 0xffff) << 1;
550 addend = (addend & ~0x37fff) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
551 bfd_put_32 (abfd, addend, (bfd_byte *) data + reloc_entry->address);
552 return bfd_reloc_ok;
553}
554
555static reloc_howto_type elf32_score_howto_table[] =
556{
557 /* No relocation. */
558 HOWTO (R_SCORE_NONE, /* type */
559 0, /* rightshift */
560 0, /* size (0 = byte, 1 = short, 2 = long) */
561 0, /* bitsize */
562 FALSE, /* pc_relative */
563 0, /* bitpos */
564 complain_overflow_dont,/* complain_on_overflow */
565 bfd_elf_generic_reloc, /* special_function */
566 "R_SCORE_NONE", /* name */
567 FALSE, /* partial_inplace */
568 0, /* src_mask */
569 0, /* dst_mask */
570 FALSE), /* pcrel_offset */
571
572 /* R_SCORE_HI16 */
573 HOWTO (R_SCORE_HI16, /* type */
574 0, /* rightshift */
575 2, /* size (0 = byte, 1 = short, 2 = long) */
576 16, /* bitsize */
577 FALSE, /* pc_relative */
578 1, /* bitpos */
579 complain_overflow_dont,/* complain_on_overflow */
580 score_elf_hi16_reloc, /* special_function */
581 "R_SCORE_HI16", /* name */
582 TRUE, /* partial_inplace */
583 0x37fff, /* src_mask */
584 0x37fff, /* dst_mask */
585 FALSE), /* pcrel_offset */
586
587 /* R_SCORE_LO16 */
588 HOWTO (R_SCORE_LO16, /* type */
589 0, /* rightshift */
590 2, /* size (0 = byte, 1 = short, 2 = long) */
591 16, /* bitsize */
592 FALSE, /* pc_relative */
593 1, /* bitpos */
594 complain_overflow_dont,/* complain_on_overflow */
595 score_elf_lo16_reloc, /* special_function */
596 "R_SCORE_LO16", /* name */
597 TRUE, /* partial_inplace */
598 0x37fff, /* src_mask */
599 0x37fff, /* dst_mask */
600 FALSE), /* pcrel_offset */
601
602 /* R_SCORE_DUMMY1 */
603 HOWTO (R_SCORE_DUMMY1, /* type */
604 0, /* rightshift */
605 2, /* size (0 = byte, 1 = short, 2 = long) */
606 16, /* bitsize */
607 FALSE, /* pc_relative */
608 1, /* bitpos */
609 complain_overflow_dont,/* complain_on_overflow */
610 bfd_elf_generic_reloc, /* special_function */
611 "R_SCORE_DUMMY1", /* name */
612 TRUE, /* partial_inplace */
613 0x0000ffff, /* src_mask */
614 0x0000ffff, /* dst_mask */
615 FALSE), /* pcrel_offset */
616
617 /*R_SCORE_24 */
618 HOWTO (R_SCORE_24, /* type */
619 1, /* rightshift */
620 2, /* size (0 = byte, 1 = short, 2 = long) */
621 24, /* bitsize */
622 FALSE, /* pc_relative */
623 1, /* bitpos */
624 complain_overflow_dont,/* complain_on_overflow */
625 bfd_elf_generic_reloc, /* special_function */
626 "R_SCORE_24", /* name */
627 FALSE, /* partial_inplace */
628 0x3ff7fff, /* src_mask */
629 0x3ff7fff, /* dst_mask */
630 FALSE), /* pcrel_offset */
631
632 /*R_SCORE_PC19 */
633 HOWTO (R_SCORE_PC19, /* type */
634 1, /* rightshift */
635 2, /* size (0 = byte, 1 = short, 2 = long) */
636 19, /* bitsize */
637 TRUE, /* pc_relative */
638 1, /* bitpos */
639 complain_overflow_dont,/* complain_on_overflow */
640 bfd_elf_generic_reloc, /* special_function */
641 "R_SCORE_PC19", /* name */
642 FALSE, /* partial_inplace */
643 0x3ff03fe, /* src_mask */
644 0x3ff03fe, /* dst_mask */
645 FALSE), /* pcrel_offset */
646
647 /*R_SCORE16_11 */
648 HOWTO (R_SCORE16_11, /* type */
649 1, /* rightshift */
650 1, /* size (0 = byte, 1 = short, 2 = long) */
651 11, /* bitsize */
652 FALSE, /* pc_relative */
653 1, /* bitpos */
654 complain_overflow_dont,/* complain_on_overflow */
655 bfd_elf_generic_reloc, /* special_function */
656 "R_SCORE16_11", /* name */
657 FALSE, /* partial_inplace */
658 0x000000ffe, /* src_mask */
659 0x000000ffe, /* dst_mask */
660 FALSE), /* pcrel_offset */
661
662 /* R_SCORE16_PC8 */
663 HOWTO (R_SCORE16_PC8, /* type */
664 1, /* rightshift */
665 1, /* size (0 = byte, 1 = short, 2 = long) */
666 8, /* bitsize */
667 TRUE, /* pc_relative */
668 0, /* bitpos */
669 complain_overflow_dont,/* complain_on_overflow */
670 bfd_elf_generic_reloc, /* special_function */
671 "R_SCORE16_PC8", /* name */
672 FALSE, /* partial_inplace */
673 0x000000ff, /* src_mask */
674 0x000000ff, /* dst_mask */
675 FALSE), /* pcrel_offset */
676
677 /* 32 bit absolute */
678 HOWTO (R_SCORE_ABS32, /* type 8 */
679 0, /* rightshift */
680 2, /* size (0 = byte, 1 = short, 2 = long) */
681 32, /* bitsize */
682 FALSE, /* pc_relative */
683 0, /* bitpos */
684 complain_overflow_bitfield, /* complain_on_overflow */
685 bfd_elf_generic_reloc, /* special_function */
686 "R_SCORE_ABS32", /* name */
687 FALSE, /* partial_inplace */
688 0xffffffff, /* src_mask */
689 0xffffffff, /* dst_mask */
690 FALSE), /* pcrel_offset */
691
692 /* 16 bit absolute */
693 HOWTO (R_SCORE_ABS16, /* type 11 */
694 0, /* rightshift */
695 1, /* size (0 = byte, 1 = short, 2 = long) */
696 16, /* bitsize */
697 FALSE, /* pc_relative */
698 0, /* bitpos */
699 complain_overflow_bitfield, /* complain_on_overflow */
700 bfd_elf_generic_reloc, /* special_function */
701 "R_SCORE_ABS16", /* name */
702 FALSE, /* partial_inplace */
703 0x0000ffff, /* src_mask */
704 0x0000ffff, /* dst_mask */
705 FALSE), /* pcrel_offset */
706
707 /* R_SCORE_DUMMY2 */
708 HOWTO (R_SCORE_DUMMY2, /* type */
709 0, /* rightshift */
710 2, /* size (0 = byte, 1 = short, 2 = long) */
711 16, /* bitsize */
712 FALSE, /* pc_relative */
713 0, /* bitpos */
714 complain_overflow_dont,/* complain_on_overflow */
715 bfd_elf_generic_reloc, /* special_function */
716 "R_SCORE_DUMMY2", /* name */
717 TRUE, /* partial_inplace */
718 0x00007fff, /* src_mask */
719 0x00007fff, /* dst_mask */
720 FALSE), /* pcrel_offset */
721
722 /* R_SCORE_GP15 */
723 HOWTO (R_SCORE_GP15, /* type */
724 0, /* rightshift */
725 2, /* size (0 = byte, 1 = short, 2 = long) */
726 16, /* bitsize */
727 FALSE, /* pc_relative */
728 0, /* bitpos */
729 complain_overflow_dont,/* complain_on_overflow */
730 score_elf_gprel15_reloc,/* special_function */
731 "R_SCORE_GP15", /* name */
732 TRUE, /* partial_inplace */
733 0x00007fff, /* src_mask */
734 0x00007fff, /* dst_mask */
735 FALSE), /* pcrel_offset */
736
737 /* GNU extension to record C++ vtable hierarchy. */
738 HOWTO (R_SCORE_GNU_VTINHERIT, /* type */
739 0, /* rightshift */
740 2, /* size (0 = byte, 1 = short, 2 = long) */
741 0, /* bitsize */
742 FALSE, /* pc_relative */
743 0, /* bitpos */
744 complain_overflow_dont,/* complain_on_overflow */
745 NULL, /* special_function */
746 "R_SCORE_GNU_VTINHERIT", /* name */
747 FALSE, /* partial_inplace */
748 0, /* src_mask */
749 0, /* dst_mask */
750 FALSE), /* pcrel_offset */
751
752 /* GNU extension to record C++ vtable member usage */
753 HOWTO (R_SCORE_GNU_VTENTRY, /* type */
754 0, /* rightshift */
755 2, /* size (0 = byte, 1 = short, 2 = long) */
756 0, /* bitsize */
757 FALSE, /* pc_relative */
758 0, /* bitpos */
759 complain_overflow_dont,/* complain_on_overflow */
760 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
761 "R_SCORE_GNU_VTENTRY", /* name */
762 FALSE, /* partial_inplace */
763 0, /* src_mask */
764 0, /* dst_mask */
765 FALSE), /* pcrel_offset */
766
767 /* Reference to global offset table. */
768 HOWTO (R_SCORE_GOT15, /* type */
769 0, /* rightshift */
770 2, /* size (0 = byte, 1 = short, 2 = long) */
771 16, /* bitsize */
772 FALSE, /* pc_relative */
773 0, /* bitpos */
774 complain_overflow_signed, /* complain_on_overflow */
775 score_elf_got15_reloc, /* special_function */
776 "R_SCORE_GOT15", /* name */
777 TRUE, /* partial_inplace */
778 0x00007fff, /* src_mask */
779 0x00007fff, /* dst_mask */
780 FALSE), /* pcrel_offset */
781
782 /* Low 16 bits of displacement in global offset table. */
783 HOWTO (R_SCORE_GOT_LO16, /* type */
784 0, /* rightshift */
785 2, /* size (0 = byte, 1 = short, 2 = long) */
786 16, /* bitsize */
787 FALSE, /* pc_relative */
788 1, /* bitpos */
789 complain_overflow_dont,/* complain_on_overflow */
790 score_elf_got_lo16_reloc, /* special_function */
791 "R_SCORE_GOT_LO16", /* name */
792 TRUE, /* partial_inplace */
793 0x37ffe, /* src_mask */
794 0x37ffe, /* dst_mask */
795 FALSE), /* pcrel_offset */
796
797 /* 15 bit call through global offset table. */
798 HOWTO (R_SCORE_CALL15, /* type */
799 0, /* rightshift */
800 2, /* size (0 = byte, 1 = short, 2 = long) */
801 16, /* bitsize */
802 FALSE, /* pc_relative */
803 0, /* bitpos */
804 complain_overflow_signed, /* complain_on_overflow */
805 bfd_elf_generic_reloc, /* special_function */
806 "R_SCORE_CALL15", /* name */
807 TRUE, /* partial_inplace */
808 0x0000ffff, /* src_mask */
809 0x0000ffff, /* dst_mask */
810 FALSE), /* pcrel_offset */
811
812 /* 32 bit GP relative reference. */
813 HOWTO (R_SCORE_GPREL32, /* type */
814 0, /* rightshift */
815 2, /* size (0 = byte, 1 = short, 2 = long) */
816 32, /* bitsize */
817 FALSE, /* pc_relative */
818 0, /* bitpos */
819 complain_overflow_dont,/* complain_on_overflow */
820 score_elf_gprel32_reloc, /* special_function */
821 "R_SCORE_GPREL32", /* name */
822 TRUE, /* partial_inplace */
823 0xffffffff, /* src_mask */
824 0xffffffff, /* dst_mask */
825 FALSE), /* pcrel_offset */
826
827 /* 32 bit symbol relative relocation. */
828 HOWTO (R_SCORE_REL32, /* type */
829 0, /* rightshift */
830 2, /* size (0 = byte, 1 = short, 2 = long) */
831 32, /* bitsize */
832 FALSE, /* pc_relative */
833 0, /* bitpos */
834 complain_overflow_dont,/* complain_on_overflow */
835 bfd_elf_generic_reloc, /* special_function */
836 "R_SCORE_REL32", /* name */
837 TRUE, /* partial_inplace */
838 0xffffffff, /* src_mask */
839 0xffffffff, /* dst_mask */
840 FALSE), /* pcrel_offset */
841
842 /* R_SCORE_DUMMY_HI16 */
843 HOWTO (R_SCORE_DUMMY_HI16, /* type */
844 0, /* rightshift */
845 2, /* size (0 = byte, 1 = short, 2 = long) */
846 16, /* bitsize */
847 FALSE, /* pc_relative */
848 1, /* bitpos */
849 complain_overflow_dont,/* complain_on_overflow */
850 score_elf_hi16_reloc, /* special_function */
851 "R_SCORE_DUMMY_HI16", /* name */
852 TRUE, /* partial_inplace */
853 0x37fff, /* src_mask */
854 0x37fff, /* dst_mask */
855 FALSE), /* pcrel_offset */
856};
857
858struct score_reloc_map
859{
860 bfd_reloc_code_real_type bfd_reloc_val;
861 unsigned char elf_reloc_val;
862};
863
864static const struct score_reloc_map elf32_score_reloc_map[] =
865{
866 {BFD_RELOC_NONE, R_SCORE_NONE},
867 {BFD_RELOC_HI16_S, R_SCORE_HI16},
868 {BFD_RELOC_LO16, R_SCORE_LO16},
869 {BFD_RELOC_SCORE_DUMMY1, R_SCORE_DUMMY1},
870 {BFD_RELOC_SCORE_JMP, R_SCORE_24},
871 {BFD_RELOC_SCORE_BRANCH, R_SCORE_PC19},
872 {BFD_RELOC_SCORE16_JMP, R_SCORE16_11},
873 {BFD_RELOC_SCORE16_BRANCH, R_SCORE16_PC8},
874 {BFD_RELOC_32, R_SCORE_ABS32},
875 {BFD_RELOC_16, R_SCORE_ABS16},
876 {BFD_RELOC_SCORE_DUMMY2, R_SCORE_DUMMY2},
877 {BFD_RELOC_SCORE_GPREL15, R_SCORE_GP15},
878 {BFD_RELOC_VTABLE_INHERIT, R_SCORE_GNU_VTINHERIT},
879 {BFD_RELOC_VTABLE_ENTRY, R_SCORE_GNU_VTENTRY},
880 {BFD_RELOC_SCORE_GOT15, R_SCORE_GOT15},
881 {BFD_RELOC_SCORE_GOT_LO16, R_SCORE_GOT_LO16},
882 {BFD_RELOC_SCORE_CALL15, R_SCORE_CALL15},
883 {BFD_RELOC_GPREL32, R_SCORE_GPREL32},
884 {BFD_RELOC_32_PCREL, R_SCORE_REL32},
885 {BFD_RELOC_SCORE_DUMMY_HI16, R_SCORE_DUMMY_HI16},
886};
887
888/* got_entries only match if they're identical, except for gotidx, so
889 use all fields to compute the hash, and compare the appropriate
890 union members. */
891
892static hashval_t
893score_elf_got_entry_hash (const void *entry_)
894{
895 const struct score_got_entry *entry = (struct score_got_entry *)entry_;
896
897 return entry->symndx
898 + (!entry->abfd ? entry->d.address : entry->abfd->id);
899}
900
901static int
902score_elf_got_entry_eq (const void *entry1, const void *entry2)
903{
904 const struct score_got_entry *e1 = (struct score_got_entry *)entry1;
905 const struct score_got_entry *e2 = (struct score_got_entry *)entry2;
906
907 return e1->abfd == e2->abfd && e1->symndx == e2->symndx
908 && (! e1->abfd ? e1->d.address == e2->d.address
909 : e1->symndx >= 0 ? e1->d.addend == e2->d.addend
910 : e1->d.h == e2->d.h);
911}
912
913/* If H needs a GOT entry, assign it the highest available dynamic
914 index. Otherwise, assign it the lowest available dynamic
915 index. */
916
917static bfd_boolean
918score_elf_sort_hash_table_f (struct score_elf_link_hash_entry *h, void *data)
919{
920 struct score_elf_hash_sort_data *hsd = data;
921
922 if (h->root.root.type == bfd_link_hash_warning)
923 h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
924
925 /* Symbols without dynamic symbol table entries aren't interesting at all. */
926 if (h->root.dynindx == -1)
927 return TRUE;
928
929 /* Global symbols that need GOT entries that are not explicitly
930 referenced are marked with got offset 2. Those that are
931 referenced get a 1, and those that don't need GOT entries get
932 -1. */
933 if (h->root.got.offset == 2)
934 {
935 if (hsd->max_unref_got_dynindx == hsd->min_got_dynindx)
936 hsd->low = (struct elf_link_hash_entry *) h;
937 h->root.dynindx = hsd->max_unref_got_dynindx++;
938 }
939 else if (h->root.got.offset != 1)
940 h->root.dynindx = hsd->max_non_got_dynindx++;
941 else
942 {
943 h->root.dynindx = --hsd->min_got_dynindx;
944 hsd->low = (struct elf_link_hash_entry *) h;
945 }
946
947 return TRUE;
948}
949
950static asection *
951score_elf_got_section (bfd *abfd, bfd_boolean maybe_excluded)
952{
953 asection *sgot = bfd_get_section_by_name (abfd, ".got");
954
955 if (sgot == NULL || (! maybe_excluded && (sgot->flags & SEC_EXCLUDE) != 0))
956 return NULL;
957 return sgot;
958}
959
960/* Returns the GOT information associated with the link indicated by
961 INFO. If SGOTP is non-NULL, it is filled in with the GOT section. */
962
963static struct score_got_info *
964score_elf_got_info (bfd *abfd, asection **sgotp)
965{
966 asection *sgot;
967 struct score_got_info *g;
968
969 sgot = score_elf_got_section (abfd, TRUE);
970 BFD_ASSERT (sgot != NULL);
971 BFD_ASSERT (elf_section_data (sgot) != NULL);
972 g = score_elf_section_data (sgot)->u.got_info;
973 BFD_ASSERT (g != NULL);
974
975 if (sgotp)
976 *sgotp = sgot;
977 return g;
978}
979
980/* Sort the dynamic symbol table so that symbols that need GOT entries
981 appear towards the end. This reduces the amount of GOT space
982 required. MAX_LOCAL is used to set the number of local symbols
983 known to be in the dynamic symbol table. During
984 _bfd_score_elf_size_dynamic_sections, this value is 1. Afterward, the
985 section symbols are added and the count is higher. */
986
987static bfd_boolean
988score_elf_sort_hash_table (struct bfd_link_info *info,
989 unsigned long max_local)
990{
991 struct score_elf_hash_sort_data hsd;
992 struct score_got_info *g;
993 bfd *dynobj;
994
995 dynobj = elf_hash_table (info)->dynobj;
996
997 g = score_elf_got_info (dynobj, NULL);
998
999 hsd.low = NULL;
1000 hsd.max_unref_got_dynindx =
1001 hsd.min_got_dynindx = elf_hash_table (info)->dynsymcount
1002 /* In the multi-got case, assigned_gotno of the master got_info
1003 indicate the number of entries that aren't referenced in the
1004 primary GOT, but that must have entries because there are
1005 dynamic relocations that reference it. Since they aren't
1006 referenced, we move them to the end of the GOT, so that they
1007 don't prevent other entries that are referenced from getting
1008 too large offsets. */
1009 - (g->next ? g->assigned_gotno : 0);
1010 hsd.max_non_got_dynindx = max_local;
1011 score_elf_link_hash_traverse (((struct score_elf_link_hash_table *)
1012 elf_hash_table (info)),
1013 score_elf_sort_hash_table_f,
1014 &hsd);
1015
1016 /* There should have been enough room in the symbol table to
1017 accommodate both the GOT and non-GOT symbols. */
1018 BFD_ASSERT (hsd.max_non_got_dynindx <= hsd.min_got_dynindx);
1019 BFD_ASSERT ((unsigned long)hsd.max_unref_got_dynindx
1020 <= elf_hash_table (info)->dynsymcount);
1021
1022 /* Now we know which dynamic symbol has the lowest dynamic symbol
1023 table index in the GOT. */
1024 g->global_gotsym = hsd.low;
1025
1026 return TRUE;
1027}
1028
1029/* Create an entry in an score ELF linker hash table. */
1030
1031static struct bfd_hash_entry *
1032score_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
1033 struct bfd_hash_table *table,
1034 const char *string)
1035{
1036 struct score_elf_link_hash_entry *ret = (struct score_elf_link_hash_entry *)entry;
1037
1038 /* Allocate the structure if it has not already been allocated by a subclass. */
1039 if (ret == NULL)
1040 ret = bfd_hash_allocate (table, sizeof (struct score_elf_link_hash_entry));
1041 if (ret == NULL)
1042 return (struct bfd_hash_entry *)ret;
1043
1044 /* Call the allocation method of the superclass. */
1045 ret = ((struct score_elf_link_hash_entry *)
1046 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *)ret, table, string));
1047
1048 if (ret != NULL)
1049 {
1050 ret->possibly_dynamic_relocs = 0;
1051 ret->readonly_reloc = FALSE;
1052 ret->no_fn_stub = FALSE;
1053 ret->forced_local = FALSE;
1054 }
1055
1056 return (struct bfd_hash_entry *)ret;
1057}
1058
1059/* Returns the first relocation of type r_type found, beginning with
1060 RELOCATION. RELEND is one-past-the-end of the relocation table. */
1061
1062static const Elf_Internal_Rela *
1063score_elf_next_relocation (bfd *abfd ATTRIBUTE_UNUSED, unsigned int r_type,
1064 const Elf_Internal_Rela *relocation,
1065 const Elf_Internal_Rela *relend)
1066{
1067 while (relocation < relend)
1068 {
1069 if (ELF32_R_TYPE (relocation->r_info) == r_type)
1070 return relocation;
1071
1072 ++relocation;
1073 }
1074
1075 /* We didn't find it. */
1076 bfd_set_error (bfd_error_bad_value);
1077 return NULL;
1078}
1079
1080/* This function is called via qsort() to sort the dynamic relocation
1081 entries by increasing r_symndx value. */
1082
1083static int
1084score_elf_sort_dynamic_relocs (const void *arg1, const void *arg2)
1085{
1086 Elf_Internal_Rela int_reloc1;
1087 Elf_Internal_Rela int_reloc2;
1088
1089 bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg1, &int_reloc1);
1090 bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg2, &int_reloc2);
1091
1092 return (ELF32_R_SYM (int_reloc1.r_info) - ELF32_R_SYM (int_reloc2.r_info));
1093}
1094
1095/* Return whether a relocation is against a local symbol. */
1096
1097static bfd_boolean
1098score_elf_local_relocation_p (bfd *input_bfd,
1099 const Elf_Internal_Rela *relocation,
1100 asection **local_sections,
1101 bfd_boolean check_forced)
1102{
1103 unsigned long r_symndx;
1104 Elf_Internal_Shdr *symtab_hdr;
1105 struct score_elf_link_hash_entry *h;
1106 size_t extsymoff;
1107
1108 r_symndx = ELF32_R_SYM (relocation->r_info);
1109 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1110 extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
1111
1112 if (r_symndx < extsymoff)
1113 return TRUE;
1114 if (elf_bad_symtab (input_bfd) && local_sections[r_symndx] != NULL)
1115 return TRUE;
1116
1117 if (check_forced)
1118 {
1119 /* Look up the hash table to check whether the symbol was forced local. */
1120 h = (struct score_elf_link_hash_entry *)
1121 elf_sym_hashes (input_bfd) [r_symndx - extsymoff];
1122 /* Find the real hash-table entry for this symbol. */
1123 while (h->root.root.type == bfd_link_hash_indirect
1124 || h->root.root.type == bfd_link_hash_warning)
1125 h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
1126 if (h->root.forced_local)
1127 return TRUE;
1128 }
1129
1130 return FALSE;
1131}
1132
1133/* Returns the dynamic relocation section for DYNOBJ. */
1134
1135static asection *
1136score_elf_rel_dyn_section (bfd *dynobj, bfd_boolean create_p)
1137{
1138 static const char dname[] = ".rel.dyn";
1139 asection *sreloc;
1140
1141 sreloc = bfd_get_section_by_name (dynobj, dname);
1142 if (sreloc == NULL && create_p)
1143 {
b3549761
NC
1144 sreloc = bfd_make_section_with_flags (dynobj, dname,
1145 (SEC_ALLOC
1146 | SEC_LOAD
1147 | SEC_HAS_CONTENTS
1148 | SEC_IN_MEMORY
1149 | SEC_LINKER_CREATED
1150 | SEC_READONLY));
1c0d3aa6 1151 if (sreloc == NULL
b3549761
NC
1152 || ! bfd_set_section_alignment (dynobj, sreloc,
1153 SCORE_ELF_LOG_FILE_ALIGN (dynobj)))
1c0d3aa6
NC
1154 return NULL;
1155 }
b3549761 1156 return sreloc;
1c0d3aa6
NC
1157}
1158
1159static void
1160score_elf_allocate_dynamic_relocations (bfd *abfd, unsigned int n)
1161{
1162 asection *s;
1163
1164 s = score_elf_rel_dyn_section (abfd, FALSE);
1165 BFD_ASSERT (s != NULL);
1166
1167 if (s->size == 0)
1168 {
1169 /* Make room for a null element. */
1170 s->size += SCORE_ELF_REL_SIZE (abfd);
1171 ++s->reloc_count;
1172 }
1173 s->size += n * SCORE_ELF_REL_SIZE (abfd);
1174}
1175
1176/* Create a rel.dyn relocation for the dynamic linker to resolve. REL
1177 is the original relocation, which is now being transformed into a
1178 dynamic relocation. The ADDENDP is adjusted if necessary; the
1179 caller should store the result in place of the original addend. */
1180
1181static bfd_boolean
1182score_elf_create_dynamic_relocation (bfd *output_bfd,
1183 struct bfd_link_info *info,
1184 const Elf_Internal_Rela *rel,
1185 struct score_elf_link_hash_entry *h,
1186 asection *sec, bfd_vma symbol,
1187 bfd_vma *addendp, asection *input_section)
1188{
1189 Elf_Internal_Rela outrel[3];
1190 asection *sreloc;
1191 bfd *dynobj;
1192 int r_type;
1193 long indx;
1194 bfd_boolean defined_p;
1195
1196 r_type = ELF32_R_TYPE (rel->r_info);
1197 dynobj = elf_hash_table (info)->dynobj;
1198 sreloc = score_elf_rel_dyn_section (dynobj, FALSE);
1199 BFD_ASSERT (sreloc != NULL);
1200 BFD_ASSERT (sreloc->contents != NULL);
1201 BFD_ASSERT (sreloc->reloc_count * SCORE_ELF_REL_SIZE (output_bfd) < sreloc->size);
1202
1203 outrel[0].r_offset =
1204 _bfd_elf_section_offset (output_bfd, info, input_section, rel[0].r_offset);
1205 outrel[1].r_offset =
1206 _bfd_elf_section_offset (output_bfd, info, input_section, rel[1].r_offset);
1207 outrel[2].r_offset =
1208 _bfd_elf_section_offset (output_bfd, info, input_section, rel[2].r_offset);
1209
1210 if (outrel[0].r_offset == MINUS_ONE)
1211 /* The relocation field has been deleted. */
1212 return TRUE;
1213
1214 if (outrel[0].r_offset == MINUS_TWO)
1215 {
1216 /* The relocation field has been converted into a relative value of
1217 some sort. Functions like _bfd_elf_write_section_eh_frame expect
1218 the field to be fully relocated, so add in the symbol's value. */
1219 *addendp += symbol;
1220 return TRUE;
1221 }
1222
1223 /* We must now calculate the dynamic symbol table index to use
1224 in the relocation. */
1225 if (h != NULL
1226 && (! info->symbolic || !h->root.def_regular)
1227 /* h->root.dynindx may be -1 if this symbol was marked to
1228 become local. */
1229 && h->root.dynindx != -1)
1230 {
1231 indx = h->root.dynindx;
1232 /* ??? glibc's ld.so just adds the final GOT entry to the
1233 relocation field. It therefore treats relocs against
1234 defined symbols in the same way as relocs against
1235 undefined symbols. */
1236 defined_p = FALSE;
1237 }
1238 else
1239 {
1240 if (sec != NULL && bfd_is_abs_section (sec))
1241 indx = 0;
1242 else if (sec == NULL || sec->owner == NULL)
1243 {
1244 bfd_set_error (bfd_error_bad_value);
1245 return FALSE;
1246 }
1247 else
1248 {
1249 indx = elf_section_data (sec->output_section)->dynindx;
1250 if (indx == 0)
1251 abort ();
1252 }
1253
1254 /* Instead of generating a relocation using the section
1255 symbol, we may as well make it a fully relative
1256 relocation. We want to avoid generating relocations to
1257 local symbols because we used to generate them
1258 incorrectly, without adding the original symbol value,
1259 which is mandated by the ABI for section symbols. In
1260 order to give dynamic loaders and applications time to
1261 phase out the incorrect use, we refrain from emitting
1262 section-relative relocations. It's not like they're
1263 useful, after all. This should be a bit more efficient
1264 as well. */
1265 /* ??? Although this behavior is compatible with glibc's ld.so,
1266 the ABI says that relocations against STN_UNDEF should have
1267 a symbol value of 0. Irix rld honors this, so relocations
1268 against STN_UNDEF have no effect. */
1269 defined_p = TRUE;
1270 }
1271
1272 /* If the relocation was previously an absolute relocation and
1273 this symbol will not be referred to by the relocation, we must
1274 adjust it by the value we give it in the dynamic symbol table.
1275 Otherwise leave the job up to the dynamic linker. */
1276 if (defined_p && r_type != R_SCORE_REL32)
1277 *addendp += symbol;
1278
1279 /* The relocation is always an REL32 relocation because we don't
1280 know where the shared library will wind up at load-time. */
1281 outrel[0].r_info = ELF32_R_INFO ((unsigned long) indx, R_SCORE_REL32);
1282
1283 /* For strict adherence to the ABI specification, we should
1284 generate a R_SCORE_64 relocation record by itself before the
1285 _REL32/_64 record as well, such that the addend is read in as
1286 a 64-bit value (REL32 is a 32-bit relocation, after all).
1287 However, since none of the existing ELF64 SCORE dynamic
1288 loaders seems to care, we don't waste space with these
1289 artificial relocations. If this turns out to not be true,
1290 score_elf_allocate_dynamic_relocations() should be tweaked so
1291 as to make room for a pair of dynamic relocations per
1292 invocation if ABI_64_P, and here we should generate an
1293 additional relocation record with R_SCORE_64 by itself for a
1294 NULL symbol before this relocation record. */
1295 outrel[1].r_info = ELF32_R_INFO (0, R_SCORE_NONE);
1296 outrel[2].r_info = ELF32_R_INFO (0, R_SCORE_NONE);
1297
1298 /* Adjust the output offset of the relocation to reference the
1299 correct location in the output file. */
1300 outrel[0].r_offset += (input_section->output_section->vma
1301 + input_section->output_offset);
1302 outrel[1].r_offset += (input_section->output_section->vma
1303 + input_section->output_offset);
1304 outrel[2].r_offset += (input_section->output_section->vma
1305 + input_section->output_offset);
1306
1307 /* Put the relocation back out. We have to use the special
1308 relocation outputter in the 64-bit case since the 64-bit
1309 relocation format is non-standard. */
1310 bfd_elf32_swap_reloc_out
1311 (output_bfd, &outrel[0],
1312 (sreloc->contents + sreloc->reloc_count * sizeof (Elf32_External_Rel)));
1313
1314 /* We've now added another relocation. */
1315 ++sreloc->reloc_count;
1316
1317 /* Make sure the output section is writable. The dynamic linker
1318 will be writing to it. */
1319 elf_section_data (input_section->output_section)->this_hdr.sh_flags |= SHF_WRITE;
1320
1321 return TRUE;
1322}
1323
1324static bfd_boolean
1325score_elf_create_got_section (bfd *abfd,
1326 struct bfd_link_info *info,
1327 bfd_boolean maybe_exclude)
1328{
1329 flagword flags;
1330 asection *s;
1331 struct elf_link_hash_entry *h;
1332 struct bfd_link_hash_entry *bh;
1333 struct score_got_info *g;
1334 bfd_size_type amt;
1335
1336 /* This function may be called more than once. */
1337 s = score_elf_got_section (abfd, TRUE);
1338 if (s)
1339 {
1340 if (! maybe_exclude)
1341 s->flags &= ~SEC_EXCLUDE;
1342 return TRUE;
1343 }
1344
1345 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
1346
1347 if (maybe_exclude)
1348 flags |= SEC_EXCLUDE;
1349
1350 /* We have to use an alignment of 2**4 here because this is hardcoded
1351 in the function stub generation and in the linker script. */
b3549761
NC
1352 s = bfd_make_section_with_flags (abfd, ".got", flags);
1353 if (s == NULL
1c0d3aa6
NC
1354 || ! bfd_set_section_alignment (abfd, s, 4))
1355 return FALSE;
1356
1357 /* Define the symbol _GLOBAL_OFFSET_TABLE_. We don't do this in the
1358 linker script because we don't want to define the symbol if we
1359 are not creating a global offset table. */
1360 bh = NULL;
1361 if (! (_bfd_generic_link_add_one_symbol
1362 (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s,
1363 0, NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
1364 return FALSE;
1365
1366 h = (struct elf_link_hash_entry *) bh;
1367 h->non_elf = 0;
1368 h->def_regular = 1;
1369 h->type = STT_OBJECT;
1370
1371 if (info->shared && ! bfd_elf_link_record_dynamic_symbol (info, h))
1372 return FALSE;
1373
1374 amt = sizeof (struct score_got_info);
1375 g = bfd_alloc (abfd, amt);
1376 if (g == NULL)
1377 return FALSE;
1378
1379 g->global_gotsym = NULL;
1380 g->global_gotno = 0;
1381
1382 g->local_gotno = SCORE_RESERVED_GOTNO;
1383 g->assigned_gotno = SCORE_RESERVED_GOTNO;
1384 g->next = NULL;
1385
1386 g->got_entries = htab_try_create (1, score_elf_got_entry_hash,
1387 score_elf_got_entry_eq, NULL);
1388 if (g->got_entries == NULL)
1389 return FALSE;
1390 score_elf_section_data (s)->u.got_info = g;
1391 score_elf_section_data (s)->elf.this_hdr.sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
1392
1393 return TRUE;
1394}
1395
1396/* Calculate the %high function. */
1397
1398static bfd_vma
1399score_elf_high (bfd_vma value)
1400{
1401 return ((value + (bfd_vma) 0x8000) >> 16) & 0xffff;
1402}
1403
1404/* Create a local GOT entry for VALUE. Return the index of the entry,
1405 or -1 if it could not be created. */
1406
1407static struct score_got_entry *
1408score_elf_create_local_got_entry (bfd *abfd,
1409 bfd *ibfd ATTRIBUTE_UNUSED,
1410 struct score_got_info *gg,
1411 asection *sgot, bfd_vma value,
1412 unsigned long r_symndx ATTRIBUTE_UNUSED,
1413 struct score_elf_link_hash_entry *h ATTRIBUTE_UNUSED,
1414 int r_type ATTRIBUTE_UNUSED)
1415{
1416 struct score_got_entry entry, **loc;
1417 struct score_got_info *g;
1418
1419 entry.abfd = NULL;
1420 entry.symndx = -1;
1421 entry.d.address = value;
1422
1423 g = gg;
1424 loc = (struct score_got_entry **) htab_find_slot (g->got_entries, &entry, INSERT);
1425 if (*loc)
1426 return *loc;
1427
1428 entry.gotidx = SCORE_ELF_GOT_SIZE (abfd) * g->assigned_gotno++;
1429
1430 *loc = bfd_alloc (abfd, sizeof entry);
1431
1432 if (! *loc)
1433 return NULL;
1434
1435 memcpy (*loc, &entry, sizeof entry);
1436
1437 if (g->assigned_gotno >= g->local_gotno)
1438 {
1439 (*loc)->gotidx = -1;
1440 /* We didn't allocate enough space in the GOT. */
1441 (*_bfd_error_handler)
1442 (_("not enough GOT space for local GOT entries"));
1443 bfd_set_error (bfd_error_bad_value);
1444 return NULL;
1445 }
1446
1447 bfd_put_32 (abfd, value, (sgot->contents + entry.gotidx));
1448
1449 return *loc;
1450}
1451
1452/* Find a GOT entry whose higher-order 16 bits are the same as those
1453 for value. Return the index into the GOT for this entry. */
1454
1455static bfd_vma
1456score_elf_got16_entry (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
1457 bfd_vma value, bfd_boolean external)
1458{
1459 asection *sgot;
1460 struct score_got_info *g;
1461 struct score_got_entry *entry;
1462
1463 if (!external)
1464 {
1465 /* Although the ABI says that it is "the high-order 16 bits" that we
1466 want, it is really the %high value. The complete value is
1467 calculated with a `addiu' of a LO16 relocation, just as with a
1468 HI16/LO16 pair. */
1469 value = score_elf_high (value) << 16;
1470 }
1471
1472 g = score_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
1473
1474 entry = score_elf_create_local_got_entry (abfd, ibfd, g, sgot, value, 0, NULL,
1475 R_SCORE_GOT15);
1476 if (entry)
1477 return entry->gotidx;
1478 else
1479 return MINUS_ONE;
1480}
1481
1482static void
1483_bfd_score_elf_hide_symbol (struct bfd_link_info *info,
1484 struct elf_link_hash_entry *entry,
1485 bfd_boolean force_local)
1486{
1487 bfd *dynobj;
1488 asection *got;
1489 struct score_got_info *g;
1490 struct score_elf_link_hash_entry *h;
1491
1492 h = (struct score_elf_link_hash_entry *) entry;
1493 if (h->forced_local)
1494 return;
1495 h->forced_local = TRUE;
1496
1497 dynobj = elf_hash_table (info)->dynobj;
1498 if (dynobj != NULL && force_local)
1499 {
1500 got = score_elf_got_section (dynobj, FALSE);
1501 if (got == NULL)
1502 return;
1503 g = score_elf_section_data (got)->u.got_info;
1504
1505 if (g->next)
1506 {
1507 struct score_got_entry e;
1508 struct score_got_info *gg = g;
1509
1510 /* Since we're turning what used to be a global symbol into a
1511 local one, bump up the number of local entries of each GOT
1512 that had an entry for it. This will automatically decrease
1513 the number of global entries, since global_gotno is actually
1514 the upper limit of global entries. */
1515 e.abfd = dynobj;
1516 e.symndx = -1;
1517 e.d.h = h;
1518
1519 for (g = g->next; g != gg; g = g->next)
1520 if (htab_find (g->got_entries, &e))
1521 {
1522 BFD_ASSERT (g->global_gotno > 0);
1523 g->local_gotno++;
1524 g->global_gotno--;
1525 }
1526
1527 /* If this was a global symbol forced into the primary GOT, we
1528 no longer need an entry for it. We can't release the entry
1529 at this point, but we must at least stop counting it as one
1530 of the symbols that required a forced got entry. */
1531 if (h->root.got.offset == 2)
1532 {
1533 BFD_ASSERT (gg->assigned_gotno > 0);
1534 gg->assigned_gotno--;
1535 }
1536 }
1537 else if (g->global_gotno == 0 && g->global_gotsym == NULL)
1538 /* If we haven't got through GOT allocation yet, just bump up the
1539 number of local entries, as this symbol won't be counted as
1540 global. */
1541 g->local_gotno++;
1542 else if (h->root.got.offset == 1)
1543 {
1544 /* If we're past non-multi-GOT allocation and this symbol had
1545 been marked for a global got entry, give it a local entry
1546 instead. */
1547 BFD_ASSERT (g->global_gotno > 0);
1548 g->local_gotno++;
1549 g->global_gotno--;
1550 }
1551 }
1552
1553 _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
1554}
1555
1556/* If H is a symbol that needs a global GOT entry, but has a dynamic
1557 symbol table index lower than any we've seen to date, record it for
1558 posterity. */
1559
1560static bfd_boolean
1561score_elf_record_global_got_symbol (struct elf_link_hash_entry *h,
1562 bfd *abfd,
1563 struct bfd_link_info *info,
1564 struct score_got_info *g)
1565{
1566 struct score_got_entry entry, **loc;
1567
1568 /* A global symbol in the GOT must also be in the dynamic symbol table. */
1569 if (h->dynindx == -1)
1570 {
1571 switch (ELF_ST_VISIBILITY (h->other))
1572 {
1573 case STV_INTERNAL:
1574 case STV_HIDDEN:
1575 _bfd_score_elf_hide_symbol (info, h, TRUE);
1576 break;
1577 }
1578 if (!bfd_elf_link_record_dynamic_symbol (info, h))
1579 return FALSE;
1580 }
1581
1582 entry.abfd = abfd;
1583 entry.symndx = -1;
1584 entry.d.h = (struct score_elf_link_hash_entry *)h;
1585
1586 loc = (struct score_got_entry **)htab_find_slot (g->got_entries, &entry, INSERT);
1587
1588 /* If we've already marked this entry as needing GOT space, we don't
1589 need to do it again. */
1590 if (*loc)
1591 return TRUE;
1592
1593 *loc = bfd_alloc (abfd, sizeof entry);
1594 if (! *loc)
1595 return FALSE;
1596
1597 entry.gotidx = -1;
1598
1599 memcpy (*loc, &entry, sizeof (entry));
1600
1601 if (h->got.offset != MINUS_ONE)
1602 return TRUE;
1603
1604 /* By setting this to a value other than -1, we are indicating that
1605 there needs to be a GOT entry for H. Avoid using zero, as the
1606 generic ELF copy_indirect_symbol tests for <= 0. */
1607 h->got.offset = 1;
1608
1609 return TRUE;
1610}
1611
1612/* Reserve space in G for a GOT entry containing the value of symbol
1613 SYMNDX in input bfd ABDF, plus ADDEND. */
1614
1615static bfd_boolean
1616score_elf_record_local_got_symbol (bfd *abfd,
1617 long symndx,
1618 bfd_vma addend,
1619 struct score_got_info *g)
1620{
1621 struct score_got_entry entry, **loc;
1622
1623 entry.abfd = abfd;
1624 entry.symndx = symndx;
1625 entry.d.addend = addend;
1626 loc = (struct score_got_entry **)htab_find_slot (g->got_entries, &entry, INSERT);
1627
1628 if (*loc)
1629 return TRUE;
1630
1631 entry.gotidx = g->local_gotno++;
1632
1633 *loc = bfd_alloc (abfd, sizeof(entry));
1634 if (! *loc)
1635 return FALSE;
1636
1637 memcpy (*loc, &entry, sizeof (entry));
1638
1639 return TRUE;
1640}
1641
1642/* Returns the GOT offset at which the indicated address can be found.
1643 If there is not yet a GOT entry for this value, create one.
1644 Returns -1 if no satisfactory GOT offset can be found. */
1645
1646static bfd_vma
1647score_elf_local_got_index (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
1648 bfd_vma value, unsigned long r_symndx,
1649 struct score_elf_link_hash_entry *h, int r_type)
1650{
1651 asection *sgot;
1652 struct score_got_info *g;
1653 struct score_got_entry *entry;
1654
1655 g = score_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
1656
1657 entry = score_elf_create_local_got_entry (abfd, ibfd, g, sgot, value,
1658 r_symndx, h, r_type);
1659 if (!entry)
1660 return MINUS_ONE;
1661
1662 else
1663 return entry->gotidx;
1664}
1665
1666/* Returns the GOT index for the global symbol indicated by H. */
1667
1668static bfd_vma
1669score_elf_global_got_index (bfd *abfd, struct elf_link_hash_entry *h)
1670{
1671 bfd_vma index;
1672 asection *sgot;
1673 struct score_got_info *g;
1674 long global_got_dynindx = 0;
1675
1676 g = score_elf_got_info (abfd, &sgot);
1677 if (g->global_gotsym != NULL)
1678 global_got_dynindx = g->global_gotsym->dynindx;
1679
1680 /* Once we determine the global GOT entry with the lowest dynamic
1681 symbol table index, we must put all dynamic symbols with greater
1682 indices into the GOT. That makes it easy to calculate the GOT
1683 offset. */
1684 BFD_ASSERT (h->dynindx >= global_got_dynindx);
1685 index = ((h->dynindx - global_got_dynindx + g->local_gotno) * SCORE_ELF_GOT_SIZE (abfd));
1686 BFD_ASSERT (index < sgot->size);
1687
1688 return index;
1689}
1690
1691/* Returns the offset for the entry at the INDEXth position in the GOT. */
1692
1693static bfd_vma
1694score_elf_got_offset_from_index (bfd *dynobj, bfd *output_bfd,
1695 bfd *input_bfd ATTRIBUTE_UNUSED, bfd_vma index)
1696{
1697 asection *sgot;
1698 bfd_vma gp;
1699 struct score_got_info *g;
1700
1701 g = score_elf_got_info (dynobj, &sgot);
1702 gp = _bfd_get_gp_value (output_bfd);
1703
1704 return sgot->output_section->vma + sgot->output_offset + index - gp;
1705}
1706
1707/* Follow indirect and warning hash entries so that each got entry
1708 points to the final symbol definition. P must point to a pointer
1709 to the hash table we're traversing. Since this traversal may
1710 modify the hash table, we set this pointer to NULL to indicate
1711 we've made a potentially-destructive change to the hash table, so
1712 the traversal must be restarted. */
1713static int
1714score_elf_resolve_final_got_entry (void **entryp, void *p)
1715{
1716 struct score_got_entry *entry = (struct score_got_entry *)*entryp;
1717 htab_t got_entries = *(htab_t *)p;
1718
1719 if (entry->abfd != NULL && entry->symndx == -1)
1720 {
1721 struct score_elf_link_hash_entry *h = entry->d.h;
1722
1723 while (h->root.root.type == bfd_link_hash_indirect
1724 || h->root.root.type == bfd_link_hash_warning)
1725 h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
1726
1727 if (entry->d.h == h)
1728 return 1;
1729
1730 entry->d.h = h;
1731
1732 /* If we can't find this entry with the new bfd hash, re-insert
1733 it, and get the traversal restarted. */
1734 if (! htab_find (got_entries, entry))
1735 {
1736 htab_clear_slot (got_entries, entryp);
1737 entryp = htab_find_slot (got_entries, entry, INSERT);
1738 if (! *entryp)
1739 *entryp = entry;
1740 /* Abort the traversal, since the whole table may have
1741 moved, and leave it up to the parent to restart the
1742 process. */
1743 *(htab_t *)p = NULL;
1744 return 0;
1745 }
1746 /* We might want to decrement the global_gotno count, but it's
1747 either too early or too late for that at this point. */
1748 }
1749
1750 return 1;
1751}
1752
1753/* Turn indirect got entries in a got_entries table into their final locations. */
1754static void
1755score_elf_resolve_final_got_entries (struct score_got_info *g)
1756{
1757 htab_t got_entries;
1758
1759 do
1760 {
1761 got_entries = g->got_entries;
1762
1763 htab_traverse (got_entries,
1764 score_elf_resolve_final_got_entry,
1765 &got_entries);
1766 }
1767 while (got_entries == NULL);
1768}
1769
1770/* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS. for -r */
1771
1772static void
1773score_elf_add_to_rel (bfd *abfd,
1774 bfd_byte *address,
1775 reloc_howto_type *howto,
1776 bfd_signed_vma increment)
1777{
1778 bfd_signed_vma addend;
1779 bfd_vma contents;
1780 unsigned long offset;
1781 unsigned long r_type = howto->type;
1782 unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
1783
1784 contents = bfd_get_32 (abfd, address);
1785 /* Get the (signed) value from the instruction. */
1786 addend = contents & howto->src_mask;
1787 if (addend & ((howto->src_mask + 1) >> 1))
1788 {
1789 bfd_signed_vma mask;
1790
1791 mask = -1;
1792 mask &= ~howto->src_mask;
1793 addend |= mask;
1794 }
1795 /* Add in the increment, (which is a byte value). */
1796 switch (r_type)
1797 {
1798 case R_SCORE_PC19:
1799 offset =
1800 (((contents & howto->src_mask) & 0x3ff0000) >> 6) | ((contents & howto->src_mask) & 0x3ff);
1801 offset += increment;
1802 contents =
1803 (contents & ~howto->
1804 src_mask) | (((offset << 6) & howto->src_mask) & 0x3ff0000) | (offset & 0x3ff);
1805 bfd_put_32 (abfd, contents, address);
1806 break;
1807 case R_SCORE_HI16:
1808 break;
1809 case R_SCORE_LO16:
1810 hi16_addend = bfd_get_32 (abfd, address - 4);
1811 hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
1812 offset = ((((contents >> 16) & 0x3) << 15) | (contents & 0x7fff)) >> 1;
1813 offset = (hi16_offset << 16) | (offset & 0xffff);
1814 uvalue = increment + offset;
1815 hi16_offset = (uvalue >> 16) << 1;
1816 hi16_value = (hi16_addend & (~(howto->dst_mask)))
1817 | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
1818 bfd_put_32 (abfd, hi16_value, address - 4);
1819 offset = (uvalue & 0xffff) << 1;
1820 contents = (contents & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
1821 bfd_put_32 (abfd, contents, address);
1822 break;
1823 case R_SCORE_24:
1824 offset =
1825 (((contents & howto->src_mask) >> 1) & 0x1ff8000) | ((contents & howto->src_mask) & 0x7fff);
1826 offset += increment;
1827 contents =
1828 (contents & ~howto->
1829 src_mask) | (((offset << 1) & howto->src_mask) & 0x3ff0000) | (offset & 0x7fff);
1830 bfd_put_32 (abfd, contents, address);
1831 break;
1832 case R_SCORE16_11:
1833
1834 contents = bfd_get_16 (abfd, address);
1835 offset = contents & howto->src_mask;
1836 offset += increment;
1837 contents = (contents & ~howto->src_mask) | (offset & howto->src_mask);
1838 bfd_put_16 (abfd, contents, address);
1839
1840 break;
1841 case R_SCORE16_PC8:
1842
1843 contents = bfd_get_16 (abfd, address);
1844 offset = (contents & howto->src_mask) + ((increment >> 1) & 0xff);
1845 contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask);
1846 bfd_put_16 (abfd, contents, address);
1847
1848 break;
1849 default:
1850 addend += increment;
1851 contents = (contents & ~howto->dst_mask) | (addend & howto->dst_mask);
1852 bfd_put_32 (abfd, contents, address);
1853 break;
1854 }
1855}
1856
1857/* Perform a relocation as part of a final link. */
1858
1859static bfd_reloc_status_type
1860score_elf_final_link_relocate (reloc_howto_type *howto,
1861 bfd *input_bfd,
1862 bfd *output_bfd,
1863 asection *input_section,
1864 bfd_byte *contents,
1865 Elf_Internal_Rela *rel,
1866 Elf_Internal_Rela *relocs,
1867 bfd_vma symbol,
1868 struct bfd_link_info *info,
1869 asection *sym_sec,
1870 const char *sym_name ATTRIBUTE_UNUSED,
1871 int sym_flags ATTRIBUTE_UNUSED,
1872 struct score_elf_link_hash_entry *h,
1873 asection **local_sections,
1874 bfd_boolean gp_disp_p)
1875{
1876 unsigned long r_type;
1877 unsigned long r_symndx;
1878 bfd_byte *hit_data = contents + rel->r_offset;
1879 bfd_vma addend;
1880 /* The final GP value to be used for the relocatable, executable, or
1881 shared object file being produced. */
1882 bfd_vma gp = MINUS_ONE;
1883 /* The place (section offset or address) of the storage unit being relocated. */
1884 bfd_vma rel_addr;
1885 /* The value of GP used to create the relocatable object. */
1886 bfd_vma gp0 = MINUS_ONE;
1887 /* The offset into the global offset table at which the address of the relocation entry
1888 symbol, adjusted by the addend, resides during execution. */
1889 bfd_vma g = MINUS_ONE;
1890 /* TRUE if the symbol referred to by this relocation is a local symbol. */
1891 bfd_boolean local_p;
1892 /* The eventual value we will relocate. */
1893 bfd_vma value = symbol;
1894 unsigned long hi16_addend, hi16_offset, hi16_value, uvalue, offset, abs_value = 0;
1895
1896 if (elf_gp (output_bfd) == 0)
1897 {
1898 struct bfd_link_hash_entry *bh;
1899 asection *o;
1900
1901 bh = bfd_link_hash_lookup (info->hash, "_gp", 0, 0, 1);
1902 if (bh != (struct bfd_link_hash_entry *)NULL && bh->type == bfd_link_hash_defined)
1903 elf_gp (output_bfd) = (bh->u.def.value
1904 + bh->u.def.section->output_section->vma
1905 + bh->u.def.section->output_offset);
1906 else if (info->relocatable)
1907 {
1908 bfd_vma lo = -1;
1909
1910 /* Find the GP-relative section with the lowest offset. */
1911 for (o = output_bfd->sections; o != (asection *) NULL; o = o->next)
1912 if (o->vma < lo)
1913 lo = o->vma;
1914 /* And calculate GP relative to that. */
1915 elf_gp (output_bfd) = lo + ELF_SCORE_GP_OFFSET (input_bfd);
1916 }
1917 else
1918 {
1919 /* If the relocate_section function needs to do a reloc
1920 involving the GP value, it should make a reloc_dangerous
1921 callback to warn that GP is not defined. */
1922 }
1923 }
1924
1925 /* Parse the relocation. */
1926 r_symndx = ELF32_R_SYM (rel->r_info);
1927 r_type = ELF32_R_TYPE (rel->r_info);
1928 rel_addr = (input_section->output_section->vma + input_section->output_offset + rel->r_offset);
1929
1c0d3aa6
NC
1930 if (r_type == R_SCORE_GOT15)
1931 {
1932 const Elf_Internal_Rela *relend;
1933 const Elf_Internal_Rela *lo16_rel;
1934 const struct elf_backend_data *bed;
1935 bfd_vma lo_value = 0;
1936
1937 addend = (bfd_get_32 (input_bfd, hit_data) >> howto->bitpos) & howto->src_mask;
1938
1939 bed = get_elf_backend_data (output_bfd);
1940 relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
1941 lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
1942 if (lo16_rel != NULL)
1943 {
1944 lo_value = (bfd_get_32 (input_bfd, contents + lo16_rel->r_offset) >> howto->bitpos)
1945 & howto->src_mask;
1946 }
1947 addend = (addend << 16) + lo_value;
1948 }
1949 else
1950 {
1951 addend = (bfd_get_32 (input_bfd, hit_data) >> howto->bitpos) & howto->src_mask;
1952 }
1953
1954 local_p = score_elf_local_relocation_p (input_bfd, rel, local_sections, TRUE);
1955
1956 /* If we haven't already determined the GOT offset, or the GP value,
1957 and we're going to need it, get it now. */
1958 switch (r_type)
1959 {
1960 case R_SCORE_CALL15:
1961 case R_SCORE_GOT15:
1962 if (!local_p)
1963 {
1964 g = score_elf_global_got_index (elf_hash_table (info)->dynobj,
1965 (struct elf_link_hash_entry *) h);
1966 }
1967 else if (r_type == R_SCORE_GOT15 || r_type == R_SCORE_CALL15)
1968 {
1969 /* There's no need to create a local GOT entry here; the
1970 calculation for a local GOT15 entry does not involve G. */
1971 ;
1972 }
1973 else
1974 {
1975 g = score_elf_local_got_index (output_bfd, input_bfd, info,
1976 symbol + addend, r_symndx, h, r_type);
1977 if (g == MINUS_ONE)
1978 return bfd_reloc_outofrange;
1979 }
1980
1981 /* Convert GOT indices to actual offsets. */
1982 g = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
1983 output_bfd, input_bfd, g);
1984 break;
1985
1986 case R_SCORE_HI16:
1987 case R_SCORE_LO16:
1988 case R_SCORE_GPREL32:
1989 gp0 = _bfd_get_gp_value (input_bfd);
1990 gp = _bfd_get_gp_value (output_bfd);
1991 break;
1992
1993 case R_SCORE_GP15:
1994 gp = _bfd_get_gp_value (output_bfd);
1995
1996 default:
1997 break;
1998 }
1999
2000 switch (r_type)
2001 {
2002 case R_SCORE_NONE:
2003 return bfd_reloc_ok;
2004
2005 case R_SCORE_ABS32:
2006 case R_SCORE_REL32:
2007 if ((info->shared
2008 || (elf_hash_table (info)->dynamic_sections_created
2009 && h != NULL
2010 && h->root.def_dynamic
2011 && !h->root.def_regular))
2012 && r_symndx != 0
2013 && (input_section->flags & SEC_ALLOC) != 0)
2014 {
2015 /* If we're creating a shared library, or this relocation is against a symbol
2016 in a shared library, then we can't know where the symbol will end up.
2017 So, we create a relocation record in the output, and leave the job up
2018 to the dynamic linker. */
2019 value = addend;
2020 if (!score_elf_create_dynamic_relocation (output_bfd, info, rel, h,
2021 sym_sec, symbol, &value,
2022 input_section))
2023 return bfd_reloc_undefined;
2024 }
2025 else
2026 {
2027 if (r_type != R_SCORE_REL32)
2028 value = symbol + addend;
2029 else
2030 value = addend;
2031 }
2032 value &= howto->dst_mask;
2033 bfd_put_32 (input_bfd, value, hit_data);
2034 return bfd_reloc_ok;
2035
2036 case R_SCORE_ABS16:
2037 value += addend;
2038 if ((long)value > 0x7fff || (long)value < -0x8000)
2039 return bfd_reloc_overflow;
2040 bfd_put_16 (input_bfd, value, hit_data);
2041 return bfd_reloc_ok;
2042
2043 case R_SCORE_24:
2044 addend = bfd_get_32 (input_bfd, hit_data);
2045 offset = (((addend & howto->src_mask) >> 1) & 0x1ff8000) | ((addend & howto->src_mask) & 0x7fff);
2046 if ((offset & 0x1000000) != 0)
2047 offset |= 0xfe000000;
2048 value += offset;
2049 addend = (addend & ~howto->src_mask)
2050 | (((value << 1) & howto->src_mask) & 0x3ff0000) | (value & 0x7fff);
2051 bfd_put_32 (input_bfd, addend, hit_data);
2052 return bfd_reloc_ok;
2053
2054 case R_SCORE_PC19:
2055 addend = bfd_get_32 (input_bfd, hit_data);
2056 offset = (((addend & howto->src_mask) & 0x3ff0000) >> 6) | ((addend & howto->src_mask) & 0x3ff);
2057 if ((offset & 0x80000) != 0)
2058 offset |= 0xfff00000;
2059 abs_value = value = value - rel_addr + offset;
2060 /* exceed 20 bit : overflow. */
2061 if ((abs_value & 0x80000000) == 0x80000000)
2062 abs_value = 0xffffffff - value + 1;
2063 if ((abs_value & 0xfff80000) != 0)
2064 return bfd_reloc_overflow;
2065 addend = (addend & ~howto->src_mask)
2066 | (((value << 6) & howto->src_mask) & 0x3ff0000) | (value & 0x3ff);
2067 bfd_put_32 (input_bfd, addend, hit_data);
2068 return bfd_reloc_ok;
2069
2070 case R_SCORE16_11:
2071 addend = bfd_get_16 (input_bfd, hit_data);
2072 offset = addend & howto->src_mask;
2073 if ((offset & 0x800) != 0) /* Offset is negative. */
2074 offset |= 0xfffff000;
2075 value += offset;
2076 addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
2077 bfd_put_16 (input_bfd, addend, hit_data);
2078 return bfd_reloc_ok;
2079
2080 case R_SCORE16_PC8:
2081 addend = bfd_get_16 (input_bfd, hit_data);
2082 offset = (addend & howto->src_mask) << 1;
2083 if ((offset & 0x100) != 0) /* Offset is negative. */
2084 offset |= 0xfffffe00;
2085 abs_value = value = value - rel_addr + offset;
2086 /* Sign bit + exceed 9 bit. */
2087 if (((value & 0xffffff00) != 0) && ((value & 0xffffff00) != 0xffffff00))
2088 return bfd_reloc_overflow;
2089 value >>= 1;
2090 addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
2091 bfd_put_16 (input_bfd, addend, hit_data);
2092 return bfd_reloc_ok;
2093
2094 case R_SCORE_HI16:
2095 return bfd_reloc_ok;
2096
2097 case R_SCORE_LO16:
2098 hi16_addend = bfd_get_32 (input_bfd, hit_data - 4);
2099 hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
2100 addend = bfd_get_32 (input_bfd, hit_data);
2101 offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
2102 offset = (hi16_offset << 16) | (offset & 0xffff);
2103
2104 if (!gp_disp_p)
2105 uvalue = value + offset;
2106 else
2107 uvalue = offset + gp - rel_addr + 4;
2108
2109 hi16_offset = (uvalue >> 16) << 1;
2110 hi16_value = (hi16_addend & (~(howto->dst_mask)))
2111 | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
2112 bfd_put_32 (input_bfd, hi16_value, hit_data - 4);
2113 offset = (uvalue & 0xffff) << 1;
2114 value = (addend & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
2115 bfd_put_32 (input_bfd, value, hit_data);
2116 return bfd_reloc_ok;
2117
2118 case R_SCORE_GP15:
2119 addend = bfd_get_32 (input_bfd, hit_data);
2120 offset = addend & 0x7fff;
2121 if ((offset & 0x4000) == 0x4000)
2122 offset |= 0xffffc000;
2123 value = value + offset - gp;
2124 if (((value & 0xffffc000) != 0) && ((value & 0xffffc000) != 0xffffc000))
2125 return bfd_reloc_overflow;
2126 value = (addend & ~howto->src_mask) | (value & howto->src_mask);
2127 bfd_put_32 (input_bfd, value, hit_data);
2128 return bfd_reloc_ok;
2129
2130 case R_SCORE_GOT15:
2131 case R_SCORE_CALL15:
2132 if (local_p)
2133 {
2134 bfd_boolean forced;
2135
2136 /* The special case is when the symbol is forced to be local. We need the
2137 full address in the GOT since no R_SCORE_GOT_LO16 relocation follows. */
2138 forced = ! score_elf_local_relocation_p (input_bfd, rel,
2139 local_sections, FALSE);
2140 value = score_elf_got16_entry (output_bfd, input_bfd, info,
2141 symbol + addend, forced);
2142 if (value == MINUS_ONE)
2143 return bfd_reloc_outofrange;
2144 value = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
2145 output_bfd, input_bfd, value);
2146 }
2147 else
2148 {
2149 value = g;
2150 }
2151
2152 if ((long) value > 0x3fff || (long) value < -0x4000)
2153 return bfd_reloc_overflow;
2154 bfd_put_16 (input_bfd, value, hit_data + 2);
2155 return bfd_reloc_ok;
2156
2157 case R_SCORE_GPREL32:
2158 value = (addend + symbol - gp);
2159 value &= howto->dst_mask;
2160 bfd_put_32 (input_bfd, value, hit_data);
2161 return bfd_reloc_ok;
2162
2163 case R_SCORE_GOT_LO16:
2164 addend = bfd_get_32 (input_bfd, hit_data);
2165 value = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
2166 value += symbol;
2167 offset = (value & 0xffff) << 1;
2168 value = (addend & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
2169
2170 bfd_put_32 (input_bfd, value, hit_data);
2171 return bfd_reloc_ok;
2172
2173 case R_SCORE_DUMMY_HI16:
2174 return bfd_reloc_ok;
2175
2176 case R_SCORE_GNU_VTINHERIT:
2177 case R_SCORE_GNU_VTENTRY:
2178 /* We don't do anything with these at present. */
2179 return bfd_reloc_continue;
2180
2181 default:
2182 return bfd_reloc_notsupported;
2183 }
2184}
2185
2186/* Score backend functions. */
2187
2188static void
2189_bfd_score_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
2190 arelent *bfd_reloc,
2191 Elf_Internal_Rela *elf_reloc)
2192{
2193 unsigned int r_type;
2194
2195 r_type = ELF32_R_TYPE (elf_reloc->r_info);
2196 if (r_type >= NUM_ELEM (elf32_score_howto_table))
2197 bfd_reloc->howto = NULL;
2198 else
2199 bfd_reloc->howto = &elf32_score_howto_table[r_type];
2200}
2201
2202/* Relocate an score ELF section. */
2203
2204static bfd_boolean
2205_bfd_score_elf_relocate_section (bfd *output_bfd,
2206 struct bfd_link_info *info,
2207 bfd *input_bfd,
2208 asection *input_section,
2209 bfd_byte *contents,
2210 Elf_Internal_Rela *relocs,
2211 Elf_Internal_Sym *local_syms,
2212 asection **local_sections)
2213{
2214 Elf_Internal_Shdr *symtab_hdr;
2215 struct elf_link_hash_entry **sym_hashes;
2216 Elf_Internal_Rela *rel;
2217 Elf_Internal_Rela *relend;
2218 const char *name;
2219 unsigned long offset;
2220 unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
2221 size_t extsymoff;
2222 bfd_boolean gp_disp_p = FALSE;
2223
2224#ifndef USE_REL
2225 if (info->relocatable)
2226 return TRUE;
2227#endif
2228
2229 /* Sort dynsym. */
2230 if (elf_hash_table (info)->dynamic_sections_created)
2231 {
2232 bfd_size_type dynsecsymcount = 0;
2233 if (info->shared)
2234 {
2235 asection * p;
2236 const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
2237
2238 for (p = output_bfd->sections; p ; p = p->next)
2239 if ((p->flags & SEC_EXCLUDE) == 0
2240 && (p->flags & SEC_ALLOC) != 0
2241 && !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p))
2242 ++ dynsecsymcount;
2243 }
2244
2245 if (!score_elf_sort_hash_table (info, dynsecsymcount + 1))
2246 return FALSE;
2247 }
2248
2249 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
2250 extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
2251 sym_hashes = elf_sym_hashes (input_bfd);
2252 rel = relocs;
2253 relend = relocs + input_section->reloc_count;
2254 for (; rel < relend; rel++)
2255 {
2256 int r_type;
2257 reloc_howto_type *howto;
2258 unsigned long r_symndx;
2259 Elf_Internal_Sym *sym;
2260 asection *sec;
2261 struct score_elf_link_hash_entry *h;
2262 bfd_vma relocation = 0;
2263 bfd_reloc_status_type r;
2264 arelent bfd_reloc;
2265
2266 r_symndx = ELF32_R_SYM (rel->r_info);
2267 r_type = ELF32_R_TYPE (rel->r_info);
2268
2269 _bfd_score_info_to_howto (input_bfd, &bfd_reloc, (Elf_Internal_Rela *) rel);
2270 howto = bfd_reloc.howto;
2271
2272 if (info->relocatable)
2273 {
2274 /* This is a relocatable link. We don't have to change
2275 anything, unless the reloc is against a section symbol,
2276 in which case we have to adjust according to where the
2277 section symbol winds up in the output section. */
2278 if (r_symndx < symtab_hdr->sh_info)
2279 {
2280 sym = local_syms + r_symndx;
2281 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2282 {
2283 sec = local_sections[r_symndx];
2284 score_elf_add_to_rel (input_bfd, contents + rel->r_offset,
2285 howto, (bfd_signed_vma) (sec->output_offset + sym->st_value));
2286 }
2287 }
2288 continue;
2289 }
2290
2291 /* This is a final link. */
2292 h = NULL;
2293 sym = NULL;
2294 sec = NULL;
2295
2296 if (r_symndx < extsymoff)
2297 {
2298 sym = local_syms + r_symndx;
2299 sec = local_sections[r_symndx];
f36b9bcd
AM
2300 relocation = (sec->output_section->vma
2301 + sec->output_offset
2302 + sym->st_value);
2303 name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, sec);
1c0d3aa6 2304
f36b9bcd
AM
2305 if ((sec->flags & SEC_MERGE)
2306 && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1c0d3aa6
NC
2307 {
2308 asection *msec;
2309 bfd_vma addend, value;
2310
2311 switch (r_type)
2312 {
2313 case R_SCORE_HI16:
2314 break;
2315 case R_SCORE_LO16:
2316 hi16_addend = bfd_get_32 (input_bfd, contents + rel->r_offset - 4);
2317 hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
2318 value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2319 offset = ((((value >> 16) & 0x3) << 15) | (value & 0x7fff)) >> 1;
2320 addend = (hi16_offset << 16) | (offset & 0xffff);
2321 msec = sec;
2322 addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend);
2323 addend -= relocation;
2324 addend += msec->output_section->vma + msec->output_offset;
2325 uvalue = addend;
2326 hi16_offset = (uvalue >> 16) << 1;
2327 hi16_value = (hi16_addend & (~(howto->dst_mask)))
2328 | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
2329 bfd_put_32 (input_bfd, hi16_value, contents + rel->r_offset - 4);
2330 offset = (uvalue & 0xffff) << 1;
2331 value = (value & (~(howto->dst_mask)))
2332 | (offset & 0x7fff) | ((offset << 1) & 0x30000);
2333 bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2334 break;
2335 default:
2336 value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2337 /* Get the (signed) value from the instruction. */
2338 addend = value & howto->src_mask;
2339 if (addend & ((howto->src_mask + 1) >> 1))
2340 {
2341 bfd_signed_vma mask;
2342
2343 mask = -1;
2344 mask &= ~howto->src_mask;
2345 addend |= mask;
2346 }
2347 msec = sec;
2348 addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
2349 addend += msec->output_section->vma + msec->output_offset;
2350 value = (value & ~howto->dst_mask) | (addend & howto->dst_mask);
2351 bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2352 break;
2353 }
2354 }
2355 }
2356 else
2357 {
2358 /* For global symbols we look up the symbol in the hash-table. */
2359 h = ((struct score_elf_link_hash_entry *)
2360 elf_sym_hashes (input_bfd) [r_symndx - extsymoff]);
2361 /* Find the real hash-table entry for this symbol. */
2362 while (h->root.root.type == bfd_link_hash_indirect
2363 || h->root.root.type == bfd_link_hash_warning)
2364 h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
2365
2366 /* Record the name of this symbol, for our caller. */
2367 name = h->root.root.root.string;
2368
2369 /* See if this is the special GP_DISP_LABEL symbol. Note that such a
2370 symbol must always be a global symbol. */
2371 if (strcmp (name, GP_DISP_LABEL) == 0)
2372 {
2373 /* Relocations against GP_DISP_LABEL are permitted only with
2374 R_SCORE_HI16 and R_SCORE_LO16 relocations. */
2375 if (r_type != R_SCORE_HI16 && r_type != R_SCORE_LO16)
2376 return bfd_reloc_notsupported;
2377
2378 gp_disp_p = TRUE;
2379 }
2380
2381 /* If this symbol is defined, calculate its address. Note that
2382 GP_DISP_LABEL is a magic symbol, always implicitly defined by the
2383 linker, so it's inappropriate to check to see whether or not
2384 its defined. */
2385 else if ((h->root.root.type == bfd_link_hash_defined
2386 || h->root.root.type == bfd_link_hash_defweak)
2387 && h->root.root.u.def.section)
2388 {
2389 sec = h->root.root.u.def.section;
2390 if (sec->output_section)
2391 relocation = (h->root.root.u.def.value
2392 + sec->output_section->vma
2393 + sec->output_offset);
2394 else
2395 {
2396 relocation = h->root.root.u.def.value;
2397 }
2398 }
2399 else if (h->root.root.type == bfd_link_hash_undefweak)
2400 /* We allow relocations against undefined weak symbols, giving
2401 it the value zero, so that you can undefined weak functions
2402 and check to see if they exist by looking at their addresses. */
2403 relocation = 0;
2404 else if (info->unresolved_syms_in_objects == RM_IGNORE
2405 && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
2406 relocation = 0;
2407 else if (strcmp (name, "_DYNAMIC_LINK") == 0)
2408 {
2409 /* If this is a dynamic link, we should have created a _DYNAMIC_LINK symbol
2410 in _bfd_score_elf_create_dynamic_sections. Otherwise, we should define
2411 the symbol with a value of 0. */
2412 BFD_ASSERT (! info->shared);
2413 BFD_ASSERT (bfd_get_section_by_name (output_bfd, ".dynamic") == NULL);
2414 relocation = 0;
2415 }
2416 else
2417 {
2418 if (! ((*info->callbacks->undefined_symbol)
2419 (info, h->root.root.root.string, input_bfd,
2420 input_section, rel->r_offset,
2421 (info->unresolved_syms_in_objects == RM_GENERATE_ERROR)
2422 || ELF_ST_VISIBILITY (h->root.other))))
2423 return bfd_reloc_undefined;
2424 relocation = 0;
2425 }
2426 }
2427
1c0d3aa6
NC
2428 r = score_elf_final_link_relocate (howto, input_bfd, output_bfd,
2429 input_section, contents, rel, relocs,
2430 relocation, info, sec, name,
2431 (h ? ELF_ST_TYPE ((unsigned int)h->root.root.type) :
2432 ELF_ST_TYPE ((unsigned int)sym->st_info)), h, local_sections,
2433 gp_disp_p);
2434
2435 if (r != bfd_reloc_ok)
2436 {
2437 const char *msg = (const char *)0;
2438
2439 switch (r)
2440 {
2441 case bfd_reloc_overflow:
2442 /* If the overflowing reloc was to an undefined symbol,
2443 we have already printed one error message and there
2444 is no point complaining again. */
2445 if (((!h) || (h->root.root.type != bfd_link_hash_undefined))
2446 && (!((*info->callbacks->reloc_overflow)
2447 (info, NULL, name, howto->name, (bfd_vma) 0,
2448 input_bfd, input_section, rel->r_offset))))
2449 return FALSE;
2450 break;
2451 case bfd_reloc_undefined:
2452 if (!((*info->callbacks->undefined_symbol)
2453 (info, name, input_bfd, input_section, rel->r_offset, TRUE)))
2454 return FALSE;
2455 break;
2456
2457 case bfd_reloc_outofrange:
2458 msg = _("internal error: out of range error");
2459 goto common_error;
2460
2461 case bfd_reloc_notsupported:
2462 msg = _("internal error: unsupported relocation error");
2463 goto common_error;
2464
2465 case bfd_reloc_dangerous:
2466 msg = _("internal error: dangerous error");
2467 goto common_error;
2468
2469 default:
2470 msg = _("internal error: unknown error");
2471 /* fall through */
2472
2473 common_error:
2474 if (!((*info->callbacks->warning)
2475 (info, msg, name, input_bfd, input_section, rel->r_offset)))
2476 return FALSE;
2477 break;
2478 }
2479 }
2480 }
2481
2482 return TRUE;
2483}
2484
2485/* Look through the relocs for a section during the first phase, and
2486 allocate space in the global offset table. */
2487
2488static bfd_boolean
2489_bfd_score_elf_check_relocs (bfd *abfd,
2490 struct bfd_link_info *info,
2491 asection *sec,
2492 const Elf_Internal_Rela *relocs)
2493{
2494 const char *name;
2495 bfd *dynobj;
2496 Elf_Internal_Shdr *symtab_hdr;
2497 struct elf_link_hash_entry **sym_hashes;
2498 struct score_got_info *g;
2499 size_t extsymoff;
2500 const Elf_Internal_Rela *rel;
2501 const Elf_Internal_Rela *rel_end;
2502 asection *sgot;
2503 asection *sreloc;
2504 const struct elf_backend_data *bed;
2505
2506 if (info->relocatable)
2507 return TRUE;
2508
2509 dynobj = elf_hash_table (info)->dynobj;
2510 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2511 sym_hashes = elf_sym_hashes (abfd);
2512 extsymoff = (elf_bad_symtab (abfd)) ? 0 : symtab_hdr->sh_info;
2513
2514 name = bfd_get_section_name (abfd, sec);
2515
2516 if (dynobj == NULL)
2517 {
2518 sgot = NULL;
2519 g = NULL;
2520 }
2521 else
2522 {
2523 sgot = score_elf_got_section (dynobj, FALSE);
2524 if (sgot == NULL)
2525 g = NULL;
2526 else
2527 {
2528 BFD_ASSERT (score_elf_section_data (sgot) != NULL);
2529 g = score_elf_section_data (sgot)->u.got_info;
2530 BFD_ASSERT (g != NULL);
2531 }
2532 }
2533
2534 sreloc = NULL;
2535 bed = get_elf_backend_data (abfd);
2536 rel_end = relocs + sec->reloc_count * bed->s->int_rels_per_ext_rel;
2537 for (rel = relocs; rel < rel_end; ++rel)
2538 {
2539 unsigned long r_symndx;
2540 unsigned int r_type;
2541 struct elf_link_hash_entry *h;
2542
2543 r_symndx = ELF32_R_SYM (rel->r_info);
2544 r_type = ELF32_R_TYPE (rel->r_info);
2545
2546 if (r_symndx < extsymoff)
2547 {
2548 h = NULL;
2549 }
2550 else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr))
2551 {
2552 (*_bfd_error_handler) (_("%s: Malformed reloc detected for section %s"), abfd, name);
2553 bfd_set_error (bfd_error_bad_value);
2554 return FALSE;
2555 }
2556 else
2557 {
2558 h = sym_hashes[r_symndx - extsymoff];
2559
2560 /* This may be an indirect symbol created because of a version. */
2561 if (h != NULL)
2562 {
2563 while (h->root.type == bfd_link_hash_indirect)
2564 h = (struct elf_link_hash_entry *)h->root.u.i.link;
2565 }
2566 }
2567
2568 /* Some relocs require a global offset table. */
2569 if (dynobj == NULL || sgot == NULL)
2570 {
2571 switch (r_type)
2572 {
2573 case R_SCORE_GOT15:
2574 case R_SCORE_CALL15:
2575 if (dynobj == NULL)
2576 elf_hash_table (info)->dynobj = dynobj = abfd;
2577 if (!score_elf_create_got_section (dynobj, info, FALSE))
2578 return FALSE;
2579 g = score_elf_got_info (dynobj, &sgot);
2580 break;
2581 case R_SCORE_ABS32:
2582 case R_SCORE_REL32:
2583 if (dynobj == NULL && (info->shared || h != NULL) && (sec->flags & SEC_ALLOC) != 0)
2584 elf_hash_table (info)->dynobj = dynobj = abfd;
2585 break;
2586 default:
2587 break;
2588 }
2589 }
2590
2591 if (!h && (r_type == R_SCORE_GOT_LO16))
2592 {
2593 if (! score_elf_record_local_got_symbol (abfd, r_symndx, rel->r_addend, g))
2594 return FALSE;
2595 }
2596
2597 switch (r_type)
2598 {
2599 case R_SCORE_CALL15:
2600 if (h == NULL)
2601 {
2602 (*_bfd_error_handler)
2603 (_("%B: CALL15 reloc at 0x%lx not against global symbol"),
2604 abfd, (unsigned long) rel->r_offset);
2605 bfd_set_error (bfd_error_bad_value);
2606 return FALSE;
2607 }
2608 else
2609 {
2610 /* This symbol requires a global offset table entry. */
2611 if (! score_elf_record_global_got_symbol (h, abfd, info, g))
2612 return FALSE;
2613
2614 /* We need a stub, not a plt entry for the undefined function. But we record
2615 it as if it needs plt. See _bfd_elf_adjust_dynamic_symbol. */
2616 h->needs_plt = 1;
2617 h->type = STT_FUNC;
2618 }
2619 break;
2620 case R_SCORE_GOT15:
2621 if (h && ! score_elf_record_global_got_symbol (h, abfd, info, g))
2622 return FALSE;
2623 break;
2624 case R_SCORE_ABS32:
2625 case R_SCORE_REL32:
2626 if ((info->shared || h != NULL) && (sec->flags & SEC_ALLOC) != 0)
2627 {
2628 if (sreloc == NULL)
2629 {
2630 sreloc = score_elf_rel_dyn_section (dynobj, TRUE);
2631 if (sreloc == NULL)
2632 return FALSE;
2633 }
2634#define SCORE_READONLY_SECTION (SEC_ALLOC | SEC_LOAD | SEC_READONLY)
2635 if (info->shared)
2636 {
2637 /* When creating a shared object, we must copy these reloc types into
2638 the output file as R_SCORE_REL32 relocs. We make room for this reloc
2639 in the .rel.dyn reloc section. */
2640 score_elf_allocate_dynamic_relocations (dynobj, 1);
2641 if ((sec->flags & SCORE_READONLY_SECTION)
2642 == SCORE_READONLY_SECTION)
2643 /* We tell the dynamic linker that there are
2644 relocations against the text segment. */
2645 info->flags |= DF_TEXTREL;
2646 }
2647 else
2648 {
2649 struct score_elf_link_hash_entry *hscore;
2650
2651 /* We only need to copy this reloc if the symbol is
2652 defined in a dynamic object. */
2653 hscore = (struct score_elf_link_hash_entry *)h;
2654 ++hscore->possibly_dynamic_relocs;
2655 if ((sec->flags & SCORE_READONLY_SECTION)
2656 == SCORE_READONLY_SECTION)
2657 /* We need it to tell the dynamic linker if there
2658 are relocations against the text segment. */
2659 hscore->readonly_reloc = TRUE;
2660 }
2661
2662 /* Even though we don't directly need a GOT entry for this symbol,
2663 a symbol must have a dynamic symbol table index greater that
2664 DT_SCORE_GOTSYM if there are dynamic relocations against it. */
2665 if (h != NULL)
2666 {
2667 if (dynobj == NULL)
2668 elf_hash_table (info)->dynobj = dynobj = abfd;
2669 if (! score_elf_create_got_section (dynobj, info, TRUE))
2670 return FALSE;
2671 g = score_elf_got_info (dynobj, &sgot);
2672 if (! score_elf_record_global_got_symbol (h, abfd, info, g))
2673 return FALSE;
2674 }
2675 }
2676 break;
2677
2678 /* This relocation describes the C++ object vtable hierarchy.
2679 Reconstruct it for later use during GC. */
2680 case R_SCORE_GNU_VTINHERIT:
2681 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
2682 return FALSE;
2683 break;
2684
2685 /* This relocation describes which C++ vtable entries are actually
2686 used. Record for later use during GC. */
2687 case R_SCORE_GNU_VTENTRY:
2688 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
2689 return FALSE;
2690 break;
2691 default:
2692 break;
2693 }
2694
2695 /* We must not create a stub for a symbol that has relocations
2696 related to taking the function's address. */
2697 switch (r_type)
2698 {
2699 default:
2700 if (h != NULL)
2701 {
2702 struct score_elf_link_hash_entry *sh;
2703
2704 sh = (struct score_elf_link_hash_entry *) h;
2705 sh->no_fn_stub = TRUE;
2706 }
2707 break;
2708 case R_SCORE_CALL15:
2709 break;
2710 }
2711 }
2712
2713 return TRUE;
2714}
2715
2716static bfd_boolean
2717_bfd_score_elf_add_symbol_hook (bfd *abfd,
2718 struct bfd_link_info *info ATTRIBUTE_UNUSED,
2719 Elf_Internal_Sym *sym,
2720 const char **namep ATTRIBUTE_UNUSED,
2721 flagword *flagsp ATTRIBUTE_UNUSED,
2722 asection **secp,
2723 bfd_vma *valp)
2724{
2725 switch (sym->st_shndx)
2726 {
2727 case SHN_COMMON:
2728 if (sym->st_size > elf_gp_size (abfd))
2729 break;
2730 /* Fall through. */
2731 case SHN_SCORE_SCOMMON:
2732 *secp = bfd_make_section_old_way (abfd, ".scommon");
2733 (*secp)->flags |= SEC_IS_COMMON;
2734 *valp = sym->st_size;
2735 break;
2736 }
2737
2738 return TRUE;
2739}
2740
2741static void
2742_bfd_score_elf_symbol_processing (bfd *abfd, asymbol *asym)
2743{
2744 elf_symbol_type *elfsym;
2745
2746 elfsym = (elf_symbol_type *) asym;
2747 switch (elfsym->internal_elf_sym.st_shndx)
2748 {
2749 case SHN_COMMON:
2750 if (asym->value > elf_gp_size (abfd))
2751 break;
2752 /* Fall through. */
2753 case SHN_SCORE_SCOMMON:
2754 if (score_elf_scom_section.name == NULL)
2755 {
2756 /* Initialize the small common section. */
2757 score_elf_scom_section.name = ".scommon";
2758 score_elf_scom_section.flags = SEC_IS_COMMON;
2759 score_elf_scom_section.output_section = &score_elf_scom_section;
2760 score_elf_scom_section.symbol = &score_elf_scom_symbol;
2761 score_elf_scom_section.symbol_ptr_ptr = &score_elf_scom_symbol_ptr;
2762 score_elf_scom_symbol.name = ".scommon";
2763 score_elf_scom_symbol.flags = BSF_SECTION_SYM;
2764 score_elf_scom_symbol.section = &score_elf_scom_section;
2765 score_elf_scom_symbol_ptr = &score_elf_scom_symbol;
2766 }
2767 asym->section = &score_elf_scom_section;
2768 asym->value = elfsym->internal_elf_sym.st_size;
2769 break;
2770 }
2771}
2772
2773static bfd_boolean
2774_bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
2775 const char *name ATTRIBUTE_UNUSED,
2776 Elf_Internal_Sym *sym,
2777 asection *input_sec,
2778 struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
2779{
2780 /* If we see a common symbol, which implies a relocatable link, then
2781 if a symbol was small common in an input file, mark it as small
2782 common in the output file. */
2783 if (sym->st_shndx == SHN_COMMON && strcmp (input_sec->name, ".scommon") == 0)
2784 sym->st_shndx = SHN_SCORE_SCOMMON;
2785
2786 return TRUE;
2787}
2788
2789static bfd_boolean
2790_bfd_score_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
2791 asection *sec,
2792 int *retval)
2793{
2794 if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
2795 {
2796 *retval = SHN_SCORE_SCOMMON;
2797 return TRUE;
2798 }
2799
2800 return FALSE;
2801}
2802
2803/* Adjust a symbol defined by a dynamic object and referenced by a
2804 regular object. The current definition is in some section of the
2805 dynamic object, but we're not including those sections. We have to
2806 change the definition to something the rest of the link can understand. */
2807
2808static bfd_boolean
2809_bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
2810 struct elf_link_hash_entry *h)
2811{
2812 bfd *dynobj;
2813 struct score_elf_link_hash_entry *hscore;
2814 asection *s;
2815
2816 dynobj = elf_hash_table (info)->dynobj;
2817
2818 /* Make sure we know what is going on here. */
2819 BFD_ASSERT (dynobj != NULL
2820 && (h->needs_plt
2821 || h->u.weakdef != NULL
2822 || (h->def_dynamic && h->ref_regular && !h->def_regular)));
2823
2824 /* If this symbol is defined in a dynamic object, we need to copy
2825 any R_SCORE_ABS32 or R_SCORE_REL32 relocs against it into the output
2826 file. */
2827 hscore = (struct score_elf_link_hash_entry *)h;
2828 if (!info->relocatable
2829 && hscore->possibly_dynamic_relocs != 0
2830 && (h->root.type == bfd_link_hash_defweak || !h->def_regular))
2831 {
2832 score_elf_allocate_dynamic_relocations (dynobj, hscore->possibly_dynamic_relocs);
2833 if (hscore->readonly_reloc)
2834 /* We tell the dynamic linker that there are relocations
2835 against the text segment. */
2836 info->flags |= DF_TEXTREL;
2837 }
2838
2839 /* For a function, create a stub, if allowed. */
2840 if (!hscore->no_fn_stub && h->needs_plt)
2841 {
2842 if (!elf_hash_table (info)->dynamic_sections_created)
2843 return TRUE;
2844
2845 /* If this symbol is not defined in a regular file, then set
2846 the symbol to the stub location. This is required to make
2847 function pointers compare as equal between the normal
2848 executable and the shared library. */
2849 if (!h->def_regular)
2850 {
2851 /* We need .stub section. */
2852 s = bfd_get_section_by_name (dynobj, SCORE_ELF_STUB_SECTION_NAME);
2853 BFD_ASSERT (s != NULL);
2854
2855 h->root.u.def.section = s;
2856 h->root.u.def.value = s->size;
2857
2858 /* XXX Write this stub address somewhere. */
2859 h->plt.offset = s->size;
2860
2861 /* Make room for this stub code. */
2862 s->size += SCORE_FUNCTION_STUB_SIZE;
2863
2864 /* The last half word of the stub will be filled with the index
2865 of this symbol in .dynsym section. */
2866 return TRUE;
2867 }
2868 }
2869 else if ((h->type == STT_FUNC) && !h->needs_plt)
2870 {
2871 /* This will set the entry for this symbol in the GOT to 0, and
2872 the dynamic linker will take care of this. */
2873 h->root.u.def.value = 0;
2874 return TRUE;
2875 }
2876
2877 /* If this is a weak symbol, and there is a real definition, the
2878 processor independent code will have arranged for us to see the
2879 real definition first, and we can just use the same value. */
2880 if (h->u.weakdef != NULL)
2881 {
2882 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2883 || h->u.weakdef->root.type == bfd_link_hash_defweak);
2884 h->root.u.def.section = h->u.weakdef->root.u.def.section;
2885 h->root.u.def.value = h->u.weakdef->root.u.def.value;
2886 return TRUE;
2887 }
2888
2889 /* This is a reference to a symbol defined by a dynamic object which
2890 is not a function. */
2891 return TRUE;
2892}
2893
2894/* This function is called after all the input files have been read,
2895 and the input sections have been assigned to output sections. */
2896
2897static bfd_boolean
2898_bfd_score_elf_always_size_sections (bfd *output_bfd,
2899 struct bfd_link_info *info)
2900{
2901 bfd *dynobj;
2902 asection *s;
2903 struct score_got_info *g;
2904 int i;
2905 bfd_size_type loadable_size = 0;
2906 bfd_size_type local_gotno;
2907 bfd *sub;
2908
2909 dynobj = elf_hash_table (info)->dynobj;
2910 if (dynobj == NULL)
2911 /* Relocatable links don't have it. */
2912 return TRUE;
2913
2914 g = score_elf_got_info (dynobj, &s);
2915 if (s == NULL)
2916 return TRUE;
2917
2918 /* Calculate the total loadable size of the output. That will give us the
2919 maximum number of GOT_PAGE entries required. */
2920 for (sub = info->input_bfds; sub; sub = sub->link_next)
2921 {
2922 asection *subsection;
2923
2924 for (subsection = sub->sections;
2925 subsection;
2926 subsection = subsection->next)
2927 {
2928 if ((subsection->flags & SEC_ALLOC) == 0)
2929 continue;
2930 loadable_size += ((subsection->size + 0xf)
2931 &~ (bfd_size_type) 0xf);
2932 }
2933 }
2934
2935 /* There has to be a global GOT entry for every symbol with
2936 a dynamic symbol table index of DT_SCORE_GOTSYM or
2937 higher. Therefore, it make sense to put those symbols
2938 that need GOT entries at the end of the symbol table. We
2939 do that here. */
2940 if (! score_elf_sort_hash_table (info, 1))
2941 return FALSE;
2942
2943 if (g->global_gotsym != NULL)
2944 i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx;
2945 else
2946 /* If there are no global symbols, or none requiring
2947 relocations, then GLOBAL_GOTSYM will be NULL. */
2948 i = 0;
2949
2950 /* In the worst case, we'll get one stub per dynamic symbol. */
2951 loadable_size += SCORE_FUNCTION_STUB_SIZE * i;
2952
2953 /* Assume there are two loadable segments consisting of
2954 contiguous sections. Is 5 enough? */
2955 local_gotno = (loadable_size >> 16) + 5;
2956
2957 g->local_gotno += local_gotno;
2958 s->size += g->local_gotno * SCORE_ELF_GOT_SIZE (output_bfd);
2959
2960 g->global_gotno = i;
2961 s->size += i * SCORE_ELF_GOT_SIZE (output_bfd);
2962
2963 score_elf_resolve_final_got_entries (g);
2964
2965 if (s->size > SCORE_ELF_GOT_MAX_SIZE (output_bfd))
2966 {
2967 /* Fixme. Error message or Warning message should be issued here. */
2968 }
2969
2970 return TRUE;
2971}
2972
2973/* Set the sizes of the dynamic sections. */
2974
2975static bfd_boolean
2976_bfd_score_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
2977{
2978 bfd *dynobj;
2979 asection *s;
2980 bfd_boolean reltext;
2981
2982 dynobj = elf_hash_table (info)->dynobj;
2983 BFD_ASSERT (dynobj != NULL);
2984
2985 if (elf_hash_table (info)->dynamic_sections_created)
2986 {
2987 /* Set the contents of the .interp section to the interpreter. */
2988 if (!info->shared)
2989 {
2990 s = bfd_get_section_by_name (dynobj, ".interp");
2991 BFD_ASSERT (s != NULL);
2992 s->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
2993 s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
2994 }
2995 }
2996
2997 /* The check_relocs and adjust_dynamic_symbol entry points have
2998 determined the sizes of the various dynamic sections. Allocate
2999 memory for them. */
3000 reltext = FALSE;
3001 for (s = dynobj->sections; s != NULL; s = s->next)
3002 {
3003 const char *name;
3004
3005 if ((s->flags & SEC_LINKER_CREATED) == 0)
3006 continue;
3007
3008 /* It's OK to base decisions on the section name, because none
3009 of the dynobj section names depend upon the input files. */
3010 name = bfd_get_section_name (dynobj, s);
3011
3012 if (CONST_STRNEQ (name, ".rel"))
3013 {
3014 if (s->size == 0)
3015 {
3016 /* We only strip the section if the output section name
3017 has the same name. Otherwise, there might be several
3018 input sections for this output section. FIXME: This
3019 code is probably not needed these days anyhow, since
3020 the linker now does not create empty output sections. */
3021 if (s->output_section != NULL
3022 && strcmp (name,
3023 bfd_get_section_name (s->output_section->owner,
3024 s->output_section)) == 0)
3025 s->flags |= SEC_EXCLUDE;
3026 }
3027 else
3028 {
3029 const char *outname;
3030 asection *target;
3031
3032 /* If this relocation section applies to a read only
3033 section, then we probably need a DT_TEXTREL entry.
3034 If the relocation section is .rel.dyn, we always
3035 assert a DT_TEXTREL entry rather than testing whether
3036 there exists a relocation to a read only section or
3037 not. */
3038 outname = bfd_get_section_name (output_bfd, s->output_section);
3039 target = bfd_get_section_by_name (output_bfd, outname + 4);
3040 if ((target != NULL
3041 && (target->flags & SEC_READONLY) != 0
3042 && (target->flags & SEC_ALLOC) != 0) || strcmp (outname, ".rel.dyn") == 0)
3043 reltext = TRUE;
3044
3045 /* We use the reloc_count field as a counter if we need
3046 to copy relocs into the output file. */
3047 if (strcmp (name, ".rel.dyn") != 0)
3048 s->reloc_count = 0;
3049 }
3050 }
3051 else if (CONST_STRNEQ (name, ".got"))
3052 {
3053 /* _bfd_score_elf_always_size_sections() has already done
3054 most of the work, but some symbols may have been mapped
3055 to versions that we must now resolve in the got_entries
3056 hash tables. */
3057 }
3058 else if (strcmp (name, SCORE_ELF_STUB_SECTION_NAME) == 0)
3059 {
3060 /* IRIX rld assumes that the function stub isn't at the end
3061 of .text section. So put a dummy. XXX */
3062 s->size += SCORE_FUNCTION_STUB_SIZE;
3063 }
3064 else if (! CONST_STRNEQ (name, ".init"))
3065 {
3066 /* It's not one of our sections, so don't allocate space. */
3067 continue;
3068 }
3069
3070 /* Allocate memory for the section contents. */
3071 s->contents = bfd_zalloc (dynobj, s->size);
3072 if (s->contents == NULL && s->size != 0)
3073 {
3074 bfd_set_error (bfd_error_no_memory);
3075 return FALSE;
3076 }
3077 }
3078
3079 if (elf_hash_table (info)->dynamic_sections_created)
3080 {
3081 /* Add some entries to the .dynamic section. We fill in the
3082 values later, in _bfd_score_elf_finish_dynamic_sections, but we
3083 must add the entries now so that we get the correct size for
3084 the .dynamic section. The DT_DEBUG entry is filled in by the
3085 dynamic linker and used by the debugger. */
3086
3087 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0))
3088 return FALSE;
3089
3090 if (reltext)
3091 info->flags |= DF_TEXTREL;
3092
3093 if ((info->flags & DF_TEXTREL) != 0)
3094 {
3095 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0))
3096 return FALSE;
3097 }
3098
3099 if (! SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTGOT, 0))
3100 return FALSE;
3101
3102 if (score_elf_rel_dyn_section (dynobj, FALSE))
3103 {
3104 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_REL, 0))
3105 return FALSE;
3106
3107 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELSZ, 0))
3108 return FALSE;
3109
3110 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELENT, 0))
3111 return FALSE;
3112 }
3113
3114 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_BASE_ADDRESS, 0))
3115 return FALSE;
3116
3117 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_LOCAL_GOTNO, 0))
3118 return FALSE;
3119
3120 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_SYMTABNO, 0))
3121 return FALSE;
3122
3123 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_UNREFEXTNO, 0))
3124 return FALSE;
3125
3126 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_GOTSYM, 0))
3127 return FALSE;
3128
3129 if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_HIPAGENO, 0))
3130 return FALSE;
3131 }
3132
3133 return TRUE;
3134}
3135
3136static bfd_boolean
3137_bfd_score_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
3138{
3139 struct elf_link_hash_entry *h;
3140 struct bfd_link_hash_entry *bh;
3141 flagword flags;
3142 asection *s;
3143
3144 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
3145 | SEC_LINKER_CREATED | SEC_READONLY);
3146
3147 /* ABI requests the .dynamic section to be read only. */
3148 s = bfd_get_section_by_name (abfd, ".dynamic");
3149 if (s != NULL)
3150 {
3151 if (!bfd_set_section_flags (abfd, s, flags))
3152 return FALSE;
3153 }
3154
3155 /* We need to create .got section. */
3156 if (!score_elf_create_got_section (abfd, info, FALSE))
3157 return FALSE;
3158
3159 if (!score_elf_rel_dyn_section (elf_hash_table (info)->dynobj, TRUE))
3160 return FALSE;
3161
3162 /* Create .stub section. */
3163 if (bfd_get_section_by_name (abfd, SCORE_ELF_STUB_SECTION_NAME) == NULL)
3164 {
b3549761
NC
3165 s = bfd_make_section_with_flags (abfd, SCORE_ELF_STUB_SECTION_NAME,
3166 flags | SEC_CODE);
1c0d3aa6 3167 if (s == NULL
1c0d3aa6
NC
3168 || !bfd_set_section_alignment (abfd, s, 2))
3169
3170 return FALSE;
3171 }
3172
3173 if (!info->shared)
3174 {
3175 const char *name;
3176
3177 name = "_DYNAMIC_LINK";
3178 bh = NULL;
3179 if (!(_bfd_generic_link_add_one_symbol
3180 (info, abfd, name, BSF_GLOBAL, bfd_abs_section_ptr,
3181 (bfd_vma) 0, (const char *)NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
3182 return FALSE;
3183
3184 h = (struct elf_link_hash_entry *)bh;
3185 h->non_elf = 0;
3186 h->def_regular = 1;
3187 h->type = STT_SECTION;
3188
3189 if (!bfd_elf_link_record_dynamic_symbol (info, h))
3190 return FALSE;
3191 }
3192
3193 return TRUE;
3194}
3195
3196
3197/* Finish up dynamic symbol handling. We set the contents of various
3198 dynamic sections here. */
3199
3200static bfd_boolean
3201_bfd_score_elf_finish_dynamic_symbol (bfd *output_bfd,
3202 struct bfd_link_info *info,
3203 struct elf_link_hash_entry *h,
3204 Elf_Internal_Sym *sym)
3205{
3206 bfd *dynobj;
3207 asection *sgot;
3208 struct score_got_info *g;
3209 const char *name;
3210
3211 dynobj = elf_hash_table (info)->dynobj;
3212
3213 if (h->plt.offset != MINUS_ONE)
3214 {
3215 asection *s;
3216 bfd_byte stub[SCORE_FUNCTION_STUB_SIZE];
3217
3218 /* This symbol has a stub. Set it up. */
3219 BFD_ASSERT (h->dynindx != -1);
3220
3221 s = bfd_get_section_by_name (dynobj, SCORE_ELF_STUB_SECTION_NAME);
3222 BFD_ASSERT (s != NULL);
3223
3224 /* FIXME: Can h->dynindex be more than 64K? */
3225 if (h->dynindx & 0xffff0000)
3226 return FALSE;
3227
3228 /* Fill the stub. */
3229 bfd_put_32 (output_bfd, STUB_LW, stub);
3230 bfd_put_32 (output_bfd, STUB_MOVE, stub + 4);
3231 bfd_put_32 (output_bfd, STUB_LI16 | (h->dynindx << 1), stub + 8);
3232 bfd_put_32 (output_bfd, STUB_BRL, stub + 12);
3233
3234 BFD_ASSERT (h->plt.offset <= s->size);
3235 memcpy (s->contents + h->plt.offset, stub, SCORE_FUNCTION_STUB_SIZE);
3236
3237 /* Mark the symbol as undefined. plt.offset != -1 occurs
3238 only for the referenced symbol. */
3239 sym->st_shndx = SHN_UNDEF;
3240
3241 /* The run-time linker uses the st_value field of the symbol
3242 to reset the global offset table entry for this external
3243 to its stub address when unlinking a shared object. */
3244 sym->st_value = (s->output_section->vma + s->output_offset + h->plt.offset);
3245 }
3246
3247 BFD_ASSERT (h->dynindx != -1 || h->forced_local);
3248
3249 sgot = score_elf_got_section (dynobj, FALSE);
3250 BFD_ASSERT (sgot != NULL);
3251 BFD_ASSERT (score_elf_section_data (sgot) != NULL);
3252 g = score_elf_section_data (sgot)->u.got_info;
3253 BFD_ASSERT (g != NULL);
3254
3255 /* Run through the global symbol table, creating GOT entries for all
3256 the symbols that need them. */
3257 if (g->global_gotsym != NULL && h->dynindx >= g->global_gotsym->dynindx)
3258 {
3259 bfd_vma offset;
3260 bfd_vma value;
3261
3262 value = sym->st_value;
3263 offset = score_elf_global_got_index (dynobj, h);
3264 bfd_put_32 (output_bfd, value, sgot->contents + offset);
3265 }
3266
3267 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
3268 name = h->root.root.string;
3269 if (strcmp (name, "_DYNAMIC") == 0 || strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
3270 sym->st_shndx = SHN_ABS;
3271 else if (strcmp (name, "_DYNAMIC_LINK") == 0)
3272 {
3273 sym->st_shndx = SHN_ABS;
3274 sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
3275 sym->st_value = 1;
3276 }
3277 else if (strcmp (name, GP_DISP_LABEL) == 0)
3278 {
3279 sym->st_shndx = SHN_ABS;
3280 sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
3281 sym->st_value = elf_gp (output_bfd);
3282 }
3283
3284 return TRUE;
3285}
3286
3287/* Finish up the dynamic sections. */
3288
3289static bfd_boolean
3290_bfd_score_elf_finish_dynamic_sections (bfd *output_bfd,
3291 struct bfd_link_info *info)
3292{
3293 bfd *dynobj;
3294 asection *sdyn;
3295 asection *sgot;
3296 asection *s;
3297 struct score_got_info *g;
3298
3299 dynobj = elf_hash_table (info)->dynobj;
3300
3301 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
3302
3303 sgot = score_elf_got_section (dynobj, FALSE);
3304 if (sgot == NULL)
3305 g = NULL;
3306 else
3307 {
3308 BFD_ASSERT (score_elf_section_data (sgot) != NULL);
3309 g = score_elf_section_data (sgot)->u.got_info;
3310 BFD_ASSERT (g != NULL);
3311 }
3312
3313 if (elf_hash_table (info)->dynamic_sections_created)
3314 {
3315 bfd_byte *b;
3316
3317 BFD_ASSERT (sdyn != NULL);
3318 BFD_ASSERT (g != NULL);
3319
3320 for (b = sdyn->contents;
3321 b < sdyn->contents + sdyn->size;
3322 b += SCORE_ELF_DYN_SIZE (dynobj))
3323 {
3324 Elf_Internal_Dyn dyn;
3325 const char *name;
3326 size_t elemsize;
3327 bfd_boolean swap_out_p;
3328
3329 /* Read in the current dynamic entry. */
3330 (*get_elf_backend_data (dynobj)->s->swap_dyn_in) (dynobj, b, &dyn);
3331
3332 /* Assume that we're going to modify it and write it out. */
3333 swap_out_p = TRUE;
3334
3335 switch (dyn.d_tag)
3336 {
3337 case DT_RELENT:
3338 s = score_elf_rel_dyn_section (dynobj, FALSE);
3339 BFD_ASSERT (s != NULL);
3340 dyn.d_un.d_val = SCORE_ELF_REL_SIZE (dynobj);
3341 break;
3342
3343 case DT_STRSZ:
3344 /* Rewrite DT_STRSZ. */
3345 dyn.d_un.d_val = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
3346 break;
3347
3348 case DT_PLTGOT:
3349 name = ".got";
3350 s = bfd_get_section_by_name (output_bfd, name);
3351 BFD_ASSERT (s != NULL);
3352 dyn.d_un.d_ptr = s->vma;
3353 break;
3354
3355 case DT_SCORE_BASE_ADDRESS:
3356 s = output_bfd->sections;
3357 BFD_ASSERT (s != NULL);
3358 dyn.d_un.d_ptr = s->vma & ~(bfd_vma) 0xffff;
3359 break;
3360
3361 case DT_SCORE_LOCAL_GOTNO:
3362 dyn.d_un.d_val = g->local_gotno;
3363 break;
3364
3365 case DT_SCORE_UNREFEXTNO:
3366 /* The index into the dynamic symbol table which is the
3367 entry of the first external symbol that is not
3368 referenced within the same object. */
3369 dyn.d_un.d_val = bfd_count_sections (output_bfd) + 1;
3370 break;
3371
3372 case DT_SCORE_GOTSYM:
3373 if (g->global_gotsym)
3374 {
3375 dyn.d_un.d_val = g->global_gotsym->dynindx;
3376 break;
3377 }
3378 /* In case if we don't have global got symbols we default
3379 to setting DT_SCORE_GOTSYM to the same value as
3380 DT_SCORE_SYMTABNO, so we just fall through. */
3381
3382 case DT_SCORE_SYMTABNO:
3383 name = ".dynsym";
3384 elemsize = SCORE_ELF_SYM_SIZE (output_bfd);
3385 s = bfd_get_section_by_name (output_bfd, name);
3386 BFD_ASSERT (s != NULL);
3387
3388 dyn.d_un.d_val = s->size / elemsize;
3389 break;
3390
3391 case DT_SCORE_HIPAGENO:
3392 dyn.d_un.d_val = g->local_gotno - SCORE_RESERVED_GOTNO;
3393 break;
3394
3395 default:
3396 swap_out_p = FALSE;
3397 break;
3398 }
3399
3400 if (swap_out_p)
3401 (*get_elf_backend_data (dynobj)->s->swap_dyn_out) (dynobj, &dyn, b);
3402 }
3403 }
3404
3405 /* The first entry of the global offset table will be filled at
3406 runtime. The second entry will be used by some runtime loaders.
3407 This isn't the case of IRIX rld. */
3408 if (sgot != NULL && sgot->size > 0)
3409 {
3410 bfd_put_32 (output_bfd, 0, sgot->contents);
3411 bfd_put_32 (output_bfd, 0x80000000, sgot->contents + SCORE_ELF_GOT_SIZE (output_bfd));
3412 }
3413
3414 if (sgot != NULL)
3415 elf_section_data (sgot->output_section)->this_hdr.sh_entsize
3416 = SCORE_ELF_GOT_SIZE (output_bfd);
3417
3418
3419 /* We need to sort the entries of the dynamic relocation section. */
3420 s = score_elf_rel_dyn_section (dynobj, FALSE);
3421
3422 if (s != NULL && s->size > (bfd_vma)2 * SCORE_ELF_REL_SIZE (output_bfd))
3423 {
3424 reldyn_sorting_bfd = output_bfd;
3425 qsort ((Elf32_External_Rel *) s->contents + 1, s->reloc_count - 1,
3426 sizeof (Elf32_External_Rel), score_elf_sort_dynamic_relocs);
3427 }
3428
3429 return TRUE;
3430}
3431
3432/* This function set up the ELF section header for a BFD section in preparation for writing
3433 it out. This is where the flags and type fields are set for unusual sections. */
3434
3435static bfd_boolean
3436_bfd_score_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
3437 Elf_Internal_Shdr *hdr,
3438 asection *sec)
3439{
3440 const char *name;
3441
3442 name = bfd_get_section_name (abfd, sec);
3443
3444 if (strcmp (name, ".got") == 0
3445 || strcmp (name, ".srdata") == 0
3446 || strcmp (name, ".sdata") == 0
3447 || strcmp (name, ".sbss") == 0)
3448 hdr->sh_flags |= SHF_SCORE_GPREL;
3449
3450 return TRUE;
3451}
3452
3453/* This function do additional processing on the ELF section header before writing
3454 it out. This is used to set the flags and type fields for some sections. */
3455
3456/* assign_file_positions_except_relocs() check section flag and if it is allocatable,
3457 warning message will be issued. backend_fake_section is called before
3458 assign_file_positions_except_relocs(); backend_section_processing after it. so, we
3459 modify section flag there, but not backend_fake_section. */
3460
3461static bfd_boolean
3462_bfd_score_elf_section_processing (bfd *abfd ATTRIBUTE_UNUSED, Elf_Internal_Shdr *hdr)
3463{
3464 if (hdr->bfd_section != NULL)
3465 {
3466 const char *name = bfd_get_section_name (abfd, hdr->bfd_section);
3467
3468 if (strcmp (name, ".sdata") == 0)
3469 {
3470 hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
3471 hdr->sh_type = SHT_PROGBITS;
3472 }
3473 else if (strcmp (name, ".sbss") == 0)
3474 {
3475 hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
3476 hdr->sh_type = SHT_NOBITS;
3477 }
3478 else if (strcmp (name, ".srdata") == 0)
3479 {
3480 hdr->sh_flags |= SHF_ALLOC | SHF_SCORE_GPREL;
3481 hdr->sh_type = SHT_PROGBITS;
3482 }
3483 }
3484
3485 return TRUE;
3486}
3487
3488static bfd_boolean
3489_bfd_score_elf_write_section (bfd *output_bfd, asection *sec, bfd_byte *contents)
3490{
3491 bfd_byte *to, *from, *end;
3492 int i;
3493
3494 if (strcmp (sec->name, ".pdr") != 0)
3495 return FALSE;
3496
3497 if (score_elf_section_data (sec)->u.tdata == NULL)
3498 return FALSE;
3499
3500 to = contents;
3501 end = contents + sec->size;
3502 for (from = contents, i = 0; from < end; from += PDR_SIZE, i++)
3503 {
3504 if ((score_elf_section_data (sec)->u.tdata)[i] == 1)
3505 continue;
3506
3507 if (to != from)
3508 memcpy (to, from, PDR_SIZE);
3509
3510 to += PDR_SIZE;
3511 }
3512 bfd_set_section_contents (output_bfd, sec->output_section, contents,
3513 (file_ptr) sec->output_offset, sec->size);
3514
3515 return TRUE;
3516}
3517
3518/* Copy data from a SCORE ELF indirect symbol to its direct symbol, hiding the old
3519 indirect symbol. Process additional relocation information. */
3520
3521static void
3522_bfd_score_elf_copy_indirect_symbol (struct bfd_link_info *info,
3523 struct elf_link_hash_entry *dir,
3524 struct elf_link_hash_entry *ind)
3525{
3526 struct score_elf_link_hash_entry *dirscore, *indscore;
3527
3528 _bfd_elf_link_hash_copy_indirect (info, dir, ind);
3529
3530 if (ind->root.type != bfd_link_hash_indirect)
3531 return;
3532
3533 dirscore = (struct score_elf_link_hash_entry *) dir;
3534 indscore = (struct score_elf_link_hash_entry *) ind;
3535 dirscore->possibly_dynamic_relocs += indscore->possibly_dynamic_relocs;
3536
3537 if (indscore->readonly_reloc)
3538 dirscore->readonly_reloc = TRUE;
3539
3540 if (indscore->no_fn_stub)
3541 dirscore->no_fn_stub = TRUE;
3542}
3543
3544/* Remove information about discarded functions from other sections which mention them. */
3545
3546static bfd_boolean
3547_bfd_score_elf_discard_info (bfd *abfd, struct elf_reloc_cookie *cookie,
3548 struct bfd_link_info *info)
3549{
3550 asection *o;
3551 bfd_boolean ret = FALSE;
3552 unsigned char *tdata;
3553 size_t i, skip;
3554
3555 o = bfd_get_section_by_name (abfd, ".pdr");
3556 if ((!o) || (o->size == 0) || (o->size % PDR_SIZE != 0)
3557 || (o->output_section != NULL && bfd_is_abs_section (o->output_section)))
3558 return FALSE;
3559
3560 tdata = bfd_zmalloc (o->size / PDR_SIZE);
3561 if (!tdata)
3562 return FALSE;
3563
3564 cookie->rels = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, info->keep_memory);
3565 if (!cookie->rels)
3566 {
3567 free (tdata);
3568 return FALSE;
3569 }
3570
3571 cookie->rel = cookie->rels;
3572 cookie->relend = cookie->rels + o->reloc_count;
3573
3574 for (i = 0, skip = 0; i < o->size; i++)
3575 {
3576 if (bfd_elf_reloc_symbol_deleted_p (i * PDR_SIZE, cookie))
3577 {
3578 tdata[i] = 1;
3579 skip++;
3580 }
3581 }
3582
3583 if (skip != 0)
3584 {
3585 score_elf_section_data (o)->u.tdata = tdata;
3586 o->size -= skip * PDR_SIZE;
3587 ret = TRUE;
3588 }
3589 else
3590 free (tdata);
3591
3592 if (!info->keep_memory)
3593 free (cookie->rels);
3594
3595 return ret;
3596}
3597
3598/* Signal that discard_info() has removed the discarded relocations for this section. */
3599
3600static bfd_boolean
3601_bfd_score_elf_ignore_discarded_relocs (asection *sec)
3602{
3603 if (strcmp (sec->name, ".pdr") == 0)
3604 return TRUE;
3605 return FALSE;
3606}
3607
07adf181
AM
3608/* Return the section that should be marked against GC for a given
3609 relocation. */
1c0d3aa6
NC
3610
3611static asection *
3612_bfd_score_elf_gc_mark_hook (asection *sec,
07adf181 3613 struct bfd_link_info *info,
1c0d3aa6
NC
3614 Elf_Internal_Rela *rel,
3615 struct elf_link_hash_entry *h,
3616 Elf_Internal_Sym *sym)
3617{
3618 if (h != NULL)
07adf181
AM
3619 switch (ELF32_R_TYPE (rel->r_info))
3620 {
3621 case R_SCORE_GNU_VTINHERIT:
3622 case R_SCORE_GNU_VTENTRY:
3623 return NULL;
3624 }
1c0d3aa6 3625
07adf181 3626 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
1c0d3aa6
NC
3627}
3628
3629/* Support for core dump NOTE sections. */
3630
3631static bfd_boolean
3632_bfd_score_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
3633{
3634 int offset;
3635 unsigned int raw_size;
3636
3637 switch (note->descsz)
3638 {
3639 default:
3640 return FALSE;
3641
3642 case 148: /* Linux/Score 32-bit. */
3643 /* pr_cursig */
3644 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
3645
3646 /* pr_pid */
3647 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
3648
3649 /* pr_reg */
3650 offset = 72;
3651 raw_size = 72;
3652
3653 break;
3654 }
3655
3656 /* Make a ".reg/999" section. */
3657 return _bfd_elfcore_make_pseudosection (abfd, ".reg", raw_size, note->descpos + offset);
3658}
3659
3660static bfd_boolean
3661_bfd_score_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
3662{
3663 switch (note->descsz)
3664 {
3665 default:
3666 return FALSE;
3667
3668 case 124: /* Linux/Score elf_prpsinfo. */
3669 elf_tdata (abfd)->core_program = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
3670 elf_tdata (abfd)->core_command = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
3671 }
3672
3673 /* Note that for some reason, a spurious space is tacked
3674 onto the end of the args in some (at least one anyway)
3675 implementations, so strip it off if it exists. */
3676
3677 {
3678 char *command = elf_tdata (abfd)->core_command;
3679 int n = strlen (command);
3680
3681 if (0 < n && command[n - 1] == ' ')
3682 command[n - 1] = '\0';
3683 }
3684
3685 return TRUE;
3686}
3687
3688
3689/* Score BFD functions. */
3690
3691static reloc_howto_type *
3692elf32_score_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
3693{
3694 unsigned int i;
3695
3696 for (i = 0; i < NUM_ELEM (elf32_score_reloc_map); i++)
3697 if (elf32_score_reloc_map[i].bfd_reloc_val == code)
3698 return &elf32_score_howto_table[elf32_score_reloc_map[i].elf_reloc_val];
3699
3700 return NULL;
3701}
3702
3703/* Create a score elf linker hash table. */
3704
3705static struct bfd_link_hash_table *
3706elf32_score_link_hash_table_create (bfd *abfd)
3707{
3708 struct score_elf_link_hash_table *ret;
3709 bfd_size_type amt = sizeof (struct score_elf_link_hash_table);
3710
3711 ret = bfd_malloc (amt);
3712 if (ret == NULL)
3713 return NULL;
3714
3715 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd, score_elf_link_hash_newfunc,
3716 sizeof (struct score_elf_link_hash_entry)))
3717 {
3718 free (ret);
3719 return NULL;
3720 }
3721
3722 return &ret->root.root;
3723}
3724
3725static bfd_boolean
3726elf32_score_print_private_bfd_data (bfd *abfd, void * ptr)
3727{
3728 FILE *file = (FILE *) ptr;
3729
3730 BFD_ASSERT (abfd != NULL && ptr != NULL);
3731
3732 /* Print normal ELF private data. */
3733 _bfd_elf_print_private_bfd_data (abfd, ptr);
3734
3735 /* xgettext:c-format */
3736 fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
3737 if (elf_elfheader (abfd)->e_flags & EF_SCORE_PIC)
3738 {
3739 fprintf (file, _(" [pic]"));
3740 }
3741 if (elf_elfheader (abfd)->e_flags & EF_SCORE_FIXDEP)
3742 {
3743 fprintf (file, _(" [fix dep]"));
3744 }
3745 fputc ('\n', file);
3746
3747 return TRUE;
3748}
3749
3750static bfd_boolean
3751elf32_score_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
3752{
3753 flagword in_flags;
3754 flagword out_flags;
3755
3756 if (!_bfd_generic_verify_endian_match (ibfd, obfd))
3757 return FALSE;
3758
3759 in_flags = elf_elfheader (ibfd)->e_flags;
3760 out_flags = elf_elfheader (obfd)->e_flags;
3761
3762 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
3763 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
3764 return TRUE;
3765
3766 in_flags = elf_elfheader (ibfd)->e_flags;
3767 out_flags = elf_elfheader (obfd)->e_flags;
3768
3769 if (! elf_flags_init (obfd))
3770 {
3771 elf_flags_init (obfd) = TRUE;
3772 elf_elfheader (obfd)->e_flags = in_flags;
3773
3774 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
3775 && bfd_get_arch_info (obfd)->the_default)
3776 {
3777 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
3778 }
3779
3780 return TRUE;
3781 }
3782
3783 if (((in_flags & EF_SCORE_PIC) != 0) != ((out_flags & EF_SCORE_PIC) != 0))
3784 {
3785 (*_bfd_error_handler) (_("%B: warning: linking PIC files with non-PIC files"), ibfd);
3786 }
3787
3788 /* FIXME: Maybe dependency fix compatibility should be checked here. */
3789
3790 return TRUE;
3791}
3792
3793static bfd_boolean
3794elf32_score_new_section_hook (bfd *abfd, asection *sec)
3795{
3796 struct _score_elf_section_data *sdata;
3797 bfd_size_type amt = sizeof (*sdata);
3798
3799 sdata = bfd_zalloc (abfd, amt);
3800 if (sdata == NULL)
3801 return FALSE;
3802 sec->used_by_bfd = sdata;
3803
3804 return _bfd_elf_new_section_hook (abfd, sec);
3805}
3806
3807
3808#define USE_REL 1
3809#define TARGET_LITTLE_SYM bfd_elf32_littlescore_vec
3810#define TARGET_LITTLE_NAME "elf32-littlescore"
3811#define TARGET_BIG_SYM bfd_elf32_bigscore_vec
3812#define TARGET_BIG_NAME "elf32-bigscore"
3813#define ELF_ARCH bfd_arch_score
3814#define ELF_MACHINE_CODE EM_SCORE
3815#define ELF_MAXPAGESIZE 0x8000
3816
3817#define elf_info_to_howto 0
3818#define elf_info_to_howto_rel _bfd_score_info_to_howto
3819#define elf_backend_relocate_section _bfd_score_elf_relocate_section
3820#define elf_backend_check_relocs _bfd_score_elf_check_relocs
3821#define elf_backend_add_symbol_hook _bfd_score_elf_add_symbol_hook
3822#define elf_backend_symbol_processing _bfd_score_elf_symbol_processing
3823#define elf_backend_link_output_symbol_hook _bfd_score_elf_link_output_symbol_hook
3824#define elf_backend_section_from_bfd_section _bfd_score_elf_section_from_bfd_section
3825#define elf_backend_adjust_dynamic_symbol _bfd_score_elf_adjust_dynamic_symbol
3826#define elf_backend_always_size_sections _bfd_score_elf_always_size_sections
3827#define elf_backend_size_dynamic_sections _bfd_score_elf_size_dynamic_sections
3828#define elf_backend_create_dynamic_sections _bfd_score_elf_create_dynamic_sections
3829#define elf_backend_finish_dynamic_symbol _bfd_score_elf_finish_dynamic_symbol
3830#define elf_backend_finish_dynamic_sections _bfd_score_elf_finish_dynamic_sections
3831#define elf_backend_fake_sections _bfd_score_elf_fake_sections
3832#define elf_backend_section_processing _bfd_score_elf_section_processing
3833#define elf_backend_write_section _bfd_score_elf_write_section
3834#define elf_backend_copy_indirect_symbol _bfd_score_elf_copy_indirect_symbol
3835#define elf_backend_hide_symbol _bfd_score_elf_hide_symbol
3836#define elf_backend_discard_info _bfd_score_elf_discard_info
3837#define elf_backend_ignore_discarded_relocs _bfd_score_elf_ignore_discarded_relocs
3838#define elf_backend_gc_mark_hook _bfd_score_elf_gc_mark_hook
3839#define elf_backend_grok_prstatus _bfd_score_elf_grok_prstatus
3840#define elf_backend_grok_psinfo _bfd_score_elf_grok_psinfo
3841#define elf_backend_can_gc_sections 1
3842#define elf_backend_want_plt_sym 0
3843#define elf_backend_got_header_size (4 * SCORE_RESERVED_GOTNO)
3844#define elf_backend_plt_header_size 0
3845#define elf_backend_collect TRUE
3846#define elf_backend_type_change_ok TRUE
3847
3848#define bfd_elf32_bfd_reloc_type_lookup elf32_score_reloc_type_lookup
3849#define bfd_elf32_bfd_link_hash_table_create elf32_score_link_hash_table_create
3850#define bfd_elf32_bfd_print_private_bfd_data elf32_score_print_private_bfd_data
3851#define bfd_elf32_bfd_merge_private_bfd_data elf32_score_merge_private_bfd_data
3852#define bfd_elf32_new_section_hook elf32_score_new_section_hook
3853
3854#include "elf32-target.h"