Skip to content

Instantly share code, notes, and snippets.

@UplinkCoder
Created February 8, 2022 10:56
Show Gist options
  • Save UplinkCoder/02aee91a30b7aa1c55f54fb22998948e to your computer and use it in GitHub Desktop.
Save UplinkCoder/02aee91a30b7aa1c55f54fb22998948e to your computer and use it in GitHub Desktop.
From 7050d61d1c8a14077d0399ad5a7422aad16b79a8 Mon Sep 17 00:00:00 2001
From: Stefan Koch <[email protected]>
Date: Tue, 8 Feb 2022 11:14:38 +0100
Subject: [PATCH] Add __attribute__(naked)
---
tcc.h | 3 ++-
tccgen.c | 13 +++++++++++--
tcctok.h | 1 +
3 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/tcc.h b/tcc.h
index ef69ef5..e8ed61d 100644
--- a/tcc.h
+++ b/tcc.h
@@ -548,7 +548,8 @@ struct FuncAttr {
func_dtor : 1, /* attribute((destructor)) */
func_args : 8, /* PE __stdcall args */
func_alwinl : 1, /* always_inline */
- xxxx : 15;
+ func_naked : 1, /* attribute((naked)) */
+ xxxx : 14;
};
/* symbol management */
diff --git a/tccgen.c b/tccgen.c
index 67e205b..18ac832 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -81,6 +81,7 @@ ST_DATA int global_expr; /* true if compound literals must be allocated globall
ST_DATA CType func_vt; /* current function return type (used by return instruction) */
ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */
ST_DATA int func_vc;
+ST_DATA int func_naked;
static int last_line_num, new_file, func_ind; /* debug info control */
ST_DATA const char *funcname;
ST_DATA CType int_type, func_old_type, char_type, char_pointer_type;
@@ -1686,6 +1687,8 @@ static void merge_funcattr(struct FuncAttr *fa, struct FuncAttr *fa1)
fa->func_args = fa1->func_args;
if (fa1->func_noreturn)
fa->func_noreturn = 1;
+ if (fa1->func_naked)
+ fa->func_naked = 1;
if (fa1->func_ctor)
fa->func_ctor = 1;
if (fa1->func_dtor)
@@ -4432,6 +4435,9 @@ redo:
case TOK_NORETURN2:
ad->f.func_noreturn = 1;
break;
+ case TOK_NAKED:
+ ad->f.func_naked = 1;
+ break;
case TOK_CDECL1:
case TOK_CDECL2:
case TOK_CDECL3:
@@ -8602,13 +8608,15 @@ static void gen_function(Sym *sym)
func_ind = ind;
func_vt = sym->type.ref->type;
func_var = sym->type.ref->f.func_type == FUNC_ELLIPSIS;
+ func_naked = sym->type.ref->f.func_naked;
/* put debug symbol */
tcc_debug_funcstart(tcc_state, sym);
/* push a dummy symbol to enable local sym storage */
sym_push2(&local_stack, SYM_FIELD, 0, 0);
local_scope = 1; /* for function parameters */
- gfunc_prolog(sym);
+ if (func_naked != 1)
+ gfunc_prolog(sym);
local_scope = 0;
rsym = 0;
clear_temp_local_var_list();
@@ -8617,7 +8625,8 @@ static void gen_function(Sym *sym)
nocode_wanted = 0;
/* reset local stack */
pop_local_syms(NULL, 0);
- gfunc_epilog();
+ if (func_naked != 1)
+ gfunc_epilog();
cur_text_section->data_offset = ind;
local_scope = 0;
label_pop(&global_label_stack, NULL, 0);
diff --git a/tcctok.h b/tcctok.h
index d4c1ef5..7eff548 100644
--- a/tcctok.h
+++ b/tcctok.h
@@ -140,6 +140,7 @@
DEF(TOK_DESTRUCTOR2, "__destructor__")
DEF(TOK_ALWAYS_INLINE1, "always_inline")
DEF(TOK_ALWAYS_INLINE2, "__always_inline__")
+ DEF(TOK_NAKED, "naked")
DEF(TOK_MODE, "__mode__")
DEF(TOK_MODE_QI, "__QI__")
--
2.17.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment