diff options
-rw-r--r-- | binutils/ChangeLog | 47 | ||||
-rw-r--r-- | binutils/Makefile.am | 10 | ||||
-rw-r--r-- | binutils/Makefile.in | 18 | ||||
-rw-r--r-- | binutils/NEWS | 5 | ||||
-rw-r--r-- | binutils/aclocal.m4 | 10 | ||||
-rw-r--r-- | binutils/doc/Makefile.in | 9 | ||||
-rw-r--r-- | binutils/doc/binutils.texi | 19 | ||||
-rw-r--r-- | binutils/doc/ctf.options.texi | 14 | ||||
-rw-r--r-- | binutils/objdump.c | 169 | ||||
-rw-r--r-- | binutils/readelf.c | 206 |
10 files changed, 480 insertions, 27 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 18ec182..b66f0b2 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,50 @@ +2019-05-28 Nick Alcock <nick.alcock@oracle.com> + + * objdump.c (ctf-api.h): New include. + (dump_ctf_section_info): New variable. + (dump_ctf_section_name): Likewise. + (usage): Describe new options. + (enum option_values): Add OPTION_CTF and OPTION_CTF_PARENT. + (main): Use them to add --ctf and --ctf-parent. + (read_section_stabs): Add new parameter, entsize_ptr. + (find_stabs_section): Adjust accordingly. + (make_ctfsect): New. + (dump_ctf_indent_lines): New. + (dump_ctf_archive_member): New. + (dump_ctf): New. + (dump_bfd): Call it. Free resources afterwards. + * readelf.c (ctf-api.h): New include. + (CTF_DUMP): New. + (static bfd_boolean do_ctf): Likewise. + (dump_ctf_parent_name): Likewise. + (dump_ctf_symtab_name): Likewise. + (dump_ctf_strtab_name): Likewise. + (OPTION_CTF_DUMP): Likewise. + (OPTION_CTF_PARENT): Likewise. + (OPTION_CTF_SYMBOLS): Likewise. + (OPTION_CTF_STRINGS): Likewise. + (options): Add them. + (usage): Likewise. + (parse_args): Handle the new options, requesting CTF_DUMP. + (process_section_contents): Handle CTF_DUMP. + (shdr_to_ctf_sect): New. + (dump_ctf_indent_lines): New. + (dump_section_as_ctf): New. + (main): Free resources. + * Makefile.am (LIBCTF): New variable. + (objdump_DEPENDENCIES): Use it. + (readelf_DEPENDENCIES): Likewise. + (objdump_LDADD): Likewise. + (readelf_LDADD): Likewise. + * aclocal.m4: Regenerated. + * Makefile.in: Likewise. + + * doc/binutils.texi (objdump): Document the new options. + (readelf): Likewise. + * doc/ctf.options.texi: New. + * doc/Makefile.in: Regenerated. + * NEWS: Mention the new feature. + 2019-05-27 Alan Modra <amodra@gmail.com> * readelf.c (process_section_groups): Continue processing groups diff --git a/binutils/Makefile.am b/binutils/Makefile.am index 7d59d8c..128494c 100644 --- a/binutils/Makefile.am +++ b/binutils/Makefile.am @@ -161,6 +161,8 @@ BFDLIB = ../bfd/libbfd.la OPCODES = ../opcodes/libopcodes.la +LIBCTF = ../libctf/libctf.a + LIBIBERTY = ../libiberty/libiberty.a POTFILES = $(CFILES) $(DEBUG_SRCS) $(HFILES) @@ -211,7 +213,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) $(OBJDUMP_PRIVATE_OFILES) +objdump_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB) $(OPCODES) $(LIBCTF) $(OBJDUMP_PRIVATE_OFILES) nm_new_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB) ar_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB) strings_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB) @@ -226,7 +228,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) +readelf_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(LIBCTF) elfedit_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) dllwrap_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) bfdtest1_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB) @@ -241,7 +243,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 $(ELFLIBS) -readelf_LDADD = $(LIBINTL) $(LIBIBERTY) $(ZLIB) +readelf_LDADD = $(LIBINTL) $(LIBCTF) $(LIBIBERTY) $(ZLIB) elfedit_SOURCES = elfedit.c version.c $(ELFLIBS) elfedit_LDADD = $(LIBINTL) $(LIBIBERTY) @@ -252,7 +254,7 @@ nm_new_SOURCES = nm.c $(BULIBS) objdump_SOURCES = objdump.c dwarf.c prdbg.c $(DEBUG_SRCS) $(BULIBS) $(ELFLIBS) EXTRA_objdump_SOURCES = od-xcoff.c -objdump_LDADD = $(OBJDUMP_PRIVATE_OFILES) $(OPCODES) $(BFDLIB) $(LIBIBERTY) $(LIBINTL) +objdump_LDADD = $(OBJDUMP_PRIVATE_OFILES) $(OPCODES) $(LIBCTF) $(BFDLIB) $(LIBIBERTY) $(LIBINTL) objdump.@OBJEXT@:objdump.c if am__fastdepCC diff --git a/binutils/Makefile.in b/binutils/Makefile.in index f6cb22f..480385b 100644 --- a/binutils/Makefile.in +++ b/binutils/Makefile.in @@ -119,7 +119,10 @@ EXTRA_PROGRAMS = srconv$(EXEEXT) sysdump$(EXEEXT) coffdump$(EXEEXT) \ $(am__EXEEXT_4) subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/../bfd/acinclude.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \ + $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \ + $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \ + $(top_srcdir)/../bfd/acinclude.m4 \ $(top_srcdir)/../bfd/warning.m4 $(top_srcdir)/../config/acx.m4 \ $(top_srcdir)/../config/depstand.m4 \ $(top_srcdir)/../config/gettext-sister.m4 \ @@ -135,9 +138,7 @@ am__aclocal_m4_deps = $(top_srcdir)/../bfd/acinclude.m4 \ $(top_srcdir)/../config/plugins.m4 \ $(top_srcdir)/../config/po.m4 \ $(top_srcdir)/../config/progtest.m4 \ - $(top_srcdir)/../config/zlib.m4 $(top_srcdir)/../libtool.m4 \ - $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \ - $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \ + $(top_srcdir)/../config/zlib.m4 \ $(top_srcdir)/../bfd/version.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) @@ -647,6 +648,7 @@ BULIBS = bucomm.c version.c filemode.c ELFLIBS = elfcomm.c BFDLIB = ../bfd/libbfd.la OPCODES = ../opcodes/libopcodes.la +LIBCTF = ../libctf/libctf.a LIBIBERTY = ../libiberty/libiberty.a POTFILES = $(CFILES) $(DEBUG_SRCS) $(HFILES) EXPECT = expect @@ -671,7 +673,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) $(OBJDUMP_PRIVATE_OFILES) +objdump_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB) $(OPCODES) $(LIBCTF) $(OBJDUMP_PRIVATE_OFILES) nm_new_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB) ar_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB) strings_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB) @@ -686,7 +688,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) +readelf_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(LIBCTF) elfedit_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) dllwrap_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) bfdtest1_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB) @@ -696,14 +698,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 $(ELFLIBS) -readelf_LDADD = $(LIBINTL) $(LIBIBERTY) $(ZLIB) +readelf_LDADD = $(LIBINTL) $(LIBCTF) $(LIBIBERTY) $(ZLIB) 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 $(BULIBS) objdump_SOURCES = objdump.c dwarf.c prdbg.c $(DEBUG_SRCS) $(BULIBS) $(ELFLIBS) EXTRA_objdump_SOURCES = od-xcoff.c -objdump_LDADD = $(OBJDUMP_PRIVATE_OFILES) $(OPCODES) $(BFDLIB) $(LIBIBERTY) $(LIBINTL) +objdump_LDADD = $(OBJDUMP_PRIVATE_OFILES) $(OPCODES) $(LIBCTF) $(BFDLIB) $(LIBIBERTY) $(LIBINTL) 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/NEWS b/binutils/NEWS index 8383a6a..b892181 100644 --- a/binutils/NEWS +++ b/binutils/NEWS @@ -18,7 +18,10 @@ displayed. In addition when combined with --disassemble the --dwarf= follow-links option will ensure that any symbol tables in the linked files are read and used when disassembling code in the main file. - + + * Add support for dumping types encoded in the Compact Type Format + to objdump and readelf. + Changes in 2.32: * The addr2line, c++filt, nm and objdump tools now have a limit on the diff --git a/binutils/aclocal.m4 b/binutils/aclocal.m4 index 4fa32ff..1b1320f 100644 --- a/binutils/aclocal.m4 +++ b/binutils/aclocal.m4 @@ -1185,6 +1185,11 @@ AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR +m4_include([../libtool.m4]) +m4_include([../ltoptions.m4]) +m4_include([../ltsugar.m4]) +m4_include([../ltversion.m4]) +m4_include([../lt~obsolete.m4]) m4_include([../bfd/acinclude.m4]) m4_include([../bfd/warning.m4]) m4_include([../config/acx.m4]) @@ -1203,8 +1208,3 @@ m4_include([../config/plugins.m4]) m4_include([../config/po.m4]) m4_include([../config/progtest.m4]) m4_include([../config/zlib.m4]) -m4_include([../libtool.m4]) -m4_include([../ltoptions.m4]) -m4_include([../ltsugar.m4]) -m4_include([../ltversion.m4]) -m4_include([../lt~obsolete.m4]) diff --git a/binutils/doc/Makefile.in b/binutils/doc/Makefile.in index a0777d8..7fa622a 100644 --- a/binutils/doc/Makefile.in +++ b/binutils/doc/Makefile.in @@ -108,7 +108,10 @@ host_triplet = @host@ target_triplet = @target@ subdir = doc ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/../bfd/acinclude.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/../libtool.m4 \ + $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \ + $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \ + $(top_srcdir)/../bfd/acinclude.m4 \ $(top_srcdir)/../bfd/warning.m4 $(top_srcdir)/../config/acx.m4 \ $(top_srcdir)/../config/depstand.m4 \ $(top_srcdir)/../config/gettext-sister.m4 \ @@ -124,9 +127,7 @@ am__aclocal_m4_deps = $(top_srcdir)/../bfd/acinclude.m4 \ $(top_srcdir)/../config/plugins.m4 \ $(top_srcdir)/../config/po.m4 \ $(top_srcdir)/../config/progtest.m4 \ - $(top_srcdir)/../config/zlib.m4 $(top_srcdir)/../libtool.m4 \ - $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \ - $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \ + $(top_srcdir)/../config/zlib.m4 \ $(top_srcdir)/../bfd/version.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index 4a7f0f9..f3c4eae 100644 --- a/binutils/doc/binutils.texi +++ b/binutils/doc/binutils.texi @@ -2110,6 +2110,7 @@ objdump [@option{-a}|@option{--archive-headers}] [@option{-s}|@option{--full-contents}] [@option{-W[lLiaprmfFsoRtUuTgAckK]}| @option{--dwarf}[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index,=addr,=cu_index,=links,=follow-links]] + [@option{--ctf=}@var{section}] [@option{-G}|@option{--stabs}] [@option{-t}|@option{--syms}] [@option{-T}|@option{--dynamic-syms}] @@ -2122,6 +2123,9 @@ objdump [@option{-a}|@option{--archive-headers}] [@option{--adjust-vma=}@var{offset}] [@option{--dwarf-depth=@var{n}}] [@option{--dwarf-start=@var{n}}] + [@option{--ctf-parent=}@var{section}] + [@option{--ctf-symbols=}@var{section}] + [@option{--ctf-strings=}@var{section}] [@option{--no-recurse-limit}|@option{--recurse-limit}] [@option{--special-syms}] [@option{--prefix=}@var{prefix}] @@ -2637,6 +2641,8 @@ instructions. @item --dwarf-check Enable additional checks for consistency of Dwarf information. +@include ctf.options.texi + @item -G @itemx --stabs @cindex stab @@ -4636,6 +4642,10 @@ readelf [@option{-a}|@option{--all}] @option{--debug-dump}[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index,=addr,=cu_index,=links,=follow-links]] [@option{--dwarf-depth=@var{n}}] [@option{--dwarf-start=@var{n}}] + [@option{--ctf=}@var{section}] + [@option{--ctf-parent=}@var{section}] + [@option{--ctf-symbols=}@var{section}] + [@option{--ctf-strings=}@var{section}] [@option{-I}|@option{--histogram}] [@option{-v}|@option{--version}] [@option{-W}|@option{--wide}] @@ -4816,6 +4826,15 @@ command to @command{ar}, but without using the BFD library. @xref{ar}. @itemx --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index,=addr,=cu_index,=links,=follow-links] @include debug.options.texi +@include ctf.options.texi +@item --ctf-symbols=@var{section} +@item --ctf-strings=@var{section} +Specify the name of another section from which the CTF file can inherit +strings and symbols. + +If either of @option{--ctf-symbols} or @option{--ctf-strings} is specified, the +other must be specified as well. + @item -I @itemx --histogram Display a histogram of bucket list lengths when displaying the contents diff --git a/binutils/doc/ctf.options.texi b/binutils/doc/ctf.options.texi new file mode 100644 index 0000000..cf05280 --- /dev/null +++ b/binutils/doc/ctf.options.texi @@ -0,0 +1,14 @@ +@c This file contains the entry for the --ctf, --ctf-parent, --ctf-symbols, -and +@c --ctf-strings options that are common to both readelf and objdump. + +@item --ctf=@var{section} +@cindex CTF +@cindex Compact Type Format + +Display the contents of the specified CTF section. CTF sections themselves +contain many subsections, all of which are displayed in order. + +@item --ctf-parent=@var{section} + +Specify the name of another section from which the CTF file can inherit +types. diff --git a/binutils/objdump.c b/binutils/objdump.c index 7381e48..156331b 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -56,6 +56,7 @@ #include "bucomm.h" #include "elfcomm.h" #include "dwarf.h" +#include "ctf-api.h" #include "getopt.h" #include "safe-ctype.h" #include "dis-asm.h" @@ -98,6 +99,9 @@ static bfd_boolean with_source_code; /* -S */ static int show_raw_insn; /* --show-raw-insn */ static int dump_dwarf_section_info; /* --dwarf */ 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 do_demangle; /* -C, --demangle */ static bfd_boolean disassemble; /* -d */ static bfd_boolean disassemble_all; /* -D */ @@ -225,6 +229,7 @@ usage (FILE *stream, int status) =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\ =addr,=cu_index,=links,=follow-links]\n\ Display DWARF info in the file\n\ + --ctf=SECTION Display CTF info from SECTION\n\ -t, --syms Display the contents of the symbol table(s)\n\ -T, --dynamic-syms Display the contents of the dynamic symbol table\n\ -r, --reloc Display the relocation entries in the file\n\ @@ -273,7 +278,8 @@ usage (FILE *stream, int status) --dwarf-start=N Display DIEs starting with N, at the same depth\n\ or deeper\n\ --dwarf-check Make additional dwarf internal consistency checks.\ - \n\n")); + \n\ + --ctf-parent=SECTION Use SECTION as the CTF parent\n\n")); list_supported_targets (program_name, stream); list_supported_architectures (program_name, stream); @@ -308,7 +314,9 @@ enum option_values OPTION_DWARF_START, OPTION_RECURSE_LIMIT, OPTION_NO_RECURSE_LIMIT, - OPTION_INLINES + OPTION_INLINES, + OPTION_CTF, + OPTION_CTF_PARENT }; static struct option long_options[]= @@ -351,6 +359,8 @@ static struct option long_options[]= {"special-syms", no_argument, &dump_special_syms, 1}, {"include", required_argument, NULL, 'I'}, {"dwarf", optional_argument, NULL, OPTION_DWARF}, + {"ctf", required_argument, NULL, OPTION_CTF}, + {"ctf-parent", required_argument, NULL, OPTION_CTF_PARENT}, {"stabs", no_argument, NULL, 'G'}, {"start-address", required_argument, NULL, OPTION_START_ADDRESS}, {"stop-address", required_argument, NULL, OPTION_STOP_ADDRESS}, @@ -2971,7 +2981,8 @@ dump_dwarf (bfd *abfd) it. Return NULL on failure. */ static bfd_byte * -read_section_stabs (bfd *abfd, const char *sect_name, bfd_size_type *size_ptr) +read_section_stabs (bfd *abfd, const char *sect_name, bfd_size_type *size_ptr, + bfd_size_type *entsize_ptr) { asection *stabsect; bfd_byte *contents; @@ -2995,6 +3006,8 @@ read_section_stabs (bfd *abfd, const char *sect_name, bfd_size_type *size_ptr) } *size_ptr = bfd_section_size (abfd, stabsect); + if (entsize_ptr) + *entsize_ptr = stabsect->entsize; return contents; } @@ -3118,11 +3131,11 @@ find_stabs_section (bfd *abfd, asection *section, void *names) { if (strtab == NULL) strtab = read_section_stabs (abfd, sought->string_section_name, - &stabstr_size); + &stabstr_size, NULL); if (strtab) { - stabs = read_section_stabs (abfd, section->name, &stab_size); + stabs = read_section_stabs (abfd, section->name, &stab_size, NULL); if (stabs) print_section_stabs (abfd, section->name, &sought->string_offset); } @@ -3184,6 +3197,140 @@ dump_bfd_header (bfd *abfd) bfd_printf_vma (abfd, abfd->start_address); printf ("\n"); } + + +/* Formatting callback function passed to ctf_dump. Returns either the pointer + it is passed, or a pointer to newly-allocated storage, in which case + dump_ctf() will free it when it no longer needs it. */ + +static char * +dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED, + char *s, void *arg) +{ + char *spaces = arg; + char *new_s; + + if (asprintf (&new_s, "%s%s", spaces, s) < 0) + return s; + return new_s; +} + +/* Make a ctfsect suitable for ctf_bfdopen_ctfsect(). */ +static ctf_sect_t +make_ctfsect (const char *name, bfd_byte *data, + bfd_size_type size) +{ + ctf_sect_t ctfsect; + + ctfsect.cts_name = name; + ctfsect.cts_type = SHT_PROGBITS; + ctfsect.cts_flags = 0; + ctfsect.cts_entsize = 1; + ctfsect.cts_offset = 0; + ctfsect.cts_size = size; + ctfsect.cts_data = data; + + return ctfsect; +} + +/* Dump one CTF archive member. */ + +static int +dump_ctf_archive_member (ctf_file_t *ctf, const char *name, void *arg) +{ + ctf_file_t *parent = (ctf_file_t *) arg; + const char *things[] = {"Labels", "Data objects", "Function objects", + "Variables", "Types", "Strings", ""}; + const char **thing; + size_t i; + + /* Only print out the name of non-default-named archive members. + The name .ctf appears everywhere, even for things that aren't + really archives, so printing it out is liable to be confusing. */ + if (strcmp (name, ".ctf") != 0) + printf (_("\nCTF archive member: %s:\n"), sanitize_string (name)); + + ctf_import (ctf, parent); + for (i = 1, thing = things; *thing[0]; thing++, i++) + { + ctf_dump_state_t *s = NULL; + char *item; + + printf ("\n %s:\n", *thing); + while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines, + (void *) " ")) != NULL) + { + printf ("%s\n", item); + free (item); + } + + if (ctf_errno (ctf)) + { + non_fatal (_("Iteration failed: %s, %s\n"), *thing, + ctf_errmsg (ctf_errno (ctf))); + break; + } + } + return 0; +} + +/* Dump the CTF debugging information. */ + +static void +dump_ctf (bfd *abfd, const char *sect_name, const char *parent_name) +{ + ctf_archive_t *ctfa, *parenta = NULL; + bfd_byte *ctfdata, *parentdata = NULL; + bfd_size_type ctfsize, parentsize; + ctf_sect_t ctfsect; + ctf_file_t *parent = NULL; + int err; + + if ((ctfdata = read_section_stabs (abfd, sect_name, &ctfsize, NULL)) == NULL) + bfd_fatal (bfd_get_filename (abfd)); + + if (parent_name + && (parentdata = read_section_stabs (abfd, parent_name, &parentsize, + NULL)) == NULL) + bfd_fatal (bfd_get_filename (abfd)); + + /* Load the CTF file and dump it. */ + + ctfsect = make_ctfsect (sect_name, ctfdata, ctfsize); + if ((ctfa = ctf_bfdopen_ctfsect (abfd, &ctfsect, &err)) == NULL) + { + non_fatal (_("CTF open failure: %s\n"), ctf_errmsg (err)); + bfd_fatal (bfd_get_filename (abfd)); + } + + if (parentdata) + { + ctfsect = make_ctfsect (parent_name, parentdata, parentsize); + if ((parenta = ctf_bfdopen_ctfsect (abfd, &ctfsect, &err)) == NULL) + { + non_fatal (_("CTF open failure: %s\n"), ctf_errmsg (err)); + bfd_fatal (bfd_get_filename (abfd)); + } + + /* Assume that the applicable parent archive member is the default one. + (This is what all known implementations are expected to do, if they + put CTFs and their parents in archives together.) */ + if ((parent = ctf_arc_open_by_name (parenta, NULL, &err)) == NULL) + { + non_fatal (_("CTF open failure: %s\n"), ctf_errmsg (err)); + bfd_fatal (bfd_get_filename (abfd)); + } + } + + printf (_("Contents of CTF section %s:\n"), sanitize_string (sect_name)); + + ctf_archive_iter (ctfa, dump_ctf_archive_member, parent); + ctf_file_close (parent); + ctf_close (ctfa); + ctf_close (parenta); + free (parentdata); + free (ctfdata); +} static void @@ -3896,6 +4043,8 @@ dump_bfd (bfd *abfd, bfd_boolean is_mainfile) dump_symbols (abfd, TRUE); if (dump_dwarf_section_info) dump_dwarf (abfd); + if (dump_ctf_section_info) + dump_ctf (abfd, dump_ctf_section_name, dump_ctf_parent_name); if (dump_stab_section_info) dump_stabs (abfd); if (dump_reloc_info && ! disassemble) @@ -4335,6 +4484,14 @@ main (int argc, char **argv) case OPTION_DWARF_CHECK: dwarf_check = TRUE; break; + case OPTION_CTF: + dump_ctf_section_info = TRUE; + dump_ctf_section_name = xstrdup (optarg); + seenflag = TRUE; + break; + case OPTION_CTF_PARENT: + dump_ctf_parent_name = xstrdup (optarg); + break; case 'G': dump_stab_section_info = TRUE; seenflag = TRUE; @@ -4394,6 +4551,8 @@ main (int argc, char **argv) } free_only_list (); + free (dump_ctf_section_name); + free (dump_ctf_parent_name); END_PROGRESS (program_name); diff --git a/binutils/readelf.c b/binutils/readelf.c index 424624e..5ae5857 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -60,6 +60,7 @@ #include "bucomm.h" #include "elfcomm.h" #include "dwarf.h" +#include "ctf-api.h" #include "elf/common.h" #include "elf/external.h" @@ -183,6 +184,7 @@ typedef struct elf_section_list #define DEBUG_DUMP (1 << 2) /* The -w command line switch. */ #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. */ typedef unsigned char dump_type; @@ -249,12 +251,17 @@ static bfd_boolean do_dump = FALSE; static bfd_boolean do_version = FALSE; static bfd_boolean do_histogram = FALSE; static bfd_boolean do_debugging = FALSE; +static bfd_boolean do_ctf = FALSE; static bfd_boolean do_arch = FALSE; static bfd_boolean do_notes = FALSE; static bfd_boolean do_archive_index = FALSE; static bfd_boolean is_32bit_elf = FALSE; static bfd_boolean decompress_dumps = FALSE; +static char *dump_ctf_parent_name; +static char *dump_ctf_symtab_name; +static char *dump_ctf_strtab_name; + struct group_list { struct group_list * next; @@ -4394,6 +4401,10 @@ get_section_type_name (Filedata * filedata, unsigned int sh_type) #define OPTION_DWARF_DEPTH 514 #define OPTION_DWARF_START 515 #define OPTION_DWARF_CHECK 516 +#define OPTION_CTF_DUMP 517 +#define OPTION_CTF_PARENT 518 +#define OPTION_CTF_SYMBOLS 519 +#define OPTION_CTF_STRINGS 520 static struct option options[] = { @@ -4432,6 +4443,12 @@ static struct option options[] = {"dwarf-start", required_argument, 0, OPTION_DWARF_START}, {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK}, + {"ctf", required_argument, 0, OPTION_CTF_DUMP}, + + {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS}, + {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS}, + {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT}, + {"version", no_argument, 0, 'v'}, {"wide", no_argument, 0, 'W'}, {"help", no_argument, 0, 'H'}, @@ -4481,6 +4498,15 @@ usage (FILE * stream) --dwarf-depth=N Do not display DIEs at depth N or greater\n\ --dwarf-start=N Display DIEs starting with N, at the same depth\n\ or deeper\n")); + fprintf (stream, _("\ + --ctf=<number|name> Display CTF info from section <number|name>\n\ + --ctf-parent=<number|name>\n\ + Use section <number|name> as the CTF parent\n\n\ + --ctf-symbols=<number|name>\n\ + Use section <number|name> as the CTF external symtab\n\n\ + --ctf-strings=<number|name>\n\ + Use section <number|name> as the CTF external strtab\n\n")); + #ifdef SUPPORT_DISASSEMBLY fprintf (stream, _("\ -i --instruction-dump=<number|name>\n\ @@ -4708,6 +4734,19 @@ parse_args (Filedata * filedata, int argc, char ** argv) case OPTION_DWARF_CHECK: dwarf_check = TRUE; break; + case OPTION_CTF_DUMP: + do_ctf = TRUE; + request_dump (filedata, CTF_DUMP); + break; + case OPTION_CTF_SYMBOLS: + dump_ctf_symtab_name = strdup (optarg); + break; + case OPTION_CTF_STRINGS: + dump_ctf_strtab_name = strdup (optarg); + break; + case OPTION_CTF_PARENT: + dump_ctf_parent_name = strdup (optarg); + break; case OPTION_DYN_SYMS: do_dyn_syms = TRUE; break; @@ -13769,6 +13808,163 @@ dump_section_as_bytes (Elf_Internal_Shdr * section, return TRUE; } +static ctf_sect_t * +shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata) +{ + buf->cts_name = SECTION_NAME(shdr); + buf->cts_type = shdr->sh_type; + buf->cts_flags = shdr->sh_flags; + buf->cts_size = shdr->sh_size; + buf->cts_entsize = shdr->sh_entsize; + buf->cts_offset = (off64_t) shdr->sh_offset; + + return buf; +} + +/* Formatting callback function passed to ctf_dump. Returns either the pointer + it is passed, or a pointer to newly-allocated storage, in which case + dump_ctf() will free it when it no longer needs it. */ + +static char *dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED, + char *s, void *arg) +{ + char *spaces = arg; + char *new_s; + + if (asprintf (&new_s, "%s%s", spaces, s) < 0) + return s; + return new_s; +} + +static bfd_boolean +dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata) +{ + Elf_Internal_Shdr * parent_sec = NULL; + Elf_Internal_Shdr * symtab_sec = NULL; + Elf_Internal_Shdr * strtab_sec = NULL; + void * data = NULL; + void * symdata = NULL; + void * strdata = NULL; + void * parentdata = NULL; + ctf_sect_t ctfsect, symsect, strsect, parentsect; + ctf_sect_t * symsectp = NULL; + ctf_sect_t * strsectp = NULL; + ctf_file_t * ctf = NULL; + ctf_file_t * parent = NULL; + + const char *things[] = {"Labels", "Data objects", "Function objects", + "Variables", "Types", "Strings", ""}; + const char **thing; + int err; + bfd_boolean ret = FALSE; + size_t i; + + shdr_to_ctf_sect (&ctfsect, section, filedata); + data = get_section_contents (section, filedata); + ctfsect.cts_data = data; + + if (dump_ctf_symtab_name) + { + if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL) + { + error (_("No symbol section named %s\n"), dump_ctf_symtab_name); + goto fail; + } + if ((symdata = (void *) get_data (NULL, filedata, + symtab_sec->sh_offset, 1, + symtab_sec->sh_size, + _("symbols"))) == NULL) + goto fail; + symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata); + symsect.cts_data = symdata; + } + if (dump_ctf_strtab_name) + { + if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL) + { + error (_("No string table section named %s\n"), + dump_ctf_strtab_name); + goto fail; + } + if ((strdata = (void *) get_data (NULL, filedata, + strtab_sec->sh_offset, 1, + strtab_sec->sh_size, + _("strings"))) == NULL) + goto fail; + strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata); + strsect.cts_data = strdata; + } + if (dump_ctf_parent_name) + { + if ((parent_sec = find_section (filedata, dump_ctf_parent_name)) == NULL) + { + error (_("No CTF parent section named %s\n"), dump_ctf_parent_name); + goto fail; + } + if ((parentdata = (void *) get_data (NULL, filedata, + parent_sec->sh_offset, 1, + parent_sec->sh_size, + _("CTF parent"))) == NULL) + goto fail; + shdr_to_ctf_sect (&parentsect, parent_sec, filedata); + parentsect.cts_data = parentdata; + } + + /* Load the CTF file and dump it. */ + + if ((ctf = ctf_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL) + { + error (_("CTF open failure: %s\n"), ctf_errmsg (err)); + goto fail; + } + + if (parentdata) + { + if ((parent = ctf_bufopen (&parentsect, symsectp, strsectp, &err)) == NULL) + { + error (_("CTF open failure: %s\n"), ctf_errmsg (err)); + goto fail; + } + + ctf_import (ctf, parent); + } + + ret = TRUE; + + printf (_("\nDump of CTF section '%s':\n"), + printable_section_name (filedata, section)); + + for (i = 1, thing = things; *thing[0]; thing++, i++) + { + ctf_dump_state_t *s = NULL; + char *item; + + printf ("\n %s:\n", *thing); + while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines, + (void *) " ")) != NULL) + { + printf ("%s\n", item); + free (item); + } + + if (ctf_errno (ctf)) + { + error (_("Iteration failed: %s, %s\n"), *thing, + ctf_errmsg (ctf_errno (ctf))); + ret = FALSE; + } + } + + fail: + ctf_file_close (ctf); + ctf_file_close (parent); + free (parentdata); + free (data); + free (symdata); + free (strdata); + return ret; +} + static bfd_boolean load_specific_debug_section (enum dwarf_section_display_enum debug, const Elf_Internal_Shdr * sec, @@ -14106,6 +14302,12 @@ process_section_contents (Filedata * filedata) if (! display_debug_section (i, section, filedata)) res = FALSE; } + + if (dump & CTF_DUMP) + { + if (! dump_section_as_ctf (section, filedata)) + res = FALSE; + } } /* Check to see if the user requested a @@ -19985,5 +20187,9 @@ main (int argc, char ** argv) if (cmdline.dump_sects != NULL) free (cmdline.dump_sects); + free (dump_ctf_symtab_name); + free (dump_ctf_strtab_name); + free (dump_ctf_parent_name); + return err ? EXIT_FAILURE : EXIT_SUCCESS; } |