From d5600e7d20b90b9c090265fa0ac810973fb17014 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Mon, 7 Oct 2002 19:39:47 +0000 Subject: [PATCH] Unbreak bin output (label resolution, Bug#6). Also fix alignment bug. svn path=/trunk/yasm/; revision=753 --- modules/objfmts/bin/bin-objfmt.c | 32 ++++++++++- modules/objfmts/bin/tests/bintest.asm | 56 +++++++++++++++++++ modules/objfmts/bin/tests/bintest.errwarn | 0 modules/objfmts/bin/tests/bintest.hex | 65 +++++++++++++++++++++++ src/objfmts/bin/bin-objfmt.c | 32 ++++++++++- src/objfmts/bin/tests/bintest.asm | 56 +++++++++++++++++++ src/objfmts/bin/tests/bintest.errwarn | 0 src/objfmts/bin/tests/bintest.hex | 65 +++++++++++++++++++++++ 8 files changed, 302 insertions(+), 4 deletions(-) create mode 100644 modules/objfmts/bin/tests/bintest.asm create mode 100644 modules/objfmts/bin/tests/bintest.errwarn create mode 100644 modules/objfmts/bin/tests/bintest.hex create mode 100644 src/objfmts/bin/tests/bintest.asm create mode 100644 src/objfmts/bin/tests/bintest.errwarn create mode 100644 src/objfmts/bin/tests/bintest.hex diff --git a/modules/objfmts/bin/bin-objfmt.c b/modules/objfmts/bin/bin-objfmt.c index bf4823d1..4cd269ce 100644 --- a/modules/objfmts/bin/bin-objfmt.c +++ b/modules/objfmts/bin/bin-objfmt.c @@ -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; inumterms; 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, §, &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 index 00000000..c434ce94 --- /dev/null +++ b/modules/objfmts/bin/tests/bintest.asm @@ -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 index 00000000..e69de29b diff --git a/modules/objfmts/bin/tests/bintest.hex b/modules/objfmts/bin/tests/bintest.hex new file mode 100644 index 00000000..3a53e371 --- /dev/null +++ b/modules/objfmts/bin/tests/bintest.hex @@ -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 diff --git a/src/objfmts/bin/bin-objfmt.c b/src/objfmts/bin/bin-objfmt.c index bf4823d1..4cd269ce 100644 --- a/src/objfmts/bin/bin-objfmt.c +++ b/src/objfmts/bin/bin-objfmt.c @@ -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; inumterms; 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, §, &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 index 00000000..c434ce94 --- /dev/null +++ b/src/objfmts/bin/tests/bintest.asm @@ -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 index 00000000..e69de29b diff --git a/src/objfmts/bin/tests/bintest.hex b/src/objfmts/bin/tests/bintest.hex new file mode 100644 index 00000000..3a53e371 --- /dev/null +++ b/src/objfmts/bin/tests/bintest.hex @@ -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 -- 2.40.0