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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [bfd/] [elf64-sparc.c] - Blame information for rev 818

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

Line No. Rev Author Line
1 24 jeremybenn
/* SPARC-specific support for 64-bit ELF
2
   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 225 jeremybenn
   2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
4 24 jeremybenn
 
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_REGISTER)
428
    {
429
      int reg;
430
      struct _bfd_sparc_elf_app_reg *p;
431
 
432
      reg = (int)sym->st_value;
433
      switch (reg & ~1)
434
        {
435
        case 2: reg -= 2; break;
436
        case 6: reg -= 4; break;
437
        default:
438
          (*_bfd_error_handler)
439
            (_("%B: Only registers %%g[2367] can be declared using STT_REGISTER"),
440
             abfd);
441
          return FALSE;
442
        }
443
 
444
      if (info->output_bfd->xvec != abfd->xvec
445
          || (abfd->flags & DYNAMIC) != 0)
446
        {
447
          /* STT_REGISTER only works when linking an elf64_sparc object.
448
             If STT_REGISTER comes from a dynamic object, don't put it into
449
             the output bfd.  The dynamic linker will recheck it.  */
450
          *namep = NULL;
451
          return TRUE;
452
        }
453
 
454
      p = _bfd_sparc_elf_hash_table(info)->app_regs + reg;
455
 
456
      if (p->name != NULL && strcmp (p->name, *namep))
457
        {
458
          (*_bfd_error_handler)
459
            (_("Register %%g%d used incompatibly: %s in %B, previously %s in %B"),
460
             abfd, p->abfd, (int) sym->st_value,
461
             **namep ? *namep : "#scratch",
462
             *p->name ? p->name : "#scratch");
463
          return FALSE;
464
        }
465
 
466
      if (p->name == NULL)
467
        {
468
          if (**namep)
469
            {
470
              struct elf_link_hash_entry *h;
471
 
472
              h = (struct elf_link_hash_entry *)
473
                bfd_link_hash_lookup (info->hash, *namep, FALSE, FALSE, FALSE);
474
 
475
              if (h != NULL)
476
                {
477
                  unsigned char type = h->type;
478
 
479
                  if (type > STT_FUNC)
480
                    type = 0;
481
                  (*_bfd_error_handler)
482
                    (_("Symbol `%s' has differing types: REGISTER in %B, previously %s in %B"),
483
                     abfd, p->abfd, *namep, stt_types[type]);
484
                  return FALSE;
485
                }
486
 
487
              p->name = bfd_hash_allocate (&info->hash->table,
488
                                           strlen (*namep) + 1);
489
              if (!p->name)
490
                return FALSE;
491
 
492
              strcpy (p->name, *namep);
493
            }
494
          else
495
            p->name = "";
496
          p->bind = ELF_ST_BIND (sym->st_info);
497
          p->abfd = abfd;
498
          p->shndx = sym->st_shndx;
499
        }
500
      else
501
        {
502
          if (p->bind == STB_WEAK
503
              && ELF_ST_BIND (sym->st_info) == STB_GLOBAL)
504
            {
505
              p->bind = STB_GLOBAL;
506
              p->abfd = abfd;
507
            }
508
        }
509
      *namep = NULL;
510
      return TRUE;
511
    }
512
  else if (*namep && **namep
513
           && info->output_bfd->xvec == abfd->xvec)
514
    {
515
      int i;
516
      struct _bfd_sparc_elf_app_reg *p;
517
 
518
      p = _bfd_sparc_elf_hash_table(info)->app_regs;
519
      for (i = 0; i < 4; i++, p++)
520
        if (p->name != NULL && ! strcmp (p->name, *namep))
521
          {
522
            unsigned char type = ELF_ST_TYPE (sym->st_info);
523
 
524
            if (type > STT_FUNC)
525
              type = 0;
526
            (*_bfd_error_handler)
527
              (_("Symbol `%s' has differing types: %s in %B, previously REGISTER in %B"),
528
               abfd, p->abfd, *namep, stt_types[type]);
529
            return FALSE;
530
          }
531
    }
532
  return TRUE;
533
}
534
 
535
/* This function takes care of emitting STT_REGISTER symbols
536
   which we cannot easily keep in the symbol hash table.  */
537
 
