Coverage Report

Created: 2026-04-04 08:16

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_tdata (input_bfd)->symtab_hdr;
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 (bfd *output_bfd,
2411
           struct bfd_link_info *info,
2412
           bfd *input_bfd,
2413
           asection *input_section,
2414
           bfd_byte *contents,
2415
           Elf_Internal_Rela *relocs,
2416
           Elf_Internal_Sym *local_syms,
2417
           asection **local_sections)
2418
0
{
2419
0
  Elf_Internal_Shdr *symtab_hdr;
2420
0
  Elf_Internal_Rela *rel;
2421
0
  Elf_Internal_Rela *relend;
2422
0
  const char *name;
2423
0
  unsigned long offset;
2424
0
  unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
2425
0
  size_t extsymoff;
2426
0
  bool gp_disp_p = false;
2427
2428
  /* Sort dynsym.  */
2429
0
  if (elf_hash_table (info)->dynamic_sections_created)
2430
0
    {
2431
0
      bfd_size_type dynsecsymcount = 0;
2432
0
      if (bfd_link_pic (info))
2433
0
  {
2434
0
    asection * p;
2435
0
    elf_backend_data *bed = get_elf_backend_data (output_bfd);
2436
2437
0
    for (p = output_bfd->sections; p ; p = p->next)
2438
0
      if ((p->flags & SEC_EXCLUDE) == 0
2439
0
    && (p->flags & SEC_ALLOC) != 0
2440
0
    && !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p))
2441
0
        ++ dynsecsymcount;
2442
0
  }
2443
2444
0
      if (!score_elf_sort_hash_table (info, dynsecsymcount + 1))
2445
0
  return false;
2446
0
    }
2447
2448
0
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
2449
0
  extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
2450
0
  rel = relocs;
2451
0
  relend = relocs + input_section->reloc_count;
2452
0
  for (; rel < relend; rel++)
2453
0
    {
2454
0
      int r_type;
2455
0
      reloc_howto_type *howto;
2456
0
      unsigned long r_symndx;
2457
0
      Elf_Internal_Sym *sym;
2458
0
      asection *sec;
2459
0
      struct score_elf_link_hash_entry *h;
2460
0
      bfd_vma relocation = 0;
2461
0
      bfd_reloc_status_type r;
2462
0
      arelent bfd_reloc;
2463
2464
0
      r_symndx = ELF32_R_SYM (rel->r_info);
2465
0
      r_type = ELF32_R_TYPE (rel->r_info);
2466
2467
0
      if (! s3_bfd_score_info_to_howto (input_bfd, &bfd_reloc, (Elf_Internal_Rela *) rel))
2468
0
  continue;
2469
0
      howto = bfd_reloc.howto;
2470
2471
0
      h = NULL;
2472
0
      sym = NULL;
2473
0
      sec = NULL;
2474
2475
0
      if (r_symndx < extsymoff)
2476
0
  {
2477
0
    sym = local_syms + r_symndx;
2478
0
    sec = local_sections[r_symndx];
2479
0
    relocation = (sec->output_section->vma
2480
0
      + sec->output_offset
2481
0
      + sym->st_value);
2482
0
    name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, sec);
2483
2484
0
    if (!bfd_link_relocatable (info)
2485
0
        && (sec->flags & SEC_MERGE)
2486
0
        && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2487
0
      {
2488
0
        asection *msec;
2489
0
        bfd_vma addend, value;
2490
2491
0
        switch (r_type)
2492
0
    {
2493
0
    case R_SCORE_HI16:
2494
0
      break;
2495
0
    case R_SCORE_LO16:
2496
0
      hi16_addend = score_bfd_get_32 (input_bfd, contents + rel->r_offset - 4);
2497
0
      hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
2498
0
      value = score_bfd_get_32 (input_bfd, contents + rel->r_offset);
2499
0
      offset = ((((value >> 16) & 0x3) << 15) | (value & 0x7fff)) >> 1;
2500
0
      addend = (hi16_offset << 16) | (offset & 0xffff);
2501
0
      msec = sec;
2502
0
      addend = _bfd_elf_rel_local_sym (output_bfd, 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 (output_bfd, sym, &msec, addend);
2524
0
        addend -= relocation;
2525
0
        addend += msec->output_section->vma + msec->output_offset;
2526
0
        addend &= 0xffffffff;
2527
0
        value = (value & ~howto->src_mask)
2528
0
           | ((addend & 0x3ff) << 5)
2529
0
           | (((addend >> 10) & 0x7fff) << 16)
2530
0
           | (((addend >> 25) & 0x7f) << 32);
2531
0
        score_bfd_put_48 (input_bfd, value, contents + rel->r_offset);
2532
0
        break;
2533
0
      }
2534
2535
0
    case R_SCORE_IMM30:
2536
0
      {
2537
0
        int not_word_align_p = 0;
2538
0
        value = score_bfd_get_48 (input_bfd, contents + rel->r_offset);
2539
0
        addend = ((value >> 7) & 0xff)
2540
0
            | (((value >> 16) & 0x7fff) << 8)
2541
0
            | (((value >> 32) & 0x7f) << 23);
2542
0
        addend <<= howto->rightshift;
2543
0
        msec = sec;
2544
0
        addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend);
2545
0
        addend -= relocation;
2546
0
        addend += msec->output_section->vma + msec->output_offset;
2547
0
        addend &= 0xffffffff;
2548
2549
        /* Check lw48/sw48 rd, value/label word align.  */
2550
0
        if ((addend & 0x3) != 0)
2551
0
          not_word_align_p = 1;
2552
2553
0
        addend >>= howto->rightshift;
2554
0
        value = (value & ~howto->src_mask)
2555
0
           | (((addend & 0xff) >> 0) << 7)
2556
0
           | (((addend & 0x7fff00) >> 8) << 16)
2557
0
           | (((addend & 0x3f800000) >> 23) << 32);
2558
0
        score_bfd_put_48 (input_bfd, value, contents + rel->r_offset);
2559
2560
0
        if (not_word_align_p)
2561
0
          return bfd_reloc_other;
2562
0
        else
2563
0
          break;
2564
0
      }
2565
2566
0
    case R_SCORE_GOT_LO16:
2567
0
      value = score_bfd_get_32 (input_bfd, contents + rel->r_offset);
2568
0
      addend = (((value >> 16) & 0x3) << 14) | ((value & 0x7fff) >> 1);
2569
0
      msec = sec;
2570
0
      addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
2571
0
      addend += msec->output_section->vma + msec->output_offset;
2572
0
      value = (value & (~(howto->dst_mask))) | ((addend & 0x3fff) << 1)
2573
0
         | (((addend >> 14) & 0x3) << 16);
2574
2575
0
      score_bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2576
0
      break;
2577
2578
0
    case R_SCORE_ABS32:
2579
0
    case R_SCORE_REL32:
2580
0
      value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2581
      /* Get the (signed) value from the instruction.  */
2582
0
      addend = value & howto->src_mask;
2583
0
      if (addend & ((howto->src_mask + 1) >> 1))
2584
0
        {
2585
0
          bfd_signed_vma mask;
2586
2587
0
          mask = -1;
2588
0
          mask &= ~howto->src_mask;
2589
0
          addend |= mask;
2590
0
        }
2591
0
      msec = sec;
2592
0
      addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
2593
0
      addend += msec->output_section->vma + msec->output_offset;
2594
0
      value = (value & ~howto->dst_mask) | (addend & howto->dst_mask);
2595
0
      bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2596
0
      break;
2597
2598
0
    default:
2599
0
      value = score_bfd_get_32 (input_bfd, contents + rel->r_offset);
2600
      /* Get the (signed) value from the instruction.  */
2601
0
      addend = value & howto->src_mask;
2602
0
      if (addend & ((howto->src_mask + 1) >> 1))
2603
0
        {
2604
0
          bfd_signed_vma mask;
2605
2606
0
          mask = -1;
2607
0
          mask &= ~howto->src_mask;
2608
0
          addend |= mask;
2609
0
        }
2610
0
      msec = sec;
2611
0
      addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
2612
0
      addend += msec->output_section->vma + msec->output_offset;
2613
0
      value = (value & ~howto->dst_mask) | (addend & howto->dst_mask);
2614
0
      score_bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2615
0
      break;
2616
0
    }
2617
0
      }
2618
0
  }
2619
0
      else
2620
0
  {
2621
    /* For global symbols we look up the symbol in the hash-table.  */
2622
0
    h = ((struct score_elf_link_hash_entry *)
2623
0
         elf_sym_hashes (input_bfd) [r_symndx - extsymoff]);
2624
2625
0
    if (info->wrap_hash != NULL
2626
0
        && (input_section->flags & SEC_DEBUGGING) != 0)
2627
0
      h = ((struct score_elf_link_hash_entry *)
2628
0
     unwrap_hash_lookup (info, input_bfd, &h->root.root));
2629
2630
    /* Find the real hash-table entry for this symbol.  */
2631
0
    while (h->root.root.type == bfd_link_hash_indirect
2632
0
     || h->root.root.type == bfd_link_hash_warning)
2633
0
      h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
2634
2635
    /* Record the name of this symbol, for our caller.  */
2636
0
    name = h->root.root.root.string;
2637
2638
    /* See if this is the special GP_DISP_LABEL symbol.  Note that such a
2639
       symbol must always be a global symbol.  */
2640
0
    if (strcmp (name, GP_DISP_LABEL) == 0)
2641
0
      {
2642
        /* Relocations against GP_DISP_LABEL are permitted only with
2643
     R_SCORE_HI16 and R_SCORE_LO16 relocations.  */
2644
0
        if (r_type != R_SCORE_HI16 && r_type != R_SCORE_LO16)
2645
0
    return bfd_reloc_notsupported;
2646
2647
0
        gp_disp_p = true;
2648
0
      }
2649
2650
    /* If this symbol is defined, calculate its address.  Note that
2651
        GP_DISP_LABEL is a magic symbol, always implicitly defined by the
2652
        linker, so it's inappropriate to check to see whether or not
2653
        its defined.  */
2654
0
    else if ((h->root.root.type == bfd_link_hash_defined
2655
0
        || h->root.root.type == bfd_link_hash_defweak)
2656
0
       && h->root.root.u.def.section)
2657
0
      {
2658
0
        sec = h->root.root.u.def.section;
2659
0
        if (sec->output_section)
2660
0
    relocation = (h->root.root.u.def.value
2661
0
            + sec->output_section->vma
2662
0
            + sec->output_offset);
2663
0
        else
2664
0
    {
2665
0
      relocation = h->root.root.u.def.value;
2666
0
    }
2667
0
      }
2668
0
    else if (h->root.root.type == bfd_link_hash_undefweak)
2669
      /* We allow relocations against undefined weak symbols, giving
2670
         it the value zero, so that you can undefined weak functions
2671
         and check to see if they exist by looking at their addresses.  */
2672
0
      relocation = 0;
2673
0
    else if (info->unresolved_syms_in_objects == RM_IGNORE
2674
0
       && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
2675
0
      relocation = 0;
2676
0
    else if (strcmp (name, "_DYNAMIC_LINK") == 0)
2677
0
      {
2678
        /* If this is a dynamic link, we should have created a _DYNAMIC_LINK symbol
2679
     in s3_bfd_score_elf_create_dynamic_sections.  Otherwise, we should define
2680
     the symbol with a value of 0.  */
2681
0
        BFD_ASSERT (! bfd_link_pic (info));
2682
0
        BFD_ASSERT (bfd_get_section_by_name (output_bfd, ".dynamic") == NULL);
2683
0
        relocation = 0;
2684
0
      }
2685
0
    else if (!bfd_link_relocatable (info))
2686
0
      {
2687
0
              info->callbacks->undefined_symbol
2688
0
    (info, h->root.root.root.string, input_bfd, input_section,
2689
0
     rel->r_offset,
2690
0
     (info->unresolved_syms_in_objects == RM_DIAGNOSE
2691
0
      && !info->warn_unresolved_syms)
2692
0
     || ELF_ST_VISIBILITY (h->root.other));
2693
0
              relocation = 0;
2694
0
            }
2695
0
  }
2696
2697
0
      if (sec != NULL && discarded_section (sec))
2698
0
  RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
2699
0
           rel, 1, relend, R_SCORE_NONE,
2700
0
           howto, 0, contents);
