From 41ce391c86df135609af33658414d4d452c5beb3 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Thu, 21 Nov 2013 21:09:44 +0800 Subject: [PATCH] Fix register corruption at function call on ARM Prior to this commit, params could use some registers that do not appear in the value stack. Therefore when generating function call, one of such register could be reused, leading to wrong parameter content. This happens when a structure is passed via core register, as only the first register would appear in the value stack. --- arm-gen.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/arm-gen.c b/arm-gen.c index ab7b0bea..488de768 100644 --- a/arm-gen.c +++ b/arm-gen.c @@ -979,10 +979,12 @@ static int assign_regs(int nb_args, int variadic, struct plan *plan, int *todo) nb_args: number of parameters the function take plan: the overall assignment plan for parameters - todo: a bitmap indicating what core reg will hold a parameter */ -static void copy_params(int nb_args, struct plan *plan, int todo) + todo: a bitmap indicating what core reg will hold a parameter + + Returns the number of SValue added by this function on the value stack */ +static int copy_params(int nb_args, struct plan *plan, int todo) { - int size, align, r, i; + int size, align, r, i, nb_extra_sval = 0; struct param_plan *pplan; /* Several constraints require parameters to be copied in a specific order: @@ -1111,11 +1113,19 @@ static void copy_params(int nb_args, struct plan *plan, int todo) if(todo) { o(0xE8BD0000|todo); /* pop {todo} */ for(pplan = plan->clsplans[CORE_STRUCT_CLASS]; pplan; pplan = pplan->prev) { + int r; pplan->sval->r = pplan->start; - if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) - pplan->sval->r2 = pplan->end; + /* TODO: why adding fake param */ + for (r = pplan->start + 1; r <= pplan->end; r++) { + if (todo & (1 << r)) { + nb_extra_sval++; + vpushi(0); + vtop->r = r; + } + } } } + return nb_extra_sval; } /* Generate function call. The function address is pushed first, then @@ -1158,7 +1168,7 @@ void gfunc_call(int nb_args) } #endif - copy_params(nb_args, &plan, todo); + nb_args += copy_params(nb_args, &plan, todo); tcc_free(plan.pplans); /* Move fct SValue on top as required by gcall_or_jmp */ -- 2.11.4.GIT