1 /*
2 * Copyright © 2022 Collabora, Ltd.
3 * SPDX-License-Identifier: MIT
4 */
5
6 extern crate bitview;
7
8 use crate::bitview::*;
9
10 use std::fs;
11 use std::io::Write;
12 use std::ops::Range;
13 use std::path::PathBuf;
14 use std::process::Command;
15
16 const TMP_FILE: &str = "/tmp/nvfuzz";
17
find_cuda() -> std::io::Result<PathBuf>18 fn find_cuda() -> std::io::Result<PathBuf> {
19 let paths = fs::read_dir("/usr/local")?;
20
21 for path in paths {
22 let mut path = path?.path();
23 let Some(fname) = path.file_name() else {
24 continue;
25 };
26
27 let Some(fname) = fname.to_str() else {
28 continue;
29 };
30
31 if !fname.starts_with("cuda-") {
32 continue;
33 }
34
35 path.push("bin");
36 path.push("nvdisasm");
37 if path.exists() {
38 return Ok(path);
39 }
40 }
41
42 Err(std::io::Error::new(
43 std::io::ErrorKind::NotFound,
44 "Failed to find nvdisasm",
45 ))
46 }
47
48 //fn write_tmpfile(data: &[u32]) -> std::io::Result<()> {
49 // let mut file = std::fs::File::create(TMP_FILE)?;
50 // for dw in data {
51 // file.write(dw.to_le_bytes())?;
52 // }
53 //}
54
main()55 fn main() {
56 let args: Vec<String> = std::env::args().collect();
57 let sm: u8 = {
58 let sm_str = &args[1];
59 assert!(sm_str.starts_with("SM"));
60 sm_str[2..].parse().unwrap()
61 };
62 let range: Vec<&str> = args[2].split("..").collect();
63 let range: Range<usize> = Range {
64 start: range[0].parse().unwrap(),
65 end: range[1].parse().unwrap(),
66 };
67
68 let dw_count = if sm >= 70 {
69 4
70 } else if sm >= 50 {
71 8
72 } else {
73 panic!("Unknown shader model");
74 };
75
76 let mut instr = Vec::new();
77 for i in 0..dw_count {
78 instr.push(u32::from_str_radix(&args[3 + i], 16).unwrap());
79 }
80
81 let cuda_path = find_cuda().expect("Failed to find CUDA");
82
83 for bits in 0..(1_u64 << range.len()) {
84 BitMutView::new(&mut instr[..]).set_field(range.clone(), bits);
85
86 print!("With {:#x} in {}..{}:", bits, range.start, range.end);
87 for dw in &instr {
88 print!(" {:#x}", dw);
89 }
90 print!("\n");
91
92 let mut data = Vec::new();
93 for dw in &instr {
94 data.extend(dw.to_le_bytes());
95 }
96 std::fs::write(TMP_FILE, data).expect("Failed to write file");
97
98 let out = Command::new(cuda_path.as_path())
99 .arg("-b")
100 .arg(format!("SM{sm}"))
101 .arg(TMP_FILE)
102 .output()
103 .expect("failed to execute process");
104 std::io::stderr().write_all(&out.stderr).expect("IO error");
105 std::io::stdout().write_all(&out.stdout).expect("IO error");
106 }
107 }
108