2011-09-27 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. */
e682d13b
TG
642 if (bfd_seek (abfd, stptr, SEEK_SET) != 0
643 || bfd_bread (&stsz_arr, sizeof (stsz_arr), abfd) != sizeof (stsz_arr))
6abcee90 644 {
e682d13b 645 non_fatal (_("cannot read strings table length"));
6abcee90
TG
646 data->strings_size = 0;
647 }
648 else
649 {
6abcee90
TG
650 data->strings_size = bfd_h_get_32 (abfd, stsz_arr);
651 if (data->strings_size > sizeof (stsz_arr))
652 {
653 unsigned int remsz = data->strings_size - sizeof (stsz_arr);
654
655 data->strings = xmalloc (data->strings_size);
656
657 memcpy (data->strings, stsz_arr, sizeof (stsz_arr));
658 if (bfd_bread (data->strings + sizeof (stsz_arr), remsz, abfd)
659 != remsz)
660 {
661 non_fatal (_("cannot read strings table"));
662 goto clean;
663 }
664 }
665 }
666
667 if (bfd_seek (abfd, data->symptr, SEEK_SET) != 0)
668 {
669 non_fatal (_("cannot read symbol table"));
670 goto clean;
671 }
672
673 data->syms = (union xcoff32_symbol *)
674 xmalloc (data->nsyms * sizeof (union xcoff32_symbol));
675
676 for (i = 0; i < data->nsyms; i++)
677 {
678 struct external_syment sym;
679 int j;
680 union xcoff32_symbol *s = &data->syms[i];
681
682 if (bfd_bread (&sym, sizeof (sym), abfd) != sizeof (sym))
683 {
684 non_fatal (_("cannot read symbol entry"));
685 goto clean;
686 }
687
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);
693
694 if (sym.e.e_name[0])
695 {
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;
699 }
700 else
701 {
702 unsigned int soff = bfd_h_get_32 (abfd, sym.e.e.e_offset);
703
704 if ((s->sym.sclass & DBXMASK) == 0 && soff < data->strings_size)
705 s->sym.name = data->strings + soff;
706 else
707 {
708 s->sym.name = NULL;
709 s->sym.raw.off = soff;
710 }
711 }
712
713 for (j = 0; j < s->sym.numaux; j++, i++)
714 {
715 if (bfd_bread (&s[j + 1].aux,
716 sizeof (union external_auxent), abfd)
717 != sizeof (union external_auxent))
718 {
719 non_fatal (_("cannot read symbol aux entry"));
720 goto clean;
721 }
722 }
723 }
724 return;
725 clean:
726 free (data->syms);
727 data->syms = NULL;
728 free (data->strings);
729 data->strings = NULL;
730}
731
732/* Dump xcoff symbols. */
733
734static void
735dump_xcoff32_symbols (bfd *abfd, struct xcoff_dump *data)
736{
737 unsigned int i;
738 asection *debugsec;
739 char *debug = NULL;
740
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)
745 {
746 printf (_(":\n No symbols\n"));
747 return;
748 }
749
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);
755
756 /* Read debug section. */
757 debugsec = bfd_get_section_by_name (abfd, ".debug");
758 if (debugsec != NULL)
759 {
760 bfd_size_type size;
761
762 size = bfd_get_section_size (debugsec);
763 debug = (char *) xmalloc (size);
764 bfd_get_section_contents (abfd, debugsec, debug, 0, size);
765 }
766
767 printf (_(" # sc value section type aux name/off\n"));
768 for (i = 0; i < data->nsyms; i++)
769 {
770 union xcoff32_symbol *s = &data->syms[i];
771 int j;
772
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)
777 {
778 if (data->sects != NULL)
779 printf ("%-8s", data->sects[s->sym.scnum - 1].name);
780 else
781 printf ("%-8u", s->sym.scnum);
782 }
783 else
784 switch ((signed short)s->sym.scnum)
785 {
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);
797 }
798 printf (" %04x %3u ", s->sym.ntype, s->sym.numaux);
799 if (s->sym.name != NULL)
800 printf ("%s", s->sym.name);
801 else
802 {
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);
807 }
808 putchar ('\n');
809
810 for (j = 0; j < s->sym.numaux; j++, i++)
811 {
812 union external_auxent *aux = &s[j + 1].aux;
813
814 printf (" %3u ", i + 1);
815 switch (s->sym.sclass)
816 {
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)
832 {
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));
842 }
843 else if (j == 1 || (j == 0 && s->sym.numaux == 1))
844 {
845 /* csect aux entry. */
846 unsigned char smtyp;
847 unsigned int scnlen;
848
849 smtyp = bfd_h_get_8 (abfd, aux->x_csect.x_smtyp);
850 scnlen = bfd_h_get_32 (abfd, aux->x_csect.x_scnlen);
851
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');
867 }
868 else
869 printf ("aux\n");
870 break;
871 case C_FILE:
872 {
873 unsigned int off;
874
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
880 {
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);
887 }
888 putchar ('\n');
889 }
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;
900 }
901 }
902
903 }
904 free (debug);
905}
906
907/* Dump xcoff relocation entries. */
908
909static void
910dump_xcoff32_relocs (bfd *abfd, struct xcoff_dump *data)
911{
912 unsigned int i;
913
914 if (data->sects == NULL)
915 {
916 non_fatal (_("cannot read section headers"));
917 return;
918 }
919
920 for (i = 0; i < data->nscns; i++)
921 {
922 struct xcoff32_section *sect = &data->sects[i];
923 unsigned int nrel = sect->nreloc;
924 unsigned int j;
925
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)
930 {
931 non_fatal (_("cannot read relocations"));
932 continue;
933 }
934 printf (_("vaddr sgn mod sz type symndx symbol\n"));
935 for (j = 0; j < nrel; j++)
936 {
937 struct external_reloc rel;
938 unsigned char rsize;
939 unsigned int symndx;
940
941 if (bfd_bread (&rel, sizeof (rel), abfd) != sizeof (rel))
942 {
943 non_fatal (_("cannot read relocation entry"));
944 return;
945 }
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');
957 }
958 putchar ('\n');
959 }
960}
961
962/* Dump xcoff line number entries. */
963
964static void
965dump_xcoff32_lineno (bfd *abfd, struct xcoff_dump *data)
966{
967 unsigned int i;
968
969 if (data->sects == NULL)
970 {
971 non_fatal (_("cannot read section headers"));
972 return;
973 }
974
975 for (i = 0; i < data->nscns; i++)
976 {
977 struct xcoff32_section *sect = &data->sects[i];
978 unsigned int nlnno = sect->nlnno;
979 unsigned int j;
980
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)
985 {
986 non_fatal (_("cannot read line numbers"));
987 continue;
988 }
989 printf (_("lineno symndx/paddr\n"));
990 for (j = 0; j < nlnno; j++)
991 {
992 struct external_lineno ln;
993 unsigned int no;
994
995 if (bfd_bread (&ln, sizeof (ln), abfd) != sizeof (ln))
996 {
997 non_fatal (_("cannot read line number entry"));
998 return;
999 }
1000 no = bfd_h_get_16 (abfd, ln.l_lnno);
1001 printf (_(" %-6u "), no);
1002 if (no == 0)
1003 {
1004 unsigned int symndx = bfd_h_get_32 (abfd, ln.l_addr.l_symndx);
1005 xcoff32_print_symbol (data, symndx);
1006 }
1007 else
1008 printf ("0x%08x",
1009 (unsigned int)bfd_h_get_32 (abfd, ln.l_addr.l_paddr));
1010 putchar ('\n');
1011 }
1012 }
1013}
1014
1015/* Dump xcoff loader section. */
1016
1017static void
1018dump_xcoff32_loader (bfd *abfd)
1019{
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;
1035
1036 loader = bfd_get_section_by_name (abfd, ".loader");
1037
1038 if (loader == NULL)
1039 {
1040 printf (_("no .loader section in file\n"));
1041 return;
1042 }
1043 size = bfd_get_section_size (loader);
1044 if (size < sizeof (*lhdr))
1045 {
1046 printf (_("section .loader is too short\n"));
1047 return;
1048 }
1049
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)
1057 {
1058 printf (_(" Unhandled version\n"));
1059 free (ldr_data);
1060 return;
1061 }
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);
1076
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++)
1081 {
1082 unsigned char smtype;
1083
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
1103 {
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);
1109 }
1110 putchar ('\n');
1111 }
1112
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++)
1118 {
1119 unsigned int rsize;
1120 unsigned int rtype;
1121 unsigned int symndx;
1122
1123 rsize = bfd_h_get_8 (abfd, ldrel->l_rtype + 0);
1124 rtype = bfd_h_get_8 (abfd, ldrel->l_rtype + 1);
1125
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)
1135 {
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;
1148 }
1149 putchar ('\n');
1150 }
1151
1152 printf (_("Import files:\n"));
1153 p = (char *)ldr_data + impoff;
1154 for (i = 0; i < nimpid; i++)
1155 {
1156 int n1, n2, n3;
1157
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;
1164 }
1165
1166 free (ldr_data);
1167}
1168
1169/* Dump xcoff exception section. */
1170
1171static void
1172dump_xcoff32_except (bfd *abfd, struct xcoff_dump *data)
1173{
1174 asection *sec;
1175 bfd_size_type size = 0;
1176 bfd_byte *excp_data;
1177 struct external_exceptab *exceptab;
1178 unsigned int i;
1179
1180 sec = bfd_get_section_by_name (abfd, ".except");
1181
1182 if (sec == NULL)
1183 {
1184 printf (_("no .except section in file\n"));
1185 return;
1186 }
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;
1191
1192 printf (_("Exception table:\n"));
1193 printf (_("lang reason sym/addr\n"));
1194 for (i = 0; i * sizeof (*exceptab) < size; i++, exceptab++)
1195 {
1196 unsigned int reason;
1197 unsigned int addr;
1198
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');
1208 }
1209 free (excp_data);
1210}
1211
1212/* Dump xcoff type-check section. */
1213
1214static void
1215dump_xcoff32_typchk (bfd *abfd)
1216{
1217 asection *sec;
1218 bfd_size_type size = 0;
1219 bfd_byte *data;
1220 unsigned int i;
1221
1222 sec = bfd_get_section_by_name (abfd, ".typchk");
1223
1224 if (sec == NULL)
1225 {
1226 printf (_("no .typchk section in file\n"));
1227 return;
1228 }
1229 size = bfd_get_section_size (sec);
1230 data = (bfd_byte *) xmalloc (size);
1231 bfd_get_section_contents (abfd, sec, data, 0, size);
1232
1233 printf (_("Type-check section:\n"));
1234 printf (_("offset len lang-id general-hash language-hash\n"));
1235 for (i = 0; i < size;)
1236 {
1237 unsigned int len;
1238
1239 len = bfd_get_16 (abfd, data + i);
1240 printf ("%08x: %-4u ", i, len);
1241 i += 2;
1242
1243 if (len == 10)
1244 {
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));
1250 }
1251 else
1252 {
1253 unsigned int j;
1254
1255 for (j = 0; j < len; j++)
1256 {
1257 if (j % 16 == 0)
1258 printf ("\n ");
1259 printf (" %02x", (unsigned char)data[i + j]);
1260 }
1261 putchar ('\n');
1262 }
1263 i += len;
1264 }
1265 free (data);
1266}
1267
1268/* Dump xcoff traceback tags section. */
1269
1270static void
1271dump_xcoff32_tbtags (bfd *abfd,
1272 const char *text, bfd_size_type text_size,
1273 unsigned int text_start, unsigned int func_start)
1274{
1275 unsigned int i;
1276
1277 if (func_start - text_start > text_size)
1278 {
1279 printf (_(" address beyond section size\n"));
1280 return;
1281 }
1282 for (i = func_start - text_start; i < text_size; i+= 4)
1283 if (bfd_get_32 (abfd, text + i) == 0)
1284 {
1285 unsigned int tb1;
1286 unsigned int tb2;
1287 unsigned int off;
1288
1289 printf (_(" tags at %08x\n"), i + 4);
1290 if (i + 8 >= text_size)
1291 goto truncated;
1292
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);
1325
1326 if (((tb2 >> 1) & 0x7fff) != 0)
1327 {
1328 unsigned int parminfo;
1329
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);
1335 }
1336
1337 if ((tb1 >> 13) & 1)
1338 {
1339 unsigned int tboff;
1340
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);
1347 }
1348 if ((tb1 >> 7) & 1)
1349 {
1350 unsigned int hand_mask;
1351
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);
1357 }
1358 if ((tb1 >> 11) & 1)
1359 {
1360 unsigned int ctl_info;
1361 unsigned int j;
1362
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++)
1369 {
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;
1375 }
1376 }
1377 if ((tb1 >> 6) & 1)
1378 {
1379 unsigned int name_len;
1380 unsigned int j;
1381
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)
1388 {
1389 printf (_("[truncated]\n"));
1390 goto truncated;
1391 }
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;
1399 }
1400 if ((tb1 >> 5) & 1)
1401 {
1402 if (off >= text_size)
1403 goto truncated;
1404 printf (_(" alloca reg: %u\n"),
1405 (unsigned) bfd_get_8 (abfd, text + off));
1406 off++;
1407 }
1408 printf (_(" (end of tags at %08x)\n"), text_start + off);
1409 return;
1410 }
1411 printf (_(" no tags found\n"));
1412 return;
1413
1414 truncated:
1415 printf (_(" Truncated .text section\n"));
1416 return;
1417}
1418
1419static void
1420dump_xcoff32_traceback (bfd *abfd, struct xcoff_dump *data)
1421{
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;
1428
1429 if (data->syms == NULL || data->sects == NULL)
1430 return;
1431
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);
1437
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);
1441
1442 for (i = 0; i < data->nscns; i++)
1443 if (data->sects[i].flags == STYP_TEXT)
1444 {
1445 scnum_text = i + 1;
1446 break;
1447 }
1448 if (scnum_text == (unsigned int)-1)
1449 return;
1450
1451 for (i = 0; i < data->nsyms; i++)
1452 {
1453 union xcoff32_symbol *s = &data->syms[i];
1454
1455 switch (s->sym.sclass)
1456 {
1457 case C_EXT:
1458 case C_HIDEXT:
1459 case C_WEAKEXT:
1460 if (s->sym.scnum == scnum_text
1461 && s->sym.numaux > 0)
1462 {
1463 union external_auxent *aux = &s[s->sym.numaux].aux;
1464
1465 unsigned int smtyp;
1466 unsigned int smclas;
1467
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))
1474 {
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);
1480 }
1481 }
1482 break;
1483 default:
1484 break;
1485 }
1486 i += s->sym.numaux;
1487 }
1488 free (text);
1489}
1490
1491/* Dump the TOC symbols. */
1492
1493static void
1494dump_xcoff32_toc (bfd *abfd, struct xcoff_dump *data)
1495{
1496 unsigned int i;
1497 unsigned int nbr_ent;
1498 unsigned int size;
1499
1500 printf (_("TOC:\n"));
1501
1502 if (data->syms == NULL)
1503 return;
1504
1505 nbr_ent = 0;
1506 size = 0;
1507
1508 for (i = 0; i < data->nsyms; i++)
1509 {
1510 union xcoff32_symbol *s = &data->syms[i];
1511
1512 switch (s->sym.sclass)
1513 {
1514 case C_EXT:
1515 case C_HIDEXT:
1516 case C_WEAKEXT:
1517 if (s->sym.numaux > 0)
1518 {
1519 union external_auxent *aux = &s[s->sym.numaux].aux;
1520 unsigned int smclas;
1521 unsigned int ent_sz;
1522
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)
1527 {
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;
1535 }
1536 }
1537 break;
1538 default:
1539 break;
1540 }
1541 i += s->sym.numaux;
1542 }
1543 printf (_("Nbr entries: %-8u Size: %08x (%u)\n"),
1544 nbr_ent, size, size);
1545}
1546
1547/* Handle an rs6000 xcoff file. */
1548
1549static void
1550dump_xcoff32 (bfd *abfd, struct external_filehdr *fhdr)
1551{
1552 struct xcoff_dump data;
1553
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;
1562
1563 if (options[OPT_FILE_HEADER].selected)
1564 dump_xcoff32_file_header (abfd, fhdr, &data);
1565
1566 if (options[OPT_AOUT].selected)
1567 dump_xcoff32_aout_header (abfd, &data);
1568
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);
1574
1575 if (options[OPT_SECTIONS].selected)
1576 dump_xcoff32_sections_header (abfd, &data);
1577
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);
1585
1586 if (options[OPT_SYMS].selected)
1587 dump_xcoff32_symbols (abfd, &data);
1588
1589 if (options[OPT_RELOCS].selected)
1590 dump_xcoff32_relocs (abfd, &data);
1591
1592 if (options[OPT_LINENO].selected)
1593 dump_xcoff32_lineno (abfd, &data);
1594
1595 if (options[OPT_LOADER].selected)
1596 dump_xcoff32_loader (abfd);
1597
1598 if (options[OPT_EXCEPT].selected)
1599 dump_xcoff32_except (abfd, &data);
1600
1601 if (options[OPT_TYPCHK].selected)
1602 dump_xcoff32_typchk (abfd);
1603
1604 if (options[OPT_TRACEBACK].selected)
1605 dump_xcoff32_traceback (abfd, &data);
1606
1607 if (options[OPT_TOC].selected)
1608 dump_xcoff32_toc (abfd, &data);
1609
1610 free (data.sects);
1611 free (data.strings);
1612 free (data.syms);
1613}
1614
1615/* Dump ABFD (according to the options[] array). */
1616
1617static void
1618xcoff_dump (bfd *abfd)
1619{
1620 struct external_filehdr fhdr;
1621 unsigned short magic;
1622
1623 /* Read file header. */
1624 if (bfd_seek (abfd, 0, SEEK_SET) != 0
1625 || bfd_bread (&fhdr, sizeof (fhdr), abfd) != sizeof (fhdr))
1626 {
1627 non_fatal (_("cannot read header"));
1628 return;
1629 }
1630
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)
1634 {
1635 printf (_("File header:\n"));
1636 printf (_(" magic: 0x%04x (0%04o) "), magic, magic);
1637 switch (magic)
1638 {
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"));
1650 }
1651 putchar ('\n');
1652 }
1653 if (magic == U802ROMAGIC || magic == U802WRMAGIC || magic == U802TOCMAGIC)
1654 dump_xcoff32 (abfd, &fhdr);
1655 else
1656 printf (_(" Unhandled magic\n"));
1657}
1658
1659/* Vector for xcoff. */
1660
1661const struct objdump_private_desc objdump_private_desc_xcoff =
1662 {
1663 xcoff_help,
1664 xcoff_filter,
1665 xcoff_dump,
1666 options
1667 };
This page took 0.094786 seconds and 4 git commands to generate.