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