2018-02-06 02:31:05 +00:00
|
|
|
/*
|
|
|
|
* vm_reflect.c
|
2018-02-13 03:15:20 +00:00
|
|
|
*
|
|
|
|
* Here we have support for reflection, or perhaps meta-manipulation, of
|
|
|
|
* the virtual machine. You can create hooks to stop the machine, or
|
|
|
|
* disassemble opcodes from it, or handle state.
|
2018-02-06 02:31:05 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include "log.h"
|
2018-02-07 06:02:20 +00:00
|
|
|
#include "vm_di.h"
|
2018-02-06 02:31:05 +00:00
|
|
|
#include "vm_reflect.h"
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create a new vm_reflect struct with the given machine, cpu and
|
|
|
|
* stream.
|
|
|
|
*/
|
|
|
|
vm_reflect *
|
2018-02-07 06:02:20 +00:00
|
|
|
vm_reflect_create()
|
2018-02-06 02:31:05 +00:00
|
|
|
{
|
|
|
|
vm_reflect *ref;
|
|
|
|
|
|
|
|
ref = malloc(sizeof(vm_reflect));
|
|
|
|
if (ref == NULL) {
|
|
|
|
log_critical("Could not allocate memory for vm_reflect");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2018-02-07 06:02:20 +00:00
|
|
|
ref->machine = vm_di_get(VM_MACHINE);
|
|
|
|
ref->cpu = vm_di_get(VM_CPU);
|
|
|
|
ref->stream = vm_di_get(VM_OUTPUT);
|
2018-02-06 02:31:05 +00:00
|
|
|
|
|
|
|
ref->cpu_info = NULL;
|
|
|
|
ref->machine_info = NULL;
|
|
|
|
ref->pause = NULL;
|
2018-02-07 20:41:44 +00:00
|
|
|
ref->disasm = NULL;
|
2018-02-06 02:31:05 +00:00
|
|
|
|
|
|
|
return ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Free a vm_reflect struct that we created earlier
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
vm_reflect_free(vm_reflect *ref)
|
|
|
|
{
|
|
|
|
// Not much to this--just going to free the main memory chunk
|
|
|
|
free(ref);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* All of the reflect functions do essentially the same thing--at least,
|
|
|
|
* right now they do.
|
|
|
|
*/
|
2018-02-06 03:54:38 +00:00
|
|
|
#define REFLECT_HANDLER(x) \
|
2018-02-06 02:31:05 +00:00
|
|
|
int vm_reflect_##x(vm_reflect *ref) { \
|
2018-02-07 06:02:20 +00:00
|
|
|
if (ref == NULL) ref = (vm_reflect *)vm_di_get(VM_REFLECT); \
|
2018-02-06 02:31:05 +00:00
|
|
|
if (ref->x == NULL) return ERR_INVALID; ref->x(ref); return OK; }
|
|
|
|
|
2018-02-06 03:54:38 +00:00
|
|
|
REFLECT_HANDLER(cpu_info); // ignore docblock
|
|
|
|
REFLECT_HANDLER(machine_info); // ignore docblock
|
|
|
|
REFLECT_HANDLER(pause); // ignore docblock
|
2018-02-07 20:41:44 +00:00
|
|
|
REFLECT_HANDLER(disasm); // ignore docblock
|