RFC: Linker feature for automatically partitioning a program into multiple binaries

Hi Peter,

I gather from your other posts that you care most about UEFI – I don’t know what capabilities the UEFI loader has.

Yes, I care Uefi most. We can extend Uefi image loader to support new linker feature if necessary. No problem.

Actually, Uefi firmware is very sensitive on code/image size. Millions of code have to be linked into only several MB ROM space. Every KB counts for us.

Uefi only support static linking for now and there are many common library function built into each module. We use the compression on multiple modules to mitigate the common library code size issue but it is not an ideal solution. The compressed module need memory to decompress in runtime but Uefi have modules need to run (XIP) before the memory is ready. So we have the requirement to support dynamic linking.

These binaries will all share a virtual address space so that they can refer to one another directly using PC-relative references or RELATIVE dynamic relocations as if they were all statically linked together in the first place, rather than via the GOT (or custom GOT-equivalent).

I like PC-relative relocation and don’t like GOT/PLT based relocations. We have to convert the ELF to COFF image after linking through special build tool, and it is very hard to do the conversion for GOT/PLT based relocations.

I could consider to natively support the ELF binary in the Uefi image loader, which will make everything easy. But the problem is current Uefi specification says Uefi only support PE/COFF image…

Each exported symbol by itself imposes additional binary size costs, as it requires the name of the symbol and a dynamic symbol table entry to be stored in both the exporting and importing DSO, and on the importing side a dynamic relocation, a GOT entry and likely a PLT entry must be present. These additional costs go some way towards defeating the purpose of splitting the program into pieces in the first place, and can also impact program startup and overall performance because of the additional indirections.

I need uncompromising code size decrease, and I don’t want GOT/PLT entries. OK, your proposal is just what I want.

I haven’t thought about how this feature will interact with linker scripts. At least to start with we will likely need to forbid using this feature together with the PHDRS or SECTIONS linker script directives.

Could you help to take a look at our ELF linker script: https://github.com/tianocore/edk2/blob/master/BaseTools/Scripts/GccBase.lds, and let me know whether it can get alone with your proposed dynamic linking feature. I’m OK to change it if it cannot. Please be aware I can fully change my loader and linking script, and let me know your suggestion on how to change them.

A prototype/proof of concept of this feature has been implemented here: https://github.com/pcc/llvm-project/tree/lld-module-symbols

Sorry, but could you let me know the basic build steps of your lld?