The GCC toolchain uses PIE mode when building code for X64, because it is the most efficient in size: it uses relative references where possible, but still uses 64-bit quantities for absolute symbol references, which is optimal for executables that need to be converted to PE/COFF using GenFw.
Enabling PIE mode has a couple of side effects though, primarily caused by the fact that the primary application area of GCC is to build programs for userland. GCC will assume that ELF symbols should be preemptible (which makes sense for PIC but not for PIE, but this simply seems to be the result of code being shared between the two modes), and it will attempt to keep absolute references close to each other so that dynamic relocations that trigger CoW for text pages have the smallest possible footprint. These side effects can be mititgated by overriding the visibility of all symbol definitions *and* symbol references, using a special #pragma. This will inform the compiler that symbol preemption and dynamic relocations are not a concern, and that all symbol references can be emitted as direct relative references rather than relative references to a GOT entry containing the absolute address. Unsurprisingly, this leads to better and smaller code. Unfortunately, we have not been able to set this override when LTO is in effect, because the LTO code generator infers from the hidden visibility of all symbols that none of the code is reachable, and discards it all, leading to corrupt, empty binaries. We can work around this by overriding the visibility for symbols that are module entry points. So implement this for all occcurrences of the symbol '_ModuleEntryPoint', and enable 'hidden' visibility in LTO builds as well. Note that all the changes in this series resolve to no-ops if USING_LTO is not #defined. Code can be found here: https://github.com/ardbiesheuvel/edk2/tree/x64-lto-visibility Cc: Michael D Kinney <michael.d.kin...@intel.com> Cc: Liming Gao <liming....@intel.com> Cc: Ruiyu Ni <ruiyu...@intel.com> Cc: Hao Wu <hao.a...@intel.com> Cc: Leif Lindholm <leif.lindh...@linaro.org> Cc: Jordan Justen <jordan.l.jus...@intel.com> Cc: Andrew Fish <af...@apple.com> Cc: Star Zeng <star.z...@intel.com> Cc: Eric Dong <eric.d...@intel.com> Cc: Laszlo Ersek <ler...@redhat.com> Cc: Zenith432 <zenith...@users.sourceforge.net> Cc: "Shi, Steven" <steven....@intel.com> Ard Biesheuvel (11): MdePkg/ProcessorBind.h: define macro to decorate module entry points DuetPkg: annotate module entry points with EFI_ENTRYPOINT EdkCompatibilityPkg: annotate module entry points with EFI_ENTRYPOINT EmbeddedPkg: annotate module entry points with EFI_ENTRYPOINT EmulatorPkg: annotate module entry points with EFI_ENTRYPOINT IntelFrameWorkPkg: annotate module entry points with EFI_ENTRYPOINT MdeModulePkg: annotate module entry points with EFI_ENTRYPOINT MdePkg: annotate module entry points with EFI_ENTRYPOINT Nt32Pkg: annotate module entry points with EFI_ENTRYPOINT UefiCpuPkg: annotate module entry points with EFI_ENTRYPOINT MdePkg/ProcessorBind.h X64: drop non-LTO limitation on visiblity override DuetPkg/DxeIpl/DxeInit.c | 1 + DuetPkg/EfiLdr/EfiLoader.c | 1 + .../EntryPoints/EdkIIGlueDxeDriverEntryPoint.c | 1 + .../EntryPoints/EdkIIGluePeimEntryPoint.c | 1 + .../EntryPoints/EdkIIGlueSmmDriverEntryPoint.c | 1 + .../Library/EdkIIGlueDxeSmmDriverEntryPoint.h | 1 + .../Include/Library/EdkIIGluePeimEntryPoint.h | 1 + .../Library/EdkIIGlueUefiDriverEntryPoint.h | 1 + EmbeddedPkg/TemplateSec/TemplateSec.c | 1 + EmulatorPkg/Sec/Sec.c | 1 + .../DxeSmmDriverEntryPoint/DriverEntryPoint.c | 1 + MdeModulePkg/Universal/CapsulePei/X64/X64Entry.c | 1 + MdePkg/Include/Base.h | 7 +++++++ MdePkg/Include/Library/DxeCoreEntryPoint.h | 1 + MdePkg/Include/Library/PeiCoreEntryPoint.h | 1 + MdePkg/Include/Library/PeimEntryPoint.h | 1 + .../Include/Library/UefiApplicationEntryPoint.h | 1 + MdePkg/Include/Library/UefiDriverEntryPoint.h | 1 + MdePkg/Include/X64/ProcessorBind.h | 16 +++++++++++----- .../DxeCoreEntryPoint/DxeCoreEntryPoint.c | 1 + .../PeiCoreEntryPoint/PeiCoreEntryPoint.c | 1 + MdePkg/Library/PeimEntryPoint/PeimEntryPoint.c | 1 + .../ApplicationEntryPoint.c | 1 + .../UefiDriverEntryPoint/DriverEntryPoint.c | 1 + Nt32Pkg/Sec/SecMain.c | 1 + .../PlatformSecLibNull/PlatformSecLibNull.c | 1 + 26 files changed, 42 insertions(+), 5 deletions(-) -- 2.17.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel