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