]> granicus.if.org Git - yasm/commitdiff
- Fix much brokenness in absolute value handling, particularly in regards to
authorPeter Johnson <peter@tortall.net>
Fri, 29 Sep 2006 07:18:45 +0000 (07:18 -0000)
committerPeter Johnson <peter@tortall.net>
Fri, 29 Sep 2006 07:18:45 +0000 (07:18 -0000)
  PC-relative relocations (jumps and calls).
- Allow SEG:OFF to be used as just an offset portion (like NASM does).
- Labels in absolute sections that are declared global are given the correct
  absolute value in the symbol table.

One difference from NASM:
  label equ 0040h:001eh
  jmp label
in NASM means the same as:
  jmp 001eh  (a near jump)
but yasm will treat this the same as:
  jmp 0040h:001eh  (a far jump)

I'm still not completely happy with this implementation, but it's workable
and fixes all the bugs I've found so far in absolute handling.

svn path=/trunk/yasm/; revision=1634

23 files changed:
libyasm/expr-int.h
libyasm/expr.c
libyasm/expr.h
libyasm/symrec.c
libyasm/symrec.h
libyasm/value.c
libyasm/value.h
modules/arch/x86/x86arch.h
modules/arch/x86/x86bc.c
modules/arch/x86/x86expr.c
modules/arch/x86/x86id.c
modules/objfmts/bin/bin-objfmt.c
modules/objfmts/bin/tests/Makefile.inc
modules/objfmts/bin/tests/bin-farabs.asm [new file with mode: 0644]
modules/objfmts/bin/tests/bin-farabs.hex [new file with mode: 0644]
modules/objfmts/elf/elf-objfmt.c
modules/objfmts/elf/elf.c
modules/objfmts/elf/tests/Makefile.inc
modules/objfmts/elf/tests/elfabssect.asm
modules/objfmts/elf/tests/elfabssect.hex
modules/objfmts/elf/tests/elfequabs.asm [new file with mode: 0644]
modules/objfmts/elf/tests/elfequabs.hex [new file with mode: 0644]
modules/objfmts/elf/tests/elfmanysym.hex

index 0a1bc5a9bd63248b19eb6f7d0d26f2ac96ebe715..8f5842dfe299de5d71bd3d5d82ca8aa55b0cc613 100644 (file)
 #ifndef YASM_EXPR_INT_H
 #define YASM_EXPR_INT_H
 
-/* Types listed in canonical sorting order.  See expr_order_terms(). */
+/* Types listed in canonical sorting order.  See expr_order_terms().
+ * Note precbc must be used carefully (in a-b pairs), as only symrecs can
+ * become the relative term in a #yasm_value.
+ */
 typedef enum {
     YASM_EXPR_NONE = 0,
     YASM_EXPR_REG = 1<<0,
@@ -35,13 +38,15 @@ typedef enum {
     YASM_EXPR_SUBST = 1<<2,
     YASM_EXPR_FLOAT = 1<<3,
     YASM_EXPR_SYM = 1<<4,
-    YASM_EXPR_SYMEXP = 1<<5, /* post-expanded sym (due to absolute expansion) */
-    YASM_EXPR_EXPR = 1<<6
+    YASM_EXPR_SYMEXP = 1<<5, /* post-expanded sym (due to EQU expansion) */
+    YASM_EXPR_PRECBC = 1<<6, /* direct bytecode ref (rather than via symrec) */
+    YASM_EXPR_EXPR = 1<<7
 } yasm_expr__type;
 
 struct yasm_expr__item {
     yasm_expr__type type;
     union {
+       yasm_bytecode *precbc;
        yasm_symrec *sym;
        yasm_expr *expn;
        yasm_intnum *intn;
index 60f2409aaab4616cf62eb4f82095b0e1fc30ad90..531ad604b5b55e92de835342f72b9a66c0226bb7 100644 (file)
@@ -49,6 +49,7 @@ static int expr_traverse_nodes_post(/*@null@*/ yasm_expr *e,
                                    /*@null@*/ void *d,
                                    int (*func) (/*@null@*/ yasm_expr *e,
                                                 /*@null@*/ void *d));
+static void expr_delete_term(yasm_expr__item *term, int recurse);
 
 /* Bitmap of used items.  We should really never need more than 2 at a time,
  * so 31 is pretty much overkill.
@@ -138,6 +139,15 @@ expr_get_item(void)
     return &itempool[z];
 }
 
+yasm_expr__item *
+yasm_expr_precbc(yasm_bytecode *precbc)
+{
+    yasm_expr__item *e = expr_get_item();
+    e->type = YASM_EXPR_PRECBC;
+    e->data.precbc = precbc;
+    return e;
+}
+
 yasm_expr__item *
 yasm_expr_sym(yasm_symrec *s)
 {
@@ -185,7 +195,8 @@ yasm_expr_reg(unsigned long reg)
 
 /* Transforms instances of symrec-symrec [symrec+(-1*symrec)] into single
  * expritems if possible.  Uses a simple n^2 algorithm because n is usually
- * quite small.
+ * quite small.  Also works for precbc-precbc (or symrec-precbc,
+ * precbc-symrec).
  */
 static /*@only@*/ yasm_expr *
 expr_xform_bc_dist_base(/*@returned@*/ /*@only@*/ yasm_expr *e,
@@ -210,7 +221,7 @@ expr_xform_bc_dist_base(/*@returned@*/ /*@only@*/ yasm_expr *e,
        int j;
        yasm_expr *sube;
        yasm_intnum *intn;
-       yasm_symrec *sym;
+       yasm_symrec *sym = NULL;
        /*@dependent@*/ yasm_section *sect2;
        /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc2;
 
@@ -223,13 +234,21 @@ expr_xform_bc_dist_base(/*@returned@*/ /*@only@*/ yasm_expr *e,
 
        if (sube->terms[0].type == YASM_EXPR_INT &&
            (sube->terms[1].type == YASM_EXPR_SYM ||
-            sube->terms[1].type == YASM_EXPR_SYMEXP)) {
+            sube->terms[1].type == YASM_EXPR_SYMEXP ||
+            sube->terms[1].type == YASM_EXPR_PRECBC)) {
            intn = sube->terms[0].data.intn;
-           sym = sube->terms[1].data.sym;
+           if (sube->terms[1].type == YASM_EXPR_PRECBC)
+               precbc = sube->terms[1].data.precbc;
+           else
+               sym = sube->terms[1].data.sym;
        } else if ((sube->terms[0].type == YASM_EXPR_SYM ||
-                   sube->terms[0].type == YASM_EXPR_SYMEXP) &&
+                   sube->terms[0].type == YASM_EXPR_SYMEXP ||
+                   sube->terms[0].type == YASM_EXPR_PRECBC) &&
                   sube->terms[1].type == YASM_EXPR_INT) {
-           sym = sube->terms[0].data.sym;
+           if (sube->terms[0].type == YASM_EXPR_PRECBC)
+               precbc = sube->terms[0].data.precbc;
+           else
+               sym = sube->terms[0].data.sym;
            intn = sube->terms[1].data.intn;
        } else
            continue;
@@ -237,15 +256,17 @@ expr_xform_bc_dist_base(/*@returned@*/ /*@only@*/ yasm_expr *e,
        if (!yasm_intnum_is_neg1(intn))
            continue;
 
-       if (!yasm_symrec_get_label(sym, &precbc))
+       if (sym && !yasm_symrec_get_label(sym, &precbc))
            continue;
        sect2 = yasm_bc_get_section(precbc);
 
        /* Now look for a symrec term in the same segment */
        for (j=0; j<e->numterms; j++) {
-           if ((e->terms[j].type == YASM_EXPR_SYM ||
-                e->terms[j].type == YASM_EXPR_SYMEXP) &&
-               yasm_symrec_get_label(e->terms[j].data.sym, &precbc2) &&
+           if ((((e->terms[j].type == YASM_EXPR_SYM ||
+                  e->terms[j].type == YASM_EXPR_SYMEXP) &&
+                 yasm_symrec_get_label(e->terms[j].data.sym, &precbc2)) ||
+                (e->terms[j].type == YASM_EXPR_PRECBC &&
+                 (precbc2 = e->terms[j].data.precbc))) &&
                (sect = yasm_bc_get_section(precbc2)) &&
                sect == sect2 &&
                callback(&e->terms[j], precbc, precbc2, cbd)) {
@@ -551,19 +572,7 @@ expr_simplify_identity(yasm_expr *e, int numterms, int int_term,
        /* Loop through, deleting everything but the integer term */
        for (i=0; i<e->numterms; i++)
            if (i != int_term)
-               switch (e->terms[i].type) {
-                   case YASM_EXPR_INT:
-                       yasm_intnum_destroy(e->terms[i].data.intn);
-                       break;
-                   case YASM_EXPR_FLOAT:
-                       yasm_floatnum_destroy(e->terms[i].data.flt);
-                       break;
-                   case YASM_EXPR_EXPR:
-                       yasm_expr_destroy(e->terms[i].data.expn);
-                       break;
-                   default:
-                       break;
-               }
+               expr_delete_term(&e->terms[i], 1);
 
        /* Move integer term to the first term (if not already there) */
        if (int_term != 0)
@@ -813,10 +822,7 @@ yasm_expr__level_tree(yasm_expr *e, int fold_const, int simplify_ident,
 
     /* traverse terms */
     for (i=0; i<e->numterms; i++) {
-       /* Expansion stage first: expand equ's, and expand symrecs that
-        * reference absolute sections into
-        * absolute start expr + (symrec - first bc in abs section).
-        */
+       /* Expansion stage first: expand equ's. */
        if (e->terms[i].type == YASM_EXPR_SYM) {
            yasm__exprentry *np;
            const yasm_expr *equ_expr =
@@ -839,45 +845,6 @@ yasm_expr__level_tree(yasm_expr *e, int fold_const, int simplify_ident,
 
                ee.e = equ_expr;
                SLIST_INSERT_HEAD(eh, &ee, next);
-           } else if (yasm_symrec_get_label(e->terms[i].data.sym, &precbc) &&
-                      (sect = yasm_bc_get_section(precbc)) &&
-                      yasm_section_is_absolute(sect)) {
-               const yasm_expr *start = yasm_section_get_start(sect);
-               yasm_expr *sube, *sube2;
-
-               /* Check for circular reference */
-               SLIST_FOREACH(np, eh, next) {
-                   if (np->e == start) {
-                       yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-                                      N_("circular reference detected"));
-                       return e;
-                   }
-               }
-
-               sube = yasm_xmalloc(sizeof(yasm_expr));
-               sube->op = YASM_EXPR_SUB;
-               sube->line = e->line;
-               sube->numterms = 2;
-               sube->terms[0].type = YASM_EXPR_SYMEXP;
-               sube->terms[0].data.sym = e->terms[i].data.sym;
-               sube->terms[1].type = YASM_EXPR_SYMEXP;
-               sube->terms[1].data.sym = yasm_section_abs_get_sym(sect);
-               assert(sube->terms[1].data.sym != NULL);
-
-               sube2 = yasm_xmalloc(sizeof(yasm_expr));
-               sube2->op = YASM_EXPR_ADD;
-               sube2->line = e->line;
-               sube2->numterms = 2;
-               sube2->terms[0].type = YASM_EXPR_EXPR;
-               sube2->terms[0].data.expn = yasm_expr_copy(start);
-               sube2->terms[1].type = YASM_EXPR_EXPR;
-               sube2->terms[1].data.expn = sube;
-
-               e->terms[i].type = YASM_EXPR_EXPR;
-               e->terms[i].data.expn = sube2;
-
-               ee.e = start;
-               SLIST_INSERT_HEAD(eh, &ee, next);
            }
        }
 
@@ -894,6 +861,15 @@ yasm_expr__level_tree(yasm_expr *e, int fold_const, int simplify_ident,
        }
     }
 
+    /* Check for SEG of SEG:OFF, if we match, simplify to just the segment */
+    if (e->op == YASM_EXPR_SEG && e->terms[0].type == YASM_EXPR_EXPR &&
+       e->terms[0].data.expn->op == YASM_EXPR_SEGOFF) {
+       e->op = YASM_EXPR_IDENT;
+       e->terms[0].data.expn->op = YASM_EXPR_IDENT;
+       /* Destroy the second (offset) term */
+       expr_delete_term(&e->terms[1], 1);
+    }
+
     /* do callback */
     e = expr_level_op(e, fold_const, simplify_ident, simplify_reg_mul);
     if (calc_bc_dist || expr_xform_extra) {
@@ -963,6 +939,10 @@ expr_item_copy(yasm_expr__item *dest, const yasm_expr__item *src)
            /* Symbols don't need to be copied */
            dest->data.sym = src->data.sym;
            break;
+       case YASM_EXPR_PRECBC:
+           /* Nor do direct bytecode references */
+           dest->data.precbc = src->data.precbc;
+           break;
        case YASM_EXPR_EXPR:
            dest->data.expn = yasm_expr__copy_except(src->data.expn, -1);
            break;
@@ -1010,22 +990,31 @@ yasm_expr_copy(const yasm_expr *e)
     return yasm_expr__copy_except(e, -1);
 }
 
+static void
+expr_delete_term(yasm_expr__item *term, int recurse)
+{
+    switch (term->type) {
+       case YASM_EXPR_INT:
+           yasm_intnum_destroy(term->data.intn);
+           break;
+       case YASM_EXPR_FLOAT:
+           yasm_floatnum_destroy(term->data.flt);
+           break;
+       case YASM_EXPR_EXPR:
+           if (recurse)
+               yasm_expr_destroy(term->data.expn);
+           break;
+       default:
+           break;
+    }
+}
+
 static int
 expr_destroy_each(/*@only@*/ yasm_expr *e, /*@unused@*/ void *d)
 {
     int i;
-    for (i=0; i<e->numterms; i++) {
-       switch (e->terms[i].type) {
-           case YASM_EXPR_INT:
-               yasm_intnum_destroy(e->terms[i].data.intn);
-               break;
-           case YASM_EXPR_FLOAT:
-               yasm_floatnum_destroy(e->terms[i].data.flt);
-               break;
-           default:
-               break;  /* none of the other types needs to be deleted */
-       }
-    }
+    for (i=0; i<e->numterms; i++)
+       expr_delete_term(&e->terms[i], 0);
     yasm_xfree(e);     /* free ourselves */
     return 0;  /* don't stop recursion */
 }
@@ -1164,6 +1153,31 @@ yasm_expr__traverse_leaves_in(yasm_expr *e, void *d,
     return 0;
 }
 
+yasm_expr *
+yasm_expr_extract_deep_segoff(yasm_expr **ep)
+{
+    yasm_expr *retval;
+    yasm_expr *e = *ep;
+    int i;
+
+    /* Try to extract at this level */
+    retval = yasm_expr_extract_segoff(ep);
+    if (retval)
+       return retval;
+
+    /* Not at this level?  Search any expr children. */
+    for (i=0; i<e->numterms; i++) {
+       if (e->terms[i].type == YASM_EXPR_EXPR) {
+           retval = yasm_expr_extract_deep_segoff(&e->terms[i].data.expn);
+           if (retval)
+               return retval;
+       }
+    }
+
+    /* Didn't find one */
+    return NULL;
+}
+
 yasm_expr *
 yasm_expr_extract_segoff(yasm_expr **ep)
 {
@@ -1381,6 +1395,10 @@ yasm_expr_print(const yasm_expr *e, FILE *f)
     }
     for (i=0; i<e->numterms; i++) {
        switch (e->terms[i].type) {
+           case YASM_EXPR_PRECBC:
+               fprintf(f, "{%lx}",
+                       yasm_bc_next_offset(e->terms[i].data.precbc));
+               break;
            case YASM_EXPR_SYM:
            case YASM_EXPR_SYMEXP:
                fprintf(f, "%s", yasm_symrec_get_name(e->terms[i].data.sym));
index 801594eb40545e5c343ec84467e328e57a6fe73e..9c7574fb00b000b43da5347b3be919caa5ed1ae3 100644 (file)
@@ -48,6 +48,12 @@ typedef struct yasm_expr__item yasm_expr__item;
     (yasm_expr_op op, /*@only@*/ yasm_expr__item *a,
      /*@only@*/ /*@null@*/ yasm_expr__item *b, unsigned long line);
 
+/** Create a new preceding-bytecode expression item.
+ * \param precbc    preceding bytecode
+ * \return Newly allocated expression item.
+ */
+/*@only@*/ yasm_expr__item *yasm_expr_precbc(/*@keep@*/ yasm_bytecode *precbc);
+
 /** Create a new symbol expression item.
  * \param sym      symbol
  * \return Newly allocated expression item.
@@ -171,6 +177,16 @@ SLIST_HEAD(yasm__exprhead, yasm__exprentry);
 #define yasm_expr_simplify(e, cbd) \
     yasm_expr__level_tree(e, 1, 1, 1, cbd, NULL, NULL, NULL)
 
+/** Extract the segment portion of an expression containing SEG:OFF, leaving
+ * the offset.
+ * \param ep           expression (pointer to)
+ * \return NULL if unable to extract a segment (expr does not contain a
+ *         YASM_EXPR_SEGOFF operator), otherwise the segment expression.
+ *         The input expression is modified such that on return, it's the
+ *         offset expression.
+ */
+/*@only@*/ /*@null@*/ yasm_expr *yasm_expr_extract_deep_segoff(yasm_expr **ep);
+
 /** Extract the segment portion of a SEG:OFF expression, leaving the offset.
  * \param ep           expression (pointer to)
  * \return NULL if unable to extract a segment (YASM_EXPR_SEGOFF not the
index 08e90f859a076621bd5076236660b6e5cbd5fc45..6028c4bc4902b06a514266fae1fe56c403baaffc 100644 (file)
@@ -37,6 +37,7 @@
 #include "assocdat.h"
 
 #include "errwarn.h"
+#include "intnum.h"
 #include "floatnum.h"
 #include "expr.h"
 #include "symrec.h"
@@ -193,6 +194,18 @@ yasm_symtab_iter_value(const yasm_symtab_iter *cur)
     return (yasm_symrec *)HAMTEntry_get_data((const HAMTEntry *)cur);
 }
 
+yasm_symrec *
+yasm_symtab_abs_sym(yasm_symtab *symtab)
+{
+    yasm_symrec *rec = symtab_get_or_new(symtab, "", 1);
+    rec->line = 0;
+    rec->type = SYM_EQU;
+    rec->value.expn =
+       yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(0)), 0);
+    rec->status |= SYM_DEFINED|SYM_VALUED|SYM_USED;
+    return rec;
+}
+
 yasm_symrec *
 yasm_symtab_use(yasm_symtab *symtab, const char *name, unsigned long line)
 {
@@ -321,6 +334,8 @@ static int
 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 & SYM_USED) && !(sym->status & SYM_DEFINED) &&
        !(sym->visibility & (YASM_SYM_EXTERN | YASM_SYM_COMMON))) {
@@ -335,6 +350,25 @@ symtab_parser_finalize_checksym(yasm_symrec *sym, /*@null@*/ void *d)
        }
     }
 
+    /* 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->line),
+           YASM_EXPR_ADD,
+           yasm_expr_copy(yasm_section_get_start(sect)),
+           sym->line);
+    }
+
     return 0;
 }
 
@@ -429,6 +463,12 @@ yasm_symrec_get_label(const yasm_symrec *sym,
     return 1;
 }
 
+int
+yasm_symrec_is_abs(const yasm_symrec *sym)
+{
+    return (sym->line == 0 && sym->type == SYM_EQU && sym->name[0] == '\0');
+}
+
 int
 yasm_symrec_is_special(const yasm_symrec *sym)
 {
index a4d9739178d8c729e4f4a64061fb0afc8cb2461e..04ec321b517f25f872cc1e98c829e0a912913f21 100644 (file)
@@ -44,6 +44,15 @@ yasm_symtab *yasm_symtab_create(void);
  */
 void yasm_symtab_destroy(/*@only@*/ yasm_symtab *symtab);
 
+/** Get a reference to the symbol table's "absolute" symbol.  This is
+ * essentially an EQU with no name and value 0, and is used for relocating
+ * absolute current-position-relative values.
+ * \see yasm_value_set_curpos_rel().
+ * \param symtab    symbol table
+ * \return Absolute symbol (dependent pointer, do not free).
+ */
+/*@dependent@*/ yasm_symrec *yasm_symtab_abs_sym(yasm_symtab *symtab);
+
 /** Get a reference to (use) a symbol.  The symbol does not necessarily need to
  * be defined before it is used.
  * \param symtab    symbol table
@@ -227,6 +236,13 @@ typedef /*@dependent@*/ yasm_bytecode *yasm_symrec_get_label_bytecodep;
 int yasm_symrec_get_label(const yasm_symrec *sym,
                          /*@out@*/ yasm_symrec_get_label_bytecodep *precbc);
 
+/** Determine if symbol is the "absolute" symbol created by
+ * yasm_symtab_abs_sym().
+ * \param sym      symbol
+ * \return 0 if symbol is not the "absolute" symbol, nonzero otherwise.
+ */
+int yasm_symrec_is_abs(const yasm_symrec *sym);
+
 /** Determine if symbol is a special symbol.
  * \param sym      symbol
  * \return 0 if symbol is not a special symbol, nonzero otherwise.
index 50b5482c193e7e3ada6451bb1e7601fe3ba6dd6e..6ef16855581064afc396932caca03bf7d812829a 100644 (file)
@@ -98,6 +98,22 @@ yasm_value_delete(yasm_value *value)
     value->rel = NULL;
 }
 
+void
+yasm_value_set_curpos_rel(yasm_value *value, yasm_bytecode *bc,
+                         unsigned int ip_rel)
+{
+    value->curpos_rel = 1;
+    value->ip_rel = ip_rel;
+    /* In order for us to correctly output curpos-relative values, we must
+     * have a relative portion of the value.  If one doesn't exist, point
+     * to a custom absolute symbol.
+     */
+    if (!value->rel) {
+       value->rel = yasm_symtab_abs_sym(yasm_object_get_symtab(
+           yasm_section_get_object(yasm_bc_get_section(bc))));
+    }
+}
+
 static int
 value_finalize_scan(yasm_value *value, yasm_expr *e, int ssym_not_ok)
 {
@@ -569,9 +585,22 @@ yasm_value_output_basic(yasm_value *value, /*@out@*/ unsigned char *buf,
            return -1;
        }
 
-       /* Handle integer expressions */
+       /* Handle normal integer expressions */
        intn = yasm_expr_get_intnum(&value->abs, 1);
+
        if (!intn) {
+           /* Second try before erroring: yasm_expr_get_intnum doesn't handle
+            * SEG:OFF, so try simplifying out any to just the OFF portion,
+            * then getting the intnum again.
+            */
+           yasm_expr *seg = yasm_expr_extract_deep_segoff(&value->abs);
+           if (seg)
+               yasm_expr_destroy(seg);
+           intn = yasm_expr_get_intnum(&value->abs, 1);
+       }
+
+       if (!intn) {
+           /* Still don't have an integer! */
            yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                           N_("expression too complex"));
            return -1;
@@ -617,7 +646,14 @@ yasm_value_output_basic(yasm_value *value, /*@out@*/ unsigned char *buf,
                                     bc, warn))
            retval = -1;
        yasm_intnum_destroy(outval);
-    } else if (intn) {
+       return retval;
+    }
+
+    if (value->seg_of || value->rshift || value->curpos_rel || value->ip_rel
+       || value->section_rel)
+       return 0;   /* We can't handle this with just an absolute */
+
+    if (intn) {
        /* Output just absolute portion */
        if (yasm_arch_intnum_tobytes(arch, intn, buf, destsize, valsize, 0, bc,
                                     warn))
index 89a93aa8ff97d79626df26989f7b0c391111ee12..4c871073075bf2a757a7eef6502a6d4d67d14a7c 100644 (file)
@@ -71,6 +71,18 @@ void yasm_value_init_copy(yasm_value *value, const yasm_value *orig);
  */
 void yasm_value_delete(yasm_value *value);
 
+/** Set a value to be relative to the current assembly position rather than
+ * relative to the section start.
+ * \param value            value
+ * \param bc       bytecode containing value
+ * \param ip_rel    if nonzero, indicates IP-relative data relocation,
+ *                 sometimes used to generate special relocations
+ * \note If value is just an absolute value, will get an absolute symrec to
+ *       reference to (via bc's symbol table).
+ */
+void yasm_value_set_curpos_rel(yasm_value *value, yasm_bytecode *bc,
+                              unsigned int ip_rel);
+
 /** Perform yasm_value_finalize_expr() on a value that already exists from
  * being initialized with yasm_value_initialize().
  * \param value                value
index 328e270a9450392ad6ea7de9715ba8785825bda0..a2639c47a33be98b4de99b7b5b6b161ebd271ba2 100644 (file)
@@ -109,8 +109,7 @@ typedef enum {
     X86_NEAR = 1,
     X86_SHORT,
     X86_FAR,
-    X86_TO,
-    X86_FAR_SEGOFF         /* FAR due to SEG:OFF immediate */
+    X86_TO
 } x86_parse_targetmod;
 
 typedef enum {
@@ -256,7 +255,7 @@ void yasm_x86__bc_apply_prefixes
  */
 int yasm_x86__expr_checkea
     (x86_effaddr *x86_ea, unsigned char *addrsize, unsigned int bits,
-     int address16_op, unsigned char *rex);
+     int address16_op, unsigned char *rex, yasm_bytecode *bc);
 
 void yasm_x86__parse_cpu(yasm_arch *arch, const char *cpuid, size_t cpuid_len);
 
index e587d36da8c632466941fbe8067c9c6e2e2f5894..6897261be2bed117dcee8fbac50814505707d3fb 100644 (file)
@@ -525,7 +525,7 @@ x86_bc_insn_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
         */
        if (yasm_x86__expr_checkea(x86_ea, &insn->common.addrsize,
                insn->common.mode_bits, insn->postop == X86_POSTOP_ADDRESS16,
-               &insn->rex))
+               &insn->rex, bc))
            /* failed, don't bother checking rest of insn */
            return -1;
 
index 21ae3debe903c5b74e3a970cb34557d31b7aceb6..c114547c02556f7764ef3a4b976328b9cd9707af 100644 (file)
@@ -547,7 +547,8 @@ x86_expr_checkea_getregsize_callback(yasm_expr__item *ei, void *d)
 
 int
 yasm_x86__expr_checkea(x86_effaddr *x86_ea, unsigned char *addrsize,
-                      unsigned int bits, int address16_op, unsigned char *rex)
+                      unsigned int bits, int address16_op, unsigned char *rex,
+                      yasm_bytecode *bc)
 {
     int retval;
 
@@ -649,16 +650,12 @@ yasm_x86__expr_checkea(x86_effaddr *x86_ea, unsigned char *addrsize,
                                   N_("invalid effective address"));
                    return 1;
                case 2:
-                   if (pcrel) {
-                       x86_ea->ea.disp.curpos_rel = 1;
-                       x86_ea->ea.disp.ip_rel = 1;
-                   }
+                   if (pcrel)
+                       yasm_value_set_curpos_rel(&x86_ea->ea.disp, bc, 1);
                    return 2;
                default:
-                   if (pcrel) {
-                       x86_ea->ea.disp.curpos_rel = 1;
-                       x86_ea->ea.disp.ip_rel = 1;
-                   }
+                   if (pcrel)
+                       yasm_value_set_curpos_rel(&x86_ea->ea.disp, bc, 1);
                    break;
            }
        }
@@ -904,16 +901,12 @@ yasm_x86__expr_checkea(x86_effaddr *x86_ea, unsigned char *addrsize,
                                   N_("invalid effective address"));
                    return 1;
                case 2:
-                   if (pcrel) {
-                       x86_ea->ea.disp.curpos_rel = 1;
-                       x86_ea->ea.disp.ip_rel = 1;
-                   }
+                   if (pcrel)
+                       yasm_value_set_curpos_rel(&x86_ea->ea.disp, bc, 1);
                    return 2;
                default:
-                   if (pcrel) {
-                       x86_ea->ea.disp.curpos_rel = 1;
-                       x86_ea->ea.disp.ip_rel = 1;
-                   }
+                   if (pcrel)
+                       yasm_value_set_curpos_rel(&x86_ea->ea.disp, bc, 1);
                    break;
            }
        }
