Fix #139: Fix a number of issues with win32 safeseh support.

- Always create a non-global absolute symbol @feat.00 with value of 1.
- Set type field to 0x20 (function) for safeseh-declared symbols.
- Force safeseh-declared symbols into the symbol table, but don't force
  them to be global.

svn path=/trunk/yasm/; revision=2343
This commit is contained in:
Peter Johnson 2010-07-31 10:17:05 +00:00
parent 71afeff2eb
commit 86534657f2
9 changed files with 237 additions and 68 deletions

View file

@ -162,7 +162,9 @@ typedef enum coff_symtab_auxtype {
} coff_symtab_auxtype;
typedef struct coff_symrec_data {
int forcevis; /* force visibility in symbol table */
unsigned long index; /* assigned COFF symbol table index */
unsigned int type; /* type */
coff_symrec_sclass sclass; /* storage class */
int numaux; /* number of auxiliary entries */
@ -254,7 +256,9 @@ coff_objfmt_sym_set_data(yasm_symrec *sym, coff_symrec_sclass sclass,
sym_data = yasm_xmalloc(sizeof(coff_symrec_data) +
(numaux-1)*sizeof(coff_symtab_auxent));
sym_data->forcevis = 0;
sym_data->index = 0;
sym_data->type = 0;
sym_data->sclass = sclass;
sym_data->numaux = numaux;
sym_data->auxtype = auxtype;
@ -343,6 +347,17 @@ win32_objfmt_create(yasm_object *object)
}
objfmt_coff->win32 = 1;
/* Define a @feat.00 symbol for win32 safeseh handling */
if (!objfmt_coff->win64) {
yasm_symrec *feat00;
coff_symrec_data *sym_data;
feat00 = yasm_symtab_define_equ(object->symtab, "@feat.00",
yasm_expr_create_ident(yasm_expr_int(
yasm_intnum_create_uint(1)), 0), 0);
sym_data = coff_objfmt_sym_set_data(feat00, COFF_SCL_STAT, 0,
COFF_SYMTAB_AUX_NONE);
sym_data->forcevis = 1;
}
}
return (yasm_objfmt *)objfmt_coff;
}
@ -937,7 +952,8 @@ coff_objfmt_count_sym(yasm_symrec *sym, /*@null@*/ void *d)
sym_data = coff_objfmt_sym_set_data(sym, COFF_SCL_EXT, 0,
COFF_SYMTAB_AUX_NONE);
if (info->all_syms || vis != YASM_SYM_LOCAL || yasm_symrec_is_abs(sym)) {
if (info->all_syms || vis != YASM_SYM_LOCAL || yasm_symrec_is_abs(sym) ||
(sym_data && sym_data->forcevis)) {
/* Save index in symrec data */
if (!sym_data) {
sym_data = coff_objfmt_sym_set_data(sym, COFF_SCL_STAT, 0,
@ -956,18 +972,20 @@ coff_objfmt_output_sym(yasm_symrec *sym, /*@null@*/ void *d)
/*@null@*/ coff_objfmt_output_info *info = (coff_objfmt_output_info *)d;
yasm_sym_vis vis = yasm_symrec_get_visibility(sym);
int is_abs = yasm_symrec_is_abs(sym);
/*@dependent@*/ /*@null@*/ coff_symrec_data *csymd;
csymd = yasm_symrec_get_data(sym, &coff_symrec_data_cb);
assert(info != NULL);
/* Don't output local syms unless outputting all syms */
if (info->all_syms || vis != YASM_SYM_LOCAL || is_abs) {
if (info->all_syms || vis != YASM_SYM_LOCAL || is_abs ||
(csymd && csymd->forcevis)) {
/*@only*/ char *name;
const yasm_expr *equ_val;
const yasm_intnum *intn;
unsigned char *localbuf;
size_t len;
int aux;
/*@dependent@*/ /*@null@*/ coff_symrec_data *csymd;
unsigned long value = 0;
unsigned int scnum = 0xfffe; /* -2 = debugging symbol */
/*@dependent@*/ /*@null@*/ yasm_section *sect;
@ -983,7 +1001,6 @@ coff_objfmt_output_sym(yasm_symrec *sym, /*@null@*/ void *d)
len = strlen(name);
/* Get symrec's of_data (needed for storage class) */
csymd = yasm_symrec_get_data(sym, &coff_symrec_data_cb);
if (!csymd)
yasm_internal_error(N_("coff: expected sym data to be present"));
@ -1055,7 +1072,7 @@ coff_objfmt_output_sym(yasm_symrec *sym, /*@null@*/ void *d)
}
YASM_WRITE_32_L(localbuf, value); /* value */
YASM_WRITE_16_L(localbuf, scnum); /* section number */
YASM_WRITE_16_L(localbuf, 0); /* type is always zero (for now) */
YASM_WRITE_16_L(localbuf, csymd->type); /* type */
YASM_WRITE_8(localbuf, csymd->sclass); /* storage class */
YASM_WRITE_8(localbuf, csymd->numaux); /* number of aux entries */
fwrite(info->buf, 18, 1, info->f);
@ -1095,17 +1112,18 @@ coff_objfmt_output_str(yasm_symrec *sym, /*@null@*/ void *d)
{
/*@null@*/ coff_objfmt_output_info *info = (coff_objfmt_output_info *)d;
yasm_sym_vis vis = yasm_symrec_get_visibility(sym);
/*@dependent@*/ /*@null@*/ coff_symrec_data *csymd;
csymd = yasm_symrec_get_data(sym, &coff_symrec_data_cb);
assert(info != NULL);
/* Don't output local syms unless outputting all syms */
if (info->all_syms || vis != YASM_SYM_LOCAL) {
if (info->all_syms || vis != YASM_SYM_LOCAL ||
(csymd && csymd->forcevis)) {
/*@only@*/ char *name = yasm_symrec_get_global_name(sym, info->object);
/*@dependent@*/ /*@null@*/ coff_symrec_data *csymd;
size_t len = strlen(name);
int aux;
csymd = yasm_symrec_get_data(sym, &coff_symrec_data_cb);
if (!csymd)
yasm_internal_error(N_("coff: expected sym data to be present"));
@ -1676,13 +1694,20 @@ dir_safeseh(yasm_object *object, yasm_valparamhead *valparams,
yasm_section *sect;
/* Reference symbol (to generate error if not declared).
* Also, symbol must be externally visible, so force global.
* Also, symbol must be externally visible, so force it.
*/
vp = yasm_vps_first(valparams);
symname = yasm_vp_id(vp);
if (symname) {
coff_symrec_data *sym_data;
sym = yasm_symtab_use(object->symtab, symname, line);
yasm_symrec_declare(sym, YASM_SYM_GLOBAL, line);
sym_data = yasm_symrec_get_data(sym, &coff_symrec_data_cb);
if (!sym_data) {
sym_data = coff_objfmt_sym_set_data(sym, COFF_SCL_STAT, 0,
COFF_SYMTAB_AUX_NONE);
}
sym_data->forcevis = 1;
sym_data->type = 0x20; /* function */
} else {
yasm_error_set(YASM_ERROR_SYNTAX,
N_("argument to SAFESEH must be symbol name"));

View file

@ -10,7 +10,7 @@
00
00
00
07
08
00
00
00
@ -159,6 +159,24 @@ ff
00
00
00
40
66
65
61
74
2e
30
30
01
00
00
00
ff
ff
00
00
03
00
2e
74
65

View file

@ -10,7 +10,7 @@
03
00
00
18
19
00
00
00
@ -551,7 +551,7 @@ c2
00
00
00
08
09
00
00
00
@ -561,7 +561,7 @@ c2
00
00
00
09
0a
00
00
00
@ -571,7 +571,7 @@ c2
00
00
00
0a
0b
00
00
00
@ -581,7 +581,7 @@ c2
00
00
00
02
03
00
00
00
@ -591,7 +591,7 @@ c2
00
00
00
0c
0d
00
00
00
@ -601,7 +601,7 @@ c2
00
00
00
0d
0e
00
00
00
@ -611,7 +611,7 @@ b6
00
00
00
04
05
00
00
00
@ -621,7 +621,7 @@ c2
00
00
00
0c
0d
00
00
00
@ -631,7 +631,7 @@ ce
00
00
00
0e
0f
00
00
00
@ -641,7 +641,7 @@ db
00
00
00
04
05
00
00
00
@ -651,7 +651,7 @@ e0
00
00
00
04
05
00
00
00
@ -661,7 +661,7 @@ e7
00
00
00
0f
10
00
00
00
@ -671,7 +671,7 @@ e7
01
00
00
04
05
00
00
00
@ -681,7 +681,7 @@ e7
01
00
00
04
05
00
00
00
@ -691,7 +691,7 @@ e7
01
00
00
10
11
00
00
00
@ -701,7 +701,7 @@ e7
01
00
00
04
05
00
00
00
@ -711,7 +711,7 @@ e7
01
00
00
04
05
00
00
00
@ -721,7 +721,7 @@ e7
01
00
00
0f
10
00
00
00
@ -731,7 +731,7 @@ e7
01
00
00
11
12
00
00
00
@ -741,7 +741,7 @@ e7
01
00
00
12
13
00
00
00
@ -751,7 +751,7 @@ e7
01
00
00
13
14
00
00
00
@ -761,7 +761,7 @@ e7
01
00
00
14
15
00
00
00
@ -771,7 +771,7 @@ e7
01
00
00
15
16
00
00
00
@ -947,6 +947,24 @@ ff
00
00
00
40
66
65
61
74
2e
30
30
01
00
00
00
ff
ff
00
00
03
00
2e
74
65

View file

@ -10,7 +10,7 @@
01
00
00
0a
0b
00
00
00
@ -162,7 +162,7 @@ e8
00
00
00
06
07
00
00
00
@ -172,7 +172,7 @@ e8
00
00
00
06
07
00
00
00
@ -182,7 +182,7 @@ e8
00
00
00
06
07
00
00
00
@ -210,7 +210,7 @@ e8
00
00
00
08
09
00
00
00
@ -220,7 +220,7 @@ e8
00
00
00
08
09
00
00
00
@ -258,7 +258,7 @@ ff
00
00
00
06
07
00
00
00
@ -268,7 +268,7 @@ ff
00
00
00
06
07
00
00
00
@ -278,7 +278,7 @@ ff
00
00
00
06
07
00
00
00
@ -288,7 +288,7 @@ ff
00
00
00
06
07
00
00
00
@ -330,6 +330,24 @@ ff
00
00
00
40
66
65
61
74
2e
30
30
01
00
00
00
ff
ff
00
00
03
00
2e
74
65

View file

@ -10,7 +10,7 @@
01
00
00
0e
0f
00
00
00
@ -314,6 +314,24 @@ ff
00
00
00
40
66
65
61
74
2e
30
30
01
00
00
00
ff
ff
00
00
03
00
2e
74
65

View file

@ -10,7 +10,7 @@
00
00
00
04
05
00
00
00
@ -94,6 +94,24 @@ ff
00
00
00
40
66
65
61
74
2e
30
30
01
00
00
00
ff
ff
00
00
03
00
2e
74
65

View file

@ -10,7 +10,7 @@
00
00
00
08
09
00
00
00
@ -99,11 +99,11 @@
00
00
c3
04
05
00
00
00
07
08
00
00
00
@ -143,6 +143,24 @@ ff
00
00
00
40
66
65
61
74
2e
30
30
01
00
00
00
ff
ff
00
00
03
00
2e
74
65
@ -193,9 +211,9 @@ ff
00
01
00
20
00
00
02
03
00
2e
73
@ -247,9 +265,9 @@ ff
00
00
00
20
00
00
02
03
00
19
00

View file

@ -10,7 +10,7 @@
00
00
00
07
08
00
00
00
@ -114,7 +114,7 @@ c0
00
00
00
04
05
00
00
00
@ -124,7 +124,7 @@ c0
00
00
00
05
06
00
00
00
@ -166,6 +166,24 @@ ff
00
00
00
40
66
65
61
74
2e
30
30
01
00
00
00
ff
ff
00
00
03
00
2e
74
65

View file

@ -10,7 +10,7 @@
01
00
00
10
11
00
00
00
@ -203,7 +203,7 @@ c3
00
00
00
0e
0f
00
00
00
@ -213,7 +213,7 @@ c3
00
00
00
0e
0f
00
00
00
@ -223,7 +223,7 @@ c3
00
00
00
0b
0c
00
00
00
@ -233,7 +233,7 @@ c3
00
00
00
0c
0d
00
00
00
@ -243,7 +243,7 @@ c3
00
00
00
0e
0f
00
00
00
@ -253,7 +253,7 @@ c3
00
00
00
0c
0d
00
00
00
@ -263,7 +263,7 @@ c3
00
00
00
0a
0b
00
00
00
@ -337,7 +337,7 @@ c3
00
00
00
0e
0f
00
00
00
@ -347,7 +347,7 @@ c3
00
00
00
02
03
00
00
00
@ -357,7 +357,7 @@ c3
00
00
00
0c
0d
00
00
00
@ -399,6 +399,24 @@ ff
00
00
00
40
66
65
61
74
2e
30
30
01
00
00
00
ff
ff
00
00
03
00
2e
74
65