Merge pull request #217 from radareorg/golden-files

Tests: golden files in r2r's format, the census among them
This commit is contained in:
potato authored and GitHub committed 2026-10-14 16:27:09 +05:30
commit 95225b13cc
42 files changed
+19006 -521

No files matched your search

+17 -30
View File
@@ -50,14 +50,15 @@ env:
jobs:
# ── What this run grades ────────────────────────────────────────────
#
# Every push runs the first tier: format, Clippy, tests, Dylints, the build,
# certification, hostile input, the census with timing, source-gold. The
# second tier, both equivalence ratchets and the coverage sweep (30 of 42
# jobs, 4 of every 5 runner-minutes), runs on master, nightly, by hand, in
# the merge queue, and on a pull request whose base is master (the next to
# merge) or that carries the `full-ci` label, and when `ci-on-request.yml`
# calls it. Every gate still runs before a merge; a restack of a 30-PR stack
# queues 30 first tiers, not 1,260 jobs.
# Every push runs the first tier: format, Clippy, tests (the golden files,
# the census among them), Dylints, the build, certification, hostile input,
# source-gold. The second tier, both equivalence ratchets, release timing
# against the base and the coverage sweep (31 of 42 jobs, most of the
# runner-minutes), runs on master, nightly, by hand, in the merge queue, on a
# pull request whose base is master (the next to merge) or that carries the
# `full-ci` label, and when `ci-on-request.yml` calls it. Every gate still
# runs before a merge; a restack of a 30-PR stack queues 30 first tiers, not
# 1,260 jobs.
plan:
name: Plan
runs-on: ubuntu-24.04
@@ -269,18 +270,18 @@ jobs:
python3 scripts/hostile_sweep.py --r2s target/ci/r2s --command pdd \
--seconds 120 --mb 3072 "$RUNNER_TEMP/testbins/fuzzed" "$RUNNER_TEMP/testbins/pe"
# ── Census and release timing, against the base ───────────────────
# ── Release timing, against the base ───────────────────────────────
#
# Every function of the repository's binaries rendered by the base and by
# this change: a structural change is byte-identical or says which lines
# moved. The big functions are timed on both builds on the same runner, so a
# quadratic pass fails here rather than in someone's session.
# The big functions timed on the base's build and this one's on the same
# runner, so a quadratic pass fails here rather than in someone's session.
# What every function renders is a golden file (tests/db/census), held in the
# first tier.
census:
name: Census + Timing vs Base
name: Timing vs Base
runs-on: ubuntu-24.04
needs: [plan, build]
# A scheduled or manual run has no base to hold the census to.
if: github.event_name != 'schedule' && github.event_name != 'workflow_dispatch'
# A scheduled or manual run has no base to time against.
if: needs.plan.outputs.full == 'true' && github.event_name != 'schedule' && github.event_name != 'workflow_dispatch'
timeout-minutes: 40
steps:
- uses: actions/checkout@v6
@@ -332,14 +333,6 @@ jobs:
git -C "$dir" sparse-checkout set elf
git -C "$dir" fetch -q --depth 1 --filter=blob:none origin "$TESTBINS_REF"
git -C "$dir" checkout -q FETCH_HEAD
- name: Census
run: |
set -eu
for side in base head; do
python3 scripts/census.py run --r2s "$RUNNER_TEMP/$side/r2s" --out "$RUNNER_TEMP/census-$side"
done
python3 scripts/census.py diff "$RUNNER_TEMP/census-base" "$RUNNER_TEMP/census-head" \
--report "$RUNNER_TEMP/census.diff" | tee -a "$GITHUB_STEP_SUMMARY"
- name: Release timing
run: |
set -o pipefail
@@ -347,12 +340,6 @@ jobs:
--count-r2s "$RUNNER_TEMP/base-count/r2s" --count-r2s "$RUNNER_TEMP/head-count/r2s" \
--bins "$RUNNER_TEMP/testbins/elf" --runs 5 --budget 1.3 --rss-budget 1.1 \
--alloc-budget 1.3 --heap-budget 1.05 | tee -a "$GITHUB_STEP_SUMMARY"
- uses: actions/upload-artifact@v4
if: always()
with:
name: census-${{ github.run_id }}-${{ github.run_attempt }}
path: ${{ runner.temp }}/census.diff
if-no-files-found: warn
# ── Source-gold: graded against the source, not against another tool ──
#
+4 -2
View File
@@ -152,7 +152,8 @@ Keep the public surface small and the common path automatic. Before adding a
command, ask: does radare2 have a name for it (use it)? should it be automatic?
should it enrich an existing view? is it only a debug surface? A command is one
entry in `VERBS` in `crates/r2s/src/commands.rs` plus one handler, with
happy- and failure-path tests in `crates/r2s/tests/`. Maintainer tier:
happy- and failure-path tests: golden files in `tests/db/`, or `crates/r2s/tests/`
where a fact needs logic. Maintainer tier:
`pdil`, `pddo`.
## Task Protocol
@@ -187,7 +188,8 @@ helper names or incidental traversal order.
|---|---|
| A lowering, predicate, certificate or fold | inline `#[cfg(test)]` beside it |
| A crate's public surface | `crates/<crate>/tests/` |
| A command's output | `crates/r2s/tests/` |
| A command's whole output | a golden file in `tests/db/` (r2r's format, [tests/db/README.md](tests/db/README.md)) |
| A command fact that needs logic (an exit status, two commands compared) | `crates/r2s/tests/` |
| What a whole function renders | the certification gate, plus a unit test for the rule |
| Discovery, naming or decoding | the differential gate, with the disagreement judged |
Generated
+20 -1
View File
@@ -472,6 +472,12 @@ dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "escape8259"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f1f0d310082fd5de539d4f41601182241147498444a7695c520288a0cdbead6"
[[package]]
name = "fastrand"
version = "2.5.0"
@@ -776,6 +782,18 @@ dependencies = [
"cxx-build",
]
[[package]]
name = "libtest-mimic"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14e6ba06f0ade6e504aff834d7c34298e5155c6baca353cc6a4aaff2f9fd7f33"
dependencies = [
"anstream",
"anstyle",
"clap",
"escape8259",
]
[[package]]
name = "link-cplusplus"
version = "1.0.12"
@@ -1113,7 +1131,7 @@ dependencies = [
"clap",
"crossterm",
"dhat",
"insta",
"libtest-mimic",
"mimalloc",
"r2engine",
"r2image",
@@ -1121,6 +1139,7 @@ dependencies = [
"ratatui",
"reedline",
"serde_json",
"similar",
]
[[package]]
+3
View File
@@ -36,6 +36,9 @@ hex = "0.4"
object = { version = "0.37", default-features = false, features = ["read", "std"] }
z3 = "0.21.0"
insta = "1"
# The golden tests' harness (crates/r2s/tests/golden.rs) and its diffs.
libtest-mimic = "0.8"
similar = "2"
ratatui = { version = "0.29", default-features = false, features = ["crossterm"] }
crossterm = "0.28"
# 0.43 is the last on crossterm 0.28, which ratatui 0.29 is built on: one
+9 -1
View File
@@ -20,7 +20,8 @@ mimalloc = { version = "0.1", default-features = false }
dhat = { version = "0.3", optional = true }
[dev-dependencies]
insta.workspace = true
libtest-mimic.workspace = true
similar.workspace = true
ratatui.workspace = true
crossterm.workspace = true
@@ -33,5 +34,12 @@ alloc-count = []
# Profile the heap: dhat's allocator; with R2S_HEAP_PROFILE set, a script writes dhat-heap.json (`census.py heap`).
dhat-heap = ["dep:dhat"]
# radare2's r2r format over `tests/db/`, one trial per test (tests/db/README.md).
[[test]]
name = "golden"
path = "tests/golden.rs"
harness = false
required-features = ["sleigh"]
[lints]
workspace = true
+2 -87
View File
@@ -927,56 +927,8 @@ fn the_image_reports_what_the_container_states() {
assert!(run.out.contains("lang c\n"), "{}", run.out);
}
/// The three tiers, pinned.
///
/// A lowering change should move exactly one of these. When one moves, read
/// the new output and judge it before blessing it: a snapshot that differs is
/// not a snapshot that is wrong, and a snapshot that agrees is evidence that
/// nothing moved rather than evidence that the output is right.
mod tiers {
use super::{FNV1A32, r2s};
#[test]
fn low_tier_is_pinned() {
let run = r2s(&format!("s {FNV1A32}; pdil"));
assert!(run.ok, "{}", run.out);
insta::assert_snapshot!("fnv1a32_r2il", run.out);
}
#[test]
fn rendered_c_is_pinned() {
let run = r2s(&format!("s {FNV1A32}; pdd"));
assert!(run.ok, "{}", run.out);
insta::assert_snapshot!("fnv1a32_c", run.out);
}
}
/// The listing, pinned on one binary per architecture the tree carries.
///
/// `pd` is the command with the least protection and the most rewriting: every
/// line it prints is built by successive substitutions over one formatted
/// string, and until now a change to any of them was caught only by a
/// comparison against radare2 that lives outside this repository. These pin the
/// spellings that rewriting is meant to preserve, so a listing that changes is
/// a listing someone decided to change.
///
/// What each one covers, beyond the decode:
///
/// - x86-64: the `ptr` and displacement spellings, and `jz` printed as `jne`'s
/// comparison rather than its flag.
/// - aarch64: a Mach-O whose operands reach data through a page and an offset.
/// - ARM 32-bit: the register roles (`fp`, `ip`, `sp`, `lr`, `pc`), the `mov`
/// alias for the encoding Sleigh spells `cpy`, and a big-endian Thumb-2
/// decode, which is the one place this engine reads an instruction radare2
/// reads wrongly.
///
/// Two spellings in these recordings are ours and not radare2's, and they are
/// pinned so that changing them is a decision rather than an accident. The x86
/// snapshot writes `nop word ptr cs:[rax + rax*0x1]`, because the rule that
/// drops `ptr` matches ` ptr [` and this operand carries a segment between the
/// two; and it writes a sixty-four-bit immediate signed, as Sleigh does, where
/// radare2 writes it unsigned. The listing comparison against radare2
/// normalises integers, so neither shows up there.
/// What the listing states beyond its text; the listings themselves are golden files in
/// `tests/db/cmd/listing`.
mod listing {
use super::{FNV1A32, Run, on, r2s};
use std::path::PathBuf;
@@ -990,23 +942,6 @@ mod listing {
)
}
#[test]
fn the_x86_listing_is_pinned() {
let run = r2s(&format!("s {FNV1A32}; pd 24"));
assert!(run.ok, "{}", run.out);
insta::assert_snapshot!("fnv1a32_pd", run.out);
}
/// The annotations, on the one pinned binary that has all three shapes:
/// a call through a relocated slot, a jump through an unnamed one, and a
/// compare against a data byte.
#[test]
fn what_a_line_reads_is_pinned() {
let run = super::r2s("s 0x401000; pd 24");
assert!(run.ok, "{}", run.out);
insta::assert_snapshot!("reads_pd", run.out);
}
/// The listing radare2 cannot write: no range that is one value the instruction fixes or only the width it wrote, each note ending in its rung.
#[test]
fn what_the_engine_proved_is_pinned() {
@@ -1032,7 +967,6 @@ mod listing {
] {
assert!(header.contains(said), "{said}: {}", run.out);
}
insta::assert_snapshot!("proved_pdf", run.out);
}
/// Each arm of siphash24's tail switch is labelled with the cases the dispatch sends there, as radare2 labels them.
@@ -1061,7 +995,6 @@ mod listing {
}
let dispatch = "; switch table (8 cases) at 0x402020 (solved)";
assert!(listed.out.contains(dispatch), "{}", listed.out);
insta::assert_snapshot!("siphash_pdf", listed.out);
}
/// A line that hands a string to a call says the text beside the address, on the rung the address stands on.
@@ -1112,16 +1045,6 @@ mod listing {
assert!(proved.out.contains(" in ["), "{}", proved.out);
}
#[test]
fn the_aarch64_listing_is_pinned() {
let run = at(
"tests/fixtures/code_pointer_table_O0",
"s 0x100000420; pd 24",
);
assert!(run.ok, "{}", run.out);
insta::assert_snapshot!("table_dispatch_pd", run.out);
}
/// `pdf` folds each block of the walked body across its lines, so the page and its offset are one address and the table load reads it; `pd` folds each line alone.
#[test]
fn the_aarch64_function_listing_folds_each_block() {
@@ -1149,7 +1072,6 @@ mod listing {
assert!(read.out.starts_with(named), "{}", read.out);
let plain = at(fixture, "s 0x100000420; pd 24");
assert!(!plain.out.contains("0x100004010"), "{}", plain.out);
insta::assert_snapshot!("table_dispatch_pdf", run.out);
}
/// `bl sym.imp.memcpy` lands on a stub in `__stubs`, which the container
@@ -1220,13 +1142,6 @@ mod listing {
let call = "sym._main 0x100000e18 [CALL:--x] bl sym.imp.memcpy\n";
assert!(refs.out.starts_with(call), "{}", refs.out);
}
#[test]
fn the_arm_listing_is_pinned() {
let run = at("crates/r2image/tests/data/arm_thumb_entry.elf", "pd 12");
assert!(run.ok, "{}", run.out);
insta::assert_snapshot!("arm_thumb_pd", run.out);
}
}
/// An aarch64 Mach-O whose dispatcher calls through a table of function
+335
View File
@@ -0,0 +1,335 @@
//! The golden tests: radare2's r2r format, run against the shell this build produced.
//!
//! Each file under `tests/db/` holds tests as r2r writes them (tests/db/README.md). A test runs
//! `r2s -q -c CMDS ARGS FILE`; its stdout must be `EXPECT` and its stderr `EXPECT_ERR`, empty where
//! none is stated. A nonzero exit passes only where the test states what r2s printed to stderr.
//! `R2S_BLESS=1` writes what ran into the files, and a bless is a judged diff.
use std::collections::BTreeMap;
use std::ops::Range;
use std::path::{Path, PathBuf};
use std::process::Command;
use std::sync::{Arc, Mutex};
use libtest_mimic::{Arguments, Failed, Trial};
/// One test as its file states it, and where its expectations sit there.
#[derive(Debug, Clone)]
struct Golden {
file: PathBuf,
name: String,
binary: String,
args: Vec<String>,
commands: String,
expect: Option<Block>,
expect_err: Option<Block>,
broken: bool,
/// The line `RUN` is on: an expectation the test lacks is written before it.
run: usize,
}
/// A stated value and the lines of its file it spans.
#[derive(Debug, Clone)]
struct Block {
text: String,
lines: Range<usize>,
}
/// What one test printed, where it differed from its file.
struct Blessing {
golden: Golden,
stdout: String,
stderr: String,
}
const KEYS: [&str; 7] = [
"NAME",
"FILE",
"ARGS",
"CMDS",
"EXPECT",
"EXPECT_ERR",
"BROKEN",
];
fn main() {
let args = Arguments::from_args();
let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../..");
let root = root.canonicalize().unwrap_or(root);
let bless = std::env::var_os("R2S_BLESS").is_some();
let blessed = Arc::new(Mutex::new(Vec::new()));
let goldens = load(&root.join("tests/db")).unwrap_or_else(|error| panic!("{error}"));
let trials = goldens
.into_iter()
.map(|golden| {
let name = format!("{}::{}", golden.file.display(), golden.name);
let broken = golden.broken;
let (root, blessed) = (root.clone(), Arc::clone(&blessed));
Trial::test(name, move || {
check(&golden, &root, bless.then_some(&*blessed))
})
.with_ignored_flag(broken)
})
.collect();
let conclusion = libtest_mimic::run(&args, trials);
let blessed = std::mem::take(&mut *blessed.lock().expect("no trial panicked holding it"));
write(&root.join("tests/db"), blessed);
conclusion.exit();
}
/// Every test of every file under `db`, files in path order.
fn load(db: &Path) -> Result<Vec<Golden>, String> {
let mut files = Vec::new();
let mut pending = vec![db.to_path_buf()];
while let Some(dir) = pending.pop() {
let entries =
std::fs::read_dir(&dir).map_err(|error| format!("{}: {error}", dir.display()))?;
for entry in entries {
let path = entry.map_err(|error| error.to_string())?.path();
let named = path
.file_name()
.and_then(|name| name.to_str())
.unwrap_or_default();
if path.is_dir() {
pending.push(path);
} else if !named.starts_with('.') && !named.ends_with(".md") {
files.push(path);
}
}
}
files.sort();
let mut goldens = Vec::new();
for path in files {
let text = std::fs::read_to_string(&path)
.map_err(|error| format!("{}: {error}", path.display()))?;
let relative = path.strip_prefix(db).unwrap_or(&path).to_path_buf();
goldens.extend(parse(&relative, &text)?);
}
Ok(goldens)
}
/// The tests one file states, each ended by `RUN`.
fn parse(file: &Path, text: &str) -> Result<Vec<Golden>, String> {
let lines = text.lines().collect::<Vec<_>>();
let at_line = |at: usize| format!("{}:{}", file.display(), at + 1);
let mut tests = Vec::new();
let mut fields = BTreeMap::new();
let mut at = 0;
while at < lines.len() {
let line = lines[at];
if line.trim().is_empty() || line.trim_start().starts_with('#') {
at += 1;
continue;
}
if line.trim() == "RUN" {
tests.push(
golden(file, std::mem::take(&mut fields), at)
.map_err(|error| format!("{}: {error}", at_line(at)))?,
);
at += 1;
continue;
}
let Some((key, value)) = line.split_once('=').filter(|(key, _)| KEYS.contains(key)) else {
return Err(format!(
"{}: not one of {KEYS:?}=value: {line}",
at_line(at)
));
};
let start = at;
let text = match value.strip_prefix("<<") {
Some(tag) => {
let mut body = String::new();
loop {
at += 1;
match lines.get(at) {
Some(next) if *next == tag => break,
Some(next) => {
body.push_str(next);
body.push('\n');
}
None => {
return Err(format!("{}: `{tag}` never closes {key}", at_line(start)));
}
}
}
body
}
None => value.to_owned(),
};
at += 1;
let block = Block {
text,
lines: start..at,
};
if fields.insert(key, block).is_some() {
return Err(format!("{}: {key} twice in one test", at_line(start)));
}
}
if !fields.is_empty() {
return Err(format!("{}: a test with no RUN", file.display()));
}
let mut names = std::collections::BTreeSet::new();
if let Some(twice) = tests
.iter()
.find(|test: &&Golden| !names.insert(test.name.clone()))
{
return Err(format!("{}: NAME={} twice", file.display(), twice.name));
}
Ok(tests)
}
fn golden(file: &Path, mut fields: BTreeMap<&str, Block>, run: usize) -> Result<Golden, String> {
let mut take = |key| {
fields
.remove(key)
.map(|block: Block| block.text.trim_end_matches('\n').to_owned())
};
let name = take("NAME").ok_or("a test with no NAME")?;
let binary = take("FILE").ok_or("a test with no FILE")?;
let commands = take("CMDS").ok_or("a test with no CMDS")?;
let args = take("ARGS")
.map(|args| args.split_whitespace().map(str::to_owned).collect())
.unwrap_or_default();
let broken = take("BROKEN").is_some_and(|broken| broken == "1");
Ok(Golden {
file: file.to_path_buf(),
name,
binary,
args,
commands,
expect: fields.remove("EXPECT"),
expect_err: fields.remove("EXPECT_ERR"),
broken,
run,
})
}
/// Run one test, and either hold it to its file or, blessing, record what it printed.
fn check(
golden: &Golden,
root: &Path,
blessed: Option<&Mutex<Vec<Blessing>>>,
) -> Result<(), Failed> {
let done = Command::new(env!("CARGO_BIN_EXE_r2s"))
.args(["-q", "-c", &golden.commands])
.args(&golden.args)
.arg(root.join(&golden.binary))
.env("NO_COLOR", "1")
.output()
.map_err(|error| format!("r2s did not start: {error}"))?;
let (stdout, stderr) = (lines(&done.stdout), lines(&done.stderr));
if done.status.code().is_none() {
return Err(format!("r2s died: {}\n{stderr}", done.status).into());
}
let expected = |block: &Option<Block>| block.as_ref().map(|block| block.text.clone());
let out_ok = expected(&golden.expect).unwrap_or_default() == stdout;
let err_ok = expected(&golden.expect_err).unwrap_or_default() == stderr;
// A failed statement exits 1 and says why on stderr, so a test that states it may exit so.
if !done.status.success() && stderr.is_empty() {
return Err(format!("r2s exited {} and printed nothing to stderr", done.status).into());
}
if out_ok && err_ok {
return Ok(());
}
if let Some(blessed) = blessed {
let blessing = Blessing {
golden: golden.clone(),
stdout,
stderr,
};
blessed
.lock()
.expect("no trial panicked holding it")
.push(blessing);
return Ok(());
}
let mut report = String::new();
if !out_ok {
report += &diff(
"EXPECT",
&expected(&golden.expect).unwrap_or_default(),
&stdout,
);
}
if !err_ok {
report += &diff(
"EXPECT_ERR",
&expected(&golden.expect_err).unwrap_or_default(),
&stderr,
);
}
Err(format!("{report}bless with R2S_BLESS=1 once the diff is judged right").into())
}
/// Output as a heredoc holds it: every line ended.
fn lines(bytes: &[u8]) -> String {
let mut text = String::from_utf8_lossy(bytes).into_owned();
if !text.is_empty() && !text.ends_with('\n') {
text.push('\n');
}
text
}
fn diff(key: &str, expected: &str, actual: &str) -> String {
let diff = similar::TextDiff::from_lines(expected, actual);
format!(
"{key} differs:\n{}",
diff.unified_diff().header("expected", "actual")
)
}
/// Write each blessed test's output into its file: a stated expectation replaced where it stood,
/// a missing one before `RUN`.
fn write(db: &Path, blessed: Vec<Blessing>) {
let mut by_file = BTreeMap::<PathBuf, Vec<Blessing>>::new();
for blessing in blessed {
by_file
.entry(blessing.golden.file.clone())
.or_default()
.push(blessing);
}
for (file, mut blessings) in by_file {
let path = db.join(&file);
let text = std::fs::read_to_string(&path).expect("a file the run read");
let mut lines = text.lines().map(str::to_owned).collect::<Vec<_>>();
// From the bottom up, so each test's line numbers still hold when it is written.
blessings.sort_by_key(|blessing| std::cmp::Reverse(blessing.golden.run));
for Blessing {
golden,
stdout,
stderr,
} in blessings
{
let mut edits = vec![(&golden.expect, "EXPECT", stdout)];
if golden.expect_err.is_some() || !stderr.is_empty() {
edits.push((&golden.expect_err, "EXPECT_ERR", stderr));
}
let at = |block: &Option<Block>| {
block
.as_ref()
.map_or(golden.run..golden.run, |block| block.lines.clone())
};
// The later edit first, so the earlier one's lines still hold.
edits.sort_by_key(|(block, ..)| std::cmp::Reverse(at(block).start));
for (block, key, text) in edits {
lines.splice(at(block), heredoc(key, &text));
}
}
let mut written = lines.join("\n");
written.push('\n');
std::fs::write(&path, written).expect("the file is writable");
eprintln!("blessed {}", path.display());
}
}
/// `KEY=<<EOF`, the text, `EOF`: a tag no line of the text is.
fn heredoc(key: &str, text: &str) -> Vec<String> {
let mut tag = String::from("EOF");
while text.lines().any(|line| line == tag) {
tag.push('_');
}
std::iter::once(format!("{key}=<<{tag}"))
.chain(text.lines().map(str::to_owned))
.chain(std::iter::once(tag))
.collect()
}
@@ -1,8 +0,0 @@
---
source: crates/r2s/tests/commands.rs
expression: run.out
---
0x00010054 4ff0000b mov.w fp, 0x0
0x00010058 4ff0000e mov.w lr, 0x0
0x0001005c 02bc pop {r1}
0x0001005e 6a46 mov r2, sp
@@ -1,28 +0,0 @@
---
source: crates/r2s/tests/commands.rs
expression: run.out
---
0x00401330 f30f1efa endbr64
0x00401334 4885f6 test rsi, rsi
0x00401337 7427 je 0x401360
0x00401339 4801fe add rsi, rdi
0x0040133c b8c59d1c81 mov eax, 0x811c9dc5
0x00401341 0f1f800000.. nop dword [rax]
0x00401348 0fb617 movzx edx, byte [rdi]
0x0040134b 4883c701 add rdi, 0x1
0x0040134f 31d0 xor eax, edx
0x00401351 69c093010001 imul eax, eax, 0x1000193
0x00401357 4839fe cmp rsi, rdi
0x0040135a 75ec jne 0x401348
0x0040135c c3 ret
0x0040135d 0f1f00 nop dword [rax]
0x00401360 b8c59d1c81 mov eax, 0x811c9dc5
0x00401365 c3 ret
0x00401366 662e0f1f84.. nop word cs:[rax + rax]
0x00401370 f30f1efa endbr64
0x00401374 48b8252322.. mov rax, -0x340d631b7bdddcdb
0x0040137e 4885f6 test rsi, rsi
0x00401381 7420 je 0x4013a3
0x00401383 48b9b30100.. mov rcx, 0x100000001b3
0x0040138d 4801fe add rsi, rdi
0x00401390 0fb617 movzx edx, byte [rdi]
@@ -1,44 +0,0 @@
---
source: crates/r2s/tests/commands.rs
expression: run.out
---
0x00401330 f30f1efa endbr64
0x00401334 4885f6 test rsi, rsi
0x00401337 7427 je 0x401360
0x00401339 4801fe add rsi, rdi
0x0040133c b8c59d1c81 mov eax, 0x811c9dc5
0x00401341 0f1f800000.. nop dword [rax]
0x00401348 0fb617 movzx edx, byte [rdi] ; loop: latches 0x401348, exits 0x40135c (certified) ; induction rdi = rdi@entry, +0x1 per trip (certified) ; trips rsi@entry (solved)
0x0040134b 4883c701 add rdi, 0x1
0x0040134f 31d0 xor eax, edx
0x00401351 69c093010001 imul eax, eax, 0x1000193
0x00401357 4839fe cmp rsi, rdi
0x0040135a 75ec jne 0x401348
0x0040135c c3 ret ; returns rax (certified)
0x00401360 b8c59d1c81 mov eax, 0x811c9dc5
0x00401365 c3 ret ; returns rax (certified)
0x00401530 f30f1efa endbr64
0x00401534 4885f6 test rsi, rsi
0x00401537 7440 je 0x401579
0x00401539 4801fe add rsi, rdi
0x0040153c b8ffffffff mov eax, 0xffffffff
0x00401541 0f1f800000.. nop dword [rax]
0x00401548 0fb617 movzx edx, byte [rdi] ; loop: latches 0x40156d, exits 0x401576 (certified) ; induction rdi = rdi@entry, +0x1 per trip (certified) ; trips rsi@entry (solved)
0x0040154b 31d0 xor eax, edx
0x0040154d ba08000000 mov edx, 0x8
0x00401552 660f1f440000 nop word [rax + rax]
0x00401558 89c1 mov ecx, eax ; loop: latches 0x401558, exits 0x40156d (certified)
0x0040155a 83e001 and eax, 0x1 ; defines rax in [0x0, 0x1] (decoded)
0x0040155d f7d8 neg eax
0x0040155f d1e9 shr ecx, 0x1 ; defines rcx in [0x0, 0x7fffffff] (decoded)
0x00401561 252083b8ed and eax, 0xedb88320 ; defines rax in [0x0, 0xedb88320] (decoded)
0x00401566 31c8 xor eax, ecx
0x00401568 83ea01 sub edx, 0x1
0x0040156b 75eb jne 0x401558
0x0040156d 4883c701 add rdi, 0x1
0x00401571 4839f7 cmp rdi, rsi
0x00401574 75d2 jne 0x401548
0x00401576 f7d0 not eax
0x00401578 c3 ret ; returns rax (certified)
0x00401579 31c0 xor eax, eax
0x0040157b c3 ret ; returns rax (certified)
@@ -1,28 +0,0 @@
---
source: crates/r2s/tests/commands.rs
expression: run.out
---
0x00401000 f30f1efa endbr64
0x00401004 4883ec08 sub rsp, 0x8
0x00401008 488b05d12f.. mov rax, qword [reloc.__gmon_start__]
0x0040100f 4885c0 test rax, rax
0x00401012 7402 je 0x401016
0x00401014 ffd0 call rax
0x00401016 4883c408 add rsp, 0x8
0x0040101a c3 ret
0x0040101b 0000 add byte [rax], al
0x0040101d 0000 add byte [rax], al
0x0040101f 00ff add bh, bh
0x00401021 35ca2f0000 xor eax, 0x2fca
0x00401026 ff25cc2f0000 jmp qword [0x403ff8]
0x0040102c 0f1f4000 nop dword [rax]
0x00401030 f30f1efa endbr64
0x00401034 6800000000 push 0x0
0x00401039 e9e2ffffff jmp 0x401020
0x0040103e 6690 nop
0x00401040 f30f1efa endbr64
0x00401044 ff25b62f0000 jmp qword [reloc.__printf_chk]
0x0040104a 660f1f440000 nop word [rax + rax]
0x00401050 f30f1efa endbr64
0x00401054 4883ec08 sub rsp, 0x8
0x00401058 be3d000000 mov esi, 0x3d
@@ -1,176 +0,0 @@
---
source: crates/r2s/tests/commands.rs
expression: listed.out
---
0x004018b0 f30f1efa endbr64
0x004018b4 48b8756573.. mov rax, 0x736f6d6570736575
0x004018be 4989f0 mov r8, rsi
0x004018c1 48be617265.. mov rsi, 0x6c7967656e657261
0x004018cb 49bb6d6f64.. mov r11, 0x646f72616e646f6d
0x004018d5 4d89c2 mov r10, r8
0x004018d8 4831d0 xor rax, rdx
0x004018db 4831f2 xor rdx, rsi
0x004018de 4931cb xor r11, rcx
0x004018e1 48be736574.. mov rsi, 0x7465646279746573
0x004018eb 4983e2f8 and r10, -0x8 ; defines r10 in [0x0, 0xfffffffffffffff8] (decoded)
0x004018ef 4831f1 xor rcx, rsi
0x004018f2 4901fa add r10, rdi
0x004018f5 4c89c6 mov rsi, r8
0x004018f8 48c1e638 shl rsi, 0x38
0x004018fc 4c39d7 cmp rdi, r10
0x004018ff 7479 je 0x40197a
0x00401901 0f1f800000.. nop dword [rax]
0x00401908 4c8b0f mov r9, qword [rdi] ; loop: latches 0x401908, exits 0x40197a (certified) ; induction rdi = rdi@entry, +0x8 per trip (certified)
0x0040190b 4c01d8 add rax, r11
0x0040190e 49c1c30d rol r11, 0xd
0x00401912 4883c708 add rdi, 0x8
0x00401916 4931c3 xor r11, rax
0x00401919 48c1c020 rol rax, 0x20
0x0040191d 4c31c9 xor rcx, r9
0x00401920 4801ca add rdx, rcx
0x00401923 48c1c110 rol rcx, 0x10
0x00401927 4831d1 xor rcx, rdx
0x0040192a 4c01da add rdx, r11
0x0040192d 49c1c311 rol r11, 0x11
0x00401931 4801c8 add rax, rcx
0x00401934 48c1c115 rol rcx, 0x15
0x00401938 4931d3 xor r11, rdx
0x0040193b 4831c1 xor rcx, rax
0x0040193e 48c1c220 rol rdx, 0x20
0x00401942 4c01d8 add rax, r11
0x00401945 4801ca add rdx, rcx
0x00401948 49c1c30d rol r11, 0xd
0x0040194c 48c1c110 rol rcx, 0x10
0x00401950 4931c3 xor r11, rax
0x00401953 48c1c020 rol rax, 0x20
0x00401957 4831d1 xor rcx, rdx
0x0040195a 4c01da add rdx, r11
0x0040195d 49c1c311 rol r11, 0x11
0x00401961 4801c8 add rax, rcx
0x00401964 48c1c115 rol rcx, 0x15
0x00401968 4931d3 xor r11, rdx
0x0040196b 4831c1 xor rcx, rax
0x0040196e 48c1c220 rol rdx, 0x20
0x00401972 4c31c8 xor rax, r9
0x00401975 4939fa cmp r10, rdi
0x00401978 758e jne 0x401908
0x0040197a 4183e007 and r8d, 0x7 ; defines r8 in [0x0, 0x7] (decoded)
0x0040197e 3e42ff24c5.. jmp qword ds:[0x402020 + r8*0x8] ; switch table (8 cases) at 0x402020 (solved)
;-- case 7: ; from 0x0040197e
0x00401990 410fb67a06 movzx edi, byte [r10 + 0x6]
0x00401995 48c1e730 shl rdi, 0x30
0x00401999 4809fe or rsi, rdi
;-- case 6: ; from 0x0040197e
0x0040199c 410fb67a05 movzx edi, byte [r10 + 0x5]
0x004019a1 48c1e728 shl rdi, 0x28
0x004019a5 4809fe or rsi, rdi
;-- case 5: ; from 0x0040197e
0x004019a8 410fb67a04 movzx edi, byte [r10 + 0x4]
0x004019ad 48c1e720 shl rdi, 0x20
0x004019b1 4809fe or rsi, rdi
;-- case 4: ; from 0x0040197e
0x004019b4 410fb67a03 movzx edi, byte [r10 + 0x3]
0x004019b9 48c1e718 shl rdi, 0x18
0x004019bd 4809fe or rsi, rdi
;-- case 3: ; from 0x0040197e
0x004019c0 410fb67a02 movzx edi, byte [r10 + 0x2]
0x004019c5 48c1e710 shl rdi, 0x10
0x004019c9 4809fe or rsi, rdi
;-- case 2: ; from 0x0040197e
0x004019cc 410fb67a01 movzx edi, byte [r10 + 0x1]
0x004019d1 48c1e708 shl rdi, 0x8
0x004019d5 4809fe or rsi, rdi
;-- case 1: ; from 0x0040197e
0x004019d8 410fb63a movzx edi, byte [r10]
0x004019dc 4809fe or rsi, rdi
;-- case 0: ; from 0x0040197e
0x004019df 4831f1 xor rcx, rsi
0x004019e2 4a8d3c18 lea rdi, [rax + r11]
0x004019e6 49c1c30d rol r11, 0xd
0x004019ea 4801ca add rdx, rcx
0x004019ed 4889f8 mov rax, rdi
0x004019f0 48c1c110 rol rcx, 0x10
0x004019f4 4931fb xor r11, rdi
0x004019f7 4831d1 xor rcx, rdx
0x004019fa 48c1c020 rol rax, 0x20
0x004019fe 4c01da add rdx, r11
0x00401a01 488d3c08 lea rdi, [rax + rcx]
0x00401a05 4c89d8 mov rax, r11
0x00401a08 48c1c115 rol rcx, 0x15
0x00401a0c 48c1c011 rol rax, 0x11
0x00401a10 4831f9 xor rcx, rdi
0x00401a13 4831d0 xor rax, rdx
0x00401a16 48c1c220 rol rdx, 0x20
0x00401a1a 4801c7 add rdi, rax
0x00401a1d 4801ca add rdx, rcx
0x00401a20 48c1c00d rol rax, 0xd
0x00401a24 48c1c110 rol rcx, 0x10
0x00401a28 4831f8 xor rax, rdi
0x00401a2b 48c1c720 rol rdi, 0x20
0x00401a2f 4831d1 xor rcx, rdx
0x00401a32 4801c2 add rdx, rax
0x00401a35 48c1c011 rol rax, 0x11
0x00401a39 4801cf add rdi, rcx
0x00401a3c 4831d0 xor rax, rdx
0x00401a3f 48c1c115 rol rcx, 0x15
0x00401a43 4831fe xor rsi, rdi
0x00401a46 48c1c220 rol rdx, 0x20
0x00401a4a 4831f9 xor rcx, rdi
0x00401a4d 4801c6 add rsi, rax
0x00401a50 80f2ff xor dl, 0xff
0x00401a53 48c1c00d rol rax, 0xd
0x00401a57 4831f0 xor rax, rsi
0x00401a5a 48c1c620 rol rsi, 0x20
0x00401a5e 4801ca add rdx, rcx
0x00401a61 48c1c110 rol rcx, 0x10
0x00401a65 4831d1 xor rcx, rdx
0x00401a68 4801c2 add rdx, rax
0x00401a6b 48c1c011 rol rax, 0x11
0x00401a6f 4801ce add rsi, rcx
0x00401a72 48c1c115 rol rcx, 0x15
0x00401a76 4831d0 xor rax, rdx
0x00401a79 4831f1 xor rcx, rsi
0x00401a7c 48c1c220 rol rdx, 0x20
0x00401a80 4801c6 add rsi, rax
0x00401a83 4801ca add rdx, rcx
0x00401a86 48c1c00d rol rax, 0xd
0x00401a8a 48c1c110 rol rcx, 0x10
0x00401a8e 4831f0 xor rax, rsi
0x00401a91 48c1c620 rol rsi, 0x20
0x00401a95 4831d1 xor rcx, rdx
0x00401a98 4801c2 add rdx, rax
0x00401a9b 48c1c011 rol rax, 0x11
0x00401a9f 4801ce add rsi, rcx
0x00401aa2 48c1c115 rol rcx, 0x15
0x00401aa6 4831d0 xor rax, rdx
0x00401aa9 4831f1 xor rcx, rsi
0x00401aac 48c1c220 rol rdx, 0x20
0x00401ab0 4801c6 add rsi, rax
0x00401ab3 4801ca add rdx, rcx
0x00401ab6 48c1c00d rol rax, 0xd
0x00401aba 48c1c110 rol rcx, 0x10
0x00401abe 4831f0 xor rax, rsi
0x00401ac1 48c1c620 rol rsi, 0x20
0x00401ac5 4831d1 xor rcx, rdx
0x00401ac8 4801ce add rsi, rcx
0x00401acb 4801c2 add rdx, rax
0x00401ace 48c1c011 rol rax, 0x11
0x00401ad2 4831d0 xor rax, rdx
0x00401ad5 48c1c115 rol rcx, 0x15
0x00401ad9 4831f1 xor rcx, rsi
0x00401adc 4801c6 add rsi, rax
0x00401adf 48c1c00d rol rax, 0xd
0x00401ae3 4831c6 xor rsi, rax
0x00401ae6 48c1c220 rol rdx, 0x20
0x00401aea 4889c8 mov rax, rcx
0x00401aed 4801ca add rdx, rcx
0x00401af0 48c1c010 rol rax, 0x10
0x00401af4 4831d0 xor rax, rdx
0x00401af7 4801f2 add rdx, rsi
0x00401afa 48c1c611 rol rsi, 0x11
0x00401afe 48c1c015 rol rax, 0x15
0x00401b02 4831d0 xor rax, rdx
0x00401b05 48c1c220 rol rdx, 0x20
0x00401b09 4831f0 xor rax, rsi
0x00401b0c 4831d0 xor rax, rdx
0x00401b0f c3 ret ; returns rax (certified)
@@ -1,28 +0,0 @@
---
source: crates/r2s/tests/commands.rs
expression: run.out
---
0x100000420 ff4301d1 sub sp, sp, 0x50
0x100000424 fd7b04a9 stp x29, x30, [sp, 0x40]
0x100000428 fd030191 add x29, sp, 0x40
0x10000042c a0831ff8 stur x0, [x29, -0x8]
0x100000430 a1031ff8 stur x1, [x29, -0x10]
0x100000434 28000090 adrp x8, 0x100004000
0x100000438 08010091 add x8, x8, 0x0
0x10000043c 0001c03d ldr q0, [x8]
0x100000440 e007803d str q0, [sp, 0x10]
0x100000444 080940f9 ldr x8, [x8, 0x10]
0x100000448 e81300f9 str x8, [sp, 0x20]
0x10000044c a8835ff8 ldur x8, [x29, -0x8]
0x100000450 e80700f9 str x8, [sp, 0x8]
0x100000454 ff0700b9 str wzr, [sp, 0x4]
0x100000458 01000014 b 0x10000045c
0x10000045c e80740b9 ldr w8, [sp, 0x4]
0x100000460 080d0071 subs w8, w8, 0x3
0x100000464 22020054 b.cs 0x1000004a8
0x100000468 01000014 b 0x10000046c
0x10000046c e80740b9 ldr w8, [sp, 0x4]
0x100000470 e90308aa mov x9, x8
0x100000474 e8430091 add x8, sp, 0x10
0x100000478 087969f8 ldr x8, [x8, x9, lsl 0x3]
0x10000047c e00740f9 ldr x0, [sp, 0x8]
@@ -1,42 +0,0 @@
---
source: crates/r2s/tests/commands.rs
expression: run.out
---
0x100000420 ff4301d1 sub sp, sp, 0x50
0x100000424 fd7b04a9 stp x29, x30, [sp, 0x40]
0x100000428 fd030191 add x29, sp, 0x40
0x10000042c a0831ff8 stur x0, [x29, -0x8]
0x100000430 a1031ff8 stur x1, [x29, -0x10]
0x100000434 28000090 adrp x8, 0x100004000
0x100000438 08010091 add x8, x8, 0x0 ; defines x8 = 0x100004000 (folded)
0x10000043c 0001c03d ldr q0, [x8]
0x100000440 e007803d str q0, [sp, 0x10]
0x100000444 080940f9 ldr x8, [x8, 0x10] ; [0x100004010:8] loaded 0x100000400 sym._table_op_mul (folded)
0x100000448 e81300f9 str x8, [sp, 0x20]
0x10000044c a8835ff8 ldur x8, [x29, -0x8]
0x100000450 e80700f9 str x8, [sp, 0x8]
0x100000454 ff0700b9 str wzr, [sp, 0x4]
0x100000458 01000014 b 0x10000045c
0x10000045c e80740b9 ldr w8, [sp, 0x4] ; loop: latches 0x100000498, exits 0x1000004a8 (certified) ; trips 0x4 (solved)
0x100000460 080d0071 subs w8, w8, 0x3
0x100000464 22020054 b.cs 0x1000004a8
0x100000468 01000014 b 0x10000046c
0x10000046c e80740b9 ldr w8, [sp, 0x4] ; defines x8 in [0x0, 0x2] (solved)
0x100000470 e90308aa mov x9, x8 ; defines x9 in [0x0, 0x2] (solved)
0x100000474 e8430091 add x8, sp, 0x10
0x100000478 087969f8 ldr x8, [x8, x9, lsl 0x3]
0x10000047c e00740f9 ldr x0, [sp, 0x8]
0x100000480 a9035ff8 ldur x9, [x29, -0x10]
0x100000484 ea0740b9 ldr w10, [sp, 0x4] ; defines x10 in [0x0, 0x2] (solved)
0x100000488 21010a8b add x1, x9, x10
0x10000048c 00013fd6 blr x8 ; indirect call: arguments unproven (certified)
0x100000490 e00700f9 str x0, [sp, 0x8]
0x100000494 01000014 b 0x100000498
0x100000498 e80740b9 ldr w8, [sp, 0x4] ; defines x8 in [0x0, 0x2] (solved)
0x10000049c 08050011 add w8, w8, 0x1 ; defines x8 in [0x1, 0x3] (solved)
0x1000004a0 e80700b9 str w8, [sp, 0x4]
0x1000004a4 eeffff17 b 0x10000045c
0x1000004a8 e00740f9 ldr x0, [sp, 0x8]
0x1000004ac fd7b44a9 ldp x29, x30, [sp, 0x40]
0x1000004b0 ff430191 add sp, sp, 0x50
0x1000004b4 c0035fd6 ret
@@ -1,40 +0,0 @@
---
source: crates/r2s/tests/commands.rs
assertion_line: 527
expression: run.out
---
uint64_t fnv1a32(uint64_t arg0, uint64_t arg1)
{
uint64_t rsi_1;
uint64_t rax_2;
uint64_t rdi_1;
uint8_t tmp_11e00_1;
uint64_t rdi_2;
uint64_t rax_4;
/* r2dec proof: no individual construct is marked; 40 source obligations: 32 rendered, 8 elided, 0 refused; 14 statements rendered */
{
if ((uint8_t)((uint64_t)arg1 == (uint64_t)0U)) {
return (uint64_t)0x811c9dc5U;
} else {
rsi_1 = (uint64_t)((uint64_t)arg1 + (uint64_t)arg0);
rax_2 = (uint64_t)0x811c9dc5U;
rdi_1 = arg0;
for (; ; ) {
tmp_11e00_1 = r2sleigh_load_u8((void*)rdi_1);
rdi_2 = (uint64_t)((uint64_t)rdi_1 + (uint64_t)1U);
rax_4 = (uint64_t)(uint32_t)((uint64_t)((uint64_t)(int32_t)((uint32_t)(uint8_t)tmp_11e00_1 ^ (uint32_t)((uint64_t)rax_2 >> 0U)) * (uint64_t)0x1000193U) >> 0U);
if ((uint8_t)((uint64_t)rsi_1 != (uint64_t)rdi_2)) {
rax_2 = rax_4;
rdi_1 = rdi_2;
} else {
break;
}
}
{
return (uint64_t)rax_4;
}
}
}
}
+3
View File
@@ -10,6 +10,9 @@ Layers
- **Unit tests**, inline beside a lowering, predicate, certificate or fold.
- **Crate integration tests** in `crates/<crate>/tests/`, through the public
surface only (`crates/r2engine/tests/native.rs` is the model).
- **Golden files** in `tests/db/`, radare2's r2r format, run by
`crates/r2s/tests/golden.rs`: a command's whole output on a fixed binary,
so a pull request's diff shows what moved ([tests/db/README.md](../tests/db/README.md)).
- **The claim oracle**, `crates/r2engine/tests/oracle.rs`, described below.
- **End-to-end harnesses** that run a built `r2s` over real binaries.
+28 -2
View File
@@ -3,6 +3,9 @@
census.py run --r2s R2S --out DIR [BINARY...] pdd every function into DIR/<binary>.txt
census.py diff BASE_DIR HEAD_DIR [--report FILE] summary of moved renderings; the diff to FILE
census.py golden --r2s R2S write tests/db/census/<binary>, one r2r test per
function of each committed binary, expectations
empty for `R2S_BLESS=1` to fill (tests/db/README.md)
census.py sites DIR each staged function whose proof line counts a
residual its text holds no site for; fails on any
census.py time --r2s BASE --r2s HEAD [--runs N] [--budget R] [--rss-budget R]
@@ -69,9 +72,12 @@ LIBRARY_FRAME = re.compile(r": <?(alloc|core|std|hashbrown)::|\((\?\?\?|dhat-|al
r"|hash|sync|rc|option|result|cell|ptr|mem|array|btree|clone|raw)/)")
def corpus():
COMMITTED = ("tests/coverage/pinned", "tests/fixtures")
def corpus(directories=(*COMMITTED, "tests/coverage/artifacts/bin")):
found = []
for directory in ("tests/coverage/pinned", "tests/fixtures", "tests/coverage/artifacts/bin"):
for directory in directories:
for path in sorted((ROOT / directory).glob("*")):
if path.is_file() and os.access(path, os.X_OK) and path.suffix == "":
found.append(path)
@@ -104,6 +110,23 @@ def run(args):
print(f"{name}: {count} functions")
def golden(args):
"""One r2r file per committed binary: its `afl`, then `aa; pdd` of each function it lists."""
out = ROOT / "tests/db/census"
out.mkdir(parents=True, exist_ok=True)
for binary in corpus(COMMITTED):
listing = r2s(binary, "afl", args.r2s)
addresses = [line.split()[0] for line in listing.splitlines() if line.startswith("0x")]
relative = binary.relative_to(ROOT).as_posix()
test = (lambda name, commands: f"NAME={name}\nFILE={relative}\nCMDS={commands}\n"
"EXPECT=<<EOF\nEOF\nEXPECT_ERR=<<EOF\nEOF\nRUN\n")
header = (f"# The census of {binary.name}: what `aa; pdd` renders for each function `afl` lists.\n"
"# Regenerate with `scripts/census.py golden` when `afl` moves, then bless.\n")
tests = [test("afl", "afl")] + [test(address, f"aa; pdd @ {address}") for address in addresses]
(out / binary.name).write_text(header + "\n" + "\n".join(tests))
print(f"{binary.name}: {len(addresses)} functions")
def functions(text):
parts = re.split(r"^== (0x[0-9a-f]+)\n", text, flags=re.M)
return dict(zip(parts[1::2], parts[2::2]))
@@ -400,6 +423,9 @@ def main():
p.add_argument("--out", required=True)
p.add_argument("binaries", nargs="*")
p.set_defaults(func=run)
p = sub.add_parser("golden")
p.add_argument("--r2s", required=True)
p.set_defaults(func=golden)
p = sub.add_parser("diff")
p.add_argument("base")
p.add_argument("head")
+53
View File
@@ -0,0 +1,53 @@
# Golden tests
Each file here holds tests in radare2's r2r format. `crates/r2s/tests/golden.rs`
runs them against the r2s that the build produced, one trial per test. It runs
under `cargo test` and `cargo nextest`, filtered by `file::NAME`.
```
# A comment.
NAME=x86 listing
FILE=tests/coverage/pinned/hashes_gcc_x64_O2
CMDS=<<EOF
s 0x401330
pd 24
EOF
EXPECT=<<EOF
...
EOF
RUN
```
| Key | Meaning |
|---|---|
| `NAME` | Unique within the file. The trial is `<file>::<NAME>`. |
| `FILE` | The binary, relative to the repository root, so every run reads the same bytes. |
| `ARGS` | r2s flags before the file, split at whitespace (`-e key=value`). |
| `CMDS` | The script, one command per line or `;`-separated, passed as `r2s -q -c`. |
| `EXPECT` | stdout, exactly. |
| `EXPECT_ERR` | stderr, exactly, where it is stated; otherwise stderr is not read. |
| `BROKEN=1` | A known failure: skipped by default, run with `--ignored`. |
A test fails on any difference, printing a unified diff, and on r2s dying from a
signal.
## Blessing
```bash
R2S_BLESS=1 cargo test -p r2s --features sleigh --test golden
```
This writes what ran into each `EXPECT` and `EXPECT_ERR`, or adds them before
`RUN` where they are missing. Use `cargo test`, not nextest: nextest runs each
trial in its own process, and they would race on the files.
Read every changed line before committing a bless, as a census move is read.
An expectation records today's output. It proves that output right only after
someone judges it. The C must still follow from canonical facts (AGENTS.md,
"Tests must not train the engine to look good").
## What belongs here
A command's whole output on a fixed binary: listings, renderings, tables, the
proof line. A fact that needs logic stays a Rust test in `crates/r2s/tests/`:
a property over many lines, a comparison of two commands, or an exit status.
File diff suppressed because it is too large. Load diff
+138
View File
@@ -0,0 +1,138 @@
# The census of code_pointer_table_O0: what `aa; pdd` renders for each function `afl` lists.
# Regenerate with `scripts/census.py golden` when `afl` moves, then bless.
NAME=afl
FILE=tests/fixtures/code_pointer_table_O0
CMDS=afl
EXPECT=<<EOF
0x1000003c0 1 32 sym._table_op_add
0x1000003e0 1 32 sym._table_op_xor
0x100000400 1 32 sym._table_op_mul
0x100000420 6 152 sym._table_dispatch
0x1000004b8 1 40 sym._main
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x1000003c0
FILE=tests/fixtures/code_pointer_table_O0
CMDS=aa; pdd @ 0x1000003c0
EXPECT=<<EOF
uint64_t _table_op_add(uint64_t arg0, uint64_t arg1)
{
/* r2dec proof: no individual construct is marked; 7 source obligations: 4 rendered, 3 elided, 0 refused; 1 statements rendered */
{
return (uint64_t)((uint64_t)arg0 + (uint64_t)arg1);
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x1000003e0
FILE=tests/fixtures/code_pointer_table_O0
CMDS=aa; pdd @ 0x1000003e0
EXPECT=<<EOF
uint64_t _table_op_xor(uint64_t arg0, uint64_t arg1)
{
/* r2dec proof: no individual construct is marked; 6 source obligations: 3 rendered, 3 elided, 0 refused; 1 statements rendered */
{
return (uint64_t)((uint64_t)arg0 ^ (uint64_t)arg1);
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x100000400
FILE=tests/fixtures/code_pointer_table_O0
CMDS=aa; pdd @ 0x100000400
EXPECT=<<EOF
uint64_t _table_op_mul(uint64_t arg0, uint64_t arg1)
{
/* r2dec proof: no individual construct is marked; 6 source obligations: 3 rendered, 3 elided, 0 refused; 1 statements rendered */
{
return (uint64_t)((uint64_t)arg0 * (uint64_t)arg1);
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x100000420
FILE=tests/fixtures/code_pointer_table_O0
CMDS=aa; pdd @ 0x100000420
EXPECT=<<EOF
uint64_t _table_dispatch(uint64_t arg0, uint64_t arg1)
{
uint64_t x8_4;
uint32_t stack_m76_1;
uint64_t stack_m72_1;
uint64_t x9_2;
uint64_t tmp_12480_1;
uint64_t x0_2;
uint64_t stack_m72_3;
_Alignas(16) uint8_t frame[64];
/* r2dec proof: 1 construct is marked below; 59 source obligations: 45 rendered, 12 elided, 0 refused, 2 residual; 17 statements rendered */
{
r2sleigh_store_u64((void*)(uint64_t)(frame + 40U), (uint64_t)arg0);
r2sleigh_store_u64((void*)(uint64_t)(frame + 32U), (uint64_t)arg1);
r2sleigh_store_u128((void*)(uint64_t)(frame + 0U), (__uint128_t)r2sleigh_load_u128((void*)(uint64_t)0x100004000U));
r2sleigh_store_u64((void*)((uint64_t)(frame + 0U) + (uint64_t)16U), (uint64_t)r2sleigh_load_u64((void*)(uint64_t)0x100004010U));
x8_4 = r2sleigh_load_u64((void*)(uint64_t)(frame + 40U));
stack_m76_1 = 0;
stack_m72_1 = x8_4;
for (; ; ) {
if ((uint8_t)((uint32_t)3U <= (uint32_t)stack_m76_1)) {
break;
} else {
{
x9_2 = r2sleigh_load_u64((void*)(uint64_t)(frame + 32U));
tmp_12480_1 = (uint64_t)((uint64_t)(uint32_t)stack_m76_1 + (uint64_t)x9_2);
x0_2 = ((uint64_t(*)(uint64_t, uint64_t))(uint64_t)r2sleigh_load_u64((void*)((uint64_t)(frame + 0U) + (uint64_t)(uint32_t)stack_m76_1 * 8U)))(stack_m72_1, tmp_12480_1);
stack_m72_3 = x0_2;
{
stack_m76_1 = (uint32_t)((uint32_t)stack_m76_1 + (uint32_t)1U);
stack_m72_1 = stack_m72_3;
}
}
}
}
{
return r2sleigh_residual_u64(1);
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x1000004b8
FILE=tests/fixtures/code_pointer_table_O0
CMDS=aa; pdd @ 0x1000004b8
EXPECT=<<EOF
uint64_t _main(void)
{
void _table_dispatch(uint64_t, uint64_t);
/* r2dec proof: 1 construct is marked below; 12 source obligations: 5 rendered, 5 elided, 0 refused, 2 residual; 2 statements rendered */
{
_table_dispatch(3, 5);
return r2sleigh_residual_u64(1);
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
+204
View File
@@ -0,0 +1,204 @@
# The census of float_calls_zig_aarch64_O2g: what `aa; pdd` renders for each function `afl` lists.
# Regenerate with `scripts/census.py golden` when `afl` moves, then bless.
NAME=afl
FILE=tests/fixtures/float_calls_zig_aarch64_O2g
CMDS=afl
EXPECT=<<EOF
0x010104e8 1 52 sym._start
0x01010520 1 12 sym.store
0x0101052c 1 8 sym.call_store
0x01010534 1 56 sym.forward
0x0101056c 1 52 sym.main
0x010105a0 4 116 sym.__libc_csu_init
0x01010614 1 4 sym.__libc_csu_fini
0x01010640 1 16 sym.imp.__libc_start_main
0x01010650 1 16 sym.imp.abort
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x010104e8
FILE=tests/fixtures/float_calls_zig_aarch64_O2g
CMDS=aa; pdd @ 0x010104e8
EXPECT=<<EOF
void _start(uint64_t arg0)
{
/* r2dec proof: 2 constructs are marked below; 22 source obligations: 0 rendered, 3 elided, 0 refused, 19 residual; 0 statements rendered; 1 callee prototype supplied by the source */
{
r2sleigh_residual_void(1); /* r2dec gap: CallNotRendered at 0x10104e8:24 covering 1 op (render::values) */
r2sleigh_residual_void(2); /* r2dec gap: TransferNotFollowed at 0x10104e8 (render::control) */
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01010520
FILE=tests/fixtures/float_calls_zig_aarch64_O2g
CMDS=aa; pdd @ 0x01010520
EXPECT=<<EOF
void store(double x, double* p)
{
/* r2dec proof: no individual construct is marked; 3 source obligations: 3 rendered, 0 elided, 0 refused; 2 statements rendered */
{
r2sleigh_store_u64((void*)(uint64_t)p, (uint64_t)r2sleigh_float_to_bits_64(x + x));
return;
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x0101052c
FILE=tests/fixtures/float_calls_zig_aarch64_O2g
CMDS=aa; pdd @ 0x0101052c
EXPECT=<<EOF
void call_store(double* p)
{
void store(double, double*);
/* r2dec proof: no individual construct is marked; 4 source obligations: 4 rendered, 0 elided, 0 refused; 2 statements rendered; 1 callee prototype supplied by the source */
{
store(r2sleigh_float_from_bits_64((uint64_t)0x3ff4000000000000U), p);
return;
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01010534
FILE=tests/fixtures/float_calls_zig_aarch64_O2g
CMDS=aa; pdd @ 0x01010534
EXPECT=<<EOF
void forward(double x, double* p)
{
void store(double, double*);
/* r2dec proof: no individual construct is marked; 14 source obligations: 9 rendered, 5 elided, 0 refused; 3 statements rendered; 2 callee prototypes supplied by the source */
{
store(x, p);
store(x + r2sleigh_float_from_bits_64((uint64_t)0x3ff0000000000000U), p);
return;
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x0101056c
FILE=tests/fixtures/float_calls_zig_aarch64_O2g
CMDS=aa; pdd @ 0x0101056c
EXPECT=<<EOF
int32_t main(int32_t argc, char** argv)
{
void call_store(double*);
void forward(double, double*);
uint64_t tmp_lane_101056c_26_4_1;
_Alignas(16) uint8_t frame[32];
/* r2dec proof: 1 construct is marked below; 25 source obligations: 16 rendered, 7 elided, 0 refused, 2 residual; 4 statements rendered; 2 callee prototypes supplied by the source */
{
call_store((double*)(uint64_t)(frame + 8U));
forward(r2sleigh_float_from_bits_64(r2sleigh_load_u64((void*)(uint64_t)(frame + 8U))), (double*)(uint64_t)(frame + 8U));
tmp_lane_101056c_26_4_1 = r2sleigh_load_u64((void*)(uint64_t)(frame + 8U));
return (int32_t)(r2sleigh_float_from_bits_64(tmp_lane_101056c_26_4_1) > -2147483649.0 && r2sleigh_float_from_bits_64(tmp_lane_101056c_26_4_1) < 2147483648.0 ? (int32_t)r2sleigh_float_from_bits_64(tmp_lane_101056c_26_4_1) : r2sleigh_residual_i32(1));
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x010105a0
FILE=tests/fixtures/float_calls_zig_aarch64_O2g
CMDS=aa; pdd @ 0x010105a0
EXPECT=<<EOF
void __libc_csu_init(int32_t argc, char** argv, char** envp)
{
uint64_t x22_2;
uint64_t x23_2;
uint64_t x8_4;
uint64_t tmp_3e280_1;
/* r2dec proof: no individual construct is marked; 45 source obligations: 30 rendered, 15 elided, 0 refused; 12 statements rendered */
{
if ((uint8_t)1U) {
} else {
x22_2 = 0x1000000;
x23_2 = 1;
for (; ; ) {
x8_4 = r2sleigh_load_u64((void*)x22_2);
((uint64_t(*)(uint64_t, uint64_t, uint64_t))(uint64_t)r2sleigh_load_u64((void*)x22_2))((uint64_t)(uint32_t)argc, (uint64_t)argv, (uint64_t)envp);
tmp_3e280_1 = (uint64_t)((uint64_t)x23_2 - (uint64_t)1U);
if ((uint8_t)((uint64_t)tmp_3e280_1 != (uint64_t)0U)) {
x22_2 = (uint64_t)((uint64_t)x22_2 + (uint64_t)8U);
x23_2 = tmp_3e280_1;
} else {
break;
}
}
}
{
return;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01010614
FILE=tests/fixtures/float_calls_zig_aarch64_O2g
CMDS=aa; pdd @ 0x01010614
EXPECT=<<EOF
void __libc_csu_fini(void)
{
/* r2dec proof: no individual construct is marked; 1 source obligations: 1 rendered, 0 elided, 0 refused; 1 statements rendered */
{
return;
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01010640
FILE=tests/fixtures/float_calls_zig_aarch64_O2g
CMDS=aa; pdd @ 0x01010640
EXPECT=<<EOF
/* r2sleigh: import stub at 0x1010640; this symbol is the import `__libc_start_main` and has no body of its own. */
extern int32_t __libc_start_main(void(*)(), int32_t, char**, void(*)(), void(*)(), void(*)(), void*);
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01010650
FILE=tests/fixtures/float_calls_zig_aarch64_O2g
CMDS=aa; pdd @ 0x01010650
EXPECT=<<EOF
/* r2sleigh: import stub at 0x1010650; this symbol is the import `abort` and has no body of its own. */
extern void abort(void);
EOF
EXPECT_ERR=<<EOF
EOF
RUN
+188
View File
@@ -0,0 +1,188 @@
# The census of float_calls_zig_x86_64_O2g: what `aa; pdd` renders for each function `afl` lists.
# Regenerate with `scripts/census.py golden` when `afl` moves, then bless.
NAME=afl
FILE=tests/fixtures/float_calls_zig_x86_64_O2g
CMDS=afl
EXPECT=<<EOF
0x010014e0 1 42 sym._start
0x01001510 1 14 sym.store
0x01001520 1 18 sym.call_store
0x01001540 1 46 sym.forward
0x01001570 1 43 sym.main
0x010015a0 4 102 sym.__libc_csu_init
0x01001610 1 6 sym.__libc_csu_fini
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x010014e0
FILE=tests/fixtures/float_calls_zig_x86_64_O2g
CMDS=aa; pdd @ 0x010014e0
EXPECT=<<EOF
void _start(void)
{
uint64_t tmp_55400_2;
uint64_t tmp_3cb80_1;
/* r2dec proof: 5 constructs are marked below; 27 source obligations: 2 rendered, 3 elided, 0 refused, 22 residual; 2 statements rendered; 1 held from entry, read as residuals (stack_p0) */
{
tmp_55400_2 = r2sleigh_residual_u64(1);
r2sleigh_residual_void(2); /* r2dec gap: StoreNotSpelled at 0x10014e0:29 covering 1 op (render::values) */
r2sleigh_residual_void(3); /* r2dec gap: StoreNotSpelled at 0x10014e0:32 covering 1 op (render::values) */
tmp_3cb80_1 = r2sleigh_load_u64((void*)(uint64_t)0x1002728U);
r2sleigh_residual_void(4); /* r2dec gap: CallNotRendered at 0x10014e0:46 covering 1 op (render::values) */
r2sleigh_residual_void(5); /* r2dec gap: TailTransferNotRendered at 0x10014e0 (render::control) */
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01001510
FILE=tests/fixtures/float_calls_zig_x86_64_O2g
CMDS=aa; pdd @ 0x01001510
EXPECT=<<EOF
void store(double x, double* p)
{
/* r2dec proof: no individual construct is marked; 9 source obligations: 3 rendered, 6 elided, 0 refused; 2 statements rendered */
{
r2sleigh_store_u64((void*)(uint64_t)p, (uint64_t)r2sleigh_float_to_bits_64(x + x));
return;
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01001520
FILE=tests/fixtures/float_calls_zig_x86_64_O2g
CMDS=aa; pdd @ 0x01001520
EXPECT=<<EOF
void call_store(double* p)
{
void store(double, double*);
/* r2dec proof: no individual construct is marked; 6 source obligations: 4 rendered, 2 elided, 0 refused; 2 statements rendered; 1 callee prototype supplied by the source */
{
store(r2sleigh_float_from_bits_64((uint64_t)0x3ff4000000000000U), p);
return;
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01001540
FILE=tests/fixtures/float_calls_zig_x86_64_O2g
CMDS=aa; pdd @ 0x01001540
EXPECT=<<EOF
void forward(double x, double* p)
{
void store(double, double*);
/* r2dec proof: no individual construct is marked; 16 source obligations: 9 rendered, 7 elided, 0 refused; 3 statements rendered; 2 callee prototypes supplied by the source */
{
store(x, p);
store(x + r2sleigh_float_from_bits_64((uint64_t)0x3ff0000000000000U), p);
return;
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01001570
FILE=tests/fixtures/float_calls_zig_x86_64_O2g
CMDS=aa; pdd @ 0x01001570
EXPECT=<<EOF
int32_t main(int32_t argc, char** argv)
{
void call_store(double*);
void forward(double, double*);
uint64_t tmp_6b00_1;
uint64_t tmp_6b00_2;
_Alignas(16) uint8_t frame[40];
/* r2dec proof: 2 constructs are marked below; 35 source obligations: 14 rendered, 18 elided, 0 refused, 3 residual; 6 statements rendered; 1 held from entry, read as residuals (RAX_0); 2 callee prototypes supplied by the source */
{
r2sleigh_store_u64((void*)(uint64_t)(frame + 16U), (uint64_t)r2sleigh_residual_u64(1));
call_store((double*)(uint64_t)(frame + 16U));
tmp_6b00_1 = r2sleigh_load_u64((void*)(uint64_t)(frame + 16U));
forward(r2sleigh_float_from_bits_64(tmp_6b00_1), (double*)(uint64_t)(frame + 16U));
tmp_6b00_2 = r2sleigh_load_u64((void*)(uint64_t)(frame + 16U));
return (int32_t)(r2sleigh_float_from_bits_64(tmp_6b00_2) > -2147483649.0 && r2sleigh_float_from_bits_64(tmp_6b00_2) < 2147483648.0 ? (int32_t)r2sleigh_float_from_bits_64(tmp_6b00_2) : r2sleigh_residual_i32(2));
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x010015a0
FILE=tests/fixtures/float_calls_zig_x86_64_O2g
CMDS=aa; pdd @ 0x010015a0
EXPECT=<<EOF
void __libc_csu_init(int32_t argc, char** argv, char** envp)
{
uint64_t r12_2;
uint64_t r13_5;
uint64_t tmp_11f80_1;
uint64_t r13_6;
/* r2dec proof: no individual construct is marked; 61 source obligations: 31 rendered, 30 elided, 0 refused; 12 statements rendered */
{
if ((uint8_t)1U) {
} else {
r12_2 = 0x1000000;
r13_5 = 1;
for (; ; ) {
tmp_11f80_1 = r2sleigh_load_u64((void*)r12_2);
((uint64_t(*)(uint64_t, uint64_t, uint64_t))(uint64_t)tmp_11f80_1)((uint64_t)(uint32_t)argc, (uint64_t)argv, (uint64_t)envp);
r13_6 = (uint64_t)((uint64_t)r13_5 - (uint64_t)1U);
if ((uint8_t)((uint64_t)r13_6 != (uint64_t)0U)) {
r12_2 = (uint64_t)((uint64_t)r12_2 + (uint64_t)8U);
r13_5 = r13_6;
} else {
break;
}
}
}
{
return;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01001610
FILE=tests/fixtures/float_calls_zig_x86_64_O2g
CMDS=aa; pdd @ 0x01001610
EXPECT=<<EOF
void __libc_csu_fini(void)
{
/* r2dec proof: no individual construct is marked; 7 source obligations: 1 rendered, 6 elided, 0 refused; 1 statements rendered */
{
return;
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
@@ -0,0 +1,253 @@
# The census of float_compares_zig_aarch64_O2g: what `aa; pdd` renders for each function `afl` lists.
# Regenerate with `scripts/census.py golden` when `afl` moves, then bless.
NAME=afl
FILE=tests/fixtures/float_compares_zig_aarch64_O2g
CMDS=afl
EXPECT=<<EOF
0x010104f0 1 52 sym._start
0x01010528 1 16 sym.below
0x01010538 1 12 sym.not_below
0x01010544 1 12 sym.floor_at
0x01010550 1 20 sym.ordered_or_equal
0x01010564 1 104 sym.main
0x010105cc 4 116 sym.__libc_csu_init
0x01010640 1 4 sym.__libc_csu_fini
0x01010670 1 16 sym.imp.__libc_start_main
0x01010680 1 16 sym.imp.abort
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x010104f0
FILE=tests/fixtures/float_compares_zig_aarch64_O2g
CMDS=aa; pdd @ 0x010104f0
EXPECT=<<EOF
void _start(uint64_t arg0)
{
/* r2dec proof: 2 constructs are marked below; 22 source obligations: 0 rendered, 3 elided, 0 refused, 19 residual; 0 statements rendered; 1 callee prototype supplied by the source */
{
r2sleigh_residual_void(1); /* r2dec gap: CallNotRendered at 0x10104f0:24 covering 1 op (render::values) */
r2sleigh_residual_void(2); /* r2dec gap: TransferNotFollowed at 0x10104f0 (render::control) */
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01010528
FILE=tests/fixtures/float_compares_zig_aarch64_O2g
CMDS=aa; pdd @ 0x01010528
EXPECT=<<EOF
int32_t below(double a, double b)
{
/* r2dec proof: no individual construct is marked; 10 source obligations: 10 rendered, 0 elided, 0 refused; 1 statements rendered */
{
return (int32_t)((uint8_t)((uint32_t)((uint8_t)((uint32_t)(uint8_t)r2sleigh_float_isnan_64(a) | (uint32_t)(uint8_t)r2sleigh_float_isnan_64(b)) ? (uint8_t)0U : (uint8_t)(a < b)) ^ (uint32_t)(uint8_t)1U) ? (uint32_t)2U : (uint32_t)1U);
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01010538
FILE=tests/fixtures/float_compares_zig_aarch64_O2g
CMDS=aa; pdd @ 0x01010538
EXPECT=<<EOF
int32_t not_below(double a, double b)
{
/* r2dec proof: no individual construct is marked; 10 source obligations: 10 rendered, 0 elided, 0 refused; 1 statements rendered */
{
return (int32_t)(uint8_t)((uint32_t)((uint8_t)((uint32_t)(uint8_t)r2sleigh_float_isnan_64(a) | (uint32_t)(uint8_t)r2sleigh_float_isnan_64(b)) ? (uint8_t)0U : (uint8_t)(a < b)) ^ (uint32_t)(uint8_t)1U);
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01010544
FILE=tests/fixtures/float_compares_zig_aarch64_O2g
CMDS=aa; pdd @ 0x01010544
EXPECT=<<EOF
double floor_at(double x, double lo)
{
uint8_t tmp_e000_1;
/* r2dec proof: no individual construct is marked; 12 source obligations: 12 rendered, 0 elided, 0 refused; 2 statements rendered */
{
tmp_e000_1 = (uint8_t)((uint32_t)(uint8_t)r2sleigh_float_isnan_64(x) | (uint32_t)(uint8_t)r2sleigh_float_isnan_64(lo));
return (double)r2sleigh_float_from_bits_64((uint8_t)((uint8_t)(tmp_e000_1 ? (uint8_t)0U : (uint8_t)(x < lo)) == (uint8_t)tmp_e000_1) ? (uint64_t)r2sleigh_float_to_bits_64(x) : (uint64_t)r2sleigh_float_to_bits_64(lo));
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01010550
FILE=tests/fixtures/float_compares_zig_aarch64_O2g
CMDS=aa; pdd @ 0x01010550
EXPECT=<<EOF
int32_t ordered_or_equal(double a, double b)
{
/* r2dec proof: no individual construct is marked; 14 source obligations: 14 rendered, 0 elided, 0 refused; 1 statements rendered */
{
return (int32_t)((uint8_t)((uint32_t)((uint8_t)((uint32_t)(uint8_t)r2sleigh_float_isnan_64(a) | (uint32_t)(uint8_t)r2sleigh_float_isnan_64(b)) ? (uint8_t)0U : (uint8_t)(a == b)) | (uint32_t)(uint8_t)((uint32_t)((uint8_t)((uint32_t)(uint8_t)r2sleigh_float_isnan_64(a) | (uint32_t)(uint8_t)r2sleigh_float_isnan_64(b)) ? (uint8_t)1U : (uint8_t)(b <= a)) ^ (uint32_t)(uint8_t)1U)) ? (uint32_t)3U : (uint32_t)4U);
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01010564
FILE=tests/fixtures/float_compares_zig_aarch64_O2g
CMDS=aa; pdd @ 0x01010564
EXPECT=<<EOF
struct r2sleigh_bits_256 {
uint8_t bytes[32];
};
static inline uint64_t r2sleigh_bits_extract_256_64(struct r2sleigh_bits_256 carrier, uint64_t at)
{
uint64_t field = 0;
for (uint32_t bit = 0; bit < 64u; ++bit) {
const uint64_t from = at + bit;
if (from < 256u && ((carrier.bytes[from / 8] >> (from % 8)) & 1) != 0) {
field = (uint64_t)(field | ((uint64_t)1 << bit));
}
}
return field;
}
static inline struct r2sleigh_bits_256 r2sleigh_bits_zero_extend_64_256(uint64_t field)
{
struct r2sleigh_bits_256 carrier = {{0}};
for (uint32_t bit = 0; bit < 64u; ++bit) {
if (((field >> bit) & 1) != 0) {
carrier.bytes[bit / 8] = (uint8_t)(carrier.bytes[bit / 8] | (1u << (bit % 8)));
}
}
return carrier;
}
int32_t main(int32_t argc, char** argv)
{
int32_t below(double, double);
double floor_at(double, double);
int32_t not_below(double, double);
int32_t ordered_or_equal(double, double);
double tmp_lane_1010564_15_2_1;
uint64_t x0_1;
uint64_t x0_2;
struct r2sleigh_bits_256 z0_13;
uint64_t tmp_lane_1010564_3f_24_1;
uint64_t x0_3;
/* r2dec proof: 1 construct is marked below; 39 source obligations: 29 rendered, 8 elided, 0 refused, 2 residual; 7 statements rendered; 4 callee prototypes supplied by the source */
{
tmp_lane_1010564_15_2_1 = (double)(int32_t)argc;
x0_1 = (uint64_t)(uint32_t)below(tmp_lane_1010564_15_2_1, r2sleigh_float_from_bits_64((uint64_t)0x4000000000000000U));
x0_2 = (uint64_t)(uint32_t)not_below(tmp_lane_1010564_15_2_1, r2sleigh_float_from_bits_64((uint64_t)0x3fe0000000000000U));
z0_13 = r2sleigh_bits_zero_extend_64_256((uint64_t)r2sleigh_float_to_bits_64(floor_at(tmp_lane_1010564_15_2_1, r2sleigh_float_from_bits_64((uint64_t)0x3ff0000000000000U))));
tmp_lane_1010564_3f_24_1 = r2sleigh_bits_extract_256_64(z0_13, 0U);
x0_3 = (uint64_t)(uint32_t)ordered_or_equal(tmp_lane_1010564_15_2_1, r2sleigh_float_from_bits_64((uint64_t)0x4008000000000000U));
return (int32_t)((uint32_t)((uint64_t)x0_3 >> 0U) + (uint32_t)((uint32_t)((uint32_t)((uint64_t)x0_1 >> 0U) + (uint32_t)((uint64_t)x0_2 >> 0U)) + (uint32_t)(r2sleigh_float_from_bits_64(tmp_lane_1010564_3f_24_1) > -2147483649.0 && r2sleigh_float_from_bits_64(tmp_lane_1010564_3f_24_1) < 2147483648.0 ? (int32_t)r2sleigh_float_from_bits_64(tmp_lane_1010564_3f_24_1) : r2sleigh_residual_i32(1))));
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x010105cc
FILE=tests/fixtures/float_compares_zig_aarch64_O2g
CMDS=aa; pdd @ 0x010105cc
EXPECT=<<EOF
void __libc_csu_init(int32_t argc, char** argv, char** envp)
{
uint64_t x22_2;
uint64_t x23_2;
uint64_t x8_4;
uint64_t tmp_3e280_1;
/* r2dec proof: no individual construct is marked; 45 source obligations: 30 rendered, 15 elided, 0 refused; 12 statements rendered */
{
if ((uint8_t)1U) {
} else {
x22_2 = 0x1000000;
x23_2 = 1;
for (; ; ) {
x8_4 = r2sleigh_load_u64((void*)x22_2);
((uint64_t(*)(uint64_t, uint64_t, uint64_t))(uint64_t)r2sleigh_load_u64((void*)x22_2))((uint64_t)(uint32_t)argc, (uint64_t)argv, (uint64_t)envp);
tmp_3e280_1 = (uint64_t)((uint64_t)x23_2 - (uint64_t)1U);
if ((uint8_t)((uint64_t)tmp_3e280_1 != (uint64_t)0U)) {
x22_2 = (uint64_t)((uint64_t)x22_2 + (uint64_t)8U);
x23_2 = tmp_3e280_1;
} else {
break;
}
}
}
{
return;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01010640
FILE=tests/fixtures/float_compares_zig_aarch64_O2g
CMDS=aa; pdd @ 0x01010640
EXPECT=<<EOF
void __libc_csu_fini(void)
{
/* r2dec proof: no individual construct is marked; 1 source obligations: 1 rendered, 0 elided, 0 refused; 1 statements rendered */
{
return;
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01010670
FILE=tests/fixtures/float_compares_zig_aarch64_O2g
CMDS=aa; pdd @ 0x01010670
EXPECT=<<EOF
/* r2sleigh: import stub at 0x1010670; this symbol is the import `__libc_start_main` and has no body of its own. */
extern int32_t __libc_start_main(void(*)(), int32_t, char**, void(*)(), void(*)(), void(*)(), void*);
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01010680
FILE=tests/fixtures/float_compares_zig_aarch64_O2g
CMDS=aa; pdd @ 0x01010680
EXPECT=<<EOF
/* r2sleigh: import stub at 0x1010680; this symbol is the import `abort` and has no body of its own. */
extern void abort(void);
EOF
EXPECT_ERR=<<EOF
EOF
RUN
@@ -0,0 +1,229 @@
# The census of float_compares_zig_x86_64_O2g: what `aa; pdd` renders for each function `afl` lists.
# Regenerate with `scripts/census.py golden` when `afl` moves, then bless.
NAME=afl
FILE=tests/fixtures/float_compares_zig_x86_64_O2g
CMDS=afl
EXPECT=<<EOF
0x01001520 1 42 sym._start
0x01001550 1 18 sym.below
0x01001570 1 15 sym.not_below
0x01001580 1 27 sym.floor_at
0x010015a0 1 15 sym.ordered_or_equal
0x010015b0 1 113 sym.main
0x01001630 4 102 sym.__libc_csu_init
0x010016a0 1 6 sym.__libc_csu_fini
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01001520
FILE=tests/fixtures/float_compares_zig_x86_64_O2g
CMDS=aa; pdd @ 0x01001520
EXPECT=<<EOF
void _start(void)
{
uint64_t tmp_55400_2;
uint64_t tmp_3cb80_1;
/* r2dec proof: 5 constructs are marked below; 27 source obligations: 2 rendered, 3 elided, 0 refused, 22 residual; 2 statements rendered; 1 held from entry, read as residuals (stack_p0) */
{
tmp_55400_2 = r2sleigh_residual_u64(1);
r2sleigh_residual_void(2); /* r2dec gap: StoreNotSpelled at 0x1001520:29 covering 1 op (render::values) */
r2sleigh_residual_void(3); /* r2dec gap: StoreNotSpelled at 0x1001520:32 covering 1 op (render::values) */
tmp_3cb80_1 = r2sleigh_load_u64((void*)(uint64_t)0x10027b8U);
r2sleigh_residual_void(4); /* r2dec gap: CallNotRendered at 0x1001520:46 covering 1 op (render::values) */
r2sleigh_residual_void(5); /* r2dec gap: TailTransferNotRendered at 0x1001520 (render::control) */
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01001550
FILE=tests/fixtures/float_compares_zig_x86_64_O2g
CMDS=aa; pdd @ 0x01001550
EXPECT=<<EOF
int32_t below(double a, double b)
{
/* r2dec proof: no individual construct is marked; 20 source obligations: 14 rendered, 6 elided, 0 refused; 1 statements rendered */
{
return (int32_t)((uint32_t)((uint64_t)(uint8_t)((uint32_t)(uint8_t)((uint32_t)(uint8_t)((uint32_t)(uint8_t)r2sleigh_float_isnan_64(b) | (uint32_t)(uint8_t)r2sleigh_float_isnan_64(a)) | (uint32_t)(uint8_t)(b == a)) | (uint32_t)(uint8_t)((uint32_t)(uint8_t)((uint32_t)(uint8_t)r2sleigh_float_isnan_64(b) | (uint32_t)(uint8_t)r2sleigh_float_isnan_64(a)) | (uint32_t)(uint8_t)(b < a))) >> 0U) + (uint32_t)1U);
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01001570
FILE=tests/fixtures/float_compares_zig_x86_64_O2g
CMDS=aa; pdd @ 0x01001570
EXPECT=<<EOF
int32_t not_below(double a, double b)
{
/* r2dec proof: no individual construct is marked; 18 source obligations: 12 rendered, 6 elided, 0 refused; 1 statements rendered */
{
return (int32_t)(uint8_t)((uint32_t)(uint8_t)((uint32_t)(uint8_t)((uint32_t)(uint8_t)r2sleigh_float_isnan_64(b) | (uint32_t)(uint8_t)r2sleigh_float_isnan_64(a)) | (uint32_t)(uint8_t)(b == a)) | (uint32_t)(uint8_t)((uint32_t)(uint8_t)((uint32_t)(uint8_t)r2sleigh_float_isnan_64(b) | (uint32_t)(uint8_t)r2sleigh_float_isnan_64(a)) | (uint32_t)(uint8_t)(b < a)));
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01001580
FILE=tests/fixtures/float_compares_zig_x86_64_O2g
CMDS=aa; pdd @ 0x01001580
EXPECT=<<EOF
double floor_at(double x, double lo)
{
uint64_t tmp_lane_1001580_5_2_1;
uint64_t xmmtmp1_qa_2;
uint64_t tmp_lane_1001580_c_9_1;
__uint128_t xmm0_1;
uint64_t tmp_lane_1001580_d_a_1;
uint64_t tmp_lane_1001580_d_c_1;
__uint128_t xmm0_2;
uint64_t tmp_lane_1001580_f_f_1;
__uint128_t xmm2_4;
uint64_t tmp_lane_1001580_11_11_1;
uint64_t tmp_lane_1001580_11_12_1;
__uint128_t xmm2_5;
/* r2dec proof: 3 constructs are marked below; 25 source obligations: 16 rendered, 6 elided, 0 refused, 3 residual; 13 statements rendered; 2 held from entry, read as residuals (XMM0_0, XMM1_0) */
{
tmp_lane_1001580_5_2_1 = (uint64_t)((__uint128_t)r2sleigh_residual_u128(1) >> 64U);
xmmtmp1_qa_2 = (uint64_t)((uint64_t)(uint8_t)(lo <= x) * (uint64_t)-0x1);
tmp_lane_1001580_c_9_1 = (uint64_t)((uint64_t)r2sleigh_float_to_bits_64(x) & (uint64_t)xmmtmp1_qa_2);
xmm0_1 = (__uint128_t)(((__uint128_t)0U & (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0U)) | ((__uint128_t)tmp_lane_1001580_c_9_1 & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) << 0U);
tmp_lane_1001580_d_a_1 = (uint64_t)((__uint128_t)r2sleigh_residual_u128(2) >> 64U);
tmp_lane_1001580_d_c_1 = (uint64_t)((uint64_t)tmp_lane_1001580_d_a_1 & (uint64_t)tmp_lane_1001580_5_2_1);
xmm0_2 = (__uint128_t)(((__uint128_t)xmm0_1 & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) | ((__uint128_t)tmp_lane_1001580_d_c_1 & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) << 64U);
tmp_lane_1001580_f_f_1 = (uint64_t)((uint64_t)~(uint64_t)xmmtmp1_qa_2 & (uint64_t)r2sleigh_float_to_bits_64(lo));
xmm2_4 = (__uint128_t)(((__uint128_t)0U & (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0U)) | ((__uint128_t)tmp_lane_1001580_f_f_1 & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) << 0U);
tmp_lane_1001580_11_11_1 = (uint64_t)((__uint128_t)r2sleigh_residual_u128(3) >> 64U);
tmp_lane_1001580_11_12_1 = (uint64_t)((uint64_t)~(uint64_t)tmp_lane_1001580_5_2_1 & (uint64_t)tmp_lane_1001580_11_11_1);
xmm2_5 = (__uint128_t)(((__uint128_t)xmm2_4 & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) | ((__uint128_t)tmp_lane_1001580_11_12_1 & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) << 64U);
return (double)r2sleigh_float_from_bits_64((uint64_t)((__uint128_t)xmm0_2 | (__uint128_t)xmm2_5));
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x010015a0
FILE=tests/fixtures/float_compares_zig_x86_64_O2g
CMDS=aa; pdd @ 0x010015a0
EXPECT=<<EOF
int32_t ordered_or_equal(double a, double b)
{
/* r2dec proof: no individual construct is marked; 15 source obligations: 9 rendered, 6 elided, 0 refused; 1 statements rendered */
{
return (int32_t)((uint32_t)(uint8_t)((uint32_t)(uint8_t)((uint32_t)(uint8_t)r2sleigh_float_isnan_64(b) | (uint32_t)(uint8_t)r2sleigh_float_isnan_64(a)) | (uint32_t)(uint8_t)(b < a)) + (uint32_t)3U);
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x010015b0
FILE=tests/fixtures/float_compares_zig_x86_64_O2g
CMDS=aa; pdd @ 0x010015b0
EXPECT=<<EOF
int32_t main(int32_t argc, char** argv)
{
int32_t below(double, double);
double floor_at(double, double);
int32_t not_below(double, double);
int32_t ordered_or_equal(double, double);
double tmp_lane_10015b0_13_1_1;
uint64_t rax_1;
uint64_t rax_2;
__uint128_t xmm0_6;
uint64_t tmp_lane_10015b0_3c_15_1;
uint64_t rax_3;
/* r2dec proof: 1 construct is marked below; 57 source obligations: 29 rendered, 26 elided, 0 refused, 2 residual; 7 statements rendered; 4 callee prototypes supplied by the source */
{
tmp_lane_10015b0_13_1_1 = (double)(int32_t)argc;
rax_1 = (uint64_t)(uint32_t)below(tmp_lane_10015b0_13_1_1, r2sleigh_float_from_bits_64((uint64_t)0x4000000000000000U));
rax_2 = (uint64_t)(uint32_t)not_below(tmp_lane_10015b0_13_1_1, r2sleigh_float_from_bits_64((uint64_t)0x3fe0000000000000U));
xmm0_6 = (__uint128_t)r2sleigh_float_to_bits_64(floor_at(tmp_lane_10015b0_13_1_1, r2sleigh_float_from_bits_64((uint64_t)0x3ff0000000000000U)));
tmp_lane_10015b0_3c_15_1 = (uint64_t)((__uint128_t)xmm0_6 >> 0U);
rax_3 = (uint64_t)(uint32_t)ordered_or_equal(tmp_lane_10015b0_13_1_1, r2sleigh_float_from_bits_64((uint64_t)0x4008000000000000U));
return (int32_t)((uint32_t)((uint64_t)rax_3 >> 0U) + (uint32_t)((uint32_t)((uint32_t)((uint64_t)rax_1 >> 0U) + (uint32_t)((uint64_t)rax_2 >> 0U)) + (uint32_t)(r2sleigh_float_from_bits_64(tmp_lane_10015b0_3c_15_1) > -2147483649.0 && r2sleigh_float_from_bits_64(tmp_lane_10015b0_3c_15_1) < 2147483648.0 ? (int32_t)r2sleigh_float_from_bits_64(tmp_lane_10015b0_3c_15_1) : r2sleigh_residual_i32(1))));
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01001630
FILE=tests/fixtures/float_compares_zig_x86_64_O2g
CMDS=aa; pdd @ 0x01001630
EXPECT=<<EOF
void __libc_csu_init(int32_t argc, char** argv, char** envp)
{
uint64_t r12_2;
uint64_t r13_5;
uint64_t tmp_11f80_1;
uint64_t r13_6;
/* r2dec proof: no individual construct is marked; 61 source obligations: 31 rendered, 30 elided, 0 refused; 12 statements rendered */
{
if ((uint8_t)1U) {
} else {
r12_2 = 0x1000000;
r13_5 = 1;
for (; ; ) {
tmp_11f80_1 = r2sleigh_load_u64((void*)r12_2);
((uint64_t(*)(uint64_t, uint64_t, uint64_t))(uint64_t)tmp_11f80_1)((uint64_t)(uint32_t)argc, (uint64_t)argv, (uint64_t)envp);
r13_6 = (uint64_t)((uint64_t)r13_5 - (uint64_t)1U);
if ((uint8_t)((uint64_t)r13_6 != (uint64_t)0U)) {
r12_2 = (uint64_t)((uint64_t)r12_2 + (uint64_t)8U);
r13_5 = r13_6;
} else {
break;
}
}
}
{
return;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x010016a0
FILE=tests/fixtures/float_compares_zig_x86_64_O2g
CMDS=aa; pdd @ 0x010016a0
EXPECT=<<EOF
void __libc_csu_fini(void)
{
/* r2dec proof: no individual construct is marked; 7 source obligations: 1 rendered, 6 elided, 0 refused; 1 statements rendered */
{
return;
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
+205
View File
@@ -0,0 +1,205 @@
# The census of float_moves_zig_aarch64_O2g: what `aa; pdd` renders for each function `afl` lists.
# Regenerate with `scripts/census.py golden` when `afl` moves, then bless.
NAME=afl
FILE=tests/fixtures/float_moves_zig_aarch64_O2g
CMDS=afl
EXPECT=<<EOF
0x010104b0 1 52 sym._start
0x010104e8 1 8 sym.scale
0x010104f0 1 16 sym.swap_call
0x01010500 1 32 sym.main
0x01010520 4 116 sym.__libc_csu_init
0x01010594 1 4 sym.__libc_csu_fini
0x010105c0 1 16 sym.imp.__libc_start_main
0x010105d0 1 16 sym.imp.abort
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x010104b0
FILE=tests/fixtures/float_moves_zig_aarch64_O2g
CMDS=aa; pdd @ 0x010104b0
EXPECT=<<EOF
void _start(uint64_t arg0)
{
/* r2dec proof: 2 constructs are marked below; 22 source obligations: 0 rendered, 3 elided, 0 refused, 19 residual; 0 statements rendered; 1 callee prototype supplied by the source */
{
r2sleigh_residual_void(1); /* r2dec gap: CallNotRendered at 0x10104b0:24 covering 1 op (render::values) */
r2sleigh_residual_void(2); /* r2dec gap: TransferNotFollowed at 0x10104b0 (render::control) */
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x010104e8
FILE=tests/fixtures/float_moves_zig_aarch64_O2g
CMDS=aa; pdd @ 0x010104e8
EXPECT=<<EOF
double scale(double x, double k)
{
/* r2dec proof: no individual construct is marked; 3 source obligations: 3 rendered, 0 elided, 0 refused; 1 statements rendered */
{
return (double)(x * k);
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x010104f0
FILE=tests/fixtures/float_moves_zig_aarch64_O2g
CMDS=aa; pdd @ 0x010104f0
EXPECT=<<EOF
double swap_call(double a, double b)
{
double scale(double, double);
/* r2dec proof: no individual construct is marked; 4 source obligations: 4 rendered, 0 elided, 0 refused; 1 statements rendered; 1 callee prototype supplied by the source */
{
return scale(b, a);
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01010500
FILE=tests/fixtures/float_moves_zig_aarch64_O2g
CMDS=aa; pdd @ 0x01010500
EXPECT=<<EOF
struct r2sleigh_bits_256 {
uint8_t bytes[32];
};
static inline uint64_t r2sleigh_bits_extract_256_64(struct r2sleigh_bits_256 carrier, uint64_t at)
{
uint64_t field = 0;
for (uint32_t bit = 0; bit < 64u; ++bit) {
const uint64_t from = at + bit;
if (from < 256u && ((carrier.bytes[from / 8] >> (from % 8)) & 1) != 0) {
field = (uint64_t)(field | ((uint64_t)1 << bit));
}
}
return field;
}
static inline struct r2sleigh_bits_256 r2sleigh_bits_zero_extend_64_256(uint64_t field)
{
struct r2sleigh_bits_256 carrier = {{0}};
for (uint32_t bit = 0; bit < 64u; ++bit) {
if (((field >> bit) & 1) != 0) {
carrier.bytes[bit / 8] = (uint8_t)(carrier.bytes[bit / 8] | (1u << (bit % 8)));
}
}
return carrier;
}
int32_t main(int32_t argc, char** argv)
{
double swap_call(double, double);
struct r2sleigh_bits_256 z0_5;
uint64_t tmp_lane_1010500_11_9_1;
/* r2dec proof: 1 construct is marked below; 15 source obligations: 10 rendered, 3 elided, 0 refused, 2 residual; 3 statements rendered; 1 callee prototype supplied by the source */
{
z0_5 = r2sleigh_bits_zero_extend_64_256((uint64_t)r2sleigh_float_to_bits_64(swap_call((double)(int32_t)argc, r2sleigh_float_from_bits_64((uint64_t)0x4000000000000000U))));
tmp_lane_1010500_11_9_1 = r2sleigh_bits_extract_256_64(z0_5, 0U);
return (int32_t)(r2sleigh_float_from_bits_64(tmp_lane_1010500_11_9_1) > -2147483649.0 && r2sleigh_float_from_bits_64(tmp_lane_1010500_11_9_1) < 2147483648.0 ? (int32_t)r2sleigh_float_from_bits_64(tmp_lane_1010500_11_9_1) : r2sleigh_residual_i32(1));
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01010520
FILE=tests/fixtures/float_moves_zig_aarch64_O2g
CMDS=aa; pdd @ 0x01010520
EXPECT=<<EOF
void __libc_csu_init(int32_t argc, char** argv, char** envp)
{
uint64_t x22_2;
uint64_t x23_2;
uint64_t x8_4;
uint64_t tmp_3e280_1;
/* r2dec proof: no individual construct is marked; 45 source obligations: 30 rendered, 15 elided, 0 refused; 12 statements rendered */
{
if ((uint8_t)1U) {
} else {
x22_2 = 0x1000000;
x23_2 = 1;
for (; ; ) {
x8_4 = r2sleigh_load_u64((void*)x22_2);
((uint64_t(*)(uint64_t, uint64_t, uint64_t))(uint64_t)r2sleigh_load_u64((void*)x22_2))((uint64_t)(uint32_t)argc, (uint64_t)argv, (uint64_t)envp);
tmp_3e280_1 = (uint64_t)((uint64_t)x23_2 - (uint64_t)1U);
if ((uint8_t)((uint64_t)tmp_3e280_1 != (uint64_t)0U)) {
x22_2 = (uint64_t)((uint64_t)x22_2 + (uint64_t)8U);
x23_2 = tmp_3e280_1;
} else {
break;
}
}
}
{
return;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01010594
FILE=tests/fixtures/float_moves_zig_aarch64_O2g
CMDS=aa; pdd @ 0x01010594
EXPECT=<<EOF
void __libc_csu_fini(void)
{
/* r2dec proof: no individual construct is marked; 1 source obligations: 1 rendered, 0 elided, 0 refused; 1 statements rendered */
{
return;
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x010105c0
FILE=tests/fixtures/float_moves_zig_aarch64_O2g
CMDS=aa; pdd @ 0x010105c0
EXPECT=<<EOF
/* r2sleigh: import stub at 0x10105c0; this symbol is the import `__libc_start_main` and has no body of its own. */
extern int32_t __libc_start_main(void(*)(), int32_t, char**, void(*)(), void(*)(), void(*)(), void*);
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x010105d0
FILE=tests/fixtures/float_moves_zig_aarch64_O2g
CMDS=aa; pdd @ 0x010105d0
EXPECT=<<EOF
/* r2sleigh: import stub at 0x10105d0; this symbol is the import `abort` and has no body of its own. */
extern void abort(void);
EOF
EXPECT_ERR=<<EOF
EOF
RUN
+159
View File
@@ -0,0 +1,159 @@
# The census of float_moves_zig_x86_64_O2g: what `aa; pdd` renders for each function `afl` lists.
# Regenerate with `scripts/census.py golden` when `afl` moves, then bless.
NAME=afl
FILE=tests/fixtures/float_moves_zig_x86_64_O2g
CMDS=afl
EXPECT=<<EOF
0x010014b0 1 42 sym._start
0x010014e0 1 10 sym.scale
0x010014f0 1 19 sym.swap_call
0x01001510 1 27 sym.main
0x01001530 4 102 sym.__libc_csu_init
0x010015a0 1 6 sym.__libc_csu_fini
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x010014b0
FILE=tests/fixtures/float_moves_zig_x86_64_O2g
CMDS=aa; pdd @ 0x010014b0
EXPECT=<<EOF
void _start(void)
{
uint64_t tmp_55400_2;
uint64_t tmp_3cb80_1;
/* r2dec proof: 5 constructs are marked below; 27 source obligations: 2 rendered, 3 elided, 0 refused, 22 residual; 2 statements rendered; 1 held from entry, read as residuals (stack_p0) */
{
tmp_55400_2 = r2sleigh_residual_u64(1);
r2sleigh_residual_void(2); /* r2dec gap: StoreNotSpelled at 0x10014b0:29 covering 1 op (render::values) */
r2sleigh_residual_void(3); /* r2dec gap: StoreNotSpelled at 0x10014b0:32 covering 1 op (render::values) */
tmp_3cb80_1 = r2sleigh_load_u64((void*)(uint64_t)0x10026b8U);
r2sleigh_residual_void(4); /* r2dec gap: CallNotRendered at 0x10014b0:46 covering 1 op (render::values) */
r2sleigh_residual_void(5); /* r2dec gap: TailTransferNotRendered at 0x10014b0 (render::control) */
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x010014e0
FILE=tests/fixtures/float_moves_zig_x86_64_O2g
CMDS=aa; pdd @ 0x010014e0
EXPECT=<<EOF
double scale(double x, double k)
{
/* r2dec proof: no individual construct is marked; 9 source obligations: 3 rendered, 6 elided, 0 refused; 1 statements rendered */
{
return (double)(x * k);
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x010014f0
FILE=tests/fixtures/float_moves_zig_x86_64_O2g
CMDS=aa; pdd @ 0x010014f0
EXPECT=<<EOF
double swap_call(double a, double b)
{
double scale(double, double);
/* r2dec proof: no individual construct is marked; 6 source obligations: 4 rendered, 2 elided, 0 refused; 1 statements rendered; 1 callee prototype supplied by the source */
{
return scale(b, a);
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01001510
FILE=tests/fixtures/float_moves_zig_x86_64_O2g
CMDS=aa; pdd @ 0x01001510
EXPECT=<<EOF
int32_t main(int32_t argc, char** argv)
{
double swap_call(double, double);
__uint128_t xmm0_2;
uint64_t tmp_lane_1001510_a_4_1;
/* r2dec proof: 1 construct is marked below; 19 source obligations: 8 rendered, 9 elided, 0 refused, 2 residual; 3 statements rendered; 1 callee prototype supplied by the source */
{
xmm0_2 = (__uint128_t)r2sleigh_float_to_bits_64(swap_call((double)(int32_t)argc, r2sleigh_float_from_bits_64((uint64_t)0x4000000000000000U)));
tmp_lane_1001510_a_4_1 = (uint64_t)((__uint128_t)xmm0_2 >> 0U);
return (int32_t)(r2sleigh_float_from_bits_64(tmp_lane_1001510_a_4_1) > -2147483649.0 && r2sleigh_float_from_bits_64(tmp_lane_1001510_a_4_1) < 2147483648.0 ? (int32_t)r2sleigh_float_from_bits_64(tmp_lane_1001510_a_4_1) : r2sleigh_residual_i32(1));
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01001530
FILE=tests/fixtures/float_moves_zig_x86_64_O2g
CMDS=aa; pdd @ 0x01001530
EXPECT=<<EOF
void __libc_csu_init(int32_t argc, char** argv, char** envp)
{
uint64_t r12_2;
uint64_t r13_5;
uint64_t tmp_11f80_1;
uint64_t r13_6;
/* r2dec proof: no individual construct is marked; 61 source obligations: 31 rendered, 30 elided, 0 refused; 12 statements rendered */
{
if ((uint8_t)1U) {
} else {
r12_2 = 0x1000000;
r13_5 = 1;
for (; ; ) {
tmp_11f80_1 = r2sleigh_load_u64((void*)r12_2);
((uint64_t(*)(uint64_t, uint64_t, uint64_t))(uint64_t)tmp_11f80_1)((uint64_t)(uint32_t)argc, (uint64_t)argv, (uint64_t)envp);
r13_6 = (uint64_t)((uint64_t)r13_5 - (uint64_t)1U);
if ((uint8_t)((uint64_t)r13_6 != (uint64_t)0U)) {
r12_2 = (uint64_t)((uint64_t)r12_2 + (uint64_t)8U);
r13_5 = r13_6;
} else {
break;
}
}
}
{
return;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x010015a0
FILE=tests/fixtures/float_moves_zig_x86_64_O2g
CMDS=aa; pdd @ 0x010015a0
EXPECT=<<EOF
void __libc_csu_fini(void)
{
/* r2dec proof: no individual construct is marked; 7 source obligations: 1 rendered, 6 elided, 0 refused; 1 statements rendered */
{
return;
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
@@ -0,0 +1,429 @@
# The census of float_returns_zig_aarch64_O2g: what `aa; pdd` renders for each function `afl` lists.
# Regenerate with `scripts/census.py golden` when `afl` moves, then bless.
NAME=afl
FILE=tests/fixtures/float_returns_zig_aarch64_O2g
CMDS=afl
EXPECT=<<EOF
0x010104e8 1 52 sym._start
0x01010520 1 12 sym.half
0x0101052c 1 56 sym.twice_half
0x01010564 10 128 sym.loop_sum
0x010105e4 1 76 sym.main
0x01010630 4 116 sym.__libc_csu_init
0x010106a4 1 4 sym.__libc_csu_fini
0x010106d0 1 16 sym.imp.__libc_start_main
0x010106e0 1 16 sym.imp.abort
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x010104e8
FILE=tests/fixtures/float_returns_zig_aarch64_O2g
CMDS=aa; pdd @ 0x010104e8
EXPECT=<<EOF
void _start(uint64_t arg0)
{
/* r2dec proof: 2 constructs are marked below; 22 source obligations: 0 rendered, 3 elided, 0 refused, 19 residual; 0 statements rendered; 1 callee prototype supplied by the source */
{
r2sleigh_residual_void(1); /* r2dec gap: CallNotRendered at 0x10104e8:24 covering 1 op (render::values) */
r2sleigh_residual_void(2); /* r2dec gap: TransferNotFollowed at 0x10104e8 (render::control) */
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01010520
FILE=tests/fixtures/float_returns_zig_aarch64_O2g
CMDS=aa; pdd @ 0x01010520
EXPECT=<<EOF
double half(double x)
{
/* r2dec proof: no individual construct is marked; 3 source obligations: 3 rendered, 0 elided, 0 refused; 1 statements rendered */
{
return (double)(x * r2sleigh_float_from_bits_64((uint64_t)0x3fe0000000000000U));
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x0101052c
FILE=tests/fixtures/float_returns_zig_aarch64_O2g
CMDS=aa; pdd @ 0x0101052c
EXPECT=<<EOF
struct r2sleigh_bits_256 {
uint8_t bytes[32];
};
static inline uint64_t r2sleigh_bits_extract_256_64(struct r2sleigh_bits_256 carrier, uint64_t at)
{
uint64_t field = 0;
for (uint32_t bit = 0; bit < 64u; ++bit) {
const uint64_t from = at + bit;
if (from < 256u && ((carrier.bytes[from / 8] >> (from % 8)) & 1) != 0) {
field = (uint64_t)(field | ((uint64_t)1 << bit));
}
}
return field;
}
static inline struct r2sleigh_bits_256 r2sleigh_bits_zero_extend_64_256(uint64_t field)
{
struct r2sleigh_bits_256 carrier = {{0}};
for (uint32_t bit = 0; bit < 64u; ++bit) {
if (((field >> bit) & 1) != 0) {
carrier.bytes[bit / 8] = (uint8_t)(carrier.bytes[bit / 8] | (1u << (bit % 8)));
}
}
return carrier;
}
double twice_half(double x)
{
double half(double);
struct r2sleigh_bits_256 z0_1;
uint64_t tmp_lane_101052c_1d_10_1;
struct r2sleigh_bits_256 z0_6;
uint64_t tmp_lane_101052c_27_1b_1;
/* r2dec proof: no individual construct is marked; 18 source obligations: 14 rendered, 4 elided, 0 refused; 5 statements rendered; 2 callee prototypes supplied by the source */
{
z0_1 = r2sleigh_bits_zero_extend_64_256((uint64_t)r2sleigh_float_to_bits_64(half(x)));
tmp_lane_101052c_1d_10_1 = r2sleigh_bits_extract_256_64(z0_1, 0U);
z0_6 = r2sleigh_bits_zero_extend_64_256((uint64_t)r2sleigh_float_to_bits_64(half(x + r2sleigh_float_from_bits_64((uint64_t)0x3ff0000000000000U))));
tmp_lane_101052c_27_1b_1 = r2sleigh_bits_extract_256_64(z0_6, 0U);
return (double)(r2sleigh_float_from_bits_64(tmp_lane_101052c_1d_10_1) + r2sleigh_float_from_bits_64(tmp_lane_101052c_27_1b_1));
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01010564
FILE=tests/fixtures/float_returns_zig_aarch64_O2g
CMDS=aa; pdd @ 0x01010564
EXPECT=<<EOF
struct r2sleigh_bits_256 {
uint8_t bytes[32];
};
static inline uint64_t r2sleigh_bits_extract_256_64(struct r2sleigh_bits_256 carrier, uint64_t at)
{
uint64_t field = 0;
for (uint32_t bit = 0; bit < 64u; ++bit) {
const uint64_t from = at + bit;
if (from < 256u && ((carrier.bytes[from / 8] >> (from % 8)) & 1) != 0) {
field = (uint64_t)(field | ((uint64_t)1 << bit));
}
}
return field;
}
static inline struct r2sleigh_bits_256 r2sleigh_bits_insert_256_64(struct r2sleigh_bits_256 carrier, uint64_t field, uint64_t at)
{
for (uint32_t bit = 0; bit < 64u; ++bit) {
const uint64_t to = at + bit;
if (to < 256u) {
const unsigned mask = 1u << (to % 8);
if (((field >> bit) & 1) != 0) {
carrier.bytes[to / 8] = (uint8_t)(carrier.bytes[to / 8] | mask);
} else {
carrier.bytes[to / 8] = (uint8_t)(carrier.bytes[to / 8] & ~mask);
}
}
}
return carrier;
}
static inline struct r2sleigh_bits_256 r2sleigh_bits_zero_extend_64_256(uint64_t field)
{
struct r2sleigh_bits_256 carrier = {{0}};
for (uint32_t bit = 0; bit < 64u; ++bit) {
if (((field >> bit) & 1) != 0) {
carrier.bytes[bit / 8] = (uint8_t)(carrier.bytes[bit / 8] | (1u << (bit % 8)));
}
}
return carrier;
}
double loop_sum(const double* v, int32_t n)
{
struct r2sleigh_bits_256 z0_1;
struct r2sleigh_bits_256 z0_2;
struct r2sleigh_bits_256 z0_3;
struct r2sleigh_bits_256 z0_4;
uint64_t x8_1;
uint64_t x9_2;
uint64_t x10_2;
uint64_t x11_2;
struct r2sleigh_bits_256 z0_5;
uint64_t tmp_7b80_1;
__uint128_t tmp_lane_1010598_1_7_1;
uint64_t tmp_ca600_1;
__uint128_t tmp_lane_1010598_5_a_1;
uint64_t tmp_3e280_1;
uint64_t tmp_lane_1010598_1a_d_1;
uint64_t tmp_lane_1010598_1e_12_1;
uint64_t tmp_lane_1010598_1e_13_1;
uint64_t tmp_lane_1010598_22_18_1;
uint64_t tmp_lane_1010598_2a_24_1;
double tmp_lane_1010598_2e_2b_1;
struct r2sleigh_bits_256 z0_18;
struct r2sleigh_bits_256 z0_19;
struct r2sleigh_bits_256 z0_20;
struct r2sleigh_bits_256 z0_21;
uint64_t x9_3;
struct r2sleigh_bits_256 z0_22;
uint64_t x10_5;
uint64_t x8_3;
struct r2sleigh_bits_256 z0_23;
uint64_t tmp_lane_10105d0_2_2f_1;
uint64_t tmp_3e280_2;
uint64_t tmp_lane_10105d0_11_33_1;
double tmp_lane_10105d0_11_35_1;
struct r2sleigh_bits_256 z0_24;
struct r2sleigh_bits_256 z0_25;
struct r2sleigh_bits_256 z0_26;
struct r2sleigh_bits_256 z0_27;
struct r2sleigh_bits_256 z0_28;
/* r2dec proof: no individual construct is marked; 91 source obligations: 91 rendered, 0 elided, 0 refused; 60 statements rendered */
{
if ((uint8_t)((int32_t)n < (int32_t)1U)) {
return (double)r2sleigh_float_from_bits_64((uint64_t)0U);
} else {
z0_1 = r2sleigh_bits_insert_256_64(r2sleigh_bits_zero_extend_64_256((uint64_t)0U), (uint64_t)0U, 0U);
z0_2 = r2sleigh_bits_insert_256_64(z0_1, (uint64_t)0U, 64U);
z0_3 = r2sleigh_bits_insert_256_64(z0_2, (uint64_t)0U, 128U);
z0_4 = r2sleigh_bits_insert_256_64(z0_3, (uint64_t)0U, 192U);
x8_1 = (uint64_t)(uint32_t)n;
if ((uint8_t)((uint32_t)4U <= (uint32_t)n)) {
x9_2 = (uint64_t)((uint64_t)x8_1 & (uint64_t)0x7ffffffcU);
x10_2 = (uint64_t)((uint64_t)v + (uint64_t)16U);
x11_2 = (uint64_t)((uint64_t)x8_1 & (uint64_t)0x7ffffffcU);
z0_5 = z0_4;
for (; ; ) {
tmp_7b80_1 = (uint64_t)((uint64_t)x10_2 - (uint64_t)16U);
tmp_lane_1010598_1_7_1 = r2sleigh_load_u128((void*)tmp_7b80_1);
tmp_ca600_1 = (uint64_t)((uint64_t)tmp_7b80_1 + (uint64_t)16U);
tmp_lane_1010598_5_a_1 = r2sleigh_load_u128((void*)tmp_ca600_1);
tmp_3e280_1 = (uint64_t)((uint64_t)x11_2 - (uint64_t)4U);
tmp_lane_1010598_1a_d_1 = (uint64_t)((__uint128_t)tmp_lane_1010598_1_7_1 >> 64U);
tmp_lane_1010598_1e_12_1 = r2sleigh_bits_extract_256_64(z0_5, 0U);
tmp_lane_1010598_1e_13_1 = (uint64_t)((__uint128_t)tmp_lane_1010598_1_7_1 >> 0U);
tmp_lane_1010598_22_18_1 = (uint64_t)((__uint128_t)tmp_lane_1010598_5_a_1 >> 64U);
tmp_lane_1010598_2a_24_1 = (uint64_t)((__uint128_t)tmp_lane_1010598_5_a_1 >> 0U);
tmp_lane_1010598_2e_2b_1 = r2sleigh_float_from_bits_64(tmp_lane_1010598_1e_12_1) + r2sleigh_float_from_bits_64(tmp_lane_1010598_1e_13_1) + r2sleigh_float_from_bits_64(tmp_lane_1010598_1a_d_1) + r2sleigh_float_from_bits_64(tmp_lane_1010598_2a_24_1) + r2sleigh_float_from_bits_64(tmp_lane_1010598_22_18_1);
z0_18 = r2sleigh_bits_insert_256_64(r2sleigh_bits_zero_extend_64_256((uint64_t)0U), (uint64_t)r2sleigh_float_to_bits_64(tmp_lane_1010598_2e_2b_1), 0U);
z0_19 = r2sleigh_bits_insert_256_64(z0_18, (uint64_t)0U, 64U);
z0_20 = r2sleigh_bits_insert_256_64(z0_19, (uint64_t)0U, 128U);
z0_21 = r2sleigh_bits_insert_256_64(z0_20, (uint64_t)0U, 192U);
if ((uint8_t)((uint64_t)tmp_3e280_1 != (uint64_t)0U)) {
x10_2 = (uint64_t)((uint64_t)x10_2 + (uint64_t)32U);
x11_2 = tmp_3e280_1;
z0_5 = z0_21;
} else {
break;
}
}
{
if ((uint8_t)((uint64_t)x9_2 == (uint64_t)x8_1)) {
z0_28 = z0_21;
goto L2;
} else {
x9_3 = x9_2;
z0_22 = z0_21;
}
}
} else {
x9_3 = 0;
z0_22 = z0_4;
}
{
x10_5 = (uint64_t)((uint64_t)v + (uint64_t)((uint64_t)x9_3 * (uint64_t)8U));
x8_3 = (uint64_t)((uint64_t)x8_1 - (uint64_t)x9_3);
z0_23 = z0_22;
for (; ; ) {
tmp_lane_10105d0_2_2f_1 = r2sleigh_load_u64((void*)x10_5);
tmp_3e280_2 = (uint64_t)((uint64_t)x8_3 - (uint64_t)1U);
tmp_lane_10105d0_11_33_1 = r2sleigh_bits_extract_256_64(z0_23, 0U);
tmp_lane_10105d0_11_35_1 = r2sleigh_float_from_bits_64(tmp_lane_10105d0_11_33_1) + r2sleigh_float_from_bits_64(tmp_lane_10105d0_2_2f_1);
z0_24 = r2sleigh_bits_insert_256_64(r2sleigh_bits_zero_extend_64_256((uint64_t)0U), (uint64_t)r2sleigh_float_to_bits_64(tmp_lane_10105d0_11_35_1), 0U);
z0_25 = r2sleigh_bits_insert_256_64(z0_24, (uint64_t)0U, 64U);
z0_26 = r2sleigh_bits_insert_256_64(z0_25, (uint64_t)0U, 128U);
z0_27 = r2sleigh_bits_insert_256_64(z0_26, (uint64_t)0U, 192U);
if ((uint8_t)((uint64_t)tmp_3e280_2 != (uint64_t)0U)) {
x10_5 = (uint64_t)((uint64_t)x10_5 + (uint64_t)8U);
x8_3 = tmp_3e280_2;
z0_23 = z0_27;
} else {
z0_28 = z0_27;
break;
}
}
}
{
L2: ;
return (double)r2sleigh_float_from_bits_64(r2sleigh_bits_extract_256_64(z0_28, 0U));
}
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x010105e4
FILE=tests/fixtures/float_returns_zig_aarch64_O2g
CMDS=aa; pdd @ 0x010105e4
EXPECT=<<EOF
struct r2sleigh_bits_256 {
uint8_t bytes[32];
};
static inline uint64_t r2sleigh_bits_extract_256_64(struct r2sleigh_bits_256 carrier, uint64_t at)
{
uint64_t field = 0;
for (uint32_t bit = 0; bit < 64u; ++bit) {
const uint64_t from = at + bit;
if (from < 256u && ((carrier.bytes[from / 8] >> (from % 8)) & 1) != 0) {
field = (uint64_t)(field | ((uint64_t)1 << bit));
}
}
return field;
}
static inline struct r2sleigh_bits_256 r2sleigh_bits_zero_extend_64_256(uint64_t field)
{
struct r2sleigh_bits_256 carrier = {{0}};
for (uint32_t bit = 0; bit < 64u; ++bit) {
if (((field >> bit) & 1) != 0) {
carrier.bytes[bit / 8] = (uint8_t)(carrier.bytes[bit / 8] | (1u << (bit % 8)));
}
}
return carrier;
}
int32_t main(int32_t argc, char** argv)
{
double loop_sum(const double*, int32_t);
double twice_half(double);
double tmp_lane_10105e4_10_2_1;
struct r2sleigh_bits_256 z0_5;
uint64_t tmp_lane_10105e4_1d_8_1;
struct r2sleigh_bits_256 z0_6;
uint64_t tmp_lane_10105e4_23_e_1;
_Alignas(16) uint8_t frame[48];
/* r2dec proof: 2 constructs are marked below; 32 source obligations: 22 rendered, 6 elided, 0 refused, 4 residual; 8 statements rendered; 2 callee prototypes supplied by the source */
{
r2sleigh_residual_void(1); /* r2dec gap: StoreNotSpelled at 0x10105e4:5 covering 1 op (render::values) */
tmp_lane_10105e4_10_2_1 = (double)(int32_t)argc;
r2sleigh_store_u64((void*)((uint64_t)(frame + 0U) + (uint64_t)8U), (uint64_t)0x4000000000000000U);
r2sleigh_store_u64((void*)(uint64_t)(frame + 0U), (uint64_t)r2sleigh_float_to_bits_64(tmp_lane_10105e4_10_2_1));
z0_5 = r2sleigh_bits_zero_extend_64_256((uint64_t)r2sleigh_float_to_bits_64(twice_half(tmp_lane_10105e4_10_2_1)));
tmp_lane_10105e4_1d_8_1 = r2sleigh_bits_extract_256_64(z0_5, 0U);
z0_6 = r2sleigh_bits_zero_extend_64_256((uint64_t)r2sleigh_float_to_bits_64(loop_sum((const double*)(uint64_t)(frame + 0U), 2)));
tmp_lane_10105e4_23_e_1 = r2sleigh_bits_extract_256_64(z0_6, 0U);
return (int32_t)(r2sleigh_float_from_bits_64(tmp_lane_10105e4_1d_8_1) + r2sleigh_float_from_bits_64(tmp_lane_10105e4_23_e_1) > -2147483649.0 && r2sleigh_float_from_bits_64(tmp_lane_10105e4_1d_8_1) + r2sleigh_float_from_bits_64(tmp_lane_10105e4_23_e_1) < 2147483648.0 ? (int32_t)(r2sleigh_float_from_bits_64(tmp_lane_10105e4_1d_8_1) + r2sleigh_float_from_bits_64(tmp_lane_10105e4_23_e_1)) : r2sleigh_residual_i32(2));
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01010630
FILE=tests/fixtures/float_returns_zig_aarch64_O2g
CMDS=aa; pdd @ 0x01010630
EXPECT=<<EOF
void __libc_csu_init(int32_t argc, char** argv, char** envp)
{
uint64_t x22_2;
uint64_t x23_2;
uint64_t x8_4;
uint64_t tmp_3e280_1;
/* r2dec proof: no individual construct is marked; 45 source obligations: 30 rendered, 15 elided, 0 refused; 12 statements rendered */
{
if ((uint8_t)1U) {
} else {
x22_2 = 0x1000000;
x23_2 = 1;
for (; ; ) {
x8_4 = r2sleigh_load_u64((void*)x22_2);
((uint64_t(*)(uint64_t, uint64_t, uint64_t))(uint64_t)r2sleigh_load_u64((void*)x22_2))((uint64_t)(uint32_t)argc, (uint64_t)argv, (uint64_t)envp);
tmp_3e280_1 = (uint64_t)((uint64_t)x23_2 - (uint64_t)1U);
if ((uint8_t)((uint64_t)tmp_3e280_1 != (uint64_t)0U)) {
x22_2 = (uint64_t)((uint64_t)x22_2 + (uint64_t)8U);
x23_2 = tmp_3e280_1;
} else {
break;
}
}
}
{
return;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x010106a4
FILE=tests/fixtures/float_returns_zig_aarch64_O2g
CMDS=aa; pdd @ 0x010106a4
EXPECT=<<EOF
void __libc_csu_fini(void)
{
/* r2dec proof: no individual construct is marked; 1 source obligations: 1 rendered, 0 elided, 0 refused; 1 statements rendered */
{
return;
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x010106d0
FILE=tests/fixtures/float_returns_zig_aarch64_O2g
CMDS=aa; pdd @ 0x010106d0
EXPECT=<<EOF
/* r2sleigh: import stub at 0x10106d0; this symbol is the import `__libc_start_main` and has no body of its own. */
extern int32_t __libc_start_main(void(*)(), int32_t, char**, void(*)(), void(*)(), void(*)(), void*);
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x010106e0
FILE=tests/fixtures/float_returns_zig_aarch64_O2g
CMDS=aa; pdd @ 0x010106e0
EXPECT=<<EOF
/* r2sleigh: import stub at 0x10106e0; this symbol is the import `abort` and has no body of its own. */
extern void abort(void);
EOF
EXPECT_ERR=<<EOF
EOF
RUN
@@ -0,0 +1,325 @@
# The census of float_returns_zig_x86_64_O2g: what `aa; pdd` renders for each function `afl` lists.
# Regenerate with `scripts/census.py golden` when `afl` moves, then bless.
NAME=afl
FILE=tests/fixtures/float_returns_zig_x86_64_O2g
CMDS=afl
EXPECT=<<EOF
0x010014f0 1 42 sym._start
0x01001520 1 14 sym.half
0x01001530 1 52 sym.twice_half
0x01001570 10 144 sym.loop_sum
0x01001600 1 70 sym.main
0x01001650 4 102 sym.__libc_csu_init
0x010016c0 1 6 sym.__libc_csu_fini
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x010014f0
FILE=tests/fixtures/float_returns_zig_x86_64_O2g
CMDS=aa; pdd @ 0x010014f0
EXPECT=<<EOF
void _start(void)
{
uint64_t tmp_55400_2;
uint64_t tmp_3cb80_1;
/* r2dec proof: 5 constructs are marked below; 27 source obligations: 2 rendered, 3 elided, 0 refused, 22 residual; 2 statements rendered; 1 held from entry, read as residuals (stack_p0) */
{
tmp_55400_2 = r2sleigh_residual_u64(1);
r2sleigh_residual_void(2); /* r2dec gap: StoreNotSpelled at 0x10014f0:29 covering 1 op (render::values) */
r2sleigh_residual_void(3); /* r2dec gap: StoreNotSpelled at 0x10014f0:32 covering 1 op (render::values) */
tmp_3cb80_1 = r2sleigh_load_u64((void*)(uint64_t)0x10027d8U);
r2sleigh_residual_void(4); /* r2dec gap: CallNotRendered at 0x10014f0:46 covering 1 op (render::values) */
r2sleigh_residual_void(5); /* r2dec gap: TailTransferNotRendered at 0x10014f0 (render::control) */
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01001520
FILE=tests/fixtures/float_returns_zig_x86_64_O2g
CMDS=aa; pdd @ 0x01001520
EXPECT=<<EOF
double half(double x)
{
/* r2dec proof: no individual construct is marked; 9 source obligations: 3 rendered, 6 elided, 0 refused; 1 statements rendered */
{
return (double)(x * r2sleigh_float_from_bits_64((uint64_t)0x3fe0000000000000U));
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01001530
FILE=tests/fixtures/float_returns_zig_x86_64_O2g
CMDS=aa; pdd @ 0x01001530
EXPECT=<<EOF
double twice_half(double x)
{
double half(double);
__uint128_t xmm0_1;
uint64_t tmp_lane_1001530_14_1_1;
__uint128_t xmm0_5;
uint64_t tmp_lane_1001530_21_6_1;
/* r2dec proof: no individual construct is marked; 28 source obligations: 14 rendered, 14 elided, 0 refused; 5 statements rendered; 2 callee prototypes supplied by the source */
{
xmm0_1 = (__uint128_t)r2sleigh_float_to_bits_64(half(x));
tmp_lane_1001530_14_1_1 = (uint64_t)((__uint128_t)xmm0_1 >> 0U);
xmm0_5 = (__uint128_t)r2sleigh_float_to_bits_64(half(x + r2sleigh_float_from_bits_64((uint64_t)0x3ff0000000000000U)));
tmp_lane_1001530_21_6_1 = (uint64_t)((__uint128_t)xmm0_5 >> 0U);
return (double)(r2sleigh_float_from_bits_64(tmp_lane_1001530_21_6_1) + r2sleigh_float_from_bits_64(tmp_lane_1001530_14_1_1));
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01001570
FILE=tests/fixtures/float_returns_zig_x86_64_O2g
CMDS=aa; pdd @ 0x01001570
EXPECT=<<EOF
double loop_sum(const double* v, int32_t n)
{
uint32_t tmp_70400_1;
uint64_t rax_2;
__uint128_t xmm0_1;
uint64_t rdx_2;
__uint128_t xmm0_3;
uint64_t rcx_3;
__uint128_t xmm0_5;
uint64_t tmp_6b00_1;
uint64_t tmp_lane_10015a0_3_1a_1;
double tmp_lane_10015a0_3_1b_1;
__uint128_t xmm0_6;
uint64_t tmp_6b00_2;
double tmp_lane_10015a0_8_1d_1;
__uint128_t xmm0_7;
uint64_t tmp_6b00_3;
double tmp_lane_10015a0_d_1f_1;
__uint128_t xmm0_8;
uint64_t tmp_6b00_4;
double tmp_lane_10015a0_12_21_1;
__uint128_t xmm0_9;
uint64_t tmp_6b00_5;
double tmp_lane_10015a0_17_23_1;
__uint128_t xmm0_10;
uint64_t tmp_6b00_6;
double tmp_lane_10015a0_1c_25_1;
__uint128_t xmm0_11;
uint64_t tmp_6b00_7;
double tmp_lane_10015a0_21_27_1;
__uint128_t xmm0_12;
uint64_t tmp_6b00_8;
double tmp_lane_10015a0_26_29_1;
__uint128_t xmm0_13;
uint64_t rcx_4;
uint64_t rcx_5;
__uint128_t xmm0_14;
uint64_t tmp_4a00_2;
uint64_t rdx_5;
__uint128_t xmm0_15;
uint64_t tmp_6b00_9;
uint64_t tmp_lane_10015f0_3_2d_1;
double tmp_lane_10015f0_3_2e_1;
__uint128_t xmm0_16;
uint64_t rdx_6;
__uint128_t xmm0_17;
__uint128_t xmm0_18;
/* r2dec proof: no individual construct is marked; 138 source obligations: 126 rendered, 12 elided, 0 refused; 65 statements rendered */
{
tmp_70400_1 = (uint32_t)n;
if ((uint8_t)((int32_t)tmp_70400_1 <= (int32_t)0U)) {
xmm0_18 = (__uint128_t)(((__uint128_t)0U & (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0xffffffff00000000U)) | ((__uint128_t)(uint32_t)0U & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffU)) << 0U);
return (double)r2sleigh_float_from_bits_64((uint64_t)(((__uint128_t)xmm0_18 & (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0xffffffffU)) | ((__uint128_t)(uint32_t)0U & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffU)) << 32U));
} else {
rax_2 = (uint64_t)(uint32_t)((uint32_t)n & (uint32_t)7U);
if ((uint8_t)((uint32_t)8U <= (uint32_t)n)) {
rdx_2 = (uint64_t)(uint32_t)((uint32_t)n & (uint32_t)0x7ffffff8U);
xmm0_3 = (__uint128_t)(((__uint128_t)0U & (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0U)) | ((__uint128_t)(uint64_t)0U & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) << 0U);
rcx_3 = 0;
xmm0_5 = (__uint128_t)(((__uint128_t)xmm0_3 & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) | ((__uint128_t)(uint64_t)0U & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) << 64U);
for (; ; ) {
tmp_6b00_1 = r2sleigh_load_u64((void*)((uint64_t)v + (uint64_t)rcx_3 * 8U));
tmp_lane_10015a0_3_1a_1 = (uint64_t)((__uint128_t)xmm0_5 >> 0U);
tmp_lane_10015a0_3_1b_1 = r2sleigh_float_from_bits_64(tmp_lane_10015a0_3_1a_1) + r2sleigh_float_from_bits_64(tmp_6b00_1);
xmm0_6 = (__uint128_t)(((__uint128_t)xmm0_5 & (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0U)) | ((__uint128_t)r2sleigh_float_to_bits_64(tmp_lane_10015a0_3_1b_1) & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) << 0U);
tmp_6b00_2 = r2sleigh_load_u64((void*)((uint64_t)v + (uint64_t)((uint64_t)rcx_3 + (uint64_t)1U) * 8U));
tmp_lane_10015a0_8_1d_1 = tmp_lane_10015a0_3_1b_1 + r2sleigh_float_from_bits_64(tmp_6b00_2);
xmm0_7 = (__uint128_t)(((__uint128_t)xmm0_6 & (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0U)) | ((__uint128_t)r2sleigh_float_to_bits_64(tmp_lane_10015a0_8_1d_1) & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) << 0U);
tmp_6b00_3 = r2sleigh_load_u64((void*)((uint64_t)v + (uint64_t)((uint64_t)rcx_3 + (uint64_t)2U) * 8U));
tmp_lane_10015a0_d_1f_1 = tmp_lane_10015a0_8_1d_1 + r2sleigh_float_from_bits_64(tmp_6b00_3);
xmm0_8 = (__uint128_t)(((__uint128_t)xmm0_7 & (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0U)) | ((__uint128_t)r2sleigh_float_to_bits_64(tmp_lane_10015a0_d_1f_1) & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) << 0U);
tmp_6b00_4 = r2sleigh_load_u64((void*)((uint64_t)v + (uint64_t)((uint64_t)rcx_3 + (uint64_t)3U) * 8U));
tmp_lane_10015a0_12_21_1 = tmp_lane_10015a0_d_1f_1 + r2sleigh_float_from_bits_64(tmp_6b00_4);
xmm0_9 = (__uint128_t)(((__uint128_t)xmm0_8 & (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0U)) | ((__uint128_t)r2sleigh_float_to_bits_64(tmp_lane_10015a0_12_21_1) & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) << 0U);
tmp_6b00_5 = r2sleigh_load_u64((void*)((uint64_t)v + (uint64_t)((uint64_t)rcx_3 + (uint64_t)4U) * 8U));
tmp_lane_10015a0_17_23_1 = tmp_lane_10015a0_12_21_1 + r2sleigh_float_from_bits_64(tmp_6b00_5);
xmm0_10 = (__uint128_t)(((__uint128_t)xmm0_9 & (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0U)) | ((__uint128_t)r2sleigh_float_to_bits_64(tmp_lane_10015a0_17_23_1) & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) << 0U);
tmp_6b00_6 = r2sleigh_load_u64((void*)((uint64_t)v + (uint64_t)((uint64_t)rcx_3 + (uint64_t)5U) * 8U));
tmp_lane_10015a0_1c_25_1 = tmp_lane_10015a0_17_23_1 + r2sleigh_float_from_bits_64(tmp_6b00_6);
xmm0_11 = (__uint128_t)(((__uint128_t)xmm0_10 & (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0U)) | ((__uint128_t)r2sleigh_float_to_bits_64(tmp_lane_10015a0_1c_25_1) & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) << 0U);
tmp_6b00_7 = r2sleigh_load_u64((void*)((uint64_t)v + (uint64_t)((uint64_t)rcx_3 + (uint64_t)6U) * 8U));
tmp_lane_10015a0_21_27_1 = tmp_lane_10015a0_1c_25_1 + r2sleigh_float_from_bits_64(tmp_6b00_7);
xmm0_12 = (__uint128_t)(((__uint128_t)xmm0_11 & (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0U)) | ((__uint128_t)r2sleigh_float_to_bits_64(tmp_lane_10015a0_21_27_1) & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) << 0U);
tmp_6b00_8 = r2sleigh_load_u64((void*)((uint64_t)v + (uint64_t)((uint64_t)rcx_3 + (uint64_t)7U) * 8U));
tmp_lane_10015a0_26_29_1 = tmp_lane_10015a0_21_27_1 + r2sleigh_float_from_bits_64(tmp_6b00_8);
xmm0_13 = (__uint128_t)(((__uint128_t)xmm0_12 & (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0U)) | ((__uint128_t)r2sleigh_float_to_bits_64(tmp_lane_10015a0_26_29_1) & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) << 0U);
rcx_4 = (uint64_t)((uint64_t)rcx_3 + (uint64_t)8U);
if ((uint8_t)((uint64_t)rdx_2 != (uint64_t)rcx_4)) {
rcx_3 = rcx_4;
xmm0_5 = xmm0_13;
} else {
break;
}
}
{
if ((uint8_t)((uint64_t)rax_2 == (uint64_t)0U)) {
xmm0_17 = xmm0_13;
goto L2;
} else {
rcx_5 = rcx_4;
xmm0_14 = xmm0_13;
}
}
} else {
xmm0_1 = (__uint128_t)(((__uint128_t)0U & (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0U)) | ((__uint128_t)(uint64_t)0U & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) << 0U);
rcx_5 = 0;
xmm0_14 = (__uint128_t)(((__uint128_t)xmm0_1 & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) | ((__uint128_t)(uint64_t)0U & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) << 64U);
}
{
tmp_4a00_2 = (uint64_t)((uint64_t)((uint64_t)rcx_5 * (uint64_t)8U) + (uint64_t)v);
rdx_5 = 0;
xmm0_15 = xmm0_14;
for (; ; ) {
tmp_6b00_9 = r2sleigh_load_u64((void*)(uint64_t)((uint64_t)((uint64_t)rdx_5 * (uint64_t)8U) + (uint64_t)tmp_4a00_2));
tmp_lane_10015f0_3_2d_1 = (uint64_t)((__uint128_t)xmm0_15 >> 0U);
tmp_lane_10015f0_3_2e_1 = r2sleigh_float_from_bits_64(tmp_lane_10015f0_3_2d_1) + r2sleigh_float_from_bits_64(tmp_6b00_9);
xmm0_16 = (__uint128_t)(((__uint128_t)xmm0_15 & (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0U)) | ((__uint128_t)r2sleigh_float_to_bits_64(tmp_lane_10015f0_3_2e_1) & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) << 0U);
rdx_6 = (uint64_t)((uint64_t)rdx_5 + (uint64_t)1U);
if ((uint8_t)((uint64_t)rax_2 != (uint64_t)rdx_6)) {
rdx_5 = rdx_6;
xmm0_15 = xmm0_16;
} else {
xmm0_17 = xmm0_16;
break;
}
}
}
{
L2: ;
return (double)r2sleigh_float_from_bits_64((uint64_t)xmm0_17);
}
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01001600
FILE=tests/fixtures/float_returns_zig_x86_64_O2g
CMDS=aa; pdd @ 0x01001600
EXPECT=<<EOF
int32_t main(int32_t argc, char** argv)
{
double loop_sum(const double*, int32_t);
double twice_half(double);
double tmp_lane_1001600_d_1_1;
__uint128_t xmm0_2;
__uint128_t xmm0_3;
uint64_t tmp_6b00_4;
uint64_t tmp_lane_1001600_23_4_1;
_Alignas(16) uint8_t frame[56];
/* r2dec proof: 1 construct is marked below; 42 source obligations: 23 rendered, 15 elided, 0 refused, 2 assumed (frame extent unproven), 2 residual; 9 statements rendered; 2 callee prototypes supplied by the source */
{
tmp_lane_1001600_d_1_1 = (double)(int32_t)argc;
r2sleigh_store_u64((void*)(uint64_t)(frame + 16U), (uint64_t)r2sleigh_float_to_bits_64(tmp_lane_1001600_d_1_1));
r2sleigh_store_u64((void*)((uint64_t)(frame + 16U) + (uint64_t)8U), (uint64_t)0x4000000000000000U);
xmm0_2 = (__uint128_t)r2sleigh_float_to_bits_64(twice_half(tmp_lane_1001600_d_1_1));
r2sleigh_store_u64((void*)(uint64_t)(frame + 40U), (uint64_t)((__uint128_t)xmm0_2 >> 0U));
xmm0_3 = (__uint128_t)r2sleigh_float_to_bits_64(loop_sum((const double*)(uint64_t)(frame + 16U), 2));
tmp_6b00_4 = r2sleigh_load_u64((void*)(uint64_t)(frame + 40U));
tmp_lane_1001600_23_4_1 = (uint64_t)((__uint128_t)xmm0_3 >> 0U);
return (int32_t)(r2sleigh_float_from_bits_64(tmp_lane_1001600_23_4_1) + r2sleigh_float_from_bits_64(tmp_6b00_4) > -2147483649.0 && r2sleigh_float_from_bits_64(tmp_lane_1001600_23_4_1) + r2sleigh_float_from_bits_64(tmp_6b00_4) < 2147483648.0 ? (int32_t)(r2sleigh_float_from_bits_64(tmp_lane_1001600_23_4_1) + r2sleigh_float_from_bits_64(tmp_6b00_4)) : r2sleigh_residual_i32(1));
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x01001650
FILE=tests/fixtures/float_returns_zig_x86_64_O2g
CMDS=aa; pdd @ 0x01001650
EXPECT=<<EOF
void __libc_csu_init(int32_t argc, char** argv, char** envp)
{
uint64_t r12_2;
uint64_t r13_5;
uint64_t tmp_11f80_1;
uint64_t r13_6;
/* r2dec proof: no individual construct is marked; 61 source obligations: 31 rendered, 30 elided, 0 refused; 12 statements rendered */
{
if ((uint8_t)1U) {
} else {
r12_2 = 0x1000000;
r13_5 = 1;
for (; ; ) {
tmp_11f80_1 = r2sleigh_load_u64((void*)r12_2);
((uint64_t(*)(uint64_t, uint64_t, uint64_t))(uint64_t)tmp_11f80_1)((uint64_t)(uint32_t)argc, (uint64_t)argv, (uint64_t)envp);
r13_6 = (uint64_t)((uint64_t)r13_5 - (uint64_t)1U);
if ((uint8_t)((uint64_t)r13_6 != (uint64_t)0U)) {
r12_2 = (uint64_t)((uint64_t)r12_2 + (uint64_t)8U);
r13_5 = r13_6;
} else {
break;
}
}
}
{
return;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x010016c0
FILE=tests/fixtures/float_returns_zig_x86_64_O2g
CMDS=aa; pdd @ 0x010016c0
EXPECT=<<EOF
void __libc_csu_fini(void)
{
/* r2dec proof: no individual construct is marked; 7 source obligations: 1 rendered, 6 elided, 0 refused; 1 statements rendered */
{
return;
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
@@ -0,0 +1,294 @@
# The census of frame_pointer_locals_clang_O0g: what `aa; pdd` renders for each function `afl` lists.
# Regenerate with `scripts/census.py golden` when `afl` moves, then bless.
NAME=afl
FILE=tests/fixtures/frame_pointer_locals_clang_O0g
CMDS=afl
EXPECT=<<EOF
0x00001000 3 27 sym._init
0x00001030 1 6 sym.imp.__cxa_finalize
0x00001040 1 37 sym._start
0x00001070 4 34 sym.deregister_tm_clones
0x000010a0 4 51 sym.register_tm_clones
0x000010e0 5 54 sym.__do_global_dtors_aux
0x00001120 1 9 sym.frame_dummy
0x00001130 4 70 sym.counter
0x00001180 1 26 sym.main
0x0000119c 1 13 sym._fini
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001000
FILE=tests/fixtures/frame_pointer_locals_clang_O0g
CMDS=aa; pdd @ 0x00001000
EXPECT=<<EOF
uint64_t _init(void)
{
uint64_t rax_1;
uint64_t rax_2;
uint64_t rax_3;
/* r2dec proof: no individual construct is marked; 22 source obligations: 12 rendered, 10 elided, 0 refused; 6 statements rendered */
{
rax_1 = r2sleigh_load_u64((void*)(uint64_t)0x3fd0U);
if ((uint8_t)((uint64_t)rax_1 == (uint64_t)0U)) {
rax_3 = rax_1;
} else {
rax_2 = ((uint64_t(*)(void))(uint64_t)rax_1)();
rax_3 = rax_2;
}
{
return (uint64_t)rax_3;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001030
FILE=tests/fixtures/frame_pointer_locals_clang_O0g
CMDS=aa; pdd @ 0x00001030
EXPECT=<<EOF
/* r2dec refused __cxa_finalize: r2sleigh: import stub at 0x1030; this symbol is the import `__cxa_finalize`, whose prototype nothing states. */
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001040
FILE=tests/fixtures/frame_pointer_locals_clang_O0g
CMDS=aa; pdd @ 0x00001040
EXPECT=<<EOF
void _start(void)
{
uint64_t tmp_55400_2;
uint64_t tmp_3cb80_1;
/* r2dec proof: 5 constructs are marked below; 28 source obligations: 2 rendered, 4 elided, 0 refused, 22 residual; 2 statements rendered; 1 held from entry, read as residuals (stack_p0) */
{
tmp_55400_2 = r2sleigh_residual_u64(1);
r2sleigh_residual_void(2); /* r2dec gap: StoreNotSpelled at 0x1040:29 covering 1 op (render::values) */
r2sleigh_residual_void(3); /* r2dec gap: StoreNotSpelled at 0x1040:32 covering 1 op (render::values) */
tmp_3cb80_1 = r2sleigh_load_u64((void*)(uint64_t)0x3fc0U);
r2sleigh_residual_void(4); /* r2dec gap: CallNotRendered at 0x1040:68 covering 1 op (render::values) */
r2sleigh_residual_void(5); /* r2dec gap: TailTransferNotRendered at 0x1040 (render::control) */
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001070
FILE=tests/fixtures/frame_pointer_locals_clang_O0g
CMDS=aa; pdd @ 0x00001070
EXPECT=<<EOF
uint64_t deregister_tm_clones(void)
{
uint64_t rax_2;
uint64_t rax_3;
/* r2dec proof: 1 construct is marked below; 17 source obligations: 13 rendered, 3 elided, 0 refused, 1 residual; 6 statements rendered */
{
if ((uint8_t)1U) {
rax_3 = 0x4010;
} else {
rax_2 = r2sleigh_load_u64((void*)(uint64_t)0x3fc8U);
if ((uint8_t)((uint64_t)rax_2 == (uint64_t)0U)) {
rax_3 = rax_2;
} else {
r2sleigh_residual_void(1); /* r2dec gap: UnresolvedIndirectBranch at 0x108f (render::control) */
}
}
{
return (uint64_t)rax_3;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000010a0
FILE=tests/fixtures/frame_pointer_locals_clang_O0g
CMDS=aa; pdd @ 0x000010a0
EXPECT=<<EOF
uint64_t register_tm_clones(void)
{
uint64_t rax_3;
uint64_t rax_4;
/* r2dec proof: 1 construct is marked below; 23 source obligations: 19 rendered, 3 elided, 0 refused, 1 residual; 6 statements rendered */
{
if ((uint8_t)1U) {
rax_4 = 0;
} else {
rax_3 = r2sleigh_load_u64((void*)(uint64_t)0x3fd8U);
if ((uint8_t)((uint64_t)rax_3 == (uint64_t)0U)) {
rax_4 = rax_3;
} else {
r2sleigh_residual_void(1); /* r2dec gap: UnresolvedIndirectBranch at 0x10d0 (render::control) */
}
}
{
return (uint64_t)rax_4;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000010e0
FILE=tests/fixtures/frame_pointer_locals_clang_O0g
CMDS=aa; pdd @ 0x000010e0
EXPECT=<<EOF
uint64_t __do_global_dtors_aux(void)
{
void __cxa_finalize(uint64_t);
uint64_t deregister_tm_clones(void);
extern char __dso_handle[];
extern char __TMC_END__[];
uint8_t tmp_3e180_1;
uint64_t tmp_3ea80_1;
uint64_t rdi_1;
/* r2dec proof: 2 constructs are marked below; 39 source obligations: 19 rendered, 16 elided, 0 refused, 4 residual; 10 statements rendered; 2 data object types refused */
{
tmp_3e180_1 = r2sleigh_load_u8((void*)&__TMC_END__);
if ((uint8_t)((uint8_t)tmp_3e180_1 != (uint8_t)0U)) {
return r2sleigh_residual_u64(1);
} else {
tmp_3ea80_1 = r2sleigh_load_u64((void*)(uint64_t)0x3fe0U);
if ((uint8_t)((uint64_t)tmp_3ea80_1 == (uint64_t)0U)) {
} else {
rdi_1 = r2sleigh_load_u64((void*)&__dso_handle);
__cxa_finalize(rdi_1);
}
{
deregister_tm_clones();
r2sleigh_store_u8((void*)&__TMC_END__, (uint8_t)1U);
return r2sleigh_residual_u64(2);
}
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001120
FILE=tests/fixtures/frame_pointer_locals_clang_O0g
CMDS=aa; pdd @ 0x00001120
EXPECT=<<EOF
uint64_t frame_dummy(void)
{
uint64_t register_tm_clones(void);
/* r2dec proof: no individual construct is marked; 3 source obligations: 2 rendered, 1 elided, 0 refused; 1 statements rendered */
{
return register_tm_clones();
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001130
FILE=tests/fixtures/frame_pointer_locals_clang_O0g
CMDS=aa; pdd @ 0x00001130
EXPECT=<<EOF
int32_t counter(void)
{
uint32_t tmp_11f00_1;
uint32_t tmp_6a80_3;
uint32_t tmp_11f00_2;
uint64_t tmp_11f80_3;
uint32_t tmp_11f00_3;
uint64_t tmp_11f80_4;
_Alignas(16) uint8_t frame[40];
/* r2dec proof: no individual construct is marked; 44 source obligations: 27 rendered, 17 elided, 0 refused; 15 statements rendered */
{
r2sleigh_store_u32((void*)(uint64_t)(frame + 28U), (uint32_t)3U);
r2sleigh_store_u64((void*)(uint64_t)(frame + 16U), (uint64_t)10U);
r2sleigh_store_u32((void*)(uint64_t)(frame + 12U), (uint32_t)0U);
for (; ; ) {
tmp_11f00_1 = r2sleigh_load_u32((void*)(uint64_t)(frame + 12U));
tmp_6a80_3 = r2sleigh_load_u32((void*)(uint64_t)(frame + 28U));
if ((uint8_t)((int32_t)tmp_6a80_3 <= (int32_t)tmp_11f00_1)) {
break;
} else {
tmp_11f00_2 = r2sleigh_load_u32((void*)(uint64_t)(frame + 12U));
tmp_11f80_3 = r2sleigh_load_u64((void*)(uint64_t)(frame + 16U));
r2sleigh_store_u64((void*)(uint64_t)(frame + 16U), (uint64_t)((uint64_t)(int32_t)tmp_11f00_2 + (uint64_t)tmp_11f80_3));
tmp_11f00_3 = r2sleigh_load_u32((void*)(uint64_t)(frame + 12U));
r2sleigh_store_u32((void*)(uint64_t)(frame + 12U), (uint32_t)((uint32_t)tmp_11f00_3 + (uint32_t)1U));
}
}
{
tmp_11f80_4 = r2sleigh_load_u64((void*)(uint64_t)(frame + 16U));
return (int32_t)tmp_11f80_4;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001180
FILE=tests/fixtures/frame_pointer_locals_clang_O0g
CMDS=aa; pdd @ 0x00001180
EXPECT=<<EOF
int32_t main(void)
{
int32_t counter(void);
uint64_t rax_1;
/* r2dec proof: no individual construct is marked; 16 source obligations: 5 rendered, 11 elided, 0 refused; 2 statements rendered; 1 callee prototype supplied by the source */
{
rax_1 = (uint64_t)(uint32_t)counter();
return (int32_t)rax_1;
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x0000119c
FILE=tests/fixtures/frame_pointer_locals_clang_O0g
CMDS=aa; pdd @ 0x0000119c
EXPECT=<<EOF
void _fini(void)
{
/* r2dec proof: no individual construct is marked; 7 source obligations: 1 rendered, 6 elided, 0 refused; 1 statements rendered */
{
return;
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+901
View File
@@ -0,0 +1,901 @@
# The census of manual_limits_O0: what `aa; pdd` renders for each function `afl` lists.
# Regenerate with `scripts/census.py golden` when `afl` moves, then bless.
NAME=afl
FILE=tests/fixtures/manual_limits_O0
CMDS=afl
EXPECT=<<EOF
0x100000548 5 144 sym._struct_nested_array
0x1000005d8 15 388 sym._out_param_parse
0x10000075c 11 200 sym._fnv_fold
0x100000824 21 284 sym._sparse_switch
0x100000940 26 352 sym._table_walk
0x100000aa0 64 684 sym._state_machine
0x100000d4c 11 160 sym._mem_scan2
0x100000dec 13 492 sym._main
0x100000fd8 1 12 sym.imp.memcpy
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x100000548
FILE=tests/fixtures/manual_limits_O0
CMDS=aa; pdd @ 0x100000548
EXPECT=<<EOF
uint32_t _struct_nested_array(void* arg0, uint32_t arg1, uint32_t arg2)
{
uint64_t tmp_12480_1;
uint32_t tmp_24c00_2;
uint16_t tmp_25700_1;
uint32_t tmp_24c00_3;
uint32_t tmp_24c00_4;
uint32_t tmp_24c00_5;
uint16_t tmp_25700_2;
uint32_t stack_m4_1;
/* r2dec proof: no individual construct is marked; 47 source obligations: 44 rendered, 3 elided, 0 refused; 12 statements rendered */
{
tmp_12480_1 = (uint64_t)((uint64_t)((uint64_t)(int32_t)arg1 * (uint64_t)40U) + (uint64_t)arg0);
tmp_24c00_2 = r2sleigh_load_u32((void*)((uint64_t)tmp_12480_1 + (uint64_t)4U * 4U));
r2sleigh_store_u32((void*)((uint64_t)tmp_12480_1 + (uint64_t)4U * 4U), (uint32_t)((uint32_t)tmp_24c00_2 + (uint32_t)arg2));
tmp_25700_1 = r2sleigh_load_u16((void*)((uint64_t)tmp_12480_1 + (uint64_t)2U * 2U));
if ((uint8_t)((uint32_t)((uint32_t)((uint32_t)2U >= (uint32_t)32U ? (uint32_t)0U : (uint32_t)((uint32_t)((uint64_t)(uint16_t)tmp_25700_1 >> 0U) >> (uint32_t)2U)) & (uint32_t)1U) == (uint32_t)0U)) {
tmp_24c00_5 = r2sleigh_load_u32((void*)((uint64_t)tmp_12480_1 + (uint64_t)2U * 4U));
tmp_25700_2 = r2sleigh_load_u16((void*)((uint64_t)tmp_12480_1 + (uint64_t)3U * 2U));
stack_m4_1 = (uint32_t)((uint32_t)tmp_24c00_5 - (uint32_t)((uint64_t)(uint16_t)tmp_25700_2 >> 0U));
} else {
{
tmp_24c00_3 = r2sleigh_load_u32((void*)((uint64_t)tmp_12480_1 + (uint64_t)4U * 4U));
tmp_24c00_4 = r2sleigh_load_u32((void*)tmp_12480_1);
stack_m4_1 = (uint32_t)((uint32_t)tmp_24c00_3 + (uint32_t)tmp_24c00_4);
}
}
{
return (uint32_t)stack_m4_1;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x1000005d8
FILE=tests/fixtures/manual_limits_O0
CMDS=aa; pdd @ 0x1000005d8
EXPECT=<<EOF
struct fcn_1000005d8_arg1 {
uint32_t f_0;
uint8_t _pad_4[4];
uint64_t f_8;
uint64_t f_10;
uint64_t f_18;
};
uint32_t _out_param_parse(uint8_t* arg0, struct fcn_1000005d8_arg1* arg1)
{
uint8_t tmp_25a00_1;
uint64_t stack_m40_1;
uint32_t stack_m20_1;
uint64_t stack_m48_1;
uint64_t stack_m40_2;
uint64_t stack_m32_1;
uint8_t tmp_26000_1;
uint8_t tmp_26000_2;
uint32_t stack_m52_1;
uint8_t tmp_26000_3;
uint64_t stack_m32_3;
uint8_t tmp_25600_1;
uint64_t stack_m48_4;
uint8_t tmp_26000_4;
uint32_t stack_m56_1;
/* r2dec proof: no individual construct is marked; 121 source obligations: 118 rendered, 3 elided, 0 refused; 33 statements rendered; 1 structure laid out from a parameter's accesses */
{
tmp_25a00_1 = r2sleigh_load_u8((void*)(uint64_t)arg0);
if ((uint8_t)((uint32_t)((uint64_t)(int8_t)tmp_25a00_1 >> 0U) != (uint32_t)45U)) {
stack_m40_1 = 0;
stack_m20_1 = 1;
} else {
{
stack_m40_1 = 1;
stack_m20_1 = (uint32_t)0xffffffffU;
}
}
{
stack_m48_1 = (uint64_t)0x14650fb0739d0383U;
stack_m40_2 = stack_m40_1;
stack_m32_1 = 0;
for (; ; ) {
tmp_26000_1 = r2sleigh_load_u8((void*)((uint64_t)arg0 + (uint64_t)stack_m40_2 * 1U));
if ((uint8_t)((int32_t)((uint64_t)(int8_t)tmp_26000_1 >> 0U) < (int32_t)48U)) {
stack_m52_1 = 0;
} else {
{
tmp_26000_2 = r2sleigh_load_u8((void*)((uint64_t)arg0 + (uint64_t)stack_m40_2 * 1U));
stack_m52_1 = (uint32_t)((uint64_t)(uint8_t)((int32_t)((uint64_t)(int8_t)tmp_26000_2 >> 0U) <= (int32_t)57U) >> 0U);
}
}
{
if ((uint8_t)((uint32_t)((uint32_t)stack_m52_1 & (uint32_t)1U) == (uint32_t)0U)) {
break;
} else {
{
tmp_26000_3 = r2sleigh_load_u8((void*)((uint64_t)arg0 + (uint64_t)stack_m40_2 * 1U));
stack_m32_3 = (uint64_t)((uint64_t)((uint64_t)stack_m32_1 * (uint64_t)10U) + (uint64_t)(int32_t)((uint32_t)((uint64_t)(int8_t)tmp_26000_3 >> 0U) - (uint32_t)48U));
tmp_25600_1 = r2sleigh_load_u8((void*)((uint64_t)arg0 + (uint64_t)stack_m40_2 * 1U));
stack_m48_4 = (uint64_t)((uint64_t)((uint64_t)(uint8_t)tmp_25600_1 ^ (uint64_t)stack_m48_1) * (uint64_t)0x100000001b3U);
{
stack_m48_1 = stack_m48_4;
stack_m40_2 = (uint64_t)((uint64_t)stack_m40_2 + (uint64_t)1U);
stack_m32_1 = stack_m32_3;
}
}
}
}
}
{
r2sleigh_store_u32((void*)&arg1->f_0, (uint32_t)((uint64_t)((uint64_t)(int32_t)stack_m20_1 * (uint64_t)stack_m32_1) >> 0U));
r2sleigh_store_u64((void*)&arg1->f_8, (uint64_t)stack_m48_1);
r2sleigh_store_u64((void*)&arg1->f_18, (uint64_t)stack_m40_2);
r2sleigh_store_u64((void*)&arg1->f_10, (uint64_t)0U);
if ((uint8_t)((uint64_t)stack_m40_2 <= (uint64_t)0U)) {
stack_m56_1 = 0;
} else {
{
tmp_26000_4 = r2sleigh_load_u8((void*)((uint64_t)arg0 + (uint64_t)stack_m40_2 * 1U));
stack_m56_1 = (uint32_t)((uint64_t)(uint8_t)((uint32_t)((uint64_t)(int8_t)tmp_26000_4 >> 0U) == (uint32_t)0U) >> 0U);
}
}
{
return (uint32_t)((uint32_t)stack_m56_1 & (uint32_t)1U);
}
}
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x10000075c
FILE=tests/fixtures/manual_limits_O0
CMDS=aa; pdd @ 0x10000075c
EXPECT=<<EOF
uint64_t _fnv_fold(uint8_t* arg0, uint64_t arg1)
{
uint64_t stack_m32_1;
uint64_t stack_m24_1;
uint8_t tmp_25500_1;
uint8_t stack_m33_2;
uint8_t stack_m33_1;
uint64_t stack_m24_4;
/* r2dec proof: no individual construct is marked; 63 source obligations: 60 rendered, 3 elided, 0 refused; 16 statements rendered */
{
stack_m32_1 = 0;
stack_m24_1 = (uint64_t)0x14650fb0739d0383U;
for (; ; ) {
if ((uint8_t)((uint64_t)arg1 <= (uint64_t)stack_m32_1)) {
break;
} else {
{
tmp_25500_1 = r2sleigh_load_u8((void*)((uint64_t)arg0 + (uint64_t)stack_m32_1 * 1U));
stack_m33_2 = tmp_25500_1;
if ((uint8_t)((int32_t)((uint64_t)(uint8_t)stack_m33_2 >> 0U) < (int32_t)65U)) {
stack_m33_1 = stack_m33_2;
} else {
{
if ((uint8_t)((int32_t)90U < (int32_t)((uint64_t)(uint8_t)stack_m33_2 >> 0U))) {
stack_m33_1 = stack_m33_2;
} else {
{
stack_m33_1 = (uint8_t)((uint32_t)((uint32_t)((uint64_t)(uint8_t)stack_m33_2 >> 0U) + (uint32_t)32U) >> 0U);
}
}
}
}
{
stack_m24_4 = (uint64_t)((uint64_t)((uint64_t)(uint8_t)stack_m33_1 ^ (uint64_t)stack_m24_1) * (uint64_t)0x100000001b3U);
{
stack_m32_1 = (uint64_t)((uint64_t)stack_m32_1 + (uint64_t)1U);
stack_m24_1 = stack_m24_4;
}
}
}
}
}
{
return (uint64_t)stack_m24_1;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x100000824
FILE=tests/fixtures/manual_limits_O0
CMDS=aa; pdd @ 0x100000824
EXPECT=<<EOF
uint32_t _sparse_switch(uint32_t arg0, uint32_t arg1, uint32_t arg2)
{
uint32_t tmp_36488_1;
uint32_t stack_m24_1;
uint32_t stack_m4_1;
/* r2dec proof: 1 construct is marked below; 63 source obligations: 58 rendered, 3 elided, 0 refused, 2 residual; 16 statements rendered */
{
if ((uint8_t)((uint32_t)((uint32_t)arg0 + (uint32_t)7U) == (uint32_t)0U)) {
stack_m4_1 = (uint32_t)((uint32_t)arg1 - (uint32_t)arg2);
} else {
{
if ((uint8_t)((uint32_t)arg0 == (uint32_t)0U)) {
stack_m4_1 = (uint32_t)((uint32_t)arg1 + (uint32_t)arg2);
} else {
{
if ((uint8_t)((uint32_t)arg0 == (uint32_t)3U)) {
stack_m4_1 = (uint32_t)((uint32_t)((uint32_t)arg1 * (uint32_t)3U) + (uint32_t)arg2);
} else {
{
if ((uint8_t)((uint32_t)arg0 == (uint32_t)42U)) {
stack_m4_1 = (uint32_t)((uint32_t)((uint32_t)arg1 ^ (uint32_t)arg2) + (uint32_t)42U);
} else {
{
if ((uint8_t)((uint32_t)arg0 == (uint32_t)0x3e8U)) {
if ((uint8_t)((uint32_t)arg2 != (uint32_t)0U)) {
tmp_36488_1 = (uint32_t)arg1 == (uint32_t)0x80000000U && (uint32_t)arg2 == (uint32_t)0xffffffffU ? r2sleigh_residual_u32(1) : (uint32_t)((int32_t)arg1 / (int32_t)arg2);
stack_m24_1 = (uint8_t)((uint32_t)arg2 == (uint32_t)0U) ? (uint32_t)0U : (uint32_t)tmp_36488_1;
} else {
{
stack_m24_1 = (uint32_t)0xffffffffU;
}
}
{
stack_m4_1 = stack_m24_1;
}
} else {
{
stack_m4_1 = (uint32_t)((uint32_t)((uint32_t)arg0 + (uint32_t)arg1) - (uint32_t)arg2);
}
}
}
}
}
}
}
}
}
}
{
return (uint32_t)stack_m4_1;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x100000940
FILE=tests/fixtures/manual_limits_O0
CMDS=aa; pdd @ 0x100000940
EXPECT=<<EOF
uint32_t _table_walk(uint64_t arg0, uint8_t* arg1)
{
uint64_t stack_m40_1;
uint32_t stack_m28_1;
uint32_t stack_m28_3;
uint64_t x8_6;
uint16_t tmp_25700_1;
uint64_t stack_m48_1;
uint16_t tmp_25700_2;
uint8_t tmp_26000_1;
uint64_t x8_15;
uint8_t tmp_26000_2;
uint8_t tmp_26000_3;
uint32_t stack_m52_1;
uint16_t tmp_25700_3;
uint8_t tmp_26000_4;
uint32_t tmp_24c00_3;
uint64_t x8_30;
uint32_t stack_m4_1;
/* r2dec proof: no individual construct is marked; 124 source obligations: 121 rendered, 3 elided, 0 refused; 40 statements rendered */
{
stack_m40_1 = arg0;
stack_m28_1 = 0;
for (; ; ) {
if ((uint8_t)((uint64_t)stack_m40_1 == (uint64_t)0U)) {
goto L6;
} else {
{
stack_m28_3 = (uint32_t)((uint32_t)stack_m28_1 + (uint32_t)1U);
x8_6 = r2sleigh_load_u64((void*)((uint64_t)stack_m40_1 + (uint64_t)3U * 8U));
if ((uint8_t)((uint64_t)x8_6 == (uint64_t)0U)) {
{
}
} else {
{
tmp_25700_1 = r2sleigh_load_u16((void*)((uint64_t)stack_m40_1 + (uint64_t)3U * 2U));
if ((uint8_t)((uint32_t)((uint64_t)(uint16_t)tmp_25700_1 >> 0U) != (uint32_t)0U)) {
stack_m48_1 = 0;
for (; ; ) {
tmp_25700_2 = r2sleigh_load_u16((void*)((uint64_t)stack_m40_1 + (uint64_t)3U * 2U));
if ((uint8_t)((uint64_t)(uint16_t)tmp_25700_2 <= (uint64_t)stack_m48_1)) {
stack_m52_1 = 0;
} else {
{
tmp_26000_1 = r2sleigh_load_u8((void*)((uint64_t)arg1 + (uint64_t)stack_m48_1 * 1U));
if ((uint8_t)((uint32_t)((uint64_t)(int8_t)tmp_26000_1 >> 0U) == (uint32_t)0U)) {
stack_m52_1 = 0;
} else {
{
x8_15 = r2sleigh_load_u64((void*)((uint64_t)stack_m40_1 + (uint64_t)3U * 8U));
tmp_26000_2 = r2sleigh_load_u8((void*)(uint64_t)((uint64_t)x8_15 + (uint64_t)stack_m48_1));
tmp_26000_3 = r2sleigh_load_u8((void*)((uint64_t)arg1 + (uint64_t)stack_m48_1 * 1U));
stack_m52_1 = (uint32_t)((uint64_t)(uint8_t)((uint32_t)((uint64_t)(int8_t)tmp_26000_3 >> 0U) == (uint32_t)((uint64_t)(int8_t)tmp_26000_2 >> 0U)) >> 0U);
}
}
}
}
{
if ((uint8_t)((uint32_t)((uint32_t)stack_m52_1 & (uint32_t)1U) == (uint32_t)0U)) {
break;
} else {
{
stack_m48_1 = (uint64_t)((uint64_t)stack_m48_1 + (uint64_t)1U);
}
}
}
}
{
tmp_25700_3 = r2sleigh_load_u16((void*)((uint64_t)stack_m40_1 + (uint64_t)3U * 2U));
if ((uint8_t)((uint64_t)(uint16_t)tmp_25700_3 != (uint64_t)stack_m48_1)) {
} else {
{
tmp_26000_4 = r2sleigh_load_u8((void*)((uint64_t)arg1 + (uint64_t)stack_m48_1 * 1U));
if ((uint8_t)((uint32_t)((uint64_t)(int8_t)tmp_26000_4 >> 0U) != (uint32_t)0U)) {
} else {
break;
}
}
}
{
}
}
} else {
{
}
}
}
}
{
x8_30 = r2sleigh_load_u64((void*)((uint64_t)stack_m40_1 + (uint64_t)4U * 8U));
stack_m40_1 = x8_30;
stack_m28_1 = stack_m28_3;
}
}
}
}
{
{
tmp_24c00_3 = r2sleigh_load_u32((void*)stack_m40_1);
stack_m4_1 = (uint32_t)((uint32_t)tmp_24c00_3 + (uint32_t)stack_m28_3);
goto L7;
}
}
{
L6: ;
stack_m4_1 = (uint32_t)((uint32_t)0U - (uint32_t)stack_m28_1);
}
{
L7: ;
return (uint32_t)stack_m4_1;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x100000aa0
FILE=tests/fixtures/manual_limits_O0
CMDS=aa; pdd @ 0x100000aa0
EXPECT=<<EOF
uint32_t _state_machine(uint8_t* arg0)
{
uint64_t stack_m32_1;
uint32_t stack_m24_1;
uint32_t stack_m20_1;
uint8_t tmp_26000_1;
uint8_t tmp_25500_1;
uint8_t tmp_3a980_1;
uint32_t stack_m20_5;
uint32_t stack_m20_6;
uint32_t stack_m24_3;
uint32_t stack_m20_3;
uint32_t stack_m24_4;
uint32_t stack_m20_4;
uint32_t stack_m24_9;
uint32_t stack_m24_2;
uint32_t stack_m20_2;
uint32_t stack_m24_5;
uint32_t stack_m20_7;
uint32_t stack_m4_1;
/* r2dec proof: no individual construct is marked; 220 source obligations: 217 rendered, 3 elided, 0 refused; 86 statements rendered */
{
stack_m32_1 = 0;
stack_m24_1 = 0;
stack_m20_1 = 0;
for (; ; ) {
tmp_26000_1 = r2sleigh_load_u8((void*)((uint64_t)arg0 + (uint64_t)stack_m32_1 * 1U));
if ((uint8_t)((uint32_t)((uint64_t)(int8_t)tmp_26000_1 >> 0U) == (uint32_t)0U)) {
goto L16;
} else {
{
tmp_25500_1 = r2sleigh_load_u8((void*)((uint64_t)arg0 + (uint64_t)stack_m32_1 * 1U));
tmp_3a980_1 = tmp_25500_1;
if ((uint8_t)((uint32_t)stack_m20_1 == (uint32_t)0U)) {
if ((uint8_t)((int32_t)((uint64_t)(uint8_t)tmp_3a980_1 >> 0U) < (int32_t)97U)) {
} else {
{
if ((uint8_t)((int32_t)((uint64_t)(uint8_t)tmp_3a980_1 >> 0U) <= (int32_t)122U)) {
goto L1;
} else {
}
}
}
{
if ((uint8_t)((uint32_t)((uint64_t)(uint8_t)tmp_3a980_1 >> 0U) != (uint32_t)95U)) {
if ((uint8_t)((int32_t)((uint64_t)(uint8_t)tmp_3a980_1 >> 0U) < (int32_t)48U)) {
goto L2;
} else {
{
if ((uint8_t)((int32_t)57U < (int32_t)((uint64_t)(uint8_t)tmp_3a980_1 >> 0U))) {
goto L2;
} else {
{
stack_m24_9 = (uint32_t)((uint32_t)stack_m24_1 - (uint32_t)5U);
{
stack_m24_2 = stack_m24_9;
stack_m20_2 = 2;
goto L3;
}
}
}
}
}
} else {
}
}
{
L1: ;
stack_m24_2 = (uint32_t)((uint32_t)stack_m24_1 + (uint32_t)3U);
stack_m20_2 = 1;
}
{
L3: ;
stack_m24_5 = stack_m24_2;
stack_m20_7 = stack_m20_2;
}
} else {
{
if ((uint8_t)((uint32_t)stack_m20_1 == (uint32_t)1U)) {
if ((uint8_t)((int32_t)((uint64_t)(uint8_t)tmp_3a980_1 >> 0U) < (int32_t)48U)) {
} else {
{
if ((uint8_t)((int32_t)57U < (int32_t)((uint64_t)(uint8_t)tmp_3a980_1 >> 0U))) {
} else {
{
stack_m24_4 = (uint32_t)((uint32_t)((uint32_t)((uint64_t)(uint8_t)tmp_3a980_1 >> 0U) + (uint32_t)stack_m24_1) - (uint32_t)48U);
stack_m20_4 = 2;
goto L9;
}
}
}
}
{
if ((uint8_t)((uint32_t)((uint64_t)(uint8_t)tmp_3a980_1 >> 0U) != (uint32_t)45U)) {
if ((uint8_t)((int32_t)((uint64_t)(uint8_t)tmp_3a980_1 >> 0U) < (int32_t)97U)) {
} else {
{
if ((uint8_t)((int32_t)((uint64_t)(uint8_t)tmp_3a980_1 >> 0U) <= (int32_t)122U)) {
goto L7;
} else {
}
}
}
{
if ((uint8_t)((uint32_t)((uint64_t)(uint8_t)tmp_3a980_1 >> 0U) == (uint32_t)95U)) {
} else {
goto L6;
}
}
{
L7: ;
stack_m24_3 = stack_m24_1;
stack_m20_3 = stack_m20_1;
}
} else {
{
stack_m24_3 = (uint32_t)((uint32_t)stack_m24_1 + (uint32_t)7U);
stack_m20_3 = 3;
}
}
{
stack_m24_4 = stack_m24_3;
stack_m20_4 = stack_m20_3;
}
}
{
L9: ;
stack_m24_5 = stack_m24_4;
stack_m20_7 = stack_m20_4;
}
} else {
{
if ((uint8_t)((uint32_t)stack_m20_1 == (uint32_t)2U)) {
if ((uint8_t)((uint32_t)((uint64_t)(uint8_t)tmp_3a980_1 >> 0U) != (uint32_t)95U)) {
if ((uint8_t)((uint32_t)((uint64_t)(uint8_t)tmp_3a980_1 >> 0U) != (uint32_t)45U)) {
if ((uint8_t)((int32_t)((uint64_t)(uint8_t)tmp_3a980_1 >> 0U) < (int32_t)48U)) {
goto L11;
} else {
{
if ((uint8_t)((int32_t)((uint64_t)(uint8_t)tmp_3a980_1 >> 0U) <= (int32_t)57U)) {
stack_m20_5 = stack_m20_1;
} else {
goto L10;
}
}
}
} else {
{
stack_m20_5 = 3;
}
}
{
stack_m20_6 = stack_m20_5;
}
} else {
{
stack_m20_6 = 1;
}
}
{
stack_m24_5 = stack_m24_1;
stack_m20_7 = stack_m20_6;
}
} else {
{
if ((uint8_t)((uint32_t)((uint64_t)(uint8_t)tmp_3a980_1 >> 0U) == (uint32_t)120U)) {
stack_m24_5 = stack_m24_1;
stack_m20_7 = 0;
} else {
break;
}
}
}
}
}
}
}
{
{
stack_m32_1 = (uint64_t)((uint64_t)stack_m32_1 + (uint64_t)1U);
stack_m24_1 = stack_m24_5;
stack_m20_1 = stack_m20_7;
}
}
}
}
}
{
{
stack_m4_1 = (uint32_t)((uint32_t)0xfffffe70U - (uint32_t)((uint64_t)stack_m32_1 >> 0U));
goto L17;
}
}
{
L10: ;
}
{
L11: ;
stack_m4_1 = (uint32_t)((uint32_t)0xfffffed4U - (uint32_t)((uint64_t)stack_m32_1 >> 0U));
goto L17;
}
{
L6: ;
{
stack_m4_1 = (uint32_t)((uint32_t)0xffffff38U - (uint32_t)((uint64_t)stack_m32_1 >> 0U));
goto L17;
}
}
{
L2: ;
stack_m4_1 = (uint32_t)((uint32_t)0xffffff9cU - (uint32_t)((uint64_t)stack_m32_1 >> 0U));
goto L17;
}
{
L16: ;
stack_m4_1 = (uint32_t)((uint32_t)stack_m24_1 + (uint32_t)stack_m20_1);
}
{
L17: ;
return (uint32_t)stack_m4_1;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x100000d4c
FILE=tests/fixtures/manual_limits_O0
CMDS=aa; pdd @ 0x100000d4c
EXPECT=<<EOF
uint64_t _mem_scan2(uint8_t* arg0, uint64_t arg1, uint8_t arg2, uint8_t arg3)
{
uint8_t tmp_3a980_1;
uint8_t tmp_3a980_2;
uint64_t stack_m40_1;
uint64_t stack_m32_1;
uint8_t tmp_25500_1;
uint8_t tmp_3a980_3;
uint64_t stack_m32_2;
/* r2dec proof: no individual construct is marked; 58 source obligations: 55 rendered, 3 elided, 0 refused; 17 statements rendered */
{
tmp_3a980_1 = arg2;
tmp_3a980_2 = arg3;
stack_m40_1 = 0;
stack_m32_1 = 0;
for (; ; ) {
if ((uint8_t)((uint64_t)arg1 <= (uint64_t)stack_m40_1)) {
break;
} else {
{
tmp_25500_1 = r2sleigh_load_u8((void*)((uint64_t)arg0 + (uint64_t)stack_m40_1 * 1U));
tmp_3a980_3 = tmp_25500_1;
if ((uint8_t)((uint32_t)((uint64_t)(uint8_t)tmp_3a980_1 >> 0U) == (uint32_t)((uint64_t)(uint8_t)tmp_3a980_3 >> 0U))) {
{
stack_m32_2 = (uint64_t)((uint64_t)stack_m32_1 + (uint64_t)1U);
}
} else {
{
if ((uint8_t)((uint32_t)((uint64_t)(uint8_t)tmp_3a980_2 >> 0U) != (uint32_t)((uint64_t)(uint8_t)tmp_3a980_3 >> 0U))) {
stack_m32_2 = stack_m32_1;
} else {
{
stack_m32_2 = (uint64_t)((uint64_t)stack_m32_1 + (uint64_t)1U);
}
}
}
}
{
{
stack_m40_1 = (uint64_t)((uint64_t)stack_m40_1 + (uint64_t)1U);
stack_m32_1 = stack_m32_2;
}
}
}
}
}
{
return (uint64_t)stack_m32_1;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x100000dec
FILE=tests/fixtures/manual_limits_O0
CMDS=aa; pdd @ 0x100000dec
EXPECT=<<EOF
struct r2sleigh_bits_256 {
uint8_t bytes[32];
};
static inline __uint128_t r2sleigh_bits_extract_256_128(struct r2sleigh_bits_256 carrier, uint64_t at)
{
__uint128_t field = 0;
for (uint32_t bit = 0; bit < 128u; ++bit) {
const uint64_t from = at + bit;
if (from < 256u && ((carrier.bytes[from / 8] >> (from % 8)) & 1) != 0) {
field = (__uint128_t)(field | ((__uint128_t)1 << bit));
}
}
return field;
}
static inline struct r2sleigh_bits_256 r2sleigh_bits_insert_256_64(struct r2sleigh_bits_256 carrier, uint64_t field, uint64_t at)
{
for (uint32_t bit = 0; bit < 64u; ++bit) {
const uint64_t to = at + bit;
if (to < 256u) {
const unsigned mask = 1u << (to % 8);
if (((field >> bit) & 1) != 0) {
carrier.bytes[to / 8] = (uint8_t)(carrier.bytes[to / 8] | mask);
} else {
carrier.bytes[to / 8] = (uint8_t)(carrier.bytes[to / 8] & ~mask);
}
}
}
return carrier;
}
static inline struct r2sleigh_bits_256 r2sleigh_bits_zero_extend_64_256(uint64_t field)
{
struct r2sleigh_bits_256 carrier = {{0}};
for (uint32_t bit = 0; bit < 64u; ++bit) {
if (((field >> bit) & 1) != 0) {
carrier.bytes[bit / 8] = (uint8_t)(carrier.bytes[bit / 8] | (1u << (bit % 8)));
}
}
return carrier;
}
uint64_t _main(uint32_t arg0, uint64_t* arg1)
{
uint64_t _fnv_fold(uint64_t, uint64_t);
uint64_t _mem_scan2(uint64_t, uint64_t, uint8_t, uint8_t);
uint32_t _out_param_parse(uint64_t, uint64_t);
uint32_t _sparse_switch(uint32_t, uint32_t, uint32_t);
uint32_t _state_machine(uint64_t);
uint32_t _struct_nested_array(uint64_t, uint32_t, uint32_t);
uint32_t _table_walk(uint64_t, uint64_t);
void* memcpy(void*, const void*, uint64_t);
extern char _manual_sink[];
uint64_t x0_3;
struct r2sleigh_bits_256 z0_2;
struct r2sleigh_bits_256 z0_3;
uint32_t tmp_24d00_1;
uint32_t tmp_24d00_2;
uint64_t x2_3;
uint64_t x0_4;
uint32_t tmp_24c00_1;
uint32_t tmp_24d00_3;
uint64_t x8_9;
uint64_t x0_6;
uint32_t tmp_24c00_2;
uint64_t x0_9;
uint64_t x8_18;
uint32_t tmp_24c00_3;
uint32_t tmp_24d00_4;
uint32_t tmp_24c00_4;
uint64_t x8_19;
uint64_t x0_11;
uint64_t x9_12;
uint32_t tmp_24c00_5;
uint32_t tmp_24d00_5;
uint64_t x8_25;
uint64_t x1_8;
uint64_t x0_13;
uint32_t tmp_24c00_6;
uint32_t tmp_24d00_6;
uint64_t x8_35;
uint64_t x0_15;
uint32_t tmp_24c00_7;
uint64_t x0_18;
uint64_t x8_44;
uint32_t tmp_24c00_8;
uint32_t tmp_24c00_9;
_Alignas(16) uint8_t frame[192];
/* r2dec proof: no individual construct is marked; 229 source obligations: 178 rendered, 35 elided, 0 refused, 16 assumed (frame extent unproven); 61 statements rendered; 1 data object type refused; 1 callee prototype supplied by the source */
{
r2sleigh_store_u32((void*)((uint64_t)(frame + 48U) + (uint64_t)124U), (uint32_t)0U);
r2sleigh_store_u32((void*)((uint64_t)(frame + 48U) + (uint64_t)120U), (uint32_t)arg0);
r2sleigh_store_u64((void*)((uint64_t)(frame + 48U) + (uint64_t)112U), (uint64_t)arg1);
r2sleigh_store_u64((void*)(uint64_t)(frame + 40U), (uint64_t)((uint64_t)(frame + 48U) + (uint64_t)32U));
memcpy((void*)(uint64_t)((uint64_t)(frame + 48U) + (uint64_t)32U), (const void*)(uint64_t)0x100004008U, 80);
x0_3 = r2sleigh_load_u64((void*)(uint64_t)(frame + 40U));
z0_2 = r2sleigh_bits_insert_256_64(r2sleigh_bits_zero_extend_64_256((uint64_t)0U), (uint64_t)0U, 0U);
z0_3 = r2sleigh_bits_insert_256_64(z0_2, (uint64_t)0U, 64U);
r2sleigh_store_u128((void*)(uint64_t)(frame + 48U), (__uint128_t)r2sleigh_bits_extract_256_128(z0_3, 0U));
r2sleigh_store_u128((void*)(uint64_t)((uint64_t)(frame + 48U) + (uint64_t)16U), (__uint128_t)r2sleigh_bits_extract_256_128(z0_3, 0U));
r2sleigh_store_u64((void*)((uint64_t)(frame + 48U) + (uint64_t)64U), (uint64_t)((uint64_t)x0_3 + (uint64_t)40U));
tmp_24d00_1 = r2sleigh_load_u32((void*)((uint64_t)(frame + 48U) + (uint64_t)120U));
tmp_24d00_2 = r2sleigh_load_u32((void*)((uint64_t)(frame + 48U) + (uint64_t)120U));
x2_3 = (uint64_t)(uint32_t)tmp_24d00_2;
x0_4 = (uint64_t)_struct_nested_array(x0_3, (uint32_t)((uint32_t)tmp_24d00_1 & (uint32_t)1U), (uint32_t)x2_3);
tmp_24c00_1 = r2sleigh_load_u32((void*)&_manual_sink);
r2sleigh_store_u32((void*)&_manual_sink, (uint32_t)((uint32_t)((uint64_t)x0_4 >> 0U) + (uint32_t)tmp_24c00_1));
tmp_24d00_3 = r2sleigh_load_u32((void*)((uint64_t)(frame + 48U) + (uint64_t)120U));
if ((uint8_t)((int32_t)tmp_24d00_3 <= (int32_t)1U)) {
r2sleigh_store_u64((void*)(uint64_t)(frame + 32U), (uint64_t)0x100000fecU);
} else {
{
x8_9 = r2sleigh_load_u64((void*)((uint64_t)(frame + 48U) + (uint64_t)112U));
r2sleigh_store_u64((void*)(uint64_t)(frame + 32U), (uint64_t)r2sleigh_load_u64((void*)((uint64_t)x8_9 + (uint64_t)1U * 8U)));
}
}
{
x0_6 = (uint64_t)_out_param_parse(r2sleigh_load_u64((void*)(uint64_t)(frame + 32U)), (uint64_t)(frame + 48U));
r2sleigh_store_u64((void*)(uint64_t)(frame + 24U), (uint64_t)0x100008000U);
tmp_24c00_2 = r2sleigh_load_u32((void*)&_manual_sink);
r2sleigh_store_u32((void*)&_manual_sink, (uint32_t)((uint32_t)((uint64_t)x0_6 >> 0U) + (uint32_t)tmp_24c00_2));
x0_9 = _fnv_fold((uint64_t)0x100000ff0U, 3);
x8_18 = r2sleigh_load_u64((void*)(uint64_t)(frame + 24U));
tmp_24c00_3 = r2sleigh_load_u32((void*)x8_18);
r2sleigh_store_u32((void*)x8_18, (uint32_t)((uint32_t)((uint64_t)x0_9 >> 0U) + (uint32_t)tmp_24c00_3));
tmp_24d00_4 = r2sleigh_load_u32((void*)((uint64_t)(frame + 48U) + (uint64_t)120U));
tmp_24c00_4 = r2sleigh_load_u32((void*)x8_18);
x8_19 = r2sleigh_load_u64((void*)((uint64_t)(frame + 48U) + (uint64_t)24U));
x0_11 = (uint64_t)_sparse_switch((uint32_t)tmp_24d00_4, (uint32_t)tmp_24c00_4, (uint32_t)x8_19);
x9_12 = r2sleigh_load_u64((void*)(uint64_t)(frame + 24U));
tmp_24c00_5 = r2sleigh_load_u32((void*)x9_12);
r2sleigh_store_u32((void*)x9_12, (uint32_t)((uint32_t)((uint64_t)x0_11 >> 0U) + (uint32_t)tmp_24c00_5));
tmp_24d00_5 = r2sleigh_load_u32((void*)((uint64_t)(frame + 48U) + (uint64_t)120U));
if ((uint8_t)((int32_t)tmp_24d00_5 <= (int32_t)2U)) {
r2sleigh_store_u64((void*)(uint64_t)(frame + 16U), (uint64_t)0x100000fe8U);
} else {
{
x8_25 = r2sleigh_load_u64((void*)((uint64_t)(frame + 48U) + (uint64_t)112U));
r2sleigh_store_u64((void*)(uint64_t)(frame + 16U), (uint64_t)r2sleigh_load_u64((void*)((uint64_t)x8_25 + (uint64_t)2U * 8U)));
}
}
{
x1_8 = r2sleigh_load_u64((void*)(uint64_t)(frame + 16U));
x0_13 = (uint64_t)_table_walk((uint64_t)((uint64_t)(frame + 48U) + (uint64_t)32U), x1_8);
tmp_24c00_6 = r2sleigh_load_u32((void*)&_manual_sink);
r2sleigh_store_u32((void*)&_manual_sink, (uint32_t)((uint32_t)((uint64_t)x0_13 >> 0U) + (uint32_t)tmp_24c00_6));
tmp_24d00_6 = r2sleigh_load_u32((void*)((uint64_t)(frame + 48U) + (uint64_t)120U));
if ((uint8_t)((int32_t)tmp_24d00_6 <= (int32_t)3U)) {
r2sleigh_store_u64((void*)(uint64_t)(frame + 8U), (uint64_t)0x100000ff4U);
} else {
{
x8_35 = r2sleigh_load_u64((void*)((uint64_t)(frame + 48U) + (uint64_t)112U));
r2sleigh_store_u64((void*)(uint64_t)(frame + 8U), (uint64_t)r2sleigh_load_u64((void*)((uint64_t)x8_35 + (uint64_t)3U * 8U)));
}
}
{
x0_15 = (uint64_t)_state_machine(r2sleigh_load_u64((void*)(uint64_t)(frame + 8U)));
r2sleigh_store_u64((void*)(uint64_t)(frame + 0U), (uint64_t)0x100008000U);
tmp_24c00_7 = r2sleigh_load_u32((void*)&_manual_sink);
r2sleigh_store_u32((void*)&_manual_sink, (uint32_t)((uint32_t)((uint64_t)x0_15 >> 0U) + (uint32_t)tmp_24c00_7));
x0_18 = _mem_scan2((uint64_t)0x100000ffbU, 6, 97, 122);
x8_44 = r2sleigh_load_u64((void*)(uint64_t)(frame + 0U));
tmp_24c00_8 = r2sleigh_load_u32((void*)x8_44);
r2sleigh_store_u32((void*)x8_44, (uint32_t)((uint32_t)((uint64_t)x0_18 >> 0U) + (uint32_t)tmp_24c00_8));
tmp_24c00_9 = r2sleigh_load_u32((void*)x8_44);
return (uint64_t)(uint8_t)((uint32_t)tmp_24c00_9 == (uint32_t)0U);
}
}
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x100000fd8
FILE=tests/fixtures/manual_limits_O0
CMDS=aa; pdd @ 0x100000fd8
EXPECT=<<EOF
/* r2sleigh: import stub at 0x100000fd8; this symbol is the import `memcpy` and has no body of its own. */
extern void* memcpy(void*, const void*, uint64_t);
EOF
EXPECT_ERR=<<EOF
EOF
RUN
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+972
View File
@@ -0,0 +1,972 @@
# The census of rv_O0g_stripped: what `aa; pdd` renders for each function `afl` lists.
# Regenerate with `scripts/census.py golden` when `afl` moves, then bless.
NAME=afl
FILE=tests/fixtures/rv_O0g_stripped
CMDS=afl
EXPECT=<<EOF
0x00001000 3 27 fcn.00001000
0x00001070 1 10 sym.imp.__cxa_finalize
0x00001080 1 10 sym.imp.strlen
0x00001090 1 10 sym.imp.__stack_chk_fail
0x000010a0 1 10 sym.imp.printf
0x000010b0 1 10 sym.imp.memcpy
0x000010c0 1 37 entry0
0x000010f0 4 34 fcn.000010f0
0x00001160 5 54 entry.fini0
0x000011a0 5 60 entry.init0
0x000011a9 1 24 fcn.000011a9
0x000011c1 4 73 fcn.000011c1
0x0000120a 3 60 fcn.0000120a
0x00001277 4 49 fcn.00001277
0x000012a8 4 71 fcn.000012a8
0x000012ef 7 115 fcn.000012ef
0x00001362 4 47 fcn.00001362
0x00001391 4 82 fcn.00001391
0x000013e3 3 105 fcn.000013e3
0x0000144c 1 33 fcn.0000144c
0x0000146d 1 28 fcn.0000146d
0x00001489 4 44 fcn.00001489
0x000014b5 10 108 fcn.000014b5
0x00001521 1 40 fcn.00001521
0x00001549 6 640 fcn.00001549
0x000017cc 1 13 fcn.000017cc
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001000
FILE=tests/fixtures/rv_O0g_stripped
CMDS=aa; pdd @ 0x00001000
EXPECT=<<EOF
uint64_t fcn_1000(void)
{
uint64_t rax_1;
uint64_t rax_2;
uint64_t rax_3;
/* r2dec proof: no individual construct is marked; 22 source obligations: 12 rendered, 10 elided, 0 refused; 6 statements rendered */
{
rax_1 = r2sleigh_load_u64((void*)(uint64_t)0x3fe8U);
if ((uint8_t)((uint64_t)rax_1 == (uint64_t)0U)) {
rax_3 = rax_1;
} else {
rax_2 = ((uint64_t(*)(void))(uint64_t)rax_1)();
rax_3 = rax_2;
}
{
return (uint64_t)rax_3;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001070
FILE=tests/fixtures/rv_O0g_stripped
CMDS=aa; pdd @ 0x00001070
EXPECT=<<EOF
/* r2dec refused __cxa_finalize: r2sleigh: import stub at 0x1070; this symbol is the import `__cxa_finalize`, whose prototype nothing states. */
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001080
FILE=tests/fixtures/rv_O0g_stripped
CMDS=aa; pdd @ 0x00001080
EXPECT=<<EOF
/* r2sleigh: import stub at 0x1080; this symbol is the import `strlen` and has no body of its own. */
extern uint64_t strlen(const char*);
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001090
FILE=tests/fixtures/rv_O0g_stripped
CMDS=aa; pdd @ 0x00001090
EXPECT=<<EOF
/* r2sleigh: import stub at 0x1090; this symbol is the import `__stack_chk_fail` and has no body of its own. */
extern void __stack_chk_fail(void);
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000010a0
FILE=tests/fixtures/rv_O0g_stripped
CMDS=aa; pdd @ 0x000010a0
EXPECT=<<EOF
/* r2sleigh: import stub at 0x10a0; this symbol is the import `printf` and has no body of its own. */
extern int32_t printf(const char*, ...);
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000010b0
FILE=tests/fixtures/rv_O0g_stripped
CMDS=aa; pdd @ 0x000010b0
EXPECT=<<EOF
/* r2sleigh: import stub at 0x10b0; this symbol is the import `memcpy` and has no body of its own. */
extern void* memcpy(void*, const void*, uint64_t);
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000010c0
FILE=tests/fixtures/rv_O0g_stripped
CMDS=aa; pdd @ 0x000010c0
EXPECT=<<EOF
void entry0(void)
{
uint64_t tmp_55400_2;
uint64_t tmp_3cb80_1;
/* r2dec proof: 5 constructs are marked below; 28 source obligations: 2 rendered, 4 elided, 0 refused, 22 residual; 2 statements rendered; 1 held from entry, read as residuals (stack_p0) */
{
tmp_55400_2 = r2sleigh_residual_u64(1);
r2sleigh_residual_void(2); /* r2dec gap: StoreNotSpelled at 0x10c0:29 covering 1 op (render::values) */
r2sleigh_residual_void(3); /* r2dec gap: StoreNotSpelled at 0x10c0:32 covering 1 op (render::values) */
tmp_3cb80_1 = r2sleigh_load_u64((void*)(uint64_t)0x3fd8U);
r2sleigh_residual_void(4); /* r2dec gap: CallNotRendered at 0x10c0:68 covering 1 op (render::values) */
r2sleigh_residual_void(5); /* r2dec gap: TailTransferNotRendered at 0x10c0 (render::control) */
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000010f0
FILE=tests/fixtures/rv_O0g_stripped
CMDS=aa; pdd @ 0x000010f0
EXPECT=<<EOF
uint64_t fcn_10f0(void)
{
uint64_t rax_2;
uint64_t rax_3;
/* r2dec proof: 1 construct is marked below; 17 source obligations: 13 rendered, 3 elided, 0 refused, 1 residual; 6 statements rendered */
{
if ((uint8_t)1U) {
rax_3 = 0x4020;
} else {
rax_2 = r2sleigh_load_u64((void*)(uint64_t)0x3fe0U);
if ((uint8_t)((uint64_t)rax_2 == (uint64_t)0U)) {
rax_3 = rax_2;
} else {
r2sleigh_residual_void(1); /* r2dec gap: UnresolvedIndirectBranch at 0x110f (render::control) */
}
}
{
return (uint64_t)rax_3;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001160
FILE=tests/fixtures/rv_O0g_stripped
CMDS=aa; pdd @ 0x00001160
EXPECT=<<EOF
uint64_t entry_fini0(void)
{
void __cxa_finalize(uint64_t);
uint64_t fcn_10f0(void);
uint8_t tmp_3e180_1;
uint64_t tmp_3ea80_1;
uint64_t rdi_1;
/* r2dec proof: 2 constructs are marked below; 39 source obligations: 19 rendered, 16 elided, 0 refused, 4 residual; 10 statements rendered */
{
tmp_3e180_1 = r2sleigh_load_u8((void*)(uint64_t)0x4020U);
if ((uint8_t)((uint8_t)tmp_3e180_1 != (uint8_t)0U)) {
return r2sleigh_residual_u64(1);
} else {
tmp_3ea80_1 = r2sleigh_load_u64((void*)(uint64_t)0x3ff8U);
if ((uint8_t)((uint64_t)tmp_3ea80_1 == (uint64_t)0U)) {
} else {
rdi_1 = r2sleigh_load_u64((void*)(uint64_t)0x4008U);
__cxa_finalize(rdi_1);
}
{
fcn_10f0();
r2sleigh_store_u8((void*)(uint64_t)0x4020U, (uint8_t)1U);
return r2sleigh_residual_u64(2);
}
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000011a0
FILE=tests/fixtures/rv_O0g_stripped
CMDS=aa; pdd @ 0x000011a0
EXPECT=<<EOF
uint64_t entry_init0(void)
{
uint64_t rax_3;
uint64_t rax_4;
/* r2dec proof: 1 construct is marked below; 25 source obligations: 20 rendered, 4 elided, 0 refused, 1 residual; 6 statements rendered */
{
{
if ((uint8_t)1U) {
rax_4 = 0;
} else {
rax_3 = r2sleigh_load_u64((void*)(uint64_t)0x3ff0U);
if ((uint8_t)((uint64_t)rax_3 == (uint64_t)0U)) {
rax_4 = rax_3;
} else {
r2sleigh_residual_void(1); /* r2dec gap: UnresolvedIndirectBranch at 0x1150 (render::control) */
}
}
{
return (uint64_t)rax_4;
}
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000011a9
FILE=tests/fixtures/rv_O0g_stripped
CMDS=aa; pdd @ 0x000011a9
EXPECT=<<EOF
uint32_t fcn_11a9(uint32_t arg0, uint32_t arg1)
{
/* r2dec proof: no individual construct is marked; 10 source obligations: 3 rendered, 7 elided, 0 refused; 1 statements rendered; the result's second register is open: no call read decides it */
{
return (uint32_t)((uint32_t)arg1 + (uint32_t)arg0);
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000011c1
FILE=tests/fixtures/rv_O0g_stripped
CMDS=aa; pdd @ 0x000011c1
EXPECT=<<EOF
uint32_t fcn_11c1(uint32_t* arg0, uint32_t arg1)
{
uint32_t stack_m16_1;
uint32_t stack_m12_1;
uint32_t tmp_11f00_3;
/* r2dec proof: no individual construct is marked; 31 source obligations: 24 rendered, 7 elided, 0 refused; 9 statements rendered */
{
stack_m16_1 = 0;
stack_m12_1 = 0;
for (; ; ) {
if ((uint8_t)((int32_t)stack_m12_1 < (int32_t)arg1)) {
tmp_11f00_3 = r2sleigh_load_u32((void*)((uint64_t)arg0 + (uint64_t)(int32_t)stack_m12_1 * 4U));
stack_m16_1 = (uint32_t)((uint32_t)stack_m16_1 + (uint32_t)tmp_11f00_3);
stack_m12_1 = (uint32_t)((uint32_t)stack_m12_1 + (uint32_t)1U);
} else {
break;
}
}
{
return (uint32_t)stack_m16_1;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x0000120a
FILE=tests/fixtures/rv_O0g_stripped
CMDS=aa; pdd @ 0x0000120a
EXPECT=<<EOF
uint64_t fcn_120a(uint32_t arg0)
{
uint64_t rax_14;
/* r2dec proof: no individual construct is marked; 38 source obligations: 22 rendered, 16 elided, 0 refused; 19 statements rendered */
{
if ((uint8_t)((uint32_t)7U < (uint32_t)arg0)) {
} else {
switch (arg0) {
case 7:
{
rax_14 = 87;
goto L1;
}
case 5:
{
rax_14 = 65;
goto L1;
}
case 4:
{
rax_14 = 54;
goto L1;
}
case 3:
{
rax_14 = 43;
goto L1;
}
case 2:
{
rax_14 = 32;
goto L1;
}
case 1:
{
rax_14 = 21;
goto L1;
}
case 0:
{
rax_14 = 10;
goto L1;
}
case 6:
break;
}
}
{
rax_14 = (uint64_t)0xffffffffU;
}
{
L1: ;
return (uint64_t)rax_14;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001277
FILE=tests/fixtures/rv_O0g_stripped
CMDS=aa; pdd @ 0x00001277
EXPECT=<<EOF
uint32_t fcn_1277(uint64_t arg0)
{
uint64_t stack_m32_1;
uint32_t stack_m12_1;
uint64_t tmp_11f80_3;
/* r2dec proof: no individual construct is marked; 28 source obligations: 21 rendered, 7 elided, 0 refused; 9 statements rendered */
{
stack_m32_1 = arg0;
stack_m12_1 = 0;
for (; ; ) {
if ((uint8_t)((uint64_t)stack_m32_1 != (uint64_t)0U)) {
tmp_11f80_3 = r2sleigh_load_u64((void*)(uint64_t)((uint64_t)stack_m32_1 + (uint64_t)8U));
stack_m32_1 = tmp_11f80_3;
stack_m12_1 = (uint32_t)((uint32_t)stack_m12_1 + (uint32_t)1U);
} else {
break;
}
}
{
return (uint32_t)stack_m12_1;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000012a8
FILE=tests/fixtures/rv_O0g_stripped
CMDS=aa; pdd @ 0x000012a8
EXPECT=<<EOF
uint64_t fcn_12a8(uint64_t arg0, uint64_t arg1)
{
uint64_t rax_4;
__uint128_t tmp_3d800_1;
uint64_t rdx_2;
__uint128_t tmp_49d00_1;
__uint128_t tmp_49d80_1;
__uint128_t tmp_49e00_1;
__uint128_t tmp_49e80_1;
__uint128_t tmp_49f80_1;
__uint128_t tmp_4a080_1;
uint64_t rax_5;
__uint128_t tmp_3d800_2;
uint64_t rdx_4;
__uint128_t tmp_49d00_2;
__uint128_t tmp_49d80_2;
__uint128_t tmp_49e00_2;
__uint128_t tmp_49e80_2;
__uint128_t tmp_49f80_2;
__uint128_t tmp_4a200_2;
uint64_t rdx_5;
uint64_t rax_10;
/* r2dec proof: 2 constructs are marked below; 41 source obligations: 31 rendered, 7 elided, 0 refused, 3 residual; 25 statements rendered */
{
if ((uint8_t)((uint64_t)arg1 != (uint64_t)0U)) {
rax_4 = (uint64_t)((uint64_t)((uint64_t)arg0 * (uint64_t)8U) - (uint64_t)arg0);
tmp_3d800_1 = (__uint128_t)(int64_t)rax_4;
rdx_2 = (uint64_t)((__uint128_t)tmp_3d800_1 >> 64U);
tmp_49d00_1 = (__uint128_t)(int64_t)arg1;
tmp_49d80_1 = (__uint128_t)(uint64_t)rdx_2;
tmp_49e00_1 = (__uint128_t)(uint32_t)64U >= (__uint128_t)128U ? (__uint128_t)0U : (__uint128_t)((__uint128_t)tmp_49d80_1 << (__uint128_t)(uint32_t)64U);
tmp_49e80_1 = (__uint128_t)(uint64_t)rax_4;
tmp_49f80_1 = (__uint128_t)((__uint128_t)tmp_49e00_1 | (__uint128_t)tmp_49e80_1);
tmp_4a080_1 = (__uint128_t)tmp_49f80_1 == (__uint128_t)((__uint128_t)0x8000000000000000U << 64U | (__uint128_t)0U) && (__uint128_t)tmp_49d00_1 == (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0xffffffffffffffffULL) ? r2sleigh_residual_u128(1) : (__uint128_t)((__int128_t)tmp_49f80_1 / (__int128_t)tmp_49d00_1);
rax_5 = (uint64_t)((__uint128_t)tmp_4a080_1 >> 0U);
(void)((__uint128_t)tmp_49d00_1 == (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0xffffffffffffffffULL) ? (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0U) : (__uint128_t)((__int128_t)tmp_49f80_1 % (__int128_t)tmp_49d00_1));
tmp_3d800_2 = (__uint128_t)(int64_t)arg0;
rdx_4 = (uint64_t)((__uint128_t)tmp_3d800_2 >> 64U);
tmp_49d00_2 = (__uint128_t)(int64_t)arg1;
tmp_49d80_2 = (__uint128_t)(uint64_t)rdx_4;
tmp_49e00_2 = (__uint128_t)(uint32_t)64U >= (__uint128_t)128U ? (__uint128_t)0U : (__uint128_t)((__uint128_t)tmp_49d80_2 << (__uint128_t)(uint32_t)64U);
tmp_49e80_2 = (__uint128_t)(uint64_t)arg0;
tmp_49f80_2 = (__uint128_t)((__uint128_t)tmp_49e00_2 | (__uint128_t)tmp_49e80_2);
(void)((__uint128_t)tmp_49f80_2 == (__uint128_t)((__uint128_t)0x8000000000000000U << 64U | (__uint128_t)0U) && (__uint128_t)tmp_49d00_2 == (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0xffffffffffffffffULL) ? r2sleigh_residual_u128(2) : (__uint128_t)((__int128_t)tmp_49f80_2 / (__int128_t)tmp_49d00_2));
tmp_4a200_2 = (__uint128_t)tmp_49d00_2 == (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0xffffffffffffffffULL) ? (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0U) : (__uint128_t)((__int128_t)tmp_49f80_2 % (__int128_t)tmp_49d00_2);
rdx_5 = (uint64_t)((__uint128_t)tmp_4a200_2 >> 0U);
rax_10 = (uint64_t)((uint64_t)rdx_5 + (uint64_t)rax_5);
} else {
rax_10 = 0;
}
{
return (uint64_t)rax_10;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000012ef
FILE=tests/fixtures/rv_O0g_stripped
CMDS=aa; pdd @ 0x000012ef
EXPECT=<<EOF
double fcn_12ef(uint64_t* arg0, uint32_t arg1)
{
uint32_t stack_m20_1;
uint64_t stack_m16_1;
__uint128_t xmm0_7;
double tmp_lane_1348_8_13_1;
__uint128_t xmm0_10;
uint64_t tmp_6b00_3;
double tmp_lane_1310_1a_c_1;
/* r2dec proof: no individual construct is marked; 41 source obligations: 34 rendered, 7 elided, 0 refused; 15 statements rendered */
{
stack_m20_1 = 0;
stack_m16_1 = 0;
for (; ; ) {
if ((uint8_t)((int32_t)stack_m20_1 < (int32_t)arg1)) {
tmp_6b00_3 = r2sleigh_load_u64((void*)((uint64_t)arg0 + (uint64_t)(int32_t)stack_m20_1 * 8U));
tmp_lane_1310_1a_c_1 = r2sleigh_float_from_bits_64(tmp_6b00_3) + r2sleigh_float_from_bits_64(stack_m16_1);
stack_m20_1 = (uint32_t)((uint32_t)stack_m20_1 + (uint32_t)1U);
stack_m16_1 = r2sleigh_float_to_bits_64(tmp_lane_1310_1a_c_1);
} else {
break;
}
}
{
if ((uint8_t)((uint32_t)arg1 == (uint32_t)0U)) {
xmm0_10 = 0;
} else {
xmm0_7 = (__uint128_t)(((__uint128_t)0U & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) | ((__uint128_t)(uint64_t)0U & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) << 64U);
tmp_lane_1348_8_13_1 = r2sleigh_float_from_bits_64(stack_m16_1) / (double)(int32_t)arg1;
xmm0_10 = (__uint128_t)(((__uint128_t)xmm0_7 & (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0U)) | ((__uint128_t)r2sleigh_float_to_bits_64(tmp_lane_1348_8_13_1) & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) << 0U);
}
{
return (double)r2sleigh_float_from_bits_64((uint64_t)xmm0_10);
}
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001362
FILE=tests/fixtures/rv_O0g_stripped
CMDS=aa; pdd @ 0x00001362
EXPECT=<<EOF
uint64_t fcn_1362(uint32_t arg0)
{
uint64_t rax_3;
uint64_t rax_6;
/* r2dec proof: no individual construct is marked; 30 source obligations: 20 rendered, 10 elided, 0 refused; 5 statements rendered */
{
if ((uint8_t)((int32_t)arg0 <= (int32_t)1U)) {
rax_6 = 1;
} else {
rax_3 = fcn_1362((uint32_t)((uint32_t)arg0 - (uint32_t)1U));
rax_6 = (uint64_t)(uint32_t)((uint64_t)((uint64_t)(int32_t)((uint64_t)rax_3 >> 0U) * (uint64_t)(int32_t)arg0) >> 0U);
}
{
return (uint64_t)rax_6;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001391
FILE=tests/fixtures/rv_O0g_stripped
CMDS=aa; pdd @ 0x00001391
EXPECT=<<EOF
uint32_t fcn_1391(uint32_t arg0)
{
uint32_t stack_m12_1;
uint32_t tmp_lane_13cf_0_7_1;
uint32_t tmp_lane_13cf_8_b_1;
/* r2dec proof: no individual construct is marked; 32 source obligations: 24 rendered, 8 elided, 0 refused; 10 statements rendered; the result's second register is open: no call read decides it */
{
stack_m12_1 = 0;
for (; ; ) {
if ((uint8_t)((int32_t)stack_m12_1 <= (int32_t)15U)) {
r2sleigh_store_u32((void*)(uint64_t)((uint64_t)((uint64_t)(int32_t)stack_m12_1 * (uint64_t)4U) + (uint64_t)0x4040U), (uint32_t)((uint64_t)((uint64_t)(uint32_t)arg0 + (uint64_t)(uint32_t)stack_m12_1) >> 0U));
stack_m12_1 = (uint32_t)((uint32_t)stack_m12_1 + (uint32_t)1U);
} else {
break;
}
}
{
tmp_lane_13cf_0_7_1 = r2sleigh_load_u32((void*)(uint64_t)0x4010U);
tmp_lane_13cf_8_b_1 = (uint32_t)((uint32_t)arg0 + (uint32_t)tmp_lane_13cf_0_7_1);
r2sleigh_store_u32((void*)(uint64_t)0x4010U, (uint32_t)tmp_lane_13cf_8_b_1);
return (uint32_t)tmp_lane_13cf_8_b_1;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000013e3
FILE=tests/fixtures/rv_O0g_stripped
CMDS=aa; pdd @ 0x000013e3
EXPECT=<<EOF
uint64_t fcn_13e3(uint8_t* arg0, uint64_t arg1, uint64_t arg2)
{
void* memcpy(void*, const void*, uint64_t);
uint64_t strlen(const char*);
uint64_t rax_2;
uint64_t stack_m16_2;
uint64_t stack_m16_1;
/* r2dec proof: no individual construct is marked; 39 source obligations: 26 rendered, 13 elided, 0 refused; 6 statements rendered; 2 callee prototypes supplied by the source; the result's second register is open: no call read decides it */
{
rax_2 = strlen((const char*)arg1);
stack_m16_2 = rax_2;
stack_m16_1 = (uint8_t)((uint64_t)stack_m16_2 < (uint64_t)arg2) ? stack_m16_2 : (uint64_t)((uint64_t)arg2 - (uint64_t)1U);
{
memcpy((void*)(uint64_t)arg0, (const void*)arg1, stack_m16_1);
r2sleigh_store_u8((void*)((uint64_t)arg0 + (uint64_t)stack_m16_1 * 1U), (uint8_t)0U);
return (uint64_t)stack_m16_1;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x0000144c
FILE=tests/fixtures/rv_O0g_stripped
CMDS=aa; pdd @ 0x0000144c
EXPECT=<<EOF
uint32_t fcn_144c(uint32_t arg0)
{
uint64_t rax_1;
uint16_t tmp_lane_144c_b_3_1;
uint64_t rax_2;
/* r2dec proof: no individual construct is marked; 17 source obligations: 10 rendered, 7 elided, 0 refused; 4 statements rendered; the result's second register is open: no call read decides it */
{
rax_1 = (uint64_t)(uint32_t)arg0;
tmp_lane_144c_b_3_1 = (uint16_t)(int8_t)((uint32_t)arg0 >> 0U);
rax_2 = (uint64_t)(((uint64_t)rax_1 & (uint64_t)0xffffffffffff0000U) | ((uint64_t)tmp_lane_144c_b_3_1 & (uint64_t)0xffffU) << 0U);
return (uint32_t)((uint32_t)((uint64_t)rax_2 >> 0U) - (uint32_t)((uint64_t)((uint64_t)rax_2 * (uint64_t)4U) >> 0U));
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x0000146d
FILE=tests/fixtures/rv_O0g_stripped
CMDS=aa; pdd @ 0x0000146d
EXPECT=<<EOF
uint32_t fcn_146d(uint32_t arg0, uint8_t arg1)
{
uint8_t tmp_63380_1;
/* r2dec proof: no individual construct is marked; 17 source obligations: 10 rendered, 7 elided, 0 refused; 2 statements rendered; the result's second register is open: no call read decides it */
{
tmp_63380_1 = (uint8_t)((uint32_t)arg1 & (uint32_t)(uint8_t)31U);
return (uint32_t)((uint32_t)((uint32_t)tmp_63380_1 >= (uint32_t)32U ? (uint32_t)0U : (uint32_t)((uint32_t)arg0 << (uint32_t)tmp_63380_1)) | (uint32_t)((uint32_t)(uint8_t)((uint32_t)(uint8_t)32U - (uint32_t)tmp_63380_1) >= (uint32_t)32U ? (uint32_t)0U : (uint32_t)((uint32_t)arg0 >> (uint32_t)(uint8_t)((uint32_t)(uint8_t)32U - (uint32_t)tmp_63380_1))));
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001489
FILE=tests/fixtures/rv_O0g_stripped
CMDS=aa; pdd @ 0x00001489
EXPECT=<<EOF
uint32_t fcn_1489(uint32_t arg0)
{
uint32_t stack_m28_1;
uint32_t stack_m12_1;
/* r2dec proof: no individual construct is marked; 27 source obligations: 20 rendered, 7 elided, 0 refused; 8 statements rendered */
{
stack_m28_1 = arg0;
stack_m12_1 = 0;
for (; ; ) {
if ((uint8_t)((uint32_t)stack_m28_1 != (uint32_t)0U)) {
stack_m28_1 = (uint32_t)((uint32_t)((uint32_t)stack_m28_1 - (uint32_t)1U) & (uint32_t)stack_m28_1);
stack_m12_1 = (uint32_t)((uint32_t)stack_m12_1 + (uint32_t)1U);
} else {
break;
}
}
{
return (uint32_t)stack_m12_1;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000014b5
FILE=tests/fixtures/rv_O0g_stripped
CMDS=aa; pdd @ 0x000014b5
EXPECT=<<EOF
uint64_t fcn_14b5(uint32_t* arg0, uint32_t arg1, uint32_t arg2)
{
uint32_t stack_m12_1;
uint32_t tmp_11f00_3;
uint32_t tmp_11f00_7;
uint64_t rax_14;
/* r2dec proof: no individual construct is marked; 45 source obligations: 37 rendered, 8 elided, 0 refused; 20 statements rendered */
{
stack_m12_1 = 0;
for (; ; ) {
if ((uint8_t)((int32_t)stack_m12_1 < (int32_t)arg1)) {
tmp_11f00_3 = r2sleigh_load_u32((void*)((uint64_t)arg0 + (uint64_t)(int32_t)stack_m12_1 * 4U));
if ((uint8_t)((uint32_t)arg2 != (uint32_t)tmp_11f00_3)) {
tmp_11f00_7 = r2sleigh_load_u32((void*)((uint64_t)arg0 + (uint64_t)(int32_t)stack_m12_1 * 4U));
if ((uint8_t)((int32_t)arg2 < (int32_t)tmp_11f00_7)) {
goto L2;
} else {
stack_m12_1 = (uint32_t)((uint32_t)stack_m12_1 + (uint32_t)1U);
}
} else {
goto L0;
}
} else {
break;
}
}
{
goto L3;
}
{
L0: ;
rax_14 = (uint64_t)(uint32_t)stack_m12_1;
goto L4;
}
{
L2: ;
}
{
L3: ;
rax_14 = (uint64_t)0xffffffffU;
}
{
L4: ;
return (uint64_t)rax_14;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001521
FILE=tests/fixtures/rv_O0g_stripped
CMDS=aa; pdd @ 0x00001521
EXPECT=<<EOF
uint64_t fcn_1521(uint64_t arg0, uint32_t arg1)
{
uint32_t tmp_lane_1521_18_2_1;
/* r2dec proof: 1 construct is marked below; 24 source obligations: 12 rendered, 10 elided, 0 refused, 2 residual; 3 statements rendered */
{
tmp_lane_1521_18_2_1 = (uint32_t)((uint64_t)((uint64_t)(uint32_t)arg1 + (uint64_t)1U) >> 0U);
((void(*)(uint64_t, uint64_t, uint64_t, uint64_t))(uint64_t)arg0)((uint64_t)(uint32_t)arg1, (uint64_t)(uint32_t)tmp_lane_1521_18_2_1, arg0, (uint64_t)(uint32_t)tmp_lane_1521_18_2_1);
return r2sleigh_residual_u64(1);
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001549
FILE=tests/fixtures/rv_O0g_stripped
CMDS=aa; pdd @ 0x00001549
EXPECT=<<EOF
uint32_t fcn_1549(uint32_t arg0, uint64_t* arg1)
{
uint32_t fcn_11a9(uint32_t, uint32_t);
uint32_t fcn_11c1(uint64_t, uint32_t);
uint64_t fcn_120a(uint32_t);
uint32_t fcn_1277(uint64_t);
uint64_t fcn_12a8(uint64_t, uint64_t);
double fcn_12ef(uint64_t, uint32_t);
uint64_t fcn_1362(uint64_t, uint64_t);
uint32_t fcn_1391(uint32_t);
uint64_t fcn_13e3(uint64_t, uint64_t, uint64_t);
uint32_t fcn_144c(uint32_t);
uint32_t fcn_146d(uint32_t, uint8_t);
uint32_t fcn_1489(uint32_t);
uint64_t fcn_14b5(uint64_t, uint32_t, uint32_t);
uint64_t fcn_1521(uint64_t, uint64_t);
int32_t printf(const char*, ...);
uint32_t tmp_11f00_1;
uint64_t rax_6;
uint64_t rax_8;
uint32_t tmp_11f00_2;
uint32_t tmp_11f00_3;
uint64_t rax_11;
uint32_t tmp_6a80_13;
uint64_t rax_13;
uint32_t tmp_6a80_20;
uint32_t tmp_11f00_4;
uint64_t rax_16;
uint64_t rax_17;
uint32_t tmp_6a80_27;
__uint128_t xmm0_7;
uint64_t tmp_lane_1549_e1_21_1;
uint32_t tmp_6a80_34;
uint64_t rax_21;
uint32_t tmp_6a80_41;
uint32_t tmp_11f00_5;
uint32_t tmp_11f00_6;
uint64_t tmp_11f80_2;
uint64_t tmp_11f80_3;
uint64_t rax_27;
uint64_t rax_28;
uint32_t tmp_6a80_48;
uint32_t tmp_11f00_7;
uint64_t rax_31;
uint32_t tmp_11f00_8;
uint64_t rax_33;
uint64_t rax_34;
uint32_t tmp_11f00_9;
uint64_t rax_38;
uint32_t tmp_11f00_10;
uint64_t rax_41;
uint32_t tmp_6a80_56;
uint32_t tmp_11f00_11;
uint32_t tmp_11f00_12;
uint32_t tmp_lane_16f0_94_4d_1;
_Alignas(16) uint8_t frame[248];
/* r2dec proof: 1 construct is marked below; 364 source obligations: 197 rendered, 95 elided, 0 refused, 5 compiler-inserted (assuming ub-free), 66 assumed (frame extent unproven), 1 residual; 106 statements rendered; 1 callee prototype supplied by the source; the result's second register is open: no call read decides it */
{
r2sleigh_store_u32((void*)(uint64_t)(frame + 28U), (uint32_t)arg0);
r2sleigh_store_u64((void*)(uint64_t)(frame + 16U), (uint64_t)arg1);
r2sleigh_store_u32((void*)(uint64_t)(frame + 48U), (uint32_t)1U);
r2sleigh_store_u32((void*)((uint64_t)(frame + 48U) + (uint64_t)4U), (uint32_t)2U);
r2sleigh_store_u32((void*)((uint64_t)(frame + 48U) + (uint64_t)8U), (uint32_t)3U);
r2sleigh_store_u32((void*)((uint64_t)(frame + 48U) + (uint64_t)12U), (uint32_t)4U);
r2sleigh_store_u32((void*)((uint64_t)(frame + 48U) + (uint64_t)16U), (uint32_t)3U);
r2sleigh_store_u64((void*)((uint64_t)(frame + 48U) + (uint64_t)24U), (uint64_t)0U);
r2sleigh_store_u64((void*)((uint64_t)(frame + 48U) + (uint64_t)32U), (uint64_t)99U);
r2sleigh_store_u32((void*)((uint64_t)(frame + 48U) + (uint64_t)48U), (uint32_t)2U);
r2sleigh_store_u64((void*)((uint64_t)(frame + 48U) + (uint64_t)56U), (uint64_t)((uint64_t)(frame + 48U) + (uint64_t)16U));
r2sleigh_store_u64((void*)((uint64_t)(frame + 48U) + (uint64_t)64U), (uint64_t)98U);
r2sleigh_store_u32((void*)((uint64_t)(frame + 48U) + (uint64_t)80U), (uint32_t)1U);
r2sleigh_store_u64((void*)((uint64_t)(frame + 48U) + (uint64_t)88U), (uint64_t)((uint64_t)(frame + 48U) + (uint64_t)48U));
r2sleigh_store_u64((void*)((uint64_t)(frame + 48U) + (uint64_t)96U), (uint64_t)97U);
r2sleigh_store_u64((void*)((uint64_t)(frame + 48U) + (uint64_t)112U), (uint64_t)0x3ff0000000000000U);
r2sleigh_store_u64((void*)((uint64_t)(frame + 48U) + (uint64_t)120U), (uint64_t)0x4004000000000000U);
r2sleigh_store_u64((void*)((uint64_t)(frame + 48U) + (uint64_t)128U), (uint64_t)0x400c000000000000U);
tmp_11f00_1 = r2sleigh_load_u32((void*)(uint64_t)(frame + 28U));
rax_6 = (uint64_t)fcn_11a9((uint32_t)tmp_11f00_1, 3);
r2sleigh_store_u32((void*)(uint64_t)(frame + 44U), (uint32_t)((uint64_t)rax_6 >> 0U));
rax_8 = (uint64_t)fcn_11c1((uint64_t)(frame + 48U), 4);
tmp_11f00_2 = r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
r2sleigh_store_u32((void*)(uint64_t)(frame + 44U), (uint32_t)((uint32_t)((uint64_t)rax_8 >> 0U) + (uint32_t)tmp_11f00_2));
tmp_11f00_3 = r2sleigh_load_u32((void*)(uint64_t)(frame + 28U));
rax_11 = fcn_120a((uint32_t)tmp_11f00_3);
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
tmp_6a80_13 = r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
r2sleigh_store_u32((void*)(uint64_t)(frame + 44U), (uint32_t)((uint32_t)((uint64_t)rax_11 >> 0U) + (uint32_t)tmp_6a80_13));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
rax_13 = (uint64_t)fcn_1277((uint64_t)((uint64_t)(frame + 48U) + (uint64_t)80U));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
tmp_6a80_20 = r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
r2sleigh_store_u32((void*)(uint64_t)(frame + 44U), (uint32_t)((uint32_t)((uint64_t)rax_13 >> 0U) + (uint32_t)tmp_6a80_20));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
tmp_11f00_4 = r2sleigh_load_u32((void*)(uint64_t)(frame + 28U));
rax_16 = (uint64_t)(int32_t)((uint64_t)((uint64_t)(int32_t)tmp_11f00_4 * (uint64_t)100U) >> 0U);
rax_17 = fcn_12a8(rax_16, 3);
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
tmp_6a80_27 = r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
r2sleigh_store_u32((void*)(uint64_t)(frame + 44U), (uint32_t)((uint32_t)((uint64_t)rax_17 >> 0U) + (uint32_t)tmp_6a80_27));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
xmm0_7 = (__uint128_t)r2sleigh_float_to_bits_64(fcn_12ef((uint64_t)((uint64_t)(frame + 48U) + (uint64_t)112U), 3));
tmp_lane_1549_e1_21_1 = (uint64_t)((__uint128_t)xmm0_7 >> 0U);
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
tmp_6a80_34 = r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
r2sleigh_store_u32((void*)(uint64_t)(frame + 44U), (uint32_t)((uint32_t)(r2sleigh_float_from_bits_64(tmp_lane_1549_e1_21_1) > -2147483649.0 && r2sleigh_float_from_bits_64(tmp_lane_1549_e1_21_1) < 2147483648.0 ? (int32_t)r2sleigh_float_from_bits_64(tmp_lane_1549_e1_21_1) : r2sleigh_residual_i32(1)) + (uint32_t)tmp_6a80_34));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
rax_21 = fcn_1362(5, 3);
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
tmp_6a80_41 = r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
r2sleigh_store_u32((void*)(uint64_t)(frame + 44U), (uint32_t)((uint32_t)((uint64_t)rax_21 >> 0U) + (uint32_t)tmp_6a80_41));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
tmp_11f00_5 = r2sleigh_load_u32((void*)(uint64_t)(frame + 28U));
fcn_1391((uint32_t)tmp_11f00_5);
tmp_11f00_6 = r2sleigh_load_u32((void*)(uint64_t)(frame + 28U));
if ((uint8_t)((int32_t)tmp_11f00_6 <= (int32_t)1U)) {
rax_27 = r2sleigh_load_u64((void*)(uint64_t)0x4018U);
} else {
tmp_11f80_2 = r2sleigh_load_u64((void*)(uint64_t)(frame + 16U));
tmp_11f80_3 = r2sleigh_load_u64((void*)((uint64_t)tmp_11f80_2 + (uint64_t)1U * 8U));
rax_27 = tmp_11f80_3;
}
{
rax_28 = fcn_13e3((uint64_t)((uint64_t)(frame + 48U) + (uint64_t)144U), rax_27, 16);
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
tmp_6a80_48 = r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
r2sleigh_store_u32((void*)(uint64_t)(frame + 44U), (uint32_t)((uint32_t)((uint64_t)rax_28 >> 0U) + (uint32_t)tmp_6a80_48));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
tmp_11f00_7 = r2sleigh_load_u32((void*)(uint64_t)(frame + 28U));
rax_31 = (uint64_t)fcn_144c((uint32_t)(int8_t)((uint32_t)tmp_11f00_7 >> 0U));
tmp_11f00_8 = r2sleigh_load_u32((void*)(uint64_t)(frame + 28U));
rax_33 = (uint64_t)fcn_146d((uint32_t)tmp_11f00_8, 3);
rax_34 = (uint64_t)fcn_1489(0xf0f0);
tmp_11f00_9 = r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
r2sleigh_store_u32((void*)(uint64_t)(frame + 44U), (uint32_t)((uint32_t)((uint64_t)((uint64_t)(uint32_t)((uint32_t)(int16_t)((uint64_t)rax_31 >> 0U) + (uint32_t)((uint64_t)rax_33 >> 0U)) + (uint64_t)rax_34) >> 0U) + (uint32_t)tmp_11f00_9));
rax_38 = fcn_14b5(0x4040, 16, 7);
tmp_11f00_10 = r2sleigh_load_u32((void*)(uint64_t)(frame + 28U));
rax_41 = fcn_1521(0x11a9, (uint64_t)(uint32_t)tmp_11f00_10);
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
tmp_6a80_56 = r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
r2sleigh_store_u32((void*)(uint64_t)(frame + 44U), (uint32_t)((uint32_t)tmp_6a80_56 + (uint32_t)((uint32_t)((uint64_t)rax_38 >> 0U) + (uint32_t)((uint64_t)rax_41 >> 0U))));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
(void)r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
tmp_11f00_11 = r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
printf("%d %s\n", (uint64_t)(uint32_t)tmp_11f00_11, (uint64_t)((uint64_t)(frame + 48U) + (uint64_t)144U));
tmp_11f00_12 = r2sleigh_load_u32((void*)(uint64_t)(frame + 44U));
tmp_lane_16f0_94_4d_1 = (uint32_t)(uint8_t)((uint32_t)tmp_11f00_12 >> 0U);
{
return (uint32_t)tmp_lane_16f0_94_4d_1;
}
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000017cc
FILE=tests/fixtures/rv_O0g_stripped
CMDS=aa; pdd @ 0x000017cc
EXPECT=<<EOF
void fcn_17cc(void)
{
/* r2dec proof: no individual construct is marked; 7 source obligations: 1 rendered, 6 elided, 0 refused; 1 statements rendered */
{
return;
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
+986
View File
@@ -0,0 +1,986 @@
# The census of rv_O2: what `aa; pdd` renders for each function `afl` lists.
# Regenerate with `scripts/census.py golden` when `afl` moves, then bless.
NAME=afl
FILE=tests/fixtures/rv_O2
CMDS=afl
EXPECT=<<EOF
0x00001000 3 27 sym._init
0x00001070 1 10 sym.imp.__cxa_finalize
0x00001080 1 10 sym.imp.strlen
0x00001090 1 10 sym.imp.__stack_chk_fail
0x000010a0 1 10 sym.imp.memcpy
0x000010b0 1 10 sym.imp.__printf_chk
0x000010c0 5 441 sym.main
0x00001280 1 37 sym._start
0x000012b0 4 34 sym.deregister_tm_clones
0x000012e0 4 51 sym.register_tm_clones
0x00001320 5 54 sym.__do_global_dtors_aux
0x00001360 1 9 sym.frame_dummy
0x00001370 1 8 sym.add
0x00001380 5 39 sym.sum_array
0x000013b0 3 27 sym.classify
0x000013d0 5 30 sym.list_len
0x00001400 3 43 sym.mul_div
0x00001430 8 78 sym.avg
0x00001490 5 31 sym.fact
0x000014c0 3 72 sym.fill
0x00001510 1 75 sym.copy_name
0x00001560 1 19 sym.sext
0x00001580 1 11 sym.rotl
0x00001590 4 29 sym.bit_count
0x000015b0 7 38 sym.find
0x000015e0 1 14 sym.dispatch
0x000015f0 1 13 sym._fini
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001000
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x00001000
EXPECT=<<EOF
uint64_t _init(void)
{
uint64_t rax_1;
uint64_t rax_2;
uint64_t rax_3;
/* r2dec proof: no individual construct is marked; 22 source obligations: 12 rendered, 10 elided, 0 refused; 6 statements rendered */
{
rax_1 = r2sleigh_load_u64((void*)(uint64_t)0x3fe8U);
if ((uint8_t)((uint64_t)rax_1 == (uint64_t)0U)) {
rax_3 = rax_1;
} else {
rax_2 = ((uint64_t(*)(void))(uint64_t)rax_1)();
rax_3 = rax_2;
}
{
return (uint64_t)rax_3;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001070
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x00001070
EXPECT=<<EOF
/* r2dec refused __cxa_finalize: r2sleigh: import stub at 0x1070; this symbol is the import `__cxa_finalize`, whose prototype nothing states. */
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001080
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x00001080
EXPECT=<<EOF
/* r2sleigh: import stub at 0x1080; this symbol is the import `strlen` and has no body of its own. */
extern uint64_t strlen(const char*);
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001090
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x00001090
EXPECT=<<EOF
/* r2sleigh: import stub at 0x1090; this symbol is the import `__stack_chk_fail` and has no body of its own. */
extern void __stack_chk_fail(void);
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000010a0
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x000010a0
EXPECT=<<EOF
/* r2sleigh: import stub at 0x10a0; this symbol is the import `memcpy` and has no body of its own. */
extern void* memcpy(void*, const void*, uint64_t);
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000010b0
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x000010b0
EXPECT=<<EOF
/* r2sleigh: import stub at 0x10b0; this symbol is the import `__printf_chk` and has no body of its own. */
extern int32_t __printf_chk(int32_t, const char*, ...);
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000010c0
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x000010c0
EXPECT=<<EOF
uint32_t fcn_10c0(uint64_t arg0, uint64_t* arg1)
{
int32_t __printf_chk(int32_t, const char*, ...);
uint32_t add(uint32_t, uint32_t);
uint64_t avg(uint64_t, uint32_t);
uint32_t bit_count(uint32_t);
uint64_t classify(uint32_t);
uint64_t copy_name(uint64_t, uint64_t, uint64_t);
uint64_t dispatch(uint64_t, uint64_t, uint64_t);
uint64_t fact(uint32_t);
uint64_t fill(uint64_t, uint64_t);
uint64_t find(uint64_t, uint32_t, uint32_t);
uint32_t list_len(uint64_t);
uint64_t mul_div(uint64_t, uint64_t);
uint32_t rotl(uint32_t, uint8_t);
uint32_t sext(uint8_t);
uint32_t sum_array(uint64_t, uint32_t);
extern char g_msg[];
uint32_t tmp_lane_10c0_b_0_1;
__uint128_t xmm0_1;
__uint128_t tmp_8eb80_1;
uint64_t tmp_lane_10c0_3b_5_1;
__uint128_t xmm0_2;
uint64_t tmp_lane_10c0_3c_6_1;
__uint128_t xmm0_3;
uint64_t rax_6;
uint64_t rax_7;
uint64_t rax_8;
uint64_t rax_9;
uint64_t rax_10;
uint64_t rax_12;
uint64_t tmp_lane_10c0_9f_1e_1;
uint64_t rbx_3;
uint64_t rsi_6;
uint64_t tmp_11f80_2;
uint64_t rsi_8;
uint64_t rax_14;
uint64_t rax_15;
uint64_t rax_16;
uint64_t rax_17;
uint64_t rax_18;
uint64_t rax_19;
uint32_t tmp_lane_11c4_63_4d_1;
uint32_t tmp_lane_11c4_70_52_1;
_Alignas(16) uint8_t frame[232];
/* r2dec proof: 2 constructs are marked below; 248 source obligations: 181 rendered, 60 elided, 0 refused, 5 compiler-inserted (assuming ub-free), 2 residual; 41 statements rendered; 1 never assigned, read as residuals (XMM0_4); 1 data object type refused; 1 callee prototype supplied by the source; the result's second register is open: no call read decides it */
/* symbol `main`; C allows that name no other prototype */
{
tmp_lane_10c0_b_0_1 = (uint32_t)((uint64_t)arg0 >> 0U);
xmm0_1 = r2sleigh_load_u128((void*)(uint64_t)0x2060U);
r2sleigh_store_u64((void*)((uint64_t)(frame + 16U) + (uint64_t)24U), (uint64_t)0U);
r2sleigh_store_u64((void*)((uint64_t)(frame + 16U) + (uint64_t)56U), (uint64_t)((uint64_t)(frame + 16U) + (uint64_t)16U));
r2sleigh_store_u64((void*)((uint64_t)(frame + 16U) + (uint64_t)88U), (uint64_t)((uint64_t)(frame + 16U) + (uint64_t)48U));
r2sleigh_store_u128((void*)(uint64_t)(frame + 16U), (__uint128_t)xmm0_1);
tmp_8eb80_1 = r2sleigh_load_u128((void*)(uint64_t)0x2070U);
tmp_lane_10c0_3b_5_1 = (uint64_t)((__uint128_t)tmp_8eb80_1 >> 0U);
xmm0_2 = (__uint128_t)(((__uint128_t)0U & (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0U)) | ((__uint128_t)tmp_lane_10c0_3b_5_1 & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) << 0U);
tmp_lane_10c0_3c_6_1 = (uint64_t)((__uint128_t)tmp_8eb80_1 >> 64U);
xmm0_3 = (__uint128_t)(((__uint128_t)xmm0_2 & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) | ((__uint128_t)tmp_lane_10c0_3c_6_1 & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffffffffffULL)) << 64U);
r2sleigh_store_u64((void*)((uint64_t)(frame + 16U) + (uint64_t)32U), (uint64_t)99U);
r2sleigh_store_u128((void*)(uint64_t)((uint64_t)(frame + 16U) + (uint64_t)112U), (__uint128_t)xmm0_3);
r2sleigh_store_u64((void*)((uint64_t)(frame + 16U) + (uint64_t)64U), (uint64_t)98U);
r2sleigh_store_u64((void*)((uint64_t)(frame + 16U) + (uint64_t)96U), (uint64_t)97U);
r2sleigh_store_u64((void*)((uint64_t)(frame + 16U) + (uint64_t)128U), (uint64_t)0x400c000000000000U);
rax_6 = (uint64_t)add((uint32_t)arg0, 3);
rax_7 = (uint64_t)sum_array((uint64_t)(frame + 16U), 4);
rax_8 = classify((uint32_t)tmp_lane_10c0_b_0_1);
rax_9 = (uint64_t)list_len((uint64_t)((uint64_t)(frame + 16U) + (uint64_t)80U));
rax_10 = mul_div((uint64_t)(int32_t)((uint64_t)((uint64_t)(int32_t)tmp_lane_10c0_b_0_1 * (uint64_t)100U) >> 0U), 3);
avg((uint64_t)((uint64_t)(frame + 16U) + (uint64_t)112U), 3);
rax_12 = fact(5);
tmp_lane_10c0_9f_1e_1 = (uint64_t)((__uint128_t)r2sleigh_residual_u128(1) >> 0U);
rbx_3 = (uint64_t)(uint32_t)((uint32_t)((uint64_t)rax_12 >> 0U) + (uint32_t)((uint32_t)((uint32_t)((uint32_t)((uint32_t)((uint32_t)((uint64_t)rax_6 >> 0U) + (uint32_t)((uint64_t)rax_7 >> 0U)) + (uint32_t)((uint64_t)rax_8 >> 0U)) + (uint32_t)((uint64_t)rax_9 >> 0U)) + (uint32_t)((uint64_t)rax_10 >> 0U)) + (uint32_t)(r2sleigh_float_from_bits_64(tmp_lane_10c0_9f_1e_1) > -2147483649.0 && r2sleigh_float_from_bits_64(tmp_lane_10c0_9f_1e_1) < 2147483648.0 ? (int32_t)r2sleigh_float_from_bits_64(tmp_lane_10c0_9f_1e_1) : r2sleigh_residual_i32(2))));
fill((uint64_t)(uint32_t)tmp_lane_10c0_b_0_1, 3);
rsi_6 = r2sleigh_load_u64((void*)&g_msg);
if ((uint8_t)((int32_t)tmp_lane_10c0_b_0_1 <= (int32_t)1U)) {
rsi_8 = rsi_6;
} else {
tmp_11f80_2 = r2sleigh_load_u64((void*)((uint64_t)arg1 + (uint64_t)1U * 8U));
rsi_8 = tmp_11f80_2;
}
{
rax_14 = copy_name((uint64_t)((uint64_t)(frame + 16U) + (uint64_t)144U), rsi_8, 16);
rax_15 = (uint64_t)sext((uint8_t)((uint64_t)arg0 >> 0U));
rax_16 = (uint64_t)rotl((uint32_t)tmp_lane_10c0_b_0_1, 3);
rax_17 = (uint64_t)bit_count(0xf0f0);
rax_18 = find(0x4040, 16, 7);
rax_19 = dispatch(0x1370, (uint64_t)(uint32_t)tmp_lane_10c0_b_0_1, 7);
tmp_lane_11c4_63_4d_1 = (uint32_t)((uint32_t)((uint64_t)rax_19 >> 0U) + (uint32_t)((uint32_t)((uint32_t)((uint32_t)((uint32_t)((uint64_t)((uint64_t)rbx_3 + (uint64_t)rax_14) >> 0U) + (uint32_t)(int16_t)((uint64_t)rax_15 >> 0U)) + (uint32_t)((uint64_t)rax_16 >> 0U)) + (uint32_t)((uint64_t)rax_17 >> 0U)) + (uint32_t)((uint64_t)rax_18 >> 0U)));
__printf_chk(2, "%d %s\n", (uint64_t)(uint32_t)tmp_lane_11c4_63_4d_1, (uint64_t)((uint64_t)(frame + 16U) + (uint64_t)144U));
tmp_lane_11c4_70_52_1 = (uint32_t)(uint8_t)((uint32_t)tmp_lane_11c4_63_4d_1 >> 0U);
{
return (uint32_t)tmp_lane_11c4_70_52_1;
}
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001280
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x00001280
EXPECT=<<EOF
void _start(void)
{
uint64_t tmp_55400_2;
uint64_t tmp_3cb80_1;
/* r2dec proof: 5 constructs are marked below; 28 source obligations: 2 rendered, 4 elided, 0 refused, 22 residual; 2 statements rendered; 1 held from entry, read as residuals (stack_p0) */
{
tmp_55400_2 = r2sleigh_residual_u64(1);
r2sleigh_residual_void(2); /* r2dec gap: StoreNotSpelled at 0x1280:29 covering 1 op (render::values) */
r2sleigh_residual_void(3); /* r2dec gap: StoreNotSpelled at 0x1280:32 covering 1 op (render::values) */
tmp_3cb80_1 = r2sleigh_load_u64((void*)(uint64_t)0x3fd8U);
r2sleigh_residual_void(4); /* r2dec gap: CallNotRendered at 0x1280:68 covering 1 op (render::values) */
r2sleigh_residual_void(5); /* r2dec gap: TailTransferNotRendered at 0x1280 (render::control) */
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000012b0
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x000012b0
EXPECT=<<EOF
uint64_t deregister_tm_clones(void)
{
uint64_t rax_2;
uint64_t rax_3;
/* r2dec proof: 1 construct is marked below; 17 source obligations: 13 rendered, 3 elided, 0 refused, 1 residual; 6 statements rendered */
{
if ((uint8_t)1U) {
rax_3 = 0x4020;
} else {
rax_2 = r2sleigh_load_u64((void*)(uint64_t)0x3fe0U);
if ((uint8_t)((uint64_t)rax_2 == (uint64_t)0U)) {
rax_3 = rax_2;
} else {
r2sleigh_residual_void(1); /* r2dec gap: UnresolvedIndirectBranch at 0x12cf (render::control) */
}
}
{
return (uint64_t)rax_3;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000012e0
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x000012e0
EXPECT=<<EOF
uint64_t register_tm_clones(void)
{
uint64_t rax_3;
uint64_t rax_4;
/* r2dec proof: 1 construct is marked below; 23 source obligations: 19 rendered, 3 elided, 0 refused, 1 residual; 6 statements rendered */
{
if ((uint8_t)1U) {
rax_4 = 0;
} else {
rax_3 = r2sleigh_load_u64((void*)(uint64_t)0x3ff0U);
if ((uint8_t)((uint64_t)rax_3 == (uint64_t)0U)) {
rax_4 = rax_3;
} else {
r2sleigh_residual_void(1); /* r2dec gap: UnresolvedIndirectBranch at 0x1310 (render::control) */
}
}
{
return (uint64_t)rax_4;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001320
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x00001320
EXPECT=<<EOF
uint64_t __do_global_dtors_aux(void)
{
void __cxa_finalize(uint64_t);
uint64_t deregister_tm_clones(void);
extern char __dso_handle[];
extern char __TMC_END__[];
uint8_t tmp_3e180_1;
uint64_t tmp_3ea80_1;
uint64_t rdi_1;
/* r2dec proof: 2 constructs are marked below; 39 source obligations: 19 rendered, 16 elided, 0 refused, 4 residual; 10 statements rendered; 2 data object types refused */
{
tmp_3e180_1 = r2sleigh_load_u8((void*)&__TMC_END__);
if ((uint8_t)((uint8_t)tmp_3e180_1 != (uint8_t)0U)) {
return r2sleigh_residual_u64(1);
} else {
tmp_3ea80_1 = r2sleigh_load_u64((void*)(uint64_t)0x3ff8U);
if ((uint8_t)((uint64_t)tmp_3ea80_1 == (uint64_t)0U)) {
} else {
rdi_1 = r2sleigh_load_u64((void*)&__dso_handle);
__cxa_finalize(rdi_1);
}
{
deregister_tm_clones();
r2sleigh_store_u8((void*)&__TMC_END__, (uint8_t)1U);
return r2sleigh_residual_u64(2);
}
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001360
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x00001360
EXPECT=<<EOF
uint64_t frame_dummy(void)
{
uint64_t register_tm_clones(void);
/* r2dec proof: no individual construct is marked; 3 source obligations: 2 rendered, 1 elided, 0 refused; 1 statements rendered */
{
return register_tm_clones();
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001370
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x00001370
EXPECT=<<EOF
uint32_t add(uint32_t arg0, uint32_t arg1)
{
/* r2dec proof: no individual construct is marked; 10 source obligations: 6 rendered, 4 elided, 0 refused; 1 statements rendered */
{
return (uint32_t)((uint64_t)((uint64_t)(uint32_t)arg0 + (uint64_t)(uint32_t)arg1) >> 0U);
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001380
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x00001380
EXPECT=<<EOF
uint32_t sum_array(uint64_t arg0, uint32_t arg1)
{
uint32_t tmp_70400_1;
uint64_t tmp_4a00_1;
uint64_t rax_2;
uint64_t rdi_1;
uint32_t tmp_11f00_3;
uint32_t tmp_lane_1398_5_6_1;
uint64_t rdi_2;
/* r2dec proof: no individual construct is marked; 44 source obligations: 36 rendered, 8 elided, 0 refused; 17 statements rendered */
{
tmp_70400_1 = arg1;
if ((uint8_t)((int32_t)tmp_70400_1 <= (int32_t)0U)) {
return 0;
} else {
tmp_4a00_1 = (uint64_t)((uint64_t)((uint64_t)(int32_t)arg1 * (uint64_t)4U) + (uint64_t)arg0);
rax_2 = 0;
rdi_1 = arg0;
for (; ; ) {
(void)r2sleigh_load_u32((void*)rdi_1);
(void)r2sleigh_load_u32((void*)rdi_1);
tmp_11f00_3 = r2sleigh_load_u32((void*)rdi_1);
tmp_lane_1398_5_6_1 = (uint32_t)((uint32_t)((uint64_t)rax_2 >> 0U) + (uint32_t)tmp_11f00_3);
rdi_2 = (uint64_t)((uint64_t)rdi_1 + (uint64_t)4U);
if ((uint8_t)((uint64_t)rdi_2 != (uint64_t)tmp_4a00_1)) {
rax_2 = (uint64_t)(uint32_t)tmp_lane_1398_5_6_1;
rdi_1 = rdi_2;
} else {
break;
}
}
{
return (uint32_t)tmp_lane_1398_5_6_1;
}
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000013b0
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x000013b0
EXPECT=<<EOF
uint64_t classify(uint32_t arg0)
{
extern char CSWTCH_12[];
uint32_t tmp_11f00_1;
uint64_t rax_4;
/* r2dec proof: no individual construct is marked; 19 source obligations: 15 rendered, 4 elided, 0 refused; 5 statements rendered; 1 data object type refused */
{
if ((uint8_t)((uint32_t)7U < (uint32_t)arg0)) {
rax_4 = (uint64_t)0xffffffffU;
} else {
tmp_11f00_1 = r2sleigh_load_u32((void*)((uint64_t)((uint64_t)(uint32_t)arg0 * (uint64_t)4U) + (uint64_t)&CSWTCH_12));
rax_4 = (uint64_t)(uint32_t)tmp_11f00_1;
}
{
return (uint64_t)rax_4;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000013d0
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x000013d0
EXPECT=<<EOF
uint32_t list_len(uint64_t arg0)
{
uint64_t rax_2;
uint64_t rdi_1;
uint64_t tmp_11f80_1;
uint64_t rdi_2;
uint32_t tmp_lane_13e0_5_4_1;
/* r2dec proof: no individual construct is marked; 34 source obligations: 27 rendered, 7 elided, 0 refused; 13 statements rendered */
{
if ((uint8_t)((uint64_t)arg0 == (uint64_t)0U)) {
return 0;
} else {
rax_2 = 0;
rdi_1 = arg0;
for (; ; ) {
tmp_11f80_1 = r2sleigh_load_u64((void*)(uint64_t)((uint64_t)rdi_1 + (uint64_t)8U));
rdi_2 = tmp_11f80_1;
tmp_lane_13e0_5_4_1 = (uint32_t)((uint32_t)((uint64_t)rax_2 >> 0U) + (uint32_t)1U);
if ((uint8_t)((uint64_t)rdi_2 != (uint64_t)0U)) {
rax_2 = (uint64_t)(uint32_t)tmp_lane_13e0_5_4_1;
rdi_1 = rdi_2;
} else {
break;
}
}
{
return (uint32_t)tmp_lane_13e0_5_4_1;
}
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001400
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x00001400
EXPECT=<<EOF
uint64_t mul_div(uint64_t arg0, uint64_t arg1)
{
uint64_t rax_3;
__uint128_t tmp_3d800_1;
uint64_t rdx_1;
__uint128_t tmp_49d00_1;
__uint128_t tmp_49d80_1;
__uint128_t tmp_49e00_1;
__uint128_t tmp_49e80_1;
__uint128_t tmp_49f80_1;
__uint128_t tmp_4a080_1;
uint64_t rax_4;
__uint128_t tmp_3d800_2;
uint64_t rdx_3;
__uint128_t tmp_49d00_2;
__uint128_t tmp_49d80_2;
__uint128_t tmp_49e00_2;
__uint128_t tmp_49e80_2;
__uint128_t tmp_49f80_2;
__uint128_t tmp_4a200_2;
uint64_t rdx_4;
uint64_t rax_8;
/* r2dec proof: 2 constructs are marked below; 38 source obligations: 31 rendered, 4 elided, 0 refused, 3 residual; 25 statements rendered */
{
if ((uint8_t)((uint64_t)arg1 == (uint64_t)0U)) {
rax_8 = 0;
} else {
rax_3 = (uint64_t)((uint64_t)((uint64_t)arg0 * (uint64_t)8U) - (uint64_t)arg0);
tmp_3d800_1 = (__uint128_t)(int64_t)rax_3;
rdx_1 = (uint64_t)((__uint128_t)tmp_3d800_1 >> 64U);
tmp_49d00_1 = (__uint128_t)(int64_t)arg1;
tmp_49d80_1 = (__uint128_t)(uint64_t)rdx_1;
tmp_49e00_1 = (__uint128_t)(uint32_t)64U >= (__uint128_t)128U ? (__uint128_t)0U : (__uint128_t)((__uint128_t)tmp_49d80_1 << (__uint128_t)(uint32_t)64U);
tmp_49e80_1 = (__uint128_t)(uint64_t)rax_3;
tmp_49f80_1 = (__uint128_t)((__uint128_t)tmp_49e00_1 | (__uint128_t)tmp_49e80_1);
tmp_4a080_1 = (__uint128_t)tmp_49f80_1 == (__uint128_t)((__uint128_t)0x8000000000000000U << 64U | (__uint128_t)0U) && (__uint128_t)tmp_49d00_1 == (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0xffffffffffffffffULL) ? r2sleigh_residual_u128(1) : (__uint128_t)((__int128_t)tmp_49f80_1 / (__int128_t)tmp_49d00_1);
rax_4 = (uint64_t)((__uint128_t)tmp_4a080_1 >> 0U);
(void)((__uint128_t)tmp_49d00_1 == (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0xffffffffffffffffULL) ? (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0U) : (__uint128_t)((__int128_t)tmp_49f80_1 % (__int128_t)tmp_49d00_1));
tmp_3d800_2 = (__uint128_t)(int64_t)arg0;
rdx_3 = (uint64_t)((__uint128_t)tmp_3d800_2 >> 64U);
tmp_49d00_2 = (__uint128_t)(int64_t)arg1;
tmp_49d80_2 = (__uint128_t)(uint64_t)rdx_3;
tmp_49e00_2 = (__uint128_t)(uint32_t)64U >= (__uint128_t)128U ? (__uint128_t)0U : (__uint128_t)((__uint128_t)tmp_49d80_2 << (__uint128_t)(uint32_t)64U);
tmp_49e80_2 = (__uint128_t)(uint64_t)arg0;
tmp_49f80_2 = (__uint128_t)((__uint128_t)tmp_49e00_2 | (__uint128_t)tmp_49e80_2);
(void)((__uint128_t)tmp_49f80_2 == (__uint128_t)((__uint128_t)0x8000000000000000U << 64U | (__uint128_t)0U) && (__uint128_t)tmp_49d00_2 == (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0xffffffffffffffffULL) ? r2sleigh_residual_u128(2) : (__uint128_t)((__int128_t)tmp_49f80_2 / (__int128_t)tmp_49d00_2));
tmp_4a200_2 = (__uint128_t)tmp_49d00_2 == (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0xffffffffffffffffULL) ? (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0U) : (__uint128_t)((__int128_t)tmp_49f80_2 % (__int128_t)tmp_49d00_2);
rdx_4 = (uint64_t)((__uint128_t)tmp_4a200_2 >> 0U);
rax_8 = (uint64_t)((uint64_t)rax_4 + (uint64_t)rdx_4);
}
{
return (uint64_t)rax_8;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001430
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x00001430
EXPECT=<<EOF
uint64_t avg(int64_t* arg0, uint32_t arg1)
{
uint32_t tmp_70400_1;
uint8_t zf_1;
uint64_t rax_1;
uint64_t rdi_1;
uint64_t rdi_2;
uint64_t rdi_3;
/* r2dec proof: 2 constructs are marked below; 49 source obligations: 37 rendered, 8 elided, 0 refused, 4 residual; 22 statements rendered */
{
tmp_70400_1 = arg1;
zf_1 = (uint8_t)((uint32_t)tmp_70400_1 == (uint32_t)0U);
if ((uint8_t)((uint32_t)(uint8_t)((int32_t)tmp_70400_1 < (int32_t)0U) | (uint32_t)zf_1)) {
if ((uint8_t)((uint32_t)zf_1 ^ (uint32_t)(uint8_t)1U)) {
} else {
return r2sleigh_residual_u64(1);
}
} else {
rax_1 = (uint64_t)((uint64_t)((uint64_t)(int32_t)arg1 * (uint64_t)8U) + (uint64_t)arg0);
if ((uint8_t)((uint32_t)((uint32_t)arg1 & (uint32_t)1U) == (uint32_t)0U)) {
rdi_2 = (uint64_t)arg0;
} else {
(void)r2sleigh_load_u64((void*)(uint64_t)arg0);
rdi_1 = (uint64_t)((uint64_t)arg0 + (uint64_t)8U);
if ((uint8_t)((uint64_t)rdi_1 == (uint64_t)rax_1)) {
goto L1;
} else {
rdi_2 = rdi_1;
}
}
for (; ; ) {
(void)r2sleigh_load_u64((void*)rdi_2);
rdi_3 = (uint64_t)((uint64_t)rdi_2 + (uint64_t)16U);
(void)r2sleigh_load_u64((void*)(uint64_t)((uint64_t)rdi_3 - (uint64_t)8U));
if ((uint8_t)((uint64_t)rdi_3 != (uint64_t)rax_1)) {
rdi_2 = rdi_3;
} else {
break;
}
}
}
{
L1: ;
return r2sleigh_residual_u64(2);
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001490
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x00001490
EXPECT=<<EOF
uint64_t fact(uint32_t arg0)
{
uint64_t rdi_1;
uint64_t rax_2;
uint64_t rdi_1_2;
uint32_t tmp_lane_14a0_4_4_1;
uint64_t rax_3;
/* r2dec proof: no individual construct is marked; 38 source obligations: 30 rendered, 8 elided, 0 refused; 13 statements rendered */
{
rdi_1 = (uint64_t)(uint32_t)arg0;
if ((uint8_t)((int32_t)arg0 <= (int32_t)1U)) {
return 1;
} else {
rax_2 = 1;
rdi_1_2 = rdi_1;
for (; ; ) {
tmp_lane_14a0_4_4_1 = (uint32_t)((uint32_t)((uint64_t)rdi_1_2 >> 0U) - (uint32_t)1U);
rax_3 = (uint64_t)(uint32_t)((uint64_t)((uint64_t)(int32_t)((uint64_t)rax_2 >> 0U) * (uint64_t)(int32_t)((uint64_t)rdi_1_2 >> 0U)) >> 0U);
if ((uint8_t)((uint32_t)tmp_lane_14a0_4_4_1 != (uint32_t)1U)) {
rax_2 = rax_3;
rdi_1_2 = (uint64_t)(uint32_t)tmp_lane_14a0_4_4_1;
} else {
break;
}
}
{
return (uint64_t)rax_3;
}
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000014c0
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x000014c0
EXPECT=<<EOF
uint64_t fill(uint32_t arg0)
{
extern char g_counter[];
__uint128_t xmm2_1;
uint64_t rax_2;
__uint128_t xmm1_2;
uint64_t rax_3;
uint32_t tmp_lane_14e8_a_9_1;
uint32_t tmp_lane_14e8_a_a_1;
uint32_t tmp_lane_14e8_a_b_1;
__uint128_t xmm1_3;
uint32_t tmp_lane_14e8_b_c_1;
uint32_t tmp_lane_14e8_b_d_1;
uint32_t tmp_lane_14e8_b_e_1;
__uint128_t xmm1_4;
uint32_t tmp_lane_14e8_c_f_1;
uint32_t tmp_lane_14e8_c_10_1;
uint32_t tmp_lane_14e8_c_11_1;
__uint128_t xmm1_5;
uint32_t tmp_lane_14e8_d_12_1;
uint32_t tmp_lane_14e8_d_13_1;
uint32_t tmp_lane_14e8_d_14_1;
uint32_t tmp_lane_14e8_e_15_1;
uint32_t tmp_lane_14e8_e_17_1;
__uint128_t xmm0_2;
uint32_t tmp_lane_14e8_f_18_1;
uint32_t tmp_lane_14e8_f_1a_1;
__uint128_t xmm0_3;
uint32_t tmp_lane_14e8_10_1b_1;
uint32_t tmp_lane_14e8_10_1d_1;
__uint128_t xmm0_4;
uint32_t tmp_lane_14e8_11_1e_1;
uint32_t tmp_lane_14e8_11_20_1;
uint32_t tmp_2c309_1;
/* r2dec proof: 1 construct is marked below; 62 source obligations: 56 rendered, 4 elided, 0 refused, 2 residual; 44 statements rendered; 1 data object type refused */
{
xmm2_1 = r2sleigh_load_u128((void*)(uint64_t)0x2050U);
rax_2 = 0x4040;
xmm1_2 = r2sleigh_load_u128((void*)(uint64_t)0x2040U);
for (; ; ) {
rax_3 = (uint64_t)((uint64_t)rax_2 + (uint64_t)16U);
tmp_lane_14e8_a_9_1 = (uint32_t)((__uint128_t)xmm1_2 >> 0U);
tmp_lane_14e8_a_a_1 = (uint32_t)((__uint128_t)xmm2_1 >> 0U);
tmp_lane_14e8_a_b_1 = (uint32_t)((uint32_t)tmp_lane_14e8_a_9_1 + (uint32_t)tmp_lane_14e8_a_a_1);
xmm1_3 = (__uint128_t)(((__uint128_t)xmm1_2 & (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0xffffffff00000000U)) | ((__uint128_t)tmp_lane_14e8_a_b_1 & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffU)) << 0U);
tmp_lane_14e8_b_c_1 = (uint32_t)((__uint128_t)xmm1_2 >> 32U);
tmp_lane_14e8_b_d_1 = (uint32_t)((__uint128_t)xmm2_1 >> 32U);
tmp_lane_14e8_b_e_1 = (uint32_t)((uint32_t)tmp_lane_14e8_b_c_1 + (uint32_t)tmp_lane_14e8_b_d_1);
xmm1_4 = (__uint128_t)(((__uint128_t)xmm1_3 & (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0xffffffffU)) | ((__uint128_t)tmp_lane_14e8_b_e_1 & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffU)) << 32U);
tmp_lane_14e8_c_f_1 = (uint32_t)((__uint128_t)xmm1_2 >> 64U);
tmp_lane_14e8_c_10_1 = (uint32_t)((__uint128_t)xmm2_1 >> 64U);
tmp_lane_14e8_c_11_1 = (uint32_t)((uint32_t)tmp_lane_14e8_c_f_1 + (uint32_t)tmp_lane_14e8_c_10_1);
xmm1_5 = (__uint128_t)(((__uint128_t)xmm1_4 & (__uint128_t)((__uint128_t)0xffffffff00000000U << 64U | (__uint128_t)0xffffffffffffffffULL)) | ((__uint128_t)tmp_lane_14e8_c_11_1 & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffU)) << 64U);
tmp_lane_14e8_d_12_1 = (uint32_t)((__uint128_t)xmm1_2 >> 96U);
tmp_lane_14e8_d_13_1 = (uint32_t)((__uint128_t)xmm2_1 >> 96U);
tmp_lane_14e8_d_14_1 = (uint32_t)((uint32_t)tmp_lane_14e8_d_12_1 + (uint32_t)tmp_lane_14e8_d_13_1);
tmp_lane_14e8_e_15_1 = (uint32_t)((__uint128_t)xmm1_2 >> 0U);
tmp_lane_14e8_e_17_1 = (uint32_t)((uint32_t)tmp_lane_14e8_e_15_1 + (uint32_t)arg0);
xmm0_2 = (__uint128_t)(((__uint128_t)xmm1_2 & (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0xffffffff00000000U)) | ((__uint128_t)tmp_lane_14e8_e_17_1 & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffU)) << 0U);
tmp_lane_14e8_f_18_1 = (uint32_t)((__uint128_t)xmm1_2 >> 32U);
tmp_lane_14e8_f_1a_1 = (uint32_t)((uint32_t)tmp_lane_14e8_f_18_1 + (uint32_t)arg0);
xmm0_3 = (__uint128_t)(((__uint128_t)xmm0_2 & (__uint128_t)((__uint128_t)0xffffffffffffffffULL << 64U | (__uint128_t)0xffffffffU)) | ((__uint128_t)tmp_lane_14e8_f_1a_1 & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffU)) << 32U);
tmp_lane_14e8_10_1b_1 = (uint32_t)((__uint128_t)xmm1_2 >> 64U);
tmp_lane_14e8_10_1d_1 = (uint32_t)((uint32_t)tmp_lane_14e8_10_1b_1 + (uint32_t)arg0);
xmm0_4 = (__uint128_t)(((__uint128_t)xmm0_3 & (__uint128_t)((__uint128_t)0xffffffff00000000U << 64U | (__uint128_t)0xffffffffffffffffULL)) | ((__uint128_t)tmp_lane_14e8_10_1d_1 & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffU)) << 64U);
tmp_lane_14e8_11_1e_1 = (uint32_t)((__uint128_t)xmm1_2 >> 96U);
tmp_lane_14e8_11_20_1 = (uint32_t)((uint32_t)tmp_lane_14e8_11_1e_1 + (uint32_t)arg0);
r2sleigh_store_u128((void*)(uint64_t)((uint64_t)rax_3 - (uint64_t)16U), (__uint128_t)(((__uint128_t)xmm0_4 & (__uint128_t)((__uint128_t)0xffffffffU << 64U | (__uint128_t)0xffffffffffffffffULL)) | ((__uint128_t)tmp_lane_14e8_11_20_1 & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffU)) << 96U));
if ((uint8_t)((uint64_t)rax_3 != (uint64_t)0x4080U)) {
rax_2 = rax_3;
xmm1_2 = (__uint128_t)(((__uint128_t)xmm1_5 & (__uint128_t)((__uint128_t)0xffffffffU << 64U | (__uint128_t)0xffffffffffffffffULL)) | ((__uint128_t)tmp_lane_14e8_d_14_1 & (__uint128_t)((__uint128_t)0U << 64U | (__uint128_t)0xffffffffU)) << 96U);
} else {
break;
}
}
{
(void)r2sleigh_load_u32((void*)&g_counter);
(void)r2sleigh_load_u32((void*)&g_counter);
tmp_2c309_1 = r2sleigh_load_u32((void*)&g_counter);
r2sleigh_store_u32((void*)&g_counter, (uint32_t)((uint32_t)tmp_2c309_1 + (uint32_t)arg0));
(void)r2sleigh_load_u32((void*)&g_counter);
(void)r2sleigh_load_u32((void*)&g_counter);
(void)r2sleigh_load_u32((void*)&g_counter);
return r2sleigh_residual_u64(1);
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001510
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x00001510
EXPECT=<<EOF
uint64_t copy_name(uint8_t* arg0, uint64_t arg1, uint64_t arg2)
{
void* memcpy(void*, const void*, uint64_t);
uint64_t strlen(const char*);
uint64_t rax_1;
uint64_t rbx_2;
/* r2dec proof: no individual construct is marked; 47 source obligations: 23 rendered, 24 elided, 0 refused; 5 statements rendered; 2 callee prototypes supplied by the source */
{
rax_1 = strlen((const char*)arg1);
rbx_2 = (uint8_t)((uint64_t)arg2 <= (uint64_t)rax_1) ? (uint64_t)((uint64_t)arg2 - (uint64_t)1U) : (uint64_t)rax_1;
memcpy((void*)(uint64_t)arg0, (const void*)arg1, rbx_2);
r2sleigh_store_u8((void*)((uint64_t)arg0 + (uint64_t)rbx_2 * 1U), (uint8_t)0U);
return (uint64_t)rbx_2;
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001560
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x00001560
EXPECT=<<EOF
uint32_t sext(uint8_t arg0)
{
uint16_t tmp_lane_1560_0_1_1;
uint64_t rax_1;
/* r2dec proof: 1 construct is marked below; 12 source obligations: 7 rendered, 4 elided, 0 refused, 1 residual; 3 statements rendered; 1 held from entry, read as residuals (RAX_0); the result's second register is open: no call read decides it */
{
tmp_lane_1560_0_1_1 = (uint16_t)(int8_t)arg0;
rax_1 = (uint64_t)(((uint64_t)r2sleigh_residual_u64(1) & (uint64_t)0xffffffffffff0000U) | ((uint64_t)tmp_lane_1560_0_1_1 & (uint64_t)0xffffU) << 0U);
return (uint32_t)((uint32_t)((uint64_t)rax_1 >> 0U) - (uint32_t)((uint64_t)((uint64_t)rax_1 * (uint64_t)4U) >> 0U));
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001580
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x00001580
EXPECT=<<EOF
uint32_t rotl(uint32_t arg0, uint8_t arg1)
{
uint8_t tmp_63380_1;
/* r2dec proof: no individual construct is marked; 11 source obligations: 7 rendered, 4 elided, 0 refused; 2 statements rendered */
{
tmp_63380_1 = (uint8_t)((uint32_t)arg1 & (uint32_t)(uint8_t)31U);
return (uint32_t)((uint32_t)((uint32_t)tmp_63380_1 >= (uint32_t)32U ? (uint32_t)0U : (uint32_t)((uint32_t)arg0 << (uint32_t)tmp_63380_1)) | (uint32_t)((uint32_t)(uint8_t)((uint32_t)(uint8_t)32U - (uint32_t)tmp_63380_1) >= (uint32_t)32U ? (uint32_t)0U : (uint32_t)((uint32_t)arg0 >> (uint32_t)(uint8_t)((uint32_t)(uint8_t)32U - (uint32_t)tmp_63380_1))));
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001590
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x00001590
EXPECT=<<EOF
uint32_t bit_count(uint32_t arg0)
{
uint64_t rdi_1;
uint64_t rdi_1_2;
uint64_t rdx_2;
uint64_t rdx_3;
uint32_t tmp_lane_15a0_f_a_1;
uint64_t rdx_4;
/* r2dec proof: no individual construct is marked; 32 source obligations: 28 rendered, 4 elided, 0 refused; 14 statements rendered */
{
rdi_1 = (uint64_t)(uint32_t)arg0;
if ((uint8_t)((uint32_t)arg0 == (uint32_t)0U)) {
rdx_4 = 0;
} else {
rdi_1_2 = rdi_1;
rdx_2 = 0;
for (; ; ) {
rdx_3 = (uint64_t)(uint32_t)((uint32_t)((uint64_t)rdx_2 >> 0U) + (uint32_t)1U);
tmp_lane_15a0_f_a_1 = (uint32_t)((uint32_t)((uint64_t)rdi_1_2 >> 0U) & (uint32_t)((uint64_t)((uint64_t)rdi_1_2 - (uint64_t)1U) >> 0U));
if ((uint8_t)((uint32_t)tmp_lane_15a0_f_a_1 != (uint32_t)0U)) {
rdi_1_2 = (uint64_t)(uint32_t)tmp_lane_15a0_f_a_1;
rdx_2 = rdx_3;
} else {
rdx_4 = rdx_3;
break;
}
}
}
{
return (uint32_t)((uint64_t)rdx_4 >> 0U);
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000015b0
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x000015b0
EXPECT=<<EOF
uint64_t find(uint32_t* arg0, uint32_t arg1, uint32_t arg2)
{
uint32_t tmp_70400_1;
uint64_t rsi_1;
uint64_t rax_2;
uint32_t tmp_11f00_1;
uint64_t rax_3;
/* r2dec proof: no individual construct is marked; 43 source obligations: 36 rendered, 7 elided, 0 refused; 17 statements rendered */
{
tmp_70400_1 = arg1;
if ((uint8_t)((int32_t)tmp_70400_1 <= (int32_t)0U)) {
} else {
rsi_1 = (uint64_t)(int32_t)arg1;
rax_2 = 0;
for (; ; ) {
tmp_11f00_1 = r2sleigh_load_u32((void*)((uint64_t)arg0 + (uint64_t)rax_2 * 4U));
if ((uint8_t)((uint32_t)tmp_11f00_1 != (uint32_t)arg2)) {
if ((uint8_t)((int32_t)arg2 < (int32_t)tmp_11f00_1)) {
goto L1;
} else {
rax_3 = (uint64_t)((uint64_t)rax_2 + (uint64_t)1U);
if ((uint8_t)((uint64_t)rax_3 == (uint64_t)rsi_1)) {
goto L1;
} else {
rax_2 = rax_3;
}
}
} else {
break;
}
}
{
return (uint64_t)rax_2;
}
}
{
L1: ;
return (uint64_t)0xffffffffU;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000015e0
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x000015e0
EXPECT=<<EOF
uint64_t dispatch(uint64_t arg0)
{
/* r2dec proof: 1 construct is marked below; 2 source obligations: 0 rendered, 1 elided, 0 refused, 1 residual; 0 statements rendered */
{
r2sleigh_residual_void(1); /* r2dec gap: UnresolvedIndirectBranch at 0x15e0 (render::control) */
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000015f0
FILE=tests/fixtures/rv_O2
CMDS=aa; pdd @ 0x000015f0
EXPECT=<<EOF
void _fini(void)
{
/* r2dec proof: no individual construct is marked; 7 source obligations: 1 rendered, 6 elided, 0 refused; 1 statements rendered */
{
return;
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+116
View File
@@ -0,0 +1,116 @@
# The census of syscalls_static_O2: what `aa; pdd` renders for each function `afl` lists.
# Regenerate with `scripts/census.py golden` when `afl` moves, then bless.
NAME=afl
FILE=tests/fixtures/syscalls_static_O2
CMDS=afl
EXPECT=<<EOF
0x00401000 1 12 fcn.00401000
0x00401010 2 19 fcn.00401010
0x00401030 1 26 fcn.00401030
0x00401050 1 10 fcn.00401050
0x00401060 1 44 entry0
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00401000
FILE=tests/fixtures/syscalls_static_O2
CMDS=aa; pdd @ 0x00401000
EXPECT=<<EOF
uint64_t fcn_401000(void)
{
/* r2dec proof: 2 constructs are marked below; 7 source obligations: 0 rendered, 4 elided, 0 refused, 3 residual; 1 statements rendered */
{
r2sleigh_residual_void(1); /* r2dec gap: UserOperation(syscall) at 0x401000:13 covering 1 op (render::values) */
return r2sleigh_residual_u64(2);
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00401010
FILE=tests/fixtures/syscalls_static_O2
CMDS=aa; pdd @ 0x00401010
EXPECT=<<EOF
uint64_t fcn_401010(void)
{
/* r2dec proof: 2 constructs are marked below; 8 source obligations: 1 rendered, 4 elided, 0 refused, 3 residual; 1 statements rendered */
{
{
r2sleigh_residual_void(1); /* r2dec gap: UserOperation(syscall) at 0x401019:13 covering 1 op (render::values) */
return r2sleigh_residual_u64(2);
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00401030
FILE=tests/fixtures/syscalls_static_O2
CMDS=aa; pdd @ 0x00401030
EXPECT=<<EOF
uint64_t fcn_401030(void)
{
/* r2dec proof: 2 constructs are marked below; 7 source obligations: 0 rendered, 4 elided, 0 refused, 3 residual; 1 statements rendered */
{
r2sleigh_residual_void(1); /* r2dec gap: UserOperation(syscall) at 0x401030:20 covering 1 op (render::values) */
return r2sleigh_residual_u64(2);
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00401050
FILE=tests/fixtures/syscalls_static_O2
CMDS=aa; pdd @ 0x00401050
EXPECT=<<EOF
uint64_t fcn_401050(void)
{
/* r2dec proof: no individual construct is marked; 7 source obligations: 3 rendered, 4 elided, 0 refused; 1 statements rendered */
{
return 0x50f;
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00401060
FILE=tests/fixtures/syscalls_static_O2
CMDS=aa; pdd @ 0x00401060
EXPECT=<<EOF
uint64_t entry0(void)
{
uint64_t fcn_401000(uint64_t);
uint64_t fcn_401010(uint64_t);
uint64_t fcn_401030(void);
uint64_t fcn_401050(void);
/* r2dec proof: 2 constructs are marked below; 35 source obligations: 16 rendered, 16 elided, 0 refused, 3 residual; 5 statements rendered */
{
fcn_401000(102);
fcn_401010(3);
fcn_401030();
fcn_401050();
r2sleigh_residual_void(1); /* r2dec gap: UserOperation(syscall) at 0x401060:65 covering 1 op (render::values) */
return r2sleigh_residual_u64(2);
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
+389
View File
@@ -0,0 +1,389 @@
# The census of two_units_O0g: what `aa; pdd` renders for each function `afl` lists.
# Regenerate with `scripts/census.py golden` when `afl` moves, then bless.
NAME=afl
FILE=tests/fixtures/two_units_O0g
CMDS=afl
EXPECT=<<EOF
0x00001000 3 27 sym._init
0x00001040 1 10 sym.imp.__cxa_finalize
0x00001050 1 10 sym.imp.__stack_chk_fail
0x00001060 1 37 sym._start
0x00001090 4 34 sym.deregister_tm_clones
0x000010c0 4 51 sym.register_tm_clones
0x00001100 5 54 sym.__do_global_dtors_aux
0x00001140 1 9 sym.frame_dummy
0x00001149 1 24 sym.helper
0x00001161 1 27 sym.from_a
0x0000117c 4 94 sym.helper
0x000011da 1 41 sym.from_b
0x00001203 3 123 sym.main
0x00001280 1 13 sym._fini
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001000
FILE=tests/fixtures/two_units_O0g
CMDS=aa; pdd @ 0x00001000
EXPECT=<<EOF
uint64_t _init(void)
{
uint64_t rax_1;
uint64_t rax_2;
uint64_t rax_3;
/* r2dec proof: no individual construct is marked; 22 source obligations: 12 rendered, 10 elided, 0 refused; 6 statements rendered */
{
rax_1 = r2sleigh_load_u64((void*)(uint64_t)0x3fe8U);
if ((uint8_t)((uint64_t)rax_1 == (uint64_t)0U)) {
rax_3 = rax_1;
} else {
rax_2 = ((uint64_t(*)(void))(uint64_t)rax_1)();
rax_3 = rax_2;
}
{
return (uint64_t)rax_3;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001040
FILE=tests/fixtures/two_units_O0g
CMDS=aa; pdd @ 0x00001040
EXPECT=<<EOF
/* r2dec refused __cxa_finalize: r2sleigh: import stub at 0x1040; this symbol is the import `__cxa_finalize`, whose prototype nothing states. */
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001050
FILE=tests/fixtures/two_units_O0g
CMDS=aa; pdd @ 0x00001050
EXPECT=<<EOF
/* r2sleigh: import stub at 0x1050; this symbol is the import `__stack_chk_fail` and has no body of its own. */
extern void __stack_chk_fail(void);
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001060
FILE=tests/fixtures/two_units_O0g
CMDS=aa; pdd @ 0x00001060
EXPECT=<<EOF
void _start(void)
{
uint64_t tmp_55400_2;
uint64_t tmp_3cb80_1;
/* r2dec proof: 5 constructs are marked below; 28 source obligations: 2 rendered, 4 elided, 0 refused, 22 residual; 2 statements rendered; 1 held from entry, read as residuals (stack_p0) */
{
tmp_55400_2 = r2sleigh_residual_u64(1);
r2sleigh_residual_void(2); /* r2dec gap: StoreNotSpelled at 0x1060:29 covering 1 op (render::values) */
r2sleigh_residual_void(3); /* r2dec gap: StoreNotSpelled at 0x1060:32 covering 1 op (render::values) */
tmp_3cb80_1 = r2sleigh_load_u64((void*)(uint64_t)0x3fd8U);
r2sleigh_residual_void(4); /* r2dec gap: CallNotRendered at 0x1060:68 covering 1 op (render::values) */
r2sleigh_residual_void(5); /* r2dec gap: TailTransferNotRendered at 0x1060 (render::control) */
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001090
FILE=tests/fixtures/two_units_O0g
CMDS=aa; pdd @ 0x00001090
EXPECT=<<EOF
uint64_t deregister_tm_clones(void)
{
uint64_t rax_2;
uint64_t rax_3;
/* r2dec proof: 1 construct is marked below; 17 source obligations: 13 rendered, 3 elided, 0 refused, 1 residual; 6 statements rendered */
{
if ((uint8_t)1U) {
rax_3 = 0x4010;
} else {
rax_2 = r2sleigh_load_u64((void*)(uint64_t)0x3fe0U);
if ((uint8_t)((uint64_t)rax_2 == (uint64_t)0U)) {
rax_3 = rax_2;
} else {
r2sleigh_residual_void(1); /* r2dec gap: UnresolvedIndirectBranch at 0x10af (render::control) */
}
}
{
return (uint64_t)rax_3;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000010c0
FILE=tests/fixtures/two_units_O0g
CMDS=aa; pdd @ 0x000010c0
EXPECT=<<EOF
uint64_t register_tm_clones(void)
{
uint64_t rax_3;
uint64_t rax_4;
/* r2dec proof: 1 construct is marked below; 23 source obligations: 19 rendered, 3 elided, 0 refused, 1 residual; 6 statements rendered */
{
if ((uint8_t)1U) {
rax_4 = 0;
} else {
rax_3 = r2sleigh_load_u64((void*)(uint64_t)0x3ff0U);
if ((uint8_t)((uint64_t)rax_3 == (uint64_t)0U)) {
rax_4 = rax_3;
} else {
r2sleigh_residual_void(1); /* r2dec gap: UnresolvedIndirectBranch at 0x10f0 (render::control) */
}
}
{
return (uint64_t)rax_4;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001100
FILE=tests/fixtures/two_units_O0g
CMDS=aa; pdd @ 0x00001100
EXPECT=<<EOF
uint64_t __do_global_dtors_aux(void)
{
void __cxa_finalize(uint64_t);
uint64_t deregister_tm_clones(void);
extern char __dso_handle[];
extern char __TMC_END__[];
uint8_t tmp_3e180_1;
uint64_t tmp_3ea80_1;
uint64_t rdi_1;
/* r2dec proof: 2 constructs are marked below; 39 source obligations: 19 rendered, 16 elided, 0 refused, 4 residual; 10 statements rendered; 2 data object types refused */
{
tmp_3e180_1 = r2sleigh_load_u8((void*)&__TMC_END__);
if ((uint8_t)((uint8_t)tmp_3e180_1 != (uint8_t)0U)) {
return r2sleigh_residual_u64(1);
} else {
tmp_3ea80_1 = r2sleigh_load_u64((void*)(uint64_t)0x3ff8U);
if ((uint8_t)((uint64_t)tmp_3ea80_1 == (uint64_t)0U)) {
} else {
rdi_1 = r2sleigh_load_u64((void*)&__dso_handle);
__cxa_finalize(rdi_1);
}
{
deregister_tm_clones();
r2sleigh_store_u8((void*)&__TMC_END__, (uint8_t)1U);
return r2sleigh_residual_u64(2);
}
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001140
FILE=tests/fixtures/two_units_O0g
CMDS=aa; pdd @ 0x00001140
EXPECT=<<EOF
uint64_t frame_dummy(void)
{
uint64_t register_tm_clones(void);
/* r2dec proof: no individual construct is marked; 3 source obligations: 2 rendered, 1 elided, 0 refused; 1 statements rendered */
{
return register_tm_clones();
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001149
FILE=tests/fixtures/two_units_O0g
CMDS=aa; pdd @ 0x00001149
EXPECT=<<EOF
int32_t helper(int32_t value)
{
_Alignas(16) uint8_t frame[40];
/* r2dec proof: no individual construct is marked; 15 source obligations: 6 rendered, 9 elided, 0 refused; 2 statements rendered */
{
r2sleigh_store_u32((void*)(uint64_t)(frame + 28U), (uint32_t)((uint32_t)value + (uint32_t)value));
return (int32_t)r2sleigh_load_u32((void*)(uint64_t)(frame + 28U));
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001161
FILE=tests/fixtures/two_units_O0g
CMDS=aa; pdd @ 0x00001161
EXPECT=<<EOF
int32_t from_a(int32_t value)
{
int32_t helper(int32_t);
uint64_t rax_2;
/* r2dec proof: no individual construct is marked; 17 source obligations: 7 rendered, 10 elided, 0 refused; 2 statements rendered; 1 callee prototype supplied by the source */
{
rax_2 = (uint64_t)(uint32_t)helper((int32_t)value);
return (int32_t)rax_2;
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x0000117c
FILE=tests/fixtures/two_units_O0g
CMDS=aa; pdd @ 0x0000117c
EXPECT=<<EOF
double helper(const double* values, int64_t count)
{
uint64_t tmp_11f80_1;
uint64_t tmp_11f80_3;
uint64_t tmp_6b00_5;
uint64_t tmp_6b00_6;
uint64_t tmp_6b00_10;
_Alignas(16) uint8_t frame[40];
/* r2dec proof: no individual construct is marked; 42 source obligations: 27 rendered, 15 elided, 0 refused; 13 statements rendered */
{
r2sleigh_store_u64((void*)(uint64_t)(frame + 16U), (uint64_t)0U);
r2sleigh_store_u64((void*)(uint64_t)(frame + 24U), (uint64_t)0U);
for (; ; ) {
tmp_11f80_1 = r2sleigh_load_u64((void*)(uint64_t)(frame + 24U));
if ((uint8_t)((int64_t)tmp_11f80_1 < (int64_t)count)) {
tmp_11f80_3 = r2sleigh_load_u64((void*)(uint64_t)(frame + 24U));
tmp_6b00_5 = r2sleigh_load_u64((void*)((uint64_t)values + (uint64_t)tmp_11f80_3 * 8U));
tmp_6b00_6 = r2sleigh_load_u64((void*)(uint64_t)(frame + 16U));
r2sleigh_store_u64((void*)(uint64_t)(frame + 16U), (uint64_t)r2sleigh_float_to_bits_64(r2sleigh_float_from_bits_64(tmp_6b00_5) + r2sleigh_float_from_bits_64(tmp_6b00_6)));
tmp_6b00_10 = r2sleigh_load_u64((void*)(uint64_t)(frame + 24U));
r2sleigh_store_u64((void*)(uint64_t)(frame + 24U), (uint64_t)((uint64_t)tmp_6b00_10 + (uint64_t)1U));
} else {
break;
}
}
{
return (double)r2sleigh_float_from_bits_64(r2sleigh_load_u64((void*)(uint64_t)(frame + 16U)));
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x000011da
FILE=tests/fixtures/two_units_O0g
CMDS=aa; pdd @ 0x000011da
EXPECT=<<EOF
double from_b(const double* values, int64_t count)
{
double helper(const double*, int64_t);
__uint128_t xmm0_1;
/* r2dec proof: no individual construct is marked; 19 source obligations: 9 rendered, 10 elided, 0 refused; 2 statements rendered; 1 callee prototype supplied by the source */
{
xmm0_1 = (__uint128_t)r2sleigh_float_to_bits_64(helper(values, count));
return (double)r2sleigh_float_from_bits_64((uint64_t)xmm0_1);
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001203
FILE=tests/fixtures/two_units_O0g
CMDS=aa; pdd @ 0x00001203
EXPECT=<<EOF
int32_t main(int32_t argc, char** argv)
{
int32_t from_a(int32_t);
double from_b(const double*, int64_t);
uint32_t tmp_11f00_1;
uint32_t tmp_11f00_2;
uint64_t rax_4;
__uint128_t xmm0_6;
uint64_t tmp_lane_1203_44_e_1;
uint32_t tmp_lane_1203_48_12_1;
_Alignas(16) uint8_t frame[88];
/* r2dec proof: 1 construct is marked below; 56 source obligations: 31 rendered, 19 elided, 0 refused, 5 compiler-inserted (assuming ub-free), 1 residual; 11 statements rendered; 2 callee prototypes supplied by the source */
{
r2sleigh_store_u32((void*)(uint64_t)(frame + 28U), (uint32_t)argc);
r2sleigh_store_u64((void*)(uint64_t)(frame + 16U), (uint64_t)argv);
r2sleigh_store_u64((void*)(uint64_t)(frame + 32U), (uint64_t)0x3ff0000000000000U);
tmp_11f00_1 = r2sleigh_load_u32((void*)(uint64_t)(frame + 28U));
r2sleigh_store_u64((void*)((uint64_t)(frame + 32U) + (uint64_t)8U), (uint64_t)r2sleigh_float_to_bits_64((double)(int32_t)tmp_11f00_1));
tmp_11f00_2 = r2sleigh_load_u32((void*)(uint64_t)(frame + 28U));
rax_4 = (uint64_t)(uint32_t)from_a((int32_t)tmp_11f00_2);
xmm0_6 = (__uint128_t)r2sleigh_float_to_bits_64(from_b((const double*)(uint64_t)(frame + 32U), 2));
tmp_lane_1203_44_e_1 = (uint64_t)((__uint128_t)xmm0_6 >> 0U);
tmp_lane_1203_48_12_1 = (uint32_t)((uint32_t)((uint64_t)rax_4 >> 0U) + (uint32_t)(r2sleigh_float_from_bits_64(tmp_lane_1203_44_e_1) > -2147483649.0 && r2sleigh_float_from_bits_64(tmp_lane_1203_44_e_1) < 2147483648.0 ? (int32_t)r2sleigh_float_from_bits_64(tmp_lane_1203_44_e_1) : r2sleigh_residual_i32(1)));
{
return (int32_t)tmp_lane_1203_48_12_1;
}
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
NAME=0x00001280
FILE=tests/fixtures/two_units_O0g
CMDS=aa; pdd @ 0x00001280
EXPECT=<<EOF
void _fini(void)
{
/* r2dec proof: no individual construct is marked; 7 source obligations: 1 rendered, 6 elided, 0 refused; 1 statements rendered */
{
return;
}
}
EOF
EXPECT_ERR=<<EOF
EOF
RUN
+389
View File
@@ -0,0 +1,389 @@
# The listing, pinned on one binary per architecture the tree carries.
#
# `pd` rewrites one formatted string by successive substitutions, so these pin the spellings the
# rewriting is meant to keep. Two are ours and not radare2's: `nop word ptr cs:[rax + rax*0x1]` (the
# rule that drops `ptr` matches ` ptr [`, and this operand has a segment between), and a 64-bit
# immediate written signed, as Sleigh writes it.
# x86-64: the `ptr` and displacement spellings, and `jz` printed as `jne`'s comparison.
NAME=x86 listing
FILE=tests/coverage/pinned/hashes_gcc_x64_O2
CMDS=s 0x401330; pd 24
EXPECT=<<EOF
0x00401330 f30f1efa endbr64
0x00401334 4885f6 test rsi, rsi
0x00401337 7427 je 0x401360
0x00401339 4801fe add rsi, rdi
0x0040133c b8c59d1c81 mov eax, 0x811c9dc5
0x00401341 0f1f800000.. nop dword [rax]
0x00401348 0fb617 movzx edx, byte [rdi]
0x0040134b 4883c701 add rdi, 0x1
0x0040134f 31d0 xor eax, edx
0x00401351 69c093010001 imul eax, eax, 0x1000193
0x00401357 4839fe cmp rsi, rdi
0x0040135a 75ec jne 0x401348
0x0040135c c3 ret
0x0040135d 0f1f00 nop dword [rax]
0x00401360 b8c59d1c81 mov eax, 0x811c9dc5
0x00401365 c3 ret
0x00401366 662e0f1f84.. nop word cs:[rax + rax]
0x00401370 f30f1efa endbr64
0x00401374 48b8252322.. mov rax, -0x340d631b7bdddcdb
0x0040137e 4885f6 test rsi, rsi
0x00401381 7420 je 0x4013a3
0x00401383 48b9b30100.. mov rcx, 0x100000001b3
0x0040138d 4801fe add rsi, rdi
0x00401390 0fb617 movzx edx, byte [rdi]
EOF
RUN
# A call through a relocated slot, a jump through an unnamed one, and a compare against a data byte.
NAME=what a line reads
FILE=tests/coverage/pinned/hashes_gcc_x64_O2
CMDS=s 0x401000; pd 24
EXPECT=<<EOF
0x00401000 f30f1efa endbr64
0x00401004 4883ec08 sub rsp, 0x8
0x00401008 488b05d12f.. mov rax, qword [reloc.__gmon_start__]
0x0040100f 4885c0 test rax, rax
0x00401012 7402 je 0x401016
0x00401014 ffd0 call rax
0x00401016 4883c408 add rsp, 0x8
0x0040101a c3 ret
0x0040101b 0000 add byte [rax], al
0x0040101d 0000 add byte [rax], al
0x0040101f 00ff add bh, bh
0x00401021 35ca2f0000 xor eax, 0x2fca
0x00401026 ff25cc2f0000 jmp qword [0x403ff8]
0x0040102c 0f1f4000 nop dword [rax]
0x00401030 f30f1efa endbr64
0x00401034 6800000000 push 0x0
0x00401039 e9e2ffffff jmp 0x401020
0x0040103e 6690 nop
0x00401040 f30f1efa endbr64
0x00401044 ff25b62f0000 jmp qword [reloc.__printf_chk]
0x0040104a 660f1f440000 nop word [rax + rax]
0x00401050 f30f1efa endbr64
0x00401054 4883ec08 sub rsp, 0x8
0x00401058 be3d000000 mov esi, 0x3d
EOF
RUN
# No range that is one value the instruction fixes, each note ending in its rung.
NAME=what the engine proved
FILE=tests/coverage/pinned/hashes_gcc_x64_O2
CMDS=s 0x401330; pdf; s 0x401530; pdf
EXPECT=<<EOF
0x00401330 f30f1efa endbr64
0x00401334 4885f6 test rsi, rsi
0x00401337 7427 je 0x401360
0x00401339 4801fe add rsi, rdi
0x0040133c b8c59d1c81 mov eax, 0x811c9dc5
0x00401341 0f1f800000.. nop dword [rax]
0x00401348 0fb617 movzx edx, byte [rdi] ; loop: latches 0x401348, exits 0x40135c (certified) ; induction rdi = rdi@entry, +0x1 per trip (certified) ; trips rsi@entry (solved)
0x0040134b 4883c701 add rdi, 0x1
0x0040134f 31d0 xor eax, edx
0x00401351 69c093010001 imul eax, eax, 0x1000193
0x00401357 4839fe cmp rsi, rdi
0x0040135a 75ec jne 0x401348
0x0040135c c3 ret ; returns rax (certified)
0x00401360 b8c59d1c81 mov eax, 0x811c9dc5
0x00401365 c3 ret ; returns rax (certified)
0x00401530 f30f1efa endbr64
0x00401534 4885f6 test rsi, rsi
0x00401537 7440 je 0x401579
0x00401539 4801fe add rsi, rdi
0x0040153c b8ffffffff mov eax, 0xffffffff
0x00401541 0f1f800000.. nop dword [rax]
0x00401548 0fb617 movzx edx, byte [rdi] ; loop: latches 0x40156d, exits 0x401576 (certified) ; induction rdi = rdi@entry, +0x1 per trip (certified) ; trips rsi@entry (solved)
0x0040154b 31d0 xor eax, edx
0x0040154d ba08000000 mov edx, 0x8
0x00401552 660f1f440000 nop word [rax + rax]
0x00401558 89c1 mov ecx, eax ; loop: latches 0x401558, exits 0x40156d (certified)
0x0040155a 83e001 and eax, 0x1 ; defines rax in [0x0, 0x1] (decoded)
0x0040155d f7d8 neg eax
0x0040155f d1e9 shr ecx, 0x1 ; defines rcx in [0x0, 0x7fffffff] (decoded)
0x00401561 252083b8ed and eax, 0xedb88320 ; defines rax in [0x0, 0xedb88320] (decoded)
0x00401566 31c8 xor eax, ecx
0x00401568 83ea01 sub edx, 0x1
0x0040156b 75eb jne 0x401558
0x0040156d 4883c701 add rdi, 0x1
0x00401571 4839f7 cmp rdi, rsi
0x00401574 75d2 jne 0x401548
0x00401576 f7d0 not eax
0x00401578 c3 ret ; returns rax (certified)
0x00401579 31c0 xor eax, eax
0x0040157b c3 ret ; returns rax (certified)
EOF
RUN
# Each arm of the tail switch labelled with the cases the dispatch sends there.
NAME=siphash24 cases
FILE=tests/coverage/pinned/hashes_gcc_x64_O2
CMDS=s sym.siphash24; pdf
EXPECT=<<EOF
0x004018b0 f30f1efa endbr64
0x004018b4 48b8756573.. mov rax, 0x736f6d6570736575
0x004018be 4989f0 mov r8, rsi
0x004018c1 48be617265.. mov rsi, 0x6c7967656e657261
0x004018cb 49bb6d6f64.. mov r11, 0x646f72616e646f6d
0x004018d5 4d89c2 mov r10, r8
0x004018d8 4831d0 xor rax, rdx
0x004018db 4831f2 xor rdx, rsi
0x004018de 4931cb xor r11, rcx
0x004018e1 48be736574.. mov rsi, 0x7465646279746573
0x004018eb 4983e2f8 and r10, -0x8 ; defines r10 in [0x0, 0xfffffffffffffff8] (decoded)
0x004018ef 4831f1 xor rcx, rsi
0x004018f2 4901fa add r10, rdi
0x004018f5 4c89c6 mov rsi, r8
0x004018f8 48c1e638 shl rsi, 0x38
0x004018fc 4c39d7 cmp rdi, r10
0x004018ff 7479 je 0x40197a
0x00401901 0f1f800000.. nop dword [rax]
0x00401908 4c8b0f mov r9, qword [rdi] ; loop: latches 0x401908, exits 0x40197a (certified) ; induction rdi = rdi@entry, +0x8 per trip (certified)
0x0040190b 4c01d8 add rax, r11
0x0040190e 49c1c30d rol r11, 0xd
0x00401912 4883c708 add rdi, 0x8
0x00401916 4931c3 xor r11, rax
0x00401919 48c1c020 rol rax, 0x20
0x0040191d 4c31c9 xor rcx, r9
0x00401920 4801ca add rdx, rcx
0x00401923 48c1c110 rol rcx, 0x10
0x00401927 4831d1 xor rcx, rdx
0x0040192a 4c01da add rdx, r11
0x0040192d 49c1c311 rol r11, 0x11
0x00401931 4801c8 add rax, rcx
0x00401934 48c1c115 rol rcx, 0x15
0x00401938 4931d3 xor r11, rdx
0x0040193b 4831c1 xor rcx, rax
0x0040193e 48c1c220 rol rdx, 0x20
0x00401942 4c01d8 add rax, r11
0x00401945 4801ca add rdx, rcx
0x00401948 49c1c30d rol r11, 0xd
0x0040194c 48c1c110 rol rcx, 0x10
0x00401950 4931c3 xor r11, rax
0x00401953 48c1c020 rol rax, 0x20
0x00401957 4831d1 xor rcx, rdx
0x0040195a 4c01da add rdx, r11
0x0040195d 49c1c311 rol r11, 0x11
0x00401961 4801c8 add rax, rcx
0x00401964 48c1c115 rol rcx, 0x15
0x00401968 4931d3 xor r11, rdx
0x0040196b 4831c1 xor rcx, rax
0x0040196e 48c1c220 rol rdx, 0x20
0x00401972 4c31c8 xor rax, r9
0x00401975 4939fa cmp r10, rdi
0x00401978 758e jne 0x401908
0x0040197a 4183e007 and r8d, 0x7 ; defines r8 in [0x0, 0x7] (decoded)
0x0040197e 3e42ff24c5.. jmp qword ds:[0x402020 + r8*0x8] ; switch table (8 cases) at 0x402020 (solved)
;-- case 7: ; from 0x0040197e
0x00401990 410fb67a06 movzx edi, byte [r10 + 0x6]
0x00401995 48c1e730 shl rdi, 0x30
0x00401999 4809fe or rsi, rdi
;-- case 6: ; from 0x0040197e
0x0040199c 410fb67a05 movzx edi, byte [r10 + 0x5]
0x004019a1 48c1e728 shl rdi, 0x28
0x004019a5 4809fe or rsi, rdi
;-- case 5: ; from 0x0040197e
0x004019a8 410fb67a04 movzx edi, byte [r10 + 0x4]
0x004019ad 48c1e720 shl rdi, 0x20
0x004019b1 4809fe or rsi, rdi
;-- case 4: ; from 0x0040197e
0x004019b4 410fb67a03 movzx edi, byte [r10 + 0x3]
0x004019b9 48c1e718 shl rdi, 0x18
0x004019bd 4809fe or rsi, rdi
;-- case 3: ; from 0x0040197e
0x004019c0 410fb67a02 movzx edi, byte [r10 + 0x2]
0x004019c5 48c1e710 shl rdi, 0x10
0x004019c9 4809fe or rsi, rdi
;-- case 2: ; from 0x0040197e
0x004019cc 410fb67a01 movzx edi, byte [r10 + 0x1]
0x004019d1 48c1e708 shl rdi, 0x8
0x004019d5 4809fe or rsi, rdi
;-- case 1: ; from 0x0040197e
0x004019d8 410fb63a movzx edi, byte [r10]
0x004019dc 4809fe or rsi, rdi
;-- case 0: ; from 0x0040197e
0x004019df 4831f1 xor rcx, rsi
0x004019e2 4a8d3c18 lea rdi, [rax + r11]
0x004019e6 49c1c30d rol r11, 0xd
0x004019ea 4801ca add rdx, rcx
0x004019ed 4889f8 mov rax, rdi
0x004019f0 48c1c110 rol rcx, 0x10
0x004019f4 4931fb xor r11, rdi
0x004019f7 4831d1 xor rcx, rdx
0x004019fa 48c1c020 rol rax, 0x20
0x004019fe 4c01da add rdx, r11
0x00401a01 488d3c08 lea rdi, [rax + rcx]
0x00401a05 4c89d8 mov rax, r11
0x00401a08 48c1c115 rol rcx, 0x15
0x00401a0c 48c1c011 rol rax, 0x11
0x00401a10 4831f9 xor rcx, rdi
0x00401a13 4831d0 xor rax, rdx
0x00401a16 48c1c220 rol rdx, 0x20
0x00401a1a 4801c7 add rdi, rax
0x00401a1d 4801ca add rdx, rcx
0x00401a20 48c1c00d rol rax, 0xd
0x00401a24 48c1c110 rol rcx, 0x10
0x00401a28 4831f8 xor rax, rdi
0x00401a2b 48c1c720 rol rdi, 0x20
0x00401a2f 4831d1 xor rcx, rdx
0x00401a32 4801c2 add rdx, rax
0x00401a35 48c1c011 rol rax, 0x11
0x00401a39 4801cf add rdi, rcx
0x00401a3c 4831d0 xor rax, rdx
0x00401a3f 48c1c115 rol rcx, 0x15
0x00401a43 4831fe xor rsi, rdi
0x00401a46 48c1c220 rol rdx, 0x20
0x00401a4a 4831f9 xor rcx, rdi
0x00401a4d 4801c6 add rsi, rax
0x00401a50 80f2ff xor dl, 0xff
0x00401a53 48c1c00d rol rax, 0xd
0x00401a57 4831f0 xor rax, rsi
0x00401a5a 48c1c620 rol rsi, 0x20
0x00401a5e 4801ca add rdx, rcx
0x00401a61 48c1c110 rol rcx, 0x10
0x00401a65 4831d1 xor rcx, rdx
0x00401a68 4801c2 add rdx, rax
0x00401a6b 48c1c011 rol rax, 0x11
0x00401a6f 4801ce add rsi, rcx
0x00401a72 48c1c115 rol rcx, 0x15
0x00401a76 4831d0 xor rax, rdx
0x00401a79 4831f1 xor rcx, rsi
0x00401a7c 48c1c220 rol rdx, 0x20
0x00401a80 4801c6 add rsi, rax
0x00401a83 4801ca add rdx, rcx
0x00401a86 48c1c00d rol rax, 0xd
0x00401a8a 48c1c110 rol rcx, 0x10
0x00401a8e 4831f0 xor rax, rsi
0x00401a91 48c1c620 rol rsi, 0x20
0x00401a95 4831d1 xor rcx, rdx
0x00401a98 4801c2 add rdx, rax
0x00401a9b 48c1c011 rol rax, 0x11
0x00401a9f 4801ce add rsi, rcx
0x00401aa2 48c1c115 rol rcx, 0x15
0x00401aa6 4831d0 xor rax, rdx
0x00401aa9 4831f1 xor rcx, rsi
0x00401aac 48c1c220 rol rdx, 0x20
0x00401ab0 4801c6 add rsi, rax
0x00401ab3 4801ca add rdx, rcx
0x00401ab6 48c1c00d rol rax, 0xd
0x00401aba 48c1c110 rol rcx, 0x10
0x00401abe 4831f0 xor rax, rsi
0x00401ac1 48c1c620 rol rsi, 0x20
0x00401ac5 4831d1 xor rcx, rdx
0x00401ac8 4801ce add rsi, rcx
0x00401acb 4801c2 add rdx, rax
0x00401ace 48c1c011 rol rax, 0x11
0x00401ad2 4831d0 xor rax, rdx
0x00401ad5 48c1c115 rol rcx, 0x15
0x00401ad9 4831f1 xor rcx, rsi
0x00401adc 4801c6 add rsi, rax
0x00401adf 48c1c00d rol rax, 0xd
0x00401ae3 4831c6 xor rsi, rax
0x00401ae6 48c1c220 rol rdx, 0x20
0x00401aea 4889c8 mov rax, rcx
0x00401aed 4801ca add rdx, rcx
0x00401af0 48c1c010 rol rax, 0x10
0x00401af4 4831d0 xor rax, rdx
0x00401af7 4801f2 add rdx, rsi
0x00401afa 48c1c611 rol rsi, 0x11
0x00401afe 48c1c015 rol rax, 0x15
0x00401b02 4831d0 xor rax, rdx
0x00401b05 48c1c220 rol rdx, 0x20
0x00401b09 4831f0 xor rax, rsi
0x00401b0c 4831d0 xor rax, rdx
0x00401b0f c3 ret ; returns rax (certified)
EOF
RUN
# aarch64: a Mach-O whose operands reach data through a page and an offset.
NAME=aarch64 listing
FILE=tests/fixtures/code_pointer_table_O0
CMDS=s 0x100000420; pd 24
EXPECT=<<EOF
0x100000420 ff4301d1 sub sp, sp, 0x50
0x100000424 fd7b04a9 stp x29, x30, [sp, 0x40]
0x100000428 fd030191 add x29, sp, 0x40
0x10000042c a0831ff8 stur x0, [x29, -0x8]
0x100000430 a1031ff8 stur x1, [x29, -0x10]
0x100000434 28000090 adrp x8, 0x100004000
0x100000438 08010091 add x8, x8, 0x0
0x10000043c 0001c03d ldr q0, [x8]
0x100000440 e007803d str q0, [sp, 0x10]
0x100000444 080940f9 ldr x8, [x8, 0x10]
0x100000448 e81300f9 str x8, [sp, 0x20]
0x10000044c a8835ff8 ldur x8, [x29, -0x8]
0x100000450 e80700f9 str x8, [sp, 0x8]
0x100000454 ff0700b9 str wzr, [sp, 0x4]
0x100000458 01000014 b 0x10000045c
0x10000045c e80740b9 ldr w8, [sp, 0x4]
0x100000460 080d0071 subs w8, w8, 0x3
0x100000464 22020054 b.cs 0x1000004a8
0x100000468 01000014 b 0x10000046c
0x10000046c e80740b9 ldr w8, [sp, 0x4]
0x100000470 e90308aa mov x9, x8
0x100000474 e8430091 add x8, sp, 0x10
0x100000478 087969f8 ldr x8, [x8, x9, lsl 0x3]
0x10000047c e00740f9 ldr x0, [sp, 0x8]
EOF
RUN
# `pdf` folds each block, so the page and its offset are one address the table load reads.
NAME=aarch64 function listing
FILE=tests/fixtures/code_pointer_table_O0
CMDS=pdf @ sym._table_dispatch
EXPECT=<<EOF
0x100000420 ff4301d1 sub sp, sp, 0x50
0x100000424 fd7b04a9 stp x29, x30, [sp, 0x40]
0x100000428 fd030191 add x29, sp, 0x40
0x10000042c a0831ff8 stur x0, [x29, -0x8]
0x100000430 a1031ff8 stur x1, [x29, -0x10]
0x100000434 28000090 adrp x8, 0x100004000
0x100000438 08010091 add x8, x8, 0x0 ; defines x8 = 0x100004000 (folded)
0x10000043c 0001c03d ldr q0, [x8]
0x100000440 e007803d str q0, [sp, 0x10]
0x100000444 080940f9 ldr x8, [x8, 0x10] ; [0x100004010:8] loaded 0x100000400 sym._table_op_mul (folded)
0x100000448 e81300f9 str x8, [sp, 0x20]
0x10000044c a8835ff8 ldur x8, [x29, -0x8]
0x100000450 e80700f9 str x8, [sp, 0x8]
0x100000454 ff0700b9 str wzr, [sp, 0x4]
0x100000458 01000014 b 0x10000045c
0x10000045c e80740b9 ldr w8, [sp, 0x4] ; loop: latches 0x100000498, exits 0x1000004a8 (certified) ; trips 0x4 (solved)
0x100000460 080d0071 subs w8, w8, 0x3
0x100000464 22020054 b.cs 0x1000004a8
0x100000468 01000014 b 0x10000046c
0x10000046c e80740b9 ldr w8, [sp, 0x4] ; defines x8 in [0x0, 0x2] (solved)
0x100000470 e90308aa mov x9, x8 ; defines x9 in [0x0, 0x2] (solved)
0x100000474 e8430091 add x8, sp, 0x10
0x100000478 087969f8 ldr x8, [x8, x9, lsl 0x3]
0x10000047c e00740f9 ldr x0, [sp, 0x8]
0x100000480 a9035ff8 ldur x9, [x29, -0x10]
0x100000484 ea0740b9 ldr w10, [sp, 0x4] ; defines x10 in [0x0, 0x2] (solved)
0x100000488 21010a8b add x1, x9, x10
0x10000048c 00013fd6 blr x8 ; indirect call: arguments unproven (certified)
0x100000490 e00700f9 str x0, [sp, 0x8]
0x100000494 01000014 b 0x100000498
0x100000498 e80740b9 ldr w8, [sp, 0x4] ; defines x8 in [0x0, 0x2] (solved)
0x10000049c 08050011 add w8, w8, 0x1 ; defines x8 in [0x1, 0x3] (solved)
0x1000004a0 e80700b9 str w8, [sp, 0x4]
0x1000004a4 eeffff17 b 0x10000045c
0x1000004a8 e00740f9 ldr x0, [sp, 0x8]
0x1000004ac fd7b44a9 ldp x29, x30, [sp, 0x40]
0x1000004b0 ff430191 add sp, sp, 0x50
0x1000004b4 c0035fd6 ret
EOF
RUN
# ARM 32-bit: the register roles (`fp`, `ip`, `sp`, `lr`, `pc`), `mov` for Sleigh's `cpy`, and a
# big-endian Thumb-2 decode, the one place this engine reads an instruction radare2 reads wrongly.
NAME=arm listing
FILE=crates/r2image/tests/data/arm_thumb_entry.elf
CMDS=pd 12
EXPECT=<<EOF
0x00010054 4ff0000b mov.w fp, 0x0
0x00010058 4ff0000e mov.w lr, 0x0
0x0001005c 02bc pop {r1}
0x0001005e 6a46 mov r2, sp
EOF
RUN
@@ -1,7 +1,10 @@
---
source: crates/r2s/tests/commands.rs
expression: run.out
---
# One function at each tier. A lowering change moves exactly one of these; read the new output and
# judge it before blessing it.
NAME=fnv1a32 low IL
FILE=tests/coverage/pinned/hashes_gcc_x64_O2
CMDS=s 0x401330; pdil
EXPECT=<<EOF
Entry: 0x401330
Blocks: 5
@@ -89,3 +92,48 @@ Block 0x401360 (6 bytes, 4 ops)
1: RIP = LOAD [ram]RSP
2: RSP = RSP + 0x8:8
3: RETURN RIP
EOF
RUN
NAME=fnv1a32 C
FILE=tests/coverage/pinned/hashes_gcc_x64_O2
CMDS=s 0x401330; pdd
EXPECT=<<EOF
uint64_t fnv1a32(uint64_t arg0, uint64_t arg1)
{
uint64_t rsi_1;
uint64_t rax_2;
uint64_t rdi_1;
uint8_t tmp_11e00_1;
uint64_t rdi_2;
uint64_t rax_4;
/* r2dec proof: no individual construct is marked; 40 source obligations: 32 rendered, 8 elided, 0 refused; 14 statements rendered */
{
if ((uint8_t)((uint64_t)arg1 == (uint64_t)0U)) {
return (uint64_t)0x811c9dc5U;
} else {
rsi_1 = (uint64_t)((uint64_t)arg1 + (uint64_t)arg0);
rax_2 = (uint64_t)0x811c9dc5U;
rdi_1 = arg0;
for (; ; ) {
tmp_11e00_1 = r2sleigh_load_u8((void*)rdi_1);
rdi_2 = (uint64_t)((uint64_t)rdi_1 + (uint64_t)1U);
rax_4 = (uint64_t)(uint32_t)((uint64_t)((uint64_t)(int32_t)((uint32_t)(uint8_t)tmp_11e00_1 ^ (uint32_t)((uint64_t)rax_2 >> 0U)) * (uint64_t)0x1000193U) >> 0U);
if ((uint8_t)((uint64_t)rsi_1 != (uint64_t)rdi_2)) {
rax_2 = rax_4;
rdi_1 = rdi_2;
} else {
break;
}
}
{
return (uint64_t)rax_4;
}
}
}
}
EOF
RUN