about summary refs log tree commit diff stats
path: root/miasm/arch/ppc
diff options
context:
space:
mode:
Diffstat (limited to 'miasm/arch/ppc')
-rw-r--r--miasm/arch/ppc/arch.py62
-rw-r--r--miasm/arch/ppc/regs.py12
-rw-r--r--miasm/arch/ppc/sem.py66
3 files changed, 109 insertions, 31 deletions
diff --git a/miasm/arch/ppc/arch.py b/miasm/arch/ppc/arch.py
index 29550931..2b951027 100644
--- a/miasm/arch/ppc/arch.py
+++ b/miasm/arch/ppc/arch.py
@@ -129,9 +129,9 @@ class instruction_ppc(instruction):
             if not isinstance(e, ExprInt):
                 return
             if name[-1] != 'A':
-                ad = e.arg + self.offset
+                ad = (int(e) + self.offset) & 0xFFFFFFFF
             else:
-                ad = e.arg
+                ad = int(e)
             loc_key = loc_db.get_or_create_offset_location(ad)
             s = ExprLoc(loc_key, e.size)
             self.args[address_index] = s
@@ -175,11 +175,11 @@ class instruction_ppc(instruction):
         if self.name[-1] != 'A':
             if self.offset is None:
                 raise ValueError('symbol not resolved %s' % self.l)
-            off = e.arg - (self.offset + self.l)
+            off = (int(e) + 0x100000000 - (self.offset + self.l)) & 0xFFFFFFFF
             if int(off % 4):
                 raise ValueError('Offset %r must be a multiple of four' % off)
         else:
-            off = e.arg
+            off = int(e)
         self.args[0] = ExprInt(off, 32)
 
     def get_args_expr(self):
@@ -343,7 +343,7 @@ class ppc_s14imm_branch(ppc_imm):
     def encode(self):
         if not isinstance(self.expr, ExprInt):
             return False
-        v = self.expr.arg.arg
+        v = int(self.expr)
         if v & 0x3:
             return False
         v = v >> 2
@@ -362,7 +362,7 @@ class ppc_s24imm_branch(ppc_imm):
     def encode(self):
         if not isinstance(self.expr, ExprInt):
             return False
-        v = self.expr.arg.arg
+        v = int(self.expr)
         if v & 0x3:
             return False
         v = v >> 2
@@ -381,7 +381,7 @@ class ppc_s16imm(ppc_imm):
     def encode(self):
         if not isinstance(self.expr, ExprInt):
             return False
-        v = self.expr.arg.arg
+        v = int(self.expr)
         if sign_ext(v & self.lmask, 16, 32) != v:
             return False
         self.value = v & self.lmask
@@ -398,7 +398,7 @@ class ppc_u16imm(ppc_imm):
     def encode(self):
         if not isinstance(self.expr, ExprInt):
             return False
-        v = self.expr.arg.arg
+        v = int(self.expr)
         if v & self.lmask != v:
             return False
         self.value = v & self.lmask
@@ -416,7 +416,7 @@ class ppc_spr(ppc_imm):
     def encode(self, e):
         if not isinstance(e, ExprInt):
             return False
-        self.value = ppc_swap_10(e.arg)
+        self.value = ppc_swap_10(int(e))
         return True
 
 class ppc_tbr(ppc_imm):
@@ -428,7 +428,7 @@ class ppc_tbr(ppc_imm):
     def encode(self, e):
         if not isinstance(e, ExprInt):
             return False
-        self.value = ppc_swap_10(e.arg)
+        self.value = ppc_swap_10(int(e))
         return True
 
 class ppc_u08imm(ppc_u16imm):
@@ -443,6 +443,13 @@ class ppc_u04imm(ppc_u16imm):
 class ppc_u02imm_noarg(imm_noarg):
     pass
 
