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