Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
66fb9763
Q
qemu
项目概览
openeuler
/
qemu
通知
10
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Q
qemu
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
66fb9763
编写于
3月 23, 2003
作者:
B
bellard
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
basic signal handling
git-svn-id:
svn://svn.savannah.nongnu.org/qemu/trunk@41
c046a42c-6fe2-441c-8c8c-71466251a162
上级
1b6b029e
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
1058 addition
and
99 deletion
+1058
-99
Makefile
Makefile
+1
-1
TODO
TODO
+3
-1
linux-user/main.c
linux-user/main.c
+2
-4
linux-user/qemu.h
linux-user/qemu.h
+10
-0
linux-user/signal.c
linux-user/signal.c
+712
-27
linux-user/syscall.c
linux-user/syscall.c
+231
-63
linux-user/syscall_defs.h
linux-user/syscall_defs.h
+37
-0
ops_template.h
ops_template.h
+20
-0
syscall-i386.h
syscall-i386.h
+42
-3
未找到文件。
Makefile
浏览文件 @
66fb9763
...
...
@@ -36,7 +36,7 @@ LDFLAGS+=-p
main.o
:
CFLAGS+=-p
endif
OBJS
=
elfload.o main.o thunk.o syscall.o libgemu.a
OBJS
=
elfload.o main.o thunk.o syscall.o
signal.o
libgemu.a
LIBOBJS
+=
translate-i386.o op-i386.o exec-i386.o
# NOTE: the disassembler code is only needed for debugging
...
...
TODO
浏览文件 @
66fb9763
- asynchronous signal interrupt / clear synchronous signal handling
- add eflags restore in emulator
- finish signal handing (fp87 state)
- verify thread support (clone() and various locks)
- signals
- optimize translated cache chaining (DLL PLT-like system)
- vm86 syscall support
- overrides/16bit for string ops
...
...
linux-user/main.c
浏览文件 @
66fb9763
...
...
@@ -81,10 +81,6 @@ int cpu_x86_inl(int addr)
return
0
;
}
/* default linux values for the selectors */
#define __USER_CS (0x23)
#define __USER_DS (0x2B)
void
write_dt
(
void
*
ptr
,
unsigned
long
addr
,
unsigned
long
limit
,
int
seg32_bit
)
{
...
...
@@ -135,6 +131,7 @@ void cpu_loop(struct CPUX86State *env)
(
long
)
pc
,
err
);
abort
();
}
process_pending_signals
(
env
);
}
}
...
...
@@ -199,6 +196,7 @@ int main(int argc, char **argv)
target_set_brk
((
char
*
)
info
->
brk
);
syscall_init
();
signal_init
();
env
=
cpu_x86_init
();
...
...
linux-user/qemu.h
浏览文件 @
66fb9763
...
...
@@ -3,6 +3,12 @@
#include "thunk.h"
#ifdef TARGET_I386
/* default linux values for the selectors */
#define __USER_CS (0x23)
#define __USER_DS (0x2B)
struct
target_pt_regs
{
long
ebx
;
long
ecx
;
...
...
@@ -21,6 +27,8 @@ struct target_pt_regs {
int
xss
;
};
#endif
/* This struct is used to hold certain information about the image.
* Basically, it replicates in user space what would be certain
* task_struct fields in the kernel
...
...
@@ -53,5 +61,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
void
gemu_log
(
const
char
*
fmt
,
...)
__attribute__
((
format
(
printf
,
1
,
2
)));
struct
CPUX86State
;
void
cpu_loop
(
struct
CPUX86State
*
env
);
void
process_pending_signals
(
void
*
cpu_env
);
void
signal_init
(
void
);
#endif
linux-user/signal.c
浏览文件 @
66fb9763
/*
* Emulation of Linux signal
handling
* Emulation of Linux signal
s
*
* Copyright (c) 2003 Fabrice Bellard
*
...
...
@@ -19,22 +19,49 @@
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <signal.h>
#include <errno.h>
#include <sys/ucontext.h>
/* Algorithm strongly inspired from em86 : we queue the signals so
that we can handle them at precise points in the emulated code. */
#include "gemu.h"
#include "syscall_defs.h"
#ifdef TARGET_I386
#include "cpu-i386.h"
#include "syscall-i386.h"
#endif
/* signal handling inspired from em86. */
//#define DEBUG_SIGNAL
#define MAX_SIGQUEUE_SIZE 1024
struct
sigqueue
{
struct
sigqueue
*
next
;
siginfo_t
info
;
};
struct
emulated_sigaction
{
struct
target_sigaction
sa
;
int
nb_pending
;
struct
target_siginfo
info
;
int
pending
;
/* true if signal is pending */
struct
sigqueue
*
first
;
struct
sigqueue
info
;
/* in order to always have memory for the
first signal, we put it here */
};
struct
emulated_sigaction
sigact_table
[
NSIG
];
int
signal_pending
;
static
struct
emulated_sigaction
sigact_table
[
TARGET_NSIG
];
static
struct
sigqueue
sigqueue_table
[
MAX_SIGQUEUE_SIZE
];
/* siginfo queue */
static
struct
sigqueue
*
first_free
;
/* first free siginfo queue entry */
static
int
signal_pending
;
/* non zero if a signal may be pending */
static
void
host_signal_handler
(
int
host_signum
,
siginfo_t
*
info
,
void
*
puc
);
/* XXX: do it properly */
static
inline
int
host_to_target_signal
(
int
sig
)
{
return
sig
;
...
...
@@ -45,6 +72,51 @@ static inline int target_to_host_signal(int sig)
return
sig
;
}
void
host_to_target_sigset
(
target_sigset_t
*
d
,
sigset_t
*
s
)
{
int
i
;
for
(
i
=
0
;
i
<
TARGET_NSIG_WORDS
;
i
++
)
{
d
->
sig
[
i
]
=
tswapl
(((
unsigned
long
*
)
s
)[
i
]);
}
}
void
target_to_host_sigset
(
sigset_t
*
d
,
target_sigset_t
*
s
)
{
int
i
;
for
(
i
=
0
;
i
<
TARGET_NSIG_WORDS
;
i
++
)
{
((
unsigned
long
*
)
d
)[
i
]
=
tswapl
(
s
->
sig
[
i
]);
}
}
void
host_to_target_old_sigset
(
target_ulong
*
old_sigset
,
const
sigset_t
*
sigset
)
{
*
old_sigset
=
tswap32
(
*
(
unsigned
long
*
)
sigset
&
0xffffffff
);
}
void
target_to_host_old_sigset
(
sigset_t
*
sigset
,
const
target_ulong
*
old_sigset
)
{
sigemptyset
(
sigset
);
*
(
unsigned
long
*
)
sigset
=
tswapl
(
*
old_sigset
);
}
/* XXX: finish it */
void
host_to_target_siginfo
(
target_siginfo_t
*
tinfo
,
siginfo_t
*
info
)
{
tinfo
->
si_signo
=
tswap32
(
info
->
si_signo
);
tinfo
->
si_errno
=
tswap32
(
info
->
si_errno
);
tinfo
->
si_code
=
tswap32
(
info
->
si_code
);
}
/* XXX: finish it */
void
target_to_host_siginfo
(
siginfo_t
*
info
,
target_siginfo_t
*
tinfo
)
{
info
->
si_signo
=
tswap32
(
tinfo
->
si_signo
);
info
->
si_errno
=
tswap32
(
tinfo
->
si_errno
);
info
->
si_code
=
tswap32
(
tinfo
->
si_code
);
}
void
signal_init
(
void
)
{
struct
sigaction
act
;
...
...
@@ -55,51 +127,664 @@ void signal_init(void)
act
.
sa_flags
=
SA_SIGINFO
;
act
.
sa_sigaction
=
host_signal_handler
;
for
(
i
=
1
;
i
<
NSIG
;
i
++
)
{
sigaction
(
i
,
&
sa
,
NULL
);
sigaction
(
i
,
&
act
,
NULL
);
}
memset
(
sigact_table
,
0
,
sizeof
(
sigact_table
));
first_free
=
&
sigqueue_table
[
0
];
for
(
i
=
0
;
i
<
MAX_SIGQUEUE_SIZE
-
1
;
i
++
)
sigqueue_table
[
i
].
next
=
&
sigqueue_table
[
i
+
1
];
sigqueue_table
[
MAX_SIGQUEUE_SIZE
-
1
].
next
=
NULL
;
}
/* signal queue handling */
static
inline
struct
sigqueue
*
alloc_sigqueue
(
void
)
{
struct
sigqueue
*
q
=
first_free
;
if
(
!
q
)
return
NULL
;
first_free
=
q
->
next
;
return
q
;
}
static
inline
void
free_sigqueue
(
struct
sigqueue
*
q
)
{
q
->
next
=
first_free
;
first_free
=
q
;
}
static
int
queue_signal
(
struct
emulated_sigaction
*
k
,
int
sig
,
siginfo_t
*
info
)
{
struct
sigqueue
*
q
,
**
pq
;
pq
=
&
k
->
first
;
if
(
!
k
->
pending
||
sig
<
TARGET_SIGRTMIN
)
{
/* first signal or non real time signal */
q
=
&
k
->
info
;
}
else
{
q
=
alloc_sigqueue
();
if
(
!
q
)
return
-
EAGAIN
;
while
(
*
pq
!=
NULL
)
pq
=
&
(
*
pq
)
->
next
;
}
*
pq
=
q
;
q
->
info
=
*
info
;
q
->
next
=
NULL
;
k
->
pending
=
1
;
/* signal that a new signal is pending */
signal_pending
=
1
;
return
0
;
}
void
force_sig
(
int
sig
)
{
int
host_sig
;
/* abort execution with signal */
host_sig
=
target_to_host_signal
(
sig
);
fprintf
(
stderr
,
"gemu: uncaught target signal %d (%s) - exiting
\n
"
,
sig
,
strsignal
(
host_sig
));
_exit
(
-
host_sig
);
}
static
void
host_signal_handler
(
int
host_signum
,
siginfo_t
*
info
,
void
*
puc
)
{
struct
ucontext
*
uc
=
puc
;
int
signum
;
struct
emulated_sigaction
*
k
;
int
sig
;
target_ulong
handler
;
/* get target signal number */
sig
num
=
host_to_target
(
host_signum
);
if
(
sig
num
>=
TARGET_NSIG
)
sig
=
host_to_target_signal
(
host_signum
);
if
(
sig
<
1
||
sig
>
TARGET_NSIG
)
return
;
/* we save the old mask */
k
=
&
sigact_table
[
sig
-
1
];
#ifdef DEBUG_SIGNAL
fprintf
(
stderr
,
"gemu: got signal %d
\n
"
,
sig
);
#endif
handler
=
k
->
sa
.
_sa_handler
;
if
(
handler
==
TARGET_SIG_DFL
)
{
/* default handler : ignore some signal. The other are fatal */
if
(
sig
!=
TARGET_SIGCHLD
&&
sig
!=
TARGET_SIGURG
&&
sig
!=
TARGET_SIGWINCH
)
{
force_sig
(
sig
);
}
}
else
if
(
handler
==
TARGET_SIG_IGN
)
{
/* ignore signal */
}
else
if
(
handler
==
TARGET_SIG_ERR
)
{
force_sig
(
sig
);
}
else
{
queue_signal
(
k
,
sig
,
info
);
}
}
int
do_sigaction
(
int
sig
,
const
struct
target_sigaction
*
act
,
struct
target_sigaction
*
oact
)
{
struct
emulated_sigaction
*
k
;
if
(
sig
<
1
||
sig
>
TARGET_NSIG
)
return
-
EINVAL
;
k
=
&
sigact_table
[
sig
-
1
];
#if defined(DEBUG_SIGNAL) && 0
fprintf
(
stderr
,
"sigaction sig=%d act=0x%08x, oact=0x%08x
\n
"
,
sig
,
(
int
)
act
,
(
int
)
oact
);
#endif
if
(
oact
)
{
oact
->
_sa_handler
=
tswapl
(
k
->
sa
.
_sa_handler
);
oact
->
sa_flags
=
tswapl
(
k
->
sa
.
sa_flags
);
oact
->
sa_restorer
=
tswapl
(
k
->
sa
.
sa_restorer
);
oact
->
sa_mask
=
k
->
sa
.
sa_mask
;
}
if
(
act
)
{
k
->
sa
.
_sa_handler
=
tswapl
(
act
->
_sa_handler
);
k
->
sa
.
sa_flags
=
tswapl
(
act
->
sa_flags
);
k
->
sa
.
sa_restorer
=
tswapl
(
act
->
sa_restorer
);
k
->
sa
.
sa_mask
=
act
->
sa_mask
;
}
return
0
;
}
#ifdef TARGET_I386
/* from the Linux kernel */
struct
target_fpreg
{
uint16_t
significand
[
4
];
uint16_t
exponent
;
};
struct
target_fpxreg
{
uint16_t
significand
[
4
];
uint16_t
exponent
;
uint16_t
padding
[
3
];
};
struct
target_xmmreg
{
target_ulong
element
[
4
];
};
struct
target_fpstate
{
/* Regular FPU environment */
target_ulong
cw
;
target_ulong
sw
;
target_ulong
tag
;
target_ulong
ipoff
;
target_ulong
cssel
;
target_ulong
dataoff
;
target_ulong
datasel
;
struct
target_fpreg
_st
[
8
];
uint16_t
status
;
uint16_t
magic
;
/* 0xffff = regular FPU data only */
/* FXSR FPU environment */
target_ulong
_fxsr_env
[
6
];
/* FXSR FPU env is ignored */
target_ulong
mxcsr
;
target_ulong
reserved
;
struct
target_fpxreg
_fxsr_st
[
8
];
/* FXSR FPU reg data is ignored */
struct
target_xmmreg
_xmm
[
8
];
target_ulong
padding
[
56
];
};
#define X86_FXSR_MAGIC 0x0000
struct
target_sigcontext
{
uint16_t
gs
,
__gsh
;
uint16_t
fs
,
__fsh
;
uint16_t
es
,
__esh
;
uint16_t
ds
,
__dsh
;
target_ulong
edi
;
target_ulong
esi
;
target_ulong
ebp
;
target_ulong
esp
;
target_ulong
ebx
;
target_ulong
edx
;
target_ulong
ecx
;
target_ulong
eax
;
target_ulong
trapno
;
target_ulong
err
;
target_ulong
eip
;
uint16_t
cs
,
__csh
;
target_ulong
eflags
;
target_ulong
esp_at_signal
;
uint16_t
ss
,
__ssh
;
target_ulong
fpstate
;
/* pointer */
target_ulong
oldmask
;
target_ulong
cr2
;
};
typedef
struct
target_sigaltstack
{
target_ulong
ss_sp
;
int
ss_flags
;
target_ulong
ss_size
;
}
target_stack_t
;
struct
target_ucontext
{
target_ulong
uc_flags
;
target_ulong
uc_link
;
target_stack_t
uc_stack
;
struct
target_sigcontext
uc_mcontext
;
target_sigset_t
uc_sigmask
;
/* mask last for extensibility */
};
struct
sigframe
{
target_ulong
pretcode
;
int
sig
;
struct
target_sigcontext
sc
;
struct
target_fpstate
fpstate
;
target_ulong
extramask
[
TARGET_NSIG_WORDS
-
1
];
char
retcode
[
8
];
};
struct
rt_sigframe
{
target_ulong
pretcode
;
int
sig
;
target_ulong
pinfo
;
target_ulong
puc
;
struct
target_siginfo
info
;
struct
target_ucontext
uc
;
struct
target_fpstate
fpstate
;
char
retcode
[
8
];
};
/*
* Set up a signal frame.
*/
#define __put_user(x,ptr)\
({\
int size = sizeof(*ptr);\
switch(size) {\
case 1:\
stb(ptr, (typeof(*ptr))(x));\
break;\
case 2:\
stw(ptr, (typeof(*ptr))(x));\
break;\
case 4:\
stl(ptr, (typeof(*ptr))(x));\
break;\
case 8:\
stq(ptr, (typeof(*ptr))(x));\
break;\
default:\
abort();\
}\
0;\
})
#define get_user(val, ptr) (typeof(*ptr))(*(ptr))
#define __copy_to_user(dst, src, size)\
({\
memcpy(dst, src, size);\
0;\
})
static
inline
int
copy_siginfo_to_user
(
target_siginfo_t
*
tinfo
,
siginfo_t
*
info
)
{
host_to_target_siginfo
(
tinfo
,
info
);
return
0
;
}
/* XXX: save x87 state */
static
int
setup_sigcontext
(
struct
target_sigcontext
*
sc
,
struct
target_fpstate
*
fpstate
,
CPUX86State
*
env
,
unsigned
long
mask
)
{
int
err
=
0
;
err
|=
__put_user
(
env
->
segs
[
R_GS
],
(
unsigned
int
*
)
&
sc
->
gs
);
err
|=
__put_user
(
env
->
segs
[
R_FS
],
(
unsigned
int
*
)
&
sc
->
fs
);
err
|=
__put_user
(
env
->
segs
[
R_ES
],
(
unsigned
int
*
)
&
sc
->
es
);
err
|=
__put_user
(
env
->
segs
[
R_DS
],
(
unsigned
int
*
)
&
sc
->
ds
);
err
|=
__put_user
(
env
->
regs
[
R_EDI
],
&
sc
->
edi
);
err
|=
__put_user
(
env
->
regs
[
R_ESI
],
&
sc
->
esi
);
err
|=
__put_user
(
env
->
regs
[
R_EBP
],
&
sc
->
ebp
);
err
|=
__put_user
(
env
->
regs
[
R_ESP
],
&
sc
->
esp
);
err
|=
__put_user
(
env
->
regs
[
R_EBX
],
&
sc
->
ebx
);
err
|=
__put_user
(
env
->
regs
[
R_EDX
],
&
sc
->
edx
);
err
|=
__put_user
(
env
->
regs
[
R_ECX
],
&
sc
->
ecx
);
err
|=
__put_user
(
env
->
regs
[
R_EAX
],
&
sc
->
eax
);
err
|=
__put_user
(
/*current->thread.trap_no*/
0
,
&
sc
->
trapno
);
err
|=
__put_user
(
/*current->thread.error_code*/
0
,
&
sc
->
err
);
err
|=
__put_user
(
env
->
eip
,
&
sc
->
eip
);
err
|=
__put_user
(
env
->
segs
[
R_CS
],
(
unsigned
int
*
)
&
sc
->
cs
);
err
|=
__put_user
(
env
->
eflags
,
&
sc
->
eflags
);
err
|=
__put_user
(
env
->
regs
[
R_ESP
],
&
sc
->
esp_at_signal
);
err
|=
__put_user
(
env
->
segs
[
R_SS
],
(
unsigned
int
*
)
&
sc
->
ss
);
#if 0
tmp = save_i387(fpstate);
if (tmp < 0)
err = 1;
else
err |= __put_user(tmp ? fpstate : NULL, &sc->fpstate);
#else
err
|=
__put_user
(
0
,
&
sc
->
fpstate
);
#endif
/* non-iBCS2 extensions.. */
err
|=
__put_user
(
mask
,
&
sc
->
oldmask
);
err
|=
__put_user
(
/*current->thread.cr2*/
0
,
&
sc
->
cr2
);
return
err
;
}
/*
* Determine which stack to use..
*/
void
process_pending_signals
(
void
)
static
inline
void
*
get_sigframe
(
struct
emulated_sigaction
*
ka
,
CPUX86State
*
env
,
size_t
frame_size
)
{
int
signum
;
target_ulong
_sa_handler
;
unsigned
long
esp
;
/* Default to using normal stack */
esp
=
env
->
regs
[
R_ESP
];
#if 0
/* This is the X/Open sanctioned signal stack switching. */
if (ka->sa.sa_flags & SA_ONSTACK) {
if (sas_ss_flags(esp) == 0)
esp = current->sas_ss_sp + current->sas_ss_size;
}
/* This is the legacy signal stack switching. */
else if ((regs->xss & 0xffff) != __USER_DS &&
!(ka->sa.sa_flags & SA_RESTORER) &&
ka->sa.sa_restorer) {
esp = (unsigned long) ka->sa.sa_restorer;
}
#endif
return
(
void
*
)((
esp
-
frame_size
)
&
-
8ul
);
}
#define TF_MASK TRAP_FLAG
static
void
setup_frame
(
int
sig
,
struct
emulated_sigaction
*
ka
,
target_sigset_t
*
set
,
CPUX86State
*
env
)
{
struct
sigframe
*
frame
;
int
err
=
0
;
frame
=
get_sigframe
(
ka
,
env
,
sizeof
(
*
frame
));
#if 0
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto give_sigsegv;
#endif
err
|=
__put_user
((
/*current->exec_domain
&& current->exec_domain->signal_invmap
&& sig < 32
? current->exec_domain->signal_invmap[sig]
: */
sig
),
&
frame
->
sig
);
if
(
err
)
goto
give_sigsegv
;
setup_sigcontext
(
&
frame
->
sc
,
&
frame
->
fpstate
,
env
,
set
->
sig
[
0
]);
if
(
err
)
goto
give_sigsegv
;
if
(
TARGET_NSIG_WORDS
>
1
)
{
err
|=
__copy_to_user
(
frame
->
extramask
,
&
set
->
sig
[
1
],
sizeof
(
frame
->
extramask
));
}
if
(
err
)
goto
give_sigsegv
;
/* Set up to return from userspace. If provided, use a stub
already in userspace. */
if
(
ka
->
sa
.
sa_flags
&
TARGET_SA_RESTORER
)
{
err
|=
__put_user
(
ka
->
sa
.
sa_restorer
,
&
frame
->
pretcode
);
}
else
{
err
|=
__put_user
(
frame
->
retcode
,
&
frame
->
pretcode
);
/* This is popl %eax ; movl $,%eax ; int $0x80 */
err
|=
__put_user
(
0xb858
,
(
short
*
)(
frame
->
retcode
+
0
));
err
|=
__put_user
(
TARGET_NR_sigreturn
,
(
int
*
)(
frame
->
retcode
+
2
));
err
|=
__put_user
(
0x80cd
,
(
short
*
)(
frame
->
retcode
+
6
));
}
if
(
err
)
goto
give_sigsegv
;
/* Set up registers for signal handler */
env
->
regs
[
R_ESP
]
=
(
unsigned
long
)
frame
;
env
->
eip
=
(
unsigned
long
)
ka
->
sa
.
_sa_handler
;
cpu_x86_load_seg
(
env
,
R_DS
,
__USER_DS
);
cpu_x86_load_seg
(
env
,
R_ES
,
__USER_DS
);
cpu_x86_load_seg
(
env
,
R_SS
,
__USER_DS
);
cpu_x86_load_seg
(
env
,
R_CS
,
__USER_CS
);
env
->
eflags
&=
~
TF_MASK
;
return
;
give_sigsegv:
if
(
sig
==
TARGET_SIGSEGV
)
ka
->
sa
.
_sa_handler
=
TARGET_SIG_DFL
;
force_sig
(
TARGET_SIGSEGV
/* , current */
);
}
static
void
setup_rt_frame
(
int
sig
,
struct
emulated_sigaction
*
ka
,
siginfo_t
*
info
,
target_sigset_t
*
set
,
CPUX86State
*
env
)
{
struct
rt_sigframe
*
frame
;
int
err
=
0
;
frame
=
get_sigframe
(
ka
,
env
,
sizeof
(
*
frame
));
#if 0
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto give_sigsegv;
#endif
err
|=
__put_user
((
/*current->exec_domain
&& current->exec_domain->signal_invmap
&& sig < 32
? current->exec_domain->signal_invmap[sig]
: */
sig
),
&
frame
->
sig
);
err
|=
__put_user
((
target_ulong
)
&
frame
->
info
,
&
frame
->
pinfo
);
err
|=
__put_user
((
target_ulong
)
&
frame
->
uc
,
&
frame
->
puc
);
err
|=
copy_siginfo_to_user
(
&
frame
->
info
,
info
);
if
(
err
)
goto
give_sigsegv
;
struct
emulated_sigaction
*
esig
;
/* Create the ucontext. */
err
|=
__put_user
(
0
,
&
frame
->
uc
.
uc_flags
);
err
|=
__put_user
(
0
,
&
frame
->
uc
.
uc_link
);
err
|=
__put_user
(
/*current->sas_ss_sp*/
0
,
&
frame
->
uc
.
uc_stack
.
ss_sp
);
err
|=
__put_user
(
/* sas_ss_flags(regs->esp) */
0
,
&
frame
->
uc
.
uc_stack
.
ss_flags
);
err
|=
__put_user
(
/* current->sas_ss_size */
0
,
&
frame
->
uc
.
uc_stack
.
ss_size
);
err
|=
setup_sigcontext
(
&
frame
->
uc
.
uc_mcontext
,
&
frame
->
fpstate
,
env
,
set
->
sig
[
0
]);
err
|=
__copy_to_user
(
&
frame
->
uc
.
uc_sigmask
,
set
,
sizeof
(
*
set
));
if
(
err
)
goto
give_sigsegv
;
/* Set up to return from userspace. If provided, use a stub
already in userspace. */
if
(
ka
->
sa
.
sa_flags
&
TARGET_SA_RESTORER
)
{
err
|=
__put_user
(
ka
->
sa
.
sa_restorer
,
&
frame
->
pretcode
);
}
else
{
err
|=
__put_user
(
frame
->
retcode
,
&
frame
->
pretcode
);
/* This is movl $,%eax ; int $0x80 */
err
|=
__put_user
(
0xb8
,
(
char
*
)(
frame
->
retcode
+
0
));
err
|=
__put_user
(
TARGET_NR_rt_sigreturn
,
(
int
*
)(
frame
->
retcode
+
1
));
err
|=
__put_user
(
0x80cd
,
(
short
*
)(
frame
->
retcode
+
5
));
}
if
(
err
)
goto
give_sigsegv
;
/* Set up registers for signal handler */
env
->
regs
[
R_ESP
]
=
(
unsigned
long
)
frame
;
env
->
eip
=
(
unsigned
long
)
ka
->
sa
.
_sa_handler
;
cpu_x86_load_seg
(
env
,
R_DS
,
__USER_DS
);
cpu_x86_load_seg
(
env
,
R_ES
,
__USER_DS
);
cpu_x86_load_seg
(
env
,
R_SS
,
__USER_DS
);
cpu_x86_load_seg
(
env
,
R_CS
,
__USER_CS
);
env
->
eflags
&=
~
TF_MASK
;
return
;
give_sigsegv:
if
(
sig
==
TARGET_SIGSEGV
)
ka
->
sa
.
_sa_handler
=
TARGET_SIG_DFL
;
force_sig
(
TARGET_SIGSEGV
/* , current */
);
}
static
int
restore_sigcontext
(
CPUX86State
*
env
,
struct
target_sigcontext
*
sc
,
int
*
peax
)
{
unsigned
int
err
=
0
;
#define COPY(x) err |= __get_user(regs->x, &sc->x)
#define COPY_SEG(seg) \
{ unsigned short tmp; \
err |= __get_user(tmp, &sc->seg); \
regs->x##seg = tmp; }
#define COPY_SEG_STRICT(seg) \
{ unsigned short tmp; \
err |= __get_user(tmp, &sc->seg); \
regs->x##seg = tmp|3; }
#define GET_SEG(seg) \
{ unsigned short tmp; \
err |= __get_user(tmp, &sc->seg); \
loadsegment(seg,tmp); }
cpu_x86_load_seg
(
env
,
R_GS
,
lduw
(
&
sc
->
gs
));
cpu_x86_load_seg
(
env
,
R_FS
,
lduw
(
&
sc
->
fs
));
cpu_x86_load_seg
(
env
,
R_ES
,
lduw
(
&
sc
->
es
));
cpu_x86_load_seg
(
env
,
R_DS
,
lduw
(
&
sc
->
ds
));
env
->
regs
[
R_EDI
]
=
ldl
(
&
sc
->
edi
);
env
->
regs
[
R_ESI
]
=
ldl
(
&
sc
->
esi
);
env
->
regs
[
R_EBP
]
=
ldl
(
&
sc
->
ebp
);
env
->
regs
[
R_ESP
]
=
ldl
(
&
sc
->
esp
);
env
->
regs
[
R_EBX
]
=
ldl
(
&
sc
->
ebx
);
env
->
regs
[
R_EDX
]
=
ldl
(
&
sc
->
edx
);
env
->
regs
[
R_ECX
]
=
ldl
(
&
sc
->
ecx
);
env
->
eip
=
ldl
(
&
sc
->
eip
);
cpu_x86_load_seg
(
env
,
R_CS
,
lduw
(
&
sc
->
cs
)
|
3
);
cpu_x86_load_seg
(
env
,
R_SS
,
lduw
(
&
sc
->
ss
)
|
3
);
{
unsigned
int
tmpflags
;
tmpflags
=
ldl
(
&
sc
->
eflags
);
env
->
eflags
=
(
env
->
eflags
&
~
0x40DD5
)
|
(
tmpflags
&
0x40DD5
);
// regs->orig_eax = -1; /* disable syscall checks */
}
#if 0
{
struct _fpstate * buf;
err |= __get_user(buf, &sc->fpstate);
if (buf) {
if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
goto badframe;
err |= restore_i387(buf);
}
}
#endif
*
peax
=
ldl
(
&
sc
->
eax
);
return
err
;
#if 0
badframe:
return 1;
#endif
}
long
do_sigreturn
(
CPUX86State
*
env
)
{
struct
sigframe
*
frame
=
(
struct
sigframe
*
)(
env
->
regs
[
R_ESP
]
-
8
);
target_sigset_t
target_set
;
sigset_t
set
;
int
eax
,
i
;
/* set blocked signals */
target_set
.
sig
[
0
]
=
frame
->
sc
.
oldmask
;
for
(
i
=
1
;
i
<
TARGET_NSIG_WORDS
;
i
++
)
target_set
.
sig
[
i
]
=
frame
->
extramask
[
i
-
1
];
target_to_host_sigset
(
&
set
,
&
target_set
);
sigprocmask
(
SIG_SETMASK
,
&
set
,
NULL
);
/* restore registers */
if
(
restore_sigcontext
(
env
,
&
frame
->
sc
,
&
eax
))
goto
badframe
;
return
eax
;
badframe:
force_sig
(
TARGET_SIGSEGV
);
return
0
;
}
long
do_rt_sigreturn
(
CPUX86State
*
env
)
{
struct
rt_sigframe
*
frame
=
(
struct
rt_sigframe
*
)(
env
->
regs
[
R_ESP
]
-
4
);
target_sigset_t
target_set
;
sigset_t
set
;
// stack_t st;
int
eax
;
#if 0
if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
goto badframe;
#endif
memcpy
(
&
target_set
,
&
frame
->
uc
.
uc_sigmask
,
sizeof
(
target_sigset_t
));
target_to_host_sigset
(
&
set
,
&
target_set
);
sigprocmask
(
SIG_SETMASK
,
&
set
,
NULL
);
if
(
restore_sigcontext
(
env
,
&
frame
->
uc
.
uc_mcontext
,
&
eax
))
goto
badframe
;
#if 0
if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
goto badframe;
/* It is more difficult to avoid calling this function than to
call it and ignore errors. */
do_sigaltstack(&st, NULL, regs->esp);
#endif
return
eax
;
badframe:
force_sig
(
TARGET_SIGSEGV
);
return
0
;
}
#endif
void
process_pending_signals
(
void
*
cpu_env
)
{
int
sig
;
target_ulong
handler
;
target_sigset_t
set
;
struct
emulated_sigaction
*
k
;
struct
sigqueue
*
q
;
if
(
!
signal_pending
)
return
;
esig
=
sigact_table
;
for
(
sig
num
=
1
;
signum
<
TARGET_NSIG
;
signum
++
)
{
if
(
esig
->
nb_pending
!=
0
)
k
=
sigact_table
;
for
(
sig
=
1
;
sig
<=
TARGET_NSIG
;
sig
++
)
{
if
(
k
->
pending
)
goto
handle_signal
;
esig
++
;
k
++
;
}
/* if no signal is pending, just return */
signal_pending
=
0
;
return
;
handle_signal:
_sa_handler
=
esig
->
sa
.
_sa_handler
;
if
(
_sa_handler
==
TARGET_SIG_DFL
)
{
/*
default
handling
#ifdef DEBUG_SIGNAL
fprintf
(
stderr
,
"gemu: process signal %d
\n
"
,
sig
);
#endif
/* dequeue signal */
q
=
k
->
first
;
k
->
first
=
q
->
next
;
if
(
!
k
->
first
)
k
->
pending
=
0
;
handler
=
k
->
sa
.
_sa_handler
;
if
(
handler
==
TARGET_SIG_DFL
)
{
/* default handler : ignore some signal. The other are fatal */
if
(
sig
!=
TARGET_SIGCHLD
&&
sig
!=
TARGET_SIGURG
&&
sig
!=
TARGET_SIGWINCH
)
{
force_sig
(
sig
);
}
}
else
if
(
handler
==
TARGET_SIG_IGN
)
{
/* ignore sig */
}
else
if
(
handler
==
TARGET_SIG_ERR
)
{
force_sig
(
sig
);
}
else
{
set
=
k
->
sa
.
sa_mask
;
/* send the signal to the CPU */
if
(
k
->
sa
.
sa_flags
&
TARGET_SA_SIGINFO
)
setup_rt_frame
(
sig
,
k
,
&
q
->
info
,
&
set
,
cpu_env
);
else
setup_frame
(
sig
,
k
,
&
set
,
cpu_env
);
if
(
k
->
sa
.
sa_flags
&
TARGET_SA_RESETHAND
)
k
->
sa
.
_sa_handler
=
TARGET_SIG_DFL
;
}
if
(
q
!=
&
k
->
info
)
free_sigqueue
(
q
);
}
}
linux-user/syscall.c
浏览文件 @
66fb9763
...
...
@@ -75,12 +75,18 @@
#include "syscall-i386.h"
#endif
void
host_to_target_siginfo
(
target_siginfo_t
*
tinfo
,
siginfo_t
*
info
);
void
target_to_host_siginfo
(
siginfo_t
*
info
,
target_siginfo_t
*
tinfo
);
long
do_sigreturn
(
CPUX86State
*
env
);
long
do_rt_sigreturn
(
CPUX86State
*
env
);
#define __NR_sys_uname __NR_uname
#define __NR_sys_getcwd1 __NR_getcwd
#define __NR_sys_statfs __NR_statfs
#define __NR_sys_fstatfs __NR_fstatfs
#define __NR_sys_getdents __NR_getdents
#define __NR_sys_getdents64 __NR_getdents64
#define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
#ifdef __NR_gettid
_syscall0
(
int
,
gettid
)
...
...
@@ -97,6 +103,9 @@ _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
loff_t
*
,
res
,
uint
,
wh
);
_syscall2
(
int
,
sys_statfs
,
const
char
*
,
path
,
struct
kernel_statfs
*
,
buf
)
_syscall2
(
int
,
sys_fstatfs
,
int
,
fd
,
struct
kernel_statfs
*
,
buf
)
_syscall3
(
int
,
sys_rt_sigqueueinfo
,
int
,
pid
,
int
,
sig
,
siginfo_t
*
,
uinfo
)
extern
int
personality
(
int
);
static
inline
long
get_errno
(
long
ret
)
{
...
...
@@ -199,18 +208,18 @@ static inline void host_to_target_fds(target_long *target_fds,
#endif
}
/* XXX: incorrect for some archs */
static
void
host_to_target_old_sigset
(
target_ulong
*
old_sigset
,
const
sigset_t
*
sigset
)
static
inline
void
target_to_host_timeval
(
struct
timeval
*
tv
,
struct
target_timeval
*
target_tv
)
{
*
old_sigset
=
tswap32
(
*
(
unsigned
long
*
)
sigset
&
0xffffffff
);
tv
->
tv_sec
=
tswapl
(
target_tv
->
tv_sec
);
tv
->
tv_usec
=
tswapl
(
target_tv
->
tv_usec
);
}
static
void
target_to_host_old_sigset
(
sigset_t
*
sigset
,
const
target_ulong
*
old_sigset
)
static
inline
void
host_to_target_timeval
(
struct
target_timeval
*
target_tv
,
struct
timeval
*
tv
)
{
sigemptyset
(
sigset
);
*
(
unsigned
long
*
)
sigset
=
tswapl
(
*
old_sigset
);
target_tv
->
tv_sec
=
tswapl
(
tv
->
tv_sec
);
target_tv
->
tv_usec
=
tswapl
(
tv
->
tv_usec
);
}
...
...
@@ -1042,28 +1051,195 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
ret
=
get_errno
(
setsid
());
break
;
case
TARGET_NR_sigaction
:
#if 1
{
ret
=
0
;
struct
target_old_sigaction
*
old_act
=
(
void
*
)
arg2
;
struct
target_old_sigaction
*
old_oact
=
(
void
*
)
arg3
;
struct
target_sigaction
act
,
oact
,
*
pact
;
if
(
old_act
)
{
act
.
_sa_handler
=
old_act
->
_sa_handler
;
target_siginitset
(
&
act
.
sa_mask
,
old_act
->
sa_mask
);
act
.
sa_flags
=
old_act
->
sa_flags
;
act
.
sa_restorer
=
old_act
->
sa_restorer
;
pact
=
&
act
;
}
else
{
pact
=
NULL
;
}
ret
=
get_errno
(
do_sigaction
(
arg1
,
pact
,
&
oact
));
if
(
!
is_error
(
ret
)
&&
old_oact
)
{
old_oact
->
_sa_handler
=
oact
.
_sa_handler
;
old_oact
->
sa_mask
=
oact
.
sa_mask
.
sig
[
0
];
old_oact
->
sa_flags
=
oact
.
sa_flags
;
old_oact
->
sa_restorer
=
oact
.
sa_restorer
;
}
}
break
;
#else
goto
unimplemented
;
#endif
case
TARGET_NR_rt_sigaction
:
ret
=
get_errno
(
do_sigaction
(
arg1
,
(
void
*
)
arg2
,
(
void
*
)
arg3
))
;
break
;
case
TARGET_NR_sgetmask
:
goto
unimplemented
;
{
sigset_t
cur_set
;
target_ulong
target_set
;
sigprocmask
(
0
,
NULL
,
&
cur_set
);
host_to_target_old_sigset
(
&
target_set
,
&
cur_set
);
ret
=
target_set
;
}
break
;
case
TARGET_NR_ssetmask
:
goto
unimplemented
;
{
sigset_t
set
,
oset
,
cur_set
;
target_ulong
target_set
=
arg1
;
sigprocmask
(
0
,
NULL
,
&
cur_set
);
target_to_host_old_sigset
(
&
set
,
&
target_set
);
sigorset
(
&
set
,
&
set
,
&
cur_set
);
sigprocmask
(
SIG_SETMASK
,
&
set
,
&
oset
);
host_to_target_old_sigset
(
&
target_set
,
&
oset
);
ret
=
target_set
;
}
break
;
case
TARGET_NR_sigprocmask
:
{
int
how
=
arg1
;
sigset_t
set
,
oldset
,
*
set_ptr
;
target_ulong
*
pset
=
(
void
*
)
arg2
,
*
poldset
=
(
void
*
)
arg3
;
if
(
pset
)
{
switch
(
how
)
{
case
TARGET_SIG_BLOCK
:
how
=
SIG_BLOCK
;
break
;
case
TARGET_SIG_UNBLOCK
:
how
=
SIG_UNBLOCK
;
break
;
case
TARGET_SIG_SETMASK
:
how
=
SIG_SETMASK
;
break
;
default:
ret
=
-
EINVAL
;
goto
fail
;
}
target_to_host_old_sigset
(
&
set
,
pset
);
set_ptr
=
&
set
;
}
else
{
how
=
0
;
set_ptr
=
NULL
;
}
ret
=
get_errno
(
sigprocmask
(
arg1
,
set_ptr
,
&
oldset
));
if
(
!
is_error
(
ret
)
&&
poldset
)
{
host_to_target_old_sigset
(
poldset
,
&
oldset
);
}
}
break
;
case
TARGET_NR_rt_sigprocmask
:
{
int
how
=
arg1
;
sigset_t
set
,
oldset
,
*
set_ptr
;
target_sigset_t
*
pset
=
(
void
*
)
arg2
;
target_sigset_t
*
poldset
=
(
void
*
)
arg3
;
if
(
pset
)
{
switch
(
how
)
{
case
TARGET_SIG_BLOCK
:
how
=
SIG_BLOCK
;
break
;
case
TARGET_SIG_UNBLOCK
:
how
=
SIG_UNBLOCK
;
break
;
case
TARGET_SIG_SETMASK
:
how
=
SIG_SETMASK
;
break
;
default:
ret
=
-
EINVAL
;
goto
fail
;
}
target_to_host_sigset
(
&
set
,
pset
);
set_ptr
=
&
set
;
}
else
{
how
=
0
;
set_ptr
=
NULL
;
}
ret
=
get_errno
(
sigprocmask
(
how
,
set_ptr
,
&
oldset
));
if
(
!
is_error
(
ret
)
&&
poldset
)
{
host_to_target_sigset
(
poldset
,
&
oldset
);
}
}
break
;
case
TARGET_NR_sigpending
:
{
sigset_t
set
;
ret
=
get_errno
(
sigpending
(
&
set
));
if
(
!
is_error
(
ret
))
{
host_to_target_old_sigset
((
target_ulong
*
)
arg1
,
&
set
);
}
}
break
;
case
TARGET_NR_rt_sigpending
:
{
sigset_t
set
;
ret
=
get_errno
(
sigpending
(
&
set
));
if
(
!
is_error
(
ret
))
{
host_to_target_sigset
((
target_sigset_t
*
)
arg1
,
&
set
);
}
}
break
;
case
TARGET_NR_sigsuspend
:
{
sigset_t
set
;
target_to_host_old_sigset
(
&
set
,
(
target_ulong
*
)
arg1
);
ret
=
get_errno
(
sigsuspend
(
&
set
));
}
break
;
case
TARGET_NR_rt_sigsuspend
:
{
sigset_t
set
;
target_to_host_sigset
(
&
set
,
(
target_sigset_t
*
)
arg1
);
ret
=
get_errno
(
sigsuspend
(
&
set
));
}
break
;
case
TARGET_NR_rt_sigtimedwait
:
{
target_sigset_t
*
target_set
=
(
void
*
)
arg1
;
target_siginfo_t
*
target_uinfo
=
(
void
*
)
arg2
;
struct
target_timespec
*
target_uts
=
(
void
*
)
arg3
;
sigset_t
set
;
struct
timespec
uts
,
*
puts
;
siginfo_t
uinfo
;
target_to_host_sigset
(
&
set
,
target_set
);
if
(
target_uts
)
{
puts
=
&
uts
;
puts
->
tv_sec
=
tswapl
(
target_uts
->
tv_sec
);
puts
->
tv_nsec
=
tswapl
(
target_uts
->
tv_nsec
);
}
else
{
puts
=
NULL
;
}
ret
=
get_errno
(
sigtimedwait
(
&
set
,
&
uinfo
,
puts
));
if
(
!
is_error
(
ret
)
&&
target_uinfo
)
{
host_to_target_siginfo
(
target_uinfo
,
&
uinfo
);
}
}
break
;
case
TARGET_NR_rt_sigqueueinfo
:
{
siginfo_t
uinfo
;
target_to_host_siginfo
(
&
uinfo
,
(
target_siginfo_t
*
)
arg3
);
ret
=
get_errno
(
sys_rt_sigqueueinfo
(
arg1
,
arg2
,
&
uinfo
));
}
break
;
case
TARGET_NR_sigreturn
:
/* NOTE: ret is eax, so not transcoding must be done */
ret
=
do_sigreturn
(
cpu_env
);
break
;
case
TARGET_NR_rt_sigreturn
:
/* NOTE: ret is eax, so not transcoding must be done */
ret
=
do_rt_sigreturn
(
cpu_env
);
break
;
case
TARGET_NR_setreuid
:
ret
=
get_errno
(
setreuid
(
arg1
,
arg2
));
break
;
case
TARGET_NR_setregid
:
ret
=
get_errno
(
setregid
(
arg1
,
arg2
));
break
;
case
TARGET_NR_sigsuspend
:
goto
unimplemented
;
case
TARGET_NR_sigpending
:
goto
unimplemented
;
case
TARGET_NR_sethostname
:
ret
=
get_errno
(
sethostname
((
const
char
*
)
arg1
,
arg2
));
break
;
...
...
@@ -1190,9 +1366,43 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
case
TARGET_NR_syslog
:
goto
unimplemented
;
case
TARGET_NR_setitimer
:
goto
unimplemented
;
{
struct
target_itimerval
*
target_value
=
(
void
*
)
arg2
;
struct
target_itimerval
*
target_ovalue
=
(
void
*
)
arg3
;
struct
itimerval
value
,
ovalue
,
*
pvalue
;
if
(
target_value
)
{
pvalue
=
&
value
;
target_to_host_timeval
(
&
pvalue
->
it_interval
,
&
target_value
->
it_interval
);
target_to_host_timeval
(
&
pvalue
->
it_value
,
&
target_value
->
it_value
);
}
else
{
pvalue
=
NULL
;
}
ret
=
get_errno
(
setitimer
(
arg1
,
pvalue
,
&
ovalue
));
if
(
!
is_error
(
ret
)
&&
target_ovalue
)
{
host_to_target_timeval
(
&
target_ovalue
->
it_interval
,
&
ovalue
.
it_interval
);
host_to_target_timeval
(
&
target_ovalue
->
it_value
,
&
ovalue
.
it_value
);
}
}
break
;
case
TARGET_NR_getitimer
:
goto
unimplemented
;
{
struct
target_itimerval
*
target_value
=
(
void
*
)
arg2
;
struct
itimerval
value
;
ret
=
get_errno
(
getitimer
(
arg1
,
&
value
));
if
(
!
is_error
(
ret
)
&&
target_value
)
{
host_to_target_timeval
(
&
target_value
->
it_interval
,
&
value
.
it_interval
);
host_to_target_timeval
(
&
target_value
->
it_value
,
&
value
.
it_value
);
}
}
break
;
case
TARGET_NR_stat
:
ret
=
get_errno
(
stat
((
const
char
*
)
arg1
,
&
st
));
goto
do_stat
;
...
...
@@ -1279,8 +1489,6 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
case
TARGET_NR_fsync
:
ret
=
get_errno
(
fsync
(
arg1
));
break
;
case
TARGET_NR_sigreturn
:
goto
unimplemented
;
case
TARGET_NR_clone
:
ret
=
get_errno
(
do_fork
(
cpu_env
,
arg1
,
arg2
));
break
;
...
...
@@ -1301,39 +1509,6 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
case
TARGET_NR_mprotect
:
ret
=
get_errno
(
mprotect
((
void
*
)
arg1
,
arg2
,
arg3
));
break
;
case
TARGET_NR_sigprocmask
:
{
int
how
=
arg1
;
sigset_t
set
,
oldset
,
*
set_ptr
;
target_ulong
*
pset
=
(
void
*
)
arg2
,
*
poldset
=
(
void
*
)
arg3
;
switch
(
how
)
{
case
TARGET_SIG_BLOCK
:
how
=
SIG_BLOCK
;
break
;
case
TARGET_SIG_UNBLOCK
:
how
=
SIG_UNBLOCK
;
break
;
case
TARGET_SIG_SETMASK
:
how
=
SIG_SETMASK
;
break
;
default:
ret
=
-
EINVAL
;
goto
fail
;
}
if
(
pset
)
{
target_to_host_old_sigset
(
&
set
,
pset
);
set_ptr
=
&
set
;
}
else
{
set_ptr
=
NULL
;
}
ret
=
get_errno
(
sigprocmask
(
arg1
,
set_ptr
,
&
oldset
));
if
(
!
is_error
(
ret
)
&&
poldset
)
{
host_to_target_old_sigset
(
poldset
,
&
oldset
);
}
}
break
;
case
TARGET_NR_create_module
:
case
TARGET_NR_init_module
:
case
TARGET_NR_delete_module
:
...
...
@@ -1516,13 +1691,6 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
case
TARGET_NR_setresgid
:
case
TARGET_NR_getresgid
:
case
TARGET_NR_prctl
:
case
TARGET_NR_rt_sigreturn
:
case
TARGET_NR_rt_sigaction
:
case
TARGET_NR_rt_sigprocmask
:
case
TARGET_NR_rt_sigpending
:
case
TARGET_NR_rt_sigtimedwait
:
case
TARGET_NR_rt_sigqueueinfo
:
case
TARGET_NR_rt_sigsuspend
:
case
TARGET_NR_pread
:
case
TARGET_NR_pwrite
:
goto
unimplemented
;
...
...
linux-user/syscall_defs.h
浏览文件 @
66fb9763
...
...
@@ -29,6 +29,11 @@ struct target_timespec {
target_long
tv_nsec
;
};
struct
target_itimerval
{
struct
target_timeval
it_interval
;
struct
target_timeval
it_value
;
};
struct
target_iovec
{
target_long
iov_base
;
/* Starting address */
target_long
iov_len
;
/* Number of bytes */
...
...
@@ -113,6 +118,38 @@ typedef struct {
target_ulong
sig
[
TARGET_NSIG_WORDS
];
}
target_sigset_t
;
#ifdef BSWAP_NEEDED
static
inline
void
tswap_sigset
(
target_sigset_t
*
d
,
const
target_sigset_t
*
s
)
{
int
i
;
for
(
i
=
0
;
i
<
TARGET_NSIG_WORDS
;
i
++
)
d
->
sig
[
i
]
=
tswapl
(
s
->
sig
[
i
]);
}
#else
static
inline
void
tswap_sigset
(
target_sigset_t
*
d
,
const
target_sigset_t
*
s
)
{
*
d
=
*
s
;
}
#endif
static
inline
void
target_siginitset
(
target_sigset_t
*
d
,
target_ulong
set
)
{
int
i
;
d
->
sig
[
0
]
=
set
;
for
(
i
=
1
;
i
<
TARGET_NSIG_WORDS
;
i
++
)
d
->
sig
[
i
]
=
0
;
}
void
host_to_target_sigset
(
target_sigset_t
*
d
,
sigset_t
*
s
);
void
target_to_host_sigset
(
sigset_t
*
d
,
target_sigset_t
*
s
);
void
host_to_target_old_sigset
(
target_ulong
*
old_sigset
,
const
sigset_t
*
sigset
);
void
target_to_host_old_sigset
(
sigset_t
*
sigset
,
const
target_ulong
*
old_sigset
);
struct
target_sigaction
;
int
do_sigaction
(
int
sig
,
const
struct
target_sigaction
*
act
,
struct
target_sigaction
*
oact
);
/* Networking ioctls */
#define TARGET_SIOCADDRT 0x890B
/* add routing table entry */
#define TARGET_SIOCDELRT 0x890C
/* delete routing table entry */
...
...
ops_template.h
浏览文件 @
66fb9763
/*
* i386 micro operations (included several times to generate
* different operand sizes)
*
* Copyright (c) 2003 Fabrice Bellard
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define DATA_BITS (1 << (3 + SHIFT))
#define SHIFT_MASK (DATA_BITS - 1)
...
...
syscall-i386.h
浏览文件 @
66fb9763
...
...
@@ -302,20 +302,59 @@ struct target_stat64 {
unsigned
long
long
st_ino
;
};
typedef
unsigned
long
old_sigset_t
;
/* at least 32 bits */
#define TARGET_SA_NOCLDSTOP 0x00000001
#define TARGET_SA_NOCLDWAIT 0x00000002
/* not supported yet */
#define TARGET_SA_SIGINFO 0x00000004
#define TARGET_SA_ONSTACK 0x08000000
#define TARGET_SA_RESTART 0x10000000
#define TARGET_SA_NODEFER 0x40000000
#define TARGET_SA_RESETHAND 0x80000000
#define TARGET_SA_RESTORER 0x04000000
#define TARGET_SIGHUP 1
#define TARGET_SIGINT 2
#define TARGET_SIGQUIT 3
#define TARGET_SIGILL 4
#define TARGET_SIGTRAP 5
#define TARGET_SIGABRT 6
#define TARGET_SIGIOT 6
#define TARGET_SIGBUS 7
#define TARGET_SIGFPE 8
#define TARGET_SIGKILL 9
#define TARGET_SIGUSR1 10
#define TARGET_SIGSEGV 11
#define TARGET_SIGUSR2 12
#define TARGET_SIGPIPE 13
#define TARGET_SIGALRM 14
#define TARGET_SIGTERM 15
#define TARGET_SIGSTKFLT 16
#define TARGET_SIGCHLD 17
#define TARGET_SIGCONT 18
#define TARGET_SIGSTOP 19
#define TARGET_SIGTSTP 20
#define TARGET_SIGTTIN 21
#define TARGET_SIGTTOU 22
#define TARGET_SIGURG 23
#define TARGET_SIGXCPU 24
#define TARGET_SIGXFSZ 25
#define TARGET_SIGVTALRM 26
#define TARGET_SIGPROF 27
#define TARGET_SIGWINCH 28
#define TARGET_SIGIO 29
#define TARGET_SIGRTMIN 32
struct
target_old_sigaction
{
target_ulong
_sa_handler
;
target_ulong
sa_mask
;
target_ulong
sa_flags
;
void
(
*
sa_restorer
)(
void
)
;
target_ulong
sa_restorer
;
};
struct
target_sigaction
{
target_ulong
_sa_handler
;
target_sigset_t
sa_mask
;
target_ulong
sa_flags
;
target_ulong
sa_restorer
;
target_sigset_t
sa_mask
;
};
typedef
union
target_sigval
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录