]> granicus.if.org Git - yasm/commitdiff
win64: Default to nobase for .xdata section.
authorPeter Johnson <peter@tortall.net>
Mon, 31 Oct 2011 05:21:57 +0000 (22:21 -0700)
committerPeter Johnson <peter@tortall.net>
Mon, 31 Oct 2011 05:21:57 +0000 (22:21 -0700)
Also add ..imagebase special symbol to force use of a nobase relocation.

[#135 state:resolved]

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

index 4278fa6d37169d6ca9905c41c0f51bea878a1dc6..c9646c627830d8dcad7c6e86a54282e6939909c1 100644 (file)
@@ -189,6 +189,8 @@ typedef struct yasm_objfmt_coff {
     unsigned long proc_frame;   /* Line number of start of proc, or 0 */
     unsigned long done_prolog;  /* Line number of end of prologue, or 0 */
     /*@null@*/ coff_unwind_info *unwind;        /* Unwind info */
+
+    yasm_symrec *ssym_imagebase;            /* ..imagebase symbol for win64 */
 } yasm_objfmt_coff;
 
 typedef struct coff_objfmt_output_info {
@@ -296,6 +298,7 @@ coff_common_create(yasm_object *object)
     objfmt_coff->proc_frame = 0;
     objfmt_coff->done_prolog = 0;
     objfmt_coff->unwind = NULL;
+    objfmt_coff->ssym_imagebase = NULL;
 
     return objfmt_coff;
 }
@@ -382,6 +385,8 @@ win64_objfmt_create(yasm_object *object)
         objfmt_coff->objfmt.module = &yasm_win64_LTX_objfmt;
         objfmt_coff->win32 = 1;
         objfmt_coff->win64 = 1;
+        objfmt_coff->ssym_imagebase =
+            yasm_symtab_define_label(object->symtab, "..imagebase", NULL, 0, 0);
     }
     return (yasm_objfmt *)objfmt_coff;
 }
@@ -489,14 +494,18 @@ coff_objfmt_output_value(yasm_value *value, unsigned char *buf,
         /*@dependent@*/ /*@null@*/ yasm_symrec *sym = value->rel;
         unsigned long addr;
         coff_reloc *reloc;
+        int nobase = info->csd->flags2 & COFF_FLAG_NOBASE;
 
         /* 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!
          */
-        if (value->wrt) {
+        if (value->wrt && value->wrt == objfmt_coff->ssym_imagebase)
+            nobase = 1;
+        else if (value->wrt) {
             /*@dependent@*/ /*@null@*/ yasm_bytecode *rel_precbc, *wrt_precbc;
+
             if (!yasm_symrec_get_label(sym, &rel_precbc)
                 || !yasm_symrec_get_label(value->wrt, &wrt_precbc)) {
                 yasm_error_set(YASM_ERROR_TOO_COMPLEX,
@@ -644,13 +653,13 @@ coff_objfmt_output_value(yasm_value *value, unsigned char *buf,
                 yasm_internal_error(N_("coff objfmt: unrecognized machine"));
         } else {
             if (objfmt_coff->machine == COFF_MACHINE_I386) {
-                if (info->csd->flags2 & COFF_FLAG_NOBASE)
+                if (nobase)
                     reloc->type = COFF_RELOC_I386_ADDR32NB;
                 else
                     reloc->type = COFF_RELOC_I386_ADDR32;
             } else if (objfmt_coff->machine == COFF_MACHINE_AMD64) {
                 if (valsize == 32) {
-                    if (info->csd->flags2 & COFF_FLAG_NOBASE)
+                    if (nobase)
                         reloc->type = COFF_RELOC_AMD64_ADDR32NB;
                     else
                         reloc->type = COFF_RELOC_AMD64_ADDR32;
@@ -1514,6 +1523,7 @@ coff_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
     } else if (objfmt_coff->win64 && strcmp(sectname, ".xdata") == 0) {
         data.flags = COFF_STYP_DATA | COFF_STYP_READ;
         align = 8;
+        data.flags2 = COFF_FLAG_NOBASE;
     } else if (objfmt_coff->win32 && strcmp(sectname, ".sxdata") == 0) {
         data.flags = COFF_STYP_INFO;
     } else if (strcmp(sectname, ".comment") == 0) {
@@ -1596,6 +1606,17 @@ coff_objfmt_get_special_sym(yasm_object *object, const char *name,
     return NULL;
 }
 
+static /*@observer@*/ /*@null@*/ yasm_symrec *
+win64_objfmt_get_special_sym(yasm_object *object, const char *name,
+                             const char *parser)
+{
+    if (yasm__strcasecmp(name, "imagebase") == 0) {
+        yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
+        return objfmt_coff->ssym_imagebase;
+    }
+    return NULL;
+}
+
 static void
 coff_section_data_destroy(void *data)
 {
@@ -2465,7 +2486,7 @@ yasm_objfmt_module yasm_win64_LTX_objfmt = {
     coff_objfmt_add_default_section,
     coff_objfmt_init_new_section,
     coff_objfmt_section_switch,
-    coff_objfmt_get_special_sym
+    win64_objfmt_get_special_sym
 };
 yasm_objfmt_module yasm_x64_LTX_objfmt = {
     "Win64",
@@ -2483,5 +2504,5 @@ yasm_objfmt_module yasm_x64_LTX_objfmt = {
     coff_objfmt_add_default_section,
     coff_objfmt_init_new_section,
     coff_objfmt_section_switch,
-    coff_objfmt_get_special_sym
+    win64_objfmt_get_special_sym
 };
index d10962685554f146a13c3edae7477ab785f69c87..24584267e78988c39c72de4c3cb39dd582d60ae5 100644 (file)
@@ -27,6 +27,8 @@ EXTRA_DIST += modules/objfmts/win64/tests/win64-dataref.masm
 EXTRA_DIST += modules/objfmts/win64/tests/win64-dataref2.asm
 EXTRA_DIST += modules/objfmts/win64/tests/win64-dataref2.hex
 EXTRA_DIST += modules/objfmts/win64/tests/win64-dataref2.masm
+EXTRA_DIST += modules/objfmts/win64/tests/win64-imagebase.hex
+EXTRA_DIST += modules/objfmts/win64/tests/win64-imagebase.asm
 
 EXTRA_DIST += modules/objfmts/win64/tests/gas/Makefile.inc
 
diff --git a/modules/objfmts/win64/tests/win64-imagebase.asm b/modules/objfmts/win64/tests/win64-imagebase.asm
new file mode 100644 (file)
index 0000000..bd63602
--- /dev/null
@@ -0,0 +1,17 @@
+[section .text]
+handler: ret
+func:  ret
+func_end:
+
+[section .pdata]
+       dd func
+       dd func_end
+       dd myunwnd
+
+[section .xdata]
+myunwnd:
+       db 9,0,0,0
+       dd handler
+
+[section .foo]
+       dd handler wrt ..imagebase
diff --git a/modules/objfmts/win64/tests/win64-imagebase.hex b/modules/objfmts/win64/tests/win64-imagebase.hex
new file mode 100644 (file)
index 0000000..b715eb4
--- /dev/null
@@ -0,0 +1,512 @@
+64 
+86 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+0e 
+00 
+00 
+00 
+00 
+00 
+04 
+00 
+2e 
+74 
+65 
+78 
+74 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+b4 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+20 
+00 
+50 
+60 
+2e 
+70 
+64 
+61 
+74 
+61 
+00 
+00 
+02 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+0c 
+00 
+00 
+00 
+b6 
+00 
+00 
+00 
+c2 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+40 
+00 
+30 
+40 
+2e 
+78 
+64 
+61 
+74 
+61 
+00 
+00 
+0e 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+08 
+00 
+00 
+00 
+e0 
+00 
+00 
+00 
+e8 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+40 
+00 
+40 
+40 
+2e 
+66 
+6f 
+6f 
+00 
+00 
+00 
+00 
+16 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+f2 
+00 
+00 
+00 
+f6 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+20 
+00 
+00 
+60 
+c3 
+c3 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+05 
+00 
+00 
+00 
+03 
+00 
+04 
+00 
+00 
+00 
+06 
+00 
+00 
+00 
+03 
+00 
+08 
+00 
+00 
+00 
+09 
+00 
+00 
+00 
+03 
+00 
+09 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+03 
+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 
+02 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+68 
+61 
+6e 
+64 
+6c 
+65 
+72 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+03 
+00 
+66 
+75 
+6e 
+63 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+03 
+00 
+66 
+75 
+6e 
+63 
+5f 
+65 
+6e 
+64 
+02 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+03 
+00 
+2e 
+70 
+64 
+61 
+74 
+61 
+00 
+00 
+00 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+03 
+01 
+0c 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+6d 
+79 
+75 
+6e 
+77 
+6e 
+64 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+03 
+00 
+2e 
+78 
+64 
+61 
+74 
+61 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+03 
+01 
+08 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+2e 
+66 
+6f 
+6f 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+03 
+01 
+04 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+04 
+00 
+00 
+00