Preparing the API for maximum code re-use

This commit is contained in:
Pierre Pronchery 2011-04-28 01:22:19 +00:00
parent e6329a15f6
commit 36b78c27ed
10 changed files with 192 additions and 156 deletions

View File

@ -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 \

View File

@ -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 */

View File

@ -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

181
src/asm.c
View File

@ -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)
{
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);
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;

View File

@ -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;

View File

@ -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