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

Subversion Repositories open8_urisc

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

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

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