Using callbacks for file operations

This commit is contained in:
Pierre Pronchery 2011-04-22 02:29:44 +00:00
parent 0f1d52fbb9
commit 2bb09ddb7d
8 changed files with 431 additions and 337 deletions

View File

@ -23,15 +23,31 @@
/* AsmFormat */ /* AsmFormat */
/* types */ /* types */
typedef struct _FormatPluginHelper typedef struct _Format Format;
{
char const * filename;
FILE * fp;
void * priv;
} FormatPluginHelper;
typedef struct _FormatPlugin FormatPlugin; typedef struct _FormatPlugin FormatPlugin;
typedef struct _FormatPluginHelper
{
Format * format;
/* callbacks */
/* accessors */
char const * (*get_filename)(Format * format);
/* useful */
ssize_t (*read)(Format * format, void * buf, size_t size);
off_t (*seek)(Format * format, off_t offset, int whence);
/* assembly */
ssize_t (*write)(Format * format, void const * buf, size_t size);
/* disassembly */
/* FIXME let a different architecture be specified in the callback */
int (*disas)(Format * format, char const * section,
off_t offset, size_t size, off_t base);
} FormatPluginHelper;
struct _FormatPlugin struct _FormatPlugin
{ {
FormatPluginHelper * helper; FormatPluginHelper * helper;
@ -47,12 +63,7 @@ struct _FormatPlugin
int (*section)(FormatPlugin * format, char const * section); int (*section)(FormatPlugin * format, char const * section);
char const * (*detect)(FormatPlugin * format); char const * (*detect)(FormatPlugin * format);
/* FIXME: int (*disas)(FormatPlugin * format);
* - put the callback in the helper structure
* - let a different architecture be specified in the callback */
int (*disas)(FormatPlugin * format, int (*callback)(
FormatPlugin * format, char const * section,
off_t offset, size_t size, off_t base));
void * priv; void * priv;
}; };

View File

@ -34,9 +34,24 @@ struct _Format
FormatPluginHelper helper; FormatPluginHelper helper;
Plugin * handle; Plugin * handle;
FormatPlugin * plugin; FormatPlugin * plugin;
/* internal */
/* file */
char const * filename;
FILE * fp;
}; };
/* prototypes */
/* callbacks */
static char const * _format_get_filename(Format * format);
static ssize_t _format_read(Format * format, void * buf, size_t size);
static off_t _format_seek(Format * format, off_t offset, int whence);
static ssize_t _format_write(Format * format, void const * buf, size_t size);
/* public */ /* public */
/* functions */ /* functions */
/* format_new */ /* format_new */
@ -100,10 +115,12 @@ int format_exit(Format * format)
#endif #endif
if(format->plugin->exit != NULL) if(format->plugin->exit != NULL)
ret = format->plugin->exit(format->plugin); ret = format->plugin->exit(format->plugin);
format->helper.format = NULL;
format->helper.read = NULL;
format->helper.seek = NULL;
format->plugin->helper = NULL; format->plugin->helper = NULL;
format->helper.fp = NULL; format->fp = NULL;
format->helper.filename = NULL; format->filename = NULL;
format->helper.priv = NULL;
return ret; return ret;
} }
@ -124,9 +141,13 @@ int format_init(Format * format, 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
format->helper.filename = filename; format->filename = filename;
format->helper.fp = fp; format->fp = fp;
format->helper.priv = NULL; format->helper.format = format;
format->helper.get_filename = _format_get_filename;
format->helper.read = _format_read;
format->helper.seek = _format_seek;
format->helper.write = _format_write;
format->plugin->helper = &format->helper; format->plugin->helper = &format->helper;
if(format->plugin->init != NULL) if(format->plugin->init != NULL)
return format->plugin->init(format->plugin, format->arch); return format->plugin->init(format->plugin, format->arch);
@ -141,3 +162,62 @@ int format_section(Format * format, char const * section)
return 0; return 0;
return format->plugin->section(format->plugin, section); return format->plugin->section(format->plugin, section);
} }
/* private */
/* functions */
/* format_get_filename */
static char const * _format_get_filename(Format * format)
{
return format->filename;
}
/* format_read */
static ssize_t _format_read(Format * format, void * buf, size_t size)
{
if(fread(buf, size, 1, format->fp) == 1)
return size;
if(ferror(format->fp))
return -error_set_code(1, "%s: %s", format->filename,
strerror(errno));
if(feof(format->fp))
return -error_set_code(1, "%s: %s", format->filename,
"End of file reached");
return -error_set_code(1, "%s: %s", format->filename, "Read error");
}
/* format_seek */
static off_t _format_seek(Format * format, off_t offset, int whence)
{
if(whence == SEEK_SET)
{
if(fseek(format->fp, offset, whence) == 0)
return offset;
}
else if(whence == SEEK_CUR || whence == SEEK_END)
{
if(fseek(format->fp, offset, whence) == 0)
return ftello(format->fp);
}
else
return -error_set_code(1, "%s: %s", format->filename,
"Invalid argument for seeking");
return -error_set_code(1, "%s: %s", format->filename, strerror(errno));
}
/* format_write */
static ssize_t _format_write(Format * format, void const * buf, size_t size)
{
if(fwrite(buf, size, 1, format->fp) == 1)
return size;
if(ferror(format->fp))
return -error_set_code(1, "%s: %s", format->filename,
strerror(errno));
if(feof(format->fp))
return -error_set_code(1, "%s: %s", format->filename,
"End of file reached");
return -error_set_code(1, "%s: %s", format->filename, "Write error");
}

View File

@ -18,15 +18,11 @@
#ifndef ASM_FORMAT_H #ifndef ASM_FORMAT_H
# define ASM_FORMAT_H # define ASM_FORMAT_H
# include <stdio.h> # include "Asm/format.h"
/* Format */ /* Format */
/* public */ /* public */
/* types */
typedef struct _Format Format;
/* functions */ /* functions */
Format * format_new(char const * format, char const * arch); Format * format_new(char const * format, char const * arch);
void format_delete(Format * format); void format_delete(Format * format);

View File

