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 148

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

powered by: WebSVN 2.1.0

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