Browse Source

Implement __attribute__((nodecorate))

Prevent any decoration that would otherwise affect an exported
PE function. For example, given the following:

__declspec(dllexport) __stdcall
int decorated(int arg) {
    return 0;
}

__declspec(dllexport) __stdcall __attribute__((nodecorate))
int undecorated(int arg) {
    return 0;
}

The following exported functions can now be seen in the DLL:
_decorated@4
undecorated

The attribute is recognised for all targets but only
affects PE codegen. I'm not sure whether this would be
useful for other targets; its intended use was to allow
the creation of a DLL matching an existing set of signatures.
Jonathan Newman 1 year ago
parent
commit
0edbed1d52
4 changed files with 12 additions and 1 deletions
  1. 3 0
      tcc-doc.texi
  2. 2 1
      tcc.h
  3. 6 0
      tccgen.c
  4. 1 0
      tcctok.h

+ 3 - 0
tcc-doc.texi

@@ -548,6 +548,7 @@ instead of
 @cindex stdcall attribute
 @cindex regparm attribute
 @cindex dllexport attribute
+@cindex nodecorate attribute
 
 @item The keyword @code{__attribute__} is handled to specify variable or
 function attributes. The following attributes are supported:
@@ -575,6 +576,8 @@ registers @code{%eax}, @code{%edx} and @code{%ecx}.
 
   @item @code{dllexport}: export function from dll/executable (win32 only)
 
+  @item @code{nodecorate}: do not apply any decorations that would otherwise be applied when exporting function from dll/executable (win32 only)
+
   @end itemize
 
 Here are some examples:

+ 2 - 1
tcc.h

@@ -439,8 +439,9 @@ struct SymAttr {
     weak        : 1,
     visibility  : 2,
     dllexport   : 1,
+    nodecorate  : 1,
     dllimport   : 1,
-    unused      : 5;
+    unused      : 4;
 };
 
 /* function attributes or temporary attributes for parsing */

+ 6 - 0
tccgen.c

@@ -391,6 +391,9 @@ ST_FUNC void put_extern_sym2(Sym *sym, int sh_num,
 #ifdef TCC_TARGET_PE
         if (sym_type == STT_FUNC && sym->type.ref) {
             Sym *ref = sym->type.ref;
+            if (ref->a.nodecorate) {
+                can_add_underscore = 0;
+            }
             if (ref->f.func_call == FUNC_STDCALL && can_add_underscore) {
                 sprintf(buf1, "_%s@%d", name, ref->f.func_args * PTR_SIZE);
                 name = buf1;
@@ -3438,6 +3441,9 @@ redo:
         case TOK_DLLEXPORT:
             ad->a.dllexport = 1;
             break;
+        case TOK_NODECORATE:
+            ad->a.nodecorate = 1;
+            break;
         case TOK_DLLIMPORT:
             ad->a.dllimport = 1;
             break;

+ 1 - 0
tcctok.h

@@ -132,6 +132,7 @@
 
      DEF(TOK_DLLEXPORT, "dllexport")
      DEF(TOK_DLLIMPORT, "dllimport")
+     DEF(TOK_NODECORATE, "nodecorate")
      DEF(TOK_NORETURN1, "noreturn")
      DEF(TOK_NORETURN2, "__noreturn__")
      DEF(TOK_VISIBILITY1, "visibility")