From: Peter Johnson Date: Fri, 30 Sep 2005 04:03:59 +0000 (-0000) Subject: * coff-objfmt.c (coff_objfmt_output_expr): Try to match the new ML64's X-Git-Tag: v0.5.0rc1~121 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fc6e94054e0134c5313b7206d93b40c58ea1521b;p=yasm * coff-objfmt.c (coff_objfmt_output_expr): Try to match the new ML64's output better by generating relocs directly to the symbol being relocated rather than to the section. Use a new coff_objfmt->win64 flag to conditionalize this rather than just COFF_MACHINE_AMD64. (coff_objfmt): New win64 flag. (coff_objfmt_create, win32_objfmt_create, win64_objfmt_create): Initialize flag. (coff_objfmt_output): Turn on outputting all symbols in win64 mode so they can be referenced by relocs. This isn't quite correct: we should only turn on the symbols that are actually used by relocs, but having them there doesn't hurt linking; it only exposes all of the internal symbol names. With these changes, yasm output matches the new ML64 output except for a very few cases: - ML64 generates REL32 relocs when referencing objects in the same .text section. I cannot see how this is necessary because call instructions don't generate REL32 relocs! I currently do not plan on fixing this unless it causes a problem. - ML64 generates ADDR32 relocs instead of REL32 relocs when loading a 32-bit register with the address of an object. I will probably try to fix this. Extended test case for this a bit. svn path=/trunk/yasm/; revision=1256 --- diff --git a/modules/objfmts/coff/coff-objfmt.c b/modules/objfmts/coff/coff-objfmt.c index 2911115f..1f2cbcdd 100644 --- a/modules/objfmts/coff/coff-objfmt.c +++ b/modules/objfmts/coff/coff-objfmt.c @@ -173,7 +173,8 @@ typedef struct yasm_objfmt_coff { yasm_objfmt_base objfmt; /* base structure*/ unsigned int parse_scnum; /* sect numbering in parser */ - int win32; /* nonzero for win32 output */ + int win32; /* nonzero for win32/64 output */ + int win64; /* nonzero for win64 output */ unsigned int machine; /* COFF machine to use */ @@ -284,6 +285,7 @@ coff_objfmt_create(const char *in_filename, yasm_object *object, yasm_arch *a) objfmt_coff->objfmt.module = &yasm_coff_LTX_objfmt; objfmt_coff->win32 = 0; + objfmt_coff->win64 = 0; } return (yasm_objfmt *)objfmt_coff; } @@ -304,6 +306,7 @@ win32_objfmt_create(const char *in_filename, yasm_object *object, yasm_arch *a) } else if (yasm__strcasecmp(yasm_arch_get_machine(a), "amd64") == 0) { objfmt_coff->machine = COFF_MACHINE_AMD64; objfmt_coff->objfmt.module = &yasm_win64_LTX_objfmt; + objfmt_coff->win64 = 1; } else { yasm_xfree(objfmt_coff); return NULL; @@ -331,6 +334,7 @@ win64_objfmt_create(const char *in_filename, yasm_object *object, yasm_arch *a) objfmt_coff->objfmt.module = &yasm_win64_LTX_objfmt; objfmt_coff->win32 = 1; + objfmt_coff->win64 = 1; } return (yasm_objfmt *)objfmt_coff; } @@ -388,7 +392,8 @@ coff_objfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize, } /* Handle integer expressions, with relocation if necessary */ - sym = yasm_expr_extract_symrec(ep, 1, yasm_common_calc_bc_dist); + sym = yasm_expr_extract_symrec(ep, !objfmt_coff->win64, + yasm_common_calc_bc_dist); if (sym) { unsigned long addr; coff_reloc *reloc; @@ -413,7 +418,7 @@ coff_objfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize, csymd->size->line); *ep = yasm_expr_simplify(*ep, yasm_common_calc_bc_dist); } - } else if (!(vis & YASM_SYM_EXTERN)) { + } else if (!(vis & YASM_SYM_EXTERN) && !objfmt_coff->win64) { /* Local symbols need relocation to their section's start */ if (yasm_symrec_get_label(sym, &label_precbc)) { /*@null@*/ coff_section_data *label_csd; @@ -450,6 +455,7 @@ coff_objfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize, * $$ in. * For Win32 COFF, need to reference to next bytecode, so add '$' * (really $+$.len) in. + * For Win64 COFF, don't add anything in. */ if (objfmt_coff->win32) *ep = yasm_expr_create(YASM_EXPR_ADD, yasm_expr_expr(*ep), @@ -472,7 +478,7 @@ coff_objfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize, if (valsize == 32) { if (info->csd->flags2 & COFF_FLAG_NOBASE) reloc->type = COFF_RELOC_AMD64_ADDR32NB; - else if (yasm_bc_is_data(bc)) + else if (!objfmt_coff->win64 || yasm_bc_is_data(bc)) reloc->type = COFF_RELOC_AMD64_ADDR32; else { /* I don't understand this, but ML64 generates REL32 @@ -905,6 +911,12 @@ coff_objfmt_output(yasm_objfmt *objfmt, FILE *f, const char *obj_filename, unsigned long symtab_count; unsigned int flags; + /* Force all syms for win64 because they're needed for relocations. + * FIXME: Not *all* syms need to be output, only the ones needed for + * relocation. Find a way to do that someday. + */ + all_syms |= objfmt_coff->win64; + info.strtab_offset = 4; info.objfmt_coff = objfmt_coff; info.f = f; diff --git a/modules/objfmts/win64/tests/win64-dataref.asm b/modules/objfmts/win64/tests/win64-dataref.asm index e98c7417..ca4ef826 100644 --- a/modules/objfmts/win64/tests/win64-dataref.asm +++ b/modules/objfmts/win64/tests/win64-dataref.asm @@ -24,10 +24,13 @@ xptr2 dq x [SECTION .bss] x resq 1 +y resq 1 [SECTION .text] x86ident: - ; with :proc + ; extern with :proc + ; This instruction generates a different relocation than + ; MASM does at present. mov ebx, foobar ; WTF ML64.. this had [] mov rcx, foobar lea rdx, [foobar wrt rip] @@ -37,6 +40,25 @@ x86ident: movzx rax, byte [foobar wrt rip] movzx rax, byte [foobar+rax] + ; local "proc" + ; See note above + mov ebx, trap + mov rcx, trap + ; MASM generates a REL32 reloc for this even though it's in + ; the same section. I don't know why, as the call instruction + ; below doesn't cause a reloc, so the linker can't be moving + ; functions around within an object! + lea rdx, [trap wrt rip] + mov rax, [trap+rcx] + mov rax, trap + mov rbx, trap + ; MASM generates a REL32 reloc for this even though it's in + ; the same section. I don't know why, as the call instruction + ; below doesn't cause a reloc, so the linker can't be moving + ; functions around within an object! + movzx rax, byte [trap wrt rip] + movzx rax, byte [trap+rax] + ; with :abs ;mov ebx,[foobar2] ;mov rcx,offset foobar2 @@ -48,6 +70,8 @@ x86ident: ;movzx rax, byte ptr foobar2[rax] ; with :qword + ; See note above + mov ebx, foobar3 mov ebx, [foobar3 wrt rip] mov rcx, foobar3 lea rdx, [foobar3 wrt rip] @@ -58,6 +82,8 @@ x86ident: movzx rax, byte [foobar3+rax] ; local var (dword) + ; See note above + mov ebx, __savident mov ebx,[__savident wrt rip] mov rcx, __savident lea rdx, [__savident wrt rip] @@ -68,6 +94,8 @@ x86ident: movzx rax, byte [__savident+rax] ; local var (qword) + ; See note above + mov ebx, savidentptr2 mov ebx, [savidentptr2 wrt rip] mov rcx, savidentptr2 lea rdx, [savidentptr2 wrt rip] @@ -77,8 +105,22 @@ x86ident: movzx rax, byte [savidentptr2 wrt rip] movzx rax, byte [savidentptr2+rax] + ; bss local var (qword) + ; See note above + mov ebx, y + mov ebx, [y wrt rip] + mov rcx, y + lea rdx, [y wrt rip] + mov rax, [y+rcx] + mov rax, [y wrt rip] + mov rbx, [y wrt rip] + movzx rax, byte [y wrt rip] + movzx rax, byte [y+rax] + call foobar + call trap + ret trap: sub rsp, 256 @@ -88,7 +130,7 @@ trap: sub rsp, 256 [SECTION .pdata] dd trap -dd trap.end +dd trap+(trap.end-trap) dd $xdatasym [SECTION .xdata] diff --git a/modules/objfmts/win64/tests/win64-dataref.hex b/modules/objfmts/win64/tests/win64-dataref.hex index 615fb1f6..02b53df6 100644 --- a/modules/objfmts/win64/tests/win64-dataref.hex +++ b/modules/objfmts/win64/tests/win64-dataref.hex @@ -6,17 +6,17 @@ 00 00 00 -fa -04 +44 +06 00 00 -14 +27 00 00 00 00 00 -0c +04 00 2e 74 @@ -34,7 +34,7 @@ fa 00 00 00 -0a +a0 01 00 00 @@ -42,7 +42,7 @@ fa 01 00 00 -0e +a4 02 00 00 @@ -50,7 +50,7 @@ fa 00 00 00 -21 +33 00 00 00 @@ -66,7 +66,7 @@ fa 00 00 00 -0a +a0 01 00 00 @@ -78,12 +78,12 @@ fa 00 00 00 -58 -03 +a2 +04 00 00 -a4 -03 +ee +04 00 00 00 @@ -106,7 +106,7 @@ c0 00 00 00 -56 +ec 01 00 00 @@ -114,7 +114,7 @@ c0 00 00 00 -08 +10 00 00 00 @@ -146,7 +146,7 @@ c0 61 00 00 -5e +fc 01 00 00 @@ -158,12 +158,12 @@ c0 00 00 00 -1c -04 +66 +05 00 00 -28 -04 +72 +05 00 00 00 @@ -186,8 +186,8 @@ c0 61 00 00 -6a -01 +08 +02 00 00 00 @@ -198,8 +198,8 @@ c0 00 00 00 -46 -04 +90 +05 00 00 00 @@ -226,8 +226,8 @@ c0 00 00 00 -72 -01 +10 +02 00 00 00 @@ -238,12 +238,12 @@ c0 00 00 00 -4e -04 +98 +05 00 00 -96 -04 +e0 +05 00 00 00 @@ -323,6 +323,76 @@ b6 00 00 00 +bb +00 +00 +00 +00 +48 +b9 +00 +00 +00 +00 +00 +00 +00 +00 +48 +8d +15 +3a +01 +00 +00 +48 +8b +81 +00 +00 +00 +00 +48 +b8 +00 +00 +00 +00 +00 +00 +00 +00 +48 +bb +00 +00 +00 +00 +00 +00 +00 +00 +48 +0f +b6 +05 +17 +01 +00 +00 +48 +0f +b6 +80 +00 +00 +00 +00 +bb +00 +00 +00 +00 8b 1d 00 @@ -383,6 +453,11 @@ b6 00 00 00 +bb +00 +00 +00 +00 8b 1d 00 @@ -443,15 +518,20 @@ b6 00 00 00 +bb +00 +00 +00 +00 8b 1d -08 +00 00 00 00 48 b9 -08 +00 00 00 00 @@ -462,28 +542,28 @@ b9 48 8d 15 -08 +00 00 00 00 48 8b 81 -08 +00 00 00 00 48 8b 05 -08 +00 00 00 00 48 8b 1d -08 +00 00 00 00 @@ -491,7 +571,72 @@ b9 0f b6 05 -08 +00 +00 +00 +00 +48 +0f +b6 +80 +00 +00 +00 +00 +bb +00 +00 +00 +00 +8b +1d +00 +00 +00 +00 +48 +b9 +00 +00 +00 +00 +00 +00 +00 +00 +48 +8d +15 +00 +00 +00 +00 +48 +8b +81 +00 +00 +00 +00 +48 +8b +05 +00 +00 +00 +00 +48 +8b +1d +00 +00 +00 +00 +48 +0f +b6 +05 +00 00 00 00 @@ -499,7 +644,7 @@ b6 0f b6 80 -08 +00 00 00 00 @@ -508,6 +653,11 @@ e8 00 00 00 +e8 +01 +00 +00 +00 c3 48 81 @@ -604,67 +754,67 @@ c4 00 04 00 -43 +42 00 00 00 -08 +1c 00 00 00 04 00 -49 +48 00 00 00 -08 +1c 00 00 00 01 00 -54 +5a 00 00 00 -08 +1c 00 00 00 04 00 -5b +60 00 00 00 -08 +1c 00 00 00 -04 +01 00 -62 +6a 00 00 00 -08 +1c 00 00 00 -04 +01 00 -69 +7e 00 00 00 -08 +1c 00 00 00 04 00 -71 +83 00 00 00 @@ -674,7 +824,7 @@ c4 00 04 00 -79 +89 00 00 00 @@ -684,169 +834,349 @@ c4 00 04 00 -7f +8f 00 00 00 -0a +08 00 00 00 -04 +01 00 -85 +9a 00 00 00 -0a +08 00 00 00 -01 +04 00 -90 +a1 00 00 00 -0a +08 00 00 00 04 00 -97 +a8 00 00 00 -0a +08 00 00 00 04 00 -9e +af 00 00 00 -0a +08 00 00 00 04 00 -a5 +b7 00 00 00 -0a +08 00 00 00 04 00 -ad +bf 00 00 00 -0a +08 00 00 00 04 00 -b5 +c4 00 00 00 -0a +05 00 00 00 04 00 -bb +ca 00 00 00 -0a +05 00 00 00 04 00 -c1 +d0 00 00 00 -0a +05 00 00 00 01 00 -cc +db 00 00 00 -0a +05 00 00 00 04 00 -d3 +e2 00 00 00 -0a +05 00 00 00 04 00 -da +e9 00 00 00 -0a +05 00 00 00 04 00 -e1 +f0 00 00 00 -0a +05 00 00 00 04 00 -e9 +f8 00 00 00 -0a +05 +00 +00 +00 +04 +00 +00 +01 +00 +00 +05 00 00 00 04 00 -f1 +05 +01 00 00 +0d +00 +00 +00 +04 +00 +0b +01 +00 +00 +0d +00 +00 +00 +04 +00 +11 +01 +00 +00 +0d +00 +00 +00 +01 +00 +1c +01 +00 +00 +0d +00 +00 +00 +04 +00 +23 +01 +00 +00 +0d +00 +00 +00 +04 +00 +2a +01 +00 +00 +0d +00 +00 +00 +04 +00 +31 +01 +00 +00 +0d +00 +00 +00 +04 +00 +39 +01 +00 +00 +0d +00 +00 +00 +04 +00 +41 +01 +00 +00 +0d +00 +00 +00 +04 +00 +46 +01 +00 +00 +1b +00 +00 +00 +04 +00 +4c +01 +00 +00 +1b +00 +00 +00 +04 +00 +52 +01 +00 +00 +1b +00 +00 +00 +01 +00 +5d +01 +00 +00 +1b +00 00 -0a +00 +04 +00 +64 +01 +00 +00 +1b +00 +00 +00 +04 +00 +6b +01 +00 +00 +1b +00 +00 +00 +04 +00 +72 +01 +00 +00 +1b +00 +00 +00 +04 +00 +7a +01 +00 +00 +1b 00 00 00 04 00 -f6 +82 +01 +00 +00 +1b +00 00 00 +04 +00 +87 +01 +00 00 06 00 @@ -934,7 +1264,7 @@ f6 00 00 00 -0a +05 00 00 00 @@ -944,7 +1274,7 @@ f6 00 00 00 -0a +05 00 00 00 @@ -954,7 +1284,7 @@ f6 00 00 00 -02 +04 00 00 00 @@ -964,7 +1294,7 @@ f6 00 00 00 -02 +04 00 00 00 @@ -1034,7 +1364,7 @@ f6 00 00 00 -0c +16 00 00 00 @@ -1044,19 +1374,17 @@ f6 00 00 00 -0c +16 00 00 00 01 00 -fb 00 00 00 -0a -01 00 +0f 00 00 00 @@ -1066,7 +1394,9 @@ fb 00 00 00 -02 +00 +00 +1c 00 00 00 @@ -1076,7 +1406,7 @@ fb 00 00 00 -02 +1c 00 00 00 @@ -1086,7 +1416,7 @@ fb 00 00 00 -10 +20 00 00 00 @@ -1326,11 +1656,11 @@ ff 00 03 01 -0a +a0 01 00 00 -21 +33 00 00 00 @@ -1488,61 +1818,55 @@ ff 00 00 00 -2e -62 -73 -73 00 00 00 00 +0f 00 00 00 +04 00 -03 00 00 +02 00 -03 -01 -08 00 00 +03 00 00 00 00 00 +1b 00 00 00 +08 00 00 00 +02 00 00 00 +03 00 -2e -70 -64 -61 -74 -61 00 00 00 00 +28 00 00 -04 00 +10 00 00 -03 -01 -0c +00 +02 00 00 00 @@ -1552,73 +1876,346 @@ ff 00 00 00 +34 00 00 00 +14 00 00 00 +02 00 00 -2e -78 -64 -61 -74 -61 00 +03 00 00 00 00 00 -05 +41 00 00 00 -03 -01 -08 +1c 00 00 00 +02 00 00 00 +03 00 00 00 00 00 +4b 00 00 00 +20 00 00 00 -5f -46 -4f -4f +02 00 00 00 +03 00 00 00 00 00 -06 +56 00 00 00 -03 -01 -48 +28 00 00 00 -0a +02 +00 +00 +00 +03 +00 +00 +00 +00 +00 +61 +00 +00 +00 +2c +00 +00 +00 +02 +00 +00 +00 +03 +00 +00 +00 +00 +00 +6d +00 +00 +00 +34 +00 +00 +00 +02 +00 +00 +00 +03 +00 +00 +00 +00 +00 +78 +00 +00 +00 +38 +00 +00 +00 +02 +00 +00 +00 +03 +00 +78 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +03 +00 +00 +00 +03 +00 +78 +70 +74 +72 +00 +00 +00 +00 +40 +00 +00 +00 +02 +00 +00 +00 +03 +00 +78 +70 +74 +72 +32 +00 +00 +00 +44 +00 +00 +00 +02 +00 +00 +00 +03 +00 +2e +62 +73 +73 +00 +00 +00 +00 +00 +00 +00 +00 +03 +00 +00 +00 +03 +01 +10 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +79 +00 +00 +00 +00 +00 +00 +00 +08 +00 +00 +00 +03 +00 +00 +00 +03 +00 +74 +72 +61 +70 +00 +00 +00 +00 +91 +01 +00 +00 +01 +00 +00 +00 +03 +00 +74 +72 +61 +70 +2e +65 +6e +64 +a0 +01 +00 +00 +01 +00 +00 +00 +03 +00 +2e +70 +64 +61 +74 +61 +00 +00 +00 +00 +00 +00 +04 +00 +00 +00 +03 +01 +0c +00 +00 +00 +03 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +84 +00 +00 +00 +00 +00 +00 +00 +05 +00 +00 +00 +03 +00 +2e +78 +64 +61 +74 +61 +00 +00 +00 +00 +00 +00 +05 +00 +00 +00 +03 +01 +08 +00 00 00 00 @@ -1632,7 +2229,82 @@ ff 00 00 00 -0f +00 +00 +00 +5f +46 +4f +4f +00 +00 +00 +00 +00 +00 +00 +00 +06 +00 +00 +00 +03 +01 +48 +00 +00 +00 +0a +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +8e +00 +00 +00 +00 +00 +00 +00 +06 +00 +00 +00 +03 +00 +00 +00 +00 +00 +9d +00 +00 +00 +04 +00 +00 +00 +06 +00 +00 +00 +03 +00 +ad 00 00 00 @@ -1647,3 +2319,161 @@ ff 6e 74 00 +73 +61 +76 +69 +64 +65 +6e +74 +70 +74 +72 +00 +73 +61 +76 +69 +64 +65 +6e +74 +70 +74 +72 +32 +00 +78 +38 +36 +69 +64 +65 +6e +74 +70 +74 +72 +00 +78 +38 +36 +69 +64 +65 +6e +74 +70 +74 +72 +32 +00 +66 +6f +6f +62 +61 +72 +70 +74 +72 +00 +66 +6f +6f +62 +61 +72 +70 +74 +72 +32 +00 +66 +6f +6f +62 +61 +72 +32 +70 +74 +72 +00 +66 +6f +6f +62 +61 +72 +32 +70 +74 +72 +32 +00 +66 +6f +6f +62 +61 +72 +33 +70 +74 +72 +00 +66 +6f +6f +62 +61 +72 +33 +70 +74 +72 +32 +00 +24 +78 +64 +61 +74 +61 +73 +79 +6d +00 +66 +6f +6f +5f +66 +6f +6f +62 +61 +72 +33 +70 +74 +72 +00 +66 +6f +6f +5f +66 +6f +6f +62 +61 +72 +33 +70 +74 +72 +32 +00 diff --git a/modules/objfmts/win64/tests/win64-dataref.masm b/modules/objfmts/win64/tests/win64-dataref.masm index cfd43ad9..63042be8 100644 --- a/modules/objfmts/win64/tests/win64-dataref.masm +++ b/modules/objfmts/win64/tests/win64-dataref.masm @@ -27,11 +27,12 @@ xptr2 dq x _DATA ENDS _BSS SEGMENT x dq ? +y dq ? _BSS ENDS _TEXT SEGMENT x86ident: - ; with :proc + ; extern with :proc mov ebx,[foobar] mov rcx,offset foobar lea rdx, foobar @@ -41,6 +42,18 @@ x86ident: movzx rax, byte ptr foobar movzx rax, byte ptr foobar[rax] + ; local proc + mov ebx,[trap] + mov rcx,offset trap + ; See note in YASM file + lea rdx, trap + mov rax, qword ptr trap[rcx] + mov rax, trap + mov rbx, trap + ; See note in YASM file + movzx rax, byte ptr trap + movzx rax, byte ptr trap[rax] + ; with :abs ;mov ebx,[foobar2] ;mov rcx,offset foobar2 @@ -52,6 +65,7 @@ x86ident: ;movzx rax, byte ptr foobar2[rax] ; with :qword + mov ebx, offset foobar3 mov ebx, dword ptr [foobar3] mov rcx,offset foobar3 lea rdx, foobar3 @@ -62,6 +76,7 @@ x86ident: movzx rax, byte ptr foobar3[rax] ; local var (dword) + mov ebx, offset __savident mov ebx,[__savident] mov rcx,offset __savident lea rdx, __savident @@ -72,6 +87,7 @@ x86ident: movzx rax, byte ptr __savident[rax] ; local var (qword) + mov ebx, offset savidentptr2 mov ebx, dword ptr [savidentptr2] mov rcx,offset savidentptr2 lea rdx, savidentptr2 @@ -81,8 +97,21 @@ x86ident: movzx rax, byte ptr savidentptr2 movzx rax, byte ptr savidentptr2[rax] + ; bss local var (qword) + mov ebx, offset y + mov ebx, dword ptr [y] + mov rcx,offset y + lea rdx, y + mov rax, y[rcx] + mov rax, y + mov rbx, y + movzx rax, byte ptr y + movzx rax, byte ptr y[rax] + call foobar + call trap + ret trap proc public frame