]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[SFrame-V3] libsframe: testsuite: add new argument to offset access APIs
authorIndu Bhagat <indu.bhagat@oracle.com>
Mon, 17 Nov 2025 18:36:27 +0000 (10:36 -0800)
committerIndu Bhagat <indu.bhagat@oracle.com>
Tue, 9 Dec 2025 08:26:14 +0000 (00:26 -0800)
For FDE of type SFRAME_FDE_TYPE_FLEX_TOPMOST_FRAME, the offsets are not
only laid out differently, they also have different encoding.

Adjust the APIs in libsframe to get stack frame offsets by adding a new
argument type.

ATM, the stack tracer testsuite is not using this newly externalized API
sframe_get_fre_offset.  So not exposing this via the libsframe.ver file
is OK for now.

At the moment, like the generation routines in GAS, the textual dump
routines in sframe-dump.c are also unaware of
SFRAME_FDE_TYPE_FLEX_TOPMOST_FRAME FDE type.  In the next commits, these
capabilities will be added.

include/
* sframe-api.h (MAX_NUM_STACK_OFFSETS): Increase the number of
stack offsets to 6 to accommodate the FDE type
SFRAME_FDE_TYPE_FLEX_TOPMOST_FRAME.
(sframe_get_fre_offset): Make extern.
(sframe_fre_get_cfa_offset): Add new arg.
(sframe_fre_get_fp_offset): Likewise.
(sframe_fre_get_ra_offset): Likewise.
libsframe/
* libsframe/sframe-dump.c (dump_sframe_func_with_fres): Pass 0
for FDE type.
* sframe.c (sframe_fre_get_cfa_offset): Handle FDE type.
(sframe_fre_get_fp_offset): Likewise.
(sframe_fre_get_ra_offset): Likewise.
libsframe/testsuite/
* libsframe.find/findfre-1.c: Pass 0 for FDE type.
* libsframe.find/findfunc-1.c: Likewise.
* libsframe.find/plt-findfre-1.c: Likewise.
* libsframe.find/plt-findfre-2.c: Likewise.

include/sframe-api.h
libsframe/libsframe.ver
libsframe/sframe-dump.c
libsframe/sframe.c
libsframe/testsuite/libsframe.find/findfre-1.c
libsframe/testsuite/libsframe.find/findfunc-1.c
libsframe/testsuite/libsframe.find/plt-findfre-1.c
libsframe/testsuite/libsframe.find/plt-findfre-2.c

index 1a3b2c307ba92939028d639e84b00a37037ba8a0..bea7cc099b8def06bb4806d73d0ee3be9e9a35bb 100644 (file)
@@ -31,7 +31,7 @@ extern "C"
 typedef struct sframe_decoder_ctx sframe_decoder_ctx;
 typedef struct sframe_encoder_ctx sframe_encoder_ctx;
 
-#define MAX_NUM_STACK_OFFSETS  3
+#define MAX_NUM_STACK_OFFSETS  6
 
 #define MAX_OFFSET_BYTES  \
   ((SFRAME_FRE_OFFSET_4B * 2 * MAX_NUM_STACK_OFFSETS))
@@ -199,6 +199,9 @@ sframe_decoder_get_funcdesc_v3 (const sframe_decoder_ctx *dctx,
 extern void
 dump_sframe (const sframe_decoder_ctx *decoder, uint64_t addr);
 
+extern int32_t
+sframe_get_fre_offset (const sframe_frame_row_entry *fre, int idx, int *errp);
+
 /* Get the base reg id from the FRE info.  Sets errp if fails.  */
 extern uint8_t
 sframe_fre_get_base_reg_id (const sframe_frame_row_entry *fre, int *errp);
@@ -206,7 +209,9 @@ sframe_fre_get_base_reg_id (const sframe_frame_row_entry *fre, int *errp);
 /* Get the CFA offset from the FRE.  If the offset is invalid, sets errp.  */
 extern int32_t
 sframe_fre_get_cfa_offset (const sframe_decoder_ctx *dtcx,
-                          const sframe_frame_row_entry *fre, int *errp);
+                          const sframe_frame_row_entry *fre,
+                          uint32_t fde_type,
+                          int *errp);
 
 /* Get the FP offset from the FRE.  If the offset is invalid, sets errp.
 
@@ -214,7 +219,9 @@ sframe_fre_get_cfa_offset (const sframe_decoder_ctx *dtcx,
    LSB set to one, which is only valid in the topmost frame.  */
 extern int32_t
 sframe_fre_get_fp_offset (const sframe_decoder_ctx *dctx,
-                         const sframe_frame_row_entry *fre, int *errp);
+                         const sframe_frame_row_entry *fre,
+                         uint32_t fde_type,
+                         int *errp);
 
 /* Get the RA offset from the FRE.  If the offset is invalid, sets errp.
 
@@ -224,7 +231,9 @@ sframe_fre_get_fp_offset (const sframe_decoder_ctx *dctx,
    LSB set to one, which is only valid in the topmost frame.  */
 extern int32_t
 sframe_fre_get_ra_offset (const sframe_decoder_ctx *dctx,
-                         const sframe_frame_row_entry *fre, int *errp);
+                         const sframe_frame_row_entry *fre,
+                         uint32_t fde_type,
+                         int *errp);
 
 /* Get whether the RA is mangled.  */
 
index 990274974861116cf8395ce0ade99e0cb7d9d1d9..f6dbde273de65d515177afb7d623087b3b6123cb 100644 (file)
@@ -6,6 +6,7 @@ LIBSFRAME_3.0 {
     sframe_fde_create_func_info;
     sframe_calc_fre_type;
     sframe_fre_get_base_reg_id;
+    sframe_get_fre_offset;
     sframe_fre_get_cfa_offset;
     sframe_fre_get_fp_offset;
     sframe_fre_get_ra_offset;
index eda97b70b781664e5460a085eebdfba6d8520fe0..6da571a841cd37f05cdac47d1f52ebe4a6db5acb 100644 (file)
@@ -232,9 +232,9 @@ dump_sframe_func_with_fres (const sframe_decoder_ctx *sfd_ctx,
         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]);
+      cfa_offset = sframe_fre_get_cfa_offset (sfd_ctx, &fre, 0, &err[0]);
+      fp_offset = sframe_fre_get_fp_offset (sfd_ctx, &fre, 0, &err[1]);
+      ra_offset = sframe_fre_get_ra_offset (sfd_ctx, &fre, 0, &err[2]);
 
       /* Dump VMA.  */
       printf ("\n");
index dd16d3218b9abc8082a26f91f606579f4e40c024..d223941b34bfc9396fda1a2b3c2c06db27d2f2cb 100644 (file)
@@ -821,7 +821,7 @@ fde_func (const void *p1, const void *p2)
 
 /* Get IDX'th offset from FRE.  Set errp as applicable.  */
 
-static int32_t
+int32_t
 sframe_get_fre_offset (const sframe_frame_row_entry *fre, int idx, int *errp)
 {
   uint8_t offset_cnt, offset_size;
@@ -938,13 +938,18 @@ sframe_fre_get_base_reg_id (const sframe_frame_row_entry *fre, int *errp)
 
 int32_t
 sframe_fre_get_cfa_offset (const sframe_decoder_ctx *dctx,
-                          const sframe_frame_row_entry *fre, int *errp)
+                          const sframe_frame_row_entry *fre,
+                          uint32_t fde_type,
+                          int *errp)
 {
   int err;
-  int32_t offset = sframe_get_fre_offset (fre, SFRAME_FRE_CFA_OFFSET_IDX, &err);
+  bool flex_p = (fde_type == SFRAME_FDE_TYPE_FLEX_TOPMOST_FRAME);
+  uint32_t idx = flex_p ? 1 : 0;
+  int32_t offset = sframe_get_fre_offset (fre, idx, &err);
 
   /* For s390x undo adjustment of CFA offset (to enable 8-bit offsets).  */
-  if (!err && sframe_decoder_get_abi_arch (dctx) == SFRAME_ABI_S390X_ENDIAN_BIG)
+  if (!err && !flex_p
+      && sframe_decoder_get_abi_arch (dctx) == SFRAME_ABI_S390X_ENDIAN_BIG)
     offset = SFRAME_V2_S390X_CFA_OFFSET_DECODE (offset);
 
   if (errp)
@@ -959,13 +964,17 @@ sframe_fre_get_cfa_offset (const sframe_decoder_ctx *dctx,
 
 int32_t
 sframe_fre_get_fp_offset (const sframe_decoder_ctx *dctx,
-                         const sframe_frame_row_entry *fre, int *errp)
+                         const sframe_frame_row_entry *fre,
+                         uint32_t fde_type,
+                         int *errp)
 {
   uint32_t fp_offset_idx = 0;
+  bool flex_p = (fde_type == SFRAME_FDE_TYPE_FLEX_TOPMOST_FRAME);
+
   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 (!flex_p && fp_offset != SFRAME_CFA_FIXED_FP_INVALID
       && !sframe_get_fre_ra_undefined_p (fre->fre_info))
     {
       if (errp)
@@ -980,6 +989,8 @@ sframe_fre_get_fp_offset (const sframe_decoder_ctx *dctx,
                    != SFRAME_CFA_FIXED_RA_INVALID)
                   ? SFRAME_FRE_RA_OFFSET_IDX
                   : SFRAME_FRE_FP_OFFSET_IDX);
+  fp_offset_idx = flex_p ? SFRAME_FRE_FP_OFFSET_IDX * 2 + 1 : fp_offset_idx;
+
   return sframe_get_fre_offset (fre, fp_offset_idx, errp);
 }
 
@@ -992,12 +1003,17 @@ sframe_fre_get_fp_offset (const sframe_decoder_ctx *dctx,
 
 int32_t
 sframe_fre_get_ra_offset (const sframe_decoder_ctx *dctx,
-                         const sframe_frame_row_entry *fre, int *errp)
+                         const sframe_frame_row_entry *fre,
+                         uint32_t fde_type,
+                         int *errp)
 {
+  uint32_t ra_offset_idx = 0;
   int8_t ra_offset = sframe_decoder_get_fixed_ra_offset (dctx);
+  bool flex_p = (fde_type == SFRAME_FDE_TYPE_FLEX_TOPMOST_FRAME);
+
   /* 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 (!flex_p && ra_offset != SFRAME_CFA_FIXED_RA_INVALID
       && !sframe_get_fre_ra_undefined_p (fre->fre_info))
     {
       if (errp)
@@ -1006,7 +1022,10 @@ sframe_fre_get_ra_offset (const sframe_decoder_ctx *dctx,
     }
 
   /* Otherwise, get the RA offset from the FRE.  */
-  return sframe_get_fre_offset (fre, SFRAME_FRE_RA_OFFSET_IDX, errp);
+  ra_offset_idx = (flex_p
+                  ? SFRAME_FRE_RA_OFFSET_IDX * 2 + 1
+                  : SFRAME_FRE_RA_OFFSET_IDX);
+  return sframe_get_fre_offset (fre, ra_offset_idx, errp);
 }
 
 /* Get whether the RA is mangled.  */
index 58cbbb85e7795c78ca8fcee7d8354098e80f2197..89357ca46cdc4aa1f5f3dd3e0b0349f7711e34ec 100644 (file)
@@ -132,31 +132,31 @@ void test_text_findfre (const char suffix, int64_t text_vaddr,
   /* Find the third FRE in first FDE.  */
   lookup_pc = func1_start_vaddr + 0x15 - sframe_vaddr;
   err = sframe_find_fre (dctx, lookup_pc, &frep);
-  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, &err) == 0x3),
+  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, 0, &err) == 0x3),
        "findfre-1%c: Find third FRE", suffix);
 
   /* Find an FRE for PC at the end of range covered by FRE.  */
   lookup_pc = func1_start_vaddr + 0x9 - sframe_vaddr;
   err = sframe_find_fre (dctx, lookup_pc, &frep);
-  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, &err) == 0x2),
+  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, 0, &err) == 0x2),
        "findfre-1%c: Find FRE for last PC covered by FRE", suffix);
 
   /* Find the last FRE in first FDE.  */
   lookup_pc = func1_start_vaddr + 0x39 - sframe_vaddr;
   err = sframe_find_fre (dctx, lookup_pc, &frep);
-  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, &err) == 0x8),
+  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, 0, &err) == 0x8),
        "findfre-1%c: Find last FRE", suffix);
 
   /* Find the second FRE in second FDE.  */
   lookup_pc = func2_start_vaddr + 0x11 - sframe_vaddr;
   err = sframe_find_fre (dctx, lookup_pc, &frep);
-  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, &err) == 0x12),
+  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, 0, &err) == 0x12),
        "findfre-1%c: Find second FRE", suffix);
 
   /* Find the first FRE in second FDE.  */
   lookup_pc = func2_start_vaddr + 0x0 - sframe_vaddr;
   err = sframe_find_fre (dctx, lookup_pc, &frep);
-  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, &err) == 0x10),
+  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, 0, &err) == 0x10),
        "findfre-1%c: Find first FRE", suffix);
 
   /* Find FRE for PC out of range.  Expect error code.  */
index c8d9a0191ed479b8a7572bad8e9157ef3491cc8b..60b2404454f401ec0bf3765d9f99181443b9d381 100644 (file)
@@ -212,19 +212,19 @@ void test_text_findfre (const char suffix, int64_t text_vaddr,
   /* Find an FRE for PC in FDE1.  */
   lookup_pc = func1_start_vaddr + 0x9 - sframe_vaddr;
   err = sframe_find_fre (dctx, lookup_pc, &frep);
-  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, &err) == 0x2),
+  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, 0, &err) == 0x2),
        "findfunc-1%c: Find FRE in FDE1", suffix);
 
   /* Find an FRE for PC in FDE2.  */
   lookup_pc = func2_start_vaddr + 0x11 - sframe_vaddr;
   err = sframe_find_fre (dctx, lookup_pc, &frep);
-  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, &err) == 0x12),
+  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, 0, &err) == 0x12),
        "findfunc-1%c: Find FRE in FDE2", suffix);
 
   /* Find an FRE for PC in FDE3.  */
   lookup_pc = func3_start_vaddr + 0x10 - sframe_vaddr;
   err = sframe_find_fre (dctx, lookup_pc, &frep);
-  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, &err) == 0x18),
+  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, 0, &err) == 0x18),
        "findfunc-1%c: Find FRE in FDE3", suffix);
 
   sframe_encoder_free (&encode);
index 5363ac7d1f68ca09fbd2cb838549e82f4eadf4c0..594a6a2f8e0e529e4382cc3e430d2ff489d277ee 100644 (file)
@@ -86,32 +86,32 @@ void test_plt_findfre (const char suffix, int64_t plt_vaddr,
 
   /* Find the first FRE in PLT1.  */
   err = sframe_find_fre (dctx, (plt_vaddr + 0x0 - sframe_vaddr), &frep);
-  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, &err) == 0x1),
+  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, 0, &err) == 0x1),
        "plt-findfre-1%c: Find first FRE in PLT1", suffix);
 
   /* Find the second FRE.  */
   err = sframe_find_fre (dctx, (plt_vaddr + 0x6 - sframe_vaddr), &frep);
-  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, &err) == 0x2),
+  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, 0, &err) == 0x2),
        "plt-findfre-1%c: Find second FRE in PLT1", suffix);
 
   /* Find the last FRE.  */
   err = sframe_find_fre (dctx, (plt_vaddr + 0xc - sframe_vaddr), &frep);
