Major re-design to facilitate code re-use from the library

This commit is contained in:
Pierre Pronchery 2011-11-27 21:02:46 +00:00
parent a5423dbc95
commit 389f82aef4
54 changed files with 1362 additions and 617 deletions

View File

@ -33,6 +33,7 @@ dist:
$(PACKAGE)-$(VERSION)/include/project.conf \
$(PACKAGE)-$(VERSION)/include/Asm/arch.h \
$(PACKAGE)-$(VERSION)/include/Asm/asm.h \
$(PACKAGE)-$(VERSION)/include/Asm/code.h \
$(PACKAGE)-$(VERSION)/include/Asm/common.h \
$(PACKAGE)-$(VERSION)/include/Asm/format.h \
$(PACKAGE)-$(VERSION)/include/Asm/Makefile \
@ -55,6 +56,8 @@ dist:
$(PACKAGE)-$(VERSION)/src/project.conf \
$(PACKAGE)-$(VERSION)/src/arch/amd64.c \
$(PACKAGE)-$(VERSION)/src/arch/arm.c \
$(PACKAGE)-$(VERSION)/src/arch/armeb.c \
$(PACKAGE)-$(VERSION)/src/arch/armel.c \
$(PACKAGE)-$(VERSION)/src/arch/dalvik.c \
$(PACKAGE)-$(VERSION)/src/arch/i386.c \
$(PACKAGE)-$(VERSION)/src/arch/i386_real.c \
@ -63,6 +66,8 @@ dist:
$(PACKAGE)-$(VERSION)/src/arch/i686.c \
$(PACKAGE)-$(VERSION)/src/arch/java.c \
$(PACKAGE)-$(VERSION)/src/arch/mips.c \
$(PACKAGE)-$(VERSION)/src/arch/mipseb.c \
$(PACKAGE)-$(VERSION)/src/arch/mipsel.c \
$(PACKAGE)-$(VERSION)/src/arch/sparc.c \
$(PACKAGE)-$(VERSION)/src/arch/sparc64.c \
$(PACKAGE)-$(VERSION)/src/arch/yasep.c \
@ -101,6 +106,8 @@ dist:
$(PACKAGE)-$(VERSION)/src/format/project.conf \
$(PACKAGE)-$(VERSION)/test/amd64.S \
$(PACKAGE)-$(VERSION)/test/arm.S \
$(PACKAGE)-$(VERSION)/test/armeb.S \
$(PACKAGE)-$(VERSION)/test/armel.S \
$(PACKAGE)-$(VERSION)/test/dalvik.S \
$(PACKAGE)-$(VERSION)/test/i386.S \
$(PACKAGE)-$(VERSION)/test/i386_real.S \
@ -108,6 +115,8 @@ dist:
$(PACKAGE)-$(VERSION)/test/i586.S \
$(PACKAGE)-$(VERSION)/test/i686.S \
$(PACKAGE)-$(VERSION)/test/mips.S \
$(PACKAGE)-$(VERSION)/test/mipseb.S \
$(PACKAGE)-$(VERSION)/test/mipsel.S \
$(PACKAGE)-$(VERSION)/test/java.S \
$(PACKAGE)-$(VERSION)/test/sparc.S \
$(PACKAGE)-$(VERSION)/test/sparc64.S \

View File

@ -27,9 +27,9 @@
# define _LITTLE_ENDIAN __LITTLE_ENDIAN
# endif
# include "Asm/common.h"
# include "Asm/arch.h"
# include "Asm/asm.h"
# include "Asm/code.h"
# include "Asm/format.h"
@ -70,5 +70,4 @@
# warning "Could not determine endian on your system"
# endif
#endif /* !DEVEL_ASM_H */

View File

@ -19,6 +19,8 @@ install:
$(MKDIR) $(DESTDIR)$(PREFIX)/include/Devel/Asm
$(INSTALL) -m 0644 -- asm.h $(DESTDIR)$(PREFIX)/include/Devel/Asm/asm.h
$(MKDIR) $(DESTDIR)$(PREFIX)/include/Devel/Asm
$(INSTALL) -m 0644 -- code.h $(DESTDIR)$(PREFIX)/include/Devel/Asm/code.h
$(MKDIR) $(DESTDIR)$(PREFIX)/include/Devel/Asm
$(INSTALL) -m 0644 -- common.h $(DESTDIR)$(PREFIX)/include/Devel/Asm/common.h
$(MKDIR) $(DESTDIR)$(PREFIX)/include/Devel/Asm
$(INSTALL) -m 0644 -- format.h $(DESTDIR)$(PREFIX)/include/Devel/Asm/format.h
@ -26,6 +28,7 @@ install:
uninstall:
$(RM) -- $(DESTDIR)$(PREFIX)/include/Devel/Asm/arch.h
$(RM) -- $(DESTDIR)$(PREFIX)/include/Devel/Asm/asm.h
$(RM) -- $(DESTDIR)$(PREFIX)/include/Devel/Asm/code.h
$(RM) -- $(DESTDIR)$(PREFIX)/include/Devel/Asm/common.h
$(RM) -- $(DESTDIR)$(PREFIX)/include/Devel/Asm/format.h

View File

@ -20,7 +20,7 @@
# include <sys/types.h>
# include <stdint.h>
# include "asm.h"
# include "common.h"
/* AsmArch */
@ -198,14 +198,14 @@ typedef struct _ArchPluginHelper
/* callbacks */
/* accessors */
char const * (*get_filename)(Arch * arch);
AsmFunction * (*get_function_by_id)(Arch * arch, AsmId id);
AsmFunction * (*get_function_by_id)(Arch * arch, AsmFunctionId id);
ArchInstruction * (*get_instruction_by_opcode)(Arch * arch,
uint8_t size, uint32_t opcode);
ArchRegister * (*get_register_by_id_size)(Arch * arch, uint32_t id,
uint32_t size);
ArchRegister * (*get_register_by_name_size)(Arch * arch,
char const * name, uint32_t size);
AsmString * (*get_string_by_id)(Arch * arch, AsmId id);
AsmString * (*get_string_by_id)(Arch * arch, AsmStringId id);
/* assembly */
ssize_t (*write)(Arch * arch, void const * buf, size_t size);
@ -230,7 +230,7 @@ struct _ArchPlugin
int (*init)(ArchPlugin * arch);
void (*exit)(ArchPlugin * arch);
int (*write)(ArchPlugin * arch, ArchInstruction * instruction,
int (*encode)(ArchPlugin * arch, ArchInstruction * instruction,
ArchInstructionCall * call);
int (*decode)(ArchPlugin * arch, ArchInstructionCall * call);
};

View File

@ -18,7 +18,7 @@
#ifndef DEVEL_ASM_ASM_H
# define DEVEL_ASM_ASM_H
# include "common.h"
# include "code.h"
/* Asm */
@ -47,24 +47,6 @@ int asm_set_arch(Asm * a, char const * arch);
char const * asm_get_format(Asm * a);
int asm_set_format(Asm * a, char const * format);
/* functions */
AsmFunction * asm_get_function_by_name(Asm * a, char const * name);
int asm_set_function(Asm * a, char const * name, off_t offset, ssize_t size);
/* labels */
AsmLabel * asm_get_label_by_name(Asm * a, char const * label);
AsmLabel * asm_get_label_by_offset(Asm * a, off_t offset);
int asm_set_label(Asm * a, char const * label, off_t offset);
/* sections */
int asm_set_section(Asm * a, char const * name, off_t offset, ssize_t size);
/* strings */
AsmString * asm_get_string_by_id(Asm * a, AsmId id);
AsmString * asm_get_string_by_name(Asm * a, char const * name);
int asm_set_string(Asm * a, int id, char const * name, off_t offset,
ssize_t length);
/* useful */
/* detection */
@ -84,10 +66,11 @@ int asm_open_assemble(Asm * a, char const * outfile);
int asm_instruction(Asm * a, char const * name, unsigned int operands_cnt, ...);
/* deassemble */
int asm_deassemble(Asm * a, char const * buffer, size_t size);
int asm_open_deassemble(Asm * a, char const * filename, int raw);
AsmCode * asm_deassemble(Asm * a, char const * buffer, size_t size,
ArchInstructionCall ** calls, size_t * calls_cnt);
AsmCode * asm_open_deassemble(Asm * a, char const * filename, int raw);
/* plug-in helpers */
int asm_plugin_list(AsmPluginType type);
int asm_plugin_list(AsmPluginType type, int decode);
#endif /* !DEVEL_ASM_AS_H */
#endif /* !DEVEL_ASM_COMMON_H */

76
include/Asm/code.h Normal file
View File

@ -0,0 +1,76 @@
/* $Id$ */
/* Copyright (c) 2011 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Devel asm */
/* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef DEVEL_ASM_CODE_H
# define DEVEL_ASM_CODE_H
# include <sys/types.h>
# include "common.h"
# include "arch.h"
/* AsmCode */
/* types */
typedef struct _AsmCode AsmCode;
/* functions */
/* accessors */
char const * asmcode_get_arch(AsmCode * code);
ArchDescription * asmcode_get_arch_description(AsmCode * code);
char const * asmcode_get_filename(AsmCode * code);
char const * asmcode_get_format(AsmCode * code);
int asmcode_set_function(AsmCode * code, int id, char const * name,
off_t offset, ssize_t size);
int asmcode_set_section(AsmCode * code, int id, char const * name, off_t offset,
ssize_t size, off_t base);
int asmcode_set_string(AsmCode * code, int id, char const * name, off_t offset,
ssize_t length);
/* functions */
AsmFunction * asmcode_get_function_by_id(AsmCode * code, AsmFunctionId id);
void asmcode_get_functions(AsmCode * code, AsmFunction ** functions,
size_t * functions_cnt);
/* sections */
AsmSection * asmcode_get_section_by_id(AsmCode * code, AsmSectionId id);
AsmSection * asmcode_get_section_by_name(AsmCode * code, char const * name);
void asmcode_get_sections(AsmCode * code, AsmSection ** sections,
size_t * sections_cnt);
/* strings */
AsmString * asmcode_get_string_by_id(AsmCode * code, AsmStringId id);
/* useful */
/* assembly */
int asmcode_function(AsmCode * code, char const * function);
int asmcode_instruction(AsmCode * code, ArchInstructionCall * call);
int asmcode_section(AsmCode * code, char const * section);
/* deassembly */
int asmcode_decode(AsmCode * code, int raw);
int asmcode_decode_at(AsmCode * code, off_t offset, size_t size, off_t base,
ArchInstructionCall ** calls, size_t * calls_cnt);
int asmcode_decode_buffer(AsmCode * code, char const * buffer, size_t size,
ArchInstructionCall ** calls, size_t * calls_cnt);
int asmcode_decode_section(AsmCode * code, AsmSection * section,
ArchInstructionCall ** calls, size_t * calls_cnt);
int asmcode_print(AsmCode * code, ArchInstructionCall * call);
#endif /* !DEVEL_ASM_CODE_H */

View File

@ -23,28 +23,37 @@
/* common */
/* types */
typedef unsigned int AsmId;
typedef int AsmElementId;
typedef struct _AsmFunction
typedef struct _AsmElement
{
AsmId id;
char const * name;
AsmElementId id;
char * name;
off_t offset;
ssize_t size;
} AsmFunction;
off_t base;
} AsmElement;
typedef struct _AsmLabel
typedef enum _AsmElementType
{
char const * name;
off_t offset;
} AsmLabel;
AET_FUNCTION,
AET_LABEL,
AET_SECTION,
AET_STRING
} AsmElementType;
# define AET_LAST AET_STRING
# define AET_COUNT (AET_LAST + 1)
typedef struct _AsmString
{
int id;
char const * name;
off_t offset;
ssize_t length;
} AsmString;
typedef AsmElementId AsmFunctionId;
typedef struct _AsmElement AsmFunction;
#endif /* !DEVEL_ASM_AS_H */
typedef AsmElementId AsmLabelId;
typedef struct _AsmElement AsmLabel;
typedef AsmElementId AsmSectionId;
typedef struct _AsmElement AsmSection;
typedef AsmElementId AsmStringId;
typedef struct _AsmElement AsmString;
#endif /* !DEVEL_ASM_COMMON_H */

View File

@ -35,6 +35,8 @@ typedef struct _FormatPluginHelper
/* callbacks */
/* accessors */
char const * (*get_filename)(Format * format);
void (*get_functions)(Format * format, AsmFunction ** functions,
size_t * functions_cnt);
/* useful */
ssize_t (*read)(Format * format, void * buf, size_t size);
@ -44,14 +46,17 @@ typedef struct _FormatPluginHelper
ssize_t (*write)(Format * format, void const * buf, size_t size);
/* disassembly */
/* FIXME let a different architecture be specified in the callback */
AsmString * (*get_string_by_id)(Format * format, AsmId id);
/* FIXME let a different architecture be specified in the callback? */
AsmSection * (*get_section_by_id)(Format * format, AsmSectionId id);
AsmString * (*get_string_by_id)(Format * format, AsmStringId id);
int (*set_function)(Format * format, int id, char const * name,
off_t offset, ssize_t size);
int (*set_section)(Format * format, int id, char const * name,
off_t offset, ssize_t size, off_t base);
int (*set_string)(Format * format, int id, char const * name,
off_t offset, ssize_t size);
int (*decode)(Format * format, char const * section,
off_t offset, size_t size, off_t base);
int (*decode)(Format * format, off_t offset, size_t size, off_t base,
ArchInstructionCall ** calls, size_t * calls_cnt);
} FormatPluginHelper;
struct _FormatPlugin
@ -70,6 +75,8 @@ struct _FormatPlugin
char const * (*detect)(FormatPlugin * format);
int (*decode)(FormatPlugin * format, int raw);
int (*decode_section)(FormatPlugin * format, AsmSection * section,
ArchInstructionCall ** calls, size_t * calls_cnt);
void * priv;
};

View File

@ -1,4 +1,4 @@
includes=arch.h,asm.h,common.h,format.h
includes=arch.h,asm.h,code.h,common.h,format.h
dist=Makefile
[arch.h]
@ -7,6 +7,9 @@ install=$(PREFIX)/include/Devel/Asm
[asm.h]
install=$(PREFIX)/include/Devel/Asm
[code.h]
install=$(PREFIX)/include/Devel/Asm
[common.h]
install=$(PREFIX)/include/Devel/Asm

View File

