[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH,V2] pickles: rename ctf-frame.pk to sframe.pk and refresh it
From: |
Indu Bhagat |
Subject: |
[PATCH,V2] pickles: rename ctf-frame.pk to sframe.pk and refresh it |
Date: |
Thu, 24 Nov 2022 22:59:18 -0800 |
Thanks for reviewing. Pushed V2 to master.
[Changes in V2]
- fixed the load statement to use sframe instead of "sframe.pk".
- fixed few occurences of tabs to use spaces instead.
- adjusted the commit message a bit.
[End of changes in V2]
--------------------
CTF Frame format has been renamed to SFrame: the Simple Frame format.
The support is now present in upstream binutils. This patch does the
renaming and updates the pickle to match the current state of the
specification.
2022-11-24 Indu Bhagat <indu.bhagat@oracle.com>
* pickles/Makefile.am (dist_pickles_DATA): Remove CTF Frame
pickles and add SFrame ones instead.
* pickles/ctf-frame.pk: Remove.
* pickles/ctf-frame-dump.pk: Rename from ..
* pickles/sframe-dump.pk: Rename to ..
* pickles/sframe.pk: Add new pickle.
* testsuite/Makefile.am (EXTRA_DIST): Add the new test.
* testsuite/poke.pickles/sframe-test.pk: New test.
---
pickles/Makefile.am | 2 +-
pickles/ctf-frame.pk | 200 ---------------
pickles/{ctf-frame-dump.pk => sframe-dump.pk} | 32 +--
pickles/sframe.pk | 234 ++++++++++++++++++
testsuite/Makefile.am | 1 +
testsuite/poke.pickles/sframe-test.pk | 62 +++++
6 files changed, 314 insertions(+), 217 deletions(-)
delete mode 100644 pickles/ctf-frame.pk
rename pickles/{ctf-frame-dump.pk => sframe-dump.pk} (60%)
create mode 100644 pickles/sframe.pk
create mode 100644 testsuite/poke.pickles/sframe-test.pk
diff --git a/pickles/Makefile.am b/pickles/Makefile.am
index 226621d1..f2b6ca50 100644
--- a/pickles/Makefile.am
+++ b/pickles/Makefile.am
@@ -19,7 +19,7 @@ picklesdir = $(pkgdatadir)/pickles
dist_pickles_DATA = elf-common.pk elf-64.pk elf-32.pk elf.pk ctf.pk
ctf-dump.pk leb128.pk \
bpf.pk btf.pk btf-ext.pk btf-dump.pk bmp.pk \
color.pk rgb24.pk id3v1.pk ios.pk diff.pk pk-table.pk \
- ctf-frame.pk ctf-frame-dump.pk \
+ sframe.pk sframe-dump.pk \
dwarf.pk dwarf-common.pk dwarf-frame.pk dwarf-pubnames.pk \
dwarf-types.pk time.pk argp.pk pktest.pk mbr.pk ustar.pk \
mcr.pk dwarf-expr.pk dwarf-info.pk id3v2.pk jffs2.pk
asn1-ber.pk \
diff --git a/pickles/ctf-frame.pk b/pickles/ctf-frame.pk
deleted file mode 100644
index 9e75c2b7..00000000
--- a/pickles/ctf-frame.pk
+++ /dev/null
@@ -1,200 +0,0 @@
-/* ctf-frame.pk - CTF Frame implementation for GNU poke. */
-
-/* Copyright (C) 2022 Free Software Foundation. */
-
-/* This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-load elf;
-
-/* Constants for CTF Preamble. */
-var CTF_FRAME_VERSION_1 = 1;
-var CTF_FRAME_MAGIC = 0xdee2;
-/* Various flags for CTF Frame section. */
-var CTF_FRAME_F_FDE_SORTED = 0x1;
-var CTF_FRAME_F_FRAME_POINTER = 0x2;
-
-type CTF_Frame_Preamble =
- struct
- {
- uint<16> ctfp_magic : ((ctfp_magic == CTF_FRAME_MAGIC)
- || (ctfp_magic == 0xe2de && set_endian
(!get_endian)))
- = CTF_FRAME_MAGIC;
-
- byte ctfp_version = CTF_FRAME_VERSION_1;
- byte ctfp_flags;
- };
-
-var CTF_FRAME_ROW_ENTRY_TYPE_ADDR1 = 1;
-var CTF_FRAME_ROW_ENTRY_TYPE_ADDR2 = 2;
-var CTF_FRAME_ROW_ENTRY_TYPE_ADDR4 = 3;
-
-/* CTF Frame FDE types.
- The CTF Frame format has two possible representations for functions. The
- choice of which type to use is made according to the instruction patterns
- in the relevant program stub. */
-
-/* Unwinders perform a (PC >= FRE_START_ADDR) to look up a matching FRE. */
-var CTF_FRAME_FUNC_DESC_ENTRY_TYPE_PCINC = 0;
-/* Unwinders perform a (PC & FRE_START_ADDR_AS_MASK >= FRE_START_ADDR_AS_MASK)
- to look up a matching FRE. */
-var CTF_FRAME_FUNC_DESC_ENTRY_TYPE_PCMASK = 1;
-
-/* CTF Frame FDE Function Info. */
-type CTF_Frame_Func_Info =
- struct
- {
- uint<3> unused;
- uint<1> fde_type : fde_type in [CTF_FRAME_FUNC_DESC_ENTRY_TYPE_PCINC,
- CTF_FRAME_FUNC_DESC_ENTRY_TYPE_PCMASK];
- uint<4> fre_type : fre_type in [CTF_FRAME_ROW_ENTRY_TYPE_ADDR1,
- CTF_FRAME_ROW_ENTRY_TYPE_ADDR2,
- CTF_FRAME_ROW_ENTRY_TYPE_ADDR4];
-};
-
-/* Supported ABIs/Arch. */
-var CTF_FRAME_ABI_AARCH64_ENDIAN_BIG = 1; /* AARCH64 little endian. */
-var CTF_FRAME_ABI_AARCH64_ENDIAN_LITTLE = 2; /* AARCH64 big endian. */
-var CTF_FRAME_ABI_AMD64_ENDIAN_LITTLE = 3; /* AMD64 little endian. */
-
-var CTF_FRAME_FRE_TYPE_BASIC = 0x0;
-
-type CTF_Frame_Header =
- struct
- {
- CTF_Frame_Preamble cth_frame_preamble;
- byte cth_frame_abi_arch : cth_frame_abi_arch in
[CTF_FRAME_ABI_AARCH64_ENDIAN_BIG,
-
CTF_FRAME_ABI_AARCH64_ENDIAN_LITTLE,
-
CTF_FRAME_ABI_AMD64_ENDIAN_LITTLE];
- int<8> cth_cfa_fixed_bp_offset;
- int<8> cth_cfa_fixed_ra_offset;
- uint<32> cth_num_fdes;
- uint<32> cth_num_fres;
- offset<uint32,B> cth_frelen;
-
- offset<uint32,B> cth_fdeoff;
- offset<uint32,B> cth_freoff;
- };
-
-var CTF_FRAME_FRE_OFFSET_1B = 0;
-var CTF_FRAME_FRE_OFFSET_2B = 1;
-var CTF_FRAME_FRE_OFFSET_4B = 2;
-/* At this time, a max of 3 distinct offsets are supported. */
-var CTF_FRAME_FRE_OFFSET_NUM = 3;
-
-/* A CTF FRE can be SP or BP based. */
-var CTF_FRAME_BASE_REG_BP = 0;
-var CTF_FRAME_BASE_REG_SP = 1;
-
-type CTF_Frame_FRE_Info =
- struct byte
- {
- uint<1> unused;
- uint<2> offset_size : offset_size in [CTF_FRAME_FRE_OFFSET_1B,
- CTF_FRAME_FRE_OFFSET_2B,
- CTF_FRAME_FRE_OFFSET_4B];
- uint<4> offset_num : offset_num <= CTF_FRAME_FRE_OFFSET_NUM;
- uint<1> base_reg_id : base_reg_id in [CTF_FRAME_BASE_REG_BP,
- CTF_FRAME_BASE_REG_SP];
- };
-
-/* CTF FRE. */
-type CTF_FRE_addr1 =
- struct
- {
- uint<8> fre_start_address;
- CTF_Frame_FRE_Info fre_info;
- union
- {
- int<8>[fre_info.offset_num] offsets_1B
- : fre_info.offset_size == CTF_FRAME_FRE_OFFSET_1B;
- int<16>[fre_info.offset_num] offsets_2B
- : fre_info.offset_size == CTF_FRAME_FRE_OFFSET_2B;
- int<32>[fre_info.offset_num] offsets_4B
- : fre_info.offset_size == CTF_FRAME_FRE_OFFSET_4B;
- } offsets;
- };
-
-type CTF_FRE_addr2 =
- struct
- {
- uint<16> fre_start_address;
- CTF_Frame_FRE_Info fre_info;
- union
- {
- int<8>[fre_info.offset_num] offsets_1B
- : fre_info.offset_size == CTF_FRAME_FRE_OFFSET_1B;
- int<16>[fre_info.offset_num] offsets_2B
- : fre_info.offset_size == CTF_FRAME_FRE_OFFSET_2B;
- int<32>[fre_info.offset_num] offsets_4B
- : fre_info.offset_size == CTF_FRAME_FRE_OFFSET_4B;
- } offsets;
- };
-
-type CTF_FRE_addr4=
- struct
- {
- uint<32> fre_start_address;
- CTF_Frame_FRE_Info fre_info;
- union
- {
- int<8>[fre_info.offset_num] offsets_1B
- : fre_info.offset_size == CTF_FRAME_FRE_OFFSET_1B;
- int<16>[fre_info.offset_num] offsets_2B
- : fre_info.offset_size == CTF_FRAME_FRE_OFFSET_2B;
- int<32>[fre_info.offset_num] offsets_4B
- : fre_info.offset_size == CTF_FRAME_FRE_OFFSET_4B;
- } offsets;
- };
-
-
-type CTF_Frame_Func_Desc_Entry =
- struct
- {
- uint<32> func_start_address;
- uint<32> func_size;
- offset<uint32,B> func_freoff;
- uint<32> func_num_fres;
- CTF_Frame_Func_Info func_info;
-
- method get_fres_addr1s = (offset<uint32,B> hdr_freoff) CTF_FRE_addr1[]:
- {
- var off = hdr_freoff + func_freoff;
- return CTF_FRE_addr1[func_num_fres] @ off;
- }
- method get_fres_addr2s = (offset<uint32,B> hdr_freoff) CTF_FRE_addr2[]:
- {
- var off = hdr_freoff + func_freoff;
- return CTF_FRE_addr2[func_num_fres] @ off;
- }
- method get_fres_addr4s = (offset<uint32,B> hdr_freoff) CTF_FRE_addr4[]:
- {
- var off = hdr_freoff + func_freoff;
- return CTF_FRE_addr4[func_num_fres] @ off;
- }
- };
-
-type CTF_Frame_section =
- struct
- {
- CTF_Frame_Header header;
-
- var func_index_off = OFFSET + header.cth_fdeoff;
- var func_index_size = header.cth_freoff - header.cth_fdeoff;
- var fre_off = OFFSET + header.cth_freoff;
- var fre_size = header.cth_frelen;
-
- CTF_Frame_Func_Desc_Entry[func_index_size] funcidx @ func_index_off;
- byte[fre_size] fres_data_bytes @ fre_off;
- };
diff --git a/pickles/ctf-frame-dump.pk b/pickles/sframe-dump.pk
similarity index 60%
rename from pickles/ctf-frame-dump.pk
rename to pickles/sframe-dump.pk
index 7fb2f222..89a24f53 100644
--- a/pickles/ctf-frame-dump.pk
+++ b/pickles/sframe-dump.pk
@@ -1,4 +1,4 @@
-/* ctf-frame-dump.pk - Utilities for dumping CTF Frame information. */
+/* sframe-dump.pk - Utilities for dumping SFrame information. */
/* Copyright (C) 2022 Free Software Foundation. */
@@ -16,49 +16,49 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* This file contains routines for dumping out CTF Frame information. */
+/* This file contains routines for dumping out SFrame information. */
-load "ctf-frame.pk";
+load sframe;
-/* Dump each FDE in the CTF Frame section. */
+/* Dump each FDE in the SFrame section. */
-fun ctf_frame_dump_fdes = (CTF_Frame_section ctf_frame_arg) void:
+fun sframe_dump_fdes = (SFrame_section sframe_arg) void:
{
var i = 0;
- for (index in ctf_frame_arg.funcidx)
+ for (index in sframe_arg.funcidx)
printf ("%u32d: %v \n", i++, index);
}
-/* Dump CTF Frame FREs. */
+/* Dump SFrame FREs. */
-fun ctf_frame_dump_fres = (CTF_Frame_section ctf_frame_arg) void:
+fun sframe_dump_fres = (SFrame_section sframe_arg) void:
{
var i = 0;
- for (func in ctf_frame_arg.funcidx)
+ for (func in sframe_arg.funcidx)
{
/* Get the FRE type. */
var fre_type = func.func_info.fre_type;
var num_fres = func.func_num_fres;
- var fre_off = ctf_frame_arg.header'size +
ctf_frame_arg.header.cth_freoff;
+ var fre_off = sframe_arg.header'size + sframe_arg.header.sfh_freoff;
- if (fre_type == CTF_FRAME_ROW_ENTRY_TYPE_ADDR1)
+ if (fre_type == SFRAME_FRE_TYPE_ADDR1)
{
- var fres = func.get_fres_addr1s (fre_off);
+ var fres = func.get_sframe_fre_addr1s (fre_off);
/* print fres. */
for (fre in fres)
printf ("%u32d: %v \n", i++, fre);
}
- else if (fre_type == CTF_FRAME_ROW_ENTRY_TYPE_ADDR2)
+ else if (fre_type == SFRAME_FRE_TYPE_ADDR2)
{
- var fres = func.get_fres_addr2s (fre_off);
+ var fres = func.get_sframe_fre_addr2s (fre_off);
/* print fres. */
for (fre in fres)
printf ("%u32d: %v \n", i++, fre);
}
- else if (fre_type == CTF_FRAME_ROW_ENTRY_TYPE_ADDR4)
+ else if (fre_type == SFRAME_FRE_TYPE_ADDR4)
{
- var fres = func.get_fres_addr4s (fre_off);
+ var fres = func.get_sframe_fre_addr4s (fre_off);
/* print fres. */
for (fre in fres)
printf ("%u32d: %v \n", i++, fre);
diff --git a/pickles/sframe.pk b/pickles/sframe.pk
new file mode 100644
index 00000000..c7acd8ec
--- /dev/null
+++ b/pickles/sframe.pk
@@ -0,0 +1,234 @@
+/* sframe.pk - SFrame implementation for GNU poke. */
+
+/* Copyright (C) 2022 Free Software Foundation. */
+
+/* This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* SFrame format.
+
+ SFrame format is the Simple Frame format, which is can be used to represent
+ information needed for vanilla backtracing. SFrame format keeps track of
+ minimal necessary information needed for backtracing:
+ - Canonical Frame Address (CFA)
+ - Frame Pointer (FP)
+ - Return Address (RA)
+
+ More details about the format are available in the upstream binutils-gdb
+ repository in :
+ - include/sframe.h header file, and
+ - libsframe/doc/sframe-spec.texi.
+*/
+
+load elf;
+
+/* SFrame format versions. */
+var SFRAME_VERSION_1 = 1;
+/* SFrame magic number. */
+var SFRAME_MAGIC = 0xdee2 as uint<16>;
+
+/* Various flags for SFrame. */
+
+/* Function Descriptor Entries are sorted on PC. */
+var SFRAME_F_FDE_SORTED = 0x1;
+/* Frame-pointer based unwinding. */
+var SFRAME_F_FRAME_POINTER = 0x2;
+
+var SFRAME_CFA_FIXED_FP_INVALID = 0;
+var SFRAME_CFA_FIXED_RA_INVALID = 0;
+
+type SFrame_Preamble =
+ struct
+ {
+ uint<16> sfp_magic : ((sfp_magic == SFRAME_MAGIC)
+ || (sfp_magic == 0xe2de && set_endian
(!get_endian)))
+ = SFRAME_MAGIC;
+
+ byte sfp_version = SFRAME_VERSION_1;
+ byte sfp_flags;
+ };
+
+/* SFrame FRE types. */
+var SFRAME_FRE_TYPE_ADDR1 = 0 as uint<4>,
+ SFRAME_FRE_TYPE_ADDR2 = 1 as uint<4>,
+ SFRAME_FRE_TYPE_ADDR4 = 2 as uint<4>;
+
+/* SFrame FDE types.
+ The SFrame format has two possible representations for functions. The
+ choice of which type to use is made according to the instruction patterns
+ in the relevant program stub. */
+
+/* Unwinders perform a (PC >= FRE_START_ADDR) to look up a matching FRE. */
+var SFRAME_FDE_TYPE_PCINC = 0 as uint<1>,
+/* Unwinders perform a (PC & FRE_START_ADDR_AS_MASK >= FRE_START_ADDR_AS_MASK)
+ to look up a matching FRE. */
+ SFRAME_FDE_TYPE_PCMASK = 1 as uint<1>;
+
+/* SFrame FDE Function Info. */
+type SFrame_Func_Info =
+ struct
+ {
+ uint<3> unused;
+ uint<1> fde_type : fde_type in [SFRAME_FDE_TYPE_PCINC,
+ SFRAME_FDE_TYPE_PCMASK];
+ uint<4> fre_type : fre_type in [SFRAME_FRE_TYPE_ADDR1,
+ SFRAME_FRE_TYPE_ADDR2,
+ SFRAME_FRE_TYPE_ADDR4];
+};
+
+/* Supported ABIs/Arch. */
+var SFRAME_ABI_AARCH64_ENDIAN_BIG = 1 as byte, /* AARCH64 little endian. */
+ SFRAME_ABI_AARCH64_ENDIAN_LITTLE = 2 as byte, /* AARCH64 big endian. */
+ SFRAME_ABI_AMD64_ENDIAN_LITTLE = 3 as byte; /* AMD64 little endian. */
+
+/* Currently auxilliary header is not being generated and used. The pickle
will
+ need updates when the SFrame format uses a non-zero number of bytes in
+ the auxilliary header. */
+var SFRAME_HEADER_AUXHDR_LEN_ZERO = 0 as uint<8>;
+
+type SFrame_Header =
+ struct
+ {
+ SFrame_Preamble sfh_preamble;
+ byte sfh_abi_arch : sfh_abi_arch in [SFRAME_ABI_AARCH64_ENDIAN_BIG,
+ SFRAME_ABI_AARCH64_ENDIAN_LITTLE,
+ SFRAME_ABI_AMD64_ENDIAN_LITTLE];
+ int<8> sfh_cfa_fixed_bp_offset;
+ int<8> sfh_cfa_fixed_ra_offset;
+ uint<8> sfh_auxhdr_len = SFRAME_HEADER_AUXHDR_LEN_ZERO;
+ uint<32> sfh_num_fdes;
+ uint<32> sfh_num_fres;
+ offset<uint32,B> sfh_frelen;
+
+ offset<uint32,B> sfh_fdeoff;
+ offset<uint32,B> sfh_freoff;
+ };
+
+var SFRAME_FRE_OFFSET_1B = 0 as uint<2>,
+ SFRAME_FRE_OFFSET_2B = 1 as uint<2>,
+ SFRAME_FRE_OFFSET_4B = 2 as uint<2>;
+
+/* In SFrame version 1, a max of 3 distinct offsets are supported. */
+var SFRAME_FRE_OFFSET_NUM = 3 as uint<2>;
+
+/* A SFRAME FRE can be SP or BP based. */
+var SFRAME_BASE_REG_BP = 0 as uint<1>,
+ SFRAME_BASE_REG_SP = 1 as uint<1>;
+
+type SFrame_FRE_Info =
+ struct byte
+ {
+ uint<1> unused;
+ uint<2> offset_size : offset_size in [SFRAME_FRE_OFFSET_1B,
+ SFRAME_FRE_OFFSET_2B,
+ SFRAME_FRE_OFFSET_4B];
+ uint<4> offset_num : offset_num <= SFRAME_FRE_OFFSET_NUM;
+ uint<1> base_reg_id : base_reg_id in [SFRAME_BASE_REG_BP,
+ SFRAME_BASE_REG_SP];
+ };
+
+/* SFRAME FRE with 8-bit start address offsets. */
+type SFrame_FRE_addr1 =
+ struct
+ {
+ uint<8> fre_start_address;
+ SFrame_FRE_Info fre_info;
+ union
+ {
+ int<8>[fre_info.offset_num] offsets_1B
+ : fre_info.offset_size == SFRAME_FRE_OFFSET_1B;
+ int<16>[fre_info.offset_num] offsets_2B
+ : fre_info.offset_size == SFRAME_FRE_OFFSET_2B;
+ int<32>[fre_info.offset_num] offsets_4B
+ : fre_info.offset_size == SFRAME_FRE_OFFSET_4B;
+ } offsets;
+ };
+
+/* SFRAME FRE with 16-bit start address offsets. */
+type SFrame_FRE_addr2 =
+ struct
+ {
+ uint<16> fre_start_address;
+ SFrame_FRE_Info fre_info;
+ union
+ {
+ int<8>[fre_info.offset_num] offsets_1B
+ : fre_info.offset_size == SFRAME_FRE_OFFSET_1B;
+ int<16>[fre_info.offset_num] offsets_2B
+ : fre_info.offset_size == SFRAME_FRE_OFFSET_2B;
+ int<32>[fre_info.offset_num] offsets_4B
+ : fre_info.offset_size == SFRAME_FRE_OFFSET_4B;
+ } offsets;
+ };
+
+/* SFRAME FRE with 32-bit start address offsets. */
+type SFrame_FRE_addr4=
+ struct
+ {
+ uint<32> fre_start_address;
+ SFrame_FRE_Info fre_info;
+ union
+ {
+ int<8>[fre_info.offset_num] offsets_1B
+ : fre_info.offset_size == SFRAME_FRE_OFFSET_1B;
+ int<16>[fre_info.offset_num] offsets_2B
+ : fre_info.offset_size == SFRAME_FRE_OFFSET_2B;
+ int<32>[fre_info.offset_num] offsets_4B
+ : fre_info.offset_size == SFRAME_FRE_OFFSET_4B;
+ } offsets;
+ };
+
+
+type SFrame_Func_Desc_Entry =
+ struct
+ {
+ uint<32> func_start_address;
+ uint<32> func_size;
+ offset<uint32,B> func_freoff;
+ uint<32> func_num_fres;
+ SFrame_Func_Info func_info;
+
+ method get_sframe_fre_addr1s
+ = (offset<uint32,B> hdr_freoff) SFrame_FRE_addr1[]:
+ {
+ var off = hdr_freoff + func_freoff;
+ return SFrame_FRE_addr1[func_num_fres] @ off;
+ }
+ method get_sframe_fre_addr2s
+ = (offset<uint32,B> hdr_freoff) SFrame_FRE_addr2[]:
+ {
+ var off = hdr_freoff + func_freoff;
+ return SFrame_FRE_addr2[func_num_fres] @ off;
+ }
+ method get_sframe_fre_addr4s
+ = (offset<uint32,B> hdr_freoff) SFrame_FRE_addr4[]:
+ {
+ var off = hdr_freoff + func_freoff;
+ return SFrame_FRE_addr4[func_num_fres] @ off;
+ }
+ };
+
+type SFrame_section =
+ struct
+ {
+ SFrame_Header header;
+
+ var func_index_off = OFFSET + header.sfh_fdeoff;
+ var func_index_size = header.sfh_freoff - header.sfh_fdeoff;
+ var fre_off = OFFSET + header.sfh_freoff;
+ var fre_size = header.sfh_frelen;
+
+ SFrame_Func_Desc_Entry[func_index_size] funcidx @ func_index_off;
+ byte[fre_size] fres_data_bytes @ fre_off;
+ };
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
index 6aa01775..3b90344a 100644
--- a/testsuite/Makefile.am
+++ b/testsuite/Makefile.am
@@ -600,6 +600,7 @@ EXTRA_DIST = \
poke.pickles/openpgp-test.pk \
poke.pickles/pe-test.pk \
poke.pickles/riscv-test.pk \
+ poke.pickles/sframe-test.pk \
poke.pickles/ustar-test.pk \
poke.pickles/color-test.pk \
poke.pickles/mbr-test.pk \
diff --git a/testsuite/poke.pickles/sframe-test.pk
b/testsuite/poke.pickles/sframe-test.pk
new file mode 100644
index 00000000..6d068433
--- /dev/null
+++ b/testsuite/poke.pickles/sframe-test.pk
@@ -0,0 +1,62 @@
+/* sframe-test.pk - Tests for the SFrame pickle. */
+
+/* Copyright (C) 2022 Free Software Foundation. */
+
+/* This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+load pktest;
+load sframe;
+
+var data = open ("*data*");
+
+/* Generated using:
+ * static int cnt;
+ * int foo() { return ++cnt; }
+ * int main() { return foo(); }
+ *
+ * gcc -O0 -Wa,--gsframe -c
+ */
+uint<8>[92] @ data : 0#B = [
+ 0xe2UB, 0xdeUB, 0x01UB, 0x00UB, 0x03UB, 0x00UB, 0xf8UB, 0x00UB,
+ 0x02UB, 0x00UB, 0x00UB, 0x00UB, 0x08UB, 0x00UB, 0x00UB, 0x00UB,
+ 0x1eUB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB,
+ 0x22UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB,
+ 0x1bUB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB,
+ 0x04UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB,
+ 0x00UB, 0x10UB, 0x00UB, 0x00UB, 0x00UB, 0x0fUB, 0x00UB, 0x00UB,
+ 0x00UB, 0x04UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x03UB,
+ 0x08UB, 0x01UB, 0x05UB, 0x10UB, 0xf0UB, 0x04UB, 0x04UB, 0x10UB,
+ 0xf0UB, 0x1aUB, 0x05UB, 0x08UB, 0xf0UB, 0x00UB, 0x03UB, 0x08UB,
+ 0x01UB, 0x05UB, 0x10UB, 0xf0UB, 0x04UB, 0x04UB, 0x10UB, 0xf0UB,
+ 0x0fUB, 0x05UB, 0x08UB, 0xf0UB
+];
+
+var tests = [
+ PkTest {
+ name = "read sframe header",
+ func = lambda (string name) void:
+ {
+ var hdr = SFrame_Header @ data : 0#B;
+
+ assert (hdr.sfh_preamble.sfp_magic == 0xdee2);
+ assert (hdr.sfh_abi_arch == SFRAME_ABI_AMD64_ENDIAN_LITTLE);
+ assert (hdr.sfh_num_fdes == 2);
+ assert (hdr.sfh_num_fres == 8);
+ },
+ },
+];
+
+var ok = pktest_run (tests);
+exit (ok ? 0 : 1);
--
2.37.2