Create ARM unwind records for system call stubs.
This commit is contained in:
parent
2242368302
commit
738860089d
|
@ -1,3 +1,30 @@
|
||||||
|
2011-03-21 Ulrich Weigand <ulrich.weigand@linaro.org>
|
||||||
|
|
||||||
|
* sysdeps/unix/sysv/arm/eabi/sysdep.h (DO_CALL): Do not save/restore
|
||||||
|
r7 into IP.
|
||||||
|
(DOARGS_0, UNDOARGS_0): Redefine to save/restore r7 to the stack.
|
||||||
|
Create appropriate ARM unwind record.
|
||||||
|
(DOARGS_1, UNDOARGS_1): Likewise.
|
||||||
|
(DOARGS_2, UNDOARGS_2): Likewise.
|
||||||
|
(DOARGS_3, UNDOARGS_3): Likewise.
|
||||||
|
(DOARGS_4, UNDOARGS_4): Likewise.
|
||||||
|
(DOARGS_5, UNDOARGS_5): Likewise.
|
||||||
|
(DOARGS_6, UNDOARGS_6): Likewise.
|
||||||
|
(DOARGS_7, UNDOARGS_7): Likewise.
|
||||||
|
* sysdeps/unix/sysv/arm/eabi/nptl/sysdep-cancel.h (PSEUDO): Adapt to
|
||||||
|
DO_CALL/DOARGS_xxx/UNDOARGS_xxx changes.
|
||||||
|
(RESTART_UNWIND): Likewise.
|
||||||
|
(DOCARGS_0, RESTORE_LR_0): Likewise.
|
||||||
|
(DOCARGS_1): Likewise.
|
||||||
|
(DOCARGS_2): Likewise.
|
||||||
|
(DOCARGS_3): Likewise.
|
||||||
|
(DOCARGS_4): Likewise.
|
||||||
|
(DOCARGS_5, UNDOCARGS_5, RESTORE_LR_5): Likewise.
|
||||||
|
(DOCARGS_6, UNDOCARGS_6): Likewise.
|
||||||
|
* sysdeps/unix/sysv/linux/arm/vfork.S (__vfork): Do no use DO_CALL to
|
||||||
|
call vfork. In the __ARM_EABI__ case, save r7 both to IP (to restore
|
||||||
|
from) and the stack (to create an ARM unwind record).
|
||||||
|
|
||||||
2011-03-21 Joseph Myers <joseph@codesourcery.com>
|
2011-03-21 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
* sysdeps/arm/eabi/__longjmp.S, sysdeps/arm/eabi/bits/fenv.h,
|
* sysdeps/arm/eabi/__longjmp.S, sysdeps/arm/eabi/bits/fenv.h,
|
||||||
|
|
|
@ -47,20 +47,20 @@
|
||||||
DOARGS_##args; \
|
DOARGS_##args; \
|
||||||
bne .Lpseudo_cancel; \
|
bne .Lpseudo_cancel; \
|
||||||
cfi_remember_state; \
|
cfi_remember_state; \
|
||||||
DO_CALL (syscall_name, 0); \
|
ldr r7, =SYS_ify (syscall_name); \
|
||||||
|
swi 0x0; \
|
||||||
UNDOARGS_##args; \
|
UNDOARGS_##args; \
|
||||||
cmn r0, $4096; \
|
cmn r0, $4096; \
|
||||||
PSEUDO_RET; \
|
PSEUDO_RET; \
|
||||||
cfi_restore_state; \
|
cfi_restore_state; \
|
||||||
.Lpseudo_cancel: \
|
.Lpseudo_cancel: \
|
||||||
.fnstart; \
|
.fnstart; /* matched by the .fnend in UNDOARGS below. */ \
|
||||||
DOCARGS_##args; /* save syscall args etc. around CENABLE. */ \
|
DOCARGS_##args; /* save syscall args etc. around CENABLE. */ \
|
||||||
CENABLE; \
|
CENABLE; \
|
||||||
mov ip, r0; /* put mask in safe place. */ \
|
mov ip, r0; /* put mask in safe place. */ \
|
||||||
UNDOCARGS_##args; /* restore syscall args. */ \
|
UNDOCARGS_##args; /* restore syscall args. */ \
|
||||||
ldr r7, =SYS_ify (syscall_name); \
|
ldr r7, =SYS_ify (syscall_name); \
|
||||||
swi 0x0; /* do the call. */ \
|
swi 0x0; /* do the call. */ \
|
||||||
.fnend; /* Past here we can't easily unwind. */ \
|
|
||||||
mov r7, r0; /* save syscall return value. */ \
|
mov r7, r0; /* save syscall return value. */ \
|
||||||
mov r0, ip; /* get mask back. */ \
|
mov r0, ip; /* get mask back. */ \
|
||||||
CDISABLE; \
|
CDISABLE; \
|
||||||
|
@ -69,34 +69,34 @@
|
||||||
UNDOARGS_##args; \
|
UNDOARGS_##args; \
|
||||||
cmn r0, $4096
|
cmn r0, $4096
|
||||||
|
|
||||||
/* DOARGS pushes four bytes on the stack for five arguments, eight bytes for
|
/* DOARGS pushes eight bytes on the stack for five arguments, twelve bytes for
|
||||||
six arguments, and nothing for fewer. In order to preserve doubleword
|
six arguments, and four bytes for fewer. In order to preserve doubleword
|
||||||
alignment, sometimes we must save an extra register. */
|
alignment, sometimes we must save an extra register. */
|
||||||
|
|
||||||
# define RESTART_UNWIND \
|
# define RESTART_UNWIND \
|
||||||
.fnend; \
|
.fnend; \
|
||||||
.fnstart; \
|
.fnstart; \
|
||||||
.save {r7, lr}
|
.save {r7}; \
|
||||||
|
.save {lr}
|
||||||
|
|
||||||
# define DOCARGS_0 \
|
# define DOCARGS_0 \
|
||||||
stmfd sp!, {r7, lr}; \
|
.save {r7}; \
|
||||||
cfi_adjust_cfa_offset (8); \
|
str lr, [sp, #-4]!; \
|
||||||
cfi_rel_offset (r7, 0); \
|
cfi_adjust_cfa_offset (4); \
|
||||||
cfi_rel_offset (lr, 4); \
|
cfi_rel_offset (lr, 0); \
|
||||||
.save {r7, lr}
|
.save {lr}
|
||||||
# define UNDOCARGS_0
|
# define UNDOCARGS_0
|
||||||
# define RESTORE_LR_0 \
|
# define RESTORE_LR_0 \
|
||||||
ldmfd sp!, {r7, lr}; \
|
ldr lr, [sp], #4; \
|
||||||
cfi_adjust_cfa_offset (-8); \
|
cfi_adjust_cfa_offset (-4); \
|
||||||
cfi_restore (r7); \
|
|
||||||
cfi_restore (lr)
|
cfi_restore (lr)
|
||||||
|
|
||||||
# define DOCARGS_1 \
|
# define DOCARGS_1 \
|
||||||
stmfd sp!, {r0, r1, r7, lr}; \
|
.save {r7}; \
|
||||||
cfi_adjust_cfa_offset (16); \
|
stmfd sp!, {r0, r1, lr}; \
|
||||||
cfi_rel_offset (r7, 8); \
|
cfi_adjust_cfa_offset (12); \
|
||||||
cfi_rel_offset (lr, 12); \
|
cfi_rel_offset (lr, 8); \
|
||||||
.save {r7, lr}; \
|
.save {lr}; \
|
||||||
.pad #8
|
.pad #8
|
||||||
# define UNDOCARGS_1 \
|
# define UNDOCARGS_1 \
|
||||||
ldr r0, [sp], #8; \
|
ldr r0, [sp], #8; \
|
||||||
|
@ -106,11 +106,11 @@
|
||||||
RESTORE_LR_0
|
RESTORE_LR_0
|
||||||
|
|
||||||
# define DOCARGS_2 \
|
# define DOCARGS_2 \
|
||||||
stmfd sp!, {r0, r1, r7, lr}; \
|
.save {r7}; \
|
||||||
cfi_adjust_cfa_offset (16); \
|
stmfd sp!, {r0, r1, lr}; \
|
||||||
cfi_rel_offset (r7, 8); \
|
cfi_adjust_cfa_offset (12); \
|
||||||
cfi_rel_offset (lr, 12); \
|
cfi_rel_offset (lr, 8); \
|
||||||
.save {r7, lr}; \
|
.save {lr}; \
|
||||||
.pad #8
|
.pad #8
|
||||||
# define UNDOCARGS_2 \
|
# define UNDOCARGS_2 \
|
||||||
ldmfd sp!, {r0, r1}; \
|
ldmfd sp!, {r0, r1}; \
|
||||||
|
@ -120,11 +120,11 @@
|
||||||
RESTORE_LR_0
|
RESTORE_LR_0
|
||||||
|
|
||||||
# define DOCARGS_3 \
|
# define DOCARGS_3 \
|
||||||
stmfd sp!, {r0, r1, r2, r3, r7, lr}; \
|
.save {r7}; \
|
||||||
cfi_adjust_cfa_offset (24); \
|
stmfd sp!, {r0, r1, r2, r3, lr}; \
|
||||||
cfi_rel_offset (r7, 16); \
|
cfi_adjust_cfa_offset (20); \
|
||||||
cfi_rel_offset (lr, 20); \
|
cfi_rel_offset (lr, 16); \
|
||||||
.save {r7, lr}; \
|
.save {lr}; \
|
||||||
.pad #16
|
.pad #16
|
||||||
# define UNDOCARGS_3 \
|
# define UNDOCARGS_3 \
|
||||||
ldmfd sp!, {r0, r1, r2, r3}; \
|
ldmfd sp!, {r0, r1, r2, r3}; \
|
||||||
|
@ -134,11 +134,11 @@
|
||||||
RESTORE_LR_0
|
RESTORE_LR_0
|
||||||
|
|
||||||
# define DOCARGS_4 \
|
# define DOCARGS_4 \
|
||||||
stmfd sp!, {r0, r1, r2, r3, r7, lr}; \
|
.save {r7}; \
|
||||||
cfi_adjust_cfa_offset (24); \
|
stmfd sp!, {r0, r1, r2, r3, lr}; \
|
||||||
cfi_rel_offset (r7, 16); \
|
cfi_adjust_cfa_offset (20); \
|
||||||
cfi_rel_offset (lr, 20); \
|
cfi_rel_offset (lr, 16); \
|
||||||
.save {r7, lr}; \
|
.save {lr}; \
|
||||||
.pad #16
|
.pad #16
|
||||||
# define UNDOCARGS_4 \
|
# define UNDOCARGS_4 \
|
||||||
ldmfd sp!, {r0, r1, r2, r3}; \
|
ldmfd sp!, {r0, r1, r2, r3}; \
|
||||||
|
@ -149,43 +149,40 @@
|
||||||
|
|
||||||
/* r4 is only stmfd'ed for correct stack alignment. */
|
/* r4 is only stmfd'ed for correct stack alignment. */
|
||||||
# define DOCARGS_5 \
|
# define DOCARGS_5 \
|
||||||
.save {r4}; \
|
.save {r4, r7}; \
|
||||||
stmfd sp!, {r0, r1, r2, r3, r4, r7, lr}; \
|
stmfd sp!, {r0, r1, r2, r3, r4, lr}; \
|
||||||
cfi_adjust_cfa_offset (28); \
|
cfi_adjust_cfa_offset (24); \
|
||||||
cfi_rel_offset (r7, 20); \
|
cfi_rel_offset (lr, 20); \
|
||||||
cfi_rel_offset (lr, 24); \
|
.save {lr}; \
|
||||||
.save {r7, lr}; \
|
|
||||||
.pad #20
|
.pad #20
|
||||||
# define UNDOCARGS_5 \
|
# define UNDOCARGS_5 \
|
||||||
ldmfd sp!, {r0, r1, r2, r3}; \
|
ldmfd sp!, {r0, r1, r2, r3}; \
|
||||||
cfi_adjust_cfa_offset (-16); \
|
cfi_adjust_cfa_offset (-16); \
|
||||||
.fnend; \
|
.fnend; \
|
||||||
.fnstart; \
|
.fnstart; \
|
||||||
.save {r4}; \
|
.save {r4, r7}; \
|
||||||
.save {r7, lr}; \
|
.save {lr}; \
|
||||||
.pad #4
|
.pad #4
|
||||||
# define RESTORE_LR_5 \
|
# define RESTORE_LR_5 \
|
||||||
ldmfd sp!, {r4, r7, lr}; \
|
ldmfd sp!, {r4, lr}; \
|
||||||
cfi_adjust_cfa_offset (-12); \
|
cfi_adjust_cfa_offset (-8); \
|
||||||
/* r4 will be marked as restored later. */ \
|
/* r4 will be marked as restored later. */ \
|
||||||
cfi_restore (r7); \
|
|
||||||
cfi_restore (lr)
|
cfi_restore (lr)
|
||||||
|
|
||||||
# define DOCARGS_6 \
|
# define DOCARGS_6 \
|
||||||
.save {r4, r5}; \
|
.save {r4, r5, r7}; \
|
||||||
stmfd sp!, {r0, r1, r2, r3, r7, lr}; \
|
stmfd sp!, {r0, r1, r2, r3, lr}; \
|
||||||
cfi_adjust_cfa_offset (24); \
|
cfi_adjust_cfa_offset (20); \
|
||||||
cfi_rel_offset (r7, 16); \
|
cfi_rel_offset (lr, 16); \
|
||||||
cfi_rel_offset (lr, 20); \
|
.save {lr}; \
|
||||||
.save {r7, lr}; \
|
|
||||||
.pad #16
|
.pad #16
|
||||||
# define UNDOCARGS_6 \
|
# define UNDOCARGS_6 \
|
||||||
ldmfd sp!, {r0, r1, r2, r3}; \
|
ldmfd sp!, {r0, r1, r2, r3}; \
|
||||||
cfi_adjust_cfa_offset (-16); \
|
cfi_adjust_cfa_offset (-16); \
|
||||||
.fnend; \
|
.fnend; \
|
||||||
.fnstart; \
|
.fnstart; \
|
||||||
.save {r4, r5}; \
|
.save {r4, r5, r7}; \
|
||||||
.save {r7, lr}
|
.save {lr};
|
||||||
# define RESTORE_LR_6 \
|
# define RESTORE_LR_6 \
|
||||||
RESTORE_LR_0
|
RESTORE_LR_0
|
||||||
|
|
||||||
|
|
|
@ -106,12 +106,95 @@
|
||||||
#undef DO_CALL
|
#undef DO_CALL
|
||||||
#define DO_CALL(syscall_name, args) \
|
#define DO_CALL(syscall_name, args) \
|
||||||
DOARGS_##args; \
|
DOARGS_##args; \
|
||||||
mov ip, r7; \
|
|
||||||
cfi_register (r7, ip); \
|
|
||||||
ldr r7, =SYS_ify (syscall_name); \
|
ldr r7, =SYS_ify (syscall_name); \
|
||||||
swi 0x0; \
|
swi 0x0; \
|
||||||
mov r7, ip; \
|
|
||||||
cfi_restore (r7); \
|
|
||||||
UNDOARGS_##args
|
UNDOARGS_##args
|
||||||
|
|
||||||
|
#undef DOARGS_0
|
||||||
|
#define DOARGS_0 \
|
||||||
|
.fnstart; \
|
||||||
|
str r7, [sp, #-4]!; \
|
||||||
|
cfi_adjust_cfa_offset (4); \
|
||||||
|
cfi_rel_offset (r7, 0); \
|
||||||
|
.save { r7 }
|
||||||
|
#undef DOARGS_1
|
||||||
|
#define DOARGS_1 DOARGS_0
|
||||||
|
#undef DOARGS_2
|
||||||
|
#define DOARGS_2 DOARGS_0
|
||||||
|
#undef DOARGS_3
|
||||||
|
#define DOARGS_3 DOARGS_0
|
||||||
|
#undef DOARGS_4
|
||||||
|
#define DOARGS_4 DOARGS_0
|
||||||
|
#undef DOARGS_5
|
||||||
|
#define DOARGS_5 \
|
||||||
|
.fnstart; \
|
||||||
|
stmfd sp!, {r4, r7}; \
|
||||||
|
cfi_adjust_cfa_offset (8); \
|
||||||
|
cfi_rel_offset (r4, 0); \
|
||||||
|
cfi_rel_offset (r7, 4); \
|
||||||
|
.save { r4, r7 }; \
|
||||||
|
ldr r4, [sp, #8]
|
||||||
|
#undef DOARGS_6
|
||||||
|
#define DOARGS_6 \
|
||||||
|
.fnstart; \
|
||||||
|
mov ip, sp; \
|
||||||
|
stmfd sp!, {r4, r5, r7}; \
|
||||||
|
cfi_adjust_cfa_offset (12); \
|
||||||
|
cfi_rel_offset (r4, 0); \
|
||||||
|
cfi_rel_offset (r5, 4); \
|
||||||
|
cfi_rel_offset (r7, 8); \
|
||||||
|
.save { r4, r5, r7 }; \
|
||||||
|
ldmia ip, {r4, r5}
|
||||||
|
#undef DOARGS_7
|
||||||
|
#define DOARGS_7 \
|
||||||
|
.fnstart; \
|
||||||
|
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); \
|
||||||
|
.save { r4, r5, r6, r7 }; \
|
||||||
|
ldmia ip, {r4, r5, r6}
|
||||||
|
|
||||||
|
#undef UNDOARGS_0
|
||||||
|
#define UNDOARGS_0 \
|
||||||
|
ldr r7, [sp], #4; \
|
||||||
|
cfi_adjust_cfa_offset (-4); \
|
||||||
|
cfi_restore (r7); \
|
||||||
|
.fnend
|
||||||
|
#undef UNDOARGS_1
|
||||||
|
#define UNDOARGS_1 UNDOARGS_0
|
||||||
|
#undef UNDOARGS_2
|
||||||
|
#define UNDOARGS_2 UNDOARGS_0
|
||||||
|
#undef UNDOARGS_3
|
||||||
|
#define UNDOARGS_3 UNDOARGS_0
|
||||||
|
#undef UNDOARGS_4
|
||||||
|
#define UNDOARGS_4 UNDOARGS_0
|
||||||
|
#undef UNDOARGS_5
|
||||||
|
#define UNDOARGS_5 \
|
||||||
|
ldmfd sp!, {r4, r7}; \
|
||||||
|
cfi_adjust_cfa_offset (-8); \
|
||||||
|
cfi_restore (r4); \
|
||||||
|
cfi_restore (r7); \
|
||||||
|
.fnend
|
||||||
|
#undef UNDOARGS_6
|
||||||
|
#define UNDOARGS_6 \
|
||||||
|
ldmfd sp!, {r4, r5, r7}; \
|
||||||
|
cfi_adjust_cfa_offset (-12); \
|
||||||
|
cfi_restore (r4); \
|
||||||
|
cfi_restore (r5); \
|
||||||
|
cfi_restore (r7); \
|
||||||
|
.fnend
|
||||||
|
#undef UNDOARGS_7
|
||||||
|
#define UNDOARGS_7 \
|
||||||
|
ldmfd sp!, {r4, r5, r6, r7}; \
|
||||||
|
cfi_adjust_cfa_offset (-16); \
|
||||||
|
cfi_restore (r4); \
|
||||||
|
cfi_restore (r5); \
|
||||||
|
cfi_restore (r6); \
|
||||||
|
cfi_restore (r7); \
|
||||||
|
.fnend
|
||||||
|
|
||||||
#endif /* _LINUX_ARM_EABI_SYSDEP_H */
|
#endif /* _LINUX_ARM_EABI_SYSDEP_H */
|
||||||
|
|
|
@ -33,7 +33,28 @@ ENTRY (__vfork)
|
||||||
#ifdef SAVE_PID
|
#ifdef SAVE_PID
|
||||||
SAVE_PID
|
SAVE_PID
|
||||||
#endif
|
#endif
|
||||||
DO_CALL (vfork, 0)
|
#ifdef __ARM_EABI__
|
||||||
|
/* The DO_CALL macro saves r7 on the stack, to enable generation
|
||||||
|
of ARM unwind info. Since the stack is initially shared between
|
||||||
|
parent and child of vfork, that saved value could be corrupted.
|
||||||
|
To avoid this problem, we save r7 into ip as well, and restore
|
||||||
|
from there. */
|
||||||
|
mov ip, r7
|
||||||
|
cfi_register (r7, ip)
|
||||||
|
.fnstart
|
||||||
|
str r7, [sp, #-4]!
|
||||||
|
cfi_adjust_cfa_offset (4)
|
||||||
|
.save { r7 }
|
||||||
|
ldr r7, =SYS_ify (vfork)
|
||||||
|
swi 0x0
|
||||||
|
.fnend
|
||||||
|
add sp, sp, #4
|
||||||
|
cfi_adjust_cfa_offset (-4)
|
||||||
|
mov r7, ip
|
||||||
|
cfi_restore (r7);
|
||||||
|
#else
|
||||||
|
swi SYS_ify(vfork)
|
||||||
|
#endif
|
||||||
#ifdef RESTORE_PID
|
#ifdef RESTORE_PID
|
||||||
RESTORE_PID
|
RESTORE_PID
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue