Preparing the API for maximum code re-use
This commit is contained in:
parent
e6329a15f6
commit
36b78c27ed
1
Makefile
1
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 \
|
||||
|
@ -19,13 +19,35 @@
|
||||
# define DEVEL_ASM_ASM_H
|
||||
|
||||
# include <stdio.h>
|
||||
# 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 */
|
||||
|
@ -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
|
||||
|
179
src/asm.c
179
src/asm.c
@ -26,7 +26,6 @@
|
||||
#include <errno.h>
|
||||
#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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
37
src/asm.h
37
src/asm.h
@ -1,37 +0,0 @@
|
||||
/* $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 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 */
|
28
src/code.c
28
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;
|
||||
}
|
||||
|
||||
|
12
src/code.h
12
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 */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user