~ubuntu-branches/debian/jessie/gdb/jessie

« back to all changes in this revision

Viewing changes to bfd/elf64-x86-64.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Jacobowitz
  • Date: 2010-03-20 01:21:29 UTC
  • mfrom: (1.3.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20100320012129-t7h25y8zgr8c2369
Tags: 7.1-1
* New upstream release, including:
  - PIE support (Closes: #346409).
  - C++ improvements, including static_cast<> et al, namespace imports,
    and bug fixes in printing virtual base classes.
  - Multi-program debugging.  One GDB can now debug multiple programs
    at the same time.
  - Python scripting improvements, including gdb.parse_and_eval.
  - Updated MIPS Linux signal frame layout (Closes: #570875).
  - No internal error stepping over _dl_debug_state (Closes: #569551).
* Update to Standards-Version: 3.8.4 (no changes required).
* Include more relevant (and smaller) docs in the gdbserver package
  (Closes: #571132).
* Do not duplicate documentation in gdb64, gdb-source, and libgdb-dev.
* Fix crash when switching into TUI mode (Closes: #568489).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* X86-64 specific support for 64-bit ELF
2
 
   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
3
 
   Free Software Foundation, Inc.
 
2
   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
 
3
   2010  Free Software Foundation, Inc.
4
4
   Contributed by Jan Hubicka <jh@suse.cz>.
5
5
 
6
6
   This file is part of BFD, the Binary File Descriptor library.
451
451
#define is_x86_64_elf(bfd)                              \
452
452
  (bfd_get_flavour (bfd) == bfd_target_elf_flavour      \
453
453
   && elf_tdata (bfd) != NULL                           \
454
 
   && elf_object_id (bfd) == X86_64_ELF_TDATA)
 
454
   && elf_object_id (bfd) == X86_64_ELF_DATA)
455
455
 
456
456
static bfd_boolean
457
457
elf64_x86_64_mkobject (bfd *abfd)
458
458
{
459
459
  return bfd_elf_allocate_object (abfd, sizeof (struct elf64_x86_64_obj_tdata),
460
 
                                  X86_64_ELF_TDATA);
 
460
                                  X86_64_ELF_DATA);
461
461
}
462
462
 
463
463
/* x86-64 ELF linker hash table.  */
470
470
  asection *sdynbss;
471
471
  asection *srelbss;
472
472
 
473
 
  /* The offset into splt of the PLT entry for the TLS descriptor
474
 
     resolver.  Special values are 0, if not necessary (or not found
475
 
     to be necessary yet), and -1 if needed but not determined
476
 
     yet.  */
477
 
  bfd_vma tlsdesc_plt;
478
 
  /* The offset into sgot of the GOT entry used by the PLT entry
479
 
     above.  */
480
 
  bfd_vma tlsdesc_got;
481
 
 
482
 
  union {
 
473
  union
 
474
  {
483
475
    bfd_signed_vma refcount;
484
476
    bfd_vma offset;
485
477
  } tls_ld_got;
495
487
 
496
488
  /* Used by local STT_GNU_IFUNC symbols.  */
497
489
  htab_t loc_hash_table;
498
 
  void *loc_hash_memory;
 
490
  void * loc_hash_memory;
 
491
 
 
492
  /* The offset into splt of the PLT entry for the TLS descriptor
 
493
     resolver.  Special values are 0, if not necessary (or not found
 
494
     to be necessary yet), and -1 if needed but not determined
 
495
     yet.  */
 
496
  bfd_vma tlsdesc_plt;
 
497
  /* The offset into sgot of the GOT entry used by the PLT entry
 
498
     above.  */
 
499
  bfd_vma tlsdesc_got;
499
500
};
500
501
 
501
502
/* Get the x86-64 ELF linker hash table from a link_info structure.  */
502
503
 
503
504
#define elf64_x86_64_hash_table(p) \
504
 
  ((struct elf64_x86_64_link_hash_table *) ((p)->hash))
 
505
  (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
 
506
  == X86_64_ELF_DATA ? ((struct elf64_x86_64_link_hash_table *) ((p)->hash)) : NULL)
505
507
 
506
508
#define elf64_x86_64_compute_jump_table_size(htab) \
507
509
  ((htab)->elf.srelplt->reloc_count * GOT_ENTRY_SIZE)
622
624
 
623
625
  if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
624
626
                                      elf64_x86_64_link_hash_newfunc,
625
 
                                      sizeof (struct elf64_x86_64_link_hash_entry)))
 
627
                                      sizeof (struct elf64_x86_64_link_hash_entry),
 
628
                                      X86_64_ELF_DATA))
