Evince
Evince is a document viewer capable of displaying multiple and single page document formats like PDF and Postscript.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
rarvm.h File Reference
#include <stdint.h>
#include <stdbool.h>
+ Include dependency graph for rarvm.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  RARVirtualMachine
 

Macros

#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
 

Typedefs

typedef struct RARVirtualMachine RARVirtualMachine
 
typedef struct RARProgram_s RARProgram
 

Enumerations

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
}
 

Functions

RARProgramRARCreateProgram (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)
 
bool RARExecuteProgram (RARVirtualMachine *vm, RARProgram *prog)
 
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)
 
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)
 
void RARPrintProgram (RARProgram *prog)
 

Macro Definition Documentation

#define RARAbsoluteAddressingMode   24

Definition at line 25 of file rarvm.h.

#define RARImmediateAddressingMode   25

Definition at line 26 of file rarvm.h.

#define RARIndexedAbsoluteAddressingMode (   n)    (16 + (n))

Definition at line 24 of file rarvm.h.

#define RARNumberOfAddressingModes   26

Definition at line 27 of file rarvm.h.

#define RARProgramGlobalSize   0x2000

Definition at line 15 of file rarvm.h.

#define RARProgramMemoryMask   (RARProgramMemorySize - 1)

Definition at line 13 of file rarvm.h.

#define RARProgramMemorySize   0x40000

Definition at line 12 of file rarvm.h.

#define RARProgramSystemGlobalAddress   RARProgramWorkSize

Definition at line 16 of file rarvm.h.

#define RARProgramSystemGlobalSize   64

Definition at line 17 of file rarvm.h.

#define RARProgramUserGlobalAddress   (RARProgramSystemGlobalAddress + RARProgramSystemGlobalSize)

Definition at line 18 of file rarvm.h.

#define RARProgramUserGlobalSize   (RARProgramGlobalSize - RARProgramSystemGlobalSize)

Definition at line 19 of file rarvm.h.

#define RARProgramWorkSize   0x3c000

Definition at line 14 of file rarvm.h.

#define RARRegisterAddressingMode (   n)    (0 + (n))

Definition at line 22 of file rarvm.h.

#define RARRegisterIndirectAddressingMode (   n)    (8 + (n))

Definition at line 23 of file rarvm.h.

#define RARRuntimeMaxInstructions   250000000

Definition at line 20 of file rarvm.h.

Typedef Documentation

typedef struct RARProgram_s RARProgram

Definition at line 36 of file rarvm.h.

Definition at line 29 of file rarvm.h.

Enumeration Type Documentation

anonymous enum
Enumerator
RARMovInstruction 
RARCmpInstruction 
RARAddInstruction 
RARSubInstruction 
RARJzInstruction 
RARJnzInstruction 
RARIncInstruction 
RARDecInstruction 
RARJmpInstruction 
RARXorInstruction 
RARAndInstruction 
RAROrInstruction 
RARTestInstruction 
RARJsInstruction 
RARJnsInstruction 
RARJbInstruction 
RARJbeInstruction 
RARJaInstruction 
RARJaeInstruction 
RARPushInstruction 
RARPopInstruction 
RARCallInstruction 
RARRetInstruction 
RARNotInstruction 
RARShlInstruction 
RARShrInstruction 
RARSarInstruction 
RARNegInstruction 
RARPushaInstruction 
RARPopaInstruction 
RARPushfInstruction 
RARPopfInstruction 
RARMovzxInstruction 
RARMovsxInstruction 
RARXchgInstruction 
RARMulInstruction 
RARDivInstruction 
RARAdcInstruction 
RARSbbInstruction 
RARPrintInstruction 
RARNumberOfInstructions 

Definition at line 40 of file rarvm.h.

