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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [elf32-score.c] - Blame information for rev 146

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 khays
/* 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 != STN_UNDEF
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 == STN_UNDEF)
2143
        /* r_symndx will be STN_UNDEF (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
        RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
2679
                                         rel, relend, howto, contents);
2680
 
2681
      if (info->relocatable)
2682
        {
2683
          /* This is a relocatable link.  We don't have to change
2684
             anything, unless the reloc is against a section symbol,
2685
             in which case we have to adjust according to where the
2686
             section symbol winds up in the output section.  */
2687
          if (r_symndx < symtab_hdr->sh_info)
2688
            {
2689
              sym = local_syms + r_symndx;
2690
              if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2691
                {
2692
                  sec = local_sections[r_symndx];
2693
                  score_elf_add_to_rel (input_bfd, contents + rel->r_offset,
2694
                                    howto, (bfd_signed_vma) (sec->output_offset + sym->st_value));
2695
                }
2696
            }
2697
          continue;
2698
        }
2699
 
2700
      /* This is a final link.  */
2701
      r = score_elf_final_link_relocate (howto, input_bfd, output_bfd,
2702
                                         input_section, contents, rel, relocs,
2703
                                         relocation, info, name,
2704
                                         (h ? ELF_ST_TYPE ((unsigned int)h->root.root.type) :
2705
                                         ELF_ST_TYPE ((unsigned int)sym->st_info)), h, local_sections,
2706
                                         gp_disp_p);
2707
 
2708
      if (r != bfd_reloc_ok)
2709
        {
2710
          const char *msg = (const char *)0;
2711
 
2712
          switch (r)
2713
            {
2714
            case bfd_reloc_overflow:
2715
              /* If the overflowing reloc was to an undefined symbol,
2716
                 we have already printed one error message and there
2717
                 is no point complaining again.  */
2718
              if (((!h) || (h->root.root.type != bfd_link_hash_undefined))
2719
                  && (!((*info->callbacks->reloc_overflow)
2720
                        (info, NULL, name, howto->name, (bfd_vma) 0,
2721
                         input_bfd, input_section, rel->r_offset))))
2722
                return FALSE;
2723
              break;
2724
            case bfd_reloc_undefined:
2725
              if (!((*info->callbacks->undefined_symbol)
2726
                    (info, name, input_bfd, input_section, rel->r_offset, TRUE)))
2727
                return FALSE;
2728
              break;
2729
 
2730
            case bfd_reloc_outofrange:
2731
              msg = _("internal error: out of range error");
2732
              goto common_error;
2733
 
2734
            case bfd_reloc_notsupported:
2735
              msg = _("internal error: unsupported relocation error");
2736
              goto common_error;
2737
 
2738
            case bfd_reloc_dangerous:
2739
              msg = _("internal error: dangerous error");
2740
              goto common_error;
2741
 
2742
            /* Use bfd_reloc_other to check lw48, sw48 word align.  */
2743
            case bfd_reloc_other:
2744
              msg = _("address not word align");
2745
              goto common_error;
2746
 
2747
            default:
2748
              msg = _("internal error: unknown error");
2749
              /* fall through */
2750
 
2751
            common_error:
2752
              if (!((*info->callbacks->warning)
2753
                    (info, msg, name, input_bfd, input_section, rel->r_offset)))
2754
                return FALSE;
2755
              break;
2756
            }
2757
        }
2758
    }
2759
 
2760
  return TRUE;
2761
}
2762
 
2763
/* Look through the relocs for a section during the first phase, and
2764
   allocate space in the global offset table.  */
2765
static bfd_boolean
2766
s3_bfd_score_elf_check_relocs (bfd *abfd,
2767
                               struct bfd_link_info *info,
2768
                               asection *sec,
2769
                               const Elf_Internal_Rela *relocs)
2770
{
2771
  const char *name;
2772
  bfd *dynobj;
2773
  Elf_Internal_Shdr *symtab_hdr;
2774
  struct elf_link_hash_entry **sym_hashes;
2775
  struct score_got_info *g;
2776
  size_t extsymoff;
2777
  const Elf_Internal_Rela *rel;
2778
  const Elf_Internal_Rela *rel_end;
2779
  asection *sgot;
2780
  asection *sreloc;
2781
  const struct elf_backend_data *bed;
2782
 
2783
  if (info->relocatable)
2784
    return TRUE;
2785
 
2786
  dynobj = elf_hash_table (info)->dynobj;
2787
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2788
  sym_hashes = elf_sym_hashes (abfd);
2789
  extsymoff = (elf_bad_symtab (abfd)) ? 0 : symtab_hdr->sh_info;
2790
 
2791
  name = bfd_get_section_name (abfd, sec);
2792
 
2793
  if (dynobj == NULL)
2794
    {
2795
      sgot = NULL;
2796
      g = NULL;
2797
    }
2798
  else
2799
    {
2800
      sgot = score_elf_got_section (dynobj, FALSE);
2801
      if (sgot == NULL)
2802
        g = NULL;
2803
      else
2804
        {
2805
          BFD_ASSERT (score_elf_section_data (sgot) != NULL);
2806
          g = score_elf_section_data (sgot)->u.got_info;
2807
          BFD_ASSERT (g != NULL);
2808
        }
2809
    }
2810
 
2811
  sreloc = NULL;
2812
  bed = get_elf_backend_data (abfd);
2813
  rel_end = relocs + sec->reloc_count * bed->s->int_rels_per_ext_rel;
2814
  for (rel = relocs; rel < rel_end; ++rel)
2815
    {
2816
      unsigned long r_symndx;
2817
      unsigned int r_type;
2818
      struct elf_link_hash_entry *h;
2819
 
2820
      r_symndx = ELF32_R_SYM (rel->r_info);
2821
      r_type = ELF32_R_TYPE (rel->r_info);
2822
 
2823
      if (r_symndx < extsymoff)
2824
        {
2825
          h = NULL;
2826
        }
2827
      else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr))
2828
        {
2829
          (*_bfd_error_handler) (_("%s: Malformed reloc detected for section %s"), abfd, name);
2830
          bfd_set_error (bfd_error_bad_value);
2831
          return FALSE;
2832
        }
2833
      else
2834
        {
2835
          h = sym_hashes[r_symndx - extsymoff];
2836
 
2837
          /* This may be an indirect symbol created because of a version.  */
2838
          if (h != NULL)
2839
            {
2840
              while (h->root.type == bfd_link_hash_indirect)
2841
                h = (struct elf_link_hash_entry *)h->root.u.i.link;
2842
            }
2843
        }
2844
 
2845
      /* Some relocs require a global offset table.  */
2846
      if (dynobj == NULL || sgot == NULL)
2847
        {
2848
          switch (r_type)
2849
            {
2850
            case R_SCORE_GOT15:
2851
            case R_SCORE_CALL15:
2852
              if (dynobj == NULL)
2853
                elf_hash_table (info)->dynobj = dynobj = abfd;
2854
              if (!score_elf_create_got_section (dynobj, info, FALSE))
2855
                return FALSE;
2856
              g = score_elf_got_info (dynobj, &sgot);
2857
              break;
2858
            case R_SCORE_ABS32:
2859
            case R_SCORE_REL32:
2860
              if (dynobj == NULL && (info->shared || h != NULL) && (sec->flags & SEC_ALLOC) != 0)
2861
                elf_hash_table (info)->dynobj = dynobj = abfd;
2862
              break;
2863
            default:
2864
              break;
2865
            }
2866
        }
2867
 
2868
      if (!h && (r_type == R_SCORE_GOT_LO16))
2869
        {
2870
          if (! score_elf_record_local_got_symbol (abfd, r_symndx, rel->r_addend, g))
2871
            return FALSE;
2872
        }
2873
 
2874
      switch (r_type)