626
629
    {
627
630
      free (ret);
628
631
      return NULL;
679
682
    return FALSE;
680
683
 
681
684
  htab = elf64_x86_64_hash_table (info);
 
685
  if (htab == NULL)
 
686
    return FALSE;
 
687
 
682
688
  htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss");
683
689
  if (!info->shared)
684
690
    htab->srelbss = bfd_get_section_by_name (dynobj, ".rela.bss");
1018
1024
        name = h->root.root.string;
1019
1025
      else
1020
1026
        {
1021
 
          Elf_Internal_Sym *isym;
1022
1027
          struct elf64_x86_64_link_hash_table *htab;
 
1028
 
1023
1029
          htab = elf64_x86_64_hash_table (info);
1024
 
          isym = bfd_sym_from_r_symndx (&htab->sym_cache,
1025
 
                                        abfd, r_symndx);
1026
 
          name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
 
1030
          if (htab == NULL)
 
1031
            name = "*unknown*";
 
1032
          else
 
1033
            {
 
1034
              Elf_Internal_Sym *isym;
 
1035
 
 
1036
              isym = bfd_sym_from_r_symndx (&htab->sym_cache,
 
1037
                                            abfd, r_symndx);
 
1038
              name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
 
1039
            }
1027
1040
        }
1028
1041
 
1029
1042
      (*_bfd_error_handler)
1061
1074
  BFD_ASSERT (is_x86_64_elf (abfd));
1062
1075
 
1063
1076
  htab = elf64_x86_64_hash_table (info);
 
1077
  if (htab == NULL)
 
1078
    return FALSE;
 
1079
 
1064
1080
  symtab_hdr = &elf_symtab_hdr (abfd);
1065
1081
  sym_hashes = elf_sym_hashes (abfd);
1066
1082
 
1100
1116
                                                   TRUE);
1101
1117
              if (h == NULL)
1102
1118
                return FALSE;
1103
 
              
 
1119
 
1104
1120
              /* Fake a STT_GNU_IFUNC symbol.  */
1105
1121
              h->type = STT_GNU_IFUNC;
1106
1122
              h->def_regular = 1;
1152
1168
              /* It is referenced by a non-shared object. */
1153
1169
              h->ref_regular = 1;
1154
1170
              h->needs_plt = 1;
1155
 
 
 
1171
 
1156
1172
              /* STT_GNU_IFUNC symbol must go through PLT.  */
1157
1173
              h->plt.refcount += 1;
1158
1174
 
1504
1520
                     easily.  Oh well.  */
1505
1521
                  asection *s;
1506
1522
                  void **vpp;
1507
 
                  Elf_Internal_Sym *isym;
1508
1523
 
1509
1524
                  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
1510
1525
                                                abfd, r_symndx);
1595
1610
                            asection *sec,
1596
1611
                            const Elf_Internal_Rela *relocs)
