]> granicus.if.org Git - yasm/commitdiff
Allow complex (expression) section starts, primarily used for implementation
authorPeter Johnson <peter@tortall.net>
Tue, 8 Jul 2003 02:55:28 +0000 (02:55 -0000)
committerPeter Johnson <peter@tortall.net>
Tue, 8 Jul 2003 02:55:28 +0000 (02:55 -0000)
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
libyasm/section.h
modules/objfmts/bin/bin-objfmt.c
modules/objfmts/dbg/dbg-objfmt.c

index 3e0dd4d4cbc646e8871382d80a4e1b15e09ecdfd..059921b014fac87809782d9f2567c2432d77557c 100644 (file)
@@ -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 *
index fc6a65fd3e1e7a42f2363beed295d4daaf01ad90..da7eeeddc63ad6a38acade67ec97844b0894b895 100644 (file)
@@ -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.
index cf3e8e916a237af622eb6a01bfa356c2dfdbeae6..84b9a68c4cf053368d647405a31617382cfb6951 100644 (file)
@@ -25,7 +25,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 #include <util.h>
-/*@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
index c9cddec784643f2f20d29e43c47d3229f8f8e2f5..14a92c7897bdd9b779e954af3c3533a249b0e253 100644 (file)
@@ -25,7 +25,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 #include <util.h>
-/*@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 <libyasm.h>
@@ -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,