aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Remus <jremus@linux.ibm.com>2024-03-13 18:03:52 +0100
committerJens Remus <jremus@linux.ibm.com>2024-05-16 13:32:22 +0200
commitffeb79ba9748417b2d586232bd44b8f345ec6524 (patch)
tree9054b4791c3a6934570f10bcc90854d5c1259309
parent4e3cdaa9746d323edc54f87f7b9f3a219735ff6b (diff)
downloadgdb-ffeb79ba9748417b2d586232bd44b8f345ec6524.zip
gdb-ffeb79ba9748417b2d586232bd44b8f345ec6524.tar.gz
gdb-ffeb79ba9748417b2d586232bd44b8f345ec6524.tar.bz2
sframe: Represent FP without RA on stack
If an architecture uses both SFrame RA and FP tracking SFrame assumes that the RA offset is the 2nd offset and the FP offset is the 3rd offset following the SFrame FRE. An architecture does not need to store both on the stack. SFrame cannot represent a FP without RA on stack, since it cannot distinguish whether the 2nd offset is the RA or FP offset. Use an invalid SFrame FRE RA offset value of zero as dummy padding to represent the FP being saved on the stack when the RA is not saved on the stack. include/ * sframe.h (SFRAME_FRE_RA_OFFSET_INVALID): New macro defining the invalid RA offset value used to represent a dummy padding offset. gas/ * gen-sframe.c (get_fre_num_offsets): Accommodate for dummy padding RA offset if FP without RA on stack. (sframe_get_fre_offset_size): Likewise. (output_sframe_row_entry): Write a dummy padding RA offset if FP without RA needs to be represented. libsframe/ * sframe-dump.c (dump_sframe_func_with_fres): Treat invalid RA offsets as if they were undefined. Display them as "u*" to distinguish them. Signed-off-by: Jens Remus <jremus@linux.ibm.com>
-rw-r--r--gas/gen-sframe.c50
-rw-r--r--include/sframe.h9
-rw-r--r--libsframe/sframe-dump.c4
3 files changed, 34 insertions, 29 deletions
diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c
index 0bb7afb..0d7dcc7 100644
--- a/gas/gen-sframe.c
+++ b/gas/gen-sframe.c
@@ -347,7 +347,9 @@ get_fre_num_offsets (struct sframe_row_entry *sframe_fre)
fre_num_offsets++;
#ifdef SFRAME_FRE_RA_TRACKING
if (sframe_ra_tracking_p ()
- && sframe_fre->ra_loc == SFRAME_FRE_ELEM_LOC_STACK)
+ && (sframe_fre->ra_loc == SFRAME_FRE_ELEM_LOC_STACK
+ /* Accommodate for padding RA offset if FP without RA on stack. */
+ || sframe_fre->bp_loc == SFRAME_FRE_ELEM_LOC_STACK))
fre_num_offsets++;
#endif
return fre_num_offsets;
@@ -371,9 +373,14 @@ sframe_get_fre_offset_size (struct sframe_row_entry *sframe_fre)
if (sframe_fre->bp_loc == SFRAME_FRE_ELEM_LOC_STACK)
bp_offset_size = get_offset_size_in_bytes (sframe_fre->bp_offset);
#ifdef SFRAME_FRE_RA_TRACKING
- if (sframe_ra_tracking_p ()
- && sframe_fre->ra_loc == SFRAME_FRE_ELEM_LOC_STACK)
- ra_offset_size = get_offset_size_in_bytes (sframe_fre->ra_offset);
+ if (sframe_ra_tracking_p ())
+ {
+ if (sframe_fre->ra_loc == SFRAME_FRE_ELEM_LOC_STACK)
+ ra_offset_size = get_offset_size_in_bytes (sframe_fre->ra_offset);
+ /* Accommodate for padding RA offset if FP without RA on stack. */
+ else if (sframe_fre->bp_loc == SFRAME_FRE_ELEM_LOC_STACK)
+ ra_offset_size = get_offset_size_in_bytes (SFRAME_FRE_RA_OFFSET_INVALID);
+ }
#endif
/* Get the maximum size needed to represent the offsets. */
@@ -537,11 +544,19 @@ output_sframe_row_entry (symbolS *fde_start_addr,
fre_write_offsets++;
#ifdef SFRAME_FRE_RA_TRACKING
- if (sframe_ra_tracking_p ()
- && sframe_fre->ra_loc == SFRAME_FRE_ELEM_LOC_STACK)
+ if (sframe_ra_tracking_p ())
{
- fre_offset_func_map[idx].out_func (sframe_fre->ra_offset);
- fre_write_offsets++;
+ if (sframe_fre->ra_loc == SFRAME_FRE_ELEM_LOC_STACK)
+ {
+ fre_offset_func_map[idx].out_func (sframe_fre->ra_offset);
+ fre_write_offsets++;
+ }
+ /* Write padding RA offset if FP without RA on stack. */
+ else if (sframe_fre->bp_loc == SFRAME_FRE_ELEM_LOC_STACK)
+ {
+ fre_offset_func_map[idx].out_func (SFRAME_FRE_RA_OFFSET_INVALID);
+ fre_write_offsets++;
+ }
}
#endif
if (sframe_fre->bp_loc == SFRAME_FRE_ELEM_LOC_STACK)
@@ -1499,25 +1514,6 @@ 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;
}
diff --git a/include/sframe.h b/include/sframe.h
index 90bc92a..d1a2687 100644
--- a/include/sframe.h
+++ b/include/sframe.h
@@ -237,6 +237,9 @@ typedef struct sframe_func_desc_entry
may or may not be tracked. */
#define SFRAME_FRE_FP_OFFSET_IDX 2
+/* Invalid RA offset. Used as padding to represent FP without RA on stack. */
+#define SFRAME_FRE_RA_OFFSET_INVALID 0
+
typedef struct sframe_fre_info
{
/* Information about
@@ -288,9 +291,11 @@ typedef struct sframe_fre_info
offset1 (interpreted as CFA = BASE_REG + offset1)
if RA is being tracked
- offset2 (interpreted as RA = CFA + offset2)
+ offset2 (interpreted as RA = CFA + offset2; an offset value of
+ SFRAME_FRE_RA_OFFSET_INVALID indicates a dummy padding RA offset
+ to represent FP without RA saved on stack)
if FP is being tracked
- offset3 (intrepreted as FP = CFA + offset2)
+ offset3 (intrepreted as FP = CFA + offset3)
fi
else
if FP is being tracked
diff --git a/libsframe/sframe-dump.c b/libsframe/sframe-dump.c
index 40ea531..3ea4bc3 100644
--- a/libsframe/sframe-dump.c
+++ b/libsframe/sframe-dump.c
@@ -199,6 +199,10 @@ dump_sframe_func_with_fres (sframe_decoder_ctx *sfd_ctx,
if (sframe_decoder_get_fixed_ra_offset (sfd_ctx)
!= SFRAME_CFA_FIXED_RA_INVALID)
strcpy (temp, "f");
+ /* If an ABI does track RA offset, e.g. AArch64 and S390, it can be a
+ dummy as padding to represent FP without RA being saved on stack. */
+ else if (err[2] == 0 && ra_offset == SFRAME_FRE_RA_OFFSET_INVALID)
+ sprintf (temp, "u*");
else if (err[2] == 0)
{
if (is_sframe_abi_arch_s390 (sfd_ctx) && (ra_offset & 1))