Files
decomp.me/backend/coreapp/m2c_wrapper.py
ConorB 721a08ccdf Make exception_on_timeout production-compatible, add more timeouts (#653)
* Force exception_on_timeout to use spawn to make gunicorn happy

* black

* Have test_fpr_reg_names_output and test_giant_compilation test for success as opposed to a lack of output

* Refactor timeouts for:
- compiling
- decompiling
- assembling
- disassembling

* Move m2c timeout wrapper to prevent interfering with StringIO

* Increase default timeouts by an order of magnitude to investigate failing CI tests

* Add timeout scale factor, have CI timeouts be 10x default

Co-authored-by: ConorBobbleHat <c.github@firstpartners.net>
2023-01-15 01:28:48 +09:00

71 lines
1.8 KiB
Python

import contextlib
import io
import logging
from m2c.main import parse_flags, run
from coreapp.compilers import Compiler
from coreapp.sandbox import Sandbox
logger = logging.getLogger(__name__)
class M2CError(Exception):
pass
class M2CWrapper:
@staticmethod
def get_triple(compiler: Compiler, arch: str) -> str:
if "mips" in arch:
t_arch = "mips"
elif "ppc" in arch:
t_arch = "ppc"
else:
raise M2CError(f"Unsupported arch '{arch}'")
if compiler.is_ido:
t_compiler = "ido"
elif compiler.is_gcc:
t_compiler = "gcc"
elif compiler.is_mwcc:
t_compiler = "mwcc"
else:
raise M2CError(f"Unsupported compiler '{compiler}'")
return f"{t_arch}-{t_compiler}"
@staticmethod
def decompile(asm: str, context: str, compiler: Compiler, arch: str) -> str:
with Sandbox() as sandbox:
flags = ["--stop-on-error", "--pointer-style=left"]
flags.append(f"--target={M2CWrapper.get_triple(compiler, arch)}")
# Create temp asm file
asm_path = sandbox.path / "asm.s"
asm_path.write_text(asm)
if context:
# Create temp context file
ctx_path = sandbox.path / "ctx.c"
ctx_path.write_text(context)
flags.append("--context")
flags.append(str(ctx_path))
flags.append(str(asm_path))
options = parse_flags(flags)
out_string = io.StringIO()
with contextlib.redirect_stdout(out_string):
returncode = run(options)
out_text = out_string.getvalue()
if returncode == 0:
return out_text
else:
raise M2CError(out_text)