@ -46,7 +46,7 @@ struct _Arch
size_t registers_cnt;
/* internal */
Code * code;
AsmCode * code;
off_t base;
char const * filename;
FILE * fp;
@ -59,8 +59,8 @@ struct _Arch
/* prototypes */
/* callbacks */
static char const * _arch_get_filename(Arch * arch);
static AsmFunction * _arch_get_function_by_id(Arch * arch, AsmId id);
static AsmString * _arch_get_string_by_id(Arch * arch, AsmId id);
static AsmFunction * _arch_get_function_by_id(Arch * arch, AsmFunctionId id);
static AsmString * _arch_get_string_by_id(Arch * arch, AsmStringId id);
static ssize_t _arch_peek(Arch * arch, void * buf, size_t size);
static ssize_t _arch_read(Arch * arch, void * buf, size_t size);
static ssize_t _arch_peek_buffer(Arch * arch, void * buf, size_t size);
@ -127,6 +127,13 @@ void arch_delete(Arch * arch)
/* accessors */
/* arch_can_decode */
int arch_can_decode(Arch * arch)
{
return arch->plugin->decode != NULL;
}
/* arch_get_description */
ArchDescription * arch_get_description(Arch * arch)
{
@ -445,15 +452,18 @@ ArchRegister * arch_get_register_by_name_size(Arch * arch, char const * name,
/* useful */
/* arch_decode */
int arch_decode(Arch * arch, Code * code, ArchInstructionCall ** calls,
size_t * calls_cnt, off_t base)
int arch_decode(Arch * arch, AsmCode * code, off_t base,
ArchInstructionCall ** calls, size_t * calls_cnt)
{
int ret = 0;
ArchInstructionCall * c = NULL;
size_t c_cnt = 0;
ArchInstructionCall * c = *calls;
size_t c_cnt = *calls_cnt;
ArchInstructionCall * p;
size_t offset = 0;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s(%ld)\n", __func__, base);
#endif
if(arch->plugin->decode == NULL)
return -error_set_code(1, "%s: %s", arch->plugin->name,
"Disassembly not supported");
@ -477,22 +487,23 @@ int arch_decode(Arch * arch, Code * code, ArchInstructionCall ** calls,
offset += p->size;
c_cnt++;
}
if(ret == 0)
{
*calls = c;
*calls_cnt = c_cnt;
}
arch->code = NULL;
return ret;
}
/* arch_decode_at */
int arch_decode_at(Arch * arch, Code * code, ArchInstructionCall ** calls,
size_t * calls_cnt, off_t offset, size_t size, off_t base)
int arch_decode_at(Arch * arch, AsmCode * code, off_t offset, size_t size,
off_t base, ArchInstructionCall ** calls, size_t * calls_cnt)
{
int ret;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s(%ld, %lu, %ld)\n", __func__, offset, size,
base);
#endif
/* FIXME this only works for files */
if(arch->fp == NULL)
return -error_set_code(1, "%s", strerror(ENOSYS));
@ -503,7 +514,7 @@ int arch_decode_at(Arch * arch, Code * code, ArchInstructionCall ** calls,
arch->code = code;
arch->buffer_pos = offset;
arch->buffer_cnt = offset + size;
if((ret = arch_decode(arch, code, calls, calls_cnt, base)) == 0
if((ret = arch_decode(arch, code, base, calls, calls_cnt)) == 0
&& fseek(arch->fp, offset + size, SEEK_SET) != 0)
{
free(*calls); /* XXX the pointer was updated anyway... */
@ -513,6 +524,17 @@ int arch_decode_at(Arch * arch, Code * code, ArchInstructionCall ** calls,
}
/* arch_encode */
int arch_encode(Arch * arch, ArchInstruction * instruction,
ArchInstructionCall * call)
{
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, instruction->name);
#endif
return arch->plugin->encode(arch->plugin, instruction, call);
}
/* arch_exit */
int arch_exit(Arch * arch)
{
@ -613,17 +635,6 @@ off_t arch_seek(Arch * arch, off_t offset, int whence)
}
/* arch_write */
int arch_write(Arch * arch, ArchInstruction * instruction,
ArchInstructionCall * call)
{
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, instruction->name);
#endif
return arch->plugin->write(arch->plugin, instruction, call);
}
/* private */
/* callbacks */
/* arch_get_filename */
@ -634,16 +645,16 @@ static char const * _arch_get_filename(Arch * arch)
/* arch_get_function_by_id */
static AsmFunction * _arch_get_function_by_id(Arch * arch, AsmId id)
static AsmFunction * _arch_get_function_by_id(Arch * arch, AsmFunctionId id)
{
return code_get_function_by_id(arch->code, id);
return asmcode_get_function_by_id(arch->code, id);
}
/* arch_get_string_by_id */
static AsmString * _arch_get_string_by_id(Arch * arch, AsmId id)
static AsmString * _arch_get_string_by_id(Arch * arch, AsmStringId id)
{
return code_get_string_by_id(arch->code, id);
return asmcode_get_string_by_id(arch->code, id);
}
@ -653,7 +664,7 @@ static ssize_t _arch_peek(Arch * arch, void * buf, size_t size)
ssize_t s;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s(arch, %p, %zu)\n", __func__, buf, size);
fprintf(stderr, "DEBUG: %s(arch, %p, %lu)\n", __func__, buf, size);
#endif
if((s = _arch_read(arch, buf, size)) == -1)
return -1;
@ -729,6 +740,9 @@ static off_t _arch_seek(Arch * arch, off_t offset, int whence)
/* arch_seek_buffer */
static off_t _arch_seek_buffer(Arch * arch, off_t offset, int whence)
{
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s(arch, %ld, %d)\n", __func__, offset, whence);
#endif
if(whence == SEEK_SET)
{
if(offset < 0 || (size_t)offset >= arch->buffer_cnt)

View File

@ -32,6 +32,8 @@ void arch_delete(Arch * arch);
/* accessors */
int arch_can_decode(Arch * arch);
ArchDescription * arch_get_description(Arch * arch);
char const * arch_get_format(Arch * arch);
char const * arch_get_name(Arch * arch);
@ -56,14 +58,14 @@ int arch_init_buffer(Arch * arch, char const * buffer, size_t size);
int arch_exit(Arch * arch);
/* assembly */
int arch_write(Arch * arch, ArchInstruction * instruction,
int arch_encode(Arch * arch, ArchInstruction * instruction,
ArchInstructionCall * call);
/* disassembly */
int arch_decode(Arch * arch, Code * code, ArchInstructionCall ** calls,
size_t * calls_cnt, off_t base);
int arch_decode_at(Arch * arch, Code * code, ArchInstructionCall ** calls,
size_t * calls_cnt, off_t offset, size_t size, off_t base);
/* deassembly */
int arch_decode(Arch * arch, AsmCode * code, off_t base,
ArchInstructionCall ** calls, size_t * calls_cnt);
int arch_decode_at(Arch * arch, AsmCode * code, off_t offset, size_t size,
off_t base, ArchInstructionCall ** calls, size_t * calls_cnt);
ssize_t arch_read(Arch * arch, void * buf, size_t cnt);
off_t arch_seek(Arch * arch, off_t offset, int whence);

View File

@ -1,4 +1,4 @@
TARGETS = amd64.so arm.so dalvik.so i386.so i386_real.so i486.so i586.so i686.so java.so mips.so sparc.so sparc64.so yasep.so
TARGETS = amd64.so arm.so armeb.so armel.so dalvik.so i386.so i386_real.so i486.so i586.so i686.so java.so mips.so mipseb.so mipsel.so sparc.so sparc64.so yasep.so
PREFIX = /usr/local
DESTDIR =
LIBDIR = $(PREFIX)/lib
@ -32,6 +32,20 @@ arm_LDFLAGS = $(LDFLAGSF) $(LDFLAGS)
arm.so: $(arm_OBJS)
$(CCSHARED) -o arm.so $(arm_OBJS) $(arm_LDFLAGS)
armeb_OBJS = armeb.o
armeb_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS)
armeb_LDFLAGS = $(LDFLAGSF) $(LDFLAGS)
armeb.so: $(armeb_OBJS)
$(CCSHARED) -o armeb.so $(armeb_OBJS) $(armeb_LDFLAGS)
armel_OBJS = armel.o
armel_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS)
armel_LDFLAGS = $(LDFLAGSF) $(LDFLAGS)
armel.so: $(armel_OBJS)
$(CCSHARED) -o armel.so $(armel_OBJS) $(armel_LDFLAGS)
dalvik_OBJS = dalvik.o
dalvik_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS)
dalvik_LDFLAGS = $(LDFLAGSF) $(LDFLAGS)
@ -88,6 +102,20 @@ mips_LDFLAGS = $(LDFLAGSF) $(LDFLAGS)
mips.so: $(mips_OBJS)
$(CCSHARED) -o mips.so $(mips_OBJS) $(mips_LDFLAGS)
mipseb_OBJS = mipseb.o
mipseb_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS)
mipseb_LDFLAGS = $(LDFLAGSF) $(LDFLAGS)
mipseb.so: $(mipseb_OBJS)
$(CCSHARED) -o mipseb.so $(mipseb_OBJS) $(mipseb_LDFLAGS)
mipsel_OBJS = mipsel.o
mipsel_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS)
mipsel_LDFLAGS = $(LDFLAGSF) $(LDFLAGS)
mipsel.so: $(mipsel_OBJS)
$(CCSHARED) -o mipsel.so $(mipsel_OBJS) $(mipsel_LDFLAGS)
sparc_OBJS = sparc.o
sparc_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS)
sparc_LDFLAGS = $(LDFLAGSF) $(LDFLAGS)
@ -115,6 +143,12 @@ amd64.o: amd64.c amd64.ins amd64.reg common.ins null.ins i386.h i386.ins i386.re
arm.o: arm.c arm.h arm.ins arm.reg common.ins null.ins
$(CC) $(arm_CFLAGS) -c arm.c
armeb.o: armeb.c arm.o
$(CC) $(armeb_CFLAGS) -c armeb.c
armel.o: armel.c arm.o
$(CC) $(armel_CFLAGS) -c armel.c
dalvik.o: dalvik.c common.ins null.ins dalvik.ins dalvik.reg
$(CC) $(dalvik_CFLAGS) -c dalvik.c
@ -139,6 +173,12 @@ java.o: java.c common.ins null.ins
mips.o: mips.c common.ins null.ins mips.h mips.ins mips.reg
$(CC) $(mips_CFLAGS) -c mips.c
mipseb.o: mipseb.c mips.o
$(CC) $(mipseb_CFLAGS) -c mipseb.c
mipsel.o: mipsel.c mips.o
$(CC) $(mipsel_CFLAGS) -c mipsel.c
sparc.o: sparc.c common.ins null.ins sparc.h sparc.ins sparc.reg
$(CC) $(sparc_CFLAGS) -c sparc.c
@ -149,7 +189,7 @@ yasep.o: yasep.c common.ins null.ins yasep.ins yasep.reg
$(CC) $(yasep_CFLAGS) -c yasep.c
clean:
$(RM) -- $(amd64_OBJS) $(arm_OBJS) $(dalvik_OBJS) $(i386_OBJS) $(i386_real_OBJS) $(i486_OBJS) $(i586_OBJS) $(i686_OBJS) $(java_OBJS) $(mips_OBJS) $(sparc_OBJS) $(sparc64_OBJS) $(yasep_OBJS)
$(RM) -- $(amd64_OBJS) $(arm_OBJS) $(armeb_OBJS) $(armel_OBJS) $(dalvik_OBJS) $(i386_OBJS) $(i386_real_OBJS) $(i486_OBJS) $(i586_OBJS) $(i686_OBJS) $(java_OBJS) $(mips_OBJS) $(mipseb_OBJS) $(mipsel_OBJS) $(sparc_OBJS) $(sparc64_OBJS) $(yasep_OBJS)
distclean: clean
$(RM) -- $(TARGETS)
@ -160,6 +200,10 @@ install: $(TARGETS)
$(MKDIR) $(DESTDIR)$(LIBDIR)/asm/arch
$(INSTALL) -m 0644 -- arm.so $(DESTDIR)$(LIBDIR)/asm/arch/arm.so
$(MKDIR) $(DESTDIR)$(LIBDIR)/asm/arch
$(INSTALL) -m 0644 -- armeb.so $(DESTDIR)$(LIBDIR)/asm/arch/armeb.so
$(MKDIR) $(DESTDIR)$(LIBDIR)/asm/arch
$(INSTALL) -m 0644 -- armel.so $(DESTDIR)$(LIBDIR)/asm/arch/armel.so
$(MKDIR) $(DESTDIR)$(LIBDIR)/asm/arch
$(INSTALL) -m 0644 -- dalvik.so $(DESTDIR)$(LIBDIR)/asm/arch/dalvik.so
$(MKDIR) $(DESTDIR)$(LIBDIR)/asm/arch
$(INSTALL) -m 0644 -- i386.so $(DESTDIR)$(LIBDIR)/asm/arch/i386.so
@ -176,6 +220,10 @@ install: $(TARGETS)
$(MKDIR) $(DESTDIR)$(LIBDIR)/asm/arch
$(INSTALL) -m 0644 -- mips.so $(DESTDIR)$(LIBDIR)/asm/arch/mips.so
$(MKDIR) $(DESTDIR)$(LIBDIR)/asm/arch
$(INSTALL) -m 0644 -- mipseb.so $(DESTDIR)$(LIBDIR)/asm/arch/mipseb.so
$(MKDIR) $(DESTDIR)$(LIBDIR)/asm/arch
$(INSTALL) -m 0644 -- mipsel.so $(DESTDIR)$(LIBDIR)/asm/arch/mipsel.so
$(MKDIR) $(DESTDIR)$(LIBDIR)/asm/arch
$(INSTALL) -m 0644 -- sparc.so $(DESTDIR)$(LIBDIR)/asm/arch/sparc.so
$(MKDIR) $(DESTDIR)$(LIBDIR)/asm/arch
$(INSTALL) -m 0644 -- sparc64.so $(DESTDIR)$(LIBDIR)/asm/arch/sparc64.so
@ -185,6 +233,8 @@ install: $(TARGETS)
uninstall:
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/amd64.so
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/arm.so
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/armeb.so
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/armel.so
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/dalvik.so
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/i386.so
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/i386_real.so
@ -193,6 +243,8 @@ uninstall:
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/i686.so
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/java.so
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/mips.so
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/mipseb.so
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/mipsel.so
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/sparc.so
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/sparc64.so
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/yasep.so

View File

@ -88,6 +88,6 @@ ArchPlugin arch_plugin =
_amd64_instructions,
NULL,
NULL,
_i386_write,
_i386_encode,
_i386_decode
};

View File

@ -19,6 +19,12 @@
#include "Asm.h"
/* constants */
#ifndef ARCH_ENDIAN
# define ARCH_ENDIAN ARCH_ENDIAN_BOTH
#endif
/* arm */
/* private */
/* types */
@ -35,7 +41,7 @@ enum
/* variables */
static ArchDescription _arm_description =
{
"elf", ARCH_ENDIAN_BOTH, 32, 32, 32
"elf", ARCH_ENDIAN, 32, 32, 32
};
#define REG(name, size, id) { "" # name, size, id },
@ -70,6 +76,6 @@ ArchPlugin arch_plugin =
_arm_instructions,
NULL,
NULL,
_arm_write,
_arm_encode,
NULL
};

View File

@ -22,14 +22,14 @@
/* private */
/* prototypes */
/* plug-in */
static int _arm_write(ArchPlugin * plugin, ArchInstruction * instruction,
static int _arm_encode(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call);
/* functions */
/* plug-in */
/* arm_write */
static int _arm_write(ArchPlugin * plugin, ArchInstruction * instruction,
/* arm_encode */
static int _arm_encode(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call)
{
ArchPluginHelper * helper = plugin->helper;

19
src/arch/armeb.c Normal file
View File

@ -0,0 +1,19 @@
/* $Id$ */
/* Copyright (c) 2011 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Devel asm */
/* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#define ARCH_ENDIAN ARCH_ENDIAN_BIG
#include "arm.c"

19
src/arch/armel.c Normal file
View File

@ -0,0 +1,19 @@
/* $Id$ */
/* Copyright (c) 2011 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Devel asm */
/* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#define ARCH_ENDIAN ARCH_ENDIAN_LITTLE
#include "arm.c"

View File

@ -79,7 +79,7 @@ static ArchInstruction _dalvik_instructions[] =
/* prototypes */
/* plug-in */
static int _dalvik_write(ArchPlugin * plugin, ArchInstruction * instruction,
static int _dalvik_encode(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call);
static int _dalvik_decode(ArchPlugin * plugin, ArchInstructionCall * call);
@ -95,15 +95,15 @@ ArchPlugin arch_plugin =
_dalvik_instructions,
NULL,
NULL,
_dalvik_write,
_dalvik_encode,
_dalvik_decode
};
/* private */
/* functions */
/* dalvik_write */
static int _dalvik_write(ArchPlugin * plugin, ArchInstruction * instruction,
/* dalvik_encode */
static int _dalvik_encode(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call)
{
ArchPluginHelper * helper = plugin->helper;

View File

@ -80,6 +80,6 @@ ArchPlugin arch_plugin =
_i386_instructions,
NULL,
NULL,
_i386_write,
_i386_encode,
_i386_decode
};

View File

@ -24,7 +24,7 @@
/* private */
/* prototypes */
static int _i386_decode(ArchPlugin * plugin, ArchInstructionCall * call);
static int _i386_write(ArchPlugin * plugin, ArchInstruction * instruction,
static int _i386_encode(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call);
@ -442,23 +442,23 @@ static int _decode_register(ArchPlugin * plugin, ArchInstructionCall * call,
}
/* i386_write */
static int _write_constant(ArchPlugin * plugin,
/* i386_encode */
static int _encode_constant(ArchPlugin * plugin,
ArchOperandDefinition definition, ArchOperand * operand);
static int _write_dregister(ArchPlugin * plugin, uint32_t * i,
static int _encode_dregister(ArchPlugin * plugin, uint32_t * i,
ArchOperandDefinition * definitions, ArchOperand * operands);
static int _write_immediate(ArchPlugin * plugin, ArchOperand * operand);
static int _write_immediate8(ArchPlugin * plugin, uint8_t value);
static int _write_immediate16(ArchPlugin * plugin, uint16_t value);
static int _write_immediate24(ArchPlugin * plugin, uint32_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, uint32_t * i,
static int _encode_immediate(ArchPlugin * plugin, ArchOperand * operand);
static int _encode_immediate8(ArchPlugin * plugin, uint8_t value);
static int _encode_immediate16(ArchPlugin * plugin, uint16_t value);
static int _encode_immediate24(ArchPlugin * plugin, uint32_t value);
static int _encode_immediate32(ArchPlugin * plugin, uint32_t value);
static int _encode_opcode(ArchPlugin * plugin, ArchInstruction * instruction);
static int _encode_operand(ArchPlugin * plugin, uint32_t * i,
ArchOperandDefinition * definitions, ArchOperand * operands);
static int _write_register(ArchPlugin * plugin, uint32_t * i,
static int _encode_register(ArchPlugin * plugin, uint32_t * i,
ArchOperandDefinition * definitions, ArchOperand * operands);
static int _i386_write(ArchPlugin * plugin, ArchInstruction * instruction,
static int _i386_encode(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call)
{
uint32_t i;
@ -467,18 +467,18 @@ static int _i386_write(ArchPlugin * plugin, ArchInstruction * instruction,
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, instruction->name);
#endif
if(_write_opcode(plugin, instruction) != 0)
if(_encode_opcode(plugin, instruction) != 0)
return -1;
definitions[0] = instruction->op1;
definitions[1] = instruction->op2;
definitions[2] = instruction->op3;
for(i = 0; i < call->operands_cnt; i++)
if(_write_operand(plugin, &i, definitions, call->operands) != 0)
if(_encode_operand(plugin, &i, definitions, call->operands) != 0)
return -1;
return 0;
}
static int _write_constant(ArchPlugin * plugin,
static int _encode_constant(ArchPlugin * plugin,
ArchOperandDefinition definition, ArchOperand * operand)
{
ArchOperand ao;
@ -487,10 +487,10 @@ static int _write_constant(ArchPlugin * plugin,
return 0;
ao = *operand;
ao.definition &= ~(AOM_FLAGS);
return _write_immediate(plugin, &ao);
return _encode_immediate(plugin, &ao);
}
static int _write_dregister(ArchPlugin * plugin, uint32_t * i,
static int _encode_dregister(ArchPlugin * plugin, uint32_t * i,
ArchOperandDefinition * definitions, ArchOperand * operands)
{
ArchPluginHelper * helper = plugin->helper;
@ -526,7 +526,7 @@ static int _write_dregister(ArchPlugin * plugin, uint32_t * i,
<< 3);
if(operand->value.dregister.offset == 0)
/* there is no offset */
return _write_immediate(plugin, &ioperand);
return _encode_immediate(plugin, &ioperand);
/* declare offset */
switch(AO_GET_OFFSET(definition) >> 3)
{
@ -539,15 +539,15 @@ static int _write_dregister(ArchPlugin * plugin, uint32_t * i,
default:
return -error_set_code(1, "%s", "Invalid offset");
}
if(_write_immediate(plugin, &ioperand) != 0)
if(_encode_immediate(plugin, &ioperand) != 0)
return -1;
/* write offset */
ioperand.definition = AO_IMMEDIATE(0, AO_GET_OFFSET(definition), 0);
ioperand.value.immediate.value = operand->value.dregister.offset;
return _write_immediate(plugin, &ioperand);
return _encode_immediate(plugin, &ioperand);
}
static int _write_immediate(ArchPlugin * plugin, ArchOperand * operand)
static int _encode_immediate(ArchPlugin * plugin, ArchOperand * operand)
{
uint64_t value = operand->value.immediate.value;
@ -559,18 +559,18 @@ static int _write_immediate(ArchPlugin * plugin, ArchOperand * operand)
case 0:
return 0;
case sizeof(uint8_t):
return _write_immediate8(plugin, value);
return _encode_immediate8(plugin, value);
case sizeof(uint16_t):
return _write_immediate16(plugin, value);
return _encode_immediate16(plugin, value);
case 3:
return _write_immediate24(plugin, value);
return _encode_immediate24(plugin, value);
case sizeof(uint32_t):
return _write_immediate32(plugin, value);
return _encode_immediate32(plugin, value);
}
return -error_set_code(1, "%s", "Invalid size");
}
static int _write_immediate8(ArchPlugin * plugin, uint8_t value)
static int _encode_immediate8(ArchPlugin * plugin, uint8_t value)
{
ArchPluginHelper * helper = plugin->helper;
@ -579,7 +579,7 @@ static int _write_immediate8(ArchPlugin * plugin, uint8_t value)
return 0;
}
static int _write_immediate16(ArchPlugin * plugin, uint16_t value)
static int _encode_immediate16(ArchPlugin * plugin, uint16_t value)
{
ArchPluginHelper * helper = plugin->helper;
@ -589,7 +589,7 @@ static int _write_immediate16(ArchPlugin * plugin, uint16_t value)
return 0;
}
static int _write_immediate24(ArchPlugin * plugin, uint32_t value)
static int _encode_immediate24(ArchPlugin * plugin, uint32_t value)
{
ArchPluginHelper * helper = plugin->helper;
@ -599,7 +599,7 @@ static int _write_immediate24(ArchPlugin * plugin, uint32_t value)
return 0;
}
static int _write_immediate32(ArchPlugin * plugin, uint32_t value)
static int _encode_immediate32(ArchPlugin * plugin, uint32_t value)
{
ArchPluginHelper * helper = plugin->helper;
@ -609,7 +609,7 @@ static int _write_immediate32(ArchPlugin * plugin, uint32_t value)
return 0;
}
static int _write_opcode(ArchPlugin * plugin, ArchInstruction * instruction)
static int _encode_opcode(ArchPlugin * plugin, ArchInstruction * instruction)
{
ArchOperand operand;
@ -639,24 +639,24 @@ static int _write_opcode(ArchPlugin * plugin, ArchInstruction * instruction)
default:
return -error_set_code(1, "%s", "Invalid size");
}
return _write_immediate(plugin, &operand);
return _encode_immediate(plugin, &operand);
}
static int _write_operand(ArchPlugin * plugin, uint32_t * i,
static int _encode_operand(ArchPlugin * plugin, uint32_t * i,
ArchOperandDefinition * definitions, ArchOperand * operands)
{
switch(operands[*i].definition)
{
case AOT_CONSTANT:
return _write_constant(plugin, definitions[*i],
return _encode_constant(plugin, definitions[*i],
&operands[*i]);
case AOT_DREGISTER:
return _write_dregister(plugin, i, definitions,
return _encode_dregister(plugin, i, definitions,
operands);
case AOT_IMMEDIATE:
return _write_immediate(plugin, &operands[*i]);
return _encode_immediate(plugin, &operands[*i]);
case AOT_REGISTER:
return _write_register(plugin, i, definitions,
return _encode_register(plugin, i, definitions,
operands);
case AOT_NONE:
case AOT_DREGISTER2:
@ -666,7 +666,7 @@ static int _write_operand(ArchPlugin * plugin, uint32_t * i,
return 0;
}
static int _write_register(ArchPlugin * plugin, uint32_t * i,
static int _encode_register(ArchPlugin * plugin, uint32_t * i,
ArchOperandDefinition * definitions, ArchOperand * operands)
{
ArchPluginHelper * helper = plugin->helper;
@ -703,5 +703,5 @@ static int _write_register(ArchPlugin * plugin, uint32_t * i,
| (AO_GET_VALUE(definition) << 3);
else
ioperand.value.immediate.value = ar->id;
return _write_immediate(plugin, &ioperand);
return _encode_immediate(plugin, &ioperand);
}

View File

@ -81,6 +81,6 @@ ArchPlugin arch_plugin =
_i386_real_instructions,
NULL,
NULL,
_i386_write,
_i386_encode,
_i386_decode
};

View File

@ -81,6 +81,6 @@ ArchPlugin arch_plugin =
_i486_instructions,
NULL,
NULL,
_i386_write,
_i386_encode,
_i386_decode
};

View File

@ -82,6 +82,6 @@ ArchPlugin arch_plugin =
_i586_instructions,
NULL,
NULL,
_i386_write,
_i386_encode,
_i386_decode
};

View File

@ -84,6 +84,6 @@ ArchPlugin arch_plugin =
_i686_instructions,
NULL,
NULL,
_i386_write,
_i386_encode,
_i386_decode
};

View File

@ -251,7 +251,7 @@ static ArchInstruction _java_instructions[] =
/* prototypes */
/* plug-in */
static int _java_write(ArchPlugin * plugin, ArchInstruction * instruction,
static int _java_encode(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call);
static int _java_decode(ArchPlugin * plugin, ArchInstructionCall * call);
@ -267,7 +267,7 @@ ArchPlugin arch_plugin =
_java_instructions,
NULL,
NULL,
_java_write,
_java_encode,
_java_decode
};
@ -275,7 +275,7 @@ ArchPlugin arch_plugin =
/* private */
/* functions */
/* plug-in */
static int _java_write(ArchPlugin * plugin, ArchInstruction * instruction,
static int _java_encode(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call)
{
ArchPluginHelper * helper = plugin->helper;

View File

@ -18,13 +18,17 @@
#include <stddef.h>
#include "Asm.h"
#ifndef ARCH_ENDIAN
# define ARCH_ENDIAN ARCH_ENDIAN_BOTH
#endif
/* mips */
/* private */
/* variables */
static ArchDescription _mips_description =
{
"elf", ARCH_ENDIAN_BOTH, 32, 32, 32
"elf", ARCH_ENDIAN, 32, 32, 32
};
#define REG(name, size, id) { "" # name, size, id },
@ -59,6 +63,6 @@ ArchPlugin arch_plugin =
_mips_instructions,
NULL,
NULL,
_mips_write,
_mips_encode,
NULL
};

View File

@ -22,14 +22,14 @@
/* private */
/* prototypes */
/* plug-in */
static int _mips_write(ArchPlugin * plugin, ArchInstruction * instruction,
static int _mips_encode(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call);
/* functions */
/* plug-in */
/* mips_write */
static int _mips_write(ArchPlugin * plugin, ArchInstruction * instruction,
/* mips_encode */
static int _mips_encode(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call)
{
ArchPluginHelper * helper = plugin->helper;

19
src/arch/mipseb.c Normal file
View File

@ -0,0 +1,19 @@
/* $Id$ */
/* Copyright (c) 2011 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Devel asm */
/* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#define ARCH_ENDIAN ARCH_ENDIAN_BIG
#include "mips.c"

19
src/arch/mipsel.c Normal file
View File

@ -0,0 +1,19 @@
/* $Id$ */
/* Copyright (c) 2011 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Devel asm */
/* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#define ARCH_ENDIAN ARCH_ENDIAN_LITTLE
#include "mips.c"

View File

@ -1,4 +1,4 @@
targets=amd64,arm,dalvik,i386,i386_real,i486,i586,i686,java,mips,sparc,sparc64,yasep
targets=amd64,arm,armeb,armel,dalvik,i386,i386_real,i486,i586,i686,java,mips,mipseb,mipsel,sparc,sparc64,yasep
cppflags_force=-I ../../include
cflags_force=-W `pkg-config --cflags libSystem`
cflags=-Wall -g -O2 -fPIC -pedantic
@ -20,6 +20,22 @@ install=$(LIBDIR)/asm/arch
[arm.c]
depends=arm.h,arm.ins,arm.reg,common.ins,null.ins
[armeb]
type=plugin
sources=armeb.c
install=$(LIBDIR)/asm/arch
[armeb.c]
depends=arm.o
[armel]
type=plugin
sources=armel.c
install=$(LIBDIR)/asm/arch
[armel.c]
depends=arm.o
[dalvik]
type=plugin
sources=dalvik.c
@ -84,6 +100,22 @@ install=$(LIBDIR)/asm/arch
[mips.c]
depends=common.ins,null.ins,mips.h,mips.ins,mips.reg
[mipseb]
type=plugin
sources=mipseb.c
install=$(LIBDIR)/asm/arch
[mipseb.c]
depends=mips.o
[mipsel]
type=plugin
sources=mipsel.c
install=$(LIBDIR)/asm/arch
[mipsel.c]
depends=mips.o
[sparc]
type=plugin
sources=sparc.c

View File

@ -59,6 +59,6 @@ ArchPlugin arch_plugin =
_sparc_instructions,
NULL,
NULL,
_sparc_write,
_sparc_encode,
_sparc_decode
};

View File

@ -23,7 +23,7 @@
/* prototypes */
/* plug-in */
static int _sparc_decode(ArchPlugin * plugin, ArchInstructionCall * call);
static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction,
static int _sparc_encode(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call);
@ -71,17 +71,17 @@ static int _sparc_decode(ArchPlugin * plugin, ArchInstructionCall * call)
}
/* sparc_write */
static int _write_branch(ArchInstruction * instruction,
/* sparc_encode */
static int _encode_branch(ArchInstruction * instruction,
ArchInstructionCall * call, uint32_t * opcode);
static int _write_integer(ArchPlugin * plugin, ArchInstruction * instruction,
static int _encode_integer(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call, uint32_t * opcode);
static int _write_loadstore(ArchPlugin * plugin, ArchInstruction * instruction,
static int _encode_loadstore(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call, uint32_t * opcode);
static int _write_sethi(ArchPlugin * plugin, ArchInstruction * instruction,
static int _encode_sethi(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call, uint32_t * opcode);
static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction,
static int _sparc_encode(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call)
{
ArchPluginHelper * helper = plugin->helper;
@ -89,22 +89,22 @@ static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction,
if((opcode & 0xc0000000) == 0xc0000000)
{
if(_write_loadstore(plugin, instruction, call, &opcode) != 0)
if(_encode_loadstore(plugin, instruction, call, &opcode) != 0)
return -1;
}
else if((opcode & 0xc1c00000) == 0x01000000)
{
if(_write_sethi(plugin, instruction, call, &opcode) != 0)
if(_encode_sethi(plugin, instruction, call, &opcode) != 0)
return -1;
}
else if((opcode & 0xc0000000) == 0x80000000)
{
if(_write_integer(plugin, instruction, call, &opcode) != 0)
if(_encode_integer(plugin, instruction, call, &opcode) != 0)
return -1;
}
else if((opcode & 0xc1c00000) == 0x00800000)
{
if(_write_branch(instruction, call, &opcode) != 0)
if(_encode_branch(instruction, call, &opcode) != 0)
return -1;
}
else
@ -116,7 +116,7 @@ static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction,
return 0;
}
static int _write_branch(ArchInstruction * instruction,
static int _encode_branch(ArchInstruction * instruction,
ArchInstructionCall * call, uint32_t * opcode)
{
uint32_t disp;
@ -131,7 +131,7 @@ static int _write_branch(ArchInstruction * instruction,
return 0;
}
static int _write_integer(ArchPlugin * plugin, ArchInstruction * instruction,
static int _encode_integer(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call, uint32_t * opcode)
{
ArchPluginHelper * helper = plugin->helper;
@ -180,7 +180,7 @@ static int _write_integer(ArchPlugin * plugin, ArchInstruction * instruction,
return 0;
}
static int _write_loadstore(ArchPlugin * plugin, ArchInstruction * instruction,
static int _encode_loadstore(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call, uint32_t * opcode)
{
ArchPluginHelper * helper = plugin->helper;
@ -266,7 +266,7 @@ static int _write_loadstore(ArchPlugin * plugin, ArchInstruction * instruction,
return 0;
}
static int _write_sethi(ArchPlugin * plugin, ArchInstruction * instruction,
static int _encode_sethi(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call, uint32_t * opcode)
{
ArchPluginHelper * helper = plugin->helper;

View File

@ -58,6 +58,6 @@ ArchPlugin arch_plugin =
_sparc64_instructions,
NULL,
NULL,
_sparc_write,
_sparc_encode,
_sparc_decode
};

View File

@ -41,7 +41,7 @@ static ArchInstruction _yasep_instructions[] =
/* prototypes */
/* plug-in */
static int _yasep_write(ArchPlugin * plugin, ArchInstruction * instruction,
static int _yasep_encode(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call);
@ -56,7 +56,7 @@ ArchPlugin arch_plugin =
_yasep_instructions,
NULL,
NULL,
_yasep_write,
_yasep_encode,
NULL
};
@ -64,21 +64,21 @@ ArchPlugin arch_plugin =
/* private */
/* functions */
/* plug-in */
/* yasep_write */
static int _write_16(ArchPlugin * plugin, ArchInstruction * instruction,
/* yasep_encode */
static int _encode_16(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call);
static int _write_32(ArchPlugin * plugin, ArchInstruction * instruction,
static int _encode_32(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call);
static int _yasep_write(ArchPlugin * plugin, ArchInstruction * instruction,
static int _yasep_encode(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call)
{
return (instruction->opcode & 0x1)
? _write_32(plugin, instruction, call)
: _write_16(plugin, instruction, call);
? _encode_32(plugin, instruction, call)
: _encode_16(plugin, instruction, call);
}
static int _write_16(ArchPlugin * plugin, ArchInstruction * instruction,
static int _encode_16(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call)
{
ArchPluginHelper * helper = plugin->helper;
@ -91,7 +91,7 @@ static int _write_16(ArchPlugin * plugin, ArchInstruction * instruction,
return 0;
}
static int _write_32(ArchPlugin * plugin, ArchInstruction * instruction,
static int _encode_32(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call)
{
ArchPluginHelper * helper = plugin->helper;

View File

@ -24,7 +24,10 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "Asm/asm.h"
#include "arch.h"
#include "code.h"
#include "format.h"
#include "parser.h"
#include "../config.h"
@ -34,10 +37,12 @@
/* types */
struct _Asm
{
#if 1 /* FIXME probably useless now */
char * arch;
char * format;
#endif
Code * code;
AsmCode * code;
};
typedef struct _AsmPluginDescription
@ -96,7 +101,7 @@ void asm_delete(Asm * a)
fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
if(a->code != NULL)
code_delete(a->code);
asmcode_delete(a->code);
string_delete(a->format);
string_delete(a->arch);
object_delete(a);
@ -107,6 +112,8 @@ void asm_delete(Asm * a)
/* asm_get_arch */
char const * asm_get_arch(Asm * a)
{
if(a->code != NULL)
return asmcode_get_arch(a->code);
return a->arch;
}
@ -114,6 +121,8 @@ char const * asm_get_arch(Asm * a)
/* asm_get_format */
char const * asm_get_format(Asm * a)
{
if(a->code != NULL)
return asmcode_get_format(a->code);
return a->format;
}
@ -147,15 +156,7 @@ int asm_set_format(Asm * a, char const * format)
/* asm_set_function */
int asm_set_function(Asm * a, char const * name, off_t offset, ssize_t size)
{
return code_set_function(a->code, -1, name, offset, size);
}
/* asm_set_section */
int asm_set_section(Asm * a, char const * name, off_t offset, ssize_t size)
{
/* FIXME fully implement */
return code_section(a->code, name);
return asmcode_set_function(a->code, -1, name, offset, size);
}
@ -176,6 +177,21 @@ int asm_assemble(Asm * a, AsmPrefs * prefs, char const * infile,
}
/* asm_assemble_string */
int asm_assemble_string(Asm * a, AsmPrefs * prefs, char const * outfile,
char const * string)
{
int ret;
/* FIXME should also allow standard output, or return a buffer */
if(_asm_open(a, outfile) != 0)
return -1;
ret = parser_string(prefs, a->code, string);
ret |= asm_close(a);
return ret;
}
/* asm_close */
int asm_close(Asm * a)
{
@ -183,29 +199,28 @@ int asm_close(Asm * a)
if(a->code == NULL)
return -error_set_code(1, "%s", "No file opened");
ret = code_close(a->code);
ret = asmcode_close(a->code);
a->code = NULL;
return ret;
}
/* asm_deassemble */
int asm_deassemble(Asm * a, char const * buffer, size_t size)
AsmCode * asm_deassemble(Asm * a, char const * buffer, size_t size,
ArchInstructionCall ** calls, size_t * calls_cnt)
{
int ret;
if(_asm_open(a, NULL) != 0)
return -1;
ret = code_decode_buffer(a->code, buffer, size);
asm_close(a);
return ret;
return NULL;
if(asmcode_decode_buffer(a->code, buffer, size, calls, calls_cnt) != 0)
return NULL;
return a->code;
}
/* asm_function */
int asm_function(Asm * a, char const * name)
{
return code_function(a->code, name);
return asmcode_function(a->code, name);
}
@ -240,7 +255,7 @@ int asm_instruction(Asm * a, char const * name, unsigned int operands_cnt, ...)
}
va_end(ap);
}
return code_instruction(a->code, &call);
return asmcode_instruction(a->code, &call);
}
@ -252,24 +267,26 @@ int asm_open_assemble(Asm * a, char const * outfile)
/* asm_open_deassemble */
int asm_open_deassemble(Asm * a, char const * filename, int raw)
AsmCode * asm_open_deassemble(Asm * a, char const * filename, int raw)
{
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, filename);
#endif
if(a->code != NULL)
return -error_set_code(1, "%s: Operation in progress",
code_get_filename(a->code));
if((a->code = code_new_file(a->arch, a->format, filename)) == NULL)
return -1;
if(code_decode(a->code, raw) != 0)
return -1;
return 0;
{
error_set_code(1, "%s: Operation in progress",
asmcode_get_filename(a->code));
return NULL;
}
if((a->code = asmcode_new_file(a->arch, a->format, filename)) == NULL
|| asmcode_decode(a->code, raw) != 0)
return NULL;
return a->code;
}
/* asm_plugin_list */
int asm_plugin_list(AsmPluginType type)
int asm_plugin_list(AsmPluginType type, int decode)
{
AsmPluginDescription const * aspd;
char * path;
@ -277,6 +294,8 @@ int asm_plugin_list(AsmPluginType type)
struct dirent * de;
size_t len;
char const * sep = "";
Arch * arch;
Format * format;
aspd = &_asm_plugin_description[type];
fprintf(stderr, "%s%s%s", "Available ", aspd->description,
@ -303,7 +322,21 @@ int asm_plugin_list(AsmPluginType type)
if(strcmp(".so", &de->d_name[len - 3]) != 0)
continue;
de->d_name[len - 3] = '\0';
if(type == APT_ARCH && (arch = arch_new(de->d_name)) != NULL
&& (decode == 0 || arch_can_decode(arch)))
{
fprintf(stderr, "%s%s", sep, de->d_name);
arch_delete(arch);
}
else if(type == APT_FORMAT && (format = format_new(de->d_name))
!= NULL && (decode == 0
|| format_can_decode(format)))
{
fprintf(stderr, "%s%s", sep, de->d_name);
format_delete(format);
}
else
continue;
sep = ", ";
}
free(path);
@ -344,10 +377,10 @@ static int _asm_open(Asm * a, char const * outfile)
return -1;
if(a->code != NULL)
return -error_set_code(1, "%s: Operation in progress",
code_get_filename(a->code));
if((a->code = code_new(arch, format)) == NULL)
asmcode_get_filename(a->code));
if((a->code = asmcode_new(arch, format)) == NULL)
return -1;
if(outfile == NULL)
return 0;
return code_open(a->code, outfile);
return asmcode_open(a->code, outfile);
}

View File

@ -12,6 +12,9 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* TODO:
* - lookup if a symbol is defined for each offset
* - derive functions/labels/etc from symbols (type, id, name, union) */
@ -30,26 +33,10 @@
#include "../config.h"
/* Code */
/* AsmCode */
/* private */
/* types */
typedef struct _CodeString
{
int id;
char * name;
off_t offset;
ssize_t length;
} CodeString;
typedef struct _CodeFunction
{
int id;
char * name;
off_t offset;
ssize_t size;
} CodeFunction;
struct _Code
struct _AsmCode
{
Arch * arch;
ArchDescription * description;
@ -57,42 +44,53 @@ struct _Code
char * filename;
FILE * fp;
/* functions */
CodeFunction * functions;
size_t functions_cnt;
/* strings */
CodeString * strings;
size_t strings_cnt;
/* elements */
AsmElement * elements[AET_COUNT];
size_t elements_cnt[AET_COUNT];
};
/* prototypes */
/* functions */
static void _code_function_delete_all(Code * code);
/* elements */
static void _asmcode_element_delete_all(AsmCode * code, AsmElementType type);
static CodeFunction * _code_function_get_by_id(Code * code, AsmId id);
static int _code_function_set(CodeFunction * codefunction, int id,
static AsmElement * _asmcode_element_get_by_id(AsmCode * code,
AsmElementType type, AsmElementId id);
static int _asmcode_element_set(AsmElement * element, AsmElementId id,
char const * name, off_t offset, ssize_t size, off_t base);
/* functions */
static void _asmcode_function_delete_all(AsmCode * code);
static AsmFunction * _asmcode_function_get_by_id(AsmCode * code,
AsmFunctionId id);
static int _asmcode_function_set(AsmFunction * codefunction, AsmFunctionId id,
char const * name, off_t offset, ssize_t size);
static CodeFunction * _code_function_append(Code * code);
static AsmFunction * _asmcode_function_append(AsmCode * code);
/* sections */
static AsmSection * _asmcode_section_get_by_id(AsmCode * code, AsmSectionId id);
static int _asmcode_section_set(AsmSection * section, int id, char const * name,
off_t offset, ssize_t size, off_t base);
static AsmSection * _asmcode_section_append(AsmCode * code);
/* strings */
static void _code_string_delete_all(Code * code);
static void _asmcode_string_delete_all(AsmCode * code);
static CodeString * _code_string_get_by_id(Code * code, AsmId id);
static int _code_string_set(CodeString * codestring, int id, char const * name,
off_t offset, ssize_t length);
static AsmString * _asmcode_string_get_by_id(AsmCode * code, AsmStringId id);
static int _asmcode_string_set(AsmString * codestring,
int id, char const * name, off_t offset, ssize_t length);
static CodeString * _code_string_append(Code * code);
static int _code_string_read(Code * code, CodeString * codestring);
static AsmString * _asmcode_string_append(AsmCode * code);
static int _asmcode_string_read(AsmCode * code, AsmString * codestring);
/* functions */
/* code_new */
Code * code_new(char const * arch, char const * format)
/* asmcode_new */
AsmCode * asmcode_new(char const * arch, char const * format)
{
Code * code;
AsmCode * code;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s(\"%s\", \"%s\")\n", __func__, arch, format);
@ -105,7 +103,7 @@ Code * code_new(char const * arch, char const * format)
code->format = format_new(format);
if(code->arch == NULL)
{
code_delete(code);
asmcode_delete(code);
return NULL;
}
code->description = arch_get_description(code->arch);
@ -113,13 +111,13 @@ Code * code_new(char const * arch, char const * format)
}
/* code_new_file */
/* asmcode_new_file */
static Format * _new_file_format(char const * filename, FILE * fp);
Code * code_new_file(char const * arch, char const * format,
AsmCode * asmcode_new_file(char const * arch, char const * format,
char const * filename)
{
Code * code;
AsmCode * code;
FILE * fp;
#ifdef DEBUG
@ -155,7 +153,7 @@ Code * code_new_file(char const * arch, char const * format,
}
if(code->filename == NULL || code->arch == NULL || code->format == NULL)
{
code_delete(code);
asmcode_delete(code);
return NULL;
}
code->description = arch_get_description(code->arch);
@ -209,8 +207,8 @@ static Format * _new_file_format(char const * filename, FILE * fp)
}
/* code_delete */
int code_delete(Code * code)
/* asmcode_delete */
int asmcode_delete(AsmCode * code)
{
int ret = 0;
@ -231,71 +229,133 @@ int code_delete(Code * code)
/* accessors */
/* code_get_arch */
char const * code_get_arch(Code * code)
/* asmcode_get_arch */
char const * asmcode_get_arch(AsmCode * code)
{
return arch_get_name(code->arch);
}
/* code_get_filename */
char const * code_get_filename(Code * code)
/* asmcode_get_arch_description */
ArchDescription * asmcode_get_arch_description(AsmCode * code)
{
return arch_get_description(code->arch);
}
/* asmcode_get_filename */
char const * asmcode_get_filename(AsmCode * code)
{
return code->filename;
}
/* code_get_format */
char const * code_get_format(Code * code)
/* asmcode_get_format */
char const * asmcode_get_format(AsmCode * code)
{
return format_get_name(code->format);
}
/* code_get_function_by_id */
AsmFunction * code_get_function_by_id(Code * code, AsmId id)
/* asmcode_get_function_by_id */
AsmFunction * asmcode_get_function_by_id(AsmCode * code, AsmFunctionId id)
{
/* XXX CodeFunction has to be exactly like an AsmFunction */
return _code_function_get_by_id(code, id);
return _asmcode_element_get_by_id(code, AET_FUNCTION, id);
}
/* code_get_string_by_id */
AsmString * code_get_string_by_id(Code * code, AsmId id)
/* asmcode_get_functions */
void asmcode_get_functions(AsmCode * code, AsmFunction ** functions,
size_t * functions_cnt)
{
/* XXX CodeString has to be exactly like an AsmString */
return _code_string_get_by_id(code, id);
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
*functions = code->elements[AET_FUNCTION];
*functions_cnt = code->elements_cnt[AET_FUNCTION];
}
/* code_set_function */
int code_set_function(Code * code, int id, char const * name, off_t offset,
ssize_t size)
/* asmcode_get_section_by_id */
AsmSection * asmcode_get_section_by_id(AsmCode * code, AsmSectionId id)
{
CodeFunction * cf = NULL;
return _asmcode_element_get_by_id(code, AET_SECTION, id);
}
/* asmcode_get_sections */
void asmcode_get_sections(AsmCode * code, AsmSection ** sections,
size_t * sections_cnt)
{
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
*sections = code->elements[AET_SECTION];
*sections_cnt = code->elements_cnt[AET_SECTION];
}
/* asmcode_get_string_by_id */
AsmString * asmcode_get_string_by_id(AsmCode * code, AsmStringId id)
{
return _asmcode_element_get_by_id(code, AET_STRING, id);
}
/* asmcode_set_function */
int asmcode_set_function(AsmCode * code, int id, char const * name,
off_t offset, ssize_t size)
{
AsmFunction * cf = NULL;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s(%u, \"%s\", %ld, %ld)\n", __func__, id, name,
offset, size);
#endif
if(id >= 0)
cf = _code_function_get_by_id(code, id);
cf = _asmcode_function_get_by_id(code, id);
if(cf == NULL)
cf = _code_function_append(code);
if(cf == NULL || _code_function_set(cf, id, name, offset, size) != 0)
cf = _asmcode_function_append(code);
if(cf == NULL || _asmcode_function_set(cf, id, name, offset, size) != 0)
return -1;
/* FIXME isn't it considered an error if no ID is known yet? */
return cf->id;
}
/* code_set_string */
int code_set_string(Code * code, int id, char const * name, off_t offset,
/* asmcode_set_section */
int asmcode_set_section(AsmCode * code, int id, char const * name, off_t offset,
ssize_t size, off_t base)
{
AsmSection * cs = NULL;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s(%u, \"%s\", %ld, %ld)\n", __func__, id, name,
offset, size);
#endif
if(id >= 0)
cs = _asmcode_section_get_by_id(code, id);
if(cs == NULL)
cs = _asmcode_section_append(code);
if(cs == NULL || _asmcode_section_set(cs, id, name, offset, size, base)
!= 0)
return -1;
/* FIXME isn't it considered an error if no ID is known yet? */
return cs->id;
}
/* asmcode_set_string */
int asmcode_set_string(AsmCode * code, int id, char const * name, off_t offset,
ssize_t length)
{
CodeString * cs = NULL;
AsmString * cs = NULL;
if(id >= 0)
cs = _code_string_get_by_id(code, id);
cs = _asmcode_string_get_by_id(code, id);
if(cs == NULL)
cs = _code_string_append(code);
if(cs == NULL || _code_string_set(cs, id, name, offset, length) != 0)
cs = _asmcode_string_append(code);
if(cs == NULL || _asmcode_string_set(cs, id, name, offset, length) != 0)
return -1;
/* FIXME isn't it considered an error if no ID is known yet? */
return cs->id;
@ -303,8 +363,8 @@ int code_set_string(Code * code, int id, char const * name, off_t offset,
/* useful */
/* code_close */
int code_close(Code * code)
/* asmcode_close */
int asmcode_close(AsmCode * code)
{
int ret = 0;
@ -318,101 +378,67 @@ int code_close(Code * code)
ret |= -error_set_code(1, "%s: %s", code->filename,
strerror(errno));
code->fp = NULL;
_code_string_delete_all(code);
_code_function_delete_all(code);
_asmcode_string_delete_all(code);
_asmcode_function_delete_all(code);
return ret;
}
/* code_decode */
int code_decode(Code * code, int raw)
/* asmcode_decode */
int asmcode_decode(AsmCode * code, int raw)
{
printf("%s: %s-%s\n", code->filename, format_get_name(code->format),
arch_get_name(code->arch));
return format_decode(code->format, code, raw);
}
/* code_decode_at */
static void _decode_at_print_address(ArchDescription * description,
unsigned long address);
int code_decode_at(Code * code, char const * section, off_t offset,
size_t size, off_t base)
/* asmcode_decode_at */
int asmcode_decode_at(AsmCode * code, off_t offset, size_t size, off_t base,
ArchInstructionCall ** calls, size_t * calls_cnt)
{
ArchDescription * description;
ArchInstructionCall * calls = NULL;
size_t calls_cnt = 0;
size_t i;
if(section != NULL)
printf("%s%s:\n", "\nDisassembly of section ", section);
if(arch_decode_at(code->arch, code, &calls, &calls_cnt, offset, size,
base) != 0)
return -1;
description = arch_get_description(code->arch);
if(size != 0)
_decode_at_print_address(description, base);
for(i = 0; i < calls_cnt; i++)
code_print(code, description, &calls[i]);
free(calls);
if(arch_seek(code->arch, offset + size, SEEK_SET) < 0)
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s(%ld, %lu, %ld)\n", __func__, offset, size,
base);
#endif
if(arch_decode_at(code->arch, code, offset, size, base, calls,
calls_cnt) != 0)
return -1;
return 0;
}
static void _decode_at_print_address(ArchDescription * description,
unsigned long address)
{
uint32_t size = (description != NULL) ? description->address_size : 32;
char const * format = "\n%08lx:\n";
switch(size)
{
case 64:
format = "\n%016lx:\n";
break;
case 20:
format = "\n%05lx:\n";
break;
default:
break;
}
printf(format, address);
}
/* code_decode_buffer */
int code_decode_buffer(Code * code, char const * buffer, size_t size)
/* asmcode_decode_buffer */
int asmcode_decode_buffer(AsmCode * code, char const * buffer, size_t size,
ArchInstructionCall ** calls, size_t * calls_cnt)
{
int ret;
ArchDescription * description;
ArchInstructionCall * calls = NULL;
size_t calls_cnt = 0;
size_t i;
arch_init_buffer(code->arch, buffer, size);
description = arch_get_description(code->arch);
if((ret = arch_decode(code->arch, code, &calls, &calls_cnt, 0)) == 0)
{
for(i = 0; i < calls_cnt; i++)
code_print(code, description, &calls[i]);
free(calls);
}
ret = arch_decode(code->arch, code, 0, calls, calls_cnt);
arch_exit(code->arch);
return ret;
}
/* code_function */
int code_function(Code * code, char const * function)
/* asmcode_decode_section */
int asmcode_decode_section(AsmCode * code, AsmSection * section,
ArchInstructionCall ** calls, size_t * calls_cnt)
{
return format_decode_section(code->format, code, section, calls,
calls_cnt);
}
/* asmcode_function */
int asmcode_function(AsmCode * code, char const * function)
{
return format_function(code->format, function);
}
/* code_instruction */
int code_instruction(Code * code, ArchInstructionCall * call)
/* asmcode_instruction */
int asmcode_instruction(AsmCode * code, ArchInstructionCall * call)
{
ArchInstruction * ai;
@ -423,12 +449,12 @@ int code_instruction(Code * code, ArchInstructionCall * call)
", 3 0x%x\n", call->name, ai->opcode, ai->op1, ai->op2,
ai->op3);
#endif
return arch_write(code->arch, ai, call);
return arch_encode(code->arch, ai, call);
}
/* code_open */
int code_open(Code * code, char const * filename)
/* asmcode_open */
int asmcode_open(AsmCode * code, char const * filename)
{
if(code->filename != NULL || code->fp != NULL)
return -error_set_code(1, "A file is already opened");
@ -455,21 +481,20 @@ int code_open(Code * code, char const * filename)
}
/* code_print */
/* asmcode_print */
static void _print_address(ArchDescription * description,
unsigned long address);
static void _print_immediate(ArchOperand * ao);
int code_print(Code * code, ArchDescription * description,
ArchInstructionCall * call)
int asmcode_print(AsmCode * code, ArchInstructionCall * call)
{
ArchDescription * description;
char const * sep = " ";
size_t i;
uint8_t u8;
ArchOperand * ao;
char const * name;
if(description == NULL)
description = arch_get_description(code->arch);
if(arch_seek(code->arch, call->offset, SEEK_SET) < 0)
return -1;
@ -558,8 +583,8 @@ static void _print_immediate(ArchOperand * ao)
}
/* code_section */
int code_section(Code * code, char const * section)
/* asmcode_section */
int asmcode_section(AsmCode * code, char const * section)
{
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, section);
@ -569,38 +594,89 @@ int code_section(Code * code, char const * section)
/* private */
/* functions */
/* functions */
/* code_function_delete_all */
static void _code_function_delete_all(Code * code)
/* elements */
/* asmcode_element_set */
static int _asmcode_element_set(AsmElement * element, AsmElementId id,
char const * name, off_t offset, ssize_t size, off_t base)
{
size_t i;
char * p = NULL;
for(i = 0; i < code->functions_cnt; i++)
free(code->functions[i].name);
code->functions_cnt = 0;
free(code->functions);
code->functions = NULL;
if(name != NULL && (p = string_new(name)) == NULL)
return -1;
element->id = id;
free(element->name);
element->name = p;
element->offset = offset;
element->size = size;
element->base = base;
return 0;
}
/* code_function_get_by_id */
static CodeFunction * _code_function_get_by_id(Code * code, AsmId id)
static AsmElement * _asmcode_element_append(AsmCode * code, AsmElementType type)
{
size_t i;
AsmElement * p = code->elements[type];
size_t cnt = code->elements_cnt[type];
for(i = 0; i < code->functions_cnt; i++)
if(code->functions[i].id >= 0
&& (AsmId)code->functions[i].id == id)
break;
if(i == code->functions_cnt)
if((p = realloc(p, sizeof(*p) * (cnt + 1))) == NULL)
{
error_set_code(1, "%s", strerror(errno));
return NULL;
return &code->functions[i];
}
code->elements[type] = p;
p = &code->elements[type][cnt];
code->elements_cnt[type]++;
p->id = -1;
p->name = NULL;
p->offset = -1;
p->size = -1;
return p;
}
/* code_function_set */
static int _code_function_set(CodeFunction * codefunction, int id,
static void _asmcode_element_delete_all(AsmCode * code, AsmElementType type)
{
size_t i;
for(i = 0; i < code->elements_cnt[type]; i++)
free(code->elements[type][i].name);
code->elements_cnt[type] = 0;
free(code->elements[type]);
code->elements[type] = NULL;
}
static AsmElement * _asmcode_element_get_by_id(AsmCode * code,
AsmElementType type, AsmElementId id)
{
size_t i;
for(i = 0; i < code->elements_cnt[type]; i++)
if(code->elements[type][i].id >= 0
&& code->elements[type][i].id == id)
return &code->elements[type][i];
return NULL;
}
/* functions */
/* asmcode_function_delete_all */
static void _asmcode_function_delete_all(AsmCode * code)
{
_asmcode_element_delete_all(code, AET_FUNCTION);
}
/* asmcode_function_get_by_id */
static AsmFunction * _asmcode_function_get_by_id(AsmCode * code,
AsmFunctionId id)
{
return _asmcode_element_get_by_id(code, AET_FUNCTION, id);
}
/* asmcode_function_set */
static int _asmcode_function_set(AsmFunction * codefunction, AsmFunctionId id,
char const * name, off_t offset, ssize_t size)
{
char * p = NULL;
@ -616,118 +692,96 @@ static int _code_function_set(CodeFunction * codefunction, int id,
}
/* code_function_append */
static CodeFunction * _code_function_append(Code * code)
/* asmcode_function_append */
static AsmFunction * _asmcode_function_append(AsmCode * code)
{
CodeFunction * p;
return _asmcode_element_append(code, AET_FUNCTION);
}
if((p = realloc(code->functions, sizeof(*p) * (code->functions_cnt
+ 1))) == NULL)
{
error_set_code(1, "%s", strerror(errno));
return NULL;
}
code->functions = p;
p = &code->functions[code->functions_cnt++];
p->id = -1;
p->name = NULL;
p->offset = -1;
p->size = -1;
return p;
/* sections */
/* asmcode_section_get_by_id */
static AsmSection * _asmcode_section_get_by_id(AsmCode * code, AsmSectionId id)
{
return _asmcode_element_get_by_id(code, AET_SECTION, id);
}
/* asmcode_section_set */
static int _asmcode_section_set(AsmSection * section, int id, char const * name,
off_t offset, ssize_t size, off_t base)
{
return _asmcode_element_set(section, id, name, offset, size, base);
}
/* asmcode_section_append */
static AsmSection * _asmcode_section_append(AsmCode * code)
{
return _asmcode_element_append(code, AET_SECTION);
}
/* strings */
/* code_string_delete_all */
static void _code_string_delete_all(Code * code)
/* asmcode_string_delete_all */
static void _asmcode_string_delete_all(AsmCode * code)
{
size_t i;
for(i = 0; i < code->strings_cnt; i++)
free(code->strings[i].name);
code->strings_cnt = 0;
free(code->strings);
code->strings = NULL;
_asmcode_element_delete_all(code, AET_STRING);
}
/* code_string_get_by_id */
static CodeString * _code_string_get_by_id(Code * code, AsmId id)
/* asmcode_string_get_by_id */
static AsmString * _asmcode_string_get_by_id(AsmCode * code, AsmStringId id)
{
size_t i;
AsmString * ret;
for(i = 0; i < code->strings_cnt; i++)
if(code->strings[i].id >= 0 && (AsmId)code->strings[i].id == id)
break;
if(i == code->strings_cnt)
if((ret = _asmcode_element_get_by_id(code, AET_STRING, id)) == NULL)
return NULL;
if(code->strings[i].name == NULL)
_code_string_read(code, &code->strings[i]);
return &code->strings[i];
if(ret->name == NULL)
_asmcode_string_read(code, ret);
return ret;
}
/* code_string_set */
static int _code_string_set(CodeString * codestring, int id, char const * name,
off_t offset, ssize_t length)
/* asmcode_string_set */
static int _asmcode_string_set(AsmString * codestring, int id,
char const * name, off_t offset, ssize_t length)
{
char * p = NULL;
if(name != NULL && (p = string_new(name)) == NULL)
return -error_set_code(1, "%s", strerror(errno));
codestring->id = id;
free(codestring->name);
codestring->name = p;
codestring->offset = offset;
codestring->length = length;
return 0;
return _asmcode_element_set(codestring, id, name, offset, length, 0);
}
/* code_string_append */
static CodeString * _code_string_append(Code * code)
/* asmcode_string_append */
static AsmString * _asmcode_string_append(AsmCode * code)
{
CodeString * p;
if((p = realloc(code->strings, sizeof(*p) * (code->strings_cnt + 1)))
== NULL)
{
error_set_code(1, "%s", strerror(errno));
return NULL;
}
code->strings = p;
p = &code->strings[code->strings_cnt++];
p->id = -1;
p->name = NULL;
p->offset = -1;
p->length = -1;
return p;
return _asmcode_element_append(code, AET_STRING);
}
/* code_string_read */
static int _code_string_read(Code * code, CodeString * codestring)
/* asmcode_string_read */
static int _asmcode_string_read(AsmCode * code, AsmString * codestring)
{
off_t offset; /* XXX should not have to be kept */
char * buf;
if(codestring->offset < 0 || codestring->length < 0)
/* FIXME if offset < 0 read until '\0' */
if(codestring->offset < 0 || codestring->size < 0)
return -error_set_code(1, "%s", "Insufficient information to"
" read string");
if((offset = arch_seek(code->arch, 0, SEEK_CUR)) < 0)
return -1;
if((buf = malloc(codestring->length + 1)) == NULL)
if((buf = malloc(codestring->size + 1)) == NULL)
return -error_set_code(1, "%s", strerror(errno));
if(arch_seek(code->arch, codestring->offset, SEEK_SET)
!= codestring->offset)
return -1;
if(arch_read(code->arch, buf, codestring->length) != codestring->length)
if(arch_read(code->arch, buf, codestring->size) != codestring->size)
{
free(buf);
arch_seek(code->arch, offset, SEEK_SET);
return -1;
}
buf[codestring->length] = '\0';
buf[codestring->size] = '\0';
free(codestring->name);
codestring->name = buf;
arch_seek(code->arch, offset, SEEK_SET);

View File

@ -19,48 +19,28 @@
# define ASM_CODE_H
# include <stdio.h>
# include "Asm/arch.h"
/* types */
typedef struct _Code Code;
# include "Asm/code.h"
/* functions */
Code * code_new(char const * arch, char const * format);
Code * code_new_file(char const * arch, char const * format,
AsmCode * asmcode_new(char const * arch, char const * format);
AsmCode * asmcode_new_file(char const * arch, char const * format,
char const * filename);
int code_delete(Code * code);
/* accessors */
char const * code_get_arch(Code * code);
char const * code_get_filename(Code * code);
char const * code_get_format(Code * code);
AsmFunction * code_get_function_by_id(Code * code, AsmId id);
AsmString * code_get_string_by_id(Code * code, AsmId id);
int code_set_function(Code * code, int id, char const * name, off_t offset,
ssize_t size);
int code_set_string(Code * code, int id, char const * name, off_t offset,
ssize_t length);
int asmcode_delete(AsmCode * code);
/* useful */
/* common */
int code_open(Code * code, char const * filename);
int code_close(Code * code);
int asmcode_open(AsmCode * code, char const * filename);
int asmcode_close(AsmCode * code);
/* assembly */
int code_function(Code * code, char const * function);
int code_instruction(Code * code, ArchInstructionCall * call);
int code_section(Code * code, char const * section);
/* disassembly */
int code_decode(Code * code, int raw);
int code_decode_at(Code * code, char const * section, off_t offset,
size_t size, off_t base);
int code_decode_buffer(Code * code, char const * buffer, size_t size);
int code_print(Code * code, ArchDescription * description,
ArchInstructionCall * call);
/* elements */
AsmElement * asmcode_get_element_by_id(AsmCode * a, AsmElementType type,
AsmElementId id);
AsmElement * asmcode_get_element_by_name(AsmCode * af, AsmElementType type,
char const * name);
AsmElement * asmcode_get_element_by_offset(AsmCode * af, AsmElementType type,
off_t offset);
int asmcode_get_elements(AsmCode * af, AsmElementType type,
AsmElement ** elements, size_t * count);
#endif /* !ASM_CODE_H */

View File

@ -40,35 +40,89 @@ static int _usage(void);
/* functions */
/* deasm */
static int _deasm_section(AsmCode * code, AsmSection * section);
static int _deasm(char const * arch, char const * format, char const * filename,
int raw)
{
int ret;
Asm * a;
AsmCode * code;
AsmSection * sections;
size_t sections_cnt;
size_t i;
if((a = asm_new(arch, format)) == NULL)
return -error_print("deasm");
if((ret = asm_open_deassemble(a, filename, raw)) != 0)
if((code = asm_open_deassemble(a, filename, raw)) == NULL)
error_print("deasm");
else
{
printf("%s: %s-%s\n", filename, asm_get_format(a),
asm_get_arch(a));
asmcode_get_sections(code, &sections, &sections_cnt);
for(i = 0; i < sections_cnt; i++)
if((ret = _deasm_section(code, &sections[i])) != 0)
break;
asm_close(a);
}
asm_delete(a);
return ret;
}
static int _deasm_section(AsmCode * code, AsmSection * section)
{
ArchDescription * description;
size_t size;
ArchInstructionCall * calls = NULL;
size_t calls_cnt = 0;
size_t i;
printf("\nDisassembly of section %s:\n", section->name);
if(asmcode_decode_section(code, section, &calls, &calls_cnt) != 0)
{
error_print("deasm");
return -1;
}
description = asmcode_get_arch_description(code);
size = (description != NULL) ? description->address_size : 32;
switch(size)
{
case 64:
printf("\n%016lx:\n", section->base);
break;
case 20:
printf("\n%05lx:\n", section->base);
break;
case 32:
default:
printf("\n%08lx:\n", section->base);
break;
}
for(i = 0; i < calls_cnt; i++)
asmcode_print(code, &calls[i]);
free(calls);
return 0;
}
/* deasm_buffer */
static int _deasm_buffer(char const * arch, char const * buffer, size_t size)
{
Asm * a;
AsmCode * code;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
if((a = asm_new(arch, NULL)) == NULL)
return -1;
if(asm_deassemble(a, buffer, size) != 0)
if((code = asm_deassemble(a, buffer, size, NULL, NULL)) == NULL)
error_print("deasm");
else
{
/* FIXME implement */
}
asm_delete(a);
return 0;
}
@ -138,8 +192,8 @@ static int _deasm_list(void)
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
asm_plugin_list(APT_ARCH);
asm_plugin_list(APT_FORMAT);
asm_plugin_list(APT_ARCH, 1);
asm_plugin_list(APT_FORMAT, 1);
return 0;
}
@ -147,9 +201,13 @@ static int _deasm_list(void)
/* usage */
static int _usage(void)
{
fputs("Usage: deasm [-a arch][-f format] filename\n"
fputs("Usage: deasm [-a arch][-f format][-D] filename\n"
" deasm [-a arch] -s string\n"
" deasm -l\n", stderr);
" deasm -l\n"
" -a Force the given architecture\n"
" -f Force the given file format\n"
" -D Deassemble all sections\n"
" -l List all the architectures and file formats available\n", stderr);
return 1;
}

View File

@ -40,21 +40,28 @@ struct _Format
FILE * fp;
/* deassembly */
Code * code;
AsmCode * code;
};
/* prototypes */
/* helpers */
static char const * _format_helper_get_filename(Format * format);
static AsmString * _format_helper_get_string_by_id(Format * format, AsmId id);
static int _format_helper_set_function(Format * format, int id,
static void _format_helper_get_functions(Format * format,
AsmFunction ** functions, size_t * functions_cnt);
static AsmSection * _format_helper_get_section_by_id(Format * format,
AsmSectionId id);
static AsmString * _format_helper_get_string_by_id(Format * format,
AsmStringId id);
static int _format_helper_set_function(Format * format, AsmFunctionId id,
char const * name, off_t offset, ssize_t size);
static int _format_helper_set_section(Format * format, AsmSectionId id,
char const * name, off_t offset, ssize_t size, off_t base);
static int _format_helper_set_string(Format * format, AsmStringId id,
char const * name, off_t offset, ssize_t size);
static int _format_helper_set_string(Format * format, int id, char const * name,
off_t offset, ssize_t size);
static int _format_helper_decode(Format * format, char const * section,
off_t offset, size_t size, off_t base);
static int _format_helper_decode(Format * format, off_t offset, size_t size,
off_t base, ArchInstructionCall ** calls, size_t * calls_cnt);
static ssize_t _format_helper_read(Format * format, void * buf, size_t size);
static off_t _format_helper_seek(Format * format, off_t offset, int whence);
static ssize_t _format_helper_write(Format * format, void const * buf,
@ -92,8 +99,11 @@ Format * format_new(char const * format)
f->helper.format = f;
f->helper.decode = _format_helper_decode;
f->helper.get_filename = _format_helper_get_filename;
f->helper.get_functions = _format_helper_get_functions;
f->helper.get_section_by_id = _format_helper_get_section_by_id;
f->helper.get_string_by_id = _format_helper_get_string_by_id;
f->helper.set_function = _format_helper_set_function;
f->helper.set_section = _format_helper_set_section;
f->helper.set_string = _format_helper_set_string;
f->helper.read = _format_helper_read;
f->helper.seek = _format_helper_seek;
@ -115,6 +125,14 @@ void format_delete(Format * format)
/* accessors */
/* format_can_decode */
int format_can_decode(Format * format)
{
return format->plugin->decode != NULL
/* && format->plugin->decode_section != NULL */;
}
/* format_get_arch */
char const * format_get_arch(Format * format)
{
@ -133,12 +151,12 @@ char const * format_get_name(Format * format)
/* useful */
/* format_decode */
int format_decode(Format * format, Code * code, int raw)
int format_decode(Format * format, AsmCode * code, int raw)
{
int ret;
if(format->plugin->decode == NULL)
return error_set_code(1, "%s: %s", format_get_name(format),
return -error_set_code(1, "%s: %s", format_get_name(format),
"Disassembly is not supported");
format->code = code;
ret = format->plugin->decode(format->plugin, raw);
@ -147,6 +165,26 @@ int format_decode(Format * format, Code * code, int raw)
}
/* format_decode_section */
int format_decode_section(Format * format, AsmCode * code, AsmSection * section,
ArchInstructionCall ** calls, size_t * calls_cnt)
{
int ret;
if(format->plugin->decode_section == NULL)
return -error_set_code(1, "%s: %s", format_get_name(format),
"Disassembly is not supported");
if(section == NULL || section->id < 0)
return -error_set_code(1, "%s: %s", format_get_name(format),
"Invalid argument");
format->code = code;
ret = format->plugin->decode_section(format->plugin, section, calls,
calls_cnt);
format->code = NULL;
return ret;
}
/* format_detect_arch */
char const * format_detect_arch(Format * format)
{
@ -255,41 +293,66 @@ static char const * _format_helper_get_filename(Format * format)
}
/* format_helper_get_string_by_id */
static AsmString * _format_helper_get_string_by_id(Format * format, AsmId id)
/* format_helper_get_functions */
static void _format_helper_get_functions(Format * format,
AsmFunction ** functions, size_t * functions_cnt)
{
return code_get_string_by_id(format->code, id);
asmcode_get_functions(format->code, functions, functions_cnt);
}
/* format_helper_get_section_by_id */
static AsmSection * _format_helper_get_section_by_id(Format * format,
AsmSectionId id)
{
return asmcode_get_section_by_id(format->code, id);
}
/* format_helper_get_string_by_id */
static AsmString * _format_helper_get_string_by_id(Format * format,
AsmStringId id)
{
return asmcode_get_string_by_id(format->code, id);
}
/* format_helper_set_function */
static int _format_helper_set_function(Format * format, int id,
static int _format_helper_set_function(Format * format, AsmFunctionId id,
char const * name, off_t offset, ssize_t size)
{
return code_set_function(format->code, id, name, offset, size);
return asmcode_set_function(format->code, id, name, offset, size);
}
/* format_helper_set_section */
static int _format_helper_set_section(Format * format, AsmSectionId id,
char const * name, off_t offset, ssize_t size, off_t base)
{
return asmcode_set_section(format->code, id, name, offset, size, base);
}
/* format_helper_set_string */
static int _format_helper_set_string(Format * format, int id, char const * name,
off_t offset, ssize_t size)
static int _format_helper_set_string(Format * format, AsmStringId id,
char const * name, off_t offset, ssize_t size)
{
return code_set_string(format->code, id, name, offset, size);
return asmcode_set_string(format->code, id, name, offset, size);
}
/* format_helper_decode */
static int _format_helper_decode(Format * format, char const * section,
off_t offset, size_t size, off_t base)
static int _format_helper_decode(Format * format, off_t offset, size_t size,
off_t base, ArchInstructionCall ** calls, size_t * calls_cnt)
{
int ret;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s(\"%s\", 0x%lx, 0x%lx, 0x%lx)\n", __func__,
section, offset, size, base);
fprintf(stderr, "DEBUG: %s(0x%lx, 0x%lx, 0x%lx)\n", __func__, offset,
size, base);
#endif
if((ret = code_decode_at(format->code, section, offset, size, base))
!= 0)
if((ret = asmcode_decode_at(format->code, offset, size, base,
calls, calls_cnt)) != 0)
error_print("deasm");
return ret;
}

View File

@ -18,6 +18,7 @@
#ifndef ASM_FORMAT_H
# define ASM_FORMAT_H
# include "Asm/common.h"
# include "Asm/format.h"
# include "code.h"
@ -27,17 +28,19 @@
/* types */
typedef int (*FormatDecodeCallback)(void * priv, char const * section,
off_t offset, size_t size, off_t base);
typedef AsmString * (*FormatGetStringByIdCallback)(void * priv, AsmId id);
typedef int (*FormatSetFunctionCallback)(void * priv, int id, char const * name,
off_t offset, ssize_t length);
typedef int (*FormatSetStringCallback)(void * priv, int id, char const * name,
off_t offset, ssize_t length);
typedef AsmString * (*FormatGetStringByIdCallback)(void * priv, AsmStringId id);
typedef int (*FormatSetFunctionCallback)(void * priv, AsmFunctionId id,
char const * name, off_t offset, ssize_t length);
typedef int (*FormatSetStringCallback)(void * priv, AsmStringId id,
char const * name, off_t offset, ssize_t length);
/* functions */
Format * format_new(char const * format);
void format_delete(Format * format);
/* accessors */
int format_can_decode(Format * format);
char const * format_get_name(Format * format);
/* useful */
@ -50,7 +53,9 @@ int format_function(Format * format, char const * function);
int format_section(Format * format, char const * section);
/* disassembly */
int format_decode(Format * format, Code * code, int raw);
int format_decode(Format * format, AsmCode * code, int raw);
int format_decode_section(Format * format, AsmCode * code, AsmSection * section,
ArchInstructionCall ** calls, size_t * calls_cnt);
char const * format_detect_arch(Format * format);
int format_match(Format * format);

View File

@ -126,6 +126,8 @@ static int _dex_init(FormatPlugin * format, char const * arch);
static int _dex_exit(FormatPlugin * format);
static char const * _dex_detect(FormatPlugin * format);
static int _dex_decode(FormatPlugin * format, int raw);
static int _dex_decode_section(FormatPlugin * format, AsmSection * section,
ArchInstructionCall ** calls, size_t * calls_cnt);
/* public */
@ -142,6 +144,7 @@ FormatPlugin format_plugin =
NULL,
_dex_detect,
_dex_decode,
_dex_decode_section,
NULL
};
@ -183,14 +186,15 @@ static int _dex_exit(FormatPlugin * format)
/* dex_detect */
static char const * _dex_detect(FormatPlugin * format)
{
/* FIXME some sections might contain native code */
/* XXX some sections might contain native code */
return "dalvik";
}
/* dex_decode */
static int _decode_map(FormatPlugin * format, DexHeader * dh);
static int _decode_map_code(FormatPlugin * format, off_t offset, size_t size);
static int _decode_map(FormatPlugin * format, DexHeader * dh, int raw);
static int _decode_map_code(FormatPlugin * format, size_t id, off_t offset,
size_t size);
static int _decode_map_method_id(FormatPlugin * format, off_t offset,
size_t size);
static int _decode_map_string_id(FormatPlugin * format, off_t offset,
@ -201,17 +205,20 @@ static int _dex_decode(FormatPlugin * format, int raw)
FormatPluginHelper * helper = format->helper;
DexHeader dh;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s(%d)\n", __func__, raw);
#endif
if(helper->seek(helper->format, 0, SEEK_SET) != 0)
return -1;
if(helper->read(helper->format, &dh, sizeof(dh)) != sizeof(dh))
return -1;
dh.map_off = _htol32(dh.map_off);
if(_decode_map(format, &dh) != 0)
if(_decode_map(format, &dh, raw) != 0)
return -1;
return 0;
}
static int _decode_map(FormatPlugin * format, DexHeader * dh)
static int _decode_map(FormatPlugin * format, DexHeader * dh, int raw)
{
int ret = 0;
FormatPluginHelper * helper = format->helper;
@ -247,7 +254,7 @@ static int _decode_map(FormatPlugin * format, DexHeader * dh)
switch(dmi.type)
{
case TYPE_CODE_ITEM:
ret |= _decode_map_code(format, dmi.offset,
ret |= _decode_map_code(format, i, dmi.offset,
dmi.size);
break;
case TYPE_METHOD_ID_ITEM:
@ -267,64 +274,17 @@ static int _decode_map(FormatPlugin * format, DexHeader * dh)
return ret;
}
static int _decode_map_code(FormatPlugin * format, off_t offset, size_t size)
static int _decode_map_code(FormatPlugin * format, size_t id, off_t offset,
size_t size)
{
FormatPluginHelper * helper = format->helper;
DexMapCodeItem dmci;
size_t i;
off_t seek;
size_t j;
DexMapTryItem dmti;
ssize_t s;
if(helper->decode(helper->format, ".text", offset, 0, offset) != 0)
return -1;
for(i = 0; i < size; i++)
{
s = sizeof(dmci);
if(helper->read(helper->format, &dmci, s) != s)
return -1;
dmci.registers_size = _htol16(dmci.registers_size);
dmci.ins_size = _htol16(dmci.ins_size);
dmci.outs_size = _htol16(dmci.outs_size);
dmci.tries_size = _htol16(dmci.tries_size);
dmci.debug_info_off = _htol32(dmci.debug_info_off);
dmci.insns_size = _htol32(dmci.insns_size);
seek = helper->seek(helper->format, 0, SEEK_CUR);
if(helper->decode(helper->format, NULL, seek,
dmci.insns_size * 2, seek) != 0)
return -1;
/* skip padding and try_items */
seek = (dmci.insns_size & 0x1) == 0x1 ? 2 : 0;
#ifdef DEBUG
fprintf(stderr, "DEBUG: code item %lu, offset 0x%lx"
", registers 0x%x, size 0x%x, debug @0x%x"
", tries 0x%x, seek 0x%lx\n", i,
helper->seek(helper->format, 0, SEEK_CUR),
dmci.registers_size, dmci.insns_size * 2,
dmci.debug_info_off, dmci.tries_size, seek);
fprintf(stderr, "DEBUG: %s(%lu, %ld, %lu)\n", __func__, id, offset,
size);
#endif
if(seek != 0 && helper->seek(helper->format, seek, SEEK_CUR)
< 0)
return -1;
if(dmci.tries_size > 0)
{
for(j = 0; j < dmci.tries_size; j++)
{
s = sizeof(dmti);
if(helper->read(helper->format, &dmti, s) != s)
return -1;
dmti.start_addr = _htol32(dmti.start_addr);
dmti.insn_count = _htol16(dmti.insn_count);
dmti.handler_off = _htol16(dmti.handler_off);
}
seek = helper->seek(helper->format, 0, SEEK_CUR);
if(helper->decode(helper->format, NULL, seek, 8, seek)
!= 0)
return -1;
}
}
return 0;
return (helper->set_section(helper->format, id, ".text", offset, size,
0) == id) ? 0 : -1;
}
static int _decode_map_method_id(FormatPlugin * format, off_t offset,
@ -337,6 +297,9 @@ static int _decode_map_method_id(FormatPlugin * format, off_t offset,
AsmString * string;
char const * name;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s(%ld, %lu)\n", __func__, offset, size);
#endif
if(dex->dmii != NULL)
return 0; /* already parsed */
if(helper->seek(helper->format, offset, SEEK_SET) != offset)
@ -372,6 +335,9 @@ static int _decode_map_string_id(FormatPlugin * format, off_t offset,
size_t i;
uint8_t u8;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s(%ld, %lu)\n", __func__, offset, size);
#endif
if(helper->seek(helper->format, offset, SEEK_SET) != offset)
return -1;
s = sizeof(*dsii) * size;
@ -396,3 +362,70 @@ static int _decode_map_string_id(FormatPlugin * format, off_t offset,
free(dsii);
return (i == size) ? 0 : -1;
}
/* dex_decode_section */
static int _dex_decode_section(FormatPlugin * format, AsmSection * section,
ArchInstructionCall ** calls, size_t * calls_cnt)
{
FormatPluginHelper * helper = format->helper;
DexMapCodeItem dmci;
size_t i;
off_t seek;
size_t j;
DexMapTryItem dmti;
ssize_t s;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
if(helper->seek(helper->format, section->offset, SEEK_SET)
!= section->offset)
return -1;
for(i = 0; i < section->size; i++)
{
s = sizeof(dmci);
if(helper->read(helper->format, &dmci, s) != s)
return -1;
dmci.registers_size = _htol16(dmci.registers_size);
dmci.ins_size = _htol16(dmci.ins_size);
dmci.outs_size = _htol16(dmci.outs_size);
dmci.tries_size = _htol16(dmci.tries_size);
dmci.debug_info_off = _htol32(dmci.debug_info_off);
dmci.insns_size = _htol32(dmci.insns_size);
seek = helper->seek(helper->format, 0, SEEK_CUR);
if(helper->decode(helper->format, seek, dmci.insns_size * 2,
seek, calls, calls_cnt) != 0)
return -1;
/* skip padding and try_items */
seek = (dmci.insns_size & 0x1) == 0x1 ? 2 : 0;
#ifdef DEBUG
fprintf(stderr, "DEBUG: code item %lu, offset 0x%lx"
", registers 0x%x, size 0x%x, debug @0x%x"
", tries 0x%x, seek 0x%lx\n", i,
helper->seek(helper->format, 0, SEEK_CUR),
dmci.registers_size, dmci.insns_size * 2,
dmci.debug_info_off, dmci.tries_size, seek);
#endif
if(seek != 0 && helper->seek(helper->format, seek, SEEK_CUR)
< 0)
return -1;
if(dmci.tries_size > 0)
{
for(j = 0; j < dmci.tries_size; j++)
{
s = sizeof(dmti);
if(helper->read(helper->format, &dmti, s) != s)
return -1;
dmti.start_addr = _htol32(dmti.start_addr);
dmti.insn_count = _htol16(dmti.insn_count);
dmti.handler_off = _htol16(dmti.handler_off);
}
seek = helper->seek(helper->format, 0, SEEK_CUR);
if(helper->decode(helper->format, seek, 8, seek, calls,
calls_cnt) != 0)
return -1;
}
}
return 0;
}

View File

@ -12,6 +12,9 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* FIXME:
* - ensure the first section output is of type SHN_UNDEF
* - use set_string() to store and remember strings? */
@ -79,6 +82,8 @@ static char const * _elf_detect(FormatPlugin * format);
static int _elf_decode(FormatPlugin * format, int raw);
static int _elf_decode32(FormatPlugin * format, int raw);
static int _elf_decode64(FormatPlugin * format, int raw);
static int _elf_decode_section(FormatPlugin * format, AsmSection * section,
ArchInstructionCall ** calls, size_t * calls_cnt);
/* ELF32 */
static int _init_32(FormatPlugin * format);
@ -106,11 +111,15 @@ static ElfArch elf_arch[] =
{
{ "amd64", EM_X86_64, ELFCLASS64, ELFDATA2LSB, 0x4 },
{ "arm", EM_ARM, ELFCLASS32, ELFDATA2LSB, 0x0 },
{ "armeb", EM_ARM, ELFCLASS32, ELFDATA2MSB, 0x0 },
{ "armel", EM_ARM, ELFCLASS32, ELFDATA2LSB, 0x0 },
{ "i386", EM_386, ELFCLASS32, ELFDATA2LSB, 0x4 },
{ "i486", EM_386, ELFCLASS32, ELFDATA2LSB, 0x4 },
{ "i586", EM_386, ELFCLASS32, ELFDATA2LSB, 0x4 },
{ "i686", EM_386, ELFCLASS32, ELFDATA2LSB, 0x4 },
{ "mips", EM_MIPS, ELFCLASS32, ELFDATA2MSB, 0x0 },
{ "mipseb", EM_MIPS, ELFCLASS32, ELFDATA2MSB, 0x0 },
{ "mipsel", EM_MIPS, ELFCLASS32, ELFDATA2LSB, 0x0 },
{ "sparc", EM_SPARC, ELFCLASS32, ELFDATA2MSB, 0x0 },
{ "sparc64", EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, 0x0 },
{ NULL, '\0', '\0', '\0', 0x0 }
@ -174,6 +183,7 @@ FormatPlugin format_plugin =
NULL,
_elf_detect,
_elf_decode,
_elf_decode_section,
NULL
};
@ -202,7 +212,9 @@ static int _elf_init(FormatPlugin * format, char const * arch)
return -1;
format->priv = elf;
elf->es32 = NULL;
elf->es32_cnt = 0;
elf->es64 = NULL;
elf->es64_cnt = 0;
if(arch == NULL)
{
elf->arch = NULL;
@ -336,6 +348,9 @@ static char const * _detect_64(FormatPlugin * format, Elf64_Ehdr * ehdr)
/* elf_decode */
static int _elf_decode(FormatPlugin * format, int raw)
{
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s(%d)\n", __func__, raw);
#endif
if(_elf_detect(format) == NULL)
return -1;
return format->decode(format, raw);
@ -394,16 +409,17 @@ static int _elf_decode32(FormatPlugin * format, int raw)
{
if(shdr[i].sh_name >= shstrtab_cnt)
continue;
if(raw || (shdr[i].sh_type == SHT_PROGBITS
&& shdr[i].sh_flags & SHF_EXECINSTR))
helper->decode(helper->format,
if((raw || (shdr[i].sh_type == SHT_PROGBITS && shdr[i].sh_flags
& SHF_EXECINSTR))
&& helper->set_section(helper->format, i,
&shstrtab[shdr[i].sh_name],
shdr[i].sh_offset, shdr[i].sh_size,
base + shdr[i].sh_offset);
base + shdr[i].sh_offset) < 0)
break;
}
free(shstrtab);
free(shdr);
return 0;
return (i == ehdr.e_shnum) ? 0 : -1;
}
static int _decode32_shdr(FormatPlugin * format, Elf32_Ehdr * ehdr,
@ -583,16 +599,17 @@ static int _elf_decode64(FormatPlugin * format, int raw)
{
if(shdr[i].sh_name >= shstrtab_cnt)
continue;
if(raw || (shdr[i].sh_type == SHT_PROGBITS
&& shdr[i].sh_flags & SHF_EXECINSTR))
helper->decode(helper->format,
if((raw || (shdr[i].sh_type == SHT_PROGBITS && shdr[i].sh_flags
& SHF_EXECINSTR))
&& helper->set_section(helper->format, i,
&shstrtab[shdr[i].sh_name],
shdr[i].sh_offset, shdr[i].sh_size,
base + shdr[i].sh_offset);
base + shdr[i].sh_offset) < 0)
break;
}
free(shstrtab);
free(shdr);
return 0;
return (i == ehdr.e_shnum) ? 0 : -1;
}
static int _decode64_shdr(FormatPlugin * format, Elf64_Ehdr * ehdr,
@ -722,12 +739,26 @@ static int _decode64_symtab(FormatPlugin * format, Elf64_Shdr * shdr,
}
/* elf_decode_section */
static int _elf_decode_section(FormatPlugin * format, AsmSection * section,
ArchInstructionCall ** calls, size_t * calls_cnt)
{
FormatPluginHelper * helper = format->helper;
return helper->decode(helper->format, section->offset, section->size,
section->base, calls, calls_cnt);
}
/* section_values */
static ElfSectionValues * _section_values(char const * name)
{
ElfSectionValues * esv;
int cmp;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, name);
#endif
for(esv = elf_section_values; esv->name != NULL; esv++)
if((cmp = strcmp(esv->name, name)) == 0)
return esv;
@ -789,6 +820,9 @@ static int _exit_32(FormatPlugin * format)
FormatPluginHelper * helper = format->helper;
long offset;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
if(_section_32(format, ".shstrtab") != 0)
ret = -1;
else if(helper->write(helper->format, shstrtab.buf, shstrtab.cnt)
@ -813,6 +847,9 @@ static int _exit_32_phdr(FormatPlugin * format, Elf32_Off offset)
ElfArch * ea = elf->arch;
Elf32_Ehdr hdr;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
if(elf->es32_cnt == 0)
return 0;
if(helper->seek(helper->format, 0, SEEK_SET) != 0)
@ -848,6 +885,9 @@ static int _exit_32_shdr(FormatPlugin * format, Elf32_Off offset)
Elf32_Shdr hdr;
int i;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
if(helper->seek(helper->format, 0, SEEK_END) < 0)
return _elf_error(format);
memset(&hdr, 0, sizeof(hdr));
@ -865,6 +905,9 @@ static int _exit_32_shdr(FormatPlugin * format, Elf32_Off offset)
return -1;
for(i = 0; i < elf->es32_cnt; i++)
{
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s() %d\n", __func__, i);
#endif
if(i + 1 == elf->es32_cnt)
es32[i].sh_size = offset - es32[i].sh_offset;
else
@ -895,6 +938,9 @@ static int _section_32(FormatPlugin * format, char const * name)
ElfSectionValues * esv;
long offset;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, name);
#endif
if((ss = _elfstrtab_set(format, &shstrtab, name)) < 0)
return -1;
if((p = realloc(elf->es32, sizeof(*p) * (elf->es32_cnt + 1))) == NULL)
@ -906,8 +952,14 @@ static int _section_32(FormatPlugin * format, char const * name)
p->sh_name = ss;
p->sh_type = esv->type;
p->sh_flags = esv->flags;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s() %s\n", __func__, "before seek()");
#endif
if((offset = helper->seek(helper->format, 0, SEEK_CUR)) < 0)
return -1;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s() %s\n", __func__, "after seek()");
#endif
p->sh_offset = offset;
p->sh_link = SHN_UNDEF; /* FIXME */
return 0;
@ -1130,8 +1182,14 @@ static int _section_64(FormatPlugin * format, char const * name)
p->sh_name = ss;
p->sh_type = esv->type;
p->sh_flags = esv->flags;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s() %s\n", __func__, "before seek()");
#endif
if((offset = helper->seek(helper->format, 0, SEEK_CUR)) < 0)
return -1;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s() %s\n", __func__, "after seek()");
#endif
p->sh_offset = offset;
p->sh_link = SHN_UNDEF; /* FIXME */
return 0;

View File

@ -25,6 +25,8 @@
/* prototypes */
/* plug-in */
static int _flat_decode(FormatPlugin * format, int raw);
static int _flat_decode_section(FormatPlugin * format, AsmSection * section,
ArchInstructionCall ** calls, size_t * calls_cnt);
/* public */
@ -41,6 +43,7 @@ FormatPlugin format_plugin =
NULL,
NULL,
_flat_decode,
_flat_decode_section,
NULL
};
@ -54,7 +57,21 @@ static int _flat_decode(FormatPlugin * format, int raw)
FormatPluginHelper * helper = format->helper;
off_t offset;
if((offset = helper->seek(helper->format, 0, SEEK_END)) < 0)
if((offset = helper->seek(helper->format, 0, SEEK_END)) >= 0)
return helper->set_section(helper->format, 0, ".text", 0,
offset, 0);
return -1;
return helper->decode(helper->format, ".data", 0, offset, 0);
}
/* flat_decode_section */
static int _flat_decode_section(FormatPlugin * format, AsmSection * section,
ArchInstructionCall ** calls, size_t * calls_cnt)
{
FormatPluginHelper * helper = format->helper;
if(section->id != 0)
return -1;
return helper->decode(helper->format, section->offset, section->size,
section->base, calls, calls_cnt);
}

View File

@ -106,6 +106,8 @@ static int _java_init(FormatPlugin * format, char const * arch);
static int _java_exit(FormatPlugin * format);
static char const * _java_detect(FormatPlugin * format);
static int _java_decode(FormatPlugin * format, int raw);
static int _java_decode_section(FormatPlugin * format, AsmSection * section,
ArchInstructionCall ** calls, size_t * calls_cnt);
/* public */
@ -123,6 +125,7 @@ FormatPlugin format_plugin =
NULL,
_java_detect,
_java_decode,
_java_decode_section,
NULL
};
@ -325,7 +328,8 @@ static int _java_decode(FormatPlugin * format, int raw)
|| (end = helper->seek(helper->format, 0, SEEK_END))
< 0)
return -1;
return helper->decode(helper->format, NULL, offset, end - offset, 0);
return helper->set_section(helper->format, 0, ".text", offset,
end - offset, 0);
}
static int _decode_skip_attributes(FormatPlugin * format, uint16_t cnt)
@ -448,3 +452,14 @@ static int _decode_skip_interfaces(FormatPlugin * format, uint16_t cnt)
return -1;
return 0;
}
/* java_decode_section */
static int _java_decode_section(FormatPlugin * format, AsmSection * section,
ArchInstructionCall ** calls, size_t * calls_cnt)
{
FormatPluginHelper * helper = format->helper;
return helper->decode(helper->format, section->offset, section->size,
section->base, calls, calls_cnt);
}

View File

@ -213,6 +213,8 @@ static char const _pe_header_signature[4] = "PE\0\0";
static int _pe_init(FormatPlugin * format, char const * arch);
static char const * _pe_detect(FormatPlugin * format);
static int _pe_decode(FormatPlugin * format, int raw);
static int _pe_decode_section(FormatPlugin * format, AsmSection * section,
ArchInstructionCall ** calls, size_t * calls_cnt);
/* useful */
static char const * _pe_get_arch(uint16_t machine);
@ -233,6 +235,7 @@ FormatPlugin format_plugin =
NULL,
_pe_detect,
_pe_decode,
_pe_decode_section,
NULL
};
@ -385,7 +388,7 @@ static int _pe_decode(FormatPlugin * format, int raw)
i) != 0)
break; /* XXX report error */
}
/* read and decode each section */
/* read and record each section */
offset = pm.offset + sizeof(_pe_header_signature) + sizeof(ph)
+ ph.opthdr_size;
if(ph.opthdr_size != 0 && helper->seek(helper->format, offset, SEEK_SET)
@ -409,8 +412,9 @@ static int _pe_decode(FormatPlugin * format, int raw)
/* the $ sign has a special meaning for the linker */
if((q = strchr(psh.name, '$')) != NULL)
*q = '\0';
if(helper->decode(helper->format, psh.name, psh.raw_offset,
psh.raw_size, psh.vaddr + base) != 0)
if(helper->set_section(helper->format, i, psh.name,
psh.raw_offset, psh.raw_size,
psh.vaddr + base) != 0)
break;
if(helper->seek(helper->format, offset, SEEK_SET) != offset)
break;
@ -554,6 +558,17 @@ static char * _decode_string(FormatPlugin * format, off_t offset)
}
/* pe_decode_section */
static int _pe_decode_section(FormatPlugin * format, AsmSection * section,
ArchInstructionCall ** calls, size_t * calls_cnt)
{
FormatPluginHelper * helper = format->helper;
return helper->decode(helper->format, section->offset, section->size,
section->base, calls, calls_cnt);
}
/* accessors */
/* pe_get_arch */
static char const * _pe_get_arch(uint16_t machine)

View File

@ -31,6 +31,13 @@
# define ASM_FILENAME_DEFAULT "a.out"
/* prototypes */
static int _asm(AsmPrefs * prefs, char const * arch, char const * format,
char const * infile, char const * outfile);
static int _asm_string(AsmPrefs * prefs, char const * arch, char const * format,
char const * outfile, char const * string);
/* functions */
/* asm */
static int _asm(AsmPrefs * prefs, char const * arch, char const * format,
@ -48,10 +55,27 @@ static int _asm(AsmPrefs * prefs, char const * arch, char const * format,
}
/* asm_string */
static int _asm_string(AsmPrefs * prefs, char const * arch, char const * format,
char const * outfile, char const * string)
{
int ret = 0;
Asm * a;
if((a = asm_new(arch, format)) == NULL)
return error_print(PACKAGE);
if(asm_assemble_string(a, prefs, outfile, string) != 0)
ret = error_print(PACKAGE);
asm_delete(a);
return ret;
}
/* usage */
static unsigned int _usage(void)
{
fputs("Usage: asm [-D name][-a arch][-f format][-o file] file\n"
" asm [-D name][-a arch][-f format][-o file] -s string\n"
" asm -l\n"
" -D Set a variable in the pre-processor\n"
" -a Target architecture\n"
@ -74,9 +98,10 @@ int main(int argc, char * argv[])
char * outfile = ASM_FILENAME_DEFAULT;
char const * arch = NULL;
char const * format = NULL;
char const * string = NULL;
memset(&prefs, 0, sizeof(prefs));
while((o = getopt(argc, argv, "a:D:f:o:l")) != -1)
while((o = getopt(argc, argv, "a:D:f:o:ls:")) != -1)
switch(o)
{
case 'a':
@ -94,21 +119,35 @@ int main(int argc, char * argv[])
break;
case 'l':
o = 0;
if(asm_plugin_list(APT_ARCH) != 0)
if(asm_plugin_list(APT_ARCH, 0) != 0)
o = error_print(PACKAGE);
else
putchar('\n');
if(asm_plugin_list(APT_FORMAT) != 0)
if(asm_plugin_list(APT_FORMAT, 0) != 0)
o = error_print(PACKAGE);
return (o == 0) ? 0 : 2;
case 's':
string = optarg;
break;
default:
free(prefs.defines);
return _usage();
}
if(optind + 1 != argc)
return _usage();
ret = _asm(&prefs, arch, format, argv[optind], outfile);
if(string != NULL)
{
if(optind != argc)
ret = _usage();
else
ret = (_asm_string(&prefs, arch, format, outfile,
string) == 0) ? 0 : 2;
}
else if(optind == argc - 1)
ret = (_asm(&prefs, arch, format, argv[optind], outfile) == 0)
? 0 : 2;
else
ret = _usage();
free(prefs.defines);
return (ret == 0) ? 0 : 2;
return ret;
}
static int _main_add_define(AsmPrefs * prefs, char * define)

View File

@ -34,7 +34,7 @@ typedef struct _State
Token * token;
unsigned int error_cnt;
unsigned int warning_cnt;
Code * code;
AsmCode * code;
ArchInstructionCall call;
} State;
@ -157,6 +157,7 @@ static int _parser_error(State * state, char const * format, ...)
fputs("asm: ", stderr);
if(state->cpp != NULL && state->token != NULL)
/* FIXME will be wrong when string-based input is supported */
fprintf(stderr, "%s%s%u: ", cpp_get_filename(state->cpp),
", line ", token_get_line(state->token));
va_start(ap, format);
@ -174,6 +175,7 @@ static int _parser_warning(State * state, char const * format, ...)
fputs("asm: ", stderr);
if(state->cpp != NULL && state->token != NULL)
/* FIXME will be wrong when string-based input is supported */
fprintf(stderr, "%s%s%u: ", cpp_get_filename(state->cpp),
", line ", token_get_line(state->token));
va_start(ap, format);
@ -187,7 +189,7 @@ static int _parser_warning(State * state, char const * format, ...)
/* protected */
/* functions */
/* parser */
int parser(AsmPrefs * ap, Code * code, char const * infile)
int parser(AsmPrefs * ap, AsmCode * code, char const * infile)
{
CppPrefs prefs;
State state;
@ -217,6 +219,38 @@ int parser(AsmPrefs * ap, Code * code, char const * infile)
}
/* parser_string */
int parser_string(AsmPrefs * ap, AsmCode * code, char const * string)
{
CppPrefs prefs;
State state;
size_t i;
memset(&prefs, 0, sizeof(prefs));
#if 0
prefs.filename = infile;
#endif
prefs.filters = CPP_FILTER_COMMENT;
memset(&state, 0, sizeof(state));
state.code = code;
if((state.cpp = cpp_new(&prefs)) == NULL)
return -1;
if(ap != NULL)
for(i = 0; i < ap->defines_cnt; i++)
/* FIXME check errors */
cpp_define_add(state.cpp, ap->defines[i], NULL);
if(_parser_scan(&state) != 0)
return _parser_error(&state, "%s", error_get());
if(_program(&state) != 0)
error_set_code(1, "%s%u%s%u%s", "Compilation failed with ",
state.error_cnt, " error(s) and ",
state.warning_cnt, " warning(s)");
if(state.token != NULL)
token_delete(state.token);
return state.error_cnt;
}
/* grammar */
/* program */
static int _program(State * state)
@ -318,7 +352,7 @@ static int _section(State * state)
#ifdef DEBUG
fprintf(stderr, "%s\"%s\"\n", "DEBUG: section ", section);
#endif
if(code_section(state->code, section) != 0)
if(asmcode_section(state->code, section) != 0)
ret |= _parser_error(state, "%s", error_get());
free(section);
}
@ -376,7 +410,7 @@ static int _function(State * state)
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s \"%s\"\n", "function", function);
#endif
if(code_function(state->code, function) != 0)
if(asmcode_function(state->code, function) != 0)
ret |= _parser_error(state, "%s", error_get());
free(function);
}
@ -403,7 +437,7 @@ static int _instruction(State * state)
}
if(state->call.name != NULL)
{
if(code_instruction(state->code, &state->call) != 0)
if(asmcode_instruction(state->code, &state->call) != 0)
ret |= _parser_error(state, "%s", error_get());
free(state->call.name);
}

View File

@ -18,9 +18,11 @@
#ifndef ASM_PARSER_H
# define ASM_PARSER_H
# include "Asm/asm.h"
# include "code.h"
int parser(AsmPrefs * prefs, Code * code, char const * infile);
int parser(AsmPrefs * prefs, AsmCode * code, char const * infile);
int parser_string(AsmPrefs * prefs, AsmCode * code, char const * string);
#endif /* !ASM_PARSER_H */

View File

@ -1,4 +1,4 @@
TARGETS = amd64.o arm.o dalvik.o i386.o i386_real.o i486.o i586.o i686.o mips.o java.o sparc.o sparc64.o yasep.o
TARGETS = amd64.o arm.o armeb.o armel.o dalvik.o i386.o i386_real.o i486.o i586.o i686.o mips.o mipseb.o mipsel.o java.o sparc.o sparc64.o yasep.o
PREFIX = /usr/local
DESTDIR =
BINDIR = $(PREFIX)/bin
@ -18,6 +18,12 @@ amd64.o_ASFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(ASFLAGS) -a amd64
arm.o_OBJS = arm.o
arm.o_ASFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(ASFLAGS) -a arm
armeb.o_OBJS = armeb.o
armeb.o_ASFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(ASFLAGS) -a armeb
armel.o_OBJS = armel.o
armel.o_ASFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(ASFLAGS) -a armel
dalvik.o_OBJS = dalvik.o
dalvik.o_ASFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(ASFLAGS) -a dalvik -f flat
@ -39,6 +45,12 @@ i686.o_ASFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(ASFLAGS) -a i686
mips.o_OBJS = mips.o
mips.o_ASFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(ASFLAGS) -a mips
mipseb.o_OBJS = mipseb.o
mipseb.o_ASFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(ASFLAGS) -a mipseb
mipsel.o_OBJS = mipsel.o
mipsel.o_ASFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(ASFLAGS) -a mipsel
java.o_OBJS = java.o
java.o_ASFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(ASFLAGS) -a java -f flat
@ -57,6 +69,12 @@ amd64.o: amd64.S ../src/asm
arm.o: arm.S ../src/asm
$(AS) $(arm.o_ASFLAGS) -o arm.o arm.S
armeb.o: armeb.S arm.S ../src/asm
$(AS) $(armeb.o_ASFLAGS) -o armeb.o armeb.S
armel.o: armel.S arm.S ../src/asm
$(AS) $(armel.o_ASFLAGS) -o armel.o armel.S
dalvik.o: dalvik.S ../src/asm
$(AS) $(dalvik.o_ASFLAGS) -o dalvik.o dalvik.S
@ -78,6 +96,12 @@ i686.o: i686.S ../src/asm
mips.o: mips.S ../src/asm
$(AS) $(mips.o_ASFLAGS) -o mips.o mips.S
mipseb.o: mipseb.S mips.S ../src/asm
$(AS) $(mipseb.o_ASFLAGS) -o mipseb.o mipseb.S
mipsel.o: mipsel.S mips.S ../src/asm
$(AS) $(mipsel.o_ASFLAGS) -o mipsel.o mipsel.S
java.o: java.S ../src/asm
$(AS) $(java.o_ASFLAGS) -o java.o java.S
@ -91,7 +115,7 @@ yasep.o: yasep.S ../src/asm
$(AS) $(yasep.o_ASFLAGS) -o yasep.o yasep.S
clean:
$(RM) -- $(amd64.o_OBJS) $(arm.o_OBJS) $(dalvik.o_OBJS) $(i386.o_OBJS) $(i386_real.o_OBJS) $(i486.o_OBJS) $(i586.o_OBJS) $(i686.o_OBJS) $(mips.o_OBJS) $(java.o_OBJS) $(sparc.o_OBJS) $(sparc64.o_OBJS) $(yasep.o_OBJS)
$(RM) -- $(amd64.o_OBJS) $(arm.o_OBJS) $(armeb.o_OBJS) $(armel.o_OBJS) $(dalvik.o_OBJS) $(i386.o_OBJS) $(i386_real.o_OBJS) $(i486.o_OBJS) $(i586.o_OBJS) $(i686.o_OBJS) $(mips.o_OBJS) $(mipseb.o_OBJS) $(mipsel.o_OBJS) $(java.o_OBJS) $(sparc.o_OBJS) $(sparc64.o_OBJS) $(yasep.o_OBJS)
distclean: clean
$(RM) -- $(TARGETS)

2
test/armeb.S Normal file
View File

@ -0,0 +1,2 @@
/* $Id$ */
#include "arm.S"

2
test/armel.S Normal file
View File

@ -0,0 +1,2 @@
/* $Id$ */
#include "arm.S"

2
test/mipseb.S Normal file
View File

@ -0,0 +1,2 @@
/* $Id$ */
#include "mips.S"

2
test/mipsel.S Normal file
View File

@ -0,0 +1,2 @@
/* $Id$ */
#include "mips.S"

View File

@ -1,4 +1,4 @@
targets=amd64.o,arm.o,dalvik.o,i386.o,i386_real.o,i486.o,i586.o,i686.o,mips.o,java.o,sparc.o,sparc64.o,yasep.o
targets=amd64.o,arm.o,armeb.o,armel.o,dalvik.o,i386.o,i386_real.o,i486.o,i586.o,i686.o,mips.o,mipseb.o,mipsel.o,java.o,sparc.o,sparc64.o,yasep.o
as=../src/asm-static
dist=Makefile
@ -18,6 +18,22 @@ sources=arm.S
asflags=-a arm
depends=../src/asm
[armeb.o]
type=object
sources=armeb.S
[armeb.S]
asflags=-a armeb
depends=arm.S,../src/asm
[armel.o]
type=object
sources=armel.S
[armel.S]
asflags=-a armel
depends=arm.S,../src/asm
[dalvik.o]
type=object
sources=dalvik.S
@ -82,6 +98,22 @@ sources=mips.S
asflags=-a mips
depends=../src/asm
[mipseb.o]
type=object
sources=mipseb.S
[mipseb.S]
asflags=-a mipseb
depends=mips.S,../src/asm
[mipsel.o]
type=object
sources=mipsel.S
[mipsel.S]
asflags=-a mipsel
depends=mips.S,../src/asm
[sparc.o]
type=object
sources=sparc.S