This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
[alpha] misc unwinding changes
- From: Richard Henderson <rth at twiddle dot net>
- To: libc-alpha at sources dot redhat dot com
- Date: Thu, 5 Jun 2003 18:17:04 -0700
- Subject: [alpha] misc unwinding changes
The sysdep-cancel.h functions are now completely accurate, which is
good since we expect to be doing asynchronous unwinding through them.
The vfork implementation needed fixing because of .ent/.end errors
that a new assembler catches.
Experimentally, the top-of-stack changes work better with gdb.
The signal trampolines get annotations, so that one day we could
perhaps get rid of special-case hackery in libgcc and gdb.
And to do all this, I require CFI assembler directives added to
gas only this morning, thus the subject of the generic/sysdep.h change.
Personally I'm fine with requiring today's assembler to build.
Does anyone have any objections to this? The result without is
demonstrably incorrect...
Ok?
r~
linuxthreads/
* sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h (PSEUDO): Use
and require CFI assembler directives.
* sysdeps/unix/sysv/linux/alpha/vfork.S: Likewise.
libc/
* sysdeps/alpha/dl-machine.h (RTLD_START): Fix top-of-stack backtrace.
* sysdeps/unix/sysv/linux/alpha/clone.S: Likewise.
* sysdeps/alpha/elf/start.S: Likewise. Remove pointless allocation.
* sysdeps/unix/sysv/linux/alpha/rt_sigaction.S: Use standard ldgp
entry sequence and explicit relocs. Add unwind info for sigreturn
and rt_sigreturn.
* sysdeps/generic/sysdep.h (cfi_register, cfi_return_column,
cfi_restore, cfi_undefined, cfi_remember_state, cfi_restore_state): New.
(CFI_REGISTER, CFI_RETURN_COLUMN, CFI_RESTORE, CFI_UNDEFINED,
CFI_REMEMBER_STATE, CFI_RESTORE_STATE): New.
Index: linuxthreads/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h
===================================================================
RCS file: /cvs/glibc/libc/linuxthreads/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h,v
retrieving revision 1.3
diff -c -p -d -r1.3 sysdep-cancel.h
*** linuxthreads/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h 12 Jan 2003 19:26:41 -0000 1.3
--- linuxthreads/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h 6 Jun 2003 00:59:39 -0000
***************
*** 40,49 ****
# define PSEUDO(name, syscall_name, args) \
.globl name; \
.align 4; \
! .ent name, 0; \
__LABEL(name) \
ldgp gp, 0(pv); \
- .prologue 1; \
PSEUDO_PROF; \
PSEUDO_PREPARE_ARGS \
SINGLE_THREAD_P(t0); \
--- 40,50 ----
# define PSEUDO(name, syscall_name, args) \
.globl name; \
.align 4; \
! .type name, @function; \
! .usepv name, std; \
! cfi_startproc; \
__LABEL(name) \
ldgp gp, 0(pv); \
PSEUDO_PROF; \
PSEUDO_PREPARE_ARGS \
SINGLE_THREAD_P(t0); \
*************** __LABEL($pseudo_ret) \
*** 55,61 ****
--- 56,64 ----
.subsection 2; \
__LABEL($pseudo_cancel) \
subq sp, 64, sp; \
+ cfi_def_cfa_offset(64); \
stq ra, 0(sp); \
+ cfi_offset(ra, -64); \
SAVE_ARGS_##args; \
CENABLE; \
LOAD_ARGS_##args; \
*************** __LABEL($pseudo_cancel) \
*** 67,85 ****
ldq ra, 0(sp); \
ldq v0, 8(sp); \
addq sp, 64, sp; \
ret; \
__LABEL($multi_error) \
CDISABLE; \
ldq ra, 0(sp); \
ldq v0, 8(sp); \
addq sp, 64, sp; \
__LABEL($syscall_error) \
SYSCALL_ERROR_HANDLER; \
- END(name); \
.previous
# undef PSEUDO_END
! # define PSEUDO_END(sym)
# define SAVE_ARGS_0 /* Nothing. */
# define SAVE_ARGS_1 SAVE_ARGS_0; stq a0, 8(sp)
--- 70,96 ----
ldq ra, 0(sp); \
ldq v0, 8(sp); \
addq sp, 64, sp; \
+ cfi_remember_state; \
+ cfi_restore(ra); \
+ cfi_def_cfa_offset(0); \
ret; \
+ cfi_restore_state; \
__LABEL($multi_error) \
CDISABLE; \
ldq ra, 0(sp); \
ldq v0, 8(sp); \
addq sp, 64, sp; \
+ cfi_restore(ra); \
+ cfi_def_cfa_offset(0); \
__LABEL($syscall_error) \
SYSCALL_ERROR_HANDLER; \
.previous
# undef PSEUDO_END
! # define PSEUDO_END(sym) \
! .subsection 2; \
! cfi_endproc; \
! .size sym, .-sym
# define SAVE_ARGS_0 /* Nothing. */
# define SAVE_ARGS_1 SAVE_ARGS_0; stq a0, 8(sp)
Index: linuxthreads/sysdeps/unix/sysv/linux/alpha/vfork.S
===================================================================
RCS file: /cvs/glibc/libc/linuxthreads/sysdeps/unix/sysv/linux/alpha/vfork.S,v
retrieving revision 1.5
diff -c -p -d -r1.5 vfork.S
*** linuxthreads/sysdeps/unix/sysv/linux/alpha/vfork.S 11 Feb 2003 06:27:53 -0000 1.5
--- linuxthreads/sysdeps/unix/sysv/linux/alpha/vfork.S 6 Jun 2003 00:59:39 -0000
***************
*** 19,30 ****
#include <sysdep-cancel.h>
- .globl __vfork
.align 4
! .ent __vfork,0
! __LABEL(__vfork)
ldgp gp, 0(pv)
- .prologue 1
PSEUDO_PROF
#ifdef SHARED
--- 19,31 ----
#include <sysdep-cancel.h>
.align 4
! .globl __vfork
! .type __vfork, @function
! .usepv __vfork, std
! cfi_startproc
! __vfork:
ldgp gp, 0(pv)
PSEUDO_PROF
#ifdef SHARED
*************** __LABEL(__vfork)
*** 46,63 ****
fork and vfork object files. */
$do_fork:
subq sp, 16, sp
stq ra, 0(sp)
jsr ra, HIDDEN_JUMPTARGET (__fork)
ldgp gp, 0(ra)
ldq ra, 0(sp)
addq sp, 16, sp
ret
$syscall_error:
SYSCALL_ERROR_HANDLER
#endif
! PSEUDO_END(__vfork)
libc_hidden_def (__vfork)
weak_alias (__vfork, vfork)
--- 47,70 ----
fork and vfork object files. */
$do_fork:
subq sp, 16, sp
+ cfi_adjust_cfa_offset(16)
stq ra, 0(sp)
+ cfi_offset(ra, -16)
jsr ra, HIDDEN_JUMPTARGET (__fork)
ldgp gp, 0(ra)
ldq ra, 0(sp)
addq sp, 16, sp
+ cfi_restore(ra)
+ cfi_adjust_cfa_offset(-16)
ret
$syscall_error:
SYSCALL_ERROR_HANDLER
#endif
! cfi_endproc
! .size __vfork, .-__vfork
!
libc_hidden_def (__vfork)
weak_alias (__vfork, vfork)
Index: sysdeps/alpha/dl-machine.h
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/alpha/dl-machine.h,v
retrieving revision 1.69
diff -c -p -d -r1.69 dl-machine.h
*** sysdeps/alpha/dl-machine.h 14 Feb 2003 06:02:01 -0000 1.69
--- sysdeps/alpha/dl-machine.h 6 Jun 2003 00:59:39 -0000
*************** elf_machine_runtime_setup (struct link_m
*** 303,308 ****
--- 303,309 ----
.globl _start \n\
.ent _start \n\
_start: \n\
+ .frame $31,0,$31,0 \n\
br $gp, 0f \n\
0: ldgp $gp, 0($gp) \n\
.prologue 0 \n\
*************** _start: \n\
*** 314,320 ****
.globl _dl_start_user \n\
.ent _dl_start_user \n\
_dl_start_user: \n\
! .frame $30,0,$31,0 \n\
.prologue 0 \n\
/* Save the user entry point address in s0. */ \n\
mov $0, $9 \n\
--- 315,321 ----
.globl _dl_start_user \n\
.ent _dl_start_user \n\
_dl_start_user: \n\
! .frame $31,0,$31,0 \n\
.prologue 0 \n\
/* Save the user entry point address in s0. */ \n\
mov $0, $9 \n\
Index: sysdeps/alpha/elf/start.S
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/alpha/elf/start.S,v
retrieving revision 1.12
diff -c -p -d -r1.12 start.S
*** sysdeps/alpha/elf/start.S 9 Dec 2002 20:37:24 -0000 1.12
--- sysdeps/alpha/elf/start.S 6 Jun 2003 00:59:39 -0000
***************
*** 1,5 ****
/* Startup code for Alpha/ELF.
! Copyright (C) 1993,1995,1996,1997,1998,2000,2001, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Richard Henderson <rth@tamu.edu>
--- 1,6 ----
/* Startup code for Alpha/ELF.
! Copyright (C) 1993, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003
! Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Richard Henderson <rth@tamu.edu>
***************
*** 26,33 ****
.ent _start, 0
.type _start,@function
_start:
! .frame fp, 0, zero
! mov zero, fp
br gp, 1f
1: ldgp gp, 0(gp)
subq sp, 16, sp
--- 27,33 ----
.ent _start, 0
.type _start,@function
_start:
! .frame $31, 0, $31
br gp, 1f
1: ldgp gp, 0(gp)
subq sp, 16, sp
*************** weak_alias(_start, __start)
*** 65,70 ****
.data
.globl __data_start
__data_start:
- .long 0
.weak data_start
data_start = __data_start
--- 65,69 ----
Index: sysdeps/generic/sysdep.h
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/generic/sysdep.h,v
retrieving revision 1.10
diff -c -p -d -r1.10 sysdep.h
*** sysdeps/generic/sysdep.h 30 May 2003 16:11:27 -0000 1.10
--- sysdeps/generic/sysdep.h 6 Jun 2003 00:59:39 -0000
***************
*** 49,61 ****
/* Makros to generate eh_frame unwind information. */
# ifdef HAVE_ASM_CFI_DIRECTIVES
! # define cfi_startproc .cfi_startproc
! # define cfi_endproc .cfi_endproc
! # define cfi_def_cfa(reg, off) .cfi_def_cfa reg, off
# define cfi_def_cfa_register(reg) .cfi_def_cfa_register reg
# define cfi_def_cfa_offset(off) .cfi_def_cfa_offset off
# define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off
! # define cfi_offset(reg, off) .cfi_offset reg, off
# else
# define cfi_startproc
# define cfi_endproc
--- 49,67 ----
/* Makros to generate eh_frame unwind information. */
# ifdef HAVE_ASM_CFI_DIRECTIVES
! # define cfi_startproc .cfi_startproc
! # define cfi_endproc .cfi_endproc
! # define cfi_def_cfa(reg, off) .cfi_def_cfa reg, off
# define cfi_def_cfa_register(reg) .cfi_def_cfa_register reg
# define cfi_def_cfa_offset(off) .cfi_def_cfa_offset off
# define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off
! # define cfi_offset(reg, off) .cfi_offset reg, off
! # define cfi_register(r1, r2) .cfi_register r1, r2
! # define cfi_return_column(reg) .cfi_return_column reg
! # define cfi_restore(reg) .cfi_restore reg
! # define cfi_undefined(reg) .cfi_undefined reg
! # define cfi_remember_state .cfi_remember_state
! # define cfi_restore_state .cfi_restore_state
# else
# define cfi_startproc
# define cfi_endproc
***************
*** 64,69 ****
--- 70,81 ----
# define cfi_def_cfa_offset(off)
# define cfi_adjust_cfa_offset(off)
# define cfi_offset(reg, off)
+ # define cfi_register(r1, r2)
+ # define cfi_return_column(reg)
+ # define cfi_restore(reg)
+ # define cfi_undefined(reg)
+ # define cfi_remember_state
+ # define cfi_restore_state
# endif
#else /* ! ASSEMBLER */
***************
*** 82,87 ****
--- 94,111 ----
".cfi_adjust_cfa_offset " CFI_STRINGIFY(off)
# define CFI_OFFSET(reg, off) \
".cfi_offset " CFI_STRINGIFY(reg) "," CFI_STRINGIFY(off)
+ # define CFI_REGISTER(r1, r2) \
+ ".cfi_register " CFI_STRINGIFY(r1) "," CFI_STRINGIFY(r2)
+ # define CFI_RETURN_COLUMN(reg) \
+ ".cfi_return_column " CFI_STRINGIFY(reg)
+ # define CFI_RESTORE(reg) \
+ ".cfi_restore " CFI_STRINGIFY(reg)
+ # define CFI_UNDEFINED(reg) \
+ ".cfi_undefined " CFI_STRINGIFY(reg)
+ # define CFI_REMEMBER_STATE \
+ ".cfi_remember_state"
+ # define CFI_RESTORE_STATE \
+ ".cfi_restore_state"
# else
# define CFI_STARTPROC
# define CFI_ENDPROC
***************
*** 90,95 ****
--- 114,125 ----
# define CFI_DEF_CFA_OFFSET(off)
# define CFI_ADJUST_CFA_OFFSET(off)
# define CFI_OFFSET(reg, off)
+ # define CFI_REGISTER(r1, r2)
+ # define CFI_RETURN_COLUMN(reg)
+ # define CFI_RESTORE(reg)
+ # define CFI_UNDEFINED(reg)
+ # define CFI_REMEMBER_STATE
+ # define CFI_RESTORE_STATE
# endif
#endif /* __ASSEMBLER__ */
Index: sysdeps/unix/sysv/linux/alpha/clone.S
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/alpha/clone.S,v
retrieving revision 1.12
diff -c -p -d -r1.12 clone.S
*** sysdeps/unix/sysv/linux/alpha/clone.S 8 Nov 2002 02:18:45 -0000 1.12
--- sysdeps/unix/sysv/linux/alpha/clone.S 6 Jun 2003 00:59:39 -0000
*************** $error:
*** 83,90 ****
.ent thread_start
thread_start:
! .frame fp,0,zero,0
! mov zero,fp
.prologue 0
/* Load up the arguments. */
--- 83,89 ----
.ent thread_start
thread_start:
! .frame zero,0,zero,0
.prologue 0
/* Load up the arguments. */
Index: sysdeps/unix/sysv/linux/alpha/rt_sigaction.S
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/alpha/rt_sigaction.S,v
retrieving revision 1.6
diff -c -p -d -r1.6 rt_sigaction.S
*** sysdeps/unix/sysv/linux/alpha/rt_sigaction.S 8 Nov 2002 02:18:47 -0000 1.6
--- sysdeps/unix/sysv/linux/alpha/rt_sigaction.S 6 Jun 2003 00:59:39 -0000
***************
*** 1,4 ****
! /* Copyright (C) 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Richard Henderson <rth@cygnus.com>, 1998
--- 1,4 ----
! /* Copyright (C) 1998, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Richard Henderson <rth@cygnus.com>, 1998
***************
*** 28,82 ****
#ifdef __NR_rt_sigaction
.text
ENTRY(__syscall_rt_sigaction)
.frame sp,0,ra,0
- #ifdef PROF
ldgp gp,0(pv)
.set noat
lda AT, _mcount
jsr AT, (AT), _mcount
.set at
#endif
! /* Indicate non-standard use of our PV. */
! .prologue 2
beq a1, 0f
! ldl t0, 8(a1) # sa_flags
! lda a4, sigreturn-__syscall_rt_sigaction(pv)
! lda t1, rt_sigreturn-__syscall_rt_sigaction(pv)
! and t0, 0x00000040, t0 # SA_SIGINFO
cmovne t0, t1, a4
! 0: ldi v0,__NR_rt_sigaction
callsys
! bne a3,1f
ret
! 1:
! #ifndef PROF
! br gp,2f
! 2: ldgp gp,0(gp)
! #endif
! SYSCALL_ERROR_HANDLER
! END(__syscall_rt_sigaction)
! .align 5
! .ent sigreturn
sigreturn:
! .prologue 0
! mov sp,a0
! ldi v0,__NR_sigreturn
callsys
! .end sigreturn
! .align 4
! .ent rt_sigreturn
rt_sigreturn:
- .prologue 0
mov sp,a0
ldi v0,__NR_rt_sigreturn
callsys
! .end rt_sigreturn
#else
ENTRY(__syscall_rt_sigaction)
ldgp $29,0($27)
--- 28,119 ----
#ifdef __NR_rt_sigaction
.text
+
ENTRY(__syscall_rt_sigaction)
.frame sp,0,ra,0
ldgp gp,0(pv)
+ #ifdef PROF
.set noat
lda AT, _mcount
jsr AT, (AT), _mcount
.set at
#endif
! .prologue 1
beq a1, 0f
! ldl t0, 8(a1) # sa_flags
! ldah a4, sigreturn(gp) !gprelhigh
! ldah t1, rt_sigreturn(gp) !gprelhigh
! lda a4, sigreturn(a4) !gprellow
! lda t1, rt_sigreturn(a4) !gprellow
! and t0, 0x00000040, t0 # SA_SIGINFO
cmovne t0, t1, a4
! 0: ldi v0, __NR_rt_sigaction
callsys
! bne a3, SYSCALL_ERROR_LABEL
ret
! PSEUDO_END(__syscall_rt_sigaction)
! /* To enable unwinding through the signal frame without special hackery
! elsewhere, describe the entire struct sigcontext with unwind info.
! Note that we begin the unwind info one instruction before the start
! of the function; the unwinder will subtract one from the return address
! attempting to find the call instruction that led us here, since we
! didn't get here via a normal call. */
! .macro SIGCONTEXT_REGS_I base, from=0
! cfi_offset (\from, \base + (4 + \from) * 8)
! .if 30-\from
! SIGCONTEXT_REGS_I \base, "(\from+1)"
! .endif
! .endm
!
! .macro SIGCONTEXT_REGS_F base, from=32
! cfi_offset (\from, \base + (4 + 1 + \from) * 8)
! .if 62-\from
! SIGCONTEXT_REGS_F \base, "(\from+1)"
! .endif
! .endm
!
! .macro SIGCONTEXT_REGS base
! SIGCONTEXT_REGS_I \base
! SIGCONTEXT_REGS_F \base
! cfi_offset (63, \base + (4 + 32 + 1 + 32) * 8)
! cfi_offset (64, \base + 2 * 8)
! .endm
!
! .align 4
! nop
! nop
! nop
!
! cfi_startproc
! cfi_return_column (64)
! SIGCONTEXT_REGS -648
! cfi_def_cfa_offset (648)
! nop
sigreturn:
! mov sp, a0
! ldi v0, __NR_sigreturn
callsys
! cfi_endproc
! .size sigreturn, .-sigreturn
! .type sigreturn, @function
! cfi_startproc
! cfi_return_column (64)
! SIGCONTEXT_REGS -648
! cfi_def_cfa_offset (176 + 648)
! nop
rt_sigreturn:
mov sp,a0
ldi v0,__NR_rt_sigreturn
callsys
! cfi_endproc
! .size rt_sigreturn, .-rt_sigreturn
! .type rt_sigreturn, @function
!
#else
ENTRY(__syscall_rt_sigaction)
ldgp $29,0($27)