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

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


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

patch to fix unwind info for ia64


I ran Harish Patil's unwcheck script on libc.so and found several
routines which had bad unwind info (number of instructions covered by
unwind info didn't match actual length of function).  The problems
were due to a known bug in GAS which causes bad unwind info when
.align is used between a .proc/.endp-pair.  Unfortunately, this is not
an easy bug to fix, so, for now, we may just have to work around the
problem in the few assembly files that have this issue.  The patch
below does that.  The change to pipe.S may seem unrelated but besides
resulting in better code, the change also fixes a similar kind of bad
unwind-info problem for pipe.S that would show up once the new
syscall-stub patch is applied.

	--david

ChangeLog

2003-11-14 David Mosberger   <davidm@hpl.hp.com>

	* sysdeps/ia64/memccpy.S: Work around GAS_ALIGN_BREAKS_UNWIND_INFO bug.
	* sysdeps/ia64/memcpy.S: Ditto.
	* sysdeps/ia64/memset.S: Ditto.
	* sysdeps/ia64/memmove.S: Ditto.  Also move the jump-table to
	out of .tex into .rodata, where it belongs

	* sysdeps/unix/sysv/linux/ia64/sysdep.h
	(GAS_ALIGN_BREAKS_UNWIND_INFO): Define this macro to indicate
	that all existing GAS versions have a problem with .align inside
	a function.

	* sysdeps/unix/sysv/linux/ia64/pipe.S: There is no need to
	save/restore input-arguments, because they're necessarily
	preserved by the kernel to support syscall-restart.

Index: sysdeps/ia64/memccpy.S
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/ia64/memccpy.S,v
retrieving revision 1.6
diff -u -r1.6 memccpy.S
--- sysdeps/ia64/memccpy.S	9 Sep 2003 20:15:59 -0000	1.6
+++ sysdeps/ia64/memccpy.S	14 Nov 2003 20:05:30 -0000
@@ -52,6 +52,15 @@
 #define loopcnt		r30
 #define	value		r31
 
+#ifdef GAS_ALIGN_BREAKS_UNWIND_INFO
+/* Manually force proper loop-alignment.  Note: be sure to
+   double-check the code-layout after making any changes to
+   this routine! */
+# define ALIGN(n)	{ nop 0 }
+#else
+# define ALIGN(n)	.align 32
+#endif
+
 ENTRY(memccpy)
 	.prologue
 	alloc 	r2 = ar.pfs, 4, 40 - 4, 0, 40
@@ -110,7 +119,7 @@
 	mov	ar.ec = MEMLAT + 6 + 1 	// six more passes needed
 	ld8	r[1] = [asrc], 8 	// r[1] = w0
 	cmp.ne	p6, p0 = r0, r0	;;	// clear p6
-	.align	32
+	ALIGN(32)
 .l2:
 (p[0])		ld8.s	r[0] = [asrc], 8		// r[0] = w1
 (p[MEMLAT])	shr.u	tmp1[0] = r[1 + MEMLAT], sh1	// tmp1 = w0 >> sh1
Index: sysdeps/ia64/memcpy.S
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/ia64/memcpy.S,v
retrieving revision 1.10
diff -u -r1.10 memcpy.S
--- sysdeps/ia64/memcpy.S	29 Apr 2003 22:47:19 -0000	1.10
+++ sysdeps/ia64/memcpy.S	14 Nov 2003 20:05:30 -0000
@@ -103,14 +103,22 @@
 #define the_z		z
 #endif
 
+#ifdef GAS_ALIGN_BREAKS_UNWIND_INFO
+/* Manually force proper loop-alignment.  Note: be sure to
+   double-check the code-layout after making any changes to
+   this routine! */
+# define ALIGN(n)	{ nop 0 }
+#else
+# define ALIGN(n)	.align 32
+#endif
 
 #if defined(USE_LFETCH)
 #define LOOP(shift)						\
-		.align	32 ;					\
+		ALIGN(32);					\
 .loop##shift##:							\
 { .mmb								\
 (p[0])	ld8.nt1	r[0] = [asrc], 8 ;				\
-(p[0])	lfetch.nt1 [ptr1], 16 ;				\
+(p[0])	lfetch.nt1 [ptr1], 16 ;					\
 	nop.b 0 ;						\
 } { .mib							\
 (p[MEMLAT+1]) st8 [dest] = tmp3, 8 ;				\
@@ -118,7 +126,7 @@
  	nop.b 0 ;;						\
  } { .mmb							\
 (p[0])	ld8.nt1	s[0] = [asrc], 8 ;				\
-(p[0])	lfetch.nt1	[ptr2], 16 ;			\
+(p[0])	lfetch.nt1	[ptr2], 16 ;				\
 	nop.b 0 ;						\
 } { .mib							\
 (p[MEMLAT+1]) st8 [dest] = tmp4, 8 ;				\
@@ -130,7 +138,7 @@
 }
 #else
 #define LOOP(shift)						\
-		.align	32 ;					\
+		ALIGN(32);					\
 .loop##shift##:							\
 { .mmb								\
 (p[0])	ld8.nt1	r[0] = [asrc], 8 ;				\
@@ -254,7 +262,11 @@
 	movi0	ar.lc = loopcnt 	// set the loop counter
 ;; }
 
+#ifdef  GAS_ALIGN_BREAKS_UNWIND_INFO
+	{ nop 0 }
+#else
 	.align	32
+#endif
 #if defined(USE_FLP)
 .l1: // ------------------------------- // L1: Everything a multiple of 8
 { .mmi
Index: sysdeps/ia64/memmove.S
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/ia64/memmove.S,v
retrieving revision 1.6
diff -u -r1.6 memmove.S
--- sysdeps/ia64/memmove.S	29 Apr 2003 22:47:19 -0000	1.6
+++ sysdeps/ia64/memmove.S	14 Nov 2003 20:05:30 -0000
@@ -56,12 +56,18 @@
 #define loopcnt		r30
 #define	value		r31
 
+#ifdef GAS_ALIGN_BREAKS_UNWIND_INFO
+# define ALIGN(n)	{ nop 0 }
+#else
+# define ALIGN(n)	.align 32
+#endif
+
 #define LOOP(shift)							\
-		.align	32 ;						\
+		ALIGN(32);						\
 .loop##shift##:								\
 (p[0])		ld8	r[0] = [asrc], 8 ;	/* w1 */		\
 (p[MEMLAT+1])	st8	[dest] = value, 8 ;				\
-(p[MEMLAT])	shrp	value = r[MEMLAT], r[MEMLAT+1], shift ;	\
+(p[MEMLAT])	shrp	value = r[MEMLAT], r[MEMLAT+1], shift ;		\
 		nop.b	0 ;						\
 		nop.b	0 ;						\
 		br.ctop.sptk .loop##shift ;				\
@@ -228,6 +234,10 @@
 (p[MEMLAT])	st1	[dest] = r[MEMLAT], -1
 		br.ctop.dptk .l6
 		br.cond.sptk .restore_and_exit
+END(memmove)
+
+	.rodata
+	.align 8
 .table:
 	data8	0			// dummy entry
 	data8 	.loop56 - .loop8
@@ -238,5 +248,4 @@
 	data8	.loop56 - .loop48
 	data8	.loop56 - .loop56
 
-END(memmove)
 libc_hidden_builtin_def (memmove)
Index: sysdeps/ia64/memset.S
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/ia64/memset.S,v
retrieving revision 1.6
diff -u -r1.6 memset.S
--- sysdeps/ia64/memset.S	29 Apr 2003 22:47:19 -0000	1.6
+++ sysdeps/ia64/memset.S	14 Nov 2003 20:05:30 -0000
@@ -153,7 +153,9 @@
 (p_zr)	br.cond.dptk.many .l1b			// Jump to use stf.spill
 ;; }
 
+#ifndef GAS_ALIGN_BREAKS_UNWIND_INFO
 	.align 32 // -------- //  L1A: store ahead into cache lines; fill later
+#endif
 { .mmi
 	and	tmp = -(LINE_SIZE), cnt		// compute end of range
 	mov	ptr9 = ptr1			// used for prefetching
@@ -222,7 +224,11 @@
 	br.cond.dpnt.many  .move_bytes_from_alignment	// Branch no. 3
 ;; }
 
+#ifdef GAS_ALIGN_BREAKS_UNWIND_INFO
+	{ nop 0 }
+#else
 	.align 32
+#endif
 .l1b:	// ------------------ //  L1B: store ahead into cache lines; fill later
 { .mmi
 	and	tmp = -(LINE_SIZE), cnt		// compute end of range
@@ -283,13 +289,15 @@
 { .mib
 	cmp.eq	p_scr, p0 = loopcnt, r0
 	add	loopcnt = -1, loopcnt
-(p_scr)	br.cond.dpnt.many .store_words
+(p_scr)	br.cond.dpnt.many store_words
 ;; }
 { .mib
 	and	cnt = 0x1f, cnt		// compute the remaining cnt
 	movi0   ar.lc = loopcnt
 ;; }
+#ifndef GAS_ALIGN_BREAKS_UNWIND_INFO
 	.align 32
+#endif
 .l2:	// ---------------------------- //  L2A:  store 32B in 2 cycles
 { .mmb
 	store	[ptr1] = myval, 8
@@ -299,7 +307,7 @@
 	store	[ptr2] = myval, 24
 	br.cloop.dptk.many .l2
 ;; }
-.store_words:
+store_words:
 { .mib
 	cmp.gt	p_scr, p0 = 8, cnt		// just a few bytes left ?
 (p_scr)	br.cond.dpnt.many .move_bytes_from_alignment	// Branch
Index: sysdeps/unix/sysv/linux/ia64/pipe.S
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/ia64/pipe.S,v
retrieving revision 1.4
diff -u -r1.4 pipe.S
--- sysdeps/unix/sysv/linux/ia64/pipe.S	3 Aug 2002 06:57:51 -0000	1.4
+++ sysdeps/unix/sysv/linux/ia64/pipe.S	14 Nov 2003 20:05:31 -0000
@@ -22,15 +22,14 @@
 #include <sysdep.h>
 
 ENTRY(__pipe)
-       st8 [sp]=r32		// save ptr across system call
+       .regstk 1,0,0
        DO_CALL (SYS_ify (pipe))
-       ld8 r2=[sp]
        cmp.ne p6,p0=-1,r10
        ;;
-(p6)   st4 [r2]=r8,4
+(p6)   st4 [in0]=r8,4
 (p6)   mov ret0=0
        ;;
-(p6)   st4 [r2]=r9
+(p6)   st4 [in0]=r9
 (p6)   ret
        br.cond.spnt.few __syscall_error
 PSEUDO_END(__pipe)
Index: sysdeps/unix/sysv/linux/ia64/sysdep.h
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/ia64/sysdep.h,v
retrieving revision 1.17
diff -u -r1.17 sysdep.h
--- sysdeps/unix/sysv/linux/ia64/sysdep.h	16 Aug 2003 08:00:24 -0000	1.17
+++ sysdeps/unix/sysv/linux/ia64/sysdep.h	14 Nov 2003 20:05:31 -0000
@@ -24,6 +24,13 @@
 #include <sysdeps/unix/sysdep.h>
 #include <sysdeps/ia64/sysdep.h>
 
+/* As of GAS v2.4.90.0.7, including a ".align" directive inside a
+   function will cause bad unwind info to be emitted (GAS doesn't know
+   how to account for the padding introduced by the .align directive).
+   Turning on this macro will work around this bug by introducing the
+   necessary padding explicitly. */
+#define GAS_ALIGN_BREAKS_UNWIND_INFO
+
 /* For Linux we can use the system call table in the header file
 	/usr/include/asm/unistd.h
    of the kernel.  But these symbols do not follow the SYS_* syntax


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