From patchwork Tue Apr 12 08:34:49 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 968 Return-Path: Delivered-To: unknown Received: from imap.gmail.com (74.125.159.109) by localhost6.localdomain6 with IMAP4-SSL; 08 Jun 2011 14:47:51 -0000 Delivered-To: patches@linaro.org Received: by 10.68.59.138 with SMTP id z10cs156894pbq; Tue, 12 Apr 2011 01:34:54 -0700 (PDT) Received: by 10.227.172.193 with SMTP id m1mr6087723wbz.201.1302597293530; Tue, 12 Apr 2011 01:34:53 -0700 (PDT) Received: from mail-wy0-f178.google.com (mail-wy0-f178.google.com [74.125.82.178]) by mx.google.com with ESMTPS id d8si12487851wbh.29.2011.04.12.01.34.52 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 12 Apr 2011 01:34:53 -0700 (PDT) Received-SPF: neutral (google.com: 74.125.82.178 is neither permitted nor denied by best guess record for domain of richard.sandiford@linaro.org) client-ip=74.125.82.178; Authentication-Results: mx.google.com; spf=neutral (google.com: 74.125.82.178 is neither permitted nor denied by best guess record for domain of richard.sandiford@linaro.org) smtp.mail=richard.sandiford@linaro.org Received: by wyb33 with SMTP id 33so6567417wyb.37 for ; Tue, 12 Apr 2011 01:34:52 -0700 (PDT) Received: by 10.216.145.135 with SMTP id p7mr3802847wej.38.1302597292665; Tue, 12 Apr 2011 01:34:52 -0700 (PDT) Received: from richards-thinkpad (gbibp9ph1--blueice2n1.emea.ibm.com [195.212.29.75]) by mx.google.com with ESMTPS id g7sm3874497wby.31.2011.04.12.01.34.51 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 12 Apr 2011 01:34:51 -0700 (PDT) From: Richard Sandiford To: binutils@sourceware.org Mail-Followup-To: binutils@sourceware.org, patches@linaro.org, richard.sandiford@linaro.org Cc: patches@linaro.org Subject: [ARM] Cortex A8 workarounds for PLT tail calls Date: Tue, 12 Apr 2011 09:34:49 +0100 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) MIME-Version: 1.0 The linker has some workarounds for a Cortex A8 branch erratum. If a 32-bit Thumb branch straddles a page boundary, and branches to somewhere in the first of the two pages, the linker will redirect it to a stub in a different page. This was failing to work correctly for non-call branches to PLTs. The stub is itself a Thumb branch, but it branched directly to the ARM PLT code, rather than to the preceding Thumb entry point. (Normal calls to PLTs work fine. We use a BLX to an ARM stub, which should and does then branch to the main PLT entry.) Tested on arm-linux-gnueabi, both on binutils and GCC. The b-plt and bcc-plt tests failed before the patch but pass after it. The other two already passed, but I've included them for completeness. OK to install? Richard bfd/ * elf32-arm.c (cortex_a8_erratum_scan): If the stub is a Thumb branch to a PLT entry, redirect it to the PLT's Thumb entry point. ld/testsuite/ * ld-arm/cortex-a8-fix-b-plt.s, ld-arm/cortex-a8-fix-b-plt.d, ld-arm/cortex-a8-fix-bcc-plt.s, ld-arm/cortex-a8-fix-bcc-plt.d, ld-arm/cortex-a8-fix-bl-plt.s, ld-arm/cortex-a8-fix-bl-plt.d, ld-arm/cortex-a8-fix-blx-plt.s, ld-arm/cortex-a8-fix-blx-plt.d, ld-arm/cortex-a8-fix-plt.ld: New tests. * ld-arm/arm-elf.exp: Run them. Index: bfd/elf32-arm.c =================================================================== --- bfd/elf32-arm.c 2011-04-11 16:23:04.000000000 +0100 +++ bfd/elf32-arm.c 2011-04-12 09:22:06.000000000 +0100 @@ -4556,6 +4556,7 @@ cortex_a8_erratum_scan (bfd *input_bfd, bfd_vma target; enum elf32_arm_stub_type stub_type = arm_stub_none; struct a8_erratum_reloc key, *found; + bfd_boolean use_plt = FALSE; key.from = base_vma + i; found = (struct a8_erratum_reloc *) @@ -4567,7 +4568,6 @@ cortex_a8_erratum_scan (bfd *input_bfd, { char *error_message = NULL; struct elf_link_hash_entry *entry; - bfd_boolean use_plt = FALSE; /* We don't care about the error returned from this function, only if there is glue or not. */ @@ -4671,6 +4671,12 @@ cortex_a8_erratum_scan (bfd *input_bfd, offset = (bfd_signed_vma) (found->destination - pc_for_insn); + /* If the stub will use a Thumb-mode branch to a + PLT target, redirect it to the preceding Thumb + entry point. */ + if (stub_type != arm_stub_a8_veneer_blx && use_plt) + offset -= PLT_THUMB_STUB_SIZE; + target = pc_for_insn + offset; /* The BLX stub is ARM-mode code. Adjust the offset to Index: ld/testsuite/ld-arm/cortex-a8-fix-b-plt.s =================================================================== --- /dev/null 2011-03-23 08:42:11.268792848 +0000 +++ ld/testsuite/ld-arm/cortex-a8-fix-b-plt.s 2011-04-11 16:23:18.000000000 +0100 @@ -0,0 +1,10 @@ + .syntax unified + .globl foo + .type foo,%function + .thumb_func +foo: + nop @ 0x00 + movw r0,#0 @ 0x02 + movw r0,#0 @ 0x06 + movw r0,#0 @ 0x0a + b.w bar(PLT) @ 0x0e Index: ld/testsuite/ld-arm/cortex-a8-fix-b-plt.d =================================================================== --- /dev/null 2011-03-23 08:42:11.268792848 +0000 +++ ld/testsuite/ld-arm/cortex-a8-fix-b-plt.d 2011-04-11 16:23:18.000000000 +0100 @@ -0,0 +1,30 @@ + +.* + + +Disassembly of section \.plt: + +00008000 <\.plt>: + 8000: e52de004 push {lr} ; \(str lr, \[sp, #-4\]!\) + 8004: e59fe004 ldr lr, \[pc, #4\] ; 8010 + 8008: e08fe00e add lr, pc, lr + 800c: e5bef008 ldr pc, \[lr, #8\]! + 8010: 00000ffc \.word 0x00000ffc + 8014: 4778 bx pc + 8016: 46c0 nop ; \(mov r8, r8\) + 8018: e28fc600 add ip, pc, #0 + 801c: e28cca00 add ip, ip, #0 + 8020: e5bcfff8 ldr pc, \[ip, #4088\]! ; 0xff8 + +Disassembly of section \.text: + +00008ff0 : + 8ff0: 46c0 nop ; \(mov r8, r8\) + 8ff2: f240 0000 movw r0, #0 + 8ff6: f240 0000 movw r0, #0 + 8ffa: f240 0000 movw r0, #0 + 8ffe: f000 b803 b\.w 9008 + 9002: 0000 movs r0, r0 + 9004: 0000 movs r0, r0 + 9006: 0000 movs r0, r0 + 9008: f7ff b804 b\.w 8014 Index: ld/testsuite/ld-arm/cortex-a8-fix-bcc-plt.s =================================================================== --- /dev/null 2011-03-23 08:42:11.268792848 +0000 +++ ld/testsuite/ld-arm/cortex-a8-fix-bcc-plt.s 2011-04-11 16:23:18.000000000 +0100 @@ -0,0 +1,10 @@ + .syntax unified + .globl foo + .type foo,%function + .thumb_func +foo: + nop @ 0x00 + movw r0,#0 @ 0x02 + movw r0,#0 @ 0x06 + movw r0,#0 @ 0x0a + beq.w bar(PLT) @ 0x0e Index: ld/testsuite/ld-arm/cortex-a8-fix-bcc-plt.d =================================================================== --- /dev/null 2011-03-23 08:42:11.268792848 +0000 +++ ld/testsuite/ld-arm/cortex-a8-fix-bcc-plt.d 2011-04-11 16:23:18.000000000 +0100 @@ -0,0 +1,32 @@ + +.* + + +Disassembly of section \.plt: + +00008000 <\.plt>: + 8000: e52de004 push {lr} ; \(str lr, \[sp, #-4\]!\) + 8004: e59fe004 ldr lr, \[pc, #4\] ; 8010 + 8008: e08fe00e add lr, pc, lr + 800c: e5bef008 ldr pc, \[lr, #8\]! + 8010: 00001004 \.word 0x00001004 + 8014: 4778 bx pc + 8016: 46c0 nop ; \(mov r8, r8\) + 8018: e28fc600 add ip, pc, #0 + 801c: e28cca01 add ip, ip, #4096 ; 0x1000 + 8020: e5bcf000 ldr pc, \[ip\]! + +Disassembly of section \.text: + +00008ff0 : + 8ff0: 46c0 nop ; \(mov r8, r8\) + 8ff2: f240 0000 movw r0, #0 + 8ff6: f240 0000 movw r0, #0 + 8ffa: f240 0000 movw r0, #0 + 8ffe: f000 b803 b\.w 9008 + 9002: 0000 movs r0, r0 + 9004: 0000 movs r0, r0 + 9006: 0000 movs r0, r0 + 9008: d001 beq\.n 900e + 900a: f7ff bffa b\.w 9002 + 900e: f7ff b801 b\.w 8014 Index: ld/testsuite/ld-arm/cortex-a8-fix-bl-plt.s =================================================================== --- /dev/null 2011-03-23 08:42:11.268792848 +0000 +++ ld/testsuite/ld-arm/cortex-a8-fix-bl-plt.s 2011-04-11 16:23:18.000000000 +0100 @@ -0,0 +1,10 @@ + .syntax unified + .globl foo + .type foo,%function + .thumb_func +foo: + nop @ 0x00 + movw r0,#0 @ 0x02 + movw r0,#0 @ 0x06 + movw r0,#0 @ 0x0a + bl bar(PLT) @ 0x0e Index: ld/testsuite/ld-arm/cortex-a8-fix-bl-plt.d =================================================================== --- /dev/null 2011-03-23 08:42:11.268792848 +0000 +++ ld/testsuite/ld-arm/cortex-a8-fix-bl-plt.d 2011-04-11 16:23:18.000000000 +0100 @@ -0,0 +1,28 @@ + +.* + + +Disassembly of section \.plt: + +00008000 <\.plt>: + 8000: e52de004 push {lr} ; \(str lr, \[sp, #-4\]!\) + 8004: e59fe004 ldr lr, \[pc, #4\] ; 8010 + 8008: e08fe00e add lr, pc, lr + 800c: e5bef008 ldr pc, \[lr, #8\]! + 8010: 00000ffc \.word 0x00000ffc + 8014: e28fc600 add ip, pc, #0 + 8018: e28cca00 add ip, ip, #0 + 801c: e5bcfffc ldr pc, \[ip, #4092\]! ; 0xffc + +Disassembly of section \.text: + +00008ff0 : + 8ff0: 46c0 nop ; \(mov r8, r8\) + 8ff2: f240 0000 movw r0, #0 + 8ff6: f240 0000 movw r0, #0 + 8ffa: f240 0000 movw r0, #0 + 8ffe: f000 e804 blx 9008 + 9002: 0000 movs r0, r0 + 9004: 0000 movs r0, r0 + 9006: 0000 movs r0, r0 + 9008: eafffc01 b 8014 Index: ld/testsuite/ld-arm/cortex-a8-fix-blx-plt.s =================================================================== --- /dev/null 2011-03-23 08:42:11.268792848 +0000 +++ ld/testsuite/ld-arm/cortex-a8-fix-blx-plt.s 2011-04-11 16:23:18.000000000 +0100 @@ -0,0 +1,10 @@ + .syntax unified + .globl foo + .type foo,%function + .thumb_func +foo: + nop @ 0x00 + movw r0,#0 @ 0x02 + movw r0,#0 @ 0x06 + movw r0,#0 @ 0x0a + blx bar @ 0x0e Index: ld/testsuite/ld-arm/cortex-a8-fix-blx-plt.d =================================================================== --- /dev/null 2011-03-23 08:42:11.268792848 +0000 +++ ld/testsuite/ld-arm/cortex-a8-fix-blx-plt.d 2011-04-11 16:23:18.000000000 +0100 @@ -0,0 +1,28 @@ + +.* + + +Disassembly of section \.plt: + +00008000 <\.plt>: + 8000: e52de004 push {lr} ; \(str lr, \[sp, #-4\]!\) + 8004: e59fe004 ldr lr, \[pc, #4\] ; 8010 + 8008: e08fe00e add lr, pc, lr + 800c: e5bef008 ldr pc, \[lr, #8\]! + 8010: 00000ffc \.word 0x00000ffc + 8014: e28fc600 add ip, pc, #0 + 8018: e28cca00 add ip, ip, #0 + 801c: e5bcfffc ldr pc, \[ip, #4092\]! ; 0xffc + +Disassembly of section \.text: + +00008ff0 : + 8ff0: 46c0 nop ; \(mov r8, r8\) + 8ff2: f240 0000 movw r0, #0 + 8ff6: f240 0000 movw r0, #0 + 8ffa: f240 0000 movw r0, #0 + 8ffe: f000 e804 blx 9008 + 9002: 0000 movs r0, r0 + 9004: 0000 movs r0, r0 + 9006: 0000 movs r0, r0 + 9008: eafffc01 b 8014 Index: ld/testsuite/ld-arm/cortex-a8-fix-plt.ld =================================================================== --- /dev/null 2011-03-23 08:42:11.268792848 +0000 +++ ld/testsuite/ld-arm/cortex-a8-fix-plt.ld 2011-04-11 16:23:18.000000000 +0100 @@ -0,0 +1,18 @@ +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x07000; + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.dyn : { *(.rel.dyn) } + .rel.plt : { *(.rel.plt) } + . = 0x08000; + .plt : { *(.plt) } + . = 0x08ff0; + .text : { *(.text) } + . = 0x10000; + .dynamic : { *(.dynamic) } +} Index: ld/testsuite/ld-arm/arm-elf.exp =================================================================== --- ld/testsuite/ld-arm/arm-elf.exp 2011-04-11 16:23:04.000000000 +0100 +++ ld/testsuite/ld-arm/arm-elf.exp 2011-04-11 16:23:18.000000000 +0100 @@ -210,18 +210,38 @@ set armelftests { "-EL -Ttext=0x8f00 --fix-cortex-a8" "-EL" {cortex-a8-fix-b.s} {{objdump -dr cortex-a8-fix-b.d}} "cortex-a8-fix-b"} + {"Cortex-A8 erratum fix, b.w to PLT" + "-EL -Tcortex-a8-fix-plt.ld --fix-cortex-a8 -shared" "-EL" + {cortex-a8-fix-b-plt.s} + {{objdump -dr cortex-a8-fix-b-plt.d}} + "cortex-a8-fix-b-plt"} {"Cortex-A8 erratum fix, bl.w" "-EL -Ttext=0x8f00 --fix-cortex-a8" "-EL" {cortex-a8-fix-bl.s} {{objdump -dr cortex-a8-fix-bl.d}} "cortex-a8-fix-bl"} + {"Cortex-A8 erratum fix, bl.w to PLT" + "-EL -Tcortex-a8-fix-plt.ld --fix-cortex-a8 -shared" "-EL" + {cortex-a8-fix-bl-plt.s} + {{objdump -dr cortex-a8-fix-bl-plt.d}} + "cortex-a8-fix-bl-plt"} {"Cortex-A8 erratum fix, bcc.w" "-EL -Ttext=0x8f00 --fix-cortex-a8" "-EL" {cortex-a8-fix-bcc.s} {{objdump -dr cortex-a8-fix-bcc.d}} "cortex-a8-fix-bcc"} + {"Cortex-A8 erratum fix, bcc.w to PLT" + "-EL -Tcortex-a8-fix-plt.ld --fix-cortex-a8 -shared" "-EL" + {cortex-a8-fix-bcc-plt.s} + {{objdump -dr cortex-a8-fix-bcc-plt.d}} + "cortex-a8-fix-bcc-plt"} {"Cortex-A8 erratum fix, blx.w" "-EL -Ttext=0x8f00 --fix-cortex-a8" "-EL" {cortex-a8-fix-blx.s} {{objdump -dr cortex-a8-fix-blx.d}} "cortex-a8-fix-blx"} + {"Cortex-A8 erratum fix, blx.w to PLT" + "-EL -Tcortex-a8-fix-plt.ld --fix-cortex-a8 -shared" "-EL" + {cortex-a8-fix-blx-plt.s} + {{objdump -dr cortex-a8-fix-blx-plt.d}} + "cortex-a8-fix-blx-plt"} {"Cortex-A8 erratum fix, relocate b.w to ARM" "-EL -Ttext=0x8f00 --fix-cortex-a8" "-EL" {cortex-a8-arm-target.s cortex-a8-fix-b-rel.s} {{objdump -dr cortex-a8-fix-b-rel-arm.d}}