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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [bfd/] [elf32-score7.c] - Blame information for rev 859

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

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

powered by: WebSVN 2.1.0

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