Compare commits
25 Commits
experiment
...
master
Author | SHA1 | Date | |
---|---|---|---|
eea42459fd | |||
8110528e1c | |||
054403ae0d | |||
c2684b995b | |||
737682ab16 | |||
bad2725805 | |||
d7cf79a092 | |||
9a08103872 | |||
f9b0bf0b5f | |||
2732383465 | |||
9ba2bbe8cd | |||
7666a650c2 | |||
718a7fe078 | |||
3e82b1610d | |||
f59947aea8 | |||
2cc2264dde | |||
b44a0a5ef3 | |||
2d88a8539f | |||
57ff2f187c | |||
c2e432c219 | |||
d14e0fe3a0 | |||
f072c0ce53 | |||
10ca8f89f6 | |||
2e5af76dbb | |||
109091c087 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1,5 @@
|
||||
/target
|
||||
*.log
|
||||
/nyx_data
|
||||
/KVM-Nyx-fork
|
||||
/benchmarks
|
350
Cargo.lock
generated
350
Cargo.lock
generated
@ -2,6 +2,21 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.24.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler2"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.3"
|
||||
@ -61,12 +76,36 @@ dependencies = [
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base-x"
|
||||
version = "0.2.11"
|
||||
@ -81,11 +120,11 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.72.0"
|
||||
version = "0.72.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f72209734318d0b619a5e0f5129918b848c416e122a3c4ce054e03cb87b726f"
|
||||
checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
"bitflags 2.9.4",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"itertools",
|
||||
@ -96,7 +135,7 @@ dependencies = [
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn 2.0.104",
|
||||
"syn 2.0.106",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -107,9 +146,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.9.1"
|
||||
version = "2.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
|
||||
checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
@ -130,24 +169,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eadd868a2ce9ca38de7eeafdcec9c7065ef89b42b32f0839278d55f35c54d1ff"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"heck",
|
||||
"heck 0.4.1",
|
||||
"indexmap",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"syn 2.0.104",
|
||||
"syn 2.0.106",
|
||||
"tempfile",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.31"
|
||||
version = "1.2.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3a42d84bb6b69d3a8b3eaacf0d88f179e1929695e1ad012b6cf64d9caaa5fd2"
|
||||
checksum = "5252b3d2648e5eedbc1a6f501e3c795e07025c1e93bbf8bbdd6eef7f447a6d54"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"shlex",
|
||||
]
|
||||
|
||||
@ -162,9 +202,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.1"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
|
||||
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
|
||||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
@ -179,18 +219,19 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.42"
|
||||
version = "4.5.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed87a9d530bb41a67537289bafcac159cb3ee28460e0a4571123d2a778a6a882"
|
||||
checksum = "7eac00902d9d136acd712710d71823fb8ac8004ca445a89e73a41d45aa712931"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.42"
|
||||
version = "4.5.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64f4f3f3c77c94aff3c7e9aac9a2ca1974a5adf392a8bb751e827d6d127ab966"
|
||||
checksum = "2ad9bbf750e73b5884fb8a211a9424a1906c1e156724260fdae972f31d70e1d6"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
@ -198,6 +239,18 @@ dependencies = [
|
||||
"strsim",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c"
|
||||
dependencies = [
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.106",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.7.5"
|
||||
@ -209,7 +262,6 @@ name = "client"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -240,7 +292,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "config"
|
||||
version = "0.1.0"
|
||||
source = "git+https://git.cs.tu-dortmund.de/david.venhoff/libnyx-fork#d85fc2487a6427a0df699c7eaee37db70bc6858b"
|
||||
source = "git+https://git.cs.tu-dortmund.de/david.venhoff/libnyx-fork#b2a71111ab428fb95055239efe84f6e81f86d4b7"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"ron",
|
||||
@ -254,6 +306,27 @@ version = "0.4.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f8a2ca5ac02d09563609681103aada9e1777d54fc57a5acd7a41404f9c93b6e"
|
||||
|
||||
[[package]]
|
||||
name = "csv"
|
||||
version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acdc4883a9c96732e4733212c01447ebd805833b7275a73ca3ee080fd77afdaf"
|
||||
dependencies = [
|
||||
"csv-core",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv-core"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d02f3b0da4c6504f86e9cd789d8dbafab48c2321be74e9987593de5a894d93d"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derivative"
|
||||
version = "2.2.0"
|
||||
@ -282,7 +355,7 @@ checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.104",
|
||||
"syn 2.0.106",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -311,12 +384,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.13"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad"
|
||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.60.2",
|
||||
"windows-sys 0.61.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -325,6 +398,12 @@ version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
||||
|
||||
[[package]]
|
||||
name = "find-msvc-tools"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fd99930f64d146689264c637b5af2f0233a933bef0d8570e2526bf9e083192d"
|
||||
|
||||
[[package]]
|
||||
name = "fs4"
|
||||
version = "0.5.4"
|
||||
@ -338,7 +417,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "fuzz_runner"
|
||||
version = "0.1.0"
|
||||
source = "git+https://git.cs.tu-dortmund.de/david.venhoff/libnyx-fork#d85fc2487a6427a0df699c7eaee37db70bc6858b"
|
||||
source = "git+https://git.cs.tu-dortmund.de/david.venhoff/libnyx-fork#b2a71111ab428fb95055239efe84f6e81f86d4b7"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"colored",
|
||||
@ -378,20 +457,26 @@ dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"r-efi",
|
||||
"wasi 0.14.2+wasi-0.2.4",
|
||||
"wasi 0.14.5+wasi-0.2.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.2"
|
||||
name = "gimli"
|
||||
version = "0.31.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
|
||||
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.4"
|
||||
version = "0.15.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5"
|
||||
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
@ -400,10 +485,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.10.0"
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "206a8042aec68fa4a62e8d3f7aa4ceb508177d9324faf261e1959e495b7a1921"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
@ -438,9 +529,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.174"
|
||||
version = "0.2.175"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
|
||||
checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
|
||||
|
||||
[[package]]
|
||||
name = "libipt"
|
||||
@ -448,7 +539,7 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c3143c4dae9794d23fa2bbc6315847fdf3ef718caa09a7ba09238bce19fe9d4"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
"bitflags 2.9.4",
|
||||
"derive_more",
|
||||
"libipt-sys",
|
||||
"num_enum",
|
||||
@ -477,7 +568,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "libnyx"
|
||||
version = "0.1.0"
|
||||
source = "git+https://git.cs.tu-dortmund.de/david.venhoff/libnyx-fork#d85fc2487a6427a0df699c7eaee37db70bc6858b"
|
||||
source = "git+https://git.cs.tu-dortmund.de/david.venhoff/libnyx-fork#b2a71111ab428fb95055239efe84f6e81f86d4b7"
|
||||
dependencies = [
|
||||
"cbindgen",
|
||||
"config",
|
||||
@ -487,15 +578,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.9.4"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
|
||||
checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.27"
|
||||
version = "0.4.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
||||
checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
@ -505,9 +596,9 @@ checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
|
||||
|
||||
[[package]]
|
||||
name = "memmap2"
|
||||
version = "0.9.7"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "483758ad303d734cec05e5c12b41d7e93e6a6390c5e9dae6bdeb7c1259012d28"
|
||||
checksum = "843a98750cd611cc2965a8213b53b43e715f13c37a9e096c6408e69990961db7"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
@ -527,6 +618,15 @@ version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.8.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
|
||||
dependencies = [
|
||||
"adler2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.26.4"
|
||||
@ -569,7 +669,16 @@ dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.104",
|
||||
"syn 2.0.106",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -601,12 +710,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
version = "0.2.36"
|
||||
version = "0.2.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff24dfcda44452b9816fff4cd4227e1bb73ff5a2f1bc1105aa92fb8565ce44d2"
|
||||
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn 2.0.104",
|
||||
"syn 2.0.106",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -626,9 +735,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.95"
|
||||
version = "1.0.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
||||
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@ -639,12 +748,16 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"libipt",
|
||||
"memmap2",
|
||||
"raw-cpuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "qemu-nyx-runner"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
"csv",
|
||||
"libnyx",
|
||||
"pt-dump-decoder",
|
||||
]
|
||||
@ -712,10 +825,19 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.11.1"
|
||||
name = "raw-cpuid"
|
||||
version = "11.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
|
||||
checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
@ -725,9 +847,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.9"
|
||||
version = "0.4.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
|
||||
checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
@ -736,9 +858,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.5"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||
checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001"
|
||||
|
||||
[[package]]
|
||||
name = "ron"
|
||||
@ -751,6 +873,12 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.1"
|
||||
@ -768,22 +896,22 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "1.0.8"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8"
|
||||
checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
"bitflags 2.9.4",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.60.2",
|
||||
"windows-sys 0.61.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.21"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d"
|
||||
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
@ -823,14 +951,14 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.104",
|
||||
"syn 2.0.106",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.142"
|
||||
version = "1.0.143"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7"
|
||||
checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
@ -976,9 +1104,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.104"
|
||||
version = "2.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
|
||||
checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -987,15 +1115,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.20.0"
|
||||
version = "3.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1"
|
||||
checksum = "84fa4d11fadde498443cca10fd3ac23c951f0dc59e080e9f4b93d4df4e4eea53"
|
||||
dependencies = [
|
||||
"fastrand",
|
||||
"getrandom 0.3.3",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.61.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1088,9 +1216,9 @@ checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.18"
|
||||
version = "1.0.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||
checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
@ -1112,44 +1240,54 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.14.2+wasi-0.2.4"
|
||||
version = "0.14.5+wasi-0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
|
||||
checksum = "a4494f6290a82f5fe584817a676a34b9d6763e8d9d18204009fb31dceca98fd4"
|
||||
dependencies = [
|
||||
"wit-bindgen-rt",
|
||||
"wasip2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasip2"
|
||||
version = "1.0.0+wasi-0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03fa2761397e5bd52002cd7e73110c71af2109aca4e521a9f40473fe685b0a24"
|
||||
dependencies = [
|
||||
"wit-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.100"
|
||||
version = "0.2.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
|
||||
checksum = "7e14915cadd45b529bb8d1f343c4ed0ac1de926144b746e2710f9cd05df6603b"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"rustversion",
|
||||
"wasm-bindgen-macro",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.100"
|
||||
version = "0.2.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
|
||||
checksum = "e28d1ba982ca7923fd01448d5c30c6864d0a14109560296a162f80f305fb93bb"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.104",
|
||||
"syn 2.0.106",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.100"
|
||||
version = "0.2.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
|
||||
checksum = "7c3d463ae3eff775b0c45df9da45d68837702ac35af998361e2c84e7c5ec1b0d"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
@ -1157,22 +1295,22 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.100"
|
||||
version = "0.2.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
|
||||
checksum = "7bb4ce89b08211f923caf51d527662b75bdc9c9c7aab40f86dcb9fb85ac552aa"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.104",
|
||||
"syn 2.0.106",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.100"
|
||||
version = "0.2.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
|
||||
checksum = "f143854a3b13752c6950862c906306adb27c7e839f7414cec8fea35beab624c1"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@ -1205,6 +1343,12 @@ version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.59.0"
|
||||
@ -1223,6 +1367,15 @@ dependencies = [
|
||||
"windows-targets 0.53.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.61.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa"
|
||||
dependencies = [
|
||||
"windows-link 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
@ -1245,7 +1398,7 @@ version = "0.53.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
"windows-link 0.1.3",
|
||||
"windows_aarch64_gnullvm 0.53.0",
|
||||
"windows_aarch64_msvc 0.53.0",
|
||||
"windows_i686_gnu 0.53.0",
|
||||
@ -1354,38 +1507,35 @@ checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.7.12"
|
||||
version = "0.7.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95"
|
||||
checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rt"
|
||||
version = "0.39.0"
|
||||
name = "wit-bindgen"
|
||||
version = "0.45.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
]
|
||||
checksum = "5c573471f125075647d03df72e026074b7203790d41351cd6edc96f46bcccd36"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.26"
|
||||
version = "0.8.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f"
|
||||
checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.26"
|
||||
version = "0.8.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181"
|
||||
checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.104",
|
||||
"syn 2.0.106",
|
||||
]
|
||||
|
@ -10,3 +10,9 @@ edition = "2024"
|
||||
[dependencies]
|
||||
libnyx = { git = "https://git.cs.tu-dortmund.de/david.venhoff/libnyx-fork" }
|
||||
pt-dump-decoder = { path = "pt-dump-decoder" }
|
||||
csv = "1.3.1"
|
||||
clap.workspace = true
|
||||
anyhow = { version = "1.0.99", features = ["backtrace"] }
|
||||
|
||||
[workspace.dependencies]
|
||||
clap = { version = "4.5.47", features = ["derive"] }
|
||||
|
12
README.md
Normal file
12
README.md
Normal file
@ -0,0 +1,12 @@
|
||||
# qemu-nyx-runner
|
||||
|
||||
This repository contains the source code of `qemu-nyx-runner`,
|
||||
a tool which can be used to execute programs inside a `Nyx` hypervisor, trace them with `Intel PT`,
|
||||
and analyze the resulting trace files to estimate its execution without all this instrumentation.
|
||||
|
||||
## Set Up
|
||||
|
||||
To use this project, `KVM-Nyx-fork`s kernel modules have to be installed and loaded.
|
||||
use the `setup-kvm.sh` script for that.
|
||||
|
||||
To run a program with `qemu-nyx-runner`, use `cargo r --release -- path/to/program`
|
18
benchmark_all.sh
Executable file
18
benchmark_all.sh
Executable file
@ -0,0 +1,18 @@
|
||||
set -e
|
||||
|
||||
cargo build --workspace --release
|
||||
|
||||
echo "Disabling turbo..."
|
||||
echo 1 | sudo tee /sys/devices/system/cpu/intel_pstate/no_turbo
|
||||
|
||||
for file in client/src/bin/*.rs; do
|
||||
bin_name=$(basename "$file" .rs)
|
||||
bin_path=./target/release/${bin_name}
|
||||
|
||||
echo "Benchmarking $bin_name..."
|
||||
sudo -E nice -n -20 taskset -c 0 ./target/release/qemu-nyx-runner "$bin_path"
|
||||
done
|
||||
|
||||
echo 0 | sudo tee /sys/devices/system/cpu/intel_pstate/no_turbo
|
||||
|
||||
echo "Done!"
|
101
build.rs
101
build.rs
@ -1,101 +0,0 @@
|
||||
use std::env;
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-changed=client");
|
||||
let out_dir = env::var("OUT_DIR").unwrap();
|
||||
let client_bin = build_client(&out_dir);
|
||||
|
||||
setup_nyx(&out_dir);
|
||||
|
||||
create_nyx_workdir(&out_dir, &client_bin);
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn shell(cwd: impl AsRef<Path>, command_string: &str) {
|
||||
println!(
|
||||
"cargo:warning=Running ({}) {command_string}",
|
||||
cwd.as_ref().display()
|
||||
);
|
||||
|
||||
let cwd = cwd.as_ref();
|
||||
let mut parts = command_string.split(" ");
|
||||
let command_name = parts.next().unwrap();
|
||||
|
||||
let mut command = Command::new(command_name);
|
||||
command.current_dir(cwd);
|
||||
command.stdout(std::process::Stdio::inherit());
|
||||
command.stderr(std::process::Stdio::inherit());
|
||||
command.args(parts);
|
||||
|
||||
let mut process = command.spawn().unwrap();
|
||||
let exit_status = process.wait().unwrap();
|
||||
if !exit_status.success() {
|
||||
panic!(
|
||||
"Command failed with {exit_status}: {}> {command_string}",
|
||||
cwd.display()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds the client and returns the path to its binary
|
||||
fn build_client(out_dir: &str) -> String {
|
||||
// Change the target dir to avoid a cargo target dir deadlock
|
||||
shell(
|
||||
"client",
|
||||
&format!("cargo build --release --target-dir {out_dir}/client_target"),
|
||||
);
|
||||
format!("{out_dir}/client_target/release/client")
|
||||
}
|
||||
|
||||
/// Downloads and compiles qemu-nyx and packer and compiles them for the current architecture
|
||||
/// This means that cross-compilation is not supported
|
||||
fn setup_nyx(out_dir: &str) {
|
||||
let packer_path = std::path::PathBuf::from(format!("{out_dir}/packer"));
|
||||
let qemu_path = std::path::PathBuf::from(format!("{out_dir}/QEMU-Nyx"));
|
||||
if !packer_path.exists() {
|
||||
shell(out_dir, "git clone https://github.com/nyx-fuzz/packer/");
|
||||
}
|
||||
if !qemu_path.exists() {
|
||||
println!("cargo:warning=Cloning and building QEMU-Nyx. This may take a while...");
|
||||
shell(
|
||||
out_dir,
|
||||
"git clone https://github.com/nyx-fuzz/QEMU-Nyx --depth 1",
|
||||
);
|
||||
|
||||
let is_debug_build = match env::var("DEBUG").unwrap().as_str() {
|
||||
"true" => true,
|
||||
"false" => false,
|
||||
other => panic!("Invalid value for DEBUG: {other}"),
|
||||
};
|
||||
let qemu_compile_mode = if is_debug_build {
|
||||
"debug_static"
|
||||
} else {
|
||||
"lto"
|
||||
};
|
||||
shell(
|
||||
qemu_path,
|
||||
&format!("bash compile_qemu_nyx.sh {qemu_compile_mode}"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn create_nyx_workdir(out_dir: &str, client_bin: &str) {
|
||||
// Create the directory and move required binaries to it
|
||||
shell(
|
||||
out_dir,
|
||||
&format!(
|
||||
"python3 packer/packer/nyx_packer.py {client_bin} build afl processor_trace --fast_reload_mode --purge"
|
||||
),
|
||||
);
|
||||
|
||||
// Create the nyx config
|
||||
shell(
|
||||
out_dir,
|
||||
"python3 packer/packer/nyx_config_gen.py build Kernel",
|
||||
);
|
||||
|
||||
// Pass the path to the build directory to src/main.rs
|
||||
println!("cargo:rustc-env=NYX_SHAREDIR={out_dir}/build")
|
||||
}
|
@ -3,8 +3,5 @@ name = "client"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
libc = "*"
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.0"
|
||||
cc = "1.2.36"
|
105
client/build.rs
105
client/build.rs
@ -1,5 +1,104 @@
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-changed=nyx-wrapper.c");
|
||||
//! Somewhat hacky build script for downloading and linking embench.
|
||||
//! Each benchmark is compiled individually, so that we can run them through rust
|
||||
//! and add some instrumentation around the benchmarks.
|
||||
|
||||
cc::Build::new().file("nyx-wrapper.c").compile("nyx");
|
||||
use std::fmt::Write;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use std::str::FromStr;
|
||||
use std::{env, fs};
|
||||
|
||||
const BENCHMARKS: &[&str] = &[
|
||||
"src/ud/libud.c",
|
||||
"src/wikisort/libwikisort.c",
|
||||
"src/nbody/nbody.c",
|
||||
"src/edn/libedn.c",
|
||||
// "src/st/libst.c", Collides with matmult-int
|
||||
"src/aha-mont64/mont64.c",
|
||||
"src/matmult-int/matmult-int.c",
|
||||
"src/slre/libslre.c",
|
||||
"src/tarfind/tarfind.c",
|
||||
"src/sglib-combined/combined.c",
|
||||
"src/huffbench/libhuffbench.c",
|
||||
"src/nsichneu/libnsichneu.c",
|
||||
"src/minver/libminver.c",
|
||||
"src/statemate/libstatemate.c",
|
||||
"src/crc32/crc_32.c",
|
||||
// "src/picojpeg/libpicojpeg.c", Contains multiple source fails, maybe a todo if relevant
|
||||
"src/cubic/basicmath_small.c",
|
||||
"src/md5sum/md5.c",
|
||||
"src/qrduino/qrtest.c",
|
||||
"src/nettle-aes/nettle-aes.c",
|
||||
"src/primecount/primecount.c",
|
||||
"src/nettle-sha256/nettle-sha256.c",
|
||||
];
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
|
||||
let out_dir = env::var("OUT_DIR").unwrap();
|
||||
Command::new("git")
|
||||
.args(["clone", "https://github.com/embench/embench-iot"])
|
||||
.current_dir(&out_dir)
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.wait()
|
||||
.unwrap();
|
||||
|
||||
let embench_dir = PathBuf::from_str(&format!("{out_dir}/embench-iot")).unwrap();
|
||||
|
||||
let mut generated_code = String::new();
|
||||
|
||||
for &benchmark_file in BENCHMARKS {
|
||||
let path = embench_dir.join(benchmark_file);
|
||||
let dir = path.parent().unwrap();
|
||||
let benchmark_name = dir.file_name().unwrap().to_string_lossy().replace("-", "_");
|
||||
|
||||
let mut build = cc::Build::new();
|
||||
build
|
||||
.include(embench_dir.join("support"))
|
||||
.file(embench_dir.join("support/beebsc.c"))
|
||||
.file(&path)
|
||||
.warnings(false)
|
||||
// Just use some roughly accurate value, it just influences how long each benchmark runs
|
||||
.define("CPU_MHZ", "2700");
|
||||
|
||||
// Rename all functions that are defined multiple times to avoid collisions
|
||||
let colliding_functions = [
|
||||
"benchmark",
|
||||
"initialise_benchmark",
|
||||
"warm_caches",
|
||||
"verify_benchmark",
|
||||
];
|
||||
for name in colliding_functions {
|
||||
build.define(name, format!("{benchmark_name}_{name}").as_str());
|
||||
}
|
||||
|
||||
build.compile(&format!("libembench_{benchmark_name}.a"));
|
||||
|
||||
write!(
|
||||
generated_code,
|
||||
r#"
|
||||
#[allow(non_camel_case_types)] pub struct {benchmark_name};
|
||||
|
||||
unsafe extern "C" {{
|
||||
fn {benchmark_name}_benchmark();
|
||||
fn {benchmark_name}_initialise_benchmark();
|
||||
}}
|
||||
|
||||
impl Benchmark for {benchmark_name} {{
|
||||
unsafe fn init() {{
|
||||
unsafe {{ {benchmark_name}_initialise_benchmark(); }}
|
||||
}}
|
||||
|
||||
unsafe fn benchmark() {{
|
||||
unsafe {{ {benchmark_name}_benchmark(); }}
|
||||
}}
|
||||
}}
|
||||
"#
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fs::write(format!("{out_dir}/libembench-sys.rs"), generated_code).unwrap();
|
||||
}
|
||||
|
@ -1,9 +0,0 @@
|
||||
#include "nyx.h"
|
||||
|
||||
void rust_hprintf(const char * format) {
|
||||
hprintf(format);
|
||||
}
|
||||
|
||||
uint32_t rust_perform_hypercall(uint32_t hypercall, uint32_t argument) {
|
||||
return kAFL_hypercall(hypercall, argument);
|
||||
}
|
372
client/nyx.h
372
client/nyx.h
@ -1,372 +0,0 @@
|
||||
/*
|
||||
This file is part of NYX.
|
||||
|
||||
Copyright (c) 2021 Sergej Schumilo
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#ifndef KAFL_USER_H
|
||||
#define KAFL_USER_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#ifndef __MINGW64__
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#ifdef __MINGW64__
|
||||
#ifndef uint64_t
|
||||
#define uint64_t UINT64
|
||||
#endif
|
||||
#ifndef int32_t
|
||||
#define int32_t INT32
|
||||
#endif
|
||||
#ifndef uint8_t
|
||||
#define uint8_t UINT8
|
||||
#endif
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#define HYPERCALL_KAFL_RAX_ID 0x01f
|
||||
#define HYPERCALL_KAFL_ACQUIRE 0
|
||||
#define HYPERCALL_KAFL_GET_PAYLOAD 1
|
||||
|
||||
/* deprecated */
|
||||
#define HYPERCALL_KAFL_GET_PROGRAM 2
|
||||
/* deprecated */
|
||||
#define HYPERCALL_KAFL_GET_ARGV 3
|
||||
|
||||
#define HYPERCALL_KAFL_RELEASE 4
|
||||
#define HYPERCALL_KAFL_SUBMIT_CR3 5
|
||||
#define HYPERCALL_KAFL_SUBMIT_PANIC 6
|
||||
|
||||
/* deprecated */
|
||||
#define HYPERCALL_KAFL_SUBMIT_KASAN 7
|
||||
|
||||
#define HYPERCALL_KAFL_PANIC 8
|
||||
|
||||
/* deprecated */
|
||||
#define HYPERCALL_KAFL_KASAN 9
|
||||
#define HYPERCALL_KAFL_LOCK 10
|
||||
|
||||
/* deprecated */
|
||||
#define HYPERCALL_KAFL_INFO 11
|
||||
|
||||
#define HYPERCALL_KAFL_NEXT_PAYLOAD 12
|
||||
#define HYPERCALL_KAFL_PRINTF 13
|
||||
|
||||
/* deprecated */
|
||||
#define HYPERCALL_KAFL_PRINTK_ADDR 14
|
||||
/* deprecated */
|
||||
#define HYPERCALL_KAFL_PRINTK 15
|
||||
|
||||
/* user space only hypercalls */
|
||||
#define HYPERCALL_KAFL_USER_RANGE_ADVISE 16
|
||||
#define HYPERCALL_KAFL_USER_SUBMIT_MODE 17
|
||||
#define HYPERCALL_KAFL_USER_FAST_ACQUIRE 18
|
||||
/* 19 is already used for exit reason KVM_EXIT_KAFL_TOPA_MAIN_FULL */
|
||||
#define HYPERCALL_KAFL_USER_ABORT 20
|
||||
#define HYPERCALL_KAFL_RANGE_SUBMIT 29
|
||||
#define HYPERCALL_KAFL_REQ_STREAM_DATA 30
|
||||
#define HYPERCALL_KAFL_PANIC_EXTENDED 32
|
||||
|
||||
#define HYPERCALL_KAFL_CREATE_TMP_SNAPSHOT 33
|
||||
#define HYPERCALL_KAFL_DEBUG_TMP_SNAPSHOT 34 /* hypercall for debugging / development purposes */
|
||||
|
||||
#define HYPERCALL_KAFL_GET_HOST_CONFIG 35
|
||||
#define HYPERCALL_KAFL_SET_AGENT_CONFIG 36
|
||||
|
||||
#define HYPERCALL_KAFL_DUMP_FILE 37
|
||||
|
||||
#define HYPERCALL_KAFL_REQ_STREAM_DATA_BULK 38
|
||||
#define HYPERCALL_KAFL_PERSIST_PAGE_PAST_SNAPSHOT 39
|
||||
|
||||
/* hypertrash only hypercalls */
|
||||
#define HYPERTRASH_HYPERCALL_MASK 0xAA000000
|
||||
|
||||
#define HYPERCALL_KAFL_NESTED_PREPARE (0 | HYPERTRASH_HYPERCALL_MASK)
|
||||
#define HYPERCALL_KAFL_NESTED_CONFIG (1 | HYPERTRASH_HYPERCALL_MASK)
|
||||
#define HYPERCALL_KAFL_NESTED_ACQUIRE (2 | HYPERTRASH_HYPERCALL_MASK)
|
||||
#define HYPERCALL_KAFL_NESTED_RELEASE (3 | HYPERTRASH_HYPERCALL_MASK)
|
||||
#define HYPERCALL_KAFL_NESTED_HPRINTF (4 | HYPERTRASH_HYPERCALL_MASK)gre
|
||||
|
||||
#define HPRINTF_MAX_SIZE 0x1000 /* up to 4KB hprintf strings */
|
||||
|
||||
/* specific defines to enable support for NYX hypercalls on unmodified KVM builds */
|
||||
/* PIO port number used by VMWare backdoor */
|
||||
#define VMWARE_PORT 0x5658
|
||||
/* slightly changed RAX_ID to avoid vmware backdoor collisions */
|
||||
#define HYPERCALL_KAFL_RAX_ID_VMWARE 0x8080801f
|
||||
|
||||
typedef struct{
|
||||
int32_t size;
|
||||
uint8_t data[];
|
||||
} kAFL_payload;
|
||||
|
||||
typedef struct{
|
||||
uint64_t ip[4];
|
||||
uint64_t size[4];
|
||||
uint8_t enabled[4];
|
||||
} kAFL_ranges;
|
||||
|
||||
#define KAFL_MODE_64 0
|
||||
#define KAFL_MODE_32 1
|
||||
#define KAFL_MODE_16 2
|
||||
|
||||
#if defined(__i386__)
|
||||
#define KAFL_HYPERCALL_NO_PT(_ebx, _ecx) ({ \
|
||||
uint32_t _eax = HYPERCALL_KAFL_RAX_ID_VMWARE; \
|
||||
do{ \
|
||||
asm volatile( \
|
||||
"outl %%eax, %%dx;" \
|
||||
: "+a" (_eax) \
|
||||
: "b" (_ebx), "c" (_ecx), "d" (VMWARE_PORT) \
|
||||
: "cc", "memory" \
|
||||
); \
|
||||
} while(0); \
|
||||
_eax; \
|
||||
})
|
||||
|
||||
#define KAFL_HYPERCALL_PT(_ebx, _ecx) ({ \
|
||||
uint32_t _eax = HYPERCALL_KAFL_RAX_ID; \
|
||||
do{ \
|
||||
asm volatile( \
|
||||
"vmcall;" \
|
||||
: "+a" (_eax) \
|
||||
: "b" (_ebx), "c" (_ecx) \
|
||||
: "cc", "memory" \
|
||||
); \
|
||||
} while(0); \
|
||||
_eax; \
|
||||
})
|
||||
|
||||
#else
|
||||
|
||||
#define KAFL_HYPERCALL_NO_PT(_rbx, _rcx) ({ \
|
||||
uint64_t _rax = HYPERCALL_KAFL_RAX_ID_VMWARE; \
|
||||
do{ \
|
||||
asm volatile( \
|
||||
"outl %%eax, %%dx;" \
|
||||
: "+a" (_rax) \
|
||||
: "b" (_rbx), "c" (_rcx), "d" (VMWARE_PORT) \
|
||||
: "cc", "memory" \
|
||||
); \
|
||||
} while(0); \
|
||||
_rax; \
|
||||
})
|
||||
|
||||
#define KAFL_HYPERCALL_PT(_rbx, _rcx) ({ \
|
||||
uint64_t _rax = HYPERCALL_KAFL_RAX_ID; \
|
||||
do{ \
|
||||
asm volatile( \
|
||||
"vmcall;" \
|
||||
: "+a" (_rax) \
|
||||
: "b" (_rbx), "c" (_rcx) \
|
||||
: "cc", "memory" \
|
||||
); \
|
||||
} while(0); \
|
||||
_rax; \
|
||||
})
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__i386__)
|
||||
#ifdef NO_PT_NYX
|
||||
|
||||
#define KAFL_HYPERCALL(__rbx, __rcx) \
|
||||
KAFL_HYPERCALL_NO_PT(_rbx, _rcx); \
|
||||
}while(0)
|
||||
|
||||
static inline uint32_t kAFL_hypercall(uint32_t rbx, uint32_t rcx){
|
||||
return KAFL_HYPERCALL_NO_PT(rbx, rcx);
|
||||
}
|
||||
#else
|
||||
#define KAFL_HYPERCALL(__rbx, __rcx) \
|
||||
KAFL_HYPERCALL_PT(_rbx, _rcx); \
|
||||
}while(0)
|
||||
|
||||
static inline uint32_t kAFL_hypercall(uint32_t rbx, uint32_t rcx){
|
||||
# ifndef __NOKAFL
|
||||
return KAFL_HYPERCALL_PT(rbx, rcx);
|
||||
# endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#elif defined(__x86_64__)
|
||||
#ifdef NO_PT_NYX
|
||||
|
||||
#define KAFL_HYPERCALL(__rbx, __rcx) \
|
||||
KAFL_HYPERCALL_NO_PT(_rbx, _rcx); \
|
||||
}while(0)
|
||||
|
||||
static inline uint64_t kAFL_hypercall(uint64_t rbx, uint64_t rcx){
|
||||
return KAFL_HYPERCALL_NO_PT(rbx, rcx);
|
||||
}
|
||||
#else
|
||||
#define KAFL_HYPERCALL(__rbx, __rcx) \
|
||||
KAFL_HYPERCALL_PT(_rbx, _rcx); \
|
||||
}while(0)
|
||||
|
||||
static inline uint64_t kAFL_hypercall(uint64_t rbx, uint64_t rcx){
|
||||
# ifndef __NOKAFL
|
||||
return KAFL_HYPERCALL_PT(rbx, rcx);
|
||||
# endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//extern uint8_t* hprintf_buffer;
|
||||
|
||||
static inline uint8_t alloc_hprintf_buffer(uint8_t** hprintf_buffer){
|
||||
if(!*hprintf_buffer){
|
||||
#ifdef __MINGW64__
|
||||
*hprintf_buffer = (uint8_t*)VirtualAlloc(0, HPRINTF_MAX_SIZE, MEM_COMMIT, PAGE_READWRITE);
|
||||
#else
|
||||
*hprintf_buffer = (uint8_t*)mmap((void*)NULL, HPRINTF_MAX_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
#endif
|
||||
if(!*hprintf_buffer){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef __NOKAFL
|
||||
int (*hprintf)(const char * format, ...) = printf;
|
||||
#else
|
||||
static void hprintf(const char * format, ...) __attribute__ ((unused));
|
||||
|
||||
static void hprintf(const char * format, ...){
|
||||
static uint8_t* hprintf_buffer = NULL;
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
if(alloc_hprintf_buffer(&hprintf_buffer)){
|
||||
vsnprintf((char*)hprintf_buffer, HPRINTF_MAX_SIZE, format, args);
|
||||
kAFL_hypercall(HYPERCALL_KAFL_PRINTF, (uintptr_t)hprintf_buffer);
|
||||
}
|
||||
//vprintf(format, args);
|
||||
va_end(args);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void habort(char* msg){
|
||||
kAFL_hypercall(HYPERCALL_KAFL_USER_ABORT, (uintptr_t)msg);
|
||||
}
|
||||
|
||||
#define NYX_HOST_MAGIC 0x4878794e
|
||||
#define NYX_AGENT_MAGIC 0x4178794e
|
||||
|
||||
#define NYX_HOST_VERSION 2
|
||||
#define NYX_AGENT_VERSION 1
|
||||
|
||||
typedef struct host_config_s{
|
||||
uint32_t host_magic;
|
||||
uint32_t host_version;
|
||||
uint32_t bitmap_size;
|
||||
uint32_t ijon_bitmap_size;
|
||||
uint32_t payload_buffer_size;
|
||||
uint32_t worker_id;
|
||||
/* more to come */
|
||||
} __attribute__((packed)) host_config_t;
|
||||
|
||||
typedef struct agent_config_s{
|
||||
uint32_t agent_magic;
|
||||
uint32_t agent_version;
|
||||
uint8_t agent_timeout_detection;
|
||||
uint8_t agent_tracing;
|
||||
uint8_t agent_ijon_tracing;
|
||||
uint8_t agent_non_reload_mode;
|
||||
uint64_t trace_buffer_vaddr;
|
||||
uint64_t ijon_trace_buffer_vaddr;
|
||||
uint32_t coverage_bitmap_size;
|
||||
uint32_t input_buffer_size; // TODO: remove this later
|
||||
|
||||
uint8_t dump_payloads; /* set by hypervisor */
|
||||
/* more to come */
|
||||
} __attribute__((packed)) agent_config_t;
|
||||
|
||||
typedef struct kafl_dump_file_s{
|
||||
uint64_t file_name_str_ptr;
|
||||
uint64_t data_ptr;
|
||||
uint64_t bytes;
|
||||
uint8_t append;
|
||||
} __attribute__((packed)) kafl_dump_file_t;
|
||||
|
||||
|
||||
enum nyx_cpu_type{
|
||||
unkown = 0,
|
||||
nyx_cpu_v1, /* Nyx CPU used by KVM-PT */
|
||||
nyx_cpu_v2 /* Nyx CPU used by vanilla KVM + VMWare backdoor */
|
||||
};
|
||||
|
||||
#define cpuid(in,a,b,c,d)\
|
||||
asm("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in));
|
||||
|
||||
static int is_nyx_vcpu(void){
|
||||
unsigned long eax,ebx,ecx,edx;
|
||||
char str[8];
|
||||
cpuid(0x80000004,eax,ebx,ecx,edx);
|
||||
|
||||
for(int j=0;j<4;j++){
|
||||
str[j] = eax >> (8*j);
|
||||
str[j+4] = ebx >> (8*j);
|
||||
}
|
||||
|
||||
return !memcmp(&str, "NYX vCPU", 8);
|
||||
}
|
||||
|
||||
static int get_nyx_cpu_type(void){
|
||||
unsigned long eax,ebx,ecx,edx;
|
||||
char str[9];
|
||||
cpuid(0x80000004,eax,ebx,ecx,edx);
|
||||
|
||||
for(int j=0;j<4;j++){
|
||||
str[j] = eax >> (8*j);
|
||||
str[j+4] = ebx >> (8*j);
|
||||
}
|
||||
|
||||
if(memcmp(&str, "NYX vCPU", 8) != 0){
|
||||
return unkown;
|
||||
}
|
||||
|
||||
for(int j=0;j<4;j++){
|
||||
str[j] = ecx >> (8*j);
|
||||
str[j+4] = edx >> (8*j);
|
||||
}
|
||||
|
||||
if(memcmp(&str, " (NO-PT)", 8) != 0){
|
||||
return nyx_cpu_v1;
|
||||
}
|
||||
|
||||
return nyx_cpu_v2;
|
||||
|
||||
str[8] = 0;
|
||||
printf("ECX: %s\n", str);
|
||||
}
|
||||
|
||||
typedef struct req_data_bulk_s{
|
||||
char file_name[256];
|
||||
uint64_t num_addresses;
|
||||
uint64_t addresses[479];
|
||||
} req_data_bulk_t;
|
||||
|
||||
#endif
|
5
client/src/bin/client_combined.rs
Normal file
5
client/src/bin/client_combined.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use client::program;
|
||||
|
||||
fn main() {
|
||||
program::<client::embench_sys::sglib_combined>();
|
||||
}
|
5
client/src/bin/client_crc_32.rs
Normal file
5
client/src/bin/client_crc_32.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use client::program;
|
||||
|
||||
fn main() {
|
||||
program::<client::embench_sys::crc32>();
|
||||
}
|
5
client/src/bin/client_edn.rs
Normal file
5
client/src/bin/client_edn.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use client::program;
|
||||
|
||||
fn main() {
|
||||
program::<client::embench_sys::edn>();
|
||||
}
|
5
client/src/bin/client_huffbench.rs
Normal file
5
client/src/bin/client_huffbench.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use client::program;
|
||||
|
||||
fn main() {
|
||||
program::<client::embench_sys::huffbench>();
|
||||
}
|
5
client/src/bin/client_matmult-int.rs
Normal file
5
client/src/bin/client_matmult-int.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use client::program;
|
||||
|
||||
fn main() {
|
||||
program::<client::embench_sys::matmult_int>();
|
||||
}
|
5
client/src/bin/client_md5.rs
Normal file
5
client/src/bin/client_md5.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use client::program;
|
||||
|
||||
fn main() {
|
||||
program::<client::embench_sys::md5sum>();
|
||||
}
|
5
client/src/bin/client_minver.rs
Normal file
5
client/src/bin/client_minver.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use client::program;
|
||||
|
||||
fn main() {
|
||||
program::<client::embench_sys::minver>();
|
||||
}
|
5
client/src/bin/client_mont64.rs
Normal file
5
client/src/bin/client_mont64.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use client::program;
|
||||
|
||||
fn main() {
|
||||
program::<client::embench_sys::aha_mont64>();
|
||||
}
|
5
client/src/bin/client_nbody.rs
Normal file
5
client/src/bin/client_nbody.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use client::program;
|
||||
|
||||
fn main() {
|
||||
program::<client::embench_sys::nbody>();
|
||||
}
|
5
client/src/bin/client_nettle-aes.rs
Normal file
5
client/src/bin/client_nettle-aes.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use client::program;
|
||||
|
||||
fn main() {
|
||||
program::<client::embench_sys::nettle_aes>();
|
||||
}
|
5
client/src/bin/client_nettle-sha256.rs
Normal file
5
client/src/bin/client_nettle-sha256.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use client::program;
|
||||
|
||||
fn main() {
|
||||
program::<client::embench_sys::nettle_sha256>();
|
||||
}
|
5
client/src/bin/client_nsichneu.rs
Normal file
5
client/src/bin/client_nsichneu.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use client::program;
|
||||
|
||||
fn main() {
|
||||
program::<client::embench_sys::nsichneu>();
|
||||
}
|
5
client/src/bin/client_primecount.rs
Normal file
5
client/src/bin/client_primecount.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use client::program;
|
||||
|
||||
fn main() {
|
||||
program::<client::embench_sys::primecount>();
|
||||
}
|
5
client/src/bin/client_slre.rs
Normal file
5
client/src/bin/client_slre.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use client::program;
|
||||
|
||||
fn main() {
|
||||
program::<client::embench_sys::slre>();
|
||||
}
|
5
client/src/bin/client_statemate.rs
Normal file
5
client/src/bin/client_statemate.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use client::program;
|
||||
|
||||
fn main() {
|
||||
program::<client::embench_sys::statemate>();
|
||||
}
|
5
client/src/bin/client_tarfind.rs
Normal file
5
client/src/bin/client_tarfind.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use client::program;
|
||||
|
||||
fn main() {
|
||||
program::<client::embench_sys::tarfind>();
|
||||
}
|
5
client/src/bin/client_ud.rs
Normal file
5
client/src/bin/client_ud.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use client::program;
|
||||
|
||||
fn main() {
|
||||
program::<client::embench_sys::ud>();
|
||||
}
|
5
client/src/bin/client_wikisort.rs
Normal file
5
client/src/bin/client_wikisort.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use client::program;
|
||||
|
||||
fn main() {
|
||||
program::<client::embench_sys::wikisort>();
|
||||
}
|
32
client/src/lib.rs
Normal file
32
client/src/lib.rs
Normal file
@ -0,0 +1,32 @@
|
||||
use std::arch::asm;
|
||||
|
||||
pub mod embench_sys {
|
||||
pub trait Benchmark {
|
||||
unsafe fn init();
|
||||
|
||||
unsafe fn benchmark();
|
||||
}
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/libembench-sys.rs"));
|
||||
}
|
||||
|
||||
pub use embench_sys::Benchmark;
|
||||
|
||||
fn ptwrite(val: u32) {
|
||||
unsafe {
|
||||
asm!("ptwrite {0:e}", in(reg) val);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn program<B: Benchmark>() {
|
||||
unsafe {
|
||||
B::init();
|
||||
}
|
||||
let start = std::time::Instant::now();
|
||||
ptwrite(42);
|
||||
unsafe {
|
||||
B::benchmark();
|
||||
}
|
||||
ptwrite(43);
|
||||
println!("{}", start.elapsed().as_secs_f64());
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
use std::arch::asm;
|
||||
use std::ffi::{CStr, CString};
|
||||
|
||||
unsafe extern "C" {
|
||||
fn rust_hprintf(format: *const libc::c_char);
|
||||
|
||||
fn rust_perform_hypercall(hypercall: u32, argument: u32);
|
||||
}
|
||||
|
||||
fn hprint(message: &CStr) {
|
||||
unsafe {
|
||||
rust_hprintf(message.as_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
enum NyxHypercall {
|
||||
Acquire = 0,
|
||||
// Release = 4,
|
||||
// Panic = 8,
|
||||
}
|
||||
|
||||
fn hypercall(hypercall: NyxHypercall, argument: u32) {
|
||||
unsafe {
|
||||
rust_perform_hypercall(hypercall as u32, argument);
|
||||
}
|
||||
}
|
||||
|
||||
fn ptwrite(val: u32) {
|
||||
unsafe {
|
||||
asm!("ptwrite {0:e}", in(reg) val);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
hprint(c"Acuiring again!\n");
|
||||
hypercall(NyxHypercall::Acquire, 100);
|
||||
let start = std::time::Instant::now();
|
||||
let mut last_time = std::time::Duration::ZERO;
|
||||
ptwrite(42);
|
||||
loop {
|
||||
let elapsed = start.elapsed();
|
||||
if elapsed.as_secs() >= 2 {
|
||||
let msg = CString::new(format!("Passed: {:?}\n", elapsed.as_secs())).unwrap();
|
||||
let msg: &'static CStr = Box::leak(Box::new(msg));
|
||||
hprint(msg);
|
||||
break;
|
||||
}
|
||||
if last_time.as_secs() != elapsed.as_secs() {
|
||||
hprint(c"A second passed\n");
|
||||
}
|
||||
last_time = elapsed;
|
||||
}
|
||||
ptwrite(43);
|
||||
hprint(c"Done\n");
|
||||
}
|
@ -9,3 +9,4 @@ edition = "2024"
|
||||
[dependencies]
|
||||
libipt = { version = "0.4.0", features = ["libipt_master"] }
|
||||
memmap2 = "0.9.7"
|
||||
raw-cpuid = "11.5.0"
|
@ -1,6 +1,8 @@
|
||||
use libipt::enc_dec_builder::EncoderDecoderBuilder;
|
||||
use libipt::packet::{Packet, PacketDecoder};
|
||||
use memmap2::Mmap;
|
||||
use raw_cpuid::{CpuId, cpuid};
|
||||
use std::collections::HashMap;
|
||||
use std::error::Error;
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
@ -9,70 +11,130 @@ use std::time::Duration;
|
||||
#[derive(Debug)]
|
||||
pub struct AnalyzeData {
|
||||
pub packets: u64,
|
||||
pub cycles: u64,
|
||||
pub time: Duration,
|
||||
pub time_outside_hypervisor: Duration,
|
||||
pub lost_cyc: u64,
|
||||
pub time_qemu: Duration,
|
||||
pub time_tsc: Duration,
|
||||
pub time_cyc: Duration,
|
||||
pub time_main: Duration,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
enum Scope {
|
||||
Main,
|
||||
PreRun,
|
||||
PostRun,
|
||||
}
|
||||
|
||||
pub fn analyze_dump(path: impl AsRef<Path>) -> Result<AnalyzeData, Box<dyn Error>> {
|
||||
pub fn analyze_dump(
|
||||
path: impl AsRef<Path>,
|
||||
qemu_duration: Duration,
|
||||
) -> Result<AnalyzeData, Box<dyn Error>> {
|
||||
let trace_file = File::open(path)?;
|
||||
// Safety: We only read from the trace file, never write to it
|
||||
// UB occurs when it is modified out-of-process, though
|
||||
let mmap = unsafe { Mmap::map(&trace_file)? };
|
||||
|
||||
let builder = EncoderDecoderBuilder::<PacketDecoder<()>>::new();
|
||||
// I hope this is safe if the buffer is never written to
|
||||
// Safety: The mmap outlives the builder
|
||||
let builder = unsafe { builder.buffer_from_raw(mmap.as_ptr() as *mut _, mmap.len()) };
|
||||
|
||||
let mut decoder = builder.build()?;
|
||||
// Required before it can be used
|
||||
decoder.sync_forward()?;
|
||||
|
||||
let mut segments = vec![(Scope::PreRun, 0u64)];
|
||||
let mut segments = vec![(Scope::PreRun, Duration::ZERO)];
|
||||
let mut total = 0u64;
|
||||
let mut lost_cyc = 0;
|
||||
|
||||
// cpuid(0x16):ecx returns the bus frequency in mHz (See volume 2, chapter 1.3 CPUID in the intel manual)
|
||||
// Combined with the core to bus ration we can calculate the core frequency
|
||||
let f_bus = cpuid!(0x16).ecx as f64 * 1_000_000.0;
|
||||
let mut current_cbr = 0u8;
|
||||
|
||||
let mut cyc_duration_before_first_tsc = Duration::ZERO;
|
||||
let mut first_tsc = None::<u64>;
|
||||
let mut cyc_duration_after_last_tsc = Duration::ZERO;
|
||||
let mut last_tsc = None::<u64>;
|
||||
|
||||
let mut seen_cbrs = HashMap::<u8, u64>::new();
|
||||
|
||||
for packet in decoder {
|
||||
total += 1;
|
||||
match packet {
|
||||
Ok(Packet::Cyc(cyc)) => {
|
||||
segments.last_mut().unwrap().1 += cyc.value();
|
||||
// Ignore cycle packets when there was no cbr packet yet.
|
||||
if current_cbr == 0 {
|
||||
lost_cyc += 1;
|
||||
continue;
|
||||
}
|
||||
let f_core = f_bus * current_cbr as f64;
|
||||
let duration = Duration::from_secs_f64(cyc.value() as f64 / f_core);
|
||||
if first_tsc.is_none() {
|
||||
cyc_duration_before_first_tsc += duration;
|
||||
}
|
||||
if last_tsc.is_some() {
|
||||
cyc_duration_after_last_tsc += duration;
|
||||
}
|
||||
segments.last_mut().unwrap().1 += duration;
|
||||
}
|
||||
Ok(Packet::Vmcs(_)) => {
|
||||
// last_packet_vmcs = true;
|
||||
Ok(Packet::Tsc(tsc)) => {
|
||||
if first_tsc.is_none() {
|
||||
first_tsc = Some(tsc.tsc());
|
||||
}
|
||||
cyc_duration_after_last_tsc = Duration::ZERO;
|
||||
last_tsc = Some(tsc.tsc());
|
||||
}
|
||||
Ok(Packet::Cbr(cbr)) => {
|
||||
current_cbr = cbr.ratio();
|
||||
*seen_cbrs.entry(cbr.ratio()).or_default() += 1;
|
||||
}
|
||||
Ok(Packet::Ptw(ptwrite)) => {
|
||||
if ptwrite.payload() == 42 {
|
||||
// Main enter
|
||||
segments.push((Scope::Main, 0));
|
||||
segments.push((Scope::Main, Duration::ZERO));
|
||||
} else if ptwrite.payload() == 43 {
|
||||
// Main exit
|
||||
segments.push((Scope::PostRun, 0));
|
||||
segments.push((Scope::PostRun, Duration::ZERO));
|
||||
} else {
|
||||
println!("GOT PTWRITE!!!!!: {ptwrite:?}");
|
||||
// println!("GOT PTWRITE!!!!!: {ptwrite:?}");
|
||||
}
|
||||
}
|
||||
Ok(Packet::Ovf(overflow)) => {
|
||||
panic!("Got overflow packet: {overflow:?}, index {total}");
|
||||
}
|
||||
Ok(_) => {}
|
||||
Err(error) => println!("Got error: {error:?}"),
|
||||
}
|
||||
}
|
||||
// dbg!(&segments);
|
||||
let cycles_main: u64 = segments
|
||||
.iter()
|
||||
.filter(|(scope, _)| matches!(scope, Scope::Main))
|
||||
.map(|(_, cycles)| cycles)
|
||||
.sum();
|
||||
let cycles_total = segments.iter().map(|(_, cycles)| cycles).sum();
|
||||
let total_seconds = cycles_total as f64 / 2_700_000_000.0;
|
||||
let total_seconds_no_hypervisor = cycles_main as f64 / 2_700_000_000.0;
|
||||
// dbg!(seen_cbrs);
|
||||
let duration_total = segments.iter().map(|(_, duration)| *duration).sum();
|
||||
let main_duration = duration_in_mode(&segments, Scope::Main);
|
||||
|
||||
let f_tsc = CpuId::new()
|
||||
.get_tsc_info()
|
||||
.unwrap()
|
||||
.tsc_frequency()
|
||||
.unwrap();
|
||||
let first_tsc_main = first_tsc.expect("Should have recorded a tsc") as f64 / f_tsc as f64
|
||||
+ cyc_duration_before_first_tsc.as_secs_f64();
|
||||
let last_tsc_main = last_tsc.expect("Should have recorded a tsc") as f64 / f_tsc as f64
|
||||
+ cyc_duration_after_last_tsc.as_secs_f64();
|
||||
let total_seconds_tsc = last_tsc_main - first_tsc_main;
|
||||
|
||||
Ok(AnalyzeData {
|
||||
packets: total,
|
||||
cycles: cycles_total,
|
||||
time: Duration::from_secs_f64(total_seconds),
|
||||
time_outside_hypervisor: Duration::from_secs_f64(total_seconds_no_hypervisor),
|
||||
lost_cyc,
|
||||
time_cyc: duration_total,
|
||||
time_main: main_duration,
|
||||
time_tsc: Duration::from_secs_f64(total_seconds_tsc),
|
||||
time_qemu: qemu_duration,
|
||||
})
|
||||
}
|
||||
|
||||
fn duration_in_mode(segments: &[(Scope, Duration)], scope: Scope) -> Duration {
|
||||
segments
|
||||
.iter()
|
||||
.filter(|(it, _)| *it == scope)
|
||||
.map(|(_, duration)| *duration)
|
||||
.sum::<Duration>()
|
||||
}
|
||||
|
10
setup-kvm.sh
Executable file
10
setup-kvm.sh
Executable file
@ -0,0 +1,10 @@
|
||||
if [ ! -d KVM-Nyx-fork ]; then
|
||||
echo "Could not find KVM-Nyx-fork"
|
||||
echo "Download from https://git.cs.tu-dortmund.de/david.venhoff/KVM-Nyx-fork"
|
||||
echo "Then setup the config with \`make oldconfig\`"
|
||||
exit
|
||||
fi
|
||||
cd KVM-Nyx-fork || exit
|
||||
sh compile_kvm_nyx_standalone.sh
|
||||
sh load_kvm_nyx.sh
|
||||
echo "Done"
|
17
src/benchmark.rs
Normal file
17
src/benchmark.rs
Normal file
@ -0,0 +1,17 @@
|
||||
use std::fmt::Debug;
|
||||
use std::io::Write;
|
||||
|
||||
/// Used for benchmarking nyx + pt, nyx - pt, and the baseline
|
||||
pub trait Benchmark {
|
||||
const TITLE: &'static str;
|
||||
|
||||
type BenchmarkResult: ToCsv + Debug;
|
||||
|
||||
fn execute_once(&mut self) -> Self::BenchmarkResult;
|
||||
}
|
||||
|
||||
pub trait ToCsv {
|
||||
const HEADERS: &'static [&'static str];
|
||||
|
||||
fn write(&self, writer: &mut csv::Writer<impl Write>) -> csv::Result<()>;
|
||||
}
|
34
src/benchmark_baseline.rs
Normal file
34
src/benchmark_baseline.rs
Normal file
@ -0,0 +1,34 @@
|
||||
use crate::benchmark::{Benchmark, ToCsv};
|
||||
use csv::Writer;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
use std::time::Duration;
|
||||
|
||||
/// Executes the given program without any instrumentation
|
||||
pub struct Baseline<'a>(pub &'a Path);
|
||||
|
||||
impl Benchmark for Baseline<'_> {
|
||||
const TITLE: &'static str = "baseline";
|
||||
|
||||
type BenchmarkResult = Duration;
|
||||
|
||||
fn execute_once(&mut self) -> Self::BenchmarkResult {
|
||||
let output = Command::new(self.0)
|
||||
.output()
|
||||
.expect("Command should succeed");
|
||||
let output = String::from_utf8_lossy(&output.stdout);
|
||||
let Ok(duration) = output.trim().parse() else {
|
||||
panic!("Invalid output: {}", output);
|
||||
};
|
||||
Duration::from_secs_f64(duration)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCsv for Duration {
|
||||
const HEADERS: &'static [&'static str] = &["time"];
|
||||
|
||||
fn write(&self, writer: &mut Writer<impl Write>) -> csv::Result<()> {
|
||||
writer.write_record([self.as_secs_f64().to_string()])
|
||||
}
|
||||
}
|
26
src/benchmark_nyx_no_pt.rs
Normal file
26
src/benchmark_nyx_no_pt.rs
Normal file
@ -0,0 +1,26 @@
|
||||
use crate::benchmark::Benchmark;
|
||||
use crate::nyx::{NyxRunner, TraceMode};
|
||||
use std::path::Path;
|
||||
use std::time::Duration;
|
||||
|
||||
/// Executes the given program with nyx, but without tracing
|
||||
pub struct BenchmarkNyxNoPt(NyxRunner);
|
||||
|
||||
impl BenchmarkNyxNoPt {
|
||||
pub fn new(client_path: &Path) -> anyhow::Result<Self> {
|
||||
Ok(BenchmarkNyxNoPt(NyxRunner::setup(
|
||||
client_path,
|
||||
TraceMode::Disabled,
|
||||
)?))
|
||||
}
|
||||
}
|
||||
|
||||
impl Benchmark for BenchmarkNyxNoPt {
|
||||
const TITLE: &'static str = "nyx";
|
||||
|
||||
type BenchmarkResult = Duration;
|
||||
|
||||
fn execute_once(&mut self) -> Self::BenchmarkResult {
|
||||
self.0.execute()
|
||||
}
|
||||
}
|
43
src/benchmark_nyx_pt.rs
Normal file
43
src/benchmark_nyx_pt.rs
Normal file
@ -0,0 +1,43 @@
|
||||
use crate::benchmark::{Benchmark, ToCsv};
|
||||
use crate::nyx::{NyxRunner, TraceMode};
|
||||
use csv::Writer;
|
||||
use pt_dump_decoder::{AnalyzeData, analyze_dump};
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
/// Executes the given program with nyx and tracing
|
||||
pub struct BenchmarkNyx(NyxRunner);
|
||||
|
||||
impl BenchmarkNyx {
|
||||
pub fn new(client_bin: &Path) -> anyhow::Result<Self> {
|
||||
Ok(BenchmarkNyx(NyxRunner::setup(
|
||||
client_bin,
|
||||
TraceMode::Enabled,
|
||||
)?))
|
||||
}
|
||||
}
|
||||
|
||||
impl Benchmark for BenchmarkNyx {
|
||||
const TITLE: &'static str = "nyx_and_pt";
|
||||
|
||||
type BenchmarkResult = AnalyzeData;
|
||||
|
||||
fn execute_once(&mut self) -> AnalyzeData {
|
||||
let qemu_duration = self.0.execute();
|
||||
let dump_path = self.0.workdir().join("pt_trace_dump_0");
|
||||
analyze_dump(dump_path, qemu_duration).expect("Should be able to analyze the data")
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCsv for AnalyzeData {
|
||||
const HEADERS: &'static [&'static str] = &["time_main_cyc", "time_total_cyc", "time_total_tsc", "time_total_qemu"];
|
||||
|
||||
fn write(&self, writer: &mut Writer<impl Write>) -> csv::Result<()> {
|
||||
writer.write_record([
|
||||
self.time_main.as_secs_f64().to_string(),
|
||||
self.time_cyc.as_secs_f64().to_string(),
|
||||
self.time_tsc.as_secs_f64().to_string(),
|
||||
self.time_qemu.as_secs_f64().to_string(),
|
||||
])
|
||||
}
|
||||
}
|
130
src/main.rs
130
src/main.rs
@ -1,47 +1,105 @@
|
||||
//! Translated from libnyx/test.c
|
||||
|
||||
use libnyx::ffi::nyx_print_aux_buffer;
|
||||
use libnyx::{NyxConfig, NyxProcess, NyxProcessRole, NyxReturnValue};
|
||||
use pt_dump_decoder::analyze_dump;
|
||||
use std::error::Error;
|
||||
mod benchmark;
|
||||
mod benchmark_baseline;
|
||||
mod benchmark_nyx_no_pt;
|
||||
mod benchmark_nyx_pt;
|
||||
mod nyx;
|
||||
|
||||
const WORKDIR_PATH: &str = "/tmp/wdir";
|
||||
// The sharedir path gets set by the build script
|
||||
const SHAREDIR_PATH: &str = env!("NYX_SHAREDIR");
|
||||
use crate::benchmark::{Benchmark, ToCsv};
|
||||
use crate::benchmark_baseline::Baseline;
|
||||
use crate::benchmark_nyx_no_pt::BenchmarkNyxNoPt;
|
||||
use crate::benchmark_nyx_pt::BenchmarkNyx;
|
||||
use anyhow::Context;
|
||||
use clap::Parser;
|
||||
use std::fmt::Debug;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
let _ = std::fs::remove_dir_all(WORKDIR_PATH);
|
||||
run_client()?;
|
||||
println!("Analyzing pt data...");
|
||||
#[derive(Debug, Parser)]
|
||||
#[command(about = "Tool to execute a program with nyx and trace it with intel pt")]
|
||||
struct Args {
|
||||
/// Path to the client binary to execute
|
||||
client: PathBuf,
|
||||
/// Directory where the benchmark files get stored
|
||||
#[arg(short = 'o', long = "output", default_value = "benchmarks")]
|
||||
output_dir: PathBuf,
|
||||
/// Whether to only execute a single nyx run, used for testing
|
||||
#[arg(short = 'd', long = "debug", default_value = "false")]
|
||||
debug: bool,
|
||||
}
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
let args = Args::parse();
|
||||
|
||||
if args.debug {
|
||||
dbg!(BenchmarkNyx::new(&args.client)?.execute_once());
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let binary_name = args.client.file_name().unwrap().to_str().unwrap();
|
||||
{
|
||||
let benchmark_nyx = BenchmarkNyx::new(&args.client)?;
|
||||
benchmark(binary_name, &args.output_dir, benchmark_nyx)?;
|
||||
}
|
||||
{
|
||||
let benchmark_nyx_no_pt = BenchmarkNyxNoPt::new(&args.client)?;
|
||||
benchmark(binary_name, &args.output_dir, benchmark_nyx_no_pt)?;
|
||||
}
|
||||
benchmark(binary_name, &args.output_dir, Baseline(&args.client))?;
|
||||
|
||||
let dump_path = format!("{WORKDIR_PATH}/pt_trace_dump_0");
|
||||
let result = analyze_dump(dump_path)?;
|
||||
println!("{result:?}");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_client() -> Result<(), Box<dyn Error>> {
|
||||
let mut nyx_config = NyxConfig::load(SHAREDIR_PATH)?;
|
||||
nyx_config.set_workdir_path(WORKDIR_PATH.to_string());
|
||||
nyx_config.set_input_buffer_size(0x2000);
|
||||
nyx_config.set_nyx_debug_log_path("qemu_nyx.log".to_string());
|
||||
fn benchmark<B: Benchmark>(
|
||||
binary_name: &str,
|
||||
output_dir: &Path,
|
||||
mut benchmark: B,
|
||||
) -> anyhow::Result<()> {
|
||||
warmup(&mut benchmark);
|
||||
let results = benchmark_loop(&mut benchmark);
|
||||
write_results::<B>(binary_name, output_dir, &results).with_context(|| "Writing results")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Warm up to make sure caches are initialized, etc.
|
||||
fn warmup(benchmark: &mut impl Benchmark) {
|
||||
let warmup_duration = Duration::from_secs(5);
|
||||
println!("Warming up for {warmup_duration:?}");
|
||||
let mut iterations = 0;
|
||||
let start = Instant::now();
|
||||
while start.elapsed() < warmup_duration {
|
||||
benchmark.execute_once();
|
||||
iterations += 1;
|
||||
}
|
||||
println!("Warmed up for {iterations} iterations");
|
||||
}
|
||||
|
||||
fn benchmark_loop<B: Benchmark>(benchmark: &mut B) -> Vec<B::BenchmarkResult> {
|
||||
let n = 500;
|
||||
println!("Perform {n} iterations...");
|
||||
(0..n)
|
||||
.map(|_| std::hint::black_box(benchmark.execute_once()))
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
fn write_results<B: Benchmark>(
|
||||
binary_name: &str,
|
||||
output_dir: &Path,
|
||||
results: &[B::BenchmarkResult],
|
||||
) -> anyhow::Result<()> {
|
||||
fs::create_dir_all(output_dir)
|
||||
.with_context(|| format!("Creating output directory {output_dir:?}"))?;
|
||||
let filename = format!("benchmark_{binary_name}_{}", B::TITLE);
|
||||
let file =
|
||||
fs::File::create(output_dir.join(filename)).with_context(|| "Creating output file")?;
|
||||
let mut writer = csv::WriterBuilder::new().from_writer(file);
|
||||
writer.write_record(B::BenchmarkResult::HEADERS)?;
|
||||
for result in results {
|
||||
result.write(&mut writer)?;
|
||||
}
|
||||
|
||||
nyx_config.set_process_role(NyxProcessRole::StandAlone);
|
||||
nyx_config.print();
|
||||
|
||||
let mut nyx_runner = NyxProcess::new(&mut nyx_config, 0)?;
|
||||
|
||||
nyx_runner.option_set_trace_mode(true);
|
||||
nyx_runner.option_set_timeout(10, 0);
|
||||
nyx_runner.option_apply();
|
||||
|
||||
let result = nyx_runner.exec();
|
||||
assert!(
|
||||
matches!(result, NyxReturnValue::Normal),
|
||||
"Unexpected return value {result:?}"
|
||||
);
|
||||
nyx_print_aux_buffer(&mut nyx_runner as *mut _);
|
||||
|
||||
nyx_runner.shutdown();
|
||||
Ok(())
|
||||
}
|
||||
|
171
src/nyx.rs
Normal file
171
src/nyx.rs
Normal file
@ -0,0 +1,171 @@
|
||||
//! This module contains functionality to download and setup nyx,
|
||||
//! so that it can be used to execute a binary.
|
||||
|
||||
use anyhow::{Context, anyhow, bail};
|
||||
use libnyx::{NyxConfig, NyxProcess, NyxProcessRole, NyxReturnValue};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
use std::time::Duration;
|
||||
use std::{fs, io};
|
||||
|
||||
const WORKDIR_PATH: &str = "/tmp/wdir";
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum TraceMode {
|
||||
Enabled,
|
||||
Disabled,
|
||||
}
|
||||
|
||||
pub struct NyxRunner(NyxProcess);
|
||||
|
||||
impl NyxRunner {
|
||||
pub fn setup(client_bin: &Path, trace_mode: TraceMode) -> anyhow::Result<Self> {
|
||||
if let Err(e) = fs::remove_dir_all(WORKDIR_PATH)
|
||||
&& !matches!(e.kind(), io::ErrorKind::NotFound)
|
||||
{
|
||||
panic!("Could not remove working directory at {WORKDIR_PATH}");
|
||||
}
|
||||
let sharedir = setup_nyx(&PathBuf::from("nyx_data"), client_bin)?;
|
||||
let sharedir = sharedir.to_str().expect("Expected unicode path");
|
||||
|
||||
let mut nyx_config = NyxConfig::load(sharedir)
|
||||
.map_err(|err| anyhow!(err))
|
||||
.with_context(|| "Creating nyx config")?;
|
||||
nyx_config.set_workdir_path(WORKDIR_PATH.to_string());
|
||||
nyx_config.set_input_buffer_size(0x2000);
|
||||
nyx_config.set_nyx_debug_log_path("qemu_nyx.log".to_string());
|
||||
nyx_config.set_pt_enabled(matches!(trace_mode, TraceMode::Enabled));
|
||||
|
||||
nyx_config.set_process_role(NyxProcessRole::StandAlone);
|
||||
nyx_config.print();
|
||||
|
||||
let mut nyx_runner = NyxProcess::new(&mut nyx_config, 0)
|
||||
.map_err(|err| anyhow!(err))
|
||||
.with_context(|| "Creating Nyx Process")?;
|
||||
|
||||
nyx_runner.option_set_trace_mode(true);
|
||||
nyx_runner.option_set_reload_mode(false);
|
||||
nyx_runner.option_set_timeout(10, 0);
|
||||
nyx_runner.option_apply();
|
||||
|
||||
Ok(NyxRunner(nyx_runner))
|
||||
}
|
||||
|
||||
/// Executes the program with Nyx and intel PT.
|
||||
///
|
||||
/// Returns the duration of the program as recorded by QEMU.
|
||||
pub fn execute(&mut self) -> Duration {
|
||||
let result = self.0.exec();
|
||||
// nyx_print_aux_buffer(&mut self.0 as *mut _);
|
||||
assert!(
|
||||
matches!(result, NyxReturnValue::Normal),
|
||||
"Unexpected return value: {result:?}"
|
||||
);
|
||||
self.0.aux_result_duration()
|
||||
}
|
||||
|
||||
pub fn workdir(&self) -> &Path {
|
||||
Path::new(WORKDIR_PATH)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for NyxRunner {
|
||||
fn drop(&mut self) {
|
||||
self.0.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
/// Downloads and installs nyx
|
||||
///
|
||||
/// [out_dir] Is the directory to which all tools get downloaded and
|
||||
/// where the working directory gets created.
|
||||
///
|
||||
/// [client] Is the path to the client binary.
|
||||
///
|
||||
/// Returns the path to the working directory
|
||||
pub fn setup_nyx(out_dir: &Path, client: &Path) -> anyhow::Result<PathBuf> {
|
||||
if !out_dir.exists() {
|
||||
fs::create_dir(out_dir)?;
|
||||
}
|
||||
|
||||
println!("Installing nyx...");
|
||||
let result = setup_nyx_tools(out_dir);
|
||||
if let Err(e) = result {
|
||||
// Remove the out directory as it may be tainted
|
||||
fs::remove_dir_all(out_dir)
|
||||
.with_context(|| format!("Error while handling error: {e}"))?;
|
||||
return Err(e);
|
||||
}
|
||||
|
||||
create_nyx_workdir(out_dir, client).with_context(|| "Creating the nyx working directory")
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn shell(cwd: impl AsRef<Path>, command_string: &str) -> anyhow::Result<()> {
|
||||
println!("Running ({}) {command_string}", cwd.as_ref().display());
|
||||
|
||||
let cwd = cwd.as_ref();
|
||||
let mut parts = command_string.split(" ");
|
||||
let command_name = parts.next().unwrap();
|
||||
|
||||
let mut command = Command::new(command_name);
|
||||
command.current_dir(cwd);
|
||||
command.stdout(std::process::Stdio::inherit());
|
||||
command.stderr(std::process::Stdio::inherit());
|
||||
command.args(parts);
|
||||
|
||||
let mut process = command.spawn()?;
|
||||
let exit_status = process.wait()?;
|
||||
if !exit_status.success() {
|
||||
bail!("Command ({command_string}) failed with {exit_status}");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Downloads and compiles qemu-nyx and packer and compiles them for the current architecture
|
||||
/// This means that cross-compilation is not supported
|
||||
fn setup_nyx_tools(out_dir: &Path) -> anyhow::Result<()> {
|
||||
let packer_path = out_dir.join("packer");
|
||||
let qemu_path = out_dir.join("QEMU-Nyx");
|
||||
if !packer_path.exists() {
|
||||
shell(out_dir, "git clone https://github.com/nyx-fuzz/packer/")?;
|
||||
}
|
||||
if !qemu_path.exists() {
|
||||
println!("Cloning and building QEMU-Nyx. This may take a while...");
|
||||
shell(
|
||||
out_dir,
|
||||
"git clone https://git.cs.tu-dortmund.de/david.venhoff/QEMU-Nyx-fork QEMU-Nyx --depth 1",
|
||||
)?;
|
||||
|
||||
// Compile with maximum optimizations
|
||||
let qemu_compile_mode = "lto";
|
||||
shell(
|
||||
qemu_path,
|
||||
&format!("bash compile_qemu_nyx.sh {qemu_compile_mode}"),
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_nyx_workdir(out_dir: &Path, client_bin: &Path) -> anyhow::Result<PathBuf> {
|
||||
let client_bin =
|
||||
fs::canonicalize(client_bin).with_context(|| format!("canonicalizing {client_bin:?}"))?;
|
||||
let client_bin = client_bin.to_str().expect("Expected unicode path");
|
||||
// Create the directory and move required binaries to it
|
||||
shell(
|
||||
out_dir,
|
||||
&format!(
|
||||
"python3 packer/packer/nyx_packer.py {client_bin} build afl processor_trace --purge"
|
||||
),
|
||||
)?;
|
||||
|
||||
// Create the nyx config
|
||||
shell(
|
||||
out_dir,
|
||||
"python3 packer/packer/nyx_config_gen.py build Kernel",
|
||||
)?;
|
||||
|
||||
Ok(out_dir.join("build"))
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user