40  {
45  RARJzInstruction = 4,
51  RARAndInstruction = 10,
52  RAROrInstruction = 11,
53  RARTestInstruction = 12,
54  RARJsInstruction = 13,
55  RARJnsInstruction = 14,
56  RARJbInstruction = 15,
57  RARJbeInstruction = 16,
58  RARJaInstruction = 17,
59  RARJaeInstruction = 18,
60  RARPushInstruction = 19,
61  RARPopInstruction = 20,
62  RARCallInstruction = 21,
63  RARRetInstruction = 22,
64  RARNotInstruction = 23,
65  RARShlInstruction = 24,
66  RARShrInstruction = 25,
67  RARSarInstruction = 26,
68  RARNegInstruction = 27,
70  RARPopaInstruction = 29,
72  RARPopfInstruction = 31,
75  RARXchgInstruction = 34,
76  RARMulInstruction = 35,
77  RARDivInstruction = 36,
78  RARAdcInstruction = 37,
79  RARSbbInstruction = 38,
82 };

Function Documentation

int NumberOfRARInstructionOperands ( uint8_t  instruction)

Definition at line 528 of file rarvm.c.

529 {
530  if (instruction >= RARNumberOfInstructions)
531  return 0;
532  return InstructionFlags[instruction] & RAROperandsFlag;
533 }

+ Here is the caller graph for this function:

RARProgram* RARCreateProgram ( void  )

Definition at line 31 of file rarvm.c.

32 {
33  return calloc(1, sizeof(RARProgram));
34 }

+ Here is the caller graph for this function:

void RARDeleteProgram ( RARProgram prog)

Definition at line 36 of file rarvm.c.

37 {
38  if (prog)
39  free(prog->opcodes);
40  free(prog);
41 }

+ Here is the caller graph for this function:

bool RARExecuteProgram ( RARVirtualMachine vm,
RARProgram prog 
)

Definition at line 140 of file rarvm.c.

