summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Johnson <peter@tortall.net>2012-10-19 17:23:26 -0700
committerPeter Johnson <peter@tortall.net>2012-10-19 17:25:27 -0700
commit1db998a3d35377f96744cf596bc904461eda796b (patch)
treeacda04ae9587c358e1815fe70f4b1428fa003b89
parent8dd87f6b1677f56ec58c9302134c9c7f8d5230ef (diff)
downloadyasm-1db998a3d35377f96744cf596bc904461eda796b.tar.gz
Add support for "function" decorator in win32/win64.
This can be used on global directives (e.g. global _foo:function) to indicate the global is a function. This is useful for incremental linking in MSVC.
-rw-r--r--modules/objfmts/coff/coff-objfmt.c11
-rw-r--r--modules/objfmts/win64/tests/Makefile.inc2
-rw-r--r--modules/objfmts/win64/tests/win64-function.asm4
-rw-r--r--modules/objfmts/win64/tests/win64-function.hex154
4 files changed, 171 insertions, 0 deletions
diff --git a/modules/objfmts/coff/coff-objfmt.c b/modules/objfmts/coff/coff-objfmt.c
index c9646c62..c42bf7e3 100644
--- a/modules/objfmts/coff/coff-objfmt.c
+++ b/modules/objfmts/coff/coff-objfmt.c
@@ -988,10 +988,21 @@ coff_objfmt_output_sym(yasm_symrec *sym, /*@null@*/ void *d)
yasm_sym_vis vis = yasm_symrec_get_visibility(sym);
int is_abs = yasm_symrec_is_abs(sym);
/*@dependent@*/ /*@null@*/ coff_symrec_data *csymd;
+ yasm_valparamhead *objext_valparams =
+ yasm_symrec_get_objext_valparams(sym);
csymd = yasm_symrec_get_data(sym, &coff_symrec_data_cb);
assert(info != NULL);
+ /* Look for "function" flag on global syms */
+ if (csymd && csymd->type == 0 && (vis & YASM_SYM_GLOBAL) != 0) {
+ if (objext_valparams) {
+ const char *id = yasm_vp_id(yasm_vps_first(objext_valparams));
+ if (yasm__strcasecmp(id, "function") == 0)
+ csymd->type = 0x20;
+ }
+ }
+
/* Don't output local syms unless outputting all syms */
if (info->all_syms || vis != YASM_SYM_LOCAL || is_abs ||
(csymd && csymd->forcevis)) {
diff --git a/modules/objfmts/win64/tests/Makefile.inc b/modules/objfmts/win64/tests/Makefile.inc
index 24584267..4062fc33 100644
--- a/modules/objfmts/win64/tests/Makefile.inc
+++ b/modules/objfmts/win64/tests/Makefile.inc
@@ -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-function.asm
+EXTRA_DIST += modules/objfmts/win64/tests/win64-function.hex
EXTRA_DIST += modules/objfmts/win64/tests/win64-imagebase.hex
EXTRA_DIST += modules/objfmts/win64/tests/win64-imagebase.asm
diff --git a/modules/objfmts/win64/tests/win64-function.asm b/modules/objfmts/win64/tests/win64-function.asm
new file mode 100644
index 00000000..b1af165c
--- /dev/null
+++ b/modules/objfmts/win64/tests/win64-function.asm
@@ -0,0 +1,4 @@
+global _foo:function
+
+_foo:
+
diff --git a/modules/objfmts/win64/tests/win64-function.hex b/modules/objfmts/win64/tests/win64-function.hex
new file mode 100644
index 00000000..ad94a4dd
--- /dev/null
+++ b/modules/objfmts/win64/tests/win64-function.hex
@@ -0,0 +1,154 @@
+64
+86
+01
+00
+00
+00
+00
+00
+3c
+00
+00
+00
+05
+00
+00
+00
+00
+00
+04
+00
+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
+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
+5f
+66
+6f
+6f
+00
+00
+00
+00
+00
+00
+00
+00
+01
+00
+20
+00
+02
+00
+04
+00
+00
+00