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
nexedi
linux
Commits
fd3f9c88
Commit
fd3f9c88
authored
Nov 18, 2002
by
Jeff Dike
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Merged the signal frame cleanups and fixes from 2.4.
parent
31a47189
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
184 additions
and
128 deletions
+184
-128
arch/um/include/frame.h
arch/um/include/frame.h
+9
-9
arch/um/include/sysdep-i386/frame_kern.h
arch/um/include/sysdep-i386/frame_kern.h
+6
-3
arch/um/kernel/frame.c
arch/um/kernel/frame.c
+117
-85
arch/um/kernel/frame_kern.c
arch/um/kernel/frame_kern.c
+52
-31
No files found.
arch/um/include/frame.h
View file @
fd3f9c88
...
@@ -8,34 +8,34 @@
...
@@ -8,34 +8,34 @@
#include "sysdep/frame.h"
#include "sysdep/frame.h"
struct
sc_frame
{
struct
frame_common
{
void
*
data
;
void
*
data
;
int
len
;
int
len
;
int
sig_index
;
int
sig_index
;
int
sc_index
;
int
sr_index
;
int
sr_index
;
int
sr_relative
;
int
sr_relative
;
int
sp_index
;
int
sp_index
;
};
struct
sc_frame
{
struct
frame_common
common
;
int
sc_index
;
struct
arch_frame_data
arch
;
struct
arch_frame_data
arch
;
};
};
extern
struct
sc_frame
signal_frame_sc
;
extern
struct
sc_frame
signal_frame_sc
;
extern
struct
sc_frame
signal_frame_sc_sr
;
struct
si_frame
{
struct
si_frame
{
void
*
data
;
struct
frame_common
common
;
int
len
;
int
sig_index
;
int
sip_index
;
int
sip_index
;
int
si_index
;
int
si_index
;
int
sr_index
;
int
sr_relative
;
int
sp_index
;
};
};
extern
struct
si_frame
signal_frame_si
;
extern
struct
si_frame
signal_frame_si
;
extern
void
capture_signal_stack
(
void
);
extern
void
capture_signal_stack
(
void
);
extern
void
set_sc_ip_sp
(
void
*
sc_ptr
,
unsigned
long
ip
,
unsigned
long
sp
);
#endif
#endif
...
...
arch/um/include/sysdep-i386/frame_kern.h
View file @
fd3f9c88
...
@@ -20,7 +20,8 @@ static inline void *sp_to_rt_sc(unsigned long sp)
...
@@ -20,7 +20,8 @@ static inline void *sp_to_rt_sc(unsigned long sp)
{
{
unsigned
long
sc
;
unsigned
long
sc
;
sc
=
sp
-
signal_frame_si
.
sp_index
+
signal_frame_si
.
len
-
4
;
sc
=
sp
-
signal_frame_si
.
common
.
sp_index
+
signal_frame_si
.
common
.
len
-
4
;
return
((
void
*
)
sc
);
return
((
void
*
)
sc
);
}
}
...
@@ -28,7 +29,8 @@ static inline void *sp_to_mask(unsigned long sp)
...
@@ -28,7 +29,8 @@ static inline void *sp_to_mask(unsigned long sp)
{
{
unsigned
long
mask
;
unsigned
long
mask
;
mask
=
sp
-
signal_frame_sc
.
sp_index
+
signal_frame_sc
.
len
-
8
;
mask
=
sp
-
signal_frame_sc
.
common
.
sp_index
+
signal_frame_sc
.
common
.
len
-
8
;
return
((
void
*
)
mask
);
return
((
void
*
)
mask
);
}
}
...
@@ -38,7 +40,8 @@ static inline void *sp_to_rt_mask(unsigned long sp)
...
@@ -38,7 +40,8 @@ static inline void *sp_to_rt_mask(unsigned long sp)
{
{
unsigned
long
mask
;
unsigned
long
mask
;
mask
=
sp
-
signal_frame_si
.
sp_index
+
signal_frame_si
.
len
+
mask
=
sp
-
signal_frame_si
.
common
.
sp_index
+
signal_frame_si
.
common
.
len
+
sc_size
(
&
signal_frame_sc
.
arch
)
-
4
;
sc_size
(
&
signal_frame_sc
.
arch
)
-
4
;
return
((
void
*
)
mask
);
return
((
void
*
)
mask
);
}
}
...
...
arch/um/kernel/frame.c
View file @
fd3f9c88
...
@@ -12,6 +12,7 @@
...
@@ -12,6 +12,7 @@
#include <sched.h>
#include <sched.h>
#include <errno.h>
#include <errno.h>
#include <sys/ptrace.h>
#include <sys/ptrace.h>
#include <sys/syscall.h>
#include <sys/mman.h>
#include <sys/mman.h>
#include <asm/page.h>
#include <asm/page.h>
#include <asm/ptrace.h>
#include <asm/ptrace.h>
...
@@ -84,8 +85,8 @@ static int capture_stack(int (*child)(void *arg), void *arg, void *sp,
...
@@ -84,8 +85,8 @@ static int capture_stack(int (*child)(void *arg), void *arg, void *sp,
printf
(
"capture_stack : waitpid failed - errno = %d
\n
"
,
errno
);
printf
(
"capture_stack : waitpid failed - errno = %d
\n
"
,
errno
);
exit
(
1
);
exit
(
1
);
}
}
if
(
!
WIF
EXITED
(
status
)
||
(
WEXITSTATUS
(
status
)
!=
0
)){
if
(
!
WIF
SIGNALED
(
status
)
||
(
WTERMSIG
(
status
)
!=
9
)){
printf
(
"capture_stack : Expected exit s
tatus 0
, "
printf
(
"capture_stack : Expected exit s
ignal 9
, "
"got status = 0x%x
\n
"
,
status
);
"got status = 0x%x
\n
"
,
status
);
exit
(
1
);
exit
(
1
);
}
}
...
@@ -103,28 +104,61 @@ static int capture_stack(int (*child)(void *arg), void *arg, void *sp,
...
@@ -103,28 +104,61 @@ static int capture_stack(int (*child)(void *arg), void *arg, void *sp,
return
(
len
);
return
(
len
);
}
}
static
void
child_common
(
void
*
sp
,
int
size
,
sighandler_t
handler
,
int
flags
)
struct
common_raw
{
void
*
stack
;
int
size
;
unsigned
long
sig
;
unsigned
long
sr
;
unsigned
long
sp
;
};
#define SA_RESTORER (0x04000000)
typedef
unsigned
long
old_sigset_t
;
struct
old_sigaction
{
__sighandler_t
handler
;
old_sigset_t
sa_mask
;
unsigned
long
sa_flags
;
void
(
*
sa_restorer
)(
void
);
};
static
void
child_common
(
struct
common_raw
*
common
,
sighandler_t
handler
,
int
restorer
,
int
flags
)
{
{
stack_t
ss
;
stack_t
ss
=
((
stack_t
)
{
.
ss_sp
=
common
->
stack
,
struct
sigaction
sa
;
.
ss_flags
=
0
,
.
ss_size
=
common
->
size
});
int
err
;
if
(
ptrace
(
PTRACE_TRACEME
,
0
,
0
,
0
)
<
0
){
if
(
ptrace
(
PTRACE_TRACEME
,
0
,
0
,
0
)
<
0
){
printf
(
"PTRACE_TRACEME failed, errno = %d
\n
"
,
errno
);
printf
(
"PTRACE_TRACEME failed, errno = %d
\n
"
,
errno
);
}
}
ss
.
ss_sp
=
sp
;
ss
.
ss_flags
=
0
;
ss
.
ss_size
=
size
;
if
(
sigaltstack
(
&
ss
,
NULL
)
<
0
){
if
(
sigaltstack
(
&
ss
,
NULL
)
<
0
){
printf
(
"sigaltstack failed - errno = %d
\n
"
,
errno
);
printf
(
"sigaltstack failed - errno = %d
\n
"
,
errno
);
_exit
(
1
);
kill
(
getpid
(),
SIGKILL
);
}
}
if
(
restorer
){
struct
sigaction
sa
;
sa
.
sa_handler
=
handler
;
sa
.
sa_handler
=
handler
;
sigemptyset
(
&
sa
.
sa_mask
);
sigemptyset
(
&
sa
.
sa_mask
);
sa
.
sa_flags
=
SA_ONSTACK
|
flags
;
sa
.
sa_flags
=
SA_ONSTACK
|
flags
;
if
(
sigaction
(
SIGUSR1
,
&
sa
,
NULL
)
<
0
){
err
=
sigaction
(
SIGUSR1
,
&
sa
,
NULL
);
}
else
{
struct
old_sigaction
sa
;
sa
.
handler
=
handler
;
sa
.
sa_mask
=
0
;
sa
.
sa_flags
=
(
SA_ONSTACK
|
flags
)
&
~
SA_RESTORER
;
err
=
syscall
(
__NR_sigaction
,
SIGUSR1
,
&
sa
,
NULL
);
}
if
(
err
<
0
){
printf
(
"sigaction failed - errno = %d
\n
"
,
errno
);
printf
(
"sigaction failed - errno = %d
\n
"
,
errno
);
_exit
(
1
);
kill
(
getpid
(),
SIGKILL
);
}
}
os_stop_process
(
os_getpid
());
os_stop_process
(
os_getpid
());
...
@@ -133,13 +167,12 @@ static void child_common(void *sp, int size, sighandler_t handler, int flags)
...
@@ -133,13 +167,12 @@ static void child_common(void *sp, int size, sighandler_t handler, int flags)
/* Changed only during early boot */
/* Changed only during early boot */
struct
sc_frame
signal_frame_sc
;
struct
sc_frame
signal_frame_sc
;
struct
sc_frame
signal_frame_sc_sr
;
struct
sc_frame_raw
{
struct
sc_frame_raw
{
void
*
stack
;
struct
common_raw
common
;
int
size
;
unsigned
long
sig
;
unsigned
long
sc
;
unsigned
long
sc
;
unsigned
long
sr
;
int
restorer
;
unsigned
long
sp
;
struct
arch_frame_data_raw
arch
;
struct
arch_frame_data_raw
arch
;
};
};
...
@@ -148,20 +181,20 @@ static struct sc_frame_raw *raw_sc = NULL;
...
@@ -148,20 +181,20 @@ static struct sc_frame_raw *raw_sc = NULL;
static
void
sc_handler
(
int
sig
,
struct
sigcontext
sc
)
static
void
sc_handler
(
int
sig
,
struct
sigcontext
sc
)
{
{
raw_sc
->
sig
=
(
unsigned
long
)
&
sig
;
raw_sc
->
common
.
sig
=
(
unsigned
long
)
&
sig
;
raw_sc
->
common
.
sr
=
frame_restorer
();
raw_sc
->
common
.
sp
=
frame_sp
();
raw_sc
->
sc
=
(
unsigned
long
)
&
sc
;
raw_sc
->
sc
=
(
unsigned
long
)
&
sc
;
raw_sc
->
sr
=
frame_restorer
();
raw_sc
->
sp
=
frame_sp
();
setup_arch_frame_raw
(
&
raw_sc
->
arch
,
&
sc
);
setup_arch_frame_raw
(
&
raw_sc
->
arch
,
&
sc
);
os_stop_process
(
os_getpid
());
os_stop_process
(
os_getpid
());
_exit
(
0
);
kill
(
getpid
(),
SIGKILL
);
}
}
static
int
sc_child
(
void
*
arg
)
static
int
sc_child
(
void
*
arg
)
{
{
raw_sc
=
arg
;
raw_sc
=
arg
;
child_common
(
raw_sc
->
stack
,
raw_sc
->
size
,
(
sighandler_t
)
sc_handler
,
child_common
(
&
raw_sc
->
common
,
(
sighandler_t
)
sc_handler
,
0
);
raw_sc
->
restorer
,
0
);
return
(
-
1
);
return
(
-
1
);
}
}
...
@@ -169,13 +202,9 @@ static int sc_child(void *arg)
...
@@ -169,13 +202,9 @@ static int sc_child(void *arg)
struct
si_frame
signal_frame_si
;
struct
si_frame
signal_frame_si
;
struct
si_frame_raw
{
struct
si_frame_raw
{
void
*
stack
;
struct
common_raw
common
;
int
size
;
unsigned
long
sig
;
unsigned
long
sip
;
unsigned
long
sip
;
unsigned
long
si
;
unsigned
long
si
;
unsigned
long
sr
;
unsigned
long
sp
;
};
};
/* Changed only during early boot */
/* Changed only during early boot */
...
@@ -183,23 +212,59 @@ static struct si_frame_raw *raw_si = NULL;
...
@@ -183,23 +212,59 @@ static struct si_frame_raw *raw_si = NULL;
static
void
si_handler
(
int
sig
,
siginfo_t
*
si
)
static
void
si_handler
(
int
sig
,
siginfo_t
*
si
)
{
{
raw_si
->
sig
=
(
unsigned
long
)
&
sig
;
raw_si
->
common
.
sig
=
(
unsigned
long
)
&
sig
;
raw_si
->
common
.
sr
=
frame_restorer
();
raw_si
->
common
.
sp
=
frame_sp
();
raw_si
->
sip
=
(
unsigned
long
)
&
si
;
raw_si
->
sip
=
(
unsigned
long
)
&
si
;
raw_si
->
si
=
(
unsigned
long
)
si
;
raw_si
->
si
=
(
unsigned
long
)
si
;
raw_si
->
sr
=
frame_restorer
();
raw_si
->
sp
=
frame_sp
();
os_stop_process
(
os_getpid
());
os_stop_process
(
os_getpid
());
_exit
(
0
);
kill
(
getpid
(),
SIGKILL
);
}
}
static
int
si_child
(
void
*
arg
)
static
int
si_child
(
void
*
arg
)
{
{
raw_si
=
arg
;
raw_si
=
arg
;
child_common
(
raw_si
->
stack
,
raw_si
->
size
,
(
sighandler_t
)
si_handler
,
child_common
(
&
raw_si
->
common
,
(
sighandler_t
)
si_handler
,
1
,
SA_SIGINFO
);
SA_SIGINFO
);
return
(
-
1
);
return
(
-
1
);
}
}
static
int
relative_sr
(
unsigned
long
sr
,
int
sr_index
,
void
*
stack
,
void
*
framep
)
{
unsigned
long
*
srp
=
(
unsigned
long
*
)
sr
;
unsigned
long
frame
=
(
unsigned
long
)
framep
;
if
((
*
srp
&
PAGE_MASK
)
==
(
unsigned
long
)
stack
){
*
srp
-=
sr
;
*
((
unsigned
long
*
)
(
frame
+
sr_index
))
=
*
srp
;
return
(
1
);
}
else
return
(
0
);
}
static
unsigned
long
capture_stack_common
(
int
(
*
proc
)(
void
*
),
void
*
arg
,
struct
common_raw
*
common_in
,
void
*
top
,
void
*
sigstack
,
int
stack_len
,
struct
frame_common
*
common_out
)
{
unsigned
long
sig_top
=
(
unsigned
long
)
sigstack
+
stack_len
,
base
;
common_in
->
stack
=
(
void
*
)
sigstack
;
common_in
->
size
=
stack_len
;
common_out
->
len
=
capture_stack
(
proc
,
arg
,
top
,
sig_top
,
&
common_out
->
data
);
base
=
sig_top
-
common_out
->
len
;
common_out
->
sig_index
=
common_in
->
sig
-
base
;
common_out
->
sp_index
=
common_in
->
sp
-
base
;
common_out
->
sr_index
=
common_in
->
sr
-
base
;
common_out
->
sr_relative
=
relative_sr
(
common_in
->
sr
,
common_out
->
sr_index
,
sigstack
,
common_out
->
data
);
return
(
base
);
}
void
capture_signal_stack
(
void
)
void
capture_signal_stack
(
void
)
{
{
struct
sc_frame_raw
raw_sc
;
struct
sc_frame_raw
raw_sc
;
...
@@ -220,54 +285,29 @@ void capture_signal_stack(void)
...
@@ -220,54 +285,29 @@ void capture_signal_stack(void)
top
=
(
unsigned
long
)
stack
+
PAGE_SIZE
-
sizeof
(
void
*
);
top
=
(
unsigned
long
)
stack
+
PAGE_SIZE
-
sizeof
(
void
*
);
sig_top
=
(
unsigned
long
)
sigstack
+
PAGE_SIZE
;
sig_top
=
(
unsigned
long
)
sigstack
+
PAGE_SIZE
;
raw_sc
.
stack
=
sigstack
;
/* Get the sigcontext, no sigrestorer layout */
raw_sc
.
size
=
PAGE_SIZE
;
raw_sc
.
restorer
=
0
;
signal_frame_sc
.
len
=
capture_stack
(
sc_child
,
&
raw_sc
,
(
void
*
)
top
,
base
=
capture_stack_common
(
sc_child
,
&
raw_sc
,
&
raw_sc
.
common
,
sig_top
,
&
signal_frame_sc
.
data
);
(
void
*
)
top
,
sigstack
,
PAGE_SIZE
,
&
signal_frame_sc
.
common
);
/* These are the offsets within signal_frame_sc.data (counting from
* the bottom) of sig, sc, SA_RESTORER, and the initial sp.
*/
base
=
sig_top
-
signal_frame_sc
.
len
;
signal_frame_sc
.
sig_index
=
raw_sc
.
sig
-
base
;
signal_frame_sc
.
sc_index
=
raw_sc
.
sc
-
base
;
signal_frame_sc
.
sc_index
=
raw_sc
.
sc
-
base
;
signal_frame_sc
.
sr_index
=
raw_sc
.
sr
-
base
;
if
((
*
((
unsigned
long
*
)
raw_sc
.
sr
)
&
PAGE_MASK
)
==
(
unsigned
long
)
sigstack
){
unsigned
long
*
sr
=
(
unsigned
long
*
)
raw_sc
.
sr
;
unsigned
long
frame
=
(
unsigned
long
)
signal_frame_sc
.
data
;
signal_frame_sc
.
sr_relative
=
1
;
*
sr
-=
raw_sc
.
sr
;
*
((
unsigned
long
*
)
(
frame
+
signal_frame_sc
.
sr_index
))
=
*
sr
;
}
else
signal_frame_sc
.
sr_relative
=
0
;
signal_frame_sc
.
sp_index
=
raw_sc
.
sp
-
base
;
setup_arch_frame
(
&
raw_sc
.
arch
,
&
signal_frame_sc
.
arch
);
setup_arch_frame
(
&
raw_sc
.
arch
,
&
signal_frame_sc
.
arch
);
/* Repeat for the siginfo variant */
/* Ditto for the sigcontext, sigrestorer layout */
raw_sc
.
restorer
=
1
;
base
=
capture_stack_common
(
sc_child
,
&
raw_sc
,
&
raw_sc
.
common
,
(
void
*
)
top
,
sigstack
,
PAGE_SIZE
,
&
signal_frame_sc_sr
.
common
);
signal_frame_sc_sr
.
sc_index
=
raw_sc
.
sc
-
base
;
/* And the siginfo layout */
raw_si
.
stack
=
sigstack
;
base
=
capture_stack_common
(
si_child
,
&
raw_si
,
&
raw_si
.
common
,
raw_si
.
size
=
PAGE_SIZE
;
(
void
*
)
top
,
sigstack
,
PAGE_SIZE
,
signal_frame_si
.
len
=
capture_stack
(
si_child
,
&
raw_si
,
(
void
*
)
top
,
&
signal_frame_si
.
common
);
sig_top
,
&
signal_frame_si
.
data
);
base
=
sig_top
-
signal_frame_si
.
len
;
signal_frame_si
.
sig_index
=
raw_si
.
sig
-
base
;
signal_frame_si
.
sip_index
=
raw_si
.
sip
-
base
;
signal_frame_si
.
sip_index
=
raw_si
.
sip
-
base
;
signal_frame_si
.
si_index
=
raw_si
.
si
-
base
;
signal_frame_si
.
si_index
=
raw_si
.
si
-
base
;
signal_frame_si
.
sr_index
=
raw_si
.
sr
-
base
;
if
((
*
((
unsigned
long
*
)
raw_si
.
sr
)
&
PAGE_MASK
)
==
(
unsigned
long
)
sigstack
){
unsigned
long
*
sr
=
(
unsigned
long
*
)
raw_si
.
sr
;
unsigned
long
frame
=
(
unsigned
long
)
signal_frame_si
.
data
;
signal_frame_sc
.
sr_relative
=
1
;
*
sr
-=
raw_si
.
sr
;
*
((
unsigned
long
*
)
(
frame
+
signal_frame_si
.
sr_index
))
=
*
sr
;
}
else
signal_frame_si
.
sr_relative
=
0
;
signal_frame_si
.
sp_index
=
raw_si
.
sp
-
base
;
if
((
munmap
(
stack
,
PAGE_SIZE
)
<
0
)
||
if
((
munmap
(
stack
,
PAGE_SIZE
)
<
0
)
||
(
munmap
(
sigstack
,
PAGE_SIZE
)
<
0
)){
(
munmap
(
sigstack
,
PAGE_SIZE
)
<
0
)){
...
@@ -277,14 +317,6 @@ void capture_signal_stack(void)
...
@@ -277,14 +317,6 @@ void capture_signal_stack(void)
}
}
}
}
void
set_sc_ip_sp
(
void
*
sc_ptr
,
unsigned
long
ip
,
unsigned
long
sp
)
{
struct
sigcontext
*
sc
=
sc_ptr
;
SC_IP
(
sc
)
=
ip
;
SC_SP
(
sc
)
=
sp
;
}
/*
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* Emacs will notice this stuff at the end of the file and automatically
...
...
arch/um/kernel/frame_kern.c
View file @
fd3f9c88
...
@@ -13,16 +13,25 @@
...
@@ -13,16 +13,25 @@
static
int
copy_restorer
(
void
(
*
restorer
)(
void
),
unsigned
long
start
,
static
int
copy_restorer
(
void
(
*
restorer
)(
void
),
unsigned
long
start
,
unsigned
long
sr_index
,
int
sr_relative
)
unsigned
long
sr_index
,
int
sr_relative
)
{
{
if
(
restorer
!=
0
){
unsigned
long
sr
;
if
(
copy_to_user
((
void
*
)
(
start
+
sr_index
),
&
restorer
,
sizeof
(
restorer
)))
if
(
sr_relative
){
return
(
1
);
sr
=
(
unsigned
long
)
restorer
;
}
sr
+=
start
+
sr_index
;
else
if
(
sr_relative
){
restorer
=
(
void
(
*
)(
void
))
sr
;
unsigned
long
*
sr
=
(
unsigned
long
*
)
(
start
+
sr_index
);
*
sr
+=
(
unsigned
long
)
sr
;
}
}
return
(
0
);
return
(
copy_to_user
((
void
*
)
(
start
+
sr_index
),
&
restorer
,
sizeof
(
restorer
)));
}
static
int
copy_sc_to_user
(
void
*
to
,
struct
pt_regs
*
from
)
{
return
(
CHOOSE_MODE
(
copy_sc_to_user_tt
(
to
,
from
->
regs
.
mode
.
tt
,
&
signal_frame_sc_sr
.
arch
),
copy_sc_to_user_skas
(
to
,
&
from
->
regs
,
current
->
thread
.
cr2
,
current
->
thread
.
err
)));
}
}
int
setup_signal_stack_si
(
unsigned
long
stack_top
,
int
sig
,
int
setup_signal_stack_si
(
unsigned
long
stack_top
,
int
sig
,
...
@@ -34,27 +43,30 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
...
@@ -34,27 +43,30 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
void
*
sip
;
void
*
sip
;
int
sig_size
=
_NSIG_WORDS
*
sizeof
(
unsigned
long
);
int
sig_size
=
_NSIG_WORDS
*
sizeof
(
unsigned
long
);
start
=
stack_top
-
signal_frame_si
.
len
-
start
=
stack_top
-
signal_frame_si
.
common
.
len
-
sc_size
(
&
signal_frame_sc
.
arch
)
-
sig_size
;
sc_size
(
&
signal_frame_sc
.
arch
)
-
sig_size
;
sip
=
(
void
*
)
(
start
+
signal_frame_si
.
si_index
);
sip
=
(
void
*
)
(
start
+
signal_frame_si
.
si_index
);
sc
=
start
+
signal_frame_si
.
len
;
sc
=
start
+
signal_frame_si
.
common
.
len
;
sigs
=
sc
+
sc_size
(
&
signal_frame_sc
.
arch
);
sigs
=
sc
+
sc_size
(
&
signal_frame_sc
.
arch
);
if
(
copy_sc_to_user
((
void
*
)
sc
,
regs
->
regs
.
sc
,
&
signal_frame_sc
.
arch
)
||
if
(
restorer
==
NULL
)
copy_to_user
((
void
*
)
start
,
signal_frame_si
.
data
,
panic
(
"setup_signal_stack_si - no restorer"
);
signal_frame_si
.
len
)
||
copy_to_user
((
void
*
)
(
start
+
signal_frame_si
.
sig_index
),
&
sig
,
if
(
copy_sc_to_user
((
void
*
)
sc
,
regs
)
||
sizeof
(
sig
))
||
copy_to_user
((
void
*
)
start
,
signal_frame_si
.
common
.
data
,
signal_frame_si
.
common
.
len
)
||
copy_to_user
((
void
*
)
(
start
+
signal_frame_si
.
common
.
sig_index
),
&
sig
,
sizeof
(
sig
))
||
copy_siginfo_to_user
(
sip
,
info
)
||
copy_siginfo_to_user
(
sip
,
info
)
||
copy_to_user
((
void
*
)
(
start
+
signal_frame_si
.
sip_index
),
&
sip
,
copy_to_user
((
void
*
)
(
start
+
signal_frame_si
.
sip_index
),
&
sip
,
sizeof
(
sip
))
||
sizeof
(
sip
))
||
copy_to_user
((
void
*
)
sigs
,
mask
,
sig_size
)
||
copy_to_user
((
void
*
)
sigs
,
mask
,
sig_size
)
||
copy_restorer
(
restorer
,
start
,
signal_frame_si
.
sr_index
,
copy_restorer
(
restorer
,
start
,
signal_frame_si
.
common
.
sr_index
,
signal_frame_si
.
sr_relative
))
signal_frame_si
.
common
.
sr_relative
))
return
(
1
);
return
(
1
);
PT_REGS_IP
(
regs
)
=
handler
;
PT_REGS_IP
(
regs
)
=
handler
;
PT_REGS_SP
(
regs
)
=
start
+
signal_frame_sc
.
sp_index
;
PT_REGS_SP
(
regs
)
=
start
+
signal_frame_sc
.
common
.
sp_index
;
return
(
0
);
return
(
0
);
}
}
...
@@ -62,26 +74,35 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
...
@@ -62,26 +74,35 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
unsigned
long
handler
,
void
(
*
restorer
)(
void
),
unsigned
long
handler
,
void
(
*
restorer
)(
void
),
struct
pt_regs
*
regs
,
sigset_t
*
mask
)
struct
pt_regs
*
regs
,
sigset_t
*
mask
)
{
{
struct
frame_common
*
frame
=
&
signal_frame_sc_sr
.
common
;
void
*
user_sc
;
int
sig_size
=
(
_NSIG_WORDS
-
1
)
*
sizeof
(
unsigned
long
);
int
sig_size
=
(
_NSIG_WORDS
-
1
)
*
sizeof
(
unsigned
long
);
unsigned
long
sigs
,
start
=
stack_top
-
signal_frame_sc
.
len
-
sig_size
;
unsigned
long
sigs
,
sr
;
void
*
user_sc
=
(
void
*
)
(
start
+
signal_frame_sc
.
sc_index
);
unsigned
long
start
=
stack_top
-
frame
->
len
-
sig_size
;
user_sc
=
(
void
*
)
(
start
+
signal_frame_sc_sr
.
sc_index
);
if
(
restorer
==
NULL
){
frame
=
&
signal_frame_sc
.
common
;
user_sc
=
(
void
*
)
(
start
+
signal_frame_sc
.
sc_index
);
sr
=
(
unsigned
long
)
frame
->
data
;
sr
+=
frame
->
sr_index
;
sr
=
*
((
unsigned
long
*
)
sr
);
restorer
=
((
void
(
*
)(
void
))
sr
);
}
sigs
=
start
+
signal_frame_sc
.
len
;
sigs
=
start
+
frame
->
len
;
if
(
copy_to_user
((
void
*
)
start
,
signal_frame_sc
.
data
,
if
(
copy_to_user
((
void
*
)
start
,
frame
->
data
,
frame
->
len
)
||
signal_frame_sc
.
len
)
||
copy_to_user
((
void
*
)
(
start
+
frame
->
sig_index
),
&
sig
,
copy_to_user
((
void
*
)
(
start
+
signal_frame_sc
.
sig_index
),
&
sig
,
sizeof
(
sig
))
||
sizeof
(
sig
))
||
copy_sc_to_user
(
user_sc
,
regs
->
regs
.
sc
,
&
signal_frame_sc
.
arch
)
||
copy_sc_to_user
(
user_sc
,
regs
)
||
copy_to_user
(
sc_sigmask
(
user_sc
),
mask
,
sizeof
(
mask
->
sig
[
0
]))
||
copy_to_user
(
sc_sigmask
(
user_sc
),
mask
,
sizeof
(
mask
->
sig
[
0
]))
||
copy_to_user
((
void
*
)
sigs
,
&
mask
->
sig
[
1
],
sig_size
)
||
copy_to_user
((
void
*
)
sigs
,
&
mask
->
sig
[
1
],
sig_size
)
||
copy_restorer
(
restorer
,
start
,
signal_frame_sc
.
sr_index
,
copy_restorer
(
restorer
,
start
,
frame
->
sr_index
,
frame
->
sr_relative
))
signal_frame_sc
.
sr_relative
))
return
(
1
);
return
(
1
);
PT_REGS_IP
(
regs
)
=
handler
;
PT_REGS_IP
(
regs
)
=
handler
;
PT_REGS_SP
(
regs
)
=
start
+
signal_frame_sc
.
sp_index
;
PT_REGS_SP
(
regs
)
=
start
+
frame
->
sp_index
;
set_sc_ip_sp
(
regs
->
regs
.
sc
,
handler
,
start
+
signal_frame_sc
.
sp_index
);
return
(
0
);
return
(
0
);
}
}
...
...
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