Browse Source

change __main__ to simple WIP text CIL emitter

master
Shiz 1 year ago
parent
commit
6eb2e07dd3
1 changed files with 74 additions and 11 deletions
  1. +74
    -11
      dotnet/__main__.py

+ 74
- 11
dotnet/__main__.py View File

@ -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…
Cancel
Save