From 3ebc2e9bd947aa213f2bc5eaf19fe9ffc8f9b5ca Mon Sep 17 00:00:00 2001 From: Michael Schmidt Date: Mon, 16 Jan 2023 15:35:11 +0100 Subject: Disable tail calls in variadic functions Variadic functions can use the stack frame to store values of registers. Hence, a pointer within the stack frame can be put in a va_list, and the stack frame should not be deallocated before a function call that may use this va_list. Fixes: #473 --- backend/Tailcall.v | 1 + backend/Tailcallproof.v | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/backend/Tailcall.v b/backend/Tailcall.v index b7a62d74..2da07ee8 100644 --- a/backend/Tailcall.v +++ b/backend/Tailcall.v @@ -93,6 +93,7 @@ Definition transf_instr (f: function) (pc: node) (instr: instruction) := Definition transf_function (f: function) : function := if zeq f.(fn_stacksize) 0 + && option_eq zeq f.(fn_sig).(sig_cc).(cc_vararg) None then RTL.transf_function (transf_instr f) f else f. diff --git a/backend/Tailcallproof.v b/backend/Tailcallproof.v index 7a5be5ed..c109e1b6 100644 --- a/backend/Tailcallproof.v +++ b/backend/Tailcallproof.v @@ -169,7 +169,8 @@ Lemma transf_instr_lookup: exists i', (transf_function f).(fn_code)!pc = Some i' /\ transf_instr_spec f i i'. Proof. intros. unfold transf_function. - destruct (zeq (fn_stacksize f) 0). + destruct (zeq (fn_stacksize f) 0 && option_eq zeq (cc_vararg (sig_cc (fn_sig f))) None) eqn:B. + InvBooleans. simpl. rewrite PTree.gmap. rewrite H. simpl. exists (transf_instr f pc i); split. auto. apply transf_instr_charact; auto. exists i; split. auto. constructor. @@ -240,14 +241,14 @@ Lemma sig_preserved: forall f, funsig (transf_fundef f) = funsig f. Proof. destruct f; auto. simpl. unfold transf_function. - destruct (zeq (fn_stacksize f) 0); auto. + destruct (zeq (fn_stacksize f) 0 && option_eq zeq (cc_vararg (sig_cc (fn_sig f))) None); auto. Qed. Lemma stacksize_preserved: forall f, fn_stacksize (transf_function f) = fn_stacksize f. Proof. unfold transf_function. intros. - destruct (zeq (fn_stacksize f) 0); auto. + destruct (zeq (fn_stacksize f) 0 && option_eq zeq (cc_vararg (sig_cc (fn_sig f))) None); auto. Qed. Lemma find_function_translated: @@ -534,7 +535,7 @@ Proof. assert (fn_stacksize (transf_function f) = fn_stacksize f /\ fn_entrypoint (transf_function f) = fn_entrypoint f /\ fn_params (transf_function f) = fn_params f). - unfold transf_function. destruct (zeq (fn_stacksize f) 0); auto. + unfold transf_function. destruct (zeq (fn_stacksize f) 0 && option_eq zeq (cc_vararg (sig_cc (fn_sig f))) None); auto. destruct H0 as [EQ1 [EQ2 EQ3]]. left. econstructor; split. simpl. eapply exec_function_internal; eauto. rewrite EQ1; eauto. @@ -602,4 +603,3 @@ Proof. Qed. End PRESERVATION. - -- cgit