From patchwork Fri Apr 7 02:59:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Youling Tang X-Patchwork-Id: 67485 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 14EAD3857710 for ; Fri, 7 Apr 2023 03:00:19 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from loongson.cn (mail.loongson.cn [114.242.206.163]) by sourceware.org (Postfix) with ESMTP id F0C613857712 for ; Fri, 7 Apr 2023 03:00:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org F0C613857712 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=loongson.cn Received: from loongson.cn (unknown [113.200.148.30]) by gateway (Coremail) with SMTP id _____8AxJDQ5hy9k2K0XAA--.37467S3; Fri, 07 Apr 2023 11:00:09 +0800 (CST) Received: from bogon.localdomain (unknown [113.200.148.30]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxwOQQhy9kEc0XAA--.59209S6; Fri, 07 Apr 2023 11:00:08 +0800 (CST) From: Youling Tang To: elfutils-devel@sourceware.org, Mark@sourceware.org, Wielaard@sourceware.org, mark@klomp.org Cc: Hengqi Chen , Liwei Ge Subject: [PATCH 4/5] backends: Add frame pointer unwinding for LoongArch Date: Fri, 7 Apr 2023 10:59:27 +0800 Message-Id: <1680836368-5373-5-git-send-email-tangyouling@loongson.cn> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1680836368-5373-1-git-send-email-tangyouling@loongson.cn> References: <1680836368-5373-1-git-send-email-tangyouling@loongson.cn> X-CM-TRANSID: AQAAf8DxwOQQhy9kEc0XAA--.59209S6 X-CM-SenderInfo: 5wdqw5prxox03j6o00pqjv00gofq/ X-Coremail-Antispam: 1Uk129KBjvJXoWxXFyrZr4rCr4rZFyDAw4fKrg_yoW7Jr1fpF WYkr45Gr1kJFW2yas3J345Zrn8Xr93Gr12qF1Sga1xAw15Xa42v347tFyqvFykJayxCFWY vF1vka4UuFyDAFJanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj qI5I8CrVACY4xI64kE6c02F40Ex7xfYxn0WfASr-VFAUDa7-sFnT9fnUUIcSsGvfJTRUUU b7kYFVCjjxCrM7AC8VAFwI0_Jr0_Gr1l1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s 1l1IIY67AEw4v_Jr0_Jr4l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2x7M28EF7xv wVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwA2z4 x0Y4vEx4A2jsIE14v26F4UJVW0owA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_Cr1j6rxdM2AI xVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x26I8E6xACxx1l5I8CrVACY4xI64 kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v26r1q6rW5McIj6I8E87Iv67AKxVW8JVWxJwAm 72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41l42xK82IYc2Ij64vIr41l4I8I3I 0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s026x8GjcxK67AKxVWU GVWUWwC2zVAF1VAY17CE14v26r126r1DMIIYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI 0_Gr0_Xr1lIxAIcVC0I7IYx2IY6xkF7I0E14v26r4j6F4UMIIF0xvE42xK8VAvwI8IcIk0 rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI42IY6I8E87Iv6xkF7I0E14v26r4j6r 4UJbIYCTnIWIevJa73UjIFyTuYvjxU2F4iUUUUU X-Spam-Status: No, score=-12.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , Errors-To: elfutils-devel-bounces+patchwork=sourceware.org@sourceware.org Sender: "Elfutils-devel" If we don't find any debug information for a given frame, we usually cannot unwind any further. However, the binary in question might have been compiled with frame pointers, in which case we can look up the well known frame pointer locations in the stack snapshot and use them to bridge the frames without debug information. Signed-off-by: Liwei Ge Signed-off-by: Youling Tang --- backends/ChangeLog | 6 +++ backends/Makefile.am | 3 +- backends/loongarch_init.c | 1 + backends/loongarch_unwind.c | 84 +++++++++++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 backends/loongarch_unwind.c diff --git a/backends/ChangeLog b/backends/ChangeLog index 40564ca7..ae385fe0 100644 --- a/backends/ChangeLog +++ b/backends/ChangeLog @@ -1,3 +1,9 @@ +2023-04-07 Youling Tang + + * Makefile.am (loongarch_SRCS): Add loongarch_unwind.c. + * loongarch_init.c (loongarch_init): Hook unwind. + * loongarch_unwind.c: New file. + 2023-04-07 Youling Tang * Makefile.am (loongarch_SRCS): Add loongarch_retval.c. diff --git a/backends/Makefile.am b/backends/Makefile.am index 9277ed59..848e520c 100644 --- a/backends/Makefile.am +++ b/backends/Makefile.am @@ -97,7 +97,8 @@ csky_SRCS = csky_attrs.c csky_init.c csky_symbol.c csky_cfi.c \ csky_regs.c csky_initreg.c csky_corenote.c loongarch_SRCS = loongarch_init.c loongarch_symbol.c loongarch_cfi.c \ - loongarch_regs.c loongarch_initreg.c loongarch_retval.c + loongarch_regs.c loongarch_initreg.c loongarch_retval.c \ + loongarch_unwind.c arc_SRCS = arc_init.c arc_symbol.c diff --git a/backends/loongarch_init.c b/backends/loongarch_init.c index 8892a2e6..808ff131 100644 --- a/backends/loongarch_init.c +++ b/backends/loongarch_init.c @@ -55,6 +55,7 @@ loongarch_init (Elf *elf __attribute__ ((unused)), HOOK (eh, check_special_symbol); HOOK (eh, set_initial_registers_tid); HOOK (eh, return_value_location); + HOOK (eh, unwind); return eh; } diff --git a/backends/loongarch_unwind.c b/backends/loongarch_unwind.c new file mode 100644 index 00000000..fb748083 --- /dev/null +++ b/backends/loongarch_unwind.c @@ -0,0 +1,84 @@ +/* Get previous frame state for an existing frame state. + Copyright (C) 2023 OpenAnolis community LoongArch SIG. + Copyright (C) 2023 Loongson Technology Corporation Limited. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at + your option) any later version + + or both in parallel, as here. + + elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define BACKEND loongarch_ +#define RA_REG 1 +#define SP_REG 3 +#define FP_REG 22 + +#define RA_OFFSET 8 +#define FP_OFFSET 16 + +#include "libebl_CPU.h" + +/* There was no CFI. Maybe we happen to have a frame pointer and can unwind from that? */ + +bool +EBLHOOK(unwind) (Ebl *ebl __attribute__ ((unused)), Dwarf_Addr pc __attribute__ ((unused)), + ebl_tid_registers_t *setfunc, ebl_tid_registers_get_t *getfunc, + ebl_pid_memory_read_t *readfunc, void *arg, + bool *signal_framep __attribute__ ((unused))) +{ + Dwarf_Word fp, ra, sp; + + if (!getfunc(RA_REG, 1, &ra, arg)) + return false; + + if (ra == 0 || !setfunc(-1, 1, &ra, arg)) + return false; + + if (!getfunc(FP_REG, 1, &fp, arg)) + fp = 0; + + if (!getfunc(SP_REG, 1, &sp, arg)) + sp = 0; + + Dwarf_Word newRa, newFp, newSp; + + if (!readfunc(fp - RA_OFFSET, &newRa, arg)) + newRa = 0; + + if (!readfunc(fp - FP_OFFSET, &newFp, arg)) + newFp = 0; + + newSp = fp; + + // These are not fatal if they don't work. They will just prevent unwinding at the next frame. + setfunc(RA_REG, 1, &newRa, arg); + setfunc(FP_REG, 1, &newFp, arg); + setfunc(SP_REG, 1, &newSp, arg); + + // If the fp is invalid, we might still have a valid ra. + // But if the fp is valid, then the stack should be moving in the right direction. + return fp == 0 || newSp > sp; +}