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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [bfd/] [elf32-score.c] - Blame information for rev 231

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

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

powered by: WebSVN 2.1.0

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