Coverage Report

Created: 2026-04-04 08:16

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