* elf32-s390.c (invalid_tls_insn): Call bfd_set_error.

(elf_s390_relocate_section): Add code to do the GD->LE and
	LD->LE TLS linker optimizations if a brasl instruction is used
	for the __tls_get_offset function call.
	* elf64-s390.c (invalid_tls_insn): Call bfd_set_error.
This commit is contained in:
Martin Schwidefsky 2006-05-05 13:21:34 +00:00
parent d1b46e8025
commit 77df29685b
3 changed files with 61 additions and 11 deletions

View File

@ -1,3 +1,11 @@
2006-05-05 Martin Schwidefsky <schwidefsky@de.ibm.com>
* elf32-s390.c (invalid_tls_insn): Call bfd_set_error.
(elf_s390_relocate_section): Add code to do the GD->LE and
LD->LE TLS linker optimizations if a brasl instruction is used
for the __tls_get_offset function call.
* elf64-s390.c (invalid_tls_insn): Call bfd_set_error.
2006-05-05 Alan Modra <amodra@bigpond.net.au>
* elf64-ppc.c (ppc64_elf_tls_optimize): Only optimize

View File

@ -2268,6 +2268,7 @@ invalid_tls_insn (input_bfd, input_section, rel)
input_section,
(long) rel->r_offset,
howto->name);
bfd_set_error (bfd_error_bad_value);
}
/* Relocate a 390 ELF section. */
@ -2982,16 +2983,44 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
unsigned int insn;
insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
if ((insn & 0xff000fff) != 0x4d000000)
if ((insn & 0xff000fff) != 0x4d000000 &&
(insn & 0xffff0000) != 0xc0e50000)
invalid_tls_insn (input_bfd, input_section, rel);
if (!info->shared && (h == NULL || h->dynindx == -1))
/* GD->LE transition.
bas %r14,0(%rx,%r13) -> bc 0,0 */
insn = 0x47000000;
{
if ((insn & 0xff000000) == 0x4d000000)
{
/* GD->LE transition.
bas %r14,0(%rx,%r13) -> bc 0,0 */
insn = 0x47000000;
}
else
{
/* GD->LE transition.
brasl %r14,_tls_get_addr@plt -> brcl 0,. */
insn = 0xc0040000;
bfd_put_16 (output_bfd, 0x0000,
contents + rel->r_offset + 4);
}
}
else
/* GD->IE transition.
bas %r14,0(%rx,%r13) -> l %r2,0(%r2,%r12) */
insn = 0x5822c000;
{
if ((insn & 0xff000000) == 0x4d000000)
{
/* GD->IE transition.
bas %r14,0(%rx,%r13) -> l %r2,0(%r2,%r12) */
insn = 0x5822c000;
}
else
{
/* GD->IE transition.
brasl %r14,__tls_get_addr@plt ->
l %r2,0(%r2,%r12) ; bcr 0,0 */
insn = 0x5822c000;
bfd_put_16 (output_bfd, 0x0700,
contents + rel->r_offset + 4);
}
}
bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
}
else if (r_type == R_390_TLS_LDCALL)
@ -3001,11 +3030,23 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
unsigned int insn;
insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
if ((insn & 0xff000fff) != 0x4d000000)
if ((insn & 0xff000fff) != 0x4d000000 &&
(insn & 0xffff0000) != 0xc0e50000)
invalid_tls_insn (input_bfd, input_section, rel);
/* LD->LE transition.
bas %r14,0(%rx,%r13) -> bc 0,0 */
insn = 0x47000000;
if ((insn & 0xff000000) == 0x4d000000)
{
/* LD->LE transition.
bas %r14,0(%rx,%r13) -> bc 0,0 */
insn = 0x47000000;
}
else
{
/* LD->LE transition.
brasl %r14,__tls_get_addr@plt -> brcl 0,. */
insn = 0xc0040000;
bfd_put_16 (output_bfd, 0x0000,
contents + rel->r_offset + 4);
}
bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
}
}

View File

@ -2240,6 +2240,7 @@ invalid_tls_insn (input_bfd, input_section, rel)
input_section,
(long) rel->r_offset,
howto->name);
bfd_set_error (bfd_error_bad_value);
}
/* Relocate a 390 ELF section. */