Back to index

cell-binutils  2.17cvs20070401
objdump.c
Go to the documentation of this file.
00001 /* objdump.c -- dump information about an object file.
00002    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
00003    2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
00004    Free Software Foundation, Inc.
00005 
00006    This file is part of GNU Binutils.
00007 
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2, or (at your option)
00011    any later version.
00012 
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00021 
00022 /* Objdump overview.
00023 
00024    Objdump displays information about one or more object files, either on
00025    their own, or inside libraries.  It is commonly used as a disassembler,
00026    but it can also display information about file headers, symbol tables,
00027    relocations, debugging directives and more.
00028 
00029    The flow of execution is as follows:
00030  
00031    1. Command line arguments are checked for control switches and the
00032       information to be displayed is selected.
00033       
00034    2. Any remaining arguments are assumed to be object files, and they are
00035       processed in order by display_bfd().  If the file is an archive each
00036       of its elements is processed in turn.
00037       
00038    3. The file's target architecture and binary file format are determined
00039       by bfd_check_format().  If they are recognised, then dump_bfd() is
00040       called.
00041 
00042    4. dump_bfd() in turn calls separate functions to display the requested
00043       item(s) of information(s).  For example disassemble_data() is called if
00044       a disassembly has been requested.
00045 
00046    When disassembling the code loops through blocks of instructions bounded
00047    by symbols, calling disassemble_bytes() on each block.  The actual
00048    disassembling is done by the libopcodes library, via a function pointer
00049    supplied by the disassembler() function.  */
00050 
00051 #include "bfd.h"
00052 #include "progress.h"
00053 #include "bucomm.h"
00054 #include "dwarf.h"
00055 #include "budemang.h"
00056 #include "getopt.h"
00057 #include "safe-ctype.h"
00058 #include "dis-asm.h"
00059 #include "libiberty.h"
00060 #include "demangle.h"
00061 #include "debug.h"
00062 #include "budbg.h"
00063 
00064 /* Internal headers for the ELF .stab-dump code - sorry.  */
00065 #define       BYTES_IN_WORD 32
00066 #include "aout/aout64.h"
00067 
00068 /* Exit status.  */
00069 static int exit_status = 0;
00070 
00071 static char *default_target = NULL;       /* Default at runtime.  */
00072 
00073 /* The following variables are set based on arguments passed on the
00074    command line.  */
00075 static int show_version = 0;              /* Show the version number.  */
00076 static int dump_section_contents;  /* -s */
00077 static int dump_section_headers;   /* -h */
00078 static bfd_boolean dump_file_header;      /* -f */
00079 static int dump_symtab;                   /* -t */
00080 static int dump_dynamic_symtab;           /* -T */
00081 static int dump_reloc_info;        /* -r */
00082 static int dump_dynamic_reloc_info;       /* -R */
00083 static int dump_ar_hdrs;           /* -a */
00084 static int dump_private_headers;   /* -p */
00085 static int prefix_addresses;              /* --prefix-addresses */
00086 static int with_line_numbers;             /* -l */
00087 static bfd_boolean with_source_code;      /* -S */
00088 static int show_raw_insn;          /* --show-raw-insn */
00089 static int dump_dwarf_section_info;       /* --dwarf */
00090 static int dump_stab_section_info; /* --stabs */
00091 static int do_demangle;                   /* -C, --demangle */
00092 static bfd_boolean disassemble;           /* -d */
00093 static bfd_boolean disassemble_all;       /* -D */
00094 static int disassemble_zeroes;            /* --disassemble-zeroes */
00095 static bfd_boolean formats_info;   /* -i */
00096 static int wide_output;                   /* -w */
00097 static bfd_vma start_address = (bfd_vma) -1; /* --start-address */
00098 static bfd_vma stop_address = (bfd_vma) -1;  /* --stop-address */
00099 static int dump_debugging;         /* --debugging */
00100 static int dump_debugging_tags;           /* --debugging-tags */
00101 static int dump_special_syms = 0;  /* --special-syms */
00102 static bfd_vma adjust_section_vma = 0;    /* --adjust-vma */
00103 static int file_start_context = 0;      /* --file-start-context */
00104 
00105 /* Pointer to an array of section names provided by
00106    one or more "-j secname" command line options.  */
00107 static char **only;
00108 /* The total number of slots in the only[] array.  */
00109 static size_t only_size = 0;
00110 /* The number of occupied slots in the only[] array.  */
00111 static size_t only_used = 0;
00112 
00113 /* Variables for handling include file path table.  */
00114 static const char **include_paths;
00115 static int include_path_count;
00116 
00117 /* Extra info to pass to the section disassembler and address printing
00118    function.  */
00119 struct objdump_disasm_info
00120 {
00121   bfd *              abfd;
00122   asection *         sec;
00123   bfd_boolean        require_sec;
00124   arelent **         dynrelbuf;
00125   long               dynrelcount;
00126   disassembler_ftype disassemble_fn;
00127   arelent *          reloc;
00128 };
00129 
00130 /* Architecture to disassemble for, or default if NULL.  */
00131 static char *machine = NULL;
00132 
00133 /* Target specific options to the disassembler.  */
00134 static char *disassembler_options = NULL;
00135 
00136 /* Endianness to disassemble for, or default if BFD_ENDIAN_UNKNOWN.  */
00137 static enum bfd_endian endian = BFD_ENDIAN_UNKNOWN;
00138 
00139 /* The symbol table.  */
00140 static asymbol **syms;
00141 
00142 /* Number of symbols in `syms'.  */
00143 static long symcount = 0;
00144 
00145 /* The sorted symbol table.  */
00146 static asymbol **sorted_syms;
00147 
00148 /* Number of symbols in `sorted_syms'.  */
00149 static long sorted_symcount = 0;
00150 
00151 /* The dynamic symbol table.  */
00152 static asymbol **dynsyms;
00153 
00154 /* The synthetic symbol table.  */
00155 static asymbol *synthsyms;
00156 static long synthcount = 0;
00157 
00158 /* Number of symbols in `dynsyms'.  */
00159 static long dynsymcount = 0;
00160 
00161 static bfd_byte *stabs;
00162 static bfd_size_type stab_size;
00163 
00164 static char *strtab;
00165 static bfd_size_type stabstr_size;
00166 
00167 static void
00168 usage (FILE *stream, int status)
00169 {
00170   fprintf (stream, _("Usage: %s <option(s)> <file(s)>\n"), program_name);
00171   fprintf (stream, _(" Display information from object <file(s)>.\n"));
00172   fprintf (stream, _(" At least one of the following switches must be given:\n"));
00173   fprintf (stream, _("\
00174   -a, --archive-headers    Display archive header information\n\
00175   -f, --file-headers       Display the contents of the overall file header\n\
00176   -p, --private-headers    Display object format specific file header contents\n\
00177   -h, --[section-]headers  Display the contents of the section headers\n\
00178   -x, --all-headers        Display the contents of all headers\n\
00179   -d, --disassemble        Display assembler contents of executable sections\n\
00180   -D, --disassemble-all    Display assembler contents of all sections\n\
00181   -S, --source             Intermix source code with disassembly\n\
00182   -s, --full-contents      Display the full contents of all sections requested\n\
00183   -g, --debugging          Display debug information in object file\n\
00184   -e, --debugging-tags     Display debug information using ctags style\n\
00185   -G, --stabs              Display (in raw form) any STABS info in the file\n\
00186   -W, --dwarf              Display DWARF info in the file\n\
00187   -t, --syms               Display the contents of the symbol table(s)\n\
00188   -T, --dynamic-syms       Display the contents of the dynamic symbol table\n\
00189   -r, --reloc              Display the relocation entries in the file\n\
00190   -R, --dynamic-reloc      Display the dynamic relocation entries in the file\n\
00191   @<file>                  Read options from <file>\n\
00192   -v, --version            Display this program's version number\n\
00193   -i, --info               List object formats and architectures supported\n\
00194   -H, --help               Display this information\n\
00195 "));
00196   if (status != 2)
00197     {
00198       fprintf (stream, _("\n The following switches are optional:\n"));
00199       fprintf (stream, _("\
00200   -b, --target=BFDNAME           Specify the target object format as BFDNAME\n\
00201   -m, --architecture=MACHINE     Specify the target architecture as MACHINE\n\
00202   -j, --section=NAME             Only display information for section NAME\n\
00203   -M, --disassembler-options=OPT Pass text OPT on to the disassembler\n\
00204   -EB --endian=big               Assume big endian format when disassembling\n\
00205   -EL --endian=little            Assume little endian format when disassembling\n\
00206       --file-start-context       Include context from start of file (with -S)\n\
00207   -I, --include=DIR              Add DIR to search list for source files\n\
00208   -l, --line-numbers             Include line numbers and filenames in output\n\
00209   -C, --demangle[=STYLE]         Decode mangled/processed symbol names\n\
00210                                   The STYLE, if specified, can be `auto', `gnu',\n\
00211                                   `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
00212                                   or `gnat'\n\
00213   -w, --wide                     Format output for more than 80 columns\n\
00214   -z, --disassemble-zeroes       Do not skip blocks of zeroes when disassembling\n\
00215       --start-address=ADDR       Only process data whose address is >= ADDR\n\
00216       --stop-address=ADDR        Only process data whose address is <= ADDR\n\
00217       --prefix-addresses         Print complete address alongside disassembly\n\
00218       --[no-]show-raw-insn       Display hex alongside symbolic disassembly\n\
00219       --adjust-vma=OFFSET        Add OFFSET to all displayed section addresses\n\
00220       --special-syms             Include special symbols in symbol dumps\n\
00221 \n"));
00222       list_supported_targets (program_name, stream);
00223       list_supported_architectures (program_name, stream);
00224 
00225       disassembler_usage (stream);
00226     }
00227   if (REPORT_BUGS_TO[0] && status == 0)
00228     fprintf (stream, _("Report bugs to %s.\n"), REPORT_BUGS_TO);
00229   exit (status);
00230 }
00231 
00232 /* 150 isn't special; it's just an arbitrary non-ASCII char value.  */
00233 enum option_values
00234   {
00235     OPTION_ENDIAN=150,
00236     OPTION_START_ADDRESS,
00237     OPTION_STOP_ADDRESS,
00238     OPTION_ADJUST_VMA
00239   };
00240 
00241 static struct option long_options[]=
00242 {
00243   {"adjust-vma", required_argument, NULL, OPTION_ADJUST_VMA},
00244   {"all-headers", no_argument, NULL, 'x'},
00245   {"private-headers", no_argument, NULL, 'p'},
00246   {"architecture", required_argument, NULL, 'm'},
00247   {"archive-headers", no_argument, NULL, 'a'},
00248   {"debugging", no_argument, NULL, 'g'},
00249   {"debugging-tags", no_argument, NULL, 'e'},
00250   {"demangle", optional_argument, NULL, 'C'},
00251   {"disassemble", no_argument, NULL, 'd'},
00252   {"disassemble-all", no_argument, NULL, 'D'},
00253   {"disassembler-options", required_argument, NULL, 'M'},
00254   {"disassemble-zeroes", no_argument, NULL, 'z'},
00255   {"dynamic-reloc", no_argument, NULL, 'R'},
00256   {"dynamic-syms", no_argument, NULL, 'T'},
00257   {"endian", required_argument, NULL, OPTION_ENDIAN},
00258   {"file-headers", no_argument, NULL, 'f'},
00259   {"file-start-context", no_argument, &file_start_context, 1},
00260   {"full-contents", no_argument, NULL, 's'},
00261   {"headers", no_argument, NULL, 'h'},
00262   {"help", no_argument, NULL, 'H'},
00263   {"info", no_argument, NULL, 'i'},
00264   {"line-numbers", no_argument, NULL, 'l'},
00265   {"no-show-raw-insn", no_argument, &show_raw_insn, -1},
00266   {"prefix-addresses", no_argument, &prefix_addresses, 1},
00267   {"reloc", no_argument, NULL, 'r'},
00268   {"section", required_argument, NULL, 'j'},
00269   {"section-headers", no_argument, NULL, 'h'},
00270   {"show-raw-insn", no_argument, &show_raw_insn, 1},
00271   {"source", no_argument, NULL, 'S'},
00272   {"special-syms", no_argument, &dump_special_syms, 1},
00273   {"include", required_argument, NULL, 'I'},
00274   {"dwarf", no_argument, NULL, 'W'},
00275   {"stabs", no_argument, NULL, 'G'},
00276   {"start-address", required_argument, NULL, OPTION_START_ADDRESS},
00277   {"stop-address", required_argument, NULL, OPTION_STOP_ADDRESS},
00278   {"syms", no_argument, NULL, 't'},
00279   {"target", required_argument, NULL, 'b'},
00280   {"version", no_argument, NULL, 'V'},
00281   {"wide", no_argument, NULL, 'w'},
00282   {0, no_argument, 0, 0}
00283 };
00284 
00285 static void
00286 nonfatal (const char *msg)
00287 {
00288   bfd_nonfatal (msg);
00289   exit_status = 1;
00290 }
00291 
00292 static void
00293 dump_section_header (bfd *abfd, asection *section,
00294                    void *ignored ATTRIBUTE_UNUSED)
00295 {
00296   char *comma = "";
00297   unsigned int opb = bfd_octets_per_byte (abfd);
00298 
00299   /* Ignore linker created section.  See elfNN_ia64_object_p in
00300      bfd/elfxx-ia64.c.  */
00301   if (section->flags & SEC_LINKER_CREATED)
00302     return;
00303 
00304   printf ("%3d %-13s %08lx  ", section->index,
00305          bfd_get_section_name (abfd, section),
00306          (unsigned long) bfd_section_size (abfd, section) / opb);
00307   bfd_printf_vma (abfd, bfd_get_section_vma (abfd, section));
00308   printf ("  ");
00309   bfd_printf_vma (abfd, section->lma);
00310   printf ("  %08lx  2**%u", (unsigned long) section->filepos,
00311          bfd_get_section_alignment (abfd, section));
00312   if (! wide_output)
00313     printf ("\n                ");
00314   printf ("  ");
00315 
00316 #define PF(x, y) \
00317   if (section->flags & x) { printf ("%s%s", comma, y); comma = ", "; }
00318 
00319   PF (SEC_HAS_CONTENTS, "CONTENTS");
00320   PF (SEC_ALLOC, "ALLOC");
00321   PF (SEC_CONSTRUCTOR, "CONSTRUCTOR");
00322   PF (SEC_LOAD, "LOAD");
00323   PF (SEC_RELOC, "RELOC");
00324   PF (SEC_READONLY, "READONLY");
00325   PF (SEC_CODE, "CODE");
00326   PF (SEC_DATA, "DATA");
00327   PF (SEC_ROM, "ROM");
00328   PF (SEC_DEBUGGING, "DEBUGGING");
00329   PF (SEC_NEVER_LOAD, "NEVER_LOAD");
00330   PF (SEC_EXCLUDE, "EXCLUDE");
00331   PF (SEC_SORT_ENTRIES, "SORT_ENTRIES");
00332   if (bfd_get_arch (abfd) == bfd_arch_tic54x)
00333     {
00334       PF (SEC_TIC54X_BLOCK, "BLOCK");
00335       PF (SEC_TIC54X_CLINK, "CLINK");
00336     }
00337   PF (SEC_SMALL_DATA, "SMALL_DATA");
00338   if (bfd_get_flavour (abfd) == bfd_target_coff_flavour)
00339     PF (SEC_COFF_SHARED, "SHARED");
00340   PF (SEC_THREAD_LOCAL, "THREAD_LOCAL");
00341   PF (SEC_GROUP, "GROUP");
00342 
00343   if ((section->flags & SEC_LINK_ONCE) != 0)
00344     {
00345       const char *ls;
00346       struct coff_comdat_info *comdat;
00347 
00348       switch (section->flags & SEC_LINK_DUPLICATES)
00349        {
00350        default:
00351          abort ();
00352        case SEC_LINK_DUPLICATES_DISCARD:
00353          ls = "LINK_ONCE_DISCARD";
00354          break;
00355        case SEC_LINK_DUPLICATES_ONE_ONLY:
00356          ls = "LINK_ONCE_ONE_ONLY";
00357          break;
00358        case SEC_LINK_DUPLICATES_SAME_SIZE:
00359          ls = "LINK_ONCE_SAME_SIZE";
00360          break;
00361        case SEC_LINK_DUPLICATES_SAME_CONTENTS:
00362          ls = "LINK_ONCE_SAME_CONTENTS";
00363          break;
00364        }
00365       printf ("%s%s", comma, ls);
00366 
00367       comdat = bfd_coff_get_comdat_section (abfd, section);
00368       if (comdat != NULL)
00369        printf (" (COMDAT %s %ld)", comdat->name, comdat->symbol);
00370 
00371       comma = ", ";
00372     }
00373 
00374   printf ("\n");
00375 #undef PF
00376 }
00377 
00378 static void
00379 dump_headers (bfd *abfd)
00380 {
00381   printf (_("Sections:\n"));
00382 
00383 #ifndef BFD64
00384   printf (_("Idx Name          Size      VMA       LMA       File off  Algn"));
00385 #else
00386   /* With BFD64, non-ELF returns -1 and wants always 64 bit addresses.  */
00387   if (bfd_get_arch_size (abfd) == 32)
00388     printf (_("Idx Name          Size      VMA       LMA       File off  Algn"));
00389   else
00390     printf (_("Idx Name          Size      VMA               LMA               File off  Algn"));
00391 #endif
00392 
00393   if (wide_output)
00394     printf (_("  Flags"));
00395   if (abfd->flags & HAS_LOAD_PAGE)
00396     printf (_("  Pg"));
00397   printf ("\n");
00398 
00399   bfd_map_over_sections (abfd, dump_section_header, NULL);
00400 }
00401 
00402 static asymbol **
00403 slurp_symtab (bfd *abfd)
00404 {
00405   asymbol **sy = NULL;
00406   long storage;
00407 
00408   if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
00409     {
00410       symcount = 0;
00411       return NULL;
00412     }
00413 
00414   storage = bfd_get_symtab_upper_bound (abfd);
00415   if (storage < 0)
00416     bfd_fatal (bfd_get_filename (abfd));
00417   if (storage)
00418     sy = xmalloc (storage);
00419 
00420   symcount = bfd_canonicalize_symtab (abfd, sy);
00421   if (symcount < 0)
00422     bfd_fatal (bfd_get_filename (abfd));
00423   return sy;
00424 }
00425 
00426 /* Read in the dynamic symbols.  */
00427 
00428 static asymbol **
00429 slurp_dynamic_symtab (bfd *abfd)
00430 {
00431   asymbol **sy = NULL;
00432   long storage;
00433 
00434   storage = bfd_get_dynamic_symtab_upper_bound (abfd);
00435   if (storage < 0)
00436     {
00437       if (!(bfd_get_file_flags (abfd) & DYNAMIC))
00438        {
00439          non_fatal (_("%s: not a dynamic object"), bfd_get_filename (abfd));
00440          dynsymcount = 0;
00441          return NULL;
00442        }
00443 
00444       bfd_fatal (bfd_get_filename (abfd));
00445     }
00446   if (storage)
00447     sy = xmalloc (storage);
00448 
00449   dynsymcount = bfd_canonicalize_dynamic_symtab (abfd, sy);
00450   if (dynsymcount < 0)
00451     bfd_fatal (bfd_get_filename (abfd));
00452   return sy;
00453 }
00454 
00455 /* Filter out (in place) symbols that are useless for disassembly.
00456    COUNT is the number of elements in SYMBOLS.
00457    Return the number of useful symbols.  */
00458 
00459 static long
00460 remove_useless_symbols (asymbol **symbols, long count)
00461 {
00462   asymbol **in_ptr = symbols, **out_ptr = symbols;
00463 
00464   while (--count >= 0)
00465     {
00466       asymbol *sym = *in_ptr++;
00467 
00468       if (sym->name == NULL || sym->name[0] == '\0')
00469        continue;
00470       if (sym->flags & (BSF_DEBUGGING | BSF_SECTION_SYM))
00471        continue;
00472       if (bfd_is_und_section (sym->section)
00473          || bfd_is_com_section (sym->section))
00474        continue;
00475 
00476       *out_ptr++ = sym;
00477     }
00478   return out_ptr - symbols;
00479 }
00480 
00481 /* Sort symbols into value order.  */
00482 
00483 static int
00484 compare_symbols (const void *ap, const void *bp)
00485 {
00486   const asymbol *a = * (const asymbol **) ap;
00487   const asymbol *b = * (const asymbol **) bp;
00488   const char *an;
00489   const char *bn;
00490   size_t anl;
00491   size_t bnl;
00492   bfd_boolean af;
00493   bfd_boolean bf;
00494   flagword aflags;
00495   flagword bflags;
00496 
00497   if (bfd_asymbol_value (a) > bfd_asymbol_value (b))
00498     return 1;
00499   else if (bfd_asymbol_value (a) < bfd_asymbol_value (b))
00500     return -1;
00501 
00502   if (a->section > b->section)
00503     return 1;
00504   else if (a->section < b->section)
00505     return -1;
00506 
00507   an = bfd_asymbol_name (a);
00508   bn = bfd_asymbol_name (b);
00509   anl = strlen (an);
00510   bnl = strlen (bn);
00511 
00512   /* The symbols gnu_compiled and gcc2_compiled convey no real
00513      information, so put them after other symbols with the same value.  */
00514   af = (strstr (an, "gnu_compiled") != NULL
00515        || strstr (an, "gcc2_compiled") != NULL);
00516   bf = (strstr (bn, "gnu_compiled") != NULL
00517        || strstr (bn, "gcc2_compiled") != NULL);
00518 
00519   if (af && ! bf)
00520     return 1;
00521   if (! af && bf)
00522     return -1;
00523 
00524   /* We use a heuristic for the file name, to try to sort it after
00525      more useful symbols.  It may not work on non Unix systems, but it
00526      doesn't really matter; the only difference is precisely which
00527      symbol names get printed.  */
00528 
00529 #define file_symbol(s, sn, snl)                  \
00530   (((s)->flags & BSF_FILE) != 0                  \
00531    || ((sn)[(snl) - 2] == '.'                    \
00532        && ((sn)[(snl) - 1] == 'o'         \
00533           || (sn)[(snl) - 1] == 'a')))
00534 
00535   af = file_symbol (a, an, anl);
00536   bf = file_symbol (b, bn, bnl);
00537 
00538   if (af && ! bf)
00539     return 1;
00540   if (! af && bf)
00541     return -1;
00542 
00543   /* Try to sort global symbols before local symbols before function
00544      symbols before debugging symbols.  */
00545 
00546   aflags = a->flags;
00547   bflags = b->flags;
00548 
00549   if ((aflags & BSF_DEBUGGING) != (bflags & BSF_DEBUGGING))
00550     {
00551       if ((aflags & BSF_DEBUGGING) != 0)
00552        return 1;
00553       else
00554        return -1;
00555     }
00556   if ((aflags & BSF_FUNCTION) != (bflags & BSF_FUNCTION))
00557     {
00558       if ((aflags & BSF_FUNCTION) != 0)
00559        return -1;
00560       else
00561        return 1;
00562     }
00563   if ((aflags & BSF_LOCAL) != (bflags & BSF_LOCAL))
00564     {
00565       if ((aflags & BSF_LOCAL) != 0)
00566        return 1;
00567       else
00568        return -1;
00569     }
00570   if ((aflags & BSF_GLOBAL) != (bflags & BSF_GLOBAL))
00571     {
00572       if ((aflags & BSF_GLOBAL) != 0)
00573        return -1;
00574       else
00575        return 1;
00576     }
00577 
00578   /* Symbols that start with '.' might be section names, so sort them
00579      after symbols that don't start with '.'.  */
00580   if (an[0] == '.' && bn[0] != '.')
00581     return 1;
00582   if (an[0] != '.' && bn[0] == '.')
00583     return -1;
00584 
00585   /* Finally, if we can't distinguish them in any other way, try to
00586      get consistent results by sorting the symbols by name.  */
00587   return strcmp (an, bn);
00588 }
00589 
00590 /* Sort relocs into address order.  */
00591 
00592 static int
00593 compare_relocs (const void *ap, const void *bp)
00594 {
00595   const arelent *a = * (const arelent **) ap;
00596   const arelent *b = * (const arelent **) bp;
00597 
00598   if (a->address > b->address)
00599     return 1;
00600   else if (a->address < b->address)
00601     return -1;
00602 
00603   /* So that associated relocations tied to the same address show up
00604      in the correct order, we don't do any further sorting.  */
00605   if (a > b)
00606     return 1;
00607   else if (a < b)
00608     return -1;
00609   else
00610     return 0;
00611 }
00612 
00613 /* Print an address (VMA) to the output stream in INFO.
00614    If SKIP_ZEROES is TRUE, omit leading zeroes.  */
00615 
00616 static void
00617 objdump_print_value (bfd_vma vma, struct disassemble_info *info,
00618                    bfd_boolean skip_zeroes)
00619 {
00620   char buf[30];
00621   char *p;
00622   struct objdump_disasm_info *aux;
00623 
00624   aux = (struct objdump_disasm_info *) info->application_data;
00625   bfd_sprintf_vma (aux->abfd, buf, vma);
00626   if (! skip_zeroes)
00627     p = buf;
00628   else
00629     {
00630       for (p = buf; *p == '0'; ++p)
00631        ;
00632       if (*p == '\0')
00633        --p;
00634     }
00635   (*info->fprintf_func) (info->stream, "%s", p);
00636 }
00637 
00638 /* Print the name of a symbol.  */
00639 
00640 static void
00641 objdump_print_symname (bfd *abfd, struct disassemble_info *info,
00642                      asymbol *sym)
00643 {
00644   char *alloc;
00645   const char *name;
00646 
00647   alloc = NULL;
00648   name = bfd_asymbol_name (sym);
00649   if (do_demangle && name[0] != '\0')
00650     {
00651       /* Demangle the name.  */
00652       alloc = demangle (abfd, name);
00653       name = alloc;
00654     }
00655 
00656   if (info != NULL)
00657     (*info->fprintf_func) (info->stream, "%s", name);
00658   else
00659     printf ("%s", name);
00660 
00661   if (alloc != NULL)
00662     free (alloc);
00663 }
00664 
00665 /* Locate a symbol given a bfd and a section (from INFO->application_data),
00666    and a VMA.  If INFO->application_data->require_sec is TRUE, then always
00667    require the symbol to be in the section.  Returns NULL if there is no
00668    suitable symbol.  If PLACE is not NULL, then *PLACE is set to the index
00669    of the symbol in sorted_syms.  */
00670 
00671 static asymbol *
00672 find_symbol_for_address (bfd_vma vma,
00673                       struct disassemble_info *info,
00674                       long *place)
00675 {
00676   /* @@ Would it speed things up to cache the last two symbols returned,
00677      and maybe their address ranges?  For many processors, only one memory
00678      operand can be present at a time, so the 2-entry cache wouldn't be
00679      constantly churned by code doing heavy memory accesses.  */
00680 
00681   /* Indices in `sorted_syms'.  */
00682   long min = 0;
00683   long max = sorted_symcount;
00684   long thisplace;
00685   struct objdump_disasm_info *aux;
00686   bfd *abfd;
00687   asection *sec;
00688   unsigned int opb;
00689 
00690   if (sorted_symcount < 1)
00691     return NULL;
00692 
00693   aux = (struct objdump_disasm_info *) info->application_data;
00694   abfd = aux->abfd;
00695   sec = aux->sec;
00696   opb = bfd_octets_per_byte (abfd);
00697 
00698   /* Perform a binary search looking for the closest symbol to the
00699      required value.  We are searching the range (min, max].  */
00700   while (min + 1 < max)
00701     {
00702       asymbol *sym;
00703 
00704       thisplace = (max + min) / 2;
00705       sym = sorted_syms[thisplace];
00706 
00707       if (bfd_asymbol_value (sym) > vma)
00708        max = thisplace;
00709       else if (bfd_asymbol_value (sym) < vma)
00710        min = thisplace;
00711       else
00712        {
00713          min = thisplace;
00714          break;
00715        }
00716     }
00717 
00718   /* The symbol we want is now in min, the low end of the range we
00719      were searching.  If there are several symbols with the same
00720      value, we want the first one.  */
00721   thisplace = min;
00722   while (thisplace > 0
00723         && (bfd_asymbol_value (sorted_syms[thisplace])
00724             == bfd_asymbol_value (sorted_syms[thisplace - 1])))
00725     --thisplace;
00726 
00727   /* If the file is relocatable, and the symbol could be from this
00728      section, prefer a symbol from this section over symbols from
00729      others, even if the other symbol's value might be closer.
00730 
00731      Note that this may be wrong for some symbol references if the
00732      sections have overlapping memory ranges, but in that case there's
00733      no way to tell what's desired without looking at the relocation
00734      table.  */
00735   if (sorted_syms[thisplace]->section != sec
00736       && (aux->require_sec
00737          || ((abfd->flags & HAS_RELOC) != 0
00738              && vma >= bfd_get_section_vma (abfd, sec)
00739              && vma < (bfd_get_section_vma (abfd, sec)
00740                      + bfd_section_size (abfd, sec) / opb))))
00741     {
00742       long i;
00743 
00744       for (i = thisplace + 1; i < sorted_symcount; i++)
00745        {
00746          if (bfd_asymbol_value (sorted_syms[i])
00747              != bfd_asymbol_value (sorted_syms[thisplace]))
00748            break;
00749        }
00750 
00751       --i;
00752 
00753       for (; i >= 0; i--)
00754        {
00755          if (sorted_syms[i]->section == sec
00756              && (i == 0
00757                 || sorted_syms[i - 1]->section != sec
00758                 || (bfd_asymbol_value (sorted_syms[i])
00759                     != bfd_asymbol_value (sorted_syms[i - 1]))))
00760            {
00761              thisplace = i;
00762              break;
00763            }
00764        }
00765 
00766       if (sorted_syms[thisplace]->section != sec)
00767        {
00768          /* We didn't find a good symbol with a smaller value.
00769             Look for one with a larger value.  */
00770          for (i = thisplace + 1; i < sorted_symcount; i++)
00771            {
00772              if (sorted_syms[i]->section == sec)
00773               {
00774                 thisplace = i;
00775                 break;
00776               }
00777            }
00778        }
00779 
00780       if (sorted_syms[thisplace]->section != sec
00781          && (aux->require_sec
00782              || ((abfd->flags & HAS_RELOC) != 0
00783                 && vma >= bfd_get_section_vma (abfd, sec)
00784                 && vma < (bfd_get_section_vma (abfd, sec)
00785                          + bfd_section_size (abfd, sec)))))
00786        /* There is no suitable symbol.  */
00787        return NULL;
00788     }
00789 
00790   /* Give the target a chance to reject the symbol.  */
00791   while (! info->symbol_is_valid (sorted_syms [thisplace], info))
00792     {
00793       ++ thisplace;
00794       if (thisplace >= sorted_symcount
00795          || bfd_asymbol_value (sorted_syms [thisplace]) > vma)
00796        return NULL;
00797     }
00798 
00799   if (place != NULL)
00800     *place = thisplace;
00801 
00802   return sorted_syms[thisplace];
00803 }
00804 
00805 /* Print an address and the offset to the nearest symbol.  */
00806 
00807 static void
00808 objdump_print_addr_with_sym (bfd *abfd, asection *sec, asymbol *sym,
00809                           bfd_vma vma, struct disassemble_info *info,
00810                           bfd_boolean skip_zeroes)
00811 {
00812   objdump_print_value (vma, info, skip_zeroes);
00813 
00814   if (sym == NULL)
00815     {
00816       bfd_vma secaddr;
00817 
00818       (*info->fprintf_func) (info->stream, " <%s",
00819                           bfd_get_section_name (abfd, sec));
00820       secaddr = bfd_get_section_vma (abfd, sec);
00821       if (vma < secaddr)
00822        {
00823          (*info->fprintf_func) (info->stream, "-0x");
00824          objdump_print_value (secaddr - vma, info, TRUE);
00825        }
00826       else if (vma > secaddr)
00827        {
00828          (*info->fprintf_func) (info->stream, "+0x");
00829          objdump_print_value (vma - secaddr, info, TRUE);
00830        }
00831       (*info->fprintf_func) (info->stream, ">");
00832     }
00833   else
00834     {
00835       (*info->fprintf_func) (info->stream, " <");
00836       objdump_print_symname (abfd, info, sym);
00837       if (bfd_asymbol_value (sym) > vma)
00838        {
00839          (*info->fprintf_func) (info->stream, "-0x");
00840          objdump_print_value (bfd_asymbol_value (sym) - vma, info, TRUE);
00841        }
00842       else if (vma > bfd_asymbol_value (sym))
00843        {
00844          (*info->fprintf_func) (info->stream, "+0x");
00845          objdump_print_value (vma - bfd_asymbol_value (sym), info, TRUE);
00846        }
00847       (*info->fprintf_func) (info->stream, ">");
00848     }
00849 }
00850 
00851 /* Print an address (VMA), symbolically if possible.
00852    If SKIP_ZEROES is TRUE, don't output leading zeroes.  */
00853 
00854 static void
00855 objdump_print_addr (bfd_vma vma,
00856                   struct disassemble_info *info,
00857                   bfd_boolean skip_zeroes)
00858 {
00859   struct objdump_disasm_info *aux;
00860   asymbol *sym = NULL; /* Initialize to avoid compiler warning.  */
00861   bfd_boolean skip_find = FALSE;
00862 
00863   if (sorted_symcount < 1)
00864     {
00865       (*info->fprintf_func) (info->stream, "0x");
00866       objdump_print_value (vma, info, skip_zeroes);
00867       return;
00868     }
00869 
00870   aux = (struct objdump_disasm_info *) info->application_data;
00871 
00872   if (aux->reloc != NULL
00873       && aux->reloc->sym_ptr_ptr != NULL
00874       && * aux->reloc->sym_ptr_ptr != NULL)
00875     {
00876       sym = * aux->reloc->sym_ptr_ptr;
00877 
00878       /* Adjust the vma to the reloc.  */
00879       vma += bfd_asymbol_value (sym);
00880 
00881       if (bfd_is_und_section (bfd_get_section (sym)))
00882        skip_find = TRUE;
00883     }
00884 
00885   if (!skip_find)
00886     sym = find_symbol_for_address (vma, info, NULL);
00887 
00888   objdump_print_addr_with_sym (aux->abfd, aux->sec, sym, vma, info,
00889                             skip_zeroes);
00890 }
00891 
00892 /* Print VMA to INFO.  This function is passed to the disassembler
00893    routine.  */
00894 
00895 static void
00896 objdump_print_address (bfd_vma vma, struct disassemble_info *info)
00897 {
00898   objdump_print_addr (vma, info, ! prefix_addresses);
00899 }
00900 
00901 /* Determine if the given address has a symbol associated with it.  */
00902 
00903 static int
00904 objdump_symbol_at_address (bfd_vma vma, struct disassemble_info * info)
00905 {
00906   asymbol * sym;
00907 
00908   sym = find_symbol_for_address (vma, info, NULL);
00909 
00910   return (sym != NULL && (bfd_asymbol_value (sym) == vma));
00911 }
00912 
00913 /* Hold the last function name and the last line number we displayed
00914    in a disassembly.  */
00915 
00916 static char *prev_functionname;
00917 static unsigned int prev_line;
00918 
00919 /* We keep a list of all files that we have seen when doing a
00920    disassembly with source, so that we know how much of the file to
00921    display.  This can be important for inlined functions.  */
00922 
00923 struct print_file_list
00924 {
00925   struct print_file_list *next;
00926   const char *filename;
00927   const char *modname;
00928   unsigned int line;
00929   FILE *f;
00930 };
00931 
00932 static struct print_file_list *print_files;
00933 
00934 /* The number of preceding context lines to show when we start
00935    displaying a file for the first time.  */
00936 
00937 #define SHOW_PRECEDING_CONTEXT_LINES (5)
00938 
00939 /* Tries to open MODNAME, and if successful adds a node to print_files
00940    linked list and returns that node.  Returns NULL on failure.  */
00941 
00942 static struct print_file_list *
00943 try_print_file_open (const char *origname, const char *modname)
00944 {
00945   struct print_file_list *p;
00946   FILE *f;
00947 
00948   f = fopen (modname, "r");
00949   if (f == NULL)
00950     return NULL;
00951 
00952   if (print_files != NULL && print_files->f != NULL)
00953     {
00954       fclose (print_files->f);
00955       print_files->f = NULL;
00956     }
00957 
00958   p = xmalloc (sizeof (struct print_file_list));
00959   p->filename = origname;
00960   p->modname = modname;
00961   p->line = 0;
00962   p->f = f;
00963   p->next = print_files;
00964   print_files = p;
00965   return p;
00966 }
00967 
00968 /* If the the source file, as described in the symtab, is not found
00969    try to locate it in one of the paths specified with -I
00970    If found, add location to print_files linked list.  */
00971 
00972 static struct print_file_list *
00973 update_source_path (const char *filename)
00974 {
00975   struct print_file_list *p;
00976   const char *fname;
00977   int i;
00978 
00979   if (filename == NULL)
00980     return NULL;
00981 
00982   p = try_print_file_open (filename, filename);
00983   if (p != NULL)
00984     return p;
00985 
00986   if (include_path_count == 0)
00987     return NULL;
00988 
00989   /* Get the name of the file.  */
00990   fname = strrchr (filename, '/');
00991 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
00992   {
00993     /* We could have a mixed forward/back slash case.  */
00994     char *backslash = strrchr (filename, '\\');
00995     if (fname == NULL || (backslash != NULL && backslash > fname))
00996       fname = backslash;
00997     if (fname == NULL && filename[0] != '\0' && filename[1] == ':')
00998       fname = filename + 1;
00999   }
01000 #endif
01001   if (fname == NULL)
01002     fname = filename;
01003   else
01004     ++fname;
01005 
01006   /* If file exists under a new path, we need to add it to the list
01007      so that show_line knows about it.  */
01008   for (i = 0; i < include_path_count; i++)
01009     {
01010       char *modname = concat (include_paths[i], "/", fname, (const char *) 0);
01011 
01012       p = try_print_file_open (filename, modname);
01013       if (p)
01014        return p;
01015 
01016       free (modname);
01017     }
01018 
01019   return NULL;
01020 }
01021 
01022 /* Skip ahead to a given line in a file, optionally printing each
01023    line.  */
01024 
01025 static void
01026 skip_to_line (struct print_file_list *p, unsigned int line,
01027              bfd_boolean show)
01028 {
01029   while (p->line < line)
01030     {
01031       char buf[100];
01032 
01033       if (fgets (buf, sizeof buf, p->f) == NULL)
01034        {
01035          fclose (p->f);
01036          p->f = NULL;
01037          break;
01038        }
01039 
01040       if (show)
01041        printf ("%s", buf);
01042 
01043       if (strchr (buf, '\n') != NULL)
01044        ++p->line;
01045     }
01046 }
01047 
01048 /* Show the line number, or the source line, in a disassembly
01049    listing.  */
01050 
01051 static void
01052 show_line (bfd *abfd, asection *section, bfd_vma addr_offset)
01053 {
01054   const char *filename;
01055   const char *functionname;
01056   unsigned int line;
01057 
01058   if (! with_line_numbers && ! with_source_code)
01059     return;
01060 
01061   if (! bfd_find_nearest_line (abfd, section, syms, addr_offset, &filename,
01062                             &functionname, &line))
01063     return;
01064 
01065   if (filename != NULL && *filename == '\0')
01066     filename = NULL;
01067   if (functionname != NULL && *functionname == '\0')
01068     functionname = NULL;
01069 
01070   if (with_line_numbers)
01071     {
01072       if (functionname != NULL
01073          && (prev_functionname == NULL
01074              || strcmp (functionname, prev_functionname) != 0))
01075        printf ("%s():\n", functionname);
01076       if (line > 0 && line != prev_line)
01077        printf ("%s:%u\n", filename == NULL ? "???" : filename, line);
01078     }
01079 
01080   if (with_source_code
01081       && filename != NULL
01082       && line > 0)
01083     {
01084       struct print_file_list **pp, *p;
01085 
01086       for (pp = &print_files; *pp != NULL; pp = &(*pp)->next)
01087        if (strcmp ((*pp)->filename, filename) == 0)
01088          break;
01089       p = *pp;
01090 
01091       if (p != NULL)
01092        {
01093          if (p != print_files)
01094            {
01095              int l;
01096 
01097              /* We have reencountered a file name which we saw
01098                earlier.  This implies that either we are dumping out
01099                code from an included file, or the same file was
01100                linked in more than once.  There are two common cases
01101                of an included file: inline functions in a header
01102                file, and a bison or flex skeleton file.  In the
01103                former case we want to just start printing (but we
01104                back up a few lines to give context); in the latter
01105                case we want to continue from where we left off.  I
01106                can't think of a good way to distinguish the cases,
01107                so I used a heuristic based on the file name.  */
01108              if (strcmp (p->filename + strlen (p->filename) - 2, ".h") != 0)
01109               l = p->line;
01110              else
01111               {
01112                 l = line - SHOW_PRECEDING_CONTEXT_LINES;
01113                 if (l < 0)
01114                   l = 0;
01115               }
01116 
01117              if (p->f == NULL)
01118               {
01119                 p->f = fopen (p->modname, "r");
01120                 p->line = 0;
01121               }
01122              if (p->f != NULL)
01123               skip_to_line (p, l, FALSE);
01124 
01125              if (print_files->f != NULL)
01126               {
01127                 fclose (print_files->f);
01128                 print_files->f = NULL;
01129               }
01130            }
01131 
01132          if (p->f != NULL)
01133            {
01134              skip_to_line (p, line, TRUE);
01135              *pp = p->next;
01136              p->next = print_files;
01137              print_files = p;
01138            }
01139        }
01140       else
01141        {
01142          p = update_source_path (filename);
01143 
01144          if (p != NULL)
01145            {
01146              int l;
01147 
01148              if (file_start_context)
01149               l = 0;
01150              else
01151               l = line - SHOW_PRECEDING_CONTEXT_LINES;
01152              if (l < 0)
01153               l = 0;
01154              skip_to_line (p, l, FALSE);
01155              if (p->f != NULL)
01156               skip_to_line (p, line, TRUE);
01157            }
01158        }
01159     }
01160 
01161   if (functionname != NULL
01162       && (prev_functionname == NULL
01163          || strcmp (functionname, prev_functionname) != 0))
01164     {
01165       if (prev_functionname != NULL)
01166        free (prev_functionname);
01167       prev_functionname = xmalloc (strlen (functionname) + 1);
01168       strcpy (prev_functionname, functionname);
01169     }
01170 
01171   if (line > 0 && line != prev_line)
01172     prev_line = line;
01173 }
01174 
01175 /* Pseudo FILE object for strings.  */
01176 typedef struct
01177 {
01178   char *buffer;
01179   size_t pos;
01180   size_t alloc;
01181 } SFILE;
01182 
01183 /* sprintf to a "stream".  */
01184 
01185 static int ATTRIBUTE_PRINTF_2
01186 objdump_sprintf (SFILE *f, const char *format, ...)
01187 {
01188   size_t n;
01189   va_list args;
01190 
01191   while (1)
01192     {
01193       size_t space = f->alloc - f->pos;
01194   
01195       va_start (args, format);
01196       n = vsnprintf (f->buffer + f->pos, space, format, args);
01197       va_end (args);
01198 
01199       if (space > n)
01200        break;
01201       
01202       f->alloc = (f->alloc + n) * 2;
01203       f->buffer = xrealloc (f->buffer, f->alloc);
01204     }
01205   f->pos += n;
01206   
01207   return n;
01208 }
01209 
01210 /* Returns TRUE if the specified section should be dumped.  */
01211 
01212 static bfd_boolean
01213 process_section_p (asection * section)
01214 {
01215   size_t i;
01216 
01217   if (only == NULL)
01218     return TRUE;
01219 
01220   for (i = 0; i < only_used; i++)
01221     if (strcmp (only [i], section->name) == 0)
01222       return TRUE;
01223 
01224   return FALSE;
01225 }
01226 
01227 
01228 /* The number of zeroes we want to see before we start skipping them.
01229    The number is arbitrarily chosen.  */
01230 
01231 #define DEFAULT_SKIP_ZEROES 8
01232 
01233 /* The number of zeroes to skip at the end of a section.  If the
01234    number of zeroes at the end is between SKIP_ZEROES_AT_END and
01235    SKIP_ZEROES, they will be disassembled.  If there are fewer than
01236    SKIP_ZEROES_AT_END, they will be skipped.  This is a heuristic
01237    attempt to avoid disassembling zeroes inserted by section
01238    alignment.  */
01239 
01240 #define DEFAULT_SKIP_ZEROES_AT_END 3
01241 
01242 /* Disassemble some data in memory between given values.  */
01243 
01244 static void
01245 disassemble_bytes (struct disassemble_info * info,
01246                  disassembler_ftype        disassemble_fn,
01247                  bfd_boolean               insns,
01248                  bfd_byte *                data,
01249                  bfd_vma                   start_offset,
01250                  bfd_vma                   stop_offset,
01251                  bfd_vma                rel_offset,
01252                  arelent ***               relppp,
01253                  arelent **                relppend)
01254 {
01255   struct objdump_disasm_info *aux;
01256   asection *section;
01257   int octets_per_line;
01258   bfd_boolean done_dot;
01259   int skip_addr_chars;
01260   bfd_vma addr_offset;
01261   unsigned int opb = info->octets_per_byte;
01262   unsigned int skip_zeroes = info->skip_zeroes;
01263   unsigned int skip_zeroes_at_end = info->skip_zeroes_at_end;
01264   int octets = opb;
01265   SFILE sfile;
01266 
01267   aux = (struct objdump_disasm_info *) info->application_data;
01268   section = aux->sec;
01269 
01270   sfile.alloc = 120;
01271   sfile.buffer = xmalloc (sfile.alloc);
01272   sfile.pos = 0;
01273   
01274   if (insns)
01275     octets_per_line = 4;
01276   else
01277     octets_per_line = 16;
01278 
01279   /* Figure out how many characters to skip at the start of an
01280      address, to make the disassembly look nicer.  We discard leading
01281      zeroes in chunks of 4, ensuring that there is always a leading
01282      zero remaining.  */
01283   skip_addr_chars = 0;
01284   if (! prefix_addresses)
01285     {
01286       char buf[30];
01287       char *s;
01288 
01289       bfd_sprintf_vma
01290        (aux->abfd, buf,
01291         (section->vma
01292          + bfd_section_size (section->owner, section) / opb));
01293       s = buf;
01294       while (s[0] == '0' && s[1] == '0' && s[2] == '0' && s[3] == '0'
01295             && s[4] == '0')
01296        {
01297          skip_addr_chars += 4;
01298          s += 4;
01299        }
01300     }
01301 
01302   info->insn_info_valid = 0;
01303 
01304   done_dot = FALSE;
01305   addr_offset = start_offset;
01306   while (addr_offset < stop_offset)
01307     {
01308       bfd_vma z;
01309       bfd_boolean need_nl = FALSE;
01310       int previous_octets;
01311 
01312       /* Remember the length of the previous instruction.  */
01313       previous_octets = octets;
01314       octets = 0;
01315 
01316       /* If we see more than SKIP_ZEROES octets of zeroes, we just
01317         print `...'.  */
01318       for (z = addr_offset * opb; z < stop_offset * opb; z++)
01319        if (data[z] != 0)
01320          break;
01321       if (! disassemble_zeroes
01322          && (info->insn_info_valid == 0
01323              || info->branch_delay_insns == 0)
01324          && (z - addr_offset * opb >= skip_zeroes
01325              || (z == stop_offset * opb &&
01326                 z - addr_offset * opb < skip_zeroes_at_end)))
01327        {
01328          printf ("\t...\n");
01329 
01330          /* If there are more nonzero octets to follow, we only skip
01331             zeroes in multiples of 4, to try to avoid running over
01332             the start of an instruction which happens to start with
01333             zero.  */
01334          if (z != stop_offset * opb)
01335            z = addr_offset * opb + ((z - addr_offset * opb) &~ 3);
01336 
01337          octets = z - addr_offset * opb;
01338        }
01339       else
01340        {
01341          char buf[50];
01342          int bpc = 0;
01343          int pb = 0;
01344 
01345          done_dot = FALSE;
01346 
01347          if (with_line_numbers || with_source_code)
01348            show_line (aux->abfd, section, addr_offset);
01349 
01350          if (! prefix_addresses)
01351            {
01352              char *s;
01353 
01354              bfd_sprintf_vma (aux->abfd, buf, section->vma + addr_offset);
01355              for (s = buf + skip_addr_chars; *s == '0'; s++)
01356               *s = ' ';
01357              if (*s == '\0')
01358               *--s = '0';
01359              printf ("%s:\t", buf + skip_addr_chars);
01360            }
01361          else
01362            {
01363              aux->require_sec = TRUE;
01364              objdump_print_address (section->vma + addr_offset, info);
01365              aux->require_sec = FALSE;
01366              putchar (' ');
01367            }
01368 
01369          if (insns)
01370            {
01371              sfile.pos = 0;
01372              info->fprintf_func = (fprintf_ftype) objdump_sprintf;
01373              info->stream = &sfile;
01374              info->bytes_per_line = 0;
01375              info->bytes_per_chunk = 0;
01376              info->flags = 0;
01377 
01378              if (info->disassembler_needs_relocs
01379                 && *relppp < relppend)
01380               {
01381                 bfd_signed_vma distance_to_rel;
01382 
01383                 distance_to_rel = (**relppp)->address
01384                   - (rel_offset + addr_offset);
01385 
01386                 /* Check to see if the current reloc is associated with
01387                    the instruction that we are about to disassemble.  */
01388                 if (distance_to_rel == 0
01389                     /* FIXME: This is wrong.  We are trying to catch
01390                       relocs that are addressed part way through the
01391                       current instruction, as might happen with a packed
01392                       VLIW instruction.  Unfortunately we do not know the
01393                       length of the current instruction since we have not
01394                       disassembled it yet.  Instead we take a guess based
01395                       upon the length of the previous instruction.  The
01396                       proper solution is to have a new target-specific
01397                       disassembler function which just returns the length
01398                       of an instruction at a given address without trying
01399                       to display its disassembly. */
01400                     || (distance_to_rel > 0
01401                        && distance_to_rel < (bfd_signed_vma) (previous_octets/ opb)))
01402                   {
01403                     info->flags = INSN_HAS_RELOC;
01404                     aux->reloc = **relppp;
01405                   }
01406                 else
01407                   aux->reloc = NULL;
01408               }
01409 
01410              octets = (*disassemble_fn) (section->vma + addr_offset, info);
01411              info->fprintf_func = (fprintf_ftype) fprintf;
01412              info->stream = stdout;
01413              if (info->bytes_per_line != 0)
01414               octets_per_line = info->bytes_per_line;
01415              if (octets < 0)
01416               {
01417                 if (sfile.pos)
01418                   printf ("%s\n", sfile.buffer);
01419                 break;
01420               }
01421            }
01422          else
01423            {
01424              bfd_vma j;
01425 
01426              octets = octets_per_line;
01427              if (addr_offset + octets / opb > stop_offset)
01428               octets = (stop_offset - addr_offset) * opb;
01429 
01430              for (j = addr_offset * opb; j < addr_offset * opb + octets; ++j)
01431               {
01432                 if (ISPRINT (data[j]))
01433                   buf[j - addr_offset * opb] = data[j];
01434                 else
01435                   buf[j - addr_offset * opb] = '.';
01436               }
01437              buf[j - addr_offset * opb] = '\0';
01438            }
01439 
01440          if (prefix_addresses
01441              ? show_raw_insn > 0
01442              : show_raw_insn >= 0)
01443            {
01444              bfd_vma j;
01445 
01446              /* If ! prefix_addresses and ! wide_output, we print
01447                octets_per_line octets per line.  */
01448              pb = octets;
01449              if (pb > octets_per_line && ! prefix_addresses && ! wide_output)
01450               pb = octets_per_line;
01451 
01452              if (info->bytes_per_chunk)
01453               bpc = info->bytes_per_chunk;
01454              else
01455               bpc = 1;
01456 
01457              for (j = addr_offset * opb; j < addr_offset * opb + pb; j += bpc)
01458               {
01459                 int k;
01460 
01461                 if (bpc > 1 && info->display_endian == BFD_ENDIAN_LITTLE)
01462                   {
01463                     for (k = bpc - 1; k >= 0; k--)
01464                      printf ("%02x", (unsigned) data[j + k]);
01465                     putchar (' ');
01466                   }
01467                 else
01468                   {
01469                     for (k = 0; k < bpc; k++)
01470                      printf ("%02x", (unsigned) data[j + k]);
01471                     putchar (' ');
01472                   }
01473               }
01474 
01475              for (; pb < octets_per_line; pb += bpc)
01476               {
01477                 int k;
01478 
01479                 for (k = 0; k < bpc; k++)
01480                   printf ("  ");
01481                 putchar (' ');
01482               }
01483 
01484              /* Separate raw data from instruction by extra space.  */
01485              if (insns)
01486               putchar ('\t');
01487              else
01488               printf ("    ");
01489            }
01490 
01491          if (! insns)
01492            printf ("%s", buf);
01493          else if (sfile.pos)
01494            printf ("%s", sfile.buffer);
01495 
01496          if (prefix_addresses
01497              ? show_raw_insn > 0
01498              : show_raw_insn >= 0)
01499            {
01500              while (pb < octets)
01501               {
01502                 bfd_vma j;
01503                 char *s;
01504 
01505                 putchar ('\n');
01506                 j = addr_offset * opb + pb;
01507 
01508                 bfd_sprintf_vma (aux->abfd, buf, section->vma + j / opb);
01509                 for (s = buf + skip_addr_chars; *s == '0'; s++)
01510                   *s = ' ';
01511                 if (*s == '\0')
01512                   *--s = '0';
01513                 printf ("%s:\t", buf + skip_addr_chars);
01514 
01515                 pb += octets_per_line;
01516                 if (pb > octets)
01517                   pb = octets;
01518                 for (; j < addr_offset * opb + pb; j += bpc)
01519                   {
01520                     int k;
01521 
01522                     if (bpc > 1 && info->display_endian == BFD_ENDIAN_LITTLE)
01523                      {
01524                        for (k = bpc - 1; k >= 0; k--)
01525                          printf ("%02x", (unsigned) data[j + k]);
01526                        putchar (' ');
01527                      }
01528                     else
01529                      {
01530                        for (k = 0; k < bpc; k++)
01531                          printf ("%02x", (unsigned) data[j + k]);
01532                        putchar (' ');
01533                      }
01534                   }
01535               }
01536            }
01537 
01538          if (!wide_output)
01539            putchar ('\n');
01540          else
01541            need_nl = TRUE;
01542        }
01543 
01544       while ((*relppp) < relppend
01545             && (**relppp)->address < rel_offset + addr_offset + octets / opb)
01546        {
01547          if (dump_reloc_info || dump_dynamic_reloc_info)
01548            {
01549              arelent *q;
01550 
01551              q = **relppp;
01552 
01553              if (wide_output)
01554               putchar ('\t');
01555              else
01556               printf ("\t\t\t");
01557 
01558              objdump_print_value (section->vma - rel_offset + q->address,
01559                                info, TRUE);
01560 
01561              if (q->howto == NULL)
01562               printf (": *unknown*\t");
01563              else if (q->howto->name)
01564               printf (": %s\t", q->howto->name);
01565              else
01566               printf (": %d\t", q->howto->type);
01567 
01568              if (q->sym_ptr_ptr == NULL || *q->sym_ptr_ptr == NULL)
01569               printf ("*unknown*");
01570              else
01571               {
01572                 const char *sym_name;
01573 
01574                 sym_name = bfd_asymbol_name (*q->sym_ptr_ptr);
01575                 if (sym_name != NULL && *sym_name != '\0')
01576                   objdump_print_symname (aux->abfd, info, *q->sym_ptr_ptr);
01577                 else
01578                   {
01579                     asection *sym_sec;
01580 
01581                     sym_sec = bfd_get_section (*q->sym_ptr_ptr);
01582                     sym_name = bfd_get_section_name (aux->abfd, sym_sec);
01583                     if (sym_name == NULL || *sym_name == '\0')
01584                      sym_name = "*unknown*";
01585                     printf ("%s", sym_name);
01586                   }
01587               }
01588 
01589              if (q->addend)
01590               {
01591                 printf ("+0x");
01592                 objdump_print_value (q->addend, info, TRUE);
01593               }
01594 
01595              printf ("\n");
01596              need_nl = FALSE;
01597            }
01598          ++(*relppp);
01599        }
01600 
01601       if (need_nl)
01602        printf ("\n");
01603 
01604       addr_offset += octets / opb;
01605     }
01606 
01607   free (sfile.buffer);
01608 }
01609 
01610 static void
01611 disassemble_section (bfd *abfd, asection *section, void *info)
01612 {
01613   struct disassemble_info *    pinfo = (struct disassemble_info *) info;
01614   struct objdump_disasm_info * paux;
01615   unsigned int                 opb = pinfo->octets_per_byte;
01616   bfd_byte *                   data = NULL;
01617   bfd_size_type                datasize = 0;
01618   arelent **                   rel_pp = NULL;
01619   arelent **                   rel_ppstart = NULL;
01620   arelent **                   rel_ppend;
01621   unsigned long                stop_offset;
01622   asymbol *                    sym = NULL;
01623   long                         place = 0;
01624   long                         rel_count;
01625   bfd_vma                      rel_offset;
01626   unsigned long                addr_offset;
01627 
01628   /* Sections that do not contain machine
01629      code are not normally disassembled.  */
01630   if (! disassemble_all
01631       && only == NULL
01632       && ((section->flags & (SEC_CODE | SEC_HAS_CONTENTS))
01633          != (SEC_CODE | SEC_HAS_CONTENTS)))
01634     return;
01635 
01636   if (! process_section_p (section))
01637     return;
01638 
01639   datasize = bfd_get_section_size (section);
01640   if (datasize == 0)
01641     return;
01642 
01643   /* Decide which set of relocs to use.  Load them if necessary.  */
01644   paux = (struct objdump_disasm_info *) pinfo->application_data;
01645   if (paux->dynrelbuf)
01646     {
01647       rel_pp = paux->dynrelbuf;
01648       rel_count = paux->dynrelcount;
01649       /* Dynamic reloc addresses are absolute, non-dynamic are section
01650         relative.  REL_OFFSET specifies the reloc address corresponding
01651         to the start of this section.  */
01652       rel_offset = section->vma;
01653     }
01654   else
01655     {
01656       rel_count = 0;
01657       rel_pp = NULL;
01658       rel_offset = 0;
01659 
01660       if ((section->flags & SEC_RELOC) != 0
01661          && (dump_reloc_info || pinfo->disassembler_needs_relocs))
01662        {
01663          long relsize;
01664 
01665          relsize = bfd_get_reloc_upper_bound (abfd, section);
01666          if (relsize < 0)
01667            bfd_fatal (bfd_get_filename (abfd));
01668 
01669          if (relsize > 0)
01670            {
01671              rel_ppstart = rel_pp = xmalloc (relsize);
01672              rel_count = bfd_canonicalize_reloc (abfd, section, rel_pp, syms);
01673              if (rel_count < 0)
01674               bfd_fatal (bfd_get_filename (abfd));
01675 
01676              /* Sort the relocs by address.  */
01677              qsort (rel_pp, rel_count, sizeof (arelent *), compare_relocs);
01678            }
01679        }
01680 
01681     }
01682   rel_ppend = rel_pp + rel_count;
01683 
01684   data = xmalloc (datasize);
01685 
01686   bfd_get_section_contents (abfd, section, data, 0, datasize);
01687 
01688   paux->sec = section;
01689   pinfo->buffer = data;
01690   pinfo->buffer_vma = section->vma;
01691   pinfo->buffer_length = datasize;
01692   pinfo->section = section;
01693 
01694   if (start_address == (bfd_vma) -1
01695       || start_address < pinfo->buffer_vma)
01696     addr_offset = 0;
01697   else
01698     addr_offset = start_address - pinfo->buffer_vma;
01699 
01700   if (stop_address == (bfd_vma) -1)
01701     stop_offset = datasize / opb;
01702   else
01703     {
01704       if (stop_address < pinfo->buffer_vma)
01705        stop_offset = 0;
01706       else
01707        stop_offset = stop_address - pinfo->buffer_vma;
01708       if (stop_offset > pinfo->buffer_length / opb)
01709        stop_offset = pinfo->buffer_length / opb;
01710     }
01711 
01712   /* Skip over the relocs belonging to addresses below the
01713      start address.  */
01714   while (rel_pp < rel_ppend
01715         && (*rel_pp)->address < rel_offset + addr_offset)
01716     ++rel_pp;
01717 
01718   printf (_("Disassembly of section %s:\n"), section->name);
01719 
01720   /* Find the nearest symbol forwards from our current position.  */
01721   paux->require_sec = TRUE;
01722   sym = find_symbol_for_address (section->vma + addr_offset, info, &place);
01723   paux->require_sec = FALSE;
01724 
01725   /* Disassemble a block of instructions up to the address associated with
01726      the symbol we have just found.  Then print the symbol and find the
01727      next symbol on.  Repeat until we have disassembled the entire section
01728      or we have reached the end of the address range we are interested in.  */
01729   while (addr_offset < stop_offset)
01730     {
01731       bfd_vma addr;
01732       asymbol *nextsym;
01733       unsigned long nextstop_offset;
01734       bfd_boolean insns;
01735 
01736       addr = section->vma + addr_offset;
01737 
01738       if (sym != NULL && bfd_asymbol_value (sym) <= addr)
01739        {
01740          int x;
01741 
01742          for (x = place;
01743               (x < sorted_symcount
01744               && (bfd_asymbol_value (sorted_syms[x]) <= addr));
01745               ++x)
01746            continue;
01747 
01748          pinfo->symbols = sorted_syms + place;
01749          pinfo->num_symbols = x - place;
01750          pinfo->symtab_pos = place;
01751        }
01752       else
01753        {
01754          pinfo->symbols = NULL;
01755          pinfo->num_symbols = 0;
01756          pinfo->symtab_pos = -1;
01757        }
01758 
01759       if (! prefix_addresses)
01760        {
01761          pinfo->fprintf_func (pinfo->stream, "\n");
01762          objdump_print_addr_with_sym (abfd, section, sym, addr,
01763                                    pinfo, FALSE);
01764          pinfo->fprintf_func (pinfo->stream, ":\n");
01765        }
01766 
01767       if (sym != NULL && bfd_asymbol_value (sym) > addr)
01768        nextsym = sym;
01769       else if (sym == NULL)
01770        nextsym = NULL;
01771       else
01772        {
01773 #define is_valid_next_sym(SYM) \
01774   ((SYM)->section == section \
01775    && (bfd_asymbol_value (SYM) > bfd_asymbol_value (sym)) \
01776    && pinfo->symbol_is_valid (SYM, pinfo))
01777            
01778          /* Search forward for the next appropriate symbol in
01779             SECTION.  Note that all the symbols are sorted
01780             together into one big array, and that some sections
01781             may have overlapping addresses.  */
01782          while (place < sorted_symcount
01783                && ! is_valid_next_sym (sorted_syms [place]))
01784            ++place;
01785 
01786          if (place >= sorted_symcount)
01787            nextsym = NULL;
01788          else
01789            nextsym = sorted_syms[place];
01790        }
01791 
01792       if (sym != NULL && bfd_asymbol_value (sym) > addr)
01793        nextstop_offset = bfd_asymbol_value (sym) - section->vma;
01794       else if (nextsym == NULL)
01795        nextstop_offset = stop_offset;
01796       else
01797        nextstop_offset = bfd_asymbol_value (nextsym) - section->vma;
01798 
01799       if (nextstop_offset > stop_offset)
01800        nextstop_offset = stop_offset;
01801 
01802       /* If a symbol is explicitly marked as being an object
01803         rather than a function, just dump the bytes without
01804         disassembling them.  */
01805       if (disassemble_all
01806          || sym == NULL
01807          || bfd_asymbol_value (sym) > addr
01808          || ((sym->flags & BSF_OBJECT) == 0
01809              && (strstr (bfd_asymbol_name (sym), "gnu_compiled")
01810                 == NULL)
01811              && (strstr (bfd_asymbol_name (sym), "gcc2_compiled")
01812                 == NULL))
01813          || (sym->flags & BSF_FUNCTION) != 0)
01814        insns = TRUE;
01815       else
01816        insns = FALSE;
01817 
01818       disassemble_bytes (pinfo, paux->disassemble_fn, insns, data,
01819                       addr_offset, nextstop_offset,
01820                       rel_offset, &rel_pp, rel_ppend);
01821 
01822       addr_offset = nextstop_offset;
01823       sym = nextsym;
01824     }
01825 
01826   free (data);
01827 
01828   if (rel_ppstart != NULL)
01829     free (rel_ppstart);
01830 }
01831 
01832 /* Disassemble the contents of an object file.  */
01833 
01834 static void
01835 disassemble_data (bfd *abfd)
01836 {
01837   struct disassemble_info disasm_info;
01838   struct objdump_disasm_info aux;
01839   long i;
01840 
01841   print_files = NULL;
01842   prev_functionname = NULL;
01843   prev_line = -1;
01844 
01845   /* We make a copy of syms to sort.  We don't want to sort syms
01846      because that will screw up the relocs.  */
01847   sorted_symcount = symcount ? symcount : dynsymcount;
01848   sorted_syms = xmalloc ((sorted_symcount + synthcount) * sizeof (asymbol *));
01849   memcpy (sorted_syms, symcount ? syms : dynsyms,
01850          sorted_symcount * sizeof (asymbol *));
01851 
01852   sorted_symcount = remove_useless_symbols (sorted_syms, sorted_symcount);
01853 
01854   for (i = 0; i < synthcount; ++i)
01855     {
01856       sorted_syms[sorted_symcount] = synthsyms + i;
01857       ++sorted_symcount;
01858     }
01859 
01860   /* Sort the symbols into section and symbol order.  */
01861   qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
01862 
01863   init_disassemble_info (&disasm_info, stdout, (fprintf_ftype) fprintf);
01864 
01865   disasm_info.application_data = (void *) &aux;
01866   aux.abfd = abfd;
01867   aux.require_sec = FALSE;
01868   aux.dynrelbuf = NULL;
01869   aux.dynrelcount = 0;
01870   aux.reloc = NULL;
01871 
01872   disasm_info.print_address_func = objdump_print_address;
01873   disasm_info.symbol_at_address_func = objdump_symbol_at_address;
01874 
01875   if (machine != NULL)
01876     {
01877       const bfd_arch_info_type *info = bfd_scan_arch (machine);
01878 
01879       if (info == NULL)
01880        fatal (_("Can't use supplied machine %s"), machine);
01881 
01882       abfd->arch_info = info;
01883     }
01884 
01885   if (endian != BFD_ENDIAN_UNKNOWN)
01886     {
01887       struct bfd_target *xvec;
01888 
01889       xvec = xmalloc (sizeof (struct bfd_target));
01890       memcpy (xvec, abfd->xvec, sizeof (struct bfd_target));
01891       xvec->byteorder = endian;
01892       abfd->xvec = xvec;
01893     }
01894 
01895   /* Use libopcodes to locate a suitable disassembler.  */
01896   aux.disassemble_fn = disassembler (abfd);
01897   if (!aux.disassemble_fn)
01898     {
01899       non_fatal (_("Can't disassemble for architecture %s\n"),
01900                bfd_printable_arch_mach (bfd_get_arch (abfd), 0));
01901       exit_status = 1;
01902       return;
01903     }
01904 
01905   disasm_info.flavour = bfd_get_flavour (abfd);
01906   disasm_info.arch = bfd_get_arch (abfd);
01907   disasm_info.mach = bfd_get_mach (abfd);
01908   disasm_info.disassembler_options = disassembler_options;
01909   disasm_info.octets_per_byte = bfd_octets_per_byte (abfd);
01910   disasm_info.skip_zeroes = DEFAULT_SKIP_ZEROES;
01911   disasm_info.skip_zeroes_at_end = DEFAULT_SKIP_ZEROES_AT_END;
01912   disasm_info.disassembler_needs_relocs = FALSE;
01913 
01914   if (bfd_big_endian (abfd))
01915     disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_BIG;
01916   else if (bfd_little_endian (abfd))
01917     disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_LITTLE;
01918   else
01919     /* ??? Aborting here seems too drastic.  We could default to big or little
01920        instead.  */
01921     disasm_info.endian = BFD_ENDIAN_UNKNOWN;
01922 
01923   /* Allow the target to customize the info structure.  */
01924   disassemble_init_for_target (& disasm_info);
01925 
01926   /* Pre-load the dynamic relocs if we are going
01927      to be dumping them along with the disassembly.  */
01928   if (dump_dynamic_reloc_info)
01929     {
01930       long relsize = bfd_get_dynamic_reloc_upper_bound (abfd);
01931   
01932       if (relsize < 0)
01933        bfd_fatal (bfd_get_filename (abfd));
01934 
01935       if (relsize > 0)
01936        {
01937          aux.dynrelbuf = xmalloc (relsize);
01938          aux.dynrelcount = bfd_canonicalize_dynamic_reloc (abfd,
01939                                                      aux.dynrelbuf,
01940                                                      dynsyms);
01941          if (aux.dynrelcount < 0)
01942            bfd_fatal (bfd_get_filename (abfd));
01943 
01944          /* Sort the relocs by address.  */
01945          qsort (aux.dynrelbuf, aux.dynrelcount, sizeof (arelent *),
01946                compare_relocs);
01947        }
01948     }
01949   disasm_info.symtab = sorted_syms;
01950   disasm_info.symtab_size = sorted_symcount;
01951 
01952   bfd_map_over_sections (abfd, disassemble_section, & disasm_info);
01953 
01954   if (aux.dynrelbuf != NULL)
01955     free (aux.dynrelbuf);
01956   free (sorted_syms);
01957 }
01958 
01959 int
01960 load_debug_section (enum dwarf_section_display_enum debug, void *file)
01961 {
01962   struct dwarf_section *section = &debug_displays [debug].section;
01963   bfd *abfd = file;
01964   asection *sec;
01965   bfd_boolean ret;
01966 
01967   /* If it is already loaded, do nothing.  */
01968   if (section->start != NULL)
01969     return 1;
01970 
01971   /* Locate the debug section.  */
01972   sec = bfd_get_section_by_name (abfd, section->name);
01973   if (sec == NULL)
01974     return 0;
01975 
01976   section->address = bfd_get_section_vma (abfd, sec);
01977   section->size = bfd_get_section_size (sec);
01978   section->start = xmalloc (section->size);
01979 
01980   if (is_relocatable && debug_displays [debug].relocate)
01981     ret = bfd_simple_get_relocated_section_contents (abfd,
01982                                                sec,
01983                                                section->start,
01984                                                syms) != NULL;
01985   else
01986     ret = bfd_get_section_contents (abfd, sec, section->start, 0,
01987                                 section->size);
01988 
01989   if (!ret)
01990     {
01991       free_debug_section (debug);
01992       printf (_("\nCan't get contents for section '%s'.\n"),
01993              section->name);
01994     }
01995 
01996   return ret;
01997 }
01998 
01999 void
02000 free_debug_section (enum dwarf_section_display_enum debug)
02001 {
02002   struct dwarf_section *section = &debug_displays [debug].section;
02003 
02004   if (section->start == NULL)
02005     return;
02006 
02007   free ((char *) section->start);
02008   section->start = NULL;
02009   section->address = 0;
02010   section->size = 0;
02011 }
02012 
02013 static void
02014 dump_dwarf_section (bfd *abfd, asection *section,
02015                   void *arg ATTRIBUTE_UNUSED)
02016 {
02017   const char *name = bfd_get_section_name (abfd, section);
02018   const char *match;
02019   enum dwarf_section_display_enum i;
02020 
02021   if (CONST_STRNEQ (name, ".gnu.linkonce.wi."))
02022     match = ".debug_info";
02023   else
02024     match = name;
02025 
02026   for (i = 0; i < max; i++)
02027     if (strcmp (debug_displays[i].section.name, match) == 0)
02028       {
02029        if (!debug_displays[i].eh_frame)
02030          {
02031            struct dwarf_section *sec = &debug_displays [i].section;
02032 
02033            if (load_debug_section (i, abfd))
02034              {
02035               debug_displays[i].display (sec, abfd);
02036 
02037               if (i != info && i != abbrev)
02038                 free_debug_section (i);
02039              }
02040          }
02041        break;
02042       }
02043 }
02044 
02045 static const char *mach_o_dwarf_sections [] = {
02046   "LC_SEGMENT.__DWARFA.__debug_abbrev",          /* .debug_abbrev */
02047   "LC_SEGMENT.__DWARFA.__debug_aranges",  /* .debug_aranges */
02048   "LC_SEGMENT.__DWARFA.__debug_frame",           /* .debug_frame */
02049   "LC_SEGMENT.__DWARFA.__debug_info",            /* .debug_info */
02050   "LC_SEGMENT.__DWARFA.__debug_line",            /* .debug_line */
02051   "LC_SEGMENT.__DWARFA.__debug_pubnames", /* .debug_pubnames */
02052   ".eh_frame",                                   /* .eh_frame */
02053   "LC_SEGMENT.__DWARFA.__debug_macinfo",  /* .debug_macinfo */
02054   "LC_SEGMENT.__DWARFA.__debug_str",             /* .debug_str */
02055   "LC_SEGMENT.__DWARFA.__debug_loc",             /* .debug_loc */
02056   "LC_SEGMENT.__DWARFA.__debug_pubtypes", /* .debug_pubtypes */
02057   "LC_SEGMENT.__DWARFA.__debug_ranges",          /* .debug_ranges */
02058   "LC_SEGMENT.__DWARFA.__debug_static_func",     /* .debug_static_func */
02059   "LC_SEGMENT.__DWARFA.__debug_static_vars",     /* .debug_static_vars */
02060   "LC_SEGMENT.__DWARFA.__debug_types",           /* .debug_types */
02061   "LC_SEGMENT.__DWARFA.__debug_weaknames" /* .debug_weaknames */
02062 };
02063 
02064 static const char *generic_dwarf_sections [max];
02065 
02066 static void
02067 check_mach_o_dwarf (bfd *abfd)
02068 {
02069   static enum bfd_flavour old_flavour = bfd_target_unknown_flavour;
02070   enum bfd_flavour current_flavour = bfd_get_flavour (abfd);
02071   enum dwarf_section_display_enum i;
02072 
02073   if (generic_dwarf_sections [0] == NULL)
02074     for (i = 0; i < max; i++)
02075       generic_dwarf_sections [i] = debug_displays[i].section.name;
02076 
02077   if (old_flavour != current_flavour)
02078     {
02079       if (current_flavour == bfd_target_mach_o_flavour)
02080        for (i = 0; i < max; i++)
02081          debug_displays[i].section.name = mach_o_dwarf_sections [i];
02082       else if (old_flavour == bfd_target_mach_o_flavour)
02083        for (i = 0; i < max; i++)
02084          debug_displays[i].section.name = generic_dwarf_sections [i];
02085 
02086       old_flavour = current_flavour;
02087     }
02088 }
02089 
02090 /* Dump the dwarf debugging information.  */
02091 
02092 static void
02093 dump_dwarf (bfd *abfd)
02094 {
02095   is_relocatable = ((abfd->flags & (HAS_RELOC | EXEC_P | DYNAMIC))
02096                   == HAS_RELOC);
02097 
02098   /* FIXME: bfd_get_arch_size may return -1.  We assume that 64bit
02099      targets will return 64.  */
02100   eh_addr_size = bfd_get_arch_size (abfd) == 64 ? 8 : 4;
02101 
02102   if (bfd_big_endian (abfd))
02103     byte_get = byte_get_big_endian;
02104   else if (bfd_little_endian (abfd))
02105     byte_get = byte_get_little_endian;
02106   else
02107     abort ();
02108 
02109   check_mach_o_dwarf (abfd);
02110 
02111   bfd_map_over_sections (abfd, dump_dwarf_section, NULL);
02112 
02113   free_debug_memory ();
02114 }
02115 
02116 /* Read ABFD's stabs section STABSECT_NAME, and return a pointer to
02117    it.  Return NULL on failure.   */
02118 
02119 static char *
02120 read_section_stabs (bfd *abfd, const char *sect_name, bfd_size_type *size_ptr)
02121 {
02122   asection *stabsect;
02123   bfd_size_type size;
02124   char *contents;
02125 
02126   stabsect = bfd_get_section_by_name (abfd, sect_name);
02127   if (stabsect == NULL)
02128     {
02129       printf (_("No %s section present\n\n"), sect_name);
02130       return FALSE;
02131     }
02132 
02133   size = bfd_section_size (abfd, stabsect);
02134   contents  = xmalloc (size);
02135 
02136   if (! bfd_get_section_contents (abfd, stabsect, contents, 0, size))
02137     {
02138       non_fatal (_("Reading %s section of %s failed: %s"),
02139                sect_name, bfd_get_filename (abfd),
02140                bfd_errmsg (bfd_get_error ()));
02141       free (contents);
02142       exit_status = 1;
02143       return NULL;
02144     }
02145 
02146   *size_ptr = size;
02147 
02148   return contents;
02149 }
02150 
02151 /* Stabs entries use a 12 byte format:
02152      4 byte string table index
02153      1 byte stab type
02154      1 byte stab other field
02155      2 byte stab desc field
02156      4 byte stab value
02157    FIXME: This will have to change for a 64 bit object format.  */
02158 
02159 #define STRDXOFF  (0)
02160 #define TYPEOFF   (4)
02161 #define OTHEROFF  (5)
02162 #define DESCOFF   (6)
02163 #define VALOFF    (8)
02164 #define STABSIZE (12)
02165 
02166 /* Print ABFD's stabs section STABSECT_NAME (in `stabs'),
02167    using string table section STRSECT_NAME (in `strtab').  */
02168 
02169 static void
02170 print_section_stabs (bfd *abfd,
02171                    const char *stabsect_name,
02172                    unsigned *string_offset_ptr)
02173 {
02174   int i;
02175   unsigned file_string_table_offset = 0;
02176   unsigned next_file_string_table_offset = *string_offset_ptr;
02177   bfd_byte *stabp, *stabs_end;
02178 
02179   stabp = stabs;
02180   stabs_end = stabp + stab_size;
02181 
02182   printf (_("Contents of %s section:\n\n"), stabsect_name);
02183   printf ("Symnum n_type n_othr n_desc n_value  n_strx String\n");
02184 
02185   /* Loop through all symbols and print them.
02186 
02187      We start the index at -1 because there is a dummy symbol on
02188      the front of stabs-in-{coff,elf} sections that supplies sizes.  */
02189   for (i = -1; stabp < stabs_end; stabp += STABSIZE, i++)
02190     {
02191       const char *name;
02192       unsigned long strx;
02193       unsigned char type, other;
02194       unsigned short desc;
02195       bfd_vma value;
02196 
02197       strx = bfd_h_get_32 (abfd, stabp + STRDXOFF);
02198       type = bfd_h_get_8 (abfd, stabp + TYPEOFF);
02199       other = bfd_h_get_8 (abfd, stabp + OTHEROFF);
02200       desc = bfd_h_get_16 (abfd, stabp + DESCOFF);
02201       value = bfd_h_get_32 (abfd, stabp + VALOFF);
02202 
02203       printf ("\n%-6d ", i);
02204       /* Either print the stab name, or, if unnamed, print its number
02205         again (makes consistent formatting for tools like awk).  */
02206       name = bfd_get_stab_name (type);
02207       if (name != NULL)
02208        printf ("%-6s", name);
02209       else if (type == N_UNDF)
02210        printf ("HdrSym");
02211       else
02212        printf ("%-6d", type);
02213       printf (" %-6d %-6d ", other, desc);
02214       bfd_printf_vma (abfd, value);
02215       printf (" %-6lu", strx);
02216 
02217       /* Symbols with type == 0 (N_UNDF) specify the length of the
02218         string table associated with this file.  We use that info
02219         to know how to relocate the *next* file's string table indices.  */
02220       if (type == N_UNDF)
02221        {
02222          file_string_table_offset = next_file_string_table_offset;
02223          next_file_string_table_offset += value;
02224        }
02225       else
02226        {
02227          /* Using the (possibly updated) string table offset, print the
02228             string (if any) associated with this symbol.  */
02229          if ((strx + file_string_table_offset) < stabstr_size)
02230            printf (" %s", &strtab[strx + file_string_table_offset]);
02231          else
02232            printf (" *");
02233        }
02234     }
02235   printf ("\n\n");
02236   *string_offset_ptr = next_file_string_table_offset;
02237 }
02238 
02239 typedef struct
02240 {
02241   const char * section_name;
02242   const char * string_section_name;
02243   unsigned string_offset;
02244 }
02245 stab_section_names;
02246 
02247 static void
02248 find_stabs_section (bfd *abfd, asection *section, void *names)
02249 {
02250   int len;
02251   stab_section_names * sought = (stab_section_names *) names;
02252 
02253   /* Check for section names for which stabsect_name is a prefix, to
02254      handle .stab.N, etc.  */
02255   len = strlen (sought->section_name);
02256 
02257   /* If the prefix matches, and the files section name ends with a
02258      nul or a digit, then we match.  I.e., we want either an exact
02259      match or a section followed by a number.  */
02260   if (strncmp (sought->section_name, section->name, len) == 0
02261       && (section->name[len] == 0
02262          || (section->name[len] == '.' && ISDIGIT (section->name[len + 1]))))
02263     {
02264       if (strtab == NULL)
02265        strtab = read_section_stabs (abfd, sought->string_section_name,
02266                                  &stabstr_size);
02267       
02268       if (strtab)
02269        {
02270          stabs = (bfd_byte *) read_section_stabs (abfd, section->name,
02271                                              &stab_size);
02272          if (stabs)
02273            print_section_stabs (abfd, section->name, &sought->string_offset);
02274        }
02275     }
02276 }
02277 
02278 static void
02279 dump_stabs_section (bfd *abfd, char *stabsect_name, char *strsect_name)
02280 {
02281   stab_section_names s;
02282 
02283   s.section_name = stabsect_name;
02284   s.string_section_name = strsect_name;
02285   s.string_offset = 0;
02286 
02287   bfd_map_over_sections (abfd, find_stabs_section, & s);
02288 
02289   free (strtab);
02290   strtab = NULL;
02291 }
02292 
02293 /* Dump the any sections containing stabs debugging information.  */
02294 
02295 static void
02296 dump_stabs (bfd *abfd)
02297 {
02298   dump_stabs_section (abfd, ".stab", ".stabstr");
02299   dump_stabs_section (abfd, ".stab.excl", ".stab.exclstr");
02300   dump_stabs_section (abfd, ".stab.index", ".stab.indexstr");
02301   dump_stabs_section (abfd, "$GDB_SYMBOLS$", "$GDB_STRINGS$");
02302 }
02303 
02304 static void
02305 dump_bfd_header (bfd *abfd)
02306 {
02307   char *comma = "";
02308 
02309   printf (_("architecture: %s, "),
02310          bfd_printable_arch_mach (bfd_get_arch (abfd),
02311                                bfd_get_mach (abfd)));
02312   printf (_("flags 0x%08x:\n"), abfd->flags);
02313 
02314 #define PF(x, y)    if (abfd->flags & x) {printf("%s%s", comma, y); comma=", ";}
02315   PF (HAS_RELOC, "HAS_RELOC");
02316   PF (EXEC_P, "EXEC_P");
02317   PF (HAS_LINENO, "HAS_LINENO");
02318   PF (HAS_DEBUG, "HAS_DEBUG");
02319   PF (HAS_SYMS, "HAS_SYMS");
02320   PF (HAS_LOCALS, "HAS_LOCALS");
02321   PF (DYNAMIC, "DYNAMIC");
02322   PF (WP_TEXT, "WP_TEXT");
02323   PF (D_PAGED, "D_PAGED");
02324   PF (BFD_IS_RELAXABLE, "BFD_IS_RELAXABLE");
02325   PF (HAS_LOAD_PAGE, "HAS_LOAD_PAGE");
02326   printf (_("\nstart address 0x"));
02327   bfd_printf_vma (abfd, abfd->start_address);
02328   printf ("\n");
02329 }
02330 
02331 
02332 static void
02333 dump_bfd_private_header (bfd *abfd)
02334 {
02335   bfd_print_private_bfd_data (abfd, stdout);
02336 }
02337 
02338 
02339 /* Display a section in hexadecimal format with associated characters.
02340    Each line prefixed by the zero padded address.  */
02341 
02342 static void
02343 dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED)
02344 {
02345   bfd_byte *data = 0;
02346   bfd_size_type datasize;
02347   bfd_size_type addr_offset;
02348   bfd_size_type start_offset;
02349   bfd_size_type stop_offset;
02350   unsigned int opb = bfd_octets_per_byte (abfd);
02351   /* Bytes per line.  */
02352   const int onaline = 16;
02353   char buf[64];
02354   int count;
02355   int width;
02356 
02357   if ((section->flags & SEC_HAS_CONTENTS) == 0)
02358     return;
02359 
02360   if (! process_section_p (section))
02361     return;
02362   
02363   if ((datasize = bfd_section_size (abfd, section)) == 0)
02364     return;
02365 
02366   printf (_("Contents of section %s:\n"), section->name);
02367 
02368   data = xmalloc (datasize);
02369 
02370   bfd_get_section_contents (abfd, section, data, 0, datasize);
02371 
02372   /* Compute the address range to display.  */
02373   if (start_address == (bfd_vma) -1
02374       || start_address < section->vma)
02375     start_offset = 0;
02376   else
02377     start_offset = start_address - section->vma;
02378 
02379   if (stop_address == (bfd_vma) -1)
02380     stop_offset = datasize / opb;
02381   else
02382     {
02383       if (stop_address < section->vma)
02384        stop_offset = 0;
02385       else
02386        stop_offset = stop_address - section->vma;
02387 
02388       if (stop_offset > datasize / opb)
02389        stop_offset = datasize / opb;
02390     }
02391 
02392   width = 4;
02393 
02394   bfd_sprintf_vma (abfd, buf, start_offset + section->vma);
02395   if (strlen (buf) >= sizeof (buf))
02396     abort ();
02397 
02398   count = 0;
02399   while (buf[count] == '0' && buf[count+1] != '\0')
02400     count++;
02401   count = strlen (buf) - count;
02402   if (count > width)
02403     width = count;
02404 
02405   bfd_sprintf_vma (abfd, buf, stop_offset + section->vma - 1);
02406   if (strlen (buf) >= sizeof (buf))
02407     abort ();
02408 
02409   count = 0;
02410   while (buf[count] == '0' && buf[count+1] != '\0')
02411     count++;
02412   count = strlen (buf) - count;
02413   if (count > width)
02414     width = count;
02415 
02416   for (addr_offset = start_offset;
02417        addr_offset < stop_offset; addr_offset += onaline / opb)
02418     {
02419       bfd_size_type j;
02420 
02421       bfd_sprintf_vma (abfd, buf, (addr_offset + section->vma));
02422       count = strlen (buf);
02423       if ((size_t) count >= sizeof (buf))
02424        abort ();
02425 
02426       putchar (' ');
02427       while (count < width)
02428        {
02429          putchar ('0');
02430          count++;
02431        }
02432       fputs (buf + count - width, stdout);
02433       putchar (' ');
02434 
02435       for (j = addr_offset * opb;
02436           j < addr_offset * opb + onaline; j++)
02437        {
02438          if (j < stop_offset * opb)
02439            printf ("%02x", (unsigned) (data[j]));
02440          else
02441            printf ("  ");
02442          if ((j & 3) == 3)
02443            printf (" ");
02444        }
02445 
02446       printf (" ");
02447       for (j = addr_offset * opb;
02448           j < addr_offset * opb + onaline; j++)
02449        {
02450          if (j >= stop_offset * opb)
02451            printf (" ");
02452          else
02453            printf ("%c", ISPRINT (data[j]) ? data[j] : '.');
02454        }
02455       putchar ('\n');
02456     }
02457   free (data);
02458 }
02459 
02460 /* Actually display the various requested regions.  */
02461 
02462 static void
02463 dump_data (bfd *abfd)
02464 {
02465   bfd_map_over_sections (abfd, dump_section, NULL);
02466 }
02467 
02468 /* Should perhaps share code and display with nm?  */
02469 
02470 static void
02471 dump_symbols (bfd *abfd ATTRIBUTE_UNUSED, bfd_boolean dynamic)
02472 {
02473   asymbol **current;
02474   long max;
02475   long count;
02476 
02477   if (dynamic)
02478     {
02479       current = dynsyms;
02480       max = dynsymcount;
02481       printf ("DYNAMIC SYMBOL TABLE:\n");
02482     }
02483   else
02484     {
02485       current = syms;
02486       max = symcount;
02487       printf ("SYMBOL TABLE:\n");
02488     }
02489 
02490   if (max == 0)
02491     printf (_("no symbols\n"));
02492 
02493   for (count = 0; count < max; count++)
02494     {
02495       bfd *cur_bfd;
02496 
02497       if (*current == NULL)
02498        printf (_("no information for symbol number %ld\n"), count);
02499 
02500       else if ((cur_bfd = bfd_asymbol_bfd (*current)) == NULL)
02501        printf (_("could not determine the type of symbol number %ld\n"),
02502               count);
02503 
02504       else if (process_section_p ((* current)->section)
02505               && (dump_special_syms
02506                  || !bfd_is_target_special_symbol (cur_bfd, *current)))
02507        {
02508          const char *name = (*current)->name;
02509 
02510          if (do_demangle && name != NULL && *name != '\0')
02511            {
02512              char *alloc;
02513 
02514              /* If we want to demangle the name, we demangle it
02515                here, and temporarily clobber it while calling
02516                bfd_print_symbol.  FIXME: This is a gross hack.  */
02517              alloc = demangle (cur_bfd, name);
02518              (*current)->name = alloc;
02519              bfd_print_symbol (cur_bfd, stdout, *current,
02520                             bfd_print_symbol_all);
02521              (*current)->name = name;
02522              free (alloc);
02523            }
02524          else
02525            bfd_print_symbol (cur_bfd, stdout, *current,
02526                            bfd_print_symbol_all);
02527          printf ("\n");
02528        }
02529 
02530       current++;
02531     }
02532   printf ("\n\n");
02533 }
02534 
02535 static void
02536 dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount)
02537 {
02538   arelent **p;
02539   char *last_filename, *last_functionname;
02540   unsigned int last_line;
02541 
02542   /* Get column headers lined up reasonably.  */
02543   {
02544     static int width;
02545 
02546     if (width == 0)
02547       {
02548        char buf[30];
02549 
02550        bfd_sprintf_vma (abfd, buf, (bfd_vma) -1);
02551        width = strlen (buf) - 7;
02552       }
02553     printf ("OFFSET %*s TYPE %*s VALUE \n", width, "", 12, "");
02554   }
02555 
02556   last_filename = NULL;
02557   last_functionname = NULL;
02558   last_line = 0;
02559 
02560   for (p = relpp; relcount && *p != NULL; p++, relcount--)
02561     {
02562       arelent *q = *p;
02563       const char *filename, *functionname;
02564       unsigned int line;
02565       const char *sym_name;
02566       const char *section_name;
02567 
02568       if (start_address != (bfd_vma) -1
02569          && q->address < start_address)
02570        continue;
02571       if (stop_address != (bfd_vma) -1
02572          && q->address > stop_address)
02573        continue;
02574 
02575       if (with_line_numbers
02576          && sec != NULL
02577          && bfd_find_nearest_line (abfd, sec, syms, q->address,
02578                                 &filename, &functionname, &line))
02579        {
02580          if (functionname != NULL
02581              && (last_functionname == NULL
02582                 || strcmp (functionname, last_functionname) != 0))
02583            {
02584              printf ("%s():\n", functionname);
02585              if (last_functionname != NULL)
02586               free (last_functionname);
02587              last_functionname = xstrdup (functionname);
02588            }
02589 
02590          if (line > 0
02591              && (line != last_line
02592                 || (filename != NULL
02593                     && last_filename != NULL
02594                     && strcmp (filename, last_filename) != 0)))
02595            {
02596              printf ("%s:%u\n", filename == NULL ? "???" : filename, line);
02597              last_line = line;
02598              if (last_filename != NULL)
02599               free (last_filename);
02600              if (filename == NULL)
02601               last_filename = NULL;
02602              else
02603               last_filename = xstrdup (filename);
02604            }
02605        }
02606 
02607       if (q->sym_ptr_ptr && *q->sym_ptr_ptr)
02608        {
02609          sym_name = (*(q->sym_ptr_ptr))->name;
02610          section_name = (*(q->sym_ptr_ptr))->section->name;
02611        }
02612       else
02613        {
02614          sym_name = NULL;
02615          section_name = NULL;
02616        }
02617 
02618       bfd_printf_vma (abfd, q->address);
02619       if (q->howto == NULL)
02620        printf (" *unknown*         ");
02621       else if (q->howto->name)
02622        printf (" %-16s  ", q->howto->name);
02623       else
02624        printf (" %-16d  ", q->howto->type);
02625       if (sym_name)
02626        objdump_print_symname (abfd, NULL, *q->sym_ptr_ptr);
02627       else
02628        {
02629          if (section_name == NULL)
02630            section_name = "*unknown*";
02631          printf ("[%s]", section_name);
02632        }
02633 
02634       if (q->addend)
02635        {
02636          printf ("+0x");
02637          bfd_printf_vma (abfd, q->addend);
02638        }
02639 
02640       printf ("\n");
02641     }
02642 }
02643 
02644 static void
02645 dump_relocs_in_section (bfd *abfd,
02646                      asection *section,
02647                      void *dummy ATTRIBUTE_UNUSED)
02648 {
02649   arelent **relpp;
02650   long relcount;
02651   long relsize;
02652 
02653   if (   bfd_is_abs_section (section)
02654       || bfd_is_und_section (section)
02655       || bfd_is_com_section (section)
02656       || (! process_section_p (section))
02657       || ((section->flags & SEC_RELOC) == 0))
02658     return;
02659 
02660   relsize = bfd_get_reloc_upper_bound (abfd, section);
02661   if (relsize < 0)
02662     bfd_fatal (bfd_get_filename (abfd));
02663 
02664   printf ("RELOCATION RECORDS FOR [%s]:", section->name);
02665 
02666   if (relsize == 0)
02667     {
02668       printf (" (none)\n\n");
02669       return;
02670     }
02671 
02672   relpp = xmalloc (relsize);
02673   relcount = bfd_canonicalize_reloc (abfd, section, relpp, syms);
02674 
02675   if (relcount < 0)
02676     bfd_fatal (bfd_get_filename (abfd));
02677   else if (relcount == 0)
02678     printf (" (none)\n\n");
02679   else
02680     {
02681       printf ("\n");
02682       dump_reloc_set (abfd, section, relpp, relcount);
02683       printf ("\n\n");
02684     }
02685   free (relpp);
02686 }
02687 
02688 static void
02689 dump_relocs (bfd *abfd)
02690 {
02691   bfd_map_over_sections (abfd, dump_relocs_in_section, NULL);
02692 }
02693 
02694 static void
02695 dump_dynamic_relocs (bfd *abfd)
02696 {
02697   long relsize;
02698   arelent **relpp;
02699   long relcount;
02700 
02701   relsize = bfd_get_dynamic_reloc_upper_bound (abfd);
02702   if (relsize < 0)
02703     bfd_fatal (bfd_get_filename (abfd));
02704 
02705   printf ("DYNAMIC RELOCATION RECORDS");
02706 
02707   if (relsize == 0)
02708     printf (" (none)\n\n");
02709   else
02710     {
02711       relpp = xmalloc (relsize);
02712       relcount = bfd_canonicalize_dynamic_reloc (abfd, relpp, dynsyms);
02713 
02714       if (relcount < 0)
02715        bfd_fatal (bfd_get_filename (abfd));
02716       else if (relcount == 0)
02717        printf (" (none)\n\n");
02718       else
02719        {
02720          printf ("\n");
02721          dump_reloc_set (abfd, NULL, relpp, relcount);
02722          printf ("\n\n");
02723        }
02724       free (relpp);
02725     }
02726 }
02727 
02728 /* Creates a table of paths, to search for source files.  */
02729 
02730 static void
02731 add_include_path (const char *path)
02732 {
02733   if (path[0] == 0)
02734     return;
02735   include_path_count++;
02736   include_paths = xrealloc (include_paths,
02737                          include_path_count * sizeof (*include_paths));
02738 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
02739   if (path[1] == ':' && path[2] == 0)
02740     path = concat (path, ".", (const char *) 0);
02741 #endif
02742   include_paths[include_path_count - 1] = path;
02743 }
02744 
02745 static void
02746 adjust_addresses (bfd *abfd ATTRIBUTE_UNUSED,
02747                 asection *section,
02748                 void *arg)
02749 {
02750   if ((section->flags & SEC_DEBUGGING) == 0)
02751     {
02752       bfd_boolean *has_reloc_p = (bfd_boolean *) arg;
02753       section->vma += adjust_section_vma;
02754       if (*has_reloc_p)
02755        section->lma += adjust_section_vma;
02756     }
02757 }
02758 
02759 /* Dump selected contents of ABFD.  */
02760 
02761 static void
02762 dump_bfd (bfd *abfd)
02763 {
02764   /* If we are adjusting section VMA's, change them all now.  Changing
02765      the BFD information is a hack.  However, we must do it, or
02766      bfd_find_nearest_line will not do the right thing.  */
02767   if (adjust_section_vma != 0)
02768     {
02769       bfd_boolean has_reloc = (abfd->flags & HAS_RELOC);
02770       bfd_map_over_sections (abfd, adjust_addresses, &has_reloc);
02771     }
02772 
02773   if (! dump_debugging_tags)
02774     printf (_("\n%s:     file format %s\n"), bfd_get_filename (abfd),
02775            abfd->xvec->name);
02776   if (dump_ar_hdrs)
02777     print_arelt_descr (stdout, abfd, TRUE);
02778   if (dump_file_header)
02779     dump_bfd_header (abfd);
02780   if (dump_private_headers)
02781     dump_bfd_private_header (abfd);
02782   if (! dump_debugging_tags)
02783     putchar ('\n');
02784   if (dump_section_headers)
02785     dump_headers (abfd);
02786 
02787   if (dump_symtab
02788       || dump_reloc_info
02789       || disassemble
02790       || dump_debugging
02791       || dump_dwarf_section_info)
02792     syms = slurp_symtab (abfd);
02793   if (dump_dynamic_symtab || dump_dynamic_reloc_info
02794       || (disassemble && bfd_get_dynamic_symtab_upper_bound (abfd) > 0))
02795     dynsyms = slurp_dynamic_symtab (abfd);
02796   if (disassemble)
02797     {
02798       synthcount = bfd_get_synthetic_symtab (abfd, symcount, syms,
02799                                         dynsymcount, dynsyms, &synthsyms);
02800       if (synthcount < 0)
02801        synthcount = 0;
02802     }
02803 
02804   if (dump_symtab)
02805     dump_symbols (abfd, FALSE);
02806   if (dump_dynamic_symtab)
02807     dump_symbols (abfd, TRUE);
02808   if (dump_dwarf_section_info)
02809     dump_dwarf (abfd);
02810   if (dump_stab_section_info)
02811     dump_stabs (abfd);
02812   if (dump_reloc_info && ! disassemble)
02813     dump_relocs (abfd);
02814   if (dump_dynamic_reloc_info && ! disassemble)
02815     dump_dynamic_relocs (abfd);
02816   if (dump_section_contents)
02817     dump_data (abfd);
02818   if (disassemble)
02819     disassemble_data (abfd);
02820 
02821   if (dump_debugging)
02822     {
02823       void *dhandle;
02824 
02825       dhandle = read_debugging_info (abfd, syms, symcount);
02826       if (dhandle != NULL)
02827        {
02828          if (! print_debugging_info (stdout, dhandle, abfd, syms, demangle,
02829              dump_debugging_tags ? TRUE : FALSE))
02830            {
02831              non_fatal (_("%s: printing debugging information failed"),
02832                       bfd_get_filename (abfd));
02833              exit_status = 1;
02834            }
02835        }
02836     }
02837 
02838   if (syms)
02839     {
02840       free (syms);
02841       syms = NULL;
02842     }
02843 
02844   if (dynsyms)
02845     {
02846       free (dynsyms);
02847       dynsyms = NULL;
02848     }
02849 
02850   if (synthsyms)
02851     {
02852       free (synthsyms);
02853       synthsyms = NULL;
02854     }
02855 
02856   symcount = 0;
02857   dynsymcount = 0;
02858   synthcount = 0;
02859 }
02860 
02861 static void
02862 display_bfd (bfd *abfd)
02863 {
02864   char **matching;
02865 
02866   if (bfd_check_format_matches (abfd, bfd_object, &matching))
02867     {
02868       dump_bfd (abfd);
02869       return;
02870     }
02871 
02872   if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
02873     {
02874       nonfatal (bfd_get_filename (abfd));
02875       list_matching_formats (matching);
02876       free (matching);
02877       return;
02878     }
02879 
02880   if (bfd_get_error () != bfd_error_file_not_recognized)
02881     {
02882       nonfatal (bfd_get_filename (abfd));
02883       return;
02884     }
02885 
02886   if (bfd_check_format_matches (abfd, bfd_core, &matching))
02887     {
02888       dump_bfd (abfd);
02889       return;
02890     }
02891 
02892   nonfatal (bfd_get_filename (abfd));
02893 
02894   if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
02895     {
02896       list_matching_formats (matching);
02897       free (matching);
02898     }
02899 }
02900 
02901 static void
02902 display_file (char *filename, char *target)
02903 {
02904   bfd *file;
02905   bfd *arfile = NULL;
02906 
02907   if (get_file_size (filename) < 1)
02908     {
02909       exit_status = 1;
02910       return;
02911     }
02912 
02913   file = bfd_openr (filename, target);
02914   if (file == NULL)
02915     {
02916       nonfatal (filename);
02917       return;
02918     }
02919 
02920   /* If the file is an archive, process all of its elements.  */
02921   if (bfd_check_format (file, bfd_archive))
02922     {
02923       bfd *last_arfile = NULL;
02924 
02925       printf (_("In archive %s:\n"), bfd_get_filename (file));
02926       for (;;)
02927        {
02928          bfd_set_error (bfd_error_no_error);
02929 
02930          arfile = bfd_openr_next_archived_file (file, arfile);
02931          if (arfile == NULL)
02932            {
02933              if (bfd_get_error () != bfd_error_no_more_archived_files)
02934               nonfatal (bfd_get_filename (file));
02935              break;
02936            }
02937 
02938          display_bfd (arfile);
02939 
02940          if (last_arfile != NULL)
02941            bfd_close (last_arfile);
02942          last_arfile = arfile;
02943        }
02944 
02945       if (last_arfile != NULL)
02946        bfd_close (last_arfile);
02947     }
02948   else
02949     display_bfd (file);
02950 
02951   bfd_close (file);
02952 }
02953 
02954 int
02955 main (int argc, char **argv)
02956 {
02957   int c;
02958   char *target = default_target;
02959   bfd_boolean seenflag = FALSE;
02960 
02961 #if defined (HAVE_SETLOCALE)
02962 #if defined (HAVE_LC_MESSAGES)
02963   setlocale (LC_MESSAGES, "");
02964 #endif
02965   setlocale (LC_CTYPE, "");
02966 #endif
02967 
02968   bindtextdomain (PACKAGE, LOCALEDIR);
02969   textdomain (PACKAGE);
02970 
02971   program_name = *argv;
02972   xmalloc_set_program_name (program_name);
02973 
02974   START_PROGRESS (program_name, 0);
02975 
02976   expandargv (&argc, &argv);
02977 
02978   bfd_init ();
02979   set_default_bfd_target ();
02980 
02981   while ((c = getopt_long (argc, argv, "pib:m:M:VvCdDlfaHhrRtTxsSI:j:wE:zgeGW",
02982                         long_options, (int *) 0))
02983         != EOF)
02984     {
02985       switch (c)
02986        {
02987        case 0:
02988          break;             /* We've been given a long option.  */
02989        case 'm':
02990          machine = optarg;
02991          break;
02992        case 'M':
02993          if (disassembler_options)
02994            /* Ignore potential memory leak for now.  */
02995            disassembler_options = concat (disassembler_options, ",",
02996                                       optarg, NULL);
02997          else
02998            disassembler_options = optarg;
02999          break;
03000        case 'j':
03001          if (only_used == only_size)
03002            {
03003              only_size += 8;
03004              only = xrealloc (only, only_size * sizeof (char *));
03005            }
03006          only [only_used++] = optarg;
03007          break;
03008        case 'l':
03009          with_line_numbers = TRUE;
03010          break;
03011        case 'b':
03012          target = optarg;
03013          break;
03014        case 'C':
03015          do_demangle = TRUE;
03016          if (optarg != NULL)
03017            {
03018              enum demangling_styles style;
03019 
03020              style = cplus_demangle_name_to_style (optarg);
03021              if (style == unknown_demangling)
03022               fatal (_("unknown demangling style `%s'"),
03023                      optarg);
03024 
03025              cplus_demangle_set_style (style);
03026            }
03027          break;
03028        case 'w':
03029          wide_output = TRUE;
03030          break;
03031        case OPTION_ADJUST_VMA:
03032          adjust_section_vma = parse_vma (optarg, "--adjust-vma");
03033          break;
03034        case OPTION_START_ADDRESS:
03035          start_address = parse_vma (optarg, "--start-address");
03036          break;
03037        case OPTION_STOP_ADDRESS:
03038          stop_address = parse_vma (optarg, "--stop-address");
03039          break;
03040        case 'E':
03041          if (strcmp (optarg, "B") == 0)
03042            endian = BFD_ENDIAN_BIG;
03043          else if (strcmp (optarg, "L") == 0)
03044            endian = BFD_ENDIAN_LITTLE;
03045          else
03046            {
03047              non_fatal (_("unrecognized -E option"));
03048              usage (stderr, 1);
03049            }
03050          break;
03051        case OPTION_ENDIAN:
03052          if (strncmp (optarg, "big", strlen (optarg)) == 0)
03053            endian = BFD_ENDIAN_BIG;
03054          else if (strncmp (optarg, "little", strlen (optarg)) == 0)
03055            endian = BFD_ENDIAN_LITTLE;
03056          else
03057            {
03058              non_fatal (_("unrecognized --endian type `%s'"), optarg);
03059              usage (stderr, 1);
03060            }
03061          break;
03062 
03063        case 'f':
03064          dump_file_header = TRUE;
03065          seenflag = TRUE;
03066          break;
03067        case 'i':
03068          formats_info = TRUE;
03069          seenflag = TRUE;
03070          break;
03071        case 'I':
03072          add_include_path (optarg);
03073          break;
03074        case 'p':
03075          dump_private_headers = TRUE;
03076          seenflag = TRUE;
03077          break;
03078        case 'x':
03079          dump_private_headers = TRUE;
03080          dump_symtab = TRUE;
03081          dump_reloc_info = TRUE;
03082          dump_file_header = TRUE;
03083          dump_ar_hdrs = TRUE;
03084          dump_section_headers = TRUE;
03085          seenflag = TRUE;
03086          break;
03087        case 't':
03088          dump_symtab = TRUE;
03089          seenflag = TRUE;
03090          break;
03091        case 'T':
03092          dump_dynamic_symtab = TRUE;
03093          seenflag = TRUE;
03094          break;
03095        case 'd':
03096          disassemble = TRUE;
03097          seenflag = TRUE;
03098          break;
03099        case 'z':
03100          disassemble_zeroes = TRUE;
03101          break;
03102        case 'D':
03103          disassemble = TRUE;
03104          disassemble_all = TRUE;
03105          seenflag = TRUE;
03106          break;
03107        case 'S':
03108          disassemble = TRUE;
03109          with_source_code = TRUE;
03110          seenflag = TRUE;
03111          break;
03112        case 'g':
03113          dump_debugging = 1;
03114          seenflag = TRUE;
03115          break;
03116        case 'e':
03117          dump_debugging = 1;
03118          dump_debugging_tags = 1;
03119          do_demangle = TRUE;
03120          seenflag = TRUE;
03121          break;
03122        case 'W':
03123          dump_dwarf_section_info = TRUE;
03124          seenflag = TRUE;
03125          do_debug_info = 1;
03126          do_debug_abbrevs = 1;
03127          do_debug_lines = 1;
03128          do_debug_pubnames = 1;
03129          do_debug_aranges = 1;
03130          do_debug_ranges = 1;
03131          do_debug_frames = 1;
03132          do_debug_macinfo = 1;
03133          do_debug_str = 1;
03134          do_debug_loc = 1;
03135          break;
03136        case 'G':
03137          dump_stab_section_info = TRUE;
03138          seenflag = TRUE;
03139          break;
03140        case 's':
03141          dump_section_contents = TRUE;
03142          seenflag = TRUE;
03143          break;
03144        case 'r':
03145          dump_reloc_info = TRUE;
03146          seenflag = TRUE;
03147          break;
03148        case 'R':
03149          dump_dynamic_reloc_info = TRUE;
03150          seenflag = TRUE;
03151          break;
03152        case 'a':
03153          dump_ar_hdrs = TRUE;
03154          seenflag = TRUE;
03155          break;
03156        case 'h':
03157          dump_section_headers = TRUE;
03158          seenflag = TRUE;
03159          break;
03160        case 'H':
03161          usage (stdout, 0);
03162          seenflag = TRUE;
03163        case 'v':
03164        case 'V':
03165          show_version = TRUE;
03166          seenflag = TRUE;
03167          break;
03168 
03169        default:
03170          usage (stderr, 1);
03171        }
03172     }
03173 
03174   if (show_version)
03175     print_version ("objdump");
03176 
03177   if (!seenflag)
03178     usage (stderr, 2);
03179 
03180   if (formats_info)
03181     exit_status = display_info ();
03182   else
03183     {
03184       if (optind == argc)
03185        display_file ("a.out", target);
03186       else
03187        for (; optind < argc;)
03188          display_file (argv[optind++], target);
03189     }
03190 
03191   END_PROGRESS (program_name);
03192 
03193   return exit_status;
03194 }