From owner-svn-src-all@freebsd.org Sun Dec 10 21:51:28 2017 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 A97D7E9E53F; Sun, 10 Dec 2017 21:51:28 +0000 (UTC) (envelope-from ian@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 8354764C3D; Sun, 10 Dec 2017 21:51:28 +0000 (UTC) (envelope-from ian@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id vBALpROm051521; Sun, 10 Dec 2017 21:51:27 GMT (envelope-from ian@FreeBSD.org) Received: (from ian@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id vBALpRGZ051520; Sun, 10 Dec 2017 21:51:27 GMT (envelope-from ian@FreeBSD.org) Message-Id: <201712102151.vBALpRGZ051520@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ian set sender to ian@FreeBSD.org using -f From: Ian Lepore Date: Sun, 10 Dec 2017 21:51:27 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r326752 - head/stand/arm/uboot X-SVN-Group: head X-SVN-Commit-Author: ian X-SVN-Commit-Paths: head/stand/arm/uboot X-SVN-Commit-Revision: 326752 X-SVN-Commit-Repository: base 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.25 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: Sun, 10 Dec 2017 21:51:28 -0000 Author: ian Date: Sun Dec 10 21:51:27 2017 New Revision: 326752 URL: https://svnweb.freebsd.org/changeset/base/326752 Log: Save and restore r9 register in arm ubldr. In old gcc 4.2, r9 was a callee- saved register, but in arm EABI it may be either callee-saved or dedicated to some special purpose (such as a TLS pointer). It appears clang does not treat it as a callee-saved register (instead using it as another work register, similar to r12). Another important side effect of these changes is that saving an extra register in the push/pop statements keeps the stack aligned to an 8-byte boundary during the self_reloc() call, as it always should have been. As stated in the PR... Essentially the important caller-saved registers are pushed (r0, r1, r9, lr) before the relocation call, and popped after. Then r8/r9 are saved as usual for the syscall trampoline, and lr is stored in r8 (now free) as a callee-saved value before calling into `main`. The call to `main` can no longer be a tail call because we must restore r9 especially after main returns (although since we have used r8 to hold lr we must also restore this). PR: 224008 Modified: head/stand/arm/uboot/start.S Modified: head/stand/arm/uboot/start.S ============================================================================== --- head/stand/arm/uboot/start.S Sun Dec 10 19:22:43 2017 (r326751) +++ head/stand/arm/uboot/start.S Sun Dec 10 21:51:27 2017 (r326752) @@ -46,11 +46,8 @@ _start: mcr p15, 0, ip, c1, c0, 0 #endif - /* - * Save r0 and r1 (argc and argv passed from u-boot), and lr (trashed - * by the call to self_reloc below) until we're ready to call main(). - */ - push {r0, r1, lr} + /* Save the arguments and return register before calling self_reloc */ + push {r0, r1, r9, lr} /* * Do self-relocation when the weak external symbol _DYNAMIC is non-NULL. @@ -68,22 +65,31 @@ _start: addne r1, r1, r0 /* r1 = dynamic section physaddr. */ blne _C_LABEL(self_reloc) /* Do reloc if _DYNAMIC is non-NULL. */ + /* Restore saved arguments */ + pop {r0, r1, r9, lr} + /* Hint where to look for the API signature */ ldr ip, =uboot_address str sp, [ip] - /* Save U-Boot's r8 and r9 */ + /* Save U-Boot's r8 and r9 for syscall trampoline */ ldr ip, =saved_regs - str r8, [ip, #0] - str r9, [ip, #4] + str r8, [ip, #0] /* old gd pointer (use to hold lr) */ + str r9, [ip, #4] /* new gd pointer */ /* - * First restore argc, argv, and the u-boot return address, then - * Start loader. This is basically a tail-recursion call; if main() - * returns, it returns to u-boot (which reports the value returned r0). + * Start loader. Save return address first (r8 is available from + * trampoline save). */ - pop {r0, r1, lr} - b main + mov r8, lr + bl main + mov lr, r8 + + /* Restore U-Boot environment */ + ldr ip, =saved_regs + ldr r8, [ip, #0] + ldr r9, [ip, #4] + mov pc, lr /* * Data for self-relocation, in the text segment for pc-rel access.