141 {
142  RAROpcode *opcode = prog->opcodes;
143  uint32_t flags = 0;
144  uint32_t op1, op2, carry, i;
145  uint32_t counter = 0;
146 
147  if (!RARIsProgramTerminated(prog))
148  return false;
149 
150  while ((uint32_t)(opcode - prog->opcodes) < prog->length && counter++ < RARRuntimeMaxInstructions) {
151  switch (opcode->instruction) {
152  case RARMovInstruction:
154  NextInstruction();
155 
156  case RARCmpInstruction:
157  op1 = GetOperand1();
158  SetFlagsWithCarry(op1 - GetOperand2(), result > op1);
159  NextInstruction();
160 
161  case RARAddInstruction:
162  op1 = GetOperand1();
163  if (opcode->bytemode)
164  SetOperand1AndByteFlagsWithCarry((op1 + GetOperand2()) & 0xFF, result < op1);
165  else
166  SetOperand1AndFlagsWithCarry(op1 + GetOperand2(), result < op1);
167  NextInstruction();
168 
169  case RARSubInstruction:
170  op1 = GetOperand1();
171 #if 0 /* apparently not correctly implemented in the RAR VM */
172  if (opcode->bytemode)
173  SetOperand1AndByteFlagsWithCarry((op1 - GetOperand2()) & 0xFF, result > op1);
174  else
175 #endif
176  SetOperand1AndFlagsWithCarry(op1 - GetOperand2(), result > op1);
177  NextInstruction();
178 
179  case RARJzInstruction:
180  if ((flags & ZeroFlag))
181  Jump(GetOperand1());
182  NextInstruction();
183 
184  case RARJnzInstruction:
185  if (!(flags & ZeroFlag))
186  Jump(GetOperand1());
187  NextInstruction();
188 
189  case RARIncInstruction:
190  if (opcode->bytemode)
191  SetOperand1AndFlags((GetOperand1() + 1) & 0xFF);
192  else
194  NextInstruction();
195 
196  case RARDecInstruction:
197  if (opcode->bytemode)
198  SetOperand1AndFlags((GetOperand1() - 1) & 0xFF);
199  else
201  NextInstruction();
202 
203  case RARJmpInstruction:
204  Jump(GetOperand1());
205 
206  case RARXorInstruction:
208  NextInstruction();
209 
210  case RARAndInstruction:
212  NextInstruction();
213 
214  case RAROrInstruction:
216  NextInstruction();
217 
218  case RARTestInstruction:
220  NextInstruction();
221 
222  case RARJsInstruction:
223  if ((flags & SignFlag))
224  Jump(GetOperand1());
225  NextInstruction();
226 
227  case RARJnsInstruction:
228  if (!(flags & SignFlag))
229  Jump(GetOperand1());
230  NextInstruction();
231 
232  case RARJbInstruction:
233  if ((flags & CarryFlag))
234  Jump(GetOperand1());
235  NextInstruction();
236 
237  case RARJbeInstruction:
238  if ((flags & (CarryFlag | ZeroFlag)))
239  Jump(GetOperand1());
240  NextInstruction();
241 
242  case RARJaInstruction:
243  if (!(flags & (CarryFlag | ZeroFlag)))
244  Jump(GetOperand1());
245  NextInstruction();
246 
247  case RARJaeInstruction:
248  if (!(flags & CarryFlag))
249  Jump(GetOperand1());
250  NextInstruction();
251 
252  case RARPushInstruction:
253  vm->registers[7] -= 4;
255  NextInstruction();
256 
257  case RARPopInstruction:
259  vm->registers[7] += 4;
260  NextInstruction();
261 
262  case RARCallInstruction:
263  vm->registers[7] -= 4;
264  RARVirtualMachineWrite32(vm, vm->registers[7], (uint32_t)(opcode - prog->opcodes + 1));
265  Jump(GetOperand1());
266 
267  case RARRetInstruction:
268  if (vm->registers[7] >= RARProgramMemorySize)
269  return true;
270  i = RARVirtualMachineRead32(vm, vm->registers[7]);
271  vm->registers[7] += 4;
272  Jump(i);
273 
274  case RARNotInstruction:
276  NextInstruction();
277 
278  case RARShlInstruction:
279  op1 = GetOperand1();
280  op2 = GetOperand2();
281  SetOperand1AndFlagsWithCarry(op1 << op2, ((op1 << (op2 - 1)) & 0x80000000) != 0);
282  NextInstruction();
283 
284  case RARShrInstruction:
285  op1 = GetOperand1();
286  op2 = GetOperand2();
287  SetOperand1AndFlagsWithCarry(op1 >> op2, ((op1 >> (op2 - 1)) & 1) != 0);
288  NextInstruction();
289 
290  case RARSarInstruction:
291  op1 = GetOperand1();
292  op2 = GetOperand2();
293  SetOperand1AndFlagsWithCarry(((int32_t)op1) >> op2, ((op1 >> (op2 - 1)) & 1) != 0);
294  NextInstruction();
295 
296  case RARNegInstruction:
297  SetOperand1AndFlagsWithCarry(-(int32_t)GetOperand1(), result != 0);
298  NextInstruction();
299 
300  case RARPushaInstruction:
301  vm->registers[7] -= 32;
302  for (i = 0; i < 8; i++)
303  RARVirtualMachineWrite32(vm, vm->registers[7] + (7 - i) * 4, vm->registers[i]);
304  NextInstruction();
305 
306  case RARPopaInstruction:
307  for (i = 0; i < 8; i++)
308  vm->registers[i] = RARVirtualMachineRead32(vm, vm->registers[7] + (7 - i) * 4);
309  vm->registers[7] += 32;
310  NextInstruction();
311 
312  case RARPushfInstruction:
313  vm->registers[7] -= 4;
314  RARVirtualMachineWrite32(vm, vm->registers[7], flags);
315  NextInstruction();
316 
317  case RARPopfInstruction:
318  flags = RARVirtualMachineRead32(vm, vm->registers[7]);
319  vm->registers[7] += 4;
320  NextInstruction();
321 
322  case RARMovzxInstruction:
324  NextInstruction();
325 
326  case RARMovsxInstruction:
328  NextInstruction();
329 
330  case RARXchgInstruction:
331  op1 = GetOperand1();
332  op2 = GetOperand2();
333  SetOperand1(op2);
334  SetOperand2(op1);
335  NextInstruction();
336 
337  case RARMulInstruction:
339  NextInstruction();
340 
341  case RARDivInstruction:
342  op2 = GetOperand2();
343  if (op2 != 0)
344  SetOperand1(GetOperand1() / op2);
345  NextInstruction();
346 
347  case RARAdcInstruction:
348  op1 = GetOperand1();
349  carry = (flags & CarryFlag);
350  if (opcode->bytemode)
351  SetOperand1AndFlagsWithCarry((op1 + GetOperand2() + carry) & 0xFF, result < op1 || (result == op1 && carry)); /* does not correctly set sign bit */
352  else
353  SetOperand1AndFlagsWithCarry(op1 + GetOperand2() + carry, result < op1 || (result == op1 && carry));
354  NextInstruction();
355 
356  case RARSbbInstruction:
357  op1 = GetOperand1();
358  carry = (flags & CarryFlag);
359  if (opcode->bytemode)
360  SetOperand1AndFlagsWithCarry((op1 - GetOperand2() - carry) & 0xFF, result > op1 || (result == op1 && carry)); /* does not correctly set sign bit */
361  else
362  SetOperand1AndFlagsWithCarry(op1 - GetOperand2() - carry, result > op1 || (result == op1 && carry));
363  NextInstruction();
364 
365  case RARPrintInstruction:
366  /* TODO: ??? */
367  NextInstruction();
368  }
369  }
370 
371  return false;
372 }

