Blame SOURCES/0009-gnuefi-preserve-.gnu.hash-sections-unbreaks-elilo-on.patch

d1fe48
From 2cc0b085fb82e80d43cc08c8376dff9f9532a72d Mon Sep 17 00:00:00 2001
d1fe48
From: Sergei Trofimovich <slyfox@gentoo.org>
d1fe48
Date: Sat, 27 Jan 2018 20:29:05 +0000
d1fe48
Subject: [PATCH 09/25] gnuefi: preserve .gnu.hash sections (unbreaks elilo on
d1fe48
 IA-64)
d1fe48
d1fe48
Gentoo has slightly modified linker defaults: --hash-style=gnu
d1fe48
This means all ELF files in system have '.gnu.hash' section
d1fe48
but no '.hash' section.
d1fe48
d1fe48
gnuefi's ldscript did not account for it and as a result
d1fe48
one symbol 'ImageBase' did not resolve locally for elilo.so
d1fe48
and caused 'elilo' to fail to load by ia64 EFI:
d1fe48
  Loading.: Gentoo (try new elilo)
d1fe48
  ImageAddress: pointer is outside of image
d1fe48
  ImageAddress: pointer is outside of image
d1fe48
d1fe48
Those two relocations come from crt0-efi-ia64.S PE32 entry point
d1fe48
fdescr:
d1fe48
d1fe48
```
d1fe48
    #define IMAGE_REL_BASED_DIR64<->10
d1fe48
    .section .reloc, "a"
d1fe48
    data4   _start_plabel // Page RVA
d1fe48
    data4   12            // Block Size (2*4+2*2)
d1fe48
    data2   (IMAGE_REL_BASED_DIR64<<12) +  0 // reloc for plabel's entry point
d1fe48
    data2   (IMAGE_REL_BASED_DIR64<<12) +  8 // reloc for plabel's global pointer
d1fe48
```
d1fe48
d1fe48
These refer ImageBase.
d1fe48
d1fe48
The change adds '.gnu.hash' collection (follows existing '.hash'
d1fe48
collection).
d1fe48
d1fe48
Tested on IA-64 by successfully booting elilo-3.16.
d1fe48
d1fe48
Bug: https://bugs.gentoo.org/575300
d1fe48
Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
d1fe48
---
d1fe48
 README.gnuefi                  | 8 +++++++-
d1fe48
 gnuefi/elf_ia32_efi.lds        | 4 +++-
d1fe48
 gnuefi/elf_ia32_fbsd_efi.lds   | 4 +++-
d1fe48
 gnuefi/elf_ia64_efi.lds        | 4 +++-
d1fe48
 gnuefi/elf_x86_64_efi.lds      | 4 +++-
d1fe48
 gnuefi/elf_x86_64_fbsd_efi.lds | 4 +++-
d1fe48
 6 files changed, 22 insertions(+), 6 deletions(-)
d1fe48
d1fe48
diff --git a/README.gnuefi b/README.gnuefi
d1fe48
index a7feec0ba28..512698c28b4 100644
d1fe48
--- a/README.gnuefi
d1fe48
+++ b/README.gnuefi
d1fe48
@@ -231,11 +231,17 @@ and page sized.These eight sections are used to group together the much
d1fe48
 greater number of sections that are typically present in ELF object files.
d1fe48
 Specifically:
d1fe48
 
d1fe48
- .hash
d1fe48
+ .hash (and/or .gnu.hash)
d1fe48
 	Collects the ELF .hash info (this section _must_ be the first
d1fe48
 	section in order to build a shared object file; the section is
d1fe48
 	not actually loaded or used at runtime).
d1fe48
 
d1fe48
+	GNU binutils provides a mechanism to generate different hash info
d1fe48
+	via --hash-style=<sysv|gnu|both> option. In this case output
d1fe48
+	shared object will contain .hash section, .gnu.hash section or
d1fe48
+	both. In order to generate correct output linker script preserves
d1fe48
+	both types of hash sections.
d1fe48
+
d1fe48
  .text
d1fe48
 	Collects all sections containing executable code.
d1fe48
 
