Improved the disassembly output again

This commit is contained in:
Pierre Pronchery 2011-04-24 16:42:24 +00:00
parent 9229d32d41
commit 99240a31be
2 changed files with 65 additions and 7 deletions

View File

@ -191,6 +191,7 @@ typedef struct _ArchPluginHelper
/* disassembly */ /* disassembly */
ssize_t (*read)(Arch * arch, void * buf, size_t size); ssize_t (*read)(Arch * arch, void * buf, size_t size);
ssize_t (*seek)(Arch * arch, off_t offset, int whence);
} ArchPluginHelper; } ArchPluginHelper;
typedef struct _ArchPlugin ArchPlugin; typedef struct _ArchPlugin ArchPlugin;

View File

@ -46,6 +46,7 @@ struct _Arch
size_t registers_cnt; size_t registers_cnt;
/* internal */ /* internal */
off_t base;
char const * filename; char const * filename;
FILE * fp; FILE * fp;
char const * buffer; char const * buffer;
@ -65,6 +66,8 @@ struct _Arch
static char const * _arch_get_filename(Arch * arch); static char const * _arch_get_filename(Arch * arch);
static ssize_t _arch_read(Arch * arch, void * buf, size_t size); static ssize_t _arch_read(Arch * arch, void * buf, size_t size);
static ssize_t _arch_read_buffer(Arch * arch, void * buf, size_t size); static ssize_t _arch_read_buffer(Arch * arch, void * buf, size_t size);
static off_t _arch_seek(Arch * arch, off_t offset, int whence);
static off_t _arch_seek_buffer(Arch * arch, off_t offset, int whence);
static ssize_t _arch_write(Arch * arch, void const * buf, size_t size); static ssize_t _arch_write(Arch * arch, void const * buf, size_t size);
@ -428,31 +431,50 @@ ArchRegister * arch_get_register_by_name_size(Arch * arch, char const * name,
/* useful */ /* useful */
/* arch_decode */ /* arch_decode */
static void _decode_print(off_t offset, ArchInstructionCall * call); static int _decode_print(Arch * arch, ArchInstructionCall * call, off_t offset,
size_t size);
int arch_decode(Arch * arch) int arch_decode(Arch * arch)
{ {
ArchInstructionCall call; ArchInstructionCall call;
off_t offset = arch->buffer_pos; off_t offset = arch->buffer_pos;
size_t size;
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); printf("\n%08lx:\n", offset + arch->base);
for(; arch->plugin->decode(arch->plugin, &call) == 0; for(; arch->plugin->decode(arch->plugin, &call) == 0;
offset = arch->buffer_pos) offset = arch->buffer_pos)
_decode_print(offset, &call); {
size = arch->buffer_pos - offset;
if(_decode_print(arch, &call, offset, size) != 0)
return -1;
}
return 0; return 0;
} }
static void _decode_print(off_t offset, ArchInstructionCall * call) static int _decode_print(Arch * arch, ArchInstructionCall * call, off_t offset,
size_t size)
{ {
char const * sep = " "; char const * sep = " ";
size_t i; size_t i;
uint8_t u8;
ArchOperand * ao; ArchOperand * ao;
char const * name; char const * name;
printf("%8lx: %-12s", offset, call->name); if(arch->helper.seek(arch, offset, SEEK_SET) != offset)
return -1;
printf("%8lx:", offset + arch->base);
for(i = 0; i < size; i++)
{
if(arch->helper.read(arch, &u8, sizeof(u8)) != sizeof(u8))
return -1;
printf(" %02x", u8);
}
for(; i < 8; i++)
printf(" ");
printf(" %-12s", call->name);
for(i = 0; i < call->operands_cnt; i++) for(i = 0; i < call->operands_cnt; i++)
{ {
ao = &call->operands[i]; ao = &call->operands[i];
@ -482,6 +504,7 @@ static void _decode_print(off_t offset, ArchInstructionCall * call)
sep = ", "; sep = ", ";
} }
putchar('\n'); putchar('\n');
return 0;
} }
@ -497,8 +520,9 @@ int arch_decode_at(Arch * arch, off_t offset, size_t size, off_t base)
return -error_set_code(1, "%s", strerror(errno)); return -error_set_code(1, "%s", strerror(errno));
if(size == 0) if(size == 0)
return 0; return 0;
arch->buffer_pos = offset + base; arch->base = base;
arch->buffer_cnt = offset + base + size; arch->buffer_pos = offset;
arch->buffer_cnt = offset + size;
if((ret = arch_decode(arch)) == 0 if((ret = arch_decode(arch)) == 0
&& fseek(arch->fp, offset + size, SEEK_SET) != 0) && fseek(arch->fp, offset + size, SEEK_SET) != 0)
ret = -error_set_code(1, "%s", strerror(errno)); ret = -error_set_code(1, "%s", strerror(errno));
@ -529,8 +553,11 @@ 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->base = 0;
arch->filename = filename; arch->filename = filename;
arch->fp = fp; arch->fp = fp;
arch->buffer = NULL;
arch->buffer_cnt = 0;
arch->buffer_pos = 0; /* XXX used as offset */ arch->buffer_pos = 0; /* XXX used as offset */
arch->helper.arch = arch; arch->helper.arch = arch;
arch->helper.get_filename = _arch_get_filename; arch->helper.get_filename = _arch_get_filename;
@ -538,6 +565,7 @@ int arch_init(Arch * arch, char const * filename, FILE * fp)
arch->helper.get_register_by_id_size = arch_get_register_by_id_size; arch->helper.get_register_by_id_size = arch_get_register_by_id_size;
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.read = _arch_read; arch->helper.read = _arch_read;
arch->helper.seek = _arch_seek;
arch->helper.write = _arch_write; arch->helper.write = _arch_write;
arch->plugin->helper = &arch->helper; arch->plugin->helper = &arch->helper;
return 0; return 0;
@ -550,7 +578,9 @@ int arch_init_buffer(Arch * arch, char const * buffer, size_t size)
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "DEBUG: %s()\n", __func__); fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif #endif
arch->base = 0;
arch->filename = "buffer"; arch->filename = "buffer";
arch->fp = NULL;
arch->buffer = buffer; arch->buffer = buffer;
arch->buffer_cnt = size; arch->buffer_cnt = size;
arch->buffer_pos = 0; arch->buffer_pos = 0;
@ -561,6 +591,7 @@ int arch_init_buffer(Arch * arch, char const * buffer, size_t size)
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 = NULL; arch->helper.write = NULL;
arch->helper.read = _arch_read_buffer; arch->helper.read = _arch_read_buffer;
arch->helper.seek = _arch_seek_buffer;
arch->plugin->helper = &arch->helper; arch->plugin->helper = &arch->helper;
return 0; return 0;
} }
@ -622,6 +653,32 @@ static ssize_t _arch_read_buffer(Arch * arch, void * buf, size_t size)
} }
/* arch_seek */
static off_t _arch_seek(Arch * arch, off_t offset, int whence)
{
if(fseek(arch->fp, offset, whence) != 0)
return -error_set_code(1, "%s: %s", arch->filename,
strerror(errno));
arch->buffer_pos = ftello(arch->fp);
return arch->buffer_pos;
}
/* arch_seek_buffer */
static off_t _arch_seek_buffer(Arch * arch, off_t offset, int whence)
{
if(whence == SEEK_SET)
{
if(offset < 0 || offset > arch->buffer_cnt)
return -error_set_code(1, "%s", "Invalid seek");
arch->buffer_pos = offset;
return offset;
}
/* FIXME implement */
return -error_set_code(1, "%s", "Not implemented");
}
/* arch_write */ /* arch_write */
static ssize_t _arch_write(Arch * arch, void const * buf, size_t size) static ssize_t _arch_write(Arch * arch, void const * buf, size_t size)
{ {