2701
2702
0
      if (bfd_link_relocatable (info))
2703
0
  {
2704
    /* This is a relocatable link.  We don't have to change
2705
       anything, unless the reloc is against a section symbol,
2706
       in which case we have to adjust according to where the
2707
       section symbol winds up in the output section.  */
2708
0
    if (r_symndx < symtab_hdr->sh_info)
2709
0
      {
2710
0
        sym = local_syms + r_symndx;
2711
0
        if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2712
0
    {
2713
0
      sec = local_sections[r_symndx];
2714
0
      score_elf_add_to_rel (input_bfd, contents + rel->r_offset,
2715
0
            howto, (bfd_signed_vma) (sec->output_offset + sym->st_value));
2716
0
    }
2717
0
      }
2718
0
    continue;
2719
0
  }
2720
2721
      /* This is a final link.  */
2722
0
      r = score_elf_final_link_relocate (howto, input_bfd, output_bfd,
2723
0
           input_section, contents, rel, relocs,
2724
0
           relocation, info, name,
2725
0
           (h ? ELF_ST_TYPE ((unsigned int)h->root.root.type) :
2726
0
           ELF_ST_TYPE ((unsigned int)sym->st_info)), h, local_sections,
2727
0
           gp_disp_p);
2728
2729
0
      if (r != bfd_reloc_ok)
2730
0
  {
2731
0
    const char *msg = (const char *)0;
2732
2733
0
    switch (r)
2734
0
      {
2735
0
      case bfd_reloc_overflow:
2736
        /* If the overflowing reloc was to an undefined symbol,
2737
     we have already printed one error message and there
2738
     is no point complaining again.  */
2739
0
        if (!h || h->root.root.type != bfd_link_hash_undefined)
2740
0
    (*info->callbacks->reloc_overflow)
2741
0
      (info, NULL, name, howto->name, (bfd_vma) 0,
2742
0
       input_bfd, input_section, rel->r_offset);
2743
0
        break;
2744
0
      case bfd_reloc_undefined:
2745
0
        (*info->callbacks->undefined_symbol)
2746
0
    (info, name, input_bfd, input_section, rel->r_offset, true);
2747
0
        break;
2748
2749
0
      case bfd_reloc_outofrange:
2750
0
        msg = _("internal error: out of range error");
2751
0
        goto common_error;
2752
2753
0
      case bfd_reloc_notsupported:
2754
0
        msg = _("internal error: unsupported relocation error");
2755
0
        goto common_error;
2756
2757
0
      case bfd_reloc_dangerous:
2758
0
        msg = _("internal error: dangerous error");
2759
0
        goto common_error;
2760
2761
      /* Use bfd_reloc_other to check lw48, sw48 word align.  */
2762
0
      case bfd_reloc_other:
2763
0
        msg = _("address not word aligned");
2764
0
        goto common_error;
2765
2766
0
      default:
2767
0
        msg = _("internal error: unknown error");
2768
        /* Fall through.  */
2769
2770
0
      common_error:
2771
0
        (*info->callbacks->warning) (info, msg, name, input_bfd,
2772
0
             input_section, rel->r_offset);
2773
0
        break;
2774
0
      }
2775
0
  }
2776
0
    }
2777
2778
0
  return true;
2779
0
}
2780
2781
/* Look through the relocs for a section during the first phase, and
2782
   allocate space in the global offset table.  */
2783
static bool
2784
s3_bfd_score_elf_check_relocs (bfd *abfd,
2785
             struct bfd_link_info *info,
2786
             asection *sec,
2787
             const Elf_Internal_Rela *relocs)
2788
0
{
2789
0
  bfd *dynobj;
2790
0
  Elf_Internal_Shdr *symtab_hdr;
2791
0
  struct elf_link_hash_entry **sym_hashes;
2792
0
  struct score_got_info *g;
2793
0
  size_t extsymoff;
2794
0
  const Elf_Internal_Rela *rel;
2795
0
  const Elf_Internal_Rela *rel_end;
2796
0
  asection *sgot;
2797
0
  asection *sreloc;
2798
2799
0
  if (bfd_link_relocatable (info))
2800
0
    return true;
2801
2802
0
  dynobj = elf_hash_table (info)->dynobj;
2803
0
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2804
0
  sym_hashes = elf_sym_hashes (abfd);
2805
0
  extsymoff = (elf_bad_symtab (abfd)) ? 0 : symtab_hdr->sh_info;
2806
2807
0
  if (dynobj == NULL)
2808
0
    {
2809
0
      sgot = NULL;
2810
0
      g = NULL;
2811
0
    }
2812
0
  else
2813
0
    {
2814
0
      sgot = score_elf_got_section (dynobj, false);
2815
0
      if (sgot == NULL)
2816
0
  g = NULL;
2817
0
      else
2818
0
  {
2819
0
    BFD_ASSERT (score_elf_section_data (sgot) != NULL);
2820
0
    g = score_elf_section_data (sgot)->u.got_info;
2821
0
    BFD_ASSERT (g != NULL);
2822
0
  }
2823
0
    }
2824
2825
0
  sreloc = NULL;
2826
0
  rel_end = relocs + sec->reloc_count;
2827
0
  for (rel = relocs; rel < rel_end; ++rel)
2828
0
    {
2829
0
      unsigned long r_symndx;
2830
0
      unsigned int r_type;
2831
0
      struct elf_link_hash_entry *h;
2832
2833
0
      r_symndx = ELF32_R_SYM (rel->r_info);
2834
0
      r_type = ELF32_R_TYPE (rel->r_info);
2835
2836
0
      if (r_symndx < extsymoff)
2837
0
  {
2838
0
    h = NULL;
2839
0
  }
2840
0
      else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr))
2841
0
  {
2842
0
    _bfd_error_handler
2843
      /* xgettext:c-format */
2844
0
      (_("%pB: malformed reloc detected for section %pA"), abfd, sec);
2845
0
    bfd_set_error (bfd_error_bad_value);
2846
0
    return false;
2847
0
  }
2848
0
      else
2849
0
  {
2850
0
    h = sym_hashes[r_symndx - extsymoff];
2851
2852
    /* This may be an indirect symbol created because of a version.  */
2853
0
    if (h != NULL)
2854
0
      {
2855
0
        while (h->root.type == bfd_link_hash_indirect)
2856
0
    h = (struct elf_link_hash_entry *)h->root.u.i.link;
2857
0
      }
2858
0
  }
2859
2860
      /* Some relocs require a global offset table.  */
2861
0
      if (dynobj == NULL || sgot == NULL)
2862
0
  {
2863
0
    switch (r_type)
2864
0
      {
2865
0
      case R_SCORE_GOT15:
2866
0
      case R_SCORE_CALL15:
2867
0
        if (dynobj == NULL)
2868
0
    elf_hash_table (info)->dynobj = dynobj = abfd;
2869
0
        if (!score_elf_create_got_section (dynobj, info, false))
2870
0
    return false;
2871
0
        g = score_elf_got_info (dynobj, &sgot);
2872
0
        break;
2873
0
      case R_SCORE_ABS32:
2874
0
      case R_SCORE_REL32:
2875
0
        if (dynobj == NULL
2876
0
      && (bfd_link_pic (info) || h != NULL)
2877
0
      && (sec->flags & SEC_ALLOC) != 0)
2878
0
    elf_hash_table (info)->dynobj = dynobj = abfd;
2879
0
        break;
2880
0
      default:
2881
0
        break;
2882
0
      }
2883
0
  }
2884
2885
0
      if (!h && (r_type == R_SCORE_GOT_LO16))
2886
0
  {
2887
0
    if (! score_elf_record_local_got_symbol (abfd, r_symndx, rel->r_addend, g))
2888
0
      return false;
2889
0
  }
2890
2891
0
      switch (r_type)
