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
/*@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.
*/
(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
#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)
/*@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) */
/*@-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;
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.
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)
{
* \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
*/
/*@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.
/*@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
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)
}
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)
#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 */
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
* 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;
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);
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);
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
/* 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) {
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"));
} 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,
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[] = {
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,
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))
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;
int flags_override = 0;
char *sectname;
int resonly = 0;
+ unsigned long align = 0;
static const struct {
const char *name;
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) {
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;
;
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);
}
/* 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
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);
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)
{
/* 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)
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,
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,
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,
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(
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,
{
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);
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)
{
}
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) {
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);
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,
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,
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,
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,
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,
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
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);
}
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;
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;
if (shead == NULL)
yasm_internal_error(N_("shead is null"));
- if (shead->align)
- yasm_intnum_destroy(shead->align);
-
yasm_xfree(shead);
}
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);
}
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;
}
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;
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;
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);
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,
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 */
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;
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;
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) {
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);
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)
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,
/* 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);
}
}