]> granicus.if.org Git - yasm/commitdiff
Take [1423] to the next logical step by supporting the general case of
authorPeter Johnson <peter@tortall.net>
Sun, 10 Dec 2006 07:05:06 +0000 (07:05 -0000)
committerPeter Johnson <peter@tortall.net>
Sun, 10 Dec 2006 07:05:06 +0000 (07:05 -0000)
(sym in other section)-(sym in this section) rather than just
(sym in other section)-(curpos) (e.g. sym-$).  Unfortunately supporting
this required precbc to be flowed down to the value_finalize functions,
but it's relatively reasonable to do so, as all of the _finalize() routines
have access to precbc.

Reported by: Peter Tanski <peter_tanski@cox.net>

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

16 files changed:
libyasm/bc-data.c
libyasm/bc-incbin.c
libyasm/bc-insn.c
libyasm/bc-reserve.c
libyasm/bytecode.c
libyasm/bytecode.h
libyasm/value.c
libyasm/value.h
modules/arch/x86/x86arch.h
modules/arch/x86/x86bc.c
modules/arch/x86/x86id.c
modules/objfmts/elf/tests/gas64/Makefile.inc
modules/objfmts/elf/tests/gas64/crosssect.asm [new file with mode: 0644]
modules/objfmts/elf/tests/gas64/crosssect.hex [new file with mode: 0644]
tools/python-yasm/bytecode.pxi
tools/python-yasm/value.pxi

index 6e025c53f272d9dd18230b2f7b99cea26f05c43f..92b1606083bb391399a0130d8860b32a0a9e17c0 100644 (file)
@@ -108,7 +108,7 @@ bc_data_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
     STAILQ_FOREACH(dv, &bc_data->datahead, link) {
        switch (dv->type) {
            case DV_VALUE:
-               if (yasm_value_finalize(&dv->data.val)) {
+               if (yasm_value_finalize(&dv->data.val, prev_bc)) {
                    yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                                   N_("data expression too complex"));
                    return;
index 9e6e7b3719cad36eb51ea9d824c2175ff4ed466f..1c51764e5ccb4a433f5fd1b52a16e7e405e61551 100644 (file)
@@ -111,7 +111,7 @@ bc_incbin_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
     bytecode_incbin *incbin = (bytecode_incbin *)bc->contents;
     yasm_value val;
 
-    if (yasm_value_finalize_expr(&val, incbin->start, 0))
+    if (yasm_value_finalize_expr(&val, incbin->start, prev_bc, 0))
        yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                       N_("start expression too complex"));
     else if (val.rel)
@@ -119,7 +119,7 @@ bc_incbin_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
                       N_("start expression not absolute"));
     incbin->start = val.abs;
 
-    if (yasm_value_finalize_expr(&val, incbin->maxlen, 0))
+    if (yasm_value_finalize_expr(&val, incbin->maxlen, prev_bc, 0))
        yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                       N_("maximum length expression too complex"));
     else if (val.rel)
index d6dafb226faa8ba1735e7b052c5eda773da68ec3..cb8aed68857c9fcdee8896ffb79782b64f48cfb9 100644 (file)
@@ -77,11 +77,11 @@ static const yasm_bytecode_callback bc_insn_callback = {
 
 
 yasm_immval *
-yasm_imm_create_expr(yasm_expr *e)
+yasm_imm_create_expr(yasm_expr *e, yasm_bytecode *precbc)
 {
     yasm_immval *im = yasm_xmalloc(sizeof(yasm_immval));
 
-    if (yasm_value_finalize_expr(&im->val, e, 0))
+    if (yasm_value_finalize_expr(&im->val, e, precbc, 0))
        yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                       N_("immediate expression too complex"));
     im->sign = 0;
index cc0ef845234ba61873495e5bba2f06954120c6a8..86be7b86b09f509ca638e4247a6db3e450f96adb 100644 (file)
@@ -92,7 +92,7 @@ bc_reserve_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
     bytecode_reserve *reserve = (bytecode_reserve *)bc->contents;
     yasm_value val;
 
-    if (yasm_value_finalize_expr(&val, reserve->numitems, 0))
+    if (yasm_value_finalize_expr(&val, reserve->numitems, prev_bc, 0))
        yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                       N_("reserve expression too complex"));
     else if (val.rel)
index 7bcafcc21d0e576bd0aa32f3d2e5f18bf4e1afad..27ccfdc938115a150df679f1c54531148b698aa1 100644 (file)
@@ -161,7 +161,7 @@ yasm_bc_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
     if (bc->multiple) {
        yasm_value val;
 
-       if (yasm_value_finalize_expr(&val, bc->multiple, 0))
+       if (yasm_value_finalize_expr(&val, bc->multiple, prev_bc, 0))
            yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                           N_("multiple expression too complex"));
        else if (val.rel)
index 7d277192f082e77c26f1395f6ea08e55db4e05ab..1a4fb6de01a4e99422463f83efd33b94023b03e6 100644 (file)
@@ -90,10 +90,12 @@ typedef struct yasm_datavalhead yasm_datavalhead;
 #endif
 
 /** Create an immediate value from an expression.
- * \param e    expression (kept, do not free).
+ * \param e            expression (kept, do not free).
+ * \param precbc       previous bytecode to bytecode containing immediate
  * \return Newly allocated immediate value.
  */
-/*@only@*/ yasm_immval *yasm_imm_create_expr(/*@keep@*/ yasm_expr *e);
+/*@only@*/ yasm_immval *yasm_imm_create_expr(/*@keep@*/ yasm_expr *e,
+                                            /*@null@*/ yasm_bytecode *precbc);
 
 /** Get the displacement portion of an effective address.
  * \param ea   effective address
index 47cf6293d66ead063b3d93c0e4dc7575c5827ce7..fa31f87d1296398acfe95180fa9dbd47251fd663 100644 (file)
@@ -115,7 +115,8 @@ yasm_value_set_curpos_rel(yasm_value *value, yasm_bytecode *bc,
 }
 
 static int
-value_finalize_scan(yasm_value *value, yasm_expr *e, int ssym_not_ok)
+value_finalize_scan(yasm_value *value, yasm_expr *e,
+                   /*@null@*/ yasm_bytecode *expr_precbc, int ssym_not_ok)
 {
     int i;
     /*@dependent@*/ yasm_section *sect;
@@ -174,7 +175,8 @@ value_finalize_scan(yasm_value *value, yasm_expr *e, int ssym_not_ok)
 
                if (sube->op != YASM_EXPR_MUL || sube->numterms != 2) {
                    /* recurse instead */
-                   if (value_finalize_scan(value, sube, ssym_not_ok))
+                   if (value_finalize_scan(value, sube, expr_precbc,
+                                           ssym_not_ok))
                        return 1;
                    continue;
                }
@@ -188,19 +190,22 @@ value_finalize_scan(yasm_value *value, yasm_expr *e, int ssym_not_ok)
                    sym = sube->terms[0].data.sym;
                    intn = sube->terms[1].data.intn;
                } else {
-                   if (value_finalize_scan(value, sube, ssym_not_ok))
+                   if (value_finalize_scan(value, sube, expr_precbc,
+                                           ssym_not_ok))
                        return 1;
                    continue;
                }
 
                if (!yasm_intnum_is_neg1(intn)) {
-                   if (value_finalize_scan(value, sube, ssym_not_ok))
+                   if (value_finalize_scan(value, sube, expr_precbc,
+                                           ssym_not_ok))
                        return 1;
                    continue;
                }
 
                if (!yasm_symrec_get_label(sym, &precbc)) {
-                   if (value_finalize_scan(value, sube, ssym_not_ok))
+                   if (value_finalize_scan(value, sube, expr_precbc,
+                                           ssym_not_ok))
                        return 1;
                    continue;
                }
@@ -225,11 +230,19 @@ value_finalize_scan(yasm_value *value, yasm_expr *e, int ssym_not_ok)
                 * unused symrec terms in other segments and generate
                 * a curpos-relative reloc.
                 *
+                * Similarly, handle -1*symrec in other segment via the
+                * following transformation:
+                * other-this = (other-.)+(.-this)
+                * We can only do this transformation if "this" is in
+                * this expr's segment.
+                *
                 * Don't do this if we've already become curpos-relative.
                 * The unmatched symrec will be caught below.
                 */
