Comment 4 for bug 503448

Revision history for this message
Dave Martin (dave-martin-arm) wrote :

Unfortunately, resolving the problem is not as simple as the article makes out, although silently building libraries containing relocations ld.so can't handle is clearly bad and it's a good thing that was fixed.

The article also doesn't comment on the costs of non-PIC shared libraries (see my last post)

IIUC, non-PIC shared libraries were never really deliberately supported for ARM, they just worked by coincidence.

The difference between ARMv7 and v6 and earlier is that ARMv7 will load 32-bit values into registers directly using the MOVW and MOVT instructions, rather than using a literal pool entry. The impact is that the code executes faster and eliminates some D-cache and D-TLB pollution; however, because relocating these references involves relocating instructions instead of a literal pool data word it would place an extra load on the dynamic linker.

Making this work correctly involves:
  * adding ld.so support for all the text relocations which may appear in static binaries in general (which may be more than just R_ARM_MOVW and R_ARM_MOVT);
  * enabling ld.so to do code relocations correctly (with the implied cache flushing requirements etc.) – I believe this is not implemented at present;
  * getting various complexities right in connection with ELF symbol binding types and symbol preemption
  * changing binutils' idea of what relocation types it should allow in shared libraries

This isn't trivial and requires some concerted effort between binutils and eglibc communities. There's also a risk that implementing these features correctly in the dynamic linker could have an impact on the performance of dynamic linking globally, if not done carefully.

The ELF specifications seem to make no direct comment on whether non-PIC shared libraries should work or not, but there's a defacto assumption from non-RISC architectures (where code relocations are simpler) that they do. It would be interesting to understand how this is currently handled for other RISC architectures such as MIPS and SPARC... but it seems not to be a common problem because very few apps build this way.