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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [bfd/] [elf32-score7.c] - Blame information for rev 841

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/* 32-bit ELF support for S+core.
2
   Copyright 2009, 2010 Free Software Foundation, Inc.
3
   Contributed by
4
   Brain.lin (brain.lin@sunplusct.com)
5
   Mei Ligang (ligang@sunnorth.com.cn)
6
   Pei-Lin Tsai (pltsai@sunplus.com)
7
 
8
   This file is part of BFD, the Binary File Descriptor library.
9
 
10
   This program is free software; you can redistribute it and/or modify
11
   it under the terms of the GNU General Public License as published by
12
   the Free Software Foundation; either version 3 of the License, or
13
   (at your option) any later version.
14
 
15
   This program is distributed in the hope that it will be useful,
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
   GNU General Public License for more details.
19
 
20
   You should have received a copy of the GNU General Public License
21
   along with this program; if not, write to the Free Software
22
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
23
   MA 02110-1301, USA.  */
24
 
25
#include "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
  if (h->root.root.type == bfd_link_hash_warning)
924
    h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
925
 
926
  /* Symbols without dynamic symbol table entries aren't interesting at all.  */
927
  if (h->root.dynindx == -1)
928
    return TRUE;
929
 
930
  /* Global symbols that need GOT entries that are not explicitly
931
     referenced are marked with got offset 2.  Those that are
932
     referenced get a 1, and those that don't need GOT entries get
933
     -1.  */
934
  if (h->root.got.offset == 2)
935
    {
936
      if (hsd->max_unref_got_dynindx == hsd->min_got_dynindx)
937
        hsd->low = (struct elf_link_hash_entry *) h;
938
      h->root.dynindx = hsd->max_unref_got_dynindx++;
939
    }
940
  else if (h->root.got.offset != 1)
941
    h->root.dynindx = hsd->max_non_got_dynindx++;
942
  else
943
    {
944
      h->root.dynindx = --hsd->min_got_dynindx;
945
      hsd->low = (struct elf_link_hash_entry *) h;
946
    }
947
 
948
  return TRUE;
949
}
950
 
951
static asection *
952
score_elf_got_section (bfd *abfd, bfd_boolean maybe_excluded)
953
{
954
  asection *sgot = bfd_get_section_by_name (abfd, ".got");
955
 
956
  if (sgot == NULL || (! maybe_excluded && (sgot->flags & SEC_EXCLUDE) != 0))
957
    return NULL;
958
  return sgot;
959
}
960
 
961
/* Returns the GOT information associated with the link indicated by
962
   INFO.  If SGOTP is non-NULL, it is filled in with the GOT section.  */
963
 
964
static struct score_got_info *
965
score_elf_got_info (bfd *abfd, asection **sgotp)
966
{
967
  asection *sgot;
968
  struct score_got_info *g;
969
 
970
  sgot = score_elf_got_section (abfd, TRUE);
971
  BFD_ASSERT (sgot != NULL);
972
  BFD_ASSERT (elf_section_data (sgot) != NULL);
973
  g = score_elf_section_data (sgot)->u.got_info;
974
  BFD_ASSERT (g != NULL);
975
 
976
  if (sgotp)
977
    *sgotp = sgot;
978
  return g;
979
}
980
 
981
/* Sort the dynamic symbol table so that symbols that need GOT entries
982
   appear towards the end.  This reduces the amount of GOT space
983
   required.  MAX_LOCAL is used to set the number of local symbols
984
   known to be in the dynamic symbol table.  During
985
   s7_bfd_score_elf_size_dynamic_sections, this value is 1.  Afterward, the
986
   section symbols are added and the count is higher.  */
987
 
988
static bfd_boolean
989
score_elf_sort_hash_table (struct bfd_link_info *info,
990
                           unsigned long max_local)
991
{
992
  struct score_elf_hash_sort_data hsd;
993
  struct score_got_info *g;
994
  bfd *dynobj;
995
 
996
  dynobj = elf_hash_table (info)->dynobj;
997
 
998
  g = score_elf_got_info (dynobj, NULL);
999
 
1000
  hsd.low = NULL;
1001
  hsd.max_unref_got_dynindx =
1002
    hsd.min_got_dynindx = elf_hash_table (info)->dynsymcount
1003
    /* In the multi-got case, assigned_gotno of the master got_info
1004
       indicate the number of entries that aren't referenced in the
1005
       primary GOT, but that must have entries because there are
1006
       dynamic relocations that reference it.  Since they aren't
1007
       referenced, we move them to the end of the GOT, so that they
1008
       don't prevent other entries that are referenced from getting
1009
       too large offsets.  */
1010
    - (g->next ? g->assigned_gotno : 0);
1011
  hsd.max_non_got_dynindx = max_local;
1012
  score_elf_link_hash_traverse (elf_hash_table (info),
1013
                                score_elf_sort_hash_table_f,
1014
                                &hsd);
1015
 
1016
  /* There should have been enough room in the symbol table to
1017
     accommodate both the GOT and non-GOT symbols.  */
1018
  BFD_ASSERT (hsd.max_non_got_dynindx <= hsd.min_got_dynindx);
1019
  BFD_ASSERT ((unsigned long) hsd.max_unref_got_dynindx
1020
              <= elf_hash_table (info)->dynsymcount);
1021
 
1022
  /* Now we know which dynamic symbol has the lowest dynamic symbol
1023
     table index in the GOT.  */
1024
  g->global_gotsym = hsd.low;
1025
 
1026
  return TRUE;
1027
}
1028
 
1029
/* Returns the first relocation of type r_type found, beginning with
1030
   RELOCATION.  RELEND is one-past-the-end of the relocation table.  */
1031
 
1032
static const Elf_Internal_Rela *
1033
score_elf_next_relocation (bfd *abfd ATTRIBUTE_UNUSED, unsigned int r_type,
1034
                           const Elf_Internal_Rela *relocation,
1035
                           const Elf_Internal_Rela *relend)
1036
{
1037
  while (relocation < relend)
1038
    {
1039
      if (ELF32_R_TYPE (relocation->r_info) == r_type)
1040
        return relocation;
1041
 
1042
      ++relocation;
1043
    }
1044
 
1045
  /* We didn't find it.  */
1046
  bfd_set_error (bfd_error_bad_value);
1047
  return NULL;
1048
}
1049
 
1050
/* This function is called via qsort() to sort the dynamic relocation
1051
   entries by increasing r_symndx value.  */
1052
static int
1053
score_elf_sort_dynamic_relocs (const void *arg1, const void *arg2)
1054
{
1055
  Elf_Internal_Rela int_reloc1;
1056
  Elf_Internal_Rela int_reloc2;
1057
 
1058
  bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg1, &int_reloc1);
1059
  bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg2, &int_reloc2);
1060
 
1061
  return (ELF32_R_SYM (int_reloc1.r_info) - ELF32_R_SYM (int_reloc2.r_info));
1062
}
1063
 
1064
/* Return whether a relocation is against a local symbol.  */
1065
static bfd_boolean
1066
score_elf_local_relocation_p (bfd *input_bfd,
1067
                              const Elf_Internal_Rela *relocation,
1068
                              asection **local_sections,
1069
                              bfd_boolean check_forced)
1070
{
1071
  unsigned long r_symndx;
1072
  Elf_Internal_Shdr *symtab_hdr;
1073
  struct score_elf_link_hash_entry *h;
1074
  size_t extsymoff;
1075
 
1076
  r_symndx = ELF32_R_SYM (relocation->r_info);
1077
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1078
  extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
1079
 
1080
  if (r_symndx < extsymoff)
1081
    return TRUE;
1082
  if (elf_bad_symtab (input_bfd) && local_sections[r_symndx] != NULL)
1083
    return TRUE;
1084
 
1085
  if (check_forced)
1086
    {
1087
      /* Look up the hash table to check whether the symbol was forced local.  */
1088
      h = (struct score_elf_link_hash_entry *)
1089
        elf_sym_hashes (input_bfd) [r_symndx - extsymoff];
1090
      /* Find the real hash-table entry for this symbol.  */
1091
      while (h->root.root.type == bfd_link_hash_indirect
1092
             || h->root.root.type == bfd_link_hash_warning)
1093
        h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
1094
      if (h->root.forced_local)
1095
        return TRUE;
1096
    }
1097
 
1098
  return FALSE;
1099
}
1100
 
1101
/* Returns the dynamic relocation section for DYNOBJ.  */
1102
 
1103
static asection *
1104
score_elf_rel_dyn_section (bfd *dynobj, bfd_boolean create_p)
1105
{
1106
  static const char dname[] = ".rel.dyn";
1107
  asection *sreloc;
1108
 
1109
  sreloc = bfd_get_section_by_name (dynobj, dname);
1110
  if (sreloc == NULL && create_p)
1111
    {
1112
      sreloc = bfd_make_section_with_flags (dynobj, dname,
1113
                                            (SEC_ALLOC
1114
                                             | SEC_LOAD
1115
                                             | SEC_HAS_CONTENTS
1116
                                             | SEC_IN_MEMORY
1117
                                             | SEC_LINKER_CREATED
1118
                                             | SEC_READONLY));
1119
      if (sreloc == NULL
1120
          || ! bfd_set_section_alignment (dynobj, sreloc,
1121
                                          SCORE_ELF_LOG_FILE_ALIGN (dynobj)))
1122
        return NULL;
1123
    }
1124
  return sreloc;
1125
}
1126
 
1127
static void
1128
score_elf_allocate_dynamic_relocations (bfd *abfd, unsigned int n)
1129
{
1130
  asection *s;
1131
 
1132
  s = score_elf_rel_dyn_section (abfd, FALSE);
1133
  BFD_ASSERT (s != NULL);
1134
 
1135
  if (s->size == 0)
1136
    {
1137
      /* Make room for a null element.  */
1138
      s->size += SCORE_ELF_REL_SIZE (abfd);
1139
      ++s->reloc_count;
1140
    }
1141
  s->size += n * SCORE_ELF_REL_SIZE (abfd);
1142
}
1143
 
1144
/* Create a rel.dyn relocation for the dynamic linker to resolve.  REL
1145
   is the original relocation, which is now being transformed into a
1146
   dynamic relocation.  The ADDENDP is adjusted if necessary; the
1147
   caller should store the result in place of the original addend.  */
1148
 
1149
static bfd_boolean
1150
score_elf_create_dynamic_relocation (bfd *output_bfd,
1151
                                     struct bfd_link_info *info,
1152
                                     const Elf_Internal_Rela *rel,
1153
                                     struct score_elf_link_hash_entry *h,
1154
                                     bfd_vma symbol,
1155
                                     bfd_vma *addendp, asection *input_section)
1156
{
1157
  Elf_Internal_Rela outrel[3];
1158
  asection *sreloc;
1159
  bfd *dynobj;
1160
  int r_type;
1161
  long indx;
1162
  bfd_boolean defined_p;
1163
 
1164
  r_type = ELF32_R_TYPE (rel->r_info);
1165
  dynobj = elf_hash_table (info)->dynobj;
1166
  sreloc = score_elf_rel_dyn_section (dynobj, FALSE);
1167
  BFD_ASSERT (sreloc != NULL);
1168
  BFD_ASSERT (sreloc->contents != NULL);
1169
  BFD_ASSERT (sreloc->reloc_count * SCORE_ELF_REL_SIZE (output_bfd) < sreloc->size);
1170
 
1171
  outrel[0].r_offset =
1172
    _bfd_elf_section_offset (output_bfd, info, input_section, rel[0].r_offset);
1173
  outrel[1].r_offset =
1174
    _bfd_elf_section_offset (output_bfd, info, input_section, rel[1].r_offset);
1175
  outrel[2].r_offset =
1176
    _bfd_elf_section_offset (output_bfd, info, input_section, rel[2].r_offset);
1177
 
1178
  if (outrel[0].r_offset == MINUS_ONE)
1179
    /* The relocation field has been deleted.  */
1180
    return TRUE;
1181
 
1182
  if (outrel[0].r_offset == MINUS_TWO)
1183
    {
1184
      /* The relocation field has been converted into a relative value of
1185
         some sort.  Functions like _bfd_elf_write_section_eh_frame expect
1186
         the field to be fully relocated, so add in the symbol's value.  */
1187
      *addendp += symbol;
1188
      return TRUE;
1189
    }
1190
 
1191
  /* We must now calculate the dynamic symbol table index to use
1192
     in the relocation.  */
1193
  if (h != NULL
1194
      && (! info->symbolic || !h->root.def_regular)
1195
      /* h->root.dynindx may be -1 if this symbol was marked to
1196
         become local.  */
1197
      && h->root.dynindx != -1)
1198
    {
1199
      indx = h->root.dynindx;
1200
        /* ??? glibc's ld.so just adds the final GOT entry to the
1201
           relocation field.  It therefore treats relocs against
1202
           defined symbols in the same way as relocs against
1203
           undefined symbols.  */
1204
      defined_p = FALSE;
1205
    }
1206
  else
1207
    {
1208
      indx = 0;
1209
      defined_p = TRUE;
1210
    }
1211
 
1212
  /* If the relocation was previously an absolute relocation and
1213
     this symbol will not be referred to by the relocation, we must
1214
     adjust it by the value we give it in the dynamic symbol table.
1215
     Otherwise leave the job up to the dynamic linker.  */
1216
  if (defined_p && r_type != R_SCORE_REL32)
1217
    *addendp += symbol;
1218
 
1219
  /* The relocation is always an REL32 relocation because we don't
1220
     know where the shared library will wind up at load-time.  */
1221
  outrel[0].r_info = ELF32_R_INFO ((unsigned long) indx, R_SCORE_REL32);
1222
 
1223
  /* For strict adherence to the ABI specification, we should
1224
     generate a R_SCORE_64 relocation record by itself before the
1225
     _REL32/_64 record as well, such that the addend is read in as
1226
     a 64-bit value (REL32 is a 32-bit relocation, after all).
1227
     However, since none of the existing ELF64 SCORE dynamic
1228
     loaders seems to care, we don't waste space with these
1229
     artificial relocations.  If this turns out to not be true,
1230
     score_elf_allocate_dynamic_relocations() should be tweaked so
1231
     as to make room for a pair of dynamic relocations per
1232
     invocation if ABI_64_P, and here we should generate an
1233
     additional relocation record with R_SCORE_64 by itself for a
1234
     NULL symbol before this relocation record.  */
1235
  outrel[1].r_info = ELF32_R_INFO (0, R_SCORE_NONE);
1236
  outrel[2].r_info = ELF32_R_INFO (0, R_SCORE_NONE);
1237
 
1238
  /* Adjust the output offset of the relocation to reference the
1239
     correct location in the output file.  */
1240
  outrel[0].r_offset += (input_section->output_section->vma
1241
                         + input_section->output_offset);
1242
  outrel[1].r_offset += (input_section->output_section->vma
1243
                         + input_section->output_offset);
1244
  outrel[2].r_offset += (input_section->output_section->vma
1245
                         + input_section->output_offset);
1246
 
1247
  /* Put the relocation back out.  We have to use the special
1248
     relocation outputter in the 64-bit case since the 64-bit
1249
     relocation format is non-standard.  */
1250
  bfd_elf32_swap_reloc_out
1251
      (output_bfd, &outrel[0],
1252
       (sreloc->contents + sreloc->reloc_count * sizeof (Elf32_External_Rel)));
1253
 
1254
  /* We've now added another relocation.  */
1255
  ++sreloc->reloc_count;
1256
 
1257
  /* Make sure the output section is writable.  The dynamic linker
1258
     will be writing to it.  */
1259
  elf_section_data (input_section->output_section)->this_hdr.sh_flags |= SHF_WRITE;
1260
 
1261
  return TRUE;
1262
}
1263
 
