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 148

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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