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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [bfd/] [elf32-score.c] - Blame information for rev 834

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

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

powered by: WebSVN 2.1.0

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