From 5fb3213be3b2cd2b21ea5e6990f32a46e161b02d Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Tue, 17 Aug 2010 05:32:46 +0000 Subject: [PATCH] coff/win32/win64: Add support for .def, .scl, .type, and .endef directives. These can be used to set a specific value for the coff sclass and type symbol fields. svn path=/trunk/yasm/; revision=2360 --- .../tests/passwin64/dwarfwin64_testhd.errwarn | 2 +- modules/objfmts/coff/coff-objfmt.c | 107 +++++++++++ modules/objfmts/win32/tests/gas/Makefile.inc | 2 + modules/objfmts/win32/tests/gas/win32def.asm | 7 + modules/objfmts/win32/tests/gas/win32def.hex | 172 ++++++++++++++++++ 5 files changed, 289 insertions(+), 1 deletion(-) create mode 100644 modules/objfmts/win32/tests/gas/win32def.asm create mode 100644 modules/objfmts/win32/tests/gas/win32def.hex diff --git a/modules/dbgfmts/dwarf2/tests/passwin64/dwarfwin64_testhd.errwarn b/modules/dbgfmts/dwarf2/tests/passwin64/dwarfwin64_testhd.errwarn index d383da2a..be2a237e 100644 --- a/modules/dbgfmts/dwarf2/tests/passwin64/dwarfwin64_testhd.errwarn +++ b/modules/dbgfmts/dwarf2/tests/passwin64/dwarfwin64_testhd.errwarn @@ -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' diff --git a/modules/objfmts/coff/coff-objfmt.c b/modules/objfmts/coff/coff-objfmt.c index 87bdd6b6..d2505e08 100644 --- a/modules/objfmts/coff/coff-objfmt.c +++ b/modules/objfmts/coff/coff-objfmt.c @@ -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 }, diff --git a/modules/objfmts/win32/tests/gas/Makefile.inc b/modules/objfmts/win32/tests/gas/Makefile.inc index fb319233..8a00372c 100644 --- a/modules/objfmts/win32/tests/gas/Makefile.inc +++ b/modules/objfmts/win32/tests/gas/Makefile.inc @@ -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 index 00000000..e4764668 --- /dev/null +++ b/modules/objfmts/win32/tests/gas/win32def.asm @@ -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 index 00000000..bfedd51b --- /dev/null +++ b/modules/objfmts/win32/tests/gas/win32def.hex @@ -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 -- 2.40.0