A more simple testcase : #include <stdio.h>
struct string { char *str; int len; }; void dummy(struct string fpath, int dump_arg) { } int main() { int a = 1; struct string x; x.str = "gg.v"; x.len = 4; dummy(x, a == 0); printf("done\n"); return 0; } run this will cause invalid memory also: bug_tcc.c:16: at main: RUNTIME ERROR: invalid memory access kbkp...@sina.com From: kbkp...@sina.com Date: 2024-12-20 10:45 To: tinycc-devel Subject: Re: [Tinycc-devel] [tcc-win32] compiler generate wrong instruction sequence By a quick search the commits, I found this bug was introduced by commit 8227db3a23fd3cf11840eaa25eab5f3f5f813ac7: commit 8227db3a23fd3cf11840eaa25eab5f3f5f813ac7 Author: grischka <grischka> Date: Sat Jun 22 11:45:35 2019 +0200 jump optimizations This unifies VT_CMP with VT_JMP(i) by using mostly VT_CMP with both a positive and a negative jump target list. Such we can delay putting the non-inverted or inverted jump until we can see which one is nore suitable (in most cases). example: if (a && b || c && d) e = 0; before this patch: a: 8b 45 fc mov 0xfffffffc(%ebp),%eax d: 83 f8 00 cmp $0x0,%eax 10: 0f 84 11 00 00 00 je 27 <main+0x27> 16: 8b 45 f8 mov 0xfffffff8(%ebp),%eax 19: 83 f8 00 cmp $0x0,%eax 1c: 0f 84 05 00 00 00 je 27 <main+0x27> 22: e9 22 00 00 00 jmp 49 <main+0x49> 27: 8b 45 f4 mov 0xfffffff4(%ebp),%eax 2a: 83 f8 00 cmp $0x0,%eax 2d: 0f 84 11 00 00 00 je 44 <main+0x44> 33: 8b 45 f0 mov 0xfffffff0(%ebp),%eax 36: 83 f8 00 cmp $0x0,%eax 39: 0f 84 05 00 00 00 je 44 <main+0x44> 3f: e9 05 00 00 00 jmp 49 <main+0x49> 44: e9 08 00 00 00 jmp 51 <main+0x51> 49: b8 00 00 00 00 mov $0x0,%eax 4e: 89 45 ec mov %eax,0xffffffec(%ebp) 51: ... with this patch: a: 8b 45 fc mov 0xfffffffc(%ebp),%eax d: 83 f8 00 cmp $0x0,%eax 10: 0f 84 0c 00 00 00 je 22 <main+0x22> 16: 8b 45 f8 mov 0xfffffff8(%ebp),%eax 19: 83 f8 00 cmp $0x0,%eax 1c: 0f 85 18 00 00 00 jne 3a <main+0x3a> 22: 8b 45 f4 mov 0xfffffff4(%ebp),%eax 25: 83 f8 00 cmp $0x0,%eax 28: 0f 84 14 00 00 00 je 42 <main+0x42> 2e: 8b 45 f0 mov 0xfffffff0(%ebp),%eax 31: 83 f8 00 cmp $0x0,%eax 34: 0f 84 08 00 00 00 je 42 <main+0x42> 3a: b8 00 00 00 00 mov $0x0,%eax 3f: 89 45 ec mov %eax,0xffffffec(%ebp) 42: ... kbkp...@sina.com From: kbkp...@sina.com Date: 2024-12-20 10:15 To: tinycc-devel Subject: [Tinycc-devel] [tcc-win32] compiler generate wrong instruction sequence It was only detected under Windows. bug_tcc.c: typedef unsigned char* byteptr; typedef unsigned char u8; struct string { u8* str; int len; }; typedef struct string string; #define _SLIT(s) ((string){ \ .str=(byteptr)("" s), \ .len=(sizeof(s)-1)}) int _v_dump_expr_int(string fpath, int dump_arg) { return 0; } void main() { int a = 1; _v_dump_expr_int(_SLIT("gg.v"), (a==0 ? (0) : (1))); } compile it with following command: tcc.exe -bt bug_tcc.c run it, will cause an Error: bug_tcc.c:19: at main: RUNTIME ERROR: invalid memory access By disassemble the bug_tcc.exe file, it is shown that the compiler generate a wrong instruction sequence: .text:0000000000401024 var_30 = byte ptr -30h .text:0000000000401024 var_18 = qword ptr -18h .text:0000000000401024 var_10 = dword ptr -10h .text:0000000000401024 var_4 = dword ptr -4 .text:0000000000401024 .text:0000000000401024 push rbp .text:0000000000401025 mov rbp, rsp .text:0000000000401028 sub rsp, 50h .text:000000000040102F mov eax, 1 .text:0000000000401034 mov [rbp+var_4], eax .text:0000000000401037 mov eax, 10h .text:000000000040103C mov r8, rax ; Size .text:000000000040103F mov eax, 0 .text:0000000000401044 mov r11, rax .text:0000000000401047 lea rax, [rbp+var_18] .text:000000000040104B mov r10, rax .text:000000000040104E mov rcx, r10 ; void * .text:0000000000401051 mov rdx, r11 ; Val .text:0000000000401054 call memset .text:0000000000401059 lea rax, aGgV ; "gg.v" .text:0000000000401060 mov [rbp+var_18], rax .text:0000000000401064 mov eax, 4 .text:0000000000401069 mov [rbp+var_10], eax .text:000000000040106C mov eax, [rbp+var_4] .text:000000000040106F cmp eax, 0 .text:0000000000401072 jnz loc_40107D .text:0000000000401078 jmp loc_401082 .text:000000000040107D ; --------------------------------------------------------------------------- .text:000000000040107D .text:000000000040107D loc_40107D: ; CODE XREF: sub_401024+4E↑j .text:000000000040107D jmp loc_40108E .text:0000000000401082 ; --------------------------------------------------------------------------- .text:0000000000401082 .text:0000000000401082 loc_401082: ; CODE XREF: sub_401024+54↑j .text:0000000000401082 lea rax, [rsp+50h+var_30] // this instruction should move outside... .text:0000000000401087 mov eax, 0 // BUG!!! overwrite the rax/eax, this will cause invalid memory access .text:000000000040108C jmp short loc_401093 .text:000000000040108E ; --------------------------------------------------------------------------- .text:000000000040108E .text:000000000040108E loc_40108E: ; CODE XREF: sub_401024:loc_40107D↑j .text:000000000040108E mov eax, 1 .text:0000000000401093 .text:0000000000401093 loc_401093: ; CODE XREF: sub_401024+68↑j .text:0000000000401093 push rsi .text:0000000000401094 push rdi .text:0000000000401095 lea rsi, [rbp+var_18] .text:0000000000401099 mov rdi, rax // Because rax was overwrite to zero, it will fail at movsq .text:000000000040109C movsq .text:000000000040109E movsq .text:00000000004010A0 pop rdi .text:00000000004010A1 pop rsi .text:00000000004010A2 mov r11, rax .text:00000000004010A5 lea r10, [rsp+50h+var_30] .text:00000000004010AA mov rcx, r10 .text:00000000004010AD mov rdx, r11 .text:00000000004010B0 call sub_401000 .text:00000000004010B5 leave .text:00000000004010B6 retn .text:00000000004010B6 sub_401024 endp Hope someone can fix it.
_______________________________________________ Tinycc-devel mailing list Tinycc-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/tinycc-devel