Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
0ecfa993
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看板
提交
0ecfa993
编写于
3月 03, 2003
作者:
B
bellard
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
prints hello world
git-svn-id:
svn://svn.savannah.nongnu.org/qemu/trunk@17
c046a42c-6fe2-441c-8c8c-71466251a162
上级
ba1c6e37
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
289 addition
and
257 deletion
+289
-257
Makefile
Makefile
+7
-4
cpu-i386.h
cpu-i386.h
+39
-6
linux-user/main.c
linux-user/main.c
+36
-195
op-i386.c
op-i386.c
+71
-32
ops_template.h
ops_template.h
+12
-12
translate-i386.c
translate-i386.c
+124
-8
未找到文件。
Makefile
浏览文件 @
0ecfa993
...
...
@@ -30,16 +30,19 @@ endif
#########################################################
DEFINES
+=
-D_GNU_SOURCE
-DGEMU
-DDOSEMU
-DNO_TRACE_MSGS
DEFINES
+=
-D_GNU_SOURCE
DEFINES
+=
-DCONFIG_PREFIX
=
\"
/usr/local
\"
LDSCRIPT
=
$(ARCH)
.ld
LIBS
+=
-ldl
-lm
OBJS
=
i386/fp87.o i386/interp_main.o i386/interp_modrm.o i386/interp_16_32.o
\
i386/interp_32_16.o i386/interp_32_32.o i386/emu-utils.o
\
i386/dis8086.o i386/emu-ldt.o
#DEFINES+= -DGEMU -DDOSEMU -DNO_TRACE_MSGS
#OBJS= i386/fp87.o i386/interp_main.o i386/interp_modrm.o i386/interp_16_32.o \
# i386/interp_32_16.o i386/interp_32_32.o i386/emu-utils.o \
# i386/dis8086.o i386/emu-ldt.o
OBJS
+=
translate-i386.o op-i386.o
OBJS
+=
elfload.o main.o thunk.o syscall.o
# NOTE: the disassembler code is only needed for debugging
OBJS
+=
i386-dis.o dis-buf.o
SRCS
=
$(OBJS:.o=.c)
all
:
gemu
...
...
cpu-i386.h
浏览文件 @
0ecfa993
/* NOTE: this header is included in op-i386.c where global register
variable are used. Care must be used when including glibc headers.
*/
#ifndef CPU_I386_H
#define CPU_I386_H
#include <setjmp.h>
#define R_EAX 0
#define R_ECX 1
#define R_EDX 2
...
...
@@ -43,6 +48,27 @@
#define VM_FLAG 0x20000
/* AC 0x40000 */
#define EXCP00_DIVZ 1
#define EXCP01_SSTP 2
#define EXCP02_NMI 3
#define EXCP03_INT3 4
#define EXCP04_INTO 5
#define EXCP05_BOUND 6
#define EXCP06_ILLOP 7
#define EXCP07_PREX 8
#define EXCP08_DBLE 9
#define EXCP09_XERR 10
#define EXCP0A_TSS 11
#define EXCP0B_NOSEG 12
#define EXCP0C_STACK 13
#define EXCP0D_GPF 14
#define EXCP0E_PAGE 15
#define EXCP10_COPR 17
#define EXCP11_ALGN 18
#define EXCP12_MCHK 19
#define EXCP_SIGNAL 256
/* async signal */
enum
{
CC_OP_DYNAMIC
,
/* must use dynamic code to get cc_op */
CC_OP_EFLAGS
,
/* all cc are explicitely computed, CC_SRC = flags */
...
...
@@ -89,27 +115,34 @@ typedef struct CPUX86State {
/* standard registers */
uint32_t
regs
[
8
];
uint32_t
pc
;
/* cs_case + eip value */
/* eflags handling */
uint32_t
eflags
;
/* emulator internal eflags handling */
uint32_t
cc_src
;
uint32_t
cc_dst
;
uint32_t
cc_op
;
int32_t
df
;
/* D flag : 1 if D = 0, -1 if D = 1 */
/* segments */
uint8_t
*
segs_base
[
6
];
uint32_t
segs
[
6
];
/* FPU state */
CPU86_LDouble
fpregs
[
8
];
uint8_t
fptags
[
8
];
/* 0 = valid, 1 = empty */
unsigned
int
fpstt
;
/* top of stack index */
unsigned
int
fpus
;
unsigned
int
fpuc
;
uint8_t
fptags
[
8
];
/* 0 = valid, 1 = empty */
CPU86_LDouble
fpregs
[
8
];
/* segments */
uint32_t
segs
[
6
];
/* emulator internal variables */
CPU86_LDouble
ft0
;
/* exception handling */
jmp_buf
jmp_env
;
int
exception_index
;
}
CPUX86State
;
static
inline
int
ldub
(
void
*
ptr
)
...
...
linux-user/main.c
浏览文件 @
0ecfa993
...
...
@@ -21,10 +21,11 @@
#include <stdio.h>
#include <stdarg.h>
#include <errno.h>
#include <unistd.h>
#include "gemu.h"
#include "
i386/hsw_interp
.h"
#include "
cpu-i386
.h"
unsigned
long
x86_stack_size
;
unsigned
long
stktop
;
...
...
@@ -38,160 +39,8 @@ void gemu_log(const char *fmt, ...)
va_end
(
ap
);
}
/* virtual x86 CPU stuff */
extern
int
invoke_code16
(
Interp_ENV
*
,
int
,
int
);
extern
int
invoke_code32
(
Interp_ENV
*
,
int
);
extern
char
*
e_print_cpuemu_regs
(
ENVPARAMS
,
int
is32
);
extern
char
*
e_emu_disasm
(
ENVPARAMS
,
unsigned
char
*
org
,
int
is32
);
extern
void
init_npu
(
void
);
Interp_ENV
env_global
;
Interp_ENV
*
envp_global
;
QWORD
EMUtime
=
0
;
int
CEmuStat
=
0
;
long
instr_count
;
/* who will initialize this? */
unsigned
long
io_bitmap
[
IO_BITMAP_SIZE
+
1
];
/* debug flag, 0=disable 1..9=level */
int
d_emu
=
0
;
unsigned
long
CRs
[
5
]
=
{
0x00000013
,
/* valid bits: 0xe005003f */
0x00000000
,
/* invalid */
0x00000000
,
0x00000000
,
0x00000000
};
/*
* DR0-3 = linear address of breakpoint 0-3
* DR4=5 = reserved
* DR6 b0-b3 = BP active
* b13 = BD
* b14 = BS
* b15 = BT
* DR7 b0-b1 = G:L bp#0
* b2-b3 = G:L bp#1
* b4-b5 = G:L bp#2
* b6-b7 = G:L bp#3
* b8-b9 = GE:LE
* b13 = GD
* b16-19= LLRW bp#0 LL=00(1),01(2),11(4)
* b20-23= LLRW bp#1 RW=00(x),01(w),11(rw)
* b24-27= LLRW bp#2
* b28-31= LLRW bp#3
*/
unsigned
long
DRs
[
8
]
=
{
0x00000000
,
0x00000000
,
0x00000000
,
0x00000000
,
0xffff1ff0
,
0x00000400
,
0xffff1ff0
,
0x00000400
};
unsigned
long
TRs
[
2
]
=
{
0x00000000
,
0x00000000
};
void
FatalAppExit
(
UINT
wAction
,
LPCSTR
lpText
)
{
fprintf
(
stderr
,
"Fatal error '%s' in CPU
\n
"
,
lpText
);
exit
(
1
);
}
int
e_debug_check
(
unsigned
char
*
PC
)
{
register
unsigned
long
d7
=
DRs
[
7
];
if
(
d7
&
0x03
)
{
if
(
d7
&
0x30000
)
return
0
;
/* only execute(00) bkp */
if
((
long
)
PC
==
DRs
[
0
])
{
e_printf
(
"DBRK: DR0 hit at %p
\n
"
,
PC
);
DRs
[
6
]
|=
1
;
return
1
;
}
}
if
(
d7
&
0x0c
)
{
if
(
d7
&
0x300000
)
return
0
;
if
((
long
)
PC
==
DRs
[
1
])
{
e_printf
(
"DBRK: DR1 hit at %p
\n
"
,
PC
);
DRs
[
6
]
|=
2
;
return
1
;
}
}
if
(
d7
&
0x30
)
{
if
(
d7
&
0x3000000
)
return
0
;
if
((
long
)
PC
==
DRs
[
2
])
{
e_printf
(
"DBRK: DR2 hit at %p
\n
"
,
PC
);
DRs
[
6
]
|=
4
;
return
1
;
}
}
if
(
d7
&
0xc0
)
{
if
(
d7
&
0x30000000
)
return
0
;
if
((
long
)
PC
==
DRs
[
3
])
{
e_printf
(
"DBRK: DR3 hit at %p
\n
"
,
PC
);
DRs
[
6
]
|=
8
;
return
1
;
}
}
return
0
;
}
/* Debug stuff */
void
logstr
(
unsigned
long
mask
,
const
char
*
fmt
,...)
{
va_list
ap
;
va_start
(
ap
,
fmt
);
vfprintf
(
stderr
,
fmt
,
ap
);
va_end
(
ap
);
}
/* unconditional message into debug log and stderr */
#undef error
void
error
(
const
char
*
fmt
,
...)
{
va_list
ap
;
va_start
(
ap
,
fmt
);
vfprintf
(
stderr
,
fmt
,
ap
);
va_end
(
ap
);
exit
(
1
);
}
int
PortIO
(
DWORD
port
,
DWORD
value
,
UINT
size
,
BOOL
is_write
)
{
fprintf
(
stderr
,
"IO: %s port=0x%lx value=0x%lx size=%d"
,
is_write
?
"write"
:
"read"
,
port
,
value
,
size
);
return
value
;
}
void
LogProcName
(
WORD
wSel
,
WORD
wOff
,
WORD
wAction
)
{
}
void
INT_handler
(
int
num
,
void
*
env
)
{
fprintf
(
stderr
,
"EM86: int %d
\n
"
,
num
);
}
/***********************************************************/
/*
new CPU cor
e */
/*
CPUX86 core interfac
e */
void
cpu_x86_outb
(
int
addr
,
int
val
)
{
...
...
@@ -245,7 +94,7 @@ int main(int argc, char **argv)
const
char
*
filename
;
struct
target_pt_regs
regs1
,
*
regs
=
&
regs1
;
struct
image_info
info1
,
*
info
=
&
info1
;
Interp_ENV
*
env
;
CPUX86State
*
env
;
if
(
argc
<=
1
)
usage
();
...
...
@@ -277,26 +126,25 @@ int main(int argc, char **argv)
target_set_brk
((
char
*
)
info
->
brk
);
syscall_init
();
env
=
&
env_global
;
envp_global
=
env
;
memset
(
env
,
0
,
sizeof
(
Interp_ENV
));
env
->
rax
.
e
=
regs
->
eax
;
env
->
rbx
.
e
=
regs
->
ebx
;
env
->
rcx
.
e
=
regs
->
ecx
;
env
->
rdx
.
e
=
regs
->
edx
;
env
->
rsi
.
esi
=
regs
->
esi
;
env
->
rdi
.
edi
=
regs
->
edi
;
env
->
rbp
.
ebp
=
regs
->
ebp
;
env
->
rsp
.
esp
=
regs
->
esp
;
env
->
cs
.
cs
=
__USER_CS
;
env
->
ds
.
ds
=
__USER_DS
;
env
->
es
.
es
=
__USER_DS
;
env
->
ss
.
ss
=
__USER_DS
;
env
->
fs
.
fs
=
__USER_DS
;
env
->
gs
.
gs
=
__USER_DS
;
env
->
trans_addr
=
regs
->
eip
;
env
=
cpu_x86_init
();
env
->
regs
[
R_EAX
]
=
regs
->
eax
;
env
->
regs
[
R_EBX
]
=
regs
->
ebx
;
env
->
regs
[
R_ECX
]
=
regs
->
ecx
;
env
->
regs
[
R_EDX
]
=
regs
->
edx
;
env
->
regs
[
R_ESI
]
=
regs
->
esi
;
env
->
regs
[
R_EDI
]
=
regs
->
edi
;
env
->
regs
[
R_EBP
]
=
regs
->
ebp
;
env
->
regs
[
R_ESP
]
=
regs
->
esp
;
env
->
segs
[
R_CS
]
=
__USER_CS
;
env
->
segs
[
R_DS
]
=
__USER_DS
;
env
->
segs
[
R_ES
]
=
__USER_DS
;
env
->
segs
[
R_SS
]
=
__USER_DS
;
env
->
segs
[
R_FS
]
=
__USER_DS
;
env
->
segs
[
R_GS
]
=
__USER_DS
;
env
->
pc
=
regs
->
eip
;
#if 0
LDT[__USER_CS >> 3].w86Flags = DF_PRESENT | DF_PAGES | DF_32;
LDT[__USER_CS >> 3].dwSelLimit = 0xfffff;
LDT[__USER_CS >> 3].lpSelBase = NULL;
...
...
@@ -304,41 +152,34 @@ int main(int argc, char **argv)
LDT[__USER_DS >> 3].w86Flags = DF_PRESENT | DF_PAGES | DF_32;
LDT[__USER_DS >> 3].dwSelLimit = 0xfffff;
LDT[__USER_DS >> 3].lpSelBase = NULL;
init_npu
();
build_decode_tables
();
#endif
for
(;;)
{
int
err
;
uint8_t
*
pc
;
err
=
invoke_code32
(
env
,
-
1
);
env
->
trans_addr
=
env
->
return_addr
;
pc
=
env
->
seg_regs
[
0
]
+
env
->
trans_addr
;
err
=
cpu_x86_exec
(
env
);
switch
(
err
)
{
case
EXCP0D_GPF
:
pc
=
(
uint8_t
*
)
env
->
pc
;
if
(
pc
[
0
]
==
0xcd
&&
pc
[
1
]
==
0x80
)
{
/* syscall */
env
->
trans_addr
+=
2
;
env
->
r
ax
.
e
=
do_syscall
(
env
->
rax
.
e
,
env
->
rbx
.
e
,
env
->
rcx
.
e
,
env
->
rdx
.
e
,
env
->
rsi
.
esi
,
env
->
rdi
.
edi
,
env
->
rbp
.
ebp
);
env
->
pc
+=
2
;
env
->
r
egs
[
R_EAX
]
=
do_syscall
(
env
->
regs
[
R_EAX
]
,
env
->
regs
[
R_EBX
]
,
env
->
regs
[
R_ECX
]
,
env
->
regs
[
R_EDX
]
,
env
->
regs
[
R_ESI
]
,
env
->
regs
[
R_EDI
]
,
env
->
regs
[
R_EBP
]
);
}
else
{
goto
trap_error
;
}
break
;
default:
trap_error:
fprintf
(
stderr
,
"GEMU: Unknown error %d, aborting
\n
"
,
err
);
#ifndef NO_TRACE_MSGS
d_emu
=
9
;
fprintf
(
stderr
,
"%s
\n
%s
\n
"
,
e_print_cpuemu_regs
(
env
,
1
),
e_emu_disasm
(
env
,
pc
,
1
));
#endif
fprintf
(
stderr
,
"0x%08lx: Unknown exception %d, aborting
\n
"
,
(
long
)
env
->
pc
,
err
);
abort
();
}
}
...
...
op-i386.c
浏览文件 @
0ecfa993
...
...
@@ -10,11 +10,6 @@ typedef signed long long int64_t;
#define NULL 0
typedef
struct
FILE
FILE
;
extern
FILE
*
stderr
;
extern
int
fprintf
(
FILE
*
,
const
char
*
,
...);
#ifdef __i386__
register
int
T0
asm
(
"esi"
);
register
int
T1
asm
(
"ebx"
);
...
...
@@ -91,6 +86,7 @@ typedef struct CCTable {
int
(
*
compute_c
)(
void
);
/* return the C flag */
}
CCTable
;
/* NOTE: data are not static to force relocation generation by GCC */
extern
CCTable
cc_table
[];
uint8_t
parity_table
[
256
]
=
{
...
...
@@ -191,6 +187,14 @@ static inline int lshift(int x, int n)
return
x
>>
(
-
n
);
}
/* exception support */
/* NOTE: not static to force relocation generation by GCC */
void
raise_exception
(
int
exception_index
)
{
env
->
exception_index
=
exception_index
;
longjmp
(
env
->
jmp_env
,
1
);
}
/* we define the various pieces of code used by the JIT */
#define REG EAX
...
...
@@ -321,7 +325,6 @@ void OPPROTO op_decl_T0_cc(void)
void
OPPROTO
op_testl_T0_T1_cc
(
void
)
{
CC_SRC
=
T0
;
CC_DST
=
T0
&
T1
;
}
...
...
@@ -555,6 +558,7 @@ void OPPROTO op_stl_T0_A0(void)
/* jumps */
/* indirect jump */
void
OPPROTO
op_jmp_T0
(
void
)
{
PC
=
T0
;
...
...
@@ -565,6 +569,30 @@ void OPPROTO op_jmp_im(void)
PC
=
PARAM1
;
}
void
OPPROTO
op_int_im
(
void
)
{
PC
=
PARAM1
;
raise_exception
(
EXCP0D_GPF
);
}
void
OPPROTO
op_int3
(
void
)
{
PC
=
PARAM1
;
raise_exception
(
EXCP03_INT3
);
}
void
OPPROTO
op_into
(
void
)
{
int
eflags
;
eflags
=
cc_table
[
CC_OP
].
compute_all
();
if
(
eflags
&
CC_O
)
{
PC
=
PARAM1
;
raise_exception
(
EXCP04_INTO
);
}
else
{
PC
=
PARAM2
;
}
}
/* string ops */
#define ldul ldl
...
...
@@ -663,17 +691,19 @@ void OPPROTO op_jo_cc(void)
int
eflags
;
eflags
=
cc_table
[
CC_OP
].
compute_all
();
if
(
eflags
&
CC_O
)
PC
+
=
PARAM1
;
PC
=
PARAM1
;
else
PC
+=
PARAM2
;
PC
=
PARAM2
;
FORCE_RET
();
}
void
OPPROTO
op_jb_cc
(
void
)
{
if
(
cc_table
[
CC_OP
].
compute_c
())
PC
+
=
PARAM1
;
PC
=
PARAM1
;
else
PC
+=
PARAM2
;
PC
=
PARAM2
;
FORCE_RET
();
}
void
OPPROTO
op_jz_cc
(
void
)
...
...
@@ -681,9 +711,10 @@ void OPPROTO op_jz_cc(void)
int
eflags
;
eflags
=
cc_table
[
CC_OP
].
compute_all
();
if
(
eflags
&
CC_Z
)
PC
+
=
PARAM1
;
PC
=
PARAM1
;
else
PC
+=
PARAM2
;
PC
=
PARAM2
;
FORCE_RET
();
}
void
OPPROTO
op_jbe_cc
(
void
)
...
...
@@ -691,9 +722,10 @@ void OPPROTO op_jbe_cc(void)
int
eflags
;
eflags
=
cc_table
[
CC_OP
].
compute_all
();
if
(
eflags
&
(
CC_Z
|
CC_C
))
PC
+
=
PARAM1
;
PC
=
PARAM1
;
else
PC
+=
PARAM2
;
PC
=
PARAM2
;
FORCE_RET
();
}
void
OPPROTO
op_js_cc
(
void
)
...
...
@@ -701,9 +733,10 @@ void OPPROTO op_js_cc(void)
int
eflags
;
eflags
=
cc_table
[
CC_OP
].
compute_all
();
if
(
eflags
&
CC_S
)
PC
+
=
PARAM1
;
PC
=
PARAM1
;
else
PC
+=
PARAM2
;
PC
=
PARAM2
;
FORCE_RET
();
}
void
OPPROTO
op_jp_cc
(
void
)
...
...
@@ -711,9 +744,10 @@ void OPPROTO op_jp_cc(void)
int
eflags
;
eflags
=
cc_table
[
CC_OP
].
compute_all
();
if
(
eflags
&
CC_P
)
PC
+
=
PARAM1
;
PC
=
PARAM1
;
else
PC
+=
PARAM2
;
PC
=
PARAM2
;
FORCE_RET
();
}
void
OPPROTO
op_jl_cc
(
void
)
...
...
@@ -721,9 +755,10 @@ void OPPROTO op_jl_cc(void)
int
eflags
;
eflags
=
cc_table
[
CC_OP
].
compute_all
();
if
((
eflags
^
(
eflags
>>
4
))
&
0x80
)
PC
+
=
PARAM1
;
PC
=
PARAM1
;
else
PC
+=
PARAM2
;
PC
=
PARAM2
;
FORCE_RET
();
}
void
OPPROTO
op_jle_cc
(
void
)
...
...
@@ -731,9 +766,10 @@ void OPPROTO op_jle_cc(void)
int
eflags
;
eflags
=
cc_table
[
CC_OP
].
compute_all
();
if
(((
eflags
^
(
eflags
>>
4
))
&
0x80
)
||
(
eflags
&
CC_Z
))
PC
+
=
PARAM1
;
PC
=
PARAM1
;
else
PC
+=
PARAM2
;
PC
=
PARAM2
;
FORCE_RET
();
}
/* slow set cases (compute x86 flags) */
...
...
@@ -1600,14 +1636,13 @@ void OPPROTO op_fcos(void)
/* main execution loop */
uint8_t
code_gen_buffer
[
65536
];
int
cpu_x86_exec
(
CPUX86State
*
env1
)
{
int
saved_T0
,
saved_T1
,
saved_A0
;
CPUX86State
*
saved_env
;
int
code_gen_size
;
int
code_gen_size
,
ret
;
void
(
*
gen_func
)(
void
);
/* first we save global registers */
saved_T0
=
T0
;
saved_T1
=
T1
;
...
...
@@ -1615,17 +1650,21 @@ int cpu_x86_exec(CPUX86State *env1)
saved_env
=
env
;
env
=
env1
;
for
(;;)
{
cpu_x86_gen_code
(
code_gen_buffer
,
&
code_gen_size
,
(
uint8_t
*
)
env
->
pc
);
/* execute the generated code */
gen_func
=
(
void
*
)
code_gen_buffer
;
gen_func
();
/* prepare setjmp context for exception handling */
if
(
setjmp
(
env
->
jmp_env
)
==
0
)
{
for
(;;)
{
cpu_x86_gen_code
(
code_gen_buffer
,
&
code_gen_size
,
(
uint8_t
*
)
env
->
pc
);
/* execute the generated code */
gen_func
=
(
void
*
)
code_gen_buffer
;
gen_func
();
}
}
ret
=
env
->
exception_index
;
/* restore global registers */
T0
=
saved_T0
;
T1
=
saved_T1
;
A0
=
saved_A0
;
env
=
saved_env
;
return
0
;
return
ret
;
}
ops_template.h
浏览文件 @
0ecfa993
...
...
@@ -149,18 +149,18 @@ void OPPROTO glue(op_jb_sub, SUFFIX)(void)
src2
=
CC_SRC
-
CC_DST
;
if
((
DATA_TYPE
)
src1
<
(
DATA_TYPE
)
src2
)
PC
+
=
PARAM1
;
PC
=
PARAM1
;
else
PC
+
=
PARAM2
;
PC
=
PARAM2
;
FORCE_RET
();
}
void
OPPROTO
glue
(
op_jz_sub
,
SUFFIX
)(
void
)
{
if
((
DATA_TYPE
)
CC_DST
!=
0
)
PC
+
=
PARAM1
;
PC
=
PARAM1
;
else
PC
+
=
PARAM2
;
PC
=
PARAM2
;
FORCE_RET
();
}
...
...
@@ -171,18 +171,18 @@ void OPPROTO glue(op_jbe_sub, SUFFIX)(void)
src2
=
CC_SRC
-
CC_DST
;
if
((
DATA_TYPE
)
src1
<=
(
DATA_TYPE
)
src2
)
PC
+
=
PARAM1
;
PC
=
PARAM1
;
else
PC
+
=
PARAM2
;
PC
=
PARAM2
;
FORCE_RET
();
}
void
OPPROTO
glue
(
op_js_sub
,
SUFFIX
)(
void
)
{
if
(
CC_DST
&
SIGN_MASK
)
PC
+
=
PARAM1
;
PC
=
PARAM1
;
else
PC
+
=
PARAM2
;
PC
=
PARAM2
;
FORCE_RET
();
}
...
...
@@ -193,9 +193,9 @@ void OPPROTO glue(op_jl_sub, SUFFIX)(void)
src2
=
CC_SRC
-
CC_DST
;
if
((
DATA_STYPE
)
src1
<
(
DATA_STYPE
)
src2
)
PC
+
=
PARAM1
;
PC
=
PARAM1
;
else
PC
+
=
PARAM2
;
PC
=
PARAM2
;
FORCE_RET
();
}
...
...
@@ -206,9 +206,9 @@ void OPPROTO glue(op_jle_sub, SUFFIX)(void)
src2
=
CC_SRC
-
CC_DST
;
if
((
DATA_STYPE
)
src1
<=
(
DATA_STYPE
)
src2
)
PC
+
=
PARAM1
;
PC
=
PARAM1
;
else
PC
+
=
PARAM2
;
PC
=
PARAM2
;
FORCE_RET
();
}
...
...
translate-i386.c
浏览文件 @
0ecfa993
...
...
@@ -5,12 +5,24 @@
#include <inttypes.h>
#include <assert.h>
/* dump all code */
#define DEBUG_DISAS
#define DEBUG_LOGFILE "/tmp/gemu.log"
#ifdef DEBUG_DISAS
#include "dis-asm.h"
#endif
#define IN_OP_I386
#include "cpu-i386.h"
static
uint8_t
*
gen_code_ptr
;
int
__op_param1
,
__op_param2
,
__op_param3
;
#ifdef DEBUG_DISAS
static
FILE
*
logfile
=
NULL
;
#endif
/* supress that */
static
void
error
(
const
char
*
fmt
,
...)
{
...
...
@@ -704,6 +716,9 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_
int
reg1
,
reg2
,
opreg
;
int
mod
,
rm
,
code
;
#ifdef DEBUG_DISAS
fprintf
(
logfile
,
"modrm=0x%x
\n
"
,
modrm
);
#endif
mod
=
(
modrm
>>
6
)
&
3
;
rm
=
modrm
&
7
;
...
...
@@ -716,6 +731,9 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_
if
(
base
==
4
)
{
havesib
=
1
;
code
=
ldub
(
s
->
pc
++
);
#ifdef DEBUG_DISAS
fprintf
(
logfile
,
"sib=0x%x
\n
"
,
code
);
#endif
scale
=
(
code
>>
6
)
&
3
;
index
=
(
code
>>
3
)
&
7
;
base
=
code
&
7
;
...
...
@@ -762,6 +780,7 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_
}
else
if
(
scale
==
0
&&
disp
==
0
)
{
gen_op_movl_A0_reg
[
reg1
]();
}
else
{
gen_op_movl_A0_im
(
disp
);
gen_op_addl_A0_reg_sN
[
scale
][
reg1
]();
}
}
else
{
...
...
@@ -953,8 +972,10 @@ static void gen_setcc(DisasContext *s, int b)
}
}
/* return the size of the intruction. Return -1 if no insn found */
int
disas_insn
(
DisasContext
*
s
,
uint8_t
*
pc_start
)
/* return the next pc address. Return -1 if no insn found. *is_jmp_ptr
is set to true if the instruction sets the PC (last instruction of
a basic block) */
long
disas_insn
(
DisasContext
*
s
,
uint8_t
*
pc_start
,
int
*
is_jmp_ptr
)
{
int
b
,
prefixes
,
aflag
,
dflag
;
int
shift
,
ot
;
...
...
@@ -967,6 +988,9 @@ int disas_insn(DisasContext *s, uint8_t *pc_start)
// cur_pc = s->pc; /* for insn generation */
next_byte:
b
=
ldub
(
s
->
pc
);
#ifdef DEBUG_DISAS
fprintf
(
logfile
,
"ib=0x%02x
\n
"
,
b
);
#endif
if
(
b
<
0
)
return
-
1
;
s
->
pc
++
;
...
...
@@ -1195,6 +1219,7 @@ int disas_insn(DisasContext *s, uint8_t *pc_start)
gen_op_mull_EAX_T0
();
break
;
}
s
->
cc_op
=
CC_OP_MUL
;
break
;
case
5
:
/* imul */
switch
(
ot
)
{
...
...
@@ -1209,6 +1234,7 @@ int disas_insn(DisasContext *s, uint8_t *pc_start)
gen_op_imull_EAX_T0
();
break
;
}
s
->
cc_op
=
CC_OP_MUL
;
break
;
case
6
:
/* div */
switch
(
ot
)
{
...
...
@@ -1281,9 +1307,11 @@ int disas_insn(DisasContext *s, uint8_t *pc_start)
gen_op_movl_T1_im
((
long
)
s
->
pc
);
gen_op_pushl_T1
();
gen_op_jmp_T0
();
*
is_jmp_ptr
=
1
;
break
;
case
4
:
/* jmp Ev */
gen_op_jmp_T0
();
*
is_jmp_ptr
=
1
;
break
;
case
6
:
/* push Ev */
gen_op_pushl_T0
();
...
...
@@ -1362,6 +1390,7 @@ int disas_insn(DisasContext *s, uint8_t *pc_start)
op_imulw_T0_T1
();
}
gen_op_mov_reg_T0
[
ot
][
reg
]();
s
->
cc_op
=
CC_OP_MUL
;
break
;
/**************************/
...
...
@@ -1418,10 +1447,14 @@ int disas_insn(DisasContext *s, uint8_t *pc_start)
ot
=
dflag
?
OT_LONG
:
OT_WORD
;
modrm
=
ldub
(
s
->
pc
++
);
mod
=
(
modrm
>>
6
)
&
3
;
if
(
mod
!=
3
)
gen_lea_modrm
(
s
,
modrm
,
&
reg_addr
,
&
offset_addr
);
val
=
insn_get
(
s
,
ot
);
gen_op_movl_T0_im
(
val
);
gen_ldst_modrm
(
s
,
modrm
,
ot
,
OR_TMP0
,
1
);
if
(
mod
!=
3
)
gen_op_st_T0_A0
[
ot
]();
else
gen_op_mov_reg_T0
[
ot
][
modrm
&
7
]();
break
;
case
0x8a
:
case
0x8b
:
/* mov Ev, Gv */
...
...
@@ -2068,10 +2101,12 @@ int disas_insn(DisasContext *s, uint8_t *pc_start)
gen_op_popl_T0
();
gen_op_addl_ESP_im
(
val
);
gen_op_jmp_T0
();
*
is_jmp_ptr
=
1
;
break
;
case
0xc3
:
/* ret */
gen_op_popl_T0
();
gen_op_jmp_T0
();
*
is_jmp_ptr
=
1
;
break
;
case
0xe8
:
/* call */
val
=
insn_get
(
s
,
OT_LONG
);
...
...
@@ -2079,16 +2114,19 @@ int disas_insn(DisasContext *s, uint8_t *pc_start)
gen_op_movl_T1_im
((
long
)
s
->
pc
);
gen_op_pushl_T1
();
gen_op_jmp_im
(
val
);
*
is_jmp_ptr
=
1
;
break
;
case
0xe9
:
/* jmp */
val
=
insn_get
(
s
,
OT_LONG
);
val
+=
(
long
)
s
->
pc
;
gen_op_jmp_im
(
val
);
*
is_jmp_ptr
=
1
;
break
;
case
0xeb
:
/* jmp Jb */
val
=
(
int8_t
)
insn_get
(
s
,
OT_BYTE
);
val
+=
(
long
)
s
->
pc
;
gen_op_jmp_im
(
val
);
*
is_jmp_ptr
=
1
;
break
;
case
0x70
...
0x7f
:
/* jcc Jb */
val
=
(
int8_t
)
insn_get
(
s
,
OT_BYTE
);
...
...
@@ -2103,6 +2141,7 @@ int disas_insn(DisasContext *s, uint8_t *pc_start)
val
+=
(
long
)
s
->
pc
;
/* XXX: fix 16 bit wrap */
do_jcc:
gen_jcc
(
s
,
b
,
val
);
*
is_jmp_ptr
=
1
;
break
;
case
0x190
...
0x19f
:
...
...
@@ -2164,8 +2203,23 @@ int disas_insn(DisasContext *s, uint8_t *pc_start)
/* misc */
case
0x90
:
/* nop */
break
;
#if 0
case
0xcc
:
/* int3 */
gen_op_int3
((
long
)
pc_start
);
*
is_jmp_ptr
=
1
;
break
;
case
0xcd
:
/* int N */
val
=
ldub
(
s
->
pc
++
);
/* XXX: currently we ignore the interrupt number */
gen_op_int_im
((
long
)
pc_start
);
*
is_jmp_ptr
=
1
;
break
;
case
0xce
:
/* into */
if
(
s
->
cc_op
!=
CC_OP_DYNAMIC
)
gen_op_set_cc_op
(
s
->
cc_op
);
gen_op_into
((
long
)
pc_start
,
(
long
)
s
->
pc
);
*
is_jmp_ptr
=
1
;
break
;
#if 0
case 0x1a2: /* cpuid */
gen_insn0(OP_ASM);
break;
...
...
@@ -2182,16 +2236,78 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int *gen_code_size_ptr,
uint8_t
*
pc_start
)
{
DisasContext
dc1
,
*
dc
=
&
dc1
;
int
is_jmp
;
long
ret
;
#ifdef DEBUG_DISAS
struct
disassemble_info
disasm_info
;
#endif
dc
->
cc_op
=
CC_OP_DYNAMIC
;
gen_code_ptr
=
gen_code_buf
;
gen_start
();
ret
=
disas_insn
(
dc
,
pc_start
);
#ifdef DEBUG_DISAS
if
(
!
logfile
)
{
logfile
=
fopen
(
DEBUG_LOGFILE
,
"w"
);
if
(
!
logfile
)
{
perror
(
DEBUG_LOGFILE
);
exit
(
1
);
}
setvbuf
(
logfile
,
NULL
,
_IOLBF
,
0
);
}
INIT_DISASSEMBLE_INFO
(
disasm_info
,
logfile
,
fprintf
);
disasm_info
.
buffer
=
pc_start
;
disasm_info
.
buffer_vma
=
(
unsigned
long
)
pc_start
;
disasm_info
.
buffer_length
=
15
;
#if 0
disasm_info.flavour = bfd_get_flavour (abfd);
disasm_info.arch = bfd_get_arch (abfd);
disasm_info.mach = bfd_get_mach (abfd);
#endif
#ifdef WORDS_BIGENDIAN
disasm_info
.
endian
=
BFD_ENDIAN_BIG
;
#else
disasm_info
.
endian
=
BFD_ENDIAN_LITTLE
;
#endif
fprintf
(
logfile
,
"IN:
\n
"
);
fprintf
(
logfile
,
"0x%08lx: "
,
(
long
)
pc_start
);
print_insn_i386
((
unsigned
long
)
pc_start
,
&
disasm_info
);
fprintf
(
logfile
,
"
\n\n
"
);
#endif
is_jmp
=
0
;
ret
=
disas_insn
(
dc
,
pc_start
,
&
is_jmp
);
if
(
ret
==
-
1
)
error
(
"unknown instruction at PC=0x%x"
,
pc_start
);
/* we must store the eflags state if it is not already done */
if
(
dc
->
cc_op
!=
CC_OP_DYNAMIC
)
gen_op_set_cc_op
(
dc
->
cc_op
);
if
(
!
is_jmp
)
{
/* we add an additionnal jmp to update the simulated PC */
gen_op_jmp_im
(
ret
);
}
gen_end
();
*
gen_code_size_ptr
=
gen_code_ptr
-
gen_code_buf
;
printf
(
"0x%08lx: code_size = %d
\n
"
,
(
long
)
pc_start
,
*
gen_code_size_ptr
);
#ifdef DEBUG_DISAS
{
uint8_t
*
pc
;
int
count
;
pc
=
gen_code_buf
;
disasm_info
.
buffer
=
pc
;
disasm_info
.
buffer_vma
=
(
unsigned
long
)
pc
;
disasm_info
.
buffer_length
=
*
gen_code_size_ptr
;
fprintf
(
logfile
,
"OUT: [size=%d]
\n
"
,
*
gen_code_size_ptr
);
while
(
pc
<
gen_code_ptr
)
{
fprintf
(
logfile
,
"0x%08lx: "
,
(
long
)
pc
);
count
=
print_insn_i386
((
unsigned
long
)
pc
,
&
disasm_info
);
fprintf
(
logfile
,
"
\n
"
);
pc
+=
count
;
}
fprintf
(
logfile
,
"
\n
"
);
}
#endif
return
0
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录