summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Gingold <gingold@adacore.com>2011-05-16 12:22:10 +0000
committerTristan Gingold <gingold@adacore.com>2011-05-16 12:22:10 +0000
commita31082056a9d42f736b884dbdf0bcab78d9ca44e (patch)
tree4fd39ec15f8e329e3a53400f95a689a2819ecf72
parentf32deb62a0953e3125a167efd6dad732cc7d809d (diff)
downloadbinutils-redhat-a31082056a9d42f736b884dbdf0bcab78d9ca44e.tar.gz
2011-05-16 Tristan Gingold <gingold@adacore.com>
* od-xcoff.c: New file. * objdump.h: New file. * objdump.c: Include objdump.h (dump_private_options, objdump_private_vectors): New variables. (usage): Mention -P/--private. Display handled options. (long_options): Add -P/--private. (dump_target_specific): New function. (dump_bfd): Handle dump_private_options. (main): Handle -P. * doc/binutils.texi (objdump): Document -P/--private. * configure.in (OBJDUMP_PRIVATE_VECTORS, OBJDUMP_PRIVATE_OFILES): New variables, compute them. (od_vectors): Add vectors for private dumpers. Make them uniq. (OBJDUMP_DEFS): Add OBJDUMP_PRIVATE_VECTORS. * Makefile.am (HFILES): Add objdump.h (CFILES): Add od-xcoff.c (OBJDUMP_PRIVATE_OFILES): New variable. (objdump_DEPENDENCIES): Append OBJDUMP_PRIVATE_OFILES. (objdump_LDADD): Ditto. (EXTRA_objdump_SOURCES): Define. * Makefile.in: Regenerate. * configure: Regenerate.
-rw-r--r--binutils/Makefile.am11
-rw-r--r--binutils/Makefile.in19
-rwxr-xr-xbinutils/configure51
-rw-r--r--binutils/configure.in46
-rw-r--r--binutils/doc/binutils.texi14
-rw-r--r--binutils/objdump.c80
-rw-r--r--binutils/objdump.h50
-rw-r--r--binutils/od-xcoff.c1670
8 files changed, 1928 insertions, 13 deletions
diff --git a/binutils/Makefile.am b/binutils/Makefile.am
index 65460878b0..6f9e4a8ebf 100644
--- a/binutils/Makefile.am
+++ b/binutils/Makefile.am
@@ -85,7 +85,7 @@ AM_CPPFLAGS = -I. -I$(srcdir) -I../bfd -I$(BFDDIR) -I$(INCDIR) \
HFILES = \
arsup.h binemul.h bucomm.h budbg.h \
coffgrok.h debug.h dlltool.h dwarf.h elfcomm.h nlmconv.h \
- sysdep.h unwind-ia64.h windres.h winduni.h windint.h \
+ objdump.h sysdep.h unwind-ia64.h windres.h winduni.h windint.h \
windmc.h
GENERATED_HFILES = arparse.h sysroff.h sysinfo.h defparse.h rcparse.h mcparse.h
@@ -99,6 +99,7 @@ CFILES = \
ieee.c is-ranlib.c is-strip.c maybe-ranlib.c maybe-strip.c \
nlmconv.c nm.c not-ranlib.c not-strip.c \
objcopy.c objdump.c prdbg.c \
+ od-xcoff.c \
rclex.c rdcoff.c rddbg.c readelf.c rename.c \
resbin.c rescoff.c resrc.c resres.c \
size.c srconv.c stabs.c strings.c sysdump.c \
@@ -113,6 +114,9 @@ GENERATED_CFILES = \
DEBUG_SRCS = rddbg.c debug.c stabs.c ieee.c rdcoff.c
WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c
+# Extra object files for objdump
+OBJDUMP_PRIVATE_OFILES = @OBJDUMP_PRIVATE_OFILES@
+
# Code shared by all the binutils.
BULIBS = bucomm.c version.c filemode.c
@@ -167,7 +171,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_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB) $(OPCODES) $(OBJDUMP_PRIVATE_OFILES)
nm_new_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
ar_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
strings_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
@@ -206,7 +210,8 @@ 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)
-objdump_LDADD = $(OPCODES) $(BFDLIB) $(LIBIBERTY) $(LIBINTL)
+EXTRA_objdump_SOURCES = od-xcoff.c
+objdump_LDADD = $(OBJDUMP_PRIVATE_OFILES) $(OPCODES) $(BFDLIB) $(LIBIBERTY) $(LIBINTL)
objdump.@OBJEXT@:objdump.c
if am__fastdepCC
diff --git a/binutils/Makefile.in b/binutils/Makefile.in
index 8e3d7f2faf..10b9e3f674 100644
--- a/binutils/Makefile.in
+++ b/binutils/Makefile.in
@@ -200,9 +200,10 @@ SOURCES = $(addr2line_SOURCES) $(ar_SOURCES) $(EXTRA_ar_SOURCES) \
$(coffdump_SOURCES) $(cxxfilt_SOURCES) $(dlltool_SOURCES) \
$(dllwrap_SOURCES) $(elfedit_SOURCES) $(nlmconv_SOURCES) \
$(nm_new_SOURCES) $(objcopy_SOURCES) $(objdump_SOURCES) \
- $(ranlib_SOURCES) $(readelf_SOURCES) $(size_SOURCES) \
- $(srconv_SOURCES) $(strings_SOURCES) $(strip_new_SOURCES) \
- $(sysdump_SOURCES) $(windmc_SOURCES) $(windres_SOURCES)
+ $(EXTRA_objdump_SOURCES) $(ranlib_SOURCES) $(readelf_SOURCES) \
+ $(size_SOURCES) $(srconv_SOURCES) $(strings_SOURCES) \
+ $(strip_new_SOURCES) $(sysdump_SOURCES) $(windmc_SOURCES) \
+ $(windres_SOURCES)
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-dvi-recursive install-exec-recursive \
@@ -298,6 +299,9 @@ NMEDIT = @NMEDIT@
NO_WERROR = @NO_WERROR@
OBJDUMP = @OBJDUMP@
OBJDUMP_DEFS = @OBJDUMP_DEFS@
+
+# Extra object files for objdump
+OBJDUMP_PRIVATE_OFILES = @OBJDUMP_PRIVATE_OFILES@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -429,7 +433,7 @@ AM_CPPFLAGS = -I. -I$(srcdir) -I../bfd -I$(BFDDIR) -I$(INCDIR) \
HFILES = \
arsup.h binemul.h bucomm.h budbg.h \
coffgrok.h debug.h dlltool.h dwarf.h elfcomm.h nlmconv.h \
- sysdep.h unwind-ia64.h windres.h winduni.h windint.h \
+ objdump.h sysdep.h unwind-ia64.h windres.h winduni.h windint.h \
windmc.h
GENERATED_HFILES = arparse.h sysroff.h sysinfo.h defparse.h rcparse.h mcparse.h
@@ -442,6 +446,7 @@ CFILES = \
ieee.c is-ranlib.c is-strip.c maybe-ranlib.c maybe-strip.c \
nlmconv.c nm.c not-ranlib.c not-strip.c \
objcopy.c objdump.c prdbg.c \
+ od-xcoff.c \
rclex.c rdcoff.c rddbg.c readelf.c rename.c \
resbin.c rescoff.c resrc.c resres.c \
size.c srconv.c stabs.c strings.c sysdump.c \
@@ -487,7 +492,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_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB) $(OPCODES) $(OBJDUMP_PRIVATE_OFILES)
nm_new_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
ar_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
strings_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB)
@@ -517,7 +522,8 @@ 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)
-objdump_LDADD = $(OPCODES) $(BFDLIB) $(LIBIBERTY) $(LIBINTL)
+EXTRA_objdump_SOURCES = od-xcoff.c
+objdump_LDADD = $(OBJDUMP_PRIVATE_OFILES) $(OPCODES) $(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)
@@ -796,6 +802,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/not-strip.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/objcopy.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/objdump.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/od-xcoff.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prdbg.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rclex.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rcparse.Po@am__quote@
diff --git a/binutils/configure b/binutils/configure
index b191a616b0..003b6f1e25 100755
--- a/binutils/configure
+++ b/binutils/configure
@@ -604,6 +604,7 @@ LTLIBOBJS
LIBOBJS
EMULATION_VECTOR
EMULATION
+OBJDUMP_PRIVATE_OFILES
OBJDUMP_DEFS
BUILD_INSTALL_MISC
BUILD_MISC
@@ -11198,7 +11199,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11201 "configure"
+#line 11202 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11304,7 +11305,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11307 "configure"
+#line 11308 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -13779,6 +13780,9 @@ BUILD_DLLWRAP=
BUILD_MISC=
BUILD_INSTALL_MISC=
OBJDUMP_DEFS=
+OBJDUMP_PRIVATE_VECTORS=
+OBJDUMP_PRIVATE_OFILES=
+od_vectors=
for targ in $target $canon_targets
do
@@ -13796,6 +13800,7 @@ do
fi
DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_I386"
BUILD_DLLWRAP='$(DLLWRAP_PROG)$(EXEEXT)'
+ od_vectors="$od_vectors objdump_private_desc_xcoff"
else
case $targ in
i[3-7]86*-*-netware*)
@@ -13815,9 +13820,11 @@ do
NLMCONV_DEFS="$NLMCONV_DEFS -DNLMCONV_SPARC"
;;
esac
+
case $targ in
*-*-hms*) BUILD_SRCONV='$(SRCONV_PROG)' ;;
esac
+
case $targ in
arm-epoc-pe*)
BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
@@ -13931,9 +13938,46 @@ do
OBJDUMP_DEFS="-DSKIP_ZEROES=256 -DSKIP_ZEROES_AT_END=0"
;;
esac
+
+ # Add objdump private vectors.
+ case $targ in
+ powerpc-*-aix*)
+ od_vectors="$od_vectors objdump_private_desc_xcoff"
+ ;;
+ esac
fi
done
+# Uniq objdump private vector, build objdump target ofiles.
+od_files=
+f=""
+for i in $od_vectors ; do
+ case " $f " in
+ *" $i "*) ;;
+ *)
+ f="$f $i"
+ OBJDUMP_PRIVATE_VECTORS="$OBJDUMP_PRIVATE_VECTORS &$i,"
+ case $i in
+ objdump_private_desc_xcoff)
+ od_files="$od_files od-xcoff" ;;
+ *) as_fn_error "*** unknown private vector $i" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+done
+
+# Uniq objdump target ofiles
+f=""
+for i in $od_files ; do
+ case " $f " in
+ *" $i "*) ;;
+ *)
+ f="$f $i"
+ OBJDUMP_PRIVATE_OFILES="$OBJDUMP_PRIVATE_OFILES $i.$objext"
+ ;;
+ esac
+done
+
DLLTOOL_DEFS="$DLLTOOL_DEFS $DLLTOOL_DEFAULT"
if test "${with_windres+set}" = set; then
@@ -13944,6 +13988,9 @@ if test "${with_windmc+set}" = set; then
BUILD_WINDMC='$(WINDMC_PROG)$(EXEEXT)'
fi
+OBJDUMP_DEFS="${OBJDUMP_DEFS} -DOBJDUMP_PRIVATE_VECTORS=\"${OBJDUMP_PRIVATE_VECTORS}\""
+
+
diff --git a/binutils/configure.in b/binutils/configure.in
index b1564bb856..4a03c75d13 100644
--- a/binutils/configure.in
+++ b/binutils/configure.in
@@ -179,6 +179,9 @@ BUILD_DLLWRAP=
BUILD_MISC=
BUILD_INSTALL_MISC=
OBJDUMP_DEFS=
+OBJDUMP_PRIVATE_VECTORS=
+OBJDUMP_PRIVATE_OFILES=
+od_vectors=
for targ in $target $canon_targets
do
@@ -196,6 +199,7 @@ do
fi
DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_I386"
BUILD_DLLWRAP='$(DLLWRAP_PROG)$(EXEEXT)'
+ od_vectors="$od_vectors objdump_private_desc_xcoff"
else
case $targ in
changequote(,)dnl
@@ -217,9 +221,11 @@ changequote([,])dnl
NLMCONV_DEFS="$NLMCONV_DEFS -DNLMCONV_SPARC"
;;
esac
+
case $targ in
*-*-hms*) BUILD_SRCONV='$(SRCONV_PROG)' ;;
esac
+
case $targ in
arm-epoc-pe*)
BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
@@ -341,9 +347,46 @@ changequote([,])dnl
OBJDUMP_DEFS="-DSKIP_ZEROES=256 -DSKIP_ZEROES_AT_END=0"
;;
esac
+
+ # Add objdump private vectors.
+ case $targ in
+ powerpc-*-aix*)
+ od_vectors="$od_vectors objdump_private_desc_xcoff"
+ ;;
+ esac
fi
done
+# Uniq objdump private vector, build objdump target ofiles.
+od_files=
+f=""
+for i in $od_vectors ; do
+ case " $f " in
+ *" $i "*) ;;
+ *)
+ f="$f $i"
+ OBJDUMP_PRIVATE_VECTORS="$OBJDUMP_PRIVATE_VECTORS &$i,"
+ case $i in
+ objdump_private_desc_xcoff)
+ od_files="$od_files od-xcoff" ;;
+ *) AC_MSG_ERROR(*** unknown private vector $i) ;;
+ esac
+ ;;
+ esac
+done
+
+# Uniq objdump target ofiles
+f=""
+for i in $od_files ; do
+ case " $f " in
+ *" $i "*) ;;
+ *)
+ f="$f $i"
+ OBJDUMP_PRIVATE_OFILES="$OBJDUMP_PRIVATE_OFILES $i.$objext"
+ ;;
+ esac
+done
+
DLLTOOL_DEFS="$DLLTOOL_DEFS $DLLTOOL_DEFAULT"
if test "${with_windres+set}" = set; then
@@ -354,6 +397,8 @@ if test "${with_windmc+set}" = set; then
BUILD_WINDMC='$(WINDMC_PROG)$(EXEEXT)'
fi
+OBJDUMP_DEFS="${OBJDUMP_DEFS} -DOBJDUMP_PRIVATE_VECTORS=\"${OBJDUMP_PRIVATE_VECTORS}\""
+
AC_SUBST(NLMCONV_DEFS)
AC_SUBST(BUILD_NLMCONV)
AC_SUBST(BUILD_SRCONV)
@@ -365,6 +410,7 @@ AC_SUBST(BUILD_DLLWRAP)
AC_SUBST(BUILD_MISC)
AC_SUBST(BUILD_INSTALL_MISC)
AC_SUBST(OBJDUMP_DEFS)
+AC_SUBST(OBJDUMP_PRIVATE_OFILES)
AC_DEFINE_UNQUOTED(TARGET, "${target}", [Configured target name.])
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index 08e1c4e276..fb3948f4a9 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -1744,6 +1744,7 @@ objdump [@option{-a}|@option{--archive-headers}]
[@option{-m} @var{machine}|@option{--architecture=}@var{machine}]
[@option{-M} @var{options}|@option{--disassembler-options=}@var{options}]
[@option{-p}|@option{--private-headers}]
+ [@option{-P} @var{options}|@option{--private=}@var{options}]
[@option{-r}|@option{--reloc}]
[@option{-R}|@option{--dynamic-reloc}]
[@option{-s}|@option{--full-contents}]
@@ -1787,7 +1788,7 @@ object files.
The long and short forms of options, shown here as alternatives, are
equivalent. At least one option from the list
-@option{-a,-d,-D,-e,-f,-g,-G,-h,-H,-p,-r,-R,-s,-S,-t,-T,-V,-x} must be given.
+@option{-a,-d,-D,-e,-f,-g,-G,-h,-H,-p,-P,-r,-R,-s,-S,-t,-T,-V,-x} must be given.
@table @env
@item -a
@@ -2066,6 +2067,17 @@ Print information that is specific to the object file format. The exact
information printed depends upon the object file format. For some
object file formats, no additional information is printed.
+@item -P @var{options}
+@itemx --private=@var{options}
+Print information that is specific to the object file format. The
+argument @var{options} is a comma separated list that depends on the
+format (the lists of options is displayed with the help).
+
+For XCOFF, the available options are: @option{header}, @option{aout},
+@option{sections}, @option{syms}, @option{relocs}, @option{lineno},
+@option{loader}, @option{except}, @option{typchk}, @option{traceback}
+and @option{toc}.
+
@item -r
@itemx --reloc
@cindex relocation entries, in object file
diff --git a/binutils/objdump.c b/binutils/objdump.c
index 231a66867a..784ead27e0 100644
--- a/binutils/objdump.c
+++ b/binutils/objdump.c
@@ -65,6 +65,7 @@
#include "filenames.h"
#include "debug.h"
#include "budbg.h"
+#include "objdump.h"
#ifdef HAVE_MMAP
#include <sys/mman.h>
@@ -93,6 +94,7 @@ static int dump_reloc_info; /* -r */
static int dump_dynamic_reloc_info; /* -R */
static int dump_ar_hdrs; /* -a */
static int dump_private_headers; /* -p */
+static char *dump_private_options; /* -P */
static int prefix_addresses; /* --prefix-addresses */
static int with_line_numbers; /* -l */
static bfd_boolean with_source_code; /* -S */
@@ -185,6 +187,13 @@ static char *strtab;
static bfd_size_type stabstr_size;
static bfd_boolean is_relocatable = FALSE;
+
+/* Handlers for -P/--private. */
+static const struct objdump_private_desc * const objdump_private_vectors[] =
+ {
+ OBJDUMP_PRIVATE_VECTORS
+ NULL
+ };
static void
usage (FILE *stream, int status)
@@ -196,6 +205,7 @@ usage (FILE *stream, int status)
-a, --archive-headers Display archive header information\n\
-f, --file-headers Display the contents of the overall file header\n\
-p, --private-headers Display object format specific file header contents\n\
+ -P, --private=OPT,OPT... Display object format specific contents\n\
-h, --[section-]headers Display the contents of the section headers\n\
-x, --all-headers Display the contents of all headers\n\
-d, --disassemble Display assembler contents of executable sections\n\
@@ -221,6 +231,8 @@ usage (FILE *stream, int status)
"));
if (status != 2)
{
+ const struct objdump_private_desc * const *desc;
+
fprintf (stream, _("\n The following switches are optional:\n"));
fprintf (stream, _("\
-b, --target=BFDNAME Specify the target object format as BFDNAME\n\
@@ -256,6 +268,14 @@ usage (FILE *stream, int status)
list_supported_architectures (program_name, stream);
disassembler_usage (stream);
+
+ if (objdump_private_vectors[0] != NULL)
+ {
+ fprintf (stream,
+ _("\nOptions supported for -P/--private switch:\n"));
+ for (desc = objdump_private_vectors; *desc != NULL; desc++)
+ (*desc)->help (stream);
+ }
}
if (REPORT_BUGS_TO[0] && status == 0)
fprintf (stream, _("Report bugs to %s.\n"), REPORT_BUGS_TO);
@@ -282,6 +302,7 @@ static struct option long_options[]=
{"adjust-vma", required_argument, NULL, OPTION_ADJUST_VMA},
{"all-headers", no_argument, NULL, 'x'},
{"private-headers", no_argument, NULL, 'p'},
+ {"private", required_argument, NULL, 'P'},
{"architecture", required_argument, NULL, 'm'},
{"archive-headers", no_argument, NULL, 'a'},
{"debugging", no_argument, NULL, 'g'},
@@ -2595,6 +2616,57 @@ dump_bfd_private_header (bfd *abfd)
bfd_print_private_bfd_data (abfd, stdout);
}
+static void
+dump_target_specific (bfd *abfd)
+{
+ const struct objdump_private_desc * const *desc;
+ struct objdump_private_option *opt;
+ char *e, *b;
+
+ /* Find the desc. */
+ for (desc = objdump_private_vectors; *desc != NULL; desc++)
+ if ((*desc)->filter (abfd))
+ break;
+
+ if (desc == NULL)
+ {
+ non_fatal (_("option -P/--private not supported by this file"));
+ return;
+ }
+
+ /* Clear all options. */
+ for (opt = (*desc)->options; opt->name; opt++)
+ opt->selected = FALSE;
+
+ /* Decode options. */
+ b = dump_private_options;
+ do
+ {
+ e = strchr (b, ',');
+
+ if (e)
+ *e = 0;
+
+ for (opt = (*desc)->options; opt->name; opt++)
+ if (strcmp (opt->name, b) == 0)
+ {
+ opt->selected = TRUE;
+ break;
+ }
+ if (opt->name == NULL)
+ non_fatal (_("target specific dump '%s' not supported"), b);
+
+ if (e)
+ {
+ *e = ',';
+ b = e + 1;
+ }
+ }
+ while (e != NULL);
+
+ /* Dump. */
+ (*desc)->dump (abfd);
+}
/* Display a section in hexadecimal format with associated characters.
Each line prefixed by the zero padded address. */
@@ -3096,6 +3168,8 @@ dump_bfd (bfd *abfd)
dump_bfd_header (abfd);
if (dump_private_headers)
dump_bfd_private_header (abfd);
+ if (dump_private_options != NULL)
+ dump_target_specific (abfd);
if (! dump_debugging_tags && ! suppress_bfd_header)
putchar ('\n');
if (dump_section_headers)
@@ -3307,7 +3381,7 @@ main (int argc, char **argv)
set_default_bfd_target ();
while ((c = getopt_long (argc, argv,
- "pib:m:M:VvCdDlfFaHhrRtTxsSI:j:wE:zgeGW::",
+ "pP:ib:m:M:VvCdDlfFaHhrRtTxsSI:j:wE:zgeGW::",
long_options, (int *) 0))
!= EOF)
{
@@ -3424,6 +3498,10 @@ main (int argc, char **argv)
dump_private_headers = TRUE;
seenflag = TRUE;
break;
+ case 'P':
+ dump_private_options = optarg;
+ seenflag = TRUE;
+ break;
case 'x':
dump_private_headers = TRUE;
dump_symtab = TRUE;
diff --git a/binutils/objdump.h b/binutils/objdump.h
new file mode 100644
index 0000000000..511898c495
--- /dev/null
+++ b/binutils/objdump.h
@@ -0,0 +1,50 @@
+/* objdump.h
+ Copyright 2011 Free Software Foundation, Inc.
+
+ This file is part of GNU Binutils.
+
+ 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, 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, write to the Free Software
+ Foundation, 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include <stdio.h>
+
+struct objdump_private_option
+{
+ /* Option name. */
+ const char *name;
+
+ /* TRUE if the option is selected. Automatically set and cleared by
+ objdump. */
+ unsigned int selected;
+};
+
+struct objdump_private_desc
+{
+ /* Help displayed for --help. */
+ void (*help)(FILE *stream);
+
+ /* Return TRUE if these options can be applied to ABFD. */
+ int (*filter)(bfd *abfd);
+
+ /* Do the actual work: display whatever is requested according to the
+ options whose SELECTED field is set. */
+ void (*dump)(bfd *abfd);
+
+ /* List of options. Terminated by a NULL name. */
+ struct objdump_private_option *options;
+};
+
+/* XCOFF specific target. */
+extern const struct objdump_private_desc objdump_private_desc_xcoff;
diff --git a/binutils/od-xcoff.c b/binutils/od-xcoff.c
new file mode 100644
index 0000000000..47d0248847
--- /dev/null
+++ b/binutils/od-xcoff.c
@@ -0,0 +1,1670 @@
+/* od-xcoff.c -- dump information about an xcoff object file.
+ Copyright 2011 Free Software Foundation, Inc.
+ Written by Tristan Gingold, Adacore.
+
+ This file is part of GNU Binutils.
+
+ 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, 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, write to the Free Software
+ Foundation, 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include <stddef.h>
+#include <time.h>
+#include "sysdep.h"
+#include "safe-ctype.h"
+#include "bfd.h"
+#include "objdump.h"
+#include "bucomm.h"
+#include "bfdlink.h"
+/* Force the support of weak symbols. */
+#ifndef AIX_WEAK_SUPPORT
+#define AIX_WEAK_SUPPORT 1
+#endif
+#include "coff/internal.h"
+#include "coff/rs6000.h"
+#include "coff/xcoff.h"
+#include "libcoff.h"
+#include "libxcoff.h"
+
+/* Index of the options in the options[] array. */
+#define OPT_FILE_HEADER 0
+#define OPT_AOUT 1
+#define OPT_SECTIONS 2
+#define OPT_SYMS 3
+#define OPT_RELOCS 4
+#define OPT_LINENO 5
+#define OPT_LOADER 6
+#define OPT_EXCEPT 7
+#define OPT_TYPCHK 8
+#define OPT_TRACEBACK 9
+#define OPT_TOC 10
+
+/* List of actions. */
+static struct objdump_private_option options[] =
+ {
+ { "header", 0 },
+ { "aout", 0 },
+ { "sections", 0 },
+ { "syms", 0 },
+ { "relocs", 0 },
+ { "lineno", 0 },
+ { "loader", 0 },
+ { "except", 0 },
+ { "typchk", 0 },
+ { "traceback", 0 },
+ { "toc", 0 },
+ { NULL, 0 }
+ };
+
+/* Display help. */
+
+static void
+xcoff_help (FILE *stream)
+{
+ fprintf (stream, _("\
+For XCOFF files:\n\
+ header Display the file header\n\
+ aout Display the auxiliary header\n\
+ sections Display the section headers\n\
+ syms Display the symbols table\n\
+ relocs Display the relocation entries\n\
+ lineno Display the line number entries\n\
+ loader Display loader section\n\
+ except Display exception table\n\
+ typchk Display type-check section\n\
+ traceback Display traceback tags\n\
+ toc Display toc symbols\n\
+"));
+}
+
+/* Return TRUE if ABFD is handled. */
+
+static int
+xcoff_filter (bfd *abfd)
+{
+ return bfd_get_flavour (abfd) == bfd_target_xcoff_flavour;
+}
+
+/* Translation entry type. The last entry must be {0, NULL}. */
+
+struct xlat_table {
+ unsigned int val;
+ const char *name;
+};
+
+/* Display the list of name (from TABLE) for FLAGS, using comma to separate
+ them. A name is displayed if FLAGS & VAL is not 0. */
+
+static void
+dump_flags (const struct xlat_table *table, unsigned int flags)
+{
+ unsigned int r = flags;
+ int first = 1;
+ const struct xlat_table *t;
+
+ for (t = table; t->name; t++)
+ if ((flags & t->val) != 0)
+ {
+ r &= ~t->val;
+
+ if (first)
+ first = 0;
+ else
+ putchar (',');
+ fputs (t->name, stdout);
+ }
+
+ /* Not decoded flags. */
+ if (r != 0)
+ {
+ if (!first)
+ putchar (',');
+ printf ("0x%x", r);
+ }
+}
+
+/* Display the name corresponding to VAL from TABLE, using at most
+ MAXLEN char (possibly passed with spaces). */
+
+static void
+dump_value (const struct xlat_table *table, unsigned int val, int maxlen)
+{
+ const struct xlat_table *t;
+
+ for (t = table; t->name; t++)
+ if (t->val == val)
+ {
+ printf ("%-*s", maxlen, t->name);
+ return;
+ }
+ printf ("(%*x)", maxlen - 2, val);
+}
+
+/* Names of f_flags. */
+static const struct xlat_table f_flag_xlat[] =
+ {
+ { F_RELFLG, "no-rel" },
+ { F_EXEC, "exec" },
+ { F_LNNO, "lineno" },
+ { F_LSYMS, "lsyms" },
+
+ { F_FDPR_PROF, "fdpr-prof" },
+ { F_FDPR_OPTI, "fdpr-opti" },
+ { F_DSA, "dsa" },
+
+ { F_VARPG, "varprg" },
+
+ { F_DYNLOAD, "dynload" },
+ { F_SHROBJ, "shrobj" },
+ { F_NONEXEC, "nonexec" },
+
+ { 0, NULL }
+ };
+
+/* Names of s_flags. */
+static const struct xlat_table s_flag_xlat[] =
+ {
+ { STYP_PAD, "pad" },
+ { STYP_DWARF, "dwarf" },
+ { STYP_TEXT, "text" },
+ { STYP_DATA, "data" },
+ { STYP_BSS, "bss" },
+
+ { STYP_EXCEPT, "except" },
+ { STYP_INFO, "info" },
+ { STYP_TDATA, "tdata" },
+ { STYP_TBSS, "tbss" },
+
+ { STYP_LOADER, "loader" },
+ { STYP_DEBUG, "debug" },
+ { STYP_TYPCHK, "typchk" },
+ { STYP_OVRFLO, "ovrflo" },
+ { 0, NULL }
+ };
+
+/* Names of storage class. */
+static const struct xlat_table sc_xlat[] =
+ {
+#define SC_ENTRY(X) { C_##X, #X }
+ SC_ENTRY(NULL),
+ SC_ENTRY(AUTO),
+ SC_ENTRY(EXT),
+ SC_ENTRY(STAT),
+ SC_ENTRY(REG),
+ SC_ENTRY(EXTDEF),
+ SC_ENTRY(LABEL),
+ SC_ENTRY(ULABEL),
+ SC_ENTRY(MOS),
+ SC_ENTRY(ARG),
+ /* SC_ENTRY(STRARG), */
+ SC_ENTRY(MOU),
+ SC_ENTRY(UNTAG),
+ SC_ENTRY(TPDEF),
+ SC_ENTRY(USTATIC),
+ SC_ENTRY(ENTAG),
+ SC_ENTRY(MOE),
+ SC_ENTRY(REGPARM),
+ SC_ENTRY(FIELD),
+ SC_ENTRY(BLOCK),
+ SC_ENTRY(FCN),
+ SC_ENTRY(EOS),
+ SC_ENTRY(FILE),
+ SC_ENTRY(LINE),
+ SC_ENTRY(ALIAS),
+ SC_ENTRY(HIDDEN),
+ SC_ENTRY(HIDEXT),
+ SC_ENTRY(BINCL),
+ SC_ENTRY(EINCL),
+ SC_ENTRY(INFO),
+ SC_ENTRY(WEAKEXT),
+ SC_ENTRY(DWARF),
+
+ /* Stabs. */
+ SC_ENTRY (GSYM),
+ SC_ENTRY (LSYM),
+ SC_ENTRY (PSYM),
+ SC_ENTRY (RSYM),
+ SC_ENTRY (RPSYM),
+ SC_ENTRY (STSYM),
+ SC_ENTRY (TCSYM),
+ SC_ENTRY (BCOMM),
+ SC_ENTRY (ECOML),
+ SC_ENTRY (ECOMM),
+ SC_ENTRY (DECL),
+ SC_ENTRY (ENTRY),
+ SC_ENTRY (FUN),
+ SC_ENTRY (BSTAT),
+ SC_ENTRY (ESTAT),
+
+ { 0, NULL }
+#undef SC_ENTRY
+ };
+
+/* Names for symbol type. */
+static const struct xlat_table smtyp_xlat[] =
+ {
+ { XTY_ER, "ER" },
+ { XTY_SD, "SD" },
+ { XTY_LD, "LD" },
+ { XTY_CM, "CM" },
+ { XTY_EM, "EM" },
+ { XTY_US, "US" },
+ { 0, NULL }
+ };
+
+/* Names for storage-mapping class. */
+static const struct xlat_table smclas_xlat[] =
+ {
+#define SMCLAS_ENTRY(X) { XMC_##X, #X }
+ SMCLAS_ENTRY (PR),
+ SMCLAS_ENTRY (RO),
+ SMCLAS_ENTRY (DB),
+ SMCLAS_ENTRY (TC),
+ SMCLAS_ENTRY (UA),
+ SMCLAS_ENTRY (RW),
+ SMCLAS_ENTRY (GL),
+ SMCLAS_ENTRY (XO),
+ SMCLAS_ENTRY (SV),
+ SMCLAS_ENTRY (BS),
+ SMCLAS_ENTRY (DS),
+ SMCLAS_ENTRY (UC),
+ SMCLAS_ENTRY (TI),
+ SMCLAS_ENTRY (TB),
+ SMCLAS_ENTRY (TC0),
+ SMCLAS_ENTRY (TD),
+ SMCLAS_ENTRY (SV64),
+ SMCLAS_ENTRY (SV3264),
+ { 0, NULL }
+#undef SMCLAS_ENTRY
+ };
+
+/* Names for relocation type. */
+static const struct xlat_table rtype_xlat[] =
+ {
+#define RTYPE_ENTRY(X) { R_##X, #X }
+ RTYPE_ENTRY (POS),
+ RTYPE_ENTRY (NEG),
+ RTYPE_ENTRY (REL),
+ RTYPE_ENTRY (TOC),
+ RTYPE_ENTRY (RTB),
+ RTYPE_ENTRY (GL),
+ RTYPE_ENTRY (TCL),
+ RTYPE_ENTRY (BA),
+ RTYPE_ENTRY (BR),
+ RTYPE_ENTRY (RL),
+ RTYPE_ENTRY (RLA),
+ RTYPE_ENTRY (REF),
+ RTYPE_ENTRY (TRL),
+ RTYPE_ENTRY (TRLA),
+ RTYPE_ENTRY (RRTBI),
+ RTYPE_ENTRY (RRTBA),
+ RTYPE_ENTRY (CAI),
+ RTYPE_ENTRY (CREL),
+ RTYPE_ENTRY (RBA),
+ RTYPE_ENTRY (RBAC),
+ RTYPE_ENTRY (RBR),
+ RTYPE_ENTRY (RBRC),
+ RTYPE_ENTRY (TLS),
+ RTYPE_ENTRY (TLS_IE),
+ RTYPE_ENTRY (TLS_LD),
+ RTYPE_ENTRY (TLS_LE),
+ RTYPE_ENTRY (TLSM),
+ RTYPE_ENTRY (TLSML),
+ RTYPE_ENTRY (TOCU),
+ RTYPE_ENTRY (TOCL),
+ { 0, NULL }
+ };
+
+/* Simplified section header. */
+struct xcoff32_section
+{
+ /* NUL terminated name. */
+ char name[9];
+
+ /* Section flags. */
+ unsigned int flags;
+
+ /* Offsets in file. */
+ ufile_ptr scnptr;
+ ufile_ptr relptr;
+ ufile_ptr lnnoptr;
+
+ /* Number of relocs and line numbers. */
+ unsigned int nreloc;
+ unsigned int nlnno;
+};
+
+/* Simplified symbol. */
+
+union xcoff32_symbol
+{
+ union external_auxent aux;
+
+ struct sym
+ {
+ /* Pointer the the NUL-terminated name. */
+ char *name;
+
+ /* XCOFF symbol fields. */
+ unsigned int val;
+ unsigned short scnum;
+ unsigned short ntype;
+ unsigned char sclass;
+ unsigned char numaux;
+
+ /* Buffer in case the name is local. */
+ union
+ {
+ char name[9];
+ unsigned int off;
+ } raw;
+ } sym;
+};
+
+/* Important fields to dump the file. */
+
+struct xcoff_dump
+{
+ /* From file header. */
+ unsigned short nscns;
+ unsigned int symptr;
+ unsigned int nsyms;
+ unsigned short opthdr;
+
+ /* Sections. */
+ struct xcoff32_section *sects;
+
+ /* Symbols. */
+ union xcoff32_symbol *syms;
+ char *strings;
+ unsigned int strings_size;
+};
+
+/* Print a symbol (if possible). */
+
+static void
+xcoff32_print_symbol (struct xcoff_dump *data, unsigned int symndx)
+{
+ if (data->syms != NULL
+ && symndx < data->nsyms
+ && data->syms[symndx].sym.name != NULL)
+ printf ("%s", data->syms[symndx].sym.name);
+ else
+ printf ("%u", symndx);
+}
+
+/* Dump the file header. */
+
+static void
+dump_xcoff32_file_header (bfd *abfd, struct external_filehdr *fhdr,
+ struct xcoff_dump *data)
+{
+ unsigned int timdat = bfd_h_get_32 (abfd, fhdr->f_timdat);
+ unsigned short flags = bfd_h_get_16 (abfd, fhdr->f_flags);
+
+ printf (_(" nbr sections: %d\n"), data->nscns);
+ printf (_(" time and date: 0x%08x - "), timdat);
+ if (timdat == 0)
+ printf (_("not set\n"));
+ else
+ {
+ /* Not correct on all platforms, but works on unix. */
+ time_t t = timdat;
+ fputs (ctime (&t), stdout);
+ }
+ printf (_(" symbols off: 0x%08x\n"), data->symptr);
+ printf (_(" nbr symbols: %d\n"), data->nsyms);
+ printf (_(" opt hdr sz: %d\n"), data->opthdr);
+ printf (_(" flags: 0x%04x "), flags);
+ dump_flags (f_flag_xlat, flags);
+ putchar ('\n');
+}
+
+/* Dump the a.out header. */
+
+static void
+dump_xcoff32_aout_header (bfd *abfd, struct xcoff_dump *data)
+{
+ AOUTHDR auxhdr;
+ unsigned short magic;
+ unsigned int sz = data->opthdr;
+
+ printf (_("Auxiliary header:\n"));
+ if (data->opthdr == 0)
+ {
+ printf (_(" No aux header\n"));
+ return;
+ }
+ if (data->opthdr > sizeof (auxhdr))
+ {
+ printf (_("warning: optionnal header size too large (> %d)\n"),
+ (int)sizeof (auxhdr));
+ sz = sizeof (auxhdr);
+ }
+ if (bfd_bread (&auxhdr, sz, abfd) != sz)
+ {
+ non_fatal (_("cannot read auxhdr"));
+ return;
+ }
+
+ magic = bfd_h_get_16 (abfd, auxhdr.magic);
+ printf (_(" o_mflag (magic): 0x%04x 0%04o\n"), magic, magic);
+ printf (_(" o_vstamp: 0x%04x\n"),
+ (unsigned short)bfd_h_get_16 (abfd, auxhdr.vstamp));
+ printf (_(" o_tsize: 0x%08x\n"),
+ (unsigned int)bfd_h_get_32 (abfd, auxhdr.tsize));
+ printf (_(" o_dsize: 0x%08x\n"),
+ (unsigned int)bfd_h_get_32 (abfd, auxhdr.dsize));
+ printf (_(" o_entry: 0x%08x\n"),
+ (unsigned int)bfd_h_get_32 (abfd, auxhdr.entry));
+ printf (_(" o_text_start: 0x%08x\n"),
+ (unsigned int)bfd_h_get_32 (abfd, auxhdr.text_start));
+ printf (_(" o_data_start: 0x%08x\n"),
+ (unsigned int)bfd_h_get_32 (abfd, auxhdr.data_start));
+ if (sz == offsetof (AOUTHDR, o_toc))
+ return;
+ printf (_(" o_toc: 0x%08x\n"),
+ (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_toc));
+ printf (_(" o_snentry: 0x%04x\n"),
+ (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snentry));
+ printf (_(" o_sntext: 0x%04x\n"),
+ (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sntext));
+ printf (_(" o_sndata: 0x%04x\n"),
+ (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sndata));
+ printf (_(" o_sntoc: 0x%04x\n"),
+ (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sntoc));
+ printf (_(" o_snloader: 0x%04x\n"),
+ (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snloader));
+ printf (_(" o_snbss: 0x%04x\n"),
+ (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snbss));
+ printf (_(" o_algntext: %u\n"),
+ (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_algntext));
+ printf (_(" o_algndata: %u\n"),
+ (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_algndata));
+ printf (_(" o_modtype: 0x%04x"),
+ (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_modtype));
+ if (ISPRINT (auxhdr.o_modtype[0]) && ISPRINT (auxhdr.o_modtype[1]))
+ printf (" (%c%c)", auxhdr.o_modtype[0], auxhdr.o_modtype[1]);
+ putchar ('\n');
+ printf (_(" o_cputype: 0x%04x\n"),
+ (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_cputype));
+ printf (_(" o_maxstack: 0x%08x\n"),
+ (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_maxstack));
+ printf (_(" o_maxdata: 0x%08x\n"),
+ (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_maxdata));
+#if 0
+ printf (_(" o_debugger: 0x%08x\n"),
+ (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_debugger));
+#endif
+}
+
+/* Dump the sections header. */
+
+static void
+dump_xcoff32_sections_header (bfd *abfd, struct xcoff_dump *data)
+{
+ unsigned int i;
+ unsigned int off;
+
+ off = sizeof (struct external_filehdr) + data->opthdr;
+ printf (_("Section headers (at %u+%u=0x%08x to 0x%08x):\n"),
+ (unsigned int)sizeof (struct external_filehdr), data->opthdr, off,
+ off + (unsigned int)sizeof (struct external_scnhdr) * data->nscns);
+ if (data->nscns == 0)
+ {
+ printf (_(" No section header\n"));
+ return;
+ }
+ if (bfd_seek (abfd, off, SEEK_SET) != 0)
+ {
+ non_fatal (_("cannot read section header"));
+ return;
+ }
+ printf (_(" # Name paddr vaddr size scnptr relptr lnnoptr nrel nlnno\n"));
+ for (i = 0; i < data->nscns; i++)
+ {
+ struct external_scnhdr scn;
+ unsigned int flags;
+
+ if (bfd_bread (&scn, sizeof (scn), abfd) != sizeof (scn))
+ {
+ non_fatal (_("cannot read section header"));
+ return;
+ }
+ flags = bfd_h_get_32 (abfd, scn.s_flags);
+ printf (_("%2d %-8.8s %08x %08x %08x %08x %08x %08x "
+ "%-5d %-5d\n"),
+ i + 1, scn.s_name,
+ (unsigned int)bfd_h_get_32 (abfd, scn.s_paddr),
+ (unsigned int)bfd_h_get_32 (abfd, scn.s_vaddr),
+ (unsigned int)bfd_h_get_32 (abfd, scn.s_size),
+ (unsigned int)bfd_h_get_32 (abfd, scn.s_scnptr),
+ (unsigned int)bfd_h_get_32 (abfd, scn.s_relptr),
+ (unsigned int)bfd_h_get_32 (abfd, scn.s_lnnoptr),
+ (unsigned int)bfd_h_get_16 (abfd, scn.s_nreloc),
+ (unsigned int)bfd_h_get_16 (abfd, scn.s_nlnno));
+ printf (_(" Flags: %08x "), flags);
+
+ if (~flags == 0)
+ {
+ /* Stripped executable ? */
+ putchar ('\n');
+ }
+ else if (flags & STYP_OVRFLO)
+ printf (_("overflow - nreloc: %u, nlnno: %u\n"),
+ (unsigned int)bfd_h_get_32 (abfd, scn.s_paddr),
+ (unsigned int)bfd_h_get_32 (abfd, scn.s_vaddr));
+ else
+ {
+ dump_flags (s_flag_xlat, flags);
+ putchar ('\n');
+ }
+ }
+}
+
+/* Read section table. */
+
+static void
+xcoff32_read_sections (bfd *abfd, struct xcoff_dump *data)
+{
+ int i;
+
+ if (bfd_seek (abfd, sizeof (struct external_filehdr) + data->opthdr,
+ SEEK_SET) != 0)
+ {
+ non_fatal (_("cannot read section headers"));
+ return;
+ }
+
+ data->sects = xmalloc (data->nscns * sizeof (struct xcoff32_section));
+ for (i = 0; i < data->nscns; i++)
+ {
+ struct external_scnhdr scn;
+ struct xcoff32_section *s = &data->sects[i];
+
+ if (bfd_bread (&scn, sizeof (scn), abfd) != sizeof (scn))
+ {
+ non_fatal (_("cannot read section header"));
+ free (data->sects);
+ data->sects = NULL;
+ return;
+ }
+ memcpy (s->name, scn.s_name, 8);
+ s->name[8] = 0;
+ s->flags = bfd_h_get_32 (abfd, scn.s_flags);
+
+ s->scnptr = bfd_h_get_32 (abfd, scn.s_scnptr);
+ s->relptr = bfd_h_get_32 (abfd, scn.s_relptr);
+ s->lnnoptr = bfd_h_get_32 (abfd, scn.s_lnnoptr);
+
+ s->nreloc = bfd_h_get_16 (abfd, scn.s_nreloc);
+ s->nlnno = bfd_h_get_16 (abfd, scn.s_nlnno);
+
+ if (s->flags == STYP_OVRFLO)
+ {
+ if (s->nreloc > 0 && s->nreloc <= data->nscns)
+ data->sects[s->nreloc - 1].nreloc =
+ bfd_h_get_32 (abfd, scn.s_paddr);
+ if (s->nlnno > 0 && s->nlnno <= data->nscns)
+ data->sects[s->nlnno - 1].nlnno =
+ bfd_h_get_32 (abfd, scn.s_vaddr);
+ }
+ }
+}
+
+/* Read symbols. */
+
+static void
+xcoff32_read_symbols (bfd *abfd, struct xcoff_dump *data)
+{
+ unsigned int i;
+ char stsz_arr[4];
+ unsigned int stptr;
+
+ if (data->nsyms == 0)
+ return;
+
+ stptr = data->symptr
+ + data->nsyms * (unsigned)sizeof (struct external_syment);
+
+ /* Read string table. */
+ if (bfd_seek (abfd, stptr, SEEK_SET) != 0)
+ {
+ data->strings_size = 0;
+ }
+ else
+ {
+ if (bfd_bread (&stsz_arr, sizeof (stsz_arr), abfd) != sizeof (stsz_arr))
+ {
+ non_fatal (_("cannot read strings table len"));
+ return;
+ }
+ data->strings_size = bfd_h_get_32 (abfd, stsz_arr);
+ if (data->strings_size > sizeof (stsz_arr))
+ {
+ unsigned int remsz = data->strings_size - sizeof (stsz_arr);
+
+ data->strings = xmalloc (data->strings_size);
+
+ memcpy (data->strings, stsz_arr, sizeof (stsz_arr));
+ if (bfd_bread (data->strings + sizeof (stsz_arr), remsz, abfd)
+ != remsz)
+ {
+ non_fatal (_("cannot read strings table"));
+ goto clean;
+ }
+ }
+ }
+
+ if (bfd_seek (abfd, data->symptr, SEEK_SET) != 0)
+ {
+ non_fatal (_("cannot read symbol table"));
+ goto clean;
+ }
+
+ data->syms = (union xcoff32_symbol *)
+ xmalloc (data->nsyms * sizeof (union xcoff32_symbol));
+
+ for (i = 0; i < data->nsyms; i++)
+ {
+ struct external_syment sym;
+ int j;
+ union xcoff32_symbol *s = &data->syms[i];
+
+ if (bfd_bread (&sym, sizeof (sym), abfd) != sizeof (sym))
+ {
+ non_fatal (_("cannot read symbol entry"));
+ goto clean;
+ }
+
+ s->sym.val = bfd_h_get_32 (abfd, sym.e_value);
+ s->sym.scnum = bfd_h_get_16 (abfd, sym.e_scnum);
+ s->sym.ntype = bfd_h_get_16 (abfd, sym.e_type);
+ s->sym.sclass = bfd_h_get_8 (abfd, sym.e_sclass);
+ s->sym.numaux = bfd_h_get_8 (abfd, sym.e_numaux);
+
+ if (sym.e.e_name[0])
+ {
+ memcpy (s->sym.raw.name, sym.e.e_name, sizeof (sym.e.e_name));
+ s->sym.raw.name[8] = 0;
+ s->sym.name = s->sym.raw.name;
+ }
+ else
+ {
+ unsigned int soff = bfd_h_get_32 (abfd, sym.e.e.e_offset);
+
+ if ((s->sym.sclass & DBXMASK) == 0 && soff < data->strings_size)
+ s->sym.name = data->strings + soff;
+ else
+ {
+ s->sym.name = NULL;
+ s->sym.raw.off = soff;
+ }
+ }
+
+ for (j = 0; j < s->sym.numaux; j++, i++)
+ {
+ if (bfd_bread (&s[j + 1].aux,
+ sizeof (union external_auxent), abfd)
+ != sizeof (union external_auxent))
+ {
+ non_fatal (_("cannot read symbol aux entry"));
+ goto clean;
+ }
+ }
+ }
+ return;
+ clean:
+ free (data->syms);
+ data->syms = NULL;
+ free (data->strings);
+ data->strings = NULL;
+}
+
+/* Dump xcoff symbols. */
+
+static void
+dump_xcoff32_symbols (bfd *abfd, struct xcoff_dump *data)
+{
+ unsigned int i;
+ asection *debugsec;
+ char *debug = NULL;
+
+ printf (_("Symbols table (strtable at 0x%08x)"),
+ data->symptr
+ + data->nsyms * (unsigned)sizeof (struct external_syment));
+ if (data->nsyms == 0 || data->syms == NULL)
+ {
+ printf (_(":\n No symbols\n"));
+ return;
+ }
+
+ /* Read string table. */
+ if (data->strings_size == 0)
+ printf (_(" (no strings):\n"));
+ else
+ printf (_(" (strings size: %08x):\n"), data->strings_size);
+
+ /* Read debug section. */
+ debugsec = bfd_get_section_by_name (abfd, ".debug");
+ if (debugsec != NULL)
+ {
+ bfd_size_type size;
+
+ size = bfd_get_section_size (debugsec);
+ debug = (char *) xmalloc (size);
+ bfd_get_section_contents (abfd, debugsec, debug, 0, size);
+ }
+
+ printf (_(" # sc value section type aux name/off\n"));
+ for (i = 0; i < data->nsyms; i++)
+ {
+ union xcoff32_symbol *s = &data->syms[i];
+ int j;
+
+ printf ("%3u ", i);
+ dump_value (sc_xlat, s->sym.sclass, 10);
+ printf (" %08x ", s->sym.val);
+ if (s->sym.scnum > 0 && s->sym.scnum <= data->nscns)
+ {
+ if (data->sects != NULL)
+ printf ("%-8s", data->sects[s->sym.scnum - 1].name);
+ else
+ printf ("%-8u", s->sym.scnum);
+ }
+ else
+ switch ((signed short)s->sym.scnum)
+ {
+ case N_DEBUG:
+ printf ("N_DEBUG ");
+ break;
+ case N_ABS:
+ printf ("N_ABS ");
+ break;
+ case N_UNDEF:
+ printf ("N_UNDEF ");
+ break;
+ default:
+ printf ("(%04x) ", s->sym.scnum);
+ }
+ printf (" %04x %3u ", s->sym.ntype, s->sym.numaux);
+ if (s->sym.name != NULL)
+ printf ("%s", s->sym.name);
+ else
+ {
+ if ((s->sym.sclass & DBXMASK) != 0 && debug != NULL)
+ printf ("%s", debug + s->sym.raw.off);
+ else
+ printf ("%08x", s->sym.raw.off);
+ }
+ putchar ('\n');
+
+ for (j = 0; j < s->sym.numaux; j++, i++)
+ {
+ union external_auxent *aux = &s[j + 1].aux;
+
+ printf (" %3u ", i + 1);
+ switch (s->sym.sclass)
+ {
+ case C_STAT:
+ printf (_(" scnlen: %08x nreloc: %-6u nlinno: %-6u\n"),
+ (unsigned)bfd_h_get_32 (abfd, aux->x_scn.x_scnlen),
+ (unsigned)bfd_h_get_16 (abfd, aux->x_scn.x_nreloc),
+ (unsigned)bfd_h_get_16 (abfd, aux->x_scn.x_nlinno));
+ break;
+ case C_DWARF:
+ printf (_(" scnlen: %08x nreloc: %-6u\n"),
+ (unsigned)bfd_h_get_32 (abfd, aux->x_scn.x_scnlen),
+ (unsigned)bfd_h_get_16 (abfd, aux->x_scn.x_nreloc));
+ break;
+ case C_EXT:
+ case C_WEAKEXT:
+ case C_HIDEXT:
+ if (j == 0 && s->sym.numaux > 1)
+ {
+ /* Function aux entry. */
+ printf (_(" exptr: %08x fsize: %08x lnnoptr: %08x endndx: %u\n"),
+ (unsigned)bfd_h_get_32 (abfd, aux->x_sym.x_tagndx),
+ (unsigned)bfd_h_get_32
+ (abfd, aux->x_sym.x_misc.x_fsize),
+ (unsigned)bfd_h_get_32
+ (abfd, aux->x_sym.x_fcnary.x_fcn.x_lnnoptr),
+ (unsigned)bfd_h_get_32
+ (abfd, aux->x_sym.x_fcnary.x_fcn.x_endndx));
+ }
+ else if (j == 1 || (j == 0 && s->sym.numaux == 1))
+ {
+ /* csect aux entry. */
+ unsigned char smtyp;
+ unsigned int scnlen;
+
+ smtyp = bfd_h_get_8 (abfd, aux->x_csect.x_smtyp);
+ scnlen = bfd_h_get_32 (abfd, aux->x_csect.x_scnlen);
+
+ if (smtyp == XTY_LD)
+ printf (_(" scnsym: %-8u"), scnlen);
+ else
+ printf (_(" scnlen: %08x"), scnlen);
+ printf (_(" h: parm=%08x sn=%04x al: 2**%u"),
+ (unsigned)bfd_h_get_32 (abfd, aux->x_csect.x_parmhash),
+ (unsigned)bfd_h_get_16 (abfd, aux->x_csect.x_snhash),
+ SMTYP_ALIGN (smtyp));
+ printf (_(" typ: "));
+ dump_value (smtyp_xlat, SMTYP_SMTYP (smtyp), 2);
+ printf (_(" cl: "));
+ dump_value
+ (smclas_xlat,
+ (unsigned)bfd_h_get_8 (abfd, aux->x_csect.x_smclas), 6);
+ putchar ('\n');
+ }
+ else
+ printf ("aux\n");
+ break;
+ case C_FILE:
+ {
+ unsigned int off;
+
+ printf (_(" ftype: %02x "),
+ (unsigned)bfd_h_get_8 (abfd, aux->x_file.x_ftype));
+ if (aux->x_file.x_n.x_fname[0] != 0)
+ printf (_("fname: %.14s"), aux->x_file.x_n.x_fname);
+ else
+ {
+ off = (unsigned)bfd_h_get_32
+ (abfd, aux->x_file.x_n.x_n.x_offset);
+ if (data->strings != NULL && off < data->strings_size)
+ printf (_(" %s"), data->strings + off);
+ else
+ printf (_("offset: %08x"), off);
+ }
+ putchar ('\n');
+ }
+ break;
+ case C_BLOCK:
+ case C_FCN:
+ printf (_(" lnno: %u\n"),
+ (unsigned)bfd_h_get_16
+ (abfd, aux->x_sym.x_misc.x_lnsz.x_lnno));
+ break;
+ default:
+ printf ("aux\n");
+ break;
+ }
+ }
+
+ }
+ free (debug);
+}
+
+/* Dump xcoff relocation entries. */
+
+static void
+dump_xcoff32_relocs (bfd *abfd, struct xcoff_dump *data)
+{
+ unsigned int i;
+
+ if (data->sects == NULL)
+ {
+ non_fatal (_("cannot read section headers"));
+ return;
+ }
+
+ for (i = 0; i < data->nscns; i++)
+ {
+ struct xcoff32_section *sect = &data->sects[i];
+ unsigned int nrel = sect->nreloc;
+ unsigned int j;
+
+ if (nrel == 0)
+ continue;
+ printf (_("Relocations for %s (%u)\n"), sect->name, nrel);
+ if (bfd_seek (abfd, sect->relptr, SEEK_SET) != 0)
+ {
+ non_fatal (_("cannot read relocations"));
+ continue;
+ }
+ printf (_("vaddr sgn mod sz type symndx symbol\n"));
+ for (j = 0; j < nrel; j++)
+ {
+ struct external_reloc rel;
+ unsigned char rsize;
+ unsigned int symndx;
+
+ if (bfd_bread (&rel, sizeof (rel), abfd) != sizeof (rel))
+ {
+ non_fatal (_("cannot read relocation entry"));
+ return;
+ }
+ rsize = bfd_h_get_8 (abfd, rel.r_size);
+ printf (_("%08x %c %c %-2u "),
+ (unsigned int)bfd_h_get_32 (abfd, rel.r_vaddr),
+ rsize & 0x80 ? 'S' : 'U',
+ rsize & 0x40 ? 'm' : ' ',
+ (rsize & 0x3f) + 1);
+ dump_value (rtype_xlat, bfd_h_get_8 (abfd, rel.r_type), 6);
+ symndx = bfd_h_get_32 (abfd, rel.r_symndx);
+ printf ("%-6u ", symndx);
+ xcoff32_print_symbol (data, symndx);
+ putchar ('\n');
+ }
+ putchar ('\n');
+ }
+}
+
+/* Dump xcoff line number entries. */
+
+static void
+dump_xcoff32_lineno (bfd *abfd, struct xcoff_dump *data)
+{
+ unsigned int i;
+
+ if (data->sects == NULL)
+ {
+ non_fatal (_("cannot read section headers"));
+ return;
+ }
+
+ for (i = 0; i < data->nscns; i++)
+ {
+ struct xcoff32_section *sect = &data->sects[i];
+ unsigned int nlnno = sect->nlnno;
+ unsigned int j;
+
+ if (nlnno == 0)
+ continue;
+ printf (_("Line numbers for %s (%u)\n"), sect->name, nlnno);
+ if (bfd_seek (abfd, sect->lnnoptr, SEEK_SET) != 0)
+ {
+ non_fatal (_("cannot read line numbers"));
+ continue;
+ }
+ printf (_("lineno symndx/paddr\n"));
+ for (j = 0; j < nlnno; j++)
+ {
+ struct external_lineno ln;
+ unsigned int no;
+
+ if (bfd_bread (&ln, sizeof (ln), abfd) != sizeof (ln))
+ {
+ non_fatal (_("cannot read line number entry"));
+ return;
+ }
+ no = bfd_h_get_16 (abfd, ln.l_lnno);
+ printf (_(" %-6u "), no);
+ if (no == 0)
+ {
+ unsigned int symndx = bfd_h_get_32 (abfd, ln.l_addr.l_symndx);
+ xcoff32_print_symbol (data, symndx);
+ }
+ else
+ printf ("0x%08x",
+ (unsigned int)bfd_h_get_32 (abfd, ln.l_addr.l_paddr));
+ putchar ('\n');
+ }
+ }
+}
+
+/* Dump xcoff loader section. */
+
+static void
+dump_xcoff32_loader (bfd *abfd)
+{
+ asection *loader;
+ bfd_size_type size = 0;
+ struct external_ldhdr *lhdr;
+ struct external_ldsym *ldsym;
+ struct external_ldrel *ldrel;
+ bfd_byte *ldr_data;
+ unsigned int version;
+ unsigned int ndsyms;
+ unsigned int ndrel;
+ unsigned int stlen;
+ unsigned int stoff;
+ unsigned int impoff;
+ unsigned int nimpid;
+ unsigned int i;
+ const char *p;
+
+ loader = bfd_get_section_by_name (abfd, ".loader");
+
+ if (loader == NULL)
+ {
+ printf (_("no .loader section in file\n"));
+ return;
+ }
+ size = bfd_get_section_size (loader);
+ if (size < sizeof (*lhdr))
+ {
+ printf (_("section .loader is too short\n"));
+ return;
+ }
+
+ ldr_data = (bfd_byte *) xmalloc (size);
+ bfd_get_section_contents (abfd, loader, ldr_data, 0, size);
+ lhdr = (struct external_ldhdr *)ldr_data;
+ printf (_("Loader header:\n"));
+ version = bfd_h_get_32 (abfd, lhdr->l_version);
+ printf (_(" version: %u\n"), version);
+ if (version != 1)
+ {
+ printf (_(" Unhandled version\n"));
+ free (ldr_data);
+ return;
+ }
+ ndsyms = bfd_h_get_32 (abfd, lhdr->l_nsyms);
+ printf (_(" nbr symbols: %u\n"), ndsyms);
+ ndrel = bfd_h_get_32 (abfd, lhdr->l_nreloc);
+ printf (_(" nbr relocs: %u\n"), ndrel);
+ printf (_(" import strtab len: %u\n"),
+ (unsigned) bfd_h_get_32 (abfd, lhdr->l_istlen));
+ nimpid = bfd_h_get_32 (abfd, lhdr->l_nimpid);
+ printf (_(" nbr import files: %u\n"), nimpid);
+ impoff = bfd_h_get_32 (abfd, lhdr->l_impoff);
+ printf (_(" import file off: %u\n"), impoff);
+ stlen = bfd_h_get_32 (abfd, lhdr->l_stlen);
+ printf (_(" string table len: %u\n"), stlen);
+ stoff = bfd_h_get_32 (abfd, lhdr->l_stoff);
+ printf (_(" string table off: %u\n"), stoff);
+
+ ldsym = (struct external_ldsym *)(ldr_data + sizeof (*lhdr));
+ printf (_("Dynamic symbols:\n"));
+ printf (_(" # value sc IFEW ty class file pa name\n"));
+ for (i = 0; i < ndsyms; i++, ldsym++)
+ {
+ unsigned char smtype;
+
+ printf (_(" %4u %08x %3u "), i,
+ (unsigned)bfd_h_get_32 (abfd, ldsym->l_value),
+ (unsigned)bfd_h_get_16 (abfd, ldsym->l_scnum));
+ smtype = bfd_h_get_8 (abfd, ldsym->l_smtype);
+ putchar (smtype & 0x40 ? 'I' : ' ');
+ putchar (smtype & 0x20 ? 'F' : ' ');
+ putchar (smtype & 0x10 ? 'E' : ' ');
+ putchar (smtype & 0x08 ? 'W' : ' ');
+ putchar (' ');
+ dump_value (smtyp_xlat, SMTYP_SMTYP (smtype), 2);
+ putchar (' ');
+ dump_value
+ (smclas_xlat, (unsigned)bfd_h_get_8 (abfd, ldsym->l_smclas), 6);
+ printf (_(" %3u %3u "),
+ (unsigned)bfd_h_get_32 (abfd, ldsym->l_ifile),
+ (unsigned)bfd_h_get_32 (abfd, ldsym->l_parm));
+ if (ldsym->_l._l_name[0] != 0)
+ printf ("%-.8s", ldsym->_l._l_name);
+ else
+ {
+ unsigned int off = bfd_h_get_32 (abfd, ldsym->_l._l_l._l_offset);
+ if (off > stlen)
+ printf (_("(bad offset: %u)"), off);
+ else
+ printf ("%s", ldr_data + stoff + off);
+ }
+ putchar ('\n');
+ }
+
+ printf (_("Dynamic relocs:\n"));
+ printf (_(" vaddr sec sz typ sym\n"));
+ ldrel = (struct external_ldrel *)(ldr_data + sizeof (*lhdr)
+ + ndsyms * sizeof (*ldsym));
+ for (i = 0; i < ndrel; i++, ldrel++)
+ {
+ unsigned int rsize;
+ unsigned int rtype;
+ unsigned int symndx;
+
+ rsize = bfd_h_get_8 (abfd, ldrel->l_rtype + 0);
+ rtype = bfd_h_get_8 (abfd, ldrel->l_rtype + 1);
+
+ printf (_(" %08x %3u %c%c %2u "),
+ (unsigned)bfd_h_get_32 (abfd, ldrel->l_vaddr),
+ (unsigned)bfd_h_get_16 (abfd, ldrel->l_rsecnm),
+ rsize & 0x80 ? 'S' : 'U',
+ rsize & 0x40 ? 'm' : ' ',
+ (rsize & 0x3f) + 1);
+ dump_value (rtype_xlat, rtype, 6);
+ symndx = bfd_h_get_32 (abfd, ldrel->l_symndx);
+ switch (symndx)
+ {
+ case 0:
+ printf (_(".text"));
+ break;
+ case 1:
+ printf (_(".data"));
+ break;
+ case 2:
+ printf (_(".bss"));
+ break;
+ default:
+ printf (_("%u"), symndx - 3);
+ break;
+ }
+ putchar ('\n');
+ }
+
+ printf (_("Import files:\n"));
+ p = (char *)ldr_data + impoff;
+ for (i = 0; i < nimpid; i++)
+ {
+ int n1, n2, n3;
+
+ n1 = strlen (p);
+ n2 = strlen (p + n1 + 1);
+ n3 = strlen (p + n1 + 1 + n2+ 1);
+ printf (" %2u: %s,%s,%s\n", i,
+ p, p + n1 + 1, p + n1 + n2 + 2);
+ p += n1 + n2 + n3 + 3;
+ }
+
+ free (ldr_data);
+}
+
+/* Dump xcoff exception section. */
+
+static void
+dump_xcoff32_except (bfd *abfd, struct xcoff_dump *data)
+{
+ asection *sec;
+ bfd_size_type size = 0;
+ bfd_byte *excp_data;
+ struct external_exceptab *exceptab;
+ unsigned int i;
+
+ sec = bfd_get_section_by_name (abfd, ".except");
+
+ if (sec == NULL)
+ {
+ printf (_("no .except section in file\n"));
+ return;
+ }
+ size = bfd_get_section_size (sec);
+ excp_data = (bfd_byte *) xmalloc (size);
+ bfd_get_section_contents (abfd, sec, excp_data, 0, size);
+ exceptab = (struct external_exceptab *)excp_data;
+
+ printf (_("Exception table:\n"));
+ printf (_("lang reason sym/addr\n"));
+ for (i = 0; i * sizeof (*exceptab) < size; i++, exceptab++)
+ {
+ unsigned int reason;
+ unsigned int addr;
+
+ addr = bfd_get_32 (abfd, exceptab->e_addr.e_paddr);
+ reason = bfd_get_8 (abfd, exceptab->e_reason);
+ printf (_(" %02x %02x "),
+ (unsigned) bfd_get_8 (abfd, exceptab->e_lang), reason);
+ if (reason == 0)
+ xcoff32_print_symbol (data, addr);
+ else
+ printf (_("@%08x"), addr);
+ putchar ('\n');
+ }
+ free (excp_data);
+}
+
+/* Dump xcoff type-check section. */
+
+static void
+dump_xcoff32_typchk (bfd *abfd)
+{
+ asection *sec;
+ bfd_size_type size = 0;
+ bfd_byte *data;
+ unsigned int i;
+
+ sec = bfd_get_section_by_name (abfd, ".typchk");
+
+ if (sec == NULL)
+ {
+ printf (_("no .typchk section in file\n"));
+ return;
+ }
+ size = bfd_get_section_size (sec);
+ data = (bfd_byte *) xmalloc (size);
+ bfd_get_section_contents (abfd, sec, data, 0, size);
+
+ printf (_("Type-check section:\n"));
+ printf (_("offset len lang-id general-hash language-hash\n"));
+ for (i = 0; i < size;)
+ {
+ unsigned int len;
+
+ len = bfd_get_16 (abfd, data + i);
+ printf ("%08x: %-4u ", i, len);
+ i += 2;
+
+ if (len == 10)
+ {
+ /* Expected format. */
+ printf ("%04x %08x %08x\n",
+ (unsigned) bfd_get_16 (abfd, data + i),
+ (unsigned) bfd_get_32 (abfd, data + i + 2),
+ (unsigned) bfd_get_32 (abfd, data + i + 2 + 4));
+ }
+ else
+ {
+ unsigned int j;
+
+ for (j = 0; j < len; j++)
+ {
+ if (j % 16 == 0)
+ printf ("\n ");
+ printf (" %02x", (unsigned char)data[i + j]);
+ }
+ putchar ('\n');
+ }
+ i += len;
+ }
+ free (data);
+}
+
+/* Dump xcoff traceback tags section. */
+
+static void
+dump_xcoff32_tbtags (bfd *abfd,
+ const char *text, bfd_size_type text_size,
+ unsigned int text_start, unsigned int func_start)
+{
+ unsigned int i;
+
+ if (func_start - text_start > text_size)
+ {
+ printf (_(" address beyond section size\n"));
+ return;
+ }
+ for (i = func_start - text_start; i < text_size; i+= 4)
+ if (bfd_get_32 (abfd, text + i) == 0)
+ {
+ unsigned int tb1;
+ unsigned int tb2;
+ unsigned int off;
+
+ printf (_(" tags at %08x\n"), i + 4);
+ if (i + 8 >= text_size)
+ goto truncated;
+
+ tb1 = bfd_get_32 (abfd, text + i + 4);
+ tb2 = bfd_get_32 (abfd, text + i + 8);
+ off = i + 12;
+ printf (_(" version: %u, lang: %u, global_link: %u, is_eprol: %u, has_tboff: %u, int_proc: %u\n"),
+ (tb1 >> 24) & 0xff,
+ (tb1 >> 16) & 0xff,
+ (tb1 >> 15) & 1,
+ (tb1 >> 14) & 1,
+ (tb1 >> 13) & 1,
+ (tb1 >> 12) & 1);
+ printf (_(" has_ctl: %u, tocless: %u, fp_pres: %u, log_abort: %u, int_hndl: %u\n"),
+ (tb1 >> 11) & 1,
+ (tb1 >> 10) & 1,
+ (tb1 >> 9) & 1,
+ (tb1 >> 8) & 1,
+ (tb1 >> 7) & 1);
+ printf (_(" name_pres: %u, uses_alloca: %u, cl_dis_inv: %u, saves_cr: %u, saves_lr: %u\n"),
+ (tb1 >> 6) & 1,
+ (tb1 >> 5) & 1,
+ (tb1 >> 2) & 7,
+ (tb1 >> 1) & 1,
+ (tb1 >> 0) & 1);
+ printf (_(" stores_bc: %u, fixup: %u, fpr_saved: %-2u, spare3: %u, gpr_saved: %-2u\n"),
+ (tb2 >> 31) & 1,
+ (tb2 >> 30) & 1,
+ (tb2 >> 24) & 63,
+ (tb2 >> 22) & 3,
+ (tb2 >> 16) & 63);
+ printf (_(" fixparms: %-3u floatparms: %-3u parm_on_stk: %u\n"),
+ (tb2 >> 8) & 0xff,
+ (tb2 >> 1) & 0x7f,
+ (tb2 >> 0) & 1);
+
+ if (((tb2 >> 1) & 0x7fff) != 0)
+ {
+ unsigned int parminfo;
+
+ if (off >= text_size)
+ goto truncated;
+ parminfo = bfd_get_32 (abfd, text + off);
+ off += 4;
+ printf (_(" parminfo: 0x%08x\n"), parminfo);
+ }
+
+ if ((tb1 >> 13) & 1)
+ {
+ unsigned int tboff;
+
+ if (off >= text_size)
+ goto truncated;
+ tboff = bfd_get_32 (abfd, text + off);
+ off += 4;
+ printf (_(" tb_offset: 0x%08x (start=0x%08x)\n"),
+ tboff, text_start + i - tboff);
+ }
+ if ((tb1 >> 7) & 1)
+ {
+ unsigned int hand_mask;
+
+ if (off >= text_size)
+ goto truncated;
+ hand_mask = bfd_get_32 (abfd, text + off);
+ off += 4;
+ printf (_(" hand_mask_offset: 0x%08x\n"), hand_mask);
+ }
+ if ((tb1 >> 11) & 1)
+ {
+ unsigned int ctl_info;
+ unsigned int j;
+
+ if (off >= text_size)
+ goto truncated;
+ ctl_info = bfd_get_32 (abfd, text + off);
+ off += 4;
+ printf (_(" number of CTL anchors: %u\n"), ctl_info);
+ for (j = 0; j < ctl_info; j++)
+ {
+ if (off >= text_size)
+ goto truncated;
+ printf (_(" CTL[%u]: %08x\n"),
+ j, (unsigned)bfd_get_32 (abfd, text + off));
+ off += 4;
+ }
+ }
+ if ((tb1 >> 6) & 1)
+ {
+ unsigned int name_len;
+ unsigned int j;
+
+ if (off >= text_size)
+ goto truncated;
+ name_len = bfd_get_16 (abfd, text + off);
+ off += 2;
+ printf (_(" Name (len: %u): "), name_len);
+ if (off + name_len >= text_size)
+ {
+ printf (_("[truncated]\n"));
+ goto truncated;
+ }
+ for (j = 0; j < name_len; j++)
+ if (ISPRINT (text[off + j]))
+ putchar (text[off + j]);
+ else
+ printf ("[%02x]", (unsigned char)text[off + j]);
+ putchar ('\n');
+ off += name_len;
+ }
+ if ((tb1 >> 5) & 1)
+ {
+ if (off >= text_size)
+ goto truncated;
+ printf (_(" alloca reg: %u\n"),
+ (unsigned) bfd_get_8 (abfd, text + off));
+ off++;
+ }
+ printf (_(" (end of tags at %08x)\n"), text_start + off);
+ return;
+ }
+ printf (_(" no tags found\n"));
+ return;
+
+ truncated:
+ printf (_(" Truncated .text section\n"));
+ return;
+}
+
+static void
+dump_xcoff32_traceback (bfd *abfd, struct xcoff_dump *data)
+{
+ unsigned int i;
+ unsigned int scnum_text = -1;
+ unsigned int text_vma;
+ asection *text_sec;
+ bfd_size_type text_size;
+ char *text;
+
+ if (data->syms == NULL || data->sects == NULL)
+ return;
+
+ /* Read text section. */
+ text_sec = bfd_get_section_by_name (abfd, ".text");
+ if (text_sec == NULL)
+ return;
+ text_vma = bfd_get_section_vma (abfd, text_sec);
+
+ text_size = bfd_get_section_size (text_sec);
+ text = (char *) xmalloc (text_size);
+ bfd_get_section_contents (abfd, text_sec, text, 0, text_size);
+
+ for (i = 0; i < data->nscns; i++)
+ if (data->sects[i].flags == STYP_TEXT)
+ {
+ scnum_text = i + 1;
+ break;
+ }
+ if (scnum_text == (unsigned int)-1)
+ return;
+
+ for (i = 0; i < data->nsyms; i++)
+ {
+ union xcoff32_symbol *s = &data->syms[i];
+
+ switch (s->sym.sclass)
+ {
+ case C_EXT:
+ case C_HIDEXT:
+ case C_WEAKEXT:
+ if (s->sym.scnum == scnum_text
+ && s->sym.numaux > 0)
+ {
+ union external_auxent *aux = &s[s->sym.numaux].aux;
+
+ unsigned int smtyp;
+ unsigned int smclas;
+
+ smtyp = bfd_h_get_8 (abfd, aux->x_csect.x_smtyp);
+ smclas = bfd_h_get_8 (abfd, aux->x_csect.x_smclas);
+ if (SMTYP_SMTYP (smtyp) == XTY_LD
+ && (smclas == XMC_PR
+ || smclas == XMC_GL
+ || smclas == XMC_XO))
+ {
+ printf ("%08x: ", s->sym.val);
+ xcoff32_print_symbol (data, i);
+ putchar ('\n');
+ dump_xcoff32_tbtags (abfd, text, text_size,
+ text_vma, s->sym.val);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ i += s->sym.numaux;
+ }
+ free (text);
+}
+
+/* Dump the TOC symbols. */
+
+static void
+dump_xcoff32_toc (bfd *abfd, struct xcoff_dump *data)
+{
+ unsigned int i;
+ unsigned int nbr_ent;
+ unsigned int size;
+
+ printf (_("TOC:\n"));
+
+ if (data->syms == NULL)
+ return;
+
+ nbr_ent = 0;
+ size = 0;
+
+ for (i = 0; i < data->nsyms; i++)
+ {
+ union xcoff32_symbol *s = &data->syms[i];
+
+ switch (s->sym.sclass)
+ {
+ case C_EXT:
+ case C_HIDEXT:
+ case C_WEAKEXT:
+ if (s->sym.numaux > 0)
+ {
+ union external_auxent *aux = &s[s->sym.numaux].aux;
+ unsigned int smclas;
+ unsigned int ent_sz;
+
+ smclas = bfd_h_get_8 (abfd, aux->x_csect.x_smclas);
+ if (smclas == XMC_TC
+ || smclas == XMC_TD
+ || smclas == XMC_TC0)
+ {
+ ent_sz = bfd_h_get_32 (abfd, aux->x_scn.x_scnlen);
+ printf ("%08x %08x ",
+ s->sym.val, ent_sz);
+ xcoff32_print_symbol (data, i);
+ putchar ('\n');
+ nbr_ent++;
+ size += ent_sz;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ i += s->sym.numaux;
+ }
+ printf (_("Nbr entries: %-8u Size: %08x (%u)\n"),
+ nbr_ent, size, size);
+}
+
+/* Handle an rs6000 xcoff file. */
+
+static void
+dump_xcoff32 (bfd *abfd, struct external_filehdr *fhdr)
+{
+ struct xcoff_dump data;
+
+ data.nscns = bfd_h_get_16 (abfd, fhdr->f_nscns);
+ data.symptr = bfd_h_get_32 (abfd, fhdr->f_symptr);
+ data.nsyms = bfd_h_get_32 (abfd, fhdr->f_nsyms);
+ data.opthdr = bfd_h_get_16 (abfd, fhdr->f_opthdr);
+ data.sects = NULL;
+ data.syms = NULL;
+ data.strings = NULL;
+ data.strings_size = 0;
+
+ if (options[OPT_FILE_HEADER].selected)
+ dump_xcoff32_file_header (abfd, fhdr, &data);
+
+ if (options[OPT_AOUT].selected)
+ dump_xcoff32_aout_header (abfd, &data);
+
+ if (options[OPT_SYMS].selected
+ || options[OPT_RELOCS].selected
+ || options[OPT_LINENO].selected
+ || options[OPT_TRACEBACK].selected)
+ xcoff32_read_sections (abfd, &data);
+
+ if (options[OPT_SECTIONS].selected)
+ dump_xcoff32_sections_header (abfd, &data);
+
+ if (options[OPT_SYMS].selected
+ || options[OPT_RELOCS].selected
+ || options[OPT_LINENO].selected
+ || options[OPT_EXCEPT].selected
+ || options[OPT_TRACEBACK].selected
+ || options[OPT_TOC].selected)
+ xcoff32_read_symbols (abfd, &data);
+
+ if (options[OPT_SYMS].selected)
+ dump_xcoff32_symbols (abfd, &data);
+
+ if (options[OPT_RELOCS].selected)
+ dump_xcoff32_relocs (abfd, &data);
+
+ if (options[OPT_LINENO].selected)
+ dump_xcoff32_lineno (abfd, &data);
+
+ if (options[OPT_LOADER].selected)
+ dump_xcoff32_loader (abfd);
+
+ if (options[OPT_EXCEPT].selected)
+ dump_xcoff32_except (abfd, &data);
+
+ if (options[OPT_TYPCHK].selected)
+ dump_xcoff32_typchk (abfd);
+
+ if (options[OPT_TRACEBACK].selected)
+ dump_xcoff32_traceback (abfd, &data);
+
+ if (options[OPT_TOC].selected)
+ dump_xcoff32_toc (abfd, &data);
+
+ free (data.sects);
+ free (data.strings);
+ free (data.syms);
+}
+
+/* Dump ABFD (according to the options[] array). */
+
+static void
+xcoff_dump (bfd *abfd)
+{
+ struct external_filehdr fhdr;
+ unsigned short magic;
+
+ /* Read file header. */
+ if (bfd_seek (abfd, 0, SEEK_SET) != 0
+ || bfd_bread (&fhdr, sizeof (fhdr), abfd) != sizeof (fhdr))
+ {
+ non_fatal (_("cannot read header"));
+ return;
+ }
+
+ /* Decoding. We don't use the bfd/coff function to get all the fields. */
+ magic = bfd_h_get_16 (abfd, fhdr.f_magic);
+ if (options[OPT_FILE_HEADER].selected)
+ {
+ printf (_("File header:\n"));
+ printf (_(" magic: 0x%04x (0%04o) "), magic, magic);
+ switch (magic)
+ {
+ case U802WRMAGIC:
+ printf (_("(WRMAGIC: writable text segments)"));
+ break;
+ case U802ROMAGIC:
+ printf (_("(ROMAGIC: readonly sharablee text segments)"));
+ break;
+ case U802TOCMAGIC:
+ printf (_("(TOCMAGIC: readonly text segments and TOC)"));
+ break;
+ default:
+ printf (_("unknown magic"));
+ }
+ putchar ('\n');
+ }
+ if (magic == U802ROMAGIC || magic == U802WRMAGIC || magic == U802TOCMAGIC)
+ dump_xcoff32 (abfd, &fhdr);
+ else
+ printf (_(" Unhandled magic\n"));
+}
+
+/* Vector for xcoff. */
+
+const struct objdump_private_desc objdump_private_desc_xcoff =
+ {
+ xcoff_help,
+ xcoff_filter,
+ xcoff_dump,
+ options
+ };