2011-05-16 Tristan Gingold <gingold@adacore.com>
[deliverable/binutils-gdb.git] / binutils / od-xcoff.c
CommitLineData
6abcee90
TG
1/* od-xcoff.c -- dump information about an xcoff object file.
2 Copyright 2011 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 <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"
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
53/* List of actions. */
54static struct objdump_private_option options[] =
55 {
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 }
68 };
69
70/* Display help. */
71
72static void
73xcoff_help (FILE *stream)
74{
75 fprintf (stream, _("\
76For 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"));
89}
90
91/* Return TRUE if ABFD is handled. */
92
93static int
94xcoff_filter (bfd *abfd)
95{
96 return bfd_get_flavour (abfd) == bfd_target_xcoff_flavour;
97}
98
99/* Translation entry type. The last entry must be {0, NULL}. */
100
101struct xlat_table {
102 unsigned int val;
103 const char *name;
104};
105
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. */
108
109static void
110dump_flags (const struct xlat_table *table, unsigned int flags)
111{
112 unsigned int r = flags;
113 int first = 1;
114 const struct xlat_table *t;
115
116 for (t = table; t->name; t++)
117 if ((flags & t->val) != 0)
118 {
119 r &= ~t->val;
120
121 if (first)
122 first = 0;
123 else
124 putchar (',');
125 fputs (t->name, stdout);
126 }
127
128 /* Not decoded flags. */
129 if (r != 0)
130 {
131 if (!first)
132 putchar (',');
133 printf ("0x%x", r);
134 }
135}
136
137/* Display the name corresponding to VAL from TABLE, using at most
138 MAXLEN char (possibly passed with spaces). */
139
140static void
141dump_value (const struct xlat_table *table, unsigned int val, int maxlen)
142{
143 const struct xlat_table *t;
144
145 for (t = table; t->name; t++)
146 if (t->val == val)
147 {
148 printf ("%-*s", maxlen, t->name);
149 return;
150 }
151 printf ("(%*x)", maxlen - 2, val);
152}
153
154/* Names of f_flags. */
155static const struct xlat_table f_flag_xlat[] =
156 {
157 { F_RELFLG, "no-rel" },
158 { F_EXEC, "exec" },
159 { F_LNNO, "lineno" },
160 { F_LSYMS, "lsyms" },
161
162 { F_FDPR_PROF, "fdpr-prof" },
163 { F_FDPR_OPTI, "fdpr-opti" },
164 { F_DSA, "dsa" },
165
166 { F_VARPG, "varprg" },
167
168 { F_DYNLOAD, "dynload" },
169 { F_SHROBJ, "shrobj" },
170 { F_NONEXEC, "nonexec" },
171
172 { 0, NULL }
173 };
174
175/* Names of s_flags. */
176static const struct xlat_table s_flag_xlat[] =
177 {
178 { STYP_PAD, "pad" },
179 { STYP_DWARF, "dwarf" },
180 { STYP_TEXT, "text" },
181 { STYP_DATA, "data" },
182 { STYP_BSS, "bss" },
183
184 { STYP_EXCEPT, "except" },
185 { STYP_INFO, "info" },
186 { STYP_TDATA, "tdata" },
187 { STYP_TBSS, "tbss" },
188
189 { STYP_LOADER, "loader" },
190 { STYP_DEBUG, "debug" },
191 { STYP_TYPCHK, "typchk" },
192 { STYP_OVRFLO, "ovrflo" },
193 { 0, NULL }
194 };
195
196/* Names of storage class. */
197static const struct xlat_table sc_xlat[] =
198 {
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),
232
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),
249
250 { 0, NULL }
251#undef SC_ENTRY
252 };
253
254/* Names for symbol type. */
255static const struct xlat_table smtyp_xlat[] =
256 {
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 }
264 };
265
266/* Names for storage-mapping class. */
267static const struct xlat_table smclas_xlat[] =
268 {
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
290 };
291
292/* Names for relocation type. */
293static const struct xlat_table rtype_xlat[] =
294 {
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 }
327 };
328
329/* Simplified section header. */
330struct xcoff32_section
331{
332 /* NUL terminated name. */
333 char name[9];
334
335 /* Section flags. */
336 unsigned int flags;
337
338 /* Offsets in file. */
339 ufile_ptr scnptr;
340 ufile_ptr relptr;
341 ufile_ptr lnnoptr;
342
343 /* Number of relocs and line numbers. */
344 unsigned int nreloc;
345 unsigned int nlnno;
346};
347
348/* Simplified symbol. */
349
350union xcoff32_symbol
351{
352 union external_auxent aux;
353
354 struct sym
355 {
356 /* Pointer the the NUL-terminated name. */
357 char *name;
358
359 /* XCOFF symbol fields. */
360 unsigned int val;
361 unsigned short scnum;
362 unsigned short ntype;
363 unsigned char sclass;
364 unsigned char numaux;
365
366 /* Buffer in case the name is local. */
367 union
368 {
369 char name[9];
370 unsigned int off;
371 } raw;
372 } sym;
373};
374
375/* Important fields to dump the file. */
376
377struct xcoff_dump
378{
379 /* From file header. */
380 unsigned short nscns;
381 unsigned int symptr;
382 unsigned int nsyms;
383 unsigned short opthdr;
384
385 /* Sections. */
386 struct xcoff32_section *sects;
387
388 /* Symbols. */
389 union xcoff32_symbol *syms;
390 char *strings;
391 unsigned int strings_size;
392};
393
394/* Print a symbol (if possible). */
395
396static void
397xcoff32_print_symbol (struct xcoff_dump *data, unsigned int symndx)
398{
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);
405}
406
407/* Dump the file header. */
408
409static void
410dump_xcoff32_file_header (bfd *abfd, struct external_filehdr *fhdr,
411 struct xcoff_dump *data)
412{
413 unsigned int timdat = bfd_h_get_32 (abfd, fhdr->f_timdat);
414 unsigned short flags = bfd_h_get_16 (abfd, fhdr->f_flags);
415
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
421 {
422 /* Not correct on all platforms, but works on unix. */
423 time_t t = timdat;
424 fputs (ctime (&t), stdout);
425 }
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');
432}
433
434/* Dump the a.out header. */
435
436static void
437dump_xcoff32_aout_header (bfd *abfd, struct xcoff_dump *data)
438{
439 AOUTHDR auxhdr;
440 unsigned short magic;
441 unsigned int sz = data->opthdr;
442
443 printf (_("Auxiliary header:\n"));
444 if (data->opthdr == 0)
445 {
446 printf (_(" No aux header\n"));
447 return;
448 }
449 if (data->opthdr > sizeof (auxhdr))
450 {
451 printf (_("warning: optionnal header size too large (> %d)\n"),
452 (int)sizeof (auxhdr));
453 sz = sizeof (auxhdr);
454 }
455 if (bfd_bread (&auxhdr, sz, abfd) != sz)
456 {
457 non_fatal (_("cannot read auxhdr"));
458 return;
459 }
460
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
510}
511
512/* Dump the sections header. */
513
514static void
515dump_xcoff32_sections_header (bfd *abfd, struct xcoff_dump *data)
516{
517 unsigned int i;
518 unsigned int off;
519
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)
525 {
526 printf (_(" No section header\n"));
527 return;
528 }
529 if (bfd_seek (abfd, off, SEEK_SET) != 0)
530 {
531 non_fatal (_("cannot read section header"));
532 return;
533 }
534 printf (_(" # Name paddr vaddr size scnptr relptr lnnoptr nrel nlnno\n"));
535 for (i = 0; i < data->nscns; i++)
536 {
537 struct external_scnhdr scn;
538 unsigned int flags;
539
540 if (bfd_bread (&scn, sizeof (scn), abfd) != sizeof (scn))
541 {
542 non_fatal (_("cannot read section header"));
543 return;
544 }
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);
558
559 if (~flags == 0)
560 {
561 /* Stripped executable ? */
562 putchar ('\n');
563 }
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
569 {
570 dump_flags (s_flag_xlat, flags);
571 putchar ('\n');
572 }
573 }
574}
575
576/* Read section table. */
577
578static void
579xcoff32_read_sections (bfd *abfd, struct xcoff_dump *data)
580{
581 int i;
582
583 if (bfd_seek (abfd, sizeof (struct external_filehdr) + data->opthdr,
584 SEEK_SET) != 0)
585 {
586 non_fatal (_("cannot read section headers"));
587 return;
588 }
589
590 data->sects = xmalloc (data->nscns * sizeof (struct xcoff32_section));
591 for (i = 0; i < data->nscns; i++)
592 {
593 struct external_scnhdr scn;
594 struct xcoff32_section *s = &data->sects[i];
595
596 if (bfd_bread (&scn, sizeof (scn), abfd) != sizeof (scn))
597 {
598 non_fatal (_("cannot read section header"));
599 free (data->sects);
600 data->sects = NULL;
601 return;
602 }
603 memcpy (s->name, scn.s_name, 8);
604 s->name[8] = 0;
605 s->flags = bfd_h_get_32 (abfd, scn.s_flags);
606
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);
610
611 s->nreloc = bfd_h_get_16 (abfd, scn.s_nreloc);
612 s->nlnno = bfd_h_get_16 (abfd, scn.s_nlnno);
613
614 if (s->flags == STYP_OVRFLO)
615 {
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);
622 }
623 }
624}
625
626/* Read symbols. */
627
628static void
629xcoff32_read_symbols (bfd *abfd, struct xcoff_dump *data)
630{
631 unsigned int i;
632 char stsz_arr[4];
633 unsigned int stptr;
634
635 if (data->nsyms == 0)
636 return;
637
638 stptr = data->symptr
639 + data->nsyms * (unsigned)sizeof (struct external_syment);
640
641 /* Read string table. */
642 if (bfd_seek (abfd, stptr, SEEK_SET) != 0)
643 {
644 data->strings_size = 0;
645 }
646 else
647 {
648 if (bfd_bread (&stsz_arr, sizeof (stsz_arr), abfd) != sizeof (stsz_arr))
649 {
650 non_fatal (_("cannot read strings table len"));
651 return;
652 }
653 data->strings_size = bfd_h_get_32 (abfd, stsz_arr);
654 if (data->strings_size > sizeof (stsz_arr))
655 {
656 unsigned int remsz = data->strings_size - sizeof (stsz_arr);
657
658 data->strings = xmalloc (data->strings_size);
659
660 memcpy (data->strings, stsz_arr, sizeof (stsz_arr));
661 if (bfd_bread (data->strings + sizeof (stsz_arr), remsz, abfd)
662 != remsz)
663 {
664 non_fatal (_("cannot read strings table"));
665 goto clean;
666 }
667 }
668 }
669
670 if (bfd_seek (abfd, data->symptr, SEEK_SET) != 0)
671 {
672 non_fatal (_("cannot read symbol table"));
673 goto clean;
674 }
675
676 data->syms = (union xcoff32_symbol *)
677 xmalloc (data->nsyms * sizeof (union xcoff32_symbol));
678
679 for (i = 0; i < data->nsyms; i++)
680 {
681 struct external_syment sym;
682 int j;
683 union xcoff32_symbol *s = &data->syms[i];
684
685 if (bfd_bread (&sym, sizeof (sym), abfd) != sizeof (sym))
686 {
687 non_fatal (_("cannot read symbol entry"));
688 goto clean;
689 }
690
691 s->sym.val = bfd_h_get_32 (abfd, sym.e_value);
692 s->sym.scnum = bfd_h_get_16 (abfd, sym.e_scnum);
693 s->sym.ntype = bfd_h_get_16 (abfd, sym.e_type);
694 s->sym.sclass = bfd_h_get_8 (abfd, sym.e_sclass);
695 s->sym.numaux = bfd_h_get_8 (abfd, sym.e_numaux);
696
697 if (sym.e.e_name[0])
698 {
699 memcpy (s->sym.raw.name, sym.e.e_name, sizeof (sym.e.e_name));
700 s->sym.raw.name[8] = 0;
701 s->sym.name = s->sym.raw.name;
702 }
703 else
704 {
705 unsigned int soff = bfd_h_get_32 (abfd, sym.e.e.e_offset);
706
707 if ((s->sym.sclass & DBXMASK) == 0 && soff < data->strings_size)
708 s->sym.name = data->strings + soff;
709 else
710 {
711 s->sym.name = NULL;
712 s->sym.raw.off = soff;
713 }
714 }
715
716 for (j = 0; j < s->sym.numaux; j++, i++)
717 {
718 if (bfd_bread (&s[j + 1].aux,
719 sizeof (union external_auxent), abfd)
720 != sizeof (union external_auxent))
721 {
722 non_fatal (_("cannot read symbol aux entry"));
723 goto clean;
724 }
725 }
726 }
727 return;
728 clean:
729 free (data->syms);
730 data->syms = NULL;
731 free (data->strings);
732 data->strings = NULL;
733}
734
735/* Dump xcoff symbols. */
736
737static void
738dump_xcoff32_symbols (bfd *abfd, struct xcoff_dump *data)
739{
740 unsigned int i;
741 asection *debugsec;
742 char *debug = NULL;
743
744 printf (_("Symbols table (strtable at 0x%08x)"),
745 data->symptr
746 + data->nsyms * (unsigned)sizeof (struct external_syment));
747 if (data->nsyms == 0 || data->syms == NULL)
748 {
749 printf (_(":\n No symbols\n"));
750 return;
751 }
752
753 /* Read string 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_get_section_size (debugsec);
766 debug = (char *) xmalloc (size);
767 bfd_get_section_contents (abfd, debugsec, debug, 0, size);
768 }
769
770 printf (_(" # sc value section type aux name/off\n"));
771 for (i = 0; i < data->nsyms; i++)
772 {
773 union xcoff32_symbol *s = &data->syms[i];
774 int j;
775
776 printf ("%3u ", i);
777 dump_value (sc_xlat, s->sym.sclass, 10);
778 printf (" %08x ", s->sym.val);
779 if (s->sym.scnum > 0 && s->sym.scnum <= data->nscns)
780 {
781 if (data->sects != NULL)
782 printf ("%-8s", data->sects[s->sym.scnum - 1].name);
783 else
784 printf ("%-8u", s->sym.scnum);
785 }
786 else
787 switch ((signed short)s->sym.scnum)
788 {
789 case N_DEBUG:
790 printf ("N_DEBUG ");
791 break;
792 case N_ABS:
793 printf ("N_ABS ");
794 break;
795 case N_UNDEF:
796 printf ("N_UNDEF ");
797 break;
798 default:
799 printf ("(%04x) ", s->sym.scnum);
800 }
801 printf (" %04x %3u ", s->sym.ntype, s->sym.numaux);
802 if (s->sym.name != NULL)
803 printf ("%s", s->sym.name);
804 else
805 {
806 if ((s->sym.sclass & DBXMASK) != 0 && debug != NULL)
807 printf ("%s", debug + s->sym.raw.off);
808 else
809 printf ("%08x", s->sym.raw.off);
810 }
811 putchar ('\n');
812
813 for (j = 0; j < s->sym.numaux; j++, i++)
814 {
815 union external_auxent *aux = &s[j + 1].aux;
816
817 printf (" %3u ", i + 1);
818 switch (s->sym.sclass)
819 {
820 case C_STAT:
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 printf (_(" scnlen: %08x nreloc: %-6u\n"),
828 (unsigned)bfd_h_get_32 (abfd, aux->x_scn.x_scnlen),
829 (unsigned)bfd_h_get_16 (abfd, aux->x_scn.x_nreloc));
830 break;
831 case C_EXT:
832 case C_WEAKEXT:
833 case C_HIDEXT:
834 if (j == 0 && s->sym.numaux > 1)
835 {
836 /* Function aux entry. */
837 printf (_(" exptr: %08x fsize: %08x lnnoptr: %08x endndx: %u\n"),
838 (unsigned)bfd_h_get_32 (abfd, aux->x_sym.x_tagndx),
839 (unsigned)bfd_h_get_32
840 (abfd, aux->x_sym.x_misc.x_fsize),
841 (unsigned)bfd_h_get_32
842 (abfd, aux->x_sym.x_fcnary.x_fcn.x_lnnoptr),
843 (unsigned)bfd_h_get_32
844 (abfd, aux->x_sym.x_fcnary.x_fcn.x_endndx));
845 }
846 else if (j == 1 || (j == 0 && s->sym.numaux == 1))
847 {
848 /* csect aux entry. */
849 unsigned char smtyp;
850 unsigned int scnlen;
851
852 smtyp = bfd_h_get_8 (abfd, aux->x_csect.x_smtyp);
853 scnlen = bfd_h_get_32 (abfd, aux->x_csect.x_scnlen);
854
855 if (smtyp == XTY_LD)
856 printf (_(" scnsym: %-8u"), scnlen);
857 else
858 printf (_(" scnlen: %08x"), scnlen);
859 printf (_(" h: parm=%08x sn=%04x al: 2**%u"),
860 (unsigned)bfd_h_get_32 (abfd, aux->x_csect.x_parmhash),
861 (unsigned)bfd_h_get_16 (abfd, aux->x_csect.x_snhash),
862 SMTYP_ALIGN (smtyp));
863 printf (_(" typ: "));
864 dump_value (smtyp_xlat, SMTYP_SMTYP (smtyp), 2);
865 printf (_(" cl: "));
866 dump_value
867 (smclas_xlat,
868 (unsigned)bfd_h_get_8 (abfd, aux->x_csect.x_smclas), 6);
869 putchar ('\n');
870 }
871 else
872 printf ("aux\n");
873 break;
874 case C_FILE:
875 {
876 unsigned int off;
877
878 printf (_(" ftype: %02x "),
879 (unsigned)bfd_h_get_8 (abfd, aux->x_file.x_ftype));
880 if (aux->x_file.x_n.x_fname[0] != 0)
881 printf (_("fname: %.14s"), aux->x_file.x_n.x_fname);
882 else
883 {
884 off = (unsigned)bfd_h_get_32
885 (abfd, aux->x_file.x_n.x_n.x_offset);
886 if (data->strings != NULL && off < data->strings_size)
887 printf (_(" %s"), data->strings + off);
888 else
889 printf (_("offset: %08x"), off);
890 }
891 putchar ('\n');
892 }
893 break;
894 case C_BLOCK:
895 case C_FCN:
896 printf (_(" lnno: %u\n"),
897 (unsigned)bfd_h_get_16
898 (abfd, aux->x_sym.x_misc.x_lnsz.x_lnno));
899 break;
900 default:
901 printf ("aux\n");
902 break;
903 }
904 }
905
906 }
907 free (debug);
908}
909
910/* Dump xcoff relocation entries. */
911
912static void
913dump_xcoff32_relocs (bfd *abfd, struct xcoff_dump *data)
914{
915 unsigned int i;
916
917 if (data->sects == NULL)
918 {
919 non_fatal (_("cannot read section headers"));
920 return;
921 }
922
923 for (i = 0; i < data->nscns; i++)
924 {
925 struct xcoff32_section *sect = &data->sects[i];
926 unsigned int nrel = sect->nreloc;
927 unsigned int j;
928
929 if (nrel == 0)
930 continue;
931 printf (_("Relocations for %s (%u)\n"), sect->name, nrel);
932 if (bfd_seek (abfd, sect->relptr, SEEK_SET) != 0)
933 {
934 non_fatal (_("cannot read relocations"));
935 continue;
936 }
937 printf (_("vaddr sgn mod sz type symndx symbol\n"));
938 for (j = 0; j < nrel; j++)
939 {
940 struct external_reloc rel;
941 unsigned char rsize;
942 unsigned int symndx;
943
944 if (bfd_bread (&rel, sizeof (rel), abfd) != sizeof (rel))
945 {
946 non_fatal (_("cannot read relocation entry"));
947 return;
948 }
949 rsize = bfd_h_get_8 (abfd, rel.r_size);
950 printf (_("%08x %c %c %-2u "),
951 (unsigned int)bfd_h_get_32 (abfd, rel.r_vaddr),
952 rsize & 0x80 ? 'S' : 'U',
953 rsize & 0x40 ? 'm' : ' ',
954 (rsize & 0x3f) + 1);
955 dump_value (rtype_xlat, bfd_h_get_8 (abfd, rel.r_type), 6);
956 symndx = bfd_h_get_32 (abfd, rel.r_symndx);
957 printf ("%-6u ", symndx);
958 xcoff32_print_symbol (data, symndx);
959 putchar ('\n');
960 }
961 putchar ('\n');
962 }
963}
964
965/* Dump xcoff line number entries. */
966
967static void
968dump_xcoff32_lineno (bfd *abfd, struct xcoff_dump *data)
969{
970 unsigned int i;
971
972 if (data->sects == NULL)
973 {
974 non_fatal (_("cannot read section headers"));
975 return;
976 }
977
978 for (i = 0; i < data->nscns; i++)
979 {
980 struct xcoff32_section *sect = &data->sects[i];
981 unsigned int nlnno = sect->nlnno;
982 unsigned int j;
983
984 if (nlnno == 0)
985 continue;
986 printf (_("Line numbers for %s (%u)\n"), sect->name, nlnno);
987 if (bfd_seek (abfd, sect->lnnoptr, SEEK_SET) != 0)
988 {
989 non_fatal (_("cannot read line numbers"));
990 continue;
991 }
992 printf (_("lineno symndx/paddr\n"));
993 for (j = 0; j < nlnno; j++)
994 {
995 struct external_lineno ln;
996 unsigned int no;
997
998 if (bfd_bread (&ln, sizeof (ln), abfd) != sizeof (ln))
999 {
1000 non_fatal (_("cannot read line number entry"));
1001 return;
1002 }
1003 no = bfd_h_get_16 (abfd, ln.l_lnno);
1004 printf (_(" %-6u "), no);
1005 if (no == 0)
1006 {
1007 unsigned int symndx = bfd_h_get_32 (abfd, ln.l_addr.l_symndx);
1008 xcoff32_print_symbol (data, symndx);
1009 }
1010 else
1011 printf ("0x%08x",
1012 (unsigned int)bfd_h_get_32 (abfd, ln.l_addr.l_paddr));
1013 putchar ('\n');
1014 }
1015 }
1016}
1017
1018/* Dump xcoff loader section. */
1019
1020static void
1021dump_xcoff32_loader (bfd *abfd)
1022{
1023 asection *loader;
1024 bfd_size_type size = 0;
1025 struct external_ldhdr *lhdr;
1026 struct external_ldsym *ldsym;
1027 struct external_ldrel *ldrel;
1028 bfd_byte *ldr_data;
1029 unsigned int version;
1030 unsigned int ndsyms;
1031 unsigned int ndrel;
1032 unsigned int stlen;
1033 unsigned int stoff;
1034 unsigned int impoff;
1035 unsigned int nimpid;
1036 unsigned int i;
1037 const char *p;
1038
1039 loader = bfd_get_section_by_name (abfd, ".loader");
1040
1041 if (loader == NULL)
1042 {
1043 printf (_("no .loader section in file\n"));
1044 return;
1045 }
1046 size = bfd_get_section_size (loader);
1047 if (size < sizeof (*lhdr))
1048 {
1049 printf (_("section .loader is too short\n"));
1050 return;
1051 }
1052
1053 ldr_data = (bfd_byte *) xmalloc (size);
1054 bfd_get_section_contents (abfd, loader, ldr_data, 0, size);
1055 lhdr = (struct external_ldhdr *)ldr_data;
1056 printf (_("Loader header:\n"));
1057 version = bfd_h_get_32 (abfd, lhdr->l_version);
1058 printf (_(" version: %u\n"), version);
1059 if (version != 1)
1060 {
1061 printf (_(" Unhandled version\n"));
1062 free (ldr_data);
1063 return;
1064 }
1065 ndsyms = bfd_h_get_32 (abfd, lhdr->l_nsyms);
1066 printf (_(" nbr symbols: %u\n"), ndsyms);
1067 ndrel = bfd_h_get_32 (abfd, lhdr->l_nreloc);
1068 printf (_(" nbr relocs: %u\n"), ndrel);
1069 printf (_(" import strtab len: %u\n"),
1070 (unsigned) bfd_h_get_32 (abfd, lhdr->l_istlen));
1071 nimpid = bfd_h_get_32 (abfd, lhdr->l_nimpid);
1072 printf (_(" nbr import files: %u\n"), nimpid);
1073 impoff = bfd_h_get_32 (abfd, lhdr->l_impoff);
1074 printf (_(" import file off: %u\n"), impoff);
1075 stlen = bfd_h_get_32 (abfd, lhdr->l_stlen);
1076 printf (_(" string table len: %u\n"), stlen);
1077 stoff = bfd_h_get_32 (abfd, lhdr->l_stoff);
1078 printf (_(" string table off: %u\n"), stoff);
1079
1080 ldsym = (struct external_ldsym *)(ldr_data + sizeof (*lhdr));
1081 printf (_("Dynamic symbols:\n"));
1082 printf (_(" # value sc IFEW ty class file pa name\n"));
1083 for (i = 0; i < ndsyms; i++, ldsym++)
1084 {
1085 unsigned char smtype;
1086
1087 printf (_(" %4u %08x %3u "), i,
1088 (unsigned)bfd_h_get_32 (abfd, ldsym->l_value),
1089 (unsigned)bfd_h_get_16 (abfd, ldsym->l_scnum));
1090 smtype = bfd_h_get_8 (abfd, ldsym->l_smtype);
1091 putchar (smtype & 0x40 ? 'I' : ' ');
1092 putchar (smtype & 0x20 ? 'F' : ' ');
1093 putchar (smtype & 0x10 ? 'E' : ' ');
1094 putchar (smtype & 0x08 ? 'W' : ' ');
1095 putchar (' ');
1096 dump_value (smtyp_xlat, SMTYP_SMTYP (smtype), 2);
1097 putchar (' ');
1098 dump_value
1099 (smclas_xlat, (unsigned)bfd_h_get_8 (abfd, ldsym->l_smclas), 6);
1100 printf (_(" %3u %3u "),
1101 (unsigned)bfd_h_get_32 (abfd, ldsym->l_ifile),
1102 (unsigned)bfd_h_get_32 (abfd, ldsym->l_parm));
1103 if (ldsym->_l._l_name[0] != 0)
1104 printf ("%-.8s", ldsym->_l._l_name);
1105 else
1106 {
1107 unsigned int off = bfd_h_get_32 (abfd, ldsym->_l._l_l._l_offset);
1108 if (off > stlen)
1109 printf (_("(bad offset: %u)"), off);
1110 else
1111 printf ("%s", ldr_data + stoff + off);
1112 }
1113 putchar ('\n');
1114 }
1115
1116 printf (_("Dynamic relocs:\n"));
1117 printf (_(" vaddr sec sz typ sym\n"));
1118 ldrel = (struct external_ldrel *)(ldr_data + sizeof (*lhdr)
1119 + ndsyms * sizeof (*ldsym));
1120 for (i = 0; i < ndrel; i++, ldrel++)
1121 {
1122 unsigned int rsize;
1123 unsigned int rtype;
1124 unsigned int symndx;
1125
1126 rsize = bfd_h_get_8 (abfd, ldrel->l_rtype + 0);
1127 rtype = bfd_h_get_8 (abfd, ldrel->l_rtype + 1);
1128
1129 printf (_(" %08x %3u %c%c %2u "),
1130 (unsigned)bfd_h_get_32 (abfd, ldrel->l_vaddr),
1131 (unsigned)bfd_h_get_16 (abfd, ldrel->l_rsecnm),
1132 rsize & 0x80 ? 'S' : 'U',
1133 rsize & 0x40 ? 'm' : ' ',
1134 (rsize & 0x3f) + 1);
1135 dump_value (rtype_xlat, rtype, 6);
1136 symndx = bfd_h_get_32 (abfd, ldrel->l_symndx);
1137 switch (symndx)
1138 {
1139 case 0:
1140 printf (_(".text"));
1141 break;
1142 case 1:
1143 printf (_(".data"));
1144 break;
1145 case 2:
1146 printf (_(".bss"));
1147 break;
1148 default:
1149 printf (_("%u"), symndx - 3);
1150 break;
1151 }
1152 putchar ('\n');
1153 }
1154
1155 printf (_("Import files:\n"));
1156 p = (char *)ldr_data + impoff;
1157 for (i = 0; i < nimpid; i++)
1158 {
1159 int n1, n2, n3;
1160
1161 n1 = strlen (p);
1162 n2 = strlen (p + n1 + 1);
1163 n3 = strlen (p + n1 + 1 + n2+ 1);
1164 printf (" %2u: %s,%s,%s\n", i,
1165 p, p + n1 + 1, p + n1 + n2 + 2);
1166 p += n1 + n2 + n3 + 3;
1167 }
1168
1169 free (ldr_data);
1170}
1171
1172/* Dump xcoff exception section. */
1173
1174static void
1175dump_xcoff32_except (bfd *abfd, struct xcoff_dump *data)
1176{
1177 asection *sec;
1178 bfd_size_type size = 0;
1179 bfd_byte *excp_data;
1180 struct external_exceptab *exceptab;
1181 unsigned int i;
1182
1183 sec = bfd_get_section_by_name (abfd, ".except");
1184
1185 if (sec == NULL)
1186 {
1187 printf (_("no .except section in file\n"));
1188 return;
1189 }
1190 size = bfd_get_section_size (sec);
1191 excp_data = (bfd_byte *) xmalloc (size);
1192 bfd_get_section_contents (abfd, sec, excp_data, 0, size);
1193 exceptab = (struct external_exceptab *)excp_data;
1194
1195 printf (_("Exception table:\n"));
1196 printf (_("lang reason sym/addr\n"));
1197 for (i = 0; i * sizeof (*exceptab) < size; i++, exceptab++)
1198 {
1199 unsigned int reason;
1200 unsigned int addr;
1201
1202 addr = bfd_get_32 (abfd, exceptab->e_addr.e_paddr);
1203 reason = bfd_get_8 (abfd, exceptab->e_reason);
1204 printf (_(" %02x %02x "),
1205 (unsigned) bfd_get_8 (abfd, exceptab->e_lang), reason);
1206 if (reason == 0)
1207 xcoff32_print_symbol (data, addr);
1208 else
1209 printf (_("@%08x"), addr);
1210 putchar ('\n');
1211 }
1212 free (excp_data);
1213}
1214
1215/* Dump xcoff type-check section. */
1216
1217static void
1218dump_xcoff32_typchk (bfd *abfd)
1219{
1220 asection *sec;
1221 bfd_size_type size = 0;
1222 bfd_byte *data;
1223 unsigned int i;
1224
1225 sec = bfd_get_section_by_name (abfd, ".typchk");
1226
1227 if (sec == NULL)
1228 {
1229 printf (_("no .typchk section in file\n"));
1230 return;
1231 }
1232 size = bfd_get_section_size (sec);
1233 data = (bfd_byte *) xmalloc (size);
1234 bfd_get_section_contents (abfd, sec, data, 0, size);
1235
1236 printf (_("Type-check section:\n"));
1237 printf (_("offset len lang-id general-hash language-hash\n"));
1238 for (i = 0; i < size;)
1239 {
1240 unsigned int len;
1241
1242 len = bfd_get_16 (abfd, data + i);
1243 printf ("%08x: %-4u ", i, len);
1244 i += 2;
1245
1246 if (len == 10)
1247 {
1248 /* Expected format. */
1249 printf ("%04x %08x %08x\n",
1250 (unsigned) bfd_get_16 (abfd, data + i),
1251 (unsigned) bfd_get_32 (abfd, data + i + 2),
1252 (unsigned) bfd_get_32 (abfd, data + i + 2 + 4));
1253 }
1254 else
1255 {
1256 unsigned int j;
1257
1258 for (j = 0; j < len; j++)
1259 {
1260 if (j % 16 == 0)
1261 printf ("\n ");
1262 printf (" %02x", (unsigned char)data[i + j]);
1263 }
1264 putchar ('\n');
1265 }
1266 i += len;
1267 }
1268 free (data);
1269}
1270
1271/* Dump xcoff traceback tags section. */
1272
1273static void
1274dump_xcoff32_tbtags (bfd *abfd,
1275 const char *text, bfd_size_type text_size,
1276 unsigned int text_start, unsigned int func_start)
1277{
1278 unsigned int i;
1279
1280 if (func_start - text_start > text_size)
1281 {
1282 printf (_(" address beyond section size\n"));
1283 return;
1284 }
1285 for (i = func_start - text_start; i < text_size; i+= 4)
1286 if (bfd_get_32 (abfd, text + i) == 0)
1287 {
1288 unsigned int tb1;
1289 unsigned int tb2;
1290 unsigned int off;
1291
1292 printf (_(" tags at %08x\n"), i + 4);
1293 if (i + 8 >= text_size)
1294 goto truncated;
1295
1296 tb1 = bfd_get_32 (abfd, text + i + 4);
1297 tb2 = bfd_get_32 (abfd, text + i + 8);
1298 off = i + 12;
1299 printf (_(" version: %u, lang: %u, global_link: %u, is_eprol: %u, has_tboff: %u, int_proc: %u\n"),
1300 (tb1 >> 24) & 0xff,
1301 (tb1 >> 16) & 0xff,
1302 (tb1 >> 15) & 1,
1303 (tb1 >> 14) & 1,
1304 (tb1 >> 13) & 1,
1305 (tb1 >> 12) & 1);
1306 printf (_(" has_ctl: %u, tocless: %u, fp_pres: %u, log_abort: %u, int_hndl: %u\n"),
1307 (tb1 >> 11) & 1,
1308 (tb1 >> 10) & 1,
1309 (tb1 >> 9) & 1,
1310 (tb1 >> 8) & 1,
1311 (tb1 >> 7) & 1);
1312 printf (_(" name_pres: %u, uses_alloca: %u, cl_dis_inv: %u, saves_cr: %u, saves_lr: %u\n"),
1313 (tb1 >> 6) & 1,
1314 (tb1 >> 5) & 1,
1315 (tb1 >> 2) & 7,
1316 (tb1 >> 1) & 1,
1317 (tb1 >> 0) & 1);
1318 printf (_(" stores_bc: %u, fixup: %u, fpr_saved: %-2u, spare3: %u, gpr_saved: %-2u\n"),
1319 (tb2 >> 31) & 1,
1320 (tb2 >> 30) & 1,
1321 (tb2 >> 24) & 63,
1322 (tb2 >> 22) & 3,
1323 (tb2 >> 16) & 63);
1324 printf (_(" fixparms: %-3u floatparms: %-3u parm_on_stk: %u\n"),
1325 (tb2 >> 8) & 0xff,
1326 (tb2 >> 1) & 0x7f,
1327 (tb2 >> 0) & 1);
1328
1329 if (((tb2 >> 1) & 0x7fff) != 0)
1330 {
1331 unsigned int parminfo;
1332
1333 if (off >= text_size)
1334 goto truncated;
1335 parminfo = bfd_get_32 (abfd, text + off);
1336 off += 4;
1337 printf (_(" parminfo: 0x%08x\n"), parminfo);
1338 }
1339
1340 if ((tb1 >> 13) & 1)
1341 {
1342 unsigned int tboff;
1343
1344 if (off >= text_size)
1345 goto truncated;
1346 tboff = bfd_get_32 (abfd, text + off);
1347 off += 4;
1348 printf (_(" tb_offset: 0x%08x (start=0x%08x)\n"),
1349 tboff, text_start + i - tboff);
1350 }
1351 if ((tb1 >> 7) & 1)
1352 {
1353 unsigned int hand_mask;
1354
1355 if (off >= text_size)
1356 goto truncated;
1357 hand_mask = bfd_get_32 (abfd, text + off);
1358 off += 4;
1359 printf (_(" hand_mask_offset: 0x%08x\n"), hand_mask);
1360 }
1361 if ((tb1 >> 11) & 1)
1362 {
1363 unsigned int ctl_info;
1364 unsigned int j;
1365
1366 if (off >= text_size)
1367 goto truncated;
1368 ctl_info = bfd_get_32 (abfd, text + off);
1369 off += 4;
1370 printf (_(" number of CTL anchors: %u\n"), ctl_info);
1371 for (j = 0; j < ctl_info; j++)
1372 {
1373 if (off >= text_size)
1374 goto truncated;
1375 printf (_(" CTL[%u]: %08x\n"),
1376 j, (unsigned)bfd_get_32 (abfd, text + off));
1377 off += 4;
1378 }
1379 }
1380 if ((tb1 >> 6) & 1)
1381 {
1382 unsigned int name_len;
1383 unsigned int j;
1384
1385 if (off >= text_size)
1386 goto truncated;
1387 name_len = bfd_get_16 (abfd, text + off);
1388 off += 2;
1389 printf (_(" Name (len: %u): "), name_len);
1390 if (off + name_len >= text_size)
1391 {
1392 printf (_("[truncated]\n"));
1393 goto truncated;
1394 }
1395 for (j = 0; j < name_len; j++)
1396 if (ISPRINT (text[off + j]))
1397 putchar (text[off + j]);
1398 else
1399 printf ("[%02x]", (unsigned char)text[off + j]);
1400 putchar ('\n');
1401 off += name_len;
1402 }
1403 if ((tb1 >> 5) & 1)
1404 {
1405 if (off >= text_size)
1406 goto truncated;
1407 printf (_(" alloca reg: %u\n"),
1408 (unsigned) bfd_get_8 (abfd, text + off));
1409 off++;
1410 }
1411 printf (_(" (end of tags at %08x)\n"), text_start + off);
1412 return;
1413 }
1414 printf (_(" no tags found\n"));
1415 return;
1416
1417 truncated:
1418 printf (_(" Truncated .text section\n"));
1419 return;
1420}
1421
1422static void
1423dump_xcoff32_traceback (bfd *abfd, struct xcoff_dump *data)
1424{
1425 unsigned int i;
1426 unsigned int scnum_text = -1;
1427 unsigned int text_vma;
1428 asection *text_sec;
1429 bfd_size_type text_size;
1430 char *text;
1431
1432 if (data->syms == NULL || data->sects == NULL)
1433 return;
1434
1435 /* Read text section. */
1436 text_sec = bfd_get_section_by_name (abfd, ".text");
1437 if (text_sec == NULL)
1438 return;
1439 text_vma = bfd_get_section_vma (abfd, text_sec);
1440
1441 text_size = bfd_get_section_size (text_sec);
1442 text = (char *) xmalloc (text_size);
1443 bfd_get_section_contents (abfd, text_sec, text, 0, text_size);
1444
1445 for (i = 0; i < data->nscns; i++)
1446 if (data->sects[i].flags == STYP_TEXT)
1447 {
1448 scnum_text = i + 1;
1449 break;
1450 }
1451 if (scnum_text == (unsigned int)-1)
1452 return;
1453
1454 for (i = 0; i < data->nsyms; i++)
1455 {
1456 union xcoff32_symbol *s = &data->syms[i];
1457
1458 switch (s->sym.sclass)
1459 {
1460 case C_EXT:
1461 case C_HIDEXT:
1462 case C_WEAKEXT:
1463 if (s->sym.scnum == scnum_text
1464 && s->sym.numaux > 0)
1465 {
1466 union external_auxent *aux = &s[s->sym.numaux].aux;
1467
1468 unsigned int smtyp;
1469 unsigned int smclas;
1470
1471 smtyp = bfd_h_get_8 (abfd, aux->x_csect.x_smtyp);
1472 smclas = bfd_h_get_8 (abfd, aux->x_csect.x_smclas);
1473 if (SMTYP_SMTYP (smtyp) == XTY_LD
1474 && (smclas == XMC_PR
1475 || smclas == XMC_GL
1476 || smclas == XMC_XO))
1477 {
1478 printf ("%08x: ", s->sym.val);
1479 xcoff32_print_symbol (data, i);
1480 putchar ('\n');
1481 dump_xcoff32_tbtags (abfd, text, text_size,
1482 text_vma, s->sym.val);
1483 }
1484 }
1485 break;
1486 default:
1487 break;
1488 }
1489 i += s->sym.numaux;
1490 }
1491 free (text);
1492}
1493
1494/* Dump the TOC symbols. */
1495
1496static void
1497dump_xcoff32_toc (bfd *abfd, struct xcoff_dump *data)
1498{
1499 unsigned int i;
1500 unsigned int nbr_ent;
1501 unsigned int size;
1502
1503 printf (_("TOC:\n"));
1504
1505 if (data->syms == NULL)
1506 return;
1507
1508 nbr_ent = 0;
1509 size = 0;
1510
1511 for (i = 0; i < data->nsyms; i++)
1512 {
1513 union xcoff32_symbol *s = &data->syms[i];
1514
1515 switch (s->sym.sclass)
1516 {
1517 case C_EXT:
1518 case C_HIDEXT:
1519 case C_WEAKEXT:
1520 if (s->sym.numaux > 0)
1521 {
1522 union external_auxent *aux = &s[s->sym.numaux].aux;
1523 unsigned int smclas;
1524 unsigned int ent_sz;
1525
1526 smclas = bfd_h_get_8 (abfd, aux->x_csect.x_smclas);
1527 if (smclas == XMC_TC
1528 || smclas == XMC_TD
1529 || smclas == XMC_TC0)
1530 {
1531 ent_sz = bfd_h_get_32 (abfd, aux->x_scn.x_scnlen);
1532 printf ("%08x %08x ",
1533 s->sym.val, ent_sz);
1534 xcoff32_print_symbol (data, i);
1535 putchar ('\n');
1536 nbr_ent++;
1537 size += ent_sz;
1538 }
1539 }
1540 break;
1541 default:
1542 break;
1543 }
1544 i += s->sym.numaux;
1545 }
1546 printf (_("Nbr entries: %-8u Size: %08x (%u)\n"),
1547 nbr_ent, size, size);
1548}
1549
1550/* Handle an rs6000 xcoff file. */
1551
1552static void
1553dump_xcoff32 (bfd *abfd, struct external_filehdr *fhdr)
1554{
1555 struct xcoff_dump data;
1556
1557 data.nscns = bfd_h_get_16 (abfd, fhdr->f_nscns);
1558 data.symptr = bfd_h_get_32 (abfd, fhdr->f_symptr);
1559 data.nsyms = bfd_h_get_32 (abfd, fhdr->f_nsyms);
1560 data.opthdr = bfd_h_get_16 (abfd, fhdr->f_opthdr);
1561 data.sects = NULL;
1562 data.syms = NULL;
1563 data.strings = NULL;
1564 data.strings_size = 0;
1565
1566 if (options[OPT_FILE_HEADER].selected)
1567 dump_xcoff32_file_header (abfd, fhdr, &data);
1568
1569 if (options[OPT_AOUT].selected)
1570 dump_xcoff32_aout_header (abfd, &data);
1571
1572 if (options[OPT_SYMS].selected
1573 || options[OPT_RELOCS].selected
1574 || options[OPT_LINENO].selected
1575 || options[OPT_TRACEBACK].selected)
1576 xcoff32_read_sections (abfd, &data);
1577
1578 if (options[OPT_SECTIONS].selected)
1579 dump_xcoff32_sections_header (abfd, &data);
1580
1581 if (options[OPT_SYMS].selected
1582 || options[OPT_RELOCS].selected
1583 || options[OPT_LINENO].selected
1584 || options[OPT_EXCEPT].selected
1585 || options[OPT_TRACEBACK].selected
1586 || options[OPT_TOC].selected)
1587 xcoff32_read_symbols (abfd, &data);
1588
1589 if (options[OPT_SYMS].selected)
1590 dump_xcoff32_symbols (abfd, &data);
1591
1592 if (options[OPT_RELOCS].selected)
1593 dump_xcoff32_relocs (abfd, &data);
1594
1595 if (options[OPT_LINENO].selected)
1596 dump_xcoff32_lineno (abfd, &data);
1597
1598 if (options[OPT_LOADER].selected)
1599 dump_xcoff32_loader (abfd);
1600
1601 if (options[OPT_EXCEPT].selected)
1602 dump_xcoff32_except (abfd, &data);
1603
1604 if (options[OPT_TYPCHK].selected)
1605 dump_xcoff32_typchk (abfd);
1606
1607 if (options[OPT_TRACEBACK].selected)
1608 dump_xcoff32_traceback (abfd, &data);
1609
1610 if (options[OPT_TOC].selected)
1611 dump_xcoff32_toc (abfd, &data);
1612
1613 free (data.sects);
1614 free (data.strings);
1615 free (data.syms);
1616}
1617
1618/* Dump ABFD (according to the options[] array). */
1619
1620static void
1621xcoff_dump (bfd *abfd)
1622{
1623 struct external_filehdr fhdr;
1624 unsigned short magic;
1625
1626 /* Read file header. */
1627 if (bfd_seek (abfd, 0, SEEK_SET) != 0
1628 || bfd_bread (&fhdr, sizeof (fhdr), abfd) != sizeof (fhdr))
1629 {
1630 non_fatal (_("cannot read header"));
1631 return;
1632 }
1633
1634 /* Decoding. We don't use the bfd/coff function to get all the fields. */
1635 magic = bfd_h_get_16 (abfd, fhdr.f_magic);
1636 if (options[OPT_FILE_HEADER].selected)
1637 {
1638 printf (_("File header:\n"));
1639 printf (_(" magic: 0x%04x (0%04o) "), magic, magic);
1640 switch (magic)
1641 {
1642 case U802WRMAGIC:
1643 printf (_("(WRMAGIC: writable text segments)"));
1644 break;
1645 case U802ROMAGIC:
1646 printf (_("(ROMAGIC: readonly sharablee text segments)"));
1647 break;
1648 case U802TOCMAGIC:
1649 printf (_("(TOCMAGIC: readonly text segments and TOC)"));
1650 break;
1651 default:
1652 printf (_("unknown magic"));
1653 }
1654 putchar ('\n');
1655 }
1656 if (magic == U802ROMAGIC || magic == U802WRMAGIC || magic == U802TOCMAGIC)
1657 dump_xcoff32 (abfd, &fhdr);
1658 else
1659 printf (_(" Unhandled magic\n"));
1660}
1661
1662/* Vector for xcoff. */
1663
1664const struct objdump_private_desc objdump_private_desc_xcoff =
1665 {
1666 xcoff_help,
1667 xcoff_filter,
1668 xcoff_dump,
1669 options
1670 };
This page took 0.080165 seconds and 4 git commands to generate.