From 3a69c30f7b8a6ad726b1443505075142ddc8966d Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Tue, 8 Jul 2003 02:55:28 +0000 Subject: [PATCH] Allow complex (expression) section starts, primarily used for implementation of [ORG] in bin objfmt. Still need to assess impact of self-referential (invalid) ORG, and how to detect for that condition. svn path=/trunk/yasm/; revision=990 --- libyasm/section.c | 17 +++++++------- libyasm/section.h | 10 ++++---- modules/objfmts/bin/bin-objfmt.c | 39 ++++++++++++++++++++------------ modules/objfmts/dbg/dbg-objfmt.c | 7 +++--- 4 files changed, 43 insertions(+), 30 deletions(-) diff --git a/libyasm/section.c b/libyasm/section.c index 3e0dd4d4..059921b0 100644 --- a/libyasm/section.c +++ b/libyasm/section.c @@ -26,7 +26,7 @@ */ #define YASM_LIB_INTERNAL #include "util.h" -/*@unused@*/ RCSID("$IdPath: yasm/libyasm/section.c,v 1.37 2003/05/04 22:15:09 peter Exp $"); +/*@unused@*/ RCSID("$IdPath$"); #include "coretype.h" #include "valparam.h" @@ -96,7 +96,7 @@ yasm_sections_new(yasm_section **def, yasm_objfmt *of) /*@-onlytrans@*/ yasm_section * yasm_sections_switch_general(yasm_sectionhead *headp, const char *name, - unsigned long start, int res_only, int *isnew, + yasm_expr *start, int res_only, int *isnew, unsigned long lindex) { yasm_section *s; @@ -122,8 +122,11 @@ yasm_sections_switch_general(yasm_sectionhead *headp, const char *name, s->data.general.name = yasm__xstrdup(name); s->data.general.of = NULL; s->data.general.of_data = NULL; - s->start = yasm_expr_new_ident(yasm_expr_int(yasm_intnum_new_uint(start)), - lindex); + if (start) + s->start = start; + else + s->start = yasm_expr_new_ident(yasm_expr_int(yasm_intnum_new_uint(0)), + lindex); s->bc = yasm_bcs_new(); s->opt_flags = 0; @@ -279,13 +282,11 @@ yasm_section_get_name(const yasm_section *sect) } void -yasm_section_set_start(yasm_section *sect, unsigned long start, +yasm_section_set_start(yasm_section *sect, yasm_expr *start, unsigned long lindex) { yasm_expr_delete(sect->start); - sect->start = - yasm_expr_new_ident(yasm_expr_int(yasm_intnum_new_uint(start)), - lindex); + sect->start = start; } const yasm_expr * diff --git a/libyasm/section.h b/libyasm/section.h index fc6a65fd..da7eeedd 100644 --- a/libyasm/section.h +++ b/libyasm/section.h @@ -47,7 +47,8 @@ * added to a section list if there's not already a section by that name. * \param headp section list * \param name section name - * \param start starting address (ignored if section already exists) + * \param start starting address (ignored if section already exists), + * NULL if 0 or don't care. * \param res_only if nonzero, only space-reserving bytecodes are allowed in * the section (ignored if section already exists) * \param isnew output; set to nonzero if section did not already exist @@ -56,8 +57,9 @@ * \return New section. */ /*@dependent@*/ yasm_section *yasm_sections_switch_general - (yasm_sectionhead *headp, const char *name, unsigned long start, - int res_only, /*@out@*/ int *isnew, unsigned long lindex); + (yasm_sectionhead *headp, const char *name, + /*@null@*/ /*@only@*/ yasm_expr *start, int res_only, + /*@out@*/ int *isnew, unsigned long lindex); /** Create a new absolute section. No checking is performed at creation to * check for overlaps with other absolute sections. @@ -153,7 +155,7 @@ int yasm_sections_traverse(yasm_sectionhead *headp, /*@null@*/ void *d, * \param start starting address * \param lindex line index */ -void yasm_section_set_start(yasm_section *sect, unsigned long start, +void yasm_section_set_start(yasm_section *sect, /*@only@*/ yasm_expr *start, unsigned long lindex); /** Get starting address of a section. diff --git a/modules/objfmts/bin/bin-objfmt.c b/modules/objfmts/bin/bin-objfmt.c index cf3e8e91..84b9a68c 100644 --- a/modules/objfmts/bin/bin-objfmt.c +++ b/modules/objfmts/bin/bin-objfmt.c @@ -25,7 +25,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include -/*@unused@*/ RCSID("$IdPath: yasm/modules/objfmts/bin/bin-objfmt.c,v 1.39 2003/03/26 05:07:56 peter Exp $"); +/*@unused@*/ RCSID("$IdPath$"); #define YASM_LIB_INTERNAL #define YASM_BC_INTERNAL @@ -251,8 +251,10 @@ bin_objfmt_output(FILE *f, yasm_sectionhead *sections, startexpr = yasm_expr_copy(yasm_section_get_start(text)); assert(startexpr != NULL); startnum = yasm_expr_get_intnum(&startexpr, NULL); - if (!startnum) - yasm_internal_error(N_("Complex expr for start in bin objfmt output")); + if (!startnum) { + yasm__error(startexpr->line, N_("ORG expression too complex")); + return; + } start = yasm_intnum_get_uint(startnum); yasm_expr_delete(startexpr); textstart = start; @@ -264,7 +266,9 @@ bin_objfmt_output(FILE *f, yasm_sectionhead *sections, if (data) { start = bin_objfmt_align_section(data, prevsect, start, 4, prevsectlenptr, prevsectpadptr); - yasm_section_set_start(data, start, 0); + yasm_section_set_start(data, + yasm_expr_new_ident(yasm_expr_int(yasm_intnum_new_uint(start)), 0), + 0); datastart = start; prevsect = data; prevsectlenptr = &datalen; @@ -273,7 +277,9 @@ bin_objfmt_output(FILE *f, yasm_sectionhead *sections, if (bss) { start = bin_objfmt_align_section(bss, prevsect, start, 4, prevsectlenptr, prevsectpadptr); - yasm_section_set_start(bss, start, 0); + yasm_section_set_start(bss, + yasm_expr_new_ident(yasm_expr_int(yasm_intnum_new_uint(start)), 0), + 0); } /* Output .text first. */ @@ -380,8 +386,9 @@ bin_objfmt_sections_switch(yasm_sectionhead *headp, } } - retval = yasm_sections_switch_general(headp, sectname, start, resonly, - &isnew, lindex); + retval = yasm_sections_switch_general(headp, sectname, + yasm_expr_new_ident(yasm_expr_int(yasm_intnum_new_uint(start)), + lindex), resonly, &isnew, lindex); if (isnew) { if (have_alignval) { @@ -428,18 +435,20 @@ bin_objfmt_directive(const char *name, yasm_valparamhead *valparams, yasm_valparam *vp; if (yasm__strcasecmp(name, "org") == 0) { - /*@dependent@*/ /*@null@*/ const yasm_intnum *start = NULL; + /*@null@*/ yasm_expr *start = NULL; /* ORG takes just a simple integer as param */ vp = yasm_vps_first(valparams); - if (vp->val) { - yasm__error(lindex, N_("argument to ORG should be numeric")); - return 0; - } else if (vp->param) - start = yasm_expr_get_intnum(&vp->param, NULL); + if (vp->val) + start = yasm_expr_new_ident(yasm_expr_sym( + yasm_symrec_use(vp->val, lindex)), lindex); + else if (vp->param) { + start = vp->param; + vp->param = NULL; /* Don't let valparams delete it */ + } if (!start) { - yasm__error(lindex, N_("argument to ORG should be numeric")); + yasm__error(lindex, N_("argument to ORG must be expression")); return 0; } @@ -448,7 +457,7 @@ bin_objfmt_directive(const char *name, yasm_valparamhead *valparams, if (!sect) yasm_internal_error( N_("bin objfmt: .text section does not exist before ORG is called?")); - yasm_section_set_start(sect, yasm_intnum_get_uint(start), lindex); + yasm_section_set_start(sect, start, lindex); return 0; /* directive recognized */ } else diff --git a/modules/objfmts/dbg/dbg-objfmt.c b/modules/objfmts/dbg/dbg-objfmt.c index c9cddec7..14a92c78 100644 --- a/modules/objfmts/dbg/dbg-objfmt.c +++ b/modules/objfmts/dbg/dbg-objfmt.c @@ -25,7 +25,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include -/*@unused@*/ RCSID("$IdPath: yasm/modules/objfmts/dbg/dbg-objfmt.c,v 1.34 2003/03/26 05:07:57 peter Exp $"); +/*@unused@*/ RCSID("$IdPath$"); #define YASM_LIB_INTERNAL #include @@ -94,8 +94,9 @@ dbg_objfmt_sections_switch(yasm_sectionhead *headp, fprintf(dbg_objfmt_file, ", %lu), returning ", lindex); if ((vp = yasm_vps_first(valparams)) && !vp->param && vp->val != NULL) { - retval = yasm_sections_switch_general(headp, vp->val, 200, 0, &isnew, - lindex); + retval = yasm_sections_switch_general(headp, vp->val, + yasm_expr_new_ident(yasm_expr_int(yasm_intnum_new_uint(200)), + lindex), 0, &isnew, lindex); if (isnew) { fprintf(dbg_objfmt_file, "(new) "); yasm_symrec_define_label(vp->val, retval, (yasm_bytecode *)NULL, 1, -- 2.40.0