Begin to implement directives

This commit is contained in:
Pierre Pronchery 2017-10-15 21:16:00 +02:00
parent dbe25195c4
commit cc56dd93cb
6 changed files with 45 additions and 18 deletions

View File

@ -69,6 +69,8 @@ AsmString * asmcode_set_string(AsmCode * code, int id, char const * name,
/* useful */ /* useful */
/* assembly */ /* 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_function(AsmCode * code, char const * name);
int asmcode_instruction(AsmCode * code, AsmArchInstructionCall * call); int asmcode_instruction(AsmCode * code, AsmArchInstructionCall * call);
int asmcode_section(AsmCode * code, char const * name); int asmcode_section(AsmCode * code, char const * name);

View File

@ -18,7 +18,6 @@
#ifndef DEVEL_ASM_FORMAT_H #ifndef DEVEL_ASM_FORMAT_H
# define DEVEL_ASM_FORMAT_H # define DEVEL_ASM_FORMAT_H
# include <stdarg.h>
# include <stdio.h> # include <stdio.h>
# include <System/license.h> # include <System/license.h>
# include "asm.h" # include "asm.h"
@ -80,7 +79,7 @@ typedef struct _AsmFormatPluginDefinition
/* assembly */ /* assembly */
char const * (*guess)(AsmFormatPlugin * format, char const * hint); char const * (*guess)(AsmFormatPlugin * format, char const * hint);
int (*directive)(AsmFormatPlugin * format, char const * directive, int (*directive)(AsmFormatPlugin * format, char const * directive,
va_list args); char const ** args, size_t size);
int (*function)(AsmFormatPlugin * format, char const * function); int (*function)(AsmFormatPlugin * format, char const * function);
int (*section)(AsmFormatPlugin * format, char const * section); int (*section)(AsmFormatPlugin * format, char const * section);

View File

@ -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 */ /* asmcode_function */
int asmcode_function(AsmCode * code, char const * name) int asmcode_function(AsmCode * code, char const * name)
{ {

View File

@ -272,7 +272,8 @@ char const * format_detect_arch(AsmFormat * format)
/* format_directive */ /* 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 #ifdef DEBUG
fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, name); 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) if(format->definition->directive == NULL)
return -error_set_code(1, "%s: %s", format->definition->name, return -error_set_code(1, "%s: %s", format->definition->name,
"No support for directives"); "No support for directives");
return format->definition->directive(format->plugin, name, args); return format->definition->directive(format->plugin, name, args,
args_cnt);
} }

View File

@ -18,7 +18,6 @@
#ifndef ASM_FORMAT_H #ifndef ASM_FORMAT_H
# define ASM_FORMAT_H # define ASM_FORMAT_H
# include <stdarg.h>
# include "Asm/common.h" # include "Asm/common.h"
# include "Asm/format.h" # include "Asm/format.h"
# include "code.h" # include "code.h"
@ -55,7 +54,8 @@ int format_exit(AsmFormat * format);
char const * format_guess_arch(AsmFormat * format, char const * hint); 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_function(AsmFormat * format, char const * name);
int format_section(AsmFormat * format, char const * name); int format_section(AsmFormat * format, char const * name);

View File

@ -42,7 +42,8 @@ typedef struct _State
/* directive */ /* directive */
char * directive; char * directive;
char * name; char ** args;
size_t args_cnt;
/* instruction */ /* instruction */
AsmArchInstructionCall call; AsmArchInstructionCall call;
@ -350,6 +351,7 @@ static int _directive(State * state)
/* "." directive_name [ space [ directive_args ] ] newline */ /* "." directive_name [ space [ directive_args ] ] newline */
{ {
int ret; int ret;
size_t i;
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "DEBUG: %s()\n", __func__); fprintf(stderr, "DEBUG: %s()\n", __func__);
@ -368,20 +370,25 @@ static int _directive(State * state)
if(_parser_in_set(state, TS_DIRECTIVE_ARGS)) if(_parser_in_set(state, TS_DIRECTIVE_ARGS))
ret |= _directive_args(state); ret |= _directive_args(state);
} }
if(string_compare(state->directive, "section") == 0 /* execute the directive */
&& state->name != NULL) 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)); ret |= _parser_error(state, "%s", error_get(NULL));
} }
else else if(asmcode_directive(state->code, state->directive, state->args,
/* FIXME implement */ state->args_cnt) != 0)
return error_set_code(1, "%s: %s", state->directive, ret |= _parser_error(state, "%s", error_get(NULL));
"Unknown directive");
free(state->directive); free(state->directive);
state->directive = NULL; state->directive = NULL;
free(state->name); for(i = 0; i < state->args_cnt; i++)
state->name = NULL; free(state->args[i]);
free(state->args);
state->args = NULL;
state->args_cnt = 0;
/* newline */ /* newline */
if(!_parser_in_set(state, TS_NEWLINE)) if(!_parser_in_set(state, TS_NEWLINE))
return _parser_recover(state, AS_CODE_NEWLINE, "New line"); return _parser_recover(state, AS_CODE_NEWLINE, "New line");
@ -395,15 +402,21 @@ static int _directive_arg(State * state)
/* WORD | NUMBER */ /* WORD | NUMBER */
{ {
char const * string; char const * string;
char ** p;
if(state->token == NULL if(state->token == NULL
|| (string = token_get_string(state->token)) == NULL || (string = token_get_string(state->token)) == NULL
|| strlen(token_get_string(state->token)) == 0) || strlen(token_get_string(state->token)) == 0)
return error_set_code(1, "%s", return error_set_code(1, "%s",
"Empty directive arguments are not allowed"); "Empty directive arguments are not allowed");
/* XXX only remembers the first argument */ if((p = realloc(state->args, sizeof(*p) * (state->args_cnt + 1)))
if(state->name == NULL && (state->name = strdup(string)) == NULL) == NULL)
return error_set_code(1, "%s", strerror(errno)); 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); return _parser_scan(state);
} }