1 /* sframe-dump.c - Textual dump of .sframe.
3 Copyright (C) 2022 Free Software Foundation, Inc.
5 his file is part of libsframe.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
24 #include "sframe-impl.h"
26 #define SFRAME_HEADER_FLAGS_STR_MAX_LEN 50
29 dump_sframe_header (sframe_decoder_ctx
*sfd_ctx
)
31 const char *verstr
= NULL
;
32 const sframe_header
*header
= &(sfd_ctx
->sfd_header
);
34 /* Prepare SFrame section version string. */
35 const char *version_names
[]
38 unsigned char ver
= header
->sfh_preamble
.sfp_version
;
39 if (ver
<= SFRAME_VERSION
)
40 verstr
= version_names
[ver
];
42 /* Prepare SFrame section flags string. */
43 unsigned char flags
= header
->sfh_preamble
.sfp_flags
;
45 = (char*) calloc (sizeof (char), SFRAME_HEADER_FLAGS_STR_MAX_LEN
);
48 const char *flag_names
[]
49 = { "SFRAME_F_FDE_SORTED",
50 "SFRAME_F_FRAME_POINTER" };
51 unsigned char flags
= header
->sfh_preamble
.sfp_flags
;
52 if (flags
& SFRAME_F_FDE_SORTED
)
53 strcpy (flags_str
, flag_names
[0]);
54 if (flags
& SFRAME_F_FRAME_POINTER
)
56 if (strlen (flags_str
) > 0)
57 strcpy (flags_str
, ",");
58 strcpy (flags_str
, flag_names
[1]);
62 strcpy (flags_str
, "NONE");
64 const char* subsec_name
= "Header";
66 printf (" %s :\n", subsec_name
);
68 printf (" Version: %s\n", verstr
);
69 printf (" Flags: %s\n", flags_str
);
70 printf (" Num FDEs: %d\n", header
->sfh_num_fdes
);
71 printf (" Num FREs: %d\n", header
->sfh_num_fres
);
77 dump_sframe_func_with_fres (sframe_decoder_ctx
*sfd_ctx
,
82 uint32_t num_fres
= 0;
83 uint32_t func_size
= 0;
84 int32_t func_start_address
= 0;
85 unsigned char func_info
= 0;
87 uint64_t func_start_pc_vma
= 0;
88 uint64_t fre_start_pc_vma
= 0;
89 const char *base_reg_str
[] = {"fp", "sp"};
90 int32_t cfa_offset
= 0;
91 int32_t fp_offset
= 0;
92 int32_t ra_offset
= 0;
93 unsigned int base_reg_id
= 0;
94 int err
[3] = {0, 0, 0};
96 sframe_frame_row_entry fre
;
98 /* Get the SFrame function descriptor. */
99 sframe_decoder_get_funcdesc (sfd_ctx
, funcidx
, &num_fres
,
100 &func_size
, &func_start_address
, &func_info
);
101 /* Calculate the virtual memory address for function start pc. */
102 func_start_pc_vma
= func_start_address
+ sec_addr
;
104 /* Mark FDEs with [m] where the FRE start address is interpreted as a
106 int fde_type_addrmask_p
= (SFRAME_V1_FUNC_FDE_TYPE (func_info
)
107 == SFRAME_FDE_TYPE_PCMASK
);
108 const char *fde_type_marker
109 = (fde_type_addrmask_p
? "[m]" : " ");
111 printf ("\n func idx [%d]: pc = 0x%"PRIx64
", size = %d bytes",
117 memset (temp
, 0, 100);
119 printf ("\n %-7s%-8s %-10s%-10s%-10s", "STARTPC", fde_type_marker
, "CFA", "FP", "RA");
120 for (j
= 0; j
< num_fres
; j
++)
122 sframe_decoder_get_fre (sfd_ctx
, funcidx
, j
, &fre
);
124 fre_start_pc_vma
= (fde_type_addrmask_p
126 : func_start_pc_vma
+ fre
.fre_start_addr
);
128 /* FIXME - fixup the err caching in array.
129 assert no error for base reg id. */
130 base_reg_id
= sframe_fre_get_base_reg_id (&fre
, &err
[0]);
131 cfa_offset
= sframe_fre_get_cfa_offset (sfd_ctx
, &fre
, &err
[0]);
132 fp_offset
= sframe_fre_get_fp_offset (sfd_ctx
, &fre
, &err
[1]);
133 ra_offset
= sframe_fre_get_ra_offset (sfd_ctx
, &fre
, &err
[2]);
137 printf (" %016"PRIx64
, fre_start_pc_vma
);
138 sprintf (temp
, "%s+%d", base_reg_str
[base_reg_id
], cfa_offset
);
139 printf (" %-10s", temp
);
141 /* Dump SP/FP info. */
142 memset (temp
, 0, 100);
144 sprintf (temp
, "c%+d", fp_offset
);
147 printf ("%-10s", temp
);
150 memset (temp
, 0, 100);
152 sprintf (temp
, "c%+d", ra_offset
);
155 printf ("%-10s", temp
);
160 dump_sframe_functions (sframe_decoder_ctx
*sfd_ctx
, uint64_t sec_addr
)
165 const char* subsec_name
= "Function Index";
166 printf ("\n %s :\n", subsec_name
);
168 num_fdes
= sframe_decoder_get_num_fidx (sfd_ctx
);
169 for (i
= 0; i
< num_fdes
; i
++)
171 dump_sframe_func_with_fres (sfd_ctx
, i
, sec_addr
);
177 dump_sframe (sframe_decoder_ctx
*sfd_ctx
, uint64_t sec_addr
)
179 dump_sframe_header (sfd_ctx
);
180 dump_sframe_functions (sfd_ctx
, sec_addr
);