From owner-svn-src-all@freebsd.org Thu Dec 1 14:28:38 2016 Return-Path: Delivered-To: svn-src-all@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 A60E0C601D9; Thu, 1 Dec 2016 14:28:38 +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 5D15E18EB; Thu, 1 Dec 2016 14:28:38 +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 uB1ESbqp063180; Thu, 1 Dec 2016 14:28:37 GMT (envelope-from emaste@FreeBSD.org) Received: (from emaste@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id uB1ESbnh063179; Thu, 1 Dec 2016 14:28:37 GMT (envelope-from emaste@FreeBSD.org) Message-Id: <201612011428.uB1ESbnh063179@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: emaste set sender to emaste@FreeBSD.org using -f From: Ed Maste Date: Thu, 1 Dec 2016 14:28:37 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r309360 - head/sys/boot/common X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 01 Dec 2016 14:28:38 -0000 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 #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)) { @@ -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. */