From: Peter Johnson Date: Wed, 19 Sep 2001 07:20:02 +0000 (-0000) Subject: Build section linked list, and support the section directive, including X-Git-Tag: v0.1.0~322 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1fd753346c7a9927e72a6309abf5dea3058ce0d2;p=yasm Build section linked list, and support the section directive, including asking the objfmt module. Add some utility functions for both bytecode and section to better modularize their data structure usage and common code. Rename doparse to do_parse to be consistent in naming. svn path=/trunk/yasm/; revision=196 --- diff --git a/frontends/yasm/yasm.c b/frontends/yasm/yasm.c index 440f977e..0b55dbbe 100644 --- a/frontends/yasm/yasm.c +++ b/frontends/yasm/yasm.c @@ -59,7 +59,7 @@ main(int argc, char *argv[]) filename = strdup(""); } - nasm_parser.doparse(&nasm_parser, &dbg_objfmt, in); + nasm_parser.do_parse(&nasm_parser, &dbg_objfmt, in); if (filename) free(filename); diff --git a/libyasm/bytecode.c b/libyasm/bytecode.c index e9eb0283..a9854b87 100644 --- a/libyasm/bytecode.c +++ b/libyasm/bytecode.c @@ -548,6 +548,17 @@ bytecode_print(bytecode *bc) printf("Offset=%lx BITS=%u\n", bc->offset, bc->mode_bits); } +void +bytecodes_append(bytecodehead *headp, bytecode *bc) +{ + if (bc) { + if (bc->type != BC_EMPTY) + STAILQ_INSERT_TAIL(headp, bc, link); + else + free(bc); + } +} + dataval * dataval_new_expr(expr *exp) { diff --git a/libyasm/bytecode.h b/libyasm/bytecode.h index 5f1e45b3..9b45b03d 100644 --- a/libyasm/bytecode.h +++ b/libyasm/bytecode.h @@ -183,6 +183,16 @@ bytecode *bytecode_new_reserve(struct expr_s *numitems, void bytecode_print(bytecode *bc); +/* void bytecodes_initialize(bytecodehead *headp); */ +#define bytecodes_initialize(headp) STAILQ_INIT(headp) + +/* Adds bc to the list of bytecodes headp. + * NOTE: Does not make a copy of bc; so don't pass this function + * static or local variables, and discard the bc pointer after calling + * this function. + */ +void bytecodes_append(bytecodehead *headp, bytecode *bc); + dataval *dataval_new_expr(struct expr_s *exp); dataval *dataval_new_float(double float_val); dataval *dataval_new_string(char *str_val); diff --git a/libyasm/objfmt.h b/libyasm/objfmt.h index 24955b36..813fc94a 100644 --- a/libyasm/objfmt.h +++ b/libyasm/objfmt.h @@ -39,6 +39,14 @@ typedef struct objfmt_s { * use) */ /* struct debugfmt_s *default_df;*/ + + /* Get the default (starting) section name. */ + const char *(*get_default_section_name) (void); + + /* Is the specified section name valid? + * Return is a boolean value. + */ + int (*is_valid_section) (const char *name); } objfmt; /* Available object formats */ diff --git a/libyasm/parser.h b/libyasm/parser.h index fb730830..e021bdc2 100644 --- a/libyasm/parser.h +++ b/libyasm/parser.h @@ -52,7 +52,7 @@ typedef struct parser_s { * This function returns the starting section of a linked list of sections * (whatever was in the file). */ - sectionhead *(*doparse) (struct parser_s *p, objfmt *of, FILE *f); + sectionhead *(*do_parse) (struct parser_s *p, objfmt *of, FILE *f); } parser; /* Generic functions for all parsers - implemented in src/parser.c */ diff --git a/libyasm/section.c b/libyasm/section.c new file mode 100644 index 00000000..ad760bbd --- /dev/null +++ b/libyasm/section.c @@ -0,0 +1,113 @@ +/* $IdPath$ + * Section utility functions + * + * Copyright (C) 2001 Peter Johnson + * + * This file is part of YASM. + * + * YASM 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; either version 2 of the License, or + * (at your option) any later version. + * + * YASM 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "util.h" + +#include + +#ifdef STDC_HEADERS +# include +# include +#endif + +#include +#define _(String) gettext(String) +#ifdef gettext_noop +#define N_(String) gettext_noop(String) +#else +#define N_(String) (String) +#endif + +#include "globals.h" +#include "errwarn.h" +#include "expr.h" + +#include "bytecode.h" +#include "section.h" +#include "objfmt.h" + +RCSID("$IdPath$"); + +section * +sections_initialize(sectionhead *headp, objfmt *of) +{ + section *s; + + /* Initialize linked list */ + STAILQ_INIT(headp); + + /* Add an initial "default" section to the list */ + s = calloc(1, sizeof(section)); + if (!s) + Fatal(FATAL_NOMEM); + STAILQ_INSERT_TAIL(headp, s, link); + + /* Initialize default section */ + s->type = SECTION_GENERAL; + s->name = strdup(of->get_default_section_name()); + bytecodes_initialize(&s->bc); + + return s; +} + +section * +sections_switch(sectionhead *headp, objfmt *of, const char *name) +{ + section *s, *sp; + + /* Search through current sections to see if we already have one with + * that name. + */ + s = (section *)NULL; + STAILQ_FOREACH(sp, headp, link) { + if (strcmp(sp->name, name) == 0) + s = sp; + } + + if (s) + return s; + + /* No: we have to allocate and create a new one. */ + + /* But first check with objfmt to see if the name is valid. + * If it isn't, error and just return the default (first) section. + */ + if (!of->is_valid_section(name)) { + Error(_("Invalid section name: %s"), name); + return STAILQ_FIRST(headp); + } + + /* Okay, the name is valid; now allocate and initialize */ + s = calloc(1, sizeof(section)); + if (!s) + Fatal(FATAL_NOMEM); + STAILQ_INSERT_TAIL(headp, s, link); + + s->type = SECTION_GENERAL; + s->name = strdup(name); + bytecodes_initialize(&s->bc); + + return s; +} diff --git a/libyasm/section.h b/libyasm/section.h index 592fb67b..71dd50b2 100644 --- a/libyasm/section.h +++ b/libyasm/section.h @@ -22,18 +22,18 @@ #ifndef YASM_SECTION_H #define YASM_SECTION_H +struct objfmt_s; + typedef STAILQ_HEAD(sectionhead_s, section_s) sectionhead; typedef struct section_s { STAILQ_ENTRY(section_s) link; - enum { SECTION_DEFAULT, SECTION_GENERAL, SECTION_ABSOLUTE } type; + enum { SECTION_GENERAL, SECTION_ABSOLUTE } type; - char *name; - unsigned int id; + char *name; /* strdup()'ed name (given by user) */ union { - /* SECTION_DEFAULT data */ /* SECTION_GENERAL data */ /* SECTION_ABSOLUTE data */ unsigned long start; @@ -42,4 +42,9 @@ typedef struct section_s { bytecodehead bc; /* the bytecodes for the section's contents */ } section; +section *sections_initialize(sectionhead *headp, struct objfmt_s *of); + +section *sections_switch(sectionhead *headp, struct objfmt_s *of, + const char *name); + #endif diff --git a/modules/objfmts/dbg/dbg-objfmt.c b/modules/objfmts/dbg/dbg-objfmt.c index 57ffcef2..7b027855 100644 --- a/modules/objfmts/dbg/dbg-objfmt.c +++ b/modules/objfmts/dbg/dbg-objfmt.c @@ -25,12 +25,30 @@ #include "util.h" +#include + #include "objfmt.h" RCSID("$IdPath$"); +static const char * +dbg_objfmt_get_default_section_name(void) +{ + fprintf(stderr, "-dbg_objfmt_get_default_section_name()\n"); + return ".text"; +} + +static int +dbg_objfmt_is_valid_section(const char *name) +{ + fprintf(stderr, "-dbg_objfmt_is_valid_section(\"%s\")\n", name); + return 1; +} + /* Define objfmt structure -- see objfmt.h for details */ objfmt dbg_objfmt = { "Trace of all info passed to object format module", - "dbg" + "dbg", + dbg_objfmt_get_default_section_name, + dbg_objfmt_is_valid_section }; diff --git a/modules/objfmts/dbg/objfmt.c b/modules/objfmts/dbg/objfmt.c index 57ffcef2..7b027855 100644 --- a/modules/objfmts/dbg/objfmt.c +++ b/modules/objfmts/dbg/objfmt.c @@ -25,12 +25,30 @@ #include "util.h" +#include + #include "objfmt.h" RCSID("$IdPath$"); +static const char * +dbg_objfmt_get_default_section_name(void) +{ + fprintf(stderr, "-dbg_objfmt_get_default_section_name()\n"); + return ".text"; +} + +static int +dbg_objfmt_is_valid_section(const char *name) +{ + fprintf(stderr, "-dbg_objfmt_is_valid_section(\"%s\")\n", name); + return 1; +} + /* Define objfmt structure -- see objfmt.h for details */ objfmt dbg_objfmt = { "Trace of all info passed to object format module", - "dbg" + "dbg", + dbg_objfmt_get_default_section_name, + dbg_objfmt_is_valid_section }; diff --git a/modules/parsers/nasm/bison.y.in b/modules/parsers/nasm/bison.y.in index e13c54c7..156b56bd 100644 --- a/modules/parsers/nasm/bison.y.in +++ b/modules/parsers/nasm/bison.y.in @@ -28,6 +28,7 @@ #ifdef STDC_HEADERS # include +# include # include #endif @@ -41,6 +42,7 @@ #include "bytecode.h" #include "section.h" +#include "objfmt.h" RCSID("$IdPath$"); @@ -51,6 +53,8 @@ extern int nasm_parser_lex(void); static unsigned long ConvertCharConstToInt(char *); void nasm_parser_error(char *); +extern objfmt *nasm_parser_objfmt; +extern sectionhead nasm_parser_sections; extern section *nasm_parser_cur_section; %} @@ -127,13 +131,7 @@ input: /* empty */ | input line { OutputError(); OutputWarning(); - if ($2) { - if ($2->type != BC_EMPTY) { - STAILQ_INSERT_TAIL(&nasm_parser_cur_section->bc, $2, link); - } else { - free($2); - } - } + bytecodes_append(&nasm_parser_cur_section->bc, $2); line_number++; } ; @@ -185,7 +183,11 @@ label_id: ID { $$ = locallabel_base = sym_def_get($1.name, SYM_LABEL); } /* directives */ directive: '[' DIRECTIVE_NAME DIRECTIVE_VAL ']' { - printf("Directive: Name='%s' Value='%s'\n", $2, $3); + if (strcasecmp($2, "section") == 0) + nasm_parser_cur_section = sections_switch(&nasm_parser_sections, + nasm_parser_objfmt, $3); + else + printf("Directive: Name='%s' Value='%s'\n", $2, $3); } | '[' DIRECTIVE_NAME DIRECTIVE_VAL error { Error(_("missing `%c'"), ']'); diff --git a/modules/parsers/nasm/nasm-bison.y b/modules/parsers/nasm/nasm-bison.y index e13c54c7..156b56bd 100644 --- a/modules/parsers/nasm/nasm-bison.y +++ b/modules/parsers/nasm/nasm-bison.y @@ -28,6 +28,7 @@ #ifdef STDC_HEADERS # include +# include # include #endif @@ -41,6 +42,7 @@ #include "bytecode.h" #include "section.h" +#include "objfmt.h" RCSID("$IdPath$"); @@ -51,6 +53,8 @@ extern int nasm_parser_lex(void); static unsigned long ConvertCharConstToInt(char *); void nasm_parser_error(char *); +extern objfmt *nasm_parser_objfmt; +extern sectionhead nasm_parser_sections; extern section *nasm_parser_cur_section; %} @@ -127,13 +131,7 @@ input: /* empty */ | input line { OutputError(); OutputWarning(); - if ($2) { - if ($2->type != BC_EMPTY) { - STAILQ_INSERT_TAIL(&nasm_parser_cur_section->bc, $2, link); - } else { - free($2); - } - } + bytecodes_append(&nasm_parser_cur_section->bc, $2); line_number++; } ; @@ -185,7 +183,11 @@ label_id: ID { $$ = locallabel_base = sym_def_get($1.name, SYM_LABEL); } /* directives */ directive: '[' DIRECTIVE_NAME DIRECTIVE_VAL ']' { - printf("Directive: Name='%s' Value='%s'\n", $2, $3); + if (strcasecmp($2, "section") == 0) + nasm_parser_cur_section = sections_switch(&nasm_parser_sections, + nasm_parser_objfmt, $3); + else + printf("Directive: Name='%s' Value='%s'\n", $2, $3); } | '[' DIRECTIVE_NAME DIRECTIVE_VAL error { Error(_("missing `%c'"), ']'); diff --git a/modules/parsers/nasm/nasm-parser.c b/modules/parsers/nasm/nasm-parser.c index 05dd1075..2f43d0c4 100644 --- a/modules/parsers/nasm/nasm-parser.c +++ b/modules/parsers/nasm/nasm-parser.c @@ -48,28 +48,21 @@ extern int nasm_parser_parse(void); int (*nasm_parser_yyinput) (char *buf, int max_size); +objfmt *nasm_parser_objfmt; sectionhead nasm_parser_sections; section *nasm_parser_cur_section; static sectionhead * -nasm_parser_doparse(parser *p, objfmt *of, FILE *f) +nasm_parser_do_parse(parser *p, objfmt *of, FILE *f) { p->current_pp->initialize(of, f); nasm_parser_in = f; nasm_parser_yyinput = p->current_pp->input; - /* Initialize linked list */ - STAILQ_INIT(&nasm_parser_sections); + nasm_parser_objfmt = of; - /* Add an initial "default" section to the list */ - nasm_parser_cur_section = calloc(1, sizeof(section)); - if (!nasm_parser_cur_section) - Fatal(FATAL_NOMEM); - STAILQ_INSERT_TAIL(&nasm_parser_sections, nasm_parser_cur_section, link); - - /* Initialize default section */ - nasm_parser_cur_section->type = SECTION_DEFAULT; - STAILQ_INIT(&nasm_parser_cur_section->bc); + /* Initialize section list */ + nasm_parser_cur_section = sections_initialize(&nasm_parser_sections, of); /* only temporary */ nasm_parser_debug = 0; @@ -91,5 +84,5 @@ parser nasm_parser = { "nasm", nasm_parser_preprocs, &raw_preproc, - nasm_parser_doparse + nasm_parser_do_parse }; diff --git a/modules/parsers/nasm/parser.c b/modules/parsers/nasm/parser.c index 05dd1075..2f43d0c4 100644 --- a/modules/parsers/nasm/parser.c +++ b/modules/parsers/nasm/parser.c @@ -48,28 +48,21 @@ extern int nasm_parser_parse(void); int (*nasm_parser_yyinput) (char *buf, int max_size); +objfmt *nasm_parser_objfmt; sectionhead nasm_parser_sections; section *nasm_parser_cur_section; static sectionhead * -nasm_parser_doparse(parser *p, objfmt *of, FILE *f) +nasm_parser_do_parse(parser *p, objfmt *of, FILE *f) { p->current_pp->initialize(of, f); nasm_parser_in = f; nasm_parser_yyinput = p->current_pp->input; - /* Initialize linked list */ - STAILQ_INIT(&nasm_parser_sections); + nasm_parser_objfmt = of; - /* Add an initial "default" section to the list */ - nasm_parser_cur_section = calloc(1, sizeof(section)); - if (!nasm_parser_cur_section) - Fatal(FATAL_NOMEM); - STAILQ_INSERT_TAIL(&nasm_parser_sections, nasm_parser_cur_section, link); - - /* Initialize default section */ - nasm_parser_cur_section->type = SECTION_DEFAULT; - STAILQ_INIT(&nasm_parser_cur_section->bc); + /* Initialize section list */ + nasm_parser_cur_section = sections_initialize(&nasm_parser_sections, of); /* only temporary */ nasm_parser_debug = 0; @@ -91,5 +84,5 @@ parser nasm_parser = { "nasm", nasm_parser_preprocs, &raw_preproc, - nasm_parser_doparse + nasm_parser_do_parse }; diff --git a/src/Makefile.am b/src/Makefile.am index 36de584d..1c313078 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -30,6 +30,7 @@ libyasm_a_SOURCES = \ globals.c \ globals.h \ util.h \ + section.c \ section.h \ objfmt.h \ preproc.h \ diff --git a/src/bytecode.c b/src/bytecode.c index e9eb0283..a9854b87 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -548,6 +548,17 @@ bytecode_print(bytecode *bc) printf("Offset=%lx BITS=%u\n", bc->offset, bc->mode_bits); } +void +bytecodes_append(bytecodehead *headp, bytecode *bc) +{ + if (bc) { + if (bc->type != BC_EMPTY) + STAILQ_INSERT_TAIL(headp, bc, link); + else + free(bc); + } +} + dataval * dataval_new_expr(expr *exp) { diff --git a/src/bytecode.h b/src/bytecode.h index 5f1e45b3..9b45b03d 100644 --- a/src/bytecode.h +++ b/src/bytecode.h @@ -183,6 +183,16 @@ bytecode *bytecode_new_reserve(struct expr_s *numitems, void bytecode_print(bytecode *bc); +/* void bytecodes_initialize(bytecodehead *headp); */ +#define bytecodes_initialize(headp) STAILQ_INIT(headp) + +/* Adds bc to the list of bytecodes headp. + * NOTE: Does not make a copy of bc; so don't pass this function + * static or local variables, and discard the bc pointer after calling + * this function. + */ +void bytecodes_append(bytecodehead *headp, bytecode *bc); + dataval *dataval_new_expr(struct expr_s *exp); dataval *dataval_new_float(double float_val); dataval *dataval_new_string(char *str_val); diff --git a/src/main.c b/src/main.c index 440f977e..0b55dbbe 100644 --- a/src/main.c +++ b/src/main.c @@ -59,7 +59,7 @@ main(int argc, char *argv[]) filename = strdup(""); } - nasm_parser.doparse(&nasm_parser, &dbg_objfmt, in); + nasm_parser.do_parse(&nasm_parser, &dbg_objfmt, in); if (filename) free(filename); diff --git a/src/objfmt.h b/src/objfmt.h index 24955b36..813fc94a 100644 --- a/src/objfmt.h +++ b/src/objfmt.h @@ -39,6 +39,14 @@ typedef struct objfmt_s { * use) */ /* struct debugfmt_s *default_df;*/ + + /* Get the default (starting) section name. */ + const char *(*get_default_section_name) (void); + + /* Is the specified section name valid? + * Return is a boolean value. + */ + int (*is_valid_section) (const char *name); } objfmt; /* Available object formats */ diff --git a/src/objfmts/dbg/dbg-objfmt.c b/src/objfmts/dbg/dbg-objfmt.c index 57ffcef2..7b027855 100644 --- a/src/objfmts/dbg/dbg-objfmt.c +++ b/src/objfmts/dbg/dbg-objfmt.c @@ -25,12 +25,30 @@ #include "util.h" +#include + #include "objfmt.h" RCSID("$IdPath$"); +static const char * +dbg_objfmt_get_default_section_name(void) +{ + fprintf(stderr, "-dbg_objfmt_get_default_section_name()\n"); + return ".text"; +} + +static int +dbg_objfmt_is_valid_section(const char *name) +{ + fprintf(stderr, "-dbg_objfmt_is_valid_section(\"%s\")\n", name); + return 1; +} + /* Define objfmt structure -- see objfmt.h for details */ objfmt dbg_objfmt = { "Trace of all info passed to object format module", - "dbg" + "dbg", + dbg_objfmt_get_default_section_name, + dbg_objfmt_is_valid_section }; diff --git a/src/objfmts/dbg/objfmt.c b/src/objfmts/dbg/objfmt.c index 57ffcef2..7b027855 100644 --- a/src/objfmts/dbg/objfmt.c +++ b/src/objfmts/dbg/objfmt.c @@ -25,12 +25,30 @@ #include "util.h" +#include + #include "objfmt.h" RCSID("$IdPath$"); +static const char * +dbg_objfmt_get_default_section_name(void) +{ + fprintf(stderr, "-dbg_objfmt_get_default_section_name()\n"); + return ".text"; +} + +static int +dbg_objfmt_is_valid_section(const char *name) +{ + fprintf(stderr, "-dbg_objfmt_is_valid_section(\"%s\")\n", name); + return 1; +} + /* Define objfmt structure -- see objfmt.h for details */ objfmt dbg_objfmt = { "Trace of all info passed to object format module", - "dbg" + "dbg", + dbg_objfmt_get_default_section_name, + dbg_objfmt_is_valid_section }; diff --git a/src/parser.h b/src/parser.h index fb730830..e021bdc2 100644 --- a/src/parser.h +++ b/src/parser.h @@ -52,7 +52,7 @@ typedef struct parser_s { * This function returns the starting section of a linked list of sections * (whatever was in the file). */ - sectionhead *(*doparse) (struct parser_s *p, objfmt *of, FILE *f); + sectionhead *(*do_parse) (struct parser_s *p, objfmt *of, FILE *f); } parser; /* Generic functions for all parsers - implemented in src/parser.c */ diff --git a/src/parsers/nasm/bison.y.in b/src/parsers/nasm/bison.y.in index e13c54c7..156b56bd 100644 --- a/src/parsers/nasm/bison.y.in +++ b/src/parsers/nasm/bison.y.in @@ -28,6 +28,7 @@ #ifdef STDC_HEADERS # include +# include # include #endif @@ -41,6 +42,7 @@ #include "bytecode.h" #include "section.h" +#include "objfmt.h" RCSID("$IdPath$"); @@ -51,6 +53,8 @@ extern int nasm_parser_lex(void); static unsigned long ConvertCharConstToInt(char *); void nasm_parser_error(char *); +extern objfmt *nasm_parser_objfmt; +extern sectionhead nasm_parser_sections; extern section *nasm_parser_cur_section; %} @@ -127,13 +131,7 @@ input: /* empty */ | input line { OutputError(); OutputWarning(); - if ($2) { - if ($2->type != BC_EMPTY) { - STAILQ_INSERT_TAIL(&nasm_parser_cur_section->bc, $2, link); - } else { - free($2); - } - } + bytecodes_append(&nasm_parser_cur_section->bc, $2); line_number++; } ; @@ -185,7 +183,11 @@ label_id: ID { $$ = locallabel_base = sym_def_get($1.name, SYM_LABEL); } /* directives */ directive: '[' DIRECTIVE_NAME DIRECTIVE_VAL ']' { - printf("Directive: Name='%s' Value='%s'\n", $2, $3); + if (strcasecmp($2, "section") == 0) + nasm_parser_cur_section = sections_switch(&nasm_parser_sections, + nasm_parser_objfmt, $3); + else + printf("Directive: Name='%s' Value='%s'\n", $2, $3); } | '[' DIRECTIVE_NAME DIRECTIVE_VAL error { Error(_("missing `%c'"), ']'); diff --git a/src/parsers/nasm/nasm-bison.y b/src/parsers/nasm/nasm-bison.y index e13c54c7..156b56bd 100644 --- a/src/parsers/nasm/nasm-bison.y +++ b/src/parsers/nasm/nasm-bison.y @@ -28,6 +28,7 @@ #ifdef STDC_HEADERS # include +# include # include #endif @@ -41,6 +42,7 @@ #include "bytecode.h" #include "section.h" +#include "objfmt.h" RCSID("$IdPath$"); @@ -51,6 +53,8 @@ extern int nasm_parser_lex(void); static unsigned long ConvertCharConstToInt(char *); void nasm_parser_error(char *); +extern objfmt *nasm_parser_objfmt; +extern sectionhead nasm_parser_sections; extern section *nasm_parser_cur_section; %} @@ -127,13 +131,7 @@ input: /* empty */ | input line { OutputError(); OutputWarning(); - if ($2) { - if ($2->type != BC_EMPTY) { - STAILQ_INSERT_TAIL(&nasm_parser_cur_section->bc, $2, link); - } else { - free($2); - } - } + bytecodes_append(&nasm_parser_cur_section->bc, $2); line_number++; } ; @@ -185,7 +183,11 @@ label_id: ID { $$ = locallabel_base = sym_def_get($1.name, SYM_LABEL); } /* directives */ directive: '[' DIRECTIVE_NAME DIRECTIVE_VAL ']' { - printf("Directive: Name='%s' Value='%s'\n", $2, $3); + if (strcasecmp($2, "section") == 0) + nasm_parser_cur_section = sections_switch(&nasm_parser_sections, + nasm_parser_objfmt, $3); + else + printf("Directive: Name='%s' Value='%s'\n", $2, $3); } | '[' DIRECTIVE_NAME DIRECTIVE_VAL error { Error(_("missing `%c'"), ']'); diff --git a/src/parsers/nasm/nasm-parser.c b/src/parsers/nasm/nasm-parser.c index 05dd1075..2f43d0c4 100644 --- a/src/parsers/nasm/nasm-parser.c +++ b/src/parsers/nasm/nasm-parser.c @@ -48,28 +48,21 @@ extern int nasm_parser_parse(void); int (*nasm_parser_yyinput) (char *buf, int max_size); +objfmt *nasm_parser_objfmt; sectionhead nasm_parser_sections; section *nasm_parser_cur_section; static sectionhead * -nasm_parser_doparse(parser *p, objfmt *of, FILE *f) +nasm_parser_do_parse(parser *p, objfmt *of, FILE *f) { p->current_pp->initialize(of, f); nasm_parser_in = f; nasm_parser_yyinput = p->current_pp->input; - /* Initialize linked list */ - STAILQ_INIT(&nasm_parser_sections); + nasm_parser_objfmt = of; - /* Add an initial "default" section to the list */ - nasm_parser_cur_section = calloc(1, sizeof(section)); - if (!nasm_parser_cur_section) - Fatal(FATAL_NOMEM); - STAILQ_INSERT_TAIL(&nasm_parser_sections, nasm_parser_cur_section, link); - - /* Initialize default section */ - nasm_parser_cur_section->type = SECTION_DEFAULT; - STAILQ_INIT(&nasm_parser_cur_section->bc); + /* Initialize section list */ + nasm_parser_cur_section = sections_initialize(&nasm_parser_sections, of); /* only temporary */ nasm_parser_debug = 0; @@ -91,5 +84,5 @@ parser nasm_parser = { "nasm", nasm_parser_preprocs, &raw_preproc, - nasm_parser_doparse + nasm_parser_do_parse }; diff --git a/src/parsers/nasm/parser.c b/src/parsers/nasm/parser.c index 05dd1075..2f43d0c4 100644 --- a/src/parsers/nasm/parser.c +++ b/src/parsers/nasm/parser.c @@ -48,28 +48,21 @@ extern int nasm_parser_parse(void); int (*nasm_parser_yyinput) (char *buf, int max_size); +objfmt *nasm_parser_objfmt; sectionhead nasm_parser_sections; section *nasm_parser_cur_section; static sectionhead * -nasm_parser_doparse(parser *p, objfmt *of, FILE *f) +nasm_parser_do_parse(parser *p, objfmt *of, FILE *f) { p->current_pp->initialize(of, f); nasm_parser_in = f; nasm_parser_yyinput = p->current_pp->input; - /* Initialize linked list */ - STAILQ_INIT(&nasm_parser_sections); + nasm_parser_objfmt = of; - /* Add an initial "default" section to the list */ - nasm_parser_cur_section = calloc(1, sizeof(section)); - if (!nasm_parser_cur_section) - Fatal(FATAL_NOMEM); - STAILQ_INSERT_TAIL(&nasm_parser_sections, nasm_parser_cur_section, link); - - /* Initialize default section */ - nasm_parser_cur_section->type = SECTION_DEFAULT; - STAILQ_INIT(&nasm_parser_cur_section->bc); + /* Initialize section list */ + nasm_parser_cur_section = sections_initialize(&nasm_parser_sections, of); /* only temporary */ nasm_parser_debug = 0; @@ -91,5 +84,5 @@ parser nasm_parser = { "nasm", nasm_parser_preprocs, &raw_preproc, - nasm_parser_doparse + nasm_parser_do_parse }; diff --git a/src/section.c b/src/section.c new file mode 100644 index 00000000..ad760bbd --- /dev/null +++ b/src/section.c @@ -0,0 +1,113 @@ +/* $IdPath$ + * Section utility functions + * + * Copyright (C) 2001 Peter Johnson + * + * This file is part of YASM. + * + * YASM 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; either version 2 of the License, or + * (at your option) any later version. + * + * YASM 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "util.h" + +#include + +#ifdef STDC_HEADERS +# include +# include +#endif + +#include +#define _(String) gettext(String) +#ifdef gettext_noop +#define N_(String) gettext_noop(String) +#else +#define N_(String) (String) +#endif + +#include "globals.h" +#include "errwarn.h" +#include "expr.h" + +#include "bytecode.h" +#include "section.h" +#include "objfmt.h" + +RCSID("$IdPath$"); + +section * +sections_initialize(sectionhead *headp, objfmt *of) +{ + section *s; + + /* Initialize linked list */ + STAILQ_INIT(headp); + + /* Add an initial "default" section to the list */ + s = calloc(1, sizeof(section)); + if (!s) + Fatal(FATAL_NOMEM); + STAILQ_INSERT_TAIL(headp, s, link); + + /* Initialize default section */ + s->type = SECTION_GENERAL; + s->name = strdup(of->get_default_section_name()); + bytecodes_initialize(&s->bc); + + return s; +} + +section * +sections_switch(sectionhead *headp, objfmt *of, const char *name) +{ + section *s, *sp; + + /* Search through current sections to see if we already have one with + * that name. + */ + s = (section *)NULL; + STAILQ_FOREACH(sp, headp, link) { + if (strcmp(sp->name, name) == 0) + s = sp; + } + + if (s) + return s; + + /* No: we have to allocate and create a new one. */ + + /* But first check with objfmt to see if the name is valid. + * If it isn't, error and just return the default (first) section. + */ + if (!of->is_valid_section(name)) { + Error(_("Invalid section name: %s"), name); + return STAILQ_FIRST(headp); + } + + /* Okay, the name is valid; now allocate and initialize */ + s = calloc(1, sizeof(section)); + if (!s) + Fatal(FATAL_NOMEM); + STAILQ_INSERT_TAIL(headp, s, link); + + s->type = SECTION_GENERAL; + s->name = strdup(name); + bytecodes_initialize(&s->bc); + + return s; +} diff --git a/src/section.h b/src/section.h index 592fb67b..71dd50b2 100644 --- a/src/section.h +++ b/src/section.h @@ -22,18 +22,18 @@ #ifndef YASM_SECTION_H #define YASM_SECTION_H +struct objfmt_s; + typedef STAILQ_HEAD(sectionhead_s, section_s) sectionhead; typedef struct section_s { STAILQ_ENTRY(section_s) link; - enum { SECTION_DEFAULT, SECTION_GENERAL, SECTION_ABSOLUTE } type; + enum { SECTION_GENERAL, SECTION_ABSOLUTE } type; - char *name; - unsigned int id; + char *name; /* strdup()'ed name (given by user) */ union { - /* SECTION_DEFAULT data */ /* SECTION_GENERAL data */ /* SECTION_ABSOLUTE data */ unsigned long start; @@ -42,4 +42,9 @@ typedef struct section_s { bytecodehead bc; /* the bytecodes for the section's contents */ } section; +section *sections_initialize(sectionhead *headp, struct objfmt_s *of); + +section *sections_switch(sectionhead *headp, struct objfmt_s *of, + const char *name); + #endif