mirror of
https://github.com/JakeHillion/drgn.git
synced 2024-12-24 10:03:05 +00:00
75c3679147
The current mixed Python/C implementation works well, but it has a couple of important limitations: - It's too slow for some common use cases, like iterating over large data structures. - It can't be reused in utilities written in other languages. This replaces the internals with a new library written in C, libdrgn. It includes Python bindings with mostly the same public interface as before, with some important improvements: - Types are now represented by a single Type class rather than the messy polymorphism in the Python implementation. - Qualifiers are a bitmask instead of a set of strings. - Bit fields are not considered a separate type. - The lvalue/rvalue terminology is replaced with reference/value. - Structure, union, and array values are better supported. - Function objects are supported. - Program distinguishes between lookups of variables, constants, and functions. The C rewrite is about 6x as fast as the original Python when using the Python bindings, and about 8x when using the C API directly. Currently, the exposed API in C is fairly conservative. In the future, the memory reader, type index, and object index APIs will probably be exposed for more flexibility.
62 lines
1.6 KiB
Python
Executable File
62 lines
1.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import re
|
|
|
|
|
|
prefixes = [
|
|
'DW_AT',
|
|
'DW_ATE',
|
|
'DW_CHILDREN',
|
|
'DW_FORM',
|
|
'DW_LNE',
|
|
'DW_LNS',
|
|
'DW_OP',
|
|
'DW_TAG',
|
|
]
|
|
|
|
if __name__ == '__main__':
|
|
with open('/usr/include/dwarf.h', 'r') as f:
|
|
dwarf_h = f.read()
|
|
dwarf_h = re.sub(r'/\*.*?\*/', '', dwarf_h, flags=re.DOTALL)
|
|
dwarf_h = re.sub(r'\\\n', '', dwarf_h)
|
|
matches = re.findall(r'^\s*(' + '|'.join(prefixes) + r')_(\w+)\s*=\s*(0x[0-9a-fA-F]+|[0-9]+)',
|
|
dwarf_h, re.MULTILINE)
|
|
|
|
enums = {}
|
|
for enum, name, value in matches:
|
|
try:
|
|
enums[enum].append((name, int(value, 0)))
|
|
except KeyError:
|
|
enums[enum] = [(name, int(value, 0))]
|
|
|
|
print("""\
|
|
# Automatically generated from dwarf.h
|
|
|
|
import enum
|
|
from typing import Text
|
|
|
|
""")
|
|
first = True
|
|
for enum in prefixes:
|
|
assert enums[enum]
|
|
if not first:
|
|
print()
|
|
print()
|
|
first = False
|
|
print(f'class {enum}(enum.IntEnum):')
|
|
for name, value in enums[enum]:
|
|
if name in ['import', 'not', 'and', 'or']:
|
|
name += '_'
|
|
print(f' {name} = 0x{value:x}', end='')
|
|
if name == 'name':
|
|
print(' # type: ignore')
|
|
else:
|
|
print()
|
|
print()
|
|
print(' @classmethod')
|
|
print(' def str(cls, value: int) -> Text:')
|
|
print(' try:')
|
|
print(f" return f'{enum}_{{cls(value).name}}'")
|
|
print(' except ValueError:')
|
|
print(' return hex(value)')
|