Received: by 2002:ac0:b7d5:0:0:0:0:0 with SMTP id v21csp118797ime; Thu, 28 Jul 2022 19:33:27 -0700 (PDT) X-Google-Smtp-Source: AGRyM1vkRI4ao3QOtqWS65f+RzMoTtEX2Onktbq++O35FfGryTEMUTG3zyJ37JnaHBLdrNpG067U X-Received: by 2002:aa7:c843:0:b0:43c:d6f0:7d6e with SMTP id g3-20020aa7c843000000b0043cd6f07d6emr1591442edt.337.1659062007822; Thu, 28 Jul 2022 19:33:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1659062007; cv=none; d=google.com; s=arc-20160816; b=D0Apxk9vykIRY3KQ/CBRBBt8H3bAUftnOjZBS21k4aRVxTEtTZJOAt4aKw8i5EYVEB s/9OJqsvtOr+R3IE1GP9WBQ0KuZTcYIwBenm9galTQBcNp8II3EcTSCuGh561bdbaivH w1pdQCb8SeT7RF6HmO7RNQutxsWG+2op2Sn+SlsZ5I/S5y4V2+edIY4TtiZGyb2kTe5r XhACazDtmUpVNGdfVecvXWzx8cCfXDzjuwXNesjjpsk6MSIZHCoSfHcIpj9pAi1teryd nwIRzGCqg9wGAxWF6cecnvsgK/S48+YeU0TNOzXYc//k0nLy0cvscxGVqbBr6FHpXi6N Ql2w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:in-reply-to :mime-version:user-agent:date:message-id:from:cc:references:to :subject; bh=cH7QZ9c6wCicAgsNn3pPvHPzImJsOyP12gN+O4/EudE=; b=KvS2aw2fkpu/FbUY2KnkUzzyV3ISPxSRnN2YSeTvyfi4CUEJlq/lwpgO7CPvdJHG/6 jIaS1LbpJZv2FillCqi8ndaX0lw6OokSui39yRRUQWtn/aM5U9EwFcK3rofiLggO3lP2 YYNI99eSEbTg5f2HmD2aN0yCJxGfcBtocTHrpqBpQD4UOoZRsLT08mvqpMMwE5l6dFBJ Zln8UWFvoiLAv94FTytEQJdARzWtbuH1hlrI4l0V66H3TG7HDVvNmXt11RM+2eDyZ/zY jFzv0HQZRD+d9ZA9Fc4ufxEC3V+5t3gpgKq4aLCrOFtj3fnGH2Dtvaerq5/3Nkm9J3Iu ZK3A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id p7-20020a1709060dc700b0072b2141a200si69318eji.401.2022.07.28.19.33.02; Thu, 28 Jul 2022 19:33:27 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232907AbiG2COy (ORCPT + 99 others); Thu, 28 Jul 2022 22:14:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37968 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231495AbiG2COx (ORCPT ); Thu, 28 Jul 2022 22:14:53 -0400 Received: from loongson.cn (mail.loongson.cn [114.242.206.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 7FEC67AB0B for ; Thu, 28 Jul 2022 19:14:51 -0700 (PDT) Received: from localhost.localdomain (unknown [111.9.175.10]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9AxGeGUQuNigMdAAA--.27510S3; Fri, 29 Jul 2022 10:14:46 +0800 (CST) Subject: Re: [PATCH 2/3] LoongArch: Add prologue unwinder support To: Qing Zhang , Huacai Chen , WANG Xuerui References: <20220728140519.5420-1-zhangqing@loongson.cn> <20220728140519.5420-2-zhangqing@loongson.cn> Cc: loongarch@lists.linux.dev, linux-kernel@vger.kernel.org, Jiaxun Yang From: Jinyang He Message-ID: Date: Fri, 29 Jul 2022 10:14:44 +0800 User-Agent: Mozilla/5.0 (X11; Linux mips64; rv:45.0) Gecko/20100101 Thunderbird/45.4.0 MIME-Version: 1.0 In-Reply-To: <20220728140519.5420-2-zhangqing@loongson.cn> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-CM-TRANSID: AQAAf9AxGeGUQuNigMdAAA--.27510S3 X-Coremail-Antispam: 1UD129KBjvJXoWxZr4kCF1DAw48Gw1rGFyDJrb_yoWrCrWDpF yDAF93GF4jgr92gr9rXrs8Zr95Grsagr12gF9xJry8CF1DXr93GFnYk34vvan5J3ykG3W8 ZF4FyrW29anrtaDanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUvj14x267AKxVW8JVW5JwAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK02 1l84ACjcxK6xIIjxv20xvE14v26ryj6F1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4U JVWxJr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVCY1x0267AKxV WxJr0_GcWle2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2Wl Yx0E2Ix0cI8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbV WUJVW8JwACjcxG0xvEwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lc7I2V7IY0VAS07Al zVAYIcxG8wCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F4 0E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_JF0_Jw1l IxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxV AFwI0_Jr0_Gr1lIxAIcVCF04k26cxKx2IYs7xG6rW3Jr0E3s1lIxAIcVC2z280aVAFwI0_ Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVWUJVW8JbIYCTnIWIevJa73UjIFyTuYvjfUoO J5UUUUU X-CM-SenderInfo: pkhmx0p1dqwqxorr0wxvrqhubq/ X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,NICE_REPLY_A, SPF_HELO_PASS,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi, Qing, On 07/28/2022 10:05 PM, Qing Zhang wrote: > It unwind the stack frame based on prologue code analyze. > CONFIG_KALLSYMS is needed, at least the address and length > of each function. > > Three stages when we do unwind, > (1)unwind_start(), the prapare of unwinding, fill unwind_state. > (2)unwind_done(), judge whether the unwind process is finished or not. > (3)unwind_next_frame(), unwind the next frame. > > Dividing unwinder helps to add new unwinders in the future, eg: > unwind_frame, unwind_orc .etc > > Signed-off-by: Qing Zhang > > > +static inline bool is_stack_alloc_ins(union loongarch_instruction *ip) > +{ > + /* addi.d $sp, $sp, -imm */ > + return ip->reg2i12_format.opcode == addid_op && > + ip->reg2i12_format.rj == LOONGARCH_GPR_SP && > + ip->reg2i12_format.rd == LOONGARCH_GPR_SP && > + ip->reg2i12_format.immediate & (1 << 11); Checking the sign bit can be used in other place. > +} > + > +static inline bool is_ra_save_ins(union loongarch_instruction *ip) > +{ > + /* st.d $ra, $sp, offset */ > + return ip->reg2i12_format.opcode == std_op && > + ip->reg2i12_format.rj == LOONGARCH_GPR_SP && > + ip->reg2i12_format.rd == LOONGARCH_GPR_RA; > +} > + > +static inline bool is_branch_insn(union loongarch_instruction insn) Does it by using pointer parameter as above functions do. > +{ > + return insn.reg1i21_format.opcode >= beqz_op && > + insn.reg1i21_format.opcode <= bgeu_op; > +} > + > u32 larch_insn_gen_lu32id(enum loongarch_gpr rd, int imm); > u32 larch_insn_gen_lu52id(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm); > u32 larch_insn_gen_jirl(enum loongarch_gpr rd, enum loongarch_gpr rj, unsigned long pc, unsigned long dest); > diff --git a/arch/loongarch/include/asm/unwind.h b/arch/loongarch/include/asm/unwind.h > index 243330b39d0d..09394e536ea9 100644 > --- a/arch/loongarch/include/asm/unwind.h > +++ b/arch/loongarch/include/asm/unwind.h > @@ -14,6 +14,10 @@ > struct unwind_state { > struct stack_info stack_info; > struct task_struct *task; > +#if defined(CONFIG_UNWINDER_PROLOGUE) > + unsigned long ra; > + bool enable; Annotating here is appreciating. Enable is the way of prologue analysis while !enable is the way of guess. > +#endif > unsigned long sp, pc; > bool first; > bool error; [...] > + > +unsigned long unwind_get_return_address(struct unwind_state *state) > +{ > + > + if (unwind_done(state)) > + return 0; > + > + if (state->enable) > + return state->pc; > + else if (state->first) > + return state->pc; Combine conditions. > + > + return *(unsigned long *)(state->sp); > + > +} > +EXPORT_SYMBOL_GPL(unwind_get_return_address); > + > +static bool unwind_by_prologue(struct unwind_state *state) > +{ > + struct stack_info *info = &state->stack_info; > + union loongarch_instruction *ip, *ip_end; > + unsigned long frame_size = 0, frame_ra = -1; > + unsigned long size, offset, pc = state->pc; > + > + if (state->sp >= info->end || state->sp < info->begin) > + return false; > + > + if (!kallsyms_lookup_size_offset(pc, &size, &offset)) > + return false; > + > + ip = (union loongarch_instruction *)(pc - offset); > + ip_end = (union loongarch_instruction *)pc; > + > + while (ip < ip_end) { > + if (is_stack_alloc_ins(ip)) { > + frame_size = (1 << 12) - ip->reg2i12_format.immediate; Due to there will be other place convert unsigned to signed, we have a chance that create a inline function in inst.h. Do it as same as checking the sign bit. > + ip++; > + break; > + } > + ip++; > + } > + [...] > + > + do { > + if (state->enable) { > + if (unwind_by_prologue(state)) > + return true; > + > + if (info->type == STACK_TYPE_IRQ && > + info->end == state->sp) { > + regs = (struct pt_regs *)info->next_sp; > + pc = regs->csr_era; > + if (user_mode(regs) || !__kernel_text_address(pc)) > + return false; > + > + state->pc = pc; > + state->sp = regs->regs[3]; > + state->ra = regs->regs[1]; > + state->first = true; > + get_stack_info(state->sp, state->task, info); > + > + return true; > + } > + } else { > + if (state->first) > + state->first = false; > + > + if (unwind_by_guess(state)) > + return true; > + } I'd prefer separate the block of 'if...else...' into two inline functions, that makes codes clear. Thanks, Jinyang