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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [bfd/] [elf32-score7.c] - Blame information for rev 833

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

Line No. Rev Author Line
1 227 jeremybenn
/* 32-bit ELF support for S+core.
2
   Copyright 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
  struct score_got_info *g;
1642
 
1643
  g = score_elf_got_info (dynobj, &sgot);
1644
  gp = _bfd_get_gp_value (output_bfd);
1645
 
1646
  return sgot->output_section->vma + sgot->output_offset + got_index - gp;
1647
}
1648
 
1649
/* Follow indirect and warning hash entries so that each got entry
1650
   points to the final symbol definition.  P must point to a pointer
1651
   to the hash table we're traversing.  Since this traversal may
1652
   modify the hash table, we set this pointer to NULL to indicate
1653
   we've made a potentially-destructive change to the hash table, so
1654
   the traversal must be restarted.  */
1655
 
1656
static int
1657
score_elf_resolve_final_got_entry (void **entryp, void *p)
1658
{
1659
  struct score_got_entry *entry = (struct score_got_entry *) *entryp;
1660
  htab_t got_entries = *(htab_t *) p;
1661
 
1662
  if (entry->abfd != NULL && entry->symndx == -1)
1663
    {
1664
      struct score_elf_link_hash_entry *h = entry->d.h;
1665
 
1666
      while (h->root.root.type == bfd_link_hash_indirect
1667
             || h->root.root.type == bfd_link_hash_warning)
1668
        h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
1669
 
1670
      if (entry->d.h == h)
1671
        return 1;
1672
 
1673
      entry->d.h = h;
1674
 
1675
      /* If we can't find this entry with the new bfd hash, re-insert
1676
         it, and get the traversal restarted.  */
1677
      if (! htab_find (got_entries, entry))
1678
        {
1679
          htab_clear_slot (got_entries, entryp);
1680
          entryp = htab_find_slot (got_entries, entry, INSERT);
1681
          if (! *entryp)
1682
            *entryp = entry;
1683
          /* Abort the traversal, since the whole table may have
1684
             moved, and leave it up to the parent to restart the
1685
             process.  */
1686
          *(htab_t *) p = NULL;
1687
          return 0;
1688
        }
1689
      /* We might want to decrement the global_gotno count, but it's
1690
         either too early or too late for that at this point.  */
1691
    }
1692
 
1693
  return 1;
1694
}
1695
 
1696
/* Turn indirect got entries in a got_entries table into their final locations.  */
1697
 
1698
static void
1699
score_elf_resolve_final_got_entries (struct score_got_info *g)
1700
{
1701
  htab_t got_entries;
1702
 
1703
  do
1704
    {
1705
      got_entries = g->got_entries;
1706
 
1707
      htab_traverse (got_entries,
1708
                     score_elf_resolve_final_got_entry,
1709
                     &got_entries);
1710
    }
1711
  while (got_entries == NULL);
1712
}
1713
 
1714
/* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS. for -r  */
1715
 
1716
static void
1717
score_elf_add_to_rel (bfd *abfd,
1718
                      bfd_byte *address,
1719
                      reloc_howto_type *howto,
1720
                      bfd_signed_vma increment)
1721
{
1722
  bfd_signed_vma addend;
1723
  bfd_vma contents;
1724
  unsigned long offset;
1725
  unsigned long r_type = howto->type;
1726
  unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
1727
 
1728
  contents = bfd_get_32 (abfd, address);
1729
  /* Get the (signed) value from the instruction.  */
1730
  addend = contents & howto->src_mask;
1731
  if (addend & ((howto->src_mask + 1) >> 1))
1732
    {
1733
      bfd_signed_vma mask;
1734
 
1735
      mask = -1;
1736
      mask &= ~howto->src_mask;
1737
      addend |= mask;
1738
    }
1739
  /* Add in the increment, (which is a byte value).  */
1740
  switch (r_type)
1741
    {
1742
    case R_SCORE_PC19:
1743
      offset =
1744
        (((contents & howto->src_mask) & 0x3ff0000) >> 6) | ((contents & howto->src_mask) & 0x3ff);
1745
      offset += increment;
1746
      contents =
1747
        (contents & ~howto->
1748
         src_mask) | (((offset << 6) & howto->src_mask) & 0x3ff0000) | (offset & 0x3ff);
1749
      bfd_put_32 (abfd, contents, address);
1750
      break;
1751
    case R_SCORE_HI16:
1752
      break;
1753
    case R_SCORE_LO16:
1754
      hi16_addend = bfd_get_32 (abfd, address - 4);
1755
      hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
1756
      offset = ((((contents >> 16) & 0x3) << 15) | (contents & 0x7fff)) >> 1;
1757
      offset = (hi16_offset << 16) | (offset & 0xffff);
1758
      uvalue = increment + offset;
1759
      hi16_offset = (uvalue >> 16) << 1;
1760
      hi16_value = (hi16_addend & (~(howto->dst_mask)))
1761
        | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
1762
      bfd_put_32 (abfd, hi16_value, address - 4);
1763
      offset = (uvalue & 0xffff) << 1;
1764
      contents = (contents & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
1765
      bfd_put_32 (abfd, contents, address);
1766
      break;
1767
    case R_SCORE_24:
1768
      offset =
1769
        (((contents & howto->src_mask) >> 1) & 0x1ff8000) | ((contents & howto->src_mask) & 0x7fff);
1770
      offset += increment;
1771
      contents =
1772
        (contents & ~howto->
1773
         src_mask) | (((offset << 1) & howto->src_mask) & 0x3ff0000) | (offset & 0x7fff);
1774
      bfd_put_32 (abfd, contents, address);
1775
      break;
1776
    case R_SCORE16_11:
1777
 
1778
      contents = bfd_get_16 (abfd, address);
1779
      offset = contents & howto->src_mask;
1780
      offset += increment;
1781
      contents = (contents & ~howto->src_mask) | (offset & howto->src_mask);
1782
      bfd_put_16 (abfd, contents, address);
1783
 
1784
      break;
1785
    case R_SCORE16_PC8:
1786
 
1787
      contents = bfd_get_16 (abfd, address);
1788
      offset = (contents & howto->src_mask) + ((increment >> 1) & 0xff);
1789
      contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask);
1790
      bfd_put_16 (abfd, contents, address);
1791
 
1792
      break;
1793
    case R_SCORE_GOT15:
1794
    case R_SCORE_GOT_LO16:
1795
      break;
1796
 
1797
    default:
1798
      addend += increment;
1799
      contents = (contents & ~howto->dst_mask) | (addend & howto->dst_mask);
1800
      bfd_put_32 (abfd, contents, address);
1801
      break;
1802
    }
1803
}
1804
 
1805
/* Perform a relocation as part of a final link.  */
1806
 
1807
static bfd_reloc_status_type
1808
score_elf_final_link_relocate (reloc_howto_type *howto,
1809
                               bfd *input_bfd,
1810
                               bfd *output_bfd,
1811
                               asection *input_section,
1812
                               bfd_byte *contents,
1813
                               Elf_Internal_Rela *rel,
1814
                               Elf_Internal_Rela *relocs,
1815
                               bfd_vma symbol,
1816
                               struct bfd_link_info *info,
1817
                               const char *sym_name ATTRIBUTE_UNUSED,
1818
                               int sym_flags ATTRIBUTE_UNUSED,
1819
                               struct score_elf_link_hash_entry *h,
1820
                               Elf_Internal_Sym *local_syms,
1821
                               asection **local_sections,
1822
                               bfd_boolean gp_disp_p)
1823
{
1824
  unsigned long r_type;
1825
  unsigned long r_symndx;
1826
  bfd_byte *hit_data = contents + rel->r_offset;
1827
  bfd_vma addend;
1828
  /* The final GP value to be used for the relocatable, executable, or
1829
     shared object file being produced.  */
1830
  bfd_vma gp = MINUS_ONE;
1831
  /* The place (section offset or address) of the storage unit being relocated.  */
1832
  bfd_vma rel_addr;
1833
  /* The value of GP used to create the relocatable object.  */
1834
  bfd_vma gp0 = MINUS_ONE;
1835
  /* The offset into the global offset table at which the address of the relocation entry
1836
     symbol, adjusted by the addend, resides during execution.  */
1837
  bfd_vma g = MINUS_ONE;
1838
  /* TRUE if the symbol referred to by this relocation is a local symbol.  */
1839
  bfd_boolean local_p;
1840
  /* The eventual value we will relocate.  */
1841
  bfd_vma value = symbol;
1842
  unsigned long hi16_addend, hi16_offset, hi16_value, uvalue, offset, abs_value = 0;
1843
 
1844
  Elf_Internal_Sym *sym = 0;
1845
  asection *sec = NULL;
1846
  bfd_boolean merge_p = 0;
1847
 
1848
 
1849
  if (elf_gp (output_bfd) == 0)
1850
    {
1851
      struct bfd_link_hash_entry *bh;
1852
      asection *o;
1853
 
1854
      bh = bfd_link_hash_lookup (info->hash, "_gp", 0, 0, 1);
1855
      if (bh != NULL && bh->type == bfd_link_hash_defined)
1856
        elf_gp (output_bfd) = (bh->u.def.value
1857
                               + bh->u.def.section->output_section->vma
1858
                               + bh->u.def.section->output_offset);
1859
      else if (info->relocatable)
1860
        {
1861
          bfd_vma lo = -1;
1862
 
1863
          /* Find the GP-relative section with the lowest offset.  */
1864
          for (o = output_bfd->sections; o != NULL; o = o->next)
1865
            if (o->vma < lo)
1866
              lo = o->vma;
1867
          /* And calculate GP relative to that.  */
1868
          elf_gp (output_bfd) = lo + ELF_SCORE_GP_OFFSET (input_bfd);
1869
        }
1870
      else
1871
        {
1872
          /* If the relocate_section function needs to do a reloc
1873
             involving the GP value, it should make a reloc_dangerous
1874
             callback to warn that GP is not defined.  */
1875
        }
1876
    }
1877
 
1878
  /* Parse the relocation.  */
1879
  r_symndx = ELF32_R_SYM (rel->r_info);
1880
  r_type = ELF32_R_TYPE (rel->r_info);
1881
  rel_addr = (input_section->output_section->vma + input_section->output_offset + rel->r_offset);
1882
 
1883
  /* For hidden symbol.  */
1884
  local_p = score_elf_local_relocation_p (input_bfd, rel, local_sections, FALSE);
1885
  if (local_p)
1886
    {
1887
      sym = local_syms + r_symndx;
1888
      sec = local_sections[r_symndx];
1889
 
1890
      symbol = sec->output_section->vma + sec->output_offset;
1891
      if (ELF_ST_TYPE (sym->st_info) != STT_SECTION
1892
          || (sec->flags & SEC_MERGE))
1893
        symbol += sym->st_value;
1894
      if ((sec->flags & SEC_MERGE)
1895
          && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1896
        merge_p = 1;
1897
    }
1898
 
1899
  if (r_type == R_SCORE_GOT15)
1900
    {
1901
      const Elf_Internal_Rela *relend;
1902
      const Elf_Internal_Rela *lo16_rel;
1903
      const struct elf_backend_data *bed;
1904
      bfd_vma lo_value = 0;
1905
 
1906
      bed = get_elf_backend_data (output_bfd);
1907
      relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
1908
      lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
1909
      if ((local_p) && (lo16_rel != NULL))
1910
        {
1911
          bfd_vma tmp = 0;
1912
          tmp = bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
1913
          lo_value = (((tmp >> 16) & 0x3) << 14) | ((tmp & 0x7fff) >> 1);
1914
          if (merge_p)
1915
            {
1916
              asection *msec = sec;
1917
              lo_value = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, lo_value);
1918
              lo_value -= symbol;
1919
              lo_value += msec->output_section->vma + msec->output_offset;
1920
            }
1921
        }
1922
      addend = lo_value;
1923
    }
1924
  else
1925
    {
1926
      addend = (bfd_get_32 (input_bfd, hit_data) >> howto->bitpos) & howto->src_mask;
1927
    }
1928
 
1929
  /* Figure out the value of the symbol.  */
1930
  if (local_p && !merge_p)
1931
    {
1932
      if (r_type == R_SCORE_GOT15)
1933
        {
1934
          const Elf_Internal_Rela *relend;
1935
          const Elf_Internal_Rela *lo16_rel;
1936
          const struct elf_backend_data *bed;
1937
          bfd_vma lo_value = 0;
1938
 
1939
          value = bfd_get_32 (input_bfd, contents + rel->r_offset);
1940
          addend = value & 0x7fff;
1941
          if ((addend & 0x4000) == 0x4000)
1942
            addend |= 0xffffc000;
1943
 
1944
          bed = get_elf_backend_data (output_bfd);
1945
          relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
1946
          lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
1947
          if ((local_p) && (lo16_rel != NULL))
1948
            {
1949
              bfd_vma tmp = 0;
1950
              tmp = bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
1951
              lo_value = (((tmp >> 16) & 0x3) << 14) | ((tmp & 0x7fff) >> 1);
1952
            }
1953
 
1954
          addend <<= 16;
1955
          addend += lo_value;
1956
        }
1957
    }
1958
 
1959
  local_p = score_elf_local_relocation_p (input_bfd, rel, local_sections, TRUE);
1960
 
1961
  /* If we haven't already determined the GOT offset, or the GP value,
1962
     and we're going to need it, get it now.  */
1963
  switch (r_type)
1964
    {
1965
    case R_SCORE_CALL15:
1966
    case R_SCORE_GOT15:
1967
      if (!local_p)
1968
        {
1969
          g = score_elf_global_got_index (elf_hash_table (info)->dynobj,
1970
                                          (struct elf_link_hash_entry *) h);
1971
          if ((! elf_hash_table(info)->dynamic_sections_created
1972
               || (info->shared
1973
                   && (info->symbolic || h->root.dynindx == -1)
1974
                   && h->root.def_regular)))
1975
            {
1976
              /* This is a static link or a -Bsymbolic link.  The
1977
                 symbol is defined locally, or was forced to be local.
1978
                 We must initialize this entry in the GOT.  */
1979
              bfd *tmpbfd = elf_hash_table (info)->dynobj;
1980
              asection *sgot = score_elf_got_section (tmpbfd, FALSE);
1981
              bfd_put_32 (tmpbfd, value, sgot->contents + g);
1982
            }
1983
        }
1984
      else if (r_type == R_SCORE_GOT15 || r_type == R_SCORE_CALL15)
1985
        {
1986
          /* There's no need to create a local GOT entry here; the
1987
             calculation for a local GOT15 entry does not involve G.  */
1988
          ;
1989
        }
1990
      else
1991
        {
1992
          g = score_elf_local_got_index (output_bfd, input_bfd, info,
1993
                                         symbol + addend, r_symndx, h, r_type);
1994
            if (g == MINUS_ONE)
1995
            return bfd_reloc_outofrange;
1996
        }
1997
 
1998
      /* Convert GOT indices to actual offsets.  */
1999
      g = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
2000
                                           output_bfd, input_bfd, g);
2001
      break;
2002
 
2003
    case R_SCORE_HI16:
2004
    case R_SCORE_LO16:
2005
    case R_SCORE_GPREL32:
2006
      gp0 = _bfd_get_gp_value (input_bfd);
2007
      gp = _bfd_get_gp_value (output_bfd);
2008
      break;
2009
 
2010
    case R_SCORE_GP15:
2011
      gp = _bfd_get_gp_value (output_bfd);
2012
 
2013
    default:
2014
      break;
2015
    }
2016
 
2017
  switch (r_type)
2018
    {
2019
    case R_SCORE_NONE:
2020
      return bfd_reloc_ok;
2021
 
2022
    case R_SCORE_ABS32:
2023
    case R_SCORE_REL32:
2024
      if ((info->shared
2025
           || (elf_hash_table (info)->dynamic_sections_created
2026
               && h != NULL
2027
               && h->root.def_dynamic
2028
               && !h->root.def_regular))
2029
           && r_symndx != 0
2030
           && (input_section->flags & SEC_ALLOC) != 0)
2031
        {
2032
          /* If we're creating a shared library, or this relocation is against a symbol
2033
             in a shared library, then we can't know where the symbol will end up.
2034
             So, we create a relocation record in the output, and leave the job up
2035
             to the dynamic linker.  */
2036
          value = addend;
2037
          if (!score_elf_create_dynamic_relocation (output_bfd, info, rel, h,
2038
                                                    symbol, &value,
2039
                                                    input_section))
2040
            return bfd_reloc_undefined;
2041
        }
2042
      else if (r_symndx == 0)
2043
        /* r_symndx will be zero only for relocs against symbols
2044
           from removed linkonce sections, or sections discarded by
2045
           a linker script.  */
2046
        value = 0;
2047
      else
2048
        {
2049
          if (r_type != R_SCORE_REL32)
2050
            value = symbol + addend;
2051
          else
2052
            value = addend;
2053
        }
2054
      value &= howto->dst_mask;
2055
      bfd_put_32 (input_bfd, value, hit_data);
2056
      return bfd_reloc_ok;
2057
 
2058
    case R_SCORE_ABS16:
2059
      value += addend;
2060
      if ((long) value > 0x7fff || (long) value < -0x8000)
2061
        return bfd_reloc_overflow;
2062
      bfd_put_16 (input_bfd, value, hit_data);
2063
      return bfd_reloc_ok;
2064
 
2065
    case R_SCORE_24:
2066
      addend = bfd_get_32 (input_bfd, hit_data);
2067
      offset = (((addend & howto->src_mask) >> 1) & 0x1ff8000) | ((addend & howto->src_mask) & 0x7fff);
2068
      if ((offset & 0x1000000) != 0)
2069
        offset |= 0xfe000000;
2070
      value += offset;
2071
      abs_value = abs (value - rel_addr);
2072
      if ((abs_value & 0xfe000000) != 0)
2073
        return bfd_reloc_overflow;
2074
      addend = (addend & ~howto->src_mask)
2075
                | (((value << 1) & howto->src_mask) & 0x3ff0000) | (value & 0x7fff);
2076
      bfd_put_32 (input_bfd, addend, hit_data);
2077
      return bfd_reloc_ok;
2078
 
2079
    case R_SCORE_PC19:
2080
      addend = bfd_get_32 (input_bfd, hit_data);
2081
      offset = (((addend & howto->src_mask) & 0x3ff0000) >> 6) | ((addend & howto->src_mask) & 0x3ff);
2082
      if ((offset & 0x80000) != 0)
2083
        offset |= 0xfff00000;
2084
      abs_value = value = value - rel_addr + offset;
2085
      /* exceed 20 bit : overflow.  */
2086
      if ((abs_value & 0x80000000) == 0x80000000)
2087
        abs_value = 0xffffffff - value + 1;
2088
      if ((abs_value & 0xfff80000) != 0)
2089
        return bfd_reloc_overflow;
2090
      addend = (addend & ~howto->src_mask)
2091
                | (((value << 6) & howto->src_mask) & 0x3ff0000) | (value & 0x3ff);
2092
      bfd_put_32 (input_bfd, addend, hit_data);
2093
      return bfd_reloc_ok;
2094
 
2095
    case R_SCORE16_11:
2096
      addend = bfd_get_16 (input_bfd, hit_data);
2097
      offset = addend & howto->src_mask;
2098
      if ((offset & 0x800) != 0)        /* Offset is negative.  */
2099
        offset |= 0xfffff000;
2100
      value += offset;
2101
      abs_value = abs (value - rel_addr);
2102
      if ((abs_value & 0xfffff000) != 0)
2103
        return bfd_reloc_overflow;
2104
      addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
2105
      bfd_put_16 (input_bfd, addend, hit_data);
2106
      return bfd_reloc_ok;
2107
 
2108
    case R_SCORE16_PC8:
2109
      addend = bfd_get_16 (input_bfd, hit_data);
2110
      offset = (addend & howto->src_mask) << 1;
2111
      if ((offset & 0x100) != 0)        /* Offset is negative.  */
2112
        offset |= 0xfffffe00;
2113
      abs_value = value = value - rel_addr + offset;
2114
      /* Sign bit + exceed 9 bit.  */
2115
      if (((value & 0xffffff00) != 0) && ((value & 0xffffff00) != 0xffffff00))
2116
        return bfd_reloc_overflow;
2117
      value >>= 1;
2118
      addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
2119
      bfd_put_16 (input_bfd, addend, hit_data);
2120
      return bfd_reloc_ok;
2121
 
2122
    case R_SCORE_HI16:
2123
      return bfd_reloc_ok;
2124
 
2125
    case R_SCORE_LO16:
2126
      hi16_addend = bfd_get_32 (input_bfd, hit_data - 4);
2127
      hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
2128
      addend = bfd_get_32 (input_bfd, hit_data);
2129
      offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
2130
      offset = (hi16_offset << 16) | (offset & 0xffff);
2131
 
2132
      if (!gp_disp_p)
2133
        uvalue = value + offset;
2134
      else
2135
        uvalue = offset + gp - rel_addr + 4;
2136
 
2137
      hi16_offset = (uvalue >> 16) << 1;
2138
      hi16_value = (hi16_addend & (~(howto->dst_mask)))
2139
                        | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
2140
      bfd_put_32 (input_bfd, hi16_value, hit_data - 4);
2141
      offset = (uvalue & 0xffff) << 1;
2142
      value = (addend & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
2143
      bfd_put_32 (input_bfd, value, hit_data);
2144
      return bfd_reloc_ok;
2145
 
2146
    case R_SCORE_GP15:
2147
      addend = bfd_get_32 (input_bfd, hit_data);
2148
      offset = addend & 0x7fff;
2149
      if ((offset & 0x4000) == 0x4000)
2150
        offset |= 0xffffc000;
2151
      value = value + offset - gp;
2152
      if (((value & 0xffffc000) != 0) && ((value & 0xffffc000) != 0xffffc000))
2153
        return bfd_reloc_overflow;
2154
      value = (addend & ~howto->src_mask) | (value & howto->src_mask);
2155
      bfd_put_32 (input_bfd, value, hit_data);
2156
      return bfd_reloc_ok;
2157
 
2158
    case R_SCORE_GOT15:
2159
    case R_SCORE_CALL15:
2160
      if (local_p)
2161
        {
2162
          bfd_boolean forced;
2163
 
2164
          /* The special case is when the symbol is forced to be local.  We need the
2165
             full address in the GOT since no R_SCORE_GOT_LO16 relocation follows.  */
2166
          forced = ! score_elf_local_relocation_p (input_bfd, rel,
2167
                                                   local_sections, FALSE);
2168
          value = score_elf_got16_entry (output_bfd, input_bfd, info,
2169
                                         symbol + addend, forced);
2170
          if (value == MINUS_ONE)
2171
            return bfd_reloc_outofrange;
2172
          value = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
2173
                                                   output_bfd, input_bfd, value);
2174
        }
2175
      else
2176
        {
2177
          value = g;
2178
        }
2179
 
2180
      if ((long) value > 0x3fff || (long) value < -0x4000)
2181
        return bfd_reloc_overflow;
2182
 
2183
      addend = bfd_get_32 (input_bfd, hit_data);
2184
      value = (addend & ~howto->dst_mask) | (value & howto->dst_mask);
2185
      bfd_put_32 (input_bfd, value, hit_data);
2186
      return bfd_reloc_ok;
2187
 
2188
    case R_SCORE_GPREL32:
2189
      value = (addend + symbol + gp0 - gp);
2190
      value &= howto->dst_mask;
2191
      bfd_put_32 (input_bfd, value, hit_data);
2192
      return bfd_reloc_ok;
2193
 
2194
    case R_SCORE_GOT_LO16:
2195
      addend = bfd_get_32 (input_bfd, hit_data);
2196
      value = (((addend >> 16) & 0x3) << 14) | ((addend & 0x7fff) >> 1);
2197
      value += symbol;
2198
      value = (addend & (~(howto->dst_mask))) | ((value & 0x3fff) << 1)
2199
               | (((value >> 14) & 0x3) << 16);
2200
 
2201
      bfd_put_32 (input_bfd, value, hit_data);
2202
      return bfd_reloc_ok;
2203
 
2204
    case R_SCORE_DUMMY_HI16:
2205
      return bfd_reloc_ok;
2206
 
2207
    case R_SCORE_GNU_VTINHERIT:
2208
    case R_SCORE_GNU_VTENTRY:
2209
      /* We don't do anything with these at present.  */
2210
      return bfd_reloc_continue;
2211
 
2212
    default:
2213
      return bfd_reloc_notsupported;
2214
    }
2215
}
2216
 
2217
/* Score backend functions.  */
2218
 
2219
void
2220
s7_bfd_score_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
2221
                            arelent *bfd_reloc,
2222
                            Elf_Internal_Rela *elf_reloc)
2223
{
2224
  unsigned int r_type;
2225
 
2226
  r_type = ELF32_R_TYPE (elf_reloc->r_info);
2227
  if (r_type >= ARRAY_SIZE (elf32_score_howto_table))
2228
    bfd_reloc->howto = NULL;
2229
  else
2230
    bfd_reloc->howto = &elf32_score_howto_table[r_type];
2231
}
2232
 
2233
/* Relocate an score ELF section.  */
2234
 
2235
bfd_boolean
2236
s7_bfd_score_elf_relocate_section (bfd *output_bfd,
2237
                                   struct bfd_link_info *info,
2238
                                   bfd *input_bfd,
2239
                                   asection *input_section,
2240
                                   bfd_byte *contents,
2241
                                   Elf_Internal_Rela *relocs,
2242
                                   Elf_Internal_Sym *local_syms,
2243
                                   asection **local_sections)
2244
{
2245
  Elf_Internal_Shdr *symtab_hdr;
2246
  struct elf_link_hash_entry **sym_hashes;
2247
  Elf_Internal_Rela *rel;
2248
  Elf_Internal_Rela *relend;
2249
  const char *name;
2250
  unsigned long offset;
2251
  unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
2252
  size_t extsymoff;
2253
  bfd_boolean gp_disp_p = FALSE;
2254
 
2255
  /* Sort dynsym.  */
2256
  if (elf_hash_table (info)->dynamic_sections_created)
2257
    {
2258
      bfd_size_type dynsecsymcount = 0;
2259
      if (info->shared)
2260
        {
2261
          asection * p;
2262
          const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
2263
 
2264
          for (p = output_bfd->sections; p ; p = p->next)
2265
            if ((p->flags & SEC_EXCLUDE) == 0
2266
                && (p->flags & SEC_ALLOC) != 0
2267
                && !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p))
2268
              ++ dynsecsymcount;
2269
        }
2270
 
2271
      if (!score_elf_sort_hash_table (info, dynsecsymcount + 1))
2272
        return FALSE;
2273
    }
2274
 
2275
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
2276
  extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
2277
  sym_hashes = elf_sym_hashes (input_bfd);
2278
  rel = relocs;
2279
  relend = relocs + input_section->reloc_count;
2280
  for (; rel < relend; rel++)
2281
    {
2282
      int r_type;
2283
      reloc_howto_type *howto;
2284
      unsigned long r_symndx;
2285
      Elf_Internal_Sym *sym;
2286
      asection *sec;
2287
      struct score_elf_link_hash_entry *h;
2288
      bfd_vma relocation = 0;
2289
      bfd_reloc_status_type r;
2290
      arelent bfd_reloc;
2291
 
2292
      r_symndx = ELF32_R_SYM (rel->r_info);
2293
      r_type = ELF32_R_TYPE (rel->r_info);
2294
 
2295
      s7_bfd_score_info_to_howto (input_bfd, &bfd_reloc, (Elf_Internal_Rela *) rel);
2296
      howto = bfd_reloc.howto;
2297
 
2298
      h = NULL;
2299
      sym = NULL;
2300
      sec = NULL;
2301
 
2302
      if (r_symndx < extsymoff)
2303
        {
2304
          sym = local_syms + r_symndx;
2305
          sec = local_sections[r_symndx];
2306
          relocation = sec->output_section->vma + sec->output_offset;
2307
          name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, sec);
2308
 
2309
          if (!info->relocatable)
2310
            {
2311
              if (ELF_ST_TYPE (sym->st_info) != STT_SECTION
2312
                      || (sec->flags & SEC_MERGE))
2313
                {
2314
                      relocation += sym->st_value;
2315
                    }
2316
 
2317
              if ((sec->flags & SEC_MERGE)
2318
                      && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2319
                {
2320
                  asection *msec;
2321
                  bfd_vma addend, value;
2322
 
2323
                  switch (r_type)
2324
                    {
2325
                    case R_SCORE_HI16:
2326
                      break;
2327
                    case R_SCORE_LO16:
2328
                      hi16_addend = bfd_get_32 (input_bfd, contents + rel->r_offset - 4);
2329
                      hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
2330
                      value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2331
                      offset = ((((value >> 16) & 0x3) << 15) | (value & 0x7fff)) >> 1;
2332
                      addend = (hi16_offset << 16) | (offset & 0xffff);
2333
                      msec = sec;
2334
                      addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend);
2335
                      addend -= relocation;
2336
                      addend += msec->output_section->vma + msec->output_offset;
2337
                      uvalue = addend;
2338
                      hi16_offset = (uvalue >> 16) << 1;
2339
                      hi16_value = (hi16_addend & (~(howto->dst_mask)))
2340
                        | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
2341
                      bfd_put_32 (input_bfd, hi16_value, contents + rel->r_offset - 4);
2342
                      offset = (uvalue & 0xffff) << 1;
2343
                      value = (value & (~(howto->dst_mask)))
2344
                        | (offset & 0x7fff) | ((offset << 1) & 0x30000);
2345
                      bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2346
                      break;
2347
                    case R_SCORE_GOT_LO16:
2348
                      value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2349
                      addend = (((value >> 16) & 0x3) << 14) | ((value & 0x7fff) >> 1);
2350
                      msec = sec;
2351
                      addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
2352
                      addend += msec->output_section->vma + msec->output_offset;
2353
                      value = (value & (~(howto->dst_mask))) | ((addend & 0x3fff) << 1)
2354
                               | (((addend >> 14) & 0x3) << 16);
2355
 
2356
                      bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2357
                      break;
2358
                    default:
2359
                      value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2360
                      /* Get the (signed) value from the instruction.  */
2361
                      addend = value & howto->src_mask;
2362
                      if (addend & ((howto->src_mask + 1) >> 1))
2363
                        {
2364
                          bfd_signed_vma mask;
2365
 
2366
                          mask = -1;
2367
                          mask &= ~howto->src_mask;
2368
                          addend |= mask;
2369
                        }
2370
                      msec = sec;
2371
                      addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
2372
                      addend += msec->output_section->vma + msec->output_offset;
2373
                      value = (value & ~howto->dst_mask) | (addend & howto->dst_mask);
2374
                      bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2375
                      break;
2376
                    }
2377
                }
2378
            }
2379
        }
2380
      else
2381
        {
2382
          /* For global symbols we look up the symbol in the hash-table.  */
2383
          h = ((struct score_elf_link_hash_entry *)
2384
               elf_sym_hashes (input_bfd) [r_symndx - extsymoff]);
2385
          /* Find the real hash-table entry for this symbol.  */
2386
          while (h->root.root.type == bfd_link_hash_indirect
2387
                 || h->root.root.type == bfd_link_hash_warning)
2388
            h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
2389
 
2390
          /* Record the name of this symbol, for our caller.  */
2391
          name = h->root.root.root.string;
2392
 
2393
          /* See if this is the special GP_DISP_LABEL symbol.  Note that such a
2394
             symbol must always be a global symbol.  */
2395
          if (strcmp (name, GP_DISP_LABEL) == 0)
2396
            {
2397
              /* Relocations against GP_DISP_LABEL are permitted only with
2398
                 R_SCORE_HI16 and R_SCORE_LO16 relocations.  */
2399
              if (r_type != R_SCORE_HI16 && r_type != R_SCORE_LO16)
2400
                return bfd_reloc_notsupported;
2401
 
2402
              gp_disp_p = TRUE;
2403
            }
2404
 
2405
          /* If this symbol is defined, calculate its address.  Note that
2406
              GP_DISP_LABEL is a magic symbol, always implicitly defined by the
2407
              linker, so it's inappropriate to check to see whether or not
2408
              its defined.  */
2409
          else if ((h->root.root.type == bfd_link_hash_defined
2410
                    || h->root.root.type == bfd_link_hash_defweak)
2411
                   && h->root.root.u.def.section)
2412
            {
2413
              sec = h->root.root.u.def.section;
2414
              if (sec->output_section)
2415
                relocation = (h->root.root.u.def.value
2416
                              + sec->output_section->vma
2417
                              + sec->output_offset);
2418
              else
2419
                {
2420
                  relocation = h->root.root.u.def.value;
2421
                }
2422
            }
2423
          else if (h->root.root.type == bfd_link_hash_undefweak)
2424
            /* We allow relocations against undefined weak symbols, giving
2425
               it the value zero, so that you can undefined weak functions
2426
               and check to see if they exist by looking at their addresses.  */
2427
            relocation = 0;
2428
          else if (info->unresolved_syms_in_objects == RM_IGNORE
2429
                   && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
2430
            relocation = 0;
2431
          else if (strcmp (name, "_DYNAMIC_LINK") == 0)
2432
            {
2433
              /* If this is a dynamic link, we should have created a _DYNAMIC_LINK symbol
2434
                 in s7_bfd_score_elf_create_dynamic_sections.  Otherwise, we should define
2435
                 the symbol with a value of 0.  */
2436
              BFD_ASSERT (! info->shared);
2437
              BFD_ASSERT (bfd_get_section_by_name (output_bfd, ".dynamic") == NULL);
2438
              relocation = 0;
2439
            }
2440
          else if (!info->relocatable)
2441
            {
2442
              if (! ((*info->callbacks->undefined_symbol)
2443
                     (info, h->root.root.root.string, input_bfd,
2444
                      input_section, rel->r_offset,
2445
                      (info->unresolved_syms_in_objects == RM_GENERATE_ERROR)
2446
                      || ELF_ST_VISIBILITY (h->root.other))))
2447
                return bfd_reloc_undefined;
2448
              relocation = 0;
2449
            }
2450
        }
2451
 
2452
      if (sec != NULL && elf_discarded_section (sec))
2453
        {
2454
          /* For relocs against symbols from removed linkonce sections,
2455
             or sections discarded by a linker script, we just want the
2456
             section contents zeroed.  Avoid any special processing.  */
2457
          _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
2458
          rel->r_info = 0;
2459
          rel->r_addend = 0;
2460
          continue;
2461
        }
2462
 
2463
      if (info->relocatable)
2464
        {
2465
          /* This is a relocatable link.  We don't have to change
2466
             anything, unless the reloc is against a section symbol,
2467
             in which case we have to adjust according to where the
2468
             section symbol winds up in the output section.  */
2469
          if (r_symndx < symtab_hdr->sh_info)
2470
            {
2471
              sym = local_syms + r_symndx;
2472
 
2473
              if (r_type == R_SCORE_GOT15)
2474
                {
2475
                  const Elf_Internal_Rela *lo16_rel;
2476
                  const struct elf_backend_data *bed;
2477
                  bfd_vma lo_addend = 0, lo_value = 0;
2478
                  bfd_vma addend, value;
2479
 
2480
                  value = bfd_get_32 (input_bfd, contents + rel->r_offset);
2481
                  addend = value & 0x7fff;
2482
                  if ((addend & 0x4000) == 0x4000)
2483
                    addend |= 0xffffc000;
2484
 
2485
                  bed = get_elf_backend_data (output_bfd);
2486
                  relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
2487
                  lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
2488
                  if (lo16_rel != NULL)
2489
                    {
2490
                      lo_value = bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
2491
                      lo_addend = (((lo_value >> 16) & 0x3) << 14) | ((lo_value & 0x7fff) >> 1);
2492
                    }
2493
 
2494
                  addend <<= 16;
2495
                  addend += lo_addend;
2496
 
2497
                  if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2498
                    addend += local_sections[r_symndx]->output_offset;
2499
 
2500
                  lo_addend = addend & 0xffff;
2501
                  lo_value = (lo_value & (~(howto->dst_mask))) | ((lo_addend & 0x3fff) << 1)
2502
                              | (((lo_addend >> 14) & 0x3) << 16);
2503
                  bfd_put_32 (input_bfd, lo_value, contents + lo16_rel->r_offset);
2504
 
2505
                  addend = addend >> 16;
2506
                  value = (value & ~howto->src_mask) | (addend & howto->src_mask);
2507
                  bfd_put_32 (input_bfd, value, contents + rel->r_offset);
2508
                }
2509
              else if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2510
                {
2511
                  sec = local_sections[r_symndx];
2512
                  score_elf_add_to_rel (input_bfd, contents + rel->r_offset,
2513
                                        howto, (bfd_signed_vma) (sec->output_offset + sym->st_value));
2514
                }
2515
            }
2516
          continue;
2517
        }
2518
 
2519
      /* This is a final link.  */
2520
      r = score_elf_final_link_relocate (howto, input_bfd, output_bfd,
2521
                                         input_section, contents, rel, relocs,
2522
                                         relocation, info, name,
2523
                                         (h ? ELF_ST_TYPE ((unsigned int) h->root.root.type) :
2524
                                         ELF_ST_TYPE ((unsigned int) sym->st_info)), h, local_syms,
2525
                                         local_sections, gp_disp_p);
2526
 
2527
      if (r != bfd_reloc_ok)
2528
        {
2529
          const char *msg = (const char *)0;
2530
 
2531
          switch (r)
2532
            {
2533
            case bfd_reloc_overflow:
2534
              /* If the overflowing reloc was to an undefined symbol,
2535
                 we have already printed one error message and there
2536
                 is no point complaining again.  */
2537
              if (((!h) || (h->root.root.type != bfd_link_hash_undefined))
2538
                  && (!((*info->callbacks->reloc_overflow)
2539
                        (info, NULL, name, howto->name, (bfd_vma) 0,
2540
                         input_bfd, input_section, rel->r_offset))))
2541
                return FALSE;
2542
              break;
2543
            case bfd_reloc_undefined:
2544
              if (!((*info->callbacks->undefined_symbol)
2545
                    (info, name, input_bfd, input_section, rel->r_offset, TRUE)))
2546
                return FALSE;
2547
              break;
2548
 
2549
            case bfd_reloc_outofrange:
2550
              msg = _("internal error: out of range error");
2551
              goto common_error;
2552
 
2553
            case bfd_reloc_notsupported:
2554
              msg = _("internal error: unsupported relocation error");
2555
              goto common_error;
2556
 
2557
            case bfd_reloc_dangerous:
2558
              msg = _("internal error: dangerous error");
2559
              goto common_error;
2560
 
2561
            default:
2562
              msg = _("internal error: unknown error");
2563
              /* fall through */
2564
 
2565
            common_error:
2566
              if (!((*info->callbacks->warning)
2567
                    (info, msg, name, input_bfd, input_section, rel->r_offset)))
2568
                return FALSE;
2569
              break;
2570
            }
2571
        }
2572
    }
2573
 
2574
  return TRUE;
2575
}
2576
 
2577
/* Look through the relocs for a section during the first phase, and
2578
   allocate space in the global offset table.  */
2579
 
2580
bfd_boolean
2581
s7_bfd_score_elf_check_relocs (bfd *abfd,
2582
                               struct bfd_link_info *info,
2583
                               asection *sec,
2584
                               const Elf_Internal_Rela *relocs)
2585
{
2586
  const char *name;
2587
  bfd *dynobj;
2588
  Elf_Internal_Shdr *symtab_hdr;
2589
  struct elf_link_hash_entry **sym_hashes;
2590
  struct score_got_info *g;
2591
  size_t extsymoff;
2592
  const Elf_Internal_Rela *rel;
2593
  const Elf_Internal_Rela *rel_end;
2594
  asection *sgot;
2595
  asection *sreloc;
2596
  const struct elf_backend_data *bed;
2597
 
2598
  if (info->relocatable)
2599
    return TRUE;
2600
 
2601
  dynobj = elf_hash_table (info)->dynobj;
2602
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2603
  sym_hashes = elf_sym_hashes (abfd);
2604
  extsymoff = (elf_bad_symtab (abfd)) ? 0 : symtab_hdr->sh_info;
2605
 
2606
  name = bfd_get_section_name (abfd, sec);
2607
 
2608
  if (dynobj == NULL)
2609
    {
2610
      sgot = NULL;
2611
      g = NULL;
2612
    }
2613
  else
2614
    {
2615
      sgot = score_elf_got_section (dynobj, FALSE);
2616
      if (sgot == NULL)
2617
        g = NULL;
2618
      else
2619
        {
2620
          BFD_ASSERT (score_elf_section_data (sgot) != NULL);
2621
          g = score_elf_section_data (sgot)->u.got_info;
2622
          BFD_ASSERT (g != NULL);
2623
        }
2624
    }
2625
 
2626
  sreloc = NULL;
2627
  bed = get_elf_backend_data (abfd);
2628
  rel_end = relocs + sec->reloc_count * bed->s->int_rels_per_ext_rel;
2629
  for (rel = relocs; rel < rel_end; ++rel)
2630
    {
2631
      unsigned long r_symndx;
2632
      unsigned int r_type;
2633
      struct elf_link_hash_entry *h;
2634
 
2635
      r_symndx = ELF32_R_SYM (rel->r_info);
2636
      r_type = ELF32_R_TYPE (rel->r_info);
2637
 
2638
      if (r_symndx < extsymoff)
2639
        {
2640
          h = NULL;
2641
        }
2642
      else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr))
2643
        {
2644
          (*_bfd_error_handler) (_("%s: Malformed reloc detected for section %s"), abfd, name);
2645
          bfd_set_error (bfd_error_bad_value);
2646
          return FALSE;
2647
        }
2648
      else
2649
        {
2650
          h = sym_hashes[r_symndx - extsymoff];
2651
 
2652
          /* This may be an indirect symbol created because of a version.  */
2653
          if (h != NULL)
2654
            {
2655
              while (h->root.type == bfd_link_hash_indirect)
2656
                h = (struct elf_link_hash_entry *) h->root.u.i.link;
2657
            }
2658
        }
2659
 
2660
      /* Some relocs require a global offset table.  */
2661
      if (dynobj == NULL || sgot == NULL)
2662
        {
2663
          switch (r_type)
2664
            {
2665
            case R_SCORE_GOT15:
2666
            case R_SCORE_CALL15:
2667
              if (dynobj == NULL)
2668
                elf_hash_table (info)->dynobj = dynobj = abfd;
2669
              if (!score_elf_create_got_section (dynobj, info, FALSE))
2670
                return FALSE;
2671
              g = score_elf_got_info (dynobj, &sgot);
2672
              break;
2673
            case R_SCORE_ABS32:
2674
            case R_SCORE_REL32:
2675
              if (dynobj == NULL && (info->shared || h != NULL) && (sec->flags & SEC_ALLOC) != 0)
2676
                elf_hash_table (info)->dynobj = dynobj = abfd;
2677
              break;
2678
            default:
2679
              break;
2680
            }
2681
        }
2682
 
2683
      if (!h && (r_type == R_SCORE_GOT_LO16))
2684
        {
2685
          if (! score_elf_record_local_got_symbol (abfd, r_symndx, rel->r_addend, g))
2686
            return FALSE;
2687
        }
2688
 
2689
      switch (r_type)
