diff options
| author | KyleMiles <krm504@nyu.edu> | 2022-09-22 13:43:46 -0400 |
|---|---|---|
| committer | KyleMiles <krm504@nyu.edu> | 2022-09-22 13:49:36 -0400 |
| commit | bdf05c261bd1c24f0440c17e10b983b50613bc20 (patch) | |
| tree | 8a6ee0c5b801b60028d22bea7f31af38bd9da0eb | |
| parent | e95b220ef18c9dd9e1aecab32b735ff47237f9c7 (diff) | |
Add new DebugInfo APIs
| -rw-r--r-- | binaryninjaapi.h | 28 | ||||
| -rw-r--r-- | binaryninjacore.h | 47 | ||||
| -rw-r--r-- | debuginfo.cpp | 154 | ||||
| -rw-r--r-- | python/debuginfo.py | 99 | ||||
| -rw-r--r-- | rust/src/debuginfo.rs | 224 |
5 files changed, 541 insertions, 11 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 752b9c52..5c04816b 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -11933,9 +11933,31 @@ namespace BinaryNinja { public: DebugInfo(BNDebugInfo* debugInfo); - std::vector<NameAndType> GetTypes(const std::string& parserName = ""); - std::vector<DebugFunctionInfo> GetFunctions(const std::string& parserName = ""); - std::vector<DataVariableAndName> GetDataVariables(const std::string& parserName = ""); + std::vector<std::string> GetParsers() const; + + std::vector<NameAndType> GetTypes(const std::string& parserName = "") const; + std::vector<DebugFunctionInfo> GetFunctions(const std::string& parserName = "") const; + std::vector<DataVariableAndName> GetDataVariables(const std::string& parserName = "") const; + + Ref<Type> GetTypeByName(const std::string& parserName, const std::string& name) const; + std::optional<std::tuple<uint64_t, Ref<Type>>> GetDataVariableByName( + const std::string& parserName, const std::string& name) const; + std::optional<std::tuple<std::string, Ref<Type>>> GetDataVariableByAddress( + const std::string& parserName, const uint64_t address) const; + + std::vector<std::tuple<std::string, Ref<Type>>> GetTypesByName(const std::string& name) const; + std::vector<std::tuple<std::string, uint64_t, Ref<Type>>> GetDataVariablesByName(const std::string& name) const; + std::vector<std::tuple<std::string, std::string, Ref<Type>>> GetDataVariablesByAddress( + const uint64_t address) const; + + bool RemoveParserInfo(const std::string& parserName); + bool RemoveParserTypes(const std::string& parserName); + bool RemoveParserFunctions(const std::string& parserName); + bool RemoveParserDataVariables(const std::string& parserName); + + bool RemoveTypeByName(const std::string& parserName, const std::string& name); + bool RemoveFunctionByIndex(const std::string& parserName, const size_t index); + bool RemoveDataVariableByAddress(const std::string& parserName, const uint64_t address); bool AddType(const std::string& name, Ref<Type> type); bool AddFunction(const DebugFunctionInfo& function); diff --git a/binaryninjacore.h b/binaryninjacore.h index 12c1b277..416f9574 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -994,6 +994,16 @@ extern "C" uint8_t typeConfidence; }; + struct BNDataVariableAndNameAndDebugParser + { + uint64_t address; + BNType* type; + char* name; + char* parser; + bool autoDiscovered; + uint8_t typeConfidence; + }; + enum BNMediumLevelILOperation { MLIL_NOP, @@ -4231,7 +4241,10 @@ extern "C" BINARYNINJACOREAPI void BNUndefineUserDataVariable(BNBinaryView* view, uint64_t addr); BINARYNINJACOREAPI BNDataVariable* BNGetDataVariables(BNBinaryView* view, size_t* count); BINARYNINJACOREAPI void BNFreeDataVariables(BNDataVariable* vars, size_t count); + BINARYNINJACOREAPI void BNFreeDataVariableAndName(BNDataVariableAndName* var); BINARYNINJACOREAPI void BNFreeDataVariablesAndName(BNDataVariableAndName* vars, size_t count); + BINARYNINJACOREAPI void BNFreeDataVariableAndNameAndDebugParserList( + BNDataVariableAndNameAndDebugParser* vars, size_t count); BINARYNINJACOREAPI bool BNGetDataVariableAtAddress(BNBinaryView* view, uint64_t addr, BNDataVariable* var); BINARYNINJACOREAPI bool BNParseTypeString(BNBinaryView* view, const char* text, BNQualifiedNameAndType* result, @@ -6255,19 +6268,43 @@ extern "C" BINARYNINJACOREAPI BNDebugInfo* BNNewDebugInfoReference(BNDebugInfo* debugInfo); BINARYNINJACOREAPI void BNFreeDebugInfoReference(BNDebugInfo* debugInfo); + BINARYNINJACOREAPI char** BNGetDebugParserNames(BNDebugInfo* const debugInfo, size_t* count); + BINARYNINJACOREAPI bool BNRemoveDebugParserInfo(BNDebugInfo* const debugInfo, const char* const parserName); + BINARYNINJACOREAPI bool BNRemoveDebugParserTypes(BNDebugInfo* const debugInfo, const char* const parserName); + BINARYNINJACOREAPI bool BNRemoveDebugParserFunctions(BNDebugInfo* const debugInfo, const char* const parserName); + BINARYNINJACOREAPI bool BNRemoveDebugParserDataVariables( + BNDebugInfo* const debugInfo, const char* const parserName); BINARYNINJACOREAPI bool BNAddDebugType( - BNDebugInfo* const debugInfo, const char* const name, const BNType* const type); + BNDebugInfo* const debugInfo, const char* const name, const BNType* const type); BINARYNINJACOREAPI BNNameAndType* BNGetDebugTypes( - BNDebugInfo* const debugInfo, const char* const name, size_t* count); + BNDebugInfo* const debugInfo, const char* const name, size_t* count); + BINARYNINJACOREAPI BNType* BNGetDebugTypeByName( + BNDebugInfo* const debugInfo, const char* const parserName, const char* const typeName); + BINARYNINJACOREAPI BNNameAndType* BNGetDebugTypesByName( + BNDebugInfo* const debugInfo, const char* const typeName, size_t* count); + BINARYNINJACOREAPI bool BNRemoveDebugTypeByName( + BNDebugInfo* const debugInfo, const char* const parserName, const char* typeName); BINARYNINJACOREAPI void BNFreeDebugTypes(BNNameAndType* types, size_t count); BINARYNINJACOREAPI bool BNAddDebugFunction(BNDebugInfo* const debugInfo, BNDebugFunctionInfo* func); BINARYNINJACOREAPI BNDebugFunctionInfo* BNGetDebugFunctions( - BNDebugInfo* const debugInfo, const char* const name, size_t* count); + BNDebugInfo* const debugInfo, const char* const name, size_t* count); + BINARYNINJACOREAPI bool BNRemoveDebugFunctionByIndex( + BNDebugInfo* const debugInfo, const char* const parserName, const size_t index); BINARYNINJACOREAPI void BNFreeDebugFunctions(BNDebugFunctionInfo* functions, size_t count); BINARYNINJACOREAPI bool BNAddDebugDataVariable( - BNDebugInfo* const debugInfo, uint64_t address, const BNType* const type, const char* name); + BNDebugInfo* const debugInfo, uint64_t address, const BNType* const type, const char* name); BINARYNINJACOREAPI BNDataVariableAndName* BNGetDebugDataVariables( - BNDebugInfo* const debugInfo, const char* const name, size_t* count); + BNDebugInfo* const debugInfo, const char* const name, size_t* count); + BINARYNINJACOREAPI BNDataVariableAndName* BNGetDebugDataVariableByName( + BNDebugInfo* const debugInfo, const char* const parserName, const char* const variableName); + BINARYNINJACOREAPI BNDataVariableAndName* BNGetDebugDataVariableByAddress( + BNDebugInfo* const debugInfo, const char* const parserName, const uint64_t address); + BINARYNINJACOREAPI BNDataVariableAndName* BNGetDebugDataVariablesByName( + BNDebugInfo* const debugInfo, const char* const variableName, size_t* count); + BINARYNINJACOREAPI BNDataVariableAndNameAndDebugParser* BNGetDebugDataVariablesByAddress( + BNDebugInfo* const debugInfo, const uint64_t address, size_t* count); + BINARYNINJACOREAPI bool BNRemoveDebugDataVariableByAddress( + BNDebugInfo* const debugInfo, const char* const parserName, const uint64_t address); // Secrets providers BINARYNINJACOREAPI BNSecretsProvider* BNRegisterSecretsProvider( diff --git a/debuginfo.cpp b/debuginfo.cpp index e8450399..fb10039e 100644 --- a/debuginfo.cpp +++ b/debuginfo.cpp @@ -38,7 +38,23 @@ DebugInfo::DebugInfo(BNDebugInfo* debugInfo) } -vector<NameAndType> DebugInfo::GetTypes(const string& parserName) +vector<string> DebugInfo::GetParsers() const +{ + size_t count; + char** parsers = BNGetDebugParserNames(m_object, &count); + + vector<string> result; + for (size_t i = 0; i < count; ++i) + { + result.emplace_back(parsers[i]); + } + BNFreeStringList(parsers, count); + + return result; +} + + +vector<NameAndType> DebugInfo::GetTypes(const string& parserName) const { size_t count; BNNameAndType* nameAndTypes = @@ -56,7 +72,7 @@ vector<NameAndType> DebugInfo::GetTypes(const string& parserName) } -vector<DebugFunctionInfo> DebugInfo::GetFunctions(const string& parserName) +vector<DebugFunctionInfo> DebugInfo::GetFunctions(const string& parserName) const { size_t count; BNDebugFunctionInfo* functions = @@ -86,7 +102,7 @@ vector<DebugFunctionInfo> DebugInfo::GetFunctions(const string& parserName) } -vector<DataVariableAndName> DebugInfo::GetDataVariables(const string& parserName) +vector<DataVariableAndName> DebugInfo::GetDataVariables(const string& parserName) const { size_t count; BNDataVariableAndName* variableAndNames = @@ -105,6 +121,138 @@ vector<DataVariableAndName> DebugInfo::GetDataVariables(const string& parserName } +// May return nullptr +Ref<Type> DebugInfo::GetTypeByName(const string& parserName, const string& name) const +{ + BNType* result = BNGetDebugTypeByName(m_object, parserName.c_str(), name.c_str()); + if (result) + return Ref<Type>(new Type(result)); + return nullptr; +} + + +optional<tuple<uint64_t, Ref<Type>>> DebugInfo::GetDataVariableByName( + const string& parserName, const string& name) const +{ + BNDataVariableAndName* result = BNGetDebugDataVariableByName(m_object, parserName.c_str(), name.c_str()); + if (result) + { + BNFreeString(result->name); + return {{result->address, Ref<Type>(new Type(result->type))}}; + } + return {}; +} + + +optional<tuple<string, Ref<Type>>> DebugInfo::GetDataVariableByAddress( + const string& parserName, const uint64_t address) const +{ + BNDataVariableAndName* nameAndVar = BNGetDebugDataVariableByAddress(m_object, parserName.c_str(), address); + if (nameAndVar) + { + const tuple<string, Ref<Type>> result = {nameAndVar->name, Ref<Type>(new Type(nameAndVar->type))}; + BNFreeString(nameAndVar->name); + return {result}; + } + return {}; +} + + +// The tuple is (DebugInfoParserName, type) +vector<tuple<string, Ref<Type>>> DebugInfo::GetTypesByName(const string& name) const +{ + size_t count; + BNNameAndType* namesAndTypes = BNGetDebugTypesByName(m_object, name.c_str(), &count); + + vector<tuple<string, Ref<Type>>> result; + for (size_t i = 0; i < count; ++i) + { + result.emplace_back(namesAndTypes[i].name, Ref<Type>(new Type(BNNewTypeReference(namesAndTypes[i].type)))); + } + + BNFreeNameAndTypeList(namesAndTypes, count); + return result; +} + + +// The tuple is (DebugInfoParserName, address, type) +vector<tuple<string, uint64_t, Ref<Type>>> DebugInfo::GetDataVariablesByName(const string& name) const +{ + size_t count; + BNDataVariableAndName* variablesAndName = BNGetDebugDataVariablesByName(m_object, name.c_str(), &count); + + vector<tuple<string, uint64_t, Ref<Type>>> result; + for (size_t i = 0; i < count; ++i) + { + result.emplace_back(variablesAndName[i].name, variablesAndName[i].address, + Ref<Type>(new Type(BNNewTypeReference(variablesAndName[i].type)))); + } + + BNFreeDataVariablesAndName(variablesAndName, count); + return result; +} + + +// The tuple is (DebugInfoParserName, TypeName, type) +vector<tuple<string, string, Ref<Type>>> DebugInfo::GetDataVariablesByAddress(const uint64_t address) const +{ + size_t count; + BNDataVariableAndNameAndDebugParser* variablesAndName = BNGetDebugDataVariablesByAddress(m_object, address, &count); + + vector<tuple<string, string, Ref<Type>>> result; + for (size_t i = 0; i < count; ++i) + { + result.emplace_back(variablesAndName[i].parser, variablesAndName[i].name, + Ref<Type>(new Type(BNNewTypeReference(variablesAndName[i].type)))); + } + + BNFreeDataVariableAndNameAndDebugParserList(variablesAndName, count); + return result; +} + + +bool DebugInfo::RemoveParserInfo(const string& parserName) +{ + return BNRemoveDebugParserInfo(m_object, parserName.c_str()); +} + + +bool DebugInfo::RemoveParserTypes(const string& parserName) +{ + return BNRemoveDebugParserTypes(m_object, parserName.c_str()); +} + + +bool DebugInfo::RemoveParserFunctions(const string& parserName) +{ + return BNRemoveDebugParserFunctions(m_object, parserName.c_str()); +} + + +bool DebugInfo::RemoveParserDataVariables(const string& parserName) +{ + return BNRemoveDebugParserDataVariables(m_object, parserName.c_str()); +} + + +bool DebugInfo::RemoveTypeByName(const string& parserName, const string& name) +{ + return BNRemoveDebugTypeByName(m_object, parserName.c_str(), name.c_str()); +} + + +bool DebugInfo::RemoveFunctionByIndex(const string& parserName, const size_t index) +{ + return BNRemoveDebugFunctionByIndex(m_object, parserName.c_str(), index); +} + + +bool DebugInfo::RemoveDataVariableByAddress(const string& parserName, const uint64_t address) +{ + return BNRemoveDebugDataVariableByAddress(m_object, parserName.c_str(), address); +} + + bool DebugInfo::AddType(const string& name, Ref<Type> type) { return BNAddDebugType(m_object, name.c_str(), type->GetObject()); diff --git a/python/debuginfo.py b/python/debuginfo.py index 46f9e959..7b5a6dbc 100644 --- a/python/debuginfo.py +++ b/python/debuginfo.py @@ -283,6 +283,18 @@ class DebugInfo(object): def __del__(self) -> None: core.BNFreeDebugInfoReference(self.handle) + def get_parsers(self): + count = ctypes.c_ulonglong() + parsers = core.BNGetDebugParserNames(self.handle, count) + + result = [] + for i in range(count.value): + assert parsers is not None, "core.BNGetDebugParserNames returned None" + result.append(parsers[i]) + core.BNFreeStringList(parsers, count.value) + + return result + def types_from_parser(self, name: Optional[str] = None) -> Iterator[Tuple[str, _types.Type]]: """Returns a generator of all types provided by a named DebugInfoParser""" count = ctypes.c_ulonglong(0) @@ -364,6 +376,93 @@ class DebugInfo(object): """A generator of all data variables provided by DebugInfoParsers""" return self.data_variables_from_parser() + def get_type_by_name(self, parser_name: str, name: str) -> Optional[_types.Type]: + result = core.BNGetDebugTypeByName(self.handle, parser_name, name) + if result is not None: + return _types.Type(core.BNNewTypeReference(result)) + return None + + def get_data_variable_by_name(self, parser_name: str, name: str) -> Optional[Tuple[int, _types.Type]]: + result = core.BNGetDebugDataVariableByName(self.handle, parser_name, name) + if result is not None: + core.BNFreeString(result.name) + return (result.address, _types.Type(result.type)) + return None + + def get_data_variable_by_address(self, parser_name: str, address: int) -> Optional[Tuple[str, _types.Type]]: + name_and_var = core.BNGetDebugDataVariableByAddress(self.handle, parser_name, address) + if name_and_var is not None: + result = (str(name_and_var.name), _types.Type(name_and_var.type)) + core.BNFreeString(name_and_var.name) + return result + return None + + def get_types_by_name(self, name: str) -> List[Tuple[str, _types.Type]]: + """ The first element in the Tuple returned in the list is the name of the debug info parser the type came from """ + count = ctypes.c_ulonglong() + names_and_types = core.BNGetDebugTypesByName(self.handle, name, count) + + result = [] + for i in range(count.value): + assert names_and_types is not None, "core.BNGetDebugTypesByName returned None" + result.append((names_and_types[i].name, _types.Type(core.BNNewTypeReference(names_and_types[i].type)))) + + core.BNFreeNameAndTypeList(names_and_types, count.value) + return result + + def get_data_variables_by_name(self, name: str) -> List[Tuple[str, _types.Type]]: + """ The values in the tuples returned in the list is (DebugInfoParserName, address, type) """ + count = ctypes.c_ulonglong() + variables_and_name = core.BNGetDebugDataVariablesByName(self.handle, name, count) + + result = [] + for i in range(count.value): + assert variables_and_name is not None, "core.BNGetDebugDataVariablesByName returned None" + result.append(( + variables_and_name[i].name, variables_and_name[i].address, + _types.Type(core.BNNewTypeReference(variables_and_name[i].type)) + )) + + core.BNFreeDataVariablesAndName(variables_and_name, count.value) + return result + + def get_data_variables_by_address(self, address: int) -> List[Tuple[str, _types.Type]]: + """ The values in the tuples returned in the list is (DebugInfoParserName, TypeName, type) """ + count = ctypes.c_ulonglong() + variables_and_name = core.BNGetDebugDataVariablesByAddress(self.handle, address, count) + + result = [] + for i in range(count.value): + assert variables_and_name is not None, "core.BNGetDebugDataVariablesByAddress returned None" + result.append(( + variables_and_name[i].parser, variables_and_name[i].name, + _types.Type(core.BNNewTypeReference(variables_and_name[i].type)) + )) + + core.BNFreeDataVariableAndNameAndDebugParserList(variables_and_name, count.value) + return result + + def remove_parser_info(self, parser_name: str): + return core.BNRemoveDebugParserInfo(self.handle, parser_name) + + def remove_parser_types(self, parser_name: str): + return core.BNRemoveDebugParserTypes(self.handle, parser_name) + + def remove_parser_functions(self, parser_name: str): + return core.BNRemoveDebugParserFunctions(self.handle, parser_name) + + def remove_parser_data_variables(self, parser_name: str): + return core.BNRemoveDebugParserDataVariables(self.handle, parser_name) + + def remove_type_by_name(self, parser_name: str, name: str): + return core.BNRemoveDebugTypeByName(self.handle, parser_name, name) + + def remove_function_by_index(self, parser_name: str, index: int): + return core.BNRemoveDebugFunctionByIndex(self.handle, parser_name, index) + + def remove_data_variable_by_address(self, parser_name: str, address: int): + return core.BNRemoveDebugDataVariableByAddress(self.handle, parser_name, address) + def add_type(self, name: str, new_type: '_types.Type') -> bool: """Adds a type scoped under the current parser's name to the debug info""" if isinstance(new_type, _types.Type): diff --git a/rust/src/debuginfo.rs b/rust/src/debuginfo.rs index aad0f996..f780973c 100644 --- a/rust/src/debuginfo.rs +++ b/rust/src/debuginfo.rs @@ -494,6 +494,230 @@ impl DebugInfo { result } + /// May return nullptr + pub fn type_by_name<S: BnStrCompatible>(&self, parser_name: S, name: S) -> Option<Ref<Type>> { + let parser_name = parser_name.as_bytes_with_nul(); + let name = name.as_bytes_with_nul(); + + let result = unsafe { + BNGetDebugTypeByName( + self.handle, + parser_name.as_ref().as_ptr() as *mut _, + name.as_ref().as_ptr() as *mut _, + ) + }; + if !result.is_null() { + Some(unsafe { Type::ref_from_raw(result) }) + } else { + None + } + } + + pub fn get_data_variable_by_name<S: BnStrCompatible>( + &self, + parser_name: S, + name: S, + ) -> Option<(u64, Ref<Type>)> { + let parser_name = parser_name.as_bytes_with_nul(); + let name = name.as_bytes_with_nul(); + + let result = unsafe { + BNGetDebugDataVariableByName( + self.handle, + parser_name.as_ref().as_ptr() as *mut _, + name.as_ref().as_ptr() as *mut _, + ) + }; + + if !result.is_null() { + unsafe { BNFreeString((*result).name) }; + Some(unsafe { ((*result).address, Type::ref_from_raw((*result).type_)) }) + } else { + None + } + } + + pub fn get_data_variable_by_address<S: BnStrCompatible>( + &self, + parser_name: S, + address: u64, + ) -> Option<(String, Ref<Type>)> { + let parser_name = parser_name.as_bytes_with_nul(); + let name_and_var = unsafe { + BNGetDebugDataVariableByAddress( + self.handle, + parser_name.as_ref().as_ptr() as *mut _, + address, + ) + }; + + if !name_and_var.is_null() { + let result = unsafe { + ( + raw_to_string((*name_and_var).name).unwrap(), + Type::ref_from_raw((*name_and_var).type_), + ) + }; + unsafe { BNFreeString((*name_and_var).name) }; + Some(result) + } else { + None + } + } + + // The tuple is (DebugInfoParserName, type) + pub fn get_types_by_name<S: BnStrCompatible>(&self, name: S) -> Vec<(String, Ref<Type>)> { + let name = name.as_bytes_with_nul(); + + let mut count: usize = 0; + let raw_names_and_types = unsafe { + BNGetDebugTypesByName(self.handle, name.as_ref().as_ptr() as *mut _, &mut count) + }; + + let names_and_types: &[*mut BNNameAndType] = + unsafe { slice::from_raw_parts(raw_names_and_types as *mut _, count) }; + + let mut result = Vec::with_capacity(count); + for i in 0..count { + unsafe { + result.push(( + raw_to_string((*names_and_types[i]).name).unwrap(), + Type::ref_from_raw(BNNewTypeReference((*names_and_types[i]).type_)), + )) + }; + } + + unsafe { BNFreeNameAndTypeList(raw_names_and_types, count) }; + result + } + + // The tuple is (DebugInfoParserName, address, type) + pub fn get_data_variables_by_name<S: BnStrCompatible>( + &self, + name: S, + ) -> Vec<(String, u64, Ref<Type>)> { + let name = name.as_bytes_with_nul(); + + let mut count: usize = 0; + let raw_variables_and_names = unsafe { + BNGetDebugDataVariablesByName(self.handle, name.as_ref().as_ptr() as *mut _, &mut count) + }; + + let variables_and_names: &[*mut BNDataVariableAndName] = + unsafe { slice::from_raw_parts(raw_variables_and_names as *mut _, count) }; + + let mut result = Vec::with_capacity(count); + for i in 0..count { + unsafe { + result.push(( + raw_to_string((*variables_and_names[i]).name).unwrap(), + (*variables_and_names[i]).address, + Type::ref_from_raw(BNNewTypeReference((*variables_and_names[i]).type_)), + )) + }; + } + + unsafe { BNFreeDataVariablesAndName(raw_variables_and_names, count) }; + result + } + + /// The tuple is (DebugInfoParserName, TypeName, type) + pub fn get_data_variables_by_address(&self, address: u64) -> Vec<(String, String, Ref<Type>)> { + let mut count: usize = 0; + let raw_variables_and_names = + unsafe { BNGetDebugDataVariablesByAddress(self.handle, address, &mut count) }; + + let variables_and_names: &[*mut BNDataVariableAndNameAndDebugParser] = + unsafe { slice::from_raw_parts(raw_variables_and_names as *mut _, count) }; + + let mut result = Vec::with_capacity(count); + for i in 0..count { + unsafe { + result.push(( + raw_to_string((*variables_and_names[i]).parser).unwrap(), + raw_to_string((*variables_and_names[i]).name).unwrap(), + Type::ref_from_raw(BNNewTypeReference((*variables_and_names[i]).type_)), + )) + }; + } + + unsafe { BNFreeDataVariableAndNameAndDebugParserList(raw_variables_and_names, count) }; + result + } + + pub fn remove_parser_info<S: BnStrCompatible>(&self, parser_name: S) -> bool { + let parser_name = parser_name.as_bytes_with_nul(); + + unsafe { BNRemoveDebugParserInfo(self.handle, parser_name.as_ref().as_ptr() as *mut _) } + } + + pub fn remove_parser_types<S: BnStrCompatible>(&self, parser_name: S) -> bool { + let parser_name = parser_name.as_bytes_with_nul(); + + unsafe { BNRemoveDebugParserTypes(self.handle, parser_name.as_ref().as_ptr() as *mut _) } + } + + pub fn remove_parser_functions<S: BnStrCompatible>(&self, parser_name: S) -> bool { + let parser_name = parser_name.as_bytes_with_nul(); + + unsafe { + BNRemoveDebugParserFunctions(self.handle, parser_name.as_ref().as_ptr() as *mut _) + } + } + + pub fn remove_parser_data_variables<S: BnStrCompatible>(&self, parser_name: S) -> bool { + let parser_name = parser_name.as_bytes_with_nul(); + + unsafe { + BNRemoveDebugParserDataVariables(self.handle, parser_name.as_ref().as_ptr() as *mut _) + } + } + + pub fn remove_type_by_name<S: BnStrCompatible>(&self, parser_name: S, name: S) -> bool { + let parser_name = parser_name.as_bytes_with_nul(); + let name = name.as_bytes_with_nul(); + + unsafe { + BNRemoveDebugTypeByName( + self.handle, + parser_name.as_ref().as_ptr() as *mut _, + name.as_ref().as_ptr() as *mut _, + ) + } + } + + pub fn remove_function_by_index<S: BnStrCompatible>( + &self, + parser_name: S, + index: usize, + ) -> bool { + let parser_name = parser_name.as_bytes_with_nul(); + + unsafe { + BNRemoveDebugFunctionByIndex( + self.handle, + parser_name.as_ref().as_ptr() as *mut _, + index, + ) + } + } + + pub fn remove_data_variable_by_address<S: BnStrCompatible>( + &self, + parser_name: S, + address: u64, + ) -> bool { + let parser_name = parser_name.as_bytes_with_nul(); + + unsafe { + BNRemoveDebugDataVariableByAddress( + self.handle, + parser_name.as_ref().as_ptr() as *mut _, + address, + ) + } + } + /// Adds a type scoped under the current parser's name to the debug info pub fn add_type<S: BnStrCompatible>(&mut self, name: S, new_type: &Type) -> bool { let name = name.as_bytes_with_nul(); |
