aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Remus <jremus@linux.ibm.com>2024-03-07 14:34:21 +0100
committerJens Remus <jremus@linux.ibm.com>2024-05-16 13:32:22 +0200
commit9e13b3122b1c60aa3fc3f60993c18daf2e6f282a (patch)
treebdb231596186e0defc8fb11753ebc8b29b573212
parent1efbe98fca238d9620bbeda5d0f5cb07ec6ce28b (diff)
downloadbinutils-9e13b3122b1c60aa3fc3f60993c18daf2e6f282a.zip
binutils-9e13b3122b1c60aa3fc3f60993c18daf2e6f282a.tar.gz
binutils-9e13b3122b1c60aa3fc3f60993c18daf2e6f282a.tar.bz2
gas: Skip SFrame FDE if FP without RA on stack
The SFrame format cannot represent the frame pointer (FP) being saved on the stack without the return address (RA) also being saved on the stack, if RA tracking is used. A SFrame FDE is followed by 1-3 offsets with the following information: Without RA tracking: 1. Offset from base pointer (SP or FP) to locate the CFA 2. Optional: Offset to CFA to restore the frame pointer (FP) With RA tracking: 1. Offset from base pointer (SP or FP) to locate the CFA 2. Optional: Offset to CFA to restore the return address (RA) 3. Optional: Offset to CFA to restore the frame pointer (FP) When RA tracking is used and a FDE is followed by two offsets the SFrame format does not provide any information to distinguish whether the second offset is the RA or FP offset. SFrame assumes the offset to be the RA offset, which may be wrong. Therefore skip generation of SFrame FDE information and print the following warning, if RA tracking is used and the FP is saved on the stack without the RA being saved as well: skipping SFrame FDE due to FP without RA on stack gas/ * gen-sframe.c (sframe_do_fde): Skip SFrame FDE if FP without RA on stack, as the SFrame format cannot represent this case. Signed-off-by: Jens Remus <jremus@linux.ibm.com>
-rw-r--r--gas/gen-sframe.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c
index 9a1773b..9fe62c2 100644
--- a/gas/gen-sframe.c
+++ b/gas/gen-sframe.c
@@ -1441,6 +1441,25 @@ sframe_do_fde (struct sframe_xlate_ctx *xlate_ctx,
= get_dw_fde_end_addrS (xlate_ctx->dw_fde);
}
+#ifdef SFRAME_FRE_RA_TRACKING
+ if (sframe_ra_tracking_p ())
+ {
+ struct sframe_row_entry *fre;
+
+ /* Iterate over the scratchpad FREs and validate them. */
+ for (fre = xlate_ctx->first_fre; fre; fre = fre->next)
+ {
+ /* SFrame format cannot represent FP on stack without RA on stack. */
+ if (fre->ra_loc != SFRAME_FRE_ELEM_LOC_STACK
+ && fre->bp_loc == SFRAME_FRE_ELEM_LOC_STACK)
+ {
+ as_warn (_("skipping SFrame FDE due to FP without RA on stack"));
+ return SFRAME_XLATE_ERR_NOTREPRESENTED;
+ }
+ }
+ }
+#endif /* SFRAME_FRE_RA_TRACKING */
+
return SFRAME_XLATE_OK;
}