Coverage Report

Created: 2025-06-24 06:45

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