Re: [Tinycc-devel] Incorrect function call code on ARMv6

2016-08-10 Thread Daniel Glöckner
On Wed, Aug 10, 2016 at 06:59:46AM +0100, Balazs Kezes wrote:
>   90:   e5912000ldr r2, [r1]  ; <-- This is the y argument.
>   94:   e50b2018str r2, [fp, #-24]
>   98:   e5901000ldr r1, [r0]
>   9c:   e284add r0, r0, #4
>   a0:   e5902000ldr r2, [r0]  ; <-- The clobbering happens here.
>   a4:   e50b101cstr r1, [fp, #-28]
>   a8:   e1a01002mov r1, r2
>   ac:   e51b001cldr r0, [fp, #-28]
>   b0:   ebfebl  0 

I think the error is caused by the "vtop--;" lines in copy_params().
The former gfunc_call() implementation for ARM rotated the elements
on the parameter stack to let get_reg() know that the registers are
still in use. The current implementation drops each element directly
after it has been moved to the final register.

Best regards,

  Daniel

___
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel


[Tinycc-devel] Incorrect function call code on ARMv6

2016-08-10 Thread Balazs Kezes
Hi all!

I'm trying to use TCC on a raspberry pi but I'm running into issues:

$ cat callbug.c
#include 

void foo(long long x, int y) {
  printf("x = %llx, y = %x\n", x, y);
}

int main(void) {
  long long a1 = 0xdeadbeefcafebabeLL;
  int a2 = 1;
  long long *xx[] = {  };
  int *yy[] = {  };
  foo(**xx, **yy);
  return 0;
}
$ tcc -c callbug.c && gcc callbug.o && ./a.out
x = deadbeefcafebabe, y = deadbeef

I'd expect it to print:
x = deadbeefcafebabe, y = 1

The problem is that TCC on the 32 bit ARM platform clobbers one of the
registers when setting up the registers for the function call. Here's
the disassembly of the above code:

$ objdump -d callbug.o
callbug.o: file format elf32-littlearm


Disassembly of section .text:

 :
   0:   e1a0c00dmov ip, sp
   4:   e92d000fpush{r0, r1, r2, r3}
   8:   e92d5800push{fp, ip, lr}
   c:   e1a0b00dmov fp, sp
  10:   e24bd004sub sp, fp, #4
  14:   e24dd004sub sp, sp, #4
  18:   e59b0014ldr r0, [fp, #20]
  1c:   e52d0004push{r0}; (str r0, [sp, #-4]!)
  20:   e59b3010ldr r3, [fp, #16]
  24:   e59b200cldr r2, [fp, #12]
  28:   e59fldr r0, [pc]; 30 
  2c:   ea00b   34 
  30:   andeq   r0, r0, r0
  34:   ebfebl  0 
  38:   e28dd008add sp, sp, #8
  3c:   e89ba800ldm fp, {fp, sp, pc}

0040 :
  40:   e1a0c00dmov ip, sp
  44:   e92d5800push{fp, ip, lr}
  48:   e1a0b00dmov fp, sp
  4c:   e24bd01csub sp, fp, #28
  50:   e59fldr r0, [pc]; 58 
  54:   ea00b   5c 
  58:   cafebabebgt fffaeb58 
  5c:   e59f1000ldr r1, [pc]; 64 
  60:   ea00b   68 
  64:   deadbeefcdple   14, 10, cr11, cr13, cr15, {7}
  68:   e50b0008str r0, [fp, #-8]
  6c:   e50b1004str r1, [fp, #-4]
  70:   e3a1mov r0, #1
  74:   e50b000cstr r0, [fp, #-12]
  78:   e24b0008sub r0, fp, #8
  7c:   e50b0010str r0, [fp, #-16]
  80:   e24b000csub r0, fp, #12
  84:   e50b0014str r0, [fp, #-20]
  88:   e51b0010ldr r0, [fp, #-16]
  8c:   e51b1014ldr r1, [fp, #-20]
  90:   e5912000ldr r2, [r1]  ; <-- This is the y argument.
  94:   e50b2018str r2, [fp, #-24]
  98:   e5901000ldr r1, [r0]
  9c:   e284add r0, r0, #4
  a0:   e5902000ldr r2, [r0]  ; <-- The clobbering happens here.
  a4:   e50b101cstr r1, [fp, #-28]
  a8:   e1a01002mov r1, r2
  ac:   e51b001cldr r0, [fp, #-28]
  b0:   ebfebl  0 
  b4:   e3a0mov r0, #0
  b8:   e1a0nop ; (mov r0, r0)
  bc:   e89ba800ldm fp, {fp, sp, pc}


See my comments at 0x94 and 0xa0. That's where the problem happens. It
clobbers r2 because it uses r2 to dereference the long long pointer. I
don't think this bug affects other platforms: x86_64 already uses 64 bit
registers and i386 afaik uses stack to pass arguments so this cannot
happen.

I'm using the latest TCC:

$ git log -n 1 | cat
commit 0a402f6e91c284dd37cb61e726cc95de20fe895e
Author: David Mertens 
Date:   Thu Aug 4 13:14:52 2016 -0400

Avoid conflicting definition for va_list on 64-bit Macs
$ uname -a
Linux eper 4.4.11-3-ARCH #1 Wed May 25 18:49:58 MDT 2016 armv6l GNU/Linux
$ ./configure --prefix=/usr
Binary  directory   /usr/bin
TinyCC directory/usr/lib/tcc
Library directory   /usr/lib
Include directory   /usr/include
Manual directory/usr/share/man
Info directory  /usr/share/info
Doc directory   /usr/share/doc
Target root prefix
Source path  /home/rlblaster/proj/tcc/tinycc
C compiler   gcc
ar   ar
cross compilers  no
Target CPU   armv4l
Host OS  Linux
Target OSLinux
Big Endian   no
gprof enabledno
use libgcc   no
Creating config.mak and config.h
config.h is unchanged


Can this be fixed? Thank you!

-- 
Balazs

___
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel