[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] sframe.pk: rename ctf-frame.pk and refresh it
From: |
Jose E. Marchesi |
Subject: |
Re: [PATCH] sframe.pk: rename ctf-frame.pk and refresh it |
Date: |
Fri, 25 Nov 2022 01:37:18 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) |
Hi Indu.
OK for master.
Thanks!
> 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..d4262736 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.pk";
>
> -/* 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..f1d79b89
> --- /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..b99ec8fe
> --- /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);