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

Reply via email to