]> granicus.if.org Git - yasm/commitdiff
Massive libyasm / module interface update - Phase 1
authorPeter Johnson <peter@tortall.net>
Thu, 2 Oct 2003 05:03:50 +0000 (05:03 -0000)
committerPeter Johnson <peter@tortall.net>
Thu, 2 Oct 2003 05:03:50 +0000 (05:03 -0000)
As yasm has evolved, various minor additions have been made to libyasm to
support the new features.  These minor additions have accumulated, and
some contain significant redundancies.  In addition, the core focus of
yasm has begun to move away from the front-end commandline program "yasm"
to focusing on libyasm, a collection of reusable routines for use in all
sorts of programs dealing with code at the assembly level, and the modules
that provide specific features for parsing such code.

This libyasm/module update focuses on cleaning up much of the cruft that
has accumulated in libyasm, standardizing function names, eliminating
redundancies, making many of the core objects more reusable for future
extensions, and starting to make libyasm and the modules thread-safe by
eliminating static variables.

Specific changes include:
 - Making a symbol table data structure (no longer global).  It follows a
   factory model for creating symrecs.
 - Label symbols now refer only to bytecodes; bytecodes have a pointer to
   their containing section.
 - Standardizing on *_create() and *_destroy() for allocation/deallocation.
 - Adding a standardized callback mechanism for all data structures that
   allow associated data.  Allowed the removal of objfmt and
   dbgfmt-specific data callbacks in their interfaces.
 - Unmodularizing linemgr, but allowing multiple linemap instances (linemgr
   is now renamed linemap).
 - Remove references to lindex; all virtual lines (from linemap) are now
   just "line"s.
 - Eliminating the bytecode "type" enum, instead adding a standardized
   callback mechanism for custom (and standard internal) bytecode types.
   This will make it much easier to add new bytecodes, and eliminate the
   possibility of type collisions.  This also allowed the removal of the
   of_data and df_data bytecodes, as objfmts and dbgfmts can now easily
   implement their own bytecodes, and the cleanup of arch's bytecode usage.
 - Remove the bytecodehead and sectionhead pseudo-containers, instead
   making true containers: section now implements all the functions of
   bytecodehead, and the new object data structure implements all the
   functions of sectionhead.
 - Add object data structure: it's a container that contains sections, a
   symbol table, and a line mapping for a single object.  Every former use
   of sectionhead now takes an object.
 - Make arch interface and all standard architectures thread-safe:
   yasm_arch_module is the module interface; it contains a create()
   function that returns a yasm_arch * to store local yasm_arch data; all
   yasm_arch_module functions take the yasm_arch *.
 - Make nasm parser thread-safe.

To be done in phase 2: making other module interfaces thread-safe.  Note
that while the module interface may be thread-safe, not all modules may be
written in such a fashion (hopefully all the "standard" ones will be, but
this is yet to be determined).

svn path=/trunk/yasm/; revision=1058

63 files changed:
frontends/yasm/yasm-module.c
frontends/yasm/yasm-module.h
frontends/yasm/yasm.c
libyasm/Makefile.inc
libyasm/arch.c
libyasm/arch.h
libyasm/assocdat.c [new file with mode: 0644]
libyasm/assocdat.h [new file with mode: 0644]
libyasm/bc-int.h
libyasm/bitvect.c
libyasm/bitvect.h
libyasm/bytecode.c
libyasm/bytecode.h
libyasm/coretype.h
libyasm/dbgfmt.h
libyasm/errwarn.c
libyasm/errwarn.h
libyasm/expr.c
libyasm/expr.h
libyasm/floatnum.c
libyasm/floatnum.h
libyasm/hamt.c
libyasm/hamt.h
libyasm/intnum.c
libyasm/intnum.h
libyasm/linemgr.c
libyasm/linemgr.h
libyasm/objfmt.c [new file with mode: 0644]
libyasm/objfmt.h
libyasm/optimizer.h
libyasm/parser.h
libyasm/preproc.h
libyasm/section.c
libyasm/section.h
libyasm/symrec.c
libyasm/symrec.h
libyasm/tests/floatnum_test.c
libyasm/valparam.c
libyasm/valparam.h
modules/arch/lc3b/lc3barch.c
modules/arch/lc3b/lc3barch.h
modules/arch/lc3b/lc3bbc.c
modules/arch/lc3b/lc3bid.re
modules/arch/x86/x86arch.c
modules/arch/x86/x86arch.h
modules/arch/x86/x86bc.c
modules/arch/x86/x86expr.c
modules/arch/x86/x86id.re
modules/dbgfmts/null/null-dbgfmt.c
modules/dbgfmts/stabs/stabs-dbgfmt.c
modules/objfmts/bin/bin-objfmt.c
modules/objfmts/coff/coff-objfmt.c
modules/objfmts/dbg/dbg-objfmt.c
modules/objfmts/elf/elf-objfmt.c
modules/objfmts/elf/elf.c
modules/objfmts/elf/elf.h
modules/optimizers/basic/basic-optimizer.c
modules/parsers/nasm/nasm-bison.y
modules/parsers/nasm/nasm-parser.c
modules/parsers/nasm/nasm-parser.h
modules/parsers/nasm/nasm-token.re
modules/preprocs/nasm/nasm-preproc.c
modules/preprocs/raw/raw-preproc.c

index 309ca9283e22e99acbe1472f1738c7dee88dfada..543fb8f7ac2a2460f827c9bec16134168a5a6d9e 100644 (file)
@@ -169,11 +169,11 @@ list_module_load(const char *filename, lt_ptr data)
     const char *module_keyword = NULL, *module_name = NULL;
     char *name;
 
-    yasm_arch *arch;
+    yasm_arch_module *arch_module;
     yasm_dbgfmt *dbgfmt;
     yasm_objfmt *objfmt;
     yasm_optimizer *optimizer;
-    yasm_parser *parser;
+    yasm_parser_module *parser_module;
     yasm_preproc *preproc;
 
     lt_dlhandle handle;
@@ -211,10 +211,10 @@ list_module_load(const char *filename, lt_ptr data)
     switch (lmdata->type) {
        case MODULE_ARCH:
            strncpy(name, "yasm", 4);
-           arch = lt_dlsym(handle, name);
-           if (arch) {
-               module_keyword = arch->keyword;
-               module_name = arch->name;
+           arch_module = lt_dlsym(handle, name);
+           if (arch_module) {
+               module_keyword = arch_module->keyword;
+               module_name = arch_module->name;
            }
            break;
        case MODULE_DBGFMT:
@@ -243,10 +243,10 @@ list_module_load(const char *filename, lt_ptr data)
            break;
        case MODULE_PARSER:
            strncpy(name+2, "yasm", 4);
-           parser = lt_dlsym(handle, name+2);
-           if (parser) {
-               module_keyword = parser->keyword;
-               module_name = parser->name;
+           parser_module = lt_dlsym(handle, name+2);
+           if (parser_module) {
+               module_keyword = parser_module->keyword;
+               module_name = parser_module->name;
            }
            break;
        case MODULE_PREPROC:
index 304afa04e3465c6cfedda563e9d0426dd7d040a6..49ca7a4a8cba63705d73952ba607f334dff0347b 100644 (file)
@@ -40,14 +40,14 @@ void unload_modules(void);
 /*@dependent@*/ /*@null@*/ void *get_module_data
     (module_type type, const char *keyword, const char *symbol);
 
-#define load_arch(keyword)     get_module_data(MODULE_ARCH, keyword, "arch")
+#define load_arch_module(keyword)      get_module_data(MODULE_ARCH, keyword, "arch")
 #define load_dbgfmt(keyword)   \
     get_module_data(MODULE_DBGFMT, keyword, "dbgfmt")
 #define load_objfmt(keyword)   \
     get_module_data(MODULE_OBJFMT, keyword, "objfmt")
 #define load_optimizer(keyword)        \
     get_module_data(MODULE_OPTIMIZER, keyword, "optimizer")
-#define load_parser(keyword)   \
+#define load_parser_module(keyword)    \
     get_module_data(MODULE_PARSER, keyword, "parser")
 #define load_preproc(keyword)  \
     get_module_data(MODULE_PREPROC, keyword, "preproc")
index f3d26a5766351dec6ae1fa38c96b4e22ea3890d7..acee6d6f5ee71f13511b44a467357a73072c58c8 100644 (file)
@@ -66,7 +66,8 @@ do { \
 /*@null@*/ /*@only@*/ static char *machine_name = NULL;
 static int special_options = 0;
 /*@null@*/ /*@dependent@*/ static yasm_arch *cur_arch = NULL;
-/*@null@*/ /*@dependent@*/ static yasm_parser *cur_parser = NULL;
+/*@null@*/ /*@dependent@*/ static yasm_arch_module *cur_arch_module = NULL;
+/*@null@*/ /*@dependent@*/ static yasm_parser_module *cur_parser_module = NULL;
 /*@null@*/ /*@dependent@*/ static yasm_preproc *cur_preproc = NULL;
 /*@null@*/ /*@dependent@*/ static yasm_objfmt *cur_objfmt = NULL;
 /*@null@*/ /*@dependent@*/ static yasm_optimizer *cur_optimizer = NULL;
@@ -75,7 +76,7 @@ static int preproc_only = 0;
 static int warning_error = 0;  /* warnings being treated as errors */
 
 /*@null@*/ /*@dependent@*/ static FILE *open_obj(const char *mode);
-static void cleanup(/*@null@*/ yasm_sectionhead *sections);
+static void cleanup(/*@null@*/ yasm_object *object);
 
 /* Forward declarations: cmd line parser handlers */
 static int opt_special_handler(char *cmd, /*@null@*/ char *param, int extra);
@@ -211,7 +212,8 @@ int
 main(int argc, char *argv[])
 {
     /*@null@*/ FILE *in = NULL, *obj = NULL;
-    yasm_sectionhead *sections;
+    yasm_object *object = NULL;
+    yasm_section *def_sect;
     size_t i;
 #ifndef WIN32
     int errors;
@@ -308,22 +310,20 @@ main(int argc, char *argv[])
            in_filename = yasm__xstrdup("-");
     }
 
-    /* Initialize line manager */
-    yasm_std_linemgr.initialize();
-    yasm_std_linemgr.set(in_filename, 1, 1);
-
     /* Initialize intnum and floatnum */
     yasm_intnum_initialize();
     yasm_floatnum_initialize();
 
-    /* Initialize symbol table */
-    yasm_symrec_initialize();
-
     /* handle preproc-only case here */
     if (preproc_only) {
+       yasm_linemap *linemap;
        char *preproc_buf = yasm_xmalloc(PREPROC_BUF_SIZE);
        size_t got;
 
+       /* Initialize line manager */
+       linemap = yasm_linemap_create();
+       yasm_linemap_set(linemap, in_filename, 1, 1);
+
        /* Default output to stdout if not specified */
        if (!obj_filename)
            obj = stdout;
@@ -351,7 +351,7 @@ main(int argc, char *argv[])
        apply_preproc_saved_options();
 
        /* Pre-process until done */
-       cur_preproc->initialize(in, in_filename, &yasm_std_linemgr);
+       cur_preproc->initialize(in, in_filename, linemap);
        while ((got = cur_preproc->input(preproc_buf, PREPROC_BUF_SIZE)) != 0)
            fwrite(preproc_buf, got, 1, obj);
 
@@ -362,39 +362,45 @@ main(int argc, char *argv[])
            fclose(obj);
 
        if (yasm_get_num_errors(warning_error) > 0) {
-           yasm_errwarn_output_all(&yasm_std_linemgr, warning_error,
-                                   print_yasm_error, print_yasm_warning);
+           yasm_errwarn_output_all(linemap, warning_error, print_yasm_error,
+                                   print_yasm_warning);
            if (obj != stdout)
                remove(obj_filename);
            yasm_xfree(preproc_buf);
+           yasm_linemap_destroy(linemap);
            cleanup(NULL);
            return EXIT_FAILURE;
        }
        yasm_xfree(preproc_buf);
+       yasm_linemap_destroy(linemap);
        cleanup(NULL);
        return EXIT_SUCCESS;
     }
 
+    /* Create object */
+    object = yasm_object_create();
+
     /* Default to x86 as the architecture */
-    if (!cur_arch) {
-       cur_arch = load_arch("x86");
-       if (!cur_arch) {
+    if (!cur_arch_module) {
+       cur_arch_module = load_arch_module("x86");
+       if (!cur_arch_module) {
            print_error(_("%s: could not load default %s"), _("FATAL"),
                        _("architecture"));
            return EXIT_FAILURE;
        }
     }
-    check_module_version(cur_arch, ARCH, "arch");
+    check_module_version(cur_arch_module, ARCH, "arch");
 
     /* Set up architecture using the selected (or default) machine */
     if (!machine_name)
-       machine_name = yasm__xstrdup(cur_arch->default_machine_keyword);
-    
-    if (cur_arch->initialize(machine_name)) {
+       machine_name = yasm__xstrdup(cur_arch_module->default_machine_keyword);
+
+    cur_arch = cur_arch_module->create(machine_name);
+    if (!cur_arch) {
        if (strcmp(machine_name, "help") == 0) {
-           yasm_arch_machine *m = cur_arch->machines;
+           yasm_arch_machine *m = cur_arch_module->machines;
            printf(_("Available %s for %s `%s':\n"), _("machines"),
-                  _("architecture"), cur_arch->keyword);
+                  _("architecture"), cur_arch_module->keyword);
            while (m->keyword && m->name) {
                print_list_keyword_desc(m->name, m->keyword);
                m++;
@@ -404,7 +410,7 @@ main(int argc, char *argv[])
 
        print_error(_("%s: `%s' is not a valid %s for %s `%s'"),
                    _("FATAL"), machine_name, _("machine"),
-                   _("architecture"), cur_arch->keyword);
+                   _("architecture"), cur_arch_module->keyword);
        return EXIT_FAILURE;
     }
 
@@ -418,10 +424,6 @@ main(int argc, char *argv[])
     }
     check_module_version(cur_optimizer, OPTIMIZER, "optimizer");
 
-    yasm_arch_common_initialize(cur_arch);
-    yasm_expr_initialize(cur_arch);
-    yasm_bc_initialize(cur_arch);
-
     /* If not already specified, default to bin as the object format. */
     if (!cur_objfmt)
        cur_objfmt = load_objfmt("bin");
@@ -477,8 +479,8 @@ main(int argc, char *argv[])
 
     /* Initialize the debug format */
     if (cur_dbgfmt->initialize) {
-       if (cur_dbgfmt->initialize(in_filename, obj_filename, &yasm_std_linemgr,
-                                  cur_objfmt, cur_arch, machine_name))
+       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'"),
@@ -491,11 +493,11 @@ main(int argc, char *argv[])
 
     /* Initialize the object format */
     if (cur_objfmt->initialize) {
-       if (cur_objfmt->initialize(in_filename, obj_filename, cur_dbgfmt,
-                                  cur_arch, machine_name)) {
+       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->keyword,
+               _("FATAL"), cur_objfmt->keyword, cur_arch_module->keyword,
                machine_name);
            if (in != stdin)
                fclose(in);
@@ -503,34 +505,37 @@ main(int argc, char *argv[])
        }
     }
 
+    /* Add an initial "default" section to object */
+    def_sect = yasm_objfmt_add_default_section(cur_objfmt, object);
+
     /* Default to NASM as the parser */
-    if (!cur_parser) {
-       cur_parser = load_parser("nasm");
-       if (!cur_parser) {
+    if (!cur_parser_module) {
+       cur_parser_module = load_parser_module("nasm");
+       if (!cur_parser_module) {
            print_error(_("%s: could not load default %s"), _("FATAL"),
                        _("parser"));
            cleanup(NULL);
            return EXIT_FAILURE;
        }
     }
-    check_module_version(cur_parser, 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->default_preproc_keyword);
+       cur_preproc = load_preproc(cur_parser_module->default_preproc_keyword);
     else {
        int matched_preproc = 0;
        /* Check to see if the requested preprocessor is in the allowed list
         * for the active parser.
         */
-       for (i=0; cur_parser->preproc_keywords[i]; i++)
-           if (yasm__strcasecmp(cur_parser->preproc_keywords[i],
+       for (i=0; cur_parser_module->preproc_keywords[i]; i++)
+           if (yasm__strcasecmp(cur_parser_module->preproc_keywords[i],
                           cur_preproc->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->keyword);
+                       _("parser"), cur_parser_module->keyword);
            if (in != stdin)
                fclose(in);
            cleanup(NULL);
@@ -549,55 +554,52 @@ main(int argc, char *argv[])
     apply_preproc_saved_options();
 
     /* Get initial x86 BITS setting from object format */
-    if (strcmp(cur_arch->keyword, "x86") == 0) {
-       unsigned char *x86_mode_bits;
-       x86_mode_bits = (unsigned char *)get_module_data(MODULE_ARCH, "x86",
-                                                        "mode_bits");
-       if (x86_mode_bits)
-           *x86_mode_bits = cur_objfmt->default_x86_mode_bits;
+    if (strcmp(cur_arch_module->keyword, "x86") == 0) {
+       cur_arch_module->set_var(cur_arch, "mode_bits",
+                                cur_objfmt->default_x86_mode_bits);
     }
 
     /* Parse! */
-    sections = cur_parser->do_parse(cur_preproc, cur_arch, cur_objfmt,
-                                   &yasm_std_linemgr, in, in_filename, 0);
+    cur_parser_module->do_parse(object, cur_preproc, cur_arch, cur_objfmt, in,
+                               in_filename, 0, def_sect);
 
     /* Close input file */
     if (in != stdin)
        fclose(in);
 
     if (yasm_get_num_errors(warning_error) > 0) {
-       yasm_errwarn_output_all(&yasm_std_linemgr, warning_error,
+       yasm_errwarn_output_all(yasm_object_get_linemap(object), warning_error,
                                print_yasm_error, print_yasm_warning);
-       cleanup(sections);
+       cleanup(object);
        return EXIT_FAILURE;
     }
 
-    yasm_symrec_parser_finalize();
-    cur_optimizer->optimize(sections);
+    yasm_symtab_parser_finalize(yasm_object_get_symtab(object));
+    cur_optimizer->optimize(object);
 
     if (yasm_get_num_errors(warning_error) > 0) {
-       yasm_errwarn_output_all(&yasm_std_linemgr, warning_error,
+       yasm_errwarn_output_all(yasm_object_get_linemap(object), warning_error,
                                print_yasm_error, print_yasm_warning);
-       cleanup(sections);
+       cleanup(object);
        return EXIT_FAILURE;
     }
 
     /* generate any debugging information */
     if (cur_dbgfmt->generate) {
-       cur_dbgfmt->generate(sections);
+       cur_dbgfmt->generate(object);
     }
 
     /* open the object file for output (if not already opened by dbg objfmt) */
     if (!obj && strcmp(cur_objfmt->keyword, "dbg") != 0) {
        obj = open_obj("wb");
        if (!obj) {
-           cleanup(sections);
+           cleanup(object);
            return EXIT_FAILURE;
        }
     }
 
     /* Write the object file */
-    cur_objfmt->output(obj?obj:stderr, sections,
+    cur_objfmt->output(obj?obj:stderr, object,
                       strcmp(cur_dbgfmt->keyword, "null"));
 
     /* Close object file */
@@ -608,17 +610,17 @@ main(int argc, char *argv[])
      * object file (to make sure it's not left newer than the source).
      */
     if (yasm_get_num_errors(warning_error) > 0) {
-       yasm_errwarn_output_all(&yasm_std_linemgr, warning_error,
+       yasm_errwarn_output_all(yasm_object_get_linemap(object), warning_error,
                                print_yasm_error, print_yasm_warning);
        remove(obj_filename);
-       cleanup(sections);
+       cleanup(object);
        return EXIT_FAILURE;
     }
 
-    yasm_errwarn_output_all(&yasm_std_linemgr, warning_error,
+    yasm_errwarn_output_all(yasm_object_get_linemap(object), warning_error,
                            print_yasm_error, print_yasm_warning);
 
-    cleanup(sections);
+    cleanup(object);
     return EXIT_SUCCESS;
 }
 /*@=globstate =unrecog@*/
@@ -645,7 +647,7 @@ open_obj(const char *mode)
 
 /* Cleans up all allocated structures. */
 static void
-cleanup(yasm_sectionhead *sections)
+cleanup(yasm_object *object)
 {
     if (DO_FREE) {
        if (cur_objfmt && cur_objfmt->cleanup)
@@ -654,17 +656,15 @@ cleanup(yasm_sectionhead *sections)
            cur_dbgfmt->cleanup();
        if (cur_preproc)
            cur_preproc->cleanup();
-       if (sections)
-           yasm_sections_delete(sections);
-       yasm_symrec_cleanup();
+       if (object)
+           yasm_object_destroy(object);
        if (cur_arch)
-           cur_arch->cleanup();
+           cur_arch_module->destroy(cur_arch);
 
        yasm_floatnum_cleanup();
        yasm_intnum_cleanup();
 
        yasm_errwarn_cleanup();
-       yasm_std_linemgr.cleanup();
 
        BitVector_Shutdown();
     }
@@ -715,8 +715,8 @@ static int
 opt_arch_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra)
 {
     assert(param != NULL);
-    cur_arch = load_arch(param);
-    if (!cur_arch) {
+    cur_arch_module = load_arch_module(param);
+    if (!cur_arch_module) {
        if (!strcmp("help", param)) {
            printf(_("Available yasm %s:\n"), _("architectures"));
            list_archs(print_list_keyword_desc);
@@ -734,8 +734,8 @@ static int
 opt_parser_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra)
 {
     assert(param != NULL);
-    cur_parser = load_parser(param);
-    if (!cur_parser) {
+    cur_parser_module = load_parser_module(param);
+    if (!cur_parser_module) {
        if (!strcmp("help", param)) {
            printf(_("Available yasm %s:\n"), _("parsers"));
            list_parsers(print_list_keyword_desc);
index a961c11243cc1eafe9360d0dd95e9e25fa562017..72785c5eaf708cf1b5935a37a0d49d45ca0a55f8 100644 (file)
@@ -8,6 +8,7 @@ libyasm_la_SOURCES += libyasm/symrec.c
 libyasm_la_SOURCES += libyasm/file.c
 libyasm_la_SOURCES += libyasm/section.c
 libyasm_la_SOURCES += libyasm/arch.c
+libyasm_la_SOURCES += libyasm/objfmt.c
 libyasm_la_SOURCES += libyasm/intnum.c
 libyasm_la_SOURCES += libyasm/floatnum.c
 libyasm_la_SOURCES += libyasm/hamt.c
@@ -15,6 +16,8 @@ libyasm_la_SOURCES += libyasm/bitvect.c
 libyasm_la_SOURCES += libyasm/valparam.c
 libyasm_la_SOURCES += libyasm/errwarn.c
 libyasm_la_SOURCES += libyasm/linemgr.c
+libyasm_la_SOURCES += libyasm/assocdat.c
+libyasm_la_SOURCES += libyasm/assocdat.h
 libyasm_la_SOURCES += libyasm/xmalloc.c
 libyasm_la_SOURCES += libyasm/xstrdup.c
 libyasm_la_SOURCES += libyasm/strcasecmp.c
index 3c5902b2ec68e69d373c29804a34a5dc33bddc46..57fbd4d2d0f2131f9dd2a131194754f3e5e951e1 100644 (file)
@@ -25,8 +25,9 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 #define YASM_LIB_INTERNAL
+#define YASM_ARCH_INTERNAL
 #include "util.h"
-/*@unused@*/ RCSID("$IdPath: yasm/libyasm/arch.c,v 1.11 2003/03/15 05:07:48 peter Exp $");
+/*@unused@*/ RCSID("$IdPath$");
 
 #include "coretype.h"
 
 #include "arch.h"
 
 
-static /*@dependent@*/ yasm_arch *cur_arch;
-
-void
-yasm_arch_common_initialize(yasm_arch *a)
+yasm_arch_module *
+yasm_arch_get_module(yasm_arch *arch)
 {
-    cur_arch = a;
+    return arch->module;
 }
 
 yasm_insn_operand *
-yasm_operand_new_reg(unsigned long reg)
+yasm_operand_create_reg(unsigned long reg)
 {
     yasm_insn_operand *retval = yasm_xmalloc(sizeof(yasm_insn_operand));
 
@@ -59,7 +58,7 @@ yasm_operand_new_reg(unsigned long reg)
 }
 
 yasm_insn_operand *
-yasm_operand_new_segreg(unsigned long segreg)
+yasm_operand_create_segreg(unsigned long segreg)
 {
     yasm_insn_operand *retval = yasm_xmalloc(sizeof(yasm_insn_operand));
 
@@ -72,7 +71,7 @@ yasm_operand_new_segreg(unsigned long segreg)
 }
 
 yasm_insn_operand *
-yasm_operand_new_mem(/*@only@*/ yasm_effaddr *ea)
+yasm_operand_create_mem(/*@only@*/ yasm_effaddr *ea)
 {
     yasm_insn_operand *retval = yasm_xmalloc(sizeof(yasm_insn_operand));
 
@@ -85,15 +84,15 @@ yasm_operand_new_mem(/*@only@*/ yasm_effaddr *ea)
 }
 
 yasm_insn_operand *
-yasm_operand_new_imm(/*@only@*/ yasm_expr *val)
+yasm_operand_create_imm(/*@only@*/ yasm_expr *val)
 {
     yasm_insn_operand *retval;
     const unsigned long *reg;
 
     reg = yasm_expr_get_reg(&val, 0);
     if (reg) {
-       retval = yasm_operand_new_reg(*reg);
-       yasm_expr_delete(val);
+       retval = yasm_operand_create_reg(*reg);
+       yasm_expr_destroy(val);
     } else {
        retval = yasm_xmalloc(sizeof(yasm_insn_operand));
        retval->type = YASM_INSN__OPERAND_IMM;
@@ -106,26 +105,27 @@ yasm_operand_new_imm(/*@only@*/ yasm_expr *val)
 }
 
 void
-yasm_operand_print(FILE *f, int indent_level, const yasm_insn_operand *op)
+yasm_operand_print(const yasm_insn_operand *op, FILE *f, int indent_level,
+                  yasm_arch *arch)
 {
     switch (op->type) {
        case YASM_INSN__OPERAND_REG:
            fprintf(f, "%*sReg=", indent_level, "");
-           cur_arch->reg_print(f, op->data.reg);
+           arch->module->reg_print(arch, op->data.reg, f);
            fprintf(f, "\n");
            break;
        case YASM_INSN__OPERAND_SEGREG:
            fprintf(f, "%*sSegReg=", indent_level, "");
-           cur_arch->segreg_print(f, op->data.reg);
+           arch->module->segreg_print(arch, op->data.reg, f);
            fprintf(f, "\n");
            break;
        case YASM_INSN__OPERAND_MEMORY:
            fprintf(f, "%*sMemory=\n", indent_level, "");
-           yasm_ea_print(f, indent_level, op->data.ea);
+           yasm_ea_print(op->data.ea, f, indent_level);
            break;
        case YASM_INSN__OPERAND_IMM:
            fprintf(f, "%*sImm=", indent_level, "");
-           yasm_expr_print(f, op->data.val);
+           yasm_expr_print(op->data.val, f);
            fprintf(f, "\n");
            break;
     }
@@ -144,10 +144,10 @@ yasm_ops_delete(yasm_insn_operandhead *headp, int content)
        if (content)
            switch (cur->type) {
                case YASM_INSN__OPERAND_MEMORY:
-                   yasm_ea_delete(cur->data.ea);
+                   yasm_ea_destroy(cur->data.ea);
                    break;
                case YASM_INSN__OPERAND_IMM:
-                   yasm_expr_delete(cur->data.val);
+                   yasm_expr_destroy(cur->data.val);
                    break;
                default:
                    break;
@@ -170,20 +170,28 @@ yasm_ops_append(yasm_insn_operandhead *headp,
 }
 
 void
-yasm_ops_print(FILE *f, int indent_level, const yasm_insn_operandhead *headp)
+yasm_ops_print(const yasm_insn_operandhead *headp, FILE *f, int indent_level,
+              yasm_arch *arch)
 {
     yasm_insn_operand *cur;
 
     STAILQ_FOREACH (cur, headp, link)
-       yasm_operand_print(f, indent_level, cur);
+       yasm_operand_print(cur, f, indent_level, arch);
+}
+
+yasm_insn_operandhead *
+yasm_ops_create(void)
+{
+    yasm_insn_operandhead *headp = yasm_xmalloc(sizeof(yasm_insn_operandhead));
+    yasm_ops_initialize(headp);
+    return headp;
 }
 
-/* Non-macro yasm_ops_initialize() for non-YASM_LIB_INTERNAL users. */
-#undef yasm_ops_initialize
 void
-yasm_ops_initialize(yasm_insn_operandhead *headp)
+yasm_ops_destroy(yasm_insn_operandhead *headp, int content)
 {
-    STAILQ_INIT(headp);
+    yasm_ops_delete(headp, content);
+    yasm_xfree(headp);
 }
 
 /* Non-macro yasm_ops_first() for non-YASM_LIB_INTERNAL users. */
@@ -194,10 +202,10 @@ yasm_ops_first(yasm_insn_operandhead *headp)
     return STAILQ_FIRST(headp);
 }
 
-/* Non-macro yasm_ops_next() for non-YASM_LIB_INTERNAL users. */
-#undef yasm_ops_next
+/* Non-macro yasm_operand_next() for non-YASM_LIB_INTERNAL users. */
+#undef yasm_operand_next
 yasm_insn_operand *
-yasm_ops_next(yasm_insn_operand *cur)
+yasm_operand_next(yasm_insn_operand *cur)
 {
     return STAILQ_NEXT(cur, link);
 }
index e3a2ba17c51b9e75115499af8179744d5816e1f8..3c790c873e1016820e1c842a6c2b94c765655a62 100644 (file)
@@ -34,7 +34,7 @@
 #ifndef YASM_ARCH_H
 #define YASM_ARCH_H
 
-/** Return value from yasm_arch::parse_check_id(). */
+/** Return value from yasm_arch_module::parse_check_id(). */
 typedef enum {
     YASM_ARCH_CHECK_ID_NONE = 0,       /**< Just a normal identifier. */
     YASM_ARCH_CHECK_ID_INSN,           /**< An instruction. */
@@ -54,6 +54,14 @@ typedef struct yasm_insn_operandhead yasm_insn_operandhead;
 /*@reldef@*/ STAILQ_HEAD(yasm_insn_operandhead, yasm_insn_operand);
 #endif
 
+/** Base #yasm_arch structure.  Must be present as the first element in any
+ * #yasm_arch implementation.
+ */
+struct yasm_arch {
+    /** #yasm_arch_module implementation for this architecture. */
+    struct yasm_arch_module *module;
+};
+
 /** "Flavor" of the parser.
  * Different assemblers order instruction operands differently.  Also, some
  * differ on how exactly various registers are specified.  There's no great
@@ -84,24 +92,24 @@ typedef struct yasm_arch_machine {
     const char *keyword;
 } yasm_arch_machine;
 
-/** Version number of #yasm_arch interface.  Any functional change to the
- * #yasm_arch interface should simultaneously increment this number.  This
- * version should be checked by #yasm_arch 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_arch_module interface.  Any functional change to
+ * the #yasm_arch_module interface should simultaneously increment this number.
+ * This version should be checked by #yasm_arch_module 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_ARCH_VERSION      1
+#define YASM_ARCH_VERSION      2
 
-/** YASM architecture interface.
+/** 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.
  */
-struct yasm_arch {
+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.
@@ -117,20 +125,29 @@ struct yasm_arch {
     /** Initialize architecture for use.
      * \param machine  keyword of machine in use (must be one listed in
      *                 #machines)
-     * \return Nonzero if machine not recognized.
+     * \return NULL if machine not recognized.
      */
-    int (*initialize) (const char *machine);
+    /*@only@*/ yasm_arch * (*create) (const char *machine);
 
     /** Clean up, free any architecture-allocated memory. */
-    void (*cleanup) (void);
+    void (*destroy) (/*@only@*/ yasm_arch *arch);
+
+    /** Get machine name in use. */
+    const char * (*get_machine) (const yasm_arch *arch);
+
+    /** Set any arch-specific variables.  For example, "mode_bits" in x86.
+     * \return Zero on success, non-zero on failure (variable does not exist).
+     */
+    int (*set_var) (yasm_arch *arch, const char *var, unsigned long val);
 
     /** Switch available instructions/registers/etc based on a user-specified
      * CPU identifier.  Should modify behavior ONLY of parse_* functions!  The
      * bytecode and output functions should be able to handle any CPU.
      * \param cpuid    cpu identifier as in the input file
-     * \param lindex   line index (as from yasm_linemgr)
+     * \param line     virtual line (from yasm_linemap)
      */
-    void (*parse_cpu) (const char *cpuid, unsigned long lindex);
+    void (*parse_cpu) (yasm_arch *arch, const char *cpuid,
+                      unsigned long line);
 
     /** Check an generic identifier to see if it matches architecture specific
      * names for instructions, registers, etc.  Unrecognized identifiers should
@@ -144,11 +161,12 @@ struct yasm_arch {
      * \param data     extra identification information (yasm_arch-specific)
      *                 [output]
      * \param id       identifier as in the input file
-     * \param lindex   line index (as from yasm_linemgr)
+     * \param line     virtual line (from yasm_linemap)
      * \return General type of identifier (#yasm_arch_check_id_retval).
      */
     yasm_arch_check_id_retval (*parse_check_id)
-       (unsigned long data[4], const char *id, unsigned long lindex);
+       (yasm_arch *arch, unsigned long data[4], const char *id,
+        unsigned long line);
 
     /** Handle architecture-specific directives.
      * Should modify behavior ONLY of parse functions, much like parse_cpu().
@@ -157,13 +175,14 @@ struct yasm_arch {
      * \param objext_valparams object format extensions
      *                         value/parameters
      * \param headp            list of sections
-     * \param lindex           line index (as from yasm_linemgr)
+     * \param line             virtual line (as from yasm_linemap)
      * \return Nonzero if directive was not recognized; 0 if directive was
      *        recognized, even if it wasn't valid.
      */
-    int (*parse_directive) (const char *name, yasm_valparamhead *valparams,
+    int (*parse_directive) (yasm_arch *arch, const char *name,
+                           yasm_valparamhead *valparams,
                            /*@null@*/ yasm_valparamhead *objext_valparams,
-                           yasm_sectionhead *headp, unsigned long lindex);
+                           yasm_object *object, unsigned long line);
 
     /** Create an instruction.  Creates a bytecode by matching the
      * instruction data and the parameters given with a valid instruction.
@@ -174,81 +193,42 @@ struct yasm_arch {
      * \param cur_section      currently active section
      * \param prev_bc          previously parsed bytecode in section (NULL if
      *                         first bytecode in section)
-     * \param lindex           line index (as from yasm_linemgr)
+     * \param line             virtual line (from yasm_linemap)
      * \return If no match is found (the instruction is invalid), NULL,
      *        otherwise newly allocated bytecode containing instruction.
      */
     /*@null@*/ yasm_bytecode * (*parse_insn)
-       (const unsigned long data[4], int num_operands,
-        /*@null@*/ yasm_insn_operandhead *operands, yasm_section *cur_section,
-        /*@null@*/ yasm_bytecode *prev_bc, unsigned long lindex);
+       (yasm_arch *arch, const unsigned long data[4], int num_operands,
+        /*@null@*/ yasm_insn_operandhead *operands, yasm_bytecode *prev_bc,
+        unsigned long line);
 
     /** Handle an instruction prefix.
      * Modifies an instruction bytecode based on the prefix in data.
      * \param bc       bytecode (must be instruction bytecode)
      * \param data     prefix (from parse_check_id())
-     * \param lindex   line index (as from yasm_linemgr)
+     * \param line     virtual line (from yasm_linemap)
      */
-    void (*parse_prefix) (yasm_bytecode *bc, const unsigned long data[4],
-                         unsigned long lindex);
+    void (*parse_prefix) (yasm_arch *arch, yasm_bytecode *bc,
+                         const unsigned long data[4], unsigned long line);
 
     /** Handle an segment register instruction prefix.
      * Modifies an instruction bytecode based on a segment register prefix.
      * \param bc       bytecode (must be instruction bytecode)
      * \param segreg   segment register (from parse_check_id())
-     * \param lindex   line index (as from yasm_linemgr)
+     * \param line     virtual line (from yasm_linemap)
      */
-    void (*parse_seg_prefix) (yasm_bytecode *bc, unsigned long segreg,
-                             unsigned long lindex);
+    void (*parse_seg_prefix) (yasm_arch *arch, yasm_bytecode *bc,
+                             unsigned long segreg, unsigned long line);
 
     /** Handle a memory expression segment override.
      * Modifies an instruction bytecode based on a segment override in a
      * memory expression.
      * \param bc       bytecode (must be instruction bytecode)
      * \param segreg   segment register (from parse_check_id())
-     * \param lindex   line index (as from yasm_linemgr)
-     */
-    void (*parse_seg_override) (yasm_effaddr *ea, unsigned long segreg,
-                               unsigned long lindex);
-
-    /** Maximum used bytecode type value+1.  Should be set to
-     * #YASM_BYTECODE_TYPE_BASE if no additional bytecode types are defined
-     * by the architecture.
-     * \internal
-     */
-    const int bc_type_max;
-
-    /** Delete a yasm_arch-defined bytecode.
-     * \internal Do not call directly, instead call yasm_bc_delete().
-     *
-     * \copydoc yasm_bc_delete()
-     */
-    void (*bc_delete) (yasm_bytecode *bc);
-
-    /** Print a yasm_arch-defined bytecode.
-     * \internal Do not call directly, instead call yasm_bc_print().
-     *
-     * \copydoc yasm_bc_print()
+     * \param line     virtual line (from yasm_linemap)
      */
-    void (*bc_print) (FILE *f, int indent_level, const yasm_bytecode *bc);
-
-    /** Resolve labels in a yasm_arch-defined bytecode.
-     * \internal Do not call directly, instead call yasm_bc_resolve().
-     *
-     * \copydoc yasm_bc_resolve()
-     */
-    yasm_bc_resolve_flags (*bc_resolve)
-       (yasm_bytecode *bc, int save, const yasm_section *sect,
-        yasm_calc_bc_dist_func calc_bc_dist);
-
-    /** Convert a yasm_arch-defined bytecode into its byte representation.
-     * \internal Do not call directly, instead call yasm_bc_tobytes().
-     *
-     * \copydoc yasm_bc_tobytes()
-     */
-    int (*bc_tobytes) (yasm_bytecode *bc, unsigned char **bufp,
-                      const yasm_section *sect, void *d,
-                      yasm_output_expr_func output_expr);
+    void (*parse_seg_override) (yasm_arch *arch, yasm_effaddr *ea,
+                               unsigned long segreg, unsigned long line);
 
     /** Output #yasm_floatnum to buffer.  Puts the value into the least
      * significant bits of the destination, or may be shifted into more
@@ -261,12 +241,13 @@ struct yasm_arch {
      * \param valsize  size (in bits)
      * \param shift    left shift (in bits)
      * \param warn     enables standard overflow/underflow warnings
-     * \param lindex   line index; may be 0 if warn is 0.
+     * \param line     virtual line; may be 0 if warn is 0.
      * \return Nonzero on error.
      */
-    int (*floatnum_tobytes) (const yasm_floatnum *flt, unsigned char *buf,
-                            size_t destsize, size_t valsize, size_t shift,
-                            int warn, unsigned long lindex);
+    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);
 
     /** Output #yasm_intnum to buffer.  Puts the value into the least
      * significant bits of the destination, or may be shifted into more
@@ -282,55 +263,39 @@ struct yasm_arch {
      * \param rel      value is a relative displacement from bc
      * \param warn     enables standard warnings (value doesn't fit into
      *                 valsize bits)
-     * \param lindex   line index; may be 0 if warn is 0
+     * \param line     virtual line; may be 0 if warn is 0
      * \return Nonzero on error.
      */
-    int (*intnum_tobytes) (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 lindex);
+    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);
 
     /** Get the equivalent byte size of a register.
      * \param reg      register
      * \return 0 if there is no suitable equivalent size, otherwise the size.
      */
-    unsigned int (*get_reg_size) (unsigned long reg);
+    unsigned int (*get_reg_size) (yasm_arch *arch, unsigned long reg);
 
     /** Print a register.  For debugging purposes.
      * \param f                        file
      * \param indent_level     indentation level
      * \param reg              register
      */
-    void (*reg_print) (FILE *f, unsigned long reg);
+    void (*reg_print) (yasm_arch *arch, unsigned long reg, FILE *f);
 
     /** Print a segment register.  For debugging purposes.
      * \param f                        file
      * \param indent_level     indentation level
      * \param segreg           segment register
      */
-    void (*segreg_print) (FILE *f, unsigned long segreg);
+    void (*segreg_print) (yasm_arch *arch, unsigned long segreg, FILE *f);
 
     /** Create an effective address from an expression.
      * \param e        expression (kept, do not delete)
      * \return Newly allocated effective address.
      */
-    yasm_effaddr * (*ea_new_expr) (/*@keep@*/ yasm_expr *e);
-
-    /** Delete the yasm_arch-specific data in an effective address.
-     * May be NULL if no special deletion is required (e.g. there's no
-     * dynamically allocated pointers in the effective address data).
-     * \internal Do not call directly, instead call yasm_ea_delete().
-     *
-     * \copydoc yasm_ea_delete()
-     */
-    void (*ea_data_delete) (yasm_effaddr *ea);
-
-    /** Print the yasm_arch-specific data in an effective address.
-     * \internal Do not call directly, instead call yasm_ea_print().
-     *
-     * \copydoc yasm_ea_print()
-     */
-    void (*ea_data_print) (FILE *f, int indent_level, const yasm_effaddr *ea);
+    yasm_effaddr * (*ea_create) (yasm_arch *arch, /*@keep@*/ yasm_expr *e);
 
     /** NULL-terminated list of machines for this architecture. */
     yasm_arch_machine *machines;
@@ -340,7 +305,7 @@ struct yasm_arch {
 
     /** Canonical "word" size in bytes. */
     unsigned int wordsize;
-};
+} yasm_arch_module;
 
 #ifdef YASM_LIB_INTERNAL
 /** An instruction operand. */
@@ -371,28 +336,29 @@ struct yasm_insn_operand {
 };
 #endif
 
-/** Common initializer for yasm_arch helper functions.
- * \param a    architecture in use
+/** Get the yasm_arch_module implementation for a yasm_arch.
+ * \param arch architecture
+ * \return Module implementation.
  */
-void yasm_arch_common_initialize(yasm_arch *a);
+yasm_arch_module *yasm_arch_get_module(yasm_arch *arch);
 
 /** Create an instruction operand from a register.
  * \param reg  register
  * \return Newly allocated operand.
  */
-yasm_insn_operand *yasm_operand_new_reg(unsigned long reg);
+yasm_insn_operand *yasm_operand_create_reg(unsigned long reg);
 
 /** Create an instruction operand from a segment register.
  * \param segreg       segment register
  * \return Newly allocated operand.
  */
-yasm_insn_operand *yasm_operand_new_segreg(unsigned long segreg);
+yasm_insn_operand *yasm_operand_create_segreg(unsigned long segreg);
 
 /** Create an instruction operand from an effective address.
  * \param ea   effective address
  * \return Newly allocated operand.
  */
-yasm_insn_operand *yasm_operand_new_mem(/*@only@*/ yasm_effaddr *ea);
+yasm_insn_operand *yasm_operand_create_mem(/*@only@*/ yasm_effaddr *ea);
 
 /** Create an instruction operand from an immediate expression.
  * Looks for cases of a single register and creates a register variant of
@@ -400,20 +366,27 @@ yasm_insn_operand *yasm_operand_new_mem(/*@only@*/ yasm_effaddr *ea);
  * \param val  immediate expression
  * \return Newly allocated operand.
  */
-yasm_insn_operand *yasm_operand_new_imm(/*@only@*/ yasm_expr *val);
+yasm_insn_operand *yasm_operand_create_imm(/*@only@*/ yasm_expr *val);
 
 /** Print an instruction operand.  For debugging purposes.
+ * \param arch         architecture
  * \param f            file
  * \param indent_level indentation level
  * \param op           instruction operand
  */
-void yasm_operand_print(FILE *f, int indent_level,
-                       const yasm_insn_operand *op);
+void yasm_operand_print(const yasm_insn_operand *op, FILE *f, int indent_level,
+                       yasm_arch *arch);
 
-/** Initialize a list of instruction operands.
- * \param headp        list of instruction operands
+/** Create a new list of instruction operands.
+ * \return Newly allocated list.
  */
-void yasm_ops_initialize(yasm_insn_operandhead *headp);
+yasm_insn_operandhead *yasm_ops_create(void);
+
+/** Destroy a list of instruction operands (created with yasm_ops_create()).
+ * \param headp                list of instruction operands
+ * \param content      if nonzero, deletes content of each operand
+ */
+void yasm_ops_destroy(yasm_insn_operandhead *headp, int content);
 
 /** Get the first operand in a list of instruction operands.
  * \param headp                list of instruction operands
@@ -425,19 +398,20 @@ yasm_insn_operand *yasm_ops_first(yasm_insn_operandhead *headp);
  * \param cur          previous operand
  * \return Next operand in list (NULL if cur was the last operand).
  */
-yasm_insn_operand *yasm_ops_next(yasm_insn_operand *cur);
+yasm_insn_operand *yasm_operand_next(yasm_insn_operand *cur);
 
 #ifdef YASM_LIB_INTERNAL
 #define yasm_ops_initialize(headp)     STAILQ_INIT(headp)
 #define yasm_ops_first(headp)          STAILQ_FIRST(headp)
-#define yasm_ops_next(cur)             STAILQ_NEXT(cur, link)
-#endif
+#define yasm_operand_next(cur)         STAILQ_NEXT(cur, link)
 
-/** Delete (free allocated memory for) a list of instruction operands.
+/** Delete (free allocated memory for) a list of instruction operands (created
+ * with yasm_ops_initialize()).
  * \param headp                list of instruction operands
  * \param content      if nonzero, deletes content of each operand
  */
 void yasm_ops_delete(yasm_insn_operandhead *headp, int content);
+#endif
 
 /** Add data value to the end of a list of instruction operands.
  * \note Does not make a copy of the operand; so don't pass this function
@@ -453,11 +427,12 @@ void yasm_ops_delete(yasm_insn_operandhead *headp, int content);
      /*@returned@*/ /*@null@*/ yasm_insn_operand *op);
 
 /** Print a list of instruction operands.  For debugging purposes.
+ * \param arch         architecture
  * \param f            file
  * \param indent_level indentation level
  * \param headp                list of instruction operands
  */
-void yasm_ops_print(FILE *f, int indent_level,
-                   const yasm_insn_operandhead *headp);
+void yasm_ops_print(const yasm_insn_operandhead *headp, FILE *f,
+                   int indent_level, yasm_arch *arch);
 
 #endif
diff --git a/libyasm/assocdat.c b/libyasm/assocdat.c
new file mode 100644 (file)
index 0000000..27fb1db
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * YASM associated data storage (libyasm internal use)
+ *
+ *  Copyright (C) 2003  Peter Johnson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * 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.
+ */
+#define YASM_LIB_INTERNAL
+#include "util.h"
+/*@unused@*/ RCSID("$IdPath$");
+
+#include "coretype.h"
+#include "assocdat.h"
+
+
+typedef struct assoc_data_item {
+    const yasm_assoc_data_callback *callback;
+    void *data;
+} assoc_data_item;
+
+struct yasm__assoc_data {
+    assoc_data_item *vector;
+    size_t size;
+    size_t alloc;
+};
+
+
+yasm__assoc_data *
+yasm__assoc_data_create(void)
+{
+    yasm__assoc_data *assoc_data = yasm_xmalloc(sizeof(yasm__assoc_data));
+
+    assoc_data->size = 0;
+    assoc_data->alloc = 2;
+    assoc_data->vector = yasm_xmalloc(assoc_data->alloc *
+                                     sizeof(assoc_data_item));
+
+    return assoc_data;
+}
+
+void *
+yasm__assoc_data_get(yasm__assoc_data *assoc_data,
+                    const yasm_assoc_data_callback *callback)
+{
+    size_t i;
+
+    if (!assoc_data)
+       return NULL;
+
+    for (i=0; i<assoc_data->size; i++) {
+       if (assoc_data->vector[i].callback == callback)
+           return assoc_data->vector[i].data;
+    }
+    return NULL;
+}
+
+yasm__assoc_data *
+yasm__assoc_data_add(yasm__assoc_data *assoc_data_arg,
+                    const yasm_assoc_data_callback *callback, void *data)
+{
+    yasm__assoc_data *assoc_data;
+    assoc_data_item *item = NULL;
+    size_t i;
+
+    /* Create a new assoc_data if necessary */
+    if (assoc_data_arg)
+       assoc_data = assoc_data_arg;
+    else
+       assoc_data = yasm__assoc_data_create();
+
+    /* See if there's already assocated data for this callback */
+    for (i=0; i<assoc_data->size; i++) {
+       if (assoc_data->vector[i].callback == callback)
+           item = &assoc_data->vector[i];
+    }
+
+    /* No?  Then append a new one */
+    if (!item) {
+       assoc_data->size++;
+       if (assoc_data->size > assoc_data->alloc) {
+           assoc_data->alloc *= 2;
+           assoc_data->vector =
+               yasm_xrealloc(assoc_data->vector,
+                             assoc_data->alloc * sizeof(assoc_data_item));
+       }
+       item = &assoc_data->vector[assoc_data->size-1];
+       item->callback = callback;
+       item->data = NULL;
+    }
+
+    /* Delete existing data (if any) */
+    if (item->data)
+       item->callback->destroy(item->data);
+
+    item->data = data;
+
+    return assoc_data;
+}
+
+void
+yasm__assoc_data_destroy(yasm__assoc_data *assoc_data)
+{
+    size_t i;
+
+    if (!assoc_data)
+       return;
+
+    for (i=0; i<assoc_data->size; i++)
+       assoc_data->vector[i].callback->destroy(assoc_data->vector[i].data);
+    yasm_xfree(assoc_data->vector);
+    yasm_xfree(assoc_data);
+}
+
+void
+yasm__assoc_data_print(const yasm__assoc_data *assoc_data, FILE *f,
+                      int indent_level)
+{
+    /*TODO*/
+}
diff --git a/libyasm/assocdat.h b/libyasm/assocdat.h
new file mode 100644 (file)
index 0000000..6f8f6b1
--- /dev/null
@@ -0,0 +1,71 @@
+/**
+ * \file assocdat.h
+ * \brief YASM associated data storage (libyasm internal use)
+ *
+ * \rcs
+ * $IdPath$
+ * \endrcs
+ *
+ * \license
+ *  Copyright (C) 2003  Peter Johnson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * 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_ASSOCDAT_H
+#define YASM_ASSOCDAT_H
+
+/** Associated data container. */
+typedef struct yasm__assoc_data yasm__assoc_data;
+
+/** Create an associated data container. */
+/*@only@*/ yasm__assoc_data *yasm__assoc_data_create(void);
+
+/** Get associated data for a data callback.
+ * \param assoc_data   container of associated data
+ * \param callback     callback used when adding data
+ * \return Associated data (NULL if none).
+ */
+/*@dependent@*/ /*@null@*/ void *yasm__assoc_data_get
+    (/*@null@*/ yasm__assoc_data *assoc_data,
+     const yasm_assoc_data_callback *callback);
+
+/** Add associated data to a associated data container.
+ * \attention Deletes any existing associated data for that data callback.
+ * \param assoc_data   container of associated data
+ * \param callback     callback
+ * \param data         data to associate
+ */
+/*@only@*/ yasm__assoc_data *yasm__assoc_data_add
+    (/*@null@*/ /*@only@*/ yasm__assoc_data *assoc_data,
+     const yasm_assoc_data_callback *callback,
+     /*@only@*/ /*@null@*/ void *data);
+
+/** Destroy all associated data in a container. */
+void yasm__assoc_data_destroy
+    (/*@null@*/ /*@only@*/ yasm__assoc_data *assoc_data);
+
+/** Print all associated data in a container. */
+void yasm__assoc_data_print(const yasm__assoc_data *assoc_data, FILE *f,
+                           int indent_level);
+
+#endif
index c6fbfb8a68d3b581add1b59516579cf976ec71a5..3b368964941bef95ac003b5bc2e9f35c192c6a6b 100644 (file)
 #ifndef YASM_BC_INT_H
 #define YASM_BC_INT_H
 
+typedef struct yasm_effaddr_callback {
+    void (*destroy) (yasm_effaddr *ea);
+    void (*print) (const yasm_effaddr *ea, FILE *f, int indent_level);
+} yasm_effaddr_callback;
+
 struct yasm_effaddr {
+    const yasm_effaddr_callback *callback;     /* callback functions */
+
     /*@only@*/ /*@null@*/ yasm_expr *disp;     /* address displacement */
     unsigned char len;         /* length of disp (in bytes), 0 if unknown,
                                 * 0xff if unknown and required to be >0.
@@ -43,10 +50,23 @@ struct yasm_immval {
     unsigned char sign;                /* 1 if final imm is treated as signed */
 };
 
+typedef struct yasm_bytecode_callback {
+    void (*destroy) (yasm_bytecode *bc);
+    void (*print) (const yasm_bytecode *bc, FILE *f, int indent_level);
+    yasm_bc_resolve_flags (*resolve)
+       (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+    int (*tobytes) (yasm_bytecode *bc, unsigned char **bufp, void *d,
+                   yasm_output_expr_func output_expr,
+                   /*@null@*/ yasm_output_reloc_func output_reloc);
+} yasm_bytecode_callback;
+
 struct yasm_bytecode {
     /*@reldef@*/ STAILQ_ENTRY(yasm_bytecode) link;
 
-    yasm_bytecode_type type;
+    /*@null@*/ const yasm_bytecode_callback *callback;
+
+    /* Pointer to section containing bytecode; NULL if not part of a section. */
+    /*@dependent@*/ /*@null@*/ yasm_section *section;
 
     /* number of times bytecode is repeated, NULL=1. */
     /*@only@*/ /*@null@*/ yasm_expr *multiple;
@@ -64,6 +84,17 @@ struct yasm_bytecode {
     unsigned long opt_flags;
 };
 
-#define yasm_bcs__next(x)              STAILQ_NEXT(x, link)
+/** Create a bytecode of any specified type.
+ * \param callback     bytecode callback functions, if NULL, creates empty
+ *                     bytecode (may not be resolved or output)
+ * \param datasize     size of type-specific data (in bytes)
+ * \param line         virtual line (from yasm_linemap)
+ * \return Newly allocated bytecode of the specified type.
+ */
+/*@only@*/ yasm_bytecode *yasm_bc_create_common
+    (/*@null@*/ const yasm_bytecode_callback *callback, size_t datasize,
+     unsigned long line);
+
+#define yasm_bc__next(x)               STAILQ_NEXT(x, link)
 
 #endif
index fa8f700e3022901c75976f4a1bc4478ed6283104..751a449a53675c51c3e12ddda06b67d18f989dfe 100644 (file)
@@ -1721,71 +1721,51 @@ charptr BitVector_to_Dec(wordptr addr)
     return(result);
 }
 
-static wordptr from_Dec_term = NULL;
-static wordptr from_Dec_base = NULL;
-static wordptr from_Dec_prod = NULL;
-static wordptr from_Dec_rank = NULL;
-static wordptr from_Dec_temp = NULL;
+struct BitVector_from_Dec_static_data {
+    wordptr term;
+    wordptr base;
+    wordptr prod;
+    wordptr rank;
+    wordptr temp;
+};
 
-ErrCode BitVector_from_Dec_static_Boot(N_word bits)
+BitVector_from_Dec_static_data *BitVector_from_Dec_static_Boot(N_word bits)
 {
+    BitVector_from_Dec_static_data *data;
+
+    data = yasm_xmalloc(sizeof(BitVector_from_Dec_static_data));
+
     if (bits > 0)
     {
-       BitVector_from_Dec_static_Shutdown();
-        from_Dec_term = BitVector_Create(BITS,FALSE);
-        if (from_Dec_term == NULL)
-        {
-            return(ErrCode_Null);
-        }
-        from_Dec_base = BitVector_Create(BITS,FALSE);
-        if (from_Dec_base == NULL)
-        {
-            BitVector_Destroy(from_Dec_term);
-            return(ErrCode_Null);
-        }
-        from_Dec_prod = BitVector_Create(bits,FALSE);
-        if (from_Dec_prod == NULL)
-        {
-            BitVector_Destroy(from_Dec_term);
-            BitVector_Destroy(from_Dec_base);
-            return(ErrCode_Null);
-        }
-        from_Dec_rank = BitVector_Create(bits,FALSE);
-        if (from_Dec_rank == NULL)
-        {
-            BitVector_Destroy(from_Dec_term);
-            BitVector_Destroy(from_Dec_base);
-            BitVector_Destroy(from_Dec_prod);
-            return(ErrCode_Null);
-        }
-        from_Dec_temp = BitVector_Create(bits,FALSE);
-        if (from_Dec_temp == NULL)
-        {
-            BitVector_Destroy(from_Dec_term);
-            BitVector_Destroy(from_Dec_base);
-            BitVector_Destroy(from_Dec_prod);
-            BitVector_Destroy(from_Dec_rank);
-            return(ErrCode_Null);
-        }
+        data->term = BitVector_Create(BITS,FALSE);
+        data->base = BitVector_Create(BITS,FALSE);
+        data->prod = BitVector_Create(bits,FALSE);
+        data->rank = BitVector_Create(bits,FALSE);
+        data->temp = BitVector_Create(bits,FALSE);
+    } else {
+       data->term = NULL;
+       data->base = NULL;
+       data->prod = NULL;
+       data->rank = NULL;
+       data->temp = NULL;
     }
-    return(ErrCode_Ok);
+    return data;
 }
 
-void BitVector_from_Dec_static_Shutdown(void)
+void BitVector_from_Dec_static_Shutdown(BitVector_from_Dec_static_data *data)
 {
-    if (from_Dec_term != NULL)
-        BitVector_Destroy(from_Dec_term);
-    if (from_Dec_base != NULL)
-        BitVector_Destroy(from_Dec_base);
-    if (from_Dec_prod != NULL)
-        BitVector_Destroy(from_Dec_prod);
-    if (from_Dec_rank != NULL)
-        BitVector_Destroy(from_Dec_rank);
-    if (from_Dec_temp != NULL)
-        BitVector_Destroy(from_Dec_temp);
+    if (data) {
+        BitVector_Destroy(data->term);
+        BitVector_Destroy(data->base);
+        BitVector_Destroy(data->prod);
+        BitVector_Destroy(data->rank);
+        BitVector_Destroy(data->temp);
+    }
+    yasm_xfree(data);
 }
 
-ErrCode BitVector_from_Dec_static(wordptr addr, charptr string)
+ErrCode BitVector_from_Dec_static(BitVector_from_Dec_static_data *data,
+                                 wordptr addr, charptr string)
 {
     ErrCode error = ErrCode_Ok;
     N_word  bits = bits_(addr);
@@ -1794,11 +1774,11 @@ ErrCode BitVector_from_Dec_static(wordptr addr, charptr string)
     boolean minus;
     boolean shift;
     boolean carry;
-    wordptr term = from_Dec_term;
-    wordptr base = from_Dec_base;
-    wordptr prod = from_Dec_prod;
-    wordptr rank = from_Dec_rank;
-    wordptr temp = from_Dec_temp;
+    wordptr term;
+    wordptr base;
+    wordptr prod;
+    wordptr rank;
+    wordptr temp;
     N_word  accu;
     N_word  powr;
     N_word  count;
@@ -1807,6 +1787,12 @@ ErrCode BitVector_from_Dec_static(wordptr addr, charptr string)
 
     if (bits > 0)
     {
+       term = data->term;
+       base = data->base;
+       prod = data->prod;
+       rank = data->rank;
+       temp = data->temp;
+
         length = strlen((char *) string);
         if (length == 0) return(ErrCode_Pars);
         digit = (int) *string;
index 6eac646f0501104482ec19cf39ed55f578f19de4..37bb893d17805e5eca847b015cba29f0537e6d61 100644 (file)
@@ -209,9 +209,11 @@ ErrCode BitVector_from_Bin   (/*@out@*/ wordptr addr, charptr string);
 /*@only@*/ charptr BitVector_to_Dec     (wordptr addr);
 ErrCode BitVector_from_Dec   (/*@out@*/ wordptr addr, charptr string);
 
-ErrCode BitVector_from_Dec_static_Boot(N_word bits);
-void BitVector_from_Dec_static_Shutdown(void);
-ErrCode BitVector_from_Dec_static(/*@out@*/ wordptr addr, charptr string);
+typedef struct BitVector_from_Dec_static_data BitVector_from_Dec_static_data;
+BitVector_from_Dec_static_data *BitVector_from_Dec_static_Boot(N_word bits);
+void BitVector_from_Dec_static_Shutdown(/*@null@*/ BitVector_from_Dec_static_data *data);
+ErrCode BitVector_from_Dec_static(BitVector_from_Dec_static_data *data,
+                                 /*@out@*/ wordptr addr, charptr string);
 
 /*@only@*/ charptr BitVector_to_Enum    (wordptr addr);
 ErrCode BitVector_from_Enum  (/*@out@*/ wordptr addr, charptr string);
index b03f4dfc40b7524c2822f527b9cdb00d86fd17b4..bb9ee898bf4e787e9034ede1c4728e1ec1f76d4d 100644 (file)
@@ -39,8 +39,6 @@
 #include "objfmt.h"
 #include "dbgfmt.h"
 
-#include "arch.h"
-
 #include "bc-int.h"
 #include "expr-int.h"
 
@@ -56,6 +54,8 @@ struct yasm_dataval {
     } data;
 };
 
+/* Standard bytecode types */
+
 typedef struct bytecode_data {
     yasm_bytecode bc;  /* base structure */
 
@@ -91,45 +91,87 @@ typedef struct bytecode_align {
     unsigned long boundary;    /* alignment boundary */
 } bytecode_align;
 
-typedef struct bytecode_objfmt_data {
-    yasm_bytecode bc;   /* base structure */
+/* Standard bytecode callback function prototypes */
+
+static void bc_data_destroy(yasm_bytecode *bc);
+static void bc_data_print(const yasm_bytecode *bc, FILE *f, int indent_level);
+static yasm_bc_resolve_flags bc_data_resolve
+    (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+static int bc_data_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+                          yasm_output_expr_func output_expr,
+                          /*@null@*/ yasm_output_reloc_func output_reloc);
+
+static void bc_reserve_destroy(yasm_bytecode *bc);
+static void bc_reserve_print(const yasm_bytecode *bc, FILE *f,
+                            int indent_level);
+static yasm_bc_resolve_flags bc_reserve_resolve
+    (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+static int bc_reserve_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+                             yasm_output_expr_func output_expr,
+                             /*@null@*/ yasm_output_reloc_func output_reloc);
+
+static void bc_incbin_destroy(yasm_bytecode *bc);
+static void bc_incbin_print(const yasm_bytecode *bc, FILE *f,
+                           int indent_level);
+static yasm_bc_resolve_flags bc_incbin_resolve
+    (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+static int bc_incbin_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+                            yasm_output_expr_func output_expr,
+                            /*@null@*/ yasm_output_reloc_func output_reloc);
+
+static void bc_align_destroy(yasm_bytecode *bc);
+static void bc_align_print(const yasm_bytecode *bc, FILE *f, int indent_level);
+static yasm_bc_resolve_flags bc_align_resolve
+    (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+static int bc_align_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+                           yasm_output_expr_func output_expr,
+                           /*@null@*/ yasm_output_reloc_func output_reloc);
+
+/* Standard bytecode callback structures */
+
+static const yasm_bytecode_callback bc_data_callback = {
+    bc_data_destroy,
+    bc_data_print,
+    bc_data_resolve,
+    bc_data_tobytes
+};
 
-    unsigned int type;                 /* objfmt-specific type */
-    /*@dependent@*/ yasm_objfmt *of;   /* objfmt that created the data */
-    /*@only@*/ void *data;             /* objfmt-specific data */
-} bytecode_objfmt_data;
+static const yasm_bytecode_callback bc_reserve_callback = {
+    bc_reserve_destroy,
+    bc_reserve_print,
+    bc_reserve_resolve,
+    bc_reserve_tobytes
+};
 
-typedef struct bytecode_dbgfmt_data {
-    yasm_bytecode bc;   /* base structure */
+static const yasm_bytecode_callback bc_incbin_callback = {
+    bc_incbin_destroy,
+    bc_incbin_print,
+    bc_incbin_resolve,
+    bc_incbin_tobytes
+};
 
-    unsigned int type;                 /* dbgfmt-specific type */
-    /*@dependent@*/ yasm_dbgfmt *df;   /* dbgfmt that created the data */
-    /*@only@*/ void *data;             /* dbgfmt-specific data */
-} bytecode_dbgfmt_data;
+static const yasm_bytecode_callback bc_align_callback = {
+    bc_align_destroy,
+    bc_align_print,
+    bc_align_resolve,
+    bc_align_tobytes
+};
 
 /* Static structures for when NULL is passed to conversion functions. */
 /*  for Convert*ToBytes() */
 unsigned char bytes_static[16];
 
-/*@dependent@*/ static yasm_arch *cur_arch;
-
-
-void
-yasm_bc_initialize(yasm_arch *a)
-{
-    cur_arch = a;
-}
 
 yasm_immval *
-yasm_imm_new_int(unsigned long int_val, unsigned long lindex)
+yasm_imm_create_int(unsigned long int_val, unsigned long line)
 {
-    return yasm_imm_new_expr(
-       yasm_expr_new_ident(yasm_expr_int(yasm_intnum_new_uint(int_val)),
-                           lindex));
+    return yasm_imm_create_expr(
+       yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(int_val)),
+                              line));
 }
 
 yasm_immval *
-yasm_imm_new_expr(yasm_expr *expr_ptr)
+yasm_imm_create_expr(yasm_expr *expr_ptr)
 {
     yasm_immval *im = yasm_xmalloc(sizeof(yasm_immval));
 
@@ -170,25 +212,23 @@ yasm_ea_set_nosplit(yasm_effaddr *ptr, unsigned int nosplit)
 
 /*@-nullstate@*/
 void
-yasm_ea_delete(yasm_effaddr *ea)
+yasm_ea_destroy(yasm_effaddr *ea)
 {
-    if (cur_arch->ea_data_delete)
-       cur_arch->ea_data_delete(ea);
-    yasm_expr_delete(ea->disp);
+    ea->callback->destroy(ea);
+    yasm_expr_destroy(ea->disp);
     yasm_xfree(ea);
 }
 /*@=nullstate@*/
 
 /*@-nullstate@*/
 void
-yasm_ea_print(FILE *f, int indent_level, const yasm_effaddr *ea)
+yasm_ea_print(const yasm_effaddr *ea, FILE *f, int indent_level)
 {
     fprintf(f, "%*sDisp=", indent_level, "");
-    yasm_expr_print(f, ea->disp);
+    yasm_expr_print(ea->disp, f);
     fprintf(f, "\n%*sLen=%u\n", indent_level, "", (unsigned int)ea->len);
     fprintf(f, "%*sNoSplit=%u\n", indent_level, "", (unsigned int)ea->nosplit);
-    if (cur_arch->ea_data_print)
-       cur_arch->ea_data_print(f, indent_level, ea);
+    ea->callback->print(ea, f, indent_level);
 }
 /*@=nullstate@*/
 
@@ -196,23 +236,26 @@ void
 yasm_bc_set_multiple(yasm_bytecode *bc, yasm_expr *e)
 {
     if (bc->multiple)
-       bc->multiple = yasm_expr_new_tree(bc->multiple, YASM_EXPR_MUL, e,
-                                         e->line);
+       bc->multiple = yasm_expr_create_tree(bc->multiple, YASM_EXPR_MUL, e,
+                                            e->line);
     else
        bc->multiple = e;
 }
 
 yasm_bytecode *
-yasm_bc_new_common(yasm_bytecode_type type, size_t size, unsigned long lindex)
+yasm_bc_create_common(const yasm_bytecode_callback *callback, size_t size,
+                     unsigned long line)
 {
     yasm_bytecode *bc = yasm_xmalloc(size);
 
-    bc->type = type;
+    bc->callback = callback;
+
+    bc->section = NULL;
 
     bc->multiple = (yasm_expr *)NULL;
     bc->len = 0;
 
-    bc->line = lindex;
+    bc->line = line;
 
     bc->offset = 0;
 
@@ -221,332 +264,130 @@ yasm_bc_new_common(yasm_bytecode_type type, size_t size, unsigned long lindex)
     return bc;
 }
 
-yasm_bytecode *
-yasm_bc_new_data(yasm_datavalhead *datahead, unsigned int size,
-                unsigned long lindex)
+static void
+bc_data_destroy(yasm_bytecode *bc)
 {
-    bytecode_data *data;
-
-    data = (bytecode_data *)
-       yasm_bc_new_common(YASM_BC__DATA, sizeof(bytecode_data), lindex);
-
-    data->datahead = *datahead;
-    data->size = (unsigned char)size;
-
-    return (yasm_bytecode *)data;
-}
-
-yasm_bytecode *
-yasm_bc_new_reserve(yasm_expr *numitems, unsigned int itemsize,
-                   unsigned long lindex)
-{
-    bytecode_reserve *reserve;
-
-    reserve = (bytecode_reserve *)
-       yasm_bc_new_common(YASM_BC__RESERVE, sizeof(bytecode_reserve), lindex);
-
-    /*@-mustfree@*/
-    reserve->numitems = numitems;
-    /*@=mustfree@*/
-    reserve->itemsize = (unsigned char)itemsize;
-
-    return (yasm_bytecode *)reserve;
+    bytecode_data *bc_data = (bytecode_data *)bc;
+    yasm_dvs_destroy(&bc_data->datahead);
 }
 
-yasm_bytecode *
-yasm_bc_new_incbin(char *filename, yasm_expr *start, yasm_expr *maxlen,
-                  unsigned long lindex)
+static void
+bc_data_print(const yasm_bytecode *bc, FILE *f, int indent_level)
 {
-    bytecode_incbin *incbin;
-
-    incbin = (bytecode_incbin *)
-       yasm_bc_new_common(YASM_BC__INCBIN, sizeof(bytecode_incbin), lindex);
-
-    /*@-mustfree@*/
-    incbin->filename = filename;
-    incbin->start = start;
-    incbin->maxlen = maxlen;
-    /*@=mustfree@*/
-
-    return (yasm_bytecode *)incbin;
+    const bytecode_data *bc_data = (const bytecode_data *)bc;
+    fprintf(f, "%*s_Data_\n", indent_level, "");
+    fprintf(f, "%*sFinal Element Size=%u\n", indent_level+1, "",
+           (unsigned int)bc_data->size);
+    fprintf(f, "%*sElements:\n", indent_level+1, "");
+    yasm_dvs_print(&bc_data->datahead, f, indent_level+2);
 }
 
-yasm_bytecode *
-yasm_bc_new_align(unsigned long boundary, unsigned long lindex)
-{
-    bytecode_align *align;
-
-    align = (bytecode_align *)
-       yasm_bc_new_common(YASM_BC__ALIGN, sizeof(bytecode_align), lindex);
-
-    align->boundary = boundary;
-
-    return (yasm_bytecode *)align;
-}
-
-yasm_bytecode *
-yasm_bc_new_objfmt_data(unsigned int type, unsigned long len, yasm_objfmt *of,
-                       void *data, unsigned long lindex)
-{
-    bytecode_objfmt_data *objfmt_data;
-
-    objfmt_data = (bytecode_objfmt_data *)
-       yasm_bc_new_common(YASM_BC__OBJFMT_DATA, sizeof(bytecode_objfmt_data),
-                          lindex);
-
-    objfmt_data->type = type;
-    objfmt_data->of = of;
-    /*@-mustfree@*/
-    objfmt_data->data = data;
-    /*@=mustfree@*/
-
-    /* Yes, this breaks the paradigm just a little.  But this data is very
-     * unlike other bytecode data--it's internally generated after the
-     * other bytecodes have been resolved, and the length is ALWAYS known.
-     */
-    objfmt_data->bc.len = len;
-
-    return (yasm_bytecode *)objfmt_data;
-}
-
-yasm_bytecode *
-yasm_bc_new_dbgfmt_data(unsigned int type, unsigned long len, yasm_dbgfmt *df,
-                       void *data, unsigned long lindex)
-{
-    bytecode_dbgfmt_data *dbgfmt_data;
-
-    dbgfmt_data = (bytecode_dbgfmt_data *)
-       yasm_bc_new_common(YASM_BC__DBGFMT_DATA, sizeof(bytecode_dbgfmt_data),
-                          lindex);
-
-    dbgfmt_data->type = type;
-    dbgfmt_data->df = df;
-    /*@-mustfree@*/
-    dbgfmt_data->data = data;
-    /*@=mustfree@*/
-
-    /* Yes, this breaks the paradigm just a little.  But this data is very
-     * unlike other bytecode data--it's internally generated after the
-     * other bytecodes have been resolved, and the length is ALWAYS known.
-     */
-    dbgfmt_data->bc.len = len;
-
-    return (yasm_bytecode *)dbgfmt_data;
-}
-
-void
-yasm_bc_delete(yasm_bytecode *bc)
-{
-    bytecode_data *data;
-    bytecode_reserve *reserve;
-    bytecode_incbin *incbin;
-    bytecode_objfmt_data *objfmt_data;
-    bytecode_dbgfmt_data *dbgfmt_data;
-
-    if (!bc)
-       return;
-
-    /*@-branchstate@*/
-    switch (bc->type) {
-       case YASM_BC__EMPTY:
-           break;
-       case YASM_BC__DATA:
-           data = (bytecode_data *)bc;
-           yasm_dvs_delete(&data->datahead);
-           break;
-       case YASM_BC__RESERVE:
-           reserve = (bytecode_reserve *)bc;
-           yasm_expr_delete(reserve->numitems);
-           break;
-       case YASM_BC__INCBIN:
-           incbin = (bytecode_incbin *)bc;
-           yasm_xfree(incbin->filename);
-           yasm_expr_delete(incbin->start);
-           yasm_expr_delete(incbin->maxlen);
-           break;
-       case YASM_BC__ALIGN:
-           break;
-       case YASM_BC__OBJFMT_DATA:
-           objfmt_data = (bytecode_objfmt_data *)bc;
-           if (objfmt_data->of->bc_objfmt_data_delete)
-               objfmt_data->of->bc_objfmt_data_delete(objfmt_data->type,
-                                                      objfmt_data->data);
-           else
-               yasm_internal_error(
-                   N_("objfmt can't handle its own objfmt data bytecode"));
-           break;
-       case YASM_BC__DBGFMT_DATA:
-           dbgfmt_data = (bytecode_dbgfmt_data *)bc;
-           if (dbgfmt_data->df->bc_dbgfmt_data_delete)
-               dbgfmt_data->df->bc_dbgfmt_data_delete(dbgfmt_data->type,
-                                                      dbgfmt_data->data);
-           else
-               yasm_internal_error(
-                   N_("dbgfmt can't handle its own dbgfmt data bytecode"));
-           break;
-       default:
-           if ((unsigned int)bc->type < (unsigned int)cur_arch->bc_type_max)
-               cur_arch->bc_delete(bc);
-           else
-               yasm_internal_error(N_("Unknown bytecode type"));
-           break;
-    }
-    /*@=branchstate@*/
-
-    yasm_expr_delete(bc->multiple);
-    yasm_xfree(bc);
-}
-
-void
-yasm_bc_print(FILE *f, int indent_level, const yasm_bytecode *bc)
-{
-    const bytecode_data *data;
-    const bytecode_reserve *reserve;
-    const bytecode_incbin *incbin;
-    const bytecode_align *align;
-    const bytecode_objfmt_data *objfmt_data;
-    const bytecode_dbgfmt_data *dbgfmt_data;
-
-    switch (bc->type) {
-       case YASM_BC__EMPTY:
-           fprintf(f, "%*s_Empty_\n", indent_level, "");
-           break;
-       case YASM_BC__DATA:
-           data = (const bytecode_data *)bc;
-           fprintf(f, "%*s_Data_\n", indent_level, "");
-           fprintf(f, "%*sFinal Element Size=%u\n", indent_level+1, "",
-                   (unsigned int)data->size);
-           fprintf(f, "%*sElements:\n", indent_level+1, "");
-           yasm_dvs_print(f, indent_level+2, &data->datahead);
-           break;
-       case YASM_BC__RESERVE:
-           reserve = (const bytecode_reserve *)bc;
-           fprintf(f, "%*s_Reserve_\n", indent_level, "");
-           fprintf(f, "%*sNum Items=", indent_level, "");
-           yasm_expr_print(f, reserve->numitems);
-           fprintf(f, "\n%*sItem Size=%u\n", indent_level, "",
-                   (unsigned int)reserve->itemsize);
-           break;
-       case YASM_BC__INCBIN:
-           incbin = (const bytecode_incbin *)bc;
-           fprintf(f, "%*s_IncBin_\n", indent_level, "");
-           fprintf(f, "%*sFilename=`%s'\n", indent_level, "",
-                   incbin->filename);
-           fprintf(f, "%*sStart=", indent_level, "");
-           if (!incbin->start)
-               fprintf(f, "nil (0)");
-           else
-               yasm_expr_print(f, incbin->start);
-           fprintf(f, "%*sMax Len=", indent_level, "");
-           if (!incbin->maxlen)
-               fprintf(f, "nil (unlimited)");
-           else
-               yasm_expr_print(f, incbin->maxlen);
-           fprintf(f, "\n");
-           break;
-       case YASM_BC__ALIGN:
-           align = (const bytecode_align *)bc;
-           fprintf(f, "%*s_Align_\n", indent_level, "");
-           fprintf(f, "%*sBoundary=%lu\n", indent_level, "", align->boundary);
-           break;
-       case YASM_BC__OBJFMT_DATA:
-           objfmt_data = (const bytecode_objfmt_data *)bc;
-           fprintf(f, "%*s_ObjFmt_Data_\n", indent_level, "");
-           if (objfmt_data->of->bc_objfmt_data_print)
-               objfmt_data->of->bc_objfmt_data_print(f, indent_level,
-                                                     objfmt_data->type,
-                                                     objfmt_data->data);
-           else
-               fprintf(f, "%*sUNKNOWN\n", indent_level, "");
-           break;
-       case YASM_BC__DBGFMT_DATA:
-           dbgfmt_data = (const bytecode_dbgfmt_data *)bc;
-           fprintf(f, "%*s_DbgFmt_Data_\n", indent_level, "");
-           if (dbgfmt_data->df->bc_dbgfmt_data_print)
-               dbgfmt_data->df->bc_dbgfmt_data_print(f, indent_level,
-                                                     dbgfmt_data->type,
-                                                     dbgfmt_data->data);
-           else
-               fprintf(f, "%*sUNKNOWN\n", indent_level, "");
-           break;
-       default:
-           if ((unsigned int)bc->type < (unsigned int)cur_arch->bc_type_max)
-               cur_arch->bc_print(f, indent_level, bc);
-           else
-               fprintf(f, "%*s_Unknown_\n", indent_level, "");
-           break;
-    }
-    fprintf(f, "%*sMultiple=", indent_level, "");
-    if (!bc->multiple)
-       fprintf(f, "nil (1)");
-    else
-       yasm_expr_print(f, bc->multiple);
-    fprintf(f, "\n%*sLength=%lu\n", indent_level, "", bc->len);
-    fprintf(f, "%*sLine Index=%lu\n", indent_level, "", bc->line);
-    fprintf(f, "%*sOffset=%lx\n", indent_level, "", bc->offset);
-}
-
-/*@null@*/ yasm_intnum *
-yasm_common_calc_bc_dist(yasm_section *sect, /*@null@*/ yasm_bytecode *precbc1,
-                        /*@null@*/ yasm_bytecode *precbc2)
+static yasm_bc_resolve_flags
+bc_data_resolve(yasm_bytecode *bc, int save,
+               yasm_calc_bc_dist_func calc_bc_dist)
 {
-    unsigned int dist;
-    yasm_intnum *intn;
+    bytecode_data *bc_data = (bytecode_data *)bc;
+    yasm_dataval *dv;
+    size_t slen;
 
-    if (precbc2) {
-       dist = precbc2->offset + precbc2->len;
-       if (precbc1) {
-           if (dist < precbc1->offset + precbc1->len) {
-               intn = yasm_intnum_new_uint(precbc1->offset + precbc1->len
-                                           - dist);
-               yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, precbc1->line);
-               return intn;
-           }
-           dist -= precbc1->offset + precbc1->len;
-       }
-       return yasm_intnum_new_uint(dist);
-    } else {
-       if (precbc1) {
-           intn = yasm_intnum_new_uint(precbc1->offset + precbc1->len);
-           yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, precbc1->line);
-           return intn;
-       } else {
-           return yasm_intnum_new_uint(0);
+    /* Count up element sizes, rounding up string length. */
+    STAILQ_FOREACH(dv, &bc_data->datahead, link) {
+       switch (dv->type) {
+           case DV_EMPTY:
+               break;
+           case DV_EXPR:
+               bc->len += bc_data->size;
+               break;
+           case DV_STRING:
+               slen = strlen(dv->data.str_val);
+               /* find count, rounding up to nearest multiple of size */
+               slen = (slen + bc_data->size - 1) / bc_data->size;
+               bc->len += slen*bc_data->size;
+               break;
        }
     }
+
+    return YASM_BC_RESOLVE_MIN_LEN;
 }
 
-static yasm_bc_resolve_flags
-bc_resolve_data(bytecode_data *bc_data, unsigned long *len)
+static int
+bc_data_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+               yasm_output_expr_func output_expr,
+               /*@unused@*/ yasm_output_reloc_func output_reloc)
 {
+    bytecode_data *bc_data = (bytecode_data *)bc;
     yasm_dataval *dv;
     size_t slen;
+    size_t i;
+    unsigned char *bufp_orig = *bufp;
 
-    /* Count up element sizes, rounding up string length. */
     STAILQ_FOREACH(dv, &bc_data->datahead, link) {
        switch (dv->type) {
            case DV_EMPTY:
                break;
            case DV_EXPR:
-               *len += bc_data->size;
+               if (output_expr(&dv->data.expn, *bufp, bc_data->size,
+                               (size_t)(bc_data->size*8), 0,
+                               (unsigned long)(*bufp-bufp_orig), bc, 0, 1, d))
+                   return 1;
+               *bufp += bc_data->size;
                break;
            case DV_STRING:
                slen = strlen(dv->data.str_val);
-               /* find count, rounding up to nearest multiple of size */
-               slen = (slen + bc_data->size - 1) / bc_data->size;
-               *len += slen*bc_data->size;
+               strncpy((char *)*bufp, dv->data.str_val, slen);
+               *bufp += slen;
+               /* pad with 0's to nearest multiple of size */
+               slen %= bc_data->size;
+               if (slen > 0) {
+                   slen = bc_data->size-slen;
+                   for (i=0; i<slen; i++)
+                       YASM_WRITE_8(*bufp, 0);
+               }
                break;
        }
     }
 
-    return YASM_BC_RESOLVE_MIN_LEN;
+    return 0;
+}
+
+yasm_bytecode *
+yasm_bc_create_data(yasm_datavalhead *datahead, unsigned int size,
+                   unsigned long line)
+{
+    bytecode_data *data;
+
+    data = (bytecode_data *)
+       yasm_bc_create_common(&bc_data_callback, sizeof(bytecode_data), line);
+
+    data->datahead = *datahead;
+    data->size = (unsigned char)size;
+
+    return (yasm_bytecode *)data;
+}
+
+static void
+bc_reserve_destroy(yasm_bytecode *bc)
+{
+    bytecode_reserve *reserve = (bytecode_reserve *)bc;
+    yasm_expr_destroy(reserve->numitems);
+}
+
+static void
+bc_reserve_print(const yasm_bytecode *bc, FILE *f, int indent_level)
+{
+    const bytecode_reserve *reserve = (const bytecode_reserve *)bc;
+    fprintf(f, "%*s_Reserve_\n", indent_level, "");
+    fprintf(f, "%*sNum Items=", indent_level, "");
+    yasm_expr_print(reserve->numitems, f);
+    fprintf(f, "\n%*sItem Size=%u\n", indent_level, "",
+           (unsigned int)reserve->itemsize);
 }
 
 static yasm_bc_resolve_flags
-bc_resolve_reserve(bytecode_reserve *reserve, unsigned long *len,
-                  int save, unsigned long line, const yasm_section *sect,
+bc_reserve_resolve(yasm_bytecode *bc, int save,
                   yasm_calc_bc_dist_func calc_bc_dist)
 {
+    bytecode_reserve *reserve = (bytecode_reserve *)bc;
     yasm_bc_resolve_flags retval = YASM_BC_RESOLVE_MIN_LEN;
     /*@null@*/ yasm_expr *temp;
     yasm_expr **tempp;
@@ -566,23 +407,80 @@ bc_resolve_reserve(bytecode_reserve *reserve, unsigned long *len,
         * the circular reference error to filter through.
         */
        if (temp && yasm_expr__contains(temp, YASM_EXPR_FLOAT))
-           yasm__error(line,
+           yasm__error(bc->line,
                N_("expression must not contain floating point value"));
        else
-           yasm__error(line,
+           yasm__error(bc->line,
                N_("attempt to reserve non-constant quantity of space"));
        retval = YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
     } else
-       *len += yasm_intnum_get_uint(num)*reserve->itemsize;
-    yasm_expr_delete(temp);
+       bc->len += yasm_intnum_get_uint(num)*reserve->itemsize;
+    yasm_expr_destroy(temp);
     return retval;
 }
 
+static int
+bc_reserve_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+                  yasm_output_expr_func output_expr,
+                  /*@unused@*/ yasm_output_reloc_func output_reloc)
+{
+    yasm_internal_error(N_("bc_reserve_tobytes called"));
+    /*@notreached@*/
+    return 1;
+}
+
+yasm_bytecode *
+yasm_bc_create_reserve(yasm_expr *numitems, unsigned int itemsize,
+                      unsigned long line)
+{
+    bytecode_reserve *reserve;
+
+    reserve = (bytecode_reserve *)
+       yasm_bc_create_common(&bc_reserve_callback, sizeof(bytecode_reserve),
+                             line);
+
+    /*@-mustfree@*/
+    reserve->numitems = numitems;
+    /*@=mustfree@*/
+    reserve->itemsize = (unsigned char)itemsize;
+
+    return (yasm_bytecode *)reserve;
+}
+
+static void
+bc_incbin_destroy(yasm_bytecode *bc)
+{
+    bytecode_incbin *incbin = (bytecode_incbin *)bc;
+    yasm_xfree(incbin->filename);
+    yasm_expr_destroy(incbin->start);
+    yasm_expr_destroy(incbin->maxlen);
+}
+
+static void
+bc_incbin_print(const yasm_bytecode *bc, FILE *f, int indent_level)
+{
+    const bytecode_incbin *incbin = (const bytecode_incbin *)bc;
+    fprintf(f, "%*s_IncBin_\n", indent_level, "");
+    fprintf(f, "%*sFilename=`%s'\n", indent_level, "",
+           incbin->filename);
+    fprintf(f, "%*sStart=", indent_level, "");
+    if (!incbin->start)
+       fprintf(f, "nil (0)");
+    else
+       yasm_expr_print(incbin->start, f);
+    fprintf(f, "%*sMax Len=", indent_level, "");
+    if (!incbin->maxlen)
+       fprintf(f, "nil (unlimited)");
+    else
+       yasm_expr_print(incbin->maxlen, f);
+    fprintf(f, "\n");
+}
+
 static yasm_bc_resolve_flags
-bc_resolve_incbin(bytecode_incbin *incbin, unsigned long *len, int save,
-                 unsigned long line, const yasm_section *sect,
+bc_incbin_resolve(yasm_bytecode *bc, int save,
                  yasm_calc_bc_dist_func calc_bc_dist)
 {
+    bytecode_incbin *incbin = (bytecode_incbin *)bc;
     FILE *f;
     /*@null@*/ yasm_expr *temp;
     yasm_expr **tempp;
@@ -602,7 +500,7 @@ bc_resolve_incbin(bytecode_incbin *incbin, unsigned long *len, int save,
        num = yasm_expr_get_intnum(tempp, calc_bc_dist);
        if (num)
            start = yasm_intnum_get_uint(num);
-       yasm_expr_delete(temp);
+       yasm_expr_destroy(temp);
        if (!num)
            return YASM_BC_RESOLVE_UNKNOWN_LEN;
     }
@@ -620,7 +518,7 @@ bc_resolve_incbin(bytecode_incbin *incbin, unsigned long *len, int save,
        num = yasm_expr_get_intnum(tempp, calc_bc_dist);
        if (num)
            maxlen = yasm_intnum_get_uint(num);
-       yasm_expr_delete(temp);
+       yasm_expr_destroy(temp);
        if (!num)
            return YASM_BC_RESOLVE_UNKNOWN_LEN;
     }
@@ -632,12 +530,12 @@ bc_resolve_incbin(bytecode_incbin *incbin, unsigned long *len, int save,
     /* Open file and determine its length */
     f = fopen(incbin->filename, "rb");
     if (!f) {
-       yasm__error(line, N_("`incbin': unable to open file `%s'"),
+       yasm__error(bc->line, N_("`incbin': unable to open file `%s'"),
                    incbin->filename);
        return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
     }
     if (fseek(f, 0L, SEEK_END) < 0) {
-       yasm__error(line, N_("`incbin': unable to seek on file `%s'"),
+       yasm__error(bc->line, N_("`incbin': unable to seek on file `%s'"),
                    incbin->filename);
        return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
     }
@@ -646,7 +544,7 @@ bc_resolve_incbin(bytecode_incbin *incbin, unsigned long *len, int save,
 
     /* Compute length of incbin from start, maxlen, and len */
     if (start > flen) {
-       yasm__warning(YASM_WARN_GENERAL, line,
+       yasm__warning(YASM_WARN_GENERAL, bc->line,
                      N_("`incbin': start past end of file `%s'"),
                      incbin->filename);
        start = flen;
@@ -655,12 +553,191 @@ bc_resolve_incbin(bytecode_incbin *incbin, unsigned long *len, int save,
     if (incbin->maxlen)
        if (maxlen < flen)
            flen = maxlen;
-    *len += flen;
+    bc->len += flen;
     return YASM_BC_RESOLVE_MIN_LEN;
 }
 
+static int
+bc_incbin_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+                 yasm_output_expr_func output_expr,
+                 /*@unused@*/ yasm_output_reloc_func output_reloc)
+{
+    bytecode_incbin *incbin = (bytecode_incbin *)bc;
+    FILE *f;
+    /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
+    unsigned long start = 0;
+
+    /* Convert start to integer value */
+    if (incbin->start) {
+       num = yasm_expr_get_intnum(&incbin->start, NULL);
+       if (!num)
+           yasm_internal_error(
+               N_("could not determine start in bc_tobytes_incbin"));
+       start = yasm_intnum_get_uint(num);
+    }
+
+    /* Open file */
+    f = fopen(incbin->filename, "rb");
+    if (!f) {
+       yasm__error(bc->line, N_("`incbin': unable to open file `%s'"),
+                   incbin->filename);
+       return 1;
+    }
+
+    /* Seek to start of data */
+    if (fseek(f, (long)start, SEEK_SET) < 0) {
+       yasm__error(bc->line, N_("`incbin': unable to seek on file `%s'"),
+                   incbin->filename);
+       fclose(f);
+       return 1;
+    }
+
+    /* Read len bytes */
+    if (fread(*bufp, (size_t)bc->len, 1, f) < (size_t)bc->len) {
+       yasm__error(bc->line,
+                   N_("`incbin': unable to read %lu bytes from file `%s'"),
+                   bc->len, incbin->filename);
+       fclose(f);
+       return 1;
+    }
+
+    *bufp += bc->len;
+    fclose(f);
+    return 0;
+}
+
+yasm_bytecode *
+yasm_bc_create_incbin(char *filename, yasm_expr *start, yasm_expr *maxlen,
+                     unsigned long line)
+{
+    bytecode_incbin *incbin;
+
+    incbin = (bytecode_incbin *)
+       yasm_bc_create_common(&bc_incbin_callback, sizeof(bytecode_incbin),
+                             line);
+
+    /*@-mustfree@*/
+    incbin->filename = filename;
+    incbin->start = start;
+    incbin->maxlen = maxlen;
+    /*@=mustfree@*/
+
+    return (yasm_bytecode *)incbin;
+}
+
+static void
+bc_align_destroy(yasm_bytecode *bc)
+{
+}
+
+static void
+bc_align_print(const yasm_bytecode *bc, FILE *f, int indent_level)
+{
+    const bytecode_align *align = (const bytecode_align *)bc;
+    fprintf(f, "%*s_Align_\n", indent_level, "");
+    fprintf(f, "%*sBoundary=%lu\n", indent_level, "", align->boundary);
+}
+
+static yasm_bc_resolve_flags
+bc_align_resolve(yasm_bytecode *bc, int save,
+                yasm_calc_bc_dist_func calc_bc_dist)
+{
+    yasm_internal_error(N_("TODO: align bytecode not implemented!"));
+    /*@notreached@*/
+    return YASM_BC_RESOLVE_ERROR;
+}
+
+static int
+bc_align_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+                yasm_output_expr_func output_expr,
+                /*@unused@*/ yasm_output_reloc_func output_reloc)
+{
+    yasm_internal_error(N_("TODO: align bytecode not implemented!"));
+    /*@notreached@*/
+    return 1;
+}
+
+yasm_bytecode *
+yasm_bc_create_align(unsigned long boundary, unsigned long line)
+{
+    bytecode_align *align;
+
+    align = (bytecode_align *)
+       yasm_bc_create_common(&bc_align_callback, sizeof(bytecode_align),
+                             line);
+
+    align->boundary = boundary;
+
+    return (yasm_bytecode *)align;
+}
+
+yasm_section *
+yasm_bc_get_section(yasm_bytecode *bc)
+{
+    return bc->section;
+}
+
+void
+yasm_bc_destroy(yasm_bytecode *bc)
+{
+    if (!bc)
+       return;
+
+    if (bc->callback)
+       bc->callback->destroy(bc);
+    yasm_expr_destroy(bc->multiple);
+    yasm_xfree(bc);
+}
+
+void
+yasm_bc_print(const yasm_bytecode *bc, FILE *f, int indent_level)
+{
+    if (!bc->callback)
+       fprintf(f, "%*s_Empty_\n", indent_level, "");
+    else
+       bc->callback->print(bc, f, indent_level);
+    fprintf(f, "%*sMultiple=", indent_level, "");
+    if (!bc->multiple)
+       fprintf(f, "nil (1)");
+    else
+       yasm_expr_print(bc->multiple, f);
+    fprintf(f, "\n%*sLength=%lu\n", indent_level, "", bc->len);
+    fprintf(f, "%*sLine Index=%lu\n", indent_level, "", bc->line);
+    fprintf(f, "%*sOffset=%lx\n", indent_level, "", bc->offset);
+}
+
+/*@null@*/ yasm_intnum *
+yasm_common_calc_bc_dist(/*@null@*/ yasm_bytecode *precbc1,
+                        /*@null@*/ yasm_bytecode *precbc2)
+{
+    unsigned int dist;
+    yasm_intnum *intn;
+
+    if (precbc2) {
+       dist = precbc2->offset + precbc2->len;
+       if (precbc1) {
+           if (dist < precbc1->offset + precbc1->len) {
+               intn = yasm_intnum_create_uint(precbc1->offset + precbc1->len
+                                              - dist);
+               yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, precbc1->line);
+               return intn;
+           }
+           dist -= precbc1->offset + precbc1->len;
+       }
+       return yasm_intnum_create_uint(dist);
+    } else {
+       if (precbc1) {
+           intn = yasm_intnum_create_uint(precbc1->offset + precbc1->len);
+           yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, precbc1->line);
+           return intn;
+       } else {
+           return yasm_intnum_create_uint(0);
+       }
+    }
+}
+
 yasm_bc_resolve_flags
-yasm_bc_resolve(yasm_bytecode *bc, int save, const yasm_section *sect,
+yasm_bc_resolve(yasm_bytecode *bc, int save,
                yasm_calc_bc_dist_func calc_bc_dist)
 {
     yasm_bc_resolve_flags retval = YASM_BC_RESOLVE_MIN_LEN;
@@ -670,34 +747,10 @@ yasm_bc_resolve(yasm_bytecode *bc, int save, const yasm_section *sect,
 
     bc->len = 0;       /* start at 0 */
 
-    switch (bc->type) {
-       case YASM_BC__EMPTY:
-           yasm_internal_error(N_("got empty bytecode in bc_calc_len"));
-           /*break;*/
-       case YASM_BC__DATA:
-           retval = bc_resolve_data((bytecode_data *)bc, &bc->len);
-           break;
-       case YASM_BC__RESERVE:
-           retval = bc_resolve_reserve((bytecode_reserve *)bc, &bc->len,
-                                       save, bc->line, sect, calc_bc_dist);
-           break;
-       case YASM_BC__INCBIN:
-           retval = bc_resolve_incbin((bytecode_incbin *)bc, &bc->len,
-                                      save, bc->line, sect, calc_bc_dist);
-           break;
-       case YASM_BC__ALIGN:
-           /* TODO */
-           yasm_internal_error(N_("TODO: align bytecode not implemented!"));
-           /*break;*/
-       case YASM_BC__OBJFMT_DATA:
-           yasm_internal_error(N_("resolving objfmt data bytecode?"));
-           /*break;*/
-       default:
-           if ((unsigned int)bc->type < (unsigned int)cur_arch->bc_type_max)
-               retval = cur_arch->bc_resolve(bc, save, sect, calc_bc_dist);
-           else
-               yasm_internal_error(N_("Unknown bytecode type"));
-    }
+    if (!bc->callback)
+       yasm_internal_error(N_("got empty bytecode in bc_resolve"));
+    else
+       retval = bc->callback->resolve(bc, save, calc_bc_dist);
 
     /* Multiply len by number of multiples */
     if (bc->multiple) {
@@ -719,7 +772,7 @@ yasm_bc_resolve(yasm_bytecode *bc, int save, const yasm_section *sect,
            }
        } else
            bc->len *= yasm_intnum_get_uint(num);
-       yasm_expr_delete(temp);
+       yasm_expr_destroy(temp);
     }
 
     /* If we got an error somewhere along the line, clear out any calc len */
@@ -729,110 +782,16 @@ yasm_bc_resolve(yasm_bytecode *bc, int save, const yasm_section *sect,
     return retval;
 }
 
-static int
-bc_tobytes_data(bytecode_data *bc_data, unsigned char **bufp,
-               const yasm_section *sect, yasm_bytecode *bc, void *d,
-               yasm_output_expr_func output_expr)
-    /*@sets **bufp@*/
-{
-    yasm_dataval *dv;
-    size_t slen;
-    size_t i;
-    unsigned char *bufp_orig = *bufp;
-
-    STAILQ_FOREACH(dv, &bc_data->datahead, link) {
-       switch (dv->type) {
-           case DV_EMPTY:
-               break;
-           case DV_EXPR:
-               if (output_expr(&dv->data.expn, *bufp, bc_data->size,
-                               (size_t)(bc_data->size*8), 0,
-                               (unsigned long)(*bufp-bufp_orig), sect, bc, 0,
-                               1, d))
-                   return 1;
-               *bufp += bc_data->size;
-               break;
-           case DV_STRING:
-               slen = strlen(dv->data.str_val);
-               strncpy((char *)*bufp, dv->data.str_val, slen);
-               *bufp += slen;
-               /* pad with 0's to nearest multiple of size */
-               slen %= bc_data->size;
-               if (slen > 0) {
-                   slen = bc_data->size-slen;
-                   for (i=0; i<slen; i++)
-                       YASM_WRITE_8(*bufp, 0);
-               }
-               break;
-       }
-    }
-
-    return 0;
-}
-
-static int
-bc_tobytes_incbin(bytecode_incbin *incbin, unsigned char **bufp,
-                 unsigned long len, unsigned long line)
-    /*@sets **bufp@*/
-{
-    FILE *f;
-    /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
-    unsigned long start = 0;
-
-    /* Convert start to integer value */
-    if (incbin->start) {
-       num = yasm_expr_get_intnum(&incbin->start, NULL);
-       if (!num)
-           yasm_internal_error(
-               N_("could not determine start in bc_tobytes_incbin"));
-       start = yasm_intnum_get_uint(num);
-    }
-
-    /* Open file */
-    f = fopen(incbin->filename, "rb");
-    if (!f) {
-       yasm__error(line, N_("`incbin': unable to open file `%s'"),
-                   incbin->filename);
-       return 1;
-    }
-
-    /* Seek to start of data */
-    if (fseek(f, (long)start, SEEK_SET) < 0) {
-       yasm__error(line, N_("`incbin': unable to seek on file `%s'"),
-                   incbin->filename);
-       fclose(f);
-       return 1;
-    }
-
-    /* Read len bytes */
-    if (fread(*bufp, (size_t)len, 1, f) < (size_t)len) {
-       yasm__error(line,
-                   N_("`incbin': unable to read %lu bytes from file `%s'"),
-                   len, incbin->filename);
-       fclose(f);
-       return 1;
-    }
-
-    *bufp += len;
-    fclose(f);
-    return 0;
-}
-
 /*@null@*/ /*@only@*/ unsigned char *
 yasm_bc_tobytes(yasm_bytecode *bc, unsigned char *buf, unsigned long *bufsize,
                /*@out@*/ unsigned long *multiple, /*@out@*/ int *gap,
-               const yasm_section *sect, void *d,
-               yasm_output_expr_func output_expr,
-               /*@null@*/ yasm_output_reloc_func output_reloc,
-               /*@null@*/ yasm_output_bc_objfmt_data_func
-                   output_bc_objfmt_data)
+               void *d, yasm_output_expr_func output_expr,
+               /*@null@*/ yasm_output_reloc_func output_reloc)
     /*@sets *buf@*/
 {
     /*@only@*/ /*@null@*/ unsigned char *mybuf = NULL;
     unsigned char *origbuf, *destbuf;
     /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
-    bytecode_objfmt_data *objfmt_data;
-    bytecode_dbgfmt_data *dbgfmt_data;
     unsigned long datasize;
     int error = 0;
 
@@ -852,7 +811,8 @@ yasm_bc_tobytes(yasm_bytecode *bc, unsigned char *buf, unsigned long *bufsize,
     datasize = bc->len / (*multiple);
     *bufsize = datasize;
 
-    if (bc->type == YASM_BC__RESERVE) {
+    /* special case for reserve bytecodes */
+    if (bc->callback == &bc_reserve_callback) {
        *gap = 1;
        return NULL;    /* we didn't allocate a buffer */
     }
@@ -868,48 +828,11 @@ yasm_bc_tobytes(yasm_bytecode *bc, unsigned char *buf, unsigned long *bufsize,
        destbuf = buf;
     }
 
-    switch (bc->type) {
-       case YASM_BC__EMPTY:
-           yasm_internal_error(N_("got empty bytecode in bc_tobytes"));
-           /*break;*/
-       case YASM_BC__DATA:
-           error = bc_tobytes_data((bytecode_data *)bc, &destbuf, sect, bc, d,
-                                   output_expr);
-           break;
-       case YASM_BC__INCBIN:
-           error = bc_tobytes_incbin((bytecode_incbin *)bc, &destbuf, bc->len,
-                                     bc->line);
-           break;
-       case YASM_BC__ALIGN:
-           /* TODO */
-           yasm_internal_error(N_("TODO: align bytecode not implemented!"));
-           /*break;*/
-       case YASM_BC__OBJFMT_DATA:
-           objfmt_data = (bytecode_objfmt_data *)bc;
-           if (output_bc_objfmt_data)
-               error = output_bc_objfmt_data(objfmt_data->type,
-                                             objfmt_data->data, &destbuf);
-           else
-               yasm_internal_error(
-                   N_("Have objfmt data bytecode but no way to output it"));
-           break;
-       case YASM_BC__DBGFMT_DATA:
-           dbgfmt_data = (bytecode_dbgfmt_data *)bc;
-           if (dbgfmt_data->df->bc_dbgfmt_data_output)
-               error = dbgfmt_data->df->bc_dbgfmt_data_output(bc,
-                           dbgfmt_data->type, dbgfmt_data->data, &destbuf,
-                           sect, output_reloc, d);
-           else
-               yasm_internal_error(
-                   N_("Have dbgfmt data bytecode but no way to output it"));
-           break;
-       default:
-           if ((unsigned int)bc->type < (unsigned int)cur_arch->bc_type_max)
-               error = cur_arch->bc_tobytes(bc, &destbuf, sect, d,
-                                            output_expr);
-           else
-               yasm_internal_error(N_("Unknown bytecode type"));
-    }
+    if (!bc->callback)
+       yasm_internal_error(N_("got empty bytecode in bc_tobytes"));
+    else
+       error = bc->callback->tobytes(bc, &destbuf, d, output_expr,
+                                     output_reloc);
 
     if (!error && ((unsigned long)(destbuf - origbuf) != datasize))
        yasm_internal_error(
@@ -917,68 +840,8 @@ yasm_bc_tobytes(yasm_bytecode *bc, unsigned char *buf, unsigned long *bufsize,
     return mybuf;
 }
 
-yasm_bytecode *
-yasm_bcs_last(yasm_bytecodehead *headp)
-{
-    return STAILQ_LAST(headp, yasm_bytecode, link);
-}
-
-void
-yasm_bcs_delete(yasm_bytecodehead *headp)
-{
-    yasm_bytecode *cur, *next;
-
-    cur = STAILQ_FIRST(headp);
-    while (cur) {
-       next = STAILQ_NEXT(cur, link);
-       yasm_bc_delete(cur);
-       cur = next;
-    }
-    STAILQ_INIT(headp);
-    yasm_xfree(headp);
-}
-
-yasm_bytecode *
-yasm_bcs_append(yasm_bytecodehead *headp, yasm_bytecode *bc)
-{
-    if (bc) {
-       if (bc->type != YASM_BC__EMPTY) {
-           STAILQ_INSERT_TAIL(headp, bc, link);
-           return bc;
-       } else {
-           yasm_xfree(bc);
-       }
-    }
-    return (yasm_bytecode *)NULL;
-}
-
-void
-yasm_bcs_print(FILE *f, int indent_level, const yasm_bytecodehead *headp)
-{
-    yasm_bytecode *cur;
-
-    STAILQ_FOREACH(cur, headp, link) {
-       fprintf(f, "%*sNext Bytecode:\n", indent_level, "");
-       yasm_bc_print(f, indent_level+1, cur);
-    }
-}
-
-int
-yasm_bcs_traverse(yasm_bytecodehead *headp, void *d,
-                 int (*func) (yasm_bytecode *bc, /*@null@*/ void *d))
-{
-    yasm_bytecode *cur;
-
-    STAILQ_FOREACH(cur, headp, link) {
-       int retval = func(cur, d);
-       if (retval != 0)
-           return retval;
-    }
-    return 0;
-}
-
 yasm_dataval *
-yasm_dv_new_expr(yasm_expr *expn)
+yasm_dv_create_expr(yasm_expr *expn)
 {
     yasm_dataval *retval = yasm_xmalloc(sizeof(yasm_dataval));
 
@@ -989,7 +852,7 @@ yasm_dv_new_expr(yasm_expr *expn)
 }
 
 yasm_dataval *
-yasm_dv_new_string(char *str_val)
+yasm_dv_create_string(char *str_val)
 {
     yasm_dataval *retval = yasm_xmalloc(sizeof(yasm_dataval));
 
@@ -1000,7 +863,7 @@ yasm_dv_new_string(char *str_val)
 }
 
 void
-yasm_dvs_delete(yasm_datavalhead *headp)
+yasm_dvs_destroy(yasm_datavalhead *headp)
 {
     yasm_dataval *cur, *next;
 
@@ -1009,7 +872,7 @@ yasm_dvs_delete(yasm_datavalhead *headp)
        next = STAILQ_NEXT(cur, link);
        switch (cur->type) {
            case DV_EXPR:
-               yasm_expr_delete(cur->data.expn);
+               yasm_expr_destroy(cur->data.expn);
                break;
            case DV_STRING:
                yasm_xfree(cur->data.str_val);
@@ -1034,7 +897,7 @@ yasm_dvs_append(yasm_datavalhead *headp, yasm_dataval *dv)
 }
 
 void
-yasm_dvs_print(FILE *f, int indent_level, const yasm_datavalhead *head)
+yasm_dvs_print(const yasm_datavalhead *head, FILE *f, int indent_level)
 {
     yasm_dataval *cur;
 
@@ -1045,7 +908,7 @@ yasm_dvs_print(FILE *f, int indent_level, const yasm_datavalhead *head)
                break;
            case DV_EXPR:
                fprintf(f, "%*sExpr=", indent_level, "");
-               yasm_expr_print(f, cur->data.expn);
+               yasm_expr_print(cur->data.expn, f);
                fprintf(f, "\n");
                break;
            case DV_STRING:
@@ -1056,23 +919,6 @@ yasm_dvs_print(FILE *f, int indent_level, const yasm_datavalhead *head)
     }
 }
 
-yasm_bytecodehead *
-yasm_bcs_new(void)
-{
-    yasm_bytecodehead *headp;
-    headp = yasm_xmalloc(sizeof(yasm_bytecodehead));
-    STAILQ_INIT(headp);
-    return headp;
-}
-
-/* Non-macro yasm_bcs_first() for non-YASM_LIB_INTERNAL users. */
-#undef yasm_bcs_first
-yasm_bytecode *
-yasm_bcs_first(yasm_bytecodehead *headp)
-{
-    return STAILQ_FIRST(headp);
-}
-
 /* Non-macro yasm_dvs_initialize() for non-YASM_LIB_INTERNAL users. */
 #undef yasm_dvs_initialize
 void
index dd67c8f24c6706a15914e130893344c9d26b035a..2c3d13ece8c35558f1293645d63bb9cc436ea44f 100644 (file)
@@ -44,46 +44,30 @@ typedef struct yasm_dataval yasm_dataval;
 typedef struct yasm_datavalhead yasm_datavalhead;
 
 #ifdef YASM_LIB_INTERNAL
-/*@reldef@*/ STAILQ_HEAD(yasm_bytecodehead, yasm_bytecode);
 /*@reldef@*/ STAILQ_HEAD(yasm_datavalhead, yasm_dataval);
-
-/** Built-in bytecode types.  Additional types may be #yasm_arch defined
- * starting at #YASM_BYTECODE_TYPE_BASE.
- * \internal
- */
-typedef enum {
-    YASM_BC__EMPTY = 0,            /**< Empty; should not exist except temporarily. */
-    YASM_BC__DATA,         /**< One or more data value(s). */
-    YASM_BC__RESERVE,      /**< Reserved space. */
-    YASM_BC__INCBIN,       /**< Included binary file. */
-    YASM_BC__ALIGN,        /**< Alignment to a boundary. */
-    YASM_BC__DBGFMT_DATA,   /**< yasm_dbgfmt specific data. */
-    YASM_BC__OBJFMT_DATA    /**< yasm_objfmt specific data. */
-} yasm_bytecode_type;
-
-/** Starting yasm_bytecode_type numeric value available for yasm_arch use. */
-#define YASM_BYTECODE_TYPE_BASE                YASM_BC__OBJFMT_DATA+1
 #endif
 
-/** Initialize bytecode utility functions.
- * \param a    architecture used during bytecode operations.
- */
-void yasm_bc_initialize(yasm_arch *a);
+/** Return value flags for yasm_bc_resolve(). */
+typedef enum {
+    YASM_BC_RESOLVE_NONE = 0,          /**< Ok, but length is not minimum. */
+    YASM_BC_RESOLVE_ERROR = 1<<0,      /**< Error found, output. */
+    YASM_BC_RESOLVE_MIN_LEN = 1<<1,    /**< Length is minimum possible. */
+    YASM_BC_RESOLVE_UNKNOWN_LEN = 1<<2 /**< Length indeterminate. */
+} yasm_bc_resolve_flags;
 
 /** Create an immediate value from an unsigned integer.
  * \param int_val   unsigned integer
- * \param lindex    line index (as from yasm_linemgr) for error/warning
- *                 purposes.
+ * \param line     virtual line (from yasm_linemap)
  * \return Newly allocated immediate value.
  */
-/*@only@*/ yasm_immval *yasm_imm_new_int(unsigned long int_val,
-                                        unsigned long lindex);
+/*@only@*/ yasm_immval *yasm_imm_create_int(unsigned long int_val,
+                                           unsigned long line);
 
 /** Create an immediate value from an expression.
  * \param e    expression (kept, do not free).
  * \return Newly allocated immediate value.
  */
-/*@only@*/ yasm_immval *yasm_imm_new_expr(/*@keep@*/ yasm_expr *e);
+/*@only@*/ yasm_immval *yasm_imm_create_expr(/*@keep@*/ yasm_expr *e);
 
 /** Get the displacement portion of an effective address.
  * \param ea   effective address
@@ -111,14 +95,14 @@ void yasm_ea_set_nosplit(yasm_effaddr *ea, unsigned int nosplit);
 /** Delete (free allocated memory for) an effective address.
  * \param ea   effective address (only pointer to it).
  */
-void yasm_ea_delete(/*@only@*/ yasm_effaddr *ea);
+void yasm_ea_destroy(/*@only@*/ yasm_effaddr *ea);
 
 /** Print an effective address.  For debugging purposes.
  * \param f            file
  * \param indent_level indentation level
  * \param ea           effective address
  */
-void yasm_ea_print(FILE *f, int indent_level, const yasm_effaddr *ea);
+void yasm_ea_print(const yasm_effaddr *ea, FILE *f, int indent_level);
 
 /** Set multiple field of a bytecode.
  * A bytecode can be repeated a number of times when output.  This function
@@ -128,37 +112,24 @@ void yasm_ea_print(FILE *f, int indent_level, const yasm_effaddr *ea);
  */
 void yasm_bc_set_multiple(yasm_bytecode *bc, /*@keep@*/ yasm_expr *e);
 
-#ifdef YASM_LIB_INTERNAL
-/** Create a bytecode of any specified type.
- * \param type         bytecode type
- * \param datasize     size of type-specific data (in bytes)
- * \param lindex       line index (as from yasm_linemgr) for the bytecode
- * \return Newly allocated bytecode of the specified type.
- */
-/*@only@*/ yasm_bytecode *yasm_bc_new_common(yasm_bytecode_type type,
-                                            size_t datasize,
-                                            unsigned long lindex);
-#endif
-
 /** Create a bytecode containing data value(s).
  * \param datahead     list of data values (kept, do not free)
  * \param size         storage size (in bytes) for each data value
- * \param lindex       line index (as from yasm_linemgr) for the bytecode
+ * \param line         virtual line (from yasm_linemap)
  * \return Newly allocated bytecode.
  */
-/*@only@*/ yasm_bytecode *yasm_bc_new_data(yasm_datavalhead *datahead,
-                                          unsigned int size,
-                                          unsigned long lindex);
+/*@only@*/ yasm_bytecode *yasm_bc_create_data
+    (yasm_datavalhead *datahead, unsigned int size, unsigned long line);
 
 /** Create a bytecode reserving space.
  * \param numitems     number of reserve "items" (kept, do not free)
  * \param itemsize     reserved size (in bytes) for each item
- * \param lindex       line index (as from yasm_linemgr) for the bytecode
+ * \param line         virtual line (from yasm_linemap)
  * \return Newly allocated bytecode.
  */
-/*@only@*/ yasm_bytecode *yasm_bc_new_reserve(/*@only@*/ yasm_expr *numitems,
-                                             unsigned int itemsize,
-                                             unsigned long lindex);
+/*@only@*/ yasm_bytecode *yasm_bc_create_reserve
+    (/*@only@*/ yasm_expr *numitems, unsigned int itemsize,
+     unsigned long line);
 
 /** Create a bytecode that includes a binary file verbatim.
  * \param filename     full path to binary file (kept, do not free)
@@ -166,56 +137,40 @@ void yasm_bc_set_multiple(yasm_bytecode *bc, /*@keep@*/ yasm_expr *e);
  *                     (kept, do not free); may be NULL to indicate 0
  * \param maxlen       maximum number of bytes to read from the file (kept, do
  *                     do not free); may be NULL to indicate no maximum
- * \param lindex       line index (as from yasm_linemgr) for the bytecode
+ * \param line         virtual line (from yasm_linemap) for the bytecode
  * \return Newly allocated bytecode.
  */
-/*@only@*/ yasm_bytecode *yasm_bc_new_incbin
+/*@only@*/ yasm_bytecode *yasm_bc_create_incbin
     (/*@only@*/ char *filename, /*@only@*/ /*@null@*/ yasm_expr *start,
-     /*@only@*/ /*@null@*/ yasm_expr *maxlen, unsigned long lindex);
+     /*@only@*/ /*@null@*/ yasm_expr *maxlen, unsigned long line);
 
 /** Create a bytecode that aligns the following bytecode to a boundary.
  * \param boundary     byte alignment (must be a power of two)
- * \param lindex       line index (as from yasm_linemgr) for the bytecode
- * \return Newly allocated bytecode.
- */
-/*@only@*/ yasm_bytecode *yasm_bc_new_align(unsigned long boundary,
-                                           unsigned long lindex);
-
-/** Create a bytecode that includes yasm_objfmt-specific data.
- * \param type         yasm_objfmt-specific type
- * \param len          length (in bytes) of data
- * \param of           yasm_objfmt storing the data
- * \param data         data (kept, do not free)
- * \param lindex       line index (as from yasm_linemgr) for the bytecode
+ * \param line         virtual line (from yasm_linemap)
  * \return Newly allocated bytecode.
  */
-/*@only@*/ yasm_bytecode *yasm_bc_new_objfmt_data
-    (unsigned int type, unsigned long len, yasm_objfmt *of,
-     /*@only@*/ void *data, unsigned long lindex);
+/*@only@*/ yasm_bytecode *yasm_bc_create_align
+    (unsigned long boundary, unsigned long line);
 
-/** Create a bytecode that includes yasm_dbgfmt-specific data.
- * \param type         yasm_dbgfmt-specific type
- * \param len          length (in bytes) of data
- * \param df           yasm_dbgfmt storing the data
- * \param data         data (kept, do not free)
- * \param lindex       line index (as from yasm_linemgr) for the bytecode
- * \return Newly allocated bytecode.
+/** Get the section that contains a particular bytecode.
+ * \param bc   bytecode
+ * \return Section containing bc (can be NULL if bytecode is not part of a
+ *        section).
  */
-/*@only@*/ yasm_bytecode *yasm_bc_new_dbgfmt_data
-    (unsigned int type, unsigned long len, yasm_dbgfmt *df,
-     /*@only@*/ void *data, unsigned long lindex);
-
+/*@dependent@*/ /*@null@*/ yasm_section *yasm_bc_get_section
+    (yasm_bytecode *bc);
+    
 /** Delete (free allocated memory for) a bytecode.
  * \param bc   bytecode (only pointer to it); may be NULL
  */
-void yasm_bc_delete(/*@only@*/ /*@null@*/ yasm_bytecode *bc);
+void yasm_bc_destroy(/*@only@*/ /*@null@*/ yasm_bytecode *bc);
 
 /** Print a bytecode.  For debugging purposes.
  * \param f            file
  * \param indent_level indentation level
  * \param bc           bytecode
  */
-void yasm_bc_print(FILE *f, int indent_level, const yasm_bytecode *bc);
+void yasm_bc_print(const yasm_bytecode *bc, FILE *f, int indent_level);
 
 /** Common version of calc_bc_dist that takes offsets from bytecodes.
  * Should be used for the final stages of optimizers as well as in yasm_objfmt
@@ -223,16 +178,7 @@ void yasm_bc_print(FILE *f, int indent_level, const yasm_bytecode *bc);
  * \see yasm_calc_bc_dist_func for parameter descriptions.
  */
 /*@null@*/ yasm_intnum *yasm_common_calc_bc_dist
-    (yasm_section *sect, /*@null@*/ yasm_bytecode *precbc1,
-     /*@null@*/ yasm_bytecode *precbc2);
-
-/** Return value flags for yasm_bc_resolve(). */
-typedef enum {
-    YASM_BC_RESOLVE_NONE = 0,          /**< Ok, but length is not minimum. */
-    YASM_BC_RESOLVE_ERROR = 1<<0,      /**< Error found, output. */
-    YASM_BC_RESOLVE_MIN_LEN = 1<<1,    /**< Length is minimum possible. */
-    YASM_BC_RESOLVE_UNKNOWN_LEN = 1<<2 /**< Length indeterminate. */
-} yasm_bc_resolve_flags;
+    (/*@null@*/ yasm_bytecode *precbc1, /*@null@*/ yasm_bytecode *precbc2);
 
 /** Resolve labels in a bytecode, and calculate its length.
  * Tries to minimize the length as much as possible.
@@ -245,14 +191,12 @@ typedef enum {
  *                     values returned by calc_bc_dist except temporarily to
  *                     try to minimize the length); when nonzero, all fields
  *                     in bc may be modified by this function
- * \param sect         section containing the bytecode
  * \param calc_bc_dist function used to determine bytecode distance
  * \return Flags indicating whether the length is the minimum possible,
  *        indeterminate, and if there was an error recognized (and output)
  *        during execution.
  */
 yasm_bc_resolve_flags yasm_bc_resolve(yasm_bytecode *bc, int save,
-                                     const yasm_section *sect,
                                      yasm_calc_bc_dist_func calc_bc_dist);
 
 /** Convert a bytecode into its byte representation.
@@ -265,12 +209,9 @@ yasm_bc_resolve_flags yasm_bc_resolve(yasm_bytecode *bc, int save,
  * \param gap          if nonzero, indicates the data does not really need to
  *                     exist in the object file; if nonzero, contents of buf
  *                     are undefined [output]
- * \param sect         section containing the bytecode
- * \param d            data to pass to each call to output_expr
+ * \param d            data to pass to each call to output_expr/output_reloc
  * \param output_expr  function to call to convert expressions into their byte
  *                     representation
- * \param output_bc_objfmt_data        function to call to convert yasm_objfmt data
- *                             bytecodes into their byte representation
  * \param output_reloc function to call to output relocation entries
  *                     for a single sym
  * \return Newly allocated buffer that should be used instead of buf for
@@ -281,84 +222,28 @@ yasm_bc_resolve_flags yasm_bc_resolve(yasm_bytecode *bc, int save,
  */
 /*@null@*/ /*@only@*/ unsigned char *yasm_bc_tobytes
     (yasm_bytecode *bc, unsigned char *buf, unsigned long *bufsize,
-     /*@out@*/ unsigned long *multiple, /*@out@*/ int *gap,
-     const yasm_section *sect, void *d, yasm_output_expr_func output_expr,
-     /*@null@*/ yasm_output_reloc_func output_reloc,
-     /*@null@*/ yasm_output_bc_objfmt_data_func output_bc_objfmt_data)
+     /*@out@*/ unsigned long *multiple, /*@out@*/ int *gap, void *d,
+     yasm_output_expr_func output_expr,
+     /*@null@*/ yasm_output_reloc_func output_reloc)
     /*@sets *buf@*/;
 
-/** Create list of bytecodes.
- * \return Newly allocated bytecode list.
- */
-/*@only@*/ yasm_bytecodehead *yasm_bcs_new(void);
-
-/** Get the first bytecode in a list of bytecodes.
- * \param headp                bytecode list
- * \return First bytecode in list (NULL if list is empty).
- */
-/*@null@*/ yasm_bytecode *yasm_bcs_first(yasm_bytecodehead *headp);
-#ifdef YASM_LIB_INTERNAL
-#define yasm_bcs_first(headp)  STAILQ_FIRST(headp)
-#endif
-
-/** Get the last bytecode in a list of bytecodes.
- * \param headp                bytecode list
- * \return Last bytecode in list (NULL if list is empty).
- */
-/*@null@*/ yasm_bytecode *yasm_bcs_last(yasm_bytecodehead *headp);
-
-/** Delete (free allocated memory for) a list of bytecodes.
- * \param headp                bytecode list
- */
-void yasm_bcs_delete(/*@only@*/ yasm_bytecodehead *headp);
-
-/** Add bytecode to the end of a list of bytecodes.
- * \note Does not make a copy of bc; so don't pass this function static or
- *      local variables, and discard the bc pointer after calling this
- *      function.
- * \param headp                bytecode list
- * \param bc           bytecode (may be NULL)
- * \return If bytecode was actually appended (it wasn't NULL or empty), the
- *        bytecode; otherwise NULL.
- */
-/*@only@*/ /*@null@*/ yasm_bytecode *yasm_bcs_append
-    (yasm_bytecodehead *headp,
-     /*@returned@*/ /*@only@*/ /*@null@*/ yasm_bytecode *bc);
-
-/** Print a bytecode list.  For debugging purposes.
- * \param f            file
- * \param indent_level indentation level
- * \param headp                bytecode list
- */
-void yasm_bcs_print(FILE *f, int indent_level, const yasm_bytecodehead *headp);
-
-/** Traverses a bytecode list, calling a function on each bytecode.
- * \param headp        bytecode list
- * \param d    data pointer passed to func on each call
- * \param func function
- * \return Stops early (and returns func's return value) if func returns a
- *        nonzero value; otherwise 0.
- */
-int yasm_bcs_traverse(yasm_bytecodehead *headp, /*@null@*/ void *d,
-                     int (*func) (yasm_bytecode *bc, /*@null@*/ void *d));
-
 /** Create a new data value from an expression.
  * \param expn expression
  * \return Newly allocated data value.
  */
-yasm_dataval *yasm_dv_new_expr(/*@keep@*/ yasm_expr *expn);
+yasm_dataval *yasm_dv_create_expr(/*@keep@*/ yasm_expr *expn);
 
 /** Create a new data value from a float.
  * \param flt  floating point value
  * \return Newly allocated data value.
  */
-yasm_dataval *yasm_dv_new_float(/*@keep@*/ yasm_floatnum *flt);
+yasm_dataval *yasm_dv_create_float(/*@keep@*/ yasm_floatnum *flt);
 
 /** Create a new data value from a string.
  * \param str_val      string
  * \return Newly allocated data value.
  */
-yasm_dataval *yasm_dv_new_string(/*@keep@*/ char *str_val);
+yasm_dataval *yasm_dv_create_string(/*@keep@*/ char *str_val);
 
 /** Initialize a list of data values.
  * \param headp        list of data values
@@ -371,7 +256,7 @@ void yasm_dvs_initialize(yasm_datavalhead *headp);
 /** Delete (free allocated memory for) a list of data values.
  * \param headp        list of data values
  */
-void yasm_dvs_delete(yasm_datavalhead *headp);
+void yasm_dvs_destroy(yasm_datavalhead *headp);
 
 /** Add data value to the end of a list of data values.
  * \note Does not make a copy of the data value; so don't pass this function
@@ -390,6 +275,6 @@ void yasm_dvs_delete(yasm_datavalhead *headp);
  * \param indent_level indentation level
  * \param headp                data value list
  */
-void yasm_dvs_print(FILE *f, int indent_level, const yasm_datavalhead *headp);
+void yasm_dvs_print(const yasm_datavalhead *headp, FILE *f, int indent_level);
 
 #endif
index 01bf6ec0d58996e95ad3c548200dbb3ca3262493..f0d0ccd4c60c5d3a4386bc4d079c6fbd8ffaad0d 100644 (file)
 #ifndef YASM_CORETYPE_H
 #define YASM_CORETYPE_H
 
-/** Architecture interface.  \see arch.h for details. */
+/** Architecture instance (mostly opaque type).  \see arch.h for details. */
 typedef struct yasm_arch yasm_arch;
 /** Preprocessor interface.  \see preproc.h for details. */
 typedef struct yasm_preproc yasm_preproc;
-/** Parser interface.  \see parser.h for details. */
+/** Parser instance (mostly opaque type).  \see parser.h for details. */
 typedef struct yasm_parser yasm_parser;
 /** Optimizer interface.  \see optimizer.h for details. */
 typedef struct yasm_optimizer yasm_optimizer;
@@ -47,18 +47,28 @@ typedef struct yasm_objfmt yasm_objfmt;
 /** Debug format interface.  \see dbgfmt.h for details. */
 typedef struct yasm_dbgfmt yasm_dbgfmt;
 
+/** YASM associated data callback structure.  Many data structures can have
+ * arbitrary data associated with them.
+ */
+typedef struct yasm_assoc_data_callback {
+    void (*destroy) (/*@only@*/ void *data);
+    void (*print) (void *data, FILE *f, int indent_level);
+} yasm_assoc_data_callback;
+
 /** Bytecode (opaque type).
  * \see bytecode.h for related functions.
  * Define YASM_BC_INTERNAL to get visible internals.
  */
 typedef struct yasm_bytecode yasm_bytecode;
-/** List of bytecodes (opaque type).  \see bytecode.h for related functions. */
-typedef struct yasm_bytecodehead yasm_bytecodehead;
+
+/** Object (opaque type).  \see section.h for related functions. */
+typedef struct yasm_object yasm_object;
 
 /** Section (opaque type).  \see section.h for related functions. */
 typedef struct yasm_section yasm_section;
-/** List of sections (opaque type).  \see section.h for related functions. */
-typedef struct yasm_sectionhead yasm_sectionhead;
+
+/** Symbol table (opaque type).  \see symrec.h for related functions. */
+typedef struct yasm_symtab yasm_symtab;
 
 /** Symbol record (opaque type).  \see symrec.h for related functions. */
 typedef struct yasm_symrec yasm_symrec;
@@ -75,8 +85,10 @@ typedef struct yasm_intnum yasm_intnum;
  */
 typedef struct yasm_floatnum yasm_floatnum;
 
-/** Line number management interface.  \see linemgr.h for more details. */
-typedef struct yasm_linemgr yasm_linemgr;
+/** Line number mapping repository (opaque type).  \see linemgr.h for related
+ * functions.
+ */
+typedef struct yasm_linemap yasm_linemap;
 
 /** Value/parameter pair (opaque type).
  * \see valparam.h for related functions.
@@ -131,19 +143,14 @@ typedef enum {
     YASM_SYM_EXTERN = 1 << 2   /**< If symbol is declared EXTERN */
 } yasm_sym_vis;
 
-/** Determine the distance between the starting offsets of two bytecodes in a
- * section.
- * \param sect         section containing the two bytecodes
- * \param precbc1      preceding bytecode to the first bytecode (NULL
- *                     indicates first bytecode in section)
- * \param precbc2      preceding bytecode to the second bytecode (NULL
- *                     indicates first bytecode in section)
+/** Determine the distance between the starting offsets of two bytecodes.
+ * \param precbc1      preceding bytecode to the first bytecode
+ * \param precbc2      preceding bytecode to the second bytecode
  * \return Distance in bytes between the two bytecodes (bc2-bc1), or NULL if
  *        the distance was indeterminate.
  */
 typedef /*@null@*/ yasm_intnum * (*yasm_calc_bc_dist_func)
-    (yasm_section *sect, /*@null@*/ yasm_bytecode *precbc1,
-     /*@null@*/ yasm_bytecode *precbc2);
+    (yasm_bytecode *precbc1, yasm_bytecode *precbc2);
 
 /** Convert yasm_expr to its byte representation.  Usually implemented by
  * object formats to keep track of relocations and verify legal expressions.
@@ -158,8 +165,6 @@ typedef /*@null@*/ yasm_intnum * (*yasm_calc_bc_dist_func)
  *                     shift (standard warnings include truncation to boundary)
  * \param offset       offset (in bytes) of the expr contents from the start
  *                     of the bytecode (sometimes needed for conditional jumps)
- * \param sect         current section (usually passed into higher-level
- *                     calling function)
  * \param bc           current bytecode (usually passed into higher-level
  *                     calling function)
  * \param rel          if nonzero, expr should be treated as PC/IP-relative
@@ -173,26 +178,12 @@ typedef /*@null@*/ yasm_intnum * (*yasm_calc_bc_dist_func)
  */
 typedef int (*yasm_output_expr_func)
     (yasm_expr **ep, /*@out@*/ unsigned char *buf, size_t destsize,
-     size_t valsize, int shift, unsigned long offset,
-     /*@observer@*/ const yasm_section *sect, yasm_bytecode *bc, int rel,
-     int warn, /*@null@*/ void *d) /*@uses *ep@*/;
+     size_t valsize, int shift, unsigned long offset, yasm_bytecode *bc,
+     int rel, int warn, /*@null@*/ void *d) /*@uses *ep@*/;
 
 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, const yasm_section *sect, void *d);
-
-/** Convert a yasm_objfmt-specific data bytecode into its byte representation.
- * Usually implemented by object formats to output their own generated data.
- * \param type         yasm_objfmt-specific type
- * \param data         data
- * \param bufp         (double) pointer to buffer for byte representation
- * \note bufp is guaranteed to have enough space to store the data into (as
- *      given by the original yasm_bc_new_objfmt_data() call).
- * \return Nonzero if an error occurred, 0 otherwise.
- */
-typedef int (*yasm_output_bc_objfmt_data_func)
-    (unsigned int type, /*@observer@*/ void *data, unsigned char **bufp)
-    /*@sets **bufp@*/;
+     size_t valsize, int rel, int warn, void *d);
 
 /** Sort an array using merge sort algorithm.
  * \internal
index a6a8e077ab3a0908fe39da9b2e430dae47ffea15..b1cebe8785b8ae967a8d7f2da810c3b878f1cfb5 100644 (file)
@@ -43,7 +43,7 @@
  * definitions match the module loader's function definitions.  The version
  * number must never be decreased.
  */
-#define YASM_DBGFMT_VERSION    1
+#define YASM_DBGFMT_VERSION    2
 
 /** YASM debug format interface. */
 struct yasm_dbgfmt {
@@ -69,8 +69,7 @@ struct yasm_dbgfmt {
      * \return Nonzero if object format does not provide needed support.
      */
     int (*initialize) (const char *in_filename, const char *obj_filename,
-                      yasm_linemgr *lm, yasm_objfmt *of, yasm_arch *a,
-                      const char *machine);
+                      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.
@@ -80,49 +79,17 @@ struct yasm_dbgfmt {
     /** DEBUG directive support.
      * \param name         directive name
      * \param valparams            value/parameters
-     * \param lindex       line index (as from yasm_linemgr)
+     * \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 (*directive) (const char *name, yasm_valparamhead *valparams,
-                     unsigned long lindex);
+                     unsigned long line);
 
     /** Generate debugging information bytecodes
-     * \param sections     list of sections
+     * \param object       object
      */
-    void (*generate) (yasm_sectionhead *sections);
-
-    /** Output debug format-specific bytecode data (YASM_BC_DBGFMT_DATA).
-     * Function may be unimplemented (NULL) if no YASM_BC_DBGFMT_DATA is ever
-     * allocated by the debug format.
-     * \param type             debug format-specific bytecode type
-     * \param data             debug format-specific data
-     * \param buf              provided buffer, as long as registered length
-     */
-    int (*bc_dbgfmt_data_output)(yasm_bytecode *bc, unsigned int type,
-                                const void *data, unsigned char **buf,
-                                const yasm_section *sect,
-                                yasm_output_reloc_func output_reloc,
-                                void *objfmt_d);
-
-    /** Delete debug format-specific bytecode data (YASM_BC_DBGFMT_DATA).
-     * Funtion may be unimplemented (NULL) if no YASM_BC_DBGFMT_DATA is ever
-     * allocated by the debug format.
-     * \param type     debug format-specific bytecode type
-     * \param data     debug-format specific data
-     */
-    void (*bc_dbgfmt_data_delete)(unsigned int type, /*@only@*/ void *data);
-
-    /** Print debug format-specific bytecode data (YASM_BC_DBGFMT_DATA).  For
-     * debugging purposes.  Function may be unimplemented (NULL) if no
-     * YASM_BC_DBGFMT_DATA is ever allocated by the debug format.
-     * \param f                        file
-     * \param indent_level     indentation level
-     * \param type             debug format-specific bytecode type
-     * \param data             debug format-specific data
-     */
-    void (*bc_dbgfmt_data_print)(FILE *f, int indent_level, unsigned int type,
-                                const void *data);
+    void (*generate) (yasm_object *object);
 };
 
 #endif
index 700a97e30f2ec0926c945f78676905059d9cbf5d..f62e182dbef2a3510e69c4ea39d2b2df8976854a 100644 (file)
@@ -179,12 +179,12 @@ def_fatal(const char *fmt, ...)
  * type is WE_PARSERERROR.
  */
 static errwarn_data *
-errwarn_data_new(unsigned long lindex, int replace_parser_error)
+errwarn_data_new(unsigned long line, int replace_parser_error)
 {
     errwarn_data *first, *next, *ins_we, *we;
     enum { INS_NONE, INS_HEAD, INS_AFTER } action = INS_NONE;
 
-    /* Find the entry with either line=lindex or the last one with line<lindex.
+    /* Find the entry with either line=line or the last one with line<line.
      * Start with the last entry added to speed the search.
      */
     ins_we = previous_we;
@@ -193,14 +193,14 @@ errwarn_data_new(unsigned long lindex, int replace_parser_error)
        action = INS_HEAD;
     while (action == INS_NONE) {
        next = SLIST_NEXT(ins_we, link);
-       if (lindex < ins_we->line) {
+       if (line < ins_we->line) {
            if (ins_we == first)
                action = INS_HEAD;
            else
                ins_we = first;
        } else if (!next)
            action = INS_AFTER;
-       else if (lindex >= ins_we->line && lindex < next->line)
+       else if (line >= ins_we->line && line < next->line)
            action = INS_AFTER;
        else
            ins_we = next;
@@ -214,7 +214,7 @@ errwarn_data_new(unsigned long lindex, int replace_parser_error)
        we = yasm_xmalloc(sizeof(errwarn_data));
 
        we->type = WE_UNKNOWN;
-       we->line = lindex;
+       we->line = line;
 
        if (action == INS_HEAD)
            SLIST_INSERT_HEAD(&errwarns, we, link);
@@ -231,13 +231,13 @@ errwarn_data_new(unsigned long lindex, int replace_parser_error)
     return we;
 }
 
-/* Register an error at line lindex.  Does not print the error, only stores it
+/* Register an error at line line.  Does not print the error, only stores it
  * for output_all() to print.
  */
 void
-yasm__error_va(unsigned long lindex, const char *fmt, va_list va)
+yasm__error_va(unsigned long line, const char *fmt, va_list va)
 {
-    errwarn_data *we = errwarn_data_new(lindex, 1);
+    errwarn_data *we = errwarn_data_new(line, 1);
 
     we->type = WE_ERROR;
 
@@ -250,11 +250,11 @@ yasm__error_va(unsigned long lindex, const char *fmt, va_list va)
     error_count++;
 }
 
-/* Register an warning at line lindex.  Does not print the warning, only stores
+/* Register an warning at line line.  Does not print the warning, only stores
  * it for output_all() to print.
  */
 void
-yasm__warning_va(yasm_warn_class num, unsigned long lindex, const char *fmt,
+yasm__warning_va(yasm_warn_class num, unsigned long line, const char *fmt,
                 va_list va)
 {
     errwarn_data *we;
@@ -262,7 +262,7 @@ yasm__warning_va(yasm_warn_class num, unsigned long lindex, const char *fmt,
     if (!(warn_class_enabled & (1UL<<num)))
        return;     /* warning is part of disabled class */
 
-    we = errwarn_data_new(lindex, 0);
+    we = errwarn_data_new(line, 0);
 
     we->type = WE_WARNING;
 
@@ -275,27 +275,27 @@ yasm__warning_va(yasm_warn_class num, unsigned long lindex, const char *fmt,
     warning_count++;
 }
 
-/* Register an error at line lindex.  Does not print the error, only stores it
+/* Register an error at line line.  Does not print the error, only stores it
  * for output_all() to print.
  */
 void
-yasm__error(unsigned long lindex, const char *fmt, ...)
+yasm__error(unsigned long line, const char *fmt, ...)
 {
     va_list va;
     va_start(va, fmt);
-    yasm__error_va(lindex, fmt, va);
+    yasm__error_va(line, fmt, va);
     va_end(va);
 }
 
-/* Register an warning at line lindex.  Does not print the warning, only stores
+/* Register an warning at line line.  Does not print the warning, only stores
  * it for output_all() to print.
  */
 void
-yasm__warning(yasm_warn_class num, unsigned long lindex, const char *fmt, ...)
+yasm__warning(yasm_warn_class num, unsigned long line, const char *fmt, ...)
 {
     va_list va;
     va_start(va, fmt);
-    yasm__warning_va(num, lindex, fmt, va);
+    yasm__warning_va(num, line, fmt, va);
     va_end(va);
 }
 
@@ -303,9 +303,9 @@ yasm__warning(yasm_warn_class num, unsigned long lindex, const char *fmt, ...)
  * system.
  */
 void
-yasm__parser_error(unsigned long lindex, const char *s)
+yasm__parser_error(unsigned long line, const char *s)
 {
-    yasm__error(lindex, N_("parser error: %s"), s);
+    yasm__error(line, N_("parser error: %s"), s);
     previous_we->type = WE_PARSERERROR;
 }
 
@@ -337,7 +337,7 @@ yasm_get_num_errors(int warning_as_error)
 }
 
 void
-yasm_errwarn_output_all(yasm_linemgr *lm, int warning_as_error,
+yasm_errwarn_output_all(yasm_linemap *lm, int warning_as_error,
      yasm_print_error_func print_error, yasm_print_warning_func print_warning)
 {
     errwarn_data *we;
@@ -354,7 +354,7 @@ yasm_errwarn_output_all(yasm_linemgr *lm, int warning_as_error,
     /* Output error/warnings. */
     SLIST_FOREACH(we, &errwarns, link) {
        /* Output error/warning */
-       lm->lookup(we->line, &filename, &line);
+       yasm_linemap_lookup(lm, we->line, &filename, &line);
        if (we->type == WE_ERROR)
            print_error(filename, line, we->msg);
        else
index 44560c697b3ed46aa31b3c5525cbcb0f698658b5..620fc81addc242e38d5d2704cbd2daa051fa4467 100644 (file)
@@ -77,50 +77,50 @@ extern /*@exits@*/ void (*yasm_fatal) (const char *message, ...);
 
 /** Log an error.  va_list version of yasm__error().
  * \internal
- * \param lindex    line index
+ * \param line      virtual line
  * \param message   printf-like-format message
  * \param va       argument list for message
  */
-void yasm__error_va(unsigned long lindex, const char *message, va_list va);
+void yasm__error_va(unsigned long line, const char *message, va_list va);
 
 /** Log a warning.  va_list version of yasm__warning().
  * \internal
  * \param wclass    warning class
- * \param lindex    line index
+ * \param line      virtual line
  * \param message   printf-like-format message
  * \param va       argument list for message
  */
-void yasm__warning_va(yasm_warn_class wclass, unsigned long lindex,
+void yasm__warning_va(yasm_warn_class wclass, unsigned long line,
                      const char *message, va_list va);
 
 /** Log an error.  Does not print it out immediately; yasm_errwarn_output_all()
  * outputs errors and warnings.
  * \internal
- * \param lindex    line index
+ * \param line      virtual line
  * \param message   printf-like-format message
  * \param ...      argument list for message
  */
-void yasm__error(unsigned long lindex, const char *message, ...)
+void yasm__error(unsigned long line, const char *message, ...)
     /*@printflike@*/;
 
 /** Log a warning.  Does not print it out immediately;
  * yasm_errwarn_output_all() outputs errors and warnings.
  * \internal
  * \param wclass    warning class
- * \param lindex    line index
+ * \param line      virtual line
  * \param message   printf-like-format message
  * \param ...      argument list for message
  */
-void yasm__warning(yasm_warn_class wclass, unsigned long lindex,
+void yasm__warning(yasm_warn_class wclass, unsigned long line,
                   const char *message, ...) /*@printflike@*/;
 
 /** Log a parser error.  Parser errors can be overwritten by non-parser errors
  * on the same line.
  * \internal
- * \param lindex    line index
+ * \param line      virtual line
  * \param message   parser error message
  */
-void yasm__parser_error(unsigned long lindex, const char *message);
+void yasm__parser_error(unsigned long line, const char *message);
 
 /** Enable a class of warnings.
  * \param wclass    warning class
@@ -158,13 +158,13 @@ typedef void (*yasm_print_warning_func)
     (const char *fn, unsigned long line, const char *msg);
 
 /** Outputs all errors and warnings.
- * \param lm   line manager (to convert line indexes into filename/line pairs)
+ * \param lm   line map (to convert virtual lines into filename/line pairs)
  * \param warning_as_error  if nonzero, treat warnings as errors
  * \param print_error      function called to print out errors
  * \param print_warning            function called to print out warnings
  */
 void yasm_errwarn_output_all
-    (yasm_linemgr *lm, int warning_as_error, yasm_print_error_func print_error,
+    (yasm_linemap *lm, int warning_as_error, yasm_print_error_func print_error,
      yasm_print_warning_func print_warning);
 
 /** Convert a possibly unprintable character into a printable string.
index e46f39c5c6a46490c410a36202b5670f7a387753..b0d0bb8a3c0cf9b64aa43ff811aa92a60b15ced5 100644 (file)
@@ -50,21 +50,12 @@ static int expr_traverse_nodes_post(/*@null@*/ yasm_expr *e,
                                    int (*func) (/*@null@*/ yasm_expr *e,
                                                 /*@null@*/ void *d));
 
-static /*@dependent@*/ yasm_arch *cur_arch;
-
-
-void
-yasm_expr_initialize(yasm_arch *a)
-{
-    cur_arch = a;
-}
-
 /* allocate a new expression node, with children as defined.
  * If it's a unary operator, put the element in left and set right=NULL. */
 /*@-compmempass@*/
 yasm_expr *
-yasm_expr_new(yasm_expr_op op, yasm_expr__item *left, yasm_expr__item *right,
-             unsigned long lindex)
+yasm_expr_create(yasm_expr_op op, yasm_expr__item *left,
+                yasm_expr__item *right, unsigned long line)
 {
     yasm_expr *ptr, *sube;
     ptr = yasm_xmalloc(sizeof(yasm_expr));
@@ -111,7 +102,7 @@ yasm_expr_new(yasm_expr_op op, yasm_expr__item *left, yasm_expr__item *right,
        }
     }
 
-    ptr->line = lindex;
+    ptr->line = line;
 
     return ptr;
 }
@@ -182,15 +173,16 @@ expr_xform_bc_dist(/*@returned@*/ /*@only@*/ yasm_expr *e,
         * absolute start expr + intnum(dist).
         */
        if (e->terms[i].type == YASM_EXPR_SYM &&
-           yasm_symrec_get_label(e->terms[i].data.sym, &sect, &precbc) &&
+           yasm_symrec_get_label(e->terms[i].data.sym, &precbc) &&
+           (sect = yasm_bc_get_section(precbc)) &&
            yasm_section_is_absolute(sect) &&
-           (dist = calc_bc_dist(sect, NULL, precbc))) {
+           (dist = calc_bc_dist(yasm_section_bcs_first(sect), precbc))) {
            const yasm_expr *start = yasm_section_get_start(sect);
            e->terms[i].type = YASM_EXPR_EXPR;
            e->terms[i].data.expn =
-               yasm_expr_new(YASM_EXPR_ADD,
-                             yasm_expr_expr(yasm_expr_copy(start)),
-                             yasm_expr_int(dist), e->line);
+               yasm_expr_create(YASM_EXPR_ADD,
+                                yasm_expr_expr(yasm_expr_copy(start)),
+                                yasm_expr_int(dist), e->line);
        }
     }
 
@@ -229,19 +221,21 @@ expr_xform_bc_dist(/*@returned@*/ /*@only@*/ yasm_expr *e,
        if (!yasm_intnum_is_neg1(intn))
            continue;
 
-       yasm_symrec_get_label(sym, &sect2, &precbc);
+       yasm_symrec_get_label(sym, &precbc);
+       sect2 = yasm_bc_get_section(precbc);
 
        /* Now look for a symrec term in the same segment */
        for (j=0; j<e->numterms; j++) {
            if (e->terms[j].type == YASM_EXPR_SYM &&
-               yasm_symrec_get_label(e->terms[j].data.sym, &sect, &precbc2) &&
+               yasm_symrec_get_label(e->terms[j].data.sym, &precbc2) &&
+               (sect = yasm_bc_get_section(precbc2)) &&
                sect == sect2 &&
-               (dist = calc_bc_dist(sect, precbc, precbc2))) {
+               (dist = calc_bc_dist(precbc, precbc2))) {
                /* Change the symrec term to an integer */
                e->terms[j].type = YASM_EXPR_INT;
                e->terms[j].data.intn = dist;
                /* Delete the matching (-1*symrec) term */
-               yasm_expr_delete(sube);
+               yasm_expr_destroy(sube);
                e->terms[i].type = YASM_EXPR_NONE;
                break;  /* stop looking for matching symrec term */
            }
@@ -276,7 +270,7 @@ expr_xform_neg_item(yasm_expr *e, yasm_expr__item *ei)
     sube->line = e->line;
     sube->numterms = 2;
     sube->terms[0].type = YASM_EXPR_INT;
-    sube->terms[0].data.intn = yasm_intnum_new_int(-1);
+    sube->terms[0].data.intn = yasm_intnum_create_int(-1);
     sube->terms[1] = *ei;      /* structure copy */
 
     /* Replace original ExprItem with subexp */
@@ -334,7 +328,7 @@ expr_xform_neg_helper(/*@returned@*/ /*@only@*/ yasm_expr *e)
                e->op = YASM_EXPR_MUL;
                e->numterms = 2;
                e->terms[1].type = YASM_EXPR_INT;
-               e->terms[1].data.intn = yasm_intnum_new_int(-1);
+               e->terms[1].data.intn = yasm_intnum_create_int(-1);
            }
            break;
        default:
@@ -346,7 +340,7 @@ expr_xform_neg_helper(/*@returned@*/ /*@only@*/ yasm_expr *e)
            ne->line = e->line;
            ne->numterms = 2;
            ne->terms[0].type = YASM_EXPR_INT;
-           ne->terms[0].data.intn = yasm_intnum_new_int(-1);
+           ne->terms[0].data.intn = yasm_intnum_create_int(-1);
            ne->terms[1].type = YASM_EXPR_EXPR;
            ne->terms[1].data.expn = e;
            return ne;
@@ -401,7 +395,7 @@ expr_is_constant(yasm_expr_op op, yasm_intnum *intn)
 
 /* Look for simple "left" identities like 0+x, 1*x, etc. */
 static int
-expr_can_delete_int_left(yasm_expr_op op, yasm_intnum *intn)
+expr_can_destroy_int_left(yasm_expr_op op, yasm_intnum *intn)
 {
     return ((yasm_intnum_is_pos1(intn) && op == YASM_EXPR_MUL) ||
            (yasm_intnum_is_zero(intn) && op == YASM_EXPR_ADD) ||
@@ -411,7 +405,7 @@ expr_can_delete_int_left(yasm_expr_op op, yasm_intnum *intn)
 
 /* Look for simple "right" identities like x+|-0, x*&/1 */
 static int
-expr_can_delete_int_right(yasm_expr_op op, yasm_intnum *intn)
+expr_can_destroy_int_right(yasm_expr_op op, yasm_intnum *intn)
 {
     return ((yasm_intnum_is_pos1(intn) && op == YASM_EXPR_MUL) ||
            (yasm_intnum_is_pos1(intn) && op == YASM_EXPR_DIV) ||
@@ -439,11 +433,11 @@ expr_simplify_identity(yasm_expr *e, int numterms, int int_term)
      * Don't delete if the intnum is the only thing in the expn.
      */
     if ((int_term == 0 && numterms > 1 &&
-        expr_can_delete_int_left(e->op, e->terms[0].data.intn)) ||
+        expr_can_destroy_int_left(e->op, e->terms[0].data.intn)) ||
        (int_term > 0 &&
-        expr_can_delete_int_right(e->op, e->terms[int_term].data.intn))) {
+        expr_can_destroy_int_right(e->op, e->terms[int_term].data.intn))) {
        /* Delete the intnum */
-       yasm_intnum_delete(e->terms[int_term].data.intn);
+       yasm_intnum_destroy(e->terms[int_term].data.intn);
 
        /* Slide everything to its right over by 1 */
        if (int_term != numterms-1) /* if it wasn't last.. */
@@ -464,13 +458,13 @@ expr_simplify_identity(yasm_expr *e, int numterms, int int_term)
            if (i != int_term)
                switch (e->terms[i].type) {
                    case YASM_EXPR_INT:
-                       yasm_intnum_delete(e->terms[i].data.intn);
+                       yasm_intnum_destroy(e->terms[i].data.intn);
                        break;
                    case YASM_EXPR_FLOAT:
-                       yasm_floatnum_delete(e->terms[i].data.flt);
+                       yasm_floatnum_destroy(e->terms[i].data.flt);
                        break;
                    case YASM_EXPR_EXPR:
-                       yasm_expr_delete(e->terms[i].data.expn);
+                       yasm_expr_destroy(e->terms[i].data.expn);
                        break;
                    default:
                        break;
@@ -575,7 +569,7 @@ expr_level_op(/*@returned@*/ /*@only@*/ yasm_expr *e, int fold_const,
                fold_numterms--;
                level_numterms--;
                /* make sure to delete folded intnum */
-               yasm_intnum_delete(e->terms[i].data.intn);
+               yasm_intnum_destroy(e->terms[i].data.intn);
            } else if (o != i) {
                /* copy term if it changed places */
                e->terms[o++] = e->terms[i];
@@ -644,7 +638,7 @@ expr_level_op(/*@returned@*/ /*@only@*/ yasm_expr *e, int fold_const,
                                         e->op, sube->terms[j].data.intn,
                                         e->line);
                        /* make sure to delete folded intnum */
-                       yasm_intnum_delete(sube->terms[j].data.intn);
+                       yasm_intnum_destroy(sube->terms[j].data.intn);
                    }
                } else {
                    if (o == first_int_term)
@@ -859,16 +853,16 @@ yasm_expr_copy(const yasm_expr *e)
 }
 
 static int
-expr_delete_each(/*@only@*/ yasm_expr *e, /*@unused@*/ void *d)
+expr_destroy_each(/*@only@*/ yasm_expr *e, /*@unused@*/ void *d)
 {
     int i;
     for (i=0; i<e->numterms; i++) {
        switch (e->terms[i].type) {
            case YASM_EXPR_INT:
-               yasm_intnum_delete(e->terms[i].data.intn);
+               yasm_intnum_destroy(e->terms[i].data.intn);
                break;
            case YASM_EXPR_FLOAT:
-               yasm_floatnum_delete(e->terms[i].data.flt);
+               yasm_floatnum_destroy(e->terms[i].data.flt);
                break;
            default:
                break;  /* none of the other types needs to be deleted */
@@ -880,9 +874,9 @@ expr_delete_each(/*@only@*/ yasm_expr *e, /*@unused@*/ void *d)
 
 /*@-mustfree@*/
 void
-yasm_expr_delete(yasm_expr *e)
+yasm_expr_destroy(yasm_expr *e)
 {
-    expr_traverse_nodes_post(e, NULL, expr_delete_each);
+    expr_traverse_nodes_post(e, NULL, expr_destroy_each);
 }
 /*@=mustfree@*/
 
@@ -1013,16 +1007,16 @@ yasm_expr_extract_symrec(yasm_expr **ep, yasm_calc_bc_dist_func calc_bc_dist)
            break;
     }
     if (sym) {
-       /*@dependent@*/ yasm_section *sect;
        /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc;
        /*@null@*/ yasm_intnum *intn;
 
-       if (yasm_symrec_get_label(sym, &sect, &precbc)) {
-           intn = calc_bc_dist(sect, NULL, precbc);
+       if (yasm_symrec_get_label(sym, &precbc)) {
+           intn = calc_bc_dist(yasm_section_bcs_first(
+                                   yasm_bc_get_section(precbc)), precbc);
            if (!intn)
                return NULL;
        } else
-           intn = yasm_intnum_new_uint(0);
+           intn = yasm_intnum_create_uint(0);
        (*ep)->terms[symterm].type = YASM_EXPR_INT;
        (*ep)->terms[symterm].data.intn = intn;
     }
@@ -1142,7 +1136,7 @@ yasm_expr_get_reg(yasm_expr **ep, int simplify)
 /*@=unqualifiedtrans =nullderef -nullstate -onlytrans@*/
 
 void
-yasm_expr_print(FILE *f, const yasm_expr *e)
+yasm_expr_print(const yasm_expr *e, FILE *f)
 {
     char opstr[6];
     int i;
@@ -1248,17 +1242,18 @@ yasm_expr_print(FILE *f, const yasm_expr *e)
                break;
            case YASM_EXPR_EXPR:
                fprintf(f, "(");
-               yasm_expr_print(f, e->terms[i].data.expn);
+               yasm_expr_print(e->terms[i].data.expn, f);
                fprintf(f, ")");
                break;
            case YASM_EXPR_INT:
-               yasm_intnum_print(f, e->terms[i].data.intn);
+               yasm_intnum_print(e->terms[i].data.intn, f);
                break;
            case YASM_EXPR_FLOAT:
-               yasm_floatnum_print(f, e->terms[i].data.flt);
+               yasm_floatnum_print(e->terms[i].data.flt, f);
                break;
            case YASM_EXPR_REG:
-               cur_arch->reg_print(f, e->terms[i].data.reg);
+               /* FIXME */
+               /*arch->module->reg_print(arch, e->terms[i].data.reg, f);*/
                break;
            case YASM_EXPR_NONE:
                break;
index ed38729b0fbaf405218f1ceb3695aadce412b16a..26d60dfb599c7c4ca1ee01df33395a29bbb6e0e2 100644 (file)
 /** Expression item (opaque type).  \internal */
 typedef struct yasm_expr__item yasm_expr__item;
 
-/** Initialize expression internal data structures.
- * \param a architecture in use
- */
-void yasm_expr_initialize(yasm_arch *a);
-
 /** Create a new expression e=a op b.
  * \param op       operation
  * \param a        expression item a
  * \param b        expression item b (optional depending on op)
- * \param lindex    line index (where expression defined)
+ * \param line     virtual line (where expression defined)
  * \return Newly allocated expression.
  */
-/*@only@*/ yasm_expr *yasm_expr_new
+/*@only@*/ yasm_expr *yasm_expr_create
     (yasm_expr_op op, /*@only@*/ yasm_expr__item *a,
-     /*@only@*/ /*@null@*/ yasm_expr__item *b, unsigned long lindex);
+     /*@only@*/ /*@null@*/ yasm_expr__item *b, unsigned long line);
 
 /** Create a new symbol expression item.
  * \param sym      symbol
@@ -90,8 +85,8 @@ void yasm_expr_initialize(yasm_arch *a);
  * \param i    line index
  * \return Newly allocated expression.
  */
-#define yasm_expr_new_tree(l,o,r,i) \
-    yasm_expr_new ((o), yasm_expr_expr(l), yasm_expr_expr(r), i)
+#define yasm_expr_create_tree(l,o,r,i) \
+    yasm_expr_create ((o), yasm_expr_expr(l), yasm_expr_expr(r), i)
 
 /** Create a new expression branch e=op r.
  * \param o    operation
@@ -99,16 +94,16 @@ void yasm_expr_initialize(yasm_arch *a);
  * \param i    line index
  * \return Newly allocated expression.
  */
-#define yasm_expr_new_branch(o,r,i) \
-    yasm_expr_new ((o), yasm_expr_expr(r), (yasm_expr__item *)NULL, i)
+#define yasm_expr_create_branch(o,r,i) \
+    yasm_expr_create ((o), yasm_expr_expr(r), (yasm_expr__item *)NULL, i)
 
 /** Create a new expression identity e=r.
  * \param r    expression for identity within new expression
  * \param i    line index
  * \return Newly allocated expression.
  */
-#define yasm_expr_new_ident(r,i) \
-    yasm_expr_new (YASM_EXPR_IDENT, (r), (yasm_expr__item *)NULL, i)
+#define yasm_expr_create_ident(r,i) \
+    yasm_expr_create (YASM_EXPR_IDENT, (r), (yasm_expr__item *)NULL, i)
 
 /** Duplicate an expression.
  * \param e    expression
@@ -119,7 +114,7 @@ yasm_expr *yasm_expr_copy(const yasm_expr *e);
 /** Destroy (free allocated memory for) an expression.
  * \param e    expression
  */
-void yasm_expr_delete(/*@only@*/ /*@null@*/ yasm_expr *e);
+void yasm_expr_destroy(/*@only@*/ /*@null@*/ yasm_expr *e);
 
 /** Determine if an expression is a specified operation (at the top level).
  * \param e            expression
@@ -241,9 +236,9 @@ SLIST_HEAD(yasm__exprhead, yasm__exprentry);
     (yasm_expr **ep, int simplify);
 
 /** Print an expression.  For debugging purposes.
- * \param f    file
  * \param e    expression
+ * \param f    file
  */
-void yasm_expr_print(FILE *f, /*@null@*/ const yasm_expr *e);
+void yasm_expr_print(/*@null@*/ const yasm_expr *e, FILE *f);
 
 #endif
index e9addc28e74914e9e27429bd123bbdf65427e0a8..4c117e1b1891939c0c1fc8c2992603b8991ce8b4 100644 (file)
@@ -303,7 +303,7 @@ floatnum_mul(yasm_floatnum *acc, const yasm_floatnum *op)
 }
 
 yasm_floatnum *
-yasm_floatnum_new(const char *str)
+yasm_floatnum_create(const char *str)
 {
     yasm_floatnum *flt;
     int dec_exponent, dec_exp_add;     /* decimal (powers of 10) exponent */
@@ -503,7 +503,7 @@ yasm_floatnum_copy(const yasm_floatnum *flt)
 }
 
 void
-yasm_floatnum_delete(yasm_floatnum *flt)
+yasm_floatnum_destroy(yasm_floatnum *flt)
 {
     BitVector_Destroy(flt->mantissa);
     yasm_xfree(flt);
@@ -511,10 +511,10 @@ yasm_floatnum_delete(yasm_floatnum *flt)
 
 void
 yasm_floatnum_calc(yasm_floatnum *acc, yasm_expr_op op,
-                  /*@unused@*/ yasm_floatnum *operand, unsigned long lindex)
+                  /*@unused@*/ yasm_floatnum *operand, unsigned long line)
 {
     if (op != YASM_EXPR_NEG)
-       yasm__error(lindex,
+       yasm__error(line,
                    N_("Unsupported floating-point arithmetic operation"));
     else
        acc->sign ^= 1;
@@ -660,7 +660,7 @@ floatnum_get_common(const yasm_floatnum *flt, /*@out@*/ unsigned char *ptr,
 int
 yasm_floatnum_get_sized(const yasm_floatnum *flt, unsigned char *ptr,
                        size_t destsize, size_t valsize, size_t shift,
-                       int bigendian, int warn, unsigned long lindex)
+                       int bigendian, int warn, unsigned long line)
 {
     int retval;
     if (destsize*8 != valsize || shift>0 || bigendian) {
@@ -684,10 +684,10 @@ yasm_floatnum_get_sized(const yasm_floatnum *flt, unsigned char *ptr,
     }
     if (warn) {
        if (retval < 0)
-           yasm__warning(YASM_WARN_GENERAL, lindex,
+           yasm__warning(YASM_WARN_GENERAL, line,
                          N_("underflow in floating point expression"));
        else if (retval > 0)
-           yasm__warning(YASM_WARN_GENERAL, lindex,
+           yasm__warning(YASM_WARN_GENERAL, line,
                          N_("overflow in floating point expression"));
     }
     return retval;
@@ -708,7 +708,7 @@ yasm_floatnum_check_size(/*@unused@*/ const yasm_floatnum *flt, size_t size)
 }
 
 void
-yasm_floatnum_print(FILE *f, const yasm_floatnum *flt)
+yasm_floatnum_print(const yasm_floatnum *flt, FILE *f)
 {
     unsigned char out[10];
     unsigned char *str;
index 98b5cbaae834a3c97028c6954d3ab2674d23e384..b850be2e7a1f600d7135326c66bcc87b144a03ba 100644 (file)
@@ -47,7 +47,7 @@ void yasm_floatnum_cleanup(void);
  * \param str  floating point decimal string
  * \return Newly allocated floatnum.
  */
-/*@only@*/ yasm_floatnum *yasm_floatnum_new(const char *str);
+/*@only@*/ yasm_floatnum *yasm_floatnum_create(const char *str);
 
 /** Duplicate a floatnum.
  * \param flt  floatnum
@@ -58,7 +58,7 @@ void yasm_floatnum_cleanup(void);
 /** Destroy (free allocated memory for) a floatnum.
  * \param flt  floatnum
  */
-void yasm_floatnum_delete(/*@only@*/ yasm_floatnum *flt);
+void yasm_floatnum_destroy(/*@only@*/ yasm_floatnum *flt);
 
 /** Floating point calculation function: acc = acc op operand.
  * \note Not all operations in yasm_expr_op may be supported; unsupported
@@ -66,10 +66,10 @@ void yasm_floatnum_delete(/*@only@*/ yasm_floatnum *flt);
  * \param acc      floatnum accumulator
  * \param op       operation
  * \param operand   floatnum operand
- * \param lindex    line index (of expression)
+ * \param line      virtual line (of expression)
  */
 void yasm_floatnum_calc(yasm_floatnum *acc, yasm_expr_op op,
-                       yasm_floatnum *operand, unsigned long lindex);
+                       yasm_floatnum *operand, unsigned long line);
 
 /** Convert a floatnum to single-precision and return as 32-bit value.
  * The 32-bit value is a "standard" C value (eg, of unknown endian).
@@ -95,13 +95,13 @@ int yasm_floatnum_get_int(const yasm_floatnum *flt,
  * \param shift            left shift (in bits)
  * \param bigendian endianness (nonzero=big, zero=little)
  * \param warn     enables standard overflow/underflow warnings
- * \param lindex    line index; may be 0 if warn is 0.
+ * \param line      virtual line; may be 0 if warn is 0.
  * \return Nonzero if flt can't fit into the specified precision: -1 if
  *         underflow occurred, 1 if overflow occurred.
  */
 int yasm_floatnum_get_sized(const yasm_floatnum *flt, unsigned char *ptr,
                            size_t destsize, size_t valsize, size_t shift,
-                           int bigendian, int warn, unsigned long lindex);
+                           int bigendian, int warn, unsigned long line);
 
 /** Basic check to see if size is valid for flt conversion (using
  * yasm_floatnum_get_sized()).  Doesn't actually check for underflow/overflow
@@ -117,6 +117,6 @@ int yasm_floatnum_check_size(const yasm_floatnum *flt, size_t size);
  * \param f        file
  * \param flt      floatnum
  */
-void yasm_floatnum_print(FILE *f, const yasm_floatnum *flt);
+void yasm_floatnum_print(const yasm_floatnum *flt, FILE *f);
 
 #endif
index c13a37f5c8e59ad96be332fecdc2d8c5432ac3a7..4d610683d700e85ced7c54b6f2734ee3fa7da100 100644 (file)
@@ -86,8 +86,8 @@ ReHashKey(const char *key, int Level)
 }
 
 HAMT *
-HAMT_new(/*@exits@*/ void (*error_func) (const char *file, unsigned int line,
-                                        const char *message))
+HAMT_create(/*@exits@*/ void (*error_func)
+    (const char *file, unsigned int line, const char *message))
 {
     /*@out@*/ HAMT *hamt = yasm_xmalloc(sizeof(HAMT));
     int i;
@@ -122,7 +122,7 @@ HAMT_delete_trie(HAMTNode *node)
 }
 
 void
-HAMT_delete(HAMT *hamt, void (*deletefunc) (/*@only@*/ void *data))
+HAMT_destroy(HAMT *hamt, void (*deletefunc) (/*@only@*/ void *data))
 {
     int i;
 
index c42cf80fb1a345caaedd25a37c2a7ab835ebe10b..a93319037ee09e635dfddbaed7341117594912b4 100644 (file)
@@ -32,15 +32,14 @@ typedef struct HAMT HAMT;
 /* Creates new, empty, HAMT.  error_func() is called when an internal error is
  * encountered--it should NOT return to the calling function.
  */
-HAMT *HAMT_new(/*@exits@*/ void (*error_func) (const char *file,
-                                              unsigned int line,
-                                              const char *message));
+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.
  */
-void HAMT_delete(/*@only@*/ HAMT *hamt,
-                void (*deletefunc) (/*@only@*/ void *data));
+void HAMT_destroy(/*@only@*/ HAMT *hamt,
+                 void (*deletefunc) (/*@only@*/ void *data));
 
 /* Inserts key into HAMT, associating it with data. 
  * If the key is not present in the HAMT, inserts it, sets *replace to 1, and
index d96bee4fab9466f537f0fb4ec017c368fb2410a5..b0b8217790b7f9b089292bfc7b0ac46420a44f06 100644 (file)
@@ -57,6 +57,8 @@ static /*@only@*/ wordptr conv_bv;
 /* static bitvects used for computation */
 static /*@only@*/ wordptr result, spare, op1static, op2static;
 
+static /*@only@*/ BitVector_from_Dec_static_data *from_dec_data;
+
 
 void
 yasm_intnum_initialize(void)
@@ -66,13 +68,13 @@ yasm_intnum_initialize(void)
     spare = BitVector_Create(BITVECT_NATIVE_SIZE, FALSE);
     op1static = BitVector_Create(BITVECT_NATIVE_SIZE, FALSE);
     op2static = BitVector_Create(BITVECT_NATIVE_SIZE, FALSE);
-    BitVector_from_Dec_static_Boot(BITVECT_NATIVE_SIZE);
+    from_dec_data = BitVector_from_Dec_static_Boot(BITVECT_NATIVE_SIZE);
 }
 
 void
 yasm_intnum_cleanup(void)
 {
-    BitVector_from_Dec_static_Shutdown();
+    BitVector_from_Dec_static_Shutdown(from_dec_data);
     BitVector_Destroy(op2static);
     BitVector_Destroy(op1static);
     BitVector_Destroy(spare);
@@ -81,15 +83,15 @@ yasm_intnum_cleanup(void)
 }
 
 yasm_intnum *
-yasm_intnum_new_dec(char *str, unsigned long lindex)
+yasm_intnum_create_dec(char *str, unsigned long line)
 {
     yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
 
     intn->origsize = 0;            /* no reliable way to figure this out */
 
-    if (BitVector_from_Dec_static(conv_bv,
+    if (BitVector_from_Dec_static(from_dec_data, conv_bv,
                                  (unsigned char *)str) == ErrCode_Ovfl)
-       yasm__warning(YASM_WARN_GENERAL, lindex,
+       yasm__warning(YASM_WARN_GENERAL, line,
                      N_("Numeric constant too large for internal format"));
     if (Set_Max(conv_bv) < 32) {
        intn->type = INTNUM_UL;
@@ -103,14 +105,14 @@ yasm_intnum_new_dec(char *str, unsigned long lindex)
 }
 
 yasm_intnum *
-yasm_intnum_new_bin(char *str, unsigned long lindex)
+yasm_intnum_create_bin(char *str, unsigned long line)
 {
     yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
 
     intn->origsize = (unsigned char)strlen(str);
 
     if(intn->origsize > BITVECT_NATIVE_SIZE)
-       yasm__warning(YASM_WARN_GENERAL, lindex,
+       yasm__warning(YASM_WARN_GENERAL, line,
                      N_("Numeric constant too large for internal format"));
 
     BitVector_from_Bin(conv_bv, (unsigned char *)str);
@@ -126,14 +128,14 @@ yasm_intnum_new_bin(char *str, unsigned long lindex)
 }
 
 yasm_intnum *
-yasm_intnum_new_oct(char *str, unsigned long lindex)
+yasm_intnum_create_oct(char *str, unsigned long line)
 {
     yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
 
     intn->origsize = strlen(str)*3;
 
     if(intn->origsize > BITVECT_NATIVE_SIZE)
-       yasm__warning(YASM_WARN_GENERAL, lindex,
+       yasm__warning(YASM_WARN_GENERAL, line,
                      N_("Numeric constant too large for internal format"));
 
     BitVector_from_Oct(conv_bv, (unsigned char *)str);
@@ -149,14 +151,14 @@ yasm_intnum_new_oct(char *str, unsigned long lindex)
 }
 
 yasm_intnum *
-yasm_intnum_new_hex(char *str, unsigned long lindex)
+yasm_intnum_create_hex(char *str, unsigned long line)
 {
     yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
 
     intn->origsize = strlen(str)*4;
 
     if(intn->origsize > BITVECT_NATIVE_SIZE)
-       yasm__warning(YASM_WARN_GENERAL, lindex,
+       yasm__warning(YASM_WARN_GENERAL, line,
                      N_("Numeric constant too large for internal format"));
 
     BitVector_from_Hex(conv_bv, (unsigned char *)str);
@@ -173,7 +175,7 @@ yasm_intnum_new_hex(char *str, unsigned long lindex)
 
 /*@-usedef -compdef -uniondef@*/
 yasm_intnum *
-yasm_intnum_new_charconst_nasm(const char *str, unsigned long lindex)
+yasm_intnum_create_charconst_nasm(const char *str, unsigned long line)
 {
     yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
     size_t len = strlen(str);
@@ -181,7 +183,7 @@ yasm_intnum_new_charconst_nasm(const char *str, unsigned long lindex)
     intn->origsize = len*8;
 
     if(intn->origsize > BITVECT_NATIVE_SIZE)
-       yasm__warning(YASM_WARN_GENERAL, lindex,
+       yasm__warning(YASM_WARN_GENERAL, line,
                      N_("Character constant too large for internal format"));
 
     if (len > 4) {
@@ -224,7 +226,7 @@ yasm_intnum_new_charconst_nasm(const char *str, unsigned long lindex)
 /*@=usedef =compdef =uniondef@*/
 
 yasm_intnum *
-yasm_intnum_new_uint(unsigned long i)
+yasm_intnum_create_uint(unsigned long i)
 {
     yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
 
@@ -236,13 +238,13 @@ yasm_intnum_new_uint(unsigned long i)
 }
 
 yasm_intnum *
-yasm_intnum_new_int(long i)
+yasm_intnum_create_int(long i)
 {
     yasm_intnum *intn;
 
     /* positive numbers can go through the uint() function */
     if (i >= 0)
-       return yasm_intnum_new_uint((unsigned long)i);
+       return yasm_intnum_create_uint((unsigned long)i);
 
     BitVector_Empty(conv_bv);
     BitVector_Chunk_Store(conv_bv, 32, 0, (unsigned long)(-i));
@@ -276,7 +278,7 @@ yasm_intnum_copy(const yasm_intnum *intn)
 }
 
 void
-yasm_intnum_delete(yasm_intnum *intn)
+yasm_intnum_destroy(yasm_intnum *intn)
 {
     if (intn->type == INTNUM_BV)
        BitVector_Destroy(intn->val.bv);
@@ -286,7 +288,7 @@ yasm_intnum_delete(yasm_intnum *intn)
 /*@-nullderef -nullpass -branchstate@*/
 void
 yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op, yasm_intnum *operand,
-                unsigned long lindex)
+                unsigned long line)
 {
     boolean carry = 0;
     wordptr op1, op2 = NULL;
@@ -409,13 +411,13 @@ yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op, yasm_intnum *operand,
            BitVector_LSB(result, !BitVector_equal(op1, op2));
            break;
        case YASM_EXPR_SEG:
-           yasm__error(lindex, N_("invalid use of '%s'"), "SEG");
+           yasm__error(line, N_("invalid use of '%s'"), "SEG");
            break;
        case YASM_EXPR_WRT:
-           yasm__error(lindex, N_("invalid use of '%s'"), "WRT");
+           yasm__error(line, N_("invalid use of '%s'"), "WRT");
            break;
        case YASM_EXPR_SEGOFF:
-           yasm__error(lindex, N_("invalid use of '%s'"), ":");
+           yasm__error(line, N_("invalid use of '%s'"), ":");
            break;
        case YASM_EXPR_IDENT:
            if (result)
@@ -512,7 +514,7 @@ yasm_intnum_get_int(const yasm_intnum *intn)
 void
 yasm_intnum_get_sized(const yasm_intnum *intn, unsigned char *ptr,
                      size_t destsize, size_t valsize, int shift,
-                     int bigendian, int warn, unsigned long lindex)
+                     int bigendian, int warn, unsigned long line)
 {
     wordptr op1 = op1static, op2;
     unsigned char *buf;
@@ -526,7 +528,7 @@ yasm_intnum_get_sized(const yasm_intnum *intn, unsigned char *ptr,
 
     /* General size warnings */
     if (warn && !yasm_intnum_check_size(intn, valsize, rshift, 2))
-       yasm__warning(YASM_WARN_GENERAL, lindex,
+       yasm__warning(YASM_WARN_GENERAL, line,
                      N_("value does not fit in %d bit field"), valsize);
 
     /* Read the original data into a bitvect */
@@ -550,7 +552,7 @@ yasm_intnum_get_sized(const yasm_intnum *intn, unsigned char *ptr,
        BitVector_Copy(conv_bv, op2);
        BitVector_Move_Left(conv_bv, BITVECT_NATIVE_SIZE-rshift);
        if (!BitVector_is_empty(conv_bv))
-           yasm__warning(YASM_WARN_GENERAL, lindex,
+           yasm__warning(YASM_WARN_GENERAL, line,
                          N_("misaligned value, truncating to boundary"));
     }
 
@@ -623,7 +625,7 @@ yasm_intnum_check_size(const yasm_intnum *intn, size_t size, size_t rshift,
 }
 
 void
-yasm_intnum_print(FILE *f, const yasm_intnum *intn)
+yasm_intnum_print(const yasm_intnum *intn, FILE *f)
 {
     unsigned char *s;
 
index b6d8350069f59ad153ef7049013931b3ae0d5682..75a121d0f17ef2c0f1f11cd506e712f0a6ce33f7 100644 (file)
@@ -42,53 +42,53 @@ void yasm_intnum_cleanup(void);
 
 /** Create a new intnum from a decimal string.
  * \param str      decimal string
- * \param lindex    line index (where the number came from)
+ * \param line     virtual line (where the number came from)
  * \return Newly allocated intnum.
  */
-/*@only@*/ yasm_intnum *yasm_intnum_new_dec(char *str, unsigned long lindex);
+/*@only@*/ yasm_intnum *yasm_intnum_create_dec(char *str, unsigned long line);
 
 /** Create a new intnum from a binary string.
  * \param str      binary string
- * \param lindex    line index (where the number came from)
+ * \param line     virtual line (where the number came from)
  * \return Newly allocated intnum.
  */
-/*@only@*/ yasm_intnum *yasm_intnum_new_bin(char *str, unsigned long lindex);
+/*@only@*/ yasm_intnum *yasm_intnum_create_bin(char *str, unsigned long line);
 
 /** Create a new intnum from an octal string.
  * \param str      octal string
- * \param lindex    line index (where the number came from)
+ * \param line     virtual line (where the number came from)
  * \return Newly allocated intnum.
  */
-/*@only@*/ yasm_intnum *yasm_intnum_new_oct(char *str, unsigned long lindex);
+/*@only@*/ yasm_intnum *yasm_intnum_create_oct(char *str, unsigned long line);
 
 /** Create a new intnum from a hexidecimal string.
  * \param str      hexidecimal string
- * \param lindex    line index (where the number came from)
+ * \param line     virtual line (where the number came from)
  * \return Newly allocated intnum.
  */
-/*@only@*/ yasm_intnum *yasm_intnum_new_hex(char *str, unsigned long lindex);
+/*@only@*/ yasm_intnum *yasm_intnum_create_hex(char *str, unsigned long line);
 
 /** Convert character constant to integer value, using NASM rules.  NASM syntax
  * supports automatic conversion from strings such as 'abcd' to a 32-bit
  * integer value.  This function performs those conversions.
  * \param str      character constant string
- * \param lindex    line index (where the number came from)
+ * \param line      virtual line (where the number came from)
  * \return Newly allocated intnum.
  */
-/*@only@*/ yasm_intnum *yasm_intnum_new_charconst_nasm(const char *str,
-                                                      unsigned long lindex);
+/*@only@*/ yasm_intnum *yasm_intnum_create_charconst_nasm(const char *str,
+                                                         unsigned long line);
 
 /** Create a new intnum from an unsigned integer value.
  * \param i        unsigned integer value
  * \return Newly allocated intnum.
  */
-/*@only@*/ yasm_intnum *yasm_intnum_new_uint(unsigned long i);
+/*@only@*/ yasm_intnum *yasm_intnum_create_uint(unsigned long i);
 
 /** Create a new intnum from an signed integer value.
  * \param i        signed integer value
  * \return Newly allocated intnum.
  */
-/*@only@*/ yasm_intnum *yasm_intnum_new_int(long i);
+/*@only@*/ yasm_intnum *yasm_intnum_create_int(long i);
 
 /** Duplicate an intnum.
  * \param intn intnum
@@ -99,7 +99,7 @@ void yasm_intnum_cleanup(void);
 /** Destroy (free allocated memory for) an intnum.
  * \param intn intnum
  */
-void yasm_intnum_delete(/*@only@*/ yasm_intnum *intn);
+void yasm_intnum_destroy(/*@only@*/ yasm_intnum *intn);
 
 /** Floating point calculation function: acc = acc op operand.
  * \note Not all operations in yasm_expr_op may be supported; unsupported
@@ -107,10 +107,10 @@ void yasm_intnum_delete(/*@only@*/ yasm_intnum *intn);
  * \param acc      intnum accumulator
  * \param op       operation
  * \param operand   intnum operand
- * \param lindex    line index (of expression)
+ * \param line      virtual line (of expression)
  */
 void yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op, yasm_intnum *operand,
-                     unsigned long lindex);
+                     unsigned long line);
 
 /** Simple value check for 0.
  * \param acc      intnum
@@ -161,11 +161,11 @@ long yasm_intnum_get_int(const yasm_intnum *intn);
  * \param bigendian endianness (nonzero=big, zero=little)
  * \param warn     enables standard warnings (value doesn't fit into valsize
  *                 bits)
- * \param lindex    line index; may be 0 if warn is 0
+ * \param line      virtual line; may be 0 if warn is 0
  */
 void yasm_intnum_get_sized(const yasm_intnum *intn, unsigned char *ptr,
                           size_t destsize, size_t valsize, int shift,
-                          int bigendian, int warn, unsigned long lindex);
+                          int bigendian, int warn, unsigned long line);
 
 /** Check to see if intnum will fit without overflow into size bits.
  * If is_signed is 1, intnum is treated as a signed number.
@@ -185,6 +185,6 @@ int yasm_intnum_check_size(const yasm_intnum *intn, size_t size,
  * \param f    file
  * \param intn intnum
  */
-void yasm_intnum_print(FILE *f, const yasm_intnum *intn);
+void yasm_intnum_print(const yasm_intnum *intn, FILE *f);
 
 #endif
index b867fb76840f4008d730f14bd7a1346ec66da763..96d756f5bb863a63b38730ff623c9ef380ff66a4 100644 (file)
@@ -26,7 +26,7 @@
  */
 #define YASM_LIB_INTERNAL
 #include "util.h"
-/*@unused@*/ RCSID("$IdPath: yasm/libyasm/linemgr.c,v 1.33 2003/03/16 23:52:23 peter Exp $");
+/*@unused@*/ RCSID("$IdPath$");
 
 #include "coretype.h"
 #include "hamt.h"
 
 /* Source lines tracking */
 typedef struct {
-    struct line_index_mapping *vector;
+    struct line_mapping *vector;
     unsigned long size;
     unsigned long allocated;
-} line_index_mapping_head;
+} line_mapping_head;
 
-typedef struct line_index_mapping {
-    /* monotonically increasing line index */
-    unsigned long index;
+typedef struct line_mapping {
+    /* monotonically increasing virtual line */
+    unsigned long line;
 
     /* related info */
     /* "original" source filename */
     /*@null@*/ /*@dependent@*/ const char *filename;
     /* "original" source base line number */
-    unsigned long line;
+    unsigned long file_line;
     /* "original" source line number increment (for following lines) */
     unsigned long line_inc;
-} line_index_mapping;
+} line_mapping;
 
-typedef struct line_index_assoc_data_raw_head {
+typedef struct line_assoc_data_raw_head {
     /*@only@*/ void **vector;
-    /*@null@*/ void (*delete_func) (/*@only@*/ void *);
-    unsigned long size;
-} line_index_assoc_data_raw_head;
+    const yasm_assoc_data_callback *callback;
+    size_t size;
+} line_assoc_data_raw_head;
 
-typedef struct line_index_assoc_data {
+typedef struct line_assoc_data {
     /*@only@*/ void *data;
-    /*@null@*/ void (*delete_func) (/*@only@*/ void *);
-    int type;
-} line_index_assoc_data;
+    const yasm_assoc_data_callback *callback;
+} line_assoc_data;
 
-/* Shared storage for filenames */
-static /*@only@*/ /*@null@*/ HAMT *filename_table;
+struct yasm_linemap {
+    /* Shared storage for filenames */
+    /*@only@*/ /*@null@*/ HAMT *filenames;
 
-/* Virtual line number.  Uniquely specifies every line read by the parser. */
-static unsigned long line_index;
-static /*@only@*/ /*@null@*/ line_index_mapping_head *line_index_map;
+    /* Current virtual line number. */
+    unsigned long current;
 
-/* Associated data arrays for odd data types (those likely to have data
- * associated for every line).
- */
-static line_index_assoc_data_raw_head *line_index_assoc_data_array;
-#define MAX_LINE_INDEX_ASSOC_DATA_ARRAY            8
+    /* Mappings from virtual to physical line numbers */
+    /*@only@*/ /*@null@*/ line_mapping_head *map;
+
+    /* Associated data arrays for odd data types (those likely to have data
+     * associated for every line).
+     */
+    /*@null@*/ /*@only@*/ line_assoc_data_raw_head *assoc_data_array;
+    size_t assoc_data_array_size;
+    size_t assoc_data_array_alloc;
+};
 
 static void
 filename_delete_one(/*@only@*/ void *d)
@@ -86,196 +90,202 @@ filename_delete_one(/*@only@*/ void *d)
     yasm_xfree(d);
 }
 
-static void
-yasm_std_linemgr_set(const char *filename, unsigned long line,
-                unsigned long line_inc)
+void
+yasm_linemap_set(yasm_linemap *linemap, const char *filename,
+                unsigned long file_line, unsigned long line_inc)
 {
     char *copy;
     int replace = 0;
-    line_index_mapping *mapping;
+    line_mapping *mapping;
 
     /* Create a new mapping in the map */
-    if (line_index_map->size >= line_index_map->allocated) {
+    if (linemap->map->size >= linemap->map->allocated) {
        /* allocate another size bins when full for 2x space */
-       line_index_map->vector =
-           yasm_xrealloc(line_index_map->vector, 2*line_index_map->allocated
-                         *sizeof(line_index_mapping));
-       line_index_map->allocated *= 2;
+       linemap->map->vector =
+           yasm_xrealloc(linemap->map->vector, 2*linemap->map->allocated
+                         *sizeof(line_mapping));
+       linemap->map->allocated *= 2;
     }
-    mapping = &line_index_map->vector[line_index_map->size];
-    line_index_map->size++;
+    mapping = &linemap->map->vector[linemap->map->size];
+    linemap->map->size++;
 
     /* Fill it */
 
     /* Copy the filename (via shared storage) */
     copy = yasm__xstrdup(filename);
     /*@-aliasunique@*/
-    mapping->filename = HAMT_insert(filename_table, copy, copy, &replace,
+    mapping->filename = HAMT_insert(linemap->filenames, copy, copy, &replace,
                                    filename_delete_one);
     /*@=aliasunique@*/
 
-    mapping->index = line_index;
-    mapping->line = line;
+    mapping->line = linemap->current;
+    mapping->file_line = file_line;
     mapping->line_inc = line_inc;
 }
 
-static void
-yasm_std_linemgr_initialize(void)
+yasm_linemap *
+yasm_linemap_create(void)
 {
-    int i;
+    yasm_linemap *linemap = yasm_xmalloc(sizeof(yasm_linemap));
 
-    filename_table = HAMT_new(yasm_internal_error_);
+    linemap->filenames = HAMT_create(yasm_internal_error_);
 
-    line_index = 1;
+    linemap->current = 1;
 
     /* initialize mapping vector */
-    line_index_map = yasm_xmalloc(sizeof(line_index_mapping_head));
-    line_index_map->vector = yasm_xmalloc(8*sizeof(line_index_mapping));
-    line_index_map->size = 0;
-    line_index_map->allocated = 8;
+    linemap->map = yasm_xmalloc(sizeof(line_mapping_head));
+    linemap->map->vector = yasm_xmalloc(8*sizeof(line_mapping));
+    linemap->map->size = 0;
+    linemap->map->allocated = 8;
     
     /* initialize associated data arrays */
-    line_index_assoc_data_array =
-       yasm_xmalloc(MAX_LINE_INDEX_ASSOC_DATA_ARRAY *
-                    sizeof(line_index_assoc_data_raw_head));
-    for (i=0; i<MAX_LINE_INDEX_ASSOC_DATA_ARRAY; i++) {
-       line_index_assoc_data_array[i].vector = NULL;
-       line_index_assoc_data_array[i].size = 0;
-    }
+    linemap->assoc_data_array_size = 0;
+    linemap->assoc_data_array_alloc = 2;
+    linemap->assoc_data_array = yasm_xmalloc(linemap->assoc_data_array_alloc *
+                                            sizeof(line_assoc_data_raw_head));
+
+    return linemap;
 }
 
-static void
-yasm_std_linemgr_cleanup(void)
+void
+yasm_linemap_destroy(yasm_linemap *linemap)
 {
-    if (line_index_assoc_data_array) {
-       int i;
-       for (i=0; i<MAX_LINE_INDEX_ASSOC_DATA_ARRAY; i++) {
-           line_index_assoc_data_raw_head *adrh =
-               &line_index_assoc_data_array[i];
-           if (adrh->delete_func && adrh->vector) {
-               unsigned int j;
+    if (linemap->assoc_data_array) {
+       size_t i;
+       for (i=0; i<linemap->assoc_data_array_size; i++) {
+           line_assoc_data_raw_head *adrh = &linemap->assoc_data_array[i];
+           if (adrh->vector) {
+               size_t j;
                for (j=0; j<adrh->size; j++) {
                    if (adrh->vector[j])
-                       adrh->delete_func(adrh->vector[j]);
+                       adrh->callback->destroy(adrh->vector[j]);
                }
                yasm_xfree(adrh->vector);
            }
        }
-       yasm_xfree(line_index_assoc_data_array);
-       line_index_assoc_data_array = NULL;
+       yasm_xfree(linemap->assoc_data_array);
     }
 
-    if (line_index_map) {
-       yasm_xfree(line_index_map->vector);
-       yasm_xfree(line_index_map);
-       line_index_map = NULL;
+    if (linemap->map) {
+       yasm_xfree(linemap->map->vector);
+       yasm_xfree(linemap->map);
     }
 
-    if (filename_table) {
-       HAMT_delete(filename_table, filename_delete_one);
-       filename_table = NULL;
-    }
+    if (linemap->filenames)
+       HAMT_destroy(linemap->filenames, filename_delete_one);
+
+    yasm_xfree(linemap);
 }
 
-static unsigned long
-yasm_std_linemgr_get_current(void)
+unsigned long
+yasm_linemap_get_current(yasm_linemap *linemap)
 {
-    return line_index;
+    return linemap->current;
 }
 
-static void
-yasm_std_linemgr_add_assoc_data(int type, /*@only@*/ void *data,
-                               /*@null@*/ void (*delete_func) (void *))
+void
+yasm_linemap_add_data(yasm_linemap *linemap,
+                     const yasm_assoc_data_callback *callback, void *data,
+                     /*@unused@*/ int every_hint)
 {
-    if ((type & 1) && type < MAX_LINE_INDEX_ASSOC_DATA_ARRAY*2) {
-       line_index_assoc_data_raw_head *adrh =
-           &line_index_assoc_data_array[type>>1];
-
-       if (adrh->size == 0) {
-           unsigned int i;
-
-           adrh->size = 4;
-           adrh->vector = yasm_xmalloc(adrh->size*sizeof(void *));
-           adrh->delete_func = delete_func;
-           for (i=0; i<adrh->size; i++)
-               adrh->vector[i] = NULL;
-       }
+    /* FIXME: Hint not supported yet. */
 
-       while (line_index > adrh->size) {
-           unsigned int i;
+    line_assoc_data_raw_head *adrh = NULL;
+    size_t i;
 
-           /* allocate another size bins when full for 2x space */
-           adrh->vector = yasm_xrealloc(adrh->vector,
-                                        2*adrh->size*sizeof(void *));
-           for(i=adrh->size; i<adrh->size*2; i++)
-               adrh->vector[i] = NULL;
-           adrh->size *= 2;
+    /* See if there's already associated data for this callback */
+    for (i=0; !adrh && i<linemap->assoc_data_array_size; i++) {
+       if (linemap->assoc_data_array[i].callback == callback)
+           adrh = &linemap->assoc_data_array[i];
+    }
+
+    /* No?  Then append a new one */
+    if (!adrh) {
+       linemap->assoc_data_array_size++;
+       if (linemap->assoc_data_array_size > linemap->assoc_data_array_alloc) {
+           linemap->assoc_data_array_alloc *= 2;
+           linemap->assoc_data_array =
+               yasm_xrealloc(linemap->assoc_data_array,
+                             linemap->assoc_data_array_alloc *
+                             sizeof(line_assoc_data_raw_head));
        }
+       adrh = &linemap->assoc_data_array[linemap->assoc_data_array_size-1];
+
+       adrh->size = 4;
+       adrh->vector = yasm_xmalloc(adrh->size*sizeof(void *));
+       adrh->callback = callback;
+       for (i=0; i<adrh->size; i++)
+           adrh->vector[i] = NULL;
+    }
 
-       adrh->vector[line_index-1] = data;
-       if (adrh->delete_func != delete_func)
-           yasm_internal_error(N_("multiple deletion functions specified"));
-    } else {
-       yasm_internal_error(N_("non-common data not supported yet"));
-       delete_func(data);
+    while (linemap->current > adrh->size) {
+       /* allocate another size bins when full for 2x space */
+       adrh->vector = yasm_xrealloc(adrh->vector,
+                                    2*adrh->size*sizeof(void *));
+       for (i=adrh->size; i<adrh->size*2; i++)
+           adrh->vector[i] = NULL;
+       adrh->size *= 2;
     }
+
+    /* Delete existing data for that line (if any) */
+    if (adrh->vector[linemap->current-1])
+       adrh->callback->destroy(adrh->vector[linemap->current-1]);
+
+    adrh->vector[linemap->current-1] = data;
 }
 
-static unsigned long
-yasm_std_linemgr_goto_next(void)
+unsigned long
+yasm_linemap_goto_next(yasm_linemap *linemap)
 {
-    return ++line_index;
+    return ++(linemap->current);
 }
 
-static void
-yasm_std_linemgr_lookup(unsigned long lindex, const char **filename,
-                       unsigned long *line)
+void
+yasm_linemap_lookup(yasm_linemap *linemap, unsigned long line,
+                   const char **filename, unsigned long *file_line)
 {
-    line_index_mapping *mapping;
+    line_mapping *mapping;
     unsigned long vindex, step;
 
-    assert(lindex <= line_index);
+    assert(line <= linemap->current);
 
     /* Binary search through map to find highest line_index <= index */
-    assert(line_index_map != NULL);
+    assert(linemap->map != NULL);
     vindex = 0;
     /* start step as the greatest power of 2 <= size */
     step = 1;
-    while (step*2<=line_index_map->size)
+    while (step*2<=linemap->map->size)
        step*=2;
     while (step>0) {
-       if (vindex+step < line_index_map->size
-               && line_index_map->vector[vindex+step].index <= lindex)
+       if (vindex+step < linemap->map->size
+               && linemap->map->vector[vindex+step].line <= line)
            vindex += step;
        step /= 2;
     }
-    mapping = &line_index_map->vector[vindex];
+    mapping = &linemap->map->vector[vindex];
 
     *filename = mapping->filename;
-    *line = mapping->line+mapping->line_inc*(lindex-mapping->index);
+    *file_line = mapping->file_line + mapping->line_inc*(line-mapping->line);
 }
 
-static /*@dependent@*/ /*@null@*/ void *
-yasm_std_linemgr_lookup_data(unsigned long lindex, int type)
+void *
+yasm_linemap_get_data(yasm_linemap *linemap, unsigned long line,
+                     const yasm_assoc_data_callback *callback)
 {
-    if ((type & 1) && type < MAX_LINE_INDEX_ASSOC_DATA_ARRAY*2) {
-       line_index_assoc_data_raw_head *adrh =
-           &line_index_assoc_data_array[type>>1];
-       
-       if (lindex > adrh->size)
-           return NULL;
-       return adrh->vector[lindex-1];
-    } else
+    line_assoc_data_raw_head *adrh = NULL;
+    size_t i;
+
+    /* Linear search through data array */
+    for (i=0; !adrh && i<linemap->assoc_data_array_size; i++) {
+       if (linemap->assoc_data_array[i].callback == callback)
+           adrh = &linemap->assoc_data_array[i];
+    }
+
+    if (!adrh)
+       return NULL;
+    
+    if (line > adrh->size)
        return NULL;
-}
 
-yasm_linemgr yasm_std_linemgr = {
-    yasm_std_linemgr_initialize,
-    yasm_std_linemgr_cleanup,
-    yasm_std_linemgr_get_current,
-    yasm_std_linemgr_add_assoc_data,
-    yasm_std_linemgr_goto_next,
-    yasm_std_linemgr_set,
-    yasm_std_linemgr_lookup,
-    yasm_std_linemgr_lookup_data
-};
+    return adrh->vector[line-1];
+}
index d08ed70d5a928a72447e4df017b7ffa1823f573f..c38e60c313da1921938395a2a8f87dc1759f6dc6 100644 (file)
@@ -1,5 +1,5 @@
 /* $IdPath$
- * YASM line manager (for parse stage) header file
+ * YASM virtual line mapping management functions
  *
  *  Copyright (C) 2002  Peter Johnson
  *
 #ifndef YASM_LINEMGR_H
 #define YASM_LINEMGR_H
 
-/* Standard data types appropriate for use with add_assoc_data(). */
-typedef enum yasm_linemgr_std_type {
-    /* Source line, a 0-terminated, allocated string. */
-    YASM_LINEMGR_STD_TYPE_SOURCE = 1,   
-    /* User-defined types start here.  Use odd numbers (low bit set) for types
-     * very likely to have data associated for every line.
-     */
-    YASM_LINEMGR_STD_TYPE_USER = 4
-} yasm_linemgr_std_type;
+/* Create a new line mapping repository. */
+yasm_linemap *yasm_linemap_create(void);
 
-struct yasm_linemgr {
-    /* Initialize cur_lindex and any manager internal data structures. */
-    void (*initialize) (void);
+/* Cleans up any memory allocated. */
+void yasm_linemap_destroy(yasm_linemap *linemap);
 
-    /* Cleans up any memory allocated. */
-    void (*cleanup) (void);
+/* Returns the current line index. */
+unsigned long yasm_linemap_get_current(yasm_linemap *linemap);
 
-    /* Returns the current line index. */
-    unsigned long (*get_current) (void);
-
-    /* Associates data with the current line index.
-     * Deletes old data associated with type if present.
-     * The function delete_func is used to delete the data (if non-NULL).
-     * All data of a particular type needs to have the exact same deletion
-     * function specified to this function on every call.
-     */
-    void (*add_assoc_data) (int type, /*@only@*/ void *data,
-                           /*@null@*/ void (*delete_func) (void *));
-
-    /* Goes to the next line (increments the current line index), returns
-     * the current (new) line index.
-     */
-    unsigned long (*goto_next) (void);
-
-    /* Sets a new file/line association starting point at the current line
-     * index.  line_inc indicates how much the "real" line is incremented by
-     * for each line index increment (0 is perfectly legal).
-     */
-    void (*set) (const char *filename, unsigned long line,
-                unsigned long line_inc);
+/** Get associated data for a virtual line and data callback.
+ * \param linemap   linemap
+ * \param line     virtual line
+ * \param callback  callback used when adding data
+ * \return Associated data (NULL if none).
+ */
+/*@dependent@*/ /*@null@*/ void *yasm_linemap_get_data
+    (yasm_linemap *linemap, unsigned long line,
+     const yasm_assoc_data_callback *callback);
 
-    /* Look up the associated actual file and line for a line index. */
-    void (*lookup) (unsigned long lindex, /*@out@*/ const char **filename,
-                   /*@out@*/ unsigned long *line);
+/** 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 callback     callback
+ * \param data         data to associate
+ * \param every_hint   non-zero if data is likely to be associated with every
+ *                     line; zero if not.
+ */
+void yasm_linemap_add_data(yasm_linemap *linemap,
+                          const yasm_assoc_data_callback *callback,
+                          /*@only@*/ /*@null@*/ void *data, int every_hint);
 
-    /* Returns data associated with line index and type.
-     * Returns NULL if no data of that type was associated with that line.
-     */
-    /*@dependent@*/ /*@null@*/ void * (*lookup_data) (unsigned long lindex,
-                                                     int type);
-};
+/* Goes to the next line (increments the current virtual line), returns
+ * the current (new) virtual line.
+ */
+unsigned long yasm_linemap_goto_next(yasm_linemap *linemap);
 
-extern yasm_linemgr yasm_std_linemgr;
+/* Sets 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).
+ */
+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. */
+void yasm_linemap_lookup(yasm_linemap *linemap, unsigned long line,
+                        /*@out@*/ const char **filename,
+                        /*@out@*/ unsigned long *file_line);
 #endif
diff --git a/libyasm/objfmt.c b/libyasm/objfmt.c
new file mode 100644 (file)
index 0000000..f841ace
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Object format interface
+ *
+ *  Copyright (C) 2003  Peter Johnson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * 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.
+ */
+#define YASM_LIB_INTERNAL
+#define YASM_ARCH_INTERNAL
+#include "util.h"
+/*@unused@*/ RCSID("$IdPath$");
+
+#include "coretype.h"
+#include "valparam.h"
+
+#include "objfmt.h"
+
+
+yasm_section *
+yasm_objfmt_add_default_section(yasm_objfmt *objfmt, yasm_object *object)
+{
+    yasm_section *retval;
+    yasm_valparamhead vps;
+    yasm_valparam *vp;
+
+    vp = yasm_vp_create(yasm__xstrdup(objfmt->default_section_name), NULL);
+    yasm_vps_initialize(&vps);
+    yasm_vps_append(&vps, vp);
+    retval = objfmt->section_switch(object, &vps, NULL, 0);
+    yasm_vps_delete(&vps);
+
+    return retval;
+}
index bc0d7b29e2ac96ed6693005487a95f29e8de1ccf..9506185bd847805b37b2a84bc02bf77ce808a76b 100644 (file)
@@ -43,7 +43,7 @@
  * definitions match the module loader's function definitions.  The version
  * number must never be decreased.
  */
-#define YASM_OBJFMT_VERSION    0
+#define YASM_OBJFMT_VERSION    1
 
 /** YASM object format interface. */
 struct yasm_objfmt {
@@ -91,23 +91,22 @@ struct yasm_objfmt {
      * \param obj_filename     object filename (e.g. "file.o")
      * \param df               debug format in use
      * \param a                        architecture in use
-     * \param machine          machine (of architecture) in use
      * \return Nonzero if architecture/machine combination not supported.
      */
     int (*initialize) (const char *in_filename, const char *obj_filename,
-                      yasm_dbgfmt *df, yasm_arch *a, const char *machine);
+                      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 sections list of sections
+     * \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.
      */
-    void (*output) (FILE *f, yasm_sectionhead *sections, int all_syms);
+    void (*output) (FILE *f, yasm_object *object, int all_syms);
 
     /** Cleans up anything allocated by initialize().  Function may be
      * unimplemented (NULL) if not needed by the object format.
@@ -115,34 +114,18 @@ struct yasm_objfmt {
     void (*cleanup) (void);
 
     /** Switch object file sections.  The first val of the valparams should
-     * be the section name.  Calls yasm_section_switch() to actually change
-     * the active section.
-     * \param headp            list of sections
+     * 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 lindex           line index (as from yasm_linemgr)
+     * \param line             virtual line (from yasm_linemap)
      * \return NULL on error, otherwise new section.
      */
     /*@observer@*/ /*@null@*/ yasm_section *
-       (*sections_switch)(yasm_sectionhead *headp,
-                          yasm_valparamhead *valparams,
-                          /*@null@*/ yasm_valparamhead *objext_valparams,
-                          unsigned long lindex);
-
-    /** Delete yasm_section object format-specific data.  Function may be
-     * unimplemented (NULL) if no data is ever allocated in sections_switch().
-     * \param data     object format-specific data
-     */
-    void (*section_data_delete)(/*@only@*/ void *data);
-
-    /** Print yasm_section object format-specific data.  For debugging
-     * purposes.  Function may be unimplemented (NULL) if no data is ever
-     * allocated in sections_switch() by the object format.
-     * \param f                        file
-     * \param indent_level     indentation level
-     * \param data             object format-specific data
-     */
-    void (*section_data_print)(FILE *f, int indent_level, void *data);
+       (*section_switch)(yasm_object *object, 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
@@ -150,22 +133,22 @@ struct yasm_objfmt {
      * declaration.
      * \param sym              symbol
      * \param objext_valparams object format-specific value/paramaters
-     * \param lindex           line index (from yasm_linemgr)
+     * \param line             virtual line (from yasm_linemap)
      */
     void (*extern_declare)(yasm_symrec *sym,
                           /*@null@*/ yasm_valparamhead *objext_valparams,
-                          unsigned long lindex);
+                          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 lindex           line index (from yasm_linemgr)
+     * \param line             virtual line (from yasm_linemap)
      */
     void (*global_declare)(yasm_symrec *sym,
                           /*@null@*/ yasm_valparamhead *objext_valparams,
-                          unsigned long lindex);
+                          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
@@ -174,58 +157,31 @@ struct yasm_objfmt {
      * \param sym              symbol
      * \param size             common data size
      * \param objext_valparams object format-specific value/paramaters
-     * \param lindex           line index (from yasm_linemgr)
+     * \param line             virtual line (from yasm_linemap)
      */
     void (*common_declare)(yasm_symrec *sym, /*@only@*/ yasm_expr *size,
                           /*@null@*/ yasm_valparamhead *objext_valparams,
-                          unsigned long lindex);
-
-    /** Delete object format-specific symbol data.  Function may be
-     * unimplemented (NULL) if yasm_symrec_set_of_data() is never called by the
-     * object format.
-     * \param data     object format-specific data
-     */
-    void (*symrec_data_delete)(/*@only@*/ void *data);
-
-    /** Print object format-specific symbol data.  For debugging purposes.
-     * Function may be unimplemented (NULL) if yasm_symrec_set_of_data() is
-     * never called by the object format.
-     * \param f                        file
-     * \param indent_level     indentation level
-     * \param data             object format-specific data
-     */
-    void (*symrec_data_print)(FILE *f, int indent_level, void *data);
+                          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 headp            list of sections
-     * \param lindex           line index (as from yasm_linemgr)
+     * \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.
      */
     int (*directive)(const char *name, yasm_valparamhead *valparams,
                     /*@null@*/ yasm_valparamhead *objext_valparams,
-                    yasm_sectionhead *headp, unsigned long lindex);
-
-    /** Delete object format-specific bytecode data (YASM_BC_OBJFMT_DATA).
-     * Function may be unimplemented (NULL) if no YASM_BC_OBJFMT_DATA is ever
-     * allocated by the object format.
-     * \param type     object format-specific bytecode type
-     * \param data     object format-specific data
-     */
-    void (*bc_objfmt_data_delete)(unsigned int type, /*@only@*/ void *data);
-
-    /** Print object format-specific bytecode data (YASM_BC_OBJFMT_DATA).  For
-     * debugging purposes.  Function may be unimplemented (NULL) if no
-     * YASM_BC_OBJFMT_DATA is ever allocated by the object format.
-     * \param f                        file
-     * \param indent_level     indentation level
-     * \param type             object format-specific bytecode type
-     * \param data             object format-specific data
-     */
-    void (*bc_objfmt_data_print)(FILE *f, int indent_level, unsigned int type,
-                                const void *data);
+                    yasm_object *object, unsigned long line);
 };
+
+/** Add a default section to an object.
+ * \param objfmt    object format
+ * \param object    object
+ * \return Default section.
+ */
+yasm_section *yasm_objfmt_add_default_section(yasm_objfmt *objfmt,
+                                             yasm_object *object);
 #endif
index ba6a3bfbe65f6161d82a4f7143cb9de453bd0a4f..86ab3c0eca0f3760bd0afc990bdeb6ed681d300a 100644 (file)
@@ -36,7 +36,7 @@
  * definitions match the module loader's function definitions.  The version
  * number must never be decreased.
  */
-#define YASM_OPTIMIZER_VERSION 0
+#define YASM_OPTIMIZER_VERSION 1
 
 /* Interface to the optimizer module(s) */
 struct yasm_optimizer {
@@ -59,7 +59,7 @@ struct yasm_optimizer {
      * object file.  (A failure is indicated by calling ErrorAt() from within
      * this function).
      */
-    void (*optimize) (yasm_sectionhead *sections);
+    void (*optimize) (yasm_object *object);
 };
 
 #endif
index 7afd5b3c0ccc182f34e15eaeadbeacbb71965ac4..1137a56ee15166a7922ce88602a3cf84dbcaae6b 100644 (file)
 #ifndef YASM_PARSER_H
 #define YASM_PARSER_H
 
-/** Version number of #yasm_parser interface.  Any functional change to the
- * #yasm_parser interface should simultaneously increment this number.  This
- * version should be checked by #yasm_parser 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_parser_module interface.  Any functional change to
+ * the #yasm_parser_module interface should simultaneously increment this
+ * number.  This version should be checked by #yasm_parser_module 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_PARSER_VERSION    0
+#define YASM_PARSER_VERSION    1
 
 /* Interface to the parser module(s) -- the "front end" of the assembler */
-struct yasm_parser {
+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
      * #YASM_PARSER_VERSION by the module loader.
@@ -70,13 +70,10 @@ struct yasm_parser {
      * the input filename.
      *
      * save_input is nonzero if the parser needs to save the original lines of
-     * source in the input file into the linemgr via linemgr->add_assoc_data().
-     *
-     * This function returns the starting section of a linked list of sections
-     * (whatever was in the file).
+     * source in the input file into the linemap via yasm_linemap_add_data().
      */
-    /*@only@*/ yasm_sectionhead *(*do_parse)
-       (yasm_preproc *pp, yasm_arch *a, yasm_objfmt *of, yasm_linemgr *lm,
-        FILE *f, const char *in_filename, int save_input);
-};
+    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
index 7082b6fff2cb1a1af7f37e5eb501158f966e2ce4..88f84dffdd4cfaa862b458646272f9a73dda222b 100644 (file)
@@ -36,7 +36,7 @@
  * definitions match the module loader's function definitions.  The version
  * number must never be decreased.
  */
-#define YASM_PREPROC_VERSION   0
+#define YASM_PREPROC_VERSION   1
 
 /* Interface to the preprocesor module(s) */
 struct yasm_preproc {
@@ -60,7 +60,7 @@ struct yasm_preproc {
      * This function also takes the FILE * to the initial starting file and
      * the filename.
      */
-    void (*initialize) (FILE *f, const char *in_filename, yasm_linemgr *lm);
+    void (*initialize) (FILE *f, const char *in_filename, yasm_linemap *lm);
 
     /* Cleans up any allocated memory. */
     void (*cleanup) (void);
index 059921b014fac87809782d9f2567c2432d77557c..b19fb82f6be3082970df8e1079b0e010cf35df55 100644 (file)
 
 #include "coretype.h"
 #include "valparam.h"
+#include "assocdat.h"
 
+#include "linemgr.h"
 #include "errwarn.h"
 #include "intnum.h"
 #include "expr.h"
+#include "symrec.h"
 
 #include "bytecode.h"
 #include "section.h"
 #include "objfmt.h"
 
+#include "bc-int.h"
+
+
+struct yasm_object {
+    yasm_symtab        *symtab;
+    yasm_linemap *linemap;
+
+    /*@reldef@*/ STAILQ_HEAD(yasm_sectionhead, yasm_section) sections;
+};
 
 struct yasm_section {
     /*@reldef@*/ STAILQ_ENTRY(yasm_section) link;
 
+    /*@dependent@*/ yasm_object *object;    /* Pointer to parent object */
+
     enum { SECTION_GENERAL, SECTION_ABSOLUTE } type;
 
     union {
        /* SECTION_GENERAL data */
        struct general {
            /*@owned@*/ char *name;     /* strdup()'ed name (given by user) */
-
-           /* object-format-specific data */
-           /*@null@*/ /*@dependent@*/ yasm_objfmt *of;
-           /*@null@*/ /*@owned@*/ void *of_data;
        } general;
     } data;
 
+    /* associated data; NULL if none */
+    /*@null@*/ /*@only@*/ yasm__assoc_data *assoc_data;
+
     /*@owned@*/ yasm_expr *start;   /* Starting address of section contents */
 
     unsigned long opt_flags;   /* storage for optimizer flags */
@@ -63,48 +76,42 @@ struct yasm_section {
     int res_only;              /* allow only resb family of bytecodes? */
 
     /* the bytecodes for the section's contents */
-    /*@only@*/ yasm_bytecodehead *bc;
+    /*@reldef@*/ STAILQ_HEAD(yasm_bytecodehead, yasm_bytecode) bcs;
 };
 
-/*@reldef@*/ STAILQ_HEAD(yasm_sectionhead, yasm_section);
+static void yasm_section_destroy(/*@only@*/ yasm_section *sect);
 
-static void yasm_section_delete(/*@only@*/ yasm_section *sect);
 
 /*@-compdestroy@*/
-yasm_sectionhead *
-yasm_sections_new(yasm_section **def, yasm_objfmt *of)
+yasm_object *
+yasm_object_create(void)
 {
-    yasm_sectionhead *headp;
-    yasm_valparamhead vps;
-    yasm_valparam *vp;
-
-    /* Initialize linked list */
-    headp = yasm_xmalloc(sizeof(yasm_sectionhead));
-    STAILQ_INIT(headp);
-
-    /* Add an initial "default" section */
-    vp = yasm_vp_new(yasm__xstrdup(of->default_section_name), NULL);
-    yasm_vps_initialize(&vps);
-    yasm_vps_append(&vps, vp);
-    *def = of->sections_switch(headp, &vps, NULL, 0);
-    yasm_vps_delete(&vps);
-
-    return headp;
+    yasm_object *object = yasm_xmalloc(sizeof(yasm_object));
+
+    /* Create empty symtab and linemap */
+    object->symtab = yasm_symtab_create();
+    object->linemap = yasm_linemap_create();
+
+    /* Initialize sections linked list */
+    STAILQ_INIT(&object->sections);
+
+    return object;
 }
 /*@=compdestroy@*/
 
 /*@-onlytrans@*/
 yasm_section *
-yasm_sections_switch_general(yasm_sectionhead *headp, const char *name,
-                            yasm_expr *start, int res_only, int *isnew,
-                            unsigned long lindex)
+yasm_object_get_general(yasm_object *object, const char *name,
+                       yasm_expr *start, int res_only, int *isnew,
+                       unsigned long line)
 {
     yasm_section *s;
+    yasm_bytecode *bc;
 
     /* Search through current sections to see if we already have one with
      * that name.
      */
-    STAILQ_FOREACH(s, headp, link) {
+    STAILQ_FOREACH(s, &object->sections, link) {
        if (s->type == SECTION_GENERAL &&
            strcmp(s->data.general.name, name) == 0) {
            *isnew = 0;
@@ -116,20 +123,27 @@ yasm_sections_switch_general(yasm_sectionhead *headp, const char *name,
 
     /* Okay, the name is valid; now allocate and initialize */
     s = yasm_xcalloc(1, sizeof(yasm_section));
-    STAILQ_INSERT_TAIL(headp, s, link);
+    STAILQ_INSERT_TAIL(&object->sections, s, link);
 
+    s->object = object;
     s->type = SECTION_GENERAL;
     s->data.general.name = yasm__xstrdup(name);
-    s->data.general.of = NULL;
-    s->data.general.of_data = NULL;
+    s->assoc_data = NULL;
     if (start)
        s->start = start;
     else
-       s->start = yasm_expr_new_ident(yasm_expr_int(yasm_intnum_new_uint(0)),
-                                      lindex);
-    s->bc = yasm_bcs_new();
+       s->start =
+           yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(0)),
+                                  line);
+
+    /* Initialize bytecodes with one empty bytecode (acts as "prior" for first
+     * real bytecode in section.
+     */
+    STAILQ_INIT(&s->bcs);
+    bc = yasm_bc_create_common(NULL, sizeof(yasm_bytecode), 0);
+    bc->section = s;
+    STAILQ_INSERT_TAIL(&s->bcs, bc, link);
 
-    s->opt_flags = 0;
     s->res_only = res_only;
 
     *isnew = 1;
@@ -139,24 +153,45 @@ yasm_sections_switch_general(yasm_sectionhead *headp, const char *name,
 
 /*@-onlytrans@*/
 yasm_section *
-yasm_sections_switch_absolute(yasm_sectionhead *headp, yasm_expr *start)
+yasm_object_create_absolute(yasm_object *object, yasm_expr *start,
+                           unsigned long line)
 {
     yasm_section *s;
+    yasm_bytecode *bc;
 
     s = yasm_xcalloc(1, sizeof(yasm_section));
-    STAILQ_INSERT_TAIL(headp, s, link);
+    STAILQ_INSERT_TAIL(&object->sections, s, link);
 
+    s->object = object;
     s->type = SECTION_ABSOLUTE;
     s->start = start;
-    s->bc = yasm_bcs_new();
 
-    s->opt_flags = 0;
+    /* Initialize bytecodes with one empty bytecode (acts as "prior" for first
+     * real bytecode in section.
+     */
+    STAILQ_INIT(&s->bcs);
+    bc = yasm_bc_create_common(NULL, sizeof(yasm_bytecode), 0);
+    bc->section = s;
+    STAILQ_INSERT_TAIL(&s->bcs, bc, link);
+
     s->res_only = 1;
 
     return s;
 }
 /*@=onlytrans@*/
 
+yasm_symtab *
+yasm_object_get_symtab(const yasm_object *object)
+{
+    return object->symtab;
+}
+
+yasm_linemap *
+yasm_object_get_linemap(const yasm_object *object)
+{
+    return object->linemap;
+}
+
 int
 yasm_section_is_absolute(yasm_section *sect)
 {
@@ -175,76 +210,70 @@ yasm_section_set_opt_flags(yasm_section *sect, unsigned long opt_flags)
     sect->opt_flags = opt_flags;
 }
 
-void
-yasm_section_set_of_data(yasm_section *sect, yasm_objfmt *of, void *of_data)
+yasm_object *
+yasm_section_get_object(const yasm_section *sect)
 {
-    /* Check to see if section type supports of_data */
-    if (sect->type != SECTION_GENERAL) {
-       if (of->section_data_delete)
-           of->section_data_delete(of_data);
-       else
-           yasm_internal_error(
-               N_("don't know how to delete objfmt-specific section data"));
-       return;
-    }
-
-    /* Delete current of_data if present */
-    if (sect->data.general.of_data && sect->data.general.of) {
-       yasm_objfmt *of2 = sect->data.general.of;
-       if (of2->section_data_delete)
-           of2->section_data_delete(sect->data.general.of_data);
-       else
-           yasm_internal_error(
-               N_("don't know how to delete objfmt-specific section data"));
-    }
-
-    /* Assign new of_data */
-    sect->data.general.of = of;
-    sect->data.general.of_data = of_data;
+    return sect->object;
 }
 
 void *
-yasm_section_get_of_data(yasm_section *sect)
+yasm_section_get_data(yasm_section *sect,
+                     const yasm_assoc_data_callback *callback)
 {
-    if (sect->type == SECTION_GENERAL)
-       return sect->data.general.of_data;
-    else
-       return NULL;
+    return yasm__assoc_data_get(sect->assoc_data, callback);
+}
+
+void
+yasm_section_add_data(yasm_section *sect,
+                     const yasm_assoc_data_callback *callback, void *data)
+{
+    sect->assoc_data = yasm__assoc_data_add(sect->assoc_data, callback, data);
 }
 
 void
-yasm_sections_delete(yasm_sectionhead *headp)
+yasm_object_destroy(yasm_object *object)
 {
     yasm_section *cur, *next;
 
-    cur = STAILQ_FIRST(headp);
+    /* Delete sections */
+    cur = STAILQ_FIRST(&object->sections);
     while (cur) {
        next = STAILQ_NEXT(cur, link);
-       yasm_section_delete(cur);
+       yasm_section_destroy(cur);
        cur = next;
     }
-    STAILQ_INIT(headp);
-    yasm_xfree(headp);
+
+    /* Delete symbol table and line mappings */
+    yasm_symtab_destroy(object->symtab);
+    yasm_linemap_destroy(object->linemap);
+
+    yasm_xfree(object);
 }
 
 void
-yasm_sections_print(FILE *f, int indent_level, const yasm_sectionhead *headp)
+yasm_object_print(const yasm_object *object, FILE *f, int indent_level)
 {
     yasm_section *cur;
-    
-    STAILQ_FOREACH(cur, headp, link) {
+
+    /* Print symbol table */
+    fprintf(f, "%*sSymbol Table:\n", indent_level, "");
+    yasm_symtab_print(object->symtab, f, indent_level+1);
+
+    /* Print sections and bytecodes */
+    STAILQ_FOREACH(cur, &object->sections, link) {
        fprintf(f, "%*sSection:\n", indent_level, "");
-       yasm_section_print(f, indent_level+1, cur, 1);
+       yasm_section_print(cur, f, indent_level+1, 1);
     }
 }
 
 int
-yasm_sections_traverse(yasm_sectionhead *headp, /*@null@*/ void *d,
-                      int (*func) (yasm_section *sect, /*@null@*/ void *d))
+yasm_object_sections_traverse(yasm_object *object, /*@null@*/ void *d,
+                             int (*func) (yasm_section *sect,
+                                          /*@null@*/ void *d))
 {
     yasm_section *cur;
-    
-    STAILQ_FOREACH(cur, headp, link) {
+
+    STAILQ_FOREACH(cur, &object->sections, link) {
        int retval = func(cur, d);
        if (retval != 0)
            return retval;
@@ -254,11 +283,11 @@ yasm_sections_traverse(yasm_sectionhead *headp, /*@null@*/ void *d,
 
 /*@-onlytrans@*/
 yasm_section *
-yasm_sections_find_general(yasm_sectionhead *headp, const char *name)
+yasm_object_find_general(yasm_object *object, const char *name)
 {
     yasm_section *cur;
 
-    STAILQ_FOREACH(cur, headp, link) {
+    STAILQ_FOREACH(cur, &object->sections, link) {
        if (cur->type == SECTION_GENERAL &&
            strcmp(cur->data.general.name, name) == 0)
            return cur;
@@ -267,10 +296,49 @@ yasm_sections_find_general(yasm_sectionhead *headp, const char *name)
 }
 /*@=onlytrans@*/
 
-yasm_bytecodehead *
-yasm_section_get_bytecodes(yasm_section *sect)
+yasm_bytecode *
+yasm_section_bcs_first(yasm_section *sect)
+{
+    return STAILQ_FIRST(&sect->bcs);
+}
+
+yasm_bytecode *
+yasm_section_bcs_last(yasm_section *sect)
 {
-    return sect->bc;
+    return STAILQ_LAST(&sect->bcs, yasm_bytecode, link);
+}
+
+yasm_bytecode *
+yasm_section_bcs_append(yasm_section *sect, yasm_bytecode *bc)
+{
+    if (bc) {
+       if (bc->callback) {
+           bc->section = sect;     /* record parent section */
+           STAILQ_INSERT_TAIL(&sect->bcs, bc, link);
+           return bc;
+       } else
+           yasm_xfree(bc);
+    }
+    return (yasm_bytecode *)NULL;
+}
+
+int
+yasm_section_bcs_traverse(yasm_section *sect, void *d,
+                         int (*func) (yasm_bytecode *bc, /*@null@*/ void *d))
+{
+    yasm_bytecode *cur = STAILQ_FIRST(&sect->bcs);
+
+    /* Skip our locally created empty bytecode first. */
+    cur = STAILQ_NEXT(cur, link);
+
+    /* Iterate through the remainder, if any. */
+    while (cur) {
+       int retval = func(cur, d);
+       if (retval != 0)
+           return retval;
+       cur = STAILQ_NEXT(cur, link);
+    }
+    return 0;
 }
 
 const char *
@@ -283,9 +351,9 @@ yasm_section_get_name(const yasm_section *sect)
 
 void
 yasm_section_set_start(yasm_section *sect, yasm_expr *start,
-                      unsigned long lindex)
+                      unsigned long line)
 {
-    yasm_expr_delete(sect->start);
+    yasm_expr_destroy(sect->start);
     sect->start = start;
 }
 
@@ -296,29 +364,32 @@ yasm_section_get_start(const yasm_section *sect)
 }
 
 static void
-yasm_section_delete(yasm_section *sect)
+yasm_section_destroy(yasm_section *sect)
 {
+    yasm_bytecode *cur, *next;
+
     if (!sect)
        return;
 
     if (sect->type == SECTION_GENERAL) {
        yasm_xfree(sect->data.general.name);
-       if (sect->data.general.of_data && sect->data.general.of) {
-           yasm_objfmt *of = sect->data.general.of;
-           if (of->section_data_delete)
-               of->section_data_delete(sect->data.general.of_data);
-           else
-               yasm_internal_error(
-                   N_("don't know how to delete objfmt-specific section data"));
-       }
     }
-    yasm_expr_delete(sect->start);
-    yasm_bcs_delete(sect->bc);
+    yasm__assoc_data_destroy(sect->assoc_data);
+    yasm_expr_destroy(sect->start);
+
+    /* Delete bytecodes */
+    cur = STAILQ_FIRST(&sect->bcs);
+    while (cur) {
+       next = STAILQ_NEXT(cur, link);
+       yasm_bc_destroy(cur);
+       cur = next;
+    }
+
     yasm_xfree(sect);
 }
 
 void
-yasm_section_print(FILE *f, int indent_level, const yasm_section *sect,
+yasm_section_print(const yasm_section *sect, FILE *f, int indent_level,
                   int print_bcs)
 {
     if (!sect) {
@@ -329,19 +400,8 @@ yasm_section_print(FILE *f, int indent_level, const yasm_section *sect,
     fprintf(f, "%*stype=", indent_level, "");
     switch (sect->type) {
        case SECTION_GENERAL:
-           fprintf(f, "general\n%*sname=%s\n%*sobjfmt data:\n", indent_level,
-                   "", sect->data.general.name, indent_level, "");
-           indent_level++;
-           if (sect->data.general.of_data && sect->data.general.of) {
-               yasm_objfmt *of = sect->data.general.of;
-               if (of->section_data_print)
-                   of->section_data_print(f, indent_level,
-                                          sect->data.general.of_data);
-               else
-                   fprintf(f, "%*sUNKNOWN\n", indent_level, "");
-           } else
-               fprintf(f, "%*s(none)\n", indent_level, "");
-           indent_level--;
+           fprintf(f, "general\n%*sname=%s\n", indent_level, "",
+                   sect->data.general.name, indent_level, "");
            break;
        case SECTION_ABSOLUTE:
            fprintf(f, "absolute\n");
@@ -349,11 +409,22 @@ yasm_section_print(FILE *f, int indent_level, const yasm_section *sect,
     }
 
     fprintf(f, "%*sstart=", indent_level, "");
-    yasm_expr_print(f, sect->start);
+    yasm_expr_print(sect->start, f);
     fprintf(f, "\n");
 
+    if (sect->assoc_data) {
+       fprintf(f, "%*sAssociated data:\n", indent_level, "");
+       yasm__assoc_data_print(sect->assoc_data, f, indent_level+1);
+    }
+
     if (print_bcs) {
+       yasm_bytecode *cur;
+
        fprintf(f, "%*sBytecodes:\n", indent_level, "");
-       yasm_bcs_print(f, indent_level+1, sect->bc);
+
+       STAILQ_FOREACH(cur, &sect->bcs, link) {
+           fprintf(f, "%*sNext Bytecode:\n", indent_level+1, "");
+           yasm_bc_print(cur, f, indent_level+2);
+       }
     }
 }
index da7eeeddc63ad6a38acade67ec97844b0894b895..104fa2c7ba3ef4b604e728c2ce70fa3e74f7e2f6 100644 (file)
 #ifndef YASM_SECTION_H
 #define YASM_SECTION_H
 
-/** Create a new section list.  A default section is created as the
- * first section.
- * \param def      returned; default section
- * \param of       object format in use
- * \return Newly allocated section list.
+/** Create a new object.  A default section is created as the first section.
+ * An empty symbol table (yasm_symtab) and line mapping (yasm_linemap) are
+ * automatically created.
+ * \return Newly allocated object.
  */
-/*@only@*/ yasm_sectionhead *yasm_sections_new
-    (/*@out@*/ /*@dependent@*/ yasm_section **def, yasm_objfmt *of);
+/*@only@*/ yasm_object *yasm_object_create(void);
 
 /** Create a new, or continue an existing, general section.  The section is
- * added to a section list if there's not already a section by that name.
- * \param headp            section list
+ * added to the object if there's not already a section by that name.
+ * \param object    object
  * \param name     section name
  * \param start            starting address (ignored if section already exists),
  *                 NULL if 0 or don't care.
  * \param res_only  if nonzero, only space-reserving bytecodes are allowed in
  *                 the section (ignored if section already exists)
  * \param isnew            output; set to nonzero if section did not already exist
- * \param lindex    line index of section declaration (ignored if section
+ * \param line      virtual line of section declaration (ignored if section
  *                 already exists)
  * \return New section.
  */
-/*@dependent@*/ yasm_section *yasm_sections_switch_general
-    (yasm_sectionhead *headp, const char *name,
+/*@dependent@*/ yasm_section *yasm_object_get_general
+    (yasm_object *object, const char *name,
      /*@null@*/ /*@only@*/ yasm_expr *start, int res_only,
-     /*@out@*/ int *isnew, unsigned long lindex);
+     /*@out@*/ int *isnew, unsigned long line);
 
 /** Create a new absolute section.  No checking is performed at creation to
  * check for overlaps with other absolute sections.
- * \param headp            section list
+ * \param object    object
  * \param start            starting address (expression)
+ * \param line     virtual line of section declaration
  * \return New section.
  */
-/*@dependent@*/ yasm_section *yasm_sections_switch_absolute
-    (yasm_sectionhead *headp, /*@keep@*/ yasm_expr *start);
+/*@dependent@*/ yasm_section *yasm_object_create_absolute
+    (yasm_object *object, /*@keep@*/ yasm_expr *start, unsigned long line);
+
+/** Delete (free allocated memory for) an object.  All sections in the
+ * object and all bytecodes within those sections are also deleted.
+ * \param object       object
+ */
+void yasm_object_destroy(/*@only@*/ yasm_object *object);
+
+/** Print an object.  For debugging purposes.
+ * \param object       object
+ * \param f            file
+ * \param indent_level indentation level
+ */
+void yasm_object_print(const yasm_object *object, FILE *f, int indent_level);
+
+/** Traverses all sections in an object, calling a function on each section.
+ * \param object       object
+ * \param d            data pointer passed to func on each call
+ * \param func         function
+ * \return Stops early (and returns func's return value) if func returns a
+ *        nonzero value; otherwise 0.
+ */
+int yasm_object_sections_traverse
+    (yasm_object *object, /*@null@*/ void *d,
+     int (*func) (yasm_section *sect, /*@null@*/ void *d));
+
+/** Find a general section in an object, based on its name.
+ * \param object       object
+ * \param name         section name
+ * \return Section matching name, or NULL if no match found.
+ */
+/*@dependent@*/ /*@null@*/ yasm_section *yasm_object_find_general
+    (yasm_object *object, const char *name);
+
+/** Get an object's symbol table (#yasm_symtab).
+ * \param object       object
+ * \return Symbol table.
+ */
+/*@dependent@*/ yasm_symtab *yasm_object_get_symtab(const yasm_object *object);
+
+/** Get an object's line mappings (#yasm_linemap).
+ * \param object       object
+ * \return Line mappings.
+ */
+/*@dependent@*/ yasm_linemap *yasm_object_get_linemap
+    (const yasm_object *object);
 
 /** Determine if a section is absolute or general.
  * \param sect     section
@@ -88,60 +132,67 @@ unsigned long yasm_section_get_opt_flags(const yasm_section *sect);
  */
 void yasm_section_set_opt_flags(yasm_section *sect, unsigned long opt_flags);
 
-/** Get yasm_objfmt-specific data.  For yasm_objfmt use only.
+/** Get object owner of a section.
  * \param sect     section
- * \return Object format-specific data.
+ * \return Object this section is a part of.
  */
-/*@dependent@*/ /*@null@*/ void *yasm_section_get_of_data(yasm_section *sect);
+yasm_object *yasm_section_get_object(const yasm_section *sect);
 
-/** Set yasm_objfmt-specific data.  For yasm_objfmt use only.
- * \attention Deletes any existing of_data.
+/** Get assocated data for a section and data callback.
  * \param sect     section
- * \param of       object format
- * \param of_data   object format-specific data.
+ * \param callback  callback used when adding data
+ * \return Associated data (NULL if none).
  */
-void yasm_section_set_of_data(yasm_section *sect, yasm_objfmt *of,
-                             /*@null@*/ /*@only@*/ void *of_data);
+/*@dependent@*/ /*@null@*/ void *yasm_section_get_data
+    (yasm_section *sect, const yasm_assoc_data_callback *callback);
 
-/** Delete (free allocated memory for) a section list.  All sections in the
- * section list and all bytecodes within those sections are also deleted.
- * \param headp            section list
+/** Add associated data to a section.
+ * \attention Deletes any existing associated data for that data callback.
+ * \param sect     section
+ * \param callback  callback
+ * \param data     data to associate
  */
-void yasm_sections_delete(/*@only@*/ yasm_sectionhead *headp);
+void yasm_section_add_data(yasm_section *sect,
+                          const yasm_assoc_data_callback *callback,
+                          /*@null@*/ /*@only@*/ void *data);
 
-/** Print a section list.  For debugging purposes.
- * \param f            file
- * \param indent_level indentation level
- * \param headp                section list
+/** Get the first bytecode in a section.
+ * \param sect         section
+ * \return First bytecode in section (at least one empty bytecode is always
+ *        present).
  */
-void yasm_sections_print(FILE *f, int indent_level,
-                        const yasm_sectionhead *headp);
+yasm_bytecode *yasm_section_bcs_first(yasm_section *sect);
 
-/** Traverses a section list, calling a function on each bytecode.
- * \param headp        bytecode list
- * \param d    data pointer passed to func on each call
- * \param func function
- * \return Stops early (and returns func's return value) if func returns a
- *        nonzero value; otherwise 0.
+/** Get the last bytecode in a section.
+ * \param sect         section
+ * \return Last bytecode in section (at least one empty bytecode is always
+ *        present).
  */
-int yasm_sections_traverse(yasm_sectionhead *headp, /*@null@*/ void *d,
-                          int (*func) (yasm_section *sect,
-                                       /*@null@*/ void *d));
+yasm_bytecode *yasm_section_bcs_last(yasm_section *sect);
 
-/** Find a section based on its name.
- * \param   headp   section list
- * \param   name    section name
- * \return Section matching name, or NULL if no match found.
+/** Add bytecode to the end of a section.
+ * \note Does not make a copy of bc; so don't pass this function static or
+ *      local variables, and discard the bc pointer after calling this
+ *      function.
+ * \param sect         section
+ * \param bc           bytecode (may be NULL)
+ * \return If bytecode was actually appended (it wasn't NULL or empty), the
+ *        bytecode; otherwise NULL.
  */
-/*@dependent@*/ /*@null@*/ yasm_section *yasm_sections_find_general
-    (yasm_sectionhead *headp, const char *name);
+/*@only@*/ /*@null@*/ yasm_bytecode *yasm_section_bcs_append
+    (yasm_section *sect,
+     /*@returned@*/ /*@only@*/ /*@null@*/ yasm_bytecode *bc);
 
-/** Get bytecode list of a section.
- * \param   sect    section
- * \return Bytecode list.
+/** Traverses all bytecodes in a section, calling a function on each bytecode.
+ * \param sect section
+ * \param d    data pointer passed to func on each call
+ * \param func function
+ * \return Stops early (and returns func's return value) if func returns a
+ *        nonzero value; otherwise 0.
  */
-/*@dependent@*/ yasm_bytecodehead *yasm_section_get_bytecodes
-    (yasm_section *sect);
+int yasm_section_bcs_traverse
+    (yasm_section *sect, /*@null@*/ void *d,
+     int (*func) (yasm_bytecode *bc, /*@null@*/ void *d));
 
 /** Get name of a section.
  * \param   sect    section
@@ -153,10 +204,10 @@ int yasm_sections_traverse(yasm_sectionhead *headp, /*@null@*/ void *d,
 /** Change starting address of a section.
  * \param sect     section
  * \param start            starting address
- * \param lindex    line index
+ * \param line     virtual line
  */
 void yasm_section_set_start(yasm_section *sect, /*@only@*/ yasm_expr *start,
-                           unsigned long lindex);
+                           unsigned long line);
 
 /** Get starting address of a section.
  * \param sect     section
@@ -172,6 +223,7 @@ void yasm_section_set_start(yasm_section *sect, /*@only@*/ yasm_expr *start,
  * \param sect         section
  * \param print_bcs    if nonzero, print bytecodes within section
  */
-void yasm_section_print(FILE *f, int indent_level,
-                       /*@null@*/ const yasm_section *sect, int print_bcs);
+void yasm_section_print(/*@null@*/ const yasm_section *sect, FILE *f,
+                       int indent_level, int print_bcs);
+
 #endif
index 8427ff4e54efd0dc900c2a7f9336bb738a74cafc..8cc5f607926309b2fa0603aec2b5e71e8812e5e9 100644 (file)
@@ -26,7 +26,7 @@
  */
 #define YASM_LIB_INTERNAL
 #include "util.h"
-/*@unused@*/ RCSID("$IdPath: yasm/libyasm/symrec.c,v 1.60 2003/03/15 05:07:48 peter Exp $");
+/*@unused@*/ RCSID("$IdPath$");
 
 #ifdef STDC_HEADERS
 # include <limits.h>
@@ -34,6 +34,7 @@
 
 #include "coretype.h"
 #include "hamt.h"
+#include "assocdat.h"
 
 #include "errwarn.h"
 #include "floatnum.h"
@@ -68,55 +69,46 @@ struct yasm_symrec {
     unsigned long line;                /*  symbol was first declared or used on */
     union {
        yasm_expr *expn;        /* equ value */
-       struct label_s {        /* bytecode immediately preceding a label */
-           /*@dependent@*/ /*@null@*/ yasm_section *sect;
-           /*@dependent@*/ /*@null@*/ yasm_bytecode *bc;
-       } label;
-    } value;
 
-    /* objfmt-specific data */
-    /*@null@*/ /*@dependent@*/ yasm_objfmt *of;
-    /*@null@*/ /*@owned@*/ void *of_data;
+       /* bytecode immediately preceding a label */
+       /*@dependent@*/ yasm_bytecode *precbc;
+    } value;
 
-    /* storage for optimizer flags */
-    unsigned long opt_flags;
+    /* associated data; NULL if none */
+    /*@null@*/ /*@only@*/ yasm__assoc_data *assoc_data;
 };
 
-/* The symbol table: a hash array mapped trie (HAMT). */
-static /*@only@*/ HAMT *sym_table;
-
 /* Linked list of symbols not in the symbol table. */
 typedef struct non_table_symrec_s {
      /*@reldef@*/ SLIST_ENTRY(non_table_symrec_s) link;
      /*@owned@*/ yasm_symrec *rec;
 } non_table_symrec;
-typedef /*@reldef@*/ SLIST_HEAD(nontablesymhead_s, non_table_symrec_s)
-       nontablesymhead;
-static /*@only@*/ nontablesymhead *non_table_syms;
 
+struct yasm_symtab {
+    /* The symbol table: a hash array mapped trie (HAMT). */
+    /*@only@*/ HAMT *sym_table;
+    /* Symbols not in the table */
+    SLIST_HEAD(nontablesymhead_s, non_table_symrec_s) non_table_syms;
+};
 
-void
-yasm_symrec_initialize(void)
+
+yasm_symtab *
+yasm_symtab_create(void)
 {
-    sym_table = HAMT_new(yasm_internal_error_);
-    non_table_syms = yasm_xmalloc(sizeof(nontablesymhead));
-    SLIST_INIT(non_table_syms);
+    yasm_symtab *symtab = yasm_xmalloc(sizeof(yasm_symtab));
+    symtab->sym_table = HAMT_create(yasm_internal_error_);
+    SLIST_INIT(&symtab->non_table_syms);
+    return symtab;
 }
 
 static void
-symrec_delete_one(/*@only@*/ void *d)
+symrec_destroy_one(/*@only@*/ void *d)
 {
     yasm_symrec *sym = d;
     yasm_xfree(sym->name);
     if (sym->type == SYM_EQU)
-       yasm_expr_delete(sym->value.expn);
-    if (sym->of_data && sym->of) {
-       if (sym->of->symrec_data_delete)
-           sym->of->symrec_data_delete(sym->of_data);
-       else
-           yasm_internal_error(
-               N_("don't know how to delete objfmt-specific data"));
-    }
+       yasm_expr_destroy(sym->value.expn);
+    yasm__assoc_data_destroy(sym->assoc_data);
     yasm_xfree(sym);
 }
 
@@ -128,32 +120,31 @@ symrec_new_common(/*@keep@*/ char *name)
     rec->type = SYM_UNKNOWN;
     rec->line = 0;
     rec->visibility = YASM_SYM_LOCAL;
-    rec->of = NULL;
-    rec->of_data = NULL;
-    rec->opt_flags = 0;
+    rec->assoc_data = NULL;
     return rec;
 }
 
 static /*@partial@*/ /*@dependent@*/ yasm_symrec *
-symrec_get_or_new_in_table(/*@only@*/ char *name)
+symtab_get_or_new_in_table(yasm_symtab *symtab, /*@only@*/ char *name)
 {
     yasm_symrec *rec = symrec_new_common(name);
     int replace = 0;
 
     rec->status = SYM_NOSTATUS;
 
-    return HAMT_insert(sym_table, name, rec, &replace, symrec_delete_one);
+    return HAMT_insert(symtab->sym_table, name, rec, &replace,
+                      symrec_destroy_one);
 }
 
 static /*@partial@*/ /*@dependent@*/ yasm_symrec *
-symrec_get_or_new_not_in_table(/*@only@*/ char *name)
+symtab_get_or_new_not_in_table(yasm_symtab *symtab, /*@only@*/ char *name)
 {
     non_table_symrec *sym = yasm_xmalloc(sizeof(non_table_symrec));
     sym->rec = symrec_new_common(name);
 
     sym->rec->status = SYM_NOTINTABLE;
 
-    SLIST_INSERT_HEAD(non_table_syms, sym, link);
+    SLIST_INSERT_HEAD(&symtab->non_table_syms, sym, link);
 
     return sym->rec;
 }
@@ -161,49 +152,50 @@ symrec_get_or_new_not_in_table(/*@only@*/ char *name)
 /* create a new symrec */
 /*@-freshtrans -mustfree@*/
 static /*@partial@*/ /*@dependent@*/ yasm_symrec *
-symrec_get_or_new(const char *name, int in_table)
+symtab_get_or_new(yasm_symtab *symtab, const char *name, int in_table)
 {
     char *symname = yasm__xstrdup(name);
 
     if (in_table)
-       return symrec_get_or_new_in_table(symname);
+       return symtab_get_or_new_in_table(symtab, symname);
     else
-       return symrec_get_or_new_not_in_table(symname);
+       return symtab_get_or_new_not_in_table(symtab, symname);
 }
 /*@=freshtrans =mustfree@*/
 
 /* Call a function with each symrec.  Stops early if 0 returned by func.
    Returns 0 if stopped early. */
 int
-yasm_symrec_traverse(void *d, int (*func) (yasm_symrec *sym, void *d))
+yasm_symtab_traverse(yasm_symtab *symtab, void *d,
+                    int (*func) (yasm_symrec *sym, void *d))
 {
-    return HAMT_traverse(sym_table, d, (int (*) (void *, void *))func);
+    return HAMT_traverse(symtab->sym_table, d, (int (*) (void *, void *))func);
 }
 
 yasm_symrec *
-yasm_symrec_use(const char *name, unsigned long lindex)
+yasm_symtab_use(yasm_symtab *symtab, const char *name, unsigned long line)
 {
-    yasm_symrec *rec = symrec_get_or_new(name, 1);
+    yasm_symrec *rec = symtab_get_or_new(symtab, name, 1);
     if (rec->line == 0)
-       rec->line = lindex;     /* set line number of first use */
+       rec->line = line;       /* set line number of first use */
     rec->status |= SYM_USED;
     return rec;
 }
 
 static /*@dependent@*/ yasm_symrec *
-symrec_define(const char *name, sym_type type, int in_table,
-             unsigned long lindex)
+symtab_define(yasm_symtab *symtab, const char *name, sym_type type,
+             int in_table, unsigned long line)
 {
-    yasm_symrec *rec = symrec_get_or_new(name, in_table);
+    yasm_symrec *rec = symtab_get_or_new(symtab, name, in_table);
 
     /* Has it been defined before (either by DEFINED or COMMON/EXTERN)? */
     if ((rec->status & SYM_DEFINED) ||
        (rec->visibility & (YASM_SYM_COMMON | YASM_SYM_EXTERN))) {
-       yasm__error(lindex,
+       yasm__error(line,
            N_("duplicate definition of `%s'; first defined on line %lu"),
            name, rec->line);
     } else {
-       rec->line = lindex;     /* set line number of definition */
+       rec->line = line;       /* set line number of definition */
        rec->type = type;
        rec->status |= SYM_DEFINED;
     }
@@ -211,29 +203,40 @@ symrec_define(const char *name, sym_type type, int in_table,
 }
 
 yasm_symrec *
-yasm_symrec_define_equ(const char *name, yasm_expr *e, unsigned long lindex)
+yasm_symtab_define_equ(yasm_symtab *symtab, const char *name, yasm_expr *e,
+                      unsigned long line)
 {
-    yasm_symrec *rec = symrec_define(name, SYM_EQU, 1, lindex);
+    yasm_symrec *rec = symtab_define(symtab, name, SYM_EQU, 1, line);
     rec->value.expn = e;
     rec->status |= SYM_VALUED;
     return rec;
 }
 
 yasm_symrec *
-yasm_symrec_define_label(const char *name, yasm_section *sect,
+yasm_symtab_define_label(yasm_symtab *symtab, const char *name,
                         yasm_bytecode *precbc, int in_table,
-                        unsigned long lindex)
+                        unsigned long line)
 {
-    yasm_symrec *rec = symrec_define(name, SYM_LABEL, in_table, lindex);
-    rec->value.label.sect = sect;
-    rec->value.label.bc = precbc;
+    yasm_symrec *rec;
+    rec = symtab_define(symtab, name, SYM_LABEL, in_table, line);
+    rec->value.precbc = precbc;
     return rec;
 }
 
 yasm_symrec *
-yasm_symrec_declare(const char *name, yasm_sym_vis vis, unsigned long lindex)
+yasm_symtab_define_label2(const char *name, yasm_bytecode *precbc,
+                         int in_table, unsigned long line)
 {
-    yasm_symrec *rec = symrec_get_or_new(name, 1);
+    return yasm_symtab_define_label(yasm_object_get_symtab(
+       yasm_section_get_object(yasm_bc_get_section(precbc))), name, precbc,
+       in_table, line);
+}
+
+yasm_symrec *
+yasm_symtab_declare(yasm_symtab *symtab, const char *name, yasm_sym_vis vis,
+                   unsigned long line)
+{
+    yasm_symrec *rec = symtab_get_or_new(symtab, name, 1);
 
     /* Allowable combinations:
      *  Existing State--------------  vis  New State-------------------
@@ -253,118 +256,52 @@ yasm_symrec_declare(const char *name, yasm_sym_vis vis, unsigned long lindex)
          ((rec->visibility & YASM_SYM_EXTERN) && (vis == YASM_SYM_EXTERN)))))
        rec->visibility |= vis;
     else
-       yasm__error(lindex,
+       yasm__error(line,
            N_("duplicate definition of `%s'; first defined on line %lu"),
            name, rec->line);
     return rec;
 }
 
-const char *
-yasm_symrec_get_name(const yasm_symrec *sym)
-{
-    return sym->name;
-}
-
-yasm_sym_vis
-yasm_symrec_get_visibility(const yasm_symrec *sym)
-{
-    return sym->visibility;
-}
-
-const yasm_expr *
-yasm_symrec_get_equ(const yasm_symrec *sym)
-{
-    if (sym->type == SYM_EQU)
-       return sym->value.expn;
-    return (const yasm_expr *)NULL;
-}
-
-int
-yasm_symrec_get_label(const yasm_symrec *sym,
-                     yasm_symrec_get_label_sectionp *sect,
-                     yasm_symrec_get_label_bytecodep *precbc)
-{
-    if (sym->type != SYM_LABEL) {
-       *sect = (yasm_symrec_get_label_sectionp)0xDEADBEEF;
-       *precbc = (yasm_symrec_get_label_bytecodep)0xDEADBEEF;
-       return 0;
-    }
-    *sect = sym->value.label.sect;
-    *precbc = sym->value.label.bc;
-    return 1;
-}
-
-unsigned long
-yasm_symrec_get_opt_flags(const yasm_symrec *sym)
-{
-    return sym->opt_flags;
-}
-
-void
-yasm_symrec_set_opt_flags(yasm_symrec *sym, unsigned long opt_flags)
-{
-    sym->opt_flags = opt_flags;
-}
-
-void *
-yasm_symrec_get_of_data(yasm_symrec *sym)
-{
-    return sym->of_data;
-}
-
-void
-yasm_symrec_set_of_data(yasm_symrec *sym, yasm_objfmt *of, void *of_data)
-{
-    if (sym->of_data && sym->of) {
-       if (sym->of->symrec_data_delete)
-           sym->of->symrec_data_delete(sym->of_data);
-       else
-           yasm_internal_error(
-               N_("don't know how to delete objfmt-specific data"));
-    }
-    sym->of = of;
-    sym->of_data = of_data;
-}
-
-static unsigned long firstundef_line;
 static int
-symrec_parser_finalize_checksym(yasm_symrec *sym,
-                               /*@unused@*/ /*@null@*/ void *d)
+symtab_parser_finalize_checksym(yasm_symrec *sym, /*@null@*/ void *d)
 {
+    unsigned long *firstundef_line = d;
     /* error if a symbol is used but never defined or extern/common declared */
     if ((sym->status & SYM_USED) && !(sym->status & SYM_DEFINED) &&
        !(sym->visibility & (YASM_SYM_EXTERN | YASM_SYM_COMMON))) {
        yasm__error(sym->line, N_("undefined symbol `%s' (first use)"),
                    sym->name);
-       if (sym->line < firstundef_line)
-           firstundef_line = sym->line;
+       if (sym->line < *firstundef_line)
+           *firstundef_line = sym->line;
     }
 
     return 1;
 }
 
 void
-yasm_symrec_parser_finalize(void)
+yasm_symtab_parser_finalize(yasm_symtab *symtab)
 {
-    firstundef_line = ULONG_MAX;
-    yasm_symrec_traverse(NULL, symrec_parser_finalize_checksym);
+    unsigned long firstundef_line = ULONG_MAX;
+    yasm_symtab_traverse(symtab, &firstundef_line,
+                        symtab_parser_finalize_checksym);
     if (firstundef_line < ULONG_MAX)
        yasm__error(firstundef_line,
                    N_(" (Each undefined symbol is reported only once.)"));
 }
 
 void
-yasm_symrec_cleanup(void)
+yasm_symtab_destroy(yasm_symtab *symtab)
 {
-    HAMT_delete(sym_table, symrec_delete_one);
+    HAMT_destroy(symtab->sym_table, symrec_destroy_one);
 
-    while (!SLIST_EMPTY(non_table_syms)) {
-       non_table_symrec *sym = SLIST_FIRST(non_table_syms);
-       SLIST_REMOVE_HEAD(non_table_syms, link);
-       symrec_delete_one(sym->rec);
+    while (!SLIST_EMPTY(&symtab->non_table_syms)) {
+       non_table_symrec *sym = SLIST_FIRST(&symtab->non_table_syms);
+       SLIST_REMOVE_HEAD(&symtab->non_table_syms, link);
+       symrec_destroy_one(sym->rec);
        yasm_xfree(sym);
     }
-    yasm_xfree(non_table_syms);
+
+    yasm_xfree(symtab);
 }
 
 typedef struct symrec_print_data {
@@ -379,22 +316,68 @@ symrec_print_wrapper(yasm_symrec *sym, /*@null@*/ void *d)
     symrec_print_data *data = (symrec_print_data *)d;
     assert(data != NULL);
     fprintf(data->f, "%*sSymbol `%s'\n", data->indent_level, "", sym->name);
-    yasm_symrec_print(data->f, data->indent_level+1, sym);
+    yasm_symrec_print(sym, data->f, data->indent_level+1);
     return 1;
 }
 
 void
-yasm_symrec_print_all(FILE *f, int indent_level)
+yasm_symtab_print(yasm_symtab *symtab, FILE *f, int indent_level)
 {
     symrec_print_data data;
     data.f = f;
     data.indent_level = indent_level;
-    yasm_symrec_traverse(&data, symrec_print_wrapper);
+    yasm_symtab_traverse(symtab, &data, symrec_print_wrapper);
 }
 /*@=voidabstract@*/
 
+const char *
+yasm_symrec_get_name(const yasm_symrec *sym)
+{
+    return sym->name;
+}
+
+yasm_sym_vis
+yasm_symrec_get_visibility(const yasm_symrec *sym)
+{
+    return sym->visibility;
+}
+
+const yasm_expr *
+yasm_symrec_get_equ(const yasm_symrec *sym)
+{
+    if (sym->type == SYM_EQU)
+       return sym->value.expn;
+    return (const yasm_expr *)NULL;
+}
+
+int
+yasm_symrec_get_label(const yasm_symrec *sym,
+                     yasm_symrec_get_label_bytecodep *precbc)
+{
+    if (sym->type != SYM_LABEL) {
+       *precbc = (yasm_symrec_get_label_bytecodep)0xDEADBEEF;
+       return 0;
+    }
+    *precbc = sym->value.precbc;
+    return 1;
+}
+
+void *
+yasm_symrec_get_data(yasm_symrec *sym,
+                    const yasm_assoc_data_callback *callback)
+{
+    return yasm__assoc_data_get(sym->assoc_data, callback);
+}
+
+void
+yasm_symrec_add_data(yasm_symrec *sym,
+                    const yasm_assoc_data_callback *callback, void *data)
+{
+    sym->assoc_data = yasm__assoc_data_add(sym->assoc_data, callback, data);
+}
+
 void
-yasm_symrec_print(FILE *f, int indent_level, const yasm_symrec *sym)
+yasm_symrec_print(const yasm_symrec *sym, FILE *f, int indent_level)
 {
     switch (sym->type) {
        case SYM_UNKNOWN:
@@ -403,19 +386,16 @@ yasm_symrec_print(FILE *f, int indent_level, const yasm_symrec *sym)
        case SYM_EQU:
            fprintf(f, "%*s_EQU_\n", indent_level, "");
            fprintf(f, "%*sExpn=", indent_level, "");
-           yasm_expr_print(f, sym->value.expn);
+           yasm_expr_print(sym->value.expn, f);
            fprintf(f, "\n");
            break;
        case SYM_LABEL:
            fprintf(f, "%*s_Label_\n%*sSection:\n", indent_level, "",
                    indent_level, "");
-           yasm_section_print(f, indent_level+1, sym->value.label.sect, 0);
-           if (!sym->value.label.bc)
-               fprintf(f, "%*sFirst bytecode\n", indent_level, "");
-           else {
-               fprintf(f, "%*sPreceding bytecode:\n", indent_level, "");
-               yasm_bc_print(f, indent_level+1, sym->value.label.bc);
-           }
+           yasm_section_print(yasm_bc_get_section(sym->value.precbc), f,
+                              indent_level+1, 0);
+           fprintf(f, "%*sPreceding bytecode:\n", indent_level, "");
+           yasm_bc_print(sym->value.precbc, f, indent_level+1);
            break;
     }
 
@@ -447,12 +427,9 @@ yasm_symrec_print(FILE *f, int indent_level, const yasm_symrec *sym)
        fprintf(f, "\n");
     }
 
-    if (sym->of_data && sym->of) {
-       fprintf(f, "%*sObject format-specific data:\n", indent_level, "");
-       if (sym->of->symrec_data_print)
-           sym->of->symrec_data_print(f, indent_level+1, sym->of_data);
-       else
-           fprintf(f, "%*sUNKNOWN\n", indent_level+1, "");
+    if (sym->assoc_data) {
+       fprintf(f, "%*sAssociated data:\n", indent_level, "");
+       yasm__assoc_data_print(sym->assoc_data, f, indent_level+1);
     }
 
     fprintf(f, "%*sLine Index=%lu\n", indent_level, "", sym->line);
index 639cd4e17805f4df1cb2135fd510c3116b0c433c..4a3aa6e06f6d2eb73f5422bf6c251f43ad9b463f 100644 (file)
 #ifndef YASM_SYMREC_H
 #define YASM_SYMREC_H
 
-/** Initialize symbol table internal data structures. */
-void yasm_symrec_initialize(void);
+/** Create a new symbol table. */
+yasm_symtab *yasm_symtab_create(void);
 
-/** Clean up internal symbol table allocations. */
-void yasm_symrec_cleanup(void);
+/** Destroy a symbol table and all internal symbols.
+ * \param symtab    symbol table
+ * \warning All yasm_symrec *'s into this symbol table become invalid after
+ * this is called!
+ */
+void yasm_symtab_destroy(/*@only@*/ yasm_symtab *symtab);
 
 /** Get a reference to (use) a symbol.  The symbol does not necessarily need to
  * be defined before it is used.
+ * \param symtab    symbol table
  * \param name     symbol name
- * \param lindex    line index where referenced
+ * \param line      virtual line where referenced
  * \return Symbol (dependent pointer, do not free).
  */
-/*@dependent@*/ yasm_symrec *yasm_symrec_use(const char *name,
-                                            unsigned long lindex);
+/*@dependent@*/ yasm_symrec *yasm_symtab_use
+    (yasm_symtab *symtab, const char *name, unsigned long line);
 
 /** Define a symbol as an EQU value.
+ * \param symtab    symbol table
  * \param name     symbol (EQU) name
  * \param e        EQU value (expression)
- * \param lindex    line index of EQU
+ * \param line      virtual line of EQU
  * \return Symbol (dependent pointer, do not free).
  */
-/*@dependent@*/ yasm_symrec *yasm_symrec_define_equ
-    (const char *name, /*@keep@*/ yasm_expr *e, unsigned long lindex);
+/*@dependent@*/ yasm_symrec *yasm_symtab_define_equ
+    (yasm_symtab *symtab, const char *name, /*@keep@*/ yasm_expr *e,
+     unsigned long line);
 
 /** Define a symbol as a label.
+ * \param symtab    symbol table
+ * \param name     symbol (label) name
+ * \param precbc    bytecode preceding label
+ * \param in_table  nonzero if the label should be inserted into the symbol
+ *                  table (some specially-generated ones should not be)
+ * \param line     virtual line of label
+ * \return Symbol (dependent pointer, do not free).
+ */
+/*@dependent@*/ yasm_symrec *yasm_symtab_define_label
+    (yasm_symtab *symtab, const char *name,
+     /*@dependent@*/ yasm_bytecode *precbc, int in_table, unsigned long line);
+
+/** Define a symbol as a label, shortcut (no need to find out symtab, it's
+ * determined from precbc).
  * \param name     symbol (label) name
- * \param sect     section containing label
- * \param precbc    bytecode preceding label (NULL if label is before first
- *                  bytecode in section)
+ * \param precbc    bytecode preceding label
  * \param in_table  nonzero if the label should be inserted into the symbol
  *                  table (some specially-generated ones should not be)
- * \param lindex    line index of label
+ * \param line     virtual line of label
  * \return Symbol (dependent pointer, do not free).
  */
-/*@dependent@*/ yasm_symrec *yasm_symrec_define_label
-    (const char *name, /*@dependent@*/ /*@null@*/ yasm_section *sect,
-     /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc, int in_table,
-     unsigned long lindex);
+/*@dependent@*/ yasm_symrec *yasm_symtab_define_label2
+    (const char *name, /*@dependent@*/ yasm_bytecode *precbc, int in_table,
+     unsigned long line);
 
 /** Declare external visibility of a symbol.
  * \note Not all visibility combinations are allowed.
+ * \param symtab    symbol table
  * \param name     symbol name
  * \param vis      visibility
- * \param lindex    line index of visibility-setting
+ * \param line      virtual line of visibility-setting
  * \return Symbol (dependent pointer, do not free).
  */
-/*@dependent@*/ yasm_symrec *yasm_symrec_declare
-    (const char *name, yasm_sym_vis vis, unsigned long lindex);
+/*@dependent@*/ yasm_symrec *yasm_symtab_declare
+    (yasm_symtab *symtab, const char *name, yasm_sym_vis vis,
+     unsigned long line);
+
+/** Callback function for yasm_symrec_traverse().
+ * \param sym      symbol
+ * \param d        data passed into yasm_symrec_traverse()
+ * \return Nonzero to stop symbol traversal.
+ */
+typedef int (*yasm_symtab_traverse_callback)
+    (yasm_symrec *sym, /*@null@*/ void *d);
+
+/** Traverse all symbols in the symbol table.
+ * \param symtab    symbol table
+ * \param d        data to pass to each call of callback function
+ * \param func     callback function called on each symbol
+ * \return Nonzero value returned by callback function if it ever returned
+ *         nonzero.
+ */
+int /*@alt void@*/ yasm_symtab_traverse
+    (yasm_symtab *symtab, /*@null@*/ void *d,
+     yasm_symtab_traverse_callback func);
+
+/** Finalize symbol table after parsing stage.  Checks for symbols that are
+ * used but never defined or declared #YASM_SYM_EXTERN or #YASM_SYM_COMMON.
+ */
+void yasm_symtab_parser_finalize(yasm_symtab *symtab);
+
+/** Print the symbol table.  For debugging purposes.
+ * \param symtab       symbol table
+ * \param f            file
+ * \param indent_level indentation level
+ */
+void yasm_symtab_print(yasm_symtab *symtab, FILE *f, int indent_level);
 
 /** Get the name of a symbol.
  * \param sym      symbol
@@ -102,86 +153,41 @@ yasm_sym_vis yasm_symrec_get_visibility(const yasm_symrec *sym);
 /*@observer@*/ /*@null@*/ const yasm_expr *yasm_symrec_get_equ
     (const yasm_symrec *sym);
 
-/** Dependent pointer to a section. */
-typedef /*@dependent@*/ /*@null@*/ yasm_section *
-    yasm_symrec_get_label_sectionp;
-
 /** Dependent pointer to a bytecode. */
-typedef /*@dependent@*/ /*@null@*/ yasm_bytecode *
-    yasm_symrec_get_label_bytecodep;
+typedef /*@dependent@*/ yasm_bytecode *yasm_symrec_get_label_bytecodep;
 
 /** Get the label location of a symbol.
  * \param sym      symbol
- * \param sect     section containing label (output)
- * \param precbc    bytecode preceding label (output); NULL if no preceding
- *                  bytecode in section.
+ * \param precbc    bytecode preceding label (output)
  * \return 0 if not symbol is not a label or if the symbol's visibility is
  *         #YASM_SYM_EXTERN or #YASM_SYM_COMMON (not defined in the file).
  */
 int yasm_symrec_get_label(const yasm_symrec *sym,
-                         /*@out@*/ yasm_symrec_get_label_sectionp *sect,
                          /*@out@*/ yasm_symrec_get_label_bytecodep *precbc);
 
-/** Get yasm_optimizer-specific flags.  For yasm_optimizer use only.
- * \param sym      symbol
- * \return Optimizer-specific flags.
- */
-unsigned long yasm_symrec_get_opt_flags(const yasm_symrec *sym);
-
-/** Set yasm_optimizer-specific flags.  For yasm_optimizer use only.
- * \param sym      symbol
- * \param opt_flags optimizer-specific flags.
- */
-void yasm_symrec_set_opt_flags(yasm_symrec *sym, unsigned long opt_flags);
-
-/** Get yasm_objfmt-specific data.  For yasm_objfmt use only.
+/** Get associated data for a symbol and data callback.
  * \param sym      symbol
- * \return Object format-specific data.
+ * \param callback  callback used when adding data
+ * \return Associated data (NULL if none).
  */
-/*@dependent@*/ /*@null@*/ void *yasm_symrec_get_of_data(yasm_symrec *sym);
+/*@dependent@*/ /*@null@*/ void *yasm_symrec_get_data
+    (yasm_symrec *sym, const yasm_assoc_data_callback *callback);
 
-/** Set yasm_objfmt-specific data.  For yasm_objfmt use only.
- * \attention Deletes any existing of_data.
+/** Add associated data to a symbol.
+ * \attention Deletes any existing associated data for that data callback.
  * \param sym      symbol
- * \param of       object format
- * \param of_data   object format-specific data.
- */
-void yasm_symrec_set_of_data(yasm_symrec *sym, yasm_objfmt *of,
-                            /*@only@*/ /*@null@*/ void *of_data);
-
-/** Callback function for yasm_symrec_traverse().
- * \param sym      symbol
- * \param d        data passed into yasm_symrec_traverse()
- * \return Nonzero to stop symbol traversal.
- */
-typedef int (*yasm_symrec_traverse_callback)
-    (yasm_symrec *sym, /*@null@*/ void *d);
-
-/** Traverse all symbols in the symbol table.
- * \param d    data to pass to each call of callback function
- * \param func callback function called on each symbol
- * \return Nonzero value returned by callback function if it ever returned
- *         nonzero.
- */
-int /*@alt void@*/ yasm_symrec_traverse
-    (/*@null@*/ void *d, yasm_symrec_traverse_callback func);
-
-/** Finalize symbol table after parsing stage.  Checks for symbols that are
- * used but never defined or declared #YASM_SYM_EXTERN or #YASM_SYM_COMMON.
- */
-void yasm_symrec_parser_finalize(void);
-
-/** Print the symbol table.  For debugging purposes.
- * \param f            file
- * \param indent_level indentation level
+ * \param callback  callback
+ * \param data     data to associate
  */
-void yasm_symrec_print_all(FILE *f, int indent_level);
+void yasm_symrec_add_data(yasm_symrec *sym,
+                         const yasm_assoc_data_callback *callback,
+                         /*@only@*/ /*@null@*/ void *data);
 
 /** Print a symbol.  For debugging purposes.
  * \param f            file
  * \param indent_level indentation level
  * \param sym          symbol
  */
-void yasm_symrec_print(FILE *f, int indent_level, const yasm_symrec *sym);
+void yasm_symrec_print(const yasm_symrec *sym, FILE *f, int indent_level);
 
 #endif
index c3e2eec38d7b953173d244671c8fab1fdc50ee82..ba47a78e91e371de278a99a670acaa88a79f866d 100644 (file)
@@ -157,7 +157,7 @@ static char ret_msg[1024], result_msg[1024];
 static void
 new_setup(Init_Entry *vals, int i)
 {
-    flt = yasm_floatnum_new(vals[i].ascii);
+    flt = yasm_floatnum_create(vals[i].ascii);
     strcpy(result_msg, vals[i].ascii);
     strcat(result_msg, ": incorrect ");
 }
@@ -202,7 +202,7 @@ START_TEST(test_new_normalized)
     for (i=0; i<num; i++) {
        new_setup(vals, i);
        fail_unless(new_check_flt(&vals[i]) == 0, result_msg);
-       yasm_floatnum_delete(flt);
+       yasm_floatnum_destroy(flt);
     }
 }
 END_TEST
@@ -215,7 +215,7 @@ START_TEST(test_new_normalized_edgecase)
     for (i=0; i<num; i++) {
        new_setup(vals, i);
        fail_unless(new_check_flt(&vals[i]) == 0, result_msg);
-       yasm_floatnum_delete(flt);
+       yasm_floatnum_destroy(flt);
     }
 }
 END_TEST
index b486a761e04ba904cae2cffa3ccfba13d2083741..4435e915cd7abc7f3921172242f7e0f52ce728c1 100644 (file)
@@ -26,7 +26,7 @@
  */
 #define YASM_LIB_INTERNAL
 #include "util.h"
-/*@unused@*/ RCSID("$IdPath: yasm/libyasm/valparam.c,v 1.13 2003/03/16 23:53:31 peter Exp $");
+/*@unused@*/ RCSID("$IdPath$");
 
 #include "coretype.h"
 #include "valparam.h"
@@ -35,7 +35,7 @@
 
 
 yasm_valparam *
-yasm_vp_new(/*@keep@*/ char *v, /*@keep@*/ yasm_expr *p)
+yasm_vp_create(/*@keep@*/ char *v, /*@keep@*/ yasm_expr *p)
 {
     yasm_valparam *r = yasm_xmalloc(sizeof(yasm_valparam));
     r->val = v;
@@ -54,7 +54,7 @@ yasm_vps_delete(yasm_valparamhead *headp)
        if (cur->val)
            yasm_xfree(cur->val);
        if (cur->param)
-           yasm_expr_delete(cur->param);
+           yasm_expr_destroy(cur->param);
        yasm_xfree(cur);
        cur = next;
     }
@@ -62,7 +62,7 @@ yasm_vps_delete(yasm_valparamhead *headp)
 }
 
 void
-yasm_vps_print(FILE *f, const yasm_valparamhead *headp)
+yasm_vps_print(const yasm_valparamhead *headp, FILE *f)
 {
     const yasm_valparam *vp;
 
@@ -77,7 +77,7 @@ yasm_vps_print(FILE *f, const yasm_valparamhead *headp)
        else
            fprintf(f, "((nil),");
        if (vp->param)
-           yasm_expr_print(f, vp->param);
+           yasm_expr_print(vp->param, f);
        else
            fprintf(f, "(nil)");
        fprintf(f, ")");
@@ -86,12 +86,19 @@ yasm_vps_print(FILE *f, const yasm_valparamhead *headp)
     }
 }
 
-/* Non-macro yasm_vps_initialize() for non-YASM_LIB_INTERNAL users. */
-#undef yasm_vps_initialize
+yasm_valparamhead *
+yasm_vps_create(void)
+{
+    yasm_valparamhead *headp = yasm_xmalloc(sizeof(yasm_valparamhead));
+    yasm_vps_initialize(headp);
+    return headp;
+}
+
 void
-yasm_vps_initialize(/*@out@*/ yasm_valparamhead *headp)
+yasm_vps_destroy(yasm_valparamhead *headp)
 {
-    STAILQ_INIT(headp);
+    yasm_vps_delete(headp);
+    yasm_xfree(headp);
 }
 
 /* Non-macro yasm_vps_append() for non-YASM_LIB_INTERNAL users. */
index 5a20e681d49358b238a25842b9c94aade28e5500..4b12442f1e4ab1e016a8a97bc5f88182adf407f6 100644 (file)
@@ -51,21 +51,31 @@ struct yasm_valparam {
  * \param p    parameter
  * \return Newly allocated valparam.
  */
-yasm_valparam *yasm_vp_new(/*@keep@*/ char *v, /*@keep@*/ yasm_expr *p);
+yasm_valparam *yasm_vp_create(/*@keep@*/ char *v, /*@keep@*/ yasm_expr *p);
 
+/** Create a new linked list of valparams.
+ * \return Newly allocated valparam list.
+ */
+yasm_valparamhead *yasm_vps_create(void);
+
+/** Destroy a list of instruction operands (created with yasm_vps_create).
+ * \param headp                list of instruction operands
+ */
+void yasm_vps_destroy(yasm_valparamhead *headp);
+
+#ifdef YASM_LIB_INTERNAL
 /** Initialize linked list of valparams.
  * \param headp        linked list
  */
-void yasm_vps_initialize(/*@out@*/ yasm_valparamhead *headp);
-#ifdef YASM_LIB_INTERNAL
 #define yasm_vps_initialize(headp)     STAILQ_INIT(headp)
-#endif
 
-/** Destroy (free allocated memory for) linked list of valparams.
+/** Destroy (free allocated memory for) linked list of valparams (created with
+ * yasm_vps_initialize).
  * \warning Deletes val/params.
  * \param headp        linked list
  */
 void yasm_vps_delete(yasm_valparamhead *headp);
+#endif
 
 /** Append valparam to tail of linked list.
  * \param headp        linked list
@@ -109,6 +119,6 @@ void yasm_vps_append(yasm_valparamhead *headp, /*@keep@*/ yasm_valparam *vp);
  * \param f    file
  * \param headp        linked list
  */
-void yasm_vps_print(FILE *f, /*@null@*/ const yasm_valparamhead *headp);
+void yasm_vps_print(/*@null@*/ const yasm_valparamhead *headp, FILE *f);
 
 #endif
index 4bb088d142a6c435f2bf1ff1893148d81c4a882e..52482e956ad5ce47aad801ebf2f3b5594cd00a10 100644 (file)
 #include "lc3barch.h"
 
 
-static int
-lc3b_initialize(/*@unused@*/ const char *machine)
+yasm_arch_module yasm_lc3b_LTX_arch;
+
+
+static /*@only@*/ yasm_arch *
+lc3b_create(const char *machine)
 {
+    yasm_arch *arch;
+
     if (yasm__strcasecmp(machine, "lc3b") != 0)
-       return 1;
-    return 0;
+       return NULL;
+
+    arch = yasm_xmalloc(sizeof(yasm_arch));
+    arch->module = &yasm_lc3b_LTX_arch;
+    return arch;
 }
 
 static void
-lc3b_cleanup(void)
+lc3b_destroy(/*@only@*/ yasm_arch *arch)
 {
+    yasm_xfree(arch);
 }
 
-int
-yasm_lc3b__parse_directive(/*@unused@*/ const char *name,
-                          /*@unused@*/ yasm_valparamhead *valparams,
-                          /*@unused@*/ /*@null@*/
-                          yasm_valparamhead *objext_valparams,
-                          /*@unused@*/ yasm_sectionhead *headp,
-                          /*@unused@*/ unsigned long lindex)
+static const char *
+lc3b_get_machine(/*@unused@*/ const yasm_arch *arch)
+{
+    return "lc3b";
+}
+
+static int
+lc3b_set_var(yasm_arch *arch, const char *var, unsigned long val)
 {
     return 1;
 }
 
-unsigned int
-yasm_lc3b__get_reg_size(unsigned long reg)
+static int
+lc3b_parse_directive(/*@unused@*/ yasm_arch *arch,
+                    /*@unused@*/ const char *name,
+                    /*@unused@*/ yasm_valparamhead *valparams,
+                    /*@unused@*/ /*@null@*/
+                    yasm_valparamhead *objext_valparams,
+                    /*@unused@*/ yasm_object *object,
+                    /*@unused@*/ unsigned long line)
+{
+    return 1;
+}
+
+static unsigned int
+lc3b_get_reg_size(/*@unused@*/ yasm_arch *arch, /*@unused@*/ unsigned long reg)
 {
     return 2;
 }
 
-void
-yasm_lc3b__reg_print(FILE *f, unsigned long reg)
+static void
+lc3b_reg_print(/*@unused@*/ yasm_arch *arch, unsigned long reg, FILE *f)
 {
     fprintf(f, "r%u", (unsigned int)(reg&7));
 }
 
 static int
-yasm_lc3b__floatnum_tobytes(const yasm_floatnum *flt, unsigned char *buf,
-                           size_t destsize, size_t valsize, size_t shift,
-                           int warn, unsigned long lindex)
+lc3b_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)
 {
-    yasm__error(lindex, N_("LC-3b does not support floating point"));
+    yasm__error(line, N_("LC-3b does not support floating point"));
     return 1;
 }
 
 static yasm_effaddr *
-yasm_lc3b__ea_new_expr(yasm_expr *e)
+lc3b_ea_create_expr(yasm_arch *arch, yasm_expr *e)
 {
-    yasm_expr_delete(e);
+    yasm_expr_destroy(e);
     return NULL;
 }
 
@@ -92,32 +114,27 @@ static yasm_arch_machine lc3b_machines[] = {
 };
 
 /* Define arch structure -- see arch.h for details */
-yasm_arch yasm_lc3b_LTX_arch = {
+yasm_arch_module yasm_lc3b_LTX_arch = {
     YASM_ARCH_VERSION,
     "LC-3b",
     "lc3b",
-    lc3b_initialize,
-    lc3b_cleanup,
+    lc3b_create,
+    lc3b_destroy,
+    lc3b_get_machine,
+    lc3b_set_var,
     yasm_lc3b__parse_cpu,
     yasm_lc3b__parse_check_id,
-    yasm_lc3b__parse_directive,
+    lc3b_parse_directive,
     yasm_lc3b__parse_insn,
     NULL,      /*yasm_lc3b__parse_prefix*/
     NULL,      /*yasm_lc3b__parse_seg_prefix*/
     NULL,      /*yasm_lc3b__parse_seg_override*/
-    LC3B_BYTECODE_TYPE_MAX,
-    yasm_lc3b__bc_delete,
-    yasm_lc3b__bc_print,
-    yasm_lc3b__bc_resolve,
-    yasm_lc3b__bc_tobytes,
-    yasm_lc3b__floatnum_tobytes,
+    lc3b_floatnum_tobytes,
     yasm_lc3b__intnum_tobytes,
-    yasm_lc3b__get_reg_size,
-    yasm_lc3b__reg_print,
+    lc3b_get_reg_size,
+    lc3b_reg_print,
     NULL,      /*yasm_lc3b__segreg_print*/
-    yasm_lc3b__ea_new_expr,
-    NULL,      /*yasm_lc3b__ea_data_delete*/
-    NULL,      /*yasm_lc3b__ea_data_print*/
+    lc3b_ea_create_expr,
     lc3b_machines,
     "lc3b",
     2
index 72164106784d33084dc71458e8778879a544178b..5ef5dbd4fd27349ce09e3030ad18f6e416098a7a 100644 (file)
 #ifndef YASM_LC3BARCH_H
 #define YASM_LC3BARCH_H
 
-typedef enum {
-    LC3B_BC_INSN = YASM_BYTECODE_TYPE_BASE
-} lc3b_bytecode_type;
-#define LC3B_BYTECODE_TYPE_MAX LC3B_BC_INSN+1
-
 /* Types of immediate.  All immediates are stored in the LSBs of the insn. */
 typedef enum lc3b_imm_type {
     LC3B_IMM_NONE = 0, /* no immediate */
@@ -49,45 +44,29 @@ typedef enum lc3b_imm_type {
  * (it doesn't make a copy).
  */
 typedef struct lc3b_new_insn_data {
-    unsigned long lindex;
+    unsigned long line;
     /*@keep@*/ /*@null@*/ yasm_expr *imm;
     lc3b_imm_type imm_type;
     /*@null@*/ /*@dependent@*/ yasm_symrec *origin;
     unsigned int opcode;
 } lc3b_new_insn_data;
 
-yasm_bytecode *yasm_lc3b__bc_new_insn(lc3b_new_insn_data *d);
-
-void yasm_lc3b__bc_delete(yasm_bytecode *bc);
-void yasm_lc3b__bc_print(FILE *f, int indent_level, const yasm_bytecode *bc);
-yasm_bc_resolve_flags yasm_lc3b__bc_resolve
-    (yasm_bytecode *bc, int save, const yasm_section *sect,
-     yasm_calc_bc_dist_func calc_bc_dist);
-int yasm_lc3b__bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
-                         const yasm_section *sect, void *d,
-                         yasm_output_expr_func output_expr);
+yasm_bytecode *yasm_lc3b__bc_create_insn(lc3b_new_insn_data *d);
 
-void yasm_lc3b__parse_cpu(const char *cpuid, unsigned long lindex);
+void yasm_lc3b__parse_cpu(yasm_arch *arch, const char *cpuid,
+                         unsigned long line);
 
 yasm_arch_check_id_retval yasm_lc3b__parse_check_id
-    (unsigned long data[2], const char *id, unsigned long lindex);
-
-int yasm_lc3b__parse_directive(const char *name, yasm_valparamhead *valparams,
-                              /*@null@*/ yasm_valparamhead *objext_valparams,
-                              yasm_sectionhead *headp, unsigned long lindex);
+    (yasm_arch *arch, unsigned long data[2], const char *id,
+     unsigned long line);
 
 /*@null@*/ yasm_bytecode *yasm_lc3b__parse_insn
-    (const unsigned long data[2], int num_operands,
-     /*@null@*/ yasm_insn_operandhead *operands, yasm_section *cur_section,
-     /*@null@*/ yasm_bytecode *prev_bc, unsigned long lindex);
-
-int yasm_lc3b__intnum_tobytes(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 lindex);
-
-unsigned int yasm_lc3b__get_reg_size(unsigned long reg);
-
-void yasm_lc3b__reg_print(FILE *f, unsigned long reg);
+    (yasm_arch *arch, const unsigned long data[2], int num_operands,
+     /*@null@*/ yasm_insn_operandhead *operands, yasm_bytecode *prev_bc,
+     unsigned long line);
 
+int yasm_lc3b__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);
 #endif
index 990632f89109899b81da5418c839ff641b6ed86f..77c6fffd1a0f1e99b0019ef4a492af0badac07d0 100644 (file)
@@ -34,6 +34,8 @@
 #include "lc3barch.h"
 
 
+/* Bytecode types */
+
 typedef struct lc3b_insn {
     yasm_bytecode bc;          /* base structure */
 
@@ -45,15 +47,35 @@ typedef struct lc3b_insn {
     unsigned int opcode;       /* opcode */
 } lc3b_insn;
 
+/* Bytecode callback function prototypes */
+
+static void lc3b_bc_insn_destroy(yasm_bytecode *bc);
+static void lc3b_bc_insn_print(const yasm_bytecode *bc, FILE *f,
+                              int indent_level);
+static yasm_bc_resolve_flags lc3b_bc_insn_resolve
+    (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+static int lc3b_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp,
+                               void *d, yasm_output_expr_func output_expr,
+                               /*@null@*/ yasm_output_reloc_func output_reloc);
+
+/* Bytecode callback structures */
+
+static const yasm_bytecode_callback lc3b_bc_callback_insn = {
+    lc3b_bc_insn_destroy,
+    lc3b_bc_insn_print,
+    lc3b_bc_insn_resolve,
+    lc3b_bc_insn_tobytes
+};
+
 
 /*@-compmempass -mustfree@*/
 yasm_bytecode *
-yasm_lc3b__bc_new_insn(lc3b_new_insn_data *d)
+yasm_lc3b__bc_create_insn(lc3b_new_insn_data *d)
 {
     lc3b_insn *insn;
    
-    insn = (lc3b_insn *)yasm_bc_new_common((yasm_bytecode_type)LC3B_BC_INSN,
-                                          sizeof(lc3b_insn), d->lindex);
+    insn = (lc3b_insn *)yasm_bc_create_common(&lc3b_bc_callback_insn,
+                                             sizeof(lc3b_insn), d->line);
 
     insn->imm = d->imm;
     if (d->imm)
@@ -67,28 +89,19 @@ yasm_lc3b__bc_new_insn(lc3b_new_insn_data *d)
 }
 /*@=compmempass =mustfree@*/
 
-void
-yasm_lc3b__bc_delete(yasm_bytecode *bc)
+static void
+lc3b_bc_insn_destroy(yasm_bytecode *bc)
 {
-    lc3b_insn *insn;
-
-    if ((lc3b_bytecode_type)bc->type != LC3B_BC_INSN)
-       return;
-
-    insn = (lc3b_insn *)bc;
+    lc3b_insn *insn = (lc3b_insn *)bc;
     if (insn->imm)
-       yasm_expr_delete(insn->imm);
+       yasm_expr_destroy(insn->imm);
 }
 
-void
-yasm_lc3b__bc_print(FILE *f, int indent_level, const yasm_bytecode *bc)
+static void
+lc3b_bc_insn_print(const yasm_bytecode *bc, FILE *f, int indent_level)
 {
-    const lc3b_insn *insn;
+    const lc3b_insn *insn = (const lc3b_insn *)bc;
 
-    if ((lc3b_bytecode_type)bc->type != LC3B_BC_INSN)
-       return;
-
-    insn = (const lc3b_insn *)bc;
     fprintf(f, "%*s_Instruction_\n", indent_level, "");
     fprintf(f, "%*sImmediate Value:", indent_level, "");
     if (!insn->imm)
@@ -96,7 +109,7 @@ yasm_lc3b__bc_print(FILE *f, int indent_level, const yasm_bytecode *bc)
     else {
        indent_level++;
        fprintf(f, "\n%*sVal=", indent_level, "");
-       yasm_expr_print(f, insn->imm);
+       yasm_expr_print(insn->imm, f);
        fprintf(f, "\n%*sType=", indent_level, "");
        switch (insn->imm_type) {
            case LC3B_IMM_NONE:
@@ -129,27 +142,22 @@ yasm_lc3b__bc_print(FILE *f, int indent_level, const yasm_bytecode *bc)
     fprintf(f, "\n%*sOrigin=", indent_level, "");
     if (insn->origin) {
        fprintf(f, "\n");
-       yasm_symrec_print(f, indent_level+1, insn->origin);
+       yasm_symrec_print(insn->origin, f, indent_level+1);
     } else
        fprintf(f, "(nil)\n");
     fprintf(f, "%*sOpcode: %04x\n", indent_level, "",
            (unsigned int)insn->opcode);
 }
 
-yasm_bc_resolve_flags
-yasm_lc3b__bc_resolve(yasm_bytecode *bc, int save, const yasm_section *sect,
-                     yasm_calc_bc_dist_func calc_bc_dist)
+static yasm_bc_resolve_flags
+lc3b_bc_insn_resolve(yasm_bytecode *bc, int save,
+                    yasm_calc_bc_dist_func calc_bc_dist)
 {
-    lc3b_insn *insn;
+    lc3b_insn *insn = (lc3b_insn *)bc;
     /*@null@*/ yasm_expr *temp;
     /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
     long rel;
 
-    if ((lc3b_bytecode_type)bc->type != LC3B_BC_INSN)
-       yasm_internal_error(N_("Didn't handle bytecode type in lc3b arch"));
-
-    insn = (lc3b_insn *)bc;
-
     /* Fixed size instruction length */
     bc->len = 2;
 
@@ -160,17 +168,17 @@ yasm_lc3b__bc_resolve(yasm_bytecode *bc, int save, const yasm_section *sect,
        return YASM_BC_RESOLVE_MIN_LEN;
 
     temp = yasm_expr_copy(insn->imm);
-    temp = yasm_expr_new(YASM_EXPR_SUB, yasm_expr_expr(temp),
-                        yasm_expr_sym(insn->origin), bc->line);
+    temp = yasm_expr_create(YASM_EXPR_SUB, yasm_expr_expr(temp),
+                           yasm_expr_sym(insn->origin), bc->line);
     num = yasm_expr_get_intnum(&temp, calc_bc_dist);
     if (!num) {
        yasm__error(bc->line, N_("target external or out of segment"));
-       yasm_expr_delete(temp);
+       yasm_expr_destroy(temp);
        return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
     }
     rel = yasm_intnum_get_int(num);
     rel -= 2;
-    yasm_expr_delete(temp);
+    yasm_expr_destroy(temp);
     /* 9-bit signed, word-multiple displacement */
     if (rel < -512 || rel > 511) {
        yasm__error(bc->line, N_("target out of range"));
@@ -179,17 +187,12 @@ yasm_lc3b__bc_resolve(yasm_bytecode *bc, int save, const yasm_section *sect,
     return YASM_BC_RESOLVE_MIN_LEN;
 }
 
-int
-yasm_lc3b__bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
-                     const yasm_section *sect, void *d,
-                     yasm_output_expr_func output_expr)
+static int
+lc3b_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+                    yasm_output_expr_func output_expr,
+                    /*@unused@*/ yasm_output_reloc_func output_reloc)
 {
-    lc3b_insn *insn;
-
-    if ((lc3b_bytecode_type)bc->type != LC3B_BC_INSN)
-       return 0;
-
-    insn = (lc3b_insn *)bc;
+    lc3b_insn *insn = (lc3b_insn *)bc;
 
     /* Output opcode */
     YASM_SAVE_16_L(*bufp, insn->opcode);
@@ -199,33 +202,34 @@ yasm_lc3b__bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
        case LC3B_IMM_NONE:
            break;
        case LC3B_IMM_4:
-           if (output_expr(&insn->imm, *bufp, 2, 4, 0, 0, sect, bc, 0, 1, d))
+           if (output_expr(&insn->imm, *bufp, 2, 4, 0, 0, bc, 0, 1, d))
                return 1;
            break;
        case LC3B_IMM_5:
-           if (output_expr(&insn->imm, *bufp, 2, 5, 0, 0, sect, bc, 0, 1, d))
+           if (output_expr(&insn->imm, *bufp, 2, 5, 0, 0, bc, 0, 1, d))
                return 1;
            break;
        case LC3B_IMM_6_WORD:
-           if (output_expr(&insn->imm, *bufp, 2, 6, -1, 0, sect, bc, 0, 1, d))
+           if (output_expr(&insn->imm, *bufp, 2, 6, -1, 0, bc, 0, 1, d))
                return 1;
            break;
        case LC3B_IMM_6_BYTE:
-           if (output_expr(&insn->imm, *bufp, 2, 6, 0, 0, sect, bc, 0, 1, d))
+           if (output_expr(&insn->imm, *bufp, 2, 6, 0, 0, bc, 0, 1, d))
                return 1;
            break;
        case LC3B_IMM_8:
-           if (output_expr(&insn->imm, *bufp, 2, 8, -1, 0, sect, bc, 0, 1, d))
+           if (output_expr(&insn->imm, *bufp, 2, 8, -1, 0, bc, 0, 1, d))
                return 1;
            break;
        case LC3B_IMM_9_PC:
-           insn->imm = yasm_expr_new(YASM_EXPR_SUB, yasm_expr_expr(insn->imm),
-                                     yasm_expr_sym(insn->origin), bc->line);
-           if (output_expr(&insn->imm, *bufp, 2, 9, -1, 0, sect, bc, 1, 1, d))
+           insn->imm = yasm_expr_create(YASM_EXPR_SUB,
+               yasm_expr_expr(insn->imm), yasm_expr_sym(insn->origin),
+               bc->line);
+           if (output_expr(&insn->imm, *bufp, 2, 9, -1, 0, bc, 1, 1, d))
                return 1;
            break;
        case LC3B_IMM_9:
-           if (output_expr(&insn->imm, *bufp, 2, 9, -1, 0, sect, bc, 0, 1, d))
+           if (output_expr(&insn->imm, *bufp, 2, 9, -1, 0, bc, 0, 1, d))
                return 1;
            break;
        default:
@@ -237,10 +241,10 @@ yasm_lc3b__bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
 }
 
 int
-yasm_lc3b__intnum_tobytes(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 lindex)
+yasm_lc3b__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)
 {
     if (rel) {
        yasm_intnum *relnum, *delta;
@@ -248,16 +252,16 @@ yasm_lc3b__intnum_tobytes(const yasm_intnum *intn, unsigned char *buf,
            yasm_internal_error(
                N_("tried to do PC-relative offset from invalid sized value"));
        relnum = yasm_intnum_copy(intn);
-       delta = yasm_intnum_new_uint(bc->len);
-       yasm_intnum_calc(relnum, YASM_EXPR_SUB, delta, lindex);
-       yasm_intnum_delete(delta);
+       delta = yasm_intnum_create_uint(bc->len);
+       yasm_intnum_calc(relnum, YASM_EXPR_SUB, delta, line);
+       yasm_intnum_destroy(delta);
        yasm_intnum_get_sized(relnum, buf, destsize, valsize, shift, 0, warn,
-                             lindex);
-       yasm_intnum_delete(relnum);
+                             line);
+       yasm_intnum_destroy(relnum);
     } else {
        /* Write value out. */
        yasm_intnum_get_sized(intn, buf, destsize, valsize, shift, 0, warn,
-                             lindex);
+                             line);
     }
     return 0;
 }
index e425c5882420b33d03c7b627a0422498c7b08f5f..5e5cdcd16e73859c60df13bc6f0de8a7d1318585 100644 (file)
@@ -173,10 +173,9 @@ static const lc3b_insn_info trap_insn[] = {
 };
 
 yasm_bytecode *
-yasm_lc3b__parse_insn(const unsigned long data[4], int num_operands,
-                     yasm_insn_operandhead *operands,
-                     yasm_section *cur_section,
-                     /*@null@*/ yasm_bytecode *prev_bc, unsigned long lindex)
+yasm_lc3b__parse_insn(yasm_arch *arch, const unsigned long data[4],
+                     int num_operands, yasm_insn_operandhead *operands,
+                     yasm_bytecode *prev_bc, unsigned long line)
 {
     lc3b_new_insn_data d;
     int num_info = (int)(data[1]&0xFF);
@@ -203,7 +202,7 @@ yasm_lc3b__parse_insn(const unsigned long data[4], int num_operands,
 
        /* Match each operand type and size */
        for(i = 0, op = yasm_ops_first(operands); op && i<info->num_operands &&
-           !mismatch; op = yasm_ops_next(op), i++) {
+           !mismatch; op = yasm_operand_next(op), i++) {
            /* Check operand type */
            switch ((int)(info->operands[i] & OPT_MASK)) {
                case OPT_Imm:
@@ -230,12 +229,12 @@ yasm_lc3b__parse_insn(const unsigned long data[4], int num_operands,
 
     if (!found) {
        /* Didn't find a matching one */
-       yasm__error(lindex, N_("invalid combination of opcode and operands"));
+       yasm__error(line, N_("invalid combination of opcode and operands"));
        return NULL;
     }
 
     /* Copy what we can from info */
-    d.lindex = lindex;
+    d.line = line;
     d.imm = NULL;
     d.imm_type = LC3B_IMM_NONE;
     d.origin = NULL;
@@ -254,12 +253,12 @@ yasm_lc3b__parse_insn(const unsigned long data[4], int num_operands,
     /* Go through operands and assign */
     if (operands) {
        for(i = 0, op = yasm_ops_first(operands); op && i<info->num_operands;
-           op = yasm_ops_next(op), i++) {
+           op = yasm_operand_next(op), i++) {
            switch ((int)(info->operands[i] & OPA_MASK)) {
                case OPA_None:
                    /* Throw away the operand contents */
                    if (op->type == YASM_INSN__OPERAND_IMM)
-                       yasm_expr_delete(op->data.val);
+                       yasm_expr_destroy(op->data.val);
                    break;
                case OPA_DR:
                    if (op->type != YASM_INSN__OPERAND_REG)
@@ -277,9 +276,9 @@ yasm_lc3b__parse_insn(const unsigned long data[4], int num_operands,
                            d.imm = op->data.val;
                            break;
                        case YASM_INSN__OPERAND_REG:
-                           d.imm = yasm_expr_new_ident(yasm_expr_int(
-                               yasm_intnum_new_uint(op->data.reg & 0x7)),
-                               lindex);
+                           d.imm = yasm_expr_create_ident(yasm_expr_int(
+                               yasm_intnum_create_uint(op->data.reg & 0x7)),
+                               line);
                            break;
                        default:
                            yasm_internal_error(N_("invalid operand conversion"));
@@ -291,13 +290,12 @@ yasm_lc3b__parse_insn(const unsigned long data[4], int num_operands,
 
            d.imm_type = (info->operands[i] & OPI_MASK)>>3;
            if (d.imm_type == LC3B_IMM_9_PC)
-               d.origin = yasm_symrec_define_label("$", cur_section, prev_bc,
-                                                   0, lindex);
+               d.origin = yasm_symtab_define_label2("$", prev_bc, 0, line);
        }
     }
 
     /* Create the bytecode and return it */
-    return yasm_lc3b__bc_new_insn(&d);
+    return yasm_lc3b__bc_create_insn(&d);
 }
 
 
@@ -338,13 +336,13 @@ yasm_lc3b__parse_insn(const unsigned long data[4], int num_operands,
 */
 
 void
-yasm_lc3b__parse_cpu(const char *id, unsigned long lindex)
+yasm_lc3b__parse_cpu(yasm_arch *arch, const char *id, unsigned long line)
 {
 }
 
 yasm_arch_check_id_retval
-yasm_lc3b__parse_check_id(unsigned long data[4], const char *id,
-                         unsigned long lindex)
+yasm_lc3b__parse_check_id(yasm_arch *arch, unsigned long data[4],
+                         const char *id, unsigned long line)
 {
     const char *oid = id;
     /*const char *marker;*/
index 888b25b592f9335b2d7cf358cda4b1c2dbdfd3b2..f098f64b0513e8b3719cc6c2ae6013cd0d751fe7 100644 (file)
 #include "x86arch.h"
 
 
-unsigned char yasm_x86_LTX_mode_bits = 0;
-unsigned long yasm_x86__cpu_enabled;
-unsigned int yasm_x86_amd64_machine;
+yasm_arch_module yasm_x86_LTX_arch;
 
-static int
-x86_initialize(const char *machine)
+
+static /*@only@*/ yasm_arch *
+x86_create(const char *machine)
 {
+    yasm_arch_x86 *arch_x86;
+    unsigned int amd64_machine;
+
     if (yasm__strcasecmp(machine, "x86") == 0)
-       yasm_x86_amd64_machine = 0;
+       amd64_machine = 0;
     else if (yasm__strcasecmp(machine, "amd64") == 0)
-       yasm_x86_amd64_machine = 1;
+       amd64_machine = 1;
     else
-       return 1;
+       return NULL;
 
-    yasm_x86__cpu_enabled = ~CPU_Any;
-    return 0;
+    arch_x86 = yasm_xmalloc(sizeof(yasm_arch_x86));
+
+    arch_x86->arch.module = &yasm_x86_LTX_arch;
+
+    arch_x86->cpu_enabled = ~CPU_Any;
+    arch_x86->amd64_machine = amd64_machine;
+    arch_x86->mode_bits = 0;
+
+    return (yasm_arch *)arch_x86;
 }
 
 static void
-x86_cleanup(void)
+x86_destroy(/*@only@*/ yasm_arch *arch)
+{
+    yasm_xfree(arch);
+}
+
+static const char *
+x86_get_machine(const yasm_arch *arch)
 {
+    const yasm_arch_x86 *arch_x86 = (const yasm_arch_x86 *)arch;
+    if (arch_x86->amd64_machine)
+       return "amd64";
+    else
+       return "x86";
 }
 
-int
-yasm_x86__parse_directive(const char *name, yasm_valparamhead *valparams,
-                         /*@unused@*/ /*@null@*/
-                         yasm_valparamhead *objext_valparams,
-                         /*@unused@*/ yasm_sectionhead *headp,
-                         unsigned long lindex)
+static int
+x86_set_var(yasm_arch *arch, const char *var, unsigned long val)
 {
+    yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
+    if (yasm__strcasecmp(var, "mode_bits") == 0)
+       arch_x86->mode_bits = val;
+    else
+       return 1;
+    return 0;
+}
+
+static int
+x86_parse_directive(yasm_arch *arch, const char *name,
+                   yasm_valparamhead *valparams,
+                   /*@unused@*/ /*@null@*/
+                   yasm_valparamhead *objext_valparams,
+                   /*@unused@*/ yasm_object *object, unsigned long line)
+{
+    yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
     yasm_valparam *vp;
     const yasm_intnum *intn;
     long lval;
@@ -73,16 +105,16 @@ yasm_x86__parse_directive(const char *name, yasm_valparamhead *valparams,
            (intn = yasm_expr_get_intnum(&vp->param, NULL)) != NULL &&
            (lval = yasm_intnum_get_int(intn)) &&
            (lval == 16 || lval == 32 || lval == 64))
-           yasm_x86_LTX_mode_bits = (unsigned char)lval;
+           arch_x86->mode_bits = (unsigned char)lval;
        else
-           yasm__error(lindex, N_("invalid argument to [%s]"), "BITS");
+           yasm__error(line, N_("invalid argument to [%s]"), "BITS");
        return 0;
     } else
        return 1;
 }
 
 unsigned int
-yasm_x86__get_reg_size(unsigned long reg)
+yasm_x86__get_reg_size(yasm_arch *arch, unsigned long reg)
 {
     switch ((x86_expritem_reg_size)(reg & ~0xFUL)) {
        case X86_REG8:
@@ -108,8 +140,8 @@ yasm_x86__get_reg_size(unsigned long reg)
     return 0;
 }
 
-void
-yasm_x86__reg_print(FILE *f, unsigned long reg)
+static void
+x86_reg_print(yasm_arch *arch, unsigned long reg, FILE *f)
 {
     static const char *name8[] = {"al","cl","dl","bl","ah","ch","dh","bh"};
     static const char *name8x[] = {
@@ -168,21 +200,20 @@ yasm_x86__reg_print(FILE *f, unsigned long reg)
     }
 }
 
-void
-yasm_x86__segreg_print(FILE *f, unsigned long segreg)
+static void
+x86_segreg_print(yasm_arch *arch, unsigned long segreg, FILE *f)
 {
     static const char *name[] = {"es","cs","ss","ds","fs","gs"};
     fprintf(f, "%s", name[segreg&7]);
 }
 
-void
-yasm_x86__parse_prefix(yasm_bytecode *bc, const unsigned long data[4],
-                      unsigned long lindex)
+static void
+x86_parse_prefix(yasm_arch *arch, yasm_bytecode *bc,
+                const unsigned long data[4], unsigned long line)
 {
     switch((x86_parse_insn_prefix)data[0]) {
        case X86_LOCKREP:
-           yasm_x86__bc_insn_set_lockrep_prefix(bc, data[1] & 0xff,
-                                                lindex);
+           yasm_x86__bc_insn_set_lockrep_prefix(bc, data[1] & 0xff, line);
            break;
        case X86_ADDRSIZE:
            yasm_x86__bc_insn_addrsize_override(bc, data[1]);
@@ -193,19 +224,19 @@ yasm_x86__parse_prefix(yasm_bytecode *bc, const unsigned long data[4],
     }
 }
 
-void
-yasm_x86__parse_seg_prefix(yasm_bytecode *bc, unsigned long segreg,
-                          unsigned long lindex)
+static void
+x86_parse_seg_prefix(yasm_arch *arch, yasm_bytecode *bc, unsigned long segreg,
+                    unsigned long line)
 {
     yasm_x86__ea_set_segment(yasm_x86__bc_insn_get_ea(bc),
-                            (unsigned char)(segreg>>8), lindex);
+                            (unsigned char)(segreg>>8), line);
 }
 
-void
-yasm_x86__parse_seg_override(yasm_effaddr *ea, unsigned long segreg,
-                            unsigned long lindex)
+static void
+x86_parse_seg_override(yasm_arch *arch, yasm_effaddr *ea,
+                      unsigned long segreg, unsigned long line)
 {
-    yasm_x86__ea_set_segment(ea, (unsigned char)(segreg>>8), lindex);
+    yasm_x86__ea_set_segment(ea, (unsigned char)(segreg>>8), line);
 }
 
 /* Define x86 machines -- see arch.h for details */
@@ -216,32 +247,27 @@ static yasm_arch_machine x86_machines[] = {
 };
 
 /* Define arch structure -- see arch.h for details */
-yasm_arch yasm_x86_LTX_arch = {
+yasm_arch_module yasm_x86_LTX_arch = {
     YASM_ARCH_VERSION,
     "x86 (IA-32 and derivatives), AMD64",
     "x86",
-    x86_initialize,
-    x86_cleanup,
+    x86_create,
+    x86_destroy,
+    x86_get_machine,
+    x86_set_var,
     yasm_x86__parse_cpu,
     yasm_x86__parse_check_id,
-    yasm_x86__parse_directive,
+    x86_parse_directive,
     yasm_x86__parse_insn,
-    yasm_x86__parse_prefix,
-    yasm_x86__parse_seg_prefix,
-    yasm_x86__parse_seg_override,
-    X86_BYTECODE_TYPE_MAX,
-    yasm_x86__bc_delete,
-    yasm_x86__bc_print,
-    yasm_x86__bc_resolve,
-    yasm_x86__bc_tobytes,
+    x86_parse_prefix,
+    x86_parse_seg_prefix,
+    x86_parse_seg_override,
     yasm_x86__floatnum_tobytes,
     yasm_x86__intnum_tobytes,
     yasm_x86__get_reg_size,
-    yasm_x86__reg_print,
-    yasm_x86__segreg_print,
-    yasm_x86__ea_new_expr,
-    NULL,      /* x86_ea_data_delete */
-    yasm_x86__ea_data_print,
+    x86_reg_print,
+    x86_segreg_print,
+    yasm_x86__ea_create_expr,
     x86_machines,
     "x86",
     2
index 82b05e0deca86ba655cb82e3c5dd03c1be6763ec..e15570311d75a89ff6aadbbfa43283c87c790aad 100644 (file)
 #define CPU_64     (1UL<<24)   /* Only available in 64-bit mode */
 #define CPU_Not64   (1UL<<25)  /* Not available (invalid) in 64-bit mode */
 
-/* What instructions/features are enabled? */
-extern unsigned long yasm_x86__cpu_enabled;
+typedef struct yasm_arch_x86 {
+    yasm_arch arch;    /* base structure */
 
-typedef enum {
-    X86_BC_INSN = YASM_BYTECODE_TYPE_BASE,
-    X86_BC_JMP
-} x86_bytecode_type;
-#define X86_BYTECODE_TYPE_MAX  X86_BC_JMP+1
+    /* What instructions/features are enabled? */
+    unsigned long cpu_enabled;
+    unsigned int amd64_machine;
+    unsigned char mode_bits;
+} yasm_arch_x86;
 
 /* 0-15 (low 4 bits) used for register number, stored in same data area.
  * Note 8-15 are only valid for some registers, and only in 64-bit mode.
@@ -127,13 +127,14 @@ int yasm_x86__set_rex_from_reg(unsigned char *rex, unsigned char *low3,
                               x86_rex_bit_pos rexbit);
 
 void yasm_x86__ea_set_segment(/*@null@*/ yasm_effaddr *ea,
-                             unsigned int segment, unsigned long lindex);
+                             unsigned int segment, unsigned long line);
 void yasm_x86__ea_set_disponly(yasm_effaddr *ea);
-yasm_effaddr *yasm_x86__ea_new_reg(unsigned long reg, unsigned char *rex,
-                                  unsigned int bits);
-yasm_effaddr *yasm_x86__ea_new_imm(/*@keep@*/ yasm_expr *imm,
-                                  unsigned int im_len);
-yasm_effaddr *yasm_x86__ea_new_expr(/*@keep@*/ yasm_expr *e);
+yasm_effaddr *yasm_x86__ea_create_reg(unsigned long reg, unsigned char *rex,
+                                     unsigned int bits);
+yasm_effaddr *yasm_x86__ea_create_imm
+    (/*@keep@*/ yasm_expr *imm, unsigned int im_len);
+yasm_effaddr *yasm_x86__ea_create_expr(yasm_arch *arch,
+                                      /*@keep@*/ yasm_expr *e);
 
 /*@observer@*/ /*@null@*/ yasm_effaddr *yasm_x86__bc_insn_get_ea
     (/*@null@*/ yasm_bytecode *bc);
@@ -144,14 +145,14 @@ void yasm_x86__bc_insn_addrsize_override(yasm_bytecode *bc,
                                         unsigned int addrsize);
 void yasm_x86__bc_insn_set_lockrep_prefix(yasm_bytecode *bc,
                                          unsigned int prefix,
-                                         unsigned long lindex);
+                                         unsigned long line);
 
 /* Structure with *all* inputs passed to x86_bytecode_new_insn().
  * IMPORTANT: ea_ptr and im_ptr cannot be reused or freed after calling the
  * function (it doesn't make a copy).
  */
 typedef struct x86_new_insn_data {
-    unsigned long lindex;
+    unsigned long line;
     /*@keep@*/ /*@null@*/ yasm_effaddr *ea;
     /*@null@*/ /*@dependent@*/ yasm_symrec *ea_origin;
     /*@keep@*/ /*@null@*/ yasm_expr *imm;
@@ -167,13 +168,13 @@ typedef struct x86_new_insn_data {
     unsigned char signext_imm8_op;
 } x86_new_insn_data;
 
-yasm_bytecode *yasm_x86__bc_new_insn(x86_new_insn_data *d);
+yasm_bytecode *yasm_x86__bc_create_insn(yasm_arch *arch, x86_new_insn_data *d);
 
 /* Structure with *all* inputs passed to x86_bytecode_new_jmp().
  * Pass 0 for the opcode_len if that version of the opcode doesn't exist.
  */
 typedef struct x86_new_jmp_data {
-    unsigned long lindex;
+    unsigned long line;
     /*@keep@*/ yasm_expr *target;
     /*@dependent@*/ yasm_symrec *origin;
     x86_jmp_opcode_sel op_sel;
@@ -187,18 +188,7 @@ typedef struct x86_new_jmp_data {
     unsigned char opersize;
 } x86_new_jmp_data;
 
-yasm_bytecode *yasm_x86__bc_new_jmp(x86_new_jmp_data *d);
-
-extern unsigned char yasm_x86_LTX_mode_bits;
-
-void yasm_x86__bc_delete(yasm_bytecode *bc);
-void yasm_x86__bc_print(FILE *f, int indent_level, const yasm_bytecode *bc);
-yasm_bc_resolve_flags yasm_x86__bc_resolve
-    (yasm_bytecode *bc, int save, const yasm_section *sect,
-     yasm_calc_bc_dist_func calc_bc_dist);
-int yasm_x86__bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
-                        const yasm_section *sect, void *d,
-                        yasm_output_expr_func output_expr);
+yasm_bytecode *yasm_x86__bc_create_jmp(yasm_arch *arch, x86_new_jmp_data *d);
 
 /* Check an effective address.  Returns 0 if EA was successfully determined,
  * 1 if invalid EA, or 2 if indeterminate EA.
@@ -210,44 +200,26 @@ int yasm_x86__expr_checkea
      unsigned char *v_sib, unsigned char *n_sib, unsigned char *pcrel,
      unsigned char *rex, yasm_calc_bc_dist_func calc_bc_dist);
 
-void yasm_x86__parse_cpu(const char *cpuid, unsigned long lindex);
+void yasm_x86__parse_cpu(yasm_arch *arch, const char *cpuid,
+                        unsigned long line);
 
 yasm_arch_check_id_retval yasm_x86__parse_check_id
-    (unsigned long data[2], const char *id, unsigned long lindex);
-
-int yasm_x86__parse_directive(const char *name, yasm_valparamhead *valparams,
-                             /*@null@*/ yasm_valparamhead *objext_valparams,
-                             yasm_sectionhead *headp, unsigned long lindex);
+    (yasm_arch *arch, unsigned long data[2], const char *id,
+     unsigned long line);
 
 /*@null@*/ yasm_bytecode *yasm_x86__parse_insn
-    (const unsigned long data[2], int num_operands,
-     /*@null@*/ yasm_insn_operandhead *operands, yasm_section *cur_section,
-     /*@null@*/ yasm_bytecode *prev_bc, unsigned long lindex);
-
-void yasm_x86__parse_prefix(yasm_bytecode *bc, const unsigned long data[4],
-                           unsigned long lindex);
-
-void yasm_x86__parse_seg_prefix(yasm_bytecode *bc, unsigned long segreg,
-                               unsigned long lindex);
-
-void yasm_x86__parse_seg_override(yasm_effaddr *ea, unsigned long segreg,
-                                 unsigned long lindex);
-
-int yasm_x86__floatnum_tobytes(const yasm_floatnum *flt, unsigned char *buf,
-                              size_t destsize, size_t valsize, size_t shift,
-                              int warn, unsigned long lindex);
-int yasm_x86__intnum_tobytes(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 lindex);
-
-unsigned int yasm_x86__get_reg_size(unsigned long reg);
-
-void yasm_x86__reg_print(FILE *f, unsigned long reg);
-
-void yasm_x86__segreg_print(FILE *f, unsigned long segreg);
-
-void yasm_x86__ea_data_print(FILE *f, int indent_level,
-                            const yasm_effaddr *ea);
-
+    (yasm_arch *arch, const unsigned long data[2], int num_operands,
+     /*@null@*/ yasm_insn_operandhead *operands, yasm_bytecode *prev_bc,
+     unsigned long line);
+
+int yasm_x86__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);
+int yasm_x86__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);
+
+unsigned int yasm_x86__get_reg_size(yasm_arch *arch, unsigned long reg);
 #endif
index 0fa4cd8de3178cefa5c8a458936e70a8a736908a..257c0c61d6ce51c57daec974b41d11f41743ac66 100644 (file)
@@ -34,6 +34,8 @@
 #include "x86arch.h"
 
 
+/* Effective address type */
+
 typedef struct x86_effaddr {
     yasm_effaddr ea;           /* base structure */
 
@@ -44,7 +46,7 @@ typedef struct x86_effaddr {
 
     /* How the spare (register) bits in Mod/RM are handled:
      * Even if valid_modrm=0, the spare bits are still valid (don't overwrite!)
-     * They're set in bytecode_new_insn().
+     * They're set in bytecode_create_insn().
      */
     unsigned char modrm;
     unsigned char valid_modrm; /* 1 if Mod/RM byte currently valid, 0 if not */
@@ -58,6 +60,8 @@ typedef struct x86_effaddr {
     unsigned char pcrel;       /* 1 if PC-relative transformation needed */
 } x86_effaddr;
 
+/* Bytecode types */
+
 typedef struct x86_insn {
     yasm_bytecode bc;          /* base structure */
 
@@ -123,6 +127,53 @@ typedef struct x86_jmp {
     unsigned char mode_bits;
 } x86_jmp;
 
+/* Effective address callback function prototypes */
+
+static void x86_ea_destroy(yasm_effaddr *ea);
+static void x86_ea_print(const yasm_effaddr *ea, FILE *f, int indent_level);
+
+/* Bytecode callback function prototypes */
+
+static void x86_bc_insn_destroy(yasm_bytecode *bc);
+static void x86_bc_insn_print(const yasm_bytecode *bc, FILE *f,
+                             int indent_level);
+static yasm_bc_resolve_flags x86_bc_insn_resolve
+    (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+static int x86_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp,
+                              void *d, yasm_output_expr_func output_expr,
+                              /*@null@*/ yasm_output_reloc_func output_reloc);
+
+static void x86_bc_jmp_destroy(yasm_bytecode *bc);
+static void x86_bc_jmp_print(const yasm_bytecode *bc, FILE *f,
+                            int indent_level);
+static yasm_bc_resolve_flags x86_bc_jmp_resolve
+    (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+static int x86_bc_jmp_tobytes(yasm_bytecode *bc, unsigned char **bufp,
+                             void *d, yasm_output_expr_func output_expr,
+                             /*@null@*/ yasm_output_reloc_func output_reloc);
+
+/* Effective address callback structures */
+
+static const yasm_effaddr_callback x86_ea_callback = {
+    x86_ea_destroy,
+    x86_ea_print
+};
+
+/* Bytecode callback structures */
+
+static const yasm_bytecode_callback x86_bc_callback_insn = {
+    x86_bc_insn_destroy,
+    x86_bc_insn_print,
+    x86_bc_insn_resolve,
+    x86_bc_insn_tobytes
+};
+
+static const yasm_bytecode_callback x86_bc_callback_jmp = {
+    x86_bc_jmp_destroy,
+    x86_bc_jmp_print,
+    x86_bc_jmp_resolve,
+    x86_bc_jmp_tobytes
+};
 
 int
 yasm_x86__set_rex_from_reg(unsigned char *rex, unsigned char *low3,
@@ -151,12 +202,13 @@ yasm_x86__set_rex_from_reg(unsigned char *rex, unsigned char *low3,
 
 /*@-compmempass -mustfree@*/
 yasm_bytecode *
-yasm_x86__bc_new_insn(x86_new_insn_data *d)
+yasm_x86__bc_create_insn(yasm_arch *arch, x86_new_insn_data *d)
 {
+    yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
     x86_insn *insn;
    
-    insn = (x86_insn *)yasm_bc_new_common((yasm_bytecode_type)X86_BC_INSN,
-                                         sizeof(x86_insn), d->lindex);
+    insn = (x86_insn *)yasm_bc_create_common(&x86_bc_callback_insn,
+                                            sizeof(x86_insn), d->line);
 
     insn->ea = (x86_effaddr *)d->ea;
     if (d->ea) {
@@ -166,7 +218,7 @@ yasm_x86__bc_new_insn(x86_new_insn_data *d)
     }
 
     if (d->imm) {
-       insn->imm = yasm_imm_new_expr(d->imm);
+       insn->imm = yasm_imm_create_expr(d->imm);
        insn->imm->len = d->im_len;
        insn->imm->sign = d->im_sign;
     } else
@@ -185,7 +237,7 @@ yasm_x86__bc_new_insn(x86_new_insn_data *d)
     insn->shift_op = d->shift_op;
     insn->signext_imm8_op = d->signext_imm8_op;
 
-    insn->mode_bits = yasm_x86_LTX_mode_bits;
+    insn->mode_bits = arch_x86->mode_bits;
 
     return (yasm_bytecode *)insn;
 }
@@ -193,22 +245,23 @@ yasm_x86__bc_new_insn(x86_new_insn_data *d)
 
 /*@-compmempass -mustfree@*/
 yasm_bytecode *
-yasm_x86__bc_new_jmp(x86_new_jmp_data *d)
+yasm_x86__bc_create_jmp(yasm_arch *arch, x86_new_jmp_data *d)
 {
+    yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
     x86_jmp *jmp;
 
-    jmp = (x86_jmp *) yasm_bc_new_common((yasm_bytecode_type)X86_BC_JMP,
-                                        sizeof(x86_jmp), d->lindex);
+    jmp = (x86_jmp *) yasm_bc_create_common(&x86_bc_callback_jmp,
+                                           sizeof(x86_jmp), d->line);
 
     jmp->target = d->target;
     jmp->origin = d->origin;
     jmp->op_sel = d->op_sel;
 
     if ((d->op_sel == JMP_SHORT_FORCED) && (d->near_op_len == 0))
-       yasm__error(d->lindex,
+       yasm__error(d->line,
                    N_("no SHORT form of that jump instruction exists"));
     if ((d->op_sel == JMP_NEAR_FORCED) && (d->short_op_len == 0))
-       yasm__error(d->lindex,
+       yasm__error(d->line,
                    N_("no NEAR form of that jump instruction exists"));
 
     jmp->shortop.opcode[0] = d->short_op[0];
@@ -230,7 +283,7 @@ yasm_x86__bc_new_jmp(x86_new_jmp_data *d)
     jmp->opersize = d->opersize;
     jmp->lockrep_pre = 0;
 
-    jmp->mode_bits = yasm_x86_LTX_mode_bits;
+    jmp->mode_bits = arch_x86->mode_bits;
 
     return (yasm_bytecode *)jmp;
 }
@@ -238,7 +291,7 @@ yasm_x86__bc_new_jmp(x86_new_jmp_data *d)
 
 void
 yasm_x86__ea_set_segment(yasm_effaddr *ea, unsigned int segment,
-                        unsigned long lindex)
+                        unsigned long line)
 {
     x86_effaddr *x86_ea = (x86_effaddr *)ea;
 
@@ -246,7 +299,7 @@ yasm_x86__ea_set_segment(yasm_effaddr *ea, unsigned int segment,
        return;
 
     if (segment != 0 && x86_ea->segment != 0)
-       yasm__warning(YASM_WARN_GENERAL, lindex,
+       yasm__warning(YASM_WARN_GENERAL, line,
                      N_("multiple segment overrides, using leftmost"));
 
     x86_ea->segment = (unsigned char)segment;
@@ -265,7 +318,8 @@ yasm_x86__ea_set_disponly(yasm_effaddr *ea)
 }
 
 yasm_effaddr *
-yasm_x86__ea_new_reg(unsigned long reg, unsigned char *rex, unsigned int bits)
+yasm_x86__ea_create_reg(unsigned long reg, unsigned char *rex,
+                       unsigned int bits)
 {
     x86_effaddr *x86_ea;
     unsigned char rm;
@@ -275,6 +329,7 @@ yasm_x86__ea_new_reg(unsigned long reg, unsigned char *rex, unsigned int bits)
 
     x86_ea = yasm_xmalloc(sizeof(x86_effaddr));
 
+    x86_ea->ea.callback = &x86_ea_callback;
     x86_ea->ea.disp = (yasm_expr *)NULL;
     x86_ea->ea.len = 0;
     x86_ea->ea.nosplit = 0;
@@ -291,12 +346,13 @@ yasm_x86__ea_new_reg(unsigned long reg, unsigned char *rex, unsigned int bits)
 }
 
 yasm_effaddr *
-yasm_x86__ea_new_expr(yasm_expr *e)
+yasm_x86__ea_create_expr(yasm_arch *arch, yasm_expr *e)
 {
     x86_effaddr *x86_ea;
 
     x86_ea = yasm_xmalloc(sizeof(x86_effaddr));
 
+    x86_ea->ea.callback = &x86_ea_callback;
     x86_ea->ea.disp = e;
     x86_ea->ea.len = 0;
     x86_ea->ea.nosplit = 0;
@@ -317,12 +373,13 @@ yasm_x86__ea_new_expr(yasm_expr *e)
 
 /*@-compmempass@*/
 yasm_effaddr *
-yasm_x86__ea_new_imm(yasm_expr *imm, unsigned int im_len)
+yasm_x86__ea_create_imm(yasm_expr *imm, unsigned int im_len)
 {
     x86_effaddr *x86_ea;
 
     x86_ea = yasm_xmalloc(sizeof(x86_effaddr));
 
+    x86_ea->ea.callback = &x86_ea_callback;
     x86_ea->ea.disp = imm;
     x86_ea->ea.len = (unsigned char)im_len;
     x86_ea->ea.nosplit = 0;
@@ -345,7 +402,7 @@ yasm_x86__bc_insn_get_ea(yasm_bytecode *bc)
     if (!bc)
        return NULL;
 
-    if ((x86_bytecode_type)bc->type != X86_BC_INSN)
+    if (bc->callback != &x86_bc_callback_insn)
        yasm_internal_error(N_("Trying to get EA of non-instruction"));
 
     return (yasm_effaddr *)(((x86_insn *)bc)->ea);
@@ -354,108 +411,86 @@ yasm_x86__bc_insn_get_ea(yasm_bytecode *bc)
 void
 yasm_x86__bc_insn_opersize_override(yasm_bytecode *bc, unsigned int opersize)
 {
-    x86_insn *insn;
-    x86_jmp *jmp;
-
     if (!bc)
        return;
 
-    switch ((x86_bytecode_type)bc->type) {
-       case X86_BC_INSN:
-           insn = (x86_insn *)bc;
-           insn->opersize = (unsigned char)opersize;
-           break;
-       case X86_BC_JMP:
-           jmp = (x86_jmp *)bc;
-           jmp->opersize = (unsigned char)opersize;
-           break;
-       default:
-           yasm_internal_error(
-               N_("OperSize override applied to non-instruction"));
-    }
+    if (bc->callback == &x86_bc_callback_insn) {
+       x86_insn *insn = (x86_insn *)bc;
+       insn->opersize = (unsigned char)opersize;
+    } else if (bc->callback == &x86_bc_callback_jmp) {
+       x86_jmp *jmp = (x86_jmp *)bc;
+       jmp->opersize = (unsigned char)opersize;
+    } else
+       yasm_internal_error(N_("OperSize override applied to non-instruction"));
 }
 
 void
 yasm_x86__bc_insn_addrsize_override(yasm_bytecode *bc, unsigned int addrsize)
 {
-    x86_insn *insn;
-    x86_jmp *jmp;
-
     if (!bc)
        return;
 
-    switch ((x86_bytecode_type)bc->type) {
-       case X86_BC_INSN:
-           insn = (x86_insn *)bc;
-           insn->addrsize = (unsigned char)addrsize;
-           break;
-       case X86_BC_JMP:
-           jmp = (x86_jmp *)bc;
-           jmp->addrsize = (unsigned char)addrsize;
-           break;
-       default:
-           yasm_internal_error(
-               N_("AddrSize override applied to non-instruction"));
-    }
+    if (bc->callback == &x86_bc_callback_insn) {
+       x86_insn *insn = (x86_insn *)bc;
+       insn->addrsize = (unsigned char)addrsize;
+    } else if (bc->callback == &x86_bc_callback_jmp) {
+       x86_jmp *jmp = (x86_jmp *)bc;
+       jmp->addrsize = (unsigned char)addrsize;
+    } else
+       yasm_internal_error(N_("AddrSize override applied to non-instruction"));
 }
 
 void
 yasm_x86__bc_insn_set_lockrep_prefix(yasm_bytecode *bc, unsigned int prefix,
-                                    unsigned long lindex)
+                                    unsigned long line)
 {
-    x86_insn *insn;
-    x86_jmp *jmp;
     unsigned char *lockrep_pre = (unsigned char *)NULL;
 
     if (!bc)
        return;
 
-    switch ((x86_bytecode_type)bc->type) {
-       case X86_BC_INSN:
-           insn = (x86_insn *)bc;
-           lockrep_pre = &insn->lockrep_pre;
-           break;
-       case X86_BC_JMP:
-           jmp = (x86_jmp *)bc;
-           lockrep_pre = &jmp->lockrep_pre;
-           break;
-       default:
-           yasm_internal_error(
-               N_("LockRep prefix applied to non-instruction"));
-    }
+    if (bc->callback == &x86_bc_callback_insn) {
+       x86_insn *insn = (x86_insn *)bc;
+       lockrep_pre = &insn->lockrep_pre;
+    } else if (bc->callback == &x86_bc_callback_jmp) {
+       x86_jmp *jmp = (x86_jmp *)bc;
+       lockrep_pre = &jmp->lockrep_pre;
+    } else
+       yasm_internal_error(N_("LockRep prefix applied to non-instruction"));
 
     if (*lockrep_pre != 0)
-       yasm__warning(YASM_WARN_GENERAL, lindex,
+       yasm__warning(YASM_WARN_GENERAL, line,
                      N_("multiple LOCK or REP prefixes, using leftmost"));
 
     *lockrep_pre = (unsigned char)prefix;
 }
 
-void
-yasm_x86__bc_delete(yasm_bytecode *bc)
+static void
+x86_bc_insn_destroy(yasm_bytecode *bc)
 {
-    x86_insn *insn;
-    x86_jmp *jmp;
-
-    switch ((x86_bytecode_type)bc->type) {
-       case X86_BC_INSN:
-           insn = (x86_insn *)bc;
-           if (insn->ea)
-               yasm_ea_delete((yasm_effaddr *)insn->ea);
-           if (insn->imm) {
-               yasm_expr_delete(insn->imm->val);
-               yasm_xfree(insn->imm);
-           }
-           break;
-       case X86_BC_JMP:
-           jmp = (x86_jmp *)bc;
-           yasm_expr_delete(jmp->target);
-           break;
+    x86_insn *insn = (x86_insn *)bc;
+    if (insn->ea)
+       yasm_ea_destroy((yasm_effaddr *)insn->ea);
+    if (insn->imm) {
+       yasm_expr_destroy(insn->imm->val);
+       yasm_xfree(insn->imm);
     }
 }
 
-void
-yasm_x86__ea_data_print(FILE *f, int indent_level, const yasm_effaddr *ea)
+static void
+x86_bc_jmp_destroy(yasm_bytecode *bc)
+{
+    x86_jmp *jmp = (x86_jmp *)bc;
+    yasm_expr_destroy(jmp->target);
+}
+
+static void
+x86_ea_destroy(yasm_effaddr *ea)
+{
+}
+
+static void
+x86_ea_print(const yasm_effaddr *ea, FILE *f, int indent_level)
 {
     const x86_effaddr *x86_ea = (const x86_effaddr *)ea;
     fprintf(f, "%*sSegmentOv=%02x PCRel=%u\n", indent_level, "",
@@ -468,131 +503,129 @@ yasm_x86__ea_data_print(FILE *f, int indent_level, const yasm_effaddr *ea)
            (unsigned int)x86_ea->need_sib);
 }
 
-void
-yasm_x86__bc_print(FILE *f, int indent_level, const yasm_bytecode *bc)
+static void
+x86_bc_insn_print(const yasm_bytecode *bc, FILE *f, int indent_level)
 {
-    const x86_insn *insn;
-    const x86_jmp *jmp;
-
-    switch ((x86_bytecode_type)bc->type) {
-       case X86_BC_INSN:
-           insn = (const x86_insn *)bc;
-           fprintf(f, "%*s_Instruction_\n", indent_level, "");
-           fprintf(f, "%*sEffective Address:", indent_level, "");
-           if (insn->ea) {
-               fprintf(f, "\n");
-               yasm_ea_print(f, indent_level+1, (yasm_effaddr *)insn->ea);
-           } else
-               fprintf(f, " (nil)\n");
-           fprintf(f, "%*sImmediate Value:", indent_level, "");
-           if (!insn->imm)
-               fprintf(f, " (nil)\n");
-           else {
-               indent_level++;
-               fprintf(f, "\n%*sVal=", indent_level, "");
-               if (insn->imm->val)
-                   yasm_expr_print(f, insn->imm->val);
-               else
-                   fprintf(f, "(nil-SHOULDN'T HAPPEN)");
-               fprintf(f, "\n");
-               fprintf(f, "%*sLen=%u, Sign=%u\n", indent_level, "",
-                       (unsigned int)insn->imm->len,
-                       (unsigned int)insn->imm->sign);
-               indent_level--;
-           }
-           fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n", indent_level,
-                   "", (unsigned int)insn->opcode[0],
-                   (unsigned int)insn->opcode[1],
-                   (unsigned int)insn->opcode[2],
-                   (unsigned int)insn->opcode_len);
-           fprintf(f,
-                   "%*sAddrSize=%u OperSize=%u LockRepPre=%02x REX=%03o\n",
-                   indent_level, "",
-                   (unsigned int)insn->addrsize,
-                   (unsigned int)insn->opersize,
-                   (unsigned int)insn->lockrep_pre,
-                   (unsigned int)insn->rex);
-           fprintf(f, "%*sShiftOp=%u BITS=%u\n", indent_level, "",
-                   (unsigned int)insn->shift_op,
-                   (unsigned int)insn->mode_bits);
+    const x86_insn *insn = (const x86_insn *)bc;
+
+    fprintf(f, "%*s_Instruction_\n", indent_level, "");
+    fprintf(f, "%*sEffective Address:", indent_level, "");
+    if (insn->ea) {
+       fprintf(f, "\n");
+       yasm_ea_print((yasm_effaddr *)insn->ea, f, indent_level+1);
+    } else
+       fprintf(f, " (nil)\n");
+    fprintf(f, "%*sImmediate Value:", indent_level, "");
+    if (!insn->imm)
+       fprintf(f, " (nil)\n");
+    else {
+       indent_level++;
+       fprintf(f, "\n%*sVal=", indent_level, "");
+       if (insn->imm->val)
+           yasm_expr_print(insn->imm->val, f);
+       else
+           fprintf(f, "(nil-SHOULDN'T HAPPEN)");
+       fprintf(f, "\n");
+       fprintf(f, "%*sLen=%u, Sign=%u\n", indent_level, "",
+               (unsigned int)insn->imm->len,
+               (unsigned int)insn->imm->sign);
+       indent_level--;
+    }
+    fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n", indent_level,
+           "", (unsigned int)insn->opcode[0],
+           (unsigned int)insn->opcode[1],
+           (unsigned int)insn->opcode[2],
+           (unsigned int)insn->opcode_len);
+    fprintf(f,
+           "%*sAddrSize=%u OperSize=%u LockRepPre=%02x REX=%03o\n",
+           indent_level, "",
+           (unsigned int)insn->addrsize,
+           (unsigned int)insn->opersize,
+           (unsigned int)insn->lockrep_pre,
+           (unsigned int)insn->rex);
+    fprintf(f, "%*sShiftOp=%u BITS=%u\n", indent_level, "",
+           (unsigned int)insn->shift_op,
+           (unsigned int)insn->mode_bits);
+}
+
+static void
+x86_bc_jmp_print(const yasm_bytecode *bc, FILE *f, int indent_level)
+{
+    const x86_jmp *jmp = (const x86_jmp *)bc;
+
+    fprintf(f, "%*s_Jump_\n", indent_level, "");
+    fprintf(f, "%*sTarget=", indent_level, "");
+    yasm_expr_print(jmp->target, f);
+    fprintf(f, "%*sOrigin=\n", indent_level, "");
+    yasm_symrec_print(jmp->origin, f, indent_level+1);
+    fprintf(f, "\n%*sShort Form:\n", indent_level, "");
+    if (jmp->shortop.opcode_len == 0)
+       fprintf(f, "%*sNone\n", indent_level+1, "");
+    else
+       fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n",
+               indent_level+1, "",
+               (unsigned int)jmp->shortop.opcode[0],
+               (unsigned int)jmp->shortop.opcode[1],
+               (unsigned int)jmp->shortop.opcode[2],
+               (unsigned int)jmp->shortop.opcode_len);
+    fprintf(f, "%*sNear Form:\n", indent_level, "");
+    if (jmp->nearop.opcode_len == 0)
+       fprintf(f, "%*sNone\n", indent_level+1, "");
+    else
+       fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n",
+               indent_level+1, "",
+               (unsigned int)jmp->nearop.opcode[0],
+               (unsigned int)jmp->nearop.opcode[1],
+               (unsigned int)jmp->nearop.opcode[2],
+               (unsigned int)jmp->nearop.opcode_len);
+    fprintf(f, "%*sFar Form:\n", indent_level, "");
+    if (jmp->farop.opcode_len == 0)
+       fprintf(f, "%*sNone\n", indent_level+1, "");
+    else
+       fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n",
+               indent_level+1, "",
+               (unsigned int)jmp->farop.opcode[0],
+               (unsigned int)jmp->farop.opcode[1],
+               (unsigned int)jmp->farop.opcode[2],
+               (unsigned int)jmp->farop.opcode_len);
+    fprintf(f, "%*sOpSel=", indent_level, "");
+    switch (jmp->op_sel) {
+       case JMP_NONE:
+           fprintf(f, "None");
            break;
-       case X86_BC_JMP:
-           jmp = (const x86_jmp *)bc;
-           fprintf(f, "%*s_Jump_\n", indent_level, "");
-           fprintf(f, "%*sTarget=", indent_level, "");
-           yasm_expr_print(f, jmp->target);
-           fprintf(f, "%*sOrigin=\n", indent_level, "");
-           yasm_symrec_print(f, indent_level+1, jmp->origin);
-           fprintf(f, "\n%*sShort Form:\n", indent_level, "");
-           if (jmp->shortop.opcode_len == 0)
-               fprintf(f, "%*sNone\n", indent_level+1, "");
-           else
-               fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n",
-                       indent_level+1, "",
-                       (unsigned int)jmp->shortop.opcode[0],
-                       (unsigned int)jmp->shortop.opcode[1],
-                       (unsigned int)jmp->shortop.opcode[2],
-                       (unsigned int)jmp->shortop.opcode_len);
-           fprintf(f, "%*sNear Form:\n", indent_level, "");
-           if (jmp->nearop.opcode_len == 0)
-               fprintf(f, "%*sNone\n", indent_level+1, "");
-           else
-               fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n",
-                       indent_level+1, "",
-                       (unsigned int)jmp->nearop.opcode[0],
-                       (unsigned int)jmp->nearop.opcode[1],
-                       (unsigned int)jmp->nearop.opcode[2],
-                       (unsigned int)jmp->nearop.opcode_len);
-           fprintf(f, "%*sFar Form:\n", indent_level, "");
-           if (jmp->farop.opcode_len == 0)
-               fprintf(f, "%*sNone\n", indent_level+1, "");
-           else
-               fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n",
-                       indent_level+1, "",
-                       (unsigned int)jmp->farop.opcode[0],
-                       (unsigned int)jmp->farop.opcode[1],
-                       (unsigned int)jmp->farop.opcode[2],
-                       (unsigned int)jmp->farop.opcode_len);
-           fprintf(f, "%*sOpSel=", indent_level, "");
-           switch (jmp->op_sel) {
-               case JMP_NONE:
-                   fprintf(f, "None");
-                   break;
-               case JMP_SHORT:
-                   fprintf(f, "Short");
-                   break;
-               case JMP_NEAR:
-                   fprintf(f, "Near");
-                   break;
-               case JMP_SHORT_FORCED:
-                   fprintf(f, "Forced Short");
-                   break;
-               case JMP_NEAR_FORCED:
-                   fprintf(f, "Forced Near");
-                   break;
-               case JMP_FAR:
-                   fprintf(f, "Far");
-                   break;
-               default:
-                   fprintf(f, "UNKNOWN!!");
-                   break;
-           }
-           fprintf(f, "\n%*sAddrSize=%u OperSize=%u LockRepPre=%02x\n",
-                   indent_level, "",
-                   (unsigned int)jmp->addrsize,
-                   (unsigned int)jmp->opersize,
-                   (unsigned int)jmp->lockrep_pre);
-           fprintf(f, "%*sBITS=%u\n", indent_level, "",
-                   (unsigned int)jmp->mode_bits);
+       case JMP_SHORT:
+           fprintf(f, "Short");
+           break;
+       case JMP_NEAR:
+           fprintf(f, "Near");
+           break;
+       case JMP_SHORT_FORCED:
+           fprintf(f, "Forced Short");
+           break;
+       case JMP_NEAR_FORCED:
+           fprintf(f, "Forced Near");
+           break;
+       case JMP_FAR:
+           fprintf(f, "Far");
+           break;
+       default:
+           fprintf(f, "UNKNOWN!!");
            break;
     }
+    fprintf(f, "\n%*sAddrSize=%u OperSize=%u LockRepPre=%02x\n",
+           indent_level, "",
+           (unsigned int)jmp->addrsize,
+           (unsigned int)jmp->opersize,
+           (unsigned int)jmp->lockrep_pre);
+    fprintf(f, "%*sBITS=%u\n", indent_level, "",
+           (unsigned int)jmp->mode_bits);
 }
 
 static yasm_bc_resolve_flags
-x86_bc_resolve_insn(x86_insn *insn, unsigned long *len, int save,
-                   const yasm_section *sect,
+x86_bc_insn_resolve(yasm_bytecode *bc, int save,
                    yasm_calc_bc_dist_func calc_bc_dist)
 {
+    x86_insn *insn = (x86_insn *)bc;
     /*@null@*/ yasm_expr *temp;
     x86_effaddr *x86_ea = insn->ea;
     yasm_effaddr *ea = &x86_ea->ea;
@@ -619,15 +652,15 @@ x86_bc_resolve_insn(x86_insn *insn, unsigned long *len, int save,
                    &eat.valid_sib, &eat.need_sib, &eat.pcrel, &insn->rex,
                    calc_bc_dist)) {
                case 1:
-                   yasm_expr_delete(temp);
+                   yasm_expr_destroy(temp);
                    /* failed, don't bother checking rest of insn */
                    return YASM_BC_RESOLVE_UNKNOWN_LEN|YASM_BC_RESOLVE_ERROR;
                case 2:
-                   yasm_expr_delete(temp);
+                   yasm_expr_destroy(temp);
                    /* failed, don't bother checking rest of insn */
                    return YASM_BC_RESOLVE_UNKNOWN_LEN;
                default:
-                   yasm_expr_delete(temp);
+                   yasm_expr_destroy(temp);
                    /* okay */
                    break;
            }
@@ -645,15 +678,15 @@ x86_bc_resolve_insn(x86_insn *insn, unsigned long *len, int save,
                *x86_ea = eat;  /* structure copy */
                ea->len = displen;
                if (displen == 0 && ea->disp) {
-                   yasm_expr_delete(ea->disp);
+                   yasm_expr_destroy(ea->disp);
                    ea->disp = NULL;
                }
            }
        }
 
        /* Compute length of ea and add to total */
-       *len += eat.need_modrm + (eat.need_sib ? 1:0) + displen;
-       *len += (eat.segment != 0) ? 1 : 0;
+       bc->len += eat.need_modrm + (eat.need_sib ? 1:0) + displen;
+       bc->len += (eat.segment != 0) ? 1 : 0;
     }
 
     if (imm) {
@@ -673,13 +706,13 @@ x86_bc_resolve_insn(x86_insn *insn, unsigned long *len, int save,
                    /* We can use the ,1 form: subtract out the imm len
                     * (as we add it back in below).
                     */
-                   *len -= imm->len;
+                   bc->len -= imm->len;
 
                    if (save) {
                        /* Make the ,1 form permanent. */
                        insn->opcode[0] = insn->opcode[1];
                        /* Delete imm, as it's not needed. */
-                       yasm_expr_delete(imm->val);
+                       yasm_expr_destroy(imm->val);
                        yasm_xfree(imm);
                        insn->imm = (yasm_immval *)NULL;
                    }
@@ -691,33 +724,33 @@ x86_bc_resolve_insn(x86_insn *insn, unsigned long *len, int save,
                    insn->shift_op = 0;
            }
 
-           yasm_expr_delete(temp);
+           yasm_expr_destroy(temp);
        }
 
-       *len += immlen;
+       bc->len += immlen;
     }
 
-    *len += insn->opcode_len;
-    *len += (insn->addrsize != 0 && insn->addrsize != insn->mode_bits) ? 1:0;
+    bc->len += insn->opcode_len;
+    bc->len += (insn->addrsize != 0 && insn->addrsize != insn->mode_bits) ? 1:0;
     if (insn->opersize != 0 &&
        ((insn->mode_bits != 64 && insn->opersize != insn->mode_bits) ||
         (insn->mode_bits == 64 && insn->opersize == 16)))
-       (*len)++;
-    *len += (insn->lockrep_pre != 0) ? 1:0;
+       bc->len++;
+    bc->len += (insn->lockrep_pre != 0) ? 1:0;
     if (insn->rex != 0xff &&
        (insn->rex != 0 ||
         (insn->mode_bits == 64 && insn->opersize == 64 &&
          insn->def_opersize_64 != 64)))
-       (*len)++;
+       bc->len++;
 
     return retval;
 }
 
 static yasm_bc_resolve_flags
-x86_bc_resolve_jmp(x86_jmp *jmp, unsigned long *len, int save,
-                  const yasm_bytecode *bc, const yasm_section *sect,
+x86_bc_jmp_resolve(yasm_bytecode *bc, int save,
                   yasm_calc_bc_dist_func calc_bc_dist)
 {
+    x86_jmp *jmp = (x86_jmp *)bc;
     yasm_bc_resolve_flags retval = YASM_BC_RESOLVE_MIN_LEN;
     /*@null@*/ yasm_expr *temp;
     /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
@@ -737,18 +770,18 @@ x86_bc_resolve_jmp(x86_jmp *jmp, unsigned long *len, int save,
            jrtype = JMP_SHORT;
            if (save) {
                temp = yasm_expr_copy(jmp->target);
-               temp = yasm_expr_new(YASM_EXPR_SUB, yasm_expr_expr(temp),
-                                    yasm_expr_sym(jmp->origin), bc->line);
+               temp = yasm_expr_create(YASM_EXPR_SUB, yasm_expr_expr(temp),
+                                       yasm_expr_sym(jmp->origin), bc->line);
                num = yasm_expr_get_intnum(&temp, calc_bc_dist);
                if (!num) {
                    yasm__error(bc->line,
                        N_("short jump target external or out of segment"));
-                   yasm_expr_delete(temp);
+                   yasm_expr_destroy(temp);
                    return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
                } else {
                    rel = yasm_intnum_get_int(num);
                    rel -= jmp->shortop.opcode_len+1;
-                   yasm_expr_delete(temp);
+                   yasm_expr_destroy(temp);
                    /* does a short form exist? */
                    if (jmp->shortop.opcode_len == 0) {
                        yasm__error(bc->line, N_("short jump does not exist"));
@@ -793,8 +826,8 @@ x86_bc_resolve_jmp(x86_jmp *jmp, unsigned long *len, int save,
             * requires offset to be set BEFORE calling calc_len in order for
             * this test to be valid.
             */
-           temp = yasm_expr_new(YASM_EXPR_SUB, yasm_expr_expr(temp),
-                                yasm_expr_sym(jmp->origin), bc->line);
+           temp = yasm_expr_create(YASM_EXPR_SUB, yasm_expr_expr(temp),
+                                   yasm_expr_sym(jmp->origin), bc->line);
            num = yasm_expr_get_intnum(&temp, calc_bc_dist);
            if (num) {
                rel = yasm_intnum_get_int(num);
@@ -844,7 +877,7 @@ x86_bc_resolve_jmp(x86_jmp *jmp, unsigned long *len, int save,
                    jrtype = JMP_SHORT;
                }
            }
-           yasm_expr_delete(temp);
+           yasm_expr_destroy(temp);
            break;
     }
 
@@ -855,7 +888,7 @@ x86_bc_resolve_jmp(x86_jmp *jmp, unsigned long *len, int save,
            if (jmp->shortop.opcode_len == 0)
                return YASM_BC_RESOLVE_UNKNOWN_LEN; /* size not available */
 
-           *len += jmp->shortop.opcode_len + 1;
+           bc->len += jmp->shortop.opcode_len + 1;
            break;
        case JMP_NEAR:
            if (save)
@@ -863,8 +896,8 @@ x86_bc_resolve_jmp(x86_jmp *jmp, unsigned long *len, int save,
            if (jmp->nearop.opcode_len == 0)
                return YASM_BC_RESOLVE_UNKNOWN_LEN; /* size not available */
 
-           *len += jmp->nearop.opcode_len;
-           *len += (opersize == 16) ? 2 : 4;
+           bc->len += jmp->nearop.opcode_len;
+           bc->len += (opersize == 16) ? 2 : 4;
            break;
        case JMP_FAR:
            if (save)
@@ -872,44 +905,26 @@ x86_bc_resolve_jmp(x86_jmp *jmp, unsigned long *len, int save,
            if (jmp->farop.opcode_len == 0)
                return YASM_BC_RESOLVE_UNKNOWN_LEN; /* size not available */
 
-           *len += jmp->farop.opcode_len;
-           *len += 2;  /* segment */
-           *len += (opersize == 16) ? 2 : 4;
+           bc->len += jmp->farop.opcode_len;
+           bc->len += 2;       /* segment */
+           bc->len += (opersize == 16) ? 2 : 4;
            break;
        default:
            yasm_internal_error(N_("unknown jump type"));
     }
-    *len += (jmp->addrsize != 0 && jmp->addrsize != jmp->mode_bits) ? 1:0;
-    *len += (jmp->opersize != 0 && jmp->opersize != jmp->mode_bits) ? 1:0;
-    *len += (jmp->lockrep_pre != 0) ? 1:0;
+    bc->len += (jmp->addrsize != 0 && jmp->addrsize != jmp->mode_bits) ? 1:0;
+    bc->len += (jmp->opersize != 0 && jmp->opersize != jmp->mode_bits) ? 1:0;
+    bc->len += (jmp->lockrep_pre != 0) ? 1:0;
 
     return retval;
 }
 
-yasm_bc_resolve_flags
-yasm_x86__bc_resolve(yasm_bytecode *bc, int save, const yasm_section *sect,
-                    yasm_calc_bc_dist_func calc_bc_dist)
-{
-    switch ((x86_bytecode_type)bc->type) {
-       case X86_BC_INSN:
-           return x86_bc_resolve_insn((x86_insn *)bc, &bc->len, save, sect,
-                                      calc_bc_dist);
-       case X86_BC_JMP:
-           return x86_bc_resolve_jmp((x86_jmp *)bc, &bc->len, save, bc, sect,
-                                     calc_bc_dist);
-       default:
-           break;
-    }
-    yasm_internal_error(N_("Didn't handle bytecode type in x86 arch"));
-    /*@notreached@*/
-    return YASM_BC_RESOLVE_UNKNOWN_LEN;
-}
-
 static int
-x86_bc_tobytes_insn(x86_insn *insn, unsigned char **bufp,
-                   const yasm_section *sect, yasm_bytecode *bc, void *d,
-                   yasm_output_expr_func output_expr)
+x86_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+                   yasm_output_expr_func output_expr,
+                   /*@unused@*/ yasm_output_reloc_func output_reloc)
 {
+    x86_insn *insn = (x86_insn *)bc;
     /*@null@*/ x86_effaddr *x86_ea = insn->ea;
     /*@null@*/ yasm_effaddr *ea = &x86_ea->ea;
     yasm_immval *imm = insn->imm;
@@ -981,18 +996,19 @@ x86_bc_tobytes_insn(x86_insn *insn, unsigned char **bufp,
            if (ea->disp) {
                if (eat.pcrel) {
                    ea->disp =
-                       yasm_expr_new(YASM_EXPR_SUB, yasm_expr_expr(ea->disp),
-                             yasm_expr_sym(eat.origin), bc->line);
+                       yasm_expr_create(YASM_EXPR_SUB,
+                                        yasm_expr_expr(ea->disp),
+                                        yasm_expr_sym(eat.origin), bc->line);
                    if (output_expr(&ea->disp, *bufp, ea->len,
                                    (size_t)(ea->len*8), 0,
-                                   (unsigned long)(*bufp-bufp_orig), sect, bc,
-                                   1, 1, d))
+                                   (unsigned long)(*bufp-bufp_orig), bc, 1, 1,
+                                   d))
                        return 1;
                } else {
                    if (output_expr(&ea->disp, *bufp, ea->len,
                                    (size_t)(ea->len*8), 0,
-                                   (unsigned long)(*bufp-bufp_orig), sect, bc,
-                                   0, 1, d))
+                                   (unsigned long)(*bufp-bufp_orig), bc, 0, 1,
+                                   d))
                        return 1;
                }
                *bufp += ea->len;
@@ -1009,7 +1025,7 @@ x86_bc_tobytes_insn(x86_insn *insn, unsigned char **bufp,
     /* Immediate (if required) */
     if (imm && imm->val) {
        if (output_expr(&imm->val, *bufp, imm->len, (size_t)(imm->len*8), 0,
-                       (unsigned long)(*bufp-bufp_orig), sect, bc, 0, 1, d))
+                       (unsigned long)(*bufp-bufp_orig), bc, 0, 1, d))
            return 1;
        *bufp += imm->len;
     }
@@ -1018,10 +1034,11 @@ x86_bc_tobytes_insn(x86_insn *insn, unsigned char **bufp,
 }
 
 static int
-x86_bc_tobytes_jmp(x86_jmp *jmp, unsigned char **bufp,
-                  const yasm_section *sect, yasm_bytecode *bc,
-                  void *d, yasm_output_expr_func output_expr)
+x86_bc_jmp_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+                  yasm_output_expr_func output_expr,
+                  /*@unused@*/ yasm_output_reloc_func output_reloc)
 {
+    x86_jmp *jmp = (x86_jmp *)bc;
     unsigned char opersize;
     unsigned int i;
     unsigned char *bufp_orig = *bufp;
@@ -1053,11 +1070,10 @@ x86_bc_tobytes_jmp(x86_jmp *jmp, unsigned char **bufp,
 
            /* Relative displacement */
            jmp->target =
-               yasm_expr_new(YASM_EXPR_SUB, yasm_expr_expr(jmp->target),
-                             yasm_expr_sym(jmp->origin), bc->line);
+               yasm_expr_create(YASM_EXPR_SUB, yasm_expr_expr(jmp->target),
+                                yasm_expr_sym(jmp->origin), bc->line);
            if (output_expr(&jmp->target, *bufp, 1, 8, 0,
-                           (unsigned long)(*bufp-bufp_orig), sect, bc, 1, 1,
-                           d))
+                           (unsigned long)(*bufp-bufp_orig), bc, 1, 1, d))
                return 1;
            *bufp += 1;
            break;
@@ -1075,12 +1091,11 @@ x86_bc_tobytes_jmp(x86_jmp *jmp, unsigned char **bufp,
 
            /* Relative displacement */
            jmp->target =
-               yasm_expr_new(YASM_EXPR_SUB, yasm_expr_expr(jmp->target),
-                             yasm_expr_sym(jmp->origin), bc->line);
+               yasm_expr_create(YASM_EXPR_SUB, yasm_expr_expr(jmp->target),
+                                yasm_expr_sym(jmp->origin), bc->line);
            i = (opersize == 16) ? 2 : 4;
            if (output_expr(&jmp->target, *bufp, i, i*8, 0,
-                           (unsigned long)(*bufp-bufp_orig), sect, bc, 1, 1,
-                           d))
+                           (unsigned long)(*bufp-bufp_orig), bc, 1, 1, d))
                return 1;
            *bufp += i;
            break;
@@ -1102,13 +1117,11 @@ x86_bc_tobytes_jmp(x86_jmp *jmp, unsigned char **bufp,
                yasm_internal_error(N_("could not extract segment for far jump"));
            i = (opersize == 16) ? 2 : 4;
            if (output_expr(&jmp->target, *bufp, i, i*8, 0,
-                           (unsigned long)(*bufp-bufp_orig), sect, bc, 0, 1,
-                           d))
+                           (unsigned long)(*bufp-bufp_orig), bc, 0, 1, d))
                return 1;
            *bufp += i;
            if (output_expr(&targetseg, *bufp, 2, 2*8, 0,
-                           (unsigned long)(*bufp-bufp_orig), sect, bc, 0, 1,
-                           d))
+                           (unsigned long)(*bufp-bufp_orig), bc, 0, 1, d))
                return 1;
            *bufp += 2;
 
@@ -1120,28 +1133,10 @@ x86_bc_tobytes_jmp(x86_jmp *jmp, unsigned char **bufp,
 }
 
 int
-yasm_x86__bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
-                    const yasm_section *sect, void *d,
-                    yasm_output_expr_func output_expr)
-{
-    switch ((x86_bytecode_type)bc->type) {
-       case X86_BC_INSN:
-           return x86_bc_tobytes_insn((x86_insn *)bc, bufp, sect, bc, d,
-                                      output_expr);
-       case X86_BC_JMP:
-           return x86_bc_tobytes_jmp((x86_jmp *)bc, bufp, sect, bc, d,
-                                     output_expr);
-       default:
-           break;
-    }
-    return 0;
-}
-
-int
-yasm_x86__intnum_tobytes(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 lindex)
+yasm_x86__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)
 {
     if (rel) {
        yasm_intnum *relnum, *delta;
@@ -1149,16 +1144,16 @@ yasm_x86__intnum_tobytes(const yasm_intnum *intn, unsigned char *buf,
            yasm_internal_error(
                N_("tried to do PC-relative offset from invalid sized value"));
        relnum = yasm_intnum_copy(intn);
-       delta = yasm_intnum_new_uint(bc->len);
-       yasm_intnum_calc(relnum, YASM_EXPR_SUB, delta, lindex);
-       yasm_intnum_delete(delta);
+       delta = yasm_intnum_create_uint(bc->len);
+       yasm_intnum_calc(relnum, YASM_EXPR_SUB, delta, line);
+       yasm_intnum_destroy(delta);
        yasm_intnum_get_sized(relnum, buf, destsize, valsize, shift, 0, warn,
-                             lindex);
-       yasm_intnum_delete(relnum);
+                             line);
+       yasm_intnum_destroy(relnum);
     } else {
        /* Write value out. */
        yasm_intnum_get_sized(intn, buf, destsize, valsize, shift, 0, warn,
-                             lindex);
+                             line);
     }
     return 0;
 }
index 30a9ec212bf43a543ebf14934180f7be7495e4a1..aafcd5f703b78037cb2fc8c6bc4ecb5e0c3e3d80 100644 (file)
@@ -71,7 +71,7 @@ x86_expr_checkea_get_reg3264(yasm_expr__item *ei, int *regnum,
 
     /* overwrite with 0 to eliminate register from displacement expr */
     ei->type = YASM_EXPR_INT;
-    ei->data.intn = yasm_intnum_new_uint(0);
+    ei->data.intn = yasm_intnum_create_uint(0);
 
     /* we're okay */
     return &data->regs[*regnum];
@@ -111,7 +111,7 @@ x86_expr_checkea_get_reg16(yasm_expr__item *ei, int *regnum, void *d)
 
     /* overwrite with 0 to eliminate register from displacement expr */
     ei->type = YASM_EXPR_INT;
-    ei->data.intn = yasm_intnum_new_uint(0);
+    ei->data.intn = yasm_intnum_create_uint(0);
 
     /* we're okay */
     return reg16[*regnum];
@@ -231,7 +231,7 @@ x86_expr_checkea_distcheck_reg(yasm_expr **ep, unsigned int bits)
        /* Replace e with expanded reg expn */
        ne = e->terms[havereg_expr].data.expn;
        e->terms[havereg_expr].type = YASM_EXPR_NONE;   /* don't delete it! */
-       yasm_expr_delete(e);                        /* but everything else */
+       yasm_expr_destroy(e);                       /* but everything else */
        e = ne;
        /*@-onlytrans@*/
        *ep = ne;
@@ -299,7 +299,7 @@ x86_expr_checkea_getregusage(yasm_expr **ep, /*@null@*/ int *indexreg,
                e->op = YASM_EXPR_IDENT;
                e->numterms = 1;
                /* Delete the intnum created by get_reg(). */
-               yasm_intnum_delete(e->terms[1].data.intn);
+               yasm_intnum_destroy(e->terms[1].data.intn);
            }
            break;
        case YASM_EXPR_ADD:
@@ -475,7 +475,7 @@ x86_checkea_calc_displen(yasm_expr **ep, unsigned int wordsize, int noreg,
                 * Don't do this if we came from dispreq check above, so
                 * check *displen.
                 */
-               yasm_expr_delete(e);
+               yasm_expr_destroy(e);
                *ep = (yasm_expr *)NULL;
            } else if (dispval >= -128 && dispval <= 127) {
                /* It fits into a signed byte */
@@ -966,16 +966,15 @@ yasm_x86__expr_checkea(yasm_expr **ep, unsigned char *addrsize,
 }
 
 int
-yasm_x86__floatnum_tobytes(const yasm_floatnum *flt, unsigned char *buf,
-                          size_t destsize, size_t valsize, size_t shift,
-                          int warn, unsigned long lindex)
+yasm_x86__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)
 {
     if (!yasm_floatnum_check_size(flt, valsize)) {
-       yasm__error(lindex, N_("invalid floating point constant size"));
+       yasm__error(line, N_("invalid floating point constant size"));
        return 1;
     }
 
-    yasm_floatnum_get_sized(flt, buf, destsize, valsize, shift, 0, warn,
-                           lindex);
+    yasm_floatnum_get_sized(flt, buf, destsize, valsize, shift, 0, warn, line);
     return 0;
 }
index c0acdc068c6d0b2ecd0c4f79c050fb8a855a3018..1724c5a5bc58767e2a473a1e3ef6a9be582e1c90 100644 (file)
@@ -1518,11 +1518,11 @@ static const x86_insn_info xbts_insn[] = {
 
 
 static yasm_bytecode *
-x86_new_jmp(const unsigned long data[4], int num_operands,
+x86_new_jmp(yasm_arch *arch, const unsigned long data[4], int num_operands,
            yasm_insn_operandhead *operands, x86_insn_info *jinfo,
-           yasm_section *cur_section, /*@null@*/ yasm_bytecode *prev_bc,
-           unsigned long lindex)
+           yasm_bytecode *prev_bc, unsigned long line)
 {
+    yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
     x86_new_jmp_data d;
     int num_info = (int)(data[1]&0xFF);
     x86_insn_info *info = (x86_insn_info *)data[0];
@@ -1530,7 +1530,7 @@ x86_new_jmp(const unsigned long data[4], int num_operands,
     yasm_insn_operand *op;
     static const unsigned char size_lookup[] = {0, 8, 16, 32, 64, 80, 128, 0};
 
-    d.lindex = lindex;
+    d.line = line;
 
     /* We know the target is in operand 0, but sanity check for Imm. */
     op = yasm_ops_first(operands);
@@ -1539,14 +1539,14 @@ x86_new_jmp(const unsigned long data[4], int num_operands,
 
     /* Far target needs to become "seg imm:imm". */
     if ((jinfo->operands[0] & OPTM_MASK) == OPTM_Far)
-       d.target = yasm_expr_new_tree(
-           yasm_expr_new_branch(YASM_EXPR_SEG, op->data.val, lindex),
-           YASM_EXPR_SEGOFF, yasm_expr_copy(op->data.val), lindex);
+       d.target = yasm_expr_create_tree(
+           yasm_expr_create_branch(YASM_EXPR_SEG, op->data.val, line),
+           YASM_EXPR_SEGOFF, yasm_expr_copy(op->data.val), line);
     else
        d.target = op->data.val;
 
     /* Need to save jump origin for relative jumps. */
-    d.origin = yasm_symrec_define_label("$", cur_section, prev_bc, 0, lindex);
+    d.origin = yasm_symtab_define_label2("$", prev_bc, 0, line);
 
     /* Initially assume no far opcode is available. */
     d.far_op_len = 0;
@@ -1594,13 +1594,13 @@ x86_new_jmp(const unsigned long data[4], int num_operands,
         num_info--, info++) {
        unsigned long cpu = info->cpu | data[2];
 
-       if ((cpu & CPU_64) && yasm_x86_LTX_mode_bits != 64)
+       if ((cpu & CPU_64) && arch_x86->mode_bits != 64)
            continue;
-       if ((cpu & CPU_Not64) && yasm_x86_LTX_mode_bits == 64)
+       if ((cpu & CPU_Not64) && arch_x86->mode_bits == 64)
            continue;
        cpu &= ~(CPU_64 | CPU_Not64);
 
-       if ((yasm_x86__cpu_enabled & cpu) != cpu)
+       if ((arch_x86->cpu_enabled & cpu) != cpu)
            continue;
 
        if (info->num_operands == 0)
@@ -1636,15 +1636,15 @@ x86_new_jmp(const unsigned long data[4], int num_operands,
        }
     }
 
-    return yasm_x86__bc_new_jmp(&d);
+    return yasm_x86__bc_create_jmp(arch, &d);
 }
 
 yasm_bytecode *
-yasm_x86__parse_insn(const unsigned long data[4], int num_operands,
-                    yasm_insn_operandhead *operands,
-                    yasm_section *cur_section,
-                    /*@null@*/ yasm_bytecode *prev_bc, unsigned long lindex)
+yasm_x86__parse_insn(yasm_arch *arch, const unsigned long data[4],
+                    int num_operands, yasm_insn_operandhead *operands,
+                    yasm_bytecode *prev_bc, unsigned long line)
 {
+    yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
     x86_new_insn_data d;
     int num_info = (int)(data[1]&0xFF);
     x86_insn_info *info = (x86_insn_info *)data[0];
@@ -1665,13 +1665,13 @@ yasm_x86__parse_insn(const unsigned long data[4], int num_operands,
        /* Match CPU */
        cpu = info->cpu | data[2];
 
-       if ((cpu & CPU_64) && yasm_x86_LTX_mode_bits != 64)
+       if ((cpu & CPU_64) && arch_x86->mode_bits != 64)
            continue;
-       if ((cpu & CPU_Not64) && yasm_x86_LTX_mode_bits == 64)
+       if ((cpu & CPU_Not64) && arch_x86->mode_bits == 64)
            continue;
        cpu &= ~(CPU_64 | CPU_Not64);
 
-       if ((yasm_x86__cpu_enabled & cpu) != cpu)
+       if ((arch_x86->cpu_enabled & cpu) != cpu)
            continue;
 
        /* Match # of operands */
@@ -1685,7 +1685,7 @@ yasm_x86__parse_insn(const unsigned long data[4], int num_operands,
 
        /* Match each operand type and size */
        for(i = 0, op = yasm_ops_first(operands); op && i<info->num_operands &&
-           !mismatch; op = yasm_ops_next(op), i++) {
+           !mismatch; op = yasm_operand_next(op), i++) {
            /* Check operand type */
            switch ((int)(info->operands[i] & OPT_MASK)) {
                case OPT_Imm:
@@ -1851,7 +1851,7 @@ yasm_x86__parse_insn(const unsigned long data[4], int num_operands,
            size = size_lookup[(info->operands[i] & OPS_MASK)>>OPS_SHIFT];
            if (op->type == YASM_INSN__OPERAND_REG && op->size == 0) {
                /* Register size must exactly match */
-               if (yasm_x86__get_reg_size(op->data.reg) != size)
+               if (yasm_x86__get_reg_size(arch, op->data.reg) != size)
                    mismatch = 1;
            } else {
                if ((info->operands[i] & OPS_RMASK) == OPS_Relaxed) {
@@ -1903,7 +1903,7 @@ yasm_x86__parse_insn(const unsigned long data[4], int num_operands,
 
     if (!found) {
        /* Didn't find a matching one */
-       yasm__error(lindex, N_("invalid combination of opcode and operands"));
+       yasm__error(line, N_("invalid combination of opcode and operands"));
        return NULL;
     }
 
@@ -1916,10 +1916,10 @@ yasm_x86__parse_insn(const unsigned long data[4], int num_operands,
            switch ((int)((info->modifiers & MOD_ExtIndex_MASK)
                          >> MOD_ExtIndex_SHIFT)) {
                case 0:
-                   yasm__error(lindex, N_("mismatch in operand sizes"));
+                   yasm__error(line, N_("mismatch in operand sizes"));
                    break;
                case 1:
-                   yasm__error(lindex, N_("operand size not specified"));
+                   yasm__error(line, N_("operand size not specified"));
                    break;
                default:
                    yasm_internal_error(N_("unrecognized x86 ext mod index"));
@@ -1938,11 +1938,11 @@ yasm_x86__parse_insn(const unsigned long data[4], int num_operands,
 
     /* Shortcut to JmpRel */
     if (operands && (info->operands[0] & OPA_MASK) == OPA_JmpRel)
-       return x86_new_jmp(data, num_operands, operands, info, cur_section,
-                          prev_bc, lindex);
+       return x86_new_jmp(arch, data, num_operands, operands, info, prev_bc,
+                          line);
 
     /* Copy what we can from info */
-    d.lindex = lindex;
+    d.line = line;
     d.ea = NULL;
     d.ea_origin = NULL;
     d.imm = NULL;
@@ -1985,8 +1985,8 @@ yasm_x86__parse_insn(const unsigned long data[4], int num_operands,
        mod_data >>= 8;
     }
     if (info->modifiers & MOD_Imm8) {
-       d.imm = yasm_expr_new_ident(yasm_expr_int(
-           yasm_intnum_new_uint(mod_data & 0xFF)), lindex);
+       d.imm = yasm_expr_create_ident(yasm_expr_int(
+           yasm_intnum_create_uint(mod_data & 0xFF)), line);
        d.im_len = 1;
        mod_data >>= 8;
     }
@@ -1998,7 +1998,7 @@ yasm_x86__parse_insn(const unsigned long data[4], int num_operands,
     /* Go through operands and assign */
     if (operands) {
        for(i = 0, op = yasm_ops_first(operands); op && i<info->num_operands;
-           op = yasm_ops_next(op), i++) {
+           op = yasm_operand_next(op), i++) {
            switch ((int)(info->operands[i] & OPA_MASK)) {
                case OPA_None:
                    /* Throw away the operand contents */
@@ -2007,10 +2007,10 @@ yasm_x86__parse_insn(const unsigned long data[4], int num_operands,
                        case YASM_INSN__OPERAND_SEGREG:
                            break;
                        case YASM_INSN__OPERAND_MEMORY:
-                           yasm_ea_delete(op->data.ea);
+                           yasm_ea_destroy(op->data.ea);
                            break;
                        case YASM_INSN__OPERAND_IMM:
-                           yasm_expr_delete(op->data.val);
+                           yasm_expr_destroy(op->data.val);
                            break;
                    }
                    break;
@@ -2018,8 +2018,8 @@ yasm_x86__parse_insn(const unsigned long data[4], int num_operands,
                    switch (op->type) {
                        case YASM_INSN__OPERAND_REG:
                            d.ea =
-                               yasm_x86__ea_new_reg(op->data.reg, &d.rex,
-                                                    yasm_x86_LTX_mode_bits);
+                               yasm_x86__ea_create_reg(op->data.reg, &d.rex,
+                                                       arch_x86->mode_bits);
                            break;
                        case YASM_INSN__OPERAND_SEGREG:
                            yasm_internal_error(
@@ -2029,13 +2029,13 @@ yasm_x86__parse_insn(const unsigned long data[4], int num_operands,
                            if ((info->operands[i] & OPT_MASK) == OPT_MemOffs)
                                /* Special-case for MOV MemOffs instruction */
                                yasm_x86__ea_set_disponly(d.ea);
-                           else if (yasm_x86_LTX_mode_bits == 64)
+                           else if (arch_x86->mode_bits == 64)
                                /* Save origin for possible RIP-relative */
-                               d.ea_origin = yasm_symrec_define_label("$",
-                                   cur_section, prev_bc, 0, lindex);
+                               d.ea_origin = yasm_symtab_define_label2("$",
+                                   prev_bc, 0, line);
                            break;
                        case YASM_INSN__OPERAND_IMM:
-                           d.ea = yasm_x86__ea_new_imm(op->data.val,
+                           d.ea = yasm_x86__ea_create_imm(op->data.val,
                                size_lookup[(info->operands[i] &
                                             OPS_MASK)>>OPS_SHIFT]);
                            break;
@@ -2063,9 +2063,9 @@ yasm_x86__parse_insn(const unsigned long data[4], int num_operands,
                        d.spare = (unsigned char)(op->data.reg&7);
                    else if (op->type == YASM_INSN__OPERAND_REG) {
                        if (yasm_x86__set_rex_from_reg(&d.rex, &d.spare,
-                               op->data.reg, yasm_x86_LTX_mode_bits,
+                               op->data.reg, arch_x86->mode_bits,
                                X86_REX_R)) {
-                           yasm__error(lindex,
+                           yasm__error(line,
                                N_("invalid combination of opcode and operands"));
                            return NULL;
                        }
@@ -2076,9 +2076,9 @@ yasm_x86__parse_insn(const unsigned long data[4], int num_operands,
                    if (op->type == YASM_INSN__OPERAND_REG) {
                        unsigned char opadd;
                        if (yasm_x86__set_rex_from_reg(&d.rex, &opadd,
-                               op->data.reg, yasm_x86_LTX_mode_bits,
+                               op->data.reg, arch_x86->mode_bits,
                                X86_REX_B)) {
-                           yasm__error(lindex,
+                           yasm__error(line,
                                N_("invalid combination of opcode and operands"));
                            return NULL;
                        }
@@ -2095,13 +2095,13 @@ yasm_x86__parse_insn(const unsigned long data[4], int num_operands,
                    break;
                case OPA_SpareEA:
                    if (op->type == YASM_INSN__OPERAND_REG) {
-                       d.ea = yasm_x86__ea_new_reg(op->data.reg, &d.rex,
-                                                   yasm_x86_LTX_mode_bits);
+                       d.ea = yasm_x86__ea_create_reg(op->data.reg, &d.rex,
+                                                      arch_x86->mode_bits);
                        if (!d.ea ||
                            yasm_x86__set_rex_from_reg(&d.rex, &d.spare,
-                               op->data.reg, yasm_x86_LTX_mode_bits,
+                               op->data.reg, arch_x86->mode_bits,
                                X86_REX_R)) {
-                           yasm__error(lindex,
+                           yasm__error(line,
                                N_("invalid combination of opcode and operands"));
                            if (d.ea)
                                yasm_xfree(d.ea);
@@ -2131,7 +2131,7 @@ yasm_x86__parse_insn(const unsigned long data[4], int num_operands,
     }
 
     /* Create the bytecode and return it */
-    return yasm_x86__bc_new_insn(&d);
+    return yasm_x86__bc_create_insn(arch, &d);
 }
 
 
@@ -2172,80 +2172,81 @@ yasm_x86__parse_insn(const unsigned long data[4], int num_operands,
 */
 
 void
-yasm_x86__parse_cpu(const char *id, unsigned long lindex)
+yasm_x86__parse_cpu(yasm_arch *arch, const char *id, unsigned long line)
 {
+    yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
     /*const char *marker;*/
 
     /*!re2c
        /* The standard CPU names /set/ cpu_enabled. */
        "8086" {
-           yasm_x86__cpu_enabled = CPU_Priv;
+           arch_x86->cpu_enabled = CPU_Priv;
            return;
        }
        ("80" | I)? "186" {
-           yasm_x86__cpu_enabled = CPU_186|CPU_Priv;
+           arch_x86->cpu_enabled = CPU_186|CPU_Priv;
            return;
        }
        ("80" | I)? "286" {
-           yasm_x86__cpu_enabled = CPU_186|CPU_286|CPU_Priv;
+           arch_x86->cpu_enabled = CPU_186|CPU_286|CPU_Priv;
            return;
        }
        ("80" | I)? "386" {
-           yasm_x86__cpu_enabled =
+           arch_x86->cpu_enabled =
                CPU_186|CPU_286|CPU_386|CPU_SMM|CPU_Prot|CPU_Priv;
            return;
        }
        ("80" | I)? "486" {
-           yasm_x86__cpu_enabled =
+           arch_x86->cpu_enabled =
                CPU_186|CPU_286|CPU_386|CPU_486|CPU_FPU|CPU_SMM|CPU_Prot|
                CPU_Priv;
            return;
        }
        (I? "586") | (P E N T I U M) | (P "5") {
-           yasm_x86__cpu_enabled =
+           arch_x86->cpu_enabled =
                CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_FPU|CPU_SMM|
                CPU_Prot|CPU_Priv;
            return;
        }
        (I? "686") | (P "6") | (P P R O) | (P E N T I U M P R O) {
-           yasm_x86__cpu_enabled =
+           arch_x86->cpu_enabled =
                CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|CPU_FPU|
                CPU_SMM|CPU_Prot|CPU_Priv;
            return;
        }
        (P "2") | (P E N T I U M "-"? ("2" | (I I))) {
-           yasm_x86__cpu_enabled =
+           arch_x86->cpu_enabled =
                CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|CPU_FPU|
                CPU_MMX|CPU_SMM|CPU_Prot|CPU_Priv;
            return;
        }
        (P "3") | (P E N T I U M "-"? ("3" | (I I I))) | (K A T M A I) {
-           yasm_x86__cpu_enabled =
+           arch_x86->cpu_enabled =
                CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|CPU_P3|CPU_FPU|
                CPU_MMX|CPU_SSE|CPU_SMM|CPU_Prot|CPU_Priv;
            return;
        }
        (P "4") | (P E N T I U M "-"? ("4" | (I V))) | (W I L L I A M E T T E) {
-           yasm_x86__cpu_enabled =
+           arch_x86->cpu_enabled =
                CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|CPU_P3|CPU_P4|
                CPU_FPU|CPU_MMX|CPU_SSE|CPU_SSE2|CPU_SMM|CPU_Prot|CPU_Priv;
            return;
        }
        (I A "-"? "64") | (I T A N I U M) {
-           yasm_x86__cpu_enabled =
+           arch_x86->cpu_enabled =
                CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|CPU_P3|CPU_P4|
                CPU_IA64|CPU_FPU|CPU_MMX|CPU_SSE|CPU_SSE2|CPU_SMM|CPU_Prot|
                CPU_Priv;
            return;
        }
        K "6" {
-           yasm_x86__cpu_enabled =
+           arch_x86->cpu_enabled =
                CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|CPU_K6|CPU_FPU|
                CPU_MMX|CPU_3DNow|CPU_SMM|CPU_Prot|CPU_Priv;
            return;
        }
        (A T H L O N) | (K "7") {
-           yasm_x86__cpu_enabled =
+           arch_x86->cpu_enabled =
                CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|CPU_K6|
                CPU_Athlon|CPU_FPU|CPU_MMX|CPU_SSE|CPU_3DNow|CPU_SMM|CPU_Prot|
                CPU_Priv;
@@ -2253,7 +2254,7 @@ yasm_x86__parse_cpu(const char *id, unsigned long lindex)
        }
        ((S L E D G E)? (H A M M E R)) | (O P T E R O N) |
        (A T H L O N "-"? "64") {
-           yasm_x86__cpu_enabled =
+           arch_x86->cpu_enabled =
                CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|CPU_K6|
                CPU_Athlon|CPU_Hammer|CPU_FPU|CPU_MMX|CPU_SSE|CPU_3DNow|
                CPU_SMM|CPU_Prot|CPU_Priv;
@@ -2263,39 +2264,39 @@ yasm_x86__parse_cpu(const char *id, unsigned long lindex)
        /* Features have "no" versions to disable them, and only set/reset the
         * specific feature being changed.  All other bits are left alone.
         */
-       F P U           { yasm_x86__cpu_enabled |= CPU_FPU; return; }
-       N O F P U       { yasm_x86__cpu_enabled &= ~CPU_FPU; return; }
-       M M X           { yasm_x86__cpu_enabled |= CPU_MMX; return; }
-       N O M M X       { yasm_x86__cpu_enabled &= ~CPU_MMX; return; }
-       S S E           { yasm_x86__cpu_enabled |= CPU_SSE; return; }
-       N O S S E       { yasm_x86__cpu_enabled &= ~CPU_SSE; return; }
-       S S E "2"       { yasm_x86__cpu_enabled |= CPU_SSE2; return; }
-       N O S S E "2"   { yasm_x86__cpu_enabled &= ~CPU_SSE2; return; }
-       "3" D N O W     { yasm_x86__cpu_enabled |= CPU_3DNow; return; }
-       N O "3" D N O W { yasm_x86__cpu_enabled &= ~CPU_3DNow; return; }
-       C Y R I X       { yasm_x86__cpu_enabled |= CPU_Cyrix; return; }
-       N O C Y R I X   { yasm_x86__cpu_enabled &= ~CPU_Cyrix; return; }
-       A M D           { yasm_x86__cpu_enabled |= CPU_AMD; return; }
-       N O A M D       { yasm_x86__cpu_enabled &= ~CPU_AMD; return; }
-       S M M           { yasm_x86__cpu_enabled |= CPU_SMM; return; }
-       N O S M M       { yasm_x86__cpu_enabled &= ~CPU_SMM; return; }
-       P R O T         { yasm_x86__cpu_enabled |= CPU_Prot; return; }
-       N O P R O T     { yasm_x86__cpu_enabled &= ~CPU_Prot; return; }
-       U N D O C       { yasm_x86__cpu_enabled |= CPU_Undoc; return; }
-       N O U N D O C   { yasm_x86__cpu_enabled &= ~CPU_Undoc; return; }
-       O B S           { yasm_x86__cpu_enabled |= CPU_Obs; return; }
-       N O O B S       { yasm_x86__cpu_enabled &= ~CPU_Obs; return; }
-       P R I V         { yasm_x86__cpu_enabled |= CPU_Priv; return; }
-       N O P R I V     { yasm_x86__cpu_enabled &= ~CPU_Priv; return; }
+       F P U           { arch_x86->cpu_enabled |= CPU_FPU; return; }
+       N O F P U       { arch_x86->cpu_enabled &= ~CPU_FPU; return; }
+       M M X           { arch_x86->cpu_enabled |= CPU_MMX; return; }
+       N O M M X       { arch_x86->cpu_enabled &= ~CPU_MMX; return; }
+       S S E           { arch_x86->cpu_enabled |= CPU_SSE; return; }
+       N O S S E       { arch_x86->cpu_enabled &= ~CPU_SSE; return; }
+       S S E "2"       { arch_x86->cpu_enabled |= CPU_SSE2; return; }
+       N O S S E "2"   { arch_x86->cpu_enabled &= ~CPU_SSE2; return; }
+       "3" D N O W     { arch_x86->cpu_enabled |= CPU_3DNow; return; }
+       N O "3" D N O W { arch_x86->cpu_enabled &= ~CPU_3DNow; return; }
+       C Y R I X       { arch_x86->cpu_enabled |= CPU_Cyrix; return; }
+       N O C Y R I X   { arch_x86->cpu_enabled &= ~CPU_Cyrix; return; }
+       A M D           { arch_x86->cpu_enabled |= CPU_AMD; return; }
+       N O A M D       { arch_x86->cpu_enabled &= ~CPU_AMD; return; }
+       S M M           { arch_x86->cpu_enabled |= CPU_SMM; return; }
+       N O S M M       { arch_x86->cpu_enabled &= ~CPU_SMM; return; }
+       P R O T         { arch_x86->cpu_enabled |= CPU_Prot; return; }
+       N O P R O T     { arch_x86->cpu_enabled &= ~CPU_Prot; return; }
+       U N D O C       { arch_x86->cpu_enabled |= CPU_Undoc; return; }
+       N O U N D O C   { arch_x86->cpu_enabled &= ~CPU_Undoc; return; }
+       O B S           { arch_x86->cpu_enabled |= CPU_Obs; return; }
+       N O O B S       { arch_x86->cpu_enabled &= ~CPU_Obs; return; }
+       P R I V         { arch_x86->cpu_enabled |= CPU_Priv; return; }
+       N O P R I V     { arch_x86->cpu_enabled &= ~CPU_Priv; return; }
 
        /* catchalls */
        [\001-\377]+    {
-           yasm__warning(YASM_WARN_GENERAL, lindex,
+           yasm__warning(YASM_WARN_GENERAL, line,
                          N_("unrecognized CPU identifier `%s'"), id);
            return;
        }
        [\000]          {
-           yasm__warning(YASM_WARN_GENERAL, lindex,
+           yasm__warning(YASM_WARN_GENERAL, line,
                          N_("unrecognized CPU identifier `%s'"), id);
            return;
        }
@@ -2303,9 +2304,10 @@ yasm_x86__parse_cpu(const char *id, unsigned long lindex)
 }
 
 yasm_arch_check_id_retval
-yasm_x86__parse_check_id(unsigned long data[4], const char *id,
-                        unsigned long lindex)
+yasm_x86__parse_check_id(yasm_arch *arch, unsigned long data[4],
+                        const char *id, unsigned long line)
 {
+    yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
     const char *oid = id;
     /*const char *marker;*/
     /*!re2c
@@ -2339,8 +2341,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
            return YASM_ARCH_CHECK_ID_PREFIX;
        }
        O "64"  {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a prefix in 64-bit mode"), oid);
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2350,8 +2352,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        }
        /* address size overrides */
        A "16"  {
-           if (yasm_x86_LTX_mode_bits == 64) {
-               yasm__error(lindex,
+           if (arch_x86->mode_bits == 64) {
+               yasm__error(line,
                    N_("Cannot override address size to 16 bits in 64-bit mode"));
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2365,8 +2367,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
            return YASM_ARCH_CHECK_ID_PREFIX;
        }
        A "64"  {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a prefix in 64-bit mode"), oid);
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2409,8 +2411,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
 
        /* control, debug, and test registers */
        C R [02-48]     {
-           if (yasm_x86_LTX_mode_bits != 64 && oid[2] == '8') {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64 && oid[2] == '8') {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a register in 64-bit mode"), oid);
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2436,9 +2438,9 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
            return YASM_ARCH_CHECK_ID_REG;
        }
        X M M [0-9]     {
-           if (yasm_x86_LTX_mode_bits != 64 &&
+           if (arch_x86->mode_bits != 64 &&
                (oid[3] == '8' || oid[3] == '9')) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a register in 64-bit mode"), oid);
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2446,8 +2448,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
            return YASM_ARCH_CHECK_ID_REG;
        }
        X M M "1" [0-5] {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a register in 64-bit mode"), oid);
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2457,8 +2459,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
 
        /* integer registers */
        R A X   {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a register in 64-bit mode"), oid);
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2466,8 +2468,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
            return YASM_ARCH_CHECK_ID_REG;
        }
        R C X   {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a register in 64-bit mode"), oid);
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2475,8 +2477,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
            return YASM_ARCH_CHECK_ID_REG;
        }
        R D X   {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a register in 64-bit mode"), oid);
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2484,8 +2486,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
            return YASM_ARCH_CHECK_ID_REG;
        }
        R B X   {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a register in 64-bit mode"), oid);
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2493,8 +2495,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
            return YASM_ARCH_CHECK_ID_REG;
        }
        R S P   {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a register in 64-bit mode"), oid);
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2502,8 +2504,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
            return YASM_ARCH_CHECK_ID_REG;
        }
        R B P   {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a register in 64-bit mode"), oid);
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2511,8 +2513,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
            return YASM_ARCH_CHECK_ID_REG;
        }
        R S I   {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a register in 64-bit mode"), oid);
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2520,8 +2522,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
            return YASM_ARCH_CHECK_ID_REG;
        }
        R D I   {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a register in 64-bit mode"), oid);
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2529,8 +2531,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
            return YASM_ARCH_CHECK_ID_REG;
        }
        R [8-9] {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a register in 64-bit mode"), oid);
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2538,8 +2540,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
            return YASM_ARCH_CHECK_ID_REG;
        }
        R "1" [0-5] {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a register in 64-bit mode"), oid);
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2556,8 +2558,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        E S I   { data[0] = X86_REG32 | 6; return YASM_ARCH_CHECK_ID_REG; }
        E D I   { data[0] = X86_REG32 | 7; return YASM_ARCH_CHECK_ID_REG; }
        R [8-9] D {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a register in 64-bit mode"), oid);
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2565,8 +2567,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
            return YASM_ARCH_CHECK_ID_REG;
        }
        R "1" [0-5] D {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a register in 64-bit mode"), oid);
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2583,8 +2585,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        S I     { data[0] = X86_REG16 | 6; return YASM_ARCH_CHECK_ID_REG; }
        D I     { data[0] = X86_REG16 | 7; return YASM_ARCH_CHECK_ID_REG; }
        R [8-9] W {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a register in 64-bit mode"), oid);
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2592,8 +2594,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
            return YASM_ARCH_CHECK_ID_REG;
        }
        R "1" [0-5] W {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a register in 64-bit mode"), oid);
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2610,8 +2612,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        D H     { data[0] = X86_REG8 | 6; return YASM_ARCH_CHECK_ID_REG; }
        B H     { data[0] = X86_REG8 | 7; return YASM_ARCH_CHECK_ID_REG; }
        S P L   {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a register in 64-bit mode"), oid);
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2619,8 +2621,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
            return YASM_ARCH_CHECK_ID_REG;
        }
        B P L   {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a register in 64-bit mode"), oid);
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2628,8 +2630,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
            return YASM_ARCH_CHECK_ID_REG;
        }
        S I L   {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a register in 64-bit mode"), oid);
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2637,8 +2639,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
            return YASM_ARCH_CHECK_ID_REG;
        }
        D I L   {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a register in 64-bit mode"), oid);
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2646,8 +2648,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
            return YASM_ARCH_CHECK_ID_REG;
        }
        R [8-9] B {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a register in 64-bit mode"), oid);
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2655,8 +2657,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
            return YASM_ARCH_CHECK_ID_REG;
        }
        R "1" [0-5] B {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a register in 64-bit mode"), oid);
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2666,23 +2668,23 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
 
        /* segment registers */
        E S     {
-           if (yasm_x86_LTX_mode_bits == 64)
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits == 64)
+               yasm__warning(YASM_WARN_GENERAL, line,
                    N_("`%s' segment register ignored in 64-bit mode"), oid);
            data[0] = 0x2600;
            return YASM_ARCH_CHECK_ID_SEGREG;
        }
        C S     { data[0] = 0x2e01; return YASM_ARCH_CHECK_ID_SEGREG; }
        S S     {
-           if (yasm_x86_LTX_mode_bits == 64)
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits == 64)
+               yasm__warning(YASM_WARN_GENERAL, line,
                    N_("`%s' segment register ignored in 64-bit mode"), oid);
            data[0] = 0x3602;
            return YASM_ARCH_CHECK_ID_SEGREG;
        }
        D S     {
-           if (yasm_x86_LTX_mode_bits == 64)
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits == 64)
+               yasm__warning(YASM_WARN_GENERAL, line,
                    N_("`%s' segment register ignored in 64-bit mode"), oid);
            data[0] = 0x3e03;
            return YASM_ARCH_CHECK_ID_SEGREG;
@@ -2692,8 +2694,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
 
        /* RIP for 64-bit mode IP-relative offsets */
        R I P   {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is a register in 64-bit mode"), oid);
                return YASM_ARCH_CHECK_ID_NONE;
            }
@@ -2708,8 +2710,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        /* Move with sign/zero extend */
        M O V S X { RET_INSN(movszx, 0xBE, CPU_386); }
        M O V S X D {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is an instruction in 64-bit mode"),
                              oid);
                return YASM_ARCH_CHECK_ID_NONE;
@@ -2720,22 +2722,22 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        /* Push instructions */
        P U S H { RET_INSN(push, 0, CPU_Any); }
        P U S H A {
-           if (yasm_x86_LTX_mode_bits == 64) {
-               yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+           if (arch_x86->mode_bits == 64) {
+               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
                RET_INSN(not64, 0, CPU_Not64);
            }
            RET_INSN(onebyte, 0x0060, CPU_186);
        }
        P U S H A D {
-           if (yasm_x86_LTX_mode_bits == 64) {
-               yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+           if (arch_x86->mode_bits == 64) {
+               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
                RET_INSN(not64, 0, CPU_Not64);
            }
            RET_INSN(onebyte, 0x2060, CPU_386);
        }
        P U S H A W {
-           if (yasm_x86_LTX_mode_bits == 64) {
-               yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+           if (arch_x86->mode_bits == 64) {
+               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
                RET_INSN(not64, 0, CPU_Not64);
            }
            RET_INSN(onebyte, 0x1060, CPU_186);
@@ -2743,22 +2745,22 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        /* Pop instructions */
        P O P { RET_INSN(pop, 0, CPU_Any); }
        P O P A {
-           if (yasm_x86_LTX_mode_bits == 64) {
-               yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+           if (arch_x86->mode_bits == 64) {
+               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
                RET_INSN(not64, 0, CPU_Not64);
            }
            RET_INSN(onebyte, 0x0061, CPU_186);
        }
        P O P A D {
-           if (yasm_x86_LTX_mode_bits == 64) {
-               yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+           if (arch_x86->mode_bits == 64) {
+               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
                RET_INSN(not64, 0, CPU_Not64);
            }
            RET_INSN(onebyte, 0x2061, CPU_386);
        }
        P O P A W {
-           if (yasm_x86_LTX_mode_bits == 64) {
-               yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+           if (arch_x86->mode_bits == 64) {
+               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
                RET_INSN(not64, 0, CPU_Not64);
            }
            RET_INSN(onebyte, 0x1061, CPU_186);
@@ -2772,15 +2774,15 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        L E A { RET_INSN(lea, 0, CPU_Any); }
        /* Load segment registers from memory */
        L D S {
-           if (yasm_x86_LTX_mode_bits == 64) {
-               yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+           if (arch_x86->mode_bits == 64) {
+               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
                RET_INSN(not64, 0, CPU_Not64);
            }
            RET_INSN(ldes, 0xC5, CPU_Any);
        }
        L E S {
-           if (yasm_x86_LTX_mode_bits == 64) {
-               yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+           if (arch_x86->mode_bits == 64) {
+               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
                RET_INSN(not64, 0, CPU_Not64);
            }
            RET_INSN(ldes, 0xC4, CPU_Any);
@@ -2795,15 +2797,15 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        C L T S { RET_INSN(twobyte, 0x0F06, CPU_286|CPU_Priv); }
        C M C { RET_INSN(onebyte, 0x00F5, CPU_Any); }
        L A H F {
-           if (yasm_x86_LTX_mode_bits == 64) {
-               yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+           if (arch_x86->mode_bits == 64) {
+               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
                RET_INSN(not64, 0, CPU_Not64);
            }
            RET_INSN(onebyte, 0x009F, CPU_Any);
        }
        S A H F {
-           if (yasm_x86_LTX_mode_bits == 64) {
-               yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+           if (arch_x86->mode_bits == 64) {
+               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
                RET_INSN(not64, 0, CPU_Not64);
            }
            RET_INSN(onebyte, 0x009E, CPU_Any);
@@ -2812,8 +2814,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        P U S H F D { RET_INSN(onebyte, 0x209C, CPU_386); }
        P U S H F W { RET_INSN(onebyte, 0x109C, CPU_Any); }
        P U S H F Q {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is an instruction in 64-bit mode"),
                              oid);
                return YASM_ARCH_CHECK_ID_NONE;
@@ -2822,16 +2824,16 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        }
        P O P F { RET_INSN(onebyte, 0x40009D, CPU_Any); }
        P O P F D {
-           if (yasm_x86_LTX_mode_bits == 64) {
-               yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+           if (arch_x86->mode_bits == 64) {
+               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
                RET_INSN(not64, 0, CPU_Not64);
            }
            RET_INSN(onebyte, 0x00209D, CPU_386);
        }
        P O P F W { RET_INSN(onebyte, 0x40109D, CPU_Any); }
        P O P F Q {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is an instruction in 64-bit mode"),
                              oid);
                return YASM_ARCH_CHECK_ID_NONE;
@@ -2856,43 +2858,43 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        N E G { RET_INSN(f6, 0x03, CPU_Any); }
        N O T { RET_INSN(f6, 0x02, CPU_Any); }
        A A A {
-           if (yasm_x86_LTX_mode_bits == 64) {
-               yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+           if (arch_x86->mode_bits == 64) {
+               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
                RET_INSN(not64, 0, CPU_Not64);
            }
            RET_INSN(onebyte, 0x0037, CPU_Any);
        }
        A A S {
-           if (yasm_x86_LTX_mode_bits == 64) {
-               yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+           if (arch_x86->mode_bits == 64) {
+               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
                RET_INSN(not64, 0, CPU_Not64);
            }
            RET_INSN(onebyte, 0x003F, CPU_Any);
        }
        D A A {
-           if (yasm_x86_LTX_mode_bits == 64) {
-               yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+           if (arch_x86->mode_bits == 64) {
+               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
                RET_INSN(not64, 0, CPU_Not64);
            }
            RET_INSN(onebyte, 0x0027, CPU_Any);
        }
        D A S {
-           if (yasm_x86_LTX_mode_bits == 64) {
-               yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+           if (arch_x86->mode_bits == 64) {
+               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
                RET_INSN(not64, 0, CPU_Not64);
            }
            RET_INSN(onebyte, 0x002F, CPU_Any);
        }
        A A D {
-           if (yasm_x86_LTX_mode_bits == 64) {
-               yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+           if (arch_x86->mode_bits == 64) {
+               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
                RET_INSN(not64, 0, CPU_Not64);
            }
            RET_INSN(aadm, 0x01, CPU_Any);
        }
        A A M {
-           if (yasm_x86_LTX_mode_bits == 64) {
-               yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+           if (arch_x86->mode_bits == 64) {
+               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
                RET_INSN(not64, 0, CPU_Not64);
            }
            RET_INSN(aadm, 0x00, CPU_Any);
@@ -2901,8 +2903,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        C B W { RET_INSN(onebyte, 0x1098, CPU_Any); }
        C W D E { RET_INSN(onebyte, 0x2098, CPU_386); }
        C D Q E {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is an instruction in 64-bit mode"),
                              oid);
                return YASM_ARCH_CHECK_ID_NONE;
@@ -2912,8 +2914,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        C W D { RET_INSN(onebyte, 0x1099, CPU_Any); }
        C D Q { RET_INSN(onebyte, 0x2099, CPU_386); }
        C D O {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is an instruction in 64-bit mode"),
                              oid);
                return YASM_ARCH_CHECK_ID_NONE;
@@ -2978,8 +2980,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        J C X Z { RET_INSN(jcxz, 16, CPU_Any); }
        J E C X Z { RET_INSN(jcxz, 32, CPU_386); }
        J R C X Z {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is an instruction in 64-bit mode"),
                              oid);
                return YASM_ARCH_CHECK_ID_NONE;
@@ -3028,8 +3030,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        C M P S W { RET_INSN(onebyte, 0x10A7, CPU_Any); }
        C M P S D { RET_INSN(cmpsd, 0, CPU_Any); }
        C M P S Q {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is an instruction in 64-bit mode"),
                              oid);
                return YASM_ARCH_CHECK_ID_NONE;
@@ -3046,8 +3048,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        L O D S W { RET_INSN(onebyte, 0x10AD, CPU_Any); }
        L O D S D { RET_INSN(onebyte, 0x20AD, CPU_386); }
        L O D S Q {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is an instruction in 64-bit mode"),
                              oid);
                return YASM_ARCH_CHECK_ID_NONE;
@@ -3058,8 +3060,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        M O V S W { RET_INSN(onebyte, 0x10A5, CPU_Any); }
        M O V S D { RET_INSN(movsd, 0, CPU_Any); }
        M O V S Q {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is an instruction in 64-bit mode"),
                              oid);
                return YASM_ARCH_CHECK_ID_NONE;
@@ -3070,8 +3072,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        S C A S W { RET_INSN(onebyte, 0x10AF, CPU_Any); }
        S C A S D { RET_INSN(onebyte, 0x20AF, CPU_386); }
        S C A S Q {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is an instruction in 64-bit mode"),
                              oid);
                return YASM_ARCH_CHECK_ID_NONE;
@@ -3082,8 +3084,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        S T O S W { RET_INSN(onebyte, 0x10AB, CPU_Any); }
        S T O S D { RET_INSN(onebyte, 0x20AB, CPU_386); }
        S T O S Q {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is an instruction in 64-bit mode"),
                              oid);
                return YASM_ARCH_CHECK_ID_NONE;
@@ -3103,8 +3105,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        I N T "3" { RET_INSN(onebyte, 0x00CC, CPU_Any); }
        I N T "03" { RET_INSN(onebyte, 0x00CC, CPU_Any); }
        I N T O {
-           if (yasm_x86_LTX_mode_bits == 64) {
-               yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+           if (arch_x86->mode_bits == 64) {
+               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
                RET_INSN(not64, 0, CPU_Not64);
            }
            RET_INSN(onebyte, 0x00CE, CPU_Any);
@@ -3113,8 +3115,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        I R E T W { RET_INSN(onebyte, 0x10CF, CPU_Any); }
        I R E T D { RET_INSN(onebyte, 0x20CF, CPU_386); }
        I R E T Q {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is an instruction in 64-bit mode"),
                              oid);
                return YASM_ARCH_CHECK_ID_NONE;
@@ -3123,8 +3125,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        }
        R S M { RET_INSN(twobyte, 0x0FAA, CPU_586|CPU_SMM); }
        B O U N D {
-           if (yasm_x86_LTX_mode_bits == 64) {
-               yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+           if (arch_x86->mode_bits == 64) {
+               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
                RET_INSN(not64, 0, CPU_Not64);
            }
            RET_INSN(bound, 0, CPU_186);
@@ -3133,8 +3135,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        N O P { RET_INSN(onebyte, 0x0090, CPU_Any); }
        /* Protection control */
        A R P L {
-           if (yasm_x86_LTX_mode_bits == 64) {
-               yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+           if (arch_x86->mode_bits == 64) {
+               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
                RET_INSN(not64, 0, CPU_Not64);
            }
            RET_INSN(arpl, 0, CPU_286|CPU_Prot);
@@ -3254,15 +3256,15 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        C M P X C H G "8" B { RET_INSN(cmpxchg8b, 0, CPU_586); }
        /* Pentium II/Pentium Pro extensions */
        S Y S E N T E R {
-           if (yasm_x86_LTX_mode_bits == 64) {
-               yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+           if (arch_x86->mode_bits == 64) {
+               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
                RET_INSN(not64, 0, CPU_Not64);
            }
            RET_INSN(twobyte, 0x0F34, CPU_686);
        }
        S Y S E X I T {
-           if (yasm_x86_LTX_mode_bits == 64) {
-               yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+           if (arch_x86->mode_bits == 64) {
+               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
                RET_INSN(not64, 0, CPU_Not64);
            }
            RET_INSN(twobyte, 0x0F35, CPU_686|CPU_Priv);
@@ -3564,8 +3566,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        S Y S R E T { RET_INSN(twobyte, 0x0F07, CPU_686|CPU_AMD|CPU_Priv); }
        /* AMD x86-64 extensions */
        S W A P G S {
-           if (yasm_x86_LTX_mode_bits != 64) {
-               yasm__warning(YASM_WARN_GENERAL, lindex,
+           if (arch_x86->mode_bits != 64) {
+               yasm__warning(YASM_WARN_GENERAL, line,
                              N_("`%s' is an instruction in 64-bit mode"),
                              oid);
                return YASM_ARCH_CHECK_ID_NONE;
@@ -3602,8 +3604,8 @@ yasm_x86__parse_check_id(unsigned long data[4], const char *id,
        L O A D A L L { RET_INSN(twobyte, 0x0F07, CPU_386|CPU_Undoc); }
        L O A D A L L "286" { RET_INSN(twobyte, 0x0F05, CPU_286|CPU_Undoc); }
        S A L C {
-           if (yasm_x86_LTX_mode_bits == 64) {
-               yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+           if (arch_x86->mode_bits == 64) {
+               yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
                RET_INSN(not64, 0, CPU_Not64);
            }
            RET_INSN(onebyte, 0x00D6, CPU_Undoc);
index 55d71c9f61379c152affed308f39ad7bcd5c7c2f..ec2ff48b09c5396d070212b5e7f389bc53e9069b 100644 (file)
@@ -39,8 +39,5 @@ yasm_dbgfmt yasm_null_LTX_dbgfmt = {
     NULL,   /*null_dbgfmt_initialize*/
     NULL,   /*null_dbgfmt_cleanup*/
     NULL,   /*null_dbgfmt_directive*/
-    NULL,   /*null_dbgfmt_generate*/
-    NULL,   /*null_dbgfmt_bc_data_output*/
-    NULL,   /*null_dbgfmt_bc_data_delete*/
-    NULL    /*null_dbgfmt_bc_data_print*/
+    NULL    /*null_dbgfmt_generate*/
 };
index efb56db92e0f7f1bb12789b6abd8c7433474657a..da0c502f128d3ad2b950440a23fac2b13129f1fc 100644 (file)
@@ -80,9 +80,6 @@ typedef enum {
     N_NBLCS = 0xf8     /* Gould non-base registers */
 } stabs_stab_type;
 
-#define STABS_DEBUG_DATA 1
-#define STABS_DEBUG_STR 2
-
 typedef struct {
     unsigned long lastline;    /* track line and file of bytecodes */
     unsigned long curline;
@@ -115,26 +112,73 @@ typedef struct {
     yasm_section *sect;
 } stabs_symsect;
 
-yasm_dbgfmt yasm_stabs_LTX_dbgfmt;
+/* Bytecode types */
+
+typedef struct {
+    yasm_bytecode bc;  /* base structure */
+    /*@only@*/ char *str;
+} stabs_bc_str;
+
+typedef struct {
+    yasm_bytecode bc;  /* base structure */
+    stabs_stab *stab;
+} stabs_bc_stab;
+
+/* Bytecode callback function prototypes */
+
+static void stabs_bc_str_destroy(yasm_bytecode *bc);
+static void stabs_bc_str_print(const yasm_bytecode *bc, FILE *f, int
+                              indent_level);
+static yasm_bc_resolve_flags stabs_bc_str_resolve
+    (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+static int stabs_bc_str_tobytes
+    (yasm_bytecode *bc, unsigned char **bufp, void *d,
+     yasm_output_expr_func output_expr,
+     /*@null@*/ yasm_output_reloc_func output_reloc);
+
+static void stabs_bc_stab_destroy(yasm_bytecode *bc);
+static void stabs_bc_stab_print(const yasm_bytecode *bc, FILE *f, int
+                               indent_level);
+static yasm_bc_resolve_flags stabs_bc_stab_resolve
+    (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+static int stabs_bc_stab_tobytes
+    (yasm_bytecode *bc, unsigned char **bufp, void *d,
+     yasm_output_expr_func output_expr,
+     /*@null@*/ yasm_output_reloc_func output_reloc);
+
+/* Bytecode callback structures */
+
+static const yasm_bytecode_callback stabs_bc_str_callback = {
+    stabs_bc_str_destroy,
+    stabs_bc_str_print,
+    stabs_bc_str_resolve,
+    stabs_bc_str_tobytes
+};
+
+static const yasm_bytecode_callback stabs_bc_stab_callback = {
+    stabs_bc_stab_destroy,
+    stabs_bc_stab_print,
+    stabs_bc_stab_resolve,
+    stabs_bc_stab_tobytes
+};
 
+static yasm_symtab *symtab = NULL;
 static yasm_objfmt *cur_objfmt = NULL;
 static const char *filename = NULL;
-static yasm_linemgr *linemgr = NULL;
+static yasm_linemap *linemap = NULL;
 static yasm_arch *cur_arch = NULL;
-static const char *cur_machine = NULL;
 static size_t stabs_relocsize_bits = 0;
 static size_t stabs_relocsize_bytes = 0;
 
 static int
 stabs_dbgfmt_initialize(const char *in_filename, const char *obj_filename,
-                       yasm_linemgr *lm, yasm_objfmt *of, yasm_arch *a,
-                       const char *machine)
+                       yasm_object *object, yasm_objfmt *of, yasm_arch *a)
 {
     cur_objfmt = of;
     filename = in_filename;
-    linemgr = lm;
+    symtab = yasm_object_get_symtab(object);
+    linemap = yasm_object_get_linemap(object);
     cur_arch = a;
-    cur_machine = machine;
     return 0;
 }
 
@@ -149,14 +193,20 @@ stabs_dbgfmt_cleanup(void)
 static yasm_bytecode *
 stabs_dbgfmt_append_bcstr(yasm_section *sect, const char *str)
 {
-    yasm_bytecode *bc = yasm_bc_new_dbgfmt_data(
-                           STABS_DEBUG_STR, strlen(str)+1,
-                           &yasm_stabs_LTX_dbgfmt,
-                           (void *)yasm__xstrdup(str), 0);
-    yasm_bytecodehead *bcs = yasm_section_get_bytecodes(sect);
-    yasm_bytecode *precbc = yasm_bcs_last(bcs);
+    yasm_bytecode *bc, *precbc;
+    stabs_bc_str *bc_str;
+   
+    precbc = yasm_section_bcs_last(sect);
+    bc = yasm_bc_create_common(&stabs_bc_str_callback, sizeof(stabs_bc_str),
+                              0);
+    bc_str = (stabs_bc_str *)bc;
+
+    bc_str->str = yasm__xstrdup(str);
+
+    bc->len = strlen(str)+1;
     bc->offset = precbc ? precbc->offset + precbc->len : 0;
-    yasm_bcs_append(bcs, bc);
+
+    yasm_section_bcs_append(sect, bc);
 
     return bc;
 }
@@ -171,8 +221,9 @@ stabs_dbgfmt_append_stab(stabs_info *info, yasm_section *sect,
                         /*@null@*/ yasm_bytecode *bcvalue, unsigned long value)
 {
     yasm_bytecode *bc, *precbc;
-    yasm_bytecodehead *bcs;
+    stabs_bc_stab *bc_stab;
     stabs_stab *stab = yasm_xmalloc(sizeof(stabs_stab));
+
     stab->other = 0;
     stab->bcstr = bcstr;
     stab->type = type;
@@ -181,13 +232,18 @@ stabs_dbgfmt_append_stab(stabs_info *info, yasm_section *sect,
     stab->bcvalue = bcvalue;
     stab->value = value;
 
-    bc = yasm_bc_new_dbgfmt_data(STABS_DEBUG_DATA, info->stablen,
-                                &yasm_stabs_LTX_dbgfmt, (void *)stab,
-                                bcvalue ? bcvalue->line : 0);
-    bcs = yasm_section_get_bytecodes(sect);
-    precbc = yasm_bcs_last(bcs);
+    precbc = yasm_section_bcs_last(sect);
+    bc = yasm_bc_create_common(&stabs_bc_stab_callback, sizeof(stabs_bc_stab),
+                              bcvalue ? bcvalue->line : 0);
+    bc_stab = (stabs_bc_stab *)bc;
+
+    bc_stab->stab = stab;
+
+    bc->len = info->stablen;
     bc->offset = precbc ? precbc->offset + precbc->len : 0;
-    yasm_bcs_append(bcs, bc);
+
+    yasm_section_bcs_append(sect, bc);
+
     info->stabcount++;
     return stab;
 }
@@ -197,14 +253,11 @@ static int
 stabs_dbgfmt_first_sym_traversal(yasm_symrec *sym, void *d)
 {
     stabs_symsect *symsect = (stabs_symsect *)d;
-    yasm_section *sect;
     yasm_bytecode *precbc;
 
-    if (!yasm_symrec_get_label(sym, &sect, &precbc))
+    if (!yasm_symrec_get_label(sym, &precbc))
        return 1;
-    if (precbc == NULL)
-       precbc = yasm_bcs_first(yasm_section_get_bytecodes(sect));
-    if ((sect == symsect->sect)
+    if ((precbc->section == symsect->sect)
        && ((symsect->sym == NULL)
            || precbc->offset < symsect->precbc->offset))
     {
@@ -225,7 +278,8 @@ stabs_dbgfmt_first_sym_by_sect(stabs_info *info, yasm_section *sect)
     }
 
     symsect.sect = sect;
-    yasm_symrec_traverse((void *)&symsect, stabs_dbgfmt_first_sym_traversal);
+    yasm_symtab_traverse(symtab, (void *)&symsect,
+                        stabs_dbgfmt_first_sym_traversal);
     info->firstsym = symsect.sym;
     info->firstbc = symsect.precbc;
 }
@@ -234,7 +288,7 @@ static int
 stabs_dbgfmt_generate_bcs(yasm_bytecode *bc, void *d)
 {
     stabs_info *info = (stabs_info *)d;
-    linemgr->lookup(bc->line, &info->curfile, &info->curline);
+    yasm_linemap_lookup(linemap, bc->line, &info->curfile, &info->curline);
 
     if (info->lastfile != info->curfile) {
        info->lastline = 0; /* new file, so line changes */
@@ -273,29 +327,29 @@ stabs_dbgfmt_generate_sections(yasm_section *sect, /*@null@*/ void *d)
                                 N_FUN, 0, info->firstsym, info->firstbc, 0);
        yasm_xfree(str);
     }
-    yasm_bcs_traverse(yasm_section_get_bytecodes(sect), d,
-                     stabs_dbgfmt_generate_bcs);
+    yasm_section_bcs_traverse(sect, d, stabs_dbgfmt_generate_bcs);
 
     return 1;
 }
 
 static void
-stabs_dbgfmt_generate(yasm_sectionhead *sections)
+stabs_dbgfmt_generate(yasm_object *object)
 {
     stabs_info info;
     int new;
     yasm_bytecode *dbgbc;
-    yasm_bytecodehead *bcs;
+    stabs_bc_stab *dbgbc_stab;
     stabs_stab *stab;
     yasm_bytecode *filebc, *nullbc, *laststr;
     yasm_section *stext;
+    const char *machine = cur_arch->module->get_machine(cur_arch);
 
     /* Stablen is determined by arch/machine */
-    if (yasm__strcasecmp(cur_arch->keyword, "x86") == 0) {
-       if (yasm__strcasecmp(cur_machine, "x86") == 0) {
+    if (yasm__strcasecmp(cur_arch->module->keyword, "x86") == 0) {
+       if (yasm__strcasecmp(machine, "x86") == 0) {
            info.stablen = 12;
        }
-       else if (yasm__strcasecmp(cur_machine, "amd64") == 0) {
+       else if (yasm__strcasecmp(machine, "amd64") == 0) {
            info.stablen = 16;
        }
        else
@@ -309,27 +363,22 @@ stabs_dbgfmt_generate(yasm_sectionhead *sections)
 
     info.lastline = 0;
     info.stabcount = 0;
-    info.stab = yasm_sections_switch_general(sections, ".stab", 0, 0, &new, 0);
+    info.stab = yasm_object_get_general(object, ".stab", 0, 0, &new, 0);
     if (!new) {
-       yasm_bytecode *last = yasm_bcs_last(
-           yasm_section_get_bytecodes(info.stab));
+       yasm_bytecode *last = yasm_section_bcs_last(info.stab);
        if (last == NULL)
-           yasm__error(
-               yasm_bcs_first(yasm_section_get_bytecodes(info.stab))->line,
+           yasm__error(yasm_section_bcs_first(info.stab)->line,
                N_("stabs debugging conflicts with user-defined section .stab"));
        else
            yasm__warning(YASM_WARN_GENERAL, 0,
                N_("stabs debugging overrides empty section .stab"));
     }
 
-    info.stabstr = yasm_sections_switch_general(sections, ".stabstr", 0, 0,
-                                               &new, 0);
+    info.stabstr = yasm_object_get_general(object, ".stabstr", 0, 0, &new, 0);
     if (!new) {
-       yasm_bytecode *last = yasm_bcs_last(
-           yasm_section_get_bytecodes(info.stabstr));
+       yasm_bytecode *last = yasm_section_bcs_last(info.stabstr);
        if (last == NULL)
-           yasm__error(
-               yasm_bcs_first(yasm_section_get_bytecodes(info.stabstr))->line,
+           yasm__error(yasm_section_bcs_first(info.stabstr)->line,
                N_("stabs debugging conflicts with user-defined section .stabstr"));
        else
            yasm__warning(YASM_WARN_GENERAL, 0,
@@ -340,27 +389,31 @@ stabs_dbgfmt_generate(yasm_sectionhead *sections)
 
     /* initial pseudo-stab */
     stab = yasm_xmalloc(sizeof(stabs_stab));
-    dbgbc = yasm_bc_new_dbgfmt_data(STABS_DEBUG_DATA, info.stablen,
-                                   &yasm_stabs_LTX_dbgfmt, (void *)stab, 0);
-    bcs = yasm_section_get_bytecodes(info.stab);
-    yasm_bcs_append(bcs, dbgbc);
+    dbgbc = yasm_bc_create_common(&stabs_bc_stab_callback,
+                                 sizeof(stabs_bc_stab), 0);
+    dbgbc_stab = (stabs_bc_stab *)dbgbc;
+
+    dbgbc->len = info.stablen;
+    dbgbc_stab->stab = stab;
+
+    yasm_section_bcs_append(info.stab, dbgbc);
 
     /* initial strtab bytecodes */
     nullbc = stabs_dbgfmt_append_bcstr(info.stabstr, "");
     filebc = stabs_dbgfmt_append_bcstr(info.stabstr, filename);
 
-    stext = yasm_sections_find_general(sections, ".text");
-    info.firstsym = yasm_symrec_use(".text", 0);
-    info.firstbc = yasm_bcs_first(yasm_section_get_bytecodes(stext));
+    stext = yasm_object_find_general(object, ".text");
+    info.firstsym = yasm_symtab_use(yasm_object_get_symtab(object), ".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_sections_traverse(sections, (void *)&info,
-                          stabs_dbgfmt_generate_sections);
+    yasm_object_sections_traverse(object, (void *)&info,
+                                 stabs_dbgfmt_generate_sections);
 
     /* fill initial pseudo-stab's fields */
-    laststr = yasm_bcs_last(yasm_section_get_bytecodes(info.stabstr));
+    laststr = yasm_section_bcs_last(info.stabstr);
     if (laststr == NULL)
        yasm_internal_error(".stabstr has no entries");
 
@@ -374,65 +427,102 @@ stabs_dbgfmt_generate(yasm_sectionhead *sections)
 }
 
 static int
-stabs_dbgfmt_bc_data_output(yasm_bytecode *bc, unsigned int type,
-                           const void *data, unsigned char **buf,
-                           const yasm_section *sect,
-                           yasm_output_reloc_func output_reloc, void *objfmt_d)
+stabs_bc_stab_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+                     yasm_output_expr_func output_expr,
+                     yasm_output_reloc_func output_reloc)
 {
-    unsigned char *bufp = *buf;
-    if (type == STABS_DEBUG_DATA) {
-       const stabs_stab *stab = data;
-
-       YASM_WRITE_32_L(bufp, stab->bcstr ? stab->bcstr->offset : 0);
-       YASM_WRITE_8(bufp, stab->type);
-       YASM_WRITE_8(bufp, stab->other);
-       YASM_WRITE_16_L(bufp, stab->desc);
-
-       if (stab->symvalue != NULL) {
-           printf("DBG: ");
-           bc->offset += 8;
-           output_reloc(stab->symvalue, bc, bufp, stabs_relocsize_bytes,
-                        stabs_relocsize_bits, 0, 0, sect, objfmt_d);
-           bc->offset -= 8;
-           bufp += stabs_relocsize_bytes;
-       }
-       else if (stab->bcvalue != NULL) {
-           YASM_WRITE_32_L(bufp, stab->bcvalue->offset);
-       }
-       else {
-           YASM_WRITE_32_L(bufp, stab->value);
-       }
+    stabs_bc_stab *bc_stab = (stabs_bc_stab *)bc;
+    unsigned char *buf = *bufp;
+    const stabs_stab *stab = bc_stab->stab;
+
+    YASM_WRITE_32_L(buf, stab->bcstr ? stab->bcstr->offset : 0);
+    YASM_WRITE_8(buf, stab->type);
+    YASM_WRITE_8(buf, stab->other);
+    YASM_WRITE_16_L(buf, stab->desc);
+
+    if (stab->symvalue != NULL) {
+       printf("DBG: ");
+       bc->offset += 8;
+       output_reloc(stab->symvalue, bc, buf, stabs_relocsize_bytes,
+                    stabs_relocsize_bits, 0, 0, d);
+       bc->offset -= 8;
+       buf += stabs_relocsize_bytes;
     }
-    else if (type == STABS_DEBUG_STR) {
-       const char *str = data;
-       strcpy((char *)bufp, str);
-       bufp += strlen(str)+1;
+    else if (stab->bcvalue != NULL) {
+       YASM_WRITE_32_L(buf, stab->bcvalue->offset);
     }
+    else {
+       YASM_WRITE_32_L(buf, stab->value);
+    }
+
+    *bufp = buf;
+    return 0;
+}
+
+static int
+stabs_bc_str_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+                    yasm_output_expr_func output_expr,
+                    yasm_output_reloc_func output_reloc)
+{
+    stabs_bc_str *bc_str = (stabs_bc_str *)bc;
+    unsigned char *buf = *bufp;
+    const char *str = bc_str->str;
+
+    strcpy((char *)buf, str);
+    buf += strlen(str)+1;
 
-    *buf = bufp;
+    *bufp = buf;
     return 0;
 }
 
 static void
-stabs_dbgfmt_bc_data_delete(unsigned int type, void *data)
+stabs_bc_stab_destroy(yasm_bytecode *bc)
 {
-    /* both stabs and strs are allocated at the top level pointer */
-    yasm_xfree(data);
+    stabs_bc_stab *bc_stab = (stabs_bc_stab *)bc;
+    yasm_xfree(bc_stab->stab);
 }
 
 static void
-stabs_dbgfmt_bc_data_print(FILE *f, int indent_level, unsigned int type,
-                   const void *data)
+stabs_bc_str_destroy(yasm_bytecode *bc)
 {
-    if (type == STABS_DEBUG_DATA) {
-       const stabs_stab *stab = data;
-       const char *str = "";
-       fprintf(f, "%*s.stabs \"%s\", 0x%x, 0x%x, 0x%x, 0x%lx\n",
-               indent_level, "", str, stab->type, stab->other, stab->desc,
-               stab->bcvalue ? stab->bcvalue->offset : stab->value);
-    }
-    else if (type == STABS_DEBUG_STR)
-       fprintf(f, "%*s\"%s\"\n", indent_level, "", (const char *)data);
+    stabs_bc_str *bc_str = (stabs_bc_str *)bc;
+    yasm_xfree(bc_str->str);
+}
+
+static void
+stabs_bc_stab_print(const yasm_bytecode *bc, FILE *f, int indent_level)
+{
+    const stabs_bc_stab *bc_stab = (const stabs_bc_stab *)bc;
+    const stabs_stab *stab = bc_stab->stab;
+    const char *str = "";
+    fprintf(f, "%*s.stabs \"%s\", 0x%x, 0x%x, 0x%x, 0x%lx\n",
+           indent_level, "", str, stab->type, stab->other, stab->desc,
+           stab->bcvalue ? stab->bcvalue->offset : stab->value);
+}
+
+static void
+stabs_bc_str_print(const yasm_bytecode *bc, FILE *f, int indent_level)
+{
+    const stabs_bc_str *bc_str = (const stabs_bc_str *)bc;
+    fprintf(f, "%*s\"%s\"\n", indent_level, "", bc_str->str);
+}
+
+static yasm_bc_resolve_flags
+stabs_bc_stab_resolve(yasm_bytecode *bc, int save,
+                     yasm_calc_bc_dist_func calc_bc_dist)
+{
+    yasm_internal_error(N_("tried to resolve a stabs stab bytecode"));
+    /*@notreached@*/
+    return YASM_BC_RESOLVE_MIN_LEN;
+}
+
+static yasm_bc_resolve_flags
+stabs_bc_str_resolve(yasm_bytecode *bc, int save,
+                    yasm_calc_bc_dist_func calc_bc_dist)
+{
+    yasm_internal_error(N_("tried to resolve a stabs str bytecode"));
+    /*@notreached@*/
+    return YASM_BC_RESOLVE_MIN_LEN;
 }
 
 /* Define dbgfmt structure -- see dbgfmt.h for details */
@@ -443,8 +533,5 @@ yasm_dbgfmt yasm_stabs_LTX_dbgfmt = {
     stabs_dbgfmt_initialize,
     stabs_dbgfmt_cleanup,
     NULL /*stabs_dbgfmt_directive*/,
-    stabs_dbgfmt_generate,
-    stabs_dbgfmt_bc_data_output,
-    stabs_dbgfmt_bc_data_delete,
-    stabs_dbgfmt_bc_data_print
+    stabs_dbgfmt_generate
 };
index 6cbcdf4c4c8f3d3aedea970d4e709f034553b411..9efa84fa7a3ebf2b5b5a17123896e1a1ff085307 100644 (file)
 
 #define REGULAR_OUTBUF_SIZE    1024
 
-yasm_objfmt yasm_bin_LTX_objfmt;
+static void bin_section_data_destroy(/*@only@*/ void *d);
+static void bin_section_data_print(void *data, FILE *f, int indent_level);
+
+static const yasm_assoc_data_callback bin_section_data_callback = {
+    bin_section_data_destroy,
+    bin_section_data_print
+};
 static /*@dependent@*/ yasm_arch *cur_arch;
 
 
 static int
 bin_objfmt_initialize(/*@unused@*/ const char *in_filename,
                      /*@unused@*/ const char *obj_filename,
-                     /*@unused@*/ yasm_dbgfmt *df, yasm_arch *a,
-                     /*@unused@*/ const char *machine)
+                     /*@unused@*/ yasm_object *object,
+                     /*@unused@*/ yasm_dbgfmt *df, yasm_arch *a)
 {
     cur_arch = a;
     return 0;
@@ -68,7 +74,7 @@ bin_objfmt_align_section(yasm_section *sect, yasm_section *prevsect,
     /* Figure out the size of .text by looking at the last bytecode's offset
      * plus its length.  Add the start and size together to get the new start.
      */
-    last = yasm_bcs_last(yasm_section_get_bytecodes(prevsect));
+    last = yasm_section_bcs_last(prevsect);
     if (last)
        *prevsectlen = last->offset + last->len;
     else
@@ -79,7 +85,7 @@ bin_objfmt_align_section(yasm_section *sect, yasm_section *prevsect,
      * indicate padded size.  Because aignment is always a power of two, we
      * can use some bit trickery to do this easily.
      */
-    alignptr = yasm_section_get_of_data(sect);
+    alignptr = yasm_section_get_data(sect, &bin_section_data_callback);
     if (alignptr)
        align = *alignptr;
     else
@@ -114,14 +120,16 @@ bin_objfmt_expr_xform(/*@returned@*/ /*@only@*/ yasm_expr *e,
         * start expr + intnum(dist).
         */
        if (e->terms[i].type == YASM_EXPR_SYM &&
-           yasm_symrec_get_label(e->terms[i].data.sym, &sect, &precbc) &&
-           (dist = yasm_common_calc_bc_dist(sect, NULL, precbc))) {
+           yasm_symrec_get_label(e->terms[i].data.sym, &precbc) &&
+           (sect = yasm_bc_get_section(precbc)) &&
+           (dist = yasm_common_calc_bc_dist(yasm_section_bcs_first(sect),
+                                            precbc))) {
            const yasm_expr *start = yasm_section_get_start(sect);
            e->terms[i].type = YASM_EXPR_EXPR;
            e->terms[i].data.expn =
-               yasm_expr_new(YASM_EXPR_ADD,
-                             yasm_expr_expr(yasm_expr_copy(start)),
-                             yasm_expr_int(dist), e->line);
+               yasm_expr_create(YASM_EXPR_ADD,
+                                yasm_expr_expr(yasm_expr_copy(start)),
+                                yasm_expr_int(dist), e->line);
        }
     }
 
@@ -131,16 +139,12 @@ bin_objfmt_expr_xform(/*@returned@*/ /*@only@*/ yasm_expr *e,
 static int
 bin_objfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize,
                       size_t valsize, int shift,
-                      /*@unused@*/ unsigned long offset,
-                      /*@observer@*/ const yasm_section *sect,
-                      yasm_bytecode *bc, int rel, int warn,
-                      /*@unused@*/ /*@null@*/ void *d)
+                      /*@unused@*/ unsigned long offset, yasm_bytecode *bc,
+                      int rel, int warn, /*@unused@*/ /*@null@*/ void *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!
@@ -154,15 +158,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 cur_arch->floatnum_tobytes(flt, buf, destsize, valsize,
-                                         (unsigned int)shift, warn, bc->line);
+       return cur_arch->module->floatnum_tobytes(cur_arch, flt, buf, destsize,
+                                                 valsize, (unsigned int)shift,
+                                                 warn, bc->line);
     }
 
     /* Handle integer expressions */
     intn = yasm_expr_get_intnum(ep, NULL);
     if (intn)
-       return cur_arch->intnum_tobytes(intn, buf, destsize, valsize, shift,
-                                       bc, rel, warn, bc->line);
+       return cur_arch->module->intnum_tobytes(cur_arch, intn, buf, destsize,
+                                               valsize, shift, bc, rel, warn,
+                                               bc->line);
 
     /* Check for complex float expressions */
     if (yasm_expr__contains(*ep, YASM_EXPR_FLOAT)) {
@@ -188,8 +194,8 @@ bin_objfmt_output_bytecode(yasm_bytecode *bc, /*@null@*/ void *d)
 
     assert(info != NULL);
 
-    bigbuf = yasm_bc_tobytes(bc, info->buf, &size, &multiple, &gap, info->sect,
-                            info, bin_objfmt_output_expr, NULL, NULL);
+    bigbuf = yasm_bc_tobytes(bc, info->buf, &size, &multiple, &gap, info,
+                            bin_objfmt_output_expr, NULL);
 
     /* Don't bother doing anything else if size ended up being 0. */
     if (size == 0) {
@@ -225,8 +231,7 @@ bin_objfmt_output_bytecode(yasm_bytecode *bc, /*@null@*/ void *d)
 }
 
 static void
-bin_objfmt_output(FILE *f, yasm_sectionhead *sections,
-                 /*@unused@*/ int all_syms)
+bin_objfmt_output(FILE *f, yasm_object *object, /*@unused@*/ int all_syms)
 {
     /*@observer@*/ /*@null@*/ yasm_section *text, *data, *bss, *prevsect;
     /*@null@*/ yasm_expr *startexpr;
@@ -240,9 +245,9 @@ bin_objfmt_output(FILE *f, yasm_sectionhead *sections,
     info.f = f;
     info.buf = yasm_xmalloc(REGULAR_OUTBUF_SIZE);
 
-    text = yasm_sections_find_general(sections, ".text");
-    data = yasm_sections_find_general(sections, ".data");
-    bss = yasm_sections_find_general(sections, ".bss");
+    text = yasm_object_find_general(object, ".text");
+    data = yasm_object_find_general(object, ".data");
+    bss = yasm_object_find_general(object, ".bss");
 
     if (!text)
        yasm_internal_error(N_("No `.text' section in bin objfmt output"));
@@ -263,7 +268,7 @@ bin_objfmt_output(FILE *f, yasm_sectionhead *sections,
        return;
     }
     start = yasm_intnum_get_uint(startnum);
-    yasm_expr_delete(startexpr);
+    yasm_expr_destroy(startexpr);
     textstart = start;
 
     /* Align .data and .bss (if present) by adjusting their starts. */
@@ -273,9 +278,8 @@ bin_objfmt_output(FILE *f, yasm_sectionhead *sections,
     if (data) {
        start = bin_objfmt_align_section(data, prevsect, start, 4,
                                         prevsectlenptr, prevsectpadptr);
-       yasm_section_set_start(data,
-           yasm_expr_new_ident(yasm_expr_int(yasm_intnum_new_uint(start)), 0),
-           0);
+       yasm_section_set_start(data, yasm_expr_create_ident(
+           yasm_expr_int(yasm_intnum_create_uint(start)), 0), 0);
        datastart = start;
        prevsect = data;
        prevsectlenptr = &datalen;
@@ -284,16 +288,14 @@ bin_objfmt_output(FILE *f, yasm_sectionhead *sections,
     if (bss) {
        start = bin_objfmt_align_section(bss, prevsect, start, 4,
                                         prevsectlenptr, prevsectpadptr);
-       yasm_section_set_start(bss,
-           yasm_expr_new_ident(yasm_expr_int(yasm_intnum_new_uint(start)), 0),
-           0);
+       yasm_section_set_start(bss, yasm_expr_create_ident(
+           yasm_expr_int(yasm_intnum_create_uint(start)), 0), 0);
     }
 
     /* Output .text first. */
     info.sect = text;
     info.start = textstart;
-    yasm_bcs_traverse(yasm_section_get_bytecodes(text), &info,
-                     bin_objfmt_output_bytecode);
+    yasm_section_bcs_traverse(text, &info, bin_objfmt_output_bytecode);
 
     /* If .data is present, output it */
     if (data) {
@@ -306,8 +308,7 @@ bin_objfmt_output(FILE *f, yasm_sectionhead *sections,
        /* Output .data bytecodes */
        info.sect = data;
        info.start = datastart;
-       yasm_bcs_traverse(yasm_section_get_bytecodes(data), &info,
-                         bin_objfmt_output_bytecode);
+       yasm_section_bcs_traverse(data, &info, bin_objfmt_output_bytecode);
     }
 
     /* If .bss is present, check it for non-reserve bytecodes */
@@ -322,11 +323,10 @@ bin_objfmt_cleanup(void)
 }
 
 static /*@observer@*/ /*@null@*/ yasm_section *
-bin_objfmt_sections_switch(yasm_sectionhead *headp,
-                          yasm_valparamhead *valparams,
-                          /*@unused@*/ /*@null@*/
-                          yasm_valparamhead *objext_valparams,
-                          unsigned long lindex)
+bin_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
+                         /*@unused@*/ /*@null@*/
+                         yasm_valparamhead *objext_valparams,
+                         unsigned long line)
 {
     yasm_valparam *vp;
     yasm_section *retval;
@@ -351,7 +351,7 @@ bin_objfmt_sections_switch(yasm_sectionhead *headp,
            resonly = 1;
        } else {
            /* other section names not recognized. */
-           yasm__error(lindex, N_("segment name `%s' not recognized"),
+           yasm__error(line, N_("segment name `%s' not recognized"),
                        sectname);
            return NULL;
        }
@@ -363,7 +363,7 @@ bin_objfmt_sections_switch(yasm_sectionhead *headp,
                unsigned long bitcnt;
 
                if (strcmp(sectname, ".text") == 0) {
-                   yasm__error(lindex,
+                   yasm__error(line,
                        N_("cannot specify an alignment to the `%s' section"),
                        sectname);
                    return NULL;
@@ -371,7 +371,7 @@ bin_objfmt_sections_switch(yasm_sectionhead *headp,
                
                align = yasm_expr_get_intnum(&vp->param, NULL);
                if (!align) {
-                   yasm__error(lindex,
+                   yasm__error(line,
                                N_("argument to `%s' is not a power of two"),
                                vp->val);
                    return NULL;
@@ -383,7 +383,7 @@ bin_objfmt_sections_switch(yasm_sectionhead *headp,
                 */
                BitCount(bitcnt, alignval);
                if (bitcnt > 1) {
-                   yasm__error(lindex,
+                   yasm__error(line,
                                N_("argument to `%s' is not a power of two"),
                                vp->val);
                    return NULL;
@@ -393,21 +393,23 @@ bin_objfmt_sections_switch(yasm_sectionhead *headp,
            }
        }
 
-       retval = yasm_sections_switch_general(headp, sectname,
-           yasm_expr_new_ident(yasm_expr_int(yasm_intnum_new_uint(start)),
-                               lindex), resonly, &isnew, lindex);
+       retval = yasm_object_get_general(object, sectname,
+           yasm_expr_create_ident(
+               yasm_expr_int(yasm_intnum_create_uint(start)), line), resonly,
+           &isnew, line);
 
        if (isnew) {
            if (have_alignval) {
                unsigned long *data = yasm_xmalloc(sizeof(unsigned long));
                *data = alignval;
-               yasm_section_set_of_data(retval, &yasm_bin_LTX_objfmt, data);
+               yasm_section_add_data(retval, &bin_section_data_callback,
+                                     data);
            }
 
-           yasm_symrec_define_label(sectname, retval, (yasm_bytecode *)NULL,
-                                    1, lindex);
+           yasm_symtab_define_label(yasm_object_get_symtab(object), sectname,
+                                    yasm_section_bcs_first(retval), 1, line);
        } else if (have_alignval)
-           yasm__warning(YASM_WARN_GENERAL, lindex,
+           yasm__warning(YASM_WARN_GENERAL, line,
                N_("alignment value ignored on section redeclaration"));
 
        return retval;
@@ -416,7 +418,7 @@ bin_objfmt_sections_switch(yasm_sectionhead *headp,
 }
 
 static void
-bin_objfmt_section_data_delete(/*@only@*/ void *d)
+bin_section_data_destroy(/*@only@*/ void *d)
 {
     yasm_xfree(d);
 }
@@ -425,10 +427,10 @@ static void
 bin_objfmt_common_declare(/*@unused@*/ yasm_symrec *sym,
                          /*@only@*/ yasm_expr *size, /*@unused@*/ /*@null@*/
                          yasm_valparamhead *objext_valparams,
-                         unsigned long lindex)
+                         unsigned long line)
 {
-    yasm_expr_delete(size);
-    yasm__error(lindex,
+    yasm_expr_destroy(size);
+    yasm__error(line,
        N_("binary object format does not support common variables"));
 }
 
@@ -436,7 +438,7 @@ static int
 bin_objfmt_directive(const char *name, yasm_valparamhead *valparams,
                     /*@unused@*/ /*@null@*/
                     yasm_valparamhead *objext_valparams,
-                    yasm_sectionhead *headp, unsigned long lindex)
+                    yasm_object *object, unsigned long line)
 {
     yasm_section *sect;
     yasm_valparam *vp;
@@ -447,24 +449,24 @@ bin_objfmt_directive(const char *name, yasm_valparamhead *valparams,
        /* ORG takes just a simple integer as param */
        vp = yasm_vps_first(valparams);
        if (vp->val)
-           start = yasm_expr_new_ident(yasm_expr_sym(
-                       yasm_symrec_use(vp->val, lindex)), lindex);
+           start = yasm_expr_create_ident(yasm_expr_sym(yasm_symtab_use(
+               yasm_object_get_symtab(object), vp->val, line)), line);
        else if (vp->param) {
            start = vp->param;
            vp->param = NULL;   /* Don't let valparams delete it */
        }
 
        if (!start) {
-           yasm__error(lindex, N_("argument to ORG must be expression"));
+           yasm__error(line, N_("argument to ORG must be expression"));
            return 0;
        }
 
        /* ORG changes the start of the .text section */
-       sect = yasm_sections_find_general(headp, ".text");
+       sect = yasm_object_find_general(object, ".text");
        if (!sect)
            yasm_internal_error(
                N_("bin objfmt: .text section does not exist before ORG is called?"));
-       yasm_section_set_start(sect, start, lindex);
+       yasm_section_set_start(sect, start, line);
 
        return 0;           /* directive recognized */
     } else
@@ -472,7 +474,7 @@ bin_objfmt_directive(const char *name, yasm_valparamhead *valparams,
 }
 
 static void
-bin_objfmt_section_data_print(FILE *f, int indent_level, void *data)
+bin_section_data_print(void *data, FILE *f, int indent_level)
 {
     fprintf(f, "%*salign=%ld\n", indent_level, "", *((unsigned long *)data));
 }
@@ -497,15 +499,9 @@ yasm_objfmt yasm_bin_LTX_objfmt = {
     bin_objfmt_initialize,
     bin_objfmt_output,
     bin_objfmt_cleanup,
-    bin_objfmt_sections_switch,
-    bin_objfmt_section_data_delete,
-    bin_objfmt_section_data_print,
+    bin_objfmt_section_switch,
     NULL /*bin_objfmt_extern_declare*/,
     NULL /*bin_objfmt_global_declare*/,
     bin_objfmt_common_declare,
-    NULL /*bin_objfmt_symrec_data_delete*/,
-    NULL /*bin_objfmt_symrec_data_print*/,
-    bin_objfmt_directive,
-    NULL /*bin_objfmt_bc_objfmt_data_delete*/,
-    NULL /*bin_objfmt_bc_objfmt_data_print*/
+    bin_objfmt_directive
 };
index 73dd43baf4fb0d0a9ad02396b4b0a8efc2c2567e..625fed6c06b5004c05f2999698755aa231f32482 100644 (file)
@@ -156,10 +156,25 @@ typedef struct coff_objfmt_output_info {
     unsigned long addr;            /* start of next section */
 } coff_objfmt_output_info;
 
+static void coff_section_data_destroy(/*@only@*/ void *d);
+static void coff_section_data_print(void *data, FILE *f, int indent_level);
+
+static const yasm_assoc_data_callback coff_section_data_cb = {
+    coff_section_data_destroy,
+    coff_section_data_print
+};
+
+static void coff_symrec_data_destroy(/*@only@*/ void *d);
+static void coff_symrec_data_print(void *data, FILE *f, int indent_level);
+
+static const yasm_assoc_data_callback coff_symrec_data_cb = {
+    coff_symrec_data_destroy,
+    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 */
 
-yasm_objfmt yasm_coff_LTX_objfmt;
 static /*@dependent@*/ yasm_arch *cur_arch;
 
 /* Set nonzero for win32 output. */
@@ -178,14 +193,14 @@ coff_objfmt_symtab_append(yasm_symrec *sym, coff_symrec_sclass sclass,
     if (STAILQ_EMPTY(&coff_symtab))
        yasm_internal_error(N_("empty COFF symbol table"));
     entry = STAILQ_LAST(&coff_symtab, coff_symtab_entry, link);
-    sym_data_prev = yasm_symrec_get_of_data(entry->sym);
+    sym_data_prev = yasm_symrec_get_data(entry->sym, &coff_symrec_data_cb);
     assert(sym_data_prev != NULL);
 
     sym_data = yasm_xmalloc(sizeof(coff_symrec_data));
     sym_data->index = sym_data_prev->index + entry->numaux + 1;
     sym_data->sclass = sclass;
     sym_data->size = size;
-    yasm_symrec_set_of_data(sym, &yasm_coff_LTX_objfmt, sym_data);
+    yasm_symrec_add_data(sym, &coff_symrec_data_cb, sym_data);
 
     entry = yasm_xmalloc(sizeof(coff_symtab_entry) +
                         (numaux-1)*sizeof(coff_symtab_auxent));
@@ -200,7 +215,7 @@ 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)
 {
-    if (!yasm_symrec_get_of_data(sym))
+    if (!yasm_symrec_get_data(sym, &coff_symrec_data_cb))
        coff_objfmt_symtab_append(sym, COFF_SCL_STAT, NULL, 0,
                                  COFF_SYMTAB_AUX_NONE);
     return 1;
@@ -209,8 +224,8 @@ coff_objfmt_append_local_sym(yasm_symrec *sym, /*@unused@*/ /*@null@*/ void *d)
 static int
 coff_common_initialize(const char *in_filename,
                       /*@unused@*/ const char *obj_filename,
-                      /*@unused@*/ yasm_dbgfmt *df, yasm_arch *a,
-                      const char *machine)
+                      yasm_object *object, /*@unused@*/ yasm_dbgfmt *df,
+                      yasm_arch *a)
 {
     yasm_symrec *filesym;
     coff_symrec_data *data;
@@ -219,8 +234,8 @@ coff_common_initialize(const char *in_filename,
     cur_arch = a;
 
     /* Only support x86 arch, x86 machine */
-    if (yasm__strcasecmp(cur_arch->keyword, "x86") != 0 ||
-       yasm__strcasecmp(machine, "x86") != 0)
+    if (yasm__strcasecmp(cur_arch->module->keyword, "x86") != 0 ||
+       yasm__strcasecmp(cur_arch->module->get_machine(cur_arch), "x86") != 0)
        return 1;
 
     coff_objfmt_parse_scnum = 1;    /* section numbering starts at 1 */
@@ -230,8 +245,10 @@ coff_common_initialize(const char *in_filename,
     data->index = 0;
     data->sclass = COFF_SCL_FILE;
     data->size = NULL;
-    filesym = yasm_symrec_define_label(".file", NULL, NULL, 0, 0);
-    yasm_symrec_set_of_data(filesym, &yasm_coff_LTX_objfmt, data);
+    /* 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);
+    yasm_symrec_add_data(filesym, &coff_symrec_data_cb, data);
 
     entry = yasm_xmalloc(sizeof(coff_symtab_entry));
     entry->sym = filesym;
@@ -245,18 +262,18 @@ coff_common_initialize(const char *in_filename,
 
 static int
 coff_objfmt_initialize(const char *in_filename, const char *obj_filename,
-                      yasm_dbgfmt *df, yasm_arch *a, const char *machine)
+                      yasm_object *object, yasm_dbgfmt *df, yasm_arch *a)
 {
     win32 = 0;
-    return coff_common_initialize(in_filename, obj_filename, df, a, machine);
+    return coff_common_initialize(in_filename, obj_filename, object, df, a);
 }
 
 static int
 win32_objfmt_initialize(const char *in_filename, const char *obj_filename,
-                       yasm_dbgfmt *df, yasm_arch *a, const char *machine)
+                       yasm_object *object, yasm_dbgfmt *df, yasm_arch *a)
 {
     win32 = 1;
-    return coff_common_initialize(in_filename, obj_filename, df, a, machine);
+    return coff_common_initialize(in_filename, obj_filename, object, df, a);
 }
 
 static int
@@ -271,11 +288,11 @@ coff_objfmt_set_section_addr(yasm_section *sect, /*@null@*/ void *d)
        return 0;
 
     assert(info != NULL);
-    csd = yasm_section_get_of_data(sect);
+    csd = yasm_section_get_data(sect, &coff_section_data_cb);
     assert(csd != NULL);
 
     csd->addr = info->addr;
-    last = yasm_bcs_last(yasm_section_get_bytecodes(sect));
+    last = yasm_section_bcs_last(sect);
     if (last)
        info->addr += last->offset + last->len;
 
@@ -285,7 +302,6 @@ coff_objfmt_set_section_addr(yasm_section *sect, /*@null@*/ void *d)
 static int
 coff_objfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize,
                        size_t valsize, int shift, unsigned long offset,
-                       /*@observer@*/ const yasm_section *sect,
                        yasm_bytecode *bc, int rel, int warn,
                        /*@null@*/ void *d)
 {
@@ -305,8 +321,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 cur_arch->floatnum_tobytes(flt, buf, destsize, valsize,
-                                         (unsigned int)shift, warn, bc->line);
+       return cur_arch->module->floatnum_tobytes(cur_arch, flt, buf, destsize,
+                                                 valsize, (unsigned int)shift,
+                                                 warn, bc->line);
     }
 
     /* Handle integer expressions, with relocation if necessary */
@@ -331,23 +348,25 @@ coff_objfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize,
            if (!win32) {
                /*@dependent@*/ /*@null@*/ coff_symrec_data *csymd;
 
-               csymd = yasm_symrec_get_of_data(sym);
+               csymd = yasm_symrec_get_data(sym, &coff_symrec_data_cb);
                assert(csymd != NULL);
-               *ep = yasm_expr_new(YASM_EXPR_ADD, yasm_expr_expr(*ep),
-                                   yasm_expr_expr(yasm_expr_copy(csymd->size)),
-                                   csymd->size->line);
+               *ep = yasm_expr_create(YASM_EXPR_ADD, yasm_expr_expr(*ep),
+                   yasm_expr_expr(yasm_expr_copy(csymd->size)),
+                   csymd->size->line);
                *ep = yasm_expr_simplify(*ep, yasm_common_calc_bc_dist);
            }
        } else if (!(vis & YASM_SYM_EXTERN)) {
            /* Local symbols need relocation to their section's start */
-           if (yasm_symrec_get_label(sym, &label_sect, &label_precbc)) {
+           if (yasm_symrec_get_label(sym, &label_precbc)) {
                /*@null@*/ coff_section_data *label_csd;
-               label_csd = yasm_section_get_of_data(label_sect);
+               label_sect = yasm_bc_get_section(label_precbc);
+               label_csd = yasm_section_get_data(label_sect,
+                                                 &coff_section_data_cb);
                assert(label_csd != NULL);
                reloc->sym = label_csd->sym;
                if (COFF_SET_VMA)
-                   *ep = yasm_expr_new(YASM_EXPR_ADD, yasm_expr_expr(*ep),
-                       yasm_expr_int(yasm_intnum_new_uint(label_csd->addr)),
+                   *ep = yasm_expr_create(YASM_EXPR_ADD, yasm_expr_expr(*ep),
+                       yasm_expr_int(yasm_intnum_create_uint(label_csd->addr)),
                        (*ep)->line);
            }
        }
@@ -360,15 +379,14 @@ coff_objfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize,
             * (really $+$.len) in.
             */
            if (win32)
-               *ep = yasm_expr_new(YASM_EXPR_ADD, yasm_expr_expr(*ep),
-                   yasm_expr_sym(yasm_symrec_define_label("$", info->sect, bc,
-                                                          0, (*ep)->line)),
+               *ep = yasm_expr_create(YASM_EXPR_ADD, yasm_expr_expr(*ep),
+                   yasm_expr_sym(yasm_symtab_define_label2("$", bc,
+                                                           0, (*ep)->line)),
                    (*ep)->line);
            else
-               *ep = yasm_expr_new(YASM_EXPR_ADD, yasm_expr_expr(*ep),
-                   yasm_expr_sym(yasm_symrec_define_label("$$", info->sect,
-                                                          NULL, 0,
-                                                          (*ep)->line)),
+               *ep = yasm_expr_create(YASM_EXPR_ADD, yasm_expr_expr(*ep),
+                   yasm_expr_sym(yasm_symtab_define_label2("$$",
+                       yasm_section_bcs_first(info->sect), 0, (*ep)->line)),
                    (*ep)->line);
            *ep = yasm_expr_simplify(*ep, yasm_common_calc_bc_dist);
        } else
@@ -378,8 +396,9 @@ coff_objfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize,
     }
     intn = yasm_expr_get_intnum(ep, NULL);
     if (intn)
-       return cur_arch->intnum_tobytes(intn, buf, destsize, valsize, shift,
-                                       bc, rel, warn, bc->line);
+       return cur_arch->module->intnum_tobytes(cur_arch, intn, buf, destsize,
+                                               valsize, shift, bc, rel, warn,
+                                               bc->line);
 
     /* Check for complex float expressions */
     if (yasm_expr__contains(*ep, YASM_EXPR_FLOAT)) {
@@ -403,8 +422,8 @@ coff_objfmt_output_bytecode(yasm_bytecode *bc, /*@null@*/ void *d)
 
     assert(info != NULL);
 
-    bigbuf = yasm_bc_tobytes(bc, info->buf, &size, &multiple, &gap, info->sect,
-                            info, coff_objfmt_output_expr, NULL, NULL);
+    bigbuf = yasm_bc_tobytes(bc, info->buf, &size, &multiple, &gap, info,
+                            coff_objfmt_output_expr, NULL);
 
     /* Don't bother doing anything else if size ended up being 0. */
     if (size == 0) {
@@ -454,24 +473,21 @@ coff_objfmt_output_section(yasm_section *sect, /*@null@*/ void *d)
        return 0;
 
     assert(info != NULL);
-    csd = yasm_section_get_of_data(sect);
+    csd = yasm_section_get_data(sect, &coff_section_data_cb);
     assert(csd != NULL);
 
     csd->addr = info->addr;
 
     if ((csd->flags & COFF_STYP_STD_MASK) == COFF_STYP_BSS) {
-       /*@null@*/ yasm_bytecode *last =
-           yasm_bcs_last(yasm_section_get_bytecodes(sect));
+       yasm_bytecode *last = yasm_section_bcs_last(sect);
 
        /* Don't output BSS sections.
         * TODO: Check for non-reserve bytecodes?
         */
        pos = 0;    /* position = 0 because it's not in the file */
-       if (last)
-           csd->size = last->offset + last->len;
+       csd->size = last->offset + last->len;
     } else {
-       /*@null@*/ yasm_bytecode *last =
-           yasm_bcs_last(yasm_section_get_bytecodes(sect));
+       yasm_bytecode *last = yasm_section_bcs_last(sect);
 
        pos = ftell(info->f);
        if (pos == -1) {
@@ -482,8 +498,7 @@ coff_objfmt_output_section(yasm_section *sect, /*@null@*/ void *d)
 
        info->sect = sect;
        info->csd = csd;
-       yasm_bcs_traverse(yasm_section_get_bytecodes(sect), info,
-                         coff_objfmt_output_bytecode);
+       yasm_section_bcs_traverse(sect, info, coff_objfmt_output_bytecode);
 
        /* Sanity check final section size */
        if (csd->size != (last->offset + last->len))
@@ -514,7 +529,7 @@ coff_objfmt_output_section(yasm_section *sect, /*@null@*/ void *d)
        unsigned char *localbuf = info->buf;
        /*@null@*/ coff_symrec_data *csymd;
 
-       csymd = yasm_symrec_get_of_data(reloc->sym);
+       csymd = yasm_symrec_get_data(reloc->sym, &coff_symrec_data_cb);
        if (!csymd)
            yasm_internal_error(
                N_("coff: no symbol data for relocated symbol"));
@@ -540,7 +555,7 @@ coff_objfmt_output_secthead(yasm_section *sect, /*@null@*/ void *d)
        return 0;
 
     assert(info != NULL);
-    csd = yasm_section_get_of_data(sect);
+    csd = yasm_section_get_data(sect, &coff_section_data_cb);
     assert(csd != NULL);
 
     localbuf = info->buf;
@@ -570,7 +585,7 @@ coff_objfmt_output_secthead(yasm_section *sect, /*@null@*/ void *d)
 }
 
 static void
-coff_objfmt_output(FILE *f, yasm_sectionhead *sections, int all_syms)
+coff_objfmt_output(FILE *f, yasm_object *object, int all_syms)
 {
     coff_objfmt_output_info info;
     unsigned char *localbuf;
@@ -598,18 +613,20 @@ coff_objfmt_output(FILE *f, yasm_sectionhead *sections, int all_syms)
         * addends in the generated code.
         */
        info.addr = 0;
-       if (yasm_sections_traverse(sections, &info,
-                                  coff_objfmt_set_section_addr))
+       if (yasm_object_sections_traverse(object, &info,
+                                         coff_objfmt_set_section_addr))
            return;
     }
     info.addr = 0;
-    if (yasm_sections_traverse(sections, &info, coff_objfmt_output_section))
+    if (yasm_object_sections_traverse(object, &info,
+                                     coff_objfmt_output_section))
        return;
 
     /* Symbol table */
     if (all_syms) {
        /* Need to put all local syms into COFF symbol table */
-       yasm_symrec_traverse(NULL, coff_objfmt_append_local_sym);
+       yasm_symtab_traverse(yasm_object_get_symtab(object), NULL,
+                            coff_objfmt_append_local_sym);
     }
     pos = ftell(f);
     if (pos == -1) {
@@ -633,18 +650,22 @@ coff_objfmt_output(FILE *f, yasm_sectionhead *sections, int all_syms)
        unsigned long nreloc = 0;   /* for sect auxent */
 
        /* Get symrec's of_data (needed for storage class) */
-       csymd = yasm_symrec_get_of_data(entry->sym);
+       csymd = yasm_symrec_get_data(entry->sym, &coff_symrec_data_cb);
        if (!csymd)
            yasm_internal_error(N_("coff: expected sym data to be present"));
 
        /* Look at symrec for value/scnum/etc. */
-       if (yasm_symrec_get_label(entry->sym, &sect, &precbc)) {
+       if (yasm_symrec_get_label(entry->sym, &precbc)) {
+           if (precbc)
+               sect = yasm_bc_get_section(precbc);
+           else
+               sect = NULL;
            /* it's a label: get value and offset.
             * If there is not a section, leave as debugging symbol.
             */
            if (sect) {
                /*@dependent@*/ /*@null@*/ coff_section_data *csectd;
-               csectd = yasm_section_get_of_data(sect);
+               csectd = yasm_section_get_data(sect, &coff_section_data_cb);
                if (csectd) {
                    scnum = csectd->scnum;
                    scnlen = csectd->size;
@@ -662,7 +683,7 @@ coff_objfmt_output(FILE *f, yasm_sectionhead *sections, int all_syms)
                            N_("absolute section start not an integer expression"));
                    else
                        value = yasm_intnum_get_uint(intn);
-                   yasm_expr_delete(abs_start);
+                   yasm_expr_destroy(abs_start);
 
                    scnum = 0xffff;     /* -1 = absolute symbol */
                } else
@@ -681,7 +702,7 @@ coff_objfmt_output(FILE *f, yasm_sectionhead *sections, int all_syms)
                        N_("global EQU value not an integer expression"));
            } else
                value = yasm_intnum_get_uint(intn);
-           yasm_expr_delete(equ_val_copy);
+           yasm_expr_destroy(equ_val_copy);
 
            scnum = 0xffff;     /* -1 = absolute symbol */
        } else {
@@ -787,7 +808,7 @@ coff_objfmt_output(FILE *f, yasm_sectionhead *sections, int all_syms)
                    |(all_syms?0:COFF_F_LSYMS));
     fwrite(info.buf, 20, 1, f);
 
-    yasm_sections_traverse(sections, &info, coff_objfmt_output_secthead);
+    yasm_object_sections_traverse(object, &info, coff_objfmt_output_secthead);
 
     yasm_xfree(info.buf);
 }
@@ -809,11 +830,10 @@ coff_objfmt_cleanup(void)
 }
 
 static /*@observer@*/ /*@null@*/ yasm_section *
-coff_objfmt_sections_switch(yasm_sectionhead *headp,
-                           yasm_valparamhead *valparams,
+coff_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
                            /*@unused@*/ /*@null@*/
                            yasm_valparamhead *objext_valparams,
-                           unsigned long lindex)
+                           unsigned long line)
 {
     yasm_valparam *vp = yasm_vps_first(valparams);
     yasm_section *retval;
@@ -861,7 +881,7 @@ coff_objfmt_sections_switch(yasm_sectionhead *headp,
        /* TODO: win32 format supports >8 character section names in object
         * files via "/nnnn" (where nnnn is decimal offset into string table).
         */
-       yasm__warning(YASM_WARN_GENERAL, lindex,
+       yasm__warning(YASM_WARN_GENERAL, line,
            N_("COFF section names limited to 8 characters: truncating"));
        sectname[8] = '\0';
     }
@@ -887,7 +907,7 @@ coff_objfmt_sections_switch(yasm_sectionhead *headp,
        if (win32)
            flags |= COFF_STYP_READ | (4<<COFF_STYP_ALIGN_SHIFT); /* align=8 */
        else
-           yasm__warning(YASM_WARN_GENERAL, lindex,
+           yasm__warning(YASM_WARN_GENERAL, line,
                N_("Standard COFF does not support read-only data sections"));
     } else {
        /* Default to code */
@@ -942,7 +962,7 @@ coff_objfmt_sections_switch(yasm_sectionhead *headp,
 
                align = yasm_expr_get_intnum(&vp->param, NULL);
                if (!align) {
-                   yasm__error(lindex,
+                   yasm__error(line,
                                N_("argument to `%s' is not a power of two"),
                                vp->val);
                    return NULL;
@@ -954,7 +974,7 @@ coff_objfmt_sections_switch(yasm_sectionhead *headp,
                 */
                BitCount(bitcnt, addralign);
                if (bitcnt > 1) {
-                   yasm__error(lindex,
+                   yasm__error(line,
                                N_("argument to `%s' is not a power of two"),
                                vp->val);
                    return NULL;
@@ -962,7 +982,7 @@ coff_objfmt_sections_switch(yasm_sectionhead *headp,
 
                /* Check to see if alignment is supported size */
                if (addralign > 8192) {
-                   yasm__error(lindex,
+                   yasm__error(line,
                        N_("Win32 does not support alignments > 8192"));
                    return NULL;
                }
@@ -976,16 +996,16 @@ coff_objfmt_sections_switch(yasm_sectionhead *headp,
            } else
                win32warn = 1;
        } else
-           yasm__warning(YASM_WARN_GENERAL, lindex,
+           yasm__warning(YASM_WARN_GENERAL, line,
                          N_("Unrecognized qualifier `%s'"), vp->val);
 
        if (win32warn)
-           yasm__warning(YASM_WARN_GENERAL, lindex,
+           yasm__warning(YASM_WARN_GENERAL, line,
                N_("Standard COFF does not support qualifier `%s'"), vp->val);
     }
 
-    retval = yasm_sections_switch_general(headp, sectname, 0, resonly, &isnew,
-                                         lindex);
+    retval = yasm_object_get_general(object, sectname, 0, resonly, &isnew,
+                                    line);
 
     if (isnew) {
        coff_section_data *data;
@@ -1000,21 +1020,22 @@ coff_objfmt_sections_switch(yasm_sectionhead *headp,
        data->relptr = 0;
        data->nreloc = 0;
        STAILQ_INIT(&data->relocs);
-       yasm_section_set_of_data(retval, &yasm_coff_LTX_objfmt, data);
+       yasm_section_add_data(retval, &coff_section_data_cb, data);
 
-       sym = yasm_symrec_define_label(sectname, retval, (yasm_bytecode *)NULL,
-                                      1, lindex);
+       sym =
+           yasm_symtab_define_label(yasm_object_get_symtab(object), sectname,
+                                    yasm_section_bcs_first(retval), 1, line);
        coff_objfmt_symtab_append(sym, COFF_SCL_STAT, NULL, 1,
                                  COFF_SYMTAB_AUX_SECT);
        data->sym = sym;
     } else if (flags_override)
-       yasm__warning(YASM_WARN_GENERAL, lindex,
+       yasm__warning(YASM_WARN_GENERAL, line,
                      N_("section flags ignored on section redeclaration"));
     return retval;
 }
 
 static void
-coff_objfmt_section_data_delete(/*@only@*/ void *data)
+coff_section_data_destroy(void *data)
 {
     coff_section_data *csd = (coff_section_data *)data;
     coff_reloc *r1, *r2;
@@ -1028,14 +1049,14 @@ coff_objfmt_section_data_delete(/*@only@*/ void *data)
 }
 
 static void
-coff_objfmt_section_data_print(FILE *f, int indent_level, void *data)
+coff_section_data_print(void *data, FILE *f, int indent_level)
 {
     coff_section_data *csd = (coff_section_data *)data;
     coff_reloc *reloc;
     unsigned long relocnum = 0;
 
     fprintf(f, "%*ssym=\n", indent_level, "");
-    yasm_symrec_print(f, indent_level+1, csd->sym);
+    yasm_symrec_print(csd->sym, f, indent_level+1);
     fprintf(f, "%*sscnum=%d\n", indent_level, "", csd->scnum);
     fprintf(f, "%*sflags=", indent_level, "");
     switch (csd->flags & COFF_STYP_STD_MASK) {
@@ -1061,7 +1082,7 @@ coff_objfmt_section_data_print(FILE *f, int indent_level, void *data)
     STAILQ_FOREACH(reloc, &csd->relocs, link) {
        fprintf(f, "%*sReloc %lu:\n", indent_level+1, "", relocnum++);
        fprintf(f, "%*ssym=\n", indent_level+2, "");
-       yasm_symrec_print(f, indent_level+3, reloc->sym);
+       yasm_symrec_print(reloc->sym, f, indent_level+3);
        fprintf(f, "%*stype=", indent_level+2, "");
        switch (reloc->type) {
            case COFF_RELOC_ADDR32:
@@ -1077,7 +1098,7 @@ coff_objfmt_section_data_print(FILE *f, int indent_level, void *data)
 static void
 coff_objfmt_extglob_declare(yasm_symrec *sym, /*@unused@*/
                            /*@null@*/ yasm_valparamhead *objext_valparams,
-                           /*@unused@*/ unsigned long lindex)
+                           /*@unused@*/ unsigned long line)
 {
     coff_objfmt_symtab_append(sym, COFF_SCL_EXT, NULL, 0,
                              COFF_SYMTAB_AUX_NONE);
@@ -1087,23 +1108,23 @@ static void
 coff_objfmt_common_declare(yasm_symrec *sym, /*@only@*/ yasm_expr *size,
                           /*@unused@*/ /*@null@*/
                           yasm_valparamhead *objext_valparams,
-                          /*@unused@*/ unsigned long lindex)
+                          /*@unused@*/ unsigned long line)
 {
     coff_objfmt_symtab_append(sym, COFF_SCL_EXT, size, 0,
                              COFF_SYMTAB_AUX_NONE);
 }
 
 static void
-coff_objfmt_symrec_data_delete(/*@only@*/ void *data)
+coff_symrec_data_destroy(void *data)
 {
     coff_symrec_data *csymd = (coff_symrec_data *)data;
     if (csymd->size)
-       yasm_expr_delete(csymd->size);
+       yasm_expr_destroy(csymd->size);
     yasm_xfree(data);
 }
 
 static void
-coff_objfmt_symrec_data_print(FILE *f, int indent_level, void *data)
+coff_symrec_data_print(void *data, FILE *f, int indent_level)
 {
     coff_symrec_data *csd = (coff_symrec_data *)data;
 
@@ -1111,7 +1132,7 @@ coff_objfmt_symrec_data_print(FILE *f, int indent_level, void *data)
     fprintf(f, "%*ssclass=%d\n", indent_level, "", csd->sclass);
     fprintf(f, "%*ssize=", indent_level, "");
     if (csd->size)
-       yasm_expr_print(f, csd->size);
+       yasm_expr_print(csd->size, f);
     else
        fprintf(f, "nil");
     fprintf(f, "\n");
@@ -1122,8 +1143,8 @@ coff_objfmt_directive(/*@unused@*/ const char *name,
                      /*@unused@*/ yasm_valparamhead *valparams,
                      /*@unused@*/ /*@null@*/
                      yasm_valparamhead *objext_valparams,
-                     /*@unused@*/ yasm_sectionhead *headp,
-                     /*@unused@*/ unsigned long lindex)
+                     /*@unused@*/ yasm_object *object,
+                     /*@unused@*/ unsigned long line)
 {
     return 1;  /* no objfmt directives */
 }
@@ -1148,17 +1169,11 @@ yasm_objfmt yasm_coff_LTX_objfmt = {
     coff_objfmt_initialize,
     coff_objfmt_output,
     coff_objfmt_cleanup,
-    coff_objfmt_sections_switch,
-    coff_objfmt_section_data_delete,
-    coff_objfmt_section_data_print,
+    coff_objfmt_section_switch,
     coff_objfmt_extglob_declare,
     coff_objfmt_extglob_declare,
     coff_objfmt_common_declare,
-    coff_objfmt_symrec_data_delete,
-    coff_objfmt_symrec_data_print,
-    coff_objfmt_directive,
-    NULL /*coff_objfmt_bc_objfmt_data_delete*/,
-    NULL /*coff_objfmt_bc_objfmt_data_print*/
+    coff_objfmt_directive
 };
 
 /* Define objfmt structure -- see objfmt.h for details */
@@ -1174,15 +1189,9 @@ yasm_objfmt yasm_win32_LTX_objfmt = {
     win32_objfmt_initialize,
     coff_objfmt_output,
     coff_objfmt_cleanup,
-    coff_objfmt_sections_switch,
-    coff_objfmt_section_data_delete,
-    coff_objfmt_section_data_print,
+    coff_objfmt_section_switch,
     coff_objfmt_extglob_declare,
     coff_objfmt_extglob_declare,
     coff_objfmt_common_declare,
-    coff_objfmt_symrec_data_delete,
-    coff_objfmt_symrec_data_print,
-    coff_objfmt_directive,
-    NULL /*coff_objfmt_bc_objfmt_data_delete*/,
-    NULL /*coff_objfmt_bc_objfmt_data_print*/
+    coff_objfmt_directive
 };
index 0b3efff974f185e394785ae3efc86ce655f2b859..aa62cf3d15656a7538b71c0a1e7e464085c31d22 100644 (file)
 #include <libyasm.h>
 
 
-yasm_objfmt yasm_dbg_LTX_objfmt;
+static void symrec_data_destroy(/*@only@*/ void *data);
+static void symrec_data_print(void *data, FILE *f, int indent_level);
+
+static const yasm_assoc_data_callback symrec_data_callback = {
+    symrec_data_destroy,
+    symrec_data_print
+};
 
 /* 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
@@ -47,7 +53,7 @@ static FILE *dbg_objfmt_file;
 
 static int
 dbg_objfmt_initialize(const char *in_filename, const char *obj_filename,
-                     yasm_dbgfmt *df, yasm_arch *a, const char *machine)
+                     yasm_object *object, yasm_dbgfmt *df, yasm_arch *a)
 {
     dbg_objfmt_file = fopen(obj_filename, "wt");
     if (!dbg_objfmt_file) {
@@ -55,20 +61,19 @@ dbg_objfmt_initialize(const char *in_filename, const char *obj_filename,
        return 0;
     }
     fprintf(dbg_objfmt_file,
-           "initialize(\"%s\", \"%s\", %s dbgfmt, %s arch, \"%s\")\n",
-           in_filename, obj_filename, df->keyword, a->keyword, machine);
+           "initialize(\"%s\", \"%s\", %s dbgfmt, %s arch)\n",
+           in_filename, obj_filename, df->keyword, a->module->keyword);
     return 0;
 }
 
 static void
-dbg_objfmt_output(/*@unused@*/ FILE *f, yasm_sectionhead *sections,
-                 int all_syms)
+dbg_objfmt_output(/*@unused@*/ FILE *f, yasm_object *object, int all_syms)
 {
-    fprintf(dbg_objfmt_file, "output(f, sections->\n");
-    yasm_sections_print(dbg_objfmt_file, 1, sections);
+    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_symrec_print_all(dbg_objfmt_file, 1);
+    yasm_symtab_print(yasm_object_get_symtab(object), dbg_objfmt_file, 1);
 }
 
 static void
@@ -78,30 +83,29 @@ dbg_objfmt_cleanup(void)
 }
 
 static /*@observer@*/ /*@null@*/ yasm_section *
-dbg_objfmt_sections_switch(yasm_sectionhead *headp,
-                          yasm_valparamhead *valparams,
-                          /*@unused@*/ /*@null@*/
-                          yasm_valparamhead *objext_valparams,
-                          unsigned long lindex)
+dbg_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
+                         /*@unused@*/ /*@null@*/
+                         yasm_valparamhead *objext_valparams,
+                         unsigned long line)
 {
     yasm_valparam *vp;
     yasm_section *retval;
     int isnew;
 
     fprintf(dbg_objfmt_file, "sections_switch(headp, ");
-    yasm_vps_print(dbg_objfmt_file, valparams);
+    yasm_vps_print(valparams, dbg_objfmt_file);
     fprintf(dbg_objfmt_file, ", ");
-    yasm_vps_print(dbg_objfmt_file, objext_valparams);
-    fprintf(dbg_objfmt_file, ", %lu), returning ", lindex);
+    yasm_vps_print(objext_valparams, dbg_objfmt_file);
+    fprintf(dbg_objfmt_file, ", %lu), returning ", line);
 
     if ((vp = yasm_vps_first(valparams)) && !vp->param && vp->val != NULL) {
-       retval = yasm_sections_switch_general(headp, vp->val,
-           yasm_expr_new_ident(yasm_expr_int(yasm_intnum_new_uint(200)),
-                               lindex), 0, &isnew, lindex);
+       retval = yasm_object_get_general(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_symrec_define_label(vp->val, retval, (yasm_bytecode *)NULL, 1,
-                                    lindex);
+           yasm_symtab_define_label(yasm_object_get_symtab(object), vp->val,
+                                    yasm_section_bcs_first(retval), 1, line);
        }
        fprintf(dbg_objfmt_file, "\"%s\" section\n", vp->val);
        return retval;
@@ -111,81 +115,63 @@ dbg_objfmt_sections_switch(yasm_sectionhead *headp,
     }
 }
 
-static void
-dbg_objfmt_section_data_delete(/*@only@*/ void *data)
-{
-    fprintf(dbg_objfmt_file, "section_data_delete(%p)\n", data);
-    yasm_xfree(data);
-}
-
-static void
-dbg_objfmt_section_data_print(FILE *f, int indent_level, /*@null@*/ void *data)
-{
-    if (data)
-       fprintf(f, "%*s%p\n", indent_level, "", data);
-    else
-       fprintf(f, "%*s(none)\n", indent_level, "");
-}
-
 static void
 dbg_objfmt_extern_declare(yasm_symrec *sym, /*@unused@*/ /*@null@*/
                          yasm_valparamhead *objext_valparams,
-                         unsigned long lindex)
+                         unsigned long line)
 {
     fprintf(dbg_objfmt_file, "extern_declare(\"%s\", ",
            yasm_symrec_get_name(sym));
-    yasm_vps_print(dbg_objfmt_file, objext_valparams);
-    fprintf(dbg_objfmt_file, ", %lu), setting of_data=NULL\n", lindex);
-    yasm_symrec_set_of_data(sym, &yasm_dbg_LTX_objfmt, NULL);
+    yasm_vps_print(objext_valparams, dbg_objfmt_file);
+    fprintf(dbg_objfmt_file, ", %lu)\n", line);
 }
 
 static void
 dbg_objfmt_global_declare(yasm_symrec *sym, /*@unused@*/ /*@null@*/
                          yasm_valparamhead *objext_valparams,
-                         unsigned long lindex)
+                         unsigned long line)
 {
     fprintf(dbg_objfmt_file, "global_declare(\"%s\", ",
            yasm_symrec_get_name(sym));
-    yasm_vps_print(dbg_objfmt_file, objext_valparams);
-    fprintf(dbg_objfmt_file, ", %lu), setting of_data=NULL\n", lindex);
-    yasm_symrec_set_of_data(sym, &yasm_dbg_LTX_objfmt, NULL);
+    yasm_vps_print(objext_valparams, dbg_objfmt_file);
+    fprintf(dbg_objfmt_file, ", %lu)\n", line);
 }
 
 static void
 dbg_objfmt_common_declare(yasm_symrec *sym, /*@only@*/ yasm_expr *size,
                          /*@unused@*/ /*@null@*/
                          yasm_valparamhead *objext_valparams,
-                         unsigned long lindex)
+                         unsigned long line)
 {
     assert(dbg_objfmt_file != NULL);
     fprintf(dbg_objfmt_file, "common_declare(\"%s\", ",
            yasm_symrec_get_name(sym));
-    yasm_expr_print(dbg_objfmt_file, size);
+    yasm_expr_print(size, dbg_objfmt_file);
     fprintf(dbg_objfmt_file, ", ");
-    yasm_vps_print(dbg_objfmt_file, objext_valparams);
-    fprintf(dbg_objfmt_file, ", %lu), setting of_data=", lindex);
-    yasm_expr_print(dbg_objfmt_file, size);
-    yasm_symrec_set_of_data(sym, &yasm_dbg_LTX_objfmt, size);
+    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");
 }
 
 static void
-dbg_objfmt_symrec_data_delete(/*@only@*/ void *data)
+symrec_data_destroy(void *data)
 {
     fprintf(dbg_objfmt_file, "symrec_data_delete(");
     if (data) {
-       yasm_expr_print(dbg_objfmt_file, data);
-       yasm_expr_delete(data);
+       yasm_expr_print((yasm_expr *)data, dbg_objfmt_file);
+       yasm_expr_destroy((yasm_expr *)data);
     }
     fprintf(dbg_objfmt_file, ")\n");
 }
 
 static void
-dbg_objfmt_symrec_data_print(FILE *f, int indent_level, /*@null@*/ void *data)
+symrec_data_print(void *data, FILE *f, int indent_level)
 {
     if (data) {
        fprintf(f, "%*sSize=", indent_level, "");
-       yasm_expr_print(f, data);
+       yasm_expr_print((yasm_expr *)data, f);
        fprintf(f, "\n");
     } else {
        fprintf(f, "%*s(none)\n", indent_level, "");
@@ -195,32 +181,17 @@ dbg_objfmt_symrec_data_print(FILE *f, int indent_level, /*@null@*/ void *data)
 static int
 dbg_objfmt_directive(const char *name, yasm_valparamhead *valparams,
                     /*@null@*/ yasm_valparamhead *objext_valparams,
-                    /*@unused@*/ yasm_sectionhead *headp,
-                    unsigned long lindex)
+                    /*@unused@*/ yasm_object *object,
+                    unsigned long line)
 {
     fprintf(dbg_objfmt_file, "directive(\"%s\", ", name);
-    yasm_vps_print(dbg_objfmt_file, valparams);
+    yasm_vps_print(valparams, dbg_objfmt_file);
     fprintf(dbg_objfmt_file, ", ");
-    yasm_vps_print(dbg_objfmt_file, objext_valparams);
-    fprintf(dbg_objfmt_file, ", %lu), returning 0 (recognized)\n", lindex);
+    yasm_vps_print(objext_valparams, dbg_objfmt_file);
+    fprintf(dbg_objfmt_file, ", %lu), returning 0 (recognized)\n", line);
     return 0;      /* dbg format "recognizes" all directives */
 }
 
-static void
-dbg_objfmt_bc_objfmt_data_delete(unsigned int type, /*@only@*/ void *data)
-{
-    fprintf(dbg_objfmt_file, "symrec_data_delete(%u, %p)\n", type, data);
-    yasm_xfree(data);
-}
-
-static void
-dbg_objfmt_bc_objfmt_data_print(FILE *f, int indent_level, unsigned int type,
-                               const void *data)
-{
-    fprintf(f, "%*sType=%u\n", indent_level, "", type);
-    fprintf(f, "%*sData=%p\n", indent_level, "", data);
-}
-
 
 /* Define valid debug formats to use with this object format */
 static const char *dbg_objfmt_dbgfmt_keywords[] = {
@@ -241,15 +212,9 @@ yasm_objfmt yasm_dbg_LTX_objfmt = {
     dbg_objfmt_initialize,
     dbg_objfmt_output,
     dbg_objfmt_cleanup,
-    dbg_objfmt_sections_switch,
-    dbg_objfmt_section_data_delete,
-    dbg_objfmt_section_data_print,
+    dbg_objfmt_section_switch,
     dbg_objfmt_extern_declare,
     dbg_objfmt_global_declare,
     dbg_objfmt_common_declare,
-    dbg_objfmt_symrec_data_delete,
-    dbg_objfmt_symrec_data_print,
-    dbg_objfmt_directive,
-    dbg_objfmt_bc_objfmt_data_delete,
-    dbg_objfmt_bc_objfmt_data_print
+    dbg_objfmt_directive
 };
index 7a886c624a91aa83bd14aee3c4b3c31dd9df19f2..5581f222a3873b3dc365c2b5ac4ce0bb1d5bac72 100644 (file)
@@ -55,7 +55,7 @@ typedef struct {
     FILE *f;
     elf_secthead *shead;
     yasm_section *sect;
-    yasm_sectionhead *sections;
+    yasm_object *object;
     unsigned long sindex;
 } elf_objfmt_output_info;
 
@@ -64,7 +64,6 @@ 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 */
 
-yasm_objfmt yasm_elf_LTX_objfmt;
 static /*@dependent@*/ yasm_arch *cur_arch;
 static /*@dependent@*/ yasm_dbgfmt *cur_dbgfmt;
 
@@ -75,11 +74,11 @@ elf_objfmt_symtab_append(yasm_symrec *sym, elf_symbol_binding bind,
 {
     elf_strtab_entry *name = elf_strtab_append_str(elf_strtab,
                                                   yasm_symrec_get_name(sym));
-    elf_symtab_entry *entry = elf_symtab_entry_new(name, sym);
+    elf_symtab_entry *entry = elf_symtab_entry_create(name, sym);
     elf_symtab_append_entry(elf_symtab, entry);
 
     elf_symtab_set_nonzero(entry, NULL, sectidx, bind, STT_NOTYPE, size, 00);
-    yasm_symrec_set_of_data(sym, &yasm_elf_LTX_objfmt, entry);
+    yasm_symrec_add_data(sym, &elf_symrec_data, entry);
 
     return entry;
 }
@@ -93,10 +92,11 @@ elf_objfmt_append_local_sym(yasm_symrec *sym, /*@unused@*/ /*@null@*/ void *d)
     yasm_section *sect=NULL;
     yasm_bytecode *precbc=NULL;
 
-    if (!yasm_symrec_get_of_data(sym)) {
+    if (!yasm_symrec_get_data(sym, &elf_symrec_data)) {
        int is_sect = 0;
-       if (!yasm_symrec_get_label(sym, &sect, &precbc))
+       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;
 
        /* neither sections nor locals (except when debugging) need names */
@@ -104,17 +104,18 @@ elf_objfmt_append_local_sym(yasm_symrec *sym, /*@unused@*/ /*@null@*/ void *d)
                    local_names && !is_sect ? elf_strtab : NULL, sym);
        elf_symtab_set_nonzero(entry, sect, 0, STB_LOCAL,
                               is_sect ? STT_SECTION : STT_NOTYPE, NULL, 0);
-       yasm_symrec_set_of_data(sym, &yasm_elf_LTX_objfmt, entry);
+       yasm_symrec_add_data(sym, &elf_symrec_data, entry);
 
        if (is_sect)
            return 1;
     }
     else {
-       if (!yasm_symrec_get_label(sym, &sect, &precbc))
+       if (!yasm_symrec_get_label(sym, &precbc))
            return 1;
+       sect = yasm_bc_get_section(precbc);
     }
 
-    entry = yasm_symrec_get_of_data(sym);
+    entry = yasm_symrec_get_data(sym, &elf_symrec_data);
     if (precbc)
        value = precbc->offset + precbc->len;
     elf_symtab_set_nonzero(entry, sect, 0, 0, 0, NULL, value);
@@ -125,27 +126,29 @@ elf_objfmt_append_local_sym(yasm_symrec *sym, /*@unused@*/ /*@null@*/ void *d)
 static int
 elf_objfmt_initialize(const char *in_filename,
                       /*@unused@*/ const char *obj_filename,
-                      /*@unused@*/ yasm_dbgfmt *df, yasm_arch *a,
-                      const char *machine)
+                      yasm_object *object, /*@unused@*/ yasm_dbgfmt *df,
+                      yasm_arch *a)
 {
     yasm_symrec *filesym;
     elf_symtab_entry *entry;
 
     cur_arch = a;
     cur_dbgfmt = df;
-    if (!elf_set_arch(a, machine))
+    if (!elf_set_arch(a))
        return 1;
 
     elf_objfmt_parse_scnum = 4;    /* section numbering starts at 0;
                                      4 predefined sections. */
-    elf_shstrtab = elf_strtab_new();
-    elf_strtab = elf_strtab_new();
-    elf_symtab = elf_symtab_new();
-
-    filesym = yasm_symrec_define_label(".file", NULL, NULL, 0, 0);
-    entry = elf_symtab_entry_new(
+    elf_shstrtab = elf_strtab_create();
+    elf_strtab = elf_strtab_create();
+    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);
-    yasm_symrec_set_of_data(filesym, &yasm_elf_LTX_objfmt, entry);
+    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);
 
@@ -179,15 +182,15 @@ elf_objfmt_output_align(FILE *f, unsigned int align)
 static int
 elf_objfmt_output_reloc(yasm_symrec *sym, yasm_bytecode *bc,
                        unsigned char *buf, size_t destsize, size_t valsize,
-                       int rel, int warn, const yasm_section *sect, void *d)
+                       int rel, int warn, void *d)
 {
     elf_reloc_entry *reloc;
     elf_objfmt_output_info *info = d;
-    yasm_intnum *zero = yasm_intnum_new_uint(0);
+    yasm_intnum *zero = yasm_intnum_create_uint(0);
     int retval;
 
-    reloc = elf_reloc_entry_new(sym,
-       yasm_intnum_new_uint(bc->offset), rel, valsize);
+    reloc = elf_reloc_entry_create(sym,
+       yasm_intnum_create_uint(bc->offset), rel, valsize);
     if (reloc == NULL) {
        yasm__error(bc->line, N_("elf: invalid relocation size"));
        return 1;
@@ -196,16 +199,16 @@ elf_objfmt_output_reloc(yasm_symrec *sym, yasm_bytecode *bc,
     if (elf_secthead_append_reloc(info->shead, reloc))
        elf_objfmt_parse_scnum++;
 
-    retval = cur_arch->intnum_tobytes(zero, buf, destsize, valsize, 0,
-                                     bc, rel, warn, bc->line);
-    yasm_intnum_delete(zero);
+    retval = cur_arch->module->intnum_tobytes(cur_arch, zero, buf, destsize,
+                                             valsize, 0, bc, rel, warn,
+                                             bc->line);
+    yasm_intnum_destroy(zero);
     return retval;
 }
 
 static int
 elf_objfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize,
                        size_t valsize, int shift, unsigned long offset,
-                       /*@observer@*/ const yasm_section *sect,
                        yasm_bytecode *bc, int rel, int warn,
                        /*@null@*/ void *d)
 {
@@ -224,8 +227,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 cur_arch->floatnum_tobytes(flt, buf, destsize, valsize,
-                                         (unsigned int)shift, warn, bc->line);
+       return cur_arch->module->floatnum_tobytes(cur_arch, flt, buf, destsize,
+                                                 valsize, (unsigned int)shift,
+                                                 warn, bc->line);
     }
 
     /* Handle integer expressions, with relocation if necessary */
@@ -237,12 +241,13 @@ elf_objfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize,
        vis = yasm_symrec_get_visibility(sym);
        if (!(vis & (YASM_SYM_COMMON|YASM_SYM_EXTERN)))
        {
-           yasm_section *label_sect;
            yasm_bytecode *label_precbc;
            /* Local symbols need relocation to their section's start */
-           if (yasm_symrec_get_label(sym, &label_sect, &label_precbc)) {
+           if (yasm_symrec_get_label(sym, &label_precbc)) {
+               yasm_section *label_sect = yasm_bc_get_section(label_precbc);
                /*@null@*/ elf_secthead *sym_shead;
-               sym_shead = yasm_section_get_of_data(label_sect);
+               sym_shead =
+                   yasm_section_get_data(label_sect, &elf_section_data);
                assert(sym_shead != NULL);
                sym = elf_secthead_get_sym(sym_shead);
            }
@@ -250,19 +255,19 @@ elf_objfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize,
 
        if (rel) {
            /* Need to reference to start of section, so add $$ in. */
-           *ep = yasm_expr_new(YASM_EXPR_ADD, yasm_expr_expr(*ep),
-               yasm_expr_sym(yasm_symrec_define_label("$$", info->sect,
-                                                      NULL, 0, (*ep)->line)),
+           *ep = yasm_expr_create(YASM_EXPR_ADD, yasm_expr_expr(*ep),
+               yasm_expr_sym(yasm_symtab_define_label2("$$",
+                   yasm_section_bcs_first(info->sect), 0, (*ep)->line)),
                (*ep)->line);
            /* HELP: and this seems to have the desired effect. */
-           *ep = yasm_expr_new(YASM_EXPR_ADD, yasm_expr_expr(*ep),
-               yasm_expr_int(yasm_intnum_new_uint(bc->offset + offset)),
+           *ep = yasm_expr_create(YASM_EXPR_ADD, yasm_expr_expr(*ep),
+               yasm_expr_int(yasm_intnum_create_uint(bc->offset + offset)),
                (*ep)->line);
            *ep = yasm_expr_simplify(*ep, yasm_common_calc_bc_dist);
        }
 
-       reloc = elf_reloc_entry_new(sym,
-           yasm_intnum_new_uint(bc->offset + offset), rel, valsize);
+       reloc = elf_reloc_entry_create(sym,
+           yasm_intnum_create_uint(bc->offset + offset), rel, valsize);
        if (reloc == NULL) {
            yasm__error(bc->line, N_("elf: invalid relocation size"));
            return 1;
@@ -274,8 +279,9 @@ elf_objfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize,
 
     intn = yasm_expr_get_intnum(ep, NULL);
     if (intn)
-       return cur_arch->intnum_tobytes(intn, buf, destsize, valsize, shift,
-                                       bc, rel, warn, bc->line);
+       return cur_arch->module->intnum_tobytes(cur_arch, intn, buf, destsize,
+                                               valsize, shift, bc, rel, warn,
+                                               bc->line);
 
     /* Check for complex float expressions */
     if (yasm_expr__contains(*ep, YASM_EXPR_FLOAT)) {
@@ -301,9 +307,8 @@ elf_objfmt_output_bytecode(yasm_bytecode *bc, /*@null@*/ void *d)
     if (info == NULL)
        yasm_internal_error("null info struct");
 
-    bigbuf = yasm_bc_tobytes(bc, buf, &size, &multiple, &gap, info->sect,
-                            info, elf_objfmt_output_expr, 
-                            elf_objfmt_output_reloc, NULL);
+    bigbuf = yasm_bc_tobytes(bc, buf, &size, &multiple, &gap, info,
+                            elf_objfmt_output_expr, elf_objfmt_output_reloc);
 
     /* Don't bother doing anything else if size ended up being 0. */
     if (size == 0) {
@@ -312,14 +317,14 @@ elf_objfmt_output_bytecode(yasm_bytecode *bc, /*@null@*/ void *d)
        return 0;
     }
     else {
-       yasm_intnum *bcsize = yasm_intnum_new_uint(size);
-       yasm_intnum *mult = yasm_intnum_new_uint(multiple);
+       yasm_intnum *bcsize = yasm_intnum_create_uint(size);
+       yasm_intnum *mult = yasm_intnum_create_uint(multiple);
 
        yasm_intnum_calc(bcsize, YASM_EXPR_MUL, mult, 0);
        elf_secthead_add_size(info->shead, bcsize);
 
-       yasm_intnum_delete(bcsize);
-       yasm_intnum_delete(mult);
+       yasm_intnum_destroy(bcsize);
+       yasm_intnum_destroy(mult);
     }
 
     /* Warn that gaps are converted to 0 and write out the 0's. */
@@ -349,7 +354,8 @@ elf_objfmt_output_bytecode(yasm_bytecode *bc, /*@null@*/ void *d)
 }
 
 static elf_secthead *
-elf_objfmt_new_dbg_secthead(yasm_section *sect, elf_objfmt_output_info *info)
+elf_objfmt_create_dbg_secthead(yasm_section *sect,
+                              elf_objfmt_output_info *info)
 {
     elf_secthead *shead;
     elf_section_type type=SHT_PROGBITS;
@@ -359,20 +365,20 @@ elf_objfmt_new_dbg_secthead(yasm_section *sect, elf_objfmt_output_info *info)
     elf_strtab_entry *name = elf_strtab_append_str(elf_shstrtab, sectname);
 
     if (yasm__strcasecmp(sectname, ".stab")==0) {
-       align = yasm_intnum_new_uint(4);
+       align = yasm_intnum_create_uint(4);
        entsize = 12;
     } else if (yasm__strcasecmp(sectname, ".stabstr")==0) {
        type = SHT_STRTAB;
-       align = yasm_intnum_new_uint(1);
+       align = yasm_intnum_create_uint(1);
     }
     else
        yasm_internal_error(N_("Unrecognized section without data"));
 
-    shead = elf_secthead_new(name, type, 0, elf_objfmt_parse_scnum++, 0, 0);
+    shead = elf_secthead_create(name, type, 0, elf_objfmt_parse_scnum++, 0, 0);
     elf_secthead_set_align(shead, align);
     elf_secthead_set_entsize(shead, entsize);
 
-    yasm_section_set_of_data(sect, &yasm_elf_LTX_objfmt, shead);
+    yasm_section_add_data(sect, &elf_section_data, shead);
 
     return shead;
 }
@@ -393,26 +399,26 @@ elf_objfmt_output_section(yasm_section *sect, /*@null@*/ void *d)
 
     if (info == NULL)
        yasm_internal_error("null info struct");
-    shead = yasm_section_get_of_data(sect);
+    shead = yasm_section_get_data(sect, &elf_section_data);
     if (shead == NULL)
-       shead = elf_objfmt_new_dbg_secthead(sect, info);
+       shead = elf_objfmt_create_dbg_secthead(sect, info);
 
     /* don't output header-only sections */
     if ((elf_secthead_get_type(shead) & SHT_NOBITS) == SHT_NOBITS)
     {
-       yasm_bytecode *last = yasm_bcs_last(yasm_section_get_bytecodes(sect));
+       yasm_bytecode *last = yasm_section_bcs_last(sect);
        if (last) {
            yasm_intnum *sectsize;
-           sectsize = yasm_intnum_new_uint(last->offset + last->len);
+           sectsize = yasm_intnum_create_uint(last->offset + last->len);
            elf_secthead_add_size(shead, sectsize);
-           yasm_intnum_delete(sectsize);
+           yasm_intnum_destroy(sectsize);
        }
        elf_secthead_set_index(shead, ++info->sindex);
        return 0;
     }
 
     /* skip empty sections */
-    if (!yasm_bcs_last(yasm_section_get_bytecodes(sect))) {
+    if (yasm_section_bcs_last(sect) == yasm_section_bcs_first(sect)) {
        return 0;
     }
 
@@ -424,8 +430,7 @@ elf_objfmt_output_section(yasm_section *sect, /*@null@*/ void *d)
 
     info->sect = sect;
     info->shead = shead;
-    yasm_bcs_traverse(yasm_section_get_bytecodes(sect), info,
-                     elf_objfmt_output_bytecode);
+    yasm_section_bcs_traverse(sect, info, elf_objfmt_output_bytecode);
 
     /* Empty?  Go on to next section */
     if (elf_secthead_is_empty(shead))
@@ -462,7 +467,7 @@ elf_objfmt_output_secthead(yasm_section *sect, /*@null@*/ void *d)
 
     if (info == NULL)
        yasm_internal_error("null info struct");
-    shead = yasm_section_get_of_data(sect);
+    shead = yasm_section_get_data(sect, &elf_section_data);
     if (shead == NULL)
        yasm_internal_error("no section header attached to section");
 
@@ -479,7 +484,7 @@ elf_objfmt_output_secthead(yasm_section *sect, /*@null@*/ void *d)
 }
 
 static void
-elf_objfmt_output(FILE *f, yasm_sectionhead *sections, int all_syms)
+elf_objfmt_output(FILE *f, yasm_object *object, int all_syms)
 {
     elf_objfmt_output_info info;
     long pos;
@@ -500,13 +505,15 @@ elf_objfmt_output(FILE *f, yasm_sectionhead *sections, 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_symrec_traverse((void *)&all_syms, elf_objfmt_append_local_sym);
+    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);
 
     /* output known sections - includes reloc sections which aren't in yasm's
      * list.  Assign indices as we go. */
     info.sindex = 3;
-    if (yasm_sections_traverse(sections, &info, elf_objfmt_output_section))
+    if (yasm_object_sections_traverse(object, &info,
+                                     elf_objfmt_output_section))
        return;
 
     /* add final sections to the shstrtab */
@@ -539,11 +546,14 @@ elf_objfmt_output(FILE *f, yasm_sectionhead *sections, int all_syms)
 
     /* stabs debugging support */
     if (strcmp(cur_dbgfmt->keyword, "stabs")==0) {
-       yasm_section *stabsect = yasm_sections_find_general(sections, ".stab");
-       yasm_section *stabstrsect = yasm_sections_find_general(sections, ".stabstr");
+       yasm_section *stabsect = yasm_object_find_general(object, ".stab");
+       yasm_section *stabstrsect =
+           yasm_object_find_general(object, ".stabstr");
        if (stabsect && stabstrsect) {
-           elf_secthead *stab = yasm_section_get_of_data(stabsect);
-           elf_secthead *stabstr = yasm_section_get_of_data(stabstrsect);
+           elf_secthead *stab =
+               yasm_section_get_data(stabsect, &elf_section_data);
+           elf_secthead *stabstr =
+               yasm_section_get_data(stabstrsect, &elf_section_data);
            if (stab && stabstr) {
                elf_secthead_set_link(stab, elf_secthead_get_index(stabstr));
            }
@@ -555,30 +565,30 @@ elf_objfmt_output(FILE *f, yasm_sectionhead *sections, int all_syms)
     /* output dummy section header - 0 */
     info.sindex = 0;
 
-    esdn = elf_secthead_new(NULL, SHT_NULL, 0, 0, 0, 0);
+    esdn = elf_secthead_create(NULL, SHT_NULL, 0, 0, 0, 0);
     elf_secthead_write_to_file(f, esdn, 0);
-    elf_secthead_delete(esdn);
+    elf_secthead_destroy(esdn);
 
-    esdn = elf_secthead_new(elf_shstrtab_name, SHT_STRTAB, 0, 1,
-                           elf_shstrtab_offset, elf_shstrtab_size);
+    esdn = elf_secthead_create(elf_shstrtab_name, SHT_STRTAB, 0, 1,
+                              elf_shstrtab_offset, elf_shstrtab_size);
     elf_secthead_write_to_file(f, esdn, 1);
-    elf_secthead_delete(esdn);
+    elf_secthead_destroy(esdn);
 
-    esdn = elf_secthead_new(elf_strtab_name, SHT_STRTAB, 0, 2,
-                           elf_strtab_offset, elf_strtab_size);
+    esdn = elf_secthead_create(elf_strtab_name, SHT_STRTAB, 0, 2,
+                              elf_strtab_offset, elf_strtab_size);
     elf_secthead_write_to_file(f, esdn, 2);
-    elf_secthead_delete(esdn);
+    elf_secthead_destroy(esdn);
 
-    esdn = elf_secthead_new(elf_symtab_name, SHT_SYMTAB, 0, 3,
-                           elf_symtab_offset, elf_symtab_size);
+    esdn = elf_secthead_create(elf_symtab_name, SHT_SYMTAB, 0, 3,
+                              elf_symtab_offset, elf_symtab_size);
     elf_secthead_set_info(esdn, elf_symtab_nlocal);
     elf_secthead_set_link(esdn, 2);    /* for .strtab, which is index 2 */
     elf_secthead_write_to_file(f, esdn, 3);
-    elf_secthead_delete(esdn);
+    elf_secthead_destroy(esdn);
 
     info.sindex = 3;
     /* output remaining section headers */
-    yasm_sections_traverse(sections, &info, elf_objfmt_output_secthead);
+    yasm_object_sections_traverse(object, &info, elf_objfmt_output_secthead);
 
     /* output Ehdr */
     if (fseek(f, 0, SEEK_SET) < 0) {
@@ -592,17 +602,16 @@ elf_objfmt_output(FILE *f, yasm_sectionhead *sections, int all_syms)
 static void
 elf_objfmt_cleanup(void)
 {
-    elf_symtab_delete(elf_symtab);
-    elf_strtab_delete(elf_shstrtab);
-    elf_strtab_delete(elf_strtab);
+    elf_symtab_destroy(elf_symtab);
+    elf_strtab_destroy(elf_shstrtab);
+    elf_strtab_destroy(elf_strtab);
 }
 
 static /*@observer@*/ /*@null@*/ yasm_section *
-elf_objfmt_sections_switch(yasm_sectionhead *headp,
-                           yasm_valparamhead *valparams,
-                           /*@unused@*/ /*@null@*/
-                           yasm_valparamhead *objext_valparams,
-                           unsigned long lindex)
+elf_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
+                         /*@unused@*/ /*@null@*/
+                         yasm_valparamhead *objext_valparams,
+                         unsigned long line)
 {
     yasm_valparam *vp = yasm_vps_first(valparams);
     yasm_section *retval;
@@ -683,7 +692,7 @@ elf_objfmt_sections_switch(yasm_sectionhead *headp,
 
                align_expr = yasm_expr_get_intnum(&vp->param, NULL);
                if (!align_expr) {
-                   yasm__error(lindex,
+                   yasm__error(line,
                                N_("argument to `%s' is not a power of two"),
                                vp->val);
                    return NULL;
@@ -692,7 +701,7 @@ elf_objfmt_sections_switch(yasm_sectionhead *headp,
 
                /* Alignments must be a power of two. */
                if ((addralign & (addralign - 1)) != 0) {
-                   yasm__error(lindex,
+                   yasm__error(line,
                                N_("argument to `%s' is not a power of two"),
                                vp->val);
                    return NULL;
@@ -701,51 +710,40 @@ elf_objfmt_sections_switch(yasm_sectionhead *headp,
                align_intn = yasm_intnum_copy(align_expr);
            } 
        } else
-           yasm__warning(YASM_WARN_GENERAL, lindex,
+           yasm__warning(YASM_WARN_GENERAL, line,
                          N_("Unrecognized qualifier `%s'"), vp->val);
     }
 
-    retval = yasm_sections_switch_general(headp, sectname, 0, resonly, &isnew,
-                                         lindex);
+    retval = yasm_object_get_general(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);
 
-       esd = elf_secthead_new(name, type, flags,
-                              elf_objfmt_parse_scnum++, 0, 0);
+       esd = elf_secthead_create(name, type, flags, elf_objfmt_parse_scnum++,
+                                 0, 0);
        if (!align_intn)
-           align_intn = yasm_intnum_new_uint(align);
+           align_intn = yasm_intnum_create_uint(align);
        if (align_intn)
            elf_secthead_set_align(esd, align_intn);
-       yasm_section_set_of_data(retval, &yasm_elf_LTX_objfmt, esd);
-       sym = yasm_symrec_define_label(sectname, retval, (yasm_bytecode *)NULL,
-                                      1, lindex);
+       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);
 
        elf_secthead_set_sym(esd, sym);
     } else if (flags_override)
-       yasm__warning(YASM_WARN_GENERAL, lindex,
+       yasm__warning(YASM_WARN_GENERAL, line,
                      N_("section flags ignored on section redeclaration"));
     return retval;
 }
 
-static void
-elf_objfmt_section_data_delete(/*@only@*/ void *data)
-{
-    elf_secthead_delete((elf_secthead *)data);
-}
-
-static void
-elf_objfmt_section_data_print(FILE *f, int indent_level, void *data)
-{
-    elf_secthead_print(f, indent_level, (elf_secthead *)data);
-}
-
 static void
 elf_objfmt_extglob_declare(yasm_symrec *sym, /*@unused@*/
                            /*@null@*/ yasm_valparamhead *objext_valparams,
-                           /*@unused@*/ unsigned long lindex)
+                           /*@unused@*/ unsigned long line)
 {
     elf_objfmt_symtab_append(sym, STB_GLOBAL, SHN_UNDEF, NULL);
 }
@@ -754,34 +752,18 @@ static void
 elf_objfmt_common_declare(yasm_symrec *sym, /*@only@*/ yasm_expr *size,
                           /*@unused@*/ /*@null@*/
                           yasm_valparamhead *objext_valparams,
-                          /*@unused@*/ unsigned long lindex)
+                          /*@unused@*/ unsigned long line)
 {
     elf_objfmt_symtab_append(sym, STB_GLOBAL, SHN_COMMON, size);
 }
 
-static void
-elf_objfmt_symrec_data_delete(/*@only@*/ void *data)
-{
-    /* do nothing, as this stuff is in the symtab anyway...  this speaks of bad
-     * design/use or this stuff, i fear */
-
-    /* watch for double-free here ... */
-    /*elf_symtab_entry_delete((elf_symtab_entry *)data);*/
-}
-
-static void
-elf_objfmt_symrec_data_print(FILE *f, int indent_level, void *data)
-{
-    elf_symtab_entry_print(f, indent_level, (elf_symtab_entry *)data);
-}
-
 static int
 elf_objfmt_directive(/*@unused@*/ const char *name,
                      /*@unused@*/ yasm_valparamhead *valparams,
                      /*@unused@*/ /*@null@*/
                      yasm_valparamhead *objext_valparams,
-                     /*@unused@*/ yasm_sectionhead *headp,
-                     /*@unused@*/ unsigned long lindex)
+                     /*@unused@*/ yasm_object *object,
+                     /*@unused@*/ unsigned long line)
 {
     return 1;  /* no objfmt directives */
 }
@@ -807,15 +789,9 @@ yasm_objfmt yasm_elf_LTX_objfmt = {
     elf_objfmt_initialize,
     elf_objfmt_output,
     elf_objfmt_cleanup,
-    elf_objfmt_sections_switch,
-    elf_objfmt_section_data_delete,
-    elf_objfmt_section_data_print,
+    elf_objfmt_section_switch,
     elf_objfmt_extglob_declare,
     elf_objfmt_extglob_declare,
     elf_objfmt_common_declare,
-    elf_objfmt_symrec_data_delete,
-    elf_objfmt_symrec_data_print,
-    elf_objfmt_directive,
-    NULL /*elf_objfmt_bc_objfmt_data_delete*/,
-    NULL /*elf_objfmt_bc_objfmt_data_print*/
+    elf_objfmt_directive
 };
index d18fcfe4d1b77de8a5c843a6bf9a7c3708116873..a72881eb1c94cb5f31ab30d42021c4f0ee335e1e 100644 (file)
 
 #define YASM_WRITE_64Z_L(p, i)         YASM_WRITE_64C_L(p, 0, i)
 
+static void elf_section_data_destroy(void *data);
+static void elf_secthead_print(void *data, FILE *f, int indent_level);
+
+const yasm_assoc_data_callback elf_section_data = {
+    elf_section_data_destroy,
+    elf_secthead_print
+};
+
+static void elf_symrec_data_destroy(/*@only@*/ void *d);
+static void elf_symtab_entry_print(void *data, FILE *f, int indent_level);
+
+const yasm_assoc_data_callback elf_symrec_data = {
+    elf_symrec_data_destroy,
+    elf_symtab_entry_print
+};
+
 static /*@dependent@*/ yasm_arch *cur_arch;
 static enum {
     M_X86_32 = 1,
@@ -61,12 +77,13 @@ static enum {
 } cur_elf = 0;
 
 int
-elf_set_arch(yasm_arch *arch, const char *machine)
+elf_set_arch(yasm_arch *arch)
 {
+    const char *machine = arch->module->get_machine(arch);
     cur_arch = arch;
 
     /* TODO: support more than x86:x86, x86:amd64 */
-    if (yasm__strcasecmp(cur_arch->keyword, "x86") == 0) {
+    if (yasm__strcasecmp(cur_arch->module->keyword, "x86") == 0) {
        if (yasm__strcasecmp(machine, "x86") == 0) {
            cur_machine = M_X86_32;
            cur_elf = ELF32;
@@ -87,17 +104,17 @@ elf_set_arch(yasm_arch *arch, const char *machine)
 /* reloc functions */
 /* takes ownership of addr */
 elf_reloc_entry *
-elf_reloc_entry_new(yasm_symrec *sym,
-                   yasm_intnum *addr,
-                   int rel,
-                   size_t valsize)
+elf_reloc_entry_create(yasm_symrec *sym,
+                      yasm_intnum *addr,
+                      int rel,
+                      size_t valsize)
 {
     elf_reloc_entry *entry;
     switch (cur_machine) {
        case M_X86_32:
            if (valsize != 32) {
                if (addr)
-                   yasm_intnum_delete(addr);
+                   yasm_intnum_destroy(addr);
                return NULL;
            }
            break;
@@ -106,7 +123,7 @@ elf_reloc_entry_new(yasm_symrec *sym,
            if (valsize != 8 && valsize != 16 && valsize != 32 && valsize != 64)
            {
                if (addr)
-                   yasm_intnum_delete(addr);
+                   yasm_intnum_destroy(addr);
                return NULL;
            }
            break;
@@ -128,15 +145,15 @@ elf_reloc_entry_new(yasm_symrec *sym,
 }
 
 void
-elf_reloc_entry_delete(elf_reloc_entry *entry)
+elf_reloc_entry_destroy(elf_reloc_entry *entry)
 {
     if (entry->addr)
-       yasm_intnum_delete(entry->addr);
+       yasm_intnum_destroy(entry->addr);
     yasm_xfree(entry);
 }
 
 elf_reloc_head *
-elf_relocs_new()
+elf_relocs_create()
 {
     elf_reloc_head *head = yasm_xmalloc(sizeof(elf_reloc_head));
     STAILQ_INIT(head);
@@ -144,7 +161,7 @@ elf_relocs_new()
 }
 
 void
-elf_reloc_delete(elf_reloc_head *relocs)
+elf_reloc_destroy(elf_reloc_head *relocs)
 {
     if (relocs == NULL)
        yasm_internal_error("relocs is null");
@@ -154,7 +171,7 @@ elf_reloc_delete(elf_reloc_head *relocs)
        e1 = STAILQ_FIRST(relocs);
        while (e1 != NULL) {
            e2 = STAILQ_NEXT(e1, qlink);
-           elf_reloc_entry_delete(e1);
+           elf_reloc_entry_destroy(e1);
            e1 = e2;
        }
     }
@@ -162,7 +179,7 @@ elf_reloc_delete(elf_reloc_head *relocs)
 
 /* strtab functions */
 elf_strtab_entry *
-elf_strtab_entry_new(const char *str)
+elf_strtab_entry_create(const char *str)
 {
     elf_strtab_entry *entry = yasm_xmalloc(sizeof(elf_strtab_entry));
     entry->str = yasm__xstrdup(str);
@@ -171,7 +188,7 @@ elf_strtab_entry_new(const char *str)
 }
 
 elf_strtab_head *
-elf_strtab_new()
+elf_strtab_create()
 {
     elf_strtab_head *strtab = yasm_xmalloc(sizeof(elf_strtab_head));
     elf_strtab_entry *entry = yasm_xmalloc(sizeof(elf_strtab_entry));
@@ -196,7 +213,7 @@ elf_strtab_append_str(elf_strtab_head *strtab, const char *str)
 
     last = STAILQ_LAST(strtab, elf_strtab_entry, qlink);
 
-    entry = elf_strtab_entry_new(str);
+    entry = elf_strtab_entry_create(str);
     entry->index = last->index + strlen(last->str) + 1;
 
     STAILQ_INSERT_TAIL(strtab, entry, qlink);
@@ -204,7 +221,7 @@ elf_strtab_append_str(elf_strtab_head *strtab, const char *str)
 }
 
 void
-elf_strtab_delete(elf_strtab_head *strtab)
+elf_strtab_destroy(elf_strtab_head *strtab)
 {
     elf_strtab_entry *s1, *s2;
 
@@ -245,8 +262,8 @@ elf_strtab_output_to_file(FILE *f, elf_strtab_head *strtab)
 
 /* symtab functions */
 elf_symtab_entry *
-elf_symtab_entry_new(elf_strtab_entry *name,
-                    yasm_symrec *sym)
+elf_symtab_entry_create(elf_strtab_entry *name,
+                       yasm_symrec *sym)
 {
     elf_symtab_entry *entry = yasm_xmalloc(sizeof(elf_symtab_entry));
     entry->sym = sym;
@@ -263,20 +280,31 @@ elf_symtab_entry_new(elf_strtab_entry *name,
     return entry;
 }
 
-void
-elf_symtab_entry_delete(elf_symtab_entry *entry)
+static void
+elf_symtab_entry_destroy(elf_symtab_entry *entry)
 {
     if (entry == NULL)
        yasm_internal_error("symtab entry is null");
 
     if (entry->xsize)
-       yasm_expr_delete(entry->xsize);
+       yasm_expr_destroy(entry->xsize);
     yasm_xfree(entry);
 }
 
-void
-elf_symtab_entry_print(FILE *f, int indent_level, elf_symtab_entry *entry)
+static void
+elf_symrec_data_destroy(void *data)
 {
+    /* do nothing, as this stuff is in the symtab anyway...  this speaks of bad
+     * design/use or this stuff, i fear */
+
+    /* watch for double-free here ... */
+    /*elf_symtab_entry_destroy((elf_symtab_entry *)data);*/
+}
+
+static void
+elf_symtab_entry_print(void *data, FILE *f, int indent_level)
+{
+    elf_symtab_entry *entry = data;
     if (entry == NULL)
        yasm_internal_error("symtab entry is null");
 
@@ -298,14 +326,14 @@ elf_symtab_entry_print(FILE *f, int indent_level, elf_symtab_entry *entry)
     }
     fprintf(f, "%*ssize=", indent_level, "");
     if (entry->xsize)
-       yasm_expr_print(f, entry->xsize);
+       yasm_expr_print(entry->xsize, f);
     else
        fprintf(f, "%ld", entry->size);
     fprintf(f, "\n");
 }
 
 elf_symtab_head *
-elf_symtab_new()
+elf_symtab_create()
 {
     elf_symtab_head *symtab = yasm_xmalloc(sizeof(elf_symtab_head));
     elf_symtab_entry *entry = yasm_xmalloc(sizeof(elf_symtab_entry));
@@ -347,7 +375,7 @@ elf_symtab_insert_local_sym(elf_symtab_head *symtab,
     elf_strtab_entry *name = strtab
        ? elf_strtab_append_str(strtab, yasm_symrec_get_name(sym))
        : NULL;
-    elf_symtab_entry *entry = elf_symtab_entry_new(name, sym);
+    elf_symtab_entry *entry = elf_symtab_entry_create(name, sym);
     elf_symtab_entry *after = STAILQ_FIRST(symtab);
     elf_symtab_entry *before = NULL;
 
@@ -362,7 +390,7 @@ elf_symtab_insert_local_sym(elf_symtab_head *symtab,
 }
 
 void
-elf_symtab_delete(elf_symtab_head *symtab)
+elf_symtab_destroy(elf_symtab_head *symtab)
 {
     elf_symtab_entry *s1, *s2;
 
@@ -374,7 +402,7 @@ elf_symtab_delete(elf_symtab_head *symtab)
     s1 = STAILQ_FIRST(symtab);
     while (s1 != NULL) {
        s2 = STAILQ_NEXT(s1, qlink);
-       elf_symtab_entry_delete(s1);
+       elf_symtab_entry_destroy(s1);
        s1 = s2;
     }
     yasm_xfree(symtab);
@@ -426,7 +454,7 @@ elf_symtab_write_to_file(FILE *f, elf_symtab_head *symtab)
                    N_("size specifier not an integer expression"));
        }
        else
-           size_intn = yasm_intnum_new_uint(entry->size);
+           size_intn = yasm_intnum_create_uint(entry->size);
 
        /* get EQU value for constants */
        if (entry->sym) {
@@ -446,11 +474,11 @@ elf_symtab_write_to_file(FILE *f, elf_symtab_head *symtab)
 
                value_intn = yasm_intnum_copy(equ_intn);
                entry->index = SHN_ABS;
-               yasm_expr_delete(equ_expr);
+               yasm_expr_destroy(equ_expr);
            }
        }
        if (value_intn == NULL)
-           value_intn = yasm_intnum_new_uint(entry->value);
+           value_intn = yasm_intnum_create_uint(entry->value);
 
        switch (cur_elf) {
            case ELF32:
@@ -461,7 +489,8 @@ elf_symtab_write_to_file(FILE *f, elf_symtab_head *symtab)
                YASM_WRITE_8(bufp, ELF32_ST_INFO(entry->bind, entry->type));
                YASM_WRITE_8(bufp, 0);
                if (entry->sect) {
-                   elf_secthead *shead = yasm_section_get_of_data(entry->sect);
+                   elf_secthead *shead =
+                       yasm_section_get_data(entry->sect, &elf_section_data);
                    if (!shead)
                        yasm_internal_error(
                            N_("symbol references section without data"));
@@ -478,7 +507,8 @@ elf_symtab_write_to_file(FILE *f, elf_symtab_head *symtab)
                YASM_WRITE_8(bufp, ELF64_ST_INFO(entry->bind, entry->type));
                YASM_WRITE_8(bufp, 0);
                if (entry->sect) {
-                   elf_secthead *shead = yasm_section_get_of_data(entry->sect);
+                   elf_secthead *shead =
+                       yasm_section_get_data(entry->sect, &elf_section_data);
                    if (!shead)
                        yasm_internal_error(
                            N_("symbol references section without data"));
@@ -493,8 +523,8 @@ elf_symtab_write_to_file(FILE *f, elf_symtab_head *symtab)
                break;
        }
 
-       yasm_intnum_delete(size_intn);
-       yasm_intnum_delete(value_intn);
+       yasm_intnum_destroy(size_intn);
+       yasm_intnum_destroy(value_intn);
 
        prev = entry;
     }
@@ -521,19 +551,19 @@ void elf_symtab_set_nonzero(elf_symtab_entry *entry,
 
 
 elf_secthead *
-elf_secthead_new(elf_strtab_entry      *name,
-                elf_section_type        type,
-                elf_section_flags       flags,
-                elf_section_index       idx,
-                elf_address             offset,
-                elf_size                size)
+elf_secthead_create(elf_strtab_entry   *name,
+                   elf_section_type     type,
+                   elf_section_flags    flags,
+                   elf_section_index    idx,
+                   elf_address          offset,
+                   elf_size             size)
 {
     elf_secthead *esd = yasm_xmalloc(sizeof(elf_secthead));
 
     esd->type = type;
     esd->flags = flags;
     esd->offset = offset;
-    esd->size = yasm_intnum_new_uint(size);
+    esd->size = yasm_intnum_create_uint(size);
     esd->link = 0;
     esd->info = 0;
     esd->align = NULL;
@@ -553,12 +583,12 @@ elf_secthead_new(elf_strtab_entry *name,
        switch (cur_elf) {
            case ELF32:
                esd->entsize = SYMTAB32_SIZE;
-               esd->align = yasm_intnum_new_uint(SYMTAB32_ALIGN);
+               esd->align = yasm_intnum_create_uint(SYMTAB32_ALIGN);
                break;
 
            case ELF64:
                esd->entsize = SYMTAB64_SIZE;
-               esd->align = yasm_intnum_new_uint(SYMTAB64_ALIGN);
+               esd->align = yasm_intnum_create_uint(SYMTAB64_ALIGN);
                break;
 
            default:
@@ -570,26 +600,34 @@ elf_secthead_new(elf_strtab_entry *name,
 }
 
 void
-elf_secthead_delete(elf_secthead *shead)
+elf_secthead_destroy(elf_secthead *shead)
 {
     if (shead == NULL)
        yasm_internal_error(N_("shead is null"));
 
     if (shead->align)
-       yasm_intnum_delete(shead->align);
+       yasm_intnum_destroy(shead->align);
 
     if (shead->relocs)
-       elf_reloc_delete(shead->relocs);
+       elf_reloc_destroy(shead->relocs);
 
     yasm_xfree(shead);
 }
 
-void elf_secthead_print(FILE *f, int indent_level, elf_secthead *sect)
+static void
+elf_section_data_destroy(void *data)
+{
+    elf_secthead_destroy((elf_secthead *)data);
+}
+
+static void
+elf_secthead_print(void *data, FILE *f, int indent_level)
 {
+    elf_secthead *sect = data;
     fprintf(f, "%*sname=%s\n", indent_level, "",
            sect->name ? sect->name->str : "<undef>");
     fprintf(f, "%*ssym=\n", indent_level, "");
-    yasm_symrec_print(f, indent_level+1, sect->sym);
+    yasm_symrec_print(sect->sym, f, indent_level+1);
     fprintf(f, "%*sindex=0x%x\n", indent_level, "", sect->index);
     fprintf(f, "%*sflags=", indent_level, "");
     if (sect->flags & SHF_WRITE)
@@ -692,7 +730,7 @@ elf_secthead_append_reloc(elf_secthead *shead, elf_reloc_entry *reloc)
 
     if (!shead->relocs)
     {
-       shead->relocs = elf_relocs_new();
+       shead->relocs = elf_relocs_create();
        new_sect = 1;
     }
     shead->nreloc++;
@@ -744,12 +782,12 @@ elf_secthead_write_rel_to_file(FILE *f, elf_section_index symtab_idx,
            YASM_WRITE_64Z_L(bufp, 0);
            YASM_WRITE_64Z_L(bufp, shead->rel_offset);
 
-           nreloc = yasm_intnum_new_uint(shead->nreloc);
-           relocsize = yasm_intnum_new_uint(RELOC64_SIZE);
+           nreloc = yasm_intnum_create_uint(shead->nreloc);
+           relocsize = yasm_intnum_create_uint(RELOC64_SIZE);
            yasm_intnum_calc(relocsize, YASM_EXPR_MUL, nreloc, 0);
            YASM_WRITE_64I_L(bufp, relocsize);          /* size */
-           yasm_intnum_delete(nreloc);
-           yasm_intnum_delete(relocsize);
+           yasm_intnum_destroy(nreloc);
+           yasm_intnum_destroy(relocsize);
 
            YASM_WRITE_32_L(bufp, symtab_idx);          /* link: symtab index */
            YASM_WRITE_32_L(bufp, shead->index);        /* info: relocated's index */
@@ -793,7 +831,7 @@ elf_secthead_write_relocs_to_file(FILE *f, elf_secthead *shead)
        unsigned char r_type=0, r_sym;
        elf_symtab_entry *esym;
 
-       esym = yasm_symrec_get_of_data(reloc->sym);
+       esym = yasm_symrec_get_data(reloc->sym, &elf_symrec_data);
        if (esym)
            r_sym = esym->symindex;
        else
@@ -901,7 +939,7 @@ const yasm_intnum *
 elf_secthead_set_align(elf_secthead *shead, yasm_intnum *align)
 {
     if (shead->align != NULL)
-       yasm_intnum_delete(shead->align);
+       yasm_intnum_destroy(shead->align);
     
     return shead->align = align;
 }
index c06fa7ea5568e797d433bd63b951d6c21cf61a19..91cd0915276ff6eba1f72c9869fc8e7402da5c61 100644 (file)
@@ -335,38 +335,38 @@ struct elf_symtab_entry {
 
 #endif /* defined(YASM_OBJFMT_ELF_INTERNAL) */
 
+extern const yasm_assoc_data_callback elf_section_data;
+extern const yasm_assoc_data_callback elf_symrec_data;
 
 
-int elf_set_arch(struct yasm_arch *arch, const char *machine);
+int elf_set_arch(struct yasm_arch *arch);
 
 /* reloc functions */
-elf_reloc_entry *elf_reloc_entry_new(yasm_symrec *sym,
-                                    yasm_intnum *addr,
-                                    int rel,
-                                    size_t valsize);
-void elf_reloc_entry_delete(elf_reloc_entry *entry);
-elf_reloc_head *elf_relocs_new(void);
-void elf_reloc_delete(elf_reloc_head *head);
+elf_reloc_entry *elf_reloc_entry_create(yasm_symrec *sym,
+                                       yasm_intnum *addr,
+                                       int rel,
+                                       size_t valsize);
+void elf_reloc_entry_destroy(elf_reloc_entry *entry);
+elf_reloc_head *elf_relocs_create(void);
+void elf_reloc_destroy(elf_reloc_head *head);
 
 /* strtab functions */
-elf_strtab_entry *elf_strtab_entry_new(const char *str);
-elf_strtab_head *elf_strtab_new(void);
+elf_strtab_entry *elf_strtab_entry_create(const char *str);
+elf_strtab_head *elf_strtab_create(void);
 elf_strtab_entry *elf_strtab_append_str(elf_strtab_head *head, const char *str);
-void elf_strtab_delete(elf_strtab_head *head);
+void elf_strtab_destroy(elf_strtab_head *head);
 unsigned long elf_strtab_output_to_file(FILE *f, elf_strtab_head *head);
 
 /* symtab functions */
-elf_symtab_entry *elf_symtab_entry_new(elf_strtab_entry *name,
-                                      struct yasm_symrec *sym);
-void elf_symtab_entry_delete(elf_symtab_entry *entry);
-void elf_symtab_entry_print(FILE *f, int indent_level, elf_symtab_entry *entry);
-elf_symtab_head *elf_symtab_new(void);
+elf_symtab_entry *elf_symtab_entry_create(elf_strtab_entry *name,
+                                         struct yasm_symrec *sym);
+elf_symtab_head *elf_symtab_create(void);
 elf_symtab_entry *elf_symtab_append_entry(elf_symtab_head *symtab,
                                          elf_symtab_entry *entry);
 elf_symtab_entry *elf_symtab_insert_local_sym(elf_symtab_head *symtab,
                                              elf_strtab_head *strtab,
                                              struct yasm_symrec *sym);
-void elf_symtab_delete(elf_symtab_head *head);
+void elf_symtab_destroy(elf_symtab_head *head);
 unsigned long elf_symtab_assign_indices(elf_symtab_head *symtab);
 unsigned long elf_symtab_write_to_file(FILE *f, elf_symtab_head *symtab);
 void elf_symtab_set_nonzero(elf_symtab_entry   *entry,
@@ -379,16 +379,15 @@ void elf_symtab_set_nonzero(elf_symtab_entry      *entry,
 
 
 /* section header functions */
-elf_secthead *elf_secthead_new(elf_strtab_entry                *name,
-                              elf_section_type         type,
-                              elf_section_flags        flags,
-                              elf_section_index        idx,
-                              elf_address              offset,
-                              elf_size                 size);
-void elf_secthead_delete(elf_secthead *esh);
+elf_secthead *elf_secthead_create(elf_strtab_entry     *name,
+                                 elf_section_type      type,
+                                 elf_section_flags     flags,
+                                 elf_section_index     idx,
+                                 elf_address           offset,
+                                 elf_size              size);
+void elf_secthead_destroy(elf_secthead *esd);
 unsigned long elf_secthead_write_to_file(FILE *f, elf_secthead *esd,
                                         elf_section_index sindex);
-void elf_secthead_print(FILE *f, int indent_level, elf_secthead *esh);
 int elf_secthead_append_reloc(elf_secthead *shead, elf_reloc_entry *reloc);
 elf_section_type elf_secthead_get_type(elf_secthead *shead);
 int elf_secthead_is_empty(elf_secthead *shead);
index 3887a4a6fb17535d01a4be121869ba1a02543f16..6b04c231d5a2a35139749559385db9a343e7e31d 100644 (file)
@@ -45,29 +45,30 @@ static int basic_optimize_section_1(yasm_section *sect,
                                    /*@unused@*/ /*@null@*/ void *d);
 
 static /*@null@*/ yasm_intnum *
-basic_optimize_calc_bc_dist_1(yasm_section *sect,
-                             /*@null@*/ yasm_bytecode *precbc1,
-                             /*@null@*/ yasm_bytecode *precbc2)
+basic_optimize_calc_bc_dist_1(yasm_bytecode *precbc1, yasm_bytecode *precbc2)
 {
     unsigned int dist;
     yasm_intnum *intn;
 
-    if (yasm_section_get_opt_flags(sect) == SECTFLAG_NONE) {
+    if (precbc1->section != precbc2->section)
+       yasm_internal_error(N_("Trying to calc_bc_dist between sections"));
+
+    if (yasm_section_get_opt_flags(precbc1->section) == SECTFLAG_NONE) {
        /* Section not started.  Optimize it (recursively). */
-       basic_optimize_section_1(sect, NULL);
+       basic_optimize_section_1(precbc1->section, NULL);
     }
 
     /* If a section is done, the following will always succeed.  If it's in-
      * progress, this will fail if the bytecode comes AFTER the current one.
      */
-    if (precbc2) {
+    if (precbc2 != yasm_section_bcs_first(precbc2->section)) {
        if (precbc2->opt_flags == BCFLAG_DONE) {
            dist = precbc2->offset + precbc2->len;
-           if (precbc1) {
+           if (precbc1 != yasm_section_bcs_first(precbc1->section)) {
                if (precbc1->opt_flags == BCFLAG_DONE) {
                    if (dist < precbc1->offset + precbc1->len) {
-                       intn = yasm_intnum_new_uint(precbc1->offset +
-                                                   precbc1->len - dist);
+                       intn = yasm_intnum_create_uint(precbc1->offset +
+                                                      precbc1->len - dist);
                        yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL,
                                         precbc1->line);
                        return intn;
@@ -77,28 +78,27 @@ basic_optimize_calc_bc_dist_1(yasm_section *sect,
                    return NULL;
                }
            }
-           return yasm_intnum_new_uint(dist);
+           return yasm_intnum_create_uint(dist);
        } else {
            return NULL;
        }
     } else {
-       if (precbc1) {
+       if (precbc1 != yasm_section_bcs_first(precbc1->section)) {
            if (precbc1->opt_flags == BCFLAG_DONE) {
-               intn = yasm_intnum_new_uint(precbc1->offset + precbc1->len);
+               intn = yasm_intnum_create_uint(precbc1->offset + precbc1->len);
                yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, precbc1->line);
                return intn;
            } else {
                return NULL;
            }
        } else {
-           return yasm_intnum_new_uint(0);
+           return yasm_intnum_create_uint(0);
        }
     }
 }
 
 typedef struct basic_optimize_data {
     /*@observer@*/ yasm_bytecode *precbc;
-    /*@observer@*/ const yasm_section *sect;
     int saw_unknown;
 } basic_optimize_data;
 
@@ -116,18 +116,14 @@ basic_optimize_bytecode_1(/*@observer@*/ yasm_bytecode *bc, void *d)
 
     bc->opt_flags = BCFLAG_INPROGRESS;
 
-    if (!data->precbc)
-       bc->offset = 0;
-    else
-       bc->offset = data->precbc->offset + data->precbc->len;
+    bc->offset = data->precbc->offset + data->precbc->len;
     data->precbc = bc;
 
     /* We're doing just a single pass, so essentially ignore whether the size
      * is minimum or not, and just check for indeterminate length (indicative
      * of circular reference).
      */
-    bcr_retval = yasm_bc_resolve(bc, 0, data->sect,
-                                basic_optimize_calc_bc_dist_1);
+    bcr_retval = yasm_bc_resolve(bc, 0, basic_optimize_calc_bc_dist_1);
     if (bcr_retval & YASM_BC_RESOLVE_UNKNOWN_LEN) {
        if (!(bcr_retval & YASM_BC_RESOLVE_ERROR))
            yasm__error(bc->line, N_("circular reference detected."));
@@ -148,8 +144,7 @@ basic_optimize_section_1(yasm_section *sect, /*@null@*/ void *d)
     unsigned long flags;
     int retval;
 
-    data.precbc = NULL;
-    data.sect = sect;
+    data.precbc = yasm_section_bcs_first(sect);
     data.saw_unknown = 0;
 
     /* Don't even bother if we're in-progress or done. */
@@ -161,8 +156,7 @@ basic_optimize_section_1(yasm_section *sect, /*@null@*/ void *d)
 
     yasm_section_set_opt_flags(sect, SECTFLAG_INPROGRESS);
 
-    retval = yasm_bcs_traverse(yasm_section_get_bytecodes(sect), &data,
-                              basic_optimize_bytecode_1);
+    retval = yasm_section_bcs_traverse(sect, &data, basic_optimize_bytecode_1);
     if (retval != 0)
        return retval;
 
@@ -184,13 +178,10 @@ basic_optimize_bytecode_2(/*@observer@*/ yasm_bytecode *bc, /*@null@*/ void *d)
     if (bc->opt_flags != BCFLAG_DONE)
        yasm_internal_error(N_("Optimizer pass 1 missed a bytecode!"));
 
-    if (!data->precbc)
-       bc->offset = 0;
-    else
-       bc->offset = data->precbc->offset + data->precbc->len;
+    bc->offset = data->precbc->offset + data->precbc->len;
     data->precbc = bc;
 
-    if (yasm_bc_resolve(bc, 1, data->sect, yasm_common_calc_bc_dist) < 0)
+    if (yasm_bc_resolve(bc, 1, yasm_common_calc_bc_dist) < 0)
        return -1;
     return 0;
 }
@@ -200,18 +191,16 @@ basic_optimize_section_2(yasm_section *sect, /*@unused@*/ /*@null@*/ void *d)
 {
     basic_optimize_data data;
 
-    data.precbc = NULL;
-    data.sect = sect;
+    data.precbc = yasm_section_bcs_first(sect);
 
     if (yasm_section_get_opt_flags(sect) != SECTFLAG_DONE)
        yasm_internal_error(N_("Optimizer pass 1 missed a section!"));
 
-    return yasm_bcs_traverse(yasm_section_get_bytecodes(sect), &data,
-                            basic_optimize_bytecode_2);
+    return yasm_section_bcs_traverse(sect, &data, basic_optimize_bytecode_2);
 }
 
 static void
-basic_optimize(yasm_sectionhead *sections)
+basic_optimize(yasm_object *object)
 {
     int saw_unknown = 0;
 
@@ -227,13 +216,13 @@ basic_optimize(yasm_sectionhead *sections)
      *   - not strictly top->bottom scanning; we scan through a section and
      *     hop to other sections as necessary.
      */
-    if (yasm_sections_traverse(sections, &saw_unknown,
-                              basic_optimize_section_1) < 0 ||
+    if (yasm_object_sections_traverse(object, &saw_unknown,
+                                     basic_optimize_section_1) < 0 ||
        saw_unknown != 0)
        return;
 
     /* Check completion of all sections and save bytecode changes */
-    yasm_sections_traverse(sections, NULL, basic_optimize_section_2);
+    yasm_object_sections_traverse(object, NULL, basic_optimize_section_2);
 }
 
 /* Define optimizer structure -- see optimizer.h for details */
index 1a1f24e2fa99dfcd68ff4583c551ca04e85ed97c..2e1f3f189c135f14bd94586cf8708cf32c13e82f 100644 (file)
@@ -39,19 +39,17 @@ RCSID("$IdPath$");
 #include "modules/parsers/nasm/nasm-parser.h"
 #include "modules/parsers/nasm/nasm-defs.h"
 
-
-static void nasm_parser_error(const char *);
 static void nasm_parser_directive
-    (const char *name, yasm_valparamhead *valparams,
+    (yasm_parser_nasm *parser_nasm, const char *name,
+     yasm_valparamhead *valparams,
      /*@null@*/ yasm_valparamhead *objext_valparams);
 static int fix_directive_symrec(/*@null@*/ yasm_expr__item *ei,
                                /*@null@*/ void *d);
 
-static /*@null@*/ yasm_bytecode *nasm_parser_prev_bc = (yasm_bytecode *)NULL;
-static yasm_bytecode *nasm_parser_temp_bc;
-
-/* additional data declarations (dynamically generated) */
-/* @DATADECLS@ */
+#define nasm_parser_error(s)   yasm__parser_error(cur_line, s)
+#define YYPARSE_PARAM  parser_nasm_arg
+#define parser_nasm    ((yasm_parser_nasm *)parser_nasm_arg)
+#define nasm_parser_debug   (parser_nasm->debug)
 
 /*@-usedef -nullassign -memtrans -usereleased -compdef -mustfree@*/
 %}
@@ -116,12 +114,11 @@ static yasm_bytecode *nasm_parser_temp_bc;
 %%
 input: /* empty */
     | input line    {
-       nasm_parser_temp_bc =
-           yasm_bcs_append(yasm_section_get_bytecodes(nasm_parser_cur_section),
-                           $2);
-       if (nasm_parser_temp_bc)
-           nasm_parser_prev_bc = nasm_parser_temp_bc;
-       nasm_parser_linemgr->goto_next();
+       parser_nasm->temp_bc =
+           yasm_section_bcs_append(parser_nasm->cur_section, $2);
+       if (parser_nasm->temp_bc)
+           parser_nasm->prev_bc = parser_nasm->temp_bc;
+       yasm_linemap_goto_next(parser_nasm->linemap);
     }
 ;
 
@@ -131,19 +128,19 @@ line: '\n'                { $$ = (yasm_bytecode *)NULL; }
        /* %line indicates the line number of the *next* line, so subtract out
         * the increment when setting the line number.
         */
-       nasm_parser_linemgr->set($5, yasm_intnum_get_uint($2)
-                                - yasm_intnum_get_uint($4),
-                                yasm_intnum_get_uint($4));
-       yasm_intnum_delete($2);
-       yasm_intnum_delete($4);
+       yasm_linemap_set(parser_nasm->linemap, $5,
+           yasm_intnum_get_uint($2) - yasm_intnum_get_uint($4),
+           yasm_intnum_get_uint($4));
+       yasm_intnum_destroy($2);
+       yasm_intnum_destroy($4);
        yasm_xfree($5);
        $$ = (yasm_bytecode *)NULL;
     }
-    | '[' { nasm_parser_set_directive_state(); } directive ']' '\n' {
+    | '[' { parser_nasm->state = DIRECTIVE; } directive ']' '\n' {
        $$ = (yasm_bytecode *)NULL;
     }
     | error '\n'       {
-       yasm__error(cur_lindex,
+       yasm__error(cur_line,
                    N_("label or instruction expected at start of line"));
        $$ = (yasm_bytecode *)NULL;
        yyerrok;
@@ -156,7 +153,7 @@ lineexp: exp
     | label exp                        { $$ = $2; }
     | label TIMES expr exp     { $$ = $4; yasm_bc_set_multiple($$, $3); }
     | label_id_equ EQU expr    {
-       yasm_symrec_define_equ($1, $3, cur_lindex);
+       yasm_symtab_define_equ(p_symtab, $1, $3, cur_line);
        yasm_xfree($1);
        $$ = (yasm_bytecode *)NULL;
     }
@@ -164,43 +161,42 @@ lineexp: exp
 
 exp: instr
     | DECLARE_DATA datavals            {
-       $$ = yasm_bc_new_data(&$2, $1, cur_lindex);
+       $$ = yasm_bc_create_data(&$2, $1, cur_line);
     }
     | RESERVE_SPACE expr               {
-       $$ = yasm_bc_new_reserve($2, $1, cur_lindex);
+       $$ = yasm_bc_create_reserve($2, $1, cur_line);
     }
     | INCBIN STRING                    {
-       $$ = yasm_bc_new_incbin($2, NULL, NULL, cur_lindex);
+       $$ = yasm_bc_create_incbin($2, NULL, NULL, cur_line);
     }
     | INCBIN STRING ',' expr           {
-       $$ = yasm_bc_new_incbin($2, $4, NULL, cur_lindex);
+       $$ = yasm_bc_create_incbin($2, $4, NULL, cur_line);
     }
     | INCBIN STRING ',' expr ',' expr  {
-       $$ = yasm_bc_new_incbin($2, $4, $6, cur_lindex);
+       $$ = yasm_bc_create_incbin($2, $4, $6, cur_line);
     }
 ;
 
 instr: INSN            {
-       $$ = nasm_parser_arch->parse_insn($1, 0, NULL, nasm_parser_cur_section,
-                                         nasm_parser_prev_bc, cur_lindex);
+       $$ = p_arch->module->parse_insn(p_arch, $1, 0, NULL,
+                                       parser_nasm->prev_bc, cur_line);
     }
     | INSN operands    {
-       $$ = nasm_parser_arch->parse_insn($1, $2.num_operands, &$2.operands,
-                                         nasm_parser_cur_section,
-                                         nasm_parser_prev_bc, cur_lindex);
+       $$ = p_arch->module->parse_insn(p_arch, $1, $2.num_operands,
+           &$2.operands, parser_nasm->prev_bc, cur_line);
        yasm_ops_delete(&$2.operands, 0);
     }
     | INSN error       {
-       yasm__error(cur_lindex, N_("expression syntax error"));
+       yasm__error(cur_line, N_("expression syntax error"));
        $$ = NULL;
     }
     | PREFIX instr     {
        $$ = $2;
-       nasm_parser_arch->parse_prefix($$, $1, cur_lindex);
+       p_arch->module->parse_prefix(p_arch, $$, $1, cur_line);
     }
     | SEGREG instr     {
        $$ = $2;
-       nasm_parser_arch->parse_seg_prefix($$, $1[0], cur_lindex);
+       p_arch->module->parse_seg_prefix(p_arch, $$, $1[0], cur_line);
     }
 ;
 
@@ -211,34 +207,34 @@ datavals: dataval     {
     | datavals ',' dataval  { yasm_dvs_append(&$1, $3); $$ = $1; }
 ;
 
-dataval: dvexpr                { $$ = yasm_dv_new_expr($1); }
-    | STRING           { $$ = yasm_dv_new_string($1); }
+dataval: dvexpr                { $$ = yasm_dv_create_expr($1); }
+    | STRING           { $$ = yasm_dv_create_string($1); }
     | error            {
-       yasm__error(cur_lindex, N_("expression syntax error"));
+       yasm__error(cur_line, N_("expression syntax error"));
        $$ = (yasm_dataval *)NULL;
     }
 ;
 
 label: label_id            {
-       yasm_symrec_define_label($1, nasm_parser_cur_section,
-                                nasm_parser_prev_bc, 1, cur_lindex);
+       yasm_symtab_define_label(p_symtab, $1, parser_nasm->prev_bc, 1,
+                                cur_line);
        yasm_xfree($1);
     }
     | label_id ':'  {
-       yasm_symrec_define_label($1, nasm_parser_cur_section,
-                                nasm_parser_prev_bc, 1, cur_lindex);
+       yasm_symtab_define_label(p_symtab, $1, parser_nasm->prev_bc, 1,
+                                cur_line);
        yasm_xfree($1);
     }
 ;
 
 label_id: ID       {
        $$ = $1;
-       if (nasm_parser_locallabel_base)
-           yasm_xfree(nasm_parser_locallabel_base);
-       nasm_parser_locallabel_base_len = strlen($1);
-       nasm_parser_locallabel_base =
-           yasm_xmalloc(nasm_parser_locallabel_base_len+1);
-       strcpy(nasm_parser_locallabel_base, $1);
+       if (parser_nasm->locallabel_base)
+           yasm_xfree(parser_nasm->locallabel_base);
+       parser_nasm->locallabel_base_len = strlen($1);
+       parser_nasm->locallabel_base =
+           yasm_xmalloc(parser_nasm->locallabel_base_len+1);
+       strcpy(parser_nasm->locallabel_base, $1);
     }
     | SPECIAL_ID
     | LOCAL_ID
@@ -254,7 +250,7 @@ directive: DIRECTIVE_NAME directive_val     {
        yasm_xfree($1);
     }
     | DIRECTIVE_NAME error             {
-       yasm__error(cur_lindex, N_("invalid arguments to [%s]"), $1);
+       yasm__error(cur_line, N_("invalid arguments to [%s]"), $1);
        yasm_xfree($1);
     }
 ;
@@ -262,10 +258,10 @@ directive: DIRECTIVE_NAME directive_val   {
     /* $<str_val>0 is the DIRECTIVE_NAME */
     /* After : is (optional) object-format specific extension */
 directive_val: directive_valparams {
-       nasm_parser_directive($<str_val>0, &$1, NULL);
+       nasm_parser_directive(parser_nasm, $<str_val>0, &$1, NULL);
     }
     | directive_valparams ':' directive_valparams {
-       nasm_parser_directive($<str_val>0, &$1, &$3);
+       nasm_parser_directive(parser_nasm, $<str_val>0, &$1, &$3);
     }
 ;
 
@@ -290,28 +286,29 @@ directive_valparam: direxpr       {
         */
        const /*@null@*/ yasm_symrec *vp_symrec;
        if ((vp_symrec = yasm_expr_get_symrec(&$1, 0))) {
-           $$ = yasm_vp_new(yasm__xstrdup(yasm_symrec_get_name(vp_symrec)),
-                            NULL);
-           yasm_expr_delete($1);
+           $$ = yasm_vp_create(yasm__xstrdup(yasm_symrec_get_name(vp_symrec)),
+                               NULL);
+           yasm_expr_destroy($1);
        } else {
-           yasm_expr__traverse_leaves_in($1, NULL, fix_directive_symrec);
-           $$ = yasm_vp_new(NULL, $1);
+           yasm_expr__traverse_leaves_in($1, parser_nasm,
+                                         fix_directive_symrec);
+           $$ = yasm_vp_create(NULL, $1);
        }
     }
-    | STRING                   { $$ = yasm_vp_new($1, NULL); }
+    | STRING                   { $$ = yasm_vp_create($1, NULL); }
     | ID '=' direxpr           {
-       yasm_expr__traverse_leaves_in($3, NULL, fix_directive_symrec);
-       $$ = yasm_vp_new($1, $3);
+       yasm_expr__traverse_leaves_in($3, parser_nasm, fix_directive_symrec);
+       $$ = yasm_vp_create($1, $3);
     }
 ;
 
 /* memory addresses */
 memaddr: expr              {
-       $$ = nasm_parser_arch->ea_new_expr($1);
+       $$ = p_arch->module->ea_create(p_arch, $1);
     }
     | SEGREG ':' memaddr    {
        $$ = $3;
-       nasm_parser_arch->parse_seg_override($$, $1[0], cur_lindex);
+       p_arch->module->parse_seg_override(p_arch, $$, $1[0], cur_line);
     }
     | BYTE memaddr         {
        $$ = $2;
@@ -319,19 +316,19 @@ memaddr: expr                 {
     }
     | HWORD memaddr        {
        $$ = $2;
-       yasm_ea_set_len($$, nasm_parser_arch->wordsize/2);
+       yasm_ea_set_len($$, p_arch->module->wordsize/2);
     }
     | WORD memaddr         {
        $$ = $2;
-       yasm_ea_set_len($$, nasm_parser_arch->wordsize);
+       yasm_ea_set_len($$, p_arch->module->wordsize);
     }
     | DWORD memaddr        {
        $$ = $2;
-       yasm_ea_set_len($$, nasm_parser_arch->wordsize*2);
+       yasm_ea_set_len($$, p_arch->module->wordsize*2);
     }
     | QWORD memaddr        {
        $$ = $2;
-       yasm_ea_set_len($$, nasm_parser_arch->wordsize*4);
+       yasm_ea_set_len($$, p_arch->module->wordsize*4);
     }
     | NOSPLIT memaddr      { $$ = $2; yasm_ea_set_nosplit($$, 1); }
 ;
@@ -349,70 +346,70 @@ operands: operand     {
     }
 ;
 
-operand: '[' memaddr ']'    { $$ = yasm_operand_new_mem($2); }
-    | expr                 { $$ = yasm_operand_new_imm($1); }
-    | SEGREG               { $$ = yasm_operand_new_segreg($1[0]); }
+operand: '[' memaddr ']'    { $$ = yasm_operand_create_mem($2); }
+    | expr                 { $$ = yasm_operand_create_imm($1); }
+    | SEGREG               { $$ = yasm_operand_create_segreg($1[0]); }
     | BYTE operand         {
        $$ = $2;
        if ($$->type == YASM_INSN__OPERAND_REG &&
-           nasm_parser_arch->get_reg_size($$->data.reg) != 1)
-           yasm__error(cur_lindex, N_("cannot override register size"));
+           p_arch->module->get_reg_size(p_arch, $$->data.reg) != 1)
+           yasm__error(cur_line, N_("cannot override register size"));
        else
            $$->size = 1;
     }
     | HWORD operand        {
        $$ = $2;
        if ($$->type == YASM_INSN__OPERAND_REG &&
-           nasm_parser_arch->get_reg_size($$->data.reg) !=
-           nasm_parser_arch->wordsize/2)
-           yasm__error(cur_lindex, N_("cannot override register size"));
+           p_arch->module->get_reg_size(p_arch, $$->data.reg) !=
+           p_arch->module->wordsize/2)
+           yasm__error(cur_line, N_("cannot override register size"));
        else
-           $$->size = nasm_parser_arch->wordsize/2;
+           $$->size = p_arch->module->wordsize/2;
     }
     | WORD operand         {
        $$ = $2;
        if ($$->type == YASM_INSN__OPERAND_REG &&
-           nasm_parser_arch->get_reg_size($$->data.reg) !=
-           nasm_parser_arch->wordsize)
-           yasm__error(cur_lindex, N_("cannot override register size"));
+           p_arch->module->get_reg_size(p_arch, $$->data.reg) !=
+           p_arch->module->wordsize)
+           yasm__error(cur_line, N_("cannot override register size"));
        else
-           $$->size = nasm_parser_arch->wordsize;
+           $$->size = p_arch->module->wordsize;
     }
     | DWORD operand        {
        $$ = $2;
        if ($$->type == YASM_INSN__OPERAND_REG &&
-           nasm_parser_arch->get_reg_size($$->data.reg) !=
-           nasm_parser_arch->wordsize*2)
-           yasm__error(cur_lindex, N_("cannot override register size"));
+           p_arch->module->get_reg_size(p_arch, $$->data.reg) !=
+           p_arch->module->wordsize*2)
+           yasm__error(cur_line, N_("cannot override register size"));
        else
-           $$->size = nasm_parser_arch->wordsize*2;
+           $$->size = p_arch->module->wordsize*2;
     }
     | QWORD operand        {
        $$ = $2;
        if ($$->type == YASM_INSN__OPERAND_REG &&
-           nasm_parser_arch->get_reg_size($$->data.reg) !=
-           nasm_parser_arch->wordsize*4)
-           yasm__error(cur_lindex, N_("cannot override register size"));
+           p_arch->module->get_reg_size(p_arch, $$->data.reg) !=
+           p_arch->module->wordsize*4)
+           yasm__error(cur_line, N_("cannot override register size"));
        else
-           $$->size = nasm_parser_arch->wordsize*4;
+           $$->size = p_arch->module->wordsize*4;
     }
     | TWORD operand        {
        $$ = $2;
        if ($$->type == YASM_INSN__OPERAND_REG &&
-           nasm_parser_arch->get_reg_size($$->data.reg) !=
-           nasm_parser_arch->wordsize*5)
-           yasm__error(cur_lindex, N_("cannot override register size"));
+           p_arch->module->get_reg_size(p_arch, $$->data.reg) !=
+           p_arch->module->wordsize*5)
+           yasm__error(cur_line, N_("cannot override register size"));
        else
-           $$->size = nasm_parser_arch->wordsize*5;
+           $$->size = p_arch->module->wordsize*5;
     }
     | DQWORD operand       {
        $$ = $2;
        if ($$->type == YASM_INSN__OPERAND_REG &&
-           nasm_parser_arch->get_reg_size($$->data.reg) !=
-           nasm_parser_arch->wordsize*8)
-           yasm__error(cur_lindex, N_("cannot override register size"));
+           p_arch->module->get_reg_size(p_arch, $$->data.reg) !=
+           p_arch->module->wordsize*8)
+           yasm__error(cur_line, N_("cannot override register size"));
        else
-           $$->size = nasm_parser_arch->wordsize*8;
+           $$->size = p_arch->module->wordsize*8;
     }
     | TARGETMOD operand            { $$ = $2; $$->targetmod = $1[0]; }
 ;
@@ -423,7 +420,9 @@ operand: '[' memaddr ']'    { $$ = yasm_operand_new_mem($2); }
 direxpr: INTNUM                        { $$ = p_expr_new_ident(yasm_expr_int($1)); }
     | ID                       {
        $$ = p_expr_new_ident(yasm_expr_sym(
-           yasm_symrec_define_label($1, NULL, NULL, 0, cur_lindex)));
+           yasm_symtab_define_label(p_symtab, $1,
+               yasm_section_bcs_first(parser_nasm->cur_section), 0,
+               cur_line)));
        yasm_xfree($1);
     }
     | direxpr '|' direxpr      { $$ = p_expr_new_tree($1, YASM_EXPR_OR, $3); }
@@ -484,7 +483,7 @@ expr: INTNUM                { $$ = p_expr_new_ident(yasm_expr_int($1)); }
     | REG              { $$ = p_expr_new_ident(yasm_expr_reg($1[0])); }
     | STRING           {
        $$ = p_expr_new_ident(yasm_expr_int(
-           yasm_intnum_new_charconst_nasm($1, cur_lindex)));
+           yasm_intnum_create_charconst_nasm($1, cur_line)));
        yasm_xfree($1);
     }
     | explabel         { $$ = p_expr_new_ident(yasm_expr_sym($1)); }
@@ -519,161 +518,158 @@ expr: INTNUM            { $$ = p_expr_new_ident(yasm_expr_int($1)); }
 ;
 
 explabel: ID           {
-       $$ = yasm_symrec_use($1, cur_lindex);
+       $$ = yasm_symtab_use(p_symtab, $1, cur_line);
        yasm_xfree($1);
     }
     | SPECIAL_ID       {
-       $$ = yasm_symrec_use($1, cur_lindex);
+       $$ = yasm_symtab_use(p_symtab, $1, cur_line);
        yasm_xfree($1);
     }
     | LOCAL_ID         {
-       $$ = yasm_symrec_use($1, cur_lindex);
+       $$ = yasm_symtab_use(p_symtab, $1, cur_line);
        yasm_xfree($1);
     }
     | '$'              {
        /* "$" references the current assembly position */
-       $$ = yasm_symrec_define_label("$", nasm_parser_cur_section,
-                                     nasm_parser_prev_bc, 0, cur_lindex);
+       $$ = yasm_symtab_define_label(p_symtab, "$", parser_nasm->prev_bc, 0,
+                                     cur_line);
     }
     | START_SECTION_ID {
        /* "$$" references the start of the current section */
-       $$ = yasm_symrec_define_label("$$", nasm_parser_cur_section, NULL, 0,
-                                     cur_lindex);
+       $$ = yasm_symtab_define_label(p_symtab, "$$",
+           yasm_section_bcs_first(parser_nasm->cur_section), 0, cur_line);
     }
 ;
 
 %%
 /*@=usedef =nullassign =memtrans =usereleased =compdef =mustfree@*/
 
+#undef parser_nasm
+
 static int
-fix_directive_symrec(yasm_expr__item *ei, /*@unused@*/ void *d)
+fix_directive_symrec(yasm_expr__item *ei, void *d)
 {
+    yasm_parser_nasm *parser_nasm = (yasm_parser_nasm *)d;
     if (!ei || ei->type != YASM_EXPR_SYM)
        return 0;
 
     /* FIXME: Delete current symrec */
     ei->data.sym =
-       yasm_symrec_use(yasm_symrec_get_name(ei->data.sym), cur_lindex);
+       yasm_symtab_use(p_symtab, yasm_symrec_get_name(ei->data.sym),
+                       cur_line);
 
     return 0;
 }
 
 static void
-nasm_parser_directive(const char *name, yasm_valparamhead *valparams,
+nasm_parser_directive(yasm_parser_nasm *parser_nasm, const char *name,
+                     yasm_valparamhead *valparams,
                      yasm_valparamhead *objext_valparams)
 {
     yasm_valparam *vp, *vp2;
     yasm_symrec *sym;
-    unsigned long lindex = cur_lindex;
+    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_symrec_declare(vp->val, YASM_SYM_EXTERN, lindex);
-           if (nasm_parser_objfmt->extern_declare)
-               nasm_parser_objfmt->extern_declare(sym, objext_valparams,
-                                                  lindex);
+           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);
        } else
-           yasm__error(lindex, N_("invalid argument to [%s]"), "EXTERN");
+           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_symrec_declare(vp->val, YASM_SYM_GLOBAL, lindex);
-           if (nasm_parser_objfmt->global_declare)
-               nasm_parser_objfmt->global_declare(sym, objext_valparams,
-                                                  lindex);
+           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);
        } else
-           yasm__error(lindex, N_("invalid argument to [%s]"), "GLOBAL");
+           yasm__error(line, N_("invalid argument to [%s]"), "GLOBAL");
     } else if (yasm__strcasecmp(name, "common") == 0) {
        vp = yasm_vps_first(valparams);
        if (vp->val) {
            vp2 = yasm_vps_next(vp);
            if (!vp2 || (!vp2->val && !vp2->param))
-               yasm__error(lindex, N_("no size specified in %s declaration"),
+               yasm__error(line, N_("no size specified in %s declaration"),
                            "COMMON");
            else {
                if (vp2->val) {
-                   sym = yasm_symrec_declare(vp->val, YASM_SYM_COMMON,
-                                             lindex);
-                   if (nasm_parser_objfmt->common_declare)
-                       nasm_parser_objfmt->common_declare(sym,
+                   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_symrec_use(vp2->val, lindex))),
-                           objext_valparams, lindex);
+                               yasm_symtab_use(p_symtab, vp2->val, line))),
+                           objext_valparams, line);
                } else if (vp2->param) {
-                   sym = yasm_symrec_declare(vp->val, YASM_SYM_COMMON,
-                                             lindex);
-                   if (nasm_parser_objfmt->common_declare)
-                       nasm_parser_objfmt->common_declare(sym, vp2->param,
-                                                          objext_valparams,
-                                                          lindex);
+                   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);
                    vp2->param = NULL;
                }
            }
        } else
-           yasm__error(lindex, N_("invalid argument to [%s]"), "COMMON");
+           yasm__error(line, N_("invalid argument to [%s]"), "COMMON");
     } else if (yasm__strcasecmp(name, "section") == 0 ||
               yasm__strcasecmp(name, "segment") == 0) {
        yasm_section *new_section =
-           nasm_parser_objfmt->sections_switch(nasm_parser_sections,
+           parser_nasm->objfmt->section_switch(parser_nasm->object,
                                                valparams, objext_valparams,
-                                               lindex);
+                                               line);
        if (new_section) {
-           nasm_parser_cur_section = new_section;
-           nasm_parser_prev_bc =
-               yasm_bcs_last(yasm_section_get_bytecodes(new_section));
+           parser_nasm->cur_section = new_section;
+           parser_nasm->prev_bc = yasm_section_bcs_last(new_section);
        } else
-           yasm__error(lindex, N_("invalid argument to [%s]"), "SECTION");
+           yasm__error(line, N_("invalid argument to [%s]"), "SECTION");
     } else if (yasm__strcasecmp(name, "absolute") == 0) {
        /* it can be just an ID or a complete expression, so handle both. */
        vp = yasm_vps_first(valparams);
        if (vp->val)
-           nasm_parser_cur_section =
-               yasm_sections_switch_absolute(nasm_parser_sections,
+           parser_nasm->cur_section =
+               yasm_object_create_absolute(parser_nasm->object,
                    p_expr_new_ident(yasm_expr_sym(
-                       yasm_symrec_use(vp->val, lindex))));
+                       yasm_symtab_use(p_symtab, vp->val, line))), line);
        else if (vp->param) {
-           nasm_parser_cur_section =
-               yasm_sections_switch_absolute(nasm_parser_sections,
-                                             vp->param);
+           parser_nasm->cur_section =
+               yasm_object_create_absolute(parser_nasm->object, vp->param,
+                                           line);
            vp->param = NULL;
        }
-       nasm_parser_prev_bc = (yasm_bytecode *)NULL;
+       parser_nasm->prev_bc = yasm_section_bcs_last(parser_nasm->cur_section);
     } else if (yasm__strcasecmp(name, "cpu") == 0) {
        yasm_vps_foreach(vp, valparams) {
            if (vp->val)
-               nasm_parser_arch->parse_cpu(vp->val, lindex);
+               p_arch->module->parse_cpu(p_arch, vp->val, line);
            else if (vp->param) {
                const yasm_intnum *intcpu;
                intcpu = yasm_expr_get_intnum(&vp->param, NULL);
                if (!intcpu)
-                   yasm__error(lindex, N_("invalid argument to [%s]"), "CPU");
+                   yasm__error(line, N_("invalid argument to [%s]"), "CPU");
                else {
                    char strcpu[16];
                    sprintf(strcpu, "%lu", yasm_intnum_get_uint(intcpu));
-                   nasm_parser_arch->parse_cpu(strcpu, lindex);
+                   p_arch->module->parse_cpu(p_arch, strcpu, line);
                }
            }
        }
-    } else if (!nasm_parser_arch->parse_directive(name, valparams,
-                                                 objext_valparams,
-                                                 nasm_parser_sections,
-                                                 lindex)) {
+    } else if (!p_arch->module->parse_directive(p_arch, name, valparams,
+                   objext_valparams, parser_nasm->object, line)) {
        ;
-    } else if (nasm_parser_objfmt->directive(name, valparams, objext_valparams,
-                                            nasm_parser_sections, lindex)) {
-       yasm__error(lindex, N_("unrecognized directive [%s]"), name);
+    } else if (parser_nasm->objfmt->directive(name, valparams,
+                   objext_valparams, parser_nasm->object, line)) {
+       yasm__error(line, N_("unrecognized directive [%s]"), name);
     }
 
     yasm_vps_delete(valparams);
     if (objext_valparams)
        yasm_vps_delete(objext_valparams);
 }
-
-static void
-nasm_parser_error(const char *s)
-{
-    yasm__parser_error(cur_lindex, s);
-}
-
index 7a50c553bef96c868c80ce3d16ab1edba4682546..1b6b60ed920901dc59e3d257763943719c7c24f9 100644 (file)
 #include "nasm-parser.h"
 
 
-FILE *nasm_parser_in = NULL;
-size_t (*nasm_parser_input) (char *buf, size_t max_size);
+static void
+nasm_parser_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_nasm parser_nasm;
 
-/*@only@*/ yasm_sectionhead *nasm_parser_sections;
-/*@dependent@*/ yasm_section *nasm_parser_cur_section;
+    parser_nasm.object = object;
+    parser_nasm.linemap = yasm_object_get_linemap(parser_nasm.object);
+    parser_nasm.symtab = yasm_object_get_symtab(parser_nasm.object);
 
-/* last "base" label for local (.) labels */
-char *nasm_parser_locallabel_base = (char *)NULL;
-size_t nasm_parser_locallabel_base_len = 0;
+    yasm_linemap_set(parser_nasm.linemap, in_filename, 1, 1);
 
-/*@dependent@*/ yasm_arch *nasm_parser_arch;
-/*@dependent@*/ yasm_objfmt *nasm_parser_objfmt;
-/*@dependent@*/ yasm_linemgr *nasm_parser_linemgr;
+    pp->initialize(f, in_filename, parser_nasm.linemap);
+    parser_nasm.in = f;
+    parser_nasm.input = pp->input;
 
-int nasm_parser_save_input;
+    parser_nasm.locallabel_base = (char *)NULL;
+    parser_nasm.locallabel_base_len = 0;
 
-static /*@only@*/ yasm_sectionhead *
-nasm_parser_do_parse(yasm_preproc *pp, yasm_arch *a, yasm_objfmt *of,
-                    yasm_linemgr *lm, FILE *f, const char *in_filename,
-                    int save_input)
-    /*@globals killed nasm_parser_locallabel_base @*/
-{
-    pp->initialize(f, in_filename, lm);
-    nasm_parser_in = f;
-    nasm_parser_input = pp->input;
-    nasm_parser_arch = a;
-    nasm_parser_objfmt = of;
-    nasm_parser_linemgr = lm;
-    nasm_parser_save_input = save_input;
+    parser_nasm.arch = a;
+    parser_nasm.objfmt = of;
+
+    parser_nasm.cur_section = def_sect;
+    parser_nasm.prev_bc = yasm_section_bcs_first(def_sect);
 
-    /* Initialize section list */
-    nasm_parser_sections = yasm_sections_new(&nasm_parser_cur_section, of);
+    parser_nasm.save_input = save_input;
+
+    /* initialize scanner structure */
+    parser_nasm.s.bot = NULL;
+    parser_nasm.s.tok = NULL;
+    parser_nasm.s.ptr = NULL;
+    parser_nasm.s.cur = NULL;
+    parser_nasm.s.pos = NULL;
+    parser_nasm.s.lim = NULL;
+    parser_nasm.s.top = NULL;
+    parser_nasm.s.eof = NULL;
+    parser_nasm.s.tchar = 0;
+    parser_nasm.s.tline = 0;
+    parser_nasm.s.cline = 1;
+
+    parser_nasm.state = INITIAL;
 
     /* yacc debugging, needs YYDEBUG set in bison.y.in to work */
     /* nasm_parser_debug = 1; */
 
-    nasm_parser_parse();
+    nasm_parser_parse(&parser_nasm);
 
-    nasm_parser_cleanup();
+    nasm_parser_cleanup(&parser_nasm);
 
     /* Free locallabel base if necessary */
-    if (nasm_parser_locallabel_base)
-       yasm_xfree(nasm_parser_locallabel_base);
-
-    return nasm_parser_sections;
+    if (parser_nasm.locallabel_base)
+       yasm_xfree(parser_nasm.locallabel_base);
 }
 
 /* Define valid preprocessors to use with this parser */
@@ -88,7 +96,7 @@ static const char *nasm_parser_preproc_keywords[] = {
 };
 
 /* Define parser structure -- see parser.h for details */
-yasm_parser yasm_nasm_LTX_parser = {
+yasm_parser_module yasm_nasm_LTX_parser = {
     YASM_PARSER_VERSION,
     "NASM-compatible parser",
     "nasm",
index 592ead03e7e505c66289d26e4e448008e47b368d..56bc59d76cb21c8ff708b9d0d9e845f23866566d 100644 (file)
@@ -1,4 +1,4 @@
-/* $IdPath: yasm/modules/parsers/nasm/nasm-parser.h,v 1.6 2003/03/13 06:54:19 peter Exp $
+/* $IdPath$
  * NASM-compatible parser header file
  *
  *  Copyright (C) 2002  Peter Johnson
 #ifndef YASM_NASM_PARSER_H
 #define YASM_NASM_PARSER_H
 
-int nasm_parser_parse(void);
-void nasm_parser_cleanup(void);
-int nasm_parser_lex(void);
-void nasm_parser_set_directive_state(void);
+#define YYCTYPE                char
+typedef struct Scanner {
+    YYCTYPE            *bot, *tok, *ptr, *cur, *pos, *lim, *top, *eof;
+    unsigned int       tchar, tline, cline;
+} Scanner;
 
-extern FILE *nasm_parser_in;
-extern int nasm_parser_debug;
-extern size_t (*nasm_parser_input) (char *buf, size_t max_size);
+#define MAX_SAVED_LINE_LEN  80
 
-extern yasm_sectionhead *nasm_parser_sections;
-extern /*@dependent@*/ yasm_section *nasm_parser_cur_section;
+typedef struct yasm_parser_nasm {
+    FILE *in;
+    int debug;
+    size_t (*input) (char *buf, size_t max_size);
 
-extern char *nasm_parser_locallabel_base;
-extern size_t nasm_parser_locallabel_base_len;
+    /*@only@*/ yasm_object *object;
+    /*@dependent@*/ yasm_section *cur_section;
 
-extern /*@dependent@*/ yasm_arch *nasm_parser_arch;
-extern /*@dependent@*/ yasm_objfmt *nasm_parser_objfmt;
-extern /*@dependent@*/ yasm_linemgr *nasm_parser_linemgr;
+    /* last "base" label for local (.) labels */
+    /*@null@*/ char *locallabel_base;
+    size_t locallabel_base_len;
 
-extern int nasm_parser_save_input;
+    /*@dependent@*/ yasm_arch *arch;
+    /*@dependent@*/ yasm_objfmt *objfmt;
 
-#define cur_lindex     (nasm_parser_linemgr->get_current())
+    /*@dependent@*/ yasm_linemap *linemap;
+    /*@dependent@*/ yasm_symtab *symtab;
 
-#define p_expr_new_tree(l,o,r) yasm_expr_new_tree(l,o,r,cur_lindex)
-#define p_expr_new_branch(o,r) yasm_expr_new_branch(o,r,cur_lindex)
-#define p_expr_new_ident(r)    yasm_expr_new_ident(r,cur_lindex)
+    /*@null@*/ yasm_bytecode *prev_bc;
+    yasm_bytecode *temp_bc;
+
+    int save_input;
+    YYCTYPE save_line[MAX_SAVED_LINE_LEN];
+
+    Scanner s;
+    enum {
+       INITIAL,
+       DIRECTIVE,
+       DIRECTIVE2,
+       LINECHG,
+       LINECHG2
+    } state;
+} yasm_parser_nasm;
+
+/* shorter access names to commonly used parser_nasm fields */
+#define p_arch         (parser_nasm->arch)
+#define p_symtab       (parser_nasm->symtab)
+
+#define cur_line       (yasm_linemap_get_current(parser_nasm->linemap))
+
+#define p_expr_new_tree(l,o,r) yasm_expr_create_tree(l,o,r,cur_line)
+#define p_expr_new_branch(o,r) yasm_expr_create_branch(o,r,cur_line)
+#define p_expr_new_ident(r)    yasm_expr_create_ident(r,cur_line)
+
+int nasm_parser_parse(void *parser_nasm_arg);
+void nasm_parser_cleanup(yasm_parser_nasm *parser_nasm);
+int nasm_parser_lex_arg(yasm_parser_nasm *parser_nasm);
+#define nasm_parser_lex()      nasm_parser_lex_arg(parser_nasm)
 
 #endif
index b8bfc2b823bc53cf20224d4c37e7f4f35de10c72..20bd923534f5cf6ce4a1adcf2e655c7575f9564e 100644 (file)
@@ -39,104 +39,107 @@ RCSID("$IdPath$");
 
 #define BSIZE  8192
 
-#define YYCTYPE                char
 #define YYCURSOR       cursor
-#define YYLIMIT                s.lim
-#define YYMARKER       s.ptr
-#define YYFILL(n)      {cursor = fill(cursor);}
+#define YYLIMIT                (s->lim)
+#define YYMARKER       (s->ptr)
+#define YYFILL(n)      {cursor = fill(parser_nasm, cursor);}
 
-#define RETURN(i)      {s.cur = cursor; return i;}
+#define RETURN(i)      {s->cur = cursor; return i;}
 
 #define SCANINIT()     { \
-       s.tchar = cursor - s.pos; \
-       s.tline = s.cline; \
-       s.tok = cursor; \
+       s->tchar = cursor - s->pos; \
+       s->tline = s->cline; \
+       s->tok = cursor; \
     }
 
-#define TOKLEN         (size_t)(cursor-s.tok)
+#define TOKLEN         (size_t)(cursor-s->tok)
 
-typedef struct Scanner {
-    YYCTYPE            *bot, *tok, *ptr, *cur, *pos, *lim, *top, *eof;
-    unsigned int       tchar, tline, cline;
-} Scanner;
-
-#define MAX_SAVED_LINE_LEN  80
-static char cur_line[MAX_SAVED_LINE_LEN];
-
-static Scanner s = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 1 };
 
 static YYCTYPE *
-fill(YYCTYPE *cursor)
+fill(yasm_parser_nasm *parser_nasm, YYCTYPE *cursor)
 {
+    Scanner *s = &parser_nasm->s;
     int first = 0;
-    if(!s.eof){
-       size_t cnt = s.tok - s.bot;
+    if(!s->eof){
+       size_t cnt = s->tok - s->bot;
        if(cnt){
-           memcpy(s.bot, s.tok, (size_t)(s.lim - s.tok));
-           s.tok = s.bot;
-           s.ptr -= cnt;
+           memcpy(s->bot, s->tok, (size_t)(s->lim - s->tok));
+           s->tok = s->bot;
+           s->ptr -= cnt;
            cursor -= cnt;
-           s.pos -= cnt;
-           s.lim -= cnt;
+           s->pos -= cnt;
+           s->lim -= cnt;
        }
-       if (!s.bot)
+       if (!s->bot)
            first = 1;
-       if((s.top - s.lim) < BSIZE){
-           char *buf = yasm_xmalloc((size_t)(s.lim - s.bot) + BSIZE);
-           memcpy(buf, s.tok, (size_t)(s.lim - s.tok));
-           s.tok = buf;
-           s.ptr = &buf[s.ptr - s.bot];
-           cursor = &buf[cursor - s.bot];
-           s.pos = &buf[s.pos - s.bot];
-           s.lim = &buf[s.lim - s.bot];
-           s.top = &s.lim[BSIZE];
-           if (s.bot)
-               yasm_xfree(s.bot);
-           s.bot = buf;
+       if((s->top - s->lim) < BSIZE){
+           char *buf = yasm_xmalloc((size_t)(s->lim - s->bot) + BSIZE);
+           memcpy(buf, s->tok, (size_t)(s->lim - s->tok));
+           s->tok = buf;
+           s->ptr = &buf[s->ptr - s->bot];
+           cursor = &buf[cursor - s->bot];
+           s->pos = &buf[s->pos - s->bot];
+           s->lim = &buf[s->lim - s->bot];
+           s->top = &s->lim[BSIZE];
+           if (s->bot)
+               yasm_xfree(s->bot);
+           s->bot = buf;
        }
-       if((cnt = nasm_parser_input(s.lim, BSIZE)) == 0){
-           s.eof = &s.lim[cnt]; *s.eof++ = '\n';
+       if((cnt = parser_nasm->input(s->lim, BSIZE)) == 0){
+           s->eof = &s->lim[cnt]; *s->eof++ = '\n';
        }
-       s.lim += cnt;
-       if (first && nasm_parser_save_input) {
+       s->lim += cnt;
+       if (first && parser_nasm->save_input) {
            int i;
            /* save next line into cur_line */
-           for (i=0; i<79 && &s.tok[i] < s.lim && s.tok[i] != '\n'; i++)
-               cur_line[i] = s.tok[i];
-           cur_line[i] = '\0';
+           for (i=0; i<79 && &s->tok[i] < s->lim && s->tok[i] != '\n'; i++)
+               parser_nasm->save_line[i] = s->tok[i];
+           parser_nasm->save_line[i] = '\0';
        }
     }
     return cursor;
 }
 
 static void
-delete_line(/*@only@*/ void *data)
+destroy_line(/*@only@*/ void *data)
 {
     yasm_xfree(data);
 }
 
+static void
+print_line(void *data, FILE *f, int indent_level)
+{
+    fprintf(f, "%*s\"%s\"\n", indent_level, "", (char *)data);
+}
+
+static const yasm_assoc_data_callback line_assoc_data = {
+    destroy_line,
+    print_line
+};
+
 static YYCTYPE *
-save_line(YYCTYPE *cursor)
+save_line(yasm_parser_nasm *parser_nasm, YYCTYPE *cursor)
 {
+    Scanner *s = &parser_nasm->s;
     int i = 0;
 
     /* save previous line using assoc_data */
-    nasm_parser_linemgr->add_assoc_data(YASM_LINEMGR_STD_TYPE_SOURCE,
-                                       yasm__xstrdup(cur_line), delete_line);
+    yasm_linemap_add_data(parser_nasm->linemap, &line_assoc_data,
+                         yasm__xstrdup(parser_nasm->save_line), 1);
     /* save next line into cur_line */
     if ((YYLIMIT - YYCURSOR) < 80)
        YYFILL(80);
-    for (i=0; i<79 && &cursor[i] < s.lim && cursor[i] != '\n'; i++)
-       cur_line[i] = cursor[i];
-    cur_line[i] = '\0';
+    for (i=0; i<79 && &cursor[i] < s->lim && cursor[i] != '\n'; i++)
+       parser_nasm->save_line[i] = cursor[i];
+    parser_nasm->save_line[i] = '\0';
     return cursor;
 }
 
 void
-nasm_parser_cleanup(void)
+nasm_parser_cleanup(yasm_parser_nasm *parser_nasm)
 {
-    if (s.bot)
-       yasm_xfree(s.bot);
+    if (parser_nasm->s.bot)
+       yasm_xfree(parser_nasm->s.bot);
 }
 
 /* starting size of string buffer */
@@ -187,35 +190,23 @@ static int linechg_numcount;
   Z = [zZ];
 */
 
-static enum {
-    INITIAL,
-    DIRECTIVE,
-    DIRECTIVE2,
-    LINECHG,
-    LINECHG2
-} state = INITIAL;
-
-void
-nasm_parser_set_directive_state(void)
-{
-    state = DIRECTIVE;
-}
 
 int
-nasm_parser_lex(void)
+nasm_parser_lex_arg(yasm_parser_nasm *parser_nasm)
 {
-    YYCTYPE *cursor = s.cur;
+    Scanner *s = &parser_nasm->s;
+    YYCTYPE *cursor = s->cur;
     YYCTYPE endch;
     size_t count, len;
     YYCTYPE savech;
     yasm_arch_check_id_retval check_id_ret;
 
     /* Catch EOF */
-    if (s.eof && cursor == s.eof)
+    if (s->eof && cursor == s->eof)
        return 0;
 
     /* Jump to proper "exclusive" states */
-    switch (state) {
+    switch (parser_nasm->state) {
        case DIRECTIVE:
            goto directive;
        case LINECHG:
@@ -232,66 +223,66 @@ scan:
     /*!re2c
        /* standard decimal integer */
        digit+ {
-           savech = s.tok[TOKLEN];
-           s.tok[TOKLEN] = '\0';
-           yylval.intn = yasm_intnum_new_dec(s.tok, cur_lindex);
-           s.tok[TOKLEN] = savech;
+           savech = s->tok[TOKLEN];
+           s->tok[TOKLEN] = '\0';
+           yylval.intn = yasm_intnum_create_dec(s->tok, cur_line);
+           s->tok[TOKLEN] = savech;
            RETURN(INTNUM);
        }
        /* 10010011b - binary number */
 
        bindigit+ "b" {
-           s.tok[TOKLEN-1] = '\0'; /* strip off 'b' */
-           yylval.intn = yasm_intnum_new_bin(s.tok, cur_lindex);
+           s->tok[TOKLEN-1] = '\0'; /* strip off 'b' */
+           yylval.intn = yasm_intnum_create_bin(s->tok, cur_line);
            RETURN(INTNUM);
        }
 
        /* 777q - octal number */
        octdigit+ "q" {
-           s.tok[TOKLEN-1] = '\0'; /* strip off 'q' */
-           yylval.intn = yasm_intnum_new_oct(s.tok, cur_lindex);
+           s->tok[TOKLEN-1] = '\0'; /* strip off 'q' */
+           yylval.intn = yasm_intnum_create_oct(s->tok, cur_line);
            RETURN(INTNUM);
        }
 
        /* 0AAh form of hexidecimal number */
        digit hexdigit* "h" {
-           s.tok[TOKLEN-1] = '\0'; /* strip off 'h' */
-           yylval.intn = yasm_intnum_new_hex(s.tok, cur_lindex);
+           s->tok[TOKLEN-1] = '\0'; /* strip off 'h' */
+           yylval.intn = yasm_intnum_create_hex(s->tok, cur_line);
            RETURN(INTNUM);
        }
 
        /* $0AA and 0xAA forms of hexidecimal number */
        (("$" digit) | "0x") hexdigit+ {
-           savech = s.tok[TOKLEN];
-           s.tok[TOKLEN] = '\0';
-           if (s.tok[1] == 'x')
+           savech = s->tok[TOKLEN];
+           s->tok[TOKLEN] = '\0';
+           if (s->tok[1] == 'x')
                /* skip 0 and x */
-               yylval.intn = yasm_intnum_new_hex(s.tok+2, cur_lindex);
+               yylval.intn = yasm_intnum_create_hex(s->tok+2, cur_line);
            else
                /* don't skip 0 */
-               yylval.intn = yasm_intnum_new_hex(s.tok+1, cur_lindex);
-           s.tok[TOKLEN] = savech;
+               yylval.intn = yasm_intnum_create_hex(s->tok+1, cur_line);
+           s->tok[TOKLEN] = savech;
            RETURN(INTNUM);
        }
 
        /* floating point value */
        digit+ "." digit* (E [-+]? digit+)? {
-           savech = s.tok[TOKLEN];
-           s.tok[TOKLEN] = '\0';
-           yylval.flt = yasm_floatnum_new(s.tok);
-           s.tok[TOKLEN] = savech;
+           savech = s->tok[TOKLEN];
+           s->tok[TOKLEN] = '\0';
+           yylval.flt = yasm_floatnum_create(s->tok);
+           s->tok[TOKLEN] = savech;
            RETURN(FLTNUM);
        }
 
        /* string/character constant values */
        quot {
-           endch = s.tok[0];
+           endch = s->tok[0];
            goto stringconst;
        }
 
        /* %line linenum+lineinc filename */
        "%line" {
-           state = LINECHG;
+           parser_nasm->state = LINECHG;
            linechg_numcount = 0;
            RETURN(LINE);
        }
@@ -334,37 +325,37 @@ scan:
        "//"                    { RETURN(SIGNDIV); }
        "%%"                    { RETURN(SIGNMOD); }
        "$$"                    { RETURN(START_SECTION_ID); }
-       [-+|^*&/%~$():=,\[]     { RETURN(s.tok[0]); }
+       [-+|^*&/%~$():=,\[]     { RETURN(s->tok[0]); }
 
        /* handle ] separately for directives */
        "]" {
-           if (state == DIRECTIVE2)
-               state = INITIAL;
-           RETURN(s.tok[0]);
+           if (parser_nasm->state == DIRECTIVE2)
+               parser_nasm->state = INITIAL;
+           RETURN(s->tok[0]);
        }
 
        /* special non-local ..@label and labels like ..start */
        ".." [a-zA-Z0-9_$#@~.?]+ {
-           yylval.str_val = yasm__xstrndup(s.tok, TOKLEN);
+           yylval.str_val = yasm__xstrndup(s->tok, TOKLEN);
            RETURN(SPECIAL_ID);
        }
 
        /* local label (.label) */
        "." [a-zA-Z0-9_$#@~?][a-zA-Z0-9_$#@~.?]* {
            /* override local labels in directive state */
-           if (state == DIRECTIVE2) {
-               yylval.str_val = yasm__xstrndup(s.tok, TOKLEN);
+           if (parser_nasm->state == DIRECTIVE2) {
+               yylval.str_val = yasm__xstrndup(s->tok, TOKLEN);
                RETURN(ID);
-           } else if (!nasm_parser_locallabel_base) {
-               yylval.str_val = yasm__xstrndup(s.tok, TOKLEN);
-               yasm__warning(YASM_WARN_GENERAL, cur_lindex,
+           } else if (!parser_nasm->locallabel_base) {
+               yylval.str_val = yasm__xstrndup(s->tok, TOKLEN);
+               yasm__warning(YASM_WARN_GENERAL, cur_line,
                              N_("no non-local label before `%s'"),
                              yylval.str_val);
            } else {
-               len = TOKLEN + nasm_parser_locallabel_base_len;
+               len = TOKLEN + parser_nasm->locallabel_base_len;
                yylval.str_val = yasm_xmalloc(len + 1);
-               strcpy(yylval.str_val, nasm_parser_locallabel_base);
-               strncat(yylval.str_val, s.tok, TOKLEN);
+               strcpy(yylval.str_val, parser_nasm->locallabel_base);
+               strncat(yylval.str_val, s->tok, TOKLEN);
                yylval.str_val[len] = '\0';
            }
 
@@ -373,21 +364,22 @@ scan:
 
        /* forced identifier */
        "$" [a-zA-Z_?][a-zA-Z0-9_$#@~.?]* {
-           yylval.str_val = yasm__xstrndup(s.tok, TOKLEN);
+           yylval.str_val = yasm__xstrndup(s->tok, TOKLEN);
            RETURN(ID);
        }
 
        /* identifier that may be a register, instruction, etc. */
        [a-zA-Z_?][a-zA-Z0-9_$#@~.?]* {
-           savech = s.tok[TOKLEN];
-           s.tok[TOKLEN] = '\0';
-           check_id_ret = nasm_parser_arch->parse_check_id(yylval.arch_data,
-                                                           s.tok, cur_lindex);
-           s.tok[TOKLEN] = savech;
+           savech = s->tok[TOKLEN];
+           s->tok[TOKLEN] = '\0';
+           check_id_ret = p_arch->module->parse_check_id(p_arch,
+                                                         yylval.arch_data,
+                                                         s->tok, cur_line);
+           s->tok[TOKLEN] = savech;
            switch (check_id_ret) {
                case YASM_ARCH_CHECK_ID_NONE:
                    /* Just an identifier, return as such. */
-                   yylval.str_val = yasm__xstrndup(s.tok, TOKLEN);
+                   yylval.str_val = yasm__xstrndup(s->tok, TOKLEN);
                    RETURN(ID);
                case YASM_ARCH_CHECK_ID_INSN:
                    RETURN(INSN);
@@ -400,9 +392,9 @@ scan:
                case YASM_ARCH_CHECK_ID_TARGETMOD:
                    RETURN(TARGETMOD);
                default:
-                   yasm__warning(YASM_WARN_GENERAL, cur_lindex,
+                   yasm__warning(YASM_WARN_GENERAL, cur_line,
                        N_("Arch feature not supported, treating as identifier"));
-                   yylval.str_val = yasm__xstrndup(s.tok, TOKLEN);
+                   yylval.str_val = yasm__xstrndup(s->tok, TOKLEN);
                    RETURN(ID);
            }
        }
@@ -412,16 +404,16 @@ scan:
        ws+                     { goto scan; }
 
        "\n"                    {
-           if (nasm_parser_save_input && cursor != s.eof)
-               cursor = save_line(cursor);
-           state = INITIAL;
-           RETURN(s.tok[0]);
+           if (parser_nasm->save_input && cursor != s->eof)
+               cursor = save_line(parser_nasm, cursor);
+           parser_nasm->state = INITIAL;
+           RETURN(s->tok[0]);
        }
 
        any {
-           yasm__warning(YASM_WARN_UNREC_CHAR, cur_lindex,
+           yasm__warning(YASM_WARN_UNREC_CHAR, cur_line,
                          N_("ignoring unrecognized character `%s'"),
-                         yasm__conv_unprint(s.tok[0]));
+                         yasm__conv_unprint(s->tok[0]));
            goto scan;
        }
     */
@@ -433,36 +425,36 @@ linechg:
     /*!re2c
        digit+ {
            linechg_numcount++;
-           savech = s.tok[TOKLEN];
-           s.tok[TOKLEN] = '\0';
-           yylval.intn = yasm_intnum_new_dec(s.tok, cur_lindex);
-           s.tok[TOKLEN] = savech;
+           savech = s->tok[TOKLEN];
+           s->tok[TOKLEN] = '\0';
+           yylval.intn = yasm_intnum_create_dec(s->tok, cur_line);
+           s->tok[TOKLEN] = savech;
            RETURN(INTNUM);
        }
 
        "\n" {
-           if (nasm_parser_save_input && cursor != s.eof)
-               cursor = save_line(cursor);
-           state = INITIAL;
-           RETURN(s.tok[0]);
+           if (parser_nasm->save_input && cursor != s->eof)
+               cursor = save_line(parser_nasm, cursor);
+           parser_nasm->state = INITIAL;
+           RETURN(s->tok[0]);
        }
 
        "+" {
-           RETURN(s.tok[0]);
+           RETURN(s->tok[0]);
        }
 
        ws+ {
            if (linechg_numcount == 2) {
-               state = LINECHG2;
+               parser_nasm->state = LINECHG2;
                goto linechg2;
            }
            goto linechg;
        }
 
        any {
-           yasm__warning(YASM_WARN_UNREC_CHAR, cur_lindex,
+           yasm__warning(YASM_WARN_UNREC_CHAR, cur_line,
                          N_("ignoring unrecognized character `%s'"),
-                         yasm__conv_unprint(s.tok[0]));
+                         yasm__conv_unprint(s->tok[0]));
            goto linechg;
        }
     */
@@ -472,17 +464,17 @@ linechg2:
 
     /*!re2c
        "\n" {
-           if (nasm_parser_save_input && cursor != s.eof)
-               cursor = save_line(cursor);
-           state = INITIAL;
-           RETURN(s.tok[0]);
+           if (parser_nasm->save_input && cursor != s->eof)
+               cursor = save_line(parser_nasm, cursor);
+           parser_nasm->state = INITIAL;
+           RETURN(s->tok[0]);
        }
 
        "\r" { }
 
        (any \ [\r\n])+ {
-           state = LINECHG;
-           yylval.str_val = yasm__xstrndup(s.tok, TOKLEN);
+           parser_nasm->state = LINECHG;
+           yylval.str_val = yasm__xstrndup(s->tok, TOKLEN);
            RETURN(FILENAME);
        }
     */
@@ -493,22 +485,22 @@ directive:
 
     /*!re2c
        [\]\n] {
-           if (nasm_parser_save_input && cursor != s.eof)
-               cursor = save_line(cursor);
-           state = INITIAL;
-           RETURN(s.tok[0]);
+           if (parser_nasm->save_input && cursor != s->eof)
+               cursor = save_line(parser_nasm, cursor);
+           parser_nasm->state = INITIAL;
+           RETURN(s->tok[0]);
        }
 
        iletter+ {
-           state = DIRECTIVE2;
-           yylval.str_val = yasm__xstrndup(s.tok, TOKLEN);
+           parser_nasm->state = DIRECTIVE2;
+           yylval.str_val = yasm__xstrndup(s->tok, TOKLEN);
            RETURN(DIRECTIVE_NAME);
        }
 
        any {
-           yasm__warning(YASM_WARN_UNREC_CHAR, cur_lindex,
+           yasm__warning(YASM_WARN_UNREC_CHAR, cur_line,
                          N_("ignoring unrecognized character `%s'"),
-                         yasm__conv_unprint(s.tok[0]));
+                         yasm__conv_unprint(s->tok[0]));
            goto directive;
        }
     */
@@ -524,26 +516,26 @@ stringconst_scan:
 
     /*!re2c
        "\n"    {
-           if (cursor == s.eof)
-               yasm__error(cur_lindex,
+           if (cursor == s->eof)
+               yasm__error(cur_line,
                            N_("unexpected end of file in string"));
            else
-               yasm__error(cur_lindex, N_("unterminated string"));
+               yasm__error(cur_line, N_("unterminated string"));
            strbuf[count] = '\0';
            yylval.str_val = strbuf;
-           if (nasm_parser_save_input && cursor != s.eof)
-               cursor = save_line(cursor);
+           if (parser_nasm->save_input && cursor != s->eof)
+               cursor = save_line(parser_nasm, cursor);
            RETURN(STRING);
        }
 
        any     {
-           if (s.tok[0] == endch) {
+           if (s->tok[0] == endch) {
                strbuf[count] = '\0';
                yylval.str_val = strbuf;
                RETURN(STRING);
            }
 
-           strbuf[count++] = s.tok[0];
+           strbuf[count++] = s->tok[0];
            if (count >= strbuf_size) {
                strbuf = yasm_xrealloc(strbuf, strbuf_size + STRBUF_ALLOC_SIZE);
                strbuf_size += STRBUF_ALLOC_SIZE;
index f43609222450eb1a6f24bca00c12599b8521c15f..552c2b57d311714d887055940a9d3f81d46b0832 100644 (file)
@@ -36,7 +36,7 @@
 #include "nasm-eval.h"
 
 static FILE *in;
-static yasm_linemgr *cur_lm;
+static yasm_linemap *cur_lm;
 static char *line, *linepos;
 static size_t lineleft;
 static char *file_name;
@@ -93,11 +93,11 @@ nasm_efunc(int severity, const char *fmt, ...)
     va_start(va, fmt);
     switch (severity & ERR_MASK) {
        case ERR_WARNING:
-           yasm__warning_va(YASM_WARN_PREPROC, cur_lm->get_current(), fmt,
-                            va);
+           yasm__warning_va(YASM_WARN_PREPROC,
+                            yasm_linemap_get_current(cur_lm), fmt, va);
            break;
        case ERR_NONFATAL:
-           yasm__error_va(cur_lm->get_current(), fmt, va);
+           yasm__error_va(yasm_linemap_get_current(cur_lm), fmt, va);
            break;
        case ERR_FATAL:
            yasm_fatal(N_("unknown"));  /* FIXME */
@@ -112,7 +112,7 @@ nasm_efunc(int severity, const char *fmt, ...)
 }
 
 static void
-nasm_preproc_initialize(FILE *f, const char *in_filename, yasm_linemgr *lm)
+nasm_preproc_initialize(FILE *f, const char *in_filename, yasm_linemap *lm)
 {
     in = f;
     cur_lm = lm;
@@ -127,6 +127,7 @@ static void
 nasm_preproc_cleanup(void)
 {
     nasmpp.cleanup(0);
+    nasm_eval_cleanup();
 }
 
 static size_t
index 2d837202c34c1a50037909ac266ca2d689bbd595..d83b74e6065d729df2c6acc74ff493616ceedb9c 100644 (file)
 
 static int is_interactive;
 static FILE *in;
-static yasm_linemgr *cur_lm;
+static yasm_linemap *cur_lm;
 
 int isatty(int);
 
 static void
-raw_preproc_initialize(FILE *f, const char *in_filename, yasm_linemgr *lm)
+raw_preproc_initialize(FILE *f, const char *in_filename, yasm_linemap *lm)
 {
     in = f;
     cur_lm = lm;
@@ -64,10 +64,11 @@ raw_preproc_input(char *buf, size_t max_size)
        if (c == '\n')
            buf[n++] = (char)c;
        if (c == EOF && ferror(in))
-           yasm__error(cur_lm->get_current(),
+           yasm__error(yasm_linemap_get_current(cur_lm),
                        N_("error when reading from file"));
     } else if (((n = fread(buf, 1, max_size, in)) == 0) && ferror(in))
-       yasm__error(cur_lm->get_current(), N_("error when reading from file"));
+       yasm__error(yasm_linemap_get_current(cur_lm),
+                   N_("error when reading from file"));
 
     return n;
 }