2875
        {
2876
        case R_SCORE_CALL15:
2877
          if (h == NULL)
2878
            {
2879
              (*_bfd_error_handler)
2880
                (_("%B: CALL15 reloc at 0x%lx not against global symbol"),
2881
                 abfd, (unsigned long) rel->r_offset);
2882
              bfd_set_error (bfd_error_bad_value);
2883
              return FALSE;
2884
            }
2885
          else
2886
            {
2887
              /* This symbol requires a global offset table entry.  */
2888
              if (! score_elf_record_global_got_symbol (h, abfd, info, g))
2889
                return FALSE;
2890
 
2891
              /* We need a stub, not a plt entry for the undefined function.  But we record
2892
                 it as if it needs plt.  See _bfd_elf_adjust_dynamic_symbol.  */
2893
              h->needs_plt = 1;
2894
              h->type = STT_FUNC;
2895
            }
2896
          break;
2897
        case R_SCORE_GOT15:
2898
          if (h && ! score_elf_record_global_got_symbol (h, abfd, info, g))
2899
            return FALSE;
2900
          break;
2901
        case R_SCORE_ABS32:
2902
        case R_SCORE_REL32:
2903
          if ((info->shared || h != NULL) && (sec->flags & SEC_ALLOC) != 0)
2904
            {
2905
              if (sreloc == NULL)
2906
                {
2907
                  sreloc = score_elf_rel_dyn_section (dynobj, TRUE);
2908
                  if (sreloc == NULL)
2909
                    return FALSE;
2910
                }
2911
#define SCORE_READONLY_SECTION (SEC_ALLOC | SEC_LOAD | SEC_READONLY)
2912
              if (info->shared)
2913
                {
2914
                  /* When creating a shared object, we must copy these reloc types into
2915
                     the output file as R_SCORE_REL32 relocs.  We make room for this reloc
2916
                     in the .rel.dyn reloc section.  */
2917
                  score_elf_allocate_dynamic_relocations (dynobj, 1);
2918
                  if ((sec->flags & SCORE_READONLY_SECTION)
2919
                      == SCORE_READONLY_SECTION)
2920
                    /* We tell the dynamic linker that there are
2921
                       relocations against the text segment.  */
2922
                    info->flags |= DF_TEXTREL;
2923
                }
2924
              else
2925
                {
2926
                  struct score_elf_link_hash_entry *hscore;
2927
 
2928
                  /* We only need to copy this reloc if the symbol is
2929
                     defined in a dynamic object.  */
2930
                  hscore = (struct score_elf_link_hash_entry *)h;
2931
                  ++hscore->possibly_dynamic_relocs;
2932
                  if ((sec->flags & SCORE_READONLY_SECTION)
2933
                      == SCORE_READONLY_SECTION)
2934
                    /* We need it to tell the dynamic linker if there
2935
                       are relocations against the text segment.  */
2936
                    hscore->readonly_reloc = TRUE;
2937
                }
2938
 
2939
              /* Even though we don't directly need a GOT entry for this symbol,
2940
                 a symbol must have a dynamic symbol table index greater that
2941
                 DT_SCORE_GOTSYM if there are dynamic relocations against it.  */
2942
              if (h != NULL)
2943
                {
2944
                  if (dynobj == NULL)
2945
                    elf_hash_table (info)->dynobj = dynobj = abfd;
2946
                  if (! score_elf_create_got_section (dynobj, info, TRUE))
2947
                    return FALSE;
2948
                  g = score_elf_got_info (dynobj, &sgot);
2949
                  if (! score_elf_record_global_got_symbol (h, abfd, info, g))
2950
                    return FALSE;
2951
                }
2952
            }
2953
          break;
2954
 
2955
          /* This relocation describes the C++ object vtable hierarchy.
2956
             Reconstruct it for later use during GC.  */
2957
        case R_SCORE_GNU_VTINHERIT:
2958
          if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
2959
            return FALSE;
2960
          break;
2961
 
2962
          /* This relocation describes which C++ vtable entries are actually
2963
             used.  Record for later use during GC.  */
2964
        case R_SCORE_GNU_VTENTRY:
2965
          if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
2966
            return FALSE;
2967
          break;
2968
        default:
2969
          break;
2970
        }
2971
 
2972
      /* We must not create a stub for a symbol that has relocations
2973
         related to taking the function's address.  */
2974
      switch (r_type)
2975
        {
2976
        default:
2977
          if (h != NULL)
2978
            {
2979
              struct score_elf_link_hash_entry *sh;
2980
 
2981
              sh = (struct score_elf_link_hash_entry *) h;
2982
              sh->no_fn_stub = TRUE;
2983
            }
2984
          break;
2985
        case R_SCORE_CALL15:
2986
          break;
2987
        }
2988
    }
2989
 
2990
  return TRUE;
2991
}
2992
 
2993
static bfd_boolean
2994
s3_bfd_score_elf_add_symbol_hook (bfd *abfd,
2995
                                  struct bfd_link_info *info ATTRIBUTE_UNUSED,
2996
                                  Elf_Internal_Sym *sym,
2997
                                  const char **namep ATTRIBUTE_UNUSED,
2998
                                  flagword *flagsp ATTRIBUTE_UNUSED,
2999
                                  asection **secp,
3000
                                  bfd_vma *valp)
3001
{
3002
  switch (sym->st_shndx)
3003
    {
3004
    case SHN_COMMON:
3005
      if (sym->st_size > elf_gp_size (abfd))
3006
        break;
3007
      /* Fall through.  */
3008
    case SHN_SCORE_SCOMMON:
3009
      *secp = bfd_make_section_old_way (abfd, ".scommon");
3010
      (*secp)->flags |= SEC_IS_COMMON;
3011
      *valp = sym->st_size;
3012
      break;
3013
    }
3014
 
3015
  return TRUE;
3016
}
3017
 
3018
static void
3019
s3_bfd_score_elf_symbol_processing (bfd *abfd, asymbol *asym)
3020
{
3021
  elf_symbol_type *elfsym;
3022
 
3023
  elfsym = (elf_symbol_type *) asym;
3024
  switch (elfsym->internal_elf_sym.st_shndx)
3025
    {
3026
    case SHN_COMMON:
3027
      if (asym->value > elf_gp_size (abfd))
3028
        break;
3029
      /* Fall through.  */
3030
    case SHN_SCORE_SCOMMON:
3031
      if (score_elf_scom_section.name == NULL)
3032
        {
3033
          /* Initialize the small common section.  */
3034
          score_elf_scom_section.name = ".scommon";
3035
          score_elf_scom_section.flags = SEC_IS_COMMON;
3036
          score_elf_scom_section.output_section = &score_elf_scom_section;
3037
          score_elf_scom_section.symbol = &score_elf_scom_symbol;
3038
          score_elf_scom_section.symbol_ptr_ptr = &score_elf_scom_symbol_ptr;
3039
          score_elf_scom_symbol.name = ".scommon";
3040
          score_elf_scom_symbol.flags = BSF_SECTION_SYM;
3041
          score_elf_scom_symbol.section = &score_elf_scom_section;
3042
          score_elf_scom_symbol_ptr = &score_elf_scom_symbol;
3043
        }
3044
      asym->section = &score_elf_scom_section;
3045
      asym->value = elfsym->internal_elf_sym.st_size;
3046
      break;
3047
    }
3048
}
3049
 
3050
static int
3051
s3_bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
3052
                                          const char *name ATTRIBUTE_UNUSED,
3053
                                          Elf_Internal_Sym *sym,
3054
                                          asection *input_sec,
3055
                                          struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
3056
{
3057
  /* If we see a common symbol, which implies a relocatable link, then
3058
     if a symbol was small common in an input file, mark it as small
3059
     common in the output file.  */
3060
  if (sym->st_shndx == SHN_COMMON && strcmp (input_sec->name, ".scommon") == 0)
3061
    sym->st_shndx = SHN_SCORE_SCOMMON;
3062
 
3063
  return 1;
3064
}
3065
 
3066
static bfd_boolean
3067
s3_bfd_score_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
3068
                                           asection *sec,
3069
                                           int *retval)
3070
{
3071
  if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
3072
    {
3073
      *retval = SHN_SCORE_SCOMMON;
3074
      return TRUE;
3075
    }
3076
 
3077
  return FALSE;
3078
}
3079
 
3080
/* Adjust a symbol defined by a dynamic object and referenced by a
3081
   regular object.  The current definition is in some section of the
3082
   dynamic object, but we're not including those sections.  We have to
3083
   change the definition to something the rest of the link can understand.  */
3084
static bfd_boolean
3085
s3_bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
3086
                                        struct elf_link_hash_entry *h)
3087
{
3088
  bfd *dynobj;
3089
  struct score_elf_link_hash_entry *hscore;
3090
  asection *s;
3091
 
3092
  dynobj = elf_hash_table (info)->dynobj;
3093
 
3094
  /* Make sure we know what is going on here.  */
3095
  BFD_ASSERT (dynobj != NULL
3096
              && (h->needs_plt
3097
                  || h->u.weakdef != NULL
3098
                  || (h->def_dynamic && h->ref_regular && !h->def_regular)));
3099
 
3100
  /* If this symbol is defined in a dynamic object, we need to copy
3101
     any R_SCORE_ABS32 or R_SCORE_REL32 relocs against it into the output
3102
     file.  */
3103
  hscore = (struct score_elf_link_hash_entry *)h;
3104
  if (!info->relocatable
3105
      && hscore->possibly_dynamic_relocs != 0
3106
      && (h->root.type == bfd_link_hash_defweak || !h->def_regular))
3107
    {
3108
      score_elf_allocate_dynamic_relocations (dynobj, hscore->possibly_dynamic_relocs);
3109
      if (hscore->readonly_reloc)
3110
        /* We tell the dynamic linker that there are relocations
3111
           against the text segment.  */
3112
        info->flags |= DF_TEXTREL;
3113
    }
3114
 
3115
  /* For a function, create a stub, if allowed.  */
3116
  if (!hscore->no_fn_stub && h->needs_plt)
3117
    {
3118
      if (!elf_hash_table (info)->dynamic_sections_created)
3119
        return TRUE;
3120
 
3121
      /* If this symbol is not defined in a regular file, then set
3122
         the symbol to the stub location.  This is required to make
3123
         function pointers compare as equal between the normal
3124
         executable and the shared library.  */
3125
      if (!h->def_regular)
3126
        {
3127
          /* We need .stub section.  */
3128
          s = bfd_get_section_by_name (dynobj, SCORE_ELF_STUB_SECTION_NAME);
3129
          BFD_ASSERT (s != NULL);
3130
 
3131
          h->root.u.def.section = s;
3132
          h->root.u.def.value = s->size;
3133
 
3134
          /* XXX Write this stub address somewhere.  */
3135
          h->plt.offset = s->size;
3136
 
3137
          /* Make room for this stub code.  */
3138
          s->size += SCORE_FUNCTION_STUB_SIZE;
3139
 
3140
          /* The last half word of the stub will be filled with the index
3141
             of this symbol in .dynsym section.  */
3142
          return TRUE;
3143
        }
3144
    }
3145
  else if ((h->type == STT_FUNC) && !h->needs_plt)
3146
    {
3147
      /* This will set the entry for this symbol in the GOT to 0, and
3148
         the dynamic linker will take care of this.  */
3149
      h->root.u.def.value = 0;
3150
      return TRUE;
3151
    }
3152
 
3153
  /* If this is a weak symbol, and there is a real definition, the
3154
     processor independent code will have arranged for us to see the
3155
     real definition first, and we can just use the same value.  */
3156
  if (h->u.weakdef != NULL)
3157
    {
3158
      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
3159
                  || h->u.weakdef->root.type == bfd_link_hash_defweak);
3160
      h->root.u.def.section = h->u.weakdef->root.u.def.section;
3161
      h->root.u.def.value = h->u.weakdef->root.u.def.value;
3162
      return TRUE;
3163
    }
3164
 
3165
  /* This is a reference to a symbol defined by a dynamic object which
3166
     is not a function.  */
3167
  return TRUE;
3168
}
3169
 
3170
/* This function is called after all the input files have been read,
3171
   and the input sections have been assigned to output sections.  */
3172
static bfd_boolean
3173
s3_bfd_score_elf_always_size_sections (bfd *output_bfd,
3174
                                       struct bfd_link_info *info)
3175
{
3176
  bfd *dynobj;
3177
  asection *s;
3178
  struct score_got_info *g;
3179
  int i;
3180
  bfd_size_type loadable_size = 0;
3181
  bfd_size_type local_gotno;
3182
  bfd *sub;
3183
 
3184
  dynobj = elf_hash_table (info)->dynobj;
3185
  if (dynobj == NULL)
3186
    /* Relocatable links don't have it.  */
3187
    return TRUE;
3188
 
3189
  g = score_elf_got_info (dynobj, &s);
3190
  if (s == NULL)
3191
    return TRUE;
3192
 
3193
  /* Calculate the total loadable size of the output.  That will give us the
3194
     maximum number of GOT_PAGE entries required.  */
3195
  for (sub = info->input_bfds; sub; sub = sub->link_next)
3196
    {
3197
      asection *subsection;
3198
 
3199
      for (subsection = sub->sections;
3200
           subsection;
3201
           subsection = subsection->next)
3202
        {
3203
          if ((subsection->flags & SEC_ALLOC) == 0)
3204
            continue;
3205
          loadable_size += ((subsection->size + 0xf)
3206
                            &~ (bfd_size_type) 0xf);
3207
        }
3208
    }
3209
 
3210
  /* There has to be a global GOT entry for every symbol with
3211
     a dynamic symbol table index of DT_SCORE_GOTSYM or
3212
     higher.  Therefore, it make sense to put those symbols
3213
     that need GOT entries at the end of the symbol table.  We
3214
     do that here.  */
3215
  if (! score_elf_sort_hash_table (info, 1))
3216
    return FALSE;
3217
 
3218
  if (g->global_gotsym != NULL)
3219
    i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx;
3220
  else
3221
    /* If there are no global symbols, or none requiring
3222
       relocations, then GLOBAL_GOTSYM will be NULL.  */
3223
    i = 0;
3224
 
3225
  /* In the worst case, we'll get one stub per dynamic symbol.  */
3226
  loadable_size += SCORE_FUNCTION_STUB_SIZE * i;
3227
 
3228
  /* Assume there are two loadable segments consisting of
3229
     contiguous sections.  Is 5 enough?  */
3230
  local_gotno = (loadable_size >> 16) + 5;
3231
 
3232
  g->local_gotno += local_gotno;
3233
  s->size += g->local_gotno * SCORE_ELF_GOT_SIZE (output_bfd);
3234
 
3235
  g->global_gotno = i;
3236
  s->size += i * SCORE_ELF_GOT_SIZE (output_bfd);
3237
 
3238
  score_elf_resolve_final_got_entries (g);
3239
 
3240
  if (s->size > SCORE_ELF_GOT_MAX_SIZE (output_bfd))
3241
    {
3242
      /* Fixme. Error message or Warning message should be issued here.  */
3243
    }
3244
 
3245
  return TRUE;
3246
}
3247
 
3248
/* Set the sizes of the dynamic sections.  */
3249
static bfd_boolean
3250
s3_bfd_score_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
3251
{
3252
  bfd *dynobj;
3253
  asection *s;
3254
  bfd_boolean reltext;
3255
 
3256
  dynobj = elf_hash_table (info)->dynobj;
3257
  BFD_ASSERT (dynobj != NULL);
3258
 
3259
  if (elf_hash_table (info)->dynamic_sections_created)
3260
    {
3261
      /* Set the contents of the .interp section to the interpreter.  */
3262
      if (!info->shared)
3263
        {
3264
          s = bfd_get_section_by_name (dynobj, ".interp");
3265
          BFD_ASSERT (s != NULL);
3266
          s->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
3267
          s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
3268
        }
3269
    }
3270
 
3271
  /* The check_relocs and adjust_dynamic_symbol entry points have
3272
     determined the sizes of the various dynamic sections.  Allocate
3273
     memory for them.  */
3274
  reltext = FALSE;
3275
  for (s = dynobj->sections; s != NULL; s = s->next)
3276
    {
3277
      const char *name;
3278
 
3279
      if ((s->flags & SEC_LINKER_CREATED) == 0)
3280
        continue;
3281
 
3282
      /* It's OK to base decisions on the section name, because none
3283
         of the dynobj section names depend upon the input files.  */
3284
      name = bfd_get_section_name (dynobj, s);
3285
 
3286
      if (CONST_STRNEQ (name, ".rel"))
3287
        {
3288
          if (s->size == 0)
3289
            {
3290
              /* We only strip the section if the output section name
3291
                 has the same name.  Otherwise, there might be several
3292
                 input sections for this output section.  FIXME: This
3293
                 code is probably not needed these days anyhow, since
3294
                 the linker now does not create empty output sections.  */
3295
              if (s->output_section != NULL
3296
                  && strcmp (name,
3297
                             bfd_get_section_name (s->output_section->owner,
3298
                                                   s->output_section)) == 0)
3299
                s->flags |= SEC_EXCLUDE;
3300
            }
3301
          else
3302
            {
3303
              const char *outname;
3304
              asection *target;
3305
 
3306
              /* If this relocation section applies to a read only
3307
                 section, then we probably need a DT_TEXTREL entry.
3308
                 If the relocation section is .rel.dyn, we always
3309
                 assert a DT_TEXTREL entry rather than testing whether
3310
                 there exists a relocation to a read only section or
3311
                 not.  */
3312
              outname = bfd_get_section_name (output_bfd, s->output_section);
3313
              target = bfd_get_section_by_name (output_bfd, outname + 4);
3314
              if ((target != NULL
3315
                   && (target->flags & SEC_READONLY) != 0
3316
                   && (target->flags & SEC_ALLOC) != 0) || strcmp (outname, ".rel.dyn") == 0)
3317
                reltext = TRUE;
3318
 
3319
              /* We use the reloc_count field as a counter if we need
3320
                 to copy relocs into the output file.  */
3321
              if (strcmp (name, ".rel.dyn") != 0)
3322
                s->reloc_count = 0;
3323
            }
3324
        }
3325
      else if (CONST_STRNEQ (name, ".got"))
3326
        {
3327
          /* s3_bfd_score_elf_always_size_sections() has already done
3328
             most of the work, but some symbols may have been mapped
3329
             to versions that we must now resolve in the got_entries
3330
             hash tables.  */
3331
        }
3332
      else if (strcmp (name, SCORE_ELF_STUB_SECTION_NAME) == 0)
3333
        {
3334
          /* IRIX rld assumes that the function stub isn't at the end
3335
             of .text section. So put a dummy. XXX  */
3336
          s->size += SCORE_FUNCTION_STUB_SIZE;
3337
        }
3338
      else if (! CONST_STRNEQ (name, ".init"))
3339
        {
3340
          /* It's not one of our sections, so don't allocate space.  */
3341
          continue;
3342
        }
3343
 
3344
      /* Allocate memory for the section contents.  */
3345
      s->contents = bfd_zalloc (dynobj, s->size);
3346
      if (s->contents == NULL && s->size != 0)
3347
        {
3348
          bfd_set_error (bfd_error_no_memory);
3349
          return FALSE;
3350
        }
3351
    }
3352
 
3353
  if (elf_hash_table (info)->dynamic_sections_created)
3354
    {
3355
      /* Add some entries to the .dynamic section.  We fill in the
3356
         values later, in s3_bfd_score_elf_finish_dynamic_sections, but we
3357
         must add the entries now so that we get the correct size for
3358
         the .dynamic section.  The DT_DEBUG entry is filled in by the
3359
         dynamic linker and used by the debugger.  */
3360
 
3361
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0))
3362
        return FALSE;
3363
 
3364
      if (reltext)
3365
        info->flags |= DF_TEXTREL;
3366
 
3367
      if ((info->flags & DF_TEXTREL) != 0)
3368
        {
3369
          if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0))
3370
            return FALSE;
3371
        }
3372
 
3373
      if (! SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTGOT, 0))