1597
1612
{
 
1613
  struct elf64_x86_64_link_hash_table *htab;
1598
1614
  Elf_Internal_Shdr *symtab_hdr;
1599
1615
  struct elf_link_hash_entry **sym_hashes;
1600
1616
  bfd_signed_vma *local_got_refcounts;
1603
1619
  if (info->relocatable)
1604
1620
    return TRUE;
1605
1621
 
 
1622
  htab = elf64_x86_64_hash_table (info);
 
1623
  if (htab == NULL)
 
1624
    return FALSE;
 
1625
 
1606
1626
  elf_section_data (sec)->local_dynrel = NULL;
1607
1627
 
1608
1628
  symtab_hdr = &elf_symtab_hdr (abfd);
1648
1668
      switch (r_type)
1649
1669
        {
1650
1670
        case R_X86_64_TLSLD:
1651
 
          if (elf64_x86_64_hash_table (info)->tls_ld_got.refcount > 0)
1652
 
            elf64_x86_64_hash_table (info)->tls_ld_got.refcount -= 1;
 
1671
          if (htab->tls_ld_got.refcount > 0)
 
1672
            htab->tls_ld_got.refcount -= 1;
1653
1673
          break;
1654
1674
 
1655
1675
        case R_X86_64_TLSGD:
1835
1855
     same memory location for the variable.  */
1836
1856
 
1837
1857
  htab = elf64_x86_64_hash_table (info);
 
1858
  if (htab == NULL)
 
1859
    return FALSE;
1838
1860
 
1839
1861
  /* We must generate a R_X86_64_COPY reloc to tell the dynamic linker
1840
1862
     to copy the initial value out of the dynamic object and into the
1870
1892
 
1871
1893
  info = (struct bfd_link_info *) inf;
1872
1894
  htab = elf64_x86_64_hash_table (info);
 
1895
  if (htab == NULL)
 
1896
    return FALSE;
1873
1897
 
1874
1898
  /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
1875
1899
     here if it is defined and referenced in a non-shared object.  */
2160
2184
  bfd *ibfd;
2161
2185
 
2162
2186
  htab = elf64_x86_64_hash_table (info);
 
2187
  if (htab == NULL)
 
2188
    return FALSE;
 
2189
 
2163
2190
  dynobj = htab->elf.dynobj;
2164
2191
  if (dynobj == NULL)
2165
2192
    abort ();
2455
2482
 
2456
2483
      if (tlsbase && tlsbase->type == STT_TLS)
2457
2484
        {
 
2485
          struct elf64_x86_64_link_hash_table *htab;
2458
2486
          struct bfd_link_hash_entry *bh = NULL;
2459
2487
          const struct elf_backend_data *bed
2460
2488
            = get_elf_backend_data (output_bfd);
2461
2489
 
 
2490
          htab = elf64_x86_64_hash_table (info);
 
2491
          if (htab == NULL)
 
2492
            return FALSE;
 
2493
 
2462
2494
          if (!(_bfd_generic_link_add_one_symbol
2463
2495
                (info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
2464
2496
                 tls_sec, 0, NULL, FALSE,
2465
2497
                 bed->collect, &bh)))
2466
2498
            return FALSE;
2467
2499
 
2468
 
          elf64_x86_64_hash_table (info)->tls_module_base = bh;
 
2500
          htab->tls_module_base = bh;
2469
2501
 
2470
2502
          tlsbase = (struct elf_link_hash_entry *)bh;
2471
2503
          tlsbase->def_regular = 1;
2485
2517
static void
2486
2518
elf64_x86_64_set_tls_module_base (struct bfd_link_info *info)
2487
2519
{
 
2520
  struct elf64_x86_64_link_hash_table *htab;
2488
2521
  struct bfd_link_hash_entry *base;
2489
2522
 
2490
2523
  if (!info->executable)
2491
2524
    return;
2492
2525
 
2493
 
  base = elf64_x86_64_hash_table (info)->tls_module_base;
2494
 
 
2495
 
  if (!base)
2496
 
    return;
2497
 
 
2498
 
  base->u.def.value = elf_hash_table (info)->tls_size;
 
2526
  htab = elf64_x86_64_hash_table (info);
 
2527
  if (htab == NULL)
 
2528
    return;
 
2529
 
 
2530
  base = htab->tls_module_base;
 
2531
  if (base == NULL)
 
2532
    return;
 
2533
 
 
2534
  base->u.def.value = htab->elf.tls_size;
2499
2535
}
2500
2536
 
2501
2537
/* Return the base VMA address which should be subtracted from real addresses
2543
2579
              && (contents [offset - 1] & 0xf0) == 0x80));
2544
2580
}
2545
2581
 
 
2582
static void
 
2583
elf64_x86_64_append_rela (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
 
2584
{
 
2585
  bfd_byte *loc = s->contents;
 
2586
  loc += s->reloc_count++ * sizeof (Elf64_External_Rela);
 
2587
  BFD_ASSERT (loc + sizeof (Elf64_External_Rela)
 
2588
              <= s->contents + s->size);
 
2589
  bfd_elf64_swap_reloca_out (abfd, rel, loc);
 
2590
}
 
2591
 
2546
2592
/* Relocate an x86_64 ELF section.  */
2547
2593
 
2548
2594
static bfd_boolean
2563
2609
  BFD_ASSERT (is_x86_64_elf (input_bfd));
2564
2610
 
2565
2611
  htab = elf64_x86_64_hash_table (info);
 
2612
  if (htab == NULL)
 
2613
    return FALSE;
2566
2614
  symtab_hdr = &elf_symtab_hdr (input_bfd);
2567
2615
  sym_hashes = elf_sym_hashes (input_bfd);
2568
2616
  local_got_offsets = elf_local_got_offsets (input_bfd);
2712
2760
              if (info->shared && h->non_got_ref)
2713
2761
                {
2714
2762
                  Elf_Internal_Rela outrel;
2715
 
                  bfd_byte *loc;
2716
2763
                  asection *sreloc;
2717
2764
 
2718
2765
                  /* Need a dynamic relocation to get the real function
2745
2792
                    }
2746
2793
 
2747
2794
                  sreloc = htab->elf.irelifunc;
2748
 
                  loc = sreloc->contents;
2749
 
                  loc += (sreloc->reloc_count++
2750
 
                          * sizeof (Elf64_External_Rela));
2751
 
                  bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
 
2795
                  elf64_x86_64_append_rela (output_bfd, sreloc, &outrel);
2752
2796
 
2753
2797
                  /* If this reloc is against an external symbol, we
2754
2798
                     do not want to fiddle with the addend.  Otherwise,
2931
2975
                    {
2932
2976
                      asection *s;
2933
2977
                      Elf_Internal_Rela outrel;
2934
 
                      bfd_byte *loc;
2935
2978
 
2936
2979
                      /* We need to generate a R_X86_64_RELATIVE reloc
2937
2980
                         for the dynamic linker.  */
2944
2987
                                         + off);
2945
2988
                      outrel.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE);
2946
2989
                      outrel.r_addend = relocation;
2947
 
                      loc = s->contents;
2948
 
                      loc += s->reloc_count++ * sizeof (Elf64_External_Rela);
2949
 
                      bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
 
2990
                      elf64_x86_64_append_rela (output_bfd, s, &outrel);
2950
2991
                    }
2951
2992
 
2952
2993
                  local_got_offsets[r_symndx] |= 1;
3135
3176
                      || h->root.type == bfd_link_hash_undefined)))
3136
3177
            {
3137
3178
              Elf_Internal_Rela outrel;
3138
 
              bfd_byte *loc;
3139
3179
              bfd_boolean skip, relocate;
3140
3180
              asection *sreloc;
3141
3181
 
3219
3259
 
3220
3260
              BFD_ASSERT (sreloc != NULL && sreloc->contents != NULL);
3221
3261
 
3222
 
              loc = sreloc->contents;
3223
 
              loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
3224
 
              bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
 
3262
              elf64_x86_64_append_rela (output_bfd, sreloc, &outrel);
3225
3263
 
3226
3264
              /* If this reloc is against an external symbol, we do
3227
3265
                 not want to fiddle with the addend.  Otherwise, we
3392
3430
          else
3393
3431
            {
3394
3432
              Elf_Internal_Rela outrel;
3395
 
              bfd_byte *loc;
3396
3433
              int dr_type, indx;
3397
3434
              asection *sreloc;
3398
3435
 
3411
3448
                                     + offplt
3412
3449
                                     + htab->sgotplt_jump_table_size);
3413
3450
                  sreloc = htab->elf.srelplt;
3414
 
                  loc = sreloc->contents;
3415
 
                  loc += sreloc->reloc_count++
3416
 
                    * sizeof (Elf64_External_Rela);
3417
 
                  BFD_ASSERT (loc + sizeof (Elf64_External_Rela)
3418
 
                              <= sreloc->contents + sreloc->size);
3419
3451
                  if (indx == 0)
3420
3452
                    outrel.r_addend = relocation - elf64_x86_64_dtpoff_base (info);
3421
3453
                  else
3422
3454
                    outrel.r_addend = 0;
3423
 
                  bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
 
3455
                  elf64_x86_64_append_rela (output_bfd, sreloc, &outrel);
3424
3456
                }
3425
3457
 
3426
3458
              sreloc = htab->elf.srelgot;
3442
3474
                outrel.r_addend = relocation - elf64_x86_64_dtpoff_base (info);
3443
3475
              outrel.r_info = ELF64_R_INFO (indx, dr_type);
3444
3476
 
3445
 
              loc = sreloc->contents;
3446
 
              loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
3447
 
              BFD_ASSERT (loc + sizeof (Elf64_External_Rela)
3448
 
                          <= sreloc->contents + sreloc->size);
3449
 
              bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
 
3477
              elf64_x86_64_append_rela (output_bfd, sreloc, &outrel);
3450
3478
 
3451
3479
              if (GOT_TLS_GD_P (tls_type))
3452
3480
                {
3464
3492
                      outrel.r_info = ELF64_R_INFO (indx,
3465
3493
                                                    R_X86_64_DTPOFF64);
3466
3494
                      outrel.r_offset += GOT_ENTRY_SIZE;
3467
 
                      sreloc->reloc_count++;
3468
 
                      loc += sizeof (Elf64_External_Rela);
3469
 
                      BFD_ASSERT (loc + sizeof (Elf64_External_Rela)
3470
 
                                  <= sreloc->contents + sreloc->size);
3471
 
                      bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
 
3495
                      elf64_x86_64_append_rela (output_bfd, sreloc,
 
3496
                                                &outrel);
3472
3497
                    }
3473
3498
                }
3474
3499
 
3608
3633
          else
3609
3634
            {
3610
3635
              Elf_Internal_Rela outrel;
3611
 
              bfd_byte *loc;
3612
3636
 
3613
3637
              if (htab->elf.srelgot == NULL)
3614
3638
                abort ();
3622
3646
                          htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
3623
3647
              outrel.r_info = ELF64_R_INFO (0, R_X86_64_DTPMOD64);
3624
3648
              outrel.r_addend = 0;
3625
 
              loc = htab->elf.srelgot->contents;
3626
 
              loc += htab->elf.srelgot->reloc_count++ * sizeof (Elf64_External_Rela);
3627
 
              bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
 
3649
              elf64_x86_64_append_rela (output_bfd, htab->elf.srelgot,
 
3650
                                        &outrel);
3628
3651
              htab->tls_ld_got.offset |= 1;
3629
3652
            }
3630
3653
          relocation = htab->elf.sgot->output_section->vma
3718
3741
  struct elf64_x86_64_link_hash_table *htab;
3719
3742
 
3720
3743
  htab = elf64_x86_64_hash_table (info);
 
3744
  if (htab == NULL)
 
3745
    return FALSE;
3721
3746
 
3722
3747
  if (h->plt.offset != (bfd_vma) -1)
3723
3748
    {
3757
3782
         corresponds to this symbol.  This is the index of this symbol
3758
3783
         in all the symbols for which we are making plt entries.  The
3759
3784
         first entry in the procedure linkage table is reserved.
3760
 
         
 
3785
 
3761
3786
         Get the offset into the .got table of the entry that
3762
3787
         corresponds to this function.  Each .got entry is GOT_ENTRY_SIZE
3763
3788
         bytes. The first three are reserved for the dynamic linker.
3858
3883
      && elf64_x86_64_hash_entry (h)->tls_type != GOT_TLS_IE)
3859
3884
    {
3860
3885
      Elf_Internal_Rela rela;
3861
 
      bfd_byte *loc;
3862
3886
 
3863
3887
      /* This symbol has an entry in the global offset table.  Set it
3864
3888
         up.  */
3921
3945
          rela.r_addend = 0;
3922
3946
        }
