typedef struct bytecode_reserve {
/*@only@*/ /*@null@*/ yasm_expr *numitems; /* number of items to reserve */
- unsigned char itemsize; /* size of each item (in bytes) */
+ unsigned int itemsize; /* size of each item (in bytes) */
} bytecode_reserve;
static void bc_reserve_destroy(void *contents);
fprintf(f, "%*s_Reserve_\n", indent_level, "");
fprintf(f, "%*sNum Items=", indent_level, "");
yasm_expr_print(reserve->numitems, f);
- fprintf(f, "\n%*sItem Size=%u\n", indent_level, "",
- (unsigned int)reserve->itemsize);
+ fprintf(f, "\n%*sItem Size=%u\n", indent_level, "", reserve->itemsize);
}
static void
/*@-mustfree@*/
reserve->numitems = numitems;
/*@=mustfree@*/
- reserve->itemsize = (unsigned char)itemsize;
+ reserve->itemsize = itemsize;
return yasm_bc_create_common(&bc_reserve_callback, reserve, line);
}
+
+const yasm_expr *
+yasm_bc_reserve_numitems(yasm_bytecode *bc, unsigned int *itemsize)
+{
+ bytecode_reserve *reserve;
+
+ if (bc->callback != &bc_reserve_callback)
+ return NULL;
+
+ reserve = (bytecode_reserve *)bc->contents;
+ *itemsize = reserve->itemsize;
+ return reserve->numitems;
+}
}
return 0;
}
+
+const yasm_expr *
+yasm_bc_get_multiple_expr(const yasm_bytecode *bc)
+{
+ return bc->multiple;
+}
(/*@only@*/ yasm_expr *numitems, unsigned int itemsize,
unsigned long line);
+/** Get the number of items and itemsize for a reserve bytecode. If bc
+ * is not a reserve bytecode, returns NULL.
+ * \param bc bytecode
+ * \param itemsize reserved size (in bytes) for each item (returned)
+ * \return NULL if bc is not a reserve bytecode, otherwise an expression
+ * for the number of items to reserve.
+ */
+/*@null@*/ const yasm_expr *yasm_bc_reserve_numitems
+ (yasm_bytecode *bc, /*@out@*/ unsigned int *itemsize);
+
/** Create a bytecode that includes a binary file verbatim.
* \param filename path to binary file (kept, do not free)
* \param start starting location in file (in bytes) to read data from
int yasm_bc_get_multiple(yasm_bytecode *bc, /*@out@*/ long *multiple,
int calc_bc_dist);
+/** Get the bytecode multiple value as an expression.
+ * \param bc bytecode
+ * \return Bytecode multiple, NULL if =1.
+ */
+const yasm_expr *yasm_bc_get_multiple_expr(const yasm_bytecode *bc);
+
/** Create a new data value from an expression.
* \param expn expression
* \return Newly allocated data value.
/*@dependent@*/ yasm_object *object; /* Pointer to parent object */
- enum { SECTION_GENERAL, SECTION_ABSOLUTE } type;
-
- union {
- /* SECTION_GENERAL data */
- struct {
- /*@owned@*/ char *name; /* strdup()'ed name (given by user) */
- } general;
- /* SECTION_ABSOLUTE data */
- struct {
- /* Internally created first symrec in section. Used by
- * yasm_expr__level_tree during absolute reference expansion.
- */
- /*@dependent@*/ yasm_symrec *first;
- } absolute;
- } data;
+ /*@owned@*/ char *name; /* strdup()'ed name (given by user) */
/* associated data; NULL if none */
/*@null@*/ /*@only@*/ yasm__assoc_data *assoc_data;
* that name.
*/
STAILQ_FOREACH(s, &object->sections, link) {
- if (s->type == SECTION_GENERAL &&
- strcmp(s->data.general.name, name) == 0) {
+ if (strcmp(s->name, name) == 0) {
*isnew = 0;
return s;
}
STAILQ_INSERT_TAIL(&object->sections, s, link);
s->object = object;
- s->type = SECTION_GENERAL;
- s->data.general.name = yasm__xstrdup(name);
+ s->name = yasm__xstrdup(name);
s->assoc_data = NULL;
if (start)
s->start = start;
}
/*@=onlytrans@*/
-/*@-onlytrans@*/
-yasm_section *
-yasm_object_create_absolute(yasm_object *object, yasm_expr *start,
- unsigned long line)
-{
- yasm_section *s;
- yasm_bytecode *bc;
-
- s = yasm_xcalloc(1, sizeof(yasm_section));
- STAILQ_INSERT_TAIL(&object->sections, s, link);
-
- s->object = object;
- s->type = SECTION_ABSOLUTE;
- s->start = start;
-
- /* Initialize bytecodes with one empty bytecode (acts as "prior" for first
- * real bytecode in section.
- */
- STAILQ_INIT(&s->bcs);
- bc = yasm_bc_create_common(NULL, NULL, 0);
- bc->section = s;
- bc->offset = 0;
- STAILQ_INSERT_TAIL(&s->bcs, bc, link);
-
- /* Initialize relocs */
- STAILQ_INIT(&s->relocs);
- s->destroy_reloc = NULL;
-
- s->data.absolute.first =
- yasm_symtab_define_label(object->symtab, ".absstart", bc, 0, 0);
-
- s->code = 0;
- s->res_only = 1;
- s->def = 0;
-
- return s;
-}
-/*@=onlytrans@*/
-
int
yasm_object_directive(yasm_object *object, const char *name,
const char *parser, yasm_valparamhead *valparams,
object->src_filename = yasm__xstrdup(src_filename);
}
-int
-yasm_section_is_absolute(yasm_section *sect)
-{
- return (sect->type == SECTION_ABSOLUTE);
-}
-
int
yasm_section_is_code(yasm_section *sect)
{
yasm_section *cur;
STAILQ_FOREACH(cur, &object->sections, link) {
- if (cur->type == SECTION_GENERAL &&
- strcmp(cur->data.general.name, name) == 0)
+ if (strcmp(cur->name, name) == 0)
return cur;
}
return NULL;
const char *
yasm_section_get_name(const yasm_section *sect)
{
- if (sect->type == SECTION_GENERAL)
- return sect->data.general.name;
- return NULL;
-}
-
-yasm_symrec *
-yasm_section_abs_get_sym(const yasm_section *sect)
-{
- if (sect->type == SECTION_ABSOLUTE)
- return sect->data.absolute.first;
- return NULL;
+ return sect->name;
}
void
if (!sect)
return;
- if (sect->type == SECTION_GENERAL) {
- yasm_xfree(sect->data.general.name);
- }
+ yasm_xfree(sect->name);
yasm__assoc_data_destroy(sect->assoc_data);
yasm_expr_destroy(sect->start);
return;
}
- fprintf(f, "%*stype=", indent_level, "");
- switch (sect->type) {
- case SECTION_GENERAL:
- fprintf(f, "general\n%*sname=%s\n", indent_level, "",
- sect->data.general.name);
- break;
- case SECTION_ABSOLUTE:
- fprintf(f, "absolute\n");
- break;
- }
-
+ fprintf(f, "%*sname=%s\n", indent_level, "", sect->name);
fprintf(f, "%*sstart=", indent_level, "");
yasm_expr_print(sect->start, f);
fprintf(f, "\n");
/*@owned@*/ yasm_objfmt *objfmt; /**< Object format */
/*@owned@*/ yasm_dbgfmt *dbgfmt; /**< Debug format */
- /** Currently active section. Used by some directives. */
- /*@dependent@*/ yasm_section *cur_section;
+ /** Currently active section. Used by some directives. NULL if no
+ * section active.
+ */
+ /*@dependent@*/ /*@null@*/ yasm_section *cur_section;
#ifdef YASM_LIB_INTERNAL
/** Linked list of sections. */
/*@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.
- * \param object object
- * \param start starting address (expression)
- * \param line virtual line of section declaration
- * \return New section.
- */
-/*@dependent@*/ yasm_section *yasm_object_create_absolute
- (yasm_object *object, /*@keep@*/ yasm_expr *start, unsigned long line);
-
/** Handle a directive. Passed down to object format, debug format, or
* architecture as appropriate.
* \param object object
*/
void yasm_object_optimize(yasm_object *object, yasm_errwarns *errwarns);
-/** Determine if a section is absolute or general.
- * \param sect section
- * \return Nonzero if section is absolute.
- */
-int yasm_section_is_absolute(yasm_section *sect);
-
/** Determine if a section is flagged to contain code.
* \param sect section
* \return Nonzero if section is flagged to contain code.
/** Get name of a section.
* \param sect section
- * \return Section name, or NULL if section is absolute.
- */
-/*@observer@*/ /*@null@*/ const char *yasm_section_get_name
- (const yasm_section *sect);
-
-/** Get starting symbol of an absolute section.
- * \param sect section
- * \return Starting symrec, or NULL if section is not absolute.
+ * \return Section name.
*/
-/*@dependent@*/ /*@null@*/ yasm_symrec *yasm_section_abs_get_sym
- (const yasm_section *sect);
+/*@observer@*/ const char *yasm_section_get_name(const yasm_section *sect);
/** Change starting address of a section.
* \param sect section
/** Get starting address of a section.
* \param sect section
- * \return Starting address (may be a complex expression if section is
- * absolute).
+ * \return Starting address.
*/
/*@observer@*/ const yasm_expr *yasm_section_get_start
(const yasm_section *sect);
symtab_parser_finalize_checksym(yasm_symrec *sym, /*@null@*/ void *d)
{
symtab_finalize_info *info = (symtab_finalize_info *)d;
- yasm_section *sect;
/* error if a symbol is used but never defined or extern/common declared */
if ((sym->status & YASM_SYM_USED) && !(sym->status & YASM_SYM_DEFINED) &&
}
}
- /* Change labels in absolute sections into EQUs with value
- * absolute start expr + (label bc - first bc in abs section).
- * Don't worry about possible circular references because that will get
- * caught in EQU expansion.
- */
- if (sym->type == SYM_LABEL && sym->value.precbc
- && (sect = yasm_bc_get_section(sym->value.precbc))
- && yasm_section_is_absolute(sect)) {
- sym->type = SYM_EQU;
- sym->value.expn = yasm_expr_create_tree(
- yasm_expr_create(YASM_EXPR_SUB,
- yasm_expr_precbc(sym->value.precbc),
- yasm_expr_precbc(yasm_section_bcs_first(sect)),
- sym->def_line),
- YASM_EXPR_ADD,
- yasm_expr_copy(yasm_section_get_start(sect)),
- sym->def_line);
- sym->status |= YASM_SYM_VALUED;
- }
-
return 0;
}
loc->line = yasm_intnum_get_uint(intn);
/* Generate new section data if it doesn't already exist */
+ if (!object->cur_section) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("[%s] can only be used inside of a section"), "loc");
+ yasm_xfree(loc);
+ return;
+ }
dsd = yasm_section_get_data(object->cur_section,
&yasm_dwarf2__section_data_cb);
if (!dsd) {
/*@null@*/ coff_objfmt_output_info *info = (coff_objfmt_output_info *)d;
/*@dependent@*/ /*@null@*/ coff_section_data *csd;
- /* Skip absolute sections */
- if (yasm_section_is_absolute(sect))
- return 0;
-
assert(info != NULL);
csd = yasm_section_get_data(sect, &coff_section_data_cb);
if (!csd) {
/*@null@*/ coff_objfmt_output_info *info = (coff_objfmt_output_info *)d;
/*@dependent@*/ /*@null@*/ coff_section_data *csd;
- /* Don't output absolute sections */
- if (yasm_section_is_absolute(sect))
- return 0;
-
assert(info != NULL);
csd = yasm_section_get_data(sect, &coff_section_data_cb);
assert(csd != NULL);
coff_reloc *reloc;
unsigned char *localbuf;
- /* Don't output absolute sections into the section table */
- if (yasm_section_is_absolute(sect))
- return 0;
-
assert(info != NULL);
csd = yasm_section_get_data(sect, &coff_section_data_cb);
assert(csd != NULL);
const char *name;
size_t len;
- /* Don't output absolute sections into the section table */
- if (yasm_section_is_absolute(sect))
- return 0;
-
/* Add to strtab if in win32 format and name > 8 chars */
if (!info->objfmt_coff->win32)
return 0;
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))
- return 0;
-
assert(info != NULL);
objfmt_coff = info->objfmt_coff;
csd = yasm_section_get_data(sect, &coff_section_data_cb);
nreloc = csectd->nreloc;
if (COFF_SET_VMA)
value = csectd->addr;
- } else if (yasm_section_is_absolute(sect)) {
- yasm_expr *abs_start;
-
- abs_start = yasm_expr_copy(yasm_section_get_start(sect));
- intn = yasm_expr_get_intnum(&abs_start, 1);
- if (!intn) {
- yasm_error_set(YASM_ERROR_NOT_CONSTANT,
- N_("absolute section start not an integer expression"));
- yasm_errwarn_propagate(info->errwarns,
- abs_start->line);
- } else
- value = yasm_intnum_get_uint(intn);
- yasm_expr_destroy(abs_start);
-
- scnum = 0xffff; /* -1 = absolute symbol */
} else
yasm_internal_error(N_("didn't understand section"));
if (precbc)
* XXX: There should be a better way to do this.
*/
static yasm_symrec *
-get_curpos(yasm_object *object, unsigned long line)
+get_curpos(yasm_object *object, const char *dirname, unsigned long line)
{
+ if (!object->cur_section) {
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("[%s] can only be used inside of a section"),
+ dirname);
+ return NULL;
+ }
return yasm_symtab_define_curpos(object->symtab, "$",
yasm_section_bcs_last(object->cur_section), line);
}
/* Generate a PUSH_NONVOL unwind code. */
code = yasm_xmalloc(sizeof(coff_unwind_code));
code->proc = objfmt_coff->unwind->proc;
- code->loc = get_curpos(object, line);
+ code->loc = get_curpos(object, "PUSHREG", line);
code->opcode = UWOP_PUSH_NONVOL;
code->info = (unsigned int)(*reg & 0xF);
yasm_value_initialize(&code->off, NULL, 0);
/* Generate a SET_FPREG unwind code */
code = yasm_xmalloc(sizeof(coff_unwind_code));
code->proc = objfmt_coff->unwind->proc;
- code->loc = get_curpos(object, line);
+ code->loc = get_curpos(object, "SETFRAME", line);
code->opcode = UWOP_SET_FPREG;
code->info = (unsigned int)(*reg & 0xF);
yasm_value_initialize(&code->off, yasm_expr_copy(off), 8);
*/
code = yasm_xmalloc(sizeof(coff_unwind_code));
code->proc = objfmt_coff->unwind->proc;
- code->loc = get_curpos(object, line);
+ code->loc = get_curpos(object, "ALLOCSTACK", line);
code->opcode = UWOP_ALLOC_SMALL;
code->info = 0;
yasm_value_initialize(&code->off, vp->param, 7);
*/
code = yasm_xmalloc(sizeof(coff_unwind_code));
code->proc = objfmt_coff->unwind->proc;
- code->loc = get_curpos(object, line);
+ code->loc = get_curpos(object, name, line);
code->opcode = op;
code->info = (unsigned int)(*reg & 0xF);
yasm_value_initialize(&code->off, vp->param, 16);
*/
code = yasm_xmalloc(sizeof(coff_unwind_code));
code->proc = objfmt_coff->unwind->proc;
- code->loc = get_curpos(object, line);
+ code->loc = get_curpos(object, "PUSHFRAME", line);
code->opcode = UWOP_PUSH_MACHFRAME;
code->info = vp && (vp->val || vp->param);
yasm_value_initialize(&code->off, NULL, 0);
return;
objfmt_coff->done_prolog = line;
- objfmt_coff->unwind->prolog = get_curpos(object, line);
+ objfmt_coff->unwind->prolog = get_curpos(object, "ENDPROLOG", line);
}
static void
proc_sym = objfmt_coff->unwind->proc;
- curpos = get_curpos(object, line);
+ curpos = get_curpos(object, "ENDPROC_FRAME", line);
/*
* Add unwind info to end of .xdata section.
/* Locals (except when debugging) do not need to be
* in the symbol table, unless they're a section.
*/
- if (sect && !yasm_section_is_absolute(sect) &&
+ if (sect &&
strcmp(yasm_symrec_get_name(sym), yasm_section_get_name(sect))==0)
is_sect = 1;
#if 0
elf_strtab_entry *name;
shead = yasm_section_get_data(sect, &elf_section_data);
- if (yasm_section_is_absolute(sect) || shead)
- return 0; /* only create new secthead if missing and non-absolute */
+ if (shead)
+ return 0; /* only create new secthead if missing */
sectname = yasm_section_get_name(sect);
name = elf_strtab_append_str(info->objfmt_elf->shstrtab, sectname);
char *relname;
const char *sectname;
- /* Don't output absolute sections into the section table */
- if (yasm_section_is_absolute(sect))
- return 0;
-
if (info == NULL)
yasm_internal_error("null info struct");
shead = yasm_section_get_data(sect, &elf_section_data);
/*@null@*/ elf_objfmt_output_info *info = (elf_objfmt_output_info *)d;
/*@dependent@*/ /*@null@*/ elf_secthead *shead;
- /* Don't output absolute sections into the section table */
- if (yasm_section_is_absolute(sect))
- return 0;
-
if (info == NULL)
yasm_internal_error("null info struct");
shead = yasm_section_get_data(sect, &elf_section_data);
YASM_WRITE_8(bufp, ELF64_ST_INFO(entry->bind, entry->type));
YASM_WRITE_8(bufp, ELF64_ST_OTHER(entry->vis));
if (entry->sect) {
- if (yasm_section_is_absolute(entry->sect)) {
- YASM_WRITE_16_L(bufp, SHN_ABS);
- } else {
- elf_secthead *shead = yasm_section_get_data(entry->sect,
- &elf_section_data);
- if (!shead)
- yasm_internal_error(
- N_("symbol references section without data"));
- YASM_WRITE_16_L(bufp, shead->index);
- }
+ elf_secthead *shead =
+ yasm_section_get_data(entry->sect, &elf_section_data);
+ if (!shead)
+ yasm_internal_error(N_("symbol references section without data"));
+ YASM_WRITE_16_L(bufp, shead->index);
} else {
YASM_WRITE_16_L(bufp, entry->index);
}
YASM_WRITE_8(bufp, ELF32_ST_INFO(entry->bind, entry->type));
YASM_WRITE_8(bufp, ELF32_ST_OTHER(entry->vis));
if (entry->sect) {
- if (yasm_section_is_absolute(entry->sect)) {
- YASM_WRITE_16_L(bufp, SHN_ABS);
- } else {
- elf_secthead *shead = yasm_section_get_data(entry->sect,
- &elf_section_data);
- if (!shead)
- yasm_internal_error(
- N_("symbol references section without data"));
- YASM_WRITE_16_L(bufp, shead->index);
- }
+ elf_secthead *shead =
+ yasm_section_get_data(entry->sect, &elf_section_data);
+ if (!shead)
+ yasm_internal_error(N_("symbol references section without data"));
+ YASM_WRITE_16_L(bufp, shead->index);
} else {
YASM_WRITE_16_L(bufp, entry->index);
}
(macho_objfmt_output_info *) d;
/*@dependent@ *//*@null@ */ macho_section_data *msd;
- /* FIXME: Don't output absolute sections into the section table */
- if (yasm_section_is_absolute(sect))
- return 0;
-
assert(info != NULL);
msd = yasm_section_get_data(sect, &macho_section_data_cb);
assert(msd != NULL);
/*@dependent@*/ /*@null@*/ macho_section_data *msd;
macho_reloc *reloc;
- /* FIXME: Don't output absolute sections into the section table */
- if (yasm_section_is_absolute(sect))
- return 0;
-
reloc = (macho_reloc *)yasm_section_relocs_first(sect);
while (reloc) {
unsigned char *localbuf = info->buf;
/*@dependent@*/ /*@null@*/ macho_section_data *msd;
unsigned char *localbuf;
- /* Don't output absolute sections into the section table */
- if (yasm_section_is_absolute(sect))
- return 0;
-
assert(info != NULL);
objfmt_macho = info->objfmt_macho;
msd = yasm_section_get_data(sect, &macho_section_data_cb);
if (msd) {
scnum = msd->scnum;
n_type = N_SECT;
- } else {
- if (yasm_section_is_absolute(sect)) {
- yasm_expr *abs_start;
-
- abs_start =
- yasm_expr_copy(yasm_section_get_start(sect));
- intn = yasm_expr_get_intnum(&abs_start, 1);
- if (!intn) {
- yasm_error_set(YASM_ERROR_NOT_CONSTANT,
- N_("absolute section start not an integer expression"));
- yasm_errwarn_propagate(info->errwarns,
- abs_start->line);
- } else
- value = yasm_intnum_get_uint(intn);
- yasm_expr_destroy(abs_start);
-
- scnum = -2; /* -2 = absolute symbol */
- } else
- yasm_internal_error(N_("didn't understand section"));
- }
+ } else
+ yasm_internal_error(N_("didn't understand section"));
if (precbc)
value += yasm_bc_next_offset(precbc);
/* all values are subject to correction: base offset is first
(macho_objfmt_output_info *) d;
/*@dependent@ *//*@null@ */ macho_section_data *msd;
- /* FIXME: Don't output absolute sections into the section table */
- if (yasm_section_is_absolute(sect))
- return 0;
-
assert(info != NULL);
msd = yasm_section_get_data(sect, &macho_section_data_cb);
assert(msd != NULL);
/*@dependent@*/ /*@null@*/ rdf_section_data *rsd;
unsigned long size;
- /* Don't output absolute sections */
- if (yasm_section_is_absolute(sect))
- return 0;
-
assert(info != NULL);
rsd = yasm_section_get_data(sect, &rdf_section_data_cb);
assert(rsd != NULL);
/*@dependent@*/ /*@null@*/ rdf_section_data *rsd;
rdf_reloc *reloc;
- /* Don't output absolute sections */
- if (yasm_section_is_absolute(sect))
- return 0;
-
assert(info != NULL);
rsd = yasm_section_get_data(sect, &rdf_section_data_cb);
assert(rsd != NULL);
/*@dependent@*/ /*@null@*/ rdf_section_data *rsd;
unsigned char *localbuf;
- /* Don't output absolute sections */
- if (yasm_section_is_absolute(sect))
- return 0;
-
assert(info != NULL);
rsd = yasm_section_get_data(sect, &rdf_section_data_cb);
assert(rsd != NULL);
/* it's a label: get value and offset. */
csectd = yasm_section_get_data(sect, &rdf_section_data_cb);
- if (csectd) {
+ if (csectd)
scnum = csectd->scnum;
- } else if (yasm_section_is_absolute(sect)) {
- yasm_warn_set(YASM_WARN_GENERAL,
- N_("rdf does not support exporting absolutes"));
- yasm_errwarn_propagate(info->errwarns,
- yasm_symrec_get_decl_line(sym));
- return 0;
- } else
+ else
yasm_internal_error(N_("didn't understand section"));
value = yasm_bc_next_offset(precbc);
} else if (yasm_symrec_get_equ(sym)) {
long pos;
xdf_reloc *reloc;
- /* FIXME: Don't output absolute sections into the section table */
- if (yasm_section_is_absolute(sect))
- return 0;
-
assert(info != NULL);
xsd = yasm_section_get_data(sect, &xdf_section_data_cb);
assert(xsd != NULL);
/*@null@*/ xdf_symrec_data *xsymd;
unsigned char *localbuf;
- /* Don't output absolute sections into the section table */
- if (yasm_section_is_absolute(sect))
- return 0;
-
assert(info != NULL);
objfmt_xdf = info->objfmt_xdf;
xsd = yasm_section_get_data(sect, &xdf_section_data_cb);
if (sect) {
/*@dependent@*/ /*@null@*/ xdf_section_data *csectd;
csectd = yasm_section_get_data(sect, &xdf_section_data_cb);
- if (csectd) {
+ if (csectd)
scnum = csectd->scnum;
- } else if (yasm_section_is_absolute(sect)) {
- yasm_expr *abs_start;
-
- abs_start = yasm_expr_copy(yasm_section_get_start(sect));
- intn = yasm_expr_get_intnum(&abs_start, 1);
- if (!intn) {
- yasm_error_set(YASM_ERROR_NOT_CONSTANT,
- N_("absolute section start not an integer expression"));
- yasm_errwarn_propagate(info->errwarns, abs_start->line);
- } else
- value = yasm_intnum_get_uint(intn);
- yasm_expr_destroy(abs_start);
-
- flags |= XDF_SYM_EQU;
- scnum = -2; /* -2 = absolute symbol */
- } else
+ else
yasm_internal_error(N_("didn't understand section"));
if (precbc)
value += yasm_bc_next_offset(precbc);
demand_eol();
}
+ if (parser_nasm->abspos) {
+ /* If we're inside an absolute section, just add to the absolute
+ * position rather than appending bytecodes to a section.
+ * Only RES* are allowed in an absolute section, so this is easy.
+ */
+ if (bc) {
+ /*@null@*/ const yasm_expr *numitems, *multiple;
+ unsigned int itemsize;
+ numitems = yasm_bc_reserve_numitems(bc, &itemsize);
+ if (numitems) {
+ yasm_expr *e;
+ e = yasm_expr_create(YASM_EXPR_MUL,
+ yasm_expr_expr(yasm_expr_copy(numitems)),
+ yasm_expr_int(yasm_intnum_create_uint(itemsize)),
+ cur_line);
+ multiple = yasm_bc_get_multiple_expr(bc);
+ if (multiple)
+ e = yasm_expr_create_tree(e, YASM_EXPR_MUL,
+ yasm_expr_copy(multiple),
+ cur_line);
+ parser_nasm->abspos = yasm_expr_create_tree(
+ parser_nasm->abspos, YASM_EXPR_ADD, e, cur_line);
+ } else
+ yasm_error_set(YASM_ERROR_SYNTAX,
+ N_("only RES* allowed within absolute section"));
+ yasm_bc_destroy(bc);
+ }
+ temp_bc = NULL;
+ } else {
+ temp_bc = yasm_section_bcs_append(cursect, bc);
+ if (temp_bc)
+ parser_nasm->prev_bc = temp_bc;
+ }
yasm_errwarn_propagate(parser_nasm->errwarns, cur_line);
- temp_bc = yasm_section_bcs_append(cursect, bc);
- if (temp_bc)
- parser_nasm->prev_bc = temp_bc;
if (parser_nasm->save_input)
yasm_linemap_add_source(parser_nasm->linemap,
temp_bc,
break;
case '$':
/* "$" references the current assembly position */
- sym = yasm_symtab_define_curpos(p_symtab, "$",
- parser_nasm->prev_bc, cur_line);
- e = p_expr_new_ident(yasm_expr_sym(sym));
+ if (parser_nasm->abspos)
+ e = yasm_expr_copy(parser_nasm->abspos);
+ else {
+ sym = yasm_symtab_define_curpos(p_symtab, "$",
+ parser_nasm->prev_bc, cur_line);
+ e = p_expr_new_ident(yasm_expr_sym(sym));
+ }
break;
case START_SECTION_ID:
/* "$$" references the start of the current section */
- sym = yasm_symtab_define_label(p_symtab, "$$",
- yasm_section_bcs_first(cursect), 0, cur_line);
- e = p_expr_new_ident(yasm_expr_sym(sym));
+ if (parser_nasm->absstart)
+ e = yasm_expr_copy(parser_nasm->absstart);
+ else {
+ sym = yasm_symtab_define_label(p_symtab, "$$",
+ yasm_section_bcs_first(cursect), 0, cur_line);
+ e = p_expr_new_ident(yasm_expr_sym(sym));
+ }
break;
default:
return NULL;
strcpy(parser_nasm->locallabel_base, name);
}
- yasm_symtab_define_label(p_symtab, name, parser_nasm->prev_bc, 1,
- cur_line);
+ if (parser_nasm->abspos)
+ yasm_symtab_define_equ(p_symtab, name,
+ yasm_expr_copy(parser_nasm->abspos), cur_line);
+ else
+ yasm_symtab_define_label(p_symtab, name, parser_nasm->prev_bc, 1,
+ cur_line);
yasm_xfree(name);
}
return 0;
}
-static void
-dir_absolute(yasm_object *object, yasm_valparamhead *valparams,
- yasm_valparamhead *objext_valparams, unsigned long line)
-{
- yasm_valparam *vp = yasm_vps_first(valparams);
- yasm_expr *start = yasm_vp_expr(vp, object->symtab, line);
-
- object->cur_section = yasm_object_create_absolute(object, start, line);
-}
-
static void
dir_align(yasm_object *object, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams, unsigned long line)
yasm_valparamhead *objext_valparams)
{
unsigned long line = cur_line;
+ yasm_valparam *vp;
if (!yasm_object_directive(p_object, name, "nasm", valparams,
objext_valparams, line))
;
- else if (yasm__strcasecmp(name, "absolute") == 0)
- dir_absolute(p_object, valparams, objext_valparams, line);
- else if (yasm__strcasecmp(name, "align") == 0)
- dir_align(p_object, valparams, objext_valparams, line);
- else
+ else if (yasm__strcasecmp(name, "absolute") == 0) {
+ vp = yasm_vps_first(valparams);
+ if (parser_nasm->absstart)
+ yasm_expr_destroy(parser_nasm->absstart);
+ if (parser_nasm->abspos)
+ yasm_expr_destroy(parser_nasm->abspos);
+ parser_nasm->absstart = yasm_vp_expr(vp, p_object->symtab, line);
+ parser_nasm->abspos = yasm_expr_copy(parser_nasm->absstart);
+ cursect = NULL;
+ parser_nasm->prev_bc = NULL;
+ } else if (yasm__strcasecmp(name, "align") == 0) {
+ /* Really, we shouldn't end up with an align directive in an absolute
+ * section (as it's supposed to be only used for nop fill, but handle
+ * it gracefully anyway.
+ */
+ if (parser_nasm->abspos) {
+ yasm_expr *boundval, *e;
+ vp = yasm_vps_first(valparams);
+ boundval = yasm_vp_expr(vp, p_object->symtab, line);
+ e = yasm_expr_create_tree(
+ yasm_expr_create_tree(yasm_expr_copy(parser_nasm->absstart),
+ YASM_EXPR_SUB,
+ yasm_expr_copy(parser_nasm->abspos),
+ cur_line),
+ YASM_EXPR_AND,
+ yasm_expr_create(YASM_EXPR_SUB, yasm_expr_expr(boundval),
+ yasm_expr_int(yasm_intnum_create_uint(1)),
+ cur_line),
+ cur_line);
+ parser_nasm->abspos = yasm_expr_create_tree(
+ parser_nasm->abspos, YASM_EXPR_ADD, e, cur_line);
+ } else
+ dir_align(p_object, valparams, objext_valparams, line);
+ } else
yasm_error_set(YASM_ERROR_SYNTAX, N_("unrecognized directive `%s'"),
name);
- /* In case cursect changed or a bytecode was added, update prev_bc. */
- parser_nasm->prev_bc = yasm_section_bcs_last(cursect);
+ if (parser_nasm->absstart && cursect) {
+ /* We switched to a new section. Get out of absolute section mode. */
+ yasm_expr_destroy(parser_nasm->absstart);
+ parser_nasm->absstart = NULL;
+ if (parser_nasm->abspos) {
+ yasm_expr_destroy(parser_nasm->abspos);
+ parser_nasm->abspos = NULL;
+ }
+ }
+
+ if (cursect) {
+ /* In case cursect changed or a bytecode was added, update prev_bc. */
+ parser_nasm->prev_bc = yasm_section_bcs_last(cursect);
+ }
if (valparams)
yasm_vps_delete(valparams);
parser_nasm.peek_token = NONE;
+ parser_nasm.absstart = NULL;
+ parser_nasm.abspos = NULL;
+
/* initialize scanner structure */
yasm_scanner_initialize(&parser_nasm.s);
int peek_token; /* NONE if none */
yystype peek_tokval;
char peek_tokch;
+
+ /* Starting point of the absolute section. NULL if not in an absolute
+ * section.
+ */
+ /*@null@*/ yasm_expr *absstart;
+
+ /* Current location inside an absolute section (including the start).
+ * NULL if not in an absolute section.
+ */
+ /*@null@*/ yasm_expr *abspos;
} yasm_parser_nasm;
/* shorter access names to commonly used parser_nasm fields */
EXTRA_DIST += modules/parsers/nasm/tests/prevlocalwarn.asm
EXTRA_DIST += modules/parsers/nasm/tests/prevlocalwarn.errwarn
EXTRA_DIST += modules/parsers/nasm/tests/prevlocalwarn.hex
+EXTRA_DIST += modules/parsers/nasm/tests/strucalign.asm
+EXTRA_DIST += modules/parsers/nasm/tests/strucalign.hex
+EXTRA_DIST += modules/parsers/nasm/tests/struczero.asm
+EXTRA_DIST += modules/parsers/nasm/tests/struczero.hex
EXTRA_DIST += modules/parsers/nasm/tests/worphan/Makefile.inc
--- /dev/null
+struc bug
+times (64-$) resb 1
+.member:
+times (128-($-$$)) resb 1
+.member2:
+alignb 256
+.member3:
+[align 512]
+endstruc
+dd bug
+dd bug.member
+dd bug.member2
+dd bug.member3
+dd bug_size
--- /dev/null
+00
+00
+00
+00
+40
+00
+00
+00
+80
+00
+00
+00
+00
+01
+00
+00
+00
+02
+00
+00
--- /dev/null
+struc MYSTRUC
+.zero resd 0
+endstruc
+
+foo:
+mov eax, [ecx+MYSTRUC.zero]
+ret
--- /dev/null
+67
+66
+8b
+01
+c3