1264
static bfd_boolean
1265
score_elf_create_got_section (bfd *abfd,
1266
                              struct bfd_link_info *info,
1267
                              bfd_boolean maybe_exclude)
1268
{
1269
  flagword flags;
1270
  asection *s;
1271
  struct elf_link_hash_entry *h;
1272
  struct bfd_link_hash_entry *bh;
1273
  struct score_got_info *g;
1274
  bfd_size_type amt;
1275
 
1276
  /* This function may be called more than once.  */
1277
  s = score_elf_got_section (abfd, TRUE);
1278
  if (s)
1279
    {
1280
      if (! maybe_exclude)
1281
        s->flags &= ~SEC_EXCLUDE;
1282
      return TRUE;
1283
    }
1284
 
1285
  flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
1286
 
1287
  if (maybe_exclude)
1288
    flags |= SEC_EXCLUDE;
1289
 
1290
  /* We have to use an alignment of 2**4 here because this is hardcoded
1291
     in the function stub generation and in the linker script.  */
1292
  s = bfd_make_section_with_flags (abfd, ".got", flags);
1293
   if (s == NULL
1294
      || ! bfd_set_section_alignment (abfd, s, 4))
1295
    return FALSE;
1296
 
1297
  /* Define the symbol _GLOBAL_OFFSET_TABLE_.  We don't do this in the
1298
     linker script because we don't want to define the symbol if we
1299
     are not creating a global offset table.  */
1300
  bh = NULL;
1301
  if (! (_bfd_generic_link_add_one_symbol
1302
         (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s,
1303
          0, NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
1304
    return FALSE;
1305
 
1306
  h = (struct elf_link_hash_entry *) bh;
1307
  h->non_elf = 0;
1308
  h->def_regular = 1;
1309
  h->type = STT_OBJECT;
1310
 
1311
  if (info->shared && ! bfd_elf_link_record_dynamic_symbol (info, h))
1312
    return FALSE;
1313
 
1314
  amt = sizeof (struct score_got_info);
1315
  g = bfd_alloc (abfd, amt);
1316
  if (g == NULL)
1317
    return FALSE;
1318
 
1319
  g->global_gotsym = NULL;
1320
  g->global_gotno = 0;
1321
 
1322
  g->local_gotno = SCORE_RESERVED_GOTNO;
1323
  g->assigned_gotno = SCORE_RESERVED_GOTNO;
1324
  g->next = NULL;
1325
 
1326
  g->got_entries = htab_try_create (1, score_elf_got_entry_hash,
1327
                                    score_elf_got_entry_eq, NULL);
1328
  if (g->got_entries == NULL)
1329
    return FALSE;
1330
  score_elf_section_data (s)->u.got_info = g;
1331
  score_elf_section_data (s)->elf.this_hdr.sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
1332
 
1333
  return TRUE;
1334
}
1335
 
1336
/* Calculate the %high function.  */
1337
 
1338
static bfd_vma
1339
score_elf_high (bfd_vma value)
1340
{
1341
  return ((value + (bfd_vma) 0x8000) >> 16) & 0xffff;
1342
}
1343
 
1344
/* Create a local GOT entry for VALUE.  Return the index of the entry,
1345
   or -1 if it could not be created.  */
1346
 
1347
static struct score_got_entry *
1348
score_elf_create_local_got_entry (bfd *abfd,
1349
                                  bfd *ibfd ATTRIBUTE_UNUSED,
1350
                                  struct score_got_info *gg,
1351
                                  asection *sgot, bfd_vma value,
1352
                                  unsigned long r_symndx ATTRIBUTE_UNUSED,
1353
                                  struct score_elf_link_hash_entry *h ATTRIBUTE_UNUSED,
1354
                                  int r_type ATTRIBUTE_UNUSED)
1355
{
1356
  struct score_got_entry entry, **loc;
1357
  struct score_got_info *g;
1358
 
1359
  entry.abfd = NULL;
1360
  entry.symndx = -1;
1361
  entry.d.address = value;
1362
 
1363
  g = gg;
1364
  loc = (struct score_got_entry **) htab_find_slot (g->got_entries, &entry, INSERT);
1365
  if (*loc)
1366
    return *loc;
1367
 
1368
  entry.gotidx = SCORE_ELF_GOT_SIZE (abfd) * g->assigned_gotno++;
1369
 
1370
  *loc = bfd_alloc (abfd, sizeof entry);
1371
 
1372
  if (! *loc)
1373
    return NULL;
1374
 
1375
  memcpy (*loc, &entry, sizeof entry);
1376
 
1377
  if (g->assigned_gotno >= g->local_gotno)
1378
    {
1379
      (*loc)->gotidx = -1;
1380
      /* We didn't allocate enough space in the GOT.  */
1381
      (*_bfd_error_handler)
1382
        (_("not enough GOT space for local GOT entries"));
1383
      bfd_set_error (bfd_error_bad_value);
1384
      return NULL;
1385
    }
1386
 
1387
  bfd_put_32 (abfd, value, (sgot->contents + entry.gotidx));
1388
 
1389
  return *loc;
1390
}
1391
 
1392
/* Find a GOT entry whose higher-order 16 bits are the same as those
1393
   for value.  Return the index into the GOT for this entry.  */
1394
 
1395
static bfd_vma
1396
score_elf_got16_entry (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
1397
                       bfd_vma value, bfd_boolean external)
1398
{
1399
  asection *sgot;
1400
  struct score_got_info *g;
1401
  struct score_got_entry *entry;
1402
 
1403
  if (!external)
1404
    {
1405
      /* Although the ABI says that it is "the high-order 16 bits" that we
1406
         want, it is really the %high value.  The complete value is
1407
         calculated with a `addiu' of a LO16 relocation, just as with a
1408
         HI16/LO16 pair.  */
1409
      value = score_elf_high (value) << 16;
1410
    }
1411
 
1412
  g = score_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
1413
 
1414
  entry = score_elf_create_local_got_entry (abfd, ibfd, g, sgot, value, 0, NULL,
1415
                                            R_SCORE_GOT15);
1416
  if (entry)
1417
    return entry->gotidx;
1418
  else
1419
    return MINUS_ONE;
1420
}
1421
 
1422
void
1423
s7_bfd_score_elf_hide_symbol (struct bfd_link_info *info,
1424
                              struct elf_link_hash_entry *entry,
1425
                              bfd_boolean force_local)
1426
{
1427
  bfd *dynobj;
1428
  asection *got;
1429
  struct score_got_info *g;
1430
  struct score_elf_link_hash_entry *h;
1431
 
1432
  h = (struct score_elf_link_hash_entry *) entry;
1433
  if (h->forced_local)
1434
    return;
1435
  h->forced_local = TRUE;
1436
 
1437
  dynobj = elf_hash_table (info)->dynobj;
1438
  if (dynobj != NULL && force_local)
1439
    {
1440
      got = score_elf_got_section (dynobj, FALSE);
1441
      if (got == NULL)
1442
        return;
1443
      g = score_elf_section_data (got)->u.got_info;
1444
 
1445
      if (g->next)
1446
        {
1447
          struct score_got_entry e;
1448
          struct score_got_info *gg = g;
1449
 
1450
          /* Since we're turning what used to be a global symbol into a
1451
             local one, bump up the number of local entries of each GOT
1452
             that had an entry for it.  This will automatically decrease
1453
             the number of global entries, since global_gotno is actually
1454
             the upper limit of global entries.  */
1455
          e.abfd = dynobj;
1456
          e.symndx = -1;
1457
          e.d.h = h;
1458
 
1459
          for (g = g->next; g != gg; g = g->next)
1460
            if (htab_find (g->got_entries, &e))
1461
              {
1462
                BFD_ASSERT (g->global_gotno > 0);
1463
                g->local_gotno++;
1464
                g->global_gotno--;
1465
              }
1466
 
1467
          /* If this was a global symbol forced into the primary GOT, we
1468
             no longer need an entry for it.  We can't release the entry
1469
             at this point, but we must at least stop counting it as one
1470
             of the symbols that required a forced got entry.  */
1471
          if (h->root.got.offset == 2)
1472
            {
1473
              BFD_ASSERT (gg->assigned_gotno > 0);
1474
              gg->assigned_gotno--;
1475
            }
1476
        }
1477
      else if (g->global_gotno == 0 && g->global_gotsym == NULL)
1478
        /* If we haven't got through GOT allocation yet, just bump up the
1479
              number of local entries, as this symbol won't be counted as
1480
              global.  */
1481
        g->local_gotno++;
1482
      else if (h->root.got.offset == 1)
1483
        {
1484
          /* If we're past non-multi-GOT allocation and this symbol had
1485
                  been marked for a global got entry, give it a local entry
1486
                  instead.  */
1487
          BFD_ASSERT (g->global_gotno > 0);
1488
          g->local_gotno++;
1489
          g->global_gotno--;
1490
        }
1491
    }
1492
 
1493
  _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
1494
}
1495
 
1496
/* If H is a symbol that needs a global GOT entry, but has a dynamic
1497
   symbol table index lower than any we've seen to date, record it for
1498
   posterity.  */
1499
 
1500
static bfd_boolean
1501
score_elf_record_global_got_symbol (struct elf_link_hash_entry *h,
1502
                                    bfd *abfd,
1503
                                    struct bfd_link_info *info,
1504
                                    struct score_got_info *g)
1505
{
1506
  struct score_got_entry entry, **loc;
1507
 
1508
  /* A global symbol in the GOT must also be in the dynamic symbol table.  */
1509
  if (h->dynindx == -1)
1510
    {
1511
      switch (ELF_ST_VISIBILITY (h->other))
1512
        {
1513
        case STV_INTERNAL:
1514
        case STV_HIDDEN:
1515
          s7_bfd_score_elf_hide_symbol (info, h, TRUE);
1516
          break;
1517
        }
1518
      if (!bfd_elf_link_record_dynamic_symbol (info, h))
1519
        return FALSE;
1520
    }
1521
 
1522
  entry.abfd = abfd;
1523
  entry.symndx = -1;
1524
  entry.d.h = (struct score_elf_link_hash_entry *) h;
1525
 
1526
  loc = (struct score_got_entry **) htab_find_slot (g->got_entries, &entry, INSERT);
1527
 
1528
  /* If we've already marked this entry as needing GOT space, we don't
1529
     need to do it again.  */
1530
  if (*loc)
1531
    return TRUE;
1532
 
1533
  *loc = bfd_alloc (abfd, sizeof entry);
1534
  if (! *loc)
1535
    return FALSE;
1536
 
1537
  entry.gotidx = -1;
1538
 
1539
  memcpy (*loc, &entry, sizeof (entry));
1540
 
1541
  if (h->got.offset != MINUS_ONE)
1542
    return TRUE;
1543
 
1544
  /* By setting this to a value other than -1, we are indicating that
1545
     there needs to be a GOT entry for H.  Avoid using zero, as the
1546
     generic ELF copy_indirect_symbol tests for <= 0.  */
1547
  h->got.offset = 1;
1548
 
1549
  return TRUE;
1550
}
1551
 
1552
/* Reserve space in G for a GOT entry containing the value of symbol
1553
   SYMNDX in input bfd ABDF, plus ADDEND.  */
1554
 
1555
static bfd_boolean
1556
score_elf_record_local_got_symbol (bfd *abfd,
1557
                                   long symndx,
1558
                                   bfd_vma addend,
1559
                                   struct score_got_info *g)
1560
{
1561
  struct score_got_entry entry, **loc;
1562
 
1563
  entry.abfd = abfd;
1564
  entry.symndx = symndx;
1565
  entry.d.addend = addend;
1566
  loc = (struct score_got_entry **) htab_find_slot (g->got_entries, &entry, INSERT);
1567
 
1568
  if (*loc)
1569
    return TRUE;
1570
 
1571
  entry.gotidx = g->local_gotno++;
1572
 
1573
  *loc = bfd_alloc (abfd, sizeof(entry));
1574
  if (! *loc)
1575
    return FALSE;
1576
 
1577
  memcpy (*loc, &entry, sizeof (entry));
1578
 
1579
  return TRUE;
1580
}
1581
 
1582
/* Returns the GOT offset at which the indicated address can be found.
1583
   If there is not yet a GOT entry for this value, create one.
1584
   Returns -1 if no satisfactory GOT offset can be found.  */
1585
 
1586
static bfd_vma
1587
score_elf_local_got_index (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
1588
                           bfd_vma value, unsigned long r_symndx,
1589
                           struct score_elf_link_hash_entry *h, int r_type)
1590
{
1591
  asection *sgot;
1592
  struct score_got_info *g;
1593
  struct score_got_entry *entry;
1594
 
1595
  g = score_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
1596
 
1597
  entry = score_elf_create_local_got_entry (abfd, ibfd, g, sgot, value,
1598
                                             r_symndx, h, r_type);
1599
  if (!entry)
1600
    return MINUS_ONE;
1601
 
1602
  else
1603
    return entry->gotidx;
1604
}
1605
 
1606
/* Returns the GOT index for the global symbol indicated by H.  */
1607
 
1608
static bfd_vma
1609
score_elf_global_got_index (bfd *abfd, struct elf_link_hash_entry *h)
1610
{
1611
  bfd_vma got_index;
1612
  asection *sgot;
1613
  struct score_got_info *g;
1614
  long global_got_dynindx = 0;
1615
 
1616
  g = score_elf_got_info (abfd, &sgot);
1617
  if (g->global_gotsym != NULL)
1618
    global_got_dynindx = g->global_gotsym->dynindx;
1619
 
1620
  /* Once we determine the global GOT entry with the lowest dynamic
1621
     symbol table index, we must put all dynamic symbols with greater
1622
     indices into the GOT.  That makes it easy to calculate the GOT
1623
     offset.  */
1624
  BFD_ASSERT (h->dynindx >= global_got_dynindx);
1625
  got_index = ((h->dynindx - global_got_dynindx + g->local_gotno) * SCORE_ELF_GOT_SIZE (abfd));
1626
  BFD_ASSERT (got_index < sgot->size);
1627
 
1628
  return got_index;
1629
}
1630
 
1631
/* Returns the offset for the entry at the INDEXth position in the GOT.  */
1632
 
1633
static bfd_vma
1634
score_elf_got_offset_from_index (bfd *dynobj,
1635
                                 bfd *output_bfd,
1636
                                 bfd *input_bfd ATTRIBUTE_UNUSED,
1637
                                 bfd_vma got_index)
1638
{
1639
  asection *sgot;
1640
  bfd_vma gp;
1641
 
1642
  score_elf_got_info (dynobj, &sgot);
1643
  gp = _bfd_get_gp_value (output_bfd);
1644
 
1645
  return sgot->output_section->vma + sgot->output_offset + got_index - gp;
1646
}
1647
 
1648
/* Follow indirect and warning hash entries so that each got entry
1649
   points to the final symbol definition.  P must point to a pointer
1650
   to the hash table we're traversing.  Since this traversal may
1651
   modify the hash table, we set this pointer to NULL to indicate
1652
   we've made a potentially-destructive change to the hash table, so
1653
   the traversal must be restarted.  */
1654
 
1655
static int
1656
score_elf_resolve_final_got_entry (void **entryp, void *p)
1657
{
1658
  struct score_got_entry *entry = (struct score_got_entry *) *entryp;
1659
  htab_t got_entries = *(htab_t *) p;
1660
 
1661
  if (entry->abfd != NULL && entry->symndx == -1)
1662
    {
1663
      struct score_elf_link_hash_entry *h = entry->d.h;
1664
 
1665
      while (h->root.root.type == bfd_link_hash_indirect
1666
             || h->root.root.type == bfd_link_hash_warning)
1667
        h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
1668
 
1669
      if (entry->d.h == h)
1670
        return 1;
1671
 
1672
      entry->d.h = h;
1673
 
1674
      /* If we can't find this entry with the new bfd hash, re-insert
1675
         it, and get the traversal restarted.  */
1676
      if (! htab_find (got_entries, entry))
1677
        {
1678
          htab_clear_slot (got_entries, entryp);
1679
          entryp = htab_find_slot (got_entries, entry, INSERT);
1680
          if (! *entryp)
1681
            *entryp = entry;
1682
          /* Abort the traversal, since the whole table may have
1683
             moved, and leave it up to the parent to restart the
1684
             process.  */
1685
          *(htab_t *) p = NULL;
1686
          return 0;
1687
        }
1688
      /* We might want to decrement the global_gotno count, but it's
1689
         either too early or too late for that at this point.  */
1690
    }
1691
 
1692
  return 1;
1693
}
1694
 
1695
/* Turn indirect got entries in a got_entries table into their final locations.  */
1696
 
1697
static void
1698
score_elf_resolve_final_got_entries (struct score_got_info *g)
1699
{
1700
  htab_t got_entries;
1701
 
1702
  do
1703
    {
1704
      got_entries = g->got_entries;
1705
 
1706
      htab_traverse (got_entries,
1707
                     score_elf_resolve_final_got_entry,
1708
                     &got_entries);
1709
    }
1710
  while (got_entries == NULL);
1711
}
1712
 
1713
/* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS. for -r  */
1714
 
1715
static void
1716
score_elf_add_to_rel (bfd *abfd,
1717
                      bfd_byte *address,
1718
                      reloc_howto_type *howto,
1719
                      bfd_signed_vma increment)
1720
{
1721
  bfd_signed_vma addend;
1722
  bfd_vma contents;
1723
  unsigned long offset;
1724
  unsigned long r_type = howto->type;
1725
  unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
1726
 
1727
  contents = bfd_get_32 (abfd, address);
1728
  /* Get the (signed) value from the instruction.  */
1729
  addend = contents & howto->src_mask;
1730
  if (addend & ((howto->src_mask + 1) >> 1))
1731
    {
1732
      bfd_signed_vma mask;
1733
 
1734
      mask = -1;
1735
      mask &= ~howto->src_mask;
1736
      addend |= mask;
1737
    }
1738
  /* Add in the increment, (which is a byte value).  */
1739
  switch (r_type)
1740
    {
1741
    case R_SCORE_PC19:
1742
      offset =
1743
        (((contents & howto->src_mask) & 0x3ff0000) >> 6) | ((contents & howto->src_mask) & 0x3ff);
1744
      offset += increment;
1745
      contents =
1746
        (contents & ~howto->
1747
         src_mask) | (((offset << 6) & howto->src_mask) & 0x3ff0000) | (offset & 0x3ff);
1748
      bfd_put_32 (abfd, contents, address);
1749
      break;
1750
    case R_SCORE_HI16:
1751
      break;
1752
    case R_SCORE_LO16:
1753
      hi16_addend = bfd_get_32 (abfd, address - 4);
1754
      hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
1755
      offset = ((((contents >> 16) & 0x3) << 15) | (contents & 0x7fff)) >> 1;
1756
      offset = (hi16_offset << 16) | (offset & 0xffff);
1757
      uvalue = increment + offset;
1758
      hi16_offset = (uvalue >> 16) << 1;
1759
      hi16_value = (hi16_addend & (~(howto->dst_mask)))
1760
        | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
1761
      bfd_put_32 (abfd, hi16_value, address - 4);
1762
      offset = (uvalue & 0xffff) << 1;
1763
      contents = (contents & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
1764
      bfd_put_32 (abfd, contents, address);
1765
      break;
1766
    case R_SCORE_24:
1767
      offset =
1768
        (((contents & howto->src_mask) >> 1) & 0x1ff8000) | ((contents & howto->src_mask) & 0x7fff);
1769
      offset += increment;
1770
      contents =
1771
        (contents & ~howto->
1772
         src_mask) | (((offset << 1) & howto->src_mask) & 0x3ff0000) | (offset & 0x7fff);
1773
      bfd_put_32 (abfd, contents, address);
1774
      break;
1775
    case R_SCORE16_11:
1776
 
1777
      contents = bfd_get_16 (abfd, address);
1778
      offset = contents & howto->src_mask;
1779
      offset += increment;
1780
      contents = (contents & ~howto->src_mask) | (offset & howto->src_mask);
1781
      bfd_put_16 (abfd, contents, address);
1782
 
1783
      break;
1784
    case R_SCORE16_PC8:
1785
 
1786
      contents = bfd_get_16 (abfd, address);
1787
      offset = (contents & howto->src_mask) + ((increment >> 1) & 0xff);
1788
      contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask);
1789
      bfd_put_16 (abfd, contents, address);
1790
 
1791
      break;
1792
    case R_SCORE_GOT15:
1793
    case R_SCORE_GOT_LO16:
1794
      break;
1795
 
1796
    default:
1797
      addend += increment;
1798
      contents = (contents & ~howto->dst_mask) | (addend & howto->dst_mask);
1799
      bfd_put_32 (abfd, contents, address);
1800
      break;
1801
    }
1802
}
1803
 
1804
/* Perform a relocation as part of a final link.  */
1805
 
1806
static bfd_reloc_status_type
1807
score_elf_final_link_relocate (reloc_howto_type *howto,
1808
                               bfd *input_bfd,
1809
                               bfd *output_bfd,
1810
                               asection *input_section,
1811
                               bfd_byte *contents,
1812
                               Elf_Internal_Rela *rel,
1813
                               Elf_Internal_Rela *relocs,
1814
                               bfd_vma symbol,
1815
                               struct bfd_link_info *info,
1816
                               const char *sym_name ATTRIBUTE_UNUSED,
1817
                               int sym_flags ATTRIBUTE_UNUSED,
1818
                               struct score_elf_link_hash_entry *h,
1819
                               Elf_Internal_Sym *local_syms,
1820
                               asection **local_sections,
1821
                               bfd_boolean gp_disp_p)
1822
{
1823
  unsigned long r_type;
1824
  unsigned long r_symndx;
1825
  bfd_byte *hit_data = contents + rel->r_offset;
1826
  bfd_vma addend;
1827
  /* The final GP value to be used for the relocatable, executable, or
1828
     shared object file being produced.  */
1829
  bfd_vma gp = MINUS_ONE;
1830
  /* The place (section offset or address) of the storage unit being relocated.  */
1831
  bfd_vma rel_addr;
1832
  /* The value of GP used to create the relocatable object.  */
1833
  bfd_vma gp0 = MINUS_ONE;
1834
  /* The offset into the global offset table at which the address of the relocation entry
1835
     symbol, adjusted by the addend, resides during execution.  */
1836
  bfd_vma g = MINUS_ONE;
1837
  /* TRUE if the symbol referred to by this relocation is a local symbol.  */
1838
  bfd_boolean local_p;
1839
  /* The eventual value we will relocate.  */
1840
  bfd_vma value = symbol;
1841
  unsigned long hi16_addend, hi16_offset, hi16_value, uvalue, offset, abs_value = 0;
1842
 
1843
  Elf_Internal_Sym *sym = 0;
1844
  asection *sec = NULL;
1845
  bfd_boolean merge_p = 0;
1846
 
1847
 
1848
  if (elf_gp (output_bfd) == 0)
1849
    {
1850
      struct bfd_link_hash_entry *bh;
1851
      asection *o;
1852
 
1853
      bh = bfd_link_hash_lookup (info->hash, "_gp", 0, 0, 1);
1854
      if (bh != NULL && bh->type == bfd_link_hash_defined)
1855
        elf_gp (output_bfd) = (bh->u.def.value
1856
                               + bh->u.def.section->output_section->vma
1857
                               + bh->u.def.section->output_offset);
1858
      else if (info->relocatable)
1859
        {
1860
          bfd_vma lo = -1;
1861
 
1862
          /* Find the GP-relative section with the lowest offset.  */
1863
          for (o = output_bfd->sections; o != NULL; o = o->next)
1864
            if (o->vma < lo)
1865
              lo = o->vma;
1866
          /* And calculate GP relative to that.  */
1867
          elf_gp (output_bfd) = lo + ELF_SCORE_GP_OFFSET (input_bfd);
1868
        }
1869
      else
1870
        {
1871
          /* If the relocate_section function needs to do a reloc
1872
             involving the GP value, it should make a reloc_dangerous
1873
             callback to warn that GP is not defined.  */
1874
        }
1875
    }
1876
 
1877
  /* Parse the relocation.  */
1878
  r_symndx = ELF32_R_SYM (rel->r_info);
1879
  r_type = ELF32_R_TYPE (rel->r_info);
1880
  rel_addr = (input_section->output_section->vma + input_section->output_offset + rel->r_offset);
1881
 
1882
  /* For hidden symbol.  */
1883
  local_p = score_elf_local_relocation_p (input_bfd, rel, local_sections, FALSE);
1884
  if (local_p)
1885
    {
1886
      sym = local_syms + r_symndx;
1887
      sec = local_sections[r_symndx];
1888
 
1889
      symbol = sec->output_section->vma + sec->output_offset;
1890
      if (ELF_ST_TYPE (sym->st_info) != STT_SECTION
1891
          || (sec->flags & SEC_MERGE))
1892
        symbol += sym->st_value;
1893
      if ((sec->flags & SEC_MERGE)
1894
          && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1895
        merge_p = 1;
1896
    }
1897
 
1898
  if (r_type == R_SCORE_GOT15)
1899
    {
1900
      const Elf_Internal_Rela *relend;
1901
      const Elf_Internal_Rela *lo16_rel;
1902
      const struct elf_backend_data *bed;
1903
      bfd_vma lo_value = 0;
1904
 
1905
      bed = get_elf_backend_data (output_bfd);
1906
      relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
1907
      lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
1908
      if ((local_p) && (lo16_rel != NULL))
1909
        {
1910
          bfd_vma tmp = 0;
1911
          tmp = bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
1912
          lo_value = (((tmp >> 16) & 0x3) << 14) | ((tmp & 0x7fff) >> 1);
1913
          if (merge_p)
1914
            {
1915
              asection *msec = sec;
1916
              lo_value = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, lo_value);
1917
              lo_value -= symbol;
1918
              lo_value += msec->output_section->vma + msec->output_offset;
1919
            }
1920
        }
1921
      addend = lo_value;
1922
    }
1923
  else
1924
    {
1925
      addend = (bfd_get_32 (input_bfd, hit_data) >> howto->bitpos) & howto->src_mask;
1926
    }
1927
 
1928
  /* Figure out the value of the symbol.  */
1929
  if (local_p && !merge_p)
1930
    {
1931
      if (r_type == R_SCORE_GOT15)
1932
        {
1933
          const Elf_Internal_Rela *relend;
1934
          const Elf_Internal_Rela *lo16_rel;
1935
          const struct elf_backend_data *bed;
1936
          bfd_vma lo_value = 0;
1937
 
1938
          value = bfd_get_32 (input_bfd, contents + rel->r_offset);
1939
          addend = value & 0x7fff;
1940
          if ((addend & 0x4000) == 0x4000)
1941
            addend |= 0xffffc000;
1942
 
1943
          bed = get_elf_backend_data (output_bfd);
1944
          relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
1945
          lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
1946
          if ((local_p) && (lo16_rel != NULL))
1947
            {
1948
              bfd_vma tmp = 0;
1949
              tmp = bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
1950
              lo_value = (((tmp >> 16) & 0x3) << 14) | ((tmp & 0x7fff) >> 1);
1951
            }
1952
 
1953
          addend <<= 16;
1954
          addend += lo_value;
1955
        }
1956
    }
1957
 
1958
  local_p = score_elf_local_relocation_p (input_bfd, rel, local_sections, TRUE);
1959
 
1960
  /* If we haven't already determined the GOT offset, or the GP value,
1961
     and we're going to need it, get it now.  */
1962
  switch (r_type)
1963
    {
1964
    case R_SCORE_CALL15:
1965
    case R_SCORE_GOT15:
1966
      if (!local_p)
1967
        {
1968
          g = score_elf_global_got_index (elf_hash_table (info)->dynobj,
1969
                                          (struct elf_link_hash_entry *) h);
1970
          if ((! elf_hash_table(info)->dynamic_sections_created
1971
               || (info->shared
1972
                   && (info->symbolic || h->root.dynindx == -1)
1973
                   && h->root.def_regular)))
1974
            {
1975
              /* This is a static link or a -Bsymbolic link.  The
1976
                 symbol is defined locally, or was forced to be local.
1977
                 We must initialize this entry in the GOT.  */
1978
              bfd *tmpbfd = elf_hash_table (info)->dynobj;
1979
              asection *sgot = score_elf_got_section (tmpbfd, FALSE);
1980
              bfd_put_32 (tmpbfd, value, sgot->contents + g);
1981
            }
1982
        }
1983
      else if (r_type == R_SCORE_GOT15 || r_type == R_SCORE_CALL15)
1984
        {
1985
          /* There's no need to create a local GOT entry here; the
1986
             calculation for a local GOT15 entry does not involve G.  */
1987
          ;
1988
        }
1989
      else
1990
        {
1991
          g = score_elf_local_got_index (output_bfd, input_bfd, info,
1992
                                         symbol + addend, r_symndx, h, r_type);
1993
            if (g == MINUS_ONE)
1994
            return bfd_reloc_outofrange;
1995
        }
1996
 
1997
      /* Convert GOT indices to actual offsets.  */
1998
      g = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
1999
                                           output_bfd, input_bfd, g);
2000
      break;
2001
 
2002
    case R_SCORE_HI16:
2003
    case R_SCORE_LO16:
2004
    case R_SCORE_GPREL32:
2005
      gp0 = _bfd_get_gp_value (input_bfd);
2006
      gp = _bfd_get_gp_value (output_bfd);
2007
      break;
2008
 
2009
    case R_SCORE_GP15:
2010
      gp = _bfd_get_gp_value (output_bfd);
2011
 
2012
    default:
2013
      break;
2014
    }
2015
 
2016
  switch (r_type)
2017
    {
2018
    case R_SCORE_NONE:
2019
      return bfd_reloc_ok;
2020
 
2021
    case R_SCORE_ABS32:
2022
    case R_SCORE_REL32:
2023
      if ((info->shared
2024
           || (elf_hash_table (info)->dynamic_sections_created
2025
               && h != NULL
2026
               && h->root.def_dynamic
2027
               && !h->root.def_regular))
2028
           && r_symndx != 0
2029
           && (input_section->flags & SEC_ALLOC) != 0)
2030
        {
2031
          /* If we're creating a shared library, or this relocation is against a symbol
2032
             in a shared library, then we can't know where the symbol will end up.
2033
             So, we create a relocation record in the output, and leave the job up
2034
             to the dynamic linker.  */
2035
          value = addend;
2036
          if (!score_elf_create_dynamic_relocation (output_bfd, info, rel, h,
2037
                                                    symbol, &value,
2038
                                                    input_section))
2039
            return bfd_reloc_undefined;
2040
        }
2041
      else if (r_symndx == 0)
2042
        /* r_symndx will be zero only for relocs against symbols
2043
           from removed linkonce sections, or sections discarded by
2044
           a linker script.  */
2045
        value = 0;
2046
      else
2047
        {
2048
          if (r_type != R_SCORE_REL32)
2049
            value = symbol + addend;
2050
          else
2051
            value = addend;
2052
        }
2053
      value &= howto->dst_mask;
2054
      bfd_put_32 (input_bfd, value, hit_data);
2055
      return bfd_reloc_ok;
2056
 
2057
    case R_SCORE_ABS16:
2058
      value += addend;
2059
      if ((long) value > 0x7fff || (long) value < -0x8000)
2060
        return bfd_reloc_overflow;
2061
      bfd_put_16 (input_bfd, value, hit_data);
2062
      return bfd_reloc_ok;
2063
 
2064
    case R_SCORE_24:
2065
      addend = bfd_get_32 (input_bfd, hit_data);
2066
      offset = (((addend & howto->src_mask) >> 1) & 0x1ff8000) | ((addend & howto->src_mask) & 0x7fff);
2067
      if ((offset & 0x1000000) != 0)
2068
        offset |= 0xfe000000;
2069
      value += offset;
2070
      abs_value = abs (value - rel_addr);
2071
      if ((abs_value & 0xfe000000) != 0)
2072
        return bfd_reloc_overflow;
2073
      addend = (addend & ~howto->src_mask)
2074
                | (((value << 1) & howto->src_mask) & 0x3ff0000) | (value & 0x7fff);
2075
      bfd_put_32 (input_bfd, addend, hit_data);
2076
      return bfd_reloc_ok;
2077
 
2078
    case R_SCORE_PC19:
2079
      addend = bfd_get_32 (input_bfd, hit_data);
2080
      offset = (((addend & howto->src_mask) & 0x3ff0000) >> 6) | ((addend & howto->src_mask) & 0x3ff);
2081
      if ((offset & 0x80000) != 0)
2082
        offset |= 0xfff00000;
2083
      abs_value = value = value - rel_addr + offset;
2084
      /* exceed 20 bit : overflow.  */
2085
      if ((abs_value & 0x80000000) == 0x80000000)
2086
        abs_value = 0xffffffff - value + 1;
2087
      if ((abs_value & 0xfff80000) != 0)
2088
        return bfd_reloc_overflow;
2089
      addend = (addend & ~howto->src_mask)
2090
                | (((value << 6) & howto->src_mask) & 0x3ff0000) | (value & 0x3ff);
2091
      bfd_put_32 (input_bfd, addend, hit_data);
2092
      return bfd_reloc_ok;
2093
 
2094
    case R_SCORE16_11:
2095
      addend = bfd_get_16 (input_bfd, hit_data);
2096
      offset = addend & howto->src_mask;
2097
      if ((offset & 0x800) != 0)        /* Offset is negative.  */
2098
        offset |= 0xfffff000;
2099
      value += offset;
2100
      abs_value = abs (value - rel_addr);
2101
      if ((abs_value & 0xfffff000) != 0)
2102
        return bfd_reloc_overflow;
2103
      addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
2104
      bfd_put_16 (input_bfd, addend, hit_data);
2105
      return bfd_reloc_ok;
2106
 
2107
    case R_SCORE16_PC8:
2108
      addend = bfd_get_16 (input_bfd, hit_data);
2109
      offset = (addend & howto->src_mask) << 1;
2110
      if ((offset & 0x100) != 0)        /* Offset is negative.  */
2111
        offset |= 0xfffffe00;
2112
      abs_value = value = value - rel_addr + offset;
2113
      /* Sign bit + exceed 9 bit.  */
2114
      if (((value & 0xffffff00) != 0) && ((value & 0xffffff00) != 0xffffff00))
2115
        return bfd_reloc_overflow;
2116
      value >>= 1;
2117
      addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
2118
      bfd_put_16 (input_bfd, addend, hit_data);
2119
      return bfd_reloc_ok;
2120
 
2121
    case R_SCORE_HI16:
2122
      return bfd_reloc_ok;
2123
 
2124
    case R_SCORE_LO16:
2125
      hi16_addend = bfd_get_32 (input_bfd, hit_data - 4);
2126
      hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
2127
      addend = bfd_get_32 (input_bfd, hit_data);
2128
      offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
2129
      offset = (hi16_offset << 16) | (offset & 0xffff);
2130
 
2131
      if (!gp_disp_p)
2132
        uvalue = value + offset;
2133
      else
2134
        uvalue = offset + gp - rel_addr + 4;
2135
 
2136
      hi16_offset = (uvalue >> 16) << 1;
2137
      hi16_value = (hi16_addend & (~(howto->dst_mask)))
2138
                        | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
2139
      bfd_put_32 (input_bfd, hi16_value, hit_data - 4);
2140
      offset = (uvalue & 0xffff) << 1;
2141
      value = (addend & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
2142
      bfd_put_32 (input_bfd, value, hit_data);
2143
      return bfd_reloc_ok;
2144
 
2145
    case R_SCORE_GP15:
2146
      addend = bfd_get_32 (input_bfd, hit_data);
2147
      offset = addend & 0x7fff;
2148
      if ((offset & 0x4000) == 0x4000)
2149
        offset |= 0xffffc000;
2150
      value = value + offset - gp;
2151
      if (((value & 0xffffc000) != 0) && ((value & 0xffffc000) != 0xffffc000))
2152
        return bfd_reloc_overflow;
2153
      value = (addend & ~howto->src_mask) | (value & howto->src_mask);
2154
      bfd_put_32 (input_bfd, value, hit_data);
2155
      return bfd_reloc_ok;
2156
 
2157
    case R_SCORE_GOT15:
2158
    case R_SCORE_CALL15:
2159
      if (local_p)
2160
        {
2161
          bfd_boolean forced;
2162
 
2163
          /* The special case is when the symbol is forced to be local.  We need the
2164
             full address in the GOT since no R_SCORE_GOT_LO16 relocation follows.  */
2165
          forced = ! score_elf_local_relocation_p (input_bfd, rel,
2166
                                                   local_sections, FALSE);
2167
          value = score_elf_got16_entry (output_bfd, input_bfd, info,
2168
                                         symbol + addend, forced);
2169
          if (value == MINUS_ONE)
2170
            return bfd_reloc_outofrange;
2171
          value = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
2172
                                                   output_bfd, input_bfd, value);
2173
        }
2174
      else
2175
        {
2176
          value = g;
2177
        }
2178
 
2179
      if ((long) value > 0x3fff || (long) value < -0x4000)
2180
        return bfd_reloc_overflow;
2181
 
2182
      addend = bfd_get_32 (input_bfd, hit_data);
2183
      value = (addend & ~howto->dst_mask) | (value & howto->dst_mask);
2184
      bfd_put_32 (input_bfd, value, hit_data);
2185
      return bfd_reloc_ok;
2186
 
2187
    case R_SCORE_GPREL32:
2188
      value = (addend + symbol + gp0 - gp);
2189
      value &= howto->dst_mask;
2190
      bfd_put_32 (input_bfd, value, hit_data);
2191
      return bfd_reloc_ok;
2192
 
2193
    case R_SCORE_GOT_LO16:
2194
      addend = bfd_get_32 (input_bfd, hit_data);
2195
      value = (((addend >> 16) & 0x3) << 14) | ((addend & 0x7fff) >> 1);
2196
      value += symbol;
2197
      value = (addend & (~(howto->dst_mask))) | ((value & 0x3fff) << 1)
2198
               | (((value >> 14) & 0x3) << 16);
2199
 
2200
      bfd_put_32 (input_bfd, value, hit_data);
2201
      return bfd_reloc_ok;
2202
 
2203
    case R_SCORE_DUMMY_HI16:
2204
      return bfd_reloc_ok;
2205
 
2206
    case R_SCORE_GNU_VTINHERIT:
2207
    case R_SCORE_GNU_VTENTRY:
2208
      /* We don't do anything with these at present.  */
2209
      return bfd_reloc_continue;
2210
 
2211
    default:
2212
      return bfd_reloc_notsupported;
2213
    }
2214
}
2215
 
2216
/* Score backend functions.  */
2217
 
2218
void
2219
s7_bfd_score_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
2220
                            arelent *bfd_reloc,
2221
                            Elf_Internal_Rela *elf_reloc)
2222
{
2223
  unsigned int r_type;
2224
 
2225
  r_type = ELF32_R_TYPE (elf_reloc->r_info);
2226
  if (r_type >= ARRAY_SIZE (elf32_score_howto_table))
2227
    bfd_reloc->howto = NULL;
2228
  else
2229
    bfd_reloc->howto = &elf32_score_howto_table[r_type];
2230
}
2231
 
2232
/* Relocate an score ELF section.  */
2233
 
2234
bfd_boolean
2235
s7_bfd_score_elf_relocate_section (bfd *output_bfd,
2236
                                   struct bfd_link_info *info,
2237
                                   bfd *input_bfd,
2238
                                   asection *input_section,
2239
                                   bfd_byte *contents,
2240
                                   Elf_Internal_Rela *relocs,
2241
                                   Elf_Internal_Sym *local_syms,
2242
                                   asection **local_sections)
2243
{
2244
  Elf_Internal_Shdr *symtab_hdr;
2245
  Elf_Internal_Rela *rel;
2246
  Elf_Internal_Rela *relend;
2247
  const char *name;
2248
  unsigned long offset;
2249
  unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
2250
  size_t extsymoff;
2251
  bfd_boolean gp_disp_p = FALSE;
2252
 
2253
  /* Sort dynsym.  */
2254
  if (elf_hash_table (info)->dynamic_sections_created)
2255
    {
2256
      bfd_size_type dynsecsymcount = 0;
2257
      if (info->shared)
2258
        {
2259
          asection * p;
2260
          const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
2261
 
2262
          for (p = output_bfd->sections; p ; p = p->next)
2263
            if ((p->flags & SEC_EXCLUDE) == 0
2264
                && (p->flags & SEC_ALLOC) != 0
2265
                && !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p))
2266
              ++ dynsecsymcount;
2267
        }
2268
 
2269
      if (!score_elf_sort_hash_table (info, dynsecsymcount + 1))
2270
        return FALSE;
2271
    }
2272
 
2273
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
2274
  extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
2275
  rel = relocs;
2276
  relend = relocs + input_section->reloc_count;
2277
  for (; rel < relend; rel++)
2278
    {
2279
      int r_type;
2280
      reloc_howto_type *howto;
2281
      unsigned long r_symndx;
2282
      Elf_Internal_Sym *sym;
2283
      asection *sec;
2284
      struct score_elf_link_hash_entry *h;
2285
      bfd_vma relocation = 0;
2286
      bfd_reloc_status_type r;
2287
      arelent bfd_reloc;
2288
 
2289
      r_symndx = ELF32_R_SYM (rel->r_info);
2290
      r_type = ELF32_R_TYPE (rel->r_info);
2291
 
2292
      s7_bfd_score_info_to_howto (input_bfd, &bfd_reloc, (Elf_Internal_Rela *) rel);
2293
      howto = bfd_reloc.howto;
2294
 
2295
      h = NULL;
2296
      sym = NULL;
2297
      sec = NULL;
2298
 
2299
      if (r_symndx < extsymoff)
2300
        {
2301
          sym = local_syms + r_symndx;
2302
          sec = local_sections[r_symndx];
2303
          relocation = sec->output_section->vma + sec->output_offset;
2304
          name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, sec);
2305
 
2306
          if (!info->relocatable)
2307
            {
2308
              if (ELF_ST_TYPE (sym->st_info) != STT_SECTION
2309
                      || (sec->flags & SEC_MERGE))
2310
                {
2311
                      relocation += sym->st_value;
2312
                    }
2313
 
2314
              if ((sec->flags & SEC_MERGE)
2315
                      && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2316
                {
2317
                  asection *msec;
2318
                  bfd_vma addend, value;
2319
 
2320
                  switch (r_type)
2321
                    {
2322
                    case R_SCORE_HI16:
2323
                      break;
2324
                    case R_SCORE_LO16:
2325
                      hi16_addend = bfd_get_32 (input_bfd, contents + rel->r_offset - 4);
2326
                      hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
2327
                      value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2328
                      offset = ((((value >> 16) & 0x3) << 15) | (value & 0x7fff)) >> 1;
2329
                      addend = (hi16_offset << 16) | (offset & 0xffff);
2330
                      msec = sec;
2331
                      addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend);
2332
                      addend -= relocation;
2333
                      addend += msec->output_section->vma + msec->output_offset;
2334
                      uvalue = addend;
2335
                      hi16_offset = (uvalue >> 16) << 1;
2336
                      hi16_value = (hi16_addend & (~(howto->dst_mask)))
2337
                        | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
2338
                      bfd_put_32 (input_bfd, hi16_value, contents + rel->r_offset - 4);
2339
                      offset = (uvalue & 0xffff) << 1;
2340
                      value = (value & (~(howto->dst_mask)))
2341
                        | (offset & 0x7fff) | ((offset << 1) & 0x30000);
2342
                      bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2343
                      break;
2344
                    case R_SCORE_GOT_LO16:
2345
                      value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2346
                      addend = (((value >> 16) & 0x3) << 14) | ((value & 0x7fff) >> 1);
2347
                      msec = sec;
2348
                      addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
2349
                      addend += msec->output_section->vma + msec->output_offset;
2350
                      value = (value & (~(howto->dst_mask))) | ((addend & 0x3fff) << 1)
2351
                               | (((addend >> 14) & 0x3) << 16);
2352
 
2353
                      bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2354
                      break;
2355
                    default:
2356
                      value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2357
                      /* Get the (signed) value from the instruction.  */
2358
                      addend = value & howto->src_mask;
2359
                      if (addend & ((howto->src_mask + 1) >> 1))
2360
                        {
2361
                          bfd_signed_vma mask;
2362
 
2363
                          mask = -1;
2364
                          mask &= ~howto->src_mask;
2365
                          addend |= mask;
2366
                        }
2367
                      msec = sec;
2368
                      addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
2369
                      addend += msec->output_section->vma + msec->output_offset;
2370
                      value = (value & ~howto->dst_mask) | (addend & howto->dst_mask);
2371
                      bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2372
                      break;
2373
                    }
2374
                }
2375
            }
2376
        }
2377
      else
2378
        {
2379
          /* For global symbols we look up the symbol in the hash-table.  */
2380
          h = ((struct score_elf_link_hash_entry *)
2381
               elf_sym_hashes (input_bfd) [r_symndx - extsymoff]);
2382
          /* Find the real hash-table entry for this symbol.  */
2383
          while (h->root.root.type == bfd_link_hash_indirect
2384
                 || h->root.root.type == bfd_link_hash_warning)
2385
            h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
2386
 
2387
          /* Record the name of this symbol, for our caller.  */
2388
          name = h->root.root.root.string;
2389
 
2390
          /* See if this is the special GP_DISP_LABEL symbol.  Note that such a
2391
             symbol must always be a global symbol.  */
2392
          if (strcmp (name, GP_DISP_LABEL) == 0)
2393
            {
2394
              /* Relocations against GP_DISP_LABEL are permitted only with
2395
                 R_SCORE_HI16 and R_SCORE_LO16 relocations.  */
2396
              if (r_type != R_SCORE_HI16 && r_type != R_SCORE_LO16)
2397
                return bfd_reloc_notsupported;
2398
 
2399
              gp_disp_p = TRUE;
2400
            }
2401
 
2402
          /* If this symbol is defined, calculate its address.  Note that
2403
              GP_DISP_LABEL is a magic symbol, always implicitly defined by the
2404
              linker, so it's inappropriate to check to see whether or not
2405
              its defined.  */
2406
          else if ((h->root.root.type == bfd_link_hash_defined
2407
                    || h->root.root.type == bfd_link_hash_defweak)
2408
                   && h->root.root.u.def.section)
2409
            {
2410
              sec = h->root.root.u.def.section;
2411
              if (sec->output_section)
2412
                relocation = (h->root.root.u.def.value
2413
                              + sec->output_section->vma
2414
                              + sec->output_offset);
2415
              else
2416
                {
2417
                  relocation = h->root.root.u.def.value;
2418
                }
2419
            }
2420
          else if (h->root.root.type == bfd_link_hash_undefweak)
2421
            /* We allow relocations against undefined weak symbols, giving
2422
               it the value zero, so that you can undefined weak functions
2423
               and check to see if they exist by looking at their addresses.  */
2424
            relocation = 0;
2425
          else if (info->unresolved_syms_in_objects == RM_IGNORE
2426
                   && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
2427
            relocation = 0;
2428
          else if (strcmp (name, "_DYNAMIC_LINK") == 0)
2429
            {
2430
              /* If this is a dynamic link, we should have created a _DYNAMIC_LINK symbol
2431
                 in s7_bfd_score_elf_create_dynamic_sections.  Otherwise, we should define
2432
                 the symbol with a value of 0.  */
2433
              BFD_ASSERT (! info->shared);
2434
              BFD_ASSERT (bfd_get_section_by_name (output_bfd, ".dynamic") == NULL);
2435
              relocation = 0;
2436
            }
2437
          else if (!info->relocatable)
2438
            {
2439
              if (! ((*info->callbacks->undefined_symbol)
2440
                     (info, h->root.root.root.string, input_bfd,
2441
                      input_section, rel->r_offset,
2442
                      (info->unresolved_syms_in_objects == RM_GENERATE_ERROR)
2443
                      || ELF_ST_VISIBILITY (h->root.other))))
2444
                return bfd_reloc_undefined;
2445
              relocation = 0;
2446
            }
2447
        }
2448
 
2449
      if (sec != NULL && elf_discarded_section (sec))
2450
        {
2451
          /* For relocs against symbols from removed linkonce sections,
2452
             or sections discarded by a linker script, we just want the
2453
             section contents zeroed.  Avoid any special processing.  */
2454
          _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
2455
          rel->r_info = 0;
2456
          rel->r_addend = 0;
2457
          continue;
2458
        }
2459
 
2460
      if (info->relocatable)
2461
        {
2462
          /* This is a relocatable link.  We don't have to change
2463
             anything, unless the reloc is against a section symbol,
2464
             in which case we have to adjust according to where the
2465
             section symbol winds up in the output section.  */
2466
          if (r_symndx < symtab_hdr->sh_info)
2467
            {
2468
              sym = local_syms + r_symndx;
2469
 
2470
              if (r_type == R_SCORE_GOT15)
2471
                {
2472
                  const Elf_Internal_Rela *lo16_rel;
2473
                  const struct elf_backend_data *bed;
2474
                  bfd_vma lo_addend = 0, lo_value = 0;
2475
                  bfd_vma addend, value;
2476
 
2477
                  value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2478
                  addend = value & 0x7fff;
2479
                  if ((addend & 0x4000) == 0x4000)
2480
                    addend |= 0xffffc000;
2481
 
2482
                  bed = get_elf_backend_data (output_bfd);
2483
                  relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
2484
                  lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
2485
                  if (lo16_rel != NULL)
2486
                    {
2487
                      lo_value = bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
2488
                      lo_addend = (((lo_value >> 16) & 0x3) << 14) | ((lo_value & 0x7fff) >> 1);
2489
                    }
2490
 
2491
                  addend <<= 16;
2492
                  addend += lo_addend;
2493
 
2494
                  if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2495
                    addend += local_sections[r_symndx]->output_offset;
2496
 
2497
                  lo_addend = addend & 0xffff;
2498
                  lo_value = (lo_value & (~(howto->dst_mask))) | ((lo_addend & 0x3fff) << 1)
2499
                              | (((lo_addend >> 14) & 0x3) << 16);
2500
                  bfd_put_32 (input_bfd, lo_value, contents + lo16_rel->r_offset);
2501
 
2502
                  addend = addend >> 16;
2503
                  value = (value & ~howto->src_mask) | (addend & howto->src_mask);
2504
                  bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2505
                }
2506
              else if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2507
                {
2508
                  sec = local_sections[r_symndx];
2509
                  score_elf_add_to_rel (input_bfd, contents + rel->r_offset,
2510
                                        howto, (bfd_signed_vma) (sec->output_offset + sym->st_value));
2511
                }
2512
            }
2513
          continue;
2514
        }
2515
 
2516
      /* This is a final link.  */
2517
      r = score_elf_final_link_relocate (howto, input_bfd, output_bfd,
2518
                                         input_section, contents, rel, relocs,
2519
                                         relocation, info, name,
2520
                                         (h ? ELF_ST_TYPE ((unsigned int) h->root.root.type) :
2521
                                         ELF_ST_TYPE ((unsigned int) sym->st_info)), h, local_syms,
2522
                                         local_sections, gp_disp_p);
2523
 
2524
      if (r != bfd_reloc_ok)
2525
        {
2526
          const char *msg = (const char *)0;
2527
 
2528
          switch (r)
2529
            {
2530
            case bfd_reloc_overflow:
2531
              /* If the overflowing reloc was to an undefined symbol,
2532
                 we have already printed one error message and there
2533
                 is no point complaining again.  */
2534
              if (((!h) || (h->root.root.type != bfd_link_hash_undefined))
2535
                  && (!((*info->callbacks->reloc_overflow)
2536
                        (info, NULL, name, howto->name, (bfd_vma) 0,
2537
                         input_bfd, input_section, rel->r_offset))))
2538
                return FALSE;
2539
              break;
2540
            case bfd_reloc_undefined:
2541
              if (!((*info->callbacks->undefined_symbol)
2542
                    (info, name, input_bfd, input_section, rel->r_offset, TRUE)))
2543
                return FALSE;
2544
              break;
2545
 
2546
            case bfd_reloc_outofrange:
2547
              msg = _("internal error: out of range error");
2548
              goto common_error;
2549
 
2550
            case bfd_reloc_notsupported:
2551
              msg = _("internal error: unsupported relocation error");
2552
              goto common_error;
2553
 
2554
            case bfd_reloc_dangerous:
2555
              msg = _("internal error: dangerous error");
2556
              goto common_error;
2557
 
2558
            default:
2559
              msg = _("internal error: unknown error");
2560
              /* fall through */
2561
 
2562
            common_error:
2563
              if (!((*info->callbacks->warning)
2564
                    (info, msg, name, input_bfd, input_section, rel->r_offset)))
2565
                return FALSE;
2566
              break;
2567
            }
2568
        }
2569
    }
2570
 
2571
  return TRUE;
2572
}
2573
 
