diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2006-05-05 13:21:34 +0000 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2006-05-05 13:21:34 +0000 |
commit | 77df29685b94bf65d393172abf0a8755205d3426 (patch) | |
tree | 8bdd3507945c81c617a2177512b31d272350bca0 /bfd | |
parent | d1b46e8025d11e7120fe71c7cee304ddaa2cd4a2 (diff) | |
download | gdb-77df29685b94bf65d393172abf0a8755205d3426.zip gdb-77df29685b94bf65d393172abf0a8755205d3426.tar.gz gdb-77df29685b94bf65d393172abf0a8755205d3426.tar.bz2 |
* 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.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 8 | ||||
-rw-r--r-- | bfd/elf32-s390.c | 63 | ||||
-rw-r--r-- | bfd/elf64-s390.c | 1 |
3 files changed, 61 insertions, 11 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index bd22f4e..1a4f314 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -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 diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c index eb8e172..9d7004e 100644 --- a/bfd/elf32-s390.c +++ b/bfd/elf32-s390.c @@ -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); } } diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c index 1fe0c6c..bb20397 100644 --- a/bfd/elf64-s390.c +++ b/bfd/elf64-s390.c @@ -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. */ |