Open kvtb opened 10 months ago
Similar as https://github.com/NixOS/patchelf/issues/244, would (partially) fixed by https://github.com/NixOS/patchelf/pull/264 and (hopefully) will be fixed together with my recent pcloud-related things (since pcloud also relies on node under the hood).
Alright, got it!
The issue is that libnode.so
happens to have .rodata
placed at the beginning of the file:
; readelf -S libnode.so
There are 29 section headers, starting at offset 0x152bf70:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .rodata PROGBITS 0000000000000240 00000240
00000000003796a8 0000000000000000 AMS 0 0 32
/* ... */
... which patchelf, when growing the program header table, moves somewhere else (which also changes its virtual memory address, aii aii!).
Relocating this section (at least without relocating all the other sections) is illegal, because the underlying assembly might use (and, in this case, does use) RIP-relative addressing, which breaks when the sections are shuffled around in the memory like that.
tl;dr patchelf changes memory address of an *.elf section that is supposed to be non-movable
I wonder if instead of extending the PHDR we could just allocate a new one, at the end of the file? This wouldn't cause this mayhem; I'll try playing with that.
Edit: I should perhaps also mention that allocating .rodata
at the beginning of the file is not a crime on its own - I think it's just that most binaries allocate this section somewhere further in the file and that's why this bug remained hidden for so long (because usually the first sections in the *.elf file were something patchelf could freely shuffle around).
Ah, we extend PHDR instead of allocating a new one due to a Linux bug:
https://github.com/NixOS/patchelf/blob/7c2f768bf9601268a4e71c2ebe91e2011918a70f/BUGS#L1
Considering the commit is from 2005, hopefully that's not the case anymore!
Describe the bug
patchelf --set-rpath ${stdenv.cc.cc.lib}/lib node
produces broken executable withpatchelf-0.17.2
andpatchelf-0.18.0
, no problem withpatchelf-0.15.0
the resulting executables crash with Segmentation Failed
ldd node
produces no output at allSteps To Reproduce
node
is from this archive: https://nodejs.org/dist/v16.14.2/node-v16.14.2-linux-x64.tar.gzThen run
patchelf --set-rpath ${stdenv.cc.cc.lib}/lib node
where${stdenv.cc.cc.lib}
is the path to gcc libs path on your systemExpected behavior
Expected working executable as it was with
patchelf-0.15.0
patchelf --version
output0.17.2, 0.18.0
Additional context
Downloaded
node
may seems ridiculous example, but using downloadednode
andprotoc
it is an usual part of Maven build process. BTW, there was no problem with patchingprotoc
with anypatchelf
version