2690
        {
2691
        case R_SCORE_CALL15:
2692
          if (h == NULL)
2693
            {
2694
              (*_bfd_error_handler)
2695
                (_("%B: CALL15 reloc at 0x%lx not against global symbol"),
2696
                 abfd, (unsigned long) rel->r_offset);
2697
              bfd_set_error (bfd_error_bad_value);
2698
              return FALSE;
2699
            }
2700
          else
2701
            {
2702
              /* This symbol requires a global offset table entry.  */
2703
              if (! score_elf_record_global_got_symbol (h, abfd, info, g))
2704
                return FALSE;
2705
 
2706
              /* We need a stub, not a plt entry for the undefined function.  But we record
2707
                 it as if it needs plt.  See _bfd_elf_adjust_dynamic_symbol.  */
2708
              h->needs_plt = 1;
2709
              h->type = STT_FUNC;
2710
            }
2711
          break;
2712
        case R_SCORE_GOT15:
2713
          if (h && ! score_elf_record_global_got_symbol (h, abfd, info, g))
2714
            return FALSE;
2715
          break;
2716
        case R_SCORE_ABS32:
2717
        case R_SCORE_REL32:
2718
          if ((info->shared || h != NULL) && (sec->flags & SEC_ALLOC) != 0)
2719
            {
2720
              if (sreloc == NULL)
2721
                {
2722
                  sreloc = score_elf_rel_dyn_section (dynobj, TRUE);
2723
                  if (sreloc == NULL)
2724
                    return FALSE;
2725
                }
2726
#define SCORE_READONLY_SECTION (SEC_ALLOC | SEC_LOAD | SEC_READONLY)
2727
              if (info->shared)
2728
                {
2729
                  /* When creating a shared object, we must copy these reloc types into
2730
                     the output file as R_SCORE_REL32 relocs.  We make room for this reloc
2731
                     in the .rel.dyn reloc section.  */
2732
                  score_elf_allocate_dynamic_relocations (dynobj, 1);
2733
                  if ((sec->flags & SCORE_READONLY_SECTION)
2734
                      == SCORE_READONLY_SECTION)
2735
                    /* We tell the dynamic linker that there are
2736
                       relocations against the text segment.  */
2737
                    info->flags |= DF_TEXTREL;
2738
                }
2739
              else
2740
                {
2741
                  struct score_elf_link_hash_entry *hscore;
2742
 
2743
                  /* We only need to copy this reloc if the symbol is
2744
                     defined in a dynamic object.  */
2745
                  hscore = (struct score_elf_link_hash_entry *) h;
2746
                  ++hscore->possibly_dynamic_relocs;
2747
                  if ((sec->flags & SCORE_READONLY_SECTION)
2748
                      == SCORE_READONLY_SECTION)
2749
                    /* We need it to tell the dynamic linker if there
2750
                       are relocations against the text segment.  */
2751
                    hscore->readonly_reloc = TRUE;
2752
                }
2753
 
2754
              /* Even though we don't directly need a GOT entry for this symbol,
2755
                 a symbol must have a dynamic symbol table index greater that
2756
                 DT_SCORE_GOTSYM if there are dynamic relocations against it.  */
2757
              if (h != NULL)
2758
                {
2759
                  if (dynobj == NULL)
2760
                    elf_hash_table (info)->dynobj = dynobj = abfd;
2761
                  if (! score_elf_create_got_section (dynobj, info, TRUE))
2762
                    return FALSE;
2763
                  g = score_elf_got_info (dynobj, &sgot);
2764
                  if (! score_elf_record_global_got_symbol (h, abfd, info, g))
2765
                    return FALSE;
2766
                }
2767
            }
2768
          break;
2769
 
2770
          /* This relocation describes the C++ object vtable hierarchy.
2771
             Reconstruct it for later use during GC.  */
2772
        case R_SCORE_GNU_VTINHERIT:
2773
          if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
2774
            return FALSE;
2775
          break;
2776
 
2777
          /* This relocation describes which C++ vtable entries are actually
2778
             used.  Record for later use during GC.  */
2779
        case R_SCORE_GNU_VTENTRY:
2780
          if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
2781
            return FALSE;
2782
          break;
2783
        default:
2784
          break;
2785
        }
2786
 
2787
      /* We must not create a stub for a symbol that has relocations
2788
         related to taking the function's address.  */
2789
      switch (r_type)
2790
        {
2791
        default:
2792
          if (h != NULL)
2793
            {
2794
              struct score_elf_link_hash_entry *sh;
2795
 
2796
              sh = (struct score_elf_link_hash_entry *) h;
2797
              sh->no_fn_stub = TRUE;
2798
            }
2799
          break;
2800
        case R_SCORE_CALL15:
2801
          break;
2802
        }
2803
    }
2804
 
2805
  return TRUE;
2806
}
2807
 
2808
bfd_boolean
2809
s7_bfd_score_elf_add_symbol_hook (bfd *abfd,
2810
                                  struct bfd_link_info *info ATTRIBUTE_UNUSED,
2811
                                  Elf_Internal_Sym *sym,
2812
                                  const char **namep ATTRIBUTE_UNUSED,
2813
                                  flagword *flagsp ATTRIBUTE_UNUSED,
2814
                                  asection **secp,
2815
                                  bfd_vma *valp)
2816
{
2817
  switch (sym->st_shndx)
2818
    {
2819
    case SHN_COMMON:
2820
      if (sym->st_size > elf_gp_size (abfd))
2821
        break;
2822
      /* Fall through.  */
2823
    case SHN_SCORE_SCOMMON:
2824
      *secp = bfd_make_section_old_way (abfd, ".scommon");
2825
      (*secp)->flags |= SEC_IS_COMMON;
2826
      *valp = sym->st_size;
2827
      break;
2828
    }
2829
 
2830
  return TRUE;
2831
}
2832
 
2833
void
2834
s7_bfd_score_elf_symbol_processing (bfd *abfd, asymbol *asym)
2835
{
2836
  elf_symbol_type *elfsym;
2837
 
2838
  elfsym = (elf_symbol_type *) asym;
2839
  switch (elfsym->internal_elf_sym.st_shndx)
2840
    {
2841
    case SHN_COMMON:
2842
      if (asym->value > elf_gp_size (abfd))
2843
        break;
2844
      /* Fall through.  */
2845
    case SHN_SCORE_SCOMMON:
2846
      if (score_elf_scom_section.name == NULL)
2847
        {
2848
          /* Initialize the small common section.  */
2849
          score_elf_scom_section.name = ".scommon";
2850
          score_elf_scom_section.flags = SEC_IS_COMMON;
2851
          score_elf_scom_section.output_section = &score_elf_scom_section;
2852
          score_elf_scom_section.symbol = &score_elf_scom_symbol;
2853
          score_elf_scom_section.symbol_ptr_ptr = &score_elf_scom_symbol_ptr;
2854
          score_elf_scom_symbol.name = ".scommon";
2855
          score_elf_scom_symbol.flags = BSF_SECTION_SYM;
2856
          score_elf_scom_symbol.section = &score_elf_scom_section;
2857
          score_elf_scom_symbol_ptr = &score_elf_scom_symbol;
2858
        }
2859
      asym->section = &score_elf_scom_section;
2860
      asym->value = elfsym->internal_elf_sym.st_size;
2861
      break;
2862
    }
2863
}
2864
 
2865
int
2866
s7_bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
2867
                                          const char *name ATTRIBUTE_UNUSED,
2868
                                          Elf_Internal_Sym *sym,
2869
                                          asection *input_sec,
2870
                                          struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
2871
{
2872
  /* If we see a common symbol, which implies a relocatable link, then
2873
     if a symbol was small common in an input file, mark it as small
2874
     common in the output file.  */
2875
  if (sym->st_shndx == SHN_COMMON && strcmp (input_sec->name, ".scommon") == 0)
2876
    sym->st_shndx = SHN_SCORE_SCOMMON;
2877
 
2878
  return 1;
2879
}
2880
 
2881
bfd_boolean
2882
s7_bfd_score_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
2883
                                         asection *sec,
2884
                                         int *retval)
2885
{
2886
  if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
2887
    {
2888
      *retval = SHN_SCORE_SCOMMON;
2889
      return TRUE;
2890
    }
2891
 
2892
  return FALSE;
2893
}
2894
 
2895
/* Adjust a symbol defined by a dynamic object and referenced by a
2896
   regular object.  The current definition is in some section of the
2897
   dynamic object, but we're not including those sections.  We have to
2898
   change the definition to something the rest of the link can understand.  */
2899
 
2900
bfd_boolean
2901
s7_bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
2902
                                        struct elf_link_hash_entry *h)
2903
{
2904
  bfd *dynobj;
2905
  struct score_elf_link_hash_entry *hscore;
2906
  asection *s;
2907
 
2908
  dynobj = elf_hash_table (info)->dynobj;
2909
 
2910
  /* Make sure we know what is going on here.  */
2911
  BFD_ASSERT (dynobj != NULL
2912
              && (h->needs_plt
2913
                  || h->u.weakdef != NULL
2914
                  || (h->def_dynamic && h->ref_regular && !h->def_regular)));
2915
 
2916
  /* If this symbol is defined in a dynamic object, we need to copy
2917
     any R_SCORE_ABS32 or R_SCORE_REL32 relocs against it into the output
2918
     file.  */
2919
  hscore = (struct score_elf_link_hash_entry *) h;
2920
  if (!info->relocatable
2921
      && hscore->possibly_dynamic_relocs != 0
2922
      && (h->root.type == bfd_link_hash_defweak || !h->def_regular))
2923
    {
2924
      score_elf_allocate_dynamic_relocations (dynobj, hscore->possibly_dynamic_relocs);
2925
      if (hscore->readonly_reloc)
2926
        /* We tell the dynamic linker that there are relocations
2927
           against the text segment.  */
2928
        info->flags |= DF_TEXTREL;
2929
    }
2930
 
2931
  /* For a function, create a stub, if allowed.  */
2932
  if (!hscore->no_fn_stub && h->needs_plt)
2933
    {
2934
      if (!elf_hash_table (info)->dynamic_sections_created)
2935
        return TRUE;
2936
 
2937
      /* If this symbol is not defined in a regular file, then set
2938
         the symbol to the stub location.  This is required to make
2939
         function pointers compare as equal between the normal
2940
         executable and the shared library.  */
2941
      if (!h->def_regular)
2942
        {
2943
          /* We need .stub section.  */
2944
          s = bfd_get_section_by_name (dynobj, SCORE_ELF_STUB_SECTION_NAME);
2945
          BFD_ASSERT (s != NULL);
2946
 
2947
          h->root.u.def.section = s;
2948
          h->root.u.def.value = s->size;
2949
 
2950
          /* XXX Write this stub address somewhere.  */
2951
          h->plt.offset = s->size;
2952
 
2953
          /* Make room for this stub code.  */
2954
          s->size += SCORE_FUNCTION_STUB_SIZE;
2955
 
2956
          /* The last half word of the stub will be filled with the index
2957
             of this symbol in .dynsym section.  */
2958
          return TRUE;
2959
        }
2960
    }
2961
  else if ((h->type == STT_FUNC) && !h->needs_plt)
2962
    {
2963
      /* This will set the entry for this symbol in the GOT to 0, and
2964
         the dynamic linker will take care of this.  */
2965
      h->root.u.def.value = 0;
2966
      return TRUE;
2967
    }
2968
 
2969
  /* If this is a weak symbol, and there is a real definition, the
2970
     processor independent code will have arranged for us to see the
2971
     real definition first, and we can just use the same value.  */
2972
  if (h->u.weakdef != NULL)
2973
    {
2974
      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2975
                  || h->u.weakdef->root.type == bfd_link_hash_defweak);
2976
      h->root.u.def.section = h->u.weakdef->root.u.def.section;
2977
      h->root.u.def.value = h->u.weakdef->root.u.def.value;
2978
      return TRUE;
2979
    }
2980
 
2981
  /* This is a reference to a symbol defined by a dynamic object which
2982
     is not a function.  */
2983
  return TRUE;
2984
}
2985
 
2986
/* This function is called after all the input files have been read,
2987
   and the input sections have been assigned to output sections.  */
2988
 
2989
bfd_boolean
2990
s7_bfd_score_elf_always_size_sections (bfd *output_bfd,
2991
                                       struct bfd_link_info *info)
