Fix MIPS segfaults relating to DT_MIPS_RLD_MAP_REL and RPath removal
This is my attempt at fixing the issue I described in this Debian bug report: https://bugs.debian.org/820334
There is a comment in the code which describes why we need to do this on MIPS:
// Background: debuggers need to know the "linker map" which contains
// the addresses each dynamic object is loaded at. Most arches use
// the DT_DEBUG tag which the dynamic linker writes to (directly) and
// contain the location of the linker map, however on MIPS the
// .dynamic section is always read-only so this is not possible. MIPS
// objects instead contain a DT_MIPS_RLD_MAP tag which contains the
// address where the dyanmic linker will write to (an indirect
// version of DT_DEBUG). Since this doesn't work when using PIE, a
// relative equivalent was created - DT_MIPS_RLD_MAP_REL. Since this
// version contains a relative offset, moving it changes the
// calculated address. This may cause the dyanmic linker to write
// into memory it should not be changing.
//
// To fix this, we adjust the value of DT_MIPS_RLD_MAP_REL here. If
// we move it up by n bytes, we add n bytes to the value of this tag.
The other 4 commits do some refactoring around the cmELF
API to make it possible to implement this. I decided to add a DynamicEntryList
type to allow cmELF
callers to read the entire .dynamic
section from the ELF, manipulate it, and then re-encode it. This seemed like the best abstraction to me since it keeps all the endian/bitness issues inside cmELF
.
Instead of adding DT_MIPS_RLD_MAP_REL
to the ByteSwap(ELF_Dyn& dyn)
method, I simply removed the switch from it. In both ELF32 and ELF64, sizeof(dyn.d_un.d_val) == sizeof(dyn.d_un.d_ptr)
so there is no need to distinguish between them when fixing the endianness.
Merge request reports
Activity
Hrm. CMake doesn't have a commit static_assert (that I can see right now). It'd be nice to static_assert the
sizeof(dyn.d_un.d_val) == sizeof(dyn.d_un.d_ptr)
so that if it ever does change, we'll know ahead of time.Also, it looks like this is a brand new tag, so it should be backwards compatible?
@jcowgill please use the negative sized array hack. We still support C++98 builds in general (the only use of C++11 is in the new optional cmake server mode feature).
Otherwise, LGTM. The commit sequence is well organized. Please squash the static assertion (hack) back into its proper commit and force-push.
Added 5 commits:
- 66c4d082 - elf: remove tag switch from ELF_Dyn ByteSwap function
- 72eb6a37 - elf: add DynamicEntryList methods and rpath tag constants
- df16bb48 - cmSystemTools: rewrite RemoveRPath using DyanmicEntryList methods
- 1d156cd3 - cmSystemTools, elf: handle DT_MIPS_RLD_REL_MAP in RemoveRPath
- 52fa6aab - elf: Remove GetDynamicEntryCount and ReadBytes methods
Toggle commit listReassigned to @brad.king
Milestone changed to %3.8.0