-               if (j == e->numterms && yasm_symrec_is_curpos(sym)
-                   && !value->curpos_rel) {
+               if (j == e->numterms && !value->curpos_rel
+                   && (yasm_symrec_is_curpos(sym)
+                       || (expr_precbc
+                           && sect2 == yasm_bc_get_section(expr_precbc)))) {
                    for (j=0; j<e->numterms; j++) {
                        if (e->terms[j].type == YASM_EXPR_SYM
                            && yasm_symrec_get_label(e->terms[j].data.sym,
@@ -242,17 +255,30 @@ value_finalize_scan(yasm_value *value, yasm_expr *e, int ssym_not_ok)
                                return 1;
                            value->rel = e->terms[j].data.sym;
                            value->curpos_rel = 1;
-                           /* Replace both symrec portions with 0 */
-                           yasm_expr_destroy(sube);
-                           e->terms[i].type = YASM_EXPR_INT;
-                           e->terms[i].data.intn = yasm_intnum_create_uint(0);
-                           e->terms[j].type = YASM_EXPR_INT;
-                           e->terms[j].data.intn = yasm_intnum_create_uint(0);
+                           if (yasm_symrec_is_curpos(sym)) {
+                               /* Replace both symrec portions with 0 */
+                               yasm_expr_destroy(sube);
+                               e->terms[i].type = YASM_EXPR_INT;
+                               e->terms[i].data.intn =
+                                   yasm_intnum_create_uint(0);
+                               e->terms[j].type = YASM_EXPR_INT;
+                               e->terms[j].data.intn =
+                                   yasm_intnum_create_uint(0);
+                           } else {
+                               /* Replace positive portion with curpos */
+                               yasm_symtab *symtab =
+                                   yasm_object_get_symtab(
+                                       yasm_section_get_object(sect2));
+                               e->terms[j].data.sym =
+                                   yasm_symtab_define_curpos
+                                   (symtab, ".", expr_precbc, e->line);
+                           }
                            break;      /* stop looking */
                        }
                    }
                }
 
+
                if (j == e->numterms)
                    return 1;   /* We didn't find a match! */
            }
@@ -287,7 +313,8 @@ value_finalize_scan(yasm_value *value, yasm_expr *e, int ssym_not_ok)
                case YASM_EXPR_SYM:
                    return 1;
                case YASM_EXPR_EXPR:
-                   if (value_finalize_scan(value, e->terms[1].data.expn, 1))
+                   if (value_finalize_scan(value, e->terms[1].data.expn,
+                                           expr_precbc, 1))
                        return 1;
                    break;
                default:
@@ -310,7 +337,7 @@ value_finalize_scan(yasm_value *value, yasm_expr *e, int ssym_not_ok)
                case YASM_EXPR_EXPR:
                    /* recurse */
                    if (value_finalize_scan(value, e->terms[0].data.expn,
-                                           ssym_not_ok))
+                                           expr_precbc, ssym_not_ok))
                        return 1;
                    break;
                default:
@@ -386,7 +413,7 @@ value_finalize_scan(yasm_value *value, yasm_expr *e, int ssym_not_ok)
                case YASM_EXPR_EXPR:
                    /* recurse */
                    return value_finalize_scan(value, e->terms[0].data.expn,
-                                              ssym_not_ok);
+                                              expr_precbc, ssym_not_ok);
                default:
                    break;  /* ignore */
            }
@@ -401,7 +428,8 @@ value_finalize_scan(yasm_value *value, yasm_expr *e, int ssym_not_ok)
                    case YASM_EXPR_EXPR:
                        /* recurse */
                        return value_finalize_scan(value,
-                                                  e->terms[i].data.expn, 1);
+                                                  e->terms[i].data.expn,
+                                                  expr_precbc, 1);
                    default:
                        break;
                }
@@ -413,7 +441,8 @@ value_finalize_scan(yasm_value *value, yasm_expr *e, int ssym_not_ok)
 }
 
 int
-yasm_value_finalize_expr(yasm_value *value, yasm_expr *e, unsigned int size)
+yasm_value_finalize_expr(yasm_value *value, yasm_expr *e,
+                        yasm_bytecode *precbc, unsigned int size)
 {
     if (!e) {
        yasm_value_initialize(value, NULL, size);
@@ -459,7 +488,7 @@ yasm_value_finalize_expr(yasm_value *value, yasm_expr *e, unsigned int size)
        }
     }
 
-    if (value_finalize_scan(value, value->abs, 0))
+    if (value_finalize_scan(value, value->abs, precbc, 0))
        return 1;
 
     value->abs = yasm_expr__level_tree(value->abs, 1, 1, 0, 0, NULL, NULL);
@@ -475,10 +504,10 @@ yasm_value_finalize_expr(yasm_value *value, yasm_expr *e, unsigned int size)
 }
 
 int
-yasm_value_finalize(yasm_value *value)
+yasm_value_finalize(yasm_value *value, yasm_bytecode *precbc)
 {
     unsigned int valsize = value->size;
-    return yasm_value_finalize_expr(value, value->abs, valsize);
+    return yasm_value_finalize_expr(value, value->abs, precbc, valsize);
 }
 
 yasm_intnum *
