change __main__ to simple WIP text CIL emitter
This commit is contained in:
parent
a05727c3a1
commit
6eb2e07dd3
|
@ -1,17 +1,80 @@
|
|||
import sys
|
||||
|
||||
from dotnet.types import CLISignature
|
||||
from dotnet.tables import CLITableType
|
||||
from dotnet.tables import CLITableType, CLIMethodCodeType
|
||||
from dotnet.file import CLIFile
|
||||
from dotnet.code import CILFlags
|
||||
from dotnet.cil import parse as disassemble
|
||||
|
||||
def emit_bytes(b):
|
||||
return '(' + ' '.join(hex(c)[2:] for c in b) + ')'
|
||||
|
||||
def emit_ident(e):
|
||||
return e.name.lower() if e.name else ''
|
||||
|
||||
def emit_type(s):
|
||||
return str(s)
|
||||
|
||||
def emit_flags(fs):
|
||||
return ' '.join(emit_ident(f) for f in fs)
|
||||
|
||||
def emit_assembly(a):
|
||||
flags = ' external' if a.external else ''
|
||||
print('.assembly{} {}'.format(flags, a.name))
|
||||
print('{')
|
||||
print(' .ver {}:{}:{}:{}'.format(a.version_major, a.version_minor, a.build_number, a.rev_number))
|
||||
if a.public_key:
|
||||
print(' .publickeytoken = {}'.format(emit_bytes(a.public_key)))
|
||||
elif not a.external:
|
||||
print(' .hash algorithm 0x{:08X}'.format(a.hash_algo.value))
|
||||
print('}')
|
||||
|
||||
def emit_field(f):
|
||||
flags = [f.flags.access]
|
||||
print(' .field {} {} \'{}\''.format(emit_flags(flags), emit_type(f.signature), f.name))
|
||||
|
||||
def emit_cil(c):
|
||||
print(' .maxstack {}'.format(c.stack_size))
|
||||
if c.vars:
|
||||
print(' .locals{} ({})'.format(
|
||||
' init' if c.attribs.flags & CILFlags.InitLocals else '',
|
||||
', '.join(emit_type(t) for t in c.vars.signature.signature.vars)
|
||||
))
|
||||
for ins in disassemble(c.code):
|
||||
print(' ' + str(ins))
|
||||
|
||||
def emit_method(m):
|
||||
flags = [m.flags.access, m.flags.flags]
|
||||
impl_flags = [m.impl_flags.code_type, m.impl_flags.managed]
|
||||
ret_type = m.signature.signature.ret_type
|
||||
param_types = m.signature.signature.params
|
||||
print(' .method {} {} {}({}) {}'.format(
|
||||
emit_flags(flags), emit_type(ret_type), m.name,
|
||||
', '.join(emit_type(t) + ' ' + p.name for p, t in zip(m.params, param_types)),
|
||||
emit_flags(impl_flags)
|
||||
))
|
||||
print(' {')
|
||||
if m.impl_flags.code_type == CLIMethodCodeType.CIL:
|
||||
emit_cil(m.code)
|
||||
else:
|
||||
print(' # Unimplemented: {}'.format(m.impl_flags.code_type.name))
|
||||
print(' }')
|
||||
|
||||
def emit_class(c):
|
||||
flags = [c.flags.visibility, c.flags.layout, c.flags.formatting]
|
||||
print('.class {} {}'.format(emit_flags(flags), c.name))
|
||||
print('{')
|
||||
for f in c.fields:
|
||||
emit_field(f)
|
||||
for m in c.methods:
|
||||
emit_method(m)
|
||||
print('}')
|
||||
|
||||
file = CLIFile(sys.argv[1])
|
||||
print(f'Entrypoint: {file.entrypoint.name}')
|
||||
for cls in file.get_table(CLITableType.TypeDef):
|
||||
print('---')
|
||||
print(f'Class: {cls.name}')
|
||||
print('Fields:')
|
||||
for f in cls.fields:
|
||||
print(f'- {f.name}: {f.signature}')
|
||||
print('Methods:')
|
||||
for m in cls.methods:
|
||||
print(f'- {m.name}: {m.signature}')
|
||||
for a in file.referenced_assemblies:
|
||||
emit_assembly(a)
|
||||
emit_assembly(file.assembly)
|
||||
for i, c in enumerate(file.classes):
|
||||
emit_class(c)
|
||||
if i >= 4:
|
||||
break
|
||||
|
|
Loading…
Reference in New Issue