From: Alan Modra Date: Mon, 25 Jan 2010 12:12:47 +0000 (+0000) Subject: Backport X-Git-Tag: binutils-2_20_1~57 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=76a6cc878ddd5ba68479dd46edcd449cbcebaa0f;p=thirdparty%2Fbinutils-gdb.git Backport 2009-12-11 Nick Clifton * elf32-ppc.c: Fix shadowed variable warnings. * elf64-ppc.c: Likewise. 2009-11-18 Alan Modra * bfd-in.h (_bfd_elf_ppc_at_tls_transform): Declare. * bfd-in2.h: Regenerate. * elf64-ppc.c (ppc64_elf_relocate_section): Move code for R_PPC64_TLS insn optimisation to.. * elf32-ppc.c (_bfd_elf_ppc_at_tls_transform): ..here. New function. (ppc_elf_relocate_section): Use it. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 3ae0386694e..5ee073d778f 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,17 @@ +2010-01-25 Alan Modra + + 2009-12-11 Nick Clifton + * elf32-ppc.c: Fix shadowed variable warnings. + * elf64-ppc.c: Likewise. + + 2009-11-18 Alan Modra + * bfd-in.h (_bfd_elf_ppc_at_tls_transform): Declare. + * bfd-in2.h: Regenerate. + * elf64-ppc.c (ppc64_elf_relocate_section): Move code for R_PPC64_TLS + insn optimisation to.. + * elf32-ppc.c (_bfd_elf_ppc_at_tls_transform): ..here. New function. + (ppc_elf_relocate_section): Use it. + 2010-01-11 Alan Modra PR 11103 diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index 516102eb94b..dfea59a5822 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -908,6 +908,10 @@ extern bfd_boolean elf32_arm_build_stubs extern bfd_boolean elf32_arm_fix_exidx_coverage (struct bfd_section **, unsigned int, struct bfd_link_info *); +/* PowerPC @tls opcode transform/validate. */ +extern unsigned int _bfd_elf_ppc_at_tls_transform + (unsigned int, unsigned int); + /* TI COFF load page support. */ extern void bfd_ticoff_set_section_load_page (struct bfd_section *, int); diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 40d3b7a896a..2509eef630b 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -915,6 +915,10 @@ extern bfd_boolean elf32_arm_build_stubs extern bfd_boolean elf32_arm_fix_exidx_coverage (struct bfd_section **, unsigned int, struct bfd_link_info *); +/* PowerPC @tls opcode transform/validate. */ +extern unsigned int _bfd_elf_ppc_at_tls_transform + (unsigned int, unsigned int); + /* TI COFF load page support. */ extern void bfd_ticoff_set_section_load_page (struct bfd_section *, int); diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index d665ad7b27c..0c372f00a41 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -3960,7 +3960,7 @@ ppc_elf_check_relocs (bfd *abfd, || !h->def_regular))) { struct ppc_elf_dyn_relocs *p; - struct ppc_elf_dyn_relocs **head; + struct ppc_elf_dyn_relocs **rel_head; #ifdef DEBUG fprintf (stderr, @@ -3985,7 +3985,7 @@ ppc_elf_check_relocs (bfd *abfd, relocations we need for this symbol. */ if (h != NULL) { - head = &ppc_elf_hash_entry (h)->dyn_relocs; + rel_head = &ppc_elf_hash_entry (h)->dyn_relocs; } else { @@ -4006,17 +4006,17 @@ ppc_elf_check_relocs (bfd *abfd, s = sec; vpp = &elf_section_data (s)->local_dynrel; - head = (struct ppc_elf_dyn_relocs **) vpp; + rel_head = (struct ppc_elf_dyn_relocs **) vpp; } - p = *head; + p = *rel_head; if (p == NULL || p->sec != sec) { p = bfd_alloc (htab->elf.dynobj, sizeof *p); if (p == NULL) return FALSE; - p->next = *head; - *head = p; + p->next = *rel_head; + *rel_head = p; p->sec = sec; p->count = 0; p->pc_count = 0; @@ -5635,6 +5635,7 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, local_plt = (struct plt_entry **) end_local_got; end_local_plt = local_plt + locsymcount; lgot_masks = (char *) end_local_plt; + for (; local_got < end_local_got; ++local_got, ++lgot_masks) if (*local_got > 0) { @@ -5678,7 +5679,7 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, for (ent = *local_plt; ent != NULL; ent = ent->next) if (ent->plt.refcount > 0) { - asection *s = htab->iplt; + s = htab->iplt; if (!doneone) { @@ -6034,7 +6035,7 @@ ppc_elf_relax_section (bfd *abfd, for (irel = internal_relocs; irel < irelend; irel++) { unsigned long r_type = ELF32_R_TYPE (irel->r_info); - bfd_vma reladdr, toff, roff; + bfd_vma toff, roff; asection *tsec; struct one_fixup *f; size_t insn_offset = 0; @@ -6218,7 +6219,6 @@ ppc_elf_relax_section (bfd *abfd, continue; roff = irel->r_offset; - reladdr = isec->output_section->vma + isec->output_offset + roff; /* If the branch is in range, no need to do anything. */ if (tsec != bfd_und_section_ptr @@ -6629,6 +6629,46 @@ is_static_defined (struct elf_link_hash_entry *h) && h->root.u.def.section->output_section != NULL); } +/* If INSN is an opcode that may be used with an @tls operand, return + the transformed insn for TLS optimisation, otherwise return 0. If + REG is non-zero only match an insn with RB or RA equal to REG. */ + +unsigned int +_bfd_elf_ppc_at_tls_transform (unsigned int insn, unsigned int reg) +{ + unsigned int rtra; + + if ((insn & (0x3f << 26)) != 31 << 26) + return 0; + + if (reg == 0 || ((insn >> 11) & 0x1f) == reg) + rtra = insn & ((1 << 26) - (1 << 16)); + else if (((insn >> 16) & 0x1f) == reg) + rtra = (insn & (0x1f << 21)) | ((insn & (0x1f << 11)) << 5); + else + return 0; + + if ((insn & (0x3ff << 1)) == 266 << 1) + /* add -> addi. */ + insn = 14 << 26; + else if ((insn & (0x1f << 1)) == 23 << 1 + && ((insn & (0x1f << 6)) < 14 << 6 + || ((insn & (0x1f << 6)) >= 16 << 6 + && (insn & (0x1f << 6)) < 24 << 6))) + /* load and store indexed -> dform. */ + insn = (32 | ((insn >> 6) & 0x1f)) << 26; + else if ((insn & (((0x1a << 5) | 0x1f) << 1)) == 21 << 1) + /* ldx, ldux, stdx, stdux -> ld, ldu, std, stdu. */ + insn = ((58 | ((insn >> 6) & 4)) << 26) | ((insn >> 6) & 1); + else if ((insn & (((0x1f << 5) | 0x1f) << 1)) == 341 << 1) + /* lwax -> lwa. */ + insn = (58 << 26) | 2; + else + return 0; + insn |= rtra; + return insn; +} + /* The RELOCATE_SECTION function is called by the ELF backend linker to handle the relocations for a section. @@ -6674,7 +6714,6 @@ ppc_elf_relocate_section (bfd *output_bfd, Elf_Internal_Rela *rel; Elf_Internal_Rela *relend; Elf_Internal_Rela outrel; - bfd_byte *loc; asection *got2, *sreloc = NULL; bfd_vma *local_got_offsets; bfd_boolean ret = TRUE; @@ -6718,7 +6757,7 @@ ppc_elf_relocate_section (bfd *output_bfd, reloc_howto_type *howto; unsigned long r_symndx; bfd_vma relocation; - bfd_vma branch_bit, insn, from; + bfd_vma branch_bit, from; bfd_boolean unresolved_reloc; bfd_boolean warned; unsigned int tls_type, tls_mask, tls_gd; @@ -6816,6 +6855,7 @@ ppc_elf_relocate_section (bfd *output_bfd, && (tls_mask & TLS_TPREL) == 0) { bfd_vma insn; + insn = bfd_get_32 (output_bfd, contents + rel->r_offset - d_offset); insn &= 31 << 21; insn |= 0x3c020000; /* addis 0,2,0 */ @@ -6829,37 +6869,12 @@ ppc_elf_relocate_section (bfd *output_bfd, if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_TPREL) == 0) { - bfd_vma insn, rtra; + bfd_vma insn; + insn = bfd_get_32 (output_bfd, contents + rel->r_offset); - if ((insn & ((31 << 26) | (31 << 11))) - == ((31 << 26) | (2 << 11))) - rtra = insn & ((1 << 26) - (1 << 16)); - else if ((insn & ((31 << 26) | (31 << 16))) - == ((31 << 26) | (2 << 16))) - rtra = (insn & (31 << 21)) | ((insn & (31 << 11)) << 5); - else + insn = _bfd_elf_ppc_at_tls_transform (insn, 2); + if (insn == 0) abort (); - if ((insn & ((1 << 11) - (1 << 1))) == 266 << 1) - /* add -> addi. */ - insn = 14 << 26; - else if ((insn & (31 << 1)) == 23 << 1 - && ((insn & (31 << 6)) < 14 << 6 - || ((insn & (31 << 6)) >= 16 << 6 - && (insn & (31 << 6)) < 24 << 6))) - /* load and store indexed -> dform. */ - insn = (32 | ((insn >> 6) & 31)) << 26; - else if ((insn & (31 << 1)) == 21 << 1 - && (insn & (0x1a << 6)) == 0) - /* ldx, ldux, stdx, stdux -> ld, ldu, std, stdu. */ - insn = (((58 | ((insn >> 6) & 4)) << 26) - | ((insn >> 6) & 1)); - else if ((insn & (31 << 1)) == 21 << 1 - && (insn & ((1 << 11) - (1 << 1))) == 341 << 1) - /* lwax -> lwa. */ - insn = (58 << 26) | 2; - else - abort (); - insn |= rtra; bfd_put_32 (output_bfd, insn, contents + rel->r_offset); r_type = R_PPC_TPREL16_LO; rel->r_info = ELF32_R_INFO (r_symndx, r_type); @@ -7056,20 +7071,24 @@ ppc_elf_relocate_section (bfd *output_bfd, /* Branch not taken prediction relocations. */ case R_PPC_ADDR14_BRNTAKEN: case R_PPC_REL14_BRNTAKEN: - insn = bfd_get_32 (output_bfd, contents + rel->r_offset); - insn &= ~BRANCH_PREDICT_BIT; - insn |= branch_bit; + { + bfd_vma insn; - from = (rel->r_offset - + input_section->output_offset - + input_section->output_section->vma); + insn = bfd_get_32 (output_bfd, contents + rel->r_offset); + insn &= ~BRANCH_PREDICT_BIT; + insn |= branch_bit; - /* Invert 'y' bit if not the default. */ - if ((bfd_signed_vma) (relocation + rel->r_addend - from) < 0) - insn ^= BRANCH_PREDICT_BIT; + from = (rel->r_offset + + input_section->output_offset + + input_section->output_section->vma); - bfd_put_32 (output_bfd, insn, contents + rel->r_offset); - break; + /* Invert 'y' bit if not the default. */ + if ((bfd_signed_vma) (relocation + rel->r_addend - from) < 0) + insn ^= BRANCH_PREDICT_BIT; + + bfd_put_32 (output_bfd, insn, contents + rel->r_offset); + break; + } } ifunc = NULL; @@ -7300,6 +7319,7 @@ ppc_elf_relocate_section (bfd *output_bfd, || h->root.type != bfd_link_hash_undefweak)) { asection *rsec = htab->relgot; + bfd_byte * loc; outrel.r_offset = (htab->got->output_section->vma + htab->got->output_offset @@ -7531,7 +7551,7 @@ ppc_elf_relocate_section (bfd *output_bfd, && !h->def_regular)) { int skip; - + bfd_byte * loc; #ifdef DEBUG fprintf (stderr, "ppc_elf_relocate_section needs to " "create relocation for %s\n", @@ -7925,7 +7945,9 @@ ppc_elf_relocate_section (bfd *output_bfd, } if (r_type == R_PPC_EMB_SDA21) - { /* fill in register field */ + { + bfd_vma insn; /* Fill in register field. */ + insn = bfd_get_32 (output_bfd, contents + rel->r_offset); insn = (insn & ~RA_REGISTER_MASK) | (reg << RA_REGISTER_SHIFT); bfd_put_32 (output_bfd, insn, contents + rel->r_offset); diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index e62bb706de6..4304aea4851 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -1,6 +1,6 @@ /* PowerPC64-specific support for 64-bit ELF. Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, - 2009 Free Software Foundation, Inc. + 2009, 2010 Free Software Foundation, Inc. Written by Linus Nordberg, Swox AB , based on elf32-ppc.c by Ian Lance Taylor. Largely rewritten by Alan Modra. @@ -5401,8 +5401,6 @@ opd_entry_value (asection *opd_sec, /* No relocs implies we are linking a --just-symbols object. */ if (opd_sec->reloc_count == 0) { - bfd_vma val; - if (!bfd_get_section_contents (opd_bfd, opd_sec, &val, offset, 8)) return (bfd_vma) -1; @@ -8573,8 +8571,7 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, for (ent = *local_plt; ent != NULL; ent = ent->next) if (ent->plt.refcount > 0) { - asection *s = htab->iplt; - + s = htab->iplt; ent->plt.offset = s->size; s->size += PLT_ENTRY_SIZE; @@ -11016,37 +11013,10 @@ ppc64_elf_relocate_section (bfd *output_bfd, if (tls_mask != 0 && (tls_mask & TLS_TPREL) == 0) { - bfd_vma rtra; insn = bfd_get_32 (output_bfd, contents + rel->r_offset); - if ((insn & ((0x3f << 26) | (31 << 11))) - == ((31 << 26) | (13 << 11))) - rtra = insn & ((1 << 26) - (1 << 16)); - else if ((insn & ((0x3f << 26) | (31 << 16))) - == ((31 << 26) | (13 << 16))) - rtra = (insn & (31 << 21)) | ((insn & (31 << 11)) << 5); - else + insn = _bfd_elf_ppc_at_tls_transform (insn, 13); + if (insn == 0) abort (); - if ((insn & ((1 << 11) - (1 << 1))) == 266 << 1) - /* add -> addi. */ - insn = 14 << 26; - else if ((insn & (31 << 1)) == 23 << 1 - && ((insn & (31 << 6)) < 14 << 6 - || ((insn & (31 << 6)) >= 16 << 6 - && (insn & (31 << 6)) < 24 << 6))) - /* load and store indexed -> dform. */ - insn = (32 | ((insn >> 6) & 31)) << 26; - else if ((insn & (31 << 1)) == 21 << 1 - && (insn & (0x1a << 6)) == 0) - /* ldx, ldux, stdx, stdux -> ld, ldu, std, stdu. */ - insn = (((58 | ((insn >> 6) & 4)) << 26) - | ((insn >> 6) & 1)); - else if ((insn & (31 << 1)) == 21 << 1 - && (insn & ((1 << 11) - (1 << 1))) == 341 << 1) - /* lwax -> lwa. */ - insn = (58 << 26) | 2; - else - abort (); - insn |= rtra; bfd_put_32 (output_bfd, insn, contents + rel->r_offset); /* Was PPC64_TLS which sits on insn boundary, now PPC64_TPREL16_LO which is at low-order half-word. */ @@ -11945,10 +11915,8 @@ ppc64_elf_relocate_section (bfd *output_bfd, ? h->elf.type == STT_GNU_IFUNC : ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC))) { - Elf_Internal_Rela outrel; bfd_boolean skip, relocate; asection *sreloc; - bfd_byte *loc; bfd_vma out_off; /* When generating a dynamic object, these relocations @@ -12409,9 +12377,6 @@ ppc64_elf_finish_dynamic_symbol (bfd *output_bfd, if (h->needs_copy) { - Elf_Internal_Rela rela; - bfd_byte *loc; - /* This symbol needs a copy reloc. Set it up. */ if (h->dynindx == -1