public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Indu Bhagat <indu.bhagat@oracle.com>
To: binutils@sourceware.org
Cc: nickc@redhat.com, weimin.pan@oracle.com,
	Indu Bhagat <indu.bhagat@oracle.com>
Subject: [PATCH,V1 07/14] readelf/objdump: support for SFrame section
Date: Thu, 29 Sep 2022 17:04:33 -0700	[thread overview]
Message-ID: <20220930000440.1672106-8-indu.bhagat@oracle.com> (raw)
In-Reply-To: <20220930000440.1672106-1-indu.bhagat@oracle.com>

This patch adds support for SFrame in readelf and objdump.

include/ChangeLog:

	* sframe-api.h (dump_sframe): New function declaration.

ChangeLog:

	* binutils/Makefile.am: Add dependency on libsframe for
	readelf and objdump.
	* binutils/Makefile.in: Regenerate.
	* binutils/doc/binutils.texi: Document --sframe=[section].
	* binutils/doc/sframe.options.texi: New file.
	* binutils/objdump.c: Add support for SFrame format.
	* binutils/readelf.c: Likewise.
	* include/sframe-api.h: Add new API for dumping .sframe
	section.
	* libsframe/Makefile.am: Add sframe-dump.c.
	* libsframe/Makefile.in: Regenerate.
	* libsframe/sframe-dump.c: New file.
---
 binutils/Makefile.am             |   8 +-
 binutils/Makefile.in             |   8 +-
 binutils/doc/binutils.texi       |   4 +
 binutils/doc/sframe.options.texi |  10 ++
 binutils/objdump.c               |  76 +++++++++++++
 binutils/readelf.c               |  46 ++++++++
 include/sframe-api.h             |   3 +
 libsframe/Makefile.am            |   3 +-
 libsframe/Makefile.in            |  12 +-
 libsframe/sframe-dump.c          | 181 +++++++++++++++++++++++++++++++
 10 files changed, 339 insertions(+), 12 deletions(-)
 create mode 100644 binutils/doc/sframe.options.texi
 create mode 100644 libsframe/sframe-dump.c

diff --git a/binutils/Makefile.am b/binutils/Makefile.am
index b93684d9a65..3343e390276 100644
--- a/binutils/Makefile.am
+++ b/binutils/Makefile.am
@@ -228,7 +228,7 @@ installcheck-local:
 # which depends on libintl, since we don't know whether LIBINTL_DEP will be
 # non-empty until configure time.  Ugh!
 size_DEPENDENCIES =      $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
-objdump_DEPENDENCIES =   $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB) $(OPCODES) $(LIBCTF) $(OBJDUMP_PRIVATE_OFILES)
+objdump_DEPENDENCIES =   $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB) $(OPCODES) $(LIBCTF) $(OBJDUMP_PRIVATE_OFILES) $(LIBSFRAME)
 nm_new_DEPENDENCIES =    $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
 ar_DEPENDENCIES =        $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
 strings_DEPENDENCIES =   $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
@@ -243,7 +243,7 @@ dlltool_DEPENDENCIES =   $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
 windres_DEPENDENCIES =   $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
 windmc_DEPENDENCIES =    $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
 addr2line_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
-readelf_DEPENDENCIES =   $(LIBINTL_DEP) $(LIBIBERTY) $(LIBCTF_NOBFD)
+readelf_DEPENDENCIES =   $(LIBINTL_DEP) $(LIBIBERTY) $(LIBCTF_NOBFD) $(LIBSFRAME)
 elfedit_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY)
 dllwrap_DEPENDENCIES =   $(LIBINTL_DEP) $(LIBIBERTY)
 bfdtest1_DEPENDENCIES =  $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
@@ -258,7 +258,7 @@ objcopy_SOURCES = objcopy.c not-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS)
 strings_SOURCES = strings.c $(BULIBS)
 
 readelf_SOURCES = readelf.c version.c unwind-ia64.c dwarf.c demanguse.c $(ELFLIBS)
-readelf_LDADD   = $(LIBCTF_NOBFD) $(LIBINTL) $(LIBIBERTY) $(ZLIB) $(DEBUGINFOD_LIBS) $(MSGPACK_LIBS)
+readelf_LDADD   = $(LIBCTF_NOBFD) $(LIBINTL) $(LIBIBERTY) $(ZLIB) $(DEBUGINFOD_LIBS) $(MSGPACK_LIBS) $(LIBSFRAME)
 
 elfedit_SOURCES = elfedit.c version.c $(ELFLIBS)
 elfedit_LDADD = $(LIBINTL) $(LIBIBERTY)
