Move section alignment to libyasm, refactoring it from individual object

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
0.5.0rc2
Peter Johnson 19 years ago
parent 94265938fd
commit 0ea57bf7bf
  1. 18
      libyasm/objfmt.h
  2. 20
      libyasm/section.c
  3. 19
      libyasm/section.h
  4. 6
      modules/dbgfmts/stabs/stabs-dbgfmt.c
  5. 92
      modules/objfmts/bin/bin-objfmt.c
  6. 105
      modules/objfmts/coff/coff-objfmt.c
  7. 3
      modules/objfmts/dbg/dbg-objfmt.c
  8. 44
      modules/objfmts/elf/elf-objfmt.c
  9. 6
      modules/objfmts/elf/elf-x86-amd64.c
  10. 5
      modules/objfmts/elf/elf-x86-x86.c
  11. 21
      modules/objfmts/elf/elf.c
  12. 7
      modules/objfmts/elf/elf.h
  13. 45
      modules/objfmts/xdf/xdf-objfmt.c
  14. 6
      modules/parsers/gas/gas-bison.y

@ -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)

@ -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)
{

@ -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

@ -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)

@ -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,

@ -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,

@ -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,

@ -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,

@ -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

@ -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);
}

@ -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;

@ -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);

@ -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,

@ -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);
}
}

Loading…
Cancel
Save