Coverage Report

Created: 2026-03-10 08:46

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