@@ -269,7 +269,7 @@ nm_new_SOURCES = nm.c demanguse.c $(BULIBS)
 
 objdump_SOURCES = objdump.c dwarf.c prdbg.c demanguse.c $(DEBUG_SRCS) $(BULIBS) $(ELFLIBS)
 EXTRA_objdump_SOURCES = od-xcoff.c
-objdump_LDADD = $(OBJDUMP_PRIVATE_OFILES) $(OPCODES) $(LIBCTF) $(BFDLIB) $(LIBIBERTY) $(LIBINTL) $(DEBUGINFOD_LIBS)
+objdump_LDADD = $(OBJDUMP_PRIVATE_OFILES) $(OPCODES) $(LIBCTF) $(BFDLIB) $(LIBIBERTY) $(LIBINTL) $(DEBUGINFOD_LIBS) $(LIBSFRAME)
 
 objdump.@OBJEXT@:objdump.c
 if am__fastdepCC
diff --git a/binutils/Makefile.in b/binutils/Makefile.in
index 6cbdba1da26..f07cd871d93 100644
--- a/binutils/Makefile.in
+++ b/binutils/Makefile.in
@@ -766,7 +766,7 @@ CC_FOR_TARGET = ` \
 # which depends on libintl, since we don't know whether LIBINTL_DEP will be
 # non-empty until configure time.  Ugh!
 size_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
-objdump_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB) $(OPCODES) $(LIBCTF) $(OBJDUMP_PRIVATE_OFILES)
+objdump_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB) $(OPCODES) $(LIBCTF) $(OBJDUMP_PRIVATE_OFILES) $(LIBSFRAME)
 nm_new_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
 ar_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
 strings_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
@@ -781,7 +781,7 @@ dlltool_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
 windres_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
 windmc_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
 addr2line_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
-readelf_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(LIBCTF_NOBFD)
+readelf_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(LIBCTF_NOBFD) $(LIBSFRAME)
 elfedit_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY)
 dllwrap_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY)
 bfdtest1_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
@@ -791,14 +791,14 @@ size_SOURCES = size.c $(BULIBS)
 objcopy_SOURCES = objcopy.c not-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS)
 strings_SOURCES = strings.c $(BULIBS)
 readelf_SOURCES = readelf.c version.c unwind-ia64.c dwarf.c demanguse.c $(ELFLIBS)
-readelf_LDADD = $(LIBCTF_NOBFD) $(LIBINTL) $(LIBIBERTY) $(ZLIB) $(DEBUGINFOD_LIBS) $(MSGPACK_LIBS)
+readelf_LDADD = $(LIBCTF_NOBFD) $(LIBINTL) $(LIBIBERTY) $(ZLIB) $(DEBUGINFOD_LIBS) $(MSGPACK_LIBS) $(LIBSFRAME)
 elfedit_SOURCES = elfedit.c version.c $(ELFLIBS)
 elfedit_LDADD = $(LIBINTL) $(LIBIBERTY)
 strip_new_SOURCES = objcopy.c is-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS)
 nm_new_SOURCES = nm.c demanguse.c $(BULIBS)
 objdump_SOURCES = objdump.c dwarf.c prdbg.c demanguse.c $(DEBUG_SRCS) $(BULIBS) $(ELFLIBS)
 EXTRA_objdump_SOURCES = od-xcoff.c
-objdump_LDADD = $(OBJDUMP_PRIVATE_OFILES) $(OPCODES) $(LIBCTF) $(BFDLIB) $(LIBIBERTY) $(LIBINTL) $(DEBUGINFOD_LIBS)
+objdump_LDADD = $(OBJDUMP_PRIVATE_OFILES) $(OPCODES) $(LIBCTF) $(BFDLIB) $(LIBIBERTY) $(LIBINTL) $(DEBUGINFOD_LIBS) $(LIBSFRAME)
 cxxfilt_SOURCES = cxxfilt.c $(BULIBS)
 ar_SOURCES = arparse.y arlex.l ar.c not-ranlib.c arsup.c rename.c binemul.c \
 	emul_$(EMULATION).c $(BULIBS)
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index 34a4164eb94..979f93e7e3f 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -2262,6 +2262,7 @@ objdump [@option{-a}|@option{--archive-headers}]
         [@option{-wE}|@option{--dwarf=do-not-use-debuginfod}]
         [@option{-L}|@option{--process-links}]
         [@option{--ctf=}@var{section}]
+        [@option{--sframe=}@var{section}]
         [@option{-G}|@option{--stabs}]
         [@option{-t}|@option{--syms}]
         [@option{-T}|@option{--dynamic-syms}]
@@ -2842,6 +2843,8 @@ Enable additional checks for consistency of Dwarf information.
 
 @include ctf.options.texi
 
+@include sframe.options.texi
+
 @item -G
 @itemx --stabs
 @cindex stab
@@ -4929,6 +4932,7 @@ readelf [@option{-a}|@option{--all}]
         [@option{--ctf-parent=}@var{section}]
         [@option{--ctf-symbols=}@var{section}]
         [@option{--ctf-strings=}@var{section}]
+        [@option{--sframe=}@var{section}]
         [@option{-I}|@option{--histogram}]
         [@option{-v}|@option{--version}]
         [@option{-W}|@option{--wide}]
diff --git a/binutils/doc/sframe.options.texi b/binutils/doc/sframe.options.texi
new file mode 100644
index 00000000000..9e23679a3da
--- /dev/null
+++ b/binutils/doc/sframe.options.texi
@@ -0,0 +1,10 @@
+@c This file contains the entry for the --sframe option that is
+@c common to both readelf and objdump.
+
+@item --sframe[=@var{section}]
+@cindex SFrame
+
+Display the contents of the specified SFrame section.
+
+By default, display the name of the section named @var{.sframe}, which is the
+name emitted by @command{ld}.
diff --git a/binutils/objdump.c b/binutils/objdump.c
index 6610906f83e..a97dc6f935a 100644
--- a/binutils/objdump.c
+++ b/binutils/objdump.c
@@ -58,6 +58,7 @@
 #include "demanguse.h"
 #include "dwarf.h"
 #include "ctf-api.h"
+#include "sframe-api.h"
 #include "getopt.h"
 #include "safe-ctype.h"
 #include "dis-asm.h"
@@ -108,6 +109,8 @@ static int dump_stab_section_info;	/* --stabs */
 static int dump_ctf_section_info;       /* --ctf */
 static char *dump_ctf_section_name;
 static char *dump_ctf_parent_name;	/* --ctf-parent */
+static int dump_sframe_section_info;	/* --sframe */
+static char *dump_sframe_section_name;
 static int do_demangle;			/* -C, --demangle */
 static bool disassemble;		/* -d */
 static bool disassemble_all;		/* -D */
@@ -316,6 +319,9 @@ usage (FILE *stream, int status)
   fprintf (stream, _("\
       --ctf[=SECTION]      Display CTF info from SECTION, (default `.ctf')\n"));
 #endif
