Coverage Report

Created: 2026-07-25 10:20

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