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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [bfd/] [elf64-sparc.c] - Blame information for rev 280

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

Line No. Rev Author Line
1 227 jeremybenn
/* SPARC-specific support for 64-bit ELF
2
   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3
   2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
4
 
5
   This file is part of BFD, the Binary File Descriptor library.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20
   MA 02110-1301, USA.  */
21
 
22
#include "sysdep.h"
23
#include "bfd.h"
24
#include "libbfd.h"
25
#include "elf-bfd.h"
26
#include "elf/sparc.h"
27
#include "opcode/sparc.h"
28
#include "elfxx-sparc.h"
29
 
30
/* In case we're on a 32-bit machine, construct a 64-bit "-1" value.  */
31
#define MINUS_ONE (~ (bfd_vma) 0)
32
 
33
/* Due to the way how we handle R_SPARC_OLO10, each entry in a SHT_RELA
34
   section can represent up to two relocs, we must tell the user to allocate
35
   more space.  */
36
 
37
static long
38
elf64_sparc_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
39
{
40
  return (sec->reloc_count * 2 + 1) * sizeof (arelent *);
41
}
42
 
43
static long
44
elf64_sparc_get_dynamic_reloc_upper_bound (bfd *abfd)
45
{
46
  return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 2;
47
}
48
 
49
/* Read  relocations for ASECT from REL_HDR.  There are RELOC_COUNT of
50
   them.  We cannot use generic elf routines for this,  because R_SPARC_OLO10
51
   has secondary addend in ELF64_R_TYPE_DATA.  We handle it as two relocations
52
   for the same location,  R_SPARC_LO10 and R_SPARC_13.  */
53
 
54
static bfd_boolean
55
elf64_sparc_slurp_one_reloc_table (bfd *abfd, asection *asect,
56
                                   Elf_Internal_Shdr *rel_hdr,
57
                                   asymbol **symbols, bfd_boolean dynamic)
58
{
59
  PTR allocated = NULL;
60
  bfd_byte *native_relocs;
61
  arelent *relent;
62
  unsigned int i;
63
  int entsize;
64
  bfd_size_type count;
65
  arelent *relents;
66
 
67
  allocated = (PTR) bfd_malloc (rel_hdr->sh_size);
68
  if (allocated == NULL)
69
    goto error_return;
70
 
71
  if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
72
      || bfd_bread (allocated, rel_hdr->sh_size, abfd) != rel_hdr->sh_size)
73
    goto error_return;
74
 
75
  native_relocs = (bfd_byte *) allocated;
76
 
77
  relents = asect->relocation + canon_reloc_count (asect);
78
 
79
  entsize = rel_hdr->sh_entsize;
80
  BFD_ASSERT (entsize == sizeof (Elf64_External_Rela));
81
 
82
  count = rel_hdr->sh_size / entsize;
83
 
84
  for (i = 0, relent = relents; i < count;
85
       i++, relent++, native_relocs += entsize)
86
    {
87
      Elf_Internal_Rela rela;
88
      unsigned int r_type;
89
 
90
      bfd_elf64_swap_reloca_in (abfd, native_relocs, &rela);
91
 
92
      /* The address of an ELF reloc is section relative for an object
93
         file, and absolute for an executable file or shared library.
94
         The address of a normal BFD reloc is always section relative,
95
         and the address of a dynamic reloc is absolute..  */
96
      if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
97
        relent->address = rela.r_offset;
98
      else
99
        relent->address = rela.r_offset - asect->vma;
100
 
101
      if (ELF64_R_SYM (rela.r_info) == 0)
102
        relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
103
      else
104
        {
105
          asymbol **ps, *s;
106
 
107
          ps = symbols + ELF64_R_SYM (rela.r_info) - 1;
108
          s = *ps;
109
 
110
          /* Canonicalize ELF section symbols.  FIXME: Why?  */
111
          if ((s->flags & BSF_SECTION_SYM) == 0)
112
            relent->sym_ptr_ptr = ps;
113
          else
114
            relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
115
        }
116
 
117
      relent->addend = rela.r_addend;
118
 
119
      r_type = ELF64_R_TYPE_ID (rela.r_info);
120
      if (r_type == R_SPARC_OLO10)
121
        {
122
          relent->howto = _bfd_sparc_elf_info_to_howto_ptr (R_SPARC_LO10);
123
          relent[1].address = relent->address;
124
          relent++;
125
          relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
126
          relent->addend = ELF64_R_TYPE_DATA (rela.r_info);
127
          relent->howto = _bfd_sparc_elf_info_to_howto_ptr (R_SPARC_13);
128
        }
129
      else
130
        relent->howto = _bfd_sparc_elf_info_to_howto_ptr (r_type);
131
    }
