From cfbeb3bebcf964b1e1b4f74b9323c5f5c75043c3 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Thu, 31 May 2007 06:16:49 +0000 Subject: [PATCH 1/8] Fix typo in filename reference in [1853]. svn path=/trunk/yasm/; revision=1854 --- modules/objfmts/macho/tests/nasm32/Makefile.inc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/objfmts/macho/tests/nasm32/Makefile.inc b/modules/objfmts/macho/tests/nasm32/Makefile.inc index 0b3a3c5b..1ee18be1 100644 --- a/modules/objfmts/macho/tests/nasm32/Makefile.inc +++ b/modules/objfmts/macho/tests/nasm32/Makefile.inc @@ -8,6 +8,6 @@ EXTRA_DIST += modules/objfmts/macho/tests/nasm32/machotest.asm EXTRA_DIST += modules/objfmts/macho/tests/nasm32/machotest.hex EXTRA_DIST += modules/objfmts/macho/tests/nasm32/macho-reloc.asm EXTRA_DIST += modules/objfmts/macho/tests/nasm32/macho-reloc.hex -EXTRA_DIST += modules/objfmts/macho/tests/nasm32/macho-sect.asm -EXTRA_DIST += modules/objfmts/macho/tests/nasm32/macho-sect.errwarn -EXTRA_DIST += modules/objfmts/macho/tests/nasm32/macho-sect.hex +EXTRA_DIST += modules/objfmts/macho/tests/nasm32/macho32-sect.asm +EXTRA_DIST += modules/objfmts/macho/tests/nasm32/macho32-sect.errwarn +EXTRA_DIST += modules/objfmts/macho/tests/nasm32/macho32-sect.hex From 67bc3c2010f06c6320864231f6c86ecbe43d735b Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Fri, 1 Jun 2007 19:31:00 +0000 Subject: [PATCH 2/8] Fix a few bugs in new directive handling. Found by: zzuf svn path=/trunk/yasm/; revision=1865 --- modules/parsers/nasm/nasm-parse.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/modules/parsers/nasm/nasm-parse.c b/modules/parsers/nasm/nasm-parse.c index cbd84993..7866cffe 100644 --- a/modules/parsers/nasm/nasm-parse.c +++ b/modules/parsers/nasm/nasm-parse.c @@ -436,6 +436,10 @@ parse_directive_valparams(yasm_parser_nasm *parser_nasm, /*@fallthrough@*/ default: e = parse_expr(parser_nasm, DIR_EXPR); + if (!e) { + yasm_vps_delete(vps); + return 0; + } vp = yasm_vp_create_expr(id, e); break; } @@ -1100,8 +1104,7 @@ dir_align(yasm_object *object, yasm_valparamhead *valparams, * Note: this doesn't match NASM behavior, but is a lot more * intelligent! */ - boundintn = yasm_expr_get_intnum(&boundval, 0); - if (boundintn) { + if (boundval && (boundintn = yasm_expr_get_intnum(&boundval, 0))) { unsigned long boundint = yasm_intnum_get_uint(boundintn); /* Alignments must be a power of two. */ @@ -1144,7 +1147,7 @@ nasm_parser_directive(yasm_parser_nasm *parser_nasm, const char *name, parser_nasm->prev_bc = NULL; } else if (yasm__strcasecmp(name, "align") == 0) { /* Really, we shouldn't end up with an align directive in an absolute - * section (as it's supposed to be only used for nop fill, but handle + * section (as it's supposed to be only used for nop fill), but handle * it gracefully anyway. */ if (parser_nasm->abspos) { @@ -1163,6 +1166,9 @@ nasm_parser_directive(yasm_parser_nasm *parser_nasm, const char *name, cur_line); parser_nasm->abspos = yasm_expr_create_tree( parser_nasm->abspos, YASM_EXPR_ADD, e, cur_line); + } else if (!valparams) { + yasm_error_set(YASM_ERROR_SYNTAX, + N_("directive `%s' requires an argument"), "align"); } else dir_align(p_object, valparams, objext_valparams, line); } else From 951a6df0263aea89107a58fd697ec58aa01a1642 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Fri, 1 Jun 2007 19:39:29 +0000 Subject: [PATCH 3/8] Fix use-after-free in linemap_poke. The first yasm_linemap_set call can realloc linemap->map->vector, invalidating the mapping pointer. Found by: zzuf+valgrind svn path=/trunk/yasm/; revision=1866 --- libyasm/linemap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libyasm/linemap.c b/libyasm/linemap.c index befd9acf..e2ff9300 100644 --- a/libyasm/linemap.c +++ b/libyasm/linemap.c @@ -131,11 +131,13 @@ yasm_linemap_poke(yasm_linemap *linemap, const char *filename, unsigned long file_line) { unsigned long line; - line_mapping *mapping = &linemap->map->vector[linemap->map->size-1]; + line_mapping *mapping; linemap->current++; yasm_linemap_set(linemap, filename, file_line, 0); + mapping = &linemap->map->vector[linemap->map->size-1]; + line = linemap->current; linemap->current++; From 1e604828b11984a597a2b357566e8422f2ae82ab Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Fri, 1 Jun 2007 19:44:38 +0000 Subject: [PATCH 4/8] Don't try to yasm_expr_copy(NULL). Found by: zzuf svn path=/trunk/yasm/; revision=1867 --- modules/objfmts/coff/coff-objfmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/objfmts/coff/coff-objfmt.c b/modules/objfmts/coff/coff-objfmt.c index 1df7c4cf..ae3ee08c 100644 --- a/modules/objfmts/coff/coff-objfmt.c +++ b/modules/objfmts/coff/coff-objfmt.c @@ -1844,7 +1844,7 @@ dir_setframe(yasm_object *object, yasm_valparamhead *valparams, code->loc = get_curpos(object, "SETFRAME", line); code->opcode = UWOP_SET_FPREG; code->info = (unsigned int)(*reg & 0xF); - yasm_value_initialize(&code->off, yasm_expr_copy(off), 8); + yasm_value_initialize(&code->off, off ? yasm_expr_copy(off) : NULL, 8); SLIST_INSERT_HEAD(&objfmt_coff->unwind->codes, code, link); } From 1a6cf7dab0bfa3e5580d0d1c7ac171c3c57a9150 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Sat, 2 Jun 2007 05:21:33 +0000 Subject: [PATCH 5/8] Correct CPU definitions for Prescott, Conroe, Penryn, and Nehalem. All are 64-bit capable and thus should set CPU_Hammer; Prescott was mistakingly also setting AMD features such as 3DNow. svn path=/trunk/yasm/; revision=1870 --- modules/arch/x86/x86parse.gap | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/arch/x86/x86parse.gap b/modules/arch/x86/x86parse.gap index b94006dd..c9d71411 100644 --- a/modules/arch/x86/x86parse.gap +++ b/modules/arch/x86/x86parse.gap @@ -984,19 +984,19 @@ CPU_ALIAS opteron hammer CPU_ALIAS athlon64 hammer CPU_ALIAS athlon-64 hammer CPU prescott CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|\ - CPU_K6|CPU_Athlon|CPU_Hammer|CPU_EM64T|CPU_FPU|CPU_MMX|\ - CPU_SSE|CPU_SSE2|CPU_SSE3|CPU_3DNow|CPU_SMM|\ + CPU_Hammer|CPU_EM64T|CPU_FPU|CPU_MMX|\ + CPU_SSE|CPU_SSE2|CPU_SSE3|CPU_SMM|\ CPU_Prot|CPU_Priv CPU conroe CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|\ - CPU_EM64T|CPU_FPU|CPU_MMX|\ + CPU_Hammer|CPU_EM64T|CPU_FPU|CPU_MMX|\ CPU_SSE|CPU_SSE2|CPU_SSE3|CPU_SSSE3|CPU_SMM|\ CPU_Prot|CPU_Priv CPU penryn CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|\ - CPU_EM64T|CPU_FPU|CPU_MMX|\ + CPU_Hammer|CPU_EM64T|CPU_FPU|CPU_MMX|\ CPU_SSE|CPU_SSE2|CPU_SSE3|CPU_SSSE3|CPU_SSE41|CPU_SMM|\ CPU_Prot|CPU_Priv CPU nehalem CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|\ - CPU_EM64T|CPU_FPU|CPU_MMX|\ + CPU_Hammer|CPU_EM64T|CPU_FPU|CPU_MMX|\ CPU_SSE|CPU_SSE2|CPU_SSE3|CPU_SSSE3|CPU_SSE41|\ CPU_SSE42|CPU_SMM|CPU_Prot|CPU_Priv From c12eca767ad014ae88f4d6251c297d774d0b388d Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Sat, 2 Jun 2007 08:23:29 +0000 Subject: [PATCH 6/8] Fix uninitialized variable, memory leak. svn path=/trunk/yasm/; revision=1872 --- modules/objfmts/macho/macho-objfmt.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/modules/objfmts/macho/macho-objfmt.c b/modules/objfmts/macho/macho-objfmt.c index 830fe5d1..ceddbf98 100644 --- a/modules/objfmts/macho/macho-objfmt.c +++ b/modules/objfmts/macho/macho-objfmt.c @@ -1252,12 +1252,14 @@ macho_objfmt_init_new_section(yasm_object *object, yasm_section *sect, data = yasm_xmalloc(sizeof(macho_section_data)); data->scnum = objfmt_macho->parse_scnum++; - data->segname = yasm__xstrdup(""); - data->sectname = yasm__xstrdup(""); + data->segname = NULL; + data->sectname = NULL; data->flags = S_REGULAR; data->size = 0; - data->nreloc = 0; data->offset = 0; + data->vmoff = 0; + data->nreloc = 0; + data->extreloc = 0; yasm_section_add_data(sect, &macho_section_data_cb, data); sym = yasm_symtab_define_label(object->symtab, sectname, @@ -1504,9 +1506,10 @@ macho_section_data_print(void *data, FILE *f, int indent_level) yasm_symrec_print(msd->sym, f, indent_level + 1); fprintf(f, "%*sscnum=%ld\n", indent_level, "", msd->scnum); fprintf(f, "%*sflags=0x%lx\n", indent_level, "", msd->flags); - fprintf(f, "%*ssize=%ld\n", indent_level, "", msd->size); - fprintf(f, "%*snreloc=%ld\n", indent_level, "", msd->nreloc); - fprintf(f, "%*soffset=%ld\n", indent_level, "", msd->offset); + fprintf(f, "%*ssize=%lu\n", indent_level, "", msd->size); + fprintf(f, "%*snreloc=%lu\n", indent_level, "", msd->nreloc); + fprintf(f, "%*soffset=%lu\n", indent_level, "", msd->offset); + fprintf(f, "%*sextreloc=%u\n", indent_level, "", msd->extreloc); } static void From 99a8519e636b56afce78d82d157eaf3e206396e0 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Sat, 2 Jun 2007 08:34:40 +0000 Subject: [PATCH 7/8] Make sure objfmt_coff->win64 gets set to 0 in win32 mode. svn path=/trunk/yasm/; revision=1873 --- modules/objfmts/coff/coff-objfmt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/objfmts/coff/coff-objfmt.c b/modules/objfmts/coff/coff-objfmt.c index ae3ee08c..bd856140 100644 --- a/modules/objfmts/coff/coff-objfmt.c +++ b/modules/objfmts/coff/coff-objfmt.c @@ -311,6 +311,7 @@ win32_objfmt_create(yasm_object *object) "x86") == 0) { objfmt_coff->machine = COFF_MACHINE_I386; objfmt_coff->objfmt.module = &yasm_win32_LTX_objfmt; + objfmt_coff->win64 = 0; } else if (yasm__strcasecmp(yasm_arch_get_machine(object->arch), "amd64") == 0) { objfmt_coff->machine = COFF_MACHINE_AMD64; From 01b18c53e9665ff620a3fbb319533e1684455e77 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Mon, 4 Jun 2007 01:12:37 +0000 Subject: [PATCH 8/8] Fix bin objfmt handling of cross-section RIP-relative values; also clean up absolute value handling. svn path=/trunk/yasm/; revision=1878 --- modules/objfmts/bin/bin-objfmt.c | 75 ++++++++++++-------------- modules/objfmts/bin/tests/Makefile.inc | 2 + modules/objfmts/bin/tests/bin-rip.asm | 20 +++++++ modules/objfmts/bin/tests/bin-rip.hex | 46 ++++++++++++++++ 4 files changed, 101 insertions(+), 42 deletions(-) create mode 100755 modules/objfmts/bin/tests/bin-rip.asm create mode 100644 modules/objfmts/bin/tests/bin-rip.hex diff --git a/modules/objfmts/bin/bin-objfmt.c b/modules/objfmts/bin/bin-objfmt.c index 1a0c9ec2..2e7fd727 100644 --- a/modules/objfmts/bin/bin-objfmt.c +++ b/modules/objfmts/bin/bin-objfmt.c @@ -103,11 +103,13 @@ bin_objfmt_expr_xform(/*@returned@*/ /*@only@*/ yasm_expr *e, /*@null@*/ yasm_intnum *dist; for (i=0; inumterms; i++) { - /* Transform symrecs that reference sections into + /* Transform symrecs or precbcs that reference sections into * start expr + intnum(dist). */ - if (e->terms[i].type == YASM_EXPR_SYM && - yasm_symrec_get_label(e->terms[i].data.sym, &precbc) && + if (((e->terms[i].type == YASM_EXPR_SYM && + yasm_symrec_get_label(e->terms[i].data.sym, &precbc)) || + (e->terms[i].type == YASM_EXPR_PRECBC && + (precbc = e->terms[i].data.precbc))) && (sect = yasm_bc_get_section(precbc)) && (dist = yasm_calc_bc_dist(yasm_section_bcs_first(sect), precbc))) { const yasm_expr *start = yasm_section_get_start(sect); @@ -135,17 +137,36 @@ bin_objfmt_output_value(yasm_value *value, unsigned char *buf, assert(info != NULL); /* Binary objects we need to resolve against object, not against section. */ - if (value->rel && !value->curpos_rel - && yasm_symrec_get_label(value->rel, &precbc) - && (sect = yasm_bc_get_section(precbc))) { + if (value->rel) { unsigned int rshift = (unsigned int)value->rshift; yasm_expr *syme; - if (value->rshift > 0) - syme = yasm_expr_create(YASM_EXPR_SHR, yasm_expr_sym(value->rel), - yasm_expr_int(yasm_intnum_create_uint(rshift)), bc->line); - else - syme = yasm_expr_create_ident(yasm_expr_sym(value->rel), bc->line); + if (yasm_symrec_is_abs(value->rel)) { + syme = yasm_expr_create_ident(yasm_expr_int( + yasm_intnum_create_uint(0)), bc->line); + } else if (yasm_symrec_get_label(value->rel, &precbc) + && (sect = yasm_bc_get_section(precbc))) { + syme = yasm_expr_create_ident(yasm_expr_sym(value->rel), bc->line); + } else + goto done; + + /* Handle PC-relative */ + if (value->curpos_rel) { + yasm_expr *sube; + sube = yasm_expr_create(YASM_EXPR_SUB, yasm_expr_precbc(bc), + yasm_expr_int(yasm_intnum_create_uint(bc->len*bc->mult_int)), + bc->line); + syme = yasm_expr_create(YASM_EXPR_SUB, yasm_expr_expr(syme), + yasm_expr_expr(sube), bc->line); + value->curpos_rel = 0; + value->ip_rel = 0; + } else + + if (value->rshift > 0) + syme = yasm_expr_create(YASM_EXPR_SHR, yasm_expr_expr(syme), + yasm_expr_int(yasm_intnum_create_uint(rshift)), bc->line); + + /* Add into absolute portion */ if (!value->abs) value->abs = syme; else @@ -155,7 +176,7 @@ bin_objfmt_output_value(yasm_value *value, unsigned char *buf, value->rel = NULL; value->rshift = 0; } - +done: /* Simplify absolute portion of value, transforming symrecs */ if (value->abs) value->abs = yasm_expr__level_tree @@ -172,36 +193,6 @@ bin_objfmt_output_value(yasm_value *value, unsigned char *buf, return 0; } - /* Absolute value; handle it here as output_basic won't understand it */ - if (value->rel && 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->object->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")); diff --git a/modules/objfmts/bin/tests/Makefile.inc b/modules/objfmts/bin/tests/Makefile.inc index 70070b00..e1993ea4 100644 --- a/modules/objfmts/bin/tests/Makefile.inc +++ b/modules/objfmts/bin/tests/Makefile.inc @@ -10,6 +10,8 @@ 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/bin-rip.asm +EXTRA_DIST += modules/objfmts/bin/tests/bin-rip.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-rip.asm b/modules/objfmts/bin/tests/bin-rip.asm new file mode 100755 index 00000000..22110545 --- /dev/null +++ b/modules/objfmts/bin/tests/bin-rip.asm @@ -0,0 +1,20 @@ +bits 64 +org 0x100 +foo_equ equ 0x12345678 + +section .text +nop +foo_text: +nop +mov rax,[foo_equ wrt rip] +mov rax,[foo_text wrt rip] +mov rax,[foo_data wrt rip] +mov rbx,[foo_equ wrt rip] +mov rbx,[foo_text wrt rip] +mov rbx,[foo_data wrt rip] + +section .data +db 0 +foo_data: +db 0 + diff --git a/modules/objfmts/bin/tests/bin-rip.hex b/modules/objfmts/bin/tests/bin-rip.hex new file mode 100644 index 00000000..d56601d9 --- /dev/null +++ b/modules/objfmts/bin/tests/bin-rip.hex @@ -0,0 +1,46 @@ +90 +90 +48 +8b +05 +6f +55 +34 +12 +48 +8b +05 +f1 +ff +ff +ff +48 +8b +05 +16 +00 +00 +00 +48 +8b +1d +5a +55 +34 +12 +48 +8b +1d +dc +ff +ff +ff +48 +8b +1d +01 +00 +00 +00 +00 +00