-
-
Notifications
You must be signed in to change notification settings - Fork 482
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Broken binaries generated on mipsel #82
Comments
Hmm. On second look it is not different (the first column appears to be the address). Why would the first complain but the second not? |
Some more information: when creating a hello world executable and running
And ended up like this:
In particular, note that the |
|
This is still true for patchelf 0.10 on my mips32el machines. I digged into that a bit, and found that the problem is around the MIPS-specific mechanism of setting up the debug map pointer. When https://sourceware.org/git/?p=glibc.git;a=blob;f=elf/rtld.c;h=453f56eb157b1795c86f9eddd2df45fcab9a0a9b#l1572 When |
The reason for that is that the dynamic loader does not look for the I'm testing the fix right now. |
`patchelf --set-rpath` corrupted executables on mips32el: the dynamic liker crushed with Segmentation fault when loading any executable with RPATH added that way. The problem was around the MIPS-specific mechanism of setting up the debug map pointer. When DT_MIPS_RLD_MAP_REL entry in the dynamic section is not zero, it holds the relative address of __RLD_MAP -- an offset relative to this dynamic section entry. Dynamic linker puts the pointer to the `r_debug` structure there. When patchelf updates the executable RPATH, it moves the .dynamic section both in the binary and in memory, while __RLD_MAP is not moved in memory, since it belongs to special .rld_map section that has type PROGBITS. So, the offset stored in DT_MIPS_RLD_MAP_REL entry is not valid anymore and should be updated. This commit adds the necessary update. Here we also import DT_MIPS_RLD_MAP_REL definition in elf.h form glibc commit a2057c984e4314c3740f04cf54e36c824e4c8f32. Refs: NixOS#82 Signed-off-by: Ivan A. Melnikov <[email protected]> DT_MIPS_RLD_MAP_REL
When loading the executable on MIPS, the dynamic loader looks for MIPS ABI flags using PT_MIPS_ABIFLAGS header. The flags themselves are stored in the .MIPS.abiflags section, so the header must be updated when the section is moved. Here we also import PT_MIPS_ABIFLAGS definition from glibc commit 0bd956720c457ff054325b48f26ac7c91cb060e8. Closes: NixOS#82 Signed-off-by: Ivan A. Melnikov <[email protected]>
`patchelf --set-rpath` corrupted executables on mips32el: the dynamic liker crushed with Segmentation fault when loading any executable with RPATH added that way. The problem was around the MIPS-specific mechanism of setting up the debug map pointer. When DT_MIPS_RLD_MAP_REL entry in the dynamic section is not zero, it holds the relative address of __RLD_MAP -- an offset relative to this dynamic section entry. Dynamic linker puts the pointer to the `r_debug` structure there. When patchelf updates the executable RPATH, it moves the .dynamic section both in the binary and in memory, while __RLD_MAP is not moved in memory, since it belongs to special .rld_map section that has type PROGBITS. So, the offset stored in DT_MIPS_RLD_MAP_REL entry is not valid anymore and should be updated. This commit adds the necessary update. Here we also import DT_MIPS_RLD_MAP_REL definition in elf.h form glibc commit a2057c984e4314c3740f04cf54e36c824e4c8f32. Refs: NixOS#82 Signed-off-by: Ivan A. Melnikov <[email protected]> DT_MIPS_RLD_MAP_REL
When loading the executable on MIPS, the dynamic loader looks for MIPS ABI flags using PT_MIPS_ABIFLAGS header. The flags themselves are stored in the .MIPS.abiflags section, so the header must be updated when the section is moved. Here we also import PT_MIPS_ABIFLAGS definition from glibc commit 0bd956720c457ff054325b48f26ac7c91cb060e8. Closes: NixOS#82 Signed-off-by: Ivan A. Melnikov <[email protected]>
`patchelf --set-rpath` corrupted executables on mips32el: the dynamic liker crushed with Segmentation fault when loading any executable with RPATH added that way. The problem was around the MIPS-specific mechanism of setting up the debug map pointer. When DT_MIPS_RLD_MAP_REL entry in the dynamic section is not zero, it holds the relative address of __RLD_MAP -- an offset relative to this dynamic section entry. Dynamic linker puts the pointer to the `r_debug` structure there. When patchelf updates the executable RPATH, it moves the .dynamic section both in the binary and in memory, while __RLD_MAP is not moved in memory, since it belongs to special .rld_map section that has type PROGBITS. So, the offset stored in DT_MIPS_RLD_MAP_REL entry is not valid anymore and should be updated. This commit adds the necessary update. Here we also import DT_MIPS_RLD_MAP_REL definition in elf.h form glibc commit a2057c984e4314c3740f04cf54e36c824e4c8f32. Refs: NixOS#82 Signed-off-by: Ivan A. Melnikov <[email protected]>
When loading the executable on MIPS, the dynamic loader looks for MIPS ABI flags using PT_MIPS_ABIFLAGS header. The flags themselves are stored in the .MIPS.abiflags section, so the header must be updated when the section is moved. Here we also import PT_MIPS_ABIFLAGS definition from glibc commit 0bd956720c457ff054325b48f26ac7c91cb060e8. Closes: NixOS#82 Signed-off-by: Ivan A. Melnikov <[email protected]>
`patchelf --set-rpath` corrupted executables on mips32el: the dynamic liker crushed with Segmentation fault when loading any executable with RPATH added that way. The problem was around the MIPS-specific mechanism of setting up the debug map pointer. When DT_MIPS_RLD_MAP_REL entry in the dynamic section is present, it holds the relative address of __RLD_MAP -- an offset relative to this dynamic section entry. Dynamic linker puts the pointer to the `r_debug` structure there. When patchelf updates the executable RPATH, it moves the .dynamic section both in the binary and in memory, while __RLD_MAP is not moved in memory, since it belongs to special .rld_map section that has type PROGBITS. So, the offset stored in DT_MIPS_RLD_MAP_REL entry is not valid anymore and should be updated. This commit adds the necessary update. In the corner case when DT_MIPS_RLD_MAP_REL is present, but .rld_map section is not, the dynamic loader writes the debug pointer to some arbitrary bytes in memory. To avoid crushes on otherwise "working" binaries, we set offset to zero so that the dynamic loader would just overwrite the dynamic section. Here we also import DT_MIPS_RLD_MAP_REL definition in elf.h form glibc commit a2057c984e4314c3740f04cf54e36c824e4c8f32. Refs: NixOS#82 Signed-off-by: Ivan A. Melnikov <[email protected]>
`patchelf --set-rpath` corrupted executables on mips32el: the dynamic liker crushed with Segmentation fault when loading any executable with RPATH added that way. The problem was around the MIPS-specific mechanism of setting up the debug map pointer. When DT_MIPS_RLD_MAP_REL entry in the dynamic section is present, it holds the relative address of __RLD_MAP -- an offset relative to this dynamic section entry. Dynamic linker puts the pointer to the `r_debug` structure there. When patchelf updates the executable RPATH, it moves the .dynamic section both in the binary and in memory, while __RLD_MAP is not moved in memory, since it belongs to special .rld_map section that has type PROGBITS. So, the offset stored in DT_MIPS_RLD_MAP_REL entry is not valid anymore and should be updated. This commit adds the necessary update. In the corner case when DT_MIPS_RLD_MAP_REL is present, but .rld_map section is not, the dynamic loader writes the debug pointer to some arbitrary bytes in memory. To avoid crushes on otherwise "working" binaries, we set offset to zero so that the dynamic loader would just overwrite the dynamic section. Here we also import DT_MIPS_RLD_MAP_REL definition in elf.h form glibc commit a2057c984e4314c3740f04cf54e36c824e4c8f32. Refs: NixOS#82 Signed-off-by: Ivan A. Melnikov <[email protected]>
When loading the executable on MIPS, the dynamic loader looks for MIPS ABI flags using PT_MIPS_ABIFLAGS header. The flags themselves are stored in the .MIPS.abiflags section, so the header must be updated when the section is moved. Here we also import PT_MIPS_ABIFLAGS definition from glibc commit 0bd956720c457ff054325b48f26ac7c91cb060e8. Closes: NixOS#82 Signed-off-by: Ivan A. Melnikov <[email protected]>
Tests failed on mipsel on debian:
Further debug shows that the library is found, it just can't be loaded because there is an invalid MIPS.abiflags:
Further testing shows that this problem happens even when libfoo-scoped has not been touched. The problem appears to be when touching the main-scoped binary. So, I dug up the mentioned header, and indeed it is different in the touched binary:
Why would patchelf modify a section it is not supposed to?
The text was updated successfully, but these errors were encountered: