OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-src/] [gdb-7.2/] [gdb-7.2-or32-1.0rc1/] [bfd/] [elf32-score.c] - Blame information for rev 341

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.