2892
0
  {
2893
0
  case R_SCORE_CALL15:
2894
0
    if (h == NULL)
2895
0
      {
2896
0
        _bfd_error_handler
2897
    /* xgettext:c-format */
2898
0
    (_("%pB: CALL15 reloc at %#" PRIx64 " not against global symbol"),
2899
0
     abfd, (uint64_t) rel->r_offset);
2900
0
        bfd_set_error (bfd_error_bad_value);
2901
0
        return false;
2902
0
      }
2903
0
    else
2904
0
      {
2905
        /* This symbol requires a global offset table entry.  */
2906
0
        if (! score_elf_record_global_got_symbol (h, abfd, info, g))
2907
0
    return false;
2908
2909
        /* We need a stub, not a plt entry for the undefined function.  But we record
2910
     it as if it needs plt.  See _bfd_elf_adjust_dynamic_symbol.  */
2911
0
        h->needs_plt = 1;
2912
0
        h->type = STT_FUNC;
2913
0
      }
2914
0
    break;
2915
0
  case R_SCORE_GOT15:
2916
0
    if (h && ! score_elf_record_global_got_symbol (h, abfd, info, g))
2917
0
      return false;
2918
0
    break;
2919
0
  case R_SCORE_ABS32:
2920
0
  case R_SCORE_REL32:
2921
0
    if ((bfd_link_pic (info) || h != NULL)
2922
0
        && (sec->flags & SEC_ALLOC) != 0)
2923
0
      {
2924
0
        if (sreloc == NULL)
2925
0
    {
2926
0
      sreloc = score_elf_rel_dyn_section (dynobj, true);
2927
0
      if (sreloc == NULL)
2928
0
        return false;
2929
0
    }
2930
0
#define SCORE_READONLY_SECTION (SEC_ALLOC | SEC_LOAD | SEC_READONLY)
2931
0
        if (bfd_link_pic (info))
2932
0
    {
2933
      /* When creating a shared object, we must copy these reloc types into
2934
         the output file as R_SCORE_REL32 relocs.  We make room for this reloc
2935
         in the .rel.dyn reloc section.  */
2936
0
      score_elf_allocate_dynamic_relocations (dynobj, 1);
2937
0
      if ((sec->flags & SCORE_READONLY_SECTION)
2938
0
          == SCORE_READONLY_SECTION)
2939
        /* We tell the dynamic linker that there are
2940
           relocations against the text segment.  */
2941
0
        info->flags |= DF_TEXTREL;
2942
0
    }
2943
0
        else
2944
0
    {
2945
0
      struct score_elf_link_hash_entry *hscore;
2946
2947
      /* We only need to copy this reloc if the symbol is
2948
         defined in a dynamic object.  */
2949
0
      hscore = (struct score_elf_link_hash_entry *)h;
2950
0
      ++hscore->possibly_dynamic_relocs;
2951
0
      if ((sec->flags & SCORE_READONLY_SECTION)
2952
0
          == SCORE_READONLY_SECTION)
2953
        /* We need it to tell the dynamic linker if there
2954
           are relocations against the text segment.  */
2955
0
        hscore->readonly_reloc = true;
2956
0
    }
2957
2958
        /* Even though we don't directly need a GOT entry for this symbol,
2959
     a symbol must have a dynamic symbol table index greater that
2960
     DT_SCORE_GOTSYM if there are dynamic relocations against it.  */
2961
0
        if (h != NULL)
2962
0
    {
2963
0
      if (dynobj == NULL)
2964
0
        elf_hash_table (info)->dynobj = dynobj = abfd;
2965
0
      if (! score_elf_create_got_section (dynobj, info, true))
2966
0
        return false;
2967
0
      g = score_elf_got_info (dynobj, &sgot);
2968
0
      if (! score_elf_record_global_got_symbol (h, abfd, info, g))
2969
0
        return false;
2970
0
    }
2971
0
      }
2972
0
    break;
2973
2974
    /* This relocation describes the C++ object vtable hierarchy.
2975
       Reconstruct it for later use during GC.  */
2976
0
  case R_SCORE_GNU_VTINHERIT:
2977
0
    if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
2978
0
      return false;
2979
0
    break;
2980
2981
    /* This relocation describes which C++ vtable entries are actually
2982
       used.  Record for later use during GC.  */
2983
0
  case R_SCORE_GNU_VTENTRY:
2984
0
    if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
2985
0
      return false;
2986
0
    break;
2987
0
  default:
2988
0
    break;
2989
0
  }
2990
2991
      /* We must not create a stub for a symbol that has relocations
2992
   related to taking the function's address.  */
2993
0
      switch (r_type)
2994
0
  {
2995
0
  default:
2996
0
    if (h != NULL)
2997
0
      {
2998
0
        struct score_elf_link_hash_entry *sh;
2999
3000
0
        sh = (struct score_elf_link_hash_entry *) h;
3001
0
        sh->no_fn_stub = true;
3002
0
      }
3003
0
    break;
3004
0
  case R_SCORE_CALL15:
3005
0
    break;
3006
0
  }
3007
0
    }
3008
3009
0
  return true;
3010
0
}
3011
3012
static bool
3013
s3_bfd_score_elf_add_symbol_hook (bfd *abfd,
3014
          struct bfd_link_info *info ATTRIBUTE_UNUSED,
3015
          Elf_Internal_Sym *sym,
3016
          const char **namep ATTRIBUTE_UNUSED,
3017
          flagword *flagsp ATTRIBUTE_UNUSED,
3018
          asection **secp,
3019
          bfd_vma *valp)
3020
0
{
3021
0
  switch (sym->st_shndx)
3022
0
    {
3023
0
    case SHN_COMMON:
3024
0
      if (sym->st_size > elf_gp_size (abfd))
3025
0
  break;
3026
      /* Fall through.  */
3027
0
    case SHN_SCORE_SCOMMON:
3028
0
      *secp = bfd_make_section_old_way (abfd, ".scommon");
3029
0
      (*secp)->flags |= SEC_IS_COMMON | SEC_SMALL_DATA;
3030
0
      *valp = sym->st_size;
3031
0
      break;
3032
0
    }
3033
3034
0
  return true;
3035
0
}
3036
3037
static void
3038
s3_bfd_score_elf_symbol_processing (bfd *abfd, asymbol *asym)
3039
0
{
3040
0
  elf_symbol_type *elfsym;
3041
3042
0
  elfsym = (elf_symbol_type *) asym;
3043
0
  switch (elfsym->internal_elf_sym.st_shndx)
3044
0
    {
3045
0
    case SHN_COMMON:
3046
0
      if (asym->value > elf_gp_size (abfd))
3047
0
  break;
3048
      /* Fall through.  */
3049
0
    case SHN_SCORE_SCOMMON:
3050
0
      asym->section = &score_elf_scom_section;
3051
0
      asym->value = elfsym->internal_elf_sym.st_size;
3052
0
      break;
3053
0
    }
3054
0
}
3055
3056
static int
3057
s3_bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
3058
            const char *name ATTRIBUTE_UNUSED,
3059
            Elf_Internal_Sym *sym,
3060
            asection *input_sec,
3061
            struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
3062
0
{
3063
  /* If we see a common symbol, which implies a relocatable link, then
3064
     if a symbol was small common in an input file, mark it as small
3065
     common in the output file.  */
3066
0
  if (sym->st_shndx == SHN_COMMON && strcmp (input_sec->name, ".scommon") == 0)
3067
0
    sym->st_shndx = SHN_SCORE_SCOMMON;
3068
3069
0
  return 1;
3070
0
}
3071
3072
static bool
3073
s3_bfd_score_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
3074
             asection *sec,
3075
             int *retval)
3076
0
{
3077
0
  if (strcmp (bfd_section_name (sec), ".scommon") == 0)
3078
0
    {
3079
0
      *retval = SHN_SCORE_SCOMMON;
3080
0
      return true;
3081
0
    }
3082
3083
0
  return false;
3084
0
}
3085
3086
/* Adjust a symbol defined by a dynamic object and referenced by a
3087
   regular object.  The current definition is in some section of the
3088
   dynamic object, but we're not including those sections.  We have to
3089
   change the definition to something the rest of the link can understand.  */
3090
static bool
3091
s3_bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
3092
          struct elf_link_hash_entry *h)
3093
0
{
3094
0
  bfd *dynobj;
3095
0
  struct score_elf_link_hash_entry *hscore;
3096
0
  asection *s;
3097
3098
0
  dynobj = elf_hash_table (info)->dynobj;
3099
3100
  /* Make sure we know what is going on here.  */
3101
0
  BFD_ASSERT (dynobj != NULL
3102
0
        && (h->needs_plt
3103
0
      || h->is_weakalias
3104
0
      || (h->def_dynamic && h->ref_regular && !h->def_regular)));
3105
3106
  /* If this symbol is defined in a dynamic object, we need to copy
3107
     any R_SCORE_ABS32 or R_SCORE_REL32 relocs against it into the output
3108
     file.  */
3109
0
  hscore = (struct score_elf_link_hash_entry *)h;
3110
0
  if (!bfd_link_relocatable (info)
3111
0
      && hscore->possibly_dynamic_relocs != 0
3112
0
      && (h->root.type == bfd_link_hash_defweak || !h->def_regular))
3113
0
    {
3114
0
      score_elf_allocate_dynamic_relocations (dynobj, hscore->possibly_dynamic_relocs);
3115
0
      if (hscore->readonly_reloc)
3116
  /* We tell the dynamic linker that there are relocations
3117
     against the text segment.  */
3118
0
  info->flags |= DF_TEXTREL;
3119
0
    }
3120
3121
  /* For a function, create a stub, if allowed.  */
3122
0
  if (!hscore->no_fn_stub && h->needs_plt)
3123
0
    {
3124
0
      if (!elf_hash_table (info)->dynamic_sections_created)
3125
0
  return true;
3126
3127
      /* If this symbol is not defined in a regular file, then set
3128
   the symbol to the stub location.  This is required to make
3129
   function pointers compare as equal between the normal
3130
   executable and the shared library.  */
3131
0
      if (!h->def_regular)
3132
0
  {
3133
    /* We need .stub section.  */
3134
0
    s = bfd_get_linker_section (dynobj, SCORE_ELF_STUB_SECTION_NAME);
3135
0
    BFD_ASSERT (s != NULL);
3136
3137
0
    h->root.u.def.section = s;
3138
0
    h->root.u.def.value = s->size;
3139
3140
    /* XXX Write this stub address somewhere.  */
3141
0
    h->plt.offset = s->size;
3142
3143
    /* Make room for this stub code.  */
3144
0
    s->size += SCORE_FUNCTION_STUB_SIZE;
3145
3146
    /* The last half word of the stub will be filled with the index
3147
       of this symbol in .dynsym section.  */
3148
0
    return true;
3149
0
  }
3150
0
    }
3151
0
  else if ((h->type == STT_FUNC) && !h->needs_plt)
3152
0
    {
3153
      /* This will set the entry for this symbol in the GOT to 0, and
3154
   the dynamic linker will take care of this.  */
3155
0
      h->root.u.def.value = 0;
3156
0
      return true;
3157
0
    }
3158
3159
  /* If this is a weak symbol, and there is a real definition, the
3160
     processor independent code will have arranged for us to see the
3161
     real definition first, and we can just use the same value.  */
3162
0
  if (h->is_weakalias)
3163
0
    {
3164
0
      struct elf_link_hash_entry *def = weakdef (h);
3165
0
      BFD_ASSERT (def->root.type == bfd_link_hash_defined);
3166
0
      h->root.u.def.section = def->root.u.def.section;
3167
0
      h->root.u.def.value = def->root.u.def.value;
3168
0
      return true;
3169
0
    }
3170
3171
  /* This is a reference to a symbol defined by a dynamic object which
3172
     is not a function.  */
3173
0
  return true;
3174
0
}
3175
3176
/* This function is called after all the input files have been read,
3177
   and the input sections have been assigned to output sections.  */
3178
static bool
3179
s3_bfd_score_elf_early_size_sections (bfd *output_bfd,
3180
              struct bfd_link_info *info)
3181
0
{
3182
0
  bfd *dynobj;
3183
0
  asection *s;
3184
0
  struct score_got_info *g;
3185
0
  int i;
3186
0
  bfd_size_type loadable_size = 0;
3187
0
  bfd_size_type local_gotno;
3188
0
  bfd *sub;
3189
3190
0
  dynobj = elf_hash_table (info)->dynobj;
3191
0
  if (dynobj == NULL)
3192
    /* Relocatable links don't have it.  */
3193
0
    return true;
3194
3195
0
  g = score_elf_got_info (dynobj, &s);
3196
0
  if (s == NULL)
3197
0
    return true;
3198
3199
  /* Calculate the total loadable size of the output.  That will give us the
3200
     maximum number of GOT_PAGE entries required.  */
3201
0
  for (sub = info->input_bfds; sub; sub = sub->link.next)
3202
0
    {
3203
0
      asection *subsection;
3204
3205
0
      for (subsection = sub->sections;
3206
0
     subsection;
3207
0
     subsection = subsection->next)
3208
0
  {
3209
0
    if ((subsection->flags & SEC_ALLOC) == 0)
3210
0
      continue;
3211
0
    loadable_size += ((subsection->size + 0xf)
3212
0
          &~ (bfd_size_type) 0xf);
3213
0
  }
3214
0
    }
3215
3216
  /* There has to be a global GOT entry for every symbol with
3217
     a dynamic symbol table index of DT_SCORE_GOTSYM or
3218
     higher.  Therefore, it make sense to put those symbols
3219
     that need GOT entries at the end of the symbol table.  We
3220
     do that here.  */
3221
0
  if (! score_elf_sort_hash_table (info, 1))
3222
0
    return false;
3223
3224
0
  if (g->global_gotsym != NULL)
3225
0
    i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx;
3226
0
  else
3227
    /* If there are no global symbols, or none requiring
3228
       relocations, then GLOBAL_GOTSYM will be NULL.  */
3229
0
    i = 0;
3230
3231
  /* In the worst case, we'll get one stub per dynamic symbol.  */
3232
0
  loadable_size += SCORE_FUNCTION_STUB_SIZE * i;
3233
3234
  /* Assume there are two loadable segments consisting of
3235
     contiguous sections.  Is 5 enough?  */
3236
0
  local_gotno = (loadable_size >> 16) + 5;
3237
3238
0
  g->local_gotno += local_gotno;
3239
0
  s->size += g->local_gotno * SCORE_ELF_GOT_SIZE (output_bfd);
3240
3241
0
  g->global_gotno = i;
3242
0
  s->size += i * SCORE_ELF_GOT_SIZE (output_bfd);
3243
3244
0
  score_elf_resolve_final_got_entries (g);
3245
3246
0
  if (s->size > SCORE_ELF_GOT_MAX_SIZE (output_bfd))
3247
0
    {
3248
      /* Fixme. Error message or Warning message should be issued here.  */
3249
0
    }
3250
3251
0
  return true;
3252
0
}
3253
3254
/* Set the sizes of the dynamic sections.  */
3255
static bool
3256
s3_bfd_score_elf_late_size_sections (bfd *output_bfd, struct bfd_link_info *info)
3257
0
{
3258
0
  bfd *dynobj;
3259
0
  asection *s;
3260
0
  bool reltext;
3261
3262
0
  dynobj = elf_hash_table (info)->dynobj;
3263
0
  if (dynobj == NULL)
3264
0
    return true;
3265
3266
0
  if (elf_hash_table (info)->dynamic_sections_created)
3267
0
    {
3268
      /* Set the contents of the .interp section to the interpreter.  */
3269
0
      if (bfd_link_executable (info) && !info->nointerp)
3270
0
  {
3271
0
    s = elf_hash_table (info)->interp;
3272
0
    BFD_ASSERT (s != NULL);
3273
0
    s->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
3274
0
    s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
3275
0
    s->alloced = 1;
3276
0
  }
3277
0
    }
3278
3279
  /* The check_relocs and adjust_dynamic_symbol entry points have
3280
     determined the sizes of the various dynamic sections.  Allocate
3281
     memory for them.  */
3282
0
  reltext = false;
3283
0
  for (s = dynobj->sections; s != NULL; s = s->next)
3284
0
    {
3285
0
      const char *name;
3286
3287
0
      if ((s->flags & SEC_LINKER_CREATED) == 0)
3288
0
  continue;
3289
3290
      /* It's OK to base decisions on the section name, because none
3291
   of the dynobj section names depend upon the input files.  */
3292
0
      name = bfd_section_name (s);
3293
3294
0
      if (startswith (name, ".rel"))
3295
0
  {
3296
0
    if (s->size == 0)
3297
0
      {
3298
        /* We only strip the section if the output section name
3299
     has the same name.  Otherwise, there might be several
3300
     input sections for this output section.  FIXME: This
3301
     code is probably not needed these days anyhow, since
3302
     the linker now does not create empty output sections.  */
3303
0
        if (s->output_section != NULL
3304
0
      && strcmp (name,
3305
0
           bfd_section_name (s->output_section)) == 0)
3306
0
    s->flags |= SEC_EXCLUDE;
3307
0
      }
3308
0
    else
3309
0
      {
3310
0
        const char *outname;
3311
0
        asection *target;
3312
3313
        /* If this relocation section applies to a read only
3314
     section, then we probably need a DT_TEXTREL entry.
3315
     If the relocation section is .rel.dyn, we always
3316
     assert a DT_TEXTREL entry rather than testing whether
3317
     there exists a relocation to a read only section or
3318
     not.  */
3319
0
        outname = bfd_section_name (s->output_section);
3320
0
        target = bfd_get_section_by_name (output_bfd, outname + 4);
3321
0
        if ((target != NULL
3322
0
       && (target->flags & SEC_READONLY) != 0
3323
0
       && (target->flags & SEC_ALLOC) != 0) || strcmp (outname, ".rel.dyn") == 0)
3324
0
    reltext = true;
3325
3326
        /* We use the reloc_count field as a counter if we need
3327
     to copy relocs into the output file.  */
3328
0
        if (strcmp (name, ".rel.dyn") != 0)
3329
0
    s->reloc_count = 0;
3330
0
      }
3331
0
  }
3332
0
      else if (startswith (name, ".got"))
3333
0
  {
3334
    /* s3_bfd_score_elf_early_size_sections() has already done
3335
       most of the work, but some symbols may have been mapped
3336
       to versions that we must now resolve in the got_entries
3337
       hash tables.  */
3338
0
  }
3339
0
      else if (strcmp (name, SCORE_ELF_STUB_SECTION_NAME) == 0)
3340
0
  {
3341
    /* IRIX rld assumes that the function stub isn't at the end
3342
       of .text section. So put a dummy. XXX  */
3343
0
    s->size += SCORE_FUNCTION_STUB_SIZE;
3344
0
  }
3345
0
      else if (! startswith (name, ".init"))
3346
0
  {
3347
    /* It's not one of our sections, so don't allocate space.  */
3348
0
    continue;
3349
0
  }
3350
3351
      /* Allocate memory for the section contents.  */
3352
0
      s->contents = bfd_zalloc (dynobj, s->size);
3353
0
      if (s->contents == NULL && s->size != 0)
3354
0
  {
3355
0
    bfd_set_error (bfd_error_no_memory);
3356
0
    return false;
3357
0
  }
3358
0
      s->alloced = 1;
3359
0
    }
3360
3361
0
  if (elf_hash_table (info)->dynamic_sections_created)
3362
0
    {
3363
      /* Add some entries to the .dynamic section.  We fill in the
3364
   values later, in s3_bfd_score_elf_finish_dynamic_sections, but we
3365
   must add the entries now so that we get the correct size for
3366
   the .dynamic section.  The DT_DEBUG entry is filled in by the
3367
   dynamic linker and used by the debugger.  */
3368
3369
0
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0))
3370
0
  return false;
3371
3372
0
      if (reltext)
3373
0
  info->flags |= DF_TEXTREL;
3374
3375
0
      if ((info->flags & DF_TEXTREL) != 0)
3376
0
  {
3377
0
    if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0))
3378
0
      return false;
3379
0
  }
3380
3381
0
      if (! SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTGOT, 0))
3382
0
  return false;
3383
3384
0
      if (score_elf_rel_dyn_section (dynobj, false))
3385
0
  {
3386
0
    if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_REL, 0))
3387
0
      return false;
3388
3389
0
    if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELSZ, 0))
3390
0
      return false;
3391
3392
0
    if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELENT, 0))
3393
0
      return false;
3394
0
  }
3395
3396
0
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_BASE_ADDRESS, 0))
3397
0
  return false;
3398
3399
0
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_LOCAL_GOTNO, 0))
3400
0
  return false;
3401
3402
0
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_SYMTABNO, 0))
3403
0
  return false;
3404
3405
0
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_UNREFEXTNO, 0))
3406
0
  return false;
3407
3408
0
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_GOTSYM, 0))
3409
0
  return false;
3410
3411
0
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_HIPAGENO, 0))
3412
0
  return false;
3413
0
    }
3414
3415
0
  return true;
3416
0
}
3417
3418
static bool
3419
s3_bfd_score_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
3420
0
{
3421
0
  struct elf_link_hash_entry *h;
3422
0
  struct bfd_link_hash_entry *bh;
3423
0
  flagword flags;
3424
0
  asection *s;
3425
3426
0
  flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
3427
0
     | SEC_LINKER_CREATED | SEC_READONLY);
3428
3429
  /* ABI requests the .dynamic section to be read only.  */
3430
0
  s = bfd_get_linker_section (abfd, ".dynamic");
3431
0
  if (s != NULL)
3432
0
    {
3433
0
      if (!bfd_set_section_flags (s, flags))
3434
0
  return false;
3435
0
    }
3436
3437
  /* We need to create .got section.  */
3438
0
  if (!score_elf_create_got_section (abfd, info, false))
3439
0
    return false;
3440
3441
0
  if (!score_elf_rel_dyn_section (elf_hash_table (info)->dynobj, true))
3442
0
    return false;
3443
3444
  /* Create .stub section.  */
3445
0
  if (bfd_get_linker_section (abfd, SCORE_ELF_STUB_SECTION_NAME) == NULL)
3446
0
    {
3447
0
      s = bfd_make_section_anyway_with_flags (abfd, SCORE_ELF_STUB_SECTION_NAME,
3448
0
                flags | SEC_CODE);
3449
0
      if (s == NULL
3450
0
    || !bfd_set_section_alignment (s, 2))
3451
3452
0
  return false;
3453
0
    }
3454
3455
0
  if (!bfd_link_pic (info))
3456
0
    {
3457
0
      const char *name;
3458
3459
0
      name = "_DYNAMIC_LINK";
3460
0
      bh = NULL;
3461
0
      if (!(_bfd_generic_link_add_one_symbol
3462
0
      (info, abfd, name, BSF_GLOBAL, bfd_abs_section_ptr,
3463
0
       (bfd_vma) 0, NULL, false, get_elf_backend_data (abfd)->collect, &bh)))
3464
0
  return false;
3465
3466
0
      h = (struct elf_link_hash_entry *)bh;
3467
0
      h->non_elf = 0;
3468
0
      h->def_regular = 1;
3469
0
      h->type = STT_SECTION;
3470
3471
0
      if (!bfd_elf_link_record_dynamic_symbol (info, h))
3472
0
  return false;
3473
0
    }
3474
3475
0
  return true;
3476
0
}
3477
3478
3479
/* Finish up dynamic symbol handling.  We set the contents of various
3480
   dynamic sections here.  */
3481
static bool
3482
s3_bfd_score_elf_finish_dynamic_symbol (bfd *output_bfd,
3483
          struct bfd_link_info *info,
3484
          struct elf_link_hash_entry *h,
3485
          Elf_Internal_Sym *sym)