3923
3947
 
3924
 
      loc = htab->elf.srelgot->contents;
3925
 
      loc += htab->elf.srelgot->reloc_count++ * sizeof (Elf64_External_Rela);
3926
 
      bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
 
3948
      elf64_x86_64_append_rela (output_bfd, htab->elf.srelgot, &rela);
3927
3949
    }
3928
3950
 
3929
3951
  if (h->needs_copy)
3930
3952
    {
3931
3953
      Elf_Internal_Rela rela;
3932
 
      bfd_byte *loc;
3933
3954
 
3934
3955
      /* This symbol needs a copy reloc.  Set it up.  */
3935
3956
 
3944
3965
                       + h->root.u.def.section->output_offset);
3945
3966
      rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_COPY);
3946
3967
      rela.r_addend = 0;
3947
 
      loc = htab->srelbss->contents;
3948
 
      loc += htab->srelbss->reloc_count++ * sizeof (Elf64_External_Rela);
3949
 
      bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
 
3968
      elf64_x86_64_append_rela (output_bfd, htab->srelbss, &rela);
3950
3969
    }
3951
3970
 
3952
3971
  /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  SYM may
4003
4022
  asection *sdyn;
4004
4023
 
4005
4024
  htab = elf64_x86_64_hash_table (info);
 
4025
  if (htab == NULL)
 
4026
    return FALSE;
 
4027
 
4006
4028
  dynobj = htab->elf.dynobj;
4007
4029
  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
4008
4030
 
4247
4269
 
4248
4270
static bfd_boolean
4249
4271
elf64_x86_64_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
4250
 
                                           asection *sec, int *index)
 
4272
                                           asection *sec, int *index_return)
4251
4273
{
4252
4274
  if (sec == &_bfd_elf_large_com_section)
4253
4275
    {
4254
 
      *index = SHN_X86_64_LCOMMON;
 
4276
      *index_return = SHN_X86_64_LCOMMON;
4255
4277
      return TRUE;
4256
4278
    }
4257
4279
  return FALSE;