2011-05-16 Tristan Gingold <gingold@adacore.com>
[platform/upstream/binutils.git] / binutils / od-xcoff.c
1 /* od-xcoff.c -- dump information about an xcoff object file.
2    Copyright 2011 Free Software Foundation, Inc.
3    Written by Tristan Gingold, Adacore.
4
5    This file is part of GNU Binutils.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3, or (at your option)
10    any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, 51 Franklin Street - Fifth Floor, Boston,
20    MA 02110-1301, USA.  */
21
22 #include <stddef.h>
23 #include <time.h>
24 #include "sysdep.h"
25 #include "safe-ctype.h"
26 #include "bfd.h"
27 #include "objdump.h"
28 #include "bucomm.h"
29 #include "bfdlink.h"
30 /* Force the support of weak symbols.  */
31 #ifndef AIX_WEAK_SUPPORT
32 #define AIX_WEAK_SUPPORT 1
33 #endif
34 #include "coff/internal.h"
35 #include "coff/rs6000.h"
36 #include "coff/xcoff.h"
37 #include "libcoff.h"
38 #include "libxcoff.h"
39
40 /* Index of the options in the options[] array.  */
41 #define OPT_FILE_HEADER 0
42 #define OPT_AOUT 1
43 #define OPT_SECTIONS 2
44 #define OPT_SYMS 3
45 #define OPT_RELOCS 4
46 #define OPT_LINENO 5
47 #define OPT_LOADER 6
48 #define OPT_EXCEPT 7
49 #define OPT_TYPCHK 8
50 #define OPT_TRACEBACK 9
51 #define OPT_TOC 10
52
53 /* List of actions.  */
54 static struct objdump_private_option options[] =
55   {
56     { "header", 0 },
57     { "aout", 0 },
58     { "sections", 0 },
59     { "syms", 0 },
60     { "relocs", 0 },
61     { "lineno", 0 },
62     { "loader", 0 },
63     { "except", 0 },
64     { "typchk", 0 },
65     { "traceback", 0 },
66     { "toc", 0 },
67     { NULL, 0 }
68   };
69
70 /* Display help.  */
71
72 static void
73 xcoff_help (FILE *stream)
74 {
75   fprintf (stream, _("\
76 For XCOFF files:\n\
77   header      Display the file header\n\
78   aout        Display the auxiliary header\n\
79   sections    Display the section headers\n\
80   syms        Display the symbols table\n\
81   relocs      Display the relocation entries\n\
82   lineno      Display the line number entries\n\
83   loader      Display loader section\n\
84   except      Display exception table\n\
85   typchk      Display type-check section\n\
86   traceback   Display traceback tags\n\
87   toc         Display toc symbols\n\
88 "));
89 }
90
91 /* Return TRUE if ABFD is handled.  */
92
93 static int
94 xcoff_filter (bfd *abfd)
95 {
96   return bfd_get_flavour (abfd) == bfd_target_xcoff_flavour;
97 }
98
99 /* Translation entry type.  The last entry must be {0, NULL}.  */
100
101 struct xlat_table {
102   unsigned int val;
103   const char *name;
104 };
105
106 /* Display the list of name (from TABLE) for FLAGS, using comma to separate
107    them.  A name is displayed if FLAGS & VAL is not 0.  */
108
109 static void
110 dump_flags (const struct xlat_table *table, unsigned int flags)
111 {
112   unsigned int r = flags;
113   int first = 1;
114   const struct xlat_table *t;
115
116   for (t = table; t->name; t++)
117     if ((flags & t->val) != 0)
118       {
119         r &= ~t->val;
120
121         if (first)
122           first = 0;
123         else
124           putchar (',');
125         fputs (t->name, stdout);
126       }
127
128   /* Not decoded flags.  */
129   if (r != 0)
130     {
131       if (!first)
132         putchar (',');
133       printf ("0x%x", r);
134     }
135 }
136
137 /* Display the name corresponding to VAL from TABLE, using at most
138    MAXLEN char (possibly passed with spaces).  */
139
140 static void
141 dump_value (const struct xlat_table *table, unsigned int val, int maxlen)
142 {
143   const struct xlat_table *t;
144
145   for (t = table; t->name; t++)
146     if (t->val == val)
147       {
148         printf ("%-*s", maxlen, t->name);
149         return;
150       }
151   printf ("(%*x)", maxlen - 2, val);
152 }
153
154 /* Names of f_flags.  */
155 static const struct xlat_table f_flag_xlat[] =
156   {
157     { F_RELFLG,    "no-rel" },
158     { F_EXEC,      "exec" },
159     { F_LNNO,      "lineno" },
160     { F_LSYMS,     "lsyms" },
161
162     { F_FDPR_PROF, "fdpr-prof" },
163     { F_FDPR_OPTI, "fdpr-opti" },
164     { F_DSA,       "dsa" },
165
166     { F_VARPG,     "varprg" },
167
168     { F_DYNLOAD,   "dynload" },
169     { F_SHROBJ,    "shrobj" },
170     { F_NONEXEC,   "nonexec" },
171
172     { 0, NULL }
173   };
174
175 /* Names of s_flags.  */
176 static const struct xlat_table s_flag_xlat[] =
177   {
178     { STYP_PAD,    "pad" },
179     { STYP_DWARF,  "dwarf" },
180     { STYP_TEXT,   "text" },
181     { STYP_DATA,   "data" },
182     { STYP_BSS,    "bss" },
183
184     { STYP_EXCEPT, "except" },
185     { STYP_INFO,   "info" },
186     { STYP_TDATA,  "tdata" },
187     { STYP_TBSS,   "tbss" },
188
189     { STYP_LOADER, "loader" },
190     { STYP_DEBUG,  "debug" },
191     { STYP_TYPCHK, "typchk" },
192     { STYP_OVRFLO, "ovrflo" },
193     { 0, NULL }
194   };
195
196 /* Names of storage class.  */
197 static const struct xlat_table sc_xlat[] =
198   {
199 #define SC_ENTRY(X) { C_##X, #X }
200     SC_ENTRY(NULL),
201     SC_ENTRY(AUTO),
202     SC_ENTRY(EXT),
203     SC_ENTRY(STAT),
204     SC_ENTRY(REG),
205     SC_ENTRY(EXTDEF),
206     SC_ENTRY(LABEL),
207     SC_ENTRY(ULABEL),
208     SC_ENTRY(MOS),
209     SC_ENTRY(ARG),
210     /*    SC_ENTRY(STRARG), */
211     SC_ENTRY(MOU),
212     SC_ENTRY(UNTAG),
213     SC_ENTRY(TPDEF),
214     SC_ENTRY(USTATIC),
215     SC_ENTRY(ENTAG),
216     SC_ENTRY(MOE),
217     SC_ENTRY(REGPARM),
218     SC_ENTRY(FIELD),
219     SC_ENTRY(BLOCK),
220     SC_ENTRY(FCN),
221     SC_ENTRY(EOS),
222     SC_ENTRY(FILE),
223     SC_ENTRY(LINE),
224     SC_ENTRY(ALIAS),
225     SC_ENTRY(HIDDEN),
226     SC_ENTRY(HIDEXT),
227     SC_ENTRY(BINCL),
228     SC_ENTRY(EINCL),
229     SC_ENTRY(INFO),
230     SC_ENTRY(WEAKEXT),
231     SC_ENTRY(DWARF),
232
233     /* Stabs.  */
234     SC_ENTRY (GSYM),
235     SC_ENTRY (LSYM),
236     SC_ENTRY (PSYM),
237     SC_ENTRY (RSYM),
238     SC_ENTRY (RPSYM),
239     SC_ENTRY (STSYM),
240     SC_ENTRY (TCSYM),
241     SC_ENTRY (BCOMM),
242     SC_ENTRY (ECOML),
243     SC_ENTRY (ECOMM),
244     SC_ENTRY (DECL),
245     SC_ENTRY (ENTRY),
246     SC_ENTRY (FUN),
247     SC_ENTRY (BSTAT),
248     SC_ENTRY (ESTAT),
249
250     { 0, NULL }
251 #undef SC_ENTRY
252   };
253
254 /* Names for symbol type.  */
255 static const struct xlat_table smtyp_xlat[] =
256   {
257     { XTY_ER, "ER" },
258     { XTY_SD, "SD" },
259     { XTY_LD, "LD" },
260     { XTY_CM, "CM" },
261     { XTY_EM, "EM" },
262     { XTY_US, "US" },
263     { 0, NULL }
264   };
265
266 /* Names for storage-mapping class.  */
267 static const struct xlat_table smclas_xlat[] =
268   {
269 #define SMCLAS_ENTRY(X) { XMC_##X, #X }
270     SMCLAS_ENTRY (PR),
271     SMCLAS_ENTRY (RO),
272     SMCLAS_ENTRY (DB),
273     SMCLAS_ENTRY (TC),
274     SMCLAS_ENTRY (UA),
275     SMCLAS_ENTRY (RW),
276     SMCLAS_ENTRY (GL),
277     SMCLAS_ENTRY (XO),
278     SMCLAS_ENTRY (SV),
279     SMCLAS_ENTRY (BS),
280     SMCLAS_ENTRY (DS),
281     SMCLAS_ENTRY (UC),
282     SMCLAS_ENTRY (TI),
283     SMCLAS_ENTRY (TB),
284     SMCLAS_ENTRY (TC0),
285     SMCLAS_ENTRY (TD),
286     SMCLAS_ENTRY (SV64),
287     SMCLAS_ENTRY (SV3264),
288     { 0, NULL }
289 #undef SMCLAS_ENTRY
290   };
291
292 /* Names for relocation type.  */
293 static const struct xlat_table rtype_xlat[] =
294   {
295 #define RTYPE_ENTRY(X) { R_##X, #X }
296     RTYPE_ENTRY (POS),
297     RTYPE_ENTRY (NEG),
298     RTYPE_ENTRY (REL),
299     RTYPE_ENTRY (TOC),
300     RTYPE_ENTRY (RTB),
301     RTYPE_ENTRY (GL),
302     RTYPE_ENTRY (TCL),
303     RTYPE_ENTRY (BA),
304     RTYPE_ENTRY (BR),
305     RTYPE_ENTRY (RL),
306     RTYPE_ENTRY (RLA),
307     RTYPE_ENTRY (REF),
308     RTYPE_ENTRY (TRL),
309     RTYPE_ENTRY (TRLA),
310     RTYPE_ENTRY (RRTBI),
311     RTYPE_ENTRY (RRTBA),
312     RTYPE_ENTRY (CAI),
313     RTYPE_ENTRY (CREL),
314     RTYPE_ENTRY (RBA),
315     RTYPE_ENTRY (RBAC),
316     RTYPE_ENTRY (RBR),
317     RTYPE_ENTRY (RBRC),
318     RTYPE_ENTRY (TLS),
319     RTYPE_ENTRY (TLS_IE),
320     RTYPE_ENTRY (TLS_LD),
321     RTYPE_ENTRY (TLS_LE),
322     RTYPE_ENTRY (TLSM),
323     RTYPE_ENTRY (TLSML),
324     RTYPE_ENTRY (TOCU),
325     RTYPE_ENTRY (TOCL),
326     { 0, NULL }
327   };
328
329 /* Simplified section header.  */
330 struct xcoff32_section
331 {
332   /* NUL terminated name.  */
333   char name[9];
334
335   /* Section flags.  */
336   unsigned int flags;
337
338   /* Offsets in file.  */
339   ufile_ptr scnptr;
340   ufile_ptr relptr;
341   ufile_ptr lnnoptr;
342
343   /* Number of relocs and line numbers.  */
344   unsigned int nreloc;
345   unsigned int nlnno;
346 };
347
348 /* Simplified symbol.  */
349
350 union xcoff32_symbol
351 {
352   union external_auxent aux;
353
354   struct sym
355   {
356     /* Pointer the the NUL-terminated name.  */
357     char *name;
358
359     /* XCOFF symbol fields.  */
360     unsigned int val;
361     unsigned short scnum;
362     unsigned short ntype;
363     unsigned char sclass;
364     unsigned char numaux;
365
366     /* Buffer in case the name is local.  */
367     union
368     {
369       char name[9];
370       unsigned int off;
371     } raw;
372   } sym;
373 };
374
375 /* Important fields to dump the file.  */
376
377 struct xcoff_dump
378 {
379   /* From file header.  */
380   unsigned short nscns;
381   unsigned int symptr;
382   unsigned int nsyms;
383   unsigned short opthdr;
384
385   /* Sections.  */
386   struct xcoff32_section *sects;
387
388   /* Symbols.  */
389   union xcoff32_symbol *syms;
390   char *strings;
391   unsigned int strings_size;
392 };
393
394 /* Print a symbol (if possible).  */
395
396 static void
397 xcoff32_print_symbol (struct xcoff_dump *data, unsigned int symndx)
398 {
399   if (data->syms != NULL
400       && symndx < data->nsyms
401       && data->syms[symndx].sym.name != NULL)
402     printf ("%s", data->syms[symndx].sym.name);
403   else
404     printf ("%u", symndx);
405 }
406
407 /* Dump the file header.  */
408
409 static void
410 dump_xcoff32_file_header (bfd *abfd, struct external_filehdr *fhdr,
411                           struct xcoff_dump *data)
412 {
413   unsigned int timdat = bfd_h_get_32 (abfd, fhdr->f_timdat);
414   unsigned short flags = bfd_h_get_16 (abfd, fhdr->f_flags);
415
416   printf (_("  nbr sections:  %d\n"), data->nscns);
417   printf (_("  time and date: 0x%08x  - "), timdat);
418   if (timdat == 0)
419     printf (_("not set\n"));
420   else
421     {
422       /* Not correct on all platforms, but works on unix.  */
423       time_t t = timdat;
424       fputs (ctime (&t), stdout);
425     }
426   printf (_("  symbols off:   0x%08x\n"), data->symptr);
427   printf (_("  nbr symbols:   %d\n"), data->nsyms);
428   printf (_("  opt hdr sz:    %d\n"), data->opthdr);
429   printf (_("  flags:         0x%04x "), flags);
430   dump_flags (f_flag_xlat, flags);
431   putchar ('\n');
432 }
433
434 /* Dump the a.out header.  */
435
436 static void
437 dump_xcoff32_aout_header (bfd *abfd, struct xcoff_dump *data)
438 {
439   AOUTHDR auxhdr;
440   unsigned short magic;
441   unsigned int sz = data->opthdr;
442
443   printf (_("Auxiliary header:\n"));
444   if (data->opthdr == 0)
445     {
446       printf (_("  No aux header\n"));
447       return;
448     }
449   if (data->opthdr > sizeof (auxhdr))
450     {
451       printf (_("warning: optionnal header size too large (> %d)\n"),
452               (int)sizeof (auxhdr));
453       sz = sizeof (auxhdr);
454     }
455   if (bfd_bread (&auxhdr, sz, abfd) != sz)
456     {
457       non_fatal (_("cannot read auxhdr"));
458       return;
459     }
460
461   magic = bfd_h_get_16 (abfd, auxhdr.magic);
462   printf (_("  o_mflag (magic): 0x%04x 0%04o\n"), magic, magic);
463   printf (_("  o_vstamp:        0x%04x\n"),
464           (unsigned short)bfd_h_get_16 (abfd, auxhdr.vstamp));
465   printf (_("  o_tsize:         0x%08x\n"),
466           (unsigned int)bfd_h_get_32 (abfd, auxhdr.tsize));
467   printf (_("  o_dsize:         0x%08x\n"),
468           (unsigned int)bfd_h_get_32 (abfd, auxhdr.dsize));
469   printf (_("  o_entry:         0x%08x\n"),
470           (unsigned int)bfd_h_get_32 (abfd, auxhdr.entry));
471   printf (_("  o_text_start:    0x%08x\n"),
472           (unsigned int)bfd_h_get_32 (abfd, auxhdr.text_start));
473   printf (_("  o_data_start:    0x%08x\n"),
474           (unsigned int)bfd_h_get_32 (abfd, auxhdr.data_start));
475   if (sz == offsetof (AOUTHDR, o_toc))
476     return;
477   printf (_("  o_toc:           0x%08x\n"),
478           (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_toc));
479   printf (_("  o_snentry:       0x%04x\n"),
480           (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snentry));
481   printf (_("  o_sntext:        0x%04x\n"),
482           (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sntext));
483   printf (_("  o_sndata:        0x%04x\n"),
484           (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sndata));
485   printf (_("  o_sntoc:         0x%04x\n"),
486           (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sntoc));
487   printf (_("  o_snloader:      0x%04x\n"),
488           (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snloader));
489   printf (_("  o_snbss:         0x%04x\n"),
490           (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snbss));
491   printf (_("  o_algntext:      %u\n"),
492           (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_algntext));
493   printf (_("  o_algndata:      %u\n"),
494           (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_algndata));
495   printf (_("  o_modtype:       0x%04x"),
496           (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_modtype));
497   if (ISPRINT (auxhdr.o_modtype[0]) && ISPRINT (auxhdr.o_modtype[1]))
498     printf (" (%c%c)", auxhdr.o_modtype[0], auxhdr.o_modtype[1]);
499   putchar ('\n');
500   printf (_("  o_cputype:       0x%04x\n"),
501           (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_cputype));
502   printf (_("  o_maxstack:      0x%08x\n"),
503           (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_maxstack));
504   printf (_("  o_maxdata:       0x%08x\n"),
505           (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_maxdata));
506 #if 0
507   printf (_("  o_debugger:      0x%08x\n"),
508           (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_debugger));
509 #endif
510 }
511
512 /* Dump the sections header.  */
513
514 static void
515 dump_xcoff32_sections_header (bfd *abfd, struct xcoff_dump *data)
516 {
517   unsigned int i;
518   unsigned int off;
519
520   off = sizeof (struct external_filehdr) + data->opthdr;
521   printf (_("Section headers (at %u+%u=0x%08x to 0x%08x):\n"),
522           (unsigned int)sizeof (struct external_filehdr), data->opthdr, off,
523           off + (unsigned int)sizeof (struct external_scnhdr) * data->nscns);
524   if (data->nscns == 0)
525     {
526       printf (_("  No section header\n"));
527       return;
528     }
529   if (bfd_seek (abfd, off, SEEK_SET) != 0)
530     {
531       non_fatal (_("cannot read section header"));
532       return;
533     }
534   printf (_(" # Name     paddr    vaddr    size     scnptr   relptr   lnnoptr  nrel  nlnno\n"));
535   for (i = 0; i < data->nscns; i++)
536     {
537       struct external_scnhdr scn;
538       unsigned int flags;
539
540       if (bfd_bread (&scn, sizeof (scn), abfd) != sizeof (scn))
541         {
542           non_fatal (_("cannot read section header"));
543           return;
544         }
545       flags = bfd_h_get_32 (abfd, scn.s_flags);
546       printf (_("%2d %-8.8s %08x %08x %08x %08x %08x %08x "
547                 "%-5d %-5d\n"),
548               i + 1, scn.s_name,
549               (unsigned int)bfd_h_get_32 (abfd, scn.s_paddr),
550               (unsigned int)bfd_h_get_32 (abfd, scn.s_vaddr),
551               (unsigned int)bfd_h_get_32 (abfd, scn.s_size),
552               (unsigned int)bfd_h_get_32 (abfd, scn.s_scnptr),
553               (unsigned int)bfd_h_get_32 (abfd, scn.s_relptr),
554               (unsigned int)bfd_h_get_32 (abfd, scn.s_lnnoptr),
555               (unsigned int)bfd_h_get_16 (abfd, scn.s_nreloc),
556               (unsigned int)bfd_h_get_16 (abfd, scn.s_nlnno));
557       printf (_("            Flags: %08x "), flags);
558
559       if (~flags == 0)
560         {
561           /* Stripped executable ?  */
562           putchar ('\n');
563         }
564       else if (flags & STYP_OVRFLO)
565         printf (_("overflow - nreloc: %u, nlnno: %u\n"),
566                 (unsigned int)bfd_h_get_32 (abfd, scn.s_paddr),
567                 (unsigned int)bfd_h_get_32 (abfd, scn.s_vaddr));
568       else
569         {
570           dump_flags (s_flag_xlat, flags);
571           putchar ('\n');
572         }
573     }
574 }
575
576 /* Read section table.  */
577
578 static void
579 xcoff32_read_sections (bfd *abfd, struct xcoff_dump *data)
580 {
581   int i;
582
583   if (bfd_seek (abfd, sizeof (struct external_filehdr) + data->opthdr,
584                 SEEK_SET) != 0)
585     {
586       non_fatal (_("cannot read section headers"));
587       return;
588     }
589
590   data->sects = xmalloc (data->nscns * sizeof (struct xcoff32_section));
591   for (i = 0; i < data->nscns; i++)
592     {
593       struct external_scnhdr scn;
594       struct xcoff32_section *s = &data->sects[i];
595
596       if (bfd_bread (&scn, sizeof (scn), abfd) != sizeof (scn))
597         {
598           non_fatal (_("cannot read section header"));
599           free (data->sects);
600           data->sects = NULL;
601           return;
602         }
603       memcpy (s->name, scn.s_name, 8);
604       s->name[8] = 0;
605       s->flags = bfd_h_get_32 (abfd, scn.s_flags);
606
607       s->scnptr = bfd_h_get_32 (abfd, scn.s_scnptr);
608       s->relptr = bfd_h_get_32 (abfd, scn.s_relptr);
609       s->lnnoptr = bfd_h_get_32 (abfd, scn.s_lnnoptr);
610
611       s->nreloc = bfd_h_get_16 (abfd, scn.s_nreloc);
612       s->nlnno = bfd_h_get_16 (abfd, scn.s_nlnno);
613
614       if (s->flags == STYP_OVRFLO)
615         {
616           if (s->nreloc > 0 && s->nreloc <= data->nscns)
617             data->sects[s->nreloc - 1].nreloc =
618               bfd_h_get_32 (abfd, scn.s_paddr);
619           if (s->nlnno > 0 && s->nlnno <= data->nscns)
620             data->sects[s->nlnno - 1].nlnno =
621               bfd_h_get_32 (abfd, scn.s_vaddr);
622         }
623     }
624 }
625
626 /* Read symbols.  */
627
628 static void
629 xcoff32_read_symbols (bfd *abfd, struct xcoff_dump *data)
630 {
631   unsigned int i;
632   char stsz_arr[4];
633   unsigned int stptr;
634
635   if (data->nsyms == 0)
636     return;
637
638   stptr = data->symptr
639     + data->nsyms * (unsigned)sizeof (struct external_syment);
640
641   /* Read string table.  */
642   if (bfd_seek (abfd, stptr, SEEK_SET) != 0)
643     {
644       data->strings_size = 0;
645     }
646   else
647     {
648       if (bfd_bread (&stsz_arr, sizeof (stsz_arr), abfd) != sizeof (stsz_arr))
649         {
650           non_fatal (_("cannot read strings table len"));
651           return;
652         }
653       data->strings_size = bfd_h_get_32 (abfd, stsz_arr);
654       if (data->strings_size > sizeof (stsz_arr))
655         {
656           unsigned int remsz = data->strings_size - sizeof (stsz_arr);
657
658           data->strings = xmalloc (data->strings_size);
659
660           memcpy (data->strings, stsz_arr, sizeof (stsz_arr));
661           if (bfd_bread (data->strings + sizeof (stsz_arr), remsz, abfd)
662               != remsz)
663             {
664               non_fatal (_("cannot read strings table"));
665               goto clean;
666             }
667         }
668     }
669
670   if (bfd_seek (abfd, data->symptr, SEEK_SET) != 0)
671     {
672       non_fatal (_("cannot read symbol table"));
673       goto clean;
674     }
675
676   data->syms = (union xcoff32_symbol *)
677     xmalloc (data->nsyms * sizeof (union xcoff32_symbol));
678
679   for (i = 0; i < data->nsyms; i++)
680     {
681       struct external_syment sym;
682       int j;
683       union xcoff32_symbol *s = &data->syms[i];
684
685       if (bfd_bread (&sym, sizeof (sym), abfd) != sizeof (sym))
686         {
687           non_fatal (_("cannot read symbol entry"));
688           goto clean;
689         }
690
691       s->sym.val = bfd_h_get_32 (abfd, sym.e_value);
692       s->sym.scnum = bfd_h_get_16 (abfd, sym.e_scnum);
693       s->sym.ntype = bfd_h_get_16 (abfd, sym.e_type);
694       s->sym.sclass = bfd_h_get_8 (abfd, sym.e_sclass);
695       s->sym.numaux = bfd_h_get_8 (abfd, sym.e_numaux);
696
697       if (sym.e.e_name[0])
698         {
699           memcpy (s->sym.raw.name, sym.e.e_name, sizeof (sym.e.e_name));
700           s->sym.raw.name[8] = 0;
701           s->sym.name = s->sym.raw.name;
702         }
703       else
704         {
705           unsigned int soff = bfd_h_get_32 (abfd, sym.e.e.e_offset);
706
707           if ((s->sym.sclass & DBXMASK) == 0 && soff < data->strings_size)
708             s->sym.name = data->strings + soff;
709           else
710             {
711               s->sym.name = NULL;
712               s->sym.raw.off = soff;
713             }
714         }
715
716       for (j = 0; j < s->sym.numaux; j++, i++)
717         {
718            if (bfd_bread (&s[j + 1].aux,
719                           sizeof (union external_auxent), abfd)
720                != sizeof (union external_auxent))
721             {
722               non_fatal (_("cannot read symbol aux entry"));
723               goto clean;
724             }
725         }
726     }
727   return;
728  clean:
729   free (data->syms);
730   data->syms = NULL;
731   free (data->strings);
732   data->strings = NULL;
733 }
734
735 /* Dump xcoff symbols.  */
736
737 static void
738 dump_xcoff32_symbols (bfd *abfd, struct xcoff_dump *data)
739 {
740   unsigned int i;
741   asection *debugsec;
742   char *debug = NULL;
743
744   printf (_("Symbols table (strtable at 0x%08x)"),
745           data->symptr
746           + data->nsyms * (unsigned)sizeof (struct external_syment));
747   if (data->nsyms == 0 || data->syms == NULL)
748     {
749       printf (_(":\n  No symbols\n"));
750       return;
751     }
752
753   /* Read string table.  */
754   if (data->strings_size == 0)
755     printf (_(" (no strings):\n"));
756   else
757     printf (_(" (strings size: %08x):\n"), data->strings_size);
758
759   /* Read debug section.  */
760   debugsec = bfd_get_section_by_name (abfd, ".debug");
761   if (debugsec != NULL)
762     {
763       bfd_size_type size;
764
765       size = bfd_get_section_size (debugsec);
766       debug = (char *) xmalloc (size);
767       bfd_get_section_contents (abfd, debugsec, debug, 0, size);
768     }
769
770   printf (_("  # sc         value    section  type aux name/off\n"));
771   for (i = 0; i < data->nsyms; i++)
772     {
773       union xcoff32_symbol *s = &data->syms[i];
774       int j;
775
776       printf ("%3u ", i);
777       dump_value (sc_xlat, s->sym.sclass, 10);
778       printf (" %08x ", s->sym.val);
779       if (s->sym.scnum > 0 && s->sym.scnum <= data->nscns)
780         {
781           if (data->sects != NULL)
782             printf ("%-8s", data->sects[s->sym.scnum - 1].name);
783           else
784             printf ("%-8u", s->sym.scnum);
785         }
786       else
787         switch ((signed short)s->sym.scnum)
788           {
789           case N_DEBUG:
790             printf ("N_DEBUG ");
791             break;
792           case N_ABS:
793             printf ("N_ABS   ");
794             break;
795           case N_UNDEF:
796             printf ("N_UNDEF ");
797             break;
798           default:
799             printf ("(%04x)  ", s->sym.scnum);
800           }
801       printf (" %04x %3u ", s->sym.ntype, s->sym.numaux);
802       if (s->sym.name != NULL)
803         printf ("%s", s->sym.name);
804       else
805         {
806           if ((s->sym.sclass & DBXMASK) != 0 && debug != NULL)
807             printf ("%s", debug + s->sym.raw.off);
808           else
809             printf ("%08x", s->sym.raw.off);
810         }
811       putchar ('\n');
812
813       for (j = 0; j < s->sym.numaux; j++, i++)
814         {
815           union external_auxent *aux = &s[j + 1].aux;
816
817           printf (" %3u ", i + 1);
818           switch (s->sym.sclass)
819             {
820             case C_STAT:
821               printf (_("  scnlen: %08x  nreloc: %-6u  nlinno: %-6u\n"),
822                       (unsigned)bfd_h_get_32 (abfd, aux->x_scn.x_scnlen),
823                       (unsigned)bfd_h_get_16 (abfd, aux->x_scn.x_nreloc),
824                       (unsigned)bfd_h_get_16 (abfd, aux->x_scn.x_nlinno));
825               break;
826             case C_DWARF:
827               printf (_("  scnlen: %08x  nreloc: %-6u\n"),
828                       (unsigned)bfd_h_get_32 (abfd, aux->x_scn.x_scnlen),
829                       (unsigned)bfd_h_get_16 (abfd, aux->x_scn.x_nreloc));
830               break;
831             case C_EXT:
832             case C_WEAKEXT:
833             case C_HIDEXT:
834               if (j == 0 && s->sym.numaux > 1)
835                 {
836                   /* Function aux entry.  */
837                   printf (_("  exptr: %08x fsize: %08x lnnoptr: %08x endndx: %u\n"),
838                           (unsigned)bfd_h_get_32 (abfd, aux->x_sym.x_tagndx),
839                           (unsigned)bfd_h_get_32
840                             (abfd, aux->x_sym.x_misc.x_fsize),
841                           (unsigned)bfd_h_get_32
842                             (abfd, aux->x_sym.x_fcnary.x_fcn.x_lnnoptr),
843                           (unsigned)bfd_h_get_32
844                             (abfd, aux->x_sym.x_fcnary.x_fcn.x_endndx));
845                 }
846               else if (j == 1 || (j == 0 && s->sym.numaux == 1))
847                 {
848                   /* csect aux entry.  */
849                   unsigned char smtyp;
850                   unsigned int scnlen;
851
852                   smtyp = bfd_h_get_8 (abfd, aux->x_csect.x_smtyp);
853                   scnlen = bfd_h_get_32 (abfd, aux->x_csect.x_scnlen);
854
855                   if (smtyp == XTY_LD)
856                     printf (_("  scnsym: %-8u"), scnlen);
857                   else
858                     printf (_("  scnlen: %08x"), scnlen);
859                   printf (_(" h: parm=%08x sn=%04x al: 2**%u"),
860                           (unsigned)bfd_h_get_32 (abfd, aux->x_csect.x_parmhash),
861                           (unsigned)bfd_h_get_16 (abfd, aux->x_csect.x_snhash),
862                           SMTYP_ALIGN (smtyp));
863                   printf (_(" typ: "));
864                   dump_value (smtyp_xlat, SMTYP_SMTYP (smtyp), 2);
865                   printf (_(" cl: "));
866                   dump_value
867                     (smclas_xlat,
868                      (unsigned)bfd_h_get_8 (abfd, aux->x_csect.x_smclas), 6);
869                   putchar ('\n');
870                 }
871               else
872                 printf ("aux\n");
873               break;
874             case C_FILE:
875               {
876                 unsigned int off;
877
878                 printf (_(" ftype: %02x "),
879                         (unsigned)bfd_h_get_8 (abfd, aux->x_file.x_ftype));
880                 if (aux->x_file.x_n.x_fname[0] != 0)
881                   printf (_("fname: %.14s"), aux->x_file.x_n.x_fname);
882                 else
883                   {
884                     off = (unsigned)bfd_h_get_32
885                       (abfd, aux->x_file.x_n.x_n.x_offset);
886                     if (data->strings != NULL && off < data->strings_size)
887                       printf (_(" %s"), data->strings + off);
888                     else
889                       printf (_("offset: %08x"), off);
890                   }
891                 putchar ('\n');
892               }
893               break;
894             case C_BLOCK:
895             case C_FCN:
896               printf (_("  lnno: %u\n"),
897                       (unsigned)bfd_h_get_16
898                       (abfd, aux->x_sym.x_misc.x_lnsz.x_lnno));
899               break;
900             default:
901               printf ("aux\n");
902               break;
903             }
904         }
905
906     }
907   free (debug);
908 }
909
910 /* Dump xcoff relocation entries.  */
911
912 static void
913 dump_xcoff32_relocs (bfd *abfd, struct xcoff_dump *data)
914 {
915   unsigned int i;
916
917   if (data->sects == NULL)
918     {
919       non_fatal (_("cannot read section headers"));
920       return;
921     }
922
923   for (i = 0; i < data->nscns; i++)
924     {
925       struct xcoff32_section *sect = &data->sects[i];
926       unsigned int nrel = sect->nreloc;
927       unsigned int j;
928
929       if (nrel == 0)
930         continue;
931       printf (_("Relocations for %s (%u)\n"), sect->name, nrel);
932       if (bfd_seek (abfd, sect->relptr, SEEK_SET) != 0)
933         {
934           non_fatal (_("cannot read relocations"));
935           continue;
936         }
937       printf (_("vaddr    sgn mod sz type  symndx symbol\n"));
938       for (j = 0; j < nrel; j++)
939         {
940           struct external_reloc rel;
941           unsigned char rsize;
942           unsigned int symndx;
943
944           if (bfd_bread (&rel, sizeof (rel), abfd) != sizeof (rel))
945             {
946               non_fatal (_("cannot read relocation entry"));
947               return;
948             }
949           rsize = bfd_h_get_8 (abfd, rel.r_size);
950           printf (_("%08x  %c   %c  %-2u "),
951                   (unsigned int)bfd_h_get_32 (abfd, rel.r_vaddr),
952                   rsize & 0x80 ? 'S' : 'U',
953                   rsize & 0x40 ? 'm' : ' ',
954                   (rsize & 0x3f) + 1);
955           dump_value (rtype_xlat, bfd_h_get_8 (abfd, rel.r_type), 6);
956           symndx = bfd_h_get_32 (abfd, rel.r_symndx);
957           printf ("%-6u ", symndx);
958           xcoff32_print_symbol (data, symndx);
959           putchar ('\n');
960         }
961       putchar ('\n');
962     }
963 }
964
965 /* Dump xcoff line number entries.  */
966
967 static void
968 dump_xcoff32_lineno (bfd *abfd, struct xcoff_dump *data)
969 {
970   unsigned int i;
971
972   if (data->sects == NULL)
973     {
974       non_fatal (_("cannot read section headers"));
975       return;
976     }
977
978   for (i = 0; i < data->nscns; i++)
979     {
980       struct xcoff32_section *sect = &data->sects[i];
981       unsigned int nlnno = sect->nlnno;
982       unsigned int j;
983
984       if (nlnno == 0)
985         continue;
986       printf (_("Line numbers for %s (%u)\n"), sect->name, nlnno);
987       if (bfd_seek (abfd, sect->lnnoptr, SEEK_SET) != 0)
988         {
989           non_fatal (_("cannot read line numbers"));
990           continue;
991         }
992       printf (_("lineno  symndx/paddr\n"));
993       for (j = 0; j < nlnno; j++)
994         {
995           struct external_lineno ln;
996           unsigned int no;
997
998           if (bfd_bread (&ln, sizeof (ln), abfd) != sizeof (ln))
999             {
1000               non_fatal (_("cannot read line number entry"));
1001               return;
1002             }
1003           no = bfd_h_get_16 (abfd, ln.l_lnno);
1004           printf (_(" %-6u "), no);
1005           if (no == 0)
1006             {
1007               unsigned int symndx = bfd_h_get_32 (abfd, ln.l_addr.l_symndx);
1008               xcoff32_print_symbol (data, symndx);
1009             }
1010           else
1011             printf ("0x%08x",
1012                     (unsigned int)bfd_h_get_32 (abfd, ln.l_addr.l_paddr));
1013           putchar ('\n');
1014         }
1015     }
1016 }
1017
1018 /* Dump xcoff loader section.  */
1019
1020 static void
1021 dump_xcoff32_loader (bfd *abfd)
1022 {
1023   asection *loader;
1024   bfd_size_type size = 0;
1025   struct external_ldhdr *lhdr;
1026   struct external_ldsym *ldsym;
1027   struct external_ldrel *ldrel;
1028   bfd_byte *ldr_data;
1029   unsigned int version;
1030   unsigned int ndsyms;
1031   unsigned int ndrel;
1032   unsigned int stlen;
1033   unsigned int stoff;
1034   unsigned int impoff;
1035   unsigned int nimpid;
1036   unsigned int i;
1037   const char *p;
1038
1039   loader = bfd_get_section_by_name (abfd, ".loader");
1040
1041   if (loader == NULL)
1042     {
1043       printf (_("no .loader section in file\n"));
1044       return;
1045     }
1046   size = bfd_get_section_size (loader);
1047   if (size < sizeof (*lhdr))
1048     {
1049       printf (_("section .loader is too short\n"));
1050       return;
1051     }
1052
1053   ldr_data = (bfd_byte *) xmalloc (size);
1054   bfd_get_section_contents (abfd, loader, ldr_data, 0, size);
1055   lhdr = (struct external_ldhdr *)ldr_data;
1056   printf (_("Loader header:\n"));
1057   version = bfd_h_get_32 (abfd, lhdr->l_version);
1058   printf (_("  version:           %u\n"), version);
1059   if (version != 1)
1060     {
1061       printf (_(" Unhandled version\n"));
1062       free (ldr_data);
1063       return;
1064     }
1065   ndsyms = bfd_h_get_32 (abfd, lhdr->l_nsyms);
1066   printf (_("  nbr symbols:       %u\n"), ndsyms);
1067   ndrel = bfd_h_get_32 (abfd, lhdr->l_nreloc);
1068   printf (_("  nbr relocs:        %u\n"), ndrel);
1069   printf (_("  import strtab len: %u\n"),
1070           (unsigned) bfd_h_get_32 (abfd, lhdr->l_istlen));
1071   nimpid = bfd_h_get_32 (abfd, lhdr->l_nimpid);
1072   printf (_("  nbr import files:  %u\n"), nimpid);
1073   impoff = bfd_h_get_32 (abfd, lhdr->l_impoff);
1074   printf (_("  import file off:   %u\n"), impoff);
1075   stlen = bfd_h_get_32 (abfd, lhdr->l_stlen);
1076   printf (_("  string table len:  %u\n"), stlen);
1077   stoff = bfd_h_get_32 (abfd, lhdr->l_stoff);
1078   printf (_("  string table off:  %u\n"), stoff);
1079
1080   ldsym = (struct external_ldsym *)(ldr_data + sizeof (*lhdr));
1081   printf (_("Dynamic symbols:\n"));
1082   printf (_("     # value     sc IFEW ty class file  pa name\n"));
1083   for (i = 0; i < ndsyms; i++, ldsym++)
1084     {
1085       unsigned char smtype;
1086
1087       printf (_("  %4u %08x %3u "), i,
1088               (unsigned)bfd_h_get_32 (abfd, ldsym->l_value),
1089               (unsigned)bfd_h_get_16 (abfd, ldsym->l_scnum));
1090       smtype = bfd_h_get_8 (abfd, ldsym->l_smtype);
1091       putchar (smtype & 0x40 ? 'I' : ' ');
1092       putchar (smtype & 0x20 ? 'F' : ' ');
1093       putchar (smtype & 0x10 ? 'E' : ' ');
1094       putchar (smtype & 0x08 ? 'W' : ' ');
1095       putchar (' ');
1096       dump_value (smtyp_xlat, SMTYP_SMTYP (smtype), 2);
1097       putchar (' ');
1098       dump_value
1099         (smclas_xlat, (unsigned)bfd_h_get_8 (abfd, ldsym->l_smclas), 6);
1100       printf (_(" %3u %3u "),
1101               (unsigned)bfd_h_get_32 (abfd, ldsym->l_ifile),
1102               (unsigned)bfd_h_get_32 (abfd, ldsym->l_parm));
1103       if (ldsym->_l._l_name[0] != 0)
1104         printf ("%-.8s", ldsym->_l._l_name);
1105       else
1106         {
1107           unsigned int off = bfd_h_get_32 (abfd, ldsym->_l._l_l._l_offset);
1108           if (off > stlen)
1109             printf (_("(bad offset: %u)"), off);
1110           else
1111             printf ("%s", ldr_data + stoff + off);
1112         }
1113       putchar ('\n');
1114     }
1115
1116   printf (_("Dynamic relocs:\n"));
1117   printf (_("  vaddr    sec    sz typ   sym\n"));
1118   ldrel = (struct external_ldrel *)(ldr_data + sizeof (*lhdr)
1119                                     + ndsyms * sizeof (*ldsym));
1120   for (i = 0; i < ndrel; i++, ldrel++)
1121     {
1122       unsigned int rsize;
1123       unsigned int rtype;
1124       unsigned int symndx;
1125
1126       rsize = bfd_h_get_8 (abfd, ldrel->l_rtype + 0);
1127       rtype = bfd_h_get_8 (abfd, ldrel->l_rtype + 1);
1128
1129       printf (_("  %08x %3u %c%c %2u "),
1130               (unsigned)bfd_h_get_32 (abfd, ldrel->l_vaddr),
1131               (unsigned)bfd_h_get_16 (abfd, ldrel->l_rsecnm),
1132               rsize & 0x80 ? 'S' : 'U',
1133               rsize & 0x40 ? 'm' : ' ',
1134               (rsize & 0x3f) + 1);
1135       dump_value (rtype_xlat, rtype, 6);
1136       symndx = bfd_h_get_32 (abfd, ldrel->l_symndx);
1137       switch (symndx)
1138         {
1139         case 0:
1140           printf (_(".text"));
1141           break;
1142         case 1:
1143           printf (_(".data"));
1144           break;
1145         case 2:
1146           printf (_(".bss"));
1147           break;
1148         default:
1149           printf (_("%u"), symndx - 3);
1150           break;
1151         }
1152       putchar ('\n');
1153     }
1154
1155   printf (_("Import files:\n"));
1156   p = (char *)ldr_data + impoff;
1157   for (i = 0; i < nimpid; i++)
1158     {
1159       int n1, n2, n3;
1160
1161       n1 = strlen (p);
1162       n2 = strlen (p + n1 + 1);
1163       n3 = strlen (p + n1 + 1 + n2+ 1);
1164       printf (" %2u: %s,%s,%s\n", i,
1165               p, p + n1 + 1, p + n1 + n2 + 2);
1166       p += n1 + n2 + n3 + 3;
1167     }
1168
1169   free (ldr_data);
1170 }
1171
1172 /* Dump xcoff exception section.  */
1173
1174 static void
1175 dump_xcoff32_except (bfd *abfd, struct xcoff_dump *data)
1176 {
1177   asection *sec;
1178   bfd_size_type size = 0;
1179   bfd_byte *excp_data;
1180   struct external_exceptab *exceptab;
1181   unsigned int i;
1182
1183   sec = bfd_get_section_by_name (abfd, ".except");
1184
1185   if (sec == NULL)
1186     {
1187       printf (_("no .except section in file\n"));
1188       return;
1189     }
1190   size = bfd_get_section_size (sec);
1191   excp_data = (bfd_byte *) xmalloc (size);
1192   bfd_get_section_contents (abfd, sec, excp_data, 0, size);
1193   exceptab = (struct external_exceptab *)excp_data;
1194
1195   printf (_("Exception table:\n"));
1196   printf (_("lang reason sym/addr\n"));
1197   for (i = 0; i * sizeof (*exceptab) < size; i++, exceptab++)
1198     {
1199       unsigned int reason;
1200       unsigned int addr;
1201
1202       addr = bfd_get_32 (abfd, exceptab->e_addr.e_paddr);
1203       reason = bfd_get_8 (abfd, exceptab->e_reason);
1204       printf (_("  %02x     %02x "),
1205               (unsigned) bfd_get_8 (abfd, exceptab->e_lang), reason);
1206       if (reason == 0)
1207         xcoff32_print_symbol (data, addr);
1208       else
1209         printf (_("@%08x"), addr);
1210       putchar ('\n');
1211     }
1212   free (excp_data);
1213 }
1214
1215 /* Dump xcoff type-check section.  */
1216
1217 static void
1218 dump_xcoff32_typchk (bfd *abfd)
1219 {
1220   asection *sec;
1221   bfd_size_type size = 0;
1222   bfd_byte *data;
1223   unsigned int i;
1224
1225   sec = bfd_get_section_by_name (abfd, ".typchk");
1226
1227   if (sec == NULL)
1228     {
1229       printf (_("no .typchk section in file\n"));
1230       return;
1231     }
1232   size = bfd_get_section_size (sec);
1233   data = (bfd_byte *) xmalloc (size);
1234   bfd_get_section_contents (abfd, sec, data, 0, size);
1235
1236   printf (_("Type-check section:\n"));
1237   printf (_("offset    len  lang-id general-hash language-hash\n"));
1238   for (i = 0; i < size;)
1239     {
1240       unsigned int len;
1241
1242       len = bfd_get_16 (abfd, data + i);
1243       printf ("%08x: %-4u ", i, len);
1244       i += 2;
1245
1246       if (len == 10)
1247         {
1248           /* Expected format.  */
1249           printf ("%04x    %08x     %08x\n",
1250                   (unsigned) bfd_get_16 (abfd, data + i),
1251                   (unsigned) bfd_get_32 (abfd, data + i + 2),
1252                   (unsigned) bfd_get_32 (abfd, data + i + 2 + 4));
1253         }
1254       else
1255         {
1256           unsigned int j;
1257
1258           for (j = 0; j < len; j++)
1259             {
1260               if (j % 16 == 0)
1261                 printf ("\n    ");
1262               printf (" %02x", (unsigned char)data[i + j]);
1263             }
1264           putchar ('\n');
1265         }
1266       i += len;
1267     }
1268   free (data);
1269 }
1270
1271 /* Dump xcoff traceback tags section.  */
1272
1273 static void
1274 dump_xcoff32_tbtags (bfd *abfd,
1275                      const char *text, bfd_size_type text_size,
1276                      unsigned int text_start, unsigned int func_start)
1277 {
1278   unsigned int i;
1279
1280   if (func_start - text_start > text_size)
1281     {
1282       printf (_(" address beyond section size\n"));
1283       return;
1284     }
1285   for (i = func_start - text_start; i < text_size; i+= 4)
1286     if (bfd_get_32 (abfd, text + i) == 0)
1287       {
1288         unsigned int tb1;
1289         unsigned int tb2;
1290         unsigned int off;
1291
1292         printf (_(" tags at %08x\n"), i + 4);
1293         if (i + 8 >= text_size)
1294           goto truncated;
1295
1296         tb1 = bfd_get_32 (abfd, text + i + 4);
1297         tb2 = bfd_get_32 (abfd, text + i + 8);
1298         off = i + 12;
1299         printf (_(" version: %u, lang: %u, global_link: %u, is_eprol: %u, has_tboff: %u, int_proc: %u\n"),
1300                 (tb1 >> 24) & 0xff,
1301                 (tb1 >> 16) & 0xff,
1302                 (tb1 >> 15) & 1,
1303                 (tb1 >> 14) & 1,
1304                 (tb1 >> 13) & 1,
1305                 (tb1 >> 12) & 1);
1306         printf (_(" has_ctl: %u, tocless: %u, fp_pres: %u, log_abort: %u, int_hndl: %u\n"),
1307                 (tb1 >> 11) & 1,
1308                 (tb1 >> 10) & 1,
1309                 (tb1 >> 9) & 1,
1310                 (tb1 >> 8) & 1,
1311                 (tb1 >> 7) & 1);
1312         printf (_(" name_pres: %u, uses_alloca: %u, cl_dis_inv: %u, saves_cr: %u, saves_lr: %u\n"),
1313                 (tb1 >> 6) & 1,
1314                 (tb1 >> 5) & 1,
1315                 (tb1 >> 2) & 7,
1316                 (tb1 >> 1) & 1,
1317                 (tb1 >> 0) & 1);
1318         printf (_(" stores_bc: %u, fixup: %u, fpr_saved: %-2u, spare3: %u, gpr_saved: %-2u\n"),
1319                 (tb2 >> 31) & 1,
1320                 (tb2 >> 30) & 1,
1321                 (tb2 >> 24) & 63,
1322                 (tb2 >> 22) & 3,
1323                 (tb2 >> 16) & 63);
1324         printf (_(" fixparms: %-3u  floatparms: %-3u  parm_on_stk: %u\n"),
1325                 (tb2 >> 8) & 0xff,
1326                 (tb2 >> 1) & 0x7f,
1327                 (tb2 >> 0) & 1);
1328
1329         if (((tb2 >> 1) & 0x7fff) != 0)
1330           {
1331             unsigned int parminfo;
1332
1333             if (off >= text_size)
1334               goto truncated;
1335             parminfo = bfd_get_32 (abfd, text + off);
1336             off += 4;
1337             printf (_(" parminfo: 0x%08x\n"), parminfo);
1338           }
1339
1340         if ((tb1 >> 13) & 1)
1341           {
1342             unsigned int tboff;
1343
1344             if (off >= text_size)
1345               goto truncated;
1346             tboff = bfd_get_32 (abfd, text + off);
1347             off += 4;
1348             printf (_(" tb_offset: 0x%08x (start=0x%08x)\n"),
1349                     tboff, text_start + i - tboff);
1350           }
1351         if ((tb1 >> 7) & 1)
1352           {
1353             unsigned int hand_mask;
1354
1355             if (off >= text_size)
1356               goto truncated;
1357             hand_mask = bfd_get_32 (abfd, text + off);
1358             off += 4;
1359             printf (_(" hand_mask_offset: 0x%08x\n"), hand_mask);
1360           }
1361         if ((tb1 >> 11) & 1)
1362           {
1363             unsigned int ctl_info;
1364             unsigned int j;
1365
1366             if (off >= text_size)
1367               goto truncated;
1368             ctl_info = bfd_get_32 (abfd, text + off);
1369             off += 4;
1370             printf (_(" number of CTL anchors: %u\n"), ctl_info);
1371             for (j = 0; j < ctl_info; j++)
1372               {
1373                 if (off >= text_size)
1374                   goto truncated;
1375                 printf (_("  CTL[%u]: %08x\n"),
1376                           j, (unsigned)bfd_get_32 (abfd, text + off));
1377                 off += 4;
1378               }
1379           }
1380         if ((tb1 >> 6) & 1)
1381           {
1382             unsigned int name_len;
1383             unsigned int j;
1384
1385             if (off >= text_size)
1386               goto truncated;
1387             name_len = bfd_get_16 (abfd, text + off);
1388             off += 2;
1389             printf (_(" Name (len: %u): "), name_len);
1390             if (off + name_len >= text_size)
1391               {
1392                 printf (_("[truncated]\n"));
1393                 goto truncated;
1394               }
1395             for (j = 0; j < name_len; j++)
1396               if (ISPRINT (text[off + j]))
1397                 putchar (text[off + j]);
1398               else
1399                 printf ("[%02x]", (unsigned char)text[off + j]);
1400             putchar ('\n');
1401             off += name_len;
1402           }
1403         if ((tb1 >> 5) & 1)
1404           {
1405             if (off >= text_size)
1406               goto truncated;
1407             printf (_(" alloca reg: %u\n"),
1408                     (unsigned) bfd_get_8 (abfd, text + off));
1409             off++;
1410           }
1411         printf (_(" (end of tags at %08x)\n"), text_start + off);
1412         return;
1413       }
1414   printf (_(" no tags found\n"));
1415   return;
1416
1417  truncated:
1418   printf (_(" Truncated .text section\n"));
1419   return;
1420 }
1421
1422 static void
1423 dump_xcoff32_traceback (bfd *abfd, struct xcoff_dump *data)
1424 {
1425   unsigned int i;
1426   unsigned int scnum_text = -1;
1427   unsigned int text_vma;
1428   asection *text_sec;
1429   bfd_size_type text_size;
1430   char *text;
1431
1432   if (data->syms == NULL || data->sects == NULL)
1433     return;
1434
1435   /* Read text section.  */
1436   text_sec = bfd_get_section_by_name (abfd, ".text");
1437   if (text_sec == NULL)
1438     return;
1439   text_vma = bfd_get_section_vma (abfd, text_sec);
1440
1441   text_size = bfd_get_section_size (text_sec);
1442   text = (char *) xmalloc (text_size);
1443   bfd_get_section_contents (abfd, text_sec, text, 0, text_size);
1444
1445   for (i = 0; i < data->nscns; i++)
1446     if (data->sects[i].flags == STYP_TEXT)
1447       {
1448         scnum_text = i + 1;
1449         break;
1450       }
1451   if (scnum_text == (unsigned int)-1)
1452     return;
1453
1454   for (i = 0; i < data->nsyms; i++)
1455     {
1456       union xcoff32_symbol *s = &data->syms[i];
1457
1458       switch (s->sym.sclass)
1459         {
1460         case C_EXT:
1461         case C_HIDEXT:
1462         case C_WEAKEXT:
1463           if (s->sym.scnum == scnum_text
1464               && s->sym.numaux > 0)
1465             {
1466               union external_auxent *aux = &s[s->sym.numaux].aux;
1467
1468               unsigned int smtyp;
1469               unsigned int smclas;
1470
1471               smtyp = bfd_h_get_8 (abfd, aux->x_csect.x_smtyp);
1472               smclas = bfd_h_get_8 (abfd, aux->x_csect.x_smclas);
1473               if (SMTYP_SMTYP (smtyp) == XTY_LD
1474                   && (smclas == XMC_PR
1475                       || smclas == XMC_GL
1476                       || smclas == XMC_XO))
1477                 {
1478                   printf ("%08x: ", s->sym.val);
1479                   xcoff32_print_symbol (data, i);
1480                   putchar ('\n');
1481                   dump_xcoff32_tbtags (abfd, text, text_size,
1482                                        text_vma, s->sym.val);
1483                 }
1484             }
1485           break;
1486         default:
1487           break;
1488         }
1489       i += s->sym.numaux;
1490     }
1491   free (text);
1492 }
1493
1494 /* Dump the TOC symbols.  */
1495
1496 static void
1497 dump_xcoff32_toc (bfd *abfd, struct xcoff_dump *data)
1498 {
1499   unsigned int i;
1500   unsigned int nbr_ent;
1501   unsigned int size;
1502
1503   printf (_("TOC:\n"));
1504
1505   if (data->syms == NULL)
1506     return;
1507
1508   nbr_ent = 0;
1509   size = 0;
1510
1511   for (i = 0; i < data->nsyms; i++)
1512     {
1513       union xcoff32_symbol *s = &data->syms[i];
1514
1515       switch (s->sym.sclass)
1516         {
1517         case C_EXT:
1518         case C_HIDEXT:
1519         case C_WEAKEXT:
1520           if (s->sym.numaux > 0)
1521             {
1522               union external_auxent *aux = &s[s->sym.numaux].aux;
1523               unsigned int smclas;
1524               unsigned int ent_sz;
1525
1526               smclas = bfd_h_get_8 (abfd, aux->x_csect.x_smclas);
1527               if (smclas == XMC_TC
1528                   || smclas == XMC_TD
1529                   || smclas == XMC_TC0)
1530                 {
1531                   ent_sz = bfd_h_get_32 (abfd, aux->x_scn.x_scnlen);
1532                   printf ("%08x %08x ",
1533                           s->sym.val, ent_sz);
1534                   xcoff32_print_symbol (data, i);
1535                   putchar ('\n');
1536                   nbr_ent++;
1537                   size += ent_sz;
1538                 }
1539             }
1540           break;
1541         default:
1542           break;
1543         }
1544       i += s->sym.numaux;
1545     }
1546   printf (_("Nbr entries: %-8u Size: %08x (%u)\n"),
1547           nbr_ent, size, size);
1548 }
1549
1550 /* Handle an rs6000 xcoff file.  */
1551
1552 static void
1553 dump_xcoff32 (bfd *abfd, struct external_filehdr *fhdr)
1554 {
1555   struct xcoff_dump data;
1556
1557   data.nscns = bfd_h_get_16 (abfd, fhdr->f_nscns);
1558   data.symptr = bfd_h_get_32 (abfd, fhdr->f_symptr);
1559   data.nsyms = bfd_h_get_32 (abfd, fhdr->f_nsyms);
1560   data.opthdr = bfd_h_get_16 (abfd, fhdr->f_opthdr);
1561   data.sects = NULL;
1562   data.syms = NULL;
1563   data.strings = NULL;
1564   data.strings_size = 0;
1565
1566   if (options[OPT_FILE_HEADER].selected)
1567     dump_xcoff32_file_header (abfd, fhdr, &data);
1568
1569   if (options[OPT_AOUT].selected)
1570     dump_xcoff32_aout_header (abfd, &data);
1571
1572   if (options[OPT_SYMS].selected
1573       || options[OPT_RELOCS].selected
1574       || options[OPT_LINENO].selected
1575       || options[OPT_TRACEBACK].selected)
1576     xcoff32_read_sections (abfd, &data);
1577
1578   if (options[OPT_SECTIONS].selected)
1579     dump_xcoff32_sections_header (abfd, &data);
1580
1581   if (options[OPT_SYMS].selected
1582       || options[OPT_RELOCS].selected
1583       || options[OPT_LINENO].selected
1584       || options[OPT_EXCEPT].selected
1585       || options[OPT_TRACEBACK].selected
1586       || options[OPT_TOC].selected)
1587     xcoff32_read_symbols (abfd, &data);
1588
1589   if (options[OPT_SYMS].selected)
1590     dump_xcoff32_symbols (abfd, &data);
1591
1592   if (options[OPT_RELOCS].selected)
1593     dump_xcoff32_relocs (abfd, &data);
1594
1595   if (options[OPT_LINENO].selected)
1596     dump_xcoff32_lineno (abfd, &data);
1597
1598   if (options[OPT_LOADER].selected)
1599     dump_xcoff32_loader (abfd);
1600
1601   if (options[OPT_EXCEPT].selected)
1602     dump_xcoff32_except (abfd, &data);
1603
1604   if (options[OPT_TYPCHK].selected)
1605     dump_xcoff32_typchk (abfd);
1606
1607   if (options[OPT_TRACEBACK].selected)
1608     dump_xcoff32_traceback (abfd, &data);
1609
1610   if (options[OPT_TOC].selected)
1611     dump_xcoff32_toc (abfd, &data);
1612
1613   free (data.sects);
1614   free (data.strings);
1615   free (data.syms);
1616 }
1617
1618 /* Dump ABFD (according to the options[] array).  */
1619
1620 static void
1621 xcoff_dump (bfd *abfd)
1622 {
1623   struct external_filehdr fhdr;
1624   unsigned short magic;
1625
1626   /* Read file header.  */
1627   if (bfd_seek (abfd, 0, SEEK_SET) != 0
1628       || bfd_bread (&fhdr, sizeof (fhdr), abfd) != sizeof (fhdr))
1629     {
1630       non_fatal (_("cannot read header"));
1631       return;
1632     }
1633
1634   /* Decoding.  We don't use the bfd/coff function to get all the fields.  */
1635   magic = bfd_h_get_16 (abfd, fhdr.f_magic);
1636   if (options[OPT_FILE_HEADER].selected)
1637     {
1638       printf (_("File header:\n"));
1639       printf (_("  magic:         0x%04x (0%04o)  "), magic, magic);
1640       switch (magic)
1641         {
1642         case U802WRMAGIC:
1643           printf (_("(WRMAGIC: writable text segments)"));
1644           break;
1645         case U802ROMAGIC:
1646           printf (_("(ROMAGIC: readonly sharablee text segments)"));
1647           break;
1648         case U802TOCMAGIC:
1649           printf (_("(TOCMAGIC: readonly text segments and TOC)"));
1650           break;
1651         default:
1652           printf (_("unknown magic"));
1653         }
1654       putchar ('\n');
1655     }
1656   if (magic == U802ROMAGIC || magic == U802WRMAGIC || magic == U802TOCMAGIC)
1657     dump_xcoff32 (abfd, &fhdr);
1658   else
1659     printf (_("  Unhandled magic\n"));
1660 }
1661
1662 /* Vector for xcoff.  */
1663
1664 const struct objdump_private_desc objdump_private_desc_xcoff =
1665   {
1666     xcoff_help,
1667     xcoff_filter,
1668     xcoff_dump,
1669     options
1670   };