mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 12:34:43 +00:00
s390: Store SFrame CFA offset adjusted
In SFrame V2 the size of the offsets following an SFrame FRE can be either signed 8-bit, 16-bit, or 32-bit integer, with the largest offset determining their size: 1. CFA offset from CFA base register 2. RA (stack save slot) offset from CFA, usually -48 on s390x if saved 3. FP (stack save slot) offset from CFA, usually -72 on s390x if saved The FP and RA offsets from CFA, when FP/RA saved on the stack, usually have fixed values that fit into signed 8-bit SFrame offsets. Likewise the DWARF register numbers on s390x of general registers (GR; 0-15) and floating-point registers (FPR; 16-31), when FP/RA saved in registers. With that the CFA offset from CFA base register has the greatest impact on the signed SFrame offset size. The s390x ELF ABI [1] defines the CFA as stack pointer (SP) at call site +160. [2] Therefore the minimum CFA offset from CFA base register on s390x is 160. This does not fit into a signed 8-bit integer and therefore effectively prevents any use of signed 8-bit SFrame offsets on s390x. For s390x store the CFA offset from CFA base register adjusted by -160 to enable the use of signed 8-bit SFrame offsets. [1]: s390x ELF ABI, https://github.com/IBM/s390x-abi/releases [2]: s390x ELF ABI, commit 4e38ad9c8a88 ("Document the CFA"), https://github.com/IBM/s390x-abi/commit/4e38ad9c8a88 include/ * sframe.h (SFRAME_S390X_CFA_OFFSET_ADJUSTMENT): Define s390x-specific CFA offset adjustment. (SFRAME_V2_S390X_CFA_OFFSET_ENCODE, SFRAME_V2_S390X_CFA_OFFSET_DECODE): New s390x-specific macros. Use SFRAME_S390X_CFA_OFFSET_ADJUSTMENT to en-/decode CFA offset. bfd/ * elf64-s390.c (elf_s390x_sframe_plt_fre): Use SFRAME_V2_S390X_CFA_OFFSET_ENCODE on CFA offset to store it adjusted and switch to 8-bit offsets. gas/ * gen-sframe.c (sframe_fre_set_cfa_offset): For s390x use SFRAME_V2_S390X_CFA_OFFSET_ENCODE on CFA offset to store it adjusted. (sframe_fre_get_cfa_offset): New helper. For s390x use SFRAME_V2_S390X_CFA_OFFSET_DECODE on CFA offset to undo its adjustment. (sframe_xlate_do_def_cfa_register): Use new helper sframe_fre_get_cfa_offset. libsframe/ * sframe.c (sframe_fre_get_cfa_offset): For s390x use SFRAME_V2_S390X_CFA_OFFSET_DECODE on CFA offset to undo its adjustment. * doc/sframe-spec.texi (s390x, SFRAME_S390X_CFA_OFFSET_ADJUSTMENT, SFRAME_V2_S390X_CFA_OFFSET_ENCODE, SFRAME_V2_S390X_CFA_OFFSET_DECODE): Document s390x-specific adjustment of CFA offset. libsframe/testsuite/ * libsframe.find/plt-findfre-2.c (add_plt0_fde, add_pltn_fde): Use SFRAME_V2_S390X_CFA_OFFSET_ENCODE to enable use of 1-byte SFrame offsets. Suggested-by: Indu Bhagat <indu.bhagat@oracle.com> Signed-off-by: Jens Remus <jremus@linux.ibm.com>
This commit is contained in:
@@ -155,6 +155,12 @@ an FP/RA offset.
|
||||
@item SFRAME_FRE_RA_OFFSET_INVALID: Invalid RA offset value (like
|
||||
SFRAME_CFA_FIXED_RA_INVALID). Used on s390x as padding offset to represent
|
||||
FP without RA saved.
|
||||
@item SFRAME_S390X_CFA_OFFSET_ADJUSTMENT: CFA offset (from CFA base register)
|
||||
adjustment value. Used to enable use of 8-bit SFrame offsets on s390x.
|
||||
@item SFRAME_V2_S390X_CFA_OFFSET_ENCODE: Encode CFA offset (i.e., apply
|
||||
CFA offset adjustment).
|
||||
@item SFRAME_V2_S390X_CFA_OFFSET_DECODE: Decode CFA offset (i.e., revert
|
||||
CFA offset adjustment).
|
||||
@end itemize
|
||||
@end itemize
|
||||
|
||||
@@ -885,7 +891,15 @@ case in the topmost stack frame of the callchain. For FP this may be the case
|
||||
in any stack frame.
|
||||
|
||||
Irrespective of the ABI, the first stack offset is always used to locate the
|
||||
CFA, by interpreting it as: CFA = @code{BASE_REG} + offset1.
|
||||
CFA. On s390x the value of the offset is stored adjusted by the s390x-specific
|
||||
@code{SFRAME_S390X_CFA_OFFSET_ADJUSTMENT} to enable the use of signed 8-bit
|
||||
offsets on s390x.
|
||||
s390x-specific helpers @code{SFRAME_V2_S390X_CFA_OFFSET_ENCODE} and
|
||||
@code{SFRAME_V2_S390X_CFA_OFFSET_DECODE} are provided to perform and undo
|
||||
the adjustment. The CFA offset can therefore be interpreted as:
|
||||
CFA = @code{BASE_REG} + @code{SFRAME_V2_S390X_CFA_OFFSET_DECODE(offset1)}
|
||||
or
|
||||
CFA = @code{BASE_REG} + offset1 - @code{SFRAME_S390X_CFA_OFFSET_ADJUSTMENT}.
|
||||
The identification of the @code{BASE_REG} is done by using the
|
||||
@code{fre_cfa_base_reg_id} field in the SFrame FRE info word.
|
||||
|
||||
|
||||
@@ -695,10 +695,16 @@ sframe_fre_get_base_reg_id (sframe_frame_row_entry *fre, int *errp)
|
||||
/* Get the CFA offset from the FRE. If the offset is invalid, sets errp. */
|
||||
|
||||
int32_t
|
||||
sframe_fre_get_cfa_offset (sframe_decoder_ctx *dctx ATTRIBUTE_UNUSED,
|
||||
sframe_fre_get_cfa_offset (sframe_decoder_ctx *dctx,
|
||||
sframe_frame_row_entry *fre, int *errp)
|
||||
{
|
||||
return sframe_get_fre_offset (fre, SFRAME_FRE_CFA_OFFSET_IDX, errp);
|
||||
int32_t offset = sframe_get_fre_offset (fre, SFRAME_FRE_CFA_OFFSET_IDX, errp);
|
||||
|
||||
/* For s390x undo adjustment of CFA offset (to enable 8-bit offsets). */
|
||||
if (sframe_decoder_get_abi_arch (dctx) == SFRAME_ABI_S390X_ENDIAN_BIG)
|
||||
offset = SFRAME_V2_S390X_CFA_OFFSET_DECODE (offset);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
/* Get the FP offset from the FRE. If the offset is invalid, sets errp.
|
||||
|
||||
@@ -43,8 +43,8 @@ add_plt0_fde (sframe_encoder_ctx *ectx, uint32_t plt_vaddr,
|
||||
/* 1 single FRE. */
|
||||
sframe_frame_row_entry fre
|
||||
= { 0x0,
|
||||
{ 0, 160 + PLT0_CFA_OFFSET_MAGIC },
|
||||
SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_2B) };
|
||||
{ SFRAME_V2_S390X_CFA_OFFSET_ENCODE (160 + PLT0_CFA_OFFSET_MAGIC) },
|
||||
SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) };
|
||||
|
||||
unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1,
|
||||
SFRAME_FDE_TYPE_PCINC);
|
||||
@@ -72,8 +72,8 @@ add_pltn_fde (sframe_encoder_ctx *ectx, uint32_t plt_vaddr,
|
||||
/* 1 single FRE. */
|
||||
sframe_frame_row_entry fre
|
||||
= { 0x0,
|
||||
{ 0, 160 + PLTN_CFA_OFFSET_MAGIC },
|
||||
SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_2B) };
|
||||
{ SFRAME_V2_S390X_CFA_OFFSET_ENCODE (160 + PLTN_CFA_OFFSET_MAGIC) },
|
||||
SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) };
|
||||
|
||||
unsigned char finfo = sframe_fde_create_func_info (SFRAME_FRE_TYPE_ADDR1,
|
||||
SFRAME_FDE_TYPE_PCMASK);
|
||||
|
||||
Reference in New Issue
Block a user