OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [binutils/] [od-xcoff.c] - Blame information for rev 95

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.