From c8be7b7a3f99251d9844edbd41162ba2c21b38c0 Mon Sep 17 00:00:00 2001 From: "knut st. osmundsen" Date: Mon, 11 May 2026 01:19:23 +0200 Subject: [PATCH] outcoff.c: Added support for 'function' type on global symbols. Setting the symbol type is necessary for the control flow guard (CFG) stuff on windows. Signed-off-by: H. Peter Anvin (Intel) --- output/outcoff.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/output/outcoff.c b/output/outcoff.c index db8b5ca3d..adcaf3a41 100644 --- a/output/outcoff.c +++ b/output/outcoff.c @@ -549,9 +549,8 @@ static void coff_deflabel(char *name, int32_t segment, int64_t offset, int pos, section; struct coff_Symbol *sym; - if (special) - nasm_nonfatal("COFF format does not support any" - " special symbol types"); + nasm_debug(2, " coff_deflabel: %s, seg=%"PRIx32", off=%"PRIx64", is_global=%d, %s, coff_nsyms=%"PRIu32"\n", + name, segment, offset, is_global, special, coff_nsyms); if (name[0] == '.' && name[1] == '.' && name[2] != '@') { if (strcmp(name,WRT_IMAGEBASE) && strcmp(name, WRT_SYMTAB)) @@ -559,6 +558,9 @@ static void coff_deflabel(char *name, int32_t segment, int64_t offset, return; } + if (is_global == 3) /* discard special-retry from pass two. */ + return; + if (segment == NO_SEG) section = -1; /* absolute symbol */ else { @@ -608,6 +610,20 @@ static void coff_deflabel(char *name, int32_t segment, int64_t offset, else sym->value = (sym->section == 0 ? 0 : offset); + if (special) { + special = nasm_skip_spaces(special); + while (*special) { + const char *wend = nasm_skip_word(special); + size_t wlen = wend - special; + if (wlen == 8 && !nasm_strnicmp(special, "function", 8)) + sym->type = 0x20; /* DT_FCN */ + else + nasm_nonfatal("unrecognised symbol type `%*.*s' on `%s'", + (int)wlen, (int)wlen, special, name); + special = nasm_skip_spaces(wend); + } + } + /* * define the references from external-symbol segment numbers * to these symbol records.