2992
{
2993
  bfd *dynobj;
2994
  asection *s;
2995
  struct score_got_info *g;
2996
  int i;
2997
  bfd_size_type loadable_size = 0;
2998
  bfd_size_type local_gotno;
2999
  bfd *sub;
3000
 
3001
  dynobj = elf_hash_table (info)->dynobj;
3002
  if (dynobj == NULL)
3003
    /* Relocatable links don't have it.  */
3004
    return TRUE;
3005
 
3006
  g = score_elf_got_info (dynobj, &s);
3007
  if (s == NULL)
3008
    return TRUE;
3009
 
3010
  /* Calculate the total loadable size of the output.  That will give us the
3011
     maximum number of GOT_PAGE entries required.  */
3012
  for (sub = info->input_bfds; sub; sub = sub->link_next)
3013
    {
3014
      asection *subsection;
3015
 
3016
      for (subsection = sub->sections;
3017
           subsection;
3018
           subsection = subsection->next)
3019
        {
3020
          if ((subsection->flags & SEC_ALLOC) == 0)
3021
            continue;
3022
          loadable_size += ((subsection->size + 0xf)
3023
                            &~ (bfd_size_type) 0xf);
3024
        }
3025
    }
3026
 
3027
  /* There has to be a global GOT entry for every symbol with
3028
     a dynamic symbol table index of DT_SCORE_GOTSYM or
3029
     higher.  Therefore, it make sense to put those symbols
3030
     that need GOT entries at the end of the symbol table.  We
3031
     do that here.  */
3032
  if (! score_elf_sort_hash_table (info, 1))
3033
    return FALSE;
3034
 
3035
  if (g->global_gotsym != NULL)
3036
    i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx;
3037
  else
3038
    /* If there are no global symbols, or none requiring
3039
       relocations, then GLOBAL_GOTSYM will be NULL.  */
3040
    i = 0;
3041
 
3042
  /* In the worst case, we'll get one stub per dynamic symbol.  */
3043
  loadable_size += SCORE_FUNCTION_STUB_SIZE * i;
3044
 
3045
  /* Assume there are two loadable segments consisting of
3046
     contiguous sections.  Is 5 enough?  */
3047
  local_gotno = (loadable_size >> 16) + 5;
3048
 
3049
  g->local_gotno += local_gotno;
3050
  s->size += g->local_gotno * SCORE_ELF_GOT_SIZE (output_bfd);
3051
 
3052
  g->global_gotno = i;
3053
  s->size += i * SCORE_ELF_GOT_SIZE (output_bfd);
3054
 
3055
  score_elf_resolve_final_got_entries (g);
3056
 
3057
  if (s->size > SCORE_ELF_GOT_MAX_SIZE (output_bfd))
3058
    {
3059
      /* Fixme. Error message or Warning message should be issued here.  */
3060
    }
3061
 
3062
  return TRUE;
3063
}
3064
 
3065
/* Set the sizes of the dynamic sections.  */
3066
 
3067
bfd_boolean
3068
s7_bfd_score_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
3069
{
3070
  bfd *dynobj;
3071
  asection *s;
3072
  bfd_boolean reltext;
3073
 
3074
  dynobj = elf_hash_table (info)->dynobj;
3075
  BFD_ASSERT (dynobj != NULL);
3076
 
3077
  if (elf_hash_table (info)->dynamic_sections_created)
3078
    {
3079
      /* Set the contents of the .interp section to the interpreter.  */
3080
      if (!info->shared)
3081
        {
3082
          s = bfd_get_section_by_name (dynobj, ".interp");
3083
          BFD_ASSERT (s != NULL);
3084
          s->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
3085
          s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
3086
        }
3087
    }
3088
 
3089
  /* The check_relocs and adjust_dynamic_symbol entry points have
3090
     determined the sizes of the various dynamic sections.  Allocate
3091
     memory for them.  */
3092
  reltext = FALSE;
3093
  for (s = dynobj->sections; s != NULL; s = s->next)
3094
    {
3095
      const char *name;
3096
 
3097
      if ((s->flags & SEC_LINKER_CREATED) == 0)
3098
        continue;
3099
 
3100
      /* It's OK to base decisions on the section name, because none
3101
         of the dynobj section names depend upon the input files.  */
3102
      name = bfd_get_section_name (dynobj, s);
3103
 
3104
      if (CONST_STRNEQ (name, ".rel"))
3105
        {
3106
          if (s->size == 0)
3107
            {
3108
              /* We only strip the section if the output section name
3109
                 has the same name.  Otherwise, there might be several
3110
                 input sections for this output section.  FIXME: This
3111
                 code is probably not needed these days anyhow, since
3112
                 the linker now does not create empty output sections.  */
3113
              if (s->output_section != NULL
3114
                  && strcmp (name,
3115
                             bfd_get_section_name (s->output_section->owner,
3116
                                                   s->output_section)) == 0)
3117
                s->flags |= SEC_EXCLUDE;
3118
            }
3119
          else
3120
            {
3121
              const char *outname;
3122
              asection *target;
3123
 
3124
              /* If this relocation section applies to a read only
3125
                 section, then we probably need a DT_TEXTREL entry.
3126
                 If the relocation section is .rel.dyn, we always
3127
                 assert a DT_TEXTREL entry rather than testing whether
3128
                 there exists a relocation to a read only section or
3129
                 not.  */
3130
              outname = bfd_get_section_name (output_bfd, s->output_section);
3131
              target = bfd_get_section_by_name (output_bfd, outname + 4);
3132
              if ((target != NULL
3133
                   && (target->flags & SEC_READONLY) != 0
3134
                   && (target->flags & SEC_ALLOC) != 0) || strcmp (outname, ".rel.dyn") == 0)
3135
                reltext = TRUE;
3136
 
3137
              /* We use the reloc_count field as a counter if we need
3138
                 to copy relocs into the output file.  */
3139
              if (strcmp (name, ".rel.dyn") != 0)
3140
                s->reloc_count = 0;
3141
            }
3142
        }
3143
      else if (CONST_STRNEQ (name, ".got"))
3144
        {
3145
          /* s7_bfd_score_elf_always_size_sections() has already done
3146
             most of the work, but some symbols may have been mapped
3147
             to versions that we must now resolve in the got_entries
3148
             hash tables.  */
3149
        }
3150
      else if (strcmp (name, SCORE_ELF_STUB_SECTION_NAME) == 0)
3151
        {
3152
          /* IRIX rld assumes that the function stub isn't at the end
3153
             of .text section. So put a dummy. XXX  */
3154
          s->size += SCORE_FUNCTION_STUB_SIZE;
3155
        }
3156
      else if (! CONST_STRNEQ (name, ".init"))
3157
        {
3158
          /* It's not one of our sections, so don't allocate space.  */
3159
          continue;
3160
        }
3161
 
3162
      /* Allocate memory for the section contents.  */
3163
      s->contents = bfd_zalloc (dynobj, s->size);
3164
      if (s->contents == NULL && s->size != 0)
3165
        {
3166
          bfd_set_error (bfd_error_no_memory);
3167
          return FALSE;
3168
        }
3169
    }
3170
 
3171
  if (elf_hash_table (info)->dynamic_sections_created)
3172
    {
3173
      /* Add some entries to the .dynamic section.  We fill in the
3174
         values later, in s7_bfd_score_elf_finish_dynamic_sections, but we
3175
         must add the entries now so that we get the correct size for
3176
         the .dynamic section.  The DT_DEBUG entry is filled in by the
3177
         dynamic linker and used by the debugger.  */
3178
 
3179
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0))
3180
        return FALSE;
3181
 
3182
      if (reltext)
3183
        info->flags |= DF_TEXTREL;
3184
 
3185
      if ((info->flags & DF_TEXTREL) != 0)
3186
        {
3187
          if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0))
3188
            return FALSE;
3189
        }
3190
 
3191
      if (! SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTGOT, 0))
3192
        return FALSE;
3193
 
3194
      if (score_elf_rel_dyn_section (dynobj, FALSE))
3195
        {
3196
          if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_REL, 0))
3197
            return FALSE;
3198
 
3199
          if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELSZ, 0))
3200
            return FALSE;
3201
 
3202
          if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELENT, 0))
3203
            return FALSE;
3204
        }
3205
 
3206
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_BASE_ADDRESS, 0))
3207
        return FALSE;
3208
 
3209
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_LOCAL_GOTNO, 0))
3210
        return FALSE;
3211
 
3212
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_SYMTABNO, 0))
3213
        return FALSE;
3214
 
3215
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_UNREFEXTNO, 0))
3216
        return FALSE;
3217
 
3218
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_GOTSYM, 0))
3219
        return FALSE;
3220
 
3221
      if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_HIPAGENO, 0))
3222
        return FALSE;
3223
    }
3224
 
3225
  return TRUE;
3226
}
3227
 
3228
bfd_boolean
3229
s7_bfd_score_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
3230
{
3231
  struct elf_link_hash_entry *h;
3232
  struct bfd_link_hash_entry *bh;
3233
  flagword flags;
3234
  asection *s;
3235
 
3236
  flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
3237
           | SEC_LINKER_CREATED | SEC_READONLY);
3238
 
3239
  /* ABI requests the .dynamic section to be read only.  */
3240
  s = bfd_get_section_by_name (abfd, ".dynamic");
3241
  if (s != NULL)
3242
    {
3243
      if (!bfd_set_section_flags (abfd, s, flags))
3244
        return FALSE;
3245
    }
3246
 
3247
  /* We need to create .got section.  */
3248
  if (!score_elf_create_got_section (abfd, info, FALSE))
3249
    return FALSE;
3250
 
3251
  if (!score_elf_rel_dyn_section (elf_hash_table (info)->dynobj, TRUE))
3252
    return FALSE;
3253
 
3254
  /* Create .stub section.  */
3255
  if (bfd_get_section_by_name (abfd, SCORE_ELF_STUB_SECTION_NAME) == NULL)
3256
    {
3257
      s = bfd_make_section_with_flags (abfd, SCORE_ELF_STUB_SECTION_NAME,
3258
                                       flags | SEC_CODE);
3259
      if (s == NULL
3260
          || !bfd_set_section_alignment (abfd, s, 2))
3261
 
3262
        return FALSE;
3263
    }
3264
 
3265
  if (!info->shared)
3266
    {
3267
      const char *name;
3268
 
3269
      name = "_DYNAMIC_LINK";
3270
      bh = NULL;
3271
      if (!(_bfd_generic_link_add_one_symbol
3272
            (info, abfd, name, BSF_GLOBAL, bfd_abs_section_ptr,
3273
             (bfd_vma) 0, NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
3274
        return FALSE;
3275
 
3276
      h = (struct elf_link_hash_entry *) bh;
3277
      h->non_elf = 0;
3278
      h->def_regular = 1;
3279
      h->type = STT_SECTION;
3280
 
3281
      if (!bfd_elf_link_record_dynamic_symbol (info, h))
3282
        return FALSE;
3283
    }
3284
 
3285
  return TRUE;
3286
}
3287
 
3288
 
3289
/* Finish up dynamic symbol handling.  We set the contents of various
3290
   dynamic sections here.  */
3291
 
3292
bfd_boolean
3293
s7_bfd_score_elf_finish_dynamic_symbol (bfd *output_bfd,
3294
                                        struct bfd_link_info *info,
3295
                                        struct elf_link_hash_entry *h,
3296
                                        Elf_Internal_Sym *sym)
3297
{
3298
  bfd *dynobj;
3299
  asection *sgot;
3300
  struct score_got_info *g;
3301
  const char *name;
3302
 
3303
  dynobj = elf_hash_table (info)->dynobj;
3304
 
3305
  if (h->plt.offset != MINUS_ONE)
3306
    {
3307
      asection *s;
3308
      bfd_byte stub[SCORE_FUNCTION_STUB_SIZE];
3309
 
3310
      /* This symbol has a stub.  Set it up.  */
3311
      BFD_ASSERT (h->dynindx != -1);
3312
 
3313
      s = bfd_get_section_by_name (dynobj, SCORE_ELF_STUB_SECTION_NAME);
3314
      BFD_ASSERT (s != NULL);
3315
 
3316
      /* FIXME: Can h->dynindex be more than 64K?  */
3317
      if (h->dynindx & 0xffff0000)
3318
        return FALSE;
3319
 
3320
      /* Fill the stub.  */
3321
      bfd_put_32 (output_bfd, STUB_LW, stub);
3322
      bfd_put_32 (output_bfd, STUB_MOVE, stub + 4);
3323
      bfd_put_32 (output_bfd, STUB_LI16 | (h->dynindx << 1), stub + 8);
3324
      bfd_put_32 (output_bfd, STUB_BRL, stub + 12);
3325
 
3326
      BFD_ASSERT (h->plt.offset <= s->size);
3327
      memcpy (s->contents + h->plt.offset, stub, SCORE_FUNCTION_STUB_SIZE);
3328
 
3329
      /* Mark the symbol as undefined.  plt.offset != -1 occurs
3330
         only for the referenced symbol.  */
3331
      sym->st_shndx = SHN_UNDEF;
3332
 
3333
      /* The run-time linker uses the st_value field of the symbol
3334
          to reset the global offset table entry for this external
3335
          to its stub address when unlinking a shared object.  */
3336
      sym->st_value = (s->output_section->vma + s->output_offset + h->plt.offset);
3337
    }
3338
 
3339
  BFD_ASSERT (h->dynindx != -1 || h->forced_local);
3340
 
3341
  sgot = score_elf_got_section (dynobj, FALSE);
3342
  BFD_ASSERT (sgot != NULL);
3343
  BFD_ASSERT (score_elf_section_data (sgot) != NULL);
3344
  g = score_elf_section_data (sgot)->u.got_info;
3345
  BFD_ASSERT (g != NULL);
3346
 
3347
  /* Run through the global symbol table, creating GOT entries for all
3348
     the symbols that need them.  */
3349
  if (g->global_gotsym != NULL && h->dynindx >= g->global_gotsym->dynindx)
3350
    {
3351
      bfd_vma offset;
3352
      bfd_vma value;
3353
 
3354
      value = sym->st_value;
3355
      offset = score_elf_global_got_index (dynobj, h);
3356
      bfd_put_32 (output_bfd, value, sgot->contents + offset);
3357
    }
3358
 
3359
  /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
3360
  name = h->root.root.string;
3361
  if (strcmp (name, "_DYNAMIC") == 0 || strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
3362
    sym->st_shndx = SHN_ABS;
3363
  else if (strcmp (name, "_DYNAMIC_LINK") == 0)
3364
    {
3365
      sym->st_shndx = SHN_ABS;
3366
      sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
3367
      sym->st_value = 1;
3368
    }
3369
  else if (strcmp (name, GP_DISP_LABEL) == 0)
3370
    {
3371
      sym->st_shndx = SHN_ABS;
3372
      sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
3373
      sym->st_value = elf_gp (output_bfd);
3374
    }
3375
 
3376
  return TRUE;
3377
}
3378
 
3379
/* Finish up the dynamic sections.  */
3380
 
3381
bfd_boolean
3382
s7_bfd_score_elf_finish_dynamic_sections (bfd *output_bfd,
3383
                                          struct bfd_link_info *info)
3384
{
3385
  bfd *dynobj;
3386
  asection *sdyn;
3387
  asection *sgot;
3388
  asection *s;
3389
  struct score_got_info *g;
3390
 
3391
  dynobj = elf_hash_table (info)->dynobj;
3392
 
3393
  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
3394
 
3395
  sgot = score_elf_got_section (dynobj, FALSE);
3396
  if (sgot == NULL)
3397
    g = NULL;
3398
  else
3399
    {
3400
      BFD_ASSERT (score_elf_section_data (sgot) != NULL);
3401
      g = score_elf_section_data (sgot)->u.got_info;
3402
      BFD_ASSERT (g != NULL);
3403
    }
3404
 
3405
  if (elf_hash_table (info)->dynamic_sections_created)
3406
    {
3407
      bfd_byte *b;
3408
 
3409
      BFD_ASSERT (sdyn != NULL);
3410
      BFD_ASSERT (g != NULL);
3411
 
3412
      for (b = sdyn->contents;
3413
           b < sdyn->contents + sdyn->size;
3414
           b += SCORE_ELF_DYN_SIZE (dynobj))
3415
        {
3416
          Elf_Internal_Dyn dyn;
3417
          const char *name;
3418
          size_t elemsize;
3419
          bfd_boolean swap_out_p;
3420
 
3421
          /* Read in the current dynamic entry.  */
3422
          (*get_elf_backend_data (dynobj)->s->swap_dyn_in) (dynobj, b, &dyn);
3423
 
3424
          /* Assume that we're going to modify it and write it out.  */
3425
          swap_out_p = TRUE;
3426
 
3427
          switch (dyn.d_tag)
3428
            {
3429
            case DT_RELENT:
3430
              s = score_elf_rel_dyn_section (dynobj, FALSE);
3431
              BFD_ASSERT (s != NULL);
3432
              dyn.d_un.d_val = SCORE_ELF_REL_SIZE (dynobj);
3433
              break;
3434
 
3435
            case DT_STRSZ:
3436
              /* Rewrite DT_STRSZ.  */
3437
              dyn.d_un.d_val = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
3438
                    break;
3439
 
3440
            case DT_PLTGOT:
3441
              name = ".got";
3442
              s = bfd_get_section_by_name (output_bfd, name);
3443
              BFD_ASSERT (s != NULL);
3444
              dyn.d_un.d_ptr = s->vma;
3445
              break;
3446
 
3447
            case DT_SCORE_BASE_ADDRESS:
3448
              s = output_bfd->sections;
3449
              BFD_ASSERT (s != NULL);
3450
              dyn.d_un.d_ptr = s->vma & ~(bfd_vma) 0xffff;
3451
              break;
3452
 
3453
            case DT_SCORE_LOCAL_GOTNO:
3454
              dyn.d_un.d_val = g->local_gotno;
3455
              break;
3456
 
3457
            case DT_SCORE_UNREFEXTNO:
3458
              /* The index into the dynamic symbol table which is the
3459
                 entry of the first external symbol that is not
3460
                 referenced within the same object.  */
3461
              dyn.d_un.d_val = bfd_count_sections (output_bfd) + 1;
3462
              break;
3463
 
3464
            case DT_SCORE_GOTSYM:
3465
              if (g->global_gotsym)
3466
                {
3467
                  dyn.d_un.d_val = g->global_gotsym->dynindx;
3468
                  break;
3469
                }
3470
              /* In case if we don't have global got symbols we default
3471
                  to setting DT_SCORE_GOTSYM to the same value as
3472
                  DT_SCORE_SYMTABNO, so we just fall through.  */
3473
 
3474
            case DT_SCORE_SYMTABNO:
3475
              name = ".dynsym";
3476
              elemsize = SCORE_ELF_SYM_SIZE (output_bfd);
3477
              s = bfd_get_section_by_name (output_bfd, name);
3478
              BFD_ASSERT (s != NULL);
3479
 
3480
              dyn.d_un.d_val = s->size / elemsize;
3481
              break;
3482
 
3483
            case DT_SCORE_HIPAGENO:
3484
              dyn.d_un.d_val = g->local_gotno - SCORE_RESERVED_GOTNO;
3485
              break;
3486
 
3487
            default:
3488
              swap_out_p = FALSE;
3489
              break;
3490
            }
3491
 
3492
          if (swap_out_p)
3493
            (*get_elf_backend_data (dynobj)->s->swap_dyn_out) (dynobj, &dyn, b);
3494
        }
3495
    }
3496
 
3497
  /* The first entry of the global offset table will be filled at
3498
     runtime. The second entry will be used by some runtime loaders.
3499
     This isn't the case of IRIX rld.  */
3500
  if (sgot != NULL && sgot->size > 0)
3501
    {
3502
      bfd_put_32 (output_bfd, 0, sgot->contents);
3503
      bfd_put_32 (output_bfd, 0x80000000, sgot->contents + SCORE_ELF_GOT_SIZE (output_bfd));
3504
    }
3505
 
3506
  if (sgot != NULL)
3507
    elf_section_data (sgot->output_section)->this_hdr.sh_entsize
3508
      = SCORE_ELF_GOT_SIZE (output_bfd);
3509
 
3510
 
3511
  /* We need to sort the entries of the dynamic relocation section.  */
3512
  s = score_elf_rel_dyn_section (dynobj, FALSE);
3513
 
3514
  if (s != NULL && s->size > (bfd_vma)2 * SCORE_ELF_REL_SIZE (output_bfd))
3515
    {
3516
      reldyn_sorting_bfd = output_bfd;
3517
      qsort ((Elf32_External_Rel *) s->contents + 1, s->reloc_count - 1,
3518
             sizeof (Elf32_External_Rel), score_elf_sort_dynamic_relocs);
3519
    }
3520
 
3521
  return TRUE;
3522
}
3523
 
3524
/* This function set up the ELF section header for a BFD section in preparation for writing
3525
   it out.  This is where the flags and type fields are set for unusual sections.  */
3526
 
3527
bfd_boolean
3528
s7_bfd_score_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
3529
                                Elf_Internal_Shdr *hdr,
3530
                                asection *sec)
3531
{
3532
  const char *name;
3533
 
3534
  name = bfd_get_section_name (abfd, sec);
3535
 
3536
  if (strcmp (name, ".got") == 0
3537
      || strcmp (name, ".srdata") == 0
3538
      || strcmp (name, ".sdata") == 0
3539
      || strcmp (name, ".sbss") == 0)
3540
    hdr->sh_flags |= SHF_SCORE_GPREL;
3541
 
3542
  return TRUE;
3543
}
3544
 
3545
/* This function do additional processing on the ELF section header before writing
3546
   it out.  This is used to set the flags and type fields for some sections.  */
3547
 
3548
/* assign_file_positions_except_relocs() check section flag and if it is allocatable,
3549
   warning message will be issued.  backend_fake_section is called before
3550
   assign_file_positions_except_relocs(); backend_section_processing after it.  so, we
3551
   modify section flag there, but not backend_fake_section.  */
3552
 
3553
bfd_boolean
3554
s7_bfd_score_elf_section_processing (bfd *abfd ATTRIBUTE_UNUSED, Elf_Internal_Shdr *hdr)
3555
{
3556
  if (hdr->bfd_section != NULL)
3557
    {
3558
      const char *name = bfd_get_section_name (abfd, hdr->bfd_section);
3559
 
3560
      if (strcmp (name, ".sdata") == 0)
3561
        {
3562
          hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
3563
          hdr->sh_type = SHT_PROGBITS;
3564
        }
3565
      else if (strcmp (name, ".sbss") == 0)
3566
        {
3567
          hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
3568
          hdr->sh_type = SHT_NOBITS;
3569
        }
3570
      else if (strcmp (name, ".srdata") == 0)
3571
        {
3572
          hdr->sh_flags |= SHF_ALLOC | SHF_SCORE_GPREL;
3573
          hdr->sh_type = SHT_PROGBITS;
3574
        }
3575
    }
3576
 
3577
  return TRUE;
3578
}
3579
 
3580
bfd_boolean
3581
s7_bfd_score_elf_write_section (bfd *output_bfd, asection *sec, bfd_byte *contents)
3582
{
3583
  bfd_byte *to, *from, *end;
3584
  int i;
3585
 
3586
  if (strcmp (sec->name, ".pdr") != 0)
3587
    return FALSE;
3588
 
3589
  if (score_elf_section_data (sec)->u.tdata == NULL)
3590
    return FALSE;
3591
 
3592
  to = contents;
3593
  end = contents + sec->size;
3594
  for (from = contents, i = 0; from < end; from += PDR_SIZE, i++)
3595
    {
3596
      if ((score_elf_section_data (sec)->u.tdata)[i] == 1)
3597
        continue;
3598
 
3599
      if (to != from)
3600
        memcpy (to, from, PDR_SIZE);
3601
 
3602
      to += PDR_SIZE;
3603
    }
3604
  bfd_set_section_contents (output_bfd, sec->output_section, contents,
3605
                            (file_ptr) sec->output_offset, sec->size);
3606
 
3607
  return TRUE;
3608
}
3609
 
3610
/* Copy data from a SCORE ELF indirect symbol to its direct symbol, hiding the old
3611
   indirect symbol.  Process additional relocation information.  */
3612
 
3613
void
3614
s7_bfd_score_elf_copy_indirect_symbol (struct bfd_link_info *info,
3615
                                       struct elf_link_hash_entry *dir,
3616
                                       struct elf_link_hash_entry *ind)
3617
{
3618
  struct score_elf_link_hash_entry *dirscore, *indscore;
3619
 
3620
  _bfd_elf_link_hash_copy_indirect (info, dir, ind);
3621
 
3622
  if (ind->root.type != bfd_link_hash_indirect)
3623
    return;
3624
 
3625
  dirscore = (struct score_elf_link_hash_entry *) dir;
3626
  indscore = (struct score_elf_link_hash_entry *) ind;
3627
  dirscore->possibly_dynamic_relocs += indscore->possibly_dynamic_relocs;
3628
 
3629
  if (indscore->readonly_reloc)
3630
    dirscore->readonly_reloc = TRUE;
3631
 
3632
  if (indscore->no_fn_stub)
3633
    dirscore->no_fn_stub = TRUE;
3634
}
3635
 
3636
/* Remove information about discarded functions from other sections which mention them.  */
3637
 
3638
bfd_boolean
3639
s7_bfd_score_elf_discard_info (bfd *abfd,
3640
                               struct elf_reloc_cookie *cookie,
3641
                               struct bfd_link_info *info)
3642
{
3643
  asection *o;
3644
  bfd_boolean ret = FALSE;
3645
  unsigned char *tdata;
3646
  size_t i, skip;
3647
 
3648
  o = bfd_get_section_by_name (abfd, ".pdr");
3649
  if ((!o) || (o->size == 0) || (o->size % PDR_SIZE != 0)
3650
      || (o->output_section != NULL && bfd_is_abs_section (o->output_section)))
3651
    return FALSE;
3652
 
3653
  tdata = bfd_zmalloc (o->size / PDR_SIZE);
3654
  if (!tdata)
3655
    return FALSE;
3656
 
3657
  cookie->rels = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, info->keep_memory);
3658
  if (!cookie->rels)
3659
    {
3660
      free (tdata);
3661
      return FALSE;
3662
    }
3663
 
3664
  cookie->rel = cookie->rels;
3665
  cookie->relend = cookie->rels + o->reloc_count;
3666
 
3667
  for (i = 0, skip = 0; i < o->size; i++)
3668
    {
3669
      if (bfd_elf_reloc_symbol_deleted_p (i * PDR_SIZE, cookie))
3670
        {
3671
          tdata[i] = 1;
3672
          skip++;
3673
        }
3674
    }
3675
 
3676
  if (skip != 0)
3677
    {
3678
      score_elf_section_data (o)->u.tdata = tdata;
3679
      o->size -= skip * PDR_SIZE;
3680
      ret = TRUE;
3681
    }
3682
  else
3683
    free (tdata);
3684
 
3685
  if (!info->keep_memory)
3686
    free (cookie->rels);
3687
 
3688
  return ret;
3689
}
3690
 
3691
/* Signal that discard_info() has removed the discarded relocations for this section.  */
3692
 
3693
bfd_boolean
3694
s7_bfd_score_elf_ignore_discarded_relocs (asection *sec)
3695
{
3696
  if (strcmp (sec->name, ".pdr") == 0)
3697
    return TRUE;
3698
  return FALSE;
3699
}
3700
 
3701
/* Return the section that should be marked against GC for a given
3702
   relocation.  */
3703
 
3704
asection *
3705
s7_bfd_score_elf_gc_mark_hook (asection *sec,
3706
                               struct bfd_link_info *info,
3707
                               Elf_Internal_Rela *rel,
3708
                               struct elf_link_hash_entry *h,
3709
                               Elf_Internal_Sym *sym)
3710
{
3711
  if (h != NULL)
3712
    switch (ELF32_R_TYPE (rel->r_info))
3713
      {
3714
      case R_SCORE_GNU_VTINHERIT:
3715
      case R_SCORE_GNU_VTENTRY:
3716
        return NULL;
3717
      }
3718
 
3719
  return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
3720
}
3721
 
3722
/* Support for core dump NOTE sections.  */
3723
 
3724
bfd_boolean
3725
s7_bfd_score_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
3726
{
3727
  int offset;
3728
  unsigned int raw_size;
3729
 
3730
  switch (note->descsz)
3731
    {
3732
    default:
3733
      return FALSE;
3734
    case 272:                  /* Linux/Score elf_prstatus */
3735
 
3736
      /* pr_cursig */
3737
      elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
3738
 
3739
      /* pr_pid */
3740
      elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
3741
 
3742
      /* pr_reg */
3743
      offset = 72;
3744
 
3745
      /* sizeof(elf_gregset_t) */
3746
      raw_size = 196;
3747
 
3748
      break;
3749
    }
3750
 
3751
  /* Make a ".reg/999" section.  */
3752
  return _bfd_elfcore_make_pseudosection (abfd, ".reg", raw_size, note->descpos + offset);
3753
}
3754
 
3755
bfd_boolean
3756
s7_bfd_score_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
3757
{
3758
  switch (note->descsz)
3759
    {
3760
    default:
3761
      return FALSE;
3762
 
3763
    case 128:                  /* Linux/Score elf_prpsinfo.  */
3764
      /* pr_fname */
3765
      elf_tdata (abfd)->core_program = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
3766
 
3767
      /* pr_psargs */
3768
      elf_tdata (abfd)->core_command = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
3769
      break;
3770
    }
3771
 
3772
  /* Note that for some reason, a spurious space is tacked
3773
     onto the end of the args in some (at least one anyway)
3774
     implementations, so strip it off if it exists.  */
3775
 
3776
  {
3777
    char *command = elf_tdata (abfd)->core_command;
3778
    int n = strlen (command);
3779
 
3780
    if (0 < n && command[n - 1] == ' ')
3781
      command[n - 1] = '\0';
3782
  }
3783
 
3784
  return TRUE;
3785
}
3786
 
3787
 
3788
/* Score BFD functions.  */
3789
 
3790
reloc_howto_type *
3791
s7_elf32_score_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
3792
{
3793
  unsigned int i;
3794
 
3795
  for (i = 0; i < ARRAY_SIZE (elf32_score_reloc_map); i++)
3796
    if (elf32_score_reloc_map[i].bfd_reloc_val == code)
3797
      return &elf32_score_howto_table[elf32_score_reloc_map[i].elf_reloc_val];
3798
 
3799
  return NULL;
3800
}
3801
 
3802
bfd_boolean
3803
s7_elf32_score_print_private_bfd_data (bfd *abfd, void * ptr)
3804
{
3805
  FILE *file = (FILE *) ptr;
3806
 
3807
  BFD_ASSERT (abfd != NULL && ptr != NULL);
3808
 
3809
  /* Print normal ELF private data.  */
3810
  _bfd_elf_print_private_bfd_data (abfd, ptr);
3811
 
3812
  /* xgettext:c-format */
3813
  fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
3814
  if (elf_elfheader (abfd)->e_flags & EF_SCORE_PIC)
3815
    {
3816
      fprintf (file, _(" [pic]"));
3817
    }
3818
  if (elf_elfheader (abfd)->e_flags & EF_SCORE_FIXDEP)
3819
    {
3820
      fprintf (file, _(" [fix dep]"));
3821
    }
3822
  fputc ('\n', file);
3823
 
3824
  return TRUE;
3825
}
3826
 
3827
bfd_boolean
3828
s7_elf32_score_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
3829
{
3830
  flagword in_flags;
3831
  flagword out_flags;
3832
 
3833
  if (!_bfd_generic_verify_endian_match (ibfd, obfd))
3834
    return FALSE;
3835
 
3836
  in_flags  = elf_elfheader (ibfd)->e_flags;
3837
  out_flags = elf_elfheader (obfd)->e_flags;
3838
 
3839
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
3840
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
3841
    return TRUE;
3842
 
3843
  in_flags = elf_elfheader (ibfd)->e_flags;
3844
  out_flags = elf_elfheader (obfd)->e_flags;
3845
 
3846
  if (! elf_flags_init (obfd))
3847
    {
3848
      elf_flags_init (obfd) = TRUE;
3849
      elf_elfheader (obfd)->e_flags = in_flags;
3850
 
3851
      if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
3852
          && bfd_get_arch_info (obfd)->the_default)
3853
        {
3854
          return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd));
3855
        }
3856
 
3857
      return TRUE;
3858
    }
3859
 
3860
  if (((in_flags & EF_SCORE_PIC) != 0) != ((out_flags & EF_SCORE_PIC) != 0))
3861
    {
3862
      (*_bfd_error_handler) (_("%B: warning: linking PIC files with non-PIC files"), ibfd);
3863
    }
3864
 
3865
  /* Maybe dependency fix compatibility should be checked here.  */
3866
  return TRUE;
3867
}
3868
 
3869
bfd_boolean
3870
s7_elf32_score_new_section_hook (bfd *abfd, asection *sec)
3871
{
3872
  struct _score_elf_section_data *sdata;
3873
  bfd_size_type amt = sizeof (*sdata);
3874
 
3875
  sdata = bfd_zalloc (abfd, amt);
3876
  if (sdata == NULL)
3877
    return FALSE;
3878
  sec->used_by_bfd = sdata;
3879
 
3880
  return _bfd_elf_new_section_hook (abfd, sec);
3881
}
3882
 
3883
#define elf_backend_omit_section_dynsym \
3884
  ((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.