fix merge conflicts

This commit is contained in:
Nguyen Anh Quynh 2017-03-10 21:04:33 +08:00
commit c01dcf0a14
41 changed files with 543 additions and 109 deletions

View File

@ -9,6 +9,13 @@ include pkgconfig.mk # package version
LIBNAME = unicorn
UNAME_S := $(shell uname -s)
# SMP_MFLAGS is used for controlling the amount of parallelism used
# in external 'make' invocations. If the user doesn't override it, it
# does "-j4". That is, it uses 4 job threads. If you want to use more or less,
# pass in a different -jX, with X being the number of threads.
# For example, to completely disable parallel building, pass "-j1".
# If you want to use 16 job threads, use "-j16".
SMP_MFLAGS := -j4
GENOBJ = $(shell find qemu/$(1) -name "*.o" 2>/dev/null)
@ -204,7 +211,7 @@ qemu/config-host.h-timestamp:
cd qemu && \
./configure --cc="${CC}" --extra-cflags="$(UNICORN_CFLAGS)" --target-list="$(UNICORN_TARGETS)" ${UNICORN_QEMU_FLAGS}
printf "$(UNICORN_ARCHS)" > config.log
$(MAKE) -C qemu -j 4
$(MAKE) -C qemu $(SMP_MFLAGS)
$(eval UC_TARGET_OBJ += $$(wildcard qemu/util/*.o) $$(wildcard qemu/*.o) $$(wildcard qemu/qom/*.o) $$(wildcard qemu/hw/core/*.o) $$(wildcard qemu/qapi/*.o) $$(wildcard qemu/qobject/*.o))
unicorn: $(LIBRARY) $(ARCHIVE)

View File

@ -42,7 +42,7 @@ python:
$(ENV_VARS) python python/$(@:%.txt=%) > $@
%.py.test: %.c.txt %.py.txt
$(DIFF) $(@:%.py.test=%.c.txt) $(@:%.py.test=%.py.txt)
$(DIFF) -u $(@:%.py.test=%.c.txt) $(@:%.py.test=%.py.txt)
clean:
# rm -rf *.txt

View File

@ -257,7 +257,8 @@ module X86 =
let UC_X86_REG_TR = 245
let UC_X86_REG_FPCW = 246
let UC_X86_REG_FPTAG = 247
let UC_X86_REG_ENDING = 248
let UC_X86_REG_MSR = 248
let UC_X86_REG_ENDING = 249
// X86 instructions

View File

@ -252,7 +252,8 @@ const (
X86_REG_TR = 245
X86_REG_FPCW = 246
X86_REG_FPTAG = 247
X86_REG_ENDING = 248
X86_REG_MSR = 248
X86_REG_ENDING = 249
// X86 instructions

View File

@ -21,3 +21,4 @@ SampleMips
SampleSparc
SampleX86
Shellcode
SampleBatchReg

View File

@ -0,0 +1,99 @@
import Unicorn
import Unicorn.Hook
import qualified Unicorn.CPU.X86 as X86
import Control.Monad.Trans.Class (lift)
import qualified Data.ByteString as BS
import Data.Int
import Data.List (intercalate)
import Data.Word
import qualified Numeric as N (showHex)
import System.IO (hPutStrLn, stderr)
syscallABI :: [X86.Register]
syscallABI = [ X86.Rax
, X86.Rdi
, X86.Rsi
, X86.Rdx
, X86.R10
, X86.R8
, X86.R9
]
vals :: [Int64]
vals = [ 200
, 10
, 11
, 12
, 13
, 14
, 15
]
ucPerror :: Error
-> IO ()
ucPerror err =
hPutStrLn stderr $ "Error " ++ ": " ++ strerror err
base :: Word64
base = 0x10000
-- mov rax, 100; mov rdi, 1; mov rsi, 2; mov rdx, 3; mov r10, 4; mov r8, 5; mov r9, 6; syscall
code :: BS.ByteString
code = BS.pack [ 0x48, 0xc7, 0xc0, 0x64, 0x00, 0x00, 0x00, 0x48, 0xc7, 0xc7
, 0x01, 0x00, 0x00, 0x00, 0x48, 0xc7, 0xc6, 0x02, 0x00, 0x00
, 0x00, 0x48, 0xc7, 0xc2, 0x03, 0x00, 0x00, 0x00, 0x49, 0xc7
, 0xc2, 0x04, 0x00, 0x00, 0x00, 0x49, 0xc7, 0xc0, 0x05, 0x00
, 0x00, 0x00, 0x49, 0xc7, 0xc1, 0x06, 0x00, 0x00, 0x00, 0x0f
, 0x05
]
-- Pretty-print integral as hex
showHex :: (Integral a, Show a) => a -> String
showHex i =
N.showHex (fromIntegral i :: Word64) ""
-- Write a string (with a newline character) to standard output in the emulator
emuPutStrLn :: String -> Emulator ()
emuPutStrLn =
lift . putStrLn
hookSyscall :: SyscallHook ()
hookSyscall uc _ = do
runEmulator $ do
readVals <- regReadBatch uc syscallABI
emuPutStrLn $ "syscall: {"
++ intercalate ", " (map show readVals)
++ "}"
return ()
hookCode :: CodeHook ()
hookCode _ addr size _ = do
putStrLn $ "HOOK_CODE: 0x" ++ showHex addr ++ ", 0x" ++
maybe "0" showHex size
main :: IO ()
main = do
result <- runEmulator $ do
uc <- open ArchX86 [Mode64]
-- regWriteBatch
emuPutStrLn "regWriteBatch {200, 10, 11, 12, 13, 14, 15}"
regWriteBatch uc syscallABI vals
readVals <- regReadBatch uc syscallABI
emuPutStrLn $ "regReadBatch = {"
++ intercalate ", " (map show readVals)
++ "}"
-- syscall
emuPutStrLn "running syscall shellcode"
syscallHookAdd uc hookSyscall () 1 0
memMap uc base (0x1000) [ProtAll]
memWrite uc base code
let codeLen = fromIntegral $ BS.length code
start uc base (base + codeLen) Nothing Nothing
case result of
Right _ -> return ()
Left err -> ucPerror err

View File

@ -98,7 +98,7 @@ hookCode :: CodeHook ()
hookCode uc addr size _ = do
runEmulator $ do
emuPutStrLn $ ">>> Tracing instruction at 0x" ++ showHex addr ++
", instruction size = 0x" ++ (maybe "0" showHex size)
", instruction size = 0x" ++ maybe "0" showHex size
eflags <- regRead uc X86.Eflags
emuPutStrLn $ ">>> --- EFLAGS is 0x" ++ showHex eflags

View File

@ -25,6 +25,8 @@ module Unicorn
-- * Register operations
, regWrite
, regRead
, regWriteBatch
, regReadBatch
-- * Memory operations
, MemoryPermission(..)
@ -140,13 +142,11 @@ stop uc = do
-- | Write to register.
regWrite :: Reg r
=> Engine -- ^ 'Unicorn' engine handle
-> r -- ^ Register ID to write to
-> r -- ^ Register to write to
-> Int64 -- ^ Value to write to register
-> Emulator () -- ^ An 'Error' on failure
regWrite uc regId value = do
err <- lift . alloca $ \ptr -> do
poke ptr value
ucRegWrite uc regId ptr
regWrite uc reg value = do
err <- lift $ ucRegWrite uc reg value
if err == ErrOk then
right ()
else
@ -155,16 +155,49 @@ regWrite uc regId value = do
-- | Read register value.
regRead :: Reg r
=> Engine -- ^ 'Unicorn' engine handle
-> r -- ^ Register ID to read from
-> r -- ^ Register to read from
-> Emulator Int64 -- ^ The value read from the register on success,
-- or an 'Error' on failure
regRead uc regId = do
(err, val) <- lift $ ucRegRead uc regId
regRead uc reg = do
(err, val) <- lift $ ucRegRead uc reg
if err == ErrOk then
right val
else
left err
-- | Write multiple register values.
regWriteBatch :: Reg r
=> Engine -- ^ 'Unicorn' engine handle
-> [r] -- ^ List of registers to write to
-> [Int64] -- ^ List of values to write to the registers
-> Emulator () -- ^ An 'Error' on failure
regWriteBatch uc regs vals = do
err <- lift $ ucRegWriteBatch uc regs vals (length regs)
if err == ErrOk then
right ()
else
left err
-- | Read multiple register values.
regReadBatch :: Reg r
=> Engine -- ^ 'Unicorn' engine handle
-> [r] -- ^ List of registers to read from
-> Emulator [Int64] -- ^ A list of register values on success,
-- or an 'Error' on failure
regReadBatch uc regs = do
-- Allocate an array of the given size
let size = length regs
result <- lift . allocaArray size $ \array -> do
err <- ucRegReadBatch uc regs array size
if err == ErrOk then
-- If ucRegReadBatch completed successfully, pack the contents of
-- the array into a list and return it
liftM Right (peekArray size array)
else
-- Otherwise return the error
return $ Left err
hoistEither result
-------------------------------------------------------------------------------
-- Memory operations
-------------------------------------------------------------------------------
@ -190,12 +223,12 @@ memRead :: Engine -- ^ 'Unicorn' engine handle
-- an 'Error' on failure
memRead uc address size = do
-- Allocate an array of the given size
result <- lift . allocaArray size $ \ptr -> do
err <- ucMemRead uc address ptr size
result <- lift . allocaArray size $ \array -> do
err <- ucMemRead uc address array size
if err == ErrOk then
-- If ucMemRead completed successfully, pack the contents of the
-- array into a ByteString and return it
liftM (Right . pack) (peekArray size ptr)
liftM (Right . pack) (peekArray size array)
else
-- Otherwise return the error
return $ Left err

View File

@ -314,7 +314,7 @@ marshalMemoryHook memoryHook =
maybeValue = case memAccess of
MemRead -> Nothing
MemWrite -> Just $ fromIntegral value
_ -> undefined -- XX Handle this?
_ -> error "Invalid memory access"
memoryHook uc memAccess address (fromIntegral size) maybeValue userData
-- | Callback function for hooking memory reads.
@ -390,7 +390,7 @@ marshalMemoryEventHook eventMemoryHook =
MemReadProt -> Nothing
MemWriteUnmapped -> Just $ fromIntegral value
MemWriteProt -> Just $ fromIntegral value
_ -> undefined -- XX Handle this?
_ -> error "Invalid memory access"
res <- eventMemoryHook uc memAccess address (fromIntegral size)
maybeValue userData
return $ boolToInt res

View File

@ -28,6 +28,8 @@ module Unicorn.Internal.Unicorn
, ucEmuStop
, ucRegWrite
, ucRegRead
, ucRegWriteBatch
, ucRegReadBatch
, ucMemWrite
, ucMemRead
, ucMemMap
@ -154,7 +156,8 @@ mkContext ptr =
, `Word64'
, `Word64'
, `Int'
, `Int'} -> `Error'
, `Int'
} -> `Error'
#}
{# fun uc_emu_stop as ^
@ -166,19 +169,37 @@ mkContext ptr =
-- Register operations
-------------------------------------------------------------------------------
{# fun uc_reg_write as ^
{# fun uc_reg_write_wrapper as ucRegWrite
`Reg r' =>
{ `Engine'
, enumToNum `r'
, castPtr `Ptr Int64'
, withIntegral* `Int64'
} -> `Error'
#}
{# fun uc_reg_read as ^
{# fun uc_reg_read_wrapper as ucRegRead
`Reg r' =>
{ `Engine'
, enumToNum `r'
, allocaInt64ToVoid- `Int64' castPtrAndPeek*
, alloca- `Int64' castPtrAndPeek*
} -> `Error'
#}
{# fun uc_reg_write_batch_wrapper as ucRegWriteBatch
`Reg r' =>
{ `Engine'
, withEnums* `[r]'
, integralListToArray* `[Int64]'
, `Int'
} -> `Error'
#}
{# fun uc_reg_read_batch_wrapper as ucRegReadBatch
`Reg r' =>
{ `Engine'
, withEnums* `[r]'
, castPtr `Ptr Int64'
, `Int'
} -> `Error'
#}
@ -197,7 +218,8 @@ mkContext ptr =
{ `Engine'
, `Word64'
, castPtr `Ptr Word8'
, `Int'} -> `Error'
, `Int'
} -> `Error'
#}
{# fun uc_mem_map as ^
@ -205,7 +227,8 @@ mkContext ptr =
, `Word64'
, `Int'
, combineEnums `[MemoryPermission]'
} -> `Error' #}
} -> `Error'
#}
{# fun uc_mem_unmap as ^
{ `Engine'
@ -296,13 +319,32 @@ expandMemPerms perms =
checkRWE _ [] =
[]
allocaInt64ToVoid :: (Ptr () -> IO b)
-> IO b
allocaInt64ToVoid f =
alloca $ \(ptr :: Ptr Int64) -> poke ptr 0 >> f (castPtr ptr)
withIntegral :: (Integral a, Num b, Storable b)
=> a
-> (Ptr b -> IO c)
-> IO c
withIntegral =
with . fromIntegral
withByteStringLen :: ByteString
-> ((Ptr (), CULong) -> IO a)
-> IO a
withByteStringLen :: Integral a
=> ByteString
-> ((Ptr (), a) -> IO b)
-> IO b
withByteStringLen bs f =
useAsCStringLen bs $ \(ptr, len) -> f (castPtr ptr, fromIntegral len)
withEnums :: Enum a
=> [a]
-> (Ptr b -> IO c)
-> IO c
withEnums l f =
let ints :: [CInt] = map enumToNum l in
withArray ints $ \ptr -> f (castPtr ptr)
integralListToArray :: (Integral a, Storable b, Num b)
=> [a]
-> (Ptr b -> IO c)
-> IO c
integralListToArray l f =
let l' = map fromIntegral l in
withArray l' $ \array -> f array

View File

@ -1,3 +1,5 @@
#include <stdlib.h>
#include "unicorn_wrapper.h"
void uc_close_wrapper(uc_engine *uc) {
@ -7,6 +9,42 @@ void uc_close_wrapper(uc_engine *uc) {
void uc_close_dummy(uc_engine *uc) {
}
uc_err uc_reg_write_wrapper(uc_engine *uc, int regid, const int64_t *value) {
return uc_reg_write(uc, regid, (const void*) value);
}
uc_err uc_reg_read_wrapper(uc_engine *uc, int regid, int64_t *value) {
return uc_reg_read(uc, regid, (void*) value);
}
uc_err uc_reg_write_batch_wrapper(uc_engine *uc, int *regs, int64_t *vals, int count) {
void **valsPtr = malloc(sizeof(void*) * count);
int i;
for (i = 0; i < count; ++i) {
valsPtr[i] = (void*) &vals[i];
}
uc_err ret = uc_reg_write_batch(uc, regs, (void *const*) valsPtr, count);
free(valsPtr);
return ret;
}
uc_err uc_reg_read_batch_wrapper(uc_engine *uc, int *regs, int64_t *vals, int count) {
void **valsPtr = malloc(sizeof(void*) * count);
int i;
for (i = 0; i < count; ++i) {
valsPtr[i] = (void*) &vals[i];
}
uc_err ret = uc_reg_read_batch(uc, regs, valsPtr, count);
free(valsPtr);
return ret;
}
void uc_free_wrapper(void *mem) {
uc_free(mem);
}

View File

@ -1,6 +1,7 @@
#ifndef UNICORN_WRAPPER_H
#define UNICORN_WRAPPER_H
#include <stdint.h>
#include <unicorn/unicorn.h>
/*
@ -13,6 +14,14 @@ void uc_close_wrapper(uc_engine *uc);
*/
void uc_close_dummy(uc_engine *uc);
/*
* Wrappers for register read/write functions that accept int64_t pointers.
*/
uc_err uc_reg_write_wrapper(uc_engine *uc, int regid, const int64_t *value);
uc_err uc_reg_read_wrapper(uc_engine *uc, int regid, int64_t *value);
uc_err uc_reg_write_batch_wrapper(uc_engine *uc, int *regs, int64_t *vals, int count);
uc_err uc_reg_read_batch_wrapper(uc_engine *uc, int *regs, int64_t *vals, int count);
/*
* Wrap Unicorn's uc_free function and ignore the returned error code.
*/

View File

@ -254,7 +254,8 @@ public interface X86Const {
public static final int UC_X86_REG_TR = 245;
public static final int UC_X86_REG_FPCW = 246;
public static final int UC_X86_REG_FPTAG = 247;
public static final int UC_X86_REG_ENDING = 248;
public static final int UC_X86_REG_MSR = 248;
public static final int UC_X86_REG_ENDING = 249;
// X86 instructions

View File

@ -41,7 +41,8 @@ def test_arm():
mu.reg_write(UC_ARM_REG_R0, 0x1234)
mu.reg_write(UC_ARM_REG_R2, 0x6789)
mu.reg_write(UC_ARM_REG_R3, 0x3333)
mu.reg_write(UC_ARM_REG_APSR, 0xFFFFFFFF) #All application flags turned on
# tracing all basic blocks with customized callback
mu.hook_add(UC_HOOK_BLOCK, hook_block)

View File

@ -9,7 +9,7 @@ import os.path
import sys
import weakref
from . import x86_const, unicorn_const as uc
from . import x86_const, arm64_const, unicorn_const as uc
if not hasattr(sys.modules[__name__], "__file__"):
__file__ = inspect.getfile(inspect.currentframe())
@ -202,6 +202,11 @@ class uc_x86_mmr(ctypes.Structure):
("flags", ctypes.c_uint32), # not used by GDTR and IDTR
]
class uc_x86_msr(ctypes.Structure):
_fields_ = [
("rid", ctypes.c_uint32),
("value", ctypes.c_uint64),
]
class uc_x86_float80(ctypes.Structure):
"""Float80"""
@ -218,6 +223,13 @@ class uc_x86_xmm(ctypes.Structure):
("high_qword", ctypes.c_uint64),
]
class uc_arm64_neon128(ctypes.Structure):
"""128-bit neon register"""
_fields_ = [
("low_qword", ctypes.c_uint64),
("high_qword", ctypes.c_uint64),
]
# Subclassing ref to allow property assignment.
class UcRef(weakref.ref):
pass
@ -282,7 +294,7 @@ class Uc(object):
raise UcError(status)
# return the value of a register
def reg_read(self, reg_id):
def reg_read(self, reg_id, opt=None):
if self._arch == uc.UC_ARCH_X86:
if reg_id in [x86_const.UC_X86_REG_IDTR, x86_const.UC_X86_REG_GDTR, x86_const.UC_X86_REG_LDTR, x86_const.UC_X86_REG_TR]:
reg = uc_x86_mmr()
@ -302,6 +314,23 @@ class Uc(object):
if status != uc.UC_ERR_OK:
raise UcError(status)
return reg.low_qword | (reg.high_qword << 64)
if reg_id is x86_const.UC_X86_REG_MSR:
if opt is None:
raise UcError(uc.UC_ERR_ARG)
reg = uc_x86_msr()
reg.rid = opt
status = _uc.uc_reg_read(self._uch, reg_id, ctypes.byref(reg))
if status != uc.UC_ERR_OK:
raise UcError(status)
return reg.value
if self._arch == uc.UC_ARCH_ARM64:
if reg_id in range(arm64_const.UC_ARM64_REG_Q0, arm64_const.UC_ARM64_REG_Q31+1) or range(arm64_const.UC_ARM64_REG_V0, arm64_const.UC_ARM64_REG_V31+1):
reg = uc_arm64_neon128()
status = _uc.uc_reg_read(self._uch, reg_id, ctypes.byref(reg))
if status != uc.UC_ERR_OK:
raise UcError(status)
return reg.low_qword | (reg.high_qword << 64)
# read to 64bit number to be safe
reg = ctypes.c_uint64(0)
@ -330,6 +359,16 @@ class Uc(object):
reg = uc_x86_xmm()
reg.low_qword = value & 0xffffffffffffffff
reg.high_qword = value >> 64
if reg_id is x86_const.UC_X86_REG_MSR:
reg = uc_x86_msr()
reg.rid = value[0]
reg.value = value[1]
if self._arch == uc.UC_ARCH_ARM64:
if reg_id in range(arm64_const.UC_ARM64_REG_Q0, arm64_const.UC_ARM64_REG_Q31+1) or range(arm64_const.UC_ARM64_REG_V0, arm64_const.UC_ARM64_REG_V31+1):
reg = uc_arm64_neon128()
reg.low_qword = value & 0xffffffffffffffff
reg.high_qword = value >> 64
if reg is None:
# convert to 64bit number to be safe
@ -339,6 +378,14 @@ class Uc(object):
if status != uc.UC_ERR_OK:
raise UcError(status)
# read from MSR - X86 only
def msr_read(self, msr_id):
return self.reg_read(x86_const.UC_X86_REG_MSR, msr_id)
# write to MSR - X86 only
def msr_write(self, msr_id, value):
return self.reg_write(x86_const.UC_X86_REG_MSR, (msr_id, value))
# read data from memory
def mem_read(self, address, size):
data = ctypes.create_string_buffer(size)

View File

@ -250,7 +250,8 @@ UC_X86_REG_LDTR = 244
UC_X86_REG_TR = 245
UC_X86_REG_FPCW = 246
UC_X86_REG_FPTAG = 247
UC_X86_REG_ENDING = 248
UC_X86_REG_MSR = 248
UC_X86_REG_ENDING = 249
# X86 instructions

View File

@ -252,7 +252,8 @@ module Unicorn
UC_X86_REG_TR = 245
UC_X86_REG_FPCW = 246
UC_X86_REG_FPTAG = 247
UC_X86_REG_ENDING = 248
UC_X86_REG_MSR = 248
UC_X86_REG_ENDING = 249
# X86 instructions

View File

@ -253,3 +253,4 @@ struct uc_context {
MemoryRegion *memory_mapping(struct uc_struct* uc, uint64_t address);
#endif
/* vim: set ts=4 noet: */

View File

@ -19,64 +19,72 @@ typedef struct uc_x86_mmr {
uint32_t flags; /* not used by GDTR and IDTR */
} uc_x86_mmr;
// Model-Specific Register structure, use this with UC_X86_REG_MSR (as the register ID) in
// call to uc_reg_write/uc_reg_read() to manipulate MSRs.
typedef struct uc_x86_msr {
uint32_t rid; // MSR id
uint64_t value; // MSR value
} uc_x86_msr;
// Callback function for tracing SYSCALL/SYSENTER (for uc_hook_intr())
// @user_data: user data passed to tracing APIs.
typedef void (*uc_cb_insn_syscall_t)(struct uc_struct *uc, void *user_data);
//> X86 registers
typedef enum uc_x86_reg {
UC_X86_REG_INVALID = 0,
UC_X86_REG_AH, UC_X86_REG_AL, UC_X86_REG_AX, UC_X86_REG_BH, UC_X86_REG_BL,
UC_X86_REG_BP, UC_X86_REG_BPL, UC_X86_REG_BX, UC_X86_REG_CH, UC_X86_REG_CL,
UC_X86_REG_CS, UC_X86_REG_CX, UC_X86_REG_DH, UC_X86_REG_DI, UC_X86_REG_DIL,
UC_X86_REG_DL, UC_X86_REG_DS, UC_X86_REG_DX, UC_X86_REG_EAX, UC_X86_REG_EBP,
UC_X86_REG_EBX, UC_X86_REG_ECX, UC_X86_REG_EDI, UC_X86_REG_EDX, UC_X86_REG_EFLAGS,
UC_X86_REG_EIP, UC_X86_REG_EIZ, UC_X86_REG_ES, UC_X86_REG_ESI, UC_X86_REG_ESP,
UC_X86_REG_FPSW, UC_X86_REG_FS, UC_X86_REG_GS, UC_X86_REG_IP, UC_X86_REG_RAX,
UC_X86_REG_RBP, UC_X86_REG_RBX, UC_X86_REG_RCX, UC_X86_REG_RDI, UC_X86_REG_RDX,
UC_X86_REG_RIP, UC_X86_REG_RIZ, UC_X86_REG_RSI, UC_X86_REG_RSP, UC_X86_REG_SI,
UC_X86_REG_SIL, UC_X86_REG_SP, UC_X86_REG_SPL, UC_X86_REG_SS, UC_X86_REG_CR0,
UC_X86_REG_CR1, UC_X86_REG_CR2, UC_X86_REG_CR3, UC_X86_REG_CR4, UC_X86_REG_CR5,
UC_X86_REG_CR6, UC_X86_REG_CR7, UC_X86_REG_CR8, UC_X86_REG_CR9, UC_X86_REG_CR10,
UC_X86_REG_CR11, UC_X86_REG_CR12, UC_X86_REG_CR13, UC_X86_REG_CR14, UC_X86_REG_CR15,
UC_X86_REG_DR0, UC_X86_REG_DR1, UC_X86_REG_DR2, UC_X86_REG_DR3, UC_X86_REG_DR4,
UC_X86_REG_DR5, UC_X86_REG_DR6, UC_X86_REG_DR7, UC_X86_REG_DR8, UC_X86_REG_DR9,
UC_X86_REG_DR10, UC_X86_REG_DR11, UC_X86_REG_DR12, UC_X86_REG_DR13, UC_X86_REG_DR14,
UC_X86_REG_DR15, UC_X86_REG_FP0, UC_X86_REG_FP1, UC_X86_REG_FP2, UC_X86_REG_FP3,
UC_X86_REG_FP4, UC_X86_REG_FP5, UC_X86_REG_FP6, UC_X86_REG_FP7,
UC_X86_REG_K0, UC_X86_REG_K1, UC_X86_REG_K2, UC_X86_REG_K3, UC_X86_REG_K4,
UC_X86_REG_K5, UC_X86_REG_K6, UC_X86_REG_K7, UC_X86_REG_MM0, UC_X86_REG_MM1,
UC_X86_REG_MM2, UC_X86_REG_MM3, UC_X86_REG_MM4, UC_X86_REG_MM5, UC_X86_REG_MM6,
UC_X86_REG_MM7, UC_X86_REG_R8, UC_X86_REG_R9, UC_X86_REG_R10, UC_X86_REG_R11,
UC_X86_REG_R12, UC_X86_REG_R13, UC_X86_REG_R14, UC_X86_REG_R15,
UC_X86_REG_ST0, UC_X86_REG_ST1, UC_X86_REG_ST2, UC_X86_REG_ST3,
UC_X86_REG_ST4, UC_X86_REG_ST5, UC_X86_REG_ST6, UC_X86_REG_ST7,
UC_X86_REG_XMM0, UC_X86_REG_XMM1, UC_X86_REG_XMM2, UC_X86_REG_XMM3, UC_X86_REG_XMM4,
UC_X86_REG_XMM5, UC_X86_REG_XMM6, UC_X86_REG_XMM7, UC_X86_REG_XMM8, UC_X86_REG_XMM9,
UC_X86_REG_XMM10, UC_X86_REG_XMM11, UC_X86_REG_XMM12, UC_X86_REG_XMM13, UC_X86_REG_XMM14,
UC_X86_REG_XMM15, UC_X86_REG_XMM16, UC_X86_REG_XMM17, UC_X86_REG_XMM18, UC_X86_REG_XMM19,
UC_X86_REG_XMM20, UC_X86_REG_XMM21, UC_X86_REG_XMM22, UC_X86_REG_XMM23, UC_X86_REG_XMM24,
UC_X86_REG_XMM25, UC_X86_REG_XMM26, UC_X86_REG_XMM27, UC_X86_REG_XMM28, UC_X86_REG_XMM29,
UC_X86_REG_XMM30, UC_X86_REG_XMM31, UC_X86_REG_YMM0, UC_X86_REG_YMM1, UC_X86_REG_YMM2,
UC_X86_REG_YMM3, UC_X86_REG_YMM4, UC_X86_REG_YMM5, UC_X86_REG_YMM6, UC_X86_REG_YMM7,
UC_X86_REG_YMM8, UC_X86_REG_YMM9, UC_X86_REG_YMM10, UC_X86_REG_YMM11, UC_X86_REG_YMM12,
UC_X86_REG_YMM13, UC_X86_REG_YMM14, UC_X86_REG_YMM15, UC_X86_REG_YMM16, UC_X86_REG_YMM17,
UC_X86_REG_YMM18, UC_X86_REG_YMM19, UC_X86_REG_YMM20, UC_X86_REG_YMM21, UC_X86_REG_YMM22,
UC_X86_REG_YMM23, UC_X86_REG_YMM24, UC_X86_REG_YMM25, UC_X86_REG_YMM26, UC_X86_REG_YMM27,
UC_X86_REG_YMM28, UC_X86_REG_YMM29, UC_X86_REG_YMM30, UC_X86_REG_YMM31, UC_X86_REG_ZMM0,
UC_X86_REG_ZMM1, UC_X86_REG_ZMM2, UC_X86_REG_ZMM3, UC_X86_REG_ZMM4, UC_X86_REG_ZMM5,
UC_X86_REG_ZMM6, UC_X86_REG_ZMM7, UC_X86_REG_ZMM8, UC_X86_REG_ZMM9, UC_X86_REG_ZMM10,
UC_X86_REG_ZMM11, UC_X86_REG_ZMM12, UC_X86_REG_ZMM13, UC_X86_REG_ZMM14, UC_X86_REG_ZMM15,
UC_X86_REG_ZMM16, UC_X86_REG_ZMM17, UC_X86_REG_ZMM18, UC_X86_REG_ZMM19, UC_X86_REG_ZMM20,
UC_X86_REG_ZMM21, UC_X86_REG_ZMM22, UC_X86_REG_ZMM23, UC_X86_REG_ZMM24, UC_X86_REG_ZMM25,
UC_X86_REG_ZMM26, UC_X86_REG_ZMM27, UC_X86_REG_ZMM28, UC_X86_REG_ZMM29, UC_X86_REG_ZMM30,
UC_X86_REG_ZMM31, UC_X86_REG_R8B, UC_X86_REG_R9B, UC_X86_REG_R10B, UC_X86_REG_R11B,
UC_X86_REG_R12B, UC_X86_REG_R13B, UC_X86_REG_R14B, UC_X86_REG_R15B, UC_X86_REG_R8D,
UC_X86_REG_R9D, UC_X86_REG_R10D, UC_X86_REG_R11D, UC_X86_REG_R12D, UC_X86_REG_R13D,
UC_X86_REG_R14D, UC_X86_REG_R15D, UC_X86_REG_R8W, UC_X86_REG_R9W, UC_X86_REG_R10W,
UC_X86_REG_R11W, UC_X86_REG_R12W, UC_X86_REG_R13W, UC_X86_REG_R14W, UC_X86_REG_R15W,
UC_X86_REG_IDTR, UC_X86_REG_GDTR, UC_X86_REG_LDTR, UC_X86_REG_TR, UC_X86_REG_FPCW,
UC_X86_REG_FPTAG,
UC_X86_REG_INVALID = 0,
UC_X86_REG_AH, UC_X86_REG_AL, UC_X86_REG_AX, UC_X86_REG_BH, UC_X86_REG_BL,
UC_X86_REG_BP, UC_X86_REG_BPL, UC_X86_REG_BX, UC_X86_REG_CH, UC_X86_REG_CL,
UC_X86_REG_CS, UC_X86_REG_CX, UC_X86_REG_DH, UC_X86_REG_DI, UC_X86_REG_DIL,
UC_X86_REG_DL, UC_X86_REG_DS, UC_X86_REG_DX, UC_X86_REG_EAX, UC_X86_REG_EBP,
UC_X86_REG_EBX, UC_X86_REG_ECX, UC_X86_REG_EDI, UC_X86_REG_EDX, UC_X86_REG_EFLAGS,
UC_X86_REG_EIP, UC_X86_REG_EIZ, UC_X86_REG_ES, UC_X86_REG_ESI, UC_X86_REG_ESP,
UC_X86_REG_FPSW, UC_X86_REG_FS, UC_X86_REG_GS, UC_X86_REG_IP, UC_X86_REG_RAX,
UC_X86_REG_RBP, UC_X86_REG_RBX, UC_X86_REG_RCX, UC_X86_REG_RDI, UC_X86_REG_RDX,
UC_X86_REG_RIP, UC_X86_REG_RIZ, UC_X86_REG_RSI, UC_X86_REG_RSP, UC_X86_REG_SI,
UC_X86_REG_SIL, UC_X86_REG_SP, UC_X86_REG_SPL, UC_X86_REG_SS, UC_X86_REG_CR0,
UC_X86_REG_CR1, UC_X86_REG_CR2, UC_X86_REG_CR3, UC_X86_REG_CR4, UC_X86_REG_CR5,
UC_X86_REG_CR6, UC_X86_REG_CR7, UC_X86_REG_CR8, UC_X86_REG_CR9, UC_X86_REG_CR10,
UC_X86_REG_CR11, UC_X86_REG_CR12, UC_X86_REG_CR13, UC_X86_REG_CR14, UC_X86_REG_CR15,
UC_X86_REG_DR0, UC_X86_REG_DR1, UC_X86_REG_DR2, UC_X86_REG_DR3, UC_X86_REG_DR4,
UC_X86_REG_DR5, UC_X86_REG_DR6, UC_X86_REG_DR7, UC_X86_REG_DR8, UC_X86_REG_DR9,
UC_X86_REG_DR10, UC_X86_REG_DR11, UC_X86_REG_DR12, UC_X86_REG_DR13, UC_X86_REG_DR14,
UC_X86_REG_DR15, UC_X86_REG_FP0, UC_X86_REG_FP1, UC_X86_REG_FP2, UC_X86_REG_FP3,
UC_X86_REG_FP4, UC_X86_REG_FP5, UC_X86_REG_FP6, UC_X86_REG_FP7,
UC_X86_REG_K0, UC_X86_REG_K1, UC_X86_REG_K2, UC_X86_REG_K3, UC_X86_REG_K4,
UC_X86_REG_K5, UC_X86_REG_K6, UC_X86_REG_K7, UC_X86_REG_MM0, UC_X86_REG_MM1,
UC_X86_REG_MM2, UC_X86_REG_MM3, UC_X86_REG_MM4, UC_X86_REG_MM5, UC_X86_REG_MM6,
UC_X86_REG_MM7, UC_X86_REG_R8, UC_X86_REG_R9, UC_X86_REG_R10, UC_X86_REG_R11,
UC_X86_REG_R12, UC_X86_REG_R13, UC_X86_REG_R14, UC_X86_REG_R15,
UC_X86_REG_ST0, UC_X86_REG_ST1, UC_X86_REG_ST2, UC_X86_REG_ST3,
UC_X86_REG_ST4, UC_X86_REG_ST5, UC_X86_REG_ST6, UC_X86_REG_ST7,
UC_X86_REG_XMM0, UC_X86_REG_XMM1, UC_X86_REG_XMM2, UC_X86_REG_XMM3, UC_X86_REG_XMM4,
UC_X86_REG_XMM5, UC_X86_REG_XMM6, UC_X86_REG_XMM7, UC_X86_REG_XMM8, UC_X86_REG_XMM9,
UC_X86_REG_XMM10, UC_X86_REG_XMM11, UC_X86_REG_XMM12, UC_X86_REG_XMM13, UC_X86_REG_XMM14,
UC_X86_REG_XMM15, UC_X86_REG_XMM16, UC_X86_REG_XMM17, UC_X86_REG_XMM18, UC_X86_REG_XMM19,
UC_X86_REG_XMM20, UC_X86_REG_XMM21, UC_X86_REG_XMM22, UC_X86_REG_XMM23, UC_X86_REG_XMM24,
UC_X86_REG_XMM25, UC_X86_REG_XMM26, UC_X86_REG_XMM27, UC_X86_REG_XMM28, UC_X86_REG_XMM29,
UC_X86_REG_XMM30, UC_X86_REG_XMM31, UC_X86_REG_YMM0, UC_X86_REG_YMM1, UC_X86_REG_YMM2,
UC_X86_REG_YMM3, UC_X86_REG_YMM4, UC_X86_REG_YMM5, UC_X86_REG_YMM6, UC_X86_REG_YMM7,
UC_X86_REG_YMM8, UC_X86_REG_YMM9, UC_X86_REG_YMM10, UC_X86_REG_YMM11, UC_X86_REG_YMM12,
UC_X86_REG_YMM13, UC_X86_REG_YMM14, UC_X86_REG_YMM15, UC_X86_REG_YMM16, UC_X86_REG_YMM17,
UC_X86_REG_YMM18, UC_X86_REG_YMM19, UC_X86_REG_YMM20, UC_X86_REG_YMM21, UC_X86_REG_YMM22,
UC_X86_REG_YMM23, UC_X86_REG_YMM24, UC_X86_REG_YMM25, UC_X86_REG_YMM26, UC_X86_REG_YMM27,
UC_X86_REG_YMM28, UC_X86_REG_YMM29, UC_X86_REG_YMM30, UC_X86_REG_YMM31, UC_X86_REG_ZMM0,
UC_X86_REG_ZMM1, UC_X86_REG_ZMM2, UC_X86_REG_ZMM3, UC_X86_REG_ZMM4, UC_X86_REG_ZMM5,
UC_X86_REG_ZMM6, UC_X86_REG_ZMM7, UC_X86_REG_ZMM8, UC_X86_REG_ZMM9, UC_X86_REG_ZMM10,
UC_X86_REG_ZMM11, UC_X86_REG_ZMM12, UC_X86_REG_ZMM13, UC_X86_REG_ZMM14, UC_X86_REG_ZMM15,
UC_X86_REG_ZMM16, UC_X86_REG_ZMM17, UC_X86_REG_ZMM18, UC_X86_REG_ZMM19, UC_X86_REG_ZMM20,
UC_X86_REG_ZMM21, UC_X86_REG_ZMM22, UC_X86_REG_ZMM23, UC_X86_REG_ZMM24, UC_X86_REG_ZMM25,
UC_X86_REG_ZMM26, UC_X86_REG_ZMM27, UC_X86_REG_ZMM28, UC_X86_REG_ZMM29, UC_X86_REG_ZMM30,
UC_X86_REG_ZMM31, UC_X86_REG_R8B, UC_X86_REG_R9B, UC_X86_REG_R10B, UC_X86_REG_R11B,
UC_X86_REG_R12B, UC_X86_REG_R13B, UC_X86_REG_R14B, UC_X86_REG_R15B, UC_X86_REG_R8D,
UC_X86_REG_R9D, UC_X86_REG_R10D, UC_X86_REG_R11D, UC_X86_REG_R12D, UC_X86_REG_R13D,
UC_X86_REG_R14D, UC_X86_REG_R15D, UC_X86_REG_R8W, UC_X86_REG_R9W, UC_X86_REG_R10W,
UC_X86_REG_R11W, UC_X86_REG_R12W, UC_X86_REG_R13W, UC_X86_REG_R14W, UC_X86_REG_R15W,
UC_X86_REG_IDTR, UC_X86_REG_GDTR, UC_X86_REG_LDTR, UC_X86_REG_TR, UC_X86_REG_FPCW,
UC_X86_REG_FPTAG,
UC_X86_REG_MSR, // Model-Specific Register
UC_X86_REG_ENDING // <-- mark the end of the list of registers
} uc_x86_reg;

View File

@ -2,6 +2,7 @@
#ifndef UNICORN_AUTOGEN_AARCH64_H
#define UNICORN_AUTOGEN_AARCH64_H
#define aarch64_tb_set_jmp_target aarch64_tb_set_jmp_target_aarch64
#define ppc_tb_set_jmp_target ppc_tb_set_jmp_target_aarch64
#define use_idiv_instructions_rt use_idiv_instructions_rt_aarch64
#define tcg_target_deposit_valid tcg_target_deposit_valid_aarch64
#define helper_power_down helper_power_down_aarch64

View File

@ -2,6 +2,7 @@
#ifndef UNICORN_AUTOGEN_ARM_H
#define UNICORN_AUTOGEN_ARM_H
#define aarch64_tb_set_jmp_target aarch64_tb_set_jmp_target_arm
#define ppc_tb_set_jmp_target ppc_tb_set_jmp_target_arm
#define use_idiv_instructions_rt use_idiv_instructions_rt_arm
#define tcg_target_deposit_valid tcg_target_deposit_valid_arm
#define helper_power_down helper_power_down_arm

View File

@ -8,6 +8,7 @@ import sys
symbols = (
'aarch64_tb_set_jmp_target',
'ppc_tb_set_jmp_target',
'use_idiv_instructions_rt',
'tcg_target_deposit_valid',
'helper_power_down',

View File

@ -126,11 +126,15 @@
/* Bits present in AT_HWCAP for Sparc. */
#define HWCAP_SPARC_VIS3 0x00020000
/* Bits present in AT_HWCAP for PowerPC. */
#define PPC_FEATURE_ARCH_2_06 0x00000100
/* Symbolic values for the entries in the auxiliary table
put on the initial stack */
#define AT_PLATFORM 15 /* string identifying CPU for optimizations */
#define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */
#define AT_DCACHEBSIZE 19 /* data cache block size */
#define AT_ICACHEBSIZE 20 /* instruction cache block size */
/*
* 68k ELF relocation types

View File

@ -2,6 +2,7 @@
#ifndef UNICORN_AUTOGEN_M68K_H
#define UNICORN_AUTOGEN_M68K_H
#define aarch64_tb_set_jmp_target aarch64_tb_set_jmp_target_m68k
#define ppc_tb_set_jmp_target ppc_tb_set_jmp_target_m68k
#define use_idiv_instructions_rt use_idiv_instructions_rt_m68k
#define tcg_target_deposit_valid tcg_target_deposit_valid_m68k
#define helper_power_down helper_power_down_m68k

View File

@ -2,6 +2,7 @@
#ifndef UNICORN_AUTOGEN_MIPS_H
#define UNICORN_AUTOGEN_MIPS_H
#define aarch64_tb_set_jmp_target aarch64_tb_set_jmp_target_mips
#define ppc_tb_set_jmp_target ppc_tb_set_jmp_target_mips
#define use_idiv_instructions_rt use_idiv_instructions_rt_mips
#define tcg_target_deposit_valid tcg_target_deposit_valid_mips
#define helper_power_down helper_power_down_mips

View File

@ -2,6 +2,7 @@
#ifndef UNICORN_AUTOGEN_MIPS64_H
#define UNICORN_AUTOGEN_MIPS64_H
#define aarch64_tb_set_jmp_target aarch64_tb_set_jmp_target_mips64
#define ppc_tb_set_jmp_target ppc_tb_set_jmp_target_mips64
#define use_idiv_instructions_rt use_idiv_instructions_rt_mips64
#define tcg_target_deposit_valid tcg_target_deposit_valid_mips64
#define helper_power_down helper_power_down_mips64

View File

@ -2,6 +2,7 @@
#ifndef UNICORN_AUTOGEN_MIPS64EL_H
#define UNICORN_AUTOGEN_MIPS64EL_H
#define aarch64_tb_set_jmp_target aarch64_tb_set_jmp_target_mips64el
#define ppc_tb_set_jmp_target ppc_tb_set_jmp_target_mips64el
#define use_idiv_instructions_rt use_idiv_instructions_rt_mips64el
#define tcg_target_deposit_valid tcg_target_deposit_valid_mips64el
#define helper_power_down helper_power_down_mips64el

View File

@ -2,6 +2,7 @@
#ifndef UNICORN_AUTOGEN_MIPSEL_H
#define UNICORN_AUTOGEN_MIPSEL_H
#define aarch64_tb_set_jmp_target aarch64_tb_set_jmp_target_mipsel
#define ppc_tb_set_jmp_target ppc_tb_set_jmp_target_mipsel
#define use_idiv_instructions_rt use_idiv_instructions_rt_mipsel
#define tcg_target_deposit_valid tcg_target_deposit_valid_mipsel
#define helper_power_down helper_power_down_mipsel

View File

@ -2,6 +2,7 @@
#ifndef UNICORN_AUTOGEN_POWERPC_H
#define UNICORN_AUTOGEN_POWERPC_H
#define aarch64_tb_set_jmp_target aarch64_tb_set_jmp_target_powerpc
#define ppc_tb_set_jmp_target ppc_tb_set_jmp_target_powerpc
#define use_idiv_instructions_rt use_idiv_instructions_rt_powerpc
#define tcg_target_deposit_valid tcg_target_deposit_valid_powerpc
#define helper_power_down helper_power_down_powerpc

View File

@ -2,6 +2,7 @@
#ifndef UNICORN_AUTOGEN_SPARC_H
#define UNICORN_AUTOGEN_SPARC_H
#define aarch64_tb_set_jmp_target aarch64_tb_set_jmp_target_sparc
#define ppc_tb_set_jmp_target ppc_tb_set_jmp_target_sparc
#define use_idiv_instructions_rt use_idiv_instructions_rt_sparc
#define tcg_target_deposit_valid tcg_target_deposit_valid_sparc
#define helper_power_down helper_power_down_sparc

View File

@ -2,6 +2,7 @@
#ifndef UNICORN_AUTOGEN_SPARC64_H
#define UNICORN_AUTOGEN_SPARC64_H
#define aarch64_tb_set_jmp_target aarch64_tb_set_jmp_target_sparc64
#define ppc_tb_set_jmp_target ppc_tb_set_jmp_target_sparc64
#define use_idiv_instructions_rt use_idiv_instructions_rt_sparc64
#define tcg_target_deposit_valid tcg_target_deposit_valid_sparc64
#define helper_power_down helper_power_down_sparc64

View File

@ -52,10 +52,27 @@ int arm64_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int co
for (i = 0; i < count; i++) {
unsigned int regid = regs[i];
void *value = vals[i];
// V & Q registers are the same
if (regid >= UC_ARM64_REG_V0 && regid <= UC_ARM64_REG_V31) {
regid += UC_ARM64_REG_Q0 - UC_ARM64_REG_V0;
}
if (regid >= UC_ARM64_REG_X0 && regid <= UC_ARM64_REG_X28) {
*(int64_t *)value = ARM_CPU(uc, mycpu)->env.xregs[regid - UC_ARM64_REG_X0];
} else if (regid >= UC_ARM64_REG_W0 && regid <= UC_ARM64_REG_W30) {
*(int32_t *)value = READ_DWORD(ARM_CPU(uc, mycpu)->env.xregs[regid - UC_ARM64_REG_W0]);
} else if (regid >= UC_ARM64_REG_Q0 && regid <= UC_ARM64_REG_Q31) {
float64 *dst = (float64*) value;
uint32_t reg_index = 2*(regid - UC_ARM64_REG_Q0);
dst[0] = ARM_CPU(uc, mycpu)->env.vfp.regs[reg_index];
dst[1] = ARM_CPU(uc, mycpu)->env.vfp.regs[reg_index+1];
} else if (regid >= UC_ARM64_REG_D0 && regid <= UC_ARM64_REG_D31) {
*(float64*)value = ARM_CPU(uc, mycpu)->env.vfp.regs[2*(regid - UC_ARM64_REG_D0)];
} else if (regid >= UC_ARM64_REG_S0 && regid <= UC_ARM64_REG_S31) {
*(int32_t*)value = READ_DWORD(ARM_CPU(uc, mycpu)->env.vfp.regs[2*(regid - UC_ARM64_REG_S0)]);
} else if (regid >= UC_ARM64_REG_H0 && regid <= UC_ARM64_REG_H31) {
*(int16_t*)value = READ_WORD(ARM_CPU(uc, mycpu)->env.vfp.regs[2*(regid - UC_ARM64_REG_H0)]);
} else if (regid >= UC_ARM64_REG_B0 && regid <= UC_ARM64_REG_B31) {
*(int8_t*)value = READ_BYTE_L(ARM_CPU(uc, mycpu)->env.vfp.regs[2*(regid - UC_ARM64_REG_B0)]);
} else {
switch(regid) {
default: break;
@ -86,10 +103,26 @@ int arm64_reg_write(struct uc_struct *uc, unsigned int *regs, void* const* vals,
for (i = 0; i < count; i++) {
unsigned int regid = regs[i];
const void *value = vals[i];
if (regid >= UC_ARM64_REG_V0 && regid <= UC_ARM64_REG_V31) {
regid += UC_ARM64_REG_Q0 - UC_ARM64_REG_V0;
}
if (regid >= UC_ARM64_REG_X0 && regid <= UC_ARM64_REG_X28) {
ARM_CPU(uc, mycpu)->env.xregs[regid - UC_ARM64_REG_X0] = *(uint64_t *)value;
} else if (regid >= UC_ARM64_REG_W0 && regid <= UC_ARM64_REG_W30) {
WRITE_DWORD(ARM_CPU(uc, mycpu)->env.xregs[regid - UC_ARM64_REG_W0], *(uint32_t *)value);
} else if (regid >= UC_ARM64_REG_Q0 && regid <= UC_ARM64_REG_Q31) {
float64 *src = (float64*) value;
uint32_t reg_index = 2*(regid - UC_ARM64_REG_Q0);
ARM_CPU(uc, mycpu)->env.vfp.regs[reg_index] = src[0];
ARM_CPU(uc, mycpu)->env.vfp.regs[reg_index+1] = src[1];
} else if (regid >= UC_ARM64_REG_D0 && regid <= UC_ARM64_REG_D31) {
ARM_CPU(uc, mycpu)->env.vfp.regs[2*(regid - UC_ARM64_REG_D0)] = * (float64*) value;
} else if (regid >= UC_ARM64_REG_S0 && regid <= UC_ARM64_REG_S31) {
WRITE_DWORD(ARM_CPU(uc, mycpu)->env.vfp.regs[2*(regid - UC_ARM64_REG_S0)], *(int32_t*) value);
} else if (regid >= UC_ARM64_REG_H0 && regid <= UC_ARM64_REG_H31) {
WRITE_WORD(ARM_CPU(uc, mycpu)->env.vfp.regs[2*(regid - UC_ARM64_REG_H0)], *(int16_t*) value);
} else if (regid >= UC_ARM64_REG_B0 && regid <= UC_ARM64_REG_B31) {
WRITE_BYTE_L(ARM_CPU(uc, mycpu)->env.vfp.regs[2*(regid - UC_ARM64_REG_B0)], *(int8_t*) value);
} else {
switch(regid) {
default: break;

View File

@ -64,6 +64,9 @@ int arm_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int coun
*(float64 *)value = ARM_CPU(uc, mycpu)->env.vfp.regs[regid - UC_ARM_REG_D0];
else {
switch(regid) {
case UC_ARM_REG_APSR:
*(int32_t *)value = cpsr_read(&ARM_CPU(uc, mycpu)->env) & CPSR_NZCV;
break;
case UC_ARM_REG_CPSR:
*(int32_t *)value = cpsr_read(&ARM_CPU(uc, mycpu)->env);
break;
@ -109,6 +112,9 @@ int arm_reg_write(struct uc_struct *uc, unsigned int *regs, void* const* vals, i
ARM_CPU(uc, mycpu)->env.vfp.regs[regid - UC_ARM_REG_D0] = *(float64 *)value;
else {
switch(regid) {
case UC_ARM_REG_APSR:
cpsr_write(&ARM_CPU(uc, mycpu)->env, *(uint32_t *)value, CPSR_NZCV);
break;
case UC_ARM_REG_CPSR:
cpsr_write(&ARM_CPU(uc, mycpu)->env, *(uint32_t *)value, ~0);
break;

View File

@ -17,6 +17,10 @@ static void load_seg_16_helper(CPUX86State *env, int seg, uint32_t selector)
cpu_x86_load_seg_cache(env, seg, selector, (selector << 4), 0xffff, X86_NON_CS_FLAGS);
}
extern void helper_wrmsr(CPUX86State *env);
extern void helper_rdmsr(CPUX86State *env);
const int X86_REGS_STORAGE_SIZE = offsetof(CPUX86State, tlb_table);
static void x86_set_pc(struct uc_struct *uc, uint64_t address)
@ -156,6 +160,49 @@ void x86_reg_reset(struct uc_struct *uc)
}
}
static int x86_msr_read(struct uc_struct *uc, uc_x86_msr *msr)
{
CPUX86State *env = (CPUX86State *)uc->cpu->env_ptr;
uint64_t ecx = env->regs[R_ECX];
uint64_t eax = env->regs[R_EAX];
uint64_t edx = env->regs[R_EDX];
env->regs[R_ECX] = msr->rid;
helper_rdmsr(env);
msr->value = ((uint32_t)env->regs[R_EAX]) |
((uint64_t)((uint32_t)env->regs[R_EDX]) << 32);
env->regs[R_EAX] = eax;
env->regs[R_ECX] = ecx;
env->regs[R_EDX] = edx;
/* The implementation doesn't throw exception or return an error if there is one, so
* we will return 0. */
return 0;
}
static int x86_msr_write(struct uc_struct *uc, uc_x86_msr *msr)
{
CPUX86State *env = (CPUX86State *)uc->cpu->env_ptr;
uint64_t ecx = env->regs[R_ECX];
uint64_t eax = env->regs[R_EAX];
uint64_t edx = env->regs[R_EDX];
env->regs[R_ECX] = msr->rid;
env->regs[R_EAX] = (unsigned int)msr->value;
env->regs[R_EDX] = (unsigned int)(msr->value >> 32);
helper_wrmsr(env);
env->regs[R_ECX] = ecx;
env->regs[R_EAX] = eax;
env->regs[R_EDX] = edx;
/* The implementation doesn't throw exception or return an error if there is one, so
* we will return 0. */
return 0;
}
int x86_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int count)
{
CPUState *mycpu = uc->cpu;
@ -401,6 +448,9 @@ int x86_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int coun
((uc_x86_mmr *)value)->selector = (uint16_t)X86_CPU(uc, mycpu)->env.tr.selector;
((uc_x86_mmr *)value)->flags = X86_CPU(uc, mycpu)->env.tr.flags;
break;
case UC_X86_REG_MSR:
x86_msr_read(uc, (uc_x86_msr *)value);
break;
}
break;
@ -680,6 +730,9 @@ int x86_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int coun
((uc_x86_mmr *)value)->selector = (uint16_t)X86_CPU(uc, mycpu)->env.tr.selector;
((uc_x86_mmr *)value)->flags = X86_CPU(uc, mycpu)->env.tr.flags;
break;
case UC_X86_REG_MSR:
x86_msr_read(uc, (uc_x86_msr *)value);
break;
}
break;
#endif
@ -924,6 +977,9 @@ int x86_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, i
X86_CPU(uc, mycpu)->env.tr.selector = (uint16_t)((uc_x86_mmr *)value)->selector;
X86_CPU(uc, mycpu)->env.tr.flags = ((uc_x86_mmr *)value)->flags;
break;
case UC_X86_REG_MSR:
x86_msr_write(uc, (uc_x86_msr *)value);
break;
}
break;
@ -1213,6 +1269,9 @@ int x86_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, i
X86_CPU(uc, mycpu)->env.tr.selector = (uint16_t)((uc_x86_mmr *)value)->selector;
X86_CPU(uc, mycpu)->env.tr.flags = ((uc_x86_mmr *)value)->flags;
break;
case UC_X86_REG_MSR:
x86_msr_write(uc, (uc_x86_msr *)value);
break;
}
break;
#endif
@ -1257,3 +1316,5 @@ void x86_uc_init(struct uc_struct* uc)
uc->stop_interrupt = x86_stop_interrupt;
uc_common_init(uc);
}
/* vim: set ts=4 sts=4 sw=4 et: */

View File

@ -18,6 +18,12 @@ const int MIPS_REGS_STORAGE_SIZE = offsetof(CPUMIPSState, tlb_table);
#endif
#endif
#ifdef TARGET_MIPS64
typedef uint64_t mipsreg_t;
#else
typedef uint32_t mipsreg_t;
#endif
static uint64_t mips_mem_redirect(uint64_t address)
{
// kseg0 range masks off high address bit
@ -91,7 +97,7 @@ int mips_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int cou
switch(regid) {
default: break;
case UC_MIPS_REG_PC:
*(int32_t *)value = MIPS_CPU(uc, mycpu)->env.active_tc.PC;
*(mipsreg_t *)value = MIPS_CPU(uc, mycpu)->env.active_tc.PC;
break;
}
}
@ -109,12 +115,12 @@ int mips_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals,
unsigned int regid = regs[i];
const void *value = vals[i];
if (regid >= UC_MIPS_REG_0 && regid <= UC_MIPS_REG_31)
MIPS_CPU(uc, mycpu)->env.active_tc.gpr[regid - UC_MIPS_REG_0] = *(uint32_t *)value;
MIPS_CPU(uc, mycpu)->env.active_tc.gpr[regid - UC_MIPS_REG_0] = *(mipsreg_t *)value;
else {
switch(regid) {
default: break;
case UC_MIPS_REG_PC:
MIPS_CPU(uc, mycpu)->env.active_tc.PC = *(uint32_t *)value;
MIPS_CPU(uc, mycpu)->env.active_tc.PC = *(mipsreg_t *)value;
// force to quit execution and flush TB
uc->quit_request = true;
uc_emu_stop(uc);

View File

@ -717,8 +717,8 @@ void tcg_gen_callN(TCGContext *s, void *func, TCGArg ret,
int is_64bit = sizemask & (1 << (i+1)*2);
if (is_64bit) {
TCGv_i64 orig = MAKE_TCGV_I64(args[i]);
TCGv_i32 h = tcg_temp_new_i32();
TCGv_i32 l = tcg_temp_new_i32();
TCGv_i32 h = tcg_temp_new_i32(s);
TCGv_i32 l = tcg_temp_new_i32(s);
tcg_gen_extr_i64_i32(l, h, orig);
split_args[real_args++] = GET_TCGV_I32(h);
split_args[real_args++] = GET_TCGV_I32(l);
@ -738,9 +738,9 @@ void tcg_gen_callN(TCGContext *s, void *func, TCGArg ret,
TCGv_i64 temp = tcg_temp_new_i64(s);
TCGv_i64 orig = MAKE_TCGV_I64(args[i]);
if (is_signed) {
tcg_gen_ext32s_i64(temp, orig);
tcg_gen_ext32s_i64(s, temp, orig);
} else {
tcg_gen_ext32u_i64(temp, orig);
tcg_gen_ext32u_i64(s, temp, orig);
}
args[i] = GET_TCGV_I64(temp);
}
@ -834,8 +834,8 @@ void tcg_gen_callN(TCGContext *s, void *func, TCGArg ret,
if (is_64bit) {
TCGv_i32 h = MAKE_TCGV_I32(args[real_args++]);
TCGv_i32 l = MAKE_TCGV_I32(args[real_args++]);
tcg_temp_free_i32(h);
tcg_temp_free_i32(l);
tcg_temp_free_i32(s, h);
tcg_temp_free_i32(s, l);
} else {
real_args++;
}
@ -845,15 +845,15 @@ void tcg_gen_callN(TCGContext *s, void *func, TCGArg ret,
Note that describing these as TCGv_i64 eliminates an unnecessary
zero-extension that tcg_gen_concat_i32_i64 would create. */
tcg_gen_concat32_i64(MAKE_TCGV_I64(ret), retl, reth);
tcg_temp_free_i64(retl);
tcg_temp_free_i64(reth);
tcg_temp_free_i64(s, retl);
tcg_temp_free_i64(s, reth);
}
#elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
for (i = 0; i < nargs; ++i) {
int is_64bit = sizemask & (1 << (i+1)*2);
if (!is_64bit) {
TCGv_i64 temp = MAKE_TCGV_I64(args[i]);
tcg_temp_free_i64(temp);
tcg_temp_free_i64(s, temp);
}
}
#endif /* TCG_TARGET_EXTEND_ARGS */

View File

@ -2,6 +2,7 @@
#ifndef UNICORN_AUTOGEN_X86_64_H
#define UNICORN_AUTOGEN_X86_64_H
#define aarch64_tb_set_jmp_target aarch64_tb_set_jmp_target_x86_64
#define ppc_tb_set_jmp_target ppc_tb_set_jmp_target_x86_64
#define use_idiv_instructions_rt use_idiv_instructions_rt_x86_64
#define tcg_target_deposit_valid tcg_target_deposit_valid_x86_64
#define helper_power_down helper_power_down_x86_64

View File

@ -42,3 +42,18 @@ if test -e $DIR/sample_m68k; then
echo "=========================="
$DIR/sample_m68k
fi
if test -e $DIR/mem_apis; then
echo "=========================="
$DIR/mem_apis
fi
if test -e $DIR/sample_batch_reg; then
echo "=========================="
$DIR/sample_batch_reg
fi
if test -e $DIR/sample_x86_32_gdt_and_seg_regs; then
echo "=========================="
$DIR/sample_x86_32_gdt_and_seg_regs
fi

View File

@ -1,5 +1,6 @@
!*.c
arm_enable_vfp
map_crash
sigill
sigill2

View File

@ -23,26 +23,32 @@ typedef uint64_t puint;
uint32_t realEflags()
{
puint val = 0;
puint i = 0xFFFFFEFF; //attempt to set ALL bits except trap flag.
#if defined(__i386__)
puint i = 0xFFFFFEFF; //attempt to set ALL bits except trap flag.
__asm__("pushf\n\t"
"push %0\n\t"
"popf\n\t"
"pushf\n\t"
"pop %0\n\t"
"popf"
#else
: "=r"(val)
: "r"(i)
: "%0");
#elif defined(__x86_64__)
puint i = 0xFFFFFEFF; //attempt to set ALL bits except trap flag.
__asm__("pushfq\n\t"
"pushq %0\n\t"
"popfq\n\t"
"pushfq\n\t"
"popq %0\n\t"
"popfq"
#endif
: "=r"(val)
: "r"(i)
: "%0");
#endif
printf("Real system eflags: 0x%08"PRIX3264"\n", val);
@ -51,7 +57,7 @@ uint32_t realEflags()
static void VM_exec()
{
#if defined(__i386__) || defined(__x86_64__)
uc_engine *uc;
uc_err err;
unsigned int r_eax, eflags, r_esp, realflags = 0;
@ -110,6 +116,7 @@ static void VM_exec()
realflags = realEflags();
assert(r_eax == realflags);
#endif
}
int main(int argc, char *argv[])

2
uc.c
View File

@ -380,14 +380,12 @@ uc_err uc_reg_read(uc_engine *uc, int regid, void *value)
return uc_reg_read_batch(uc, &regid, &value, 1);
}
UNICORN_EXPORT
uc_err uc_reg_write(uc_engine *uc, int regid, const void *value)
{
return uc_reg_write_batch(uc, &regid, (void *const *)&value, 1);
}
// check if a memory area is mapped
// this is complicated because an area can overlap adjacent blocks
static bool check_mem_area(uc_engine *uc, uint64_t address, size_t size)