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] | |
[Oops, there was a stupid 2-character typo in the patch for pipe.S
which my testing didn't catch initially. Corrected in the patch
below.]
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,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] |