diff options
Diffstat (limited to 'sysdeps/unix')
-rw-r--r-- | sysdeps/unix/sysv/linux/i386/____longjmp_chk.S | 106 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/i386/i686/sysconf.c | 1 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S | 109 |
3 files changed, 216 insertions, 0 deletions
diff --git a/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S b/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S new file mode 100644 index 0000000000..a07e6c8edf --- /dev/null +++ b/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S @@ -0,0 +1,106 @@ +/* Copyright (C) 2001,2004,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 + 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 Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> +#include <jmpbuf-offsets.h> +#include <asm-syntax.h> + + + .section .rodata.str1.1,"aMS",@progbits,1 + .type longjmp_msg,@object +longjmp_msg: + .string "longjmp causes uninitialized stack frame" + .size longjmp_msg, .-longjmp_msg + + +#ifdef PIC +# define CALL_FAIL movl %ebx, %ecx; \ + cfi_register(%ebx,%ecx); \ + LOAD_PIC_REG (bx); \ + leal longjmp_msg@GOTOFF(%ebx), %eax; \ + call __GI___fortify_fail@PLT +#else +# define CALL_FAIL movl $longjmp_msg, %eax; \ + call __fortify_fail +#endif + + + .text +ENTRY (____longjmp_chk) + movl 4(%esp), %ecx /* User's jmp_buf in %ecx. */ + + /* Save the return address now. */ + movl (JB_PC*4)(%ecx), %edx + /* Get the stack pointer. */ + movl (JB_SP*4)(%ecx), %edi + cfi_undefined(%edi) + PTR_DEMANGLE (%edx) + PTR_DEMANGLE (%edi) + + cmpl %edi, %esp + jbe .Lok + + subl $12, %esp + cfi_adjust_cfa_offset(12) + xorl %ebx, %ebx + movl %esp, %ecx + movl $__NR_sigaltstack, %eax + ENTER_KERNEL + /* Without working sigaltstack we cannot perform the test. */ + test %eax, %eax + jne .Lok2 + testl $1, 4(%esp) + jz .Lfail + + movl (%esp), %eax + addl 8(%esp), %eax + subl %edi, %eax + cmpl 8(%esp), %eax + jae .Lok2 + +.Lfail: CALL_FAIL + +.Lok2: addl $12, %esp + cfi_adjust_cfa_offset(-12) + movl 4(%esp), %ecx + +.Lok: /* We add unwind information for the target here. */ + cfi_def_cfa(%ecx, 0) + cfi_register(%eip, %edx) + cfi_register(%esp, %edi) + cfi_offset(%ebx, JB_BX*4) + cfi_offset(%esi, JB_SI*4) + cfi_offset(%edi, JB_DI*4) + cfi_offset(%ebp, JB_BP*4) + + movl 8(%esp), %eax /* Second argument is return value. */ + movl %edi, %esp + + /* Restore registers. */ + movl (JB_BX*4)(%ecx), %ebx + movl (JB_SI*4)(%ecx), %esi + movl (JB_DI*4)(%ecx), %edi + movl (JB_BP*4)(%ecx), %ebp + cfi_restore(%ebx) + cfi_restore(%esi) + cfi_restore(%edi) + cfi_restore(%ebp) + + /* Jump to saved PC. */ + jmp *%edx +END (____longjmp_chk) diff --git a/sysdeps/unix/sysv/linux/i386/i686/sysconf.c b/sysdeps/unix/sysv/linux/i386/i686/sysconf.c new file mode 100644 index 0000000000..cf79750de3 --- /dev/null +++ b/sysdeps/unix/sysv/linux/i386/i686/sysconf.c @@ -0,0 +1 @@ +#include <sysdeps/unix/sysv/linux/x86_64/sysconf.c> diff --git a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S new file mode 100644 index 0000000000..5e11540fd4 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S @@ -0,0 +1,109 @@ +/* Copyright (C) 2001,2004,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 + 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 Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> +#include <jmpbuf-offsets.h> +#include <asm-syntax.h> + + .section .rodata.str1.1,"aMS",@progbits,1 + .type longjmp_msg,@object +longjmp_msg: + .string "longjmp causes uninitialized stack frame" + .size longjmp_msg, .-longjmp_msg + + +//#define __longjmp ____longjmp_chk + +#ifdef PIC +# define CALL_FAIL leaq longjmp_msg(%rip), %rdi; \ + call __GI___fortify_fail +#else +# define CALL_FAIL movq $longjmp_msg, %rdi; \ + call __fortify_fail +#endif + +#define CHECK_RSP(reg) \ + cmpq reg, %rsp; \ + jbe .Lok; \ + CALL_FAIL; \ +.Lok: + +/* Jump to the position specified by ENV, causing the + setjmp call there to return VAL, or 1 if VAL is 0. + void __longjmp (__jmp_buf env, int val). */ + .text +ENTRY(____longjmp_chk) + /* Restore registers. */ + movq (JB_RSP*8)(%rdi),%r8 + movq (JB_RBP*8)(%rdi),%r9 + movq (JB_PC*8)(%rdi),%rdx +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (%r8) + PTR_DEMANGLE (%r9) + PTR_DEMANGLE (%rdx) +#endif + + cmpq %r8, %rsp + jbe .Lok + + /* Save function parameters. */ + movq %rdi, %r10 + movl %esi, %ecx + + xorl %edi, %edi + leaq -24(%rsp), %rsi + movl $__NR_sigaltstack, %eax + syscall + /* Without working sigaltstack we cannot perform the test. */ + testl %eax, %eax + jne .Lok2 + testl $1, -16(%rsp) + jz .Lfail + + movq -24(%rsp), %rax + addq -8(%rsp), %rax + subq %r8, %rax + cmpq -8(%rsp), %rax + jae .Lok2 + +.Lfail: CALL_FAIL + +.Lok2: movq %r10, %rdi + movl %ecx, %esi + +.Lok: /* We add unwind information for the target here. */ + cfi_def_cfa(%rdi, 0) + cfi_register(%rsp,%r8) + cfi_register(%rbp,%r9) + cfi_register(%rip,%rdx) + cfi_offset(%rbx,JB_RBX*8) + cfi_offset(%r12,JB_R12*8) + cfi_offset(%r13,JB_R13*8) + cfi_offset(%r14,JB_R14*8) + cfi_offset(%r15,JB_R15*8) + movq (JB_RBX*8)(%rdi),%rbx + movq (JB_R12*8)(%rdi),%r12 + movq (JB_R13*8)(%rdi),%r13 + movq (JB_R14*8)(%rdi),%r14 + movq (JB_R15*8)(%rdi),%r15 + /* Set return value for setjmp. */ + movl %esi, %eax + movq %r8,%rsp + movq %r9,%rbp + jmpq *%rdx +END (____longjmp_chk) |