Merge branch 'master' into merge-job
[deliverable/binutils-gdb.git] / binutils / od-xcoff.c
CommitLineData
6abcee90 1/* od-xcoff.c -- dump information about an xcoff object file.
82704155 2 Copyright (C) 2011-2019 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
868d1840 52#define OPT_LDINFO 11
6abcee90
TG
53
54/* List of actions. */
55static struct objdump_private_option options[] =
56 {
57 { "header", 0 },
58 { "aout", 0 },
59 { "sections", 0 },
60 { "syms", 0 },
61 { "relocs", 0 },
62 { "lineno", 0 },
63 { "loader", 0 },
64 { "except", 0 },
65 { "typchk", 0 },
66 { "traceback", 0 },
67 { "toc", 0 },
868d1840 68 { "ldinfo", 0 },
6abcee90
TG
69 { NULL, 0 }
70 };
71
72/* Display help. */
73
74static void
75xcoff_help (FILE *stream)
76{
77 fprintf (stream, _("\
78For XCOFF files:\n\
79 header Display the file header\n\
80 aout Display the auxiliary header\n\
81 sections Display the section headers\n\
82 syms Display the symbols table\n\
83 relocs Display the relocation entries\n\
84 lineno Display the line number entries\n\
85 loader Display loader section\n\
86 except Display exception table\n\
87 typchk Display type-check section\n\
88 traceback Display traceback tags\n\
89 toc Display toc symbols\n\
868d1840 90 ldinfo Display loader info in core files\n\
6abcee90
TG
91"));
92}
93
94/* Return TRUE if ABFD is handled. */
95
96static int
97xcoff_filter (bfd *abfd)
98{
99 return bfd_get_flavour (abfd) == bfd_target_xcoff_flavour;
100}
101
102/* Translation entry type. The last entry must be {0, NULL}. */
103
104struct xlat_table {
105 unsigned int val;
106 const char *name;
107};
108
109/* Display the list of name (from TABLE) for FLAGS, using comma to separate
110 them. A name is displayed if FLAGS & VAL is not 0. */
111
112static void
113dump_flags (const struct xlat_table *table, unsigned int flags)
114{
115 unsigned int r = flags;
116 int first = 1;
117 const struct xlat_table *t;
118
119 for (t = table; t->name; t++)
120 if ((flags & t->val) != 0)
121 {
122 r &= ~t->val;
123
124 if (first)
125 first = 0;
126 else
127 putchar (',');
128 fputs (t->name, stdout);
129 }
130
131 /* Not decoded flags. */
132 if (r != 0)
133 {
134 if (!first)
135 putchar (',');
136 printf ("0x%x", r);
137 }
138}
139
140/* Display the name corresponding to VAL from TABLE, using at most
141 MAXLEN char (possibly passed with spaces). */
142
143static void
144dump_value (const struct xlat_table *table, unsigned int val, int maxlen)
145{
146 const struct xlat_table *t;
147
148 for (t = table; t->name; t++)
149 if (t->val == val)
150 {
151 printf ("%-*s", maxlen, t->name);
152 return;
153 }
154 printf ("(%*x)", maxlen - 2, val);
155}
156
157/* Names of f_flags. */
158static const struct xlat_table f_flag_xlat[] =
159 {
160 { F_RELFLG, "no-rel" },
161 { F_EXEC, "exec" },
162 { F_LNNO, "lineno" },
163 { F_LSYMS, "lsyms" },
164
165 { F_FDPR_PROF, "fdpr-prof" },
166 { F_FDPR_OPTI, "fdpr-opti" },
167 { F_DSA, "dsa" },
168
169 { F_VARPG, "varprg" },
170
171 { F_DYNLOAD, "dynload" },
172 { F_SHROBJ, "shrobj" },
173 { F_NONEXEC, "nonexec" },
174
175 { 0, NULL }
176 };
177
178/* Names of s_flags. */
179static const struct xlat_table s_flag_xlat[] =
180 {
181 { STYP_PAD, "pad" },
182 { STYP_DWARF, "dwarf" },
183 { STYP_TEXT, "text" },
184 { STYP_DATA, "data" },
185 { STYP_BSS, "bss" },
186
187 { STYP_EXCEPT, "except" },
188 { STYP_INFO, "info" },
189 { STYP_TDATA, "tdata" },
190 { STYP_TBSS, "tbss" },
191
192 { STYP_LOADER, "loader" },
193 { STYP_DEBUG, "debug" },
194 { STYP_TYPCHK, "typchk" },
195 { STYP_OVRFLO, "ovrflo" },
196 { 0, NULL }
197 };
198
199/* Names of storage class. */
200static const struct xlat_table sc_xlat[] =
201 {
202#define SC_ENTRY(X) { C_##X, #X }
203 SC_ENTRY(NULL),
204 SC_ENTRY(AUTO),
205 SC_ENTRY(EXT),
206 SC_ENTRY(STAT),
207 SC_ENTRY(REG),
208 SC_ENTRY(EXTDEF),
209 SC_ENTRY(LABEL),
210 SC_ENTRY(ULABEL),
211 SC_ENTRY(MOS),
212 SC_ENTRY(ARG),
213 /* SC_ENTRY(STRARG), */
214 SC_ENTRY(MOU),
215 SC_ENTRY(UNTAG),
216 SC_ENTRY(TPDEF),
217 SC_ENTRY(USTATIC),
218 SC_ENTRY(ENTAG),
219 SC_ENTRY(MOE),
220 SC_ENTRY(REGPARM),
221 SC_ENTRY(FIELD),
222 SC_ENTRY(BLOCK),
223 SC_ENTRY(FCN),
224 SC_ENTRY(EOS),
225 SC_ENTRY(FILE),
226 SC_ENTRY(LINE),
227 SC_ENTRY(ALIAS),
228 SC_ENTRY(HIDDEN),
229 SC_ENTRY(HIDEXT),
230 SC_ENTRY(BINCL),
231 SC_ENTRY(EINCL),
232 SC_ENTRY(INFO),
233 SC_ENTRY(WEAKEXT),
234 SC_ENTRY(DWARF),
235
236 /* Stabs. */
237 SC_ENTRY (GSYM),
238 SC_ENTRY (LSYM),
239 SC_ENTRY (PSYM),
240 SC_ENTRY (RSYM),
241 SC_ENTRY (RPSYM),
242 SC_ENTRY (STSYM),
243 SC_ENTRY (TCSYM),
244 SC_ENTRY (BCOMM),
245 SC_ENTRY (ECOML),
246 SC_ENTRY (ECOMM),
247 SC_ENTRY (DECL),
248 SC_ENTRY (ENTRY),
249 SC_ENTRY (FUN),
250 SC_ENTRY (BSTAT),
251 SC_ENTRY (ESTAT),
252
253 { 0, NULL }
254#undef SC_ENTRY
255 };
256
257/* Names for symbol type. */
258static const struct xlat_table smtyp_xlat[] =
259 {
260 { XTY_ER, "ER" },
261 { XTY_SD, "SD" },
262 { XTY_LD, "LD" },
263 { XTY_CM, "CM" },
264 { XTY_EM, "EM" },
265 { XTY_US, "US" },
266 { 0, NULL }
267 };
268
269/* Names for storage-mapping class. */
270static const struct xlat_table smclas_xlat[] =
271 {
272#define SMCLAS_ENTRY(X) { XMC_##X, #X }
273 SMCLAS_ENTRY (PR),
274 SMCLAS_ENTRY (RO),
275 SMCLAS_ENTRY (DB),
276 SMCLAS_ENTRY (TC),
277 SMCLAS_ENTRY (UA),
278 SMCLAS_ENTRY (RW),
279 SMCLAS_ENTRY (GL),
280 SMCLAS_ENTRY (XO),
281 SMCLAS_ENTRY (SV),
282 SMCLAS_ENTRY (BS),
283 SMCLAS_ENTRY (DS),
284 SMCLAS_ENTRY (UC),
285 SMCLAS_ENTRY (TI),
286 SMCLAS_ENTRY (TB),
287 SMCLAS_ENTRY (TC0),
288 SMCLAS_ENTRY (TD),
289 SMCLAS_ENTRY (SV64),
290 SMCLAS_ENTRY (SV3264),
291 { 0, NULL }
292#undef SMCLAS_ENTRY
293 };
294
295/* Names for relocation type. */
296static const struct xlat_table rtype_xlat[] =
297 {
298#define RTYPE_ENTRY(X) { R_##X, #X }
299 RTYPE_ENTRY (POS),
300 RTYPE_ENTRY (NEG),
301 RTYPE_ENTRY (REL),
302 RTYPE_ENTRY (TOC),
303 RTYPE_ENTRY (RTB),
304 RTYPE_ENTRY (GL),
305 RTYPE_ENTRY (TCL),
306 RTYPE_ENTRY (BA),
307 RTYPE_ENTRY (BR),
308 RTYPE_ENTRY (RL),
309 RTYPE_ENTRY (RLA),
310 RTYPE_ENTRY (REF),
311 RTYPE_ENTRY (TRL),
312 RTYPE_ENTRY (TRLA),
313 RTYPE_ENTRY (RRTBI),
314 RTYPE_ENTRY (RRTBA),
315 RTYPE_ENTRY (CAI),
316 RTYPE_ENTRY (CREL),
317 RTYPE_ENTRY (RBA),
318 RTYPE_ENTRY (RBAC),
319 RTYPE_ENTRY (RBR),
320 RTYPE_ENTRY (RBRC),
321 RTYPE_ENTRY (TLS),
322 RTYPE_ENTRY (TLS_IE),
323 RTYPE_ENTRY (TLS_LD),
324 RTYPE_ENTRY (TLS_LE),
325 RTYPE_ENTRY (TLSM),
326 RTYPE_ENTRY (TLSML),
327 RTYPE_ENTRY (TOCU),
328 RTYPE_ENTRY (TOCL),
329 { 0, NULL }
330 };
331
332/* Simplified section header. */
333struct xcoff32_section
334{
335 /* NUL terminated name. */
336 char name[9];
337
338 /* Section flags. */
339 unsigned int flags;
340
341 /* Offsets in file. */
342 ufile_ptr scnptr;
343 ufile_ptr relptr;
344 ufile_ptr lnnoptr;
345
346 /* Number of relocs and line numbers. */
347 unsigned int nreloc;
348 unsigned int nlnno;
349};
350
351/* Simplified symbol. */
352
353union xcoff32_symbol
354{
355 union external_auxent aux;
356
357 struct sym
358 {
a8685210 359 /* Pointer to the NUL-terminated name. */
6abcee90
TG
360 char *name;
361
362 /* XCOFF symbol fields. */
363 unsigned int val;
364 unsigned short scnum;
365 unsigned short ntype;
366 unsigned char sclass;
367 unsigned char numaux;
368
369 /* Buffer in case the name is local. */
370 union
371 {
372 char name[9];
373 unsigned int off;
374 } raw;
375 } sym;
376};
377
378/* Important fields to dump the file. */
379
380struct xcoff_dump
381{
382 /* From file header. */
383 unsigned short nscns;
384 unsigned int symptr;
385 unsigned int nsyms;
386 unsigned short opthdr;
387
388 /* Sections. */
389 struct xcoff32_section *sects;
390
391 /* Symbols. */
392 union xcoff32_symbol *syms;
393 char *strings;
394 unsigned int strings_size;
395};
396
397/* Print a symbol (if possible). */
398
399static void
400xcoff32_print_symbol (struct xcoff_dump *data, unsigned int symndx)
401{
402 if (data->syms != NULL
403 && symndx < data->nsyms
404 && data->syms[symndx].sym.name != NULL)
405 printf ("%s", data->syms[symndx].sym.name);
406 else
407 printf ("%u", symndx);
408}
409
410/* Dump the file header. */
411
412static void
413dump_xcoff32_file_header (bfd *abfd, struct external_filehdr *fhdr,
414 struct xcoff_dump *data)
415{
416 unsigned int timdat = bfd_h_get_32 (abfd, fhdr->f_timdat);
417 unsigned short flags = bfd_h_get_16 (abfd, fhdr->f_flags);
418
419 printf (_(" nbr sections: %d\n"), data->nscns);
420 printf (_(" time and date: 0x%08x - "), timdat);
421 if (timdat == 0)
422 printf (_("not set\n"));
423 else
424 {
425 /* Not correct on all platforms, but works on unix. */
426 time_t t = timdat;
427 fputs (ctime (&t), stdout);
428 }
429 printf (_(" symbols off: 0x%08x\n"), data->symptr);
430 printf (_(" nbr symbols: %d\n"), data->nsyms);
431 printf (_(" opt hdr sz: %d\n"), data->opthdr);
432 printf (_(" flags: 0x%04x "), flags);
433 dump_flags (f_flag_xlat, flags);
434 putchar ('\n');
435}
436
437/* Dump the a.out header. */
438
439static void
440dump_xcoff32_aout_header (bfd *abfd, struct xcoff_dump *data)
441{
442 AOUTHDR auxhdr;
443 unsigned short magic;
444 unsigned int sz = data->opthdr;
445
446 printf (_("Auxiliary header:\n"));
447 if (data->opthdr == 0)
448 {
449 printf (_(" No aux header\n"));
450 return;
451 }
452 if (data->opthdr > sizeof (auxhdr))
453 {
9aff4b7a 454 printf (_("warning: optional header size too large (> %d)\n"),
6abcee90
TG
455 (int)sizeof (auxhdr));
456 sz = sizeof (auxhdr);
457 }
458 if (bfd_bread (&auxhdr, sz, abfd) != sz)
459 {
460 non_fatal (_("cannot read auxhdr"));
461 return;
462 }
463
464 magic = bfd_h_get_16 (abfd, auxhdr.magic);
a82526dd 465 /* We don't translate these strings as they are fields name. */
21eb9156
TG
466 printf (" o_mflag (magic): 0x%04x 0%04o\n", magic, magic);
467 printf (" o_vstamp: 0x%04x\n",
6abcee90 468 (unsigned short)bfd_h_get_16 (abfd, auxhdr.vstamp));
21eb9156 469 printf (" o_tsize: 0x%08x\n",
6abcee90 470 (unsigned int)bfd_h_get_32 (abfd, auxhdr.tsize));
21eb9156 471 printf (" o_dsize: 0x%08x\n",
6abcee90 472 (unsigned int)bfd_h_get_32 (abfd, auxhdr.dsize));
21eb9156 473 printf (" o_entry: 0x%08x\n",
6abcee90 474 (unsigned int)bfd_h_get_32 (abfd, auxhdr.entry));
21eb9156 475 printf (" o_text_start: 0x%08x\n",
6abcee90 476 (unsigned int)bfd_h_get_32 (abfd, auxhdr.text_start));
21eb9156 477 printf (" o_data_start: 0x%08x\n",
6abcee90
TG
478 (unsigned int)bfd_h_get_32 (abfd, auxhdr.data_start));
479 if (sz == offsetof (AOUTHDR, o_toc))
480 return;
21eb9156 481 printf (" o_toc: 0x%08x\n",
6abcee90 482 (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_toc));
21eb9156 483 printf (" o_snentry: 0x%04x\n",
6abcee90 484 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snentry));
21eb9156 485 printf (" o_sntext: 0x%04x\n",
6abcee90 486 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sntext));
21eb9156 487 printf (" o_sndata: 0x%04x\n",
6abcee90 488 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sndata));
21eb9156 489 printf (" o_sntoc: 0x%04x\n",
6abcee90 490 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_sntoc));
21eb9156 491 printf (" o_snloader: 0x%04x\n",
6abcee90 492 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snloader));
21eb9156 493 printf (" o_snbss: 0x%04x\n",
6abcee90 494 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_snbss));
21eb9156 495 printf (" o_algntext: %u\n",
6abcee90 496 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_algntext));
21eb9156 497 printf (" o_algndata: %u\n",
6abcee90 498 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_algndata));
21eb9156 499 printf (" o_modtype: 0x%04x",
6abcee90
TG
500 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_modtype));
501 if (ISPRINT (auxhdr.o_modtype[0]) && ISPRINT (auxhdr.o_modtype[1]))
502 printf (" (%c%c)", auxhdr.o_modtype[0], auxhdr.o_modtype[1]);
503 putchar ('\n');
21eb9156 504 printf (" o_cputype: 0x%04x\n",
6abcee90 505 (unsigned int)bfd_h_get_16 (abfd, auxhdr.o_cputype));
21eb9156 506 printf (" o_maxstack: 0x%08x\n",
6abcee90 507 (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_maxstack));
21eb9156 508 printf (" o_maxdata: 0x%08x\n",
6abcee90
TG
509 (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_maxdata));
510#if 0
21eb9156 511 printf (" o_debugger: 0x%08x\n",
6abcee90
TG
512 (unsigned int)bfd_h_get_32 (abfd, auxhdr.o_debugger));
513#endif
514}
515
516/* Dump the sections header. */
517
518static void
519dump_xcoff32_sections_header (bfd *abfd, struct xcoff_dump *data)
520{
521 unsigned int i;
522 unsigned int off;
523
524 off = sizeof (struct external_filehdr) + data->opthdr;
525 printf (_("Section headers (at %u+%u=0x%08x to 0x%08x):\n"),
526 (unsigned int)sizeof (struct external_filehdr), data->opthdr, off,
527 off + (unsigned int)sizeof (struct external_scnhdr) * data->nscns);
528 if (data->nscns == 0)
529 {
530 printf (_(" No section header\n"));
531 return;
532 }
533 if (bfd_seek (abfd, off, SEEK_SET) != 0)
534 {
535 non_fatal (_("cannot read section header"));
536 return;
537 }
21eb9156
TG
538 /* We don't translate this string as it consists in fields name. */
539 printf (" # Name paddr vaddr size scnptr relptr lnnoptr nrel nlnno\n");
6abcee90
TG
540 for (i = 0; i < data->nscns; i++)
541 {
542 struct external_scnhdr scn;
543 unsigned int flags;
544
545 if (bfd_bread (&scn, sizeof (scn), abfd) != sizeof (scn))
546 {
547 non_fatal (_("cannot read section header"));
548 return;
549 }
550 flags = bfd_h_get_32 (abfd, scn.s_flags);
21eb9156 551 printf ("%2d %-8.8s %08x %08x %08x %08x %08x %08x %-5d %-5d\n",
6abcee90
TG
552 i + 1, scn.s_name,
553 (unsigned int)bfd_h_get_32 (abfd, scn.s_paddr),
554 (unsigned int)bfd_h_get_32 (abfd, scn.s_vaddr),
555 (unsigned int)bfd_h_get_32 (abfd, scn.s_size),
556 (unsigned int)bfd_h_get_32 (abfd, scn.s_scnptr),
557 (unsigned int)bfd_h_get_32 (abfd, scn.s_relptr),
558 (unsigned int)bfd_h_get_32 (abfd, scn.s_lnnoptr),
559 (unsigned int)bfd_h_get_16 (abfd, scn.s_nreloc),
560 (unsigned int)bfd_h_get_16 (abfd, scn.s_nlnno));
561 printf (_(" Flags: %08x "), flags);
562
563 if (~flags == 0)
564 {
565 /* Stripped executable ? */
566 putchar ('\n');
567 }
568 else if (flags & STYP_OVRFLO)
569 printf (_("overflow - nreloc: %u, nlnno: %u\n"),
570 (unsigned int)bfd_h_get_32 (abfd, scn.s_paddr),
571 (unsigned int)bfd_h_get_32 (abfd, scn.s_vaddr));
572 else
573 {
574 dump_flags (s_flag_xlat, flags);
575 putchar ('\n');
576 }
577 }
578}
579
580/* Read section table. */
581
582static void
583xcoff32_read_sections (bfd *abfd, struct xcoff_dump *data)
584{
585 int i;
586
587 if (bfd_seek (abfd, sizeof (struct external_filehdr) + data->opthdr,
588 SEEK_SET) != 0)
589 {
590 non_fatal (_("cannot read section headers"));
591 return;
592 }
593
594 data->sects = xmalloc (data->nscns * sizeof (struct xcoff32_section));
595 for (i = 0; i < data->nscns; i++)
596 {
597 struct external_scnhdr scn;
598 struct xcoff32_section *s = &data->sects[i];
599
600 if (bfd_bread (&scn, sizeof (scn), abfd) != sizeof (scn))
601 {
602 non_fatal (_("cannot read section header"));
603 free (data->sects);
604 data->sects = NULL;
605 return;
606 }
607 memcpy (s->name, scn.s_name, 8);
608 s->name[8] = 0;
609 s->flags = bfd_h_get_32 (abfd, scn.s_flags);
610
611 s->scnptr = bfd_h_get_32 (abfd, scn.s_scnptr);
612 s->relptr = bfd_h_get_32 (abfd, scn.s_relptr);
613 s->lnnoptr = bfd_h_get_32 (abfd, scn.s_lnnoptr);
614
615 s->nreloc = bfd_h_get_16 (abfd, scn.s_nreloc);
616 s->nlnno = bfd_h_get_16 (abfd, scn.s_nlnno);
617
618 if (s->flags == STYP_OVRFLO)
619 {
620 if (s->nreloc > 0 && s->nreloc <= data->nscns)
621 data->sects[s->nreloc - 1].nreloc =
622 bfd_h_get_32 (abfd, scn.s_paddr);
623 if (s->nlnno > 0 && s->nlnno <= data->nscns)
624 data->sects[s->nlnno - 1].nlnno =
625 bfd_h_get_32 (abfd, scn.s_vaddr);
626 }
627 }
628}
629
630/* Read symbols. */
631
632static void
633xcoff32_read_symbols (bfd *abfd, struct xcoff_dump *data)
634{
635 unsigned int i;
636 char stsz_arr[4];
637 unsigned int stptr;
638
639 if (data->nsyms == 0)
640 return;
641
642 stptr = data->symptr
643 + data->nsyms * (unsigned)sizeof (struct external_syment);
644
645 /* Read string table. */
e682d13b
TG
646 if (bfd_seek (abfd, stptr, SEEK_SET) != 0
647 || bfd_bread (&stsz_arr, sizeof (stsz_arr), abfd) != sizeof (stsz_arr))
6abcee90 648 {
e682d13b 649 non_fatal (_("cannot read strings table length"));
6abcee90
TG
650 data->strings_size = 0;
651 }
652 else
653 {
6abcee90
TG
654 data->strings_size = bfd_h_get_32 (abfd, stsz_arr);
655 if (data->strings_size > sizeof (stsz_arr))
656 {
657 unsigned int remsz = data->strings_size - sizeof (stsz_arr);
658
659 data->strings = xmalloc (data->strings_size);
660
661 memcpy (data->strings, stsz_arr, sizeof (stsz_arr));
662 if (bfd_bread (data->strings + sizeof (stsz_arr), remsz, abfd)
663 != remsz)
664 {
665 non_fatal (_("cannot read strings table"));
666 goto clean;
667 }
668 }
669 }
670
671 if (bfd_seek (abfd, data->symptr, SEEK_SET) != 0)
672 {
673 non_fatal (_("cannot read symbol table"));
674 goto clean;
675 }
676
677 data->syms = (union xcoff32_symbol *)
678 xmalloc (data->nsyms * sizeof (union xcoff32_symbol));
679
680 for (i = 0; i < data->nsyms; i++)
681 {
682 struct external_syment sym;
683 int j;
684 union xcoff32_symbol *s = &data->syms[i];
685
686 if (bfd_bread (&sym, sizeof (sym), abfd) != sizeof (sym))
687 {
688 non_fatal (_("cannot read symbol entry"));
689 goto clean;
690 }
691
692 s->sym.val = bfd_h_get_32 (abfd, sym.e_value);
693 s->sym.scnum = bfd_h_get_16 (abfd, sym.e_scnum);
694 s->sym.ntype = bfd_h_get_16 (abfd, sym.e_type);
695 s->sym.sclass = bfd_h_get_8 (abfd, sym.e_sclass);
696 s->sym.numaux = bfd_h_get_8 (abfd, sym.e_numaux);
697
698 if (sym.e.e_name[0])
699 {
700 memcpy (s->sym.raw.name, sym.e.e_name, sizeof (sym.e.e_name));
701 s->sym.raw.name[8] = 0;
702 s->sym.name = s->sym.raw.name;
703 }
704 else
705 {
706 unsigned int soff = bfd_h_get_32 (abfd, sym.e.e.e_offset);
707
708 if ((s->sym.sclass & DBXMASK) == 0 && soff < data->strings_size)
709 s->sym.name = data->strings + soff;
710 else
711 {
712 s->sym.name = NULL;
713 s->sym.raw.off = soff;
714 }
715 }
716
717 for (j = 0; j < s->sym.numaux; j++, i++)
718 {
719 if (bfd_bread (&s[j + 1].aux,
720 sizeof (union external_auxent), abfd)
721 != sizeof (union external_auxent))
722 {
723 non_fatal (_("cannot read symbol aux entry"));
724 goto clean;
725 }
726 }
727 }
728 return;
729 clean:
730 free (data->syms);
731 data->syms = NULL;
732 free (data->strings);
733 data->strings = NULL;
734}
735
736/* Dump xcoff symbols. */
737
738static void
739dump_xcoff32_symbols (bfd *abfd, struct xcoff_dump *data)
740{
741 unsigned int i;
742 asection *debugsec;
743 char *debug = NULL;
744
745 printf (_("Symbols table (strtable at 0x%08x)"),
746 data->symptr
747 + data->nsyms * (unsigned)sizeof (struct external_syment));
748 if (data->nsyms == 0 || data->syms == NULL)
749 {
750 printf (_(":\n No symbols\n"));
751 return;
752 }
753
21eb9156 754 /* Read strings table. */
6abcee90
TG
755 if (data->strings_size == 0)
756 printf (_(" (no strings):\n"));
757 else
758 printf (_(" (strings size: %08x):\n"), data->strings_size);
759
760 /* Read debug section. */
761 debugsec = bfd_get_section_by_name (abfd, ".debug");
762 if (debugsec != NULL)
763 {
764 bfd_size_type size;
765
fd361982 766 size = bfd_section_size (debugsec);
6abcee90
TG
767 debug = (char *) xmalloc (size);
768 bfd_get_section_contents (abfd, debugsec, debug, 0, size);
769 }
770
21eb9156 771 /* Translators: 'sc' is for storage class, 'off' for offset. */
6abcee90
TG
772 printf (_(" # sc value section type aux name/off\n"));
773 for (i = 0; i < data->nsyms; i++)
774 {
775 union xcoff32_symbol *s = &data->syms[i];
776 int j;
777
778 printf ("%3u ", i);
779 dump_value (sc_xlat, s->sym.sclass, 10);
780 printf (" %08x ", s->sym.val);
781 if (s->sym.scnum > 0 && s->sym.scnum <= data->nscns)
782 {
783 if (data->sects != NULL)
784 printf ("%-8s", data->sects[s->sym.scnum - 1].name);
785 else
786 printf ("%-8u", s->sym.scnum);
787 }
788 else
789 switch ((signed short)s->sym.scnum)
790 {
791 case N_DEBUG:
792 printf ("N_DEBUG ");
793 break;
794 case N_ABS:
795 printf ("N_ABS ");
796 break;
797 case N_UNDEF:
798 printf ("N_UNDEF ");
799 break;
800 default:
801 printf ("(%04x) ", s->sym.scnum);
802 }
803 printf (" %04x %3u ", s->sym.ntype, s->sym.numaux);
804 if (s->sym.name != NULL)
805 printf ("%s", s->sym.name);
806 else
807 {
808 if ((s->sym.sclass & DBXMASK) != 0 && debug != NULL)
809 printf ("%s", debug + s->sym.raw.off);
810 else
811 printf ("%08x", s->sym.raw.off);
812 }
813 putchar ('\n');
814
815 for (j = 0; j < s->sym.numaux; j++, i++)
816 {
817 union external_auxent *aux = &s[j + 1].aux;
818
819 printf (" %3u ", i + 1);
820 switch (s->sym.sclass)
821 {
822 case C_STAT:
21eb9156 823 /* Section length, number of relocs and line number. */
6abcee90
TG
824 printf (_(" scnlen: %08x nreloc: %-6u nlinno: %-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 (unsigned)bfd_h_get_16 (abfd, aux->x_scn.x_nlinno));
828 break;
829 case C_DWARF:
21eb9156 830 /* Section length and number of relocs. */
6abcee90
TG
831 printf (_(" scnlen: %08x nreloc: %-6u\n"),
832 (unsigned)bfd_h_get_32 (abfd, aux->x_scn.x_scnlen),
833 (unsigned)bfd_h_get_16 (abfd, aux->x_scn.x_nreloc));
834 break;
835 case C_EXT:
836 case C_WEAKEXT:
837 case C_HIDEXT:
838 if (j == 0 && s->sym.numaux > 1)
839 {
21eb9156
TG
840 /* Function aux entry (Do not translate). */
841 printf (" exptr: %08x fsize: %08x lnnoptr: %08x endndx: %u\n",
6abcee90
TG
842 (unsigned)bfd_h_get_32 (abfd, aux->x_sym.x_tagndx),
843 (unsigned)bfd_h_get_32
844 (abfd, aux->x_sym.x_misc.x_fsize),
845 (unsigned)bfd_h_get_32
846 (abfd, aux->x_sym.x_fcnary.x_fcn.x_lnnoptr),
847 (unsigned)bfd_h_get_32
848 (abfd, aux->x_sym.x_fcnary.x_fcn.x_endndx));
849 }
850 else if (j == 1 || (j == 0 && s->sym.numaux == 1))
851 {
852 /* csect aux entry. */
853 unsigned char smtyp;
854 unsigned int scnlen;
855
856 smtyp = bfd_h_get_8 (abfd, aux->x_csect.x_smtyp);
857 scnlen = bfd_h_get_32 (abfd, aux->x_csect.x_scnlen);
858
859 if (smtyp == XTY_LD)
21eb9156 860 printf (" scnsym: %-8u", scnlen);
6abcee90 861 else
21eb9156
TG
862 printf (" scnlen: %08x", scnlen);
863 printf (" h: parm=%08x sn=%04x al: 2**%u",
6abcee90
TG
864 (unsigned)bfd_h_get_32 (abfd, aux->x_csect.x_parmhash),
865 (unsigned)bfd_h_get_16 (abfd, aux->x_csect.x_snhash),
866 SMTYP_ALIGN (smtyp));
21eb9156 867 printf (" typ: ");
6abcee90 868 dump_value (smtyp_xlat, SMTYP_SMTYP (smtyp), 2);
21eb9156 869 printf (" cl: ");
6abcee90
TG
870 dump_value
871 (smclas_xlat,
872 (unsigned)bfd_h_get_8 (abfd, aux->x_csect.x_smclas), 6);
873 putchar ('\n');
874 }
875 else
21eb9156 876 /* Do not translate - generic field name. */
6abcee90
TG
877 printf ("aux\n");
878 break;
879 case C_FILE:
880 {
881 unsigned int off;
882
21eb9156 883 printf (" ftype: %02x ",
6abcee90
TG
884 (unsigned)bfd_h_get_8 (abfd, aux->x_file.x_ftype));
885 if (aux->x_file.x_n.x_fname[0] != 0)
21eb9156 886 printf ("fname: %.14s", aux->x_file.x_n.x_fname);
6abcee90
TG
887 else
888 {
889 off = (unsigned)bfd_h_get_32
890 (abfd, aux->x_file.x_n.x_n.x_offset);
891 if (data->strings != NULL && off < data->strings_size)
21eb9156 892 printf (" %s", data->strings + off);
6abcee90
TG
893 else
894 printf (_("offset: %08x"), off);
895 }
896 putchar ('\n');
897 }
898 break;
899 case C_BLOCK:
900 case C_FCN:
21eb9156 901 printf (" lnno: %u\n",
6abcee90
TG
902 (unsigned)bfd_h_get_16
903 (abfd, aux->x_sym.x_misc.x_lnsz.x_lnno));
904 break;
905 default:
21eb9156 906 /* Do not translate - generic field name. */
6abcee90
TG
907 printf ("aux\n");
908 break;
909 }
910 }
911
912 }
913 free (debug);
914}
915
916/* Dump xcoff relocation entries. */
917
918static void
919dump_xcoff32_relocs (bfd *abfd, struct xcoff_dump *data)
920{
921 unsigned int i;
922
923 if (data->sects == NULL)
924 {
925 non_fatal (_("cannot read section headers"));
926 return;
927 }
928
929 for (i = 0; i < data->nscns; i++)
930 {
931 struct xcoff32_section *sect = &data->sects[i];
932 unsigned int nrel = sect->nreloc;
933 unsigned int j;
934
935 if (nrel == 0)
936 continue;
937 printf (_("Relocations for %s (%u)\n"), sect->name, nrel);
938 if (bfd_seek (abfd, sect->relptr, SEEK_SET) != 0)
939 {
940 non_fatal (_("cannot read relocations"));
941 continue;
942 }
21eb9156
TG
943 /* Do not translate: fields name. */
944 printf ("vaddr sgn mod sz type symndx symbol\n");
6abcee90
TG
945 for (j = 0; j < nrel; j++)
946 {
947 struct external_reloc rel;
948 unsigned char rsize;
949 unsigned int symndx;
950
951 if (bfd_bread (&rel, sizeof (rel), abfd) != sizeof (rel))
952 {
953 non_fatal (_("cannot read relocation entry"));
954 return;
955 }
956 rsize = bfd_h_get_8 (abfd, rel.r_size);
21eb9156 957 printf ("%08x %c %c %-2u ",
6abcee90
TG
958 (unsigned int)bfd_h_get_32 (abfd, rel.r_vaddr),
959 rsize & 0x80 ? 'S' : 'U',
960 rsize & 0x40 ? 'm' : ' ',
961 (rsize & 0x3f) + 1);
962 dump_value (rtype_xlat, bfd_h_get_8 (abfd, rel.r_type), 6);
963 symndx = bfd_h_get_32 (abfd, rel.r_symndx);
964 printf ("%-6u ", symndx);
965 xcoff32_print_symbol (data, symndx);
966 putchar ('\n');
967 }
968 putchar ('\n');
969 }
970}
971
972/* Dump xcoff line number entries. */
973
974static void
975dump_xcoff32_lineno (bfd *abfd, struct xcoff_dump *data)
976{
977 unsigned int i;
978
979 if (data->sects == NULL)
980 {
981 non_fatal (_("cannot read section headers"));
982 return;
983 }
984
985 for (i = 0; i < data->nscns; i++)
986 {
987 struct xcoff32_section *sect = &data->sects[i];
988 unsigned int nlnno = sect->nlnno;
989 unsigned int j;
990
991 if (nlnno == 0)
992 continue;
993 printf (_("Line numbers for %s (%u)\n"), sect->name, nlnno);
994 if (bfd_seek (abfd, sect->lnnoptr, SEEK_SET) != 0)
995 {
996 non_fatal (_("cannot read line numbers"));
997 continue;
998 }
21eb9156 999 /* Line number, symbol index and physical address. */
6abcee90
TG
1000 printf (_("lineno symndx/paddr\n"));
1001 for (j = 0; j < nlnno; j++)
1002 {
1003 struct external_lineno ln;
1004 unsigned int no;
1005
1006 if (bfd_bread (&ln, sizeof (ln), abfd) != sizeof (ln))
1007 {
1008 non_fatal (_("cannot read line number entry"));
1009 return;
1010 }
1011 no = bfd_h_get_16 (abfd, ln.l_lnno);
21eb9156 1012 printf (" %-6u ", no);
6abcee90
TG
1013 if (no == 0)
1014 {
1015 unsigned int symndx = bfd_h_get_32 (abfd, ln.l_addr.l_symndx);
1016 xcoff32_print_symbol (data, symndx);
1017 }
1018 else
1019 printf ("0x%08x",
1020 (unsigned int)bfd_h_get_32 (abfd, ln.l_addr.l_paddr));
1021 putchar ('\n');
1022 }
1023 }
1024}
1025
1026/* Dump xcoff loader section. */
1027
1028static void
1029dump_xcoff32_loader (bfd *abfd)
1030{
1031 asection *loader;
1032 bfd_size_type size = 0;
1033 struct external_ldhdr *lhdr;
1034 struct external_ldsym *ldsym;
1035 struct external_ldrel *ldrel;
1036 bfd_byte *ldr_data;
1037 unsigned int version;
1038 unsigned int ndsyms;
1039 unsigned int ndrel;
1040 unsigned int stlen;
1041 unsigned int stoff;
1042 unsigned int impoff;
1043 unsigned int nimpid;
1044 unsigned int i;
1045 const char *p;
1046
1047 loader = bfd_get_section_by_name (abfd, ".loader");
1048
1049 if (loader == NULL)
1050 {
1051 printf (_("no .loader section in file\n"));
1052 return;
1053 }
fd361982 1054 size = bfd_section_size (loader);
6abcee90
TG
1055 if (size < sizeof (*lhdr))
1056 {
1057 printf (_("section .loader is too short\n"));
1058 return;
1059 }
1060
1061 ldr_data = (bfd_byte *) xmalloc (size);
1062 bfd_get_section_contents (abfd, loader, ldr_data, 0, size);
1063 lhdr = (struct external_ldhdr *)ldr_data;
1064 printf (_("Loader header:\n"));
1065 version = bfd_h_get_32 (abfd, lhdr->l_version);
1066 printf (_(" version: %u\n"), version);
1067 if (version != 1)
1068 {
1069 printf (_(" Unhandled version\n"));
1070 free (ldr_data);
1071 return;
1072 }
1073 ndsyms = bfd_h_get_32 (abfd, lhdr->l_nsyms);
1074 printf (_(" nbr symbols: %u\n"), ndsyms);
1075 ndrel = bfd_h_get_32 (abfd, lhdr->l_nreloc);
1076 printf (_(" nbr relocs: %u\n"), ndrel);
21eb9156 1077 /* Import string table length. */
6abcee90
TG
1078 printf (_(" import strtab len: %u\n"),
1079 (unsigned) bfd_h_get_32 (abfd, lhdr->l_istlen));
1080 nimpid = bfd_h_get_32 (abfd, lhdr->l_nimpid);
1081 printf (_(" nbr import files: %u\n"), nimpid);
1082 impoff = bfd_h_get_32 (abfd, lhdr->l_impoff);
1083 printf (_(" import file off: %u\n"), impoff);
1084 stlen = bfd_h_get_32 (abfd, lhdr->l_stlen);
1085 printf (_(" string table len: %u\n"), stlen);
1086 stoff = bfd_h_get_32 (abfd, lhdr->l_stoff);
1087 printf (_(" string table off: %u\n"), stoff);
1088
1089 ldsym = (struct external_ldsym *)(ldr_data + sizeof (*lhdr));
1090 printf (_("Dynamic symbols:\n"));
21eb9156
TG
1091 /* Do not translate: field names. */
1092 printf (" # value sc IFEW ty class file pa name\n");
6abcee90
TG
1093 for (i = 0; i < ndsyms; i++, ldsym++)
1094 {
1095 unsigned char smtype;
1096
1097 printf (_(" %4u %08x %3u "), i,
1098 (unsigned)bfd_h_get_32 (abfd, ldsym->l_value),
1099 (unsigned)bfd_h_get_16 (abfd, ldsym->l_scnum));
1100 smtype = bfd_h_get_8 (abfd, ldsym->l_smtype);
1101 putchar (smtype & 0x40 ? 'I' : ' ');
1102 putchar (smtype & 0x20 ? 'F' : ' ');
1103 putchar (smtype & 0x10 ? 'E' : ' ');
1104 putchar (smtype & 0x08 ? 'W' : ' ');
1105 putchar (' ');
1106 dump_value (smtyp_xlat, SMTYP_SMTYP (smtype), 2);
1107 putchar (' ');
1108 dump_value
1109 (smclas_xlat, (unsigned)bfd_h_get_8 (abfd, ldsym->l_smclas), 6);
1110 printf (_(" %3u %3u "),
1111 (unsigned)bfd_h_get_32 (abfd, ldsym->l_ifile),
1112 (unsigned)bfd_h_get_32 (abfd, ldsym->l_parm));
1113 if (ldsym->_l._l_name[0] != 0)
1114 printf ("%-.8s", ldsym->_l._l_name);
1115 else
1116 {
1117 unsigned int off = bfd_h_get_32 (abfd, ldsym->_l._l_l._l_offset);
1118 if (off > stlen)
1119 printf (_("(bad offset: %u)"), off);
1120 else
1121 printf ("%s", ldr_data + stoff + off);
1122 }
1123 putchar ('\n');
1124 }
1125
1126 printf (_("Dynamic relocs:\n"));
21eb9156
TG
1127 /* Do not translate fields name. */
1128 printf (" vaddr sec sz typ sym\n");
6abcee90
TG
1129 ldrel = (struct external_ldrel *)(ldr_data + sizeof (*lhdr)
1130 + ndsyms * sizeof (*ldsym));
1131 for (i = 0; i < ndrel; i++, ldrel++)
1132 {
1133 unsigned int rsize;
1134 unsigned int rtype;
1135 unsigned int symndx;
1136
1137 rsize = bfd_h_get_8 (abfd, ldrel->l_rtype + 0);
1138 rtype = bfd_h_get_8 (abfd, ldrel->l_rtype + 1);
1139
21eb9156 1140 printf (" %08x %3u %c%c %2u ",
6abcee90
TG
1141 (unsigned)bfd_h_get_32 (abfd, ldrel->l_vaddr),
1142 (unsigned)bfd_h_get_16 (abfd, ldrel->l_rsecnm),
1143 rsize & 0x80 ? 'S' : 'U',
1144 rsize & 0x40 ? 'm' : ' ',
1145 (rsize & 0x3f) + 1);
1146 dump_value (rtype_xlat, rtype, 6);
1147 symndx = bfd_h_get_32 (abfd, ldrel->l_symndx);
1148 switch (symndx)
1149 {
1150 case 0:
21eb9156 1151 printf (".text");
6abcee90
TG
1152 break;
1153 case 1:
21eb9156 1154 printf (".data");
6abcee90
TG
1155 break;
1156 case 2:
21eb9156 1157 printf (".bss");
6abcee90
TG
1158 break;
1159 default:
21eb9156 1160 printf ("%u", symndx - 3);
6abcee90
TG
1161 break;
1162 }
1163 putchar ('\n');
1164 }
1165
1166 printf (_("Import files:\n"));
1167 p = (char *)ldr_data + impoff;
1168 for (i = 0; i < nimpid; i++)
1169 {
1170 int n1, n2, n3;
1171
1172 n1 = strlen (p);
1173 n2 = strlen (p + n1 + 1);
1174 n3 = strlen (p + n1 + 1 + n2+ 1);
1175 printf (" %2u: %s,%s,%s\n", i,
1176 p, p + n1 + 1, p + n1 + n2 + 2);
1177 p += n1 + n2 + n3 + 3;
1178 }
1179
1180 free (ldr_data);
1181}
1182
1183/* Dump xcoff exception section. */
1184
1185static void
1186dump_xcoff32_except (bfd *abfd, struct xcoff_dump *data)
1187{
1188 asection *sec;
1189 bfd_size_type size = 0;
1190 bfd_byte *excp_data;
1191 struct external_exceptab *exceptab;
1192 unsigned int i;
1193
1194 sec = bfd_get_section_by_name (abfd, ".except");
1195
1196 if (sec == NULL)
1197 {
1198 printf (_("no .except section in file\n"));
1199 return;
1200 }
fd361982 1201 size = bfd_section_size (sec);
6abcee90
TG
1202 excp_data = (bfd_byte *) xmalloc (size);
1203 bfd_get_section_contents (abfd, sec, excp_data, 0, size);
1204 exceptab = (struct external_exceptab *)excp_data;
1205
1206 printf (_("Exception table:\n"));
21eb9156
TG
1207 /* Do not translate fields name. */
1208 printf ("lang reason sym/addr\n");
6abcee90
TG
1209 for (i = 0; i * sizeof (*exceptab) < size; i++, exceptab++)
1210 {
1211 unsigned int reason;
1212 unsigned int addr;
1213
1214 addr = bfd_get_32 (abfd, exceptab->e_addr.e_paddr);
1215 reason = bfd_get_8 (abfd, exceptab->e_reason);
21eb9156 1216 printf (" %02x %02x ",
6abcee90
TG
1217 (unsigned) bfd_get_8 (abfd, exceptab->e_lang), reason);
1218 if (reason == 0)
1219 xcoff32_print_symbol (data, addr);
1220 else
21eb9156 1221 printf ("@%08x", addr);
6abcee90
TG
1222 putchar ('\n');
1223 }
1224 free (excp_data);
1225}
1226
1227/* Dump xcoff type-check section. */
1228
1229static void
1230dump_xcoff32_typchk (bfd *abfd)
1231{
1232 asection *sec;
1233 bfd_size_type size = 0;
1234 bfd_byte *data;
1235 unsigned int i;
1236
1237 sec = bfd_get_section_by_name (abfd, ".typchk");
1238
1239 if (sec == NULL)
1240 {
1241 printf (_("no .typchk section in file\n"));
1242 return;
1243 }
fd361982 1244 size = bfd_section_size (sec);
6abcee90
TG
1245 data = (bfd_byte *) xmalloc (size);
1246 bfd_get_section_contents (abfd, sec, data, 0, size);
1247
1248 printf (_("Type-check section:\n"));
21eb9156
TG
1249 /* Do not translate field names. */
1250 printf ("offset len lang-id general-hash language-hash\n");
6abcee90
TG
1251 for (i = 0; i < size;)
1252 {
1253 unsigned int len;
1254
1255 len = bfd_get_16 (abfd, data + i);
1256 printf ("%08x: %-4u ", i, len);
1257 i += 2;
1258
1259 if (len == 10)
1260 {
1261 /* Expected format. */
1262 printf ("%04x %08x %08x\n",
1263 (unsigned) bfd_get_16 (abfd, data + i),
1264 (unsigned) bfd_get_32 (abfd, data + i + 2),
1265 (unsigned) bfd_get_32 (abfd, data + i + 2 + 4));
1266 }
1267 else
1268 {
1269 unsigned int j;
1270
1271 for (j = 0; j < len; j++)
1272 {
1273 if (j % 16 == 0)
1274 printf ("\n ");
1275 printf (" %02x", (unsigned char)data[i + j]);
1276 }
1277 putchar ('\n');
1278 }
1279 i += len;
1280 }
1281 free (data);
1282}
1283
1284/* Dump xcoff traceback tags section. */
1285
1286static void
1287dump_xcoff32_tbtags (bfd *abfd,
1288 const char *text, bfd_size_type text_size,
1289 unsigned int text_start, unsigned int func_start)
1290{
1291 unsigned int i;
1292
1293 if (func_start - text_start > text_size)
1294 {
1295 printf (_(" address beyond section size\n"));
1296 return;
1297 }
1298 for (i = func_start - text_start; i < text_size; i+= 4)
1299 if (bfd_get_32 (abfd, text + i) == 0)
1300 {
1301 unsigned int tb1;
1302 unsigned int tb2;
1303 unsigned int off;
1304
1305 printf (_(" tags at %08x\n"), i + 4);
1306 if (i + 8 >= text_size)
1307 goto truncated;
1308
1309 tb1 = bfd_get_32 (abfd, text + i + 4);
1310 tb2 = bfd_get_32 (abfd, text + i + 8);
1311 off = i + 12;
21eb9156 1312 printf (" version: %u, lang: %u, global_link: %u, is_eprol: %u, has_tboff: %u, int_proc: %u\n",
6abcee90
TG
1313 (tb1 >> 24) & 0xff,
1314 (tb1 >> 16) & 0xff,
1315 (tb1 >> 15) & 1,
1316 (tb1 >> 14) & 1,
1317 (tb1 >> 13) & 1,
1318 (tb1 >> 12) & 1);
21eb9156 1319 printf (" has_ctl: %u, tocless: %u, fp_pres: %u, log_abort: %u, int_hndl: %u\n",
6abcee90
TG
1320 (tb1 >> 11) & 1,
1321 (tb1 >> 10) & 1,
1322 (tb1 >> 9) & 1,
1323 (tb1 >> 8) & 1,
1324 (tb1 >> 7) & 1);
21eb9156 1325 printf (" name_pres: %u, uses_alloca: %u, cl_dis_inv: %u, saves_cr: %u, saves_lr: %u\n",
6abcee90
TG
1326 (tb1 >> 6) & 1,
1327 (tb1 >> 5) & 1,
1328 (tb1 >> 2) & 7,
1329 (tb1 >> 1) & 1,
1330 (tb1 >> 0) & 1);
21eb9156 1331 printf (" stores_bc: %u, fixup: %u, fpr_saved: %-2u, spare3: %u, gpr_saved: %-2u\n",
6abcee90
TG
1332 (tb2 >> 31) & 1,
1333 (tb2 >> 30) & 1,
1334 (tb2 >> 24) & 63,
1335 (tb2 >> 22) & 3,
1336 (tb2 >> 16) & 63);
21eb9156 1337 printf (" fixparms: %-3u floatparms: %-3u parm_on_stk: %u\n",
6abcee90
TG
1338 (tb2 >> 8) & 0xff,
1339 (tb2 >> 1) & 0x7f,
1340 (tb2 >> 0) & 1);
1341
1342 if (((tb2 >> 1) & 0x7fff) != 0)
1343 {
1344 unsigned int parminfo;
1345
1346 if (off >= text_size)
1347 goto truncated;
1348 parminfo = bfd_get_32 (abfd, text + off);
1349 off += 4;
21eb9156 1350 printf (" parminfo: 0x%08x\n", parminfo);
6abcee90
TG
1351 }
1352
1353 if ((tb1 >> 13) & 1)
1354 {
1355 unsigned int tboff;
1356
1357 if (off >= text_size)
1358 goto truncated;
1359 tboff = bfd_get_32 (abfd, text + off);
1360 off += 4;
21eb9156 1361 printf (" tb_offset: 0x%08x (start=0x%08x)\n",
6abcee90
TG
1362 tboff, text_start + i - tboff);
1363 }
1364 if ((tb1 >> 7) & 1)
1365 {
1366 unsigned int hand_mask;
1367
1368 if (off >= text_size)
1369 goto truncated;
1370 hand_mask = bfd_get_32 (abfd, text + off);
1371 off += 4;
21eb9156 1372 printf (" hand_mask_offset: 0x%08x\n", hand_mask);
6abcee90
TG
1373 }
1374 if ((tb1 >> 11) & 1)
1375 {
1376 unsigned int ctl_info;
1377 unsigned int j;
1378
1379 if (off >= text_size)
1380 goto truncated;
1381 ctl_info = bfd_get_32 (abfd, text + off);
1382 off += 4;
1383 printf (_(" number of CTL anchors: %u\n"), ctl_info);
1384 for (j = 0; j < ctl_info; j++)
1385 {
1386 if (off >= text_size)
1387 goto truncated;
21eb9156
TG
1388 printf (" CTL[%u]: %08x\n",
1389 j, (unsigned)bfd_get_32 (abfd, text + off));
6abcee90
TG
1390 off += 4;
1391 }
1392 }
1393 if ((tb1 >> 6) & 1)
1394 {
1395 unsigned int name_len;
1396 unsigned int j;
1397
1398 if (off >= text_size)
1399 goto truncated;
1400 name_len = bfd_get_16 (abfd, text + off);
1401 off += 2;
1402 printf (_(" Name (len: %u): "), name_len);
1403 if (off + name_len >= text_size)
1404 {
1405 printf (_("[truncated]\n"));
1406 goto truncated;
1407 }
1408 for (j = 0; j < name_len; j++)
1409 if (ISPRINT (text[off + j]))
1410 putchar (text[off + j]);
1411 else
1412 printf ("[%02x]", (unsigned char)text[off + j]);
1413 putchar ('\n');
1414 off += name_len;
1415 }
1416 if ((tb1 >> 5) & 1)
1417 {
1418 if (off >= text_size)
1419 goto truncated;
21eb9156 1420 printf (" alloca reg: %u\n",
6abcee90
TG
1421 (unsigned) bfd_get_8 (abfd, text + off));
1422 off++;
1423 }
1424 printf (_(" (end of tags at %08x)\n"), text_start + off);
1425 return;
1426 }
1427 printf (_(" no tags found\n"));
1428 return;
1429
1430 truncated:
1431 printf (_(" Truncated .text section\n"));
1432 return;
1433}
1434
1435static void
1436dump_xcoff32_traceback (bfd *abfd, struct xcoff_dump *data)
1437{
1438 unsigned int i;
1439 unsigned int scnum_text = -1;
1440 unsigned int text_vma;
1441 asection *text_sec;
1442 bfd_size_type text_size;
1443 char *text;
1444
1445 if (data->syms == NULL || data->sects == NULL)
1446 return;
1447
1448 /* Read text section. */
1449 text_sec = bfd_get_section_by_name (abfd, ".text");
1450 if (text_sec == NULL)
1451 return;
fd361982 1452 text_vma = bfd_section_vma (text_sec);
6abcee90 1453
fd361982 1454 text_size = bfd_section_size (text_sec);
6abcee90
TG
1455 text = (char *) xmalloc (text_size);
1456 bfd_get_section_contents (abfd, text_sec, text, 0, text_size);
1457
1458 for (i = 0; i < data->nscns; i++)
1459 if (data->sects[i].flags == STYP_TEXT)
1460 {
1461 scnum_text = i + 1;
1462 break;
1463 }
1464 if (scnum_text == (unsigned int)-1)
1465 return;
1466
1467 for (i = 0; i < data->nsyms; i++)
1468 {
1469 union xcoff32_symbol *s = &data->syms[i];
1470
1471 switch (s->sym.sclass)
1472 {
1473 case C_EXT:
1474 case C_HIDEXT:
1475 case C_WEAKEXT:
1476 if (s->sym.scnum == scnum_text
1477 && s->sym.numaux > 0)
1478 {
1479 union external_auxent *aux = &s[s->sym.numaux].aux;
1480
1481 unsigned int smtyp;
1482 unsigned int smclas;
1483
1484 smtyp = bfd_h_get_8 (abfd, aux->x_csect.x_smtyp);
1485 smclas = bfd_h_get_8 (abfd, aux->x_csect.x_smclas);
1486 if (SMTYP_SMTYP (smtyp) == XTY_LD
1487 && (smclas == XMC_PR
1488 || smclas == XMC_GL
1489 || smclas == XMC_XO))
1490 {
1491 printf ("%08x: ", s->sym.val);
1492 xcoff32_print_symbol (data, i);
1493 putchar ('\n');
1494 dump_xcoff32_tbtags (abfd, text, text_size,
1495 text_vma, s->sym.val);
1496 }
1497 }
1498 break;
1499 default:
1500 break;
1501 }
1502 i += s->sym.numaux;
1503 }
1504 free (text);
1505}
1506
1507/* Dump the TOC symbols. */
1508
1509static void
1510dump_xcoff32_toc (bfd *abfd, struct xcoff_dump *data)
1511{
1512 unsigned int i;
1513 unsigned int nbr_ent;
1514 unsigned int size;
1515
1516 printf (_("TOC:\n"));
1517
1518 if (data->syms == NULL)
1519 return;
1520
1521 nbr_ent = 0;
1522 size = 0;
1523
1524 for (i = 0; i < data->nsyms; i++)
1525 {
1526 union xcoff32_symbol *s = &data->syms[i];
1527
1528 switch (s->sym.sclass)
1529 {
1530 case C_EXT:
1531 case C_HIDEXT:
1532 case C_WEAKEXT:
1533 if (s->sym.numaux > 0)
1534 {
1535 union external_auxent *aux = &s[s->sym.numaux].aux;
1536 unsigned int smclas;
1537 unsigned int ent_sz;
1538
1539 smclas = bfd_h_get_8 (abfd, aux->x_csect.x_smclas);
1540 if (smclas == XMC_TC
1541 || smclas == XMC_TD
1542 || smclas == XMC_TC0)
1543 {
1544 ent_sz = bfd_h_get_32 (abfd, aux->x_scn.x_scnlen);
1545 printf ("%08x %08x ",
1546 s->sym.val, ent_sz);
1547 xcoff32_print_symbol (data, i);
1548 putchar ('\n');
1549 nbr_ent++;
1550 size += ent_sz;
1551 }
1552 }
1553 break;
1554 default:
1555 break;
1556 }
1557 i += s->sym.numaux;
1558 }
1559 printf (_("Nbr entries: %-8u Size: %08x (%u)\n"),
1560 nbr_ent, size, size);
1561}
1562
1563/* Handle an rs6000 xcoff file. */
1564
1565static void
1566dump_xcoff32 (bfd *abfd, struct external_filehdr *fhdr)
1567{
1568 struct xcoff_dump data;
1569
1570 data.nscns = bfd_h_get_16 (abfd, fhdr->f_nscns);
1571 data.symptr = bfd_h_get_32 (abfd, fhdr->f_symptr);
1572 data.nsyms = bfd_h_get_32 (abfd, fhdr->f_nsyms);
1573 data.opthdr = bfd_h_get_16 (abfd, fhdr->f_opthdr);
1574 data.sects = NULL;
1575 data.syms = NULL;
1576 data.strings = NULL;
1577 data.strings_size = 0;
1578
1579 if (options[OPT_FILE_HEADER].selected)
1580 dump_xcoff32_file_header (abfd, fhdr, &data);
1581
1582 if (options[OPT_AOUT].selected)
1583 dump_xcoff32_aout_header (abfd, &data);
1584
1585 if (options[OPT_SYMS].selected
1586 || options[OPT_RELOCS].selected
1587 || options[OPT_LINENO].selected
1588 || options[OPT_TRACEBACK].selected)
1589 xcoff32_read_sections (abfd, &data);
1590
1591 if (options[OPT_SECTIONS].selected)
1592 dump_xcoff32_sections_header (abfd, &data);
1593
1594 if (options[OPT_SYMS].selected
1595 || options[OPT_RELOCS].selected
1596 || options[OPT_LINENO].selected
1597 || options[OPT_EXCEPT].selected
1598 || options[OPT_TRACEBACK].selected
1599 || options[OPT_TOC].selected)
1600 xcoff32_read_symbols (abfd, &data);
1601
1602 if (options[OPT_SYMS].selected)
1603 dump_xcoff32_symbols (abfd, &data);
1604
1605 if (options[OPT_RELOCS].selected)
1606 dump_xcoff32_relocs (abfd, &data);
1607
1608 if (options[OPT_LINENO].selected)
1609 dump_xcoff32_lineno (abfd, &data);
1610
1611 if (options[OPT_LOADER].selected)
1612 dump_xcoff32_loader (abfd);
1613
1614 if (options[OPT_EXCEPT].selected)
1615 dump_xcoff32_except (abfd, &data);
1616
1617 if (options[OPT_TYPCHK].selected)
1618 dump_xcoff32_typchk (abfd);
1619
1620 if (options[OPT_TRACEBACK].selected)
1621 dump_xcoff32_traceback (abfd, &data);
1622
1623 if (options[OPT_TOC].selected)
1624 dump_xcoff32_toc (abfd, &data);
1625
1626 free (data.sects);
1627 free (data.strings);
1628 free (data.syms);
1629}
1630
1631/* Dump ABFD (according to the options[] array). */
1632
1633static void
868d1840 1634xcoff_dump_obj (bfd *abfd)
6abcee90
TG
1635{
1636 struct external_filehdr fhdr;
1637 unsigned short magic;
1638
1639 /* Read file header. */
1640 if (bfd_seek (abfd, 0, SEEK_SET) != 0
1641 || bfd_bread (&fhdr, sizeof (fhdr), abfd) != sizeof (fhdr))
1642 {
1643 non_fatal (_("cannot read header"));
1644 return;
1645 }
1646
1647 /* Decoding. We don't use the bfd/coff function to get all the fields. */
1648 magic = bfd_h_get_16 (abfd, fhdr.f_magic);
1649 if (options[OPT_FILE_HEADER].selected)
1650 {
1651 printf (_("File header:\n"));
1652 printf (_(" magic: 0x%04x (0%04o) "), magic, magic);
1653 switch (magic)
1654 {
1655 case U802WRMAGIC:
1656 printf (_("(WRMAGIC: writable text segments)"));
1657 break;
1658 case U802ROMAGIC:
1659 printf (_("(ROMAGIC: readonly sharablee text segments)"));
1660 break;
1661 case U802TOCMAGIC:
1662 printf (_("(TOCMAGIC: readonly text segments and TOC)"));
1663 break;
1664 default:
1665 printf (_("unknown magic"));
868d1840 1666 break;
6abcee90
TG
1667 }
1668 putchar ('\n');
1669 }
1670 if (magic == U802ROMAGIC || magic == U802WRMAGIC || magic == U802TOCMAGIC)
1671 dump_xcoff32 (abfd, &fhdr);
1672 else
1673 printf (_(" Unhandled magic\n"));
1674}
1675
868d1840
TG
1676/* Handle an AIX dumpx core file. */
1677
1678static void
1679dump_dumpx_core (bfd *abfd, struct external_core_dumpx *hdr)
1680{
1681 if (options[OPT_FILE_HEADER].selected)
1682 {
09c78487
AM
1683 printf (" signal: %u\n",
1684 (unsigned) bfd_h_get_8 (abfd, hdr->c_signo));
1685 printf (" flags: 0x%02x\n",
1686 (unsigned) bfd_h_get_8 (abfd, hdr->c_flag));
868d1840
TG
1687 printf (" entries: %u\n",
1688 (unsigned) bfd_h_get_16 (abfd, hdr->c_entries));
1689#ifdef BFD64
1690 printf (" fdsinfox: offset: 0x%08" BFD_VMA_FMT "x\n",
1691 bfd_h_get_64 (abfd, hdr->c_fdsinfox));
1692 printf (" loader: offset: 0x%08" BFD_VMA_FMT "x, "
1693 "size: 0x%" BFD_VMA_FMT"x\n",
1694 bfd_h_get_64 (abfd, hdr->c_loader),
1695 bfd_h_get_64 (abfd, hdr->c_lsize));
1696 printf (" thr: offset: 0x%08" BFD_VMA_FMT "x, nbr: %u\n",
1697 bfd_h_get_64 (abfd, hdr->c_thr),
1698 (unsigned) bfd_h_get_32 (abfd, hdr->c_n_thr));
1699 printf (" segregions: offset: 0x%08" BFD_VMA_FMT "x, "
1700 "nbr: %" BFD_VMA_FMT "u\n",
1701 bfd_h_get_64 (abfd, hdr->c_segregion),
1702 bfd_h_get_64 (abfd, hdr->c_segs));
1703 printf (" stack: offset: 0x%08" BFD_VMA_FMT "x, "
1704 "org: 0x%" BFD_VMA_FMT"x, "
1705 "size: 0x%" BFD_VMA_FMT"x\n",
1706 bfd_h_get_64 (abfd, hdr->c_stack),
1707 bfd_h_get_64 (abfd, hdr->c_stackorg),
1708 bfd_h_get_64 (abfd, hdr->c_size));
1709 printf (" data: offset: 0x%08" BFD_VMA_FMT "x, "
1710 "org: 0x%" BFD_VMA_FMT"x, "
1711 "size: 0x%" BFD_VMA_FMT"x\n",
1712 bfd_h_get_64 (abfd, hdr->c_data),
1713 bfd_h_get_64 (abfd, hdr->c_dataorg),
1714 bfd_h_get_64 (abfd, hdr->c_datasize));
1715 printf (" sdata: org: 0x%" BFD_VMA_FMT"x, "
1716 "size: 0x%" BFD_VMA_FMT"x\n",
1717 bfd_h_get_64 (abfd, hdr->c_sdorg),
1718 bfd_h_get_64 (abfd, hdr->c_sdsize));
1719 printf (" vmmregions: offset: 0x%" BFD_VMA_FMT"x, "
1720 "num: 0x%" BFD_VMA_FMT"x\n",
1721 bfd_h_get_64 (abfd, hdr->c_vmm),
1722 bfd_h_get_64 (abfd, hdr->c_vmmregions));
1723 printf (" impl: 0x%08x\n",
1724 (unsigned) bfd_h_get_32 (abfd, hdr->c_impl));
1725 printf (" cprs: 0x%" BFD_VMA_FMT "x\n",
1726 bfd_h_get_64 (abfd, hdr->c_cprs));
1727#endif
1728 }
1729 if (options[OPT_LDINFO].selected)
1730 {
1731#ifdef BFD64
1732 file_ptr off = (file_ptr) bfd_h_get_64 (abfd, hdr->c_loader);
1733 bfd_size_type len = (bfd_size_type) bfd_h_get_64 (abfd, hdr->c_lsize);
1734 char *ldr;
1735
1736 ldr = xmalloc (len);
1737 if (bfd_seek (abfd, off, SEEK_SET) != 0
1738 || bfd_bread (ldr, len, abfd) != len)
1739 non_fatal (_("cannot read loader info table"));
1740 else
1741 {
1742 char *p;
1743
1744 printf ("\n"
1745 "ld info:\n");
1746 printf (" next core off textorg textsize dataorg datasize\n");
1747 p = ldr;
1748 while (1)
1749 {
1750 struct external_ld_info32 *l = (struct external_ld_info32 *)p;
1751 unsigned int next;
1752 size_t n1;
1753
1754 next = bfd_h_get_32 (abfd, l->ldinfo_next);
1755 printf (" %08x %08x %08x %08x %08x %08x\n",
1756 next,
1757 (unsigned) bfd_h_get_32 (abfd, l->core_offset),
1758 (unsigned) bfd_h_get_32 (abfd, l->ldinfo_textorg),
1759 (unsigned) bfd_h_get_32 (abfd, l->ldinfo_textsize),
1760 (unsigned) bfd_h_get_32 (abfd, l->ldinfo_dataorg),
1761 (unsigned) bfd_h_get_32 (abfd, l->ldinfo_datasize));
1762 n1 = strlen ((char *) l->ldinfo_filename);
1763 printf (" %s %s\n",
1764 l->ldinfo_filename, l->ldinfo_filename + n1 + 1);
1765 if (next == 0)
1766 break;
1767 p += next;
1768 }
1769 }
1770#else
1771 printf (_("\n"
1772 "ldinfo dump not supported in 32 bits environments\n"));
1773#endif
1774 }
1775}
1776
1777/* Dump a core file. */
1778
1779static void
1780xcoff_dump_core (bfd *abfd)
1781{
1782 struct external_core_dumpx hdr;
1783 unsigned int version;
1784
1785 /* Read file header. */
1786 if (bfd_seek (abfd, 0, SEEK_SET) != 0
1787 || bfd_bread (&hdr, sizeof (hdr), abfd) != sizeof (hdr))
1788 {
1789 non_fatal (_("cannot core read header"));
1790 return;
1791 }
1792
1793 version = bfd_h_get_32 (abfd, hdr.c_version);
1794 if (options[OPT_FILE_HEADER].selected)
1795 {
1796 printf (_("Core header:\n"));
1797 printf (_(" version: 0x%08x "), version);
1798 switch (version)
1799 {
1800 case CORE_DUMPX_VERSION:
1801 printf (_("(dumpx format - aix4.3 / 32 bits)"));
1802 break;
1803 case CORE_DUMPXX_VERSION:
1804 printf (_("(dumpxx format - aix5.0 / 64 bits)"));
1805 break;
1806 default:
1807 printf (_("unknown format"));
1808 break;
1809 }
1810 putchar ('\n');
1811 }
1812 if (version == CORE_DUMPX_VERSION)
1813 dump_dumpx_core (abfd, &hdr);
1814 else
1815 printf (_(" Unhandled magic\n"));
1816}
1817
1818/* Dump an XCOFF file. */
1819
1820static void
1821xcoff_dump (bfd *abfd)
1822{
1823 /* We rely on BFD to decide if the file is a core file. Note that core
1824 files are only supported on native environment by BFD. */
1825 switch (bfd_get_format (abfd))
1826 {
1827 case bfd_core:
1828 xcoff_dump_core (abfd);
1829 break;
1830 default:
1831 xcoff_dump_obj (abfd);
1832 break;
1833 }
1834}
1835
6abcee90
TG
1836/* Vector for xcoff. */
1837
1838const struct objdump_private_desc objdump_private_desc_xcoff =
1839 {
1840 xcoff_help,
1841 xcoff_filter,
1842 xcoff_dump,
1843 options
1844 };
This page took 0.500002 seconds and 4 git commands to generate.