3486
0
{
3487
0
  bfd *dynobj;
3488
0
  asection *sgot;
3489
0
  struct score_got_info *g;
3490
0
  const char *name;
3491
3492
0
  dynobj = elf_hash_table (info)->dynobj;
3493
3494
0
  if (h->plt.offset != MINUS_ONE)
3495
0
    {
3496
0
      asection *s;
3497
0
      bfd_byte stub[SCORE_FUNCTION_STUB_SIZE];
3498
3499
      /* This symbol has a stub.  Set it up.  */
3500
0
      BFD_ASSERT (h->dynindx != -1);
3501
3502
0
      s = bfd_get_linker_section (dynobj, SCORE_ELF_STUB_SECTION_NAME);
3503
0
      BFD_ASSERT (s != NULL);
3504
3505
      /* FIXME: Can h->dynindex be more than 64K?  */
3506
0
      if (h->dynindx & 0xffff0000)
3507
0
  {
3508
0
    _bfd_error_handler
3509
0
      (_("%pB: cannot handle more than %d dynamic symbols"),
3510
0
       output_bfd, 0xffff);
3511
0
    bfd_set_error (bfd_error_bad_value);
3512
0
    return false;
3513
0
  }
3514
3515
      /* Fill the stub.  */
3516
0
      score_bfd_put_32 (output_bfd, STUB_LW, stub);
3517
0
      score_bfd_put_32 (output_bfd, STUB_MOVE, stub + 4);
3518
0
      score_bfd_put_32 (output_bfd, STUB_LI16 | (h->dynindx << 1), stub + 8);
3519
0
      score_bfd_put_32 (output_bfd, STUB_BRL, stub + 12);
3520
3521
0
      BFD_ASSERT (h->plt.offset <= s->size);
3522
0
      memcpy (s->contents + h->plt.offset, stub, SCORE_FUNCTION_STUB_SIZE);
3523
3524
      /* Mark the symbol as undefined.  plt.offset != -1 occurs
3525
   only for the referenced symbol.  */
3526
0
      sym->st_shndx = SHN_UNDEF;
3527
3528
      /* The run-time linker uses the st_value field of the symbol
3529
    to reset the global offset table entry for this external
3530
    to its stub address when unlinking a shared object.  */
3531
0
      sym->st_value = (s->output_section->vma + s->output_offset + h->plt.offset);
3532
0
    }
3533
3534
0
  BFD_ASSERT (h->dynindx != -1 || h->forced_local);
3535
3536
0
  sgot = score_elf_got_section (dynobj, false);
3537
0
  BFD_ASSERT (sgot != NULL);
3538
0
  BFD_ASSERT (score_elf_section_data (sgot) != NULL);
3539
0
  g = score_elf_section_data (sgot)->u.got_info;
3540
0
  BFD_ASSERT (g != NULL);
3541
3542
  /* Run through the global symbol table, creating GOT entries for all
3543
     the symbols that need them.  */
3544
0
  if (g->global_gotsym != NULL && h->dynindx >= g->global_gotsym->dynindx)
3545
0
    {
3546
0
      bfd_vma offset;
3547
0
      bfd_vma value;
3548
3549
0
      value = sym->st_value;
3550
0
      offset = score_elf_global_got_index (dynobj, h);
3551
0
      score_bfd_put_32 (output_bfd, value, sgot->contents + offset);
3552
0
    }
3553
3554
  /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
3555
0
  name = h->root.root.string;
3556
0
  if (h == elf_hash_table (info)->hdynamic
3557
0
      || h == elf_hash_table (info)->hgot)
3558
0
    sym->st_shndx = SHN_ABS;
3559
0
  else if (strcmp (name, "_DYNAMIC_LINK") == 0)
3560
0
    {
3561
0
      sym->st_shndx = SHN_ABS;
3562
0
      sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
3563
0
      sym->st_value = 1;
3564
0
    }
3565
0
  else if (strcmp (name, GP_DISP_LABEL) == 0)
3566
0
    {
3567
0
      sym->st_shndx = SHN_ABS;
3568
0
      sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
3569
0
      sym->st_value = elf_gp (output_bfd);
3570
0
    }
3571
3572
0
  return true;
3573
0
}
3574
3575
/* Finish up the dynamic sections.  */
3576
static bool
3577
s3_bfd_score_elf_finish_dynamic_sections (bfd *output_bfd,
3578
            struct bfd_link_info *info,
3579
            bfd_byte *buf ATTRIBUTE_UNUSED)
3580
0
{
3581
0
  bfd *dynobj;
3582
0
  asection *sdyn;
3583
0
  asection *sgot;
3584
0
  asection *s;
3585
0
  struct score_got_info *g;
3586
3587
0
  dynobj = elf_hash_table (info)->dynobj;
3588
3589
0
  sdyn = bfd_get_linker_section (dynobj, ".dynamic");
3590
3591
0
  sgot = score_elf_got_section (dynobj, false);
3592
0
  if (sgot == NULL)
3593
0
    g = NULL;
3594
0
  else
3595
0
    {
3596
0
      BFD_ASSERT (score_elf_section_data (sgot) != NULL);
3597
0
      g = score_elf_section_data (sgot)->u.got_info;
3598
0
      BFD_ASSERT (g != NULL);
3599
0
    }
3600
3601
0
  if (elf_hash_table (info)->dynamic_sections_created)
3602
0
    {
3603
0
      bfd_byte *b;
3604
3605
0
      BFD_ASSERT (sdyn != NULL);
3606
0
      BFD_ASSERT (g != NULL);
3607
3608
0
      for (b = sdyn->contents;
3609
0
     b < sdyn->contents + sdyn->size;
3610
0
     b += SCORE_ELF_DYN_SIZE (dynobj))
3611
0
  {
3612
0
    Elf_Internal_Dyn dyn;
3613
0
    const char *name;
3614
0
    size_t elemsize;
3615
0
    bool swap_out_p;
3616
3617
    /* Read in the current dynamic entry.  */
3618
0
    (*get_elf_backend_data (dynobj)->s->swap_dyn_in) (dynobj, b, &dyn);
3619
3620
    /* Assume that we're going to modify it and write it out.  */
3621
0
    swap_out_p = true;
3622
3623
0
    switch (dyn.d_tag)
3624
0
      {
3625
0
      case DT_RELENT:
3626
0
        dyn.d_un.d_val = SCORE_ELF_REL_SIZE (dynobj);
3627
0
        break;
3628
3629
0
      case DT_STRSZ:
3630
        /* Rewrite DT_STRSZ.  */
3631
0
        dyn.d_un.d_val
3632
0
    = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
3633
0
        break;
3634
3635
0
      case DT_PLTGOT:
3636
0
        s = elf_hash_table (info)->sgot;
3637
0
        dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
3638
0
        break;
3639
3640
0
      case DT_SCORE_BASE_ADDRESS:
3641
0
        s = output_bfd->sections;
3642
0
        BFD_ASSERT (s != NULL);
3643
0
        dyn.d_un.d_ptr = s->vma & ~(bfd_vma) 0xffff;
3644
0
        break;
3645
3646
0
      case DT_SCORE_LOCAL_GOTNO:
3647
0
        dyn.d_un.d_val = g->local_gotno;
3648
0
        break;
3649
3650
0
      case DT_SCORE_UNREFEXTNO:
3651
        /* The index into the dynamic symbol table which is the
3652
     entry of the first external symbol that is not
3653
     referenced within the same object.  */
3654
0
        dyn.d_un.d_val = bfd_count_sections (output_bfd) + 1;
3655
0
        break;
3656
3657
0
      case DT_SCORE_GOTSYM:
3658
0
        if (g->global_gotsym)
3659
0
    {
3660
0
      dyn.d_un.d_val = g->global_gotsym->dynindx;
3661
0
      break;
3662
0
    }
3663
        /* In case if we don't have global got symbols we default
3664
      to setting DT_SCORE_GOTSYM to the same value as
3665
      DT_SCORE_SYMTABNO.  */
3666
        /* Fall through.  */
3667
3668
0
      case DT_SCORE_SYMTABNO:
3669
0
        name = ".dynsym";
3670
0
        elemsize = SCORE_ELF_SYM_SIZE (output_bfd);
3671
0
        s = bfd_get_linker_section (dynobj, name);
3672
0
        dyn.d_un.d_val = s->size / elemsize;
3673
0
        break;
3674
3675
0
      case DT_SCORE_HIPAGENO:
3676
0
        dyn.d_un.d_val = g->local_gotno - SCORE_RESERVED_GOTNO;
3677
0
        break;
3678
3679
0
      default:
3680
0
        swap_out_p = false;
3681
0
        break;
3682
0
      }
3683
3684
0
    if (swap_out_p)
3685
0
      (*get_elf_backend_data (dynobj)->s->swap_dyn_out) (dynobj, &dyn, b);
3686
0
  }
3687
0
    }
3688
3689
  /* The first entry of the global offset table will be filled at
3690
     runtime. The second entry will be used by some runtime loaders.
3691
     This isn't the case of IRIX rld.  */
3692
0
  if (sgot != NULL && sgot->size > 0)
3693
0
    {
3694
0
      score_bfd_put_32 (output_bfd, 0, sgot->contents);
3695
0
      score_bfd_put_32 (output_bfd, 0x80000000, sgot->contents + SCORE_ELF_GOT_SIZE (output_bfd));
3696
0
    }
3697
3698
0
  if (sgot != NULL)
3699
0
    elf_section_data (sgot->output_section)->this_hdr.sh_entsize
3700
0
      = SCORE_ELF_GOT_SIZE (output_bfd);
3701
3702
3703
  /* We need to sort the entries of the dynamic relocation section.  */
3704
0
  s = score_elf_rel_dyn_section (dynobj, false);
3705
3706
0
  if (s != NULL && s->size > (bfd_vma)2 * SCORE_ELF_REL_SIZE (output_bfd))
3707
0
    {
3708
0
      reldyn_sorting_bfd = output_bfd;
3709
0
      qsort ((Elf32_External_Rel *) s->contents + 1, s->reloc_count - 1,
3710
0
       sizeof (Elf32_External_Rel), score_elf_sort_dynamic_relocs);
3711
0
    }
3712
3713
0
  return true;
3714
0
}
3715
3716
/* This function set up the ELF section header for a BFD section in preparation for writing
3717
   it out.  This is where the flags and type fields are set for unusual sections.  */
3718
static bool
3719
s3_bfd_score_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
3720
        Elf_Internal_Shdr *hdr,
3721
        asection *sec)
3722
0
{
3723
0
  const char *name;
3724
3725
0
  name = bfd_section_name (sec);
3726
3727
0
  if (strcmp (name, ".got") == 0
3728
0
      || strcmp (name, ".srdata") == 0
3729
0
      || strcmp (name, ".sdata") == 0
3730
0
      || strcmp (name, ".sbss") == 0)
3731
0
    hdr->sh_flags |= SHF_SCORE_GPREL;
3732
3733
0
  return true;
3734
0
}
3735
3736
/* This function do additional processing on the ELF section header before writing
3737
   it out.  This is used to set the flags and type fields for some sections.  */
3738
3739
/* assign_file_positions_except_relocs() check section flag and if it is allocatable,
3740
   warning message will be issued.  backend_fake_section is called before
3741
   assign_file_positions_except_relocs(); backend_section_processing after it.  so, we
3742
   modify section flag there, but not backend_fake_section.  */
