Develop and Download Open Source Software

Browse Subversion Repository

Diff of /trunk/bfd/elf32-i386.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 20 by monabuilder, Sun Dec 28 03:31:28 2008 UTC revision 21 by monamour, Mon Jul 27 20:34:36 2009 UTC
# Line 26  Line 26 
26  #include "elf-bfd.h"  #include "elf-bfd.h"
27  #include "elf-vxworks.h"  #include "elf-vxworks.h"
28  #include "bfd_stdint.h"  #include "bfd_stdint.h"
29    #include "objalloc.h"
30    #include "hashtab.h"
31    
32  /* 386 uses REL relocations instead of RELA.  */  /* 386 uses REL relocations instead of RELA.  */
33  #define USE_REL 1  #define USE_REL 1
# Line 138  static reloc_howto_type elf_howto_table[ Line 140  static reloc_howto_type elf_howto_table[
140    HOWTO(R_386_TLS_DESC, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,    HOWTO(R_386_TLS_DESC, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
141          bfd_elf_generic_reloc, "R_386_TLS_DESC",          bfd_elf_generic_reloc, "R_386_TLS_DESC",
142          TRUE, 0xffffffff, 0xffffffff, FALSE),          TRUE, 0xffffffff, 0xffffffff, FALSE),
143      HOWTO(R_386_IRELATIVE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
144            bfd_elf_generic_reloc, "R_386_IRELATIVE",
145            TRUE, 0xffffffff, 0xffffffff, FALSE),
146    
147    /* Another gap.  */    /* Another gap.  */
148  #define R_386_tls (R_386_TLS_DESC + 1 - R_386_tls_offset)  #define R_386_irelative (R_386_IRELATIVE + 1 - R_386_tls_offset)
149  #define R_386_vt_offset (R_386_GNU_VTINHERIT - R_386_tls)  #define R_386_vt_offset (R_386_GNU_VTINHERIT - R_386_irelative)
150    
151  /* GNU extension to record C++ vtable hierarchy.  */  /* GNU extension to record C++ vtable hierarchy.  */
152    HOWTO (R_386_GNU_VTINHERIT,   /* type */    HOWTO (R_386_GNU_VTINHERIT,   /* type */
# Line 316  elf_i386_reloc_type_lookup (bfd *abfd AT Line 321  elf_i386_reloc_type_lookup (bfd *abfd AT
321        TRACE ("BFD_RELOC_386_TLS_DESC");        TRACE ("BFD_RELOC_386_TLS_DESC");
322        return &elf_howto_table[R_386_TLS_DESC - R_386_tls_offset];        return &elf_howto_table[R_386_TLS_DESC - R_386_tls_offset];
323    
324        case BFD_RELOC_386_IRELATIVE:
325          TRACE ("BFD_RELOC_386_IRELATIVE");
326          return &elf_howto_table[R_386_IRELATIVE];
327    
328      case BFD_RELOC_VTABLE_INHERIT:      case BFD_RELOC_VTABLE_INHERIT:
329        TRACE ("BFD_RELOC_VTABLE_INHERIT");        TRACE ("BFD_RELOC_VTABLE_INHERIT");
330        return &elf_howto_table[R_386_GNU_VTINHERIT - R_386_vt_offset];        return &elf_howto_table[R_386_GNU_VTINHERIT - R_386_vt_offset];
# Line 355  elf_i386_rtype_to_howto (bfd *abfd, unsi Line 364  elf_i386_rtype_to_howto (bfd *abfd, unsi
364        && ((indx = r_type - R_386_ext_offset) - R_386_standard        && ((indx = r_type - R_386_ext_offset) - R_386_standard
365            >= R_386_ext - R_386_standard)            >= R_386_ext - R_386_standard)
366        && ((indx = r_type - R_386_tls_offset) - R_386_ext        && ((indx = r_type - R_386_tls_offset) - R_386_ext
367            >= R_386_tls - R_386_ext)            >= R_386_irelative - R_386_ext)
368        && ((indx = r_type - R_386_vt_offset) - R_386_tls        && ((indx = r_type - R_386_vt_offset) - R_386_irelative
369            >= R_386_vt - R_386_tls))            >= R_386_vt - R_386_irelative))
370      {      {
371        (*_bfd_error_handler) (_("%B: invalid relocation type %d"),        (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
372                               abfd, (int) r_type);                               abfd, (int) r_type);
# Line 568  static const bfd_byte elf_i386_pic_plt_e Line 577  static const bfd_byte elf_i386_pic_plt_e
577  #define PLTRESOLVE_RELOCS 2  #define PLTRESOLVE_RELOCS 2
578  #define PLT_NON_JUMP_SLOT_RELOCS 2  #define PLT_NON_JUMP_SLOT_RELOCS 2
579    
 /* The i386 linker needs to keep track of the number of relocs that it  
    decides to copy as dynamic relocs in check_relocs for each symbol.  
    This is so that it can later discard them if they are found to be  
    unnecessary.  We store the information in a field extending the  
    regular ELF linker hash table.  */  
   
 struct elf_i386_dyn_relocs  
 {  
   struct elf_i386_dyn_relocs *next;  
   
   /* The input section of the reloc.  */  
   asection *sec;  
   
   /* Total number of relocs copied for the input section.  */  
   bfd_size_type count;  
   
   /* Number of pc-relative relocs copied for the input section.  */  
   bfd_size_type pc_count;  
 };  
   
580  /* i386 ELF linker hash entry.  */  /* i386 ELF linker hash entry.  */
581    
582  struct elf_i386_link_hash_entry  struct elf_i386_link_hash_entry
# Line 595  struct elf_i386_link_hash_entry Line 584  struct elf_i386_link_hash_entry
584    struct elf_link_hash_entry elf;    struct elf_link_hash_entry elf;
585    
586    /* Track dynamic relocs copied for this symbol.  */    /* Track dynamic relocs copied for this symbol.  */
587    struct elf_i386_dyn_relocs *dyn_relocs;    struct elf_dyn_relocs *dyn_relocs;
588    
589  #define GOT_UNKNOWN     0  #define GOT_UNKNOWN     0
590  #define GOT_NORMAL      1  #define GOT_NORMAL      1
# Line 661  struct elf_i386_link_hash_table Line 650  struct elf_i386_link_hash_table
650    struct elf_link_hash_table elf;    struct elf_link_hash_table elf;
651    
652    /* Short-cuts to get to dynamic linker sections.  */    /* Short-cuts to get to dynamic linker sections.  */
   asection *sgot;  
   asection *sgotplt;  
   asection *srelgot;  
   asection *splt;  
   asection *srelplt;  
653    asection *sdynbss;    asection *sdynbss;
654    asection *srelbss;    asection *srelbss;
655    
# Line 690  struct elf_i386_link_hash_table Line 674  struct elf_i386_link_hash_table
674       section, plus whatever space is used by the jump slots.  */       section, plus whatever space is used by the jump slots.  */
675    bfd_vma sgotplt_jump_table_size;    bfd_vma sgotplt_jump_table_size;
676    
677    /* Small local sym to section mapping cache.  */    /* Small local sym cache.  */
678    struct sym_sec_cache sym_sec;    struct sym_cache sym_cache;
679    
680    /* _TLS_MODULE_BASE_ symbol.  */    /* _TLS_MODULE_BASE_ symbol.  */
681    struct bfd_link_hash_entry *tls_module_base;    struct bfd_link_hash_entry *tls_module_base;
682    
683      /* Used by local STT_GNU_IFUNC symbols.  */
684      htab_t loc_hash_table;
685      void *loc_hash_memory;
686  };  };
687    
688  /* Get the i386 ELF linker hash table from a link_info structure.  */  /* Get the i386 ELF linker hash table from a link_info structure.  */
# Line 708  struct elf_i386_link_hash_table Line 696  struct elf_i386_link_hash_table
696  /* Create an entry in an i386 ELF linker hash table.  */  /* Create an entry in an i386 ELF linker hash table.  */
697    
698  static struct bfd_hash_entry *  static struct bfd_hash_entry *
699  link_hash_newfunc (struct bfd_hash_entry *entry,  elf_i386_link_hash_newfunc (struct bfd_hash_entry *entry,
700                     struct bfd_hash_table *table,                              struct bfd_hash_table *table,
701                     const char *string)                              const char *string)
702  {  {
703    /* Allocate the structure if it has not already been allocated by a    /* Allocate the structure if it has not already been allocated by a
704       subclass.  */       subclass.  */
# Line 737  link_hash_newfunc (struct bfd_hash_entry Line 725  link_hash_newfunc (struct bfd_hash_entry
725    return entry;    return entry;
726  }  }
727    
728    /* Compute a hash of a local hash entry.  We use elf_link_hash_entry
729      for local symbol so that we can handle local STT_GNU_IFUNC symbols
730      as global symbol.  We reuse indx and dynstr_index for local symbol
731      hash since they aren't used by global symbols in this backend.  */
732    
733    static hashval_t
734    elf_i386_local_htab_hash (const void *ptr)
735    {
736      struct elf_link_hash_entry *h
737        = (struct elf_link_hash_entry *) ptr;
738      return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index);
739    }
740    
741    /* Compare local hash entries.  */
742    
743    static int
744    elf_i386_local_htab_eq (const void *ptr1, const void *ptr2)
745    {
746      struct elf_link_hash_entry *h1
747         = (struct elf_link_hash_entry *) ptr1;
748      struct elf_link_hash_entry *h2
749        = (struct elf_link_hash_entry *) ptr2;
750    
751      return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index;
752    }
753    
754    /* Find and/or create a hash entry for local symbol.  */
755    
756    static struct elf_link_hash_entry *
757    elf_i386_get_local_sym_hash (struct elf_i386_link_hash_table *htab,
758                                 bfd *abfd, const Elf_Internal_Rela *rel,
759                                 bfd_boolean create)
760    {
761      struct elf_i386_link_hash_entry e, *ret;
762      asection *sec = abfd->sections;
763      hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
764                                           ELF32_R_SYM (rel->r_info));
765      void **slot;
766    
767      e.elf.indx = sec->id;
768      e.elf.dynstr_index = ELF32_R_SYM (rel->r_info);
769      slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
770                                       create ? INSERT : NO_INSERT);
771    
772      if (!slot)
773        return NULL;
774    
775      if (*slot)
776        {
777          ret = (struct elf_i386_link_hash_entry *) *slot;
778          return &ret->elf;
779        }
780    
781      ret = (struct elf_i386_link_hash_entry *)
782            objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
783                            sizeof (struct elf_i386_link_hash_entry));
784      if (ret)
785        {
786          memset (ret, 0, sizeof (*ret));
787          ret->elf.indx = sec->id;
788          ret->elf.dynstr_index = ELF32_R_SYM (rel->r_info);
789          ret->elf.dynindx = -1;
790          ret->elf.plt.offset = (bfd_vma) -1;
791          ret->elf.got.offset = (bfd_vma) -1;
792          *slot = ret;
793        }
794      return &ret->elf;
795    }
796    
797  /* Create an i386 ELF linker hash table.  */  /* Create an i386 ELF linker hash table.  */
798    
799  static struct bfd_link_hash_table *  static struct bfd_link_hash_table *
# Line 749  elf_i386_link_hash_table_create (bfd *ab Line 806  elf_i386_link_hash_table_create (bfd *ab
806    if (ret == NULL)    if (ret == NULL)
807      return NULL;      return NULL;
808    
809    if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc,    if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
810                                          elf_i386_link_hash_newfunc,
811                                        sizeof (struct elf_i386_link_hash_entry)))                                        sizeof (struct elf_i386_link_hash_entry)))
812      {      {
813        free (ret);        free (ret);
814        return NULL;        return NULL;
815      }      }
816    
   ret->sgot = NULL;  
   ret->sgotplt = NULL;  
   ret->srelgot = NULL;  
   ret->splt = NULL;  
   ret->srelplt = NULL;  
817    ret->sdynbss = NULL;    ret->sdynbss = NULL;
818    ret->srelbss = NULL;    ret->srelbss = NULL;
819    ret->tls_ldm_got.refcount = 0;    ret->tls_ldm_got.refcount = 0;
820    ret->next_tls_desc_index = 0;    ret->next_tls_desc_index = 0;
821    ret->sgotplt_jump_table_size = 0;    ret->sgotplt_jump_table_size = 0;
822    ret->sym_sec.abfd = NULL;    ret->sym_cache.abfd = NULL;
823    ret->is_vxworks = 0;    ret->is_vxworks = 0;
824    ret->srelplt2 = NULL;    ret->srelplt2 = NULL;
825    ret->plt0_pad_byte = 0;    ret->plt0_pad_byte = 0;
826    ret->tls_module_base = NULL;    ret->tls_module_base = NULL;
827    
828      ret->loc_hash_table = htab_try_create (1024,
829                                             elf_i386_local_htab_hash,
830                                             elf_i386_local_htab_eq,
831                                             NULL);
832      ret->loc_hash_memory = objalloc_create ();
833      if (!ret->loc_hash_table || !ret->loc_hash_memory)
834        {
835          free (ret);
836          return NULL;
837        }
838    
839    return &ret->elf.root;    return &ret->elf.root;
840  }  }
841    
842  /* Create .got, .gotplt, and .rel.got sections in DYNOBJ, and set up  /* Destroy an i386 ELF linker hash table.  */
    shortcuts to them in our hash table.  */  
