]> granicus.if.org Git - yasm/commitdiff
Move section alignment to libyasm, refactoring it from individual object
authorPeter Johnson <peter@tortall.net>
Sun, 13 Nov 2005 20:44:21 +0000 (20:44 -0000)
committerPeter Johnson <peter@tortall.net>
Sun, 13 Nov 2005 20:44:21 +0000 (20:44 -0000)
formats.

* section.h (yasm_object_get_general): Add align parameter.
(yasm_section_set_align, yasm_section_get_align): New.
* section.c (yasm_section): Add align member and implementations.

* objfmt.h (yasm_objfmt_section_align): Remove.

* gas-bison.y (gas_parser_align): Change to use yasm_section_get/set_align().

* xdf, elf, bin, dbg, coff, stabs: Refactor as necessary.

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

14 files changed:
libyasm/objfmt.h
libyasm/section.c
libyasm/section.h
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-x86-amd64.c
modules/objfmts/elf/elf-x86-x86.c
modules/objfmts/elf/elf.c
modules/objfmts/elf/elf.h
modules/objfmts/xdf/xdf-objfmt.c
modules/parsers/gas/gas-bison.y

index 34cf80f0f2a4102fc787d60efa477c5f88c5f84a..0bdd64832e80f422c89ee9a1281f3f2b0ce862cd 100644 (file)
@@ -107,12 +107,6 @@ typedef struct yasm_objfmt_module {
                          /*@null@*/ yasm_valparamhead *objext_valparams,
                          unsigned long line);
 
-    /** Module-level implementation of yasm_objfmt_section_align().
-     * Call yasm_objfmt_section_align() instead of calling this function.
-     */
-    void (*section_align)(yasm_objfmt *objfmt, yasm_section *sect,
-                         unsigned long align, unsigned long line);
-
     /** Module-level implementation of yasm_objfmt_extern_declare().
      * Call yasm_objfmt_extern_declare() instead of calling this function.
      */
@@ -185,15 +179,6 @@ void yasm_objfmt_destroy(/*@only@*/ yasm_objfmt *objfmt);
     (yasm_objfmt *objfmt, yasm_valparamhead *valparams,
      /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line);
 
-/** Set alignment for a section.
- * \param objfmt       object format
- * \param sect         section
- * \param align                desired alignment (must be power of two)
- * \param line         virtual line (from yasm_linemap)
- */
-void yasm_objfmt_section_align(yasm_objfmt *objfmt, yasm_section *sect,
-                              unsigned long align, unsigned long line);
-
 /** Declare an "extern" (importing from another module) symbol.  Should
  * call yasm_symtab_declare().
  * \param objfmt               object format
@@ -261,9 +246,6 @@ int yasm_objfmt_directive(yasm_objfmt *objfmt, const char *name,
 #define yasm_objfmt_section_switch(objfmt, vpms, oe_vpms, line) \
     ((yasm_objfmt_base *)objfmt)->module->section_switch(objfmt, vpms, \
                                                         oe_vpms, line)
-#define yasm_objfmt_section_align(objfmt, sect, align, line) \
-    ((yasm_objfmt_base *)objfmt)->module->section_align(objfmt, sect, \
-                                                       align, line)
 #define yasm_objfmt_extern_declare(objfmt, name, oe_vpms, line) \
     ((yasm_objfmt_base *)objfmt)->module->extern_declare(objfmt, name, \
                                                         oe_vpms, line)
index d691718a66aaf3959417c25c7ac568ebea5af833..89a4bc3aaaf4d42179c06d99b348083ba740eedc 100644 (file)
@@ -71,6 +71,8 @@ struct yasm_section {
 
     /*@owned@*/ yasm_expr *start;   /* Starting address of section contents */
 
+    unsigned long align;       /* Section alignment */
+
     unsigned long opt_flags;   /* storage for optimizer flags */
 
     int code;                  /* section contains code (instructions) */
@@ -108,8 +110,8 @@ yasm_object_create(void)
 /*@-onlytrans@*/
 yasm_section *
 yasm_object_get_general(yasm_object *object, const char *name,
-                       yasm_expr *start, int code, int res_only, int *isnew,
-                       unsigned long line)
+                       yasm_expr *start, unsigned long align, int code,
+                       int res_only, int *isnew, unsigned long line)
 {
     yasm_section *s;
     yasm_bytecode *bc;
@@ -141,6 +143,7 @@ yasm_object_get_general(yasm_object *object, const char *name,
        s->start =
            yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(0)),
                                   line);
+    s->align = align;
 
     /* Initialize bytecodes with one empty bytecode (acts as "prior" for first
      * real bytecode in section.
@@ -441,6 +444,19 @@ yasm_section_get_start(const yasm_section *sect)
     return sect->start;
 }
 
+void
+yasm_section_set_align(yasm_section *sect, unsigned long align,
+                      unsigned long line)
+{
+    sect->align = align;
+}
+
+unsigned long
+yasm_section_get_align(const yasm_section *sect)
+{
+    return sect->align;
+}
+
 static void
 yasm_section_destroy(yasm_section *sect)
 {
index 6634da8ff6968ace11a167113e60bd60f515943c..c41321861a1309820e93b4852d0e2d58f3d15c44 100644 (file)
@@ -60,6 +60,7 @@ struct yasm_reloc {
  * \param name     section name
  * \param start            starting address (ignored if section already exists),
  *                 NULL if 0 or don't care.
+ * \param align            alignment in bytes (0 if none)
  * \param code     if nonzero, section is intended to contain code
  *                 (e.g. alignment should be made with NOP instructions, not 0)
  * \param res_only  if nonzero, only space-reserving bytecodes are allowed in
@@ -71,8 +72,8 @@ struct yasm_reloc {
  */
 /*@dependent@*/ yasm_section *yasm_object_get_general
     (yasm_object *object, const char *name,
-     /*@null@*/ /*@only@*/ yasm_expr *start, int code, int res_only,
-     /*@out@*/ int *isnew, unsigned long line);
+     /*@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.
@@ -279,6 +280,20 @@ void yasm_section_set_start(yasm_section *sect, /*@only@*/ yasm_expr *start,
 /*@observer@*/ const yasm_expr *yasm_section_get_start
     (const yasm_section *sect);
 
+/** Change alignment of a section.
+ * \param sect     section
+ * \param align            alignment in bytes
+ * \param line     virtual line
+ */
+void yasm_section_set_align(yasm_section *sect, unsigned long align,
+                           unsigned long line);
+
+/** Get alignment of a section.
+ * \param sect     section
+ * \return Alignment in bytes (0 if none).
+ */
+unsigned long yasm_section_get_align(const yasm_section *sect);
+
 /** Print a section.  For debugging purposes.
  * \param f            file
  * \param indent_level indentation level
index 578e1261678712a0a836d487c9d27eb1f2e10522..07794791ba7b525140954bccd947948cd33059bc 100644 (file)
@@ -336,8 +336,8 @@ stabs_dbgfmt_generate(yasm_dbgfmt *dbgfmt)
     info.dbgfmt_stabs = dbgfmt_stabs;
     info.lastline = 0;
     info.stabcount = 0;
-    info.stab = yasm_object_get_general(dbgfmt_stabs->object, ".stab", 0, 0, 0,
-                                       &new, 0);
+    info.stab = yasm_object_get_general(dbgfmt_stabs->object, ".stab", 0, 4, 0,
+                                       0, &new, 0);
     if (!new) {
        yasm_bytecode *last = yasm_section_bcs_last(info.stab);
        if (last == NULL)
@@ -349,7 +349,7 @@ stabs_dbgfmt_generate(yasm_dbgfmt *dbgfmt)
     }
 
     info.stabstr = yasm_object_get_general(dbgfmt_stabs->object, ".stabstr", 0,
-                                          0, 0, &new, 0);
+                                          1, 0, 0, &new, 0);
     if (!new) {
        yasm_bytecode *last = yasm_section_bcs_last(info.stabstr);
        if (last == NULL)
index 27fafb93e3a776d211e1a3124acd1a97e7a3ec7b..fe5cdc7861443263129de860b51ba731a6ed365b 100644 (file)
 
 #define REGULAR_OUTBUF_SIZE    1024
 
-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
-};
-
 typedef struct yasm_objfmt_bin {
     yasm_objfmt_base objfmt;           /* base structure */
 
@@ -66,20 +58,18 @@ bin_objfmt_create(/*@unused@*/ const char *in_filename, yasm_object *object,
     return (yasm_objfmt *)objfmt_bin;
 }
 
-/* Aligns sect to either its specified alignment (in its objfmt-specific data)
- * or def_align if no alignment was specified.  Uses prevsect and base to both
- * determine the new starting address (returned) and the total length of
+/* Aligns sect to either its specified alignment.  Uses prevsect and base to
+ * both determine the new starting address (returned) and the total length of
  * prevsect after sect has been aligned.
  */
 static unsigned long
 bin_objfmt_align_section(yasm_section *sect, yasm_section *prevsect,
-                        unsigned long base, unsigned long def_align,
+                        unsigned long base,
                         /*@out@*/ unsigned long *prevsectlen,
                         /*@out@*/ unsigned long *padamt)
 {
     /*@dependent@*/ /*@null@*/ yasm_bytecode *last;
     unsigned long start;
-    /*@dependent@*/ /*@null@*/ unsigned long *alignptr;
     unsigned long align;
 
     /* Figure out the size of .text by looking at the last bytecode's offset
@@ -96,11 +86,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_data(sect, &bin_section_data_callback);
-    if (alignptr)
-       align = *alignptr;
-    else
-       align = def_align;      /* No alignment: use default */
+    align = yasm_section_get_align(sect);
 
     if (start & (align-1))
        start = (start & ~(align-1)) + align;
@@ -302,7 +288,7 @@ bin_objfmt_output(yasm_objfmt *objfmt, FILE *f, const char *obj_filename,
     prevsectlenptr = &textlen;
     prevsectpadptr = &textpad;
     if (data) {
-       start = bin_objfmt_align_section(data, prevsect, start, 4,
+       start = bin_objfmt_align_section(data, prevsect, start,
                                         prevsectlenptr, prevsectpadptr);
        yasm_section_set_start(data, yasm_expr_create_ident(
            yasm_expr_int(yasm_intnum_create_uint(start)), 0), 0);
@@ -312,7 +298,7 @@ bin_objfmt_output(yasm_objfmt *objfmt, FILE *f, const char *obj_filename,
        prevsectpadptr = &datapad;
     }
     if (bss) {
-       start = bin_objfmt_align_section(bss, prevsect, start, 4,
+       start = bin_objfmt_align_section(bss, prevsect, start,
                                         prevsectlenptr, prevsectpadptr);
        yasm_section_set_start(bss, yasm_expr_create_ident(
            yasm_expr_int(yasm_intnum_create_uint(start)), 0), 0);
@@ -362,8 +348,8 @@ bin_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,
     unsigned long start;
     char *sectname;
     int resonly = 0;
-    unsigned long alignval = 0;
-    int have_alignval = 0;
+    unsigned long align = 4;
+    int have_align = 0;
 
     if ((vp = yasm_vps_first(valparams)) && !vp->param && vp->val != NULL) {
        /* If it's the first section output (.text) start at 0, otherwise
@@ -387,7 +373,7 @@ bin_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,
        /* Check for ALIGN qualifier */
        while ((vp = yasm_vps_next(vp))) {
            if (yasm__strcasecmp(vp->val, "align") == 0 && vp->param) {
-               /*@dependent@*/ /*@null@*/ const yasm_intnum *align;
+               /*@dependent@*/ /*@null@*/ const yasm_intnum *align_expr;
                unsigned long bitcnt;
 
                if (strcmp(sectname, ".text") == 0) {
@@ -397,47 +383,37 @@ bin_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,
                    return NULL;
                }
                
-               align = yasm_expr_get_intnum(&vp->param, NULL);
-               if (!align) {
+               align_expr = yasm_expr_get_intnum(&vp->param, NULL);
+               if (!align_expr) {
                    yasm__error(line,
                                N_("argument to `%s' is not a power of two"),
                                vp->val);
                    return NULL;
                }
-               alignval = yasm_intnum_get_uint(align);
+               align = yasm_intnum_get_uint(align_expr);
 
-               /* Check to see if alignval is a power of two.
-                * This can be checked by seeing if only one bit is set.
-                */
-               BitCount(bitcnt, alignval);
-               if (bitcnt > 1) {
+               /* Alignments must be a power of two. */
+               if ((align & (align - 1)) != 0) {
                    yasm__error(line,
                                N_("argument to `%s' is not a power of two"),
                                vp->val);
                    return NULL;
                }
 
-               have_alignval = 1;
+               have_align = 1;
            }
        }
 
        retval = yasm_object_get_general(objfmt_bin->object, sectname,
            yasm_expr_create_ident(
-               yasm_expr_int(yasm_intnum_create_uint(start)), line),
+               yasm_expr_int(yasm_intnum_create_uint(start)), line), align,
            strcmp(sectname, ".text") == 0, resonly, &isnew, line);
 
        if (isnew) {
-           if (have_alignval) {
-               unsigned long *data = yasm_xmalloc(sizeof(unsigned long));
-               *data = alignval;
-               yasm_section_add_data(retval, &bin_section_data_callback,
-                                     data);
-           }
-
            yasm_symtab_define_label(
                yasm_object_get_symtab(objfmt_bin->object), sectname,
                yasm_section_bcs_first(retval), 1, line);
-       } else if (have_alignval)
+       } else if (have_align)
            yasm__warning(YASM_WARN_GENERAL, line,
                N_("alignment value ignored on section redeclaration"));
 
@@ -445,33 +421,6 @@ bin_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,
     } else
        return NULL;
 }
-static void
-bin_objfmt_section_align(yasm_objfmt *objfmt, yasm_section *sect,
-                        unsigned long align, unsigned long line)
-{
-    /*@only@*/ unsigned long *oldalign;
-
-    if (strcmp(yasm_section_get_name(sect), ".text") == 0) {
-       yasm__error(line, N_("cannot specify an alignment to the `%s' section"),
-                   ".text");
-       return;
-    }
-
-    oldalign = yasm_section_get_data(sect, &bin_section_data_callback);
-    if (oldalign)
-       *oldalign = align;
-    else {
-       unsigned long *data = yasm_xmalloc(sizeof(unsigned long));
-       *data = align;
-       yasm_section_add_data(sect, &bin_section_data_callback, data);
-    }
-}
-
-static void
-bin_section_data_destroy(/*@only@*/ void *d)
-{
-    yasm_xfree(d);
-}
 
 static yasm_symrec *
 bin_objfmt_extern_declare(yasm_objfmt *objfmt, const char *name,
@@ -563,12 +512,6 @@ bin_objfmt_directive(yasm_objfmt *objfmt, const char *name,
        return 1;           /* directive unrecognized */
 }
 
-static void
-bin_section_data_print(void *data, FILE *f, int indent_level)
-{
-    fprintf(f, "%*salign=%ld\n", indent_level, "", *((unsigned long *)data));
-}
-
 
 /* Define valid debug formats to use with this object format */
 static const char *bin_objfmt_dbgfmt_keywords[] = {
@@ -589,7 +532,6 @@ yasm_objfmt_module yasm_bin_LTX_objfmt = {
     bin_objfmt_output,
     bin_objfmt_destroy,
     bin_objfmt_section_switch,
-    bin_objfmt_section_align,
     bin_objfmt_extern_declare,
     bin_objfmt_global_declare,
     bin_objfmt_common_declare,
index fd18e3a3b54265a5128b00036e94adbd3468cbe2..af848b5e5539540f0cea212c20353f42cc8705e8 100644 (file)
@@ -662,6 +662,7 @@ coff_objfmt_output_secthead(yasm_section *sect, /*@null@*/ void *d)
     yasm_objfmt_coff *objfmt_coff;
     /*@dependent@*/ /*@null@*/ coff_section_data *csd;
     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))
@@ -672,6 +673,17 @@ coff_objfmt_output_secthead(yasm_section *sect, /*@null@*/ void *d)
     csd = yasm_section_get_data(sect, &coff_section_data_cb);
     assert(csd != NULL);
 
+    /* Check to see if alignment is supported size */
+    if (align > 8192)
+       align = 8192;
+
+    /* Convert alignment into flags setting */
+    csd->flags &= ~COFF_STYP_ALIGN_MASK;
+    while (align != 0) {
+       csd->flags += 1<<COFF_STYP_ALIGN_SHIFT;
+       align >>= 1;
+    }
+
     localbuf = info->buf;
     strncpy((char *)localbuf, yasm_section_get_name(sect), 8);/* section name */
     localbuf += 8;
@@ -1040,6 +1052,7 @@ coff_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,
     int flags_override = 0;
     char *sectname;
     int resonly = 0;
+    unsigned long align = 0;
 
     static const struct {
        const char *name;
@@ -1093,30 +1106,32 @@ coff_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,
        if (objfmt_coff->win32) {
            flags |= COFF_STYP_READ | COFF_STYP_WRITE;
            if (objfmt_coff->machine == COFF_MACHINE_AMD64)
-               flags |= 5<<COFF_STYP_ALIGN_SHIFT;      /* align=16 */
+               align = 16;
            else
-               flags |= 3<<COFF_STYP_ALIGN_SHIFT;      /* align=4 */
+               align = 4;
        }
     } else if (strcmp(sectname, ".bss") == 0) {
        flags = COFF_STYP_BSS;
        if (objfmt_coff->win32) {
            flags |= COFF_STYP_READ | COFF_STYP_WRITE;
            if (objfmt_coff->machine == COFF_MACHINE_AMD64)
-               flags |= 5<<COFF_STYP_ALIGN_SHIFT;      /* align=16 */
+               align = 16;
            else
-               flags |= 3<<COFF_STYP_ALIGN_SHIFT;      /* align=4 */
+               align = 4;
        }
        resonly = 1;
     } else if (strcmp(sectname, ".text") == 0) {
        flags = COFF_STYP_TEXT;
-       if (objfmt_coff->win32)
-           flags |= COFF_STYP_EXECUTE | COFF_STYP_READ |
-               (5<<COFF_STYP_ALIGN_SHIFT);     /* align=16 */
+       if (objfmt_coff->win32) {
+           flags |= COFF_STYP_EXECUTE | COFF_STYP_READ;
+           align = 16;
+       }
     } else if (strcmp(sectname, ".rdata") == 0) {
        flags = COFF_STYP_DATA;
-       if (objfmt_coff->win32)
-           flags |= COFF_STYP_READ | (4<<COFF_STYP_ALIGN_SHIFT); /* align=8 */
-       else
+       if (objfmt_coff->win32) {
+           flags |= COFF_STYP_READ;
+           align = 8;
+       } else
            yasm__warning(YASM_WARN_GENERAL, line,
                N_("Standard COFF does not support read-only data sections"));
     } else if (strcmp(sectname, ".drectve") == 0) {
@@ -1124,12 +1139,12 @@ coff_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,
        if (objfmt_coff->win32)
            flags |= COFF_STYP_DISCARD | COFF_STYP_READ;
     } else if (objfmt_coff->win32 && strcmp(sectname, ".pdata") == 0) {
-       flags = COFF_STYP_DATA | COFF_STYP_READ
-           | 3<<COFF_STYP_ALIGN_SHIFT; /* align=4 */
+       flags = COFF_STYP_DATA | COFF_STYP_READ;
+       align = 4;
        flags2 = COFF_FLAG_NOBASE;
     } else if (objfmt_coff->win32 && strcmp(sectname, ".xdata") == 0) {
-       flags = COFF_STYP_DATA | COFF_STYP_READ
-           | 4<<COFF_STYP_ALIGN_SHIFT; /* align=8 */
+       flags = COFF_STYP_DATA | COFF_STYP_READ;
+       align = 8;
     } else {
        /* Default to code */
        flags = COFF_STYP_TEXT;
@@ -1180,24 +1195,20 @@ coff_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,
            ;
        else if (yasm__strcasecmp(vp->val, "align") == 0 && vp->param) {
            if (objfmt_coff->win32) {
-               /*@dependent@*/ /*@null@*/ const yasm_intnum *align;
+               /*@dependent@*/ /*@null@*/ const yasm_intnum *align_expr;
                unsigned long bitcnt;
-               unsigned long addralign;
 
-               align = yasm_expr_get_intnum(&vp->param, NULL);
-               if (!align) {
+               align_expr = yasm_expr_get_intnum(&vp->param, NULL);
+               if (!align_expr) {
                    yasm__error(line,
                                N_("argument to `%s' is not a power of two"),
                                vp->val);
                    return NULL;
                }
-               addralign = yasm_intnum_get_uint(align);
+               align = yasm_intnum_get_uint(align_expr);
 
-               /* Check to see if alignment is a power of two.
-                * This can be checked by seeing if only one bit is set.
-                */
-               BitCount(bitcnt, addralign);
-               if (bitcnt > 1) {
+               /* Alignments must be a power of two. */
+               if ((align & (align - 1)) != 0) {
                    yasm__error(line,
                                N_("argument to `%s' is not a power of two"),
                                vp->val);
@@ -1205,18 +1216,12 @@ coff_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,
                }
 
                /* Check to see if alignment is supported size */
-               if (addralign > 8192) {
+               if (align > 8192) {
                    yasm__error(line,
                        N_("Win32 does not support alignments > 8192"));
                    return NULL;
                }
 
-               /* Convert alignment into flags setting */
-               flags &= ~COFF_STYP_ALIGN_MASK;
-               while (addralign != 0) {
-                   flags += 1<<COFF_STYP_ALIGN_SHIFT;
-                   addralign >>= 1;
-               }
            } else
                win32warn = 1;
        } else
@@ -1228,7 +1233,7 @@ coff_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,
                N_("Standard COFF does not support qualifier `%s'"), vp->val);
     }
 
-    retval = yasm_object_get_general(objfmt_coff->object, sectname, 0,
+    retval = yasm_object_get_general(objfmt_coff->object, sectname, 0, align,
                                     (flags & COFF_STYP_EXECUTE) != 0,
                                     resonly, &isnew, line);
 
@@ -1241,37 +1246,6 @@ coff_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,
     return retval;
 }
 
-static void
-coff_objfmt_section_align(yasm_objfmt *objfmt, yasm_section *sect,
-                         unsigned long align, unsigned long line)
-{
-    yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)objfmt;
-    /*@dependent@*/ /*@null@*/ coff_section_data *csd;
-
-    csd = yasm_section_get_data(sect, &coff_section_data_cb);
-    if (!csd)
-       yasm_internal_error(N_("NULL coff section data in section_align"));
-
-    if (!objfmt_coff->win32) {
-       yasm__warning(YASM_WARN_GENERAL, line,
-                     N_("COFF does not support section alignment"));
-       return;
-    }
-
-    /* Check to see if alignment is supported size */
-    if (align > 8192) {
-       yasm__error(line, N_("Win32 does not support alignments > 8192"));
-       return;
-    }
-
-    /* Convert alignment into flags setting */
-    csd->flags &= ~COFF_STYP_ALIGN_MASK;
-    while (align != 0) {
-       csd->flags += 1<<COFF_STYP_ALIGN_SHIFT;
-       align >>= 1;
-    }
-}
-
 static void
 coff_section_data_destroy(void *data)
 {
@@ -1418,7 +1392,7 @@ win32_objfmt_directive(yasm_objfmt *objfmt, const char *name,
 
        /* Add to end of linker directives */
        sect = yasm_object_get_general(objfmt_coff->object, ".drectve", 0, 0,
-                                      0, &isnew, line);
+                                      0, 0, &isnew, line);
 
        /* Initialize directive section if needed */
        if (isnew)
@@ -1462,7 +1436,6 @@ yasm_objfmt_module yasm_coff_LTX_objfmt = {
     coff_objfmt_output,
     coff_objfmt_destroy,
     coff_objfmt_section_switch,
-    coff_objfmt_section_align,
     coff_objfmt_extern_declare,
     coff_objfmt_global_declare,
     coff_objfmt_common_declare,
@@ -1482,7 +1455,6 @@ yasm_objfmt_module yasm_win32_LTX_objfmt = {
     coff_objfmt_output,
     coff_objfmt_destroy,
     coff_objfmt_section_switch,
-    coff_objfmt_section_align,
     coff_objfmt_extern_declare,
     coff_objfmt_global_declare,
     coff_objfmt_common_declare,
@@ -1502,7 +1474,6 @@ yasm_objfmt_module yasm_win64_LTX_objfmt = {
     coff_objfmt_output,
     coff_objfmt_destroy,
     coff_objfmt_section_switch,
-    coff_objfmt_section_align,
     coff_objfmt_extern_declare,
     coff_objfmt_global_declare,
     coff_objfmt_common_declare,
index 3b2b7fcc7440b1d7b00228c5637f45e57e843526..2b8b83a5ac7e2b190871a4a74897bdeba1c0635f 100644 (file)
@@ -118,7 +118,7 @@ dbg_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,
     if ((vp = yasm_vps_first(valparams)) && !vp->param && vp->val != NULL) {
        retval = yasm_object_get_general(objfmt_dbg->object, vp->val,
            yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(200)),
-                                  line), 0, 0, &isnew, line);
+                                  line), 0, 0, 0, &isnew, line);
        if (isnew) {
            fprintf(objfmt_dbg->dbgfile, "(new) ");
            yasm_symtab_define_label(
@@ -234,7 +234,6 @@ yasm_objfmt_module yasm_dbg_LTX_objfmt = {
     dbg_objfmt_output,
     dbg_objfmt_destroy,
     dbg_objfmt_section_switch,
-    dbg_objfmt_section_align,
     dbg_objfmt_extern_declare,
     dbg_objfmt_global_declare,
     dbg_objfmt_common_declare,
index 4d14b76f71f3433757321caba2c83375b7c42140..8fd9f81ca2af7d9ad0e68b6137f711804593b76b 100644 (file)
@@ -472,24 +472,20 @@ elf_objfmt_create_dbg_secthead(yasm_section *sect,
 {
     elf_secthead *shead;
     elf_section_type type=SHT_PROGBITS;
-    yasm_intnum *align=NULL;
     elf_size entsize=0;
     const char *sectname = yasm_section_get_name(sect);
     elf_strtab_entry *name = elf_strtab_append_str(info->objfmt_elf->shstrtab,
                                                   sectname);
 
     if (yasm__strcasecmp(sectname, ".stab")==0) {
-       align = yasm_intnum_create_uint(4);
        entsize = 12;
     } else if (yasm__strcasecmp(sectname, ".stabstr")==0) {
        type = SHT_STRTAB;
-       align = yasm_intnum_create_uint(1);
     }
     else
        yasm_internal_error(N_("Unrecognized section without data"));
 
     shead = elf_secthead_create(name, type, 0, 0, 0);
-    elf_secthead_set_align(shead, align);
     elf_secthead_set_entsize(shead, entsize);
 
     yasm_section_add_data(sect, &elf_section_data, shead);
@@ -516,6 +512,9 @@ elf_objfmt_output_section(yasm_section *sect, /*@null@*/ void *d)
     if (shead == NULL)
        shead = elf_objfmt_create_dbg_secthead(sect, info);
 
+    if (elf_secthead_get_align(shead) == 0)
+       elf_secthead_set_align(shead, yasm_section_get_align(sect));
+
     /* don't output header-only sections */
     if ((elf_secthead_get_type(shead) & SHT_NOBITS) == SHT_NOBITS)
     {
@@ -843,7 +842,6 @@ elf_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,
        }
        else if (yasm__strcasecmp(vp->val, "align") == 0 && vp->param) {
             /*@dependent@*/ /*@null@*/ const yasm_intnum *align_expr;
-            unsigned long addralign;
 
             align_expr = yasm_expr_get_intnum(&vp->param, NULL);
             if (!align_expr) {
@@ -852,23 +850,21 @@ elf_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,
                             vp->val);
                 return NULL;
             }
-            addralign = yasm_intnum_get_uint(align_expr);
+            align = yasm_intnum_get_uint(align_expr);
 
             /* Alignments must be a power of two. */
-            if ((addralign & (addralign - 1)) != 0) {
+            if ((align & (align - 1)) != 0) {
                 yasm__error(line,
                             N_("argument to `%s' is not a power of two"),
                             vp->val);
                 return NULL;
             }
-
-            align_intn = yasm_intnum_copy(align_expr);
        } else
            yasm__warning(YASM_WARN_GENERAL, line,
                          N_("Unrecognized qualifier `%s'"), vp->val);
     }
 
-    retval = yasm_object_get_general(objfmt_elf->object, sectname, 0,
+    retval = yasm_object_get_general(objfmt_elf->object, sectname, 0, align,
                                     (flags & SHF_EXECINSTR) != 0, resonly,
                                     &isnew, line);
 
@@ -879,10 +875,6 @@ elf_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,
                                                       sectname);
 
        esd = elf_secthead_create(name, type, flags, 0, 0);
-       if (!align_intn)
-           align_intn = yasm_intnum_create_uint(align);
-       if (align_intn)
-           elf_secthead_set_align(esd, align_intn);
        yasm_section_add_data(retval, &elf_section_data, esd);
        sym = yasm_symtab_define_label(
            yasm_object_get_symtab(objfmt_elf->object), sectname,
@@ -915,27 +907,6 @@ elf_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,
     return retval;
 }
 
-static void
-elf_objfmt_section_align(/*@unused@*/ yasm_objfmt *objfmt, yasm_section *sect,
-                        unsigned long align, unsigned long line)
-{
-    /*@dependent@*/ /*@null@*/ elf_secthead *esd;
-    const yasm_intnum *old_align_intn;
-    unsigned long old_align = 0;
-
-    esd = yasm_section_get_data(sect, &elf_section_data);
-
-    if (!esd)
-       yasm_internal_error(N_("NULL elf section data in section_align"));
-
-    old_align_intn = elf_secthead_get_align(esd);
-    if (old_align_intn)
-       old_align = yasm_intnum_get_uint(old_align_intn);
-
-    if (align > old_align)
-       elf_secthead_set_align(esd, yasm_intnum_create_uint(align));
-}
-
 static yasm_symrec *
 elf_objfmt_extern_declare(yasm_objfmt *objfmt, const char *name, /*@unused@*/
                          /*@null@*/ yasm_valparamhead *objext_valparams,
@@ -1156,7 +1127,6 @@ yasm_objfmt_module yasm_elf_LTX_objfmt = {
     elf_objfmt_output,
     elf_objfmt_destroy,
     elf_objfmt_section_switch,
-    elf_objfmt_section_align,
     elf_objfmt_extern_declare,
     elf_objfmt_global_declare,
     elf_objfmt_common_declare,
@@ -1175,7 +1145,6 @@ yasm_objfmt_module yasm_elf32_LTX_objfmt = {
     elf_objfmt_output,
     elf_objfmt_destroy,
     elf_objfmt_section_switch,
-    elf_objfmt_section_align,
     elf_objfmt_extern_declare,
     elf_objfmt_global_declare,
     elf_objfmt_common_declare,
@@ -1194,7 +1163,6 @@ yasm_objfmt_module yasm_elf64_LTX_objfmt = {
     elf_objfmt_output,
     elf_objfmt_destroy,
     elf_objfmt_section_switch,
-    elf_objfmt_section_align,
     elf_objfmt_extern_declare,
     elf_objfmt_global_declare,
     elf_objfmt_common_declare,
index 4a018c047677c59951151f7fd96ac59f518e956b..7894bec195d5aeb4b4f71ed6314a3157960ffc0a 100644 (file)
@@ -95,12 +95,8 @@ elf_x86_amd64_write_secthead(unsigned char *bufp, elf_secthead *shead)
     YASM_WRITE_32_L(bufp, shead->link);
     YASM_WRITE_32_L(bufp, shead->info);
 
-    if (shead->align)
-        YASM_WRITE_64I_L(bufp, shead->align);
-    else
-        YASM_WRITE_64Z_L(bufp, 0);
+    YASM_WRITE_64Z_L(bufp, shead->align);
     YASM_WRITE_64Z_L(bufp, shead->entsize);
-    
 }
 
 static void
index 5da22aa1b61cdcdd8a69e4d182bb242843611483..dcf66ea2ca8c27f455e041bcf994b460509f3c1d 100644 (file)
@@ -98,10 +98,7 @@ elf_x86_x86_write_secthead(unsigned char *bufp, elf_secthead *shead)
     YASM_WRITE_32_L(bufp, shead->link);
     YASM_WRITE_32_L(bufp, shead->info);
 
-    if (shead->align)
-        YASM_WRITE_32I_L(bufp, shead->align);
-    else
-        YASM_WRITE_32_L(bufp, 0);
+    YASM_WRITE_32_L(bufp, shead->align);
     YASM_WRITE_32_L(bufp, shead->entsize);
 
 }
index 3e77556a513ff98093c47e6846b9afc510ba360c..bab607f18bd74c6dcbf18e49f9bc100c8fc74b2a 100644 (file)
@@ -531,7 +531,7 @@ elf_secthead_create(elf_strtab_entry        *name,
     esd->size = yasm_intnum_create_uint(size);
     esd->link = 0;
     esd->info = 0;
-    esd->align = NULL;
+    esd->align = 0;
     esd->entsize = 0;
     esd->index = 0;
 
@@ -547,7 +547,7 @@ elf_secthead_create(elf_strtab_entry        *name,
         if (!elf_march->symtab_entry_size || !elf_march->symtab_entry_align)
            yasm_internal_error(N_("unsupported ELF format"));
         esd->entsize = elf_march->symtab_entry_size;
-        esd->align = yasm_intnum_create_uint(elf_march->symtab_entry_align);
+        esd->align = elf_march->symtab_entry_align;
     }
 
     return esd;
@@ -559,9 +559,6 @@ elf_secthead_destroy(elf_secthead *shead)
     if (shead == NULL)
        yasm_internal_error(N_("shead is null"));
 
-    if (shead->align)
-       yasm_intnum_destroy(shead->align);
-
     yasm_xfree(shead);
 }
 
@@ -593,8 +590,7 @@ elf_secthead_print(void *data, FILE *f, int indent_level)
     fprintf(f, "%*ssize=0x%lx\n", indent_level, "",
            yasm_intnum_get_uint(sect->size));
     fprintf(f, "%*slink=0x%x\n", indent_level, "", sect->link);
-    fprintf(f, "%*salign=%ld\n", indent_level, "",
-           yasm_intnum_get_uint(sect->align));
+    fprintf(f, "%*salign=%lu\n", indent_level, "", sect->align);
     fprintf(f, "%*snreloc=%ld\n", indent_level, "", sect->nreloc);
 }
 
@@ -761,18 +757,15 @@ elf_secthead_get_index(elf_secthead *shead)
     return shead->index;
 }
 
-const yasm_intnum *
+unsigned long
 elf_secthead_get_align(const elf_secthead *shead)
 {
     return shead->align;
 }
 
-const yasm_intnum *
-elf_secthead_set_align(elf_secthead *shead, yasm_intnum *align)
+unsigned long
+elf_secthead_set_align(elf_secthead *shead, unsigned long align)
 {
-    if (shead->align != NULL)
-       yasm_intnum_destroy(shead->align);
-    
     return shead->align = align;
 }
 
@@ -829,7 +822,7 @@ elf_secthead_add_size(elf_secthead *shead, yasm_intnum *size)
 long
 elf_secthead_set_file_offset(elf_secthead *shead, long pos)
 {
-    unsigned long align = yasm_intnum_get_uint(shead->align);
+    unsigned long align = shead->align;
 
     if (align == 0 || align == 1) {
        shead->offset = (unsigned long)pos;
index fb6129a2b036f2ef6ad6f443826fee84f2e56b44..b33bbef2412b8d2e59250d8f35ce357258b38c56 100644 (file)
@@ -337,7 +337,7 @@ struct elf_secthead {
     yasm_intnum                *size;
     elf_section_index   link;
     elf_section_info    info;      /* see note ESD1 */
-    yasm_intnum        *align;
+    unsigned long       align;
     elf_size            entsize;
 
     yasm_symrec                *sym;
@@ -463,9 +463,8 @@ void elf_secthead_append_reloc(yasm_section *sect, elf_secthead *shead,
 elf_section_type elf_secthead_get_type(elf_secthead *shead);
 int elf_secthead_is_empty(elf_secthead *shead);
 struct yasm_symrec *elf_secthead_get_sym(elf_secthead *shead);
-const struct yasm_intnum *elf_secthead_get_align(const elf_secthead *shead);
-const struct yasm_intnum *elf_secthead_set_align(elf_secthead *shead,
-                                                struct yasm_intnum *align);
+unsigned long elf_secthead_get_align(const elf_secthead *shead);
+unsigned long elf_secthead_set_align(elf_secthead *shead, unsigned long align);
 elf_section_index elf_secthead_get_index(elf_secthead *shead);
 elf_section_info elf_secthead_set_info(elf_secthead *shead,
                                       elf_section_info info);
index 30f87c53c10f1e9a0e051194764683bb65178f7d..44d68ebe296c437aa8f8031f58e03785b021ec74 100644 (file)
@@ -66,7 +66,6 @@ typedef struct xdf_section_data {
     yasm_intnum *addr;     /* starting memory address */
     yasm_intnum *vaddr;            /* starting virtual address */
     long scnum;                    /* section number (0=first section) */
-    unsigned int align;            /* section alignment (0-4096) */
     enum {
        XDF_SECT_ABSOLUTE = 0x01,
        XDF_SECT_FLAT = 0x02,
@@ -453,7 +452,7 @@ xdf_objfmt_output_secthead(yasm_section *sect, /*@null@*/ void *d)
        YASM_WRITE_32_L(localbuf, 0);
        YASM_WRITE_32_L(localbuf, 0);
     }
-    YASM_WRITE_16_L(localbuf, xsd->align);     /* alignment */
+    YASM_WRITE_16_L(localbuf, yasm_section_get_align(sect)); /* alignment */
     YASM_WRITE_16_L(localbuf, xsd->flags);     /* flags */
     YASM_WRITE_32_L(localbuf, xsd->scnptr);    /* file ptr to data */
     YASM_WRITE_32_L(localbuf, xsd->size);      /* section size */
@@ -664,7 +663,7 @@ xdf_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,
     int isnew;
     /*@dependent@*/ /*@null@*/ const yasm_intnum *absaddr = NULL;
     /*@dependent@*/ /*@null@*/ const yasm_intnum *vaddr = NULL;
-    unsigned int addralign = 0;
+    unsigned long align = 0;
     unsigned long flags = 0;
     int flags_override = 0;
     char *sectname;
@@ -709,29 +708,25 @@ xdf_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,
                return NULL;
            }
        } else if (yasm__strcasecmp(vp->val, "align") == 0 && vp->param) {
-           /*@dependent@*/ /*@null@*/ const yasm_intnum *align;
-           unsigned long bitcnt;
+           /*@dependent@*/ /*@null@*/ const yasm_intnum *align_expr;
 
-           align = yasm_expr_get_intnum(&vp->param, NULL);
-           if (!align) {
+           align_expr = yasm_expr_get_intnum(&vp->param, NULL);
+           if (!align_expr) {
                yasm__error(line, N_("argument to `%s' is not a power of two"),
                            vp->val);
                return NULL;
            }
-           addralign = yasm_intnum_get_uint(align);
+           align = yasm_intnum_get_uint(align_expr);
 
-           /* Check to see if alignment is a power of two.
-            * This can be checked by seeing if only one bit is set.
-            */
-           BitCount(bitcnt, addralign);
-           if (bitcnt > 1) {
+            /* Alignments must be a power of two. */
+            if ((align & (align - 1)) != 0) {
                yasm__error(line, N_("argument to `%s' is not a power of two"),
                            vp->val);
                return NULL;
            }
 
            /* Check to see if alignment is supported size */
-           if (addralign > 4096) {
+           if (align > 4096) {
                yasm__error(line,
                            N_("XDF does not support alignments > 4096"));
                return NULL;
@@ -741,7 +736,7 @@ xdf_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,
                          N_("Unrecognized qualifier `%s'"), vp->val);
     }
 
-    retval = yasm_object_get_general(objfmt_xdf->object, sectname, 0, 1,
+    retval = yasm_object_get_general(objfmt_xdf->object, sectname, 0, align, 1,
                                     resonly, &isnew, line);
 
     if (isnew) {
@@ -750,7 +745,6 @@ xdf_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,
 
        data = yasm_xmalloc(sizeof(xdf_section_data));
        data->scnum = objfmt_xdf->parse_scnum++;
-       data->align = addralign;
        data->flags = flags;
        if (absaddr)
            data->addr = yasm_intnum_copy(absaddr);
@@ -776,24 +770,6 @@ xdf_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams,
                      N_("section flags ignored on section redeclaration"));
     return retval;
 }
-static void
-xdf_objfmt_section_align(yasm_objfmt *objfmt, yasm_section *sect,
-                        unsigned long align, unsigned long line)
-{
-    /*@dependent@*/ /*@null@*/ xdf_section_data *xsd;
-
-    xsd = yasm_section_get_data(sect, &xdf_section_data_cb);
-    if (!xsd)
-       yasm_internal_error(N_("NULL xdf section data in section_align"));
-
-    /* Check to see if alignment is supported size */
-    if (align > 4096) {
-       yasm__error(line, N_("XDF does not support alignments > 4096"));
-       return;
-    }
-
-    xsd->align = align;
-}
 
 static void
 xdf_section_data_destroy(void *data)
@@ -909,7 +885,6 @@ yasm_objfmt_module yasm_xdf_LTX_objfmt = {
     xdf_objfmt_output,
     xdf_objfmt_destroy,
     xdf_objfmt_section_switch,
-    xdf_objfmt_section_align,
     xdf_objfmt_extern_declare,
     xdf_objfmt_global_declare,
     xdf_objfmt_common_declare,
index 0370a7d8d4e8d0887904e55fca26a1fd739e87ab..2a9d8b3ba97205b41cd37ca17f18e603ebe2d72d 100644 (file)
@@ -850,9 +850,9 @@ gas_parser_align(yasm_parser_gas *parser_gas, yasm_valparamhead *valparams,
 
        /* Alignments must be a power of two. */
        if ((boundint & (boundint - 1)) == 0) {
-           yasm_objfmt_section_align(parser_gas->objfmt,
-                                     parser_gas->cur_section, boundint,
-                                     cur_line);
+           if (boundint > yasm_section_get_align(parser_gas->cur_section))
+               yasm_section_set_align(parser_gas->cur_section, boundint,
+                                      cur_line);
        }
     }