132
 
133
  canon_reloc_count (asect) += relent - relents;
134
 
135
  if (allocated != NULL)
136
    free (allocated);
137
 
138
  return TRUE;
139
 
140
 error_return:
141
  if (allocated != NULL)
142
    free (allocated);
143
  return FALSE;
144
}
145
 
146
/* Read in and swap the external relocs.  */
147
 
148
static bfd_boolean
149
elf64_sparc_slurp_reloc_table (bfd *abfd, asection *asect,
150
                               asymbol **symbols, bfd_boolean dynamic)
151
{
152
  struct bfd_elf_section_data * const d = elf_section_data (asect);
153
  Elf_Internal_Shdr *rel_hdr;
154
  Elf_Internal_Shdr *rel_hdr2;
155
  bfd_size_type amt;
156
 
157
  if (asect->relocation != NULL)
158
    return TRUE;
159
 
160
  if (! dynamic)
161
    {
162
      if ((asect->flags & SEC_RELOC) == 0
163
          || asect->reloc_count == 0)
164
        return TRUE;
165
 
166
      rel_hdr = &d->rel_hdr;
167
      rel_hdr2 = d->rel_hdr2;
168
 
169
      BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
170
                  || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
171
    }
172
  else
173
    {
174
      /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
175
         case because relocations against this section may use the
176
         dynamic symbol table, and in that case bfd_section_from_shdr
177
         in elf.c does not update the RELOC_COUNT.  */
178
      if (asect->size == 0)
179
        return TRUE;
180
 
181
      rel_hdr = &d->this_hdr;
182
      asect->reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
183
      rel_hdr2 = NULL;
184
    }
185
 
186
  amt = asect->reloc_count;
187
  amt *= 2 * sizeof (arelent);
188
  asect->relocation = (arelent *) bfd_alloc (abfd, amt);
189
  if (asect->relocation == NULL)
190
    return FALSE;
191
 
192
  /* The elf64_sparc_slurp_one_reloc_table routine increments
193
     canon_reloc_count.  */
194
  canon_reloc_count (asect) = 0;
195
 
196
  if (!elf64_sparc_slurp_one_reloc_table (abfd, asect, rel_hdr, symbols,
197
                                          dynamic))
198
    return FALSE;
199
 
200
  if (rel_hdr2
201
      && !elf64_sparc_slurp_one_reloc_table (abfd, asect, rel_hdr2, symbols,
202
                                             dynamic))
203
    return FALSE;
204
 
205
  return TRUE;
206
}
207
 
208
/* Canonicalize the relocs.  */
209
 
210
static long
211
elf64_sparc_canonicalize_reloc (bfd *abfd, sec_ptr section,
212
                                arelent **relptr, asymbol **symbols)
213
{
214
  arelent *tblptr;
215
  unsigned int i;
216
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
217
 
218
  if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
219
    return -1;
220
 
221
  tblptr = section->relocation;
222
  for (i = 0; i < canon_reloc_count (section); i++)
223
    *relptr++ = tblptr++;
224
 
225
  *relptr = NULL;
226
 
227
  return canon_reloc_count (section);
228
}
229
 
230
 
231
/* Canonicalize the dynamic relocation entries.  Note that we return
232
   the dynamic relocations as a single block, although they are
233
   actually associated with particular sections; the interface, which
234
   was designed for SunOS style shared libraries, expects that there
235
   is only one set of dynamic relocs.  Any section that was actually
236
   installed in the BFD, and has type SHT_REL or SHT_RELA, and uses
237
   the dynamic symbol table, is considered to be a dynamic reloc
238
   section.  */
239
 
240
static long
241
elf64_sparc_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage,
242
                                        asymbol **syms)
