summaryrefslogtreecommitdiff
path: root/rust/src/platform.rs
diff options
context:
space:
mode:
authorJosh Watson <josh@joshwatson.com>2021-03-15 09:34:30 -0700
committerKyle Martin <krm504@nyu.edu>2021-03-22 13:04:43 -0400
commit7acc36513c72b84d595d205771b883d67191ef39 (patch)
tree5d38be4a92a52d1971ee52dc5b1916e3cbb081ae /rust/src/platform.rs
parentd8277e7cc9b488de628a8570f526cf7f7e9c569f (diff)
Implement Platform::parse_types_from_source
Change include_directories to `&[AsRef<Path>]` Make TypeParserResult default and clone Change error_msg scope cargo fmt Kyle's comments Whackamole with .as_ptr() as _ Fixed up error_msg as BnString
Diffstat (limited to 'rust/src/platform.rs')
-rw-r--r--rust/src/platform.rs110
1 files changed, 104 insertions, 6 deletions
diff --git a/rust/src/platform.rs b/rust/src/platform.rs
index 45e4211e..875069c1 100644
--- a/rust/src/platform.rs
+++ b/rust/src/platform.rs
@@ -12,15 +12,17 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-use std::borrow::Borrow;
+use std::{borrow::Borrow, collections::HashMap, os::raw, path::Path, ptr, slice};
use binaryninjacore_sys::*;
-use crate::architecture::{Architecture, CoreArchitecture};
-use crate::callingconvention::CallingConvention;
-use crate::rc::*;
-use crate::string::*;
-use crate::types::QualifiedNameAndType;
+use crate::{
+ architecture::{Architecture, CoreArchitecture},
+ callingconvention::CallingConvention,
+ rc::*,
+ string::*,
+ types::{QualifiedName, QualifiedNameAndType, Type},
+};
#[derive(PartialEq, Eq, Hash)]
pub struct Platform {
@@ -230,6 +232,102 @@ impl Platform {
}
}
+pub trait TypeParser {
+ fn parse_types_from_source<S: BnStrCompatible, P: AsRef<Path>>(
+ &self,
+ _source: S,
+ _filename: S,
+ _include_directories: &[P],
+ _auto_type_source: S,
+ ) -> Result<TypeParserResult, String> {
+ Err(String::new())
+ }
+}
+
+#[derive(Clone, Default)]
+pub struct TypeParserResult {
+ pub types: HashMap<String, Ref<Type>>,
+ pub variables: HashMap<String, Ref<Type>>,
+ pub functions: HashMap<String, Ref<Type>>,
+}
+
+impl TypeParser for Platform {
+ fn parse_types_from_source<S: BnStrCompatible, P: AsRef<Path>>(
+ &self,
+ source: S,
+ filename: S,
+ include_directories: &[P],
+ auto_type_source: S,
+ ) -> Result<TypeParserResult, String> {
+ let mut result = BNTypeParserResult {
+ functionCount: 0,
+ typeCount: 0,
+ variableCount: 0,
+ functions: ptr::null_mut(),
+ types: ptr::null_mut(),
+ variables: ptr::null_mut(),
+ };
+
+ let mut type_parser_result = TypeParserResult::default();
+
+ let mut error_string: *mut raw::c_char = ptr::null_mut();
+
+ let src = source.as_bytes_with_nul();
+ let filename = filename.as_bytes_with_nul();
+ let auto_type_source = auto_type_source.as_bytes_with_nul();
+
+ let mut include_dirs = vec![];
+
+ for dir in include_directories.iter() {
+ let d = dir.as_ref().to_string_lossy().as_bytes_with_nul();
+ include_dirs.push(d.as_ptr() as _);
+ }
+
+ unsafe {
+ let success = BNParseTypesFromSource(
+ self.handle,
+ src.as_ref().as_ptr() as _,
+ filename.as_ref().as_ptr() as _,
+ &mut result,
+ &mut error_string,
+ include_dirs.as_mut_ptr(),
+ include_dirs.len(),
+ auto_type_source.as_ref().as_ptr() as _,
+ );
+
+ let error_msg = BnString::from_raw(error_string);
+ BNFreeString(error_string);
+
+ if !success {
+ return Err(error_msg.to_string());
+ }
+
+ for i in slice::from_raw_parts(result.types, result.typeCount) {
+ let name = QualifiedName(i.name);
+ type_parser_result
+ .types
+ .insert(name.string(), Type::ref_from_raw(i.type_));
+ }
+
+ for i in slice::from_raw_parts(result.functions, result.functionCount) {
+ let name = QualifiedName(i.name);
+ type_parser_result
+ .functions
+ .insert(name.string(), Type::ref_from_raw(i.type_));
+ }
+
+ for i in slice::from_raw_parts(result.variables, result.variableCount) {
+ let name = QualifiedName(i.name);
+ type_parser_result
+ .variables
+ .insert(name.string(), Type::ref_from_raw(i.type_));
+ }
+ }
+
+ Ok(type_parser_result)
+ }
+}
+
impl ToOwned for Platform {
type Owned = Ref<Self>;