From a7b3e155882f0c543504fc80de6abd8542af0331 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Sat, 29 Jan 2005 10:24:23 +0000 Subject: [PATCH] * coff-objfmt.c (win32_objfmt_directive): New function that implements the undocumented (in NASM) win32 object format "export" directive. (yasm_win32_LTX_objfmt): Reference above instead of coff_objfmt_directive. (coff_objfmt_section_switch): Add support for ".drectve" section. (coff_objfmt_init_new_section): Refactored from coff_objfmt_section_switch. * preproc.h (yasm_preproc_module): Add define_builtin for defining macros before standard.mac macros are processed. (yasm_preproc_builtin_define): Add prototype and macro to call above. * raw-preproc.c (raw_preproc_define_builtin): Add (empty). (yasm_raw_LTX_preproc): Use. * nasm-preproc.c (nasm_preproc_define_builtin): Add wrapper around new pp_builtin_define. (yasm_nasm_LTX_preproc): Use. * nasm-pp.h (pp_builtin_define): Add prototype. * nasm-pp.c (builtindef): New list of builtin definitions. (read_line): Iterate through builtindef. (pp_builtin_define): Add to builtindef. * standard.mac: Add wrapper around definition of ORG (only for bin objfmt), add wrappered EXPORT definition. * yasm.c (apply_preproc_builtins): Define __YASM_OBJFMT__ to selected objfmt. (main): Call above in correct places. * export.asm, export.hex, export.errwarn: New test for use of "export" macro and directive. svn path=/trunk/yasm/; revision=1199 --- frontends/yasm/yasm.c | 25 +- libyasm/preproc.h | 15 ++ modules/objfmts/coff/coff-objfmt.c | 105 +++++++-- modules/objfmts/win32/tests/Makefile.inc | 3 + modules/objfmts/win32/tests/export.asm | 5 + modules/objfmts/win32/tests/export.errwarn | 0 modules/objfmts/win32/tests/export.hex | 255 +++++++++++++++++++++ modules/preprocs/nasm/nasm-pp.c | 48 +++- modules/preprocs/nasm/nasm-pp.h | 1 + modules/preprocs/nasm/nasm-preproc.c | 10 +- modules/preprocs/nasm/standard.mac | 8 + modules/preprocs/raw/raw-preproc.c | 9 +- 12 files changed, 455 insertions(+), 29 deletions(-) create mode 100644 modules/objfmts/win32/tests/export.asm create mode 100644 modules/objfmts/win32/tests/export.errwarn create mode 100644 modules/objfmts/win32/tests/export.hex diff --git a/frontends/yasm/yasm.c b/frontends/yasm/yasm.c index a5129b77..b56c88da 100644 --- a/frontends/yasm/yasm.c +++ b/frontends/yasm/yasm.c @@ -38,6 +38,8 @@ #include "yasm-options.h" +#define DEFAULT_OBJFMT_MODULE "bin" + /* Preprocess-only buffer size */ #define PREPROC_BUF_SIZE 16384 @@ -105,6 +107,7 @@ static void print_yasm_error(const char *filename, unsigned long line, static void print_yasm_warning(const char *filename, unsigned long line, const char *msg); +static void apply_preproc_builtins(void); static void apply_preproc_saved_options(void); static void print_list_keyword_desc(const char *name, const char *keyword); @@ -320,6 +323,7 @@ main(int argc, char *argv[]) return EXIT_FAILURE; } + apply_preproc_builtins(); apply_preproc_saved_options(); /* Pre-process until done */ @@ -406,7 +410,7 @@ main(int argc, char *argv[]) /* If not already specified, default to bin as the object format. */ if (!cur_objfmt_module) - cur_objfmt_module = yasm_load_objfmt("bin"); + cur_objfmt_module = yasm_load_objfmt(DEFAULT_OBJFMT_MODULE); if (!cur_objfmt_module) { print_error(_("%s: could not load default %s"), _("FATAL"), @@ -531,6 +535,7 @@ main(int argc, char *argv[]) cur_preproc = cur_preproc_module->create(in, in_filename, yasm_object_get_linemap(object)); + apply_preproc_builtins(); apply_preproc_saved_options(); /* Get initial x86 BITS setting from object format */ @@ -946,6 +951,24 @@ opt_ewmsg_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra) return 0; } +static void +apply_preproc_builtins() +{ + char *predef; + const char *objfmt_keyword = DEFAULT_OBJFMT_MODULE; + + if (cur_objfmt_module) + objfmt_keyword = cur_objfmt_module->keyword; + + /* Define standard YASM assembly-time macro constants */ + predef = yasm_xmalloc(strlen("__YASM_OBJFMT__=") + + strlen(objfmt_keyword) + 1); + strcpy(predef, "__YASM_OBJFMT__="); + strcat(predef, objfmt_keyword); + yasm_preproc_define_builtin(cur_preproc, predef); + yasm_xfree(predef); +} + static void apply_preproc_saved_options() { diff --git a/libyasm/preproc.h b/libyasm/preproc.h index d7f83050..b487fa98 100644 --- a/libyasm/preproc.h +++ b/libyasm/preproc.h @@ -97,6 +97,11 @@ typedef struct yasm_preproc_module { * Call yasm_preproc_undefine_macro() instead of calling this function. */ void (*undefine_macro) (yasm_preproc *preproc, const char *macroname); + + /** Module-level implementation of yasm_preproc_builtin_define(). + * Call yasm_preproc_builtin_define() instead of calling this function. + */ + void (*define_builtin) (yasm_preproc *preproc, const char *macronameval); } yasm_preproc_module; /** Initialize preprocessor. @@ -153,6 +158,13 @@ void yasm_preproc_predefine_macro(yasm_preproc *preproc, */ void yasm_preproc_undefine_macro(yasm_preproc *preproc, const char *macroname); +/** Define a builtin macro, preprocessed before the "standard" macros. + * \param preproc preprocessor + * \param macronameval "name=value" string + */ +void yasm_preproc_builtin_define(yasm_preproc *preproc, + const char *macronameval); + #ifndef YASM_DOXYGEN /* Inline macro implementations for preproc functions */ @@ -173,6 +185,9 @@ void yasm_preproc_undefine_macro(yasm_preproc *preproc, const char *macroname); macronameval) #define yasm_preproc_undefine_macro(preproc, macroname) \ ((yasm_preproc_base *)preproc)->module->undefine_macro(preproc, macroname) +#define yasm_preproc_define_builtin(preproc, macronameval) \ + ((yasm_preproc_base *)preproc)->module->define_builtin(preproc, \ + macronameval) #endif diff --git a/modules/objfmts/coff/coff-objfmt.c b/modules/objfmts/coff/coff-objfmt.c index 1e5bcc07..4560276e 100644 --- a/modules/objfmts/coff/coff-objfmt.c +++ b/modules/objfmts/coff/coff-objfmt.c @@ -918,6 +918,32 @@ coff_objfmt_destroy(yasm_objfmt *objfmt) yasm_xfree(objfmt); } +static void +coff_objfmt_init_new_section(yasm_objfmt_coff *objfmt_coff, + yasm_section *sect, const char *sectname, + unsigned long flags, unsigned long line) +{ + coff_section_data *data; + yasm_symrec *sym; + + data = yasm_xmalloc(sizeof(coff_section_data)); + data->scnum = objfmt_coff->parse_scnum++; + data->flags = flags; + data->addr = 0; + data->scnptr = 0; + data->size = 0; + data->relptr = 0; + data->nreloc = 0; + yasm_section_add_data(sect, &coff_section_data_cb, data); + + sym = yasm_symtab_define_label(objfmt_coff->symtab, sectname, + yasm_section_bcs_first(sect), 1, line); + yasm_symrec_declare(sym, YASM_SYM_GLOBAL, line); + coff_objfmt_sym_set_data(sym, COFF_SCL_STAT, NULL, 1, + COFF_SYMTAB_AUX_SECT); + data->sym = sym; +} + static /*@observer@*/ /*@null@*/ yasm_section * coff_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, /*@unused@*/ /*@null@*/ @@ -999,6 +1025,10 @@ coff_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, else yasm__warning(YASM_WARN_GENERAL, line, N_("Standard COFF does not support read-only data sections")); + } else if (strcmp(sectname, ".drectve") == 0) { + flags = COFF_STYP_INFO; + if (objfmt_coff->win32) + flags |= COFF_STYP_DISCARD | COFF_STYP_READ; } else { /* Default to code */ flags = COFF_STYP_TEXT; @@ -1097,28 +1127,10 @@ coff_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, 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 = objfmt_coff->parse_scnum++; - data->flags = flags; - data->addr = 0; - data->scnptr = 0; - data->size = 0; - data->relptr = 0; - data->nreloc = 0; - yasm_section_add_data(retval, &coff_section_data_cb, data); - - sym = - yasm_symtab_define_label(objfmt_coff->symtab, sectname, - yasm_section_bcs_first(retval), 1, line); - yasm_symrec_declare(sym, YASM_SYM_GLOBAL, line); - coff_objfmt_sym_set_data(sym, COFF_SCL_STAT, NULL, 1, - COFF_SYMTAB_AUX_SECT); - data->sym = sym; - } else if (flags_override) + if (isnew) + coff_objfmt_init_new_section(objfmt_coff, retval, sectname, flags, + line); + else if (flags_override) yasm__warning(YASM_WARN_GENERAL, line, N_("section flags ignored on section redeclaration")); return retval; @@ -1245,6 +1257,53 @@ coff_objfmt_directive(/*@unused@*/ yasm_objfmt *objfmt, return 1; /* no objfmt directives */ } +static int +win32_objfmt_directive(yasm_objfmt *objfmt, const char *name, + yasm_valparamhead *valparams, + /*@unused@*/ /*@null@*/ + yasm_valparamhead *objext_valparams, + unsigned long line) +{ + yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)objfmt; + + if (yasm__strcasecmp(name, "export") == 0) { + yasm_valparam *vp = yasm_vps_first(valparams); + int isnew; + yasm_section *sect; + yasm_datavalhead dvs; + + /* Reference exported symbol (to generate error if not declared) */ + if (vp->val) + yasm_symtab_use(objfmt_coff->symtab, vp->val, line); + else { + yasm__error(line, N_("argument to EXPORT must be symbol name")); + return 0; + } + + /* Add to end of linker directives */ + sect = yasm_object_get_general(objfmt_coff->object, ".drectve", 0, 0, + &isnew, line); + + /* Initialize directive section if needed */ + if (isnew) + coff_objfmt_init_new_section(objfmt_coff, sect, + yasm_section_get_name(sect), + COFF_STYP_INFO | COFF_STYP_DISCARD + | COFF_STYP_READ, line); + + /* Add text as data bytecode */ + yasm_dvs_initialize(&dvs); + yasm_dvs_append(&dvs, + yasm_dv_create_string(yasm__xstrdup("-export:"))); + yasm_dvs_append(&dvs, yasm_dv_create_string(yasm__xstrdup(vp->val))); + yasm_dvs_append(&dvs, yasm_dv_create_string(yasm__xstrdup(" "))); + yasm_section_bcs_append(sect, yasm_bc_create_data(&dvs, 1, line)); + + return 0; + } else + return 1; +} + /* Define valid debug formats to use with this object format */ static const char *coff_objfmt_dbgfmt_keywords[] = { @@ -1287,5 +1346,5 @@ yasm_objfmt_module yasm_win32_LTX_objfmt = { coff_objfmt_extern_declare, coff_objfmt_global_declare, coff_objfmt_common_declare, - coff_objfmt_directive + win32_objfmt_directive }; diff --git a/modules/objfmts/win32/tests/Makefile.inc b/modules/objfmts/win32/tests/Makefile.inc index d40aeed6..0fdd0353 100644 --- a/modules/objfmts/win32/tests/Makefile.inc +++ b/modules/objfmts/win32/tests/Makefile.inc @@ -2,6 +2,9 @@ TESTS += modules/objfmts/win32/tests/win32_test.sh +EXTRA_DIST += modules/objfmts/win32/tests/export.asm +EXTRA_DIST += modules/objfmts/win32/tests/export.hex +EXTRA_DIST += modules/objfmts/win32/tests/export.errwarn EXTRA_DIST += modules/objfmts/win32/tests/win32_test.sh EXTRA_DIST += modules/objfmts/win32/tests/win32test.c EXTRA_DIST += modules/objfmts/win32/tests/win32test.asm diff --git a/modules/objfmts/win32/tests/export.asm b/modules/objfmts/win32/tests/export.asm new file mode 100644 index 00000000..0db05059 --- /dev/null +++ b/modules/objfmts/win32/tests/export.asm @@ -0,0 +1,5 @@ +export foo +export foo2 +global foo2 +foo: +foo2: diff --git a/modules/objfmts/win32/tests/export.errwarn b/modules/objfmts/win32/tests/export.errwarn new file mode 100644 index 00000000..e69de29b diff --git a/modules/objfmts/win32/tests/export.hex b/modules/objfmts/win32/tests/export.hex new file mode 100644 index 00000000..bcae2219 --- /dev/null +++ b/modules/objfmts/win32/tests/export.hex @@ -0,0 +1,255 @@ +4c +01 +02 +00 +00 +00 +00 +00 +7d +00 +00 +00 +07 +00 +00 +00 +00 +00 +0c +01 +2e +74 +65 +78 +74 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +20 +00 +50 +60 +2e +64 +72 +65 +63 +74 +76 +65 +00 +00 +00 +00 +00 +00 +00 +00 +19 +00 +00 +00 +64 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +02 +00 +42 +2d +65 +78 +70 +6f +72 +74 +3a +66 +6f +6f +20 +2d +65 +78 +70 +6f +72 +74 +3a +66 +6f +6f +32 +20 +2e +66 +69 +6c +65 +00 +00 +00 +00 +00 +00 +00 +fe +ff +00 +00 +67 +01 +2d +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +2e +74 +65 +78 +74 +00 +00 +00 +00 +00 +00 +00 +01 +00 +00 +00 +03 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +2e +64 +72 +65 +63 +74 +76 +65 +00 +00 +00 +00 +02 +00 +00 +00 +03 +01 +19 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +66 +6f +6f +32 +00 +00 +00 +00 +00 +00 +00 +00 +01 +00 +00 +00 +02 +00 +04 +00 +00 +00 diff --git a/modules/preprocs/nasm/nasm-pp.c b/modules/preprocs/nasm/nasm-pp.c index 20a760d1..4e075331 100644 --- a/modules/preprocs/nasm/nasm-pp.c +++ b/modules/preprocs/nasm/nasm-pp.c @@ -359,6 +359,7 @@ static int pass; /* HACK: pass 0 = generate dependencies only */ static unsigned long unique; /* unique identifier numbers */ +static Line *builtindef = NULL; static Line *predef = NULL; static ListGen *list; @@ -646,6 +647,26 @@ read_line(void) char *buffer, *p, *q; int bufsize, continued_count; + Line *pd, *l; + Token *head, **tail, *t; + + /* Nasty hack for builtin defines */ + for (pd = builtindef; pd; pd = pd->next) + { + head = NULL; + tail = &head; + for (t = pd->first; t; t = t->next) + { + *tail = new_Token(NULL, t->type, t->text, 0); + tail = &(*tail)->next; + } + l = nasm_malloc(sizeof(Line)); + l->next = istk->expansion; + l->first = head; + l->finishes = FALSE; + istk->expansion = l; + } + if (stdmacpos) { if (*stdmacpos) @@ -665,9 +686,6 @@ read_line(void) */ if (!*stdmacpos) { - Line *pd, *l; - Token *head, **tail, *t; - for (pd = predef; pd; pd = pd->next) { head = NULL; @@ -4422,6 +4440,7 @@ pp_cleanup(int pass_) ctx_pop(); if (pass_ == 0) { + free_llist(builtindef); free_llist(predef); delete_Blocks(); } @@ -4506,6 +4525,29 @@ pp_pre_undefine(char *definition) predef = l; } +void +pp_builtin_define(char *definition) +{ + Token *def, *space; + Line *l; + char *equals; + + equals = strchr(definition, '='); + space = new_Token(NULL, TOK_WHITESPACE, NULL, 0); + def = new_Token(space, TOK_PREPROC_ID, "%define", 0); + if (equals) + *equals = ' '; + space->next = tokenise(definition); + if (equals) + *equals = '='; + + l = nasm_malloc(sizeof(Line)); + l->next = builtindef; + l->first = def; + l->finishes = FALSE; + builtindef = l; +} + void pp_extra_stdmac(const char **macros) { diff --git a/modules/preprocs/nasm/nasm-pp.h b/modules/preprocs/nasm/nasm-pp.h index e4d56e12..5eb580e8 100644 --- a/modules/preprocs/nasm/nasm-pp.h +++ b/modules/preprocs/nasm/nasm-pp.h @@ -13,6 +13,7 @@ void pp_include_path (const char *); void pp_pre_include (const char *); void pp_pre_define (char *); void pp_pre_undefine (char *); +void pp_builtin_define (char *); void pp_extra_stdmac (const char **); extern Preproc nasmpp; diff --git a/modules/preprocs/nasm/nasm-preproc.c b/modules/preprocs/nasm/nasm-preproc.c index 088cc355..48b80f1d 100644 --- a/modules/preprocs/nasm/nasm-preproc.c +++ b/modules/preprocs/nasm/nasm-preproc.c @@ -222,6 +222,13 @@ nasm_preproc_undefine_macro(yasm_preproc *preproc, const char *macroname) yasm_xfree(mn); } +static void +nasm_preproc_define_builtin(yasm_preproc *preproc, const char *macronameval) +{ + char *mnv = yasm__xstrdup(macronameval); + pp_builtin_define(mnv); + yasm_xfree(mnv); +} /* Define preproc structure -- see preproc.h for details */ yasm_preproc_module yasm_nasm_LTX_preproc = { @@ -233,5 +240,6 @@ yasm_preproc_module yasm_nasm_LTX_preproc = { nasm_preproc_add_include_path, nasm_preproc_add_include_file, nasm_preproc_predefine_macro, - nasm_preproc_undefine_macro + nasm_preproc_undefine_macro, + nasm_preproc_define_builtin }; diff --git a/modules/preprocs/nasm/standard.mac b/modules/preprocs/nasm/standard.mac index 26d77f7a..cdb88f35 100644 --- a/modules/preprocs/nasm/standard.mac +++ b/modules/preprocs/nasm/standard.mac @@ -107,7 +107,15 @@ __SECT__ [cpu %1] %endmacro +%ifidn __YASM_OBJFMT__,bin %imacro org 1+.nolist [org %1] %endmacro +%endif + +%ifidn __YASM_OBJFMT__,win32 +%imacro export 1+.nolist +[export %1] +%endmacro +%endif diff --git a/modules/preprocs/raw/raw-preproc.c b/modules/preprocs/raw/raw-preproc.c index 85e6a926..7246f629 100644 --- a/modules/preprocs/raw/raw-preproc.c +++ b/modules/preprocs/raw/raw-preproc.c @@ -112,6 +112,12 @@ raw_preproc_undefine_macro(yasm_preproc *preproc, const char *macroname) /* no undefining macros */ } +static void +raw_preproc_define_builtin(yasm_preproc *preproc, const char *macronameval) +{ + /* no builtin defines */ +} + /* Define preproc structure -- see preproc.h for details */ yasm_preproc_module yasm_raw_LTX_preproc = { @@ -123,5 +129,6 @@ yasm_preproc_module yasm_raw_LTX_preproc = { raw_preproc_add_include_path, raw_preproc_add_include_file, raw_preproc_predefine_macro, - raw_preproc_undefine_macro + raw_preproc_undefine_macro, + raw_preproc_define_builtin }; -- 2.40.0