mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 12:34:43 +00:00
gas: sframe: Represent .cfi_undefined RA as FRE without offsets
In DWARF CFI an "undefined" register rule for the return address (RA) register indicates that there is no return address and the stack trace is complete. Represent DW_CFA_undefined as SFrame FRE without any offsets, so that a stack tracer implementation can use this as indication that an outermost frame has been reached and the stack trace is complete. This representation is backward compatible, as existing stack tracers should already deal with the case, that an SFrame FRE a so far invalid offset count of zero and stop the trace. include/ * sframe.h (SFRAME_V2_FRE_RA_UNDEFINED_P): New macro to test FRE info word for RA undefined (FRE without any offsets). binutils/ * NEWS: Mention SFrame can represent an undefined RA as FRE without any offsets. gas/ * gen-sframe.h (struct sframe_row_entry): Add ra_undefined_p flag. * gen-sframe.c (sframe_row_entry_new): Initialize ra_undefined_p flag to not set. (sframe_row_entry_initialize): Treat ra_undefined_p flag as sticky. (sframe_fre_set_ra_track): Reset ra_undefined_p flag. (sframe_xlate_do_restore): Reset ra_undefined_p flag to saved state. (sframe_xlate_do_same_value): Reset ra_undefined_p flag. (sframe_xlate_do_cfi_undefined): For RA set ra_undefined_p flag. (output_sframe_row_entry): Represent RA undefined as SFrame FRE without any offsets and FRE info word fields zeroed. * NEWS: Mention assembler represents .cfi_undefined RA in SFrame as FRE without any offsets. libsframe/ * doc/sframe-spec.texi (Changes from Version 1 to Version 2): Mention that a SFrame FRE without any offsets flag indicates an outermost frame with an undefined RA. (fre_offset_count): Document that a FRE offset count of zero indicates an outermost frame with an undefined RA. * sframe.c (sframe_get_fre_ra_undefined_p): Use macro SFRAME_V2_FRE_RA_UNDEFINED_P. (sframe_fre_get_fp_offset, sframe_fre_get_ra_offset): Do not return fixed FP/RA offset if RA undefined. * sframe-dump.c (dump_sframe_func_with_fres): Show FRE without any offsets as "RA undefined". gas/testsuite/ * gas/cfi-sframe/cfi-sframe.exp: Run tests for .cfi_undefined RA on AArch64, s390x, and x86-64. * gas/cfi-sframe/cfi-sframe-aarch64-ra-undefined-1.d: Add test for .cfi_undefined RA on AArch64. * gas/cfi-sframe/cfi-sframe-aarch64-ra-undefined-1.s: Likewise. * as/cfi-sframe/cfi-sframe-s390x-ra-undefined-1.d: Add test for .cfi_undefined RA on s390x. * gas/cfi-sframe/cfi-sframe-s390x-ra-undefined-1.s: Likewise. * gas/cfi-sframe/cfi-sframe-x86_64-ra-undefined-1.d: Add test for .cfi_undefined RA on x86-64. * gas/cfi-sframe/cfi-sframe-x86_64-ra-undefined-1.s: Likewise. Signed-off-by: Jens Remus <jremus@linux.ibm.com>
This commit is contained in:
@@ -171,6 +171,11 @@ by CFA offset alignment factor and then revert CFA offset adjustment).
|
||||
@end itemize
|
||||
@item
|
||||
[Errata 1] An ELF SFrame section has the type SHT_GNU_SFRAME.
|
||||
@item
|
||||
[Errata 2] An SFrame FRE info word offset count of zero indicates that the
|
||||
return address (RA) is undefined for the range of PCs covered by the SFrame FRE.
|
||||
A stack tracer may use this as indication that an outermost frame has been
|
||||
reached and the stack trace is complete.
|
||||
@end itemize
|
||||
|
||||
SFrame version 1 is now obsolete and should not be used.
|
||||
@@ -777,7 +782,10 @@ SFRAME_FRE_OFFSET_4B.
|
||||
@item 1-4
|
||||
@tab @code{fre_offset_count}
|
||||
@tab A max value of 15 is allowed. Typically, a value of upto 3 is sufficient
|
||||
for most ABIs to track all three of CFA, FP and RA.
|
||||
for most ABIs to track all three of CFA, FP and RA. A value of zero indicates
|
||||
that the return address (RA) is undefined. A stack tracer may use this as
|
||||
indication that an outermost frame has been reached and the stack trace is
|
||||
complete.
|
||||
|
||||
@item 0
|
||||
@tab @code{fre_cfa_base_reg_id}
|
||||
|
||||
@@ -130,6 +130,7 @@ dump_sframe_func_with_fres (sframe_decoder_ctx *sfd_ctx,
|
||||
uint64_t func_start_pc_vma = 0;
|
||||
uint64_t fre_start_pc_vma = 0;
|
||||
const char *base_reg_str[] = {"fp", "sp"};
|
||||
bool ra_undefined_p = false;
|
||||
int32_t cfa_offset = 0;
|
||||
int32_t fp_offset = 0;
|
||||
int32_t ra_offset = 0;
|
||||
@@ -180,15 +181,25 @@ dump_sframe_func_with_fres (sframe_decoder_ctx *sfd_ctx,
|
||||
: func_start_pc_vma + fre.fre_start_addr);
|
||||
|
||||
/* FIXME - fixup the err caching in array.
|
||||
assert no error for base reg id. */
|
||||
assert no error for base reg id and RA undefined. */
|
||||
base_reg_id = sframe_fre_get_base_reg_id (&fre, &err[0]);
|
||||
ra_undefined_p = sframe_fre_get_ra_undefined_p (sfd_ctx, &fre, &err[0]);
|
||||
cfa_offset = sframe_fre_get_cfa_offset (sfd_ctx, &fre, &err[0]);
|
||||
fp_offset = sframe_fre_get_fp_offset (sfd_ctx, &fre, &err[1]);
|
||||
ra_offset = sframe_fre_get_ra_offset (sfd_ctx, &fre, &err[2]);
|
||||
|
||||
/* Dump CFA info. */
|
||||
/* Dump VMA. */
|
||||
printf ("\n");
|
||||
printf (" %016"PRIx64, fre_start_pc_vma);
|
||||
|
||||
/* Dump RA undefined (FRE without any offsets). */
|
||||
if (ra_undefined_p)
|
||||
{
|
||||
printf (" RA undefined");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Dump CFA info. */
|
||||
sprintf (temp, "%s+%d", base_reg_str[base_reg_id], cfa_offset);
|
||||
printf (" %-10s", temp);
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ sframe_get_fre_ra_mangled_p (uint8_t fre_info)
|
||||
static bool
|
||||
sframe_get_fre_ra_undefined_p (uint8_t fre_info)
|
||||
{
|
||||
return SFRAME_V1_FRE_OFFSET_COUNT (fre_info) == 0;
|
||||
return SFRAME_V2_FRE_RA_UNDEFINED_P (fre_info);
|
||||
}
|
||||
|
||||
/* Access functions for info from function descriptor entry. */
|
||||
@@ -729,7 +729,8 @@ sframe_fre_get_fp_offset (sframe_decoder_ctx *dctx,
|
||||
int8_t fp_offset = sframe_decoder_get_fixed_fp_offset (dctx);
|
||||
/* If the FP offset is not being tracked, return the fixed FP offset
|
||||
from the SFrame header. */
|
||||
if (fp_offset != SFRAME_CFA_FIXED_FP_INVALID)
|
||||
if (fp_offset != SFRAME_CFA_FIXED_FP_INVALID
|
||||
&& !sframe_get_fre_ra_undefined_p (fre->fre_info))
|
||||
{
|
||||
if (errp)
|
||||
*errp = 0;
|
||||
@@ -760,7 +761,8 @@ sframe_fre_get_ra_offset (sframe_decoder_ctx *dctx,
|
||||
int8_t ra_offset = sframe_decoder_get_fixed_ra_offset (dctx);
|
||||
/* If the RA offset was not being tracked, return the fixed RA offset
|
||||
from the SFrame header. */
|
||||
if (ra_offset != SFRAME_CFA_FIXED_RA_INVALID)
|
||||
if (ra_offset != SFRAME_CFA_FIXED_RA_INVALID
|
||||
&& !sframe_get_fre_ra_undefined_p (fre->fre_info))
|
||||
{
|
||||
if (errp)
|
||||
*errp = 0;
|
||||
|
||||
Reference in New Issue
Block a user