~ubuntu-branches/ubuntu/utopic/binutils-arm64-cross/utopic

« back to all changes in this revision

Viewing changes to binutils-2.23.52.20130611/bfd/elf32-score7.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-06-20 17:38:09 UTC
  • Revision ID: package-import@ubuntu.com-20130620173809-app8lzgvymy5fg6c
Tags: 0.7
Build-depend on binutils-source (>= 2.23.52.20130620-1~).

Show diffs side-by-side

added added

removed removed

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