The attached patch fixes the problem on arm64/riscv64 for me.

This this look OK.

    Herman


On 6/21/21 7:35 PM, Christian Jullien wrote:

Your second patch does not solve the issue on Risc-V. I continue to get coredump

C.

*From:*Tinycc-devel [mailto:[email protected]] *On Behalf Of *Pursuer via Tinycc-devel
*Sent:* Saturday, June 19, 2021 18:20
*To:* jullien; tinycc-devel
*Cc:* Pursuer
*Subject:* Re: [Tinycc-devel] Segfault on arm64 when making a function call with many arguments

Thank you. (I just used another email account and forgot to add nickname in previous email.)

After inspecting the code more deeply, I found another way to fix this bug.

Most functions in tccgen.c ,which modify the vstack , call vcheck_cmp() at the beginning (like "vsetc" ,"vswap", "vrotb" etc.). but "vpushv" seem to omit it. So the below patch should also work.

diff --git a/tccgen.c b/tccgen.c

index c36032a..dc6dd9d 100644

--- a/tccgen.c

+++ b/tccgen.c

@@ -1473,6 +1473,7 @@ ST_FUNC void vpushv(SValue *v)

 {

     if (vtop >= vstack + (VSTACK_SIZE - 1))

         tcc_error("memory full (vstack)");

+   vcheck_cmp();

     vtop++;

     *vtop = *v;

 }

I prefer latter patch, add vcheck_cmp() just like other vstack-related functions did.

------------------ Original ------------------

*From:*"jullien" <[email protected]>;

*Date:* Sat, Jun 19, 2021 10:56 PM

*To:* "jullien"<[email protected]>;"tinycc-devel"<[email protected]>;

*Subject:* Re: [Tinycc-devel] Segfault on arm64 when making a function call with many arguments

All parameters go to the right arguments. So patch looks good

#include <stdio.h>

void map_add(int x0, int x1, int x2, int x3, int x4, int x5, int x6, int x7, in\

t x8) {

        printf("%d ", x0);

        printf("%d ", x1);

        printf("%d ", x2);

        printf("%d ", x3);

        printf("%d ", x4);

        printf("%d ", x5);

        printf("%d ", x6);

        printf("%d ", x7);

printf("%d ", x8);

}

void main() {

  int A = 1;

  int B = 2;

  map_add(10, 20, 30, 40, 50, 60, 70, 80, A && B);

}

$  tcc foo.c -o foo && ./foo;echo

10 20 30 40 50 60 70 80 1

*From:*Tinycc-devel [mailto:[email protected]] *On Behalf Of *Christian Jullien
*Sent:* Saturday, June 19, 2021 08:57
*To:* [email protected]
*Subject:* Re: [Tinycc-devel] Segfault on arm64 when making a function call with many arguments

Hi just quickly tested on my RPi arm64.

I don’t know if it works, i.e. all arguments go to the right parameter with the right value but, at least it no longer segfault.

I’ll make more tests today.

C.

*From:*Tinycc-devel [mailto:[email protected]] *On Behalf Of *pursuer2 via Tinycc-devel
*Sent:* Saturday, June 19, 2021 08:28
*To:* jullien; tinycc-devel
*Cc:* pursuer2
*Subject:* Re: [Tinycc-devel] Segfault on arm64 when making a function call with many arguments

This bug may caused by "vpushv" SValue with VT_CMP flag. There should be only one VT_CMP SValue on vstack.

I make below patch to fix it, then the compilation exit normally. But I have no arm64 device with GNU/Linux to verify the test.

diff --git a/arm64-gen.c b/arm64-gen.c

index 6389409..a9cbfa2 100644

--- a/arm64-gen.c

+++ b/arm64-gen.c

@@ -1017,6 +1017,9 @@ ST_FUNC void gfunc_call(int nb_args)

   if (stack >> 12)

           o(0xd14003ff | (stack >> 12) << 10);