+  fprintf (stream, _("\
+      --sframe[=SECTION]\n\
+                           Display SFrame info from SECTION, (default '.sframe')\n"));
   fprintf (stream, _("\
   -t, --syms               Display the contents of the symbol table(s)\n"));
   fprintf (stream, _("\
@@ -462,6 +468,7 @@ enum option_values
     OPTION_CTF,
     OPTION_CTF_PARENT,
 #endif
+    OPTION_SFRAME,
     OPTION_VISUALIZE_JUMPS,
     OPTION_DISASSEMBLER_COLOR
   };
@@ -516,6 +523,7 @@ static struct option long_options[]=
   {"reloc", no_argument, NULL, 'r'},
   {"section", required_argument, NULL, 'j'},
   {"section-headers", no_argument, NULL, 'h'},
+  {"sframe", optional_argument, NULL, OPTION_SFRAME},
   {"show-raw-insn", no_argument, &show_raw_insn, 1},
   {"source", no_argument, NULL, 'S'},
   {"source-comment", optional_argument, NULL, OPTION_SOURCE_COMMENT},
@@ -4798,6 +4806,66 @@ dump_ctf (bfd *abfd ATTRIBUTE_UNUSED, const char *sect_name ATTRIBUTE_UNUSED,
 	  const char *parent_name ATTRIBUTE_UNUSED) {}
 #endif
 
+static bfd_byte*
+read_section_sframe (bfd *abfd, const char *sect_name, bfd_size_type *size_ptr,
+		     bfd_vma *sframe_vma)
+{
+  asection *sframe_sect;
+  bfd_byte *contents;
+
+  sframe_sect = bfd_get_section_by_name (abfd, sect_name);
+  if (sframe_sect == NULL)
+    {
+      printf (_("No %s section present\n\n"),
+	      sanitize_string (sect_name));
+      return NULL;
+    }
+
+  if (!bfd_malloc_and_get_section (abfd, sframe_sect, &contents))
+    {
+      non_fatal (_("reading %s section of %s failed: %s"),
+		 sect_name, bfd_get_filename (abfd),
+		 bfd_errmsg (bfd_get_error ()));
+      exit_status = 1;
+      free (contents);
+      return NULL;
+    }
+
+  *size_ptr = bfd_section_size (sframe_sect);
+  *sframe_vma = bfd_section_vma (sframe_sect);
+
+  return contents;
+}
+
+static void
+dump_section_sframe (bfd *abfd ATTRIBUTE_UNUSED,
+		     const char * sect_name)
+{
+  sframe_decoder_ctx *sfd_ctx = NULL;
+  size_t sf_size;
+  bfd_byte *sframe_data = NULL;
+  bfd_vma sf_vma;
+  int err = 0;
+
+  if (sect_name == NULL)
+    sect_name = ".sframe";
+
+  sframe_data = read_section_sframe (abfd, sect_name, &sf_size, &sf_vma);
+
+  if (sframe_data == NULL)
+    bfd_fatal (bfd_get_filename (abfd));
+
+  /* Decode the contents of the section.  */
+  sfd_ctx = sframe_decode ((const char*)sframe_data, sf_size, &err);
+  if (!sfd_ctx)
+    bfd_fatal (bfd_get_filename (abfd));
+
+  printf (_("Contents of the SFrame section %s:"),
+	  sanitize_string (sect_name));
+  /* Dump the contents as text.  */
+  dump_sframe (sfd_ctx, sf_vma);
+}
+
 \f
 static void
 dump_bfd_private_header (bfd *abfd)
@@ -5551,6 +5619,8 @@ dump_bfd (bfd *abfd, bool is_mainfile)
     {
       if (dump_ctf_section_info)
 	dump_ctf (abfd, dump_ctf_section_name, dump_ctf_parent_name);
+      if (dump_sframe_section_info)
+	dump_section_sframe (abfd, dump_sframe_section_name);
       if (dump_stab_section_info)
 	dump_stabs (abfd);
       if (dump_reloc_info && ! disassemble)
@@ -6048,6 +6118,12 @@ main (int argc, char **argv)
 	  dump_ctf_parent_name = xstrdup (optarg);
 	  break;
 #endif
+	case OPTION_SFRAME:
+	  dump_sframe_section_info = true;
+	  if (optarg)
+	    dump_sframe_section_name = xstrdup (optarg);
+	  seenflag = true;
+	  break;
 	case 'G':
 	  dump_stab_section_info = true;
 	  seenflag = true;
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 241c44ecfa1..ff223e48cee 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -60,6 +60,7 @@
 #include "demanguse.h"
 #include "dwarf.h"
 #include "ctf-api.h"
+#include "sframe-api.h"
 #include "demangle.h"
 
 #include "elf/common.h"
@@ -187,6 +188,7 @@ typedef struct elf_section_list
 #define STRING_DUMP     (1 << 3)	/* The -p command line switch.  */
 #define RELOC_DUMP      (1 << 4)	/* The -R command line switch.  */
 #define CTF_DUMP	(1 << 5)	/* The --ctf command line switch.  */
+#define SFRAME_DUMP	(1 << 6)	/* The --sframe command line switch.  */
 
 typedef unsigned char dump_type;
 
@@ -230,6 +232,7 @@ static bool do_version = false;
 static bool do_histogram = false;
 static bool do_debugging = false;
 static bool do_ctf = false;
+static bool do_sframe = false;
 static bool do_arch = false;
 static bool do_notes = false;
 static bool do_archive_index = false;
@@ -5068,6 +5071,7 @@ enum long_option_values
   OPTION_CTF_PARENT,
   OPTION_CTF_SYMBOLS,
   OPTION_CTF_STRINGS,
+  OPTION_SFRAME_DUMP,
   OPTION_WITH_SYMBOL_VERSIONS,
   OPTION_RECURSE_LIMIT,
   OPTION_NO_RECURSE_LIMIT,
@@ -5130,6 +5134,7 @@ static struct option options[] =
   {"ctf-strings",      required_argument, 0, OPTION_CTF_STRINGS},
   {"ctf-parent",       required_argument, 0, OPTION_CTF_PARENT},
 #endif
+  {"sframe",	       required_argument, 0, OPTION_SFRAME_DUMP},
   {"sym-base",	       optional_argument, 0, OPTION_SYM_BASE},
 
   {0,		       no_argument, 0, 0}
@@ -5270,6 +5275,8 @@ usage (FILE * stream)
   --ctf-strings=<number|name>\n\
                          Use section <number|name> as the CTF external strtab\n"));
 #endif
+  fprintf (stream, _("\
+  --sframe=<name>        Display SFrame info from section name\n"));
 
 #ifdef SUPPORT_DISASSEMBLY
   fprintf (stream, _("\
@@ -5543,6 +5550,10 @@ parse_args (struct dump_data *dumpdata, int argc, char ** argv)
 	  free (dump_ctf_parent_name);
 	  dump_ctf_parent_name = strdup (optarg);
 	  break;
+	case OPTION_SFRAME_DUMP:
+	  do_sframe = true;
+	  request_dump (dumpdata, SFRAME_DUMP);
+	  break;
 	case OPTION_DYN_SYMS:
 	  do_dyn_syms = true;
 	  break;
@@ -15819,6 +15830,36 @@ dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
 }
 #endif
 
+static bool
+dump_section_as_sframe (Elf_Internal_Shdr * section, Filedata * filedata)
+{
+  void *		  data = NULL;
+  sframe_decoder_ctx	  *sfd_ctx = NULL;
+  const char *print_name = printable_section_name (filedata, section);
+
+  bool ret = true;
+  size_t sf_size;
+  int err = 0;
+
+  data = get_section_contents (section, filedata);
+  sf_size = section->sh_size;
+  /* Decode the contents of the section.  */
+  sfd_ctx = sframe_decode ((const char*)data, sf_size, &err);
+  if (!sfd_ctx)
+    {
+      ret = false;
+      goto fail;
+    }
+
+  printf (_("Contents of the SFrame section %s:"), print_name);
+  /* Dump the contents as text.  */
+  dump_sframe (sfd_ctx, section->sh_addr);
+
+ fail:
+  free (data);
+  return ret;
+}
+
 static bool
 load_specific_debug_section (enum dwarf_section_display_enum  debug,
 			     const Elf_Internal_Shdr *        sec,
@@ -16318,6 +16359,11 @@ process_section_contents (Filedata * filedata)
 	    res = false;
 	}
 #endif
+      if (dump & SFRAME_DUMP)
+	{
+	  if (! dump_section_as_sframe (section, filedata))
+	    res = false;
+	}
     }
 
   if (! filedata->is_separate)
diff --git a/include/sframe-api.h b/include/sframe-api.h
index 351cf1f7398..7712bbf4b53 100644
--- a/include/sframe-api.h
+++ b/include/sframe-api.h
@@ -145,6 +145,9 @@ sframe_decoder_get_funcdesc (sframe_decoder_ctx *ctx,
 				int32_t *func_start_address,
 				unsigned char *func_info);
 
+/* SFrame textual dump.  */
+extern void
+dump_sframe (sframe_decoder_ctx *decoder, uint64_t addr);
 
 /* Get the base reg id from the FRE info.  Sets errp if fails.  */
 extern unsigned int
diff --git a/libsframe/Makefile.am b/libsframe/Makefile.am
index 3a2218f1e5e..31576429816 100644
--- a/libsframe/Makefile.am
+++ b/libsframe/Makefile.am
@@ -37,7 +37,6 @@ include_HEADERS =
 noinst_LTLIBRARIES = libsframe.la
 endif
 
-libsframe_la_SOURCES = sframe.c sframe-error.c
+libsframe_la_SOURCES = sframe.c sframe-dump.c sframe-error.c
 libsframe_la_CPPFLAGS = -D_GNU_SOURCE -I$(srcdir) -I$(srcdir)/../include \
 			-I$(srcdir)/../libctf
-
diff --git a/libsframe/Makefile.in b/libsframe/Makefile.in
index 79ea3a9209d..0db5ff954b9 100644
--- a/libsframe/Makefile.in
+++ b/libsframe/Makefile.in
@@ -161,7 +161,7 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"
 LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
 libsframe_la_LIBADD =
 am_libsframe_la_OBJECTS = libsframe_la-sframe.lo \
-	libsframe_la-sframe-error.lo
+	libsframe_la-sframe-dump.lo libsframe_la-sframe-error.lo
 libsframe_la_OBJECTS = $(am_libsframe_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -430,7 +430,7 @@ AM_CFLAGS = -std=gnu99 @ac_libsframe_warn_cflags@ @warn@ @c_warn@ @WARN_PEDANTIC
 @INSTALL_LIBBFD_FALSE@include_HEADERS = 
 @INSTALL_LIBBFD_TRUE@include_HEADERS = $(INCDIR)/sframe.h $(INCDIR)/sframe-api.h
 @INSTALL_LIBBFD_FALSE@noinst_LTLIBRARIES = libsframe.la
-libsframe_la_SOURCES = sframe.c sframe-error.c
+libsframe_la_SOURCES = sframe.c sframe-dump.c sframe-error.c
 libsframe_la_CPPFLAGS = -D_GNU_SOURCE -I$(srcdir) -I$(srcdir)/../include \
 			-I$(srcdir)/../libctf
 
@@ -543,6 +543,7 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsframe_la-sframe-dump.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsframe_la-sframe-error.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsframe_la-sframe.Plo@am__quote@
 
@@ -574,6 +575,13 @@ libsframe_la-sframe.lo: sframe.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsframe_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsframe_la-sframe.lo `test -f 'sframe.c' || echo '$(srcdir)/'`sframe.c
 
+libsframe_la-sframe-dump.lo: sframe-dump.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsframe_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsframe_la-sframe-dump.lo -MD -MP -MF $(DEPDIR)/libsframe_la-sframe-dump.Tpo -c -o libsframe_la-sframe-dump.lo `test -f 'sframe-dump.c' || echo '$(srcdir)/'`sframe-dump.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libsframe_la-sframe-dump.Tpo $(DEPDIR)/libsframe_la-sframe-dump.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='sframe-dump.c' object='libsframe_la-sframe-dump.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsframe_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsframe_la-sframe-dump.lo `test -f 'sframe-dump.c' || echo '$(srcdir)/'`sframe-dump.c
+
 libsframe_la-sframe-error.lo: sframe-error.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsframe_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsframe_la-sframe-error.lo -MD -MP -MF $(DEPDIR)/libsframe_la-sframe-error.Tpo -c -o libsframe_la-sframe-error.lo `test -f 'sframe-error.c' || echo '$(srcdir)/'`sframe-error.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libsframe_la-sframe-error.Tpo $(DEPDIR)/libsframe_la-sframe-error.Plo
diff --git a/libsframe/sframe-dump.c b/libsframe/sframe-dump.c
new file mode 100644
index 00000000000..8ad1580afcf
--- /dev/null
+++ b/libsframe/sframe-dump.c
@@ -0,0 +1,181 @@
+/* sframe-dump.c - Textual dump of .sframe.
+
+   Copyright (C) 2022 Free Software Foundation, Inc.
+
+   his file is part of libsframe.
+
+   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/>.  */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "sframe-impl.h"
+
+#define SFRAME_HEADER_FLAGS_STR_MAX_LEN 50
+
+static void
+dump_sframe_header (sframe_decoder_ctx *sfd_ctx)
+{
+  const char *verstr = NULL;
+  const sframe_header *header = &(sfd_ctx->sfd_header);
+
+  /* Prepare SFrame section version string.  */
+  const char *version_names[]
+    = { "NULL",
+	"SFRAME_VERSION_1" };
+  unsigned char ver = header->sfh_preamble.sfp_version;
+  if (ver <= SFRAME_VERSION)
+    verstr = version_names[ver];
+
+  /* Prepare SFrame section flags string.  */
+  unsigned char flags = header->sfh_preamble.sfp_flags;
+  char *flags_str
+    = (char*) calloc (sizeof (char), SFRAME_HEADER_FLAGS_STR_MAX_LEN);
+  if (flags)
+    {
+      const char *flag_names[]
+	= { "SFRAME_F_FDE_SORTED",
+	    "SFRAME_F_FRAME_POINTER" };
+      unsigned char flags = header->sfh_preamble.sfp_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");
+
+  const char* subsec_name = "Header";
+  printf ("\n");
+  printf ("  %s :\n", subsec_name);
+  printf ("\n");
+  printf ("    Version: %s\n", verstr);
+  printf ("    Flags: %s\n", flags_str);
+  printf ("    Num FDEs: %d\n", header->sfh_num_fdes);
+  printf ("    Num FREs: %d\n", header->sfh_num_fres);
+
+  free (flags_str);
+}
+
+static void
+dump_sframe_func_with_fres (sframe_decoder_ctx *sfd_ctx,
+			    unsigned int funcidx,
+			    uint64_t sec_addr)
+{
+  uint32_t j = 0;
+  uint32_t num_fres = 0;
+  uint32_t func_size = 0;
+  int32_t func_start_address = 0;
+  unsigned char func_info = 0;
+
+  uint64_t func_start_pc_vma = 0;
+  uint64_t fre_start_pc_vma = 0;
+  const char *base_reg_str[] = {"fp", "sp"};
+  int32_t cfa_offset = 0;
+  int32_t fp_offset = 0;
+  int32_t ra_offset = 0;
+  unsigned int base_reg_id = 0;
+  int err[3] = {0, 0, 0};
+
+  sframe_frame_row_entry fre;
+
+  /* Get the SFrame function descriptor.  */
+  sframe_decoder_get_funcdesc (sfd_ctx, funcidx, &num_fres,
+			       &func_size, &func_start_address, &func_info);
+  sframe_assert (func_info);
+  /* Calculate the virtual memory address for function start pc.  */
+  func_start_pc_vma = func_start_address + sec_addr;
+
+  /* Mark FDEs with [m] where the FRE start address is interpreted as a
+     mask.  */
+  int fde_type_addrmask_p = (SFRAME_V1_FUNC_FDE_TYPE (func_info)
+			     == SFRAME_FDE_TYPE_PCMASK);
+  const char *fde_type_marker
+    = (fde_type_addrmask_p ? "[m]" : "   ");
+
+  printf ("\n    func idx [%d]: pc = 0x%lx, size = %d bytes",
+	  funcidx,
+	  func_start_pc_vma,
+	  func_size);
+
+  char temp[100];
+  memset (temp, 0, 100);
+
+  printf ("\n    %-7s%-8s %-10s%-10s%-10s", "STARTPC", fde_type_marker, "CFA", "FP", "RA");
+  for (j = 0; j < num_fres; j++)
+    {
+      sframe_decoder_get_fre (sfd_ctx, funcidx, j, &fre);
+
+      fre_start_pc_vma = (fde_type_addrmask_p
+			  ? fre.fre_start_addr
+			  : func_start_pc_vma + fre.fre_start_addr);
+
+      /* FIXME - fixup the err caching in array.
+	 assert no error for base reg id.  */
+      base_reg_id = sframe_fre_get_base_reg_id (&fre, &err[0]);
+      cfa_offset = sframe_fre_get_cfa_offset (&fre, &err[0]);
+      fp_offset = sframe_fre_get_fp_offset (&fre, &err[1]);
+      ra_offset = sframe_fre_get_ra_offset (&fre, &err[2]);
+
+      /* Dump CFA info.  */
+      printf ("\n");
+      printf ("    %016lx", fre_start_pc_vma);
+      sprintf (temp, "%s+%d", base_reg_str[base_reg_id], cfa_offset);
+      printf ("  %-10s", temp);
+
+      /* Dump SP/FP info.  */
+      memset (temp, 0, 100);
+      if (err[1] == 0)
+	sprintf (temp, "c%+d", fp_offset);
+      else
+	strcpy (temp, "u");
+      printf ("%-10s", temp);
+
+      /* Dump RA info.  */
+      memset (temp, 0, 100);
+      if (err[2] == 0)
+	sprintf (temp, "c%+d", ra_offset);
+      else
+	strcpy (temp, "u");
+      printf ("%-10s", temp);
+    }
+}
+
+static void
+dump_sframe_functions (sframe_decoder_ctx *sfd_ctx, uint64_t sec_addr)
+{
+  uint32_t i;
+  uint32_t num_fdes;
+
+  const char* subsec_name = "Function Index";
+  printf ("\n  %s :\n", subsec_name);
+
+  num_fdes = sframe_decoder_get_num_fidx (sfd_ctx);
+  for (i = 0; i < num_fdes; i++)
+    {
+      dump_sframe_func_with_fres (sfd_ctx, i, sec_addr);
+      printf ("\n");
+    }
+}
+
+void
+dump_sframe (sframe_decoder_ctx *sfd_ctx, uint64_t sec_addr)
+{
+  dump_sframe_header (sfd_ctx);
+  dump_sframe_functions (sfd_ctx, sec_addr);
+}
-- 
2.37.2


  parent reply	other threads:[~2022-09-30  0:10 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-02  8:04 [PATCH,V6 00/10] Definition and Implementation of CTF Frame format Indu Bhagat
2022-08-02  8:04 ` [PATCH,V6 01/10] ctf-frame.h: Add CTF Frame format definition Indu Bhagat
2022-08-15 12:04   ` Nick Clifton
2022-08-02  8:04 ` [PATCH,V6 02/10] gas: add new command line option --gctf-frame Indu Bhagat
2022-08-15 12:07   ` Nick Clifton
2022-08-02  8:04 ` [PATCH,V6 03/10] gas: generate .ctf_frame Indu Bhagat
2022-08-15 12:22   ` Nick Clifton
2022-08-02  8:04 ` [PATCH,V6 04/10] libctfframe: add the CTF Frame library Indu Bhagat
2022-08-15 12:46   ` Nick Clifton
2022-08-02  8:04 ` [PATCH,V6 05/10] libctfframe: add GNU poke pickles for CTF Frame Indu Bhagat
2022-08-15 12:50   ` Nick Clifton
2022-08-02  8:04 ` [PATCH,V6 06/10] bfd: linker: merge .ctf_frame sections Indu Bhagat
2022-08-15 13:02   ` Nick Clifton
2022-08-18  2:11     ` Indu Bhagat
2022-08-02  8:04 ` [PATCH,V6 07/10] readelf/objdump: support for CTF Frame section Indu Bhagat
2022-08-15 13:11   ` Nick Clifton
2022-08-02  8:04 ` [PATCH,V6 08/10] unwinder: generate backtrace using CTF Frame format Indu Bhagat
2022-08-15 13:16   ` Nick Clifton
2022-08-02  8:04 ` [PATCH,V6 09/10] unwinder: Add CTF Frame unwinder tests Indu Bhagat
2022-08-15 13:27   ` Nick Clifton
2022-08-02  8:04 ` [PATCH, V6 10/10] gdb: sim: buildsystem changes to accommodate libctfframe Indu Bhagat
2022-08-05 14:43   ` Tom Tromey
2022-08-15 12:18 ` [PATCH,V6 00/10] Definition and Implementation of CTF Frame format Nick Clifton
2022-08-18  1:38   ` Indu Bhagat
2022-08-15 14:25 ` Nick Clifton
2022-09-30  0:04   ` [PATCH,V1 00/14] Definition and support for SFrame unwind format Indu Bhagat
2022-09-30  0:04     ` [PATCH,V1 01/14] sframe.h: Add SFrame format definition Indu Bhagat
2022-09-30  0:04     ` [PATCH,V1 02/14] gas: add new command line option --gsframe Indu Bhagat
2022-09-30  0:04     ` [PATCH,V1 03/14] gas: generate .sframe from CFI directives Indu Bhagat
2022-09-30  0:04     ` [PATCH,V1 04/14] gas: testsuite: add new tests for SFrame unwind info Indu Bhagat
2022-09-30  0:04     ` [PATCH,V1 05/14] libsframe: add the SFrame library Indu Bhagat
2022-09-30  0:04     ` [PATCH,V1 06/14] bfd: linker: merge .sframe sections Indu Bhagat
2022-09-30 10:51       ` Nick Clifton
2022-09-30  0:04     ` Indu Bhagat [this message]
2022-09-30 11:08       ` [PATCH,V1 07/14] readelf/objdump: support for SFrame section Nick Clifton
2022-09-30  0:04     ` [PATCH,V1 08/14] unwinder: generate backtrace using SFrame format Indu Bhagat
2022-09-30  0:04     ` [PATCH,V1 09/14] unwinder: Add SFrame unwinder tests Indu Bhagat
2022-09-30  0:04     ` [PATCH,V1 10/14] gdb: sim: buildsystem changes to accommodate libsframe Indu Bhagat
2022-10-11 16:08       ` [PATCH, V1 " Tom Tromey
2022-09-30  0:04     ` [PATCH,V1 11/14] libctf: add libsframe to LDFLAGS and LIBS Indu Bhagat
2022-09-30  0:04     ` [PATCH,V1 12/14] src-release.sh: Add libsframe Indu Bhagat
2022-09-30  0:04     ` [PATCH,V1 13/14] binutils/NEWS: add text for SFrame support Indu Bhagat
2022-09-30  0:04     ` [PATCH,V1 14/14] gas/NEWS: add text about new command line option and " Indu Bhagat
2022-09-30  8:09     ` [PATCH,V1 00/14] Definition and support for SFrame unwind format Jan Beulich
2022-10-04  5:16       ` Indu Bhagat
2022-10-04  6:53         ` Jan Beulich
2022-09-30  8:24     ` Fangrui Song
2022-10-01  0:15       ` Indu Bhagat
2022-09-30  9:12     ` Nick Clifton
2022-10-01  0:29       ` Indu Bhagat
2022-10-01  9:51       ` Jose E. Marchesi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220930000440.1672106-8-indu.bhagat@oracle.com \
    --to=indu.bhagat@oracle.com \
    --cc=binutils@sourceware.org \
    --cc=nickc@redhat.com \
    --cc=weimin.pan@oracle.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).