From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3437 invoked by alias); 5 May 2006 13:24:27 -0000 Received: (qmail 3428 invoked by uid 22791); 5 May 2006 13:24:26 -0000 X-Spam-Check-By: sourceware.org Received: from mtagate3.de.ibm.com (HELO mtagate3.de.ibm.com) (195.212.29.152) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 05 May 2006 13:24:23 +0000 Received: from d12nrmr1607.megacenter.de.ibm.com (d12nrmr1607.megacenter.de.ibm.com [9.149.167.49]) by mtagate3.de.ibm.com (8.13.6/8.13.6) with ESMTP id k45DOKe9126718 for ; Fri, 5 May 2006 13:24:20 GMT Received: from d12av02.megacenter.de.ibm.com (d12av02.megacenter.de.ibm.com [9.149.165.228]) by d12nrmr1607.megacenter.de.ibm.com (8.12.10/NCO/VER6.8) with ESMTP id k45DPYSh141918 for ; Fri, 5 May 2006 15:25:34 +0200 Received: from d12av02.megacenter.de.ibm.com (loopback [127.0.0.1]) by d12av02.megacenter.de.ibm.com (8.12.11/8.13.3) with ESMTP id k45DOK5p007543 for ; Fri, 5 May 2006 15:24:20 +0200 Received: from localhost (dyn-9-152-216-91.boeblingen.de.ibm.com [9.152.216.91]) by d12av02.megacenter.de.ibm.com (8.12.11/8.12.11) with ESMTP id k45DOKWo007535 for ; Fri, 5 May 2006 15:24:20 +0200 Date: Fri, 05 May 2006 15:46:00 -0000 From: Martin Schwidefsky To: binutils@sources.redhat.com Subject: [PATCH] s390 brasl TLS code morphing. Message-ID: <20060505132431.GA21010@skybase> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.11+cvs20060403 X-IsSubscribed: yes Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org X-SW-Source: 2006-05/txt/msg00114.txt.bz2 Hi, if a 32 bit libc is compiled with the option -march=z990 gcc will use a "brasl" instruction instead of a "bas" for the function call to __tls_get_offset in the general dynamic and local dynamic TLS model. The 32 bit elf bfd can only optimize the "bas" instruction and generates broken code if a "brasl" instruction is used. This patch adds the code morphing for the "brasl" instruction to the 32 bit elf bfd and sets an error in invalid_tls_insn for the 32 and 64 bit bfds if an unknown instruction has been found in the tls code morphing. blue skies, Martin. 2006-05-05 Martin Schwidefsky * 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. diff -urpN src/bfd/elf32-s390.c src-s390/bfd/elf32-s390.c --- src/bfd/elf32-s390.c 2006-03-23 11:36:06.000000000 +0100 +++ src-s390/bfd/elf32-s390.c 2006-05-05 14:13:39.000000000 +0200 @@ -2268,6 +2268,7 @@ invalid_tls_insn (input_bfd, input_secti 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, i 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, i 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 -urpN src/bfd/elf64-s390.c src-s390/bfd/elf64-s390.c --- src/bfd/elf64-s390.c 2006-05-05 14:14:58.000000000 +0200 +++ src-s390/bfd/elf64-s390.c 2006-05-05 14:13:08.000000000 +0200 @@ -2240,6 +2240,7 @@ invalid_tls_insn (input_bfd, input_secti input_section, (long) rel->r_offset, howto->name); + bfd_set_error (bfd_error_bad_value); } /* Relocate a 390 ELF section. */