538
static bfd_boolean
539
elf64_sparc_output_arch_syms (bfd *output_bfd ATTRIBUTE_UNUSED,
540
                              struct bfd_link_info *info,
541 225 jeremybenn
                              PTR finfo,
542
                              int (*func) (PTR, const char *,
543
                                           Elf_Internal_Sym *,
544
                                           asection *,
545
                                           struct elf_link_hash_entry *))
546 24 jeremybenn
{
547
  int reg;
548
  struct _bfd_sparc_elf_app_reg *app_regs =
549
    _bfd_sparc_elf_hash_table(info)->app_regs;
550
  Elf_Internal_Sym sym;
551
 
552
  /* We arranged in size_dynamic_sections to put the STT_REGISTER entries
553
     at the end of the dynlocal list, so they came at the end of the local
554
     symbols in the symtab.  Except that they aren't STB_LOCAL, so we need
555
     to back up symtab->sh_info.  */
556
  if (elf_hash_table (info)->dynlocal)
557
    {
558
      bfd * dynobj = elf_hash_table (info)->dynobj;
559
      asection *dynsymsec = bfd_get_section_by_name (dynobj, ".dynsym");
560
      struct elf_link_local_dynamic_entry *e;
561
 
562
      for (e = elf_hash_table (info)->dynlocal; e ; e = e->next)
563
        if (e->input_indx == -1)
564
          break;
565
      if (e)
566
        {
567
          elf_section_data (dynsymsec->output_section)->this_hdr.sh_info
568
            = e->dynindx;
569
        }
570
    }
571
 
572
  if (info->strip == strip_all)
573
    return TRUE;
574
 
575
  for (reg = 0; reg < 4; reg++)
576
    if (app_regs [reg].name != NULL)
577
      {
578
        if (info->strip == strip_some
579
            && bfd_hash_lookup (info->keep_hash,
580
                                app_regs [reg].name,
581
                                FALSE, FALSE) == NULL)
582
          continue;
583
 
584
        sym.st_value = reg < 2 ? reg + 2 : reg + 4;
585
        sym.st_size = 0;
586
        sym.st_other = 0;
587
        sym.st_info = ELF_ST_INFO (app_regs [reg].bind, STT_REGISTER);
588
        sym.st_shndx = app_regs [reg].shndx;
589 225 jeremybenn
        if ((*func) (finfo, app_regs [reg].name, &sym,
590
                     sym.st_shndx == SHN_ABS
591
                     ? bfd_abs_section_ptr : bfd_und_section_ptr,
592
                     NULL) != 1)
593 24 jeremybenn
          return FALSE;
594
      }
595
 
596
  return TRUE;
597
}
598
 
599
static int
600
elf64_sparc_get_symbol_type (Elf_Internal_Sym *elf_sym, int type)
601
{
602
  if (ELF_ST_TYPE (elf_sym->st_info) == STT_REGISTER)
603
    return STT_REGISTER;
604
  else
605
    return type;
606
}
607
 
608
/* A STB_GLOBAL,STT_REGISTER symbol should be BSF_GLOBAL
609
   even in SHN_UNDEF section.  */
610
 
611
static void
612
elf64_sparc_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED, asymbol *asym)
613
{
614
  elf_symbol_type *elfsym;
615
 
616
  elfsym = (elf_symbol_type *) asym;
617
  if (elfsym->internal_elf_sym.st_info
618
      == ELF_ST_INFO (STB_GLOBAL, STT_REGISTER))
619
    {
620
      asym->flags |= BSF_GLOBAL;
621
    }
622
}
623
 
624
 
625
/* Functions for dealing with the e_flags field.  */
626
 
627
/* Merge backend specific data from an object file to the output
628
   object file when linking.  */
629
 
630
static bfd_boolean
631
elf64_sparc_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
632
{
633
  bfd_boolean error;
634
  flagword new_flags, old_flags;
635
  int new_mm, old_mm;
636
 
637
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
638
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
639
    return TRUE;
640
 
641
  new_flags = elf_elfheader (ibfd)->e_flags;
642
  old_flags = elf_elfheader (obfd)->e_flags;
643
 
644
  if (!elf_flags_init (obfd))   /* First call, no flags set */
645
    {
646
      elf_flags_init (obfd) = TRUE;
647
      elf_elfheader (obfd)->e_flags = new_flags;
648
    }
649
 
650
  else if (new_flags == old_flags)      /* Compatible flags are ok */
651
    ;
652
 
653
  else                                  /* Incompatible flags */
654
    {
655
      error = FALSE;
656
 
657
#define EF_SPARC_ISA_EXTENSIONS \
658
  (EF_SPARC_SUN_US1 | EF_SPARC_SUN_US3 | EF_SPARC_HAL_R1)
659
 
660
      if ((ibfd->flags & DYNAMIC) != 0)
661
        {
662
          /* We don't want dynamic objects memory ordering and
663
             architecture to have any role. That's what dynamic linker
664
             should do.  */
665
          new_flags &= ~(EF_SPARCV9_MM | EF_SPARC_ISA_EXTENSIONS);
666
          new_flags |= (old_flags
667
                        & (EF_SPARCV9_MM | EF_SPARC_ISA_EXTENSIONS));
668
        }
669
      else
670
        {
671
          /* Choose the highest architecture requirements.  */
672
          old_flags |= (new_flags & EF_SPARC_ISA_EXTENSIONS);
673
          new_flags |= (old_flags & EF_SPARC_ISA_EXTENSIONS);
674
          if ((old_flags & (EF_SPARC_SUN_US1 | EF_SPARC_SUN_US3))
675
              && (old_flags & EF_SPARC_HAL_R1))
676
            {
677
              error = TRUE;
678
              (*_bfd_error_handler)
679
                (_("%B: linking UltraSPARC specific with HAL specific code"),
680
                 ibfd);
681
            }
682
          /* Choose the most restrictive memory ordering.  */
683
          old_mm = (old_flags & EF_SPARCV9_MM);
684
          new_mm = (new_flags & EF_SPARCV9_MM);
685
          old_flags &= ~EF_SPARCV9_MM;
686
          new_flags &= ~EF_SPARCV9_MM;
687
          if (new_mm < old_mm)
688
            old_mm = new_mm;
689
          old_flags |= old_mm;
690
          new_flags |= old_mm;
691
        }
692
 
693
      /* Warn about any other mismatches */
694
      if (new_flags != old_flags)
695
        {
696
          error = TRUE;
697
          (*_bfd_error_handler)
698
            (_("%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
699
             ibfd, (long) new_flags, (long) old_flags);
700
        }
701
 
702
      elf_elfheader (obfd)->e_flags = old_flags;
703
 
704
      if (error)
705
        {
706
          bfd_set_error (bfd_error_bad_value);
707
          return FALSE;
708
        }
709
    }
710
  return TRUE;
711
}
712
 
713
/* MARCO: Set the correct entry size for the .stab section.  */
714
 
715
static bfd_boolean
716
elf64_sparc_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
717
                           Elf_Internal_Shdr *hdr ATTRIBUTE_UNUSED,
718
                           asection *sec)
719
{
720
  const char *name;
721
 
722
  name = bfd_get_section_name (abfd, sec);
723
 
724
  if (strcmp (name, ".stab") == 0)
725
    {
726
      /* Even in the 64bit case the stab entries are only 12 bytes long.  */
727
      elf_section_data (sec)->this_hdr.sh_entsize = 12;
728
    }
729
 
730
  return TRUE;
731
}
732
 
733
/* Print a STT_REGISTER symbol to file FILE.  */
734
 
735
static const char *
736
elf64_sparc_print_symbol_all (bfd *abfd ATTRIBUTE_UNUSED, PTR filep,
737
                              asymbol *symbol)
738
{
739
  FILE *file = (FILE *) filep;
740
  int reg, type;
741
 
742
  if (ELF_ST_TYPE (((elf_symbol_type *) symbol)->internal_elf_sym.st_info)
743
      != STT_REGISTER)
744
    return NULL;
745
 
746
  reg = ((elf_symbol_type *) symbol)->internal_elf_sym.st_value;
747
  type = symbol->flags;
748
  fprintf (file, "REG_%c%c%11s%c%c    R", "GOLI" [reg / 8], '0' + (reg & 7), "",
749
                 ((type & BSF_LOCAL)
750
                  ? (type & BSF_GLOBAL) ? '!' : 'l'
751
                  : (type & BSF_GLOBAL) ? 'g' : ' '),
752
                 (type & BSF_WEAK) ? 'w' : ' ');
753
  if (symbol->name == NULL || symbol->name [0] == '\0')
754
    return "#scratch";
755
  else
756
    return symbol->name;
757
}
758
 
