Major re-design to facilitate code re-use from the library
This commit is contained in:
parent
a5423dbc95
commit
389f82aef4
9
Makefile
9
Makefile
@ -33,6 +33,7 @@ dist:
|
|||||||
$(PACKAGE)-$(VERSION)/include/project.conf \
|
$(PACKAGE)-$(VERSION)/include/project.conf \
|
||||||
$(PACKAGE)-$(VERSION)/include/Asm/arch.h \
|
$(PACKAGE)-$(VERSION)/include/Asm/arch.h \
|
||||||
$(PACKAGE)-$(VERSION)/include/Asm/asm.h \
|
$(PACKAGE)-$(VERSION)/include/Asm/asm.h \
|
||||||
|
$(PACKAGE)-$(VERSION)/include/Asm/code.h \
|
||||||
$(PACKAGE)-$(VERSION)/include/Asm/common.h \
|
$(PACKAGE)-$(VERSION)/include/Asm/common.h \
|
||||||
$(PACKAGE)-$(VERSION)/include/Asm/format.h \
|
$(PACKAGE)-$(VERSION)/include/Asm/format.h \
|
||||||
$(PACKAGE)-$(VERSION)/include/Asm/Makefile \
|
$(PACKAGE)-$(VERSION)/include/Asm/Makefile \
|
||||||
@ -55,6 +56,8 @@ dist:
|
|||||||
$(PACKAGE)-$(VERSION)/src/project.conf \
|
$(PACKAGE)-$(VERSION)/src/project.conf \
|
||||||
$(PACKAGE)-$(VERSION)/src/arch/amd64.c \
|
$(PACKAGE)-$(VERSION)/src/arch/amd64.c \
|
||||||
$(PACKAGE)-$(VERSION)/src/arch/arm.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/dalvik.c \
|
||||||
$(PACKAGE)-$(VERSION)/src/arch/i386.c \
|
$(PACKAGE)-$(VERSION)/src/arch/i386.c \
|
||||||
$(PACKAGE)-$(VERSION)/src/arch/i386_real.c \
|
$(PACKAGE)-$(VERSION)/src/arch/i386_real.c \
|
||||||
@ -63,6 +66,8 @@ dist:
|
|||||||
$(PACKAGE)-$(VERSION)/src/arch/i686.c \
|
$(PACKAGE)-$(VERSION)/src/arch/i686.c \
|
||||||
$(PACKAGE)-$(VERSION)/src/arch/java.c \
|
$(PACKAGE)-$(VERSION)/src/arch/java.c \
|
||||||
$(PACKAGE)-$(VERSION)/src/arch/mips.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/sparc.c \
|
||||||
$(PACKAGE)-$(VERSION)/src/arch/sparc64.c \
|
$(PACKAGE)-$(VERSION)/src/arch/sparc64.c \
|
||||||
$(PACKAGE)-$(VERSION)/src/arch/yasep.c \
|
$(PACKAGE)-$(VERSION)/src/arch/yasep.c \
|
||||||
@ -101,6 +106,8 @@ dist:
|
|||||||
$(PACKAGE)-$(VERSION)/src/format/project.conf \
|
$(PACKAGE)-$(VERSION)/src/format/project.conf \
|
||||||
$(PACKAGE)-$(VERSION)/test/amd64.S \
|
$(PACKAGE)-$(VERSION)/test/amd64.S \
|
||||||
$(PACKAGE)-$(VERSION)/test/arm.S \
|
$(PACKAGE)-$(VERSION)/test/arm.S \
|
||||||
|
$(PACKAGE)-$(VERSION)/test/armeb.S \
|
||||||
|
$(PACKAGE)-$(VERSION)/test/armel.S \
|
||||||
$(PACKAGE)-$(VERSION)/test/dalvik.S \
|
$(PACKAGE)-$(VERSION)/test/dalvik.S \
|
||||||
$(PACKAGE)-$(VERSION)/test/i386.S \
|
$(PACKAGE)-$(VERSION)/test/i386.S \
|
||||||
$(PACKAGE)-$(VERSION)/test/i386_real.S \
|
$(PACKAGE)-$(VERSION)/test/i386_real.S \
|
||||||
@ -108,6 +115,8 @@ dist:
|
|||||||
$(PACKAGE)-$(VERSION)/test/i586.S \
|
$(PACKAGE)-$(VERSION)/test/i586.S \
|
||||||
$(PACKAGE)-$(VERSION)/test/i686.S \
|
$(PACKAGE)-$(VERSION)/test/i686.S \
|
||||||
$(PACKAGE)-$(VERSION)/test/mips.S \
|
$(PACKAGE)-$(VERSION)/test/mips.S \
|
||||||
|
$(PACKAGE)-$(VERSION)/test/mipseb.S \
|
||||||
|
$(PACKAGE)-$(VERSION)/test/mipsel.S \
|
||||||
$(PACKAGE)-$(VERSION)/test/java.S \
|
$(PACKAGE)-$(VERSION)/test/java.S \
|
||||||
$(PACKAGE)-$(VERSION)/test/sparc.S \
|
$(PACKAGE)-$(VERSION)/test/sparc.S \
|
||||||
$(PACKAGE)-$(VERSION)/test/sparc64.S \
|
$(PACKAGE)-$(VERSION)/test/sparc64.S \
|
||||||
|
@ -27,9 +27,9 @@
|
|||||||
# define _LITTLE_ENDIAN __LITTLE_ENDIAN
|
# define _LITTLE_ENDIAN __LITTLE_ENDIAN
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# include "Asm/common.h"
|
|
||||||
# include "Asm/arch.h"
|
# include "Asm/arch.h"
|
||||||
# include "Asm/asm.h"
|
# include "Asm/asm.h"
|
||||||
|
# include "Asm/code.h"
|
||||||
# include "Asm/format.h"
|
# include "Asm/format.h"
|
||||||
|
|
||||||
|
|
||||||
@ -70,5 +70,4 @@
|
|||||||
# warning "Could not determine endian on your system"
|
# warning "Could not determine endian on your system"
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
|
||||||
#endif /* !DEVEL_ASM_H */
|
#endif /* !DEVEL_ASM_H */
|
||||||
|
@ -19,6 +19,8 @@ install:
|
|||||||
$(MKDIR) $(DESTDIR)$(PREFIX)/include/Devel/Asm
|
$(MKDIR) $(DESTDIR)$(PREFIX)/include/Devel/Asm
|
||||||
$(INSTALL) -m 0644 -- asm.h $(DESTDIR)$(PREFIX)/include/Devel/Asm/asm.h
|
$(INSTALL) -m 0644 -- asm.h $(DESTDIR)$(PREFIX)/include/Devel/Asm/asm.h
|
||||||
$(MKDIR) $(DESTDIR)$(PREFIX)/include/Devel/Asm
|
$(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
|
$(INSTALL) -m 0644 -- common.h $(DESTDIR)$(PREFIX)/include/Devel/Asm/common.h
|
||||||
$(MKDIR) $(DESTDIR)$(PREFIX)/include/Devel/Asm
|
$(MKDIR) $(DESTDIR)$(PREFIX)/include/Devel/Asm
|
||||||
$(INSTALL) -m 0644 -- format.h $(DESTDIR)$(PREFIX)/include/Devel/Asm/format.h
|
$(INSTALL) -m 0644 -- format.h $(DESTDIR)$(PREFIX)/include/Devel/Asm/format.h
|
||||||
@ -26,6 +28,7 @@ install:
|
|||||||
uninstall:
|
uninstall:
|
||||||
$(RM) -- $(DESTDIR)$(PREFIX)/include/Devel/Asm/arch.h
|
$(RM) -- $(DESTDIR)$(PREFIX)/include/Devel/Asm/arch.h
|
||||||
$(RM) -- $(DESTDIR)$(PREFIX)/include/Devel/Asm/asm.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/common.h
|
||||||
$(RM) -- $(DESTDIR)$(PREFIX)/include/Devel/Asm/format.h
|
$(RM) -- $(DESTDIR)$(PREFIX)/include/Devel/Asm/format.h
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
# include <stdint.h>
|
# include <stdint.h>
|
||||||
# include "asm.h"
|
# include "common.h"
|
||||||
|
|
||||||
|
|
||||||
/* AsmArch */
|
/* AsmArch */
|
||||||
@ -198,14 +198,14 @@ typedef struct _ArchPluginHelper
|
|||||||
/* callbacks */
|
/* callbacks */
|
||||||
/* accessors */
|
/* accessors */
|
||||||
char const * (*get_filename)(Arch * arch);
|
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,
|
ArchInstruction * (*get_instruction_by_opcode)(Arch * arch,
|
||||||
uint8_t size, uint32_t opcode);
|
uint8_t size, uint32_t opcode);
|
||||||
ArchRegister * (*get_register_by_id_size)(Arch * arch, uint32_t id,
|
ArchRegister * (*get_register_by_id_size)(Arch * arch, uint32_t id,
|
||||||
uint32_t size);
|
uint32_t size);
|
||||||
ArchRegister * (*get_register_by_name_size)(Arch * arch,
|
ArchRegister * (*get_register_by_name_size)(Arch * arch,
|
||||||
char const * name, uint32_t size);
|
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 */
|
/* assembly */
|
||||||
ssize_t (*write)(Arch * arch, void const * buf, size_t size);
|
ssize_t (*write)(Arch * arch, void const * buf, size_t size);
|
||||||
@ -230,7 +230,7 @@ struct _ArchPlugin
|
|||||||
|
|
||||||
int (*init)(ArchPlugin * arch);
|
int (*init)(ArchPlugin * arch);
|
||||||
void (*exit)(ArchPlugin * arch);
|
void (*exit)(ArchPlugin * arch);
|
||||||
int (*write)(ArchPlugin * arch, ArchInstruction * instruction,
|
int (*encode)(ArchPlugin * arch, ArchInstruction * instruction,
|
||||||
ArchInstructionCall * call);
|
ArchInstructionCall * call);
|
||||||
int (*decode)(ArchPlugin * arch, ArchInstructionCall * call);
|
int (*decode)(ArchPlugin * arch, ArchInstructionCall * call);
|
||||||
};
|
};
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#ifndef DEVEL_ASM_ASM_H
|
#ifndef DEVEL_ASM_ASM_H
|
||||||
# define DEVEL_ASM_ASM_H
|
# define DEVEL_ASM_ASM_H
|
||||||
|
|
||||||
# include "common.h"
|
# include "code.h"
|
||||||
|
|
||||||
|
|
||||||
/* Asm */
|
/* Asm */
|
||||||
@ -47,24 +47,6 @@ int asm_set_arch(Asm * a, char const * arch);
|
|||||||
char const * asm_get_format(Asm * a);
|
char const * asm_get_format(Asm * a);
|
||||||
int asm_set_format(Asm * a, char const * format);
|
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 */
|
/* useful */
|
||||||
/* detection */
|
/* 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, ...);
|
int asm_instruction(Asm * a, char const * name, unsigned int operands_cnt, ...);
|
||||||
|
|
||||||
/* deassemble */
|
/* deassemble */
|
||||||
int asm_deassemble(Asm * a, char const * buffer, size_t size);
|
AsmCode * asm_deassemble(Asm * a, char const * buffer, size_t size,
|
||||||
int asm_open_deassemble(Asm * a, char const * filename, int raw);
|
ArchInstructionCall ** calls, size_t * calls_cnt);
|
||||||
|
AsmCode * asm_open_deassemble(Asm * a, char const * filename, int raw);
|
||||||
|
|
||||||
/* plug-in helpers */
|
/* 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
76
include/Asm/code.h
Normal 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 */
|
@ -23,28 +23,37 @@
|
|||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
/* types */
|
/* types */
|
||||||
typedef unsigned int AsmId;
|
typedef int AsmElementId;
|
||||||
|
|
||||||
typedef struct _AsmFunction
|
typedef struct _AsmElement
|
||||||
{
|
{
|
||||||
AsmId id;
|
AsmElementId id;
|
||||||
char const * name;
|
char * name;
|
||||||
off_t offset;
|
off_t offset;
|
||||||
ssize_t size;
|
ssize_t size;
|
||||||
} AsmFunction;
|
off_t base;
|
||||||
|
} AsmElement;
|
||||||
|
|
||||||
typedef struct _AsmLabel
|
typedef enum _AsmElementType
|
||||||
{
|
{
|
||||||
char const * name;
|
AET_FUNCTION,
|
||||||
off_t offset;
|
AET_LABEL,
|
||||||
} AsmLabel;
|
AET_SECTION,
|
||||||
|
AET_STRING
|
||||||
|
} AsmElementType;
|
||||||
|
# define AET_LAST AET_STRING
|
||||||
|
# define AET_COUNT (AET_LAST + 1)
|
||||||
|
|
||||||
typedef struct _AsmString
|
typedef AsmElementId AsmFunctionId;
|
||||||
{
|
typedef struct _AsmElement AsmFunction;
|
||||||
int id;
|
|
||||||
char const * name;
|
|
||||||
off_t offset;
|
|
||||||
ssize_t length;
|
|
||||||
} AsmString;
|
|
||||||
|
|
||||||
#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 */
|
||||||
|
@ -35,6 +35,8 @@ typedef struct _FormatPluginHelper
|
|||||||
/* callbacks */
|
/* callbacks */
|
||||||
/* accessors */
|
/* accessors */
|
||||||
char const * (*get_filename)(Format * format);
|
char const * (*get_filename)(Format * format);
|
||||||
|
void (*get_functions)(Format * format, AsmFunction ** functions,
|
||||||
|
size_t * functions_cnt);
|
||||||
|
|
||||||
/* useful */
|
/* useful */
|
||||||
ssize_t (*read)(Format * format, void * buf, size_t size);
|
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);
|
ssize_t (*write)(Format * format, void const * buf, size_t size);
|
||||||
|
|
||||||
/* disassembly */
|
/* disassembly */
|
||||||
/* FIXME let a different architecture be specified in the callback */
|
/* FIXME let a different architecture be specified in the callback? */
|
||||||
AsmString * (*get_string_by_id)(Format * format, AsmId id);
|
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,
|
int (*set_function)(Format * format, int id, char const * name,
|
||||||
off_t offset, ssize_t size);
|
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,
|
int (*set_string)(Format * format, int id, char const * name,
|
||||||
off_t offset, ssize_t size);
|
off_t offset, ssize_t size);
|
||||||
int (*decode)(Format * format, char const * section,
|
int (*decode)(Format * format, off_t offset, size_t size, off_t base,
|
||||||
off_t offset, size_t size, off_t base);
|
ArchInstructionCall ** calls, size_t * calls_cnt);
|
||||||
} FormatPluginHelper;
|
} FormatPluginHelper;
|
||||||
|
|
||||||
struct _FormatPlugin
|
struct _FormatPlugin
|
||||||
@ -70,6 +75,8 @@ struct _FormatPlugin
|
|||||||
|
|
||||||
char const * (*detect)(FormatPlugin * format);
|
char const * (*detect)(FormatPlugin * format);
|
||||||
int (*decode)(FormatPlugin * format, int raw);
|
int (*decode)(FormatPlugin * format, int raw);
|
||||||
|
int (*decode_section)(FormatPlugin * format, AsmSection * section,
|
||||||
|
ArchInstructionCall ** calls, size_t * calls_cnt);
|
||||||
|
|
||||||
void * priv;
|
void * priv;
|
||||||
};
|
};
|
||||||
|
@ -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
|
dist=Makefile
|
||||||
|
|
||||||
[arch.h]
|
[arch.h]
|
||||||
@ -7,6 +7,9 @@ install=$(PREFIX)/include/Devel/Asm
|
|||||||
[asm.h]
|
[asm.h]
|
||||||
install=$(PREFIX)/include/Devel/Asm
|
install=$(PREFIX)/include/Devel/Asm
|
||||||
|
|
||||||
|
[code.h]
|
||||||
|
install=$(PREFIX)/include/Devel/Asm
|
||||||
|
|
||||||
[common.h]
|
[common.h]
|
||||||
install=$(PREFIX)/include/Devel/Asm
|
install=$(PREFIX)/include/Devel/Asm
|
||||||
|
|
||||||
|
72
src/arch.c
72
src/arch.c
@ -46,7 +46,7 @@ struct _Arch
|
|||||||
size_t registers_cnt;
|
size_t registers_cnt;
|
||||||
|
|
||||||
/* internal */
|
/* internal */
|
||||||
Code * code;
|
AsmCode * code;
|
||||||
off_t base;
|
off_t base;
|
||||||
char const * filename;
|
char const * filename;
|
||||||
FILE * fp;
|
FILE * fp;
|
||||||
@ -59,8 +59,8 @@ struct _Arch
|
|||||||
/* prototypes */
|
/* prototypes */
|
||||||
/* callbacks */
|
/* callbacks */
|
||||||
static char const * _arch_get_filename(Arch * arch);
|
static char const * _arch_get_filename(Arch * arch);
|
||||||
static AsmFunction * _arch_get_function_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, AsmId 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_peek(Arch * arch, void * buf, size_t size);
|
||||||
static ssize_t _arch_read(Arch * arch, void * buf, size_t size);
|
static ssize_t _arch_read(Arch * arch, void * buf, size_t size);
|
||||||
static ssize_t _arch_peek_buffer(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 */
|
/* accessors */
|
||||||
|
/* arch_can_decode */
|
||||||
|
int arch_can_decode(Arch * arch)
|
||||||
|
{
|
||||||
|
return arch->plugin->decode != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* arch_get_description */
|
/* arch_get_description */
|
||||||
ArchDescription * arch_get_description(Arch * arch)
|
ArchDescription * arch_get_description(Arch * arch)
|
||||||
{
|
{
|
||||||
@ -445,15 +452,18 @@ ArchRegister * arch_get_register_by_name_size(Arch * arch, char const * name,
|
|||||||
|
|
||||||
/* useful */
|
/* useful */
|
||||||
/* arch_decode */
|
/* arch_decode */
|
||||||
int arch_decode(Arch * arch, Code * code, ArchInstructionCall ** calls,
|
int arch_decode(Arch * arch, AsmCode * code, off_t base,
|
||||||
size_t * calls_cnt, off_t base)
|
ArchInstructionCall ** calls, size_t * calls_cnt)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
ArchInstructionCall * c = NULL;
|
ArchInstructionCall * c = *calls;
|
||||||
size_t c_cnt = 0;
|
size_t c_cnt = *calls_cnt;
|
||||||
ArchInstructionCall * p;
|
ArchInstructionCall * p;
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "DEBUG: %s(%ld)\n", __func__, base);
|
||||||
|
#endif
|
||||||
if(arch->plugin->decode == NULL)
|
if(arch->plugin->decode == NULL)
|
||||||
return -error_set_code(1, "%s: %s", arch->plugin->name,
|
return -error_set_code(1, "%s: %s", arch->plugin->name,
|
||||||
"Disassembly not supported");
|
"Disassembly not supported");
|
||||||
@ -477,22 +487,23 @@ int arch_decode(Arch * arch, Code * code, ArchInstructionCall ** calls,
|
|||||||
offset += p->size;
|
offset += p->size;
|
||||||
c_cnt++;
|
c_cnt++;
|
||||||
}
|
}
|
||||||
if(ret == 0)
|
|
||||||
{
|
|
||||||
*calls = c;
|
*calls = c;
|
||||||
*calls_cnt = c_cnt;
|
*calls_cnt = c_cnt;
|
||||||
}
|
|
||||||
arch->code = NULL;
|
arch->code = NULL;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* arch_decode_at */
|
/* arch_decode_at */
|
||||||
int arch_decode_at(Arch * arch, Code * code, ArchInstructionCall ** calls,
|
int arch_decode_at(Arch * arch, AsmCode * code, off_t offset, size_t size,
|
||||||
size_t * calls_cnt, off_t offset, size_t size, off_t base)
|
off_t base, ArchInstructionCall ** calls, size_t * calls_cnt)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "DEBUG: %s(%ld, %lu, %ld)\n", __func__, offset, size,
|
||||||
|
base);
|
||||||
|
#endif
|
||||||
/* FIXME this only works for files */
|
/* FIXME this only works for files */
|
||||||
if(arch->fp == NULL)
|
if(arch->fp == NULL)
|
||||||
return -error_set_code(1, "%s", strerror(ENOSYS));
|
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->code = code;
|
||||||
arch->buffer_pos = offset;
|
arch->buffer_pos = offset;
|
||||||
arch->buffer_cnt = offset + size;
|
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)
|
&& fseek(arch->fp, offset + size, SEEK_SET) != 0)
|
||||||
{
|
{
|
||||||
free(*calls); /* XXX the pointer was updated anyway... */
|
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 */
|
/* arch_exit */
|
||||||
int arch_exit(Arch * arch)
|
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 */
|
/* private */
|
||||||
/* callbacks */
|
/* callbacks */
|
||||||
/* arch_get_filename */
|
/* arch_get_filename */
|
||||||
@ -634,16 +645,16 @@ static char const * _arch_get_filename(Arch * arch)
|
|||||||
|
|
||||||
|
|
||||||
/* arch_get_function_by_id */
|
/* 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 */
|
/* 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;
|
ssize_t s;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#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
|
#endif
|
||||||
if((s = _arch_read(arch, buf, size)) == -1)
|
if((s = _arch_read(arch, buf, size)) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
@ -729,6 +740,9 @@ static off_t _arch_seek(Arch * arch, off_t offset, int whence)
|
|||||||
/* arch_seek_buffer */
|
/* arch_seek_buffer */
|
||||||
static off_t _arch_seek_buffer(Arch * arch, off_t offset, int whence)
|
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(whence == SEEK_SET)
|
||||||
{
|
{
|
||||||
if(offset < 0 || (size_t)offset >= arch->buffer_cnt)
|
if(offset < 0 || (size_t)offset >= arch->buffer_cnt)
|
||||||
|
14
src/arch.h
14
src/arch.h
@ -32,6 +32,8 @@ void arch_delete(Arch * arch);
|
|||||||
|
|
||||||
|
|
||||||
/* accessors */
|
/* accessors */
|
||||||
|
int arch_can_decode(Arch * arch);
|
||||||
|
|
||||||
ArchDescription * arch_get_description(Arch * arch);
|
ArchDescription * arch_get_description(Arch * arch);
|
||||||
char const * arch_get_format(Arch * arch);
|
char const * arch_get_format(Arch * arch);
|
||||||
char const * arch_get_name(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);
|
int arch_exit(Arch * arch);
|
||||||
|
|
||||||
/* assembly */
|
/* assembly */
|
||||||
int arch_write(Arch * arch, ArchInstruction * instruction,
|
int arch_encode(Arch * arch, ArchInstruction * instruction,
|
||||||
ArchInstructionCall * call);
|
ArchInstructionCall * call);
|
||||||
|
|
||||||
/* disassembly */
|
/* deassembly */
|
||||||
int arch_decode(Arch * arch, Code * code, ArchInstructionCall ** calls,
|
int arch_decode(Arch * arch, AsmCode * code, off_t base,
|
||||||
size_t * calls_cnt, off_t base);
|
ArchInstructionCall ** calls, size_t * calls_cnt);
|
||||||
int arch_decode_at(Arch * arch, Code * code, ArchInstructionCall ** calls,
|
int arch_decode_at(Arch * arch, AsmCode * code, off_t offset, size_t size,
|
||||||
size_t * calls_cnt, off_t offset, size_t size, off_t base);
|
off_t base, ArchInstructionCall ** calls, size_t * calls_cnt);
|
||||||
ssize_t arch_read(Arch * arch, void * buf, size_t cnt);
|
ssize_t arch_read(Arch * arch, void * buf, size_t cnt);
|
||||||
off_t arch_seek(Arch * arch, off_t offset, int whence);
|
off_t arch_seek(Arch * arch, off_t offset, int whence);
|
||||||
|
|
||||||
|
@ -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
|
PREFIX = /usr/local
|
||||||
DESTDIR =
|
DESTDIR =
|
||||||
LIBDIR = $(PREFIX)/lib
|
LIBDIR = $(PREFIX)/lib
|
||||||
@ -32,6 +32,20 @@ arm_LDFLAGS = $(LDFLAGSF) $(LDFLAGS)
|
|||||||
arm.so: $(arm_OBJS)
|
arm.so: $(arm_OBJS)
|
||||||
$(CCSHARED) -o arm.so $(arm_OBJS) $(arm_LDFLAGS)
|
$(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_OBJS = dalvik.o
|
||||||
dalvik_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS)
|
dalvik_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS)
|
||||||
dalvik_LDFLAGS = $(LDFLAGSF) $(LDFLAGS)
|
dalvik_LDFLAGS = $(LDFLAGSF) $(LDFLAGS)
|
||||||
@ -88,6 +102,20 @@ mips_LDFLAGS = $(LDFLAGSF) $(LDFLAGS)
|
|||||||
mips.so: $(mips_OBJS)
|
mips.so: $(mips_OBJS)
|
||||||
$(CCSHARED) -o mips.so $(mips_OBJS) $(mips_LDFLAGS)
|
$(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_OBJS = sparc.o
|
||||||
sparc_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS)
|
sparc_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS)
|
||||||
sparc_LDFLAGS = $(LDFLAGSF) $(LDFLAGS)
|
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
|
arm.o: arm.c arm.h arm.ins arm.reg common.ins null.ins
|
||||||
$(CC) $(arm_CFLAGS) -c arm.c
|
$(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
|
dalvik.o: dalvik.c common.ins null.ins dalvik.ins dalvik.reg
|
||||||
$(CC) $(dalvik_CFLAGS) -c dalvik.c
|
$(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
|
mips.o: mips.c common.ins null.ins mips.h mips.ins mips.reg
|
||||||
$(CC) $(mips_CFLAGS) -c mips.c
|
$(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
|
sparc.o: sparc.c common.ins null.ins sparc.h sparc.ins sparc.reg
|
||||||
$(CC) $(sparc_CFLAGS) -c sparc.c
|
$(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
|
$(CC) $(yasep_CFLAGS) -c yasep.c
|
||||||
|
|
||||||
clean:
|
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
|
distclean: clean
|
||||||
$(RM) -- $(TARGETS)
|
$(RM) -- $(TARGETS)
|
||||||
@ -160,6 +200,10 @@ install: $(TARGETS)
|
|||||||
$(MKDIR) $(DESTDIR)$(LIBDIR)/asm/arch
|
$(MKDIR) $(DESTDIR)$(LIBDIR)/asm/arch
|
||||||
$(INSTALL) -m 0644 -- arm.so $(DESTDIR)$(LIBDIR)/asm/arch/arm.so
|
$(INSTALL) -m 0644 -- arm.so $(DESTDIR)$(LIBDIR)/asm/arch/arm.so
|
||||||
$(MKDIR) $(DESTDIR)$(LIBDIR)/asm/arch
|
$(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
|
$(INSTALL) -m 0644 -- dalvik.so $(DESTDIR)$(LIBDIR)/asm/arch/dalvik.so
|
||||||
$(MKDIR) $(DESTDIR)$(LIBDIR)/asm/arch
|
$(MKDIR) $(DESTDIR)$(LIBDIR)/asm/arch
|
||||||
$(INSTALL) -m 0644 -- i386.so $(DESTDIR)$(LIBDIR)/asm/arch/i386.so
|
$(INSTALL) -m 0644 -- i386.so $(DESTDIR)$(LIBDIR)/asm/arch/i386.so
|
||||||
@ -176,6 +220,10 @@ install: $(TARGETS)
|
|||||||
$(MKDIR) $(DESTDIR)$(LIBDIR)/asm/arch
|
$(MKDIR) $(DESTDIR)$(LIBDIR)/asm/arch
|
||||||
$(INSTALL) -m 0644 -- mips.so $(DESTDIR)$(LIBDIR)/asm/arch/mips.so
|
$(INSTALL) -m 0644 -- mips.so $(DESTDIR)$(LIBDIR)/asm/arch/mips.so
|
||||||
$(MKDIR) $(DESTDIR)$(LIBDIR)/asm/arch
|
$(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
|
$(INSTALL) -m 0644 -- sparc.so $(DESTDIR)$(LIBDIR)/asm/arch/sparc.so
|
||||||
$(MKDIR) $(DESTDIR)$(LIBDIR)/asm/arch
|
$(MKDIR) $(DESTDIR)$(LIBDIR)/asm/arch
|
||||||
$(INSTALL) -m 0644 -- sparc64.so $(DESTDIR)$(LIBDIR)/asm/arch/sparc64.so
|
$(INSTALL) -m 0644 -- sparc64.so $(DESTDIR)$(LIBDIR)/asm/arch/sparc64.so
|
||||||
@ -185,6 +233,8 @@ install: $(TARGETS)
|
|||||||
uninstall:
|
uninstall:
|
||||||
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/amd64.so
|
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/amd64.so
|
||||||
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/arm.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/dalvik.so
|
||||||
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/i386.so
|
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/i386.so
|
||||||
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/i386_real.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/i686.so
|
||||||
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/java.so
|
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/java.so
|
||||||
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/mips.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/sparc.so
|
||||||
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/sparc64.so
|
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/sparc64.so
|
||||||
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/yasep.so
|
$(RM) -- $(DESTDIR)$(LIBDIR)/asm/arch/yasep.so
|
||||||
|
@ -88,6 +88,6 @@ ArchPlugin arch_plugin =
|
|||||||
_amd64_instructions,
|
_amd64_instructions,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
_i386_write,
|
_i386_encode,
|
||||||
_i386_decode
|
_i386_decode
|
||||||
};
|
};
|
||||||
|
@ -19,6 +19,12 @@
|
|||||||
#include "Asm.h"
|
#include "Asm.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* constants */
|
||||||
|
#ifndef ARCH_ENDIAN
|
||||||
|
# define ARCH_ENDIAN ARCH_ENDIAN_BOTH
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* arm */
|
/* arm */
|
||||||
/* private */
|
/* private */
|
||||||
/* types */
|
/* types */
|
||||||
@ -35,7 +41,7 @@ enum
|
|||||||
/* variables */
|
/* variables */
|
||||||
static ArchDescription _arm_description =
|
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 },
|
#define REG(name, size, id) { "" # name, size, id },
|
||||||
@ -70,6 +76,6 @@ ArchPlugin arch_plugin =
|
|||||||
_arm_instructions,
|
_arm_instructions,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
_arm_write,
|
_arm_encode,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
@ -22,14 +22,14 @@
|
|||||||
/* private */
|
/* private */
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
/* plug-in */
|
/* plug-in */
|
||||||
static int _arm_write(ArchPlugin * plugin, ArchInstruction * instruction,
|
static int _arm_encode(ArchPlugin * plugin, ArchInstruction * instruction,
|
||||||
ArchInstructionCall * call);
|
ArchInstructionCall * call);
|
||||||
|
|
||||||
|
|
||||||
/* functions */
|
/* functions */
|
||||||
/* plug-in */
|
/* plug-in */
|
||||||
/* arm_write */
|
/* arm_encode */
|
||||||
static int _arm_write(ArchPlugin * plugin, ArchInstruction * instruction,
|
static int _arm_encode(ArchPlugin * plugin, ArchInstruction * instruction,
|
||||||
ArchInstructionCall * call)
|
ArchInstructionCall * call)
|
||||||
{
|
{
|
||||||
ArchPluginHelper * helper = plugin->helper;
|
ArchPluginHelper * helper = plugin->helper;
|
||||||
|
19
src/arch/armeb.c
Normal file
19
src/arch/armeb.c
Normal 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
19
src/arch/armel.c
Normal 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"
|
@ -79,7 +79,7 @@ static ArchInstruction _dalvik_instructions[] =
|
|||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
/* plug-in */
|
/* plug-in */
|
||||||
static int _dalvik_write(ArchPlugin * plugin, ArchInstruction * instruction,
|
static int _dalvik_encode(ArchPlugin * plugin, ArchInstruction * instruction,
|
||||||
ArchInstructionCall * call);
|
ArchInstructionCall * call);
|
||||||
static int _dalvik_decode(ArchPlugin * plugin, ArchInstructionCall * call);
|
static int _dalvik_decode(ArchPlugin * plugin, ArchInstructionCall * call);
|
||||||
|
|
||||||
@ -95,15 +95,15 @@ ArchPlugin arch_plugin =
|
|||||||
_dalvik_instructions,
|
_dalvik_instructions,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
_dalvik_write,
|
_dalvik_encode,
|
||||||
_dalvik_decode
|
_dalvik_decode
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* private */
|
/* private */
|
||||||
/* functions */
|
/* functions */
|
||||||
/* dalvik_write */
|
/* dalvik_encode */
|
||||||
static int _dalvik_write(ArchPlugin * plugin, ArchInstruction * instruction,
|
static int _dalvik_encode(ArchPlugin * plugin, ArchInstruction * instruction,
|
||||||
ArchInstructionCall * call)
|
ArchInstructionCall * call)
|
||||||
{
|
{
|
||||||
ArchPluginHelper * helper = plugin->helper;
|
ArchPluginHelper * helper = plugin->helper;
|
||||||
|
@ -80,6 +80,6 @@ ArchPlugin arch_plugin =
|
|||||||
_i386_instructions,
|
_i386_instructions,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
_i386_write,
|
_i386_encode,
|
||||||
_i386_decode
|
_i386_decode
|
||||||
};
|
};
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
/* private */
|
/* private */
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
static int _i386_decode(ArchPlugin * plugin, ArchInstructionCall * call);
|
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);
|
ArchInstructionCall * call);
|
||||||
|
|
||||||
|
|
||||||
@ -442,23 +442,23 @@ static int _decode_register(ArchPlugin * plugin, ArchInstructionCall * call,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* i386_write */
|
/* i386_encode */
|
||||||
static int _write_constant(ArchPlugin * plugin,
|
static int _encode_constant(ArchPlugin * plugin,
|
||||||
ArchOperandDefinition definition, ArchOperand * operand);
|
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);
|
ArchOperandDefinition * definitions, ArchOperand * operands);
|
||||||
static int _write_immediate(ArchPlugin * plugin, ArchOperand * operand);
|
static int _encode_immediate(ArchPlugin * plugin, ArchOperand * operand);
|
||||||
static int _write_immediate8(ArchPlugin * plugin, uint8_t value);
|
static int _encode_immediate8(ArchPlugin * plugin, uint8_t value);
|
||||||
static int _write_immediate16(ArchPlugin * plugin, uint16_t value);
|
static int _encode_immediate16(ArchPlugin * plugin, uint16_t value);
|
||||||
static int _write_immediate24(ArchPlugin * plugin, uint32_t value);
|
static int _encode_immediate24(ArchPlugin * plugin, uint32_t value);
|
||||||
static int _write_immediate32(ArchPlugin * plugin, uint32_t value);
|
static int _encode_immediate32(ArchPlugin * plugin, uint32_t value);
|
||||||
static int _write_opcode(ArchPlugin * plugin, ArchInstruction * instruction);
|
static int _encode_opcode(ArchPlugin * plugin, ArchInstruction * instruction);
|
||||||
static int _write_operand(ArchPlugin * plugin, uint32_t * i,
|
static int _encode_operand(ArchPlugin * plugin, uint32_t * i,
|
||||||
ArchOperandDefinition * definitions, ArchOperand * operands);
|
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);
|
ArchOperandDefinition * definitions, ArchOperand * operands);
|
||||||
|
|
||||||
static int _i386_write(ArchPlugin * plugin, ArchInstruction * instruction,
|
static int _i386_encode(ArchPlugin * plugin, ArchInstruction * instruction,
|
||||||
ArchInstructionCall * call)
|
ArchInstructionCall * call)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
@ -467,18 +467,18 @@ static int _i386_write(ArchPlugin * plugin, ArchInstruction * instruction,
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, instruction->name);
|
fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, instruction->name);
|
||||||
#endif
|
#endif
|
||||||
if(_write_opcode(plugin, instruction) != 0)
|
if(_encode_opcode(plugin, instruction) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
definitions[0] = instruction->op1;
|
definitions[0] = instruction->op1;
|
||||||
definitions[1] = instruction->op2;
|
definitions[1] = instruction->op2;
|
||||||
definitions[2] = instruction->op3;
|
definitions[2] = instruction->op3;
|
||||||
for(i = 0; i < call->operands_cnt; i++)
|
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 -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _write_constant(ArchPlugin * plugin,
|
static int _encode_constant(ArchPlugin * plugin,
|
||||||
ArchOperandDefinition definition, ArchOperand * operand)
|
ArchOperandDefinition definition, ArchOperand * operand)
|
||||||
{
|
{
|
||||||
ArchOperand ao;
|
ArchOperand ao;
|
||||||
@ -487,10 +487,10 @@ static int _write_constant(ArchPlugin * plugin,
|
|||||||
return 0;
|
return 0;
|
||||||
ao = *operand;
|
ao = *operand;
|
||||||
ao.definition &= ~(AOM_FLAGS);
|
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)
|
ArchOperandDefinition * definitions, ArchOperand * operands)
|
||||||
{
|
{
|
||||||
ArchPluginHelper * helper = plugin->helper;
|
ArchPluginHelper * helper = plugin->helper;
|
||||||
@ -526,7 +526,7 @@ static int _write_dregister(ArchPlugin * plugin, uint32_t * i,
|
|||||||
<< 3);
|
<< 3);
|
||||||
if(operand->value.dregister.offset == 0)
|
if(operand->value.dregister.offset == 0)
|
||||||
/* there is no offset */
|
/* there is no offset */
|
||||||
return _write_immediate(plugin, &ioperand);
|
return _encode_immediate(plugin, &ioperand);
|
||||||
/* declare offset */
|
/* declare offset */
|
||||||
switch(AO_GET_OFFSET(definition) >> 3)
|
switch(AO_GET_OFFSET(definition) >> 3)
|
||||||
{
|
{
|
||||||
@ -539,15 +539,15 @@ static int _write_dregister(ArchPlugin * plugin, uint32_t * i,
|
|||||||
default:
|
default:
|
||||||
return -error_set_code(1, "%s", "Invalid offset");
|
return -error_set_code(1, "%s", "Invalid offset");
|
||||||
}
|
}
|
||||||
if(_write_immediate(plugin, &ioperand) != 0)
|
if(_encode_immediate(plugin, &ioperand) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
/* write offset */
|
/* write offset */
|
||||||
ioperand.definition = AO_IMMEDIATE(0, AO_GET_OFFSET(definition), 0);
|
ioperand.definition = AO_IMMEDIATE(0, AO_GET_OFFSET(definition), 0);
|
||||||
ioperand.value.immediate.value = operand->value.dregister.offset;
|
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;
|
uint64_t value = operand->value.immediate.value;
|
||||||
|
|
||||||
@ -559,18 +559,18 @@ static int _write_immediate(ArchPlugin * plugin, ArchOperand * operand)
|
|||||||
case 0:
|
case 0:
|
||||||
return 0;
|
return 0;
|
||||||
case sizeof(uint8_t):
|
case sizeof(uint8_t):
|
||||||
return _write_immediate8(plugin, value);
|
return _encode_immediate8(plugin, value);
|
||||||
case sizeof(uint16_t):
|
case sizeof(uint16_t):
|
||||||
return _write_immediate16(plugin, value);
|
return _encode_immediate16(plugin, value);
|
||||||
case 3:
|
case 3:
|
||||||
return _write_immediate24(plugin, value);
|
return _encode_immediate24(plugin, value);
|
||||||
case sizeof(uint32_t):
|
case sizeof(uint32_t):
|
||||||
return _write_immediate32(plugin, value);
|
return _encode_immediate32(plugin, value);
|
||||||
}
|
}
|
||||||
return -error_set_code(1, "%s", "Invalid size");
|
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;
|
ArchPluginHelper * helper = plugin->helper;
|
||||||
|
|
||||||
@ -579,7 +579,7 @@ static int _write_immediate8(ArchPlugin * plugin, uint8_t value)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _write_immediate16(ArchPlugin * plugin, uint16_t value)
|
static int _encode_immediate16(ArchPlugin * plugin, uint16_t value)
|
||||||
{
|
{
|
||||||
ArchPluginHelper * helper = plugin->helper;
|
ArchPluginHelper * helper = plugin->helper;
|
||||||
|
|
||||||
@ -589,7 +589,7 @@ static int _write_immediate16(ArchPlugin * plugin, uint16_t value)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _write_immediate24(ArchPlugin * plugin, uint32_t value)
|
static int _encode_immediate24(ArchPlugin * plugin, uint32_t value)
|
||||||
{
|
{
|
||||||
ArchPluginHelper * helper = plugin->helper;
|
ArchPluginHelper * helper = plugin->helper;
|
||||||
|
|
||||||
@ -599,7 +599,7 @@ static int _write_immediate24(ArchPlugin * plugin, uint32_t value)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _write_immediate32(ArchPlugin * plugin, uint32_t value)
|
static int _encode_immediate32(ArchPlugin * plugin, uint32_t value)
|
||||||
{
|
{
|
||||||
ArchPluginHelper * helper = plugin->helper;
|
ArchPluginHelper * helper = plugin->helper;
|
||||||
|
|
||||||
@ -609,7 +609,7 @@ static int _write_immediate32(ArchPlugin * plugin, uint32_t value)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _write_opcode(ArchPlugin * plugin, ArchInstruction * instruction)
|
static int _encode_opcode(ArchPlugin * plugin, ArchInstruction * instruction)
|
||||||
{
|
{
|
||||||
ArchOperand operand;
|
ArchOperand operand;
|
||||||
|
|
||||||
@ -639,24 +639,24 @@ static int _write_opcode(ArchPlugin * plugin, ArchInstruction * instruction)
|
|||||||
default:
|
default:
|
||||||
return -error_set_code(1, "%s", "Invalid size");
|
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)
|
ArchOperandDefinition * definitions, ArchOperand * operands)
|
||||||
{
|
{
|
||||||
switch(operands[*i].definition)
|
switch(operands[*i].definition)
|
||||||
{
|
{
|
||||||
case AOT_CONSTANT:
|
case AOT_CONSTANT:
|
||||||
return _write_constant(plugin, definitions[*i],
|
return _encode_constant(plugin, definitions[*i],
|
||||||
&operands[*i]);
|
&operands[*i]);
|
||||||
case AOT_DREGISTER:
|
case AOT_DREGISTER:
|
||||||
return _write_dregister(plugin, i, definitions,
|
return _encode_dregister(plugin, i, definitions,
|
||||||
operands);
|
operands);
|
||||||
case AOT_IMMEDIATE:
|
case AOT_IMMEDIATE:
|
||||||
return _write_immediate(plugin, &operands[*i]);
|
return _encode_immediate(plugin, &operands[*i]);
|
||||||
case AOT_REGISTER:
|
case AOT_REGISTER:
|
||||||
return _write_register(plugin, i, definitions,
|
return _encode_register(plugin, i, definitions,
|
||||||
operands);
|
operands);
|
||||||
case AOT_NONE:
|
case AOT_NONE:
|
||||||
case AOT_DREGISTER2:
|
case AOT_DREGISTER2:
|
||||||
@ -666,7 +666,7 @@ static int _write_operand(ArchPlugin * plugin, uint32_t * i,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _write_register(ArchPlugin * plugin, uint32_t * i,
|
static int _encode_register(ArchPlugin * plugin, uint32_t * i,
|
||||||
ArchOperandDefinition * definitions, ArchOperand * operands)
|
ArchOperandDefinition * definitions, ArchOperand * operands)
|
||||||
{
|
{
|
||||||
ArchPluginHelper * helper = plugin->helper;
|
ArchPluginHelper * helper = plugin->helper;
|
||||||
@ -703,5 +703,5 @@ static int _write_register(ArchPlugin * plugin, uint32_t * i,
|
|||||||
| (AO_GET_VALUE(definition) << 3);
|
| (AO_GET_VALUE(definition) << 3);
|
||||||
else
|
else
|
||||||
ioperand.value.immediate.value = ar->id;
|
ioperand.value.immediate.value = ar->id;
|
||||||
return _write_immediate(plugin, &ioperand);
|
return _encode_immediate(plugin, &ioperand);
|
||||||
}
|
}
|
||||||
|
@ -81,6 +81,6 @@ ArchPlugin arch_plugin =
|
|||||||
_i386_real_instructions,
|
_i386_real_instructions,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
_i386_write,
|
_i386_encode,
|
||||||
_i386_decode
|
_i386_decode
|
||||||
};
|
};
|
||||||
|
@ -81,6 +81,6 @@ ArchPlugin arch_plugin =
|
|||||||
_i486_instructions,
|
_i486_instructions,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
_i386_write,
|
_i386_encode,
|
||||||
_i386_decode
|
_i386_decode
|
||||||
};
|
};
|
||||||
|
@ -82,6 +82,6 @@ ArchPlugin arch_plugin =
|
|||||||
_i586_instructions,
|
_i586_instructions,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
_i386_write,
|
_i386_encode,
|
||||||
_i386_decode
|
_i386_decode
|
||||||
};
|
};
|
||||||
|
@ -84,6 +84,6 @@ ArchPlugin arch_plugin =
|
|||||||
_i686_instructions,
|
_i686_instructions,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
_i386_write,
|
_i386_encode,
|
||||||
_i386_decode
|
_i386_decode
|
||||||
};
|
};
|
||||||
|
@ -251,7 +251,7 @@ static ArchInstruction _java_instructions[] =
|
|||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
/* plug-in */
|
/* plug-in */
|
||||||
static int _java_write(ArchPlugin * plugin, ArchInstruction * instruction,
|
static int _java_encode(ArchPlugin * plugin, ArchInstruction * instruction,
|
||||||
ArchInstructionCall * call);
|
ArchInstructionCall * call);
|
||||||
static int _java_decode(ArchPlugin * plugin, ArchInstructionCall * call);
|
static int _java_decode(ArchPlugin * plugin, ArchInstructionCall * call);
|
||||||
|
|
||||||
@ -267,7 +267,7 @@ ArchPlugin arch_plugin =
|
|||||||
_java_instructions,
|
_java_instructions,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
_java_write,
|
_java_encode,
|
||||||
_java_decode
|
_java_decode
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -275,7 +275,7 @@ ArchPlugin arch_plugin =
|
|||||||
/* private */
|
/* private */
|
||||||
/* functions */
|
/* functions */
|
||||||
/* plug-in */
|
/* plug-in */
|
||||||
static int _java_write(ArchPlugin * plugin, ArchInstruction * instruction,
|
static int _java_encode(ArchPlugin * plugin, ArchInstruction * instruction,
|
||||||
ArchInstructionCall * call)
|
ArchInstructionCall * call)
|
||||||
{
|
{
|
||||||
ArchPluginHelper * helper = plugin->helper;
|
ArchPluginHelper * helper = plugin->helper;
|
||||||
|
@ -18,13 +18,17 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "Asm.h"
|
#include "Asm.h"
|
||||||
|
|
||||||
|
#ifndef ARCH_ENDIAN
|
||||||
|
# define ARCH_ENDIAN ARCH_ENDIAN_BOTH
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* mips */
|
/* mips */
|
||||||
/* private */
|
/* private */
|
||||||
/* variables */
|
/* variables */
|
||||||
static ArchDescription _mips_description =
|
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 },
|
#define REG(name, size, id) { "" # name, size, id },
|
||||||
@ -59,6 +63,6 @@ ArchPlugin arch_plugin =
|
|||||||
_mips_instructions,
|
_mips_instructions,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
_mips_write,
|
_mips_encode,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
@ -22,14 +22,14 @@
|
|||||||
/* private */
|
/* private */
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
/* plug-in */
|
/* plug-in */
|
||||||
static int _mips_write(ArchPlugin * plugin, ArchInstruction * instruction,
|
static int _mips_encode(ArchPlugin * plugin, ArchInstruction * instruction,
|
||||||
ArchInstructionCall * call);
|
ArchInstructionCall * call);
|
||||||
|
|
||||||
|
|
||||||
/* functions */
|
/* functions */
|
||||||
/* plug-in */
|
/* plug-in */
|
||||||
/* mips_write */
|
/* mips_encode */
|
||||||
static int _mips_write(ArchPlugin * plugin, ArchInstruction * instruction,
|
static int _mips_encode(ArchPlugin * plugin, ArchInstruction * instruction,
|
||||||
ArchInstructionCall * call)
|
ArchInstructionCall * call)
|
||||||
{
|
{
|
||||||
ArchPluginHelper * helper = plugin->helper;
|
ArchPluginHelper * helper = plugin->helper;
|
||||||
|
19
src/arch/mipseb.c
Normal file
19
src/arch/mipseb.c
Normal 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
19
src/arch/mipsel.c
Normal 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"
|
@ -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
|
cppflags_force=-I ../../include
|
||||||
cflags_force=-W `pkg-config --cflags libSystem`
|
cflags_force=-W `pkg-config --cflags libSystem`
|
||||||
cflags=-Wall -g -O2 -fPIC -pedantic
|
cflags=-Wall -g -O2 -fPIC -pedantic
|
||||||
@ -20,6 +20,22 @@ install=$(LIBDIR)/asm/arch
|
|||||||
[arm.c]
|
[arm.c]
|
||||||
depends=arm.h,arm.ins,arm.reg,common.ins,null.ins
|
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]
|
[dalvik]
|
||||||
type=plugin
|
type=plugin
|
||||||
sources=dalvik.c
|
sources=dalvik.c
|
||||||
@ -84,6 +100,22 @@ install=$(LIBDIR)/asm/arch
|
|||||||
[mips.c]
|
[mips.c]
|
||||||
depends=common.ins,null.ins,mips.h,mips.ins,mips.reg
|
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]
|
[sparc]
|
||||||
type=plugin
|
type=plugin
|
||||||
sources=sparc.c
|
sources=sparc.c
|
||||||
|
@ -59,6 +59,6 @@ ArchPlugin arch_plugin =
|
|||||||
_sparc_instructions,
|
_sparc_instructions,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
_sparc_write,
|
_sparc_encode,
|
||||||
_sparc_decode
|
_sparc_decode
|
||||||
};
|
};
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
/* prototypes */
|
/* prototypes */
|
||||||
/* plug-in */
|
/* plug-in */
|
||||||
static int _sparc_decode(ArchPlugin * plugin, ArchInstructionCall * call);
|
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);
|
ArchInstructionCall * call);
|
||||||
|
|
||||||
|
|
||||||
@ -71,17 +71,17 @@ static int _sparc_decode(ArchPlugin * plugin, ArchInstructionCall * call)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* sparc_write */
|
/* sparc_encode */
|
||||||
static int _write_branch(ArchInstruction * instruction,
|
static int _encode_branch(ArchInstruction * instruction,
|
||||||
ArchInstructionCall * call, uint32_t * opcode);
|
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);
|
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);
|
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);
|
ArchInstructionCall * call, uint32_t * opcode);
|
||||||
|
|
||||||
static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction,
|
static int _sparc_encode(ArchPlugin * plugin, ArchInstruction * instruction,
|
||||||
ArchInstructionCall * call)
|
ArchInstructionCall * call)
|
||||||
{
|
{
|
||||||
ArchPluginHelper * helper = plugin->helper;
|
ArchPluginHelper * helper = plugin->helper;
|
||||||
@ -89,22 +89,22 @@ static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction,
|
|||||||
|
|
||||||
if((opcode & 0xc0000000) == 0xc0000000)
|
if((opcode & 0xc0000000) == 0xc0000000)
|
||||||
{
|
{
|
||||||
if(_write_loadstore(plugin, instruction, call, &opcode) != 0)
|
if(_encode_loadstore(plugin, instruction, call, &opcode) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else if((opcode & 0xc1c00000) == 0x01000000)
|
else if((opcode & 0xc1c00000) == 0x01000000)
|
||||||
{
|
{
|
||||||
if(_write_sethi(plugin, instruction, call, &opcode) != 0)
|
if(_encode_sethi(plugin, instruction, call, &opcode) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else if((opcode & 0xc0000000) == 0x80000000)
|
else if((opcode & 0xc0000000) == 0x80000000)
|
||||||
{
|
{
|
||||||
if(_write_integer(plugin, instruction, call, &opcode) != 0)
|
if(_encode_integer(plugin, instruction, call, &opcode) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else if((opcode & 0xc1c00000) == 0x00800000)
|
else if((opcode & 0xc1c00000) == 0x00800000)
|
||||||
{
|
{
|
||||||
if(_write_branch(instruction, call, &opcode) != 0)
|
if(_encode_branch(instruction, call, &opcode) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -116,7 +116,7 @@ static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _write_branch(ArchInstruction * instruction,
|
static int _encode_branch(ArchInstruction * instruction,
|
||||||
ArchInstructionCall * call, uint32_t * opcode)
|
ArchInstructionCall * call, uint32_t * opcode)
|
||||||
{
|
{
|
||||||
uint32_t disp;
|
uint32_t disp;
|
||||||
@ -131,7 +131,7 @@ static int _write_branch(ArchInstruction * instruction,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _write_integer(ArchPlugin * plugin, ArchInstruction * instruction,
|
static int _encode_integer(ArchPlugin * plugin, ArchInstruction * instruction,
|
||||||
ArchInstructionCall * call, uint32_t * opcode)
|
ArchInstructionCall * call, uint32_t * opcode)
|
||||||
{
|
{
|
||||||
ArchPluginHelper * helper = plugin->helper;
|
ArchPluginHelper * helper = plugin->helper;
|
||||||
@ -180,7 +180,7 @@ static int _write_integer(ArchPlugin * plugin, ArchInstruction * instruction,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _write_loadstore(ArchPlugin * plugin, ArchInstruction * instruction,
|
static int _encode_loadstore(ArchPlugin * plugin, ArchInstruction * instruction,
|
||||||
ArchInstructionCall * call, uint32_t * opcode)
|
ArchInstructionCall * call, uint32_t * opcode)
|
||||||
{
|
{
|
||||||
ArchPluginHelper * helper = plugin->helper;
|
ArchPluginHelper * helper = plugin->helper;
|
||||||
@ -266,7 +266,7 @@ static int _write_loadstore(ArchPlugin * plugin, ArchInstruction * instruction,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _write_sethi(ArchPlugin * plugin, ArchInstruction * instruction,
|
static int _encode_sethi(ArchPlugin * plugin, ArchInstruction * instruction,
|
||||||
ArchInstructionCall * call, uint32_t * opcode)
|
ArchInstructionCall * call, uint32_t * opcode)
|
||||||
{
|
{
|
||||||
ArchPluginHelper * helper = plugin->helper;
|
ArchPluginHelper * helper = plugin->helper;
|
||||||
|
@ -58,6 +58,6 @@ ArchPlugin arch_plugin =
|
|||||||
_sparc64_instructions,
|
_sparc64_instructions,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
_sparc_write,
|
_sparc_encode,
|
||||||
_sparc_decode
|
_sparc_decode
|
||||||
};
|
};
|
||||||
|
@ -41,7 +41,7 @@ static ArchInstruction _yasep_instructions[] =
|
|||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
/* plug-in */
|
/* plug-in */
|
||||||
static int _yasep_write(ArchPlugin * plugin, ArchInstruction * instruction,
|
static int _yasep_encode(ArchPlugin * plugin, ArchInstruction * instruction,
|
||||||
ArchInstructionCall * call);
|
ArchInstructionCall * call);
|
||||||
|
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ ArchPlugin arch_plugin =
|
|||||||
_yasep_instructions,
|
_yasep_instructions,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
_yasep_write,
|
_yasep_encode,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -64,21 +64,21 @@ ArchPlugin arch_plugin =
|
|||||||
/* private */
|
/* private */
|
||||||
/* functions */
|
/* functions */
|
||||||
/* plug-in */
|
/* plug-in */
|
||||||
/* yasep_write */
|
/* yasep_encode */
|
||||||
static int _write_16(ArchPlugin * plugin, ArchInstruction * instruction,
|
static int _encode_16(ArchPlugin * plugin, ArchInstruction * instruction,
|
||||||
ArchInstructionCall * call);
|
ArchInstructionCall * call);
|
||||||
static int _write_32(ArchPlugin * plugin, ArchInstruction * instruction,
|
static int _encode_32(ArchPlugin * plugin, ArchInstruction * instruction,
|
||||||
ArchInstructionCall * call);
|
ArchInstructionCall * call);
|
||||||
|
|
||||||
static int _yasep_write(ArchPlugin * plugin, ArchInstruction * instruction,
|
static int _yasep_encode(ArchPlugin * plugin, ArchInstruction * instruction,
|
||||||
ArchInstructionCall * call)
|
ArchInstructionCall * call)
|
||||||
{
|
{
|
||||||
return (instruction->opcode & 0x1)
|
return (instruction->opcode & 0x1)
|
||||||
? _write_32(plugin, instruction, call)
|
? _encode_32(plugin, instruction, call)
|
||||||
: _write_16(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)
|
ArchInstructionCall * call)
|
||||||
{
|
{
|
||||||
ArchPluginHelper * helper = plugin->helper;
|
ArchPluginHelper * helper = plugin->helper;
|
||||||
@ -91,7 +91,7 @@ static int _write_16(ArchPlugin * plugin, ArchInstruction * instruction,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _write_32(ArchPlugin * plugin, ArchInstruction * instruction,
|
static int _encode_32(ArchPlugin * plugin, ArchInstruction * instruction,
|
||||||
ArchInstructionCall * call)
|
ArchInstructionCall * call)
|
||||||
{
|
{
|
||||||
ArchPluginHelper * helper = plugin->helper;
|
ArchPluginHelper * helper = plugin->helper;
|
||||||
|
99
src/asm.c
99
src/asm.c
@ -24,7 +24,10 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include "Asm/asm.h"
|
||||||
|
#include "arch.h"
|
||||||
#include "code.h"
|
#include "code.h"
|
||||||
|
#include "format.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
|
|
||||||
@ -34,10 +37,12 @@
|
|||||||
/* types */
|
/* types */
|
||||||
struct _Asm
|
struct _Asm
|
||||||
{
|
{
|
||||||
|
#if 1 /* FIXME probably useless now */
|
||||||
char * arch;
|
char * arch;
|
||||||
char * format;
|
char * format;
|
||||||
|
#endif
|
||||||
|
|
||||||
Code * code;
|
AsmCode * code;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _AsmPluginDescription
|
typedef struct _AsmPluginDescription
|
||||||
@ -96,7 +101,7 @@ void asm_delete(Asm * a)
|
|||||||
fprintf(stderr, "DEBUG: %s()\n", __func__);
|
fprintf(stderr, "DEBUG: %s()\n", __func__);
|
||||||
#endif
|
#endif
|
||||||
if(a->code != NULL)
|
if(a->code != NULL)
|
||||||
code_delete(a->code);
|
asmcode_delete(a->code);
|
||||||
string_delete(a->format);
|
string_delete(a->format);
|
||||||
string_delete(a->arch);
|
string_delete(a->arch);
|
||||||
object_delete(a);
|
object_delete(a);
|
||||||
@ -107,6 +112,8 @@ void asm_delete(Asm * a)
|
|||||||
/* asm_get_arch */
|
/* asm_get_arch */
|
||||||
char const * asm_get_arch(Asm * a)
|
char const * asm_get_arch(Asm * a)
|
||||||
{
|
{
|
||||||
|
if(a->code != NULL)
|
||||||
|
return asmcode_get_arch(a->code);
|
||||||
return a->arch;
|
return a->arch;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,6 +121,8 @@ char const * asm_get_arch(Asm * a)
|
|||||||
/* asm_get_format */
|
/* asm_get_format */
|
||||||
char const * asm_get_format(Asm * a)
|
char const * asm_get_format(Asm * a)
|
||||||
{
|
{
|
||||||
|
if(a->code != NULL)
|
||||||
|
return asmcode_get_format(a->code);
|
||||||
return a->format;
|
return a->format;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,15 +156,7 @@ int asm_set_format(Asm * a, char const * format)
|
|||||||
/* asm_set_function */
|
/* asm_set_function */
|
||||||
int asm_set_function(Asm * a, char const * name, off_t offset, ssize_t size)
|
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);
|
return asmcode_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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -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 */
|
/* asm_close */
|
||||||
int asm_close(Asm * a)
|
int asm_close(Asm * a)
|
||||||
{
|
{
|
||||||
@ -183,29 +199,28 @@ int asm_close(Asm * a)
|
|||||||
|
|
||||||
if(a->code == NULL)
|
if(a->code == NULL)
|
||||||
return -error_set_code(1, "%s", "No file opened");
|
return -error_set_code(1, "%s", "No file opened");
|
||||||
ret = code_close(a->code);
|
ret = asmcode_close(a->code);
|
||||||
a->code = NULL;
|
a->code = NULL;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* asm_deassemble */
|
/* 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)
|
if(_asm_open(a, NULL) != 0)
|
||||||
return -1;
|
return NULL;
|
||||||
ret = code_decode_buffer(a->code, buffer, size);
|
if(asmcode_decode_buffer(a->code, buffer, size, calls, calls_cnt) != 0)
|
||||||
asm_close(a);
|
return NULL;
|
||||||
return ret;
|
return a->code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* asm_function */
|
/* asm_function */
|
||||||
int asm_function(Asm * a, char const * name)
|
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);
|
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 */
|
/* 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
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, filename);
|
fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, filename);
|
||||||
#endif
|
#endif
|
||||||
if(a->code != NULL)
|
if(a->code != NULL)
|
||||||
return -error_set_code(1, "%s: Operation in progress",
|
{
|
||||||
code_get_filename(a->code));
|
error_set_code(1, "%s: Operation in progress",
|
||||||
if((a->code = code_new_file(a->arch, a->format, filename)) == NULL)
|
asmcode_get_filename(a->code));
|
||||||
return -1;
|
return NULL;
|
||||||
if(code_decode(a->code, raw) != 0)
|
}
|
||||||
return -1;
|
if((a->code = asmcode_new_file(a->arch, a->format, filename)) == NULL
|
||||||
return 0;
|
|| asmcode_decode(a->code, raw) != 0)
|
||||||
|
return NULL;
|
||||||
|
return a->code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* asm_plugin_list */
|
/* asm_plugin_list */
|
||||||
int asm_plugin_list(AsmPluginType type)
|
int asm_plugin_list(AsmPluginType type, int decode)
|
||||||
{
|
{
|
||||||
AsmPluginDescription const * aspd;
|
AsmPluginDescription const * aspd;
|
||||||
char * path;
|
char * path;
|
||||||
@ -277,6 +294,8 @@ int asm_plugin_list(AsmPluginType type)
|
|||||||
struct dirent * de;
|
struct dirent * de;
|
||||||
size_t len;
|
size_t len;
|
||||||
char const * sep = "";
|
char const * sep = "";
|
||||||
|
Arch * arch;
|
||||||
|
Format * format;
|
||||||
|
|
||||||
aspd = &_asm_plugin_description[type];
|
aspd = &_asm_plugin_description[type];
|
||||||
fprintf(stderr, "%s%s%s", "Available ", aspd->description,
|
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)
|
if(strcmp(".so", &de->d_name[len - 3]) != 0)
|
||||||
continue;
|
continue;
|
||||||
de->d_name[len - 3] = '\0';
|
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);
|
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 = ", ";
|
sep = ", ";
|
||||||
}
|
}
|
||||||
free(path);
|
free(path);
|
||||||
@ -344,10 +377,10 @@ static int _asm_open(Asm * a, char const * outfile)
|
|||||||
return -1;
|
return -1;
|
||||||
if(a->code != NULL)
|
if(a->code != NULL)
|
||||||
return -error_set_code(1, "%s: Operation in progress",
|
return -error_set_code(1, "%s: Operation in progress",
|
||||||
code_get_filename(a->code));
|
asmcode_get_filename(a->code));
|
||||||
if((a->code = code_new(arch, format)) == NULL)
|
if((a->code = asmcode_new(arch, format)) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
if(outfile == NULL)
|
if(outfile == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
return code_open(a->code, outfile);
|
return asmcode_open(a->code, outfile);
|
||||||
}
|
}
|
||||||
|
534
src/code.c
534
src/code.c
@ -12,6 +12,9 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
* 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"
|
#include "../config.h"
|
||||||
|
|
||||||
|
|
||||||
/* Code */
|
/* AsmCode */
|
||||||
/* private */
|
/* private */
|
||||||
/* types */
|
/* types */
|
||||||
typedef struct _CodeString
|
struct _AsmCode
|
||||||
{
|
|
||||||
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
|
|
||||||
{
|
{
|
||||||
Arch * arch;
|
Arch * arch;
|
||||||
ArchDescription * description;
|
ArchDescription * description;
|
||||||
@ -57,42 +44,53 @@ struct _Code
|
|||||||
char * filename;
|
char * filename;
|
||||||
FILE * fp;
|
FILE * fp;
|
||||||
|
|
||||||
/* functions */
|
/* elements */
|
||||||
CodeFunction * functions;
|
AsmElement * elements[AET_COUNT];
|
||||||
size_t functions_cnt;
|
size_t elements_cnt[AET_COUNT];
|
||||||
|
|
||||||
/* strings */
|
|
||||||
CodeString * strings;
|
|
||||||
size_t strings_cnt;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
/* functions */
|
/* elements */
|
||||||
static void _code_function_delete_all(Code * code);
|
static void _asmcode_element_delete_all(AsmCode * code, AsmElementType type);
|
||||||
|
|
||||||
static CodeFunction * _code_function_get_by_id(Code * code, AsmId id);
|
static AsmElement * _asmcode_element_get_by_id(AsmCode * code,
|
||||||
static int _code_function_set(CodeFunction * codefunction, int id,
|
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);
|
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 */
|
/* 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 AsmString * _asmcode_string_get_by_id(AsmCode * code, AsmStringId id);
|
||||||
static int _code_string_set(CodeString * codestring, int id, char const * name,
|
static int _asmcode_string_set(AsmString * codestring,
|
||||||
off_t offset, ssize_t length);
|
int id, char const * name, off_t offset, ssize_t length);
|
||||||
|
|
||||||
static CodeString * _code_string_append(Code * code);
|
static AsmString * _asmcode_string_append(AsmCode * code);
|
||||||
static int _code_string_read(Code * code, CodeString * codestring);
|
static int _asmcode_string_read(AsmCode * code, AsmString * codestring);
|
||||||
|
|
||||||
|
|
||||||
/* functions */
|
/* functions */
|
||||||
/* code_new */
|
/* asmcode_new */
|
||||||
Code * code_new(char const * arch, char const * format)
|
AsmCode * asmcode_new(char const * arch, char const * format)
|
||||||
{
|
{
|
||||||
Code * code;
|
AsmCode * code;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "DEBUG: %s(\"%s\", \"%s\")\n", __func__, arch, format);
|
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);
|
code->format = format_new(format);
|
||||||
if(code->arch == NULL)
|
if(code->arch == NULL)
|
||||||
{
|
{
|
||||||
code_delete(code);
|
asmcode_delete(code);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
code->description = arch_get_description(code->arch);
|
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);
|
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)
|
char const * filename)
|
||||||
{
|
{
|
||||||
Code * code;
|
AsmCode * code;
|
||||||
FILE * fp;
|
FILE * fp;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#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)
|
if(code->filename == NULL || code->arch == NULL || code->format == NULL)
|
||||||
{
|
{
|
||||||
code_delete(code);
|
asmcode_delete(code);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
code->description = arch_get_description(code->arch);
|
code->description = arch_get_description(code->arch);
|
||||||
@ -209,8 +207,8 @@ static Format * _new_file_format(char const * filename, FILE * fp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* code_delete */
|
/* asmcode_delete */
|
||||||
int code_delete(Code * code)
|
int asmcode_delete(AsmCode * code)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@ -231,71 +229,133 @@ int code_delete(Code * code)
|
|||||||
|
|
||||||
|
|
||||||
/* accessors */
|
/* accessors */
|
||||||
/* code_get_arch */
|
/* asmcode_get_arch */
|
||||||
char const * code_get_arch(Code * code)
|
char const * asmcode_get_arch(AsmCode * code)
|
||||||
{
|
{
|
||||||
return arch_get_name(code->arch);
|
return arch_get_name(code->arch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* code_get_filename */
|
/* asmcode_get_arch_description */
|
||||||
char const * code_get_filename(Code * code)
|
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;
|
return code->filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* code_get_format */
|
/* asmcode_get_format */
|
||||||
char const * code_get_format(Code * code)
|
char const * asmcode_get_format(AsmCode * code)
|
||||||
{
|
{
|
||||||
return format_get_name(code->format);
|
return format_get_name(code->format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* code_get_function_by_id */
|
/* asmcode_get_function_by_id */
|
||||||
AsmFunction * code_get_function_by_id(Code * code, AsmId id)
|
AsmFunction * asmcode_get_function_by_id(AsmCode * code, AsmFunctionId id)
|
||||||
{
|
{
|
||||||
/* XXX CodeFunction has to be exactly like an AsmFunction */
|
return _asmcode_element_get_by_id(code, AET_FUNCTION, id);
|
||||||
return _code_function_get_by_id(code, id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* code_get_string_by_id */
|
/* asmcode_get_functions */
|
||||||
AsmString * code_get_string_by_id(Code * code, AsmId id)
|
void asmcode_get_functions(AsmCode * code, AsmFunction ** functions,
|
||||||
|
size_t * functions_cnt)
|
||||||
{
|
{
|
||||||
/* XXX CodeString has to be exactly like an AsmString */
|
#ifdef DEBUG
|
||||||
return _code_string_get_by_id(code, id);
|
fprintf(stderr, "DEBUG: %s()\n", __func__);
|
||||||
|
#endif
|
||||||
|
*functions = code->elements[AET_FUNCTION];
|
||||||
|
*functions_cnt = code->elements_cnt[AET_FUNCTION];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* code_set_function */
|
/* asmcode_get_section_by_id */
|
||||||
int code_set_function(Code * code, int id, char const * name, off_t offset,
|
AsmSection * asmcode_get_section_by_id(AsmCode * code, AsmSectionId id)
|
||||||
ssize_t size)
|
|
||||||
{
|
{
|
||||||
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)
|
if(id >= 0)
|
||||||
cf = _code_function_get_by_id(code, id);
|
cf = _asmcode_function_get_by_id(code, id);
|
||||||
if(cf == NULL)
|
if(cf == NULL)
|
||||||
cf = _code_function_append(code);
|
cf = _asmcode_function_append(code);
|
||||||
if(cf == NULL || _code_function_set(cf, id, name, offset, size) != 0)
|
if(cf == NULL || _asmcode_function_set(cf, id, name, offset, size) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
/* FIXME isn't it considered an error if no ID is known yet? */
|
/* FIXME isn't it considered an error if no ID is known yet? */
|
||||||
return cf->id;
|
return cf->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* code_set_string */
|
/* asmcode_set_section */
|
||||||
int code_set_string(Code * code, int id, char const * name, off_t offset,
|
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)
|
ssize_t length)
|
||||||
{
|
{
|
||||||
CodeString * cs = NULL;
|
AsmString * cs = NULL;
|
||||||
|
|
||||||
if(id >= 0)
|
if(id >= 0)
|
||||||
cs = _code_string_get_by_id(code, id);
|
cs = _asmcode_string_get_by_id(code, id);
|
||||||
if(cs == NULL)
|
if(cs == NULL)
|
||||||
cs = _code_string_append(code);
|
cs = _asmcode_string_append(code);
|
||||||
if(cs == NULL || _code_string_set(cs, id, name, offset, length) != 0)
|
if(cs == NULL || _asmcode_string_set(cs, id, name, offset, length) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
/* FIXME isn't it considered an error if no ID is known yet? */
|
/* FIXME isn't it considered an error if no ID is known yet? */
|
||||||
return cs->id;
|
return cs->id;
|
||||||
@ -303,8 +363,8 @@ int code_set_string(Code * code, int id, char const * name, off_t offset,
|
|||||||
|
|
||||||
|
|
||||||
/* useful */
|
/* useful */
|
||||||
/* code_close */
|
/* asmcode_close */
|
||||||
int code_close(Code * code)
|
int asmcode_close(AsmCode * code)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@ -318,101 +378,67 @@ int code_close(Code * code)
|
|||||||
ret |= -error_set_code(1, "%s: %s", code->filename,
|
ret |= -error_set_code(1, "%s: %s", code->filename,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
code->fp = NULL;
|
code->fp = NULL;
|
||||||
_code_string_delete_all(code);
|
_asmcode_string_delete_all(code);
|
||||||
_code_function_delete_all(code);
|
_asmcode_function_delete_all(code);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* code_decode */
|
/* asmcode_decode */
|
||||||
int code_decode(Code * code, int raw)
|
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);
|
return format_decode(code->format, code, raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* code_decode_at */
|
/* asmcode_decode_at */
|
||||||
static void _decode_at_print_address(ArchDescription * description,
|
int asmcode_decode_at(AsmCode * code, off_t offset, size_t size, off_t base,
|
||||||
unsigned long address);
|
ArchInstructionCall ** calls, size_t * calls_cnt)
|
||||||
|
|
||||||
int code_decode_at(Code * code, char const * section, off_t offset,
|
|
||||||
size_t size, off_t base)
|
|
||||||
{
|
{
|
||||||
ArchDescription * description;
|
#ifdef DEBUG
|
||||||
ArchInstructionCall * calls = NULL;
|
fprintf(stderr, "DEBUG: %s(%ld, %lu, %ld)\n", __func__, offset, size,
|
||||||
size_t calls_cnt = 0;
|
base);
|
||||||
size_t i;
|
#endif
|
||||||
|
if(arch_decode_at(code->arch, code, offset, size, base, calls,
|
||||||
if(section != NULL)
|
calls_cnt) != 0)
|
||||||
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)
|
|
||||||
return -1;
|
return -1;
|
||||||
return 0;
|
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)
|
/* asmcode_decode_buffer */
|
||||||
{
|
int asmcode_decode_buffer(AsmCode * code, char const * buffer, size_t size,
|
||||||
case 64:
|
ArchInstructionCall ** calls, size_t * calls_cnt)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
ArchDescription * description;
|
ArchDescription * description;
|
||||||
ArchInstructionCall * calls = NULL;
|
|
||||||
size_t calls_cnt = 0;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
arch_init_buffer(code->arch, buffer, size);
|
arch_init_buffer(code->arch, buffer, size);
|
||||||
description = arch_get_description(code->arch);
|
description = arch_get_description(code->arch);
|
||||||
if((ret = arch_decode(code->arch, code, &calls, &calls_cnt, 0)) == 0)
|
ret = arch_decode(code->arch, code, 0, calls, calls_cnt);
|
||||||
{
|
|
||||||
for(i = 0; i < calls_cnt; i++)
|
|
||||||
code_print(code, description, &calls[i]);
|
|
||||||
free(calls);
|
|
||||||
}
|
|
||||||
arch_exit(code->arch);
|
arch_exit(code->arch);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* code_function */
|
/* asmcode_decode_section */
|
||||||
int code_function(Code * code, char const * function)
|
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);
|
return format_function(code->format, function);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* code_instruction */
|
/* asmcode_instruction */
|
||||||
int code_instruction(Code * code, ArchInstructionCall * call)
|
int asmcode_instruction(AsmCode * code, ArchInstructionCall * call)
|
||||||
{
|
{
|
||||||
ArchInstruction * ai;
|
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,
|
", 3 0x%x\n", call->name, ai->opcode, ai->op1, ai->op2,
|
||||||
ai->op3);
|
ai->op3);
|
||||||
#endif
|
#endif
|
||||||
return arch_write(code->arch, ai, call);
|
return arch_encode(code->arch, ai, call);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* code_open */
|
/* asmcode_open */
|
||||||
int code_open(Code * code, char const * filename)
|
int asmcode_open(AsmCode * code, char const * filename)
|
||||||
{
|
{
|
||||||
if(code->filename != NULL || code->fp != NULL)
|
if(code->filename != NULL || code->fp != NULL)
|
||||||
return -error_set_code(1, "A file is already opened");
|
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,
|
static void _print_address(ArchDescription * description,
|
||||||
unsigned long address);
|
unsigned long address);
|
||||||
static void _print_immediate(ArchOperand * ao);
|
static void _print_immediate(ArchOperand * ao);
|
||||||
|
|
||||||
int code_print(Code * code, ArchDescription * description,
|
int asmcode_print(AsmCode * code, ArchInstructionCall * call)
|
||||||
ArchInstructionCall * call)
|
|
||||||
{
|
{
|
||||||
|
ArchDescription * description;
|
||||||
char const * sep = " ";
|
char const * sep = " ";
|
||||||
size_t i;
|
size_t i;
|
||||||
uint8_t u8;
|
uint8_t u8;
|
||||||
ArchOperand * ao;
|
ArchOperand * ao;
|
||||||
char const * name;
|
char const * name;
|
||||||
|
|
||||||
if(description == NULL)
|
|
||||||
description = arch_get_description(code->arch);
|
description = arch_get_description(code->arch);
|
||||||
if(arch_seek(code->arch, call->offset, SEEK_SET) < 0)
|
if(arch_seek(code->arch, call->offset, SEEK_SET) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -558,8 +583,8 @@ static void _print_immediate(ArchOperand * ao)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* code_section */
|
/* asmcode_section */
|
||||||
int code_section(Code * code, char const * section)
|
int asmcode_section(AsmCode * code, char const * section)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, section);
|
fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, section);
|
||||||
@ -569,38 +594,89 @@ int code_section(Code * code, char const * section)
|
|||||||
|
|
||||||
|
|
||||||
/* private */
|
/* private */
|
||||||
/* functions */
|
/* elements */
|
||||||
/* functions */
|
/* asmcode_element_set */
|
||||||
/* code_function_delete_all */
|
static int _asmcode_element_set(AsmElement * element, AsmElementId id,
|
||||||
static void _code_function_delete_all(Code * code)
|
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++)
|
if(name != NULL && (p = string_new(name)) == NULL)
|
||||||
free(code->functions[i].name);
|
return -1;
|
||||||
code->functions_cnt = 0;
|
element->id = id;
|
||||||
free(code->functions);
|
free(element->name);
|
||||||
code->functions = NULL;
|
element->name = p;
|
||||||
|
element->offset = offset;
|
||||||
|
element->size = size;
|
||||||
|
element->base = base;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* code_function_get_by_id */
|
static AsmElement * _asmcode_element_append(AsmCode * code, AsmElementType type)
|
||||||
static CodeFunction * _code_function_get_by_id(Code * code, AsmId id)
|
|
||||||
{
|
{
|
||||||
size_t i;
|
AsmElement * p = code->elements[type];
|
||||||
|
size_t cnt = code->elements_cnt[type];
|
||||||
|
|
||||||
for(i = 0; i < code->functions_cnt; i++)
|
if((p = realloc(p, sizeof(*p) * (cnt + 1))) == NULL)
|
||||||
if(code->functions[i].id >= 0
|
{
|
||||||
&& (AsmId)code->functions[i].id == id)
|
error_set_code(1, "%s", strerror(errno));
|
||||||
break;
|
|
||||||
if(i == code->functions_cnt)
|
|
||||||
return NULL;
|
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 void _asmcode_element_delete_all(AsmCode * code, AsmElementType type)
|
||||||
static int _code_function_set(CodeFunction * codefunction, int id,
|
{
|
||||||
|
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 const * name, off_t offset, ssize_t size)
|
||||||
{
|
{
|
||||||
char * p = NULL;
|
char * p = NULL;
|
||||||
@ -616,118 +692,96 @@ static int _code_function_set(CodeFunction * codefunction, int id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* code_function_append */
|
/* asmcode_function_append */
|
||||||
static CodeFunction * _code_function_append(Code * code)
|
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)
|
/* sections */
|
||||||
{
|
/* asmcode_section_get_by_id */
|
||||||
error_set_code(1, "%s", strerror(errno));
|
static AsmSection * _asmcode_section_get_by_id(AsmCode * code, AsmSectionId id)
|
||||||
return NULL;
|
{
|
||||||
}
|
return _asmcode_element_get_by_id(code, AET_SECTION, id);
|
||||||
code->functions = p;
|
}
|
||||||
p = &code->functions[code->functions_cnt++];
|
|
||||||
p->id = -1;
|
|
||||||
p->name = NULL;
|
/* asmcode_section_set */
|
||||||
p->offset = -1;
|
static int _asmcode_section_set(AsmSection * section, int id, char const * name,
|
||||||
p->size = -1;
|
off_t offset, ssize_t size, off_t base)
|
||||||
return p;
|
{
|
||||||
|
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 */
|
/* strings */
|
||||||
/* code_string_delete_all */
|
/* asmcode_string_delete_all */
|
||||||
static void _code_string_delete_all(Code * code)
|
static void _asmcode_string_delete_all(AsmCode * code)
|
||||||
{
|
{
|
||||||
size_t i;
|
_asmcode_element_delete_all(code, AET_STRING);
|
||||||
|
|
||||||
for(i = 0; i < code->strings_cnt; i++)
|
|
||||||
free(code->strings[i].name);
|
|
||||||
code->strings_cnt = 0;
|
|
||||||
free(code->strings);
|
|
||||||
code->strings = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* code_string_get_by_id */
|
/* asmcode_string_get_by_id */
|
||||||
static CodeString * _code_string_get_by_id(Code * code, AsmId 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((ret = _asmcode_element_get_by_id(code, AET_STRING, id)) == NULL)
|
||||||
if(code->strings[i].id >= 0 && (AsmId)code->strings[i].id == id)
|
|
||||||
break;
|
|
||||||
if(i == code->strings_cnt)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
if(code->strings[i].name == NULL)
|
if(ret->name == NULL)
|
||||||
_code_string_read(code, &code->strings[i]);
|
_asmcode_string_read(code, ret);
|
||||||
return &code->strings[i];
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* code_string_set */
|
/* asmcode_string_set */
|
||||||
static int _code_string_set(CodeString * codestring, int id, char const * name,
|
static int _asmcode_string_set(AsmString * codestring, int id,
|
||||||
off_t offset, ssize_t length)
|
char const * name, off_t offset, ssize_t length)
|
||||||
{
|
{
|
||||||
char * p = NULL;
|
return _asmcode_element_set(codestring, id, name, offset, length, 0);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* code_string_append */
|
/* asmcode_string_append */
|
||||||
static CodeString * _code_string_append(Code * code)
|
static AsmString * _asmcode_string_append(AsmCode * code)
|
||||||
{
|
{
|
||||||
CodeString * p;
|
return _asmcode_element_append(code, AET_STRING);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* code_string_read */
|
/* asmcode_string_read */
|
||||||
static int _code_string_read(Code * code, CodeString * codestring)
|
static int _asmcode_string_read(AsmCode * code, AsmString * codestring)
|
||||||
{
|
{
|
||||||
off_t offset; /* XXX should not have to be kept */
|
off_t offset; /* XXX should not have to be kept */
|
||||||
char * buf;
|
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"
|
return -error_set_code(1, "%s", "Insufficient information to"
|
||||||
" read string");
|
" read string");
|
||||||
if((offset = arch_seek(code->arch, 0, SEEK_CUR)) < 0)
|
if((offset = arch_seek(code->arch, 0, SEEK_CUR)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if((buf = malloc(codestring->length + 1)) == NULL)
|
if((buf = malloc(codestring->size + 1)) == NULL)
|
||||||
return -error_set_code(1, "%s", strerror(errno));
|
return -error_set_code(1, "%s", strerror(errno));
|
||||||
if(arch_seek(code->arch, codestring->offset, SEEK_SET)
|
if(arch_seek(code->arch, codestring->offset, SEEK_SET)
|
||||||
!= codestring->offset)
|
!= codestring->offset)
|
||||||
return -1;
|
return -1;
|
||||||
if(arch_read(code->arch, buf, codestring->length) != codestring->length)
|
if(arch_read(code->arch, buf, codestring->size) != codestring->size)
|
||||||
{
|
{
|
||||||
free(buf);
|
free(buf);
|
||||||
arch_seek(code->arch, offset, SEEK_SET);
|
arch_seek(code->arch, offset, SEEK_SET);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
buf[codestring->length] = '\0';
|
buf[codestring->size] = '\0';
|
||||||
free(codestring->name);
|
free(codestring->name);
|
||||||
codestring->name = buf;
|
codestring->name = buf;
|
||||||
arch_seek(code->arch, offset, SEEK_SET);
|
arch_seek(code->arch, offset, SEEK_SET);
|
||||||
|
50
src/code.h
50
src/code.h
@ -19,48 +19,28 @@
|
|||||||
# define ASM_CODE_H
|
# define ASM_CODE_H
|
||||||
|
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
# include "Asm/arch.h"
|
# include "Asm/code.h"
|
||||||
|
|
||||||
|
|
||||||
/* types */
|
|
||||||
typedef struct _Code Code;
|
|
||||||
|
|
||||||
|
|
||||||
/* functions */
|
/* functions */
|
||||||
Code * code_new(char const * arch, char const * format);
|
AsmCode * asmcode_new(char const * arch, char const * format);
|
||||||
Code * code_new_file(char const * arch, char const * format,
|
AsmCode * asmcode_new_file(char const * arch, char const * format,
|
||||||
char const * filename);
|
char const * filename);
|
||||||
int code_delete(Code * code);
|
int asmcode_delete(AsmCode * 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);
|
|
||||||
|
|
||||||
/* useful */
|
/* useful */
|
||||||
/* common */
|
/* common */
|
||||||
int code_open(Code * code, char const * filename);
|
int asmcode_open(AsmCode * code, char const * filename);
|
||||||
int code_close(Code * code);
|
int asmcode_close(AsmCode * code);
|
||||||
|
|
||||||
/* assembly */
|
/* elements */
|
||||||
int code_function(Code * code, char const * function);
|
AsmElement * asmcode_get_element_by_id(AsmCode * a, AsmElementType type,
|
||||||
int code_instruction(Code * code, ArchInstructionCall * call);
|
AsmElementId id);
|
||||||
int code_section(Code * code, char const * section);
|
AsmElement * asmcode_get_element_by_name(AsmCode * af, AsmElementType type,
|
||||||
|
char const * name);
|
||||||
/* disassembly */
|
AsmElement * asmcode_get_element_by_offset(AsmCode * af, AsmElementType type,
|
||||||
int code_decode(Code * code, int raw);
|
off_t offset);
|
||||||
int code_decode_at(Code * code, char const * section, off_t offset,
|
int asmcode_get_elements(AsmCode * af, AsmElementType type,
|
||||||
size_t size, off_t base);
|
AsmElement ** elements, size_t * count);
|
||||||
int code_decode_buffer(Code * code, char const * buffer, size_t size);
|
|
||||||
int code_print(Code * code, ArchDescription * description,
|
|
||||||
ArchInstructionCall * call);
|
|
||||||
|
|
||||||
#endif /* !ASM_CODE_H */
|
#endif /* !ASM_CODE_H */
|
||||||
|
70
src/deasm.c
70
src/deasm.c
@ -40,35 +40,89 @@ static int _usage(void);
|
|||||||
|
|
||||||
/* functions */
|
/* functions */
|
||||||
/* deasm */
|
/* deasm */
|
||||||
|
static int _deasm_section(AsmCode * code, AsmSection * section);
|
||||||
|
|
||||||
static int _deasm(char const * arch, char const * format, char const * filename,
|
static int _deasm(char const * arch, char const * format, char const * filename,
|
||||||
int raw)
|
int raw)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
Asm * a;
|
Asm * a;
|
||||||
|
AsmCode * code;
|
||||||
|
AsmSection * sections;
|
||||||
|
size_t sections_cnt;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
if((a = asm_new(arch, format)) == NULL)
|
if((a = asm_new(arch, format)) == NULL)
|
||||||
return -error_print("deasm");
|
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");
|
error_print("deasm");
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
printf("%s: %s-%s\n", filename, asm_get_format(a),
|
||||||
|
asm_get_arch(a));
|
||||||
|
asmcode_get_sections(code, §ions, §ions_cnt);
|
||||||
|
for(i = 0; i < sections_cnt; i++)
|
||||||
|
if((ret = _deasm_section(code, §ions[i])) != 0)
|
||||||
|
break;
|
||||||
asm_close(a);
|
asm_close(a);
|
||||||
|
}
|
||||||
asm_delete(a);
|
asm_delete(a);
|
||||||
return ret;
|
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 */
|
/* deasm_buffer */
|
||||||
static int _deasm_buffer(char const * arch, char const * buffer, size_t size)
|
static int _deasm_buffer(char const * arch, char const * buffer, size_t size)
|
||||||
{
|
{
|
||||||
Asm * a;
|
Asm * a;
|
||||||
|
AsmCode * code;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "DEBUG: %s()\n", __func__);
|
fprintf(stderr, "DEBUG: %s()\n", __func__);
|
||||||
#endif
|
#endif
|
||||||
if((a = asm_new(arch, NULL)) == NULL)
|
if((a = asm_new(arch, NULL)) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
if(asm_deassemble(a, buffer, size) != 0)
|
if((code = asm_deassemble(a, buffer, size, NULL, NULL)) == NULL)
|
||||||
error_print("deasm");
|
error_print("deasm");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* FIXME implement */
|
||||||
|
}
|
||||||
asm_delete(a);
|
asm_delete(a);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -138,8 +192,8 @@ static int _deasm_list(void)
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "DEBUG: %s()\n", __func__);
|
fprintf(stderr, "DEBUG: %s()\n", __func__);
|
||||||
#endif
|
#endif
|
||||||
asm_plugin_list(APT_ARCH);
|
asm_plugin_list(APT_ARCH, 1);
|
||||||
asm_plugin_list(APT_FORMAT);
|
asm_plugin_list(APT_FORMAT, 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,9 +201,13 @@ static int _deasm_list(void)
|
|||||||
/* usage */
|
/* usage */
|
||||||
static int _usage(void)
|
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 [-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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
109
src/format.c
109
src/format.c
@ -40,21 +40,28 @@ struct _Format
|
|||||||
FILE * fp;
|
FILE * fp;
|
||||||
|
|
||||||
/* deassembly */
|
/* deassembly */
|
||||||
Code * code;
|
AsmCode * code;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
/* helpers */
|
/* helpers */
|
||||||
static char const * _format_helper_get_filename(Format * format);
|
static char const * _format_helper_get_filename(Format * format);
|
||||||
static AsmString * _format_helper_get_string_by_id(Format * format, AsmId id);
|
static void _format_helper_get_functions(Format * format,
|
||||||
static int _format_helper_set_function(Format * format, int id,
|
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);
|
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,
|
static int _format_helper_decode(Format * format, off_t offset, size_t size,
|
||||||
off_t offset, size_t size, off_t base);
|
off_t base, ArchInstructionCall ** calls, size_t * calls_cnt);
|
||||||
static ssize_t _format_helper_read(Format * format, void * buf, size_t size);
|
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 off_t _format_helper_seek(Format * format, off_t offset, int whence);
|
||||||
static ssize_t _format_helper_write(Format * format, void const * buf,
|
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.format = f;
|
||||||
f->helper.decode = _format_helper_decode;
|
f->helper.decode = _format_helper_decode;
|
||||||
f->helper.get_filename = _format_helper_get_filename;
|
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.get_string_by_id = _format_helper_get_string_by_id;
|
||||||
f->helper.set_function = _format_helper_set_function;
|
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.set_string = _format_helper_set_string;
|
||||||
f->helper.read = _format_helper_read;
|
f->helper.read = _format_helper_read;
|
||||||
f->helper.seek = _format_helper_seek;
|
f->helper.seek = _format_helper_seek;
|
||||||
@ -115,6 +125,14 @@ void format_delete(Format * format)
|
|||||||
|
|
||||||
|
|
||||||
/* accessors */
|
/* accessors */
|
||||||
|
/* format_can_decode */
|
||||||
|
int format_can_decode(Format * format)
|
||||||
|
{
|
||||||
|
return format->plugin->decode != NULL
|
||||||
|
/* && format->plugin->decode_section != NULL */;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* format_get_arch */
|
/* format_get_arch */
|
||||||
char const * format_get_arch(Format * format)
|
char const * format_get_arch(Format * format)
|
||||||
{
|
{
|
||||||
@ -133,12 +151,12 @@ char const * format_get_name(Format * format)
|
|||||||
|
|
||||||
/* useful */
|
/* useful */
|
||||||
/* format_decode */
|
/* format_decode */
|
||||||
int format_decode(Format * format, Code * code, int raw)
|
int format_decode(Format * format, AsmCode * code, int raw)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if(format->plugin->decode == NULL)
|
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");
|
"Disassembly is not supported");
|
||||||
format->code = code;
|
format->code = code;
|
||||||
ret = format->plugin->decode(format->plugin, raw);
|
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 */
|
/* format_detect_arch */
|
||||||
char const * format_detect_arch(Format * format)
|
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 */
|
/* format_helper_get_functions */
|
||||||
static AsmString * _format_helper_get_string_by_id(Format * format, AsmId id)
|
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 */
|
/* 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)
|
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 */
|
/* format_helper_set_string */
|
||||||
static int _format_helper_set_string(Format * format, int id, char const * name,
|
static int _format_helper_set_string(Format * format, AsmStringId id,
|
||||||
off_t offset, ssize_t size)
|
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 */
|
/* format_helper_decode */
|
||||||
static int _format_helper_decode(Format * format, char const * section,
|
static int _format_helper_decode(Format * format, off_t offset, size_t size,
|
||||||
off_t offset, size_t size, off_t base)
|
off_t base, ArchInstructionCall ** calls, size_t * calls_cnt)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "DEBUG: %s(\"%s\", 0x%lx, 0x%lx, 0x%lx)\n", __func__,
|
fprintf(stderr, "DEBUG: %s(0x%lx, 0x%lx, 0x%lx)\n", __func__, offset,
|
||||||
section, offset, size, base);
|
size, base);
|
||||||
#endif
|
#endif
|
||||||
if((ret = code_decode_at(format->code, section, offset, size, base))
|
if((ret = asmcode_decode_at(format->code, offset, size, base,
|
||||||
!= 0)
|
calls, calls_cnt)) != 0)
|
||||||
error_print("deasm");
|
error_print("deasm");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
17
src/format.h
17
src/format.h
@ -18,6 +18,7 @@
|
|||||||
#ifndef ASM_FORMAT_H
|
#ifndef ASM_FORMAT_H
|
||||||
# define ASM_FORMAT_H
|
# define ASM_FORMAT_H
|
||||||
|
|
||||||
|
# include "Asm/common.h"
|
||||||
# include "Asm/format.h"
|
# include "Asm/format.h"
|
||||||
# include "code.h"
|
# include "code.h"
|
||||||
|
|
||||||
@ -27,17 +28,19 @@
|
|||||||
/* types */
|
/* types */
|
||||||
typedef int (*FormatDecodeCallback)(void * priv, char const * section,
|
typedef int (*FormatDecodeCallback)(void * priv, char const * section,
|
||||||
off_t offset, size_t size, off_t base);
|
off_t offset, size_t size, off_t base);
|
||||||
typedef AsmString * (*FormatGetStringByIdCallback)(void * priv, AsmId id);
|
typedef AsmString * (*FormatGetStringByIdCallback)(void * priv, AsmStringId id);
|
||||||
typedef int (*FormatSetFunctionCallback)(void * priv, int id, char const * name,
|
typedef int (*FormatSetFunctionCallback)(void * priv, AsmFunctionId id,
|
||||||
off_t offset, ssize_t length);
|
char const * name, off_t offset, ssize_t length);
|
||||||
typedef int (*FormatSetStringCallback)(void * priv, int id, char const * name,
|
typedef int (*FormatSetStringCallback)(void * priv, AsmStringId id,
|
||||||
off_t offset, ssize_t length);
|
char const * name, off_t offset, ssize_t length);
|
||||||
|
|
||||||
/* functions */
|
/* functions */
|
||||||
Format * format_new(char const * format);
|
Format * format_new(char const * format);
|
||||||
void format_delete(Format * format);
|
void format_delete(Format * format);
|
||||||
|
|
||||||
/* accessors */
|
/* accessors */
|
||||||
|
int format_can_decode(Format * format);
|
||||||
|
|
||||||
char const * format_get_name(Format * format);
|
char const * format_get_name(Format * format);
|
||||||
|
|
||||||
/* useful */
|
/* useful */
|
||||||
@ -50,7 +53,9 @@ int format_function(Format * format, char const * function);
|
|||||||
int format_section(Format * format, char const * section);
|
int format_section(Format * format, char const * section);
|
||||||
|
|
||||||
/* disassembly */
|
/* 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);
|
char const * format_detect_arch(Format * format);
|
||||||
int format_match(Format * format);
|
int format_match(Format * format);
|
||||||
|
|
||||||
|
151
src/format/dex.c
151
src/format/dex.c
@ -126,6 +126,8 @@ static int _dex_init(FormatPlugin * format, char const * arch);
|
|||||||
static int _dex_exit(FormatPlugin * format);
|
static int _dex_exit(FormatPlugin * format);
|
||||||
static char const * _dex_detect(FormatPlugin * format);
|
static char const * _dex_detect(FormatPlugin * format);
|
||||||
static int _dex_decode(FormatPlugin * format, int raw);
|
static int _dex_decode(FormatPlugin * format, int raw);
|
||||||
|
static int _dex_decode_section(FormatPlugin * format, AsmSection * section,
|
||||||
|
ArchInstructionCall ** calls, size_t * calls_cnt);
|
||||||
|
|
||||||
|
|
||||||
/* public */
|
/* public */
|
||||||
@ -142,6 +144,7 @@ FormatPlugin format_plugin =
|
|||||||
NULL,
|
NULL,
|
||||||
_dex_detect,
|
_dex_detect,
|
||||||
_dex_decode,
|
_dex_decode,
|
||||||
|
_dex_decode_section,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -183,14 +186,15 @@ static int _dex_exit(FormatPlugin * format)
|
|||||||
/* dex_detect */
|
/* dex_detect */
|
||||||
static char const * _dex_detect(FormatPlugin * format)
|
static char const * _dex_detect(FormatPlugin * format)
|
||||||
{
|
{
|
||||||
/* FIXME some sections might contain native code */
|
/* XXX some sections might contain native code */
|
||||||
return "dalvik";
|
return "dalvik";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* dex_decode */
|
/* dex_decode */
|
||||||
static int _decode_map(FormatPlugin * format, DexHeader * dh);
|
static int _decode_map(FormatPlugin * format, DexHeader * dh, int raw);
|
||||||
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);
|
||||||
static int _decode_map_method_id(FormatPlugin * format, off_t offset,
|
static int _decode_map_method_id(FormatPlugin * format, off_t offset,
|
||||||
size_t size);
|
size_t size);
|
||||||
static int _decode_map_string_id(FormatPlugin * format, off_t offset,
|
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;
|
FormatPluginHelper * helper = format->helper;
|
||||||
DexHeader dh;
|
DexHeader dh;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "DEBUG: %s(%d)\n", __func__, raw);
|
||||||
|
#endif
|
||||||
if(helper->seek(helper->format, 0, SEEK_SET) != 0)
|
if(helper->seek(helper->format, 0, SEEK_SET) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
if(helper->read(helper->format, &dh, sizeof(dh)) != sizeof(dh))
|
if(helper->read(helper->format, &dh, sizeof(dh)) != sizeof(dh))
|
||||||
return -1;
|
return -1;
|
||||||
dh.map_off = _htol32(dh.map_off);
|
dh.map_off = _htol32(dh.map_off);
|
||||||
if(_decode_map(format, &dh) != 0)
|
if(_decode_map(format, &dh, raw) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _decode_map(FormatPlugin * format, DexHeader * dh)
|
static int _decode_map(FormatPlugin * format, DexHeader * dh, int raw)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
FormatPluginHelper * helper = format->helper;
|
FormatPluginHelper * helper = format->helper;
|
||||||
@ -247,7 +254,7 @@ static int _decode_map(FormatPlugin * format, DexHeader * dh)
|
|||||||
switch(dmi.type)
|
switch(dmi.type)
|
||||||
{
|
{
|
||||||
case TYPE_CODE_ITEM:
|
case TYPE_CODE_ITEM:
|
||||||
ret |= _decode_map_code(format, dmi.offset,
|
ret |= _decode_map_code(format, i, dmi.offset,
|
||||||
dmi.size);
|
dmi.size);
|
||||||
break;
|
break;
|
||||||
case TYPE_METHOD_ID_ITEM:
|
case TYPE_METHOD_ID_ITEM:
|
||||||
@ -267,64 +274,17 @@ static int _decode_map(FormatPlugin * format, DexHeader * dh)
|
|||||||
return ret;
|
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;
|
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
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "DEBUG: code item %lu, offset 0x%lx"
|
fprintf(stderr, "DEBUG: %s(%lu, %ld, %lu)\n", __func__, id, offset,
|
||||||
", registers 0x%x, size 0x%x, debug @0x%x"
|
size);
|
||||||
", 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
|
#endif
|
||||||
if(seek != 0 && helper->seek(helper->format, seek, SEEK_CUR)
|
return (helper->set_section(helper->format, id, ".text", offset, size,
|
||||||
< 0)
|
0) == id) ? 0 : -1;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _decode_map_method_id(FormatPlugin * format, off_t offset,
|
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;
|
AsmString * string;
|
||||||
char const * name;
|
char const * name;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "DEBUG: %s(%ld, %lu)\n", __func__, offset, size);
|
||||||
|
#endif
|
||||||
if(dex->dmii != NULL)
|
if(dex->dmii != NULL)
|
||||||
return 0; /* already parsed */
|
return 0; /* already parsed */
|
||||||
if(helper->seek(helper->format, offset, SEEK_SET) != offset)
|
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;
|
size_t i;
|
||||||
uint8_t u8;
|
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)
|
if(helper->seek(helper->format, offset, SEEK_SET) != offset)
|
||||||
return -1;
|
return -1;
|
||||||
s = sizeof(*dsii) * size;
|
s = sizeof(*dsii) * size;
|
||||||
@ -396,3 +362,70 @@ static int _decode_map_string_id(FormatPlugin * format, off_t offset,
|
|||||||
free(dsii);
|
free(dsii);
|
||||||
return (i == size) ? 0 : -1;
|
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;
|
||||||
|
}
|
||||||
|
@ -12,6 +12,9 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
* 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_decode(FormatPlugin * format, int raw);
|
||||||
static int _elf_decode32(FormatPlugin * format, int raw);
|
static int _elf_decode32(FormatPlugin * format, int raw);
|
||||||
static int _elf_decode64(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 */
|
/* ELF32 */
|
||||||
static int _init_32(FormatPlugin * format);
|
static int _init_32(FormatPlugin * format);
|
||||||
@ -106,11 +111,15 @@ static ElfArch elf_arch[] =
|
|||||||
{
|
{
|
||||||
{ "amd64", EM_X86_64, ELFCLASS64, ELFDATA2LSB, 0x4 },
|
{ "amd64", EM_X86_64, ELFCLASS64, ELFDATA2LSB, 0x4 },
|
||||||
{ "arm", EM_ARM, ELFCLASS32, ELFDATA2LSB, 0x0 },
|
{ "arm", EM_ARM, ELFCLASS32, ELFDATA2LSB, 0x0 },
|
||||||
|
{ "armeb", EM_ARM, ELFCLASS32, ELFDATA2MSB, 0x0 },
|
||||||
|
{ "armel", EM_ARM, ELFCLASS32, ELFDATA2LSB, 0x0 },
|
||||||
{ "i386", EM_386, ELFCLASS32, ELFDATA2LSB, 0x4 },
|
{ "i386", EM_386, ELFCLASS32, ELFDATA2LSB, 0x4 },
|
||||||
{ "i486", EM_386, ELFCLASS32, ELFDATA2LSB, 0x4 },
|
{ "i486", EM_386, ELFCLASS32, ELFDATA2LSB, 0x4 },
|
||||||
{ "i586", EM_386, ELFCLASS32, ELFDATA2LSB, 0x4 },
|
{ "i586", EM_386, ELFCLASS32, ELFDATA2LSB, 0x4 },
|
||||||
{ "i686", EM_386, ELFCLASS32, ELFDATA2LSB, 0x4 },
|
{ "i686", EM_386, ELFCLASS32, ELFDATA2LSB, 0x4 },
|
||||||
{ "mips", EM_MIPS, ELFCLASS32, ELFDATA2MSB, 0x0 },
|
{ "mips", EM_MIPS, ELFCLASS32, ELFDATA2MSB, 0x0 },
|
||||||
|
{ "mipseb", EM_MIPS, ELFCLASS32, ELFDATA2MSB, 0x0 },
|
||||||
|
{ "mipsel", EM_MIPS, ELFCLASS32, ELFDATA2LSB, 0x0 },
|
||||||
{ "sparc", EM_SPARC, ELFCLASS32, ELFDATA2MSB, 0x0 },
|
{ "sparc", EM_SPARC, ELFCLASS32, ELFDATA2MSB, 0x0 },
|
||||||
{ "sparc64", EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, 0x0 },
|
{ "sparc64", EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, 0x0 },
|
||||||
{ NULL, '\0', '\0', '\0', 0x0 }
|
{ NULL, '\0', '\0', '\0', 0x0 }
|
||||||
@ -174,6 +183,7 @@ FormatPlugin format_plugin =
|
|||||||
NULL,
|
NULL,
|
||||||
_elf_detect,
|
_elf_detect,
|
||||||
_elf_decode,
|
_elf_decode,
|
||||||
|
_elf_decode_section,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -202,7 +212,9 @@ static int _elf_init(FormatPlugin * format, char const * arch)
|
|||||||
return -1;
|
return -1;
|
||||||
format->priv = elf;
|
format->priv = elf;
|
||||||
elf->es32 = NULL;
|
elf->es32 = NULL;
|
||||||
|
elf->es32_cnt = 0;
|
||||||
elf->es64 = NULL;
|
elf->es64 = NULL;
|
||||||
|
elf->es64_cnt = 0;
|
||||||
if(arch == NULL)
|
if(arch == NULL)
|
||||||
{
|
{
|
||||||
elf->arch = NULL;
|
elf->arch = NULL;
|
||||||
@ -336,6 +348,9 @@ static char const * _detect_64(FormatPlugin * format, Elf64_Ehdr * ehdr)
|
|||||||
/* elf_decode */
|
/* elf_decode */
|
||||||
static int _elf_decode(FormatPlugin * format, int raw)
|
static int _elf_decode(FormatPlugin * format, int raw)
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "DEBUG: %s(%d)\n", __func__, raw);
|
||||||
|
#endif
|
||||||
if(_elf_detect(format) == NULL)
|
if(_elf_detect(format) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
return format->decode(format, raw);
|
return format->decode(format, raw);
|
||||||
@ -394,16 +409,17 @@ static int _elf_decode32(FormatPlugin * format, int raw)
|
|||||||
{
|
{
|
||||||
if(shdr[i].sh_name >= shstrtab_cnt)
|
if(shdr[i].sh_name >= shstrtab_cnt)
|
||||||
continue;
|
continue;
|
||||||
if(raw || (shdr[i].sh_type == SHT_PROGBITS
|
if((raw || (shdr[i].sh_type == SHT_PROGBITS && shdr[i].sh_flags
|
||||||
&& shdr[i].sh_flags & SHF_EXECINSTR))
|
& SHF_EXECINSTR))
|
||||||
helper->decode(helper->format,
|
&& helper->set_section(helper->format, i,
|
||||||
&shstrtab[shdr[i].sh_name],
|
&shstrtab[shdr[i].sh_name],
|
||||||
shdr[i].sh_offset, shdr[i].sh_size,
|
shdr[i].sh_offset, shdr[i].sh_size,
|
||||||
base + shdr[i].sh_offset);
|
base + shdr[i].sh_offset) < 0)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
free(shstrtab);
|
free(shstrtab);
|
||||||
free(shdr);
|
free(shdr);
|
||||||
return 0;
|
return (i == ehdr.e_shnum) ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _decode32_shdr(FormatPlugin * format, Elf32_Ehdr * ehdr,
|
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)
|
if(shdr[i].sh_name >= shstrtab_cnt)
|
||||||
continue;
|
continue;
|
||||||
if(raw || (shdr[i].sh_type == SHT_PROGBITS
|
if((raw || (shdr[i].sh_type == SHT_PROGBITS && shdr[i].sh_flags
|
||||||
&& shdr[i].sh_flags & SHF_EXECINSTR))
|
& SHF_EXECINSTR))
|
||||||
helper->decode(helper->format,
|
&& helper->set_section(helper->format, i,
|
||||||
&shstrtab[shdr[i].sh_name],
|
&shstrtab[shdr[i].sh_name],
|
||||||
shdr[i].sh_offset, shdr[i].sh_size,
|
shdr[i].sh_offset, shdr[i].sh_size,
|
||||||
base + shdr[i].sh_offset);
|
base + shdr[i].sh_offset) < 0)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
free(shstrtab);
|
free(shstrtab);
|
||||||
free(shdr);
|
free(shdr);
|
||||||
return 0;
|
return (i == ehdr.e_shnum) ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _decode64_shdr(FormatPlugin * format, Elf64_Ehdr * ehdr,
|
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 */
|
/* section_values */
|
||||||
static ElfSectionValues * _section_values(char const * name)
|
static ElfSectionValues * _section_values(char const * name)
|
||||||
{
|
{
|
||||||
ElfSectionValues * esv;
|
ElfSectionValues * esv;
|
||||||
int cmp;
|
int cmp;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, name);
|
||||||
|
#endif
|
||||||
for(esv = elf_section_values; esv->name != NULL; esv++)
|
for(esv = elf_section_values; esv->name != NULL; esv++)
|
||||||
if((cmp = strcmp(esv->name, name)) == 0)
|
if((cmp = strcmp(esv->name, name)) == 0)
|
||||||
return esv;
|
return esv;
|
||||||
@ -789,6 +820,9 @@ static int _exit_32(FormatPlugin * format)
|
|||||||
FormatPluginHelper * helper = format->helper;
|
FormatPluginHelper * helper = format->helper;
|
||||||
long offset;
|
long offset;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "DEBUG: %s()\n", __func__);
|
||||||
|
#endif
|
||||||
if(_section_32(format, ".shstrtab") != 0)
|
if(_section_32(format, ".shstrtab") != 0)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
else if(helper->write(helper->format, shstrtab.buf, shstrtab.cnt)
|
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;
|
ElfArch * ea = elf->arch;
|
||||||
Elf32_Ehdr hdr;
|
Elf32_Ehdr hdr;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "DEBUG: %s()\n", __func__);
|
||||||
|
#endif
|
||||||
if(elf->es32_cnt == 0)
|
if(elf->es32_cnt == 0)
|
||||||
return 0;
|
return 0;
|
||||||
if(helper->seek(helper->format, 0, SEEK_SET) != 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;
|
Elf32_Shdr hdr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "DEBUG: %s()\n", __func__);
|
||||||
|
#endif
|
||||||
if(helper->seek(helper->format, 0, SEEK_END) < 0)
|
if(helper->seek(helper->format, 0, SEEK_END) < 0)
|
||||||
return _elf_error(format);
|
return _elf_error(format);
|
||||||
memset(&hdr, 0, sizeof(hdr));
|
memset(&hdr, 0, sizeof(hdr));
|
||||||
@ -865,6 +905,9 @@ static int _exit_32_shdr(FormatPlugin * format, Elf32_Off offset)
|
|||||||
return -1;
|
return -1;
|
||||||
for(i = 0; i < elf->es32_cnt; i++)
|
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)
|
if(i + 1 == elf->es32_cnt)
|
||||||
es32[i].sh_size = offset - es32[i].sh_offset;
|
es32[i].sh_size = offset - es32[i].sh_offset;
|
||||||
else
|
else
|
||||||
@ -895,6 +938,9 @@ static int _section_32(FormatPlugin * format, char const * name)
|
|||||||
ElfSectionValues * esv;
|
ElfSectionValues * esv;
|
||||||
long offset;
|
long offset;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, name);
|
||||||
|
#endif
|
||||||
if((ss = _elfstrtab_set(format, &shstrtab, name)) < 0)
|
if((ss = _elfstrtab_set(format, &shstrtab, name)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if((p = realloc(elf->es32, sizeof(*p) * (elf->es32_cnt + 1))) == NULL)
|
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_name = ss;
|
||||||
p->sh_type = esv->type;
|
p->sh_type = esv->type;
|
||||||
p->sh_flags = esv->flags;
|
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)
|
if((offset = helper->seek(helper->format, 0, SEEK_CUR)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "DEBUG: %s() %s\n", __func__, "after seek()");
|
||||||
|
#endif
|
||||||
p->sh_offset = offset;
|
p->sh_offset = offset;
|
||||||
p->sh_link = SHN_UNDEF; /* FIXME */
|
p->sh_link = SHN_UNDEF; /* FIXME */
|
||||||
return 0;
|
return 0;
|
||||||
@ -1130,8 +1182,14 @@ static int _section_64(FormatPlugin * format, char const * name)
|
|||||||
p->sh_name = ss;
|
p->sh_name = ss;
|
||||||
p->sh_type = esv->type;
|
p->sh_type = esv->type;
|
||||||
p->sh_flags = esv->flags;
|
p->sh_flags = esv->flags;
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "DEBUG: %s() %s\n", __func__, "before seek()");
|
||||||
|
#endif
|
||||||
if((offset = helper->seek(helper->format, 0, SEEK_CUR)) < 0)
|
if((offset = helper->seek(helper->format, 0, SEEK_CUR)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "DEBUG: %s() %s\n", __func__, "after seek()");
|
||||||
|
#endif
|
||||||
p->sh_offset = offset;
|
p->sh_offset = offset;
|
||||||
p->sh_link = SHN_UNDEF; /* FIXME */
|
p->sh_link = SHN_UNDEF; /* FIXME */
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
/* prototypes */
|
/* prototypes */
|
||||||
/* plug-in */
|
/* plug-in */
|
||||||
static int _flat_decode(FormatPlugin * format, int raw);
|
static int _flat_decode(FormatPlugin * format, int raw);
|
||||||
|
static int _flat_decode_section(FormatPlugin * format, AsmSection * section,
|
||||||
|
ArchInstructionCall ** calls, size_t * calls_cnt);
|
||||||
|
|
||||||
|
|
||||||
/* public */
|
/* public */
|
||||||
@ -41,6 +43,7 @@ FormatPlugin format_plugin =
|
|||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
_flat_decode,
|
_flat_decode,
|
||||||
|
_flat_decode_section,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -54,7 +57,21 @@ static int _flat_decode(FormatPlugin * format, int raw)
|
|||||||
FormatPluginHelper * helper = format->helper;
|
FormatPluginHelper * helper = format->helper;
|
||||||
off_t offset;
|
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 -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);
|
||||||
}
|
}
|
||||||
|
@ -106,6 +106,8 @@ static int _java_init(FormatPlugin * format, char const * arch);
|
|||||||
static int _java_exit(FormatPlugin * format);
|
static int _java_exit(FormatPlugin * format);
|
||||||
static char const * _java_detect(FormatPlugin * format);
|
static char const * _java_detect(FormatPlugin * format);
|
||||||
static int _java_decode(FormatPlugin * format, int raw);
|
static int _java_decode(FormatPlugin * format, int raw);
|
||||||
|
static int _java_decode_section(FormatPlugin * format, AsmSection * section,
|
||||||
|
ArchInstructionCall ** calls, size_t * calls_cnt);
|
||||||
|
|
||||||
|
|
||||||
/* public */
|
/* public */
|
||||||
@ -123,6 +125,7 @@ FormatPlugin format_plugin =
|
|||||||
NULL,
|
NULL,
|
||||||
_java_detect,
|
_java_detect,
|
||||||
_java_decode,
|
_java_decode,
|
||||||
|
_java_decode_section,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -325,7 +328,8 @@ static int _java_decode(FormatPlugin * format, int raw)
|
|||||||
|| (end = helper->seek(helper->format, 0, SEEK_END))
|
|| (end = helper->seek(helper->format, 0, SEEK_END))
|
||||||
< 0)
|
< 0)
|
||||||
return -1;
|
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)
|
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 -1;
|
||||||
return 0;
|
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);
|
||||||
|
}
|
||||||
|
@ -213,6 +213,8 @@ static char const _pe_header_signature[4] = "PE\0\0";
|
|||||||
static int _pe_init(FormatPlugin * format, char const * arch);
|
static int _pe_init(FormatPlugin * format, char const * arch);
|
||||||
static char const * _pe_detect(FormatPlugin * format);
|
static char const * _pe_detect(FormatPlugin * format);
|
||||||
static int _pe_decode(FormatPlugin * format, int raw);
|
static int _pe_decode(FormatPlugin * format, int raw);
|
||||||
|
static int _pe_decode_section(FormatPlugin * format, AsmSection * section,
|
||||||
|
ArchInstructionCall ** calls, size_t * calls_cnt);
|
||||||
|
|
||||||
/* useful */
|
/* useful */
|
||||||
static char const * _pe_get_arch(uint16_t machine);
|
static char const * _pe_get_arch(uint16_t machine);
|
||||||
@ -233,6 +235,7 @@ FormatPlugin format_plugin =
|
|||||||
NULL,
|
NULL,
|
||||||
_pe_detect,
|
_pe_detect,
|
||||||
_pe_decode,
|
_pe_decode,
|
||||||
|
_pe_decode_section,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -385,7 +388,7 @@ static int _pe_decode(FormatPlugin * format, int raw)
|
|||||||
i) != 0)
|
i) != 0)
|
||||||
break; /* XXX report error */
|
break; /* XXX report error */
|
||||||
}
|
}
|
||||||
/* read and decode each section */
|
/* read and record each section */
|
||||||
offset = pm.offset + sizeof(_pe_header_signature) + sizeof(ph)
|
offset = pm.offset + sizeof(_pe_header_signature) + sizeof(ph)
|
||||||
+ ph.opthdr_size;
|
+ ph.opthdr_size;
|
||||||
if(ph.opthdr_size != 0 && helper->seek(helper->format, offset, SEEK_SET)
|
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 */
|
/* the $ sign has a special meaning for the linker */
|
||||||
if((q = strchr(psh.name, '$')) != NULL)
|
if((q = strchr(psh.name, '$')) != NULL)
|
||||||
*q = '\0';
|
*q = '\0';
|
||||||
if(helper->decode(helper->format, psh.name, psh.raw_offset,
|
if(helper->set_section(helper->format, i, psh.name,
|
||||||
psh.raw_size, psh.vaddr + base) != 0)
|
psh.raw_offset, psh.raw_size,
|
||||||
|
psh.vaddr + base) != 0)
|
||||||
break;
|
break;
|
||||||
if(helper->seek(helper->format, offset, SEEK_SET) != offset)
|
if(helper->seek(helper->format, offset, SEEK_SET) != offset)
|
||||||
break;
|
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 */
|
/* accessors */
|
||||||
/* pe_get_arch */
|
/* pe_get_arch */
|
||||||
static char const * _pe_get_arch(uint16_t machine)
|
static char const * _pe_get_arch(uint16_t machine)
|
||||||
|
53
src/main.c
53
src/main.c
@ -31,6 +31,13 @@
|
|||||||
# define ASM_FILENAME_DEFAULT "a.out"
|
# 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 */
|
/* functions */
|
||||||
/* asm */
|
/* asm */
|
||||||
static int _asm(AsmPrefs * prefs, char const * arch, char const * format,
|
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 */
|
/* usage */
|
||||||
static unsigned int _usage(void)
|
static unsigned int _usage(void)
|
||||||
{
|
{
|
||||||
fputs("Usage: asm [-D name][-a arch][-f format][-o file] file\n"
|
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"
|
" asm -l\n"
|
||||||
" -D Set a variable in the pre-processor\n"
|
" -D Set a variable in the pre-processor\n"
|
||||||
" -a Target architecture\n"
|
" -a Target architecture\n"
|
||||||
@ -74,9 +98,10 @@ int main(int argc, char * argv[])
|
|||||||
char * outfile = ASM_FILENAME_DEFAULT;
|
char * outfile = ASM_FILENAME_DEFAULT;
|
||||||
char const * arch = NULL;
|
char const * arch = NULL;
|
||||||
char const * format = NULL;
|
char const * format = NULL;
|
||||||
|
char const * string = NULL;
|
||||||
|
|
||||||
memset(&prefs, 0, sizeof(prefs));
|
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)
|
switch(o)
|
||||||
{
|
{
|
||||||
case 'a':
|
case 'a':
|
||||||
@ -94,21 +119,35 @@ int main(int argc, char * argv[])
|
|||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
o = 0;
|
o = 0;
|
||||||
if(asm_plugin_list(APT_ARCH) != 0)
|
if(asm_plugin_list(APT_ARCH, 0) != 0)
|
||||||
o = error_print(PACKAGE);
|
o = error_print(PACKAGE);
|
||||||
else
|
else
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
if(asm_plugin_list(APT_FORMAT) != 0)
|
if(asm_plugin_list(APT_FORMAT, 0) != 0)
|
||||||
o = error_print(PACKAGE);
|
o = error_print(PACKAGE);
|
||||||
return (o == 0) ? 0 : 2;
|
return (o == 0) ? 0 : 2;
|
||||||
|
case 's':
|
||||||
|
string = optarg;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
|
free(prefs.defines);
|
||||||
return _usage();
|
return _usage();
|
||||||
}
|
}
|
||||||
if(optind + 1 != argc)
|
if(string != NULL)
|
||||||
return _usage();
|
{
|
||||||
ret = _asm(&prefs, arch, format, argv[optind], outfile);
|
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);
|
free(prefs.defines);
|
||||||
return (ret == 0) ? 0 : 2;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _main_add_define(AsmPrefs * prefs, char * define)
|
static int _main_add_define(AsmPrefs * prefs, char * define)
|
||||||
|
44
src/parser.c
44
src/parser.c
@ -34,7 +34,7 @@ typedef struct _State
|
|||||||
Token * token;
|
Token * token;
|
||||||
unsigned int error_cnt;
|
unsigned int error_cnt;
|
||||||
unsigned int warning_cnt;
|
unsigned int warning_cnt;
|
||||||
Code * code;
|
AsmCode * code;
|
||||||
ArchInstructionCall call;
|
ArchInstructionCall call;
|
||||||
} State;
|
} State;
|
||||||
|
|
||||||
@ -157,6 +157,7 @@ static int _parser_error(State * state, char const * format, ...)
|
|||||||
|
|
||||||
fputs("asm: ", stderr);
|
fputs("asm: ", stderr);
|
||||||
if(state->cpp != NULL && state->token != NULL)
|
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),
|
fprintf(stderr, "%s%s%u: ", cpp_get_filename(state->cpp),
|
||||||
", line ", token_get_line(state->token));
|
", line ", token_get_line(state->token));
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
@ -174,6 +175,7 @@ static int _parser_warning(State * state, char const * format, ...)
|
|||||||
|
|
||||||
fputs("asm: ", stderr);
|
fputs("asm: ", stderr);
|
||||||
if(state->cpp != NULL && state->token != NULL)
|
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),
|
fprintf(stderr, "%s%s%u: ", cpp_get_filename(state->cpp),
|
||||||
", line ", token_get_line(state->token));
|
", line ", token_get_line(state->token));
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
@ -187,7 +189,7 @@ static int _parser_warning(State * state, char const * format, ...)
|
|||||||
/* protected */
|
/* protected */
|
||||||
/* functions */
|
/* functions */
|
||||||
/* parser */
|
/* parser */
|
||||||
int parser(AsmPrefs * ap, Code * code, char const * infile)
|
int parser(AsmPrefs * ap, AsmCode * code, char const * infile)
|
||||||
{
|
{
|
||||||
CppPrefs prefs;
|
CppPrefs prefs;
|
||||||
State state;
|
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 */
|
/* grammar */
|
||||||
/* program */
|
/* program */
|
||||||
static int _program(State * state)
|
static int _program(State * state)
|
||||||
@ -318,7 +352,7 @@ static int _section(State * state)
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "%s\"%s\"\n", "DEBUG: section ", section);
|
fprintf(stderr, "%s\"%s\"\n", "DEBUG: section ", section);
|
||||||
#endif
|
#endif
|
||||||
if(code_section(state->code, section) != 0)
|
if(asmcode_section(state->code, section) != 0)
|
||||||
ret |= _parser_error(state, "%s", error_get());
|
ret |= _parser_error(state, "%s", error_get());
|
||||||
free(section);
|
free(section);
|
||||||
}
|
}
|
||||||
@ -376,7 +410,7 @@ static int _function(State * state)
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "DEBUG: %s \"%s\"\n", "function", function);
|
fprintf(stderr, "DEBUG: %s \"%s\"\n", "function", function);
|
||||||
#endif
|
#endif
|
||||||
if(code_function(state->code, function) != 0)
|
if(asmcode_function(state->code, function) != 0)
|
||||||
ret |= _parser_error(state, "%s", error_get());
|
ret |= _parser_error(state, "%s", error_get());
|
||||||
free(function);
|
free(function);
|
||||||
}
|
}
|
||||||
@ -403,7 +437,7 @@ static int _instruction(State * state)
|
|||||||
}
|
}
|
||||||
if(state->call.name != NULL)
|
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());
|
ret |= _parser_error(state, "%s", error_get());
|
||||||
free(state->call.name);
|
free(state->call.name);
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,11 @@
|
|||||||
#ifndef ASM_PARSER_H
|
#ifndef ASM_PARSER_H
|
||||||
# define ASM_PARSER_H
|
# define ASM_PARSER_H
|
||||||
|
|
||||||
|
# include "Asm/asm.h"
|
||||||
# include "code.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 */
|
#endif /* !ASM_PARSER_H */
|
||||||
|
@ -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
|
PREFIX = /usr/local
|
||||||
DESTDIR =
|
DESTDIR =
|
||||||
BINDIR = $(PREFIX)/bin
|
BINDIR = $(PREFIX)/bin
|
||||||
@ -18,6 +18,12 @@ amd64.o_ASFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(ASFLAGS) -a amd64
|
|||||||
arm.o_OBJS = arm.o
|
arm.o_OBJS = arm.o
|
||||||
arm.o_ASFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(ASFLAGS) -a arm
|
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_OBJS = dalvik.o
|
||||||
dalvik.o_ASFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(ASFLAGS) -a dalvik -f flat
|
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_OBJS = mips.o
|
||||||
mips.o_ASFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(ASFLAGS) -a mips
|
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_OBJS = java.o
|
||||||
java.o_ASFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(ASFLAGS) -a java -f flat
|
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
|
arm.o: arm.S ../src/asm
|
||||||
$(AS) $(arm.o_ASFLAGS) -o arm.o arm.S
|
$(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
|
dalvik.o: dalvik.S ../src/asm
|
||||||
$(AS) $(dalvik.o_ASFLAGS) -o dalvik.o dalvik.S
|
$(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
|
mips.o: mips.S ../src/asm
|
||||||
$(AS) $(mips.o_ASFLAGS) -o mips.o mips.S
|
$(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
|
java.o: java.S ../src/asm
|
||||||
$(AS) $(java.o_ASFLAGS) -o java.o java.S
|
$(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
|
$(AS) $(yasep.o_ASFLAGS) -o yasep.o yasep.S
|
||||||
|
|
||||||
clean:
|
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
|
distclean: clean
|
||||||
$(RM) -- $(TARGETS)
|
$(RM) -- $(TARGETS)
|
||||||
|
2
test/armeb.S
Normal file
2
test/armeb.S
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/* $Id$ */
|
||||||
|
#include "arm.S"
|
2
test/armel.S
Normal file
2
test/armel.S
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/* $Id$ */
|
||||||
|
#include "arm.S"
|
2
test/mipseb.S
Normal file
2
test/mipseb.S
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/* $Id$ */
|
||||||
|
#include "mips.S"
|
2
test/mipsel.S
Normal file
2
test/mipsel.S
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/* $Id$ */
|
||||||
|
#include "mips.S"
|
@ -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
|
as=../src/asm-static
|
||||||
dist=Makefile
|
dist=Makefile
|
||||||
|
|
||||||
@ -18,6 +18,22 @@ sources=arm.S
|
|||||||
asflags=-a arm
|
asflags=-a arm
|
||||||
depends=../src/asm
|
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]
|
[dalvik.o]
|
||||||
type=object
|
type=object
|
||||||
sources=dalvik.S
|
sources=dalvik.S
|
||||||
@ -82,6 +98,22 @@ sources=mips.S
|
|||||||
asflags=-a mips
|
asflags=-a mips
|
||||||
depends=../src/asm
|
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]
|
[sparc.o]
|
||||||
type=object
|
type=object
|
||||||
sources=sparc.S
|
sources=sparc.S
|
||||||
|
Loading…
Reference in New Issue
Block a user