public void AddSegmentReference(ulong imageOffset, ushort segmentSelector) { var c = Constant.Create(PrimitiveType.SegmentSelector, segmentSelector); map.Add(imageOffset, c); }
public void TerArrayAssignment() { var sExp = #region Expected @"// Before /////// // test // Return size: 0 define test test_entry: // succ: l000000000040EC30 l000000000040EC30: word64 rbx_18 = rdx - 1<64> branch rdx == 0<64> l000000000040EC69 // succ: l000000000040EC40 l000000000040EC69 l000000000040EC40: word64 rax_22 = 0x10000040<64> // succ: l000000000040EC50 l000000000040EC50: Mem0[rdi + rbx_18:byte] = CONVERT(Mem0[Mem0[rax_22:word64] + CONVERT(CONVERT(Mem0[rsi + rbx_18:byte], byte, word32), word32, uint64) * 4<64>:word32], word32, byte) rbx_18 = rbx_18 - 1<64> branch rbx_18 != 0xFFFFFFFFFFFFFFFF<64> l000000000040EC50 // succ: l000000000040EC69 l000000000040EC50 l000000000040EC69: return // succ: test_exit test_exit: // After /////// // test // Return size: 0 define test test_entry: // succ: l000000000040EC30 l000000000040EC30: int64 rbx_18 = rdx - 1<64> branch rdx == 0<64> l000000000040EC69 // succ: l000000000040EC40 l000000000040EC69 l000000000040EC40: word32 (** rax_22)[] = (word32 (**)[]) 0x10000040<64> // succ: l000000000040EC50 l000000000040EC50: rdi[rbx_18] = (byte) *((char *) *rax_22 + (uint64) ((word32) (rsi + rbx_18)) * 4<64>) rbx_18 = rbx_18 - 1<64> branch rbx_18 != 0xFFFFFFFFFFFFFFFF<64> l000000000040EC50 // succ: l000000000040EC69 l000000000040EC50 l000000000040EC69: return // succ: test_exit test_exit: "; #endregion // fn000000000040EC30 ////////// RunStringTest(m => { Identifier rbx_18 = m.Local(PrimitiveType.Word64, "rbx_18"); Identifier rdx = m.Local(PrimitiveType.Word64, "rdx"); Identifier rax_22 = m.Local(PrimitiveType.Word64, "rax_22"); Identifier rsi = m.Local(PrimitiveType.Word64, "rsi"); Identifier rdi = m.Local(PrimitiveType.Word64, "rdi"); m.Label("l000000000040EC30"); m.Declare(rbx_18, m.ISub(rdx, Constant.Create(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), 0x1))); m.BranchIf(m.Eq(rdx, Constant.Create(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), 0x0)), "l000000000040EC69"); m.Label("l000000000040EC40"); m.Declare(rax_22, m.Word64(0x10000040)); m.Label("l000000000040EC50"); m.MStore(m.IAdd(rdi, rbx_18), m.Convert( m.Mem32(m.IAdd(m.Mem64(rax_22), m.IMul(m.Convert( m.Convert( m.Mem8(m.IAdd(rsi, rbx_18)), PrimitiveType.Byte, PrimitiveType.Word32), PrimitiveType.Word32, PrimitiveType.UInt64), Constant.Create(PrimitiveType.Word64, 0x4)))), PrimitiveType.Word32, PrimitiveType.Byte)); m.Assign(rbx_18, m.ISub(rbx_18, Constant.Create(PrimitiveType.Word64, 0x1))); m.BranchIf(m.Ne(rbx_18, Constant.Create(PrimitiveType.Word64, 0xFFFFFFFFFFFFFFFF)), "l000000000040EC50"); m.Label("l000000000040EC69"); m.Return(); }, sExp); }
public RtlInstruction Assign(Expression dst, int n) { return(Assign(dst, Constant.Create(dst.DataType, n))); }
public PICOperandImmediate(int immValue, PrimitiveType dataWidth) : base(dataWidth) { ImmediateValue = Constant.Create(dataWidth, immValue); }
public Expression Transform() { return(Constant.Create(slice.DataType, Slice(c.ToInt32()))); }
private MachineOperand DecodeOperand(byte b, string fmt) { MachineOperand op; byte r; Constant c; byte o8; int incCode; switch (fmt[0]) { case '+': // Predecrement if (!rdr.TryReadByte(out r)) { return(null); } incCode = r & 3; if (incCode >= incDecSize.Length) { return(null); } op = MemoryOperand.PostIncrement(Size(fmt[1]), incDecSize[r & 3], Reg('x', (r >> 2) & 0x3F)); SetSize(fmt[1]); return(op); case '-': if (!rdr.TryReadByte(out r)) { return(null); } incCode = r & 3; if (incCode >= incDecSize.Length) { return(null); } op = MemoryOperand.PreDecrement(Size(fmt[1]), incDecSize[r & 3], Reg('x', (r >> 2) & 0x3F)); SetSize(fmt[1]); return(op); case '3': // Immediate encoded in low 3 bits c = Constant.Create(Size(fmt[1]), b & 7); SetSize(fmt[1]); return(new ImmediateOperand(c)); case '#': // Immediate encoded in low 3 bits, with 8 encoded as 0 c = Constant.Create(Size(fmt[1]), imm3Const[b & 7]); SetSize(fmt[1]); return(new ImmediateOperand(c)); case 'A': // A register op = new RegisterOperand(Tlcs900Registers.a); return(op); case 'C': // condition code op = new ConditionOperand((CondCode)(b & 0xF)); return(op); case 'I': // immediate op = Immediate(fmt[1]); return(op); case 'j': // Relative jump switch (fmt[1]) { case 'b': if (!rdr.TryReadByte(out o8)) { return(null); } else { return(AddressOperand.Create(rdr.Address + (sbyte)o8)); } case 'w': short o16; if (!rdr.TryReadLeInt16(out o16)) { return(null); } else { return(AddressOperand.Create(rdr.Address + o16)); } } return(null); case 'r': // Register case 'R': //$TODO: 'r' may encode other registers. manual is dense op = new RegisterOperand(Reg(fmt[1], b & 0x7)); SetSize(fmt[1]); return(op); case 'M': // Register indirect op = MemoryOperand.Indirect(Size(fmt[1]), Reg('x', b & 7)); SetSize(fmt[1]); return(op); case 'N': // indexed (8-bit offset) if (!rdr.TryReadByte(out o8)) { return(null); } op = MemoryOperand.Indexed8(Size(fmt[1]), Reg('x', b & 7), (sbyte)o8); SetSize(fmt[1]); return(op); case 'm': // various mem formats byte m; if (!rdr.TryReadByte(out m)) { return(null); } switch (m & 3) { case 0: // Register indirect op = MemoryOperand.Indirect(Size(fmt[1]), Reg('x', (m >> 2) & 0x3F)); break; case 1: // indexed (16-bit offset) short o16; if (!rdr.TryReadLeInt16(out o16)) { return(null); } op = MemoryOperand.Indexed16(Size(fmt[1]), Reg('x', (m >> 2) & 0x3F), o16); SetSize(fmt[1]); return(op); case 3: if (m != 3 && m != 7) { return(null); } byte rBase; if (!rdr.TryReadByte(out rBase)) { return(null); } byte rIdx; if (!rdr.TryReadByte(out rIdx)) { return(null); } var regBase = Reg('x', rBase); var regIdx = Reg(m == 3 ? 'b' : 'w', rIdx); op = MemoryOperand.RegisterIndexed(Size(fmt[1]), regBase, regIdx); SetSize(fmt[1]); return(op); default: throw new FormatException(string.Format( "Unknown format {0} decoding bytes {1:X2}{2:X2}.", fmt[0], (int)b, (int)m)); } SetSize(fmt[1]); return(op); case 'O': return(Absolute(1, fmt[1])); case 'P': return(Absolute(2, fmt[1])); case 'Q': return(Absolute(3, fmt[1])); default: throw new FormatException( string.Format( "Unknown format {0} decoding byte {1:X2}.", fmt[0], (int)b)); } }
public void VpMulAddShift() { Identifier id = Reg32("id"); var vp = new ExpressionSimplifier(new SsaEvaluationContext(arch, ssaIds), listener); PrimitiveType t = PrimitiveType.Int32; BinaryExpression b = new BinaryExpression(Operator.Shl, t, new BinaryExpression(Operator.IAdd, t, new BinaryExpression(Operator.SMul, t, id, Constant.Create(t, 4)), id), Constant.Create(t, 2)); Expression e = vp.VisitBinaryExpression(b); Assert.AreEqual("id *s 20", e.ToString()); }
private Constant Seg(int seg) { return(Constant.Create(PrimitiveType.SegmentSelector, seg)); }
public void VpMulAddShift() { Identifier id = m.Reg32("id"); var vp = new ExpressionSimplifier(segmentMap, new SsaEvaluationContext(arch.Object, m.Ssa.Identifiers, dynamicLinker.Object), listener); PrimitiveType t = PrimitiveType.Int32; BinaryExpression b = new BinaryExpression(Operator.Shl, t, new BinaryExpression(Operator.IAdd, t, new BinaryExpression(Operator.SMul, t, id, Constant.Create(t, 4)), id), Constant.Create(t, 2)); Expression e = vp.VisitBinaryExpression(b); Assert.AreEqual("id *s 20<i32>", e.ToString()); }
public Expression Rewrite(Address addr, Expression?basePtr, bool dereferenced) { if (addr.Selector.HasValue) { if (!mpSelectorToSegId.TryGetValue(addr.Selector.Value, out Identifier segId)) { eventListener.Warn( "Selector {0:X4} has no known segment.", addr.Selector.Value); return(addr); } var ptrSeg = segId.TypeVariable !.DataType.ResolveAs <Pointer>(); if (ptrSeg == null) { //$TODO: what should the warning be? //$BUG: create a fake field for now. var field = new StructureField((int)addr.Offset, new UnknownType()); Expression x = new FieldAccess(new UnknownType(), new Dereference(segId.DataType, segId), field); if (!dereferenced) { x = new UnaryExpression(Operator.AddrOf, addr.DataType, x); } return(x); } var baseType = ptrSeg.Pointee.ResolveAs <StructureType>() !; var dt = addr.TypeVariable !.DataType.ResolveAs <Pointer>() !; this.c = Constant.Create( PrimitiveType.CreateWord(addr.DataType.BitSize - ptrSeg.BitSize), addr.Offset); DataType pointee; if (dt != null) { pointee = dt.Pointee; } else { pointee = new UnknownType(); } var f = EnsureFieldAtOffset(baseType, pointee, c.ToInt32()); Expression ex = new FieldAccess(f.DataType, new Dereference(ptrSeg, segId), f); if (dereferenced || pointee is ArrayType) { return(ex); } else { var un = new UnaryExpression(Operator.AddrOf, addr.TypeVariable !.DataType, ex); return(un); } } else { this.c = addr.ToConstant(); this.c.TypeVariable = addr.TypeVariable; var dtInferred = addr.TypeVariable !.DataType.ResolveAs <DataType>() !; this.pOrig = addr.TypeVariable.OriginalDataType as PrimitiveType; this.dereferenced = dereferenced; return(dtInferred.Accept(this)); } }
public virtual Assignment Assign(Identifier dst, int n) { return(Assign(dst, Constant.Create((PrimitiveType)dst.DataType, n))); }
public MipsInstruction DecodeOperands(Opcode opcode, uint wInstr, string opFmt) { var ops = new List <MachineOperand>(); MachineOperand op = null; for (int i = 0; i < opFmt.Length; ++i) { switch (opFmt[i]) { default: throw new NotImplementedException(string.Format("Operator format {0}", opFmt[i])); case ',': continue; case 'R': switch (opFmt[++i]) { case '1': op = Reg(wInstr >> 21); break; case '2': op = Reg(wInstr >> 16); break; case '3': op = Reg(wInstr >> 11); break; //case '4': op = MemOff(wInstr >> 6, wInstr); break; default: throw new NotImplementedException(string.Format("Register field {0}.", opFmt[i])); } break; case 'F': switch (opFmt[++i]) { case '1': op = FReg(wInstr >> 21); break; case '2': op = FReg(wInstr >> 16); break; case '3': op = FReg(wInstr >> 11); break; case '4': op = FReg(wInstr >> 6); break; default: throw new NotImplementedException(string.Format("Register field {0}.", opFmt[i])); } break; case 'f': // FPU control register RegisterOperand fcreg; switch (opFmt[++i]) { case '1': if (!TryGetFCReg(wInstr >> 21, out fcreg)) { return(null); } op = fcreg; break; case '2': if (!TryGetFCReg(wInstr >> 16, out fcreg)) { return(null); } op = fcreg; break; case '3': if (!TryGetFCReg(wInstr >> 11, out fcreg)) { return(null); } op = fcreg; break; //case '4': op = MemOff(wInstr >> 6, wInstr); break; default: throw new NotImplementedException(string.Format("Register field {0}.", opFmt[i])); } break; case 'I': op = new ImmediateOperand(Constant.Create(this.signedWord, (short)wInstr)); break; case 'U': op = new ImmediateOperand(Constant.Create(arch.WordWidth, (ushort)wInstr)); break; case 'i': op = ImmediateOperand.Int16((short)wInstr); break; case 'j': op = RelativeBranch(wInstr); break; case 'J': op = LargeBranch(wInstr); break; case 'B': op = ImmediateOperand.Word32((wInstr >> 6) & 0xFFFFF); break; case 's': // Shift amount or sync type op = ImmediateOperand.Byte((byte)((wInstr >> 6) & 0x1F)); break; case 'E': // effective address w 16-bit offset op = Ea(wInstr, opFmt[++i], 21, (short)wInstr); break; case 'e': // effective address w 9-bit offset op = Ea(wInstr, opFmt[++i], 21, (short)(((short)wInstr) >> 7)); break; case 'T': // trap code op = ImmediateOperand.Word16((ushort)((wInstr >> 6) & 0x03FF)); break; case 'c': // condition code op = CCodeFlag(wInstr, opFmt, ref i); break; case 'C': // FPU condition code op = FpuCCodeFlag(wInstr, opFmt, ref i); break; case 'H': // hardware register, see instruction rdhwr op = ImmediateOperand.Byte((byte)((wInstr >> 11) & 0x1f)); break; } ops.Add(op); } return(new MipsInstruction { opcode = opcode, Address = addr, Length = 4, op1 = ops.Count > 0 ? ops[0] : null, op2 = ops.Count > 1 ? ops[1] : null, op3 = ops.Count > 2 ? ops[2] : null, }); }
public void AddSegmentReference(ulong linAddress, ushort segmentSelector) { var c = Constant.Create(PrimitiveType.SegmentSelector, segmentSelector); map.Add(linAddress, c); }
public void AddPointerReference(ulong linAddress, uint pointer) { var c = Constant.Create(PrimitiveType.Ptr32, pointer); map.Add(linAddress, c); }
public void Execute(Tag action, Stack <Tag> stk, Token tk, ref Environment env) { #region Sentenças Declarativas if (action == Tag._Begin) { // Sinaliza o início de uma sentença imperativa env.SentencaImperativa = true; } else if (action == Tag._End) { // Sinaliza o final de uma sentença imperativa env.SentencaImperativa = false; } else if (action == Tag._CreateList) { List <object> list = new List <object>(); list.Add(((IdNew)tk).Lexema); stk.ElementAt <Tag>(0).Inherited[0] = list; } else if (action == Tag._InsertList) { List <object> list = (List <object>)action.Inherited[0]; list.Add(((IdNew)tk).Lexema); stk.ElementAt <Tag>(0).Inherited[0] = list; } else if (action == Tag._Integer) { stk.ElementAt <Tag>(0).Inherited[0] = new IntegerType(); // stk.ElementAt<Tag>(0).Inherited[0] = AbsType.IntegerType; } else if (action == Tag._Real) { stk.ElementAt <Tag>(0).Inherited[0] = new RealType(); // stk.ElementAt<Tag>(0).Inherited[0] = AbsType.RealType; } else if (action == Tag._BeginRange) { stk.ElementAt <Tag>(6).Inherited[2] = ((Integer)tk).Value; } else if (action == Tag._EndRange) { stk.ElementAt <Tag>(3).Inherited[1] = ((Integer)tk).Value; } else if (action == Tag._ArrayDec) { AbsType type = (AbsType)action.Inherited[0]; int rangeEnd = (int)action.Inherited[1]; int rangeBegin = (int)action.Inherited[2]; stk.ElementAt <Tag>(0).Inherited[0] = new ArrayType(type, rangeBegin, rangeEnd); } else if (action == Tag._IdVar) { stk.ElementAt <Tag>(2).Inherited[1] = action.Inherited[0]; } else if (action == Tag._VarDec) { List <object> lexemas = (List <object>)action.Inherited[1]; AbsType type = (AbsType)action.Inherited[0]; foreach (string v in lexemas) { env.locals.Add(v, type); } } else if (action == Tag._IdProc) { // Verificar se o identificador é novo if (tk.tag != Tag.IDNEW) { throw new NotImplementedException("O Id deve ser novo!"); } string lexema = ((IdNew)tk).Lexema; // O contexto deve ser alterado logo antes dos parâmetros serem declarados ProcType type = new ProcType(env, env.machine); env.locals.Add(lexema, type); env = type.Env; stk.ElementAt <Tag>(1).Inherited[0] = lexema; } else if (action == Tag._IdFunc) { // Verificar se o identificador é novo if (tk.tag != Tag.IDNEW) { throw new NotImplementedException("O Id deve ser novo!"); } string lexema = ((IdNew)tk).Lexema; // O contexto deve ser alterado logo antes dos parâmetros serem declarados FuncType type = new FuncType(env, env.machine); env.locals.Add(lexema, type); env = type.Env; stk.ElementAt <Tag>(3).Inherited[1] = lexema; } else if (action == Tag._ProcDec) { // Identificador do procedimento string lexema = (string)action.Inherited[0]; ProcType type = (ProcType)Environment.SearchLocal(env.parent, lexema); } else if (action == Tag._FuncDec) { // Identificador da função string lexema = (string)action.Inherited[1]; FuncType type = (FuncType)Environment.SearchLocal(env.parent, lexema); type.ReturnType = (AbsType)action.Inherited[0]; } else if (action == Tag._EndParList) { stk.ElementAt <Tag>(2).Inherited[1] = action.Inherited[0]; } else if (action == Tag._ParDec) { foreach (string arg in (List <object>)action.Inherited[1]) { env.parameters.Add(arg, (AbsType)action.Inherited[0]); } } else if (action == Tag._EnvRestore) { IntermediateInstruction code = ic.CreateReturn(); // Console.WriteLine(code.ToString()); env.machine.AddInstruction(code); env = env.parent; } else if (action == Tag._Args) { // Recebe a lista de argumentos do programa foreach (string arg in (List <object>)action.Inherited[0]) { env.parameters.Add(arg, AbsType.Untyped); } } #endregion #region Sentenças Imperativas else if (action == Tag._Number) { stk.ElementAt <Tag>(0).Inherited[0] = Constant.Create(((Integer)tk).Value); } else if (action == Tag._RValue) { Address address = (Address)action.Inherited[0]; stk.ElementAt <Tag>(0).Inherited[0] = address; } else if (action == Tag._Not) { Name tmp = new Name(); IntermediateInstruction code = ic.CreateUnary(Operator.NOT, (Address)action.Inherited[0], tmp); // Console.WriteLine(code.ToString()); env.machine.AddInstruction(code); stk.ElementAt <Tag>(0).Inherited[0] = tmp; } else if (action == Tag._Skip1) { stk.ElementAt <Tag>(1).Inherited[0] = action.Inherited[0]; } else if (action == Tag._FAddress) // Endereço da função { FuncType func = (FuncType)Environment.Search(env, ((IdFunc)tk).Lexema); stk.ElementAt <Tag>(1).Inherited[1] = func; } else if (action == Tag._PAddress) // Endereço do procedimento { ProcType proc = (ProcType)Environment.Search(env, ((IdProc)tk).Lexema); stk.ElementAt <Tag>(1).Inherited[1] = proc.Env.CodeAddress; } else if (action == Tag._FCall) // Chamada de função { // Destino FuncType func = (FuncType)action.Inherited[1]; Label label = new Label(func.Env.CodeAddress); // Número de argumentos int n = (int)action.Inherited[0]; IntermediateInstruction code = ic.CreateCall(label, n); // Console.WriteLine(code.ToString()); env.machine.AddInstruction(code); stk.ElementAt <Tag>(0).Inherited[0] = func.Env.returnvalue; } else if (action == Tag._PCall) // Chamada de procedimento { // Destino Label label = new Label((int)action.Inherited[1]); // Número de argumentos int n = (int)action.Inherited[0]; IntermediateInstruction code = ic.CreateCall(label, n); // Console.WriteLine(code.ToString()); env.machine.AddInstruction(code); } else if (action == Tag._FirstActualPar) // Primeiro parâmetro atual { IntermediateInstruction code = ic.CreateParam((Address)action.Inherited[0]); // Console.WriteLine(code.ToString()); env.machine.AddInstruction(code); stk.ElementAt <Tag>(0).Inherited[0] = 1; // Primeiro parametro } else if (action == Tag._NextActualPar) // Próximo parâmetro atual { IntermediateInstruction code = ic.CreateParam((Address)action.Inherited[0]); // Console.WriteLine(code.ToString()); env.machine.AddInstruction(code); stk.ElementAt <Tag>(0).Inherited[0] = (int)action.Inherited[1] + 1; } else if (action == Tag._EndActualPar) // Lista de parâmetros atuais completa { stk.ElementAt <Tag>(1).Inherited[0] = (int)action.Inherited[0]; // Número de parâmetros } else if (action == Tag._NoArgs) { stk.ElementAt <Tag>(0).Inherited[0] = 0; // Não há parâmetros atuais } else if (action == Tag._AddOp) { if (((AddOp)tk).Value == '+') { stk.ElementAt <Tag>(1).Inherited[1] = Operator.ADD; } else // if (((AddOp)tk).Value == '-') { stk.ElementAt <Tag>(1).Inherited[1] = Operator.SUB; } } else if (action == Tag._Add) { Address x = (Address)action.Inherited[2]; Operator op = (Operator)action.Inherited[1]; Address y = (Address)action.Inherited[0]; Name tmp = new Name(); IntermediateInstruction code = ic.CreateBinary(op, tmp, x, y); // Console.WriteLine(code.ToString()); env.machine.AddInstruction(code); stk.ElementAt <Tag>(0).Inherited[0] = tmp; } else if (action == Tag._MulOp) { if (((MulOp)tk).Value == '*') { stk.ElementAt <Tag>(1).Inherited[1] = Operator.MUL; } else // if (((MulOp)tk).Value == '/') { stk.ElementAt <Tag>(1).Inherited[1] = Operator.DIV; } } else if (action == Tag._Mul) { Address x = (Address)action.Inherited[2]; Operator op = (Operator)action.Inherited[1]; Address y = (Address)action.Inherited[0]; Name tmp = new Name(); IntermediateInstruction code = ic.CreateBinary(op, tmp, x, y); // Console.WriteLine(code.ToString()); env.machine.AddInstruction(code); stk.ElementAt <Tag>(0).Inherited[0] = tmp; } else if (action == Tag._RelOp) { if (((RelOp)tk).Value == "<") { stk.ElementAt <Tag>(1).Inherited[1] = Operator.LT; } else if (((RelOp)tk).Value == "<=") { stk.ElementAt <Tag>(1).Inherited[1] = Operator.LE; } else if (((RelOp)tk).Value == ">") { stk.ElementAt <Tag>(1).Inherited[1] = Operator.GT; } else if (((RelOp)tk).Value == ">=") { stk.ElementAt <Tag>(1).Inherited[1] = Operator.GE; } else if (((RelOp)tk).Value == "=") { stk.ElementAt <Tag>(1).Inherited[1] = Operator.EQ; } else // if (((RelOp)tk).Value == "<>") { stk.ElementAt <Tag>(1).Inherited[1] = Operator.NEQ; } } else if (action == Tag._Rel) { Address x = (Address)action.Inherited[2]; Operator op = (Operator)action.Inherited[1]; Address y = (Address)action.Inherited[0]; Name tmp = new Name(); IntermediateInstruction code = ic.CreateBinary(op, tmp, x, y); // Console.WriteLine(code.ToString()); env.machine.AddInstruction(code); stk.ElementAt <Tag>(0).Inherited[0] = tmp; } else if (action == Tag._Variable) { stk.ElementAt <Tag>(0).Inherited[0] = new Name(((IdVar)tk).Lexema); } else if (action == Tag._ToArray) { Name tmp = new Name(); Address y = (Address)action.Inherited[1]; Address i = (Address)action.Inherited[0]; IntermediateInstruction code = ic.CreateToArray(tmp, i, y); // Console.WriteLine(code.ToString()); env.machine.AddInstruction(code); stk.ElementAt <Tag>(1).Inherited[0] = tmp; } else if (action == Tag._FromArray) { Name tmp = new Name(); Address y = (Address)action.Inherited[1]; Address i = (Address)action.Inherited[0]; IntermediateInstruction code = ic.CreateFromArray(tmp, i, y); // Console.WriteLine(code.ToString()); env.machine.AddInstruction(code); stk.ElementAt <Tag>(1).Inherited[0] = tmp; } else if (action == Tag._LValue) { stk.ElementAt <Tag>(2).Inherited[1] = action.Inherited[0]; } else if (action == Tag._Assign) { Address lValue = (Address)action.Inherited[1]; Address rValue = (Address)action.Inherited[0]; IntermediateInstruction code = ic.CreateCopy(lValue, rValue); // Console.WriteLine(code.ToString()); env.machine.AddInstruction(code); } else if (action == Tag._RetAssign) { Address lValue = env.returnvalue; Address rValue = (Address)action.Inherited[0]; if (lValue == null) { lValue = new Name(); } IntermediateInstruction code1 = ic.CreateCopy(lValue, rValue); // Console.WriteLine(code1.ToString()); env.machine.AddInstruction(code1); env.returnvalue = lValue; IntermediateInstruction code2 = ic.CreateRetVal(lValue); // ic.CreateCopy(lValue, rValue); // Console.WriteLine(code2.ToString()); env.machine.AddInstruction(code2); } else if (action == Tag._IfExp) { IntermediateInstruction code1 = ic.CreateIfTrue((Address)action.Inherited[0], null);; env.machine.AddInstruction(code1); IntermediateInstruction code2 = ic.CreateGoto(null); env.machine.AddInstruction(code2); stk.ElementAt <Tag>(0).Inherited[0] = code1; stk.ElementAt <Tag>(3).Inherited[0] = code2; } else if (action == Tag._Then) { ((IntermediateInstruction)action.Inherited[0])[0].Arg2 = new Label(env.machine.Count); // Console.WriteLine(action.Inherited[0].ToString()); } else if (action == Tag._Else) { ((IntermediateInstruction)action.Inherited[0])[0].Arg2 = new Label(env.machine.Count + 1); // Console.WriteLine(action.Inherited[0].ToString()); IntermediateInstruction code = ic.CreateGoto(null); env.machine.AddInstruction(code); stk.ElementAt <Tag>(2).Inherited[0] = code; } else if (action == Tag._ExitIf) { Label exit = new Label(env.machine.Count + 1); ((IntermediateInstruction)action.Inherited[0])[0].Arg2 = exit; // Console.WriteLine(action.Inherited[0].ToString()); IntermediateInstruction code = ic.CreateGoto(exit); env.machine.AddInstruction(code); } else if (action == Tag._Loop) { Label loop = new Label(env.machine.Count); stk.ElementAt <Tag>(5).Inherited[1] = loop; } else if (action == Tag._WhileExp) { IntermediateInstruction code1 = ic.CreateIfTrue((Address)action.Inherited[0], null);; env.machine.AddInstruction(code1); IntermediateInstruction code2 = ic.CreateGoto(null); env.machine.AddInstruction(code2); stk.ElementAt <Tag>(1).Inherited[0] = code1; stk.ElementAt <Tag>(3).Inherited[0] = code2; } else if (action == Tag._Do) { ((IntermediateInstruction)action.Inherited[0])[0].Arg2 = new Label(env.machine.Count); // Console.WriteLine(action.Inherited[0].ToString()); } else if (action == Tag._ExitWhile) { Label loop = (Label)action.Inherited[1]; IntermediateInstruction code = ic.CreateGoto(loop); env.machine.AddInstruction(code); ((IntermediateInstruction)action.Inherited[0])[0].Arg2 = new Label(env.machine.Count); // Console.WriteLine(action.Inherited[0].ToString()); } else if (action == Tag._MainCode) { Environment.root.EntryPoint(); } else if (action == Tag._Done) { // Insere uma instrução ret no final do código do programa. IntermediateInstruction code = ic.CreateReturn(); // Console.WriteLine(code.ToString()); env.machine.AddInstruction(code); string str = "program " + programName + " " + env.ToString(); Console.WriteLine(str); Console.WriteLine("\nPRESSIONE UMA TECLA PARA CONTINUAR..."); Console.ReadKey(); } #endregion else if (action == Tag._ProgramName) { programName = ((IdNew)tk).Lexema; } else if (action == Tag._Echo) { stk.ElementAt <Tag>(0).Inherited[0] = action.Inherited[0]; } else { throw new NotImplementedException("Não implementado!"); } }
public void EmitStringInstruction(X86Instruction instr, CodeEmitter emitter) { this.emitter = emitter; bool incSi = false; bool incDi = false; this.instrCur = instr; switch (instrCur.code) { default: throw new ApplicationException("NYI"); case Mnemonic.cmps: case Mnemonic.cmpsb: emitter.Assign( orw.FlagGroup(X86Instruction.DefCc(Mnemonic.cmp)), new ConditionOf( new BinaryExpression(Operator.ISub, instrCur.dataWidth, MemSi(), MemDi()))); incSi = true; incDi = true; break; case Mnemonic.lods: case Mnemonic.lodsb: emitter.Assign(RegAl, MemSi()); incSi = true; break; case Mnemonic.movs: case Mnemonic.movsb: { Identifier tmp = emitter.Frame.CreateTemporary(instrCur.dataWidth); emitter.Assign(tmp, MemSi()); emitter.Store(MemDi(), tmp); incSi = true; incDi = true; break; } case Mnemonic.ins: case Mnemonic.insb: { Identifier regDX = orw.AluRegister(Registers.edx, instrCur.addrWidth); emitter.Store(MemDi(), host.PseudoProc("__in", instrCur.dataWidth, regDX)); incDi = true; break; } case Mnemonic.outs: case Mnemonic.outsb: { Identifier regDX = orw.AluRegister(Registers.edx, instrCur.addrWidth); emitter.SideEffect("__out" + RegAl.DataType.Prefix, regDX, RegAl); incSi = true; break; } case Mnemonic.scas: case Mnemonic.scasb: emitter.Assign( orw.FlagGroup(X86Instruction.DefCc(Mnemonic.cmp)), new ConditionOf( new BinaryExpression(Operator.ISub, instrCur.dataWidth, RegAl, MemDi()))); incDi = true; break; case Mnemonic.stos: case Mnemonic.stosb: emitter.Store(MemDi(), RegAl); incDi = true; break; } if (incSi) { emitter.Assign(RegSi, new BinaryExpression(Operator.IAdd, instrCur.addrWidth, RegSi, Constant.Create(instrCur.addrWidth, instrCur.dataWidth.Size))); } if (incDi) { emitter.Assign(RegDi, new BinaryExpression(Operator.IAdd, instrCur.addrWidth, RegDi, Constant.Create(instrCur.addrWidth, instrCur.dataWidth.Size))); } }
public void TtranArrayAssignment() { var pp = new ProgramBuilder(); pp.Add("Fn", m => { Identifier rbx_18 = m.Local(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), "rbx_18"); Identifier rdx = m.Local(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), "rdx"); Identifier rax_22 = m.Local(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), "rax_22"); Identifier rsi = m.Local(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), "rsi"); Identifier rdi = m.Local(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), "rdi"); m.Label("l000000000040EC30"); m.Declare(rbx_18, m.ISub(rdx, Constant.Create(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), 0x1))); m.BranchIf(m.Eq(rdx, Constant.Create(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), 0x0)), "l000000000040EC69"); m.Label("l000000000040EC40"); m.Declare(rax_22, m.Word64(0x10000040)); m.Label("l000000000040EC50"); m.MStore(m.IAdd(rdi, rbx_18), m.Cast(PrimitiveType.Byte, m.Mem(PrimitiveType.Word32, m.IAdd(m.Mem(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), rax_22), m.IMul(m.Cast(PrimitiveType.Create(Domain.UnsignedInt, 64), m.Cast(PrimitiveType.Word32, m.Mem(PrimitiveType.Byte, m.IAdd(rsi, rbx_18)))), Constant.Create(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), 0x4)))))); m.Assign(rbx_18, m.ISub(rbx_18, Constant.Create(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), 0x1))); m.BranchIf(m.Ne(rbx_18, Constant.Create(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), 0xFFFFFFFFFFFFFFFF)), "l000000000040EC50"); m.Label("l000000000040EC69"); m.Return(); }); RunTest(pp.BuildProgram(), $"Typing/{nameof(TtranArrayAssignment)}.txt"); }
/// <summary> /// Emits the ModRM byte (and SIB byte if applicable) /// </summary> /// <param name="reg"></param> /// <param name="memOp"></param> /// <returns>The offset value to be emitted as the last piece of the instruction</returns> public Constant?EmitModRMPrefix(int reg, MemoryOperand memOp) { offset = null; reg <<= 3; if (memOp.Base != RegisterStorage.None || memOp.Index != RegisterStorage.None) { PrimitiveType baseWidth = memOp.Base.DataType; PrimitiveType indexWidth = memOp.Index.DataType; if (memOp.Base != RegisterStorage.None && memOp.Index != RegisterStorage.None) { if (baseWidth != indexWidth) { OnError("mismatched base and index registers"); return(null); } } // Add the 'mod' bits if (memOp.Offset != null) { Debug.Assert(memOp.Offset.IsValid); if (memOp.Offset.DataType == PrimitiveType.SByte) { reg |= 0x40; offset = memOp.Offset; } else { reg |= 0x80; offset = Constant.Create(defaultWordSize, memOp.Offset.ToInt32()); } } bool fNeedsSib = false; int sib = 0; if (baseWidth == PrimitiveType.Word16) { reg |= Get16AddressingModeMask(memOp); } else if (baseWidth == PrimitiveType.Word32 || indexWidth == PrimitiveType.Word32) { if (memOp.Index == RegisterStorage.None) { if (memOp.Base != Registers.esp) { reg |= X86Assembler.RegisterEncoding(memOp.Base); if (memOp.Offset == null && memOp.Base == Registers.ebp) { reg |= 0x40; offset = Constant.Byte(0); } } else { reg |= 0x04; fNeedsSib = true; sib = 0x24; } } else { reg |= 0x04; fNeedsSib = true; switch (memOp.Scale) { case 1: sib = 0; break; case 2: sib = 0x40; break; case 4: sib = 0x80; break; case 8: sib = 0xC0; break; default: OnError("Scale factor must be 1, 2, 4, or 8"); return(Constant.Invalid); } if (memOp.Base == RegisterStorage.None) { sib |= 0x05; reg &= ~0xC0; // clear mod part of modRM. if (memOp.Offset == null) { offset = Constant.Word32(0); } } else { sib |= X86Assembler.RegisterEncoding(memOp.Base); } if (memOp.Index != Registers.esp) { sib |= X86Assembler.RegisterEncoding(memOp.Index) << 3; } else { throw new ApplicationException("ESP register can't be used as an index register"); } } } else { throw new ApplicationException("unexpected address width"); } emitter.EmitByte(reg); if (fNeedsSib) { emitter.EmitByte(sib); } return(offset); } else { return(EmitDirectAddress(reg, memOp)); } }
private Tlcs900Instruction Decode(byte b, Opcode opcode, string fmt) { var instr = new Tlcs900Instruction { Opcode = opcode, Address = this.addr, }; var ops = new List <MachineOperand>(); MachineOperand op = null; for (int i = 0; i < fmt.Length; ++i) { switch (fmt[i++]) { case ',': continue; case 'C': // condition code var cc = (CondCode)(b & 0xF); if (cc == CondCode.T) { continue; } op = new ConditionOperand(cc); break; case 'A': op = new RegisterOperand(Tlcs900Registers.a); break; case '3': // Immediate encoded in low 3 bits var c = Constant.Create(Size(fmt[1]), imm3Const[b & 7]); SetSize(fmt[1]); op = new ImmediateOperand(c); break; case 'I': // immediate op = Immediate(fmt[i++]); break; case 'j': // Relative jump switch (fmt[i++]) { case 'b': byte o8; if (!rdr.TryReadByte(out o8)) { op = null; } else { op = AddressOperand.Create(rdr.Address + (sbyte)o8); } break; case 'w': short o16; if (!rdr.TryReadLeInt16(out o16)) { op = null; } else { op = AddressOperand.Create(rdr.Address + o16); } break; } break; case 'J': // Absolute jump switch (fmt[i++]) { case 'w': op = AbsoluteDestination(2); break; case 'l': op = AbsoluteDestination(3); break; default: op = null; break; } break; case 'R': // 16 bit register encoded in lsb op = new RegisterOperand(Reg(fmt[i++], b & 0x7)); break; case 'S': // status/flag register op = StatusRegister(fmt[i++]); break; } if (op == null) { return(Decode(b, Opcode.invalid, "")); } ops.Add(op); } if (ops.Count > 0) { instr.op1 = ops[0]; if (ops.Count > 1) { instr.op2 = ops[1]; if (ops.Count > 2) { instr.op3 = ops[2]; } } } return(instr); }
public Expression Transform() { ctx.RemoveIdentifierUse(idLeft); return(new BinaryExpression(Operator.IMul, idLeft.DataType, idLeft, Constant.Create(idLeft.DataType, 2))); }
public override IExpression Invoke(IExpressionContext context) { return(Constant.Create(nameof(Select), Expressions.SafeInvoke(context).ToList())); }
public Expression Const(DataType dataType, int p) { return(Constant.Create(dataType, p)); }
public virtual Expression VisitMkSequence(MkSequence seq) { var newSeq = seq.Expressions.Select(e => { var eNew = e.Accept(this); if (eNew == Constant.Invalid) { eNew = e; } return(eNew); }).ToArray(); if (newSeq.Length == 2) { // Special case for the frequent case of segment:offset or // two concatenated bit vectors. if (newSeq[0] is Constant c1 && newSeq[1] is Constant c2) { PrimitiveType tHead = (PrimitiveType)c1.DataType; PrimitiveType tTail = (PrimitiveType)c2.DataType; PrimitiveType t; Changed = true; if (tHead.Domain == Domain.Selector) //$REVIEW: seems to require Address, SegmentedAddress? { t = PrimitiveType.Create(Domain.Pointer, tHead.BitSize + tTail.BitSize); return(ctx.MakeSegmentedAddress(c1, c2)); } else { t = PrimitiveType.Create(tHead.Domain, tHead.BitSize + tTail.BitSize); return(Constant.Create(t, (c1.ToUInt64() << tTail.BitSize) | c2.ToUInt64())); } } } else if (newSeq.All(e => e is Constant)) { //$TODO: > 64 bit values? ulong value = 0; for (int i = 0; i < newSeq.Length; ++i) { var c = (Constant)newSeq[i]; value = (value << c.DataType.BitSize) | c.ToUInt64(); } return(Constant.Create(seq.DataType, value)); } if (newSeq.Take(newSeq.Length - 1).All(e => e.IsZero)) { var tail = newSeq.Last(); // leading zeros imply a conversion to unsigned. return(new Conversion( tail, PrimitiveType.Create(Domain.UnsignedInt, tail.DataType.BitSize), PrimitiveType.Create(Domain.UnsignedInt, seq.DataType.BitSize))); } var mem = FuseAdjacentMemoryAccesses(seq.DataType, newSeq); if (mem != null) { return(mem); } return(FuseAdjacentSlices(seq.DataType, newSeq)); }
public void ExaUsrGlobals_Real32() { Given_GlobalVariable( Address.Ptr32(0x10001200), PrimitiveType.Real32); RunTest(Constant.Create(PrimitiveType.Real32, 0x10001200)); }
} // the data width of the current instruction being rewritten. /// <summary> /// Rewrite operands being used as sources. /// </summary> /// <param name="operand"></param> /// <param name="addrInstr">Address of the current instruction</param> /// <returns></returns> public Expression RewriteSrc(MachineOperand operand, Address addrInstr, bool addressAsAddress = false) { var reg = operand as RegisterOperand; if (reg != null) { Expression r = binder.EnsureRegister(reg.Register); if (DataWidth != null && DataWidth.Size != reg.Width.Size) { r = m.Cast(DataWidth, r); } return(r); } var imm = operand as M68kImmediateOperand; if (imm != null) { if (imm.Width.Domain == Domain.Real) { return(imm.Constant.CloneExpression()); } if (DataWidth != null && DataWidth.BitSize > imm.Width.BitSize) { return(Constant.Create(DataWidth, imm.Constant.ToInt64())); } else { return(Constant.Create(imm.Width, imm.Constant.ToUInt32())); } } var mem = operand as MemoryOperand; if (mem != null) { return(RewriteMemoryAccess(mem, DataWidth, addrInstr)); } var addr = operand as M68kAddressOperand; if (addr != null) { if (addressAsAddress) { return(addr.Address); } else { return(m.Mem(DataWidth, addr.Address)); } } var pre = operand as PredecrementMemoryOperand; if (pre != null) { var ea = binder.EnsureRegister(pre.Register); m.Assign(ea, m.ISub(ea, m.Int32(DataWidth.Size))); return(m.Mem(DataWidth, ea)); } var post = operand as PostIncrementMemoryOperand; if (post != null) { var r = binder.EnsureRegister(post.Register); var tmp = binder.CreateTemporary(DataWidth); m.Assign(tmp, m.Mem(DataWidth, r)); m.Assign(r, m.IAdd(r, m.Int32(DataWidth.Size))); return(tmp); } var indidx = operand as IndirectIndexedOperand; if (indidx != null) { Expression ea = RewriteIndirectBaseRegister(indidx, addrInstr); Expression ix = binder.EnsureRegister(indidx.XRegister); if (indidx.XWidth.Size != 4) { ix = m.Cast(PrimitiveType.Int32, m.Cast(PrimitiveType.Int16, ix)); } if (indidx.Scale > 1) { ix = m.IMul(ix, Constant.Int32(indidx.Scale)); } return(m.Mem(DataWidth, m.IAdd(ea, ix))); } var indop = operand as IndexedOperand; if (indop != null) { Expression ea = Combine(indop.Base, indop.base_reg); if (indop.postindex) { ea = m.Mem32(ea); } if (indop.index_reg != null) { var idx = Combine(null, indop.index_reg); if (indop.index_reg_width.BitSize != 32) { idx = m.Cast(PrimitiveType.Word32, m.Cast(PrimitiveType.Int16, idx)); } if (indop.index_scale > 1) { idx = m.IMul(idx, indop.index_scale); } ea = Combine(ea, idx); } if (indop.preindex) { ea = m.Mem32(ea); } ea = Combine(ea, indop.outer); return(m.Mem(DataWidth, ea)); } throw new NotImplementedException("Unimplemented RewriteSrc for operand type " + operand.GetType().Name); }
private void RewriteOne(PrimitiveType dt) { m.Assign(RewriteSrc(instr.Operands[0]), Constant.Create(dt, 1)); }
public virtual Expression VisitConversion(Conversion conversion) { var exp = conversion.Expression.Accept(this); if (exp != Constant.Invalid) { var ptCvt = conversion.DataType.ResolveAs <PrimitiveType>(); var ptSrc = conversion.SourceDataType.ResolveAs <PrimitiveType>(); if (exp is Constant c && ptCvt != null) { if (ptSrc != null) { if (ptCvt.Domain == Domain.Real) { if (ptSrc.Domain == Domain.Real) { if (ptCvt.Size < ptSrc.Size) { // Real-to-real conversion. Changed = true; return(ConstantReal.Create(ptCvt, c.ToReal64())); } } else if (ptSrc.IsWord) { // Raw bit pattern reinterpretation. Changed = true; return(CastRawBitsToReal(ptCvt, c)); } else { // integer to real conversion Changed = true; return(ConstantReal.Create(ptCvt, c.ToInt64())); } } else if ((ptSrc.Domain & Domain.Integer) != 0) { if (ptSrc != null) { if (ptSrc.Domain == Domain.SignedInt) { Changed = true; return(Constant.Create(ptCvt, c.ToInt64())); } else if (ptSrc.Domain.HasFlag(Domain.SignedInt)) { Changed = true; return(Constant.Create(ptCvt, c.ToUInt64())); } } } } } if (exp is Identifier id && ctx.GetDefiningExpression(id) is MkSequence seq) { // If we are casting a SEQ, and the corresponding element is >= // the size of the cast, then use deposited part directly. var lsbElem = seq.Expressions[seq.Expressions.Length - 1]; int sizeDiff = lsbElem.DataType.Size - conversion.DataType.Size; if (sizeDiff >= 0) { foreach (var elem in seq.Expressions) { ctx.RemoveExpressionUse(elem); } ctx.UseExpression(lsbElem); Changed = true; if (sizeDiff > 0) { return(new Conversion(lsbElem, lsbElem.DataType, conversion.DataType)); } else { return(lsbElem); } } } if (exp is ProcedureConstant pc && conversion.DataType.BitSize == pc.DataType.BitSize) { // (wordnn) procedure_const => procedure_const return(pc); } if (exp.DataType.BitSize == conversion.DataType.BitSize) { // Redundant word-casts can be stripped. if (conversion.DataType.IsWord) { return(exp); } } conversion = new Conversion(exp, exp.DataType, conversion.DataType); } if (convertConvertRule.Match(conversion)) { Changed = true; return(convertConvertRule.Transform()); } return(conversion); }
private BinaryExpression CmpExpressionToZero(Expression e) { return(new BinaryExpression(Operator.ISub, e.DataType, e, Constant.Create(e.DataType, 0))); }
/// <summary> /// Memory accesses are translated into expressions, performing simplifications /// where possible. /// </summary> public Expression EffectiveAddressExpression(X86Instruction instr, MemoryOperand mem) { Expression?eIndex = null; Expression?eBase = null; Expression?expr = null; bool ripRelative = false; if (mem.Base != RegisterStorage.None) { if (mem.Base == Registers.rip) { ripRelative = true; } else { eBase = AluRegister(mem.Base); if (expr != null) { expr = m.IAdd(eBase, expr); } else { expr = eBase; } } } if (mem.Offset !.IsValid) { if (ripRelative) { expr = instr.Address + (instr.Length + mem.Offset.ToInt64()); } else if (expr != null) { BinaryOperator op = Operator.IAdd; long l = mem.Offset.ToInt64(); if (l < 0 && l > -0x800) { l = -l; op = Operator.ISub; } DataType dt = (eBase != null) ? eBase.DataType : eIndex !.DataType; Constant cOffset = Constant.Create(dt, l); expr = new BinaryExpression(op, dt, expr, cOffset); } else { expr = mem.Offset; } } if (mem.Index != RegisterStorage.None) { eIndex = AluRegister(mem.Index); if (mem.Scale != 0 && mem.Scale != 1) { eIndex = m.IMul(eIndex, Constant.Create(mem.Index.DataType, mem.Scale)); } expr = m.IAdd(expr !, eIndex); } if (!IsSegmentedAccessRequired && expr is Constant c && mem.SegOverride == RegisterStorage.None) { return(arch.MakeAddressFromConstant(c, false) !); } return(expr !); }
public void AddPointerReference(ulong imageOffset, uint pointer) { var c = Constant.Create(PrimitiveType.Pointer32, pointer); map.Add(imageOffset, c); }