Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
c0897856
Commit
c0897856
authored
Jun 24, 2006
by
Russell King
Committed by
Russell King
Jun 24, 2006
Browse files
Options
Browse Files
Download
Plain Diff
Merge signal handler branch
parents
e11c910b
85fe0681
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
160 additions
and
126 deletions
+160
-126
arch/arm/kernel/signal.c
arch/arm/kernel/signal.c
+82
-125
include/asm-arm/ucontext.h
include/asm-arm/ucontext.h
+78
-1
No files found.
arch/arm/kernel/signal.c
View file @
c0897856
...
@@ -134,17 +134,6 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
...
@@ -134,17 +134,6 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
#ifdef CONFIG_IWMMXT
#ifdef CONFIG_IWMMXT
/* iwmmxt_area is 0x98 bytes long, preceeded by 8 bytes of signature */
#define IWMMXT_STORAGE_SIZE (0x98 + 8)
#define IWMMXT_MAGIC0 0x12ef842a
#define IWMMXT_MAGIC1 0x1c07ca71
struct
iwmmxt_sigframe
{
unsigned
long
magic0
;
unsigned
long
magic1
;
unsigned
long
storage
[
0x98
/
4
];
};
static
int
preserve_iwmmxt_context
(
struct
iwmmxt_sigframe
*
frame
)
static
int
preserve_iwmmxt_context
(
struct
iwmmxt_sigframe
*
frame
)
{
{
char
kbuf
[
sizeof
(
*
frame
)
+
8
];
char
kbuf
[
sizeof
(
*
frame
)
+
8
];
...
@@ -152,8 +141,8 @@ static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame)
...
@@ -152,8 +141,8 @@ static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame)
/* the iWMMXt context must be 64 bit aligned */
/* the iWMMXt context must be 64 bit aligned */
kframe
=
(
struct
iwmmxt_sigframe
*
)((
unsigned
long
)(
kbuf
+
8
)
&
~
7
);
kframe
=
(
struct
iwmmxt_sigframe
*
)((
unsigned
long
)(
kbuf
+
8
)
&
~
7
);
kframe
->
magic
0
=
IWMMXT_MAGIC0
;
kframe
->
magic
=
IWMMXT_MAGIC
;
kframe
->
magic1
=
IWMMXT_MAGIC1
;
kframe
->
size
=
IWMMXT_STORAGE_SIZE
;
iwmmxt_task_copy
(
current_thread_info
(),
&
kframe
->
storage
);
iwmmxt_task_copy
(
current_thread_info
(),
&
kframe
->
storage
);
return
__copy_to_user
(
frame
,
kframe
,
sizeof
(
*
frame
));
return
__copy_to_user
(
frame
,
kframe
,
sizeof
(
*
frame
));
}
}
...
@@ -167,8 +156,8 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
...
@@ -167,8 +156,8 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
kframe
=
(
struct
iwmmxt_sigframe
*
)((
unsigned
long
)(
kbuf
+
8
)
&
~
7
);
kframe
=
(
struct
iwmmxt_sigframe
*
)((
unsigned
long
)(
kbuf
+
8
)
&
~
7
);
if
(
__copy_from_user
(
kframe
,
frame
,
sizeof
(
*
frame
)))
if
(
__copy_from_user
(
kframe
,
frame
,
sizeof
(
*
frame
)))
return
-
1
;
return
-
1
;
if
(
kframe
->
magic
0
!=
IWMMXT_MAGIC0
||
if
(
kframe
->
magic
!=
IWMMXT_MAGIC
||
kframe
->
magic1
!=
IWMMXT_MAGIC1
)
kframe
->
size
!=
IWMMXT_STORAGE_SIZE
)
return
-
1
;
return
-
1
;
iwmmxt_task_restore
(
current_thread_info
(),
&
kframe
->
storage
);
iwmmxt_task_restore
(
current_thread_info
(),
&
kframe
->
storage
);
return
0
;
return
0
;
...
@@ -176,71 +165,62 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
...
@@ -176,71 +165,62 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
#endif
#endif
/*
* Auxiliary signal frame. This saves stuff like FP state.
* The layout of this structure is not part of the user ABI.
*/
struct
aux_sigframe
{
#ifdef CONFIG_IWMMXT
struct
iwmmxt_sigframe
iwmmxt
;
#endif
#ifdef CONFIG_VFP
union
vfp_state
vfp
;
#endif
};
/*
/*
* Do a signal return; undo the signal stack. These are aligned to 64-bit.
* Do a signal return; undo the signal stack. These are aligned to 64-bit.
*/
*/
struct
sigframe
{
struct
sigframe
{
struct
sigcontext
sc
;
struct
ucontext
uc
;
unsigned
long
extramask
[
_NSIG_WORDS
-
1
];
unsigned
long
retcode
[
2
];
unsigned
long
retcode
[
2
];
struct
aux_sigframe
aux
__attribute__
((
aligned
(
8
)));
};
};
struct
rt_sigframe
{
struct
rt_sigframe
{
struct
siginfo
__user
*
pinfo
;
void
__user
*
puc
;
struct
siginfo
info
;
struct
siginfo
info
;
struct
ucontext
uc
;
struct
sigframe
sig
;
unsigned
long
retcode
[
2
];
struct
aux_sigframe
aux
__attribute__
((
aligned
(
8
)));
};
};
static
int
static
int
restore_sigframe
(
struct
pt_regs
*
regs
,
struct
sigframe
__user
*
sf
)
restore_sigcontext
(
struct
pt_regs
*
regs
,
struct
sigcontext
__user
*
sc
,
struct
aux_sigframe
__user
*
aux
)
{
{
int
err
=
0
;
struct
aux_sigframe
__user
*
aux
;
sigset_t
set
;
int
err
;
err
=
__copy_from_user
(
&
set
,
&
sf
->
uc
.
uc_sigmask
,
sizeof
(
set
));
if
(
err
==
0
)
{
sigdelsetmask
(
&
set
,
~
_BLOCKABLE
);
spin_lock_irq
(
&
current
->
sighand
->
siglock
);
current
->
blocked
=
set
;
recalc_sigpending
();
spin_unlock_irq
(
&
current
->
sighand
->
siglock
);
}
__get_user_error
(
regs
->
ARM_r0
,
&
s
c
->
arm_r0
,
err
);
__get_user_error
(
regs
->
ARM_r0
,
&
s
f
->
uc
.
uc_mcontext
.
arm_r0
,
err
);
__get_user_error
(
regs
->
ARM_r1
,
&
s
c
->
arm_r1
,
err
);
__get_user_error
(
regs
->
ARM_r1
,
&
s
f
->
uc
.
uc_mcontext
.
arm_r1
,
err
);
__get_user_error
(
regs
->
ARM_r2
,
&
s
c
->
arm_r2
,
err
);
__get_user_error
(
regs
->
ARM_r2
,
&
s
f
->
uc
.
uc_mcontext
.
arm_r2
,
err
);
__get_user_error
(
regs
->
ARM_r3
,
&
s
c
->
arm_r3
,
err
);
__get_user_error
(
regs
->
ARM_r3
,
&
s
f
->
uc
.
uc_mcontext
.
arm_r3
,
err
);
__get_user_error
(
regs
->
ARM_r4
,
&
s
c
->
arm_r4
,
err
);
__get_user_error
(
regs
->
ARM_r4
,
&
s
f
->
uc
.
uc_mcontext
.
arm_r4
,
err
);
__get_user_error
(
regs
->
ARM_r5
,
&
s
c
->
arm_r5
,
err
);
__get_user_error
(
regs
->
ARM_r5
,
&
s
f
->
uc
.
uc_mcontext
.
arm_r5
,
err
);
__get_user_error
(
regs
->
ARM_r6
,
&
s
c
->
arm_r6
,
err
);
__get_user_error
(
regs
->
ARM_r6
,
&
s
f
->
uc
.
uc_mcontext
.
arm_r6
,
err
);
__get_user_error
(
regs
->
ARM_r7
,
&
s
c
->
arm_r7
,
err
);
__get_user_error
(
regs
->
ARM_r7
,
&
s
f
->
uc
.
uc_mcontext
.
arm_r7
,
err
);
__get_user_error
(
regs
->
ARM_r8
,
&
s
c
->
arm_r8
,
err
);
__get_user_error
(
regs
->
ARM_r8
,
&
s
f
->
uc
.
uc_mcontext
.
arm_r8
,
err
);
__get_user_error
(
regs
->
ARM_r9
,
&
s
c
->
arm_r9
,
err
);
__get_user_error
(
regs
->
ARM_r9
,
&
s
f
->
uc
.
uc_mcontext
.
arm_r9
,
err
);
__get_user_error
(
regs
->
ARM_r10
,
&
s
c
->
arm_r10
,
err
);
__get_user_error
(
regs
->
ARM_r10
,
&
s
f
->
uc
.
uc_mcontext
.
arm_r10
,
err
);
__get_user_error
(
regs
->
ARM_fp
,
&
s
c
->
arm_fp
,
err
);
__get_user_error
(
regs
->
ARM_fp
,
&
s
f
->
uc
.
uc_mcontext
.
arm_fp
,
err
);
__get_user_error
(
regs
->
ARM_ip
,
&
s
c
->
arm_ip
,
err
);
__get_user_error
(
regs
->
ARM_ip
,
&
s
f
->
uc
.
uc_mcontext
.
arm_ip
,
err
);
__get_user_error
(
regs
->
ARM_sp
,
&
s
c
->
arm_sp
,
err
);
__get_user_error
(
regs
->
ARM_sp
,
&
s
f
->
uc
.
uc_mcontext
.
arm_sp
,
err
);
__get_user_error
(
regs
->
ARM_lr
,
&
s
c
->
arm_lr
,
err
);
__get_user_error
(
regs
->
ARM_lr
,
&
s
f
->
uc
.
uc_mcontext
.
arm_lr
,
err
);
__get_user_error
(
regs
->
ARM_pc
,
&
s
c
->
arm_pc
,
err
);
__get_user_error
(
regs
->
ARM_pc
,
&
s
f
->
uc
.
uc_mcontext
.
arm_pc
,
err
);
__get_user_error
(
regs
->
ARM_cpsr
,
&
s
c
->
arm_cpsr
,
err
);
__get_user_error
(
regs
->
ARM_cpsr
,
&
s
f
->
uc
.
uc_mcontext
.
arm_cpsr
,
err
);
err
|=
!
valid_user_regs
(
regs
);
err
|=
!
valid_user_regs
(
regs
);
aux
=
(
struct
aux_sigframe
__user
*
)
sf
->
uc
.
uc_regspace
;
#ifdef CONFIG_IWMMXT
#ifdef CONFIG_IWMMXT
if
(
err
==
0
&&
test_thread_flag
(
TIF_USING_IWMMXT
))
if
(
err
==
0
&&
test_thread_flag
(
TIF_USING_IWMMXT
))
err
|=
restore_iwmmxt_context
(
&
aux
->
iwmmxt
);
err
|=
restore_iwmmxt_context
(
&
aux
->
iwmmxt
);
#endif
#endif
#ifdef CONFIG_VFP
#ifdef CONFIG_VFP
// if (err == 0)
// if (err == 0)
// err |= vfp_restore_state(&
aux->
vfp);
// err |= vfp_restore_state(&
sf->aux.
vfp);
#endif
#endif
return
err
;
return
err
;
...
@@ -249,7 +229,6 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
...
@@ -249,7 +229,6 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
asmlinkage
int
sys_sigreturn
(
struct
pt_regs
*
regs
)
asmlinkage
int
sys_sigreturn
(
struct
pt_regs
*
regs
)
{
{
struct
sigframe
__user
*
frame
;
struct
sigframe
__user
*
frame
;
sigset_t
set
;
/* Always make any pending restarted system calls return -EINTR */
/* Always make any pending restarted system calls return -EINTR */
current_thread_info
()
->
restart_block
.
fn
=
do_no_restart_syscall
;
current_thread_info
()
->
restart_block
.
fn
=
do_no_restart_syscall
;
...
@@ -266,19 +245,8 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs)
...
@@ -266,19 +245,8 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs)
if
(
!
access_ok
(
VERIFY_READ
,
frame
,
sizeof
(
*
frame
)))
if
(
!
access_ok
(
VERIFY_READ
,
frame
,
sizeof
(
*
frame
)))
goto
badframe
;
goto
badframe
;
if
(
__get_user
(
set
.
sig
[
0
],
&
frame
->
sc
.
oldmask
)
||
(
_NSIG_WORDS
>
1
&&
__copy_from_user
(
&
set
.
sig
[
1
],
&
frame
->
extramask
,
sizeof
(
frame
->
extramask
))))
goto
badframe
;
sigdelsetmask
(
&
set
,
~
_BLOCKABLE
);
spin_lock_irq
(
&
current
->
sighand
->
siglock
);
current
->
blocked
=
set
;
recalc_sigpending
();
spin_unlock_irq
(
&
current
->
sighand
->
siglock
);
if
(
restore_sig
context
(
regs
,
&
frame
->
sc
,
&
frame
->
aux
))
if
(
restore_sig
frame
(
regs
,
frame
))
goto
badframe
;
goto
badframe
;
/* Send SIGTRAP if we're single-stepping */
/* Send SIGTRAP if we're single-stepping */
...
@@ -297,7 +265,6 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs)
...
@@ -297,7 +265,6 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs)
asmlinkage
int
sys_rt_sigreturn
(
struct
pt_regs
*
regs
)
asmlinkage
int
sys_rt_sigreturn
(
struct
pt_regs
*
regs
)
{
{
struct
rt_sigframe
__user
*
frame
;
struct
rt_sigframe
__user
*
frame
;
sigset_t
set
;
/* Always make any pending restarted system calls return -EINTR */
/* Always make any pending restarted system calls return -EINTR */
current_thread_info
()
->
restart_block
.
fn
=
do_no_restart_syscall
;
current_thread_info
()
->
restart_block
.
fn
=
do_no_restart_syscall
;
...
@@ -314,19 +281,11 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
...
@@ -314,19 +281,11 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
if
(
!
access_ok
(
VERIFY_READ
,
frame
,
sizeof
(
*
frame
)))
if
(
!
access_ok
(
VERIFY_READ
,
frame
,
sizeof
(
*
frame
)))
goto
badframe
;
goto
badframe
;
if
(
__copy_from_user
(
&
set
,
&
frame
->
uc
.
uc_sigmask
,
sizeof
(
set
)))
goto
badframe
;
sigdelsetmask
(
&
set
,
~
_BLOCKABLE
);
if
(
restore_sigframe
(
regs
,
&
frame
->
sig
))
spin_lock_irq
(
&
current
->
sighand
->
siglock
);
current
->
blocked
=
set
;
recalc_sigpending
();
spin_unlock_irq
(
&
current
->
sighand
->
siglock
);
if
(
restore_sigcontext
(
regs
,
&
frame
->
uc
.
uc_mcontext
,
&
frame
->
aux
))
goto
badframe
;
goto
badframe
;
if
(
do_sigaltstack
(
&
frame
->
uc
.
uc_stack
,
NULL
,
regs
->
ARM_sp
)
==
-
EFAULT
)
if
(
do_sigaltstack
(
&
frame
->
sig
.
uc
.
uc_stack
,
NULL
,
regs
->
ARM_sp
)
==
-
EFAULT
)
goto
badframe
;
goto
badframe
;
/* Send SIGTRAP if we're single-stepping */
/* Send SIGTRAP if we're single-stepping */
...
@@ -343,42 +302,46 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
...
@@ -343,42 +302,46 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
}
}
static
int
static
int
setup_sigcontext
(
struct
sigcontext
__user
*
sc
,
struct
aux_sigframe
__user
*
aux
,
setup_sigframe
(
struct
sigframe
__user
*
sf
,
struct
pt_regs
*
regs
,
sigset_t
*
set
)
struct
pt_regs
*
regs
,
unsigned
long
mask
)
{
{
struct
aux_sigframe
__user
*
aux
;
int
err
=
0
;
int
err
=
0
;
__put_user_error
(
regs
->
ARM_r0
,
&
sc
->
arm_r0
,
err
);
__put_user_error
(
regs
->
ARM_r0
,
&
sf
->
uc
.
uc_mcontext
.
arm_r0
,
err
);
__put_user_error
(
regs
->
ARM_r1
,
&
sc
->
arm_r1
,
err
);
__put_user_error
(
regs
->
ARM_r1
,
&
sf
->
uc
.
uc_mcontext
.
arm_r1
,
err
);
__put_user_error
(
regs
->
ARM_r2
,
&
sc
->
arm_r2
,
err
);
__put_user_error
(
regs
->
ARM_r2
,
&
sf
->
uc
.
uc_mcontext
.
arm_r2
,
err
);
__put_user_error
(
regs
->
ARM_r3
,
&
sc
->
arm_r3
,
err
);
__put_user_error
(
regs
->
ARM_r3
,
&
sf
->
uc
.
uc_mcontext
.
arm_r3
,
err
);
__put_user_error
(
regs
->
ARM_r4
,
&
sc
->
arm_r4
,
err
);
__put_user_error
(
regs
->
ARM_r4
,
&
sf
->
uc
.
uc_mcontext
.
arm_r4
,
err
);
__put_user_error
(
regs
->
ARM_r5
,
&
sc
->
arm_r5
,
err
);
__put_user_error
(
regs
->
ARM_r5
,
&
sf
->
uc
.
uc_mcontext
.
arm_r5
,
err
);
__put_user_error
(
regs
->
ARM_r6
,
&
sc
->
arm_r6
,
err
);
__put_user_error
(
regs
->
ARM_r6
,
&
sf
->
uc
.
uc_mcontext
.
arm_r6
,
err
);
__put_user_error
(
regs
->
ARM_r7
,
&
sc
->
arm_r7
,
err
);
__put_user_error
(
regs
->
ARM_r7
,
&
sf
->
uc
.
uc_mcontext
.
arm_r7
,
err
);
__put_user_error
(
regs
->
ARM_r8
,
&
sc
->
arm_r8
,
err
);
__put_user_error
(
regs
->
ARM_r8
,
&
sf
->
uc
.
uc_mcontext
.
arm_r8
,
err
);
__put_user_error
(
regs
->
ARM_r9
,
&
sc
->
arm_r9
,
err
);
__put_user_error
(
regs
->
ARM_r9
,
&
sf
->
uc
.
uc_mcontext
.
arm_r9
,
err
);
__put_user_error
(
regs
->
ARM_r10
,
&
sc
->
arm_r10
,
err
);
__put_user_error
(
regs
->
ARM_r10
,
&
sf
->
uc
.
uc_mcontext
.
arm_r10
,
err
);
__put_user_error
(
regs
->
ARM_fp
,
&
sc
->
arm_fp
,
err
);
__put_user_error
(
regs
->
ARM_fp
,
&
sf
->
uc
.
uc_mcontext
.
arm_fp
,
err
);
__put_user_error
(
regs
->
ARM_ip
,
&
sc
->
arm_ip
,
err
);
__put_user_error
(
regs
->
ARM_ip
,
&
sf
->
uc
.
uc_mcontext
.
arm_ip
,
err
);
__put_user_error
(
regs
->
ARM_sp
,
&
sc
->
arm_sp
,
err
);
__put_user_error
(
regs
->
ARM_sp
,
&
sf
->
uc
.
uc_mcontext
.
arm_sp
,
err
);
__put_user_error
(
regs
->
ARM_lr
,
&
sc
->
arm_lr
,
err
);
__put_user_error
(
regs
->
ARM_lr
,
&
sf
->
uc
.
uc_mcontext
.
arm_lr
,
err
);
__put_user_error
(
regs
->
ARM_pc
,
&
sc
->
arm_pc
,
err
);
__put_user_error
(
regs
->
ARM_pc
,
&
sf
->
uc
.
uc_mcontext
.
arm_pc
,
err
);
__put_user_error
(
regs
->
ARM_cpsr
,
&
sc
->
arm_cpsr
,
err
);
__put_user_error
(
regs
->
ARM_cpsr
,
&
sf
->
uc
.
uc_mcontext
.
arm_cpsr
,
err
);
__put_user_error
(
current
->
thread
.
trap_no
,
&
sc
->
trap_no
,
err
);
__put_user_error
(
current
->
thread
.
trap_no
,
&
sf
->
uc
.
uc_mcontext
.
trap_no
,
err
);
__put_user_error
(
current
->
thread
.
error_code
,
&
sc
->
error_code
,
err
);
__put_user_error
(
current
->
thread
.
error_code
,
&
sf
->
uc
.
uc_mcontext
.
error_code
,
err
);
__put_user_error
(
current
->
thread
.
address
,
&
sc
->
fault_address
,
err
);
__put_user_error
(
current
->
thread
.
address
,
&
sf
->
uc
.
uc_mcontext
.
fault_address
,
err
);
__put_user_error
(
mask
,
&
sc
->
oldmask
,
err
);
__put_user_error
(
set
->
sig
[
0
],
&
sf
->
uc
.
uc_mcontext
.
oldmask
,
err
);
err
|=
__copy_to_user
(
&
sf
->
uc
.
uc_sigmask
,
set
,
sizeof
(
*
set
));
aux
=
(
struct
aux_sigframe
__user
*
)
sf
->
uc
.
uc_regspace
;
#ifdef CONFIG_IWMMXT
#ifdef CONFIG_IWMMXT
if
(
err
==
0
&&
test_thread_flag
(
TIF_USING_IWMMXT
))
if
(
err
==
0
&&
test_thread_flag
(
TIF_USING_IWMMXT
))
err
|=
preserve_iwmmxt_context
(
&
aux
->
iwmmxt
);
err
|=
preserve_iwmmxt_context
(
&
aux
->
iwmmxt
);
#endif
#endif
#ifdef CONFIG_VFP
#ifdef CONFIG_VFP
// if (err == 0)
// if (err == 0)
// err |= vfp_save_state(&
aux->
vfp);
// err |= vfp_save_state(&
sf->aux.
vfp);
#endif
#endif
__put_user_error
(
0
,
&
aux
->
end_magic
,
err
);
return
err
;
return
err
;
}
}
...
@@ -487,13 +450,12 @@ setup_frame(int usig, struct k_sigaction *ka, sigset_t *set, struct pt_regs *reg
...
@@ -487,13 +450,12 @@ setup_frame(int usig, struct k_sigaction *ka, sigset_t *set, struct pt_regs *reg
if
(
!
frame
)
if
(
!
frame
)
return
1
;
return
1
;
err
|=
setup_sigcontext
(
&
frame
->
sc
,
&
frame
->
aux
,
regs
,
set
->
sig
[
0
]);
/*
* Set uc.uc_flags to a value which sc.trap_no would never have.
if
(
_NSIG_WORDS
>
1
)
{
*/
err
|=
__copy_to_user
(
frame
->
extramask
,
&
set
->
sig
[
1
],
__put_user_error
(
0x5ac3c35a
,
&
frame
->
uc
.
uc_flags
,
err
);
sizeof
(
frame
->
extramask
));
}
err
|=
setup_sigframe
(
frame
,
regs
,
set
);
if
(
err
==
0
)
if
(
err
==
0
)
err
=
setup_return
(
regs
,
ka
,
frame
->
retcode
,
frame
,
usig
);
err
=
setup_return
(
regs
,
ka
,
frame
->
retcode
,
frame
,
usig
);
...
@@ -511,25 +473,20 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
...
@@ -511,25 +473,20 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
if
(
!
frame
)
if
(
!
frame
)
return
1
;
return
1
;
__put_user_error
(
&
frame
->
info
,
&
frame
->
pinfo
,
err
);
__put_user_error
(
&
frame
->
uc
,
&
frame
->
puc
,
err
);
err
|=
copy_siginfo_to_user
(
&
frame
->
info
,
info
);
err
|=
copy_siginfo_to_user
(
&
frame
->
info
,
info
);
__put_user_error
(
0
,
&
frame
->
uc
.
uc_flags
,
err
);
__put_user_error
(
0
,
&
frame
->
sig
.
uc
.
uc_flags
,
err
);
__put_user_error
(
NULL
,
&
frame
->
uc
.
uc_link
,
err
);
__put_user_error
(
NULL
,
&
frame
->
sig
.
uc
.
uc_link
,
err
);
memset
(
&
stack
,
0
,
sizeof
(
stack
));
memset
(
&
stack
,
0
,
sizeof
(
stack
));
stack
.
ss_sp
=
(
void
__user
*
)
current
->
sas_ss_sp
;
stack
.
ss_sp
=
(
void
__user
*
)
current
->
sas_ss_sp
;
stack
.
ss_flags
=
sas_ss_flags
(
regs
->
ARM_sp
);
stack
.
ss_flags
=
sas_ss_flags
(
regs
->
ARM_sp
);
stack
.
ss_size
=
current
->
sas_ss_size
;
stack
.
ss_size
=
current
->
sas_ss_size
;
err
|=
__copy_to_user
(
&
frame
->
uc
.
uc_stack
,
&
stack
,
sizeof
(
stack
));
err
|=
__copy_to_user
(
&
frame
->
sig
.
uc
.
uc_stack
,
&
stack
,
sizeof
(
stack
));
err
|=
setup_sigcontext
(
&
frame
->
uc
.
uc_mcontext
,
&
frame
->
aux
,
regs
,
set
->
sig
[
0
]);
err
|=
__copy_to_user
(
&
frame
->
uc
.
uc_sigmask
,
set
,
sizeof
(
*
set
));
err
|=
setup_sigframe
(
&
frame
->
sig
,
regs
,
set
);
if
(
err
==
0
)
if
(
err
==
0
)
err
=
setup_return
(
regs
,
ka
,
frame
->
retcode
,
frame
,
usig
);
err
=
setup_return
(
regs
,
ka
,
frame
->
sig
.
retcode
,
frame
,
usig
);
if
(
err
==
0
)
{
if
(
err
==
0
)
{
/*
/*
...
@@ -538,7 +495,7 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
...
@@ -538,7 +495,7 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
* -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 2000-12-06
* -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 2000-12-06
*/
*/
regs
->
ARM_r1
=
(
unsigned
long
)
&
frame
->
info
;
regs
->
ARM_r1
=
(
unsigned
long
)
&
frame
->
info
;
regs
->
ARM_r2
=
(
unsigned
long
)
&
frame
->
uc
;
regs
->
ARM_r2
=
(
unsigned
long
)
&
frame
->
sig
.
uc
;
}
}
return
err
;
return
err
;
...
...
include/asm-arm/ucontext.h
View file @
c0897856
#ifndef _ASMARM_UCONTEXT_H
#ifndef _ASMARM_UCONTEXT_H
#define _ASMARM_UCONTEXT_H
#define _ASMARM_UCONTEXT_H
#include <asm/fpstate.h>
/*
* struct sigcontext only has room for the basic registers, but struct
* ucontext now has room for all registers which need to be saved and
* restored. Coprocessor registers are stored in uc_regspace. Each
* coprocessor's saved state should start with a documented 32-bit magic
* number, followed by a 32-bit word giving the coproccesor's saved size.
* uc_regspace may be expanded if necessary, although this takes some
* coordination with glibc.
*/
struct
ucontext
{
struct
ucontext
{
unsigned
long
uc_flags
;
unsigned
long
uc_flags
;
struct
ucontext
*
uc_link
;
struct
ucontext
*
uc_link
;
stack_t
uc_stack
;
stack_t
uc_stack
;
struct
sigcontext
uc_mcontext
;
struct
sigcontext
uc_mcontext
;
sigset_t
uc_sigmask
;
/* mask last for extensibility */
sigset_t
uc_sigmask
;
/* Allow for uc_sigmask growth. Glibc uses a 1024-bit sigset_t. */
int
__unused
[
32
-
(
sizeof
(
sigset_t
)
/
sizeof
(
int
))];
/* Last for extensibility. Eight byte aligned because some
coprocessors require eight byte alignment. */
unsigned
long
uc_regspace
[
128
]
__attribute__
((
__aligned__
(
8
)));
};
};
#ifdef __KERNEL__
/*
* Coprocessor save state. The magic values and specific
* coprocessor's layouts are part of the userspace ABI. Each one of
* these should be a multiple of eight bytes and aligned to eight
* bytes, to prevent unpredictable padding in the signal frame.
*/
#ifdef CONFIG_IWMMXT
/* iwmmxt_area is 0x98 bytes long, preceeded by 8 bytes of signature */
#define IWMMXT_MAGIC 0x12ef842a
#define IWMMXT_STORAGE_SIZE (IWMMXT_SIZE + 8)
struct
iwmmxt_sigframe
{
unsigned
long
magic
;
unsigned
long
size
;
struct
iwmmxt_struct
storage
;
}
__attribute__
((
__aligned__
(
8
)));
#endif
/* CONFIG_IWMMXT */
#ifdef CONFIG_VFP
#if __LINUX_ARM_ARCH__ < 6
/* For ARM pre-v6, we use fstmiax and fldmiax. This adds one extra
* word after the registers, and a word of padding at the end for
* alignment. */
#define VFP_MAGIC 0x56465001
#define VFP_STORAGE_SIZE 152
#else
#define VFP_MAGIC 0x56465002
#define VFP_STORAGE_SIZE 144
#endif
struct
vfp_sigframe
{
unsigned
long
magic
;
unsigned
long
size
;
union
vfp_state
storage
;
};
#endif
/* CONFIG_VFP */
/*
* Auxiliary signal frame. This saves stuff like FP state.
* The layout of this structure is not part of the user ABI,
* because the config options aren't. uc_regspace is really
* one of these.
*/
struct
aux_sigframe
{
#ifdef CONFIG_IWMMXT
struct
iwmmxt_sigframe
iwmmxt
;
#endif
#if 0 && defined CONFIG_VFP /* Not yet saved. */
struct vfp_sigframe vfp;
#endif
/* Something that isn't a valid magic number for any coprocessor. */
unsigned
long
end_magic
;
}
__attribute__
((
__aligned__
(
8
)));
#endif
#endif
/* !_ASMARM_UCONTEXT_H */
#endif
/* !_ASMARM_UCONTEXT_H */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment