1
1
use std:: {
2
2
fs:: { create_dir_all, File } ,
3
- io:: { Error , Write } ,
3
+ io:: Write ,
4
4
path:: PathBuf ,
5
5
} ;
6
6
7
7
use clap:: Parser ;
8
8
use libafl_targets:: drcov:: DrCovReader ;
9
+ use walkdir:: WalkDir ;
9
10
10
11
#[ derive( Parser , Debug ) ]
11
12
#[ clap( author, version, about, long_about = None ) ]
@@ -15,7 +16,12 @@ use libafl_targets::drcov::DrCovReader;
15
16
long_about = "Writes a list of all addresses from a DrCovFile"
16
17
) ]
17
18
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
+ ) ]
19
25
pub inputs : Vec < PathBuf > ,
20
26
21
27
#[ arg(
@@ -35,81 +41,114 @@ pub struct Opt {
35
41
pub sort : bool ,
36
42
}
37
43
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
+ } ;
40
50
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 ( ) ;
47
52
48
- assert ! ( out_dir. is_dir( ) , "Out_dir {out_dir:?} not a directory!" ) ;
53
+ if opts. sort {
54
+ blocks. sort_unstable ( ) ;
49
55
}
50
56
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 ( ( ) ) ;
56
69
} ;
57
70
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
+ ) ?;
62
92
}
93
+ writeln ! ( writer, "# {} Blocks covered in {input:?}." , blocks. len( ) ) ?;
63
94
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
+ }
71
99
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
+ }
77
105
78
- println ! ( "Dumping traces from drcov file {input:?} to {out_file:?}" , ) ;
106
+ Ok ( ( ) )
107
+ }
79
108
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 ( ) ;
84
112
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) ;
99
118
}
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 ( ) ;
101
127
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:?}" ) ;
104
132
}
105
133
}
106
134
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
+ }
110
147
}
148
+ files
149
+ } ;
150
+ for drcov_file in drcovs {
151
+ let _ = process ( & opts, & drcov_file) ;
111
152
}
112
153
}
113
-
114
- Ok ( ( ) )
115
154
}
0 commit comments