+ Here is the caller graph for this function:

bool RARInstructionHasByteMode ( uint8_t  instruction)

Definition at line 535 of file rarvm.c.

536 {
537  if (instruction >= RARNumberOfInstructions)
538  return false;
539  return (InstructionFlags[instruction] & RARHasByteModeFlag)!=0;
540 }

+ Here is the caller graph for this function:

bool RARInstructionIsRelativeJump ( uint8_t  instruction)

Definition at line 549 of file rarvm.c.

550 {
551  if (instruction >= RARNumberOfInstructions)
552  return false;
553  return (InstructionFlags[instruction] & RARIsRelativeJumpFlag) != 0;
554 }

+ Here is the caller graph for this function:

bool RARInstructionIsUnconditionalJump ( uint8_t  instruction)

Definition at line 542 of file rarvm.c.

543 {
544  if (instruction >= RARNumberOfInstructions)
545  return false;
546  return (InstructionFlags[instruction] & RARIsUnconditionalJumpFlag) != 0;
547 }

+ Here is the caller graph for this function:

bool RARInstructionWritesFirstOperand ( uint8_t  instruction)

Definition at line 556 of file rarvm.c.

557 {
558  if (instruction >= RARNumberOfInstructions)
559  return false;
560  return (InstructionFlags[instruction] & RARWritesFirstOperandFlag) != 0;
561 }

+ Here is the caller graph for this function:

bool RARInstructionWritesSecondOperand ( uint8_t  instruction)

Definition at line 563 of file rarvm.c.

564 {
565  if (instruction >= RARNumberOfInstructions)
566  return false;
567  return (InstructionFlags[instruction] & RARWritesSecondOperandFlag) != 0;
568 }

+ Here is the caller graph for this function:

bool RARIsProgramTerminated ( RARProgram prog)

Definition at line 101 of file rarvm.c.

102 {
103  return prog->length > 0 && RARInstructionIsUnconditionalJump(prog->opcodes[prog->length - 1].instruction);
104 }

+ Here is the caller graph for this function:

void RARPrintProgram ( RARProgram prog)

Definition at line 589 of file rarvm.c.

590 {
591  static const char *instructionNames[RARNumberOfInstructions] = {
592  "Mov", "Cmp", "Add", "Sub", "Jz", "Jnz", "Inc", "Dec", "Jmp", "Xor",
593  "And", "Or", "Test", "Js", "Jns", "Jb", "Jbe", "Ja", "Jae", "Push",
594  "Pop", "Call", "Ret", "Not", "Shl", "Shr", "Sar", "Neg", "Pusha", "Popa",
595  "Pushf", "Popf", "Movzx", "Movsx", "Xchg", "Mul", "Div", "Adc", "Sbb", "Print",
596  };
597 
598  uint32_t i;
599  for (i = 0; i < prog->length; i++) {
600  RAROpcode *opcode = &prog->opcodes[i];
601  int numoperands = NumberOfRARInstructionOperands(opcode->instruction);
602  printf(" %02x: %s", i, instructionNames[opcode->instruction]);
603  if (opcode->bytemode)
604  printf("B");
605  if (numoperands >= 1) {
606  printf(" ");
607  RARPrintOperand(opcode->addressingmode1, opcode->value1);
608  }
609  if (numoperands == 2) {
610  printf(", ");
611  RARPrintOperand(opcode->addressingmode2, opcode->value2);
612  }
613  printf("\n");
614  }
615 }
bool RARProgramAddInstr ( RARProgram prog,
uint8_t  instruction,
bool  bytemode 
)

