summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorGlenn Smith <glenn@vector35.com>2023-02-20 21:58:55 -0500
committerGlenn Smith <glenn@vector35.com>2023-11-06 16:10:47 -0500
commit4108964609171327618627477163339656037111 (patch)
tree79f4c6da6394b973cee05cc42b6edd7e2e20909d /python
parentb270d7ebe1e2a406e1f7f14807987d24b0c4a846 (diff)
Type Containers
Diffstat (limited to 'python')
-rw-r--r--python/__init__.py1
-rw-r--r--python/binaryview.py18
-rw-r--r--python/debuginfo.py5
-rw-r--r--python/platform.py11
-rw-r--r--python/typecontainer.py246
-rw-r--r--python/typelibrary.py12
-rw-r--r--python/typeprinter.py30
-rw-r--r--python/types.py28
8 files changed, 319 insertions, 32 deletions
diff --git a/python/__init__.py b/python/__init__.py
index 4a9d1d1c..2fddefe4 100644
--- a/python/__init__.py
+++ b/python/__init__.py
@@ -69,6 +69,7 @@ from .secretsprovider import *
from .typeparser import *
from .typeprinter import *
from .component import *
+from .typecontainer import *
# We import each of these by name to prevent conflicts between
# log.py and the function 'log' which we don't import below
from .log import (
diff --git a/python/binaryview.py b/python/binaryview.py
index cd7a0cdf..d7d2a2a8 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -71,6 +71,7 @@ from . import function as _function
from . import types as _types
from . import platform as _platform
from . import deprecation
+from . import typecontainer
PathType = Union[str, os.PathLike]
InstructionsType = Generator[Tuple[List['_function.InstructionTextToken'], int], None, None]
@@ -1745,7 +1746,7 @@ class TypeMapping(collections.abc.Mapping): # type: ignore
def __del__(self):
if core is not None and self._type_list is not None:
- core.BNFreeTypeList(self._type_list, len(self))
+ core.BNFreeTypeAndNameList(self._type_list, len(self))
def __getitem__(self, key):
if self._type_cache is None:
@@ -6958,6 +6959,21 @@ class BinaryView:
raise ValueError(error_str)
return variable.PossibleValueSet(self.arch, result)
+ @property
+ def type_container(self) -> 'typecontainer.TypeContainer':
+ container = core.BNGetAnalysisTypeContainer(self.handle)
+ return typecontainer.TypeContainer(handle=container)
+
+ @property
+ def auto_type_container(self) -> 'typecontainer.TypeContainer':
+ container = core.BNGetAnalysisAutoTypeContainer(self.handle)
+ return typecontainer.TypeContainer(handle=container)
+
+ @property
+ def user_type_container(self) -> 'typecontainer.TypeContainer':
+ container = core.BNGetAnalysisUserTypeContainer(self.handle)
+ return typecontainer.TypeContainer(handle=container)
+
def get_type_by_name(self, name: '_types.QualifiedNameType') -> Optional['_types.Type']:
"""
``get_type_by_name`` returns the defined type whose name corresponds with the provided ``name``
diff --git a/python/debuginfo.py b/python/debuginfo.py
index 1b9bc712..65f879ea 100644
--- a/python/debuginfo.py
+++ b/python/debuginfo.py
@@ -31,6 +31,7 @@ from . import types as _types
from .log import log_error
from . import binaryview
from . import filemetadata
+from . import typecontainer
_debug_info_parsers = {}
ProgressFuncType = Callable[[int, int], bool]
@@ -303,6 +304,10 @@ class DebugInfo(object):
core.BNFreeStringList(parsers, count.value)
+ def get_type_container(self, parser_name: str) -> 'typecontainer.TypeContainer':
+ """Returns a TypeContainer interface for one of the parsers in this DebugInfo"""
+ return typecontainer.TypeContainer(core.BNGetDebugInfoTypeContainer(self.handle, parser_name))
+
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)
diff --git a/python/platform.py b/python/platform.py
index e60f9a8f..2c4a26f6 100644
--- a/python/platform.py
+++ b/python/platform.py
@@ -30,6 +30,7 @@ from . import typeparser
from . import callingconvention
from . import typelibrary
from . import architecture
+from . import typecontainer
class _PlatformMetaClass(type):
@@ -262,7 +263,7 @@ class Platform(metaclass=_PlatformMetaClass):
for i in range(0, count.value):
name = types.QualifiedName._from_core_struct(type_list[i].name)
result[name] = types.Type.create(core.BNNewTypeReference(type_list[i].type), platform=self)
- core.BNFreeTypeList(type_list, count.value)
+ core.BNFreeTypeAndNameList(type_list, count.value)
return result
@property
@@ -275,7 +276,7 @@ class Platform(metaclass=_PlatformMetaClass):
for i in range(0, count.value):
name = types.QualifiedName._from_core_struct(type_list[i].name)
result[name] = types.Type.create(core.BNNewTypeReference(type_list[i].type), platform=self)
- core.BNFreeTypeList(type_list, count.value)
+ core.BNFreeTypeAndNameList(type_list, count.value)
return result
@property
@@ -288,7 +289,7 @@ class Platform(metaclass=_PlatformMetaClass):
for i in range(0, count.value):
name = types.QualifiedName._from_core_struct(type_list[i].name)
result[name] = types.Type.create(core.BNNewTypeReference(type_list[i].type), platform=self)
- core.BNFreeTypeList(type_list, count.value)
+ core.BNFreeTypeAndNameList(type_list, count.value)
return result
@property
@@ -359,6 +360,10 @@ class Platform(metaclass=_PlatformMetaClass):
result = core.BNGetAssociatedPlatformByAddress(self.handle, new_addr)
return Platform(handle=result), new_addr.value
+ @property
+ def type_container(self) -> 'typecontainer.TypeContainer':
+ return typecontainer.TypeContainer(core.BNGetPlatformTypeContainer(self.handle))
+
def get_type_by_name(self, name):
name = types.QualifiedName(name)._to_core_struct()
obj = core.BNGetPlatformTypeByName(self.handle, name)
diff --git a/python/typecontainer.py b/python/typecontainer.py
new file mode 100644
index 00000000..3f371213
--- /dev/null
+++ b/python/typecontainer.py
@@ -0,0 +1,246 @@
+# Copyright (c) 2015-2023 Vector 35 Inc
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+
+import ctypes
+from typing import Optional, Mapping, Callable, List, Tuple
+
+# Binary Ninja components
+import binaryninja
+from . import _binaryninjacore as core
+from . import types as ty_
+from . import platform
+from . import typeparser
+from . import enums
+
+
+ProgressFuncType = Callable[[int, int], bool]
+
+
+class TypeContainer:
+ def __init__(self, handle: core.BNTypeContainerHandle):
+ binaryninja._init_plugins()
+ self.handle: core.BNTypeContainerHandle = core.handle_of_type(handle, core.BNTypeContainer)
+
+ def __del__(self):
+ if core is not None:
+ core.BNFreeTypeContainer(self.handle)
+
+ def __repr__(self):
+ return f"<type container {self.name}>"
+
+ @property
+ def id(self) -> str:
+ return core.BNTypeContainerGetId(self.handle)
+
+ @property
+ def name(self) -> str:
+ return core.BNTypeContainerGetName(self.handle)
+
+ @property
+ def container_type(self) -> 'enums.TypeContainerType':
+ return core.BNTypeContainerGetType(self.handle)
+
+ @property
+ def mutable(self) -> bool:
+ return core.BNTypeContainerIsMutable(self.handle)
+
+ @property
+ def platform(self) -> 'platform.Platform':
+ handle = core.BNTypeContainerGetPlatform(self.handle)
+ assert handle is not None
+ return platform.Platform(handle=handle)
+
+ def add_types(self, types: Mapping['ty_.QualifiedNameType', 'ty_.Type'], progress_func: Optional[ProgressFuncType] = None) -> Optional[Mapping['ty_.QualifiedName', str]]:
+ api_names = (core.BNQualifiedName * len(types))()
+ api_types = (ctypes.POINTER(core.BNType) * len(types))()
+ for (i, (key, value)) in enumerate(types.items()):
+ api_names[i] = ty_.QualifiedName(key)._to_core_struct()
+ api_types[i] = value.handle
+
+ if progress_func:
+ progress_func_obj = ctypes.CFUNCTYPE(
+ ctypes.c_bool, ctypes.c_void_p, ctypes.c_ulonglong, ctypes.c_ulonglong
+ )(lambda ctxt, cur, total: progress_func(cur, total))
+ else:
+ progress_func_obj = ctypes.CFUNCTYPE(
+ ctypes.c_bool, ctypes.c_void_p, ctypes.c_ulonglong, ctypes.c_ulonglong
+ )(lambda ctxt, cur, total: True)
+
+ result_names = ctypes.POINTER(core.BNQualifiedName)()
+ result_ids = ctypes.POINTER(ctypes.c_char_p)()
+ result_count = ctypes.c_size_t(0)
+
+ if not core.BNTypeContainerAddTypes(self.handle, api_names, api_types, len(types), progress_func_obj, None, result_names, result_ids, result_count):
+ return None
+
+ result = {}
+ for i in range(result_count.value):
+ name = ty_.QualifiedName._from_core_struct(result_names[i])
+ id = core.pyNativeStr(result_ids[i])
+ result[name] = id
+
+ core.BNFreeTypeNameList(result_names, result_count.value)
+ core.BNFreeStringList(result_ids, result_count.value)
+ return result
+
+ def rename_type(self, type_id: str, new_name: 'ty_.QualifiedNameType') -> bool:
+ return core.BNTypeContainerRenameType(self.handle, type_id, ty_.QualifiedName(new_name)._to_core_struct())
+
+ def delete_type(self, type_id: str) -> bool:
+ return core.BNTypeContainerDeleteType(self.handle, type_id)
+
+ def get_type_id(self, type_name: 'ty_.QualifiedNameType') -> Optional[str]:
+ result = ctypes.c_char_p()
+ if not core.BNTypeContainerGetTypeId(self.handle, ty_.QualifiedName(type_name)._to_core_struct(), result):
+ return None
+ return core.pyNativeStr(result.value)
+
+ def get_type_name(self, type_id: str) -> Optional['ty_.QualifiedName']:
+ api_result = core.BNQualifiedName()
+ if not core.BNTypeContainerGetTypeName(self.handle, type_id, api_result):
+ return None
+ result = ty_.QualifiedName._from_core_struct(api_result)
+ core.BNFreeQualifiedName(api_result)
+ return result
+
+ def get_type_by_id(self, type_id: str) -> Optional['ty_.Type']:
+ result = ctypes.POINTER(core.BNType)()
+ if not core.BNTypeContainerGetTypeById(self.handle, type_id, result):
+ return None
+ return ty_.Type(handle=result)
+
+ @property
+ def types(self) -> Optional[Mapping[str, Tuple['ty_.QualifiedName', 'ty_.Type']]]:
+ result_names = ctypes.POINTER(core.BNQualifiedName)()
+ result_ids = ctypes.POINTER(ctypes.c_char_p)()
+ result_types = ctypes.POINTER(ctypes.POINTER(core.BNType))()
+ result_count = ctypes.c_size_t(0)
+
+ if not core.BNTypeContainerGetTypes(self.handle, result_ids, result_names, result_types, result_count):
+ return None
+
+ result = {}
+ for i in range(result_count.value):
+ name = ty_.QualifiedName._from_core_struct(result_names[i])
+ id = core.pyNativeStr(result_ids[i])
+ type = ty_.Type(handle=core.BNNewTypeReference(result_types[i]))
+ result[id] = (name, type)
+
+ core.BNFreeTypeNameList(result_names, result_count.value)
+ core.BNFreeStringList(result_ids, result_count.value)
+ core.BNFreeTypeList(result_types, result_count.value)
+ return result
+
+ def get_type_by_name(self, type_name: 'ty_.QualifiedNameType') -> Optional['ty_.Type']:
+ result = ctypes.POINTER(core.BNType)()
+ if not core.BNTypeContainerGetTypeByName(self.handle, ty_.QualifiedName(type_name)._to_core_struct(), result):
+ return None
+ return ty_.Type(handle=result)
+
+ @property
+ def type_ids(self) -> Optional[List[str]]:
+ result_ids = ctypes.POINTER(ctypes.c_char_p)()
+ result_count = ctypes.c_size_t(0)
+ if not core.BNTypeContainerGetTypeIds(self.handle, result_ids, result_count):
+ return None
+
+ result = []
+ for i in range(result_count.value):
+ id = core.pyNativeStr(result_ids[i])
+ result.append(id)
+
+ core.BNFreeStringList(result_ids, result_count.value)
+ return result
+
+ @property
+ def type_names(self) -> Optional[List['ty_.QualifiedName']]:
+ result_names = ctypes.POINTER(core.BNQualifiedName)()
+ result_count = ctypes.c_size_t(0)
+ if not core.BNTypeContainerGetTypeNames(self.handle, result_names, result_count):
+ return None
+
+ result = []
+ for i in range(result_count.value):
+ name = ty_.QualifiedName._from_core_struct(result_names[i])
+ result.append(name)
+
+ core.BNFreeTypeNameList(result_names, result_count.value)
+ return result
+
+ @property
+ def type_names_and_ids(self) -> Optional[Mapping[str, 'ty_.QualifiedName']]:
+ result_names = ctypes.POINTER(core.BNQualifiedName)()
+ result_ids = ctypes.POINTER(ctypes.c_char_p)()
+ result_count = ctypes.c_size_t(0)
+ if not core.BNTypeContainerGetTypeNamesAndIds(self.handle, result_ids, result_names, result_count):
+ return None
+
+ result = {}
+ for i in range(result_count.value):
+ name = ty_.QualifiedName._from_core_struct(result_names[i])
+ id = core.pyNativeStr(result_ids[i])
+ result[id] = name
+
+ core.BNFreeTypeNameList(result_names, result_count.value)
+ core.BNFreeStringList(result_ids, result_count.value)
+ return result
+
+ def parse_types_from_source(self, source: str, file_name: str, platform: 'platform.Platform',
+ options: Optional[List[str]] = None, include_dirs: Optional[List[str]] = None,
+ auto_type_source: str = ""
+ ) -> Tuple[Optional['typeparser.TypeParserResult'], List['typeparser.TypeParserError']]:
+ if options is None:
+ options = []
+ if include_dirs is None:
+ include_dirs = []
+
+ options_cpp = (ctypes.c_char_p * len(options))()
+ for (i, s) in enumerate(options):
+ options_cpp[i] = core.cstr(s)
+
+ include_dirs_cpp = (ctypes.c_char_p * len(include_dirs))()
+ for (i, s) in enumerate(include_dirs):
+ include_dirs_cpp[i] = core.cstr(s)
+
+ result_cpp = core.BNTypeParserResult()
+ errors_cpp = ctypes.POINTER(core.BNTypeParserError)()
+ error_count = ctypes.c_size_t()
+
+ success = core.BNTypeContainerParseTypesFromSource(
+ self.handle, source, file_name, platform.handle,
+ options_cpp, len(options),
+ include_dirs_cpp, len(include_dirs), auto_type_source,
+ result_cpp, errors_cpp, error_count
+ )
+
+ if success:
+ result = typeparser.TypeParserResult._from_core_struct(result_cpp)
+ else:
+ result = None
+ core.BNFreeTypeParserResult(result_cpp)
+
+ errors = []
+ for i in range(error_count.value):
+ errors.append(typeparser.TypeParserError._from_core_struct(errors_cpp[i]))
+ core.BNFreeTypeParserErrors(errors_cpp, error_count.value)
+
+ return result, errors
+
+
diff --git a/python/typelibrary.py b/python/typelibrary.py
index 53f3e8ef..364a458d 100644
--- a/python/typelibrary.py
+++ b/python/typelibrary.py
@@ -28,6 +28,7 @@ from . import types
from . import metadata
from . import platform
from . import architecture
+from . import typecontainer
class TypeLibrary:
@@ -227,7 +228,7 @@ class TypeLibrary:
"""
return core.BNFinalizeTypeLibrary(self.handle)
- def query_metadata(self, key: str) -> Optional[metadata.Metadata]:
+ def query_metadata(self, key: str) -> Optional['metadata.MetadataValueType']:
"""
`query_metadata` retrieves a metadata associated with the given key stored in the type library
@@ -281,6 +282,15 @@ class TypeLibrary:
"""
core.BNTypeLibraryRemoveMetadata(self.handle, key)
+ @property
+ def type_container(self) -> 'typecontainer.TypeContainer':
+ """
+ `type_container` returns a TypeContainer interface for interacting with the type library.
+
+ :return: TypeContainer interface
+ """
+ return typecontainer.TypeContainer(core.BNGetTypeLibraryTypeContainer(self.handle))
+
def add_named_object(self, name: 'types.QualifiedName', type: 'types.Type') -> None:
"""
`add_named_object` directly inserts a named object into the type library's object store.
diff --git a/python/typeprinter.py b/python/typeprinter.py
index d7af3087..d6bf579e 100644
--- a/python/typeprinter.py
+++ b/python/typeprinter.py
@@ -35,6 +35,7 @@ from . import platform as _platform
from . import types
from . import function as _function
from . import binaryview
+from . import typecontainer
from .log import log_error
from .enums import TokenEscapingType
@@ -220,11 +221,11 @@ class TypePrinter(metaclass=_TypePrinterMetaclass):
log_error(traceback.format_exc())
return False
- def _get_type_lines(self, ctxt, type, data, name, line_width, collapsed, escaping, result, result_count):
+ def _get_type_lines(self, ctxt, type, container, name, line_width, collapsed, escaping, result, result_count):
try:
result_py = self.get_type_lines(
types.Type.create(handle=core.BNNewTypeReference(type)),
- binaryview.BinaryView(handle=core.BNNewViewReference(data)),
+ typecontainer.TypeContainer(handle=container),
types.QualifiedName._from_core_struct(name.contents),
line_width, collapsed, escaping)
@@ -378,12 +379,12 @@ class TypePrinter(metaclass=_TypePrinterMetaclass):
"""
raise NotImplementedError()
- def get_type_lines(self, type: types.Type, data: binaryview.BinaryView, name: types.QualifiedNameType, line_width = 80, collapsed = False, escaping: TokenEscapingType = TokenEscapingType.BackticksTokenEscapingType) -> List[types.TypeDefinitionLine]:
+ def get_type_lines(self, type: types.Type, container: 'typecontainer.TypeContainer', name: types.QualifiedNameType, line_width = 80, collapsed = False, escaping: TokenEscapingType = TokenEscapingType.BackticksTokenEscapingType) -> List[types.TypeDefinitionLine]:
"""
Generate a multi-line representation of a type
:param type: Type to print
- :param data: Binary View in which the type is defined
+ :param container: Type Container containing the type and dependencies
:param name: Name of the type
:param line_width: Maximum width of lines, in characters
:param collapsed: Whether to collapse structure/enum blocks
@@ -488,31 +489,20 @@ class CoreTypePrinter(TypePrinter):
core.free_string(result_cpp)
return result
- def get_type_lines(self, type: types.Type, data: binaryview.BinaryView,
- name: types.QualifiedNameType, line_width = 80, collapsed = False,
+ def get_type_lines(self, type: types.Type, container: 'typecontainer.TypeContainer',
+ name: types.QualifiedNameType,
+ line_width = 80, collapsed = False,
escaping: TokenEscapingType = TokenEscapingType.BackticksTokenEscapingType
) -> List[types.TypeDefinitionLine]:
if not isinstance(name, types.QualifiedName):
name = types.QualifiedName(name)
count = ctypes.c_ulonglong()
core_lines = ctypes.POINTER(core.BNTypeDefinitionLine)()
- if not core.BNGetTypePrinterTypeLines(self.handle, type.handle, data.handle, name._to_core_struct(), line_width, collapsed, ctypes.c_int(escaping), core_lines, count):
+ if not core.BNGetTypePrinterTypeLines(self.handle, type.handle, container.handle, name._to_core_struct(), line_width, collapsed, ctypes.c_int(escaping), core_lines, count):
raise RuntimeError("BNGetTypePrinterTypeLines returned False")
lines = []
for i in range(count.value):
- tokens = _function.InstructionTextToken._from_core_struct(core_lines[i].tokens, core_lines[i].count)
- type_ = types.Type.create(handle=core.BNNewTypeReference(core_lines[i].type), platform=data.platform)
- root_type = types.Type.create(handle=core.BNNewTypeReference(core_lines[i].rootType), platform=data.platform)
- root_type_name = core.pyNativeStr(core_lines[i].rootTypeName)
- if core_lines[i].baseType:
- const_conf = types.BoolWithConfidence.get_core_struct(False, 0)
- volatile_conf = types.BoolWithConfidence.get_core_struct(False, 0)
- handle = core.BNCreateNamedTypeReference(core_lines[i].baseType, 0, 1, const_conf, volatile_conf)
- base_type = types.NamedTypeReferenceType(handle, data.platform)
- else:
- base_type = None
- line = types.TypeDefinitionLine(core_lines[i].lineType, tokens, type_, root_type, root_type_name, base_type,
- core_lines[i].baseOffset, core_lines[i].offset, core_lines[i].fieldIndex)
+ line = types.TypeDefinitionLine._from_core_struct(core_lines[i], container.platform)
lines.append(line)
core.BNFreeTypeDefinitionLineList(core_lines, count.value)
return lines
diff --git a/python/types.py b/python/types.py
index 96532a4d..9fbe7a93 100644
--- a/python/types.py
+++ b/python/types.py
@@ -37,6 +37,7 @@ from . import variable
from . import architecture
from . import binaryview
from . import platform as _platform
+from . import typecontainer
from . import typelibrary
from . import typeparser
@@ -47,7 +48,7 @@ ParamsType = Union[List['Type'], List['FunctionParameter'], List[Tuple[str, 'Typ
MembersType = Union[List['StructureMember'], List['Type'], List[Tuple['Type', str]]]
EnumMembersType = Union[List[Tuple[str, int]], List[str], List['EnumerationMember']]
SomeType = Union['TypeBuilder', 'Type']
-TypeContainer = Union['binaryview.BinaryView', 'typelibrary.TypeLibrary']
+TypeContainerType = Union['binaryview.BinaryView', 'typelibrary.TypeLibrary']
NameSpaceType = Optional[Union[str, List[str], 'NameSpace']]
TypeParserResult = typeparser.TypeParserResult
# The following are needed to prevent the type checker from getting
@@ -515,7 +516,7 @@ class BoolWithConfidence:
@dataclass
class MutableTypeBuilder(Generic[TB]):
type: TB
- container: TypeContainer
+ container: TypeContainerType
name: QualifiedName
platform: Optional['_platform.Platform']
confidence: int
@@ -601,7 +602,7 @@ class TypeBuilder:
@classmethod
def builder(
- cls: typing.Type[TB], container: TypeContainer, name: 'QualifiedName', user: bool = True, platform: Optional['_platform.Platform'] = None,
+ cls: typing.Type[TB], container: TypeContainerType, name: 'QualifiedName', user: bool = True, platform: Optional['_platform.Platform'] = None,
confidence: int = core.max_confidence
) -> 'MutableTypeBuilder[TB]':
return MutableTypeBuilder(cls.create(), container, name, platform, confidence, user)
@@ -1997,7 +1998,7 @@ class Type:
return result
def get_lines(
- self, bv: 'binaryview.BinaryView', name: str, line_width: int = 80, collapsed: bool = False,
+ self, bv: Union['binaryview.BinaryView', 'typecontainer.TypeContainer'], name: str, line_width: int = 80, collapsed: bool = False,
escaping: TokenEscapingType = TokenEscapingType.NoTokenEscapingType
) -> List['TypeDefinitionLine']:
"""
@@ -2014,7 +2015,13 @@ class Type:
:rtype: :py:class:`TypeDefinitionLine`
"""
count = ctypes.c_ulonglong()
- core_lines = core.BNGetTypeLines(self._handle, bv.handle, name, line_width, collapsed, escaping, count)
+ if isinstance(bv, (binaryview.BinaryView,)):
+ container = bv.type_container
+ elif isinstance(bv, (typecontainer.TypeContainer,)):
+ container = bv
+ else:
+ assert False, "Unexpected type container type"
+ core_lines = core.BNGetTypeLines(self._handle, container.handle, name, line_width, collapsed, escaping, count)
assert core_lines is not None, "core.BNGetTypeLines returned None"
lines = []
for i in range(count.value):
@@ -2526,10 +2533,17 @@ class StructureType(Type):
def type(self) -> StructureVariant:
return StructureVariant(core.BNGetStructureType(self.struct_handle))
- def members_including_inherited(self, view: 'binaryview.BinaryView') -> List[InheritedStructureMember]:
+ def members_including_inherited(self, view: Union['binaryview.BinaryView', 'typecontainer.TypeContainer']) -> List[InheritedStructureMember]:
"""Returns structure member list, including those inherited by base structures"""
count = ctypes.c_ulonglong()
- members = core.BNGetStructureMembersIncludingInherited(self.struct_handle, view.handle, count)
+ if isinstance(view, (binaryview.BinaryView,)):
+ container = view.type_container
+ elif isinstance(view, (typecontainer.TypeContainer,)):
+ container = view
+ else:
+ assert False, "Unexpected type container type"
+
+ members = core.BNGetStructureMembersIncludingInherited(self.struct_handle, container.handle, count)
assert members is not None, "core.BNGetInheritedStructureMembers returned None"
try:
result = []