index a0275a2c92df1f6e4277d9cc0500dec4b1b006cd..def4549b0d1ec9eebaaf36609715b631cf748062 100644 (file)
@@ -109,6 +109,7 @@ RCSID("$Id$");
  *             15 = memory offset (an EA, but with no registers allowed)
  *                  [special case for MOV opcode]
  *             16 = immediate, value=1 (for special-case shift)
+ *             17 = immediate, does not contain SEG:OFF (for jmp/call)
  *  - 3 bits = size (user-specified, or from register size):
  *             0 = any size acceptable/no size spec acceptable (dep. on strict)
  *             1/2/3/4 = 8/16/32/64 bits (from user or reg size)
@@ -182,6 +183,7 @@ RCSID("$Id$");
 #define OPT_CR4                0x14
 #define OPT_MemOffs    0x15
 #define OPT_Imm1       0x16
+#define OPT_ImmNotSegOff 0x17
 #define OPT_MASK       0x1F
 
 #define OPS_Any                (0UL<<5)
@@ -1141,13 +1143,13 @@ static const x86_insn_info shlrd_insn[] = {
 /* Control transfer instructions (unconditional) */
 static const x86_insn_info call_insn[] = {
     { CPU_Any, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 1,
-      {OPT_Imm|OPS_Any|OPA_JmpRel, 0, 0} },
+      {OPT_ImmNotSegOff|OPS_Any|OPA_JmpRel, 0, 0} },
     { CPU_Any, 0, 16, 0, 0, 0, {0, 0, 0}, 0, 1,
-      {OPT_Imm|OPS_16|OPA_JmpRel, 0, 0} },
+      {OPT_ImmNotSegOff|OPS_16|OPA_JmpRel, 0, 0} },
     { CPU_386|CPU_Not64, 0, 32, 0, 0, 0, {0, 0, 0}, 0, 1,
-      {OPT_Imm|OPS_32|OPA_JmpRel, 0, 0} },
+      {OPT_ImmNotSegOff|OPS_32|OPA_JmpRel, 0, 0} },
     { CPU_Hammer|CPU_64, 0, 64, 0, 0, 0, {0, 0, 0}, 0, 1,
-      {OPT_Imm|OPS_32|OPA_JmpRel, 0, 0} },
+      {OPT_ImmNotSegOff|OPS_32|OPA_JmpRel, 0, 0} },
 
     { CPU_Any, 0, 16, 64, 0, 1, {0xE8, 0, 0}, 0, 1,
       {OPT_Imm|OPS_16|OPTM_Near|OPA_JmpRel, 0, 0} },
@@ -1175,13 +1177,7 @@ static const x86_insn_info call_insn[] = {
     { CPU_Any, 0, 0, 64, 0, 1, {0xFF, 0, 0}, 2, 1,
       {OPT_Mem|OPS_Any|OPTM_Near|OPA_EA, 0, 0} },
 
-    { CPU_Not64, 0, 16, 0, 0, 1, {0x9A, 0, 0}, 3, 1,
-      {OPT_Imm|OPS_16|OPTM_Far|OPA_JmpFar, 0, 0} },
-    { CPU_386|CPU_Not64, 0, 32, 0, 0, 1, {0x9A, 0, 0}, 3, 1,
-      {OPT_Imm|OPS_32|OPTM_Far|OPA_JmpFar, 0, 0} },
-    { CPU_Not64, 0, 0, 0, 0, 1, {0x9A, 0, 0}, 3, 1,
-      {OPT_Imm|OPS_Any|OPTM_Far|OPA_JmpFar, 0, 0} },
-
+    /* Far indirect (through memory).  Needs explicit FAR override. */
     { CPU_Any, 0, 16, 0, 0, 1, {0xFF, 0, 0}, 3, 1,
       {OPT_Mem|OPS_16|OPTM_Far|OPA_EA, 0, 0} },
     { CPU_386, 0, 32, 0, 0, 1, {0xFF, 0, 0}, 3, 1,
@@ -1189,17 +1185,33 @@ static const x86_insn_info call_insn[] = {
     { CPU_EM64T|CPU_64, 0, 64, 0, 0, 1, {0xFF, 0, 0}, 3, 1,
       {OPT_Mem|OPS_64|OPTM_Far|OPA_EA, 0, 0} },
     { CPU_Any, 0, 0, 0, 0, 1, {0xFF, 0, 0}, 3, 1,
-      {OPT_Mem|OPS_Any|OPTM_Far|OPA_EA, 0, 0} }
+      {OPT_Mem|OPS_Any|OPTM_Far|OPA_EA, 0, 0} },
+
+    /* With explicit FAR override */
+    { CPU_Not64, 0, 16, 0, 0, 1, {0x9A, 0, 0}, 3, 1,
+      {OPT_Imm|OPS_16|OPTM_Far|OPA_JmpFar, 0, 0} },
+    { CPU_386|CPU_Not64, 0, 32, 0, 0, 1, {0x9A, 0, 0}, 3, 1,
+      {OPT_Imm|OPS_32|OPTM_Far|OPA_JmpFar, 0, 0} },
+    { CPU_Not64, 0, 0, 0, 0, 1, {0x9A, 0, 0}, 3, 1,
+      {OPT_Imm|OPS_Any|OPTM_Far|OPA_JmpFar, 0, 0} },
+
+    /* Since not caught by first ImmNotSegOff group, implicitly FAR. */
+    { CPU_Not64, 0, 16, 0, 0, 1, {0x9A, 0, 0}, 3, 1,
+      {OPT_Imm|OPS_16|OPA_JmpFar, 0, 0} },
+    { CPU_386|CPU_Not64, 0, 32, 0, 0, 1, {0x9A, 0, 0}, 3, 1,
+      {OPT_Imm|OPS_32|OPA_JmpFar, 0, 0} },
+    { CPU_Not64, 0, 0, 0, 0, 1, {0x9A, 0, 0}, 3, 1,
+      {OPT_Imm|OPS_Any|OPA_JmpFar, 0, 0} }
 };
 static const x86_insn_info jmp_insn[] = {
     { CPU_Any, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 1,
-      {OPT_Imm|OPS_Any|OPA_JmpRel, 0, 0} },
+      {OPT_ImmNotSegOff|OPS_Any|OPA_JmpRel, 0, 0} },
     { CPU_Any, 0, 16, 0, 0, 0, {0, 0, 0}, 0, 1,
-      {OPT_Imm|OPS_16|OPA_JmpRel, 0, 0} },
+      {OPT_ImmNotSegOff|OPS_16|OPA_JmpRel, 0, 0} },
     { CPU_386|CPU_Not64, 0, 32, 0, 0, 1, {0, 0, 0}, 0, 1,
-      {OPT_Imm|OPS_32|OPA_JmpRel, 0, 0} },
+      {OPT_ImmNotSegOff|OPS_32|OPA_JmpRel, 0, 0} },
     { CPU_Hammer|CPU_64, 0, 64, 0, 0, 1, {0, 0, 0}, 0, 1,
-      {OPT_Imm|OPS_32|OPA_JmpRel, 0, 0} },
+      {OPT_ImmNotSegOff|OPS_32|OPA_JmpRel, 0, 0} },
 
     { CPU_Any, 0, 0, 64, 0, 1, {0xEB, 0, 0}, 0, 1,
       {OPT_Imm|OPS_Any|OPTM_Short|OPA_JmpRel, 0, 0} },
@@ -1229,13 +1241,7 @@ static const x86_insn_info jmp_insn[] = {
     { CPU_Any, 0, 0, 64, 0, 1, {0xFF, 0, 0}, 4, 1,
       {OPT_Mem|OPS_Any|OPTM_Near|OPA_EA, 0, 0} },
 
-    { CPU_Not64, 0, 16, 0, 0, 1, {0xEA, 0, 0}, 3, 1,
-      {OPT_Imm|OPS_16|OPTM_Far|OPA_JmpFar, 0, 0} },
-    { CPU_386|CPU_Not64, 0, 32, 0, 0, 1, {0xEA, 0, 0}, 3, 1,
-      {OPT_Imm|OPS_32|OPTM_Far|OPA_JmpFar, 0, 0} },
-    { CPU_Not64, 0, 0, 0, 0, 1, {0xEA, 0, 0}, 3, 1,
-      {OPT_Imm|OPS_Any|OPTM_Far|OPA_JmpFar, 0, 0} },
-
+    /* Far indirect (through memory).  Needs explicit FAR override. */
     { CPU_Any, 0, 16, 0, 0, 1, {0xFF, 0, 0}, 5, 1,
       {OPT_Mem|OPS_16|OPTM_Far|OPA_EA, 0, 0} },
     { CPU_386, 0, 32, 0, 0, 1, {0xFF, 0, 0}, 5, 1,
@@ -1243,7 +1249,23 @@ static const x86_insn_info jmp_insn[] = {
     { CPU_EM64T|CPU_64, 0, 64, 0, 0, 1, {0xFF, 0, 0}, 5, 1,
       {OPT_Mem|OPS_64|OPTM_Far|OPA_EA, 0, 0} },
     { CPU_Any, 0, 0, 0, 0, 1, {0xFF, 0, 0}, 5, 1,
-      {OPT_Mem|OPS_Any|OPTM_Far|OPA_EA, 0, 0} }
+      {OPT_Mem|OPS_Any|OPTM_Far|OPA_EA, 0, 0} },
+
+    /* With explicit FAR override */
+    { CPU_Not64, 0, 16, 0, 0, 1, {0xEA, 0, 0}, 3, 1,
+      {OPT_Imm|OPS_16|OPTM_Far|OPA_JmpFar, 0, 0} },
+    { CPU_386|CPU_Not64, 0, 32, 0, 0, 1, {0xEA, 0, 0}, 3, 1,
+      {OPT_Imm|OPS_32|OPTM_Far|OPA_JmpFar, 0, 0} },
+    { CPU_Not64, 0, 0, 0, 0, 1, {0xEA, 0, 0}, 3, 1,
+      {OPT_Imm|OPS_Any|OPTM_Far|OPA_JmpFar, 0, 0} },
+
+    /* Since not caught by first ImmNotSegOff group, implicitly FAR. */
+    { CPU_Not64, 0, 16, 0, 0, 1, {0xEA, 0, 0}, 3, 1,
+      {OPT_Imm|OPS_16|OPA_JmpFar, 0, 0} },
+    { CPU_386|CPU_Not64, 0, 32, 0, 0, 1, {0xEA, 0, 0}, 3, 1,
+      {OPT_Imm|OPS_32|OPA_JmpFar, 0, 0} },
+    { CPU_Not64, 0, 0, 0, 0, 1, {0xEA, 0, 0}, 3, 1,
+      {OPT_Imm|OPS_Any|OPA_JmpFar, 0, 0} }
 };
 static const x86_insn_info retnf_insn[] = {
     { CPU_Not64, MOD_Op0Add, 0, 0, 0, 1,
@@ -2089,31 +2111,28 @@ x86_finalize_jmpfar(yasm_arch *arch, yasm_bytecode *bc,
 
     op = yasm_ops_first(operands);
 
-    switch (op->targetmod) {
-       case X86_FAR:
-           /* "FAR imm" target needs to become "seg imm:imm". */
-           if (yasm_value_finalize_expr(&jmpfar->offset,
-                                        yasm_expr_copy(op->data.val), 0)
-               || yasm_value_finalize_expr(&jmpfar->segment, op->data.val, 16))
-               yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-                              N_("jump target expression too complex"));
-           jmpfar->segment.seg_of = 1;
-           break;
-       case X86_FAR_SEGOFF:
-           /* SEG:OFF expression; split it. */
-           segment = yasm_expr_extract_segoff(&op->data.val);
-           if (!segment)
-               yasm_internal_error(N_("didn't get SEG:OFF expression in jmpfar"));
-           if (yasm_value_finalize_expr(&jmpfar->segment, segment, 16))
-               yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-                              N_("jump target segment too complex"));
-           if (yasm_value_finalize_expr(&jmpfar->offset, op->data.val, 0))
-               yasm_error_set(YASM_ERROR_TOO_COMPLEX,
-                              N_("jump target offset too complex"));
-           break;
-       default:
-           yasm_internal_error(N_("didn't get FAR expression in jmpfar"));
-    }
+    if (op->type == YASM_INSN__OPERAND_IMM &&
+       yasm_expr_is_op(op->data.val, YASM_EXPR_SEGOFF)) {
+       /* SEG:OFF expression; split it. */
+       segment = yasm_expr_extract_segoff(&op->data.val);
+       if (!segment)
+           yasm_internal_error(N_("didn't get SEG:OFF expression in jmpfar"));
+       if (yasm_value_finalize_expr(&jmpfar->segment, segment, 16))
+           yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+                          N_("jump target segment too complex"));
+       if (yasm_value_finalize_expr(&jmpfar->offset, op->data.val, 0))
+           yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+                          N_("jump target offset too complex"));
+    } else if (op->targetmod == X86_FAR) {
+       /* "FAR imm" target needs to become "seg imm:imm". */
+       if (yasm_value_finalize_expr(&jmpfar->offset,
+                                    yasm_expr_copy(op->data.val), 0)
+           || yasm_value_finalize_expr(&jmpfar->segment, op->data.val, 16))
+           yasm_error_set(YASM_ERROR_TOO_COMPLEX,
+                          N_("jump target expression too complex"));
+       jmpfar->segment.seg_of = 1;
+    } else
+       yasm_internal_error(N_("didn't get FAR expression in jmpfar"));
 
     yasm_x86__bc_apply_prefixes((x86_common *)jmpfar, NULL, num_prefixes,
                                prefixes);
@@ -2150,7 +2169,7 @@ x86_finalize_jmp(yasm_arch *arch, yasm_bytecode *bc, yasm_bytecode *prev_bc,
                       N_("jump target expression too complex"));
     if (jmp->target.seg_of || jmp->target.rshift || jmp->target.curpos_rel)
        yasm_error_set(YASM_ERROR_VALUE, N_("invalid jump target"));
-    jmp->target.curpos_rel = 1;
+    yasm_value_set_curpos_rel(&jmp->target, bc, 0);
 
     /* See if the user explicitly specified short/near/far. */
     switch ((int)(jinfo->operands[0] & OPTM_MASK)) {
@@ -2320,13 +2339,6 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
        }
     }
 
-    /* Look for SEG:OFF operands and apply X86_FAR_SEGOFF targetmod. */
-    for (i = 0, op = ops[0]; op; op = ops[++i]) {
-       if (op->type == YASM_INSN__OPERAND_IMM && op->targetmod == 0 &&
-           yasm_expr_is_op(op->data.val, YASM_EXPR_SEGOFF))
-           op->targetmod = X86_FAR_SEGOFF;
-    }
-
     /* Just do a simple linear search through the info array for a match.
      * First match wins.
      */
@@ -2543,6 +2555,12 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
                    } else
                        mismatch = 1;
                    break;
+               case OPT_ImmNotSegOff:
+                   if (op->type != YASM_INSN__OPERAND_IMM ||
+                       op->targetmod != 0 ||
+                       yasm_expr_is_op(op->data.val, YASM_EXPR_SEGOFF))
+                       mismatch = 1;
+                   break;
                default:
                    yasm_internal_error(N_("invalid operand type"));
            }
@@ -2560,7 +2578,9 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
                    /* Register size must exactly match */
                    if (yasm_x86__get_reg_size(arch, op->data.reg) != size)
                        mismatch = 1;