2574
/* Look through the relocs for a section during the first phase, and
2575
   allocate space in the global offset table.  */
2576
 
2577
bfd_boolean
2578
s7_bfd_score_elf_check_relocs (bfd *abfd,
2579
                               struct bfd_link_info *info,
2580
                               asection *sec,
2581
                               const Elf_Internal_Rela *relocs)
2582
{
2583
  const char *name;
2584
  bfd *dynobj;
2585
  Elf_Internal_Shdr *symtab_hdr;
2586
  struct elf_link_hash_entry **sym_hashes;
2587
  struct score_got_info *g;
2588
  size_t extsymoff;
2589
  const Elf_Internal_Rela *rel;
2590
  const Elf_Internal_Rela *rel_end;
2591
  asection *sgot;
2592
  asection *sreloc;
2593
  const struct elf_backend_data *bed;
2594
 
2595
  if (info->relocatable)
2596
    return TRUE;
2597
 
2598
  dynobj = elf_hash_table (info)->dynobj;
2599
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2600
  sym_hashes = elf_sym_hashes (abfd);
2601
  extsymoff = (elf_bad_symtab (abfd)) ? 0 : symtab_hdr->sh_info;
2602
 
2603
  name = bfd_get_section_name (abfd, sec);
2604
 
2605
  if (dynobj == NULL)
2606
    {
2607
      sgot = NULL;
2608
      g = NULL;
2609
    }
2610
  else
2611
    {
2612
      sgot = score_elf_got_section (dynobj, FALSE);
2613
      if (sgot == NULL)
2614
        g = NULL;
2615
      else
2616
        {
2617
          BFD_ASSERT (score_elf_section_data (sgot) != NULL);
2618
          g = score_elf_section_data (sgot)->u.got_info;
2619
          BFD_ASSERT (g != NULL);
2620
        }
2621
    }
2622
 
2623
  sreloc = NULL;
2624
  bed = get_elf_backend_data (abfd);
2625
  rel_end = relocs + sec->reloc_count * bed->s->int_rels_per_ext_rel;
2626
  for (rel = relocs; rel < rel_end; ++rel)
2627
    {
2628
      unsigned long r_symndx;
2629
      unsigned int r_type;
2630
      struct elf_link_hash_entry *h;
2631
 
2632
      r_symndx = ELF32_R_SYM (rel->r_info);
2633
      r_type = ELF32_R_TYPE (rel->r_info);
2634
 
2635
      if (r_symndx < extsymoff)
2636
        {
2637
          h = NULL;
2638
        }
2639
      else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr))
