From 6abcee9042f9603cf9fdeb62fa55335a6aa974e9 Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Mon, 16 May 2011 12:22:13 +0000 Subject: 2011-05-16 Tristan Gingold * 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. --- binutils/Makefile.am | 11 +- binutils/Makefile.in | 19 +- binutils/configure | 51 +- binutils/configure.in | 46 ++ binutils/doc/binutils.texi | 14 +- binutils/objdump.c | 80 ++- binutils/objdump.h | 50 ++ binutils/od-xcoff.c | 1670 ++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 1928 insertions(+), 13 deletions(-) create mode 100644 binutils/objdump.h create mode 100644 binutils/od-xcoff.c (limited to 'binutils') diff --git a/binutils/Makefile.am b/binutils/Makefile.am index 6546087..6f9e4a8 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 8e3d7f2..10b9e3f 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 b191a61..003b6f1 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 b1564bb..4a03c75 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 08e1c4e..fb3948f 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 231a668..784ead2 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 @@ -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 0000000..511898c --- /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 + +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 0000000..47d0248 --- /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 +#include +#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 + }; -- cgit v1.1