diff options
author | Indu Bhagat <indu.bhagat@oracle.com> | 2022-11-15 15:07:09 -0800 |
---|---|---|
committer | Indu Bhagat <indu.bhagat@oracle.com> | 2022-11-15 15:50:05 -0800 |
commit | 42b6953bbad652d3f7cba405c941ad9c6eab26b0 (patch) | |
tree | 7f1276452e23a847be0105dba5bf563b1f8e3457 /binutils | |
parent | cf0e0a0ba91664b680dff1e310f24dbe6447bd4c (diff) | |
download | binutils-42b6953bbad652d3f7cba405c941ad9c6eab26b0.zip binutils-42b6953bbad652d3f7cba405c941ad9c6eab26b0.tar.gz binutils-42b6953bbad652d3f7cba405c941ad9c6eab26b0.tar.bz2 |
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.am | 8 | ||||
-rw-r--r-- | binutils/Makefile.in | 8 | ||||
-rw-r--r-- | binutils/doc/binutils.texi | 4 | ||||
-rw-r--r-- | binutils/doc/sframe.options.texi | 10 | ||||
-rw-r--r-- | binutils/objdump.c | 75 | ||||
-rw-r--r-- | binutils/readelf.c | 63 |
6 files changed, 160 insertions, 8 deletions
diff --git a/binutils/Makefile.am b/binutils/Makefile.am index 6d974fd..ce5fa1d 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 05aca3d..30b78a9 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 2ca114d..483b72f 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 0000000..9e23679 --- /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 7630986..61a1874 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 f82c3a9..6b2cbbc 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) |