Coverage Report

Created: 2024-05-21 06:29

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