selfrando icon indicating copy to clipboard operation
selfrando copied to clipboard

Add support for .gnu.linkonce sections

Open ahomescu opened this issue 7 years ago • 2 comments

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:

  1. 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.
  2. A grouped .text.__x86.get_pc_thunk + .txtrp section pair in each linked object file, which all get discarded together.
  3. A lone .text.__x86.get_pc_thunk section with a .txtrp from our own selfrando object files (librandoentry_exec.a and librandoentry_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.

ahomescu avatar Jun 13 '17 22:06 ahomescu

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

ahomescu avatar Jun 22 '17 00:06 ahomescu

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.

ahomescu avatar Jul 03 '17 23:07 ahomescu