]> granicus.if.org Git - yasm/commitdiff
coff/win32/win64: Add support for .def, .scl, .type, and .endef directives.
authorPeter Johnson <peter@tortall.net>
Tue, 17 Aug 2010 05:32:46 +0000 (05:32 -0000)
committerPeter Johnson <peter@tortall.net>
Tue, 17 Aug 2010 05:32:46 +0000 (05:32 -0000)
These can be used to set a specific value for the coff sclass and type
symbol fields.

svn path=/trunk/yasm/; revision=2360

modules/dbgfmts/dwarf2/tests/passwin64/dwarfwin64_testhd.errwarn
modules/objfmts/coff/coff-objfmt.c
modules/objfmts/win32/tests/gas/Makefile.inc
modules/objfmts/win32/tests/gas/win32def.asm [new file with mode: 0644]
modules/objfmts/win32/tests/gas/win32def.hex [new file with mode: 0644]

index d383da2ab1c1ec9fdfce619e53169df8c8dd8e9d..be2a237ee3a2dfd6e148e2fa8a2680e52eefd114 100644 (file)
@@ -4,7 +4,7 @@
 -:10: warning: unrecognized section attribute: `M'
 -:10: warning: unrecognized section attribute: `S'
 -:10: warning: Unrecognized qualifier `progbits'
--:24: warning: directive `.type' not recognized
+-:24: warning: .type pseudo-op used outside of .def/.endef; ignored
 -:152: warning: directive `.size' not recognized
 -:153: warning: Unrecognized qualifier `progbits'
 -:190: warning: Unrecognized qualifier `progbits'
index 87bdd6b65728c3fefa86acd28a221fec243751a4..d2505e081c2f2cd2387cdc4e7fa7501c08f9847d 100644 (file)
@@ -183,6 +183,9 @@ typedef struct yasm_objfmt_coff {
 
     coff_symrec_data *filesym_data;         /* Data for .file symbol */
 
+    /* data for .def/.endef and related directives */
+    coff_symrec_data *def_sym;              /* symbol specified by .def */
+
     /* data for win64 proc_frame and related directives */
     unsigned long proc_frame;   /* Line number of start of proc, or 0 */
     unsigned long done_prolog;  /* Line number of end of prologue, or 0 */
@@ -1839,6 +1842,98 @@ dir_ident(yasm_object *object, yasm_valparamhead *valparams,
         yasm_bc_create_data(&dvs, 1, 1, object->arch, line));
 }
 
+static void
+dir_def(yasm_object *object, yasm_valparamhead *valparams,
+        yasm_valparamhead *objext_valparams, unsigned long line)
+{
+    yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
+    yasm_valparam *vp;
+    const char *symname;
+    yasm_symrec *sym;
+    coff_symrec_data *sym_data;
+
+    if (objfmt_coff->def_sym) {
+        yasm_warn_set(YASM_WARN_GENERAL,
+                      N_(".def pseudo-op used inside of .def/.endef; ignored"));
+        return;
+    }
+
+    vp = yasm_vps_first(valparams);
+    symname = yasm_vp_id(vp);
+    if (!symname) {
+        yasm_error_set(YASM_ERROR_SYNTAX,
+                       N_("argument to SAFESEH must be symbol name"));
+        return;
+    }
+
+    sym = yasm_symtab_get(object->symtab, symname);
+    sym_data = yasm_symrec_get_data(sym, &coff_symrec_data_cb);
+    if (!sym_data) {
+        sym_data = coff_objfmt_sym_set_data(sym, COFF_SCL_NULL, 0,
+                                            COFF_SYMTAB_AUX_NONE);
+    }
+    objfmt_coff->def_sym = sym_data;
+}
+
+static void
+dir_scl(yasm_object *object, yasm_valparamhead *valparams,
+        yasm_valparamhead *objext_valparams, unsigned long line)
+{
+    yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
+    yasm_intnum *intn = NULL;
+
+    if (!objfmt_coff->def_sym) {
+        yasm_warn_set(YASM_WARN_GENERAL,
+                      N_("%s pseudo-op used outside of .def/.endef; ignored"),
+                      ".scl");
+        return;
+    }
+
+    if (yasm_dir_helper_intn(object, yasm_vps_first(valparams), line,
+                             &intn, 0) < 0)
+        return;
+    if (!intn)
+        return;
+    objfmt_coff->def_sym->sclass = yasm_intnum_get_uint(intn);
+    yasm_intnum_destroy(intn);
+}
+
+static void
+dir_type(yasm_object *object, yasm_valparamhead *valparams,
+         yasm_valparamhead *objext_valparams, unsigned long line)
+{
+    yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
+    yasm_intnum *intn = NULL;
+
+    if (!objfmt_coff->def_sym) {
+        yasm_warn_set(YASM_WARN_GENERAL,
+                      N_("%s pseudo-op used outside of .def/.endef; ignored"),
+                      ".type");
+        return;
+    }
+
+    if (yasm_dir_helper_intn(object, yasm_vps_first(valparams), line,
+                             &intn, 0) < 0)
+        return;
+    if (!intn)
+        return;
+    objfmt_coff->def_sym->type = yasm_intnum_get_uint(intn);
+    yasm_intnum_destroy(intn);
+}
+
+static void
+dir_endef(yasm_object *object, yasm_valparamhead *valparams,
+          yasm_valparamhead *objext_valparams, unsigned long line)
+{
+    yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)object->objfmt;
+    if (!objfmt_coff->def_sym) {
+        yasm_warn_set(YASM_WARN_GENERAL,
+                      N_(".endef pseudo-op used before .def; ignored"));
+        return;
+    }
+    objfmt_coff->def_sym = NULL;
+}
+
 static void
 dir_proc_frame(yasm_object *object, /*@null@*/ yasm_valparamhead *valparams,
                yasm_valparamhead *objext_valparams, unsigned long line)
@@ -2194,6 +2289,10 @@ static const char *coff_objfmt_dbgfmt_keywords[] = {
 static const yasm_directive coff_objfmt_directives[] = {
     { ".ident",         "gas",  dir_ident,      YASM_DIR_ANY },
     { "ident",          "nasm", dir_ident,      YASM_DIR_ANY },
+    { ".def",           "gas",  dir_def,        YASM_DIR_ID_REQUIRED },
+    { ".endef",         "gas",  dir_endef,      YASM_DIR_ANY },
+    { ".scl",           "gas",  dir_scl,        YASM_DIR_ARG_REQUIRED },
+    { ".type",          "gas",  dir_type,       YASM_DIR_ARG_REQUIRED },
     { NULL, NULL, NULL, 0 }
 };
 
@@ -2228,6 +2327,10 @@ static const char *winXX_objfmt_dbgfmt_keywords[] = {
 static const yasm_directive win32_objfmt_directives[] = {
     { ".ident",         "gas",  dir_ident,      YASM_DIR_ANY },
     { "ident",          "nasm", dir_ident,      YASM_DIR_ANY },
+    { ".def",           "gas",  dir_def,        YASM_DIR_ID_REQUIRED },
+    { ".endef",         "gas",  dir_endef,      YASM_DIR_ANY },
+    { ".scl",           "gas",  dir_scl,        YASM_DIR_ARG_REQUIRED },
+    { ".type",          "gas",  dir_type,       YASM_DIR_ARG_REQUIRED },
     { ".export",        "gas",  dir_export,     YASM_DIR_ID_REQUIRED },
     { "export",         "nasm", dir_export,     YASM_DIR_ID_REQUIRED },
     { ".safeseh",       "gas",  dir_safeseh,    YASM_DIR_ID_REQUIRED },
@@ -2273,6 +2376,10 @@ yasm_objfmt_module yasm_win32_LTX_objfmt = {
 static const yasm_directive win64_objfmt_directives[] = {
     { ".ident",         "gas",  dir_ident,      YASM_DIR_ANY },
     { "ident",          "nasm", dir_ident,      YASM_DIR_ANY },
+    { ".def",           "gas",  dir_def,        YASM_DIR_ID_REQUIRED },
+    { ".endef",         "gas",  dir_endef,      YASM_DIR_ANY },
+    { ".scl",           "gas",  dir_scl,        YASM_DIR_ARG_REQUIRED },
+    { ".type",          "gas",  dir_type,       YASM_DIR_ARG_REQUIRED },
     { ".export",        "gas",  dir_export,     YASM_DIR_ID_REQUIRED },
     { "export",         "nasm", dir_export,     YASM_DIR_ID_REQUIRED },
     { ".proc_frame",    "gas",  dir_proc_frame, YASM_DIR_ID_REQUIRED },
index fb3192333bf27a3d9cc34a86e6fa9622f3380de1..8a00372ccf139f359e4b1a9da47a7f71f7fc7ace 100644 (file)
@@ -5,3 +5,5 @@ TESTS += modules/objfmts/win32/tests/gas/win32_gas_test.sh
 EXTRA_DIST += modules/objfmts/win32/tests/gas/win32_gas_test.sh
 EXTRA_DIST += modules/objfmts/win32/tests/gas/win32at.asm
 EXTRA_DIST += modules/objfmts/win32/tests/gas/win32at.hex
+EXTRA_DIST += modules/objfmts/win32/tests/gas/win32def.asm
+EXTRA_DIST += modules/objfmts/win32/tests/gas/win32def.hex
diff --git a/modules/objfmts/win32/tests/gas/win32def.asm b/modules/objfmts/win32/tests/gas/win32def.asm
new file mode 100644 (file)
index 0000000..e476466
--- /dev/null
@@ -0,0 +1,7 @@
+.globl label
+label:
+
+.def label
+.scl 2
+.type 32
+.endef
diff --git a/modules/objfmts/win32/tests/gas/win32def.hex b/modules/objfmts/win32/tests/gas/win32def.hex
new file mode 100644 (file)
index 0000000..bfedd51
--- /dev/null
@@ -0,0 +1,172 @@
+4c 
+01 
+01 
+00 
+00 
+00 
+00 
+00 
+3c 
+00 
+00 
+00 
+06 
+00 
+00 
+00 
+00 
+00 
+0c 
+01 
+2e 
+74 
+65 
+78 
+74 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+20 
+00 
+50 
+60 
+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 
+40 
+66 
+65 
+61 
+74 
+2e 
+30 
+30 
+01 
+00 
+00 
+00 
+ff 
+ff 
+00 
+00 
+03 
+00 
+2e 
+74 
+65 
+78 
+74 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+03 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+6c 
+61 
+62 
+65 
+6c 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+20 
+00 
+02 
+00 
+04 
+00 
+00 
+00