SymbolMapping object is used to improve performance of the `bv.symbols` API. This allows pythonic code like this to have reasonable performance characteristics >>> my_symbols = get_my_symbols() >>> for symbol in my_symbols: >>> if bv.symbols[symbol].address == 0x41414141: >>> print("
| 1922 | |
| 1923 | |
| 1924 | class SymbolMapping(collections.abc.Mapping): # type: ignore |
| 1925 | """ |
| 1926 | SymbolMapping object is used to improve performance of the `bv.symbols` API. |
| 1927 | This allows pythonic code like this to have reasonable performance characteristics |
| 1928 | |
| 1929 | >>> my_symbols = get_my_symbols() |
| 1930 | >>> for symbol in my_symbols: |
| 1931 | >>> if bv.symbols[symbol].address == 0x41414141: |
| 1932 | >>> print("Found") |
| 1933 | |
| 1934 | """ |
| 1935 | def __init__(self, view: 'BinaryView'): |
| 1936 | self._symbol_list = None |
| 1937 | self._count = None |
| 1938 | self._symbol_cache: Optional[Mapping[str, List[_types.CoreSymbol]]] = None |
| 1939 | self._view = view |
| 1940 | self._n = 0 |
| 1941 | self._keys = None |
| 1942 | |
| 1943 | def __repr__(self): |
| 1944 | return f"<SymbolMapping {len(self)} symbols: {self._symbol_cache}>" |
| 1945 | |
| 1946 | def __del__(self): |
| 1947 | if core is not None and self._symbol_list is not None: |
| 1948 | core.BNFreeSymbolList(self._symbol_list, len(self)) |
| 1949 | |
| 1950 | def __getitem__(self, key: str) -> Optional[List['_types.CoreSymbol']]: |
| 1951 | if self._symbol_cache is None: |
| 1952 | sym = self._view.get_symbols_by_raw_name(key) |
| 1953 | if len(sym) == 0: |
| 1954 | raise KeyError(f"'{key}': symbol not found") |
| 1955 | return sym |
| 1956 | else: |
| 1957 | return self._symbol_cache[key] |
| 1958 | |
| 1959 | def _build_symbol_cache(self): |
| 1960 | count = ctypes.c_ulonglong(0) |
| 1961 | self._symbol_list = core.BNGetSymbols(self._view.handle, count, None) |
| 1962 | assert self._symbol_list is not None, "core.BNGetSymbols returned None" |
| 1963 | self._symbol_cache = {} |
| 1964 | self._count = count.value |
| 1965 | for i in range(len(self)): |
| 1966 | _handle = core.BNNewSymbolReference(self._symbol_list[i]) |
| 1967 | assert _handle is not None, "core.BNNewSymbolReference returned None" |
| 1968 | sym = _types.CoreSymbol(_handle) |
| 1969 | try: |
| 1970 | if sym.raw_name in self._symbol_cache: |
| 1971 | self._symbol_cache[sym.raw_name].append(sym) |
| 1972 | else: |
| 1973 | self._symbol_cache[sym.raw_name] = [sym] |
| 1974 | except UnicodeDecodeError: |
| 1975 | mapped_str = sym.raw_bytes.decode('charmap') |
| 1976 | if mapped_str in self._symbol_cache: |
| 1977 | self._symbol_cache[mapped_str].append(sym) |
| 1978 | else: |
| 1979 | self._symbol_cache[mapped_str] = [sym] |
| 1980 | |
| 1981 | def __iter__(self) -> Iterator[str]: |