aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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))