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] |
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] |