2640
        {
2641
          (*_bfd_error_handler) (_("%s: Malformed reloc detected for section %s"), abfd, name);
2642
          bfd_set_error (bfd_error_bad_value);
2643
          return FALSE;
2644
        }
2645
      else
2646
        {
2647
          h = sym_hashes[r_symndx - extsymoff];
2648
 
2649
          /* This may be an indirect symbol created because of a version.  */
2650
          if (h != NULL)
2651
            {
2652
              while (h->root.type == bfd_link_hash_indirect)
2653
                h = (struct elf_link_hash_entry *) h->root.u.i.link;
2654
            }
2655
        }
2656
 
2657
      /* Some relocs require a global offset table.  */
2658
      if (dynobj == NULL || sgot == NULL)
2659
        {
2660
          switch (r_type)
2661
            {
2662
            case R_SCORE_GOT15:
2663
            case R_SCORE_CALL15:
2664
              if (dynobj == NULL)
2665
                elf_hash_table (info)->dynobj = dynobj = abfd;
2666
              if (!score_elf_create_got_section (dynobj, info, FALSE))
2667
                return FALSE;
2668
              g = score_elf_got_info (dynobj, &sgot);
2669
              break;
2670
            case R_SCORE_ABS32:
2671
            case R_SCORE_REL32:
2672
              if (dynobj == NULL && (info->shared || h != NULL) && (sec->flags & SEC_ALLOC) != 0)
2673
                elf_hash_table (info)->dynobj = dynobj = abfd;
2674
              break;
2675
            default:
2676
              break;
2677
            }
2678
        }
