Deleted Added
full compact
749c749
< /* Marker reloc for TLS. */
---
> /* Marker relocs for TLS. */
763a764,791
> HOWTO (R_PPC_TLSGD,
> 0, /* rightshift */
> 2, /* size (0 = byte, 1 = short, 2 = long) */
> 32, /* bitsize */
> FALSE, /* pc_relative */
> 0, /* bitpos */
> complain_overflow_dont, /* complain_on_overflow */
> bfd_elf_generic_reloc, /* special_function */
> "R_PPC_TLSGD", /* name */
> FALSE, /* partial_inplace */
> 0, /* src_mask */
> 0, /* dst_mask */
> FALSE), /* pcrel_offset */
>
> HOWTO (R_PPC_TLSLD,
> 0, /* rightshift */
> 2, /* size (0 = byte, 1 = short, 2 = long) */
> 32, /* bitsize */
> FALSE, /* pc_relative */
> 0, /* bitpos */
> complain_overflow_dont, /* complain_on_overflow */
> bfd_elf_generic_reloc, /* special_function */
> "R_PPC_TLSLD", /* name */
> FALSE, /* partial_inplace */
> 0, /* src_mask */
> 0, /* dst_mask */
> FALSE), /* pcrel_offset */
>
1526a1555,1556
> case BFD_RELOC_PPC_TLSGD: r = R_PPC_TLSGD; break;
> case BFD_RELOC_PPC_TLSLD: r = R_PPC_TLSLD; break;
2348c2378
< /* Of those relocs that might be copied as dynamic relocs, this macro
---
> /* Of those relocs that might be copied as dynamic relocs, this function
2352,2357c2382,2389
< #define MUST_BE_DYN_RELOC(RTYPE) \
< ((RTYPE) != R_PPC_REL24 \
< && (RTYPE) != R_PPC_REL14 \
< && (RTYPE) != R_PPC_REL14_BRTAKEN \
< && (RTYPE) != R_PPC_REL14_BRNTAKEN \
< && (RTYPE) != R_PPC_REL32)
---
> static int
> must_be_dyn_reloc (struct bfd_link_info *info,
> enum elf_ppc_reloc_type r_type)
> {
> switch (r_type)
> {
> default:
> return 1;
2358a2391,2406
> case R_PPC_REL24:
> case R_PPC_REL14:
> case R_PPC_REL14_BRTAKEN:
> case R_PPC_REL14_BRNTAKEN:
> case R_PPC_REL32:
> return 0;
>
> case R_PPC_TPREL32:
> case R_PPC_TPREL16:
> case R_PPC_TPREL16_LO:
> case R_PPC_TPREL16_HI:
> case R_PPC_TPREL16_HA:
> return !info->executable;
> }
> }
>
2424c2472
< /* Shortcut to .__tls_get_addr. */
---
> /* Shortcut to __tls_get_addr. */
3042a3091
> struct elf_link_hash_entry *tga;
3065a3115,3116
> tga = elf_link_hash_lookup (&htab->elf, "__tls_get_addr",
> FALSE, FALSE, TRUE);
3077c3128
< int tls_type = 0;
---
> int tls_type;
3103a3155
> tls_type = 0;
3104a3157,3184
> if (h != NULL && h == tga)
> switch (r_type)
> {
> default:
> break;
>
> case R_PPC_PLTREL24:
> case R_PPC_LOCAL24PC:
> case R_PPC_REL24:
> case R_PPC_REL14:
> case R_PPC_REL14_BRTAKEN:
> case R_PPC_REL14_BRNTAKEN:
> case R_PPC_ADDR24:
> case R_PPC_ADDR14:
> case R_PPC_ADDR14_BRTAKEN:
> case R_PPC_ADDR14_BRNTAKEN:
> if (rel != relocs
> && (ELF32_R_TYPE (rel[-1].r_info) == R_PPC_TLSGD
> || ELF32_R_TYPE (rel[-1].r_info) == R_PPC_TLSLD))
> /* We have a new-style __tls_get_addr call with a marker
> reloc. */
> ;
> else
> /* Mark this section as having an old-style call. */
> sec->has_tls_get_addr_call = 1;
> break;
> }
>
3106a3187,3192
> case R_PPC_TLSGD:
> case R_PPC_TLSLD:
> /* These special tls relocs tie a call to __tls_get_addr with
> its parameter symbol. */
> break;
>
3111d3196
< htab->tlsld_got.refcount += 1;
3126c3211
< if (info->shared)
---
> if (!info->executable)
3361c3446
< if (h && h == htab->elf.hgot && htab->plt_type == PLT_UNSET)
---
> if (h != NULL && h == htab->elf.hgot && htab->plt_type == PLT_UNSET)
3384c3469,3473
< if (info->shared)
---
> case R_PPC_TPREL16:
> case R_PPC_TPREL16_LO:
> case R_PPC_TPREL16_HI:
> case R_PPC_TPREL16_HA:
> if (!info->executable)
3393,3400d3481
< case R_PPC_TPREL16:
< case R_PPC_TPREL16_LO:
< case R_PPC_TPREL16_HI:
< case R_PPC_TPREL16_HA:
< if (info->shared)
< info->flags |= DF_STATIC_TLS;
< goto dodyn;
<
3491c3572
< && (MUST_BE_DYN_RELOC (r_type)
---
> && (must_be_dyn_reloc (info, r_type)
3586c3667
< if (!MUST_BE_DYN_RELOC (r_type))
---
> if (!must_be_dyn_reloc (info, r_type))
3906,3908d3986
< htab->tlsld_got.refcount -= 1;
< /* Fall thru */
<
3982c4060,4061
< /* 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
> generic ELF tls_setup function. */
4002a4082,4118
> /* Return TRUE iff REL is a branch reloc with a global symbol matching
> HASH. */
>
> static bfd_boolean
> branch_reloc_hash_match (const bfd *ibfd,
> const Elf_Internal_Rela *rel,
> const struct elf_link_hash_entry *hash)
> {
> Elf_Internal_Shdr *symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
> enum elf_ppc_reloc_type r_type = ELF32_R_TYPE (rel->r_info);
> unsigned int r_symndx = ELF32_R_SYM (rel->r_info);
>
> if (r_symndx >= symtab_hdr->sh_info
> && (r_type == R_PPC_PLTREL24
> || r_type == R_PPC_LOCAL24PC
> || r_type == R_PPC_REL14
> || r_type == R_PPC_REL14_BRTAKEN
> || r_type == R_PPC_REL14_BRNTAKEN
> || r_type == R_PPC_REL24
> || r_type == R_PPC_ADDR24
> || r_type == R_PPC_ADDR14
> || r_type == R_PPC_ADDR14_BRTAKEN
> || r_type == R_PPC_ADDR14_BRNTAKEN))
> {
> struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (ibfd);
> struct elf_link_hash_entry *h;
>
> h = sym_hashes[r_symndx - symtab_hdr->sh_info];
> while (h->root.type == bfd_link_hash_indirect
> || h->root.type == bfd_link_hash_warning)
> h = (struct elf_link_hash_entry *) h->root.u.i.link;
> if (h == hash)
> return TRUE;
> }
> return FALSE;
> }
>
4012a4129
> int pass;
4014c4131
< if (info->relocatable || info->shared)
---
> if (info->relocatable || !info->executable)
4018,4021c4135,4143
< for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
< {
< Elf_Internal_Sym *locsyms = NULL;
< Elf_Internal_Shdr *symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
---
> /* Make two passes through the relocs. First time check that tls
> relocs involved in setting up a tls_get_addr call are indeed
> followed by such a call. If they are not, exclude them from
> the optimizations done on the second pass. */
> for (pass = 0; pass < 2; ++pass)
> for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
> {
> Elf_Internal_Sym *locsyms = NULL;
> Elf_Internal_Shdr *symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
4023,4027c4145,4148
< for (sec = ibfd->sections; sec != NULL; sec = sec->next)
< if (sec->has_tls_reloc && !bfd_is_abs_section (sec->output_section))
< {
< Elf_Internal_Rela *relstart, *rel, *relend;
< int expecting_tls_get_addr;
---
> for (sec = ibfd->sections; sec != NULL; sec = sec->next)
> if (sec->has_tls_reloc && !bfd_is_abs_section (sec->output_section))
> {
> Elf_Internal_Rela *relstart, *rel, *relend;
4029,4033c4150,4154
< /* Read the relocations. */
< relstart = _bfd_elf_link_read_relocs (ibfd, sec, NULL, NULL,
< info->keep_memory);
< if (relstart == NULL)
< return FALSE;
---
> /* Read the relocations. */
> relstart = _bfd_elf_link_read_relocs (ibfd, sec, NULL, NULL,
> info->keep_memory);
> if (relstart == NULL)
> return FALSE;
4035,4044c4156,4166
< expecting_tls_get_addr = 0;
< relend = relstart + sec->reloc_count;
< for (rel = relstart; rel < relend; rel++)
< {
< enum elf_ppc_reloc_type r_type;
< unsigned long r_symndx;
< struct elf_link_hash_entry *h = NULL;
< char *tls_mask;
< char tls_set, tls_clear;
< bfd_boolean is_local;
---
> relend = relstart + sec->reloc_count;
> for (rel = relstart; rel < relend; rel++)
> {
> enum elf_ppc_reloc_type r_type;
> unsigned long r_symndx;
> struct elf_link_hash_entry *h = NULL;
> char *tls_mask;
> char tls_set, tls_clear;
> bfd_boolean is_local;
> int expecting_tls_get_addr;
> bfd_signed_vma *got_count;
4046,4049c4168,4171
< r_symndx = ELF32_R_SYM (rel->r_info);
< if (r_symndx >= symtab_hdr->sh_info)
< {
< struct elf_link_hash_entry **sym_hashes;
---
> r_symndx = ELF32_R_SYM (rel->r_info);
> if (r_symndx >= symtab_hdr->sh_info)
> {
> struct elf_link_hash_entry **sym_hashes;
4051,4056c4173,4178
< sym_hashes = elf_sym_hashes (ibfd);
< h = sym_hashes[r_symndx - symtab_hdr->sh_info];
< while (h->root.type == bfd_link_hash_indirect
< || h->root.type == bfd_link_hash_warning)
< h = (struct elf_link_hash_entry *) h->root.u.i.link;
< }
---
> sym_hashes = elf_sym_hashes (ibfd);
> h = sym_hashes[r_symndx - symtab_hdr->sh_info];
> while (h->root.type == bfd_link_hash_indirect
> || h->root.type == bfd_link_hash_warning)
> h = (struct elf_link_hash_entry *) h->root.u.i.link;
> }
4058,4061c4180,4184
< is_local = FALSE;
< if (h == NULL
< || !h->def_dynamic)
< is_local = TRUE;
---
> expecting_tls_get_addr = 0;
> is_local = FALSE;
> if (h == NULL
> || !h->def_dynamic)
> is_local = TRUE;
4063,4076c4186,4192
< r_type = ELF32_R_TYPE (rel->r_info);
< switch (r_type)
< {
< case R_PPC_GOT_TLSLD16:
< case R_PPC_GOT_TLSLD16_LO:
< case R_PPC_GOT_TLSLD16_HI:
< case R_PPC_GOT_TLSLD16_HA:
< /* These relocs should never be against a symbol
< defined in a shared lib. Leave them alone if
< that turns out to be the case. */
< expecting_tls_get_addr = 0;
< htab->tlsld_got.refcount -= 1;
< if (!is_local)
< continue;
---
> r_type = ELF32_R_TYPE (rel->r_info);
> switch (r_type)
> {
> case R_PPC_GOT_TLSLD16:
> case R_PPC_GOT_TLSLD16_LO:
> expecting_tls_get_addr = 1;
> /* Fall thru */
4078,4082c4194,4200
< /* LD -> LE */
< tls_set = 0;
< tls_clear = TLS_LD;
< expecting_tls_get_addr = 1;
< break;
---
> case R_PPC_GOT_TLSLD16_HI:
> case R_PPC_GOT_TLSLD16_HA:
> /* These relocs should never be against a symbol
> defined in a shared lib. Leave them alone if
> that turns out to be the case. */
> if (!is_local)
> continue;
4084,4089c4202
< case R_PPC_GOT_TLSGD16:
< case R_PPC_GOT_TLSGD16_LO:
< case R_PPC_GOT_TLSGD16_HI:
< case R_PPC_GOT_TLSGD16_HA:
< if (is_local)
< /* GD -> LE */
---
> /* LD -> LE */
4091,4096c4204,4205
< else
< /* GD -> IE */
< tls_set = TLS_TLS | TLS_TPRELGD;
< tls_clear = TLS_GD;
< expecting_tls_get_addr = 1;
< break;
---
> tls_clear = TLS_LD;
> break;
4098,4105c4207,4215
< case R_PPC_GOT_TPREL16:
< case R_PPC_GOT_TPREL16_LO:
< case R_PPC_GOT_TPREL16_HI:
< case R_PPC_GOT_TPREL16_HA:
< expecting_tls_get_addr = 0;
< if (is_local)
< {
< /* IE -> LE */
---
> case R_PPC_GOT_TLSGD16:
> case R_PPC_GOT_TLSGD16_LO:
> expecting_tls_get_addr = 1;
> /* Fall thru */
>
> case R_PPC_GOT_TLSGD16_HI:
> case R_PPC_GOT_TLSGD16_HA:
> if (is_local)
> /* GD -> LE */
4107,4110c4217,4237
< tls_clear = TLS_TPREL;
< break;
< }
< else
---
> else
> /* GD -> IE */
> tls_set = TLS_TLS | TLS_TPRELGD;
> tls_clear = TLS_GD;
> break;
>
> case R_PPC_GOT_TPREL16:
> case R_PPC_GOT_TPREL16_LO:
> case R_PPC_GOT_TPREL16_HI:
> case R_PPC_GOT_TPREL16_HA:
> if (is_local)
> {
> /* IE -> LE */
> tls_set = 0;
> tls_clear = TLS_TPREL;
> break;
> }
> else
> continue;
>
> default:
4111a4239
> }
4113,4126c4241,4245
< case R_PPC_REL14:
< case R_PPC_REL14_BRTAKEN:
< case R_PPC_REL14_BRNTAKEN:
< case R_PPC_REL24:
< if (expecting_tls_get_addr
< && h != NULL
< && h == htab->tls_get_addr)
< {
< struct plt_entry *ent = find_plt_ent (h, NULL, 0);
< if (ent != NULL && ent->plt.refcount > 0)
< ent->plt.refcount -= 1;
< }
< expecting_tls_get_addr = 0;
< continue;
---
> if (pass == 0)
> {
> if (!expecting_tls_get_addr
> || !sec->has_tls_get_addr_call)
> continue;
4128,4131c4247,4250
< default:
< expecting_tls_get_addr = 0;
< continue;
< }
---
> if (rel + 1 < relend
> && branch_reloc_hash_match (ibfd, rel + 1,
> htab->tls_get_addr))
> continue;
4133,4147c4252,4258
< if (h != NULL)
< {
< if (tls_set == 0)
< {
< /* We managed to get rid of a got entry. */
< if (h->got.refcount > 0)
< h->got.refcount -= 1;
< }
< tls_mask = &ppc_elf_hash_entry (h)->tls_mask;
< }
< else
< {
< Elf_Internal_Sym *sym;
< bfd_signed_vma *lgot_refs;
< char *lgot_masks;
---
> /* Uh oh, we didn't find the expected call. We
> could just mark this symbol to exclude it
> from tls optimization but it's safer to skip
> the entire section. */
> sec->has_tls_reloc = 0;
> break;
> }
4149,4175c4260,4269
< if (locsyms == NULL)
< {
< locsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
< if (locsyms == NULL)
< locsyms = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
< symtab_hdr->sh_info,
< 0, NULL, NULL, NULL);
< if (locsyms == NULL)
< {
< if (elf_section_data (sec)->relocs != relstart)
< free (relstart);
< return FALSE;
< }
< }
< sym = locsyms + r_symndx;
< lgot_refs = elf_local_got_refcounts (ibfd);
< if (lgot_refs == NULL)
< abort ();
< if (tls_set == 0)
< {
< /* We managed to get rid of a got entry. */
< if (lgot_refs[r_symndx] > 0)
< lgot_refs[r_symndx] -= 1;
< }
< lgot_masks = (char *) (lgot_refs + symtab_hdr->sh_info);
< tls_mask = &lgot_masks[r_symndx];
< }
---
> if (h != NULL)
> {
> tls_mask = &ppc_elf_hash_entry (h)->tls_mask;
> got_count = &h->got.refcount;
> }
> else
> {
> Elf_Internal_Sym *sym;
> bfd_signed_vma *lgot_refs;
> char *lgot_masks;
4177,4179c4271,4292
< *tls_mask |= tls_set;
< *tls_mask &= ~tls_clear;
< }
---
> if (locsyms == NULL)
> {
> locsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
> if (locsyms == NULL)
> locsyms = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
> symtab_hdr->sh_info,
> 0, NULL, NULL, NULL);
> if (locsyms == NULL)
> {
> if (elf_section_data (sec)->relocs != relstart)
> free (relstart);
> return FALSE;
> }
> }
> sym = locsyms + r_symndx;
> lgot_refs = elf_local_got_refcounts (ibfd);
> if (lgot_refs == NULL)
> abort ();
> lgot_masks = (char *) (lgot_refs + symtab_hdr->sh_info);
> tls_mask = &lgot_masks[r_symndx];
> got_count = &lgot_refs[r_symndx];
> }
4181,4183c4294,4299
< if (elf_section_data (sec)->relocs != relstart)
< free (relstart);
< }
---
> if (tls_set == 0)
> {
> /* We managed to get rid of a got entry. */
> if (*got_count > 0)
> *got_count -= 1;
> }
4185,4193c4301,4326
< if (locsyms != NULL
< && (symtab_hdr->contents != (unsigned char *) locsyms))
< {
< if (!info->keep_memory)
< free (locsyms);
< else
< symtab_hdr->contents = (unsigned char *) locsyms;
< }
< }
---
> if (expecting_tls_get_addr)
> {
> struct plt_entry *ent;
>
> ent = find_plt_ent (htab->tls_get_addr, NULL, 0);
> if (ent != NULL && ent->plt.refcount > 0)
> ent->plt.refcount -= 1;
> }
>
> *tls_mask |= tls_set;
> *tls_mask &= ~tls_clear;
> }
>
> if (elf_section_data (sec)->relocs != relstart)
> free (relstart);
> }
>
> if (locsyms != NULL
> && (symtab_hdr->contents != (unsigned char *) locsyms))
> {
> if (!info->keep_memory)
> free (locsyms);
> else
> symtab_hdr->contents = (unsigned char *) locsyms;
> }
> }
4618,4619c4751,4755
< /* If just an LD reloc, we'll just use htab->tlsld_got.offset. */
< eh->elf.got.offset = (bfd_vma) -1;
---
> {
> /* If just an LD reloc, we'll just use htab->tlsld_got.offset. */
> htab->tlsld_got.refcount += 1;
> eh->elf.got.offset = (bfd_vma) -1;
> }
4667c4803
< or certain REL relocs (see MUST_BE_DYN_RELOC) that can be
---
> or certain REL relocs (see must_be_dyn_reloc) that can be
4893a5030,5032
> /* Allocate space for global sym dynamic relocs. */
> elf_link_hash_traverse (elf_hash_table (info), allocate_dynrelocs, info);
>
4903,4905d5041
< /* Allocate space for global sym dynamic relocs. */
< elf_link_hash_traverse (elf_hash_table (info), allocate_dynrelocs, info);
<
5757c5893,5895
< if (IS_PPC_TLS_RELOC (r_type))
---
> if (h != NULL)
> tls_mask = ((struct ppc_elf_link_hash_entry *) h)->tls_mask;
> else if (local_got_offsets != NULL)
5759,5766c5897,5899
< if (h != NULL)
< tls_mask = ((struct ppc_elf_link_hash_entry *) h)->tls_mask;
< else if (local_got_offsets != NULL)
< {
< char *lgot_masks;
< lgot_masks = (char *) (local_got_offsets + symtab_hdr->sh_info);
< tls_mask = lgot_masks[r_symndx];
< }
---
> char *lgot_masks;
> lgot_masks = (char *) (local_got_offsets + symtab_hdr->sh_info);
> tls_mask = lgot_masks[r_symndx];
5873c6006
< goto tls_get_addr_check;
---
> goto tls_ldgd_opt;
5880,5887c6013,6014
< tls_get_addr_check:
< if (rel + 1 < relend)
< {
< enum elf_ppc_reloc_type r_type2;
< unsigned long r_symndx2;
< struct elf_link_hash_entry *h2;
< bfd_vma insn1, insn2;
< bfd_vma offset;
---
> unsigned int insn1, insn2;
> bfd_vma offset;
5889,5909c6016,6030
< /* 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))
< break;
<
< 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 == NULL || h2 != htab->tls_get_addr)
< break;
<
< /* OK, it checks out. Replace the call. */
< offset = rel[1].r_offset;
---
> tls_ldgd_opt:
> offset = (bfd_vma) -1;
> /* If not using the newer R_PPC_TLSGD/LD to mark
> __tls_get_addr calls, we must trust that the call
> stays with its arg setup insns, ie. that the next
> reloc is the __tls_get_addr call associated with
> the current reloc. Edit both insns. */
> if (input_section->has_tls_get_addr_call
> && rel + 1 < relend
> && branch_reloc_hash_match (input_bfd, rel + 1,
> htab->tls_get_addr))
> offset = rel[1].r_offset;
> if ((tls_mask & tls_gd) != 0)
> {
> /* IE */
5912c6033,6035
< if ((tls_mask & tls_gd) != 0)
---
> insn1 &= (1 << 26) - 1;
> insn1 |= 32 << 26; /* lwz */
> if (offset != (bfd_vma) -1)
5914,5916c6037,6039
< /* IE */
< insn1 &= (1 << 26) - 1;
< insn1 |= 32 << 26; /* lwz */
---
> rel[1].r_info
> = ELF32_R_INFO (ELF32_R_SYM (rel[1].r_info),
> R_PPC_NONE);
5918,5922c6041
< rel[1].r_info = ELF32_R_INFO (r_symndx2, R_PPC_NONE);
< rel[1].r_addend = 0;
< r_type = (((r_type - (R_PPC_GOT_TLSGD16 & 3)) & 3)
< + R_PPC_GOT_TPREL16);
< rel->r_info = ELF32_R_INFO (r_symndx, r_type);
---
> bfd_put_32 (output_bfd, insn2, contents + offset);
5924c6043,6051
< else
---
> r_type = (((r_type - (R_PPC_GOT_TLSGD16 & 3)) & 3)
> + R_PPC_GOT_TPREL16);
> rel->r_info = ELF32_R_INFO (r_symndx, r_type);
> }
> else
> {
> /* LE */
> insn1 = 0x3c620000; /* addis 3,2,0 */
> if (tls_gd == 0)
5926,5940c6053,6065
< /* LE */
< insn1 = 0x3c620000; /* addis 3,2,0 */
< insn2 = 0x38630000; /* addi 3,3,0 */
< if (tls_gd == 0)
< {
< /* Was an LD reloc. */
< r_symndx = 0;
< rel->r_addend = htab->elf.tls_sec->vma + DTP_OFFSET;
< }
< r_type = R_PPC_TPREL16_HA;
< rel->r_info = ELF32_R_INFO (r_symndx, r_type);
< rel[1].r_info = ELF32_R_INFO (r_symndx,
< R_PPC_TPREL16_LO);
< rel[1].r_offset += d_offset;
< rel[1].r_addend = rel->r_addend;
---
> /* Was an LD reloc. */
> for (r_symndx = 0;
> r_symndx < symtab_hdr->sh_info;
> r_symndx++)
> if (local_sections[r_symndx] == sec)
> break;
> if (r_symndx >= symtab_hdr->sh_info)
> r_symndx = 0;
> rel->r_addend = htab->elf.tls_sec->vma + DTP_OFFSET;
> if (r_symndx != 0)
> rel->r_addend -= (local_syms[r_symndx].st_value
> + sec->output_offset
> + sec->output_section->vma);
5942,5944c6067,6069
< bfd_put_32 (output_bfd, insn1, contents + rel->r_offset - d_offset);
< bfd_put_32 (output_bfd, insn2, contents + offset);
< if (tls_gd == 0)
---
> r_type = R_PPC_TPREL16_HA;
> rel->r_info = ELF32_R_INFO (r_symndx, r_type);
> if (offset != (bfd_vma) -1)
5946,5949c6071,6075
< /* We changed the symbol on an LD reloc. Start over
< in order to get h, sym, sec etc. right. */
< rel--;
< continue;
---
> rel[1].r_info = ELF32_R_INFO (r_symndx, R_PPC_TPREL16_LO);
> rel[1].r_offset = offset + d_offset;
> rel[1].r_addend = rel->r_addend;
> insn2 = 0x38630000; /* addi 3,3,0 */
> bfd_put_32 (output_bfd, insn2, contents + offset);
5951a6078,6086
> bfd_put_32 (output_bfd, insn1,
> contents + rel->r_offset - d_offset);
> if (tls_gd == 0)
> {
> /* We changed the symbol on an LD reloc. Start over
> in order to get h, sym, sec etc. right. */
> rel--;
> continue;
> }
5953a6089,6148
>
> case R_PPC_TLSGD:
> if (tls_mask != 0 && (tls_mask & TLS_GD) == 0)
> {
> unsigned int insn2;
> bfd_vma offset = rel->r_offset;
>
> if ((tls_mask & TLS_TPRELGD) != 0)
> {
> /* IE */
> r_type = R_PPC_NONE;
> insn2 = 0x7c631214; /* add 3,3,2 */
> }
> else
> {
> /* LE */
> r_type = R_PPC_TPREL16_LO;
> rel->r_offset += d_offset;
> insn2 = 0x38630000; /* addi 3,3,0 */
> }
> rel->r_info = ELF32_R_INFO (r_symndx, r_type);
> bfd_put_32 (output_bfd, insn2, contents + offset);
> /* Zap the reloc on the _tls_get_addr call too. */
> BFD_ASSERT (offset == rel[1].r_offset);
> rel[1].r_info = ELF32_R_INFO (ELF32_R_SYM (rel[1].r_info),
> R_PPC_NONE);
> }
> break;
>
> case R_PPC_TLSLD:
> if (tls_mask != 0 && (tls_mask & TLS_LD) == 0)
> {
> unsigned int insn2;
>
> for (r_symndx = 0;
> r_symndx < symtab_hdr->sh_info;
> r_symndx++)
> if (local_sections[r_symndx] == sec)
> break;
> if (r_symndx >= symtab_hdr->sh_info)
> r_symndx = 0;
> rel->r_addend = htab->elf.tls_sec->vma + DTP_OFFSET;
> if (r_symndx != 0)
> rel->r_addend -= (local_syms[r_symndx].st_value
> + sec->output_offset
> + sec->output_section->vma);
>
> rel->r_info = ELF32_R_INFO (r_symndx, R_PPC_TPREL16_LO);
> rel->r_offset += d_offset;
> insn2 = 0x38630000; /* addi 3,3,0 */
> bfd_put_32 (output_bfd, insn2,
> contents + rel->r_offset - d_offset);
> /* Zap the reloc on the _tls_get_addr call too. */
> BFD_ASSERT (rel->r_offset - d_offset == rel[1].r_offset);
> rel[1].r_info = ELF32_R_INFO (ELF32_R_SYM (rel[1].r_info),
> R_PPC_NONE);
> rel--;
> continue;
> }
> break;
6005a6201,6202
> case R_PPC_TLSGD:
> case R_PPC_TLSLD:
6046a6244
> tls_mask = 0;
6345c6543
< && (MUST_BE_DYN_RELOC (r_type)
---
> && (must_be_dyn_reloc (info, r_type)
6414c6612
< long indx;
---
> long indx = 0;
6416,6417c6614,6615
< if (bfd_is_abs_section (sec))
< indx = 0;
---
> if (r_symndx == 0 || bfd_is_abs_section (sec))
> ;