summaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
authorIndu Bhagat <indu.bhagat@oracle.com>2022-11-15 15:07:09 -0800
committerIndu Bhagat <indu.bhagat@oracle.com>2022-11-15 15:50:05 -0800
commit42b6953bbad652d3f7cba405c941ad9c6eab26b0 (patch)
tree7f1276452e23a847be0105dba5bf563b1f8e3457 /binutils
parentcf0e0a0ba91664b680dff1e310f24dbe6447bd4c (diff)
downloadbinutils-gdb-42b6953bbad652d3f7cba405c941ad9c6eab26b0.tar.gz
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.
Diffstat (limited to 'binutils')
-rw-r--r--binutils/Makefile.am8
-rw-r--r--binutils/Makefile.in8
-rw-r--r--binutils/doc/binutils.texi4
-rw-r--r--binutils/doc/sframe.options.texi10
-rw-r--r--binutils/objdump.c75
-rw-r--r--binutils/readelf.c63
6 files changed, 160 insertions, 8 deletions
diff --git a/binutils/Makefile.am b/binutils/Makefile.am
index 6d974fd3f8a..ce5fa1d39bb 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) $(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_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 05aca3d3965..30b78a961dd 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) $(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_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 2ca114d5774..483b72f443e 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}]
@@ -2851,6 +2852,8 @@ Enable additional checks for consistency of Dwarf information.
@include ctf.options.texi
+@include sframe.options.texi
+
@item -G
@itemx --stabs
@cindex stab
@@ -4948,6 +4951,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 7630986f59a..61a18746fde 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 */
@@ -322,6 +325,8 @@ usage (FILE *stream, int status)
--ctf[=SECTION] Display CTF info from SECTION, (default `.ctf')\n"));
#endif
fprintf (stream, _("\
+ --sframe[=SECTION] Display SFrame info from SECTION, (default '.sframe')\n"));
+ fprintf (stream, _("\
-t, --syms Display the contents of the symbol table(s)\n"));
fprintf (stream, _("\
-T, --dynamic-syms Display the contents of the dynamic symbol table\n"));
@@ -476,6 +481,7 @@ enum option_values
OPTION_CTF,
OPTION_CTF_PARENT,
#endif
+ OPTION_SFRAME,
OPTION_VISUALIZE_JUMPS,
OPTION_DISASSEMBLER_COLOR
};
@@ -530,6 +536,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},
@@ -4815,6 +4822,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;
+ 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
dump_bfd_private_header (bfd *abfd)
@@ -5568,6 +5635,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)
@@ -6071,6 +6140,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 f82c3a973f2..6b2cbbcbb1b 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -63,6 +63,7 @@
#include "demanguse.h"
#include "dwarf.h"
#include "ctf-api.h"
+#include "sframe-api.h"
#include "demangle.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 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;
@@ -233,6 +235,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;
@@ -5071,6 +5074,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,
@@ -5133,6 +5137,7 @@ static struct option options[] =
{"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
{"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
#endif
+ {"sframe", optional_argument, 0, OPTION_SFRAME_DUMP},
{"sym-base", optional_argument, 0, OPTION_SYM_BASE},
{0, no_argument, 0, 0}
@@ -5273,6 +5278,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, (default '.sframe')\n"));
#ifdef SUPPORT_DISASSEMBLY
fprintf (stream, _("\
@@ -5546,6 +5553,19 @@ 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;
+ /* 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:
do_dyn_syms = true;
break;
@@ -15860,6 +15880,44 @@ 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;
+
+ 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
load_specific_debug_section (enum dwarf_section_display_enum debug,
const Elf_Internal_Shdr * sec,
void * data)
@@ -16365,6 +16423,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)