1 /* od-xcoff.c -- dump information about an xcoff object file.
2    Copyright (C) 2011-2021 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.  */
55 static 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 
74 static void
xcoff_help(FILE * stream)75 xcoff_help (FILE *stream)
76 {
77   fprintf (stream, _("\
78 For 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 
96 static int
xcoff_filter(bfd * abfd)97 xcoff_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 
104 struct 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 
112 static void
dump_flags(const struct xlat_table * table,unsigned int flags)113 dump_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 
143 static void
dump_value(const struct xlat_table * table,unsigned int val,int maxlen)144 dump_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.  */
158 static 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.  */
179 static 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.  */
200 static 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.  */
258 static 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.  */
270 static 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.  */
296 static 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.  */
332 struct 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 
352 union 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 
379 struct 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 
398 static void
xcoff32_print_symbol(struct xcoff_dump * data,unsigned int symndx)399 xcoff32_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 
411 static void
dump_xcoff32_file_header(bfd * abfd,struct external_filehdr * fhdr,struct xcoff_dump * data)412 dump_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 
438 static void
dump_xcoff32_aout_header(bfd * abfd,struct xcoff_dump * data)439 dump_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 
517 static void
dump_xcoff32_sections_header(bfd * abfd,struct xcoff_dump * data)518 dump_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 
581 static void
xcoff32_read_sections(bfd * abfd,struct xcoff_dump * data)582 xcoff32_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 
631 static void
xcoff32_read_symbols(bfd * abfd,struct xcoff_dump * data)632 xcoff32_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 
737 static void
dump_xcoff32_symbols(bfd * abfd,struct xcoff_dump * data)738 dump_xcoff32_symbols (bfd *abfd, struct xcoff_dump *data)
739 {
740   unsigned int i;
741   asection *debugsec;
742   char *debug = NULL;
743 
744   printf (_("Symbols table (strtable at 0x%08x)"),
745           data->symptr
746           + data->nsyms * (unsigned)sizeof (struct external_syment));
747   if (data->nsyms == 0 || data->syms == NULL)
748     {
749       printf (_(":\n  No symbols\n"));
750       return;
751     }
752 
753   /* Read 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 
917 static void
dump_xcoff32_relocs(bfd * abfd,struct xcoff_dump * data)918 dump_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 
973 static void
dump_xcoff32_lineno(bfd * abfd,struct xcoff_dump * data)974 dump_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 
1027 static void
dump_xcoff32_loader(bfd * abfd)1028 dump_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 
1184 static void
dump_xcoff32_except(bfd * abfd,struct xcoff_dump * data)1185 dump_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 
1228 static void
dump_xcoff32_typchk(bfd * abfd)1229 dump_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 
1285 static void
dump_xcoff32_tbtags(bfd * abfd,const char * text,bfd_size_type text_size,unsigned int text_start,unsigned int func_start)1286 dump_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 
1434 static void
dump_xcoff32_traceback(bfd * abfd,struct xcoff_dump * data)1435 dump_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 
1508 static void
dump_xcoff32_toc(bfd * abfd,struct xcoff_dump * data)1509 dump_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 
1564 static void
dump_xcoff32(bfd * abfd,struct external_filehdr * fhdr)1565 dump_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 
1632 static void
xcoff_dump_obj(bfd * abfd)1633 xcoff_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 
1677 static void
dump_dumpx_core(bfd * abfd,struct external_core_dumpx * hdr)1678 dump_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 
1778 static void
xcoff_dump_core(bfd * abfd)1779 xcoff_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 
1819 static void
xcoff_dump(bfd * abfd)1820 xcoff_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 
1837 const struct objdump_private_desc objdump_private_desc_xcoff =
1838   {
1839     xcoff_help,
1840     xcoff_filter,
1841     xcoff_dump,
1842     options
1843   };
1844