d1fe48
diff --git a/gnuefi/elf_ia32_efi.lds b/gnuefi/elf_ia32_efi.lds
d1fe48
index 6cc4ce1b8c7..f27fe5fc6e6 100644
d1fe48
--- a/gnuefi/elf_ia32_efi.lds
d1fe48
+++ b/gnuefi/elf_ia32_efi.lds
d1fe48
@@ -5,7 +5,9 @@ SECTIONS
d1fe48
 {
d1fe48
   . = 0;
d1fe48
   ImageBase = .;
d1fe48
-  .hash : { *(.hash) }	/* this MUST come first! */
d1fe48
+  /* .hash and/or .gnu.hash MUST come first! */
d1fe48
+  .hash : { *(.hash) }
d1fe48
+  .gnu.hash : { *(.gnu.hash) }
d1fe48
   . = ALIGN(4096);
d1fe48
   .text :
d1fe48
   {
d1fe48
diff --git a/gnuefi/elf_ia32_fbsd_efi.lds b/gnuefi/elf_ia32_fbsd_efi.lds
d1fe48
index 77d6fade1a5..cd309e24f7f 100644
d1fe48
--- a/gnuefi/elf_ia32_fbsd_efi.lds
d1fe48
+++ b/gnuefi/elf_ia32_fbsd_efi.lds
d1fe48
@@ -5,7 +5,9 @@ SECTIONS
d1fe48
 {
d1fe48
   . = 0;
d1fe48
   ImageBase = .;
d1fe48
-  .hash : { *(.hash) }	/* this MUST come first! */
d1fe48
+  /* .hash and/or .gnu.hash MUST come first! */
d1fe48
+  .hash : { *(.hash) }
d1fe48
+  .gnu.hash : { *(.gnu.hash) }
d1fe48
   . = ALIGN(4096);
d1fe48
   .text :
d1fe48
   {
d1fe48
diff --git a/gnuefi/elf_ia64_efi.lds b/gnuefi/elf_ia64_efi.lds
d1fe48
index baca9623b57..190792a0c94 100644
d1fe48
--- a/gnuefi/elf_ia64_efi.lds
d1fe48
+++ b/gnuefi/elf_ia64_efi.lds
d1fe48
@@ -5,7 +5,9 @@ SECTIONS
d1fe48
 {
d1fe48
   . = 0;
d1fe48
   ImageBase = .;
d1fe48
-  .hash : { *(.hash) }	/* this MUST come first! */
d1fe48
+  /* .hash and/or .gnu.hash MUST come first! */
d1fe48
+  .hash : { *(.hash) }
d1fe48
+  .gnu.hash : { *(.gnu.hash) }
d1fe48
   . = ALIGN(4096);
d1fe48
   .text :
d1fe48
   {
d1fe48
diff --git a/gnuefi/elf_x86_64_efi.lds b/gnuefi/elf_x86_64_efi.lds
d1fe48
index 942d1f3eff7..7be59023510 100644
d1fe48
--- a/gnuefi/elf_x86_64_efi.lds
d1fe48
+++ b/gnuefi/elf_x86_64_efi.lds
d1fe48
@@ -6,7 +6,9 @@ SECTIONS
d1fe48
 {
d1fe48
   . = 0;
d1fe48
   ImageBase = .;
d1fe48
-  .hash : { *(.hash) }	/* this MUST come first! */
d1fe48
+  /* .hash and/or .gnu.hash MUST come first! */
d1fe48
+  .hash : { *(.hash) }
d1fe48
+  .gnu.hash : { *(.gnu.hash) }
d1fe48
   . = ALIGN(4096);
d1fe48
   .eh_frame : 
d1fe48
   { 
d1fe48
diff --git a/gnuefi/elf_x86_64_fbsd_efi.lds b/gnuefi/elf_x86_64_fbsd_efi.lds
d1fe48
index 6fd2031c13b..fe1f3342cae 100644
d1fe48
--- a/gnuefi/elf_x86_64_fbsd_efi.lds
d1fe48
+++ b/gnuefi/elf_x86_64_fbsd_efi.lds
d1fe48
@@ -6,7 +6,9 @@ SECTIONS
d1fe48
 {
d1fe48
   . = 0;
d1fe48
   ImageBase = .;
d1fe48
-  .hash : { *(.hash) }	/* this MUST come first! */
d1fe48
+  /* .hash and/or .gnu.hash MUST come first! */
d1fe48
+  .hash : { *(.hash) }
d1fe48
+  .gnu.hash : { *(.gnu.hash) }
d1fe48
   . = ALIGN(4096);
d1fe48
   .eh_frame : 
d1fe48
   { 
d1fe48
-- 
d1fe48
2.15.0
d1fe48