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