diff --git a/ChangeLog.arm b/ChangeLog.arm index 420c1532ba..1088fc02a8 100644 --- a/ChangeLog.arm +++ b/ChangeLog.arm @@ -1,3 +1,9 @@ +2009-05-16 Joseph Myers + + * sysdeps/arm/____longjmp_chk.S: New file. + * sysdeps/arm/__longjmp.S: If CHECK_SP is defined, use it. + * sysdeps/arm/eabi/__longjmp.S: Likewise. + 2009-05-16 Joseph Myers * sysdeps/unix/sysv/linux/arm/kernel-features.h (__ASSUME_PREADV, diff --git a/sysdeps/arm/____longjmp_chk.S b/sysdeps/arm/____longjmp_chk.S new file mode 100644 index 0000000000..9b65c368a0 --- /dev/null +++ b/sysdeps/arm/____longjmp_chk.S @@ -0,0 +1,55 @@ +/* Copyright (C) 2009 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING. If not, write to the Free + Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + + + .section .rodata.str1.1,"aMS",%progbits,1 + .type longjmp_msg,%object +longjmp_msg: + .string "longjmp causes uninitialized stack frame" + .size longjmp_msg, .-longjmp_msg + .text + +#define __longjmp ____longjmp_chk + +#ifdef PIC +# define CALL_FAIL \ + ldr sl, .L_GOT; \ +.L_GOT_OFF: \ + add sl, pc, sl; \ + ldr r0, .Lstr; \ + add r0, sl, r0; \ + B PLTJMP(HIDDEN_JUMPTARGET(__fortify_fail)); \ +.L_GOT: \ + .word _GLOBAL_OFFSET_TABLE_-(.L_GOT_OFF+8); \ +.Lstr: \ + .word longjmp_msg(GOTOFF); +#else +# define CALL_FAIL \ + ldr r0, .Lstr; \ + B HIDDEN_JUMPTARGET(__fortify_fail); \ +.Lstr: \ + .word longjmp_msg; +#endif + +#define CHECK_SP(reg) \ + cmp sp, reg; \ + ble .Lok; \ + CALL_FAIL \ +.Lok: + +#include <__longjmp.S> diff --git a/sysdeps/arm/__longjmp.S b/sysdeps/arm/__longjmp.S index 7b30160047..c834e7860b 100644 --- a/sysdeps/arm/__longjmp.S +++ b/sysdeps/arm/__longjmp.S @@ -1,5 +1,5 @@ /* longjmp for ARM. - Copyright (C) 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -29,5 +29,9 @@ ENTRY (__longjmp) movs r0, r1 /* get the return value in place */ moveq r0, #1 /* can't let setjmp() return zero! */ +#ifdef CHECK_SP + ldr r1, [ip, #32] + CHECK_SP (r1) +#endif LOADREGS(ia, ip, {v1-v6, sl, fp, sp, pc}) END (__longjmp) diff --git a/sysdeps/arm/eabi/__longjmp.S b/sysdeps/arm/eabi/__longjmp.S index fff25cd948..1f3f791569 100644 --- a/sysdeps/arm/eabi/__longjmp.S +++ b/sysdeps/arm/eabi/__longjmp.S @@ -1,5 +1,5 @@ /* longjmp for ARM. - Copyright (C) 1997, 1998, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 2005, 2006, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -30,6 +30,10 @@ ENTRY (__longjmp) movs r0, r1 /* get the return value in place */ moveq r0, #1 /* can't let setjmp() return zero! */ +#ifdef CHECK_SP + ldr r1, [ip, #32] + CHECK_SP (r1) +#endif LOADREGS(ia, ip!, {v1-v6, sl, fp, sp, lr}) #ifdef IS_IN_rtld