-               } else if ((info->operands[i] & OPT_MASK) == OPT_Imm
+               } else if (((info->operands[i] & OPT_MASK) == OPT_Imm
+                           || (info->operands[i] & OPT_MASK) == OPT_ImmNotSegOff
+                           || (info->operands[i] & OPT_MASK) == OPT_Imm1)
                    && (info->operands[i] & OPS_RMASK) != OPS_Relaxed
                    && (info->operands[i] & OPA_MASK) != OPA_JmpRel)
                    mismatch = 1;
@@ -2612,8 +2632,7 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
                        mismatch = 1;
                    break;
                case OPTM_Far:
-                   if (op->targetmod != X86_FAR &&
-                       op->targetmod != X86_FAR_SEGOFF)
+                   if (op->targetmod != X86_FAR)
                        mismatch = 1;
                    break;
                case OPTM_To:
index 9d9114eed021ec60fa667cf8685928c88b003251..17bdfab2184d3661c932ec565931f158f49b69a8 100644 (file)
@@ -95,7 +95,8 @@ typedef struct bin_objfmt_output_info {
     /*@dependent@*/ FILE *f;
     /*@only@*/ unsigned char *buf;
     /*@observer@*/ const yasm_section *sect;
-    unsigned long start;
+    unsigned long start;       /* what normal variables go against */
+    unsigned long abs_start;   /* what absolutes go against */
 } bin_objfmt_output_info;
 
 static /*@only@*/ yasm_expr *
@@ -169,6 +170,36 @@ bin_objfmt_output_value(yasm_value *value, unsigned char *buf, size_t destsize,
            return 0;
     }
 
+    /* Absolute value; handle it here as output_basic won't understand it */
+    if (yasm_symrec_is_abs(value->rel)) {
+       if (value->curpos_rel) {
+           /* Calculate value relative to current assembly position */
+           /*@only@*/ yasm_intnum *outval;
+           unsigned int valsize = value->size;
+           int retval = 0;
+
+           outval = yasm_intnum_create_uint(bc->offset + info->abs_start);
+           yasm_intnum_calc(outval, YASM_EXPR_NEG, NULL);
+
+           if (value->rshift > 0) {
+               /*@only@*/ yasm_intnum *shamt =
+                   yasm_intnum_create_uint((unsigned long)value->rshift);
+               yasm_intnum_calc(outval, YASM_EXPR_SHR, shamt);
+               yasm_intnum_destroy(shamt);
+           }
+           /* Add in absolute portion */
+           if (value->abs)
+               yasm_intnum_calc(outval, YASM_EXPR_ADD,
+                                yasm_expr_get_intnum(&value->abs, 1));
+           /* Output! */
+           if (yasm_arch_intnum_tobytes(info->objfmt_bin->arch, outval, buf,
+                                        destsize, valsize, 0, bc, warn))
+               retval = 1;
+           yasm_intnum_destroy(outval);
+           return retval;
+       }
+    }
+
     /* Couldn't output, assume it contains an external reference. */
     yasm_error_set(YASM_ERROR_GENERAL,
        N_("binary object format does not support external references"));
@@ -264,6 +295,7 @@ bin_objfmt_output(yasm_objfmt *objfmt, FILE *f, /*@unused@*/ int all_syms,
     }
     start = yasm_intnum_get_uint(startnum);
     yasm_expr_destroy(startexpr);
+    info.abs_start = start;
     textstart = start;
 
     /* Align .data and .bss (if present) by adjusting their starts. */
index a2620ee5907bb8638dc6a4e65fbcc254fb973137..1251308c7de860f6bdf601ce0f071031a6f69762 100644 (file)
@@ -8,6 +8,8 @@ EXTRA_DIST += modules/objfmts/bin/tests/abs.hex
 EXTRA_DIST += modules/objfmts/bin/tests/bigorg.asm
 EXTRA_DIST += modules/objfmts/bin/tests/bigorg.hex
 EXTRA_DIST += modules/objfmts/bin/tests/bigorg.errwarn
+EXTRA_DIST += modules/objfmts/bin/tests/bin-farabs.asm
+EXTRA_DIST += modules/objfmts/bin/tests/bin-farabs.hex
 EXTRA_DIST += modules/objfmts/bin/tests/bintest.asm
 EXTRA_DIST += modules/objfmts/bin/tests/bintest.hex
 EXTRA_DIST += modules/objfmts/bin/tests/float-err.asm
diff --git a/modules/objfmts/bin/tests/bin-farabs.asm b/modules/objfmts/bin/tests/bin-farabs.asm
new file mode 100644 (file)
index 0000000..e26bcbc
--- /dev/null
@@ -0,0 +1,51 @@
+keybuf equ 0040h:001Eh
+
+absolute 5000h
+label:
+
+section .text
+absval equ 1000h
+
+org 0x100
+; Using seg should yield the segment part.
+mov ax, seg keybuf
+mov ax, seg (0040h:001Eh)      ; NASM doesn't understand this syntax
+mov es, ax
+
+; Use without seg should yield just the offset part.
+mov bx, keybuf
+mov bx, 0040h:001Eh            ; Illegal in NASM ("invalid combination...")
+
+; Each of the below pairs should be equivalent (and legal) in Yasm.
+; There are some differences from NASM here!
+
+; Direct far jump.
+jmp keybuf             ; Results in a near jump in NASM
+jmp 0040h:001Eh                ; But Yasm sees the equ value as equivalent to this
+
+; Force near (non-far) jump (just offset, no segment).
+jmp near keybuf
+jmp near 0040h:001Eh   ; Illegal in NASM ("mismatch in operand sizes")
+
+; A couple of jumps to "normal" absolute addresses.
+jmp 0x1e
+jmp 0
+jmp absval
+jmp label
+
+; Non-absolute jump
+label2:
+jmp label2
+
+; Non-relative access
+mov ax, [0]
+mov ax, [label]
+
+; Direct far, explicitly.
+jmp far keybuf         ; Illegal in NASM ("value referenced by FAR is not relocatable")
+jmp far 0040h:001Eh    ; Illegal in NASM ("mismatch in operand sizes")
+
+keybufptr:
+dw keybuf      ; offset part
+dw seg keybuf  ; segment part
+
diff --git a/modules/objfmts/bin/tests/bin-farabs.hex b/modules/objfmts/bin/tests/bin-farabs.hex
new file mode 100644 (file)
index 0000000..6f626b5
--- /dev/null
@@ -0,0 +1,64 @@
+b8 
+40 
+00 
+b8 
+40 
+00 
+8e 
+c0 
+bb 
+1e 
+00 
+bb 
+1e 
+00 
+ea 
+1e 
+00 
+40 
+00 
+ea 
+1e 
+00 
+40 
+00 
+e9 
+03 
+ff 
+e9 
+00 
+ff 
+e9 
+fd 
+fe 
+e9 
+dc 
+fe 
+e9 
+d9 
+0e 
+e9 
+d6 
+4e 
+eb 
+fe 
+a1 
+00 
+00 
+a1 
+00 
+50 
+ea 
+1e 
+00 
+40 
+00 
+ea 
+1e 
+00 
+40 
+00 
+1e 
+00 
+40 
+00 
index e82b574dc58393c2b688cfb1db9494617e7a1177..c5947c5a2cfc4e25835c97a89db7eabcbebf86d9 100644 (file)
@@ -123,14 +123,19 @@ elf_objfmt_append_local_sym(yasm_symrec *sym, /*@null@*/ void *d)
 
     assert(info != NULL);
 
-    if (!yasm_symrec_get_label(sym, &precbc))
-       return 0;
-    sect = yasm_bc_get_section(precbc);
+    if (!yasm_symrec_get_label(sym, &precbc)) {
+       if (!yasm_symrec_is_abs(sym))   /* let absolute symbol into output */
+           return 0;
+       precbc = NULL;
+    }
+
+    if (precbc)
+       sect = yasm_bc_get_section(precbc);
 
     entry = yasm_symrec_get_data(sym, &elf_symrec_data);
     if (!entry || !elf_sym_in_table(entry)) {
        int is_sect = 0;
-       if (!yasm_section_is_absolute(sect) &&
+       if (sect && !yasm_section_is_absolute(sect) &&
            strcmp(yasm_symrec_get_name(sym), yasm_section_get_name(sect))==0)
            is_sect = 1;
 
index ce1e9dcbcb79196504b0875279255d2ddc708e02..5961c6a1633ab97fe4febf43859185f447f99c59 100644 (file)
@@ -465,9 +465,8 @@ elf_symtab_write_to_file(FILE *f, elf_symtab_head *symtab,
                    yasm_error_set(YASM_ERROR_VALUE,
                                   N_("EQU value not an integer expression"));
                    yasm_errwarn_propagate(errwarns, equ_expr->line);
-               }
-
-               value_intn = yasm_intnum_copy(equ_intn);
+               } else
+                   value_intn = yasm_intnum_copy(equ_intn);
                entry->index = SHN_ABS;
                yasm_expr_destroy(equ_expr);
            }
index 716c99c100154b82c8754139b886ab9b9b60b140..e6d485f31d2c04e3d45ac656d4c5462d164f33f5 100644 (file)
@@ -15,6 +15,8 @@ EXTRA_DIST += modules/objfmts/elf/tests/elfabssect.asm
 EXTRA_DIST += modules/objfmts/elf/tests/elfabssect.hex
 EXTRA_DIST += modules/objfmts/elf/tests/elfcond.asm
 EXTRA_DIST += modules/objfmts/elf/tests/elfcond.hex
+EXTRA_DIST += modules/objfmts/elf/tests/elfequabs.asm
+EXTRA_DIST += modules/objfmts/elf/tests/elfequabs.hex
 EXTRA_DIST += modules/objfmts/elf/tests/elfglobal.asm
 EXTRA_DIST += modules/objfmts/elf/tests/elfglobal.hex
 EXTRA_DIST += modules/objfmts/elf/tests/elfglobext.asm
index cf0cb3bafa1134b706d26138e8d6fbd12426f491..0c9c4348588842a372be5aa21bcb3d1ca67cbed6 100644 (file)
@@ -7,3 +7,6 @@ teststruc:
 teststruc_size:
 %line 3+0 elfabssect.asm
 [section .text]
+;global teststruc
+global teststruc.testlabel
+global teststruc_size
index 7b34fd08b17e0dfec83cc38a31e6f6b602ba9463..65d3974afe315b089f3f482a469ab2ac0a2cd99d 100644 (file)
@@ -30,7 +30,7 @@
 00 
 00 
 00 
-d
+e
 00 
 00 
 00 
@@ -101,6 +101,42 @@ d0
 00 
 2d 
 00 
+74 
+65 
+73 
+74 
+73 
+74 
+72 
+75 
+63 
+2e 
+74 
+65 
+73 
+74 
+6c 
+61 
+62 
+65 
+6c 
+00 
+74 
+65 
+73 
+74 
+73 
+74 
+72 
+75 
+63 
+5f 
+73 
+69 
+7a 
+65 
+00 
+00 
 00 
 00 
 00 
@@ -138,8 +174,6 @@ ff
 00 
 00 
 00 
-02 
-00 
 00 
 00 
 00 
@@ -148,10 +182,11 @@ ff
 00 
 00 
 00 
-f1 
-ff 
+03 
 00 
+04 
 00 
+03 
 00 
 00 
 00 
@@ -163,12 +198,15 @@ ff
 00 
 00 
 00 
+10 
 00 
 f1 
 ff 
+17 
 00 
 00 
 00 
+02 
 00 
 00 
 00 
@@ -176,9 +214,7 @@ ff
 00 
 00 
 00 
-00 
-00 
-00 
+10 
 00 
 f1 
 ff 
@@ -194,26 +230,6 @@ ff
 00 
 00 
 00 
-03 
-00 
-04 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
 00 
 00 
 00 
@@ -306,7 +322,7 @@ ff
 00 
 00 
 00 
-03 
+26 
 00 
 00 
 00 
@@ -342,11 +358,11 @@ ff
 00 
 00 
 00 
-68 
+8c 
 00 
 00 
 00 
-6
+5
 00 
 00 
 00 
@@ -354,7 +370,7 @@ ff
 00 
 00 
 00 
-06 
+03 
 00 
 00 
 00 
diff --git a/modules/objfmts/elf/tests/elfequabs.asm b/modules/objfmts/elf/tests/elfequabs.asm
new file mode 100644 (file)
index 0000000..39f62a2
--- /dev/null
@@ -0,0 +1,10 @@
+global label
+absolute 5000h
+label:
+
+section .text
+global absval
+absval equ 1000h
+
+jmp absval
+jmp label
diff --git a/modules/objfmts/elf/tests/elfequabs.hex b/modules/objfmts/elf/tests/elfequabs.hex
new file mode 100644 (file)
index 0000000..514f7d2
--- /dev/null
@@ -0,0 +1,496 @@
+7f 
+45 
+4c 
+46 
+01 
+01 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+03 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+34 
+00 
+00 
+00 
+00 
+00 
+28 
+00 
+06 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+e9 
+fc 
+0f 
+00 
+00 
+e9 
+fc 
+4f 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+02 
+02 
+00 
+00 
+06 
+00 
+00 
+00 
+02 
+02 
+00 
+00 
+00 
+2e 
+74 
+65 
+78 
+74 
+00 
+2e 
+72 
+65 
+6c 
+2e 
+74 
+65 
+78 
+74 
+00 
+2e 
+73 
+74 
+72 
+74 
+61 
+62 
+00 
+2e 
+73 
+79 
+6d 
+74 
+61 
+62 
+00 
+2e 
+73 
+68 
+73 
+74 
+72 
+74 
+61 
+62 
+00 
+00 
+00 
+2d 
+00 
+6c 
+61 
+62 
+65 
+6c 
+00 
+61 
+62 
+73 
+76 
+61 
+6c 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+04 
+00 
+f1 
+ff 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+f1 
+ff 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+04 
+00 
+03 
+00 
+00 
+00 
+00 
+50 
+00 
+00 
+00 
+00 
+00 
+00 
+10 
+00 
+f1 
+ff 
+09 
+00 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+00 
+00 
+00 
+10 
+00 
+f1 
+ff 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+21 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+5c 
+00 
+00 
+00 
+2b 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+11 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+88 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+19 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+98 
+00 
+00 
+00 
+60 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+06 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+40 
+00 
+00 
+00 
+0a 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+07 
+00 
+00 
+00 
+09 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+4c 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+08 
+00 
+00 
+00 
index c4971e1f8002265ace24ffc45f1c6cdbbbe88fe5..a5f6e1ad346c4d2edacf00a1618a0c79cf654395 100644 (file)
@@ -30,8 +30,8 @@
 00 
 00 
 00 
-2
-16 
+b
+10 
 00 
 00 
 00 
@@ -75,8 +75,8 @@ bf
 00 
 00 
 01 
-01 
-01 
+aa 
+00 
 00 
 00 
 2e 
@@ -3678,16 +3678,11 @@ ff
 00 
 00 
 00 
+03 
 00 
+04 
 00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
+03 
 00 
 00 
 00 
@@ -3696,14 +3691,14 @@ ff
 00 
 00 
 00 
-f1 
-ff 
 00 
 00 
 00 
+10 
 00 
 00 
 00 
+08 
 00 
 00 
 00 
@@ -3712,14 +3707,14 @@ ff
 00 
 00 
 00 
-f1 
-ff 
 00 
 00 
 00 
+10 
 00 
 00 
 00 
+0e 
 00 
 00 
 00 
@@ -3728,14 +3723,14 @@ ff
 00 
 00 
 00 
-f1 
-ff 
 00 
 00 
 00 
+10 
 00 
 00 
 00 
+16 
 00 
 00 
 00 
@@ -3744,14 +3739,14 @@ ff
 00 
 00 
 00 
-f1 
-ff 
 00 
 00 
 00 
+10 
 00 
 00 
 00 
+22 
 00 
 00 
 00 
@@ -3760,14 +3755,14 @@ ff
 00 
 00 
 00 
-f1 
-ff 
 00 
 00 
 00 
+10 
 00 
 00 
 00 
+2d 
 00 
 00 
 00 
@@ -3776,14 +3771,14 @@ ff
 00 
 00 
 00 
-f1 
-ff 
 00 
 00 
 00 
+10 
 00 
 00 
 00 
+43 
 00 
 00 
 00 
@@ -3792,14 +3787,14 @@ ff
 00 
 00 
 00 
-f1 
-ff 
 00 
 00 
 00 
+10 
 00 
 00 
 00 
+59 
 00 
 00 
 00 
@@ -3808,14 +3803,14 @@ ff
 00 
 00 
 00 
-f1 
-ff 
 00 
 00 
 00 
+10 
 00 
 00 
 00 
+76 
 00 
 00 
 00 
@@ -3824,14 +3819,14 @@ ff
 00 
 00 
 00 
-f1 
-ff 
 00 
 00 
 00 
+10 
 00 
 00 
 00 
+87 
 00 
 00 
 00 
@@ -3840,14 +3835,14 @@ ff
 00 
 00 
 00 
-f1 
-ff 
 00 
 00 
 00 
+10 
 00 
 00 
 00 
+99 
 00 
 00 
 00 
@@ -3856,14 +3851,14 @@ ff
 00 
 00 
 00 
-f1 
-ff 
 00 
 00 
 00 
+10 
 00 
 00 
 00 
+ac 
 00 
 00 
 00 
@@ -3872,14 +3867,14 @@ ff
 00 
 00 
 00 
-f1 
-ff 
 00 
 00 
 00 
+10 
 00 
 00 
 00 
+c0 
 00 
 00 
 00 
@@ -3888,14 +3883,14 @@ ff
 00 
 00 
 00 