Definition at line 43 of file rarvm.c.

44 {
45  if (instruction >= RARNumberOfInstructions)
46  return false;
47  if (bytemode && !RARInstructionHasByteMode(instruction))
48  return false;
49  if (prog->length + 1 >= prog->capacity) {
50  /* in my small file sample, 16 is the value needed most often */
51  uint32_t newCapacity = prog->capacity ? prog->capacity * 4 : 32;
52  RAROpcode *newCodes = calloc(newCapacity, sizeof(*prog->opcodes));
53  if (!newCodes)
54  return false;
55  memcpy(newCodes, prog->opcodes, prog->capacity * sizeof(*prog->opcodes));
56  free(prog->opcodes);
57  prog->opcodes = newCodes;
58  prog->capacity = newCapacity;
59  }
60  memset(&prog->opcodes[prog->length], 0, sizeof(prog->opcodes[prog->length]));
61  prog->opcodes[prog->length].instruction = instruction;
62  if (instruction == RARMovzxInstruction || instruction == RARMovsxInstruction)
63  prog->opcodes[prog->length].bytemode = 2; /* second argument only */
64  else if (bytemode)
65  prog->opcodes[prog->length].bytemode = (1 | 2);
66  else
67  prog->opcodes[prog->length].bytemode = 0;
68  prog->length++;
69  return true;
70 }

+ Here is the caller graph for this function:

bool RARSetLastInstrOperands ( RARProgram prog,
uint8_t  addressingmode1,
uint32_t  value1,
uint8_t  addressingmode2,
uint32_t  value2 
)

Definition at line 72 of file rarvm.c.

73 {
74  RAROpcode *opcode = &prog->opcodes[prog->length - 1];
75  int numoperands;
76 
77  if (addressingmode1 >= RARNumberOfAddressingModes || addressingmode2 >= RARNumberOfAddressingModes)
78  return false;
79  if (!prog->length || opcode->addressingmode1 || opcode->value1 || opcode->addressingmode2 || opcode->value2)
80  return false;
81 
82  numoperands = NumberOfRARInstructionOperands(opcode->instruction);
83  if (numoperands == 0)
84  return true;
85 
87  return false;
88  opcode->addressingmode1 = addressingmode1;
89  opcode->value1 = value1;
90 
91  if (numoperands == 2) {
93  return false;
94  opcode->addressingmode2 = addressingmode2;
95  opcode->value2 = value2;
96  }
97 
98  return true;
99 }

+ Here is the caller graph for this function:

void RARSetVirtualMachineRegisters ( RARVirtualMachine vm,
uint32_t  registers[8] 
)

Definition at line 389 of file rarvm.c.

390 {
391  if (registers)
392  memcpy(vm->registers, registers, sizeof(vm->registers));
393  else
394  memset(vm->registers, 0, sizeof(vm->registers));
395 }

+ Here is the caller graph for this function:

uint32_t RARVirtualMachineRead32 ( RARVirtualMachine vm,
uint32_t  address 
)

Definition at line 397 of file rarvm.c.

398 {
399  return _RARRead32(&vm->memory[address & RARProgramMemoryMask]);
400 }

+ Here is the caller graph for this function:

uint8_t RARVirtualMachineRead8 ( RARVirtualMachine vm,
uint32_t  address 
)

Definition at line 407 of file rarvm.c.

408 {
409  return vm->memory[address & RARProgramMemoryMask];
410 }

+ Here is the caller graph for this function:

void RARVirtualMachineWrite32 ( RARVirtualMachine vm,
uint32_t  address,
uint32_t  val 
)

Definition at line 402 of file rarvm.c.

403 {
404  _RARWrite32(&vm->memory[address & RARProgramMemoryMask], val);
405 }

+ Here is the caller graph for this function:

void RARVirtualMachineWrite8 ( RARVirtualMachine vm,
uint32_t  address,
uint8_t  val 
)

Definition at line 412 of file rarvm.c.

413 {
414  vm->memory[address & RARProgramMemoryMask] = val;
415 }

+ Here is the caller graph for this function: