home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / gnu / djgpp / src / binutils.2 / binutils / objdump.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-30  |  27.5 KB  |  1,147 lines

  1. /* objdump.c -- dump information about an object file.
  2.    Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
  3.  
  4. This file is part of BFD, the Binary File Diddler.
  5.  
  6. BFD is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. BFD is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with BFD; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /*
  21.  * Until there is other documentation, refer to the manual page dump(1) in
  22.  * the system 5 program's reference manual
  23.  */
  24.  
  25. #include "bfd.h"
  26. #include "sysdep.h"
  27. #include "getopt.h"
  28. #include <stdio.h>
  29. #include <ctype.h>
  30. #include "dis-asm.h"
  31.  
  32. #define    ELF_STAB_DISPLAY    /* This code works, but uses internal
  33.                    bfd and elf stuff.  Flip this define
  34.                    off if you need to just use generic
  35.                    BFD interfaces.  */
  36.  
  37. #ifdef    ELF_STAB_DISPLAY
  38. /* Internal headers for the ELF .stab-dump code - sorry.  */
  39. #define    BYTES_IN_WORD    32
  40. #include "aout/aout64.h"
  41. #include "elf/internal.h"
  42. extern Elf_Internal_Shdr *bfd_elf_find_section();
  43. #endif    /* ELF_STAB_DISPLAY */
  44.  
  45. extern char *xmalloc ();
  46. extern int fprintf PARAMS ((FILE *, CONST char *, ...));
  47.  
  48. char *default_target = NULL;    /* default at runtime */
  49.  
  50. extern *program_version;
  51. char *program_name = NULL;
  52.  
  53. int show_version = 0;        /* show the version number */
  54. int dump_section_contents;    /* -s */
  55. int dump_section_headers;    /* -h */
  56. boolean dump_file_header;    /* -f */
  57. int dump_symtab;        /* -t */
  58. int dump_reloc_info;        /* -r */
  59. int dump_ar_hdrs;        /* -a */
  60. int with_line_numbers;        /* -l */
  61. int dump_stab_section_info;    /* -stabs */
  62. boolean disassemble;        /* -d */
  63. boolean info;            /* -i */
  64. char *only;
  65.  
  66. char *machine = (char *) NULL;
  67. asymbol **syms;
  68. asymbol **syms2;
  69.  
  70. unsigned int storage;
  71.  
  72. unsigned int symcount = 0;
  73.  
  74. /* Forward declarations.  */
  75.  
  76. static void
  77. display_file PARAMS ((char *filename, char *target));
  78.  
  79. static void
  80. dump_data PARAMS ((bfd *abfd));
  81.  
  82. static void
  83. dump_relocs PARAMS ((bfd *abfd));
  84.  
  85. static void
  86. dump_symbols PARAMS ((bfd *abfd));
  87.  
  88. void
  89. usage ()
  90. {
  91.   fprintf (stderr, "\
  92. Usage: %s [-ahifdrtxsl] [-m machine] [-j section_name] [-b bfdname]\n\
  93.        [--syms] [--reloc] [--header] [--version] objfile...\n", program_name);
  94.   exit (1);
  95. }
  96.  
  97. static struct option long_options[]=
  98. {
  99.   {"syms", no_argument, &dump_symtab, 1},
  100.   {"reloc", no_argument, &dump_reloc_info, 1},
  101.   {"header", no_argument, &dump_section_headers, 1},
  102.   {"version", no_argument, &show_version,    1},
  103. #ifdef    ELF_STAB_DISPLAY
  104.   {"stabs", no_argument, &dump_stab_section_info, 1},
  105. #endif
  106.   {0, no_argument, 0, 0}
  107. };
  108.  
  109.  
  110. static void
  111. dump_headers (abfd)
  112.      bfd *abfd;
  113. {
  114.   asection *section;
  115.  
  116.   for (section = abfd->sections;
  117.        section != (asection *) NULL;
  118.        section = section->next)
  119.     {
  120.       char *comma = "";
  121.  
  122. #define PF(x,y) \
  123.     if (section->flags & x) {  printf("%s%s",comma,y); comma = ", "; }
  124.  
  125.  
  126.       printf ("SECTION %d [%s]\t: size %08x",
  127.           section->index,
  128.           section->name,
  129.           (unsigned) bfd_get_section_size_before_reloc (section));
  130.       printf (" vma ");
  131.       printf_vma (section->vma);
  132.       printf (" align 2**%u\n ",
  133.           section->alignment_power);
  134.       PF (SEC_ALLOC, "ALLOC");
  135.       PF (SEC_CONSTRUCTOR, "CONSTRUCTOR");
  136.       PF (SEC_CONSTRUCTOR_TEXT, "CONSTRUCTOR TEXT");
  137.       PF (SEC_CONSTRUCTOR_DATA, "CONSTRUCTOR DATA");
  138.       PF (SEC_CONSTRUCTOR_BSS, "CONSTRUCTOR BSS");
  139.       PF (SEC_LOAD, "LOAD");
  140.       PF (SEC_RELOC, "RELOC");
  141.       PF (SEC_BALIGN, "BALIGN");
  142.       PF (SEC_READONLY, "READONLY");
  143.       PF (SEC_CODE, "CODE");
  144.       PF (SEC_DATA, "DATA");
  145.       PF (SEC_ROM, "ROM");
  146.       printf ("\n");
  147. #undef PF
  148.     }
  149. }
  150.  
  151. static asymbol **
  152. DEFUN (slurp_symtab, (abfd),
  153.        bfd * abfd)
  154. {
  155.   asymbol **sy = (asymbol **) NULL;
  156.  
  157.   if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
  158.     {
  159.       (void) printf ("No symbols in \"%s\".\n", bfd_get_filename (abfd));
  160.       return (NULL);
  161.     }
  162.  
  163.   storage = get_symtab_upper_bound (abfd);
  164.   if (storage)
  165.     {
  166.       sy = (asymbol **) malloc (storage);
  167.       if (sy == NULL)
  168.     {
  169.       fprintf (stderr, "%s: out of memory.\n", program_name);
  170.       exit (1);
  171.     }
  172.     }
  173.   symcount = bfd_canonicalize_symtab (abfd, sy);
  174.   return sy;
  175. }
  176.  
  177. /* Sort symbols into value order */
  178. static int 
  179. comp (ap, bp)
  180.      PTR ap;
  181.      PTR bp;
  182. {
  183.   asymbol *a = *(asymbol **)ap;
  184.   asymbol *b = *(asymbol **)bp;
  185.   int diff;
  186.   bfd *a_bfd, *b_bfd;
  187.  
  188.   if (a->name == (char *) NULL || (a->flags & (BSF_DEBUGGING)))
  189.     a_bfd = 0;
  190.   else
  191.     a_bfd = bfd_asymbol_bfd(a);
  192.   if (b->name == (char *) NULL || (b->flags & (BSF_DEBUGGING)))
  193.     b_bfd = 0;
  194.   else
  195.     b_bfd = bfd_asymbol_bfd(b);
  196.  
  197.   diff = a_bfd - b_bfd;
  198.   if (diff)
  199.     {
  200.       return -diff;
  201.     }
  202.   diff = a->value - b->value;
  203.   if (diff)
  204.     {
  205.       return diff;
  206.     }
  207.   return a->section - b->section;
  208. }
  209.  
  210. /* Print the supplied address symbolically if possible */
  211. void
  212. objdump_print_address (vma, info)
  213.      bfd_vma vma;
  214.      struct disassemble_info *info;
  215. {
  216.   /* Perform a binary search looking for the closest symbol to
  217.      the required value */
  218.  
  219.   unsigned int min = 0;
  220.   unsigned int max = symcount;
  221.  
  222.   unsigned int thisplace = 1;
  223.   unsigned int oldthisplace;
  224.  
  225.   int vardiff;
  226.  
  227.   if (symcount == 0)
  228.     {
  229.       fprintf_vma (info->stream, vma);
  230.     }
  231.   else
  232.     {
  233.       while (true)
  234.     {
  235.       oldthisplace = thisplace;
  236.       thisplace = (max + min) / 2;
  237.       if (thisplace == oldthisplace)
  238.         break;
  239.       vardiff = syms[thisplace]->value - vma;
  240.  
  241.       if (vardiff
  242.           /* Check that the value isn't merely a coincidence.
  243.              (if not checked, we might print some undefined symbol
  244.          for the address 0 rather than "main", for example.  */
  245.           || !(syms[thisplace]->flags & (BSF_GLOBAL|BSF_LOCAL)))
  246.         {
  247.           if (vardiff > 0)
  248.         {
  249.           max = thisplace;
  250.         }
  251.           else
  252.         {
  253.           min = thisplace;
  254.         }
  255.         }
  256.       else
  257.         {
  258.           /* Totally awesome! the exact right symbol */
  259.           CONST char *match_name = syms[thisplace]->name;
  260.           int sym_len = strlen (match_name);
  261.  
  262.           /* Avoid "filename.o" as a match */
  263.           if (sym_len > 2
  264.           && match_name[sym_len - 2] == '.'
  265.           && match_name[sym_len - 1] == 'o'
  266.           && thisplace + 1 < symcount
  267.           && syms[thisplace + 1]->value == vma)
  268.         match_name = syms[thisplace + 1]->name;
  269.           /* Totally awesome! the exact right symbol */
  270.           fprintf_vma (info->stream, vma);
  271.           fprintf (info->stream, " (%s+)0000", syms[thisplace]->name);
  272.           return;
  273.         }
  274.     }
  275.       /* We've run out of places to look, print the symbol before this one
  276.          see if this or the symbol before describes this location the best */
  277.  
  278.       if (thisplace != 0)
  279.     {
  280.       if (syms[thisplace - 1]->value - vma >
  281.           syms[thisplace]->value - vma)
  282.         {
  283.           /* Previous symbol is in correct section and is closer */
  284.           thisplace--;
  285.         }
  286.     }
  287.  
  288.       fprintf_vma (info->stream, vma);
  289.       if (syms[thisplace]->value > vma)
  290.     {
  291.       fprintf (info->stream, " (%s-)", syms[thisplace]->name);
  292.       fprintf (info->stream, "%04x", syms[thisplace]->value - vma);
  293.     }
  294.       else
  295.     {
  296.       fprintf (info->stream, " (%s+)", syms[thisplace]->name);
  297.       fprintf (info->stream, "%04x", vma - syms[thisplace]->value);
  298.     }
  299.     }
  300. }
  301.  
  302. void
  303. disassemble_data (abfd)
  304.      bfd *abfd;
  305. {
  306.   bfd_byte *data = NULL;
  307.   bfd_arch_info_type *info;
  308.   bfd_size_type datasize = 0;
  309.   bfd_size_type i;
  310.   unsigned int (*print) ()= 0; /* Old style */
  311.   disassembler_ftype disassemble = 0; /* New style */
  312.   unsigned int print_insn_h8300 ();
  313.   enum bfd_architecture a;
  314.   struct disassemble_info disasm_info;
  315.  
  316.   int prevline;
  317.   CONST char *prev_function = "";
  318.  
  319.   asection *section;
  320.  
  321.   /* Replace symbol section relative values with abs values */
  322.   boolean done_dot = false;
  323.  
  324.   INIT_DISASSEMBLE_INFO(disasm_info, stdout);
  325.   disasm_info.print_address_func = objdump_print_address;
  326.  
  327.   for (i = 0; i < symcount; i++)
  328.     {
  329.       syms[i]->value += syms[i]->section->vma;
  330.     }
  331.  
  332.   /* We keep a copy of the symbols in the original order */
  333.   syms2 = slurp_symtab (abfd);
  334.  
  335.   /* Sort the symbols into section and symbol order */
  336.   (void) qsort (syms, symcount, sizeof (asymbol *), comp);
  337.  
  338.   /* Find the first useless symbol */
  339.   {
  340.     unsigned int i;
  341.  
  342.     for (i = 0; i < symcount; i++)
  343.       {
  344.     if (syms[i]->name == (char *) NULL
  345.         || (syms[i]->flags & BSF_DEBUGGING) != 0)
  346.       {
  347.         symcount = i;
  348.         break;
  349.       }
  350.       }
  351.   }
  352.  
  353.  
  354.   if (machine != (char *) NULL)
  355.     {
  356.       info = bfd_scan_arch (machine);
  357.       if (info == 0)
  358.     {
  359.       fprintf (stderr, "%s: Can't use supplied machine %s\n",
  360.            program_name,
  361.            machine);
  362.       exit (1);
  363.     }
  364.       abfd->arch_info = info;
  365.     }
  366.  
  367.   /* See if we can disassemble using bfd */
  368.  
  369.   if (abfd->arch_info->disassemble)
  370.     {
  371.       print = abfd->arch_info->disassemble;
  372.     }
  373.   else
  374.     {
  375.       a = bfd_get_arch (abfd);
  376.       switch (a)
  377.     {
  378.     case bfd_arch_sparc:
  379.       disassemble = print_insn_sparc;
  380.       break;
  381.         case bfd_arch_z8k:
  382.       if (bfd_get_mach(abfd) == bfd_mach_z8001)
  383.        disassemble = print_insn_z8001;
  384.       else 
  385.        disassemble = print_insn_z8002;
  386.       break;
  387.     case bfd_arch_i386:
  388.       disassemble = print_insn_i386;
  389.       break;
  390.     case bfd_arch_h8500:
  391.       disassemble = print_insn_h8500;
  392.       break;
  393.     case bfd_arch_sh:
  394.       disassemble = print_insn_sh;
  395.       break;
  396.     case bfd_arch_alpha:
  397.       disassemble = print_insn_alpha;
  398.       break;
  399.     case bfd_arch_m68k:
  400.       disassemble = print_insn_m68k;
  401.       break;
  402.     case bfd_arch_a29k:
  403.       /* As far as I know we only handle big-endian 29k objects.  */
  404.       disassemble = print_insn_big_a29k;
  405.       break;
  406.     case bfd_arch_i960:
  407.       disassemble = print_insn_i960;
  408.       break;
  409.     case bfd_arch_mips:
  410.       if (abfd->xvec->byteorder_big_p)
  411.         disassemble = print_insn_big_mips;
  412.       else
  413.         disassemble = print_insn_little_mips;
  414.       break;
  415.     default:
  416.       fprintf (stderr, "%s: Can't disassemble for architecture %s\n",
  417.            program_name,
  418.            bfd_printable_arch_mach (bfd_get_arch (abfd), 0));
  419.       exit (1);
  420.     }
  421.  
  422.     }
  423.  
  424.   for (section = abfd->sections;
  425.        section != (asection *) NULL;
  426.        section = section->next)
  427.     {
  428.  
  429.       if ((section->flags & SEC_LOAD)
  430.       && (only == (char *) NULL || strcmp (only, section->name) == 0))
  431.     {
  432.       printf ("Disassembly of section %s:\n", section->name);
  433.  
  434.       if (bfd_get_section_size_before_reloc (section) == 0)
  435.         continue;
  436.  
  437.       data = (bfd_byte *) malloc (bfd_get_section_size_before_reloc (section));
  438.  
  439.       if (data == (bfd_byte *) NULL)
  440.         {
  441.           fprintf (stderr, "%s: memory exhausted.\n", program_name);
  442.           exit (1);
  443.         }
  444.       datasize = bfd_get_section_size_before_reloc (section);
  445.  
  446.       bfd_get_section_contents (abfd, section, data, 0, bfd_get_section_size_before_reloc (section));
  447.  
  448.       disasm_info.buffer = data;
  449.       disasm_info.buffer_vma = section->vma;
  450.       disasm_info.buffer_length =
  451.         bfd_get_section_size_before_reloc (section);
  452.       i = 0;
  453.       while (i < disasm_info.buffer_length)
  454.         {
  455.           if (data[i] == 0 && data[i + 1] == 0 && data[i + 2] == 0 &&
  456.           data[i + 3] == 0)
  457.         {
  458.           if (done_dot == false)
  459.             {
  460.               printf ("...\n");
  461.               done_dot = true;
  462.             }
  463.           i += 4;
  464.         }
  465.           else
  466.         {
  467.           done_dot = false;
  468.           if (with_line_numbers)
  469.             {
  470.               CONST char *filename;
  471.               CONST char *functionname;
  472.               unsigned int line;
  473.  
  474.               if (bfd_find_nearest_line (abfd,
  475.                          section,
  476.                          syms,
  477.                          section->vma + i,
  478.                          &filename,
  479.                          &functionname,
  480.                          &line))
  481.             {
  482.               if (functionname && *functionname
  483.                   && strcmp(functionname, prev_function))
  484.                 {
  485.                   printf ("%s():\n", functionname);
  486.                   prev_function = functionname;
  487.                 }
  488.               if (!filename)
  489.                 filename = "???";
  490.               if (line && line != prevline)
  491.                 {
  492.                   printf ("%s:%u\n", filename, line);
  493.                   prevline = line;
  494.                 }
  495.             }
  496.             }
  497.           objdump_print_address (section->vma + i, &disasm_info);
  498.           printf (" ");
  499.  
  500.           if (disassemble) /* New style */
  501.             {
  502.               int bytes = (*disassemble)(section->vma + i,
  503.                          &disasm_info);
  504.               if (bytes < 0)
  505.             break;
  506.               i += bytes;
  507.             }
  508.           else /* Old style */
  509.             i += print (section->vma + i,
  510.                 data + i,
  511.                 stdout);
  512.           putchar ('\n');
  513.         }
  514.         }
  515.       free (data);
  516.     }
  517.     }
  518. }
  519.  
  520. #ifdef    ELF_STAB_DISPLAY
  521.  
  522. /* Define a table of stab values and print-strings.  We wish the initializer
  523.    could be a direct-mapped table, but instead we build one the first
  524.    time we need it.  */
  525.  
  526. #define    STAB_STRING_LENGTH    6
  527.  
  528. char stab_name[256][STAB_STRING_LENGTH];
  529.  
  530. struct stab_print {
  531.   int value;
  532.   char string[STAB_STRING_LENGTH];
  533. };
  534.  
  535. struct stab_print stab_print[] = {
  536. #define __define_stab(NAME, CODE, STRING) {CODE, STRING},
  537. #include "aout/stab.def"
  538. #undef __define_stab
  539.   {0, 0}
  540. };
  541.  
  542. void dump_elf_stabs_1 ();
  543.  
  544. /* This is a kludge for dumping the stabs section from an ELF file that
  545.    uses Sun stabs encoding.  It has to use some hooks into BFD because
  546.    string table sections are not normally visible to BFD callers.  */
  547.  
  548. void
  549. dump_elf_stabs (abfd)
  550.      bfd *abfd;
  551. {
  552.   int i;
  553.  
  554.   /* Initialize stab name array if first time.  */
  555.   if (stab_name[0][0] == 0) 
  556.     {
  557.       /* Fill in numeric values for all possible strings.  */
  558.       for (i = 0; i < 256; i++)
  559.     {
  560.       sprintf (stab_name[i], "%d", i);
  561.     }
  562.       for (i = 0; stab_print[i].string[0]; i++)
  563.     strcpy (stab_name[stab_print[i].value], stab_print[i].string);
  564.     }
  565.  
  566.   if (0 != strncmp ("elf", abfd->xvec->name, 3))
  567.     {
  568.       fprintf (stderr, "%s: %s is not in ELF format.\n", program_name,
  569.            abfd->filename);
  570.       return;
  571.     }
  572.  
  573.   dump_elf_stabs_1 (abfd, ".stab", ".stabstr");
  574.   dump_elf_stabs_1 (abfd, ".stab.excl", ".stab.exclstr");
  575.   dump_elf_stabs_1 (abfd, ".stab.index", ".stab.indexstr");
  576. }
  577.  
  578. void
  579. dump_elf_stabs_1 (abfd, name1, name2)
  580.      bfd *abfd;
  581.      char *name1;        /* Section name of .stab */
  582.      char *name2;        /* Section name of its string section */
  583. {
  584.   Elf_Internal_Shdr *stab_hdr, *stabstr_hdr;
  585.   char *strtab;
  586.   struct internal_nlist *stabs, *stabs_end;
  587.   int i;
  588.   unsigned file_string_table_offset, next_file_string_table_offset;
  589.  
  590.   stab_hdr = bfd_elf_find_section (abfd, name1);
  591.   if (0 == stab_hdr)
  592.     {
  593.       printf ("Contents of %s section:  none.\n\n", name1);
  594.       return;
  595.     }
  596.  
  597.   stabstr_hdr = bfd_elf_find_section (abfd, name2);
  598.   if (0 == stabstr_hdr)
  599.     {
  600.       fprintf (stderr, "%s: %s has no %s section.\n", program_name,
  601.            abfd->filename, name2);
  602.       return;
  603.     }
  604.  
  605.   stabs  = (struct internal_nlist *) xmalloc (stab_hdr   ->sh_size);
  606.   strtab = (char *)             xmalloc (stabstr_hdr->sh_size);
  607.   stabs_end = (struct internal_nlist *) (stab_hdr->sh_size + (char *)stabs);
  608.   
  609.   if (bfd_seek (abfd, stab_hdr->sh_offset, SEEK_SET) < 0 ||
  610.       stab_hdr->sh_size != bfd_read ((PTR)stabs, stab_hdr->sh_size, 1, abfd))
  611.     {
  612.       fprintf (stderr, "%s: reading %s section of %s failed.\n",
  613.            program_name, name1, 
  614.            abfd->filename);
  615.       return;
  616.     }
  617.  
  618.   if (bfd_seek (abfd, stabstr_hdr->sh_offset, SEEK_SET) < 0 ||
  619.       stabstr_hdr->sh_size != bfd_read ((PTR)strtab, stabstr_hdr->sh_size,
  620.                     1, abfd))
  621.     {
  622.       fprintf (stderr, "%s: reading %s section of %s failed.\n",
  623.            program_name, name2,
  624.            abfd->filename);
  625.       return;
  626.     }
  627.  
  628. #define SWAP_SYMBOL(symp, abfd) \
  629.   { \
  630.     (symp)->n_strx = bfd_h_get_32(abfd,            \
  631.                 (unsigned char *)&(symp)->n_strx);    \
  632.     (symp)->n_desc = bfd_h_get_16 (abfd,            \
  633.                 (unsigned char *)&(symp)->n_desc);      \
  634.     (symp)->n_value = bfd_h_get_32 (abfd,            \
  635.                 (unsigned char *)&(symp)->n_value);     \
  636.   }
  637.  
  638.   printf ("Contents of %s section:\n\n", name1);
  639.   printf ("Symnum n_type n_othr n_desc n_value  n_strx String\n");
  640.  
  641.   file_string_table_offset = 0;
  642.   next_file_string_table_offset = 0;
  643.  
  644.   /* Loop through all symbols and print them.
  645.  
  646.      We start the index at -1 because there is a dummy symbol on
  647.      the front of Sun's stabs-in-elf sections.  */
  648.  
  649.   for (i = -1; stabs < stabs_end; stabs++, i++)
  650.     {
  651.       SWAP_SYMBOL (stabs, abfd);
  652.       printf ("\n%-6d %-6s %-6d %-6d %08x %-6d", i,
  653.           stab_name [stabs->n_type],
  654.           stabs->n_other, stabs->n_desc, stabs->n_value,
  655.           stabs->n_strx);
  656.  
  657.       /* Symbols with type == 0 (N_UNDF) specify the length of the
  658.      string table associated with this file.  We use that info
  659.      to know how to relocate the *next* file's string table indices.  */
  660.  
  661.       if (stabs->n_type == N_UNDF)
  662.     {
  663.       file_string_table_offset = next_file_string_table_offset;
  664.       next_file_string_table_offset += stabs->n_value;
  665.     }
  666.  
  667.       /* Now, using the possibly updated string table offset, print the
  668.      string (if any) associated with this symbol.  */
  669.  
  670.       if ((stabs->n_strx + file_string_table_offset) < stabstr_hdr->sh_size)
  671.     printf (" %s", &strtab[stabs->n_strx + file_string_table_offset]);
  672.       else
  673.         printf (" *");
  674.     }
  675.   printf ("\n\n");
  676. }
  677. #endif    /* ELF_STAB_DISPLAY */
  678.  
  679. display_bfd (abfd)
  680.      bfd *abfd;
  681. {
  682.  
  683.   if (!bfd_check_format (abfd, bfd_object))
  684.     {
  685.       fprintf (stderr, "%s: %s not an object file\n", program_name,
  686.            abfd->filename);
  687.       return;
  688.     }
  689.   printf ("\n%s:     file format %s\n", abfd->filename, abfd->xvec->name);
  690.   if (dump_ar_hdrs)
  691.     print_arelt_descr (stdout, abfd, true);
  692.  
  693.   if (dump_file_header)
  694.     {
  695.       char *comma = "";
  696.  
  697.       printf ("architecture: %s, ",
  698.           bfd_printable_arch_mach (bfd_get_arch (abfd),
  699.                        bfd_get_mach (abfd)));
  700.       printf ("flags 0x%08x:\n", abfd->flags);
  701.  
  702. #define PF(x, y)    if (abfd->flags & x) {printf("%s%s", comma, y); comma=", ";}
  703.       PF (HAS_RELOC, "HAS_RELOC");
  704.       PF (EXEC_P, "EXEC_P");
  705.       PF (HAS_LINENO, "HAS_LINENO");
  706.       PF (HAS_DEBUG, "HAS_DEBUG");
  707.       PF (HAS_SYMS, "HAS_SYMS");
  708.       PF (HAS_LOCALS, "HAS_LOCALS");
  709.       PF (DYNAMIC, "DYNAMIC");
  710.       PF (WP_TEXT, "WP_TEXT");
  711.       PF (D_PAGED, "D_PAGED");
  712.       PF (BFD_IS_RELAXABLE, "BFD_IS_RELAXABLE");
  713.       printf ("\nstart address 0x");
  714.       printf_vma (abfd->start_address);
  715.     }
  716.   printf ("\n");
  717.  
  718.   if (dump_section_headers)
  719.     dump_headers (abfd);
  720.   if (dump_symtab || dump_reloc_info || disassemble)
  721.     {
  722.       syms = slurp_symtab (abfd);
  723.     }
  724.   if (dump_symtab)
  725.     dump_symbols (abfd);
  726. #ifdef    ELF_STAB_DISPLAY
  727.   if (dump_stab_section_info)
  728.     dump_elf_stabs (abfd);
  729. #endif
  730.   if (dump_reloc_info)
  731.     dump_relocs (abfd);
  732.   if (dump_section_contents)
  733.     dump_data (abfd);
  734.   if (disassemble)
  735.     disassemble_data (abfd);
  736. }
  737.  
  738. static void
  739. display_file (filename, target)
  740.      char *filename;
  741.      char *target;
  742. {
  743.   bfd *file, *arfile = (bfd *) NULL;
  744.  
  745.   file = bfd_openr (filename, target);
  746.   if (file == NULL)
  747.     {
  748.       fprintf (stderr, "%s: ", program_name);
  749.       bfd_perror (filename);
  750.       return;
  751.     }
  752.  
  753.   if (bfd_check_format (file, bfd_archive) == true)
  754.     {
  755.       printf ("In archive %s:\n", bfd_get_filename (file));
  756.       for (;;)
  757.     {
  758.       bfd_error = no_error;
  759.  
  760.       arfile = bfd_openr_next_archived_file (file, arfile);
  761.       if (arfile == NULL)
  762.         {
  763.           if (bfd_error != no_more_archived_files)
  764.         {
  765.           fprintf (stderr, "%s: ", program_name);
  766.           bfd_perror (bfd_get_filename (file));
  767.         }
  768.           return;
  769.         }
  770.  
  771.       display_bfd (arfile);
  772.       /* Don't close the archive elements; we need them for next_archive */
  773.     }
  774.     }
  775.   else
  776.     display_bfd (file);
  777.  
  778.   bfd_close (file);
  779. }
  780.  
  781. /* Actually display the various requested regions */
  782.  
  783. static void
  784. dump_data (abfd)
  785.      bfd *abfd;
  786. {
  787.   asection *section;
  788.   bfd_byte *data = 0;
  789.   bfd_size_type datasize = 0;
  790.   bfd_size_type i;
  791.  
  792.   for (section = abfd->sections; section != NULL; section =
  793.        section->next)
  794.     {
  795.       int onaline = 16;
  796.  
  797.       if (only == (char *) NULL ||
  798.       strcmp (only, section->name) == 0)
  799.     {
  800.       if (section->flags & SEC_HAS_CONTENTS)
  801.         {
  802.           printf ("Contents of section %s:\n", section->name);
  803.  
  804.           if (bfd_get_section_size_before_reloc (section) == 0)
  805.         continue;
  806.           data = (bfd_byte *) malloc (bfd_get_section_size_before_reloc (section));
  807.           if (data == (bfd_byte *) NULL)
  808.         {
  809.           fprintf (stderr, "%s: memory exhausted.\n", program_name);
  810.           exit (1);
  811.         }
  812.           datasize = bfd_get_section_size_before_reloc (section);
  813.  
  814.  
  815.           bfd_get_section_contents (abfd, section, (PTR) data, 0, bfd_get_section_size_before_reloc (section));
  816.  
  817.           for (i = 0; i < bfd_get_section_size_before_reloc (section); i += onaline)
  818.         {
  819.           bfd_size_type j;
  820.  
  821.           printf (" %04lx ", (unsigned long int) (i + section->vma));
  822.           for (j = i; j < i + onaline; j++)
  823.             {
  824.               if (j < bfd_get_section_size_before_reloc (section))
  825.             printf ("%02x", (unsigned) (data[j]));
  826.               else
  827.             printf ("  ");
  828.               if ((j & 3) == 3)
  829.             printf (" ");
  830.             }
  831.  
  832.           printf (" ");
  833.           for (j = i; j < i + onaline; j++)
  834.             {
  835.               if (j >= bfd_get_section_size_before_reloc (section))
  836.             printf (" ");
  837.               else
  838.             printf ("%c", isprint (data[j]) ? data[j] : '.');
  839.             }
  840.           putchar ('\n');
  841.         }
  842.           free (data);
  843.         }
  844.     }
  845.     }
  846. }
  847.  
  848. /* Should perhaps share code and display with nm? */
  849. static void
  850. dump_symbols (abfd)
  851.      bfd *abfd;
  852. {
  853.  
  854.   unsigned int count;
  855.   asymbol **current = syms;
  856.  
  857.   printf ("SYMBOL TABLE:\n");
  858.  
  859.   for (count = 0; count < symcount; count++)
  860.     {
  861.  
  862.       if (*current)
  863.     {
  864.       bfd *cur_bfd = bfd_asymbol_bfd(*current);
  865.       if (cur_bfd)
  866.         {
  867.           bfd_print_symbol (cur_bfd,
  868.                 stdout,
  869.                 *current, bfd_print_symbol_all);
  870.           printf ("\n");
  871.         }
  872.  
  873.     }
  874.       current++;
  875.     }
  876.   printf ("\n");
  877.   printf ("\n");
  878. }
  879.  
  880. static void
  881. dump_relocs (abfd)
  882.      bfd *abfd;
  883. {
  884.   arelent **relpp;
  885.   unsigned int relcount;
  886.   asection *a;
  887.  
  888.   for (a = abfd->sections; a != (asection *) NULL; a = a->next)
  889.     {
  890.       if (a == &bfd_abs_section)
  891.     continue;
  892.       if (a == &bfd_und_section)
  893.     continue;
  894.       if (bfd_is_com_section (a))
  895.     continue;
  896.  
  897.       printf ("RELOCATION RECORDS FOR [%s]:", a->name);
  898.  
  899.       if (bfd_get_reloc_upper_bound (abfd, a) == 0)
  900.     {
  901.       printf (" (none)\n\n");
  902.     }
  903.       else
  904.     {
  905.       arelent **p;
  906.  
  907.       relpp = (arelent **) xmalloc (bfd_get_reloc_upper_bound (abfd, a));
  908.       relcount = bfd_canonicalize_reloc (abfd, a, relpp, syms);
  909.       if (relcount == 0)
  910.         {
  911.           printf (" (none)\n\n");
  912.         }
  913.       else
  914.         {
  915.           printf ("\n");
  916.           printf ("OFFSET   TYPE      VALUE \n");
  917.  
  918.           for (p = relpp; relcount && *p != (arelent *) NULL; p++,
  919.            relcount--)
  920.         {
  921.           arelent *q = *p;
  922.           CONST char *sym_name;
  923.  
  924.           /*      CONST char *section_name =        q->section == (asection *)NULL ? "*abs" :*/
  925.           /*      q->section->name;*/
  926.           CONST char *section_name = (*(q->sym_ptr_ptr))->section->name;
  927.  
  928.           if (q->sym_ptr_ptr && *q->sym_ptr_ptr)
  929.             {
  930.               sym_name = (*(q->sym_ptr_ptr))->name;
  931.             }
  932.           else
  933.             {
  934.               sym_name = 0;
  935.             }
  936.           if (sym_name)
  937.             {
  938.               printf_vma (q->address);
  939.               printf (" %-8s  %s",
  940.                   q->howto->name,
  941.                   sym_name);
  942.             }
  943.           else
  944.             {
  945.               printf_vma (q->address);
  946.               printf (" %-8s  [%s]",
  947.                   q->howto->name,
  948.                   section_name);
  949.             }
  950.           if (q->addend)
  951.             {
  952.               printf ("+0x");
  953.               printf_vma (q->addend);
  954.             }
  955.           printf ("\n");
  956.         }
  957.           printf ("\n\n");
  958.           free (relpp);
  959.         }
  960.     }
  961.  
  962.     }
  963. }
  964.  
  965. #ifdef __MSDOS__
  966. #define _DUMMY_NAME_ "nul"
  967. #else
  968. #ifdef unix
  969. #define _DUMMY_NAME_ "/dev/null"
  970. #else
  971. #define _DUMMY_NAME_ "##dummy"
  972. #endif
  973. #endif
  974. static void
  975. DEFUN (display_info_table, (first, last),
  976.        int first AND int last)
  977. {
  978.   unsigned int i, j;
  979.   extern bfd_target *target_vector[];
  980.  
  981.   printf ("\n%12s", " ");
  982.   for (i = first; i++ < last && target_vector[i];)
  983.     printf ("%s ", target_vector[i]->name);
  984.   printf ("\n");
  985.  
  986.   for (j = (int) bfd_arch_obscure + 1; (int) j < (int) bfd_arch_last; j++)
  987.     if (strcmp (bfd_printable_arch_mach (j, 0), "UNKNOWN!") != 0)
  988.       {
  989.     printf ("%11s ", bfd_printable_arch_mach (j, 0));
  990.     for (i = first; i++ < last && target_vector[i];)
  991.       {
  992.         bfd_target *p = target_vector[i];
  993.         bfd *abfd = bfd_openw (_DUMMY_NAME_, p->name);
  994.         int l = strlen (p->name);
  995.         int ok;
  996.         bfd_set_format (abfd, bfd_object);
  997.         ok = bfd_set_arch_mach (abfd, j, 0);
  998.  
  999.         if (ok)
  1000.           printf ("%s ", p->name);
  1001.         else
  1002.           {
  1003.         while (l--)
  1004.           printf ("%c", ok ? '*' : '-');
  1005.         printf (" ");
  1006.           }
  1007.       }
  1008.     printf ("\n");
  1009.       }
  1010. }
  1011.  
  1012. static void
  1013. DEFUN_VOID (display_info)
  1014. {
  1015.   char *colum;
  1016.   unsigned int i, j, columns;
  1017.   extern bfd_target *target_vector[];
  1018.   extern char *getenv ();
  1019.  
  1020.   printf ("BFD header file version %s\n", BFD_VERSION);
  1021.   for (i = 0; target_vector[i]; i++)
  1022.     {
  1023.       bfd_target *p = target_vector[i];
  1024.       bfd *abfd = bfd_openw (_DUMMY_NAME_, p->name);
  1025.       bfd_set_format (abfd, bfd_object);
  1026.       printf ("%s\n (header %s, data %s)\n", p->name,
  1027.           p->header_byteorder_big_p ? "big endian" : "little endian",
  1028.           p->byteorder_big_p ? "big endian" : "little endian");
  1029.       for (j = (int) bfd_arch_obscure + 1; j < (int) bfd_arch_last; j++)
  1030.     if (bfd_set_arch_mach (abfd, (enum bfd_architecture) j, 0))
  1031.       printf ("  %s\n",
  1032.           bfd_printable_arch_mach ((enum bfd_architecture) j, 0));
  1033.     }
  1034.   columns = 0;
  1035.   if (colum = getenv ("COLUMNS"))
  1036.     columns = atoi (colum);
  1037.   if (!columns)
  1038.     columns = 80;
  1039.   for (i = 0; target_vector[i];)
  1040.     {
  1041.       int old;
  1042.       old = i;
  1043.       for (j = 12; target_vector[i] && j < columns; i++)
  1044.     j += strlen (target_vector[i]->name) + 1;
  1045.       i--;
  1046.       if (old == i)
  1047.     break;
  1048.       display_info_table (old, i);
  1049.     }
  1050. }
  1051.  
  1052. /** main and like trivia */
  1053. int
  1054. main (argc, argv)
  1055.      int argc;
  1056.      char **argv;
  1057. {
  1058.   int c;
  1059.   extern int optind;
  1060.   extern char *optarg;
  1061.   char *target = default_target;
  1062.   boolean seenflag = false;
  1063.  
  1064.   bfd_init ();
  1065.   program_name = *argv;
  1066.  
  1067.   while ((c = getopt_long (argc, argv, "ib:m:Vdlfahrtxsj:", long_options,
  1068.                (int *) 0))
  1069.      != EOF)
  1070.     {
  1071.       seenflag = true;
  1072.       switch (c)
  1073.     {
  1074.     case 'm':
  1075.       machine = optarg;
  1076.       break;
  1077.     case 'j':
  1078.       only = optarg;
  1079.       break;
  1080.     case 'l':
  1081.       with_line_numbers = 1;
  1082.       break;
  1083.     case 'b':
  1084.       target = optarg;
  1085.       break;
  1086.     case 'f':
  1087.       dump_file_header = true;
  1088.       break;
  1089.     case 'i':
  1090.       info = true;
  1091.       break;
  1092.     case 'x':
  1093.       dump_symtab = 1;
  1094.       dump_reloc_info = 1;
  1095.       dump_file_header = true;
  1096.       dump_ar_hdrs = 1;
  1097.       dump_section_headers = 1;
  1098.       break;
  1099.     case 0:
  1100.       break;        /* we've been given a long option */
  1101.     case 't':
  1102.       dump_symtab = 1;
  1103.       break;
  1104.     case 'd':
  1105.       disassemble = true;
  1106.       break;
  1107.     case 's':
  1108.       dump_section_contents = 1;
  1109.       break;
  1110.     case 'r':
  1111.       dump_reloc_info = 1;
  1112.       break;
  1113.     case 'a':
  1114.       dump_ar_hdrs = 1;
  1115.       break;
  1116.     case 'h':
  1117.       dump_section_headers = 1;
  1118.       break;
  1119.     case 'V':
  1120.       show_version = 1;
  1121.       break;
  1122.     default:
  1123.       usage ();
  1124.     }
  1125.     }
  1126.  
  1127.   if (show_version)
  1128.     printf ("%s version %s\n", program_name, program_version);
  1129.  
  1130.   if (seenflag == false)
  1131.     usage ();
  1132.  
  1133.   if (info)
  1134.     {
  1135.       display_info ();
  1136.     }
  1137.   else
  1138.     {
  1139.       if (optind == argc)
  1140.     display_file ("a.out", target);
  1141.       else
  1142.     for (; optind < argc;)
  1143.       display_file (argv[optind++], target);
  1144.     }
  1145.   return 0;
  1146. }
  1147.