aboutsummaryrefslogtreecommitdiff
path: root/libsframe/sframe-dump.c
diff options
context:
space:
mode:
Diffstat (limited to 'libsframe/sframe-dump.c')
-rw-r--r--libsframe/sframe-dump.c91
1 files changed, 57 insertions, 34 deletions
diff --git a/libsframe/sframe-dump.c b/libsframe/sframe-dump.c
index 42a086a..47ac00e 100644
--- a/libsframe/sframe-dump.c
+++ b/libsframe/sframe-dump.c
@@ -1,6 +1,6 @@
/* sframe-dump.c - Textual dump of .sframe.
- Copyright (C) 2022-2024 Free Software Foundation, Inc.
+ Copyright (C) 2022-2025 Free Software Foundation, Inc.
This file is part of libsframe.
@@ -23,8 +23,6 @@
#include <inttypes.h>
#include "sframe-impl.h"
-#define SFRAME_HEADER_FLAGS_STR_MAX_LEN 50
-
/* Return TRUE if the SFrame section is associated with the aarch64 ABIs. */
static bool
@@ -41,12 +39,43 @@ is_sframe_abi_arch_aarch64 (sframe_decoder_ctx *sfd_ctx)
}
static void
+dump_sframe_header_flags (sframe_decoder_ctx *sfd_ctx)
+{
+ uint8_t flags;
+ const char *prefix = "Flags: ";
+
+ flags = sframe_decoder_get_flags (sfd_ctx);
+ if (!flags)
+ {
+ printf ("%11sNONE\n", prefix);
+ return;
+ }
+
+#define PRINT_FLAG(x) \
+ if (flags & (x)) \
+ { flags = (flags & ~(x)); \
+ printf ("%11s%s%s\n", prefix, #x, flags ? "," : ""); \
+ prefix = " "; \
+ }
+
+ PRINT_FLAG (SFRAME_F_FDE_SORTED);
+ PRINT_FLAG (SFRAME_F_FRAME_POINTER);
+ PRINT_FLAG (SFRAME_F_FDE_FUNC_START_PCREL);
+#undef PRINT_FLAG
+
+ /* Print any residual flags, should this implementation be out of sync when
+ new flags are added. */
+ if (flags)
+ printf ("%11s%d\n", prefix, flags);
+}
+
+static void
dump_sframe_header (sframe_decoder_ctx *sfd_ctx)
{
uint8_t ver;
- uint8_t flags;
- char *flags_str;
const char *ver_str = NULL;
+ int8_t cfa_fixed_fp_offset;
+ int8_t cfa_fixed_ra_offset;
const sframe_header *header = &(sfd_ctx->sfd_header);
/* Prepare SFrame section version string. */
@@ -55,43 +84,28 @@ dump_sframe_header (sframe_decoder_ctx *sfd_ctx)
"SFRAME_VERSION_1",
"SFRAME_VERSION_2" };
- /* PS: Keep SFRAME_HEADER_FLAGS_STR_MAX_LEN in sync if adding more members to
- this array. */
- const char *flag_names[]
- = { "SFRAME_F_FDE_SORTED",
- "SFRAME_F_FRAME_POINTER" };
-
ver = sframe_decoder_get_version (sfd_ctx);
if (ver <= SFRAME_VERSION)
ver_str = version_names[ver];
- /* Prepare SFrame section flags string. */
- flags = header->sfh_preamble.sfp_flags;
- flags_str = (char*) calloc (SFRAME_HEADER_FLAGS_STR_MAX_LEN, sizeof (char));
- if (flags)
- {
- if (flags & SFRAME_F_FDE_SORTED)
- strcpy (flags_str, flag_names[0]);
- if (flags & SFRAME_F_FRAME_POINTER)
- {
- if (strlen (flags_str) > 0)
- strcpy (flags_str, ",");
- strcpy (flags_str, flag_names[1]);
- }
- }
- else
- strcpy (flags_str, "NONE");
+ /* CFA fixed FP and RA offsets. */
+ cfa_fixed_fp_offset = header->sfh_cfa_fixed_fp_offset;
+ cfa_fixed_ra_offset = header->sfh_cfa_fixed_ra_offset;
const char* subsec_name = "Header";
printf ("\n");
printf (" %s :\n", subsec_name);
printf ("\n");
printf (" Version: %s\n", ver_str);
- printf (" Flags: %s\n", flags_str);
+
+ dump_sframe_header_flags (sfd_ctx);
+
+ if (cfa_fixed_fp_offset != SFRAME_CFA_FIXED_FP_INVALID)
+ printf (" CFA fixed FP offset: %d\n", cfa_fixed_fp_offset);
+ if (cfa_fixed_ra_offset != SFRAME_CFA_FIXED_RA_INVALID)
+ printf (" CFA fixed RA offset: %d\n", cfa_fixed_ra_offset);
printf (" Num FDEs: %d\n", sframe_decoder_get_num_fidx (sfd_ctx));
printf (" Num FREs: %d\n", header->sfh_num_fres);
-
- free (flags_str);
}
static void
@@ -119,8 +133,15 @@ dump_sframe_func_with_fres (sframe_decoder_ctx *sfd_ctx,
/* Get the SFrame function descriptor. */
sframe_decoder_get_funcdesc (sfd_ctx, funcidx, &num_fres,
&func_size, &func_start_address, &func_info);
- /* Calculate the virtual memory address for function start pc. */
+/* Calculate the virtual memory address for function start pc. Some older
+ SFrame V2 sections in ET_DYN or ET_EXEC may still have the
+ SFRAME_F_FDE_FUNC_START_PCREL flag unset, and hence may be using the
+ old encoding. Continue to support dumping the sections at least. */
func_start_pc_vma = func_start_address + sec_addr;
+ if (sframe_decoder_get_flags (sfd_ctx) & SFRAME_F_FDE_FUNC_START_PCREL)
+ func_start_pc_vma += sframe_decoder_get_offsetof_fde_start_addr (sfd_ctx,
+ funcidx,
+ NULL);
/* Mark FDEs with [m] where the FRE start address is interpreted as a
mask. */
@@ -171,13 +192,15 @@ dump_sframe_func_with_fres (sframe_decoder_ctx *sfd_ctx,
printf ("%-10s", temp);
/* Dump RA info.
- If an ABI does not track RA offset, e.g., AMD64, display a 'u',
+ If an ABI does not track RA offset, e.g., AMD64, display 'f',
else display the offset d as 'c+-d'. */
- if (sframe_decoder_get_fixed_ra_offset(sfd_ctx)
+ if (sframe_decoder_get_fixed_ra_offset (sfd_ctx)
!= SFRAME_CFA_FIXED_RA_INVALID)
- strcpy (temp, "u");
+ strcpy (temp, "f");
else if (err[2] == 0)
sprintf (temp, "c%+d", ra_offset);
+ else
+ strcpy (temp, "u");
/* Mark SFrame FRE's RA information with "[s]" if the RA is mangled
with signature bits. */