PR binutils/14475:
[deliverable/binutils-gdb.git] / binutils / od-xcoff.c
CommitLineData
6abcee90 1/* od-xcoff.c -- dump information about an xcoff object file.
dbb7c441 2 Copyright 2011, 2012 Free Software Foundation, Inc.
6abcee90
TG
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
dbb7c441 22#include "sysdep.h"
6abcee90
TG
23#include <stddef.h>
24#include <time.h>
6abcee90
TG
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);
a82526dd 462 /* We don't translate these strings as they are fields name. */
21eb9156
TG
463 printf (" o_mflag (magic): 0x%04x 0%04o\n", magic, magic);
464 printf (" o_vstamp: 0x%04x\n",
6abcee90 465 (unsigned short)bfd_h_get_16 (abfd, auxhdr.vstamp));
21eb9156 466 printf (" o_tsize: 0x%08x\n",
6abcee90 467 (unsigned int)bfd_h_get_32 (abfd, auxhdr.tsize));
21eb9156 468 printf (" o_dsize: 0x%08x\n",
6abcee90 469 (unsigned int)bfd_h_get_32 (abfd, auxhdr.dsize));
21eb9156 470 printf (" o_entry: 0x%08x\n",
6abcee90 471 (unsigned int)bfd_h_get_32 (abfd, auxhdr.entry));
21eb9156 472 printf (" o_text_start: 0x%08x\n",
6abcee90 473 (unsigned int)bfd_h_get_32 (abfd, auxhdr.text_start));
21eb9156 474 printf (" o_data_start: 0x%08x\n",
6abcee90
TG
475 (unsigned int)bfd_h_get_32 (abfd, auxhdr.data_start));
476 if (sz == offsetof (AOUTHDR, o_toc))
477 return;
21eb9156 478 printf (" o_toc: 0x%08x\n",
6abcee90 479 (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_toc));
21eb9156 480 printf (" o_snentry: 0x%04x\n",
6abcee90 481 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snentry));
21eb9156 482 printf (" o_sntext: 0x%04x\n",
6abcee90 483 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sntext));
21eb9156 484 printf (" o_sndata: 0x%04x\n",
6abcee90 485 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sndata));
21eb9156 486 printf (" o_sntoc: 0x%04x\n",
6abcee90 487 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sntoc));
21eb9156 488 printf (" o_snloader: 0x%04x\n",
6abcee90 489 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snloader));
21eb9156 490 printf (" o_snbss: 0x%04x\n",
6abcee90 491 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snbss));
21eb9156 492 printf (" o_algntext: %u\n",
6abcee90 493 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_algntext));
21eb9156 494 printf (" o_algndata: %u\n",
6abcee90 495 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_algndata));
21eb9156 496 printf (" o_modtype: 0x%04x",
6abcee90
TG
497 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_modtype));
498 if (ISPRINT (auxhdr.o_modtype[0]) && ISPRINT (auxhdr.o_modtype[1]))
499 printf (" (%c%c)", auxhdr.o_modtype[0], auxhdr.o_modtype[1]);
500 putchar ('\n');
21eb9156 501 printf (" o_cputype: 0x%04x\n",
6abcee90 502 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_cputype));
21eb9156 503 printf (" o_maxstack: 0x%08x\n",
6abcee90 504 (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_maxstack));
21eb9156 505 printf (" o_maxdata: 0x%08x\n",
6abcee90
TG
506 (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_maxdata));
507#if 0
21eb9156 508 printf (" o_debugger: 0x%08x\n",
6abcee90
TG
509 (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_debugger));
510#endif
511}
512
513/* Dump the sections header. */
514
515static void
516dump_xcoff32_sections_header (bfd *abfd, struct xcoff_dump *data)
517{
518 unsigned int i;
519 unsigned int off;
520
521 off = sizeof (struct external_filehdr) + data->opthdr;
522 printf (_("Section headers (at %u+%u=0x%08x to 0x%08x):\n"),
523 (unsigned int)sizeof (struct external_filehdr), data->opthdr, off,
524 off + (unsigned int)sizeof (struct external_scnhdr) * data->nscns);
525 if (data->nscns == 0)
526 {
527 printf (_(" No section header\n"));
528 return;
529 }
530 if (bfd_seek (abfd, off, SEEK_SET) != 0)
531 {
532 non_fatal (_("cannot read section header"));
533 return;
534 }
21eb9156
TG
535 /* We don't translate this string as it consists in fields name. */
536 printf (" # Name paddr vaddr size scnptr relptr lnnoptr nrel nlnno\n");
6abcee90
TG
537 for (i = 0; i < data->nscns; i++)
538 {
539 struct external_scnhdr scn;
540 unsigned int flags;
541
542 if (bfd_bread (&scn, sizeof (scn), abfd) != sizeof (scn))
543 {
544 non_fatal (_("cannot read section header"));
545 return;
546 }
547 flags = bfd_h_get_32 (abfd, scn.s_flags);
21eb9156 548 printf ("%2d %-8.8s %08x %08x %08x %08x %08x %08x %-5d %-5d\n",
6abcee90
TG
549 i + 1, scn.s_name,
550 (unsigned int)bfd_h_get_32 (abfd, scn.s_paddr),
551 (unsigned int)bfd_h_get_32 (abfd, scn.s_vaddr),
552 (unsigned int)bfd_h_get_32 (abfd, scn.s_size),
553 (unsigned int)bfd_h_get_32 (abfd, scn.s_scnptr),
554 (unsigned int)bfd_h_get_32 (abfd, scn.s_relptr),
555 (unsigned int)bfd_h_get_32 (abfd, scn.s_lnnoptr),
556 (unsigned int)bfd_h_get_16 (abfd, scn.s_nreloc),
557 (unsigned int)bfd_h_get_16 (abfd, scn.s_nlnno));
558 printf (_(" Flags: %08x "), flags);
559
560 if (~flags == 0)
561 {
562 /* Stripped executable ? */
563 putchar ('\n');
564 }
565 else if (flags & STYP_OVRFLO)
566 printf (_("overflow - nreloc: %u, nlnno: %u\n"),
567 (unsigned int)bfd_h_get_32 (abfd, scn.s_paddr),
568 (unsigned int)bfd_h_get_32 (abfd, scn.s_vaddr));
569 else
570 {
571 dump_flags (s_flag_xlat, flags);
572 putchar ('\n');
573 }
574 }
575}
576
577/* Read section table. */
578
579static void
580xcoff32_read_sections (bfd *abfd, struct xcoff_dump *data)
581{
582 int i;
583
584 if (bfd_seek (abfd, sizeof (struct external_filehdr) + data->opthdr,
585 SEEK_SET) != 0)
586 {
587 non_fatal (_("cannot read section headers"));
588 return;
589 }
590
591 data->sects = xmalloc (data->nscns * sizeof (struct xcoff32_section));
592 for (i = 0; i < data->nscns; i++)
593 {
594 struct external_scnhdr scn;
595 struct xcoff32_section *s = &data->sects[i];
596
597 if (bfd_bread (&scn, sizeof (scn), abfd) != sizeof (scn))
598 {
599 non_fatal (_("cannot read section header"));
600 free (data->sects);
601 data->sects = NULL;
602 return;
603 }
604 memcpy (s->name, scn.s_name, 8);
605 s->name[8] = 0;
606 s->flags = bfd_h_get_32 (abfd, scn.s_flags);
607
608 s->scnptr = bfd_h_get_32 (abfd, scn.s_scnptr);
609 s->relptr = bfd_h_get_32 (abfd, scn.s_relptr);
610 s->lnnoptr = bfd_h_get_32 (abfd, scn.s_lnnoptr);
611
612 s->nreloc = bfd_h_get_16 (abfd, scn.s_nreloc);
613 s->nlnno = bfd_h_get_16 (abfd, scn.s_nlnno);
614
615 if (s->flags == STYP_OVRFLO)
616 {
617 if (s->nreloc > 0 && s->nreloc <= data->nscns)
618 data->sects[s->nreloc - 1].nreloc =
619 bfd_h_get_32 (abfd, scn.s_paddr);
620 if (s->nlnno > 0 && s->nlnno <= data->nscns)
621 data->sects[s->nlnno - 1].nlnno =
622 bfd_h_get_32 (abfd, scn.s_vaddr);
623 }
624 }
625}
626
627/* Read symbols. */
628
629static void
630xcoff32_read_symbols (bfd *abfd, struct xcoff_dump *data)
631{
632 unsigned int i;
633 char stsz_arr[4];
634 unsigned int stptr;
635
636 if (data->nsyms == 0)
637 return;
638
639 stptr = data->symptr
640 + data->nsyms * (unsigned)sizeof (struct external_syment);
641
642 /* Read string table. */
e682d13b
TG
643 if (bfd_seek (abfd, stptr, SEEK_SET) != 0
644 || bfd_bread (&stsz_arr, sizeof (stsz_arr), abfd) != sizeof (stsz_arr))
6abcee90 645 {
e682d13b 646 non_fatal (_("cannot read strings table length"));
6abcee90
TG
647 data->strings_size = 0;
648 }
649 else
650 {
6abcee90
TG
651 data->strings_size = bfd_h_get_32 (abfd, stsz_arr);
652 if (data->strings_size > sizeof (stsz_arr))
653 {
654 unsigned int remsz = data->strings_size - sizeof (stsz_arr);
655
656 data->strings = xmalloc (data->strings_size);
657
658 memcpy (data->strings, stsz_arr, sizeof (stsz_arr));
659 if (bfd_bread (data->strings + sizeof (stsz_arr), remsz, abfd)
660 != remsz)
661 {
662 non_fatal (_("cannot read strings table"));
663 goto clean;
664 }
665 }
666 }
667
668 if (bfd_seek (abfd, data->symptr, SEEK_SET) != 0)
669 {
670 non_fatal (_("cannot read symbol table"));
671 goto clean;
672 }
673
674 data->syms = (union xcoff32_symbol *)
675 xmalloc (data->nsyms * sizeof (union xcoff32_symbol));
676
677 for (i = 0; i < data->nsyms; i++)
678 {
679 struct external_syment sym;
680 int j;
681 union xcoff32_symbol *s = &data->syms[i];
682
683 if (bfd_bread (&sym, sizeof (sym), abfd) != sizeof (sym))
684 {
685 non_fatal (_("cannot read symbol entry"));
686 goto clean;
687 }
688
689 s->sym.val = bfd_h_get_32 (abfd, sym.e_value);
690 s->sym.scnum = bfd_h_get_16 (abfd, sym.e_scnum);
691 s->sym.ntype = bfd_h_get_16 (abfd, sym.e_type);
692 s->sym.sclass = bfd_h_get_8 (abfd, sym.e_sclass);
693 s->sym.numaux = bfd_h_get_8 (abfd, sym.e_numaux);
694
695 if (sym.e.e_name[0])
696 {
697 memcpy (s->sym.raw.name, sym.e.e_name, sizeof (sym.e.e_name));
698 s->sym.raw.name[8] = 0;
699 s->sym.name = s->sym.raw.name;
700 }
701 else
702 {
703 unsigned int soff = bfd_h_get_32 (abfd, sym.e.e.e_offset);
704
705 if ((s->sym.sclass & DBXMASK) == 0 && soff < data->strings_size)
706 s->sym.name = data->strings + soff;
707 else
708 {
709 s->sym.name = NULL;
710 s->sym.raw.off = soff;
711 }
712 }
713
714 for (j = 0; j < s->sym.numaux; j++, i++)
715 {
716 if (bfd_bread (&s[j + 1].aux,
717 sizeof (union external_auxent), abfd)
718 != sizeof (union external_auxent))
719 {
720 non_fatal (_("cannot read symbol aux entry"));
721 goto clean;
722 }
723 }
724 }
725 return;
726 clean:
727 free (data->syms);
728 data->syms = NULL;
729 free (data->strings);
730 data->strings = NULL;
731}
732
733/* Dump xcoff symbols. */
734
735static void
736dump_xcoff32_symbols (bfd *abfd, struct xcoff_dump *data)
737{
738 unsigned int i;
739 asection *debugsec;
740 char *debug = NULL;
741
742 printf (_("Symbols table (strtable at 0x%08x)"),
743 data->symptr
744 + data->nsyms * (unsigned)sizeof (struct external_syment));
745 if (data->nsyms == 0 || data->syms == NULL)
746 {
747 printf (_(":\n No symbols\n"));
748 return;
749 }
750
21eb9156 751 /* Read strings table. */
6abcee90
TG
752 if (data->strings_size == 0)
753 printf (_(" (no strings):\n"));
754 else
755 printf (_(" (strings size: %08x):\n"), data->strings_size);
756
757 /* Read debug section. */
758 debugsec = bfd_get_section_by_name (abfd, ".debug");
759 if (debugsec != NULL)
760 {
761 bfd_size_type size;
762
763 size = bfd_get_section_size (debugsec);
764 debug = (char *) xmalloc (size);
765 bfd_get_section_contents (abfd, debugsec, debug, 0, size);
766 }
767
21eb9156 768 /* Translators: 'sc' is for storage class, 'off' for offset. */
6abcee90
TG
769 printf (_(" # sc value section type aux name/off\n"));
770 for (i = 0; i < data->nsyms; i++)
771 {
772 union xcoff32_symbol *s = &data->syms[i];
773 int j;
774
775 printf ("%3u ", i);
776 dump_value (sc_xlat, s->sym.sclass, 10);
777 printf (" %08x ", s->sym.val);
778 if (s->sym.scnum > 0 && s->sym.scnum <= data->nscns)
779 {
780 if (data->sects != NULL)
781 printf ("%-8s", data->sects[s->sym.scnum - 1].name);
782 else
783 printf ("%-8u", s->sym.scnum);
784 }
785 else
786 switch ((signed short)s->sym.scnum)
787 {
788 case N_DEBUG:
789 printf ("N_DEBUG ");
790 break;
791 case N_ABS:
792 printf ("N_ABS ");
793 break;
794 case N_UNDEF:
795 printf ("N_UNDEF ");
796 break;
797 default:
798 printf ("(%04x) ", s->sym.scnum);
799 }
800 printf (" %04x %3u ", s->sym.ntype, s->sym.numaux);
801 if (s->sym.name != NULL)
802 printf ("%s", s->sym.name);
803 else
804 {
805 if ((s->sym.sclass & DBXMASK) != 0 && debug != NULL)
806 printf ("%s", debug + s->sym.raw.off);
807 else
808 printf ("%08x", s->sym.raw.off);
809 }
810 putchar ('\n');
811
812 for (j = 0; j < s->sym.numaux; j++, i++)
813 {
814 union external_auxent *aux = &s[j + 1].aux;
815
816 printf (" %3u ", i + 1);
817 switch (s->sym.sclass)
818 {
819 case C_STAT:
21eb9156 820 /* Section length, number of relocs and line number. */
6abcee90
TG
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:
21eb9156 827 /* Section length and number of relocs. */
6abcee90
TG
828 printf (_(" scnlen: %08x nreloc: %-6u\n"),
829 (unsigned)bfd_h_get_32 (abfd, aux->x_scn.x_scnlen),
830 (unsigned)bfd_h_get_16 (abfd, aux->x_scn.x_nreloc));
831 break;
832 case C_EXT:
833 case C_WEAKEXT:
834 case C_HIDEXT:
835 if (j == 0 && s->sym.numaux > 1)
836 {
21eb9156
TG
837 /* Function aux entry (Do not translate). */
838 printf (" exptr: %08x fsize: %08x lnnoptr: %08x endndx: %u\n",
6abcee90
TG
839 (unsigned)bfd_h_get_32 (abfd, aux->x_sym.x_tagndx),
840 (unsigned)bfd_h_get_32
841 (abfd, aux->x_sym.x_misc.x_fsize),
842 (unsigned)bfd_h_get_32
843 (abfd, aux->x_sym.x_fcnary.x_fcn.x_lnnoptr),
844 (unsigned)bfd_h_get_32
845 (abfd, aux->x_sym.x_fcnary.x_fcn.x_endndx));
846 }
847 else if (j == 1 || (j == 0 && s->sym.numaux == 1))
848 {
849 /* csect aux entry. */
850 unsigned char smtyp;
851 unsigned int scnlen;
852
853 smtyp = bfd_h_get_8 (abfd, aux->x_csect.x_smtyp);
854 scnlen = bfd_h_get_32 (abfd, aux->x_csect.x_scnlen);
855
856 if (smtyp == XTY_LD)
21eb9156 857 printf (" scnsym: %-8u", scnlen);
6abcee90 858 else
21eb9156
TG
859 printf (" scnlen: %08x", scnlen);
860 printf (" h: parm=%08x sn=%04x al: 2**%u",
6abcee90
TG
861 (unsigned)bfd_h_get_32 (abfd, aux->x_csect.x_parmhash),
862 (unsigned)bfd_h_get_16 (abfd, aux->x_csect.x_snhash),
863 SMTYP_ALIGN (smtyp));
21eb9156 864 printf (" typ: ");
6abcee90 865 dump_value (smtyp_xlat, SMTYP_SMTYP (smtyp), 2);
21eb9156 866 printf (" cl: ");
6abcee90
TG
867 dump_value
868 (smclas_xlat,
869 (unsigned)bfd_h_get_8 (abfd, aux->x_csect.x_smclas), 6);
870 putchar ('\n');
871 }
872 else
21eb9156 873 /* Do not translate - generic field name. */
6abcee90
TG
874 printf ("aux\n");
875 break;
876 case C_FILE:
877 {
878 unsigned int off;
879
21eb9156 880 printf (" ftype: %02x ",
6abcee90
TG
881 (unsigned)bfd_h_get_8 (abfd, aux->x_file.x_ftype));
882 if (aux->x_file.x_n.x_fname[0] != 0)
21eb9156 883 printf ("fname: %.14s", aux->x_file.x_n.x_fname);
6abcee90
TG
884 else
885 {
886 off = (unsigned)bfd_h_get_32
887 (abfd, aux->x_file.x_n.x_n.x_offset);
888 if (data->strings != NULL && off < data->strings_size)
21eb9156 889 printf (" %s", data->strings + off);
6abcee90
TG
890 else
891 printf (_("offset: %08x"), off);
892 }
893 putchar ('\n');
894 }
895 break;
896 case C_BLOCK:
897 case C_FCN:
21eb9156 898 printf (" lnno: %u\n",
6abcee90
TG
899 (unsigned)bfd_h_get_16
900 (abfd, aux->x_sym.x_misc.x_lnsz.x_lnno));
901 break;
902 default:
21eb9156 903 /* Do not translate - generic field name. */
6abcee90
TG
904 printf ("aux\n");
905 break;
906 }
907 }
908
909 }
910 free (debug);
911}
912
913/* Dump xcoff relocation entries. */
914
915static void
916dump_xcoff32_relocs (bfd *abfd, struct xcoff_dump *data)
917{
918 unsigned int i;
919
920 if (data->sects == NULL)
921 {
922 non_fatal (_("cannot read section headers"));
923 return;
924 }
925
926 for (i = 0; i < data->nscns; i++)
927 {
928 struct xcoff32_section *sect = &data->sects[i];
929 unsigned int nrel = sect->nreloc;
930 unsigned int j;
931
932 if (nrel == 0)
933 continue;
934 printf (_("Relocations for %s (%u)\n"), sect->name, nrel);
935 if (bfd_seek (abfd, sect->relptr, SEEK_SET) != 0)
936 {
937 non_fatal (_("cannot read relocations"));
938 continue;
939 }
21eb9156
TG
940 /* Do not translate: fields name. */
941 printf ("vaddr sgn mod sz type symndx symbol\n");
6abcee90
TG
942 for (j = 0; j < nrel; j++)
943 {
944 struct external_reloc rel;
945 unsigned char rsize;
946 unsigned int symndx;
947
948 if (bfd_bread (&rel, sizeof (rel), abfd) != sizeof (rel))
949 {
950 non_fatal (_("cannot read relocation entry"));
951 return;
952 }
953 rsize = bfd_h_get_8 (abfd, rel.r_size);
21eb9156 954 printf ("%08x %c %c %-2u ",
6abcee90
TG
955 (unsigned int)bfd_h_get_32 (abfd, rel.r_vaddr),
956 rsize & 0x80 ? 'S' : 'U',
957 rsize & 0x40 ? 'm' : ' ',
958 (rsize & 0x3f) + 1);
959 dump_value (rtype_xlat, bfd_h_get_8 (abfd, rel.r_type), 6);
960 symndx = bfd_h_get_32 (abfd, rel.r_symndx);
961 printf ("%-6u ", symndx);
962 xcoff32_print_symbol (data, symndx);
963 putchar ('\n');
964 }
965 putchar ('\n');
966 }
967}
968
969/* Dump xcoff line number entries. */
970
971static void
972dump_xcoff32_lineno (bfd *abfd, struct xcoff_dump *data)
973{
974 unsigned int i;
975
976 if (data->sects == NULL)
977 {
978 non_fatal (_("cannot read section headers"));
979 return;
980 }
981
982 for (i = 0; i < data->nscns; i++)
983 {
984 struct xcoff32_section *sect = &data->sects[i];
985 unsigned int nlnno = sect->nlnno;
986 unsigned int j;
987
988 if (nlnno == 0)
989 continue;
990 printf (_("Line numbers for %s (%u)\n"), sect->name, nlnno);
991 if (bfd_seek (abfd, sect->lnnoptr, SEEK_SET) != 0)
992 {
993 non_fatal (_("cannot read line numbers"));
994 continue;
995 }
21eb9156 996 /* Line number, symbol index and physical address. */
6abcee90
TG
997 printf (_("lineno symndx/paddr\n"));
998 for (j = 0; j < nlnno; j++)
999 {
1000 struct external_lineno ln;
1001 unsigned int no;
1002
1003 if (bfd_bread (&ln, sizeof (ln), abfd) != sizeof (ln))
1004 {
1005 non_fatal (_("cannot read line number entry"));
1006 return;
1007 }
1008 no = bfd_h_get_16 (abfd, ln.l_lnno);
21eb9156 1009 printf (" %-6u ", no);
6abcee90
TG
1010 if (no == 0)
1011 {
1012 unsigned int symndx = bfd_h_get_32 (abfd, ln.l_addr.l_symndx);
1013 xcoff32_print_symbol (data, symndx);
1014 }
1015 else
1016 printf ("0x%08x",
1017 (unsigned int)bfd_h_get_32 (abfd, ln.l_addr.l_paddr));
1018 putchar ('\n');
1019 }
1020 }
1021}
1022
1023/* Dump xcoff loader section. */
1024
1025static void
1026dump_xcoff32_loader (bfd *abfd)
1027{
1028 asection *loader;
1029 bfd_size_type size = 0;
1030 struct external_ldhdr *lhdr;
1031 struct external_ldsym *ldsym;
1032 struct external_ldrel *ldrel;
1033 bfd_byte *ldr_data;
1034 unsigned int version;
1035 unsigned int ndsyms;
1036 unsigned int ndrel;
1037 unsigned int stlen;
1038 unsigned int stoff;
1039 unsigned int impoff;
1040 unsigned int nimpid;
1041 unsigned int i;
1042 const char *p;
1043
1044 loader = bfd_get_section_by_name (abfd, ".loader");
1045
1046 if (loader == NULL)
1047 {
1048 printf (_("no .loader section in file\n"));
1049 return;
1050 }
1051 size = bfd_get_section_size (loader);
1052 if (size < sizeof (*lhdr))
1053 {
1054 printf (_("section .loader is too short\n"));
1055 return;
1056 }
1057
1058 ldr_data = (bfd_byte *) xmalloc (size);
1059 bfd_get_section_contents (abfd, loader, ldr_data, 0, size);
1060 lhdr = (struct external_ldhdr *)ldr_data;
1061 printf (_("Loader header:\n"));
1062 version = bfd_h_get_32 (abfd, lhdr->l_version);
1063 printf (_(" version: %u\n"), version);
1064 if (version != 1)
1065 {
1066 printf (_(" Unhandled version\n"));
1067 free (ldr_data);
1068 return;
1069 }
1070 ndsyms = bfd_h_get_32 (abfd, lhdr->l_nsyms);
1071 printf (_(" nbr symbols: %u\n"), ndsyms);
1072 ndrel = bfd_h_get_32 (abfd, lhdr->l_nreloc);
1073 printf (_(" nbr relocs: %u\n"), ndrel);
21eb9156 1074 /* Import string table length. */
6abcee90
TG
1075 printf (_(" import strtab len: %u\n"),
1076 (unsigned) bfd_h_get_32 (abfd, lhdr->l_istlen));
1077 nimpid = bfd_h_get_32 (abfd, lhdr->l_nimpid);
1078 printf (_(" nbr import files: %u\n"), nimpid);
1079 impoff = bfd_h_get_32 (abfd, lhdr->l_impoff);
1080 printf (_(" import file off: %u\n"), impoff);
1081 stlen = bfd_h_get_32 (abfd, lhdr->l_stlen);
1082 printf (_(" string table len: %u\n"), stlen);
1083 stoff = bfd_h_get_32 (abfd, lhdr->l_stoff);
1084 printf (_(" string table off: %u\n"), stoff);
1085
1086 ldsym = (struct external_ldsym *)(ldr_data + sizeof (*lhdr));
1087 printf (_("Dynamic symbols:\n"));
21eb9156
TG
1088 /* Do not translate: field names. */
1089 printf (" # value sc IFEW ty class file pa name\n");
6abcee90
TG
1090 for (i = 0; i < ndsyms; i++, ldsym++)
1091 {
1092 unsigned char smtype;
1093
1094 printf (_(" %4u %08x %3u "), i,
1095 (unsigned)bfd_h_get_32 (abfd, ldsym->l_value),
1096 (unsigned)bfd_h_get_16 (abfd, ldsym->l_scnum));
1097 smtype = bfd_h_get_8 (abfd, ldsym->l_smtype);
1098 putchar (smtype & 0x40 ? 'I' : ' ');
1099 putchar (smtype & 0x20 ? 'F' : ' ');
1100 putchar (smtype & 0x10 ? 'E' : ' ');
1101 putchar (smtype & 0x08 ? 'W' : ' ');
1102 putchar (' ');
1103 dump_value (smtyp_xlat, SMTYP_SMTYP (smtype), 2);
1104 putchar (' ');
1105 dump_value
1106 (smclas_xlat, (unsigned)bfd_h_get_8 (abfd, ldsym->l_smclas), 6);
1107 printf (_(" %3u %3u "),
1108 (unsigned)bfd_h_get_32 (abfd, ldsym->l_ifile),
1109 (unsigned)bfd_h_get_32 (abfd, ldsym->l_parm));
1110 if (ldsym->_l._l_name[0] != 0)
1111 printf ("%-.8s", ldsym->_l._l_name);
1112 else
1113 {
1114 unsigned int off = bfd_h_get_32 (abfd, ldsym->_l._l_l._l_offset);
1115 if (off > stlen)
1116 printf (_("(bad offset: %u)"), off);
1117 else
1118 printf ("%s", ldr_data + stoff + off);
1119 }
1120 putchar ('\n');
1121 }
1122
1123 printf (_("Dynamic relocs:\n"));
21eb9156
TG
1124 /* Do not translate fields name. */
1125 printf (" vaddr sec sz typ sym\n");
6abcee90
TG
1126 ldrel = (struct external_ldrel *)(ldr_data + sizeof (*lhdr)
1127 + ndsyms * sizeof (*ldsym));
1128 for (i = 0; i < ndrel; i++, ldrel++)
1129 {
1130 unsigned int rsize;
1131 unsigned int rtype;
1132 unsigned int symndx;
1133
1134 rsize = bfd_h_get_8 (abfd, ldrel->l_rtype + 0);
1135 rtype = bfd_h_get_8 (abfd, ldrel->l_rtype + 1);
1136
21eb9156 1137 printf (" %08x %3u %c%c %2u ",
6abcee90
TG
1138 (unsigned)bfd_h_get_32 (abfd, ldrel->l_vaddr),
1139 (unsigned)bfd_h_get_16 (abfd, ldrel->l_rsecnm),
1140 rsize & 0x80 ? 'S' : 'U',
1141 rsize & 0x40 ? 'm' : ' ',
1142 (rsize & 0x3f) + 1);
1143 dump_value (rtype_xlat, rtype, 6);
1144 symndx = bfd_h_get_32 (abfd, ldrel->l_symndx);
1145 switch (symndx)
1146 {
1147 case 0:
21eb9156 1148 printf (".text");
6abcee90
TG
1149 break;
1150 case 1:
21eb9156 1151 printf (".data");
6abcee90
TG
1152 break;
1153 case 2:
21eb9156 1154 printf (".bss");
6abcee90
TG
1155 break;
1156 default:
21eb9156 1157 printf ("%u", symndx - 3);
6abcee90
TG
1158 break;
1159 }
1160 putchar ('\n');
1161 }
1162
1163 printf (_("Import files:\n"));
1164 p = (char *)ldr_data + impoff;
1165 for (i = 0; i < nimpid; i++)
1166 {
1167 int n1, n2, n3;
1168
1169 n1 = strlen (p);
1170 n2 = strlen (p + n1 + 1);
1171 n3 = strlen (p + n1 + 1 + n2+ 1);
1172 printf (" %2u: %s,%s,%s\n", i,
1173 p, p + n1 + 1, p + n1 + n2 + 2);
1174 p += n1 + n2 + n3 + 3;
1175 }
1176
1177 free (ldr_data);
1178}
1179
1180/* Dump xcoff exception section. */
1181
1182static void
1183dump_xcoff32_except (bfd *abfd, struct xcoff_dump *data)
1184{
1185 asection *sec;
1186 bfd_size_type size = 0;
1187 bfd_byte *excp_data;
1188 struct external_exceptab *exceptab;
1189 unsigned int i;
1190
1191 sec = bfd_get_section_by_name (abfd, ".except");
1192
1193 if (sec == NULL)
1194 {
1195 printf (_("no .except section in file\n"));
1196 return;
1197 }
1198 size = bfd_get_section_size (sec);
1199 excp_data = (bfd_byte *) xmalloc (size);
1200 bfd_get_section_contents (abfd, sec, excp_data, 0, size);
1201 exceptab = (struct external_exceptab *)excp_data;
1202
1203 printf (_("Exception table:\n"));
21eb9156
TG
1204 /* Do not translate fields name. */
1205 printf ("lang reason sym/addr\n");
6abcee90
TG
1206 for (i = 0; i * sizeof (*exceptab) < size; i++, exceptab++)
1207 {
1208 unsigned int reason;
1209 unsigned int addr;
1210
1211 addr = bfd_get_32 (abfd, exceptab->e_addr.e_paddr);
1212 reason = bfd_get_8 (abfd, exceptab->e_reason);
21eb9156 1213 printf (" %02x %02x ",
6abcee90
TG
1214 (unsigned) bfd_get_8 (abfd, exceptab->e_lang), reason);
1215 if (reason == 0)
1216 xcoff32_print_symbol (data, addr);
1217 else
21eb9156 1218 printf ("@%08x", addr);
6abcee90
TG
1219 putchar ('\n');
1220 }
1221 free (excp_data);
1222}
1223
1224/* Dump xcoff type-check section. */
1225
1226static void
1227dump_xcoff32_typchk (bfd *abfd)
1228{
1229 asection *sec;
1230 bfd_size_type size = 0;
1231 bfd_byte *data;
1232 unsigned int i;
1233
1234 sec = bfd_get_section_by_name (abfd, ".typchk");
1235
1236 if (sec == NULL)
1237 {
1238 printf (_("no .typchk section in file\n"));
1239 return;
1240 }
1241 size = bfd_get_section_size (sec);
1242 data = (bfd_byte *) xmalloc (size);
1243 bfd_get_section_contents (abfd, sec, data, 0, size);
1244
1245 printf (_("Type-check section:\n"));
21eb9156
TG
1246 /* Do not translate field names. */
1247 printf ("offset len lang-id general-hash language-hash\n");
6abcee90
TG
1248 for (i = 0; i < size;)
1249 {
1250 unsigned int len;
1251
1252 len = bfd_get_16 (abfd, data + i);
1253 printf ("%08x: %-4u ", i, len);
1254 i += 2;
1255
1256 if (len == 10)
1257 {
1258 /* Expected format. */
1259 printf ("%04x %08x %08x\n",
1260 (unsigned) bfd_get_16 (abfd, data + i),
1261 (unsigned) bfd_get_32 (abfd, data + i + 2),
1262 (unsigned) bfd_get_32 (abfd, data + i + 2 + 4));
1263 }
1264 else
1265 {
1266 unsigned int j;
1267
1268 for (j = 0; j < len; j++)
1269 {
1270 if (j % 16 == 0)
1271 printf ("\n ");
1272 printf (" %02x", (unsigned char)data[i + j]);
1273 }
1274 putchar ('\n');
1275 }
1276 i += len;
1277 }
1278 free (data);
1279}
1280
1281/* Dump xcoff traceback tags section. */
1282
1283static void
1284dump_xcoff32_tbtags (bfd *abfd,
1285 const char *text, bfd_size_type text_size,
1286 unsigned int text_start, unsigned int func_start)
1287{
1288 unsigned int i;
1289
1290 if (func_start - text_start > text_size)
1291 {
1292 printf (_(" address beyond section size\n"));
1293 return;
1294 }
1295 for (i = func_start - text_start; i < text_size; i+= 4)
1296 if (bfd_get_32 (abfd, text + i) == 0)
1297 {
1298 unsigned int tb1;
1299 unsigned int tb2;
1300 unsigned int off;
1301
1302 printf (_(" tags at %08x\n"), i + 4);
1303 if (i + 8 >= text_size)
1304 goto truncated;
1305
1306 tb1 = bfd_get_32 (abfd, text + i + 4);
1307 tb2 = bfd_get_32 (abfd, text + i + 8);
1308 off = i + 12;
21eb9156 1309 printf (" version: %u, lang: %u, global_link: %u, is_eprol: %u, has_tboff: %u, int_proc: %u\n",
6abcee90
TG
1310 (tb1 >> 24) & 0xff,
1311 (tb1 >> 16) & 0xff,
1312 (tb1 >> 15) & 1,
1313 (tb1 >> 14) & 1,
1314 (tb1 >> 13) & 1,
1315 (tb1 >> 12) & 1);
21eb9156 1316 printf (" has_ctl: %u, tocless: %u, fp_pres: %u, log_abort: %u, int_hndl: %u\n",
6abcee90
TG
1317 (tb1 >> 11) & 1,
1318 (tb1 >> 10) & 1,
1319 (tb1 >> 9) & 1,
1320 (tb1 >> 8) & 1,
1321 (tb1 >> 7) & 1);
21eb9156 1322 printf (" name_pres: %u, uses_alloca: %u, cl_dis_inv: %u, saves_cr: %u, saves_lr: %u\n",
6abcee90
TG
1323 (tb1 >> 6) & 1,
1324 (tb1 >> 5) & 1,
1325 (tb1 >> 2) & 7,
1326 (tb1 >> 1) & 1,
1327 (tb1 >> 0) & 1);
21eb9156 1328 printf (" stores_bc: %u, fixup: %u, fpr_saved: %-2u, spare3: %u, gpr_saved: %-2u\n",
6abcee90
TG
1329 (tb2 >> 31) & 1,
1330 (tb2 >> 30) & 1,
1331 (tb2 >> 24) & 63,
1332 (tb2 >> 22) & 3,
1333 (tb2 >> 16) & 63);
21eb9156 1334 printf (" fixparms: %-3u floatparms: %-3u parm_on_stk: %u\n",
6abcee90
TG
1335 (tb2 >> 8) & 0xff,
1336 (tb2 >> 1) & 0x7f,
1337 (tb2 >> 0) & 1);
1338
1339 if (((tb2 >> 1) & 0x7fff) != 0)
1340 {
1341 unsigned int parminfo;
1342
1343 if (off >= text_size)
1344 goto truncated;
1345 parminfo = bfd_get_32 (abfd, text + off);
1346 off += 4;
21eb9156 1347 printf (" parminfo: 0x%08x\n", parminfo);
6abcee90
TG
1348 }
1349
1350 if ((tb1 >> 13) & 1)
1351 {
1352 unsigned int tboff;
1353
1354 if (off >= text_size)
1355 goto truncated;
1356 tboff = bfd_get_32 (abfd, text + off);
1357 off += 4;
21eb9156 1358 printf (" tb_offset: 0x%08x (start=0x%08x)\n",
6abcee90
TG
1359 tboff, text_start + i - tboff);
1360 }
1361 if ((tb1 >> 7) & 1)
1362 {
1363 unsigned int hand_mask;
1364
1365 if (off >= text_size)
1366 goto truncated;
1367 hand_mask = bfd_get_32 (abfd, text + off);
1368 off += 4;
21eb9156 1369 printf (" hand_mask_offset: 0x%08x\n", hand_mask);
6abcee90
TG
1370 }
1371 if ((tb1 >> 11) & 1)
1372 {
1373 unsigned int ctl_info;
1374 unsigned int j;
1375
1376 if (off >= text_size)
1377 goto truncated;
1378 ctl_info = bfd_get_32 (abfd, text + off);
1379 off += 4;
1380 printf (_(" number of CTL anchors: %u\n"), ctl_info);
1381 for (j = 0; j < ctl_info; j++)
1382 {
1383 if (off >= text_size)
1384 goto truncated;
21eb9156
TG
1385 printf (" CTL[%u]: %08x\n",
1386 j, (unsigned)bfd_get_32 (abfd, text + off));
6abcee90
TG
1387 off += 4;
1388 }
1389 }
1390 if ((tb1 >> 6) & 1)
1391 {
1392 unsigned int name_len;
1393 unsigned int j;
1394
1395 if (off >= text_size)
1396 goto truncated;
1397 name_len = bfd_get_16 (abfd, text + off);
1398 off += 2;
1399 printf (_(" Name (len: %u): "), name_len);
1400 if (off + name_len >= text_size)
1401 {
1402 printf (_("[truncated]\n"));
1403 goto truncated;
1404 }
1405 for (j = 0; j < name_len; j++)
1406 if (ISPRINT (text[off + j]))
1407 putchar (text[off + j]);
1408 else
1409 printf ("[%02x]", (unsigned char)text[off + j]);
1410 putchar ('\n');
1411 off += name_len;
1412 }
1413 if ((tb1 >> 5) & 1)
1414 {
1415 if (off >= text_size)
1416 goto truncated;
21eb9156 1417 printf (" alloca reg: %u\n",
6abcee90
TG
1418 (unsigned) bfd_get_8 (abfd, text + off));
1419 off++;
1420 }
1421 printf (_(" (end of tags at %08x)\n"), text_start + off);
1422 return;
1423 }
1424 printf (_(" no tags found\n"));
1425 return;
1426
1427 truncated:
1428 printf (_(" Truncated .text section\n"));
1429 return;
1430}
1431
1432static void
1433dump_xcoff32_traceback (bfd *abfd, struct xcoff_dump *data)
1434{
1435 unsigned int i;
1436 unsigned int scnum_text = -1;
1437 unsigned int text_vma;
1438 asection *text_sec;
1439 bfd_size_type text_size;
1440 char *text;
1441
1442 if (data->syms == NULL || data->sects == NULL)
1443 return;
1444
1445 /* Read text section. */
1446 text_sec = bfd_get_section_by_name (abfd, ".text");
1447 if (text_sec == NULL)
1448 return;
1449 text_vma = bfd_get_section_vma (abfd, text_sec);
1450
1451 text_size = bfd_get_section_size (text_sec);
1452 text = (char *) xmalloc (text_size);
1453 bfd_get_section_contents (abfd, text_sec, text, 0, text_size);
1454
1455 for (i = 0; i < data->nscns; i++)
1456 if (data->sects[i].flags == STYP_TEXT)
1457 {
1458 scnum_text = i + 1;
1459 break;
1460 }
1461 if (scnum_text == (unsigned int)-1)
1462 return;
1463
1464 for (i = 0; i < data->nsyms; i++)
1465 {
1466 union xcoff32_symbol *s = &data->syms[i];
1467
1468 switch (s->sym.sclass)
1469 {
1470 case C_EXT:
1471 case C_HIDEXT:
1472 case C_WEAKEXT:
1473 if (s->sym.scnum == scnum_text
1474 && s->sym.numaux > 0)
1475 {
1476 union external_auxent *aux = &s[s->sym.numaux].aux;
1477
1478 unsigned int smtyp;
1479 unsigned int smclas;
1480
1481 smtyp = bfd_h_get_8 (abfd, aux->x_csect.x_smtyp);
1482 smclas = bfd_h_get_8 (abfd, aux->x_csect.x_smclas);
1483 if (SMTYP_SMTYP (smtyp) == XTY_LD
1484 && (smclas == XMC_PR
1485 || smclas == XMC_GL
1486 || smclas == XMC_XO))
1487 {
1488 printf ("%08x: ", s->sym.val);
1489 xcoff32_print_symbol (data, i);
1490 putchar ('\n');
1491 dump_xcoff32_tbtags (abfd, text, text_size,
1492 text_vma, s->sym.val);
1493 }
1494 }
1495 break;
1496 default:
1497 break;
1498 }
1499 i += s->sym.numaux;
1500 }
1501 free (text);
1502}
1503
1504/* Dump the TOC symbols. */
1505
1506static void
1507dump_xcoff32_toc (bfd *abfd, struct xcoff_dump *data)
1508{
1509 unsigned int i;
1510 unsigned int nbr_ent;
1511 unsigned int size;
1512
1513 printf (_("TOC:\n"));
1514
1515 if (data->syms == NULL)
1516 return;
1517
1518 nbr_ent = 0;
1519 size = 0;
1520
1521 for (i = 0; i < data->nsyms; i++)
1522 {
1523 union xcoff32_symbol *s = &data->syms[i];
1524
1525 switch (s->sym.sclass)
1526 {
1527 case C_EXT:
1528 case C_HIDEXT:
1529 case C_WEAKEXT:
1530 if (s->sym.numaux > 0)
1531 {
1532 union external_auxent *aux = &s[s->sym.numaux].aux;
1533 unsigned int smclas;
1534 unsigned int ent_sz;
1535
1536 smclas = bfd_h_get_8 (abfd, aux->x_csect.x_smclas);
1537 if (smclas == XMC_TC
1538 || smclas == XMC_TD
1539 || smclas == XMC_TC0)
1540 {
1541 ent_sz = bfd_h_get_32 (abfd, aux->x_scn.x_scnlen);
1542 printf ("%08x %08x ",
1543 s->sym.val, ent_sz);
1544 xcoff32_print_symbol (data, i);
1545 putchar ('\n');
1546 nbr_ent++;
1547 size += ent_sz;
1548 }
1549 }
1550 break;
1551 default:
1552 break;
1553 }
1554 i += s->sym.numaux;
1555 }
1556 printf (_("Nbr entries: %-8u Size: %08x (%u)\n"),
1557 nbr_ent, size, size);
1558}
1559
1560/* Handle an rs6000 xcoff file. */
1561
1562static void
1563dump_xcoff32 (bfd *abfd, struct external_filehdr *fhdr)
1564{
1565 struct xcoff_dump data;
1566
1567 data.nscns = bfd_h_get_16 (abfd, fhdr->f_nscns);
1568 data.symptr = bfd_h_get_32 (abfd, fhdr->f_symptr);
1569 data.nsyms = bfd_h_get_32 (abfd, fhdr->f_nsyms);
1570 data.opthdr = bfd_h_get_16 (abfd, fhdr->f_opthdr);
1571 data.sects = NULL;
1572 data.syms = NULL;
1573 data.strings = NULL;
1574 data.strings_size = 0;
1575
1576 if (options[OPT_FILE_HEADER].selected)
1577 dump_xcoff32_file_header (abfd, fhdr, &data);
1578
1579 if (options[OPT_AOUT].selected)
1580 dump_xcoff32_aout_header (abfd, &data);
1581
1582 if (options[OPT_SYMS].selected
1583 || options[OPT_RELOCS].selected
1584 || options[OPT_LINENO].selected
1585 || options[OPT_TRACEBACK].selected)
1586 xcoff32_read_sections (abfd, &data);
1587
1588 if (options[OPT_SECTIONS].selected)
1589 dump_xcoff32_sections_header (abfd, &data);
1590
1591 if (options[OPT_SYMS].selected
1592 || options[OPT_RELOCS].selected
1593 || options[OPT_LINENO].selected
1594 || options[OPT_EXCEPT].selected
1595 || options[OPT_TRACEBACK].selected
1596 || options[OPT_TOC].selected)
1597 xcoff32_read_symbols (abfd, &data);
1598
1599 if (options[OPT_SYMS].selected)
1600 dump_xcoff32_symbols (abfd, &data);
1601
1602 if (options[OPT_RELOCS].selected)
1603 dump_xcoff32_relocs (abfd, &data);
1604
1605 if (options[OPT_LINENO].selected)
1606 dump_xcoff32_lineno (abfd, &data);
1607
1608 if (options[OPT_LOADER].selected)
1609 dump_xcoff32_loader (abfd);
1610
1611 if (options[OPT_EXCEPT].selected)
1612 dump_xcoff32_except (abfd, &data);
1613
1614 if (options[OPT_TYPCHK].selected)
1615 dump_xcoff32_typchk (abfd);
1616
1617 if (options[OPT_TRACEBACK].selected)
1618 dump_xcoff32_traceback (abfd, &data);
1619
1620 if (options[OPT_TOC].selected)
1621 dump_xcoff32_toc (abfd, &data);
1622
1623 free (data.sects);
1624 free (data.strings);
1625 free (data.syms);
1626}
1627
1628/* Dump ABFD (according to the options[] array). */
1629
1630static void
1631xcoff_dump (bfd *abfd)
1632{
1633 struct external_filehdr fhdr;
1634 unsigned short magic;
1635
1636 /* Read file header. */
1637 if (bfd_seek (abfd, 0, SEEK_SET) != 0
1638 || bfd_bread (&fhdr, sizeof (fhdr), abfd) != sizeof (fhdr))
1639 {
1640 non_fatal (_("cannot read header"));
1641 return;
1642 }
1643
1644 /* Decoding. We don't use the bfd/coff function to get all the fields. */
1645 magic = bfd_h_get_16 (abfd, fhdr.f_magic);
1646 if (options[OPT_FILE_HEADER].selected)
1647 {
1648 printf (_("File header:\n"));
1649 printf (_(" magic: 0x%04x (0%04o) "), magic, magic);
1650 switch (magic)
1651 {
1652 case U802WRMAGIC:
1653 printf (_("(WRMAGIC: writable text segments)"));
1654 break;
1655 case U802ROMAGIC:
1656 printf (_("(ROMAGIC: readonly sharablee text segments)"));
1657 break;
1658 case U802TOCMAGIC:
1659 printf (_("(TOCMAGIC: readonly text segments and TOC)"));
1660 break;
1661 default:
1662 printf (_("unknown magic"));
1663 }
1664 putchar ('\n');
1665 }
1666 if (magic == U802ROMAGIC || magic == U802WRMAGIC || magic == U802TOCMAGIC)
1667 dump_xcoff32 (abfd, &fhdr);
1668 else
1669 printf (_(" Unhandled magic\n"));
1670}
1671
1672/* Vector for xcoff. */
1673
1674const struct objdump_private_desc objdump_private_desc_xcoff =
1675 {
1676 xcoff_help,
1677 xcoff_filter,
1678 xcoff_dump,
1679 options
1680 };
This page took 0.125501 seconds and 4 git commands to generate.