readelf/objdump: support for SFrame section
This patch adds support for SFrame in readelf and objdump. The arguments of --sframe are optional for both 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.
This commit is contained in:
parent
cf0e0a0ba9
commit
42b6953bba
10 changed files with 355 additions and 11 deletions
|
@ -228,7 +228,7 @@ installcheck-local:
|
||||||
# which depends on libintl, since we don't know whether LIBINTL_DEP will be
|
# which depends on libintl, since we don't know whether LIBINTL_DEP will be
|
||||||
# non-empty until configure time. Ugh!
|
# non-empty until configure time. Ugh!
|
||||||
size_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
|
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)
|
nm_new_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
|
||||||
ar_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
|
ar_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
|
||||||
strings_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)
|
windres_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
|
||||||
windmc_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
|
windmc_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
|
||||||
addr2line_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)
|
elfedit_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY)
|
||||||
dllwrap_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY)
|
dllwrap_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY)
|
||||||
bfdtest1_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
|
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)
|
strings_SOURCES = strings.c $(BULIBS)
|
||||||
|
|
||||||
readelf_SOURCES = readelf.c version.c unwind-ia64.c dwarf.c demanguse.c $(ELFLIBS)
|
readelf_SOURCES = readelf.c version.c unwind-ia64.c dwarf.c demanguse.c $(ELFLIBS)
|
||||||
readelf_LDADD = $(LIBCTF_NOBFD) $(LIBINTL) $(LIBIBERTY) $(ZLIB) $(ZSTD_LIBS) $(DEBUGINFOD_LIBS) $(MSGPACK_LIBS)
|
readelf_LDADD = $(LIBCTF_NOBFD) $(LIBINTL) $(LIBIBERTY) $(ZLIB) $(ZSTD_LIBS) $(DEBUGINFOD_LIBS) $(MSGPACK_LIBS) $(LIBSFRAME)
|
||||||
|
|
||||||
elfedit_SOURCES = elfedit.c version.c $(ELFLIBS)
|
elfedit_SOURCES = elfedit.c version.c $(ELFLIBS)
|
||||||
elfedit_LDADD = $(LIBINTL) $(LIBIBERTY)
|
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)
|
objdump_SOURCES = objdump.c dwarf.c prdbg.c demanguse.c $(DEBUG_SRCS) $(BULIBS) $(ELFLIBS)
|
||||||
EXTRA_objdump_SOURCES = od-xcoff.c
|
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
|
objdump.@OBJEXT@:objdump.c
|
||||||
if am__fastdepCC
|
if am__fastdepCC
|
||||||
|
|
|
@ -766,7 +766,7 @@ CC_FOR_TARGET = ` \
|
||||||
# which depends on libintl, since we don't know whether LIBINTL_DEP will be
|
# which depends on libintl, since we don't know whether LIBINTL_DEP will be
|
||||||
# non-empty until configure time. Ugh!
|
# non-empty until configure time. Ugh!
|
||||||
size_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
|
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)
|
nm_new_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
|
||||||
ar_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
|
ar_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
|
||||||
strings_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)
|
windres_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
|
||||||
windmc_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
|
windmc_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
|
||||||
addr2line_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)
|
elfedit_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY)
|
||||||
dllwrap_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY)
|
dllwrap_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY)
|
||||||
bfdtest1_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
|
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)
|
objcopy_SOURCES = objcopy.c not-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS)
|
||||||
strings_SOURCES = strings.c $(BULIBS)
|
strings_SOURCES = strings.c $(BULIBS)
|
||||||
readelf_SOURCES = readelf.c version.c unwind-ia64.c dwarf.c demanguse.c $(ELFLIBS)
|
readelf_SOURCES = readelf.c version.c unwind-ia64.c dwarf.c demanguse.c $(ELFLIBS)
|
||||||
readelf_LDADD = $(LIBCTF_NOBFD) $(LIBINTL) $(LIBIBERTY) $(ZLIB) $(ZSTD_LIBS) $(DEBUGINFOD_LIBS) $(MSGPACK_LIBS)
|
readelf_LDADD = $(LIBCTF_NOBFD) $(LIBINTL) $(LIBIBERTY) $(ZLIB) $(ZSTD_LIBS) $(DEBUGINFOD_LIBS) $(MSGPACK_LIBS) $(LIBSFRAME)
|
||||||
elfedit_SOURCES = elfedit.c version.c $(ELFLIBS)
|
elfedit_SOURCES = elfedit.c version.c $(ELFLIBS)
|
||||||
elfedit_LDADD = $(LIBINTL) $(LIBIBERTY)
|
elfedit_LDADD = $(LIBINTL) $(LIBIBERTY)
|
||||||
strip_new_SOURCES = objcopy.c is-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS)
|
strip_new_SOURCES = objcopy.c is-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS)
|
||||||
nm_new_SOURCES = nm.c demanguse.c $(BULIBS)
|
nm_new_SOURCES = nm.c demanguse.c $(BULIBS)
|
||||||
objdump_SOURCES = objdump.c dwarf.c prdbg.c demanguse.c $(DEBUG_SRCS) $(BULIBS) $(ELFLIBS)
|
objdump_SOURCES = objdump.c dwarf.c prdbg.c demanguse.c $(DEBUG_SRCS) $(BULIBS) $(ELFLIBS)
|
||||||
EXTRA_objdump_SOURCES = od-xcoff.c
|
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)
|
cxxfilt_SOURCES = cxxfilt.c $(BULIBS)
|
||||||
ar_SOURCES = arparse.y arlex.l ar.c not-ranlib.c arsup.c rename.c binemul.c \
|
ar_SOURCES = arparse.y arlex.l ar.c not-ranlib.c arsup.c rename.c binemul.c \
|
||||||
emul_$(EMULATION).c $(BULIBS)
|
emul_$(EMULATION).c $(BULIBS)
|
||||||
|
|
|
@ -2262,6 +2262,7 @@ objdump [@option{-a}|@option{--archive-headers}]
|
||||||
[@option{-wE}|@option{--dwarf=do-not-use-debuginfod}]
|
[@option{-wE}|@option{--dwarf=do-not-use-debuginfod}]
|
||||||
[@option{-L}|@option{--process-links}]
|
[@option{-L}|@option{--process-links}]
|
||||||
[@option{--ctf=}@var{section}]
|
[@option{--ctf=}@var{section}]
|
||||||
|
[@option{--sframe=}@var{section}]
|
||||||
[@option{-G}|@option{--stabs}]
|
[@option{-G}|@option{--stabs}]
|
||||||
[@option{-t}|@option{--syms}]
|
[@option{-t}|@option{--syms}]
|
||||||
[@option{-T}|@option{--dynamic-syms}]
|
[@option{-T}|@option{--dynamic-syms}]
|
||||||
|
@ -2851,6 +2852,8 @@ Enable additional checks for consistency of Dwarf information.
|
||||||
|
|
||||||
@include ctf.options.texi
|
@include ctf.options.texi
|
||||||
|
|
||||||
|
@include sframe.options.texi
|
||||||
|
|
||||||
@item -G
|
@item -G
|
||||||
@itemx --stabs
|
@itemx --stabs
|
||||||
@cindex stab
|
@cindex stab
|
||||||
|
@ -4948,6 +4951,7 @@ readelf [@option{-a}|@option{--all}]
|
||||||
[@option{--ctf-parent=}@var{section}]
|
[@option{--ctf-parent=}@var{section}]
|
||||||
[@option{--ctf-symbols=}@var{section}]
|
[@option{--ctf-symbols=}@var{section}]
|
||||||
[@option{--ctf-strings=}@var{section}]
|
[@option{--ctf-strings=}@var{section}]
|
||||||
|
[@option{--sframe=}@var{section}]
|
||||||
[@option{-I}|@option{--histogram}]
|
[@option{-I}|@option{--histogram}]
|
||||||
[@option{-v}|@option{--version}]
|
[@option{-v}|@option{--version}]
|
||||||
[@option{-W}|@option{--wide}]
|
[@option{-W}|@option{--wide}]
|
||||||
|
|
10
binutils/doc/sframe.options.texi
Normal file
10
binutils/doc/sframe.options.texi
Normal file
|
@ -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}.
|
|
@ -58,6 +58,7 @@
|
||||||
#include "demanguse.h"
|
#include "demanguse.h"
|
||||||
#include "dwarf.h"
|
#include "dwarf.h"
|
||||||
#include "ctf-api.h"
|
#include "ctf-api.h"
|
||||||
|
#include "sframe-api.h"
|
||||||
#include "getopt.h"
|
#include "getopt.h"
|
||||||
#include "safe-ctype.h"
|
#include "safe-ctype.h"
|
||||||
#include "dis-asm.h"
|
#include "dis-asm.h"
|
||||||
|
@ -108,6 +109,8 @@ static int dump_stab_section_info; /* --stabs */
|
||||||
static int dump_ctf_section_info; /* --ctf */
|
static int dump_ctf_section_info; /* --ctf */
|
||||||
static char *dump_ctf_section_name;
|
static char *dump_ctf_section_name;
|
||||||
static char *dump_ctf_parent_name; /* --ctf-parent */
|
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 int do_demangle; /* -C, --demangle */
|
||||||
static bool disassemble; /* -d */
|
static bool disassemble; /* -d */
|
||||||
static bool disassemble_all; /* -D */
|
static bool disassemble_all; /* -D */
|
||||||
|
@ -321,6 +324,8 @@ usage (FILE *stream, int status)
|
||||||
fprintf (stream, _("\
|
fprintf (stream, _("\
|
||||||
--ctf[=SECTION] Display CTF info from SECTION, (default `.ctf')\n"));
|
--ctf[=SECTION] Display CTF info from SECTION, (default `.ctf')\n"));
|
||||||
#endif
|
#endif
|
||||||
|
fprintf (stream, _("\
|
||||||
|
--sframe[=SECTION] Display SFrame info from SECTION, (default '.sframe')\n"));
|
||||||
fprintf (stream, _("\
|
fprintf (stream, _("\
|
||||||
-t, --syms Display the contents of the symbol table(s)\n"));
|
-t, --syms Display the contents of the symbol table(s)\n"));
|
||||||
fprintf (stream, _("\
|
fprintf (stream, _("\
|
||||||
|
@ -476,6 +481,7 @@ enum option_values
|
||||||
OPTION_CTF,
|
OPTION_CTF,
|
||||||
OPTION_CTF_PARENT,
|
OPTION_CTF_PARENT,
|
||||||
#endif
|
#endif
|
||||||
|
OPTION_SFRAME,
|
||||||
OPTION_VISUALIZE_JUMPS,
|
OPTION_VISUALIZE_JUMPS,
|
||||||
OPTION_DISASSEMBLER_COLOR
|
OPTION_DISASSEMBLER_COLOR
|
||||||
};
|
};
|
||||||
|
@ -530,6 +536,7 @@ static struct option long_options[]=
|
||||||
{"reloc", no_argument, NULL, 'r'},
|
{"reloc", no_argument, NULL, 'r'},
|
||||||
{"section", required_argument, NULL, 'j'},
|
{"section", required_argument, NULL, 'j'},
|
||||||
{"section-headers", no_argument, NULL, 'h'},
|
{"section-headers", no_argument, NULL, 'h'},
|
||||||
|
{"sframe", optional_argument, NULL, OPTION_SFRAME},
|
||||||
{"show-raw-insn", no_argument, &show_raw_insn, 1},
|
{"show-raw-insn", no_argument, &show_raw_insn, 1},
|
||||||
{"source", no_argument, NULL, 'S'},
|
{"source", no_argument, NULL, 'S'},
|
||||||
{"source-comment", optional_argument, NULL, OPTION_SOURCE_COMMENT},
|
{"source-comment", optional_argument, NULL, OPTION_SOURCE_COMMENT},
|
||||||
|
@ -4815,6 +4822,66 @@ dump_ctf (bfd *abfd ATTRIBUTE_UNUSED, const char *sect_name ATTRIBUTE_UNUSED,
|
||||||
const char *parent_name ATTRIBUTE_UNUSED) {}
|
const char *parent_name ATTRIBUTE_UNUSED) {}
|
||||||
#endif
|
#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;
|
||||||
|
bfd_size_type 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dump_bfd_private_header (bfd *abfd)
|
dump_bfd_private_header (bfd *abfd)
|
||||||
|
@ -5568,6 +5635,8 @@ dump_bfd (bfd *abfd, bool is_mainfile)
|
||||||
{
|
{
|
||||||
if (dump_ctf_section_info)
|
if (dump_ctf_section_info)
|
||||||
dump_ctf (abfd, dump_ctf_section_name, dump_ctf_parent_name);
|
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)
|
if (dump_stab_section_info)
|
||||||
dump_stabs (abfd);
|
dump_stabs (abfd);
|
||||||
if (dump_reloc_info && ! disassemble)
|
if (dump_reloc_info && ! disassemble)
|
||||||
|
@ -6071,6 +6140,12 @@ main (int argc, char **argv)
|
||||||
dump_ctf_parent_name = xstrdup (optarg);
|
dump_ctf_parent_name = xstrdup (optarg);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
case OPTION_SFRAME:
|
||||||
|
dump_sframe_section_info = true;
|
||||||
|
if (optarg)
|
||||||
|
dump_sframe_section_name = xstrdup (optarg);
|
||||||
|
seenflag = true;
|
||||||
|
break;
|
||||||
case 'G':
|
case 'G':
|
||||||
dump_stab_section_info = true;
|
dump_stab_section_info = true;
|
||||||
seenflag = true;
|
seenflag = true;
|
||||||
|
|
|
@ -63,6 +63,7 @@
|
||||||
#include "demanguse.h"
|
#include "demanguse.h"
|
||||||
#include "dwarf.h"
|
#include "dwarf.h"
|
||||||
#include "ctf-api.h"
|
#include "ctf-api.h"
|
||||||
|
#include "sframe-api.h"
|
||||||
#include "demangle.h"
|
#include "demangle.h"
|
||||||
|
|
||||||
#include "elf/common.h"
|
#include "elf/common.h"
|
||||||
|
@ -190,6 +191,7 @@ typedef struct elf_section_list
|
||||||
#define STRING_DUMP (1 << 3) /* The -p command line switch. */
|
#define STRING_DUMP (1 << 3) /* The -p command line switch. */
|
||||||
#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
|
#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
|
||||||
#define CTF_DUMP (1 << 5) /* The --ctf 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;
|
typedef unsigned char dump_type;
|
||||||
|
|
||||||
|
@ -233,6 +235,7 @@ static bool do_version = false;
|
||||||
static bool do_histogram = false;
|
static bool do_histogram = false;
|
||||||
static bool do_debugging = false;
|
static bool do_debugging = false;
|
||||||
static bool do_ctf = false;
|
static bool do_ctf = false;
|
||||||
|
static bool do_sframe = false;
|
||||||
static bool do_arch = false;
|
static bool do_arch = false;
|
||||||
static bool do_notes = false;
|
static bool do_notes = false;
|
||||||
static bool do_archive_index = false;
|
static bool do_archive_index = false;
|
||||||
|
@ -5071,6 +5074,7 @@ enum long_option_values
|
||||||
OPTION_CTF_PARENT,
|
OPTION_CTF_PARENT,
|
||||||
OPTION_CTF_SYMBOLS,
|
OPTION_CTF_SYMBOLS,
|
||||||
OPTION_CTF_STRINGS,
|
OPTION_CTF_STRINGS,
|
||||||
|
OPTION_SFRAME_DUMP,
|
||||||
OPTION_WITH_SYMBOL_VERSIONS,
|
OPTION_WITH_SYMBOL_VERSIONS,
|
||||||
OPTION_RECURSE_LIMIT,
|
OPTION_RECURSE_LIMIT,
|
||||||
OPTION_NO_RECURSE_LIMIT,
|
OPTION_NO_RECURSE_LIMIT,
|
||||||
|
@ -5133,6 +5137,7 @@ static struct option options[] =
|
||||||
{"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
|
{"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
|
||||||
{"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
|
{"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
|
||||||
#endif
|
#endif
|
||||||
|
{"sframe", optional_argument, 0, OPTION_SFRAME_DUMP},
|
||||||
{"sym-base", optional_argument, 0, OPTION_SYM_BASE},
|
{"sym-base", optional_argument, 0, OPTION_SYM_BASE},
|
||||||
|
|
||||||
{0, no_argument, 0, 0}
|
{0, no_argument, 0, 0}
|
||||||
|
@ -5273,6 +5278,8 @@ usage (FILE * stream)
|
||||||
--ctf-strings=<number|name>\n\
|
--ctf-strings=<number|name>\n\
|
||||||
Use section <number|name> as the CTF external strtab\n"));
|
Use section <number|name> as the CTF external strtab\n"));
|
||||||
#endif
|
#endif
|
||||||
|
fprintf (stream, _("\
|
||||||
|
--sframe[=NAME] Display SFrame info from section NAME, (default '.sframe')\n"));
|
||||||
|
|
||||||
#ifdef SUPPORT_DISASSEMBLY
|
#ifdef SUPPORT_DISASSEMBLY
|
||||||
fprintf (stream, _("\
|
fprintf (stream, _("\
|
||||||
|
@ -5546,6 +5553,19 @@ parse_args (struct dump_data *dumpdata, int argc, char ** argv)
|
||||||
free (dump_ctf_parent_name);
|
free (dump_ctf_parent_name);
|
||||||
dump_ctf_parent_name = strdup (optarg);
|
dump_ctf_parent_name = strdup (optarg);
|
||||||
break;
|
break;
|
||||||
|
case OPTION_SFRAME_DUMP:
|
||||||
|
do_sframe = true;
|
||||||
|
/* Providing section name is optional. request_dump (), however,
|
||||||
|
thrives on non NULL optarg. Handle it explicitly here. */
|
||||||
|
if (optarg != NULL)
|
||||||
|
request_dump (dumpdata, SFRAME_DUMP);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
do_dump = true;
|
||||||
|
const char *sframe_sec_name = strdup (".sframe");
|
||||||
|
request_dump_byname (sframe_sec_name, SFRAME_DUMP);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case OPTION_DYN_SYMS:
|
case OPTION_DYN_SYMS:
|
||||||
do_dyn_syms = true;
|
do_dyn_syms = true;
|
||||||
break;
|
break;
|
||||||
|
@ -15859,6 +15879,44 @@ dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
|
||||||
}
|
}
|
||||||
#endif
|
#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;
|
||||||
|
|
||||||
|
if (strcmp (print_name, "") == 0)
|
||||||
|
{
|
||||||
|
error (_("Section name must be provided \n"));
|
||||||
|
ret = false;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
error (_("SFrame decode failure: %s\n"), sframe_errmsg (err));
|
||||||
|
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
|
static bool
|
||||||
load_specific_debug_section (enum dwarf_section_display_enum debug,
|
load_specific_debug_section (enum dwarf_section_display_enum debug,
|
||||||
const Elf_Internal_Shdr * sec,
|
const Elf_Internal_Shdr * sec,
|
||||||
|
@ -16365,6 +16423,11 @@ process_section_contents (Filedata * filedata)
|
||||||
res = false;
|
res = false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (dump & SFRAME_DUMP)
|
||||||
|
{
|
||||||
|
if (! dump_section_as_sframe (section, filedata))
|
||||||
|
res = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! filedata->is_separate)
|
if (! filedata->is_separate)
|
||||||
|
|
|
@ -157,6 +157,9 @@ sframe_decoder_get_funcdesc (sframe_decoder_ctx *ctx,
|
||||||
int32_t *func_start_address,
|
int32_t *func_start_address,
|
||||||
unsigned char *func_info);
|
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. */
|
/* Get the base reg id from the FRE info. Sets errp if fails. */
|
||||||
extern unsigned int
|
extern unsigned int
|
||||||
|
|
|
@ -33,7 +33,7 @@ include_HEADERS =
|
||||||
noinst_LTLIBRARIES = libsframe.la
|
noinst_LTLIBRARIES = libsframe.la
|
||||||
endif
|
endif
|
||||||
|
|
||||||
libsframe_la_SOURCES = sframe.c sframe-error.c
|
libsframe_la_SOURCES = sframe.c sframe-dump.c sframe-error.c
|
||||||
libsframe_la_CPPFLAGS = $(AM_CPPFLAGS)
|
libsframe_la_CPPFLAGS = $(AM_CPPFLAGS)
|
||||||
|
|
||||||
include testsuite/local.mk
|
include testsuite/local.mk
|
||||||
|
|
|
@ -149,7 +149,7 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"
|
||||||
LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
|
LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
|
||||||
libsframe_la_LIBADD =
|
libsframe_la_LIBADD =
|
||||||
am_libsframe_la_OBJECTS = libsframe_la-sframe.lo \
|
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)
|
libsframe_la_OBJECTS = $(am_libsframe_la_OBJECTS)
|
||||||
AM_V_lt = $(am__v_lt_@AM_V@)
|
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||||
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
|
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
|
||||||
|
@ -427,7 +427,7 @@ AM_CFLAGS = @ac_libsframe_warn_cflags@
|
||||||
@INSTALL_LIBBFD_FALSE@include_HEADERS =
|
@INSTALL_LIBBFD_FALSE@include_HEADERS =
|
||||||
@INSTALL_LIBBFD_TRUE@include_HEADERS = $(INCDIR)/sframe.h $(INCDIR)/sframe-api.h
|
@INSTALL_LIBBFD_TRUE@include_HEADERS = $(INCDIR)/sframe.h $(INCDIR)/sframe-api.h
|
||||||
@INSTALL_LIBBFD_FALSE@noinst_LTLIBRARIES = libsframe.la
|
@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 = $(AM_CPPFLAGS)
|
libsframe_la_CPPFLAGS = $(AM_CPPFLAGS)
|
||||||
|
|
||||||
# Setup the testing framework
|
# Setup the testing framework
|
||||||
|
@ -607,6 +607,7 @@ mostlyclean-compile:
|
||||||
distclean-compile:
|
distclean-compile:
|
||||||
-rm -f *.tab.c
|
-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-error.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsframe_la-sframe.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsframe_la-sframe.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@testsuite/libsframe.decode/$(DEPDIR)/testsuite_libsframe_decode_be_flipping-be-flipping.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@testsuite/libsframe.decode/$(DEPDIR)/testsuite_libsframe_decode_be_flipping-be-flipping.Po@am__quote@
|
||||||
|
@ -645,6 +646,13 @@ libsframe_la-sframe.lo: sframe.c
|
||||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @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.lo `test -f 'sframe.c' || echo '$(srcdir)/'`sframe.c
|
@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
|
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_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
|
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsframe_la-sframe-error.Tpo $(DEPDIR)/libsframe_la-sframe-error.Plo
|
||||||
|
|
181
libsframe/sframe-dump.c
Normal file
181
libsframe/sframe-dump.c
Normal file
|
@ -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 <inttypes.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);
|
||||||
|
/* 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%"PRIx64 ", 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 (sfd_ctx, &fre, &err[0]);
|
||||||
|
fp_offset = sframe_fre_get_fp_offset (sfd_ctx, &fre, &err[1]);
|
||||||
|
ra_offset = sframe_fre_get_ra_offset (sfd_ctx, &fre, &err[2]);
|
||||||
|
|
||||||
|
/* Dump CFA info. */
|
||||||
|
printf ("\n");
|
||||||
|
printf (" %016"PRIx64, 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);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue