diff --git a/libyasm/objfmt.h b/libyasm/objfmt.h index 34cf80f0..0bdd6483 100644 --- a/libyasm/objfmt.h +++ b/libyasm/objfmt.h @@ -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) diff --git a/libyasm/section.c b/libyasm/section.c index d691718a..89a4bc3a 100644 --- a/libyasm/section.c +++ b/libyasm/section.c @@ -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) { diff --git a/libyasm/section.h b/libyasm/section.h index 6634da8f..c4132186 100644 --- a/libyasm/section.h +++ b/libyasm/section.h @@ -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 diff --git a/modules/dbgfmts/stabs/stabs-dbgfmt.c b/modules/dbgfmts/stabs/stabs-dbgfmt.c index 578e1261..07794791 100644 --- a/modules/dbgfmts/stabs/stabs-dbgfmt.c +++ b/modules/dbgfmts/stabs/stabs-dbgfmt.c @@ -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) diff --git a/modules/objfmts/bin/bin-objfmt.c b/modules/objfmts/bin/bin-objfmt.c index 27fafb93..fe5cdc78 100644 --- a/modules/objfmts/bin/bin-objfmt.c +++ b/modules/objfmts/bin/bin-objfmt.c @@ -35,14 +35,6 @@ #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, diff --git a/modules/objfmts/coff/coff-objfmt.c b/modules/objfmts/coff/coff-objfmt.c index fd18e3a3..af848b5e 100644 --- a/modules/objfmts/coff/coff-objfmt.c +++ b/modules/objfmts/coff/coff-objfmt.c @@ -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<>= 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<win32) { flags |= COFF_STYP_READ | COFF_STYP_WRITE; if (objfmt_coff->machine == COFF_MACHINE_AMD64) - flags |= 5<win32) - flags |= COFF_STYP_EXECUTE | COFF_STYP_READ | - (5<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<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<win32 && strcmp(sectname, ".xdata") == 0) { - flags = COFF_STYP_DATA | COFF_STYP_READ - | 4<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<>= 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<>= 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, diff --git a/modules/objfmts/dbg/dbg-objfmt.c b/modules/objfmts/dbg/dbg-objfmt.c index 3b2b7fcc..2b8b83a5 100644 --- a/modules/objfmts/dbg/dbg-objfmt.c +++ b/modules/objfmts/dbg/dbg-objfmt.c @@ -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, diff --git a/modules/objfmts/elf/elf-objfmt.c b/modules/objfmts/elf/elf-objfmt.c index 4d14b76f..8fd9f81c 100644 --- a/modules/objfmts/elf/elf-objfmt.c +++ b/modules/objfmts/elf/elf-objfmt.c @@ -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, diff --git a/modules/objfmts/elf/elf-x86-amd64.c b/modules/objfmts/elf/elf-x86-amd64.c index 4a018c04..7894bec1 100644 --- a/modules/objfmts/elf/elf-x86-amd64.c +++ b/modules/objfmts/elf/elf-x86-amd64.c @@ -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 diff --git a/modules/objfmts/elf/elf-x86-x86.c b/modules/objfmts/elf/elf-x86-x86.c index 5da22aa1..dcf66ea2 100644 --- a/modules/objfmts/elf/elf-x86-x86.c +++ b/modules/objfmts/elf/elf-x86-x86.c @@ -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); } diff --git a/modules/objfmts/elf/elf.c b/modules/objfmts/elf/elf.c index 3e77556a..bab607f1 100644 --- a/modules/objfmts/elf/elf.c +++ b/modules/objfmts/elf/elf.c @@ -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; diff --git a/modules/objfmts/elf/elf.h b/modules/objfmts/elf/elf.h index fb6129a2..b33bbef2 100644 --- a/modules/objfmts/elf/elf.h +++ b/modules/objfmts/elf/elf.h @@ -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); diff --git a/modules/objfmts/xdf/xdf-objfmt.c b/modules/objfmts/xdf/xdf-objfmt.c index 30f87c53..44d68ebe 100644 --- a/modules/objfmts/xdf/xdf-objfmt.c +++ b/modules/objfmts/xdf/xdf-objfmt.c @@ -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, diff --git a/modules/parsers/gas/gas-bison.y b/modules/parsers/gas/gas-bison.y index 0370a7d8..2a9d8b3b 100644 --- a/modules/parsers/gas/gas-bison.y +++ b/modules/parsers/gas/gas-bison.y @@ -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); } }