This is the mail archive of the libc-ports@sources.redhat.com mailing list for the libc-ports project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Adding CFI statements to ARM's assembly code: syscall stub infrastructure


Hello!

This patch adds CFI statements to the main syscall stub infrastructure.


2009-12-21  Thomas Schwinge  <thomas@codesourcery.com>

	* 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.

diff --git a/glibc-ports-mainline/sysdeps/arm/sysdep.h b/glibc-ports-mainline/sysdeps/arm/sysdep.h
index 442d3a1..929a452 100644
--- a/glibc-ports-mainline/sysdeps/arm/sysdep.h
+++ b/glibc-ports-mainline/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 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,10 +81,13 @@
   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.  */
diff --git a/glibc-ports-mainline/sysdeps/unix/arm/sysdep.S b/glibc-ports-mainline/sysdeps/unix/arm/sysdep.S
index dcb427e..d3ad81b 100644
--- a/glibc-ports-mainline/sysdeps/unix/arm/sysdep.S
+++ b/glibc-ports-mainline/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/glibc-ports-mainline/sysdeps/unix/sysv/linux/arm/eabi/nptl/sysdep-cancel.h b/glibc-ports-mainline/sysdeps/unix/sysv/linux/arm/eabi/nptl/sysdep-cancel.h
index 73912d5..458558b 100644
--- a/glibc-ports-mainline/sysdeps/unix/sysv/linux/arm/eabi/nptl/sysdep-cancel.h
+++ b/glibc-ports-mainline/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/glibc-ports-mainline/sysdeps/unix/sysv/linux/arm/eabi/sysdep.h b/glibc-ports-mainline/sysdeps/unix/sysv/linux/arm/eabi/sysdep.h
index a7dd40d..0490500 100644
--- a/glibc-ports-mainline/sysdeps/unix/sysv/linux/arm/eabi/sysdep.h
+++ b/glibc-ports-mainline/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.
@@ -100,11 +100,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/glibc-ports-mainline/sysdeps/unix/sysv/linux/arm/sysdep.h b/glibc-ports-mainline/sysdeps/unix/sysv/linux/arm/sysdep.h
index 3911aee..bd5b2ce 100644
--- a/glibc-ports-mainline/sysdeps/unix/sysv/linux/arm/sysdep.h
+++ b/glibc-ports-mainline/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__ */
 
diff --git a/glibc-ports-mainline/sysdeps/unix/sysv/linux/arm/eabi/sigrestorer.S b/glibc-ports-mainline/sysdeps/unix/sysv/linux/arm/eabi/sigrestorer.S
index cc06a55..f0f2015 100644
--- a/glibc-ports-mainline/sysdeps/unix/sysv/linux/arm/eabi/sigrestorer.S
+++ b/glibc-ports-mainline/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 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
@@ -43,6 +43,7 @@ ENTRY(__default_sa_restorer_v1)
 	mov	r7, $SYS_ify(sigreturn)
 	swi	0x0
 	.fnend
+END(__default_sa_restorer_v1)
 #endif
 
 	.fnstart
@@ -53,6 +54,7 @@ ENTRY(__default_sa_restorer_v2)
 	mov	r7, $SYS_ify(sigreturn)
 	swi	0x0
 	.fnend
+END(__default_sa_restorer_v2)
 
 #ifdef __NR_rt_sigreturn
 
@@ -65,6 +67,7 @@ ENTRY(__default_rt_sa_restorer_v1)
 	mov	r7, $SYS_ify(rt_sigreturn)
 	swi	0x0
 	.fnend
+END(__default_rt_sa_restorer_v1)
 #endif
 
 	.fnstart
@@ -75,5 +78,6 @@ ENTRY(__default_rt_sa_restorer_v2)
 	mov	r7, $SYS_ify(rt_sigreturn)
 	swi	0x0
 	.fnend
+END(__default_rt_sa_restorer_v2)
 
 #endif


Not updated:
sysdeps/unix/sysv/linux/arm/eabi/linuxthreads/sysdep-cancel.h,
sysdeps/unix/sysv/linux/arm/linuxthreads/sysdep-cancel.h,
sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h,
sysdeps/unix/sysv/linux/arm/sigrestorer.S


Regards,
 Thomas

Attachment: pgp00000.pgp
Description: PGP signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]