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