243
{
244
  asection *s;
245
  long ret;
246
 
247
  if (elf_dynsymtab (abfd) == 0)
248
    {
249
      bfd_set_error (bfd_error_invalid_operation);
250
      return -1;
251
    }
252
 
253
  ret = 0;
254
  for (s = abfd->sections; s != NULL; s = s->next)
255
    {
256
      if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
257
          && (elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
258
        {
259
          arelent *p;
260
          long count, i;
261
 
262
          if (! elf64_sparc_slurp_reloc_table (abfd, s, syms, TRUE))
263
            return -1;
264
          count = canon_reloc_count (s);
265
          p = s->relocation;
266
          for (i = 0; i < count; i++)
267
            *storage++ = p++;
268
          ret += count;
269
        }
270
    }
271
 
272
  *storage = NULL;
273
 
274
  return ret;
275
}
276
 
277
/* Write out the relocs.  */
278
 
279
static void
280
elf64_sparc_write_relocs (bfd *abfd, asection *sec, PTR data)
281
{
282
  bfd_boolean *failedp = (bfd_boolean *) data;
283
  Elf_Internal_Shdr *rela_hdr;
284
  bfd_vma addr_offset;
285
  Elf64_External_Rela *outbound_relocas, *src_rela;
286
  unsigned int idx, count;
287
  asymbol *last_sym = 0;
288
  int last_sym_idx = 0;
289
 
290
  /* If we have already failed, don't do anything.  */
291
  if (*failedp)
292
    return;
293
 
294
  if ((sec->flags & SEC_RELOC) == 0)
295
    return;
296
 
297
  /* The linker backend writes the relocs out itself, and sets the
298
     reloc_count field to zero to inhibit writing them here.  Also,
299
     sometimes the SEC_RELOC flag gets set even when there aren't any
300
     relocs.  */
301
  if (sec->reloc_count == 0)
302
    return;
303
 
304
  /* We can combine two relocs that refer to the same address
305
     into R_SPARC_OLO10 if first one is R_SPARC_LO10 and the
306
     latter is R_SPARC_13 with no associated symbol.  */
307
  count = 0;
308
  for (idx = 0; idx < sec->reloc_count; idx++)
309
    {
310
      bfd_vma addr;
311
 
312
      ++count;
313
 
314
      addr = sec->orelocation[idx]->address;
315
      if (sec->orelocation[idx]->howto->type == R_SPARC_LO10
316
          && idx < sec->reloc_count - 1)
317
        {
318
          arelent *r = sec->orelocation[idx + 1];
319
 
320
          if (r->howto->type == R_SPARC_13
321
              && r->address == addr
322
              && bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
323
              && (*r->sym_ptr_ptr)->value == 0)
324
            ++idx;
325
        }
326
    }
327
 
328
  rela_hdr = &elf_section_data (sec)->rel_hdr;
329
 
330
  rela_hdr->sh_size = rela_hdr->sh_entsize * count;
331
  rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size);
332
  if (rela_hdr->contents == NULL)
333
    {
334
      *failedp = TRUE;
335
      return;
336
    }
337
 
338
  /* Figure out whether the relocations are RELA or REL relocations.  */
339
  if (rela_hdr->sh_type != SHT_RELA)
340
    abort ();
341
 
342
  /* The address of an ELF reloc is section relative for an object
343
     file, and absolute for an executable file or shared library.
344
     The address of a BFD reloc is always section relative.  */
345
  addr_offset = 0;
346
  if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
347
    addr_offset = sec->vma;
348
 
349
  /* orelocation has the data, reloc_count has the count...  */
350
  outbound_relocas = (Elf64_External_Rela *) rela_hdr->contents;
351
  src_rela = outbound_relocas;
352
 
353
  for (idx = 0; idx < sec->reloc_count; idx++)
354
    {
355
      Elf_Internal_Rela dst_rela;
356
      arelent *ptr;
357
      asymbol *sym;
358
      int n;
359
 
360
      ptr = sec->orelocation[idx];
361
      sym = *ptr->sym_ptr_ptr;
362
      if (sym == last_sym)
363
        n = last_sym_idx;
364
      else if (bfd_is_abs_section (sym->section) && sym->value == 0)
365
        n = STN_UNDEF;
366
      else
367
        {
368
          last_sym = sym;
369
          n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
370
          if (n < 0)
371
            {
372
              *failedp = TRUE;
373
              return;
374
            }
375
          last_sym_idx = n;
376
        }
377
 
378
      if ((*ptr->sym_ptr_ptr)->the_bfd != NULL
379
          && (*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
380
          && ! _bfd_elf_validate_reloc (abfd, ptr))
381
        {
382
          *failedp = TRUE;
383
          return;
384
        }
385
 
386
      if (ptr->howto->type == R_SPARC_LO10
387
          && idx < sec->reloc_count - 1)
388
        {
389
          arelent *r = sec->orelocation[idx + 1];
390
 
391
          if (r->howto->type == R_SPARC_13
392
              && r->address == ptr->address
393
              && bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
394
              && (*r->sym_ptr_ptr)->value == 0)
395
            {
396
              idx++;
397
              dst_rela.r_info
398
                = ELF64_R_INFO (n, ELF64_R_TYPE_INFO (r->addend,
399
                                                      R_SPARC_OLO10));
400
            }
401
          else
402
            dst_rela.r_info = ELF64_R_INFO (n, R_SPARC_LO10);
403
        }
404
      else
405
        dst_rela.r_info = ELF64_R_INFO (n, ptr->howto->type);
406
 
407
      dst_rela.r_offset = ptr->address + addr_offset;
408
      dst_rela.r_addend = ptr->addend;
409
 
410
      bfd_elf64_swap_reloca_out (abfd, &dst_rela, (bfd_byte *) src_rela);
411
      ++src_rela;
412
    }
413
}
414
 
415
/* Hook called by the linker routine which adds symbols from an object
416
   file.  We use it for STT_REGISTER symbols.  */
417
 
418
static bfd_boolean
419
elf64_sparc_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
420
                             Elf_Internal_Sym *sym, const char **namep,
421
                             flagword *flagsp ATTRIBUTE_UNUSED,
422
                             asection **secp ATTRIBUTE_UNUSED,
423
                             bfd_vma *valp ATTRIBUTE_UNUSED)
424
{
425
  static const char *const stt_types[] = { "NOTYPE", "OBJECT", "FUNCTION" };
426
 
427
  if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
428
    elf_tdata (info->output_bfd)->has_ifunc_symbols = TRUE;
429
 
430
  if (ELF_ST_TYPE (sym->st_info) == STT_REGISTER)
431
    {
432
      int reg;
433
      struct _bfd_sparc_elf_app_reg *p;
434
 
435
      reg = (int)sym->st_value;
436
      switch (reg & ~1)
437
        {
438
        case 2: reg -= 2; break;
439
        case 6: reg -= 4; break;
440
        default:
441
          (*_bfd_error_handler)
442
            (_("%B: Only registers %%g[2367] can be declared using STT_REGISTER"),
443
             abfd);
444
          return FALSE;
445
        }
446
 
447
      if (info->output_bfd->xvec != abfd->xvec
448
          || (abfd->flags & DYNAMIC) != 0)
449
        {
450
          /* STT_REGISTER only works when linking an elf64_sparc object.
451
             If STT_REGISTER comes from a dynamic object, don't put it into
452
             the output bfd.  The dynamic linker will recheck it.  */
453
          *namep = NULL;
454
          return TRUE;
455
        }
456
 
457
      p = _bfd_sparc_elf_hash_table(info)->app_regs + reg;
458
 
459
      if (p->name != NULL && strcmp (p->name, *namep))
460
        {
461
          (*_bfd_error_handler)
462
            (_("Register %%g%d used incompatibly: %s in %B, previously %s in %B"),
463
             abfd, p->abfd, (int) sym->st_value,
464
             **namep ? *namep : "#scratch",
465
             *p->name ? p->name : "#scratch");
466
          return FALSE;
467
        }
468
 
469
      if (p->name == NULL)
470
        {
471
          if (**namep)
472
            {
473
              struct elf_link_hash_entry *h;
474
 
475
              h = (struct elf_link_hash_entry *)
476
                bfd_link_hash_lookup (info->hash, *namep, FALSE, FALSE, FALSE);
477
 
478
              if (h != NULL)
479
                {
480
                  unsigned char type = h->type;
481
 
482
                  if (type > STT_FUNC)
483
                    type = 0;
484
                  (*_bfd_error_handler)
485
                    (_("Symbol `%s' has differing types: REGISTER in %B, previously %s in %B"),
486
                     abfd, p->abfd, *namep, stt_types[type]);
487
                  return FALSE;
488
                }
489
 
490
              p->name = bfd_hash_allocate (&info->hash->table,
491
                                           strlen (*namep) + 1);
492
              if (!p->name)
493
                return FALSE;
494
 
495
              strcpy (p->name, *namep);
496
            }
497
          else
498
            p->name = "";
499
          p->bind = ELF_ST_BIND (sym->st_info);
500
          p->abfd = abfd;
501
          p->shndx = sym->st_shndx;
502
        }
503
      else
504
        {
505
          if (p->bind == STB_WEAK
506
              && ELF_ST_BIND (sym->st_info) == STB_GLOBAL)
507
            {
508
              p->bind = STB_GLOBAL;
509
              p->abfd = abfd;
510
            }
511
        }
512
      *namep = NULL;
513
      return TRUE;
514
    }
515
  else if (*namep && **namep
516
           && info->output_bfd->xvec == abfd->xvec)
517
    {
518
      int i;
519
      struct _bfd_sparc_elf_app_reg *p;
520
 
521
      p = _bfd_sparc_elf_hash_table(info)->app_regs;
522
      for (i = 0; i < 4; i++, p++)
523
        if (p->name != NULL && ! strcmp (p->name, *namep))
524
          {
525
            unsigned char type = ELF_ST_TYPE (sym->st_info);
526
 
527
            if (type > STT_FUNC)
528
              type = 0;
529
            (*_bfd_error_handler)
530
              (_("Symbol `%s' has differing types: %s in %B, previously REGISTER in %B"),
531
               abfd, p->abfd, *namep, stt_types[type]);
532
            return FALSE;
533
          }
534
    }
535
  return TRUE;
536
}
537
 