+   if((vtop->r&VT_VALMASK)==VT_CMP){

+       gv(RC_INT);

+   }

   // First pass: set all values on stack

   for (i = nb_args; i; i--) {

       vpushv(vtop - nb_args + i);

------------------ Original ------------------

*From:*"jullien" <[email protected]>;

*Date:* Fri, Jun 18, 2021 04:04 PM

*To:* "tinycc-devel"<[email protected]>;

*Subject:* Re: [Tinycc-devel] Segfault on arm64 when making a function call with many arguments

I confirm it fails on arm64 (but works on arm 32bits).

It also fails with complete prototype:

void map_add(int a, int b, int c, int d, int e, int f, int g, int h, int i)

{}

C.

*From:*Tinycc-devel [mailto:[email protected]] *On Behalf Of *Arthur Williams
*Sent:* Wednesday, June 16, 2021 20:18
*To:* [email protected]
*Subject:* [Tinycc-devel] Segfault on arm64 when making a function call with many arguments

Was trying to compile vim with tcc on arm64 but got a segfault. I can simplify it to the following case:

  void map_add(){}
  void main() {
    int A;
    int B;
    map_add(0, 0, 0, 0, 0, 0, 0, 0, A && B); // segfaults when compiling

}

The bad pointer was generated in arm64-gen.c::gsym_addr and the actual segfault occurred in tcc.h::read16le.

Removing one of the 0s or removing A/B or replacing A && B with a constant avoids the problem. Cannot repro on x86. I'm running musl on Linux and using the latest tcc from mob.


diff --git a/arm64-gen.c b/arm64-gen.c
index 6389409..83193f6 100644
--- a/arm64-gen.c
+++ b/arm64-gen.c
@@ -1010,6 +1010,10 @@ ST_FUNC void gfunc_call(int nb_args)
 
     stack = (stack + 15) >> 4 << 4;
 
+    /* fetch cpu flag before generating any code */
+    if ((vtop->r & VT_VALMASK) == VT_CMP)
+      gv(RC_INT);
+
     if (stack >= 0x1000000) // 16Mb
         tcc_error("stack size too big %lu", stack);
     if (stack & 0xfff)
diff --git a/riscv64-gen.c b/riscv64-gen.c
index 54e52bf..04b591f 100644
--- a/riscv64-gen.c
+++ b/riscv64-gen.c
@@ -621,6 +621,11 @@ ST_FUNC void gfunc_call(int nb_args)
     stack_adj = (stack_adj + 15) & -16;
     tempspace = (tempspace + 15) & -16;
     stack_add = stack_adj + tempspace;
+
+    /* fetch cpu flag before generating any code */
+    if ((vtop->r & VT_VALMASK) == VT_CMP)
+      gv(RC_INT);
+
     if (stack_add) {
         if (stack_add >= 0x1000) {
             o(0x37 | (5 << 7) | (-stack_add & 0xfffff000)); //lui t0, upper(v)
diff --git a/tests/tcctest.c b/tests/tcctest.c
index e58a97f..16fa83e 100644
--- a/tests/tcctest.c
+++ b/tests/tcctest.c
@@ -4161,6 +4161,19 @@ void bounds_check1_test (void)
     pv(y);
 }
 
+/* This failed on arm64/riscv64 */
+void map_add(int a, int b, int c, int d, int e, int f, int g, int h, int i)
+{
+  printf ("%d %d %d %d %d %d %d %d %d\n", a, b, c, d, e, f, g, h, i);
+}
+
+void func_arg_test(void)
+{
+    int a = 0;
+    int b = 1;
+    map_add(0, 1, 2, 3, 4, 5, 6, 7, a && b);
+}
+
 /* gcc 2.95.3 does not handle correctly CR in strings or after strays */
 #define CORRECT_CR_HANDLING
 
@@ -4276,6 +4289,7 @@ int main(int argc, char **argv)
     RUN(volatile_test);
     RUN(attrib_test);
     RUN(bounds_check1_test);
+    RUN(func_arg_test);
 
     return 0;
 }
_______________________________________________
Tinycc-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

Reply via email to