Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Sign in / Register
Toggle navigation
Q
qemu
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
PureOS
Packages
qemu
Commits
c27004ec
Commit
c27004ec
authored
Jan 03, 2005
by
bellard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
64 bit target support
git-svn-id:
svn://svn.savannah.nongnu.org/qemu/trunk@1189
c046a42c-6fe2-441c-8c8c-71466251a162
parent
612458f5
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
309 additions
and
204 deletions
+309
-204
cpu-all.h
cpu-all.h
+74
-56
cpu-defs.h
cpu-defs.h
+2
-0
cpu-exec.c
cpu-exec.c
+32
-29
dis-asm.h
dis-asm.h
+3
-0
disas.c
disas.c
+86
-57
disas.h
disas.h
+3
-2
exec-all.h
exec-all.h
+29
-10
exec.c
exec.c
+24
-18
monitor.c
monitor.c
+1
-1
softmmu_header.h
softmmu_header.h
+23
-19
softmmu_template.h
softmmu_template.h
+16
-12
vl.h
vl.h
+16
-0
No files found.
cpu-all.h
View file @
c27004ec
...
...
@@ -166,17 +166,17 @@ typedef union {
* user : user mode access using soft MMU
* kernel : kernel mode access using soft MMU
*/
static
inline
int
ldub_
raw
(
void
*
ptr
)
static
inline
int
ldub_
p
(
void
*
ptr
)
{
return
*
(
uint8_t
*
)
ptr
;
}
static
inline
int
ldsb_
raw
(
void
*
ptr
)
static
inline
int
ldsb_
p
(
void
*
ptr
)
{
return
*
(
int8_t
*
)
ptr
;
}
static
inline
void
stb_
raw
(
void
*
ptr
,
int
v
)
static
inline
void
stb_
p
(
void
*
ptr
,
int
v
)
{
*
(
uint8_t
*
)
ptr
=
v
;
}
...
...
@@ -187,7 +187,7 @@ static inline void stb_raw(void *ptr, int v)
#if !defined(TARGET_WORDS_BIGENDIAN) && (defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED))
/* conservative code for little endian unaligned accesses */
static
inline
int
lduw_
raw
(
void
*
ptr
)
static
inline
int
lduw_
p
(
void
*
ptr
)
{
#ifdef __powerpc__
int
val
;
...
...
@@ -199,7 +199,7 @@ static inline int lduw_raw(void *ptr)
#endif
}
static
inline
int
ldsw_
raw
(
void
*
ptr
)
static
inline
int
ldsw_
p
(
void
*
ptr
)
{
#ifdef __powerpc__
int
val
;
...
...
@@ -211,7 +211,7 @@ static inline int ldsw_raw(void *ptr)
#endif
}
static
inline
int
ldl_
raw
(
void
*
ptr
)
static
inline
int
ldl_
p
(
void
*
ptr
)
{
#ifdef __powerpc__
int
val
;
...
...
@@ -223,16 +223,16 @@ static inline int ldl_raw(void *ptr)
#endif
}
static
inline
uint64_t
ldq_
raw
(
void
*
ptr
)
static
inline
uint64_t
ldq_
p
(
void
*
ptr
)
{
uint8_t
*
p
=
ptr
;
uint32_t
v1
,
v2
;
v1
=
ldl_
raw
(
p
);
v2
=
ldl_
raw
(
p
+
4
);
v1
=
ldl_
p
(
p
);
v2
=
ldl_
p
(
p
+
4
);
return
v1
|
((
uint64_t
)
v2
<<
32
);
}
static
inline
void
stw_
raw
(
void
*
ptr
,
int
v
)
static
inline
void
stw_
p
(
void
*
ptr
,
int
v
)
{
#ifdef __powerpc__
__asm__
__volatile__
(
"sthbrx %1,0,%2"
:
"=m"
(
*
(
uint16_t
*
)
ptr
)
:
"r"
(
v
),
"r"
(
ptr
));
...
...
@@ -243,7 +243,7 @@ static inline void stw_raw(void *ptr, int v)
#endif
}
static
inline
void
stl_
raw
(
void
*
ptr
,
int
v
)
static
inline
void
stl_
p
(
void
*
ptr
,
int
v
)
{
#ifdef __powerpc__
__asm__
__volatile__
(
"stwbrx %1,0,%2"
:
"=m"
(
*
(
uint32_t
*
)
ptr
)
:
"r"
(
v
),
"r"
(
ptr
));
...
...
@@ -256,54 +256,54 @@ static inline void stl_raw(void *ptr, int v)
#endif
}
static
inline
void
stq_
raw
(
void
*
ptr
,
uint64_t
v
)
static
inline
void
stq_
p
(
void
*
ptr
,
uint64_t
v
)
{
uint8_t
*
p
=
ptr
;
stl_
raw
(
p
,
(
uint32_t
)
v
);
stl_
raw
(
p
+
4
,
v
>>
32
);
stl_
p
(
p
,
(
uint32_t
)
v
);
stl_
p
(
p
+
4
,
v
>>
32
);
}
/* float access */
static
inline
float
ldfl_
raw
(
void
*
ptr
)
static
inline
float
ldfl_
p
(
void
*
ptr
)
{
union
{
float
f
;
uint32_t
i
;
}
u
;
u
.
i
=
ldl_
raw
(
ptr
);
u
.
i
=
ldl_
p
(
ptr
);
return
u
.
f
;
}
static
inline
void
stfl_
raw
(
void
*
ptr
,
float
v
)
static
inline
void
stfl_
p
(
void
*
ptr
,
float
v
)
{
union
{
float
f
;
uint32_t
i
;
}
u
;
u
.
f
=
v
;
stl_
raw
(
ptr
,
u
.
i
);
stl_
p
(
ptr
,
u
.
i
);
}
static
inline
double
ldfq_
raw
(
void
*
ptr
)
static
inline
double
ldfq_
p
(
void
*
ptr
)
{
CPU_DoubleU
u
;
u
.
l
.
lower
=
ldl_
raw
(
ptr
);
u
.
l
.
upper
=
ldl_
raw
(
ptr
+
4
);
u
.
l
.
lower
=
ldl_
p
(
ptr
);
u
.
l
.
upper
=
ldl_
p
(
ptr
+
4
);
return
u
.
d
;
}
static
inline
void
stfq_
raw
(
void
*
ptr
,
double
v
)
static
inline
void
stfq_
p
(
void
*
ptr
,
double
v
)
{
CPU_DoubleU
u
;
u
.
d
=
v
;
stl_
raw
(
ptr
,
u
.
l
.
lower
);
stl_
raw
(
ptr
+
4
,
u
.
l
.
upper
);
stl_
p
(
ptr
,
u
.
l
.
lower
);
stl_
p
(
ptr
+
4
,
u
.
l
.
upper
);
}
#elif defined(TARGET_WORDS_BIGENDIAN) && (!defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED))
static
inline
int
lduw_
raw
(
void
*
ptr
)
static
inline
int
lduw_
p
(
void
*
ptr
)
{
#if defined(__i386__)
int
val
;
...
...
@@ -318,7 +318,7 @@ static inline int lduw_raw(void *ptr)
#endif
}
static
inline
int
ldsw_
raw
(
void
*
ptr
)
static
inline
int
ldsw_
p
(
void
*
ptr
)
{
#if defined(__i386__)
int
val
;
...
...
@@ -333,7 +333,7 @@ static inline int ldsw_raw(void *ptr)
#endif
}
static
inline
int
ldl_
raw
(
void
*
ptr
)
static
inline
int
ldl_
p
(
void
*
ptr
)
{
#if defined(__i386__) || defined(__x86_64__)
int
val
;
...
...
@@ -348,15 +348,15 @@ static inline int ldl_raw(void *ptr)
#endif
}
static
inline
uint64_t
ldq_
raw
(
void
*
ptr
)
static
inline
uint64_t
ldq_
p
(
void
*
ptr
)
{
uint32_t
a
,
b
;
a
=
ldl_
raw
(
ptr
);
b
=
ldl_
raw
(
ptr
+
4
);
a
=
ldl_
p
(
ptr
);
b
=
ldl_
p
(
ptr
+
4
);
return
(((
uint64_t
)
a
<<
32
)
|
b
);
}
static
inline
void
stw_
raw
(
void
*
ptr
,
int
v
)
static
inline
void
stw_
p
(
void
*
ptr
,
int
v
)
{
#if defined(__i386__)
asm
volatile
(
"xchgb %b0, %h0
\n
"
...
...
@@ -370,7 +370,7 @@ static inline void stw_raw(void *ptr, int v)
#endif
}
static
inline
void
stl_
raw
(
void
*
ptr
,
int
v
)
static
inline
void
stl_
p
(
void
*
ptr
,
int
v
)
{
#if defined(__i386__) || defined(__x86_64__)
asm
volatile
(
"bswap %0
\n
"
...
...
@@ -386,105 +386,105 @@ static inline void stl_raw(void *ptr, int v)
#endif
}
static
inline
void
stq_
raw
(
void
*
ptr
,
uint64_t
v
)
static
inline
void
stq_
p
(
void
*
ptr
,
uint64_t
v
)
{
stl_
raw
(
ptr
,
v
>>
32
);
stl_
raw
(
ptr
+
4
,
v
);
stl_
p
(
ptr
,
v
>>
32
);
stl_
p
(
ptr
+
4
,
v
);
}
/* float access */
static
inline
float
ldfl_
raw
(
void
*
ptr
)
static
inline
float
ldfl_
p
(
void
*
ptr
)
{
union
{
float
f
;
uint32_t
i
;
}
u
;
u
.
i
=
ldl_
raw
(
ptr
);
u
.
i
=
ldl_
p
(
ptr
);
return
u
.
f
;
}
static
inline
void
stfl_
raw
(
void
*
ptr
,
float
v
)
static
inline
void
stfl_
p
(
void
*
ptr
,
float
v
)
{
union
{
float
f
;
uint32_t
i
;
}
u
;
u
.
f
=
v
;
stl_
raw
(
ptr
,
u
.
i
);
stl_
p
(
ptr
,
u
.
i
);
}
static
inline
double
ldfq_
raw
(
void
*
ptr
)
static
inline
double
ldfq_
p
(
void
*
ptr
)
{
CPU_DoubleU
u
;
u
.
l
.
upper
=
ldl_
raw
(
ptr
);
u
.
l
.
lower
=
ldl_
raw
(
ptr
+
4
);
u
.
l
.
upper
=
ldl_
p
(
ptr
);
u
.
l
.
lower
=
ldl_
p
(
ptr
+
4
);
return
u
.
d
;
}
static
inline
void
stfq_
raw
(
void
*
ptr
,
double
v
)
static
inline
void
stfq_
p
(
void
*
ptr
,
double
v
)
{
CPU_DoubleU
u
;
u
.
d
=
v
;
stl_
raw
(
ptr
,
u
.
l
.
upper
);
stl_
raw
(
ptr
+
4
,
u
.
l
.
lower
);
stl_
p
(
ptr
,
u
.
l
.
upper
);
stl_
p
(
ptr
+
4
,
u
.
l
.
lower
);
}
#else
static
inline
int
lduw_
raw
(
void
*
ptr
)
static
inline
int
lduw_
p
(
void
*
ptr
)
{
return
*
(
uint16_t
*
)
ptr
;
}
static
inline
int
ldsw_
raw
(
void
*
ptr
)
static
inline
int
ldsw_
p
(
void
*
ptr
)
{
return
*
(
int16_t
*
)
ptr
;
}
static
inline
int
ldl_
raw
(
void
*
ptr
)
static
inline
int
ldl_
p
(
void
*
ptr
)
{
return
*
(
uint32_t
*
)
ptr
;
}
static
inline
uint64_t
ldq_
raw
(
void
*
ptr
)
static
inline
uint64_t
ldq_
p
(
void
*
ptr
)
{
return
*
(
uint64_t
*
)
ptr
;
}
static
inline
void
stw_
raw
(
void
*
ptr
,
int
v
)
static
inline
void
stw_
p
(
void
*
ptr
,
int
v
)
{
*
(
uint16_t
*
)
ptr
=
v
;
}
static
inline
void
stl_
raw
(
void
*
ptr
,
int
v
)
static
inline
void
stl_
p
(
void
*
ptr
,
int
v
)
{
*
(
uint32_t
*
)
ptr
=
v
;
}
static
inline
void
stq_
raw
(
void
*
ptr
,
uint64_t
v
)
static
inline
void
stq_
p
(
void
*
ptr
,
uint64_t
v
)
{
*
(
uint64_t
*
)
ptr
=
v
;
}
/* float access */
static
inline
float
ldfl_
raw
(
void
*
ptr
)
static
inline
float
ldfl_
p
(
void
*
ptr
)
{
return
*
(
float
*
)
ptr
;
}
static
inline
double
ldfq_
raw
(
void
*
ptr
)
static
inline
double
ldfq_
p
(
void
*
ptr
)
{
return
*
(
double
*
)
ptr
;
}
static
inline
void
stfl_
raw
(
void
*
ptr
,
float
v
)
static
inline
void
stfl_
p
(
void
*
ptr
,
float
v
)
{
*
(
float
*
)
ptr
=
v
;
}
static
inline
void
stfq_
raw
(
void
*
ptr
,
double
v
)
static
inline
void
stfq_
p
(
void
*
ptr
,
double
v
)
{
*
(
double
*
)
ptr
=
v
;
}
...
...
@@ -492,6 +492,24 @@ static inline void stfq_raw(void *ptr, double v)
/* MMU memory access macros */
/* NOTE: we use double casts if pointers and target_ulong have
different sizes */
#define ldub_raw(p) ldub_p((uint8_t *)(long)(p))
#define ldsb_raw(p) ldsb_p((uint8_t *)(long)(p))
#define lduw_raw(p) lduw_p((uint8_t *)(long)(p))
#define ldsw_raw(p) ldsw_p((uint8_t *)(long)(p))
#define ldl_raw(p) ldl_p((uint8_t *)(long)(p))
#define ldq_raw(p) ldq_p((uint8_t *)(long)(p))
#define ldfl_raw(p) ldfl_p((uint8_t *)(long)(p))
#define ldfq_raw(p) ldfq_p((uint8_t *)(long)(p))
#define stb_raw(p, v) stb_p((uint8_t *)(long)(p), v)
#define stw_raw(p, v) stw_p((uint8_t *)(long)(p), v)
#define stl_raw(p, v) stl_p((uint8_t *)(long)(p), v)
#define stq_raw(p, v) stq_p((uint8_t *)(long)(p), v)
#define stfl_raw(p, v) stfl_p((uint8_t *)(long)(p), v)
#define stfq_raw(p, v) stfq_p((uint8_t *)(long)(p), v)
#if defined(CONFIG_USER_ONLY)
/* if user mode, no other memory access functions */
...
...
cpu-defs.h
View file @
c27004ec
...
...
@@ -49,9 +49,11 @@
#if TARGET_LONG_SIZE == 4
typedef
int32_t
target_long
;
typedef
uint32_t
target_ulong
;
#define TARGET_FMT_lx "%08x"
#elif TARGET_LONG_SIZE == 8
typedef
int64_t
target_long
;
typedef
uint64_t
target_ulong
;
#define TARGET_FMT_lx "%016llx"
#else
#error TARGET_LONG_SIZE undefined
#endif
...
...
cpu-exec.c
View file @
c27004ec
...
...
@@ -106,15 +106,16 @@ int cpu_exec(CPUState *env1)
int
code_gen_size
,
ret
,
interrupt_request
;
void
(
*
gen_func
)(
void
);
TranslationBlock
*
tb
,
**
ptb
;
uint8_t
*
tc_ptr
,
*
cs_base
,
*
pc
;
target_ulong
cs_base
,
pc
;
uint8_t
*
tc_ptr
;
unsigned
int
flags
;
/* first we save global registers */
saved_env
=
env
;
env
=
env1
;
saved_T0
=
T0
;
saved_T1
=
T1
;
saved_T2
=
T2
;
saved_env
=
env
;
env
=
env1
;
#ifdef __sparc__
/* we also save i7 because longjmp may not restore it */
asm
volatile
(
"mov %%i7, %0"
:
"=r"
(
saved_i7
));
...
...
@@ -285,7 +286,7 @@ int cpu_exec(CPUState *env1)
}
}
#ifdef DEBUG_EXEC
if
(
loglevel
&
CPU_LOG_EXEC
)
{
if
(
(
loglevel
&
CPU_LOG_EXEC
)
)
{
#if defined(TARGET_I386)
/* restore flags in standard format */
env
->
regs
[
R_EAX
]
=
EAX
;
...
...
@@ -323,19 +324,19 @@ int cpu_exec(CPUState *env1)
#elif defined(TARGET_ARM)
flags
=
0
;
cs_base
=
0
;
pc
=
(
uint8_t
*
)
env
->
regs
[
15
];
pc
=
env
->
regs
[
15
];
#elif defined(TARGET_SPARC)
flags
=
0
;
cs_base
=
(
uint8_t
*
)
env
->
npc
;
pc
=
(
uint8_t
*
)
env
->
pc
;
cs_base
=
env
->
npc
;
pc
=
env
->
pc
;
#elif defined(TARGET_PPC)
flags
=
0
;
cs_base
=
0
;
pc
=
(
uint8_t
*
)
env
->
nip
;
pc
=
env
->
nip
;
#else
#error unsupported CPU
#endif
tb
=
tb_find
(
&
ptb
,
(
unsigned
long
)
pc
,
(
unsigned
long
)
cs_base
,
tb
=
tb_find
(
&
ptb
,
pc
,
cs_base
,
flags
);
if
(
!
tb
)
{
TranslationBlock
**
ptb1
;
...
...
@@ -350,7 +351,7 @@ int cpu_exec(CPUState *env1)
regs_to_env
();
/* XXX: do it just before cpu_gen_code() */
/* find translated block using physical mappings */
phys_pc
=
get_phys_addr_code
(
env
,
(
unsigned
long
)
pc
);
phys_pc
=
get_phys_addr_code
(
env
,
pc
);
phys_page1
=
phys_pc
&
TARGET_PAGE_MASK
;
phys_page2
=
-
1
;
h
=
tb_phys_hash_func
(
phys_pc
);
...
...
@@ -359,13 +360,13 @@ int cpu_exec(CPUState *env1)
tb
=
*
ptb1
;
if
(
!
tb
)
goto
not_found
;
if
(
tb
->
pc
==
(
unsigned
long
)
pc
&&
if
(
tb
->
pc
==
pc
&&
tb
->
page_addr
[
0
]
==
phys_page1
&&
tb
->
cs_base
==
(
unsigned
long
)
cs_base
&&
tb
->
cs_base
==
cs_base
&&
tb
->
flags
==
flags
)
{
/* check next page if needed */
if
(
tb
->
page_addr
[
1
]
!=
-
1
)
{
virt_page2
=
(
(
unsigned
long
)
pc
&
TARGET_PAGE_MASK
)
+
virt_page2
=
(
pc
&
TARGET_PAGE_MASK
)
+
TARGET_PAGE_SIZE
;
phys_page2
=
get_phys_addr_code
(
env
,
virt_page2
);
if
(
tb
->
page_addr
[
1
]
==
phys_page2
)
...
...
@@ -378,27 +379,27 @@ int cpu_exec(CPUState *env1)
}
not_found:
/* if no translated code available, then translate it now */
tb
=
tb_alloc
(
(
unsigned
long
)
pc
);
tb
=
tb_alloc
(
pc
);
if
(
!
tb
)
{
/* flush must be done */
tb_flush
(
env
);
/* cannot fail at this point */
tb
=
tb_alloc
(
(
unsigned
long
)
pc
);
tb
=
tb_alloc
(
pc
);
/* don't forget to invalidate previous TB info */
ptb
=
&
tb_hash
[
tb_hash_func
(
(
unsigned
long
)
pc
)];
ptb
=
&
tb_hash
[
tb_hash_func
(
pc
)];
T0
=
0
;
}
tc_ptr
=
code_gen_ptr
;
tb
->
tc_ptr
=
tc_ptr
;
tb
->
cs_base
=
(
unsigned
long
)
cs_base
;
tb
->
cs_base
=
cs_base
;
tb
->
flags
=
flags
;
cpu_gen_code
(
env
,
tb
,
CODE_GEN_MAX_SIZE
,
&
code_gen_size
);
code_gen_ptr
=
(
void
*
)(((
unsigned
long
)
code_gen_ptr
+
code_gen_size
+
CODE_GEN_ALIGN
-
1
)
&
~
(
CODE_GEN_ALIGN
-
1
));
/* check next page if needed */
virt_page2
=
(
(
unsigned
long
)
pc
+
tb
->
size
-
1
)
&
TARGET_PAGE_MASK
;
virt_page2
=
(
pc
+
tb
->
size
-
1
)
&
TARGET_PAGE_MASK
;
phys_page2
=
-
1
;
if
((
(
unsigned
long
)
pc
&
TARGET_PAGE_MASK
)
!=
virt_page2
)
{
if
((
pc
&
TARGET_PAGE_MASK
)
!=
virt_page2
)
{
phys_page2
=
get_phys_addr_code
(
env
,
virt_page2
);
}
tb_link_phys
(
tb
,
phys_pc
,
phys_page2
);
...
...
@@ -408,7 +409,7 @@ int cpu_exec(CPUState *env1)
/* as some TB could have been invalidated because
of memory exceptions while generating the code, we
must recompute the hash index here */
ptb
=
&
tb_hash
[
tb_hash_func
(
(
unsigned
long
)
pc
)];
ptb
=
&
tb_hash
[
tb_hash_func
(
pc
)];
while
(
*
ptb
!=
NULL
)
ptb
=
&
(
*
ptb
)
->
hash_next
;
T0
=
0
;
...
...
@@ -420,24 +421,25 @@ int cpu_exec(CPUState *env1)
spin_unlock
(
&
tb_lock
);
}
#ifdef DEBUG_EXEC
if
(
loglevel
&
CPU_LOG_EXEC
)
{
fprintf
(
logfile
,
"Trace 0x%08lx [
0x%08lx
] %s
\n
"
,
(
long
)
tb
->
tc_ptr
,
(
long
)
tb
->
pc
,
lookup_symbol
(
(
void
*
)
tb
->
pc
));
if
(
(
loglevel
&
CPU_LOG_EXEC
)
&&
(
env
->
hflags
&
HF_LMA_MASK
)
)
{
fprintf
(
logfile
,
"Trace 0x%08lx [
"
TARGET_FMT_lx
"
] %s
\n
"
,
(
long
)
tb
->
tc_ptr
,
tb
->
pc
,
lookup_symbol
(
tb
->
pc
));
}
#endif
#ifdef __sparc__
T0
=
tmp_T0
;
#endif
/* see if we can patch the calling TB. */
if
(
T0
!=
0
{
if
(
T0
!=
0
#if defined(TARGET_I386) && defined(USE_CODE_COPY)
&&
(
tb
->
cflags
&
CF_CODE_COPY
)
==
(((
TranslationBlock
*
)(
T0
&
~
3
))
->
cflags
&
CF_CODE_COPY
)
#endif
)
{
spin_lock
(
&
tb_lock
);
tb_add_jump
((
TranslationBlock
*
)(
T0
&
~
3
),
T0
&
3
,
tb
);
tb_add_jump
((
TranslationBlock
*
)(
long
)(
T0
&
~
3
),
T0
&
3
,
tb
);
#if defined(USE_CODE_COPY)
/* propagates the FP use info */
((
TranslationBlock
*
)(
T0
&
~
3
))
->
cflags
|=
...
...
@@ -445,6 +447,7 @@ int cpu_exec(CPUState *env1)
#endif
spin_unlock
(
&
tb_lock
);
}
}
tc_ptr
=
tb
->
tc_ptr
;
env
->
current_tb
=
tb
;
/* execute the generated code */
...
...
@@ -631,7 +634,7 @@ void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector)
if
(
!
(
env
->
cr
[
0
]
&
CR0_PE_MASK
)
||
(
env
->
eflags
&
VM_MASK
))
{
selector
&=
0xffff
;
cpu_x86_load_seg_cache
(
env
,
seg_reg
,
selector
,
(
uint8_t
*
)(
selector
<<
4
),
0xffff
,
0
);
(
selector
<<
4
),
0xffff
,
0
);
}
else
{
load_seg
(
seg_reg
,
selector
);
}
...
...
@@ -645,7 +648,7 @@ void cpu_x86_fsave(CPUX86State *s, uint8_t *ptr, int data32)
saved_env
=
env
;
env
=
s
;
helper_fsave
(
ptr
,
data32
);
helper_fsave
(
(
target_ulong
)
ptr
,
data32
);
env
=
saved_env
;
}
...
...
@@ -657,7 +660,7 @@ void cpu_x86_frstor(CPUX86State *s, uint8_t *ptr, int data32)
saved_env
=
env
;
env
=
s
;
helper_frstor
(
ptr
,
data32
);
helper_frstor
(
(
target_ulong
)
ptr
,
data32
);
env
=
saved_env
;
}
...
...
dis-asm.h
View file @
c27004ec
...
...
@@ -9,6 +9,7 @@
#ifndef DIS_ASM_H
#define DIS_ASM_H
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
...
...
@@ -20,6 +21,8 @@ typedef int64_t bfd_signed_vma;
typedef
uint8_t
bfd_byte
;
#define sprintf_vma(s,x) sprintf (s, "%0" PRIx64, x)
#define BFD64
enum
bfd_flavour
{
bfd_target_unknown_flavour
,
bfd_target_aout_flavour
,
...
...
disas.c
View file @
c27004ec
...
...
@@ -28,23 +28,20 @@ buffer_read_memory (memaddr, myaddr, length, info)
return
0
;
}
#if !defined(CONFIG_USER_ONLY)
/* Get LENGTH bytes from info's buffer, at target address memaddr.
Transfer them to myaddr. */
static
int
target_read_memory
(
memaddr
,
myaddr
,
length
,
info
)
bfd_vma
memaddr
;
bfd_byte
*
myaddr
;
int
length
;
struct
disassemble_info
*
info
;
target_read_memory
(
bfd_vma
memaddr
,
bfd_byte
*
myaddr
,
int
length
,
struct
disassemble_info
*
info
)
{
int
i
;
for
(
i
=
0
;
i
<
length
;
i
++
)
{
myaddr
[
i
]
=
ldub_code
(
(
void
*
)((
long
)
memaddr
+
i
)
);
myaddr
[
i
]
=
ldub_code
(
memaddr
+
i
);
}
return
0
;
}
#endif
/* Print an error message. We can assume that this is in response to
an error return from buffer_read_memory. */
...
...
@@ -113,75 +110,107 @@ bfd_vma bfd_getb32 (const bfd_byte *addr)
/* Disassemble this for me please... (debugging). 'flags' is only used
for i386: non zero means 16 bit code */
void
disas
(
FILE
*
out
,
void
*
code
,
unsigned
long
size
,
int
is_host
,
int
flags
)
void
target_disas
(
FILE
*
out
,
target_ulong
code
,
unsigned
long
size
,
int
flags
)
{
uint8_t
*
pc
;
target_ulong
pc
;
int
count
;
struct
disassemble_info
disasm_info
;
int
(
*
print_insn
)(
bfd_vma
pc
,
disassemble_info
*
info
);
INIT_DISASSEMBLE_INFO
(
disasm_info
,
out
,
fprintf
);
#if !defined(CONFIG_USER_ONLY)
if
(
!
is_host
)
{
disasm_info
.
read_memory_func
=
target_read_memory
;
}
disasm_info
.
read_memory_func
=
target_read_memory
;
disasm_info
.
buffer_vma
=
code
;
disasm_info
.
buffer_length
=
size
;
#ifdef TARGET_WORDS_BIGENDIAN
disasm_info
.
endian
=
BFD_ENDIAN_BIG
;
#else
disasm_info
.
endian
=
BFD_ENDIAN_LITTLE
;
#endif
#if defined(TARGET_I386)
if
(
flags
==
2
)
disasm_info
.
mach
=
bfd_mach_x86_64
;
else
if
(
flags
==
1
)
disasm_info
.
mach
=
bfd_mach_i386_i8086
;
else
disasm_info
.
mach
=
bfd_mach_i386_i386
;
print_insn
=
print_insn_i386
;
#elif defined(TARGET_ARM)
print_insn
=
print_insn_arm
;
#elif defined(TARGET_SPARC)
print_insn
=
print_insn_sparc
;
#elif defined(TARGET_PPC)
print_insn
=
print_insn_ppc
;
#else
fprintf
(
out
,
"Asm output not supported on this arch
\n
"
);
return
;
#endif
for
(
pc
=
code
;
pc
<
code
+
size
;
pc
+=
count
)
{
#if TARGET_LONG_BITS == 64
fprintf
(
out
,
"0x%016llx: "
,
pc
);
#else
fprintf
(
out
,
"0x%08x: "
,
pc
);
#endif
count
=
print_insn
(
pc
,
&
disasm_info
);
#if 0
{
int i;
uint8_t b;
fprintf(out, " {");
for(i = 0; i < count; i++) {
target_read_memory(pc + i, &b, 1, &disasm_info);
fprintf(out, " %02x", b);
}
fprintf(out, " }");
}
#endif
fprintf
(
out
,
"
\n
"
);
if
(
count
<
0
)
break
;
}
}
/* Disassemble this for me please... (debugging). */
void
disas
(
FILE
*
out
,
void
*
code
,
unsigned
long
size
)
{
unsigned
long
pc
;
int
count
;
struct
disassemble_info
disasm_info
;
int
(
*
print_insn
)(
bfd_vma
pc
,
disassemble_info
*
info
);
INIT_DISASSEMBLE_INFO
(
disasm_info
,
out
,
fprintf
);
disasm_info
.
buffer
=
code
;
disasm_info
.
buffer_vma
=
(
unsigned
long
)
code
;
disasm_info
.
buffer_length
=
size
;
if
(
is_host
)
{
#ifdef WORDS_BIGENDIAN
disasm_info
.
endian
=
BFD_ENDIAN_BIG
;
disasm_info
.
endian
=
BFD_ENDIAN_BIG
;
#else
disasm_info
.
endian
=
BFD_ENDIAN_LITTLE
;
disasm_info
.
endian
=
BFD_ENDIAN_LITTLE
;
#endif
#if defined(__i386__)
disasm_info
.
mach
=
bfd_mach_i386_i386
;
print_insn
=
print_insn_i386
;
disasm_info
.
mach
=
bfd_mach_i386_i386
;
print_insn
=
print_insn_i386
;
#elif defined(__x86_64__)
disasm_info
.
mach
=
bfd_mach_x86_64
;
print_insn
=
print_insn_i386
;
disasm_info
.
mach
=
bfd_mach_x86_64
;
print_insn
=
print_insn_i386
;
#elif defined(__powerpc__)
print_insn
=
print_insn_ppc
;
print_insn
=
print_insn_ppc
;
#elif defined(__alpha__)
print_insn
=
print_insn_alpha
;
print_insn
=
print_insn_alpha
;
#elif defined(__sparc__)
print_insn
=
print_insn_sparc
;
print_insn
=
print_insn_sparc
;
#elif defined(__arm__)
print_insn
=
print_insn_arm
;
#else
fprintf
(
out
,
"Asm output not supported on this arch
\n
"
);
return
;
#endif
}
else
{
#ifdef TARGET_WORDS_BIGENDIAN
disasm_info
.
endian
=
BFD_ENDIAN_BIG
;
#else
disasm_info
.
endian
=
BFD_ENDIAN_LITTLE
;
#endif
#if defined(TARGET_I386)
if
(
!
flags
)
disasm_info
.
mach
=
bfd_mach_i386_i386
;
else
disasm_info
.
mach
=
bfd_mach_i386_i8086
;
print_insn
=
print_insn_i386
;
#elif defined(TARGET_ARM)
print_insn
=
print_insn_arm
;
#elif defined(TARGET_SPARC)
print_insn
=
print_insn_sparc
;
#elif defined(TARGET_PPC)
print_insn
=
print_insn_ppc
;
print_insn
=
print_insn_arm
;
#else
fprintf
(
out
,
"Asm output not supported on this arch
\n
"
);
return
;
fprintf
(
out
,
"Asm output not supported on this arch
\n
"
);
return
;
#endif
}
for
(
pc
=
code
;
pc
<
(
uint8_t
*
)
code
+
size
;
pc
+=
count
)
{
fprintf
(
out
,
"0x%08lx: "
,
(
long
)
pc
);
for
(
pc
=
(
unsigned
long
)
code
;
pc
<
(
unsigned
long
)
code
+
size
;
pc
+=
count
)
{
fprintf
(
out
,
"0x%08lx: "
,
pc
);
#ifdef __arm__
/* since data are included in the code, it is better to
display code data too */
...
...
@@ -189,7 +218,7 @@ void disas(FILE *out, void *code, unsigned long size, int is_host, int flags)
fprintf
(
out
,
"%08x "
,
(
int
)
bfd_getl32
((
const
bfd_byte
*
)
pc
));
}
#endif
count
=
print_insn
(
(
unsigned
long
)
pc
,
&
disasm_info
);
count
=
print_insn
(
pc
,
&
disasm_info
);
fprintf
(
out
,
"
\n
"
);
if
(
count
<
0
)
break
;
...
...
@@ -197,7 +226,7 @@ void disas(FILE *out, void *code, unsigned long size, int is_host, int flags)
}