759
static enum elf_reloc_type_class
760
elf64_sparc_reloc_type_class (const Elf_Internal_Rela *rela)
761
{
762
  switch ((int) ELF64_R_TYPE (rela->r_info))
763
    {
764
    case R_SPARC_RELATIVE:
765
      return reloc_class_relative;
766
    case R_SPARC_JMP_SLOT:
767
      return reloc_class_plt;
768
    case R_SPARC_COPY:
769
      return reloc_class_copy;
770
    default:
771
      return reloc_class_normal;
772
    }
773
}
774
 
775
/* Relocations in the 64 bit SPARC ELF ABI are more complex than in
776
   standard ELF, because R_SPARC_OLO10 has secondary addend in
777
   ELF64_R_TYPE_DATA field.  This structure is used to redirect the
778
   relocation handling routines.  */
779
 
780
const struct elf_size_info elf64_sparc_size_info =
781
{
782
  sizeof (Elf64_External_Ehdr),
783
  sizeof (Elf64_External_Phdr),
784
  sizeof (Elf64_External_Shdr),
785
  sizeof (Elf64_External_Rel),
786
  sizeof (Elf64_External_Rela),
787
  sizeof (Elf64_External_Sym),
788
  sizeof (Elf64_External_Dyn),
789
  sizeof (Elf_External_Note),
790
  4,            /* hash-table entry size.  */
791
  /* Internal relocations per external relocations.
792
     For link purposes we use just 1 internal per
793
     1 external, for assembly and slurp symbol table
794
     we use 2.  */
795
  1,
796
  64,           /* arch_size.  */
797
  3,            /* log_file_align.  */
798
  ELFCLASS64,
799
  EV_CURRENT,
800
  bfd_elf64_write_out_phdrs,
801
  bfd_elf64_write_shdrs_and_ehdr,
802
  bfd_elf64_checksum_contents,
803
  elf64_sparc_write_relocs,
804
  bfd_elf64_swap_symbol_in,
805
  bfd_elf64_swap_symbol_out,
806
  elf64_sparc_slurp_reloc_table,
807
  bfd_elf64_slurp_symbol_table,
808
  bfd_elf64_swap_dyn_in,
809
  bfd_elf64_swap_dyn_out,
810
  bfd_elf64_swap_reloc_in,
811
  bfd_elf64_swap_reloc_out,
812
  bfd_elf64_swap_reloca_in,
813
  bfd_elf64_swap_reloca_out
814
};
815
 
816
#define TARGET_BIG_SYM  bfd_elf64_sparc_vec
817
#define TARGET_BIG_NAME "elf64-sparc"
818
#define ELF_ARCH        bfd_arch_sparc
819
#define ELF_MAXPAGESIZE 0x100000
820
#define ELF_COMMONPAGESIZE 0x2000
821
 
822
/* This is the official ABI value.  */
823
#define ELF_MACHINE_CODE EM_SPARCV9
824
 
825
/* This is the value that we used before the ABI was released.  */
826
#define ELF_MACHINE_ALT1 EM_OLD_SPARCV9
827
 
828
#define elf_backend_reloc_type_class \
829
  elf64_sparc_reloc_type_class
830
#define bfd_elf64_get_reloc_upper_bound \
831
  elf64_sparc_get_reloc_upper_bound
832
#define bfd_elf64_get_dynamic_reloc_upper_bound \
833
  elf64_sparc_get_dynamic_reloc_upper_bound
834
#define bfd_elf64_canonicalize_reloc \
835
  elf64_sparc_canonicalize_reloc
836
#define bfd_elf64_canonicalize_dynamic_reloc \
837
  elf64_sparc_canonicalize_dynamic_reloc
838
#define elf_backend_add_symbol_hook \
839
  elf64_sparc_add_symbol_hook
840
#define elf_backend_get_symbol_type \
841
  elf64_sparc_get_symbol_type
842
#define elf_backend_symbol_processing \
843
  elf64_sparc_symbol_processing
