Skip to content

Commit 79f8e2d

Browse files
committed
make idb_import a background task
1 parent 161a57c commit 79f8e2d

File tree

2 files changed

+43
-37
lines changed

2 files changed

+43
-37
lines changed

plugins/idb_import/src/lib.rs

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ mod types;
22
use std::fs::File;
33
use std::io::BufReader;
44

5+
use binaryninja::background_task::BackgroundTask;
56
use binaryninja::command::Command;
67
use binaryninja::string::BnStrCompatible;
78
use binaryninja::type_library::TypeLibrary;
@@ -84,7 +85,7 @@ struct LoadTilFile;
8485

8586
impl Command for LoadTilFile {
8687
fn action(&self, view: &BinaryView) {
87-
if let Err(error) = interactive_import_til(view) {
88+
if let Err(error) = background_import_til(view) {
8889
error!("Unable to convert TIL file: {error}");
8990
}
9091
}
@@ -126,10 +127,6 @@ impl std::io::Seek for BinaryViewReader<'_> {
126127
}
127128
}
128129

129-
fn dummy_progress(_: usize, _: usize) -> Result<(), ()> {
130-
Ok(())
131-
}
132-
133130
fn import_idb_info<P: Fn(usize, usize) -> Result<(), ()>>(
134131
debug_info: &mut DebugInfo,
135132
bv: &BinaryView,
@@ -181,7 +178,18 @@ fn import_til_info_from_debug_file<P: Fn(usize, usize) -> Result<(), ()>>(
181178
import_til_to_type_library(til, filename, bv, progress)
182179
}
183180

181+
fn background_import_til(view: &BinaryView) -> Result<()> {
182+
let moved_view = view.to_owned();
183+
binaryninja::worker_thread::execute_on_worker_thread_interactive(c"Til Import", move || {
184+
if let Err(err) = interactive_import_til(&moved_view) {
185+
error!("Unable to import TIL: {err}");
186+
}
187+
});
188+
Ok(())
189+
}
190+
184191
fn interactive_import_til(view: &BinaryView) -> Result<()> {
192+
let bt = BackgroundTask::new("Import TIL", true);
185193
let Some(file) =
186194
binaryninja::interaction::get_open_filename_input("Select a .til file", "*.til")
187195
else {
@@ -192,8 +200,19 @@ fn interactive_import_til(view: &BinaryView) -> Result<()> {
192200
let mut file = BufReader::new(File::open(&file)?);
193201
let til = TILSection::read(&mut file, idb_rs::IDBSectionCompression::None)?;
194202

195-
// TODO remove the extension?
196-
import_til_to_type_library(til, filename, view, dummy_progress)
203+
let progress = |current, total| {
204+
if bt.is_cancelled() {
205+
return Err(());
206+
}
207+
bt.set_progress_text(format!(
208+
"Import TIL progress: {}%",
209+
((current as f32 / total as f32) * 100f32) as u32
210+
));
211+
Ok(())
212+
};
213+
import_til_to_type_library(til, filename, view, progress)?;
214+
bt.finish();
215+
Ok(())
197216
}
198217

199218
fn import_til_to_type_library<S, P>(
@@ -271,7 +290,7 @@ fn import_til_section<P: Fn(usize, usize) -> Result<(), ()>>(
271290
let default_arch = view
272291
.default_arch()
273292
.ok_or_else(|| anyhow!("Unable to get the default arch"))?;
274-
let types = types::translate_tils_types(default_arch, tils, progress)?;
293+
let types = types::translate_til_types(default_arch, tils, progress)?;
275294

276295
// print any errors
277296
print_til_convertsion_errors(&types)?;
@@ -437,11 +456,11 @@ pub extern "C" fn CorePluginInit() -> bool {
437456
.with_level(LevelFilter::Error)
438457
.init();
439458
binaryninja::command::register_command(
440-
"Import TIL types",
441-
"Convert and import a TIL file into a TypeLibrary",
459+
c"Import TIL types",
460+
c"Convert and import a TIL file into a TypeLibrary",
442461
LoadTilFile,
443462
);
444-
DebugInfoParser::register("idb_parser", IDBDebugInfoParser);
445-
DebugInfoParser::register("til_parser", TILDebugInfoParser);
463+
DebugInfoParser::register(c"idb_parser", IDBDebugInfoParser);
464+
DebugInfoParser::register(c"til_parser", TILDebugInfoParser);
446465
true
447466
}

plugins/idb_import/src/types.rs

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ pub struct TranslatesIDBType<'a> {
114114

115115
pub struct TranslateIDBTypes<'a, F> {
116116
pub arch: CoreArchitecture,
117-
pub total: usize,
118117
pub progress: F,
119118
// key til addr and type idx
120119
pub types_by_idx: HashMap<(usize, usize), usize>,
@@ -129,19 +128,16 @@ where
129128
F: Fn(usize, usize) -> Result<(), ()>,
130129
{
131130
pub fn from_types(arch: CoreArchitecture, tils: &'a [TILSection], progress: F) -> Result<Self> {
132-
let total = tils
133-
.iter()
134-
.map(|til| til.symbols.len() + til.types.len())
135-
.sum();
136-
let mut types = Vec::with_capacity(total);
137-
let mut types_by_idx = HashMap::with_capacity(total);
138-
let mut types_by_ord = HashMap::with_capacity(total);
139-
let mut types_by_name = HashMap::with_capacity(total);
140131
let all_types = tils.iter().flat_map(|til| {
141132
core::iter::repeat(til).zip(til.types.iter().enumerate().zip(core::iter::repeat(false)))
142133
// TODO: it's unclear how the demangle symbols and types names/ord, for now only parse types
143134
//.chain(til.symbols.iter().zip(core::iter::repeat(true)))
144135
});
136+
let total = all_types.clone().count();
137+
let mut types = Vec::with_capacity(total);
138+
let mut types_by_idx = HashMap::with_capacity(total);
139+
let mut types_by_ord = HashMap::with_capacity(total);
140+
let mut types_by_name = HashMap::with_capacity(total);
145141
for (i, (til, ((ty_idx, ty), is_symbol))) in all_types.enumerate() {
146142
// TODO sanitized the input
147143
// TODO find out how the namespaces used by TIL works
@@ -189,7 +185,6 @@ where
189185
}
190186

191187
Ok(TranslateIDBTypes {
192-
total,
193188
arch,
194189
progress,
195190
tils,
@@ -201,7 +196,7 @@ where
201196
}
202197

203198
fn resolve(&mut self) -> Result<()> {
204-
if (self.progress)(0, self.total).is_err() {
199+
if (self.progress)(0, self.types.len()).is_err() {
205200
return Err(anyhow!("IDB import aborted"));
206201
}
207202

@@ -238,14 +233,15 @@ where
238233
}
239234

240235
// count the number of finished types
241-
if let TranslateTypeResult::Translated(_) = &self.types[i].ty {
242-
num_translated += 1
236+
let was_translated =
237+
matches!(&self.types[i].ty, TranslateTypeResult::Translated(_));
238+
if was_translated {
239+
num_translated += 1;
243240
}
244-
245-
all_done &= matches!(&self.types[i].ty, TranslateTypeResult::Translated(_));
241+
all_done &= was_translated;
246242
}
247243

248-
if (self.progress)(num_translated, self.total).is_err() {
244+
if (self.progress)(num_translated, self.types.len()).is_err() {
249245
// error means the user aborted the progress
250246
return Err(anyhow!("User aborted during processing"));
251247
}
@@ -770,7 +766,6 @@ pub fn translate_ephemeral_type(debug_file: &BinaryView, ty: &TILType) -> Transl
770766
macros: None,
771767
}],
772768
types: vec![],
773-
total: 0,
774769
types_by_idx: HashMap::new(),
775770
types_by_ord: HashMap::new(),
776771
types_by_name: HashMap::new(),
@@ -779,14 +774,6 @@ pub fn translate_ephemeral_type(debug_file: &BinaryView, ty: &TILType) -> Transl
779774
translator.translate_type(&translator.tils[0], ty)
780775
}
781776

782-
pub fn translate_tils_types(
783-
arch: CoreArchitecture,
784-
tils: &[TILSection],
785-
progress: impl Fn(usize, usize) -> Result<(), ()>,
786-
) -> Result<Vec<TranslatesIDBType<'_>>> {
787-
translate_til_types(arch, tils, progress)
788-
}
789-
790777
pub fn translate_til_types(
791778
arch: CoreArchitecture,
792779
tils: &[TILSection],

0 commit comments

Comments
 (0)