Develop and Download Open Source Software

Browse Subversion Repository

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

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

revision 20 by monabuilder, Sun Dec 7 02:23:44 2008 UTC revision 21 by monamour, Mon Jul 27 20:34:36 2009 UTC
# Line 1  Line 1 
1  /* PowerPC-specific support for 32-bit ELF  /* PowerPC-specific support for 32-bit ELF
2     Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,     Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3     2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.     2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
4     Written by Ian Lance Taylor, Cygnus Support.     Written by Ian Lance Taylor, Cygnus Support.
5    
6     This file is part of BFD, the Binary File Descriptor library.     This file is part of BFD, the Binary File Descriptor library.
# Line 753  static reloc_howto_type ppc_elf_howto_ra Line 753  static reloc_howto_type ppc_elf_howto_ra
753           0xffff,                /* dst_mask */           0xffff,                /* dst_mask */
754           FALSE),                /* pcrel_offset */           FALSE),                /* pcrel_offset */
755    
756    /* Marker reloc for TLS.  */    /* Marker relocs for TLS.  */
757    HOWTO (R_PPC_TLS,    HOWTO (R_PPC_TLS,
758           0,                     /* rightshift */           0,                     /* rightshift */
759           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
# Line 768  static reloc_howto_type ppc_elf_howto_ra Line 768  static reloc_howto_type ppc_elf_howto_ra
768           0,                     /* dst_mask */           0,                     /* dst_mask */
769           FALSE),                /* pcrel_offset */           FALSE),                /* pcrel_offset */
770    
771      HOWTO (R_PPC_TLSGD,
772             0,                     /* rightshift */
773             2,                     /* size (0 = byte, 1 = short, 2 = long) */
774             32,                    /* bitsize */
775             FALSE,                 /* pc_relative */
776             0,                     /* bitpos */
777             complain_overflow_dont, /* complain_on_overflow */
778             bfd_elf_generic_reloc, /* special_function */
779             "R_PPC_TLSGD",         /* name */
780             FALSE,                 /* partial_inplace */
781             0,                     /* src_mask */
782             0,                     /* dst_mask */
783             FALSE),                /* pcrel_offset */
784    
785      HOWTO (R_PPC_TLSLD,
786             0,                     /* rightshift */
787             2,                     /* size (0 = byte, 1 = short, 2 = long) */
788             32,                    /* bitsize */
789             FALSE,                 /* pc_relative */
790             0,                     /* bitpos */
791             complain_overflow_dont, /* complain_on_overflow */
792             bfd_elf_generic_reloc, /* special_function */
793             "R_PPC_TLSLD",         /* name */
794             FALSE,                 /* partial_inplace */
795             0,                     /* src_mask */
796             0,                     /* dst_mask */
797             FALSE),                /* pcrel_offset */
798    
799    /* Computes the load module index of the load module that contains the    /* Computes the load module index of the load module that contains the
800       definition of its TLS sym.  */       definition of its TLS sym.  */
801    HOWTO (R_PPC_DTPMOD32,    HOWTO (R_PPC_DTPMOD32,
# Line 1354  static reloc_howto_type ppc_elf_howto_ra Line 1382  static reloc_howto_type ppc_elf_howto_ra
1382           0xffff,                /* dst_mask */           0xffff,                /* dst_mask */
1383           FALSE),                /* pcrel_offset */           FALSE),                /* pcrel_offset */
1384    
1385      HOWTO (R_PPC_IRELATIVE,       /* type */
1386             0,                     /* rightshift */
1387             2,                     /* size (0 = byte, 1 = short, 2 = long) */
1388             32,                    /* bitsize */
1389             FALSE,                 /* pc_relative */
1390             0,                     /* bitpos */
1391             complain_overflow_bitfield, /* complain_on_overflow */
1392             bfd_elf_generic_reloc,  /* special_function */
1393             "R_PPC_IRELATIVE",     /* name */
1394             FALSE,                 /* partial_inplace */
1395             0,                     /* src_mask */
1396             0xffffffff,            /* dst_mask */
1397             FALSE),                /* pcrel_offset */
1398    
1399    /* A 16 bit relative relocation.  */    /* A 16 bit relative relocation.  */
1400    HOWTO (R_PPC_REL16,           /* type */    HOWTO (R_PPC_REL16,           /* type */
1401           0,                     /* rightshift */           0,                     /* rightshift */
# Line 1531  ppc_elf_reloc_type_lookup (bfd *abfd ATT Line 1573  ppc_elf_reloc_type_lookup (bfd *abfd ATT
1573      case BFD_RELOC_CTOR:                r = R_PPC_ADDR32;               break;      case BFD_RELOC_CTOR:                r = R_PPC_ADDR32;               break;
1574      case BFD_RELOC_PPC_TOC16:           r = R_PPC_TOC16;                break;      case BFD_RELOC_PPC_TOC16:           r = R_PPC_TOC16;                break;
1575      case BFD_RELOC_PPC_TLS:             r = R_PPC_TLS;                  break;      case BFD_RELOC_PPC_TLS:             r = R_PPC_TLS;                  break;
1576        case BFD_RELOC_PPC_TLSGD:           r = R_PPC_TLSGD;                break;
1577        case BFD_RELOC_PPC_TLSLD:           r = R_PPC_TLSLD;                break;
1578      case BFD_RELOC_PPC_DTPMOD:          r = R_PPC_DTPMOD32;             break;      case BFD_RELOC_PPC_DTPMOD:          r = R_PPC_DTPMOD32;             break;
1579      case BFD_RELOC_PPC_TPREL16:         r = R_PPC_TPREL16;              break;      case BFD_RELOC_PPC_TPREL16:         r = R_PPC_TPREL16;              break;
1580      case BFD_RELOC_PPC_TPREL16_LO:      r = R_PPC_TPREL16_LO;           break;      case BFD_RELOC_PPC_TPREL16_LO:      r = R_PPC_TPREL16_LO;           break;
# Line 2298  ppc_elf_final_write_processing (bfd *abf Line 2342  ppc_elf_final_write_processing (bfd *abf
2342  }  }
2343    
2344  static bfd_boolean  static bfd_boolean
2345  is_pic_glink_stub (bfd *abfd, asection *glink, bfd_vma off)  is_nonpic_glink_stub (bfd *abfd, asection *glink, bfd_vma off)
2346  {  {
2347    bfd_byte buf[16];    bfd_byte buf[GLINK_ENTRY_SIZE];
   unsigned int insn;  
2348    
2349    if (!bfd_get_section_contents (abfd, glink, buf, off, 16))    if (!bfd_get_section_contents (abfd, glink, buf, off, GLINK_ENTRY_SIZE))
2350      return FALSE;      return FALSE;
2351    
2352    insn = bfd_get_32 (abfd, buf);    return ((bfd_get_32 (abfd, buf + 0) & 0xffff0000) == LIS_11
2353    if ((insn & 0xffff0000) == LWZ_11_30            && (bfd_get_32 (abfd, buf + 4) & 0xffff0000) == LWZ_11_11
2354        && bfd_get_32 (abfd, buf + 4) == MTCTR_11            && bfd_get_32 (abfd, buf + 8) == MTCTR_11
2355        && bfd_get_32 (abfd, buf + 8) == BCTR)            && bfd_get_32 (abfd, buf + 12) == BCTR);
     return TRUE;  
   
   if ((insn & 0xffff0000) == ADDIS_11_30  
       && (bfd_get_32 (abfd, buf + 4) & 0xffff0000) == LWZ_11_11  
       && bfd_get_32 (abfd, buf + 8) == MTCTR_11  
       && bfd_get_32 (abfd, buf + 12) == BCTR)  
     return TRUE;  
   return FALSE;  
2356  }  }
2357    
2358  static bfd_boolean  static bfd_boolean
# Line 2454  ppc_elf_get_synthetic_symtab (bfd *abfd, Line 2489  ppc_elf_get_synthetic_symtab (bfd *abfd,
2489       multiple stubs for each plt entry.  If that is the case then       multiple stubs for each plt entry.  If that is the case then
2490       there is no way to associate stubs with their plt entries short       there is no way to associate stubs with their plt entries short
2491       of figuring out the GOT pointer value used in the stub.  */       of figuring out the GOT pointer value used in the stub.  */
2492    if (!bfd_get_section_contents (abfd, glink, buf,    if (!is_nonpic_glink_stub (abfd, glink,
2493                                   stub_vma - glink->vma, 4)                               glink_vma - GLINK_ENTRY_SIZE - glink->vma))
       || ((bfd_get_32 (abfd, buf) & 0xffff0000) != LIS_11  
           && is_pic_glink_stub (abfd, glink, stub_vma - glink->vma - 16)))  
2494      return 0;      return 0;
2495    
2496    slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;    slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
# Line 2467  ppc_elf_get_synthetic_symtab (bfd *abfd, Line 2500  ppc_elf_get_synthetic_symtab (bfd *abfd,
2500    size = count * sizeof (asymbol);    size = count * sizeof (asymbol);
2501    p = relplt->relocation;    p = relplt->relocation;
2502    for (i = 0; i < count; i++, p++)    for (i = 0; i < count; i++, p++)
2503      size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");      {
2504          size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
2505          if (p->addend != 0)
2506            size += sizeof ("+0x") - 1 + 8;
2507        }
2508    
2509    size += sizeof (asymbol) + sizeof ("__glink");    size += sizeof (asymbol) + sizeof ("__glink");
2510    
# Line 2497  ppc_elf_get_synthetic_symtab (bfd *abfd, Line 2534  ppc_elf_get_synthetic_symtab (bfd *abfd,
2534        len = strlen ((*p->sym_ptr_ptr)->name);        len = strlen ((*p->sym_ptr_ptr)->name);
2535        memcpy (names, (*p->sym_ptr_ptr)->name, len);        memcpy (names, (*p->sym_ptr_ptr)->name, len);
2536        names += len;        names += len;
2537          if (p->addend != 0)
2538            {
2539              memcpy (names, "+0x", sizeof ("+0x") - 1);
2540              names += sizeof ("+0x") - 1;
2541              bfd_sprintf_vma (abfd, names, p->addend);
2542              names += strlen (names);
2543            }
2544        memcpy (names, "@plt", sizeof ("@plt"));        memcpy (names, "@plt", sizeof ("@plt"));
2545        names += sizeof ("@plt");        names += sizeof ("@plt");
2546        ++s;        ++s;
# Line 2646  struct ppc_elf_link_hash_entry Line 2690  struct ppc_elf_link_hash_entry
2690  #define TLS_DTPREL       8      /* DTPREL reloc, => LD. */  #define TLS_DTPREL       8      /* DTPREL reloc, => LD. */
2691  #define TLS_TLS         16      /* Any TLS reloc.  */  #define TLS_TLS         16      /* Any TLS reloc.  */
2692  #define TLS_TPRELGD     32      /* TPREL reloc resulting from GD->IE. */  #define TLS_TPRELGD     32      /* TPREL reloc resulting from GD->IE. */
2693    #define PLT_IFUNC       64      /* STT_GNU_IFUNC.  */
2694    char tls_mask;    char tls_mask;
2695    
2696    /* Nonzero if we have seen a small data relocation referring to this    /* Nonzero if we have seen a small data relocation referring to this
# Line 2667  struct ppc_elf_link_hash_table Line 2712  struct ppc_elf_link_hash_table
2712    asection *glink;    asection *glink;
2713    asection *plt;    asection *plt;
2714    asection *relplt;    asection *relplt;
2715      asection *iplt;
2716      asection *reliplt;
2717    asection *dynbss;    asection *dynbss;
2718    asection *relbss;    asection *relbss;
2719    asection *dynsbss;    asection *dynsbss;
# Line 2692  struct ppc_elf_link_hash_table Line 2739  struct ppc_elf_link_hash_table
2739      bfd_vma offset;      bfd_vma offset;
2740    } tlsld_got;    } tlsld_got;
2741    
2742    /* Offset of PltResolve function in glink.  */    /* Offset of branch table to PltResolve function in glink.  */
2743    bfd_vma glink_pltresolve;    bfd_vma glink_pltresolve;
2744    
2745    /* Size of reserved GOT entries.  */    /* Size of reserved GOT entries.  */
# Line 2716  struct ppc_elf_link_hash_table Line 2763  struct ppc_elf_link_hash_table
2763    /* The size of the first PLT entry.  */    /* The size of the first PLT entry.  */
2764    int plt_initial_entry_size;    int plt_initial_entry_size;
2765    
2766    /* Small local sym to section mapping cache.  */    /* Small local sym cache.  */
2767    struct sym_sec_cache sym_sec;    struct sym_cache sym_cache;
2768  };  };
2769    
2770  /* Get the PPC ELF linker hash table from a link_info structure.  */  /* Get the PPC ELF linker hash table from a link_info structure.  */
# Line 2826  ppc_elf_create_got (bfd *abfd, struct bf Line 2873  ppc_elf_create_got (bfd *abfd, struct bf
2873          return FALSE;          return FALSE;
2874      }      }
2875    
2876    flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY    htab->relgot = bfd_get_section_by_name (abfd, ".rela.got");
2877             | SEC_LINKER_CREATED | SEC_READONLY);    if (!htab->relgot)
2878    htab->relgot = bfd_make_section_with_flags (abfd, ".rela.got", flags);      abort ();
2879    if (!htab->relgot  
2880        || ! bfd_set_section_alignment (abfd, htab->relgot, 2))    return TRUE;
2881    }
2882    
2883    static bfd_boolean
2884    ppc_elf_create_glink (bfd *abfd, struct bfd_link_info *info)
2885    {
2886      struct ppc_elf_link_hash_table *htab = ppc_elf_hash_table (info);
2887      asection *s;
2888      flagword flags;
2889    
2890      flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY | SEC_HAS_CONTENTS
2891               | SEC_IN_MEMORY | SEC_LINKER_CREATED);
2892      s = bfd_make_section_anyway_with_flags (abfd, ".glink", flags);
2893      htab->glink = s;
2894      if (s == NULL
2895          || !bfd_set_section_alignment (abfd, s, 4))
2896        return FALSE;
2897    
2898      flags = SEC_ALLOC | SEC_LINKER_CREATED;
2899      s = bfd_make_section_anyway_with_flags (abfd, ".iplt", flags);
2900      htab->iplt = s;
2901      if (s == NULL
2902          || !bfd_set_section_alignment (abfd, s, 4))
2903      return FALSE;      return FALSE;
2904    
2905      flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_HAS_CONTENTS
2906               | SEC_IN_MEMORY | SEC_LINKER_CREATED);
2907      s = bfd_make_section_with_flags (abfd, ".rela.iplt", flags);
2908      htab->reliplt = s;
2909      if (s == NULL
2910          || ! bfd_set_section_alignment (abfd, s, 2))
2911        return FALSE;
2912    return TRUE;    return TRUE;
2913  }  }
2914    
# Line 2856  ppc_elf_create_dynamic_sections (bfd *ab Line 2932  ppc_elf_create_dynamic_sections (bfd *ab
2932    if (!_bfd_elf_create_dynamic_sections (abfd, info))    if (!_bfd_elf_create_dynamic_sections (abfd, info))
2933      return FALSE;      return FALSE;
2934    
2935    flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_HAS_CONTENTS    if (htab->glink == NULL
2936             | SEC_IN_MEMORY | SEC_LINKER_CREATED);        && !ppc_elf_create_glink (abfd, info))
   
   s = bfd_make_section_anyway_with_flags (abfd, ".glink", flags | SEC_CODE);  
   htab->glink = s;  
   if (s == NULL  
       || !bfd_set_section_alignment (abfd, s, 4))  
