Using helper callbacks to write assembly instructions
This commit is contained in:
parent
26777f9856
commit
a8407ddd19
@ -176,13 +176,14 @@ typedef struct _ArchPluginHelper
|
|||||||
{
|
{
|
||||||
Arch * arch;
|
Arch * arch;
|
||||||
|
|
||||||
/* variables */
|
|
||||||
char const * filename;
|
|
||||||
FILE * fp;
|
|
||||||
|
|
||||||
/* callbacks */
|
/* callbacks */
|
||||||
|
/* accessors */
|
||||||
|
char const * (*get_filename)(Arch * arch);
|
||||||
ArchRegister * (*get_register_by_name_size)(Arch * arch,
|
ArchRegister * (*get_register_by_name_size)(Arch * arch,
|
||||||
char const * name, uint32_t size);
|
char const * name, uint32_t size);
|
||||||
|
|
||||||
|
/* assembly */
|
||||||
|
ssize_t (*write)(Arch * arch, void const * buf, size_t size);
|
||||||
} ArchPluginHelper;
|
} ArchPluginHelper;
|
||||||
|
|
||||||
typedef struct _ArchPlugin ArchPlugin;
|
typedef struct _ArchPlugin ArchPlugin;
|
||||||
|
44
src/arch.c
44
src/arch.c
@ -19,7 +19,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <errno.h>
|
||||||
#include "Asm/arch.h"
|
#include "Asm/arch.h"
|
||||||
#include "Asm/asm.h"
|
#include "Asm/asm.h"
|
||||||
#include "arch.h"
|
#include "arch.h"
|
||||||
@ -41,6 +41,10 @@ struct _Arch
|
|||||||
ArchPlugin * plugin;
|
ArchPlugin * plugin;
|
||||||
size_t instructions_cnt;
|
size_t instructions_cnt;
|
||||||
size_t registers_cnt;
|
size_t registers_cnt;
|
||||||
|
|
||||||
|
/* internal */
|
||||||
|
char const * filename;
|
||||||
|
FILE * fp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -50,6 +54,12 @@ struct _Arch
|
|||||||
((ai->op3 & AOM_TYPE) ? 1 : 0))
|
((ai->op3 & AOM_TYPE) ? 1 : 0))
|
||||||
|
|
||||||
|
|
||||||
|
/* prototypes */
|
||||||
|
/* callbacks */
|
||||||
|
static char const * _arch_get_filename(Arch * arch);
|
||||||
|
static ssize_t _arch_write(Arch * arch, void const * buf, size_t size);
|
||||||
|
|
||||||
|
|
||||||
/* public */
|
/* public */
|
||||||
/* functions */
|
/* functions */
|
||||||
/* arch_new */
|
/* arch_new */
|
||||||
@ -413,6 +423,8 @@ ArchRegister * arch_get_register_by_name_size(Arch * arch, char const * name,
|
|||||||
/* arch_exit */
|
/* arch_exit */
|
||||||
int arch_exit(Arch * arch)
|
int arch_exit(Arch * arch)
|
||||||
{
|
{
|
||||||
|
arch->filename = NULL;
|
||||||
|
arch->fp = NULL;
|
||||||
memset(&arch->helper, 0, sizeof(arch->helper));
|
memset(&arch->helper, 0, sizeof(arch->helper));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -425,10 +437,12 @@ int arch_init(Arch * arch, char const * filename, FILE * fp)
|
|||||||
fprintf(stderr, "DEBUG: %s(\"%s\", %p)\n", __func__, filename,
|
fprintf(stderr, "DEBUG: %s(\"%s\", %p)\n", __func__, filename,
|
||||||
(void *)fp);
|
(void *)fp);
|
||||||
#endif
|
#endif
|
||||||
|
arch->filename = filename;
|
||||||
|
arch->fp = fp;
|
||||||
arch->helper.arch = arch;
|
arch->helper.arch = arch;
|
||||||
arch->helper.filename = filename;
|
arch->helper.get_filename = _arch_get_filename;
|
||||||
arch->helper.fp = fp;
|
|
||||||
arch->helper.get_register_by_name_size = arch_get_register_by_name_size;
|
arch->helper.get_register_by_name_size = arch_get_register_by_name_size;
|
||||||
|
arch->helper.write = _arch_write;
|
||||||
arch->plugin->helper = &arch->helper;
|
arch->plugin->helper = &arch->helper;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -443,3 +457,27 @@ int arch_write(Arch * arch, ArchInstruction * instruction,
|
|||||||
#endif
|
#endif
|
||||||
return arch->plugin->write(arch->plugin, instruction, call);
|
return arch->plugin->write(arch->plugin, instruction, call);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* private */
|
||||||
|
/* callbacks */
|
||||||
|
/* arch_get_filename */
|
||||||
|
static char const * _arch_get_filename(Arch * arch)
|
||||||
|
{
|
||||||
|
return arch->filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* arch_write */
|
||||||
|
static ssize_t _arch_write(Arch * arch, void const * buf, size_t size)
|
||||||
|
{
|
||||||
|
if(fwrite(buf, size, 1, arch->fp) == 1)
|
||||||
|
return size;
|
||||||
|
if(ferror(arch->fp))
|
||||||
|
return -error_set_code(1, "%s: %s", arch->filename,
|
||||||
|
strerror(errno));
|
||||||
|
if(feof(arch->fp))
|
||||||
|
return -error_set_code(1, "%s: %s", arch->filename,
|
||||||
|
"End of file reached");
|
||||||
|
return -error_set_code(1, "%s: %s", arch->filename, "Write error");
|
||||||
|
}
|
||||||
|
@ -111,10 +111,11 @@ static int _dalvik_write(ArchPlugin * plugin, ArchInstruction * instruction,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* FIXME should not happen */
|
/* FIXME should not happen */
|
||||||
return -error_set_code(1, "%s: %s", helper->filename,
|
return -error_set_code(1, "%s: %s",
|
||||||
|
helper->get_filename(helper->arch),
|
||||||
"Invalid size for opcode");
|
"Invalid size for opcode");
|
||||||
}
|
}
|
||||||
if(fwrite(buf, size, 1, helper->fp) != 1)
|
if(helper->write(helper->arch, buf, size) != size)
|
||||||
return -1; /* XXX report error */
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -158,36 +158,40 @@ static int _write_immediate(ArchPlugin * plugin,
|
|||||||
|
|
||||||
static int _write_immediate8(ArchPlugin * plugin, uint8_t value)
|
static int _write_immediate8(ArchPlugin * plugin, uint8_t value)
|
||||||
{
|
{
|
||||||
if(fwrite(&value, sizeof(value), 1, plugin->helper->fp) != 1)
|
ArchPluginHelper * helper = plugin->helper;
|
||||||
return -error_set_code(1, "%s: %s", plugin->helper->filename,
|
|
||||||
strerror(errno));
|
if(helper->write(helper->arch, &value, sizeof(value)) != sizeof(value))
|
||||||
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _write_immediate16(ArchPlugin * plugin, uint16_t value)
|
static int _write_immediate16(ArchPlugin * plugin, uint16_t value)
|
||||||
{
|
{
|
||||||
|
ArchPluginHelper * helper = plugin->helper;
|
||||||
|
|
||||||
value = _htol16(value);
|
value = _htol16(value);
|
||||||
if(fwrite(&value, sizeof(value), 1, plugin->helper->fp) != 1)
|
if(helper->write(helper->arch, &value, sizeof(value)) != sizeof(value))
|
||||||
return -error_set_code(1, "%s: %s", plugin->helper->filename,
|
return -1;
|
||||||
strerror(errno));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _write_immediate24(ArchPlugin * plugin, uint32_t value)
|
static int _write_immediate24(ArchPlugin * plugin, uint32_t value)
|
||||||
{
|
{
|
||||||
|
ArchPluginHelper * helper = plugin->helper;
|
||||||
|
|
||||||
value = _htol32(value) >> 8;
|
value = _htol32(value) >> 8;
|
||||||
if(fwrite(&value, 3, 1, plugin->helper->fp) != 1)
|
if(helper->write(helper->arch, &value, 3) != 3)
|
||||||
return -error_set_code(1, "%s: %s", plugin->helper->filename,
|
return -1;
|
||||||
strerror(errno));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _write_immediate32(ArchPlugin * plugin, uint32_t value)
|
static int _write_immediate32(ArchPlugin * plugin, uint32_t value)
|
||||||
{
|
{
|
||||||
|
ArchPluginHelper * helper = plugin->helper;
|
||||||
|
|
||||||
value = _htol32(value);
|
value = _htol32(value);
|
||||||
if(fwrite(&value, sizeof(value), 1, plugin->helper->fp) != 1)
|
if(helper->write(helper->arch, &value, sizeof(value)) != sizeof(value))
|
||||||
return -error_set_code(1, "%s: %s", plugin->helper->filename,
|
return -1;
|
||||||
strerror(errno));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,7 +275,6 @@ static int _java_write(ArchPlugin * plugin, ArchInstruction * instruction,
|
|||||||
ArchPluginHelper * helper = plugin->helper;
|
ArchPluginHelper * helper = plugin->helper;
|
||||||
|
|
||||||
/* FIXME really implement */
|
/* FIXME really implement */
|
||||||
return (fwrite(&instruction->opcode, sizeof(char), 1, helper->fp) == 1)
|
return (helper->write(helper->arch, &instruction->opcode, 1) == 1)
|
||||||
? 0 : -error_set_code(1, "%s: %s", helper->filename,
|
? 0 : -1;
|
||||||
strerror(errno));
|
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@ static int _write_sethi(ArchPlugin * plugin, ArchInstruction * instruction,
|
|||||||
static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction,
|
static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction,
|
||||||
ArchInstructionCall * call)
|
ArchInstructionCall * call)
|
||||||
{
|
{
|
||||||
|
ArchPluginHelper * helper = plugin->helper;
|
||||||
uint32_t opcode = instruction->opcode;
|
uint32_t opcode = instruction->opcode;
|
||||||
|
|
||||||
if((opcode & 0xc0000000) == 0xc0000000)
|
if((opcode & 0xc0000000) == 0xc0000000)
|
||||||
@ -66,7 +67,8 @@ static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction,
|
|||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
opcode = _htob32(opcode);
|
opcode = _htob32(opcode);
|
||||||
if(fwrite(&opcode, sizeof(opcode), 1, plugin->helper->fp) != 1)
|
if(helper->write(helper->arch, &opcode, sizeof(opcode))
|
||||||
|
!= sizeof(opcode))
|
||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user