From owner-svn-src-stable@freebsd.org Wed Dec 28 21:58:22 2016 Return-Path: Delivered-To: svn-src-stable@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 47B39C950D0; Wed, 28 Dec 2016 21:58:22 +0000 (UTC) (envelope-from emaste@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id EF1D61483; Wed, 28 Dec 2016 21:58:21 +0000 (UTC) (envelope-from emaste@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id uBSLwLIn023678; Wed, 28 Dec 2016 21:58:21 GMT (envelope-from emaste@FreeBSD.org) Received: (from emaste@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id uBSLwL39023677; Wed, 28 Dec 2016 21:58:21 GMT (envelope-from emaste@FreeBSD.org) Message-Id: <201612282158.uBSLwL39023677@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: emaste set sender to emaste@FreeBSD.org using -f From: Ed Maste Date: Wed, 28 Dec 2016 21:58:21 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r310725 - stable/11/sys/boot/common X-SVN-Group: stable-11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Dec 2016 21:58:22 -0000 Author: emaste Date: Wed Dec 28 21:58:20 2016 New Revision: 310725 URL: https://svnweb.freebsd.org/changeset/base/310725 Log: Fix EFI self relocation code for rela architectures MFC r306812 (andrew): The bootloader self relocation code was slightly wrong for the R_AARCH64_RELATIVE relocation found on arm64. It would try to add the contents of the memory location being relocated to the base address and the relocation addend. This worked when the contents was zero, however this now seems to be set to the value of the addend so we add this twice. Fix this by just setting the memory to the computed value. MFC r309360: 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. Modified: stable/11/sys/boot/common/self_reloc.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/boot/common/self_reloc.c ============================================================================== --- stable/11/sys/boot/common/self_reloc.c Wed Dec 28 21:54:33 2016 (r310724) +++ stable/11/sys/boot/common/self_reloc.c Wed Dec 28 21:58:20 2016 (r310725) @@ -31,7 +31,7 @@ __FBSDID("$FreeBSD$"); #include #include -#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)) { @@ -108,12 +106,13 @@ self_reloc(Elf_Addr baseaddr, ElfW_Dyn * break; case RELOC_TYPE_RELATIVE: - /* Address relative to the base address. */ newaddr = (Elf_Addr *)(rel->r_offset + baseaddr); - *newaddr += baseaddr; - /* Add the addend when the ABI uses them */ #ifdef ELF_RELA - *newaddr += rel->r_addend; + /* Addend relative to the base address. */ + *newaddr = baseaddr + rel->r_addend; +#else + /* Address relative to the base address. */ + *newaddr += baseaddr; #endif break; default: