]> granicus.if.org Git - yasm/commitdiff
Unbreak bin output (label resolution, Bug#6). Also fix alignment bug.
authorPeter Johnson <peter@tortall.net>
Mon, 7 Oct 2002 19:39:47 +0000 (19:39 -0000)
committerPeter Johnson <peter@tortall.net>
Mon, 7 Oct 2002 19:39:47 +0000 (19:39 -0000)
svn path=/trunk/yasm/; revision=753

modules/objfmts/bin/bin-objfmt.c
modules/objfmts/bin/tests/bintest.asm [new file with mode: 0644]
modules/objfmts/bin/tests/bintest.errwarn [new file with mode: 0644]
modules/objfmts/bin/tests/bintest.hex [new file with mode: 0644]
src/objfmts/bin/bin-objfmt.c
src/objfmts/bin/tests/bintest.asm [new file with mode: 0644]
src/objfmts/bin/tests/bintest.errwarn [new file with mode: 0644]
src/objfmts/bin/tests/bintest.hex [new file with mode: 0644]

index bf4823d15b145d74a42a86d4dca46827de55d1f8..4cd269ce9da0daad535f4ab34140330a1fec08ce 100644 (file)
@@ -86,7 +86,7 @@ bin_objfmt_align_section(section *sect, section *prevsect, unsigned long base,
     else
        align = def_align;      /* No alignment: use default */
 
-    if (start & ~(align-1))
+    if (start & (align-1))
        start = (start & ~(align-1)) + align;
 
     *padamt = start - (base + *prevsectlen);
@@ -101,6 +101,33 @@ typedef struct bin_objfmt_output_info {
     unsigned long start;
 } bin_objfmt_output_info;
 
+static /*@only@*/ expr *
+bin_objfmt_expr_xform(/*@returned@*/ /*@only@*/ expr *e,
+                     /*@unused@*/ /*@null@*/ void *d)
+{
+    int i;
+    /*@dependent@*/ section *sect;
+    /*@dependent@*/ /*@null@*/ bytecode *precbc;
+    /*@null@*/ intnum *dist;
+
+    for (i=0; i<e->numterms; i++) {
+       /* Transform symrecs that reference sections into
+        * start expr + intnum(dist).
+        */
+       if (e->terms[i].type == EXPR_SYM &&
+           symrec_get_label(e->terms[i].data.sym, &sect, &precbc) &&
+           (dist = common_calc_bc_dist(sect, NULL, precbc))) {
+           e->terms[i].type = EXPR_EXPR;
+           e->terms[i].data.expn =
+               expr_new(EXPR_ADD,
+                        ExprExpr(expr_copy(section_get_start(sect))),
+                        ExprInt(dist));
+       }
+    }
+
+    return e;
+}
+
 static int
 bin_objfmt_output_expr(expr **ep, unsigned char **bufp, unsigned long valsize,
                       /*@observer@*/ const section *sect,
@@ -117,7 +144,8 @@ bin_objfmt_output_expr(expr **ep, unsigned char **bufp, unsigned long valsize,
      * Other object formats need to generate their relocation list from here!
      */
 
-    *ep = expr_simplify(*ep, common_calc_bc_dist);
+    *ep = expr_xform_neg_tree(*ep);
+    *ep = expr_level_tree(*ep, 1, 1, NULL, bin_objfmt_expr_xform, NULL, NULL);
 
     /* Handle floating point expressions */
     flt = expr_get_floatnum(ep);
diff --git a/modules/objfmts/bin/tests/bintest.asm b/modules/objfmts/bin/tests/bintest.asm
new file mode 100644 (file)
index 0000000..c434ce9
--- /dev/null
@@ -0,0 +1,56 @@
+; test source file for assembling to binary files
+; build with:
+;    yasm -f bin -o bintest.com bintest.asm
+
+; When run (as a DOS .COM file), this program should print
+;    hello, world
+; on two successive lines, then exit cleanly.
+
+; This file should test the following:
+; [1] Define a text-section symbol
+; [2] Define a data-section symbol
+; [3] Define a BSS-section symbol
+; [4] Define a NASM local label
+; [5] Reference a NASM local label
+; [6] Reference a text-section symbol in the text section
+; [7] Reference a data-section symbol in the text section
+; [8] Reference a BSS-section symbol in the text section
+; [9] Reference a text-section symbol in the data section
+; [10] Reference a data-section symbol in the data section
+; [11] Reference a BSS-section symbol in the data section
+
+[BITS 16]
+[ORG 0x100]
+
+[SECTION .text]
+
+         jmp start             ; [6]
+
+endX     mov ax,0x4c00         ; [1]
+         int 0x21
+
+start    mov byte [bss_sym],',' ; [1] [8]
+         mov bx,[bssptr]       ; [7]
+         mov al,[bx]
+         mov bx,[dataptr]      ; [7]
+         mov [bx],al
+         mov cx,2
+.loop    mov dx,datasym        ; [1] [4] [7]
+         mov ah,9
+         push cx
+         int 0x21
+         pop cx
+         loop .loop            ; [5] [6]
+         mov bx,[textptr]      ; [7]
+         jmp bx
+
+[SECTION .data]
+
+datasym          db 'hello  world', 13, 10, '$' ; [2]
+bssptr   dw bss_sym            ; [2] [11]
+dataptr          dw datasym+5          ; [2] [10]
+textptr          dw endX               ; [2] [9]
+
+[SECTION .bss]
+
+bss_sym          resb 1                ; [3]
diff --git a/modules/objfmts/bin/tests/bintest.errwarn b/modules/objfmts/bin/tests/bintest.errwarn
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/modules/objfmts/bin/tests/bintest.hex b/modules/objfmts/bin/tests/bintest.hex
new file mode 100644 (file)
index 0000000..3a53e37
--- /dev/null
@@ -0,0 +1,65 @@
+eb 
+05 
+b8 
+00 
+4c 
+cd 
+21 
+c6 
+06 
+44 
+01 
+2c 
+8b 
+1e 
+3b 
+01 
+8a 
+07 
+8b 
+1e 
+3d 
+01 
+88 
+07 
+b9 
+02 
+00 
+ba 
+2c 
+01 
+b4 
+09 
+51 
+cd 
+21 
+59 
+e2 
+f5 
+8b 
+1e 
+3f 
+01 
+ff 
+e3 
+68 
+65 
+6c 
+6c 
+6f 
+20 
+20 
+77 
+6f 
+72 
+6c 
+64 
+0d 
+0a 
+24 
+44 
+01 
+31 
+01 
+02 
+01 
index bf4823d15b145d74a42a86d4dca46827de55d1f8..4cd269ce9da0daad535f4ab34140330a1fec08ce 100644 (file)
@@ -86,7 +86,7 @@ bin_objfmt_align_section(section *sect, section *prevsect, unsigned long base,
     else
        align = def_align;      /* No alignment: use default */
 
-    if (start & ~(align-1))
+    if (start & (align-1))
        start = (start & ~(align-1)) + align;
 
     *padamt = start - (base + *prevsectlen);
@@ -101,6 +101,33 @@ typedef struct bin_objfmt_output_info {
     unsigned long start;
 } bin_objfmt_output_info;
 
+static /*@only@*/ expr *
+bin_objfmt_expr_xform(/*@returned@*/ /*@only@*/ expr *e,
+                     /*@unused@*/ /*@null@*/ void *d)
+{
+    int i;
+    /*@dependent@*/ section *sect;
+    /*@dependent@*/ /*@null@*/ bytecode *precbc;
+    /*@null@*/ intnum *dist;
+
+    for (i=0; i<e->numterms; i++) {
+       /* Transform symrecs that reference sections into
+        * start expr + intnum(dist).
+        */
+       if (e->terms[i].type == EXPR_SYM &&
+           symrec_get_label(e->terms[i].data.sym, &sect, &precbc) &&
+           (dist = common_calc_bc_dist(sect, NULL, precbc))) {
+           e->terms[i].type = EXPR_EXPR;
+           e->terms[i].data.expn =
+               expr_new(EXPR_ADD,
+                        ExprExpr(expr_copy(section_get_start(sect))),
+                        ExprInt(dist));
+       }
+    }
+
+    return e;
+}
+
 static int
 bin_objfmt_output_expr(expr **ep, unsigned char **bufp, unsigned long valsize,
                       /*@observer@*/ const section *sect,
@@ -117,7 +144,8 @@ bin_objfmt_output_expr(expr **ep, unsigned char **bufp, unsigned long valsize,
      * Other object formats need to generate their relocation list from here!
      */
 
-    *ep = expr_simplify(*ep, common_calc_bc_dist);
+    *ep = expr_xform_neg_tree(*ep);
+    *ep = expr_level_tree(*ep, 1, 1, NULL, bin_objfmt_expr_xform, NULL, NULL);
 
     /* Handle floating point expressions */
     flt = expr_get_floatnum(ep);
diff --git a/src/objfmts/bin/tests/bintest.asm b/src/objfmts/bin/tests/bintest.asm
new file mode 100644 (file)
index 0000000..c434ce9
--- /dev/null
@@ -0,0 +1,56 @@
+; test source file for assembling to binary files
+; build with:
+;    yasm -f bin -o bintest.com bintest.asm
+
+; When run (as a DOS .COM file), this program should print
+;    hello, world
+; on two successive lines, then exit cleanly.
+
+; This file should test the following:
+; [1] Define a text-section symbol
+; [2] Define a data-section symbol
+; [3] Define a BSS-section symbol
+; [4] Define a NASM local label
+; [5] Reference a NASM local label
+; [6] Reference a text-section symbol in the text section
+; [7] Reference a data-section symbol in the text section
+; [8] Reference a BSS-section symbol in the text section
+; [9] Reference a text-section symbol in the data section
+; [10] Reference a data-section symbol in the data section
+; [11] Reference a BSS-section symbol in the data section
+
+[BITS 16]
+[ORG 0x100]
+
+[SECTION .text]
+
+         jmp start             ; [6]
+
+endX     mov ax,0x4c00         ; [1]
+         int 0x21
+
+start    mov byte [bss_sym],',' ; [1] [8]
+         mov bx,[bssptr]       ; [7]
+         mov al,[bx]
+         mov bx,[dataptr]      ; [7]
+         mov [bx],al
+         mov cx,2
+.loop    mov dx,datasym        ; [1] [4] [7]
+         mov ah,9
+         push cx
+         int 0x21
+         pop cx
+         loop .loop            ; [5] [6]
+         mov bx,[textptr]      ; [7]
+         jmp bx
+
+[SECTION .data]
+
+datasym          db 'hello  world', 13, 10, '$' ; [2]
+bssptr   dw bss_sym            ; [2] [11]
+dataptr          dw datasym+5          ; [2] [10]
+textptr          dw endX               ; [2] [9]
+
+[SECTION .bss]
+
+bss_sym          resb 1                ; [3]
diff --git a/src/objfmts/bin/tests/bintest.errwarn b/src/objfmts/bin/tests/bintest.errwarn
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/objfmts/bin/tests/bintest.hex b/src/objfmts/bin/tests/bintest.hex
new file mode 100644 (file)
index 0000000..3a53e37
--- /dev/null
@@ -0,0 +1,65 @@
+eb 
+05 
+b8 
+00 
+4c 
+cd 
+21 
+c6 
+06 
+44 
+01 
+2c 
+8b 
+1e 
+3b 
+01 
+8a 
+07 
+8b 
+1e 
+3d 
+01 
+88 
+07 
+b9 
+02 
+00 
+ba 
+2c 
+01 
+b4 
+09 
+51 
+cd 
+21 
+59 
+e2 
+f5 
+8b 
+1e 
+3f 
+01 
+ff 
+e3 
+68 
+65 
+6c 
+6c 
+6f 
+20 
+20 
+77 
+6f 
+72 
+6c 
+64 
+0d 
+0a 
+24 
+44 
+01 
+31 
+01 
+02 
+01