+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
OPCODES = ../opcodes/libopcodes.la
+LIBCTF = ../libctf/libctf.a
+
LIBIBERTY = ../libiberty/libiberty.a
POTFILES = $(CFILES) $(DEBUG_SRCS) $(HFILES)
# 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)
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)
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)
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
$(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 \
$(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)
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
# 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)
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)
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)
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
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])
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])
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 \
$(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)
[@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}]
[@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}]
@item --dwarf-check
Enable additional checks for consistency of Dwarf information.
+@include ctf.options.texi
+
@item -G
@itemx --stabs
@cindex stab
@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}]
@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
--- /dev/null
+@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.
#include "bucomm.h"
#include "elfcomm.h"
#include "dwarf.h"
+#include "ctf-api.h"
#include "getopt.h"
#include "safe-ctype.h"
#include "dis-asm.h"
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 */
=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\
--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);
OPTION_DWARF_START,
OPTION_RECURSE_LIMIT,
OPTION_NO_RECURSE_LIMIT,
- OPTION_INLINES
+ OPTION_INLINES,
+ OPTION_CTF,
+ OPTION_CTF_PARENT
};
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},
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;
}
*size_ptr = bfd_section_size (abfd, stabsect);
+ if (entsize_ptr)
+ *entsize_ptr = stabsect->entsize;
return contents;
}
{
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);
}
bfd_printf_vma (abfd, abfd->start_address);
printf ("\n");
}
+\f
+
+/* 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);
+}
\f
static void
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)
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;
}
free_only_list ();
+ free (dump_ctf_section_name);
+ free (dump_ctf_parent_name);
END_PROGRESS (program_name);
#include "bucomm.h"
#include "elfcomm.h"
#include "dwarf.h"
+#include "ctf-api.h"
#include "elf/common.h"
#include "elf/external.h"
#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;
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;
#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[] =
{
{"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'},
--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\
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;
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,
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
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;
}