1/* od-xcoff.c -- dump information about an xcoff object file.
2   Copyright (C) 2011-2017 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 (RTB),
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 (TRL),
312    RTYPE_ENTRY (TRLA),
313    RTYPE_ENTRY (RRTBI),
314    RTYPE_ENTRY (RRTBA),
315    RTYPE_ENTRY (CAI),
316    RTYPE_ENTRY (CREL),
317    RTYPE_ENTRY (RBA),
318    RTYPE_ENTRY (RBAC),
319    RTYPE_ENTRY (RBR),
320    RTYPE_ENTRY (RBRC),
321    RTYPE_ENTRY (TLS),
322    RTYPE_ENTRY (TLS_IE),
323    RTYPE_ENTRY (TLS_LD),
324    RTYPE_ENTRY (TLS_LE),
325    RTYPE_ENTRY (TLSM),
326    RTYPE_ENTRY (TLSML),
327    RTYPE_ENTRY (TOCU),
328    RTYPE_ENTRY (TOCL),
329    { 0, NULL }
330  };
331
332/* Simplified section header.  */
333struct xcoff32_section
334{
335  /* NUL terminated name.  */
336  char name[9];
337
338  /* Section flags.  */
339  unsigned int flags;
340
341  /* Offsets in file.  */
342  ufile_ptr scnptr;
343  ufile_ptr relptr;
344  ufile_ptr lnnoptr;
345
346  /* Number of relocs and line numbers.  */
347  unsigned int nreloc;
348  unsigned int nlnno;
349};
350
351/* Simplified symbol.  */
352
353union xcoff32_symbol
354{
355  union external_auxent aux;
356
357  struct sym
358  {
359    /* Pointer to the NUL-terminated name.  */
360    char *name;
361
362    /* XCOFF symbol fields.  */
363    unsigned int val;
364    unsigned short scnum;
365    unsigned short ntype;
366    unsigned char sclass;
367    unsigned char numaux;
368
369    /* Buffer in case the name is local.  */
370    union
371    {
372      char name[9];
373      unsigned int off;
374    } raw;
375  } sym;
376};
377
378/* Important fields to dump the file.  */
379
380struct xcoff_dump
381{
382  /* From file header.  */
383  unsigned short nscns;
384  unsigned int symptr;
385  unsigned int nsyms;
386  unsigned short opthdr;
387
388  /* Sections.  */
389  struct xcoff32_section *sects;
390
391  /* Symbols.  */
392  union xcoff32_symbol *syms;
393  char *strings;
394  unsigned int strings_size;
395};
396
397/* Print a symbol (if possible).  */
398
399static void
400xcoff32_print_symbol (struct xcoff_dump *data, unsigned int symndx)
401{
402  if (data->syms != NULL
403      && symndx < data->nsyms
404      && data->syms[symndx].sym.name != NULL)
405    printf ("%s", data->syms[symndx].sym.name);
406  else
407    printf ("%u", symndx);
408}
409
410/* Dump the file header.  */
411
412static void
413dump_xcoff32_file_header (bfd *abfd, struct external_filehdr *fhdr,
414                          struct xcoff_dump *data)
415{
416  unsigned int timdat = bfd_h_get_32 (abfd, fhdr->f_timdat);
417  unsigned short flags = bfd_h_get_16 (abfd, fhdr->f_flags);
418
419  printf (_("  nbr sections:  %d\n"), data->nscns);
420  printf (_("  time and date: 0x%08x  - "), timdat);
421  if (timdat == 0)
422    printf (_("not set\n"));
423  else
424    {
425      /* Not correct on all platforms, but works on unix.  */
426      time_t t = timdat;
427      fputs (ctime (&t), stdout);
428    }
429  printf (_("  symbols off:   0x%08x\n"), data->symptr);
430  printf (_("  nbr symbols:   %d\n"), data->nsyms);
431  printf (_("  opt hdr sz:    %d\n"), data->opthdr);
432  printf (_("  flags:         0x%04x "), flags);
433  dump_flags (f_flag_xlat, flags);
434  putchar ('\n');
435}
436
437/* Dump the a.out header.  */
438
439static void
440dump_xcoff32_aout_header (bfd *abfd, struct xcoff_dump *data)
441{
442  AOUTHDR auxhdr;
443  unsigned short magic;
444  unsigned int sz = data->opthdr;
445
446  printf (_("Auxiliary header:\n"));
447  if (data->opthdr == 0)
448    {
449      printf (_("  No aux header\n"));
450      return;
451    }
452  if (data->opthdr > sizeof (auxhdr))
453    {
454      printf (_("warning: optional header size too large (> %d)\n"),
455              (int)sizeof (auxhdr));
456      sz = sizeof (auxhdr);
457    }
458  if (bfd_bread (&auxhdr, sz, abfd) != sz)
459    {
460      non_fatal (_("cannot read auxhdr"));
461      return;
462    }
463
464  magic = bfd_h_get_16 (abfd, auxhdr.magic);
465  /* We don't translate these strings as they are fields name.  */
466  printf ("  o_mflag (magic): 0x%04x 0%04o\n", magic, magic);
467  printf ("  o_vstamp:        0x%04x\n",
468          (unsigned short)bfd_h_get_16 (abfd, auxhdr.vstamp));
469  printf ("  o_tsize:         0x%08x\n",
470          (unsigned int)bfd_h_get_32 (abfd, auxhdr.tsize));
471  printf ("  o_dsize:         0x%08x\n",
472          (unsigned int)bfd_h_get_32 (abfd, auxhdr.dsize));
473  printf ("  o_entry:         0x%08x\n",
474          (unsigned int)bfd_h_get_32 (abfd, auxhdr.entry));
475  printf ("  o_text_start:    0x%08x\n",
476          (unsigned int)bfd_h_get_32 (abfd, auxhdr.text_start));
477  printf ("  o_data_start:    0x%08x\n",
478          (unsigned int)bfd_h_get_32 (abfd, auxhdr.data_start));
479  if (sz == offsetof (AOUTHDR, o_toc))
480    return;
481  printf ("  o_toc:           0x%08x\n",
482          (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_toc));
483  printf ("  o_snentry:       0x%04x\n",
484          (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snentry));
485  printf ("  o_sntext:        0x%04x\n",
486          (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sntext));
487  printf ("  o_sndata:        0x%04x\n",
488          (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sndata));
489  printf ("  o_sntoc:         0x%04x\n",
490          (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sntoc));
491  printf ("  o_snloader:      0x%04x\n",
492          (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snloader));
493  printf ("  o_snbss:         0x%04x\n",
494          (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snbss));
495  printf ("  o_algntext:      %u\n",
496          (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_algntext));
497  printf ("  o_algndata:      %u\n",
498          (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_algndata));
499  printf ("  o_modtype:       0x%04x",
500          (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_modtype));
501  if (ISPRINT (auxhdr.o_modtype[0]) && ISPRINT (auxhdr.o_modtype[1]))
502    printf (" (%c%c)", auxhdr.o_modtype[0], auxhdr.o_modtype[1]);
503  putchar ('\n');
504  printf ("  o_cputype:       0x%04x\n",
505          (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_cputype));
506  printf ("  o_maxstack:      0x%08x\n",
507          (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_maxstack));
508  printf ("  o_maxdata:       0x%08x\n",
509          (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_maxdata));
510#if 0
511  printf ("  o_debugger:      0x%08x\n",
512          (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_debugger));
513#endif
514}
515
516/* Dump the sections header.  */
517
518static void
519dump_xcoff32_sections_header (bfd *abfd, struct xcoff_dump *data)
520{
521  unsigned int i;
522  unsigned int off;
523
524  off = sizeof (struct external_filehdr) + data->opthdr;
525  printf (_("Section headers (at %u+%u=0x%08x to 0x%08x):\n"),
526          (unsigned int)sizeof (struct external_filehdr), data->opthdr, off,
527          off + (unsigned int)sizeof (struct external_scnhdr) * data->nscns);
528  if (data->nscns == 0)
529    {
530      printf (_("  No section header\n"));
531      return;
532    }
533  if (bfd_seek (abfd, off, SEEK_SET) != 0)
534    {
535      non_fatal (_("cannot read section header"));
536      return;
537    }
538  /* We don't translate this string as it consists in fields name.  */
539  printf (" # Name     paddr    vaddr    size     scnptr   relptr   lnnoptr  nrel  nlnno\n");
540  for (i = 0; i < data->nscns; i++)
541    {
542      struct external_scnhdr scn;
543      unsigned int flags;
544
545      if (bfd_bread (&scn, sizeof (scn), abfd) != sizeof (scn))
546        {
547          non_fatal (_("cannot read section header"));
548          return;
549        }
550      flags = bfd_h_get_32 (abfd, scn.s_flags);
551      printf ("%2d %-8.8s %08x %08x %08x %08x %08x %08x %-5d %-5d\n",
552              i + 1, scn.s_name,
553              (unsigned int)bfd_h_get_32 (abfd, scn.s_paddr),
554              (unsigned int)bfd_h_get_32 (abfd, scn.s_vaddr),
555              (unsigned int)bfd_h_get_32 (abfd, scn.s_size),
556              (unsigned int)bfd_h_get_32 (abfd, scn.s_scnptr),
557              (unsigned int)bfd_h_get_32 (abfd, scn.s_relptr),
558              (unsigned int)bfd_h_get_32 (abfd, scn.s_lnnoptr),
559              (unsigned int)bfd_h_get_16 (abfd, scn.s_nreloc),
560              (unsigned int)bfd_h_get_16 (abfd, scn.s_nlnno));
561      printf (_("            Flags: %08x "), flags);
562
563      if (~flags == 0)
564        {
565          /* Stripped executable ?  */
566          putchar ('\n');
567        }
568      else if (flags & STYP_OVRFLO)
569        printf (_("overflow - nreloc: %u, nlnno: %u\n"),
570                (unsigned int)bfd_h_get_32 (abfd, scn.s_paddr),
571                (unsigned int)bfd_h_get_32 (abfd, scn.s_vaddr));
572      else
573        {
574          dump_flags (s_flag_xlat, flags);
575          putchar ('\n');
576        }
577    }
578}
579
580/* Read section table.  */
581
582static void
583xcoff32_read_sections (bfd *abfd, struct xcoff_dump *data)
584{
585  int i;
586
587  if (bfd_seek (abfd, sizeof (struct external_filehdr) + data->opthdr,
588                SEEK_SET) != 0)
589    {
590      non_fatal (_("cannot read section headers"));
591      return;
592    }
593
594  data->sects = xmalloc (data->nscns * sizeof (struct xcoff32_section));
595  for (i = 0; i < data->nscns; i++)
596    {
597      struct external_scnhdr scn;
598      struct xcoff32_section *s = &data->sects[i];
599
600      if (bfd_bread (&scn, sizeof (scn), abfd) != sizeof (scn))
601        {
602          non_fatal (_("cannot read section header"));
603          free (data->sects);
604          data->sects = NULL;
605          return;
606        }
607      memcpy (s->name, scn.s_name, 8);
608      s->name[8] = 0;
609      s->flags = bfd_h_get_32 (abfd, scn.s_flags);
610
611      s->scnptr = bfd_h_get_32 (abfd, scn.s_scnptr);
612      s->relptr = bfd_h_get_32 (abfd, scn.s_relptr);
613      s->lnnoptr = bfd_h_get_32 (abfd, scn.s_lnnoptr);
614
615      s->nreloc = bfd_h_get_16 (abfd, scn.s_nreloc);
616      s->nlnno = bfd_h_get_16 (abfd, scn.s_nlnno);
617
618      if (s->flags == STYP_OVRFLO)
619        {
620          if (s->nreloc > 0 && s->nreloc <= data->nscns)
621            data->sects[s->nreloc - 1].nreloc =
622              bfd_h_get_32 (abfd, scn.s_paddr);
623          if (s->nlnno > 0 && s->nlnno <= data->nscns)
624            data->sects[s->nlnno - 1].nlnno =
625              bfd_h_get_32 (abfd, scn.s_vaddr);
626        }
627    }
628}
629
630/* Read symbols.  */
631
632static void
633xcoff32_read_symbols (bfd *abfd, struct xcoff_dump *data)
634{
635  unsigned int i;
636  char stsz_arr[4];
637  unsigned int stptr;
638
639  if (data->nsyms == 0)
640    return;
641
642  stptr = data->symptr
643    + data->nsyms * (unsigned)sizeof (struct external_syment);
644
645  /* Read string table.  */
646  if (bfd_seek (abfd, stptr, SEEK_SET) != 0
647      || bfd_bread (&stsz_arr, sizeof (stsz_arr), abfd) != sizeof (stsz_arr))
648    {
649      non_fatal (_("cannot read strings table length"));
650      data->strings_size = 0;
651    }
652  else
653    {
654      data->strings_size = bfd_h_get_32 (abfd, stsz_arr);
655      if (data->strings_size > sizeof (stsz_arr))
656        {
657          unsigned int remsz = data->strings_size - sizeof (stsz_arr);
658
659          data->strings = xmalloc (data->strings_size);
660
661          memcpy (data->strings, stsz_arr, sizeof (stsz_arr));
662          if (bfd_bread (data->strings + sizeof (stsz_arr), remsz, abfd)
663              != remsz)
664            {
665              non_fatal (_("cannot read strings table"));
666              goto clean;
667            }
668        }
669    }
670
671  if (bfd_seek (abfd, data->symptr, SEEK_SET) != 0)
672    {
673      non_fatal (_("cannot read symbol table"));
674      goto clean;
675    }
676
677  data->syms = (union xcoff32_symbol *)
678    xmalloc (data->nsyms * sizeof (union xcoff32_symbol));
679
680  for (i = 0; i < data->nsyms; i++)
681    {
682      struct external_syment sym;
683      int j;
684      union xcoff32_symbol *s = &data->syms[i];
685
686      if (bfd_bread (&sym, sizeof (sym), abfd) != sizeof (sym))
687        {
688          non_fatal (_("cannot read symbol entry"));
689          goto clean;
690        }
691
692      s->sym.val = bfd_h_get_32 (abfd, sym.e_value);
693      s->sym.scnum = bfd_h_get_16 (abfd, sym.e_scnum);
694      s->sym.ntype = bfd_h_get_16 (abfd, sym.e_type);
695      s->sym.sclass = bfd_h_get_8 (abfd, sym.e_sclass);
696      s->sym.numaux = bfd_h_get_8 (abfd, sym.e_numaux);
697
698      if (sym.e.e_name[0])
699        {
700          memcpy (s->sym.raw.name, sym.e.e_name, sizeof (sym.e.e_name));
701          s->sym.raw.name[8] = 0;
702          s->sym.name = s->sym.raw.name;
703        }
704      else
705        {
706          unsigned int soff = bfd_h_get_32 (abfd, sym.e.e.e_offset);
707
708          if ((s->sym.sclass & DBXMASK) == 0 && soff < data->strings_size)
709            s->sym.name = data->strings + soff;
710          else
711            {
712              s->sym.name = NULL;
713              s->sym.raw.off = soff;
714            }
715        }
716
717      for (j = 0; j < s->sym.numaux; j++, i++)
718        {
719           if (bfd_bread (&s[j + 1].aux,
720                          sizeof (union external_auxent), abfd)
721               != sizeof (union external_auxent))
722            {
723              non_fatal (_("cannot read symbol aux entry"));
724              goto clean;
725            }
726        }
727    }
728  return;
729 clean:
730  free (data->syms);
731  data->syms = NULL;
732  free (data->strings);
733  data->strings = NULL;
734}
735
736/* Dump xcoff symbols.  */
737
738static void
739dump_xcoff32_symbols (bfd *abfd, struct xcoff_dump *data)
740{
741  unsigned int i;
742  asection *debugsec;
743  char *debug = NULL;
744
745  printf (_("Symbols table (strtable at 0x%08x)"),
746          data->symptr
747          + data->nsyms * (unsigned)sizeof (struct external_syment));
748  if (data->nsyms == 0 || data->syms == NULL)
749    {
750      printf (_(":\n  No symbols\n"));
751      return;
752    }
753
754  /* Read strings table.  */
755  if (data->strings_size == 0)
756    printf (_(" (no strings):\n"));
757  else
758    printf (_(" (strings size: %08x):\n"), data->strings_size);
759
760  /* Read debug section.  */
761  debugsec = bfd_get_section_by_name (abfd, ".debug");
762  if (debugsec != NULL)
763    {
764      bfd_size_type size;
765
766      size = bfd_get_section_size (debugsec);
767      debug = (char *) xmalloc (size);
768      bfd_get_section_contents (abfd, debugsec, debug, 0, size);
769    }
770
771  /* Translators: 'sc' is for storage class, 'off' for offset.  */
772  printf (_("  # sc         value    section  type aux name/off\n"));
773  for (i = 0; i < data->nsyms; i++)
774    {
775      union xcoff32_symbol *s = &data->syms[i];
776      int j;
777
778      printf ("%3u ", i);
779      dump_value (sc_xlat, s->sym.sclass, 10);
780      printf (" %08x ", s->sym.val);
781      if (s->sym.scnum > 0 && s->sym.scnum <= data->nscns)
782        {
783          if (data->sects != NULL)
784            printf ("%-8s", data->sects[s->sym.scnum - 1].name);
785          else
786            printf ("%-8u", s->sym.scnum);
787        }
788      else
789        switch ((signed short)s->sym.scnum)
790          {
791          case N_DEBUG:
792            printf ("N_DEBUG ");
793            break;
794          case N_ABS:
795            printf ("N_ABS   ");
796            break;
797          case N_UNDEF:
798            printf ("N_UNDEF ");
799            break;
800          default:
801            printf ("(%04x)  ", s->sym.scnum);
802          }
803      printf (" %04x %3u ", s->sym.ntype, s->sym.numaux);
804      if (s->sym.name != NULL)
805        printf ("%s", s->sym.name);
806      else
807        {
808          if ((s->sym.sclass & DBXMASK) != 0 && debug != NULL)
809            printf ("%s", debug + s->sym.raw.off);
810          else
811            printf ("%08x", s->sym.raw.off);
812        }
813      putchar ('\n');
814
815      for (j = 0; j < s->sym.numaux; j++, i++)
816        {
817          union external_auxent *aux = &s[j + 1].aux;
818
819          printf (" %3u ", i + 1);
820          switch (s->sym.sclass)
821            {
822            case C_STAT:
823              /* Section length, number of relocs and line number.  */
824              printf (_("  scnlen: %08x  nreloc: %-6u  nlinno: %-6u\n"),
825                      (unsigned)bfd_h_get_32 (abfd, aux->x_scn.x_scnlen),
826                      (unsigned)bfd_h_get_16 (abfd, aux->x_scn.x_nreloc),
827                      (unsigned)bfd_h_get_16 (abfd, aux->x_scn.x_nlinno));
828              break;
829            case C_DWARF:
830              /* Section length and number of relocs.  */
831              printf (_("  scnlen: %08x  nreloc: %-6u\n"),
832                      (unsigned)bfd_h_get_32 (abfd, aux->x_scn.x_scnlen),
833                      (unsigned)bfd_h_get_16 (abfd, aux->x_scn.x_nreloc));
834              break;
835            case C_EXT:
836            case C_WEAKEXT:
837            case C_HIDEXT:
838              if (j == 0 && s->sym.numaux > 1)
839                {
840                  /* Function aux entry  (Do not translate).  */
841                  printf ("  exptr: %08x fsize: %08x lnnoptr: %08x endndx: %u\n",
842                          (unsigned)bfd_h_get_32 (abfd, aux->x_sym.x_tagndx),
843                          (unsigned)bfd_h_get_32
844                            (abfd, aux->x_sym.x_misc.x_fsize),
845                          (unsigned)bfd_h_get_32
846                            (abfd, aux->x_sym.x_fcnary.x_fcn.x_lnnoptr),
847                          (unsigned)bfd_h_get_32
848                            (abfd, aux->x_sym.x_fcnary.x_fcn.x_endndx));
849                }
850              else if (j == 1 || (j == 0 && s->sym.numaux == 1))
851                {
852                  /* csect aux entry.  */
853                  unsigned char smtyp;
854                  unsigned int scnlen;
855
856                  smtyp = bfd_h_get_8 (abfd, aux->x_csect.x_smtyp);
857                  scnlen = bfd_h_get_32 (abfd, aux->x_csect.x_scnlen);
858
859                  if (smtyp == XTY_LD)
860                    printf ("  scnsym: %-8u", scnlen);
861                  else
862                    printf ("  scnlen: %08x", scnlen);
863                  printf (" h: parm=%08x sn=%04x al: 2**%u",
864                          (unsigned)bfd_h_get_32 (abfd, aux->x_csect.x_parmhash),
865                          (unsigned)bfd_h_get_16 (abfd, aux->x_csect.x_snhash),
866                          SMTYP_ALIGN (smtyp));
867                  printf (" typ: ");
868                  dump_value (smtyp_xlat, SMTYP_SMTYP (smtyp), 2);
869                  printf (" cl: ");
870                  dump_value
871                    (smclas_xlat,
872                     (unsigned)bfd_h_get_8 (abfd, aux->x_csect.x_smclas), 6);
873                  putchar ('\n');
874                }
875              else
876                /* Do not translate - generic field name.  */
877                printf ("aux\n");
878              break;
879            case C_FILE:
880              {
881                unsigned int off;
882
883                printf (" ftype: %02x ",
884                        (unsigned)bfd_h_get_8 (abfd, aux->x_file.x_ftype));
885                if (aux->x_file.x_n.x_fname[0] != 0)
886                  printf ("fname: %.14s", aux->x_file.x_n.x_fname);
887                else
888                  {
889                    off = (unsigned)bfd_h_get_32
890                      (abfd, aux->x_file.x_n.x_n.x_offset);
891                    if (data->strings != NULL && off < data->strings_size)
892                      printf (" %s", data->strings + off);
893                    else
894                      printf (_("offset: %08x"), off);
895                  }
896                putchar ('\n');
897              }
898              break;
899            case C_BLOCK:
900            case C_FCN:
901              printf ("  lnno: %u\n",
902                      (unsigned)bfd_h_get_16
903                      (abfd, aux->x_sym.x_misc.x_lnsz.x_lnno));
904              break;
905            default:
906              /* Do not translate - generic field name.  */
907              printf ("aux\n");
908              break;
909            }
910        }
911
912    }
913  free (debug);
914}
915
916/* Dump xcoff relocation entries.  */
917
918static void
919dump_xcoff32_relocs (bfd *abfd, struct xcoff_dump *data)
920{
921  unsigned int i;
922
923  if (data->sects == NULL)
924    {
925      non_fatal (_("cannot read section headers"));
926      return;
927    }
928
929  for (i = 0; i < data->nscns; i++)
930    {
931      struct xcoff32_section *sect = &data->sects[i];
932      unsigned int nrel = sect->nreloc;
933      unsigned int j;
934
935      if (nrel == 0)
936        continue;
937      printf (_("Relocations for %s (%u)\n"), sect->name, nrel);
938      if (bfd_seek (abfd, sect->relptr, SEEK_SET) != 0)
939        {
940          non_fatal (_("cannot read relocations"));
941          continue;
942        }
943      /* Do not translate: fields name.  */
944      printf ("vaddr    sgn mod sz type  symndx symbol\n");
945      for (j = 0; j < nrel; j++)
946        {
947          struct external_reloc rel;
948          unsigned char rsize;
949          unsigned int symndx;
950
951          if (bfd_bread (&rel, sizeof (rel), abfd) != sizeof (rel))
952            {
953              non_fatal (_("cannot read relocation entry"));
954              return;
955            }
956          rsize = bfd_h_get_8 (abfd, rel.r_size);
957          printf ("%08x  %c   %c  %-2u ",
958                  (unsigned int)bfd_h_get_32 (abfd, rel.r_vaddr),
959                  rsize & 0x80 ? 'S' : 'U',
960                  rsize & 0x40 ? 'm' : ' ',
961                  (rsize & 0x3f) + 1);
962          dump_value (rtype_xlat, bfd_h_get_8 (abfd, rel.r_type), 6);
963          symndx = bfd_h_get_32 (abfd, rel.r_symndx);
964          printf ("%-6u ", symndx);
965          xcoff32_print_symbol (data, symndx);
966          putchar ('\n');
967        }
968      putchar ('\n');
969    }
970}
971
972/* Dump xcoff line number entries.  */
973
974static void
975dump_xcoff32_lineno (bfd *abfd, struct xcoff_dump *data)
976{
977  unsigned int i;
978
979  if (data->sects == NULL)
980    {
981      non_fatal (_("cannot read section headers"));
982      return;
983    }
984
985  for (i = 0; i < data->nscns; i++)
986    {
987      struct xcoff32_section *sect = &data->sects[i];
988      unsigned int nlnno = sect->nlnno;
989      unsigned int j;
990
991      if (nlnno == 0)
992        continue;
993      printf (_("Line numbers for %s (%u)\n"), sect->name, nlnno);
994      if (bfd_seek (abfd, sect->lnnoptr, SEEK_SET) != 0)
995        {
996          non_fatal (_("cannot read line numbers"));
997          continue;
998        }
999      /* Line number, symbol index and physical address.  */
1000      printf (_("lineno  symndx/paddr\n"));
1001      for (j = 0; j < nlnno; j++)
1002        {
1003          struct external_lineno ln;
1004          unsigned int no;
1005
1006          if (bfd_bread (&ln, sizeof (ln), abfd) != sizeof (ln))
1007            {
1008              non_fatal (_("cannot read line number entry"));
1009              return;
1010            }
1011          no = bfd_h_get_16 (abfd, ln.l_lnno);
1012          printf (" %-6u ", no);
1013          if (no == 0)
1014            {
1015              unsigned int symndx = bfd_h_get_32 (abfd, ln.l_addr.l_symndx);
1016              xcoff32_print_symbol (data, symndx);
1017            }
1018          else
1019            printf ("0x%08x",
1020                    (unsigned int)bfd_h_get_32 (abfd, ln.l_addr.l_paddr));
1021          putchar ('\n');
1022        }
1023    }
1024}
1025
1026/* Dump xcoff loader section.  */
1027
1028static void
1029dump_xcoff32_loader (bfd *abfd)
1030{
1031  asection *loader;
1032  bfd_size_type size = 0;
1033  struct external_ldhdr *lhdr;
1034  struct external_ldsym *ldsym;
1035  struct external_ldrel *ldrel;
1036  bfd_byte *ldr_data;
1037  unsigned int version;
1038  unsigned int ndsyms;
1039  unsigned int ndrel;
1040  unsigned int stlen;
1041  unsigned int stoff;
1042  unsigned int impoff;
1043  unsigned int nimpid;
1044  unsigned int i;
1045  const char *p;
1046
1047  loader = bfd_get_section_by_name (abfd, ".loader");
1048
1049  if (loader == NULL)
1050    {
1051      printf (_("no .loader section in file\n"));
1052      return;
1053    }
1054  size = bfd_get_section_size (loader);
1055  if (size < sizeof (*lhdr))
1056    {
1057      printf (_("section .loader is too short\n"));
1058      return;
1059    }
1060
1061  ldr_data = (bfd_byte *) xmalloc (size);
1062  bfd_get_section_contents (abfd, loader, ldr_data, 0, size);
1063  lhdr = (struct external_ldhdr *)ldr_data;
1064  printf (_("Loader header:\n"));
1065  version = bfd_h_get_32 (abfd, lhdr->l_version);
1066  printf (_("  version:           %u\n"), version);
1067  if (version != 1)
1068    {
1069      printf (_(" Unhandled version\n"));
1070      free (ldr_data);
1071      return;
1072    }
1073  ndsyms = bfd_h_get_32 (abfd, lhdr->l_nsyms);
1074  printf (_("  nbr symbols:       %u\n"), ndsyms);
1075  ndrel = bfd_h_get_32 (abfd, lhdr->l_nreloc);
1076  printf (_("  nbr relocs:        %u\n"), ndrel);
1077  /* Import string table length.  */
1078  printf (_("  import strtab len: %u\n"),
1079          (unsigned) bfd_h_get_32 (abfd, lhdr->l_istlen));
1080  nimpid = bfd_h_get_32 (abfd, lhdr->l_nimpid);
1081  printf (_("  nbr import files:  %u\n"), nimpid);
1082  impoff = bfd_h_get_32 (abfd, lhdr->l_impoff);
1083  printf (_("  import file off:   %u\n"), impoff);
1084  stlen = bfd_h_get_32 (abfd, lhdr->l_stlen);
1085  printf (_("  string table len:  %u\n"), stlen);
1086  stoff = bfd_h_get_32 (abfd, lhdr->l_stoff);
1087  printf (_("  string table off:  %u\n"), stoff);
1088
1089  ldsym = (struct external_ldsym *)(ldr_data + sizeof (*lhdr));
1090  printf (_("Dynamic symbols:\n"));
1091  /* Do not translate: field names.  */
1092  printf ("     # value     sc IFEW ty class file  pa name\n");
1093  for (i = 0; i < ndsyms; i++, ldsym++)
1094    {
1095      unsigned char smtype;
1096
1097      printf (_("  %4u %08x %3u "), i,
1098              (unsigned)bfd_h_get_32 (abfd, ldsym->l_value),
1099              (unsigned)bfd_h_get_16 (abfd, ldsym->l_scnum));
1100      smtype = bfd_h_get_8 (abfd, ldsym->l_smtype);
1101      putchar (smtype & 0x40 ? 'I' : ' ');
1102      putchar (smtype & 0x20 ? 'F' : ' ');
1103      putchar (smtype & 0x10 ? 'E' : ' ');
1104      putchar (smtype & 0x08 ? 'W' : ' ');
1105      putchar (' ');
1106      dump_value (smtyp_xlat, SMTYP_SMTYP (smtype), 2);
1107      putchar (' ');
1108      dump_value
1109        (smclas_xlat, (unsigned)bfd_h_get_8 (abfd, ldsym->l_smclas), 6);
1110      printf (_(" %3u %3u "),
1111              (unsigned)bfd_h_get_32 (abfd, ldsym->l_ifile),
1112              (unsigned)bfd_h_get_32 (abfd, ldsym->l_parm));
1113      if (ldsym->_l._l_name[0] != 0)
1114        printf ("%-.8s", ldsym->_l._l_name);
1115      else
1116        {
1117          unsigned int off = bfd_h_get_32 (abfd, ldsym->_l._l_l._l_offset);
1118          if (off > stlen)
1119            printf (_("(bad offset: %u)"), off);
1120          else
1121            printf ("%s", ldr_data + stoff + off);
1122        }
1123      putchar ('\n');
1124    }
1125
1126  printf (_("Dynamic relocs:\n"));
1127  /* Do not translate fields name.  */
1128  printf ("  vaddr    sec    sz typ   sym\n");
1129  ldrel = (struct external_ldrel *)(ldr_data + sizeof (*lhdr)
1130                                    + ndsyms * sizeof (*ldsym));
1131  for (i = 0; i < ndrel; i++, ldrel++)
1132    {
1133      unsigned int rsize;
1134      unsigned int rtype;
1135      unsigned int symndx;
1136
1137      rsize = bfd_h_get_8 (abfd, ldrel->l_rtype + 0);
1138      rtype = bfd_h_get_8 (abfd, ldrel->l_rtype + 1);
1139
1140      printf ("  %08x %3u %c%c %2u ",
1141              (unsigned)bfd_h_get_32 (abfd, ldrel->l_vaddr),
1142              (unsigned)bfd_h_get_16 (abfd, ldrel->l_rsecnm),
1143              rsize & 0x80 ? 'S' : 'U',
1144              rsize & 0x40 ? 'm' : ' ',
1145              (rsize & 0x3f) + 1);
1146      dump_value (rtype_xlat, rtype, 6);
1147      symndx = bfd_h_get_32 (abfd, ldrel->l_symndx);
1148      switch (symndx)
1149        {
1150        case 0:
1151          printf (".text");
1152          break;
1153        case 1:
1154          printf (".data");
1155          break;
1156        case 2:
1157          printf (".bss");
1158          break;
1159        default:
1160          printf ("%u", symndx - 3);
1161          break;
1162        }
1163      putchar ('\n');
1164    }
1165
1166  printf (_("Import files:\n"));
1167  p = (char *)ldr_data + impoff;
1168  for (i = 0; i < nimpid; i++)
1169    {
1170      int n1, n2, n3;
1171
1172      n1 = strlen (p);
1173      n2 = strlen (p + n1 + 1);
1174      n3 = strlen (p + n1 + 1 + n2+ 1);
1175      printf (" %2u: %s,%s,%s\n", i,
1176              p, p + n1 + 1, p + n1 + n2 + 2);
1177      p += n1 + n2 + n3 + 3;
1178    }
1179
1180  free (ldr_data);
1181}
1182
1183/* Dump xcoff exception section.  */
1184
1185static void
1186dump_xcoff32_except (bfd *abfd, struct xcoff_dump *data)
1187{
1188  asection *sec;
1189  bfd_size_type size = 0;
1190  bfd_byte *excp_data;
1191  struct external_exceptab *exceptab;
1192  unsigned int i;
1193
1194  sec = bfd_get_section_by_name (abfd, ".except");
1195
1196  if (sec == NULL)
1197    {
1198      printf (_("no .except section in file\n"));
1199      return;
1200    }
1201  size = bfd_get_section_size (sec);
1202  excp_data = (bfd_byte *) xmalloc (size);
1203  bfd_get_section_contents (abfd, sec, excp_data, 0, size);
1204  exceptab = (struct external_exceptab *)excp_data;
1205
1206  printf (_("Exception table:\n"));
1207  /* Do not translate fields name.  */
1208  printf ("lang reason sym/addr\n");
1209  for (i = 0; i * sizeof (*exceptab) < size; i++, exceptab++)
1210    {
1211      unsigned int reason;
1212      unsigned int addr;
1213
1214      addr = bfd_get_32 (abfd, exceptab->e_addr.e_paddr);
1215      reason = bfd_get_8 (abfd, exceptab->e_reason);
1216      printf ("  %02x     %02x ",
1217              (unsigned) bfd_get_8 (abfd, exceptab->e_lang), reason);
1218      if (reason == 0)
1219        xcoff32_print_symbol (data, addr);
1220      else
1221        printf ("@%08x", addr);
1222      putchar ('\n');
1223    }
1224  free (excp_data);
1225}
1226
1227/* Dump xcoff type-check section.  */
1228
1229static void
1230dump_xcoff32_typchk (bfd *abfd)
1231{
1232  asection *sec;
1233  bfd_size_type size = 0;
1234  bfd_byte *data;
1235  unsigned int i;
1236
1237  sec = bfd_get_section_by_name (abfd, ".typchk");
1238
1239  if (sec == NULL)
1240    {
1241      printf (_("no .typchk section in file\n"));
1242      return;
1243    }
1244  size = bfd_get_section_size (sec);
1245  data = (bfd_byte *) xmalloc (size);
1246  bfd_get_section_contents (abfd, sec, data, 0, size);
1247
1248  printf (_("Type-check section:\n"));
1249  /* Do not translate field names.  */
1250  printf ("offset    len  lang-id general-hash language-hash\n");
1251  for (i = 0; i < size;)
1252    {
1253      unsigned int len;
1254
1255      len = bfd_get_16 (abfd, data + i);
1256      printf ("%08x: %-4u ", i, len);
1257      i += 2;
1258
1259      if (len == 10)
1260        {
1261          /* Expected format.  */
1262          printf ("%04x    %08x     %08x\n",
1263                  (unsigned) bfd_get_16 (abfd, data + i),
1264                  (unsigned) bfd_get_32 (abfd, data + i + 2),
1265                  (unsigned) bfd_get_32 (abfd, data + i + 2 + 4));
1266        }
1267      else
1268        {
1269          unsigned int j;
1270
1271          for (j = 0; j < len; j++)
1272            {
1273              if (j % 16 == 0)
1274                printf ("\n    ");
1275              printf (" %02x", (unsigned char)data[i + j]);
1276            }
1277          putchar ('\n');
1278        }
1279      i += len;
1280    }
1281  free (data);
1282}
1283
1284/* Dump xcoff traceback tags section.  */
1285
1286static void
1287dump_xcoff32_tbtags (bfd *abfd,
1288                     const char *text, bfd_size_type text_size,
1289                     unsigned int text_start, unsigned int func_start)
1290{
1291  unsigned int i;
1292
1293  if (func_start - text_start > text_size)
1294    {
1295      printf (_(" address beyond section size\n"));
1296      return;
1297    }
1298  for (i = func_start - text_start; i < text_size; i+= 4)
1299    if (bfd_get_32 (abfd, text + i) == 0)
1300      {
1301        unsigned int tb1;
1302        unsigned int tb2;
1303        unsigned int off;
1304
1305        printf (_(" tags at %08x\n"), i + 4);
1306        if (i + 8 >= text_size)
1307          goto truncated;
1308
1309        tb1 = bfd_get_32 (abfd, text + i + 4);
1310        tb2 = bfd_get_32 (abfd, text + i + 8);
1311        off = i + 12;
1312        printf (" version: %u, lang: %u, global_link: %u, is_eprol: %u, has_tboff: %u, int_proc: %u\n",
1313                (tb1 >> 24) & 0xff,
1314                (tb1 >> 16) & 0xff,
1315                (tb1 >> 15) & 1,
1316                (tb1 >> 14) & 1,
1317                (tb1 >> 13) & 1,
1318                (tb1 >> 12) & 1);
1319        printf (" has_ctl: %u, tocless: %u, fp_pres: %u, log_abort: %u, int_hndl: %u\n",
1320                (tb1 >> 11) & 1,
1321                (tb1 >> 10) & 1,
1322                (tb1 >> 9) & 1,
1323                (tb1 >> 8) & 1,
1324                (tb1 >> 7) & 1);
1325        printf (" name_pres: %u, uses_alloca: %u, cl_dis_inv: %u, saves_cr: %u, saves_lr: %u\n",
1326                (tb1 >> 6) & 1,
1327                (tb1 >> 5) & 1,
1328                (tb1 >> 2) & 7,
1329                (tb1 >> 1) & 1,
1330                (tb1 >> 0) & 1);
1331        printf (" stores_bc: %u, fixup: %u, fpr_saved: %-2u, spare3: %u, gpr_saved: %-2u\n",
1332                (tb2 >> 31) & 1,
1333                (tb2 >> 30) & 1,
1334                (tb2 >> 24) & 63,
1335                (tb2 >> 22) & 3,
1336                (tb2 >> 16) & 63);
1337        printf (" fixparms: %-3u  floatparms: %-3u  parm_on_stk: %u\n",
1338                (tb2 >> 8) & 0xff,
1339                (tb2 >> 1) & 0x7f,
1340                (tb2 >> 0) & 1);
1341
1342        if (((tb2 >> 1) & 0x7fff) != 0)
1343          {
1344            unsigned int parminfo;
1345
1346            if (off >= text_size)
1347              goto truncated;
1348            parminfo = bfd_get_32 (abfd, text + off);
1349            off += 4;
1350            printf (" parminfo: 0x%08x\n", parminfo);
1351          }
1352
1353        if ((tb1 >> 13) & 1)
1354          {
1355            unsigned int tboff;
1356
1357            if (off >= text_size)
1358              goto truncated;
1359            tboff = bfd_get_32 (abfd, text + off);
1360            off += 4;
1361            printf (" tb_offset: 0x%08x (start=0x%08x)\n",
1362                    tboff, text_start + i - tboff);
1363          }
1364        if ((tb1 >> 7) & 1)
1365          {
1366            unsigned int hand_mask;
1367
1368            if (off >= text_size)
1369              goto truncated;
1370            hand_mask = bfd_get_32 (abfd, text + off);
1371            off += 4;
1372            printf (" hand_mask_offset: 0x%08x\n", hand_mask);
1373          }
1374        if ((tb1 >> 11) & 1)
1375          {
1376            unsigned int ctl_info;
1377            unsigned int j;
1378
1379            if (off >= text_size)
1380              goto truncated;
1381            ctl_info = bfd_get_32 (abfd, text + off);
1382            off += 4;
1383            printf (_(" number of CTL anchors: %u\n"), ctl_info);
1384            for (j = 0; j < ctl_info; j++)
1385              {
1386                if (off >= text_size)
1387                  goto truncated;
1388                printf ("  CTL[%u]: %08x\n",
1389                        j, (unsigned)bfd_get_32 (abfd, text + off));
1390                off += 4;
1391              }
1392          }
1393        if ((tb1 >> 6) & 1)
1394          {
1395            unsigned int name_len;
1396            unsigned int j;
1397
1398            if (off >= text_size)
1399              goto truncated;
1400            name_len = bfd_get_16 (abfd, text + off);
1401            off += 2;
1402            printf (_(" Name (len: %u): "), name_len);
1403            if (off + name_len >= text_size)
1404              {
1405                printf (_("[truncated]\n"));
1406                goto truncated;
1407              }
1408            for (j = 0; j < name_len; j++)
1409              if (ISPRINT (text[off + j]))
1410                putchar (text[off + j]);
1411              else
1412                printf ("[%02x]", (unsigned char)text[off + j]);
1413            putchar ('\n');
1414            off += name_len;
1415          }
1416        if ((tb1 >> 5) & 1)
1417          {
1418            if (off >= text_size)
1419              goto truncated;
1420            printf (" alloca reg: %u\n",
1421                    (unsigned) bfd_get_8 (abfd, text + off));
1422            off++;
1423          }
1424        printf (_(" (end of tags at %08x)\n"), text_start + off);
1425        return;
1426      }
1427  printf (_(" no tags found\n"));
1428  return;
1429
1430 truncated:
1431  printf (_(" Truncated .text section\n"));
1432  return;
1433}
1434
1435static void
1436dump_xcoff32_traceback (bfd *abfd, struct xcoff_dump *data)
1437{
1438  unsigned int i;
1439  unsigned int scnum_text = -1;
1440  unsigned int text_vma;
1441  asection *text_sec;
1442  bfd_size_type text_size;
1443  char *text;
1444
1445  if (data->syms == NULL || data->sects == NULL)
1446    return;
1447
1448  /* Read text section.  */
1449  text_sec = bfd_get_section_by_name (abfd, ".text");
1450  if (text_sec == NULL)
1451    return;
1452  text_vma = bfd_get_section_vma (abfd, text_sec);
1453
1454  text_size = bfd_get_section_size (text_sec);
1455  text = (char *) xmalloc (text_size);
1456  bfd_get_section_contents (abfd, text_sec, text, 0, text_size);
1457
1458  for (i = 0; i < data->nscns; i++)
1459    if (data->sects[i].flags == STYP_TEXT)
1460      {
1461        scnum_text = i + 1;
1462        break;
1463      }
1464  if (scnum_text == (unsigned int)-1)
1465    return;
1466
1467  for (i = 0; i < data->nsyms; i++)
1468    {
1469      union xcoff32_symbol *s = &data->syms[i];
1470
1471      switch (s->sym.sclass)
1472        {
1473        case C_EXT:
1474        case C_HIDEXT:
1475        case C_WEAKEXT:
1476          if (s->sym.scnum == scnum_text
1477              && s->sym.numaux > 0)
1478            {
1479              union external_auxent *aux = &s[s->sym.numaux].aux;
1480
1481              unsigned int smtyp;
1482              unsigned int smclas;
1483
1484              smtyp = bfd_h_get_8 (abfd, aux->x_csect.x_smtyp);
1485              smclas = bfd_h_get_8 (abfd, aux->x_csect.x_smclas);
1486              if (SMTYP_SMTYP (smtyp) == XTY_LD
1487                  && (smclas == XMC_PR
1488                      || smclas == XMC_GL
1489                      || smclas == XMC_XO))
1490                {
1491                  printf ("%08x: ", s->sym.val);
1492                  xcoff32_print_symbol (data, i);
1493                  putchar ('\n');
1494                  dump_xcoff32_tbtags (abfd, text, text_size,
1495                                       text_vma, s->sym.val);
1496                }
1497            }
1498          break;
1499        default:
1500          break;
1501        }
1502      i += s->sym.numaux;
1503    }
1504  free (text);
1505}
1506
1507/* Dump the TOC symbols.  */
1508
1509static void
1510dump_xcoff32_toc (bfd *abfd, struct xcoff_dump *data)
1511{
1512  unsigned int i;
1513  unsigned int nbr_ent;
1514  unsigned int size;
1515
1516  printf (_("TOC:\n"));
1517
1518  if (data->syms == NULL)
1519    return;
1520
1521  nbr_ent = 0;
1522  size = 0;
1523
1524  for (i = 0; i < data->nsyms; i++)
1525    {
1526      union xcoff32_symbol *s = &data->syms[i];
1527
1528      switch (s->sym.sclass)
1529        {
1530        case C_EXT:
1531        case C_HIDEXT:
1532        case C_WEAKEXT:
1533          if (s->sym.numaux > 0)
1534            {
1535              union external_auxent *aux = &s[s->sym.numaux].aux;
1536              unsigned int smclas;
1537              unsigned int ent_sz;
1538
1539              smclas = bfd_h_get_8 (abfd, aux->x_csect.x_smclas);
1540              if (smclas == XMC_TC
1541                  || smclas == XMC_TD
1542                  || smclas == XMC_TC0)
1543                {
1544                  ent_sz = bfd_h_get_32 (abfd, aux->x_scn.x_scnlen);
1545                  printf ("%08x %08x ",
1546                          s->sym.val, ent_sz);
1547                  xcoff32_print_symbol (data, i);
1548                  putchar ('\n');
1549                  nbr_ent++;
1550                  size += ent_sz;
1551                }
1552            }
1553          break;
1554        default:
1555          break;
1556        }
1557      i += s->sym.numaux;
1558    }
1559  printf (_("Nbr entries: %-8u Size: %08x (%u)\n"),
1560          nbr_ent, size, size);
1561}
1562
1563/* Handle an rs6000 xcoff file.  */
1564
1565static void
1566dump_xcoff32 (bfd *abfd, struct external_filehdr *fhdr)
1567{
1568  struct xcoff_dump data;
1569
1570  data.nscns = bfd_h_get_16 (abfd, fhdr->f_nscns);
1571  data.symptr = bfd_h_get_32 (abfd, fhdr->f_symptr);
1572  data.nsyms = bfd_h_get_32 (abfd, fhdr->f_nsyms);
1573  data.opthdr = bfd_h_get_16 (abfd, fhdr->f_opthdr);
1574  data.sects = NULL;
1575  data.syms = NULL;
1576  data.strings = NULL;
1577  data.strings_size = 0;
1578
1579  if (options[OPT_FILE_HEADER].selected)
1580    dump_xcoff32_file_header (abfd, fhdr, &data);
1581
1582  if (options[OPT_AOUT].selected)
1583    dump_xcoff32_aout_header (abfd, &data);
1584
1585  if (options[OPT_SYMS].selected
1586      || options[OPT_RELOCS].selected
1587      || options[OPT_LINENO].selected
1588      || options[OPT_TRACEBACK].selected)
1589    xcoff32_read_sections (abfd, &data);
1590
1591  if (options[OPT_SECTIONS].selected)
1592    dump_xcoff32_sections_header (abfd, &data);
1593
1594  if (options[OPT_SYMS].selected
1595      || options[OPT_RELOCS].selected
1596      || options[OPT_LINENO].selected
1597      || options[OPT_EXCEPT].selected
1598      || options[OPT_TRACEBACK].selected
1599      || options[OPT_TOC].selected)
1600    xcoff32_read_symbols (abfd, &data);
1601
1602  if (options[OPT_SYMS].selected)
1603    dump_xcoff32_symbols (abfd, &data);
1604
1605  if (options[OPT_RELOCS].selected)
1606    dump_xcoff32_relocs (abfd, &data);
1607
1608  if (options[OPT_LINENO].selected)
1609    dump_xcoff32_lineno (abfd, &data);
1610
1611  if (options[OPT_LOADER].selected)
1612    dump_xcoff32_loader (abfd);
1613
1614  if (options[OPT_EXCEPT].selected)
1615    dump_xcoff32_except (abfd, &data);
1616
1617  if (options[OPT_TYPCHK].selected)
1618    dump_xcoff32_typchk (abfd);
1619
1620  if (options[OPT_TRACEBACK].selected)
1621    dump_xcoff32_traceback (abfd, &data);
1622
1623  if (options[OPT_TOC].selected)
1624    dump_xcoff32_toc (abfd, &data);
1625
1626  free (data.sects);
1627  free (data.strings);
1628  free (data.syms);
1629}
1630
1631/* Dump ABFD (according to the options[] array).  */
1632
1633static void
1634xcoff_dump_obj (bfd *abfd)
1635{
1636  struct external_filehdr fhdr;
1637  unsigned short magic;
1638
1639  /* Read file header.  */
1640  if (bfd_seek (abfd, 0, SEEK_SET) != 0
1641      || bfd_bread (&fhdr, sizeof (fhdr), abfd) != sizeof (fhdr))
1642    {
1643      non_fatal (_("cannot read header"));
1644      return;
1645    }
1646
1647  /* Decoding.  We don't use the bfd/coff function to get all the fields.  */
1648  magic = bfd_h_get_16 (abfd, fhdr.f_magic);
1649  if (options[OPT_FILE_HEADER].selected)
1650    {
1651      printf (_("File header:\n"));
1652      printf (_("  magic:         0x%04x (0%04o)  "), magic, magic);
1653      switch (magic)
1654        {
1655        case U802WRMAGIC:
1656          printf (_("(WRMAGIC: writable text segments)"));
1657          break;
1658        case U802ROMAGIC:
1659          printf (_("(ROMAGIC: readonly sharablee text segments)"));
1660          break;
1661        case U802TOCMAGIC:
1662          printf (_("(TOCMAGIC: readonly text segments and TOC)"));
1663          break;
1664        default:
1665          printf (_("unknown magic"));
1666	  break;
1667        }
1668      putchar ('\n');
1669    }
1670  if (magic == U802ROMAGIC || magic == U802WRMAGIC || magic == U802TOCMAGIC)
1671    dump_xcoff32 (abfd, &fhdr);
1672  else
1673    printf (_("  Unhandled magic\n"));
1674}
1675
1676/* Handle an AIX dumpx core file.  */
1677
1678static void
1679dump_dumpx_core (bfd *abfd, struct external_core_dumpx *hdr)
1680{
1681  if (options[OPT_FILE_HEADER].selected)
1682    {
1683      printf ("  signal:     %u\n", bfd_h_get_8 (abfd, hdr->c_signo));
1684      printf ("  flags:      0x%02x\n", bfd_h_get_8 (abfd, hdr->c_flag));
1685      printf ("  entries:    %u\n",
1686	      (unsigned) bfd_h_get_16 (abfd, hdr->c_entries));
1687#ifdef BFD64
1688      printf ("  fdsinfox:   offset: 0x%08" BFD_VMA_FMT "x\n",
1689	      bfd_h_get_64 (abfd, hdr->c_fdsinfox));
1690      printf ("  loader:     offset: 0x%08" BFD_VMA_FMT "x, "
1691	      "size: 0x%" BFD_VMA_FMT"x\n",
1692	      bfd_h_get_64 (abfd, hdr->c_loader),
1693	      bfd_h_get_64 (abfd, hdr->c_lsize));
1694      printf ("  thr:        offset: 0x%08" BFD_VMA_FMT "x, nbr: %u\n",
1695	      bfd_h_get_64 (abfd, hdr->c_thr),
1696	      (unsigned) bfd_h_get_32 (abfd, hdr->c_n_thr));
1697      printf ("  segregions: offset: 0x%08" BFD_VMA_FMT "x, "
1698	      "nbr: %" BFD_VMA_FMT "u\n",
1699	      bfd_h_get_64 (abfd, hdr->c_segregion),
1700	      bfd_h_get_64 (abfd, hdr->c_segs));
1701      printf ("  stack:      offset: 0x%08" BFD_VMA_FMT "x, "
1702	      "org: 0x%" BFD_VMA_FMT"x, "
1703	      "size: 0x%" BFD_VMA_FMT"x\n",
1704	      bfd_h_get_64 (abfd, hdr->c_stack),
1705	      bfd_h_get_64 (abfd, hdr->c_stackorg),
1706	      bfd_h_get_64 (abfd, hdr->c_size));
1707      printf ("  data:       offset: 0x%08" BFD_VMA_FMT "x, "
1708	      "org: 0x%" BFD_VMA_FMT"x, "
1709	      "size: 0x%" BFD_VMA_FMT"x\n",
1710	      bfd_h_get_64 (abfd, hdr->c_data),
1711	      bfd_h_get_64 (abfd, hdr->c_dataorg),
1712	      bfd_h_get_64 (abfd, hdr->c_datasize));
1713      printf ("  sdata:         org: 0x%" BFD_VMA_FMT"x, "
1714	      "size: 0x%" BFD_VMA_FMT"x\n",
1715	      bfd_h_get_64 (abfd, hdr->c_sdorg),
1716	      bfd_h_get_64 (abfd, hdr->c_sdsize));
1717      printf ("  vmmregions: offset: 0x%" BFD_VMA_FMT"x, "
1718	      "num: 0x%" BFD_VMA_FMT"x\n",
1719	      bfd_h_get_64 (abfd, hdr->c_vmm),
1720	      bfd_h_get_64 (abfd, hdr->c_vmmregions));
1721      printf ("  impl:       0x%08x\n",
1722	      (unsigned) bfd_h_get_32 (abfd, hdr->c_impl));
1723      printf ("  cprs:       0x%" BFD_VMA_FMT "x\n",
1724	      bfd_h_get_64 (abfd, hdr->c_cprs));
1725#endif
1726    }
1727  if (options[OPT_LDINFO].selected)
1728    {
1729#ifdef BFD64
1730      file_ptr off = (file_ptr) bfd_h_get_64 (abfd, hdr->c_loader);
1731      bfd_size_type len = (bfd_size_type) bfd_h_get_64 (abfd, hdr->c_lsize);
1732      char *ldr;
1733
1734      ldr = xmalloc (len);
1735      if (bfd_seek (abfd, off, SEEK_SET) != 0
1736	  || bfd_bread (ldr, len, abfd) != len)
1737	non_fatal (_("cannot read loader info table"));
1738      else
1739	{
1740	  char *p;
1741
1742	  printf ("\n"
1743		  "ld info:\n");
1744	  printf ("  next     core off textorg  textsize dataorg  datasize\n");
1745	  p = ldr;
1746	  while (1)
1747	    {
1748	      struct external_ld_info32 *l = (struct external_ld_info32 *)p;
1749	      unsigned int next;
1750	      size_t n1;
1751
1752	      next = bfd_h_get_32 (abfd, l->ldinfo_next);
1753	      printf ("  %08x %08x %08x %08x %08x %08x\n",
1754		      next,
1755		      (unsigned) bfd_h_get_32 (abfd, l->core_offset),
1756		      (unsigned) bfd_h_get_32 (abfd, l->ldinfo_textorg),
1757		      (unsigned) bfd_h_get_32 (abfd, l->ldinfo_textsize),
1758		      (unsigned) bfd_h_get_32 (abfd, l->ldinfo_dataorg),
1759		      (unsigned) bfd_h_get_32 (abfd, l->ldinfo_datasize));
1760	      n1 = strlen ((char *) l->ldinfo_filename);
1761	      printf ("    %s %s\n",
1762		      l->ldinfo_filename, l->ldinfo_filename + n1 + 1);
1763	      if (next == 0)
1764		break;
1765	      p += next;
1766	    }
1767	}
1768#else
1769      printf (_("\n"
1770		"ldinfo dump not supported in 32 bits environments\n"));
1771#endif
1772    }
1773}
1774
1775/* Dump a core file.  */
1776
1777static void
1778xcoff_dump_core (bfd *abfd)
1779{
1780  struct external_core_dumpx hdr;
1781  unsigned int version;
1782
1783  /* Read file header.  */
1784  if (bfd_seek (abfd, 0, SEEK_SET) != 0
1785      || bfd_bread (&hdr, sizeof (hdr), abfd) != sizeof (hdr))
1786    {
1787      non_fatal (_("cannot core read header"));
1788      return;
1789    }
1790
1791  version = bfd_h_get_32 (abfd, hdr.c_version);
1792  if (options[OPT_FILE_HEADER].selected)
1793    {
1794      printf (_("Core header:\n"));
1795      printf (_("  version:    0x%08x  "), version);
1796      switch (version)
1797	{
1798	case CORE_DUMPX_VERSION:
1799	  printf (_("(dumpx format - aix4.3 / 32 bits)"));
1800	  break;
1801	case CORE_DUMPXX_VERSION:
1802	  printf (_("(dumpxx format - aix5.0 / 64 bits)"));
1803	  break;
1804	default:
1805	  printf (_("unknown format"));
1806	  break;
1807	}
1808      putchar ('\n');
1809    }
1810  if (version == CORE_DUMPX_VERSION)
1811    dump_dumpx_core (abfd, &hdr);
1812  else
1813    printf (_("  Unhandled magic\n"));
1814}
1815
1816/* Dump an XCOFF file.  */
1817
1818static void
1819xcoff_dump (bfd *abfd)
1820{
1821  /* We rely on BFD to decide if the file is a core file.  Note that core
1822     files are only supported on native environment by BFD.  */
1823  switch (bfd_get_format (abfd))
1824    {
1825    case bfd_core:
1826      xcoff_dump_core (abfd);
1827      break;
1828    default:
1829      xcoff_dump_obj (abfd);
1830      break;
1831    }
1832}
1833
1834/* Vector for xcoff.  */
1835
1836const struct objdump_private_desc objdump_private_desc_xcoff =
1837  {
1838    xcoff_help,
1839    xcoff_filter,
1840    xcoff_dump,
1841    options
1842  };
1843