-  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, &err) == 0x3),
+  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, 0, &err) == 0x3),
        "plt-findfre-1%c: Find last FRE in PLT1", suffix);
 
   /* Find the first FRE in PLT4.  */
   err = sframe_find_fre (dctx, (plt_vaddr + 16*3 + 0x0 - sframe_vaddr), &frep);
-  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, &err) == 0x1),
+  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, 0, &err) == 0x1),
        "plt-findfre-1%c: Find first FRE in PLT4", suffix);
 
   /* Find the second FRE in PLT4.  */
   err = sframe_find_fre (dctx, (plt_vaddr + 16*3 + 0x6 - sframe_vaddr), &frep);
-  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, &err) == 0x2),
+  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, 0, &err) == 0x2),
        "plt-findfre-1%c: Find second FRE in PLT4", suffix);
 
   /* Find the last FRE in PLT4.  */
   err = sframe_find_fre (dctx, (plt_vaddr + 16*3 + 0xc - sframe_vaddr), &frep);
-  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, &err) == 0x3),
+  TEST ((err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, 0, &err) == 0x3),
        "plt-findfre-1%c: Find last FRE in PLT4", suffix);
 
   /* Find no FRE for out of range PLT6.  */
index 4cb04bd14c8eb25cf1bf3e6a0a54dfa4e71a3105..248465c84e9861fd4e112fb52ee5ed0bd8c5c66d 100644 (file)
@@ -134,12 +134,12 @@ void test_plt_findfre (const char suffix, const int64_t plt_vaddr,
 
   /* Find the only FRE in PLT0 at offset 0.  */
   err = sframe_find_fre (dctx, (plt_vaddr + 0 - sframe_vaddr), &frep);
-  TEST (err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, &err) == 160 + PLT0_CFA_OFFSET_MAGIC,
+  TEST (err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, 0, &err) == 160 + PLT0_CFA_OFFSET_MAGIC,
        "plt-findfre-2%c: Find only FRE in PLT0 at offset 0", suffix);
 
   /* Find the only FRE in PLT0 at offset PLT_SIZE-1.  */
   err = sframe_find_fre (dctx, (plt_vaddr + (PLT_SIZE-1) - sframe_vaddr), &frep);
-  TEST (err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, &err) == 160 + PLT0_CFA_OFFSET_MAGIC,
+  TEST (err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, 0, &err) == 160 + PLT0_CFA_OFFSET_MAGIC,
        "plt-findfre-2%c: Find only FRE in PLT0 at offset PLT_SIZE-1", suffix);
 
   /* Find the only FRE in PLT1-5 at offset 0 and PLT_SIZE-1.  */
@@ -147,12 +147,12 @@ void test_plt_findfre (const char suffix, const int64_t plt_vaddr,
     {
       /* Find the only FRE in PLTN at offset 0.  */
       err = sframe_find_fre (dctx, (plt_vaddr + i * PLT_SIZE + 0 - sframe_vaddr), &frep);
-      TEST (err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, &err) == 160 + PLTN_CFA_OFFSET_MAGIC,
+      TEST (err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, 0, &err) == 160 + PLTN_CFA_OFFSET_MAGIC,
            "plt-findfre-2%c: Find only FRE in PLT%d at offset 0", suffix, i);
 
       /* Find the only FRE in PLTN at offset 31.  */
       err = sframe_find_fre (dctx, (plt_vaddr + i * PLT_SIZE + (PLT_SIZE-1) - sframe_vaddr), &frep);
-      TEST (err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, &err) == 160 + PLTN_CFA_OFFSET_MAGIC,
+      TEST (err == 0 && sframe_fre_get_cfa_offset (dctx, &frep, 0, &err) == 160 + PLTN_CFA_OFFSET_MAGIC,
            "plt-findfre-2%c: Find only FRE in PLT%d at offset PLT_SIZE-1", suffix, i);
     }