3743
static bool
3744
s3_bfd_score_elf_section_processing (bfd *abfd ATTRIBUTE_UNUSED, Elf_Internal_Shdr *hdr)
3745
0
{
3746
0
  if (hdr->bfd_section != NULL)
3747
0
    {
3748
0
      const char *name = bfd_section_name (hdr->bfd_section);
3749
3750
0
      if (strcmp (name, ".sdata") == 0)
3751
0
  {
3752
0
    hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
3753
0
    hdr->sh_type = SHT_PROGBITS;
3754
0
  }
3755
0
      else if (strcmp (name, ".sbss") == 0)
3756
0
  {
3757
0
    hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
3758
0
    hdr->sh_type = SHT_NOBITS;
3759
0
  }
3760
0
      else if (strcmp (name, ".srdata") == 0)
3761
0
  {
3762
0
    hdr->sh_flags |= SHF_ALLOC | SHF_SCORE_GPREL;
3763
0
    hdr->sh_type = SHT_PROGBITS;
3764
0
  }
3765
0
    }
3766
3767
0
  return true;
3768
0
}
3769
3770
static bool
3771
s3_bfd_score_elf_write_section (bfd *output_bfd, asection *sec, bfd_byte *contents)
3772
0
{
3773
0
  bfd_byte *to, *from, *end;
3774
0
  int i;
3775
3776
0
  if (strcmp (sec->name, ".pdr") != 0)
3777
0
    return false;
3778
3779
0
  if (score_elf_section_data (sec)->u.tdata == NULL)
3780
0
    return false;
3781
3782
0
  to = contents;
3783
0
  end = contents + sec->size;
3784
0
  for (from = contents, i = 0; from < end; from += PDR_SIZE, i++)
3785
0
    {
3786
0
      if ((score_elf_section_data (sec)->u.tdata)[i] == 1)
3787
0
  continue;
3788
3789
0
      if (to != from)
3790
0
  memcpy (to, from, PDR_SIZE);
3791
3792
0
      to += PDR_SIZE;
3793
0
    }
3794
0
  bfd_set_section_contents (output_bfd, sec->output_section, contents,
3795
0
          (file_ptr) sec->output_offset, sec->size);
3796
3797
0
  return true;
3798
0
}
3799
3800
/* Copy data from a SCORE ELF indirect symbol to its direct symbol, hiding the old
3801
   indirect symbol.  Process additional relocation information.  */
3802
static void
3803
s3_bfd_score_elf_copy_indirect_symbol (struct bfd_link_info *info,
3804
               struct elf_link_hash_entry *dir,
3805
               struct elf_link_hash_entry *ind)
3806
0
{
3807
0
  struct score_elf_link_hash_entry *dirscore, *indscore;
3808
3809
0
  _bfd_elf_link_hash_copy_indirect (info, dir, ind);
3810
3811
0
  if (ind->root.type != bfd_link_hash_indirect)
3812
0
    return;
3813
3814
0
  dirscore = (struct score_elf_link_hash_entry *) dir;
3815
0
  indscore = (struct score_elf_link_hash_entry *) ind;
3816
0
  dirscore->possibly_dynamic_relocs += indscore->possibly_dynamic_relocs;
3817
3818
0
  if (indscore->readonly_reloc)
3819
0
    dirscore->readonly_reloc = true;
3820
3821
0
  if (indscore->no_fn_stub)
3822
0
    dirscore->no_fn_stub = true;
3823
0
}
3824
3825
/* Remove information about discarded functions from other sections which mention them.  */
3826
static bool
3827
s3_bfd_score_elf_discard_info (bfd *abfd, struct elf_reloc_cookie *cookie,
3828
             struct bfd_link_info *info)
3829
0
{
3830
0
  asection *o;
3831
0
  bool ret = false;
3832
0
  unsigned char *tdata;
3833
0
  size_t i, skip;
3834
3835
0
  o = bfd_get_section_by_name (abfd, ".pdr");
3836
0
  if ((!o) || (o->size == 0) || (o->size % PDR_SIZE != 0)
3837
0
      || (o->output_section != NULL && bfd_is_abs_section (o->output_section)))
3838
0
    return false;
3839
3840
0
  tdata = bfd_zmalloc (o->size / PDR_SIZE);
3841
0
  if (!tdata)
3842
0
    return false;
3843
3844
0
  cookie->rels = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, info->keep_memory);
3845
0
  if (!cookie->rels)
3846
0
    {
3847
0
      free (tdata);
3848
0
      return false;
3849
0
    }
3850
3851
0
  cookie->rel = cookie->rels;
3852
0
  cookie->relend = cookie->rels + o->reloc_count;
3853
3854
0
  for (i = 0, skip = 0; i < o->size; i++)
3855
0
    {
3856
0
      if (bfd_elf_reloc_symbol_deleted_p (i * PDR_SIZE, cookie))
3857
0
  {
3858
0
    tdata[i] = 1;
3859
0
    skip++;
3860
0
  }
3861
0
    }
3862
3863
0
  if (skip != 0)
3864
0
    {
3865
0
      score_elf_section_data (o)->u.tdata = tdata;
3866
0
      o->size -= skip * PDR_SIZE;
3867
0
      ret = true;
3868
0
    }
3869
0
  else
3870
0
    free (tdata);
3871
3872
0
  if (!info->keep_memory)
3873
0
    free (cookie->rels);
3874
3875
0
  return ret;
3876
0
}
3877
3878
/* Signal that discard_info() has removed the discarded relocations for this section.  */
3879
static bool
3880
s3_bfd_score_elf_ignore_discarded_relocs (asection *sec)
3881
0
{
3882
0
  if (strcmp (sec->name, ".pdr") == 0)
3883
0
    return true;
3884
0
  return false;
3885
0
}
3886
3887
/* Return the section that should be marked against GC for a given
3888
   relocation.  */
3889
static asection *
3890
s3_bfd_score_elf_gc_mark_hook (asection *sec,
3891
             struct bfd_link_info *info,
3892
             struct elf_reloc_cookie *cookie,
3893
             struct elf_link_hash_entry *h,
3894
             unsigned int symndx)
3895
0
{
3896
0
  if (h != NULL)
3897
0
    switch (ELF32_R_TYPE (cookie->rel->r_info))
3898
0
      {
3899
0
      case R_SCORE_GNU_VTINHERIT:
3900
0
      case R_SCORE_GNU_VTENTRY:
3901
0
  return NULL;
3902
0
      }
3903
3904
0
  return _bfd_elf_gc_mark_hook (sec, info, cookie, h, symndx);
3905
0
}
3906
3907
/* Support for core dump NOTE sections.  */
3908
3909
static bool
3910
s3_bfd_score_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
3911
0
{
3912
0
  int offset;
3913
0
  unsigned int raw_size;
3914
3915
0
  switch (note->descsz)
3916
0
    {
3917
0
    default:
3918
0
      return false;
3919
3920
0
    case 148:          /* Linux/Score 32-bit.  */
3921
      /* pr_cursig */
3922
0
      elf_tdata (abfd)->core->signal
3923
0
  = score_bfd_get_16 (abfd, note->descdata + 12);
3924
3925
      /* pr_pid */
3926
0
      elf_tdata (abfd)->core->lwpid
3927
0
  = score_bfd_get_32 (abfd, note->descdata + 24);
3928
3929
      /* pr_reg */
3930
0
      offset = 72;
3931
0
      raw_size = 72;
3932
3933
0
      break;
3934
0
    }
3935
3936
  /* Make a ".reg/999" section.  */
3937
0
  return _bfd_elfcore_make_pseudosection (abfd, ".reg", raw_size,
3938
0
            note->descpos + offset);
3939
0
}
3940
3941
static bool
3942
s3_bfd_score_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
3943
0
{
3944
0
  switch (note->descsz)
3945
0
    {
3946
0
    default:
3947
0
      return false;
3948
3949
0
    case 124:          /* Linux/Score elf_prpsinfo.  */
3950
0
      elf_tdata (abfd)->core->program
3951
0
  = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
3952
0
      elf_tdata (abfd)->core->command
3953
0
  = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
3954
0
    }
3955
3956
  /* Note that for some reason, a spurious space is tacked
3957
     onto the end of the args in some (at least one anyway)
3958
     implementations, so strip it off if it exists.  */
3959
3960
0
  {
3961
0
    char *command = elf_tdata (abfd)->core->command;
3962
0
    int n = strlen (command);
3963
3964
0
    if (0 < n && command[n - 1] == ' ')
3965
0
      command[n - 1] = '\0';
3966
0
  }
3967
3968
0
  return true;
3969
0
}
3970
3971
3972
/* Score BFD functions.  */
3973
static reloc_howto_type *
3974
s3_elf32_score_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
3975
0
{
3976
0
  unsigned int i;
3977
3978
0
  for (i = 0; i < ARRAY_SIZE (elf32_score_reloc_map); i++)
3979
0
    if (elf32_score_reloc_map[i].bfd_reloc_val == code)
3980
0
      return &elf32_score_howto_table[elf32_score_reloc_map[i].elf_reloc_val];
3981
3982
0
  return NULL;
3983
0
}
3984
3985
static reloc_howto_type *
3986
elf32_score_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
3987
             const char *r_name)
3988
0
{
3989
0
  unsigned int i;
3990
3991
0
  for (i = 0;
3992
0
       i < (sizeof (elf32_score_howto_table)
3993
0
      / sizeof (elf32_score_howto_table[0]));
3994
0
       i++)
3995
0
    if (elf32_score_howto_table[i].name != NULL
3996
0
  && strcasecmp (elf32_score_howto_table[i].name, r_name) == 0)
3997
0
      return &elf32_score_howto_table[i];
3998
3999
0
  return NULL;
4000
0
}
4001
4002
static bool
4003
s3_elf32_score_print_private_bfd_data (bfd *abfd, void * ptr)
4004
47
{
4005
47
  FILE *file = (FILE *) ptr;
4006
4007
47
  BFD_ASSERT (abfd != NULL && ptr != NULL);
4008
4009
  /* Print normal ELF private data.  */
4010
47
  _bfd_elf_print_private_bfd_data (abfd, ptr);
4011
4012
  /* xgettext:c-format */
4013
47
  fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
4014
47
  if (elf_elfheader (abfd)->e_flags & EF_SCORE_PIC)
4015
1
    {
4016
1
      fprintf (file, _(" [pic]"));
4017
1
    }
4018
47
  if (elf_elfheader (abfd)->e_flags & EF_SCORE_FIXDEP)
4019
0
    {
4020
0
      fprintf (file, _(" [fix dep]"));
4021
0
    }
4022
47
  fputc ('\n', file);
4023
4024
47
  return true;
4025
47
}
4026
4027
static bool
4028
s3_elf32_score_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
4029
0
{
4030
0
  bfd *obfd = info->output_bfd;
4031
0
  flagword in_flags;
4032
0
  flagword out_flags;
4033
4034
0
  if (!_bfd_generic_verify_endian_match (ibfd, info))
4035
0
    return false;
4036
4037
  /* FIXME: What should be checked when linking shared libraries?  */
4038
0
  if ((ibfd->flags & DYNAMIC) != 0)
4039
0
    return true;
4040
4041
0
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
4042
0
    return true;
4043
4044
0
  in_flags  = elf_elfheader (ibfd)->e_flags;
4045
0
  out_flags = elf_elfheader (obfd)->e_flags;
4046
4047
0
  in_flags = elf_elfheader (ibfd)->e_flags;
4048
0
  out_flags = elf_elfheader (obfd)->e_flags;
4049
4050
0
  if (! elf_flags_init (obfd))
4051
0
    {
4052
0
      elf_flags_init (obfd) = true;
4053
0
      elf_elfheader (obfd)->e_flags = in_flags;
4054
4055
0
      if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
4056
0
    && bfd_get_arch_info (obfd)->the_default)
4057
0
  {
4058
0
    return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
4059
0
  }
4060
4061
0
      return true;
4062
0
    }