2679
 
2680
      if (!h && (r_type == R_SCORE_GOT_LO16))
2681
        {
2682
          if (! score_elf_record_local_got_symbol (abfd, r_symndx, rel->r_addend, g))
2683
            return FALSE;
2684
        }
2685
 
2686
      switch (r_type)
2687
        {
2688
        case R_SCORE_CALL15:
2689
          if (h == NULL)
2690
            {
2691
              (*_bfd_error_handler)
2692
                (_("%B: CALL15 reloc at 0x%lx not against global symbol"),
2693
                 abfd, (unsigned long) rel->r_offset);
2694
              bfd_set_error (bfd_error_bad_value);
2695
              return FALSE;
2696
            }
2697
          else
2698
            {
2699
              /* This symbol requires a global offset table entry.  */
2700
              if (! score_elf_record_global_got_symbol (h, abfd, info, g))
2701
                return FALSE;
2702
 
2703
              /* We need a stub, not a plt entry for the undefined function.  But we record
2704
                 it as if it needs plt.  See _bfd_elf_adjust_dynamic_symbol.  */
2705
              h->needs_plt = 1;
2706
              h->type = STT_FUNC;
2707
            }
2708
          break;
2709
        case R_SCORE_GOT15:
2710
          if (h && ! score_elf_record_global_got_symbol (h, abfd, info, g))
2711
            return FALSE;
2712
          break;
2713
        case R_SCORE_ABS32:
2714
        case R_SCORE_REL32:
2715
          if ((info->shared || h != NULL) && (sec->flags & SEC_ALLOC) != 0)
2716
            {
2717
              if (sreloc == NULL)
2718
                {
2719
                  sreloc = score_elf_rel_dyn_section (dynobj, TRUE);
2720
                  if (sreloc == NULL)
2721
                    return FALSE;
2722
                }
2723
#define SCORE_READONLY_SECTION (SEC_ALLOC | SEC_LOAD | SEC_READONLY)
2724
              if (info->shared)
2725
                {
2726
                  /* When creating a shared object, we must copy these reloc types into
2727
                     the output file as R_SCORE_REL32 relocs.  We make room for this reloc
2728
                     in the .rel.dyn reloc section.  */
2729
                  score_elf_allocate_dynamic_relocations (dynobj, 1);
2730
                  if ((sec->flags & SCORE_READONLY_SECTION)
2731
                      == SCORE_READONLY_SECTION)
2732
                    /* We tell the dynamic linker that there are
2733
                       relocations against the text segment.  */
2734
                    info->flags |= DF_TEXTREL;
2735
                }
2736
              else
2737
                {
2738
                  struct score_elf_link_hash_entry *hscore;
2739
 
2740
                  /* We only need to copy this reloc if the symbol is
2741
                     defined in a dynamic object.  */
2742
                  hscore = (struct score_elf_link_hash_entry *) h;
2743
                  ++hscore->possibly_dynamic_relocs;
2744
                  if ((sec->flags & SCORE_READONLY_SECTION)
2745
                      == SCORE_READONLY_SECTION)
2746
                    /* We need it to tell the dynamic linker if there
2747
                       are relocations against the text segment.  */
2748
                    hscore->readonly_reloc = TRUE;
2749
                }
2750
 
2751
              /* Even though we don't directly need a GOT entry for this symbol,
2752
                 a symbol must have a dynamic symbol table index greater that
2753
                 DT_SCORE_GOTSYM if there are dynamic relocations against it.  */
2754
              if (h != NULL)
2755
                {
2756
                  if (dynobj == NULL)
2757
                    elf_hash_table (info)->dynobj = dynobj = abfd;
2758
                  if (! score_elf_create_got_section (dynobj, info, TRUE))
2759
                    return FALSE;
2760
                  g = score_elf_got_info (dynobj, &sgot);
2761
                  if (! score_elf_record_global_got_symbol (h, abfd, info, g))
2762
                    return FALSE;
2763
                }
2764
            }
2765
          break;
2766
 
2767
          /* This relocation describes the C++ object vtable hierarchy.
2768
             Reconstruct it for later use during GC.  */
2769
        case R_SCORE_GNU_VTINHERIT:
2770
          if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
2771
            return FALSE;
2772
          break;
2773
 
2774
          /* This relocation describes which C++ vtable entries are actually
2775
             used.  Record for later use during GC.  */
2776
        case R_SCORE_GNU_VTENTRY:
2777
          if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
2778
            return FALSE;
2779
          break;
2780
        default:
2781
          break;
2782
        }