+class ppc_float(ppc_reg):
+    reg_info = floatregs
+    parser = reg_info.parser
+
+class ppc_vex(ppc_reg):
+    reg_info = vexregs
+    parser = reg_info.parser
 
 def ppc_bo_bi_to_mnemo(bo, bi, prefer_taken=True, default_taken=True):
     bo2mnemo = { 0: 'DNZF', 2: 'DZF', 4: 'F', 8: 'DNZT',
@@ -520,7 +527,7 @@ class ppc_deref32(ppc_arg):
         if len(addr.args) != 2:
             return False
         reg, disp = addr.args[0], addr.args[1]
-        v = int(disp.arg)
+        v = int(disp)
         if sign_ext(v & 0xFFFF, 16, 32) != v:
             return False
         v &= 0xFFFF
@@ -566,6 +573,16 @@ dregimm = bs(l=16, cls=(ppc_deref32,))
 
 rc_mod = bs_mod_name(l=1, mn_mod=['', '.'], fname='rc')
 
+frd = bs(l=5, cls=(ppc_float,))
+frb = bs(l=5, cls=(ppc_float,))
+frs = bs(l=5, cls=(ppc_float,))
+fm = bs(l=8, cls=(ppc_u08imm,))
+
+va = bs(l=5, cls=(ppc_vex,))
+vb = bs(l=5, cls=(ppc_vex,))
+vd = bs(l=5, cls=(ppc_vex,))
+rb_noarg = bs(l=5, cls=(ppc_gpreg_noarg,), fname="rb")
+
 arith1_name = {"MULLI": 0b000111, "SUBFIC": 0b001000, "ADDIC": 0b001100,
                "ADDIC.": 0b001101 }
 
@@ -636,6 +653,17 @@ dcb_name = {"DCBST": 0b00001, "DCBF": 0b00010,
             "DCBI": 0b01110, "DCBA": 0b10111,
             "ICBI": 0b11110, "DCBZ": 0b11111 }
 
+
+load1_name_float = {"LFS": 0b110000, "LFD": 0b110010 }
+load1_name_float_u = {"LFSU": 0b110001, "LFDU": 0b110011 }
+store1_name_float = {"STFS": 0b110100, "STFD": 0b110110 }
+store1_name_float_u = {"STFSU": 0b110101, "STFDU": 0b110111 }
+
+load1_name_vex = {"LVEBX": 0b0000000111, "LVEHX": 0b0000100111,
+                  "LVEWX": 0b0001000111, "LVSL": 0b0000000110,
+                  "LVSR": 0b0000100110, "LVX": 0b0001100111,
+                  "LVXL": 0b0101100111 }
+
 class bs_mod_name_prio4(bs_mod_name):
     prio = 4
 
@@ -762,3 +790,15 @@ ppcop("SRAWI", [bs('011111'), rs, ra, sh, bs('1100111000'), rc_mod],
       [ra, rs, sh])
 
 ppcop("EIEIO", [bs('011111'), bs('000000000000000'), bs('11010101100')])
+
+ppcop("load1f", [bs_name(l=6, name=load1_name_float), frd, ra_noarg, dregimm])
+ppcop("load1fu", [bs_name(l=6, name=load1_name_float_u), frd, ra_noarg, dregimm])
+ppcop("store1f", [bs_name(l=6, name=store1_name_float), frd, ra_noarg, dregimm])
+ppcop("store1fu", [bs_name(l=6, name=store1_name_float_u), frd, ra_noarg, dregimm])
+ppcop("MTFSF", [bs('111111'), bs('0'), fm, bs('0'), frb, bs('10110001110')])
+ppcop("MTFSF.", [bs('111111'), bs('0'), fm, bs('0'), frb, bs('10110001111')])
+ppcop("MFFS", [bs('111111'), frd, bs('00000000001001000111'), bs('0')])
+ppcop("MFFS.", [bs('111111'), frd, bs('00000000001001000111'), bs('1')])
+
+ppcop("load1vex", [bs('011111'), vd, ra, rb, bs_name(l=10, name=load1_name_vex), bs('0')])
+ppcop("mtvscr", [bs('0001000000000000'), vb, bs('11001000100')])
diff --git a/miasm/arch/ppc/regs.py b/miasm/arch/ppc/regs.py
index 4b710045..00781d6a 100644
--- a/miasm/arch/ppc/regs.py
+++ b/miasm/arch/ppc/regs.py
@@ -35,7 +35,7 @@ xerbcreg_expr, xerbcreg_init, xerbcreg = gen_regs(xerbcreg_str,
                                                   globals(), 7)
 
 
-otherregs_str = ["PC", "CTR", "LR" ]
+otherregs_str = ["PC", "CTR", "LR", "FPSCR", "VRSAVE", "VSCR" ]
 otherregs_expr, otherregs_init, otherregs = gen_regs(otherregs_str,
                                                      globals(), 32)
 
@@ -55,10 +55,18 @@ mmuregs_str = (["SR%d" % i for i in range(16)] +
 mmuregs_expr, mmuregs_init, mmuregs = gen_regs(mmuregs_str,
                                                globals(), 32)
 
+floatregs_str = (["FPR%d" % i for i in range(32)])
+floatregs_expr, floatregs_init, floatregs = gen_regs(floatregs_str,
+                                                     globals(), 64)
+
+vexregs_str = (["VR%d" % i for i in range(32)])
+vexregs_expr, vexregs_init, vexregs = gen_regs(vexregs_str,
+                                              globals(), 128)
+
 regs_flt_expr = []
 
 all_regs_ids = (gpregs_expr + crfbitregs_expr + xerbitregs_expr +
-                xerbcreg_expr + otherregs_expr + superregs_expr + mmuregs_expr +
+                xerbcreg_expr + otherregs_expr + superregs_expr + mmuregs_expr + floatregs_expr + vexregs_expr +
                 [ exception_flags, spr_access, reserve, reserve_address ])
 all_regs_ids_byname = dict([(x.name, x) for x in all_regs_ids])
 all_regs_ids_init = [ExprId("%s_init" % x.name, x.size) for x in all_regs_ids]
diff --git a/miasm/arch/ppc/sem.py b/miasm/arch/ppc/sem.py
index fd6db8f3..7ca7e3e1 100644
--- a/miasm/arch/ppc/sem.py
+++ b/miasm/arch/ppc/sem.py
@@ -25,6 +25,20 @@ sr_dict = {
     12: SR12, 13: SR13, 14: SR14, 15: SR15
 }
 
+float_dict = {
+    0: FPR0, 1: FPR1, 2: FPR2, 3: FPR3, 4: FPR4, 5: FPR5, 6: FPR6, 7: FPR7, 8: FPR8,
+    9: FPR9, 10: FPR10, 11: FPR11, 12: FPR12, 13: FPR13, 14: FPR14, 15: FPR15, 16: FPR16,
+    17: FPR17, 18: FPR18, 19: FPR19, 20: FPR20, 21: FPR21, 22: FPR22, 23: FPR23, 24: FPR24,
+    25: FPR25, 26: FPR26, 27: FPR27, 28: FPR28, 29: FPR29, 30: FPR30, 31: FPR31
+}
+
+vex_dict = {
+    0: VR0, 1: VR1, 2: VR2, 3: VR3, 4: VR4, 5: VR5, 6: VR6, 7: VR7, 8: VR8,
+    9: VR9, 10: VR10, 11: VR11, 12: VR12, 13: VR13, 14: VR14, 15: VR15, 16: VR16,
+    17: VR17, 18: VR18, 19: VR19, 20: VR20, 21: VR21, 22: VR22, 23: VR23, 24: VR24,
+    25: VR25, 26: VR26, 27: VR27, 28: VR28, 29: VR29, 30: VR30, 31: VR31,
+}
+
 crf_dict = dict((ExprId("CR%d" % i, 4),
                  dict( (bit, ExprId("CR%d_%s" % (i, bit), 1))
                        for bit in ['LT', 'GT', 'EQ', 'SO' ] ))
@@ -34,6 +48,8 @@ ctx = {
     'crf_dict': crf_dict,
     'spr_dict': spr_dict,
     'sr_dict': sr_dict,
+    'float_dict': float_dict,
+    'vex_dict': vex_dict,
     'expr': expr,
 }
 
@@ -125,7 +141,7 @@ def mn_do_cntlzw(ir, instr, ra, rs):
     return ret, []
 
 def crbit_to_reg(bit):
-    bit = bit.arg.arg
+    bit = int(bit)
     crid = bit // 4
     bitname = [ 'LT', 'GT', 'EQ', 'SO' ][bit % 4]
     return all_regs_ids_byname["CR%d_%s" % (crid, bitname)]
@@ -232,8 +248,8 @@ def mn_do_exts(ir, instr, ra, rs):
 
 def byte_swap(expr):
     nbytes = expr.size // 8
-    bytes = [ expr[i*8:i*8+8] for i in range(nbytes - 1, -1, -1) ]
-    return ExprCompose(bytes)
+    lbytes = [ expr[i*8:i*8+8] for i in range(nbytes - 1, -1, -1) ]
+    return ExprCompose(*lbytes)
 
 def mn_do_load(ir, instr, arg1, arg2, arg3=None):
     assert instr.name[0] == 'L'
@@ -244,6 +260,12 @@ def mn_do_load(ir, instr, arg1, arg2, arg3=None):
         return mn_do_lmw(ir, instr, arg1, arg2)
     elif instr.name[1] == 'S':
         raise RuntimeError("LSWI, and LSWX need implementing")
+    elif instr.name[1] == 'F':
+        print("Warning, instruction %s implemented as NOP" % instr)
+        return  [], []
+    elif instr.name[1] == 'V':
+        print("Warning, instruction %s implemented as NOP" % instr)
+        return [], []
 
     size = {'B': 8, 'H': 16, 'W': 32}[instr.name[1]]
 
@@ -298,7 +320,7 @@ def mn_do_load(ir, instr, arg1, arg2, arg3=None):
 
 def mn_do_lmw(ir, instr, rd, src):
     ret = []
-    address = src.arg
+    address = src.ptr
     ri = int(rd.name[1:],10)
     i = 0
     while ri <= 31:
@@ -348,7 +370,7 @@ def mn_mfmsr(rd):
     rd = MSR
 
 def mn_mfspr(ir, instr, arg1, arg2):
-    sprid = arg2.arg.arg
+    sprid = int(arg2)
     gprid = int(arg1.name[1:])
     if sprid in spr_dict:
         return [ ExprAssign(arg1, spr_dict[sprid]) ], []
@@ -365,7 +387,7 @@ def mn_mtcrf(ir, instr, crm, rs):
     ret = []
 
     for i in range(8):
-        if crm.arg.arg & (1 << (7 - i)):
+        if int(crm) & (1 << (7 - i)):
             j = (28 - 4 * i) + 3
             for b in ['LT', 'GT', 'EQ', 'SO']:
                 ret.append(ExprAssign(all_regs_ids_byname["CR%d_%s" % (i, b)],
@@ -379,7 +401,7 @@ def mn_mtmsr(ir, instr, rs):
     return [ ExprAssign(MSR, rs) ], []
 
 def mn_mtspr(ir, instr, arg1, arg2):
-    sprid = arg1.arg.arg
+    sprid = int(arg1)
     gprid = int(arg2.name[1:])
     if sprid in spr_dict:
         return [ ExprAssign(spr_dict[sprid], arg2) ], []
@@ -505,7 +527,7 @@ def mn_do_rfi(ir, instr):
     ret = [ ExprAssign(MSR, (MSR &
                           ~ExprInt(0b1111111101110011, 32) |
                           ExprCompose(SRR1[0:2], ExprInt(0, 2),
-                                      SRR1[4:7], ExprInt(0, 1), 
+                                      SRR1[4:7], ExprInt(0, 1),
                                       SRR1[8:16], ExprInt(0, 16)))),
             ExprAssign(PC, dest),
             ExprAssign(ir.IRDst, dest) ]
@@ -562,7 +584,7 @@ def mn_do_srawi(ir, instr, ra, rs, imm):
     if instr.name[-1] == '.':
         ret += mn_compute_flags(rvalue)
 
-    mask = ExprInt(0xFFFFFFFF >> (32 - imm.arg.arg), 32)
+    mask = ExprInt(0xFFFFFFFF >> (32 - int(imm)), 32)
 
     ret.append(ExprAssign(XER_CA, rs.msb() &
                        ExprCond(rs & mask, ExprInt(1, 1), ExprInt(0, 1))))
@@ -580,7 +602,7 @@ def mn_do_srw(ir, instr, ra, rs, rb):
 
 def mn_do_stmw(ir, instr, rs, dest):
     ret = []
-    address = dest.arg
+    address = dest.ptr
     ri = int(rs.name[1:],10)
     i = 0
     while ri <= 31:
@@ -599,6 +621,9 @@ def mn_do_store(ir, instr, arg1, arg2, arg3=None):
 
     if instr.name[2] == 'S':
         raise RuntimeError("STSWI, and STSWX need implementing")
+    elif instr.name[2] == 'F':
+        print("Warning, instruction %s implemented as NOP" % instr)
+        return  [], []
 
     size = {'B': 8, 'H': 16, 'W': 32}[instr.name[2]]
 
@@ -650,8 +675,8 @@ def mn_do_store(ir, instr, arg1, arg2, arg3=None):
         ret.append(ExprAssign(ir.IRDst, loc_next))
         dont = flags + [ ExprAssign(CR0_EQ, ExprInt(0,1)),
                          ExprAssign(ir.IRDst, loc_next) ]
-        additional_ir = [ IRBlock(loc_do, [ AssignBlock(ret) ]),
-                          IRBlock(loc_dont, [ AssignBlock(dont) ]) ]
+        additional_ir = [ IRBlock(loc_do.loc_key, [ AssignBlock(ret) ]),
+                          IRBlock(loc_dont.loc_key, [ AssignBlock(dont) ]) ]
         ret = [ ExprAssign(reserve, ExprInt(0, 1)),
                 ExprAssign(ir.IRDst, ExprCond(reserve, loc_do, loc_dont)) ]
 
@@ -834,16 +859,21 @@ sem_dir = {
     'MCRF': mn_do_mcrf,
     'MCRXR': mn_do_mcrxr,
     'MFCR': mn_do_mfcr,
+    'MFFS': mn_do_nop_warn,
+    'MFFS.': mn_do_nop_warn,
     'MFMSR': mn_mfmsr,
     'MFSPR': mn_mfspr,
     'MFSR': mn_mfsr,
     'MFSRIN': mn_do_nop_warn,
-    'MFTB': mn_mfmsr,
+    'MTFSF': mn_do_nop_warn,
+    'MTFSF.': mn_do_nop_warn,
+    'MFTB': mn_mfspr,
     'MTCRF': mn_mtcrf,
     'MTMSR': mn_mtmsr,
     'MTSPR': mn_mtspr,
     'MTSR': mn_mtsr,
     'MTSRIN': mn_do_nop_warn,
+    'MTVSCR': mn_do_nop_warn,
     'NAND': mn_do_nand,
     'NAND.': mn_do_nand,
     'NOR': mn_do_nor,
@@ -879,7 +909,7 @@ class ir_ppc32b(IntermediateRepresentation):
     def get_ir(self, instr):
         args = instr.args[:]
         if instr.name[0:5] in [ 'ADDIS', 'ORIS', 'XORIS', 'ANDIS' ]:
-            args[2] = ExprInt(args[2].arg << 16, 32)
+            args[2] = ExprInt(int(args[2]) << 16, 32)
         if instr.name[0:3] == 'ADD':
             if instr.name[0:4] == 'ADDZ':
                 last_arg = ExprInt(0, 32)
@@ -920,17 +950,17 @@ class ir_ppc32b(IntermediateRepresentation):
             instr_ir, extra_ir = mn_do_or(self, instr, *args)
         elif instr.name[0:2] == 'RL':
             instr_ir, extra_ir = mn_do_rotate(self, instr, args[0], args[1],
-                                              args[2], args[3].arg.arg,
-                                              args[4].arg.arg)
+                                              args[2], int(args[3]),
+                                              int(args[4]))
         elif instr.name == 'STMW':
             instr_ir, extra_ir = mn_do_stmw(self, instr, *args)
         elif instr.name[0:2] == 'ST':
             instr_ir, extra_ir = mn_do_store(self, instr, *args)
         elif instr.name[0:4] == 'SUBF':
             if instr.name[0:5] == 'SUBFZ':
-                last_arg = ExprInt(0)
+                last_arg = ExprInt(0, 32)
             elif instr.name[0:5] == 'SUBFM':
-                last_arg = ExprInt(0xFFFFFFFF)
+                last_arg = ExprInt(0xFFFFFFFF, 32)
             else:
                 last_arg = args[2]
             instr_ir, extra_ir = mn_do_sub(self, instr, args[0], args[1],