Saving all instructions into memory before printing them (will help handle labels)

This commit is contained in:
Pierre Pronchery 2011-04-25 00:10:50 +00:00
parent 62978f4e08
commit 92979e4dac
2 changed files with 35 additions and 16 deletions

View File

@ -163,6 +163,11 @@ typedef struct _ArchInstructionCall
char const * name; char const * name;
ArchOperand operands[3]; ArchOperand operands[3];
uint32_t operands_cnt; uint32_t operands_cnt;
/* meta information */
off_t base;
size_t offset;
size_t size;
} ArchInstructionCall; } ArchInstructionCall;
typedef struct _ArchRegister typedef struct _ArchRegister

View File

@ -431,31 +431,45 @@ ArchRegister * arch_get_register_by_name_size(Arch * arch, char const * name,
/* useful */ /* useful */
/* arch_decode */ /* arch_decode */
static int _decode_print(Arch * arch, ArchInstructionCall * call, off_t offset, static int _decode_print(Arch * arch, ArchInstructionCall * call);
size_t size);
int arch_decode(Arch * arch) int arch_decode(Arch * arch)
{ {
ArchInstructionCall call; ArchInstructionCall * calls = NULL;
off_t offset = arch->buffer_pos; size_t calls_cnt = 0;
size_t size; ArchInstructionCall * p;
size_t i;
if(arch->plugin->decode == NULL) if(arch->plugin->decode == NULL)
return -error_set_code(1, "%s: %s", arch->plugin->name, return -error_set_code(1, "%s: %s", arch->plugin->name,
"Disassembly not supported"); "Disassembly not supported");
printf("\n%08lx:\n", offset + arch->base); printf("\n%08lx:\n", arch->buffer_pos + arch->base);
for(; arch->plugin->decode(arch->plugin, &call) == 0; for(;;)
offset = arch->buffer_pos)
{ {
size = arch->buffer_pos - offset; if((p = realloc(calls, sizeof(*calls) * (calls_cnt + 1)))
if(_decode_print(arch, &call, offset, size) != 0) == NULL)
return -1; {
free(calls);
return -error_set_code(1, "%s", strerror(errno));
}
calls = p;
p = &calls[calls_cnt];
memset(p, 0, sizeof(*p));
p->base = arch->base;
p->offset = arch->buffer_pos;
if(arch->plugin->decode(arch->plugin, p) != 0)
break;
p->size = arch->buffer_pos - p->offset;
calls_cnt++;
} }
for(i = 0; i < calls_cnt; i++)
if(_decode_print(arch, &calls[i]) != 0)
return -1;
free(calls);
return 0; return 0;
} }
static int _decode_print(Arch * arch, ArchInstructionCall * call, off_t offset, static int _decode_print(Arch * arch, ArchInstructionCall * call)
size_t size)
{ {
char const * sep = " "; char const * sep = " ";
size_t i; size_t i;
@ -463,10 +477,10 @@ static int _decode_print(Arch * arch, ArchInstructionCall * call, off_t offset,
ArchOperand * ao; ArchOperand * ao;
char const * name; char const * name;
if(arch->helper.seek(arch, offset, SEEK_SET) != offset) if(arch->helper.seek(arch, call->offset, SEEK_SET) != call->offset)
return -1; return -1;
printf("%8lx:", offset + arch->base); printf("%8lx:", call->base + call->offset);
for(i = 0; i < size; i++) for(i = 0; i < call->size; i++)
{ {
if(arch->helper.read(arch, &u8, sizeof(u8)) != sizeof(u8)) if(arch->helper.read(arch, &u8, sizeof(u8)) != sizeof(u8))
return -1; return -1;