3374
        return FALSE;
3375
 
3376
      if (score_elf_rel_dyn_section (dynobj, FALSE))
3377
        {
3378
          if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_REL, 0))
3379
            return FALSE;
3380
 
3381
          if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELSZ, 0))
3382
            return FALSE;
3383
 
3384
          if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELENT, 0))
3385
            return FALSE;
3386
        }
3387
 
3388
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_BASE_ADDRESS, 0))
3389
        return FALSE;
3390
 
3391
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_LOCAL_GOTNO, 0))
3392
        return FALSE;
3393
 
3394
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_SYMTABNO, 0))
3395
        return FALSE;
3396
 
3397
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_UNREFEXTNO, 0))
3398
        return FALSE;
3399
 
3400
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_GOTSYM, 0))
3401
        return FALSE;
3402
 
3403
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_HIPAGENO, 0))
3404
        return FALSE;
3405
    }
3406
 
3407
  return TRUE;
3408
}
3409
 
3410
static bfd_boolean
3411
s3_bfd_score_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
3412
{
3413
  struct elf_link_hash_entry *h;
3414
  struct bfd_link_hash_entry *bh;
3415
  flagword flags;
3416
  asection *s;
3417
 
3418
  flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
3419
           | SEC_LINKER_CREATED | SEC_READONLY);
3420
 
3421
  /* ABI requests the .dynamic section to be read only.  */
3422
  s = bfd_get_section_by_name (abfd, ".dynamic");
3423
  if (s != NULL)
3424
    {
3425
      if (!bfd_set_section_flags (abfd, s, flags))
3426
        return FALSE;
3427
    }
3428
 
3429
  /* We need to create .got section.  */
3430
  if (!score_elf_create_got_section (abfd, info, FALSE))
3431
    return FALSE;
3432
 
3433
  if (!score_elf_rel_dyn_section (elf_hash_table (info)->dynobj, TRUE))
3434
    return FALSE;
3435
 
3436
  /* Create .stub section.  */
3437
  if (bfd_get_section_by_name (abfd, SCORE_ELF_STUB_SECTION_NAME) == NULL)
3438
    {
3439
      s = bfd_make_section_with_flags (abfd, SCORE_ELF_STUB_SECTION_NAME,
3440
                                       flags | SEC_CODE);
3441
      if (s == NULL
3442
          || !bfd_set_section_alignment (abfd, s, 2))
3443
 
3444
        return FALSE;
3445
    }
3446
 
3447
  if (!info->shared)
