public static MaybeOption <YmmRegister> GetOperand(CodeContext context, Instruction instruction, SharpDisasm.Operand operand, YmmRegister overload) { if (operand.Type == ud_type.UD_OP_REG) { var reg = SdToAsm.SdToAsmJit(context, operand.Base); if (reg.Present && reg.Type == RegisterType.YmmRegister) { return(new MaybeOption <YmmRegister>() { Present = true, Value = (YmmRegister)reg.Register }); } } return(new MaybeOption <YmmRegister>()); }
public static MaybeOption <Memory> GetOperand(CodeContext context, Instruction instruction, SharpDisasm.Operand operand, Memory overload) { if (operand.Type == ud_type.UD_OP_MEM) { Memory memoryReference = null; GpRegister baseRegister = null; bool baseRipRegister = false; MaybeRegister maybeIndexRegister = null; if (operand.Base != ud_type.UD_NONE) { var maybeBaseRegister = SdToAsm.SdToAsmJit(context, operand.Base); if (!maybeBaseRegister.Present) { throw new Exception($"could not map base register for: {instruction}"); } if (maybeBaseRegister.Type != RegisterType.GpRegister) { if (maybeBaseRegister.Type == RegisterType.RipRegister) { baseRipRegister = true; } else { throw new Exception("could not map base register to GpRegister"); } } else { baseRegister = (GpRegister)maybeBaseRegister.Register; } } if (operand.Index != ud_type.UD_NONE) { maybeIndexRegister = SdToAsm.SdToAsmJit(context, operand.Index); if (!maybeIndexRegister.Present) { throw new Exception("could not map base register"); } } var displacement = SdToAsm.GetDisplacement(instruction, operand); var displacementIntPtr = (IntPtr)displacement.Value; var scale = 0; switch (operand.Scale) { case 0: case 1: scale = 0; break; case 2: scale = 1; break; case 4: scale = 2; break; case 8: scale = 3; break; } if (baseRipRegister) { // in our emulator we are going to keep our RIP in target (RAX) if (maybeIndexRegister == null) { switch (operand.Size) { case 8: memoryReference = Memory.Byte(CodeContext.Rip, (int)displacement.Value); break; case 16: memoryReference = Memory.Word(CodeContext.Rip, (int)displacement.Value); break; case 32: memoryReference = Memory.DWord(CodeContext.Rip, (int)displacement.Value); break; case 64: memoryReference = Memory.QWord(CodeContext.Rip, (int)displacement.Value); break; case 80: memoryReference = Memory.TWord(CodeContext.Rip, (int)displacement.Value); break; default: throw new Exception("unsupported operand size"); } } else { throw new Exception("index register not supported when base register is RIP"); } } else { if (baseRegister == null && maybeIndexRegister == null) { switch (operand.Size) { case 8: memoryReference = Memory.ByteAbs(displacementIntPtr); break; case 16: memoryReference = Memory.WordAbs(displacementIntPtr); break; case 32: memoryReference = Memory.DWordAbs(displacementIntPtr); break; case 64: memoryReference = Memory.QWordAbs(displacementIntPtr); break; default: throw new Exception("unsupported operand size"); } } else if (baseRegister != null && maybeIndexRegister == null) { switch (operand.Size) { case 8: memoryReference = Memory.Byte(baseRegister, (int)displacement.Value); break; case 16: memoryReference = Memory.Word(baseRegister, (int)displacement.Value); break; case 32: memoryReference = Memory.DWord(baseRegister, (int)displacement.Value); break; case 64: memoryReference = Memory.QWord(baseRegister, (int)displacement.Value); break; case 80: memoryReference = Memory.TWord(baseRegister, (int)displacement.Value); break; default: throw new Exception("unsupported operand size"); } } else if (baseRegister == null) { switch (operand.Size) { case 8: switch (maybeIndexRegister.Type) { case RegisterType.MmRegister: throw new Exception("mmregister not supported as index by asmjit"); case RegisterType.SegRegister: throw new Exception("segregister not supported as index by asmjit"); case RegisterType.GpRegister: memoryReference = Memory.ByteAbs(displacementIntPtr, (GpRegister)maybeIndexRegister.Register, scale); break; case RegisterType.XmmRegister: memoryReference = Memory.ByteAbs(displacementIntPtr, (XmmRegister)maybeIndexRegister.Register, scale); break; case RegisterType.YmmRegister: memoryReference = Memory.ByteAbs(displacementIntPtr, (YmmRegister)maybeIndexRegister.Register, scale); break; } break; case 16: switch (maybeIndexRegister.Type) { case RegisterType.MmRegister: throw new Exception("mmregister not supported as index by asmjit"); case RegisterType.SegRegister: throw new Exception("segregister not supported as index by asmjit"); case RegisterType.GpRegister: memoryReference = Memory.WordAbs(displacementIntPtr, (GpRegister)maybeIndexRegister.Register, scale); break; case RegisterType.XmmRegister: memoryReference = Memory.WordAbs(displacementIntPtr, (XmmRegister)maybeIndexRegister.Register, scale); break; case RegisterType.YmmRegister: memoryReference = Memory.WordAbs(displacementIntPtr, (YmmRegister)maybeIndexRegister.Register, scale); break; } break; case 32: switch (maybeIndexRegister.Type) { case RegisterType.MmRegister: throw new Exception("mmregister not supported as index by asmjit"); case RegisterType.SegRegister: throw new Exception("segregister not supported as index by asmjit"); case RegisterType.GpRegister: memoryReference = Memory.DWordAbs(displacementIntPtr, (GpRegister)maybeIndexRegister.Register, scale); break; case RegisterType.XmmRegister: memoryReference = Memory.DWordAbs(displacementIntPtr, (XmmRegister)maybeIndexRegister.Register, scale); break; case RegisterType.YmmRegister: memoryReference = Memory.DWordAbs(displacementIntPtr, (YmmRegister)maybeIndexRegister.Register, scale); break; } break; case 64: switch (maybeIndexRegister.Type) { case RegisterType.MmRegister: throw new Exception("mmregister not supported as index by asmjit"); case RegisterType.SegRegister: throw new Exception("segregister not supported as index by asmjit"); case RegisterType.GpRegister: memoryReference = Memory.QWordAbs(displacementIntPtr, (GpRegister)maybeIndexRegister.Register, scale); break; case RegisterType.XmmRegister: memoryReference = Memory.QWordAbs(displacementIntPtr, (XmmRegister)maybeIndexRegister.Register, scale); break; case RegisterType.YmmRegister: memoryReference = Memory.QWordAbs(displacementIntPtr, (YmmRegister)maybeIndexRegister.Register, scale); break; } break; case 80: throw new Exception("unsupported operand size 80"); default: throw new Exception("unsupported operand size"); } } else { switch (operand.Size) { case 8: switch (maybeIndexRegister.Type) { case RegisterType.MmRegister: throw new Exception("mmregister not supported as index by asmjit"); case RegisterType.SegRegister: throw new Exception("segregister not supported as index by asmjit"); case RegisterType.GpRegister: memoryReference = Memory.Byte(baseRegister, (GpRegister)maybeIndexRegister.Register, scale, (int)displacement.Value); break; case RegisterType.XmmRegister: memoryReference = Memory.Byte(baseRegister, (XmmRegister)maybeIndexRegister.Register, scale, (int)displacement.Value); break; case RegisterType.YmmRegister: memoryReference = Memory.Byte(baseRegister, (YmmRegister)maybeIndexRegister.Register, scale, (int)displacement.Value); break; } break; case 16: switch (maybeIndexRegister.Type) { case RegisterType.MmRegister: throw new Exception("mmregister not supported as index by asmjit"); case RegisterType.SegRegister: throw new Exception("segregister not supported as index by asmjit"); case RegisterType.GpRegister: memoryReference = Memory.Word(baseRegister, (GpRegister)maybeIndexRegister.Register, scale, (int)displacement.Value); break; case RegisterType.XmmRegister: memoryReference = Memory.Word(baseRegister, (XmmRegister)maybeIndexRegister.Register, scale, (int)displacement.Value); break; case RegisterType.YmmRegister: memoryReference = Memory.Word(baseRegister, (YmmRegister)maybeIndexRegister.Register, scale, (int)displacement.Value); break; } break; case 32: switch (maybeIndexRegister.Type) { case RegisterType.MmRegister: throw new Exception("mmregister not supported as index by asmjit"); case RegisterType.SegRegister: throw new Exception("segregister not supported as index by asmjit"); case RegisterType.GpRegister: memoryReference = Memory.DWord(baseRegister, (GpRegister)maybeIndexRegister.Register, scale, (int)displacement.Value); break; case RegisterType.XmmRegister: memoryReference = Memory.DWord(baseRegister, (XmmRegister)maybeIndexRegister.Register, scale, (int)displacement.Value); break; case RegisterType.YmmRegister: memoryReference = Memory.DWord(baseRegister, (YmmRegister)maybeIndexRegister.Register, scale, (int)displacement.Value); break; } break; case 64: switch (maybeIndexRegister.Type) { case RegisterType.MmRegister: throw new Exception("mmregister not supported as index by asmjit"); case RegisterType.SegRegister: throw new Exception("segregister not supported as index by asmjit"); case RegisterType.GpRegister: memoryReference = Memory.QWord(baseRegister, (GpRegister)maybeIndexRegister.Register, scale, (int)displacement.Value); break; case RegisterType.XmmRegister: memoryReference = Memory.QWord(baseRegister, (XmmRegister)maybeIndexRegister.Register, scale, (int)displacement.Value); break; case RegisterType.YmmRegister: memoryReference = Memory.QWord(baseRegister, (YmmRegister)maybeIndexRegister.Register, scale, (int)displacement.Value); break; } break; case 80: throw new Exception("unsupported operand size 80"); default: throw new Exception("unsupported operand size"); } } } if (memoryReference == null) { throw new AssembleException("could not parse SharpDisasm memory reference"); } return(new MaybeOption <Memory>() { Present = true, Value = memoryReference }); } return(new MaybeOption <Memory>()); }