-f1 
-ff 
 00 
 00 
 00 
+10 
 00 
 00 
 00 
+d4 
 00 
 00 
 00 
@@ -3904,14 +3899,14 @@ ff
 00 
 00 
 00 
-f1 
-ff 
 00 
 00 
 00 
+10 
 00 
 00 
 00 
+e9 
 00 
 00 
 00 
@@ -3920,14 +3915,15 @@ ff
 00 
 00 
 00 
-f1 
-ff 
 00 
 00 
 00 
+10 
 00 
 00 
 00 
+04 
+01 
 00 
 00 
 00 
@@ -3936,15 +3932,17 @@ ff
 00 
 00 
 00 
-f1 
-ff 
 00 
 00 
+10 
 00 
 00 
 00 
+20 
+01 
 00 
 00 
+05 
 00 
 00 
 00 
@@ -3952,10 +3950,12 @@ ff
 00 
 00 
 00 
-f1 
-ff 
+10 
 00 
+04 
 00 
+3f 
+01 
 00 
 00 
 00 
@@ -3966,13 +3966,15 @@ ff
 00 
 00 
 00 
+10 
 00 
 00 
-f1 
-ff 
 00 
+5e 
+01 
 00 
 00 
+05 
 00 
 00 
 00 
@@ -3980,12 +3982,15 @@ ff
 00 
 00 
 00 
+10 
 00 
+04 
 00 
+7b 
+01 
 00 
 00 
-f1 
-ff 
+05 
 00 
 00 
 00 
@@ -3993,36 +3998,47 @@ ff
 00 
 00 
 00 
+10 
 00 
+04 
 00 
+98 
+01 
 00 
 00 
+05 
 00 
 00 
 00 
-f1 
-ff 
 00 
 00 
 00 
 00 
+10 
 00 
+04 
 00 
+b5 
+01 
 00 
 00 
+05 
 00 
 00 
 00 
 00 
 00 
 00 
-f1 
-ff 
 00 
+10 
 00 
+04 
 00 
+d3 
+01 
 00 
 00 
+05 
 00 
 00 
 00 
@@ -4030,26 +4046,15 @@ ff
 00 
 00 
 00 
+10 
 00 
+04 
 00 
 f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
+01 
 00 
 00 
-f1 
-ff 
+05 
 00 
 00 
 00 
@@ -4057,36 +4062,47 @@ ff
 00 
 00 
 00 
+10 
 00 
+04 
 00 
+13 
+02 
 00 
 00 
+05 
 00 
 00 
 00 
-f1 
-ff 
 00 
 00 
 00 
 00 
+10 
 00 
+04 
 00 
+2f 
+02 
 00 
 00 
+05 
 00 
 00 
 00 
 00 
 00 
 00 
-f1 
-ff 
 00 
+10 
 00 
+04 
 00 
+4d 
+02 
 00 
 00 
+05 
 00 
 00 
 00 
@@ -4094,12 +4110,15 @@ ff
 00 
 00 
 00 
+10 
 00 
+04 
 00 
-f1 
-ff 
+6b 
+02 
 00 
 00 
+05 
 00 
 00 
 00 
@@ -4107,36 +4126,47 @@ ff
 00 
 00 
 00 
+10 
 00 
+04 
 00 
+87 
+02 
 00 
 00 
+05 
 00 
-f1 
-ff 
 00 
 00 
 00 
 00 
 00 
 00 
+10 
 00 
+04 
 00 
+a4 
+02 
 00 
 00 
+05 
 00 
 00 
 00 
 00 
-f1 
-ff 
 00 
 00 
 00 
+10 
 00 
+04 
 00 
+c1 
+02 
 00 
 00 
+05 
 00 
 00 
 00 
@@ -4144,10 +4174,12 @@ ff
 00 
 00 
 00 
-f1 
-ff 
+10 
 00 
+04 
 00 
+e2 
+02 
 00 
 00 
 00 
@@ -4158,12 +4190,15 @@ ff
 00 
 00 
 00 
+10 
 00 
+04 
 00 
-f
-ff 
+0
+03 
 00 
 00 
+05 
 00 
 00 
 00 
@@ -4171,36 +4206,47 @@ ff
 00 
 00 
 00 
+10 
 00 
+04 
 00 
+22 
+03 
 00 
 00 
+05 
 00 
-f1 
-ff 
 00 
 00 
 00 
 00 
 00 
 00 
+10 
 00 
+04 
 00 
+33 
+03 
 00 
 00 
+05 
 00 
 00 
 00 
 00 
-f1 
-ff 
 00 
 00 
 00 
+10 
 00 
+04 
 00 
+45 
+03 
 00 
 00 
+05 
 00 
 00 
 00 
@@ -4208,9 +4254,9 @@ ff
 00 
 00 
 00 
-f1 
-ff 
+10 
 00 
+04 
 00 
 00 
 00 
@@ -4224,8 +4270,6 @@ ff
 00 
 00 
 00 
-f1 
-ff 
 00 
 00 
 00 
@@ -4240,8 +4284,6 @@ ff
 00 
 00 
 00 
-f1 
-ff 
 00 
 00 
 00 
@@ -4256,8 +4298,6 @@ ff
 00 
 00 
 00 
-f1 
-ff 
 00 
 00 
 00 
@@ -4270,11 +4310,11 @@ ff
 00 
 00 
 00 
+21 
 00 
 00 
-f1 
-ff 
 00 
+03 
 00 
 00 
 00 
@@ -4286,11 +4326,11 @@ ff
 00 
 00 
 00 
+50 
 00 
 00 
-f1 
-ff 
 00 
+2b 
 00 
 00 
 00 
@@ -4304,40 +4344,39 @@ ff
 00 
 00 
 00 
-f1 
-ff 
 00 
 00 
 00 
 00 
 00 
 00 
+11 
 00 
 00 
 00 
+03 
 00 
 00 
 00 
 00 
 00 
-f1 
-ff 
 00 
 00 
 00 
 00 
 00 
 00 
+7c 
 00 
 00 
 00 
+56 
+03 
 00 
 00 
 00 
 00 
 00 
-f1 
-ff 
 00 
 00 
 00 
@@ -4351,11 +4390,11 @@ ff
 00 
 00 
 00 
+19 
 00 
-f1 
-ff 
 00 
 00 
+02 
 00 
 00 
 00 
 00 
 00 
 00 
+d4 
+03 
 00 
-f1 
-ff 
 00 
+d0 
+0c 
 00 
 00 
+02 
 00 
 00 
 00 
+a9 
 00 
 00 
 00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-f1 
-ff 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-03 
-00 
-04 
-00 
-03 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-00 
-00 
-08 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-00 
-00 
-0e 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-00 
-00 
-16 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-00 
-00 
-22 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-00 
-00 
-2d 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-00 
-00 
-43 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-00 
-00 
-59 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-00 
-00 
-76 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-00 
-00 
-87 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-00 
-00 
-99 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-00 
-00 
-ac 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-00 
-00 
-c0 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-00 
-00 
-d4 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-00 
-00 
-e9 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-00 
-00 
-04 
-01 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-00 
-00 
-20 
-01 
-00 
-00 
-05 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-04 
-00 
-3f 
-01 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-00 
-00 
-5e 
-01 
-00 
-00 
-05 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-04 
-00 
-7b 
-01 
-00 
-00 
-05 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-04 
-00 
-98 
-01 
-00 
-00 
-05 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-04 
-00 
-b5 
-01 
-00 
-00 
-05 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-04 
-00 
-d3 
-01 
-00 
-00 
-05 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-04 
-00 
-f1 
-01 
-00 
-00 
-05 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-04 
-00 
-13 
-02 
-00 
-00 
-05 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-04 
-00 
-2f 
-02 
-00 
-00 
-05 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-04 
-00 
-4d 
-02 
-00 
-00 
-05 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-04 
-00 
-6b 
-02 
-00 
-00 
-05 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-04 
-00 
-87 
-02 
-00 
-00 
-05 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-04 
-00 
-a4 
-02 
-00 
-00 
-05 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-04 
-00 
-c1 
-02 
-00 
-00 
-05 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-04 
-00 
-e2 
-02 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-04 
-00 
-01 
-03 
-00 
-00 
-05 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-04 
-00 
-22 
-03 
-00 
-00 
-05 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-04 
-00 
-33 
-03 
-00 
-00 
-05 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-04 
-00 
-45 
-03 
-00 
-00 
-05 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-10 
-00 
-04 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-21 
-00 
-00 
-00 
-03 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-50 
-00 
-00 
-00 
-2b 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-11 
-00 
-00 
-00 
-03 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-7c 
-00 
-00 
-00 
-56 
-03 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-19 
-00 
-00 
-00 
-02 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-00 
-d4 
-03 
-00 
-00 
-40 
-12 
-00 
-00 
-02 
-00 
-00 
-00 
-00 
-01 
-00 
-00 
 04 
 00 
 00