]> granicus.if.org Git - yasm/commitdiff
* coff-objfmt.c (coff_objfmt_output_value): Add support for SEG value as
authorPeter Johnson <peter@tortall.net>
Mon, 20 Mar 2006 06:15:15 +0000 (06:15 -0000)
committerPeter Johnson <peter@tortall.net>
Mon, 20 Mar 2006 06:15:15 +0000 (06:15 -0000)
COFF has a SECTION relocation that supports this.

* win32-segof.asm: New test for above.

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

modules/objfmts/coff/coff-objfmt.c
modules/objfmts/win32/tests/Makefile.inc
modules/objfmts/win32/tests/win32-segof.asm [new file with mode: 0644]
modules/objfmts/win32/tests/win32-segof.errwarn [new file with mode: 0644]
modules/objfmts/win32/tests/win32-segof.hex [new file with mode: 0644]

index c193e87dc9beccf5ead822b056cb049af6128a41..4cf329a06a35515ad86ced3ba3c5dc187556fb0e 100644 (file)
@@ -447,7 +447,8 @@ coff_objfmt_output_value(yasm_value *value, unsigned char *buf, size_t destsize,
     }
 
     /* Handle other expressions, with relocation if necessary */
-    if (value->seg_of || value->rshift > 0) {
+    if (value->rshift > 0
+       || (value->seg_of && (value->wrt || value->curpos_rel))) {
        yasm__error(bc->line, N_("coff: relocation too complex"));
        return 1;
     }
@@ -462,8 +463,8 @@ coff_objfmt_output_value(yasm_value *value, unsigned char *buf, size_t destsize,
 
        /* Sometimes we want the relocation to be generated against one
         * symbol but the value generated correspond to a different symbol.
-        * This is done through (sym being referenced) WRT (sym used for reloc).
-        * Note both syms need to be in the same section!
+        * This is done through (sym being referenced) WRT (sym used for
+        * reloc).  Note both syms need to be in the same section!
         */
        if (value->wrt) {
            /*@dependent@*/ /*@null@*/ yasm_bytecode *rel_precbc, *wrt_precbc;
@@ -535,6 +536,12 @@ coff_objfmt_output_value(yasm_value *value, unsigned char *buf, size_t destsize,
                intn_minus = bc->offset;
        }
 
+       if (value->seg_of) {
+           /* Segment generation; zero value. */
+           intn_val = 0;
+           intn_minus = 0;
+       }
+
        /* Generate reloc */
        reloc = yasm_xmalloc(sizeof(coff_reloc));
        addr = bc->offset + offset;
@@ -584,6 +591,13 @@ coff_objfmt_output_value(yasm_value *value, unsigned char *buf, size_t destsize,
                }
            } else
                yasm_internal_error(N_("coff objfmt: unrecognized machine"));
+       } else if (value->seg_of) {
+           if (objfmt_coff->machine == COFF_MACHINE_I386)
+               reloc->type = COFF_RELOC_I386_SECTION;
+           else if (objfmt_coff->machine == COFF_MACHINE_AMD64)
+               reloc->type = COFF_RELOC_AMD64_SECTION;
+           else
+               yasm_internal_error(N_("coff objfmt: unrecognized machine"));
        } else {
            if (objfmt_coff->machine == COFF_MACHINE_I386) {
                if (info->csd->flags2 & COFF_FLAG_NOBASE)
index e6b34b6567da343da2f44faf5ee6187be6170ce1..02d0d5b77976c7b653e9c867c8b95b43859ae994 100644 (file)
@@ -9,6 +9,9 @@ EXTRA_DIST += modules/objfmts/win32/tests/win32_test.sh
 EXTRA_DIST += modules/objfmts/win32/tests/win32-curpos.asm
 EXTRA_DIST += modules/objfmts/win32/tests/win32-curpos.hex
 EXTRA_DIST += modules/objfmts/win32/tests/win32-curpos.errwarn
+EXTRA_DIST += modules/objfmts/win32/tests/win32-segof.asm
+EXTRA_DIST += modules/objfmts/win32/tests/win32-segof.hex
+EXTRA_DIST += modules/objfmts/win32/tests/win32-segof.errwarn
 EXTRA_DIST += modules/objfmts/win32/tests/win32-overdef.asm
 EXTRA_DIST += modules/objfmts/win32/tests/win32-overdef.hex
 EXTRA_DIST += modules/objfmts/win32/tests/win32-overdef.errwarn
diff --git a/modules/objfmts/win32/tests/win32-segof.asm b/modules/objfmts/win32/tests/win32-segof.asm
new file mode 100644 (file)
index 0000000..5535cd0
--- /dev/null
@@ -0,0 +1,10 @@
+extern value
+mov ax, seg value
+mov ds, ax
+
+mov ax, seg local
+mov es, ax
+
+section .data
+
+local:
diff --git a/modules/objfmts/win32/tests/win32-segof.errwarn b/modules/objfmts/win32/tests/win32-segof.errwarn
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/modules/objfmts/win32/tests/win32-segof.hex b/modules/objfmts/win32/tests/win32-segof.hex
new file mode 100644 (file)
index 0000000..873129f
--- /dev/null
@@ -0,0 +1,262 @@
+4c 
+01 
+02 
+00 
+00 
+00 
+00 
+00 
+84 
+00 
+00 
+00 
+07 
+00 
+00 
+00 
+00 
+00 
+0c 
+01 
+2e 
+74 
+65 
+78 
+74 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+0c 
+00 
+00 
+00 
+64 
+00 
+00 
+00 
+70 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+20 
+00 
+50 
+60 
+2e 
+64 
+61 
+74 
+61 
+00 
+00 
+00 
+0c 
+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 
+40 
+00 
+30 
+c0 
+66 
+b8 
+00 
+00 
+8e 
+d8 
+66 
+b8 
+00 
+00 
+8e 
+c0 
+02 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+0a 
+00 
+08 
+00 
+00 
+00 
+05 
+00 
+00 
+00 
+0a 
+00 
+2e 
+66 
+69 
+6c 
+65 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+fe 
+ff 
+00 
+00 
+67 
+01 
+2d 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+2e 
+74 
+65 
+78 
+74 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+03 
+01 
+0c 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+76 
+61 
+6c 
+75 
+65 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+02 
+00 
+2e 
+64 
+61 
+74 
+61 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+03 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+04 
+00 
+00 
+00