selfrando
selfrando copied to clipboard
Add support for .gnu.linkonce sections
There are 2 different COMDAT implementations for ELF: group sections and .gnu.linkonce
sections. The former are the newer and better version, so group sections are now used almost everywhere, but 32-bit libc still uses linkonce sections for one thing: the __x86.get_pc_thunk.bx
helper function for PIC code.
TrapLinker supports group sections by adding each .txtrp
section to the group of its owner section, but we can't do the same for .gnu.linkonce
sections. A correct fix would be to convert all linkonce sections to equivalent group sections, then add .txtrp
to those, but this is not trivial to implement (each .gnu.linkonce.t
section would be converted to one .group
section followed by a .text
section containing its actual data).
Luckily, for our singular use case, we do not need this (for now). When we link a 32-bit x86 file, we get the following sections:
- A
.gnu.linkonce.t.__x86.get_pc_thunk
linkonce section from/usr/lib32/crti.o
, which TrapLinker adds a dangling (non-grouped).txtrp
section to. The linkonce section gets discarded, but.txtrp
does not. - A grouped
.text.__x86.get_pc_thunk
+.txtrp
section pair in each linked object file, which all get discarded together. - A lone
.text.__x86.get_pc_thunk
section with a.txtrp
from our own selfrando object files (librandoentry_exec.a
andlibrandoentry_so.a
). This one gets linked into the output binary.
The output binary contains the function section from 3. above together with the .txtrp
from 1., so all we need to do is make sure they match. Commit https://github.com/immunant/selfrando/commit/4754ceebbaa68d8115ff23cff9a6e47cd592d78a takes care of this.
Later testing showed that we need to pin the .txtrp
section from crti.o
ourselves (using an anchor reloc in .init
), as implemented in commit https://github.com/immunant/selfrando/commit/4d3b52cae8c4d18a718a918f72f948641334867f
For now, support for .gnu.linkonce
sections is limited: they are allowed in object files, but we do not emit TRaP information for them.
To support 32-bit x86 crti.o
, we uses another approach: librandoentry_{exec,so}.a
now contains its own version of __x86.get_pc_thunk.bx
along with the correct .txtrp
section for this function, and the latter is pinned using a NOP anchor in .init
.