• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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