Fix #130: Add SAFESEH directive for indicating SEH handlers in win32 output.

Unlike in MASM, no command-line switch is required.
Usage:
  extern handler (or handler: to define locally)
  safeseh handler

svn path=/trunk/yasm/; revision=2032
0.7.0
Peter Johnson 17 years ago
parent 2fe53b2c29
commit 0fba7dca8d
  1. 107
      modules/objfmts/coff/coff-objfmt.c
  2. 3
      modules/objfmts/win32/tests/Makefile.inc
  3. 5
      modules/objfmts/win32/tests/win32-safeseh.asm
  4. 278
      modules/objfmts/win32/tests/win32-safeseh.hex
  5. 10
      modules/objfmts/win32/tests/win32-safeseh.masm
  6. 4
      modules/preprocs/nasm/standard.mac

@ -218,6 +218,28 @@ static const yasm_assoc_data_callback coff_symrec_data_cb = {
coff_symrec_data_print
};
/* Bytecode callback function prototypes */
static void win32_sxdata_bc_destroy(void *contents);
static void win32_sxdata_bc_print(const void *contents, FILE *f,
int indent_level);
static int win32_sxdata_bc_calc_len
(yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data);
static int win32_sxdata_bc_tobytes
(yasm_bytecode *bc, unsigned char **bufp, void *d,
yasm_output_value_func output_value,
/*@null@*/ yasm_output_reloc_func output_reloc);
/* Bytecode callback structures */
static const yasm_bytecode_callback win32_sxdata_bc_callback = {
win32_sxdata_bc_destroy,
win32_sxdata_bc_print,
yasm_bc_finalize_common,
win32_sxdata_bc_calc_len,
yasm_bc_expand_common,
win32_sxdata_bc_tobytes,
0
};
yasm_objfmt_module yasm_coff_LTX_objfmt;
yasm_objfmt_module yasm_win32_LTX_objfmt;
yasm_objfmt_module yasm_win64_LTX_objfmt;
@ -1478,6 +1500,8 @@ 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;
} else if (objfmt_coff->win32 && strcmp(sectname, ".sxdata") == 0) {
data.flags = COFF_STYP_INFO;
} else if (strcmp(sectname, ".comment") == 0) {
data.flags = COFF_STYP_INFO | COFF_STYP_DISCARD | COFF_STYP_READ;
} else if (yasm__strncasecmp(sectname, ".debug", 6)==0) {
@ -1649,6 +1673,88 @@ dir_export(yasm_object *object, yasm_valparamhead *valparams,
yasm_section_bcs_append(sect, yasm_bc_create_data(&dvs, 1, 0, NULL, line));
}
static void
dir_safeseh(yasm_object *object, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams, unsigned long line)
{
yasm_valparam *vp;
/*@null@*/ const char *symname;
yasm_symrec *sym;
int isnew;
yasm_section *sect;
/* Reference symbol (to generate error if not declared).
* Also, symbol must be externally visible, so force global.
*/
vp = yasm_vps_first(valparams);
symname = yasm_vp_id(vp);
if (symname) {
sym = yasm_symtab_use(object->symtab, symname, line);
yasm_symrec_declare(sym, YASM_SYM_GLOBAL, line);
} else {
yasm_error_set(YASM_ERROR_SYNTAX,
N_("argument to SAFESEH must be symbol name"));
return;
}
/*
* Add symbol number to end of .sxdata section.
*/
sect = yasm_object_get_general(object, ".sxdata", 0, 0, 0, &isnew, line);
/* Initialize sxdata section if needed */
if (isnew) {
coff_section_data *csd;
csd = coff_objfmt_init_new_section(object, sect, ".sxdata", line);
csd->flags = COFF_STYP_INFO;
}
/* Add as sxdata bytecode */
yasm_section_bcs_append(sect,
yasm_bc_create_common(&win32_sxdata_bc_callback,
sym, line));
}
static void
win32_sxdata_bc_destroy(void *contents)
{
/* Contents is just the symbol pointer, so no need to delete */
}
static void
win32_sxdata_bc_print(const void *contents, FILE *f, int indent_level)
{
/* TODO */
}
static int
win32_sxdata_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
void *add_span_data)
{
bc->len += 4;
return 0;
}
static int
win32_sxdata_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
yasm_output_value_func output_value,
yasm_output_reloc_func output_reloc)
{
yasm_symrec *sym = (yasm_symrec *)bc->contents;
unsigned char *buf = *bufp;
coff_symrec_data *csymd;
csymd = yasm_symrec_get_data(sym, &coff_symrec_data_cb);
if (!csymd)
yasm_internal_error(N_("coff: no symbol data for SAFESEH symbol"));
YASM_WRITE_32_L(buf, csymd->index);
*bufp = buf;
return 0;
}
static void
dir_ident(yasm_object *object, yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams, unsigned long line)
@ -2099,6 +2205,7 @@ static const yasm_directive win32_objfmt_directives[] = {
{ ".export", "gas", dir_export, YASM_DIR_ID_REQUIRED },
{ "ident", "nasm", dir_ident, YASM_DIR_ANY },
{ "export", "nasm", dir_export, YASM_DIR_ID_REQUIRED },
{ "safeseh", "nasm", dir_safeseh, YASM_DIR_ID_REQUIRED },
{ NULL, NULL, NULL, 0 }
};

