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