3448
    {
3449
      const char *name;
3450
 
3451
      name = "_DYNAMIC_LINK";
3452
      bh = NULL;
3453
      if (!(_bfd_generic_link_add_one_symbol
3454
            (info, abfd, name, BSF_GLOBAL, bfd_abs_section_ptr,
3455
             (bfd_vma) 0, NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
3456
        return FALSE;
3457
 
3458
      h = (struct elf_link_hash_entry *)bh;
3459
      h->non_elf = 0;
3460
      h->def_regular = 1;
3461
      h->type = STT_SECTION;
3462
 
3463
      if (!bfd_elf_link_record_dynamic_symbol (info, h))
3464
        return FALSE;
3465
    }
3466
 
3467
  return TRUE;
3468
}
3469
 
3470
 
3471
/* Finish up dynamic symbol handling.  We set the contents of various
3472
   dynamic sections here.  */
3473
static bfd_boolean
3474
s3_bfd_score_elf_finish_dynamic_symbol (bfd *output_bfd,
3475
                                        struct bfd_link_info *info,
3476
                                        struct elf_link_hash_entry *h,
3477
                                        Elf_Internal_Sym *sym)
3478
{
3479
  bfd *dynobj;
3480
  asection *sgot;
3481
  struct score_got_info *g;
3482
  const char *name;
3483
 
3484
  dynobj = elf_hash_table (info)->dynobj;
3485
 
3486
  if (h->plt.offset != MINUS_ONE)
3487
    {
3488
      asection *s;
3489
      bfd_byte stub[SCORE_FUNCTION_STUB_SIZE];
3490
 
3491
      /* This symbol has a stub.  Set it up.  */
3492
      BFD_ASSERT (h->dynindx != -1);
3493
 
3494
      s = bfd_get_section_by_name (dynobj, SCORE_ELF_STUB_SECTION_NAME);
3495
      BFD_ASSERT (s != NULL);
3496
 
3497
      /* FIXME: Can h->dynindex be more than 64K?  */
3498
      if (h->dynindx & 0xffff0000)
3499
        return FALSE;
3500
 
3501
      /* Fill the stub.  */
3502
      score_bfd_put_32 (output_bfd, STUB_LW, stub);
3503
      score_bfd_put_32 (output_bfd, STUB_MOVE, stub + 4);
3504
      score_bfd_put_32 (output_bfd, STUB_LI16 | (h->dynindx << 1), stub + 8);
3505
      score_bfd_put_32 (output_bfd, STUB_BRL, stub + 12);
3506
 
3507
      BFD_ASSERT (h->plt.offset <= s->size);
3508
      memcpy (s->contents + h->plt.offset, stub, SCORE_FUNCTION_STUB_SIZE);
3509
 
3510
      /* Mark the symbol as undefined.  plt.offset != -1 occurs
3511
         only for the referenced symbol.  */
3512
      sym->st_shndx = SHN_UNDEF;
3513
 
3514
      /* The run-time linker uses the st_value field of the symbol
3515
          to reset the global offset table entry for this external
3516
          to its stub address when unlinking a shared object.  */
3517
      sym->st_value = (s->output_section->vma + s->output_offset + h->plt.offset);
3518
    }
3519
 
3520
  BFD_ASSERT (h->dynindx != -1 || h->forced_local);
3521
 
3522
  sgot = score_elf_got_section (dynobj, FALSE);
3523
  BFD_ASSERT (sgot != NULL);
3524
  BFD_ASSERT (score_elf_section_data (sgot) != NULL);
3525
  g = score_elf_section_data (sgot)->u.got_info;
3526
  BFD_ASSERT (g != NULL);
3527
 
3528
  /* Run through the global symbol table, creating GOT entries for all
3529
     the symbols that need them.  */
3530
  if (g->global_gotsym != NULL && h->dynindx >= g->global_gotsym->dynindx)
3531
    {
3532
      bfd_vma offset;
3533
      bfd_vma value;
3534
 
3535
      value = sym->st_value;
3536
      offset = score_elf_global_got_index (dynobj, h);
3537
      score_bfd_put_32 (output_bfd, value, sgot->contents + offset);
3538
    }
3539
 
3540
  /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
3541
  name = h->root.root.string;
3542
  if (strcmp (name, "_DYNAMIC") == 0 || strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
3543
    sym->st_shndx = SHN_ABS;
3544
  else if (strcmp (name, "_DYNAMIC_LINK") == 0)
3545
    {
3546
      sym->st_shndx = SHN_ABS;
3547
      sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
3548
      sym->st_value = 1;
3549
    }
3550
  else if (strcmp (name, GP_DISP_LABEL) == 0)
3551
    {
3552
      sym->st_shndx = SHN_ABS;
3553
      sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
3554
      sym->st_value = elf_gp (output_bfd);
3555
    }
3556
 
3557
  return TRUE;
3558
}
3559
 
3560
/* Finish up the dynamic sections.  */
3561
static bfd_boolean
3562
s3_bfd_score_elf_finish_dynamic_sections (bfd *output_bfd,
3563
                                          struct bfd_link_info *info)
3564
{
3565
  bfd *dynobj;
3566
  asection *sdyn;
3567
  asection *sgot;
3568
  asection *s;
3569
  struct score_got_info *g;
3570
 
3571
  dynobj = elf_hash_table (info)->dynobj;
3572
 
3573
  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
3574
 
3575
  sgot = score_elf_got_section (dynobj, FALSE);
3576
  if (sgot == NULL)
3577
    g = NULL;
3578
  else
3579
    {
3580
      BFD_ASSERT (score_elf_section_data (sgot) != NULL);
3581
      g = score_elf_section_data (sgot)->u.got_info;
3582
      BFD_ASSERT (g != NULL);
3583
    }
3584
 
3585
  if (elf_hash_table (info)->dynamic_sections_created)
3586
    {
3587
      bfd_byte *b;
3588
 
3589
      BFD_ASSERT (sdyn != NULL);
3590
      BFD_ASSERT (g != NULL);
3591
 
3592
      for (b = sdyn->contents;
3593
           b < sdyn->contents + sdyn->size;
3594
           b += SCORE_ELF_DYN_SIZE (dynobj))
3595
        {
3596
          Elf_Internal_Dyn dyn;
3597
          const char *name;
3598
          size_t elemsize;
3599
          bfd_boolean swap_out_p;
3600
 
3601
          /* Read in the current dynamic entry.  */
3602
          (*get_elf_backend_data (dynobj)->s->swap_dyn_in) (dynobj, b, &dyn);
3603
 
3604
          /* Assume that we're going to modify it and write it out.  */
3605
          swap_out_p = TRUE;
3606
 
3607
          switch (dyn.d_tag)
3608
            {
3609
            case DT_RELENT:
3610
              s = score_elf_rel_dyn_section (dynobj, FALSE);
3611
              BFD_ASSERT (s != NULL);
3612
              dyn.d_un.d_val = SCORE_ELF_REL_SIZE (dynobj);
3613
              break;
3614
 
3615
            case DT_STRSZ:
3616
              /* Rewrite DT_STRSZ.  */
3617
              dyn.d_un.d_val = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
3618
                    break;
3619
 
3620
            case DT_PLTGOT:
3621
              name = ".got";
3622
              s = bfd_get_section_by_name (output_bfd, name);
3623
              BFD_ASSERT (s != NULL);
3624
              dyn.d_un.d_ptr = s->vma;
3625
              break;
3626
 
3627
            case DT_SCORE_BASE_ADDRESS:
3628
              s = output_bfd->sections;
3629
              BFD_ASSERT (s != NULL);
3630
              dyn.d_un.d_ptr = s->vma & ~(bfd_vma) 0xffff;
3631
              break;
3632
 
3633
            case DT_SCORE_LOCAL_GOTNO:
3634
              dyn.d_un.d_val = g->local_gotno;
3635
              break;
3636
 
3637
            case DT_SCORE_UNREFEXTNO:
3638
              /* The index into the dynamic symbol table which is the
3639
                 entry of the first external symbol that is not
3640
                 referenced within the same object.  */
3641
              dyn.d_un.d_val = bfd_count_sections (output_bfd) + 1;
3642
              break;
3643
 
3644
            case DT_SCORE_GOTSYM:
3645
              if (g->global_gotsym)
3646
                {
3647
                  dyn.d_un.d_val = g->global_gotsym->dynindx;
3648
                  break;
3649
                }
3650
              /* In case if we don't have global got symbols we default
3651
                  to setting DT_SCORE_GOTSYM to the same value as
3652
                  DT_SCORE_SYMTABNO, so we just fall through.  */
3653
 
3654
            case DT_SCORE_SYMTABNO:
3655
              name = ".dynsym";
3656
              elemsize = SCORE_ELF_SYM_SIZE (output_bfd);
3657
              s = bfd_get_section_by_name (output_bfd, name);
3658
              BFD_ASSERT (s != NULL);
3659
 
3660
              dyn.d_un.d_val = s->size / elemsize;
3661
              break;
3662
 
3663
            case DT_SCORE_HIPAGENO:
3664
              dyn.d_un.d_val = g->local_gotno - SCORE_RESERVED_GOTNO;
3665
              break;
3666
 
3667
            default:
3668
              swap_out_p = FALSE;
3669
              break;
3670
            }
3671
 
3672
          if (swap_out_p)
3673
            (*get_elf_backend_data (dynobj)->s->swap_dyn_out) (dynobj, &dyn, b);
3674
        }
3675
    }
3676
 
3677
  /* The first entry of the global offset table will be filled at
3678
     runtime. The second entry will be used by some runtime loaders.
3679
     This isn't the case of IRIX rld.  */
3680
  if (sgot != NULL && sgot->size > 0)
3681
    {
3682
      score_bfd_put_32 (output_bfd, 0, sgot->contents);
3683
      score_bfd_put_32 (output_bfd, 0x80000000, sgot->contents + SCORE_ELF_GOT_SIZE (output_bfd));
3684
    }
3685
 
3686
  if (sgot != NULL)
3687
    elf_section_data (sgot->output_section)->this_hdr.sh_entsize
3688
      = SCORE_ELF_GOT_SIZE (output_bfd);
3689
 
3690
 
3691
  /* We need to sort the entries of the dynamic relocation section.  */
3692
  s = score_elf_rel_dyn_section (dynobj, FALSE);
3693
 
3694
  if (s != NULL && s->size > (bfd_vma)2 * SCORE_ELF_REL_SIZE (output_bfd))
3695
    {
3696
      reldyn_sorting_bfd = output_bfd;
3697
      qsort ((Elf32_External_Rel *) s->contents + 1, s->reloc_count - 1,
3698
             sizeof (Elf32_External_Rel), score_elf_sort_dynamic_relocs);
3699
    }
3700
 
3701
  return TRUE;
3702
}
3703
 
3704
/* This function set up the ELF section header for a BFD section in preparation for writing
3705
   it out.  This is where the flags and type fields are set for unusual sections.  */
3706
static bfd_boolean
3707
s3_bfd_score_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
3708
                                Elf_Internal_Shdr *hdr,
3709
                                asection *sec)
3710
{
3711
  const char *name;
3712
 
3713
  name = bfd_get_section_name (abfd, sec);
3714
 
3715
  if (strcmp (name, ".got") == 0
3716
      || strcmp (name, ".srdata") == 0
3717
      || strcmp (name, ".sdata") == 0
3718
      || strcmp (name, ".sbss") == 0)
3719
    hdr->sh_flags |= SHF_SCORE_GPREL;
3720
 
3721
  return TRUE;
3722
}
3723
 
3724
/* This function do additional processing on the ELF section header before writing
3725
   it out.  This is used to set the flags and type fields for some sections.  */
3726
 
3727
/* assign_file_positions_except_relocs() check section flag and if it is allocatable,
3728
   warning message will be issued.  backend_fake_section is called before
3729
   assign_file_positions_except_relocs(); backend_section_processing after it.  so, we
3730
   modify section flag there, but not backend_fake_section.  */
3731
static bfd_boolean
3732
s3_bfd_score_elf_section_processing (bfd *abfd ATTRIBUTE_UNUSED, Elf_Internal_Shdr *hdr)
3733
{
3734
  if (hdr->bfd_section != NULL)
3735
    {
3736
      const char *name = bfd_get_section_name (abfd, hdr->bfd_section);
3737
 
3738
      if (strcmp (name, ".sdata") == 0)
3739
        {
3740
          hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
3741
          hdr->sh_type = SHT_PROGBITS;
3742
        }
3743
      else if (strcmp (name, ".sbss") == 0)
3744
        {
3745
          hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
3746
          hdr->sh_type = SHT_NOBITS;
3747
        }
3748
      else if (strcmp (name, ".srdata") == 0)
3749
        {
3750
          hdr->sh_flags |= SHF_ALLOC | SHF_SCORE_GPREL;
3751
          hdr->sh_type = SHT_PROGBITS;
3752
        }
3753
    }
3754
 
3755
  return TRUE;
3756
}
3757
 
3758
static bfd_boolean
3759
s3_bfd_score_elf_write_section (bfd *output_bfd, asection *sec, bfd_byte *contents)
3760
{
3761
  bfd_byte *to, *from, *end;
3762
  int i;
3763
 
3764
  if (strcmp (sec->name, ".pdr") != 0)
3765
    return FALSE;
3766
 
3767
  if (score_elf_section_data (sec)->u.tdata == NULL)
3768
    return FALSE;
3769
 
3770
  to = contents;
3771
  end = contents + sec->size;
3772
  for (from = contents, i = 0; from < end; from += PDR_SIZE, i++)
3773
    {
3774
      if ((score_elf_section_data (sec)->u.tdata)[i] == 1)
3775
        continue;
3776
 
3777
      if (to != from)
3778
        memcpy (to, from, PDR_SIZE);
3779
 
3780
      to += PDR_SIZE;
3781
    }
3782
  bfd_set_section_contents (output_bfd, sec->output_section, contents,
3783
                            (file_ptr) sec->output_offset, sec->size);
3784
 
3785
  return TRUE;
3786
}
3787
 
3788
/* Copy data from a SCORE ELF indirect symbol to its direct symbol, hiding the old
3789
   indirect symbol.  Process additional relocation information.  */
3790
static void
3791
s3_bfd_score_elf_copy_indirect_symbol (struct bfd_link_info *info,
3792
                                       struct elf_link_hash_entry *dir,
3793
                                       struct elf_link_hash_entry *ind)
3794
{
3795
  struct score_elf_link_hash_entry *dirscore, *indscore;
3796
 
3797
  _bfd_elf_link_hash_copy_indirect (info, dir, ind);
3798
 
3799
  if (ind->root.type != bfd_link_hash_indirect)
3800
    return;
3801
 
3802
  dirscore = (struct score_elf_link_hash_entry *) dir;
3803
  indscore = (struct score_elf_link_hash_entry *) ind;
3804
  dirscore->possibly_dynamic_relocs += indscore->possibly_dynamic_relocs;
3805
 
3806
  if (indscore->readonly_reloc)
3807
    dirscore->readonly_reloc = TRUE;
3808
 
3809
  if (indscore->no_fn_stub)
3810
    dirscore->no_fn_stub = TRUE;
3811
}
3812
 
3813
/* Remove information about discarded functions from other sections which mention them.  */
3814
static bfd_boolean
3815
s3_bfd_score_elf_discard_info (bfd *abfd, struct elf_reloc_cookie *cookie,
3816
                               struct bfd_link_info *info)
3817
{
3818
  asection *o;
3819
  bfd_boolean ret = FALSE;
3820
  unsigned char *tdata;
3821
  size_t i, skip;
3822
 
3823
  o = bfd_get_section_by_name (abfd, ".pdr");
3824
  if ((!o) || (o->size == 0) || (o->size % PDR_SIZE != 0)
3825
      || (o->output_section != NULL && bfd_is_abs_section (o->output_section)))
3826
    return FALSE;
3827
 
3828
  tdata = bfd_zmalloc (o->size / PDR_SIZE);
3829
  if (!tdata)
3830
    return FALSE;
3831
 
3832
  cookie->rels = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, info->keep_memory);
3833
  if (!cookie->rels)
3834
    {
3835
      free (tdata);
3836
      return FALSE;
3837
    }
3838
 
3839
  cookie->rel = cookie->rels;
3840
  cookie->relend = cookie->rels + o->reloc_count;
3841
 
3842
  for (i = 0, skip = 0; i < o->size; i++)
3843
    {
3844
      if (bfd_elf_reloc_symbol_deleted_p (i * PDR_SIZE, cookie))
3845
        {
3846
          tdata[i] = 1;
3847
          skip++;
3848
        }
3849
    }
3850
 
3851
  if (skip != 0)
3852
    {
3853
      score_elf_section_data (o)->u.tdata = tdata;
3854
      o->size -= skip * PDR_SIZE;
3855
      ret = TRUE;
3856
    }
3857
  else
3858
    free (tdata);
3859
 
3860
  if (!info->keep_memory)
3861
    free (cookie->rels);
3862
 
3863
  return ret;
3864
}
3865
 
3866
/* Signal that discard_info() has removed the discarded relocations for this section.  */
3867
static bfd_boolean
3868
s3_bfd_score_elf_ignore_discarded_relocs (asection *sec)
3869
{
3870
  if (strcmp (sec->name, ".pdr") == 0)
3871
    return TRUE;
3872
  return FALSE;
3873
}
3874
 
3875
/* Return the section that should be marked against GC for a given
3876
   relocation.  */
3877
static asection *
3878
s3_bfd_score_elf_gc_mark_hook (asection *sec,
3879
                               struct bfd_link_info *info,
3880
                               Elf_Internal_Rela *rel,
3881
                               struct elf_link_hash_entry *h,
3882
                               Elf_Internal_Sym *sym)
3883
{
3884
  if (h != NULL)
3885
    switch (ELF32_R_TYPE (rel->r_info))
3886
      {
3887
      case R_SCORE_GNU_VTINHERIT:
3888
      case R_SCORE_GNU_VTENTRY:
3889
        return NULL;
3890
      }
3891
 
3892
  return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
3893
}
3894
 
3895
/* Support for core dump NOTE sections.  */
3896
 
3897
static bfd_boolean
3898
s3_bfd_score_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
3899
{
3900
  int offset;
3901
  unsigned int raw_size;
3902
 
3903
  switch (note->descsz)
3904
    {
3905
    default:
3906
      return FALSE;
3907
 
3908
    case 148:                  /* Linux/Score 32-bit.  */
3909
      /* pr_cursig */
3910
      elf_tdata (abfd)->core_signal = score_bfd_get_16 (abfd, note->descdata + 12);
3911
 
3912
      /* pr_pid */
3913
      elf_tdata (abfd)->core_lwpid = score_bfd_get_32 (abfd, note->descdata + 24);
3914
 
3915
      /* pr_reg */
3916
      offset = 72;
3917
      raw_size = 72;
3918
 
3919
      break;
3920
    }
3921
 
3922
  /* Make a ".reg/999" section.  */
3923
  return _bfd_elfcore_make_pseudosection (abfd, ".reg", raw_size, note->descpos + offset);
3924
}
3925
 
3926
static bfd_boolean
3927
s3_bfd_score_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
3928
{
3929
  switch (note->descsz)
3930
    {
3931
    default:
3932
      return FALSE;
3933
 
3934
    case 124:                  /* Linux/Score elf_prpsinfo.  */
3935
      elf_tdata (abfd)->core_program = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
3936
      elf_tdata (abfd)->core_command = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
3937
    }
3938
 
3939
  /* Note that for some reason, a spurious space is tacked
3940
     onto the end of the args in some (at least one anyway)
3941
     implementations, so strip it off if it exists.  */
3942
 
3943
  {
3944
    char *command = elf_tdata (abfd)->core_command;
3945
    int n = strlen (command);
3946
 
3947
    if (0 < n && command[n - 1] == ' ')
3948
      command[n - 1] = '\0';
3949
  }
3950
 
3951
  return TRUE;
3952
}
3953
 
3954
 
3955
/* Score BFD functions.  */
3956
static reloc_howto_type *
3957
s3_elf32_score_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
3958
{
3959
  unsigned int i;
3960
 
3961
  for (i = 0; i < ARRAY_SIZE (elf32_score_reloc_map); i++)
3962
    if (elf32_score_reloc_map[i].bfd_reloc_val == code)
3963
      return &elf32_score_howto_table[elf32_score_reloc_map[i].elf_reloc_val];
3964
 
3965
  return NULL;
3966
}
3967
 
3968
static reloc_howto_type *
3969
elf32_score_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
3970
                               const char *r_name)
