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

Reply via email to