2783
 
2784
      /* We must not create a stub for a symbol that has relocations
2785
         related to taking the function's address.  */
2786
      switch (r_type)
2787
        {
2788
        default:
2789
          if (h != NULL)
2790
            {
2791
              struct score_elf_link_hash_entry *sh;
2792
 
2793
              sh = (struct score_elf_link_hash_entry *) h;
2794
              sh->no_fn_stub = TRUE;
2795
            }
2796
          break;
2797
        case R_SCORE_CALL15:
2798
          break;
2799
        }
2800
    }
2801
 
2802
  return TRUE;
2803
}
2804
 
2805
bfd_boolean
2806
s7_bfd_score_elf_add_symbol_hook (bfd *abfd,
2807
                                  struct bfd_link_info *info ATTRIBUTE_UNUSED,
2808
                                  Elf_Internal_Sym *sym,
2809
                                  const char **namep ATTRIBUTE_UNUSED,
2810
                                  flagword *flagsp ATTRIBUTE_UNUSED,
2811
                                  asection **secp,
2812
                                  bfd_vma *valp)
2813
{
2814
  switch (sym->st_shndx)
2815
    {
2816
    case SHN_COMMON:
2817
      if (sym->st_size > elf_gp_size (abfd))
2818
        break;
2819
      /* Fall through.  */
2820
    case SHN_SCORE_SCOMMON:
2821
      *secp = bfd_make_section_old_way (abfd, ".scommon");
2822
      (*secp)->flags |= SEC_IS_COMMON;
2823
      *valp = sym->st_size;
2824
      break;
2825
    }
2826
 
2827
  return TRUE;
2828
}
2829
 
2830
void
2831
s7_bfd_score_elf_symbol_processing (bfd *abfd, asymbol *asym)
2832
{
2833
  elf_symbol_type *elfsym;
2834
 
2835
  elfsym = (elf_symbol_type *) asym;
2836
  switch (elfsym->internal_elf_sym.st_shndx)
2837
    {
2838
    case SHN_COMMON:
2839
      if (asym->value > elf_gp_size (abfd))
2840
        break;
2841
      /* Fall through.  */
2842
    case SHN_SCORE_SCOMMON:
2843
      if (score_elf_scom_section.name == NULL)
2844
        {
2845
          /* Initialize the small common section.  */
2846
          score_elf_scom_section.name = ".scommon";
2847
          score_elf_scom_section.flags = SEC_IS_COMMON;
2848
          score_elf_scom_section.output_section = &score_elf_scom_section;
2849
          score_elf_scom_section.symbol = &score_elf_scom_symbol;
2850
          score_elf_scom_section.symbol_ptr_ptr = &score_elf_scom_symbol_ptr;
2851
          score_elf_scom_symbol.name = ".scommon";
2852
          score_elf_scom_symbol.flags = BSF_SECTION_SYM;
2853
          score_elf_scom_symbol.section = &score_elf_scom_section;
2854
          score_elf_scom_symbol_ptr = &score_elf_scom_symbol;
2855
        }
2856
      asym->section = &score_elf_scom_section;
2857
      asym->value = elfsym->internal_elf_sym.st_size;
2858
      break;
2859
    }
2860
}
2861
 
2862
int
2863
s7_bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
2864
                                          const char *name ATTRIBUTE_UNUSED,
2865
                                          Elf_Internal_Sym *sym,
2866
                                          asection *input_sec,
2867
                                          struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
2868
{
2869
  /* If we see a common symbol, which implies a relocatable link, then
2870
     if a symbol was small common in an input file, mark it as small
2871
     common in the output file.  */
2872
  if (sym->st_shndx == SHN_COMMON && strcmp (input_sec->name, ".scommon") == 0)
2873
    sym->st_shndx = SHN_SCORE_SCOMMON;
2874
 
2875
  return 1;
2876
}
2877
 
2878
bfd_boolean
2879
s7_bfd_score_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
2880
                                         asection *sec,
2881
                                         int *retval)
2882
{
2883
  if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
2884
    {
2885
      *retval = SHN_SCORE_SCOMMON;
2886
      return TRUE;
2887
    }
2888
 
2889
  return FALSE;
2890
}
2891
 
2892
/* Adjust a symbol defined by a dynamic object and referenced by a
2893
   regular object.  The current definition is in some section of the
2894
   dynamic object, but we're not including those sections.  We have to
2895
   change the definition to something the rest of the link can understand.  */
2896
 
2897
bfd_boolean
2898
s7_bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
2899
                                        struct elf_link_hash_entry *h)
2900
{
2901
  bfd *dynobj;
2902
  struct score_elf_link_hash_entry *hscore;
2903
  asection *s;
2904
 
2905
  dynobj = elf_hash_table (info)->dynobj;
2906
 
2907
  /* Make sure we know what is going on here.  */
2908
  BFD_ASSERT (dynobj != NULL
2909
              && (h->needs_plt
2910
                  || h->u.weakdef != NULL
2911
                  || (h->def_dynamic && h->ref_regular && !h->def_regular)));
2912
 
2913
  /* If this symbol is defined in a dynamic object, we need to copy
2914
     any R_SCORE_ABS32 or R_SCORE_REL32 relocs against it into the output
2915
     file.  */
2916
  hscore = (struct score_elf_link_hash_entry *) h;
2917
  if (!info->relocatable
2918
      && hscore->possibly_dynamic_relocs != 0
2919
      && (h->root.type == bfd_link_hash_defweak || !h->def_regular))
2920
    {
2921
      score_elf_allocate_dynamic_relocations (dynobj, hscore->possibly_dynamic_relocs);
2922
      if (hscore->readonly_reloc)
2923
        /* We tell the dynamic linker that there are relocations
2924
           against the text segment.  */
2925
        info->flags |= DF_TEXTREL;
2926
    }
2927
 
2928
  /* For a function, create a stub, if allowed.  */
2929
  if (!hscore->no_fn_stub && h->needs_plt)
2930
    {
2931
      if (!elf_hash_table (info)->dynamic_sections_created)
2932
        return TRUE;
2933
 
2934
      /* If this symbol is not defined in a regular file, then set
2935
         the symbol to the stub location.  This is required to make
2936
         function pointers compare as equal between the normal
2937
         executable and the shared library.  */
2938
      if (!h->def_regular)
2939
        {
2940
          /* We need .stub section.  */
2941
          s = bfd_get_section_by_name (dynobj, SCORE_ELF_STUB_SECTION_NAME);
2942
          BFD_ASSERT (s != NULL);
2943
 
2944
          h->root.u.def.section = s;
2945
          h->root.u.def.value = s->size;
2946
 
2947
          /* XXX Write this stub address somewhere.  */
2948
          h->plt.offset = s->size;
2949
 
2950
          /* Make room for this stub code.  */
2951
          s->size += SCORE_FUNCTION_STUB_SIZE;
2952
 
2953
          /* The last half word of the stub will be filled with the index
2954
             of this symbol in .dynsym section.  */
2955
          return TRUE;
2956
        }
2957
    }
2958
  else if ((h->type == STT_FUNC) && !h->needs_plt)
2959
    {
2960
      /* This will set the entry for this symbol in the GOT to 0, and
2961
         the dynamic linker will take care of this.  */
2962
      h->root.u.def.value = 0;
2963
      return TRUE;
2964
    }
2965
 
2966
  /* If this is a weak symbol, and there is a real definition, the
2967
     processor independent code will have arranged for us to see the
2968
     real definition first, and we can just use the same value.  */
2969
  if (h->u.weakdef != NULL)
2970
    {
2971
      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2972
                  || h->u.weakdef->root.type == bfd_link_hash_defweak);
2973
      h->root.u.def.section = h->u.weakdef->root.u.def.section;
2974
      h->root.u.def.value = h->u.weakdef->root.u.def.value;
2975
      return TRUE;
2976
    }
2977
 
2978
  /* This is a reference to a symbol defined by a dynamic object which
2979
     is not a function.  */
2980
  return TRUE;
2981
}
2982
 
2983
/* This function is called after all the input files have been read,
2984
   and the input sections have been assigned to output sections.  */
2985
 
2986
bfd_boolean
2987
s7_bfd_score_elf_always_size_sections (bfd *output_bfd,
2988
                                       struct bfd_link_info *info)
2989
{
2990
  bfd *dynobj;
2991
  asection *s;
2992
  struct score_got_info *g;
2993
  int i;
2994
  bfd_size_type loadable_size = 0;
2995
  bfd_size_type local_gotno;
2996
  bfd *sub;
2997
 
2998
  dynobj = elf_hash_table (info)->dynobj;
2999
  if (dynobj == NULL)
3000
    /* Relocatable links don't have it.  */
3001
    return TRUE;
3002
 
3003
  g = score_elf_got_info (dynobj, &s);
3004
  if (s == NULL)
3005
    return TRUE;
3006
 
3007
  /* Calculate the total loadable size of the output.  That will give us the
3008
     maximum number of GOT_PAGE entries required.  */
3009
  for (sub = info->input_bfds; sub; sub = sub->link_next)
3010
    {
3011
      asection *subsection;
3012
 
3013
      for (subsection = sub->sections;
3014
           subsection;
3015
           subsection = subsection->next)
3016
        {
3017
          if ((subsection->flags & SEC_ALLOC) == 0)
3018
            continue;
3019
          loadable_size += ((subsection->size + 0xf)
3020
                            &~ (bfd_size_type) 0xf);
3021
        }
3022
    }
3023
 
3024
  /* There has to be a global GOT entry for every symbol with
3025
     a dynamic symbol table index of DT_SCORE_GOTSYM or
3026
     higher.  Therefore, it make sense to put those symbols
3027
     that need GOT entries at the end of the symbol table.  We
3028
     do that here.  */
3029
  if (! score_elf_sort_hash_table (info, 1))
3030
    return FALSE;
3031
 
3032
  if (g->global_gotsym != NULL)
3033
    i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx;
3034
  else
3035
    /* If there are no global symbols, or none requiring
3036
       relocations, then GLOBAL_GOTSYM will be NULL.  */
3037
    i = 0;
3038
 
3039
  /* In the worst case, we'll get one stub per dynamic symbol.  */
3040
  loadable_size += SCORE_FUNCTION_STUB_SIZE * i;
3041
 
3042
  /* Assume there are two loadable segments consisting of
3043
     contiguous sections.  Is 5 enough?  */
3044
  local_gotno = (loadable_size >> 16) + 5;
3045
 
3046
  g->local_gotno += local_gotno;
3047
  s->size += g->local_gotno * SCORE_ELF_GOT_SIZE (output_bfd);
3048
 
3049
  g->global_gotno = i;
3050
  s->size += i * SCORE_ELF_GOT_SIZE (output_bfd);
3051
 
3052
  score_elf_resolve_final_got_entries (g);
3053
 
3054
  if (s->size > SCORE_ELF_GOT_MAX_SIZE (output_bfd))
3055
    {
3056
      /* Fixme. Error message or Warning message should be issued here.  */
3057
    }
3058
 
3059
  return TRUE;
3060
}
3061
 
3062
/* Set the sizes of the dynamic sections.  */
3063
 
3064
bfd_boolean
3065
s7_bfd_score_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
3066
{
3067
  bfd *dynobj;
3068
  asection *s;
3069
  bfd_boolean reltext;
3070
 
3071
  dynobj = elf_hash_table (info)->dynobj;
3072
  BFD_ASSERT (dynobj != NULL);
3073
 
3074
  if (elf_hash_table (info)->dynamic_sections_created)
3075
    {
3076
      /* Set the contents of the .interp section to the interpreter.  */
3077
      if (!info->shared)
3078
        {
3079
          s = bfd_get_section_by_name (dynobj, ".interp");
3080
          BFD_ASSERT (s != NULL);
3081
          s->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
3082
          s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
3083
        }
3084
    }
3085
 
3086
  /* The check_relocs and adjust_dynamic_symbol entry points have
3087
     determined the sizes of the various dynamic sections.  Allocate
3088
     memory for them.  */
3089
  reltext = FALSE;
3090
  for (s = dynobj->sections; s != NULL; s = s->next)
3091
    {
3092
      const char *name;
3093
 
3094
      if ((s->flags & SEC_LINKER_CREATED) == 0)
3095
        continue;
3096
 
3097
      /* It's OK to base decisions on the section name, because none
3098
         of the dynobj section names depend upon the input files.  */
3099
      name = bfd_get_section_name (dynobj, s);
3100
 
3101
      if (CONST_STRNEQ (name, ".rel"))
3102
        {
3103
          if (s->size == 0)
3104
            {
3105
              /* We only strip the section if the output section name
3106
                 has the same name.  Otherwise, there might be several
3107
                 input sections for this output section.  FIXME: This
3108
                 code is probably not needed these days anyhow, since
3109
                 the linker now does not create empty output sections.  */
3110
              if (s->output_section != NULL
3111
                  && strcmp (name,
3112
                             bfd_get_section_name (s->output_section->owner,
3113
                                                   s->output_section)) == 0)
3114
                s->flags |= SEC_EXCLUDE;
3115
            }
3116
          else
3117
            {
3118
              const char *outname;
3119
              asection *target;
3120
 
3121
              /* If this relocation section applies to a read only
3122
                 section, then we probably need a DT_TEXTREL entry.
3123
                 If the relocation section is .rel.dyn, we always
3124
                 assert a DT_TEXTREL entry rather than testing whether
3125
                 there exists a relocation to a read only section or
3126
                 not.  */
3127
              outname = bfd_get_section_name (output_bfd, s->output_section);
3128
              target = bfd_get_section_by_name (output_bfd, outname + 4);
3129
              if ((target != NULL
3130
                   && (target->flags & SEC_READONLY) != 0
3131
                   && (target->flags & SEC_ALLOC) != 0) || strcmp (outname, ".rel.dyn") == 0)
3132
                reltext = TRUE;
3133
 
3134
              /* We use the reloc_count field as a counter if we need
3135
                 to copy relocs into the output file.  */
3136
              if (strcmp (name, ".rel.dyn") != 0)
3137
                s->reloc_count = 0;
3138
            }
3139
        }
3140
      else if (CONST_STRNEQ (name, ".got"))
3141
        {
3142
          /* s7_bfd_score_elf_always_size_sections() has already done
3143
             most of the work, but some symbols may have been mapped
3144
             to versions that we must now resolve in the got_entries
3145
             hash tables.  */
3146
        }
3147
      else if (strcmp (name, SCORE_ELF_STUB_SECTION_NAME) == 0)
3148
        {
3149
          /* IRIX rld assumes that the function stub isn't at the end
3150
             of .text section. So put a dummy. XXX  */
3151
          s->size += SCORE_FUNCTION_STUB_SIZE;
3152
        }
3153
      else if (! CONST_STRNEQ (name, ".init"))
3154
        {
3155
          /* It's not one of our sections, so don't allocate space.  */
3156
          continue;
3157
        }
3158
 
3159
      /* Allocate memory for the section contents.  */
3160
      s->contents = bfd_zalloc (dynobj, s->size);
3161
      if (s->contents == NULL && s->size != 0)
3162
        {
3163
          bfd_set_error (bfd_error_no_memory);
3164
          return FALSE;
3165
        }
3166
    }
3167
 
3168
  if (elf_hash_table (info)->dynamic_sections_created)
3169
    {
3170
      /* Add some entries to the .dynamic section.  We fill in the
3171
         values later, in s7_bfd_score_elf_finish_dynamic_sections, but we
3172
         must add the entries now so that we get the correct size for
3173
         the .dynamic section.  The DT_DEBUG entry is filled in by the
3174
         dynamic linker and used by the debugger.  */
3175
 
3176
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0))
3177
        return FALSE;
3178
 
3179
      if (reltext)
3180
        info->flags |= DF_TEXTREL;
3181
 
3182
      if ((info->flags & DF_TEXTREL) != 0)
3183
        {
3184
          if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0))
3185
            return FALSE;
3186
        }
3187
 
3188
      if (! SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTGOT, 0))
3189
        return FALSE;
3190
 
3191
      if (score_elf_rel_dyn_section (dynobj, FALSE))
3192
        {
3193
          if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_REL, 0))
3194
            return FALSE;
3195
 
3196
          if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELSZ, 0))
3197
            return FALSE;
3198
 
3199
          if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELENT, 0))
3200
            return FALSE;
3201
        }
3202
 
3203
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_BASE_ADDRESS, 0))
3204
        return FALSE;
3205
 
3206
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_LOCAL_GOTNO, 0))
3207
        return FALSE;
3208
 
3209
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_SYMTABNO, 0))
3210
        return FALSE;
3211
 
3212
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_UNREFEXTNO, 0))
3213
        return FALSE;
3214
 
3215
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_GOTSYM, 0))
3216
        return FALSE;
3217
 
3218
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_HIPAGENO, 0))
3219
        return FALSE;
3220
    }
3221
 
3222
  return TRUE;
3223
}
3224
 
3225
bfd_boolean
3226
s7_bfd_score_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
3227
{
3228
  struct elf_link_hash_entry *h;
3229
  struct bfd_link_hash_entry *bh;
3230
  flagword flags;
3231
  asection *s;
3232
 
3233
  flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
3234
           | SEC_LINKER_CREATED | SEC_READONLY);
3235
 
3236
  /* ABI requests the .dynamic section to be read only.  */
3237
  s = bfd_get_section_by_name (abfd, ".dynamic");
3238
  if (s != NULL)
3239
    {
3240
      if (!bfd_set_section_flags (abfd, s, flags))
3241
        return FALSE;
3242
    }
3243
 
3244
  /* We need to create .got section.  */
3245
  if (!score_elf_create_got_section (abfd, info, FALSE))
3246
    return FALSE;
3247
 
3248
  if (!score_elf_rel_dyn_section (elf_hash_table (info)->dynobj, TRUE))
3249
    return FALSE;
3250
 
3251
  /* Create .stub section.  */
3252
  if (bfd_get_section_by_name (abfd, SCORE_ELF_STUB_SECTION_NAME) == NULL)
3253
    {
3254
      s = bfd_make_section_with_flags (abfd, SCORE_ELF_STUB_SECTION_NAME,
3255
                                       flags | SEC_CODE);
3256
      if (s == NULL
3257
          || !bfd_set_section_alignment (abfd, s, 2))
3258
 
3259
        return FALSE;
3260
    }
3261
 
3262
  if (!info->shared)
