/* Copyright 2015 the unarr project authors (see AUTHORS file). License: LGPLv3 */ /* adapted from https://code.google.com/p/theunarchiver/source/browse/XADMaster/RARVirtualMachine.h */ #ifndef rar_vm_h #define rar_vm_h #include #include #define RARProgramMemorySize 0x40000 #define RARProgramMemoryMask (RARProgramMemorySize - 1) #define RARProgramWorkSize 0x3c000 #define RARProgramGlobalSize 0x2000 #define RARProgramSystemGlobalAddress RARProgramWorkSize #define RARProgramSystemGlobalSize 64 #define RARProgramUserGlobalAddress (RARProgramSystemGlobalAddress + RARProgramSystemGlobalSize) #define RARProgramUserGlobalSize (RARProgramGlobalSize - RARProgramSystemGlobalSize) #define RARRuntimeMaxInstructions 250000000 #define RARRegisterAddressingMode(n) (0 + (n)) #define RARRegisterIndirectAddressingMode(n) (8 + (n)) #define RARIndexedAbsoluteAddressingMode(n) (16 + (n)) #define RARAbsoluteAddressingMode 24 #define RARImmediateAddressingMode 25 #define RARNumberOfAddressingModes 26 typedef struct RARVirtualMachine RARVirtualMachine; struct RARVirtualMachine { uint32_t registers[8]; uint8_t memory[RARProgramMemorySize + sizeof(uint32_t) /* overflow sentinel */]; }; typedef struct RARProgram_s RARProgram; /* Program building */ enum { RARMovInstruction = 0, RARCmpInstruction = 1, RARAddInstruction = 2, RARSubInstruction = 3, RARJzInstruction = 4, RARJnzInstruction = 5, RARIncInstruction = 6, RARDecInstruction = 7, RARJmpInstruction = 8, RARXorInstruction = 9, RARAndInstruction = 10, RAROrInstruction = 11, RARTestInstruction = 12, RARJsInstruction = 13, RARJnsInstruction = 14, RARJbInstruction = 15, RARJbeInstruction = 16, RARJaInstruction = 17, RARJaeInstruction = 18, RARPushInstruction = 19, RARPopInstruction = 20, RARCallInstruction = 21, RARRetInstruction = 22, RARNotInstruction = 23, RARShlInstruction = 24, RARShrInstruction = 25, RARSarInstruction = 26, RARNegInstruction = 27, RARPushaInstruction = 28, RARPopaInstruction = 29, RARPushfInstruction = 30, RARPopfInstruction = 31, RARMovzxInstruction = 32, RARMovsxInstruction = 33, RARXchgInstruction = 34, RARMulInstruction = 35, RARDivInstruction = 36, RARAdcInstruction = 37, RARSbbInstruction = 38, RARPrintInstruction = 39, RARNumberOfInstructions = 40, }; RARProgram *RARCreateProgram(void); void RARDeleteProgram(RARProgram *prog); bool RARProgramAddInstr(RARProgram *prog, uint8_t instruction, bool bytemode); bool RARSetLastInstrOperands(RARProgram *prog, uint8_t addressingmode1, uint32_t value1, uint8_t addressingmode2, uint32_t value2); bool RARIsProgramTerminated(RARProgram *prog); /* Execution */ bool RARExecuteProgram(RARVirtualMachine *vm, RARProgram *prog); /* Memory and register access (convenience) */ void RARSetVirtualMachineRegisters(RARVirtualMachine *vm, uint32_t registers[8]); uint32_t RARVirtualMachineRead32(RARVirtualMachine *vm, uint32_t address); void RARVirtualMachineWrite32(RARVirtualMachine *vm, uint32_t address, uint32_t val); uint8_t RARVirtualMachineRead8(RARVirtualMachine *vm, uint32_t address); void RARVirtualMachineWrite8(RARVirtualMachine *vm, uint32_t address, uint8_t val); /* Instruction properties */ int NumberOfRARInstructionOperands(uint8_t instruction); bool RARInstructionHasByteMode(uint8_t instruction); bool RARInstructionIsUnconditionalJump(uint8_t instruction); bool RARInstructionIsRelativeJump(uint8_t instruction); bool RARInstructionWritesFirstOperand(uint8_t instruction); bool RARInstructionWritesSecondOperand(uint8_t instruction); /* Program debugging */ #ifndef NDEBUG void RARPrintProgram(RARProgram *prog); #endif #endif