From cc56dd93cb41fc7b1a3160d0177cd302a36bddf9 Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Sun, 15 Oct 2017 21:16:00 +0200 Subject: [PATCH] Begin to implement directives --- include/Asm/code.h | 2 ++ include/Asm/format.h | 3 +-- src/code.c | 11 +++++++++++ src/format.c | 6 ++++-- src/format.h | 4 ++-- src/parser.c | 37 +++++++++++++++++++++++++------------ 6 files changed, 45 insertions(+), 18 deletions(-) diff --git a/include/Asm/code.h b/include/Asm/code.h index c59878a..305b171 100644 --- a/include/Asm/code.h +++ b/include/Asm/code.h @@ -69,6 +69,8 @@ AsmString * asmcode_set_string(AsmCode * code, int id, char const * name, /* useful */ /* assembly */ +int asmcode_directive(AsmCode * code, char const * name, + char const ** args, size_t args_cnt); int asmcode_function(AsmCode * code, char const * name); int asmcode_instruction(AsmCode * code, AsmArchInstructionCall * call); int asmcode_section(AsmCode * code, char const * name); diff --git a/include/Asm/format.h b/include/Asm/format.h index 4097d2f..25df554 100644 --- a/include/Asm/format.h +++ b/include/Asm/format.h @@ -18,7 +18,6 @@ #ifndef DEVEL_ASM_FORMAT_H # define DEVEL_ASM_FORMAT_H -# include # include # include # include "asm.h" @@ -80,7 +79,7 @@ typedef struct _AsmFormatPluginDefinition /* assembly */ char const * (*guess)(AsmFormatPlugin * format, char const * hint); int (*directive)(AsmFormatPlugin * format, char const * directive, - va_list args); + char const ** args, size_t size); int (*function)(AsmFormatPlugin * format, char const * function); int (*section)(AsmFormatPlugin * format, char const * section); diff --git a/src/code.c b/src/code.c index e4614d3..9b7714f 100644 --- a/src/code.c +++ b/src/code.c @@ -490,6 +490,17 @@ int asmcode_decode_section(AsmCode * code, AsmSection * section, } +/* asmcode_directive */ +int asmcode_directive(AsmCode * code, char const * name, char const ** args, + size_t args_cnt) +{ +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, name); +#endif + return format_directive(code->format, name, args, args_cnt); +} + + /* asmcode_function */ int asmcode_function(AsmCode * code, char const * name) { diff --git a/src/format.c b/src/format.c index 9f1abad..7355fc3 100644 --- a/src/format.c +++ b/src/format.c @@ -272,7 +272,8 @@ char const * format_detect_arch(AsmFormat * format) /* format_directive */ -int format_directive(AsmFormat * format, char const * name, va_list args) +int format_directive(AsmFormat * format, char const * name, + char const ** args, size_t args_cnt) { #ifdef DEBUG fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, name); @@ -282,7 +283,8 @@ int format_directive(AsmFormat * format, char const * name, va_list args) if(format->definition->directive == NULL) return -error_set_code(1, "%s: %s", format->definition->name, "No support for directives"); - return format->definition->directive(format->plugin, name, args); + return format->definition->directive(format->plugin, name, args, + args_cnt); } diff --git a/src/format.h b/src/format.h index b12821e..83dab7b 100644 --- a/src/format.h +++ b/src/format.h @@ -18,7 +18,6 @@ #ifndef ASM_FORMAT_H # define ASM_FORMAT_H -# include # include "Asm/common.h" # include "Asm/format.h" # include "code.h" @@ -55,7 +54,8 @@ int format_exit(AsmFormat * format); char const * format_guess_arch(AsmFormat * format, char const * hint); -int format_directive(AsmFormat * format, char const * name, va_list args); +int format_directive(AsmFormat * format, char const * name, char const ** args, + size_t args_cnt); int format_function(AsmFormat * format, char const * name); int format_section(AsmFormat * format, char const * name); diff --git a/src/parser.c b/src/parser.c index 98b9a36..2ce26b2 100644 --- a/src/parser.c +++ b/src/parser.c @@ -42,7 +42,8 @@ typedef struct _State /* directive */ char * directive; - char * name; + char ** args; + size_t args_cnt; /* instruction */ AsmArchInstructionCall call; @@ -350,6 +351,7 @@ static int _directive(State * state) /* "." directive_name [ space [ directive_args ] ] newline */ { int ret; + size_t i; #ifdef DEBUG fprintf(stderr, "DEBUG: %s()\n", __func__); @@ -368,20 +370,25 @@ static int _directive(State * state) if(_parser_in_set(state, TS_DIRECTIVE_ARGS)) ret |= _directive_args(state); } - if(string_compare(state->directive, "section") == 0 - && state->name != NULL) + /* execute the directive */ + if(string_compare(state->directive, "section") == 0) { - if(asmcode_section(state->code, state->name) != 0) + if(state->args_cnt != 1) + ret |= _parser_error(state, "%s", + "Sections expect a name"); + else if(asmcode_section(state->code, state->args[0]) != 0) ret |= _parser_error(state, "%s", error_get(NULL)); } - else - /* FIXME implement */ - return error_set_code(1, "%s: %s", state->directive, - "Unknown directive"); + else if(asmcode_directive(state->code, state->directive, state->args, + state->args_cnt) != 0) + ret |= _parser_error(state, "%s", error_get(NULL)); free(state->directive); state->directive = NULL; - free(state->name); - state->name = NULL; + for(i = 0; i < state->args_cnt; i++) + free(state->args[i]); + free(state->args); + state->args = NULL; + state->args_cnt = 0; /* newline */ if(!_parser_in_set(state, TS_NEWLINE)) return _parser_recover(state, AS_CODE_NEWLINE, "New line"); @@ -395,15 +402,21 @@ static int _directive_arg(State * state) /* WORD | NUMBER */ { char const * string; + char ** p; if(state->token == NULL || (string = token_get_string(state->token)) == NULL || strlen(token_get_string(state->token)) == 0) return error_set_code(1, "%s", "Empty directive arguments are not allowed"); - /* XXX only remembers the first argument */ - if(state->name == NULL && (state->name = strdup(string)) == NULL) + if((p = realloc(state->args, sizeof(*p) * (state->args_cnt + 1))) + == NULL) return error_set_code(1, "%s", strerror(errno)); + state->args = p; + p = &state->args[state->args_cnt]; + if((*p = strdup(string)) == NULL) + return error_set_code(1, "%s", strerror(errno)); + state->args_cnt++; return _parser_scan(state); }