Browse Source

gnuefi: preserve .gnu.hash sections (unbreaks elilo on IA-64)

Gentoo has slightly modified linker defaults: --hash-style=gnu
This means all ELF files in system have '.gnu.hash' section
but no '.hash' section.

gnuefi's ldscript did not account for it and as a result
one symbol 'ImageBase' did not resolve locally for elilo.so
and caused 'elilo' to fail to load by ia64 EFI:
  Loading.: Gentoo (try new elilo)
  ImageAddress: pointer is outside of image
  ImageAddress: pointer is outside of image

Those two relocations come from crt0-efi-ia64.S PE32 entry point
fdescr:

```
    #define IMAGE_REL_BASED_DIR64<->10
    .section .reloc, "a"
    data4   _start_plabel // Page RVA
    data4   12            // Block Size (2*4+2*2)
    data2   (IMAGE_REL_BASED_DIR64<<12) +  0 // reloc for plabel's entry point
    data2   (IMAGE_REL_BASED_DIR64<<12) +  8 // reloc for plabel's global pointer
```

These refer ImageBase.

The change adds '.gnu.hash' collection (follows existing '.hash'
collection).

Tested on IA-64 by successfully booting elilo-3.16.

Bug: https://bugs.gentoo.org/575300
Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
Sergei Trofimovich 7 years ago
parent
commit
2cc0b085fb

+ 7 - 1
README.gnuefi

@@ -231,11 +231,17 @@ and page sized.These eight sections are used to group together the much
 greater number of sections that are typically present in ELF object files.
 greater number of sections that are typically present in ELF object files.
 Specifically:
 Specifically:
 
 
- .hash
+ .hash (and/or .gnu.hash)
 	Collects the ELF .hash info (this section _must_ be the first
 	Collects the ELF .hash info (this section _must_ be the first
 	section in order to build a shared object file; the section is
 	section in order to build a shared object file; the section is
 	not actually loaded or used at runtime).
 	not actually loaded or used at runtime).
 
 
+	GNU binutils provides a mechanism to generate different hash info
+	via --hash-style=<sysv|gnu|both> option. In this case output
+	shared object will contain .hash section, .gnu.hash section or
+	both. In order to generate correct output linker script preserves
+	both types of hash sections.
+
  .text
  .text
 	Collects all sections containing executable code.
 	Collects all sections containing executable code.
 
 

+ 3 - 1
gnuefi/elf_ia32_efi.lds

@@ -5,7 +5,9 @@ SECTIONS
 {
 {
   . = 0;
   . = 0;
   ImageBase = .;
   ImageBase = .;
-  .hash : { *(.hash) }	/* this MUST come first! */
+  /* .hash and/or .gnu.hash MUST come first! */
+  .hash : { *(.hash) }
+  .gnu.hash : { *(.gnu.hash) }
   . = ALIGN(4096);
   . = ALIGN(4096);
   .text :
   .text :
   {
   {

+ 3 - 1
gnuefi/elf_ia32_fbsd_efi.lds

@@ -5,7 +5,9 @@ SECTIONS
 {
 {
   . = 0;
   . = 0;
   ImageBase = .;
   ImageBase = .;
-  .hash : { *(.hash) }	/* this MUST come first! */
+  /* .hash and/or .gnu.hash MUST come first! */
+  .hash : { *(.hash) }
+  .gnu.hash : { *(.gnu.hash) }
   . = ALIGN(4096);
   . = ALIGN(4096);
   .text :
   .text :
   {
   {

+ 3 - 1
gnuefi/elf_ia64_efi.lds

@@ -5,7 +5,9 @@ SECTIONS
 {
 {
   . = 0;
   . = 0;
   ImageBase = .;
   ImageBase = .;
-  .hash : { *(.hash) }	/* this MUST come first! */
+  /* .hash and/or .gnu.hash MUST come first! */
+  .hash : { *(.hash) }
+  .gnu.hash : { *(.gnu.hash) }
   . = ALIGN(4096);
   . = ALIGN(4096);
   .text :
   .text :
   {
   {

+ 3 - 1
gnuefi/elf_x86_64_efi.lds

@@ -6,7 +6,9 @@ SECTIONS
 {
 {
   . = 0;
   . = 0;
   ImageBase = .;
   ImageBase = .;
-  .hash : { *(.hash) }	/* this MUST come first! */
+  /* .hash and/or .gnu.hash MUST come first! */
+  .hash : { *(.hash) }
+  .gnu.hash : { *(.gnu.hash) }
   . = ALIGN(4096);
   . = ALIGN(4096);
   .eh_frame : 
   .eh_frame : 
   { 
   { 

+ 3 - 1
gnuefi/elf_x86_64_fbsd_efi.lds

@@ -6,7 +6,9 @@ SECTIONS
 {
 {
   . = 0;
   . = 0;
   ImageBase = .;
   ImageBase = .;
-  .hash : { *(.hash) }	/* this MUST come first! */
+  /* .hash and/or .gnu.hash MUST come first! */
+  .hash : { *(.hash) }
+  .gnu.hash : { *(.gnu.hash) }
   . = ALIGN(4096);
   . = ALIGN(4096);
   .eh_frame : 
   .eh_frame : 
   { 
   {