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.
Unified · Split
| @@ -548,6 +548,7 @@ instead of · 547 unmodified lines | ||
| 548 | 548 | @cindex stdcall attribute |
| 549 | 549 | @cindex regparm attribute |
| 550 | 550 | @cindex dllexport attribute |
| 551 | +@cindex nodecorate attribute | |
| 551 | 552 | |
| 552 | 553 | @item The keyword @code{__attribute__} is handled to specify variable or |
| 553 | 554 | function attributes. The following attributes are supported: |
| @@ -575,6 +576,8 @@ registers @code{%eax}, @code{%edx} and @code{%ecx}. · 21 unmodified lines | ||
| 575 | 576 | |
| 576 | 577 | @item @code{dllexport}: export function from dll/executable (win32 only) |
| 577 | 578 | |
| 579 | + @item @code{nodecorate}: do not apply any decorations that would otherwise be applied when exporting function from dll/executable (win32 only) | |
| 580 | + | |
| 578 | 581 | @end itemize |
| 579 | 582 | |
| 580 | 583 | Here are some examples: |
| @@ -439,8 +439,9 @@ struct SymAttr { · 438 unmodified lines | ||
| 439 | 439 | weak : 1, |
| 440 | 440 | visibility : 2, |
| 441 | 441 | dllexport : 1, |
| 442 | + nodecorate : 1, | |
| 442 | 443 | dllimport : 1, |
| 443 | − unused : 5; | |
| 444 | + unused : 4; | |
| 444 | 445 | }; |
| 445 | 446 | |
| 446 | 447 | /* function attributes or temporary attributes for parsing */ |
| @@ -391,6 +391,9 @@ ST_FUNC void put_extern_sym2(Sym *sym, int sh_num, · 390 unmodified lines | ||
| 391 | 391 | #ifdef TCC_TARGET_PE |
| 392 | 392 | if (sym_type == STT_FUNC && sym->type.ref) { |
| 393 | 393 | Sym *ref = sym->type.ref; |
| 394 | + if (ref->a.nodecorate) { | |
| 395 | + can_add_underscore = 0; | |
| 396 | + } | |
| 394 | 397 | if (ref->f.func_call == FUNC_STDCALL && can_add_underscore) { |
| 395 | 398 | sprintf(buf1, "_%s@%d", name, ref->f.func_args * PTR_SIZE); |
| 396 | 399 | name = buf1; |
| @@ -3438,6 +3441,9 @@ redo: · 3041 unmodified lines | ||
| 3438 | 3441 | case TOK_DLLEXPORT: |
| 3439 | 3442 | ad->a.dllexport = 1; |
| 3440 | 3443 | break; |
| 3444 | + case TOK_NODECORATE: | |
| 3445 | + ad->a.nodecorate = 1; | |
| 3446 | + break; | |
| 3441 | 3447 | case TOK_DLLIMPORT: |
| 3442 | 3448 | ad->a.dllimport = 1; |
| 3443 | 3449 | break; |
| @@ -132,6 +132,7 @@ · 131 unmodified lines | ||
| 132 | 132 | |
| 133 | 133 | DEF(TOK_DLLEXPORT, "dllexport") |
| 134 | 134 | DEF(TOK_DLLIMPORT, "dllimport") |
| 135 | + DEF(TOK_NODECORATE, "nodecorate") | |
| 135 | 136 | DEF(TOK_NORETURN1, "noreturn") |
| 136 | 137 | DEF(TOK_NORETURN2, "__noreturn__") |
| 137 | 138 | DEF(TOK_VISIBILITY1, "visibility") |