From patchwork Mon Nov 26 17:28:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Buclaw X-Patchwork-Id: 1003342 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-490891-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gdcproject.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="hUmzJge1"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 433Yms5l1Fz9ryk for ; Tue, 27 Nov 2018 04:29:01 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:content-type; q= dns; s=default; b=g4CGo5gDO9Yl8PhJyDXWXRxUz/vxQO+a/Le2AKjM3g+nWv KEramk/QsStHcB7SbzHF51KE+zpeVTdranTtTRv1SMjAlYwFDHjWX/4LY20kZW0/ 6UrgUCJkg/r99G3jzXGyuvFxWaIhETi9nitDgs8Kibrbo5f6xST6CZSS85nvE= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:content-type; s= default; bh=nVLNdWHdsNMkNl/7VoFA6MDw0NQ=; b=hUmzJge1cquOJ01Vxzrs WwRK60XmjTpKUmyf6iOum0JSc4CZknNitg5AtbuUeqZbI09WnR58BTAwlLApP7bl wEud2uSwt++FL4uzTiUWo0xc1yVb60vVIsbk4Dd9doYqKTfe5Pzhv+ngD3qXm3hh 6bLiM+l2m7P8iovqI582Eyk= Received: (qmail 63366 invoked by alias); 26 Nov 2018 17:28:55 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 63351 invoked by uid 89); 26 Nov 2018 17:28:54 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.4 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_NUMSUBJECT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=saved, cfi_endproc, cfi_startproc, continuation X-HELO: mail-qt1-f172.google.com Received: from mail-qt1-f172.google.com (HELO mail-qt1-f172.google.com) (209.85.160.172) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 26 Nov 2018 17:28:52 +0000 Received: by mail-qt1-f172.google.com with SMTP id l11so18518823qtp.0 for ; Mon, 26 Nov 2018 09:28:52 -0800 (PST) MIME-Version: 1.0 From: Iain Buclaw Date: Mon, 26 Nov 2018 18:28:39 +0100 Message-ID: Subject: [PATCH, libphobos] Committed fix backtraces in Fibers on AArch64 To: gcc-patches X-IsSubscribed: yes Hi, This patch is backported from druntime 2.083, in continuation of finishing off AArch64 library support. When throwing an Exception in the Fiber the backtrace generation crashes. This happens because backtrace does not func the stack bottom. Using '.cfi_undefined x30' tells the debug info that the value in the lr is unknown, which seems to be the nicest way to stop the unwinder. Setting x30 to 0 is another option, however it still creates one invalid frame in gdb, so the .cfi variant is used here instead. Bootstrapped and tested on aarch64-linux-gnu. Committed to trunk as r266470. diff --git a/libphobos/libdruntime/core/thread.d b/libphobos/libdruntime/core/thread.d index b5244711646..ff15d066a49 100644 --- a/libphobos/libdruntime/core/thread.d +++ b/libphobos/libdruntime/core/thread.d @@ -3582,6 +3582,15 @@ private version = AsmExternal; } } + else version (AArch64) + { + version (Posix) + { + version = AsmAArch64_Posix; + version = AsmExternal; + version = AlignFiberStackTo16Byte; + } + } else version (ARM) { version (Posix) @@ -3673,7 +3682,11 @@ private // Look above the definition of 'class Fiber' for some information about the implementation of this routine version (AsmExternal) - extern (C) void fiber_switchContext( void** oldp, void* newp ) nothrow @nogc; + { + extern (C) void fiber_switchContext( void** oldp, void* newp ) nothrow @nogc; + version (AArch64) + extern (C) void fiber_trampoline() nothrow; + } else extern (C) void fiber_switchContext( void** oldp, void* newp ) nothrow @nogc { @@ -4909,6 +4922,29 @@ private: pstack -= ABOVE; *cast(size_t*)(pstack - SZ_RA) = cast(size_t)&fiber_entryPoint; } + else version (AsmAArch64_Posix) + { + // Like others, FP registers and return address (lr) are kept + // below the saved stack top (tstack) to hide from GC scanning. + // fiber_switchContext expects newp sp to look like this: + // 19: x19 + // ... + // 9: x29 (fp) <-- newp tstack + // 8: x30 (lr) [&fiber_entryPoint] + // 7: d8 + // ... + // 0: d15 + + version (StackGrowsDown) {} + else + static assert(false, "Only full descending stacks supported on AArch64"); + + // Only need to set return address (lr). Everything else is fine + // zero initialized. + pstack -= size_t.sizeof * 11; // skip past x19-x29 + push(cast(size_t) &fiber_trampoline); // see threadasm.S for docs + pstack += size_t.sizeof; // adjust sp (newp) above lr + } else version (AsmARM_Posix) { /* We keep the FP registers and the return address below diff --git a/libphobos/libdruntime/core/threadasm.S b/libphobos/libdruntime/core/threadasm.S index 02bd756de3c..140e5f9a9e4 100644 --- a/libphobos/libdruntime/core/threadasm.S +++ b/libphobos/libdruntime/core/threadasm.S @@ -487,6 +487,7 @@ fiber_switchContext: */ .text .global CSYM(fiber_switchContext) + .type fiber_switchContext, %function .p2align 2 CSYM(fiber_switchContext): stp d15, d14, [sp, #-20*8]! @@ -518,6 +519,29 @@ CSYM(fiber_switchContext): ldp d15, d14, [sp], #20*8 ret + +/** + * When generating any kind of backtrace (gdb, exception handling) for + * a function called in a Fiber, we need to tell the unwinder to stop + * at our Fiber main entry point, i.e. we need to mark the bottom of + * the call stack. This can be done by clearing the link register lr + * prior to calling fiber_entryPoint (i.e. in fiber_switchContext) or + * using a .cfi_undefined directive for the link register in the + * Fiber entry point. cfi_undefined seems to yield better results in gdb. + * Unfortunately we can't place it into fiber_entryPoint using inline + * asm, so we use this trampoline instead. + */ + .text + .global CSYM(fiber_trampoline) + .p2align 2 + .type fiber_trampoline, %function +CSYM(fiber_trampoline): + .cfi_startproc + .cfi_undefined x30 + // fiber_entryPoint never returns + bl fiber_entryPoint + .cfi_endproc + #elif defined(__MINGW32__) /************************************************************************************ * GDC MinGW ASM BITS