3971
{
3972
  unsigned int i;
3973
 
3974
  for (i = 0;
3975
       i < (sizeof (elf32_score_howto_table)
3976
            / sizeof (elf32_score_howto_table[0]));
3977
       i++)
3978
    if (elf32_score_howto_table[i].name != NULL
3979
        && strcasecmp (elf32_score_howto_table[i].name, r_name) == 0)
3980
      return &elf32_score_howto_table[i];
3981
 
3982
  return NULL;
3983
}
3984
 
3985
static bfd_boolean
3986
s3_elf32_score_print_private_bfd_data (bfd *abfd, void * ptr)
3987
{
3988
  FILE *file = (FILE *) ptr;
3989
 
3990
  BFD_ASSERT (abfd != NULL && ptr != NULL);
3991
 
3992
  /* Print normal ELF private data.  */
3993
  _bfd_elf_print_private_bfd_data (abfd, ptr);
3994
 
3995
  /* xgettext:c-format */
3996
  fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
3997
  if (elf_elfheader (abfd)->e_flags & EF_SCORE_PIC)
3998
    {
3999
      fprintf (file, _(" [pic]"));
4000
    }
4001
  if (elf_elfheader (abfd)->e_flags & EF_SCORE_FIXDEP)
4002
    {
4003
      fprintf (file, _(" [fix dep]"));
4004
    }
4005
  fputc ('\n', file);
4006
 
4007
  return TRUE;
4008
}
4009
 
4010
static bfd_boolean
4011
s3_elf32_score_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
4012
{
4013
  flagword in_flags;
4014
  flagword out_flags;
4015
 
4016
  if (!_bfd_generic_verify_endian_match (ibfd, obfd))
4017
    return FALSE;
4018
 
4019
  in_flags  = elf_elfheader (ibfd)->e_flags;
4020
  out_flags = elf_elfheader (obfd)->e_flags;
4021
 
4022
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
4023
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
4024
    return TRUE;
4025
 
4026
  in_flags = elf_elfheader (ibfd)->e_flags;
4027
  out_flags = elf_elfheader (obfd)->e_flags;
4028
 
4029
  if (! elf_flags_init (obfd))
4030
    {
4031
      elf_flags_init (obfd) = TRUE;
4032
      elf_elfheader (obfd)->e_flags = in_flags;
4033
 
4034
      if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
4035
          && bfd_get_arch_info (obfd)->the_default)
4036
        {
4037
          return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
4038
        }
4039
 
4040
      return TRUE;
4041
    }
4042
 
4043
  if (((in_flags & EF_SCORE_PIC) != 0) != ((out_flags & EF_SCORE_PIC) != 0))
4044
    {
4045
      (*_bfd_error_handler) (_("%B: warning: linking PIC files with non-PIC files"), ibfd);
4046
    }
4047
 
4048
  /* FIXME: Maybe dependency fix compatibility should be checked here.  */
4049
 
4050
  return TRUE;
4051
}
4052
 
4053
static bfd_boolean
4054
s3_elf32_score_new_section_hook (bfd *abfd, asection *sec)
4055
{
4056
  struct _score_elf_section_data *sdata;
4057
  bfd_size_type amt = sizeof (*sdata);
4058
 
4059
  sdata = bfd_zalloc (abfd, amt);
4060
  if (sdata == NULL)
4061
    return FALSE;
4062
  sec->used_by_bfd = sdata;
4063
 
4064
  return _bfd_elf_new_section_hook (abfd, sec);
4065
}
4066
 
4067
/*****************************************************************************/
4068
 
4069
/* s3_s7: backend hooks.  */
4070
static void
4071
_bfd_score_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
4072
                          arelent *bfd_reloc,
4073
                          Elf_Internal_Rela *elf_reloc)
4074
{
4075
  if (bfd_get_mach (abfd) == bfd_mach_score3)
4076
    return s3_bfd_score_info_to_howto (abfd, bfd_reloc, elf_reloc);
4077
  else
4078
    return s7_bfd_score_info_to_howto (abfd, bfd_reloc, elf_reloc);
4079
}
4080
 
4081
static bfd_boolean
4082
_bfd_score_elf_relocate_section (bfd *output_bfd,
4083
                                 struct bfd_link_info *info,
4084
                                 bfd *input_bfd,
4085
                                 asection *input_section,
4086
                                 bfd_byte *contents,
4087
                                 Elf_Internal_Rela *relocs,
4088
                                 Elf_Internal_Sym *local_syms,
4089
                                 asection **local_sections)
4090
{
4091
  if (bfd_get_mach (output_bfd) == bfd_mach_score3)
4092
    return s3_bfd_score_elf_relocate_section (output_bfd,
4093
             info, input_bfd, input_section, contents, relocs,
4094
             local_syms, local_sections);
4095
  else
4096
    return s7_bfd_score_elf_relocate_section (output_bfd,
4097
             info, input_bfd, input_section, contents, relocs,
4098
             local_syms, local_sections);
4099
}
4100
 
4101
static bfd_boolean
4102
_bfd_score_elf_check_relocs (bfd *abfd,
4103
                             struct bfd_link_info *info,
4104
                             asection *sec,
4105
                             const Elf_Internal_Rela *relocs)
4106
{
4107
  if (bfd_get_mach (abfd) == bfd_mach_score3)
4108
    return s3_bfd_score_elf_check_relocs (abfd, info, sec, relocs);
4109
  else
4110
    return s7_bfd_score_elf_check_relocs (abfd, info, sec, relocs);
4111
}
4112
 
4113
static bfd_boolean
4114
_bfd_score_elf_add_symbol_hook (bfd *abfd,
4115
                                struct bfd_link_info *info ATTRIBUTE_UNUSED,
4116
                                Elf_Internal_Sym *sym,
4117
                                const char **namep ATTRIBUTE_UNUSED,
4118
                                flagword *flagsp ATTRIBUTE_UNUSED,
4119
                                asection **secp,
4120
                                bfd_vma *valp)
4121
{
4122
  if (bfd_get_mach (abfd) == bfd_mach_score3)
4123
    return s3_bfd_score_elf_add_symbol_hook (abfd, info, sym, namep, flagsp,
4124
                                             secp, valp);
4125
  else
4126
    return s7_bfd_score_elf_add_symbol_hook (abfd, info, sym, namep, flagsp,
4127
                                             secp, valp);
4128
}
4129
 
4130
static void
4131
_bfd_score_elf_symbol_processing (bfd *abfd, asymbol *asym)
4132
{
4133
  if (bfd_get_mach (abfd) == bfd_mach_score3)
4134
    return s3_bfd_score_elf_symbol_processing (abfd, asym);
4135
  else
4136
    return s7_bfd_score_elf_symbol_processing (abfd, asym);
4137
}
4138
 
4139
static int
4140
_bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
4141
     const char *name ATTRIBUTE_UNUSED,
4142
     Elf_Internal_Sym *sym,
4143
     asection *input_sec,
4144
     struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
4145
{
4146
  /* If link a empty .o, then this filed is NULL.  */
4147
  if (info->input_bfds == NULL)
4148
    {
4149
      /* If we see a common symbol, which implies a relocatable link, then
4150
         if a symbol was small common in an input file, mark it as small
4151
         common in the output file.  */
4152
      if (sym->st_shndx == SHN_COMMON && strcmp (input_sec->name, ".scommon") == 0)
4153
        sym->st_shndx = SHN_SCORE_SCOMMON;
4154
      return 1;
4155
    }
4156
 
4157
  if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
4158
    return s3_bfd_score_elf_link_output_symbol_hook (info, name, sym, input_sec, h);
4159
  else
4160
    return s7_bfd_score_elf_link_output_symbol_hook (info, name, sym, input_sec, h);
4161
}
4162
 
4163
static bfd_boolean
4164
_bfd_score_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
4165
                                         asection *sec,
4166
                                         int *retval)
4167
{
4168
  if (bfd_get_mach (abfd) == bfd_mach_score3)
4169
    return s3_bfd_score_elf_section_from_bfd_section (abfd, sec, retval);
4170
  else
4171
    return s7_bfd_score_elf_section_from_bfd_section (abfd, sec, retval);
4172
}
4173
 
4174
static bfd_boolean
4175
_bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
4176
                                      struct elf_link_hash_entry *h)
4177
{
4178
  if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
4179
    return s3_bfd_score_elf_adjust_dynamic_symbol (info, h);
4180
  else
4181
    return s7_bfd_score_elf_adjust_dynamic_symbol (info, h);
4182
}
4183
 
4184
static bfd_boolean
4185
_bfd_score_elf_always_size_sections (bfd *output_bfd,
4186
                                     struct bfd_link_info *info)
4187
{
4188
  if (bfd_get_mach (output_bfd) == bfd_mach_score3)
4189
    return s3_bfd_score_elf_always_size_sections (output_bfd, info);
4190
  else
4191
    return s7_bfd_score_elf_always_size_sections (output_bfd, info);
4192
}
4193
 
4194
static bfd_boolean
4195
_bfd_score_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
4196
{
4197
  if (bfd_get_mach (output_bfd) == bfd_mach_score3)
4198
    return s3_bfd_score_elf_size_dynamic_sections (output_bfd, info);
4199
  else
4200
    return s7_bfd_score_elf_size_dynamic_sections (output_bfd, info);
4201
}
4202
 
4203
static bfd_boolean
4204
_bfd_score_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
4205
{
4206
  if (bfd_get_mach (abfd) == bfd_mach_score3)
4207
    return s3_bfd_score_elf_create_dynamic_sections (abfd, info);
4208
  else
4209
    return s7_bfd_score_elf_create_dynamic_sections (abfd, info);
4210
}
4211
 
4212
static bfd_boolean
4213
_bfd_score_elf_finish_dynamic_symbol (bfd *output_bfd,
4214
                                      struct bfd_link_info *info,
4215
                                      struct elf_link_hash_entry *h,
4216
                                      Elf_Internal_Sym *sym)
4217
{
4218
  if (bfd_get_mach (output_bfd) == bfd_mach_score3)
4219
    return s3_bfd_score_elf_finish_dynamic_symbol (output_bfd, info, h, sym);
4220
  else
4221
    return s7_bfd_score_elf_finish_dynamic_symbol (output_bfd, info, h, sym);
4222
}
4223
 
4224
static bfd_boolean
4225
_bfd_score_elf_finish_dynamic_sections (bfd *output_bfd,
4226
                                        struct bfd_link_info *info)
4227
{
4228
  if (bfd_get_mach (output_bfd) == bfd_mach_score3)
4229
    return s3_bfd_score_elf_finish_dynamic_sections (output_bfd, info);
4230
  else
4231
    return s7_bfd_score_elf_finish_dynamic_sections (output_bfd, info);
4232
}
4233
 
4234
static bfd_boolean
4235
_bfd_score_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
4236
                              Elf_Internal_Shdr *hdr,
4237
                              asection *sec)
4238
{
4239
  if (bfd_get_mach (abfd) == bfd_mach_score3)
4240
    return s3_bfd_score_elf_fake_sections (abfd, hdr, sec);
4241
  else
4242
    return s7_bfd_score_elf_fake_sections (abfd, hdr, sec);
4243
}
4244
 
4245
static bfd_boolean
4246
_bfd_score_elf_section_processing (bfd *abfd ATTRIBUTE_UNUSED, Elf_Internal_Shdr *hdr)
4247
{
4248
  if (bfd_get_mach (abfd) == bfd_mach_score3)
4249
    return s3_bfd_score_elf_section_processing (abfd, hdr);
4250
  else
4251
    return s7_bfd_score_elf_section_processing (abfd, hdr);
4252
}
4253
 
4254
static bfd_boolean
4255
_bfd_score_elf_write_section (bfd *output_bfd,
4256
                              struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
4257
                              asection *sec, bfd_byte *contents)
4258
{
4259
  if (bfd_get_mach (output_bfd) == bfd_mach_score3)
4260
    return s3_bfd_score_elf_write_section (output_bfd, sec, contents);
4261
  else
4262
    return s7_bfd_score_elf_write_section (output_bfd, sec, contents);
4263
}
4264
 
4265
static void
4266
_bfd_score_elf_copy_indirect_symbol (struct bfd_link_info *info,
4267
                                     struct elf_link_hash_entry *dir,
4268
                                     struct elf_link_hash_entry *ind)
4269
{
4270
  if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
4271
    return s3_bfd_score_elf_copy_indirect_symbol (info, dir, ind);
4272
  else
4273
    return s7_bfd_score_elf_copy_indirect_symbol (info, dir, ind);
4274
}
4275
 
4276
static void
4277
_bfd_score_elf_hide_symbol (struct bfd_link_info *info,
4278
                            struct elf_link_hash_entry *entry,
4279
                            bfd_boolean force_local)
4280
{
4281
  if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
4282
    return s3_bfd_score_elf_hide_symbol (info, entry, force_local);
4283
  else
4284
    return s7_bfd_score_elf_hide_symbol (info, entry, force_local);
4285
}
4286
 
4287
static bfd_boolean
4288
_bfd_score_elf_discard_info (bfd *abfd, struct elf_reloc_cookie *cookie,
4289
                         struct bfd_link_info *info)
4290
{
4291
  if (bfd_get_mach (abfd) == bfd_mach_score3)
4292
    return s3_bfd_score_elf_discard_info (abfd, cookie, info);
4293
  else
4294
    return s7_bfd_score_elf_discard_info (abfd, cookie, info);
4295
}
4296
 
4297
static bfd_boolean
4298
_bfd_score_elf_ignore_discarded_relocs (asection *sec)
4299
{
4300
  if (bfd_get_mach (sec->owner) == bfd_mach_score3)
4301
    return s3_bfd_score_elf_ignore_discarded_relocs (sec);
4302
  else
4303
    return s7_bfd_score_elf_ignore_discarded_relocs (sec);
4304
}
4305
 
