From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) by sourceware.org (Postfix) with ESMTPS id 595A4384AB7E for ; Fri, 19 Apr 2024 13:13:24 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 595A4384AB7E Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linux.ibm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 595A4384AB7E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1713532408; cv=none; b=YYONWrVW369O+urN3x6+OVLVDZhQCDLLDTBHqJNocIeY1BzApj6juN1Tr66xZ1IwBzpNCbaPEx4zluX74HMABj7XBGmU2ZtCOtzh8Fx7UB8S+xZ1NiJZBQVNYb//6SsqWOSi4V5NvPRtSr1WgquQKh5ywIuL0LpVEu6q1rIDPU4= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1713532408; c=relaxed/simple; bh=j2twli17UvvpC5+rnfnbqLxbc4sCMCt+9of80fB3EIY=; h=DKIM-Signature:Message-ID:Date:Subject:To:From:MIME-Version; b=utq6NESo2dUZocljxd8iHuWdy77RM1P5eoZCs1UH+r1BbXMuNDml9cIAj79zUtHWc/5ooT5mtZUcIs6dR4kOnXxpW1J3IXnxx5erGrKqRGQOcNRXYn9bWd4G+crv72lPDAgMb/o/u1kOPGjcXGJmGDpftf220rnTYwSh4nu1++g= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from pps.filterd (m0360083.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 43JCRNnl028992; Fri, 19 Apr 2024 13:13:21 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=message-id : date : subject : to : cc : references : from : in-reply-to : content-type : content-transfer-encoding : mime-version; s=pp1; bh=ZWDcBSyd/IFRZAXStHprUcuht4rfuVAJ/dYCUiPueCo=; b=dX6XTyTfnrNrwh2NBPO+f7ukaa0ruFDG7iKK4Ks2E4Kv2IBzfGr/FFIaKVMJCTH5VfVL 75a1hfLgXdIsEBEf1aNXlP0ZfsAUn1VqDr+9xXilBK2fMudi3m/5kDMHCwnkqgZIndIF yDzzTGN+QD94N01V4l3PG/YmFNVLPYnbiW2H5wy2s5EGq6ExqdItOOGTGJ3kGDmbB2Ns jD1ISSlDeiCjkyeRkikCBevNnQj1+SWVq0eCsXVx9+3173DZ2f9UX80TtxLKL3HdTqjy tllv+vFsohR9hgzOYPUNPf9nmtVhSplQU0nj9lLQB1GgAOkQzqpzfS6/legI7qKD9SQ/ Ag== Received: from ppma12.dal12v.mail.ibm.com (dc.9e.1632.ip4.static.sl-reverse.com [50.22.158.220]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3xkrmj0414-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 19 Apr 2024 13:13:20 +0000 Received: from pps.filterd (ppma12.dal12v.mail.ibm.com [127.0.0.1]) by ppma12.dal12v.mail.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 43JCL3tj030284; Fri, 19 Apr 2024 13:13:19 GMT Received: from smtprelay02.fra02v.mail.ibm.com ([9.218.2.226]) by ppma12.dal12v.mail.ibm.com (PPS) with ESMTPS id 3xkbmckrbm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 19 Apr 2024 13:13:19 +0000 Received: from smtpav03.fra02v.mail.ibm.com (smtpav03.fra02v.mail.ibm.com [10.20.54.102]) by smtprelay02.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 43JDDE5035586360 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 19 Apr 2024 13:13:16 GMT Received: from smtpav03.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6B0BB20043; Fri, 19 Apr 2024 13:13:14 +0000 (GMT) Received: from smtpav03.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 0804F20040; Fri, 19 Apr 2024 13:13:14 +0000 (GMT) Received: from [9.171.19.94] (unknown [9.171.19.94]) by smtpav03.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 19 Apr 2024 13:13:13 +0000 (GMT) Message-ID: <1e518650-2d11-4a28-a3b7-de94a32582b1@linux.ibm.com> Date: Fri, 19 Apr 2024 15:13:12 +0200 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v3 13/15] gas: Don't skip SFrame FDE if .cfi_register specifies SP register To: Indu Bhagat , binutils@sourceware.org Cc: Andreas Krebbel References: <20240412144718.4191286-1-jremus@linux.ibm.com> <20240412144718.4191286-14-jremus@linux.ibm.com> From: Jens Remus Content-Language: en-US Organization: IBM Deutschland Research & Development GmbH In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: yGU8Vrmweu8_X-cqmWtZe86UbMmqgSlR X-Proofpoint-GUID: yGU8Vrmweu8_X-cqmWtZe86UbMmqgSlR Content-Transfer-Encoding: 8bit X-Proofpoint-UnRewURL: 0 URL was un-rewritten MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-04-19_09,2024-04-19_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxlogscore=999 adultscore=0 bulkscore=0 impostorscore=0 malwarescore=0 spamscore=0 suspectscore=0 clxscore=1015 mlxscore=0 phishscore=0 priorityscore=1501 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2404010000 definitions=main-2404190099 X-Spam-Status: No, score=-11.1 required=5.0 tests=BAYES_00,BODY_8BITS,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,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 List-Id: Am 18.04.2024 um 22:37 schrieb Indu Bhagat: > On 4/12/24 07:47, Jens Remus wrote: >> The stack-pointer (SP) register contents on entry can be reconstructed >> from the CFA base register tracking information from the current SFrame >> FRE and initial FRE from the FDE: >> >> 1. Compute CFA from the current CFA base register (SP or FP) and CFA >>     offset from the SFrame CFA base register tracking information from >>     the SFrame FRE for the current instruction address: >> >>       CFA = + >> >> 2. Compute SP from the current CFA and the CFA offset from the SFrame >>     CFA tracking information from the initial SFrame FRE of the FDE: >> >>       SP = CFA - >> >> While at it add a comment to the processing of .cfi_val_offset that the >> SP can be reconstructed from the CFA base register tracking information. >> > > Sorry, but I am not sure I follow.  Yes, SP can be reconstructed using > the means you outline, but so can FP.  And also RA when applicable. > > In other words, I dont follow why treat SP differently from FP / RA when > it comes to .cfi_register (or even .cfi_val_offset) for reporting the > warning. > I did not find any explanation how unwinding using SFrame is exactly expected to be performed. Following is how I assume it to work in general and on s390x specifically. Details of how to restore the stack pointer register value at the call site are probably architecture specific. 1. Use the program counter (PC) or subsequently return address (RA) as address to do a binary search through the SFrame FDEs to determine the FDE for the current function. Binary search can be used, as the FDEs are of fixed size. 2. Note/print the function start address taken from the FDE or lookup its symbol for the stack trace. 3. Do a linear search through the SFrame FREs associated with the FDE to determine the FRE for the address within the function. Linear search must be used, since the FREs are of different size and different numbers of offsets may follow each. 3. Unwind the stack-pointer (SP), frame-pointer (FP), and return- address (RA) register values at function entry: - SP: Since SFrame does not track the SP register, the mean to restore its contents at entry to the function must be to use the SFrame CFA trackig information from the current FRE and initial FRE of the function/FDE to restore the SP value: CFA = + SP = CFA - NOTE: Above does not restore the SP value from the stack, as SFrame does not know whether and where it would be saved. Instead it computes the SP value. The use of both the current and initial CFA offsets is valid, as the DWARF standard mandates the CFA to be fixed for a function: "The algorithm to compute CFA changes as you progress through the prologue and epilogue code. (__By definition, the CFA value does not change.__)" - FP: Without SFrame FP tracking use the fixed FP offset as follows. With FP tacking (currently the default), if available use the FP offset to recover the FP value as follows, otherwise the FP value is still in the FP register. CFA = + FP = [CFA + FP-offset] NOTE: Above restores the FP value from the stack. - RA: Without SFrame RA tracking use the fixed RA offset as follows. With RA tracking (depending on architecture), if available use the RA offset to recover the RA value as follows, otherwise the RA value is still in the RA register. CFA = + RA = [CFA + RA-offset] NOTE: Same as for FP. 4. Unwind the SP register value at the call site. This step be merged with the previous one. On s390x the value of the stack pointer on entry to a function is identical to the value of the stack pointer at the call site. Thus nothing has to be done. Note that on s390x the CFA is not defined to be the value of the stack pointer at the call site, as it is for other architectures. Instead it is usually defined as the upper bound (exclusive) of the current stack frame. This is valid as the DWARF standard does not mandate the CFA to be defined as the value of the SP at the call site. "__Typically__, the CFA is defined to be the value of the stack pointer at the call site in the previous frame (which may be different from its value on entry to the current frame)." On x86-64 the SP at the call site can be determined using a fixed offset, or SP = CFA can be used, if the CFA is defined as the SP value at the call site on x86-64. 5. Repeat at step 1 using the RA value as address to perform the next FDE lookup. With that to your question why I assume it would be acceptable to treat SP different from FP and RA when it comes to .cfi_offset, .cfi_val_offset, and .cfi_register: On s390x, and I assume this to apply to all other architectures, the SP value on function entry and from that also at the call site can always be restored using above steps. It is irrelevant whether the SP value on function entry is saved on the stack (.cfi_offset), in another register (.cfi_register), or is defined as offset from CFA (.cfi_val_offset). Actually the SP is inherently defined as an offset from the CFA that can be deducted from the CFA tracking information (see above). An exception would be if a compiler would generate code that defines a non-SP register as CFA base register on function entry. I have not observed that on s390x. Regarding the aforementioned CFI directives I observed the following on s390x: The SP register value is saved on the stack in the function prologue and restored in the epilogue, when allocating stack space of fixed size for local variables. The compiler generates respective .cfi_offset , ... and .cfi_restore CFI directives. Note that the compiler could alternatively use arithmetic instructions to restore the initial SP value. Due to the availability of Load/Store Multiple instructions those are generally preferred. An unwinder using .eh_frame information would most likely use the .cfi_offset information for the SP register. An unwinder using .sframe information would instead need to perform above mentioned computations, as SFrame does not track the SP register. As for the .cfi_val_offset , ... instances in glibc it is similar. An unwinder using .eh_frame information would use the .cfi_val_offset information. An unwinder using .sframe information would instead again need to perform above mentioned computations. Does that make sense? If I have missed something, then SFrame generation would probably need to skip FDE when the SP register is specified in .cfi_offset (new), .cfi_register, and .cfi_val_offset, no? Btw., besides the RFC Linux Kernel perf patch series "[PATCH RFC 00/10] perf: user space sframe unwinding" [1] is there any reference implementation of a SFrame unwinder I could use as base for testing SFrame unwinding on s390x? Maybe a GDB Python script to do unwinding using SFrame (not sure how to access the .sframe section)? [1] [PATCH RFC 00/10] perf: user space sframe unwinding, https://lore.kernel.org/all/cover.1699487758.git.jpoimboe@kernel.org/ >> gas/ >>     * gen-sframe.c (sframe_xlate_do_register): Do not skip SFrame >>     FDE if .cfi_register specifies SP register. >>     (sframe_xlate_do_val_offset): Add comment that this is likewise. >> >> Signed-off-by: Jens Remus >> --- >> >> Notes (jremus): >>      Changes v2 -> v3: >>      - New patch. >> >>   gas/gen-sframe.c | 8 +++++--- >>   1 file changed, 5 insertions(+), 3 deletions(-) >> >> diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c >> index 61c846f214ee..12b523a8d59a 100644 >> --- a/gas/gen-sframe.c >> +++ b/gas/gen-sframe.c >> @@ -1136,6 +1136,7 @@ sframe_xlate_do_val_offset (struct >> sframe_xlate_ctx *xlate_ctx ATTRIBUTE_UNUSED, >>   #ifdef SFRAME_FRE_RA_TRACKING >>         || (sframe_ra_tracking_p () && cfi_insn->u.r == >> SFRAME_CFA_RA_REG) >>   #endif >> +      /* Ignore SP reg, as it can be recovered from the CFA tracking >> info.  */ >>         ) >>       { >>         as_warn (_("skipping SFrame FDE due to .cfi_val_offset >> specifying %s register"), >> @@ -1155,14 +1156,15 @@ sframe_xlate_do_register (struct >> sframe_xlate_ctx *xlate_ctx ATTRIBUTE_UNUSED, >>                 struct cfi_insn_data *cfi_insn) >>   { >>     /* Previous value of register1 is register2.  However, if the >> specified >> -     register1 is not interesting (SP, FP, or RA reg), the current >> DW_CFA_register >> +     register1 is not interesting (FP or RA reg), the current >> DW_CFA_register >>        instruction can be safely skipped without sacrificing the >> asynchronicity of >>        stack trace information.  */ >> -  if (cfi_insn->u.rr.reg1 == SFRAME_CFA_SP_REG >> +  if (cfi_insn->u.rr.reg1 == SFRAME_CFA_FP_REG >>   #ifdef SFRAME_FRE_RA_TRACKING >>         || (sframe_ra_tracking_p () && cfi_insn->u.rr.reg1 == >> SFRAME_CFA_RA_REG) >>   #endif >> -      || cfi_insn->u.rr.reg1 == SFRAME_CFA_FP_REG) >> +      /* Ignore SP reg, as it can be recovered from the CFA tracking >> info.  */ >> +      ) >>       { >>         as_warn (_("skipping SFrame FDE due to .cfi_register >> specifying %s register"), >>              sframe_register_name (cfi_insn->u.rr.reg1)); > Thanks and regards, Jens -- Jens Remus Linux on Z Development (D3303) and z/VSE Support +49-7031-16-1128 Office jremus@de.ibm.com IBM IBM Deutschland Research & Development GmbH; Vorsitzender des Aufsichtsrats: Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der Gesellschaft: Böblingen; Registergericht: Amtsgericht Stuttgart, HRB 243294 IBM Data Privacy Statement: https://www.ibm.com/privacy/