From 9d75f14107766f954fd56702ee1a66922b6d59f2 Mon Sep 17 00:00:00 2001 From: herman ten brugge Date: Wed, 8 Jul 2020 15:48:15 +0200 Subject: [PATCH] Fix structure passing i386 PE The orignal code does: push eax/edx/size call alloca pop eax/edx/size The pop does not work because the stack pointer has changed. To make this also work with bound checking the code is now using the stack probing from alloca. --- i386-gen.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/i386-gen.c b/i386-gen.c index cbdf757c..dbf0fda2 100644 --- a/i386-gen.c +++ b/i386-gen.c @@ -419,14 +419,19 @@ ST_FUNC void gfunc_call(int nb_args) /* allocate the necessary size on stack */ #ifdef TCC_TARGET_PE if (size >= 0x4096) { - o(0x5250); - oad(0x68, size); - vpush_global_sym(&func_old_type, TOK_alloca); - gcall_or_jmp(0); - vtop--; - o(0x585a58); - oad(0xec81, 8); /* sub $8, %esp */ - } else + /* cannot call alloca with bound checking. Do stack probing. */ + o(0x50); // push %eax + oad(0xb8, size - 4); // mov size-4,%eax + oad(0x3d, 4096); // p1: cmp $4096,%eax + o(0x1476); // jbe + oad(0x248485,-4096); // test %eax,-4096(%esp) + oad(0xec81, 4096); // sub $4096,%esp + oad(0x2d, 4096); // sub $4096,%eax + o(0xe5eb); // jmp + o(0xc429); // p2: sub %eax,%esp + oad(0xc481, size - 4); // add size-4,%esp + o(0x58); // pop %eax + } #endif oad(0xec81, size); /* sub $xxx, %esp */ /* generate structure store */