4063
4064
0
  if (((in_flags & EF_SCORE_PIC) != 0) != ((out_flags & EF_SCORE_PIC) != 0))
4065
0
    _bfd_error_handler
4066
0
      (_("%pB: warning: linking PIC files with non-PIC files"), ibfd);
4067
4068
  /* FIXME: Maybe dependency fix compatibility should be checked here.  */
4069
4070
0
  return true;
4071
0
}
4072
4073
static bool
4074
s3_elf32_score_new_section_hook (bfd *abfd, asection *sec)
4075
27.6k
{
4076
27.6k
  struct _score_elf_section_data *sdata;
4077
4078
27.6k
  sdata = bfd_zalloc (abfd, sizeof (*sdata));
4079
27.6k
  if (sdata == NULL)
4080
0
    return false;
4081
27.6k
  sec->used_by_bfd = sdata;
4082
4083
27.6k
  return _bfd_elf_new_section_hook (abfd, sec);
4084
27.6k
}
4085
4086
/*****************************************************************************/
4087
4088
/* s3_s7: backend hooks.  */
4089
static bool
4090
_bfd_score_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
4091
        arelent *bfd_reloc,
4092
        Elf_Internal_Rela *elf_reloc)
4093
136
{
4094
136
  if (bfd_get_mach (abfd) == bfd_mach_score3)
4095
0
    return s3_bfd_score_info_to_howto (abfd, bfd_reloc, elf_reloc);
4096
136
  else
4097
136
    return s7_bfd_score_info_to_howto (abfd, bfd_reloc, elf_reloc);
4098
136
}
4099
4100
static int
4101
_bfd_score_elf_relocate_section (bfd *output_bfd,
4102
         struct bfd_link_info *info,
4103
         bfd *input_bfd,
4104
         asection *input_section,
4105
         bfd_byte *contents,
4106
         Elf_Internal_Rela *relocs,
4107
         Elf_Internal_Sym *local_syms,
4108
         asection **local_sections)
4109
0
{
4110
0
  if (bfd_get_mach (output_bfd) == bfd_mach_score3)
4111
0
    return s3_bfd_score_elf_relocate_section (output_bfd,
4112
0
       info, input_bfd, input_section, contents, relocs,
4113
0
       local_syms, local_sections);
4114
0
  else
4115
0
    return s7_bfd_score_elf_relocate_section (output_bfd,
4116
0
       info, input_bfd, input_section, contents, relocs,
4117
0
       local_syms, local_sections);
4118
0
}
4119
4120
static bool
4121
_bfd_score_elf_check_relocs (bfd *abfd,
4122
           struct bfd_link_info *info,
4123
           asection *sec,
4124
           const Elf_Internal_Rela *relocs)
4125
0
{
4126
0
  if (bfd_get_mach (abfd) == bfd_mach_score3)
4127
0
    return s3_bfd_score_elf_check_relocs (abfd, info, sec, relocs);
4128
0
  else
4129
0
    return s7_bfd_score_elf_check_relocs (abfd, info, sec, relocs);
4130
0
}
4131
4132
static bool
4133
_bfd_score_elf_add_symbol_hook (bfd *abfd,
4134
        struct bfd_link_info *info ATTRIBUTE_UNUSED,
4135
        Elf_Internal_Sym *sym,
4136
        const char **namep ATTRIBUTE_UNUSED,
4137
        flagword *flagsp ATTRIBUTE_UNUSED,
4138
        asection **secp,
4139
        bfd_vma *valp)
4140
0
{
4141
0
  if (bfd_get_mach (abfd) == bfd_mach_score3)
4142
0
    return s3_bfd_score_elf_add_symbol_hook (abfd, info, sym, namep, flagsp,
4143
0
               secp, valp);
4144
0
  else
4145
0
    return s7_bfd_score_elf_add_symbol_hook (abfd, info, sym, namep, flagsp,
4146
0
               secp, valp);
4147
0
}
4148
4149
static void
4150
_bfd_score_elf_symbol_processing (bfd *abfd, asymbol *asym)
4151
285
{
4152
285
  if (bfd_get_mach (abfd) == bfd_mach_score3)
4153
0
    return s3_bfd_score_elf_symbol_processing (abfd, asym);
4154
285
  else
4155
285
    return s7_bfd_score_elf_symbol_processing (abfd, asym);
4156
285
}
4157
4158
static int
4159
_bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
4160
     const char *name ATTRIBUTE_UNUSED,
4161
     Elf_Internal_Sym *sym,
4162
     asection *input_sec,
4163
     struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
4164
0
{
4165
  /* If link a empty .o, then this filed is NULL.  */
4166
0
  if (info->input_bfds == NULL)
4167
0
    {
4168
      /* If we see a common symbol, which implies a relocatable link, then
4169
   if a symbol was small common in an input file, mark it as small
4170
   common in the output file.  */
4171
0
      if (sym->st_shndx == SHN_COMMON && strcmp (input_sec->name, ".scommon") == 0)
4172
0
  sym->st_shndx = SHN_SCORE_SCOMMON;
4173
0
      return 1;
4174
0
    }
4175
4176
0
  if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
4177
0
    return s3_bfd_score_elf_link_output_symbol_hook (info, name, sym, input_sec, h);
4178
0
  else
4179
0
    return s7_bfd_score_elf_link_output_symbol_hook (info, name, sym, input_sec, h);
4180
0
}
4181
4182
static bool
4183
_bfd_score_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
4184
           asection *sec,
4185
           int *retval)
4186
0
{
4187
0
  if (bfd_get_mach (abfd) == bfd_mach_score3)
4188
0
    return s3_bfd_score_elf_section_from_bfd_section (abfd, sec, retval);
4189
0
  else
4190
0
    return s7_bfd_score_elf_section_from_bfd_section (abfd, sec, retval);
4191
0
}
4192
4193
static bool
4194
_bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
4195
              struct elf_link_hash_entry *h)
4196
0
{
4197
0
  if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
4198
0
    return s3_bfd_score_elf_adjust_dynamic_symbol (info, h);
4199
0
  else
4200
0
    return s7_bfd_score_elf_adjust_dynamic_symbol (info, h);
4201
0
}
4202
4203
static bool
4204
_bfd_score_elf_early_size_sections (bfd *output_bfd,
4205
            struct bfd_link_info *info)
4206
0
{
4207
0
  if (bfd_get_mach (output_bfd) == bfd_mach_score3)
4208
0
    return s3_bfd_score_elf_early_size_sections (output_bfd, info);
4209
0
  else
4210
0
    return s7_bfd_score_elf_early_size_sections (output_bfd, info);
4211
0
}
4212
4213
static bool
4214
_bfd_score_elf_late_size_sections (bfd *output_bfd, struct bfd_link_info *info)
4215
0
{
4216
0
  if (bfd_get_mach (output_bfd) == bfd_mach_score3)
4217
0
    return s3_bfd_score_elf_late_size_sections (output_bfd, info);
4218
0
  else
4219
0
    return s7_bfd_score_elf_late_size_sections (output_bfd, info);
4220
0
}
4221
4222
static bool
4223
_bfd_score_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
4224
0
{
4225
0
  if (bfd_get_mach (abfd) == bfd_mach_score3)
4226
0
    return s3_bfd_score_elf_create_dynamic_sections (abfd, info);
4227
0
  else
4228
0
    return s7_bfd_score_elf_create_dynamic_sections (abfd, info);
4229
0
}
4230
4231
static bool
4232
_bfd_score_elf_finish_dynamic_symbol (bfd *output_bfd,
4233
              struct bfd_link_info *info,
4234
              struct elf_link_hash_entry *h,
4235
              Elf_Internal_Sym *sym)
4236
0
{
4237
0
  if (bfd_get_mach (output_bfd) == bfd_mach_score3)
4238
0
    return s3_bfd_score_elf_finish_dynamic_symbol (output_bfd, info, h, sym);
4239
0
  else
4240
0
    return s7_bfd_score_elf_finish_dynamic_symbol (output_bfd, info, h, sym);
4241
0
}
4242
4243
static bool
4244
_bfd_score_elf_finish_dynamic_sections (bfd *output_bfd,
4245
          struct bfd_link_info *info,
4246
          bfd_byte *buf)
4247
0
{
4248
0
  if (bfd_get_mach (output_bfd) == bfd_mach_score3)
4249
0
    return s3_bfd_score_elf_finish_dynamic_sections (output_bfd, info, buf);
4250
0
  else
4251
0
    return s7_bfd_score_elf_finish_dynamic_sections (output_bfd, info, buf);
4252
0
}
4253
4254
static bool
4255
_bfd_score_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
4256
            Elf_Internal_Shdr *hdr,
4257
            asection *sec)
4258
0
{
4259
0
  if (bfd_get_mach (abfd) == bfd_mach_score3)
4260
0
    return s3_bfd_score_elf_fake_sections (abfd, hdr, sec);
4261
0
  else
4262
0
    return s7_bfd_score_elf_fake_sections (abfd, hdr, sec);
4263
0
}
4264
4265
static bool
4266
_bfd_score_elf_section_processing (bfd *abfd ATTRIBUTE_UNUSED, Elf_Internal_Shdr *hdr)
4267
0
{
4268
0
  if (bfd_get_mach (abfd) == bfd_mach_score3)
4269
0
    return s3_bfd_score_elf_section_processing (abfd, hdr);
4270
0
  else
4271
0
    return s7_bfd_score_elf_section_processing (abfd, hdr);
4272
0
}
4273
4274
static bool
4275
_bfd_score_elf_write_section (bfd *output_bfd,
4276
            struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
4277
            asection *sec, bfd_byte *contents)
4278
0
{
4279
0
  if (bfd_get_mach (output_bfd) == bfd_mach_score3)
4280
0
    return s3_bfd_score_elf_write_section (output_bfd, sec, contents);
4281
0
  else
4282
0
    return s7_bfd_score_elf_write_section (output_bfd, sec, contents);
4283
0
}
4284
4285
static void
4286
_bfd_score_elf_copy_indirect_symbol (struct bfd_link_info *info,
4287
             struct elf_link_hash_entry *dir,
4288
             struct elf_link_hash_entry *ind)
4289
0
{
4290
0
  if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
4291
0
    return s3_bfd_score_elf_copy_indirect_symbol (info, dir, ind);
4292
0
  else
4293
0
    return s7_bfd_score_elf_copy_indirect_symbol (info, dir, ind);
4294
0
}
4295
4296
static void
4297
_bfd_score_elf_hide_symbol (struct bfd_link_info *info,
4298
          struct elf_link_hash_entry *entry,
4299
          bool force_local)
4300
0
{
4301
0
  if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
4302
0
    return s3_bfd_score_elf_hide_symbol (info, entry, force_local);
4303
0
  else
4304
0
    return s7_bfd_score_elf_hide_symbol (info, entry, force_local);
4305
0
}
4306
4307
static bool
4308
_bfd_score_elf_discard_info (bfd *abfd, struct elf_reloc_cookie *cookie,
4309
       struct bfd_link_info *info)
4310
0
{
4311
0
  if (bfd_get_mach (abfd) == bfd_mach_score3)
4312
0
    return s3_bfd_score_elf_discard_info (abfd, cookie, info);
4313
0
  else
4314
0
    return s7_bfd_score_elf_discard_info (abfd, cookie, info);
4315
0
}
4316
4317
static bool
4318
_bfd_score_elf_ignore_discarded_relocs (asection *sec)
4319
0
{
4320
0
  if (bfd_get_mach (sec->owner) == bfd_mach_score3)
4321
0
    return s3_bfd_score_elf_ignore_discarded_relocs (sec);
4322
0
  else
4323
0
    return s7_bfd_score_elf_ignore_discarded_relocs (sec);
4324
0
}
4325
4326
static asection *
4327
_bfd_score_elf_gc_mark_hook (asection *sec,
4328
           struct bfd_link_info *info,
4329
           struct elf_reloc_cookie *cookie,
4330
           struct elf_link_hash_entry *h,
4331
           unsigned int symndx)
4332
0
{
4333
0
  if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
4334
0
    return s3_bfd_score_elf_gc_mark_hook (sec, info, cookie, h, symndx);
4335
0
  else
4336
0
    return s7_bfd_score_elf_gc_mark_hook (sec, info, cookie, h, symndx);
4337
0
}
4338
4339
static bool
4340
_bfd_score_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
4341
0
{
4342
0
  if (bfd_get_mach (abfd) == bfd_mach_score3)
4343
0
    return s3_bfd_score_elf_grok_prstatus (abfd, note);
4344
0
  else
4345
0
    return s7_bfd_score_elf_grok_prstatus (abfd, note);
4346
0
}
4347
4348
static bool
4349
_bfd_score_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
4350
0
{
4351
0
  if (bfd_get_mach (abfd) == bfd_mach_score3)
4352
0
    return s3_bfd_score_elf_grok_psinfo (abfd, note);
4353
0
  else
4354
0
    return s7_bfd_score_elf_grok_psinfo (abfd, note);
4355
0
}
4356
4357
static reloc_howto_type *
4358
elf32_score_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
4359
0
{
4360
  /* s3: NOTE!!!
4361
     gas will call elf32_score_reloc_type_lookup, and don't write elf file.
4362
     So just using score3, but we don't know ld will call this or not.
4363
     If so, this way can't work.  */
4364
4365
0
  if (score3)
4366
0
    return s3_elf32_score_reloc_type_lookup (abfd, code);
4367
0
  else
4368
0
    return s7_elf32_score_reloc_type_lookup (abfd, code);
4369
0
}
4370
4371
/* Create a score elf linker hash table.
4372
   This is a copy of _bfd_elf_link_hash_table_create() except with a
4373
   different hash table entry creation function.  */
4374
4375
static struct bfd_link_hash_table *
4376
elf32_score_link_hash_table_create (bfd *abfd)
4377
0
{
4378
0
  struct elf_link_hash_table *ret;
4379
0
  size_t amt = sizeof (struct elf_link_hash_table);
4380
4381
0
  ret = (struct elf_link_hash_table *) bfd_zmalloc (amt);
4382
0
  if (ret == NULL)
4383
0
    return NULL;
4384
4385
0
  if (!_bfd_elf_link_hash_table_init (ret, abfd, score_elf_link_hash_newfunc,
4386
0
              sizeof (struct score_elf_link_hash_entry)))
4387
0
    {
4388
0
      free (ret);
4389
0
      return NULL;
4390
0
    }
4391
4392
0
  return &ret->root;
4393
0
}
4394
4395
static bool
4396
elf32_score_print_private_bfd_data (bfd *abfd, void * ptr)
4397
84
{
4398
84
  if (bfd_get_mach (abfd) == bfd_mach_score3)
4399
47
    return s3_elf32_score_print_private_bfd_data (abfd, ptr);
4400
37
  else
4401
37
    return s7_elf32_score_print_private_bfd_data (abfd, ptr);
4402
84
}
4403
4404
static bool
4405
elf32_score_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
4406
0
{
4407
0
  if (bfd_get_mach (info->output_bfd) == bfd_mach_score3)
4408
0
    return s3_elf32_score_merge_private_bfd_data (ibfd, info);
4409
0
  else
4410
0
    return s7_elf32_score_merge_private_bfd_data (ibfd, info);
4411
0
}
4412
4413
static bool
4414
elf32_score_new_section_hook (bfd *abfd, asection *sec)
4415
35.1k
{
4416
35.1k
  if (bfd_get_mach (abfd) == bfd_mach_score3)
4417
27.6k
    return s3_elf32_score_new_section_hook (abfd, sec);
4418
7.52k
  else
4419
7.52k
    return s7_elf32_score_new_section_hook (abfd, sec);
4420
35.1k
}
4421
4422
4423
/* s3_s7: don't need to split.  */
4424
4425
/* Set the right machine number.  */
4426
static bool
4427
_bfd_score_elf_score_object_p (bfd * abfd)
4428
244
{
4429
244
  int e_set = bfd_mach_score7;
4430
4431
244
  if (elf_elfheader (abfd)->e_machine == EM_SCORE)
4432
136
    {
4433
136
      int e_mach = elf_elfheader (abfd)->e_flags & EF_SCORE_MACH & EF_OMIT_PIC_FIXDD;
4434
136
      switch (e_mach)
4435
136
  {
4436
  /* Set default target is score7.  */
4437
36
  default:
4438
36
  case E_SCORE_MACH_SCORE7:
4439
36
    e_set = bfd_mach_score7;
4440
36
    break;
4441
4442
100
  case E_SCORE_MACH_SCORE3:
4443
100
    e_set = bfd_mach_score3;
4444
100
    break;
4445
136
  }
4446
136
    }
4447
4448
244
  return bfd_default_set_arch_mach (abfd, bfd_arch_score, e_set);
4449
244
}
4450
4451
bool
4452
_bfd_score_elf_common_definition (Elf_Internal_Sym *sym)
4453
0
{
4454
0
  return (sym->st_shndx == SHN_COMMON || sym->st_shndx == SHN_SCORE_SCOMMON);
4455
0
}
4456
4457
/*****************************************************************************/
4458
4459
4460
#define USE_REL       1
4461
#define TARGET_LITTLE_SYM   score_elf32_le_vec
4462
#define TARGET_LITTLE_NAME    "elf32-littlescore"
4463
#define TARGET_BIG_SYM      score_elf32_be_vec
4464
#define TARGET_BIG_NAME     "elf32-bigscore"
4465
#define ELF_ARCH      bfd_arch_score
4466
#define ELF_MACHINE_CODE    EM_SCORE
4467
#define ELF_MACHINE_ALT1    EM_SCORE_OLD
4468
#define ELF_TARGET_ID     SCORE_ELF_DATA
4469
#define ELF_MAXPAGESIZE     0x8000
4470
4471
#define elf_info_to_howto   NULL
4472
#define elf_info_to_howto_rel   _bfd_score_info_to_howto
4473
#define elf_backend_relocate_section  _bfd_score_elf_relocate_section
4474
#define elf_backend_check_relocs  _bfd_score_elf_check_relocs
4475
#define elf_backend_add_symbol_hook _bfd_score_elf_add_symbol_hook
4476
#define elf_backend_symbol_processing _bfd_score_elf_symbol_processing
4477
#define elf_backend_link_output_symbol_hook \
4478
  _bfd_score_elf_link_output_symbol_hook
4479
#define elf_backend_section_from_bfd_section \
4480
  _bfd_score_elf_section_from_bfd_section
4481
#define elf_backend_adjust_dynamic_symbol \
4482
  _bfd_score_elf_adjust_dynamic_symbol
4483
#define elf_backend_early_size_sections \
4484
  _bfd_score_elf_early_size_sections
4485
#define elf_backend_late_size_sections \
4486
  _bfd_score_elf_late_size_sections
4487
#define elf_backend_omit_section_dynsym   _bfd_elf_omit_section_dynsym_all
4488
#define elf_backend_create_dynamic_sections \
4489
  _bfd_score_elf_create_dynamic_sections
4490
#define elf_backend_finish_dynamic_symbol \
4491
  _bfd_score_elf_finish_dynamic_symbol
4492
#define elf_backend_finish_dynamic_sections \
4493
  _bfd_score_elf_finish_dynamic_sections
4494
#define elf_backend_fake_sections   _bfd_score_elf_fake_sections
4495
#define elf_backend_section_processing    _bfd_score_elf_section_processing
4496
#define elf_backend_write_section   _bfd_score_elf_write_section
4497
#define elf_backend_copy_indirect_symbol  _bfd_score_elf_copy_indirect_symbol
4498
#define elf_backend_hide_symbol     _bfd_score_elf_hide_symbol
4499
#define elf_backend_discard_info    _bfd_score_elf_discard_info
4500
#define elf_backend_ignore_discarded_relocs \
4501
  _bfd_score_elf_ignore_discarded_relocs
4502
#define elf_backend_gc_mark_hook    _bfd_score_elf_gc_mark_hook
4503
#define elf_backend_grok_prstatus   _bfd_score_elf_grok_prstatus
4504
#define elf_backend_grok_psinfo     _bfd_score_elf_grok_psinfo
4505
#define elf_backend_can_gc_sections   1
4506
#define elf_backend_want_plt_sym    0
4507
#define elf_backend_got_header_size   (4 * SCORE_RESERVED_GOTNO)
4508
#define elf_backend_plt_header_size   0
4509
#define elf_backend_collect     true
4510
#define elf_backend_type_change_ok    true
4511
#define elf_backend_object_p          _bfd_score_elf_score_object_p
4512
4513
#define bfd_elf32_bfd_reloc_type_lookup      elf32_score_reloc_type_lookup
4514
#define bfd_elf32_bfd_reloc_name_lookup \
4515
  elf32_score_reloc_name_lookup
4516
#define bfd_elf32_bfd_link_hash_table_create elf32_score_link_hash_table_create
4517
#define bfd_elf32_bfd_print_private_bfd_data elf32_score_print_private_bfd_data
4518
#define bfd_elf32_bfd_merge_private_bfd_data elf32_score_merge_private_bfd_data
4519
#define bfd_elf32_new_section_hook       elf32_score_new_section_hook
4520
4521
#include "elf32-target.h"