* gas/mips/loc-swap.s: Add file missing from a previous commit.
[binutils.git] / binutils / od-xcoff.c
blob5b8b5896eb59ae0daf5c65683e5391cffea22ed3
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 printf (_(" o_mflag (magic): 0x%04x 0%04o\n"), magic, magic);
463 printf (_(" o_vstamp: 0x%04x\n"),
464 (unsigned short)bfd_h_get_16 (abfd, auxhdr.vstamp));
465 printf (_(" o_tsize: 0x%08x\n"),
466 (unsigned int)bfd_h_get_32 (abfd, auxhdr.tsize));
467 printf (_(" o_dsize: 0x%08x\n"),
468 (unsigned int)bfd_h_get_32 (abfd, auxhdr.dsize));
469 printf (_(" o_entry: 0x%08x\n"),
470 (unsigned int)bfd_h_get_32 (abfd, auxhdr.entry));
471 printf (_(" o_text_start: 0x%08x\n"),
472 (unsigned int)bfd_h_get_32 (abfd, auxhdr.text_start));
473 printf (_(" o_data_start: 0x%08x\n"),
474 (unsigned int)bfd_h_get_32 (abfd, auxhdr.data_start));
475 if (sz == offsetof (AOUTHDR, o_toc))
476 return;
477 printf (_(" o_toc: 0x%08x\n"),
478 (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_toc));
479 printf (_(" o_snentry: 0x%04x\n"),
480 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snentry));
481 printf (_(" o_sntext: 0x%04x\n"),
482 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sntext));
483 printf (_(" o_sndata: 0x%04x\n"),
484 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sndata));
485 printf (_(" o_sntoc: 0x%04x\n"),
486 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sntoc));
487 printf (_(" o_snloader: 0x%04x\n"),
488 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snloader));
489 printf (_(" o_snbss: 0x%04x\n"),
490 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snbss));
491 printf (_(" o_algntext: %u\n"),
492 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_algntext));
493 printf (_(" o_algndata: %u\n"),
494 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_algndata));
495 printf (_(" o_modtype: 0x%04x"),
496 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_modtype));
497 if (ISPRINT (auxhdr.o_modtype[0]) && ISPRINT (auxhdr.o_modtype[1]))
498 printf (" (%c%c)", auxhdr.o_modtype[0], auxhdr.o_modtype[1]);
499 putchar ('\n');
500 printf (_(" o_cputype: 0x%04x\n"),
501 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_cputype));
502 printf (_(" o_maxstack: 0x%08x\n"),
503 (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_maxstack));
504 printf (_(" o_maxdata: 0x%08x\n"),
505 (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_maxdata));
506 #if 0
507 printf (_(" o_debugger: 0x%08x\n"),
508 (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_debugger));
509 #endif
512 /* Dump the sections header. */
514 static void
515 dump_xcoff32_sections_header (bfd *abfd, struct xcoff_dump *data)
517 unsigned int i;
518 unsigned int off;
520 off = sizeof (struct external_filehdr) + data->opthdr;
521 printf (_("Section headers (at %u+%u=0x%08x to 0x%08x):\n"),
522 (unsigned int)sizeof (struct external_filehdr), data->opthdr, off,
523 off + (unsigned int)sizeof (struct external_scnhdr) * data->nscns);
524 if (data->nscns == 0)
526 printf (_(" No section header\n"));
527 return;
529 if (bfd_seek (abfd, off, SEEK_SET) != 0)
531 non_fatal (_("cannot read section header"));
532 return;
534 printf (_(" # Name paddr vaddr size scnptr relptr lnnoptr nrel nlnno\n"));
535 for (i = 0; i < data->nscns; i++)
537 struct external_scnhdr scn;
538 unsigned int flags;
540 if (bfd_bread (&scn, sizeof (scn), abfd) != sizeof (scn))
542 non_fatal (_("cannot read section header"));
543 return;
545 flags = bfd_h_get_32 (abfd, scn.s_flags);
546 printf (_("%2d %-8.8s %08x %08x %08x %08x %08x %08x "
547 "%-5d %-5d\n"),
548 i + 1, scn.s_name,
549 (unsigned int)bfd_h_get_32 (abfd, scn.s_paddr),
550 (unsigned int)bfd_h_get_32 (abfd, scn.s_vaddr),
551 (unsigned int)bfd_h_get_32 (abfd, scn.s_size),
552 (unsigned int)bfd_h_get_32 (abfd, scn.s_scnptr),
553 (unsigned int)bfd_h_get_32 (abfd, scn.s_relptr),
554 (unsigned int)bfd_h_get_32 (abfd, scn.s_lnnoptr),
555 (unsigned int)bfd_h_get_16 (abfd, scn.s_nreloc),
556 (unsigned int)bfd_h_get_16 (abfd, scn.s_nlnno));
557 printf (_(" Flags: %08x "), flags);
559 if (~flags == 0)
561 /* Stripped executable ? */
562 putchar ('\n');
564 else if (flags & STYP_OVRFLO)
565 printf (_("overflow - nreloc: %u, nlnno: %u\n"),
566 (unsigned int)bfd_h_get_32 (abfd, scn.s_paddr),
567 (unsigned int)bfd_h_get_32 (abfd, scn.s_vaddr));
568 else
570 dump_flags (s_flag_xlat, flags);
571 putchar ('\n');
576 /* Read section table. */
578 static void
579 xcoff32_read_sections (bfd *abfd, struct xcoff_dump *data)
581 int i;
583 if (bfd_seek (abfd, sizeof (struct external_filehdr) + data->opthdr,
584 SEEK_SET) != 0)
586 non_fatal (_("cannot read section headers"));
587 return;
590 data->sects = xmalloc (data->nscns * sizeof (struct xcoff32_section));
591 for (i = 0; i < data->nscns; i++)
593 struct external_scnhdr scn;
594 struct xcoff32_section *s = &data->sects[i];
596 if (bfd_bread (&scn, sizeof (scn), abfd) != sizeof (scn))
598 non_fatal (_("cannot read section header"));
599 free (data->sects);
600 data->sects = NULL;
601 return;
603 memcpy (s->name, scn.s_name, 8);
604 s->name[8] = 0;
605 s->flags = bfd_h_get_32 (abfd, scn.s_flags);
607 s->scnptr = bfd_h_get_32 (abfd, scn.s_scnptr);
608 s->relptr = bfd_h_get_32 (abfd, scn.s_relptr);
609 s->lnnoptr = bfd_h_get_32 (abfd, scn.s_lnnoptr);
611 s->nreloc = bfd_h_get_16 (abfd, scn.s_nreloc);
612 s->nlnno = bfd_h_get_16 (abfd, scn.s_nlnno);
614 if (s->flags == STYP_OVRFLO)
616 if (s->nreloc > 0 && s->nreloc <= data->nscns)
617 data->sects[s->nreloc - 1].nreloc =
618 bfd_h_get_32 (abfd, scn.s_paddr);
619 if (s->nlnno > 0 && s->nlnno <= data->nscns)
620 data->sects[s->nlnno - 1].nlnno =
621 bfd_h_get_32 (abfd, scn.s_vaddr);
626 /* Read symbols. */
628 static void
629 xcoff32_read_symbols (bfd *abfd, struct xcoff_dump *data)
631 unsigned int i;
632 char stsz_arr[4];
633 unsigned int stptr;
635 if (data->nsyms == 0)
636 return;
638 stptr = data->symptr
639 + data->nsyms * (unsigned)sizeof (struct external_syment);
641 /* Read string table. */
642 if (bfd_seek (abfd, stptr, SEEK_SET) != 0
643 || bfd_bread (&stsz_arr, sizeof (stsz_arr), abfd) != sizeof (stsz_arr))
645 non_fatal (_("cannot read strings table length"));
646 data->strings_size = 0;
648 else
650 data->strings_size = bfd_h_get_32 (abfd, stsz_arr);
651 if (data->strings_size > sizeof (stsz_arr))
653 unsigned int remsz = data->strings_size - sizeof (stsz_arr);
655 data->strings = xmalloc (data->strings_size);
657 memcpy (data->strings, stsz_arr, sizeof (stsz_arr));
658 if (bfd_bread (data->strings + sizeof (stsz_arr), remsz, abfd)
659 != remsz)
661 non_fatal (_("cannot read strings table"));
662 goto clean;
667 if (bfd_seek (abfd, data->symptr, SEEK_SET) != 0)
669 non_fatal (_("cannot read symbol table"));
670 goto clean;
673 data->syms = (union xcoff32_symbol *)
674 xmalloc (data->nsyms * sizeof (union xcoff32_symbol));
676 for (i = 0; i < data->nsyms; i++)
678 struct external_syment sym;
679 int j;
680 union xcoff32_symbol *s = &data->syms[i];
682 if (bfd_bread (&sym, sizeof (sym), abfd) != sizeof (sym))
684 non_fatal (_("cannot read symbol entry"));
685 goto clean;
688 s->sym.val = bfd_h_get_32 (abfd, sym.e_value);
689 s->sym.scnum = bfd_h_get_16 (abfd, sym.e_scnum);
690 s->sym.ntype = bfd_h_get_16 (abfd, sym.e_type);
691 s->sym.sclass = bfd_h_get_8 (abfd, sym.e_sclass);
692 s->sym.numaux = bfd_h_get_8 (abfd, sym.e_numaux);
694 if (sym.e.e_name[0])
696 memcpy (s->sym.raw.name, sym.e.e_name, sizeof (sym.e.e_name));
697 s->sym.raw.name[8] = 0;
698 s->sym.name = s->sym.raw.name;
700 else
702 unsigned int soff = bfd_h_get_32 (abfd, sym.e.e.e_offset);
704 if ((s->sym.sclass & DBXMASK) == 0 && soff < data->strings_size)
705 s->sym.name = data->strings + soff;
706 else
708 s->sym.name = NULL;
709 s->sym.raw.off = soff;
713 for (j = 0; j < s->sym.numaux; j++, i++)
715 if (bfd_bread (&s[j + 1].aux,
716 sizeof (union external_auxent), abfd)
717 != sizeof (union external_auxent))
719 non_fatal (_("cannot read symbol aux entry"));
720 goto clean;
724 return;
725 clean:
726 free (data->syms);
727 data->syms = NULL;
728 free (data->strings);
729 data->strings = NULL;
732 /* Dump xcoff symbols. */
734 static void
735 dump_xcoff32_symbols (bfd *abfd, struct xcoff_dump *data)
737 unsigned int i;
738 asection *debugsec;
739 char *debug = NULL;
741 printf (_("Symbols table (strtable at 0x%08x)"),
742 data->symptr
743 + data->nsyms * (unsigned)sizeof (struct external_syment));
744 if (data->nsyms == 0 || data->syms == NULL)
746 printf (_(":\n No symbols\n"));
747 return;
750 /* Read string table. */
751 if (data->strings_size == 0)
752 printf (_(" (no strings):\n"));
753 else
754 printf (_(" (strings size: %08x):\n"), data->strings_size);
756 /* Read debug section. */
757 debugsec = bfd_get_section_by_name (abfd, ".debug");
758 if (debugsec != NULL)
760 bfd_size_type size;
762 size = bfd_get_section_size (debugsec);
763 debug = (char *) xmalloc (size);
764 bfd_get_section_contents (abfd, debugsec, debug, 0, size);
767 printf (_(" # sc value section type aux name/off\n"));
768 for (i = 0; i < data->nsyms; i++)
770 union xcoff32_symbol *s = &data->syms[i];
771 int j;
773 printf ("%3u ", i);
774 dump_value (sc_xlat, s->sym.sclass, 10);
775 printf (" %08x ", s->sym.val);
776 if (s->sym.scnum > 0 && s->sym.scnum <= data->nscns)
778 if (data->sects != NULL)
779 printf ("%-8s", data->sects[s->sym.scnum - 1].name);
780 else
781 printf ("%-8u", s->sym.scnum);
783 else
784 switch ((signed short)s->sym.scnum)
786 case N_DEBUG:
787 printf ("N_DEBUG ");
788 break;
789 case N_ABS:
790 printf ("N_ABS ");
791 break;
792 case N_UNDEF:
793 printf ("N_UNDEF ");
794 break;
795 default:
796 printf ("(%04x) ", s->sym.scnum);
798 printf (" %04x %3u ", s->sym.ntype, s->sym.numaux);
799 if (s->sym.name != NULL)
800 printf ("%s", s->sym.name);
801 else
803 if ((s->sym.sclass & DBXMASK) != 0 && debug != NULL)
804 printf ("%s", debug + s->sym.raw.off);
805 else
806 printf ("%08x", s->sym.raw.off);
808 putchar ('\n');
810 for (j = 0; j < s->sym.numaux; j++, i++)
812 union external_auxent *aux = &s[j + 1].aux;
814 printf (" %3u ", i + 1);
815 switch (s->sym.sclass)
817 case C_STAT:
818 printf (_(" scnlen: %08x nreloc: %-6u nlinno: %-6u\n"),
819 (unsigned)bfd_h_get_32 (abfd, aux->x_scn.x_scnlen),
820 (unsigned)bfd_h_get_16 (abfd, aux->x_scn.x_nreloc),
821 (unsigned)bfd_h_get_16 (abfd, aux->x_scn.x_nlinno));
822 break;
823 case C_DWARF:
824 printf (_(" scnlen: %08x nreloc: %-6u\n"),
825 (unsigned)bfd_h_get_32 (abfd, aux->x_scn.x_scnlen),
826 (unsigned)bfd_h_get_16 (abfd, aux->x_scn.x_nreloc));
827 break;
828 case C_EXT:
829 case C_WEAKEXT:
830 case C_HIDEXT:
831 if (j == 0 && s->sym.numaux > 1)
833 /* Function aux entry. */
834 printf (_(" exptr: %08x fsize: %08x lnnoptr: %08x endndx: %u\n"),
835 (unsigned)bfd_h_get_32 (abfd, aux->x_sym.x_tagndx),
836 (unsigned)bfd_h_get_32
837 (abfd, aux->x_sym.x_misc.x_fsize),
838 (unsigned)bfd_h_get_32
839 (abfd, aux->x_sym.x_fcnary.x_fcn.x_lnnoptr),
840 (unsigned)bfd_h_get_32
841 (abfd, aux->x_sym.x_fcnary.x_fcn.x_endndx));
843 else if (j == 1 || (j == 0 && s->sym.numaux == 1))
845 /* csect aux entry. */
846 unsigned char smtyp;
847 unsigned int scnlen;
849 smtyp = bfd_h_get_8 (abfd, aux->x_csect.x_smtyp);
850 scnlen = bfd_h_get_32 (abfd, aux->x_csect.x_scnlen);
852 if (smtyp == XTY_LD)
853 printf (_(" scnsym: %-8u"), scnlen);
854 else
855 printf (_(" scnlen: %08x"), scnlen);
856 printf (_(" h: parm=%08x sn=%04x al: 2**%u"),
857 (unsigned)bfd_h_get_32 (abfd, aux->x_csect.x_parmhash),
858 (unsigned)bfd_h_get_16 (abfd, aux->x_csect.x_snhash),
859 SMTYP_ALIGN (smtyp));
860 printf (_(" typ: "));
861 dump_value (smtyp_xlat, SMTYP_SMTYP (smtyp), 2);
862 printf (_(" cl: "));
863 dump_value
864 (smclas_xlat,
865 (unsigned)bfd_h_get_8 (abfd, aux->x_csect.x_smclas), 6);
866 putchar ('\n');
868 else
869 printf ("aux\n");
870 break;
871 case C_FILE:
873 unsigned int off;
875 printf (_(" ftype: %02x "),
876 (unsigned)bfd_h_get_8 (abfd, aux->x_file.x_ftype));
877 if (aux->x_file.x_n.x_fname[0] != 0)
878 printf (_("fname: %.14s"), aux->x_file.x_n.x_fname);
879 else
881 off = (unsigned)bfd_h_get_32
882 (abfd, aux->x_file.x_n.x_n.x_offset);
883 if (data->strings != NULL && off < data->strings_size)
884 printf (_(" %s"), data->strings + off);
885 else
886 printf (_("offset: %08x"), off);
888 putchar ('\n');
890 break;
891 case C_BLOCK:
892 case C_FCN:
893 printf (_(" lnno: %u\n"),
894 (unsigned)bfd_h_get_16
895 (abfd, aux->x_sym.x_misc.x_lnsz.x_lnno));
896 break;
897 default:
898 printf ("aux\n");
899 break;
904 free (debug);
907 /* Dump xcoff relocation entries. */
909 static void
910 dump_xcoff32_relocs (bfd *abfd, struct xcoff_dump *data)
912 unsigned int i;
914 if (data->sects == NULL)
916 non_fatal (_("cannot read section headers"));
917 return;
920 for (i = 0; i < data->nscns; i++)
922 struct xcoff32_section *sect = &data->sects[i];
923 unsigned int nrel = sect->nreloc;
924 unsigned int j;
926 if (nrel == 0)
927 continue;
928 printf (_("Relocations for %s (%u)\n"), sect->name, nrel);
929 if (bfd_seek (abfd, sect->relptr, SEEK_SET) != 0)
931 non_fatal (_("cannot read relocations"));
932 continue;
934 printf (_("vaddr sgn mod sz type symndx symbol\n"));
935 for (j = 0; j < nrel; j++)
937 struct external_reloc rel;
938 unsigned char rsize;
939 unsigned int symndx;
941 if (bfd_bread (&rel, sizeof (rel), abfd) != sizeof (rel))
943 non_fatal (_("cannot read relocation entry"));
944 return;
946 rsize = bfd_h_get_8 (abfd, rel.r_size);
947 printf (_("%08x %c %c %-2u "),
948 (unsigned int)bfd_h_get_32 (abfd, rel.r_vaddr),
949 rsize & 0x80 ? 'S' : 'U',
950 rsize & 0x40 ? 'm' : ' ',
951 (rsize & 0x3f) + 1);
952 dump_value (rtype_xlat, bfd_h_get_8 (abfd, rel.r_type), 6);
953 symndx = bfd_h_get_32 (abfd, rel.r_symndx);
954 printf ("%-6u ", symndx);
955 xcoff32_print_symbol (data, symndx);
956 putchar ('\n');
958 putchar ('\n');
962 /* Dump xcoff line number entries. */
964 static void
965 dump_xcoff32_lineno (bfd *abfd, struct xcoff_dump *data)
967 unsigned int i;
969 if (data->sects == NULL)
971 non_fatal (_("cannot read section headers"));
972 return;
975 for (i = 0; i < data->nscns; i++)
977 struct xcoff32_section *sect = &data->sects[i];
978 unsigned int nlnno = sect->nlnno;
979 unsigned int j;
981 if (nlnno == 0)
982 continue;
983 printf (_("Line numbers for %s (%u)\n"), sect->name, nlnno);
984 if (bfd_seek (abfd, sect->lnnoptr, SEEK_SET) != 0)
986 non_fatal (_("cannot read line numbers"));
987 continue;
989 printf (_("lineno symndx/paddr\n"));
990 for (j = 0; j < nlnno; j++)
992 struct external_lineno ln;
993 unsigned int no;
995 if (bfd_bread (&ln, sizeof (ln), abfd) != sizeof (ln))
997 non_fatal (_("cannot read line number entry"));
998 return;
1000 no = bfd_h_get_16 (abfd, ln.l_lnno);
1001 printf (_(" %-6u "), no);
1002 if (no == 0)
1004 unsigned int symndx = bfd_h_get_32 (abfd, ln.l_addr.l_symndx);
1005 xcoff32_print_symbol (data, symndx);
1007 else
1008 printf ("0x%08x",
1009 (unsigned int)bfd_h_get_32 (abfd, ln.l_addr.l_paddr));
1010 putchar ('\n');
1015 /* Dump xcoff loader section. */
1017 static void
1018 dump_xcoff32_loader (bfd *abfd)
1020 asection *loader;
1021 bfd_size_type size = 0;
1022 struct external_ldhdr *lhdr;
1023 struct external_ldsym *ldsym;
1024 struct external_ldrel *ldrel;
1025 bfd_byte *ldr_data;
1026 unsigned int version;
1027 unsigned int ndsyms;
1028 unsigned int ndrel;
1029 unsigned int stlen;
1030 unsigned int stoff;
1031 unsigned int impoff;
1032 unsigned int nimpid;
1033 unsigned int i;
1034 const char *p;
1036 loader = bfd_get_section_by_name (abfd, ".loader");
1038 if (loader == NULL)
1040 printf (_("no .loader section in file\n"));
1041 return;
1043 size = bfd_get_section_size (loader);
1044 if (size < sizeof (*lhdr))
1046 printf (_("section .loader is too short\n"));
1047 return;
1050 ldr_data = (bfd_byte *) xmalloc (size);
1051 bfd_get_section_contents (abfd, loader, ldr_data, 0, size);
1052 lhdr = (struct external_ldhdr *)ldr_data;
1053 printf (_("Loader header:\n"));
1054 version = bfd_h_get_32 (abfd, lhdr->l_version);
1055 printf (_(" version: %u\n"), version);
1056 if (version != 1)
1058 printf (_(" Unhandled version\n"));
1059 free (ldr_data);
1060 return;
1062 ndsyms = bfd_h_get_32 (abfd, lhdr->l_nsyms);
1063 printf (_(" nbr symbols: %u\n"), ndsyms);
1064 ndrel = bfd_h_get_32 (abfd, lhdr->l_nreloc);
1065 printf (_(" nbr relocs: %u\n"), ndrel);
1066 printf (_(" import strtab len: %u\n"),
1067 (unsigned) bfd_h_get_32 (abfd, lhdr->l_istlen));
1068 nimpid = bfd_h_get_32 (abfd, lhdr->l_nimpid);
1069 printf (_(" nbr import files: %u\n"), nimpid);
1070 impoff = bfd_h_get_32 (abfd, lhdr->l_impoff);
1071 printf (_(" import file off: %u\n"), impoff);
1072 stlen = bfd_h_get_32 (abfd, lhdr->l_stlen);
1073 printf (_(" string table len: %u\n"), stlen);
1074 stoff = bfd_h_get_32 (abfd, lhdr->l_stoff);
1075 printf (_(" string table off: %u\n"), stoff);
1077 ldsym = (struct external_ldsym *)(ldr_data + sizeof (*lhdr));
1078 printf (_("Dynamic symbols:\n"));
1079 printf (_(" # value sc IFEW ty class file pa name\n"));
1080 for (i = 0; i < ndsyms; i++, ldsym++)
1082 unsigned char smtype;
1084 printf (_(" %4u %08x %3u "), i,
1085 (unsigned)bfd_h_get_32 (abfd, ldsym->l_value),
1086 (unsigned)bfd_h_get_16 (abfd, ldsym->l_scnum));
1087 smtype = bfd_h_get_8 (abfd, ldsym->l_smtype);
1088 putchar (smtype & 0x40 ? 'I' : ' ');
1089 putchar (smtype & 0x20 ? 'F' : ' ');
1090 putchar (smtype & 0x10 ? 'E' : ' ');
1091 putchar (smtype & 0x08 ? 'W' : ' ');
1092 putchar (' ');
1093 dump_value (smtyp_xlat, SMTYP_SMTYP (smtype), 2);
1094 putchar (' ');
1095 dump_value
1096 (smclas_xlat, (unsigned)bfd_h_get_8 (abfd, ldsym->l_smclas), 6);
1097 printf (_(" %3u %3u "),
1098 (unsigned)bfd_h_get_32 (abfd, ldsym->l_ifile),
1099 (unsigned)bfd_h_get_32 (abfd, ldsym->l_parm));
1100 if (ldsym->_l._l_name[0] != 0)
1101 printf ("%-.8s", ldsym->_l._l_name);
1102 else
1104 unsigned int off = bfd_h_get_32 (abfd, ldsym->_l._l_l._l_offset);
1105 if (off > stlen)
1106 printf (_("(bad offset: %u)"), off);
1107 else
1108 printf ("%s", ldr_data + stoff + off);
1110 putchar ('\n');
1113 printf (_("Dynamic relocs:\n"));
1114 printf (_(" vaddr sec sz typ sym\n"));
1115 ldrel = (struct external_ldrel *)(ldr_data + sizeof (*lhdr)
1116 + ndsyms * sizeof (*ldsym));
1117 for (i = 0; i < ndrel; i++, ldrel++)
1119 unsigned int rsize;
1120 unsigned int rtype;
1121 unsigned int symndx;
1123 rsize = bfd_h_get_8 (abfd, ldrel->l_rtype + 0);
1124 rtype = bfd_h_get_8 (abfd, ldrel->l_rtype + 1);
1126 printf (_(" %08x %3u %c%c %2u "),
1127 (unsigned)bfd_h_get_32 (abfd, ldrel->l_vaddr),
1128 (unsigned)bfd_h_get_16 (abfd, ldrel->l_rsecnm),
1129 rsize & 0x80 ? 'S' : 'U',
1130 rsize & 0x40 ? 'm' : ' ',
1131 (rsize & 0x3f) + 1);
1132 dump_value (rtype_xlat, rtype, 6);
1133 symndx = bfd_h_get_32 (abfd, ldrel->l_symndx);
1134 switch (symndx)
1136 case 0:
1137 printf (_(".text"));
1138 break;
1139 case 1:
1140 printf (_(".data"));
1141 break;
1142 case 2:
1143 printf (_(".bss"));
1144 break;
1145 default:
1146 printf (_("%u"), symndx - 3);
1147 break;
1149 putchar ('\n');
1152 printf (_("Import files:\n"));
1153 p = (char *)ldr_data + impoff;
1154 for (i = 0; i < nimpid; i++)
1156 int n1, n2, n3;
1158 n1 = strlen (p);
1159 n2 = strlen (p + n1 + 1);
1160 n3 = strlen (p + n1 + 1 + n2+ 1);
1161 printf (" %2u: %s,%s,%s\n", i,
1162 p, p + n1 + 1, p + n1 + n2 + 2);
1163 p += n1 + n2 + n3 + 3;
1166 free (ldr_data);
1169 /* Dump xcoff exception section. */
1171 static void
1172 dump_xcoff32_except (bfd *abfd, struct xcoff_dump *data)
1174 asection *sec;
1175 bfd_size_type size = 0;
1176 bfd_byte *excp_data;
1177 struct external_exceptab *exceptab;
1178 unsigned int i;
1180 sec = bfd_get_section_by_name (abfd, ".except");
1182 if (sec == NULL)
1184 printf (_("no .except section in file\n"));
1185 return;
1187 size = bfd_get_section_size (sec);
1188 excp_data = (bfd_byte *) xmalloc (size);
1189 bfd_get_section_contents (abfd, sec, excp_data, 0, size);
1190 exceptab = (struct external_exceptab *)excp_data;
1192 printf (_("Exception table:\n"));
1193 printf (_("lang reason sym/addr\n"));
1194 for (i = 0; i * sizeof (*exceptab) < size; i++, exceptab++)
1196 unsigned int reason;
1197 unsigned int addr;
1199 addr = bfd_get_32 (abfd, exceptab->e_addr.e_paddr);
1200 reason = bfd_get_8 (abfd, exceptab->e_reason);
1201 printf (_(" %02x %02x "),
1202 (unsigned) bfd_get_8 (abfd, exceptab->e_lang), reason);
1203 if (reason == 0)
1204 xcoff32_print_symbol (data, addr);
1205 else
1206 printf (_("@%08x"), addr);
1207 putchar ('\n');
1209 free (excp_data);
1212 /* Dump xcoff type-check section. */
1214 static void
1215 dump_xcoff32_typchk (bfd *abfd)
1217 asection *sec;
1218 bfd_size_type size = 0;
1219 bfd_byte *data;
1220 unsigned int i;
1222 sec = bfd_get_section_by_name (abfd, ".typchk");
1224 if (sec == NULL)
1226 printf (_("no .typchk section in file\n"));
1227 return;
1229 size = bfd_get_section_size (sec);
1230 data = (bfd_byte *) xmalloc (size);
1231 bfd_get_section_contents (abfd, sec, data, 0, size);
1233 printf (_("Type-check section:\n"));
1234 printf (_("offset len lang-id general-hash language-hash\n"));
1235 for (i = 0; i < size;)
1237 unsigned int len;
1239 len = bfd_get_16 (abfd, data + i);
1240 printf ("%08x: %-4u ", i, len);
1241 i += 2;
1243 if (len == 10)
1245 /* Expected format. */
1246 printf ("%04x %08x %08x\n",
1247 (unsigned) bfd_get_16 (abfd, data + i),
1248 (unsigned) bfd_get_32 (abfd, data + i + 2),
1249 (unsigned) bfd_get_32 (abfd, data + i + 2 + 4));
1251 else
1253 unsigned int j;
1255 for (j = 0; j < len; j++)
1257 if (j % 16 == 0)
1258 printf ("\n ");
1259 printf (" %02x", (unsigned char)data[i + j]);
1261 putchar ('\n');
1263 i += len;
1265 free (data);
1268 /* Dump xcoff traceback tags section. */
1270 static void
1271 dump_xcoff32_tbtags (bfd *abfd,
1272 const char *text, bfd_size_type text_size,
1273 unsigned int text_start, unsigned int func_start)
1275 unsigned int i;
1277 if (func_start - text_start > text_size)
1279 printf (_(" address beyond section size\n"));
1280 return;
1282 for (i = func_start - text_start; i < text_size; i+= 4)
1283 if (bfd_get_32 (abfd, text + i) == 0)
1285 unsigned int tb1;
1286 unsigned int tb2;
1287 unsigned int off;
1289 printf (_(" tags at %08x\n"), i + 4);
1290 if (i + 8 >= text_size)
1291 goto truncated;
1293 tb1 = bfd_get_32 (abfd, text + i + 4);
1294 tb2 = bfd_get_32 (abfd, text + i + 8);
1295 off = i + 12;
1296 printf (_(" version: %u, lang: %u, global_link: %u, is_eprol: %u, has_tboff: %u, int_proc: %u\n"),
1297 (tb1 >> 24) & 0xff,
1298 (tb1 >> 16) & 0xff,
1299 (tb1 >> 15) & 1,
1300 (tb1 >> 14) & 1,
1301 (tb1 >> 13) & 1,
1302 (tb1 >> 12) & 1);
1303 printf (_(" has_ctl: %u, tocless: %u, fp_pres: %u, log_abort: %u, int_hndl: %u\n"),
1304 (tb1 >> 11) & 1,
1305 (tb1 >> 10) & 1,
1306 (tb1 >> 9) & 1,
1307 (tb1 >> 8) & 1,
1308 (tb1 >> 7) & 1);
1309 printf (_(" name_pres: %u, uses_alloca: %u, cl_dis_inv: %u, saves_cr: %u, saves_lr: %u\n"),
1310 (tb1 >> 6) & 1,
1311 (tb1 >> 5) & 1,
1312 (tb1 >> 2) & 7,
1313 (tb1 >> 1) & 1,
1314 (tb1 >> 0) & 1);
1315 printf (_(" stores_bc: %u, fixup: %u, fpr_saved: %-2u, spare3: %u, gpr_saved: %-2u\n"),
1316 (tb2 >> 31) & 1,
1317 (tb2 >> 30) & 1,
1318 (tb2 >> 24) & 63,
1319 (tb2 >> 22) & 3,
1320 (tb2 >> 16) & 63);
1321 printf (_(" fixparms: %-3u floatparms: %-3u parm_on_stk: %u\n"),
1322 (tb2 >> 8) & 0xff,
1323 (tb2 >> 1) & 0x7f,
1324 (tb2 >> 0) & 1);
1326 if (((tb2 >> 1) & 0x7fff) != 0)
1328 unsigned int parminfo;
1330 if (off >= text_size)
1331 goto truncated;
1332 parminfo = bfd_get_32 (abfd, text + off);
1333 off += 4;
1334 printf (_(" parminfo: 0x%08x\n"), parminfo);
1337 if ((tb1 >> 13) & 1)
1339 unsigned int tboff;
1341 if (off >= text_size)
1342 goto truncated;
1343 tboff = bfd_get_32 (abfd, text + off);
1344 off += 4;
1345 printf (_(" tb_offset: 0x%08x (start=0x%08x)\n"),
1346 tboff, text_start + i - tboff);
1348 if ((tb1 >> 7) & 1)
1350 unsigned int hand_mask;
1352 if (off >= text_size)
1353 goto truncated;
1354 hand_mask = bfd_get_32 (abfd, text + off);
1355 off += 4;
1356 printf (_(" hand_mask_offset: 0x%08x\n"), hand_mask);
1358 if ((tb1 >> 11) & 1)
1360 unsigned int ctl_info;
1361 unsigned int j;
1363 if (off >= text_size)
1364 goto truncated;
1365 ctl_info = bfd_get_32 (abfd, text + off);
1366 off += 4;
1367 printf (_(" number of CTL anchors: %u\n"), ctl_info);
1368 for (j = 0; j < ctl_info; j++)
1370 if (off >= text_size)
1371 goto truncated;
1372 printf (_(" CTL[%u]: %08x\n"),
1373 j, (unsigned)bfd_get_32 (abfd, text + off));
1374 off += 4;
1377 if ((tb1 >> 6) & 1)
1379 unsigned int name_len;
1380 unsigned int j;
1382 if (off >= text_size)
1383 goto truncated;
1384 name_len = bfd_get_16 (abfd, text + off);
1385 off += 2;
1386 printf (_(" Name (len: %u): "), name_len);
1387 if (off + name_len >= text_size)
1389 printf (_("[truncated]\n"));
1390 goto truncated;
1392 for (j = 0; j < name_len; j++)
1393 if (ISPRINT (text[off + j]))
1394 putchar (text[off + j]);
1395 else
1396 printf ("[%02x]", (unsigned char)text[off + j]);
1397 putchar ('\n');
1398 off += name_len;
1400 if ((tb1 >> 5) & 1)
1402 if (off >= text_size)
1403 goto truncated;
1404 printf (_(" alloca reg: %u\n"),
1405 (unsigned) bfd_get_8 (abfd, text + off));
1406 off++;
1408 printf (_(" (end of tags at %08x)\n"), text_start + off);
1409 return;
1411 printf (_(" no tags found\n"));
1412 return;
1414 truncated:
1415 printf (_(" Truncated .text section\n"));
1416 return;
1419 static void
1420 dump_xcoff32_traceback (bfd *abfd, struct xcoff_dump *data)
1422 unsigned int i;
1423 unsigned int scnum_text = -1;
1424 unsigned int text_vma;
1425 asection *text_sec;
1426 bfd_size_type text_size;
1427 char *text;
1429 if (data->syms == NULL || data->sects == NULL)
1430 return;
1432 /* Read text section. */
1433 text_sec = bfd_get_section_by_name (abfd, ".text");
1434 if (text_sec == NULL)
1435 return;
1436 text_vma = bfd_get_section_vma (abfd, text_sec);
1438 text_size = bfd_get_section_size (text_sec);
1439 text = (char *) xmalloc (text_size);
1440 bfd_get_section_contents (abfd, text_sec, text, 0, text_size);
1442 for (i = 0; i < data->nscns; i++)
1443 if (data->sects[i].flags == STYP_TEXT)
1445 scnum_text = i + 1;
1446 break;
1448 if (scnum_text == (unsigned int)-1)
1449 return;
1451 for (i = 0; i < data->nsyms; i++)
1453 union xcoff32_symbol *s = &data->syms[i];
1455 switch (s->sym.sclass)
1457 case C_EXT:
1458 case C_HIDEXT:
1459 case C_WEAKEXT:
1460 if (s->sym.scnum == scnum_text
1461 && s->sym.numaux > 0)
1463 union external_auxent *aux = &s[s->sym.numaux].aux;
1465 unsigned int smtyp;
1466 unsigned int smclas;
1468 smtyp = bfd_h_get_8 (abfd, aux->x_csect.x_smtyp);
1469 smclas = bfd_h_get_8 (abfd, aux->x_csect.x_smclas);
1470 if (SMTYP_SMTYP (smtyp) == XTY_LD
1471 && (smclas == XMC_PR
1472 || smclas == XMC_GL
1473 || smclas == XMC_XO))
1475 printf ("%08x: ", s->sym.val);
1476 xcoff32_print_symbol (data, i);
1477 putchar ('\n');
1478 dump_xcoff32_tbtags (abfd, text, text_size,
1479 text_vma, s->sym.val);
1482 break;
1483 default:
1484 break;
1486 i += s->sym.numaux;
1488 free (text);
1491 /* Dump the TOC symbols. */
1493 static void
1494 dump_xcoff32_toc (bfd *abfd, struct xcoff_dump *data)
1496 unsigned int i;
1497 unsigned int nbr_ent;
1498 unsigned int size;
1500 printf (_("TOC:\n"));
1502 if (data->syms == NULL)
1503 return;
1505 nbr_ent = 0;
1506 size = 0;
1508 for (i = 0; i < data->nsyms; i++)
1510 union xcoff32_symbol *s = &data->syms[i];
1512 switch (s->sym.sclass)
1514 case C_EXT:
1515 case C_HIDEXT:
1516 case C_WEAKEXT:
1517 if (s->sym.numaux > 0)
1519 union external_auxent *aux = &s[s->sym.numaux].aux;
1520 unsigned int smclas;
1521 unsigned int ent_sz;
1523 smclas = bfd_h_get_8 (abfd, aux->x_csect.x_smclas);
1524 if (smclas == XMC_TC
1525 || smclas == XMC_TD
1526 || smclas == XMC_TC0)
1528 ent_sz = bfd_h_get_32 (abfd, aux->x_scn.x_scnlen);
1529 printf ("%08x %08x ",
1530 s->sym.val, ent_sz);
1531 xcoff32_print_symbol (data, i);
1532 putchar ('\n');
1533 nbr_ent++;
1534 size += ent_sz;
1537 break;
1538 default:
1539 break;
1541 i += s->sym.numaux;
1543 printf (_("Nbr entries: %-8u Size: %08x (%u)\n"),
1544 nbr_ent, size, size);
1547 /* Handle an rs6000 xcoff file. */
1549 static void
1550 dump_xcoff32 (bfd *abfd, struct external_filehdr *fhdr)
1552 struct xcoff_dump data;
1554 data.nscns = bfd_h_get_16 (abfd, fhdr->f_nscns);
1555 data.symptr = bfd_h_get_32 (abfd, fhdr->f_symptr);
1556 data.nsyms = bfd_h_get_32 (abfd, fhdr->f_nsyms);
1557 data.opthdr = bfd_h_get_16 (abfd, fhdr->f_opthdr);
1558 data.sects = NULL;
1559 data.syms = NULL;
1560 data.strings = NULL;
1561 data.strings_size = 0;
1563 if (options[OPT_FILE_HEADER].selected)
1564 dump_xcoff32_file_header (abfd, fhdr, &data);
1566 if (options[OPT_AOUT].selected)
1567 dump_xcoff32_aout_header (abfd, &data);
1569 if (options[OPT_SYMS].selected
1570 || options[OPT_RELOCS].selected
1571 || options[OPT_LINENO].selected
1572 || options[OPT_TRACEBACK].selected)
1573 xcoff32_read_sections (abfd, &data);
1575 if (options[OPT_SECTIONS].selected)
1576 dump_xcoff32_sections_header (abfd, &data);
1578 if (options[OPT_SYMS].selected
1579 || options[OPT_RELOCS].selected
1580 || options[OPT_LINENO].selected
1581 || options[OPT_EXCEPT].selected
1582 || options[OPT_TRACEBACK].selected
1583 || options[OPT_TOC].selected)
1584 xcoff32_read_symbols (abfd, &data);
1586 if (options[OPT_SYMS].selected)
1587 dump_xcoff32_symbols (abfd, &data);
1589 if (options[OPT_RELOCS].selected)
1590 dump_xcoff32_relocs (abfd, &data);
1592 if (options[OPT_LINENO].selected)
1593 dump_xcoff32_lineno (abfd, &data);
1595 if (options[OPT_LOADER].selected)
1596 dump_xcoff32_loader (abfd);
1598 if (options[OPT_EXCEPT].selected)
1599 dump_xcoff32_except (abfd, &data);
1601 if (options[OPT_TYPCHK].selected)
1602 dump_xcoff32_typchk (abfd);
1604 if (options[OPT_TRACEBACK].selected)
1605 dump_xcoff32_traceback (abfd, &data);
1607 if (options[OPT_TOC].selected)
1608 dump_xcoff32_toc (abfd, &data);
1610 free (data.sects);
1611 free (data.strings);
1612 free (data.syms);
1615 /* Dump ABFD (according to the options[] array). */
1617 static void
1618 xcoff_dump (bfd *abfd)
1620 struct external_filehdr fhdr;
1621 unsigned short magic;
1623 /* Read file header. */
1624 if (bfd_seek (abfd, 0, SEEK_SET) != 0
1625 || bfd_bread (&fhdr, sizeof (fhdr), abfd) != sizeof (fhdr))
1627 non_fatal (_("cannot read header"));
1628 return;
1631 /* Decoding. We don't use the bfd/coff function to get all the fields. */
1632 magic = bfd_h_get_16 (abfd, fhdr.f_magic);
1633 if (options[OPT_FILE_HEADER].selected)
1635 printf (_("File header:\n"));
1636 printf (_(" magic: 0x%04x (0%04o) "), magic, magic);
1637 switch (magic)
1639 case U802WRMAGIC:
1640 printf (_("(WRMAGIC: writable text segments)"));
1641 break;
1642 case U802ROMAGIC:
1643 printf (_("(ROMAGIC: readonly sharablee text segments)"));
1644 break;
1645 case U802TOCMAGIC:
1646 printf (_("(TOCMAGIC: readonly text segments and TOC)"));
1647 break;
1648 default:
1649 printf (_("unknown magic"));
1651 putchar ('\n');
1653 if (magic == U802ROMAGIC || magic == U802WRMAGIC || magic == U802TOCMAGIC)
1654 dump_xcoff32 (abfd, &fhdr);
1655 else
1656 printf (_(" Unhandled magic\n"));
1659 /* Vector for xcoff. */
1661 const struct objdump_private_desc objdump_private_desc_xcoff =
1663 xcoff_help,
1664 xcoff_filter,
1665 xcoff_dump,
1666 options