@ -9,6 +9,9 @@ EXTRA_DIST += modules/objfmts/win32/tests/win32-curpos.asm
EXTRA_DIST += modules/objfmts/win32/tests/win32-curpos.hex
EXTRA_DIST += modules/objfmts/win32/tests/win32-overdef.asm
EXTRA_DIST += modules/objfmts/win32/tests/win32-overdef.hex
EXTRA_DIST += modules/objfmts/win32/tests/win32-safeseh.asm
EXTRA_DIST += modules/objfmts/win32/tests/win32-safeseh.hex
EXTRA_DIST += modules/objfmts/win32/tests/win32-safeseh.masm
EXTRA_DIST += modules/objfmts/win32/tests/win32-segof.asm
EXTRA_DIST += modules/objfmts/win32/tests/win32-segof.hex
EXTRA_DIST += modules/objfmts/win32/tests/win32test.c

@ -0,0 +1,5 @@
MyHandler:
ret
safeseh MyHandler
extern MyHandler3
safeseh MyHandler3

@ -0,0 +1,278 @@
4c
01
02
00
00
00
00
00
6d
00
00
00
08
00
00
00
00
00
0c
01
2e
74
65
78
74
00
00
00
00
00
00
00
00
00
00
00
01
00
00
00
64
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
20
00
50
60
2e
73
78
64
61
74
61
00
01
00
00
00
00
00
00
00
08
00
00
00
65
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
02
00
00
c3
04
00
00
00
07
00
00
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
01
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
04
00
00
00
00
00
00
00
01
00
00
00
02
00
2e
73
78
64
61
74
61
00
00
00
00
00
02
00
00
00
03
01
08
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
0e
00
00
00
00
00
00
00
00
00
00
00
02
00
19
00
00
00
4d
79
48
61
6e
64
6c
65
72
00
4d
79
48
61
6e
64
6c
65
72
33
00

@ -0,0 +1,10 @@
.386
.model flat
_TEXT SEGMENT USE32 PUBLIC 'CODE'
MyHandler proc
.safeseh MyHandler
MyHandler endp
_TEXT ENDS
MyHandler3 proto
.safeseh MyHandler3
end

@ -131,6 +131,10 @@ __SECT__
%imacro export 1+.nolist
[export %1]
%endmacro
%imacro safeseh 1+.nolist
[safeseh %1]
%endmacro
%endif
%ifidn __YASM_OBJFMT__,win64

Loading…
Cancel
Save