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