diff --git a/Makefile b/Makefile index 2062daa..a4c9abf 100644 --- a/Makefile +++ b/Makefile @@ -43,7 +43,6 @@ dist: $(PACKAGE)-$(VERSION)/src/deasm.c \ $(PACKAGE)-$(VERSION)/src/Makefile \ $(PACKAGE)-$(VERSION)/src/arch.h \ - $(PACKAGE)-$(VERSION)/src/asm.h \ $(PACKAGE)-$(VERSION)/src/code.h \ $(PACKAGE)-$(VERSION)/src/common.h \ $(PACKAGE)-$(VERSION)/src/format.h \ diff --git a/include/Asm/asm.h b/include/Asm/asm.h index 734e7c2..90f8e4a 100644 --- a/include/Asm/asm.h +++ b/include/Asm/asm.h @@ -19,13 +19,35 @@ # define DEVEL_ASM_ASM_H # include -# include "arch.h" /* Asm */ /* types */ typedef struct _Asm Asm; +typedef unsigned int AsmId; + +typedef struct _AsmFunction +{ + AsmId id; + char const * name; + off_t offset; + ssize_t size; +} AsmFunction; + +typedef struct _AsmLabel +{ + char const * name; + off_t offset; +} AsmLabel; + +typedef struct _AsmString +{ + AsmId id; + char const * string; + ssize_t size; +} AsmString; + typedef enum _AsmPluginType { APT_ARCH = 0, APT_FORMAT } AsmPluginType; @@ -35,21 +57,53 @@ void asm_delete(Asm * a); /* accessors */ -char const * asm_get_arch_name(Asm * a); -char const * asm_get_format_name(Asm * a); +/* detection */ +char const * asm_get_arch(Asm * a); +int asm_set_arch(Asm * a, char const * arch); + +char const * asm_get_format(Asm * a); +int asm_set_format(Asm * a, char const * format); + +/* functions */ +AsmFunction * asm_get_function_by_name(Asm * a, char const * name); +int asm_set_function(Asm * a, char const * name, off_t offset, int whence, + 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, int whence); + +/* sections */ +int asm_set_section(Asm * a, char const * name, off_t offset, int whence, + 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, + int whence, ssize_t size); /* useful */ -int asm_decode(Asm * a, char const * buffer, size_t size); -int asm_decode_file(Asm * a, char const * filename, FILE * fp); -int asm_parse(Asm * a, char const * infile, char const * outfile); +/* detection */ +int asm_guess_arch(Asm * a); +int asm_guess_format(Asm * a); + +/* common */ +int asm_close(Asm * a); + +/* assemble */ +int asm_assemble(Asm * a, char const * infile, char const * outfile); +int asm_open_assemble(Asm * a, char const * infile, char const * outfile); -int asm_section(Asm * a, char const * name); -int asm_function(Asm * a, char const * name); int asm_instruction(Asm * a, char const * name, unsigned int operands_cnt, ...); +/* deassemble */ +int asm_deassemble(Asm * a, char const * buffer, size_t size); +int asm_open_deassemble(Asm * a, char const * filename); -/* plugins helpers */ +/* plug-in helpers */ int asm_plugin_list(AsmPluginType type); #endif /* !DEVEL_ASM_AS_H */ diff --git a/src/Makefile b/src/Makefile index 16e12e0..e118b3c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -52,7 +52,7 @@ deasm: $(deasm_OBJS) libasm.so arch.o: arch.c arch.h ../config.h $(CC) $(libasm_CFLAGS) -c arch.c -asm.o: asm.c ../include/Asm.h code.h parser.h asm.h ../config.h +asm.o: asm.c ../include/Asm.h code.h parser.h ../config.h $(CC) $(libasm_CFLAGS) -c asm.c code.o: code.c ../include/Asm.h arch.h code.h diff --git a/src/asm.c b/src/asm.c index 44d7fc1..d42c7ba 100644 --- a/src/asm.c +++ b/src/asm.c @@ -26,7 +26,6 @@ #include #include "code.h" #include "parser.h" -#include "asm.h" #include "../config.h" @@ -35,6 +34,9 @@ /* types */ struct _Asm { + char * arch; + char * format; + Code * code; }; @@ -49,8 +51,6 @@ typedef struct _AsmPluginDescription #define APT_LAST APT_FORMAT #define APT_COUNT (APT_LAST + 1) - -/* variables */ static const AsmPluginDescription _asm_plugin_description[APT_COUNT] = { { "arch", "architecture" }, @@ -60,26 +60,9 @@ static const AsmPluginDescription _asm_plugin_description[APT_COUNT] = /* prototypes */ static char const * _asm_guess_arch(void); +static char const * _asm_guess_format(void); - -/* functions */ -/* asm_guess_arch */ -static char const * _asm_guess_arch(void) -{ - static struct utsname uts; - static int cached = 0; - - if(cached == 0) - { - if(uname(&uts) != 0) - { - error_set_code(1, "%s", strerror(errno)); - return NULL; - } - cached = 1; - } - return uts.machine; -} +static int _asm_open(Asm * a, char const * outfile); /* public */ @@ -91,9 +74,11 @@ Asm * asm_new(char const * arch, char const * format) if((a = object_new(sizeof(*a))) == NULL) return NULL; - if(arch == NULL) - arch = _asm_guess_arch(); - if((a->code = code_new(arch, format)) == NULL) + a->arch = (arch != NULL) ? string_new(arch) : NULL; + a->format = (format != NULL) ? string_new(format) : NULL; + a->code = NULL; + if((arch != NULL && a->arch == NULL) + || (format != NULL && a->format == NULL)) { object_delete(a); return NULL; @@ -105,76 +90,36 @@ Asm * asm_new(char const * arch, char const * format) /* asm_delete */ void asm_delete(Asm * a) { - code_delete(a->code); + if(a->code != NULL) + code_delete(a->code); + string_delete(a->format); + string_delete(a->arch); object_delete(a); } /* accessors */ /* asm_get_arch */ -Arch * asm_get_arch(Asm * a) +char const * asm_get_arch(Asm * a) { - return code_get_arch(a->code); -} - - -/* asm_get_arch_name */ -char const * asm_get_arch_name(Asm * a) -{ - return code_get_arch_name(a->code); + return a->arch; } /* asm_get_format */ -Format * asm_get_format(Asm * a) +char const * asm_get_format(Asm * a) { - return code_get_format(a->code); -} - - -/* asm_get_format_name */ -char const * asm_get_format_name(Asm * a) -{ - return code_get_format_name(a->code); + return a->format; } /* useful */ -/* asm_close */ -int asm_close(Asm * a) -{ - return code_close(a->code); -} - - -/* asm_decode */ -int asm_decode(Asm * a, char const * buffer, size_t size) -{ - return code_decode(a->code, buffer, size); -} - - -/* asm_decode_file */ -int asm_decode_file(Asm * a, char const * filename, FILE * fp) +/* asm_assemble */ +int asm_assemble(Asm * a, char const * infile, char const * outfile) { int ret; - if(fp != NULL) - return code_decode_file(a->code, filename, fp); - if((fp = fopen(filename, "r")) == NULL) - return -error_set_code(1, "%s: %s", filename, strerror(errno)); - ret = code_decode_file(a->code, filename, fp); - fclose(fp); - return ret; -} - - -/* asm_parse */ -int asm_parse(Asm * a, char const * infile, char const * outfile) -{ - int ret; - - if(asm_open(a, outfile) != 0) + if(_asm_open(a, outfile) != 0) return -1; ret = parser(a->code, infile); if(ret != 0 && unlink(outfile) != 0) @@ -184,10 +129,38 @@ int asm_parse(Asm * a, char const * infile, char const * outfile) } -/* asm_open */ -int asm_open(Asm * a, char const * outfile) +/* asm_close */ +int asm_close(Asm * a) { - return code_open(a->code, outfile); + int ret; + + if(a->code == NULL) + return -error_set_code(1, "%s", "No file opened"); + ret = code_close(a->code); + a->code = NULL; + return ret; +} + + +/* asm_deassemble */ +int asm_deassemble(Asm * a, char const * buffer, size_t size) +{ + int ret; + + if(_asm_open(a, NULL) != 0) + return -1; + ret = code_decode(a->code, buffer, size); + asm_close(a); + return ret; +} + + +/* asm_open_deassemble */ +int asm_open_deassemble(Asm * a, char const * filename) +{ + if(_asm_open(a, NULL) != 0) + return -1; + return code_decode_file(a->code, filename); } @@ -272,3 +245,53 @@ int asm_plugin_list(AsmPluginType type) fputc('\n', stderr); return 0; } + + +/* private */ +/* functions */ +/* asm_guess_arch */ +static char const * _asm_guess_arch(void) +{ + static struct utsname uts; + static int cached = 0; + + if(cached == 0) + { + if(uname(&uts) != 0) + { + error_set_code(1, "%s", strerror(errno)); + return NULL; + } + cached = 1; + } + return uts.machine; +} + + +/* asm_guess_format */ +static char const * _asm_guess_format(void) +{ + /* FIXME really guess from known/guessed architecture plug-in */ + return "elf"; +} + + +/* asm_open */ +static int _asm_open(Asm * a, char const * outfile) +{ + char const * arch = a->arch; + char const * format = a->format; + + if(arch == NULL && (arch = _asm_guess_arch()) == NULL) + return -1; + if(format == NULL) + format = _asm_guess_format(); + if(a->code != NULL) + return -error_set_code(1, "%s: Operation in progress", + code_get_filename(a->code)); + if((a->code = code_new(arch, format)) == NULL) + return -1; + if(outfile == NULL) + return 0; + return code_open(a->code, outfile); +} diff --git a/src/asm.h b/src/asm.h deleted file mode 100644 index c9a2db1..0000000 --- a/src/asm.h +++ /dev/null @@ -1,37 +0,0 @@ -/* $Id$ */ -/* Copyright (c) 2011 Pierre Pronchery */ -/* 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 . */ - - - -#ifndef ASM_ASM_H -# define ASM_ASM_H - -# include "Asm/asm.h" -# include "arch.h" -# include "format.h" - - -/* protected */ -/* functions */ -/* accessors */ -Arch * asm_get_arch(Asm * a); -Format * asm_get_format(Asm * a); - - -/* useful */ -int asm_open(Asm * a, char const * outfile); -int asm_close(Asm * a); - -#endif /* !ASM_ASM_H */ diff --git a/src/code.c b/src/code.c index 6169074..208d93c 100644 --- a/src/code.c +++ b/src/code.c @@ -85,28 +85,21 @@ int code_delete(Code * code) /* accessors */ /* code_get_arch */ -Arch * code_get_arch(Code * code) -{ - return code->arch; -} - - -/* code_get_arch_name */ -char const * code_get_arch_name(Code * code) +char const * code_get_arch(Code * code) { return arch_get_name(code->arch); } -/* code_get_format */ -Format * code_get_format(Code * code) +/* code_get_filename */ +char const * code_get_filename(Code * code) { - return code->format; + return code->filename; } -/* code_get_format_name */ -char const * code_get_format_name(Code * code) +/* code_get_format */ +char const * code_get_format(Code * code) { return format_get_name(code->format); } @@ -120,7 +113,7 @@ int code_close(Code * code) ret |= arch_exit(code->arch); ret |= format_exit(code->format); - if(fclose(code->fp) != 0 && ret == 0) + if(code->fp != NULL && fclose(code->fp) != 0 && ret == 0) ret |= -error_set_code(1, "%s: %s", code->filename, strerror(errno)); code->fp = NULL; @@ -144,15 +137,20 @@ int code_decode(Code * code, char const * buffer, size_t size) static int _decode_file_callback(void * priv, char const * section, off_t offset, size_t size, off_t base); -int code_decode_file(Code * code, char const * filename, FILE * fp) +int code_decode_file(Code * code, char const * filename) { int ret; + FILE * fp; + if((fp = fopen(filename, "r")) == NULL) + return -error_set_code(1, "%s: %s", filename, strerror(errno)); arch_init(code->arch, filename, fp); format_init(code->format, filename, fp); ret = format_decode(code->format, _decode_file_callback, code); format_exit(code->format); arch_exit(code->arch); + if(fclose(fp) != 0 && ret == 0) + ret = -error_set_code(1, "%s: %s", filename, strerror(errno)); return ret; } diff --git a/src/code.h b/src/code.h index 0fe61e7..8556d66 100644 --- a/src/code.h +++ b/src/code.h @@ -34,22 +34,22 @@ Code * code_new(char const * arch, char const * format); int code_delete(Code * code); /* accessors */ -Arch * code_get_arch(Code * code); -char const * code_get_arch_name(Code * code); -Format * code_get_format(Code * code); -char const * code_get_format_name(Code * code); +char const * code_get_arch(Code * code); +char const * code_get_filename(Code * code); +char const * code_get_format(Code * code); /* useful */ -/* assembly */ +/* common */ int code_open(Code * code, char const * filename); int code_close(Code * code); +/* assembly */ int code_function(Code * code, char const * function); int code_instruction(Code * code, ArchInstructionCall * call); int code_section(Code * code, char const * section); /* disassembly */ int code_decode(Code * code, char const * buffer, size_t size); -int code_decode_file(Code * code, char const * filename, FILE * fp); +int code_decode_file(Code * code, char const * filename); #endif /* !ASM_CODE_H */ diff --git a/src/deasm.c b/src/deasm.c index 9528e90..2a6669d 100644 --- a/src/deasm.c +++ b/src/deasm.c @@ -202,16 +202,15 @@ static int _deasm_do_callback(Deasm * deasm, FormatPlugin * format) if(deasm->arch == NULL) { if(format->detect == NULL) - return -error_set_code(1, "%s: %s", format->name, + return -error_set_code(1, "%s: %s", deasm->filename, "Unable to detect the architecture"); if((deasm->arch = format->detect(format)) == NULL) return -1; } if((a = asm_new(deasm->arch, format->name)) == NULL) return -error_print("deasm"); - printf("\n%s: %s-%s\n", deasm->filename, format->name, - asm_get_arch_name(a)); - ret = asm_decode_file(a, deasm->filename, deasm->fp); + printf("\n%s: %s-%s\n", deasm->filename, format->name, asm_get_arch(a)); + ret = asm_open_deassemble(a, deasm->filename); asm_delete(a); return ret; } @@ -228,7 +227,7 @@ static int _deasm_buffer(char const * arch, char const * format, #endif if((a = asm_new(arch, format)) == NULL) return -1; - if(asm_decode(a, buffer, size) != 0) + if(asm_deassemble(a, buffer, size) != 0) error_print("deasm"); asm_delete(a); return 0; diff --git a/src/main.c b/src/main.c index 1f7bbd5..f2dc5e2 100644 --- a/src/main.c +++ b/src/main.c @@ -39,7 +39,7 @@ static int _asm(char const * arch, char const * format, char const * infile, if((a = asm_new(arch, format)) == NULL) return error_print(PACKAGE); - if(asm_parse(a, infile, outfile) != 0) + if(asm_assemble(a, infile, outfile) != 0) ret = error_print(PACKAGE); asm_delete(a); return ret; diff --git a/src/project.conf b/src/project.conf index d747363..a1d425d 100644 --- a/src/project.conf +++ b/src/project.conf @@ -5,7 +5,7 @@ cppflags= cflags_force=-W `pkg-config --cflags cpp` cflags=-Wall -g -O2 -pedantic ldflags_force=-ldl -dist=Makefile,arch.h,asm.h,code.h,common.h,format.h,parser.h,token.h +dist=Makefile,arch.h,code.h,common.h,format.h,parser.h,token.h [libasm] type=library @@ -32,7 +32,7 @@ install=$(BINDIR) depends=arch.h,../config.h [asm.c] -depends=../include/Asm.h,code.h,parser.h,asm.h,../config.h +depends=../include/Asm.h,code.h,parser.h,../config.h [code.c] depends=../include/Asm.h,arch.h,code.h