I try to compile code like below with tcc: void zfunc() { ((void (*)(void))0) (); } and tcc broken with SegmengFault.
tcc was buit to target armv7l and run on Windows host. I found that the implemention of gcall_or_jmp in arm_gen.c caused that. I try to fix this problem. It seem worked. Though I only tested on Windows and checked the generated file with arm-objdump. $ git diff arm-gen.c diff --git a/arm-gen.c b/arm-gen.c index 634cffb..c5de065 100644 --- a/arm-gen.c +++ b/arm-gen.c @@ -739,25 +739,28 @@ static void gadd_sp(int val) static void gcall_or_jmp(int is_jmp) { int r; + uint32_t x; if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { - uint32_t x; /* constant case */ - x=encbranch(ind,ind+vtop->c.i,0); - if(x) { - if (vtop->r & VT_SYM) { - /* relocation case */ - greloc(cur_text_section, vtop->sym, ind, R_ARM_PC24); - } else - put_elf_reloc(symtab_section, cur_text_section, ind, R_ARM_PC24, 0); - o(x|(is_jmp?0xE0000000:0xE1000000)); - } else { - if(!is_jmp) - o(0xE28FE004); // add lr,pc,#4 - o(0xE51FF004); // ldr pc,[pc,#-4] - if (vtop->r & VT_SYM) - greloc(cur_text_section, vtop->sym, ind, R_ARM_ABS32); - o(vtop->c.i); - } + if(vtop->r & VT_SYM){ + x=encbranch(ind,ind+vtop->c.i,0); + if(x) { + /* relocation case */ + greloc(cur_text_section, vtop->sym, ind, R_ARM_PC24); + o(x|(is_jmp?0xE0000000:0xE1000000)); + } else { + if(!is_jmp) + o(0xE28FE004); // add lr,pc,#4 + o(0xE51FF004); // ldr pc,[pc,#-4] + greloc(cur_text_section, vtop->sym, ind, R_ARM_ABS32); + o(vtop->c.i); + } + }else{ + if(!is_jmp) + o(0xE28FE004); // add lr,pc,#4 + o(0xE51FF004); // ldr pc,[pc,#-4] + o(vtop->c.i); + } } else { /* otherwise, indirect call */ r = gv(RC_INT); _______________________________________________ Tinycc-devel mailing list Tinycc-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/tinycc-devel