A user encountered this bug trying to build musl libc for i386 using tcc, where an asm source file using pc-relative addressing to load its data was reading from the wrong address. I tracked it down to the offset in the immediate to an add instruction, which I simplified down to the following minimal test case to reproduce the problem:
Simple testcase: .text 1: add $1f-1b,%eax .data 1: .long 0 The relocation emitted is the pc-relative address based on the beginning of the add opcode, but it needs to be based on the beginning of the immediate operand in the add opcode. This is because asm_expr uses the value of ind at the time it is called to offset symbol value in pe->v, but this value of ind points to the beginning of the instruction. Something needs to happen to update it to point to the location where the immediate is actually emitted. Here is a really dumb fix, but I don't know if it breaks other things, and it's likely incomplete: diff --git a/i386-asm.c b/i386-asm.c index e134d804..63cfbf6b 100644 --- a/i386-asm.c +++ b/i386-asm.c @@ -738,6 +738,8 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode) s = 0; /* avoid warning */ + int ind0 = ind; + again: /* optimize matching by using a lookup table (no hashing is needed !) */ @@ -1153,6 +1155,7 @@ again: } else if (pa->op_type[i] == OPT_DISP || pa->op_type[i] == OPT_DISP8) { gen_disp32(&ops[i].e); } else { + if (ops[i].e.pcrel) ops[i].e.v += ind-ind0; gen_expr32(&ops[i].e); } } Please CC me on replies, as I'm not subscribed. Rich _______________________________________________ Tinycc-devel mailing list Tinycc-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/tinycc-devel