svn commit: r309360 - head/sys/boot/common

Ed Maste emaste at FreeBSD.org
Thu Dec 1 14:28:38 UTC 2016


Author: emaste
Date: Thu Dec  1 14:28:37 2016
New Revision: 309360
URL: https://svnweb.freebsd.org/changeset/base/309360

Log:
  EFI loaders: parse rela relocations on amd64
  
  Prior to this change the loader self relocation code interpreted amd64's
  rela relocations as if they were rel relocations, discarding the addend.
  This "works" because GNU ld 2.17.50 stores the addend value in both the
  r_addend field of the relocation (as expected) and at the target of the
  relocation.
  
  Other linkers, and possibly other versions of GNU ld, won't have this
  behaviour, so interpret the relocations correctly.
  
  Reported by:	George Rimar
  Reviewed by:	andrew
  MFC after:	2 weeks
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D8681

Modified:
  head/sys/boot/common/self_reloc.c

Modified: head/sys/boot/common/self_reloc.c
==============================================================================
--- head/sys/boot/common/self_reloc.c	Thu Dec  1 12:32:52 2016	(r309359)
+++ head/sys/boot/common/self_reloc.c	Thu Dec  1 14:28:37 2016	(r309360)
@@ -31,7 +31,7 @@ __FBSDID("$FreeBSD$");
 #include <elf.h>
 #include <bootstrap.h>
 
-#if defined(__aarch64__)
+#if defined(__aarch64__) || defined(__amd64__)
 #define	ElfW_Rel	Elf64_Rela
 #define	ElfW_Dyn	Elf64_Dyn
 #define	ELFW_R_TYPE	ELF64_R_TYPE
@@ -40,10 +40,6 @@ __FBSDID("$FreeBSD$");
 #define	ElfW_Rel	Elf32_Rel
 #define	ElfW_Dyn	Elf32_Dyn
 #define	ELFW_R_TYPE	ELF32_R_TYPE
-#elif defined(__amd64__)
-#define	ElfW_Rel	Elf64_Rel
-#define	ElfW_Dyn	Elf64_Dyn
-#define	ELFW_R_TYPE	ELF64_R_TYPE
 #else
 #error architecture not supported
 #endif
@@ -99,7 +95,9 @@ self_reloc(Elf_Addr baseaddr, ElfW_Dyn *
 	}
 
 	/*
-	 * Perform the actual relocation.
+	 * Perform the actual relocation. We rely on the object having been
+	 * linked at 0, so that the difference between the load and link
+	 * address is the same as the load address.
 	 */
 	for (; relsz > 0; relsz -= relent) {
 		switch (ELFW_R_TYPE(rel->r_info)) {
@@ -110,12 +108,7 @@ self_reloc(Elf_Addr baseaddr, ElfW_Dyn *
 		case RELOC_TYPE_RELATIVE:
 			newaddr = (Elf_Addr *)(rel->r_offset + baseaddr);
 #ifdef ELF_RELA
-			/*
-			 * For R_AARCH64_RELATIVE we need to calculate the
-			 * delta between the address we are run from and the
-			 * address we are linked at. As the latter is 0 we
-			 * just use the address we are run from for this.
-			 */
+			/* Addend relative to the base address. */
 			*newaddr = baseaddr + rel->r_addend;
 #else
 			/* Address relative to the base address. */


More information about the svn-src-head mailing list