Re: [Tinycc-devel] tcc assembler emits wrong pc-relative symbol difference reloctions in immediates

2024-03-03 Thread grischka via Tinycc-devel

On 01.03.2024 17:32, Rich Felker wrote:

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.


I just moved the addition of (ind + 4)

https://repo.or.cz/tinycc.git/commitdiff/ca061f3a96216f85f6fe72868083208aa0a740b9#patch2
to where the operand is put.

https://repo.or.cz/tinycc.git/commitdiff/ca061f3a96216f85f6fe72868083208aa0a740b9#patch1
thanks, -- gr



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([i].e);
  } else {
+if (ops[i].e.pcrel) ops[i].e.v += ind-ind0;
  gen_expr32([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




___
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel


[Tinycc-devel] tcc assembler emits wrong pc-relative symbol difference reloctions in immediates

2024-03-01 Thread Rich Felker
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([i].e);
 } else {
+if (ops[i].e.pcrel) ops[i].e.v += ind-ind0;
 gen_expr32([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