From a4996c06c66d6f06fec27eadcb0f651bb896a4a7 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Fri, 6 Feb 2004 21:12:56 +0000 Subject: [PATCH] Massive libyasm / module interface update - Phase 2 (finally). (Hopefully) finish cleanups begun in phase 1 (see phase 1 commit message), making dbgfmt, objfmt, optimizer, and preproc module interfaces follow the same thread-safe interface style as the phase 1 changes. Also put in a large number of doxygen documentation cleanups. svn path=/trunk/yasm/; revision=1097 --- Mkfiles/vc/yasm-module.c | 34 +-- frontends/yasm/yasm-module.c | 40 +-- frontends/yasm/yasm-module.h | 11 +- frontends/yasm/yasm.c | 186 +++++++------- libyasm/arch.h | 138 ++++++----- libyasm/coretype.h | 27 ++ libyasm/dbgfmt.h | 139 ++++++++--- libyasm/hamt.h | 42 +++- libyasm/linemgr.h | 50 +++- libyasm/objfmt.c | 6 +- libyasm/objfmt.h | 273 ++++++++++++++------- libyasm/optimizer.h | 48 ++-- libyasm/parser.h | 47 ++-- libyasm/preproc.h | 175 ++++++++++--- modules/dbgfmts/null/null-dbgfmt.c | 41 +++- modules/dbgfmts/stabs/stabs-dbgfmt.c | 87 ++++--- modules/objfmts/bin/bin-objfmt.c | 132 +++++++--- modules/objfmts/coff/coff-objfmt.c | 251 ++++++++++++------- modules/objfmts/dbg/dbg-objfmt.c | 215 ++++++++-------- modules/objfmts/elf/elf-objfmt.c | 250 ++++++++++++------- modules/optimizers/basic/basic-optimizer.c | 2 +- modules/parsers/nasm/nasm-bison.y | 44 ++-- modules/parsers/nasm/nasm-parser.c | 5 +- modules/parsers/nasm/nasm-parser.h | 2 +- modules/parsers/nasm/nasm-token.re | 3 +- modules/preprocs/nasm/nasm-preproc.c | 98 ++++---- modules/preprocs/raw/raw-preproc.c | 86 +++++-- 27 files changed, 1571 insertions(+), 861 deletions(-) diff --git a/Mkfiles/vc/yasm-module.c b/Mkfiles/vc/yasm-module.c index 214f2e91..3e2cd108 100644 --- a/Mkfiles/vc/yasm-module.c +++ b/Mkfiles/vc/yasm-module.c @@ -39,19 +39,19 @@ typedef struct module { void *data; /* associated data */ } module; -extern yasm_arch yasm_x86_LTX_arch; -extern yasm_arch yasm_lc3b_LTX_arch; -extern yasm_dbgfmt yasm_null_LTX_dbgfmt; -extern yasm_objfmt yasm_bin_LTX_objfmt; -extern yasm_objfmt yasm_coff_LTX_objfmt; -extern yasm_objfmt yasm_win32_LTX_objfmt; -extern yasm_objfmt yasm_dbg_LTX_objfmt; -extern yasm_objfmt yasm_elf_LTX_objfmt; -extern yasm_optimizer yasm_basic_LTX_optimizer; -extern yasm_parser yasm_nasm_LTX_parser; -extern yasm_preproc yasm_nasm_LTX_preproc; -extern yasm_preproc yasm_raw_LTX_preproc; -extern yasm_preproc yasm_yapp_LTX_preproc; +extern yasm_arch_module yasm_x86_LTX_arch; +extern yasm_arch_module yasm_lc3b_LTX_arch; +extern yasm_dbgfmt_module yasm_null_LTX_dbgfmt; +extern yasm_objfmt_module yasm_bin_LTX_objfmt; +extern yasm_objfmt_module yasm_coff_LTX_objfmt; +extern yasm_objfmt_module yasm_win32_LTX_objfmt; +extern yasm_objfmt_module yasm_dbg_LTX_objfmt; +extern yasm_objfmt_module yasm_elf_LTX_objfmt; +extern yasm_optimizer_module yasm_basic_LTX_optimizer; +extern yasm_parser_module yasm_nasm_LTX_parser; +extern yasm_preproc_module yasm_nasm_LTX_preproc; +extern yasm_preproc_module yasm_raw_LTX_preproc; +extern yasm_preproc_module yasm_yapp_LTX_preproc; static module modules[] = { {MODULE_ARCH, "x86", "arch", &yasm_x86_LTX_arch}, @@ -111,11 +111,11 @@ list_modules(module_type type, { int i; yasm_arch_module *arch; - yasm_dbgfmt *dbgfmt; - yasm_objfmt *objfmt; - yasm_optimizer *optimizer; + yasm_dbgfmt_module *dbgfmt; + yasm_objfmt_module *objfmt; + yasm_optimizer_module *optimizer; yasm_parser_module *parser; - yasm_preproc *preproc; + yasm_preproc_module *preproc; /* Go through available list, and try to load each one */ for (i=0; ikeyword; - module_name = dbgfmt->name; + dbgfmt_module = lt_dlsym(handle, name+2); + if (dbgfmt_module) { + module_keyword = dbgfmt_module->keyword; + module_name = dbgfmt_module->name; } break; case MODULE_OBJFMT: strncpy(name+2, "yasm", 4); - objfmt = lt_dlsym(handle, name+2); - if (objfmt) { - module_keyword = objfmt->keyword; - module_name = objfmt->name; + objfmt_module = lt_dlsym(handle, name+2); + if (objfmt_module) { + module_keyword = objfmt_module->keyword; + module_name = objfmt_module->name; } break; case MODULE_OPTIMIZER: strncpy(name+5, "yasm", 4); - optimizer = lt_dlsym(handle, name+5); - if (optimizer) { - module_keyword = optimizer->keyword; - module_name = optimizer->name; + optimizer_module = lt_dlsym(handle, name+5); + if (optimizer_module) { + module_keyword = optimizer_module->keyword; + module_name = optimizer_module->name; } break; case MODULE_PARSER: @@ -251,10 +251,10 @@ list_module_load(const char *filename, lt_ptr data) break; case MODULE_PREPROC: strncpy(name+3, "yasm", 4); - preproc = lt_dlsym(handle, name+3); - if (preproc) { - module_keyword = preproc->keyword; - module_name = preproc->name; + preproc_module = lt_dlsym(handle, name+3); + if (preproc_module) { + module_keyword = preproc_module->keyword; + module_name = preproc_module->name; } break; } diff --git a/frontends/yasm/yasm-module.h b/frontends/yasm/yasm-module.h index 49ca7a4a..f7efa845 100644 --- a/frontends/yasm/yasm-module.h +++ b/frontends/yasm/yasm-module.h @@ -40,16 +40,17 @@ void unload_modules(void); /*@dependent@*/ /*@null@*/ void *get_module_data (module_type type, const char *keyword, const char *symbol); -#define load_arch_module(keyword) get_module_data(MODULE_ARCH, keyword, "arch") -#define load_dbgfmt(keyword) \ +#define load_arch_module(keyword) \ + get_module_data(MODULE_ARCH, keyword, "arch") +#define load_dbgfmt_module(keyword) \ get_module_data(MODULE_DBGFMT, keyword, "dbgfmt") -#define load_objfmt(keyword) \ +#define load_objfmt_module(keyword) \ get_module_data(MODULE_OBJFMT, keyword, "objfmt") -#define load_optimizer(keyword) \ +#define load_optimizer_module(keyword) \ get_module_data(MODULE_OPTIMIZER, keyword, "optimizer") #define load_parser_module(keyword) \ get_module_data(MODULE_PARSER, keyword, "parser") -#define load_preproc(keyword) \ +#define load_preproc_module(keyword) \ get_module_data(MODULE_PREPROC, keyword, "preproc") void list_modules(module_type type, diff --git a/frontends/yasm/yasm.c b/frontends/yasm/yasm.c index 9f012848..a3c12cb7 100644 --- a/frontends/yasm/yasm.c +++ b/frontends/yasm/yasm.c @@ -51,12 +51,12 @@ extern const lt_dlsymlist lt_preloaded_symbols[]; #define PREPROC_BUF_SIZE 16384 /* Check the module version */ -#define check_module_version(d, TYPE, desc) \ +#define check_module_version(d, TYPE, type) \ do { \ if (d && d->version != YASM_##TYPE##_VERSION) { \ print_error( \ _("%s: module version mismatch: %s `%s' (need %d, module %d)"), \ - _("FATAL"), _(desc), d->keyword, YASM_##TYPE##_VERSION, \ + _("FATAL"), _(#type), d->keyword, YASM_##TYPE##_VERSION, \ d->version); \ exit(EXIT_FAILURE); \ } \ @@ -71,9 +71,16 @@ static int special_options = 0; /*@null@*/ /*@dependent@*/ static const yasm_parser_module * cur_parser_module = NULL; /*@null@*/ /*@dependent@*/ static yasm_preproc *cur_preproc = NULL; +/*@null@*/ /*@dependent@*/ static const yasm_preproc_module * + cur_preproc_module = NULL; /*@null@*/ /*@dependent@*/ static yasm_objfmt *cur_objfmt = NULL; -/*@null@*/ /*@dependent@*/ static yasm_optimizer *cur_optimizer = NULL; +/*@null@*/ /*@dependent@*/ static const yasm_objfmt_module * + cur_objfmt_module = NULL; +/*@null@*/ /*@dependent@*/ static const yasm_optimizer_module * + cur_optimizer_module = NULL; /*@null@*/ /*@dependent@*/ static yasm_dbgfmt *cur_dbgfmt = NULL; +/*@null@*/ /*@dependent@*/ static const yasm_dbgfmt_module * + cur_dbgfmt_module = NULL; static int preproc_only = 0; static int warning_error = 0; /* warnings being treated as errors */ static enum { @@ -346,22 +353,24 @@ main(int argc, char *argv[]) } /* If not already specified, default to nasm preproc. */ - if (!cur_preproc) - cur_preproc = load_preproc("nasm"); + if (!cur_preproc_module) + cur_preproc_module = load_preproc_module("nasm"); - if (!cur_preproc) { + if (!cur_preproc_module) { print_error(_("%s: could not load default %s"), _("FATAL"), _("preprocessor")); cleanup(NULL); return EXIT_FAILURE; } - check_module_version(cur_preproc, PREPROC, "preproc"); + check_module_version(cur_preproc_module, PREPROC, preproc); apply_preproc_saved_options(); /* Pre-process until done */ - cur_preproc->initialize(in, in_filename, linemap); - while ((got = cur_preproc->input(preproc_buf, PREPROC_BUF_SIZE)) != 0) + cur_preproc = yasm_preproc_create(cur_preproc_module, in, in_filename, + linemap); + while ((got = yasm_preproc_input(cur_preproc, preproc_buf, + PREPROC_BUF_SIZE)) != 0) fwrite(preproc_buf, got, 1, obj); if (in != stdin) @@ -388,6 +397,7 @@ main(int argc, char *argv[]) /* Create object */ object = yasm_object_create(); + yasm_linemap_set(yasm_object_get_linemap(object), in_filename, 1, 1); /* Default to x86 as the architecture */ if (!cur_arch_module) { @@ -398,7 +408,7 @@ main(int argc, char *argv[]) return EXIT_FAILURE; } } - check_module_version(cur_arch_module, ARCH, "arch"); + check_module_version(cur_arch_module, ARCH, arch); /* Set up architecture using the selected (or default) machine */ if (!machine_name) @@ -424,42 +434,42 @@ main(int argc, char *argv[]) } /* Set basic as the optimizer (TODO: user choice) */ - cur_optimizer = load_optimizer("basic"); + cur_optimizer_module = load_optimizer_module("basic"); - if (!cur_optimizer) { + if (!cur_optimizer_module) { print_error(_("%s: could not load default %s"), _("FATAL"), _("optimizer")); return EXIT_FAILURE; } - check_module_version(cur_optimizer, OPTIMIZER, "optimizer"); + check_module_version(cur_optimizer_module, OPTIMIZER, optimizer); /* If not already specified, default to bin as the object format. */ - if (!cur_objfmt) - cur_objfmt = load_objfmt("bin"); + if (!cur_objfmt_module) + cur_objfmt_module = load_objfmt_module("bin"); - if (!cur_objfmt) { + if (!cur_objfmt_module) { print_error(_("%s: could not load default %s"), _("FATAL"), _("object format")); return EXIT_FAILURE; } - check_module_version(cur_objfmt, OBJFMT, "objfmt"); + check_module_version(cur_objfmt_module, OBJFMT, objfmt); /* If not already specified, default to null as the debug format. */ - if (!cur_dbgfmt) - cur_dbgfmt = load_dbgfmt("null"); + if (!cur_dbgfmt_module) + cur_dbgfmt_module = load_dbgfmt_module("null"); else { int matched_dbgfmt = 0; /* Check to see if the requested debug format is in the allowed list * for the active object format. */ - for (i=0; cur_objfmt->dbgfmt_keywords[i]; i++) - if (yasm__strcasecmp(cur_objfmt->dbgfmt_keywords[i], - cur_dbgfmt->keyword) == 0) + for (i=0; cur_objfmt_module->dbgfmt_keywords[i]; i++) + if (yasm__strcasecmp(cur_objfmt_module->dbgfmt_keywords[i], + cur_dbgfmt_module->keyword) == 0) matched_dbgfmt = 1; if (!matched_dbgfmt) { print_error(_("%s: `%s' is not a valid %s for %s `%s'"), - _("FATAL"), cur_dbgfmt->keyword, _("debug format"), - _("object format"), cur_objfmt->keyword); + _("FATAL"), cur_dbgfmt_module->keyword, _("debug format"), + _("object format"), cur_objfmt_module->keyword); if (in != stdin) fclose(in); /*cleanup(NULL);*/ @@ -467,12 +477,12 @@ main(int argc, char *argv[]) } } - if (!cur_dbgfmt) { + if (!cur_dbgfmt_module) { print_error(_("%s: could not load default %s"), _("FATAL"), _("debug format")); return EXIT_FAILURE; } - check_module_version(cur_dbgfmt, DBGFMT, "dbgfmt"); + check_module_version(cur_dbgfmt_module, DBGFMT, dbgfmt); /* determine the object filename if not specified */ if (!obj_filename) { @@ -482,41 +492,40 @@ main(int argc, char *argv[]) else /* replace (or add) extension */ obj_filename = replace_extension(in_filename, - cur_objfmt->extension, + cur_objfmt_module->extension, "yasm.out"); } - /* Initialize the debug format */ - if (cur_dbgfmt->initialize) { - if (cur_dbgfmt->initialize(in_filename, obj_filename, object, - cur_objfmt, cur_arch)) - { - print_error( - _("%s: debug format `%s' does not work with object format `%s'"), - _("FATAL"), cur_dbgfmt->keyword, cur_objfmt->keyword); - if (in != stdin) - fclose(in); - return EXIT_FAILURE; - } - } - /* Initialize the object format */ - if (cur_objfmt->initialize) { - if (cur_objfmt->initialize(in_filename, obj_filename, object, - cur_dbgfmt, cur_arch)) { - print_error( - _("%s: object format `%s' does not support architecture `%s' machine `%s'"), - _("FATAL"), cur_objfmt->keyword, cur_arch_module->keyword, - machine_name); - if (in != stdin) - fclose(in); - return EXIT_FAILURE; - } + cur_objfmt = yasm_objfmt_create(cur_objfmt_module, in_filename, object, + cur_arch); + if (!cur_objfmt) { + print_error( + _("%s: object format `%s' does not support architecture `%s' machine `%s'"), + _("FATAL"), cur_objfmt_module->keyword, cur_arch_module->keyword, + machine_name); + if (in != stdin) + fclose(in); + return EXIT_FAILURE; } /* Add an initial "default" section to object */ def_sect = yasm_objfmt_add_default_section(cur_objfmt, object); + /* Initialize the debug format */ + cur_dbgfmt = yasm_dbgfmt_create(cur_dbgfmt_module, in_filename, + obj_filename, object, cur_objfmt, + cur_arch); + if (!cur_dbgfmt) { + print_error( + _("%s: debug format `%s' does not work with object format `%s'"), + _("FATAL"), cur_dbgfmt_module->keyword, + cur_objfmt_module->keyword); + if (in != stdin) + fclose(in); + return EXIT_FAILURE; + } + /* Default to NASM as the parser */ if (!cur_parser_module) { cur_parser_module = load_parser_module("nasm"); @@ -527,11 +536,12 @@ main(int argc, char *argv[]) return EXIT_FAILURE; } } - check_module_version(cur_parser_module, PARSER, "parser"); + check_module_version(cur_parser_module, PARSER, parser); /* If not already specified, default to the parser's default preproc. */ - if (!cur_preproc) - cur_preproc = load_preproc(cur_parser_module->default_preproc_keyword); + if (!cur_preproc_module) + cur_preproc_module = + load_preproc_module(cur_parser_module->default_preproc_keyword); else { int matched_preproc = 0; /* Check to see if the requested preprocessor is in the allowed list @@ -539,12 +549,13 @@ main(int argc, char *argv[]) */ for (i=0; cur_parser_module->preproc_keywords[i]; i++) if (yasm__strcasecmp(cur_parser_module->preproc_keywords[i], - cur_preproc->keyword) == 0) + cur_preproc_module->keyword) == 0) matched_preproc = 1; if (!matched_preproc) { print_error(_("%s: `%s' is not a valid %s for %s `%s'"), - _("FATAL"), cur_preproc->keyword, _("preprocessor"), - _("parser"), cur_parser_module->keyword); + _("FATAL"), cur_preproc_module->keyword, + _("preprocessor"), _("parser"), + cur_parser_module->keyword); if (in != stdin) fclose(in); cleanup(NULL); @@ -552,20 +563,23 @@ main(int argc, char *argv[]) } } - if (!cur_preproc) { + if (!cur_preproc_module) { print_error(_("%s: could not load default %s"), _("FATAL"), _("preprocessor")); cleanup(NULL); return EXIT_FAILURE; } - check_module_version(cur_preproc, PREPROC, "preproc"); + check_module_version(cur_preproc_module, PREPROC, preproc); + + cur_preproc = cur_preproc_module->create(in, in_filename, + yasm_object_get_linemap(object)); apply_preproc_saved_options(); /* Get initial x86 BITS setting from object format */ if (strcmp(cur_arch_module->keyword, "x86") == 0) { - cur_arch_module->set_var(cur_arch, "mode_bits", - cur_objfmt->default_x86_mode_bits); + yasm_arch_set_var(cur_arch, "mode_bits", + cur_objfmt_module->default_x86_mode_bits); } /* Parse! */ @@ -584,7 +598,7 @@ main(int argc, char *argv[]) } yasm_symtab_parser_finalize(yasm_object_get_symtab(object)); - cur_optimizer->optimize(object); + cur_optimizer_module->optimize(object); if (yasm_get_num_errors(warning_error) > 0) { yasm_errwarn_output_all(yasm_object_get_linemap(object), warning_error, @@ -594,12 +608,10 @@ main(int argc, char *argv[]) } /* generate any debugging information */ - if (cur_dbgfmt->generate) { - cur_dbgfmt->generate(object); - } + yasm_dbgfmt_generate(cur_dbgfmt); /* open the object file for output (if not already opened by dbg objfmt) */ - if (!obj && strcmp(cur_objfmt->keyword, "dbg") != 0) { + if (!obj && strcmp(cur_objfmt_module->keyword, "dbg") != 0) { obj = open_obj("wb"); if (!obj) { cleanup(object); @@ -608,8 +620,8 @@ main(int argc, char *argv[]) } /* Write the object file */ - cur_objfmt->output(obj?obj:stderr, object, - strcmp(cur_dbgfmt->keyword, "null")); + yasm_objfmt_output(cur_objfmt, obj?obj:stderr, obj_filename, + strcmp(cur_dbgfmt_module->keyword, "null"), cur_dbgfmt); /* Close object file */ if (obj) @@ -659,16 +671,16 @@ static void cleanup(yasm_object *object) { if (DO_FREE) { - if (cur_objfmt && cur_objfmt->cleanup) - cur_objfmt->cleanup(); - if (cur_dbgfmt && cur_dbgfmt->cleanup) - cur_dbgfmt->cleanup(); + if (cur_objfmt) + yasm_objfmt_destroy(cur_objfmt); + if (cur_dbgfmt) + yasm_dbgfmt_destroy(cur_dbgfmt); if (cur_preproc) - cur_preproc->cleanup(); + yasm_preproc_destroy(cur_preproc); if (object) yasm_object_destroy(object); if (cur_arch) - cur_arch_module->destroy(cur_arch); + yasm_arch_destroy(cur_arch); yasm_floatnum_cleanup(); yasm_intnum_cleanup(); @@ -762,8 +774,8 @@ static int opt_preproc_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra) { assert(param != NULL); - cur_preproc = load_preproc(param); - if (!cur_preproc) { + cur_preproc_module = load_preproc_module(param); + if (!cur_preproc_module) { if (!strcmp("help", param)) { printf(_("Available yasm %s:\n"), _("preprocessors")); list_preprocs(print_list_keyword_desc); @@ -781,8 +793,8 @@ static int opt_objfmt_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra) { assert(param != NULL); - cur_objfmt = load_objfmt(param); - if (!cur_objfmt) { + cur_objfmt_module = load_objfmt_module(param); + if (!cur_objfmt_module) { if (!strcmp("help", param)) { printf(_("Available yasm %s:\n"), _("object formats")); list_objfmts(print_list_keyword_desc); @@ -800,8 +812,8 @@ static int opt_dbgfmt_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra) { assert(param != NULL); - cur_dbgfmt = load_dbgfmt(param); - if (!cur_dbgfmt) { + cur_dbgfmt_module = load_dbgfmt_module(param); + if (!cur_dbgfmt_module) { if (!strcmp("help", param)) { printf(_("Available yasm %s:\n"), _("debug formats")); list_dbgfmts(print_list_keyword_desc); @@ -918,15 +930,15 @@ apply_preproc_saved_options() { constcharparam *cp, *cpnext; - void (*funcs[4])(const char *); - funcs[0] = cur_preproc->add_include_path; - funcs[1] = cur_preproc->add_include_file; - funcs[2] = cur_preproc->predefine_macro; - funcs[3] = cur_preproc->undefine_macro; + void (*funcs[4])(yasm_preproc *, const char *); + funcs[0] = cur_preproc_module->add_include_path; + funcs[1] = cur_preproc_module->add_include_file; + funcs[2] = cur_preproc_module->predefine_macro; + funcs[3] = cur_preproc_module->undefine_macro; STAILQ_FOREACH(cp, &preproc_options, link) { if (0 <= cp->id && cp->id < 4 && funcs[cp->id]) - funcs[cp->id](cp->param); + funcs[cp->id](cur_preproc, cp->param); } cp = STAILQ_FIRST(&preproc_options); diff --git a/libyasm/arch.h b/libyasm/arch.h index 43a262fb..132a65e1 100644 --- a/libyasm/arch.h +++ b/libyasm/arch.h @@ -107,113 +107,156 @@ typedef struct yasm_arch_machine { #define YASM_ARCH_VERSION 2 /** YASM architecture module interface. - * \note All "data" in parser-related functions (parse_*) needs to start the - * parse initialized to 0 to make it okay for a parser-related function - * to use/check previously stored data to see if it's been called before - * on the same piece of data. + * \note All "data" in parser-related functions (yasm_arch_parse_*) needs to + * start the parse initialized to 0 to make it okay for a parser-related + * function to use/check previously stored data to see if it's been + * called before on the same piece of data. */ -typedef struct yasm_arch_module yasm_arch_module; - -#ifndef YASM_DOXYGEN -struct yasm_arch_module { +typedef struct yasm_arch_module { /** Version (see #YASM_ARCH_VERSION). Should always be set to * #YASM_ARCH_VERSION by the module source and checked against * #YASM_ARCH_VERSION by the module loader. */ unsigned int version; - /** One-line description of the architecture. */ + /** One-line description of the architecture. + * Call yasm_arch_name() to get the name of a particular #yasm_arch. + */ const char *name; - /** Keyword used to select architecture. */ + /** Keyword used to select architecture. + * Call yasm_arch_keyword() to get the keyword of a particular #yasm_arch. + */ const char *keyword; - /** Initialize architecture for use. + /** Create architecture. + * Module-level implementation of yasm_arch_create(). + * Call yasm_arch_create() instead of calling this function. * \param machine keyword of machine in use (must be one listed in * #machines) * \return NULL if machine not recognized. */ /*@only@*/ yasm_arch * (*create) (const char *machine); - /** \copydoc yasm_arch_destroy() */ + /** Module-level implementation of yasm_arch_destroy(). + * Call yasm_arch_destroy() instead of calling this function. + */ void (*destroy) (/*@only@*/ yasm_arch *arch); - /** \copydoc yasm_arch_get_machine() */ + /** Module-level implementation of yasm_arch_get_machine(). + * Call yasm_arch_get_machine() instead of calling this function. + */ const char * (*get_machine) (const yasm_arch *arch); - /** \copydoc yasm_arch_set_var() */ + /** Module-level implementation of yasm_arch_set_var(). + * Call yasm_arch_set_var() instead of calling this function. + */ int (*set_var) (yasm_arch *arch, const char *var, unsigned long val); - /** \copydoc yasm_arch_parse_cpu() */ + /** Module-level implementation of yasm_arch_parse_cpu(). + * Call yasm_arch_parse_cpu() instead of calling this function. + */ void (*parse_cpu) (yasm_arch *arch, const char *cpuid, unsigned long line); - /** \copydoc yasm_arch_parse_check_id() */ + /** Module-level implementation of yasm_arch_parse_check_id(). + * Call yasm_arch_parse_check_id() instead of calling this function. + */ yasm_arch_check_id_retval (*parse_check_id) (yasm_arch *arch, unsigned long data[4], const char *id, unsigned long line); - /** \copydoc yasm_arch_parse_directive() */ + /** Module-level implementation of yasm_arch_parse_directive(). + * Call yasm_arch_parse_directive() instead of calling this function. + */ int (*parse_directive) (yasm_arch *arch, const char *name, yasm_valparamhead *valparams, /*@null@*/ yasm_valparamhead *objext_valparams, yasm_object *object, unsigned long line); - /** \copydoc yasm_arch_parse_insn() */ + /** Module-level implementation of yasm_arch_parse_insn(). + * Call yasm_arch_parse_insn() instead of calling this function. + */ /*@null@*/ yasm_bytecode * (*parse_insn) (yasm_arch *arch, const unsigned long data[4], int num_operands, /*@null@*/ yasm_insn_operands *operands, yasm_bytecode *prev_bc, unsigned long line); - /** \copydoc yasm_arch_parse_prefix() */ + /** Module-level implementation of yasm_arch_parse_prefix(). + * Call yasm_arch_parse_prefix() instead of calling this function. + */ void (*parse_prefix) (yasm_arch *arch, yasm_bytecode *bc, const unsigned long data[4], unsigned long line); - /** \copydoc yasm_arch_parse_seg_prefix() */ + /** Module-level implementation of yasm_arch_parse_seg_prefix(). + * Call yasm_arch_parse_seg_prefix() instead of calling this function. + */ void (*parse_seg_prefix) (yasm_arch *arch, yasm_bytecode *bc, unsigned long segreg, unsigned long line); - /** \copydoc yasm_arch_parse_seg_override() */ + /** Module-level implementation of yasm_arch_parse_seg_override(). + * Call yasm_arch_parse_seg_override() instead of calling this function. + */ void (*parse_seg_override) (yasm_arch *arch, yasm_effaddr *ea, unsigned long segreg, unsigned long line); - /** \copydoc yasm_arch_floatnum_tobytes() */ + /** Module-level implementation of yasm_arch_floatnum_tobytes(). + * Call yasm_arch_floatnum_tobytes() instead of calling this function. + */ int (*floatnum_tobytes) (yasm_arch *arch, const yasm_floatnum *flt, unsigned char *buf, size_t destsize, size_t valsize, size_t shift, int warn, unsigned long line); - /** \copydoc yasm_arch_intnum_tobytes() */ + /** Module-level implementation of yasm_arch_intnum_tobytes(). + * Call yasm_arch_intnum_tobytes() instead of calling this function. + */ int (*intnum_tobytes) (yasm_arch *arch, const yasm_intnum *intn, unsigned char *buf, size_t destsize, size_t valsize, int shift, const yasm_bytecode *bc, int rel, int warn, unsigned long line); - /** \copydoc yasm_arch_get_reg_size() */ + /** Module-level implementation of yasm_arch_get_reg_size(). + * Call yasm_arch_get_reg_size() instead of calling this function. + */ unsigned int (*get_reg_size) (yasm_arch *arch, unsigned long reg); - /** \copydoc yasm_arch_reg_print() */ + /** Module-level implementation of yasm_arch_reg_print(). + * Call yasm_arch_reg_print() instead of calling this function. + */ void (*reg_print) (yasm_arch *arch, unsigned long reg, FILE *f); - /** \copydoc yasm_arch_segreg_print() */ + /** Module-level implementation of yasm_arch_segreg_print(). + * Call yasm_arch_segreg_print() instead of calling this function. + */ void (*segreg_print) (yasm_arch *arch, unsigned long segreg, FILE *f); - /** \copydoc yasm_arch_ea_create() */ + /** Module-level implementation of yasm_arch_ea_create(). + * Call yasm_arch_ea_create() instead of calling this function. + */ yasm_effaddr * (*ea_create) (yasm_arch *arch, /*@keep@*/ yasm_expr *e); - /** NULL-terminated list of machines for this architecture. */ + /** NULL-terminated list of machines for this architecture. + * Call yasm_arch_get_machine() to get the active machine of a particular + * #yasm_arch. + */ yasm_arch_machine *machines; - /** Default machine keyword. */ + /** Default machine keyword. + * Call yasm_arch_get_machine() to get the active machine of a particular + * #yasm_arch. + */ const char *default_machine_keyword; - /** Canonical "word" size in bytes. */ + /** Canonical "word" size in bytes. + * Call yasm_arch_wordsize() to get the word size of a particular + * #yasm_arch. + */ unsigned int wordsize; -}; -#endif +} yasm_arch_module; #ifdef YASM_LIB_INTERNAL -/** An instruction operand. */ +/** An instruction operand. \internal */ struct yasm_insn_operand { /** Link for building linked list of operands. \internal */ /*@reldef@*/ STAILQ_ENTRY(yasm_insn_operand) link; @@ -241,40 +284,21 @@ struct yasm_insn_operand { }; #endif -/** Get the version number of an architecture module. - * \param module architecture module - * \return Version number (see #YASM_ARCH_VERSION). - */ -unsigned int yasm_arch_module_version(const yasm_arch_module *module); - -/** Get the machines usable with an architecture module. - * \param module architecture module - * \return NULL-terminated list of machines. - */ -const yasm_arch_machine *yasm_arch_module_machines - (const yasm_arch_module *module); - -/** Get the default machine keyword for an architecture module. - * \param module architecture module - * \return Default machine keyword. - */ -const char *yasm_arch_module_def_machine(const yasm_arch_module *module); - /** Get the one-line description of an architecture. * \param arch architecture - * \return keyword + * \return One-line description of architecture. */ const char *yasm_arch_name(const yasm_arch *arch); /** Get the keyword used to select an architecture. * \param arch architecture - * \return keyword + * \return Architecture keyword. */ const char *yasm_arch_keyword(const yasm_arch *arch); /** Get the word size of an architecture. * \param arch architecture - * \return word size + * \return Word size (in bits). */ unsigned int yasm_arch_wordsize(const yasm_arch *arch); @@ -479,10 +503,6 @@ yasm_effaddr *yasm_arch_ea_create(yasm_arch *arch, /*@keep@*/ yasm_expr *e); /* Inline macro implementations for arch functions */ -#define yasm_arch_module_version(module) (module->version) -#define yasm_arch_module_machines(module, machine) (module->machines) -#define yasm_arch_module_def_machine(module) (module->default_machine_keyword) - #define yasm_arch_name(arch) \ (((yasm_arch_base *)arch)->module->name) #define yasm_arch_keyword(arch) \ diff --git a/libyasm/coretype.h b/libyasm/coretype.h index f0d0ccd4..dc5cb5b0 100644 --- a/libyasm/coretype.h +++ b/libyasm/coretype.h @@ -51,7 +51,16 @@ typedef struct yasm_dbgfmt yasm_dbgfmt; * arbitrary data associated with them. */ typedef struct yasm_assoc_data_callback { + /** Free memory allocated for associated data. + * \param data associated data + */ void (*destroy) (/*@only@*/ void *data); + + /** Print a description of allocated data. For debugging purposes. + * \param data associated data + * \param f output file + * \param indent_level indentation level + */ void (*print) (void *data, FILE *f, int indent_level); } yasm_assoc_data_callback; @@ -181,6 +190,24 @@ typedef int (*yasm_output_expr_func) size_t valsize, int shift, unsigned long offset, yasm_bytecode *bc, int rel, int warn, /*@null@*/ void *d) /*@uses *ep@*/; +/** Convert a symbol reference to its byte representation. Usually implemented + * by object formats and debug formats to keep track of relocations generated + * by themselves. + * \param sym symbol + * \param bc current bytecode (usually passed into higher-level + * calling function) + * \param buf buffer for byte representation + * \param destsize destination size (in bytes) + * \param valsize size (in bits) + * \param rel if nonzero, expr should be treated as PC/IP-relative + * \param warn enables standard warnings: zero for none; + * nonzero for overflow/underflow floating point warnings; + * negative for signed integer warnings, + * positive for unsigned integer warnings + * \param d objfmt-specific data (passed into higher-level calling + * function) + * \return Nonzero if an error occurred, 0 otherwise. + */ typedef int (*yasm_output_reloc_func) (yasm_symrec *sym, yasm_bytecode *bc, unsigned char *buf, size_t destsize, size_t valsize, int rel, int warn, void *d); diff --git a/libyasm/dbgfmt.h b/libyasm/dbgfmt.h index b1cebe87..20253994 100644 --- a/libyasm/dbgfmt.h +++ b/libyasm/dbgfmt.h @@ -34,19 +34,29 @@ #ifndef YASM_DBGFMT_H #define YASM_DBGFMT_H -/** Version number of #yasm_dbgfmt interface. Any functional change to the - * #yasm_dbgfmt interface should simultaneously increment this number. This - * version should be checked by #yasm_dbgfmt loaders to verify that the - * expected version (the version defined by its libyasm header files) matches - * the loaded module version (the version defined by the module's libyasm - * header files). Doing this will ensure that the module version's function - * definitions match the module loader's function definitions. The version - * number must never be decreased. +#ifndef YASM_DOXYGEN +/** Base #yasm_dbgfmt structure. Must be present as the first element in any + * #yasm_dbgfmt implementation. */ -#define YASM_DBGFMT_VERSION 2 +typedef struct yasm_dbgfmt_base { + /** #yasm_dbgfmt_module implementation for this debug format. */ + const struct yasm_dbgfmt_module *module; +} yasm_dbgfmt_base; +#endif + +/** Version number of #yasm_dbgfmt_module interface. Any functional change to + * the #yasm_dbgfmt_module interface should simultaneously increment this + * number. This version should be checked by #yasm_dbgfmt loaders to verify + * that the expected version (the version defined by its libyasm header files) + * matches the loaded module version (the version defined by the module's + * libyasm header files). Doing this will ensure that the module version's + * function definitions match the module loader's function definitions. The + * version number must never be decreased. + */ +#define YASM_DBGFMT_VERSION 3 -/** YASM debug format interface. */ -struct yasm_dbgfmt { +/** YASM debug format module interface. */ +typedef struct yasm_dbgfmt_module { /** Version (see #YASM_DBGFMT_VERSION). Should always be set to * #YASM_DBGFMT_VERSION by the module source and checked against * #YASM_DBGFMT_VERSION by the module loader. @@ -59,37 +69,98 @@ struct yasm_dbgfmt { /** Keyword used to select debug format. */ const char *keyword; - /** Initialize debug output for use. Must call before any other debug - * format functions. The filenames are provided solely for informational - * purposes. Function may be unimplemented (NULL) if not needed by the - * debug format. + /** Create debug format. + * Module-level implementation of yasm_dbgfmt_create(). + * The filenames are provided solely for informational purposes. * \param in_filename primary input filename * \param obj_filename object filename + * \param object object * \param of object format in use - * \return Nonzero if object format does not provide needed support. + * \param a architecture in use + * \return NULL if object format does not provide needed support. */ - int (*initialize) (const char *in_filename, const char *obj_filename, - yasm_object *object, yasm_objfmt *of, yasm_arch *a); + /*@null@*/ /*@only@*/ yasm_dbgfmt * (*create) + (const char *in_filename, const char *obj_filename, + yasm_object *object, yasm_objfmt *of, yasm_arch *a); - /** Clean up anything allocated by initialize(). Function may be - * unimplemented (NULL) if not needed by the debug format. + /** Module-level implementation of yasm_dbgfmt_destroy(). + * Call yasm_dbgfmt_destroy() instead of calling this function. */ - void (*cleanup) (void); - - /** DEBUG directive support. - * \param name directive name - * \param valparams value/parameters - * \param line virtual line (from yasm_linemap) - * \return Nonzero if directive was not recognized; 0 if directive was - * recognized even if it wasn't valid. + void (*destroy) (/*@only@*/ yasm_dbgfmt *dbgfmt); + + /** Module-level implementation of yasm_dbgfmt_directive(). + * Call yasm_dbgfmt_directive() instead of calling this function. */ - int (*directive) (const char *name, yasm_valparamhead *valparams, - unsigned long line); + int (*directive) (yasm_dbgfmt *dbgfmt, const char *name, + yasm_valparamhead *valparams, unsigned long line); - /** Generate debugging information bytecodes - * \param object object + /** Module-level implementation of yasm_dbgfmt_generate(). + * Call yasm_dbgfmt_generate() instead of calling this function. */ - void (*generate) (yasm_object *object); -}; + void (*generate) (yasm_dbgfmt *dbgfmt); +} yasm_dbgfmt_module; + +/** Get the keyword used to select a debug format. + * \param dbgfmt debug format + * \return keyword + */ +const char *yasm_dbgfmt_keyword(const yasm_dbgfmt *dbgfmt); + +/** Initialize debug output for use. Must call before any other debug + * format functions. The filenames are provided solely for informational + * purposes. + * \param module debug format module + * \param in_filename primary input filename + * \param obj_filename object filename + * \param object object to generate debugging information for + * \param of object format in use + * \param a architecture in use + * \return NULL if object format does not provide needed support. + */ +/*@null@*/ /*@only@*/ yasm_dbgfmt *yasm_dbgfmt_create + (const yasm_dbgfmt_module *module, const char *in_filename, + const char *obj_filename, yasm_object *object, yasm_objfmt *of, + yasm_arch *a); + +/** Cleans up any allocated debug format memory. + * \param dbgfmt debug format + */ +void yasm_dbgfmt_destroy(/*@only@*/ yasm_dbgfmt *dbgfmt); + +/** DEBUG directive support. + * \param dbgfmt debug format + * \param name directive name + * \param valparams value/parameters + * \param line virtual line (from yasm_linemap) + * \return Nonzero if directive was not recognized; 0 if directive was + * recognized even if it wasn't valid. + */ +int yasm_dbgfmt_directive(yasm_dbgfmt *dbgfmt, const char *name, + yasm_valparamhead *valparams, unsigned long line); + +/** Generate debugging information bytecodes. + * \param dbgfmt debug format + */ +void yasm_dbgfmt_generate(yasm_dbgfmt *dbgfmt); + +#ifndef YASM_DOXYGEN + +/* Inline macro implementations for dbgfmt functions */ + +#define yasm_dbgfmt_keyword(dbgfmt) \ + (((yasm_dbgfmt_base *)dbgfmt)->module->keyword) + +#define yasm_dbgfmt_create(module, in_filename, obj_filename, object, of, a) \ + module->create(in_filename, obj_filename, object, of, a) + +#define yasm_dbgfmt_destroy(dbgfmt) \ + ((yasm_dbgfmt_base *)dbgfmt)->module->destroy(dbgfmt) +#define yasm_dbgfmt_directive(dbgfmt, name, valparams, line) \ + ((yasm_dbgfmt_base *)dbgfmt)->module->directive(dbgfmt, name, valparams, \ + line) +#define yasm_dbgfmt_generate(dbgfmt) \ + ((yasm_dbgfmt_base *)dbgfmt)->module->generate(dbgfmt) + +#endif #endif diff --git a/libyasm/hamt.h b/libyasm/hamt.h index a9331903..a85fd63a 100644 --- a/libyasm/hamt.h +++ b/libyasm/hamt.h @@ -1,6 +1,12 @@ -/* $IdPath$ - * Hash Array Mapped Trie (HAMT) header file. +/** + * \file libyasm/hamt.h + * \brief Hash Array Mapped Trie (HAMT) functions. * + * \rcs + * $IdPath$ + * \endrcs + * + * \license * Copyright (C) 2001 Peter Johnson * * Redistribution and use in source and binary forms, with or without @@ -23,25 +29,31 @@ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. + * \endlicense */ #ifndef YASM_HAMT_H #define YASM_HAMT_H +/** Hash array mapped trie data structure (opaque type). */ typedef struct HAMT HAMT; -/* Creates new, empty, HAMT. error_func() is called when an internal error is +/** Create new, empty, HAMT. error_func() is called when an internal error is * encountered--it should NOT return to the calling function. + * \param error_func function called on internal error + * \return New, empty, hash array mapped trie. */ HAMT *HAMT_create(/*@exits@*/ void (*error_func) (const char *file, unsigned int line, const char *message)); -/* Deletes HAMT and all data associated with it using deletefunc() on each data - * item. +/** Delete HAMT and all data associated with it. Uses deletefunc() to delete + * each data item. + * \param hamt Hash array mapped trie + * \param deletefunc Data deletion function */ void HAMT_destroy(/*@only@*/ HAMT *hamt, void (*deletefunc) (/*@only@*/ void *data)); -/* Inserts key into HAMT, associating it with data. +/** Insert key into HAMT, associating it with data. * If the key is not present in the HAMT, inserts it, sets *replace to 1, and * returns the data passed in. * If the key is already present and *replace is 0, deletes the data passed @@ -50,18 +62,30 @@ void HAMT_destroy(/*@only@*/ HAMT *hamt, * If the key is already present and *replace is 1, deletes the data currently * associated with the key using deletefunc() and replaces it with the data * passed in. + * \param hamt Hash array mapped trie + * \param str Key + * \param data Data to associate with key + * \param replace See above description + * \param deletefunc Data deletion function if data is replaced + * \return Data now associated with key. */ /*@dependent@*/ void *HAMT_insert(HAMT *hamt, /*@dependent@*/ const char *str, /*@only@*/ void *data, int *replace, void (*deletefunc) (/*@only@*/ void *data)); -/* Searches for the data associated with a key in the HAMT. If the key is not - * present, returns NULL. +/** Search for the data associated with a key in the HAMT. + * \param hamt Hash array mapped trie + * \param str Key + * \return NULL if key/data not present in HAMT, otherwise associated data. */ /*@dependent@*/ /*@null@*/ void *HAMT_search(HAMT *hamt, const char *str); -/* Traverse over all keys in HAMT, calling func() for each data item. +/** Traverse over all keys in HAMT, calling function on each data item. * Stops early if func returns 0. + * \param hamt Hash array mapped trie + * \param d Data to pass to each call to func. + * \param func Function to call + * \return 0 if stopped early, 1 if all data items were traversed. */ int HAMT_traverse(HAMT *hamt, /*@null@*/ void *d, int (*func) (/*@dependent@*/ /*@null@*/ void *node, diff --git a/libyasm/linemgr.h b/libyasm/linemgr.h index c38e60c3..9337e5e7 100644 --- a/libyasm/linemgr.h +++ b/libyasm/linemgr.h @@ -1,6 +1,12 @@ -/* $IdPath$ - * YASM virtual line mapping management functions +/** + * \file libyasm/linemgr.h + * \brief YASM virtual line mapping management interface. * + * \rcs + * $IdPath$ + * \endrcs + * + * \license * Copyright (C) 2002 Peter Johnson * * Redistribution and use in source and binary forms, with or without @@ -23,23 +29,31 @@ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. + * \endlicense */ #ifndef YASM_LINEMGR_H #define YASM_LINEMGR_H -/* Create a new line mapping repository. */ +/** Create a new line mapping repository. + * \return New repository. + */ yasm_linemap *yasm_linemap_create(void); -/* Cleans up any memory allocated. */ +/** Clean up any memory allocated for a repository. + * \param linemap line mapping repository + */ void yasm_linemap_destroy(yasm_linemap *linemap); -/* Returns the current line index. */ +/** Get the current line position in a repository. + * \param linemap line mapping repository + * \return Current virtual line. + */ unsigned long yasm_linemap_get_current(yasm_linemap *linemap); /** Get associated data for a virtual line and data callback. - * \param linemap linemap - * \param line virtual line - * \param callback callback used when adding data + * \param linemap line mapping repository + * \param line virtual line + * \param callback callback used when adding data * \return Associated data (NULL if none). */ /*@dependent@*/ /*@null@*/ void *yasm_linemap_get_data @@ -49,7 +63,7 @@ unsigned long yasm_linemap_get_current(yasm_linemap *linemap); /** Add associated data to the current virtual line. * \attention Deletes any existing associated data for that data callback for * the current virtual line. - * \param linemap linemap + * \param linemap line mapping repository * \param callback callback * \param data data to associate * \param every_hint non-zero if data is likely to be associated with every @@ -59,19 +73,29 @@ void yasm_linemap_add_data(yasm_linemap *linemap, const yasm_assoc_data_callback *callback, /*@only@*/ /*@null@*/ void *data, int every_hint); -/* Goes to the next line (increments the current virtual line), returns - * the current (new) virtual line. +/** Go to the next line (increments the current virtual line)l + * \param linemap line mapping repository + * \return The current (new) virtual line. */ unsigned long yasm_linemap_goto_next(yasm_linemap *linemap); -/* Sets a new file/line physical association starting point at the current +/** Set a new file/line physical association starting point at the current * virtual line. line_inc indicates how much the "real" line is incremented * by for each virtual line increment (0 is perfectly legal). + * \param linemap line mapping repository + * \param filename physical file name + * \param file_line physical line number + * \param line_inc line increment */ void yasm_linemap_set(yasm_linemap *linemap, const char *filename, unsigned long file_line, unsigned long line_inc); -/* Look up the associated physical file and line for a virtual line. */ +/** Look up the associated physical file and line for a virtual line. + * \param linemap line mapping repository + * \param line virtual line + * \param filename physical file name (output) + * \param file_line physical line number (output) + */ void yasm_linemap_lookup(yasm_linemap *linemap, unsigned long line, /*@out@*/ const char **filename, /*@out@*/ unsigned long *file_line); diff --git a/libyasm/objfmt.c b/libyasm/objfmt.c index f841ace7..813977ba 100644 --- a/libyasm/objfmt.c +++ b/libyasm/objfmt.c @@ -38,14 +38,16 @@ yasm_section * yasm_objfmt_add_default_section(yasm_objfmt *objfmt, yasm_object *object) { + yasm_objfmt_base *of_base = (yasm_objfmt_base *)objfmt; yasm_section *retval; yasm_valparamhead vps; yasm_valparam *vp; - vp = yasm_vp_create(yasm__xstrdup(objfmt->default_section_name), NULL); + vp = yasm_vp_create(yasm__xstrdup(of_base->module->default_section_name), + NULL); yasm_vps_initialize(&vps); yasm_vps_append(&vps, vp); - retval = objfmt->section_switch(object, &vps, NULL, 0); + retval = yasm_objfmt_section_switch(objfmt, &vps, NULL, 0); yasm_vps_delete(&vps); return retval; diff --git a/libyasm/objfmt.h b/libyasm/objfmt.h index 9506185b..a7432c90 100644 --- a/libyasm/objfmt.h +++ b/libyasm/objfmt.h @@ -34,19 +34,29 @@ #ifndef YASM_OBJFMT_H #define YASM_OBJFMT_H -/** Version number of #yasm_objfmt interface. Any functional change to the - * #yasm_objfmt interface should simultaneously increment this number. This - * version should be checked by #yasm_objfmt loaders to verify that the - * expected version (the version defined by its libyasm header files) matches - * the loaded module version (the version defined by the module's libyasm - * header files). Doing this will ensure that the module version's function - * definitions match the module loader's function definitions. The version - * number must never be decreased. +#ifndef YASM_DOXYGEN +/** Base #yasm_objfmt structure. Must be present as the first element in any + * #yasm_objfmt implementation. + */ +typedef struct yasm_objfmt_base { + /** #yasm_objfmt_module implementation for this object format. */ + const struct yasm_objfmt_module *module; +} yasm_objfmt_base; +#endif + +/** Version number of #yasm_objfmt_module interface. Any functional change to + * the #yasm_objfmt_module interface should simultaneously increment this + * number. This version should be checked by #yasm_objfmt loaders to verify + * that the expected version (the version defined by its libyasm header files) + * matches the loaded module version (the version defined by the module's + * libyasm header files). Doing this will ensure that the module version's + * function definitions match the module loader's function definitions. The + * version number must never be decreased. */ #define YASM_OBJFMT_VERSION 1 -/** YASM object format interface. */ -struct yasm_objfmt { +/** YASM object format module interface. */ +typedef struct yasm_objfmt_module { /** Version (see #YASM_OBJFMT_VERSION). Should always be set to * #YASM_OBJFMT_VERSION by the module source and checked against * #YASM_OBJFMT_VERSION by the module loader. @@ -84,98 +94,189 @@ struct yasm_objfmt { */ const char *default_dbgfmt_keyword; - /** Initialize object output for use. Must be called before any other - * object format functions. Should /not/ open the object file; the - * filenames are provided solely for informational purposes. + /** Create object format. + * Module-level implementation of yasm_objfmt_create(). + * Call yasm_objfmt_create() instead of calling this function. * \param in_filename main input filename (e.g. "file.asm") - * \param obj_filename object filename (e.g. "file.o") - * \param df debug format in use + * \param object object * \param a architecture in use - * \return Nonzero if architecture/machine combination not supported. + * \return NULL if architecture/machine combination not supported. */ - int (*initialize) (const char *in_filename, const char *obj_filename, - yasm_object *object, yasm_dbgfmt *df, yasm_arch *a); - - /** Write out (post-optimized) sections to the object file. - * This function may call yasm_symrec_* functions as necessary (including - * yasm_symrec_traverse()) to retrieve symbolic information. - * \param f output object file - * \param object object - * \param all_syms if nonzero, all symbols should be included in the - * object file - * \note The list of sections may include sections that will not actually - * be output into the object file. + /*@null@*/ /*@only@*/ yasm_objfmt * (*create) + (const char *in_filename, yasm_object *object, yasm_arch *a); + + /** Module-level implementation of yasm_objfmt_output(). + * Call yasm_objfmt_output() instead of calling this function. */ - void (*output) (FILE *f, yasm_object *object, int all_syms); + void (*output) (yasm_objfmt *of, FILE *f, const char *obj_filename, + int all_syms, yasm_dbgfmt *df); - /** Cleans up anything allocated by initialize(). Function may be - * unimplemented (NULL) if not needed by the object format. + /** Module-level implementation of yasm_objfmt_destroy(). + * Call yasm_objfmt_destroy() instead of calling this function. */ - void (*cleanup) (void); + void (*destroy) (/*@only@*/ yasm_objfmt *objfmt); - /** Switch object file sections. The first val of the valparams should - * be the section name. Calls yasm_object_get_general() to actually get - * the section. - * \param object object - * \param valparams value/parameters - * \param objext_valparams object format-specific value/parameters - * \param line virtual line (from yasm_linemap) - * \return NULL on error, otherwise new section. + /** Module-level implementation of yasm_objfmt_section_switch(). + * Call yasm_objfmt_section_switch() instead of calling this function. */ /*@observer@*/ /*@null@*/ yasm_section * - (*section_switch)(yasm_object *object, yasm_valparamhead *valparams, + (*section_switch)(yasm_objfmt *objfmt, yasm_valparamhead *valparams, /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line); - /** Declare an "extern" (importing from another module) symbol. Should - * call yasm_symrec_set_of_data() to store data. Function may be - * unimplemented (NULL) if object format doesn't care about such a - * declaration. - * \param sym symbol - * \param objext_valparams object format-specific value/paramaters - * \param line virtual line (from yasm_linemap) + /** Module-level implementation of yasm_objfmt_extern_declare(). + * Call yasm_objfmt_extern_declare() instead of calling this function. */ - void (*extern_declare)(yasm_symrec *sym, - /*@null@*/ yasm_valparamhead *objext_valparams, - unsigned long line); - - /** Declare a "global" (exporting to other modules) symbol. Should call - * yasm_symrec_set_of_data() to store data. Function may be unimplemented - * (NULL) if object format doesn't care about such a declaration. - * \param sym symbol - * \param objext_valparams object format-specific value/paramaters - * \param line virtual line (from yasm_linemap) + yasm_symrec * (*extern_declare) + (yasm_objfmt *objfmt, const char *name, + /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line); + + /** Module-level implementation of yasm_objfmt_global_declare(). + * Call yasm_objfmt_global_declare() instead of calling this function. */ - void (*global_declare)(yasm_symrec *sym, - /*@null@*/ yasm_valparamhead *objext_valparams, - unsigned long line); - - /** Declare a "common" (shared space with other modules) symbol. Should - * call yasm_symrec_set_of_data() to store data. Function may be - * unimplemented (NULL) if object format doesn't care about such a - * declaration. - * \param sym symbol - * \param size common data size - * \param objext_valparams object format-specific value/paramaters - * \param line virtual line (from yasm_linemap) + yasm_symrec * (*global_declare) + (yasm_objfmt *objfmt, const char *name, + /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line); + + /** Module-level implementation of yasm_objfmt_common_declare(). + * Call yasm_objfmt_common_declare() instead of calling this function. */ - void (*common_declare)(yasm_symrec *sym, /*@only@*/ yasm_expr *size, - /*@null@*/ yasm_valparamhead *objext_valparams, - unsigned long line); - - /** Handle object format-specific directives. - * \param name directive name - * \param valparams value/parameters - * \param objext_valparams object format-specific value/parameters - * \param object object - * \param line virtual line (from yasm_linemap) - * \return Nonzero if directive was not recognized; 0 if directive was - * recognized, even if it wasn't valid. + yasm_symrec * (*common_declare) + (yasm_objfmt *objfmt, const char *name, /*@only@*/ yasm_expr *size, + /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line); + + /** Module-level implementation of yasm_objfmt_directive(). + * Call yasm_objfmt_directive() instead of calling this function. */ - int (*directive)(const char *name, yasm_valparamhead *valparams, - /*@null@*/ yasm_valparamhead *objext_valparams, - yasm_object *object, unsigned long line); -}; + int (*directive) (yasm_objfmt *objfmt, const char *name, + yasm_valparamhead *valparams, + /*@null@*/ yasm_valparamhead *objext_valparams, + unsigned long line); +} yasm_objfmt_module; + +/** Create object format. + * \param module object format module + * \param in_filename main input filename (e.g. "file.asm") + * \param object object + * \param a architecture in use + * \return NULL if architecture/machine combination not supported. + */ +/*@null@*/ /*@only@*/ yasm_objfmt *yasm_objfmt_create + (const yasm_objfmt_module *module, const char *in_filename, + yasm_object *object, yasm_arch *a); + +/** Write out (post-optimized) sections to the object file. + * This function may call yasm_symrec_* functions as necessary (including + * yasm_symrec_traverse()) to retrieve symbolic information. + * \param objfmt object format + * \param f output object file + * \param obj_filename output filename (e.g. "file.o") + * \param all_syms if nonzero, all symbols should be included in + * the object file + * \param df debug format in use + */ +void yasm_objfmt_output(yasm_objfmt *objfmt, FILE *f, const char *obj_filename, + int all_syms, yasm_dbgfmt *df); + +/** Cleans up any allocated object format memory. + * \param objfmt object format + */ +void yasm_objfmt_destroy(/*@only@*/ yasm_objfmt *objfmt); + +/** Switch object file sections. The first val of the valparams should + * be the section name. Calls yasm_object_get_general() to actually get + * the section. + * \param objfmt object format + * \param valparams value/parameters + * \param objext_valparams object format-specific value/parameters + * \param line virtual line (from yasm_linemap) + * \return NULL on error, otherwise new section. + */ +/*@observer@*/ /*@null@*/ yasm_section *yasm_objfmt_section_switch + (yasm_objfmt *objfmt, yasm_valparamhead *valparams, + /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line); + +/** Declare an "extern" (importing from another module) symbol. Should + * call yasm_symtab_declare(). + * \param objfmt object format + * \param name symbol name + * \param objext_valparams object format-specific value/paramaters + * \param line virtual line (from yasm_linemap) + * \return Declared symbol. + */ +yasm_symrec *yasm_objfmt_extern_declare + (yasm_objfmt *objfmt, const char *name, + /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line); + +/** Declare a "global" (exporting to other modules) symbol. Should call + * yasm_symtab_declare(). + * \param objfmt object format + * \param name symbol name + * \param objext_valparams object format-specific value/paramaters + * \param line virtual line (from yasm_linemap) + * \return Declared symbol. + */ +yasm_symrec *yasm_objfmt_global_declare + (yasm_objfmt *objfmt, const char *name, + /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line); + +/** Declare a "common" (shared space with other modules) symbol. Should + * call yasm_symtab_declare(). + * declaration. + * \param objfmt object format + * \param name symbol name + * \param size common data size + * \param objext_valparams object format-specific value/paramaters + * \param line virtual line (from yasm_linemap) + * \return Declared symbol. + */ +yasm_symrec *yasm_objfmt_common_declare + (yasm_objfmt *objfmt, const char *name, /*@only@*/ yasm_expr *size, + /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line); + +/** Handle object format-specific directives. + * \param objfmt object format + * \param name directive name + * \param valparams value/parameters + * \param objext_valparams object format-specific value/parameters + * \param line virtual line (from yasm_linemap) + * \return Nonzero if directive was not recognized; 0 if directive was + * recognized, even if it wasn't valid. + */ +int yasm_objfmt_directive(yasm_objfmt *objfmt, const char *name, + yasm_valparamhead *valparams, + /*@null@*/ yasm_valparamhead *objext_valparams, + unsigned long line); + +#ifndef YASM_DOXYGEN + +/* Inline macro implementations for objfmt functions */ + +#define yasm_objfmt_create(module, in_filename, object, a) \ + module->create(in_filename, object, a) + +#define yasm_objfmt_output(objfmt, f, obj_fn, all_syms, df) \ + ((yasm_objfmt_base *)objfmt)->module->output(objfmt, f, obj_fn, all_syms, \ + df) +#define yasm_objfmt_destroy(objfmt) \ + ((yasm_objfmt_base *)objfmt)->module->destroy(objfmt) +#define yasm_objfmt_section_switch(objfmt, vpms, oe_vpms, line) \ + ((yasm_objfmt_base *)objfmt)->module->section_switch(objfmt, vpms, \ + oe_vpms, line) +#define yasm_objfmt_extern_declare(objfmt, name, oe_vpms, line) \ + ((yasm_objfmt_base *)objfmt)->module->extern_declare(objfmt, name, \ + oe_vpms, line) +#define yasm_objfmt_global_declare(objfmt, name, oe_vpms, line) \ + ((yasm_objfmt_base *)objfmt)->module->global_declare(objfmt, name, \ + oe_vpms, line) +#define yasm_objfmt_common_declare(objfmt, name, size, oe_vpms, line) \ + ((yasm_objfmt_base *)objfmt)->module->common_declare(objfmt, name, size, \ + oe_vpms, line) +#define yasm_objfmt_directive(objfmt, name, vpms, oe_vpms, line) \ + ((yasm_objfmt_base *)objfmt)->module->directive(objfmt, name, vpms, \ + oe_vpms, line) + +#endif /** Add a default section to an object. * \param objfmt object format diff --git a/libyasm/optimizer.h b/libyasm/optimizer.h index 86ab3c0e..2359dcc6 100644 --- a/libyasm/optimizer.h +++ b/libyasm/optimizer.h @@ -1,6 +1,12 @@ -/* $IdPath$ - * YASM optimizer module interface header file +/** + * \file libyasm/optimizer.h + * \brief YASM optimizer module interface. * + * \rcs + * $IdPath$ + * \endrcs + * + * \license * Copyright (C) 2001 Peter Johnson * * Redistribution and use in source and binary forms, with or without @@ -23,43 +29,43 @@ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. + * \endlicense */ #ifndef YASM_OPTIMIZER_H #define YASM_OPTIMIZER_H -/** Version number of #yasm_optimizer interface. Any functional change to the - * #yasm_optimizer interface should simultaneously increment this number. This - * version should be checked by #yasm_optimizer loaders to verify that the - * expected version (the version defined by its libyasm header files) matches - * the loaded module version (the version defined by the module's libyasm - * header files). Doing this will ensure that the module version's function - * definitions match the module loader's function definitions. The version - * number must never be decreased. +/** Version number of #yasm_optimizer_module interface. Any functional change + * to the #yasm_optimizer_module interface should simultaneously increment this + * number. This version should be checked by #yasm_optimizer loaders to verify + * that the expected version (the version defined by its libyasm header files) + * matches the loaded module version (the version defined by the module's + * libyasm header files). Doing this will ensure that the module version's + * function definitions match the module loader's function definitions. The + * version number must never be decreased. */ #define YASM_OPTIMIZER_VERSION 1 -/* Interface to the optimizer module(s) */ -struct yasm_optimizer { +/** YASM optimizer module interface. */ +typedef struct yasm_optimizer_module { /** Version (see #YASM_OPTIMIZER_VERSION). Should always be set to * #YASM_OPTIMIZER_VERSION by the module source and checked against * #YASM_OPTIMIZER_VERSION by the module loader. */ unsigned int version; - /* one-line description of the optimizer */ + /** One-line description of the optimizer */ const char *name; - /* keyword used to select optimizer on the command line */ + /** Keyword used to select optimizer on the command line */ const char *keyword; - /* Main entrance point for the optimizer. - * - * This function takes the unoptimized linked list of sections and - * optimizes it. If successful, the sections are ready for output to an - * object file. (A failure is indicated by calling ErrorAt() from within - * this function). + /** Optimize an object. Takes the unoptimized object and optimizes it. + * If successful, the object is ready for output to an object file. + * \param object object + * \note Optimization failures are indicated by this function calling + * yasm__error_at(); see errwarn.h for details. */ void (*optimize) (yasm_object *object); -}; +} yasm_optimizer_module; #endif diff --git a/libyasm/parser.h b/libyasm/parser.h index 1137a56e..22572dde 100644 --- a/libyasm/parser.h +++ b/libyasm/parser.h @@ -1,6 +1,12 @@ -/* $IdPath$ - * Parser module interface header file +/** + * \file libyasm/parser.h + * \brief YASM parser module interface. * + * \rcs + * $IdPath$ + * \endrcs + * + * \license * Copyright (C) 2001 Peter Johnson * * Redistribution and use in source and binary forms, with or without @@ -23,6 +29,7 @@ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. + * \endlicense */ #ifndef YASM_PARSER_H #define YASM_PARSER_H @@ -38,7 +45,7 @@ */ #define YASM_PARSER_VERSION 1 -/* Interface to the parser module(s) -- the "front end" of the assembler */ +/** YASM parser module interface. The "front end" of the assembler. */ typedef struct yasm_parser_module { /** Version (see #YASM_PARSER_VERSION). Should always be set to * #YASM_PARSER_VERSION by the module source and checked against @@ -46,34 +53,40 @@ typedef struct yasm_parser_module { */ unsigned int version; - /* one-line description of the parser */ + /** One-line description of the parser */ const char *name; - /* keyword used to select parser on the command line */ + /** Keyword used to select parser on the command line */ const char *keyword; - /* NULL-terminated list of preprocessors that are valid to use with this + /** NULL-terminated list of preprocessors that are valid to use with this * parser. The raw preprocessor (raw_preproc) should always be in this * list so it's always possible to have no preprocessing done. */ const char **preproc_keywords; - /* Default preprocessor. */ + /** Default preprocessor. */ const char *default_preproc_keyword; - /* Main entrance point for the parser. - * - * The parser needs access to both the object format module (for format- - * specific directives and segment names), and the preprocessor. - * - * This function also takes the FILE * to the initial starting file and - * the input filename. - * - * save_input is nonzero if the parser needs to save the original lines of - * source in the input file into the linemap via yasm_linemap_add_data(). + /** Parse a source file into an object. + * \param object object to parse into (already created) + * \param pp preprocessor + * \param a architecture; architecture-specific directives are + * obtained from this. + * \param of object format; objfmt-specific directives and segment + * names are obtained from this. + * \param f initial starting file + * \param in_filename initial starting file's filename + * \param save_input nonzero if the parser should save the original + * lines of source into the object's linemap (via + * yasm_linemap_add_data()). + * \param def_sect default (starting) section in the object + * \note Parse failures are indicated by this function calling + * yasm__error(); see errwarn.h for details. */ void (*do_parse) (yasm_object *object, yasm_preproc *pp, yasm_arch *a, yasm_objfmt *of, FILE *f, const char *in_filename, int save_input, yasm_section *def_sect); } yasm_parser_module; + #endif diff --git a/libyasm/preproc.h b/libyasm/preproc.h index fd43d364..4bce005a 100644 --- a/libyasm/preproc.h +++ b/libyasm/preproc.h @@ -1,6 +1,12 @@ -/* $IdPath$ - * YASM preprocessor module interface header file +/** + * \file libyasm/preproc.h + * \brief YASM preprocessor module interface. * + * \rcs + * $IdPath$ + * \endrcs + * + * \license * Copyright (C) 2001 Peter Johnson * * Redistribution and use in source and binary forms, with or without @@ -23,63 +29,168 @@ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. + * \endlicense */ #ifndef YASM_PREPROC_H #define YASM_PREPROC_H -/** Version number of #yasm_preproc interface. Any functional change to the - * #yasm_preproc interface should simultaneously increment this number. This - * version should be checked by #yasm_preproc loaders to verify that the - * expected version (the version defined by its libyasm header files) matches - * the loaded module version (the version defined by the module's libyasm - * header files). Doing this will ensure that the module version's function - * definitions match the module loader's function definitions. The version - * number must never be decreased. +#ifndef YASM_DOXYGEN +/** Base #yasm_preproc structure. Must be present as the first element in any + * #yasm_preproc implementation. + */ +typedef struct yasm_preproc_base { + /** #yasm_preproc_module implementation for this preprocessor. */ + const struct yasm_preproc_module *module; +} yasm_preproc_base; +#endif + +/** Version number of #yasm_preproc_module interface. Any functional change to + * the #yasm_preproc_module interface should simultaneously increment this + * number. This version should be checked by #yasm_preproc loaders to verify + * that the expected version (the version defined by its libyasm header files) + * matches the loaded module version (the version defined by the module's + * libyasm header files). Doing this will ensure that the module version's + * function definitions match the module loader's function definitions. The + * version number must never be decreased. */ #define YASM_PREPROC_VERSION 2 -/* Interface to the preprocesor module(s) */ -struct yasm_preproc { +/** YASM preprocesor module interface. */ +typedef struct yasm_preproc_module { /** Version (see #YASM_PREPROC_VERSION). Should always be set to * #YASM_PREPROC_VERSION by the module source and checked against * #YASM_PREPROC_VERSION by the module loader. */ unsigned int version; - /* one-line description of the preprocessor */ + /** One-line description of the preprocessor. */ const char *name; - /* keyword used to select preprocessor on the command line */ + /** Keyword used to select preprocessor on the command line. */ const char *keyword; - /* Initializes preprocessor. + /** Create preprocessor. + * Module-level implementation of yasm_preproc_create(). + * Call yasm_preproc_create() instead of calling this function. * * The preprocessor needs access to the object format module to find out * any output format specific macros. * - * This function also takes the FILE * to the initial starting file and - * the filename. + * \param f initial starting file + * \param in_filename initial starting filename + * \param lm line mapping repository + * \return New preprocessor. + */ + /*@only@*/ yasm_preproc * (*create) (FILE *f, const char *in_filename, + yasm_linemap *lm); + + /** Module-level implementation of yasm_preproc_destroy(). + * Call yasm_preproc_destroy() instead of calling this function. + */ + void (*destroy) (/*@only@*/ yasm_preproc *preproc); + + /** Module-level implementation of yasm_preproc_input(). + * Call yasm_preproc_input() instead of calling this function. + */ + size_t (*input) (yasm_preproc *preproc, /*@out@*/ char *buf, + size_t max_size); + + /** Module-level implementation of yasm_preproc_add_include_path(). + * Call yasm_preproc_add_include_path() instead of calling this function. + */ + void (*add_include_path) (yasm_preproc *preproc, const char *path); + + /** Module-level implementation of yasm_preproc_add_include_file(). + * Call yasm_preproc_add_include_file() instead of calling this function. + */ + void (*add_include_file) (yasm_preproc *preproc, const char *filename); + + /** Module-level implementation of yasm_preproc_predefine_macro(). + * Call yasm_preproc_predefine_macro() instead of calling this function. + */ + void (*predefine_macro) (yasm_preproc *preproc, const char *macronameval); + + /** Module-level implementation of yasm_preproc_undefine_macro(). + * Call yasm_preproc_undefine_macro() instead of calling this function. */ - void (*initialize) (FILE *f, const char *in_filename, yasm_linemap *lm); + void (*undefine_macro) (yasm_preproc *preproc, const char *macroname); +} yasm_preproc_module; + +/** Initialize preprocessor. + * The preprocessor needs access to the object format module to find out + * any output format specific macros. + * \param module preprocessor module + * \param f initial starting file + * \param in_filename initial starting file filename + * \param lm line mapping repository + * \return New preprocessor. + */ +/*@only@*/ yasm_preproc *yasm_preproc_create + (yasm_preproc_module *module, FILE *f, const char *in_filename, + yasm_linemap *lm); - /* Cleans up any allocated memory. */ - void (*cleanup) (void); +/** Cleans up any allocated preproc memory. + * \param preproc preprocessor + */ +void yasm_preproc_destroy(/*@only@*/ yasm_preproc *preproc); - /* Gets more preprocessed source code (up to max_size bytes) into buf. - * Note that more than a single line may be returned in buf. */ - size_t (*input) (/*@out@*/ char *buf, size_t max_size); +/** Gets more preprocessed source code (up to max_size bytes) into buf. + * More than a single line may be returned in buf. + * \param preproc preprocessor + * \param buf destination buffer for preprocessed source + * \param max_size maximum number of bytes that can be returned in buf + * \return Actual number of bytes returned in buf. + */ +size_t yasm_preproc_input(yasm_preproc *preproc, /*@out@*/ char *buf, + size_t max_size); - /* Add a directory to the %include search path */ - void (*add_include_path) (const char *path); +/** Add a directory to the include search path. + * \param preproc preprocessor + * \param path pathname + */ +void yasm_preproc_add_include_path(yasm_preproc *preproc, const char *path); - /* Pre-include a file */ - void (*add_include_file) (const char *filename); +/** Pre-include a file. + * \param preproc preprocessor + * \param filename filename + */ +void yasm_preproc_add_include_file(yasm_preproc *preproc, + const char *filename); - /* Pre-define a macro */ - void (*predefine_macro) (const char *macronameval); +/** Pre-define a macro. + * \param preproc preprocessor + * \param macronameval "name=value" string + */ +void yasm_preproc_predefine_macro(yasm_preproc *preproc, + const char *macronameval); - /* Un-define a macro */ - void (*undefine_macro) (const char *macroname); -}; +/** Un-define a macro. + * \param preproc preprocessor + * \param macroname macro name + */ +void yasm_preproc_undefine_macro(yasm_preproc *preproc, const char *macroname); + +#ifndef YASM_DOXYGEN + +/* Inline macro implementations for preproc functions */ + +#define yasm_preproc_create(module, f, in_filename, lm) \ + module->create(f, in_filename, lm) + +#define yasm_preproc_destroy(preproc) \ + ((yasm_preproc_base *)preproc)->module->destroy(preproc) +#define yasm_preproc_input(preproc, buf, max_size) \ + ((yasm_preproc_base *)preproc)->module->input(preproc, buf, max_size) +#define yasm_preproc_add_include_path(preproc, path) \ + ((yasm_preproc_base *)preproc)->module->add_include_path(preproc, path) +#define yasm_preproc_add_include_file(preproc, filename) \ + ((yasm_preproc_base *)preproc)->module->add_include_file(preproc, filename) +#define yasm_preproc_predefine_macro(preproc, macronameval) \ + ((yasm_preproc_base *)preproc)->module->predefine_macro(preproc, \ + macronameval) +#define yasm_preproc_undefine_macro(preproc, macroname) \ + ((yasm_preproc_base *)preproc)->module->undefine_macro(preproc, macroname) + +#endif #endif diff --git a/modules/dbgfmts/null/null-dbgfmt.c b/modules/dbgfmts/null/null-dbgfmt.c index ec2ff48b..a3fc0ea1 100644 --- a/modules/dbgfmts/null/null-dbgfmt.c +++ b/modules/dbgfmts/null/null-dbgfmt.c @@ -31,13 +31,44 @@ #include +yasm_dbgfmt_module yasm_null_LTX_dbgfmt; + + +static /*@null@*/ /*@only@*/ yasm_dbgfmt * +null_dbgfmt_create(const char *in_filename, const char *obj_filename, + yasm_object *object, yasm_objfmt *of, yasm_arch *a) +{ + yasm_dbgfmt_base *dbgfmt = yasm_xmalloc(sizeof(yasm_dbgfmt_base)); + dbgfmt->module = &yasm_null_LTX_dbgfmt; + return (yasm_dbgfmt *)dbgfmt; +} + +static void +null_dbgfmt_destroy(/*@only@*/ yasm_dbgfmt *dbgfmt) +{ + yasm_xfree(dbgfmt); +} + +static int +null_dbgfmt_directive(yasm_dbgfmt *dbgfmt, const char *name, + yasm_valparamhead *valparams, unsigned long line) +{ + return 1; +} + +static void +null_dbgfmt_generate(yasm_dbgfmt *dbgfmt) +{ +} + + /* Define dbgfmt structure -- see dbgfmt.h for details */ -yasm_dbgfmt yasm_null_LTX_dbgfmt = { +yasm_dbgfmt_module yasm_null_LTX_dbgfmt = { YASM_DBGFMT_VERSION, "No debugging info", "null", - NULL, /*null_dbgfmt_initialize*/ - NULL, /*null_dbgfmt_cleanup*/ - NULL, /*null_dbgfmt_directive*/ - NULL /*null_dbgfmt_generate*/ + null_dbgfmt_create, + null_dbgfmt_destroy, + null_dbgfmt_directive, + null_dbgfmt_generate }; diff --git a/modules/dbgfmts/stabs/stabs-dbgfmt.c b/modules/dbgfmts/stabs/stabs-dbgfmt.c index dd958118..25768824 100644 --- a/modules/dbgfmts/stabs/stabs-dbgfmt.c +++ b/modules/dbgfmts/stabs/stabs-dbgfmt.c @@ -80,6 +80,16 @@ typedef enum { N_NBLCS = 0xf8 /* Gould non-base registers */ } stabs_stab_type; +typedef struct yasm_dbgfmt_stabs { + yasm_dbgfmt_base dbgfmt; /* base structure */ + + yasm_object *object; + yasm_symtab *symtab; + const char *filename; + yasm_linemap *linemap; + yasm_arch *arch; +} yasm_dbgfmt_stabs; + typedef struct { unsigned long lastline; /* track line and file of bytecodes */ unsigned long curline; @@ -93,6 +103,8 @@ typedef struct { yasm_section *stabstr; yasm_symrec *firstsym; /* track leading sym of section/function */ yasm_bytecode *firstbc; /* and its bytecode */ + + yasm_dbgfmt_stabs *dbgfmt_stabs; } stabs_info; typedef struct { @@ -162,27 +174,27 @@ static const yasm_bytecode_callback stabs_bc_stab_callback = { stabs_bc_stab_tobytes }; -static yasm_symtab *symtab = NULL; -static yasm_objfmt *cur_objfmt = NULL; -static const char *filename = NULL; -static yasm_linemap *linemap = NULL; -static yasm_arch *cur_arch = NULL; +yasm_dbgfmt_module yasm_stabs_LTX_dbgfmt; -static int -stabs_dbgfmt_initialize(const char *in_filename, const char *obj_filename, - yasm_object *object, yasm_objfmt *of, yasm_arch *a) + +static /*@null@*/ /*@only@*/ yasm_dbgfmt * +stabs_dbgfmt_create(const char *in_filename, const char *obj_filename, + yasm_object *object, yasm_objfmt *of, yasm_arch *a) { - cur_objfmt = of; - filename = in_filename; - symtab = yasm_object_get_symtab(object); - linemap = yasm_object_get_linemap(object); - cur_arch = a; - return 0; + yasm_dbgfmt_stabs *dbgfmt_stabs = yasm_xmalloc(sizeof(yasm_dbgfmt_stabs)); + dbgfmt_stabs->dbgfmt.module = &yasm_stabs_LTX_dbgfmt; + dbgfmt_stabs->filename = in_filename; + dbgfmt_stabs->object = object; + dbgfmt_stabs->symtab = yasm_object_get_symtab(object); + dbgfmt_stabs->linemap = yasm_object_get_linemap(object); + dbgfmt_stabs->arch = a; + return (yasm_dbgfmt *)dbgfmt_stabs; } static void -stabs_dbgfmt_cleanup(void) +stabs_dbgfmt_destroy(/*@only@*/ yasm_dbgfmt *dbgfmt) { + yasm_xfree(dbgfmt); } /* Create and add a new strtab-style string bytecode to a section, updating @@ -267,7 +279,8 @@ stabs_dbgfmt_first_sym_traversal(yasm_symrec *sym, void *d) /* Find the first sym and its preceding bytecode in a given section */ static void -stabs_dbgfmt_first_sym_by_sect(stabs_info *info, yasm_section *sect) +stabs_dbgfmt_first_sym_by_sect(yasm_dbgfmt_stabs *dbgfmt_stabs, + stabs_info *info, yasm_section *sect) { stabs_symsect symsect = { NULL, NULL, NULL }; if (sect == NULL) { @@ -276,7 +289,7 @@ stabs_dbgfmt_first_sym_by_sect(stabs_info *info, yasm_section *sect) } symsect.sect = sect; - yasm_symtab_traverse(symtab, (void *)&symsect, + yasm_symtab_traverse(dbgfmt_stabs->symtab, (void *)&symsect, stabs_dbgfmt_first_sym_traversal); info->firstsym = symsect.sym; info->firstbc = symsect.precbc; @@ -286,7 +299,8 @@ static int stabs_dbgfmt_generate_bcs(yasm_bytecode *bc, void *d) { stabs_info *info = (stabs_info *)d; - yasm_linemap_lookup(linemap, bc->line, &info->curfile, &info->curline); + yasm_linemap_lookup(info->dbgfmt_stabs->linemap, bc->line, &info->curfile, + &info->curline); if (info->lastfile != info->curfile) { info->lastline = 0; /* new file, so line changes */ @@ -313,7 +327,7 @@ stabs_dbgfmt_generate_sections(yasm_section *sect, /*@null@*/ void *d) stabs_info *info = (stabs_info *)d; const char *sectname=yasm_section_get_name(sect); - stabs_dbgfmt_first_sym_by_sect(info, sect); + stabs_dbgfmt_first_sym_by_sect(info->dbgfmt_stabs, info, sect); if (yasm__strcasecmp(sectname, ".text")==0) { char *str; const char *symname=yasm_symrec_get_name(info->firstsym); @@ -331,8 +345,9 @@ stabs_dbgfmt_generate_sections(yasm_section *sect, /*@null@*/ void *d) } static void -stabs_dbgfmt_generate(yasm_object *object) +stabs_dbgfmt_generate(yasm_dbgfmt *dbgfmt) { + yasm_dbgfmt_stabs *dbgfmt_stabs = (yasm_dbgfmt_stabs *)dbgfmt; stabs_info info; int new; yasm_bytecode *dbgbc; @@ -342,15 +357,17 @@ stabs_dbgfmt_generate(yasm_object *object) yasm_section *stext; /* Stablen is determined by arch/machine */ - if (yasm__strcasecmp(yasm_arch_keyword(cur_arch), "x86") == 0) { + if (yasm__strcasecmp(yasm_arch_keyword(dbgfmt_stabs->arch), "x86") == 0) { info.stablen = 12; } else /* unknown machine; generate nothing */ return; + info.dbgfmt_stabs = dbgfmt_stabs; info.lastline = 0; info.stabcount = 0; - info.stab = yasm_object_get_general(object, ".stab", 0, 0, &new, 0); + info.stab = yasm_object_get_general(dbgfmt_stabs->object, ".stab", 0, 0, + &new, 0); if (!new) { yasm_bytecode *last = yasm_section_bcs_last(info.stab); if (last == NULL) @@ -361,7 +378,8 @@ stabs_dbgfmt_generate(yasm_object *object) N_("stabs debugging overrides empty section .stab")); } - info.stabstr = yasm_object_get_general(object, ".stabstr", 0, 0, &new, 0); + info.stabstr = yasm_object_get_general(dbgfmt_stabs->object, ".stabstr", 0, + 0, &new, 0); if (!new) { yasm_bytecode *last = yasm_section_bcs_last(info.stabstr); if (last == NULL) @@ -387,16 +405,16 @@ stabs_dbgfmt_generate(yasm_object *object) /* initial strtab bytecodes */ nullbc = stabs_dbgfmt_append_bcstr(info.stabstr, ""); - filebc = stabs_dbgfmt_append_bcstr(info.stabstr, filename); + filebc = stabs_dbgfmt_append_bcstr(info.stabstr, dbgfmt_stabs->filename); - stext = yasm_object_find_general(object, ".text"); - info.firstsym = yasm_symtab_use(yasm_object_get_symtab(object), ".text", 0); + stext = yasm_object_find_general(dbgfmt_stabs->object, ".text"); + info.firstsym = yasm_symtab_use(dbgfmt_stabs->symtab, ".text", 0); info.firstbc = yasm_section_bcs_first(stext); /* N_SO file stab */ stabs_dbgfmt_append_stab(&info, info.stab, filebc, N_SO, 0, info.firstsym, info.firstbc, 0); - yasm_object_sections_traverse(object, (void *)&info, + yasm_object_sections_traverse(dbgfmt_stabs->object, (void *)&info, stabs_dbgfmt_generate_sections); /* fill initial pseudo-stab's fields */ @@ -514,13 +532,20 @@ stabs_bc_str_resolve(yasm_bytecode *bc, int save, return YASM_BC_RESOLVE_MIN_LEN; } +static int +stabs_dbgfmt_directive(yasm_dbgfmt *dbgfmt, const char *name, + yasm_valparamhead *valparams, unsigned long line) +{ + return 1; +} + /* Define dbgfmt structure -- see dbgfmt.h for details */ -yasm_dbgfmt yasm_stabs_LTX_dbgfmt = { +yasm_dbgfmt_module yasm_stabs_LTX_dbgfmt = { YASM_DBGFMT_VERSION, "Stabs debugging format", "stabs", - stabs_dbgfmt_initialize, - stabs_dbgfmt_cleanup, - NULL /*stabs_dbgfmt_directive*/, + stabs_dbgfmt_create, + stabs_dbgfmt_destroy, + stabs_dbgfmt_directive, stabs_dbgfmt_generate }; diff --git a/modules/objfmts/bin/bin-objfmt.c b/modules/objfmts/bin/bin-objfmt.c index cb7706e7..93028fa3 100644 --- a/modules/objfmts/bin/bin-objfmt.c +++ b/modules/objfmts/bin/bin-objfmt.c @@ -42,17 +42,28 @@ static const yasm_assoc_data_callback bin_section_data_callback = { bin_section_data_destroy, bin_section_data_print }; -static /*@dependent@*/ yasm_arch *cur_arch; +typedef struct yasm_objfmt_bin { + yasm_objfmt_base objfmt; /* base structure */ -static int -bin_objfmt_initialize(/*@unused@*/ const char *in_filename, - /*@unused@*/ const char *obj_filename, - /*@unused@*/ yasm_object *object, - /*@unused@*/ yasm_dbgfmt *df, yasm_arch *a) + yasm_object *object; + yasm_symtab *symtab; + /*@dependent@*/ yasm_arch *arch; +} yasm_objfmt_bin; + +yasm_objfmt_module yasm_bin_LTX_objfmt; + + +static yasm_objfmt * +bin_objfmt_create(/*@unused@*/ const char *in_filename, yasm_object *object, + yasm_arch *a) { - cur_arch = a; - return 0; + yasm_objfmt_bin *objfmt_bin = yasm_xmalloc(sizeof(yasm_objfmt_bin)); + objfmt_bin->objfmt.module = &yasm_bin_LTX_objfmt; + objfmt_bin->object = object; + objfmt_bin->symtab = yasm_object_get_symtab(object); + objfmt_bin->arch = a; + return (yasm_objfmt *)objfmt_bin; } /* Aligns sect to either its specified alignment (in its objfmt-specific data) @@ -100,6 +111,7 @@ bin_objfmt_align_section(yasm_section *sect, yasm_section *prevsect, } typedef struct bin_objfmt_output_info { + yasm_objfmt_bin *objfmt_bin; /*@dependent@*/ FILE *f; /*@only@*/ unsigned char *buf; /*@observer@*/ const yasm_section *sect; @@ -140,11 +152,14 @@ static int bin_objfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize, size_t valsize, int shift, /*@unused@*/ unsigned long offset, yasm_bytecode *bc, - int rel, int warn, /*@unused@*/ /*@null@*/ void *d) + int rel, int warn, /*@null@*/ void *d) { + /*@null@*/ bin_objfmt_output_info *info = (bin_objfmt_output_info *)d; /*@dependent@*/ /*@null@*/ const yasm_intnum *intn; /*@dependent@*/ /*@null@*/ const yasm_floatnum *flt; + assert(info != NULL); + /* For binary output, this is trivial: any expression that doesn't simplify * to an integer is an error (references something external). * Other object formats need to generate their relocation list from here! @@ -158,16 +173,17 @@ bin_objfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize, if (flt) { if (shift < 0) yasm_internal_error(N_("attempting to negative shift a float")); - return yasm_arch_floatnum_tobytes(cur_arch, flt, buf, destsize, - valsize, (unsigned int)shift, warn, - bc->line); + return yasm_arch_floatnum_tobytes(info->objfmt_bin->arch, flt, buf, + destsize, valsize, + (unsigned int)shift, warn, bc->line); } /* Handle integer expressions */ intn = yasm_expr_get_intnum(ep, NULL); if (intn) - return yasm_arch_intnum_tobytes(cur_arch, intn, buf, destsize, valsize, - shift, bc, rel, warn, bc->line); + return yasm_arch_intnum_tobytes(info->objfmt_bin->arch, intn, buf, + destsize, valsize, shift, bc, rel, + warn, bc->line); /* Check for complex float expressions */ if (yasm_expr__contains(*ep, YASM_EXPR_FLOAT)) { @@ -230,8 +246,10 @@ bin_objfmt_output_bytecode(yasm_bytecode *bc, /*@null@*/ void *d) } static void -bin_objfmt_output(FILE *f, yasm_object *object, /*@unused@*/ int all_syms) +bin_objfmt_output(yasm_objfmt *objfmt, FILE *f, const char *obj_filename, + /*@unused@*/ int all_syms, /*@unused@*/ yasm_dbgfmt *df) { + yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)objfmt; /*@observer@*/ /*@null@*/ yasm_section *text, *data, *bss, *prevsect; /*@null@*/ yasm_expr *startexpr; /*@dependent@*/ /*@null@*/ const yasm_intnum *startnum; @@ -241,12 +259,13 @@ bin_objfmt_output(FILE *f, yasm_object *object, /*@unused@*/ int all_syms) unsigned long i; bin_objfmt_output_info info; + info.objfmt_bin = objfmt_bin; info.f = f; info.buf = yasm_xmalloc(REGULAR_OUTBUF_SIZE); - text = yasm_object_find_general(object, ".text"); - data = yasm_object_find_general(object, ".data"); - bss = yasm_object_find_general(object, ".bss"); + text = yasm_object_find_general(objfmt_bin->object, ".text"); + data = yasm_object_find_general(objfmt_bin->object, ".data"); + bss = yasm_object_find_general(objfmt_bin->object, ".bss"); if (!text) yasm_internal_error(N_("No `.text' section in bin objfmt output")); @@ -317,16 +336,18 @@ bin_objfmt_output(FILE *f, yasm_object *object, /*@unused@*/ int all_syms) } static void -bin_objfmt_cleanup(void) +bin_objfmt_destroy(yasm_objfmt *objfmt) { + yasm_xfree(objfmt); } static /*@observer@*/ /*@null@*/ yasm_section * -bin_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams, +bin_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, /*@unused@*/ /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line) { + yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)objfmt; yasm_valparam *vp; yasm_section *retval; int isnew; @@ -392,7 +413,7 @@ bin_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams, } } - retval = yasm_object_get_general(object, sectname, + retval = yasm_object_get_general(objfmt_bin->object, sectname, yasm_expr_create_ident( yasm_expr_int(yasm_intnum_create_uint(start)), line), resonly, &isnew, line); @@ -405,8 +426,9 @@ bin_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams, data); } - yasm_symtab_define_label(yasm_object_get_symtab(object), sectname, - yasm_section_bcs_first(retval), 1, line); + yasm_symtab_define_label( + yasm_object_get_symtab(objfmt_bin->object), sectname, + yasm_section_bcs_first(retval), 1, line); } else if (have_alignval) yasm__warning(YASM_WARN_GENERAL, line, N_("alignment value ignored on section redeclaration")); @@ -422,23 +444,62 @@ bin_section_data_destroy(/*@only@*/ void *d) yasm_xfree(d); } -static void -bin_objfmt_common_declare(/*@unused@*/ yasm_symrec *sym, +static yasm_symrec * +bin_objfmt_extern_declare(yasm_objfmt *objfmt, const char *name, + /*@unused@*/ /*@null@*/ + yasm_valparamhead *objext_valparams, + unsigned long line) +{ + yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)objfmt; + yasm_symrec *sym; + + yasm__warning(YASM_WARN_GENERAL, line, + N_("binary object format does not support extern variables")); + + sym = yasm_symtab_declare(objfmt_bin->symtab, name, YASM_SYM_EXTERN, line); + return sym; +} + +static yasm_symrec * +bin_objfmt_global_declare(yasm_objfmt *objfmt, const char *name, + /*@unused@*/ /*@null@*/ + yasm_valparamhead *objext_valparams, + unsigned long line) +{ + yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)objfmt; + yasm_symrec *sym; + + yasm__warning(YASM_WARN_GENERAL, line, + N_("binary object format does not support global variables")); + + sym = yasm_symtab_declare(objfmt_bin->symtab, name, YASM_SYM_GLOBAL, line); + return sym; +} + +static yasm_symrec * +bin_objfmt_common_declare(yasm_objfmt *objfmt, const char *name, /*@only@*/ yasm_expr *size, /*@unused@*/ /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line) { + yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)objfmt; + yasm_symrec *sym; + yasm_expr_destroy(size); yasm__error(line, N_("binary object format does not support common variables")); + + sym = yasm_symtab_declare(objfmt_bin->symtab, name, YASM_SYM_COMMON, line); + return sym; } static int -bin_objfmt_directive(const char *name, yasm_valparamhead *valparams, +bin_objfmt_directive(yasm_objfmt *objfmt, const char *name, + yasm_valparamhead *valparams, /*@unused@*/ /*@null@*/ - yasm_valparamhead *objext_valparams, - yasm_object *object, unsigned long line) + yasm_valparamhead *objext_valparams, unsigned long line) { + yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)objfmt; yasm_section *sect; yasm_valparam *vp; @@ -449,7 +510,8 @@ bin_objfmt_directive(const char *name, yasm_valparamhead *valparams, vp = yasm_vps_first(valparams); if (vp->val) start = yasm_expr_create_ident(yasm_expr_sym(yasm_symtab_use( - yasm_object_get_symtab(object), vp->val, line)), line); + yasm_object_get_symtab(objfmt_bin->object), vp->val, line)), + line); else if (vp->param) { start = vp->param; vp->param = NULL; /* Don't let valparams delete it */ @@ -461,7 +523,7 @@ bin_objfmt_directive(const char *name, yasm_valparamhead *valparams, } /* ORG changes the start of the .text section */ - sect = yasm_object_find_general(object, ".text"); + sect = yasm_object_find_general(objfmt_bin->object, ".text"); if (!sect) yasm_internal_error( N_("bin objfmt: .text section does not exist before ORG is called?")); @@ -486,7 +548,7 @@ static const char *bin_objfmt_dbgfmt_keywords[] = { }; /* Define objfmt structure -- see objfmt.h for details */ -yasm_objfmt yasm_bin_LTX_objfmt = { +yasm_objfmt_module yasm_bin_LTX_objfmt = { YASM_OBJFMT_VERSION, "Flat format binary", "bin", @@ -495,12 +557,12 @@ yasm_objfmt yasm_bin_LTX_objfmt = { 16, bin_objfmt_dbgfmt_keywords, "null", - bin_objfmt_initialize, + bin_objfmt_create, bin_objfmt_output, - bin_objfmt_cleanup, + bin_objfmt_destroy, bin_objfmt_section_switch, - NULL /*bin_objfmt_extern_declare*/, - NULL /*bin_objfmt_global_declare*/, + bin_objfmt_extern_declare, + bin_objfmt_global_declare, bin_objfmt_common_declare, bin_objfmt_directive }; diff --git a/modules/objfmts/coff/coff-objfmt.c b/modules/objfmts/coff/coff-objfmt.c index 872a4abd..9963ef8e 100644 --- a/modules/objfmts/coff/coff-objfmt.c +++ b/modules/objfmts/coff/coff-objfmt.c @@ -42,7 +42,7 @@ * with VMA=0. Who's right? This is #defined as changing this setting affects * several places in the code. */ -#define COFF_SET_VMA (!win32) +#define COFF_SET_VMA (!objfmt_coff->win32) #define COFF_I386MAGIC 0x14C @@ -148,7 +148,20 @@ typedef struct coff_symtab_entry { } coff_symtab_entry; typedef STAILQ_HEAD(coff_symtab_head, coff_symtab_entry) coff_symtab_head; +typedef struct yasm_objfmt_coff { + yasm_objfmt_base objfmt; /* base structure*/ + + unsigned int parse_scnum; /* sect numbering in parser */ + coff_symtab_head coff_symtab; /* symbol table of indexed syms */ + int win32; /* nonzero for win32 output */ + + yasm_object *object; + yasm_symtab *symtab; + /*@dependent@*/ yasm_arch *arch; +} yasm_objfmt_coff; + typedef struct coff_objfmt_output_info { + yasm_objfmt_coff *objfmt_coff; /*@dependent@*/ FILE *f; /*@only@*/ unsigned char *buf; yasm_section *sect; @@ -172,17 +185,13 @@ static const yasm_assoc_data_callback coff_symrec_data_cb = { coff_symrec_data_print }; -static unsigned int coff_objfmt_parse_scnum; /* sect numbering in parser */ -static coff_symtab_head coff_symtab; /* symbol table of indexed syms */ - -static /*@dependent@*/ yasm_arch *cur_arch; - -/* Set nonzero for win32 output. */ -static int win32; +yasm_objfmt_module yasm_coff_LTX_objfmt; +yasm_objfmt_module yasm_win32_LTX_objfmt; static /*@dependent@*/ coff_symtab_entry * -coff_objfmt_symtab_append(yasm_symrec *sym, coff_symrec_sclass sclass, +coff_objfmt_symtab_append(yasm_objfmt_coff *objfmt_coff, yasm_symrec *sym, + coff_symrec_sclass sclass, /*@only@*/ /*@null@*/ yasm_expr *size, int numaux, coff_symtab_auxtype auxtype) { @@ -190,9 +199,9 @@ coff_objfmt_symtab_append(yasm_symrec *sym, coff_symrec_sclass sclass, coff_symrec_data *sym_data; coff_symtab_entry *entry; - if (STAILQ_EMPTY(&coff_symtab)) + if (STAILQ_EMPTY(&objfmt_coff->coff_symtab)) yasm_internal_error(N_("empty COFF symbol table")); - entry = STAILQ_LAST(&coff_symtab, coff_symtab_entry, link); + entry = STAILQ_LAST(&objfmt_coff->coff_symtab, coff_symtab_entry, link); sym_data_prev = yasm_symrec_get_data(entry->sym, &coff_symrec_data_cb); assert(sym_data_prev != NULL); @@ -207,7 +216,7 @@ coff_objfmt_symtab_append(yasm_symrec *sym, coff_symrec_sclass sclass, entry->sym = sym; entry->numaux = numaux; entry->auxtype = auxtype; - STAILQ_INSERT_TAIL(&coff_symtab, entry, link); + STAILQ_INSERT_TAIL(&objfmt_coff->coff_symtab, entry, link); return entry; } @@ -215,39 +224,43 @@ coff_objfmt_symtab_append(yasm_symrec *sym, coff_symrec_sclass sclass, static int coff_objfmt_append_local_sym(yasm_symrec *sym, /*@unused@*/ /*@null@*/ void *d) { + /*@null@*/ yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)d; + assert(objfmt_coff != NULL); if (!yasm_symrec_get_data(sym, &coff_symrec_data_cb)) - coff_objfmt_symtab_append(sym, COFF_SCL_STAT, NULL, 0, + coff_objfmt_symtab_append(objfmt_coff, sym, COFF_SCL_STAT, NULL, 0, COFF_SYMTAB_AUX_NONE); return 1; } -static int -coff_common_initialize(const char *in_filename, - /*@unused@*/ const char *obj_filename, - yasm_object *object, /*@unused@*/ yasm_dbgfmt *df, - yasm_arch *a) +static yasm_objfmt_coff * +coff_common_create(const char *in_filename, yasm_object *object, yasm_arch *a) { + yasm_objfmt_coff *objfmt_coff = yasm_xmalloc(sizeof(yasm_objfmt_coff)); yasm_symrec *filesym; coff_symrec_data *data; coff_symtab_entry *entry; - cur_arch = a; + objfmt_coff->object = object; + objfmt_coff->symtab = yasm_object_get_symtab(object); + objfmt_coff->arch = a; /* Only support x86 arch, x86 machine */ - if (yasm__strcasecmp(yasm_arch_keyword(cur_arch), "x86") != 0 || - yasm__strcasecmp(yasm_arch_get_machine(cur_arch), "x86") != 0) - return 1; + if (yasm__strcasecmp(yasm_arch_keyword(a), "x86") != 0 || + yasm__strcasecmp(yasm_arch_get_machine(a), "x86") != 0) { + yasm_xfree(objfmt_coff); + return NULL; + } - coff_objfmt_parse_scnum = 1; /* section numbering starts at 1 */ - STAILQ_INIT(&coff_symtab); + objfmt_coff->parse_scnum = 1; /* section numbering starts at 1 */ + STAILQ_INIT(&objfmt_coff->coff_symtab); data = yasm_xmalloc(sizeof(coff_symrec_data)); data->index = 0; data->sclass = COFF_SCL_FILE; data->size = NULL; /* FIXME: misuse of NULL bytecode here; it works, but only barely. */ - filesym = yasm_symtab_define_label(yasm_object_get_symtab(object), ".file", - NULL, 0, 0); + filesym = yasm_symtab_define_label(objfmt_coff->symtab, ".file", NULL, 0, + 0); yasm_symrec_add_data(filesym, &coff_symrec_data_cb, data); entry = yasm_xmalloc(sizeof(coff_symtab_entry)); @@ -255,25 +268,33 @@ coff_common_initialize(const char *in_filename, entry->numaux = 1; entry->auxtype = COFF_SYMTAB_AUX_FILE; entry->aux[0].fname = yasm__xstrdup(in_filename); - STAILQ_INSERT_TAIL(&coff_symtab, entry, link); + STAILQ_INSERT_TAIL(&objfmt_coff->coff_symtab, entry, link); - return 0; + return objfmt_coff; } -static int -coff_objfmt_initialize(const char *in_filename, const char *obj_filename, - yasm_object *object, yasm_dbgfmt *df, yasm_arch *a) +static yasm_objfmt * +coff_objfmt_create(const char *in_filename, yasm_object *object, yasm_arch *a) { - win32 = 0; - return coff_common_initialize(in_filename, obj_filename, object, df, a); + yasm_objfmt_coff *objfmt_coff = + coff_common_create(in_filename, object, a); + if (objfmt_coff) { + objfmt_coff->objfmt.module = &yasm_coff_LTX_objfmt; + objfmt_coff->win32 = 0; + } + return (yasm_objfmt *)objfmt_coff; } -static int -win32_objfmt_initialize(const char *in_filename, const char *obj_filename, - yasm_object *object, yasm_dbgfmt *df, yasm_arch *a) +static yasm_objfmt * +win32_objfmt_create(const char *in_filename, yasm_object *object, yasm_arch *a) { - win32 = 1; - return coff_common_initialize(in_filename, obj_filename, object, df, a); + yasm_objfmt_coff *objfmt_coff = + coff_common_create(in_filename, object, a); + if (objfmt_coff) { + objfmt_coff->objfmt.module = &yasm_win32_LTX_objfmt; + objfmt_coff->win32 = 1; + } + return (yasm_objfmt *)objfmt_coff; } static int @@ -306,6 +327,7 @@ coff_objfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize, /*@null@*/ void *d) { /*@null@*/ coff_objfmt_output_info *info = (coff_objfmt_output_info *)d; + yasm_objfmt_coff *objfmt_coff; /*@dependent@*/ /*@null@*/ const yasm_intnum *intn; /*@dependent@*/ /*@null@*/ const yasm_floatnum *flt; /*@dependent@*/ /*@null@*/ yasm_symrec *sym; @@ -313,6 +335,7 @@ coff_objfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize, /*@dependent@*/ /*@null@*/ yasm_bytecode *label_precbc; assert(info != NULL); + objfmt_coff = info->objfmt_coff; *ep = yasm_expr_simplify(*ep, yasm_common_calc_bc_dist); @@ -321,9 +344,9 @@ coff_objfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize, if (flt) { if (shift < 0) yasm_internal_error(N_("attempting to negative shift a float")); - return yasm_arch_floatnum_tobytes(cur_arch, flt, buf, destsize, - valsize, (unsigned int)shift, warn, - bc->line); + return yasm_arch_floatnum_tobytes(objfmt_coff->arch, flt, buf, + destsize, valsize, + (unsigned int)shift, warn, bc->line); } /* Handle integer expressions, with relocation if necessary */ @@ -345,7 +368,7 @@ coff_objfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize, vis = yasm_symrec_get_visibility(sym); if (vis & YASM_SYM_COMMON) { /* In standard COFF, COMMON symbols have their length added in */ - if (!win32) { + if (!objfmt_coff->win32) { /*@dependent@*/ /*@null@*/ coff_symrec_data *csymd; csymd = yasm_symrec_get_data(sym, &coff_symrec_data_cb); @@ -378,7 +401,7 @@ coff_objfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize, * For Win32 COFF, need to reference to next bytecode, so add '$' * (really $+$.len) in. */ - if (win32) + if (objfmt_coff->win32) *ep = yasm_expr_create(YASM_EXPR_ADD, yasm_expr_expr(*ep), yasm_expr_sym(yasm_symtab_define_label2("$", bc, 0, (*ep)->line)), @@ -396,8 +419,9 @@ coff_objfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize, } intn = yasm_expr_get_intnum(ep, NULL); if (intn) - return yasm_arch_intnum_tobytes(cur_arch, intn, buf, destsize, valsize, - shift, bc, rel, warn, bc->line); + return yasm_arch_intnum_tobytes(objfmt_coff->arch, intn, buf, destsize, + valsize, shift, bc, rel, warn, + bc->line); /* Check for complex float expressions */ if (yasm_expr__contains(*ep, YASM_EXPR_FLOAT)) { @@ -546,6 +570,7 @@ static int coff_objfmt_output_secthead(yasm_section *sect, /*@null@*/ void *d) { /*@null@*/ coff_objfmt_output_info *info = (coff_objfmt_output_info *)d; + yasm_objfmt_coff *objfmt_coff; /*@dependent@*/ /*@null@*/ coff_section_data *csd; unsigned char *localbuf; @@ -554,6 +579,7 @@ coff_objfmt_output_secthead(yasm_section *sect, /*@null@*/ void *d) return 0; assert(info != NULL); + objfmt_coff = info->objfmt_coff; csd = yasm_section_get_data(sect, &coff_section_data_cb); assert(csd != NULL); @@ -584,8 +610,10 @@ coff_objfmt_output_secthead(yasm_section *sect, /*@null@*/ void *d) } static void -coff_objfmt_output(FILE *f, yasm_object *object, int all_syms) +coff_objfmt_output(yasm_objfmt *objfmt, FILE *f, const char *obj_filename, + int all_syms, /*@unused@*/ yasm_dbgfmt *df) { + yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)objfmt; coff_objfmt_output_info info; unsigned char *localbuf; long pos; @@ -594,11 +622,12 @@ coff_objfmt_output(FILE *f, yasm_object *object, int all_syms) unsigned long strtab_offset = 4; coff_symtab_entry *entry; + info.objfmt_coff = objfmt_coff; info.f = f; info.buf = yasm_xmalloc(REGULAR_OUTBUF_SIZE); /* Allocate space for headers by seeking forward */ - if (fseek(f, (long)(20+40*(coff_objfmt_parse_scnum-1)), SEEK_SET) < 0) { + if (fseek(f, (long)(20+40*(objfmt_coff->parse_scnum-1)), SEEK_SET) < 0) { yasm__fatal(N_("could not seek on output file")); /*@notreached@*/ return; @@ -612,19 +641,19 @@ coff_objfmt_output(FILE *f, yasm_object *object, int all_syms) * addends in the generated code. */ info.addr = 0; - if (yasm_object_sections_traverse(object, &info, + if (yasm_object_sections_traverse(objfmt_coff->object, &info, coff_objfmt_set_section_addr)) return; } info.addr = 0; - if (yasm_object_sections_traverse(object, &info, + if (yasm_object_sections_traverse(objfmt_coff->object, &info, coff_objfmt_output_section)) return; /* Symbol table */ if (all_syms) { /* Need to put all local syms into COFF symbol table */ - yasm_symtab_traverse(yasm_object_get_symtab(object), NULL, + yasm_symtab_traverse(objfmt_coff->symtab, objfmt_coff, coff_objfmt_append_local_sym); } pos = ftell(f); @@ -634,7 +663,7 @@ coff_objfmt_output(FILE *f, yasm_object *object, int all_syms) return; } symtab_pos = (unsigned long)pos; - STAILQ_FOREACH(entry, &coff_symtab, link) { + STAILQ_FOREACH(entry, &objfmt_coff->coff_symtab, link) { const char *name = yasm_symrec_get_name(entry->sym); const yasm_expr *equ_val; const yasm_intnum *intn; @@ -768,7 +797,7 @@ coff_objfmt_output(FILE *f, yasm_object *object, int all_syms) /* String table */ yasm_fwrite_32_l(strtab_offset, f); /* first four bytes are total length */ - STAILQ_FOREACH(entry, &coff_symtab, link) { + STAILQ_FOREACH(entry, &objfmt_coff->coff_symtab, link) { const char *name = yasm_symrec_get_name(entry->sym); size_t len = strlen(name); int aux; @@ -797,7 +826,7 @@ coff_objfmt_output(FILE *f, yasm_object *object, int all_syms) localbuf = info.buf; YASM_WRITE_16_L(localbuf, COFF_I386MAGIC); /* magic number */ - YASM_WRITE_16_L(localbuf, coff_objfmt_parse_scnum-1);/* number of sects */ + YASM_WRITE_16_L(localbuf, objfmt_coff->parse_scnum-1);/* number of sects */ YASM_WRITE_32_L(localbuf, 0); /* time/date stamp */ YASM_WRITE_32_L(localbuf, symtab_pos); /* file ptr to symtab */ YASM_WRITE_32_L(localbuf, symtab_count); /* number of symtabs */ @@ -807,18 +836,20 @@ coff_objfmt_output(FILE *f, yasm_object *object, int all_syms) |(all_syms?0:COFF_F_LSYMS)); fwrite(info.buf, 20, 1, f); - yasm_object_sections_traverse(object, &info, coff_objfmt_output_secthead); + yasm_object_sections_traverse(objfmt_coff->object, &info, + coff_objfmt_output_secthead); yasm_xfree(info.buf); } static void -coff_objfmt_cleanup(void) +coff_objfmt_destroy(yasm_objfmt *objfmt) { + yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)objfmt; coff_symtab_entry *entry1, *entry2; /* Delete local symbol table */ - entry1 = STAILQ_FIRST(&coff_symtab); + entry1 = STAILQ_FIRST(&objfmt_coff->coff_symtab); while (entry1 != NULL) { entry2 = STAILQ_NEXT(entry1, link); if (entry1->numaux == 1 && entry1->auxtype == COFF_SYMTAB_AUX_FILE) @@ -826,14 +857,16 @@ coff_objfmt_cleanup(void) yasm_xfree(entry1); entry1 = entry2; } + yasm_xfree(objfmt); } static /*@observer@*/ /*@null@*/ yasm_section * -coff_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams, +coff_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, /*@unused@*/ /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line) { + yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)objfmt; yasm_valparam *vp = yasm_vps_first(valparams); yasm_section *retval; int isnew; @@ -887,23 +920,23 @@ coff_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams, if (strcmp(sectname, ".data") == 0) { flags = COFF_STYP_DATA; - if (win32) + if (objfmt_coff->win32) flags |= COFF_STYP_READ | COFF_STYP_WRITE | (3<win32) flags |= COFF_STYP_READ | COFF_STYP_WRITE | (3<win32) flags |= COFF_STYP_EXECUTE | COFF_STYP_READ | (5<win32) flags |= COFF_STYP_READ | (4<win32) flags |= COFF_STYP_EXECUTE | COFF_STYP_READ; } @@ -924,23 +957,23 @@ coff_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams, match = 0; for (i=0; ival, flagquals[i].name) == 0) { - if (!win32 && flagquals[i].stdflags == 0) + if (!objfmt_coff->win32 && flagquals[i].stdflags == 0) win32warn = 1; else switch (flagquals[i].mode) { case 0: flags &= ~flagquals[i].stdflags; - if (win32) + if (objfmt_coff->win32) flags &= ~flagquals[i].win32flags; break; case 1: flags |= flagquals[i].stdflags; - if (win32) + if (objfmt_coff->win32) flags |= flagquals[i].win32flags; break; case 2: flags &= ~COFF_STYP_STD_MASK; flags |= flagquals[i].stdflags; - if (win32) { + if (objfmt_coff->win32) { flags &= ~COFF_STYP_WIN32_MASK; flags |= flagquals[i].win32flags; } @@ -954,7 +987,7 @@ coff_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams, if (match) ; else if (yasm__strcasecmp(vp->val, "align") == 0 && vp->param) { - if (win32) { + if (objfmt_coff->win32) { /*@dependent@*/ /*@null@*/ const yasm_intnum *align; unsigned long bitcnt; unsigned long addralign; @@ -1003,15 +1036,15 @@ coff_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams, N_("Standard COFF does not support qualifier `%s'"), vp->val); } - retval = yasm_object_get_general(object, sectname, 0, resonly, &isnew, - line); + retval = yasm_object_get_general(objfmt_coff->object, sectname, 0, resonly, + &isnew, line); if (isnew) { coff_section_data *data; yasm_symrec *sym; data = yasm_xmalloc(sizeof(coff_section_data)); - data->scnum = coff_objfmt_parse_scnum++; + data->scnum = objfmt_coff->parse_scnum++; data->flags = flags; data->addr = 0; data->scnptr = 0; @@ -1022,9 +1055,9 @@ coff_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams, yasm_section_add_data(retval, &coff_section_data_cb, data); sym = - yasm_symtab_define_label(yasm_object_get_symtab(object), sectname, + yasm_symtab_define_label(objfmt_coff->symtab, sectname, yasm_section_bcs_first(retval), 1, line); - coff_objfmt_symtab_append(sym, COFF_SCL_STAT, NULL, 1, + coff_objfmt_symtab_append(objfmt_coff, sym, COFF_SCL_STAT, NULL, 1, COFF_SYMTAB_AUX_SECT); data->sym = sym; } else if (flags_override) @@ -1094,23 +1127,53 @@ coff_section_data_print(void *data, FILE *f, int indent_level) } } -static void -coff_objfmt_extglob_declare(yasm_symrec *sym, /*@unused@*/ - /*@null@*/ yasm_valparamhead *objext_valparams, - /*@unused@*/ unsigned long line) +static yasm_symrec * +coff_objfmt_extern_declare(yasm_objfmt *objfmt, const char *name, /*@unused@*/ + /*@null@*/ yasm_valparamhead *objext_valparams, + unsigned long line) { - coff_objfmt_symtab_append(sym, COFF_SCL_EXT, NULL, 0, + yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)objfmt; + yasm_symrec *sym; + + sym = yasm_symtab_declare(objfmt_coff->symtab, name, YASM_SYM_EXTERN, + line); + coff_objfmt_symtab_append(objfmt_coff, sym, COFF_SCL_EXT, NULL, 0, COFF_SYMTAB_AUX_NONE); + + return sym; } -static void -coff_objfmt_common_declare(yasm_symrec *sym, /*@only@*/ yasm_expr *size, - /*@unused@*/ /*@null@*/ +static yasm_symrec * +coff_objfmt_global_declare(yasm_objfmt *objfmt, const char *name, /*@unused@*/ + /*@null@*/ yasm_valparamhead *objext_valparams, + unsigned long line) +{ + yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)objfmt; + yasm_symrec *sym; + + sym = yasm_symtab_declare(objfmt_coff->symtab, name, YASM_SYM_GLOBAL, + line); + coff_objfmt_symtab_append(objfmt_coff, sym, COFF_SCL_EXT, NULL, 0, + COFF_SYMTAB_AUX_NONE); + + return sym; +} + +static yasm_symrec * +coff_objfmt_common_declare(yasm_objfmt *objfmt, const char *name, + /*@only@*/ yasm_expr *size, /*@unused@*/ /*@null@*/ yasm_valparamhead *objext_valparams, - /*@unused@*/ unsigned long line) + unsigned long line) { - coff_objfmt_symtab_append(sym, COFF_SCL_EXT, size, 0, + yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)objfmt; + yasm_symrec *sym; + + sym = yasm_symtab_declare(objfmt_coff->symtab, name, YASM_SYM_COMMON, + line); + coff_objfmt_symtab_append(objfmt_coff, sym, COFF_SCL_EXT, size, 0, COFF_SYMTAB_AUX_NONE); + + return sym; } static void @@ -1138,11 +1201,11 @@ coff_symrec_data_print(void *data, FILE *f, int indent_level) } static int -coff_objfmt_directive(/*@unused@*/ const char *name, +coff_objfmt_directive(/*@unused@*/ yasm_objfmt *objfmt, + /*@unused@*/ const char *name, /*@unused@*/ yasm_valparamhead *valparams, /*@unused@*/ /*@null@*/ yasm_valparamhead *objext_valparams, - /*@unused@*/ yasm_object *object, /*@unused@*/ unsigned long line) { return 1; /* no objfmt directives */ @@ -1156,7 +1219,7 @@ static const char *coff_objfmt_dbgfmt_keywords[] = { }; /* Define objfmt structure -- see objfmt.h for details */ -yasm_objfmt yasm_coff_LTX_objfmt = { +yasm_objfmt_module yasm_coff_LTX_objfmt = { YASM_OBJFMT_VERSION, "COFF (DJGPP)", "coff", @@ -1165,18 +1228,18 @@ yasm_objfmt yasm_coff_LTX_objfmt = { 32, coff_objfmt_dbgfmt_keywords, "null", - coff_objfmt_initialize, + coff_objfmt_create, coff_objfmt_output, - coff_objfmt_cleanup, + coff_objfmt_destroy, coff_objfmt_section_switch, - coff_objfmt_extglob_declare, - coff_objfmt_extglob_declare, + coff_objfmt_extern_declare, + coff_objfmt_global_declare, coff_objfmt_common_declare, coff_objfmt_directive }; /* Define objfmt structure -- see objfmt.h for details */ -yasm_objfmt yasm_win32_LTX_objfmt = { +yasm_objfmt_module yasm_win32_LTX_objfmt = { YASM_OBJFMT_VERSION, "Win32", "win32", @@ -1185,12 +1248,12 @@ yasm_objfmt yasm_win32_LTX_objfmt = { 32, coff_objfmt_dbgfmt_keywords, "null", - win32_objfmt_initialize, + win32_objfmt_create, coff_objfmt_output, - coff_objfmt_cleanup, + coff_objfmt_destroy, coff_objfmt_section_switch, - coff_objfmt_extglob_declare, - coff_objfmt_extglob_declare, + coff_objfmt_extern_declare, + coff_objfmt_global_declare, coff_objfmt_common_declare, coff_objfmt_directive }; diff --git a/modules/objfmts/dbg/dbg-objfmt.c b/modules/objfmts/dbg/dbg-objfmt.c index ab2a60e2..2f6b7567 100644 --- a/modules/objfmts/dbg/dbg-objfmt.c +++ b/modules/objfmts/dbg/dbg-objfmt.c @@ -31,164 +31,177 @@ #include -static void symrec_data_destroy(/*@only@*/ void *data); -static void symrec_data_print(void *data, FILE *f, int indent_level); +typedef struct yasm_objfmt_dbg { + yasm_objfmt_base objfmt; /* base structure */ -static const yasm_assoc_data_callback symrec_data_callback = { - symrec_data_destroy, - symrec_data_print -}; + yasm_object *object; + yasm_symtab *symtab; + FILE *dbgfile; +} yasm_objfmt_dbg; -/* Output file for debugging-type formats. This is so that functions that are - * called before the object file is usually opened can still write data out to - * it (whereas for "normal" formats the object file is not opened until later - * in the assembly process). Opening the file early is done in initialize(). - * - * Note that the functions here write to dbg_objfmt_file. This is NOT legal - * for other object formats to do--only the output() function can write to a - * file, and only the file it's passed in its f parameter! - */ -static FILE *dbg_objfmt_file; +yasm_objfmt_module yasm_dbg_LTX_objfmt; -static int -dbg_objfmt_initialize(const char *in_filename, const char *obj_filename, - yasm_object *object, yasm_dbgfmt *df, yasm_arch *a) +static yasm_objfmt * +dbg_objfmt_create(const char *in_filename, yasm_object *object, + yasm_arch *a) { - dbg_objfmt_file = fopen(obj_filename, "wt"); - if (!dbg_objfmt_file) { - fprintf(stderr, N_("could not open file `%s'"), obj_filename); + yasm_objfmt_dbg *objfmt_dbg = yasm_xmalloc(sizeof(yasm_objfmt_dbg)); + + objfmt_dbg->objfmt.module = &yasm_dbg_LTX_objfmt; + + objfmt_dbg->object = object; + objfmt_dbg->symtab = yasm_object_get_symtab(object); + objfmt_dbg->dbgfile = tmpfile(); + if (!objfmt_dbg->dbgfile) { + fprintf(stderr, N_("could not open temporary file")); return 0; } - fprintf(dbg_objfmt_file, - "initialize(\"%s\", \"%s\", %s dbgfmt, %s arch)\n", - in_filename, obj_filename, df->keyword, yasm_arch_keyword(a)); - return 0; + fprintf(objfmt_dbg->dbgfile, "create(\"%s\", %s arch)\n", + in_filename, yasm_arch_keyword(a)); + return (yasm_objfmt *)objfmt_dbg; } static void -dbg_objfmt_output(/*@unused@*/ FILE *f, yasm_object *object, int all_syms) +dbg_objfmt_output(yasm_objfmt *objfmt, FILE *f, const char *obj_filename, + int all_syms, yasm_dbgfmt *df) { - fprintf(dbg_objfmt_file, "output(f, object->\n"); - yasm_object_print(object, dbg_objfmt_file, 1); - fprintf(dbg_objfmt_file, "%d)\n", all_syms); - fprintf(dbg_objfmt_file, " Symbol Table:\n"); - yasm_symtab_print(yasm_object_get_symtab(object), dbg_objfmt_file, 1); + yasm_objfmt_dbg *objfmt_dbg = (yasm_objfmt_dbg *)objfmt; + char buf[1024]; + unsigned int i; + + /* Copy temp file to real output file */ + rewind(objfmt_dbg->dbgfile); + while ((i = fread(buf, 1, 1024, objfmt_dbg->dbgfile))) { + if (fwrite(buf, 1, i, f) != i) + break; + } + + /* Reassign objfmt debug file to output file */ + fclose(objfmt_dbg->dbgfile); + objfmt_dbg->dbgfile = f; + + fprintf(objfmt_dbg->dbgfile, "output(f, object->\n"); + yasm_object_print(objfmt_dbg->object, objfmt_dbg->dbgfile, 1); + fprintf(objfmt_dbg->dbgfile, "%d, %s dbgfmt)\n", all_syms, + yasm_dbgfmt_keyword(df)); + fprintf(objfmt_dbg->dbgfile, " Symbol Table:\n"); + yasm_symtab_print(yasm_object_get_symtab(objfmt_dbg->object), + objfmt_dbg->dbgfile, 1); } static void -dbg_objfmt_cleanup(void) +dbg_objfmt_destroy(yasm_objfmt *objfmt) { - fprintf(dbg_objfmt_file, "cleanup()\n"); + yasm_objfmt_dbg *objfmt_dbg = (yasm_objfmt_dbg *)objfmt; + fprintf(objfmt_dbg->dbgfile, "destroy()\n"); + yasm_xfree(objfmt); } static /*@observer@*/ /*@null@*/ yasm_section * -dbg_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams, +dbg_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, /*@unused@*/ /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line) { + yasm_objfmt_dbg *objfmt_dbg = (yasm_objfmt_dbg *)objfmt; yasm_valparam *vp; yasm_section *retval; int isnew; - fprintf(dbg_objfmt_file, "sections_switch(headp, "); - yasm_vps_print(valparams, dbg_objfmt_file); - fprintf(dbg_objfmt_file, ", "); - yasm_vps_print(objext_valparams, dbg_objfmt_file); - fprintf(dbg_objfmt_file, ", %lu), returning ", line); + fprintf(objfmt_dbg->dbgfile, "section_switch(headp, "); + yasm_vps_print(valparams, objfmt_dbg->dbgfile); + fprintf(objfmt_dbg->dbgfile, ", "); + yasm_vps_print(objext_valparams, objfmt_dbg->dbgfile); + fprintf(objfmt_dbg->dbgfile, ", %lu), returning ", line); if ((vp = yasm_vps_first(valparams)) && !vp->param && vp->val != NULL) { - retval = yasm_object_get_general(object, vp->val, + retval = yasm_object_get_general(objfmt_dbg->object, vp->val, yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(200)), line), 0, &isnew, line); if (isnew) { - fprintf(dbg_objfmt_file, "(new) "); - yasm_symtab_define_label(yasm_object_get_symtab(object), vp->val, - yasm_section_bcs_first(retval), 1, line); + fprintf(objfmt_dbg->dbgfile, "(new) "); + yasm_symtab_define_label( + yasm_object_get_symtab(objfmt_dbg->object), vp->val, + yasm_section_bcs_first(retval), 1, line); } - fprintf(dbg_objfmt_file, "\"%s\" section\n", vp->val); + fprintf(objfmt_dbg->dbgfile, "\"%s\" section\n", vp->val); return retval; } else { - fprintf(dbg_objfmt_file, "NULL\n"); + fprintf(objfmt_dbg->dbgfile, "NULL\n"); return NULL; } } -static void -dbg_objfmt_extern_declare(yasm_symrec *sym, /*@unused@*/ /*@null@*/ +static yasm_symrec * +dbg_objfmt_extern_declare(yasm_objfmt *objfmt, const char *name, + /*@unused@*/ /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line) { - fprintf(dbg_objfmt_file, "extern_declare(\"%s\", ", - yasm_symrec_get_name(sym)); - yasm_vps_print(objext_valparams, dbg_objfmt_file); - fprintf(dbg_objfmt_file, ", %lu)\n", line); + yasm_objfmt_dbg *objfmt_dbg = (yasm_objfmt_dbg *)objfmt; + yasm_symrec *sym; + + fprintf(objfmt_dbg->dbgfile, "extern_declare(\"%s\", ", name); + yasm_vps_print(objext_valparams, objfmt_dbg->dbgfile); + fprintf(objfmt_dbg->dbgfile, ", %lu), returning sym\n", line); + + sym = yasm_symtab_declare(objfmt_dbg->symtab, name, YASM_SYM_EXTERN, line); + return sym; } -static void -dbg_objfmt_global_declare(yasm_symrec *sym, /*@unused@*/ /*@null@*/ +static yasm_symrec * +dbg_objfmt_global_declare(yasm_objfmt *objfmt, const char *name, + /*@unused@*/ /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line) { - fprintf(dbg_objfmt_file, "global_declare(\"%s\", ", - yasm_symrec_get_name(sym)); - yasm_vps_print(objext_valparams, dbg_objfmt_file); - fprintf(dbg_objfmt_file, ", %lu)\n", line); + yasm_objfmt_dbg *objfmt_dbg = (yasm_objfmt_dbg *)objfmt; + yasm_symrec *sym; + + fprintf(objfmt_dbg->dbgfile, "global_declare(\"%s\", ", name); + yasm_vps_print(objext_valparams, objfmt_dbg->dbgfile); + fprintf(objfmt_dbg->dbgfile, ", %lu), returning sym\n", line); + + sym = yasm_symtab_declare(objfmt_dbg->symtab, name, YASM_SYM_GLOBAL, line); + return sym; } -static void -dbg_objfmt_common_declare(yasm_symrec *sym, /*@only@*/ yasm_expr *size, +static yasm_symrec * +dbg_objfmt_common_declare(yasm_objfmt *objfmt, const char *name, + /*@only@*/ yasm_expr *size, /*@unused@*/ /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line) { - assert(dbg_objfmt_file != NULL); - fprintf(dbg_objfmt_file, "common_declare(\"%s\", ", - yasm_symrec_get_name(sym)); - yasm_expr_print(size, dbg_objfmt_file); - fprintf(dbg_objfmt_file, ", "); - yasm_vps_print(objext_valparams, dbg_objfmt_file); - fprintf(dbg_objfmt_file, ", %lu), setting of_data=", line); - yasm_expr_print(size, dbg_objfmt_file); - yasm_symrec_add_data(sym, &symrec_data_callback, size); - fprintf(dbg_objfmt_file, "\n"); -} + yasm_objfmt_dbg *objfmt_dbg = (yasm_objfmt_dbg *)objfmt; + yasm_symrec *sym; -static void -symrec_data_destroy(void *data) -{ - fprintf(dbg_objfmt_file, "symrec_data_delete("); - if (data) { - yasm_expr_print((yasm_expr *)data, dbg_objfmt_file); - yasm_expr_destroy((yasm_expr *)data); - } - fprintf(dbg_objfmt_file, ")\n"); -} + assert(objfmt_dbg->dbgfile != NULL); + fprintf(objfmt_dbg->dbgfile, "common_declare(\"%s\", ", name); + yasm_expr_print(size, objfmt_dbg->dbgfile); + fprintf(objfmt_dbg->dbgfile, ", "); + yasm_vps_print(objext_valparams, objfmt_dbg->dbgfile); + fprintf(objfmt_dbg->dbgfile, ", %lu), returning sym\n", line); + yasm_expr_destroy(size); -static void -symrec_data_print(void *data, FILE *f, int indent_level) -{ - if (data) { - fprintf(f, "%*sSize=", indent_level, ""); - yasm_expr_print((yasm_expr *)data, f); - fprintf(f, "\n"); - } else { - fprintf(f, "%*s(none)\n", indent_level, ""); - } + + sym = yasm_symtab_declare(objfmt_dbg->symtab, name, YASM_SYM_COMMON, line); + return sym; } static int -dbg_objfmt_directive(const char *name, yasm_valparamhead *valparams, +dbg_objfmt_directive(yasm_objfmt *objfmt, const char *name, + yasm_valparamhead *valparams, /*@null@*/ yasm_valparamhead *objext_valparams, - /*@unused@*/ yasm_object *object, unsigned long line) { - fprintf(dbg_objfmt_file, "directive(\"%s\", ", name); - yasm_vps_print(valparams, dbg_objfmt_file); - fprintf(dbg_objfmt_file, ", "); - yasm_vps_print(objext_valparams, dbg_objfmt_file); - fprintf(dbg_objfmt_file, ", %lu), returning 0 (recognized)\n", line); + yasm_objfmt_dbg *objfmt_dbg = (yasm_objfmt_dbg *)objfmt; + fprintf(objfmt_dbg->dbgfile, "directive(\"%s\", ", name); + yasm_vps_print(valparams, objfmt_dbg->dbgfile); + fprintf(objfmt_dbg->dbgfile, ", "); + yasm_vps_print(objext_valparams, objfmt_dbg->dbgfile); + fprintf(objfmt_dbg->dbgfile, ", %lu), returning 0 (recognized)\n", line); return 0; /* dbg format "recognizes" all directives */ } @@ -200,7 +213,7 @@ static const char *dbg_objfmt_dbgfmt_keywords[] = { }; /* Define objfmt structure -- see objfmt.h for details */ -yasm_objfmt yasm_dbg_LTX_objfmt = { +yasm_objfmt_module yasm_dbg_LTX_objfmt = { YASM_OBJFMT_VERSION, "Trace of all info passed to object format module", "dbg", @@ -209,9 +222,9 @@ yasm_objfmt yasm_dbg_LTX_objfmt = { 32, dbg_objfmt_dbgfmt_keywords, "null", - dbg_objfmt_initialize, + dbg_objfmt_create, dbg_objfmt_output, - dbg_objfmt_cleanup, + dbg_objfmt_destroy, dbg_objfmt_section_switch, dbg_objfmt_extern_declare, dbg_objfmt_global_declare, diff --git a/modules/objfmts/elf/elf-objfmt.c b/modules/objfmts/elf/elf-objfmt.c index 7e4b8b11..a8cb5956 100644 --- a/modules/objfmts/elf/elf-objfmt.c +++ b/modules/objfmts/elf/elf-objfmt.c @@ -51,7 +51,21 @@ #include "elf.h" +typedef struct yasm_objfmt_elf { + yasm_objfmt_base objfmt; /* base structure */ + + unsigned int parse_scnum; /* sect numbering in parser */ + elf_symtab_head* elf_symtab; /* symbol table of indexed syms */ + elf_strtab_head* shstrtab; /* section name strtab */ + elf_strtab_head* strtab; /* strtab entries */ + + yasm_object *object; + yasm_symtab *symtab; + /*@dependent@*/ yasm_arch *arch; +} yasm_objfmt_elf; + typedef struct { + yasm_objfmt_elf *objfmt_elf; FILE *f; elf_secthead *shead; yasm_section *sect; @@ -59,23 +73,23 @@ typedef struct { unsigned long sindex; } elf_objfmt_output_info; -static unsigned int elf_objfmt_parse_scnum; /* sect numbering in parser */ -static elf_symtab_head* elf_symtab; /* symbol table of indexed syms */ -static elf_strtab_head* elf_shstrtab; /* section name strtab */ -static elf_strtab_head* elf_strtab; /* strtab entries */ +typedef struct { + yasm_objfmt_elf *objfmt_elf; + int local_names; +} append_local_sym_info; -static /*@dependent@*/ yasm_arch *cur_arch; -static /*@dependent@*/ yasm_dbgfmt *cur_dbgfmt; +yasm_objfmt_module yasm_elf_LTX_objfmt; static elf_symtab_entry * -elf_objfmt_symtab_append(yasm_symrec *sym, elf_symbol_binding bind, - elf_section_index sectidx, yasm_expr *size) +elf_objfmt_symtab_append(yasm_objfmt_elf *objfmt_elf, yasm_symrec *sym, + elf_symbol_binding bind, elf_section_index sectidx, + yasm_expr *size) { - elf_strtab_entry *name = elf_strtab_append_str(elf_strtab, + elf_strtab_entry *name = elf_strtab_append_str(objfmt_elf->strtab, yasm_symrec_get_name(sym)); elf_symtab_entry *entry = elf_symtab_entry_create(name, sym); - elf_symtab_append_entry(elf_symtab, entry); + elf_symtab_append_entry(objfmt_elf->elf_symtab, entry); elf_symtab_set_nonzero(entry, NULL, sectidx, bind, STT_NOTYPE, size, 00); yasm_symrec_add_data(sym, &elf_symrec_data, entry); @@ -84,24 +98,28 @@ elf_objfmt_symtab_append(yasm_symrec *sym, elf_symbol_binding bind, } static int -elf_objfmt_append_local_sym(yasm_symrec *sym, /*@unused@*/ /*@null@*/ void *d) +elf_objfmt_append_local_sym(yasm_symrec *sym, /*@null@*/ void *d) { - int local_names = *(int *)d; + append_local_sym_info *info = (append_local_sym_info *)d; elf_symtab_entry *entry; elf_address value=0; yasm_section *sect=NULL; yasm_bytecode *precbc=NULL; + assert(info != NULL); + if (!yasm_symrec_get_data(sym, &elf_symrec_data)) { int is_sect = 0; if (!yasm_symrec_get_label(sym, &precbc)) return 1; sect = yasm_bc_get_section(precbc); - is_sect = strcmp(yasm_symrec_get_name(sym), yasm_section_get_name(sect))==0; + is_sect = strcmp(yasm_symrec_get_name(sym), + yasm_section_get_name(sect))==0; /* neither sections nor locals (except when debugging) need names */ - entry = elf_symtab_insert_local_sym(elf_symtab, - local_names && !is_sect ? elf_strtab : NULL, sym); + entry = elf_symtab_insert_local_sym(info->objfmt_elf->elf_symtab, + info->local_names && !is_sect ? + info->objfmt_elf->strtab : NULL, sym); elf_symtab_set_nonzero(entry, sect, 0, STB_LOCAL, is_sect ? STT_SECTION : STT_NOTYPE, NULL, 0); yasm_symrec_add_data(sym, &elf_symrec_data, entry); @@ -123,36 +141,38 @@ elf_objfmt_append_local_sym(yasm_symrec *sym, /*@unused@*/ /*@null@*/ void *d) return 1; } -static int -elf_objfmt_initialize(const char *in_filename, - /*@unused@*/ const char *obj_filename, - yasm_object *object, /*@unused@*/ yasm_dbgfmt *df, - yasm_arch *a) +static yasm_objfmt * +elf_objfmt_create(const char *in_filename, yasm_object *object, yasm_arch *a) { + yasm_objfmt_elf *objfmt_elf = yasm_xmalloc(sizeof(yasm_objfmt_elf)); yasm_symrec *filesym; elf_symtab_entry *entry; - cur_arch = a; - cur_dbgfmt = df; - if (!elf_set_arch(a)) - return 1; + objfmt_elf->objfmt.module = &yasm_elf_LTX_objfmt; + objfmt_elf->object = object; + objfmt_elf->symtab = yasm_object_get_symtab(object); + objfmt_elf->arch = a; + if (!elf_set_arch(a)) { + yasm_xfree(objfmt_elf); + return NULL; + } - elf_objfmt_parse_scnum = 4; /* section numbering starts at 0; - 4 predefined sections. */ - elf_shstrtab = elf_strtab_create(); - elf_strtab = elf_strtab_create(); - elf_symtab = elf_symtab_create(); + objfmt_elf->parse_scnum = 4; /* section numbering starts at 0; + 4 predefined sections. */ + objfmt_elf->shstrtab = elf_strtab_create(); + objfmt_elf->strtab = elf_strtab_create(); + objfmt_elf->elf_symtab = elf_symtab_create(); /* FIXME: misuse of NULL bytecode here; it works, but only barely. */ filesym = yasm_symtab_define_label(yasm_object_get_symtab(object), ".file", NULL, 0, 0); entry = elf_symtab_entry_create( - elf_strtab_append_str(elf_strtab, in_filename), filesym); + elf_strtab_append_str(objfmt_elf->strtab, in_filename), filesym); yasm_symrec_add_data(filesym, &elf_symrec_data, entry); elf_symtab_set_nonzero(entry, NULL, SHN_ABS, STB_LOCAL, STT_FILE, NULL, 0); - elf_symtab_append_entry(elf_symtab, entry); + elf_symtab_append_entry(objfmt_elf->elf_symtab, entry); - return 0; + return (yasm_objfmt *)objfmt_elf; } static long @@ -197,10 +217,11 @@ elf_objfmt_output_reloc(yasm_symrec *sym, yasm_bytecode *bc, } /* allocate .rel sections on a need-basis */ if (elf_secthead_append_reloc(info->shead, reloc)) - elf_objfmt_parse_scnum++; + info->objfmt_elf->parse_scnum++; - retval = yasm_arch_intnum_tobytes(cur_arch, zero, buf, destsize, valsize, - 0, bc, rel, warn, bc->line); + retval = yasm_arch_intnum_tobytes(info->objfmt_elf->arch, zero, buf, + destsize, valsize, 0, bc, rel, warn, + bc->line); yasm_intnum_destroy(zero); return retval; } @@ -226,9 +247,9 @@ elf_objfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize, if (flt) { if (shift < 0) yasm_internal_error(N_("attempting to negative shift a float")); - return yasm_arch_floatnum_tobytes(cur_arch, flt, buf, destsize, - valsize, (unsigned int)shift, warn, - bc->line); + return yasm_arch_floatnum_tobytes(info->objfmt_elf->arch, flt, buf, + destsize, valsize, + (unsigned int)shift, warn, bc->line); } /* Handle integer expressions, with relocation if necessary */ @@ -273,13 +294,14 @@ elf_objfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize, } /* allocate .rel sections on a need-basis */ if (elf_secthead_append_reloc(info->shead, reloc)) - elf_objfmt_parse_scnum++; + info->objfmt_elf->parse_scnum++; } intn = yasm_expr_get_intnum(ep, NULL); if (intn) - return yasm_arch_intnum_tobytes(cur_arch, intn, buf, destsize, valsize, - shift, bc, rel, warn, bc->line); + return yasm_arch_intnum_tobytes(info->objfmt_elf->arch, intn, buf, + destsize, valsize, shift, bc, rel, + warn, bc->line); /* Check for complex float expressions */ if (yasm_expr__contains(*ep, YASM_EXPR_FLOAT)) { @@ -360,7 +382,8 @@ elf_objfmt_create_dbg_secthead(yasm_section *sect, yasm_intnum *align=NULL; elf_size entsize=0; const char *sectname = yasm_section_get_name(sect); - elf_strtab_entry *name = elf_strtab_append_str(elf_shstrtab, sectname); + elf_strtab_entry *name = elf_strtab_append_str(info->objfmt_elf->shstrtab, + sectname); if (yasm__strcasecmp(sectname, ".stab")==0) { align = yasm_intnum_create_uint(4); @@ -372,7 +395,8 @@ elf_objfmt_create_dbg_secthead(yasm_section *sect, else yasm_internal_error(N_("Unrecognized section without data")); - shead = elf_secthead_create(name, type, 0, elf_objfmt_parse_scnum++, 0, 0); + shead = elf_secthead_create(name, type, 0, info->objfmt_elf->parse_scnum++, + 0, 0); elf_secthead_set_align(shead, align); elf_secthead_set_entsize(shead, entsize); @@ -447,7 +471,8 @@ elf_objfmt_output_section(yasm_section *sect, /*@null@*/ void *d) relname = yasm_xmalloc(relname_len); snprintf(relname, relname_len, ".rel%s", sectname); elf_secthead_set_rel_name(shead, - elf_strtab_append_str(elf_shstrtab, relname)); + elf_strtab_append_str(info->objfmt_elf->shstrtab, + relname)); yasm_xfree(relname); return 0; @@ -482,9 +507,12 @@ elf_objfmt_output_secthead(yasm_section *sect, /*@null@*/ void *d) } static void -elf_objfmt_output(FILE *f, yasm_object *object, int all_syms) +elf_objfmt_output(yasm_objfmt *objfmt, FILE *f, const char *obj_filename, + int all_syms, yasm_dbgfmt *df) { + yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)objfmt; elf_objfmt_output_info info; + append_local_sym_info localsym_info; long pos; unsigned long elf_shead_addr; elf_secthead *esdn; @@ -493,6 +521,7 @@ elf_objfmt_output(FILE *f, yasm_object *object, int all_syms) elf_strtab_entry *elf_strtab_name, *elf_shstrtab_name, *elf_symtab_name; unsigned long elf_symtab_nlocal; + info.objfmt_elf = objfmt_elf; info.f = f; /* Allocate space for Ehdr by seeking forward */ @@ -503,39 +532,42 @@ elf_objfmt_output(FILE *f, yasm_object *object, int all_syms) /* add all (local) syms to symtab because relocation needs a symtab index * if all_syms, register them by name. if not, use strtab entry 0 */ - yasm_symtab_traverse(yasm_object_get_symtab(object), (void *)&all_syms, - elf_objfmt_append_local_sym); - elf_symtab_nlocal = elf_symtab_assign_indices(elf_symtab); + localsym_info.local_names = all_syms; + localsym_info.objfmt_elf = objfmt_elf; + yasm_symtab_traverse(yasm_object_get_symtab(objfmt_elf->object), + &localsym_info, elf_objfmt_append_local_sym); + elf_symtab_nlocal = elf_symtab_assign_indices(objfmt_elf->elf_symtab); /* output known sections - includes reloc sections which aren't in yasm's * list. Assign indices as we go. */ info.sindex = 3; - if (yasm_object_sections_traverse(object, &info, + if (yasm_object_sections_traverse(objfmt_elf->object, &info, elf_objfmt_output_section)) return; /* add final sections to the shstrtab */ - elf_strtab_name = elf_strtab_append_str(elf_shstrtab, ".strtab"); - elf_symtab_name = elf_strtab_append_str(elf_shstrtab, ".symtab"); - elf_shstrtab_name = elf_strtab_append_str(elf_shstrtab, ".shstrtab"); + elf_strtab_name = elf_strtab_append_str(objfmt_elf->shstrtab, ".strtab"); + elf_symtab_name = elf_strtab_append_str(objfmt_elf->shstrtab, ".symtab"); + elf_shstrtab_name = elf_strtab_append_str(objfmt_elf->shstrtab, + ".shstrtab"); /* output .shstrtab */ if ((pos = elf_objfmt_output_align(f, 4)) == -1) return; elf_shstrtab_offset = (unsigned long) pos; - elf_shstrtab_size = elf_strtab_output_to_file(f, elf_shstrtab); + elf_shstrtab_size = elf_strtab_output_to_file(f, objfmt_elf->shstrtab); /* output .strtab */ if ((pos = elf_objfmt_output_align(f, 4)) == -1) return; elf_strtab_offset = (unsigned long) pos; - elf_strtab_size = elf_strtab_output_to_file(f, elf_strtab); + elf_strtab_size = elf_strtab_output_to_file(f, objfmt_elf->strtab); /* output .symtab - last section so all others have indexes */ if ((pos = elf_objfmt_output_align(f, 4)) == -1) return; elf_symtab_offset = (unsigned long) pos; - elf_symtab_size = elf_symtab_write_to_file(f, elf_symtab); + elf_symtab_size = elf_symtab_write_to_file(f, objfmt_elf->elf_symtab); /* output section header table */ if ((pos = elf_objfmt_output_align(f, 16)) == -1) @@ -543,10 +575,11 @@ elf_objfmt_output(FILE *f, yasm_object *object, int all_syms) elf_shead_addr = (unsigned long) pos; /* stabs debugging support */ - if (strcmp(cur_dbgfmt->keyword, "stabs")==0) { - yasm_section *stabsect = yasm_object_find_general(object, ".stab"); + if (strcmp(yasm_dbgfmt_keyword(df), "stabs")==0) { + yasm_section *stabsect = yasm_object_find_general(objfmt_elf->object, + ".stab"); yasm_section *stabstrsect = - yasm_object_find_general(object, ".stabstr"); + yasm_object_find_general(objfmt_elf->object, ".stabstr"); if (stabsect && stabstrsect) { elf_secthead *stab = yasm_section_get_data(stabsect, &elf_section_data); @@ -586,7 +619,8 @@ elf_objfmt_output(FILE *f, yasm_object *object, int all_syms) info.sindex = 3; /* output remaining section headers */ - yasm_object_sections_traverse(object, &info, elf_objfmt_output_secthead); + yasm_object_sections_traverse(objfmt_elf->object, &info, + elf_objfmt_output_secthead); /* output Ehdr */ if (fseek(f, 0, SEEK_SET) < 0) { @@ -598,19 +632,22 @@ elf_objfmt_output(FILE *f, yasm_object *object, int all_syms) } static void -elf_objfmt_cleanup(void) +elf_objfmt_destroy(yasm_objfmt *objfmt) { - elf_symtab_destroy(elf_symtab); - elf_strtab_destroy(elf_shstrtab); - elf_strtab_destroy(elf_strtab); + yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)objfmt; + elf_symtab_destroy(objfmt_elf->elf_symtab); + elf_strtab_destroy(objfmt_elf->shstrtab); + elf_strtab_destroy(objfmt_elf->strtab); + yasm_xfree(objfmt); } static /*@observer@*/ /*@null@*/ yasm_section * -elf_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams, +elf_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, /*@unused@*/ /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line) { + yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)objfmt; yasm_valparam *vp = yasm_vps_first(valparams); yasm_section *retval; int isnew; @@ -710,24 +747,25 @@ elf_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams, N_("Unrecognized qualifier `%s'"), vp->val); } - retval = yasm_object_get_general(object, sectname, 0, resonly, &isnew, - line); + retval = yasm_object_get_general(objfmt_elf->object, sectname, 0, resonly, + &isnew, line); if (isnew) { elf_secthead *esd; yasm_symrec *sym; - elf_strtab_entry *name = elf_strtab_append_str(elf_shstrtab, sectname); + elf_strtab_entry *name = elf_strtab_append_str(objfmt_elf->shstrtab, + sectname); - esd = elf_secthead_create(name, type, flags, elf_objfmt_parse_scnum++, + esd = elf_secthead_create(name, type, flags, objfmt_elf->parse_scnum++, 0, 0); if (!align_intn) align_intn = yasm_intnum_create_uint(align); if (align_intn) elf_secthead_set_align(esd, align_intn); yasm_section_add_data(retval, &elf_section_data, esd); - sym = - yasm_symtab_define_label(yasm_object_get_symtab(object), sectname, - yasm_section_bcs_first(retval), 1, line); + sym = yasm_symtab_define_label( + yasm_object_get_symtab(objfmt_elf->object), sectname, + yasm_section_bcs_first(retval), 1, line); elf_secthead_set_sym(esd, sym); } else if (flags_override) @@ -736,30 +774,56 @@ elf_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams, return retval; } -static void -elf_objfmt_extglob_declare(yasm_symrec *sym, /*@unused@*/ - /*@null@*/ yasm_valparamhead *objext_valparams, - /*@unused@*/ unsigned long line) +static yasm_symrec * +elf_objfmt_extern_declare(yasm_objfmt *objfmt, const char *name, /*@unused@*/ + /*@null@*/ yasm_valparamhead *objext_valparams, + unsigned long line) { - elf_objfmt_symtab_append(sym, STB_GLOBAL, SHN_UNDEF, NULL); + yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)objfmt; + yasm_symrec *sym; + + sym = yasm_symtab_declare(objfmt_elf->symtab, name, YASM_SYM_EXTERN, line); + elf_objfmt_symtab_append(objfmt_elf, sym, STB_GLOBAL, SHN_UNDEF, NULL); + + return sym; } -static void -elf_objfmt_common_declare(yasm_symrec *sym, /*@only@*/ yasm_expr *size, - /*@unused@*/ /*@null@*/ - yasm_valparamhead *objext_valparams, - /*@unused@*/ unsigned long line) +static yasm_symrec * +elf_objfmt_global_declare(yasm_objfmt *objfmt, const char *name, /*@unused@*/ + /*@null@*/ yasm_valparamhead *objext_valparams, + unsigned long line) { - elf_objfmt_symtab_append(sym, STB_GLOBAL, SHN_COMMON, size); + yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)objfmt; + yasm_symrec *sym; + + sym = yasm_symtab_declare(objfmt_elf->symtab, name, YASM_SYM_GLOBAL, line); + elf_objfmt_symtab_append(objfmt_elf, sym, STB_GLOBAL, SHN_UNDEF, NULL); + + return sym; +} + +static yasm_symrec * +elf_objfmt_common_declare(yasm_objfmt *objfmt, const char *name, + /*@only@*/ yasm_expr *size, /*@unused@*/ /*@null@*/ + yasm_valparamhead *objext_valparams, + unsigned long line) +{ + yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)objfmt; + yasm_symrec *sym; + + sym = yasm_symtab_declare(objfmt_elf->symtab, name, YASM_SYM_COMMON, line); + elf_objfmt_symtab_append(objfmt_elf, sym, STB_GLOBAL, SHN_COMMON, size); + + return sym; } static int -elf_objfmt_directive(/*@unused@*/ const char *name, - /*@unused@*/ yasm_valparamhead *valparams, - /*@unused@*/ /*@null@*/ - yasm_valparamhead *objext_valparams, - /*@unused@*/ yasm_object *object, - /*@unused@*/ unsigned long line) +elf_objfmt_directive(/*@unused@*/ yasm_objfmt *objfmt, + /*@unused@*/ const char *name, + /*@unused@*/ yasm_valparamhead *valparams, + /*@unused@*/ /*@null@*/ + yasm_valparamhead *objext_valparams, + /*@unused@*/ unsigned long line) { return 1; /* no objfmt directives */ } @@ -773,7 +837,7 @@ static const char *elf_objfmt_dbgfmt_keywords[] = { }; /* Define objfmt structure -- see objfmt.h for details */ -yasm_objfmt yasm_elf_LTX_objfmt = { +yasm_objfmt_module yasm_elf_LTX_objfmt = { YASM_OBJFMT_VERSION, "ELF", "elf", @@ -782,12 +846,12 @@ yasm_objfmt yasm_elf_LTX_objfmt = { 32, elf_objfmt_dbgfmt_keywords, "null", - elf_objfmt_initialize, + elf_objfmt_create, elf_objfmt_output, - elf_objfmt_cleanup, + elf_objfmt_destroy, elf_objfmt_section_switch, - elf_objfmt_extglob_declare, - elf_objfmt_extglob_declare, + elf_objfmt_extern_declare, + elf_objfmt_global_declare, elf_objfmt_common_declare, elf_objfmt_directive }; diff --git a/modules/optimizers/basic/basic-optimizer.c b/modules/optimizers/basic/basic-optimizer.c index 6b04c231..a700fc49 100644 --- a/modules/optimizers/basic/basic-optimizer.c +++ b/modules/optimizers/basic/basic-optimizer.c @@ -226,7 +226,7 @@ basic_optimize(yasm_object *object) } /* Define optimizer structure -- see optimizer.h for details */ -yasm_optimizer yasm_basic_LTX_optimizer = { +yasm_optimizer_module yasm_basic_LTX_optimizer = { YASM_OPTIMIZER_VERSION, "Only the most basic optimizations", "basic", diff --git a/modules/parsers/nasm/nasm-bison.y b/modules/parsers/nasm/nasm-bison.y index f95eea6f..6d4642be 100644 --- a/modules/parsers/nasm/nasm-bison.y +++ b/modules/parsers/nasm/nasm-bison.y @@ -517,28 +517,21 @@ nasm_parser_directive(yasm_parser_nasm *parser_nasm, const char *name, yasm_valparamhead *objext_valparams) { yasm_valparam *vp, *vp2; - yasm_symrec *sym; unsigned long line = cur_line; /* Handle (mostly) output-format independent directives here */ if (yasm__strcasecmp(name, "extern") == 0) { vp = yasm_vps_first(valparams); if (vp->val) { - sym = yasm_symtab_declare(p_symtab, vp->val, YASM_SYM_EXTERN, - line); - if (parser_nasm->objfmt->extern_declare) - parser_nasm->objfmt->extern_declare(sym, objext_valparams, - line); + yasm_objfmt_extern_declare(parser_nasm->objfmt, vp->val, + objext_valparams, line); } else yasm__error(line, N_("invalid argument to [%s]"), "EXTERN"); } else if (yasm__strcasecmp(name, "global") == 0) { vp = yasm_vps_first(valparams); if (vp->val) { - sym = yasm_symtab_declare(p_symtab, vp->val, YASM_SYM_GLOBAL, - line); - if (parser_nasm->objfmt->global_declare) - parser_nasm->objfmt->global_declare(sym, objext_valparams, - line); + yasm_objfmt_global_declare(parser_nasm->objfmt, vp->val, + objext_valparams, line); } else yasm__error(line, N_("invalid argument to [%s]"), "GLOBAL"); } else if (yasm__strcasecmp(name, "common") == 0) { @@ -550,20 +543,14 @@ nasm_parser_directive(yasm_parser_nasm *parser_nasm, const char *name, "COMMON"); else { if (vp2->val) { - sym = yasm_symtab_declare(p_symtab, vp->val, - YASM_SYM_COMMON, line); - if (parser_nasm->objfmt->common_declare) - parser_nasm->objfmt->common_declare(sym, - p_expr_new_ident(yasm_expr_sym( - yasm_symtab_use(p_symtab, vp2->val, line))), - objext_valparams, line); + yasm_objfmt_common_declare(parser_nasm->objfmt, vp->val, + p_expr_new_ident(yasm_expr_sym( + yasm_symtab_use(p_symtab, vp2->val, line))), + objext_valparams, line); } else if (vp2->param) { - sym = yasm_symtab_declare(p_symtab, vp->val, - YASM_SYM_COMMON, line); - if (parser_nasm->objfmt->common_declare) - parser_nasm->objfmt->common_declare(sym, vp2->param, - objext_valparams, - line); + yasm_objfmt_common_declare(parser_nasm->objfmt, vp->val, + vp2->param, objext_valparams, + line); vp2->param = NULL; } } @@ -572,9 +559,8 @@ nasm_parser_directive(yasm_parser_nasm *parser_nasm, const char *name, } else if (yasm__strcasecmp(name, "section") == 0 || yasm__strcasecmp(name, "segment") == 0) { yasm_section *new_section = - parser_nasm->objfmt->section_switch(parser_nasm->object, - valparams, objext_valparams, - line); + yasm_objfmt_section_switch(parser_nasm->objfmt, valparams, + objext_valparams, line); if (new_section) { parser_nasm->cur_section = new_section; parser_nasm->prev_bc = yasm_section_bcs_last(new_section); @@ -614,8 +600,8 @@ nasm_parser_directive(yasm_parser_nasm *parser_nasm, const char *name, } else if (!yasm_arch_parse_directive(parser_nasm->arch, name, valparams, objext_valparams, parser_nasm->object, line)) { ; - } else if (parser_nasm->objfmt->directive(name, valparams, - objext_valparams, parser_nasm->object, line)) { + } else if (yasm_objfmt_directive(parser_nasm->objfmt, name, valparams, + objext_valparams, line)) { yasm__error(line, N_("unrecognized directive [%s]"), name); } diff --git a/modules/parsers/nasm/nasm-parser.c b/modules/parsers/nasm/nasm-parser.c index 1b6b60ed..6f433a04 100644 --- a/modules/parsers/nasm/nasm-parser.c +++ b/modules/parsers/nasm/nasm-parser.c @@ -44,15 +44,12 @@ nasm_parser_do_parse(yasm_object *object, yasm_preproc *pp, yasm_arch *a, parser_nasm.linemap = yasm_object_get_linemap(parser_nasm.object); parser_nasm.symtab = yasm_object_get_symtab(parser_nasm.object); - yasm_linemap_set(parser_nasm.linemap, in_filename, 1, 1); - - pp->initialize(f, in_filename, parser_nasm.linemap); parser_nasm.in = f; - parser_nasm.input = pp->input; parser_nasm.locallabel_base = (char *)NULL; parser_nasm.locallabel_base_len = 0; + parser_nasm.preproc = pp; parser_nasm.arch = a; parser_nasm.objfmt = of; diff --git a/modules/parsers/nasm/nasm-parser.h b/modules/parsers/nasm/nasm-parser.h index 43d90ccc..39f87206 100644 --- a/modules/parsers/nasm/nasm-parser.h +++ b/modules/parsers/nasm/nasm-parser.h @@ -40,7 +40,6 @@ typedef struct Scanner { typedef struct yasm_parser_nasm { FILE *in; int debug; - size_t (*input) (char *buf, size_t max_size); /*@only@*/ yasm_object *object; /*@dependent@*/ yasm_section *cur_section; @@ -49,6 +48,7 @@ typedef struct yasm_parser_nasm { /*@null@*/ char *locallabel_base; size_t locallabel_base_len; + /*@dependent@*/ yasm_preproc *preproc; /*@dependent@*/ yasm_arch *arch; /*@dependent@*/ yasm_objfmt *objfmt; diff --git a/modules/parsers/nasm/nasm-token.re b/modules/parsers/nasm/nasm-token.re index 582813a7..a1287845 100644 --- a/modules/parsers/nasm/nasm-token.re +++ b/modules/parsers/nasm/nasm-token.re @@ -84,7 +84,8 @@ fill(yasm_parser_nasm *parser_nasm, YYCTYPE *cursor) yasm_xfree(s->bot); s->bot = buf; } - if((cnt = parser_nasm->input(s->lim, BSIZE)) == 0){ + if((cnt = yasm_preproc_input(parser_nasm->preproc, s->lim, + BSIZE)) == 0) { s->eof = &s->lim[cnt]; *s->eof++ = '\n'; } s->lim += cnt; diff --git a/modules/preprocs/nasm/nasm-preproc.c b/modules/preprocs/nasm/nasm-preproc.c index 6bd93780..f2978086 100644 --- a/modules/preprocs/nasm/nasm-preproc.c +++ b/modules/preprocs/nasm/nasm-preproc.c @@ -35,15 +35,21 @@ #include "nasm-pp.h" #include "nasm-eval.h" -static FILE *in; +typedef struct yasm_preproc_nasm { + yasm_preproc_base preproc; /* Base structure */ + + FILE *in; + char *line, *linepos; + size_t lineleft; + char *file_name; + long prior_linnum; + int lineinc; +} yasm_preproc_nasm; static yasm_linemap *cur_lm; -static char *line, *linepos; -static size_t lineleft; -static char *file_name; -static long prior_linnum; -static int lineinc; int tasm_compatible_mode = 0; +yasm_preproc_module yasm_nasm_LTX_preproc; + static void nil_listgen_init(char *p, efunc e) @@ -112,86 +118,96 @@ nasm_efunc(int severity, const char *fmt, ...) va_end(va); } -static void -nasm_preproc_initialize(FILE *f, const char *in_filename, yasm_linemap *lm) +static yasm_preproc * +nasm_preproc_create(FILE *f, const char *in_filename, yasm_linemap *lm) { - in = f; + yasm_preproc_nasm *preproc_nasm = yasm_xmalloc(sizeof(yasm_preproc_nasm)); + + preproc_nasm->preproc.module = &yasm_nasm_LTX_preproc; + + preproc_nasm->in = f; cur_lm = lm; - line = NULL; - file_name = NULL; - prior_linnum = 0; - lineinc = 0; + preproc_nasm->line = NULL; + preproc_nasm->file_name = NULL; + preproc_nasm->prior_linnum = 0; + preproc_nasm->lineinc = 0; nasmpp.reset(f, in_filename, 2, nasm_efunc, nasm_evaluate, &nil_list); + + return (yasm_preproc *)preproc_nasm; } static void -nasm_preproc_cleanup(void) +nasm_preproc_destroy(yasm_preproc *preproc) { nasmpp.cleanup(0); nasm_eval_cleanup(); + yasm_xfree(preproc); } static size_t -nasm_preproc_input(char *buf, size_t max_size) +nasm_preproc_input(yasm_preproc *preproc, char *buf, size_t max_size) { + yasm_preproc_nasm *preproc_nasm = (yasm_preproc_nasm *)preproc; size_t tot = 0, n; - long linnum = prior_linnum += lineinc; + long linnum = preproc_nasm->prior_linnum += preproc_nasm->lineinc; int altline; - if (!line) { - line = nasmpp.getline(); - if (!line) + if (!preproc_nasm->line) { + preproc_nasm->line = nasmpp.getline(); + if (!preproc_nasm->line) return 0; - linepos = line; - lineleft = strlen(line) + 1; - line[lineleft-1] = '\n'; + preproc_nasm->linepos = preproc_nasm->line; + preproc_nasm->lineleft = strlen(preproc_nasm->line) + 1; + preproc_nasm->line[preproc_nasm->lineleft-1] = '\n'; } - altline = nasm_src_get(&linnum, &file_name); + altline = nasm_src_get(&linnum, &preproc_nasm->file_name); if (altline) { - if (altline == 1 && lineinc == 1) { + if (altline == 1 && preproc_nasm->lineinc == 1) { *buf++ = '\n'; max_size--; tot++; } else { - lineinc = (altline != -1 || lineinc != 1); - n = sprintf(buf, "%%line %ld+%d %s\n", linnum, lineinc, file_name); + preproc_nasm->lineinc = + (altline != -1 || preproc_nasm->lineinc != 1); + n = sprintf(buf, "%%line %ld+%d %s\n", linnum, + preproc_nasm->lineinc, preproc_nasm->file_name); buf += n; max_size -= n; tot += n; } - prior_linnum = linnum; + preproc_nasm->prior_linnum = linnum; } - n = lineleftlineleftlineleft:max_size; + strncpy(buf, preproc_nasm->linepos, n); tot += n; - if (n == lineleft) { - yasm_xfree(line); - line = NULL; + if (n == preproc_nasm->lineleft) { + yasm_xfree(preproc_nasm->line); + preproc_nasm->line = NULL; } else { - lineleft -= n; - linepos += n; + preproc_nasm->lineleft -= n; + preproc_nasm->linepos += n; } return tot; } static void -nasm_preproc_add_include_path (const char *path) +nasm_preproc_add_include_path(yasm_preproc *preproc, const char *path) { pp_include_path(path); } static void -nasm_preproc_add_include_file (const char *filename) +nasm_preproc_add_include_file(yasm_preproc *preproc, const char *filename) { pp_pre_include(filename); } static void -nasm_preproc_predefine_macro (const char *macronameval) +nasm_preproc_predefine_macro(yasm_preproc *preproc, const char *macronameval) { char *mnv = yasm__xstrdup(macronameval); pp_pre_define(mnv); @@ -199,7 +215,7 @@ nasm_preproc_predefine_macro (const char *macronameval) } static void -nasm_preproc_undefine_macro (const char *macroname) +nasm_preproc_undefine_macro(yasm_preproc *preproc, const char *macroname) { char *mn = yasm__xstrdup(macroname); pp_pre_undefine(mn); @@ -208,12 +224,12 @@ nasm_preproc_undefine_macro (const char *macroname) /* Define preproc structure -- see preproc.h for details */ -yasm_preproc yasm_nasm_LTX_preproc = { +yasm_preproc_module yasm_nasm_LTX_preproc = { YASM_PREPROC_VERSION, "Real NASM Preprocessor", "nasm", - nasm_preproc_initialize, - nasm_preproc_cleanup, + nasm_preproc_create, + nasm_preproc_destroy, nasm_preproc_input, nasm_preproc_add_include_path, nasm_preproc_add_include_file, diff --git a/modules/preprocs/raw/raw-preproc.c b/modules/preprocs/raw/raw-preproc.c index a455cf7c..2c8ad635 100644 --- a/modules/preprocs/raw/raw-preproc.c +++ b/modules/preprocs/raw/raw-preproc.c @@ -31,58 +31,98 @@ #include -static int is_interactive; -static FILE *in; -static yasm_linemap *cur_lm; +typedef struct yasm_preproc_raw { + yasm_preproc_base preproc; /* base structure */ + + int is_interactive; + FILE *in; + yasm_linemap *cur_lm; +} yasm_preproc_raw; + +yasm_preproc_module yasm_raw_LTX_preproc; int isatty(int); -static void -raw_preproc_initialize(FILE *f, const char *in_filename, yasm_linemap *lm) +static yasm_preproc * +raw_preproc_create(FILE *f, const char *in_filename, yasm_linemap *lm) { - in = f; - cur_lm = lm; + yasm_preproc_raw *preproc_raw = yasm_xmalloc(sizeof(yasm_preproc_raw)); + + preproc_raw->preproc.module = &yasm_raw_LTX_preproc; + preproc_raw->in = f; + preproc_raw->cur_lm = lm; /*@-unrecog@*/ - is_interactive = f ? (isatty(fileno(f)) > 0) : 0; + preproc_raw->is_interactive = f ? (isatty(fileno(f)) > 0) : 0; /*@=unrecog@*/ + + return (yasm_preproc *)preproc_raw; } static void -raw_preproc_cleanup(void) +raw_preproc_destroy(yasm_preproc *preproc) { + yasm_xfree(preproc); } static size_t -raw_preproc_input(char *buf, size_t max_size) +raw_preproc_input(yasm_preproc *preproc, char *buf, size_t max_size) { + yasm_preproc_raw *preproc_raw = (yasm_preproc_raw *)preproc; int c = '*'; size_t n; - if (is_interactive) { - for (n = 0; n < max_size && (c = getc(in)) != EOF && c != '\n'; n++) + if (preproc_raw->is_interactive) { + for (n = 0; n < max_size && (c = getc(preproc_raw->in)) != EOF && + c != '\n'; n++) buf[n] = (char)c; if (c == '\n') buf[n++] = (char)c; - if (c == EOF && ferror(in)) - yasm__error(yasm_linemap_get_current(cur_lm), + if (c == EOF && ferror(preproc_raw->in)) + yasm__error(yasm_linemap_get_current(preproc_raw->cur_lm), N_("error when reading from file")); - } else if (((n = fread(buf, 1, max_size, in)) == 0) && ferror(in)) - yasm__error(yasm_linemap_get_current(cur_lm), + } else if (((n = fread(buf, 1, max_size, preproc_raw->in)) == 0) && + ferror(preproc_raw->in)) + yasm__error(yasm_linemap_get_current(preproc_raw->cur_lm), N_("error when reading from file")); return n; } +static void +raw_preproc_add_include_path(yasm_preproc *preproc, const char *path) +{ + /* no include paths */ +} + +static void +raw_preproc_add_include_file(yasm_preproc *preproc, const char *filename) +{ + /* no pre-include files */ +} + +static void +raw_preproc_predefine_macro(yasm_preproc *preproc, const char *macronameval) +{ + /* no pre-defining macros */ +} + +static void +raw_preproc_undefine_macro(yasm_preproc *preproc, const char *macroname) +{ + /* no undefining macros */ +} + + /* Define preproc structure -- see preproc.h for details */ -yasm_preproc yasm_raw_LTX_preproc = { +yasm_preproc_module yasm_raw_LTX_preproc = { YASM_PREPROC_VERSION, "Disable preprocessing", "raw", - raw_preproc_initialize, - raw_preproc_cleanup, + raw_preproc_create, + raw_preproc_destroy, raw_preproc_input, - /* no include paths */ NULL, - /* no pre-include files */ NULL, - /* no predefining macros */ NULL, - /* no undefining macros */ NULL + raw_preproc_add_include_path, + raw_preproc_add_include_file, + raw_preproc_predefine_macro, + raw_preproc_undefine_macro }; -- 2.40.0