History

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.

Michael Matz committed 10 years ago

Commit f15c0a91 parent e2642431 file · +4 −2Browse files

Unified · Split

tccelf.c+4−2
@@ -898,7 +898,8 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 897 unmodified lines
898898 /* XXX: this logic may depend on TCC's codegen
899899 now TCC uses R_X86_64_32 even for a 64bit pointer */
900900 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
901− qrel->r_addend = read32le(ptr) + val;
901+ /* Use sign extension! */
902+ qrel->r_addend = (int)read32le(ptr) + val;
902903 qrel++;
903904 }
904905 write32le(ptr, read32le(ptr) + val);
@@ -911,7 +912,8 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 6 unmodified lines
911912 if (esym_index) {
912913 qrel->r_offset = rel->r_offset;
913914 qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32);
914− qrel->r_addend = read32le(ptr);
915+ /* Use sign extension! */
916+ qrel->r_addend = (int)read32le(ptr);
915917 qrel++;
916918 break;
917919 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t