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:
@@ -135,10 +135,26 @@ sframe_fre_set_cfa_base_reg (struct sframe_row_entry *fre,
|
||||
fre->merge_candidate = false;
|
||||
}
|
||||
|
||||
static offsetT
|
||||
sframe_fre_get_cfa_offset (const struct sframe_row_entry * fre)
|
||||
{
|
||||
offsetT offset = fre->cfa_offset;
|
||||
|
||||
/* For s390x undo adjustment of CFA offset (to enable 8-bit offsets). */
|
||||
if (sframe_get_abi_arch () == SFRAME_ABI_S390X_ENDIAN_BIG)
|
||||
offset = SFRAME_V2_S390X_CFA_OFFSET_DECODE (offset);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static void
|
||||
sframe_fre_set_cfa_offset (struct sframe_row_entry *fre,
|
||||
offsetT cfa_offset)
|
||||
{
|
||||
/* For s390x adjust CFA offset to enable 8-bit offsets. */
|
||||
if (sframe_get_abi_arch () == SFRAME_ABI_S390X_ENDIAN_BIG)
|
||||
cfa_offset = SFRAME_V2_S390X_CFA_OFFSET_ENCODE (cfa_offset);
|
||||
|
||||
fre->cfa_offset = cfa_offset;
|
||||
fre->merge_candidate = false;
|
||||
}
|
||||
@@ -1043,7 +1059,7 @@ sframe_xlate_do_def_cfa_register (struct sframe_xlate_ctx *xlate_ctx,
|
||||
}
|
||||
sframe_fre_set_cfa_base_reg (cur_fre, cfi_insn->u.r);
|
||||
if (last_fre)
|
||||
sframe_fre_set_cfa_offset (cur_fre, last_fre->cfa_offset);
|
||||
sframe_fre_set_cfa_offset (cur_fre, sframe_fre_get_cfa_offset (last_fre));
|
||||
|
||||
cur_fre->merge_candidate = false;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user