index 4c871073075bf2a757a7eef6502a6d4d67d14a7c..1f10465b75fe71ef35a6db1c1b28fd92adbe85cc 100644 (file)
@@ -86,9 +86,10 @@ void yasm_value_set_curpos_rel(yasm_value *value, yasm_bytecode *bc,
 /** Perform yasm_value_finalize_expr() on a value that already exists from
  * being initialized with yasm_value_initialize().
  * \param value                value
+ * \param precbc       previous bytecode to bytecode containing value
  * \return Nonzero if value could not be split.
  */
-int yasm_value_finalize(yasm_value *value);
+int yasm_value_finalize(yasm_value *value, /*@null@*/ yasm_bytecode *precbc);
 
 /** Break a #yasm_expr into a #yasm_value constituent parts.  Extracts
  * the relative portion of the value, SEG and WRT portions, and top-level
@@ -99,6 +100,7 @@ int yasm_value_finalize(yasm_value *value);
  * symrec offset within the absolute section.
  * \param value                value to store split portions into
  * \param e            expression input
+ * \param precbc       previous bytecode to bytecode containing expression
  * \param size         value size (in bits)
  * \return Nonzero if the expr could not be split into a value for some
  *         reason (e.g. the relative portion was not added, but multiplied,
@@ -110,6 +112,7 @@ int yasm_value_finalize(yasm_value *value);
  */
 int yasm_value_finalize_expr(/*@out@*/ yasm_value *value,
                             /*@null@*/ /*@kept@*/ yasm_expr *e,
+                            /*@null@*/ yasm_bytecode *precbc,
                             unsigned int size);
 
 /** Get value if absolute or PC-relative section-local relative.  Returns NULL
index a2487d09faf884c699223d9d34f9e0cb1be772d0..eeb6762d6211ef4e8d36aa4fd989fa0bfd2b4440 100644 (file)
@@ -155,7 +155,8 @@ typedef struct x86_effaddr {
                                   0xff if unknown */
 } x86_effaddr;
 
-void yasm_x86__ea_init(x86_effaddr *x86_ea, unsigned int spare);
+void yasm_x86__ea_init(x86_effaddr *x86_ea, unsigned int spare,
+                      yasm_bytecode *precbc);
 
 void yasm_x86__ea_set_disponly(x86_effaddr *x86_ea);
 x86_effaddr *yasm_x86__ea_create_reg(unsigned long reg, unsigned char *rex,
index 91544c8007ebb5691c208ba3d20854bcc56717db..93075fac9758d68c4340653471b712eab501ec57 100644 (file)
@@ -168,9 +168,10 @@ yasm_x86__bc_transform_jmpfar(yasm_bytecode *bc, x86_jmpfar *jmpfar)
 }
 
 void
-yasm_x86__ea_init(x86_effaddr *x86_ea, unsigned int spare)
+yasm_x86__ea_init(x86_effaddr *x86_ea, unsigned int spare,
+                 yasm_bytecode *precbc)
 {
-    if (yasm_value_finalize(&x86_ea->ea.disp))
+    if (yasm_value_finalize(&x86_ea->ea.disp, precbc))
        yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                       N_("effective address too complex"));
     x86_ea->modrm &= 0xC7;                 /* zero spare/reg bits */
index 4ea48781bfa9047d7c1a9b45e50c096c67dda790..f50157261258e461bc212c9a6f10e20cbd95580b 100644 (file)
@@ -2115,7 +2115,7 @@ x86_finalize_opcode(x86_opcode *opcode, const x86_insn_info *info)
 }
 
 static void
-x86_finalize_jmpfar(yasm_arch *arch, yasm_bytecode *bc,
+x86_finalize_jmpfar(yasm_arch *arch, yasm_bytecode *bc, yasm_bytecode *prev_bc,
                    const unsigned long data[4], int num_operands,
                    yasm_insn_operands *operands, int num_prefixes,
                    unsigned long **prefixes, const x86_insn_info *info)
@@ -2136,17 +2136,19 @@ x86_finalize_jmpfar(yasm_arch *arch, yasm_bytecode *bc,
        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))
+       if (yasm_value_finalize_expr(&jmpfar->segment, segment, prev_bc, 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))
+       if (yasm_value_finalize_expr(&jmpfar->offset, op->data.val, prev_bc,
+                                    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_expr_copy(op->data.val), prev_bc, 0)
+           || yasm_value_finalize_expr(&jmpfar->segment, op->data.val,
+                                       prev_bc, 16))
            yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                           N_("jump target expression too complex"));
        jmpfar->segment.seg_of = 1;
@@ -2183,7 +2185,7 @@ x86_finalize_jmp(yasm_arch *arch, yasm_bytecode *bc, yasm_bytecode *prev_bc,
 
     jmp = yasm_xmalloc(sizeof(x86_jmp));
     x86_finalize_common(&jmp->common, jinfo, mode_bits);
-    if (yasm_value_finalize_expr(&jmp->target, op->data.val, 0))
+    if (yasm_value_finalize_expr(&jmp->target, op->data.val, prev_bc, 0))
        yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                       N_("jump target expression too complex"));
     if (jmp->target.seg_of || jmp->target.rshift || jmp->target.curpos_rel)
@@ -2771,8 +2773,8 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
                return;
            case OPA_JmpFar:
                /* Shortcut to JmpFar */
-               x86_finalize_jmpfar(arch, bc, data, num_operands, operands,
-                                   num_prefixes, prefixes, info);
+               x86_finalize_jmpfar(arch, bc, prev_bc, data, num_operands,
+                                   operands, num_prefixes, prefixes, info);
                return;
        }
     }
@@ -2992,7 +2994,7 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
     }
 
     if (insn->x86_ea) {
-       yasm_x86__ea_init(insn->x86_ea, spare);
+       yasm_x86__ea_init(insn->x86_ea, spare, prev_bc);
        for (i=0; i<num_segregs; i++)
            yasm_ea_set_segreg(&insn->x86_ea->ea, segregs[i]);
     } else if (num_segregs > 0 && insn->special_prefix == 0) {
@@ -3004,7 +3006,7 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
        yasm_internal_error(N_("unhandled segment prefix"));
 
     if (imm) {
-       insn->imm = yasm_imm_create_expr(imm);
+       insn->imm = yasm_imm_create_expr(imm, prev_bc);
        insn->imm->val.size = im_len;
        insn->imm->sign = im_sign;
     } else
index 76d917c43042bc85528d66b1e9c01424b226f163..9be81625475e78751aec87a721d2224475e13d5d 100644 (file)
@@ -3,6 +3,8 @@
 TESTS += modules/objfmts/elf/tests/gas64/elf_gas64_test.sh
 
 EXTRA_DIST += modules/objfmts/elf/tests/gas64/elf_gas64_test.sh
+EXTRA_DIST += modules/objfmts/elf/tests/gas64/crosssect.asm
+EXTRA_DIST += modules/objfmts/elf/tests/gas64/crosssect.hex
 EXTRA_DIST += modules/objfmts/elf/tests/gas64/elf_gas64_curpos.asm
 EXTRA_DIST += modules/objfmts/elf/tests/gas64/elf_gas64_curpos.hex
 EXTRA_DIST += modules/objfmts/elf/tests/gas64/elf_gas64_reloc.asm
diff --git a/modules/objfmts/elf/tests/gas64/crosssect.asm b/modules/objfmts/elf/tests/gas64/crosssect.asm
new file mode 100644 (file)
index 0000000..4199979
--- /dev/null
@@ -0,0 +1,18 @@
+.section .rodata
+       .align 4
+_sys_srt:
+       .long 0
+
+.text
+       .align 4,0x90
+       .long _sys_srt-.
+       .long _sys_srt-_sys_info
+       #.long _sys_info-_sys_srt
+       #.long -(_sys_srt-_sys_info)
+       .long _sys_info-.
+       .long .-_sys_info
+       .long (_sys_srt-.)+(.-_sys_info) # GAS cannot handle this but we can
+       .long 0
+       .long 65558
+_sys_info:
+       .long 0
diff --git a/modules/objfmts/elf/tests/gas64/crosssect.hex b/modules/objfmts/elf/tests/gas64/crosssect.hex
new file mode 100644 (file)
index 0000000..4e15f93
--- /dev/null
@@ -0,0 +1,832 @@
+7f 
+45 
+4c 
+46 
+02 
+01 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+3e 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+80 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+40 
+00 
+00 
+00 
+00 
+00 
+40 
+00 
+07 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+14 
+00 
+00 
+00 
+f0 
+ff 
+ff 
+ff 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+16 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+e8 
+ff 
+ff 
+ff 
+ff 
+ff 
+ff 
+ff 
+10 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+f4 
+ff 
+ff 
+ff 
+ff 
+ff 
+ff 
+ff 
+00 
+00 
+00 
+00 
+00 
+2e 
+74 
+65 
+78 
+74 
+00 
+2e 
+72 
+6f 
+64 
+61 
+74 
+61 
+00 
+2e 
+72 
+65 
+6c 
+61 
+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 
+2d 
+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 
+01 
+00 
+00 
+00 
+04 
+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 
+04 
+00 
+1c 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+06 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+06 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+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 
+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 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+2a 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+ac 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+34 
+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 
+1a 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+e0 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+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 
+22 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+e4 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+90 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+06 
+00 
+00 
+00 
+08 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+18 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+06 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+40 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+20 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+0f 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+60 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+48 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+08 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+18 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+07 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+a8 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
index 913a408155396782d7e63758c2a8b800834dac23..50c72ae77bbef52c2d412a0e3415f499fe7fe16f 100644 (file)
@@ -47,7 +47,7 @@ cdef extern from "libyasm/bytecode.h":
     cdef struct yasm_dataval
     cdef struct yasm_datavalhead
 
-    cdef yasm_immval* yasm_imm_create_expr(yasm_expr *e)
+    cdef yasm_immval* yasm_imm_create_expr(yasm_expr *e, yasm_bytecode *precbc)
     cdef yasm_expr* yasm_ea_get_disp(yasm_effaddr *ea)
     cdef void yasm_ea_set_len(yasm_effaddr *ea, unsigned int len)
     cdef void yasm_ea_set_nosplit(yasm_effaddr *ea, unsigned int nosplit)
@@ -159,14 +159,21 @@ cdef object __make_immval(yasm_immval *imm):
 cdef class ImmVal:
     cdef yasm_immval *imm
 
-    def __new__(self, value):
+    def __new__(self, value, precbc=None):
         if isinstance(value, Expression):
-            self.imm = yasm_imm_create_expr(
-                    yasm_expr_copy((<Expression>value).expr))
+            if precbc is None:
+                self.imm = yasm_imm_create_expr(
+                    yasm_expr_copy((<Expression>value).expr), NULL)
+            elif isinstance(precbc, Bytecode):
+                self.imm = yasm_imm_create_expr(
+                    yasm_expr_copy((<Expression>value).expr),
+                    (<Bytecode>precbc).bc)
+            else:
+                raise TypeError("Invalid precbc type '%s'" % type(precbc))
         elif PyCObject_Check(value):
             self.imm = <yasm_immval *>__get_voidp(value, ImmVal)
         else:
-            raise TypeError
+            raise TypeError("Invalid value type '%s'" % type(value))
 
 cdef class Bytecode:
     cdef yasm_bytecode *bc
index 2e89c0f7750b73ce10ee7950a5261b1c4684b428..98ba14eae41a9485b19e54830cfd9fbe106f2637 100644 (file)
@@ -29,9 +29,9 @@ cdef extern from "libyasm/value.h":
     cdef void yasm_value_init_sym(yasm_value *value, yasm_symrec *sym,
                                   unsigned int size)
     cdef void yasm_value_delete(yasm_value *value)
-    cdef int yasm_value_finalize(yasm_value *value)
+    cdef int yasm_value_finalize(yasm_value *value, yasm_bytecode *precbc)
     cdef int yasm_value_finalize_expr(yasm_value *value, yasm_expr *e,
-                                      unsigned int size)
+                                      yasm_bytecode *precbc, unsigned int size)
     cdef yasm_intnum *yasm_value_get_intnum(yasm_value *value,
                                             yasm_bytecode *bc)
     cdef int yasm_value_output_basic(yasm_value *value, unsigned char *buf,
@@ -56,11 +56,16 @@ cdef class Value:
         elif isinstance(value, Symbol):
             yasm_value_init_sym(&self.value, (<Symbol>value).sym, sz)
         else:
-            raise ValueError("Invalid value type '%s'" % type(value))
+            raise TypeError("Invalid value type '%s'" % type(value))
 
     def __dealloc__(self):
         yasm_value_delete(&self.value)
 
-    def finalize(self):
-        return yasm_value_finalize(&self.value)
+    def finalize(self, precbc=None):
+        if precbc is None:
+            return yasm_value_finalize(&self.value, NULL)
+        elif isinstance(precbc, Bytecode):
+            return yasm_value_finalize(&self.value, (<Bytecode>precbc).bc)
+        else:
+            raise TypeError("Invalid precbc type '%s'" % type(precbc))