Improving support for the i386 architecture again

This commit is contained in:
Pierre Pronchery 2011-04-16 15:51:39 +00:00
parent 7649d220c2
commit ed661daee0
3 changed files with 113 additions and 23 deletions

View File

@ -166,9 +166,15 @@ typedef struct _ArchRegister
typedef struct _ArchPluginHelper typedef struct _ArchPluginHelper
{ {
void * priv;
/* variables */
char const * filename; char const * filename;
FILE * fp; FILE * fp;
void * priv;
/* callbacks */
int32_t (*get_register_by_name_size)(void * priv, char const * name,
uint32_t size);
} ArchPluginHelper; } ArchPluginHelper;
typedef struct _ArchPlugin ArchPlugin; typedef struct _ArchPlugin ArchPlugin;

View File

@ -386,8 +386,10 @@ 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->helper.priv = arch;
arch->helper.filename = filename; arch->helper.filename = filename;
arch->helper.fp = fp; arch->helper.fp = fp;
arch->helper.get_register_by_name_size = arch_get_register_by_name_size;
arch->plugin->helper = &arch->helper; arch->plugin->helper = &arch->helper;
return 0; return 0;
} }

View File

@ -81,41 +81,123 @@ ArchPlugin arch_plugin =
/* functions */ /* functions */
static int _write_immediate(ArchPlugin * plugin,
ArchOperandDefinition definition, ArchOperand * operand);
static int _write_immediate8(ArchPlugin * plugin, uint8_t value);
static int _write_immediate16(ArchPlugin * plugin, uint16_t value);
static int _write_immediate32(ArchPlugin * plugin, uint32_t value);
static int _write_opcode(ArchPlugin * plugin, ArchInstruction * instruction);
static int _write_operand(ArchPlugin * plugin, ArchOperandDefinition definition,
ArchOperand * operand);
static int _write_register(ArchPlugin * plugin,
ArchOperandDefinition definition, ArchOperand * operand);
static int _i386_write(ArchPlugin * plugin, ArchInstruction * instruction, static int _i386_write(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call) ArchInstructionCall * call)
{ {
unsigned char * buf; size_t i;
uint32_t size; ArchOperandDefinition definition;
uint8_t u8;
uint16_t u16;
uint32_t u32;
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, instruction->name); fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, instruction->name);
#endif #endif
/* opcode */ if(_write_opcode(plugin, instruction) != 0)
size = (AO_GET_SIZE(instruction->flags) >> 3); return -1;
for(i = 0; i < call->operands_cnt; i++)
{
definition = (i == 0) ? instruction->op1 : ((i == 1)
? instruction->op2 : instruction->op3);
if(_write_operand(plugin, definition, &call->operands[i]) != 0)
return -1;
}
return 0;
}
static int _write_immediate(ArchPlugin * plugin,
ArchOperandDefinition definition, ArchOperand * operand)
{
size_t size;
size = AO_GET_SIZE(definition) >> 3;
switch(size) switch(size)
{ {
case 0: case 0:
break; return 0;
case sizeof(u8): case sizeof(uint8_t):
u8 = instruction->opcode; return _write_immediate8(plugin,
buf = &u8; operand->value.immediate.value);
break; case sizeof(uint16_t):
case sizeof(u16): return _write_immediate16(plugin,
u16 = _htob16(instruction->opcode); operand->value.immediate.value);
buf = &u16; case sizeof(uint32_t):
break; return _write_immediate32(plugin,
case sizeof(u32): operand->value.immediate.value);
u32 = _htob32(instruction->opcode);
buf = &u32;
break;
default: default:
return -1; return -1;
} }
if(size > 0 && fwrite(buf, size, 1, plugin->helper->fp) != 1) }
static int _write_immediate8(ArchPlugin * plugin, uint8_t value)
{
if(fwrite(&value, sizeof(value), 1, plugin->helper->fp) != 1)
return -1; return -1;
/* FIXME implement the rest */
return 0; return 0;
} }
static int _write_immediate16(ArchPlugin * plugin, uint16_t value)
{
value = _htol16(value);
if(fwrite(&value, sizeof(value), 1, plugin->helper->fp) != 1)
return -1;
return 0;
}
static int _write_immediate32(ArchPlugin * plugin, uint32_t value)
{
value = _htol32(value);
if(fwrite(&value, sizeof(value), 1, plugin->helper->fp) != 1)
return -1;
return 0;
}
static int _write_opcode(ArchPlugin * plugin, ArchInstruction * instruction)
{
ArchOperand operand;
memset(&operand, 0, sizeof(operand));
operand.type = AOT_IMMEDIATE;
operand.value.immediate.value = instruction->opcode;
return _write_immediate(plugin, instruction->flags, &operand);
}
static int _write_operand(ArchPlugin * plugin, ArchOperandDefinition definition,
ArchOperand * operand)
{
switch(operand->type)
{
case AOT_IMMEDIATE:
return _write_immediate(plugin, definition, operand);
case AOT_REGISTER:
return _write_register(plugin, definition, operand);
}
return 0;
}
static int _write_register(ArchPlugin * plugin,
ArchOperandDefinition definition, ArchOperand * operand)
{
ArchPluginHelper * helper = plugin->helper;
ArchOperandDefinition idefinition;
ArchOperand ioperand;
char const * name = operand->value._register.name;
size_t size = AO_GET_SIZE(definition);
if(AO_GET_FLAGS(definition) & AOF_IMPLICIT)
return 0;
idefinition = AO_IMMEDIATE(0, 0, 8);
memset(&ioperand, 0, sizeof(ioperand));
ioperand.type = AOT_IMMEDIATE;
ioperand.value.immediate.value = helper->get_register_by_name_size(
helper->priv, name, size);
return _write_immediate(plugin, idefinition, &ioperand);
}