538
/* This function takes care of emitting STT_REGISTER symbols
539
   which we cannot easily keep in the symbol hash table.  */
540
 
541
static bfd_boolean
542
elf64_sparc_output_arch_syms (bfd *output_bfd ATTRIBUTE_UNUSED,
543
                              struct bfd_link_info *info,
544
                              PTR finfo,
545
                              int (*func) (PTR, const char *,
546
                                           Elf_Internal_Sym *,
547
                                           asection *,
548
                                           struct elf_link_hash_entry *))
549
{
550
  int reg;
551
  struct _bfd_sparc_elf_app_reg *app_regs =
552
    _bfd_sparc_elf_hash_table(info)->app_regs;
553
  Elf_Internal_Sym sym;
554
 
555
  /* We arranged in size_dynamic_sections to put the STT_REGISTER entries
556
     at the end of the dynlocal list, so they came at the end of the local
557
     symbols in the symtab.  Except that they aren't STB_LOCAL, so we need
558
     to back up symtab->sh_info.  */
559
  if (elf_hash_table (info)->dynlocal)
560
    {
561
      bfd * dynobj = elf_hash_table (info)->dynobj;
562
      asection *dynsymsec = bfd_get_section_by_name (dynobj, ".dynsym");
563
      struct elf_link_local_dynamic_entry *e;
564
 
565
      for (e = elf_hash_table (info)->dynlocal; e ; e = e->next)
566
        if (e->input_indx == -1)
567
          break;
568
      if (e)
569
        {
570
          elf_section_data (dynsymsec->output_section)->this_hdr.sh_info
571
            = e->dynindx;
572
        }
573
    }
574
 
575
  if (info->strip == strip_all)
576
    return TRUE;
577
 
578
  for (reg = 0; reg < 4; reg++)
579
    if (app_regs [reg].name != NULL)
580
      {
581
        if (info->strip == strip_some
582
            && bfd_hash_lookup (info->keep_hash,
583
                                app_regs [reg].name,
584
                                FALSE, FALSE) == NULL)
585
          continue;
586
 
587
        sym.st_value = reg < 2 ? reg + 2 : reg + 4;
588
        sym.st_size = 0;
589
        sym.st_other = 0;
590
        sym.st_info = ELF_ST_INFO (app_regs [reg].bind, STT_REGISTER);
591
        sym.st_shndx = app_regs [reg].shndx;
592
        if ((*func) (finfo, app_regs [reg].name, &sym,
593
                     sym.st_shndx == SHN_ABS
594
                     ? bfd_abs_section_ptr : bfd_und_section_ptr,
595
                     NULL) != 1)
596
          return FALSE;
597
      }
598
 
599
  return TRUE;
600
}
601
 
602
static int
603
elf64_sparc_get_symbol_type (Elf_Internal_Sym *elf_sym, int type)
604
{
605
  if (ELF_ST_TYPE (elf_sym->st_info) == STT_REGISTER)
606
    return STT_REGISTER;
607
  else
608
    return type;
609
}
610
 
611
/* A STB_GLOBAL,STT_REGISTER symbol should be BSF_GLOBAL
612
   even in SHN_UNDEF section.  */
613
 
614
static void
615
elf64_sparc_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED, asymbol *asym)
616
{
617
  elf_symbol_type *elfsym;
618
 
619
  elfsym = (elf_symbol_type *) asym;
620
  if (elfsym->internal_elf_sym.st_info
621
      == ELF_ST_INFO (STB_GLOBAL, STT_REGISTER))
622
    {
623
      asym->flags |= BSF_GLOBAL;
624
    }
625
}
626
 
627
 
628
/* Functions for dealing with the e_flags field.  */
629
 
630
/* Merge backend specific data from an object file to the output
631
   object file when linking.  */
632
 
633
static bfd_boolean
634
elf64_sparc_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
635
{
636
  bfd_boolean error;
637
  flagword new_flags, old_flags;
638
  int new_mm, old_mm;
639
 
640
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
641
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
642
    return TRUE;
643
 
644
  new_flags = elf_elfheader (ibfd)->e_flags;
645
  old_flags = elf_elfheader (obfd)->e_flags;
646
 
647
  if (!elf_flags_init (obfd))   /* First call, no flags set */
648
    {
649
      elf_flags_init (obfd) = TRUE;
650
      elf_elfheader (obfd)->e_flags = new_flags;
651
    }
652
 
653
  else if (new_flags == old_flags)      /* Compatible flags are ok */
654
    ;
655
 
656
  else                                  /* Incompatible flags */
657
    {
658
      error = FALSE;
659
 
660
#define EF_SPARC_ISA_EXTENSIONS \
661
  (EF_SPARC_SUN_US1 | EF_SPARC_SUN_US3 | EF_SPARC_HAL_R1)
662
 
663
      if ((ibfd->flags & DYNAMIC) != 0)
664
        {
665
          /* We don't want dynamic objects memory ordering and
666
             architecture to have any role. That's what dynamic linker
667
             should do.  */
668
          new_flags &= ~(EF_SPARCV9_MM | EF_SPARC_ISA_EXTENSIONS);
669
          new_flags |= (old_flags
670
                        & (EF_SPARCV9_MM | EF_SPARC_ISA_EXTENSIONS));
671
        }
672
      else
673
        {
674
          /* Choose the highest architecture requirements.  */
675
          old_flags |= (new_flags & EF_SPARC_ISA_EXTENSIONS);
676
          new_flags |= (old_flags & EF_SPARC_ISA_EXTENSIONS);
677
          if ((old_flags & (EF_SPARC_SUN_US1 | EF_SPARC_SUN_US3))
678
              && (old_flags & EF_SPARC_HAL_R1))
679
            {
680
              error = TRUE;
681
              (*_bfd_error_handler)
682
                (_("%B: linking UltraSPARC specific with HAL specific code"),
683
                 ibfd);
684
            }
685
          /* Choose the most restrictive memory ordering.  */
686
          old_mm = (old_flags & EF_SPARCV9_MM);
687
          new_mm = (new_flags & EF_SPARCV9_MM);
688
          old_flags &= ~EF_SPARCV9_MM;
689
          new_flags &= ~EF_SPARCV9_MM;
690
          if (new_mm < old_mm)
691
            old_mm = new_mm;
692
          old_flags |= old_mm;
693
          new_flags |= old_mm;
694
        }
695
 
696
      /* Warn about any other mismatches */
697
      if (new_flags != old_flags)
698
        {
699
          error = TRUE;
700
          (*_bfd_error_handler)
701
            (_("%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
702
             ibfd, (long) new_flags, (long) old_flags);
703
        }
704
 
705
      elf_elfheader (obfd)->e_flags = old_flags;
706
 
707
      if (error)
708
        {
709
          bfd_set_error (bfd_error_bad_value);
710
          return FALSE;
711
        }
712
    }
713
  return TRUE;
714
}
715
 
716
/* MARCO: Set the correct entry size for the .stab section.  */
717
 
718
static bfd_boolean
719
elf64_sparc_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
720
                           Elf_Internal_Shdr *hdr ATTRIBUTE_UNUSED,
721
                           asection *sec)
722
{
723
  const char *name;
724
 
725
  name = bfd_get_section_name (abfd, sec);
726
 
727
  if (strcmp (name, ".stab") == 0)
728
    {
729
      /* Even in the 64bit case the stab entries are only 12 bytes long.  */
730
      elf_section_data (sec)->this_hdr.sh_entsize = 12;
731
    }
732
 
733
  return TRUE;
734
}
735
 
736
/* Print a STT_REGISTER symbol to file FILE.  */
737
 
738
static const char *
739
elf64_sparc_print_symbol_all (bfd *abfd ATTRIBUTE_UNUSED, PTR filep,
740
                              asymbol *symbol)
741
{
742
  FILE *file = (FILE *) filep;
743
  int reg, type;
744
 
745
  if (ELF_ST_TYPE (((elf_symbol_type *) symbol)->internal_elf_sym.st_info)
746
      != STT_REGISTER)
747
    return NULL;
748
 
749
  reg = ((elf_symbol_type *) symbol)->internal_elf_sym.st_value;
750
  type = symbol->flags;
751
  fprintf (file, "REG_%c%c%11s%c%c    R", "GOLI" [reg / 8], '0' + (reg & 7), "",
752
                 ((type & BSF_LOCAL)
753
                  ? (type & BSF_GLOBAL) ? '!' : 'l'
754
                  : (type & BSF_GLOBAL) ? 'g' : ' '),
755
                 (type & BSF_WEAK) ? 'w' : ' ');
756
  if (symbol->name == NULL || symbol->name [0] == '\0')
757
    return "#scratch";
758
  else
759
    return symbol->name;
760
}
761
 
762
static enum elf_reloc_type_class
763
elf64_sparc_reloc_type_class (const Elf_Internal_Rela *rela)
764
{
765
  switch ((int) ELF64_R_TYPE (rela->r_info))
766
    {
767
    case R_SPARC_RELATIVE:
768
      return reloc_class_relative;
769
    case R_SPARC_JMP_SLOT:
770
      return reloc_class_plt;
771
    case R_SPARC_COPY:
772
      return reloc_class_copy;
773
    default:
774
      return reloc_class_normal;
775
    }
776
}
777
 
778
/* Relocations in the 64 bit SPARC ELF ABI are more complex than in
779
   standard ELF, because R_SPARC_OLO10 has secondary addend in
780
   ELF64_R_TYPE_DATA field.  This structure is used to redirect the
781
   relocation handling routines.  */
782
 
783
const struct elf_size_info elf64_sparc_size_info =
784
{
785
  sizeof (Elf64_External_Ehdr),
786
  sizeof (Elf64_External_Phdr),
787
  sizeof (Elf64_External_Shdr),
788
  sizeof (Elf64_External_Rel),
789
  sizeof (Elf64_External_Rela),
790
  sizeof (Elf64_External_Sym),
791
  sizeof (Elf64_External_Dyn),
792
  sizeof (Elf_External_Note),
793
  4,            /* hash-table entry size.  */
794
  /* Internal relocations per external relocations.
795
     For link purposes we use just 1 internal per
796
     1 external, for assembly and slurp symbol table
797
     we use 2.  */
798
  1,
799
  64,           /* arch_size.  */
800
  3,            /* log_file_align.  */
801
  ELFCLASS64,
802
  EV_CURRENT,
803
  bfd_elf64_write_out_phdrs,
804
  bfd_elf64_write_shdrs_and_ehdr,
805
  bfd_elf64_checksum_contents,
806
  elf64_sparc_write_relocs,
807
  bfd_elf64_swap_symbol_in,
808
  bfd_elf64_swap_symbol_out,
809
  elf64_sparc_slurp_reloc_table,
810
  bfd_elf64_slurp_symbol_table,
811
  bfd_elf64_swap_dyn_in,
812
  bfd_elf64_swap_dyn_out,
813
  bfd_elf64_swap_reloc_in,
814
  bfd_elf64_swap_reloc_out,
815
  bfd_elf64_swap_reloca_in,
816
  bfd_elf64_swap_reloca_out
817
};
818
 
819
#define TARGET_BIG_SYM  bfd_elf64_sparc_vec
820
#define TARGET_BIG_NAME "elf64-sparc"
821
#define ELF_ARCH        bfd_arch_sparc
822
#define ELF_MAXPAGESIZE 0x100000
823
#define ELF_COMMONPAGESIZE 0x2000
824
 
825
/* This is the official ABI value.  */
826
#define ELF_MACHINE_CODE EM_SPARCV9
827
 
828
/* This is the value that we used before the ABI was released.  */
829
#define ELF_MACHINE_ALT1 EM_OLD_SPARCV9
830
 
831
#define elf_backend_reloc_type_class \
832
  elf64_sparc_reloc_type_class
833
#define bfd_elf64_get_reloc_upper_bound \
834
  elf64_sparc_get_reloc_upper_bound
835
#define bfd_elf64_get_dynamic_reloc_upper_bound \
836
  elf64_sparc_get_dynamic_reloc_upper_bound
837
#define bfd_elf64_canonicalize_reloc \
838
  elf64_sparc_canonicalize_reloc
839
#define bfd_elf64_canonicalize_dynamic_reloc \
840
  elf64_sparc_canonicalize_dynamic_reloc
841
#define elf_backend_add_symbol_hook \
842
  elf64_sparc_add_symbol_hook
843
#define elf_backend_get_symbol_type \
844
  elf64_sparc_get_symbol_type
845
#define elf_backend_symbol_processing \
846
  elf64_sparc_symbol_processing
847
#define elf_backend_print_symbol_all \
848
  elf64_sparc_print_symbol_all
849
#define elf_backend_output_arch_syms \
850
  elf64_sparc_output_arch_syms
851
#define bfd_elf64_bfd_merge_private_bfd_data \
852
  elf64_sparc_merge_private_bfd_data
853
#define elf_backend_fake_sections \
854
  elf64_sparc_fake_sections
855
#define elf_backend_size_info \
856
  elf64_sparc_size_info
857
 
858
#define elf_backend_plt_sym_val \
859
  _bfd_sparc_elf_plt_sym_val
860
#define bfd_elf64_bfd_link_hash_table_create \
861
  _bfd_sparc_elf_link_hash_table_create
862
#define bfd_elf64_bfd_link_hash_table_free \
863
  _bfd_sparc_elf_link_hash_table_free
864
#define elf_info_to_howto \
865
  _bfd_sparc_elf_info_to_howto
866
#define elf_backend_copy_indirect_symbol \
867
  _bfd_sparc_elf_copy_indirect_symbol
868
#define bfd_elf64_bfd_reloc_type_lookup \
869
  _bfd_sparc_elf_reloc_type_lookup
870
#define bfd_elf64_bfd_reloc_name_lookup \
871
  _bfd_sparc_elf_reloc_name_lookup
872
#define bfd_elf64_bfd_relax_section \
873
  _bfd_sparc_elf_relax_section
874
#define bfd_elf64_new_section_hook \
875
  _bfd_sparc_elf_new_section_hook
876
 
877
#define elf_backend_create_dynamic_sections \
878
  _bfd_sparc_elf_create_dynamic_sections
879
#define elf_backend_relocs_compatible \
880
  _bfd_elf_relocs_compatible
881
#define elf_backend_check_relocs \
882
  _bfd_sparc_elf_check_relocs
883
#define elf_backend_adjust_dynamic_symbol \
884
  _bfd_sparc_elf_adjust_dynamic_symbol
885
#define elf_backend_omit_section_dynsym \
886
  _bfd_sparc_elf_omit_section_dynsym
887
#define elf_backend_size_dynamic_sections \
888
  _bfd_sparc_elf_size_dynamic_sections
889
#define elf_backend_relocate_section \
890
  _bfd_sparc_elf_relocate_section
891
#define elf_backend_finish_dynamic_symbol \
892
  _bfd_sparc_elf_finish_dynamic_symbol
893
#define elf_backend_finish_dynamic_sections \
894
  _bfd_sparc_elf_finish_dynamic_sections
895
 
896
#define bfd_elf64_mkobject \
897
  _bfd_sparc_elf_mkobject
898
#define elf_backend_object_p \
899
  _bfd_sparc_elf_object_p
900
#define elf_backend_gc_mark_hook \
901
  _bfd_sparc_elf_gc_mark_hook
902
#define elf_backend_gc_sweep_hook \
903
  _bfd_sparc_elf_gc_sweep_hook
904
#define elf_backend_init_index_section \
905
  _bfd_elf_init_1_index_section
906
 
907
#define elf_backend_can_gc_sections 1
908
#define elf_backend_can_refcount 1
909
#define elf_backend_want_got_plt 0
910
#define elf_backend_plt_readonly 0
911
#define elf_backend_want_plt_sym 1
912
#define elf_backend_got_header_size 8
913
#define elf_backend_rela_normal 1
914
 
915
/* Section 5.2.4 of the ABI specifies a 256-byte boundary for the table.  */
916
#define elf_backend_plt_alignment 8
917
 
918
#define elf_backend_post_process_headers        _bfd_elf_set_osabi
919
 
920
#include "elf64-target.h"
921
 
922
/* FreeBSD support */
923
#undef  TARGET_BIG_SYM
924
#define TARGET_BIG_SYM bfd_elf64_sparc_freebsd_vec
925
#undef  TARGET_BIG_NAME
926
#define TARGET_BIG_NAME "elf64-sparc-freebsd"
927
#undef  ELF_OSABI
928
#define ELF_OSABI ELFOSABI_FREEBSD
929
 
930
#undef  elf64_bed
931
#define elf64_bed                               elf64_sparc_fbsd_bed
932
 
933
#include "elf64-target.h"
934
 

powered by: WebSVN 2.1.0

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