Re: older ld converts push with GOTPCRELX into call - is a local guard ok?
Sam James <[email protected]>
| Newsgroups | gmane.comp.gnu.binutils |
|---|---|
| Organization | Gentoo |
| Message-ID | <[email protected]> |
"Dora, Sunil Kumar via Binutils" <[email protected]> writes: > Hi, > > I was debugging rustc segfaults and traced them to GOTPCRELX handling > in older ld. > > Since commit 11c2852449825 (binutils 2.45), gas emits > R_X86_64_GOTPCRELX for "push foo@GOTPCREL(%rip)". Older ld's > elf_x86_64_convert_load_reloc() only checks modrm 0x25 (jmp) in the > 0xff case and treats everything else as call, so a push (modrm 0x35) > gets silently rewritten to "addr32 call foo". In our case foo is a > read-only LLVM table statically linked into librustc_driver.so, so > rustc calls into .rodata and crashes. > > Reproducer (two installs on purpose - that mismatch is the bug): > > $ cat repro.s > .text > .globl func > func: > push tbl@GOTPCREL(%rip) > add $8, %rsp > ret > .section .rodata > .globl tbl > .hidden tbl > tbl: > .zero 576 > > $ as --version | head -1 > GNU assembler (GNU Binutils) 2.46.1 > $ as -o repro.o repro.s > $ readelf -rW repro.o | grep tbl > 0000000000000002 0000000300000029 R_X86_64_GOTPCRELX 0000000000000000 tbl - 4 > > $ ld --version | head -1 > GNU ld (GNU Binutils for Ubuntu) 2.38 > $ ld -shared -o bad.so repro.o > $ objdump -d bad.so | grep -A1 '<func>:' > 0000000000001000 <func>: > 1000: 67 e8 fa 0f 00 00 addr32 call 2000 <tbl> > > ld 2.46.1 on the same repro.o keeps "ff 35" (push through GOT). > gas 2.38 emits plain GOTPCREL for this source, so only new-gas > objects with old ld are affected. > > Old branches are closed, I know - but some of our build hosts must > stay on distro binutils for a while, so we plan to carry this locally > (skip conversion for anything that isn't call/jmp, matching what newer > ld does for push in a shared library): Older branches are not closed. Like glibc, we keep older branches alive for obvious trivial fixes for as long as people are willing to maintian them (within reason). But in fact, not only are they not closed, H.J. already backported fixes for your exact problem a year ago. > [...] > > 1. Is this guard safe, or can modrm be something other than > 0x15/0x25/0x35 here that needs different handling? Use H.J.'s patch? > > 2. Worth documenting this incompatibility (PR or release notes)? > Every ld before 2.45 silently produces bad code from such objects, > and tracing the crash back to the linker was not easy. There's already https://sourceware.org/PR32991. > > Thanks, > Sunil Dora sam
signature.asc
(application/pgp-signature, 418 B)
-----BEGIN PGP SIGNATURE----- iQEBBAEWCgCpFiEEJaa7iN2bdkxrVUHCc4QJ9SDfkZAFAmpP90UbFIAAAAAABAAO bWFudTIsMi41KzEuMTIsMiwyXxSAAAAAAC4AKGlzc3Vlci1mcHJAbm90YXRpb25z Lm9wZW5wZ3AuZmlmdGhob3JzZW1hbi5uZXQyNUE2QkI4OEREOUI3NjRDNkI1NTQx QzI3Mzg0MDlGNTIwREY5MTkwDxxzYW1AZ2VudG9vLm9yZwAKCRBzhAn1IN+RkEXc AQCHAZ92vMeDUBVaTmwwgnJUEWLw1vSBEDiYEXLRYPqdTQD/diccvHFiarheaP06 oJaGISzdItjKR+T4E/qIHA2mqg8= =oiR3 -----END PGP SIGNATURE-----