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 */
/* 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);

View File

@ -18,7 +18,6 @@
#ifndef DEVEL_ASM_FORMAT_H
# define DEVEL_ASM_FORMAT_H
# include <stdarg.h>
# include <stdio.h>
# include <System/license.h>
# 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);

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

View File

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

View File

@ -18,7 +18,6 @@
#ifndef ASM_FORMAT_H
# define ASM_FORMAT_H
# include <stdarg.h>
# 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);

View File

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