fix rust bindings build on windows (#1584)

Refine rust bindings.
This commit is contained in:
shuffle2 2022-04-16 04:40:04 -07:00 committed by GitHub
parent 9620514b68
commit 2912cd1e29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 268 additions and 320 deletions

View File

@ -25,22 +25,22 @@ jobs:
fail-fast: false
matrix:
config:
- {
- {
os: windows-2019,
arch: x64,
name: 'Windows x86_64'
}
- {
- {
os: windows-2019,
arch: x86,
name: 'Windows x86'
}
- {
- {
os: ubuntu-latest,
arch: x64,
name: 'Ubuntu x86_64'
}
- {
- {
os: macos-latest,
arch: x64,
name: 'macOS x86_64'
@ -69,15 +69,13 @@ jobs:
- name: '🚧 Cargo test'
if: "!startsWith(github.ref, 'refs/tags')"
env:
UNICORN_LOCAL: uc
run: |
cd bindings/rust && cargo test
cargo test
- name: '📦 Cargo Publish'
if: startsWith(github.ref, 'refs/tags') && contains(matrix.config.os, 'ubuntu')
env:
TOKEN: ${{ secrets.cratesio_token }}
UNICORN_VERSION: dev
run: |
cd bindings/rust && cargo login $TOKEN && cargo test && cargo publish
cargo login $TOKEN && cargo test && cargo publish

22
.gitignore vendored
View File

@ -12,23 +12,7 @@
*.jar
*~
qemu/aarch64-softmmu/
qemu/aarch64eb-softmmu/
qemu/arm-softmmu/
qemu/armeb-softmmu/
qemu/m68k-softmmu/
qemu/mips64el-softmmu/
qemu/mips64-softmmu/
qemu/mipsel-softmmu/
qemu/mips-softmmu/
qemu/sparc64-softmmu/
qemu/sparc-softmmu/
qemu/i386-softmmu/
qemu/x86_64-softmmu/
qemu/ppc-softmmu/
qemu/ppc64-softmmu/
qemu/riscv32-softmmu/
qemu/riscv64-softmmu/
qemu/*-softmmu/
tags
qemu/config-host.ld
@ -68,8 +52,8 @@ bindings/python/unicorn.egg-info/
bindings/python/unicorn/lib/
bindings/python/unicorn/include/
bindings/python/MANIFEST
bindings/rust/target/
bindings/rust/Cargo.lock
target/
Cargo.lock
config.log

View File

@ -3,6 +3,18 @@
cmake_minimum_required(VERSION 3.1)
if(MSVC)
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.15")
# set all policies to max supported by actual running cmake version
# mainly want the following:
# CMP0091: prevent msvcrt flags being added to default CMAKE_<LANG>_FLAGS_<CONFIG>
# CMP0092: prevent warning flags being added to default CMAKE_<LANG>_FLAGS
cmake_policy(VERSION ${CMAKE_VERSION})
else()
message(FATAL_ERROR "please update cmake")
endif()
endif()
# Workaround to fix wrong compiler on macos.
if(APPLE AND NOT CMAKE_C_COMPILER)
set(CMAKE_C_COMPILER "/usr/bin/cc")
@ -12,13 +24,16 @@ endif()
set(PROJECT_IS_TOP_LEVEL OFF)
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
set(PROJECT_IS_TOP_LEVEL ON)
# Enable folder support
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
endif()
project(unicorn C)
# mainline qemu mostly just uses compiler default
set(CMAKE_C_STANDARD 11)
set(UNICORN_VERSION_MAJOR 2)
set(UNICORN_VERSION_MINOR 0)
set(UNICORN_VERSION_PATCH 0)
@ -63,6 +78,7 @@ if(MSVC)
else()
message(FATAL_ERROR "Neither WIN64 or WIN32!")
endif()
add_compile_options(
-Dinline=__inline
-D__func__=__FUNCTION__
@ -71,22 +87,30 @@ if(MSVC)
${MSVC_FLAG}
/I${CMAKE_CURRENT_SOURCE_DIR}/qemu/tcg/i386
)
# Disable some warnings
add_compile_options(
/wd4018
/wd4098
/wd4244
/wd4267
)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
string(REPLACE "/ZI" "/Zi" CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG})
add_compile_options($<$<COMPILE_LANGUAGE:C>:/wd4018>)
add_compile_options($<$<COMPILE_LANGUAGE:C>:/wd4098>)
add_compile_options($<$<COMPILE_LANGUAGE:C>:/wd4244>)
add_compile_options($<$<COMPILE_LANGUAGE:C>:/wd4267>)
# handle msvcrt setting being passed in CMAKE_C_FLAGS
if(DEFINED CMAKE_MSVC_RUNTIME_LIBRARY)
# do not support other methods of setting this (it would be more conformant, tho)
message(FATAL_ERROR "please set msvcrt via CMAKE_C_FLAGS")
endif()
# default use the multithread, static version of the run-time library.
option(UNICORN_STATIC_MSVCRT "Embed static runtime library" ${PROJECT_IS_TOP_LEVEL})
if(UNICORN_STATIC_MSVCRT)
string(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG})
string(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE})
if(CMAKE_C_FLAGS MATCHES "[/-]MTd")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDebug")
elseif(CMAKE_C_FLAGS MATCHES "[/-]MDd")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDebugDLL")
elseif(CMAKE_C_FLAGS MATCHES "[/-]MT")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded")
elseif(CMAKE_C_FLAGS MATCHES "[/-]MD")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL")
endif()
# prevent the arg from occurring more than once (not a big deal, just to keep tidy)
string(REGEX REPLACE "[/-]M[TD]d?" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
else()
if(MINGW)
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpmachine
@ -1181,7 +1205,7 @@ if(UNICORN_TRACER)
target_compile_options(unicorn PRIVATE -DUNICORN_TRACER)
endif()
target_compile_options(unicorn-common PRIVATE
target_compile_options(unicorn-common PRIVATE
${UNICORN_COMPILE_OPTIONS}
)

44
Cargo.toml Normal file
View File

@ -0,0 +1,44 @@
[package]
name = "unicorn-engine"
version = "2.0.0-rc6"
authors = ["Ziqiao Kong", "Lukas Seidel"]
documentation = "https://github.com/unicorn-engine/unicorn/wiki"
edition = "2021"
license = "GPL-2.0"
readme = "README.md"
repository = "https://github.com/unicorn-engine/unicorn"
description = "Rust bindings for the Unicorn emulator with utility functions"
build = "bindings/rust/build.rs"
links = "unicorn"
# use `cargo publish --list` to see files to be included
# the resulting list what cargo uses to check for out-of-date files during build
exclude = [
"/docs",
"/bindings/dotnet",
"/bindings/go",
"/bindings/haskell",
"/bindings/java",
"/bindings/pascal",
"/bindings/python",
"/bindings/ruby",
"/bindings/vb6",
"/samples",
"/tests",
]
[lib]
path = "bindings/rust/src/lib.rs"
[dependencies]
bitflags = "1.3"
libc = "0.2"
[build-dependencies]
cc = { optional = true, version = "1.0" }
cmake = { optional = true, version = "0.1" }
pkg-config = { optional = true, version = "0.3" }
[features]
default = ["build_unicorn_cmake"]
build_unicorn_cmake = ["cc", "cmake"]
use_system_unicorn = ["pkg-config"]

View File

@ -1,37 +0,0 @@
[package]
name = "unicorn-engine"
version = "2.0.0-rc6"
authors = ["Ziqiao Kong", "Lukas Seidel"]
documentation = "https://github.com/unicorn-engine/unicorn/wiki"
edition = "2021"
include = [
"/.gitmodules",
"/COPYING",
"/Cargo.toml",
"/README.md",
"/src/*",
"build.rs",
]
license = "GPL-2.0"
readme = "README.md"
repository = "https://github.com/unicorn-engine/unicorn/"
description = "Rust bindings for the Unicorn emulator with utility functions"
build = "build.rs"
links = "unicorn"
[dependencies]
bitflags = "1.3"
libc = "0.2"
[build-dependencies]
reqwest = { optional = true, version = "0.11", features = ["blocking"] }
flate2 = { optional = true, version = "1.0" }
tar = { optional = true, version = "0.4" }
bytes = { optional = true, version = "1" }
pkg-config = { optional = true, version = "0.3" }
[features]
default = ["build_unicorn_cmake"]
use_system_unicorn = ["pkg-config"]
build_unicorn_cmake = ["reqwest", "flate2", "tar", "bytes"]

View File

@ -1,176 +1,109 @@
#[cfg(feature = "build_unicorn_cmake")]
use bytes::Buf;
#[cfg(feature = "build_unicorn_cmake")]
use flate2::read::GzDecoder;
#[cfg(feature = "use_system_unicorn")]
use pkg_config;
#[cfg(feature = "build_unicorn_cmake")]
use reqwest::header::USER_AGENT;
use std::env;
#[cfg(feature = "build_unicorn_cmake")]
use std::path::{Path, PathBuf};
use std::path::PathBuf;
#[cfg(feature = "build_unicorn_cmake")]
use std::{env, process::Command};
#[cfg(feature = "build_unicorn_cmake")]
use tar::Archive;
use std::process::Command;
#[cfg(feature = "build_unicorn_cmake")]
fn find_unicorn(unicorn_dir: &Path) -> Option<PathBuf> {
for entry in std::fs::read_dir(unicorn_dir).ok()? {
let entry = entry.unwrap();
let path = entry.path();
#[cfg(all(feature = "build_unicorn_cmake"))]
fn ninja_available() -> bool {
Command::new("ninja").arg("--version").spawn().is_ok()
}
if path.is_dir() && path.file_name()?.to_str()?.contains("unicorn") {
return Some(path);
#[cfg(all(feature = "build_unicorn_cmake"))]
fn msvc_cmake_tools_available() -> bool {
Command::new("cmake").arg("--version").spawn().is_ok() && ninja_available()
}
#[cfg(all(feature = "build_unicorn_cmake"))]
fn setup_env_msvc(compiler: &cc::Tool) {
// If PATH already contains what we need, skip this
if msvc_cmake_tools_available() {
return;
}
let target = env::var("TARGET").unwrap();
let devenv = cc::windows_registry::find_tool(target.as_str(), "devenv");
let tool_root: PathBuf = match devenv {
Some(devenv_tool) => {
devenv_tool.path().parent().unwrap().to_path_buf()
},
None => {
// if devenv (i.e. Visual Studio) was not found, assume compiler is
// from standalone Build Tools and look there instead.
// this should be done properly in cc crate, but for now it's not.
let tools_name = std::ffi::OsStr::new("BuildTools");
let compiler_path = compiler.path().to_path_buf();
compiler_path.iter().find(|x| *x == tools_name)
.expect("Failed to find devenv or Build Tools");
compiler_path.iter().take_while(|x| *x != tools_name)
.collect::<PathBuf>().join(tools_name).join(r"Common7\IDE")
},
};
let cmake_pkg_dir = tool_root.join(r"CommonExtensions\Microsoft\CMake");
let cmake_path = cmake_pkg_dir.join(r"CMake\bin\cmake.exe");
let ninja_path = cmake_pkg_dir.join(r"Ninja\ninja.exe");
if !cmake_path.is_file() {
panic!("missing cmake");
}
if !ninja_path.is_file() {
panic!("missing ninja");
}
// append cmake and ninja location to PATH
if let Some(path) = env::var_os("PATH") {
let mut paths = env::split_paths(&path).collect::<Vec<_>>();
for tool_path in [cmake_path, ninja_path] {
paths.push(tool_path.parent().unwrap().to_path_buf());
}
let new_path = env::join_paths(paths).unwrap();
env::set_var("PATH", &new_path);
}
None
}
#[cfg(feature = "build_unicorn_cmake")]
fn out_dir() -> PathBuf {
let out_dir = env::var("OUT_DIR").unwrap();
Path::new(&out_dir).to_path_buf()
}
#[cfg(feature = "build_unicorn_cmake")]
fn download_unicorn() -> PathBuf {
// https://docs.github.com/en/rest/reference/repos#download-a-repository-archive-tar
let pkg_version;
if let Ok(unicorn_version) = env::var("UNICORN_VERSION") {
pkg_version = unicorn_version;
} else {
pkg_version = env::var("CARGO_PKG_VERSION").unwrap();
}
let out_dir = out_dir();
let client = reqwest::blocking::Client::new();
let resp = client
.get(format!(
"https://api.github.com/repos/unicorn-engine/unicorn/tarball/{}",
pkg_version
))
.header(USER_AGENT, "unicorn-engine-rust-bindings")
.send()
.unwrap()
.bytes()
.unwrap();
let tar = GzDecoder::new(resp.reader());
let mut archive = Archive::new(tar);
archive.unpack(&out_dir).unwrap();
find_unicorn(&out_dir).unwrap()
}
#[cfg(feature = "build_unicorn_cmake")]
#[allow(clippy::branches_sharing_code)]
fn build_with_cmake() {
let profile = env::var("PROFILE").unwrap();
if let Some(unicorn_dir) = find_unicorn(&out_dir()) {
let rust_build_path = unicorn_dir.join("build_rust");
println!(
"cargo:rustc-link-search={}",
rust_build_path.to_str().unwrap()
);
println!(
"cargo:rustc-link-search={}",
rust_build_path.join("Debug").to_str().unwrap()
);
println!(
"cargo:rustc-link-search={}",
rust_build_path.join("Release").to_str().unwrap()
);
let uc_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
let compiler = cc::Build::new().get_compiler();
let has_ninja = if compiler.is_like_msvc() {
setup_env_msvc(&compiler);
// this is a BIG HACK that should be fixed in unicorn's cmake!!
// but for now, tell link.exe to ignore multiply defined symbol names
println!("cargo:rustc-link-arg=/FORCE:MULTIPLE");
true
} else {
let unicorn_dir = if let Result::Ok(_) = env::var("UNICORN_LOCAL") {
Path::new("..").join("..")
} else {
println!("cargo:warning=Unicorn not found. Downloading...");
download_unicorn()
};
ninja_available()
};
let rust_build_path = unicorn_dir.join("build_rust");
let mut cmd = Command::new("cmake");
// We don't use TARGET since we can't cross-build.
if env::consts::OS == "windows" {
// Windows
cmd.current_dir(&unicorn_dir)
.arg("-B")
.arg("build_rust")
.arg("-DBUILD_SHARED_LIBS=OFF")
.arg("-G")
.arg("Visual Studio 16 2019");
if profile == "debug" {
cmd.arg("-DCMAKE_BUILD_TYPE=Debug");
} else {
cmd.arg("-DCMAKE_BUILD_TYPE=Release");
}
cmd.output()
.expect("Fail to create build directory on Windows.");
let mut platform = "x64";
let mut conf = "Release";
if std::mem::size_of::<usize>() == 4 {
platform = "Win32";
}
if profile == "debug" {
conf = "Debug";
}
Command::new("msbuild")
.current_dir(&rust_build_path)
.arg("unicorn.sln")
.arg("-m")
.arg("-p:Platform=".to_owned() + platform)
.arg("-p:Configuration=".to_owned() + conf)
.output()
.expect("Fail to build unicorn on Win32.");
println!(
"cargo:rustc-link-search={}",
rust_build_path.to_str().unwrap()
);
} else {
// Most Unix-like systems
let mut cmd = Command::new("cmake");
cmd.current_dir(&unicorn_dir)
.arg("-B")
.arg("build_rust")
.arg("-DBUILD_SHARED_LIBS=OFF");
if profile == "debug" {
cmd.arg("-DCMAKE_BUILD_TYPE=Debug");
} else {
cmd.arg("-DCMAKE_BUILD_TYPE=Release");
}
cmd.output()
.expect("Fail to create build directory on *nix.");
Command::new("make")
.current_dir(&rust_build_path)
.arg("-j6")
.output()
.expect("Fail to build unicorn on *nix.");
println!(
"cargo:rustc-link-search={}",
rust_build_path.to_str().unwrap()
);
}
// cc crate (as of 1.0.73) misdetects clang as gnu on apple
if compiler.is_like_gnu() && env::consts::OS != "macos" {
// see comment on /FORCE:MULTIPLE
println!("cargo:rustc-link-arg=-Wl,-allow-multiple-definition");
}
let mut config = cmake::Config::new(&uc_dir);
if has_ninja {
config.generator("Ninja");
}
// need to clear build target and append "build" to the path because
// unicorn's CMakeLists.txt doesn't properly support 'install', so we use
// the build artifacts from the build directory, which cmake crate sets
// to "<out_dir>/build/"
let dst = config.define("BUILD_SHARED_LIBS", "OFF")
.define("UNICORN_BUILD_TESTS", "OFF")
.define("UNICORN_INSTALL", "OFF")
.no_build_target(true).build();
println!("cargo:rustc-link-search=native={}", dst.join("build").display());
// Lazymio(@wtdcode): Why do I stick to static link? See: https://github.com/rust-lang/cargo/issues/5077
println!("cargo:rustc-link-lib=unicorn");
if env::consts::OS != "windows" {
println!("cargo:rustc-link-lib=static=unicorn");
if !compiler.is_like_msvc() {
println!("cargo:rustc-link-lib=pthread");
println!("cargo:rustc-link-lib=m");
}
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=src");
}
fn main() {

View File

@ -418,6 +418,7 @@ static int sigp_set_architecture(S390CPU *cpu, uint32_t param,
return SIGP_CC_STATUS_STORED;
}
#if 0
int handle_sigp(CPUS390XState *env, uint8_t order, uint64_t r1, uint64_t r3)
{
uint64_t *status_reg = &env->regs[r1];
@ -438,6 +439,7 @@ int handle_sigp(CPUS390XState *env, uint8_t order, uint64_t r1, uint64_t r3)
return ret;
}
#endif
int s390_cpu_restart(S390CPU *cpu)
{

View File

@ -12,7 +12,7 @@ static void uc_common_setup(uc_engine **uc, uc_arch arch, uc_mode mode,
OK(uc_mem_write(*uc, code_start, code, size));
}
static void test_arm_nop()
static void test_arm_nop(void)
{
uc_engine *uc;
char code[] = "\x00\xf0\x20\xe3"; // nop
@ -34,7 +34,7 @@ static void test_arm_nop()
OK(uc_close(uc));
}
static void test_arm_thumb_sub()
static void test_arm_thumb_sub(void)
{
uc_engine *uc;
char code[] = "\x83\xb0"; // sub sp, #0xc
@ -52,7 +52,7 @@ static void test_arm_thumb_sub()
OK(uc_close(uc));
}
static void test_armeb_sub()
static void test_armeb_sub(void)
{
uc_engine *uc;
char code[] =
@ -83,7 +83,7 @@ static void test_armeb_sub()
OK(uc_close(uc));
}
static void test_armeb_be8_sub()
static void test_armeb_be8_sub(void)
{
uc_engine *uc;
char code[] =
@ -114,7 +114,7 @@ static void test_armeb_be8_sub()
OK(uc_close(uc));
}
static void test_arm_thumbeb_sub()
static void test_arm_thumbeb_sub(void)
{
uc_engine *uc;
char code[] = "\xb0\x83"; // sub sp, #0xc
@ -140,7 +140,7 @@ static void test_arm_thumb_ite_count_callback(uc_engine *uc, uint64_t address,
(*count) += 1;
}
static void test_arm_thumb_ite()
static void test_arm_thumb_ite(void)
{
uc_engine *uc;
uc_hook hook;
@ -200,7 +200,7 @@ static void test_arm_thumb_ite()
OK(uc_close(uc));
}
static void test_arm_m_thumb_mrs()
static void test_arm_m_thumb_mrs(void)
{
uc_engine *uc;
char code[] =
@ -225,7 +225,7 @@ static void test_arm_m_thumb_mrs()
OK(uc_close(uc));
}
static void test_arm_m_control()
static void test_arm_m_control(void)
{
uc_engine *uc;
int r_control, r_msp, r_psp;
@ -274,7 +274,7 @@ static void test_arm_m_exc_return_hook_interrupt(uc_engine *uc, int intno,
OK(uc_emu_stop(uc));
}
static void test_arm_m_exc_return()
static void test_arm_m_exc_return(void)
{
uc_engine *uc;
char code[] = "\x6f\xf0\x02\x00\x00\x47"; // mov r0, #0xFFFFFFFD; bx r0;
@ -302,7 +302,7 @@ static void test_arm_m_exc_return()
}
// For details, see https://github.com/unicorn-engine/unicorn/issues/1494.
static void test_arm_und32_to_svc32()
static void test_arm_und32_to_svc32(void)
{
uc_engine *uc;
// # MVN r0, #0
@ -343,7 +343,7 @@ static void test_arm_und32_to_svc32()
OK(uc_close(uc));
}
static void test_arm_usr32_to_svc32()
static void test_arm_usr32_to_svc32(void)
{
uc_engine *uc;
int r_cpsr, r_sp, r_spsr, r_lr;
@ -392,7 +392,7 @@ static void test_arm_usr32_to_svc32()
OK(uc_close(uc));
}
static void test_arm_v8()
static void test_arm_v8(void)
{
char code[] = "\xd0\xe8\xff\x17"; // LDAEXD.W R1, [R0]
uc_engine *uc;
@ -416,7 +416,7 @@ static void test_arm_v8()
OK(uc_close(uc));
}
static void test_arm_thumb_smlabb()
static void test_arm_thumb_smlabb(void)
{
char code[] = "\x13\xfb\x01\x23";
uint32_t r_r1, r_r2, r_r3;
@ -441,7 +441,7 @@ static void test_arm_thumb_smlabb()
OK(uc_close(uc));
}
static void test_arm_not_allow_privilege_escalation()
static void test_arm_not_allow_privilege_escalation(void)
{
uc_engine *uc;
int r_cpsr, r_sp, r_spsr, r_lr;
@ -488,7 +488,7 @@ static void test_arm_not_allow_privilege_escalation()
OK(uc_close(uc));
}
static void test_arm_mrc()
static void test_arm_mrc(void)
{
uc_engine *uc;
// mrc p15, #0, r1, c13, c0, #3
@ -502,7 +502,7 @@ static void test_arm_mrc()
OK(uc_close(uc));
}
static void test_arm_hflags_rebuilt()
static void test_arm_hflags_rebuilt(void)
{
// MRS r6, apsr
// BIC r6, r6, #&1F
@ -575,7 +575,7 @@ static bool test_arm_mem_access_abort_hook_insn_invalid(uc_engine *uc,
return false;
}
static void test_arm_mem_access_abort()
static void test_arm_mem_access_abort(void)
{
// LDR r0, [r0]
// Undefined instruction
@ -623,7 +623,7 @@ static void test_arm_mem_access_abort()
OK(uc_close(uc));
}
static void test_arm_read_sctlr()
static void test_arm_read_sctlr(void)
{
uc_engine *uc;
uc_arm_cp_reg reg;
@ -646,7 +646,7 @@ static void test_arm_read_sctlr()
OK(uc_close(uc));
}
static void test_arm_be_cpsr_sctlr()
static void test_arm_be_cpsr_sctlr(void)
{
uc_engine *uc;
uc_arm_cp_reg reg;
@ -695,7 +695,7 @@ static void test_arm_be_cpsr_sctlr()
OK(uc_close(uc));
}
static void test_arm_switch_endian()
static void test_arm_switch_endian(void)
{
uc_engine *uc;
char code[] = "\x00\x00\x91\xe5"; // ldr r0, [r1]

View File

@ -12,7 +12,7 @@ static void uc_common_setup(uc_engine **uc, uc_arch arch, uc_mode mode,
OK(uc_mem_write(*uc, code_start, code, size));
}
static void test_arm64_until()
static void test_arm64_until(void)
{
uc_engine *uc;
char code[] = "\x30\x00\x80\xd2\x11\x04\x80\xd2\x9c\x23\x00\x91";
@ -52,7 +52,7 @@ static void test_arm64_until()
OK(uc_close(uc));
}
static void test_arm64_code_patching()
static void test_arm64_code_patching(void)
{
uc_engine *uc;
char code[] = "\x00\x04\x00\x11"; // add w0, w0, 0x1
@ -82,7 +82,7 @@ static void test_arm64_code_patching()
}
// Need to flush the cache before running the emulation after patching
static void test_arm64_code_patching_count()
static void test_arm64_code_patching_count(void)
{
uc_engine *uc;
char code[] = "\x00\x04\x00\x11"; // add w0, w0, 0x1
@ -113,7 +113,7 @@ static void test_arm64_code_patching_count()
OK(uc_close(uc));
}
static void test_arm64_v8_pac()
static void test_arm64_v8_pac(void)
{
uc_engine *uc;
char code[] = "\x28\xfd\xea\xc8"; // casal x10, x8, [x9]
@ -138,7 +138,7 @@ static void test_arm64_v8_pac()
OK(uc_close(uc));
}
static void test_arm64_read_sctlr()
static void test_arm64_read_sctlr(void)
{
uc_engine *uc;
uc_arm64_cp_reg reg;
@ -170,7 +170,7 @@ static uint32_t test_arm64_mrs_hook_cb(uc_engine *uc, uc_arm64_reg reg,
return 1;
}
static void test_arm64_mrs_hook()
static void test_arm64_mrs_hook(void)
{
uc_engine *uc;
uc_hook hk;

View File

@ -73,7 +73,7 @@ static void uc_common_setup(uc_engine **uc, uc_arch arch, uc_mode mode,
}
#define GEN_SIMPLE_READ_TEST(field, ctl_type, arg_type, expected) \
static void test_uc_ctl_##field() \
static void test_uc_ctl_##field(void) \
{ \
uc_engine *uc; \
arg_type arg; \
@ -88,7 +88,7 @@ GEN_SIMPLE_READ_TEST(arch, UC_CTL_UC_ARCH, int, 4)
GEN_SIMPLE_READ_TEST(page_size, UC_CTL_UC_PAGE_SIZE, uint32_t, 4096)
GEN_SIMPLE_READ_TEST(time_out, UC_CTL_UC_TIMEOUT, uint64_t, 0)
static void test_uc_ctl_exits()
static void test_uc_ctl_exits(void)
{
uc_engine *uc;
// cmp eax, 0;
@ -141,7 +141,7 @@ double time_emulation(uc_engine *uc, uint64_t start, uint64_t end)
#define TCG_MAX_INSNS (512) // from tcg.h
#define CODE_LEN TB_COUNT *TCG_MAX_INSNS
static void test_uc_ctl_tb_cache()
static void test_uc_ctl_tb_cache(void)
{
uc_engine *uc;
char code[CODE_LEN + 1];
@ -174,7 +174,7 @@ static void test_uc_ctl_tb_cache()
OK(uc_close(uc));
}
static void test_uc_ctl_change_page_size()
static void test_uc_ctl_change_page_size(void)
{
uc_engine *uc;
uc_engine *uc2;
@ -192,7 +192,7 @@ static void test_uc_ctl_change_page_size()
}
// Copy from test_arm.c but with new API.
static void test_uc_ctl_arm_cpu()
static void test_uc_ctl_arm_cpu(void)
{
uc_engine *uc;
int r_control, r_msp, r_psp;

View File

@ -13,7 +13,7 @@ static void uc_common_setup(uc_engine **uc, uc_arch arch, uc_mode mode,
OK(uc_mem_write(*uc, code_start, code, size));
}
static void test_move_to_sr()
static void test_move_to_sr(void)
{
uc_engine *uc;

View File

@ -1,6 +1,6 @@
#include "unicorn_test.h"
static void test_map_correct()
static void test_map_correct(void)
{
uc_engine *uc;
@ -24,7 +24,7 @@ static void test_map_correct()
OK(uc_close(uc));
}
static void test_map_wrapping()
static void test_map_wrapping(void)
{
uc_engine *uc;
@ -35,7 +35,7 @@ static void test_map_wrapping()
OK(uc_close(uc));
}
static void test_mem_protect()
static void test_mem_protect(void)
{
uc_engine *qc;
int r_eax = 0x2000;
@ -60,7 +60,7 @@ static void test_mem_protect()
OK(uc_close(qc));
}
static void test_splitting_mem_unmap()
static void test_splitting_mem_unmap(void)
{
uc_engine *uc;
@ -85,7 +85,7 @@ static uint64_t test_splitting_mmio_unmap_read_callback(uc_engine *uc,
return 0x19260817;
}
static void test_splitting_mmio_unmap()
static void test_splitting_mmio_unmap(void)
{
uc_engine *uc;
// mov ecx, [0x3004] <-- normal read
@ -118,7 +118,7 @@ static void test_splitting_mmio_unmap()
OK(uc_close(uc));
}
static void test_mem_protect_map_ptr()
static void test_mem_protect_map_ptr(void)
{
uc_engine *uc;
uint64_t val = 0x114514;

View File

@ -11,7 +11,7 @@ static void uc_common_setup(uc_engine **uc, uc_arch arch, uc_mode mode,
OK(uc_mem_write(*uc, code_start, code, size));
}
static void test_mips_el_ori()
static void test_mips_el_ori(void)
{
uc_engine *uc;
char code[] = "\x56\x34\x21\x34"; // ori $at, $at, 0x3456;
@ -30,7 +30,7 @@ static void test_mips_el_ori()
OK(uc_close(uc));
}
static void test_mips_eb_ori()
static void test_mips_eb_ori(void)
{
uc_engine *uc;
char code[] = "\x34\x21\x34\x56"; // ori $at, $at, 0x3456;
@ -49,7 +49,7 @@ static void test_mips_eb_ori()
OK(uc_close(uc));
}
static void test_mips_stop_at_branch()
static void test_mips_stop_at_branch(void)
{
uc_engine *uc;
char code[] =
@ -71,7 +71,7 @@ static void test_mips_stop_at_branch()
OK(uc_close(uc));
}
static void test_mips_stop_at_delay_slot()
static void test_mips_stop_at_delay_slot(void)
{
uc_engine *uc;
char code[] =
@ -93,7 +93,7 @@ static void test_mips_stop_at_delay_slot()
OK(uc_close(uc));
}
static void test_mips_lwx_exception_issue_1314()
static void test_mips_lwx_exception_issue_1314(void)
{
uc_engine *uc;
char code[] = "\x0a\xc8\x79\x7e"; // lwx $t9, $t9($s3)

View File

@ -11,7 +11,7 @@ static void uc_common_setup(uc_engine **uc, uc_arch arch, uc_mode mode,
OK(uc_mem_write(*uc, code_start, code, size));
}
static void test_ppc32_add()
static void test_ppc32_add(void)
{
uc_engine *uc;
char code[] = "\x7f\x46\x1a\x14"; // ADD 26, 6, 3
@ -35,7 +35,7 @@ static void test_ppc32_add()
}
// https://www.ibm.com/docs/en/aix/7.2?topic=set-fadd-fa-floating-add-instruction
static void test_ppc32_fadd()
static void test_ppc32_fadd(void)
{
uc_engine *uc;
char code[] = "\xfc\xc4\x28\x2a"; // fadd 6, 4, 5
@ -69,7 +69,7 @@ static void test_ppc32_sc_cb(uc_engine *uc, uint32_t intno, void *data)
return;
}
static void test_ppc32_sc()
static void test_ppc32_sc(void)
{
uc_engine *uc;
char code[] = "\x44\x00\x00\x02"; // sc

View File

@ -11,7 +11,7 @@ static void uc_common_setup(uc_engine **uc, uc_arch arch, uc_mode mode,
OK(uc_mem_write(*uc, code_start, code, size));
}
static void test_riscv32_nop()
static void test_riscv32_nop(void)
{
uc_engine *uc;
char code[] = "\x13\x00\x00\x00"; // nop
@ -33,7 +33,7 @@ static void test_riscv32_nop()
OK(uc_close(uc));
}
static void test_riscv64_nop()
static void test_riscv64_nop(void)
{
uc_engine *uc;
char code[] = "\x13\x00\x00\x00"; // nop
@ -55,7 +55,7 @@ static void test_riscv64_nop()
OK(uc_close(uc));
}
static void test_riscv32_until_pc_update()
static void test_riscv32_until_pc_update(void)
{
uc_engine *uc;
char code[] = "\x93\x02\x10\x00\x13\x03\x00\x02\x13\x01\x81\x00";
@ -96,7 +96,7 @@ static void test_riscv32_until_pc_update()
OK(uc_close(uc));
}
static void test_riscv64_until_pc_update()
static void test_riscv64_until_pc_update(void)
{
uc_engine *uc;
char code[] = "\x93\x02\x10\x00\x13\x03\x00\x02\x13\x01\x81\x00";
@ -136,7 +136,7 @@ static void test_riscv64_until_pc_update()
OK(uc_close(uc));
}
static void test_riscv32_3steps_pc_update()
static void test_riscv32_3steps_pc_update(void)
{
uc_engine *uc;
char code[] = "\x93\x02\x10\x00\x13\x03\x00\x02\x13\x01\x81\x00";
@ -177,7 +177,7 @@ static void test_riscv32_3steps_pc_update()
OK(uc_close(uc));
}
static void test_riscv64_3steps_pc_update()
static void test_riscv64_3steps_pc_update(void)
{
uc_engine *uc;
char code[] = "\x93\x02\x10\x00\x13\x03\x00\x02\x13\x01\x81\x00";
@ -372,7 +372,7 @@ static void test_riscv64_fp_move_to_int(void)
uc_close(uc);
}
static void test_riscv64_code_patching()
static void test_riscv64_code_patching(void)
{
uc_engine *uc;
char code[] = "\x93\x82\x12\x00"; // addi t0, t0, 0x1
@ -402,7 +402,7 @@ static void test_riscv64_code_patching()
}
// Need to flush the cache before running the emulation after patching
static void test_riscv64_code_patching_count()
static void test_riscv64_code_patching_count(void)
{
uc_engine *uc;
char code[] = "\x93\x82\x12\x00"; // addi t0, t0, 0x1
@ -439,7 +439,7 @@ static void test_riscv64_ecall_cb(uc_engine *uc, uint32_t intno, void *data)
return;
}
static void test_riscv64_ecall()
static void test_riscv64_ecall(void)
{
uc_engine *uc;
char code[] = "\x73\x00\x00\x00"; // ecall
@ -469,7 +469,7 @@ static uint64_t test_riscv32_mmio_map_read_cb(uc_engine *uc, uint64_t offset,
return 0;
}
static void test_riscv32_mmio_map()
static void test_riscv32_mmio_map(void)
{
uc_engine *uc;
// 37 17 02 40 lui a4, 0x40021
@ -487,7 +487,7 @@ static void test_riscv32_mmio_map()
OK(uc_close(uc));
}
static void test_riscv32_map()
static void test_riscv32_map(void)
{
uc_engine *uc;
// 37 17 02 40 lui a4, 0x40021
@ -519,7 +519,7 @@ static uint64_t test_riscv64_mmio_map_read_cb(uc_engine *uc, uint64_t offset,
return 0;
}
static void test_riscv64_mmio_map()
static void test_riscv64_mmio_map(void)
{
uc_engine *uc;
// 37 17 02 40 lui a4, 0x40021

View File

@ -11,7 +11,7 @@ static void uc_common_setup(uc_engine **uc, uc_arch arch, uc_mode mode,
OK(uc_mem_write(*uc, code_start, code, size));
}
static void test_s390x_lr()
static void test_s390x_lr(void)
{
char code[] = "\x18\x23"; // lr %r2, %r3
uint64_t r_pc, r_r2, r_r3 = 0x114514;

View File

@ -25,7 +25,7 @@ static void test_x86_in_callback(uc_engine *uc, uint32_t port, int size,
result->size = size;
}
static void test_x86_in()
static void test_x86_in(void)
{
uc_engine *uc;
uc_hook hook;
@ -60,7 +60,7 @@ static void test_x86_out_callback(uc_engine *uc, uint32_t port, int size,
result->value = value;
}
static void test_x86_out()
static void test_x86_out(void)
{
uc_engine *uc;
uc_hook hook;
@ -116,7 +116,7 @@ static bool test_x86_mem_hook_all_callback(uc_engine *uc, uc_mem_type type,
return true;
}
static void test_x86_mem_hook_all()
static void test_x86_mem_hook_all(void)
{
uc_engine *uc;
uc_hook hook;
@ -148,7 +148,7 @@ static void test_x86_mem_hook_all()
OK(uc_close(uc));
}
static void test_x86_inc_dec_pxor()
static void test_x86_inc_dec_pxor(void)
{
uc_engine *uc;
char code[] =
@ -178,7 +178,7 @@ static void test_x86_inc_dec_pxor()
OK(uc_close(uc));
}
static void test_x86_relative_jump()
static void test_x86_relative_jump(void)
{
uc_engine *uc;
char code[] = "\xeb\x02\x90\x90\x90\x90\x90\x90"; // jmp 4; nop; nop; nop;
@ -196,7 +196,7 @@ static void test_x86_relative_jump()
OK(uc_close(uc));
}
static void test_x86_loop()
static void test_x86_loop(void)
{
uc_engine *uc;
char code[] = "\x41\x4a\xeb\xfe"; // inc ecx; dec edx; jmp $;
@ -219,7 +219,7 @@ static void test_x86_loop()
OK(uc_close(uc));
}
static void test_x86_invalid_mem_read()
static void test_x86_invalid_mem_read(void)
{
uc_engine *uc;
char code[] = "\x8b\x0d\xaa\xaa\xaa\xaa"; // mov ecx, [0xAAAAAAAA]
@ -233,7 +233,7 @@ static void test_x86_invalid_mem_read()
OK(uc_close(uc));
}
static void test_x86_invalid_mem_write()
static void test_x86_invalid_mem_write(void)
{
uc_engine *uc;
char code[] = "\x89\x0d\xaa\xaa\xaa\xaa"; // mov ecx, [0xAAAAAAAA]
@ -247,7 +247,7 @@ static void test_x86_invalid_mem_write()
OK(uc_close(uc));
}
static void test_x86_invalid_jump()
static void test_x86_invalid_jump(void)
{
uc_engine *uc;
char code[] = "\xe9\xe9\xee\xee\xee"; // jmp 0xEEEEEEEE
@ -270,7 +270,7 @@ static void test_x86_64_syscall_callback(uc_engine *uc, void *user_data)
TEST_CHECK(rax == 0x100);
}
static void test_x86_64_syscall()
static void test_x86_64_syscall(void)
{
uc_engine *uc;
uc_hook hook;
@ -288,7 +288,7 @@ static void test_x86_64_syscall()
OK(uc_close(uc));
}
static void test_x86_16_add()
static void test_x86_16_add(void)
{
uc_engine *uc;
char code[] = "\x00\x00"; // add byte ptr [bx + si], al
@ -310,7 +310,7 @@ static void test_x86_16_add()
OK(uc_close(uc));
}
static void test_x86_reg_save()
static void test_x86_reg_save(void)
{
uc_engine *uc;
uc_context *ctx;
@ -349,7 +349,7 @@ test_x86_invalid_mem_read_stop_in_cb_callback(uc_engine *uc, uc_mem_type type,
return false;
}
static void test_x86_invalid_mem_read_stop_in_cb()
static void test_x86_invalid_mem_read_stop_in_cb(void)
{
uc_engine *uc;
uc_hook hook;
@ -400,7 +400,7 @@ static void test_x86_x87_fnstenv_callback(uc_engine *uc, uint64_t address,
}
}
static void test_x86_x87_fnstenv()
static void test_x86_x87_fnstenv(void)
{
uc_engine *uc;
uc_hook hook;
@ -447,7 +447,7 @@ static void test_x86_mmio_write_callback(uc_engine *uc, uint64_t offset,
return;
}
static void test_x86_mmio()
static void test_x86_mmio(void)
{
uc_engine *uc;
int r_ecx = 0xdeadbeef;
@ -485,7 +485,7 @@ static bool test_x86_missing_code_callback(uc_engine *uc, uc_mem_type type,
return true;
}
static void test_x86_missing_code()
static void test_x86_missing_code(void)
{
uc_engine *uc;
uc_hook hook;
@ -510,7 +510,7 @@ static void test_x86_missing_code()
OK(uc_close(uc));
}
static void test_x86_smc_xor()
static void test_x86_smc_xor(void)
{
uc_engine *uc;
/*
@ -559,7 +559,7 @@ static void test_x86_mmio_uc_mem_rw_write_callback(uc_engine *uc,
return;
}
static void test_x86_mmio_uc_mem_rw()
static void test_x86_mmio_uc_mem_rw(void)
{
uc_engine *uc;
int data = 0xdeadbeef;
@ -582,7 +582,7 @@ static void test_x86_sysenter_hook(uc_engine *uc, void *user)
*(int *)user = 1;
}
static void test_x86_sysenter()
static void test_x86_sysenter(void)
{
uc_engine *uc;
char code[] = "\x0F\x34"; // sysenter
@ -611,7 +611,7 @@ static int test_x86_hook_cpuid_callback(uc_engine *uc, void *data)
return 1;
}
static void test_x86_hook_cpuid()
static void test_x86_hook_cpuid(void)
{
uc_engine *uc;
char code[] = "\x40\x0F\xA2"; // INC EAX; CPUID
@ -657,7 +657,7 @@ static void test_x86_486_cpuid(void)
}
// This is a regression bug.
static void test_x86_clear_tb_cache()
static void test_x86_clear_tb_cache(void)
{
uc_engine *uc;
char code[] = "\x83\xc1\x01\x4a"; // ADD ecx, 1; DEC edx;
@ -691,7 +691,7 @@ static void test_x86_clear_tb_cache()
}
// This is a regression bug.
static void test_x86_clear_empty_tb()
static void test_x86_clear_empty_tb(void)
{
uc_engine *uc;
// lb:
@ -746,7 +746,7 @@ static void test_x86_hook_tcg_op_cb(uc_engine *uc, uint64_t address,
result->arg2 = arg2;
}
static void test_x86_hook_tcg_op()
static void test_x86_hook_tcg_op(void)
{
uc_engine *uc;
uc_hook h;
@ -808,7 +808,7 @@ static void test_x86_cmpxchg_mem_hook(uc_engine *uc, uc_mem_type type,
}
}
static void test_x86_cmpxchg()
static void test_x86_cmpxchg(void)
{
uc_engine *uc;
char code[] = "\x0F\xC7\x0D\xE0\xBE\xAD\xDE"; // cmpxchg8b [0xdeadbee0]
@ -846,7 +846,7 @@ static void test_x86_nested_emu_start_cb(uc_engine *uc, uint64_t addr,
OK(uc_emu_start(uc, code_start + 1, code_start + 2, 0, 0));
}
static void test_x86_nested_emu_start()
static void test_x86_nested_emu_start(void)
{
uc_engine *uc;
char code[] = "\x41\x4a"; // INC ecx; DEC edx;
@ -881,7 +881,7 @@ static void test_x86_nested_emu_stop_cb(uc_engine *uc, uint64_t addr,
OK(uc_emu_stop(uc));
}
static void test_x86_nested_emu_stop()
static void test_x86_nested_emu_stop(void)
{
uc_engine *uc;
// INC ecx; DEC edx; DEC edx;
@ -915,7 +915,7 @@ static void test_x86_nested_emu_start_error_cb(uc_engine *uc, uint64_t addr,
uc_emu_start(uc, code_start + 2, 0, 0, 0));
}
static void test_x86_64_nested_emu_start_error()
static void test_x86_64_nested_emu_start_error(void)
{
uc_engine *uc;
// "nop;nop;mov rax, [0x10000]"
@ -932,7 +932,7 @@ static void test_x86_64_nested_emu_start_error()
OK(uc_close(uc));
}
static void test_x86_eflags_reserved_bit()
static void test_x86_eflags_reserved_bit(void)
{
uc_engine *uc;
uint32_t r_eflags;
@ -958,7 +958,7 @@ static void test_x86_nested_uc_emu_start_exits_cb(uc_engine *uc, uint64_t addr,
OK(uc_emu_start(uc, code_start + 5, code_start + 6, 0, 0));
}
static void test_x86_nested_uc_emu_start_exits()
static void test_x86_nested_uc_emu_start_exits(void)
{
uc_engine *uc;
// cmp eax, 0