844
#define elf_backend_print_symbol_all \
845
  elf64_sparc_print_symbol_all
846
#define elf_backend_output_arch_syms \
847
  elf64_sparc_output_arch_syms
848
#define bfd_elf64_bfd_merge_private_bfd_data \
849
  elf64_sparc_merge_private_bfd_data
850
#define elf_backend_fake_sections \
851
  elf64_sparc_fake_sections
852
#define elf_backend_size_info \
853
  elf64_sparc_size_info
854
 
855
#define elf_backend_plt_sym_val \
856
  _bfd_sparc_elf_plt_sym_val
857
#define bfd_elf64_bfd_link_hash_table_create \
858
  _bfd_sparc_elf_link_hash_table_create
859
#define elf_info_to_howto \
860
  _bfd_sparc_elf_info_to_howto
861
#define elf_backend_copy_indirect_symbol \
862
  _bfd_sparc_elf_copy_indirect_symbol
863
#define bfd_elf64_bfd_reloc_type_lookup \
864
  _bfd_sparc_elf_reloc_type_lookup
865
#define bfd_elf64_bfd_reloc_name_lookup \
866
  _bfd_sparc_elf_reloc_name_lookup
867
#define bfd_elf64_bfd_relax_section \
868
  _bfd_sparc_elf_relax_section
869
#define bfd_elf64_new_section_hook \
870
  _bfd_sparc_elf_new_section_hook
871
 
872
#define elf_backend_create_dynamic_sections \
873
  _bfd_sparc_elf_create_dynamic_sections
874
#define elf_backend_relocs_compatible \
875
  _bfd_elf_relocs_compatible
876
#define elf_backend_check_relocs \
877
  _bfd_sparc_elf_check_relocs
878
#define elf_backend_adjust_dynamic_symbol \
879
  _bfd_sparc_elf_adjust_dynamic_symbol
880
#define elf_backend_omit_section_dynsym \
881
  _bfd_sparc_elf_omit_section_dynsym
882
#define elf_backend_size_dynamic_sections \
883
  _bfd_sparc_elf_size_dynamic_sections
884
#define elf_backend_relocate_section \
885
  _bfd_sparc_elf_relocate_section
886
#define elf_backend_finish_dynamic_symbol \
887
  _bfd_sparc_elf_finish_dynamic_symbol
888
#define elf_backend_finish_dynamic_sections \
889
  _bfd_sparc_elf_finish_dynamic_sections
890
 
891
#define bfd_elf64_mkobject \
892
  _bfd_sparc_elf_mkobject
893
#define elf_backend_object_p \
894
  _bfd_sparc_elf_object_p
895
#define elf_backend_gc_mark_hook \
896
  _bfd_sparc_elf_gc_mark_hook
897
#define elf_backend_gc_sweep_hook \
898
  _bfd_sparc_elf_gc_sweep_hook
899
#define elf_backend_init_index_section \
900
  _bfd_elf_init_1_index_section
901
 
902
#define elf_backend_can_gc_sections 1
903
#define elf_backend_can_refcount 1
904
#define elf_backend_want_got_plt 0
905
#define elf_backend_plt_readonly 0
906
#define elf_backend_want_plt_sym 1
907
#define elf_backend_got_header_size 8
908
#define elf_backend_rela_normal 1
909
 
910
/* Section 5.2.4 of the ABI specifies a 256-byte boundary for the table.  */
911
#define elf_backend_plt_alignment 8
912
 
913
#include "elf64-target.h"
914
 
915
/* FreeBSD support */
916
#undef  TARGET_BIG_SYM
917
#define TARGET_BIG_SYM bfd_elf64_sparc_freebsd_vec
918
#undef  TARGET_BIG_NAME
919
#define TARGET_BIG_NAME "elf64-sparc-freebsd"
920
#undef  ELF_OSABI
921
#define ELF_OSABI ELFOSABI_FREEBSD
922
 
923
#undef  elf_backend_post_process_headers
924
#define elf_backend_post_process_headers        _bfd_elf_set_osabi
925
#undef  elf64_bed
926
#define elf64_bed                               elf64_sparc_fbsd_bed
927
 
928
#include "elf64-target.h"
929
 

powered by: WebSVN 2.1.0

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