bfd:
[binutils.git] / binutils / od-xcoff.c
blob2b38cbdaca504fee868ff9f7666cf0074e8ef0e5
1 /* od-xcoff.c -- dump information about an xcoff object file.
2 Copyright 2011 Free Software Foundation, Inc.
3 Written by Tristan Gingold, Adacore.
5 This file is part of GNU Binutils.
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.
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.
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. */
22 #include <stddef.h>
23 #include <time.h>
24 #include "sysdep.h"
25 #include "safe-ctype.h"
26 #include "bfd.h"
27 #include "objdump.h"
28 #include "bucomm.h"
29 #include "bfdlink.h"
30 /* Force the support of weak symbols. */
31 #ifndef AIX_WEAK_SUPPORT
32 #define AIX_WEAK_SUPPORT 1
33 #endif
34 #include "coff/internal.h"
35 #include "coff/rs6000.h"
36 #include "coff/xcoff.h"
37 #include "libcoff.h"
38 #include "libxcoff.h"
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
53 /* List of actions. */
54 static struct objdump_private_option options[] =
56 { "header", 0 },
57 { "aout", 0 },
58 { "sections", 0 },
59 { "syms", 0 },
60 { "relocs", 0 },
61 { "lineno", 0 },
62 { "loader", 0 },
63 { "except", 0 },
64 { "typchk", 0 },
65 { "traceback", 0 },
66 { "toc", 0 },
67 { NULL, 0 }
70 /* Display help. */
72 static void
73 xcoff_help (FILE *stream)
75 fprintf (stream, _("\
76 For XCOFF files:\n\
77 header Display the file header\n\
78 aout Display the auxiliary header\n\
79 sections Display the section headers\n\
80 syms Display the symbols table\n\
81 relocs Display the relocation entries\n\
82 lineno Display the line number entries\n\
83 loader Display loader section\n\
84 except Display exception table\n\
85 typchk Display type-check section\n\
86 traceback Display traceback tags\n\
87 toc Display toc symbols\n\
88 "));
91 /* Return TRUE if ABFD is handled. */
93 static int
94 xcoff_filter (bfd *abfd)
96 return bfd_get_flavour (abfd) == bfd_target_xcoff_flavour;
99 /* Translation entry type. The last entry must be {0, NULL}. */
101 struct xlat_table {
102 unsigned int val;
103 const char *name;
106 /* Display the list of name (from TABLE) for FLAGS, using comma to separate
107 them. A name is displayed if FLAGS & VAL is not 0. */
109 static void
110 dump_flags (const struct xlat_table *table, unsigned int flags)
112 unsigned int r = flags;
113 int first = 1;
114 const struct xlat_table *t;
116 for (t = table; t->name; t++)
117 if ((flags & t->val) != 0)
119 r &= ~t->val;
121 if (first)
122 first = 0;
123 else
124 putchar (',');
125 fputs (t->name, stdout);
128 /* Not decoded flags. */
129 if (r != 0)
131 if (!first)
132 putchar (',');
133 printf ("0x%x", r);
137 /* Display the name corresponding to VAL from TABLE, using at most
138 MAXLEN char (possibly passed with spaces). */
140 static void
141 dump_value (const struct xlat_table *table, unsigned int val, int maxlen)
143 const struct xlat_table *t;
145 for (t = table; t->name; t++)
146 if (t->val == val)
148 printf ("%-*s", maxlen, t->name);
149 return;
151 printf ("(%*x)", maxlen - 2, val);
154 /* Names of f_flags. */
155 static const struct xlat_table f_flag_xlat[] =
157 { F_RELFLG, "no-rel" },
158 { F_EXEC, "exec" },
159 { F_LNNO, "lineno" },
160 { F_LSYMS, "lsyms" },
162 { F_FDPR_PROF, "fdpr-prof" },
163 { F_FDPR_OPTI, "fdpr-opti" },
164 { F_DSA, "dsa" },
166 { F_VARPG, "varprg" },
168 { F_DYNLOAD, "dynload" },
169 { F_SHROBJ, "shrobj" },
170 { F_NONEXEC, "nonexec" },
172 { 0, NULL }
175 /* Names of s_flags. */
176 static const struct xlat_table s_flag_xlat[] =
178 { STYP_PAD, "pad" },
179 { STYP_DWARF, "dwarf" },
180 { STYP_TEXT, "text" },
181 { STYP_DATA, "data" },
182 { STYP_BSS, "bss" },
184 { STYP_EXCEPT, "except" },
185 { STYP_INFO, "info" },
186 { STYP_TDATA, "tdata" },
187 { STYP_TBSS, "tbss" },
189 { STYP_LOADER, "loader" },
190 { STYP_DEBUG, "debug" },
191 { STYP_TYPCHK, "typchk" },
192 { STYP_OVRFLO, "ovrflo" },
193 { 0, NULL }
196 /* Names of storage class. */
197 static const struct xlat_table sc_xlat[] =
199 #define SC_ENTRY(X) { C_##X, #X }
200 SC_ENTRY(NULL),
201 SC_ENTRY(AUTO),
202 SC_ENTRY(EXT),
203 SC_ENTRY(STAT),
204 SC_ENTRY(REG),
205 SC_ENTRY(EXTDEF),
206 SC_ENTRY(LABEL),
207 SC_ENTRY(ULABEL),
208 SC_ENTRY(MOS),
209 SC_ENTRY(ARG),
210 /* SC_ENTRY(STRARG), */
211 SC_ENTRY(MOU),
212 SC_ENTRY(UNTAG),
213 SC_ENTRY(TPDEF),
214 SC_ENTRY(USTATIC),
215 SC_ENTRY(ENTAG),
216 SC_ENTRY(MOE),
217 SC_ENTRY(REGPARM),
218 SC_ENTRY(FIELD),
219 SC_ENTRY(BLOCK),
220 SC_ENTRY(FCN),
221 SC_ENTRY(EOS),
222 SC_ENTRY(FILE),
223 SC_ENTRY(LINE),
224 SC_ENTRY(ALIAS),
225 SC_ENTRY(HIDDEN),
226 SC_ENTRY(HIDEXT),
227 SC_ENTRY(BINCL),
228 SC_ENTRY(EINCL),
229 SC_ENTRY(INFO),
230 SC_ENTRY(WEAKEXT),
231 SC_ENTRY(DWARF),
233 /* Stabs. */
234 SC_ENTRY (GSYM),
235 SC_ENTRY (LSYM),
236 SC_ENTRY (PSYM),
237 SC_ENTRY (RSYM),
238 SC_ENTRY (RPSYM),
239 SC_ENTRY (STSYM),
240 SC_ENTRY (TCSYM),
241 SC_ENTRY (BCOMM),
242 SC_ENTRY (ECOML),
243 SC_ENTRY (ECOMM),
244 SC_ENTRY (DECL),
245 SC_ENTRY (ENTRY),
246 SC_ENTRY (FUN),
247 SC_ENTRY (BSTAT),
248 SC_ENTRY (ESTAT),
250 { 0, NULL }
251 #undef SC_ENTRY
254 /* Names for symbol type. */
255 static const struct xlat_table smtyp_xlat[] =
257 { XTY_ER, "ER" },
258 { XTY_SD, "SD" },
259 { XTY_LD, "LD" },
260 { XTY_CM, "CM" },
261 { XTY_EM, "EM" },
262 { XTY_US, "US" },
263 { 0, NULL }
266 /* Names for storage-mapping class. */
267 static const struct xlat_table smclas_xlat[] =
269 #define SMCLAS_ENTRY(X) { XMC_##X, #X }
270 SMCLAS_ENTRY (PR),
271 SMCLAS_ENTRY (RO),
272 SMCLAS_ENTRY (DB),
273 SMCLAS_ENTRY (TC),
274 SMCLAS_ENTRY (UA),
275 SMCLAS_ENTRY (RW),
276 SMCLAS_ENTRY (GL),
277 SMCLAS_ENTRY (XO),
278 SMCLAS_ENTRY (SV),
279 SMCLAS_ENTRY (BS),
280 SMCLAS_ENTRY (DS),
281 SMCLAS_ENTRY (UC),
282 SMCLAS_ENTRY (TI),
283 SMCLAS_ENTRY (TB),
284 SMCLAS_ENTRY (TC0),
285 SMCLAS_ENTRY (TD),
286 SMCLAS_ENTRY (SV64),
287 SMCLAS_ENTRY (SV3264),
288 { 0, NULL }
289 #undef SMCLAS_ENTRY
292 /* Names for relocation type. */
293 static const struct xlat_table rtype_xlat[] =
295 #define RTYPE_ENTRY(X) { R_##X, #X }
296 RTYPE_ENTRY (POS),
297 RTYPE_ENTRY (NEG),
298 RTYPE_ENTRY (REL),
299 RTYPE_ENTRY (TOC),
300 RTYPE_ENTRY (RTB),
301 RTYPE_ENTRY (GL),
302 RTYPE_ENTRY (TCL),
303 RTYPE_ENTRY (BA),
304 RTYPE_ENTRY (BR),
305 RTYPE_ENTRY (RL),
306 RTYPE_ENTRY (RLA),
307 RTYPE_ENTRY (REF),
308 RTYPE_ENTRY (TRL),
309 RTYPE_ENTRY (TRLA),
310 RTYPE_ENTRY (RRTBI),
311 RTYPE_ENTRY (RRTBA),
312 RTYPE_ENTRY (CAI),
313 RTYPE_ENTRY (CREL),
314 RTYPE_ENTRY (RBA),
315 RTYPE_ENTRY (RBAC),
316 RTYPE_ENTRY (RBR),
317 RTYPE_ENTRY (RBRC),
318 RTYPE_ENTRY (TLS),
319 RTYPE_ENTRY (TLS_IE),
320 RTYPE_ENTRY (TLS_LD),
321 RTYPE_ENTRY (TLS_LE),
322 RTYPE_ENTRY (TLSM),
323 RTYPE_ENTRY (TLSML),
324 RTYPE_ENTRY (TOCU),
325 RTYPE_ENTRY (TOCL),
326 { 0, NULL }
329 /* Simplified section header. */
330 struct xcoff32_section
332 /* NUL terminated name. */
333 char name[9];
335 /* Section flags. */
336 unsigned int flags;
338 /* Offsets in file. */
339 ufile_ptr scnptr;
340 ufile_ptr relptr;
341 ufile_ptr lnnoptr;
343 /* Number of relocs and line numbers. */
344 unsigned int nreloc;
345 unsigned int nlnno;
348 /* Simplified symbol. */
350 union xcoff32_symbol
352 union external_auxent aux;
354 struct sym
356 /* Pointer the the NUL-terminated name. */
357 char *name;
359 /* XCOFF symbol fields. */
360 unsigned int val;
361 unsigned short scnum;
362 unsigned short ntype;
363 unsigned char sclass;
364 unsigned char numaux;
366 /* Buffer in case the name is local. */
367 union
369 char name[9];
370 unsigned int off;
371 } raw;
372 } sym;
375 /* Important fields to dump the file. */
377 struct xcoff_dump
379 /* From file header. */
380 unsigned short nscns;
381 unsigned int symptr;
382 unsigned int nsyms;
383 unsigned short opthdr;
385 /* Sections. */
386 struct xcoff32_section *sects;
388 /* Symbols. */
389 union xcoff32_symbol *syms;
390 char *strings;
391 unsigned int strings_size;
394 /* Print a symbol (if possible). */
396 static void
397 xcoff32_print_symbol (struct xcoff_dump *data, unsigned int symndx)
399 if (data->syms != NULL
400 && symndx < data->nsyms
401 && data->syms[symndx].sym.name != NULL)
402 printf ("%s", data->syms[symndx].sym.name);
403 else
404 printf ("%u", symndx);
407 /* Dump the file header. */
409 static void
410 dump_xcoff32_file_header (bfd *abfd, struct external_filehdr *fhdr,
411 struct xcoff_dump *data)
413 unsigned int timdat = bfd_h_get_32 (abfd, fhdr->f_timdat);
414 unsigned short flags = bfd_h_get_16 (abfd, fhdr->f_flags);
416 printf (_(" nbr sections: %d\n"), data->nscns);
417 printf (_(" time and date: 0x%08x - "), timdat);
418 if (timdat == 0)
419 printf (_("not set\n"));
420 else
422 /* Not correct on all platforms, but works on unix. */
423 time_t t = timdat;
424 fputs (ctime (&t), stdout);
426 printf (_(" symbols off: 0x%08x\n"), data->symptr);
427 printf (_(" nbr symbols: %d\n"), data->nsyms);
428 printf (_(" opt hdr sz: %d\n"), data->opthdr);
429 printf (_(" flags: 0x%04x "), flags);
430 dump_flags (f_flag_xlat, flags);
431 putchar ('\n');
434 /* Dump the a.out header. */
436 static void
437 dump_xcoff32_aout_header (bfd *abfd, struct xcoff_dump *data)
439 AOUTHDR auxhdr;
440 unsigned short magic;
441 unsigned int sz = data->opthdr;
443 printf (_("Auxiliary header:\n"));
444 if (data->opthdr == 0)
446 printf (_(" No aux header\n"));
447 return;
449 if (data->opthdr > sizeof (auxhdr))
451 printf (_("warning: optionnal header size too large (> %d)\n"),
452 (int)sizeof (auxhdr));
453 sz = sizeof (auxhdr);
455 if (bfd_bread (&auxhdr, sz, abfd) != sz)
457 non_fatal (_("cannot read auxhdr"));
458 return;
461 magic = bfd_h_get_16 (abfd, auxhdr.magic);
462 /* We don't translate these strings as they are fields name. */
463 printf (" o_mflag (magic): 0x%04x 0%04o\n", magic, magic);
464 printf (" o_vstamp: 0x%04x\n",
465 (unsigned short)bfd_h_get_16 (abfd, auxhdr.vstamp));
466 printf (" o_tsize: 0x%08x\n",
467 (unsigned int)bfd_h_get_32 (abfd, auxhdr.tsize));
468 printf (" o_dsize: 0x%08x\n",
469 (unsigned int)bfd_h_get_32 (abfd, auxhdr.dsize));
470 printf (" o_entry: 0x%08x\n",
471 (unsigned int)bfd_h_get_32 (abfd, auxhdr.entry));
472 printf (" o_text_start: 0x%08x\n",
473 (unsigned int)bfd_h_get_32 (abfd, auxhdr.text_start));
474 printf (" o_data_start: 0x%08x\n",
475 (unsigned int)bfd_h_get_32 (abfd, auxhdr.data_start));
476 if (sz == offsetof (AOUTHDR, o_toc))
477 return;
478 printf (" o_toc: 0x%08x\n",
479 (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_toc));
480 printf (" o_snentry: 0x%04x\n",
481 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snentry));
482 printf (" o_sntext: 0x%04x\n",
483 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sntext));
484 printf (" o_sndata: 0x%04x\n",
485 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sndata));
486 printf (" o_sntoc: 0x%04x\n",
487 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sntoc));
488 printf (" o_snloader: 0x%04x\n",
489 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snloader));
490 printf (" o_snbss: 0x%04x\n",
491 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snbss));
492 printf (" o_algntext: %u\n",
493 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_algntext));
494 printf (" o_algndata: %u\n",
495 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_algndata));
496 printf (" o_modtype: 0x%04x",
497 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_modtype));
498 if (ISPRINT (auxhdr.o_modtype[0]) && ISPRINT (auxhdr.o_modtype[1]))
499 printf (" (%c%c)", auxhdr.o_modtype[0], auxhdr.o_modtype[1]);
500 putchar ('\n');
501 printf (" o_cputype: 0x%04x\n",
502 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_cputype));
503 printf (" o_maxstack: 0x%08x\n",
504 (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_maxstack));
505 printf (" o_maxdata: 0x%08x\n",
506 (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_maxdata));
507 #if 0
508 printf (" o_debugger: 0x%08x\n",
509 (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_debugger));
510 #endif
513 /* Dump the sections header. */
515 static void
516 dump_xcoff32_sections_header (bfd *abfd, struct xcoff_dump *data)
518 unsigned int i;
519 unsigned int off;
521 off = sizeof (struct external_filehdr) + data->opthdr;
522 printf (_("Section headers (at %u+%u=0x%08x to 0x%08x):\n"),
523 (unsigned int)sizeof (struct external_filehdr), data->opthdr, off,
524 off + (unsigned int)sizeof (struct external_scnhdr) * data->nscns);
525 if (data->nscns == 0)
527 printf (_(" No section header\n"));
528 return;
530 if (bfd_seek (abfd, off, SEEK_SET) != 0)
532 non_fatal (_("cannot read section header"));
533 return;
535 /* We don't translate this string as it consists in fields name. */
536 printf (" # Name paddr vaddr size scnptr relptr lnnoptr nrel nlnno\n");
537 for (i = 0; i < data->nscns; i++)
539 struct external_scnhdr scn;
540 unsigned int flags;
542 if (bfd_bread (&scn, sizeof (scn), abfd) != sizeof (scn))
544 non_fatal (_("cannot read section header"));
545 return;
547 flags = bfd_h_get_32 (abfd, scn.s_flags);
548 printf ("%2d %-8.8s %08x %08x %08x %08x %08x %08x %-5d %-5d\n",
549 i + 1, scn.s_name,
550 (unsigned int)bfd_h_get_32 (abfd, scn.s_paddr),
551 (unsigned int)bfd_h_get_32 (abfd, scn.s_vaddr),
552 (unsigned int)bfd_h_get_32 (abfd, scn.s_size),
553 (unsigned int)bfd_h_get_32 (abfd, scn.s_scnptr),
554 (unsigned int)bfd_h_get_32 (abfd, scn.s_relptr),
555 (unsigned int)bfd_h_get_32 (abfd, scn.s_lnnoptr),
556 (unsigned int)bfd_h_get_16 (abfd, scn.s_nreloc),
557 (unsigned int)bfd_h_get_16 (abfd, scn.s_nlnno));
558 printf (_(" Flags: %08x "), flags);
560 if (~flags == 0)
562 /* Stripped executable ? */
563 putchar ('\n');
565 else if (flags & STYP_OVRFLO)
566 printf (_("overflow - nreloc: %u, nlnno: %u\n"),
567 (unsigned int)bfd_h_get_32 (abfd, scn.s_paddr),
568 (unsigned int)bfd_h_get_32 (abfd, scn.s_vaddr));
569 else
571 dump_flags (s_flag_xlat, flags);
572 putchar ('\n');
577 /* Read section table. */
579 static void
580 xcoff32_read_sections (bfd *abfd, struct xcoff_dump *data)
582 int i;
584 if (bfd_seek (abfd, sizeof (struct external_filehdr) + data->opthdr,
585 SEEK_SET) != 0)
587 non_fatal (_("cannot read section headers"));
588 return;
591 data->sects = xmalloc (data->nscns * sizeof (struct xcoff32_section));
592 for (i = 0; i < data->nscns; i++)
594 struct external_scnhdr scn;
595 struct xcoff32_section *s = &data->sects[i];
597 if (bfd_bread (&scn, sizeof (scn), abfd) != sizeof (scn))
599 non_fatal (_("cannot read section header"));
600 free (data->sects);
601 data->sects = NULL;
602 return;
604 memcpy (s->name, scn.s_name, 8);
605 s->name[8] = 0;
606 s->flags = bfd_h_get_32 (abfd, scn.s_flags);
608 s->scnptr = bfd_h_get_32 (abfd, scn.s_scnptr);
609 s->relptr = bfd_h_get_32 (abfd, scn.s_relptr);
610 s->lnnoptr = bfd_h_get_32 (abfd, scn.s_lnnoptr);
612 s->nreloc = bfd_h_get_16 (abfd, scn.s_nreloc);
613 s->nlnno = bfd_h_get_16 (abfd, scn.s_nlnno);
615 if (s->flags == STYP_OVRFLO)
617 if (s->nreloc > 0 && s->nreloc <= data->nscns)
618 data->sects[s->nreloc - 1].nreloc =
619 bfd_h_get_32 (abfd, scn.s_paddr);
620 if (s->nlnno > 0 && s->nlnno <= data->nscns)
621 data->sects[s->nlnno - 1].nlnno =
622 bfd_h_get_32 (abfd, scn.s_vaddr);
627 /* Read symbols. */
629 static void
630 xcoff32_read_symbols (bfd *abfd, struct xcoff_dump *data)
632 unsigned int i;
633 char stsz_arr[4];
634 unsigned int stptr;
636 if (data->nsyms == 0)
637 return;
639 stptr = data->symptr
640 + data->nsyms * (unsigned)sizeof (struct external_syment);
642 /* Read string table. */
643 if (bfd_seek (abfd, stptr, SEEK_SET) != 0
644 || bfd_bread (&stsz_arr, sizeof (stsz_arr), abfd) != sizeof (stsz_arr))
646 non_fatal (_("cannot read strings table length"));
647 data->strings_size = 0;
649 else
651 data->strings_size = bfd_h_get_32 (abfd, stsz_arr);
652 if (data->strings_size > sizeof (stsz_arr))
654 unsigned int remsz = data->strings_size - sizeof (stsz_arr);
656 data->strings = xmalloc (data->strings_size);
658 memcpy (data->strings, stsz_arr, sizeof (stsz_arr));
659 if (bfd_bread (data->strings + sizeof (stsz_arr), remsz, abfd)
660 != remsz)
662 non_fatal (_("cannot read strings table"));
663 goto clean;
668 if (bfd_seek (abfd, data->symptr, SEEK_SET) != 0)
670 non_fatal (_("cannot read symbol table"));
671 goto clean;
674 data->syms = (union xcoff32_symbol *)
675 xmalloc (data->nsyms * sizeof (union xcoff32_symbol));
677 for (i = 0; i < data->nsyms; i++)
679 struct external_syment sym;
680 int j;
681 union xcoff32_symbol *s = &data->syms[i];
683 if (bfd_bread (&sym, sizeof (sym), abfd) != sizeof (sym))
685 non_fatal (_("cannot read symbol entry"));
686 goto clean;
689 s->sym.val = bfd_h_get_32 (abfd, sym.e_value);
690 s->sym.scnum = bfd_h_get_16 (abfd, sym.e_scnum);
691 s->sym.ntype = bfd_h_get_16 (abfd, sym.e_type);
692 s->sym.sclass = bfd_h_get_8 (abfd, sym.e_sclass);
693 s->sym.numaux = bfd_h_get_8 (abfd, sym.e_numaux);
695 if (sym.e.e_name[0])
697 memcpy (s->sym.raw.name, sym.e.e_name, sizeof (sym.e.e_name));
698 s->sym.raw.name[8] = 0;
699 s->sym.name = s->sym.raw.name;
701 else
703 unsigned int soff = bfd_h_get_32 (abfd, sym.e.e.e_offset);
705 if ((s->sym.sclass & DBXMASK) == 0 && soff < data->strings_size)
706 s->sym.name = data->strings + soff;
707 else
709 s->sym.name = NULL;
710 s->sym.raw.off = soff;
714 for (j = 0; j < s->sym.numaux; j++, i++)
716 if (bfd_bread (&s[j + 1].aux,
717 sizeof (union external_auxent), abfd)
718 != sizeof (union external_auxent))
720 non_fatal (_("cannot read symbol aux entry"));
721 goto clean;
725 return;
726 clean:
727 free (data->syms);
728 data->syms = NULL;
729 free (data->strings);
730 data->strings = NULL;
733 /* Dump xcoff symbols. */
735 static void
736 dump_xcoff32_symbols (bfd *abfd, struct xcoff_dump *data)
738 unsigned int i;
739 asection *debugsec;
740 char *debug = NULL;
742 printf (_("Symbols table (strtable at 0x%08x)"),
743 data->symptr
744 + data->nsyms * (unsigned)sizeof (struct external_syment));
745 if (data->nsyms == 0 || data->syms == NULL)
747 printf (_(":\n No symbols\n"));
748 return;
751 /* Read strings table. */
752 if (data->strings_size == 0)
753 printf (_(" (no strings):\n"));
754 else
755 printf (_(" (strings size: %08x):\n"), data->strings_size);
757 /* Read debug section. */
758 debugsec = bfd_get_section_by_name (abfd, ".debug");
759 if (debugsec != NULL)
761 bfd_size_type size;
763 size = bfd_get_section_size (debugsec);
764 debug = (char *) xmalloc (size);
765 bfd_get_section_contents (abfd, debugsec, debug, 0, size);
768 /* Translators: 'sc' is for storage class, 'off' for offset. */
769 printf (_(" # sc value section type aux name/off\n"));
770 for (i = 0; i < data->nsyms; i++)
772 union xcoff32_symbol *s = &data->syms[i];
773 int j;
775 printf ("%3u ", i);
776 dump_value (sc_xlat, s->sym.sclass, 10);
777 printf (" %08x ", s->sym.val);
778 if (s->sym.scnum > 0 && s->sym.scnum <= data->nscns)
780 if (data->sects != NULL)
781 printf ("%-8s", data->sects[s->sym.scnum - 1].name);
782 else
783 printf ("%-8u", s->sym.scnum);
785 else
786 switch ((signed short)s->sym.scnum)
788 case N_DEBUG:
789 printf ("N_DEBUG ");
790 break;
791 case N_ABS:
792 printf ("N_ABS ");
793 break;
794 case N_UNDEF:
795 printf ("N_UNDEF ");
796 break;
797 default:
798 printf ("(%04x) ", s->sym.scnum);
800 printf (" %04x %3u ", s->sym.ntype, s->sym.numaux);
801 if (s->sym.name != NULL)
802 printf ("%s", s->sym.name);
803 else
805 if ((s->sym.sclass & DBXMASK) != 0 && debug != NULL)
806 printf ("%s", debug + s->sym.raw.off);
807 else
808 printf ("%08x", s->sym.raw.off);
810 putchar ('\n');
812 for (j = 0; j < s->sym.numaux; j++, i++)
814 union external_auxent *aux = &s[j + 1].aux;
816 printf (" %3u ", i + 1);
817 switch (s->sym.sclass)
819 case C_STAT:
820 /* Section length, number of relocs and line number. */
821 printf (_(" scnlen: %08x nreloc: %-6u nlinno: %-6u\n"),
822 (unsigned)bfd_h_get_32 (abfd, aux->x_scn.x_scnlen),
823 (unsigned)bfd_h_get_16 (abfd, aux->x_scn.x_nreloc),
824 (unsigned)bfd_h_get_16 (abfd, aux->x_scn.x_nlinno));
825 break;
826 case C_DWARF:
827 /* Section length and number of relocs. */
828 printf (_(" scnlen: %08x nreloc: %-6u\n"),
829 (unsigned)bfd_h_get_32 (abfd, aux->x_scn.x_scnlen),
830 (unsigned)bfd_h_get_16 (abfd, aux->x_scn.x_nreloc));
831 break;
832 case C_EXT:
833 case C_WEAKEXT:
834 case C_HIDEXT:
835 if (j == 0 && s->sym.numaux > 1)
837 /* Function aux entry (Do not translate). */
838 printf (" exptr: %08x fsize: %08x lnnoptr: %08x endndx: %u\n",
839 (unsigned)bfd_h_get_32 (abfd, aux->x_sym.x_tagndx),
840 (unsigned)bfd_h_get_32
841 (abfd, aux->x_sym.x_misc.x_fsize),
842 (unsigned)bfd_h_get_32
843 (abfd, aux->x_sym.x_fcnary.x_fcn.x_lnnoptr),
844 (unsigned)bfd_h_get_32
845 (abfd, aux->x_sym.x_fcnary.x_fcn.x_endndx));
847 else if (j == 1 || (j == 0 && s->sym.numaux == 1))
849 /* csect aux entry. */
850 unsigned char smtyp;
851 unsigned int scnlen;
853 smtyp = bfd_h_get_8 (abfd, aux->x_csect.x_smtyp);
854 scnlen = bfd_h_get_32 (abfd, aux->x_csect.x_scnlen);
856 if (smtyp == XTY_LD)
857 printf (" scnsym: %-8u", scnlen);
858 else
859 printf (" scnlen: %08x", scnlen);
860 printf (" h: parm=%08x sn=%04x al: 2**%u",
861 (unsigned)bfd_h_get_32 (abfd, aux->x_csect.x_parmhash),
862 (unsigned)bfd_h_get_16 (abfd, aux->x_csect.x_snhash),
863 SMTYP_ALIGN (smtyp));
864 printf (" typ: ");
865 dump_value (smtyp_xlat, SMTYP_SMTYP (smtyp), 2);
866 printf (" cl: ");
867 dump_value
868 (smclas_xlat,
869 (unsigned)bfd_h_get_8 (abfd, aux->x_csect.x_smclas), 6);
870 putchar ('\n');
872 else
873 /* Do not translate - generic field name. */
874 printf ("aux\n");
875 break;
876 case C_FILE:
878 unsigned int off;
880 printf (" ftype: %02x ",
881 (unsigned)bfd_h_get_8 (abfd, aux->x_file.x_ftype));
882 if (aux->x_file.x_n.x_fname[0] != 0)
883 printf ("fname: %.14s", aux->x_file.x_n.x_fname);
884 else
886 off = (unsigned)bfd_h_get_32
887 (abfd, aux->x_file.x_n.x_n.x_offset);
888 if (data->strings != NULL && off < data->strings_size)
889 printf (" %s", data->strings + off);
890 else
891 printf (_("offset: %08x"), off);
893 putchar ('\n');
895 break;
896 case C_BLOCK:
897 case C_FCN:
898 printf (" lnno: %u\n",
899 (unsigned)bfd_h_get_16
900 (abfd, aux->x_sym.x_misc.x_lnsz.x_lnno));
901 break;
902 default:
903 /* Do not translate - generic field name. */
904 printf ("aux\n");
905 break;
910 free (debug);
913 /* Dump xcoff relocation entries. */
915 static void
916 dump_xcoff32_relocs (bfd *abfd, struct xcoff_dump *data)
918 unsigned int i;
920 if (data->sects == NULL)
922 non_fatal (_("cannot read section headers"));
923 return;
926 for (i = 0; i < data->nscns; i++)
928 struct xcoff32_section *sect = &data->sects[i];
929 unsigned int nrel = sect->nreloc;
930 unsigned int j;
932 if (nrel == 0)
933 continue;
934 printf (_("Relocations for %s (%u)\n"), sect->name, nrel);
935 if (bfd_seek (abfd, sect->relptr, SEEK_SET) != 0)
937 non_fatal (_("cannot read relocations"));
938 continue;
940 /* Do not translate: fields name. */
941 printf ("vaddr sgn mod sz type symndx symbol\n");
942 for (j = 0; j < nrel; j++)
944 struct external_reloc rel;
945 unsigned char rsize;
946 unsigned int symndx;
948 if (bfd_bread (&rel, sizeof (rel), abfd) != sizeof (rel))
950 non_fatal (_("cannot read relocation entry"));
951 return;
953 rsize = bfd_h_get_8 (abfd, rel.r_size);
954 printf ("%08x %c %c %-2u ",
955 (unsigned int)bfd_h_get_32 (abfd, rel.r_vaddr),
956 rsize & 0x80 ? 'S' : 'U',
957 rsize & 0x40 ? 'm' : ' ',
958 (rsize & 0x3f) + 1);
959 dump_value (rtype_xlat, bfd_h_get_8 (abfd, rel.r_type), 6);
960 symndx = bfd_h_get_32 (abfd, rel.r_symndx);
961 printf ("%-6u ", symndx);
962 xcoff32_print_symbol (data, symndx);
963 putchar ('\n');
965 putchar ('\n');
969 /* Dump xcoff line number entries. */
971 static void
972 dump_xcoff32_lineno (bfd *abfd, struct xcoff_dump *data)
974 unsigned int i;
976 if (data->sects == NULL)
978 non_fatal (_("cannot read section headers"));
979 return;
982 for (i = 0; i < data->nscns; i++)
984 struct xcoff32_section *sect = &data->sects[i];
985 unsigned int nlnno = sect->nlnno;
986 unsigned int j;
988 if (nlnno == 0)
989 continue;
990 printf (_("Line numbers for %s (%u)\n"), sect->name, nlnno);
991 if (bfd_seek (abfd, sect->lnnoptr, SEEK_SET) != 0)
993 non_fatal (_("cannot read line numbers"));
994 continue;
996 /* Line number, symbol index and physical address. */
997 printf (_("lineno symndx/paddr\n"));
998 for (j = 0; j < nlnno; j++)
1000 struct external_lineno ln;
1001 unsigned int no;
1003 if (bfd_bread (&ln, sizeof (ln), abfd) != sizeof (ln))
1005 non_fatal (_("cannot read line number entry"));
1006 return;
1008 no = bfd_h_get_16 (abfd, ln.l_lnno);
1009 printf (" %-6u ", no);
1010 if (no == 0)
1012 unsigned int symndx = bfd_h_get_32 (abfd, ln.l_addr.l_symndx);
1013 xcoff32_print_symbol (data, symndx);
1015 else
1016 printf ("0x%08x",
1017 (unsigned int)bfd_h_get_32 (abfd, ln.l_addr.l_paddr));
1018 putchar ('\n');
1023 /* Dump xcoff loader section. */
1025 static void
1026 dump_xcoff32_loader (bfd *abfd)
1028 asection *loader;
1029 bfd_size_type size = 0;
1030 struct external_ldhdr *lhdr;
1031 struct external_ldsym *ldsym;
1032 struct external_ldrel *ldrel;
1033 bfd_byte *ldr_data;
1034 unsigned int version;
1035 unsigned int ndsyms;
1036 unsigned int ndrel;
1037 unsigned int stlen;
1038 unsigned int stoff;
1039 unsigned int impoff;
1040 unsigned int nimpid;
1041 unsigned int i;
1042 const char *p;
1044 loader = bfd_get_section_by_name (abfd, ".loader");
1046 if (loader == NULL)
1048 printf (_("no .loader section in file\n"));
1049 return;
1051 size = bfd_get_section_size (loader);
1052 if (size < sizeof (*lhdr))
1054 printf (_("section .loader is too short\n"));
1055 return;
1058 ldr_data = (bfd_byte *) xmalloc (size);
1059 bfd_get_section_contents (abfd, loader, ldr_data, 0, size);
1060 lhdr = (struct external_ldhdr *)ldr_data;
1061 printf (_("Loader header:\n"));
1062 version = bfd_h_get_32 (abfd, lhdr->l_version);
1063 printf (_(" version: %u\n"), version);
1064 if (version != 1)
1066 printf (_(" Unhandled version\n"));
1067 free (ldr_data);
1068 return;
1070 ndsyms = bfd_h_get_32 (abfd, lhdr->l_nsyms);
1071 printf (_(" nbr symbols: %u\n"), ndsyms);
1072 ndrel = bfd_h_get_32 (abfd, lhdr->l_nreloc);
1073 printf (_(" nbr relocs: %u\n"), ndrel);
1074 /* Import string table length. */
1075 printf (_(" import strtab len: %u\n"),
1076 (unsigned) bfd_h_get_32 (abfd, lhdr->l_istlen));
1077 nimpid = bfd_h_get_32 (abfd, lhdr->l_nimpid);
1078 printf (_(" nbr import files: %u\n"), nimpid);
1079 impoff = bfd_h_get_32 (abfd, lhdr->l_impoff);
1080 printf (_(" import file off: %u\n"), impoff);
1081 stlen = bfd_h_get_32 (abfd, lhdr->l_stlen);
1082 printf (_(" string table len: %u\n"), stlen);
1083 stoff = bfd_h_get_32 (abfd, lhdr->l_stoff);
1084 printf (_(" string table off: %u\n"), stoff);
1086 ldsym = (struct external_ldsym *)(ldr_data + sizeof (*lhdr));
1087 printf (_("Dynamic symbols:\n"));
1088 /* Do not translate: field names. */
1089 printf (" # value sc IFEW ty class file pa name\n");
1090 for (i = 0; i < ndsyms; i++, ldsym++)
1092 unsigned char smtype;
1094 printf (_(" %4u %08x %3u "), i,
1095 (unsigned)bfd_h_get_32 (abfd, ldsym->l_value),
1096 (unsigned)bfd_h_get_16 (abfd, ldsym->l_scnum));
1097 smtype = bfd_h_get_8 (abfd, ldsym->l_smtype);
1098 putchar (smtype & 0x40 ? 'I' : ' ');
1099 putchar (smtype & 0x20 ? 'F' : ' ');
1100 putchar (smtype & 0x10 ? 'E' : ' ');
1101 putchar (smtype & 0x08 ? 'W' : ' ');
1102 putchar (' ');
1103 dump_value (smtyp_xlat, SMTYP_SMTYP (smtype), 2);
1104 putchar (' ');
1105 dump_value
1106 (smclas_xlat, (unsigned)bfd_h_get_8 (abfd, ldsym->l_smclas), 6);
1107 printf (_(" %3u %3u "),
1108 (unsigned)bfd_h_get_32 (abfd, ldsym->l_ifile),
1109 (unsigned)bfd_h_get_32 (abfd, ldsym->l_parm));
1110 if (ldsym->_l._l_name[0] != 0)
1111 printf ("%-.8s", ldsym->_l._l_name);
1112 else
1114 unsigned int off = bfd_h_get_32 (abfd, ldsym->_l._l_l._l_offset);
1115 if (off > stlen)
1116 printf (_("(bad offset: %u)"), off);
1117 else
1118 printf ("%s", ldr_data + stoff + off);
1120 putchar ('\n');
1123 printf (_("Dynamic relocs:\n"));
1124 /* Do not translate fields name. */
1125 printf (" vaddr sec sz typ sym\n");
1126 ldrel = (struct external_ldrel *)(ldr_data + sizeof (*lhdr)
1127 + ndsyms * sizeof (*ldsym));
1128 for (i = 0; i < ndrel; i++, ldrel++)
1130 unsigned int rsize;
1131 unsigned int rtype;
1132 unsigned int symndx;
1134 rsize = bfd_h_get_8 (abfd, ldrel->l_rtype + 0);
1135 rtype = bfd_h_get_8 (abfd, ldrel->l_rtype + 1);
1137 printf (" %08x %3u %c%c %2u ",
1138 (unsigned)bfd_h_get_32 (abfd, ldrel->l_vaddr),
1139 (unsigned)bfd_h_get_16 (abfd, ldrel->l_rsecnm),
1140 rsize & 0x80 ? 'S' : 'U',
1141 rsize & 0x40 ? 'm' : ' ',
1142 (rsize & 0x3f) + 1);
1143 dump_value (rtype_xlat, rtype, 6);
1144 symndx = bfd_h_get_32 (abfd, ldrel->l_symndx);
1145 switch (symndx)
1147 case 0:
1148 printf (".text");
1149 break;
1150 case 1:
1151 printf (".data");
1152 break;
1153 case 2:
1154 printf (".bss");
1155 break;
1156 default:
1157 printf ("%u", symndx - 3);
1158 break;
1160 putchar ('\n');
1163 printf (_("Import files:\n"));
1164 p = (char *)ldr_data + impoff;
1165 for (i = 0; i < nimpid; i++)
1167 int n1, n2, n3;
1169 n1 = strlen (p);
1170 n2 = strlen (p + n1 + 1);
1171 n3 = strlen (p + n1 + 1 + n2+ 1);
1172 printf (" %2u: %s,%s,%s\n", i,
1173 p, p + n1 + 1, p + n1 + n2 + 2);
1174 p += n1 + n2 + n3 + 3;
1177 free (ldr_data);
1180 /* Dump xcoff exception section. */
1182 static void
1183 dump_xcoff32_except (bfd *abfd, struct xcoff_dump *data)
1185 asection *sec;
1186 bfd_size_type size = 0;
1187 bfd_byte *excp_data;
1188 struct external_exceptab *exceptab;
1189 unsigned int i;
1191 sec = bfd_get_section_by_name (abfd, ".except");
1193 if (sec == NULL)
1195 printf (_("no .except section in file\n"));
1196 return;
1198 size = bfd_get_section_size (sec);
1199 excp_data = (bfd_byte *) xmalloc (size);
1200 bfd_get_section_contents (abfd, sec, excp_data, 0, size);
1201 exceptab = (struct external_exceptab *)excp_data;
1203 printf (_("Exception table:\n"));
1204 /* Do not translate fields name. */
1205 printf ("lang reason sym/addr\n");
1206 for (i = 0; i * sizeof (*exceptab) < size; i++, exceptab++)
1208 unsigned int reason;
1209 unsigned int addr;
1211 addr = bfd_get_32 (abfd, exceptab->e_addr.e_paddr);
1212 reason = bfd_get_8 (abfd, exceptab->e_reason);
1213 printf (" %02x %02x ",
1214 (unsigned) bfd_get_8 (abfd, exceptab->e_lang), reason);
1215 if (reason == 0)
1216 xcoff32_print_symbol (data, addr);
1217 else
1218 printf ("@%08x", addr);
1219 putchar ('\n');
1221 free (excp_data);
1224 /* Dump xcoff type-check section. */
1226 static void
1227 dump_xcoff32_typchk (bfd *abfd)
1229 asection *sec;
1230 bfd_size_type size = 0;
1231 bfd_byte *data;
1232 unsigned int i;
1234 sec = bfd_get_section_by_name (abfd, ".typchk");
1236 if (sec == NULL)
1238 printf (_("no .typchk section in file\n"));
1239 return;
1241 size = bfd_get_section_size (sec);
1242 data = (bfd_byte *) xmalloc (size);
1243 bfd_get_section_contents (abfd, sec, data, 0, size);
1245 printf (_("Type-check section:\n"));
1246 /* Do not translate field names. */
1247 printf ("offset len lang-id general-hash language-hash\n");
1248 for (i = 0; i < size;)
1250 unsigned int len;
1252 len = bfd_get_16 (abfd, data + i);
1253 printf ("%08x: %-4u ", i, len);
1254 i += 2;
1256 if (len == 10)
1258 /* Expected format. */
1259 printf ("%04x %08x %08x\n",
1260 (unsigned) bfd_get_16 (abfd, data + i),
1261 (unsigned) bfd_get_32 (abfd, data + i + 2),
1262 (unsigned) bfd_get_32 (abfd, data + i + 2 + 4));
1264 else
1266 unsigned int j;
1268 for (j = 0; j < len; j++)
1270 if (j % 16 == 0)
1271 printf ("\n ");
1272 printf (" %02x", (unsigned char)data[i + j]);
1274 putchar ('\n');
1276 i += len;
1278 free (data);
1281 /* Dump xcoff traceback tags section. */
1283 static void
1284 dump_xcoff32_tbtags (bfd *abfd,
1285 const char *text, bfd_size_type text_size,
1286 unsigned int text_start, unsigned int func_start)
1288 unsigned int i;
1290 if (func_start - text_start > text_size)
1292 printf (_(" address beyond section size\n"));
1293 return;
1295 for (i = func_start - text_start; i < text_size; i+= 4)
1296 if (bfd_get_32 (abfd, text + i) == 0)
1298 unsigned int tb1;
1299 unsigned int tb2;
1300 unsigned int off;
1302 printf (_(" tags at %08x\n"), i + 4);
1303 if (i + 8 >= text_size)
1304 goto truncated;
1306 tb1 = bfd_get_32 (abfd, text + i + 4);
1307 tb2 = bfd_get_32 (abfd, text + i + 8);
1308 off = i + 12;
1309 printf (" version: %u, lang: %u, global_link: %u, is_eprol: %u, has_tboff: %u, int_proc: %u\n",
1310 (tb1 >> 24) & 0xff,
1311 (tb1 >> 16) & 0xff,
1312 (tb1 >> 15) & 1,
1313 (tb1 >> 14) & 1,
1314 (tb1 >> 13) & 1,
1315 (tb1 >> 12) & 1);
1316 printf (" has_ctl: %u, tocless: %u, fp_pres: %u, log_abort: %u, int_hndl: %u\n",
1317 (tb1 >> 11) & 1,
1318 (tb1 >> 10) & 1,
1319 (tb1 >> 9) & 1,
1320 (tb1 >> 8) & 1,
1321 (tb1 >> 7) & 1);
1322 printf (" name_pres: %u, uses_alloca: %u, cl_dis_inv: %u, saves_cr: %u, saves_lr: %u\n",
1323 (tb1 >> 6) & 1,
1324 (tb1 >> 5) & 1,
1325 (tb1 >> 2) & 7,
1326 (tb1 >> 1) & 1,
1327 (tb1 >> 0) & 1);
1328 printf (" stores_bc: %u, fixup: %u, fpr_saved: %-2u, spare3: %u, gpr_saved: %-2u\n",
1329 (tb2 >> 31) & 1,
1330 (tb2 >> 30) & 1,
1331 (tb2 >> 24) & 63,
1332 (tb2 >> 22) & 3,
1333 (tb2 >> 16) & 63);
1334 printf (" fixparms: %-3u floatparms: %-3u parm_on_stk: %u\n",
1335 (tb2 >> 8) & 0xff,
1336 (tb2 >> 1) & 0x7f,
1337 (tb2 >> 0) & 1);
1339 if (((tb2 >> 1) & 0x7fff) != 0)
1341 unsigned int parminfo;
1343 if (off >= text_size)
1344 goto truncated;
1345 parminfo = bfd_get_32 (abfd, text + off);
1346 off += 4;
1347 printf (" parminfo: 0x%08x\n", parminfo);
1350 if ((tb1 >> 13) & 1)
1352 unsigned int tboff;
1354 if (off >= text_size)
1355 goto truncated;
1356 tboff = bfd_get_32 (abfd, text + off);
1357 off += 4;
1358 printf (" tb_offset: 0x%08x (start=0x%08x)\n",
1359 tboff, text_start + i - tboff);
1361 if ((tb1 >> 7) & 1)
1363 unsigned int hand_mask;
1365 if (off >= text_size)
1366 goto truncated;
1367 hand_mask = bfd_get_32 (abfd, text + off);
1368 off += 4;
1369 printf (" hand_mask_offset: 0x%08x\n", hand_mask);
1371 if ((tb1 >> 11) & 1)
1373 unsigned int ctl_info;
1374 unsigned int j;
1376 if (off >= text_size)
1377 goto truncated;
1378 ctl_info = bfd_get_32 (abfd, text + off);
1379 off += 4;
1380 printf (_(" number of CTL anchors: %u\n"), ctl_info);
1381 for (j = 0; j < ctl_info; j++)
1383 if (off >= text_size)
1384 goto truncated;
1385 printf (" CTL[%u]: %08x\n",
1386 j, (unsigned)bfd_get_32 (abfd, text + off));
1387 off += 4;
1390 if ((tb1 >> 6) & 1)
1392 unsigned int name_len;
1393 unsigned int j;
1395 if (off >= text_size)
1396 goto truncated;
1397 name_len = bfd_get_16 (abfd, text + off);
1398 off += 2;
1399 printf (_(" Name (len: %u): "), name_len);
1400 if (off + name_len >= text_size)
1402 printf (_("[truncated]\n"));
1403 goto truncated;
1405 for (j = 0; j < name_len; j++)
1406 if (ISPRINT (text[off + j]))
1407 putchar (text[off + j]);
1408 else
1409 printf ("[%02x]", (unsigned char)text[off + j]);
1410 putchar ('\n');
1411 off += name_len;
1413 if ((tb1 >> 5) & 1)
1415 if (off >= text_size)
1416 goto truncated;
1417 printf (" alloca reg: %u\n",
1418 (unsigned) bfd_get_8 (abfd, text + off));
1419 off++;
1421 printf (_(" (end of tags at %08x)\n"), text_start + off);
1422 return;
1424 printf (_(" no tags found\n"));
1425 return;
1427 truncated:
1428 printf (_(" Truncated .text section\n"));
1429 return;
1432 static void
1433 dump_xcoff32_traceback (bfd *abfd, struct xcoff_dump *data)
1435 unsigned int i;
1436 unsigned int scnum_text = -1;
1437 unsigned int text_vma;
1438 asection *text_sec;
1439 bfd_size_type text_size;
1440 char *text;
1442 if (data->syms == NULL || data->sects == NULL)
1443 return;
1445 /* Read text section. */
1446 text_sec = bfd_get_section_by_name (abfd, ".text");
1447 if (text_sec == NULL)
1448 return;
1449 text_vma = bfd_get_section_vma (abfd, text_sec);
1451 text_size = bfd_get_section_size (text_sec);
1452 text = (char *) xmalloc (text_size);
1453 bfd_get_section_contents (abfd, text_sec, text, 0, text_size);
1455 for (i = 0; i < data->nscns; i++)
1456 if (data->sects[i].flags == STYP_TEXT)
1458 scnum_text = i + 1;
1459 break;
1461 if (scnum_text == (unsigned int)-1)
1462 return;
1464 for (i = 0; i < data->nsyms; i++)
1466 union xcoff32_symbol *s = &data->syms[i];
1468 switch (s->sym.sclass)
1470 case C_EXT:
1471 case C_HIDEXT:
1472 case C_WEAKEXT:
1473 if (s->sym.scnum == scnum_text
1474 && s->sym.numaux > 0)
1476 union external_auxent *aux = &s[s->sym.numaux].aux;
1478 unsigned int smtyp;
1479 unsigned int smclas;
1481 smtyp = bfd_h_get_8 (abfd, aux->x_csect.x_smtyp);
1482 smclas = bfd_h_get_8 (abfd, aux->x_csect.x_smclas);
1483 if (SMTYP_SMTYP (smtyp) == XTY_LD
1484 && (smclas == XMC_PR
1485 || smclas == XMC_GL
1486 || smclas == XMC_XO))
1488 printf ("%08x: ", s->sym.val);
1489 xcoff32_print_symbol (data, i);
1490 putchar ('\n');
1491 dump_xcoff32_tbtags (abfd, text, text_size,
1492 text_vma, s->sym.val);
1495 break;
1496 default:
1497 break;
1499 i += s->sym.numaux;
1501 free (text);
1504 /* Dump the TOC symbols. */
1506 static void
1507 dump_xcoff32_toc (bfd *abfd, struct xcoff_dump *data)
1509 unsigned int i;
1510 unsigned int nbr_ent;
1511 unsigned int size;
1513 printf (_("TOC:\n"));
1515 if (data->syms == NULL)
1516 return;
1518 nbr_ent = 0;
1519 size = 0;
1521 for (i = 0; i < data->nsyms; i++)
1523 union xcoff32_symbol *s = &data->syms[i];
1525 switch (s->sym.sclass)
1527 case C_EXT:
1528 case C_HIDEXT:
1529 case C_WEAKEXT:
1530 if (s->sym.numaux > 0)
1532 union external_auxent *aux = &s[s->sym.numaux].aux;
1533 unsigned int smclas;
1534 unsigned int ent_sz;
1536 smclas = bfd_h_get_8 (abfd, aux->x_csect.x_smclas);
1537 if (smclas == XMC_TC
1538 || smclas == XMC_TD
1539 || smclas == XMC_TC0)
1541 ent_sz = bfd_h_get_32 (abfd, aux->x_scn.x_scnlen);
1542 printf ("%08x %08x ",
1543 s->sym.val, ent_sz);
1544 xcoff32_print_symbol (data, i);
1545 putchar ('\n');
1546 nbr_ent++;
1547 size += ent_sz;
1550 break;
1551 default:
1552 break;
1554 i += s->sym.numaux;
1556 printf (_("Nbr entries: %-8u Size: %08x (%u)\n"),
1557 nbr_ent, size, size);
1560 /* Handle an rs6000 xcoff file. */
1562 static void
1563 dump_xcoff32 (bfd *abfd, struct external_filehdr *fhdr)
1565 struct xcoff_dump data;
1567 data.nscns = bfd_h_get_16 (abfd, fhdr->f_nscns);
1568 data.symptr = bfd_h_get_32 (abfd, fhdr->f_symptr);
1569 data.nsyms = bfd_h_get_32 (abfd, fhdr->f_nsyms);
1570 data.opthdr = bfd_h_get_16 (abfd, fhdr->f_opthdr);
1571 data.sects = NULL;
1572 data.syms = NULL;
1573 data.strings = NULL;
1574 data.strings_size = 0;
1576 if (options[OPT_FILE_HEADER].selected)
1577 dump_xcoff32_file_header (abfd, fhdr, &data);
1579 if (options[OPT_AOUT].selected)
1580 dump_xcoff32_aout_header (abfd, &data);
1582 if (options[OPT_SYMS].selected
1583 || options[OPT_RELOCS].selected
1584 || options[OPT_LINENO].selected
1585 || options[OPT_TRACEBACK].selected)
1586 xcoff32_read_sections (abfd, &data);
1588 if (options[OPT_SECTIONS].selected)
1589 dump_xcoff32_sections_header (abfd, &data);
1591 if (options[OPT_SYMS].selected
1592 || options[OPT_RELOCS].selected
1593 || options[OPT_LINENO].selected
1594 || options[OPT_EXCEPT].selected
1595 || options[OPT_TRACEBACK].selected
1596 || options[OPT_TOC].selected)
1597 xcoff32_read_symbols (abfd, &data);
1599 if (options[OPT_SYMS].selected)
1600 dump_xcoff32_symbols (abfd, &data);
1602 if (options[OPT_RELOCS].selected)
1603 dump_xcoff32_relocs (abfd, &data);
1605 if (options[OPT_LINENO].selected)
1606 dump_xcoff32_lineno (abfd, &data);
1608 if (options[OPT_LOADER].selected)
1609 dump_xcoff32_loader (abfd);
1611 if (options[OPT_EXCEPT].selected)
1612 dump_xcoff32_except (abfd, &data);
1614 if (options[OPT_TYPCHK].selected)
1615 dump_xcoff32_typchk (abfd);
1617 if (options[OPT_TRACEBACK].selected)
1618 dump_xcoff32_traceback (abfd, &data);
1620 if (options[OPT_TOC].selected)
1621 dump_xcoff32_toc (abfd, &data);
1623 free (data.sects);
1624 free (data.strings);
1625 free (data.syms);
1628 /* Dump ABFD (according to the options[] array). */
1630 static void
1631 xcoff_dump (bfd *abfd)
1633 struct external_filehdr fhdr;
1634 unsigned short magic;
1636 /* Read file header. */
1637 if (bfd_seek (abfd, 0, SEEK_SET) != 0
1638 || bfd_bread (&fhdr, sizeof (fhdr), abfd) != sizeof (fhdr))
1640 non_fatal (_("cannot read header"));
1641 return;
1644 /* Decoding. We don't use the bfd/coff function to get all the fields. */
1645 magic = bfd_h_get_16 (abfd, fhdr.f_magic);
1646 if (options[OPT_FILE_HEADER].selected)
1648 printf (_("File header:\n"));
1649 printf (_(" magic: 0x%04x (0%04o) "), magic, magic);
1650 switch (magic)
1652 case U802WRMAGIC:
1653 printf (_("(WRMAGIC: writable text segments)"));
1654 break;
1655 case U802ROMAGIC:
1656 printf (_("(ROMAGIC: readonly sharablee text segments)"));
1657 break;
1658 case U802TOCMAGIC:
1659 printf (_("(TOCMAGIC: readonly text segments and TOC)"));
1660 break;
1661 default:
1662 printf (_("unknown magic"));
1664 putchar ('\n');
1666 if (magic == U802ROMAGIC || magic == U802WRMAGIC || magic == U802TOCMAGIC)
1667 dump_xcoff32 (abfd, &fhdr);
1668 else
1669 printf (_(" Unhandled magic\n"));
1672 /* Vector for xcoff. */
1674 const struct objdump_private_desc objdump_private_desc_xcoff =
1676 xcoff_help,
1677 xcoff_filter,
1678 xcoff_dump,
1679 options