3263
    {
3264
      const char *name;
3265
 
3266
      name = "_DYNAMIC_LINK";
3267
      bh = NULL;
3268
      if (!(_bfd_generic_link_add_one_symbol
3269
            (info, abfd, name, BSF_GLOBAL, bfd_abs_section_ptr,
3270
             (bfd_vma) 0, NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
3271
        return FALSE;
3272
 
3273
      h = (struct elf_link_hash_entry *) bh;
3274
      h->non_elf = 0;
3275
      h->def_regular = 1;
3276
      h->type = STT_SECTION;
3277
 
3278
      if (!bfd_elf_link_record_dynamic_symbol (info, h))
3279
        return FALSE;
3280
    }
3281
 
3282
  return TRUE;
3283
}
3284
 
3285
 
3286
/* Finish up dynamic symbol handling.  We set the contents of various
3287
   dynamic sections here.  */
3288
 
3289
bfd_boolean
3290
s7_bfd_score_elf_finish_dynamic_symbol (bfd *output_bfd,
3291
                                        struct bfd_link_info *info,
3292
                                        struct elf_link_hash_entry *h,
3293
                                        Elf_Internal_Sym *sym)
3294
{
3295
  bfd *dynobj;
3296
  asection *sgot;
3297
  struct score_got_info *g;
3298
  const char *name;
3299
 
3300
  dynobj = elf_hash_table (info)->dynobj;
3301
 
3302
  if (h->plt.offset != MINUS_ONE)
3303
    {
3304
      asection *s;
3305
      bfd_byte stub[SCORE_FUNCTION_STUB_SIZE];
3306
 
3307
      /* This symbol has a stub.  Set it up.  */
3308
      BFD_ASSERT (h->dynindx != -1);
3309
 
3310
      s = bfd_get_section_by_name (dynobj, SCORE_ELF_STUB_SECTION_NAME);
3311
      BFD_ASSERT (s != NULL);
3312
 
3313
      /* FIXME: Can h->dynindex be more than 64K?  */
3314
      if (h->dynindx & 0xffff0000)
3315
        return FALSE;
3316
 
3317
      /* Fill the stub.  */
3318
      bfd_put_32 (output_bfd, STUB_LW, stub);
3319
      bfd_put_32 (output_bfd, STUB_MOVE, stub + 4);
3320
      bfd_put_32 (output_bfd, STUB_LI16 | (h->dynindx << 1), stub + 8);
3321
      bfd_put_32 (output_bfd, STUB_BRL, stub + 12);
3322
 
3323
      BFD_ASSERT (h->plt.offset <= s->size);
3324
      memcpy (s->contents + h->plt.offset, stub, SCORE_FUNCTION_STUB_SIZE);
3325
 
3326
      /* Mark the symbol as undefined.  plt.offset != -1 occurs
3327
         only for the referenced symbol.  */
3328
      sym->st_shndx = SHN_UNDEF;
3329
 
3330
      /* The run-time linker uses the st_value field of the symbol
3331
          to reset the global offset table entry for this external
3332
          to its stub address when unlinking a shared object.  */
3333
      sym->st_value = (s->output_section->vma + s->output_offset + h->plt.offset);
3334
    }
3335
 
3336
  BFD_ASSERT (h->dynindx != -1 || h->forced_local);
3337
 
3338
  sgot = score_elf_got_section (dynobj, FALSE);
3339
  BFD_ASSERT (sgot != NULL);
3340
  BFD_ASSERT (score_elf_section_data (sgot) != NULL);
3341
  g = score_elf_section_data (sgot)->u.got_info;
3342
  BFD_ASSERT (g != NULL);
3343
 
3344
  /* Run through the global symbol table, creating GOT entries for all
3345
     the symbols that need them.  */
3346
  if (g->global_gotsym != NULL && h->dynindx >= g->global_gotsym->dynindx)
3347
    {
3348
      bfd_vma offset;
3349
      bfd_vma value;
3350
 
3351
      value = sym->st_value;
3352
      offset = score_elf_global_got_index (dynobj, h);
3353
      bfd_put_32 (output_bfd, value, sgot->contents + offset);
3354
    }
3355
 
3356
  /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
3357
  name = h->root.root.string;
3358
  if (strcmp (name, "_DYNAMIC") == 0 || strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
3359
    sym->st_shndx = SHN_ABS;
3360
  else if (strcmp (name, "_DYNAMIC_LINK") == 0)
3361
    {
3362
      sym->st_shndx = SHN_ABS;
3363
      sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
3364
      sym->st_value = 1;
3365
    }
3366
  else if (strcmp (name, GP_DISP_LABEL) == 0)
3367
    {
3368
      sym->st_shndx = SHN_ABS;
3369
      sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
3370
      sym->st_value = elf_gp (output_bfd);
3371
    }
3372
 
3373
  return TRUE;
3374
}
3375
 
3376
/* Finish up the dynamic sections.  */
3377
 
3378
bfd_boolean
3379
s7_bfd_score_elf_finish_dynamic_sections (bfd *output_bfd,
3380
                                          struct bfd_link_info *info)
3381
{
3382
  bfd *dynobj;
3383
  asection *sdyn;
3384
  asection *sgot;
3385
  asection *s;
3386
  struct score_got_info *g;
3387
 
3388
  dynobj = elf_hash_table (info)->dynobj;
3389
 
3390
  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
3391
 
3392
  sgot = score_elf_got_section (dynobj, FALSE);
3393
  if (sgot == NULL)
3394
    g = NULL;
3395
  else
3396
    {
3397
      BFD_ASSERT (score_elf_section_data (sgot) != NULL);
3398
      g = score_elf_section_data (sgot)->u.got_info;
3399
      BFD_ASSERT (g != NULL);
3400
    }
3401
 
3402
  if (elf_hash_table (info)->dynamic_sections_created)
3403
    {
3404
      bfd_byte *b;
3405
 
3406
      BFD_ASSERT (sdyn != NULL);
3407
      BFD_ASSERT (g != NULL);
3408
 
3409
      for (b = sdyn->contents;
3410
           b < sdyn->contents + sdyn->size;
3411
           b += SCORE_ELF_DYN_SIZE (dynobj))
3412
        {
3413
          Elf_Internal_Dyn dyn;
3414
          const char *name;
3415
          size_t elemsize;
3416
          bfd_boolean swap_out_p;
3417
 
3418
          /* Read in the current dynamic entry.  */
3419
          (*get_elf_backend_data (dynobj)->s->swap_dyn_in) (dynobj, b, &dyn);
3420
 
3421
          /* Assume that we're going to modify it and write it out.  */
3422
          swap_out_p = TRUE;
3423
 
3424
          switch (dyn.d_tag)
3425
            {
3426
            case DT_RELENT:
3427
              s = score_elf_rel_dyn_section (dynobj, FALSE);
3428
              BFD_ASSERT (s != NULL);
3429
              dyn.d_un.d_val = SCORE_ELF_REL_SIZE (dynobj);
3430
              break;
3431
 
3432
            case DT_STRSZ:
3433
              /* Rewrite DT_STRSZ.  */
3434
              dyn.d_un.d_val = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
3435
                    break;
3436
 
3437
            case DT_PLTGOT:
3438
              name = ".got";
3439
              s = bfd_get_section_by_name (output_bfd, name);
3440
              BFD_ASSERT (s != NULL);
3441
              dyn.d_un.d_ptr = s->vma;
3442
              break;
3443
 
3444
            case DT_SCORE_BASE_ADDRESS:
3445
              s = output_bfd->sections;
3446
              BFD_ASSERT (s != NULL);
3447
              dyn.d_un.d_ptr = s->vma & ~(bfd_vma) 0xffff;
3448
              break;
3449
 
3450
            case DT_SCORE_LOCAL_GOTNO:
3451
              dyn.d_un.d_val = g->local_gotno;
3452
              break;
3453
 
3454
            case DT_SCORE_UNREFEXTNO:
3455
              /* The index into the dynamic symbol table which is the
3456
                 entry of the first external symbol that is not
3457
                 referenced within the same object.  */
3458
              dyn.d_un.d_val = bfd_count_sections (output_bfd) + 1;
3459
              break;
3460
 
3461
            case DT_SCORE_GOTSYM:
3462
              if (g->global_gotsym)
3463
                {
3464
                  dyn.d_un.d_val = g->global_gotsym->dynindx;
3465
                  break;
3466
                }
3467
              /* In case if we don't have global got symbols we default
3468
                  to setting DT_SCORE_GOTSYM to the same value as
3469
                  DT_SCORE_SYMTABNO, so we just fall through.  */
3470
 
3471
            case DT_SCORE_SYMTABNO:
3472
              name = ".dynsym";
3473
              elemsize = SCORE_ELF_SYM_SIZE (output_bfd);
3474
              s = bfd_get_section_by_name (output_bfd, name);
3475
              BFD_ASSERT (s != NULL);
3476
 
3477
              dyn.d_un.d_val = s->size / elemsize;
3478
              break;
3479
 
3480
            case DT_SCORE_HIPAGENO:
3481
              dyn.d_un.d_val = g->local_gotno - SCORE_RESERVED_GOTNO;
3482
              break;
3483
 
3484
            default:
3485
              swap_out_p = FALSE;
3486
              break;
3487
            }
3488
 
3489
          if (swap_out_p)
3490
            (*get_elf_backend_data (dynobj)->s->swap_dyn_out) (dynobj, &dyn, b);
3491
        }
3492
    }
3493
 
3494
  /* The first entry of the global offset table will be filled at
3495
     runtime. The second entry will be used by some runtime loaders.
3496
     This isn't the case of IRIX rld.  */
3497
  if (sgot != NULL && sgot->size > 0)
3498
    {
3499
      bfd_put_32 (output_bfd, 0, sgot->contents);
3500
      bfd_put_32 (output_bfd, 0x80000000, sgot->contents + SCORE_ELF_GOT_SIZE (output_bfd));
3501
    }
3502
 
3503
  if (sgot != NULL)
3504
    elf_section_data (sgot->output_section)->this_hdr.sh_entsize
3505
      = SCORE_ELF_GOT_SIZE (output_bfd);
3506
 
3507
 
3508
  /* We need to sort the entries of the dynamic relocation section.  */
3509
  s = score_elf_rel_dyn_section (dynobj, FALSE);
3510
 
3511
  if (s != NULL && s->size > (bfd_vma)2 * SCORE_ELF_REL_SIZE (output_bfd))
3512
    {
3513
      reldyn_sorting_bfd = output_bfd;
3514
      qsort ((Elf32_External_Rel *) s->contents + 1, s->reloc_count - 1,
3515
             sizeof (Elf32_External_Rel), score_elf_sort_dynamic_relocs);
3516
    }
3517
 
3518
  return TRUE;
3519
}
3520
 
3521
/* This function set up the ELF section header for a BFD section in preparation for writing
3522
   it out.  This is where the flags and type fields are set for unusual sections.  */
3523
 
3524
bfd_boolean
3525
s7_bfd_score_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
3526
                                Elf_Internal_Shdr *hdr,
3527
                                asection *sec)
3528
{
3529
  const char *name;
3530
 
3531
  name = bfd_get_section_name (abfd, sec);
3532
 
3533
  if (strcmp (name, ".got") == 0
3534
      || strcmp (name, ".srdata") == 0
3535
      || strcmp (name, ".sdata") == 0
3536
      || strcmp (name, ".sbss") == 0)
3537
    hdr->sh_flags |= SHF_SCORE_GPREL;
3538
 
3539
  return TRUE;
3540
}
3541
 
3542
/* This function do additional processing on the ELF section header before writing
3543
   it out.  This is used to set the flags and type fields for some sections.  */
3544
 
3545
/* assign_file_positions_except_relocs() check section flag and if it is allocatable,
3546
   warning message will be issued.  backend_fake_section is called before
3547
   assign_file_positions_except_relocs(); backend_section_processing after it.  so, we
3548
   modify section flag there, but not backend_fake_section.  */
3549
 
3550
bfd_boolean
3551
s7_bfd_score_elf_section_processing (bfd *abfd ATTRIBUTE_UNUSED, Elf_Internal_Shdr *hdr)
3552
{
3553
  if (hdr->bfd_section != NULL)
3554
    {
3555
      const char *name = bfd_get_section_name (abfd, hdr->bfd_section);
3556
 
3557
      if (strcmp (name, ".sdata") == 0)
3558
        {
3559
          hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
3560
          hdr->sh_type = SHT_PROGBITS;
3561
        }
3562
      else if (strcmp (name, ".sbss") == 0)
3563
        {
3564
          hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
3565
          hdr->sh_type = SHT_NOBITS;
3566
        }
3567
      else if (strcmp (name, ".srdata") == 0)
3568
        {
3569
          hdr->sh_flags |= SHF_ALLOC | SHF_SCORE_GPREL;
3570
          hdr->sh_type = SHT_PROGBITS;
3571
        }
3572
    }
3573
 
3574
  return TRUE;
3575
}
3576
 
3577
bfd_boolean
3578
s7_bfd_score_elf_write_section (bfd *output_bfd, asection *sec, bfd_byte *contents)
3579
{
3580
  bfd_byte *to, *from, *end;
3581
  int i;
3582
 
3583
  if (strcmp (sec->name, ".pdr") != 0)
3584
    return FALSE;
3585
 
3586
  if (score_elf_section_data (sec)->u.tdata == NULL)
3587
    return FALSE;
3588
 
3589
  to = contents;
3590
  end = contents + sec->size;
3591
  for (from = contents, i = 0; from < end; from += PDR_SIZE, i++)
3592
    {
3593
      if ((score_elf_section_data (sec)->u.tdata)[i] == 1)
3594
        continue;
3595
 
3596
      if (to != from)
3597
        memcpy (to, from, PDR_SIZE);
3598
 
3599
      to += PDR_SIZE;
3600
    }
3601
  bfd_set_section_contents (output_bfd, sec->output_section, contents,
3602
                            (file_ptr) sec->output_offset, sec->size);
3603
 
3604
  return TRUE;
3605
}
3606
 
3607
/* Copy data from a SCORE ELF indirect symbol to its direct symbol, hiding the old
3608
   indirect symbol.  Process additional relocation information.  */
3609
 
3610
void
3611
s7_bfd_score_elf_copy_indirect_symbol (struct bfd_link_info *info,
3612
                                       struct elf_link_hash_entry *dir,
3613
                                       struct elf_link_hash_entry *ind)
3614
{
3615
  struct score_elf_link_hash_entry *dirscore, *indscore;
3616
 
3617
  _bfd_elf_link_hash_copy_indirect (info, dir, ind);
3618
 
3619
  if (ind->root.type != bfd_link_hash_indirect)
3620
    return;
3621
 
3622
  dirscore = (struct score_elf_link_hash_entry *) dir;
3623
  indscore = (struct score_elf_link_hash_entry *) ind;
3624
  dirscore->possibly_dynamic_relocs += indscore->possibly_dynamic_relocs;
3625
 
3626
  if (indscore->readonly_reloc)
3627
    dirscore->readonly_reloc = TRUE;
3628
 
3629
  if (indscore->no_fn_stub)
3630
    dirscore->no_fn_stub = TRUE;
3631
}
3632
 
3633
/* Remove information about discarded functions from other sections which mention them.  */
3634
 
3635
bfd_boolean
3636
s7_bfd_score_elf_discard_info (bfd *abfd,
3637
                               struct elf_reloc_cookie *cookie,
3638
                               struct bfd_link_info *info)
3639
{
3640
  asection *o;
3641
  bfd_boolean ret = FALSE;
3642
  unsigned char *tdata;
3643
  size_t i, skip;
3644
 
3645
  o = bfd_get_section_by_name (abfd, ".pdr");
3646
  if ((!o) || (o->size == 0) || (o->size % PDR_SIZE != 0)
3647
      || (o->output_section != NULL && bfd_is_abs_section (o->output_section)))
3648
    return FALSE;
3649
 
3650
  tdata = bfd_zmalloc (o->size / PDR_SIZE);
3651
  if (!tdata)
3652
    return FALSE;
3653
 
3654
  cookie->rels = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, info->keep_memory);
3655
  if (!cookie->rels)
3656
    {
3657
      free (tdata);
3658
      return FALSE;
3659
    }
3660
 
3661
  cookie->rel = cookie->rels;
3662
  cookie->relend = cookie->rels + o->reloc_count;
3663
 
3664
  for (i = 0, skip = 0; i < o->size; i++)
3665
    {
3666
      if (bfd_elf_reloc_symbol_deleted_p (i * PDR_SIZE, cookie))
3667
        {
3668
          tdata[i] = 1;
3669
          skip++;
3670
        }
3671
    }
3672
 
3673
  if (skip != 0)
3674
    {
3675
      score_elf_section_data (o)->u.tdata = tdata;
3676
      o->size -= skip * PDR_SIZE;
3677
      ret = TRUE;
3678
    }
3679
  else
3680
    free (tdata);
3681
 
3682
  if (!info->keep_memory)
3683
    free (cookie->rels);
3684
 
3685
  return ret;
3686
}
3687
 
3688
/* Signal that discard_info() has removed the discarded relocations for this section.  */
3689
 
3690
bfd_boolean
3691
s7_bfd_score_elf_ignore_discarded_relocs (asection *sec)
3692
{
3693
  if (strcmp (sec->name, ".pdr") == 0)
3694
    return TRUE;
3695
  return FALSE;
3696
}
3697
 
3698
/* Return the section that should be marked against GC for a given
3699
   relocation.  */
3700
 
3701
asection *
3702
s7_bfd_score_elf_gc_mark_hook (asection *sec,
3703
                               struct bfd_link_info *info,
3704
                               Elf_Internal_Rela *rel,
3705
                               struct elf_link_hash_entry *h,
3706
                               Elf_Internal_Sym *sym)
3707
{
3708
  if (h != NULL)
3709
    switch (ELF32_R_TYPE (rel->r_info))
3710
      {
3711
      case R_SCORE_GNU_VTINHERIT:
3712
      case R_SCORE_GNU_VTENTRY:
3713
        return NULL;
3714
      }
3715
 
3716
  return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
3717
}
3718
 
3719
/* Support for core dump NOTE sections.  */
3720
 
3721
bfd_boolean
3722
s7_bfd_score_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
3723
{
3724
  int offset;
3725
  unsigned int raw_size;
3726
 
3727
  switch (note->descsz)
3728
    {
3729
    default:
3730
      return FALSE;
3731
    case 272:                  /* Linux/Score elf_prstatus */
3732
 
3733
      /* pr_cursig */
3734
      elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
3735
 
3736
      /* pr_pid */
3737
      elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
3738
 
3739
      /* pr_reg */
3740
      offset = 72;
3741
 
3742
      /* sizeof(elf_gregset_t) */
3743
      raw_size = 196;
3744
 
3745
      break;
3746
    }
3747
 
3748
  /* Make a ".reg/999" section.  */
3749
  return _bfd_elfcore_make_pseudosection (abfd, ".reg", raw_size, note->descpos + offset);
3750
}
3751
 
3752
bfd_boolean
3753
s7_bfd_score_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
3754
{
3755
  switch (note->descsz)
3756
    {
3757
    default:
3758
      return FALSE;
3759
 
3760
    case 128:                  /* Linux/Score elf_prpsinfo.  */
3761
      /* pr_fname */
3762
      elf_tdata (abfd)->core_program = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
3763
 
3764
      /* pr_psargs */
3765
      elf_tdata (abfd)->core_command = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
3766
      break;
3767
    }
3768
 
3769
  /* Note that for some reason, a spurious space is tacked
3770
     onto the end of the args in some (at least one anyway)
3771
     implementations, so strip it off if it exists.  */
3772
 
3773
  {
3774
    char *command = elf_tdata (abfd)->core_command;
3775
    int n = strlen (command);
3776
 
3777
    if (0 < n && command[n - 1] == ' ')
3778
      command[n - 1] = '\0';
3779
  }
3780
 
3781
  return TRUE;
3782
}
3783
 
3784
 
3785
/* Score BFD functions.  */
3786
 
3787
reloc_howto_type *
3788
s7_elf32_score_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
3789
{
3790
  unsigned int i;
3791
 
3792
  for (i = 0; i < ARRAY_SIZE (elf32_score_reloc_map); i++)
3793
    if (elf32_score_reloc_map[i].bfd_reloc_val == code)
3794
      return &elf32_score_howto_table[elf32_score_reloc_map[i].elf_reloc_val];
3795
 
3796
  return NULL;
3797
}
3798
 
3799
bfd_boolean
3800
s7_elf32_score_print_private_bfd_data (bfd *abfd, void * ptr)
3801
{
3802
  FILE *file = (FILE *) ptr;
3803
 
3804
  BFD_ASSERT (abfd != NULL && ptr != NULL);
3805
 
3806
  /* Print normal ELF private data.  */
3807
  _bfd_elf_print_private_bfd_data (abfd, ptr);
3808
 
3809
  /* xgettext:c-format */
3810
  fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
3811
  if (elf_elfheader (abfd)->e_flags & EF_SCORE_PIC)
3812
    {
3813
      fprintf (file, _(" [pic]"));
3814
    }
3815
  if (elf_elfheader (abfd)->e_flags & EF_SCORE_FIXDEP)
3816
    {
3817
      fprintf (file, _(" [fix dep]"));
3818
    }
3819
  fputc ('\n', file);
3820
 
3821
  return TRUE;
3822
}
3823
 
3824
bfd_boolean
3825
s7_elf32_score_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
3826
{
3827
  flagword in_flags;
3828
  flagword out_flags;
3829
 
3830
  if (!_bfd_generic_verify_endian_match (ibfd, obfd))
3831
    return FALSE;
3832
 
3833
  in_flags  = elf_elfheader (ibfd)->e_flags;
3834
  out_flags = elf_elfheader (obfd)->e_flags;
3835
 
3836
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
3837
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
3838
    return TRUE;
3839
 
3840
  in_flags = elf_elfheader (ibfd)->e_flags;
3841
  out_flags = elf_elfheader (obfd)->e_flags;
3842
 
3843
  if (! elf_flags_init (obfd))
3844
    {
3845
      elf_flags_init (obfd) = TRUE;
3846
      elf_elfheader (obfd)->e_flags = in_flags;
3847
 
3848
      if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
3849
          && bfd_get_arch_info (obfd)->the_default)
3850
        {
3851
          return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
3852
        }
3853
 
3854
      return TRUE;
3855
    }
3856
 
3857
  if (((in_flags & EF_SCORE_PIC) != 0) != ((out_flags & EF_SCORE_PIC) != 0))
3858
    {
3859
      (*_bfd_error_handler) (_("%B: warning: linking PIC files with non-PIC files"), ibfd);
3860
    }
3861
 
3862
  /* Maybe dependency fix compatibility should be checked here.  */
3863
  return TRUE;
3864
}
3865
 
3866
bfd_boolean
3867
s7_elf32_score_new_section_hook (bfd *abfd, asection *sec)
3868
{
3869
  struct _score_elf_section_data *sdata;
3870
  bfd_size_type amt = sizeof (*sdata);
3871
 
3872
  sdata = bfd_zalloc (abfd, amt);
3873
  if (sdata == NULL)
3874
    return FALSE;
3875
  sec->used_by_bfd = sdata;
3876
 
3877
  return _bfd_elf_new_section_hook (abfd, sec);
3878
}
3879
 
3880
#define elf_backend_omit_section_dynsym \
3881
  ((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.