mirror of
https://github.com/frida/tinycc
synced 2025-02-26 12:14:04 +03:00
x86-64: fix shared libs
The introduction of read32le everywhere created a subtle issue, going from x = *(int*)p; to x = read32le(p); is not equivalent if x is a larger than 32bit quantity, like an address on x86_64, because read32le returns an unsigned int. The first sign extends, the latter zero extends. This broke shared library creation for gawk. It's enough to amend the case of the above situation, cases like "write32le(p, read32le(p) +- something)" are okay, no extensions happen or matter.
This commit is contained in:
parent
e264243adc
commit
f15c0a9333
6
tccelf.c
6
tccelf.c
@ -898,7 +898,8 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
|
||||
/* XXX: this logic may depend on TCC's codegen
|
||||
now TCC uses R_X86_64_32 even for a 64bit pointer */
|
||||
qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
|
||||
qrel->r_addend = read32le(ptr) + val;
|
||||
/* Use sign extension! */
|
||||
qrel->r_addend = (int)read32le(ptr) + val;
|
||||
qrel++;
|
||||
}
|
||||
write32le(ptr, read32le(ptr) + val);
|
||||
@ -911,7 +912,8 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
|
||||
if (esym_index) {
|
||||
qrel->r_offset = rel->r_offset;
|
||||
qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32);
|
||||
qrel->r_addend = read32le(ptr);
|
||||
/* Use sign extension! */
|
||||
qrel->r_addend = (int)read32le(ptr);
|
||||
qrel++;
|
||||
break;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user