843    
844  static bfd_boolean  static void
845  create_got_section (bfd *dynobj, struct bfd_link_info *info)  elf_i386_link_hash_table_free (struct bfd_link_hash_table *hash)
846  {  {
847    struct elf_i386_link_hash_table *htab;    struct elf_i386_link_hash_table *htab
848        = (struct elf_i386_link_hash_table *) hash;
   if (! _bfd_elf_create_got_section (dynobj, info))  
     return FALSE;  
849    
850    htab = elf_i386_hash_table (info);    if (htab->loc_hash_table)
851    htab->sgot = bfd_get_section_by_name (dynobj, ".got");      htab_delete (htab->loc_hash_table);
852    htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");    if (htab->loc_hash_memory)
853    if (!htab->sgot || !htab->sgotplt)      objalloc_free ((struct objalloc *) htab->loc_hash_memory);
854      abort ();    _bfd_generic_link_hash_table_free (hash);
   
   htab->srelgot = bfd_make_section_with_flags (dynobj, ".rel.got",  
                                                (SEC_ALLOC | SEC_LOAD  
                                                 | SEC_HAS_CONTENTS  
                                                 | SEC_IN_MEMORY  
                                                 | SEC_LINKER_CREATED  
                                                 | SEC_READONLY));  
   if (htab->srelgot == NULL  
       || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2))  
     return FALSE;  
   return TRUE;  
855  }  }
856    
857  /* Create .plt, .rel.plt, .got, .got.plt, .rel.got, .dynbss, and  /* Create .plt, .rel.plt, .got, .got.plt, .rel.got, .dynbss, and
# Line 813  elf_i386_create_dynamic_sections (bfd *d Line 863  elf_i386_create_dynamic_sections (bfd *d
863  {  {
864    struct elf_i386_link_hash_table *htab;    struct elf_i386_link_hash_table *htab;
865    
   htab = elf_i386_hash_table (info);  
   if (!htab->sgot && !create_got_section (dynobj, info))  
     return FALSE;  
   
866    if (!_bfd_elf_create_dynamic_sections (dynobj, info))    if (!_bfd_elf_create_dynamic_sections (dynobj, info))
867      return FALSE;      return FALSE;
868    
869    htab->splt = bfd_get_section_by_name (dynobj, ".plt");    htab = elf_i386_hash_table (info);
   htab->srelplt = bfd_get_section_by_name (dynobj, ".rel.plt");  
870    htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss");    htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss");
871    if (!info->shared)    if (!info->shared)
872      htab->srelbss = bfd_get_section_by_name (dynobj, ".rel.bss");      htab->srelbss = bfd_get_section_by_name (dynobj, ".rel.bss");
873    
874    if (!htab->splt || !htab->srelplt || !htab->sdynbss    if (!htab->sdynbss
875        || (!info->shared && !htab->srelbss))        || (!info->shared && !htab->srelbss))
876      abort ();      abort ();
877    
878    if (htab->is_vxworks    if (htab->is_vxworks
879        && !elf_vxworks_create_dynamic_sections (dynobj, info, &htab->srelplt2))        && !elf_vxworks_create_dynamic_sections (dynobj, info,
880                                                   &htab->srelplt2))
881      return FALSE;      return FALSE;
882    
883    return TRUE;    return TRUE;
# Line 853  elf_i386_copy_indirect_symbol (struct bf Line 899  elf_i386_copy_indirect_symbol (struct bf
899      {      {
900        if (edir->dyn_relocs != NULL)        if (edir->dyn_relocs != NULL)
901          {          {
902            struct elf_i386_dyn_relocs **pp;            struct elf_dyn_relocs **pp;
903            struct elf_i386_dyn_relocs *p;            struct elf_dyn_relocs *p;
904    
905            /* Add reloc counts against the indirect sym to the direct sym            /* Add reloc counts against the indirect sym to the direct sym
906               list.  Merge any entries against the same section.  */               list.  Merge any entries against the same section.  */
907            for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )            for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
908              {              {
909                struct elf_i386_dyn_relocs *q;                struct elf_dyn_relocs *q;
910    
911                for (q = edir->dyn_relocs; q != NULL; q = q->next)                for (q = edir->dyn_relocs; q != NULL; q = q->next)
912                  if (q->sec == p->sec)                  if (q->sec == p->sec)
# Line 955  elf_i386_check_tls_transition (bfd *abfd Line 1001  elf_i386_check_tls_transition (bfd *abfd
1001        type = bfd_get_8 (abfd, contents + offset - 2);        type = bfd_get_8 (abfd, contents + offset - 2);
1002        if (r_type == R_386_TLS_GD)        if (r_type == R_386_TLS_GD)
1003          {          {
1004            /* Check transition from LD access model.  Only            /* Check transition from GD access model.  Only
1005                  leal foo@tlsgd(,%reg,1), %eax; call ___tls_get_addr                  leal foo@tlsgd(,%reg,1), %eax; call ___tls_get_addr
1006                  leal foo@tlsgd(%reg), %eax; call ___tls_get_addr; nop                  leal foo@tlsgd(%reg), %eax; call ___tls_get_addr; nop
1007               can transit to different access model.  */               can transit to different access model.  */
# Line 1007  elf_i386_check_tls_transition (bfd *abfd Line 1053  elf_i386_check_tls_transition (bfd *abfd
1053          return FALSE;          return FALSE;
1054    
1055        h = sym_hashes[r_symndx - symtab_hdr->sh_info];        h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1056          /* Use strncmp to check ___tls_get_addr since ___tls_get_addr
1057             may be versioned.  */
1058        return (h != NULL        return (h != NULL
1059                && h->root.root.string != NULL                && h->root.root.string != NULL
1060                && (ELF32_R_TYPE (rel[1].r_info) == R_386_PC32                && (ELF32_R_TYPE (rel[1].r_info) == R_386_PC32
1061                    || ELF32_R_TYPE (rel[1].r_info) == R_386_PLT32)                    || ELF32_R_TYPE (rel[1].r_info) == R_386_PLT32)
1062                && (strcmp (h->root.root.string, "___tls_get_addr") == 0));                && (strncmp (h->root.root.string, "___tls_get_addr",
1063                               15) == 0));
1064    
1065      case R_386_TLS_IE:      case R_386_TLS_IE:
1066        /* Check transition from IE access model:        /* Check transition from IE access model:
# Line 1100  elf_i386_tls_transition (struct bfd_link Line 1149  elf_i386_tls_transition (struct bfd_link
1149                           unsigned int *r_type, int tls_type,                           unsigned int *r_type, int tls_type,
1150                           const Elf_Internal_Rela *rel,                           const Elf_Internal_Rela *rel,
1151                           const Elf_Internal_Rela *relend,                           const Elf_Internal_Rela *relend,
1152                           struct elf_link_hash_entry *h)                           struct elf_link_hash_entry *h,
1153                             unsigned long r_symndx)
1154  {  {
1155    unsigned int from_type = *r_type;    unsigned int from_type = *r_type;
1156    unsigned int to_type = from_type;    unsigned int to_type = from_type;
# Line 1175  elf_i386_tls_transition (struct bfd_link Line 1225  elf_i386_tls_transition (struct bfd_link
1225                                            from_type, rel, relend))                                            from_type, rel, relend))
1226      {      {
1227        reloc_howto_type *from, *to;        reloc_howto_type *from, *to;
1228          const char *name;
1229    
1230        from = elf_i386_rtype_to_howto (abfd, from_type);        from = elf_i386_rtype_to_howto (abfd, from_type);
1231        to = elf_i386_rtype_to_howto (abfd, to_type);        to = elf_i386_rtype_to_howto (abfd, to_type);
1232    
1233          if (h)
1234            name = h->root.root.string;
1235          else
1236            {
1237              Elf_Internal_Sym *isym;
1238              struct elf_i386_link_hash_table *htab;
1239              htab = elf_i386_hash_table (info);
1240              isym = bfd_sym_from_r_symndx (&htab->sym_cache,
1241                                            abfd, r_symndx);
1242              name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
1243            }
1244    
1245        (*_bfd_error_handler)        (*_bfd_error_handler)
1246          (_("%B: TLS transition from %s to %s against `%s' at 0x%lx "          (_("%B: TLS transition from %s to %s against `%s' at 0x%lx "
1247             "in section `%A' failed"),             "in section `%A' failed"),
1248           abfd, sec, from->name, to->name,           abfd, sec, from->name, to->name, name,
          h ? h->root.root.string : "a local symbol",  
1249           (unsigned long) rel->r_offset);           (unsigned long) rel->r_offset);
1250        bfd_set_error (bfd_error_bad_value);        bfd_set_error (bfd_error_bad_value);
1251        return FALSE;        return FALSE;
# Line 1227  elf_i386_check_relocs (bfd *abfd, Line 1289  elf_i386_check_relocs (bfd *abfd,
1289        unsigned int r_type;        unsigned int r_type;
1290        unsigned long r_symndx;        unsigned long r_symndx;
1291        struct elf_link_hash_entry *h;        struct elf_link_hash_entry *h;
1292          Elf_Internal_Sym *isym;
1293          const char *name;
1294    
1295        r_symndx = ELF32_R_SYM (rel->r_info);        r_symndx = ELF32_R_SYM (rel->r_info);
1296        r_type = ELF32_R_TYPE (rel->r_info);        r_type = ELF32_R_TYPE (rel->r_info);
# Line 1240  elf_i386_check_relocs (bfd *abfd, Line 1304  elf_i386_check_relocs (bfd *abfd,
1304          }          }
1305    
1306        if (r_symndx < symtab_hdr->sh_info)        if (r_symndx < symtab_hdr->sh_info)
1307          h = NULL;          {
1308              /* A local symbol.  */
1309              isym = bfd_sym_from_r_symndx (&htab->sym_cache,
1310                                            abfd, r_symndx);
1311              if (isym == NULL)
1312                return FALSE;
1313    
1314              /* Check relocation against local STT_GNU_IFUNC symbol.  */
1315              if (ELF32_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
1316                {
1317                  h = elf_i386_get_local_sym_hash (htab, abfd, rel,
1318                                                       TRUE);
1319                  if (h == NULL)
1320                    return FALSE;
1321                  
1322                  /* Fake a STT_GNU_IFUNC symbol.  */
1323                  h->type = STT_GNU_IFUNC;
1324                  h->def_regular = 1;
1325                  h->ref_regular = 1;
1326                  h->forced_local = 1;
1327                  h->root.type = bfd_link_hash_defined;
1328                }
1329              else
1330                h = NULL;
1331            }
1332        else        else
1333          {          {
1334              isym = NULL;
1335            h = sym_hashes[r_symndx - symtab_hdr->sh_info];            h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1336            while (h->root.type == bfd_link_hash_indirect            while (h->root.type == bfd_link_hash_indirect
1337                   || h->root.type == bfd_link_hash_warning)                   || h->root.type == bfd_link_hash_warning)
1338              h = (struct elf_link_hash_entry *) h->root.u.i.link;              h = (struct elf_link_hash_entry *) h->root.u.i.link;
1339          }          }
1340    
1341          if (h != NULL)
1342            {
1343              /* Create the ifunc sections for static executables.  If we
1344                 never see an indirect function symbol nor we are building
1345                 a static executable, those sections will be empty and
1346                 won't appear in output.  */
1347              switch (r_type)
1348                {
1349                default:
1350                  break;
1351    
1352                case R_386_32:
1353                case R_386_PC32:
1354                case R_386_PLT32:
1355                case R_386_GOT32:
1356                case R_386_GOTOFF:
1357                  if (!_bfd_elf_create_ifunc_sections (abfd, info))
1358                    return FALSE;
1359                  break;
1360                }
1361    
1362              /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
1363                 it here if it is defined in a non-shared object.  */
1364              if (h->type == STT_GNU_IFUNC
1365                  && h->def_regular)
1366                {
1367                  /* It is referenced by a non-shared object. */
1368                  h->ref_regular = 1;
1369                  h->needs_plt = 1;
1370    
1371                  /* STT_GNU_IFUNC symbol must go through PLT.  */
1372                  h->plt.refcount += 1;
1373    
1374                  /* STT_GNU_IFUNC needs dynamic sections.  */
1375                  if (htab->elf.dynobj == NULL)
1376                    htab->elf.dynobj = abfd;
1377    
1378                  switch (r_type)
1379                    {
1380                    default:
1381                      if (h->root.root.string)
1382                        name = h->root.root.string;
1383                      else
1384                        name = bfd_elf_sym_name (abfd, symtab_hdr, isym,
1385                                                 NULL);
1386                      (*_bfd_error_handler)
1387                        (_("%B: relocation %s against STT_GNU_IFUNC "
1388                           "symbol `%s' isn't handled by %s"), abfd,
1389                         elf_howto_table[r_type].name,
1390                         name, __FUNCTION__);
1391                      bfd_set_error (bfd_error_bad_value);
1392                      return FALSE;
1393    
1394                    case R_386_32:
1395                      h->non_got_ref = 1;
1396                      h->pointer_equality_needed = 1;
1397                      if (info->shared)
1398                        {
1399                          /* We must copy these reloc types into the
1400                             output file.  Create a reloc section in
1401                             dynobj and make room for this reloc.  */
1402                          sreloc = _bfd_elf_create_ifunc_dyn_reloc
1403                            (abfd, info, sec, sreloc,
1404                             &((struct elf_i386_link_hash_entry *) h)->dyn_relocs);
1405                          if (sreloc == NULL)
1406                            return FALSE;
1407                        }
1408                      break;
1409    
1410                    case R_386_PC32:
1411                      h->non_got_ref = 1;
1412                      break;
1413    
1414                    case R_386_PLT32:
1415                      break;
1416    
1417                    case R_386_GOT32:
1418                    case R_386_GOTOFF:
1419                      h->got.refcount += 1;
1420                      if (htab->elf.sgot == NULL
1421                          && !_bfd_elf_create_got_section (htab->elf.dynobj,
1422                                                           info))
1423                        return FALSE;
1424                      break;
1425                    }
1426    
1427                  continue;
1428                }
1429            }
1430    
1431        if (! elf_i386_tls_transition (info, abfd, sec, NULL,        if (! elf_i386_tls_transition (info, abfd, sec, NULL,
1432                                       symtab_hdr, sym_hashes,                                       symtab_hdr, sym_hashes,
1433                                       &r_type, GOT_UNKNOWN,                                       &r_type, GOT_UNKNOWN,
1434                                       rel, rel_end, h))                                       rel, rel_end, h, r_symndx))
1435          return FALSE;          return FALSE;
1436    
1437        switch (r_type)        switch (r_type)
# Line 1360  elf_i386_check_relocs (bfd *abfd, Line 1539  elf_i386_check_relocs (bfd *abfd,
1539                    tls_type |= old_tls_type;                    tls_type |= old_tls_type;
1540                  else                  else
1541                    {                    {
1542                        if (h)
1543                          name = h->root.root.string;
1544                        else
1545                          name = bfd_elf_sym_name (abfd, symtab_hdr, isym,
1546                                                 NULL);
1547                      (*_bfd_error_handler)                      (*_bfd_error_handler)
1548                        (_("%B: `%s' accessed both as normal and "                        (_("%B: `%s' accessed both as normal and "
1549                           "thread local symbol"),                           "thread local symbol"),
1550                         abfd,                         abfd, name);
                        h ? h->root.root.string : "<local>");  
1551                      return FALSE;                      return FALSE;
1552                    }                    }
1553                }                }
# Line 1382  elf_i386_check_relocs (bfd *abfd, Line 1565  elf_i386_check_relocs (bfd *abfd,
1565          case R_386_GOTOFF:          case R_386_GOTOFF:
1566          case R_386_GOTPC:          case R_386_GOTPC:
1567          create_got:          create_got:
1568            if (htab->sgot == NULL)            if (htab->elf.sgot == NULL)
1569              {              {
1570                if (htab->elf.dynobj == NULL)                if (htab->elf.dynobj == NULL)
1571                  htab->elf.dynobj = abfd;                  htab->elf.dynobj = abfd;
1572                if (!create_got_section (htab->elf.dynobj, info))                if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
1573                  return FALSE;                  return FALSE;
1574              }              }
1575            if (r_type != R_386_TLS_IE)            if (r_type != R_386_TLS_IE)
# Line 1402  elf_i386_check_relocs (bfd *abfd, Line 1585  elf_i386_check_relocs (bfd *abfd,
1585    
1586          case R_386_32:          case R_386_32:
1587          case R_386_PC32:          case R_386_PC32:
1588            if (h != NULL && !info->shared)            if (h != NULL && info->executable)
1589              {              {
1590                /* If this reloc is in a read-only section, we might                /* If this reloc is in a read-only section, we might
1591                   need a copy reloc.  We can't check reliably at this                   need a copy reloc.  We can't check reliably at this
# Line 1454  elf_i386_check_relocs (bfd *abfd, Line 1637  elf_i386_check_relocs (bfd *abfd,
1637                    && (h->root.type == bfd_link_hash_defweak                    && (h->root.type == bfd_link_hash_defweak
1638                        || !h->def_regular)))                        || !h->def_regular)))
1639              {              {
1640                struct elf_i386_dyn_relocs *p;                struct elf_dyn_relocs *p;
1641                struct elf_i386_dyn_relocs **head;                struct elf_dyn_relocs **head;
1642    
1643                /* We must copy these reloc types into the output file.                /* We must copy these reloc types into the output file.
1644                   Create a reloc section in dynobj and make room for                   Create a reloc section in dynobj and make room for
# Line 1480  elf_i386_check_relocs (bfd *abfd, Line 1663  elf_i386_check_relocs (bfd *abfd,
1663                  }                  }
1664                else                else
1665                  {                  {
                   void **vpp;  
1666                    /* Track dynamic relocs needed for local syms too.                    /* Track dynamic relocs needed for local syms too.
1667                       We really need local syms available to do this                       We really need local syms available to do this
1668                       easily.  Oh well.  */                       easily.  Oh well.  */
1669                      void **vpp;
1670                    asection *s;                    asection *s;
1671                    s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,                    Elf_Internal_Sym *isym;
1672                                                   sec, r_symndx);  
1673                    if (s == NULL)                    isym = bfd_sym_from_r_symndx (&htab->sym_cache,
1674                                                    abfd, r_symndx);
1675                      if (isym == NULL)
1676                      return FALSE;                      return FALSE;
1677    
1678                      s = bfd_section_from_elf_index (abfd, isym->st_shndx);
1679                      if (s == NULL)
1680                        s = sec;
1681    
1682                    vpp = &elf_section_data (s)->local_dynrel;                    vpp = &elf_section_data (s)->local_dynrel;
1683                    head = (struct elf_i386_dyn_relocs **)vpp;                    head = (struct elf_dyn_relocs **)vpp;
1684                  }                  }
1685    
1686                p = *head;                p = *head;
# Line 1593  elf_i386_gc_sweep_hook (bfd *abfd, Line 1781  elf_i386_gc_sweep_hook (bfd *abfd,
1781        if (r_symndx >= symtab_hdr->sh_info)        if (r_symndx >= symtab_hdr->sh_info)
1782          {          {
1783            struct elf_i386_link_hash_entry *eh;            struct elf_i386_link_hash_entry *eh;
1784            struct elf_i386_dyn_relocs **pp;            struct elf_dyn_relocs **pp;
1785            struct elf_i386_dyn_relocs *p;            struct elf_dyn_relocs *p;
1786    
1787            h = sym_hashes[r_symndx - symtab_hdr->sh_info];            h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1788            while (h->root.type == bfd_link_hash_indirect            while (h->root.type == bfd_link_hash_indirect
# Line 1615  elf_i386_gc_sweep_hook (bfd *abfd, Line 1803  elf_i386_gc_sweep_hook (bfd *abfd,
1803        if (! elf_i386_tls_transition (info, abfd, sec, NULL,        if (! elf_i386_tls_transition (info, abfd, sec, NULL,
1804                                       symtab_hdr, sym_hashes,                                       symtab_hdr, sym_hashes,
1805                                       &r_type, GOT_UNKNOWN,                                       &r_type, GOT_UNKNOWN,
1806                                       rel, relend, h))                                       rel, relend, h, r_symndx))
1807          return FALSE;          return FALSE;
1808    
1809        switch (r_type)        switch (r_type)
# Line 1679  elf_i386_adjust_dynamic_symbol (struct b Line 1867  elf_i386_adjust_dynamic_symbol (struct b
1867    struct elf_i386_link_hash_table *htab;    struct elf_i386_link_hash_table *htab;
1868    asection *s;    asection *s;
1869    
1870      /* STT_GNU_IFUNC symbol must go through PLT. */
1871      if (h->type == STT_GNU_IFUNC)
1872        {
1873          if (h->plt.refcount <= 0)
1874            {
1875              h->plt.offset = (bfd_vma) -1;
1876              h->needs_plt = 0;
1877            }
1878          return TRUE;
1879        }
1880    
1881    /* If this is a function, put it in the procedure linkage table.  We    /* If this is a function, put it in the procedure linkage table.  We
1882       will fill in the contents of the procedure linkage table later,       will fill in the contents of the procedure linkage table later,
1883       when we know the address of the .got section.  */       when we know the address of the .got section.  */
# Line 1754  elf_i386_adjust_dynamic_symbol (struct b Line 1953  elf_i386_adjust_dynamic_symbol (struct b
1953    if (ELIMINATE_COPY_RELOCS && !htab->is_vxworks)    if (ELIMINATE_COPY_RELOCS && !htab->is_vxworks)
1954      {      {
1955        struct elf_i386_link_hash_entry * eh;        struct elf_i386_link_hash_entry * eh;
1956        struct elf_i386_dyn_relocs *p;        struct elf_dyn_relocs *p;
1957    
1958        eh = (struct elf_i386_link_hash_entry *) h;        eh = (struct elf_i386_link_hash_entry *) h;
1959        for (p = eh->dyn_relocs; p != NULL; p = p->next)        for (p = eh->dyn_relocs; p != NULL; p = p->next)
# Line 1806  elf_i386_adjust_dynamic_symbol (struct b Line 2005  elf_i386_adjust_dynamic_symbol (struct b
2005     dynamic relocs.  */     dynamic relocs.  */
2006    
2007  static bfd_boolean  static bfd_boolean
2008  allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)  elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
2009  {  {
2010    struct bfd_link_info *info;    struct bfd_link_info *info;
2011    struct elf_i386_link_hash_table *htab;    struct elf_i386_link_hash_table *htab;
2012    struct elf_i386_link_hash_entry *eh;    struct elf_i386_link_hash_entry *eh;
2013    struct elf_i386_dyn_relocs *p;    struct elf_dyn_relocs *p;
2014    
2015    if (h->root.type == bfd_link_hash_indirect)    if (h->root.type == bfd_link_hash_indirect)
2016      return TRUE;      return TRUE;
# Line 1821  allocate_dynrelocs (struct elf_link_hash Line 2020  allocate_dynrelocs (struct elf_link_hash
2020         entry in the hash table, thus we never get to see the real         entry in the hash table, thus we never get to see the real
2021         symbol in a hash traversal.  So look at it now.  */         symbol in a hash traversal.  So look at it now.  */
2022      h = (struct elf_link_hash_entry *) h->root.u.i.link;      h = (struct elf_link_hash_entry *) h->root.u.i.link;
2023      eh = (struct elf_i386_link_hash_entry *) h;
2024    
2025    info = (struct bfd_link_info *) inf;    info = (struct bfd_link_info *) inf;
2026    htab = elf_i386_hash_table (info);    htab = elf_i386_hash_table (info);
2027    
2028    if (htab->elf.dynamic_sections_created    /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
2029        && h->plt.refcount > 0)       here if it is defined and referenced in a non-shared object.  */
2030      if (h->type == STT_GNU_IFUNC
2031          && h->def_regular)
2032        return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
2033                                                   &eh->dyn_relocs,
2034                                                   PLT_ENTRY_SIZE, 4);
2035      else if (htab->elf.dynamic_sections_created
2036               && h->plt.refcount > 0)
2037      {      {
2038        /* Make sure this symbol is output as a dynamic symbol.        /* Make sure this symbol is output as a dynamic symbol.
2039           Undefined weak syms won't yet be marked as dynamic.  */           Undefined weak syms won't yet be marked as dynamic.  */
# Line 1840  allocate_dynrelocs (struct elf_link_hash Line 2047  allocate_dynrelocs (struct elf_link_hash
2047        if (info->shared        if (info->shared
2048            || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))            || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
2049          {          {
2050            asection *s = htab->splt;            asection *s = htab->elf.splt;
2051    
2052            /* If this is the first .plt entry, make room for the special            /* If this is the first .plt entry, make room for the special
2053               first entry.  */               first entry.  */
# Line 1866  allocate_dynrelocs (struct elf_link_hash Line 2073  allocate_dynrelocs (struct elf_link_hash
2073    
2074            /* We also need to make an entry in the .got.plt section, which            /* We also need to make an entry in the .got.plt section, which
2075               will be placed in the .got section by the linker script.  */               will be placed in the .got section by the linker script.  */
2076            htab->sgotplt->size += 4;            htab->elf.sgotplt->size += 4;
2077    
2078            /* We also need to make an entry in the .rel.plt section.  */            /* We also need to make an entry in the .rel.plt section.  */
2079            htab->srelplt->size += sizeof (Elf32_External_Rel);            htab->elf.srelplt->size += sizeof (Elf32_External_Rel);
2080            htab->next_tls_desc_index++;            htab->next_tls_desc_index++;
2081    
2082            if (htab->is_vxworks && !info->shared)            if (htab->is_vxworks && !info->shared)
# Line 1904  allocate_dynrelocs (struct elf_link_hash Line 2111  allocate_dynrelocs (struct elf_link_hash
2111        h->needs_plt = 0;        h->needs_plt = 0;
2112      }      }
2113    
   eh = (struct elf_i386_link_hash_entry *) h;  
2114    eh->tlsdesc_got = (bfd_vma) -1;    eh->tlsdesc_got = (bfd_vma) -1;
2115    
2116    /* If R_386_TLS_{IE_32,IE,GOTIE} symbol is now local to the binary,    /* If R_386_TLS_{IE_32,IE,GOTIE} symbol is now local to the binary,
# Line 1929  allocate_dynrelocs (struct elf_link_hash Line 2135  allocate_dynrelocs (struct elf_link_hash
2135              return FALSE;              return FALSE;
2136          }          }
2137    
2138        s = htab->sgot;        s = htab->elf.sgot;
2139        if (GOT_TLS_GDESC_P (tls_type))        if (GOT_TLS_GDESC_P (tls_type))
2140          {          {
2141            eh->tlsdesc_got = htab->sgotplt->size            eh->tlsdesc_got = htab->elf.sgotplt->size
2142              - elf_i386_compute_jump_table_size (htab);              - elf_i386_compute_jump_table_size (htab);
2143            htab->sgotplt->size += 8;            htab->elf.sgotplt->size += 8;
2144            h->got.offset = (bfd_vma) -2;            h->got.offset = (bfd_vma) -2;
2145          }          }
2146        if (! GOT_TLS_GDESC_P (tls_type)        if (! GOT_TLS_GDESC_P (tls_type)
# Line 1953  allocate_dynrelocs (struct elf_link_hash Line 2159  allocate_dynrelocs (struct elf_link_hash
2159           need two), R_386_TLS_GD needs one if local symbol and two if           need two), R_386_TLS_GD needs one if local symbol and two if
2160           global.  */           global.  */
2161        if (tls_type == GOT_TLS_IE_BOTH)        if (tls_type == GOT_TLS_IE_BOTH)
2162          htab->srelgot->size += 2 * sizeof (Elf32_External_Rel);          htab->elf.srelgot->size += 2 * sizeof (Elf32_External_Rel);
2163        else if ((GOT_TLS_GD_P (tls_type) && h->dynindx == -1)        else if ((GOT_TLS_GD_P (tls_type) && h->dynindx == -1)
2164                 || (tls_type & GOT_TLS_IE))                 || (tls_type & GOT_TLS_IE))
2165          htab->srelgot->size += sizeof (Elf32_External_Rel);          htab->elf.srelgot->size += sizeof (Elf32_External_Rel);
2166        else if (GOT_TLS_GD_P (tls_type))        else if (GOT_TLS_GD_P (tls_type))
2167          htab->srelgot->size += 2 * sizeof (Elf32_External_Rel);          htab->elf.srelgot->size += 2 * sizeof (Elf32_External_Rel);
2168        else if (! GOT_TLS_GDESC_P (tls_type)        else if (! GOT_TLS_GDESC_P (tls_type)
2169                 && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT                 && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
2170                     || h->root.type != bfd_link_hash_undefweak)                     || h->root.type != bfd_link_hash_undefweak)
2171                 && (info->shared                 && (info->shared
2172                     || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))                     || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
2173          htab->srelgot->size += sizeof (Elf32_External_Rel);          htab->elf.srelgot->size += sizeof (Elf32_External_Rel);
2174        if (GOT_TLS_GDESC_P (tls_type))        if (GOT_TLS_GDESC_P (tls_type))
2175          htab->srelplt->size += sizeof (Elf32_External_Rel);          htab->elf.srelplt->size += sizeof (Elf32_External_Rel);
2176      }      }
2177    else    else
2178      h->got.offset = (bfd_vma) -1;      h->got.offset = (bfd_vma) -1;
# Line 1990  allocate_dynrelocs (struct elf_link_hash Line 2196  allocate_dynrelocs (struct elf_link_hash
2196           should avoid writing assembly like ".long foo - .".  */           should avoid writing assembly like ".long foo - .".  */
2197        if (SYMBOL_CALLS_LOCAL (info, h))        if (SYMBOL_CALLS_LOCAL (info, h))
2198          {          {
2199            struct elf_i386_dyn_relocs **pp;            struct elf_dyn_relocs **pp;
2200    
2201            for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )            for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
2202              {              {
# Line 2005  allocate_dynrelocs (struct elf_link_hash Line 2211  allocate_dynrelocs (struct elf_link_hash
2211    
2212        if (htab->is_vxworks)        if (htab->is_vxworks)
2213          {          {
2214            struct elf_i386_dyn_relocs **pp;            struct elf_dyn_relocs **pp;
2215            for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )            for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
2216              {              {
2217                if (strcmp (p->sec->output_section->name, ".tls_vars") == 0)                if (strcmp (p->sec->output_section->name, ".tls_vars") == 0)
# Line 2080  allocate_dynrelocs (struct elf_link_hash Line 2286  allocate_dynrelocs (struct elf_link_hash
2286    return TRUE;    return TRUE;
2287  }  }
2288    
2289    /* Allocate space in .plt, .got and associated reloc sections for
2290       local dynamic relocs.  */
2291    
2292    static bfd_boolean
2293    elf_i386_allocate_local_dynrelocs (void **slot, void *inf)
2294    {
2295      struct elf_link_hash_entry *h
2296        = (struct elf_link_hash_entry *) *slot;
2297    
2298      if (h->type != STT_GNU_IFUNC
2299          || !h->def_regular
2300          || !h->ref_regular
2301          || !h->forced_local
2302          || h->root.type != bfd_link_hash_defined)
2303        abort ();
2304    
2305      return elf_i386_allocate_dynrelocs (h, inf);
2306    }
2307    
2308  /* Find any dynamic relocs that apply to read-only sections.  */  /* Find any dynamic relocs that apply to read-only sections.  */
2309    
2310  static bfd_boolean  static bfd_boolean
2311  readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)  elf_i386_readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
2312  {  {
2313    struct elf_i386_link_hash_entry *eh;    struct elf_i386_link_hash_entry *eh;
2314    struct elf_i386_dyn_relocs *p;    struct elf_dyn_relocs *p;
2315    
2316    if (h->root.type == bfd_link_hash_warning)    if (h->root.type == bfd_link_hash_warning)
2317      h = (struct elf_link_hash_entry *) h->root.u.i.link;      h = (struct elf_link_hash_entry *) h->root.u.i.link;
# Line 2156  elf_i386_size_dynamic_sections (bfd *out Line 2381  elf_i386_size_dynamic_sections (bfd *out
2381    
2382        for (s = ibfd->sections; s != NULL; s = s->next)        for (s = ibfd->sections; s != NULL; s = s->next)
2383          {          {
2384            struct elf_i386_dyn_relocs *p;            struct elf_dyn_relocs *p;
2385    
2386            for (p = ((struct elf_i386_dyn_relocs *)            for (p = ((struct elf_dyn_relocs *)
2387                       elf_section_data (s)->local_dynrel);                       elf_section_data (s)->local_dynrel);
2388                 p != NULL;                 p != NULL;
2389                 p = p->next)                 p = p->next)
# Line 2197  elf_i386_size_dynamic_sections (bfd *out Line 2422  elf_i386_size_dynamic_sections (bfd *out
2422        end_local_got = local_got + locsymcount;        end_local_got = local_got + locsymcount;
2423        local_tls_type = elf_i386_local_got_tls_type (ibfd);        local_tls_type = elf_i386_local_got_tls_type (ibfd);
2424        local_tlsdesc_gotent = elf_i386_local_tlsdesc_gotent (ibfd);        local_tlsdesc_gotent = elf_i386_local_tlsdesc_gotent (ibfd);
2425        s = htab->sgot;        s = htab->elf.sgot;
2426        srel = htab->srelgot;        srel = htab->elf.srelgot;
2427        for (; local_got < end_local_got;        for (; local_got < end_local_got;
2428             ++local_got, ++local_tls_type, ++local_tlsdesc_gotent)             ++local_got, ++local_tls_type, ++local_tlsdesc_gotent)
2429          {          {
# Line 2207  elf_i386_size_dynamic_sections (bfd *out Line 2432  elf_i386_size_dynamic_sections (bfd *out
2432              {              {
2433                if (GOT_TLS_GDESC_P (*local_tls_type))                if (GOT_TLS_GDESC_P (*local_tls_type))
2434                  {                  {
2435                    *local_tlsdesc_gotent = htab->sgotplt->size                    *local_tlsdesc_gotent = htab->elf.sgotplt->size
2436                      - elf_i386_compute_jump_table_size (htab);                      - elf_i386_compute_jump_table_size (htab);
2437                    htab->sgotplt->size += 8;                    htab->elf.sgotplt->size += 8;
2438                    *local_got = (bfd_vma) -2;                    *local_got = (bfd_vma) -2;
2439                  }                  }
2440                if (! GOT_TLS_GDESC_P (*local_tls_type)                if (! GOT_TLS_GDESC_P (*local_tls_type)
# Line 2231  elf_i386_size_dynamic_sections (bfd *out Line 2456  elf_i386_size_dynamic_sections (bfd *out
2456                             || ! GOT_TLS_GDESC_P (*local_tls_type))                             || ! GOT_TLS_GDESC_P (*local_tls_type))
2457                      srel->size += sizeof (Elf32_External_Rel);                      srel->size += sizeof (Elf32_External_Rel);
2458                    if (GOT_TLS_GDESC_P (*local_tls_type))                    if (GOT_TLS_GDESC_P (*local_tls_type))
2459                      htab->srelplt->size += sizeof (Elf32_External_Rel);                      htab->elf.srelplt->size += sizeof (Elf32_External_Rel);
2460                  }                  }
2461              }              }
2462            else            else
# Line 2243  elf_i386_size_dynamic_sections (bfd *out Line 2468  elf_i386_size_dynamic_sections (bfd *out
2468      {      {
2469        /* Allocate 2 got entries and 1 dynamic reloc for R_386_TLS_LDM        /* Allocate 2 got entries and 1 dynamic reloc for R_386_TLS_LDM
2470           relocs.  */           relocs.  */
2471        htab->tls_ldm_got.offset = htab->sgot->size;        htab->tls_ldm_got.offset = htab->elf.sgot->size;
2472        htab->sgot->size += 8;        htab->elf.sgot->size += 8;
2473        htab->srelgot->size += sizeof (Elf32_External_Rel);        htab->elf.srelgot->size += sizeof (Elf32_External_Rel);
2474      }      }
2475    else    else
2476      htab->tls_ldm_got.offset = -1;      htab->tls_ldm_got.offset = -1;
2477    
2478    /* Allocate global sym .plt and .got entries, and space for global    /* Allocate global sym .plt and .got entries, and space for global
2479       sym dynamic relocs.  */       sym dynamic relocs.  */
2480    elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);    elf_link_hash_traverse (&htab->elf, elf_i386_allocate_dynrelocs, info);
2481    
2482      /* Allocate .plt and .got entries, and space for local symbols.  */
2483      htab_traverse (htab->loc_hash_table,
2484                     elf_i386_allocate_local_dynrelocs,
2485                     info);
2486    
2487    /* For every jump slot reserved in the sgotplt, reloc_count is    /* For every jump slot reserved in the sgotplt, reloc_count is
2488       incremented.  However, when we reserve space for TLS descriptors,       incremented.  However, when we reserve space for TLS descriptors,
2489       it's not incremented, so in order to compute the space reserved       it's not incremented, so in order to compute the space reserved
2490       for them, it suffices to multiply the reloc count by the jump       for them, it suffices to multiply the reloc count by the jump
2491       slot size.  */       slot size.  */
2492    if (htab->srelplt)    if (htab->elf.srelplt)
2493      htab->sgotplt_jump_table_size = htab->next_tls_desc_index * 4;      htab->sgotplt_jump_table_size = htab->next_tls_desc_index * 4;
2494    
2495    /* We now have determined the sizes of the various dynamic sections.    /* We now have determined the sizes of the various dynamic sections.
# Line 2272  elf_i386_size_dynamic_sections (bfd *out Line 2502  elf_i386_size_dynamic_sections (bfd *out
2502        if ((s->flags & SEC_LINKER_CREATED) == 0)        if ((s->flags & SEC_LINKER_CREATED) == 0)
2503          continue;          continue;
2504    
2505        if (s == htab->splt        if (s == htab->elf.splt
2506            || s == htab->sgot            || s == htab->elf.sgot
2507            || s == htab->sgotplt            || s == htab->elf.sgotplt
2508              || s == htab->elf.iplt
2509              || s == htab->elf.igotplt
2510            || s == htab->sdynbss)            || s == htab->sdynbss)
2511          {          {
2512            /* Strip this section if we don't need it; see the            /* Strip this section if we don't need it; see the
# Line 2288  elf_i386_size_dynamic_sections (bfd *out Line 2520  elf_i386_size_dynamic_sections (bfd *out
2520          }          }
2521        else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rel"))        else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rel"))
2522          {          {
2523            if (s->size != 0 && s != htab->srelplt && s != htab->srelplt2)            if (s->size != 0
2524                  && s != htab->elf.srelplt
2525                  && s != htab->srelplt2)
2526              relocs = TRUE;              relocs = TRUE;
2527    
2528            /* We use the reloc_count field as a counter if we need            /* We use the reloc_count field as a counter if we need
# Line 2346  elf_i386_size_dynamic_sections (bfd *out Line 2580  elf_i386_size_dynamic_sections (bfd *out
2580              return FALSE;              return FALSE;
2581          }          }
2582    
2583        if (htab->splt->size != 0)        if (htab->elf.splt->size != 0)
2584          {          {
2585            if (!add_dynamic_entry (DT_PLTGOT, 0)            if (!add_dynamic_entry (DT_PLTGOT, 0)
2586                || !add_dynamic_entry (DT_PLTRELSZ, 0)                || !add_dynamic_entry (DT_PLTRELSZ, 0)
# Line 2365  elf_i386_size_dynamic_sections (bfd *out Line 2599  elf_i386_size_dynamic_sections (bfd *out
2599            /* If any dynamic relocs apply to a read-only section,            /* If any dynamic relocs apply to a read-only section,
2600               then we need a DT_TEXTREL entry.  */               then we need a DT_TEXTREL entry.  */
2601            if ((info->flags & DF_TEXTREL) == 0)            if ((info->flags & DF_TEXTREL) == 0)
2602              elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, info);              elf_link_hash_traverse (&htab->elf,
2603                                        elf_i386_readonly_dynrelocs, info);
2604    
2605            if ((info->flags & DF_TEXTREL) != 0)            if ((info->flags & DF_TEXTREL) != 0)
2606              {              {
# Line 2460  elf_i386_fake_sections (bfd *abfd ATTRIB Line 2695  elf_i386_fake_sections (bfd *abfd ATTRIB
2695     multiple times, it is idempotent.  */     multiple times, it is idempotent.  */
2696    
2697  static void  static void
2698  set_tls_module_base (struct bfd_link_info *info)  elf_i386_set_tls_module_base (struct bfd_link_info *info)
2699  {  {
2700    struct bfd_link_hash_entry *base;    struct bfd_link_hash_entry *base;
2701    
# Line 2480  set_tls_module_base (struct bfd_link_inf Line 2715  set_tls_module_base (struct bfd_link_inf
2715     This is PT_TLS segment p_vaddr.  */     This is PT_TLS segment p_vaddr.  */
2716    
2717  static bfd_vma  static bfd_vma
2718  dtpoff_base (struct bfd_link_info *info)  elf_i386_dtpoff_base (struct bfd_link_info *info)
2719  {  {
2720    /* If tls_sec is NULL, we should have signalled an error already.  */    /* If tls_sec is NULL, we should have signalled an error already.  */
2721    if (elf_hash_table (info)->tls_sec == NULL)    if (elf_hash_table (info)->tls_sec == NULL)
# Line 2492  dtpoff_base (struct bfd_link_info *info) Line 2727  dtpoff_base (struct bfd_link_info *info)
2727     if STT_TLS virtual address is ADDRESS.  */     if STT_TLS virtual address is ADDRESS.  */
2728    
2729  static bfd_vma  static bfd_vma
2730  tpoff (struct bfd_link_info *info, bfd_vma address)  elf_i386_tpoff (struct bfd_link_info *info, bfd_vma address)
2731  {  {
2732    struct elf_link_hash_table *htab = elf_hash_table (info);    struct elf_link_hash_table *htab = elf_hash_table (info);
2733    
# Line 2536  elf_i386_relocate_section (bfd *output_b Line 2771  elf_i386_relocate_section (bfd *output_b
2771                      && !strcmp (input_section->output_section->name,                      && !strcmp (input_section->output_section->name,
2772                                  ".tls_vars"));                                  ".tls_vars"));
2773    
2774    set_tls_module_base (info);    elf_i386_set_tls_module_base (info);
2775    
2776    rel = relocs;    rel = relocs;
2777    relend = relocs + input_section->reloc_count;    relend = relocs + input_section->reloc_count;
# Line 2564  elf_i386_relocate_section (bfd *output_b Line 2799  elf_i386_relocate_section (bfd *output_b
2799            && ((indx = r_type - R_386_ext_offset) - R_386_standard            && ((indx = r_type - R_386_ext_offset) - R_386_standard
2800                >= R_386_ext - R_386_standard)                >= R_386_ext - R_386_standard)
2801            && ((indx = r_type - R_386_tls_offset) - R_386_ext            && ((indx = r_type - R_386_tls_offset) - R_386_ext
2802                >= R_386_tls - R_386_ext))                >= R_386_irelative - R_386_ext))
2803          {          {
2804            (*_bfd_error_handler)            (*_bfd_error_handler)
2805              (_("%B: unrecognized relocation (0x%x) in section `%A'"),              (_("%B: unrecognized relocation (0x%x) in section `%A'"),
# Line 2656  elf_i386_relocate_section (bfd *output_b Line 2891  elf_i386_relocate_section (bfd *output_b
2891                    break;                    break;
2892                  }                  }
2893              }              }
2894              else if (!info->relocatable
2895                       && ELF32_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
2896                {
2897                  /* Relocate against local STT_GNU_IFUNC symbol.  */
2898                  h = elf_i386_get_local_sym_hash (htab, input_bfd,
2899                                                       rel, FALSE);
2900                  if (h == NULL)
2901                    abort ();
2902    
2903                  /* Set STT_GNU_IFUNC symbol value.  */
2904                  h->root.u.def.value = sym->st_value;
2905                  h->root.u.def.section = sec;
2906                }
2907          }          }
2908        else        else
2909          {          {
# Line 2681  elf_i386_relocate_section (bfd *output_b Line 2929  elf_i386_relocate_section (bfd *output_b
2929        if (info->relocatable)        if (info->relocatable)
2930          continue;          continue;
2931    
2932          /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
2933             it here if it is defined in a non-shared object.  */
2934          if (h != NULL
2935              && h->type == STT_GNU_IFUNC
2936              && h->def_regular)
2937            {
2938              asection *plt, *gotplt, *base_got;
2939              bfd_vma plt_index;
2940              const char *name;
2941    
2942              if ((input_section->flags & SEC_ALLOC) == 0
2943                  || h->plt.offset == (bfd_vma) -1)
2944                abort ();
2945    
2946              /* STT_GNU_IFUNC symbol must go through PLT.  */
2947              if (htab->elf.splt != NULL)
2948                {
2949                  plt = htab->elf.splt;
2950                  gotplt = htab->elf.sgotplt;
2951                }
2952              else
2953                {
2954                  plt = htab->elf.iplt;
2955                  gotplt = htab->elf.igotplt;
2956                }
2957    
2958              relocation = (plt->output_section->vma
2959                            + plt->output_offset + h->plt.offset);
2960    
2961              switch (r_type)
2962                {
2963                default:
2964                  if (h->root.root.string)
2965                    name = h->root.root.string;
2966                  else
2967                    name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
2968                                             NULL);
2969                  (*_bfd_error_handler)
2970                    (_("%B: relocation %s against STT_GNU_IFUNC "
2971                       "symbol `%s' isn't handled by %s"), input_bfd,
2972                     elf_howto_table[r_type].name,
2973                     name, __FUNCTION__);
2974                  bfd_set_error (bfd_error_bad_value);
2975                  return FALSE;
2976    
2977                case R_386_32:
2978                  /* Generate dynamic relcoation only when there is a
2979                     non-GOF reference in a shared object.  */
2980                  if (info->shared && h->non_got_ref)
2981                    {
2982                      Elf_Internal_Rela outrel;
2983                      bfd_byte *loc;
2984                      asection *sreloc;
2985                      bfd_vma offset;
2986    
2987                      /* Need a dynamic relocation to get the real function
2988                         adddress.  */
2989                      offset = _bfd_elf_section_offset (output_bfd,
2990                                                        info,
2991                                                        input_section,
2992                                                        rel->r_offset);
2993                      if (offset == (bfd_vma) -1
2994                          || offset == (bfd_vma) -2)
2995                        abort ();
2996    
2997                      outrel.r_offset = (input_section->output_section->vma
2998                                         + input_section->output_offset
2999                                         + offset);
3000    
3001                      if (h->dynindx == -1
3002                          || h->forced_local
3003                          || info->executable)
3004                        {
3005                          /* This symbol is resolved locally.  */
3006                          outrel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE);
3007                          bfd_put_32 (output_bfd,
3008                                      (h->root.u.def.value
3009                                       + h->root.u.def.section->output_section->vma
3010                                       + h->root.u.def.section->output_offset),
3011                                      contents + offset);
3012                        }
3013                      else
3014                        outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
3015    
3016                      sreloc = htab->elf.irelifunc;
3017                      loc = sreloc->contents;
3018                      loc += (sreloc->reloc_count++
3019                              * sizeof (Elf32_External_Rel));
3020                      bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
3021    
3022                      /* If this reloc is against an external symbol, we
3023                         do not want to fiddle with the addend.  Otherwise,
3024                         we need to include the symbol value so that it
3025                         becomes an addend for the dynamic reloc.  For an
3026                         internal symbol, we have updated addend.  */
3027                      continue;
3028                    }
3029    
3030                case R_386_PC32:
3031                case R_386_PLT32:
3032                  goto do_relocation;
3033    
3034                case R_386_GOT32:
3035                  base_got = htab->elf.sgot;
3036                  off = h->got.offset;
3037    
3038                  if (base_got == NULL)
3039                    abort ();
3040    
3041                  if (off == (bfd_vma) -1)
3042                    {
3043                      /* We can't use h->got.offset here to save state, or
3044                         even just remember the offset, as finish_dynamic_symbol
3045                         would use that as offset into .got.  */
3046                      
3047                      if (htab->elf.splt != NULL)
3048                        {
3049                          plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
3050                          off = (plt_index + 3) * 4;
3051                          base_got = htab->elf.sgotplt;
3052                        }
3053                      else
3054                        {
3055                          plt_index = h->plt.offset / PLT_ENTRY_SIZE;
3056                          off = plt_index * 4;
3057                          base_got = htab->elf.igotplt;
3058                        }
3059    
3060                      if (h->dynindx == -1
3061                          || h->forced_local
3062                          || info->symbolic)
3063                        {
3064                          /* This references the local defitionion.  We must
3065                             initialize this entry in the global offset table.
3066                             Since the offset must always be a multiple of 8,
3067                             we use the least significant bit to record
3068                             whether we have initialized it already.
3069    
3070                             When doing a dynamic link, we create a .rela.got
3071                             relocation entry to initialize the value.  This
3072                             is done in the finish_dynamic_symbol routine.   */
3073                          if ((off & 1) != 0)
3074                            off &= ~1;
3075                          else
3076                            {
3077                              bfd_put_32 (output_bfd, relocation,
3078                                          base_got->contents + off);
3079                              h->got.offset |= 1;
3080                            }
3081                        }
3082    
3083                      relocation = off;
3084    
3085                      /* Adjust for static executables.  */
3086                      if (htab->elf.splt == NULL)
3087                        relocation += gotplt->output_offset;
3088                    }
3089                  else
3090                    {
3091                      relocation = (base_got->output_section->vma
3092                                    + base_got->output_offset + off
3093                                    - gotplt->output_section->vma
3094                                    - gotplt->output_offset);
3095                      /* Adjust for static executables.  */
3096                      if (htab->elf.splt == NULL)
3097                        relocation += gotplt->output_offset;
3098                    }
3099    
3100                  goto do_relocation;
3101    
3102                case R_386_GOTOFF:
3103                  relocation -= (gotplt->output_section->vma
3104                                 + gotplt->output_offset);
3105                  goto do_relocation;
3106                }
3107            }
3108    
3109        switch (r_type)        switch (r_type)
3110          {          {
3111          case R_386_GOT32:          case R_386_GOT32:
3112            /* Relocation is to the entry for this symbol in the global            /* Relocation is to the entry for this symbol in the global
3113               offset table.  */               offset table.  */
3114            if (htab->sgot == NULL)            if (htab->elf.sgot == NULL)
3115              abort ();              abort ();
3116    
3117            if (h != NULL)            if (h != NULL)
# Line 2718  elf_i386_relocate_section (bfd *output_b Line 3143  elf_i386_relocate_section (bfd *output_b
3143                    else                    else
3144                      {                      {
3145                        bfd_put_32 (output_bfd, relocation,                        bfd_put_32 (output_bfd, relocation,
3146                                    htab->sgot->contents + off);                                    htab->elf.sgot->contents + off);
3147                        h->got.offset |= 1;                        h->got.offset |= 1;
3148                      }                      }
3149                  }                  }
# Line 2740  elf_i386_relocate_section (bfd *output_b Line 3165  elf_i386_relocate_section (bfd *output_b
3165                else                else
3166                  {                  {
3167                    bfd_put_32 (output_bfd, relocation,                    bfd_put_32 (output_bfd, relocation,
3168                                htab->sgot->contents + off);                                htab->elf.sgot->contents + off);
3169    
3170                    if (info->shared)                    if (info->shared)
3171                      {                      {
# Line 2748  elf_i386_relocate_section (bfd *output_b Line 3173  elf_i386_relocate_section (bfd *output_b
3173                        Elf_Internal_Rela outrel;                        Elf_Internal_Rela outrel;
3174                        bfd_byte *loc;                        bfd_byte *loc;
3175    
3176                        s = htab->srelgot;                        s = htab->elf.srelgot;
3177                        if (s == NULL)                        if (s == NULL)
3178                          abort ();                          abort ();
3179    
3180                        outrel.r_offset = (htab->sgot->output_section->vma                        outrel.r_offset = (htab->elf.sgot->output_section->vma
3181                                           + htab->sgot->output_offset                                           + htab->elf.sgot->output_offset
3182                                           + off);                                           + off);
3183                        outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);                        outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
3184                        loc = s->contents;                        loc = s->contents;
# Line 2768  elf_i386_relocate_section (bfd *output_b Line 3193  elf_i386_relocate_section (bfd *output_b
3193            if (off >= (bfd_vma) -2)            if (off >= (bfd_vma) -2)
3194              abort ();              abort ();
3195    
3196            relocation = htab->sgot->output_section->vma            relocation = htab->elf.sgot->output_section->vma
3197                         + htab->sgot->output_offset + off                         + htab->elf.sgot->output_offset + off
3198                         - htab->sgotplt->output_section->vma                         - htab->elf.sgotplt->output_section->vma
3199                         - htab->sgotplt->output_offset;                         - htab->elf.sgotplt->output_offset;
3200            break;            break;
3201    
3202          case R_386_GOTOFF:          case R_386_GOTOFF:
# Line 2827  elf_i386_relocate_section (bfd *output_b Line 3252  elf_i386_relocate_section (bfd *output_b
3252               defined _GLOBAL_OFFSET_TABLE_ in a different way, as is               defined _GLOBAL_OFFSET_TABLE_ in a different way, as is
3253               permitted by the ABI, we might have to change this               permitted by the ABI, we might have to change this
3254               calculation.  */               calculation.  */
3255            relocation -= htab->sgotplt->output_section->vma            relocation -= htab->elf.sgotplt->output_section->vma
3256                          + htab->sgotplt->output_offset;                          + htab->elf.sgotplt->output_offset;
3257            break;            break;
3258    
3259          case R_386_GOTPC:          case R_386_GOTPC:
3260            /* Use global offset table as symbol value.  */            /* Use global offset table as symbol value.  */
3261            relocation = htab->sgotplt->output_section->vma            relocation = htab->elf.sgotplt->output_section->vma
3262                         + htab->sgotplt->output_offset;                         + htab->elf.sgotplt->output_offset;
3263            unresolved_reloc = FALSE;            unresolved_reloc = FALSE;
3264            break;            break;
3265    
# Line 2848  elf_i386_relocate_section (bfd *output_b Line 3273  elf_i386_relocate_section (bfd *output_b
3273              break;              break;
3274    
3275            if (h->plt.offset == (bfd_vma) -1            if (h->plt.offset == (bfd_vma) -1
3276                || htab->splt == NULL)                || htab->elf.splt == NULL)
3277              {              {
3278                /* We didn't make a PLT entry for this symbol.  This                /* We didn't make a PLT entry for this symbol.  This
3279                   happens when statically linking PIC code, or when                   happens when statically linking PIC code, or when
# Line 2856  elf_i386_relocate_section (bfd *output_b Line 3281  elf_i386_relocate_section (bfd *output_b
3281                break;                break;
3282              }              }
3283    
3284            relocation = (htab->splt->output_section->vma            relocation = (htab->elf.splt->output_section->vma
3285                          + htab->splt->output_offset                          + htab->elf.splt->output_offset
3286                          + h->plt.offset);                          + h->plt.offset);
3287            unresolved_reloc = FALSE;            unresolved_reloc = FALSE;
3288            break;            break;
# Line 2977  elf_i386_relocate_section (bfd *output_b Line 3402  elf_i386_relocate_section (bfd *output_b
3402                                           input_section, contents,                                           input_section, contents,
3403                                           symtab_hdr, sym_hashes,                                           symtab_hdr, sym_hashes,
3404                                           &r_type, tls_type, rel,                                           &r_type, tls_type, rel,
3405                                           relend, h))                                           relend, h, r_symndx))
3406              return FALSE;              return FALSE;
3407    
3408            if (r_type == R_386_TLS_LE_32)            if (r_type == R_386_TLS_LE_32)
# Line 3010  elf_i386_relocate_section (bfd *output_b Line 3435  elf_i386_relocate_section (bfd *output_b
3435                                "\x65\xa1\0\0\0\0\x81\xe8\0\0\0", 12);                                "\x65\xa1\0\0\0\0\x81\xe8\0\0\0", 12);
3436                        roff = rel->r_offset + 6;                        roff = rel->r_offset + 6;
3437                      }                      }
3438                    bfd_put_32 (output_bfd, tpoff (info, relocation),                    bfd_put_32 (output_bfd, elf_i386_tpoff (info, relocation),
3439                                contents + roff);                                contents + roff);
3440                    /* Skip R_386_PC32/R_386_PLT32.  */                    /* Skip R_386_PC32/R_386_PLT32.  */
3441                    rel++;                    rel++;
# Line 3037  elf_i386_relocate_section (bfd *output_b Line 3462  elf_i386_relocate_section (bfd *output_b
3462                       below with 0x86.  */                       below with 0x86.  */
3463                    bfd_put_8 (output_bfd, val ^ 0x86,                    bfd_put_8 (output_bfd, val ^ 0x86,
3464                               contents + roff - 1);                               contents + roff - 1);
3465                    bfd_put_32 (output_bfd, -tpoff (info, relocation),                    bfd_put_32 (output_bfd, -elf_i386_tpoff (info, relocation),
3466                                contents + roff);                                contents + roff);
3467                    continue;                    continue;
3468                  }                  }
# Line 3105  elf_i386_relocate_section (bfd *output_b Line 3530  elf_i386_relocate_section (bfd *output_b
3530                            break;                            break;
3531                          }                          }
3532                      }                      }
3533                    bfd_put_32 (output_bfd, -tpoff (info, relocation),                    bfd_put_32 (output_bfd, -elf_i386_tpoff (info, relocation),
3534                                contents + rel->r_offset);                                contents + rel->r_offset);
3535                    continue;                    continue;
3536                  }                  }
# Line 3151  elf_i386_relocate_section (bfd *output_b Line 3576  elf_i386_relocate_section (bfd *output_b
3576                    else                    else
3577                      BFD_FAIL ();                      BFD_FAIL ();
3578                    if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTIE)                    if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTIE)
3579                      bfd_put_32 (output_bfd, -tpoff (info, relocation),                      bfd_put_32 (output_bfd, -elf_i386_tpoff (info, relocation),
3580                                  contents + rel->r_offset);                                  contents + rel->r_offset);
3581                    else                    else
3582                      bfd_put_32 (output_bfd, tpoff (info, relocation),                      bfd_put_32 (output_bfd, elf_i386_tpoff (info, relocation),
3583                                  contents + rel->r_offset);                                  contents + rel->r_offset);
3584                    continue;                    continue;
3585                  }                  }
3586              }              }
3587    
3588            if (htab->sgot == NULL)            if (htab->elf.sgot == NULL)
3589              abort ();              abort ();
3590    
3591            if (h != NULL)            if (h != NULL)
# Line 3186  elf_i386_relocate_section (bfd *output_b Line 3611  elf_i386_relocate_section (bfd *output_b
3611                int dr_type, indx;                int dr_type, indx;
3612                asection *sreloc;                asection *sreloc;
3613    
3614                if (htab->srelgot == NULL)                if (htab->elf.srelgot == NULL)
3615                  abort ();                  abort ();
3616    
3617                indx = h && h->dynindx != -1 ? h->dynindx : 0;                indx = h && h->dynindx != -1 ? h->dynindx : 0;
# Line 3195  elf_i386_relocate_section (bfd *output_b Line 3620  elf_i386_relocate_section (bfd *output_b
3620                  {                  {
3621                    outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_DESC);                    outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_DESC);
3622                    BFD_ASSERT (htab->sgotplt_jump_table_size + offplt + 8                    BFD_ASSERT (htab->sgotplt_jump_table_size + offplt + 8
3623                                <= htab->sgotplt->size);                                <= htab->elf.sgotplt->size);
3624                    outrel.r_offset = (htab->sgotplt->output_section->vma                    outrel.r_offset = (htab->elf.sgotplt->output_section->vma
3625                                       + htab->sgotplt->output_offset                                       + htab->elf.sgotplt->output_offset
3626                                       + offplt                                       + offplt
3627                                       + htab->sgotplt_jump_table_size);                                       + htab->sgotplt_jump_table_size);
3628                    sreloc = htab->srelplt;                    sreloc = htab->elf.srelplt;
3629                    loc = sreloc->contents;                    loc = sreloc->contents;
3630                    loc += (htab->next_tls_desc_index++                    loc += (htab->next_tls_desc_index++
3631                            * sizeof (Elf32_External_Rel));                            * sizeof (Elf32_External_Rel));
# Line 3211  elf_i386_relocate_section (bfd *output_b Line 3636  elf_i386_relocate_section (bfd *output_b
3636                      {                      {
3637                        BFD_ASSERT (! unresolved_reloc);                        BFD_ASSERT (! unresolved_reloc);
3638                        bfd_put_32 (output_bfd,                        bfd_put_32 (output_bfd,
3639                                    relocation - dtpoff_base (info),                                    relocation - elf_i386_dtpoff_base (info),
3640                                    htab->sgotplt->contents + offplt                                    htab->elf.sgotplt->contents + offplt
3641                                    + htab->sgotplt_jump_table_size + 4);                                    + htab->sgotplt_jump_table_size + 4);
3642                      }                      }
3643                    else                    else
3644                      {                      {
3645                        bfd_put_32 (output_bfd, 0,                        bfd_put_32 (output_bfd, 0,
3646                                    htab->sgotplt->contents + offplt                                    htab->elf.sgotplt->contents + offplt
3647                                    + htab->sgotplt_jump_table_size + 4);                                    + htab->sgotplt_jump_table_size + 4);
3648                      }                      }
3649                  }                  }
3650    
3651                sreloc = htab->srelgot;                sreloc = htab->elf.srelgot;
3652    
3653                outrel.r_offset = (htab->sgot->output_section->vma                outrel.r_offset = (htab->elf.sgot->output_section->vma
3654                                   + htab->sgot->output_offset + off);                                   + htab->elf.sgot->output_offset + off);
3655    
3656                if (GOT_TLS_GD_P (tls_type))                if (GOT_TLS_GD_P (tls_type))
3657                  dr_type = R_386_TLS_DTPMOD32;                  dr_type = R_386_TLS_DTPMOD32;
# Line 3238  elf_i386_relocate_section (bfd *output_b Line 3663  elf_i386_relocate_section (bfd *output_b
3663                  dr_type = R_386_TLS_TPOFF32;                  dr_type = R_386_TLS_TPOFF32;
3664    
3665                if (dr_type == R_386_TLS_TPOFF && indx == 0)                if (dr_type == R_386_TLS_TPOFF && indx == 0)
3666                  bfd_put_32 (output_bfd, relocation - dtpoff_base (info),                  bfd_put_32 (output_bfd,
3667                              htab->sgot->contents + off);                              relocation - elf_i386_dtpoff_base (info),
3668                                htab->elf.sgot->contents + off);
3669                else if (dr_type == R_386_TLS_TPOFF32 && indx == 0)                else if (dr_type == R_386_TLS_TPOFF32 && indx == 0)
3670                  bfd_put_32 (output_bfd, dtpoff_base (info) - relocation,                  bfd_put_32 (output_bfd,
3671                              htab->sgot->contents + off);                              elf_i386_dtpoff_base (info) - relocation,
3672                                htab->elf.sgot->contents + off);
3673                else if (dr_type != R_386_TLS_DESC)                else if (dr_type != R_386_TLS_DESC)
3674                  bfd_put_32 (output_bfd, 0,                  bfd_put_32 (output_bfd, 0,
3675                              htab->sgot->contents + off);                              htab->elf.sgot->contents + off);
3676                outrel.r_info = ELF32_R_INFO (indx, dr_type);                outrel.r_info = ELF32_R_INFO (indx, dr_type);
3677    
3678                loc = sreloc->contents;                loc = sreloc->contents;
# Line 3260  elf_i386_relocate_section (bfd *output_b Line 3687  elf_i386_relocate_section (bfd *output_b
3687                      {                      {
3688                        BFD_ASSERT (! unresolved_reloc);                        BFD_ASSERT (! unresolved_reloc);
3689                        bfd_put_32 (output_bfd,                        bfd_put_32 (output_bfd,
3690                                    relocation - dtpoff_base (info),                                    relocation - elf_i386_dtpoff_base (info),
3691                                    htab->sgot->contents + off + 4);                                    htab->elf.sgot->contents + off + 4);
3692                      }                      }
3693                    else                    else
3694                      {                      {
3695                        bfd_put_32 (output_bfd, 0,                        bfd_put_32 (output_bfd, 0,
3696                                    htab->sgot->contents + off + 4);                                    htab->elf.sgot->contents + off + 4);
3697                        outrel.r_info = ELF32_R_INFO (indx,                        outrel.r_info = ELF32_R_INFO (indx,
3698                                                      R_386_TLS_DTPOFF32);                                                      R_386_TLS_DTPOFF32);
3699                        outrel.r_offset += 4;                        outrel.r_offset += 4;
# Line 3280  elf_i386_relocate_section (bfd *output_b Line 3707  elf_i386_relocate_section (bfd *output_b
3707                else if (tls_type == GOT_TLS_IE_BOTH)                else if (tls_type == GOT_TLS_IE_BOTH)
3708                  {                  {
3709                    bfd_put_32 (output_bfd,                    bfd_put_32 (output_bfd,
3710                                indx == 0 ? relocation - dtpoff_base (info) : 0,                                (indx == 0
3711                                htab->sgot->contents + off + 4);                                 ? relocation - elf_i386_dtpoff_base (info)
3712                                   : 0),
3713                                  htab->elf.sgot->contents + off + 4);
3714                    outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF);                    outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF);
3715                    outrel.r_offset += 4;                    outrel.r_offset += 4;
3716                    sreloc->reloc_count++;                    sreloc->reloc_count++;
# Line 3307  elf_i386_relocate_section (bfd *output_b Line 3736  elf_i386_relocate_section (bfd *output_b
3736              }              }
3737            else if (r_type == ELF32_R_TYPE (rel->r_info))            else if (r_type == ELF32_R_TYPE (rel->r_info))
3738              {              {
3739                bfd_vma g_o_t = htab->sgotplt->output_section->vma                bfd_vma g_o_t = htab->elf.sgotplt->output_section->vma
3740                                + htab->sgotplt->output_offset;                                + htab->elf.sgotplt->output_offset;
3741                relocation = htab->sgot->output_section->vma                relocation = htab->elf.sgot->output_section->vma
3742                  + htab->sgot->output_offset + off - g_o_t;                  + htab->elf.sgot->output_offset + off - g_o_t;
3743                if ((r_type == R_386_TLS_IE || r_type == R_386_TLS_GOTIE)                if ((r_type == R_386_TLS_IE || r_type == R_386_TLS_GOTIE)
3744                    && tls_type == GOT_TLS_IE_BOTH)                    && tls_type == GOT_TLS_IE_BOTH)
3745                  relocation += 4;                  relocation += 4;
# Line 3352  elf_i386_relocate_section (bfd *output_b Line 3781  elf_i386_relocate_section (bfd *output_b
3781                if (tls_type == GOT_TLS_IE_POS)                if (tls_type == GOT_TLS_IE_POS)
3782                  contents[roff + 6] = 0x03;                  contents[roff + 6] = 0x03;
3783                bfd_put_32 (output_bfd,                bfd_put_32 (output_bfd,
3784                            htab->sgot->output_section->vma                            htab->elf.sgot->output_section->vma
3785                            + htab->sgot->output_offset + off                            + htab->elf.sgot->output_offset + off
3786                            - htab->sgotplt->output_section->vma                            - htab->elf.sgotplt->output_section->vma
3787                            - htab->sgotplt->output_offset,                            - htab->elf.sgotplt->output_offset,
3788                            contents + roff + 8);                            contents + roff + 8);
3789                /* Skip R_386_PLT32.  */                /* Skip R_386_PLT32.  */
3790                rel++;                rel++;
# Line 3393  elf_i386_relocate_section (bfd *output_b Line 3822  elf_i386_relocate_section (bfd *output_b
3822                  off += 4;                  off += 4;
3823    
3824                bfd_put_32 (output_bfd,                bfd_put_32 (output_bfd,
3825                            htab->sgot->output_section->vma                            htab->elf.sgot->output_section->vma
3826                            + htab->sgot->output_offset + off                            + htab->elf.sgot->output_offset + off
3827                            - htab->sgotplt->output_section->vma                            - htab->elf.sgotplt->output_section->vma
3828                            - htab->sgotplt->output_offset,                            - htab->elf.sgotplt->output_offset,
3829                            contents + roff);                            contents + roff);
3830                continue;                continue;
3831              }              }
# Line 3442  elf_i386_relocate_section (bfd *output_b Line 3871  elf_i386_relocate_section (bfd *output_b
3871                                           input_section, contents,                                           input_section, contents,
3872                                           symtab_hdr, sym_hashes,                                           symtab_hdr, sym_hashes,
3873                                           &r_type, GOT_UNKNOWN, rel,                                           &r_type, GOT_UNKNOWN, rel,
3874                                           relend, h))                                           relend, h, r_symndx))
3875              return FALSE;              return FALSE;
3876    
3877            if (r_type != R_386_TLS_LDM)            if (r_type != R_386_TLS_LDM)
# Line 3459  elf_i386_relocate_section (bfd *output_b Line 3888  elf_i386_relocate_section (bfd *output_b
3888                continue;                continue;
3889              }              }
3890    
3891            if (htab->sgot == NULL)            if (htab->elf.sgot == NULL)
3892              abort ();              abort ();
3893    
3894            off = htab->tls_ldm_got.offset;            off = htab->tls_ldm_got.offset;
# Line 3470  elf_i386_relocate_section (bfd *output_b Line 3899  elf_i386_relocate_section (bfd *output_b
3899                Elf_Internal_Rela outrel;                Elf_Internal_Rela outrel;
3900                bfd_byte *loc;                bfd_byte *loc;
3901    
3902                if (htab->srelgot == NULL)                if (htab->elf.srelgot == NULL)
3903                  abort ();                  abort ();
3904    
3905                outrel.r_offset = (htab->sgot->output_section->vma                outrel.r_offset = (htab->elf.sgot->output_section->vma
3906                                   + htab->sgot->output_offset + off);                                   + htab->elf.sgot->output_offset + off);
3907    
3908                bfd_put_32 (output_bfd, 0,                bfd_put_32 (output_bfd, 0,
3909                            htab->sgot->contents + off);                            htab->elf.sgot->contents + off);
3910                bfd_put_32 (output_bfd, 0,                bfd_put_32 (output_bfd, 0,
3911                            htab->sgot->contents + off + 4);                            htab->elf.sgot->contents + off + 4);
3912                outrel.r_info = ELF32_R_INFO (0, R_386_TLS_DTPMOD32);                outrel.r_info = ELF32_R_INFO (0, R_386_TLS_DTPMOD32);
3913                loc = htab->srelgot->contents;                loc = htab->elf.srelgot->contents;
3914                loc += htab->srelgot->reloc_count++ * sizeof (Elf32_External_Rel);                loc += htab->elf.srelgot->reloc_count++ * sizeof (Elf32_External_Rel);
3915                bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);                bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
3916                htab->tls_ldm_got.offset |= 1;                htab->tls_ldm_got.offset |= 1;
3917              }              }
3918            relocation = htab->sgot->output_section->vma            relocation = htab->elf.sgot->output_section->vma
3919                         + htab->sgot->output_offset + off                         + htab->elf.sgot->output_offset + off
3920                         - htab->sgotplt->output_section->vma                         - htab->elf.sgotplt->output_section->vma
3921                         - htab->sgotplt->output_offset;                         - htab->elf.sgotplt->output_offset;
3922            unresolved_reloc = FALSE;            unresolved_reloc = FALSE;
3923            break;            break;
3924    
3925          case R_386_TLS_LDO_32:          case R_386_TLS_LDO_32:
3926            if (info->shared || (input_section->flags & SEC_CODE) == 0)            if (info->shared || (input_section->flags & SEC_CODE) == 0)
3927              relocation -= dtpoff_base (info);              relocation -= elf_i386_dtpoff_base (info);
3928            else            else
3929              /* When converting LDO to LE, we must negate.  */              /* When converting LDO to LE, we must negate.  */
3930              relocation = -tpoff (info, relocation);              relocation = -elf_i386_tpoff (info, relocation);
3931            break;            break;
3932    
3933          case R_386_TLS_LE_32:          case R_386_TLS_LE_32:
# Line 3530  elf_i386_relocate_section (bfd *output_b Line 3959  elf_i386_relocate_section (bfd *output_b
3959                if (indx)                if (indx)
3960                  continue;                  continue;
3961                else if (r_type == R_386_TLS_LE_32)                else if (r_type == R_386_TLS_LE_32)
3962                  relocation = dtpoff_base (info) - relocation;                  relocation = elf_i386_dtpoff_base (info) - relocation;
3963                else                else
3964                  relocation -= dtpoff_base (info);                  relocation -= elf_i386_dtpoff_base (info);
3965              }              }
3966            else if (r_type == R_386_TLS_LE_32)            else if (r_type == R_386_TLS_LE_32)
3967              relocation = tpoff (info, relocation);              relocation = elf_i386_tpoff (info, relocation);
3968            else            else
3969              relocation = -tpoff (info, relocation);              relocation = -elf_i386_tpoff (info, relocation);
3970            break;            break;
3971    
3972          default:          default:
# Line 3561  elf_i386_relocate_section (bfd *output_b Line 3990  elf_i386_relocate_section (bfd *output_b
3990            return FALSE;            return FALSE;
3991          }          }
3992    
3993    do_relocation:
3994        r = _bfd_final_link_relocate (howto, input_bfd, input_section,        r = _bfd_final_link_relocate (howto, input_bfd, input_section,
3995                                      contents, rel->r_offset,                                      contents, rel->r_offset,
3996                                      relocation, 0);                                      relocation, 0);
# Line 3623  elf_i386_finish_dynamic_symbol (bfd *out Line 4053  elf_i386_finish_dynamic_symbol (bfd *out
4053        bfd_vma got_offset;        bfd_vma got_offset;
4054        Elf_Internal_Rela rel;        Elf_Internal_Rela rel;
4055        bfd_byte *loc;        bfd_byte *loc;
4056          asection *plt, *gotplt, *relplt;
4057    
4058          /* When building a static executable, use .iplt, .igot.plt and
4059             .rel.iplt sections for STT_GNU_IFUNC symbols.  */
4060          if (htab->elf.splt != NULL)
4061            {
4062              plt = htab->elf.splt;
4063              gotplt = htab->elf.sgotplt;
4064              relplt = htab->elf.srelplt;
4065            }
4066          else
4067            {
4068              plt = htab->elf.iplt;
4069              gotplt = htab->elf.igotplt;
4070              relplt = htab->elf.irelplt;
4071            }
4072    
4073        /* This symbol has an entry in the procedure linkage table.  Set        /* This symbol has an entry in the procedure linkage table.  Set
4074           it up.  */           it up.  */
4075    
4076        if (h->dynindx == -1        if ((h->dynindx == -1
4077            || htab->splt == NULL             && !((h->forced_local || info->executable)
4078            || htab->sgotplt == NULL                  && h->def_regular
4079            || htab->srelplt == NULL)                  && h->type == STT_GNU_IFUNC))
4080              || plt == NULL
4081              || gotplt == NULL
4082              || relplt == NULL)
4083          abort ();          abort ();
4084    
4085        /* Get the index in the procedure linkage table which        /* Get the index in the procedure linkage table which
4086           corresponds to this symbol.  This is the index of this symbol           corresponds to this symbol.  This is the index of this symbol
4087           in all the symbols for which we are making plt entries.  The           in all the symbols for which we are making plt entries.  The
4088           first entry in the procedure linkage table is reserved.  */           first entry in the procedure linkage table is reserved.
       plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;  
4089    
4090        /* Get the offset into the .got table of the entry that           Get the offset into the .got table of the entry that
4091           corresponds to this function.  Each .got entry is 4 bytes.           corresponds to this function.  Each .got entry is 4 bytes.
4092           The first three are reserved.  */           The first three are reserved.
4093        got_offset = (plt_index + 3) * 4;          
4094             For static executables, we don't reserve anything.  */
4095    
4096          if (plt == htab->elf.splt)
4097            {
4098              plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
4099              got_offset = (plt_index + 3) * 4;
4100            }
4101          else
4102            {
4103              plt_index = h->plt.offset / PLT_ENTRY_SIZE;
4104              got_offset = plt_index * 4;
4105            }
4106    
4107        /* Fill in the entry in the procedure linkage table.  */        /* Fill in the entry in the procedure linkage table.  */
4108        if (! info->shared)        if (! info->shared)
4109          {          {
4110            memcpy (htab->splt->contents + h->plt.offset, elf_i386_plt_entry,            memcpy (plt->contents + h->plt.offset, elf_i386_plt_entry,
4111                    PLT_ENTRY_SIZE);                    PLT_ENTRY_SIZE);
4112            bfd_put_32 (output_bfd,            bfd_put_32 (output_bfd,
4113                        (htab->sgotplt->output_section->vma                        (gotplt->output_section->vma
4114                         + htab->sgotplt->output_offset                         + gotplt->output_offset
4115                         + got_offset),                         + got_offset),
4116                        htab->splt->contents + h->plt.offset + 2);                        plt->contents + h->plt.offset + 2);
4117    
4118            if (htab->is_vxworks)            if (htab->is_vxworks)
4119              {              {
# Line 3675  elf_i386_finish_dynamic_symbol (bfd *out Line 4135  elf_i386_finish_dynamic_symbol (bfd *out
4135                loc = (htab->srelplt2->contents + reloc_index                loc = (htab->srelplt2->contents + reloc_index
4136                       * sizeof (Elf32_External_Rel));                       * sizeof (Elf32_External_Rel));
4137    
4138                rel.r_offset = (htab->splt->output_section->vma                rel.r_offset = (htab->elf.splt->output_section->vma
4139                                + htab->splt->output_offset                                + htab->elf.splt->output_offset
4140                                + h->plt.offset + 2),                                + h->plt.offset + 2),
4141                rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);                rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);
4142                bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);                bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
4143    
4144                /* Create the R_386_32 relocation referencing the beginning of                /* Create the R_386_32 relocation referencing the beginning of
4145                   the PLT for this GOT entry.  */                   the PLT for this GOT entry.  */
4146                rel.r_offset = (htab->sgotplt->output_section->vma                rel.r_offset = (htab->elf.sgotplt->output_section->vma
4147                                + htab->sgotplt->output_offset                                + htab->elf.sgotplt->output_offset
4148                                + got_offset);                                + got_offset);
4149                rel.r_info = ELF32_R_INFO (htab->elf.hplt->indx, R_386_32);                rel.r_info = ELF32_R_INFO (htab->elf.hplt->indx, R_386_32);
4150                bfd_elf32_swap_reloc_out (output_bfd, &rel,                bfd_elf32_swap_reloc_out (output_bfd, &rel,
# Line 3693  elf_i386_finish_dynamic_symbol (bfd *out Line 4153  elf_i386_finish_dynamic_symbol (bfd *out
4153          }          }
4154        else        else
4155          {          {
4156            memcpy (htab->splt->contents + h->plt.offset, elf_i386_pic_plt_entry,            memcpy (plt->contents + h->plt.offset, elf_i386_pic_plt_entry,
4157                    PLT_ENTRY_SIZE);                    PLT_ENTRY_SIZE);
4158            bfd_put_32 (output_bfd, got_offset,            bfd_put_32 (output_bfd, got_offset,
4159                        htab->splt->contents + h->plt.offset + 2);                        plt->contents + h->plt.offset + 2);
4160          }          }
4161    
4162        bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rel),        /* Don't fill PLT entry for static executables.  */
4163                    htab->splt->contents + h->plt.offset + 7);        if (plt == htab->elf.splt)
4164        bfd_put_32 (output_bfd, - (h->plt.offset + PLT_ENTRY_SIZE),          {
4165                    htab->splt->contents + h->plt.offset + 12);            bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rel),
4166                          plt->contents + h->plt.offset + 7);
4167              bfd_put_32 (output_bfd, - (h->plt.offset + PLT_ENTRY_SIZE),
4168                          plt->contents + h->plt.offset + 12);
4169            }
4170    
4171        /* Fill in the entry in the global offset table.  */        /* Fill in the entry in the global offset table.  */
4172        bfd_put_32 (output_bfd,        bfd_put_32 (output_bfd,
4173                    (htab->splt->output_section->vma                    (plt->output_section->vma
4174                     + htab->splt->output_offset                     + plt->output_offset
4175                     + h->plt.offset                     + h->plt.offset
4176                     + 6),                     + 6),
4177                    htab->sgotplt->contents + got_offset);                    gotplt->contents + got_offset);
4178    
4179        /* Fill in the entry in the .rel.plt section.  */        /* Fill in the entry in the .rel.plt section.  */
4180        rel.r_offset = (htab->sgotplt->output_section->vma        rel.r_offset = (gotplt->output_section->vma
4181                        + htab->sgotplt->output_offset                        + gotplt->output_offset
4182                        + got_offset);                        + got_offset);
4183        rel.r_info = ELF32_R_INFO (h->dynindx, R_386_JUMP_SLOT);        if (h->dynindx == -1
4184        loc = htab->srelplt->contents + plt_index * sizeof (Elf32_External_Rel);            || ((info->executable
4185                   || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
4186                  && h->def_regular
4187                   && h->type == STT_GNU_IFUNC))
4188            {
4189              /* If an STT_GNU_IFUNC symbol is locally defined, generate
4190                 R_386_IRELATIVE instead of R_386_JUMP_SLOT.  Store addend
4191                 in the .got.plt section.  */
4192              bfd_put_32 (output_bfd,
4193                          (h->root.u.def.value
4194                           + h->root.u.def.section->output_section->vma
4195                           + h->root.u.def.section->output_offset),
4196                          gotplt->contents + got_offset);
4197              rel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE);
4198            }
4199          else
4200            rel.r_info = ELF32_R_INFO (h->dynindx, R_386_JUMP_SLOT);
4201          loc = relplt->contents + plt_index * sizeof (Elf32_External_Rel);
4202        bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);        bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
4203    
4204        if (!h->def_regular)        if (!h->def_regular)
# Line 3746  elf_i386_finish_dynamic_symbol (bfd *out Line 4227  elf_i386_finish_dynamic_symbol (bfd *out
4227        /* This symbol has an entry in the global offset table.  Set it        /* This symbol has an entry in the global offset table.  Set it
4228           up.  */           up.  */
4229    
4230        if (htab->sgot == NULL || htab->srelgot == NULL)        if (htab->elf.sgot == NULL || htab->elf.srelgot == NULL)
4231          abort ();          abort ();
4232    
4233        rel.r_offset = (htab->sgot->output_section->vma        rel.r_offset = (htab->elf.sgot->output_section->vma
4234                        + htab->sgot->output_offset                        + htab->elf.sgot->output_offset
4235                        + (h->got.offset & ~(bfd_vma) 1));                        + (h->got.offset & ~(bfd_vma) 1));
4236    
4237        /* If this is a static link, or it is a -Bsymbolic link and the        /* If this is a static link, or it is a -Bsymbolic link and the
# Line 3758  elf_i386_finish_dynamic_symbol (bfd *out Line 4239  elf_i386_finish_dynamic_symbol (bfd *out
4239           of a version file, we just want to emit a RELATIVE reloc.           of a version file, we just want to emit a RELATIVE reloc.
4240           The entry in the global offset table will already have been           The entry in the global offset table will already have been
4241           initialized in the relocate_section function.  */           initialized in the relocate_section function.  */
4242        if (info->shared        if (h->def_regular
4243            && SYMBOL_REFERENCES_LOCAL (info, h))            && h->type == STT_GNU_IFUNC)
4244            {
4245              if (info->shared)
4246                {
4247                  /* Generate R_386_GLOB_DAT.  */
4248                  goto do_glob_dat;
4249                }
4250              else
4251                {
4252                  if (!h->pointer_equality_needed)
4253                    abort ();
4254    
4255                  /* For non-shared object, we can't use .got.plt, which
4256                     contains the real function addres if we need pointer
4257                     equality.  We load the GOT entry with the PLT entry.  */
4258                  asection *plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
4259                  bfd_put_32 (output_bfd,
4260                              (plt->output_section->vma
4261                               + plt->output_offset + h->plt.offset),
4262                              htab->elf.sgot->contents + h->got.offset);
4263                  return TRUE;
4264                }
4265            }
4266          else if (info->shared
4267                   && SYMBOL_REFERENCES_LOCAL (info, h))
4268          {          {
4269            BFD_ASSERT((h->got.offset & 1) != 0);            BFD_ASSERT((h->got.offset & 1) != 0);
4270            rel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);            rel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
# Line 3767  elf_i386_finish_dynamic_symbol (bfd *out Line 4272  elf_i386_finish_dynamic_symbol (bfd *out
4272        else        else
4273          {          {
4274            BFD_ASSERT((h->got.offset & 1) == 0);            BFD_ASSERT((h->got.offset & 1) == 0);
4275    do_glob_dat:
4276            bfd_put_32 (output_bfd, (bfd_vma) 0,            bfd_put_32 (output_bfd, (bfd_vma) 0,
4277                        htab->sgot->contents + h->got.offset);                        htab->elf.sgot->contents + h->got.offset);
4278            rel.r_info = ELF32_R_INFO (h->dynindx, R_386_GLOB_DAT);            rel.r_info = ELF32_R_INFO (h->dynindx, R_386_GLOB_DAT);
4279          }          }
4280    
4281        loc = htab->srelgot->contents;        loc = htab->elf.srelgot->contents;
4282        loc += htab->srelgot->reloc_count++ * sizeof (Elf32_External_Rel);        loc += htab->elf.srelgot->reloc_count++ * sizeof (Elf32_External_Rel);
4283        bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);        bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
4284      }      }
4285    
# Line 3799  elf_i386_finish_dynamic_symbol (bfd *out Line 4305  elf_i386_finish_dynamic_symbol (bfd *out
4305        bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);        bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
4306      }      }
4307    
4308    /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.    /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  SYM may
4309         be NULL for local symbols.
4310    
4311       On VxWorks, the _GLOBAL_OFFSET_TABLE_ symbol is not absolute: it       On VxWorks, the _GLOBAL_OFFSET_TABLE_ symbol is not absolute: it
4312       is relative to the ".got" section.  */       is relative to the ".got" section.  */
4313    if (strcmp (h->root.root.string, "_DYNAMIC") == 0    if (sym != NULL
4314        || (!htab->is_vxworks && h == htab->elf.hgot))        && (strcmp (h->root.root.string, "_DYNAMIC") == 0
4315              || (!htab->is_vxworks && h == htab->elf.hgot)))
4316      sym->st_shndx = SHN_ABS;      sym->st_shndx = SHN_ABS;
4317    
4318    return TRUE;    return TRUE;
4319  }  }
4320    
4321    /* Finish up local dynamic symbol handling.  We set the contents of
4322       various dynamic sections here.  */
4323    
4324    static bfd_boolean
4325    elf_i386_finish_local_dynamic_symbol (void **slot, void *inf)
4326    {
4327      struct elf_link_hash_entry *h
4328        = (struct elf_link_hash_entry *) *slot;
4329      struct bfd_link_info *info
4330        = (struct bfd_link_info *) inf;
4331    
4332      return elf_i386_finish_dynamic_symbol (info->output_bfd, info,
4333                                             h, NULL);
4334    }
4335    
4336  /* Used to decide how to sort relocs in an optimal manner for the  /* Used to decide how to sort relocs in an optimal manner for the
4337     dynamic linker, before writing them out.  */     dynamic linker, before writing them out.  */
4338    
# Line 3846  elf_i386_finish_dynamic_sections (bfd *o Line 4370  elf_i386_finish_dynamic_sections (bfd *o
4370      {      {
4371        Elf32_External_Dyn *dyncon, *dynconend;        Elf32_External_Dyn *dyncon, *dynconend;
4372    
4373        if (sdyn == NULL || htab->sgot == NULL)        if (sdyn == NULL || htab->elf.sgot == NULL)
4374          abort ();          abort ();
4375    
4376        dyncon = (Elf32_External_Dyn *) sdyn->contents;        dyncon = (Elf32_External_Dyn *) sdyn->contents;
# Line 3867  elf_i386_finish_dynamic_sections (bfd *o Line 4391  elf_i386_finish_dynamic_sections (bfd *o
4391                continue;                continue;
4392    
4393              case DT_PLTGOT:              case DT_PLTGOT:
4394                s = htab->sgotplt;                s = htab->elf.sgotplt;
4395                dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;                dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
4396                break;                break;
4397    
4398              case DT_JMPREL:              case DT_JMPREL:
4399                s = htab->srelplt;                s = htab->elf.srelplt;
4400                dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;                dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
4401                break;                break;
4402    
4403              case DT_PLTRELSZ:              case DT_PLTRELSZ:
4404                s = htab->srelplt;                s = htab->elf.srelplt;
4405                dyn.d_un.d_val = s->size;                dyn.d_un.d_val = s->size;
4406                break;                break;
4407    
# Line 3888  elf_i386_finish_dynamic_sections (bfd *o Line 4412  elf_i386_finish_dynamic_sections (bfd *o
4412                   what Solaris does.  However, UnixWare can not handle                   what Solaris does.  However, UnixWare can not handle
4413                   that case.  Therefore, we override the DT_RELSZ entry                   that case.  Therefore, we override the DT_RELSZ entry
4414                   here to make it not include the JMPREL relocs.  */                   here to make it not include the JMPREL relocs.  */
4415                s = htab->srelplt;                s = htab->elf.srelplt;
4416                if (s == NULL)                if (s == NULL)
4417                  continue;                  continue;
4418                dyn.d_un.d_val -= s->size;                dyn.d_un.d_val -= s->size;
# Line 3898  elf_i386_finish_dynamic_sections (bfd *o Line 4422  elf_i386_finish_dynamic_sections (bfd *o
4422                /* We may not be using the standard ELF linker script.                /* We may not be using the standard ELF linker script.
4423                   If .rel.plt is the first .rel section, we adjust                   If .rel.plt is the first .rel section, we adjust
4424                   DT_REL to not include it.  */                   DT_REL to not include it.  */
4425                s = htab->srelplt;                s = htab->elf.srelplt;
4426                if (s == NULL)                if (s == NULL)
4427                  continue;                  continue;
4428                if (dyn.d_un.d_ptr != s->output_section->vma + s->output_offset)                if (dyn.d_un.d_ptr != s->output_section->vma + s->output_offset)
# Line 3911  elf_i386_finish_dynamic_sections (bfd *o Line 4435  elf_i386_finish_dynamic_sections (bfd *o
4435          }          }
4436    
4437        /* Fill in the first entry in the procedure linkage table.  */        /* Fill in the first entry in the procedure linkage table.  */
4438        if (htab->splt && htab->splt->size > 0)        if (htab->elf.splt && htab->elf.splt->size > 0)
4439          {          {
4440            if (info->shared)            if (info->shared)
4441              {              {
4442                memcpy (htab->splt->contents, elf_i386_pic_plt0_entry,                memcpy (htab->elf.splt->contents, elf_i386_pic_plt0_entry,
4443                        sizeof (elf_i386_pic_plt0_entry));                        sizeof (elf_i386_pic_plt0_entry));
4444                memset (htab->splt->contents + sizeof (elf_i386_pic_plt0_entry),                memset (htab->elf.splt->contents + sizeof (elf_i386_pic_plt0_entry),
4445                        htab->plt0_pad_byte,                        htab->plt0_pad_byte,
4446                        PLT_ENTRY_SIZE - sizeof (elf_i386_pic_plt0_entry));                        PLT_ENTRY_SIZE - sizeof (elf_i386_pic_plt0_entry));
4447              }              }
4448            else            else
4449              {              {
4450                memcpy (htab->splt->contents, elf_i386_plt0_entry,                memcpy (htab->elf.splt->contents, elf_i386_plt0_entry,
4451                        sizeof(elf_i386_plt0_entry));                        sizeof(elf_i386_plt0_entry));
4452                memset (htab->splt->contents + sizeof (elf_i386_plt0_entry),                memset (htab->elf.splt->contents + sizeof (elf_i386_plt0_entry),
4453                        htab->plt0_pad_byte,                        htab->plt0_pad_byte,
4454                        PLT_ENTRY_SIZE - sizeof (elf_i386_plt0_entry));                        PLT_ENTRY_SIZE - sizeof (elf_i386_plt0_entry));
4455                bfd_put_32 (output_bfd,                bfd_put_32 (output_bfd,
4456                            (htab->sgotplt->output_section->vma                            (htab->elf.sgotplt->output_section->vma
4457                             + htab->sgotplt->output_offset                             + htab->elf.sgotplt->output_offset
4458                             + 4),                             + 4),
4459                            htab->splt->contents + 2);                            htab->elf.splt->contents + 2);
4460                bfd_put_32 (output_bfd,                bfd_put_32 (output_bfd,
4461                            (htab->sgotplt->output_section->vma                            (htab->elf.sgotplt->output_section->vma
4462                             + htab->sgotplt->output_offset                             + htab->elf.sgotplt->output_offset
4463                             + 8),                             + 8),
4464                            htab->splt->contents + 8);                            htab->elf.splt->contents + 8);
4465    
4466                if (htab->is_vxworks)                if (htab->is_vxworks)
4467                  {                  {
# Line 3946  elf_i386_finish_dynamic_sections (bfd *o Line 4470  elf_i386_finish_dynamic_sections (bfd *o
4470                    /* Generate a relocation for _GLOBAL_OFFSET_TABLE_ + 4.                    /* Generate a relocation for _GLOBAL_OFFSET_TABLE_ + 4.
4471                       On IA32 we use REL relocations so the addend goes in                       On IA32 we use REL relocations so the addend goes in
4472                       the PLT directly.  */                       the PLT directly.  */
4473                    rel.r_offset = (htab->splt->output_section->vma                    rel.r_offset = (htab->elf.splt->output_section->vma
4474                                    + htab->splt->output_offset                                    + htab->elf.splt->output_offset
4475                                    + 2);                                    + 2);
4476                    rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);                    rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);
4477                    bfd_elf32_swap_reloc_out (output_bfd, &rel,                    bfd_elf32_swap_reloc_out (output_bfd, &rel,
4478                                              htab->srelplt2->contents);                                              htab->srelplt2->contents);
4479                    /* Generate a relocation for _GLOBAL_OFFSET_TABLE_ + 8.  */                    /* Generate a relocation for _GLOBAL_OFFSET_TABLE_ + 8.  */
4480                    rel.r_offset = (htab->splt->output_section->vma                    rel.r_offset = (htab->elf.splt->output_section->vma
4481                                    + htab->splt->output_offset                                    + htab->elf.splt->output_offset
4482                                    + 8);                                    + 8);
4483                    rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);                    rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);
4484                    bfd_elf32_swap_reloc_out (output_bfd, &rel,                    bfd_elf32_swap_reloc_out (output_bfd, &rel,
# Line 3965  elf_i386_finish_dynamic_sections (bfd *o Line 4489  elf_i386_finish_dynamic_sections (bfd *o
4489    
4490            /* UnixWare sets the entsize of .plt to 4, although that doesn't            /* UnixWare sets the entsize of .plt to 4, although that doesn't
4491               really seem like the right value.  */               really seem like the right value.  */
4492            elf_section_data (htab->splt->output_section)            elf_section_data (htab->elf.splt->output_section)
4493              ->this_hdr.sh_entsize = 4;              ->this_hdr.sh_entsize = 4;
4494    
4495            /* Correct the .rel.plt.unloaded relocations.  */            /* Correct the .rel.plt.unloaded relocations.  */
4496            if (htab->is_vxworks && !info->shared)            if (htab->is_vxworks && !info->shared)
4497              {              {
4498                int num_plts = (htab->splt->size / PLT_ENTRY_SIZE) - 1;                int num_plts = (htab->elf.splt->size / PLT_ENTRY_SIZE) - 1;
4499                unsigned char *p;                unsigned char *p;
4500    
4501                p = htab->srelplt2->contents;                p = htab->srelplt2->contents;
# Line 3997  elf_i386_finish_dynamic_sections (bfd *o Line 4521  elf_i386_finish_dynamic_sections (bfd *o
4521          }          }
4522      }      }
4523    
4524    if (htab->sgotplt)    if (htab->elf.sgotplt)
4525      {      {
4526        /* Fill in the first three entries in the global offset table.  */        /* Fill in the first three entries in the global offset table.  */
4527        if (htab->sgotplt->size > 0)        if (htab->elf.sgotplt->size > 0)
4528          {          {
4529            bfd_put_32 (output_bfd,            bfd_put_32 (output_bfd,
4530                        (sdyn == NULL ? 0                        (sdyn == NULL ? 0
4531                         : sdyn->output_section->vma + sdyn->output_offset),                         : sdyn->output_section->vma + sdyn->output_offset),
4532                        htab->sgotplt->contents);                        htab->elf.sgotplt->contents);
4533            bfd_put_32 (output_bfd, 0, htab->sgotplt->contents + 4);            bfd_put_32 (output_bfd, 0, htab->elf.sgotplt->contents + 4);
4534            bfd_put_32 (output_bfd, 0, htab->sgotplt->contents + 8);            bfd_put_32 (output_bfd, 0, htab->elf.sgotplt->contents + 8);
4535          }          }
4536    
4537        elf_section_data (htab->sgotplt->output_section)->this_hdr.sh_entsize = 4;        elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize = 4;
4538      }      }
4539    
4540    if (htab->sgot && htab->sgot->size > 0)    if (htab->elf.sgot && htab->elf.sgot->size > 0)
4541      elf_section_data (htab->sgot->output_section)->this_hdr.sh_entsize = 4;      elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = 4;
4542    
4543      /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols.  */
4544      htab_traverse (htab->loc_hash_table,
4545                     elf_i386_finish_local_dynamic_symbol,
4546                     info);
4547    
4548    return TRUE;    return TRUE;
4549  }  }
# Line 4042  elf_i386_hash_symbol (struct elf_link_ha Line 4571  elf_i386_hash_symbol (struct elf_link_ha
4571    return _bfd_elf_hash_symbol (h);    return _bfd_elf_hash_symbol (h);
4572  }  }
4573    
4574    /* Hook called by the linker routine which adds symbols from an object
4575       file.  */
4576    
4577    static bfd_boolean
4578    elf_i386_add_symbol_hook (bfd * abfd ATTRIBUTE_UNUSED,
4579                              struct bfd_link_info * info ATTRIBUTE_UNUSED,
4580                              Elf_Internal_Sym * sym,
4581                              const char ** namep ATTRIBUTE_UNUSED,
4582                              flagword * flagsp ATTRIBUTE_UNUSED,
4583                              asection ** secp ATTRIBUTE_UNUSED,
4584                              bfd_vma * valp ATTRIBUTE_UNUSED)
4585    {
4586      if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
4587        elf_tdata (info->output_bfd)->has_ifunc_symbols = TRUE;
4588    
4589      return TRUE;
4590    }
4591    
4592  #define TARGET_LITTLE_SYM               bfd_elf32_i386_vec  #define TARGET_LITTLE_SYM               bfd_elf32_i386_vec
4593  #define TARGET_LITTLE_NAME              "elf32-i386"  #define TARGET_LITTLE_NAME              "elf32-i386"
4594  #define ELF_ARCH                        bfd_arch_i386  #define ELF_ARCH                        bfd_arch_i386
# Line 4063  elf_i386_hash_symbol (struct elf_link_ha Line 4610  elf_i386_hash_symbol (struct elf_link_ha
4610    
4611  #define bfd_elf32_bfd_is_local_label_name     elf_i386_is_local_label_name  #define bfd_elf32_bfd_is_local_label_name     elf_i386_is_local_label_name
4612  #define bfd_elf32_bfd_link_hash_table_create  elf_i386_link_hash_table_create  #define bfd_elf32_bfd_link_hash_table_create  elf_i386_link_hash_table_create
4613    #define bfd_elf32_bfd_link_hash_table_free    elf_i386_link_hash_table_free
4614  #define bfd_elf32_bfd_reloc_type_lookup       elf_i386_reloc_type_lookup  #define bfd_elf32_bfd_reloc_type_lookup       elf_i386_reloc_type_lookup
4615  #define bfd_elf32_bfd_reloc_name_lookup       elf_i386_reloc_name_lookup  #define bfd_elf32_bfd_reloc_name_lookup       elf_i386_reloc_name_lookup
4616    
# Line 4086  elf_i386_hash_symbol (struct elf_link_ha Line 4634  elf_i386_hash_symbol (struct elf_link_ha
4634    ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)    ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
4635  #define elf_backend_plt_sym_val               elf_i386_plt_sym_val  #define elf_backend_plt_sym_val               elf_i386_plt_sym_val
4636  #define elf_backend_hash_symbol               elf_i386_hash_symbol  #define elf_backend_hash_symbol               elf_i386_hash_symbol
4637    #define elf_backend_add_symbol_hook           elf_i386_add_symbol_hook
4638    #undef  elf_backend_post_process_headers
4639    #define elf_backend_post_process_headers        _bfd_elf_set_osabi
4640    
4641  #include "elf32-target.h"  #include "elf32-target.h"
4642    
# Line 4103  elf_i386_hash_symbol (struct elf_link_ha Line 4654  elf_i386_hash_symbol (struct elf_link_ha
4654     executables and (for simplicity) also all other object files.  */     executables and (for simplicity) also all other object files.  */
4655    
4656  static void  static void
4657  elf_i386_post_process_headers (bfd *abfd,  elf_i386_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info)
                                struct bfd_link_info *info ATTRIBUTE_UNUSED)  
4658  {  {
4659    Elf_Internal_Ehdr *i_ehdrp;    _bfd_elf_set_osabi (abfd, info);
   
   i_ehdrp = elf_elfheader (abfd);  
4660    
   /* Put an ABI label supported by FreeBSD >= 4.1.  */  
   i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;  
4661  #ifdef OLD_FREEBSD_ABI_LABEL  #ifdef OLD_FREEBSD_ABI_LABEL
4662    /* The ABI label supported by FreeBSD <= 4.0 is quite nonstandard.  */    /* The ABI label supported by FreeBSD <= 4.0 is quite nonstandard.  */
4663    memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8);    memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8);
# Line 4119  elf_i386_post_process_headers (bfd *abfd Line 4665  elf_i386_post_process_headers (bfd *abfd
4665  }  }
4666    
4667  #undef  elf_backend_post_process_headers  #undef  elf_backend_post_process_headers
4668  #define elf_backend_post_process_headers        elf_i386_post_process_headers  #define elf_backend_post_process_headers        elf_i386_fbsd_post_process_headers
4669  #undef  elf32_bed  #undef  elf32_bed
4670  #define elf32_bed                               elf32_i386_fbsd_bed  #define elf32_bed                               elf32_i386_fbsd_bed
4671    
4672    #undef elf_backend_add_symbol_hook
4673    
4674  #include "elf32-target.h"  #include "elf32-target.h"
4675    
4676  /* VxWorks support.  */  /* VxWorks support.  */

Legend:
Removed from v.20  
changed lines
  Added in v.21

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26