2937      return FALSE;      return FALSE;
2938    
2939    htab->dynbss = bfd_get_section_by_name (abfd, ".dynbss");    htab->dynbss = bfd_get_section_by_name (abfd, ".dynbss");
# Line 2875  ppc_elf_create_dynamic_sections (bfd *ab Line 2946  ppc_elf_create_dynamic_sections (bfd *ab
2946    if (! info->shared)    if (! info->shared)
2947      {      {
2948        htab->relbss = bfd_get_section_by_name (abfd, ".rela.bss");        htab->relbss = bfd_get_section_by_name (abfd, ".rela.bss");
2949          flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_HAS_CONTENTS
2950                   | SEC_IN_MEMORY | SEC_LINKER_CREATED);
2951        s = bfd_make_section_with_flags (abfd, ".rela.sbss", flags);        s = bfd_make_section_with_flags (abfd, ".rela.sbss", flags);
2952        htab->relsbss = s;        htab->relsbss = s;
2953        if (s == NULL        if (s == NULL
# Line 3048  ppc_elf_add_symbol_hook (bfd *abfd, Line 3121  ppc_elf_add_symbol_hook (bfd *abfd,
3121        *valp = sym->st_size;        *valp = sym->st_size;
3122      }      }
3123    
3124      if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
3125        elf_tdata (info->output_bfd)->has_ifunc_symbols = TRUE;
3126    
3127    return TRUE;    return TRUE;
3128  }  }
3129    
# Line 3196  elf_create_pointer_linker_section (bfd * Line 3272  elf_create_pointer_linker_section (bfd *
3272    return TRUE;    return TRUE;
3273  }  }
3274    
3275  static bfd_boolean  static struct plt_entry **
3276  update_local_sym_info (bfd *abfd,  update_local_sym_info (bfd *abfd,
3277                         Elf_Internal_Shdr *symtab_hdr,                         Elf_Internal_Shdr *symtab_hdr,
3278                         unsigned long r_symndx,                         unsigned long r_symndx,
3279                         int tls_type)                         int tls_type)
3280  {  {
3281    bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (abfd);    bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (abfd);
3282      struct plt_entry **local_plt;
3283    char *local_got_tls_masks;    char *local_got_tls_masks;
3284    
3285    if (local_got_refcounts == NULL)    if (local_got_refcounts == NULL)
3286      {      {
3287        bfd_size_type size = symtab_hdr->sh_info;        bfd_size_type size = symtab_hdr->sh_info;
3288    
3289        size *= sizeof (*local_got_refcounts) + sizeof (*local_got_tls_masks);        size *= (sizeof (*local_got_refcounts)
3290                   + sizeof (*local_plt)
3291                   + sizeof (*local_got_tls_masks));
3292        local_got_refcounts = bfd_zalloc (abfd, size);        local_got_refcounts = bfd_zalloc (abfd, size);
3293        if (local_got_refcounts == NULL)        if (local_got_refcounts == NULL)
3294          return FALSE;          return NULL;
3295        elf_local_got_refcounts (abfd) = local_got_refcounts;        elf_local_got_refcounts (abfd) = local_got_refcounts;
3296      }      }
3297    
3298    local_got_refcounts[r_symndx] += 1;    local_plt = (struct plt_entry **) (local_got_refcounts + symtab_hdr->sh_info);
3299    local_got_tls_masks = (char *) (local_got_refcounts + symtab_hdr->sh_info);    local_got_tls_masks = (char *) (local_plt + symtab_hdr->sh_info);
3300    local_got_tls_masks[r_symndx] |= tls_type;    local_got_tls_masks[r_symndx] |= tls_type;
3301    return TRUE;    if (tls_type != PLT_IFUNC)
3302        local_got_refcounts[r_symndx] += 1;
3303      return local_plt + r_symndx;
3304  }  }
3305    
3306  static bfd_boolean  static bfd_boolean
3307  update_plt_info (bfd *abfd, struct elf_link_hash_entry *h,  update_plt_info (bfd *abfd, struct plt_entry **plist,
3308                   asection *sec, bfd_vma addend)                   asection *sec, bfd_vma addend)
3309  {  {
3310    struct plt_entry *ent;    struct plt_entry *ent;
3311    
3312    if (addend < 32768)    for (ent = *plist; ent != NULL; ent = ent->next)
     sec = NULL;  
   for (ent = h->plt.plist; ent != NULL; ent = ent->next)  
3313      if (ent->sec == sec && ent->addend == addend)      if (ent->sec == sec && ent->addend == addend)
3314        break;        break;
3315    if (ent == NULL)    if (ent == NULL)
# Line 3239  update_plt_info (bfd *abfd, struct elf_l Line 3318  update_plt_info (bfd *abfd, struct elf_l
3318        ent = bfd_alloc (abfd, amt);        ent = bfd_alloc (abfd, amt);
3319        if (ent == NULL)        if (ent == NULL)
3320          return FALSE;          return FALSE;
3321        ent->next = h->plt.plist;        ent->next = *plist;
3322        ent->sec = sec;        ent->sec = sec;
3323        ent->addend = addend;        ent->addend = addend;
3324        ent->plt.refcount = 0;        ent->plt.refcount = 0;
3325        h->plt.plist = ent;        *plist = ent;
3326      }      }
3327    ent->plt.refcount += 1;    ent->plt.refcount += 1;
3328    return TRUE;    return TRUE;
3329  }  }
3330    
3331  static struct plt_entry *  static struct plt_entry *
3332  find_plt_ent (struct elf_link_hash_entry *h, asection *sec, bfd_vma addend)  find_plt_ent (struct plt_entry **plist, asection *sec, bfd_vma addend)
3333  {  {
3334    struct plt_entry *ent;    struct plt_entry *ent;
3335    
3336    if (addend < 32768)    if (addend < 32768)
3337      sec = NULL;      sec = NULL;
3338    for (ent = h->plt.plist; ent != NULL; ent = ent->next)    for (ent = *plist; ent != NULL; ent = ent->next)
3339      if (ent->sec == sec && ent->addend == addend)      if (ent->sec == sec && ent->addend == addend)
3340        break;        break;
3341    return ent;    return ent;
3342  }  }
3343    
3344    static bfd_boolean
3345    is_branch_reloc (enum elf_ppc_reloc_type r_type)
3346    {
3347      return (r_type == R_PPC_PLTREL24
3348              || r_type == R_PPC_LOCAL24PC
3349              || r_type == R_PPC_REL24
3350              || r_type == R_PPC_REL14
3351              || r_type == R_PPC_REL14_BRTAKEN
3352              || r_type == R_PPC_REL14_BRNTAKEN
3353              || r_type == R_PPC_ADDR24
3354              || r_type == R_PPC_ADDR14
3355              || r_type == R_PPC_ADDR14_BRTAKEN
3356              || r_type == R_PPC_ADDR14_BRNTAKEN);
3357    }
3358    
3359  static void  static void
3360  bad_shared_reloc (bfd *abfd, enum elf_ppc_reloc_type r_type)  bad_shared_reloc (bfd *abfd, enum elf_ppc_reloc_type r_type)
3361  {  {
# Line 3288  ppc_elf_check_relocs (bfd *abfd, Line 3382  ppc_elf_check_relocs (bfd *abfd,
3382    const Elf_Internal_Rela *rel;    const Elf_Internal_Rela *rel;
3383    const Elf_Internal_Rela *rel_end;    const Elf_Internal_Rela *rel_end;
3384    asection *got2, *sreloc;    asection *got2, *sreloc;
3385      struct elf_link_hash_entry *tga;
3386    
3387    if (info->relocatable)    if (info->relocatable)
3388      return TRUE;      return TRUE;
# Line 3313  ppc_elf_check_relocs (bfd *abfd, Line 3408  ppc_elf_check_relocs (bfd *abfd,
3408      ppc_elf_howto_init ();      ppc_elf_howto_init ();
3409    
3410    htab = ppc_elf_hash_table (info);    htab = ppc_elf_hash_table (info);
3411      tga = elf_link_hash_lookup (&htab->elf, "__tls_get_addr",
3412                                  FALSE, FALSE, TRUE);
3413    symtab_hdr = &elf_symtab_hdr (abfd);    symtab_hdr = &elf_symtab_hdr (abfd);
3414    sym_hashes = elf_sym_hashes (abfd);    sym_hashes = elf_sym_hashes (abfd);
3415    got2 = bfd_get_section_by_name (abfd, ".got2");    got2 = bfd_get_section_by_name (abfd, ".got2");
# Line 3324  ppc_elf_check_relocs (bfd *abfd, Line 3421  ppc_elf_check_relocs (bfd *abfd,
3421        unsigned long r_symndx;        unsigned long r_symndx;
3422        enum elf_ppc_reloc_type r_type;        enum elf_ppc_reloc_type r_type;
3423        struct elf_link_hash_entry *h;        struct elf_link_hash_entry *h;
3424        int tls_type = 0;        int tls_type;
3425          struct plt_entry **ifunc;
3426    
3427        r_symndx = ELF32_R_SYM (rel->r_info);        r_symndx = ELF32_R_SYM (rel->r_info);
3428        if (r_symndx < symtab_hdr->sh_info)        if (r_symndx < symtab_hdr->sh_info)
# Line 3351  ppc_elf_check_relocs (bfd *abfd, Line 3449  ppc_elf_check_relocs (bfd *abfd,
3449            BFD_ASSERT (h == htab->elf.hgot);            BFD_ASSERT (h == htab->elf.hgot);
3450          }          }
3451    
3452          tls_type = 0;
3453          ifunc = NULL;
3454        r_type = ELF32_R_TYPE (rel->r_info);        r_type = ELF32_R_TYPE (rel->r_info);
3455          if (!htab->is_vxworks && is_branch_reloc (r_type))
3456            {
3457              if (h != NULL && h == tga)
3458                {
3459                  if (rel != relocs
3460                      && (ELF32_R_TYPE (rel[-1].r_info) == R_PPC_TLSGD
3461                          || ELF32_R_TYPE (rel[-1].r_info) == R_PPC_TLSLD))
3462                    /* We have a new-style __tls_get_addr call with a marker
3463                       reloc.  */
3464                    ;
3465                  else
3466                    /* Mark this section as having an old-style call.  */
3467                    sec->has_tls_get_addr_call = 1;
3468                }
3469    
3470              /* STT_GNU_IFUNC symbols must have a PLT entry.  */
3471              if (h != NULL)
3472                {
3473                  if (h->type == STT_GNU_IFUNC)
3474                    {
3475                      h->needs_plt = 1;
3476                      ifunc = &h->plt.plist;
3477                    }
3478                }
3479              else
3480                {
3481                  Elf_Internal_Sym *isym = bfd_sym_from_r_symndx (&htab->sym_cache,
3482                                                                  abfd, r_symndx);
3483                  if (isym == NULL)
3484                    return FALSE;
3485    
3486                  if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
3487                    {
3488                      ifunc = update_local_sym_info (abfd, symtab_hdr, r_symndx,
3489                                                     PLT_IFUNC);
3490                      if (ifunc == NULL)
3491                        return FALSE;
3492                    }
3493                }
3494              if (ifunc != NULL)
3495                {
3496                  bfd_vma addend = 0;
3497    
3498                  if (r_type == R_PPC_PLTREL24)
3499                    {
3500                      ppc_elf_tdata (abfd)->makes_plt_call = 1;
3501                      addend = rel->r_addend;
3502                    }
3503                  if (!update_plt_info (abfd, ifunc,
3504                                        addend < 32768 ? NULL : got2, addend))
3505                    return FALSE;
3506    
3507                  if (htab->glink == NULL)
3508                    {
3509                      if (htab->elf.dynobj == NULL)
3510                        htab->elf.dynobj = abfd;
3511                      if (!ppc_elf_create_glink (htab->elf.dynobj, info))
3512                        return FALSE;
3513                    }
3514                }
3515            }
3516    
3517        switch (r_type)        switch (r_type)
3518          {          {
3519            case R_PPC_TLSGD:
3520            case R_PPC_TLSLD:
3521              /* These special tls relocs tie a call to __tls_get_addr with
3522                 its parameter symbol.  */
3523              break;
3524    
3525          case R_PPC_GOT_TLSLD16:          case R_PPC_GOT_TLSLD16:
3526          case R_PPC_GOT_TLSLD16_LO:          case R_PPC_GOT_TLSLD16_LO:
3527          case R_PPC_GOT_TLSLD16_HI:          case R_PPC_GOT_TLSLD16_HI:
# Line 3518  ppc_elf_check_relocs (bfd *abfd, Line 3686  ppc_elf_check_relocs (bfd *abfd,
3686              h->non_got_ref = TRUE;              h->non_got_ref = TRUE;
3687            break;            break;
3688    
         case R_PPC_PLT32:  
3689          case R_PPC_PLTREL24:          case R_PPC_PLTREL24:
3690              if (h == NULL || ifunc != NULL)
3691                break;
3692              /* Fall through */
3693            case R_PPC_PLT32:
3694          case R_PPC_PLTREL32:          case R_PPC_PLTREL32:
3695          case R_PPC_PLT16_LO:          case R_PPC_PLT16_LO:
3696          case R_PPC_PLT16_HI:          case R_PPC_PLT16_HI:
# Line 3556  ppc_elf_check_relocs (bfd *abfd, Line 3727  ppc_elf_check_relocs (bfd *abfd,
3727                    addend = rel->r_addend;                    addend = rel->r_addend;
3728                  }                  }
3729                h->needs_plt = 1;                h->needs_plt = 1;
3730                if (!update_plt_info (abfd, h, got2, addend))                if (!update_plt_info (abfd, &h->plt.plist,
3731                                        addend < 32768 ? NULL : got2, addend))
3732                  return FALSE;                  return FALSE;
3733              }              }
3734            break;            break;
# Line 3587  ppc_elf_check_relocs (bfd *abfd, Line 3759  ppc_elf_check_relocs (bfd *abfd,
3759          case R_PPC_EMB_MRKREF:          case R_PPC_EMB_MRKREF:
3760          case R_PPC_NONE:          case R_PPC_NONE:
3761          case R_PPC_max:          case R_PPC_max:
3762            case R_PPC_RELAX32:
3763            case R_PPC_RELAX32PC:
3764            case R_PPC_RELAX32_PLT:
3765            case R_PPC_RELAX32PC_PLT:
3766            break;            break;
3767    
3768            /* These should only appear in dynamic objects.  */            /* These should only appear in dynamic objects.  */
# Line 3594  ppc_elf_check_relocs (bfd *abfd, Line 3770  ppc_elf_check_relocs (bfd *abfd,
3770          case R_PPC_GLOB_DAT:          case R_PPC_GLOB_DAT:
3771          case R_PPC_JMP_SLOT:          case R_PPC_JMP_SLOT:
3772          case R_PPC_RELATIVE:          case R_PPC_RELATIVE:
3773            case R_PPC_IRELATIVE:
3774            break;            break;
3775    
3776            /* These aren't handled yet.  We'll report an error later.  */            /* These aren't handled yet.  We'll report an error later.  */
# Line 3607  ppc_elf_check_relocs (bfd *abfd, Line 3784  ppc_elf_check_relocs (bfd *abfd,
3784    
3785            /* This refers only to functions defined in the shared library.  */            /* This refers only to functions defined in the shared library.  */
3786          case R_PPC_LOCAL24PC:          case R_PPC_LOCAL24PC:
3787            if (h && h == htab->elf.hgot && htab->plt_type == PLT_UNSET)            if (h != NULL && h == htab->elf.hgot && htab->plt_type == PLT_UNSET)
3788              {              {
3789                htab->plt_type = PLT_OLD;                htab->plt_type = PLT_OLD;
3790                htab->old_bfd = abfd;                htab->old_bfd = abfd;
# Line 3659  ppc_elf_check_relocs (bfd *abfd, Line 3836  ppc_elf_check_relocs (bfd *abfd,
3836                   reliably deduce the GOT pointer value needed for                   reliably deduce the GOT pointer value needed for
3837                   PLT call stubs.  */                   PLT call stubs.  */
3838                asection *s;                asection *s;
3839                  Elf_Internal_Sym *isym;
3840    
3841                s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, sec,                isym = bfd_sym_from_r_symndx (&htab->sym_cache,
3842                                               r_symndx);                                              abfd, r_symndx);
3843                  if (isym == NULL)
3844                    return FALSE;
3845    
3846                  s = bfd_section_from_elf_index (abfd, isym->st_shndx);
3847                if (s == got2)                if (s == got2)
3848                  {                  {
3849                    htab->plt_type = PLT_OLD;                    htab->plt_type = PLT_OLD;
# Line 3683  ppc_elf_check_relocs (bfd *abfd, Line 3865  ppc_elf_check_relocs (bfd *abfd,
3865              {              {
3866                /* We may need a plt entry if the symbol turns out to be                /* We may need a plt entry if the symbol turns out to be
3867                   a function defined in a dynamic object.  */                   a function defined in a dynamic object.  */
3868                if (!update_plt_info (abfd, h, NULL, 0))                if (!update_plt_info (abfd, &h->plt.plist, NULL, 0))
3869                  return FALSE;                  return FALSE;
3870    
3871                /* We may need a copy reloc too.  */                /* We may need a copy reloc too.  */
# Line 3717  ppc_elf_check_relocs (bfd *abfd, Line 3899  ppc_elf_check_relocs (bfd *abfd,
3899              {              {
3900                /* We may need a plt entry if the symbol turns out to be                /* We may need a plt entry if the symbol turns out to be
3901                   a function defined in a dynamic object.  */                   a function defined in a dynamic object.  */
3902                if (!update_plt_info (abfd, h, NULL, 0))                h->needs_plt = 1;
3903                  if (ifunc == NULL
3904                      && !update_plt_info (abfd, &h->plt.plist, NULL, 0))
3905                  return FALSE;                  return FALSE;
3906                break;                break;
3907              }              }
# Line 3789  ppc_elf_check_relocs (bfd *abfd, Line 3973  ppc_elf_check_relocs (bfd *abfd,
3973                    /* Track dynamic relocs needed for local syms too.                    /* Track dynamic relocs needed for local syms too.
3974                       We really need local syms available to do this                       We really need local syms available to do this
3975                       easily.  Oh well.  */                       easily.  Oh well.  */
   
3976                    asection *s;                    asection *s;
3977                    void *vpp;                    void *vpp;
3978                      Elf_Internal_Sym *isym;
3979    
3980                    s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,                    isym = bfd_sym_from_r_symndx (&htab->sym_cache,
3981                                                   sec, r_symndx);                                                  abfd, r_symndx);
3982                    if (s == NULL)                    if (isym == NULL)
3983                      return FALSE;                      return FALSE;
3984    
3985                      s = bfd_section_from_elf_index (abfd, isym->st_shndx);
3986                      if (s == NULL)
3987                        s = sec;
3988    
3989                    vpp = &elf_section_data (s)->local_dynrel;                    vpp = &elf_section_data (s)->local_dynrel;
3990                    head = (struct ppc_elf_dyn_relocs **) vpp;                    head = (struct ppc_elf_dyn_relocs **) vpp;
3991                  }                  }
# Line 4222  ppc_elf_gc_sweep_hook (bfd *abfd, Line 4410  ppc_elf_gc_sweep_hook (bfd *abfd,
4410          }          }
4411    
4412        r_type = ELF32_R_TYPE (rel->r_info);        r_type = ELF32_R_TYPE (rel->r_info);
4413          if (!htab->is_vxworks && is_branch_reloc (r_type))
4414            {
4415              struct plt_entry **ifunc = NULL;
4416              if (h != NULL)
4417                {
4418                  if (h->type == STT_GNU_IFUNC)
4419                    ifunc = &h->plt.plist;
4420                }
4421              else if (local_got_refcounts != NULL)
4422                {
4423                  struct plt_entry **local_plt = (struct plt_entry **)
4424                    (local_got_refcounts + symtab_hdr->sh_info);
4425                  char *local_got_tls_masks = (char *)
4426                    (local_plt + symtab_hdr->sh_info);
4427                  if ((local_got_tls_masks[r_symndx] & PLT_IFUNC) != 0)
4428                    ifunc = local_plt + r_symndx;
4429                }
4430              if (ifunc != NULL)
4431                {
4432                  bfd_vma addend = r_type == R_PPC_PLTREL24 ? rel->r_addend : 0;
4433                  struct plt_entry *ent = find_plt_ent (ifunc, got2, addend);
4434                  if (ent->plt.refcount > 0)
4435                    ent->plt.refcount -= 1;
4436                  continue;
4437                }
4438            }
4439    
4440        switch (r_type)        switch (r_type)
4441          {          {
4442          case R_PPC_GOT_TLSLD16:          case R_PPC_GOT_TLSLD16:
# Line 4288  ppc_elf_gc_sweep_hook (bfd *abfd, Line 4503  ppc_elf_gc_sweep_hook (bfd *abfd,
4503            if (h != NULL)            if (h != NULL)
4504              {              {
4505                bfd_vma addend = r_type == R_PPC_PLTREL24 ? rel->r_addend : 0;                bfd_vma addend = r_type == R_PPC_PLTREL24 ? rel->r_addend : 0;
4506                struct plt_entry *ent = find_plt_ent (h, got2, addend);                struct plt_entry *ent = find_plt_ent (&h->plt.plist,
4507                                                        got2, addend);
4508                if (ent->plt.refcount > 0)                if (ent->plt.refcount > 0)
4509                  ent->plt.refcount -= 1;                  ent->plt.refcount -= 1;
4510              }              }
# Line 4301  ppc_elf_gc_sweep_hook (bfd *abfd, Line 4517  ppc_elf_gc_sweep_hook (bfd *abfd,
4517    return TRUE;    return TRUE;
4518  }  }
4519    
4520  /* Set htab->tls_get_addr and call the generic ELF tls_setup function.  */  /* Set plt output section type, htab->tls_get_addr, and call the
4521       generic ELF tls_setup function.  */
4522    
4523  asection *  asection *
4524  ppc_elf_tls_setup (bfd *obfd, struct bfd_link_info *info)  ppc_elf_tls_setup (bfd *obfd, struct bfd_link_info *info)
# Line 4322  ppc_elf_tls_setup (bfd *obfd, struct bfd Line 4539  ppc_elf_tls_setup (bfd *obfd, struct bfd
4539    return _bfd_elf_tls_setup (obfd, info);    return _bfd_elf_tls_setup (obfd, info);
4540  }  }
4541    
4542    /* Return TRUE iff REL is a branch reloc with a global symbol matching
4543       HASH.  */
4544    
4545    static bfd_boolean
4546    branch_reloc_hash_match (const bfd *ibfd,
4547                             const Elf_Internal_Rela *rel,
4548                             const struct elf_link_hash_entry *hash)
4549    {
4550      Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (ibfd);
4551      enum elf_ppc_reloc_type r_type = ELF32_R_TYPE (rel->r_info);
4552      unsigned int r_symndx = ELF32_R_SYM (rel->r_info);
4553    
4554      if (r_symndx >= symtab_hdr->sh_info && is_branch_reloc (r_type))
4555        {
4556          struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (ibfd);
4557          struct elf_link_hash_entry *h;
4558    
4559          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
4560          while (h->root.type == bfd_link_hash_indirect
4561                 || h->root.type == bfd_link_hash_warning)
4562            h = (struct elf_link_hash_entry *) h->root.u.i.link;
4563          if (h == hash)
4564            return TRUE;
4565        }
4566      return FALSE;
4567    }
4568    
4569  /* Run through all the TLS relocs looking for optimization  /* Run through all the TLS relocs looking for optimization
4570     opportunities.  */     opportunities.  */
4571    
# Line 4446  ppc_elf_tls_optimize (bfd *obfd ATTRIBUT Line 4690  ppc_elf_tls_optimize (bfd *obfd ATTRIBUT
4690    
4691                    if (pass == 0)                    if (pass == 0)
4692                      {                      {
4693                        if (!expecting_tls_get_addr)                        if (!expecting_tls_get_addr
4694                              || !sec->has_tls_get_addr_call)
4695                          continue;                          continue;
4696    
4697                        if (rel + 1 < relend)                        if (rel + 1 < relend
4698                          {                            && branch_reloc_hash_match (ibfd, rel + 1,
4699                            enum elf_ppc_reloc_type r_type2;                                                        htab->tls_get_addr))
4700                            unsigned long r_symndx2;                          continue;
                           struct elf_link_hash_entry *h2;  
   
                           /* The next instruction should be a call to  
                              __tls_get_addr.  Peek at the reloc to be sure.  */  
                           r_type2 = ELF32_R_TYPE (rel[1].r_info);  
                           r_symndx2 = ELF32_R_SYM (rel[1].r_info);  
                           if (r_symndx2 >= symtab_hdr->sh_info  
                               && (r_type2 == R_PPC_REL14  
                                   || r_type2 == R_PPC_REL14_BRTAKEN  
                                   || r_type2 == R_PPC_REL14_BRNTAKEN  
                                   || r_type2 == R_PPC_REL24  
                                   || r_type2 == R_PPC_PLTREL24))  
                             {  
                               struct elf_link_hash_entry **sym_hashes;  
   
                               sym_hashes = elf_sym_hashes (ibfd);  
                               h2 = sym_hashes[r_symndx2 - symtab_hdr->sh_info];  
                               while (h2->root.type == bfd_link_hash_indirect  
                                      || h2->root.type == bfd_link_hash_warning)  
                                 h2 = ((struct elf_link_hash_entry *)  
                                       h2->root.u.i.link);  
                               if (h2 == htab->tls_get_addr)  
                                 continue;  
                             }  
                         }  
4701    
4702                        /* Uh oh, we didn't find the expected call.  We                        /* Uh oh, we didn't find the expected call.  We
4703                           could just mark this symbol to exclude it                           could just mark this symbol to exclude it
# Line 4496  ppc_elf_tls_optimize (bfd *obfd ATTRIBUT Line 4716  ppc_elf_tls_optimize (bfd *obfd ATTRIBUT
4716                      {                      {
4717                        Elf_Internal_Sym *sym;                        Elf_Internal_Sym *sym;
4718                        bfd_signed_vma *lgot_refs;                        bfd_signed_vma *lgot_refs;
4719                          struct plt_entry **local_plt;
4720                        char *lgot_masks;                        char *lgot_masks;
4721    
4722                        if (locsyms == NULL)                        if (locsyms == NULL)
# Line 4516  ppc_elf_tls_optimize (bfd *obfd ATTRIBUT Line 4737  ppc_elf_tls_optimize (bfd *obfd ATTRIBUT
4737                        lgot_refs = elf_local_got_refcounts (ibfd);                        lgot_refs = elf_local_got_refcounts (ibfd);
4738                        if (lgot_refs == NULL)                        if (lgot_refs == NULL)
4739                          abort ();                          abort ();
4740                        lgot_masks = (char *) (lgot_refs + symtab_hdr->sh_info);                        local_plt = (struct plt_entry **)
4741                            (lgot_refs + symtab_hdr->sh_info);
4742                          lgot_masks = (char *) (local_plt + symtab_hdr->sh_info);
4743                        tls_mask = &lgot_masks[r_symndx];                        tls_mask = &lgot_masks[r_symndx];
4744                        got_count = &lgot_refs[r_symndx];                        got_count = &lgot_refs[r_symndx];
4745                      }                      }
# Line 4532  ppc_elf_tls_optimize (bfd *obfd ATTRIBUT Line 4755  ppc_elf_tls_optimize (bfd *obfd ATTRIBUT
4755                      {                      {
4756                        struct plt_entry *ent;                        struct plt_entry *ent;
4757    
4758                        ent = find_plt_ent (htab->tls_get_addr, NULL, 0);                        ent = find_plt_ent (&htab->tls_get_addr->plt.plist,
4759                                              NULL, 0);
4760                        if (ent != NULL && ent->plt.refcount > 0)                        if (ent != NULL && ent->plt.refcount > 0)
4761                          ent->plt.refcount -= 1;                          ent->plt.refcount -= 1;
4762                      }                      }
# Line 4605  ppc_elf_adjust_dynamic_symbol (struct bf Line 4829  ppc_elf_adjust_dynamic_symbol (struct bf
4829    
4830    /* Deal with function syms.  */    /* Deal with function syms.  */
4831    if (h->type == STT_FUNC    if (h->type == STT_FUNC
4832          || h->type == STT_GNU_IFUNC
4833        || h->needs_plt)        || h->needs_plt)
4834      {      {
4835        /* Clear procedure linkage table information for any symbol that        /* Clear procedure linkage table information for any symbol that
# Line 4614  ppc_elf_adjust_dynamic_symbol (struct bf Line 4839  ppc_elf_adjust_dynamic_symbol (struct bf
4839          if (ent->plt.refcount > 0)          if (ent->plt.refcount > 0)
4840            break;            break;
4841        if (ent == NULL        if (ent == NULL
4842            || SYMBOL_CALLS_LOCAL (info, h)            || (h->type != STT_GNU_IFUNC
4843            || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT                && (SYMBOL_CALLS_LOCAL (info, h)
4844                && h->root.type == bfd_link_hash_undefweak))                    || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
4845                          && h->root.type == bfd_link_hash_undefweak))))
4846          {          {
4847            /* A PLT entry is not required/allowed when:            /* A PLT entry is not required/allowed when:
4848    
# Line 4852  allocate_dynrelocs (struct elf_link_hash Line 5078  allocate_dynrelocs (struct elf_link_hash
5078      h = (struct elf_link_hash_entry *) h->root.u.i.link;      h = (struct elf_link_hash_entry *) h->root.u.i.link;
5079    
5080    htab = ppc_elf_hash_table (info);    htab = ppc_elf_hash_table (info);
5081    if (htab->elf.dynamic_sections_created)    if (htab->elf.dynamic_sections_created
5082          || h->type == STT_GNU_IFUNC)
5083      {      {
5084        struct plt_entry *ent;        struct plt_entry *ent;
5085        bfd_boolean doneone = FALSE;        bfd_boolean doneone = FALSE;
5086        bfd_vma plt_offset = 0, glink_offset = 0;        bfd_vma plt_offset = 0, glink_offset = 0;
5087          bfd_boolean dyn;
5088    
5089        for (ent = h->plt.plist; ent != NULL; ent = ent->next)        for (ent = h->plt.plist; ent != NULL; ent = ent->next)
5090          if (ent->plt.refcount > 0)          if (ent->plt.refcount > 0)
5091            {            {
5092              /* Make sure this symbol is output as a dynamic symbol.  */              /* Make sure this symbol is output as a dynamic symbol.  */
5093              if (h->dynindx == -1              if (h->dynindx == -1
5094                  && !h->forced_local)                  && !h->forced_local
5095                    && !h->def_regular
5096                    && htab->elf.dynamic_sections_created)
5097                {                {
5098                  if (! bfd_elf_link_record_dynamic_symbol (info, h))                  if (! bfd_elf_link_record_dynamic_symbol (info, h))
5099                    return FALSE;                    return FALSE;
5100                }                }
5101    
5102                dyn = htab->elf.dynamic_sections_created;
5103              if (info->shared              if (info->shared
5104                  || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))                  || h->type == STT_GNU_IFUNC
5105                    || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))
5106                {                {
5107                  asection *s = htab->plt;                  asection *s = htab->plt;
5108                    if (!dyn)
5109                      s = htab->iplt;
5110    
5111                  if (htab->plt_type == PLT_NEW)                  if (htab->plt_type == PLT_NEW || !dyn)
5112                    {                    {
5113                      if (!doneone)                      if (!doneone)
5114                        {                        {
# Line 4952  allocate_dynrelocs (struct elf_link_hash Line 5186  allocate_dynrelocs (struct elf_link_hash
5186                  /* We also need to make an entry in the .rela.plt section.  */                  /* We also need to make an entry in the .rela.plt section.  */
5187                  if (!doneone)                  if (!doneone)
5188                    {                    {
5189                      htab->relplt->size += sizeof (Elf32_External_Rela);                      if (!htab->elf.dynamic_sections_created)
5190                          htab->reliplt->size += sizeof (Elf32_External_Rela);
5191                      if (htab->plt_type == PLT_VXWORKS)                      else
5192                        {                        {
5193                          /* Allocate space for the unloaded relocations.  */                          htab->relplt->size += sizeof (Elf32_External_Rela);
5194                          if (!info->shared)  
5195                            if (htab->plt_type == PLT_VXWORKS)
5196                            {                            {
5197                              if (ent->plt.offset                              /* Allocate space for the unloaded relocations.  */
5198                                  == (bfd_vma) htab->plt_initial_entry_size)                              if (!info->shared
5199                                    && htab->elf.dynamic_sections_created)
5200                                {                                {
5201                                    if (ent->plt.offset
5202                                        == (bfd_vma) htab->plt_initial_entry_size)
5203                                      {
5204                                        htab->srelplt2->size
5205                                          += (sizeof (Elf32_External_Rela)
5206                                              * VXWORKS_PLTRESOLVE_RELOCS);
5207                                      }
5208    
5209                                  htab->srelplt2->size                                  htab->srelplt2->size
5210                                    += sizeof (Elf32_External_Rela)                                    += (sizeof (Elf32_External_Rela)
5211                                        * VXWORKS_PLTRESOLVE_RELOCS;                                        * VXWORKS_PLT_NON_JMP_SLOT_RELOCS);
5212                                }                                }
5213    
5214                              htab->srelplt2->size                              /* Every PLT entry has an associated GOT entry in
5215                                += sizeof (Elf32_External_Rela)                                 .got.plt.  */
5216                                    * VXWORKS_PLT_NON_JMP_SLOT_RELOCS;                              htab->sgotplt->size += 4;
5217                            }                            }
   
                         /* Every PLT entry has an associated GOT entry in  
                            .got.plt.  */  
                         htab->sgotplt->size += 4;  
5218                        }                        }
5219                      doneone = TRUE;                      doneone = TRUE;
5220                    }                    }
# Line 5006  allocate_dynrelocs (struct elf_link_hash Line 5246  allocate_dynrelocs (struct elf_link_hash
5246        /* Make sure this symbol is output as a dynamic symbol.  */        /* Make sure this symbol is output as a dynamic symbol.  */
5247        if (eh->elf.dynindx == -1        if (eh->elf.dynindx == -1
5248            && !eh->elf.forced_local            && !eh->elf.forced_local
5249              && !eh->elf.def_regular
5250            && htab->elf.dynamic_sections_created)            && htab->elf.dynamic_sections_created)
5251          {          {
5252            if (!bfd_elf_link_record_dynamic_symbol (info, &eh->elf))            if (!bfd_elf_link_record_dynamic_symbol (info, &eh->elf))
# Line 5121  allocate_dynrelocs (struct elf_link_hash Line 5362  allocate_dynrelocs (struct elf_link_hash
5362            /* Make sure undefined weak symbols are output as a dynamic            /* Make sure undefined weak symbols are output as a dynamic
5363               symbol in PIEs.  */               symbol in PIEs.  */
5364            else if (h->dynindx == -1            else if (h->dynindx == -1
5365                     && !h->forced_local)                     && !h->forced_local
5366                       && !h->def_regular)
5367              {              {
5368                if (! bfd_elf_link_record_dynamic_symbol (info, h))                if (! bfd_elf_link_record_dynamic_symbol (info, h))
5369                  return FALSE;                  return FALSE;
# Line 5140  allocate_dynrelocs (struct elf_link_hash Line 5382  allocate_dynrelocs (struct elf_link_hash
5382            /* Make sure this symbol is output as a dynamic symbol.            /* Make sure this symbol is output as a dynamic symbol.
5383               Undefined weak syms won't yet be marked as dynamic.  */               Undefined weak syms won't yet be marked as dynamic.  */
5384            if (h->dynindx == -1            if (h->dynindx == -1
5385                && !h->forced_local)                && !h->forced_local
5386                  && !h->def_regular)
5387              {              {
5388                if (! bfd_elf_link_record_dynamic_symbol (info, h))                if (! bfd_elf_link_record_dynamic_symbol (info, h))
5389                  return FALSE;                  return FALSE;
# Line 5230  ppc_elf_size_dynamic_sections (bfd *outp Line 5473  ppc_elf_size_dynamic_sections (bfd *outp
5473      {      {
5474        bfd_signed_vma *local_got;        bfd_signed_vma *local_got;
5475        bfd_signed_vma *end_local_got;        bfd_signed_vma *end_local_got;
5476          struct plt_entry **local_plt;
5477          struct plt_entry **end_local_plt;
5478        char *lgot_masks;        char *lgot_masks;
5479        bfd_size_type locsymcount;        bfd_size_type locsymcount;
5480        Elf_Internal_Shdr *symtab_hdr;        Elf_Internal_Shdr *symtab_hdr;
# Line 5280  ppc_elf_size_dynamic_sections (bfd *outp Line 5525  ppc_elf_size_dynamic_sections (bfd *outp
5525        symtab_hdr = &elf_symtab_hdr (ibfd);        symtab_hdr = &elf_symtab_hdr (ibfd);
5526        locsymcount = symtab_hdr->sh_info;        locsymcount = symtab_hdr->sh_info;
5527        end_local_got = local_got + locsymcount;        end_local_got = local_got + locsymcount;
5528        lgot_masks = (char *) end_local_got;        local_plt = (struct plt_entry **) end_local_got;
5529          end_local_plt = local_plt + locsymcount;
5530          lgot_masks = (char *) end_local_plt;
5531        for (; local_got < end_local_got; ++local_got, ++lgot_masks)        for (; local_got < end_local_got; ++local_got, ++lgot_masks)
5532          if (*local_got > 0)          if (*local_got > 0)
5533            {            {
# Line 5310  ppc_elf_size_dynamic_sections (bfd *outp Line 5557  ppc_elf_size_dynamic_sections (bfd *outp
5557            }            }
5558          else          else
5559            *local_got = (bfd_vma) -1;            *local_got = (bfd_vma) -1;
5560    
5561          if (htab->is_vxworks)
5562            continue;
5563    
5564          /* Allocate space for calls to local STT_GNU_IFUNC syms in .iplt.  */
5565          for (; local_plt < end_local_plt; ++local_plt)
5566            {
5567              struct plt_entry *ent;
5568              bfd_boolean doneone = FALSE;
5569              bfd_vma plt_offset = 0, glink_offset = 0;
5570    
5571              for (ent = *local_plt; ent != NULL; ent = ent->next)
5572                if (ent->plt.refcount > 0)
5573                  {
5574                    asection *s = htab->iplt;
5575    
5576                    if (!doneone)
5577                      {
5578                        plt_offset = s->size;
5579                        s->size += 4;
5580                      }
5581                    ent->plt.offset = plt_offset;
5582    
5583                    s = htab->glink;
5584                    if (!doneone || info->shared || info->pie)
5585                      {
5586                        glink_offset = s->size;
5587                        s->size += GLINK_ENTRY_SIZE;
5588                      }
5589                    ent->glink_offset = glink_offset;
5590    
5591                    if (!doneone)
5592                      {
5593                        htab->reliplt += sizeof (Elf32_External_Rela);
5594                        doneone = TRUE;
5595                      }
5596                  }
5597                else
5598                  ent->plt.offset = (bfd_vma) -1;
5599            }
5600      }      }
5601    
5602    /* Allocate space for global sym dynamic relocs.  */    /* Allocate space for global sym dynamic relocs.  */
# Line 5343  ppc_elf_size_dynamic_sections (bfd *outp Line 5630  ppc_elf_size_dynamic_sections (bfd *outp
5630        htab->elf.hgot->root.u.def.value = g_o_t;        htab->elf.hgot->root.u.def.value = g_o_t;
5631      }      }
5632    
5633    if (htab->glink != NULL && htab->glink->size != 0)    if (htab->glink != NULL
5634          && htab->glink->size != 0
5635          && htab->elf.dynamic_sections_created)
5636      {      {
5637        htab->glink_pltresolve = htab->glink->size;        htab->glink_pltresolve = htab->glink->size;
5638        /* Space for the branch table.  */        /* Space for the branch table.  */
# Line 5399  ppc_elf_size_dynamic_sections (bfd *outp Line 5688  ppc_elf_size_dynamic_sections (bfd *outp
5688          continue;          continue;
5689    
5690        if (s == htab->plt        if (s == htab->plt
5691            || s == htab->glink            || s == htab->got)
           || s == htab->got  
           || s == htab->sgotplt  
           || s == htab->sbss  
           || s == htab->dynbss  
           || s == htab->dynsbss)  
5692          {          {
5693            /* We'd like to strip these sections if they aren't needed, but if            /* We'd like to strip these sections if they aren't needed, but if
5694               we've exported dynamic symbols from them we must leave them.               we've exported dynamic symbols from them we must leave them.
5695               It's too late to tell BFD to get rid of the symbols.  */               It's too late to tell BFD to get rid of the symbols.  */
5696            if ((s == htab->plt || s == htab->got) && htab->elf.hplt != NULL)            if (htab->elf.hplt != NULL)
5697              strip_section = FALSE;              strip_section = FALSE;
5698            /* Strip this section if we don't need it; see the            /* Strip this section if we don't need it; see the
5699               comment below.  */               comment below.  */
5700          }          }
5701        else if (s == htab->sdata[0].section        else if (s == htab->iplt
5702                   || s == htab->glink
5703                   || s == htab->sgotplt
5704                   || s == htab->sbss
5705                   || s == htab->dynbss
5706                   || s == htab->dynsbss
5707                   || s == htab->sdata[0].section
5708                 || s == htab->sdata[1].section)                 || s == htab->sdata[1].section)
5709          {          {
5710            /* Strip these too.  */            /* Strip these too.  */
# Line 5576  ppc_elf_relax_section (bfd *abfd, Line 5866  ppc_elf_relax_section (bfd *abfd,
5866    Elf_Internal_Rela *internal_relocs = NULL;    Elf_Internal_Rela *internal_relocs = NULL;
5867    Elf_Internal_Rela *irel, *irelend;    Elf_Internal_Rela *irel, *irelend;
5868    struct one_fixup *fixups = NULL;    struct one_fixup *fixups = NULL;
5869    bfd_boolean changed;    unsigned changes = 0;
5870    struct ppc_elf_link_hash_table *htab;    struct ppc_elf_link_hash_table *htab;
5871    bfd_size_type trampoff;    bfd_size_type trampoff;
5872    asection *got2;    asection *got2;
# Line 5590  ppc_elf_relax_section (bfd *abfd, Line 5880  ppc_elf_relax_section (bfd *abfd,
5880        || isec->reloc_count == 0)        || isec->reloc_count == 0)
5881      return TRUE;      return TRUE;
5882    
5883      /* We cannot represent the required PIC relocs in the output, so don't
5884         do anything.  The linker doesn't support mixing -shared and -r
5885         anyway.  */
5886      if (link_info->relocatable && link_info->shared)
5887         return TRUE;
5888      
5889    trampoff = (isec->size + 3) & (bfd_vma) -4;    trampoff = (isec->size + 3) & (bfd_vma) -4;
5890    /* Space for a branch around any trampolines.  */    /* Space for a branch around any trampolines.  */
5891    trampoff += 4;    trampoff += 4;
# Line 5655  ppc_elf_relax_section (bfd *abfd, Line 5951  ppc_elf_relax_section (bfd *abfd,
5951              }              }
5952            isym = isymbuf + ELF32_R_SYM (irel->r_info);            isym = isymbuf + ELF32_R_SYM (irel->r_info);
5953            if (isym->st_shndx == SHN_UNDEF)            if (isym->st_shndx == SHN_UNDEF)
5954              continue;   /* We can't do anything with undefined symbols.  */              tsec = bfd_und_section_ptr;
5955            else if (isym->st_shndx == SHN_ABS)            else if (isym->st_shndx == SHN_ABS)
5956              tsec = bfd_abs_section_ptr;              tsec = bfd_abs_section_ptr;
5957            else if (isym->st_shndx == SHN_COMMON)            else if (isym->st_shndx == SHN_COMMON)
# Line 5684  ppc_elf_relax_section (bfd *abfd, Line 5980  ppc_elf_relax_section (bfd *abfd,
5980            if (r_type == R_PPC_PLTREL24            if (r_type == R_PPC_PLTREL24
5981                && htab->plt != NULL)                && htab->plt != NULL)
5982              {              {
5983                struct plt_entry *ent = find_plt_ent (h, got2, irel->r_addend);                struct plt_entry *ent = find_plt_ent (&h->plt.plist,
5984                                                        got2, irel->r_addend);
5985    
5986                if (ent != NULL)                if (ent != NULL)
5987                  {                  {
# Line 5708  ppc_elf_relax_section (bfd *abfd, Line 6005  ppc_elf_relax_section (bfd *abfd,
6005                tsec = h->root.u.def.section;                tsec = h->root.u.def.section;
6006                toff = h->root.u.def.value;                toff = h->root.u.def.value;
6007              }              }
6008              else if (h->root.type == bfd_link_hash_undefined
6009                       || h->root.type == bfd_link_hash_undefweak)
6010                {
6011                  tsec = bfd_und_section_ptr;
6012                  toff = 0;
6013                }
6014            else            else
6015              continue;              continue;
6016    
# Line 5767  ppc_elf_relax_section (bfd *abfd, Line 6070  ppc_elf_relax_section (bfd *abfd,
6070        reladdr = isec->output_section->vma + isec->output_offset + roff;        reladdr = isec->output_section->vma + isec->output_offset + roff;
6071    
6072        /* If the branch is in range, no need to do anything.  */        /* If the branch is in range, no need to do anything.  */
6073        if (symaddr - reladdr + max_branch_offset < 2 * max_branch_offset)        if (tsec != bfd_und_section_ptr
6074              && (!link_info->relocatable
6075                  /* A relocatable link may have sections moved during
6076                     final link, so do not presume they remain in range.  */
6077                  || tsec->output_section == isec->output_section)
6078              && symaddr - reladdr + max_branch_offset < 2 * max_branch_offset)
6079          continue;          continue;
6080    
6081        /* Look for an existing fixup to this address.  */        /* Look for an existing fixup to this address.  */
# Line 5823  ppc_elf_relax_section (bfd *abfd, Line 6131  ppc_elf_relax_section (bfd *abfd,
6131            fixups = f;            fixups = f;
6132    
6133            trampoff += size;            trampoff += size;
6134              changes++;
6135          }          }
6136        else        else
6137          {          {
# Line 5873  ppc_elf_relax_section (bfd *abfd, Line 6182  ppc_elf_relax_section (bfd *abfd,
6182      }      }
6183    
6184    /* Write out the trampolines.  */    /* Write out the trampolines.  */
   changed = fixups != NULL;  
6185    if (fixups != NULL)    if (fixups != NULL)
6186      {      {
6187        const int *stub;        const int *stub;
# Line 5939  ppc_elf_relax_section (bfd *abfd, Line 6247  ppc_elf_relax_section (bfd *abfd,
6247    if (contents != NULL    if (contents != NULL
6248        && elf_section_data (isec)->this_hdr.contents != contents)        && elf_section_data (isec)->this_hdr.contents != contents)
6249      {      {
6250        if (!changed && !link_info->keep_memory)        if (!changes && !link_info->keep_memory)
6251          free (contents);          free (contents);
6252        else        else
6253          {          {
# Line 5948  ppc_elf_relax_section (bfd *abfd, Line 6256  ppc_elf_relax_section (bfd *abfd,
6256          }          }
6257      }      }
6258    
6259    if (elf_section_data (isec)->relocs != internal_relocs)    if (changes != 0)
6260      {      {
6261        if (!changed)        /* Append sufficient NOP relocs so we can write out relocation
6262             information for the trampolines.  */
6263          Elf_Internal_Rela *new_relocs = bfd_malloc ((changes + isec->reloc_count)
6264                                                      * sizeof (*new_relocs));
6265          unsigned ix;
6266          
6267          if (!new_relocs)
6268            goto error_return;
6269          memcpy (new_relocs, internal_relocs,
6270                  isec->reloc_count * sizeof (*new_relocs));
6271          for (ix = changes; ix--;)
6272            {
6273              irel = new_relocs + ix + isec->reloc_count;
6274    
6275              irel->r_info = ELF32_R_INFO (0, R_PPC_NONE);
6276            }
6277          if (internal_relocs != elf_section_data (isec)->relocs)
6278          free (internal_relocs);          free (internal_relocs);
6279        else        elf_section_data (isec)->relocs = new_relocs;
6280          elf_section_data (isec)->relocs = internal_relocs;        isec->reloc_count += changes;
6281          elf_section_data (isec)->rel_hdr.sh_size
6282            += changes * elf_section_data (isec)->rel_hdr.sh_entsize;
6283      }      }
6284      else if (elf_section_data (isec)->relocs != internal_relocs)
6285        free (internal_relocs);
6286    
6287    *again = changed;    *again = changes != 0;
6288      if (!*again && link_info->relocatable)
6289        {
6290          /* Convert the internal relax relocs to external form.  */
6291          for (irel = internal_relocs; irel < irelend; irel++)
6292            if (ELF32_R_TYPE (irel->r_info) == R_PPC_RELAX32)
6293              {
6294                unsigned long r_symndx = ELF32_R_SYM (irel->r_info);
6295    
6296                /* Rewrite the reloc and convert one of the trailing nop
6297                   relocs to describe this relocation.  */
6298                BFD_ASSERT (ELF32_R_TYPE (irelend[-1].r_info) == R_PPC_NONE);
6299                /* The relocs are at the bottom 2 bytes */
6300                irel[0].r_offset += 2;
6301                memmove (irel + 1, irel, (irelend - irel - 1) * sizeof (*irel));
6302                irel[0].r_info = ELF32_R_INFO (r_symndx, R_PPC_ADDR16_HA);
6303                irel[1].r_offset += 4;
6304                irel[1].r_info = ELF32_R_INFO (r_symndx, R_PPC_ADDR16_LO);
6305                irel++;
6306              }
6307        }
6308      
6309    return TRUE;    return TRUE;
6310    
6311   error_return:   error_return:
# Line 6048  elf_finish_pointer_linker_section (bfd * Line 6397  elf_finish_pointer_linker_section (bfd *
6397    return relocation - linker_section_ptr->addend;    return relocation - linker_section_ptr->addend;
6398  }  }
6399    
6400    #define PPC_LO(v) ((v) & 0xffff)
6401    #define PPC_HI(v) (((v) >> 16) & 0xffff)
6402    #define PPC_HA(v) PPC_HI ((v) + 0x8000)
6403    
6404    static void
6405    write_glink_stub (struct plt_entry *ent, asection *plt_sec,
6406                      struct bfd_link_info *info)
6407    {
6408      struct ppc_elf_link_hash_table *htab = ppc_elf_hash_table (info);
6409      bfd *output_bfd = info->output_bfd;
6410      bfd_vma plt;
6411      unsigned char *p;
6412    
6413      plt = ((ent->plt.offset & ~1)
6414             + plt_sec->output_section->vma
6415             + plt_sec->output_offset);
6416      p = (unsigned char *) htab->glink->contents + ent->glink_offset;
6417    
6418      if (info->shared || info->pie)
6419        {
6420          bfd_vma got = 0;
6421    
6422          if (ent->addend >= 32768)
6423            got = (ent->addend
6424                   + ent->sec->output_section->vma
6425                   + ent->sec->output_offset);
6426          else if (htab->elf.hgot != NULL)
6427            got = SYM_VAL (htab->elf.hgot);
6428    
6429          plt -= got;
6430    
6431          if (plt + 0x8000 < 0x10000)
6432            {
6433              bfd_put_32 (output_bfd, LWZ_11_30 + PPC_LO (plt), p);
6434              p += 4;
6435              bfd_put_32 (output_bfd, MTCTR_11, p);
6436              p += 4;
6437              bfd_put_32 (output_bfd, BCTR, p);
6438              p += 4;
6439              bfd_put_32 (output_bfd, NOP, p);
6440              p += 4;
6441            }
6442          else
6443            {
6444              bfd_put_32 (output_bfd, ADDIS_11_30 + PPC_HA (plt), p);
6445              p += 4;
6446              bfd_put_32 (output_bfd, LWZ_11_11 + PPC_LO (plt), p);
6447              p += 4;
6448              bfd_put_32 (output_bfd, MTCTR_11, p);
6449              p += 4;
6450              bfd_put_32 (output_bfd, BCTR, p);
6451              p += 4;
6452            }
6453        }
6454      else
6455        {
6456          bfd_put_32 (output_bfd, LIS_11 + PPC_HA (plt), p);
6457          p += 4;
6458          bfd_put_32 (output_bfd, LWZ_11_11 + PPC_LO (plt), p);
6459          p += 4;
6460          bfd_put_32 (output_bfd, MTCTR_11, p);
6461          p += 4;
6462          bfd_put_32 (output_bfd, BCTR, p);
6463          p += 4;
6464        }
6465    }
6466    
6467  /* The RELOCATE_SECTION function is called by the ELF backend linker  /* The RELOCATE_SECTION function is called by the ELF backend linker
6468     to handle the relocations for a section.     to handle the relocations for a section.
6469    
# Line 6141  ppc_elf_relocate_section (bfd *output_bf Line 6557  ppc_elf_relocate_section (bfd *output_bf
6557        bfd_boolean unresolved_reloc;        bfd_boolean unresolved_reloc;
6558        bfd_boolean warned;        bfd_boolean warned;
6559        unsigned int tls_type, tls_mask, tls_gd;        unsigned int tls_type, tls_mask, tls_gd;
6560          struct plt_entry **ifunc;
6561    
6562        r_type = ELF32_R_TYPE (rel->r_info);        r_type = ELF32_R_TYPE (rel->r_info);
6563        sym = NULL;        sym = NULL;
# Line 6201  ppc_elf_relocate_section (bfd *output_bf Line 6618  ppc_elf_relocate_section (bfd *output_bf
6618           for the final instruction stream.  */           for the final instruction stream.  */
6619        tls_mask = 0;        tls_mask = 0;
6620        tls_gd = 0;        tls_gd = 0;
6621        if (IS_PPC_TLS_RELOC (r_type))        if (h != NULL)
6622          {          tls_mask = ((struct ppc_elf_link_hash_entry *) h)->tls_mask;
6623            if (h != NULL)        else if (local_got_offsets != NULL)
6624              tls_mask = ((struct ppc_elf_link_hash_entry *) h)->tls_mask;          {
6625            else if (local_got_offsets != NULL)            struct plt_entry **local_plt;
6626              {            char *lgot_masks;
6627                char *lgot_masks;            local_plt
6628                lgot_masks = (char *) (local_got_offsets + symtab_hdr->sh_info);              = (struct plt_entry **) (local_got_offsets + symtab_hdr->sh_info);
6629                tls_mask = lgot_masks[r_symndx];            lgot_masks = (char *) (local_plt + symtab_hdr->sh_info);
6630              }            tls_mask = lgot_masks[r_symndx];
6631          }          }
6632    
6633        /* Ensure reloc mapping code below stays sane.  */        /* Ensure reloc mapping code below stays sane.  */
# Line 6230  ppc_elf_relocate_section (bfd *output_bf Line 6647  ppc_elf_relocate_section (bfd *output_bf
6647    
6648          case R_PPC_GOT_TPREL16:          case R_PPC_GOT_TPREL16:
6649          case R_PPC_GOT_TPREL16_LO:          case R_PPC_GOT_TPREL16_LO:
6650            if (tls_mask != 0            if ((tls_mask & TLS_TLS) != 0
6651                && (tls_mask & TLS_TPREL) == 0)                && (tls_mask & TLS_TPREL) == 0)
6652              {              {
6653                bfd_vma insn;                bfd_vma insn;
# Line 6244  ppc_elf_relocate_section (bfd *output_bf Line 6661  ppc_elf_relocate_section (bfd *output_bf
6661            break;            break;
6662    
6663          case R_PPC_TLS:          case R_PPC_TLS:
6664            if (tls_mask != 0            if ((tls_mask & TLS_TLS) != 0
6665                && (tls_mask & TLS_TPREL) == 0)                && (tls_mask & TLS_TPREL) == 0)
6666              {              {
6667                bfd_vma insn, rtra;                bfd_vma insn, rtra;
# Line 6291  ppc_elf_relocate_section (bfd *output_bf Line 6708  ppc_elf_relocate_section (bfd *output_bf
6708          case R_PPC_GOT_TLSGD16_HI:          case R_PPC_GOT_TLSGD16_HI:
6709          case R_PPC_GOT_TLSGD16_HA:          case R_PPC_GOT_TLSGD16_HA:
6710            tls_gd = TLS_TPRELGD;            tls_gd = TLS_TPRELGD;
6711            if (tls_mask != 0 && (tls_mask & TLS_GD) == 0)            if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_GD) == 0)
6712              goto tls_gdld_hi;              goto tls_gdld_hi;
6713            break;            break;
6714    
6715          case R_PPC_GOT_TLSLD16_HI:          case R_PPC_GOT_TLSLD16_HI:
6716          case R_PPC_GOT_TLSLD16_HA:          case R_PPC_GOT_TLSLD16_HA:
6717            if (tls_mask != 0 && (tls_mask & TLS_LD) == 0)            if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_LD) == 0)
6718              {              {
6719              tls_gdld_hi:              tls_gdld_hi:
6720                if ((tls_mask & tls_gd) != 0)                if ((tls_mask & tls_gd) != 0)
# Line 6316  ppc_elf_relocate_section (bfd *output_bf Line 6733  ppc_elf_relocate_section (bfd *output_bf
6733          case R_PPC_GOT_TLSGD16:          case R_PPC_GOT_TLSGD16:
6734          case R_PPC_GOT_TLSGD16_LO:          case R_PPC_GOT_TLSGD16_LO:
6735            tls_gd = TLS_TPRELGD;            tls_gd = TLS_TPRELGD;
6736            if (tls_mask != 0 && (tls_mask & TLS_GD) == 0)            if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_GD) == 0)
6737              goto tls_ldgd_opt;              goto tls_ldgd_opt;
6738            break;            break;
6739    
6740          case R_PPC_GOT_TLSLD16:          case R_PPC_GOT_TLSLD16:
6741          case R_PPC_GOT_TLSLD16_LO:          case R_PPC_GOT_TLSLD16_LO:
6742            if (tls_mask != 0 && (tls_mask & TLS_LD) == 0)            if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_LD) == 0)
6743              {              {
6744                bfd_vma insn1, insn2;                unsigned int insn1, insn2;
6745                bfd_vma offset;                bfd_vma offset;
6746    
6747              tls_ldgd_opt:              tls_ldgd_opt:
6748                offset = rel[1].r_offset;                offset = (bfd_vma) -1;
6749                insn1 = bfd_get_32 (output_bfd,                /* If not using the newer R_PPC_TLSGD/LD to mark
6750                                    contents + rel->r_offset - d_offset);                   __tls_get_addr calls, we must trust that the call
6751                     stays with its arg setup insns, ie. that the next
6752                     reloc is the __tls_get_addr call associated with
6753                     the current reloc.  Edit both insns.  */
6754                  if (input_section->has_tls_get_addr_call
6755                      && rel + 1 < relend
6756                      && branch_reloc_hash_match (input_bfd, rel + 1,
6757                                                  htab->tls_get_addr))
6758                    offset = rel[1].r_offset;
6759                if ((tls_mask & tls_gd) != 0)                if ((tls_mask & tls_gd) != 0)
6760                  {                  {
6761                    /* IE */                    /* IE */
6762                      insn1 = bfd_get_32 (output_bfd,
6763                                          contents + rel->r_offset - d_offset);
6764                    insn1 &= (1 << 26) - 1;                    insn1 &= (1 << 26) - 1;
6765                    insn1 |= 32 << 26;    /* lwz */                    insn1 |= 32 << 26;    /* lwz */
6766                    insn2 = 0x7c631214;   /* add 3,3,2 */                    if (offset != (bfd_vma) -1)
6767                    rel[1].r_info                      {
6768                      = ELF32_R_INFO (ELF32_R_SYM (rel[1].r_info), R_PPC_NONE);                        rel[1].r_info
6769                    rel[1].r_addend = 0;                          = ELF32_R_INFO (ELF32_R_SYM (rel[1].r_info),
6770                                            R_PPC_NONE);
6771                          insn2 = 0x7c631214;       /* add 3,3,2 */
6772                          bfd_put_32 (output_bfd, insn2, contents + offset);
6773                        }
6774                    r_type = (((r_type - (R_PPC_GOT_TLSGD16 & 3)) & 3)                    r_type = (((r_type - (R_PPC_GOT_TLSGD16 & 3)) & 3)
6775                              + R_PPC_GOT_TPREL16);                              + R_PPC_GOT_TPREL16);
6776                    rel->r_info = ELF32_R_INFO (r_symndx, r_type);                    rel->r_info = ELF32_R_INFO (r_symndx, r_type);
# Line 6348  ppc_elf_relocate_section (bfd *output_bf Line 6779  ppc_elf_relocate_section (bfd *output_bf
6779                  {                  {
6780                    /* LE */                    /* LE */
6781                    insn1 = 0x3c620000;   /* addis 3,2,0 */                    insn1 = 0x3c620000;   /* addis 3,2,0 */
                   insn2 = 0x38630000;   /* addi 3,3,0 */  
6782                    if (tls_gd == 0)                    if (tls_gd == 0)
6783                      {                      {
6784                        /* Was an LD reloc.  */                        /* Was an LD reloc.  */
# Line 6367  ppc_elf_relocate_section (bfd *output_bf Line 6797  ppc_elf_relocate_section (bfd *output_bf
6797                      }                      }
6798                    r_type = R_PPC_TPREL16_HA;                    r_type = R_PPC_TPREL16_HA;
6799                    rel->r_info = ELF32_R_INFO (r_symndx, r_type);                    rel->r_info = ELF32_R_INFO (r_symndx, r_type);
6800                    rel[1].r_info = ELF32_R_INFO (r_symndx,                    if (offset != (bfd_vma) -1)
6801                                                  R_PPC_TPREL16_LO);                      {
6802                    rel[1].r_offset += d_offset;                        rel[1].r_info = ELF32_R_INFO (r_symndx, R_PPC_TPREL16_LO);
6803                    rel[1].r_addend = rel->r_addend;                        rel[1].r_offset = offset + d_offset;
6804                          rel[1].r_addend = rel->r_addend;
6805                          insn2 = 0x38630000;       /* addi 3,3,0 */
6806                          bfd_put_32 (output_bfd, insn2, contents + offset);
6807                        }
6808                  }                  }
6809                bfd_put_32 (output_bfd, insn1,                bfd_put_32 (output_bfd, insn1,
6810                            contents + rel->r_offset - d_offset);                            contents + rel->r_offset - d_offset);
               bfd_put_32 (output_bfd, insn2, contents + offset);  
6811                if (tls_gd == 0)                if (tls_gd == 0)
6812                  {                  {
6813                    /* We changed the symbol on an LD reloc.  Start over                    /* We changed the symbol on an LD reloc.  Start over
# Line 6384  ppc_elf_relocate_section (bfd *output_bf Line 6817  ppc_elf_relocate_section (bfd *output_bf
6817                  }                  }
6818              }              }
6819            break;            break;
6820    
6821            case R_PPC_TLSGD:
6822              if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_GD) == 0)
6823                {
6824                  unsigned int insn2;
6825                  bfd_vma offset = rel->r_offset;
6826    
6827                  if ((tls_mask & TLS_TPRELGD) != 0)
6828                    {
6829                      /* IE */
6830                      r_type = R_PPC_NONE;
6831                      insn2 = 0x7c631214;   /* add 3,3,2 */
6832                    }
6833                  else
6834                    {
6835                      /* LE */
6836                      r_type = R_PPC_TPREL16_LO;
6837                      rel->r_offset += d_offset;
6838                      insn2 = 0x38630000;   /* addi 3,3,0 */
6839                    }
6840                  rel->r_info = ELF32_R_INFO (r_symndx, r_type);
6841                  bfd_put_32 (output_bfd, insn2, contents + offset);
6842                  /* Zap the reloc on the _tls_get_addr call too.  */
6843                  BFD_ASSERT (offset == rel[1].r_offset);
6844                  rel[1].r_info = ELF32_R_INFO (ELF32_R_SYM (rel[1].r_info),
6845                                                R_PPC_NONE);
6846                }
6847              break;
6848    
6849            case R_PPC_TLSLD:
6850              if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_LD) == 0)
6851                {
6852                  unsigned int insn2;
6853    
6854                  for (r_symndx = 0;
6855                       r_symndx < symtab_hdr->sh_info;
6856                       r_symndx++)
6857                    if (local_sections[r_symndx] == sec)
6858                      break;
6859                  if (r_symndx >= symtab_hdr->sh_info)
6860                    r_symndx = 0;
6861                  rel->r_addend = htab->elf.tls_sec->vma + DTP_OFFSET;
6862                  if (r_symndx != 0)
6863                    rel->r_addend -= (local_syms[r_symndx].st_value
6864                                      + sec->output_offset
6865                                      + sec->output_section->vma);
6866    
6867                  rel->r_info = ELF32_R_INFO (r_symndx, R_PPC_TPREL16_LO);
6868                  rel->r_offset += d_offset;
6869                  insn2 = 0x38630000;       /* addi 3,3,0 */
6870                  bfd_put_32 (output_bfd, insn2,
6871                              contents + rel->r_offset - d_offset);
6872                  /* Zap the reloc on the _tls_get_addr call too.  */
6873                  BFD_ASSERT (rel->r_offset - d_offset == rel[1].r_offset);
6874                  rel[1].r_info = ELF32_R_INFO (ELF32_R_SYM (rel[1].r_info),
6875                                                R_PPC_NONE);
6876                  rel--;
6877                  continue;
6878                }
6879              break;
6880          }          }
6881    
6882        /* Handle other relocations that tweak non-addend part of insn.  */        /* Handle other relocations that tweak non-addend part of insn.  */
# Line 6418  ppc_elf_relocate_section (bfd *output_bf Line 6911  ppc_elf_relocate_section (bfd *output_bf
6911            break;            break;
6912          }          }
6913    
6914          ifunc = NULL;
6915          if (!htab->is_vxworks && is_branch_reloc (r_type))
6916            {
6917              if (h != NULL)
6918                {
6919                  if (h->type == STT_GNU_IFUNC)
6920                    ifunc = &h->plt.plist;
6921                }
6922              else if (local_got_offsets != NULL)
6923                {
6924                  if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
6925                    {
6926                      struct plt_entry **local_plt = (struct plt_entry **)
6927                        (local_got_offsets + symtab_hdr->sh_info);
6928    
6929                      ifunc = local_plt + r_symndx;
6930                    }
6931                }
6932              if (ifunc != NULL)
6933                {
6934                  struct plt_entry *ent = find_plt_ent (ifunc, got2, rel->r_addend);
6935    
6936                  if (h == NULL && (ent->plt.offset & 1) == 0)
6937                    {
6938                      Elf_Internal_Rela rela;
6939                      bfd_byte *loc;
6940    
6941                      rela.r_offset = (htab->iplt->output_section->vma
6942                                       + htab->iplt->output_offset
6943                                       + ent->plt.offset);
6944                      rela.r_info = ELF32_R_INFO (0, R_PPC_IRELATIVE);
6945                      rela.r_addend = relocation;
6946                      loc = (htab->reliplt->contents
6947                             + ent->plt.offset * sizeof (Elf32_External_Rela) / 4);
6948                      bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
6949    
6950                      ent->plt.offset |= 1;
6951                    }
6952                  if (h == NULL && (ent->glink_offset & 1) == 0)
6953                    {
6954                      write_glink_stub (ent, htab->iplt, info);
6955                      ent->glink_offset |= 1;
6956                    }
6957    
6958                  unresolved_reloc = FALSE;
6959                  if (htab->plt_type == PLT_NEW
6960                      || !htab->elf.dynamic_sections_created
6961                      || h == NULL)
6962                    relocation = (htab->glink->output_section->vma
6963                                  + htab->glink->output_offset
6964                                  + (ent->glink_offset & ~1));
6965                  else
6966                    relocation = (htab->plt->output_section->vma
6967                                  + htab->plt->output_offset
6968                                  + ent->plt.offset);
6969                }
6970            }
6971    
6972        addend = rel->r_addend;        addend = rel->r_addend;
6973        tls_type = 0;        tls_type = 0;
6974        howto = NULL;        howto = NULL;
# Line 6436  ppc_elf_relocate_section (bfd *output_bf Line 6987  ppc_elf_relocate_section (bfd *output_bf
6987    
6988          case R_PPC_NONE:          case R_PPC_NONE:
6989          case R_PPC_TLS:          case R_PPC_TLS:
6990            case R_PPC_TLSGD:
6991            case R_PPC_TLSLD:
6992          case R_PPC_EMB_MRKREF:          case R_PPC_EMB_MRKREF:
6993          case R_PPC_GNU_VTINHERIT:          case R_PPC_GNU_VTINHERIT:
6994          case R_PPC_GNU_VTENTRY:          case R_PPC_GNU_VTENTRY:
# Line 6477  ppc_elf_relocate_section (bfd *output_bf Line 7030  ppc_elf_relocate_section (bfd *output_bf
7030          case R_PPC_GOT16_LO:          case R_PPC_GOT16_LO:
7031          case R_PPC_GOT16_HI:          case R_PPC_GOT16_HI:
7032          case R_PPC_GOT16_HA:          case R_PPC_GOT16_HA:
7033              tls_mask = 0;
7034          dogot:          dogot:
7035            {            {
7036              /* Relocation is to the entry for this symbol in the global              /* Relocation is to the entry for this symbol in the global
# Line 6908  ppc_elf_relocate_section (bfd *output_bf Line 7462  ppc_elf_relocate_section (bfd *output_bf
7462          case R_PPC_RELAX32PC_PLT:          case R_PPC_RELAX32PC_PLT:
7463          case R_PPC_RELAX32_PLT:          case R_PPC_RELAX32_PLT:
7464            {            {
7465              struct plt_entry *ent = find_plt_ent (h, got2, addend);              struct plt_entry *ent = find_plt_ent (&h->plt.plist, got2, addend);
7466    
7467              if (htab->plt_type == PLT_NEW)              if (htab->plt_type == PLT_NEW)
7468                relocation = (htab->glink->output_section->vma                relocation = (htab->glink->output_section->vma
# Line 6950  ppc_elf_relocate_section (bfd *output_bf Line 7504  ppc_elf_relocate_section (bfd *output_bf
7504    
7505              bfd_put_32 (output_bfd, t0, contents + rel->r_offset);              bfd_put_32 (output_bfd, t0, contents + rel->r_offset);
7506              bfd_put_32 (output_bfd, t1, contents + rel->r_offset + 4);              bfd_put_32 (output_bfd, t1, contents + rel->r_offset + 4);
7507    
7508                /* Rewrite the reloc and convert one of the trailing nop
7509                   relocs to describe this relocation.  */
7510                BFD_ASSERT (ELF32_R_TYPE (relend[-1].r_info) == R_PPC_NONE);
7511                /* The relocs are at the bottom 2 bytes */
7512                rel[0].r_offset += 2;
7513                memmove (rel + 1, rel, (relend - rel - 1) * sizeof (*rel));
7514                rel[0].r_info = ELF32_R_INFO (r_symndx, R_PPC_ADDR16_HA);
7515                rel[1].r_offset += 4;
7516                rel[1].r_info = ELF32_R_INFO (r_symndx, R_PPC_ADDR16_LO);
7517                rel++;
7518            }            }
7519            continue;            continue;
7520    
# Line 6986  ppc_elf_relocate_section (bfd *output_bf Line 7551  ppc_elf_relocate_section (bfd *output_bf
7551            break;            break;
7552    
7553          case R_PPC_PLTREL24:          case R_PPC_PLTREL24:
7554              if (h == NULL || ifunc != NULL)
7555                break;
7556            /* Relocation is to the entry for this symbol in the            /* Relocation is to the entry for this symbol in the
7557               procedure linkage table.  */               procedure linkage table.  */
7558            {            {
7559              struct plt_entry *ent = find_plt_ent (h, got2, addend);              struct plt_entry *ent = find_plt_ent (&h->plt.plist, got2, addend);
7560    
7561              addend = 0;              addend = 0;
7562              if (ent == NULL              if (ent == NULL
# Line 7156  ppc_elf_relocate_section (bfd *output_bf Line 7723  ppc_elf_relocate_section (bfd *output_bf
7723          case R_PPC_GLOB_DAT:          case R_PPC_GLOB_DAT:
7724          case R_PPC_JMP_SLOT:          case R_PPC_JMP_SLOT:
7725          case R_PPC_RELATIVE:          case R_PPC_RELATIVE:
7726            case R_PPC_IRELATIVE:
7727          case R_PPC_PLT32:          case R_PPC_PLT32:
7728          case R_PPC_PLTREL32:          case R_PPC_PLTREL32:
7729          case R_PPC_PLT16_LO:          case R_PPC_PLT16_LO:
# Line 7291  ppc_elf_relocate_section (bfd *output_bf Line 7859  ppc_elf_relocate_section (bfd *output_bf
7859    return ret;    return ret;
7860  }  }
7861    
 #define PPC_LO(v) ((v) & 0xffff)  
 #define PPC_HI(v) (((v) >> 16) & 0xffff)  
 #define PPC_HA(v) PPC_HI ((v) + 0x8000)  
   
7862  /* Finish up dynamic symbol handling.  We set the contents of various  /* Finish up dynamic symbol handling.  We set the contents of various
7863     dynamic sections here.  */     dynamic sections here.  */
7864    
# Line 7326  ppc_elf_finish_dynamic_symbol (bfd *outp Line 7890  ppc_elf_finish_dynamic_symbol (bfd *outp
7890              bfd_byte *loc;              bfd_byte *loc;
7891              bfd_vma reloc_index;              bfd_vma reloc_index;
7892    
7893              if (htab->plt_type == PLT_NEW)              if (htab->plt_type == PLT_NEW
7894                    || !htab->elf.dynamic_sections_created)
7895                reloc_index = ent->plt.offset / 4;                reloc_index = ent->plt.offset / 4;
7896              else              else
7897                {                {
# Line 7339  ppc_elf_finish_dynamic_symbol (bfd *outp Line 7904  ppc_elf_finish_dynamic_symbol (bfd *outp
7904    
7905              /* This symbol has an entry in the procedure linkage table.              /* This symbol has an entry in the procedure linkage table.
7906                 Set it up.  */                 Set it up.  */
7907              if (htab->plt_type == PLT_VXWORKS)              if (htab->plt_type == PLT_VXWORKS
7908                    && htab->elf.dynamic_sections_created)
7909                {                {
7910                  bfd_vma got_offset;                  bfd_vma got_offset;
7911                  const bfd_vma *plt_entry;                  const bfd_vma *plt_entry;
# Line 7461  ppc_elf_finish_dynamic_symbol (bfd *outp Line 8027  ppc_elf_finish_dynamic_symbol (bfd *outp
8027                }                }
8028              else              else
8029                {                {
8030                  rela.r_offset = (htab->plt->output_section->vma                  asection *splt = htab->plt;
8031                                   + htab->plt->output_offset                  if (!htab->elf.dynamic_sections_created)
8032                      splt = htab->iplt;
8033    
8034                    rela.r_offset = (splt->output_section->vma
8035                                     + splt->output_offset
8036                                   + ent->plt.offset);                                   + ent->plt.offset);
8037                  if (htab->plt_type == PLT_OLD)                  if (htab->plt_type == PLT_OLD
8038                        || !htab->elf.dynamic_sections_created)
8039                    {                    {
8040                      /* We don't need to fill in the .plt.  The ppc dynamic                      /* We don't need to fill in the .plt.  The ppc dynamic
8041                         linker will fill it in.  */                         linker will fill it in.  */
# Line 7475  ppc_elf_finish_dynamic_symbol (bfd *outp Line 8046  ppc_elf_finish_dynamic_symbol (bfd *outp
8046                                     + htab->glink->output_section->vma                                     + htab->glink->output_section->vma
8047                                     + htab->glink->output_offset);                                     + htab->glink->output_offset);
8048                      bfd_put_32 (output_bfd, val,                      bfd_put_32 (output_bfd, val,
8049                                  htab->plt->contents + ent->plt.offset);                                  splt->contents + ent->plt.offset);
8050                    }                    }
8051                }                }
8052    
8053              /* Fill in the entry in the .rela.plt section.  */              /* Fill in the entry in the .rela.plt section.  */
             rela.r_info = ELF32_R_INFO (h->dynindx, R_PPC_JMP_SLOT);  
8054              rela.r_addend = 0;              rela.r_addend = 0;
8055                if (!htab->elf.dynamic_sections_created
8056                    || h->dynindx == -1)
8057                  {
8058                    BFD_ASSERT (h->type == STT_GNU_IFUNC
8059                                && h->def_regular
8060                                && (h->root.type == bfd_link_hash_defined
8061                                    || h->root.type == bfd_link_hash_defweak));
8062                    rela.r_info = ELF32_R_INFO (0, R_PPC_IRELATIVE);
8063                    rela.r_addend = SYM_VAL (h);
8064                  }
8065                else
8066                  rela.r_info = ELF32_R_INFO (h->dynindx, R_PPC_JMP_SLOT);
8067    
8068              loc = (htab->relplt->contents              if (!htab->elf.dynamic_sections_created)
8069                     + reloc_index * sizeof (Elf32_External_Rela));                loc = htab->reliplt->contents;
8070                else
8071                  loc = htab->relplt->contents;
8072                loc += reloc_index * sizeof (Elf32_External_Rela);
8073              bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);              bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
8074    
8075              if (!h->def_regular)              if (!h->def_regular)
# Line 7510  ppc_elf_finish_dynamic_symbol (bfd *outp Line 8095  ppc_elf_finish_dynamic_symbol (bfd *outp
8095              doneone = TRUE;              doneone = TRUE;
8096            }            }
8097    
8098          if (htab->plt_type == PLT_NEW)          if (htab->plt_type == PLT_NEW
8099                || !htab->elf.dynamic_sections_created)
8100            {            {
8101              bfd_vma plt;              asection *splt = htab->plt;
8102              unsigned char *p;              if (!htab->elf.dynamic_sections_created)
8103                  splt = htab->iplt;
8104    
8105              plt = (ent->plt.offset              write_glink_stub (ent, splt, info);
                    + htab->plt->output_section->vma  
                    + htab->plt->output_offset);  
             p = (unsigned char *) htab->glink->contents + ent->glink_offset;  
8106    
8107              if (info->shared || info->pie)              if (!info->shared && !info->pie)
8108                {                /* We only need one non-PIC glink stub.  */
8109                  bfd_vma got = 0;                break;
   
                 if (ent->addend >= 32768)  
                   got = (ent->addend  
                          + ent->sec->output_section->vma  
                          + ent->sec->output_offset);  
                 else if (htab->elf.hgot != NULL)  
                   got = SYM_VAL (htab->elf.hgot);  
   
                 plt -= got;  
   
                 if (plt + 0x8000 < 0x10000)  
                   {  
                     bfd_put_32 (output_bfd, LWZ_11_30 + PPC_LO (plt), p);  
                     p += 4;  
                     bfd_put_32 (output_bfd, MTCTR_11, p);  
                     p += 4;  
                     bfd_put_32 (output_bfd, BCTR, p);  
                     p += 4;  
                     bfd_put_32 (output_bfd, NOP, p);  
                     p += 4;  
                   }  
                 else  
                   {  
                     bfd_put_32 (output_bfd, ADDIS_11_30 + PPC_HA (plt), p);  
                     p += 4;  
                     bfd_put_32 (output_bfd, LWZ_11_11 + PPC_LO (plt), p);  
                     p += 4;  
                     bfd_put_32 (output_bfd, MTCTR_11, p);  
                     p += 4;  
                     bfd_put_32 (output_bfd, BCTR, p);  
                     p += 4;  
                   }  
               }  
             else  
               {  
                 bfd_put_32 (output_bfd, LIS_11 + PPC_HA (plt), p);  
                 p += 4;  
                 bfd_put_32 (output_bfd, LWZ_11_11 + PPC_LO (plt), p);  
                 p += 4;  
                 bfd_put_32 (output_bfd, MTCTR_11, p);  
                 p += 4;  
                 bfd_put_32 (output_bfd, BCTR, p);  
                 p += 4;  
   
                 /* We only need one non-PIC glink stub.  */  
                 break;  
               }  
8110            }            }
8111          else          else
8112            break;            break;
# Line 7840  ppc_elf_finish_dynamic_sections (bfd *ou Line 8377  ppc_elf_finish_dynamic_sections (bfd *ou
8377          }          }
8378      }      }
8379    
8380    if (htab->glink != NULL && htab->glink->contents != NULL)    if (htab->glink != NULL
8381          && htab->glink->contents != NULL
8382          && htab->elf.dynamic_sections_created)
8383      {      {
8384        unsigned char *p;        unsigned char *p;
8385        unsigned char *endp;        unsigned char *endp;
# Line 8107  ppc_elf_finish_dynamic_sections (bfd *ou Line 8646  ppc_elf_finish_dynamic_sections (bfd *ou
8646  #define elf_backend_plt_sym_val                 ppc_elf_plt_sym_val  #define elf_backend_plt_sym_val                 ppc_elf_plt_sym_val
8647  #define elf_backend_action_discarded            ppc_elf_action_discarded  #define elf_backend_action_discarded            ppc_elf_action_discarded
8648  #define elf_backend_init_index_section          _bfd_elf_init_1_index_section  #define elf_backend_init_index_section          _bfd_elf_init_1_index_section
8649    #define elf_backend_post_process_headers        _bfd_elf_set_osabi
8650    
8651  #include "elf32-target.h"  #include "elf32-target.h"
8652    
# Line 8216  ppc_elf_vxworks_final_write_processing ( Line 8756  ppc_elf_vxworks_final_write_processing (
8756    
8757  #undef elf32_bed  #undef elf32_bed
8758  #define elf32_bed                               ppc_elf_vxworks_bed  #define elf32_bed                               ppc_elf_vxworks_bed
8759    #undef elf_backend_post_process_headers
8760    
8761  #include "elf32-target.h"  #include "elf32-target.h"

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