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