/*@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)
} 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)
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,
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)
{
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,
}
}
+static void
+dbg_objfmt_section_align(yasm_objfmt *objfmt, yasm_section *sect,
+ unsigned long align, unsigned long line)
+{
+ yasm_objfmt_dbg *objfmt_dbg = (yasm_objfmt_dbg *)objfmt;
+ fprintf(objfmt_dbg->dbgfile, "section_align(\"%s\", %lu, %lu)\n",
+ yasm_section_get_name(sect), align, line);
+}
+
static yasm_symrec *
dbg_objfmt_extern_declare(yasm_objfmt *objfmt, const char *name,
/*@unused@*/ /*@null@*/
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,
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;
+
+ esd = yasm_section_get_data(sect, &elf_section_data);
+
+ if (!esd)
+ yasm_internal_error(N_("NULL elf section data in section_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,
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,
yasm_expr_int(yasm_intnum_create_uint(1)),
yasm_expr_expr(boundval), cur_line);
+ /* If .align is the first bytecode in the section, it's really specifying
+ * section alignment.
+ */
+ if (parser_gas->prev_bc
+ == yasm_section_bcs_first(parser_gas->cur_section)) {
+ yasm_intnum *boundintn = yasm_expr_get_intnum(&boundval, NULL);
+ unsigned long boundint;
+ if (!boundintn) {
+ yasm__error(cur_line, N_("section alignment not constnat"));
+ return NULL;
+ }
+ boundint = yasm_intnum_get_uint(boundintn);
+
+ /* Alignments must be a power of two. */
+ if ((boundint & (boundint - 1)) != 0) {
+ yasm__error(cur_line,
+ N_("section alignment is not a power of two"));
+ return NULL;
+ }
+
+ yasm_objfmt_section_align(parser_gas->objfmt, parser_gas->cur_section,
+ boundint, cur_line);
+ return NULL;
+ }
+
return yasm_bc_create_align(boundval, fillval, maxskipval,
parser_gas->code_section ?
yasm_arch_get_fill(parser_gas->arch) : NULL,
EXTRA_DIST += modules/parsers/gas/tests/gas-semi.asm
EXTRA_DIST += modules/parsers/gas/tests/gas-semi.errwarn
EXTRA_DIST += modules/parsers/gas/tests/gas-semi.hex
+EXTRA_DIST += modules/parsers/gas/tests/gassectalign.asm
+EXTRA_DIST += modules/parsers/gas/tests/gassectalign.errwarn
+EXTRA_DIST += modules/parsers/gas/tests/gassectalign.hex
EXTRA_DIST += modules/parsers/gas/tests/jmpcall.asm
EXTRA_DIST += modules/parsers/gas/tests/jmpcall.errwarn
EXTRA_DIST += modules/parsers/gas/tests/jmpcall.hex
--- /dev/null
+.text
+.align 8
+.data
+.align 16
+.bss
+.align 32
--- /dev/null
+7f
+45
+4c
+46
+01
+01
+01
+00
+00
+00
+00
+00
+00
+00
+00
+00
+01
+00
+03
+00
+01
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+c0
+00
+00
+00
+00
+00
+00
+00
+34
+00
+00
+00
+00
+00
+28
+00
+07
+00
+01
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+2e
+74
+65
+78
+74
+00
+2e
+64
+61
+74
+61
+00
+2e
+62
+73
+73
+00
+2e
+73
+74
+72
+74
+61
+62
+00
+2e
+73
+79
+6d
+74
+61
+62
+00
+2e
+73
+68
+73
+74
+72
+74
+61
+62
+00
+00
+2d
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+01
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+04
+00
+f1
+ff
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+03
+00
+06
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+03
+00
+05
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+03
+00
+04
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+22
+00
+00
+00
+03
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+40
+00
+00
+00
+2c
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+12
+00
+00
+00
+03
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+6c
+00
+00
+00
+03
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+1a
+00
+00
+00
+02
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+70
+00
+00
+00
+50
+00
+00
+00
+02
+00
+00
+00
+05
+00
+00
+00
+04
+00
+00
+00
+10
+00
+00
+00
+01
+00
+00
+00
+01
+00
+00
+00
+06
+00
+00
+00
+00
+00
+00
+00
+38
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+08
+00
+00
+00
+00
+00
+00
+00
+07
+00
+00
+00
+01
+00
+00
+00
+03
+00
+00
+00
+00
+00
+00
+00
+40
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+10
+00
+00
+00
+00
+00
+00
+00
+0d
+00
+00
+00
+08
+00
+00
+00
+03
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+20
+00
+00
+00
+00
+00
+00
+00