Skip to content

Commit 2ec534a

Browse files
authored
Make drcov_dump_address.rs accept list of directories (#2904)
* accept folders * lol * use walkdir instead of my impl
1 parent 6b96581 commit 2ec534a

File tree

2 files changed

+99
-59
lines changed

2 files changed

+99
-59
lines changed

utils/drcov_utils/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ keywords = ["fuzzing", "libafl", "drcov"]
1212
env_logger = "0.11.6"
1313
libafl_targets = { workspace = true, default-features = true }
1414
clap = { workspace = true, features = ["derive", "wrap_help"] }
15+
walkdir = "2.5"
1516

1617
[lints]
1718
workspace = true
+98-59
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use std::{
22
fs::{create_dir_all, File},
3-
io::{Error, Write},
3+
io::Write,
44
path::PathBuf,
55
};
66

77
use clap::Parser;
88
use libafl_targets::drcov::DrCovReader;
9+
use walkdir::WalkDir;
910

1011
#[derive(Parser, Debug)]
1112
#[clap(author, version, about, long_about = None)]
@@ -15,7 +16,12 @@ use libafl_targets::drcov::DrCovReader;
1516
long_about = "Writes a list of all addresses from a DrCovFile"
1617
)]
1718
pub struct Opt {
18-
#[arg(short, long, help = "DrCov traces to read", required = true)]
19+
#[arg(
20+
short,
21+
long,
22+
help = "DrCov traces or directories to read",
23+
required = true
24+
)]
1925
pub inputs: Vec<PathBuf>,
2026

2127
#[arg(
@@ -35,81 +41,114 @@ pub struct Opt {
3541
pub sort: bool,
3642
}
3743

38-
fn main() -> Result<(), Error> {
39-
let opts = Opt::parse();
44+
fn process(opts: &Opt, input: &PathBuf) -> Result<(), std::io::Error> {
45+
let Ok(drcov) = DrCovReader::read(&input)
46+
.map_err(|err| eprintln!("Ignored coverage file {input:?}, reason: {err:?}"))
47+
else {
48+
return Ok(());
49+
};
4050

41-
if let Some(out_dir) = &opts.out_dir {
42-
if !out_dir.exists() {
43-
if let Err(err) = create_dir_all(out_dir) {
44-
eprint!("Failed to create dir {out_dir:?}: {err:?}");
45-
}
46-
}
51+
let mut blocks = drcov.basic_block_addresses_u64();
4752

48-
assert!(out_dir.is_dir(), "Out_dir {out_dir:?} not a directory!");
53+
if opts.sort {
54+
blocks.sort_unstable();
4955
}
5056

51-
for input in opts.inputs {
52-
let Ok(drcov) = DrCovReader::read(&input)
53-
.map_err(|err| eprint!("Ignored coverage file {input:?}, reason: {err:?}"))
54-
else {
55-
continue;
57+
let mut writer: Box<dyn Write> = if let Some(out_dir) = &opts.out_dir {
58+
// Write files to a directory
59+
let out_file = out_dir.join(
60+
input
61+
.file_name()
62+
.expect("File without filename shouldn't exist"),
63+
);
64+
65+
let Ok(file) = File::create_new(&out_file).map_err(|err| {
66+
eprintln!("Could not create file {out_file:?} - continuing: {err:?}");
67+
}) else {
68+
return Ok(());
5669
};
5770

58-
let mut blocks = drcov.basic_block_addresses_u64();
59-
60-
if opts.sort {
61-
blocks.sort_unstable();
71+
println!("Dumping traces from drcov file {input:?} to {out_file:?}",);
72+
73+
Box::new(file)
74+
} else {
75+
Box::new(std::io::stdout())
76+
};
77+
78+
// dump to stdout
79+
let modules = &drcov.module_entries;
80+
81+
if opts.metadata {
82+
writeln!(writer, "# {} Modules:", modules.len())?;
83+
for module in &drcov.module_entries {
84+
writeln!(
85+
writer,
86+
"\t{} - [{:#020x}-{:#020x}] {}",
87+
module.id,
88+
module.base,
89+
module.end,
90+
module.path.display()
91+
)?;
6292
}
93+
writeln!(writer, "# {} Blocks covered in {input:?}.", blocks.len())?;
6394

64-
let mut writer: Box<dyn Write> = if let Some(out_dir) = &opts.out_dir {
65-
// Write files to a directory
66-
let out_file = out_dir.join(
67-
input
68-
.file_name()
69-
.expect("File without filename shouldn't exist"),
70-
);
95+
if opts.addrs {
96+
writeln!(writer)?;
97+
}
98+
}
7199

72-
let Ok(file) = File::create_new(&out_file).map_err(|err| {
73-
eprintln!("Could not create file {out_file:?} - continuing: {err:?}");
74-
}) else {
75-
continue;
76-
};
100+
if opts.addrs {
101+
for line in blocks {
102+
writeln!(writer, "{line:#x}")?;
103+
}
104+
}
77105

78-
println!("Dumping traces from drcov file {input:?} to {out_file:?}",);
106+
Ok(())
107+
}
79108

80-
Box::new(file)
81-
} else {
82-
Box::new(std::io::stdout())
83-
};
109+
#[must_use]
110+
pub fn find_drcov_files(dir: &PathBuf) -> Vec<PathBuf> {
111+
let mut drcov_files = Vec::new();
84112

85-
// dump to stdout
86-
let modules = &drcov.module_entries;
87-
88-
if opts.metadata {
89-
writeln!(writer, "# {} Modules:", modules.len())?;
90-
for module in &drcov.module_entries {
91-
writeln!(
92-
writer,
93-
"\t{} - [{:#020x}-{:#020x}] {}",
94-
module.id,
95-
module.base,
96-
module.end,
97-
module.path.display()
98-
)?;
113+
for entry in WalkDir::new(dir) {
114+
let entry = entry.unwrap().into_path();
115+
if let Some(ext) = entry.extension() {
116+
if ext == "drcov" {
117+
drcov_files.push(entry);
99118
}
100-
writeln!(writer, "# {} Blocks covered in {input:?}.", blocks.len())?;
119+
}
120+
}
121+
122+
drcov_files
123+
}
124+
125+
fn main() {
126+
let opts = Opt::parse();
101127

102-
if opts.addrs {
103-
writeln!(writer)?;
128+
if let Some(out_dir) = &opts.out_dir {
129+
if !out_dir.exists() {
130+
if let Err(err) = create_dir_all(out_dir) {
131+
eprintln!("Failed to create dir {out_dir:?}: {err:?}");
104132
}
105133
}
106134

107-
if opts.addrs {
108-
for line in blocks {
109-
writeln!(writer, "{line:#x}")?;
135+
assert!(out_dir.is_dir(), "Out_dir {out_dir:?} not a directory!");
136+
}
137+
138+
for input in &opts.inputs {
139+
let drcovs = if input.is_dir() {
140+
find_drcov_files(input)
141+
} else {
142+
let mut files = vec![];
143+
if let Some(ext) = input.extension() {
144+
if ext == "drcov" {
145+
files.push(input.clone());
146+
}
110147
}
148+
files
149+
};
150+
for drcov_file in drcovs {
151+
let _ = process(&opts, &drcov_file);
111152
}
112153
}
113-
114-
Ok(())
115154
}

0 commit comments

Comments
 (0)