Coverage Report

Created: 2023-08-28 06:31

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