Hello, I found simple loops(for, while, do-while) asm code generated from
cproc/qbe got issue, there's segmentation fault
I just get started with tinycc source code, and I want to push a fix to this
part, can you please give me some pointers? thanks!
example:
`for-loop-test.c`
```sh
$ cat for-loop-test.c
#include<tcclib.h>
int main(){
for(int i = 0; i < 5; i++)
printf("i = %d\n", i);
return 0;
}
```
```sh
$ ~/tinycc/tcc -run for-loop-test.c
i = 0
i = 1
i = 2
i = 3
i = 4
```
generate `for-loop-test.i` for `cproc`
```sh
$ ~/tinycc/tcc -Btinycc -Itinycc -E for-loop-test.c -o for-loop-test.i
$ cat for-loop-test.i
# 1 "for-loop-test.c"
# 1 "<command line>" 1
# 1 "for-loop-test.c" 2
# 1 "tinycc/tcclib.h" 1
# 11 "tinycc/tcclib.h"
# 1 "tinycc/include/stddef.h" 1
typedef unsigned long size_t;
typedef long ssize_t;
typedef int wchar_t;
typedef long ptrdiff_t;
typedef long intptr_t;
typedef unsigned long uintptr_t;
# 22 "tinycc/include/stddef.h"
void *alloca(size_t size);
# 11 "tinycc/tcclib.h" 2
# 1 "tinycc/include/stdarg.h" 1
typedef __builtin_va_list va_list;
typedef va_list __gnuc_va_list;
# 12 "tinycc/tcclib.h" 2
void *calloc(size_t nmemb, size_t size);
void *malloc(size_t size);
void free(void *ptr);
void *realloc(void *ptr, size_t size);
int atoi(const char *nptr);
long int strtol(const char *nptr, char **endptr, int base);
unsigned long int strtoul(const char *nptr, char **endptr, int base);
void exit(int);
typedef struct __FILE FILE;
extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;
FILE *fopen(const char *path, const char *mode);
FILE *fdopen(int fildes, const char *mode);
FILE *freopen(const char *path, const char *mode, FILE *stream);
int fclose(FILE *stream);
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(void *ptr, size_t size, size_t nmemb, FILE *stream);
int fgetc(FILE *stream);
char *fgets(char *s, int size, FILE *stream);
int getc(FILE *stream);
int getchar(void);
char *gets(char *s);
int ungetc(int c, FILE *stream);
int fflush(FILE *stream);
int putchar (int c);
int printf(const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
int sprintf(char *str, const char *format, ...);
int snprintf(char *str, size_t size, const char *format, ...);
int asprintf(char **strp, const char *format, ...);
int dprintf(int fd, const char *format, ...);
int vprintf(const char *format, va_list ap);
int vfprintf(FILE *stream, const char *format, va_list ap);
int vsprintf(char *str, const char *format, va_list ap);
int vsnprintf(char *str, size_t size, const char *format, va_list ap);
int vasprintf(char **strp, const char *format, va_list ap);
int vdprintf(int fd, const char *format, va_list ap);
void perror(const char *s);
char *strcat(char *dest, const char *src);
char *strchr(const char *s, int c);
char *strrchr(const char *s, int c);
char *strcpy(char *dest, const char *src);
void *memcpy(void *dest, const void *src, size_t n);
void *memmove(void *dest, const void *src, size_t n);
void *memset(void *s, int c, size_t n);
char *strdup(const char *s);
size_t strlen(const char *s);
void *dlopen(const char *filename, int flag);
const char *dlerror(void);
void *dlsym(void *handle, char *symbol);
int dlclose(void *handle);
# 2 "for-loop-test.c" 2
int main(){
for(int i = 0; i < 5; i++)
printf("i = %d\n", i);
return 0;
}
```
generate `qbe` IR code `for-loop-test.qbe`
```sh
$ ~/cproc/cproc-qbe for-loop-test.i > for-loop-test.qbe
$ cat for-loop-test.qbe
data $.Lstring.2 = align 1 { b "i = %d\012\000", }
export
function w $main() {
@start.1
%.1 =l alloc4 4
@body.2
storew 0, %.1
@for_cond.3
%.2 =w loadw %.1
%.3 =w csltw %.2, 5
jnz %.3, @for_body.4, @for_join.6
@for_body.4
%.4 =w loadw %.1
%.5 =w call $printf(l $.Lstring.2, ..., w %.4)
@for_cont.5
%.6 =w loadw %.1
%.7 =w add %.6, 1
storew %.7, %.1
jmp @for_cond.3
@for_join.6
ret 0
}
```
generate x86_64 assembly `for-loop-test.s`
```sh
$ ~/qbe/qbe for-loop-test.qbe > for-loop-test.s
$ cat for-loop-test.s
.data
.balign 1
.Lstring.2:
.ascii "i = %d\012\000"
/* end data */
.text
.balign 16
.globl main
main:
endbr64
pushq %rbp
movq %rsp, %rbp
subq $8, %rsp
pushq %rbx
movl $0, %ebx
.p2align 4
.Lbb2:
cmpl $5, %ebx
jge .Lbb4
movl %ebx, %esi
leaq .Lstring.2(%rip), %rdi
movl $0, %eax
callq printf
addl $1, %ebx
jmp .Lbb2
.Lbb4:
movl $0, %eax
popq %rbx
leave
ret
.type main, @function
.size main, .-main
/* end function main */
.section .note.GNU-stack,"",@progbits
```
now compile and run `for-loop-test`
```sh
$ ~/tinycc/tcc for-loop-test.s -o for-loop-test
$ ./for-loop-test
Segmentation fault (core dumped)
```
objdump
```sh
$ objdump -d for-loop-test
for-loop-test: file format elf64-x86-64
Disassembly of section .text:
0000000000600aa0 <main@@Base-0x40>:
600aa0: f3 0f 1e fa endbr64
600aa4: 31 ed xor %ebp,%ebp
600aa6: 49 89 d1 mov %rdx,%r9
600aa9: 5e pop %rsi
600aaa: 48 89 e2 mov %rsp,%rdx
600aad: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
600ab1: 50 push %rax
600ab2: 54 push %rsp
600ab3: 45 31 c0 xor %r8d,%r8d
600ab6: 31 c9 xor %ecx,%ecx
600ab8: 48 8b 3d 81 03 40 00 mov 0x400381(%rip),%rdi #
a00e40 <printf@plt+0x4002d8>
600abf: ff 15 83 03 40 00 call *0x400383(%rip) # a00e48
<printf@plt+0x4002e0>
600ac5: f4 hlt
600ac6: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1)
600acd: 00 00 00
600ad0: f3 0f 1e fa endbr64
600ad4: c3 ret
...
0000000000600ae0 <main@@Base>:
600ae0: f3 0f 1e fa endbr64
600ae4: 55 push %rbp
600ae5: 48 89 e5 mov %rsp,%rbp
600ae8: 48 83 ec 08 sub $0x8,%rsp
600aec: 53 push %rbx
600aed: bb 00 00 00 00 mov $0x0,%ebx
...
600afe: 00 00 add %al,(%rax)
600b00: 83 fb 05 cmp $0x5,%ebx
600b03: 0f 8d 18 00 00 00 jge 600b21 <main@@Base+0x41>
600b09: 89 de mov %ebx,%esi
600b0b: 48 8d 3d 4a 03 60 00 lea 0x60034a(%rip),%rdi #
c00e5c <printf@plt+0x6002f4>
600b12: b8 00 00 00 00 mov $0x0,%eax
600b17: e8 4c 00 00 00 call 600b68 <printf@plt>
600b1c: 83 c3 01 add $0x1,%ebx
600b1f: eb df jmp 600b00 <main@@Base+0x20>
600b21: b8 00 00 00 00 mov $0x0,%eax
600b26: 5b pop %rbx
600b27: c9 leave
600b28: c3 ret
Disassembly of section .init:
0000000000600b2c <.init>:
600b2c: f3 0f 1e fa endbr64
600b30: 48 83 ec 08 sub $0x8,%rsp
600b34: 48 8b 05 15 03 40 00 mov 0x400315(%rip),%rax #
a00e50 <printf@plt+0x4002e8>
600b3b: 48 85 c0 test %rax,%rax
600b3e: 74 02 je 600b42 <main@@Base+0x62>
600b40: ff d0 call *%rax
600b42: 48 83 c4 08 add $0x8,%rsp
600b46: c3 ret
Disassembly of section .fini:
0000000000600b48 <.fini>:
600b48: f3 0f 1e fa endbr64
600b4c: 48 83 ec 08 sub $0x8,%rsp
600b50: 48 83 c4 08 add $0x8,%rsp
600b54: c3 ret
Disassembly of section .plt:
0000000000600b58 <printf@plt-0x10>:
600b58: ff 35 ca 02 40 00 push 0x4002ca(%rip) # a00e28
<printf@plt+0x4002c0>
600b5e: ff 25 cc 02 40 00 jmp *0x4002cc(%rip) # a00e30
<printf@plt+0x4002c8>
600b64: 00 00 add %al,(%rax)
...
0000000000600b68 <printf@plt>:
600b68: ff 25 ca 02 40 00 jmp *0x4002ca(%rip) # a00e38
<printf@plt+0x4002d0>
600b6e: 68 00 00 00 00 push $0x0
600b73: e9 e0 ff ff ff jmp 600b58 <main@@Base+0x78>
```
Regards
Jerry
_______________________________________________
Tinycc-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/tinycc-devel