]> granicus.if.org Git - yasm/commitdiff
Move absolute section handling into NASM parser, removing all traces of it
authorPeter Johnson <peter@tortall.net>
Tue, 15 May 2007 07:27:26 +0000 (07:27 -0000)
committerPeter Johnson <peter@tortall.net>
Tue, 15 May 2007 07:27:26 +0000 (07:27 -0000)
from libyasm core.  Now absolute sections are tracked locally to the parser
and the parser generates EQUs directly for labels in absolute sections.

Fixes #106 and #103.

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

22 files changed:
libyasm/bc-reserve.c
libyasm/bytecode.c
libyasm/bytecode.h
libyasm/section.c
libyasm/section.h
libyasm/symrec.c
modules/dbgfmts/dwarf2/dwarf2-line.c
modules/objfmts/coff/coff-objfmt.c
modules/objfmts/elf/elf-objfmt.c
modules/objfmts/elf/elf-x86-amd64.c
modules/objfmts/elf/elf-x86-x86.c
modules/objfmts/macho/macho-objfmt.c
modules/objfmts/rdf/rdf-objfmt.c
modules/objfmts/xdf/xdf-objfmt.c
modules/parsers/nasm/nasm-parse.c
modules/parsers/nasm/nasm-parser.c
modules/parsers/nasm/nasm-parser.h
modules/parsers/nasm/tests/Makefile.inc
modules/parsers/nasm/tests/strucalign.asm [new file with mode: 0644]
modules/parsers/nasm/tests/strucalign.hex [new file with mode: 0644]
modules/parsers/nasm/tests/struczero.asm [new file with mode: 0644]
modules/parsers/nasm/tests/struczero.hex [new file with mode: 0644]

index 8ffa98b95c2efc252d1e27b8ac6bf14fbde11b1b..9acde378f2128cc6471832e321d903b9f917f65d 100644 (file)
@@ -44,7 +44,7 @@
 
 typedef struct bytecode_reserve {
     /*@only@*/ /*@null@*/ yasm_expr *numitems; /* number of items to reserve */
-    unsigned char itemsize;         /* size of each item (in bytes) */
+    unsigned int itemsize;          /* size of each item (in bytes) */
 } bytecode_reserve;
 
 static void bc_reserve_destroy(void *contents);
@@ -83,8 +83,7 @@ bc_reserve_print(const void *contents, FILE *f, int indent_level)
     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);
+    fprintf(f, "\n%*sItem Size=%u\n", indent_level, "", reserve->itemsize);
 }
 
 static void
@@ -128,7 +127,20 @@ yasm_bc_create_reserve(yasm_expr *numitems, unsigned int itemsize,
     /*@-mustfree@*/
     reserve->numitems = numitems;
     /*@=mustfree@*/
-    reserve->itemsize = (unsigned char)itemsize;
+    reserve->itemsize = itemsize;
 
     return yasm_bc_create_common(&bc_reserve_callback, reserve, line);
 }
+
+const yasm_expr *
+yasm_bc_reserve_numitems(yasm_bytecode *bc, unsigned int *itemsize)
+{
+    bytecode_reserve *reserve;
+
+    if (bc->callback != &bc_reserve_callback)
+        return NULL;
+
+    reserve = (bytecode_reserve *)bc->contents;
+    *itemsize = reserve->itemsize;
+    return reserve->numitems;
+}
index d785e9b856d539660a0f44d7bffe48005d419b98..41fe3ca256c66fa512637a5f8c6fd419c056fb98 100644 (file)
@@ -339,3 +339,9 @@ yasm_bc_get_multiple(yasm_bytecode *bc, long *multiple, int calc_bc_dist)
     }
     return 0;
 }
+
+const yasm_expr *
+yasm_bc_get_multiple_expr(const yasm_bytecode *bc)
+{
+    return bc->multiple;
+}
index 269952167260b714a0248c99b2d17e4f2ccb946f..86c3c7e550182f8355d24dfabe26e09be96084da 100644 (file)
@@ -176,6 +176,16 @@ void yasm_bc_set_multiple(yasm_bytecode *bc, /*@keep@*/ yasm_expr *e);
     (/*@only@*/ yasm_expr *numitems, unsigned int itemsize,
      unsigned long line);
 
+/** Get the number of items and itemsize for a reserve bytecode.  If bc
+ * is not a reserve bytecode, returns NULL.
+ * \param bc            bytecode
+ * \param itemsize      reserved size (in bytes) for each item (returned)
+ * \return NULL if bc is not a reserve bytecode, otherwise an expression
+ *         for the number of items to reserve.
+ */
+/*@null@*/ const yasm_expr *yasm_bc_reserve_numitems
+    (yasm_bytecode *bc, /*@out@*/ unsigned int *itemsize);
+
 /** Create a bytecode that includes a binary file verbatim.
  * \param filename      path to binary file (kept, do not free)
  * \param start         starting location in file (in bytes) to read data from
@@ -388,6 +398,12 @@ int yasm_bc_expand(yasm_bytecode *bc, int span, long old_val, long new_val,
 int yasm_bc_get_multiple(yasm_bytecode *bc, /*@out@*/ long *multiple,
                          int calc_bc_dist);
 
+/** Get the bytecode multiple value as an expression.
+ * \param bc            bytecode
+ * \return Bytecode multiple, NULL if =1.
+ */
+const yasm_expr *yasm_bc_get_multiple_expr(const yasm_bytecode *bc);
+
 /** Create a new data value from an expression.
  * \param expn  expression
  * \return Newly allocated data value.
index 6ee8eeae244b8cea5cd3777aa335c8cd442b033b..15549c967c0930df2faad9dcad5aa6500fcd75ce 100644 (file)
@@ -61,21 +61,7 @@ struct yasm_section {
 
     /*@dependent@*/ yasm_object *object;    /* Pointer to parent object */
 
-    enum { SECTION_GENERAL, SECTION_ABSOLUTE } type;
-
-    union {
-        /* SECTION_GENERAL data */
-        struct {
-            /*@owned@*/ char *name;     /* strdup()'ed name (given by user) */
-        } general;
-        /* SECTION_ABSOLUTE data */
-        struct {
-            /* Internally created first symrec in section.  Used by
-             * yasm_expr__level_tree during absolute reference expansion.
-             */
-            /*@dependent@*/ yasm_symrec *first;
-        } absolute;
-    } data;
+    /*@owned@*/ char *name;     /* strdup()'ed name (given by user) */
 
     /* associated data; NULL if none */
     /*@null@*/ /*@only@*/ yasm__assoc_data *assoc_data;
@@ -325,8 +311,7 @@ yasm_object_get_general(yasm_object *object, const char *name,
      * that name.
      */
     STAILQ_FOREACH(s, &object->sections, link) {
-        if (s->type == SECTION_GENERAL &&
-            strcmp(s->data.general.name, name) == 0) {
+        if (strcmp(s->name, name) == 0) {
             *isnew = 0;
             return s;
         }
@@ -339,8 +324,7 @@ yasm_object_get_general(yasm_object *object, const char *name,
     STAILQ_INSERT_TAIL(&object->sections, s, link);
 
     s->object = object;
-    s->type = SECTION_GENERAL;
-    s->data.general.name = yasm__xstrdup(name);
+    s->name = yasm__xstrdup(name);
     s->assoc_data = NULL;
     if (start)
         s->start = start;
@@ -372,45 +356,6 @@ yasm_object_get_general(yasm_object *object, const char *name,
 }
 /*@=onlytrans@*/
 
-/*@-onlytrans@*/
-yasm_section *
-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(&object->sections, s, link);
-
-    s->object = object;
-    s->type = SECTION_ABSOLUTE;
-    s->start = start;
-
-    /* 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, NULL, 0);
-    bc->section = s;
-    bc->offset = 0;
-    STAILQ_INSERT_TAIL(&s->bcs, bc, link);
-
-    /* Initialize relocs */
-    STAILQ_INIT(&s->relocs);
-    s->destroy_reloc = NULL;
-
-    s->data.absolute.first =
-        yasm_symtab_define_label(object->symtab, ".absstart", bc, 0, 0);
-
-    s->code = 0;
-    s->res_only = 1;
-    s->def = 0;
-
-    return s;
-}
-/*@=onlytrans@*/
-
 int
 yasm_object_directive(yasm_object *object, const char *name,
                       const char *parser, yasm_valparamhead *valparams,
@@ -440,12 +385,6 @@ yasm_object_set_source_fn(yasm_object *object, const char *src_filename)
     object->src_filename = yasm__xstrdup(src_filename);
 }
 
-int
-yasm_section_is_absolute(yasm_section *sect)
-{
-    return (sect->type == SECTION_ABSOLUTE);
-}
-
 int
 yasm_section_is_code(yasm_section *sect)
 {
@@ -597,8 +536,7 @@ yasm_object_find_general(yasm_object *object, const char *name)
     yasm_section *cur;
 
     STAILQ_FOREACH(cur, &object->sections, link) {
-        if (cur->type == SECTION_GENERAL &&
-            strcmp(cur->data.general.name, name) == 0)
+        if (strcmp(cur->name, name) == 0)
             return cur;
     }
     return NULL;
@@ -690,17 +628,7 @@ yasm_section_bcs_traverse(yasm_section *sect,
 const char *
 yasm_section_get_name(const yasm_section *sect)
 {
-    if (sect->type == SECTION_GENERAL)
-        return sect->data.general.name;
-    return NULL;
-}
-
-yasm_symrec *
-yasm_section_abs_get_sym(const yasm_section *sect)
-{
-    if (sect->type == SECTION_ABSOLUTE)
-        return sect->data.absolute.first;
-    return NULL;
+    return sect->name;
 }
 
 void
@@ -739,9 +667,7 @@ yasm_section_destroy(yasm_section *sect)
     if (!sect)
         return;
 
-    if (sect->type == SECTION_GENERAL) {
-        yasm_xfree(sect->data.general.name);
-    }
+    yasm_xfree(sect->name);
     yasm__assoc_data_destroy(sect->assoc_data);
     yasm_expr_destroy(sect->start);
 
@@ -774,17 +700,7 @@ yasm_section_print(const yasm_section *sect, FILE *f, int indent_level,
         return;
     }
 
-    fprintf(f, "%*stype=", indent_level, "");
-    switch (sect->type) {
-        case SECTION_GENERAL:
-            fprintf(f, "general\n%*sname=%s\n", indent_level, "",
-                    sect->data.general.name);
-            break;
-        case SECTION_ABSOLUTE:
-            fprintf(f, "absolute\n");
-            break;
-    }
-
+    fprintf(f, "%*sname=%s\n", indent_level, "", sect->name);
     fprintf(f, "%*sstart=", indent_level, "");
     yasm_expr_print(sect->start, f);
     fprintf(f, "\n");
index a99a8430994e617ccdfe344da0a8dd65f32b4bf7..27ccb298a87397c71db8a497247d48e6df76670a 100644 (file)
@@ -57,8 +57,10 @@ struct yasm_object {
     /*@owned@*/ yasm_objfmt *objfmt;    /**< Object format */
     /*@owned@*/ yasm_dbgfmt *dbgfmt;    /**< Debug format */
 
-    /** Currently active section.  Used by some directives. */
-    /*@dependent@*/ yasm_section *cur_section;
+    /** Currently active section.  Used by some directives.  NULL if no
+     * section active.
+     */
+    /*@dependent@*/ /*@null@*/ yasm_section *cur_section;
 
 #ifdef YASM_LIB_INTERNAL
     /** Linked list of sections. */
@@ -108,16 +110,6 @@ struct yasm_object {
      /*@null@*/ /*@only@*/ yasm_expr *start, unsigned long align, int code,
      int res_only, /*@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 object    object
- * \param start     starting address (expression)
- * \param line      virtual line of section declaration
- * \return New section.
- */
-/*@dependent@*/ yasm_section *yasm_object_create_absolute
-    (yasm_object *object, /*@keep@*/ yasm_expr *start, unsigned long line);
-
 /** Handle a directive.  Passed down to object format, debug format, or
  * architecture as appropriate.
  * \param object                object
@@ -186,12 +178,6 @@ void yasm_object_set_source_fn(yasm_object *object, const char *src_filename);
  */
 void yasm_object_optimize(yasm_object *object, yasm_errwarns *errwarns);
 
-/** Determine if a section is absolute or general.
- * \param sect      section
- * \return Nonzero if section is absolute.
- */
-int yasm_section_is_absolute(yasm_section *sect);
-
 /** Determine if a section is flagged to contain code.
  * \param sect      section
  * \return Nonzero if section is flagged to contain code.
@@ -326,17 +312,9 @@ int yasm_section_bcs_traverse
 
 /** Get name of a section.
  * \param   sect    section
- * \return Section name, or NULL if section is absolute.
- */
-/*@observer@*/ /*@null@*/ const char *yasm_section_get_name
-    (const yasm_section *sect);
-
-/** Get starting symbol of an absolute section.
- * \param   sect    section
- * \return Starting symrec, or NULL if section is not absolute.
+ * \return Section name.
  */
-/*@dependent@*/ /*@null@*/ yasm_symrec *yasm_section_abs_get_sym
-    (const yasm_section *sect);
+/*@observer@*/ const char *yasm_section_get_name(const yasm_section *sect);
 
 /** Change starting address of a section.
  * \param sect      section
@@ -348,8 +326,7 @@ void yasm_section_set_start(yasm_section *sect, /*@only@*/ yasm_expr *start,
 
 /** Get starting address of a section.
  * \param sect      section
- * \return Starting address (may be a complex expression if section is
- *         absolute).
+ * \return Starting address.
  */
 /*@observer@*/ const yasm_expr *yasm_section_get_start
     (const yasm_section *sect);
index 2754fe440989c75ec5e2b9c5dde5b745fe782e46..bef0eaa931f9046d884b094e3519c8d4279c198e 100644 (file)
@@ -375,7 +375,6 @@ static int
 symtab_parser_finalize_checksym(yasm_symrec *sym, /*@null@*/ void *d)
 {
     symtab_finalize_info *info = (symtab_finalize_info *)d;
-    yasm_section *sect;
 
     /* error if a symbol is used but never defined or extern/common declared */
     if ((sym->status & YASM_SYM_USED) && !(sym->status & YASM_SYM_DEFINED) &&
@@ -391,26 +390,6 @@ symtab_parser_finalize_checksym(yasm_symrec *sym, /*@null@*/ void *d)
         }
     }
 
-    /* Change labels in absolute sections into EQUs with value
-     * absolute start expr + (label bc - first bc in abs section).
-     * Don't worry about possible circular references because that will get
-     * caught in EQU expansion.
-     */
-    if (sym->type == SYM_LABEL && sym->value.precbc
-        && (sect = yasm_bc_get_section(sym->value.precbc))
-        && yasm_section_is_absolute(sect)) {
-        sym->type = SYM_EQU;
-        sym->value.expn = yasm_expr_create_tree(
-            yasm_expr_create(YASM_EXPR_SUB,
-                             yasm_expr_precbc(sym->value.precbc),
-                             yasm_expr_precbc(yasm_section_bcs_first(sect)),
-                             sym->def_line),
-            YASM_EXPR_ADD,
-            yasm_expr_copy(yasm_section_get_start(sect)),
-            sym->def_line);
-        sym->status |= YASM_SYM_VALUED;
-    }
-
     return 0;
 }
 
index f98759960c33a4e59e2ed0cec4b6925b7e210364..c85763cf3f16953072e4d4f9f8a3a9e2f43c5cfc 100644 (file)
@@ -873,6 +873,12 @@ yasm_dwarf2__dir_loc(yasm_object *object, yasm_valparamhead *valparams,
     loc->line = yasm_intnum_get_uint(intn);
 
     /* Generate new section data if it doesn't already exist */
+    if (!object->cur_section) {
+        yasm_error_set(YASM_ERROR_SYNTAX,
+                       N_("[%s] can only be used inside of a section"), "loc");
+        yasm_xfree(loc);
+        return;
+    }
     dsd = yasm_section_get_data(object->cur_section,
                                 &yasm_dwarf2__section_data_cb);
     if (!dsd) {
index 72b2bdc6e6225f394ede0508781892fd4b853913..b7208fa7d8085ba2da299ee4a380f3c62ff34c03 100644 (file)
@@ -383,10 +383,6 @@ coff_objfmt_init_remaining_section(yasm_section *sect, /*@null@*/ void *d)
     /*@null@*/ coff_objfmt_output_info *info = (coff_objfmt_output_info *)d;
     /*@dependent@*/ /*@null@*/ coff_section_data *csd;
 
-    /* Skip absolute sections */
-    if (yasm_section_is_absolute(sect))
-        return 0;
-
     assert(info != NULL);
     csd = yasm_section_get_data(sect, &coff_section_data_cb);
     if (!csd) {
@@ -411,10 +407,6 @@ coff_objfmt_set_section_addr(yasm_section *sect, /*@null@*/ void *d)
     /*@null@*/ coff_objfmt_output_info *info = (coff_objfmt_output_info *)d;
     /*@dependent@*/ /*@null@*/ coff_section_data *csd;
 
-    /* Don't output absolute sections */
-    if (yasm_section_is_absolute(sect))
-        return 0;
-
     assert(info != NULL);
     csd = yasm_section_get_data(sect, &coff_section_data_cb);
     assert(csd != NULL);
@@ -744,10 +736,6 @@ coff_objfmt_output_section(yasm_section *sect, /*@null@*/ void *d)
     coff_reloc *reloc;
     unsigned char *localbuf;
 
-    /* Don't output absolute sections into the section table */
-    if (yasm_section_is_absolute(sect))
-        return 0;
-
     assert(info != NULL);
     csd = yasm_section_get_data(sect, &coff_section_data_cb);
     assert(csd != NULL);
@@ -849,10 +837,6 @@ coff_objfmt_output_sectstr(yasm_section *sect, /*@null@*/ void *d)
     const char *name;
     size_t len;
 
-    /* Don't output absolute sections into the section table */
-    if (yasm_section_is_absolute(sect))
-        return 0;
-
     /* Add to strtab if in win32 format and name > 8 chars */
     if (!info->objfmt_coff->win32)
        return 0;
@@ -873,10 +857,6 @@ coff_objfmt_output_secthead(yasm_section *sect, /*@null@*/ void *d)
     unsigned char *localbuf;
     unsigned long align = yasm_section_get_align(sect);
 
-    /* Don't output absolute sections into the section table */
-    if (yasm_section_is_absolute(sect))
-        return 0;
-
     assert(info != NULL);
     objfmt_coff = info->objfmt_coff;
     csd = yasm_section_get_data(sect, &coff_section_data_cb);
@@ -1011,21 +991,6 @@ coff_objfmt_output_sym(yasm_symrec *sym, /*@null@*/ void *d)
                     nreloc = csectd->nreloc;
                     if (COFF_SET_VMA)
                         value = csectd->addr;
-                } else if (yasm_section_is_absolute(sect)) {
-                    yasm_expr *abs_start;
-
-                    abs_start = yasm_expr_copy(yasm_section_get_start(sect));
-                    intn = yasm_expr_get_intnum(&abs_start, 1);
-                    if (!intn) {
-                        yasm_error_set(YASM_ERROR_NOT_CONSTANT,
-                            N_("absolute section start not an integer expression"));
-                        yasm_errwarn_propagate(info->errwarns,
-                                               abs_start->line);
-                    } else
-                        value = yasm_intnum_get_uint(intn);
-                    yasm_expr_destroy(abs_start);
-
-                    scnum = 0xffff;     /* -1 = absolute symbol */
                 } else
                     yasm_internal_error(N_("didn't understand section"));
                 if (precbc)
@@ -1807,8 +1772,14 @@ procframe_checkstate(yasm_objfmt_coff *objfmt_coff, const char *dirname)
  * XXX: There should be a better way to do this.
  */
 static yasm_symrec *
-get_curpos(yasm_object *object, unsigned long line)
+get_curpos(yasm_object *object, const char *dirname, unsigned long line)
 {
+    if (!object->cur_section) {
+        yasm_error_set(YASM_ERROR_SYNTAX,
+                       N_("[%s] can only be used inside of a section"),
+                       dirname);
+        return NULL;
+    }
     return yasm_symtab_define_curpos(object->symtab, "$",
         yasm_section_bcs_last(object->cur_section), line);
 }
@@ -1835,7 +1806,7 @@ dir_pushreg(yasm_object *object, yasm_valparamhead *valparams,
     /* Generate a PUSH_NONVOL unwind code. */
     code = yasm_xmalloc(sizeof(coff_unwind_code));
     code->proc = objfmt_coff->unwind->proc;
-    code->loc = get_curpos(object, line);
+    code->loc = get_curpos(object, "PUSHREG", line);
     code->opcode = UWOP_PUSH_NONVOL;
     code->info = (unsigned int)(*reg & 0xF);
     yasm_value_initialize(&code->off, NULL, 0);
@@ -1875,7 +1846,7 @@ dir_setframe(yasm_object *object, yasm_valparamhead *valparams,
     /* Generate a SET_FPREG unwind code */
     code = yasm_xmalloc(sizeof(coff_unwind_code));
     code->proc = objfmt_coff->unwind->proc;
-    code->loc = get_curpos(object, line);
+    code->loc = get_curpos(object, "SETFRAME", line);
     code->opcode = UWOP_SET_FPREG;
     code->info = (unsigned int)(*reg & 0xF);
     yasm_value_initialize(&code->off, yasm_expr_copy(off), 8);
@@ -1910,7 +1881,7 @@ dir_allocstack(yasm_object *object, yasm_valparamhead *valparams,
      */
     code = yasm_xmalloc(sizeof(coff_unwind_code));
     code->proc = objfmt_coff->unwind->proc;
-    code->loc = get_curpos(object, line);
+    code->loc = get_curpos(object, "ALLOCSTACK", line);
     code->opcode = UWOP_ALLOC_SMALL;
     code->info = 0;
     yasm_value_initialize(&code->off, vp->param, 7);
@@ -1957,7 +1928,7 @@ dir_save_common(yasm_object *object, yasm_valparamhead *valparams,
      */
     code = yasm_xmalloc(sizeof(coff_unwind_code));
     code->proc = objfmt_coff->unwind->proc;
-    code->loc = get_curpos(object, line);
+    code->loc = get_curpos(object, name, line);
     code->opcode = op;
     code->info = (unsigned int)(*reg & 0xF);
     yasm_value_initialize(&code->off, vp->param, 16);
@@ -1995,7 +1966,7 @@ dir_pushframe(yasm_object *object, /*@null@*/ yasm_valparamhead *valparams,
      */
     code = yasm_xmalloc(sizeof(coff_unwind_code));
     code->proc = objfmt_coff->unwind->proc;
-    code->loc = get_curpos(object, line);
+    code->loc = get_curpos(object, "PUSHFRAME", line);
     code->opcode = UWOP_PUSH_MACHFRAME;
     code->info = vp && (vp->val || vp->param);
     yasm_value_initialize(&code->off, NULL, 0);
@@ -2011,7 +1982,7 @@ dir_endprolog(yasm_object *object, /*@null@*/ yasm_valparamhead *valparams,
         return;
     objfmt_coff->done_prolog = line;
 
-    objfmt_coff->unwind->prolog = get_curpos(object, line);
+    objfmt_coff->unwind->prolog = get_curpos(object, "ENDPROLOG", line);
 }
 
 static void
@@ -2047,7 +2018,7 @@ dir_endproc_frame(yasm_object *object, /*@null@*/ yasm_valparamhead *valparams,
 
     proc_sym = objfmt_coff->unwind->proc;
 
-    curpos = get_curpos(object, line);
+    curpos = get_curpos(object, "ENDPROC_FRAME", line);
 
     /*
      * Add unwind info to end of .xdata section.
index eb4e662c14f064b990d297a0a3b777de5cd25b63..84a27e3bddd521758667e220f30f4f8246e7b6ac 100644 (file)
@@ -272,7 +272,7 @@ elf_objfmt_build_symtab(yasm_symrec *sym, /*@null@*/ void *d)
         /* Locals (except when debugging) do not need to be
          * in the symbol table, unless they're a section.
          */
-        if (sect && !yasm_section_is_absolute(sect) &&
+        if (sect &&
             strcmp(yasm_symrec_get_name(sym), yasm_section_get_name(sect))==0)
             is_sect = 1;
 #if 0
@@ -608,8 +608,8 @@ elf_objfmt_create_dbg_secthead(yasm_section *sect, /*@null@*/ void *d)
     elf_strtab_entry *name;
 
     shead = yasm_section_get_data(sect, &elf_section_data);
-    if (yasm_section_is_absolute(sect) || shead)
-        return 0;   /* only create new secthead if missing and non-absolute */
+    if (shead)
+        return 0;   /* only create new secthead if missing */
 
     sectname = yasm_section_get_name(sect);
     name = elf_strtab_append_str(info->objfmt_elf->shstrtab, sectname);
@@ -644,10 +644,6 @@ elf_objfmt_output_section(yasm_section *sect, /*@null@*/ void *d)
     char *relname;
     const char *sectname;
 
-    /* Don't output absolute sections into the section table */
-    if (yasm_section_is_absolute(sect))
-        return 0;
-
     if (info == NULL)
         yasm_internal_error("null info struct");
     shead = yasm_section_get_data(sect, &elf_section_data);
@@ -711,10 +707,6 @@ elf_objfmt_output_secthead(yasm_section *sect, /*@null@*/ void *d)
     /*@null@*/ elf_objfmt_output_info *info = (elf_objfmt_output_info *)d;
     /*@dependent@*/ /*@null@*/ elf_secthead *shead;
 
-    /* Don't output absolute sections into the section table */
-    if (yasm_section_is_absolute(sect))
-        return 0;
-
     if (info == NULL)
         yasm_internal_error("null info struct");
     shead = yasm_section_get_data(sect, &elf_section_data);
index 0c5ba3c98a2bf68491b6111a5212560b01d4733a..c1318d6410f32c73a4d00beb18f22c085483496a 100644 (file)
@@ -65,16 +65,11 @@ elf_x86_amd64_write_symtab_entry(unsigned char *bufp,
     YASM_WRITE_8(bufp, ELF64_ST_INFO(entry->bind, entry->type));
     YASM_WRITE_8(bufp, ELF64_ST_OTHER(entry->vis));
     if (entry->sect) {
-        if (yasm_section_is_absolute(entry->sect)) {
-            YASM_WRITE_16_L(bufp, SHN_ABS);
-        } else {
-            elf_secthead *shead = yasm_section_get_data(entry->sect,
-                &elf_section_data);
-            if (!shead)
-                yasm_internal_error(
-                    N_("symbol references section without data"));
-            YASM_WRITE_16_L(bufp, shead->index);
-        }
+        elf_secthead *shead =
+            yasm_section_get_data(entry->sect, &elf_section_data);
+        if (!shead)
+            yasm_internal_error(N_("symbol references section without data"));
+        YASM_WRITE_16_L(bufp, shead->index);
     } else {
         YASM_WRITE_16_L(bufp, entry->index);
     }
index c6b41c0ec61a455165b81930898f161c3a70bdc0..00d7a047bb0553f8bfff7dffe3b86a3b6c426758 100644 (file)
@@ -70,16 +70,11 @@ elf_x86_x86_write_symtab_entry(unsigned char *bufp,
     YASM_WRITE_8(bufp, ELF32_ST_INFO(entry->bind, entry->type));
     YASM_WRITE_8(bufp, ELF32_ST_OTHER(entry->vis));
     if (entry->sect) {
-        if (yasm_section_is_absolute(entry->sect)) {
-            YASM_WRITE_16_L(bufp, SHN_ABS);
-        } else {
-            elf_secthead *shead = yasm_section_get_data(entry->sect,
-                &elf_section_data);
-            if (!shead)
-                yasm_internal_error(
-                    N_("symbol references section without data"));
-            YASM_WRITE_16_L(bufp, shead->index);
-        }
+        elf_secthead *shead =
+            yasm_section_get_data(entry->sect, &elf_section_data);
+        if (!shead)
+            yasm_internal_error(N_("symbol references section without data"));
+        YASM_WRITE_16_L(bufp, shead->index);
     } else {
         YASM_WRITE_16_L(bufp, entry->index);
     }
index ad60d89db3fa36cbdb48c19aa270e9a56e2ae122..70f463ba526dbcc26d422fed7e5c766943b0ea80 100644 (file)
@@ -634,10 +634,6 @@ macho_objfmt_output_section(yasm_section *sect, /*@null@ */ void *d)
         (macho_objfmt_output_info *) d;
     /*@dependent@ *//*@null@ */ macho_section_data *msd;
 
-    /* FIXME: Don't output absolute sections into the section table */
-    if (yasm_section_is_absolute(sect))
-        return 0;
-
     assert(info != NULL);
     msd = yasm_section_get_data(sect, &macho_section_data_cb);
     assert(msd != NULL);
@@ -659,10 +655,6 @@ macho_objfmt_output_relocs(yasm_section *sect, /*@null@*/ void *d)
     /*@dependent@*/ /*@null@*/ macho_section_data *msd;
     macho_reloc *reloc;
 
-    /* FIXME: Don't output absolute sections into the section table */
-    if (yasm_section_is_absolute(sect))
-        return 0;
-
     reloc = (macho_reloc *)yasm_section_relocs_first(sect);
     while (reloc) {
         unsigned char *localbuf = info->buf;
@@ -744,10 +736,6 @@ macho_objfmt_output_secthead(yasm_section *sect, /*@null@*/ void *d)
     /*@dependent@*/ /*@null@*/ macho_section_data *msd;
     unsigned char *localbuf;
 
-    /* Don't output absolute sections into the section table */
-    if (yasm_section_is_absolute(sect))
-        return 0;
-
     assert(info != NULL);
     objfmt_macho = info->objfmt_macho;
     msd = yasm_section_get_data(sect, &macho_section_data_cb);
@@ -894,26 +882,8 @@ macho_objfmt_output_symtable(yasm_symrec *sym, /*@null@*/ void *d)
                 if (msd) {
                     scnum = msd->scnum;
                     n_type = N_SECT;
-                } else {
-                    if (yasm_section_is_absolute(sect)) {
-                        yasm_expr *abs_start;
-
-                        abs_start =
-                            yasm_expr_copy(yasm_section_get_start(sect));
-                        intn = yasm_expr_get_intnum(&abs_start, 1);
-                        if (!intn) {
-                            yasm_error_set(YASM_ERROR_NOT_CONSTANT,
-                                N_("absolute section start not an integer expression"));
-                            yasm_errwarn_propagate(info->errwarns,
-                                                   abs_start->line);
-                        } else
-                            value = yasm_intnum_get_uint(intn);
-                        yasm_expr_destroy(abs_start);
-
-                        scnum = -2;     /* -2 = absolute symbol */
-                    } else
-                        yasm_internal_error(N_("didn't understand section"));
-                }
+                } else
+                    yasm_internal_error(N_("didn't understand section"));
                 if (precbc)
                     value += yasm_bc_next_offset(precbc);
                 /* all values are subject to correction: base offset is first
@@ -1017,10 +987,6 @@ macho_objfmt_calc_sectsize(yasm_section *sect, /*@null@ */ void *d)
         (macho_objfmt_output_info *) d;
     /*@dependent@ *//*@null@ */ macho_section_data *msd;
 
-    /* FIXME: Don't output absolute sections into the section table */
-    if (yasm_section_is_absolute(sect))
-        return 0;
-
     assert(info != NULL);
     msd = yasm_section_get_data(sect, &macho_section_data_cb);
     assert(msd != NULL);
index f9fc22689271f2dec392d054629e7dd3f43abdc3..aa583a5bf23b37576da5ae9123065224b7e0ca67 100644 (file)
@@ -346,10 +346,6 @@ rdf_objfmt_output_section_mem(yasm_section *sect, /*@null@*/ void *d)
     /*@dependent@*/ /*@null@*/ rdf_section_data *rsd;
     unsigned long size;
 
-    /* Don't output absolute sections */
-    if (yasm_section_is_absolute(sect))
-        return 0;
-
     assert(info != NULL);
     rsd = yasm_section_get_data(sect, &rdf_section_data_cb);
     assert(rsd != NULL);
@@ -392,10 +388,6 @@ rdf_objfmt_output_section_reloc(yasm_section *sect, /*@null@*/ void *d)
     /*@dependent@*/ /*@null@*/ rdf_section_data *rsd;
     rdf_reloc *reloc;
 
-    /* Don't output absolute sections */
-    if (yasm_section_is_absolute(sect))
-        return 0;
-
     assert(info != NULL);
     rsd = yasm_section_get_data(sect, &rdf_section_data_cb);
     assert(rsd != NULL);
@@ -440,10 +432,6 @@ rdf_objfmt_output_section_file(yasm_section *sect, /*@null@*/ void *d)
     /*@dependent@*/ /*@null@*/ rdf_section_data *rsd;
     unsigned char *localbuf;
 
-    /* Don't output absolute sections */
-    if (yasm_section_is_absolute(sect))
-        return 0;
-
     assert(info != NULL);
     rsd = yasm_section_get_data(sect, &rdf_section_data_cb);
     assert(rsd != NULL);
@@ -572,15 +560,9 @@ rdf_objfmt_output_sym(yasm_symrec *sym, /*@null@*/ void *d)
 
         /* it's a label: get value and offset. */
         csectd = yasm_section_get_data(sect, &rdf_section_data_cb);
-        if (csectd) {
+        if (csectd)
             scnum = csectd->scnum;
-        } else if (yasm_section_is_absolute(sect)) {
-            yasm_warn_set(YASM_WARN_GENERAL,
-                          N_("rdf does not support exporting absolutes"));
-            yasm_errwarn_propagate(info->errwarns,
-                                   yasm_symrec_get_decl_line(sym));
-            return 0;
-        } else
+        else
             yasm_internal_error(N_("didn't understand section"));
         value = yasm_bc_next_offset(precbc);
     } else if (yasm_symrec_get_equ(sym)) {
index 0c924e850c1aec4538b1c9744a5f8eebb2990698..5c23c4ed0d78af71bc755724f43752a6bbed63e0 100644 (file)
@@ -291,10 +291,6 @@ xdf_objfmt_output_section(yasm_section *sect, /*@null@*/ void *d)
     long pos;
     xdf_reloc *reloc;
 
-    /* FIXME: Don't output absolute sections into the section table */
-    if (yasm_section_is_absolute(sect))
-        return 0;
-
     assert(info != NULL);
     xsd = yasm_section_get_data(sect, &xdf_section_data_cb);
     assert(xsd != NULL);
@@ -388,10 +384,6 @@ xdf_objfmt_output_secthead(yasm_section *sect, /*@null@*/ void *d)
     /*@null@*/ xdf_symrec_data *xsymd;
     unsigned char *localbuf;
 
-    /* Don't output absolute sections into the section table */
-    if (yasm_section_is_absolute(sect))
-        return 0;
-
     assert(info != NULL);
     objfmt_xdf = info->objfmt_xdf;
     xsd = yasm_section_get_data(sect, &xdf_section_data_cb);
@@ -489,24 +481,9 @@ xdf_objfmt_output_sym(yasm_symrec *sym, /*@null@*/ void *d)
             if (sect) {
                 /*@dependent@*/ /*@null@*/ xdf_section_data *csectd;
                 csectd = yasm_section_get_data(sect, &xdf_section_data_cb);
-                if (csectd) {
+                if (csectd)
                     scnum = csectd->scnum;
-                } else if (yasm_section_is_absolute(sect)) {
-                    yasm_expr *abs_start;
-
-                    abs_start = yasm_expr_copy(yasm_section_get_start(sect));
-                    intn = yasm_expr_get_intnum(&abs_start, 1);
-                    if (!intn) {
-                        yasm_error_set(YASM_ERROR_NOT_CONSTANT,
-                            N_("absolute section start not an integer expression"));
-                        yasm_errwarn_propagate(info->errwarns, abs_start->line);
-                    } else
-                        value = yasm_intnum_get_uint(intn);
-                    yasm_expr_destroy(abs_start);
-
-                    flags |= XDF_SYM_EQU;
-                    scnum = -2; /* -2 = absolute symbol */
-                } else
+                else
                     yasm_internal_error(N_("didn't understand section"));
                 if (precbc)
                     value += yasm_bc_next_offset(precbc);
index d3ddbb3e27d0d97fa7a0b624aab54a71e0131422..0202eae0f22b8dce94c3b7cd195f9e748a95d33b 100644 (file)
@@ -197,11 +197,41 @@ nasm_parser_parse(yasm_parser_nasm *parser_nasm)
             demand_eol();
         }
 
+        if (parser_nasm->abspos) {
+            /* If we're inside an absolute section, just add to the absolute
+             * position rather than appending bytecodes to a section.
+             * Only RES* are allowed in an absolute section, so this is easy.
+             */
+            if (bc) {
+                /*@null@*/ const yasm_expr *numitems, *multiple;
+                unsigned int itemsize;
+                numitems = yasm_bc_reserve_numitems(bc, &itemsize);
+                if (numitems) {
+                    yasm_expr *e;
+                    e = yasm_expr_create(YASM_EXPR_MUL,
+                        yasm_expr_expr(yasm_expr_copy(numitems)),
+                        yasm_expr_int(yasm_intnum_create_uint(itemsize)),
+                        cur_line);
+                    multiple = yasm_bc_get_multiple_expr(bc);
+                    if (multiple)
+                        e = yasm_expr_create_tree(e, YASM_EXPR_MUL,
+                                                  yasm_expr_copy(multiple),
+                                                  cur_line);
+                    parser_nasm->abspos = yasm_expr_create_tree(
+                        parser_nasm->abspos, YASM_EXPR_ADD, e, cur_line);
+                } else
+                    yasm_error_set(YASM_ERROR_SYNTAX,
+                        N_("only RES* allowed within absolute section"));
+                yasm_bc_destroy(bc);
+            }
+            temp_bc = NULL;
+        } else {
+            temp_bc = yasm_section_bcs_append(cursect, bc);
+            if (temp_bc)
+                parser_nasm->prev_bc = temp_bc;
+        }
         yasm_errwarn_propagate(parser_nasm->errwarns, cur_line);
 
-        temp_bc = yasm_section_bcs_append(cursect, bc);
-        if (temp_bc)
-            parser_nasm->prev_bc = temp_bc;
         if (parser_nasm->save_input)
             yasm_linemap_add_source(parser_nasm->linemap,
                 temp_bc,
@@ -1024,15 +1054,23 @@ parse_expr6(yasm_parser_nasm *parser_nasm, expr_type type)
             break;
         case '$':
             /* "$" references the current assembly position */
-            sym = yasm_symtab_define_curpos(p_symtab, "$",
-                                            parser_nasm->prev_bc, cur_line);
-            e = p_expr_new_ident(yasm_expr_sym(sym));
+            if (parser_nasm->abspos)
+                e = yasm_expr_copy(parser_nasm->abspos);
+            else {
+                sym = yasm_symtab_define_curpos(p_symtab, "$",
+                    parser_nasm->prev_bc, cur_line);
+                e = p_expr_new_ident(yasm_expr_sym(sym));
+            }
             break;
         case START_SECTION_ID:
             /* "$$" references the start of the current section */
-            sym = yasm_symtab_define_label(p_symtab, "$$",
-                yasm_section_bcs_first(cursect), 0, cur_line);
-            e = p_expr_new_ident(yasm_expr_sym(sym));
+            if (parser_nasm->absstart)
+                e = yasm_expr_copy(parser_nasm->absstart);
+            else {
+                sym = yasm_symtab_define_label(p_symtab, "$$",
+                    yasm_section_bcs_first(cursect), 0, cur_line);
+                e = p_expr_new_ident(yasm_expr_sym(sym));
+            }
             break;
         default:
             return NULL;
@@ -1053,8 +1091,12 @@ define_label(yasm_parser_nasm *parser_nasm, char *name, int local)
         strcpy(parser_nasm->locallabel_base, name);
     }
 
-    yasm_symtab_define_label(p_symtab, name, parser_nasm->prev_bc, 1,
-                             cur_line);
+    if (parser_nasm->abspos)
+        yasm_symtab_define_equ(p_symtab, name,
+                               yasm_expr_copy(parser_nasm->abspos), cur_line);
+    else
+        yasm_symtab_define_label(p_symtab, name, parser_nasm->prev_bc, 1,
+                                 cur_line);
     yasm_xfree(name);
 }
 
@@ -1073,16 +1115,6 @@ fix_directive_symrec(yasm_expr__item *ei, void *d)
     return 0;
 }
 
-static void
-dir_absolute(yasm_object *object, yasm_valparamhead *valparams,
-             yasm_valparamhead *objext_valparams, unsigned long line)
-{
-    yasm_valparam *vp = yasm_vps_first(valparams);
-    yasm_expr *start = yasm_vp_expr(vp, object->symtab, line);
-
-    object->cur_section = yasm_object_create_absolute(object, start, line);
-}
-
 static void
 dir_align(yasm_object *object, yasm_valparamhead *valparams,
           yasm_valparamhead *objext_valparams, unsigned long line)
@@ -1122,20 +1154,62 @@ nasm_parser_directive(yasm_parser_nasm *parser_nasm, const char *name,
                       yasm_valparamhead *objext_valparams)
 {
     unsigned long line = cur_line;
+    yasm_valparam *vp;
 
     if (!yasm_object_directive(p_object, name, "nasm", valparams,
                                objext_valparams, line))
         ;
-    else if (yasm__strcasecmp(name, "absolute") == 0)
-        dir_absolute(p_object, valparams, objext_valparams, line);
-    else if (yasm__strcasecmp(name, "align") == 0)
-        dir_align(p_object, valparams, objext_valparams, line);
-    else
+    else if (yasm__strcasecmp(name, "absolute") == 0) {
+        vp = yasm_vps_first(valparams);
+        if (parser_nasm->absstart)
+            yasm_expr_destroy(parser_nasm->absstart);
+        if (parser_nasm->abspos)
+            yasm_expr_destroy(parser_nasm->abspos);
+        parser_nasm->absstart = yasm_vp_expr(vp, p_object->symtab, line);
+        parser_nasm->abspos = yasm_expr_copy(parser_nasm->absstart);
+        cursect = NULL;
+        parser_nasm->prev_bc = NULL;
+    } else if (yasm__strcasecmp(name, "align") == 0) {
+        /* Really, we shouldn't end up with an align directive in an absolute
+         * section (as it's supposed to be only used for nop fill, but handle
+         * it gracefully anyway.
+         */
+        if (parser_nasm->abspos) {
+            yasm_expr *boundval, *e;
+            vp = yasm_vps_first(valparams);
+            boundval = yasm_vp_expr(vp, p_object->symtab, line);
+            e = yasm_expr_create_tree(
+                yasm_expr_create_tree(yasm_expr_copy(parser_nasm->absstart),
+                                      YASM_EXPR_SUB,
+                                      yasm_expr_copy(parser_nasm->abspos),
+                                      cur_line),
+                YASM_EXPR_AND,
+                yasm_expr_create(YASM_EXPR_SUB, yasm_expr_expr(boundval),
+                                 yasm_expr_int(yasm_intnum_create_uint(1)),
+                                 cur_line),
+                cur_line);
+            parser_nasm->abspos = yasm_expr_create_tree(
+                parser_nasm->abspos, YASM_EXPR_ADD, e, cur_line);
+        } else
+            dir_align(p_object, valparams, objext_valparams, line);
+    } else
         yasm_error_set(YASM_ERROR_SYNTAX, N_("unrecognized directive `%s'"),
                        name);
 
-    /* In case cursect changed or a bytecode was added, update prev_bc. */
-    parser_nasm->prev_bc = yasm_section_bcs_last(cursect);
+    if (parser_nasm->absstart && cursect) {
+        /* We switched to a new section.  Get out of absolute section mode. */
+        yasm_expr_destroy(parser_nasm->absstart);
+        parser_nasm->absstart = NULL;
+        if (parser_nasm->abspos) {
+            yasm_expr_destroy(parser_nasm->abspos);
+            parser_nasm->abspos = NULL;
+        }
+    }
+
+    if (cursect) {
+        /* In case cursect changed or a bytecode was added, update prev_bc. */
+        parser_nasm->prev_bc = yasm_section_bcs_last(cursect);
+    }
 
     if (valparams)
         yasm_vps_delete(valparams);
index 786b6d50b35aa0639aaa41076e8489427c0811a7..2fa1934badf48c75ee4fb6dd6a57d467903d4542 100644 (file)
@@ -58,6 +58,9 @@ nasm_parser_do_parse(yasm_object *object, yasm_preproc *pp, FILE *f,
 
     parser_nasm.peek_token = NONE;
 
+    parser_nasm.absstart = NULL;
+    parser_nasm.abspos = NULL;
+
     /* initialize scanner structure */
     yasm_scanner_initialize(&parser_nasm.s);
 
index 51bb6b7d8603bb52dc5ea32ed8dbc93683492eb8..de0824b5bb1b7b556dbf09d1ddb213d9d651d5ba 100644 (file)
@@ -117,6 +117,16 @@ typedef struct yasm_parser_nasm {
     int peek_token;     /* NONE if none */
     yystype peek_tokval;
     char peek_tokch;
+
+    /* Starting point of the absolute section.  NULL if not in an absolute
+     * section.
+     */
+    /*@null@*/ yasm_expr *absstart;
+
+    /* Current location inside an absolute section (including the start).
+     * NULL if not in an absolute section.
+     */
+    /*@null@*/ yasm_expr *abspos;
 } yasm_parser_nasm;
 
 /* shorter access names to commonly used parser_nasm fields */
index 87f8c1ca907cd0f1358a2f9550eff61a327e70d6..552320cc94cc2755457d8d22ddbd10823f79272e 100644 (file)
@@ -24,6 +24,10 @@ EXTRA_DIST += modules/parsers/nasm/tests/orphannowarn.hex
 EXTRA_DIST += modules/parsers/nasm/tests/prevlocalwarn.asm
 EXTRA_DIST += modules/parsers/nasm/tests/prevlocalwarn.errwarn
 EXTRA_DIST += modules/parsers/nasm/tests/prevlocalwarn.hex
+EXTRA_DIST += modules/parsers/nasm/tests/strucalign.asm
+EXTRA_DIST += modules/parsers/nasm/tests/strucalign.hex
+EXTRA_DIST += modules/parsers/nasm/tests/struczero.asm
+EXTRA_DIST += modules/parsers/nasm/tests/struczero.hex
 
 EXTRA_DIST += modules/parsers/nasm/tests/worphan/Makefile.inc
 
diff --git a/modules/parsers/nasm/tests/strucalign.asm b/modules/parsers/nasm/tests/strucalign.asm
new file mode 100644 (file)
index 0000000..f3fbd48
--- /dev/null
@@ -0,0 +1,14 @@
+struc bug
+times (64-$) resb 1
+.member:
+times (128-($-$$)) resb 1
+.member2:
+alignb 256
+.member3:
+[align 512]
+endstruc
+dd bug
+dd bug.member
+dd bug.member2
+dd bug.member3
+dd bug_size
diff --git a/modules/parsers/nasm/tests/strucalign.hex b/modules/parsers/nasm/tests/strucalign.hex
new file mode 100644 (file)
index 0000000..d3baa2a
--- /dev/null
@@ -0,0 +1,20 @@
+00 
+00 
+00 
+00 
+40 
+00 
+00 
+00 
+80 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+02 
+00 
+00 
diff --git a/modules/parsers/nasm/tests/struczero.asm b/modules/parsers/nasm/tests/struczero.asm
new file mode 100644 (file)
index 0000000..26bf13d
--- /dev/null
@@ -0,0 +1,7 @@
+struc MYSTRUC
+.zero resd 0
+endstruc
+
+foo:
+mov eax, [ecx+MYSTRUC.zero]
+ret
diff --git a/modules/parsers/nasm/tests/struczero.hex b/modules/parsers/nasm/tests/struczero.hex
new file mode 100644 (file)
index 0000000..769fb4e
--- /dev/null
@@ -0,0 +1,5 @@
+67 
+66 
+8b 
+01 
+c3