about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAymeric Vincent <13720957+a-vincent@users.noreply.github.com>2019-09-24 13:41:25 +0200
committerAymeric Vincent <13720957+a-vincent@users.noreply.github.com>2019-09-25 14:18:53 +0200
commitdd23691c86890e865d1e5fbe45ccdd591737dfa3 (patch)
treed3d7d597a5e13f54e7a083e53bd47b3782fb2ff6
parenta92af0c6e3a5d52e3ec1b1f549fdd68784dc328e (diff)
downloadmiasm-dd23691c86890e865d1e5fbe45ccdd591737dfa3.tar.gz
miasm-dd23691c86890e865d1e5fbe45ccdd591737dfa3.zip
Add a few PPC32 tests
-rw-r--r--test/arch/ppc32/arch.py117
-rw-r--r--test/arch/ppc32/sem.py129
-rwxr-xr-xtest/test_all.py2
3 files changed, 248 insertions, 0 deletions
diff --git a/test/arch/ppc32/arch.py b/test/arch/ppc32/arch.py
new file mode 100644
index 00000000..c10a046e
--- /dev/null
+++ b/test/arch/ppc32/arch.py
@@ -0,0 +1,117 @@
+import logging
+import time
+from miasm.arch.ppc.arch import mn_ppc
+from miasm.core.bin_stream import bin_stream_str
+from miasm.core.utils import decode_hex, encode_hex
+from pdb import pm
+
+def h2i(s):
+    return decode_hex(s.replace(' ', ''))
+
+reg_tests = [
+    ('b', "XXXXXXXX    ADDI       R1, R1, 0x20", "38210020"),
+    ('b', "XXXXXXXX    ADDI       R3, R4, 0x12", "38640012"),
+    ('b', "XXXXXXXX    ADDIC      R3, R4, 0x12", "30640012"),
+    ('b', "XXXXXXXX    ADDIC      R9, R0, 0xFFFFFFFF", "3120FFFF"),
+    ('b', "XXXXXXXX    ADDIC.     R3, R4, 0x12", "34640012"),
+    ('b', "XXXXXXXX    ADDIC.     R31, R31, 0xFFFFFFFE", "37fffffe"),
+    ('b', "XXXXXXXX    ADDIS      R3, R4, 0x12", "3c640012"),
+    ('b', "XXXXXXXX    ADDIS      R9, R9, 0xD76B", "3d29d76b"),
+    ('b', "XXXXXXXX    AND        R8, R11, R28", "7d68e038"),
+    ('b', "XXXXXXXX    AND.       R11, R9, R0", "7d2b0039"),
+    ('b', "XXXXXXXX    ANDC       R0, R17, R19", "7e209878"),
+    ('b', "XXXXXXXX    ANDC.      R9, R10, R0", "7d490079"),
+    ('b', "XXXXXXXX    ANDI.      R9, R0, 0x1", "70090001"),
+    ('b', "XXXXXXXX    ANDIS.     R9, R0, 0x1000", "74091000"),
+    ('b', "XXXXXXXX    B          0xBEE0", "4800bee0"),
+    ('b', "XXXXXXXX    BA         0xBEE0", "4800bee2"),
+    ('b', "XXXXXXXX    BGE        CR0, 0x18", "40a00018"),
+    ('b', "XXXXXXXX    BGEA       CR0, 0x18", "40a0001a"),
+    ('b', "XXXXXXXX    BGECTR     CR0", "4ca00420"),
+    ('b', "XXXXXXXX    BGECTRL    CR0", "4ca00421"),
+    ('b', "XXXXXXXX    BGEL       CR0, 0x18", "40a00019"),
+    ('b', "XXXXXXXX    BGELA      CR0, 0x18", "40a0001b"),
+    ('b', "XXXXXXXX    BGELR      CR0", "4ca00020"),
+    ('b', "XXXXXXXX    BGELRL     CR0", "4ca00021"),
+    ('b', "XXXXXXXX    CMPLWI     CR7, R5, 0xBEEF", "2b85beef"),
+    ('b', "XXXXXXXX    CMPW       CR3, R3, R2", "7d831000"),
+    ('b', "XXXXXXXX    CMPWI      CR0, R0, 0x12", "2c000012"),
+    ('b', "XXXXXXXX    CRAND      0x3, 0x5, 0x2", "4c651202"),
+    ('b', "XXXXXXXX    ISYNC", "4c00012c"),
+    ('b', "XXXXXXXX    LBZ        R11, 0xFFFFFFFE(R9)", "8969fffe"),
+    ('b', "XXXXXXXX    LBZU       R0, 0x1(R31)", "8c1f0001"),
+    ('b', "XXXXXXXX    LBZUX      R0, R31, R3", "7c1f18ee"),
+    ('b', "XXXXXXXX    LBZX       R0, R30, R31", "7c1ef8ae"),
+    ('b', "XXXXXXXX    LHA        R9, 0x8(R31)", "a93f0008"),
+    ('b', "XXXXXXXX    LHAU       R0, 0xFFFFFFFE(R9)", "ac09fffe"),
+    ('b', "XXXXXXXX    LHAX       R0, R11, R9", "7c0b4aae"),
+    ('b', "XXXXXXXX    LHZ        R0, 0xC(R28)", "a01c000c"),
+    ('b', "XXXXXXXX    LHZX       R0, R9, R10", "7c09522e"),
+    ('b', "XXXXXXXX    LMW        R14, 0x8(R1)", "b9c10008"),
+    ('b', "XXXXXXXX    LSWI       R5, R4, 0xC", "7ca464aa"),
+    ('b', "XXXXXXXX    LWZ        R0, 0x24(R1)", "80010024"),
+    ('b', "XXXXXXXX    LWZU       R0, 0x4(R7)", "84070004"),
+    ('b', "XXXXXXXX    LWZX       R29, R25, R0", "7fb9002e"),
+    ('b', "XXXXXXXX    MCRF       CR1, CR2", "4c880000"),
+    ('b', "XXXXXXXX    MULLI      R0, R2, 0xFFFFFFE7", "1c02ffe7"),
+    ('b', "XXXXXXXX    MULLI      R3, R30, 0xC", "1c7e000c"),
+    ('b', "XXXXXXXX    NAND       R0, R0, R0", "7c0003b8"),
+    ('b', "XXXXXXXX    OR         R8, R0, R9", "7c084b78"),
+    ('b', "XXXXXXXX    OR.        R8, R0, R11", "7c085b79"),
+    ('b', "XXXXXXXX    ORC        R9, R19, R17", "7e698b38"),
+    ('b', "XXXXXXXX    ORI        R0, R0, 0xBEAF", "6000beaf"),
+    ('b', "XXXXXXXX    ORI        R0, R9, 0x2", "61200002"),
+    ('b', "XXXXXXXX    ORIS       R29, R29, 0x1", "67bd0001"),
+    ('b', "XXXXXXXX    RFI", "4c000064"),
+    ('b', "XXXXXXXX    RLWIMI     R3, R2, 0x3, 0x1, 0x10", "50431860"),
+    ('b', "XXXXXXXX    RLWNM.     R3, R2, R4, 0x1, 0x10", "5c432061"),
+    ('b', "XXXXXXXX    SC", "44000002"),
+    ('b', "XXXXXXXX    SLW        R11, R23, R31", "7eebf830"),
+    ('b', "XXXXXXXX    SRAW       R0, R11, R31", "7d60fe30"),
+    ('b', "XXXXXXXX    SRAWI      R0, R10, 0x3", "7d401e70"),
+    ('b', "XXXXXXXX    SRW        R0, R23, R10", "7ee05430"),
+    ('b', "XXXXXXXX    STB        R0, 0x1020(R30)", "981e1020"),
+    ('b', "XXXXXXXX    STBU       R0, 0x1(R11)", "9c0b0001"),
+    ('b', "XXXXXXXX    STH        R6, (R3)", "b0c30000"),
+    ('b', "XXXXXXXX    STMW       R14, 0x8(R1)", "bdc10008"),
+    ('b', "XXXXXXXX    STW        R0, 0x24(R1)", "90010024"),
+    ('b', "XXXXXXXX    STWU       R1, 0xFFFFFFE0(R1)", "9421ffe0"),
+    ('b', "XXXXXXXX    SUBFIC     R0, R2, 0xFFFFFFE0", "2002ffe0"),
+    ('b', "XXXXXXXX    SUBFIC     R11, R31, 0x0", "217f0000"),
+    ('b', "XXXXXXXX    TW         0x5, R0, R3", "7ca01808"),
+    ('b', "XXXXXXXX    TWI        0x5, R0, 0x12", "0ca00012"),
+    ('b', "XXXXXXXX    XORI       R9, R0, 0x62", "68090062"),
+    ('b', "XXXXXXXX    XORIS      R10, R10, 0x8000", "6d4a8000"),
+]
+
+ts = time.time()
+for mode, s, l, in reg_tests:
+    print("-" * 80)
+    s = s[12:]
+    b = h2i(l)
+    print("fromstring %r" % s)
+    l = mn_ppc.fromstring(s, None, mode)
+    for x in mn_ppc.asm(l):
+        print('(%r, "XXXXXXXX    %s", "%s"),' % (mode, l, encode_hex(x)))
+    print("%s %r" % (mode, b))
+    mn = mn_ppc.dis(b, mode)
+    print("dis args %s" % [(str(x), x.size) for x in mn.args])
+    print(s)
+    print(mn)
+    assert(str(mn).strip() == s)
+    print('fromstring %r' % s)
+    l = mn_ppc.fromstring(s, None, mode)
+    print('str args %s' % [(str(x), x.size) for x in l.args])
+    assert(str(l).strip(' ') == s)
+    a = mn_ppc.asm(l)
+    print('asm result %s' % [x for x in a])
+    print(repr(b))
+
+    print('test re dis')
+    for x in a:
+        print(repr(x))
+        rl = mn_ppc.dis(x, mode)
+        assert(str(rl).strip(' ') == s)
+    print("%r %s" % (b, a))
+    assert(b in a)
+print('TEST time %s' % (time.time() - ts))
diff --git a/test/arch/ppc32/sem.py b/test/arch/ppc32/sem.py
new file mode 100644
index 00000000..95ef08c8
--- /dev/null
+++ b/test/arch/ppc32/sem.py
@@ -0,0 +1,129 @@
+#! /usr/bin/env python2
+#-*- coding:utf-8 -*-
+
+from __future__ import print_function
+import unittest
+import logging
+
+from future.utils import viewitems
+
+from miasm.ir.symbexec import SymbolicExecutionEngine
+from miasm.arch.ppc.arch import mn_ppc as mn
+from miasm.arch.ppc.sem import ir_ppc32b as ir_arch
+from miasm.arch.ppc.regs import *
+from miasm.expression.expression import *
+from miasm.core.locationdb import LocationDB
+from pdb import pm
+
+logging.getLogger('cpuhelper').setLevel(logging.ERROR)
+EXCLUDE_REGS = set([ir_arch().IRDst])
+
+
+def M(addr):
+    return ExprMem(ExprInt(addr, 32), 32)
+
+
+def compute(asm, inputstate={}, debug=False):
+    loc_db = LocationDB()
+    sympool = dict(regs_init)
+    sympool.update({k: ExprInt(v, k.size) for k, v in viewitems(inputstate)})
+    ir_tmp = ir_arch(loc_db)
+    ircfg = ir_tmp.new_ircfg()
+    symexec = SymbolicExecutionEngine(ir_tmp, sympool)
+    instr = mn.fromstring(asm, loc_db, "b")
+    code = mn.asm(instr)[0]
+    instr = mn.dis(code, "b")
+    instr.offset = inputstate.get(PC, 0)
+    lbl = ir_tmp.add_instr_to_ircfg(instr, ircfg)
+    symexec.run_at(ircfg, lbl)
+    if debug:
+        for k, v in viewitems(symexec.symbols):
+            if regs_init.get(k, None) != v:
+                print(k, v)
+    out = {}
+    for k, v in viewitems(symexec.symbols):
+        if k in EXCLUDE_REGS:
+            continue
+        elif regs_init.get(k, None) == v:
+            continue
+        elif isinstance(v, ExprInt):
+            out[k] = int(v)
+        else:
+            out[k] = v
+    return out
+
+class TestPPC32Semantic(unittest.TestCase):
+
+    # def test_condition(self):
+    # §A8.3:                   Conditional execution
+    #    pass
+
+    def test_shift(self):
+        self.assertEqual(
+            compute('SLW R5, R4, R1',
+                    {R1: 8, R4: 0xDEADBEEF, }),
+            {R1: 8, R4: 0xDEADBEEF, R5: 0xADBEEF00, })
+        self.assertEqual(
+            compute('SLW. R5, R4, R1',
+                    {R1: 8, R4: 0xDEADBEEF, }),
+            {R1: 8, R4: 0xDEADBEEF, R5: 0xADBEEF00,
+             CR0_LT: 1, CR0_GT: 0, CR0_EQ: 0, CR0_SO: ExprId('XER_SO_init', 1)})
+        self.assertEqual(
+            compute('SLW R5, R4, R1',
+                    {R1: 32 | 0xbeef, R4: 0xDEADBEEF, }),
+            {R1: 32 | 0xbeef, R4: 0xDEADBEEF, R5: 0x0, })
+        self.assertEqual(
+            compute('SLW. R5, R4, R1',
+                    {R1: 32 | 0xbeef, R4: 0xDEADBEEF, }),
+            {R1: 32 | 0xbeef, R4: 0xDEADBEEF, R5: 0x0,
+             CR0_LT: 0, CR0_GT: 0, CR0_EQ: 1, CR0_SO: ExprId('XER_SO_init', 1)})
+#        self.assertRaises(ValueError, compute, 'MOV R4, R4 LSL  0')
+
+    def test_ADD(self):
+        self.assertEqual(
+            compute('ADD R5, R4, R1',
+                    {R1: 0xCAFEBABE, R4: 0xDEADBEEF, }),
+            {R1: 0xCAFEBABE, R4: 0xDEADBEEF, R5: 0xA9AC79AD, })
+        self.assertEqual(
+            compute('ADD. R5, R4, R1',
+                    {R1: 0xCAFEBABE, R4: 0xDEADBEEF, }),
+            {R1: 0xCAFEBABE, R4: 0xDEADBEEF, R5: 0xA9AC79AD,
+             CR0_LT: 1, CR0_GT: 0, CR0_EQ: 0, CR0_SO: ExprId('XER_SO_init', 1)})
+        pass
+
+    def test_AND(self):
+        self.assertEqual(
+            compute('AND R5, R4, R1',
+                    {R1: 0xCAFEBABE, R4: 0xDEADBEEF, }),
+            {R1: 0xCAFEBABE, R4: 0xDEADBEEF, R5: 0xCAACBAAE, })
+        self.assertEqual(
+            compute('AND. R5, R4, R1',
+                    {R1: 0xCAFEBABE, R4: 0xDEADBEEF, }),
+            {R1: 0xCAFEBABE, R4: 0xDEADBEEF, R5: 0xCAACBAAE,
+             CR0_LT: 1, CR0_GT: 0, CR0_EQ: 0, CR0_SO: ExprId('XER_SO_init', 1)})
+        pass
+
+    def test_SUB(self):
+        self.assertEqual(
+            compute('SUBF R5, R4, R1',
+                    {R1: 0xCAFEBABE, R4: 0xDEADBEEF, }),
+            {R1: 0xCAFEBABE, R4: 0xDEADBEEF, R5: 0xEC50FBCF, })
+        self.assertEqual(
+            compute('SUBF. R5, R4, R1',
+                    {R1: 0xCAFEBABE, R4: 0xDEADBEEF, }),
+            {R1: 0xCAFEBABE, R4: 0xDEADBEEF, R5: 0xEC50FBCF,
+             CR0_LT: 1, CR0_GT: 0, CR0_EQ: 0, CR0_SO: ExprId('XER_SO_init', 1)})
+        pass
+
+    def test_CMP(self):
+        self.assertEqual(
+            compute('CMPW CR2, R4, R1',
+                    {R1: 0xCAFEBABE, R4: 0xDEADBEEF, }),
+            {R1: 0xCAFEBABE, R4: 0xDEADBEEF,
+             CR2_LT: 0, CR2_GT: 1, CR2_EQ: 0, CR2_SO: ExprId('XER_SO_init', 1)})
+        pass
+
+if __name__ == '__main__':
+    testsuite = unittest.TestLoader().loadTestsFromTestCase(TestPPC32Semantic)
+    report = unittest.TextTestRunner(verbosity=2).run(testsuite)
+    exit(len(report.errors + report.failures))
diff --git a/test/test_all.py b/test/test_all.py
index 9dcd43e0..02bddb51 100755
--- a/test/test_all.py
+++ b/test/test_all.py
@@ -60,6 +60,7 @@ testset += RegressionTest(["aarch64/arch.py"], base_dir="arch")
 testset += RegressionTest(["sh4/arch.py"], base_dir="arch")
 testset += RegressionTest(["msp430/arch.py"], base_dir="arch")
 testset += RegressionTest(["mips32/arch.py"], base_dir="arch")
+testset += RegressionTest(["ppc32/arch.py"], base_dir="arch")
 
 
 
@@ -105,6 +106,7 @@ for script in ["x86/sem.py",
                "aarch64/unit/mn_ubfm.py",
                "msp430/sem.py",
                "mips32/unit/mn_bcc.py",
+               "ppc32/sem.py",
                ]:
     for jitter in ArchUnitTest.jitter_engines:
         if jitter in blacklist.get(script, []):