@ -117,12 +117,9 @@ static char _dex_signature[4] = "dex\n";
static int _dex_init(FormatPlugin * format, char const * arch); static int _dex_init(FormatPlugin * format, char const * arch);
static int _dex_destroy(FormatPlugin * format); static int _dex_destroy(FormatPlugin * format);
static char const * _dex_detect(FormatPlugin * format); static char const * _dex_detect(FormatPlugin * format);
static int _dex_disas(FormatPlugin * format, int (*callback)( static int _dex_disas(FormatPlugin * format);
FormatPlugin * format, char const * section,
off_t offset, size_t size, off_t base));
static int _dex_error(FormatPlugin * format); static int _dex_error(FormatPlugin * format);
static int _dex_error_fread(FormatPlugin * format);
/* public */ /* public */
@ -189,59 +186,52 @@ static char const * _dex_detect(FormatPlugin * format)
/* dex_disas */ /* dex_disas */
static int _disas_map(FormatPlugin * format, DexHeader * dh, int (*callback)( static int _disas_map(FormatPlugin * format, DexHeader * dh);
FormatPlugin * format, char const * section, static int _disas_map_code(FormatPlugin * format, off_t offset, size_t size);
off_t offset, size_t size, off_t base));
static int _disas_map_code(FormatPlugin * format, off_t offset, size_t size,
int (*callback)(FormatPlugin * format, char const * section,
off_t offset, size_t size, off_t base));
static int _disas_map_string_id(FormatPlugin * format, off_t offset, static int _disas_map_string_id(FormatPlugin * format, off_t offset,
size_t size); size_t size);
static int _dex_disas(FormatPlugin * format, int (*callback)( static int _dex_disas(FormatPlugin * format)
FormatPlugin * format, char const * section,
off_t offset, size_t size, off_t base))
{ {
FILE * fp = format->helper->fp; FormatPluginHelper * helper = format->helper;
DexHeader dh; DexHeader dh;
if(fseek(fp, 0, SEEK_SET) != 0) if(helper->seek(helper->format, 0, SEEK_SET) != 0)
return -_dex_error(format); return -1;
if(fread(&dh, sizeof(dh), 1, fp) != 1) if(helper->read(helper->format, &dh, sizeof(dh)) != sizeof(dh))
return _dex_error_fread(format); return -1;
dh.map_off = _htol32(dh.map_off); dh.map_off = _htol32(dh.map_off);
if(_disas_map(format, &dh, callback) != 0) if(_disas_map(format, &dh) != 0)
return -1; return -1;
return 0; return 0;
} }
static int _disas_map(FormatPlugin * format, DexHeader * dh, int (*callback)( static int _disas_map(FormatPlugin * format, DexHeader * dh)
FormatPlugin * format, char const * section,
off_t offset, size_t size, off_t base))
{ {
int ret = 0; int ret = 0;
FILE * fp = format->helper->fp; FormatPluginHelper * helper = format->helper;
uint32_t size; uint32_t size;
uint32_t i; uint32_t i;
fpos_t pos; off_t offset;
DexMapItem dmi; DexMapItem dmi;
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "DEBUG: %s()\n", __func__); fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif #endif
if(fseek(fp, dh->map_off, SEEK_SET) != 0) if(helper->seek(helper->format, dh->map_off, SEEK_SET) != dh->map_off)
return -_dex_error(format); return -1;
if(fread(&size, sizeof(size), 1, fp) != 1) if(helper->read(helper->format, &size, sizeof(size)) != sizeof(size))
return -_dex_error_fread(format); return -1;
size = _htol32(size); size = _htol32(size);
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "DEBUG: %s() %u items\n", __func__, size); fprintf(stderr, "DEBUG: %s() %u items\n", __func__, size);
#endif #endif
for(i = 0; i < size; i++) for(i = 0; i < size; i++)
{ {
if(fread(&dmi, sizeof(dmi), 1, fp) != 1) if(helper->read(helper->format, &dmi, sizeof(dmi))
return -_dex_error_fread(format); != sizeof(dmi))
fgetpos(fp, &pos); return -1;
offset = helper->seek(helper->format, 0, SEEK_CUR);
dmi.type = _htol16(dmi.type); dmi.type = _htol16(dmi.type);
dmi.size = _htol32(dmi.size); dmi.size = _htol32(dmi.size);
dmi.offset = _htol32(dmi.offset); dmi.offset = _htol32(dmi.offset);
@ -253,44 +243,48 @@ static int _disas_map(FormatPlugin * format, DexHeader * dh, int (*callback)(
{ {
case TYPE_CODE_ITEM: case TYPE_CODE_ITEM:
ret |= _disas_map_code(format, dmi.offset, ret |= _disas_map_code(format, dmi.offset,
dmi.size, callback); dmi.size);
break; break;
case TYPE_STRING_ID_ITEM: case TYPE_STRING_ID_ITEM:
ret |= _disas_map_string_id(format, dmi.offset, ret |= _disas_map_string_id(format, dmi.offset,
dmi.size); dmi.size);
} }
fsetpos(fp, &pos); if(helper->seek(helper->format, offset, SEEK_SET) != offset)
return -1;
if(ret != 0) if(ret != 0)
break; break;
} }
return ret; return ret;
} }
static int _disas_map_code(FormatPlugin * format, off_t offset, size_t size, static int _disas_map_code(FormatPlugin * format, off_t offset, size_t size)
int (*callback)(FormatPlugin * format, char const * section,
off_t offset, size_t size, off_t base))
{ {
FILE * fp = format->helper->fp; FormatPluginHelper * helper = format->helper;
DexMapCodeItem dmci; DexMapCodeItem dmci;
size_t i; size_t i;
off_t seek; off_t seek;
size_t j; size_t j;
DexMapTryItem dmti; DexMapTryItem dmti;
ssize_t s;
if(fseek(fp, offset, SEEK_SET) != 0) if(helper->disas(helper->format, ".text", offset, 0, 0) != 0)
return -_dex_error(format); return -1;
callback(format, ".text", ftello(fp), 0, 0);
for(i = 0; i < size; i++) for(i = 0; i < size; i++)
{ {
if(fread(&dmci, sizeof(dmci), 1, fp) != 1) s = sizeof(dmci);
return -_dex_error_fread(format); if(helper->read(helper->format, &dmci, s) != s)
return -1;
dmci.registers_size = _htol16(dmci.registers_size); dmci.registers_size = _htol16(dmci.registers_size);
dmci.ins_size = _htol16(dmci.ins_size); dmci.ins_size = _htol16(dmci.ins_size);
dmci.outs_size = _htol16(dmci.outs_size); dmci.outs_size = _htol16(dmci.outs_size);
dmci.tries_size = _htol16(dmci.tries_size); dmci.tries_size = _htol16(dmci.tries_size);
dmci.debug_info_off = _htol32(dmci.debug_info_off); dmci.debug_info_off = _htol32(dmci.debug_info_off);
dmci.insns_size = _htol32(dmci.insns_size); dmci.insns_size = _htol32(dmci.insns_size);
seek = (dmci.insns_size & 0x1) == 0x1 ? 2 : 0; /* padding */ seek = helper->seek(helper->format, 0, SEEK_CUR);
helper->disas(helper->format, NULL, seek, dmci.insns_size * 2,
0);
/* skip padding and try_items */
seek = (dmci.insns_size & 0x1) == 0x1 ? 2 : 0;
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "DEBUG: code item %lu, registers 0x%x" fprintf(stderr, "DEBUG: code item %lu, registers 0x%x"
", size 0x%x, debug @0x%x, tries 0x%x" ", size 0x%x, debug @0x%x, tries 0x%x"
@ -298,21 +292,22 @@ static int _disas_map_code(FormatPlugin * format, off_t offset, size_t size,
dmci.insns_size * 2, dmci.debug_info_off, dmci.insns_size * 2, dmci.debug_info_off,
dmci.tries_size, seek); dmci.tries_size, seek);
#endif #endif
callback(format, NULL, ftello(fp), dmci.insns_size * 2, 0); if(seek != 0 && helper->seek(helper->format, seek, SEEK_CUR)
/* skip padding and try_items */ < 0)
if(seek != 0 && fseek(fp, seek, SEEK_CUR) != 0) return -1;
return -_dex_error(format);
if(dmci.tries_size > 0) if(dmci.tries_size > 0)
{ {
for(j = 0; j < dmci.tries_size; j++) for(j = 0; j < dmci.tries_size; j++)
{ {
if(fread(&dmti, sizeof(dmti), 1, fp) != 1) s = sizeof(dmti);
return -_dex_error_fread(format); if(helper->read(helper->format, &dmti, s) != s)
return -1;
dmti.start_addr = _htol32(dmti.start_addr); dmti.start_addr = _htol32(dmti.start_addr);
dmti.insn_count = _htol16(dmti.insn_count); dmti.insn_count = _htol16(dmti.insn_count);
dmti.handler_off = _htol16(dmti.handler_off); dmti.handler_off = _htol16(dmti.handler_off);
} }
callback(format, NULL, ftello(fp), 8, 0); seek = helper->seek(helper->format, 0, SEEK_CUR);
helper->disas(helper->format, NULL, seek, 8, 0);
} }
} }
return 0; return 0;
@ -321,21 +316,23 @@ static int _disas_map_code(FormatPlugin * format, off_t offset, size_t size,
static int _disas_map_string_id(FormatPlugin * format, off_t offset, static int _disas_map_string_id(FormatPlugin * format, off_t offset,
size_t size) size_t size)
{ {
FILE * fp = format->helper->fp; FormatPluginHelper * helper = format->helper;
Dex * dex = format->priv; Dex * dex = format->priv;
size_t i; size_t i;
DexStringIdItem dsii; DexStringIdItem dsii;
ssize_t s;
if(dex->strings_cnt != 0) if(dex->strings_cnt != 0)
return -error_set_code(1, "%s: %s", "dex", return -error_set_code(1, "%s: %s", "dex",
"String section already parsed"); "String section already parsed");
if(fseek(fp, offset, SEEK_SET) != 0) if(helper->seek(helper->format, offset, SEEK_SET) != offset)
return -_dex_error(format); return -1;
if((dex->strings = malloc(sizeof(*dex->strings) * size)) == NULL) if((dex->strings = malloc(sizeof(*dex->strings) * size)) == NULL)
return -_dex_error(format); return -_dex_error(format);
for(i = 0; i < size; i++) for(i = 0; i < size; i++)
{ {
if(fread(&dsii, sizeof(dsii), 1, fp) != 1) s = sizeof(dsii);
if(helper->read(helper->format, &dsii, s) != s)
break; break;
dsii.string_data_off = _htol32(dsii.string_data_off); dsii.string_data_off = _htol32(dsii.string_data_off);
#ifdef DEBUG #ifdef DEBUG
@ -349,7 +346,7 @@ static int _disas_map_string_id(FormatPlugin * format, off_t offset,
{ {
free(dex->strings); free(dex->strings);
dex->strings = NULL; dex->strings = NULL;
return -_dex_error_fread(format); return -1;
} }
dex->strings_cnt = size; dex->strings_cnt = size;
return 0; return 0;
@ -359,16 +356,8 @@ static int _disas_map_string_id(FormatPlugin * format, off_t offset,
/* dex_error */ /* dex_error */
static int _dex_error(FormatPlugin * format) static int _dex_error(FormatPlugin * format)
{ {
return -error_set_code(1, "%s: %s", format->helper->filename, FormatPluginHelper * helper = format->helper;
strerror(errno));
}
return -error_set_code(1, "%s: %s",
/* dex_error_fread */ helper->get_filename(helper->format), strerror(errno));
static int _dex_error_fread(FormatPlugin * format)
{
if(ferror(format->helper->fp))
return _dex_error(format);
return -error_set_code(1, "%s: %s", format->helper->filename,
"End of file reached");
} }

View File

@ -56,18 +56,14 @@ typedef struct _ElfStrtab
/* prototypes */ /* prototypes */
static int _elf_error(FormatPlugin * format);
/* plug-in */ /* plug-in */
static int _elf_init(FormatPlugin * format, char const * arch); static int _elf_init(FormatPlugin * format, char const * arch);
static char const * _elf_detect(FormatPlugin * format); static char const * _elf_detect(FormatPlugin * format);
static int _elf_disas(FormatPlugin * format, int (*callback)( static int _elf_disas(FormatPlugin * format);
FormatPlugin * format, char const * section, static int _elf_disas32(FormatPlugin * format);
off_t offset, size_t size, off_t base)); static int _elf_disas64(FormatPlugin * format);
static int _elf_disas32(FormatPlugin * format, int (*callback)(
FormatPlugin * format, char const * section,
off_t offset, size_t size, off_t base));
static int _elf_disas64(FormatPlugin * format, int (*callback)(
FormatPlugin * format, char const * section,
off_t offset, size_t size, off_t base));
/* ELF32 */ /* ELF32 */
static int _init_32(FormatPlugin * format); static int _init_32(FormatPlugin * format);
@ -152,8 +148,8 @@ FormatPlugin format_plugin =
/* elf_error */ /* elf_error */
static int _elf_error(FormatPlugin * format) static int _elf_error(FormatPlugin * format)
{ {
return -error_set_code(1, "%s: %s", format->helper->filename, return -error_set_code(1, "%s: %s", format->helper->get_filename(
strerror(errno)); format->helper->format), strerror(errno));
} }
@ -196,22 +192,22 @@ static ElfArch * _init_arch(char const * arch)
/* elf_detect */ /* elf_detect */
static char const * _detect_error(FormatPlugin * format);
static char const * _detect_32(FormatPlugin * format, Elf32_Ehdr * ehdr); static char const * _detect_32(FormatPlugin * format, Elf32_Ehdr * ehdr);
static char const * _detect_64(FormatPlugin * format, Elf64_Ehdr * ehdr); static char const * _detect_64(FormatPlugin * format, Elf64_Ehdr * ehdr);
static char const * _elf_detect(FormatPlugin * format) static char const * _elf_detect(FormatPlugin * format)
{ {
FormatPluginHelper * helper = format->helper;
union union
{ {
Elf32_Ehdr ehdr32; Elf32_Ehdr ehdr32;
Elf64_Ehdr ehdr64; Elf64_Ehdr ehdr64;
} ehdr; } ehdr;
if(fseek(format->helper->fp, 0, SEEK_SET) != 0) if(helper->seek(helper->format, 0, SEEK_SET) != 0)
return _detect_error(format); return NULL;
if(fread(&ehdr, sizeof(ehdr), 1, format->helper->fp) != 1) if(helper->read(helper->format, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
return _detect_error(format); return NULL;
switch(ehdr.ehdr32.e_ident[EI_CLASS]) switch(ehdr.ehdr32.e_ident[EI_CLASS])
{ {
case ELFCLASS32: case ELFCLASS32:
@ -219,17 +215,11 @@ static char const * _elf_detect(FormatPlugin * format)
case ELFCLASS64: case ELFCLASS64:
return _detect_64(format, &ehdr.ehdr64); return _detect_64(format, &ehdr.ehdr64);
} }
error_set_code(1, "%s: %s 0x%x\n", format->helper->filename, error_set_code(1, "%s: %s 0x%x\n", helper->get_filename(helper->format),
"Unsupported ELF class", ehdr.ehdr32.e_ident[EI_CLASS]); "Unsupported ELF class", ehdr.ehdr32.e_ident[EI_CLASS]);
return NULL; return NULL;
} }
static char const * _detect_error(FormatPlugin * format)
{
error_set_code(1, "%s: %s", format->helper->filename, strerror(errno));
return NULL;
}
static char const * _detect_32(FormatPlugin * format, Elf32_Ehdr * ehdr) static char const * _detect_32(FormatPlugin * format, Elf32_Ehdr * ehdr)
{ {
format->disas = _elf_disas32; format->disas = _elf_disas32;
@ -272,13 +262,11 @@ static char const * _detect_64(FormatPlugin * format, Elf64_Ehdr * ehdr)
/* elf_disas */ /* elf_disas */
static int _elf_disas(FormatPlugin * format, int (*callback)( static int _elf_disas(FormatPlugin * format)
FormatPlugin * format, char const * section,
off_t offset, size_t size, off_t base))
{ {
if(_elf_detect(format) == NULL) if(_elf_detect(format) == NULL)
return -1; return -1;
return format->disas(format, callback); return format->disas(format);
} }
@ -291,10 +279,9 @@ static int _disas32_strtab(FormatPlugin * format, Elf32_Shdr * shdr,
size_t shdr_cnt, uint16_t ndx, char ** strtab, size_t shdr_cnt, uint16_t ndx, char ** strtab,
size_t * strtab_cnt); size_t * strtab_cnt);
static int _elf_disas32(FormatPlugin * format, int (*callback)( static int _elf_disas32(FormatPlugin * format)
FormatPlugin * format, char const * section,
off_t offset, size_t size, off_t base))
{ {
FormatPluginHelper * helper = format->helper;
Elf32_Ehdr ehdr; Elf32_Ehdr ehdr;
Elf32_Shdr * shdr = NULL; Elf32_Shdr * shdr = NULL;
Elf32_Addr base = 0x0; Elf32_Addr base = 0x0;
@ -306,10 +293,10 @@ static int _elf_disas32(FormatPlugin * format, int (*callback)(
fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__, fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__,
format->helper->filename); format->helper->filename);
#endif #endif
if(fseek(format->helper->fp, 0, SEEK_SET) != 0 if(helper->seek(helper->format, 0, SEEK_SET) != 0
|| fread(&ehdr, sizeof(ehdr), 1, format->helper->fp) || helper->read(helper->format, &ehdr, sizeof(ehdr))
!= 1) != sizeof(ehdr))
return -_elf_error(format); return -1;
if(_disas32_shdr(format, &ehdr, &shdr) != 0) if(_disas32_shdr(format, &ehdr, &shdr) != 0)
return -1; return -1;
if(_disas32_addr(format, &ehdr, &base) != 0 if(_disas32_addr(format, &ehdr, &base) != 0
@ -326,7 +313,8 @@ static int _elf_disas32(FormatPlugin * format, int (*callback)(
continue; continue;
if(shdr[i].sh_type == SHT_PROGBITS if(shdr[i].sh_type == SHT_PROGBITS
&& shdr[i].sh_flags & SHF_EXECINSTR) && shdr[i].sh_flags & SHF_EXECINSTR)
callback(format, &shstrtab[shdr[i].sh_name], helper->disas(helper->format,
&shstrtab[shdr[i].sh_name],
shdr[i].sh_offset, shdr[i].sh_size, shdr[i].sh_offset, shdr[i].sh_size,
base); base);
} }
@ -338,24 +326,27 @@ static int _elf_disas32(FormatPlugin * format, int (*callback)(
static int _disas32_shdr(FormatPlugin * format, Elf32_Ehdr * ehdr, static int _disas32_shdr(FormatPlugin * format, Elf32_Ehdr * ehdr,
Elf32_Shdr ** shdr) Elf32_Shdr ** shdr)
{ {
FormatPluginHelper * helper = format->helper;
ssize_t size;
if(ehdr->e_shentsize == 0) if(ehdr->e_shentsize == 0)
{ {
*shdr = NULL; *shdr = NULL;
return 0; return 0;
} }
if(ehdr->e_shentsize != sizeof(**shdr)) if(ehdr->e_shentsize != sizeof(**shdr))
return -error_set_code(1, "%s: %s", format->helper->filename, return -error_set_code(1, "%s: %s",
helper->get_filename(helper->format),
"Invalid section header size"); "Invalid section header size");
if(fseek(format->helper->fp, ehdr->e_shoff, SEEK_SET) != 0 if(helper->seek(helper->format, ehdr->e_shoff, SEEK_SET) < 0)
|| (*shdr = malloc(ehdr->e_shentsize * ehdr->e_shnum)) return -1;
== NULL) size = sizeof(**shdr) * ehdr->e_shnum;
if((*shdr = malloc(size)) == NULL)
return -_elf_error(format); return -_elf_error(format);
if(fread(*shdr, sizeof(**shdr), ehdr->e_shnum, format->helper->fp) if(helper->read(helper->format, *shdr, size) != size)
!= ehdr->e_shnum)
{ {
free(*shdr); free(*shdr);
return -error_set_code(1, "%s: %s", format->helper->filename, return -1;
"Short read");
} }
return 0; return 0;
} }
@ -363,14 +354,16 @@ static int _disas32_shdr(FormatPlugin * format, Elf32_Ehdr * ehdr,
static int _disas32_addr(FormatPlugin * format, Elf32_Ehdr * ehdr, static int _disas32_addr(FormatPlugin * format, Elf32_Ehdr * ehdr,
Elf32_Addr * addr) Elf32_Addr * addr)
{ {
FormatPluginHelper * helper = format->helper;
Elf32_Half i; Elf32_Half i;
Elf32_Phdr phdr; Elf32_Phdr phdr;
if(fseek(format->helper->fp, ehdr->e_phoff, SEEK_SET) != 0) if(helper->seek(helper->format, ehdr->e_phoff, SEEK_SET) < 0)
return -_elf_error(format); return -1;
for(i = 0; i < ehdr->e_phnum; i++) for(i = 0; i < ehdr->e_phnum; i++)
if(fread(&phdr, sizeof(phdr), 1, format->helper->fp) != 1) if(helper->read(helper->format, &phdr, sizeof(phdr))
return -_elf_error(format); != sizeof(phdr))
return -1;
else if(phdr.p_type == PT_LOAD && phdr.p_flags & (PF_R | PF_X)) else if(phdr.p_type == PT_LOAD && phdr.p_flags & (PF_R | PF_X))
{ {
*addr = phdr.p_vaddr; *addr = phdr.p_vaddr;
@ -384,19 +377,22 @@ static int _disas32_strtab(FormatPlugin * format, Elf32_Shdr * shdr,
size_t shdr_cnt, uint16_t ndx, char ** strtab, size_t shdr_cnt, uint16_t ndx, char ** strtab,
size_t * strtab_cnt) size_t * strtab_cnt)
{ {
FormatPluginHelper * helper = format->helper;
if(ndx >= shdr_cnt) if(ndx >= shdr_cnt)
return -error_set_code(1, "%s: %s", format->helper->filename, return -error_set_code(1, "%s: %s",
helper->get_filename(helper->format),
"Unable to read the string table"); "Unable to read the string table");
shdr = &shdr[ndx]; shdr = &shdr[ndx];
if(fseek(format->helper->fp, shdr->sh_offset, SEEK_SET) != 0 if(helper->seek(helper->format, shdr->sh_offset, SEEK_SET) < 0)
|| (*strtab = malloc(shdr->sh_size)) == NULL) return -1;
if((*strtab = malloc(shdr->sh_size)) == NULL)
return -_elf_error(format); return -_elf_error(format);
if(fread(*strtab, sizeof(**strtab), shdr->sh_size, format->helper->fp) if(helper->read(helper->format, *strtab, shdr->sh_size)
!= shdr->sh_size) != shdr->sh_size)
{ {
free(*strtab); free(*strtab);
return -error_set_code(1, "%s: %s", format->helper->filename, return -1;
"Short read");
} }
*strtab_cnt = shdr->sh_size; *strtab_cnt = shdr->sh_size;
return 0; return 0;
@ -412,10 +408,9 @@ static int _disas64_strtab(FormatPlugin * format, Elf64_Shdr * shdr,
size_t shdr_cnt, uint16_t ndx, char ** strtab, size_t shdr_cnt, uint16_t ndx, char ** strtab,
size_t * strtab_cnt); size_t * strtab_cnt);
static int _elf_disas64(FormatPlugin * format, int (*callback)( static int _elf_disas64(FormatPlugin * format)
FormatPlugin * format, char const * section,
off_t offset, size_t size, off_t base))
{ {
FormatPluginHelper * helper = format->helper;
Elf64_Ehdr ehdr; Elf64_Ehdr ehdr;
Elf64_Shdr * shdr = NULL; Elf64_Shdr * shdr = NULL;
Elf64_Addr base = 0x0; Elf64_Addr base = 0x0;
@ -425,12 +420,12 @@ static int _elf_disas64(FormatPlugin * format, int (*callback)(
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__, fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__,
format->helper->filename); helper->get_filename(helper->format));
#endif #endif
if(fseek(format->helper->fp, 0, SEEK_SET) != 0 if(helper->seek(helper->format, 0, SEEK_SET) != 0
|| fread(&ehdr, sizeof(ehdr), 1, format->helper->fp) || helper->read(helper->format, &ehdr, sizeof(ehdr))
!= 1) != sizeof(ehdr))
return -_elf_error(format); return -1;
if(_disas64_shdr(format, &ehdr, &shdr) != 0) if(_disas64_shdr(format, &ehdr, &shdr) != 0)
return -1; return -1;
if(_disas64_addr(format, &ehdr, &base) != 0 if(_disas64_addr(format, &ehdr, &base) != 0
@ -447,7 +442,8 @@ static int _elf_disas64(FormatPlugin * format, int (*callback)(
continue; continue;
if(shdr[i].sh_type == SHT_PROGBITS if(shdr[i].sh_type == SHT_PROGBITS
&& shdr[i].sh_flags & SHF_EXECINSTR) && shdr[i].sh_flags & SHF_EXECINSTR)
callback(format, &shstrtab[shdr[i].sh_name], helper->disas(helper->format,
&shstrtab[shdr[i].sh_name],
shdr[i].sh_offset, shdr[i].sh_size, shdr[i].sh_offset, shdr[i].sh_size,
base); base);
} }
@ -459,24 +455,27 @@ static int _elf_disas64(FormatPlugin * format, int (*callback)(
static int _disas64_shdr(FormatPlugin * format, Elf64_Ehdr * ehdr, static int _disas64_shdr(FormatPlugin * format, Elf64_Ehdr * ehdr,
Elf64_Shdr ** shdr) Elf64_Shdr ** shdr)
{ {
FormatPluginHelper * helper = format->helper;
ssize_t size;
if(ehdr->e_shentsize == 0) if(ehdr->e_shentsize == 0)
{ {
*shdr = NULL; *shdr = NULL;
return 0; return 0;
} }
if(ehdr->e_shentsize != sizeof(**shdr)) if(ehdr->e_shentsize != sizeof(**shdr))
return -error_set_code(1, "%s: %s", format->helper->filename, return -error_set_code(1, "%s: %s",
helper->get_filename(helper->format),
"Invalid section header size"); "Invalid section header size");
if(fseek(format->helper->fp, ehdr->e_shoff, SEEK_SET) != 0 if(helper->seek(helper->format, ehdr->e_shoff, SEEK_SET) < 0)
|| (*shdr = malloc(ehdr->e_shentsize * ehdr->e_shnum)) return -1;
== NULL) size = sizeof(**shdr) * ehdr->e_shnum;
if((*shdr = malloc(size)) == NULL)
return -_elf_error(format); return -_elf_error(format);
if(fread(*shdr, sizeof(**shdr), ehdr->e_shnum, format->helper->fp) if(helper->read(helper->format, *shdr, size) != size)
!= ehdr->e_shnum)
{ {
free(*shdr); free(*shdr);
return -error_set_code(1, "%s: %s", format->helper->filename, return -1;
"Short read");
} }
return 0; return 0;
} }
@ -484,14 +483,16 @@ static int _disas64_shdr(FormatPlugin * format, Elf64_Ehdr * ehdr,
static int _disas64_addr(FormatPlugin * format, Elf64_Ehdr * ehdr, static int _disas64_addr(FormatPlugin * format, Elf64_Ehdr * ehdr,
Elf64_Addr * addr) Elf64_Addr * addr)
{ {
FormatPluginHelper * helper = format->helper;
Elf64_Quarter i; Elf64_Quarter i;
Elf64_Phdr phdr; Elf64_Phdr phdr;
if(fseek(format->helper->fp, ehdr->e_phoff, SEEK_SET) != 0) if(helper->seek(helper->format, ehdr->e_phoff, SEEK_SET) < 0)
return -_elf_error(format); return -1;
for(i = 0; i < ehdr->e_phnum; i++) for(i = 0; i < ehdr->e_phnum; i++)
if(fread(&phdr, sizeof(phdr), 1, format->helper->fp) != 1) if(helper->read(helper->format, &phdr, sizeof(phdr))
return -_elf_error(format); != sizeof(phdr))
return -1;
else if(phdr.p_type == PT_LOAD && phdr.p_flags & (PF_R | PF_X)) else if(phdr.p_type == PT_LOAD && phdr.p_flags & (PF_R | PF_X))
{ {
*addr = phdr.p_vaddr; *addr = phdr.p_vaddr;
@ -505,19 +506,23 @@ static int _disas64_strtab(FormatPlugin * format, Elf64_Shdr * shdr,
size_t shdr_cnt, uint16_t ndx, char ** strtab, size_t shdr_cnt, uint16_t ndx, char ** strtab,
size_t * strtab_cnt) size_t * strtab_cnt)
{ {
FormatPluginHelper * helper = format->helper;
ssize_t size;
if(ndx >= shdr_cnt) if(ndx >= shdr_cnt)
return -error_set_code(1, "%s: %s", format->helper->filename, return -error_set_code(1, "%s: %s",
helper->get_filename(helper->format),
"Unable to read the string table"); "Unable to read the string table");
shdr = &shdr[ndx]; shdr = &shdr[ndx];
if(fseek(format->helper->fp, shdr->sh_offset, SEEK_SET) != 0 if(helper->seek(helper->format, shdr->sh_offset, SEEK_SET) < 0)
|| (*strtab = malloc(shdr->sh_size)) == NULL) return -1;
size = sizeof(**strtab) * shdr->sh_size;
if((*strtab = malloc(size)) == NULL)
return -_elf_error(format); return -_elf_error(format);
if(fread(*strtab, sizeof(**strtab), shdr->sh_size, format->helper->fp) if(helper->read(helper->format, *strtab, size) != size)
!= shdr->sh_size)
{ {
free(*strtab); free(*strtab);
return -error_set_code(1, "%s: %s", format->helper->filename, return -1;
"Short read");
} }
*strtab_cnt = shdr->sh_size; *strtab_cnt = shdr->sh_size;
return 0; return 0;
@ -549,6 +554,7 @@ static int es32_cnt = 0;
/* init_32 */ /* init_32 */
static int _init_32(FormatPlugin * format) static int _init_32(FormatPlugin * format)
{ {
FormatPluginHelper * helper = format->helper;
Elf32_Ehdr hdr; Elf32_Ehdr hdr;
memset(&hdr, 0, sizeof(hdr)); memset(&hdr, 0, sizeof(hdr));
@ -574,7 +580,7 @@ static int _init_32(FormatPlugin * format)
hdr.e_shentsize = _htol16(sizeof(Elf32_Shdr)); hdr.e_shentsize = _htol16(sizeof(Elf32_Shdr));
hdr.e_shstrndx = _htol16(SHN_UNDEF); hdr.e_shstrndx = _htol16(SHN_UNDEF);
} }
if(fwrite(&hdr, sizeof(hdr), 1, format->helper->fp) != 1) if(helper->write(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr))
return _elf_error(format); return _elf_error(format);
return 0; return 0;
} }
@ -587,18 +593,19 @@ static int _exit_32_shdr(FormatPlugin * format, Elf32_Off offset);
static int _exit_32(FormatPlugin * format) static int _exit_32(FormatPlugin * format)
{ {
int ret = 0; int ret = 0;
FormatPluginHelper * helper = format->helper;
long offset; long offset;
if(_section_32(format, ".shstrtab") != 0) if(_section_32(format, ".shstrtab") != 0)
ret = 1; ret = -1;
else if(fwrite(shstrtab.buf, sizeof(char), shstrtab.cnt, else if(helper->write(helper->format, shstrtab.buf, shstrtab.cnt)
format->helper->fp) != shstrtab.cnt) != (ssize_t)shstrtab.cnt)
ret = _elf_error(format); ret = -1;
else if((offset = ftell(format->helper->fp)) == -1) else if((offset = helper->seek(helper->format, 0, SEEK_CUR)) < 0)
ret = _elf_error(format); ret = -1;
else if(_exit_32_phdr(format, offset) != 0 else if(_exit_32_phdr(format, offset) != 0
|| _exit_32_shdr(format, offset) != 0) || _exit_32_shdr(format, offset) != 0)
ret = 1; ret = -1;
free(es32); free(es32);
es32 = NULL; es32 = NULL;
es32_cnt = 0; es32_cnt = 0;
@ -610,13 +617,14 @@ static int _exit_32(FormatPlugin * format)
static int _exit_32_phdr(FormatPlugin * format, Elf32_Off offset) static int _exit_32_phdr(FormatPlugin * format, Elf32_Off offset)
{ {
FormatPluginHelper * helper = format->helper;
Elf32_Ehdr hdr; Elf32_Ehdr hdr;
if(es32_cnt == 0) if(es32_cnt == 0)
return 0; return 0;
if(fseek(format->helper->fp, 0, SEEK_SET) != 0) if(helper->seek(helper->format, 0, SEEK_SET) != 0)
return _elf_error(format); return -1;
if(fread(&hdr, sizeof(hdr), 1, format->helper->fp) != 1) if(helper->read(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr))
return _elf_error(format); return _elf_error(format);
if(ea->endian == ELFDATA2MSB) if(ea->endian == ELFDATA2MSB)
{ {
@ -630,19 +638,20 @@ static int _exit_32_phdr(FormatPlugin * format, Elf32_Off offset)
hdr.e_shnum = _htol16(es32_cnt + 1); hdr.e_shnum = _htol16(es32_cnt + 1);
hdr.e_shstrndx = _htol16(es32_cnt); hdr.e_shstrndx = _htol16(es32_cnt);
} }
if(fseek(format->helper->fp, 0, SEEK_SET) != 0) if(helper->seek(helper->format, 0, SEEK_SET) != 0)
return _elf_error(format); return -1;
if(fwrite(&hdr, sizeof(hdr), 1, format->helper->fp) != 1) if(helper->write(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr))
return _elf_error(format); return -1;
return 0; return 0;
} }
static int _exit_32_shdr(FormatPlugin * format, Elf32_Off offset) static int _exit_32_shdr(FormatPlugin * format, Elf32_Off offset)
{ {
FormatPluginHelper * helper = format->helper;
Elf32_Shdr hdr; Elf32_Shdr hdr;
int i; int i;
if(fseek(format->helper->fp, 0, SEEK_END) != 0) if(helper->seek(helper->format, 0, SEEK_END) < 0)
return _elf_error(format); return _elf_error(format);
memset(&hdr, 0, sizeof(hdr)); memset(&hdr, 0, sizeof(hdr));
if(ea->endian == ELFDATA2MSB) if(ea->endian == ELFDATA2MSB)
@ -655,8 +664,8 @@ static int _exit_32_shdr(FormatPlugin * format, Elf32_Off offset)
hdr.sh_type = _htol32(SHT_NULL); hdr.sh_type = _htol32(SHT_NULL);
hdr.sh_link = _htol32(SHN_UNDEF); hdr.sh_link = _htol32(SHN_UNDEF);
} }
if(fwrite(&hdr, sizeof(hdr), 1, format->helper->fp) != 1) if(helper->write(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr))
return _elf_error(format); return -1;
for(i = 0; i < es32_cnt; i++) for(i = 0; i < es32_cnt; i++)
{ {
if(i + 1 == es32_cnt) if(i + 1 == es32_cnt)
@ -666,9 +675,9 @@ static int _exit_32_shdr(FormatPlugin * format, Elf32_Off offset)
- es32[i].sh_offset; - es32[i].sh_offset;
es32[i].sh_size = ea->endian == ELFDATA2MSB es32[i].sh_size = ea->endian == ELFDATA2MSB
? _htob32(es32[i].sh_size) : _htol32(es32[i].sh_size); ? _htob32(es32[i].sh_size) : _htol32(es32[i].sh_size);
if(fwrite(&es32[i], sizeof(Elf32_Shdr), 1, format->helper->fp) if(helper->write(helper->format, &es32[i], sizeof(Elf32_Shdr))
!= 1) != sizeof(Elf32_Shdr))
return _elf_error(format); return -1;
} }
return 0; return 0;
} }
@ -677,13 +686,14 @@ static int _exit_32_shdr(FormatPlugin * format, Elf32_Off offset)
/* section_32 */ /* section_32 */
static int _section_32(FormatPlugin * format, char const * name) static int _section_32(FormatPlugin * format, char const * name)
{ {
FormatPluginHelper * helper = format->helper;
int ss; int ss;
Elf32_Shdr * p; Elf32_Shdr * p;
ElfSectionValues * esv; ElfSectionValues * esv;
long offset; long offset;
if((ss = _elfstrtab_set(format, &shstrtab, name)) < 0) if((ss = _elfstrtab_set(format, &shstrtab, name)) < 0)
return 1; return -1;
if((p = realloc(es32, sizeof(*es32) * (es32_cnt + 1))) == NULL) if((p = realloc(es32, sizeof(*es32) * (es32_cnt + 1))) == NULL)
return _elf_error(format); return _elf_error(format);
es32 = p; es32 = p;
@ -693,8 +703,8 @@ static int _section_32(FormatPlugin * format, char const * name)
p->sh_name = ss; p->sh_name = ss;
p->sh_type = esv->type; p->sh_type = esv->type;
p->sh_flags = esv->flags; p->sh_flags = esv->flags;
if((offset = ftell(format->helper->fp)) == -1) if((offset = helper->seek(helper->format, 0, SEEK_CUR)) < 0)
return _elf_error(format); return -1;
p->sh_offset = offset; p->sh_offset = offset;
p->sh_link = SHN_UNDEF; /* FIXME */ p->sh_link = SHN_UNDEF; /* FIXME */
return 0; return 0;
@ -710,6 +720,7 @@ static int es64_cnt = 0;
/* init_64 */ /* init_64 */
static int _init_64(FormatPlugin * format) static int _init_64(FormatPlugin * format)
{ {
FormatPluginHelper * helper = format->helper;
Elf64_Ehdr hdr; Elf64_Ehdr hdr;
memset(&hdr, 0, sizeof(hdr)); memset(&hdr, 0, sizeof(hdr));
@ -734,8 +745,8 @@ static int _init_64(FormatPlugin * format)
hdr.e_shentsize = _htol16(sizeof(Elf64_Shdr)); hdr.e_shentsize = _htol16(sizeof(Elf64_Shdr));
} }
hdr.e_shstrndx = SHN_UNDEF; hdr.e_shstrndx = SHN_UNDEF;
if(fwrite(&hdr, sizeof(hdr), 1, format->helper->fp) != 1) if(helper->write(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr))
return _elf_error(format); return -1;
return 0; return 0;
} }
@ -747,15 +758,16 @@ static int _exit_64_shdr(FormatPlugin * format, Elf64_Off offset);
static int _exit_64(FormatPlugin * format) static int _exit_64(FormatPlugin * format)
{ {
int ret = 0; int ret = 0;
FormatPluginHelper * helper = format->helper;
long offset; long offset;
if(_section_64(format, ".shstrtab") != 0) if(_section_64(format, ".shstrtab") != 0)
ret = 1; ret = 1;
else if(fwrite(shstrtab.buf, sizeof(char), shstrtab.cnt, else if(helper->write(helper->format, shstrtab.buf, shstrtab.cnt)
format->helper->fp) != shstrtab.cnt) != (ssize_t)shstrtab.cnt)
ret = _elf_error(format); ret = -1;
else if((offset = ftell(format->helper->fp)) == -1) else if((offset = helper->seek(helper->format, 0, SEEK_CUR)) < 0)
ret = _elf_error(format); ret = -1;
else if(_exit_64_phdr(format, offset) != 0 else if(_exit_64_phdr(format, offset) != 0
|| _exit_64_shdr(format, offset) != 0) || _exit_64_shdr(format, offset) != 0)
ret = 1; ret = 1;
@ -770,14 +782,15 @@ static int _exit_64(FormatPlugin * format)
static int _exit_64_phdr(FormatPlugin * format, Elf64_Off offset) static int _exit_64_phdr(FormatPlugin * format, Elf64_Off offset)
{ {
FormatPluginHelper * helper = format->helper;
Elf64_Ehdr hdr; Elf64_Ehdr hdr;
if(es64_cnt == 0) if(es64_cnt == 0)
return 0; return 0;
if(fseek(format->helper->fp, 0, SEEK_SET) != 0) if(helper->seek(helper->format, 0, SEEK_SET) != 0)
return _elf_error(format); return -1;
if(fread(&hdr, sizeof(hdr), 1, format->helper->fp) != 1) if(helper->read(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr))
return _elf_error(format); return -1;
if(ea->endian == ELFDATA2MSB) if(ea->endian == ELFDATA2MSB)
{ {
hdr.e_shoff = _htob64(offset); hdr.e_shoff = _htob64(offset);
@ -790,19 +803,20 @@ static int _exit_64_phdr(FormatPlugin * format, Elf64_Off offset)
hdr.e_shnum = _htol16(es64_cnt); hdr.e_shnum = _htol16(es64_cnt);
hdr.e_shstrndx = _htol16(es64_cnt - 1); hdr.e_shstrndx = _htol16(es64_cnt - 1);
} }
if(fseek(format->helper->fp, 0, SEEK_SET) != 0) if(helper->seek(helper->format, 0, SEEK_SET) != 0)
return _elf_error(format); return -1;
if(fwrite(&hdr, sizeof(hdr), 1, format->helper->fp) != 1) if(helper->write(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr))
return _elf_error(format); return -1;
return 0; return 0;
} }
static int _exit_64_shdr(FormatPlugin * format, Elf64_Off offset) static int _exit_64_shdr(FormatPlugin * format, Elf64_Off offset)
{ {
FormatPluginHelper * helper = format->helper;
int i; int i;
if(fseek(format->helper->fp, 0, SEEK_END) != 0) if(helper->seek(helper->format, 0, SEEK_END) < 0)
return _elf_error(format); return -1;
for(i = 0; i < es64_cnt; i++) for(i = 0; i < es64_cnt; i++)
{ {
if(i + 1 == es64_cnt) if(i + 1 == es64_cnt)
@ -812,9 +826,9 @@ static int _exit_64_shdr(FormatPlugin * format, Elf64_Off offset)
- es64[i].sh_offset; - es64[i].sh_offset;
es64[i].sh_size = ea->endian == ELFDATA2MSB es64[i].sh_size = ea->endian == ELFDATA2MSB
? _htob64(es64[i].sh_size) : _htol64(es64[i].sh_size); ? _htob64(es64[i].sh_size) : _htol64(es64[i].sh_size);
if(fwrite(&es64[i], sizeof(Elf64_Shdr), 1, format->helper->fp) if(helper->write(helper->format, &es64[i], sizeof(Elf64_Shdr))
!= 1) != sizeof(Elf64_Shdr))
return _elf_error(format); return -1;
} }
return 0; return 0;
} }
@ -823,6 +837,7 @@ static int _exit_64_shdr(FormatPlugin * format, Elf64_Off offset)
/* section_64 */ /* section_64 */
static int _section_64(FormatPlugin * format, char const * name) static int _section_64(FormatPlugin * format, char const * name)
{ {
FormatPluginHelper * helper = format->helper;
int ss; int ss;
Elf64_Shdr * p; Elf64_Shdr * p;
ElfSectionValues * esv; ElfSectionValues * esv;
@ -839,8 +854,8 @@ static int _section_64(FormatPlugin * format, char const * name)
p->sh_name = ss; p->sh_name = ss;
p->sh_type = esv->type; p->sh_type = esv->type;
p->sh_flags = esv->flags; p->sh_flags = esv->flags;
if((offset = ftell(format->helper->fp)) == -1) if((offset = helper->seek(helper->format, 0, SEEK_CUR)) < 0)
return _elf_error(format); return -1;
p->sh_offset = offset; p->sh_offset = offset;
p->sh_link = SHN_UNDEF; /* FIXME */ p->sh_link = SHN_UNDEF; /* FIXME */
return 0; return 0;

View File

@ -16,9 +16,7 @@
#include <System.h> #include <System.h>
#include <sys/stat.h>
#include <string.h> #include <string.h>
#include <errno.h>
#include "Asm.h" #include "Asm.h"
@ -26,9 +24,7 @@
/* private */ /* private */
/* prototypes */ /* prototypes */
/* plug-in */ /* plug-in */
static int _flat_disas(FormatPlugin * format, int (*callback)( static int _flat_disas(FormatPlugin * format);
FormatPlugin * format, char const * section,
off_t offset, size_t size, off_t base));
/* public */ /* public */
@ -53,14 +49,12 @@ FormatPlugin format_plugin =
/* functions */ /* functions */
/* plug-in */ /* plug-in */
/* flat_disas */ /* flat_disas */
static int _flat_disas(FormatPlugin * format, int (*callback)( static int _flat_disas(FormatPlugin * format)
FormatPlugin * format, char const * section,
off_t offset, size_t size, off_t base))
{ {
struct stat st; FormatPluginHelper * helper = format->helper;
off_t offset;
if(fstat(fileno(format->helper->fp), &st) != 0) if((offset = helper->seek(helper->format, 0, SEEK_END)) < 0)
return -error_set_code(1, "%s: %s", format->helper->filename, return -1;
strerror(errno)); return helper->disas(helper->format, ".data", 0, offset, 0);
return callback(format, ".data", 0, st.st_size, 0);
} }

View File

@ -105,12 +105,9 @@ static char _java_signature[4] = "\xca\xfe\xba\xbe";
static int _java_init(FormatPlugin * format, char const * arch); static int _java_init(FormatPlugin * format, char const * arch);
static int _java_exit(FormatPlugin * format); static int _java_exit(FormatPlugin * format);
static char const * _java_detect(FormatPlugin * format); static char const * _java_detect(FormatPlugin * format);
static int _java_disas(FormatPlugin * format, int (*callback)( static int _java_disas(FormatPlugin * format);
FormatPlugin * format, char const * section,
off_t offset, size_t size, off_t base));
static int _java_error(FormatPlugin * format); static int _java_error(FormatPlugin * format);
static int _java_error_fread(FormatPlugin * format);
/* public */ /* public */
@ -137,6 +134,7 @@ FormatPlugin format_plugin =
/* java_init */ /* java_init */
static int _java_init(FormatPlugin * format, char const * arch) static int _java_init(FormatPlugin * format, char const * arch)
{ {
FormatPluginHelper * helper = format->helper;
JavaHeader jh; JavaHeader jh;
JavaPlugin * java; JavaPlugin * java;
@ -147,8 +145,8 @@ static int _java_init(FormatPlugin * format, char const * arch)
jh.minor = _htob16(0); jh.minor = _htob16(0);
jh.major = _htob16(0x32); /* XXX choose a more appropriate version */ jh.major = _htob16(0x32); /* XXX choose a more appropriate version */
jh.cp_cnt = _htob16(0); jh.cp_cnt = _htob16(0);
if(fwrite(&jh, sizeof(jh), 1, format->helper->fp) != 1) if(helper->write(helper->format, &jh, sizeof(jh)) != sizeof(jh))
return -_java_error(format); return -1;
if((java = malloc(sizeof(*java))) == NULL) if((java = malloc(sizeof(*java))) == NULL)
return -_java_error(format); return -_java_error(format);
memset(java, 0, sizeof(*java)); memset(java, 0, sizeof(*java));
@ -186,85 +184,96 @@ static int _java_exit(FormatPlugin * format)
static int _exit_constant_pool(FormatPlugin * format) static int _exit_constant_pool(FormatPlugin * format)
{ {
FormatPluginHelper * helper = format->helper;
JavaPlugin * java = format->priv; JavaPlugin * java = format->priv;
uint16_t cnt = _htob16(java->constants_cnt + 1); uint16_t cnt = _htob16(java->constants_cnt + 1);
if(fwrite(&cnt, sizeof(cnt), 1, format->helper->fp) != 1) if(helper->write(helper->format, &cnt, sizeof(cnt)) != sizeof(cnt))
return -_java_error(format); return -1;
/* XXX output the constants */ /* XXX output the constants */
return 0; return 0;
} }
static int _exit_access_flags(FormatPlugin * format) static int _exit_access_flags(FormatPlugin * format)
{ {
FormatPluginHelper * helper = format->helper;
JavaPlugin * java = format->priv; JavaPlugin * java = format->priv;
uint16_t flags = _htob16(java->access_flags); uint16_t flags = _htob16(java->access_flags);
if(fwrite(&flags, sizeof(flags), 1, format->helper->fp) != 1) if(helper->write(helper->format, &flags, sizeof(flags))
return -_java_error(format); != sizeof(flags))
return -1;
return 0; return 0;
} }
static int _exit_class_name(FormatPlugin * format) static int _exit_class_name(FormatPlugin * format)
{ {
FormatPluginHelper * helper = format->helper;
uint16_t index = _htob16(0); uint16_t index = _htob16(0);
/* FIXME really implement */ /* FIXME really implement */
if(fwrite(&index, sizeof(index), 1, format->helper->fp) != 1) if(helper->write(helper->format, &index, sizeof(index))
return -_java_error(format); != sizeof(index))
return -1;
return 0; return 0;
} }
static int _exit_super_name(FormatPlugin * format) static int _exit_super_name(FormatPlugin * format)
{ {
FormatPluginHelper * helper = format->helper;
uint16_t index = _htob16(0); uint16_t index = _htob16(0);
/* FIXME really implement */ /* FIXME really implement */
if(fwrite(&index, sizeof(index), 1, format->helper->fp) != 1) if(helper->write(helper->format, &index, sizeof(index))
return -_java_error(format); != sizeof(index))
return -1;
return 0; return 0;
} }
static int _exit_interface_table(FormatPlugin * format) static int _exit_interface_table(FormatPlugin * format)
{ {
FormatPluginHelper * helper = format->helper;
JavaPlugin * java = format->priv; JavaPlugin * java = format->priv;
uint16_t cnt = _htob16(java->interfaces_cnt); uint16_t cnt = _htob16(java->interfaces_cnt);
if(fwrite(&cnt, sizeof(cnt), 1, format->helper->fp) != 1) if(helper->write(helper->format, &cnt, sizeof(cnt)) != sizeof(cnt))
return -_java_error(format); return -1;
/* XXX output the interfaces */ /* XXX output the interfaces */
return 0; return 0;
} }
static int _exit_field_table(FormatPlugin * format) static int _exit_field_table(FormatPlugin * format)
{ {
FormatPluginHelper * helper = format->helper;
JavaPlugin * java = format->priv; JavaPlugin * java = format->priv;
uint16_t cnt = _htob16(java->fields_cnt); uint16_t cnt = _htob16(java->fields_cnt);
if(fwrite(&cnt, sizeof(cnt), 1, format->helper->fp) != 1) if(helper->write(helper->format, &cnt, sizeof(cnt)) != sizeof(cnt))
return -_java_error(format); return -1;
/* XXX output the fields */ /* XXX output the fields */
return 0; return 0;
} }
static int _exit_method_table(FormatPlugin * format) static int _exit_method_table(FormatPlugin * format)
{ {
FormatPluginHelper * helper = format->helper;
JavaPlugin * java = format->priv; JavaPlugin * java = format->priv;
uint16_t cnt = _htob16(java->methods_cnt); uint16_t cnt = _htob16(java->methods_cnt);
if(fwrite(&cnt, sizeof(cnt), 1, format->helper->fp) != 1) if(helper->write(helper->format, &cnt, sizeof(cnt)) != sizeof(cnt))
return -_java_error(format); return -1;
/* XXX output the methods */ /* XXX output the methods */
return 0; return 0;
} }
static int _exit_attribute_table(FormatPlugin * format) static int _exit_attribute_table(FormatPlugin * format)
{ {
FormatPluginHelper * helper = format->helper;
JavaPlugin * java = format->priv; JavaPlugin * java = format->priv;
uint16_t cnt = _htob16(java->attributes_cnt); uint16_t cnt = _htob16(java->attributes_cnt);
if(fwrite(&cnt, sizeof(cnt), 1, format->helper->fp) != 1) if(helper->write(helper->format, &cnt, sizeof(cnt)) != sizeof(cnt))
return -_java_error(format); return -1;
/* XXX output the attributes */ /* XXX output the attributes */
return 0; return 0;
} }
@ -283,48 +292,47 @@ static int _disas_skip_constants(FormatPlugin * format, uint16_t cnt);
static int _disas_skip_fields(FormatPlugin * format, uint16_t cnt); static int _disas_skip_fields(FormatPlugin * format, uint16_t cnt);
static int _disas_skip_interfaces(FormatPlugin * format, uint16_t cnt); static int _disas_skip_interfaces(FormatPlugin * format, uint16_t cnt);
static int _java_disas(FormatPlugin * format, int (*callback)( static int _java_disas(FormatPlugin * format)
FormatPlugin * format, char const * section,
off_t offset, size_t size, off_t base))
{ {
FILE * fp = format->helper->fp; FormatPluginHelper * helper = format->helper;
JavaHeader jh; JavaHeader jh;
JavaHeader2 jh2; JavaHeader2 jh2;
uint16_t u16; uint16_t u16;
off_t offset; off_t offset;
off_t end; off_t end;
if(fseek(fp, sizeof(JavaHeader), SEEK_SET) != 0) /* FIXME can this be correct? */
return -_java_error(format); if(helper->seek(helper->format, sizeof(jh), SEEK_SET) != sizeof(jh))
if(fread(&jh, sizeof(jh), 1, fp) != 1) return -1;
return -_java_error_fread(format); if(helper->read(helper->format, &jh, sizeof(jh)) != sizeof(jh))
return -1;
/* skip constants */ /* skip constants */
jh.cp_cnt = _htob16(jh.cp_cnt); jh.cp_cnt = _htob16(jh.cp_cnt);
if(jh.cp_cnt > 1 && _disas_skip_constants(format, jh.cp_cnt) != 0) if(jh.cp_cnt > 1 && _disas_skip_constants(format, jh.cp_cnt) != 0)
return -1; return -1;
/* skip interfaces */ /* skip interfaces */
if(fread(&jh2, sizeof(jh2), 1, fp) != 1) if(helper->read(helper->format, &jh2, sizeof(jh2)) != sizeof(jh2))
return -_java_error_fread(format); return -1;
jh2.interfaces_cnt = _htob16(jh2.interfaces_cnt); jh2.interfaces_cnt = _htob16(jh2.interfaces_cnt);
if(_disas_skip_interfaces(format, jh2.interfaces_cnt) != 0) if(_disas_skip_interfaces(format, jh2.interfaces_cnt) != 0)
return -1; return -1;
/* skip fields */ /* skip fields */
if(fread(&u16, sizeof(u16), 1, fp) != 1) if(helper->read(helper->format, &u16, sizeof(u16)) != sizeof(u16))
return -_java_error_fread(format); return -1;
u16 = _htob16(u16); u16 = _htob16(u16);
if(_disas_skip_fields(format, u16) != 0) if(_disas_skip_fields(format, u16) != 0)
return -1; return -1;
/* disassemble the rest */ /* disassemble the rest */
if((offset = ftello(fp)) == -1 if((offset = helper->seek(helper->format, 0, SEEK_CUR)) < 0
|| fseek(fp, 0, SEEK_END) != 0 || (end = helper->seek(helper->format, 0, SEEK_END))
|| (end = ftello(fp)) == -1) < 0)
return -_java_error(format); return -1;
return callback(format, NULL, offset, end - offset, 0); return helper->disas(helper->format, NULL, offset, end - offset, 0);
} }
static int _disas_skip_attributes(FormatPlugin * format, uint16_t cnt) static int _disas_skip_attributes(FormatPlugin * format, uint16_t cnt)
{ {
FILE * fp = format->helper->fp; FormatPluginHelper * helper = format->helper;
size_t i; size_t i;
JavaAttributeInfo jai; JavaAttributeInfo jai;
@ -333,22 +341,23 @@ static int _disas_skip_attributes(FormatPlugin * format, uint16_t cnt)
#endif #endif
for(i = 0; i < cnt; i++) for(i = 0; i < cnt; i++)
{ {
if(fread(&jai, sizeof(jai), 1, fp) != 1) if(helper->read(helper->format, &jai, sizeof(jai))
return -_java_error_fread(format); != sizeof(jai))
return -1;
jai.length = _htob32(jai.length); jai.length = _htob32(jai.length);
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "DEBUG: %s() length=%u\n", __func__, fprintf(stderr, "DEBUG: %s() length=%u\n", __func__,
jai.length); jai.length);
#endif #endif
if(fseek(fp, jai.length, SEEK_CUR) != 0) if(helper->seek(helper->format, jai.length, SEEK_CUR) < 0)
return -_java_error(format); return -1;
} }
return 0; return 0;
} }
static int _disas_skip_constants(FormatPlugin * format, uint16_t cnt) static int _disas_skip_constants(FormatPlugin * format, uint16_t cnt)
{ {
FILE * fp = format->helper->fp; FormatPluginHelper * helper = format->helper;
size_t i; size_t i;
JavaCpInfo jci; JavaCpInfo jci;
size_t size; size_t size;
@ -360,8 +369,9 @@ static int _disas_skip_constants(FormatPlugin * format, uint16_t cnt)
#endif #endif
for(i = 0; i < cnt; i++) for(i = 0; i < cnt; i++)
{ {
if(fread(&jci, sizeof(jci), 1, fp) != 1) if(helper->read(helper->format, &jci, sizeof(jci))
return -_java_error_fread(format); != sizeof(jci))
return -1;
switch(jci.tag) switch(jci.tag)
{ {
case CONSTANT_Double: case CONSTANT_Double:
@ -381,28 +391,33 @@ static int _disas_skip_constants(FormatPlugin * format, uint16_t cnt)
size = 2; size = 2;
break; break;
case CONSTANT_Utf8: case CONSTANT_Utf8:
if(fread(&u16, sizeof(u16), 1, fp) != 1) size = sizeof(u16);
return -_java_error_fread(format); if(helper->read(helper->format, &u16, size)
!= (ssize_t)size)
return -1;
u16 = _htob16(u16); u16 = _htob16(u16);
if(fseek(fp, u16, SEEK_CUR) != 0) if(helper->seek(helper->format, u16, SEEK_CUR)
return -_java_error(format); < 0)
return -1;
size = 0; size = 0;
break; break;
default: default:
return -error_set_code(1, "%s: %s 0x%x", return -error_set_code(1, "%s: %s 0x%x",
format->helper->filename, helper->get_filename(
helper->format),
"Unknown constant tag", "Unknown constant tag",
jci.tag); jci.tag);
} }
if(size != 0 && fread(buf, sizeof(*buf), size, fp) != size) if(size != 0 && helper->read(helper->format, buf, size)
return -_java_error_fread(format); != (ssize_t)size)
return -1;
} }
return 0; return 0;
} }
static int _disas_skip_fields(FormatPlugin * format, uint16_t cnt) static int _disas_skip_fields(FormatPlugin * format, uint16_t cnt)
{ {
FILE * fp = format->helper->fp; FormatPluginHelper * helper = format->helper;
size_t i; size_t i;
JavaFieldInfo jfi; JavaFieldInfo jfi;
@ -411,8 +426,9 @@ static int _disas_skip_fields(FormatPlugin * format, uint16_t cnt)
#endif #endif
for(i = 0; i < cnt; i++) for(i = 0; i < cnt; i++)
{ {
if(fread(&jfi, sizeof(jfi), 1, fp) != 1) if(helper->read(helper->format, &jfi, sizeof(jfi))
return -_java_error_fread(format); != sizeof(jfi))
return -1;
jfi.attributes_cnt = _htob16(jfi.attributes_cnt); jfi.attributes_cnt = _htob16(jfi.attributes_cnt);
_disas_skip_attributes(format, jfi.attributes_cnt); _disas_skip_attributes(format, jfi.attributes_cnt);
} }
@ -421,7 +437,7 @@ static int _disas_skip_fields(FormatPlugin * format, uint16_t cnt)
static int _disas_skip_interfaces(FormatPlugin * format, uint16_t cnt) static int _disas_skip_interfaces(FormatPlugin * format, uint16_t cnt)
{ {
FILE * fp = format->helper->fp; FormatPluginHelper * helper = format->helper;
size_t i; size_t i;
uint16_t u16; uint16_t u16;
@ -429,8 +445,9 @@ static int _disas_skip_interfaces(FormatPlugin * format, uint16_t cnt)
fprintf(stderr, "DEBUG: %s(%u)\n", __func__, cnt); fprintf(stderr, "DEBUG: %s(%u)\n", __func__, cnt);
#endif #endif
for(i = 0; i < cnt; i++) for(i = 0; i < cnt; i++)
if(fread(&u16, sizeof(u16), 1, fp) != 1) if(helper->read(helper->format, &u16, sizeof(u16))
return -_java_error_fread(format); != sizeof(u16))
return -1;
return 0; return 0;
} }
@ -438,16 +455,6 @@ static int _disas_skip_interfaces(FormatPlugin * format, uint16_t cnt)
/* java_error */ /* java_error */
static int _java_error(FormatPlugin * format) static int _java_error(FormatPlugin * format)
{ {
return -error_set_code(1, "%s: %s", format->helper->filename, return -error_set_code(1, "%s: %s", format->helper->get_filename(
strerror(errno)); format->helper->format), strerror(errno));
}
/* java_error_fread */
static int _java_error_fread(FormatPlugin * format)
{
if(ferror(format->helper->fp))
return _java_error(format);
return -error_set_code(1, "%s: %s", format->helper->filename,
"End of file reached");
} }

View File

@ -89,9 +89,7 @@ static char const _pe_header_signature[4] = "PE\0\0";
/* plug-in */ /* plug-in */
static int _pe_init(FormatPlugin * format, char const * arch); static int _pe_init(FormatPlugin * format, char const * arch);
static char const * _pe_detect(FormatPlugin * format); static char const * _pe_detect(FormatPlugin * format);
static int _pe_disas(FormatPlugin * format, int (*callback)( static int _pe_disas(FormatPlugin * format);
FormatPlugin * format, char const * section,
off_t offset, size_t size, off_t base));
/* useful */ /* useful */
static char const * _pe_get_arch(uint16_t machine); static char const * _pe_get_arch(uint16_t machine);
@ -121,6 +119,7 @@ FormatPlugin format_plugin =
/* pe_init */ /* pe_init */
static int _pe_init(FormatPlugin * format, char const * arch) static int _pe_init(FormatPlugin * format, char const * arch)
{ {
FormatPluginHelper * helper = format->helper;
int machine; int machine;
struct pe_msdos pm; struct pe_msdos pm;
struct pe_header ph; struct pe_header ph;
@ -135,12 +134,10 @@ static int _pe_init(FormatPlugin * format, char const * arch)
ph.machine = _htol16(machine); ph.machine = _htol16(machine);
ph.timestamp = _htol32(time(NULL)); ph.timestamp = _htol32(time(NULL));
/* FIXME update the section and symbol lists */ /* FIXME update the section and symbol lists */
if(fwrite(&pm, sizeof(pm), 1, format->helper->fp) != 1) if(helper->write(helper->format, &pm, sizeof(pm)) != sizeof(pm))
return -error_set_code(1, "%s: %s", format->helper->filename, return -1;
strerror(errno)); if(helper->write(helper->format, &ph, sizeof(ph)) != sizeof(ph))
if(fwrite(&ph, sizeof(ph), 1, format->helper->fp) != 1) return -1;
return -error_set_code(1, "%s: %s", format->helper->filename,
strerror(errno));
return 0; return 0;
} }
@ -150,25 +147,28 @@ static char const * _detect_error(FormatPlugin * format);
static char const * _pe_detect(FormatPlugin * format) static char const * _pe_detect(FormatPlugin * format)
{ {
FormatPluginHelper * helper = format->helper;
struct pe_msdos pm; struct pe_msdos pm;
struct pe_header ph; struct pe_header ph;
if(fseek(format->helper->fp, 0, SEEK_SET) != 0) if(helper->seek(helper->format, 0, SEEK_SET) != 0)
return _detect_error(format); return NULL;
if(fread(&pm, sizeof(pm), 1, format->helper->fp) != 1) if(helper->read(helper->format, &pm, sizeof(pm)) != sizeof(pm))
return _detect_error(format); return NULL;
if((pm.offset = _htol16(pm.offset)) != sizeof(pm) if((pm.offset = _htol16(pm.offset)) != sizeof(pm))
&& fseek(format->helper->fp, pm.offset, SEEK_SET) != 0)
return _detect_error(format);
if(fread(&ph, sizeof(ph), 1, format->helper->fp) != 1)
return _detect_error(format); return _detect_error(format);
if(helper->seek(helper->format, pm.offset, SEEK_SET) != pm.offset)
return NULL;
if(helper->read(helper->format, &ph, sizeof(ph)) != sizeof(ph))
return NULL;
ph.machine = _htol16(ph.machine); ph.machine = _htol16(ph.machine);
return _pe_get_arch(ph.machine); return _pe_get_arch(ph.machine);
} }
static char const * _detect_error(FormatPlugin * format) static char const * _detect_error(FormatPlugin * format)
{ {
error_set_code(1, "%s: %s", format->helper->filename, strerror(errno)); error_set_code(1, "%s: %s", format->helper->get_filename(
format->helper->format), strerror(errno));
return NULL; return NULL;
} }
@ -176,47 +176,49 @@ static char const * _detect_error(FormatPlugin * format)
/* pe_disas */ /* pe_disas */
static int _disas_error(FormatPlugin * format); static int _disas_error(FormatPlugin * format);
static int _pe_disas(FormatPlugin * format, int (*callback)( static int _pe_disas(FormatPlugin * format)
FormatPlugin * format, char const * section,
off_t offset, size_t size, off_t base))
{ {
FormatPluginHelper * helper = format->helper;
struct pe_msdos pm; struct pe_msdos pm;
struct pe_header ph; struct pe_header ph;
size_t i; size_t i;
struct pe_section_header psh; struct pe_section_header psh;
if(fseek(format->helper->fp, 0, SEEK_SET) != 0) if(helper->seek(helper->format, 0, SEEK_SET) != 0)
return _disas_error(format); return -1;
if(fread(&pm, sizeof(pm), 1, format->helper->fp) != 1) if(helper->read(helper->format, &pm, sizeof(pm)) != sizeof(pm))
return _disas_error(format); return -1;
if((pm.offset = _htol16(pm.offset)) != sizeof(pm) if((pm.offset = _htol16(pm.offset)) != sizeof(pm)
&& fseek(format->helper->fp, pm.offset, SEEK_SET) != 0) && helper->seek(helper->format, pm.offset, SEEK_SET)
return _disas_error(format); != pm.offset)
if(fread(&ph, sizeof(ph), 1, format->helper->fp) != 1) return -1;
if(helper->read(helper->format, &ph, sizeof(ph)) != sizeof(ph))
return _disas_error(format); return _disas_error(format);
ph.section_cnt = _htol16(ph.section_cnt); ph.section_cnt = _htol16(ph.section_cnt);
ph.opthdr_size = _htol16(ph.opthdr_size); ph.opthdr_size = _htol16(ph.opthdr_size);
if(ph.section_cnt > 0 && ph.opthdr_size != 0 if(ph.section_cnt > 0 && ph.opthdr_size != 0
&& fseek(format->helper->fp, ph.opthdr_size, SEEK_CUR)) && helper->seek(helper->format, ph.opthdr_size,
SEEK_CUR) < 0)
return _disas_error(format); return _disas_error(format);
for(i = 0; i < ph.section_cnt; i++) for(i = 0; i < ph.section_cnt; i++)
{ {
if(fread(&psh, sizeof(psh), 1, format->helper->fp) != 1) if(helper->read(helper->format, &psh, sizeof(psh))
return _disas_error(format); != sizeof(psh))
return -1;
psh.name[sizeof(psh.name) - 1] = '\0'; psh.name[sizeof(psh.name) - 1] = '\0';
psh.vaddr = _htol32(psh.vaddr); psh.vaddr = _htol32(psh.vaddr);
psh.raw_size = _htol32(psh.raw_size); psh.raw_size = _htol32(psh.raw_size);
psh.raw_offset = _htol32(psh.raw_offset); psh.raw_offset = _htol32(psh.raw_offset);
callback(format, psh.name, psh.raw_offset, psh.raw_size, helper->disas(helper->format, psh.name, psh.raw_offset,
psh.vaddr); psh.raw_size, psh.vaddr);
} }
return 0; return 0;
} }
static int _disas_error(FormatPlugin * format) static int _disas_error(FormatPlugin * format)
{ {
return -error_set_code(1, "%s: %s", format->helper->filename, return -error_set_code(1, "%s: %s", format->helper->get_filename(
strerror(errno)); format->helper->format), strerror(errno));
} }