4306
static asection *
4307
_bfd_score_elf_gc_mark_hook (asection *sec,
4308
                             struct bfd_link_info *info,
4309
                             Elf_Internal_Rela *rel,
4310
                             struct elf_link_hash_entry *h,
4311
                             Elf_Internal_Sym *sym)
4312
{
4313
  if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
4314
    return s3_bfd_score_elf_gc_mark_hook (sec, info, rel, h, sym);
4315
  else
4316
    return s7_bfd_score_elf_gc_mark_hook (sec, info, rel, h, sym);
4317
}
4318
 
4319
static bfd_boolean
4320
_bfd_score_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
4321
{
4322
  if (bfd_get_mach (abfd) == bfd_mach_score3)
4323
    return s3_bfd_score_elf_grok_prstatus (abfd, note);
4324
  else
4325
    return s7_bfd_score_elf_grok_prstatus (abfd, note);
4326
}
4327
 
4328
static bfd_boolean
4329
_bfd_score_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
4330
{
4331
  if (bfd_get_mach (abfd) == bfd_mach_score3)
4332
    return s3_bfd_score_elf_grok_psinfo (abfd, note);
4333
  else
4334
    return s7_bfd_score_elf_grok_psinfo (abfd, note);
4335
}
4336
 
4337
static reloc_howto_type *
4338
elf32_score_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
4339
{
4340
  /* s3: NOTE!!!
4341
     gas will call elf32_score_reloc_type_lookup, and don't write elf file.
4342
     So just using score3, but we don't know ld will call this or not.
4343
     If so, this way can't work.  */
4344
 
4345
  if (score3)
4346
    return s3_elf32_score_reloc_type_lookup (abfd, code);
4347
  else
4348
    return s7_elf32_score_reloc_type_lookup (abfd, code);
4349
}
4350
 
4351
/* Create a score elf linker hash table.
4352
   This is a copy of _bfd_elf_link_hash_table_create() except with a
4353
   different hash table entry creation function.  */
4354
 
4355
static struct bfd_link_hash_table *
4356
elf32_score_link_hash_table_create (bfd *abfd)
4357
{
4358
  struct elf_link_hash_table *ret;
4359
  bfd_size_type amt = sizeof (struct elf_link_hash_table);
4360
 
4361
  ret = (struct elf_link_hash_table *) bfd_malloc (amt);
4362
  if (ret == NULL)
4363
    return NULL;
4364
 
4365
  if (!_bfd_elf_link_hash_table_init (ret, abfd, score_elf_link_hash_newfunc,
4366
                                      sizeof (struct score_elf_link_hash_entry),
4367
                                      GENERIC_ELF_DATA))
4368
    {
4369
      free (ret);
4370
      return NULL;
4371
    }
4372
 
4373
  return &ret->root;
4374
}
4375
 
4376
static bfd_boolean
4377
elf32_score_print_private_bfd_data (bfd *abfd, void * ptr)
4378
{
4379
  if (bfd_get_mach (abfd) == bfd_mach_score3)
4380
    return s3_elf32_score_print_private_bfd_data (abfd, ptr);
4381
  else
4382
    return s7_elf32_score_print_private_bfd_data (abfd, ptr);
4383
}
4384
 
4385
static bfd_boolean
4386
elf32_score_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
4387
{
4388
  if (bfd_get_mach (obfd) == bfd_mach_score3)
4389
    return s3_elf32_score_merge_private_bfd_data (ibfd, obfd);
4390
  else
4391
    return s7_elf32_score_merge_private_bfd_data (ibfd, obfd);
4392
}
4393
 
4394
static bfd_boolean
4395
elf32_score_new_section_hook (bfd *abfd, asection *sec)
4396
{
4397
  if (bfd_get_mach (abfd) == bfd_mach_score3)
4398
    return s3_elf32_score_new_section_hook (abfd, sec);
4399
  else
4400
    return s7_elf32_score_new_section_hook (abfd, sec);
4401
}
4402
 
4403
 
4404
/* s3_s7: don't need to split.  */
4405
 
4406
/* Set the right machine number.  */
4407
static bfd_boolean
4408
_bfd_score_elf_score_object_p (bfd * abfd)
4409
{
4410
  int e_set = bfd_mach_score7;
4411
 
4412
  if (elf_elfheader (abfd)->e_machine == EM_SCORE)
4413
    {
4414
      int e_mach = elf_elfheader (abfd)->e_flags & EF_SCORE_MACH & EF_OMIT_PIC_FIXDD;
4415
      switch (e_mach)
4416
        {
4417
        /* Set default target is score7.  */
4418
        default:
4419
        case E_SCORE_MACH_SCORE7:
4420
          e_set = bfd_mach_score7;
4421
          break;
4422
 
4423
        case E_SCORE_MACH_SCORE3:
4424
          e_set = bfd_mach_score3;
4425
          break;
4426
        }
4427
    }
4428
 
4429
  return bfd_default_set_arch_mach (abfd, bfd_arch_score, e_set);
4430
}
4431
 
4432
bfd_boolean
4433
_bfd_score_elf_common_definition (Elf_Internal_Sym *sym)
4434
{
4435
  return (sym->st_shndx == SHN_COMMON || sym->st_shndx == SHN_SCORE_SCOMMON);
4436
}
4437
 
4438
/*****************************************************************************/
4439
 
4440
 
4441
#define USE_REL                         1
4442
#define TARGET_LITTLE_SYM               bfd_elf32_littlescore_vec
4443
#define TARGET_LITTLE_NAME              "elf32-littlescore"
4444
#define TARGET_BIG_SYM                  bfd_elf32_bigscore_vec
4445
#define TARGET_BIG_NAME                 "elf32-bigscore"
4446
#define ELF_ARCH                        bfd_arch_score
4447
#define ELF_MACHINE_CODE                EM_SCORE
4448
#define ELF_MACHINE_ALT1                EM_SCORE_OLD
4449
#define ELF_MAXPAGESIZE                 0x8000
4450
 
4451
#define elf_info_to_howto               0
4452
#define elf_info_to_howto_rel           _bfd_score_info_to_howto
4453
#define elf_backend_relocate_section    _bfd_score_elf_relocate_section
4454
#define elf_backend_check_relocs        _bfd_score_elf_check_relocs
4455
#define elf_backend_add_symbol_hook     _bfd_score_elf_add_symbol_hook
4456
#define elf_backend_symbol_processing   _bfd_score_elf_symbol_processing
4457
#define elf_backend_link_output_symbol_hook \
4458
  _bfd_score_elf_link_output_symbol_hook
4459
#define elf_backend_section_from_bfd_section \
4460
  _bfd_score_elf_section_from_bfd_section
4461
#define elf_backend_adjust_dynamic_symbol \
4462
  _bfd_score_elf_adjust_dynamic_symbol
4463
#define elf_backend_always_size_sections \
4464
  _bfd_score_elf_always_size_sections
4465
#define elf_backend_size_dynamic_sections \
4466
  _bfd_score_elf_size_dynamic_sections
4467
#define elf_backend_omit_section_dynsym \
4468
  ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
4469
#define elf_backend_create_dynamic_sections \
4470
  _bfd_score_elf_create_dynamic_sections
4471
#define elf_backend_finish_dynamic_symbol \
4472
  _bfd_score_elf_finish_dynamic_symbol
4473
#define elf_backend_finish_dynamic_sections \
4474
  _bfd_score_elf_finish_dynamic_sections
4475
#define elf_backend_fake_sections         _bfd_score_elf_fake_sections
4476
#define elf_backend_section_processing    _bfd_score_elf_section_processing
4477
#define elf_backend_write_section         _bfd_score_elf_write_section
4478
#define elf_backend_copy_indirect_symbol  _bfd_score_elf_copy_indirect_symbol
4479
#define elf_backend_hide_symbol           _bfd_score_elf_hide_symbol
4480
#define elf_backend_discard_info          _bfd_score_elf_discard_info
4481
#define elf_backend_ignore_discarded_relocs \
4482
  _bfd_score_elf_ignore_discarded_relocs
4483
#define elf_backend_gc_mark_hook          _bfd_score_elf_gc_mark_hook
4484
#define elf_backend_grok_prstatus         _bfd_score_elf_grok_prstatus
4485
#define elf_backend_grok_psinfo           _bfd_score_elf_grok_psinfo
4486
#define elf_backend_can_gc_sections       1
4487
#define elf_backend_want_plt_sym          0
4488
#define elf_backend_got_header_size       (4 * SCORE_RESERVED_GOTNO)
4489
#define elf_backend_plt_header_size       0
4490
#define elf_backend_collect               TRUE
4491
#define elf_backend_type_change_ok        TRUE
4492
#define elf_backend_object_p                  _bfd_score_elf_score_object_p
4493
 
4494
#define bfd_elf32_bfd_reloc_type_lookup      elf32_score_reloc_type_lookup
4495
#define bfd_elf32_bfd_reloc_name_lookup \
4496
  elf32_score_reloc_name_lookup
4497
#define bfd_elf32_bfd_link_hash_table_create elf32_score_link_hash_table_create
4498
#define bfd_elf32_bfd_print_private_bfd_data elf32_score_print_private_bfd_data
4499
#define bfd_elf32_bfd_merge_private_bfd_data elf32_score_merge_private_bfd_data
4500
#define bfd_elf32_new_section_hook           elf32_score_new_section_hook
4501
 
4502
#include "elf32-target.h"

powered by: WebSVN 2.1.0

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