From: Thomas Schwinge Date: Fri, 26 Mar 2010 18:12:56 +0000 (+0000) Subject: Add CFI statements to ARM's assembly code. X-Git-Tag: glibc-2.16-ports-before-merge~505 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=01b32e7361d68ade13d88f7245af778bb3ba02fd;p=thirdparty%2Fglibc.git Add CFI statements to ARM's assembly code. --- diff --git a/ChangeLog.arm b/ChangeLog.arm index fbd173ea84a..aa8f2d777b9 100644 --- a/ChangeLog.arm +++ b/ChangeLog.arm @@ -1,3 +1,53 @@ +2010-03-26 Thomas Schwinge + + * sysdeps/arm/configure.in: New file. + * sysdeps/arm/configure: Generate. + * sysdeps/arm/sysdep.h (ENTRY, END): Add CFI statements. + * sysdeps/unix/arm/sysdep.S (__syscall_error): Likewise. + * sysdeps/unix/sysv/linux/arm/eabi/nptl/sysdep-cancel.h + (PSEUDO, DOCARGS_0, RESTORE_LR_0, DOCARGS_1, UNDOCARGS_1, DOCARGS_2) + (UNDOCARGS_2, DOCARGS_3, UNDOCARGS_3, DOCARGS_4, UNDOCARGS_4) + (DOCARGS_5, UNDOCARGS_5, RESTORE_LR_5, DOCARGS_6, UNDOCARGS_6): + Likewise. + [__ASSEMBLER__] (SINGLE_THREAD_P): Likewise. + * sysdeps/unix/sysv/linux/arm/eabi/sysdep.h (DO_CALL): Likewise. + * sysdeps/unix/sysv/linux/arm/sysdep.h + (POP_PC, SYSCALL_ERROR_HANDLER (__local_syscall_error)) + (DOARGS_5, UNDOARGS_5, DOARGS_6, UNDOARGS_6, DOARGS_7, UNDOARGS_7): + Likewise. + * sysdeps/unix/sysv/linux/arm/eabi/sigrestorer.S + (__default_sa_restorer_v1, __default_sa_restorer_v2) + (__default_rt_sa_restorer_v1, __default_rt_sa_restorer_v2): Add END + statements. + * sysdeps/unix/sysv/linux/arm/eabi/syscall.S (syscall): Add CFI + statements. + * sysdeps/arm/memcpy.S (memcpy): Add CFI statements. + * sysdeps/arm/memmove.S (memmove): Likewise. + * sysdeps/unix/sysv/linux/arm/eabi/mmap64.S (__mmap64): Add CFI + statements. + * sysdeps/unix/sysv/linux/arm/mmap.S (__mmap): Likewise. + * sysdeps/arm/eabi/arm-mcount.S (__gnu_mcount_nc, _mcount): Add CFI + statements. + * sysdeps/arm/sysdep.h (CALL_MCOUNT): Likewise. + * sysdeps/unix/sysv/linux/arm/eabi/nptl/unwind-forcedunwind.c + (_Unwind_Resume): Add CFI statements. + * sysdeps/unix/sysv/linux/arm/eabi/nptl/unwind-resume.c + (_Unwind_Resume): Likewise. + * sysdeps/arm/dl-trampoline.S (_dl_runtime_resolve) + (_dl_runtime_profile) : Only emit .debug_frame. + * sysdeps/arm/eabi/__longjmp.S (__longjmp): Add CFI statements. + * sysdeps/unix/sysv/linux/arm/eabi/____longjmp_chk.S (CALL_FAIL) + (CHECK_SP): Likewise + * sysdeps/unix/sysv/linux/arm/nptl/pt-vfork.S (SAVE_PID): Add CFI + statements. + * sysdeps/unix/sysv/linux/arm/nptl/vfork.S (SAVE_PID): Likewise. + * sysdeps/unix/sysv/linux/arm/clone.S (__clone): Add CFI statements. + * sysdeps/unix/sysv/linux/arm/eabi/sigrestorer.S (cfi_startproc): + Redefine for signal frames. + (__default_sa_restorer_v1, __default_sa_restorer_v2) + (__default_rt_sa_restorer_v1, __default_rt_sa_restorer_v2): Add CFI + statements. + 2010-02-10 Joseph Myers * sysdeps/arm/eabi/fegetenv.c, sysdeps/arm/fpu/fegetenv.c: Add diff --git a/sysdeps/arm/configure b/sysdeps/arm/configure new file mode 100644 index 00000000000..066a8b69c58 --- /dev/null +++ b/sysdeps/arm/configure @@ -0,0 +1,33 @@ +# This file is generated from configure.in by Autoconf. DO NOT EDIT! + # Local configure fragment for sysdeps/arm. + +{ $as_echo "$as_me:$LINENO: checking whether the CFI directive .cfi_sections is supported" >&5 +$as_echo_n "checking whether the CFI directive .cfi_sections is supported... " >&6; } +if test "${libc_cv_asm_cfi_directive_sections+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat > conftest.s <&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + libc_cv_asm_cfi_directive_sections=yes + else + libc_cv_asm_cfi_directive_sections=no + fi + rm -f conftest* +fi +{ $as_echo "$as_me:$LINENO: result: $libc_cv_asm_cfi_directive_sections" >&5 +$as_echo "$libc_cv_asm_cfi_directive_sections" >&6; } +if test $libc_cv_asm_cfi_directive_sections != yes; then + { { $as_echo "$as_me:$LINENO: error: need .cfi_sections in this configuration" >&5 +$as_echo "$as_me: error: need .cfi_sections in this configuration" >&2;} + { (exit 1); exit 1; }; } +fi diff --git a/sysdeps/arm/configure.in b/sysdeps/arm/configure.in new file mode 100644 index 00000000000..9f4ff3b7384 --- /dev/null +++ b/sysdeps/arm/configure.in @@ -0,0 +1,20 @@ +GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. +# Local configure fragment for sysdeps/arm. + +AC_CACHE_CHECK([whether the CFI directive .cfi_sections is supported], + [libc_cv_asm_cfi_directive_sections], + [cat > conftest.s <&AS_MESSAGE_LOG_FD); then + libc_cv_asm_cfi_directive_sections=yes + else + libc_cv_asm_cfi_directive_sections=no + fi + rm -f conftest*]) +if test $libc_cv_asm_cfi_directive_sections != yes; then + AC_MSG_ERROR([need .cfi_sections in this configuration]) +fi diff --git a/sysdeps/arm/dl-trampoline.S b/sysdeps/arm/dl-trampoline.S index 0224fa1d1cb..de8d891821a 100644 --- a/sysdeps/arm/dl-trampoline.S +++ b/sysdeps/arm/dl-trampoline.S @@ -1,5 +1,5 @@ /* PLT trampolines. ARM version. - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2010 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,6 +29,7 @@ .text .globl _dl_runtime_resolve .type _dl_runtime_resolve, #function + .cfi_sections .debug_frame cfi_startproc .align 2 _dl_runtime_resolve: @@ -77,6 +78,7 @@ _dl_runtime_resolve: #ifndef PROF .globl _dl_runtime_profile .type _dl_runtime_profile, #function + .cfi_sections .debug_frame cfi_startproc .align 2 _dl_runtime_profile: diff --git a/sysdeps/arm/eabi/__longjmp.S b/sysdeps/arm/eabi/__longjmp.S index 305919393d2..edabdad4a21 100644 --- a/sysdeps/arm/eabi/__longjmp.S +++ b/sysdeps/arm/eabi/__longjmp.S @@ -1,5 +1,6 @@ /* longjmp for ARM. - Copyright (C) 1997, 1998, 2005, 2006, 2009 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 2005, 2006, 2009, 2010 + 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 @@ -31,10 +32,21 @@ ENTRY (__longjmp) moveq r0, #1 /* can't let setjmp() return zero! */ #ifdef CHECK_SP - ldr r4, [ip, #32] + ldr r4, [ip, #32] /* jmpbuf's sp */ + cfi_undefined (r4) CHECK_SP (r4) #endif LOADREGS(ia, ip!, {v1-v6, sl, fp, sp, lr}) + cfi_restore (v1) + cfi_restore (v2) + cfi_restore (v3) + cfi_restore (v4) + cfi_restore (v5) + cfi_restore (v6) + cfi_restore (sl) + cfi_restore (fp) + cfi_restore (sp) + cfi_restore (lr) #ifdef IS_IN_rtld ldr a2, 1f diff --git a/sysdeps/arm/eabi/arm-mcount.S b/sysdeps/arm/eabi/arm-mcount.S index 2aa50b70e70..06e5f182d89 100644 --- a/sysdeps/arm/eabi/arm-mcount.S +++ b/sysdeps/arm/eabi/arm-mcount.S @@ -1,5 +1,5 @@ /* Implementation of profiling support. ARM EABI version. - Copyright (C) 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 2008, 2009, 2010 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 @@ -46,10 +46,22 @@ func: ENTRY(__gnu_mcount_nc) push {r0, r1, r2, r3, lr} + cfi_adjust_cfa_offset (20) + cfi_rel_offset (r0, 0) + cfi_rel_offset (r1, 4) + cfi_rel_offset (r2, 8) + cfi_rel_offset (r3, 12) + cfi_rel_offset (lr, 16) bic r1, lr, #1 ldr r0, [sp, #20] bl __mcount_internal pop {r0, r1, r2, r3, ip, lr} + cfi_adjust_cfa_offset (-24) + cfi_restore (r0) + cfi_restore (r1) + cfi_restore (r2) + cfi_restore (r3) + cfi_register (lr, ip) bx ip END(__gnu_mcount_nc) @@ -59,6 +71,13 @@ END(__gnu_mcount_nc) ENTRY(_mcount) stmdb sp!, {r0, r1, r2, r3, fp, lr} + cfi_adjust_cfa_offset (24) + cfi_rel_offset (r0, 0) + cfi_rel_offset (r1, 4) + cfi_rel_offset (r2, 8) + cfi_rel_offset (r3, 12) + cfi_rel_offset (fp, 16) + cfi_rel_offset (lr, 20) #ifdef __thumb2__ movs r0, fp ittt ne @@ -73,6 +92,13 @@ ENTRY(_mcount) ldmia sp!, {r0, r1, r2, r3, fp, pc} #else ldmia sp!, {r0, r1, r2, r3, fp, lr} + cfi_adjust_cfa_offset (-24) + cfi_restore (r0) + cfi_restore (r1) + cfi_restore (r2) + cfi_restore (r3) + cfi_restore (fp) + cfi_restore (lr) bx lr #endif END(_mcount) diff --git a/sysdeps/arm/memcpy.S b/sysdeps/arm/memcpy.S index 7f669a6e906..673bf43c48c 100644 --- a/sysdeps/arm/memcpy.S +++ b/sysdeps/arm/memcpy.S @@ -58,6 +58,11 @@ ENTRY(memcpy) stmfd sp!, {r0, r4, lr} + cfi_adjust_cfa_offset (12) + cfi_rel_offset (r4, 4) + cfi_rel_offset (lr, 8) + + cfi_remember_state subs r2, r2, #4 blt 8f @@ -69,6 +74,11 @@ ENTRY(memcpy) 1: subs r2, r2, #(28) stmfd sp!, {r5 - r8} + cfi_adjust_cfa_offset (16) + cfi_rel_offset (r5, 0) + cfi_rel_offset (r6, 4) + cfi_rel_offset (r7, 8) + cfi_rel_offset (r8, 12) blt 5f CALGN( ands ip, r1, #31 ) @@ -121,6 +131,11 @@ ENTRY(memcpy) CALGN( bcs 2b ) 7: ldmfd sp!, {r5 - r8} + cfi_adjust_cfa_offset (-16) + cfi_restore (r5) + cfi_restore (r6) + cfi_restore (r7) + cfi_restore (r8) 8: movs r2, r2, lsl #31 ldrneb r3, [r1], #1 @@ -132,11 +147,16 @@ ENTRY(memcpy) #if defined (__ARM_ARCH_4T__) && defined(__THUMB_INTERWORK__) ldmfd sp!, {r0, r4, lr} + cfi_adjust_cfa_offset (-12) + cfi_restore (r4) + cfi_restore (lr) bx lr #else ldmfd sp!, {r0, r4, pc} #endif + cfi_restore_state + 9: rsb ip, ip, #4 cmp ip, #2 ldrgtb r3, [r1], #1 @@ -169,6 +189,12 @@ ENTRY(memcpy) CALGN( bcc 15f ) 11: stmfd sp!, {r5 - r9} + cfi_adjust_cfa_offset (20) + cfi_rel_offset (r5, 0) + cfi_rel_offset (r6, 4) + cfi_rel_offset (r7, 8) + cfi_rel_offset (r8, 12) + cfi_rel_offset (r9, 16) PLD( pld [r1, #0] ) PLD( subs r2, r2, #96 ) @@ -203,6 +229,12 @@ ENTRY(memcpy) PLD( bge 13b ) ldmfd sp!, {r5 - r9} + cfi_adjust_cfa_offset (-20) + cfi_restore (r5) + cfi_restore (r6) + cfi_restore (r7) + cfi_restore (r8) + cfi_restore (r9) 14: ands ip, r2, #28 beq 16f diff --git a/sysdeps/arm/memmove.S b/sysdeps/arm/memmove.S index 9c9b2344d2c..026d8e2bd1d 100644 --- a/sysdeps/arm/memmove.S +++ b/sysdeps/arm/memmove.S @@ -73,6 +73,12 @@ ENTRY(memmove) #endif stmfd sp!, {r0, r4, lr} + cfi_adjust_cfa_offset (12) + cfi_rel_offset (r4, 4) + cfi_rel_offset (lr, 8) + + cfi_remember_state + add r1, r1, r2 add r0, r0, r2 subs r2, r2, #4 @@ -85,6 +91,11 @@ ENTRY(memmove) 1: subs r2, r2, #(28) stmfd sp!, {r5 - r8} + cfi_adjust_cfa_offset (16) + cfi_rel_offset (r5, 0) + cfi_rel_offset (r6, 4) + cfi_rel_offset (r7, 8) + cfi_rel_offset (r8, 12) blt 5f CALGN( ands ip, r1, #31 ) @@ -136,6 +147,11 @@ ENTRY(memmove) CALGN( bcs 2b ) 7: ldmfd sp!, {r5 - r8} + cfi_adjust_cfa_offset (-16) + cfi_restore (r5) + cfi_restore (r6) + cfi_restore (r7) + cfi_restore (r8) 8: movs r2, r2, lsl #31 ldrneb r3, [r1, #-1]! @@ -144,13 +160,19 @@ ENTRY(memmove) strneb r3, [r0, #-1]! strcsb r4, [r0, #-1]! strcsb ip, [r0, #-1] + #if defined (__ARM_ARCH_4T__) && defined (__THUMB_INTERWORK__) ldmfd sp!, {r0, r4, lr} + cfi_adjust_cfa_offset (-12) + cfi_restore (r4) + cfi_restore (lr) bx lr #else ldmfd sp!, {r0, r4, pc} #endif + cfi_restore_state + 9: cmp ip, #2 ldrgtb r3, [r1, #-1]! ldrgeb r4, [r1, #-1]! @@ -182,6 +204,12 @@ ENTRY(memmove) CALGN( bcc 15f ) 11: stmfd sp!, {r5 - r9} + cfi_adjust_cfa_offset (20) + cfi_rel_offset (r5, 0) + cfi_rel_offset (r6, 4) + cfi_rel_offset (r7, 8) + cfi_rel_offset (r8, 12) + cfi_rel_offset (r9, 16) PLD( pld [r1, #-4] ) PLD( subs r2, r2, #96 ) @@ -216,6 +244,12 @@ ENTRY(memmove) PLD( bge 13b ) ldmfd sp!, {r5 - r9} + cfi_adjust_cfa_offset (-20) + cfi_restore (r5) + cfi_restore (r6) + cfi_restore (r7) + cfi_restore (r8) + cfi_restore (r9) 14: ands ip, r2, #28 beq 16f diff --git a/sysdeps/arm/sysdep.h b/sysdeps/arm/sysdep.h index 442d3a146ec..9ffd7df2b5d 100644 --- a/sysdeps/arm/sysdep.h +++ b/sysdeps/arm/sysdep.h @@ -1,5 +1,5 @@ /* Assembler macros for ARM. - Copyright (C) 1997, 1998, 2003 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 2003, 2009, 2010 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 @@ -81,18 +81,25 @@ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),function) \ .align ALIGNARG(4); \ C_LABEL(name) \ + .cfi_sections .debug_frame; \ + cfi_startproc; \ CALL_MCOUNT #undef END #define END(name) \ + cfi_endproc; \ ASM_SIZE_DIRECTIVE(name) /* If compiled for profiling, call `mcount' at the start of each function. */ #ifdef PROF -#define CALL_MCOUNT \ - str lr,[sp, #-4]! ; \ - bl PLTJMP(mcount) ; \ - ldr lr, [sp], #4 ; +#define CALL_MCOUNT \ + str lr,[sp, #-4]!; \ + cfi_adjust_cfa_offset (4); \ + cfi_rel_offset (lr, 0); \ + bl PLTJMP(mcount); \ + ldr lr, [sp], #4; \ + cfi_adjust_cfa_offset (-4); \ + cfi_restore (lr) #else #define CALL_MCOUNT /* Do nothing. */ #endif diff --git a/sysdeps/unix/arm/sysdep.S b/sysdeps/unix/arm/sysdep.S index dcb427e57fc..d3ad81b7bdd 100644 --- a/sysdeps/unix/arm/sysdep.S +++ b/sysdeps/unix/arm/sysdep.S @@ -1,5 +1,5 @@ /* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2002, 2003, - 2004, 2005 + 2004, 2005, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -44,6 +44,7 @@ syscall_error: #if USE___THREAD mov ip, lr + cfi_register (lr, ip) mov r1, r0 mov r0, #0xffff0fff @@ -66,9 +67,13 @@ syscall_error: 1: .word C_SYMBOL_NAME(rtld_errno) - 0b - 8 #elif defined(_LIBC_REENTRANT) str lr, [sp, #-4]! + cfi_adjust_cfa_offset (4) + cfi_rel_offset (lr, 0) str r0, [sp, #-4]! + cfi_adjust_cfa_offset (4) bl PLTJMP(C_SYMBOL_NAME(__errno_location)) ldr r1, [sp], #4 + cfi_adjust_cfa_offset (-4) str r1, [r0] mvn r0, $0 ldr pc, [sp], #4 diff --git a/sysdeps/unix/sysv/linux/arm/clone.S b/sysdeps/unix/sysv/linux/arm/clone.S index 1a19f5b558f..178b0f1efdd 100644 --- a/sysdeps/unix/sysv/linux/arm/clone.S +++ b/sysdeps/unix/sysv/linux/arm/clone.S @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1997, 1998, 1999, 2002, 2005, 2008, 2009 +/* Copyright (C) 1996, 1997, 1998, 1999, 2002, 2005, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Pat Beirne @@ -52,8 +52,13 @@ ENTRY(__clone) @ new sp is already in r1 #ifdef __ARM_EABI__ stmfd sp!, {r4, r7} + cfi_adjust_cfa_offset (8) + cfi_rel_offset (r4, 0) + cfi_rel_offset (r7, 4) #else str r4, [sp, #-8]! + cfi_adjust_cfa_offset (8) + cfi_rel_offset (r4, 0) #endif ldr r2, [sp, #8] ldr r3, [sp, #12] @@ -64,6 +69,7 @@ ENTRY(__clone) #else swi SYS_ify(clone) #endif + cfi_endproc cmp r0, #0 beq 1f #ifdef __ARM_EABI__ @@ -74,6 +80,8 @@ ENTRY(__clone) blt PLTJMP(C_SYMBOL_NAME(__syscall_error)) RETINSTR(, lr) + cfi_startproc + cfi_undefined (lr) 1: #ifdef RESET_PID tst ip, #CLONE_THREAD diff --git a/sysdeps/unix/sysv/linux/arm/eabi/____longjmp_chk.S b/sysdeps/unix/sysv/linux/arm/eabi/____longjmp_chk.S index f92a382e441..423e7776eae 100644 --- a/sysdeps/unix/sysv/linux/arm/eabi/____longjmp_chk.S +++ b/sysdeps/unix/sysv/linux/arm/eabi/____longjmp_chk.S @@ -30,6 +30,7 @@ longjmp_msg: #ifdef PIC # define CALL_FAIL \ ldr sl, .L_GOT; \ + cfi_undefined (sl); \ .L_GOT_OFF: \ add sl, pc, sl; \ ldr r0, .Lstr; \ @@ -48,12 +49,17 @@ longjmp_msg: #endif #define CHECK_SP(reg) \ + cfi_remember_state; \ cmp sp, reg; \ bls .Lok; \ mov r5, r0; \ + cfi_undefined (r5); \ mov r7, #SYS_ify(sigaltstack); \ + cfi_undefined (r7); \ mov r0, #0; \ - sub sp, sp, #16; \ + sub sp, sp, #16; /* >= sizeof (stack_t) */ \ + cfi_adjust_cfa_offset (16); \ + cfi_remember_state; \ mov r1, sp; \ swi #0; \ cmp r0, #0; \ @@ -69,8 +75,10 @@ longjmp_msg: bhi .Lok2; \ .Lfail: \ CALL_FAIL \ + cfi_restore_state; \ .Lok2: \ mov r0, r5; \ + cfi_restore_state; \ .Lok: #include <__longjmp.S> diff --git a/sysdeps/unix/sysv/linux/arm/eabi/mmap64.S b/sysdeps/unix/sysv/linux/arm/eabi/mmap64.S index 38fac06c35f..59352f71d4f 100644 --- a/sysdeps/unix/sysv/linux/arm/eabi/mmap64.S +++ b/sysdeps/unix/sysv/linux/arm/eabi/mmap64.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2000, 2003, 2005 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2003, 2005, 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 @@ -34,8 +34,13 @@ ENTRY (__mmap64) ldr ip, [sp, $LOW_OFFSET] str r5, [sp, #-4]! + cfi_adjust_cfa_offset (4) + cfi_rel_offset (r5, 0) ldr r5, [sp, $HIGH_OFFSET] str r4, [sp, #-4]! + cfi_adjust_cfa_offset (4) + cfi_rel_offset (r4, 0) + cfi_remember_state movs r4, ip, lsl $20 @ check that offset is page-aligned mov ip, ip, lsr $12 moveqs r4, r5, lsr $12 @ check for overflow @@ -45,11 +50,19 @@ ENTRY (__mmap64) DO_CALL (mmap2, 0) cmn r0, $4096 ldmfd sp!, {r4, r5} + cfi_adjust_cfa_offset (-8) + cfi_restore (r4) + cfi_restore (r5) RETINSTR(cc, lr) b PLTJMP(syscall_error) + + cfi_restore_state .Linval: mov r0, $-EINVAL ldmfd sp!, {r4, r5} + cfi_adjust_cfa_offset (-8) + cfi_restore (r4) + cfi_restore (r5) b PLTJMP(syscall_error) PSEUDO_END (__mmap64) diff --git a/sysdeps/unix/sysv/linux/arm/eabi/nptl/sysdep-cancel.h b/sysdeps/unix/sysv/linux/arm/eabi/nptl/sysdep-cancel.h index 73912d51745..458558b9cf5 100644 --- a/sysdeps/unix/sysv/linux/arm/eabi/nptl/sysdep-cancel.h +++ b/sysdeps/unix/sysv/linux/arm/eabi/nptl/sysdep-cancel.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 2005, 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 @@ -36,17 +36,22 @@ .type __##syscall_name##_nocancel,%function; \ .globl __##syscall_name##_nocancel; \ __##syscall_name##_nocancel: \ + .cfi_sections .debug_frame; \ + cfi_startproc; \ DO_CALL (syscall_name, args); \ PSEUDO_RET; \ + cfi_endproc; \ .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \ ENTRY (name); \ SINGLE_THREAD_P; \ DOARGS_##args; \ bne .Lpseudo_cancel; \ + cfi_remember_state; \ DO_CALL (syscall_name, 0); \ UNDOARGS_##args; \ cmn r0, $4096; \ PSEUDO_RET; \ + cfi_restore_state; \ .Lpseudo_cancel: \ .fnstart; \ DOCARGS_##args; /* save syscall args etc. around CENABLE. */ \ @@ -62,41 +67,127 @@ mov r0, r7; /* retrieve return value. */ \ RESTORE_LR_##args; \ UNDOARGS_##args; \ - cmn r0, $4096; + cmn r0, $4096 /* DOARGS pushes four bytes on the stack for five arguments, eight bytes for six arguments, and nothing for fewer. In order to preserve doubleword alignment, sometimes we must save an extra register. */ -# define RESTART_UNWIND .fnend; .fnstart; .save {r7, lr} - -# define DOCARGS_0 stmfd sp!, {r7, lr}; .save {r7, lr} +# define RESTART_UNWIND \ + .fnend; \ + .fnstart; \ + .save {r7, lr} + +# define DOCARGS_0 \ + stmfd sp!, {r7, lr}; \ + cfi_adjust_cfa_offset (8); \ + cfi_rel_offset (r7, 0); \ + cfi_rel_offset (lr, 4); \ + .save {r7, lr} # define UNDOCARGS_0 -# define RESTORE_LR_0 ldmfd sp!, {r7, lr}; - -# define DOCARGS_1 stmfd sp!, {r0, r1, r7, lr}; .save {r7, lr}; .pad #8 -# define UNDOCARGS_1 ldr r0, [sp], #8; RESTART_UNWIND -# define RESTORE_LR_1 RESTORE_LR_0 - -# define DOCARGS_2 stmfd sp!, {r0, r1, r7, lr}; .save {r7, lr}; .pad #8 -# define UNDOCARGS_2 ldmfd sp!, {r0, r1}; RESTART_UNWIND -# define RESTORE_LR_2 RESTORE_LR_0 - -# define DOCARGS_3 stmfd sp!, {r0, r1, r2, r3, r7, lr}; .save {r7, lr}; .pad #16 -# define UNDOCARGS_3 ldmfd sp!, {r0, r1, r2, r3}; RESTART_UNWIND -# define RESTORE_LR_3 RESTORE_LR_0 - -# define DOCARGS_4 stmfd sp!, {r0, r1, r2, r3, r7, lr}; .save {r7, lr}; .pad #16 -# define UNDOCARGS_4 ldmfd sp!, {r0, r1, r2, r3}; RESTART_UNWIND -# define RESTORE_LR_4 RESTORE_LR_0 - -# define DOCARGS_5 .save {r4}; stmfd sp!, {r0, r1, r2, r3, r4, r7, lr}; .save {r7, lr}; .pad #20 -# define UNDOCARGS_5 ldmfd sp!, {r0, r1, r2, r3}; .fnend; .fnstart; .save {r4}; .save {r7, lr}; .pad #4 -# define RESTORE_LR_5 ldmfd sp!, {r4, r7, lr} - -# define DOCARGS_6 .save {r4, r5}; stmfd sp!, {r0, r1, r2, r3, r7, lr}; .save {r7, lr}; .pad #16 -# define UNDOCARGS_6 ldmfd sp!, {r0, r1, r2, r3}; .fnend; .fnstart; .save {r4, r5}; .save {r7, lr} -# define RESTORE_LR_6 RESTORE_LR_0 +# define RESTORE_LR_0 \ + ldmfd sp!, {r7, lr}; \ + cfi_adjust_cfa_offset (-8); \ + cfi_restore (r7); \ + cfi_restore (lr) + +# define DOCARGS_1 \ + stmfd sp!, {r0, r1, r7, lr}; \ + cfi_adjust_cfa_offset (16); \ + cfi_rel_offset (r7, 8); \ + cfi_rel_offset (lr, 12); \ + .save {r7, lr}; \ + .pad #8 +# define UNDOCARGS_1 \ + ldr r0, [sp], #8; \ + cfi_adjust_cfa_offset (-8); \ + RESTART_UNWIND +# define RESTORE_LR_1 \ + RESTORE_LR_0 + +# define DOCARGS_2 \ + stmfd sp!, {r0, r1, r7, lr}; \ + cfi_adjust_cfa_offset (16); \ + cfi_rel_offset (r7, 8); \ + cfi_rel_offset (lr, 12); \ + .save {r7, lr}; \ + .pad #8 +# define UNDOCARGS_2 \ + ldmfd sp!, {r0, r1}; \ + cfi_adjust_cfa_offset (-8); \ + RESTART_UNWIND +# define RESTORE_LR_2 \ + RESTORE_LR_0 + +# define DOCARGS_3 \ + stmfd sp!, {r0, r1, r2, r3, r7, lr}; \ + cfi_adjust_cfa_offset (24); \ + cfi_rel_offset (r7, 16); \ + cfi_rel_offset (lr, 20); \ + .save {r7, lr}; \ + .pad #16 +# define UNDOCARGS_3 \ + ldmfd sp!, {r0, r1, r2, r3}; \ + cfi_adjust_cfa_offset (-16); \ + RESTART_UNWIND +# define RESTORE_LR_3 \ + RESTORE_LR_0 + +# define DOCARGS_4 \ + stmfd sp!, {r0, r1, r2, r3, r7, lr}; \ + cfi_adjust_cfa_offset (24); \ + cfi_rel_offset (r7, 16); \ + cfi_rel_offset (lr, 20); \ + .save {r7, lr}; \ + .pad #16 +# define UNDOCARGS_4 \ + ldmfd sp!, {r0, r1, r2, r3}; \ + cfi_adjust_cfa_offset (-16); \ + RESTART_UNWIND +# define RESTORE_LR_4 \ + RESTORE_LR_0 + +/* r4 is only stmfd'ed for correct stack alignment. */ +# define DOCARGS_5 \ + .save {r4}; \ + stmfd sp!, {r0, r1, r2, r3, r4, r7, lr}; \ + cfi_adjust_cfa_offset (28); \ + cfi_rel_offset (r7, 20); \ + cfi_rel_offset (lr, 24); \ + .save {r7, lr}; \ + .pad #20 +# define UNDOCARGS_5 \ + ldmfd sp!, {r0, r1, r2, r3}; \ + cfi_adjust_cfa_offset (-16); \ + .fnend; \ + .fnstart; \ + .save {r4}; \ + .save {r7, lr}; \ + .pad #4 +# define RESTORE_LR_5 \ + ldmfd sp!, {r4, r7, lr}; \ + cfi_adjust_cfa_offset (-12); \ + /* r4 will be marked as restored later. */ \ + cfi_restore (r7); \ + cfi_restore (lr) + +# define DOCARGS_6 \ + .save {r4, r5}; \ + stmfd sp!, {r0, r1, r2, r3, r7, lr}; \ + cfi_adjust_cfa_offset (24); \ + cfi_rel_offset (r7, 16); \ + cfi_rel_offset (lr, 20); \ + .save {r7, lr}; \ + .pad #16 +# define UNDOCARGS_6 \ + ldmfd sp!, {r0, r1, r2, r3}; \ + cfi_adjust_cfa_offset (-16); \ + .fnend; \ + .fnstart; \ + .save {r4, r5}; \ + .save {r7, lr} +# define RESTORE_LR_6 \ + RESTORE_LR_0 # ifdef IS_IN_libpthread # define CENABLE bl PLTJMP(__pthread_enable_asynccancel) @@ -136,9 +227,13 @@ extern int __local_multiple_threads attribute_hidden; # define PSEUDO_PROLOGUE # define SINGLE_THREAD_P \ stmfd sp!, {r0, lr}; \ + cfi_adjust_cfa_offset (8); \ + cfi_rel_offset (lr, 4); \ bl __aeabi_read_tp; \ ldr ip, [r0, #MULTIPLE_THREADS_OFFSET]; \ ldmfd sp!, {r0, lr}; \ + cfi_adjust_cfa_offset (-8); \ + cfi_restore (lr); \ teq ip, #0 # define SINGLE_THREAD_P_PIC(x) SINGLE_THREAD_P # endif diff --git a/sysdeps/unix/sysv/linux/arm/eabi/nptl/unwind-forcedunwind.c b/sysdeps/unix/sysv/linux/arm/eabi/nptl/unwind-forcedunwind.c index ed321a39640..011746d0e86 100644 --- a/sysdeps/unix/sysv/linux/arm/eabi/nptl/unwind-forcedunwind.c +++ b/sysdeps/unix/sysv/linux/arm/eabi/nptl/unwind-forcedunwind.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2005, 2007, 2009 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2005, 2007, 2009, 2010 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek . @@ -89,7 +89,15 @@ asm ( " .globl _Unwind_Resume\n" " .type _Unwind_Resume, %function\n" "_Unwind_Resume:\n" +" .cfi_sections .debug_frame\n" +" " CFI_STARTPROC "\n" " stmfd sp!, {r4, r5, r6, lr}\n" +" " CFI_ADJUST_CFA_OFFSET (16)" \n" +" " CFI_REL_OFFSET (r4, 0) "\n" +" " CFI_REL_OFFSET (r5, 4) "\n" +" " CFI_REL_OFFSET (r6, 8) "\n" +" " CFI_REL_OFFSET (lr, 12) "\n" +" " CFI_REMEMBER_STATE "\n" " ldr r4, 1f\n" " ldr r5, 2f\n" "3: add r4, pc, r4\n" @@ -99,10 +107,17 @@ asm ( " beq 4f\n" "5: mov r0, r6\n" " ldmfd sp!, {r4, r5, r6, lr}\n" +" " CFI_ADJUST_CFA_OFFSET (-16) "\n" +" " CFI_RESTORE (r4) "\n" +" " CFI_RESTORE (r5) "\n" +" " CFI_RESTORE (r6) "\n" +" " CFI_RESTORE (lr) "\n" " bx r3\n" +" " CFI_RESTORE_STATE "\n" "4: bl pthread_cancel_init\n" " ldr r3, [r4, r5]\n" " b 5b\n" +" " CFI_ENDPROC "\n" " .align 2\n" #ifdef __thumb2__ "1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 4\n" diff --git a/sysdeps/unix/sysv/linux/arm/eabi/nptl/unwind-resume.c b/sysdeps/unix/sysv/linux/arm/eabi/nptl/unwind-resume.c index 3c780b71372..cdab10e3052 100644 --- a/sysdeps/unix/sysv/linux/arm/eabi/nptl/unwind-resume.c +++ b/sysdeps/unix/sysv/linux/arm/eabi/nptl/unwind-resume.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2005 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2005, 2010 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek . @@ -52,7 +52,15 @@ asm ( " .globl _Unwind_Resume\n" " .type _Unwind_Resume, %function\n" "_Unwind_Resume:\n" +" .cfi_sections .debug_frame\n" +" " CFI_STARTPROC "\n" " stmfd sp!, {r4, r5, r6, lr}\n" +" " CFI_ADJUST_CFA_OFFSET (16)" \n" +" " CFI_REL_OFFSET (r4, 0) "\n" +" " CFI_REL_OFFSET (r5, 4) "\n" +" " CFI_REL_OFFSET (r6, 8) "\n" +" " CFI_REL_OFFSET (lr, 12) "\n" +" " CFI_REMEMBER_STATE "\n" " ldr r4, 1f\n" " ldr r5, 2f\n" "3: add r4, pc, r4\n" @@ -62,10 +70,17 @@ asm ( " beq 4f\n" "5: mov r0, r6\n" " ldmfd sp!, {r4, r5, r6, lr}\n" +" " CFI_ADJUST_CFA_OFFSET (-16) "\n" +" " CFI_RESTORE (r4) "\n" +" " CFI_RESTORE (r5) "\n" +" " CFI_RESTORE (r6) "\n" +" " CFI_RESTORE (lr) "\n" " bx r3\n" +" " CFI_RESTORE_STATE "\n" "4: bl init\n" " ldr r3, [r4, r5]\n" " b 5b\n" +" " CFI_ENDPROC "\n" " .align 2\n" #ifdef __thumb2__ "1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 4\n" diff --git a/sysdeps/unix/sysv/linux/arm/eabi/sigrestorer.S b/sysdeps/unix/sysv/linux/arm/eabi/sigrestorer.S index cc06a55972a..09ff9c7d91c 100644 --- a/sysdeps/unix/sysv/linux/arm/eabi/sigrestorer.S +++ b/sysdeps/unix/sysv/linux/arm/eabi/sigrestorer.S @@ -1,4 +1,4 @@ -/* Copyright (C) 1999, 2005 Free Software Foundation, Inc. +/* Copyright (C) 1999, 2005, 2009, 2010 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 @@ -34,46 +34,89 @@ Because the signal frame layout changed in 2.6.18, we provide two copies of these functions with different unwind information. */ +/* Used in ENTRY. */ +#undef cfi_startproc +#define cfi_startproc \ + .cfi_startproc simple; \ + .cfi_signal_frame + +/* The CFA is not computed / used correctly here; this is neither trivial to + do, nor is it needed. */ +#define CFI \ + cfi_def_cfa (sp, 0); \ + cfi_offset (r0, OFFSET + 0 * 4); \ + cfi_offset (r1, OFFSET + 1 * 4); \ + cfi_offset (r2, OFFSET + 2 * 4); \ + cfi_offset (r3, OFFSET + 3 * 4); \ + cfi_offset (r4, OFFSET + 4 * 4); \ + cfi_offset (r5, OFFSET + 5 * 4); \ + cfi_offset (r6, OFFSET + 6 * 4); \ + cfi_offset (r7, OFFSET + 7 * 4); \ + cfi_offset (r8, OFFSET + 8 * 4); \ + cfi_offset (r9, OFFSET + 9 * 4); \ + cfi_offset (r10, OFFSET + 10 * 4); \ + cfi_offset (r11, OFFSET + 11 * 4); \ + cfi_offset (r12, OFFSET + 12 * 4); \ + cfi_offset (r13, OFFSET + 13 * 4); \ + cfi_offset (r14, OFFSET + 14 * 4); \ + cfi_offset (r15, OFFSET + 15 * 4) + #ifndef __ASSUME_SIGFRAME_V2 +#define OFFSET 12 .fnstart .save {r0-r15} - .pad #12 + .pad #OFFSET nop ENTRY(__default_sa_restorer_v1) + CFI mov r7, $SYS_ify(sigreturn) swi 0x0 .fnend -#endif +END(__default_sa_restorer_v1) +#undef OFFSET +#endif /* __ASSUME_SIGFRAME_V2 */ +#define OFFSET 32 .fnstart .save {r0-r15} - .pad #32 + .pad #OFFSET nop ENTRY(__default_sa_restorer_v2) + CFI mov r7, $SYS_ify(sigreturn) swi 0x0 .fnend +END(__default_sa_restorer_v2) +#undef OFFSET #ifdef __NR_rt_sigreturn #ifndef __ASSUME_SIGFRAME_V2 +#define OFFSET 168 .fnstart .save {r0-r15} - .pad #168 + .pad #OFFSET nop ENTRY(__default_rt_sa_restorer_v1) + CFI mov r7, $SYS_ify(rt_sigreturn) swi 0x0 .fnend -#endif +END(__default_rt_sa_restorer_v1) +#undef OFFSET +#endif /* __ASSUME_SIGFRAME_V2 */ +#define OFFSET 160 .fnstart .save {r0-r15} - .pad #160 + .pad #OFFSET nop ENTRY(__default_rt_sa_restorer_v2) + CFI mov r7, $SYS_ify(rt_sigreturn) swi 0x0 .fnend +END(__default_rt_sa_restorer_v2) +#undef OFFSET -#endif +#endif /* __NR_rt_sigreturn */ diff --git a/sysdeps/unix/sysv/linux/arm/eabi/syscall.S b/sysdeps/unix/sysv/linux/arm/eabi/syscall.S index 59ca051a8b2..f6d775e0aad 100644 --- a/sysdeps/unix/sysv/linux/arm/eabi/syscall.S +++ b/sysdeps/unix/sysv/linux/arm/eabi/syscall.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2005 Free Software Foundation, Inc. +/* Copyright (C) 2005, 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 @@ -25,6 +25,11 @@ ENTRY (syscall) mov ip, sp stmfd sp!, {r4, r5, r6, r7} + cfi_adjust_cfa_offset (16) + cfi_rel_offset (r4, 0) + cfi_rel_offset (r5, 4) + cfi_rel_offset (r6, 8) + cfi_rel_offset (r7, 12) mov r7, r0 mov r0, r1 mov r1, r2 @@ -32,6 +37,11 @@ ENTRY (syscall) ldmfd ip, {r3, r4, r5, r6} swi 0x0 ldmfd sp!, {r4, r5, r6, r7} + cfi_adjust_cfa_offset (-16) + cfi_restore (r4) + cfi_restore (r5) + cfi_restore (r6) + cfi_restore (r7) cmn r0, #4096 RETINSTR(cc, lr) b PLTJMP(syscall_error) diff --git a/sysdeps/unix/sysv/linux/arm/eabi/sysdep.h b/sysdeps/unix/sysv/linux/arm/eabi/sysdep.h index a7dd40d7414..9d90f3e35fb 100644 --- a/sysdeps/unix/sysv/linux/arm/eabi/sysdep.h +++ b/sysdeps/unix/sysv/linux/arm/eabi/sysdep.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2005, 2006, 2007 +/* Copyright (C) 2005, 2006, 2007, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -50,6 +50,7 @@ For the moment the LOAD_ARGS_7 is sacrificed. We can't use push/pop inside the asm because that breaks unwinding (ie. thread cancellation). */ +/* FIXME: the str / ldr of r7 are not covered by CFI information. */ #undef LOAD_ARGS_7 #undef INTERNAL_SYSCALL_RAW #define INTERNAL_SYSCALL_RAW(name, err, nr, args...) \ @@ -100,11 +101,13 @@ #undef DO_CALL #define DO_CALL(syscall_name, args) \ - DOARGS_##args \ + DOARGS_##args; \ mov ip, r7; \ + cfi_register (r7, ip); \ ldr r7, =SYS_ify (syscall_name); \ swi 0x0; \ mov r7, ip; \ + cfi_restore (r7); \ UNDOARGS_##args #endif /* _LINUX_ARM_EABI_SYSDEP_H */ diff --git a/sysdeps/unix/sysv/linux/arm/mmap.S b/sysdeps/unix/sysv/linux/arm/mmap.S index 9227bd79f32..abac9e0669b 100644 --- a/sysdeps/unix/sysv/linux/arm/mmap.S +++ b/sysdeps/unix/sysv/linux/arm/mmap.S @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 2000, 2003, 2005 Free Software Foundation, Inc. +/* Copyright (C) 1998, 2000, 2003, 2005, 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 @@ -33,8 +33,13 @@ ENTRY (__mmap) /* shuffle args */ str r5, [sp, #-4]! + cfi_adjust_cfa_offset (4) + cfi_rel_offset (r5, 0) ldr r5, [sp, #8] str r4, [sp, #-4]! + cfi_adjust_cfa_offset (4) + cfi_rel_offset (r4, 0) + cfi_remember_state ldr r4, [sp, #8] /* convert offset to pages */ @@ -48,12 +53,17 @@ ENTRY (__mmap) /* restore registers */ 2: ldr r4, [sp], #4 + cfi_adjust_cfa_offset (-4) + cfi_restore (r4) ldr r5, [sp], #4 + cfi_adjust_cfa_offset (-4) + cfi_restore (r5) cmn r0, $4096 RETINSTR(cc, lr) b PLTJMP(syscall_error) + cfi_restore_state .Linval: mov r0, #-EINVAL b 2b @@ -74,6 +84,7 @@ ENTRY (__mmap) /* store args on the stack */ stmdb sp!, {a1-a4} + cfi_adjust_cfa_offset (16) /* do the syscall */ mov a1, sp @@ -81,6 +92,7 @@ ENTRY (__mmap) /* pop args off the stack. */ add sp, sp, #16 + cfi_adjust_cfa_offset (-16) cmn r0, $4096 RETINSTR(cc, lr) diff --git a/sysdeps/unix/sysv/linux/arm/nptl/pt-vfork.S b/sysdeps/unix/sysv/linux/arm/nptl/pt-vfork.S index 1c2e1f5547d..964a389a652 100644 --- a/sysdeps/unix/sysv/linux/arm/nptl/pt-vfork.S +++ b/sysdeps/unix/sysv/linux/arm/nptl/pt-vfork.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2005 Free Software Foundation, Inc. +/* Copyright (C) 2005, 2010 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 @@ -21,10 +21,14 @@ /* Save the PID value. */ #define SAVE_PID \ str lr, [sp, #-4]!; /* Save LR. */ \ + cfi_adjust_cfa_offset (4); \ + cfi_rel_offset (lr, 0); \ mov r0, #0xffff0fff; /* Point to the high page. */ \ mov lr, pc; /* Save our return address. */ \ sub pc, r0, #31; /* Jump to the TLS entry. */ \ ldr lr, [sp], #4; /* Restore LR. */ \ + cfi_adjust_cfa_offset (-4); \ + cfi_restore (lr); \ mov r2, r0; /* Save the TLS addr in r2. */ \ ldr r3, [r2, #PID_OFFSET]; /* Load the saved PID. */ \ rsb r0, r3, #0; /* Negate it. */ \ diff --git a/sysdeps/unix/sysv/linux/arm/nptl/vfork.S b/sysdeps/unix/sysv/linux/arm/nptl/vfork.S index 87e055e6577..009d03ad958 100644 --- a/sysdeps/unix/sysv/linux/arm/nptl/vfork.S +++ b/sysdeps/unix/sysv/linux/arm/nptl/vfork.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2005 Free Software Foundation, Inc. +/* Copyright (C) 2005, 2010 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 @@ -21,10 +21,14 @@ /* Save the PID value. */ #define SAVE_PID \ str lr, [sp, #-4]!; /* Save LR. */ \ + cfi_adjust_cfa_offset (4); \ + cfi_rel_offset (lr, 0); \ mov r0, #0xffff0fff; /* Point to the high page. */ \ mov lr, pc; /* Save our return address. */ \ sub pc, r0, #31; /* Jump to the TLS entry. */ \ ldr lr, [sp], #4; /* Restore LR. */ \ + cfi_adjust_cfa_offset (-4); \ + cfi_restore (lr); \ mov r2, r0; /* Save the TLS addr in r2. */ \ ldr r3, [r2, #PID_OFFSET]; /* Load the saved PID. */ \ rsbs r0, r3, #0; /* Negate it. */ \ diff --git a/sysdeps/unix/sysv/linux/arm/sysdep.h b/sysdeps/unix/sysv/linux/arm/sysdep.h index 3911aee6260..bd5b2ce3e45 100644 --- a/sysdeps/unix/sysv/linux/arm/sysdep.h +++ b/sysdeps/unix/sysv/linux/arm/sysdep.h @@ -84,7 +84,7 @@ #undef PSEUDO_END #define PSEUDO_END(name) \ - SYSCALL_ERROR_HANDLER \ + SYSCALL_ERROR_HANDLER; \ END (name) #undef PSEUDO_NOERRNO @@ -129,17 +129,26 @@ __local_syscall_error: \ DO_RET(lr); \ 1: .word C_SYMBOL_NAME(rtld_errno) - 0b - 8; # else -#if defined(__ARM_ARCH_4T__) && defined(__THUMB_INTERWORK__) -#define POP_PC ldr lr, [sp], #4; bx lr -#else -#define POP_PC ldr pc, [sp], #4 -#endif +# if defined(__ARM_ARCH_4T__) && defined(__THUMB_INTERWORK__) +# define POP_PC \ + ldr lr, [sp], #4; \ + cfi_adjust_cfa_offset (-4); \ + cfi_restore (lr); \ + bx lr +# else +# define POP_PC \ + ldr pc, [sp], #4 +# endif # define SYSCALL_ERROR_HANDLER \ __local_syscall_error: \ str lr, [sp, #-4]!; \ + cfi_adjust_cfa_offset (4); \ + cfi_rel_offset (lr, 0); \ str r0, [sp, #-4]!; \ + cfi_adjust_cfa_offset (4); \ bl PLTJMP(C_SYMBOL_NAME(__errno_location)); \ ldr r1, [sp], #4; \ + cfi_adjust_cfa_offset (-4); \ rsb r1, r1, #0; \ str r1, [r0]; \ mvn r0, #0; \ @@ -179,7 +188,7 @@ __local_syscall_error: \ #undef DO_CALL #define DO_CALL(syscall_name, args) \ - DOARGS_##args \ + DOARGS_##args; \ swi SYS_ify (syscall_name); \ UNDOARGS_##args @@ -188,18 +197,47 @@ __local_syscall_error: \ #define DOARGS_2 /* nothing */ #define DOARGS_3 /* nothing */ #define DOARGS_4 /* nothing */ -#define DOARGS_5 str r4, [sp, $-4]!; ldr r4, [sp, $4]; -#define DOARGS_6 mov ip, sp; stmfd sp!, {r4, r5}; ldmia ip, {r4, r5}; -#define DOARGS_7 mov ip, sp; stmfd sp!, {r4, r5, r6}; ldmia ip, {r4, r5, r6}; +#define DOARGS_5 \ + str r4, [sp, $-4]!; \ + cfi_adjust_cfa_offset (4); \ + cfi_rel_offset (r4, 0); \ + ldr r4, [sp, $4] +#define DOARGS_6 \ + mov ip, sp; \ + stmfd sp!, {r4, r5}; \ + cfi_adjust_cfa_offset (8); \ + cfi_rel_offset (r4, 0); \ + cfi_rel_offset (r5, 4); \ + ldmia ip, {r4, r5} +#define DOARGS_7 \ + mov ip, sp; \ + stmfd sp!, {r4, r5, r6}; \ + cfi_adjust_cfa_offset (12); \ + cfi_rel_offset (r4, 0); \ + cfi_rel_offset (r5, 4); \ + cfi_rel_offset (r6, 8); \ + ldmia ip, {r4, r5, r6} #define UNDOARGS_0 /* nothing */ #define UNDOARGS_1 /* nothing */ #define UNDOARGS_2 /* nothing */ #define UNDOARGS_3 /* nothing */ #define UNDOARGS_4 /* nothing */ -#define UNDOARGS_5 ldr r4, [sp], $4; -#define UNDOARGS_6 ldmfd sp!, {r4, r5}; -#define UNDOARGS_7 ldmfd sp!, {r4, r5, r6}; +#define UNDOARGS_5 \ + ldr r4, [sp], $4; \ + cfi_adjust_cfa_offset (-4); \ + cfi_restore (r4) +#define UNDOARGS_6 \ + ldmfd sp!, {r4, r5}; \ + cfi_adjust_cfa_offset (-8); \ + cfi_restore (r4); \ + cfi_restore (r5) +#define UNDOARGS_7 \ + ldmfd sp!, {r4, r5, r6}; \ + cfi_adjust_cfa_offset (-12); \ + cfi_restore (r4); \ + cfi_restore (r5); \ + cfi_restore (r6) #else /* not __ASSEMBLER__ */