From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-io0-x229.google.com (mail-io0-x229.google.com [IPv6:2607:f8b0:4001:c06::229]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id D7FB381F6F for ; Thu, 8 Dec 2016 06:32:09 -0800 (PST) Received: by mail-io0-x229.google.com with SMTP id d9so3886770ioe.0 for ; Thu, 08 Dec 2016 06:32:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=zjn/SI7nmM0dGS5Xn2qn33gzN9Dwc+90fWQfAU6jHIo=; b=W0oJ0pZHdPUDOQbupOxTTayhh8HLDFedVe+D1ah0P175sIMj7TEAW8HFib+ez/jmvv W3MEqKk8YWZ72q8yo3P107uAXP+gbBuFxOIdKs01mgPlY8Rz2fkmhxG+no5Aao4sP4Hc QIiNbDgJ9qdTszcnX/poqLrTR8ev8yVEaGvjI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=zjn/SI7nmM0dGS5Xn2qn33gzN9Dwc+90fWQfAU6jHIo=; b=G6kWZT4pNb0e4sp46VKarbgk5/ZTzYHGPziDHb0TwzdykXCl4nd51enXi9RtM7UeaR 56pIeATTf0ZYq6e07W8bqmj+Ehy5R9SYkD/aq7gR5j6kcJbJb2Zl9DkLkKPrvgssPo6b yvJqmGnE8JYFZppRyiZYP4NVOEwrNhfPSsedykfxHHv39dhXg1/0a9+/IutQAs5BcHkg 2UbtqG73TZBI0921n0jk3IrXljw9JUti0+Zz1gOOSmkxrpTHCg0GZo5mA0anGZg4XPEH kZ3TTvTMUJzfM3opTGH1S391KGn02U+MIZ84R/iAzw+zgfeh8tDgFkP2ouZew3AYIh+P oLSQ== X-Gm-Message-State: AKaTC01yIwQLV+9NgDVZ5+IekzJVKVWWmi60xnHG15kACkgpmWYwtKLqYojVnThtfmNyGA2/orKFWIfI43oXdlWn X-Received: by 10.107.25.204 with SMTP id 195mr59219638ioz.138.1481207526720; Thu, 08 Dec 2016 06:32:06 -0800 (PST) MIME-Version: 1.0 Received: by 10.107.198.67 with HTTP; Thu, 8 Dec 2016 06:32:06 -0800 (PST) In-Reply-To: References: From: Ard Biesheuvel Date: Thu, 8 Dec 2016 14:32:06 +0000 Message-ID: To: Michael Zimmermann , "Gao, Liming" , "Zhu, Yonghong" , "Shi, Steven" Cc: "edk2-devel@lists.01.org" Subject: Re: GCC needs __attribute__((returns_twice)) for SetJump X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 08 Dec 2016 14:32:10 -0000 Content-Type: text/plain; charset=UTF-8 On 8 December 2016 at 13:30, Michael Zimmermann wrote: > When compiling with any ARM toolchain and Os, registers can get > trashed when returning for the second time from SetJump because GCC > only handles this correctly when using standard names like 'setjmp' or > 'getcontext'. When different names are used you have to use the > attribute 'returns_twice' to tell gcc to be extra careful. > > example: > #define FN_NAME nonstandard_setjmp > extern int FN_NAME(void*); > > void jmp_buf_set(void *jmpb, void (*f)(void)) > { > if (!FN_NAME(jmpb)) > f(); > } > > this code produces this wrong code with Os: > 00000000 : > 0: e92d4010 push {r4, lr} > 4: e1a04001 mov r4, r1 > 8: ebfffffe bl 0 > c: e3500000 cmp r0, #0 > 10: 01a03004 moveq r3, r4 > 14: 08bd4010 popeq {r4, lr} > 18: 012fff13 bxeq r3 > 1c: e8bd4010 pop {r4, lr} > 20: e12fff1e bx lr > > The generated code pushes backups of r4 and lr to the stack and then > saves all registers using nonstandard_setjmp. > Then it pops the stack and jumps to the function in r3 which is the > main problem because now the function can overwrite our register > backups on the stack. > When we return a second time from the call to nonstandard_setjmp, the > stack pointer has it's original(pushed) position and when the code > pops r4 and lr from the stack the values are not guaranteed to be the > same. > > When using a standard name like setjmp or getcontext or adding > '__attribute__((returns_twice))' to nonstandard_setjmp's declaration > the code looks different: > > 00000000 : > 0: e92d4007 push {r0, r1, r2, lr} > 4: e58d1004 str r1, [sp, #4] > 8: ebfffffe bl 0 > c: e3500000 cmp r0, #0 > 10: 059d3004 ldreq r3, [sp, #4] > 14: 01a0e00f moveq lr, pc > 18: 012fff13 bxeq r3 > 1c: e28dd00c add sp, sp, #12 > 20: e49de004 pop {lr} ; (ldr lr, [sp], #4) > 24: e12fff1e bx lr > > Here the problem is being solved by restoring r3 from the stack > without popping it. > > I would have sent a patch but since there's no define for > 'returns_twice' yet and I don't know how other compilers handle this I > want to discuss this first. > Well spotted! This issue applies to all GCC supported architectures, not just ARM, and so I think we need to solve this generically. I have no idea how other toolchains deal with this, although I assume Clang will support the same attribute