mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-07-03 03:07:26 +08:00
PR ld/11217
* elf64-ppc.c (ppc64_elf_tls_optimize): Optimize tls sequences with relocations against undefined weak symbols. (ppc64_elf_relocate_section): Don't optimize calls to undefined weak functions if the symbol is dynamic. (ppc64_elf_relocate_section): Edit tprel tls sequences. * elf32-ppc.c (ppc_elf_relocate_section): Likewise. (_bfd_elf_ppc_at_tprel_transform): New function. * bfd-in.h (_bfd_elf_ppc_at_tprel_transform): Declare. * bfd-in2.h: Regenerate.
This commit is contained in:
@ -1,3 +1,16 @@
|
|||||||
|
2010-01-25 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
PR ld/11217
|
||||||
|
* elf64-ppc.c (ppc64_elf_tls_optimize): Optimize tls sequences
|
||||||
|
with relocations against undefined weak symbols.
|
||||||
|
(ppc64_elf_relocate_section): Don't optimize calls to undefined
|
||||||
|
weak functions if the symbol is dynamic.
|
||||||
|
(ppc64_elf_relocate_section): Edit tprel tls sequences.
|
||||||
|
* elf32-ppc.c (ppc_elf_relocate_section): Likewise.
|
||||||
|
(_bfd_elf_ppc_at_tprel_transform): New function.
|
||||||
|
* bfd-in.h (_bfd_elf_ppc_at_tprel_transform): Declare.
|
||||||
|
* bfd-in2.h: Regenerate.
|
||||||
|
|
||||||
2010-01-23 Richard Sandiford <r.sandiford@uk.ibm.com>
|
2010-01-23 Richard Sandiford <r.sandiford@uk.ibm.com>
|
||||||
|
|
||||||
* coff-rs6000.c (xcoff_howto_table): Change size to 0 and bitsize to 1.
|
* coff-rs6000.c (xcoff_howto_table): Change size to 0 and bitsize to 1.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* Main header file for the bfd library -- portable access to object files.
|
/* Main header file for the bfd library -- portable access to object files.
|
||||||
|
|
||||||
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||||
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
Contributed by Cygnus Support.
|
Contributed by Cygnus Support.
|
||||||
@ -911,6 +911,9 @@ extern bfd_boolean elf32_arm_fix_exidx_coverage
|
|||||||
/* PowerPC @tls opcode transform/validate. */
|
/* PowerPC @tls opcode transform/validate. */
|
||||||
extern unsigned int _bfd_elf_ppc_at_tls_transform
|
extern unsigned int _bfd_elf_ppc_at_tls_transform
|
||||||
(unsigned int, unsigned int);
|
(unsigned int, unsigned int);
|
||||||
|
/* PowerPC @tprel opcode transform/validate. */
|
||||||
|
extern unsigned int _bfd_elf_ppc_at_tprel_transform
|
||||||
|
(unsigned int, unsigned int);
|
||||||
|
|
||||||
/* TI COFF load page support. */
|
/* TI COFF load page support. */
|
||||||
extern void bfd_ticoff_set_section_load_page
|
extern void bfd_ticoff_set_section_load_page
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
/* Main header file for the bfd library -- portable access to object files.
|
/* Main header file for the bfd library -- portable access to object files.
|
||||||
|
|
||||||
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||||
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
Contributed by Cygnus Support.
|
Contributed by Cygnus Support.
|
||||||
@ -918,6 +918,9 @@ extern bfd_boolean elf32_arm_fix_exidx_coverage
|
|||||||
/* PowerPC @tls opcode transform/validate. */
|
/* PowerPC @tls opcode transform/validate. */
|
||||||
extern unsigned int _bfd_elf_ppc_at_tls_transform
|
extern unsigned int _bfd_elf_ppc_at_tls_transform
|
||||||
(unsigned int, unsigned int);
|
(unsigned int, unsigned int);
|
||||||
|
/* PowerPC @tprel opcode transform/validate. */
|
||||||
|
extern unsigned int _bfd_elf_ppc_at_tprel_transform
|
||||||
|
(unsigned int, unsigned int);
|
||||||
|
|
||||||
/* TI COFF load page support. */
|
/* TI COFF load page support. */
|
||||||
extern void bfd_ticoff_set_section_load_page
|
extern void bfd_ticoff_set_section_load_page
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* PowerPC-specific support for 32-bit ELF
|
/* PowerPC-specific support for 32-bit ELF
|
||||||
Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
|
Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
|
||||||
2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||||
Written by Ian Lance Taylor, Cygnus Support.
|
Written by Ian Lance Taylor, Cygnus Support.
|
||||||
|
|
||||||
This file is part of BFD, the Binary File Descriptor library.
|
This file is part of BFD, the Binary File Descriptor library.
|
||||||
@ -6669,6 +6669,51 @@ _bfd_elf_ppc_at_tls_transform (unsigned int insn, unsigned int reg)
|
|||||||
return insn;
|
return insn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If INSN is an opcode that may be used with an @tprel operand, return
|
||||||
|
the transformed insn for an undefined weak symbol, ie. with the
|
||||||
|
thread pointer REG operand removed. Otherwise return 0. */
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
_bfd_elf_ppc_at_tprel_transform (unsigned int insn, unsigned int reg)
|
||||||
|
{
|
||||||
|
if ((insn & (0x1f << 16)) == reg << 16
|
||||||
|
&& ((insn & (0x3f << 26)) == 14u << 26 /* addi */
|
||||||
|
|| (insn & (0x3f << 26)) == 15u << 26 /* addis */
|
||||||
|
|| (insn & (0x3f << 26)) == 32u << 26 /* lwz */
|
||||||
|
|| (insn & (0x3f << 26)) == 34u << 26 /* lbz */
|
||||||
|
|| (insn & (0x3f << 26)) == 36u << 26 /* stw */
|
||||||
|
|| (insn & (0x3f << 26)) == 38u << 26 /* stb */
|
||||||
|
|| (insn & (0x3f << 26)) == 40u << 26 /* lhz */
|
||||||
|
|| (insn & (0x3f << 26)) == 42u << 26 /* lha */
|
||||||
|
|| (insn & (0x3f << 26)) == 44u << 26 /* sth */
|
||||||
|
|| (insn & (0x3f << 26)) == 46u << 26 /* lmw */
|
||||||
|
|| (insn & (0x3f << 26)) == 47u << 26 /* stmw */
|
||||||
|
|| (insn & (0x3f << 26)) == 48u << 26 /* lfs */
|
||||||
|
|| (insn & (0x3f << 26)) == 50u << 26 /* lfd */
|
||||||
|
|| (insn & (0x3f << 26)) == 52u << 26 /* stfs */
|
||||||
|
|| (insn & (0x3f << 26)) == 54u << 26 /* stfd */
|
||||||
|
|| ((insn & (0x3f << 26)) == 58u << 26 /* lwa,ld,lmd */
|
||||||
|
&& (insn & 3) != 1)
|
||||||
|
|| ((insn & (0x3f << 26)) == 62u << 26 /* std, stmd */
|
||||||
|
&& ((insn & 3) == 0 || (insn & 3) == 3))))
|
||||||
|
{
|
||||||
|
insn &= ~(0x1f << 16);
|
||||||
|
}
|
||||||
|
else if ((insn & (0x1f << 21)) == reg << 21
|
||||||
|
&& ((insn & (0x3e << 26)) == 24u << 26 /* ori, oris */
|
||||||
|
|| (insn & (0x3e << 26)) == 26u << 26 /* xori,xoris */
|
||||||
|
|| (insn & (0x3e << 26)) == 28u << 26 /* andi,andis */))
|
||||||
|
{
|
||||||
|
insn &= ~(0x1f << 21);
|
||||||
|
insn |= (insn & (0x1f << 16)) << 5;
|
||||||
|
if ((insn & (0x3e << 26)) == 26 << 26 /* xori,xoris */)
|
||||||
|
insn -= 2 >> 26; /* convert to ori,oris */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
insn = 0;
|
||||||
|
return insn;
|
||||||
|
}
|
||||||
|
|
||||||
/* The RELOCATE_SECTION function is called by the ELF backend linker
|
/* The RELOCATE_SECTION function is called by the ELF backend linker
|
||||||
to handle the relocations for a section.
|
to handle the relocations for a section.
|
||||||
|
|
||||||
@ -7471,6 +7516,21 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
|||||||
case R_PPC_TPREL16_LO:
|
case R_PPC_TPREL16_LO:
|
||||||
case R_PPC_TPREL16_HI:
|
case R_PPC_TPREL16_HI:
|
||||||
case R_PPC_TPREL16_HA:
|
case R_PPC_TPREL16_HA:
|
||||||
|
if (h != NULL
|
||||||
|
&& h->root.type == bfd_link_hash_undefweak
|
||||||
|
&& h->dynindx == -1)
|
||||||
|
{
|
||||||
|
/* Make this relocation against an undefined weak symbol
|
||||||
|
resolve to zero. This is really just a tweak, since
|
||||||
|
code using weak externs ought to check that they are
|
||||||
|
defined before using them. */
|
||||||
|
bfd_byte *p = contents + rel->r_offset - d_offset;
|
||||||
|
unsigned int insn = bfd_get_32 (output_bfd, p);
|
||||||
|
insn = _bfd_elf_ppc_at_tprel_transform (insn, 2);
|
||||||
|
if (insn != 0)
|
||||||
|
bfd_put_32 (output_bfd, insn, p);
|
||||||
|
break;
|
||||||
|
}
|
||||||
addend -= htab->elf.tls_sec->vma + TP_OFFSET;
|
addend -= htab->elf.tls_sec->vma + TP_OFFSET;
|
||||||
/* The TPREL16 relocs shouldn't really be used in shared
|
/* The TPREL16 relocs shouldn't really be used in shared
|
||||||
libs as they will result in DT_TEXTREL being set, but
|
libs as they will result in DT_TEXTREL being set, but
|
||||||
|
@ -7409,10 +7409,13 @@ ppc64_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
|
|||||||
|
|
||||||
if (h != NULL)
|
if (h != NULL)
|
||||||
{
|
{
|
||||||
if (h->root.type != bfd_link_hash_defined
|
if (h->root.type == bfd_link_hash_defined
|
||||||
&& h->root.type != bfd_link_hash_defweak)
|
|| h->root.type == bfd_link_hash_defweak)
|
||||||
|
value = h->root.u.def.value;
|
||||||
|
else if (h->root.type == bfd_link_hash_undefweak)
|
||||||
|
value = 0;
|
||||||
|
else
|
||||||
continue;
|
continue;
|
||||||
value = h->root.u.def.value;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* Symbols referenced by TLS relocs must be of type
|
/* Symbols referenced by TLS relocs must be of type
|
||||||
@ -7425,11 +7428,17 @@ ppc64_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
|
|||||||
|| !h->def_dynamic)
|
|| !h->def_dynamic)
|
||||||
{
|
{
|
||||||
is_local = TRUE;
|
is_local = TRUE;
|
||||||
value += sym_sec->output_offset;
|
if (h != NULL
|
||||||
value += sym_sec->output_section->vma;
|
&& h->root.type == bfd_link_hash_undefweak)
|
||||||
value -= htab->elf.tls_sec->vma;
|
ok_tprel = TRUE;
|
||||||
ok_tprel = (value + TP_OFFSET + ((bfd_vma) 1 << 31)
|
else
|
||||||
< (bfd_vma) 1 << 32);
|
{
|
||||||
|
value += sym_sec->output_offset;
|
||||||
|
value += sym_sec->output_section->vma;
|
||||||
|
value -= htab->elf.tls_sec->vma;
|
||||||
|
ok_tprel = (value + TP_OFFSET + ((bfd_vma) 1 << 31)
|
||||||
|
< (bfd_vma) 1 << 32);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r_type = ELF64_R_TYPE (rel->r_info);
|
r_type = ELF64_R_TYPE (rel->r_info);
|
||||||
@ -11498,6 +11507,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|||||||
checking whether the function is defined. */
|
checking whether the function is defined. */
|
||||||
else if (h != NULL
|
else if (h != NULL
|
||||||
&& h->elf.root.type == bfd_link_hash_undefweak
|
&& h->elf.root.type == bfd_link_hash_undefweak
|
||||||
|
&& h->elf.dynindx == -1
|
||||||
&& r_type == R_PPC64_REL24
|
&& r_type == R_PPC64_REL24
|
||||||
&& relocation == 0
|
&& relocation == 0
|
||||||
&& addend == 0)
|
&& addend == 0)
|
||||||
@ -11833,6 +11843,22 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|||||||
case R_PPC64_TPREL16_HIGHERA:
|
case R_PPC64_TPREL16_HIGHERA:
|
||||||
case R_PPC64_TPREL16_HIGHEST:
|
case R_PPC64_TPREL16_HIGHEST:
|
||||||
case R_PPC64_TPREL16_HIGHESTA:
|
case R_PPC64_TPREL16_HIGHESTA:
|
||||||
|
if (h != NULL
|
||||||
|
&& h->elf.root.type == bfd_link_hash_undefweak
|
||||||
|
&& h->elf.dynindx == -1)
|
||||||
|
{
|
||||||
|
/* Make this relocation against an undefined weak symbol
|
||||||
|
resolve to zero. This is really just a tweak, since
|
||||||
|
code using weak externs ought to check that they are
|
||||||
|
defined before using them. */
|
||||||
|
bfd_byte *p = contents + rel->r_offset - d_offset;
|
||||||
|
|
||||||
|
insn = bfd_get_32 (output_bfd, p);
|
||||||
|
insn = _bfd_elf_ppc_at_tprel_transform (insn, 13);
|
||||||
|
if (insn != 0)
|
||||||
|
bfd_put_32 (output_bfd, insn, p);
|
||||||
|
break;
|
||||||
|
}
|
||||||
addend -= htab->elf.tls_sec->vma + TP_OFFSET;
|
addend -= htab->elf.tls_sec->vma + TP_OFFSET;
|
||||||
if (info->shared)
|
if (info->shared)
|
||||||
/* The TPREL16 relocs shouldn't really be used in shared
|
/* The TPREL16 relocs shouldn't really be used in shared
|
||||||
|
Reference in New Issue
Block a user