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

Subversion Repositories core_arm

[/] [core_arm/] [trunk/] [soft/] [sim/] [load.c] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 tarookumic
#include "sim.h"
2
#include "bfd.h"
3
#include "dis-asm.h"
4
 
5
static char *default_target = "elf32-littlearm";        /* Default at runtime.  */
6
/* Architecture to disassemble for, or default if NULL.  */
7
static char *machine = "arm";
8
 
9
/* Endianness to disassemble for, or default if BFD_ENDIAN_UNKNOWN.  */
10
static enum bfd_endian endian = BFD_ENDIAN_UNKNOWN;
11
 
12
static bfd_boolean disassemble_all;     /* -D */
13
 
14
/* Target specific options to the disassembler.  */
15
static char *disassembler_options = (char *) NULL;
16
 
17
void parse_args PARAMS ((int, char **));
18
static int dump_reloc_info;             /* -r */
19
 
20
int exit_status = 0;
21
 
22
static char *only = 0;                   /* -j secname */
23
 
24
#ifndef SKIP_ZEROES
25
#define SKIP_ZEROES (8)
26
#endif
27
 
28
#ifndef SKIP_ZEROES_AT_END
29
#define SKIP_ZEROES_AT_END (3)
30
#endif
31
 
32
static bfd_vma adjust_section_vma = 0;   /* --adjust-vma */
33
 
34
static int with_line_numbers;           /* -l */
35
static bfd_boolean with_source_code;    /* -S */
36
static int show_raw_insn;               /* --show-raw-insn */
37
 
38
 
39
 
40
/* Pseudo FILE object for strings.  */
41
typedef struct
42
{
43
  char *buffer;
44
  size_t size;
45
  char *current;
46
} SFILE;
47
 
48
 
49
static int
50
objdump_sprintf VPARAMS ((SFILE *f, const char *format, ...))
51
{
52
  char *buf;
53
  size_t n;
54
 
55
  VA_OPEN (args, format);
56
  VA_FIXEDARG (args, SFILE *, f);
57
  VA_FIXEDARG (args, const char *, format);
58
 
59
  vasprintf (&buf, format, args);
60
 
61
  if (buf == NULL)
62
    {
63
      va_end (args);
64
      fatal ("Out of virtual memory");
65
    }
66
 
67
  n = strlen (buf);
68
 
69
  while ((size_t) ((f->buffer + f->size) - f->current) < n + 1)
70
    {
71
      size_t curroff;
72
 
73
      curroff = f->current - f->buffer;
74
      f->size *= 2;
75
      f->buffer = xrealloc (f->buffer, f->size);
76
      f->current = f->buffer + curroff;
77
    }
78
 
79
  memcpy (f->current, buf, n);
80
  f->current += n;
81
  f->current[0] = '\0';
82
 
83
  free (buf);
84
 
85
  VA_CLOSE (args);
86
  return n;
87
}
88
 
89
 
90
/* Should perhaps share code and display with nm?  */
91
static int disassemble_zeroes;          /* --disassemble-zeroes */
92
 
93
/* The dynamic symbol table.  */
94
static asymbol **dynsyms;
95
 
96
/* Number of symbols in `dynsyms'.  */
97
static long dynsymcount = 0;
98
 
99
/* The symbol table.  */
100
static asymbol **syms;
101
 
102
/* Number of symbols in `syms'.  */
103
static long symcount = 0;
104
 
105
/* The sorted symbol table.  */
106
static asymbol **sorted_syms;
107
 
108
/* Number of symbols in `sorted_syms'.  */
109
static long sorted_symcount = 0;
110
 
111
 
112
/* Extra info to pass to the disassembler address printing function.  */
113
struct objdump_disasm_info
114
{
115
  bfd *abfd;
116
  asection *sec;
117
  bfd_boolean require_sec;
118
};
119
 
120
/* Hold the last function name and the last line number we displayed
121
   in a disassembly.  */
122
 
123
static char *prev_functionname;
124
static unsigned int prev_line;
125
 
126
/* We keep a list of all files that we have seen when doing a
127
   dissassembly with source, so that we know how much of the file to
128
   display.  This can be important for inlined functions.  */
129
 
130
struct print_file_list
131
{
132
  struct print_file_list *next;
133
  char *filename;
134
  unsigned int line;
135
  FILE *f;
136
};
137
 
138
 
139
 
140
int
141
main (argc, argv)
142
     int argc;
143
     char **argv;
144
{
145
  char *target = default_target;
146
  bfd_boolean seenflag = FALSE;
147
 
148
  //parse_args(argc,argv);
149
  bfd_init ();
150
  //set_default_bfd_target ();
151
 
152
 
153
  read_exe (argv[1], target);
154
 
155
 
156
  return exit_status;
157
}
158
 
159
static bfd_vma start_address = (bfd_vma) -1; /* --start-address */
160
static bfd_vma stop_address = (bfd_vma) -1;  /* --stop-address */
161
 
162
static int wide_output;                 /* -w */
163
 
164
static int prefix_addresses;            /* --prefix-addresses */
165
 
166
 
167
 
168
 
169
/* Print the name of a symbol.  */
170
 
171
static void
172
objdump_print_symname (abfd, info, sym)
173
     bfd *abfd;
174
     struct disassemble_info *info;
175
     asymbol *sym;
176
{
177
  char *alloc;
178
  const char *name;
179
 
180
  alloc = NULL;
181
  name = bfd_asymbol_name (sym);
182
  //if (do_demangle && name[0] != '\0')
183
  //  {
184
      /* Demangle the name.  */
185
  //    alloc = demangle (abfd, name);
186
  //    name = alloc;
187
  //  }
188
 
189
  if (info != NULL)
190
    (*info->fprintf_func) (info->stream, "%s", name);
191
  else
192
    printf ("%s", name);
193
 
194
  if (alloc != NULL)
195
    free (alloc);
196
}
197
 
198
/* Locate a symbol given a bfd, a section, and a VMA.  If REQUIRE_SEC
199
   is TRUE, then always require the symbol to be in the section.  This
200
   returns NULL if there is no suitable symbol.  If PLACE is not NULL,
201
   then *PLACE is set to the index of the symbol in sorted_syms.  */
202
 
203
static asymbol *
204
find_symbol_for_address (abfd, sec, vma, require_sec, place)
205
     bfd *abfd;
206
     asection *sec;
207
     bfd_vma vma;
208
     bfd_boolean require_sec;
209
     long *place;
210
{
211
  /* @@ Would it speed things up to cache the last two symbols returned,
212
     and maybe their address ranges?  For many processors, only one memory
213
     operand can be present at a time, so the 2-entry cache wouldn't be
214
     constantly churned by code doing heavy memory accesses.  */
215
 
216
  /* Indices in `sorted_syms'.  */
217
  long min = 0;
218
  long max = sorted_symcount;
219
  long thisplace;
220
  unsigned int opb = bfd_octets_per_byte (abfd);
221
 
222
  if (sorted_symcount < 1)
223
    return NULL;
224
 
225
  /* Perform a binary search looking for the closest symbol to the
226
     required value.  We are searching the range (min, max].  */
227
  while (min + 1 < max)
228
    {
229
      asymbol *sym;
230
 
231
      thisplace = (max + min) / 2;
232
      sym = sorted_syms[thisplace];
233
 
234
      if (bfd_asymbol_value (sym) > vma)
235
        max = thisplace;
236
      else if (bfd_asymbol_value (sym) < vma)
237
        min = thisplace;
238
      else
239
        {
240
          min = thisplace;
241
          break;
242
        }
243
    }
244
 
245
  /* The symbol we want is now in min, the low end of the range we
246
     were searching.  If there are several symbols with the same
247
     value, we want the first one.  */
248
  thisplace = min;
249
  while (thisplace > 0
250
         && (bfd_asymbol_value (sorted_syms[thisplace])
251
             == bfd_asymbol_value (sorted_syms[thisplace - 1])))
252
    --thisplace;
253
 
254
  /* If the file is relocateable, and the symbol could be from this
255
     section, prefer a symbol from this section over symbols from
256
     others, even if the other symbol's value might be closer.
257
 
258
     Note that this may be wrong for some symbol references if the
259
     sections have overlapping memory ranges, but in that case there's
260
     no way to tell what's desired without looking at the relocation
261
     table.  */
262
  if (sorted_syms[thisplace]->section != sec
263
      && (require_sec
264
          || ((abfd->flags & HAS_RELOC) != 0
265
              && vma >= bfd_get_section_vma (abfd, sec)
266
              && vma < (bfd_get_section_vma (abfd, sec)
267
                        + bfd_section_size (abfd, sec) / opb))))
268
    {
269
      long i;
270
 
271
      for (i = thisplace + 1; i < sorted_symcount; i++)
272
        {
273
          if (bfd_asymbol_value (sorted_syms[i])
274
              != bfd_asymbol_value (sorted_syms[thisplace]))
275
            break;
276
        }
277
 
278
      --i;
279
 
280
      for (; i >= 0; i--)
281
        {
282
          if (sorted_syms[i]->section == sec
283
              && (i == 0
284
                  || sorted_syms[i - 1]->section != sec
285
                  || (bfd_asymbol_value (sorted_syms[i])
286
                      != bfd_asymbol_value (sorted_syms[i - 1]))))
287
            {
288
              thisplace = i;
289
              break;
290
            }
291
        }
292
 
293
      if (sorted_syms[thisplace]->section != sec)
294
        {
295
          /* We didn't find a good symbol with a smaller value.
296
             Look for one with a larger value.  */
297
          for (i = thisplace + 1; i < sorted_symcount; i++)
298
            {
299
              if (sorted_syms[i]->section == sec)
300
                {
301
                  thisplace = i;
302
                  break;
303
                }
304
            }
305
        }
306
 
307
      if (sorted_syms[thisplace]->section != sec
308
          && (require_sec
309
              || ((abfd->flags & HAS_RELOC) != 0
310
                  && vma >= bfd_get_section_vma (abfd, sec)
311
                  && vma < (bfd_get_section_vma (abfd, sec)
312
                            + bfd_section_size (abfd, sec)))))
313
        {
314
          /* There is no suitable symbol.  */
315
          return NULL;
316
        }
317
    }
318
 
319
  if (place != NULL)
320
    *place = thisplace;
321
 
322
  return sorted_syms[thisplace];
323
}
324
 
325
/* Sort relocs into address order.  */
326
 
327
static int
328
compare_relocs (ap, bp)
329
     const PTR ap;
330
     const PTR bp;
331
{
332
  const arelent *a = *(const arelent **)ap;
333
  const arelent *b = *(const arelent **)bp;
334
 
335
  if (a->address > b->address)
336
    return 1;
337
  else if (a->address < b->address)
338
    return -1;
339
 
340
  /* So that associated relocations tied to the same address show up
341
     in the correct order, we don't do any further sorting.  */
342
  if (a > b)
343
    return 1;
344
  else if (a < b)
345
    return -1;
346
  else
347
    return 0;
348
}
349
 
350
 
351
/* Sort symbols into value order.  */
352
 
353
static int
354
compare_symbols (ap, bp)
355
     const PTR ap;
356
     const PTR bp;
357
{
358
  const asymbol *a = *(const asymbol **)ap;
359
  const asymbol *b = *(const asymbol **)bp;
360
  const char *an, *bn;
361
  size_t anl, bnl;
362
  bfd_boolean af, bf;
363
  flagword aflags, bflags;
364
 
365
  if (bfd_asymbol_value (a) > bfd_asymbol_value (b))
366
    return 1;
367
  else if (bfd_asymbol_value (a) < bfd_asymbol_value (b))
368
    return -1;
369
 
370
  if (a->section > b->section)
371
    return 1;
372
  else if (a->section < b->section)
373
    return -1;
374
 
375
  an = bfd_asymbol_name (a);
376
  bn = bfd_asymbol_name (b);
377
  anl = strlen (an);
378
  bnl = strlen (bn);
379
 
380
  /* The symbols gnu_compiled and gcc2_compiled convey no real
381
     information, so put them after other symbols with the same value.  */
382
  af = (strstr (an, "gnu_compiled") != NULL
383
        || strstr (an, "gcc2_compiled") != NULL);
384
  bf = (strstr (bn, "gnu_compiled") != NULL
385
        || strstr (bn, "gcc2_compiled") != NULL);
386
 
387
  if (af && ! bf)
388
    return 1;
389
  if (! af && bf)
390
    return -1;
391
 
392
  /* We use a heuristic for the file name, to try to sort it after
393
     more useful symbols.  It may not work on non Unix systems, but it
394
     doesn't really matter; the only difference is precisely which
395
     symbol names get printed.  */
396
 
397
#define file_symbol(s, sn, snl)                 \
398
  (((s)->flags & BSF_FILE) != 0                  \
399
   || ((sn)[(snl) - 2] == '.'                   \
400
       && ((sn)[(snl) - 1] == 'o'               \
401
           || (sn)[(snl) - 1] == 'a')))
402
 
403
  af = file_symbol (a, an, anl);
404
  bf = file_symbol (b, bn, bnl);
405
 
406
  if (af && ! bf)
407
    return 1;
408
  if (! af && bf)
409
    return -1;
410
 
411
  /* Try to sort global symbols before local symbols before function
412
     symbols before debugging symbols.  */
413
 
414
  aflags = a->flags;
415
  bflags = b->flags;
416
 
417
  if ((aflags & BSF_DEBUGGING) != (bflags & BSF_DEBUGGING))
418
    {
419
      if ((aflags & BSF_DEBUGGING) != 0)
420
        return 1;
421
      else
422
        return -1;
423
    }
424
  if ((aflags & BSF_FUNCTION) != (bflags & BSF_FUNCTION))
425
    {
426
      if ((aflags & BSF_FUNCTION) != 0)
427
        return -1;
428
      else
429
        return 1;
430
    }
431
  if ((aflags & BSF_LOCAL) != (bflags & BSF_LOCAL))
432
    {
433
      if ((aflags & BSF_LOCAL) != 0)
434
        return 1;
435
      else
436
        return -1;
437
    }
438
  if ((aflags & BSF_GLOBAL) != (bflags & BSF_GLOBAL))
439
    {
440
      if ((aflags & BSF_GLOBAL) != 0)
441
        return -1;
442
      else
443
        return 1;
444
    }
445
 
446
  /* Symbols that start with '.' might be section names, so sort them
447
     after symbols that don't start with '.'.  */
448
  if (an[0] == '.' && bn[0] != '.')
449
    return 1;
450
  if (an[0] != '.' && bn[0] == '.')
451
    return -1;
452
 
453
  /* Finally, if we can't distinguish them in any other way, try to
454
     get consistent results by sorting the symbols by name.  */
455
  return strcmp (an, bn);
456
}
457
 
458
/* Print VMA to STREAM.  If SKIP_ZEROES is TRUE, omit leading zeroes.  */
459
 
460
static void
461
objdump_print_value (vma, info, skip_zeroes)
462
     bfd_vma vma;
463
     struct disassemble_info *info;
464
     bfd_boolean skip_zeroes;
465
{
466
  char buf[30];
467
  char *p;
468
  struct objdump_disasm_info *aux
469
    = (struct objdump_disasm_info *) info->application_data;
470
 
471
  bfd_sprintf_vma (aux->abfd, buf, vma);
472
  if (! skip_zeroes)
473
    p = buf;
474
  else
475
    {
476
      for (p = buf; *p == '0'; ++p)
477
        ;
478
      if (*p == '\0')
479
        --p;
480
    }
481
  (*info->fprintf_func) (info->stream, "%s", p);
482
}
483
 
484
 
485
/* Print an address to INFO symbolically.  */
486
 
487
static void
488
objdump_print_addr_with_sym (abfd, sec, sym, vma, info, skip_zeroes)
489
     bfd *abfd;
490
     asection *sec;
491
     asymbol *sym;
492
     bfd_vma vma;
493
     struct disassemble_info *info;
494
     bfd_boolean skip_zeroes;
495
{
496
  objdump_print_value (vma, info, skip_zeroes);
497
 
498
  if (sym == NULL)
499
    {
500
      bfd_vma secaddr;
501
 
502
      (*info->fprintf_func) (info->stream, " <%s",
503
                             bfd_get_section_name (abfd, sec));
504
      secaddr = bfd_get_section_vma (abfd, sec);
505
      if (vma < secaddr)
506
        {
507
          (*info->fprintf_func) (info->stream, "-0x");
508
          objdump_print_value (secaddr - vma, info, TRUE);
509
        }
510
      else if (vma > secaddr)
511
        {
512
          (*info->fprintf_func) (info->stream, "+0x");
513
          objdump_print_value (vma - secaddr, info, TRUE);
514
        }
515
      (*info->fprintf_func) (info->stream, ">");
516
    }
517
  else
518
    {
519
      (*info->fprintf_func) (info->stream, " <");
520
      objdump_print_symname (abfd, info, sym);
521
      if (bfd_asymbol_value (sym) > vma)
522
        {
523
          (*info->fprintf_func) (info->stream, "-0x");
524
          objdump_print_value (bfd_asymbol_value (sym) - vma, info, TRUE);
525
        }
526
      else if (vma > bfd_asymbol_value (sym))
527
        {
528
          (*info->fprintf_func) (info->stream, "+0x");
529
          objdump_print_value (vma - bfd_asymbol_value (sym), info, TRUE);
530
        }
531
      (*info->fprintf_func) (info->stream, ">");
532
    }
533
}
534
 
535
/* Print VMA to INFO, symbolically if possible.  If SKIP_ZEROES is
536
   TRUE, don't output leading zeroes.  */
537
 
538
static void
539
objdump_print_addr (vma, info, skip_zeroes)
540
     bfd_vma vma;
541
     struct disassemble_info *info;
542
     bfd_boolean skip_zeroes;
543
{
544
  struct objdump_disasm_info *aux;
545
  asymbol *sym;
546
 
547
  if (sorted_symcount < 1)
548
    {
549
      (*info->fprintf_func) (info->stream, "0x");
550
      objdump_print_value (vma, info, skip_zeroes);
551
      return;
552
    }
553
 
554
  aux = (struct objdump_disasm_info *) info->application_data;
555
  sym = find_symbol_for_address (aux->abfd, aux->sec, vma, aux->require_sec,
556
                                 (long *) NULL);
557
  objdump_print_addr_with_sym (aux->abfd, aux->sec, sym, vma, info,
558
                               skip_zeroes);
559
}
560
 
561
/* Print VMA to INFO.  This function is passed to the disassembler
562
   routine.  */
563
 
564
static void
565
objdump_print_address (vma, info)
566
     bfd_vma vma;
567
     struct disassemble_info *info;
568
{
569
  objdump_print_addr (vma, info, ! prefix_addresses);
570
}
571
 
572
/* Determine of the given address has a symbol associated with it.  */
573
 
574
static int
575
objdump_symbol_at_address (vma, info)
576
     bfd_vma vma;
577
     struct disassemble_info * info;
578
{
579
  struct objdump_disasm_info * aux;
580
  asymbol * sym;
581
 
582
  /* No symbols - do not bother checking.  */
583
  if (sorted_symcount < 1)
584
    return 0;
585
 
586
  aux = (struct objdump_disasm_info *) info->application_data;
587
  sym = find_symbol_for_address (aux->abfd, aux->sec, vma, aux->require_sec,
588
                                 (long *) NULL);
589
 
590
  return (sym != NULL && (bfd_asymbol_value (sym) == vma));
591
}
592
 
593
static struct print_file_list *print_files;
594
 
595
 
596
/* Filter out (in place) symbols that are useless for disassembly.
597
   COUNT is the number of elements in SYMBOLS.
598
   Return the number of useful symbols.  */
599
 
600
static long
601
remove_useless_symbols (symbols, count)
602
     asymbol **symbols;
603
     long count;
604
{
605
  register asymbol **in_ptr = symbols, **out_ptr = symbols;
606
 
607
  while (--count >= 0)
608
    {
609
      asymbol *sym = *in_ptr++;
610
 
611
      if (sym->name == NULL || sym->name[0] == '\0')
612
        continue;
613
      if (sym->flags & (BSF_DEBUGGING))
614
        continue;
615
      if (bfd_is_und_section (sym->section)
616
          || bfd_is_com_section (sym->section))
617
        continue;
618
 
619
      *out_ptr++ = sym;
620
    }
621
  return out_ptr - symbols;
622
}
623
 
624
static void
625
skip_to_line (p, line, show)
626
     struct print_file_list *p;
627
     unsigned int line;
628
     bfd_boolean show;
629
{
630
  while (p->line < line)
631
    {
632
      char buf[100];
633
 
634
      if (fgets (buf, sizeof buf, p->f) == NULL)
635
        {
636
          fclose (p->f);
637
          p->f = NULL;
638
          break;
639
        }
640
 
641
      if (show)
642
        printf ("%s", buf);
643
 
644
      if (strchr (buf, '\n') != NULL)
645
        ++p->line;
646
    }
647
}
648
 
649
 
650
static int file_start_context = 0;      /* --file-start-context */
651
 
652
 
653
#define SHOW_PRECEDING_CONTEXT_LINES (5)
654
 
655
 
656
 
657
/* Show the line number, or the source line, in a dissassembly
658
   listing.  */
659
 
660
static void
661
show_line (abfd, section, addr_offset)
662
     bfd *abfd;
663
     asection *section;
664
     bfd_vma addr_offset;
665
{
666
  const char *filename;
667
  const char *functionname;
668
  unsigned int line;
669
 
670
  if (! with_line_numbers && ! with_source_code)
671
    return;
672
 
673
  if (! bfd_find_nearest_line (abfd, section, syms, addr_offset, &filename,
674
                               &functionname, &line))
675
    return;
676
 
677
  if (filename != NULL && *filename == '\0')
678
    filename = NULL;
679
  if (functionname != NULL && *functionname == '\0')
680
    functionname = NULL;
681
 
682
  if (with_line_numbers)
683
    {
684
      if (functionname != NULL
685
          && (prev_functionname == NULL
686
              || strcmp (functionname, prev_functionname) != 0))
687
        printf ("%s():\n", functionname);
688
      if (line > 0 && line != prev_line)
689
        printf ("%s:%u\n", filename == NULL ? "???" : filename, line);
690
    }
691
 
692
  if (with_source_code
693
      && filename != NULL
694
      && line > 0)
695
    {
696
      struct print_file_list **pp, *p;
697
 
698
      for (pp = &print_files; *pp != NULL; pp = &(*pp)->next)
699
        if (strcmp ((*pp)->filename, filename) == 0)
700
          break;
701
      p = *pp;
702
 
703
      if (p != NULL)
704
        {
705
          if (p != print_files)
706
            {
707
              int l;
708
 
709
              /* We have reencountered a file name which we saw
710
                 earlier.  This implies that either we are dumping out
711
                 code from an included file, or the same file was
712
                 linked in more than once.  There are two common cases
713
                 of an included file: inline functions in a header
714
                 file, and a bison or flex skeleton file.  In the
715
                 former case we want to just start printing (but we
716
                 back up a few lines to give context); in the latter
717
                 case we want to continue from where we left off.  I
718
                 can't think of a good way to distinguish the cases,
719
                 so I used a heuristic based on the file name.  */
720
              if (strcmp (p->filename + strlen (p->filename) - 2, ".h") != 0)
721
                l = p->line;
722
              else
723
                {
724
                  l = line - SHOW_PRECEDING_CONTEXT_LINES;
725
                  if (l < 0)
726
                    l = 0;
727
                }
728
 
729
              if (p->f == NULL)
730
                {
731
                  p->f = fopen (p->filename, "r");
732
                  p->line = 0;
733
                }
734
              if (p->f != NULL)
735
                skip_to_line (p, l, FALSE);
736
 
737
              if (print_files->f != NULL)
738
                {
739
                  fclose (print_files->f);
740
                  print_files->f = NULL;
741
                }
742
            }
743
 
744
          if (p->f != NULL)
745
            {
746
              skip_to_line (p, line, TRUE);
747
              *pp = p->next;
748
              p->next = print_files;
749
              print_files = p;
750
            }
751
        }
752
      else
753
        {
754
          FILE *f;
755
 
756
          f = fopen (filename, "r");
757
          if (f != NULL)
758
            {
759
              int l;
760
 
761
              p = ((struct print_file_list *)
762
                   xmalloc (sizeof (struct print_file_list)));
763
              p->filename = xmalloc (strlen (filename) + 1);
764
              strcpy (p->filename, filename);
765
              p->line = 0;
766
              p->f = f;
767
 
768
              if (print_files != NULL && print_files->f != NULL)
769
                {
770
                  fclose (print_files->f);
771
                  print_files->f = NULL;
772
                }
773
              p->next = print_files;
774
              print_files = p;
775
 
776
              if (file_start_context)
777
                l = 0;
778
              else
779
                l = line - SHOW_PRECEDING_CONTEXT_LINES;
780
              if (l < 0)
781
                l = 0;
782
              skip_to_line (p, l, FALSE);
783
              if (p->f != NULL)
784
                skip_to_line (p, line, TRUE);
785
            }
786
        }
787
    }
788
 
789
  if (functionname != NULL
790
      && (prev_functionname == NULL
791
          || strcmp (functionname, prev_functionname) != 0))
792
    {
793
      if (prev_functionname != NULL)
794
        free (prev_functionname);
795
      prev_functionname = xmalloc (strlen (functionname) + 1);
796
      strcpy (prev_functionname, functionname);
797
    }
798
 
799
  if (line > 0 && line != prev_line)
800
    prev_line = line;
801
}
802
 
803
 
804
 
805
 
806
 
807
 
808
 
809
 
810
 
811
 
812
/* Disassemble some data in memory between given values.  */
813
 
814
static void
815
disassemble_bytes (info, disassemble_fn, insns, data,
816
                   start_offset, stop_offset, relppp,
817
                   relppend)
818
     struct disassemble_info *info;
819
     disassembler_ftype disassemble_fn;
820
     bfd_boolean insns;
821
     bfd_byte *data;
822
     bfd_vma start_offset;
823
     bfd_vma stop_offset;
824
     arelent ***relppp;
825
     arelent **relppend;
826
{
827
  struct objdump_disasm_info *aux;
828
  asection *section;
829
  int octets_per_line;
830
  bfd_boolean done_dot;
831
  int skip_addr_chars;
832
  bfd_vma addr_offset;
833
  int opb = info->octets_per_byte;
834
 
835
  aux = (struct objdump_disasm_info *) info->application_data;
836
  section = aux->sec;
837
 
838
  if (insns)
839
    octets_per_line = 4;
840
  else
841
    octets_per_line = 16;
842
 
843
  /* Figure out how many characters to skip at the start of an
844
     address, to make the disassembly look nicer.  We discard leading
845
     zeroes in chunks of 4, ensuring that there is always a leading
846
     zero remaining.  */
847
  skip_addr_chars = 0;
848
  if (! prefix_addresses)
849
    {
850
      char buf[30];
851
      char *s;
852
 
853
      bfd_sprintf_vma
854
        (aux->abfd, buf,
855
         (section->vma
856
          + bfd_section_size (section->owner, section) / opb));
857
      s = buf;
858
      while (s[0] == '0' && s[1] == '0' && s[2] == '0' && s[3] == '0'
859
             && s[4] == '0')
860
        {
861
          skip_addr_chars += 4;
862
          s += 4;
863
        }
864
    }
865
 
866
  info->insn_info_valid = 0;
867
 
868
  done_dot = FALSE;
869
  addr_offset = start_offset;
870
  while (addr_offset < stop_offset)
871
    {
872
      bfd_vma z;
873
      int octets = 0;
874
      bfd_boolean need_nl = FALSE;
875
 
876
      /* If we see more than SKIP_ZEROES octets of zeroes, we just
877
         print `...'.  */
878
      for (z = addr_offset * opb; z < stop_offset * opb; z++)
879
        if (data[z] != 0)
880
          break;
881
      if (! disassemble_zeroes
882
          && (info->insn_info_valid == 0
883
              || info->branch_delay_insns == 0)
884
          && (z - addr_offset * opb >= SKIP_ZEROES
885
              || (z == stop_offset * opb &&
886
                  z - addr_offset * opb < SKIP_ZEROES_AT_END)))
887
        {
888
          printf ("\t...\n");
889
 
890
          /* If there are more nonzero octets to follow, we only skip
891
             zeroes in multiples of 4, to try to avoid running over
892
             the start of an instruction which happens to start with
893
             zero.  */
894
          if (z != stop_offset * opb)
895
            z = addr_offset * opb + ((z - addr_offset * opb) &~ 3);
896
 
897
          octets = z - addr_offset * opb;
898
        }
899
      else
900
        {
901
          char buf[50];
902
          SFILE sfile;
903
          int bpc = 0;
904
          int pb = 0;
905
 
906
          done_dot = FALSE;
907
 
908
          if (with_line_numbers || with_source_code)
909
            /* The line number tables will refer to unadjusted
910
               section VMAs, so we must undo any VMA modifications
911
               when calling show_line.  */
912
            show_line (aux->abfd, section, addr_offset - adjust_section_vma);
913
 
914
          if (! prefix_addresses)
915
            {
916
              char *s;
917
 
918
              bfd_sprintf_vma (aux->abfd, buf, section->vma + addr_offset);
919
              for (s = buf + skip_addr_chars; *s == '0'; s++)
920
                *s = ' ';
921
              if (*s == '\0')
922
                *--s = '0';
923
              printf ("%s:\t", buf + skip_addr_chars);
924
            }
925
          else
926
            {
927
              aux->require_sec = TRUE;
928
              objdump_print_address (section->vma + addr_offset, info);
929
              aux->require_sec = FALSE;
930
              putchar (' ');
931
            }
932
 
933
          if (insns)
934
            {
935
              sfile.size = 120;
936
              sfile.buffer = xmalloc (sfile.size);
937
              sfile.current = sfile.buffer;
938
              info->fprintf_func = (fprintf_ftype) objdump_sprintf;
939
              info->stream = (FILE *) &sfile;
940
              info->bytes_per_line = 0;
941
              info->bytes_per_chunk = 0;
942
 
943
#ifdef DISASSEMBLER_NEEDS_RELOCS
944
              /* FIXME: This is wrong.  It tests the number of octets
945
                 in the last instruction, not the current one.  */
946
              if (*relppp < relppend
947
                  && (**relppp)->address >= addr_offset
948
                  && (**relppp)->address <= addr_offset + octets / opb)
949
                info->flags = INSN_HAS_RELOC;
950
              else
951
#endif
952
                info->flags = 0;
953
 
954
              octets = (*disassemble_fn) (section->vma + addr_offset, info);
955
              info->fprintf_func = (fprintf_ftype) fprintf;
956
              info->stream = stdout;
957
              if (info->bytes_per_line != 0)
958
                octets_per_line = info->bytes_per_line;
959
              if (octets < 0)
960
                {
961
                  if (sfile.current != sfile.buffer)
962
                    printf ("%s\n", sfile.buffer);
963
                  free (sfile.buffer);
964
                  break;
965
                }
966
            }
967
          else
968
            {
969
              bfd_vma j;
970
 
971
              octets = octets_per_line;
972
              if (addr_offset + octets / opb > stop_offset)
973
                octets = (stop_offset - addr_offset) * opb;
974
 
975
              for (j = addr_offset * opb; j < addr_offset * opb + octets; ++j)
976
                {
977
                  if (isprint (data[j]))
978
                    buf[j - addr_offset * opb] = data[j];
979
                  else
980
                    buf[j - addr_offset * opb] = '.';
981
                }
982
              buf[j - addr_offset * opb] = '\0';
983
            }
984
 
985
          if (prefix_addresses
986
              ? show_raw_insn > 0
987
              : show_raw_insn >= 0)
988
            {
989
              bfd_vma j;
990
 
991
              /* If ! prefix_addresses and ! wide_output, we print
992
                 octets_per_line octets per line.  */
993
              pb = octets;
994
              if (pb > octets_per_line && ! prefix_addresses && ! wide_output)
995
                pb = octets_per_line;
996
 
997
              if (info->bytes_per_chunk)
998
                bpc = info->bytes_per_chunk;
999
              else
1000
                bpc = 1;
1001
 
1002
              for (j = addr_offset * opb; j < addr_offset * opb + pb; j += bpc)
1003
                {
1004
                  int k;
1005
                  if (bpc > 1 && info->display_endian == BFD_ENDIAN_LITTLE)
1006
                    {
1007
                      for (k = bpc - 1; k >= 0; k--)
1008
                        printf ("%02x", (unsigned) data[j + k]);
1009
                      putchar (' ');
1010
                    }
1011
                  else
1012
                    {
1013
                      for (k = 0; k < bpc; k++)
1014
                        printf ("%02x", (unsigned) data[j + k]);
1015
                      putchar (' ');
1016
                    }
1017
                }
1018
 
1019
              for (; pb < octets_per_line; pb += bpc)
1020
                {
1021
                  int k;
1022
 
1023
                  for (k = 0; k < bpc; k++)
1024
                    printf ("  ");
1025
                  putchar (' ');
1026
                }
1027
 
1028
              /* Separate raw data from instruction by extra space.  */
1029
              if (insns)
1030
                putchar ('\t');
1031
              else
1032
                printf ("    ");
1033
            }
1034
 
1035
          if (! insns)
1036
            printf ("%s", buf);
1037
          else
1038
            {
1039
              printf ("%s", sfile.buffer);
1040
              free (sfile.buffer);
1041
            }
1042
 
1043
          if (prefix_addresses
1044
              ? show_raw_insn > 0
1045
              : show_raw_insn >= 0)
1046
            {
1047
              while (pb < octets)
1048
                {
1049
                  bfd_vma j;
1050
                  char *s;
1051
 
1052
                  putchar ('\n');
1053
                  j = addr_offset * opb + pb;
1054
 
1055
                  bfd_sprintf_vma (aux->abfd, buf, section->vma + j / opb);
1056
                  for (s = buf + skip_addr_chars; *s == '0'; s++)
1057
                    *s = ' ';
1058
                  if (*s == '\0')
1059
                    *--s = '0';
1060
                  printf ("%s:\t", buf + skip_addr_chars);
1061
 
1062
                  pb += octets_per_line;
1063
                  if (pb > octets)
1064
                    pb = octets;
1065
                  for (; j < addr_offset * opb + pb; j += bpc)
1066
                    {
1067
                      int k;
1068
 
1069
                      if (bpc > 1 && info->display_endian == BFD_ENDIAN_LITTLE)
1070
                        {
1071
                          for (k = bpc - 1; k >= 0; k--)
1072
                            printf ("%02x", (unsigned) data[j + k]);
1073
                          putchar (' ');
1074
                        }
1075
                      else
1076
                        {
1077
                          for (k = 0; k < bpc; k++)
1078
                            printf ("%02x", (unsigned) data[j + k]);
1079
                          putchar (' ');
1080
                        }
1081
                    }
1082
                }
1083
            }
1084
 
1085
          if (!wide_output)
1086
            putchar ('\n');
1087
          else
1088
            need_nl = TRUE;
1089
        }
1090
 
1091
      if ((section->flags & SEC_RELOC) != 0
1092
#ifndef DISASSEMBLER_NEEDS_RELOCS
1093
          && dump_reloc_info
1094
#endif
1095
          )
1096
        {
1097
          while ((*relppp) < relppend
1098
                 && ((**relppp)->address >= (bfd_vma) addr_offset
1099
                     && (**relppp)->address < (bfd_vma) addr_offset + octets / opb))
1100
#ifdef DISASSEMBLER_NEEDS_RELOCS
1101
            if (! dump_reloc_info)
1102
              ++(*relppp);
1103
            else
1104
#endif
1105
            {
1106
              arelent *q;
1107
 
1108
              q = **relppp;
1109
 
1110
              if (wide_output)
1111
                putchar ('\t');
1112
              else
1113
                printf ("\t\t\t");
1114
 
1115
              objdump_print_value (section->vma + q->address, info, TRUE);
1116
 
1117
              printf (": %s\t", q->howto->name);
1118
 
1119
              if (q->sym_ptr_ptr == NULL || *q->sym_ptr_ptr == NULL)
1120
                printf ("*unknown*");
1121
              else
1122
                {
1123
                  const char *sym_name;
1124
 
1125
                  sym_name = bfd_asymbol_name (*q->sym_ptr_ptr);
1126
                  if (sym_name != NULL && *sym_name != '\0')
1127
                    objdump_print_symname (aux->abfd, info, *q->sym_ptr_ptr);
1128
                  else
1129
                    {
1130
                      asection *sym_sec;
1131
 
1132
                      sym_sec = bfd_get_section (*q->sym_ptr_ptr);
1133
                      sym_name = bfd_get_section_name (aux->abfd, sym_sec);
1134
                      if (sym_name == NULL || *sym_name == '\0')
1135
                        sym_name = "*unknown*";
1136
                      printf ("%s", sym_name);
1137
                    }
1138
                }
1139
 
1140
              if (q->addend)
1141
                {
1142
                  printf ("+0x");
1143
                  objdump_print_value (q->addend, info, TRUE);
1144
                }
1145
 
1146
              printf ("\n");
1147
              need_nl = FALSE;
1148
              ++(*relppp);
1149
            }
1150
        }
1151
 
1152
      if (need_nl)
1153
        printf ("\n");
1154
 
1155
      addr_offset += octets / opb;
1156
    }
1157
}
1158
 
1159
 
1160
 
1161
 
1162
 
1163
 
1164
 
1165
/* Disassemble the contents of an object file.  */
1166
 
1167
static void
1168
disassemble_data (abfd)
1169
     bfd *abfd;
1170
{
1171
  unsigned long addr_offset;
1172
  disassembler_ftype disassemble_fn;
1173
  struct disassemble_info disasm_info;
1174
  struct objdump_disasm_info aux;
1175
  asection *section;
1176
  unsigned int opb;
1177
 
1178
  print_files = NULL;
1179
  prev_functionname = NULL;
1180
  prev_line = -1;
1181
 
1182
  /* We make a copy of syms to sort.  We don't want to sort syms
1183
     because that will screw up the relocs.  */
1184
  sorted_syms = (asymbol **) xmalloc (symcount * sizeof (asymbol *));
1185
  memcpy (sorted_syms, syms, symcount * sizeof (asymbol *));
1186
 
1187
  sorted_symcount = remove_useless_symbols (sorted_syms, symcount);
1188
 
1189
  /* Sort the symbols into section and symbol order.  */
1190
  qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
1191
 
1192
  INIT_DISASSEMBLE_INFO (disasm_info, stdout, fprintf);
1193
 
1194
  disasm_info.application_data = (PTR) &aux;
1195
  aux.abfd = abfd;
1196
  aux.require_sec = FALSE;
1197
  disasm_info.print_address_func = objdump_print_address;
1198
  disasm_info.symbol_at_address_func = objdump_symbol_at_address;
1199
 
1200
  if (machine != (char *) NULL)
1201
    {
1202
      const bfd_arch_info_type *info = bfd_scan_arch (machine);
1203
 
1204
      if (info == NULL)
1205
        fatal ("Can't use supplied machine %s", machine);
1206
 
1207
      abfd->arch_info = info;
1208
    }
1209
 
1210
  if (endian != BFD_ENDIAN_UNKNOWN)
1211
    {
1212
      struct bfd_target *xvec;
1213
 
1214
      xvec = (struct bfd_target *) xmalloc (sizeof (struct bfd_target));
1215
      memcpy (xvec, abfd->xvec, sizeof (struct bfd_target));
1216
      xvec->byteorder = endian;
1217
      abfd->xvec = xvec;
1218
    }
1219
 
1220
  disassemble_fn = disassembler (abfd);
1221
  if (!disassemble_fn)
1222
    {
1223
      non_fatal ("Can't disassemble for architecture %s\n",
1224
                 bfd_printable_arch_mach (bfd_get_arch (abfd), 0));
1225
      exit_status = 1;
1226
      return;
1227
    }
1228
 
1229
  opb = bfd_octets_per_byte (abfd);
1230
 
1231
  disasm_info.flavour = bfd_get_flavour (abfd);
1232
  disasm_info.arch = bfd_get_arch (abfd);
1233
  disasm_info.mach = bfd_get_mach (abfd);
1234
  disasm_info.disassembler_options = disassembler_options;
1235
  disasm_info.octets_per_byte = opb;
1236
 
1237
  if (bfd_big_endian (abfd))
1238
    disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_BIG;
1239
  else if (bfd_little_endian (abfd))
1240
    disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_LITTLE;
1241
  else
1242
    /* ??? Aborting here seems too drastic.  We could default to big or little
1243
       instead.  */
1244
    disasm_info.endian = BFD_ENDIAN_UNKNOWN;
1245
 
1246
  for (section = abfd->sections;
1247
       section != (asection *) NULL;
1248
       section = section->next)
1249
    {
1250
      bfd_byte *data = NULL;
1251
      bfd_size_type datasize = 0;
1252
      arelent **relbuf = NULL;
1253
      arelent **relpp = NULL;
1254
      arelent **relppend = NULL;
1255
      unsigned long stop_offset;
1256
      asymbol *sym = NULL;
1257
      long place = 0;
1258
 
1259
      if ((section->flags & SEC_LOAD) == 0
1260
          || (! disassemble_all
1261
              && only == NULL
1262
              && (section->flags & SEC_CODE) == 0))
1263
        continue;
1264
      if (only != (char *) NULL && strcmp (only, section->name) != 0)
1265
        continue;
1266
 
1267
      if ((section->flags & SEC_RELOC) != 0
1268
#ifndef DISASSEMBLER_NEEDS_RELOCS
1269
          && dump_reloc_info
1270
#endif
1271
          )
1272
        {
1273
          long relsize;
1274
 
1275
          relsize = bfd_get_reloc_upper_bound (abfd, section);
1276
          if (relsize < 0)
1277
            bfd_fatal (bfd_get_filename (abfd));
1278
 
1279
          if (relsize > 0)
1280
            {
1281
              long relcount;
1282
 
1283
              relbuf = (arelent **) xmalloc (relsize);
1284
              relcount = bfd_canonicalize_reloc (abfd, section, relbuf, syms);
1285
              if (relcount < 0)
1286
                bfd_fatal (bfd_get_filename (abfd));
1287
 
1288
              /* Sort the relocs by address.  */
1289
              qsort (relbuf, relcount, sizeof (arelent *), compare_relocs);
1290
 
1291
              relpp = relbuf;
1292
              relppend = relpp + relcount;
1293
 
1294
              /* Skip over the relocs belonging to addresses below the
1295
                 start address.  */
1296
              if (start_address != (bfd_vma) -1)
1297
                while (relpp < relppend
1298
                       && (*relpp)->address < start_address)
1299
                  ++relpp;
1300
            }
1301
        }
1302
 
1303
      printf ("Disassembly of section %s:\n", section->name);
1304
 
1305
      datasize = bfd_get_section_size_before_reloc (section);
1306
      if (datasize == 0)
1307
        continue;
1308
 
1309
      data = (bfd_byte *) xmalloc ((size_t) datasize);
1310
 
1311
      bfd_get_section_contents (abfd, section, data, 0, datasize);
1312
 
1313
      aux.sec = section;
1314
      disasm_info.buffer = data;
1315
      disasm_info.buffer_vma = section->vma;
1316
      disasm_info.buffer_length = datasize;
1317
      disasm_info.section = section;
1318
 
1319
      if (start_address == (bfd_vma) -1
1320
          || start_address < disasm_info.buffer_vma)
1321
        addr_offset = 0;
1322
      else
1323
        addr_offset = start_address - disasm_info.buffer_vma;
1324
 
1325
      if (stop_address == (bfd_vma) -1)
1326
        stop_offset = datasize / opb;
1327
      else
1328
        {
1329
          if (stop_address < disasm_info.buffer_vma)
1330
            stop_offset = 0;
1331
          else
1332
            stop_offset = stop_address - disasm_info.buffer_vma;
1333
          if (stop_offset > disasm_info.buffer_length / opb)
1334
            stop_offset = disasm_info.buffer_length / opb;
1335
        }
1336
 
1337
      sym = find_symbol_for_address (abfd, section, section->vma + addr_offset,
1338
                                     TRUE, &place);
1339
 
1340
      while (addr_offset < stop_offset)
1341
        {
1342
          asymbol *nextsym;
1343
          unsigned long nextstop_offset;
1344
          bfd_boolean insns;
1345
 
1346
          if (sym != NULL && bfd_asymbol_value (sym) <= section->vma + addr_offset)
1347
            {
1348
              int x;
1349
 
1350
              for (x = place;
1351
                   (x < sorted_symcount
1352
                    && bfd_asymbol_value (sorted_syms[x]) <= section->vma + addr_offset);
1353
                   ++x)
1354
                continue;
1355
 
1356
              disasm_info.symbols = & sorted_syms[place];
1357
              disasm_info.num_symbols = x - place;
1358
            }
1359
          else
1360
            disasm_info.symbols = NULL;
1361
 
1362
          if (! prefix_addresses)
1363
            {
1364
              (* disasm_info.fprintf_func) (disasm_info.stream, "\n");
1365
              objdump_print_addr_with_sym (abfd, section, sym,
1366
                                           section->vma + addr_offset,
1367
                                           &disasm_info,
1368
                                           FALSE);
1369
              (* disasm_info.fprintf_func) (disasm_info.stream, ":\n");
1370
            }
1371
 
1372
          if (sym != NULL && bfd_asymbol_value (sym) > section->vma + addr_offset)
1373
            nextsym = sym;
1374
          else if (sym == NULL)
1375
            nextsym = NULL;
1376
          else
1377
            {
1378
              /* Search forward for the next appropriate symbol in
1379
                 SECTION.  Note that all the symbols are sorted
1380
                 together into one big array, and that some sections
1381
                 may have overlapping addresses.  */
1382
              while (place < sorted_symcount
1383
                     && (sorted_syms[place]->section != section
1384
                         || (bfd_asymbol_value (sorted_syms[place])
1385
                             <= bfd_asymbol_value (sym))))
1386
                ++place;
1387
              if (place >= sorted_symcount)
1388
                nextsym = NULL;
1389
              else
1390
                nextsym = sorted_syms[place];
1391
            }
1392
 
1393
          if (sym != NULL && bfd_asymbol_value (sym) > section->vma + addr_offset)
1394
            {
1395
              nextstop_offset = bfd_asymbol_value (sym) - section->vma;
1396
              if (nextstop_offset > stop_offset)
1397
                nextstop_offset = stop_offset;
1398
            }
1399
          else if (nextsym == NULL)
1400
            nextstop_offset = stop_offset;
1401
          else
1402
            {
1403
              nextstop_offset = bfd_asymbol_value (nextsym) - section->vma;
1404
              if (nextstop_offset > stop_offset)
1405
                nextstop_offset = stop_offset;
1406
            }
1407
 
1408
          /* If a symbol is explicitly marked as being an object
1409
             rather than a function, just dump the bytes without
1410
             disassembling them.  */
1411
          if (disassemble_all
1412
              || sym == NULL
1413
              || bfd_asymbol_value (sym) > section->vma + addr_offset
1414
              || ((sym->flags & BSF_OBJECT) == 0
1415
                  && (strstr (bfd_asymbol_name (sym), "gnu_compiled")
1416
                      == NULL)
1417
                  && (strstr (bfd_asymbol_name (sym), "gcc2_compiled")
1418
                      == NULL))
1419
              || (sym->flags & BSF_FUNCTION) != 0)
1420
            insns = TRUE;
1421
          else
1422
            insns = FALSE;
1423
 
1424
          disassemble_bytes (&disasm_info, disassemble_fn, insns, data,
1425
                             addr_offset, nextstop_offset, &relpp, relppend);
1426
 
1427
          addr_offset = nextstop_offset;
1428
          sym = nextsym;
1429
        }
1430
 
1431
      free (data);
1432
 
1433
      if (relbuf != NULL)
1434
        free (relbuf);
1435
    }
1436
  free (sorted_syms);
1437
}
1438
 
1439
 
1440
 
1441
 
1442
 
1443
 
1444
 
1445
 
1446
 
1447
 
1448
 
1449
 
1450
 
1451
 
1452
 
1453
 
1454
 
1455
 
1456
 
1457
 
1458
 
1459
 
1460
 
1461
static asymbol **
1462
slurp_symtab (abfd)
1463
     bfd *abfd;
1464
{
1465
  asymbol **sy = (asymbol **) NULL;
1466
  long storage;
1467
 
1468
  if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
1469
    {
1470
      symcount = 0;
1471
      return NULL;
1472
    }
1473
 
1474
  storage = bfd_get_symtab_upper_bound (abfd);
1475
  if (storage < 0)
1476
    bfd_fatal (bfd_get_filename (abfd));
1477
  if (storage)
1478
    sy = (asymbol **) xmalloc (storage);
1479
 
1480
  symcount = bfd_canonicalize_symtab (abfd, sy);
1481
  if (symcount < 0)
1482
    bfd_fatal (bfd_get_filename (abfd));
1483
  return sy;
1484
}
1485
 
1486
/* Read in the dynamic symbols.  */
1487
 
1488
static asymbol **
1489
slurp_dynamic_symtab (abfd)
1490
     bfd *abfd;
1491
{
1492
  asymbol **sy = (asymbol **) NULL;
1493
  long storage;
1494
 
1495
  storage = bfd_get_dynamic_symtab_upper_bound (abfd);
1496
  if (storage < 0)
1497
    {
1498
      if (!(bfd_get_file_flags (abfd) & DYNAMIC))
1499
        {
1500
          non_fatal ("%s: not a dynamic object", bfd_get_filename (abfd));
1501
          dynsymcount = 0;
1502
          return NULL;
1503
        }
1504
 
1505
      bfd_fatal (bfd_get_filename (abfd));
1506
    }
1507
  if (storage)
1508
    sy = (asymbol **) xmalloc (storage);
1509
 
1510
  dynsymcount = bfd_canonicalize_dynamic_symtab (abfd, sy);
1511
  if (dynsymcount < 0)
1512
    bfd_fatal (bfd_get_filename (abfd));
1513
  return sy;
1514
}
1515
 
1516
 
1517
 
1518
 
1519
static void
1520
dump_symbols (abfd, dynamic)
1521
     bfd *abfd ATTRIBUTE_UNUSED;
1522
     bfd_boolean dynamic;
1523
{
1524
  asymbol **current;
1525
  long max;
1526
  long count;
1527
 
1528
  if (dynamic)
1529
    {
1530
      current = dynsyms;
1531
      max = dynsymcount;
1532
      printf ("DYNAMIC SYMBOL TABLE:\n");
1533
    }
1534
  else
1535
    {
1536
      current = syms;
1537
      max = symcount;
1538
      printf ("SYMBOL TABLE:\n");
1539
    }
1540
 
1541
  if (max == 0)
1542
    printf ("no symbols\n");
1543
 
1544
  for (count = 0; count < max; count++)
1545
    {
1546
      if (*current)
1547
        {
1548
          bfd *cur_bfd = bfd_asymbol_bfd (*current);
1549
 
1550
          if (cur_bfd != NULL)
1551
            {
1552
              const char *name;
1553
              char *alloc;
1554
 
1555
              name = (*current)->name;
1556
              alloc = NULL;
1557
              //if (do_demangle && name != NULL && *name != '\0')
1558
              //        {
1559
                  /* If we want to demangle the name, we demangle it
1560
                     here, and temporarily clobber it while calling
1561
                     bfd_print_symbol.  FIXME: This is a gross hack.  */
1562
                  //alloc = demangle (cur_bfd, name);
1563
                  //(*current)->name = alloc;
1564
                  //}
1565
 
1566
              bfd_print_symbol (cur_bfd, stdout, *current,
1567
                                bfd_print_symbol_all);
1568
 
1569
              (*current)->name = name;
1570
              if (alloc != NULL)
1571
                free (alloc);
1572
 
1573
              printf ("\n");
1574
            }
1575
        }
1576
      current++;
1577
    }
1578
  printf ("\n");
1579
  printf ("\n");
1580
}
1581
 
1582
 
1583
 
1584
static void
1585
dump_section_header (abfd, section, ignored)
1586
     bfd *abfd ATTRIBUTE_UNUSED;
1587
     asection *section;
1588
     PTR ignored ATTRIBUTE_UNUSED;
1589
{
1590
  char *comma = "";
1591
  unsigned int opb = bfd_octets_per_byte (abfd);
1592
 
1593
  printf ("%3d %-13s %08lx  ", section->index,
1594
          bfd_get_section_name (abfd, section),
1595
          (unsigned long) bfd_section_size (abfd, section) / opb);
1596
  bfd_printf_vma (abfd, bfd_get_section_vma (abfd, section));
1597
  printf ("  ");
1598
  bfd_printf_vma (abfd, section->lma);
1599
  printf ("  %08lx  2**%u", (unsigned long) section->filepos,
1600
          bfd_get_section_alignment (abfd, section));
1601
  if (! wide_output)
1602
    printf ("\n                ");
1603
  printf ("  ");
1604
 
1605
#define PF(x, y) \
1606
  if (section->flags & x) { printf ("%s%s", comma, y); comma = ", "; }
1607
 
1608
  PF (SEC_HAS_CONTENTS, "CONTENTS");
1609
  PF (SEC_ALLOC, "ALLOC");
1610
  PF (SEC_CONSTRUCTOR, "CONSTRUCTOR");
1611
  PF (SEC_LOAD, "LOAD");
1612
  PF (SEC_RELOC, "RELOC");
1613
  PF (SEC_READONLY, "READONLY");
1614
  PF (SEC_CODE, "CODE");
1615
  PF (SEC_DATA, "DATA");
1616
  PF (SEC_ROM, "ROM");
1617
  PF (SEC_DEBUGGING, "DEBUGGING");
1618
  PF (SEC_NEVER_LOAD, "NEVER_LOAD");
1619
  PF (SEC_EXCLUDE, "EXCLUDE");
1620
  PF (SEC_SORT_ENTRIES, "SORT_ENTRIES");
1621
  PF (SEC_BLOCK, "BLOCK");
1622
  PF (SEC_CLINK, "CLINK");
1623
  PF (SEC_SMALL_DATA, "SMALL_DATA");
1624
  PF (SEC_SHARED, "SHARED");
1625
  PF (SEC_ARCH_BIT_0, "ARCH_BIT_0");
1626
  PF (SEC_THREAD_LOCAL, "THREAD_LOCAL");
1627
 
1628
  if ((section->flags & SEC_LINK_ONCE) != 0)
1629
    {
1630
      const char *ls;
1631
 
1632
      switch (section->flags & SEC_LINK_DUPLICATES)
1633
        {
1634
        default:
1635
          abort ();
1636
        case SEC_LINK_DUPLICATES_DISCARD:
1637
          ls = "LINK_ONCE_DISCARD";
1638
          break;
1639
        case SEC_LINK_DUPLICATES_ONE_ONLY:
1640
          ls = "LINK_ONCE_ONE_ONLY";
1641
          break;
1642
        case SEC_LINK_DUPLICATES_SAME_SIZE:
1643
          ls = "LINK_ONCE_SAME_SIZE";
1644
          break;
1645
        case SEC_LINK_DUPLICATES_SAME_CONTENTS:
1646
          ls = "LINK_ONCE_SAME_CONTENTS";
1647
          break;
1648
        }
1649
      printf ("%s%s", comma, ls);
1650
 
1651
      if (section->comdat != NULL)
1652
        printf (" (COMDAT %s %ld)", section->comdat->name,
1653
                section->comdat->symbol);
1654
 
1655
      comma = ", ";
1656
    }
1657
 
1658
  printf ("\n");
1659
#undef PF
1660
}
1661
 
1662
 
1663
 
1664
static void
1665
dump_headers (abfd)
1666
     bfd *abfd;
1667
{
1668
  printf ("Sections:\n");
1669
 
1670
#ifndef BFD64
1671
  printf ("Idx Name          Size      VMA       LMA       File off  Algn");
1672
#else
1673
  /* With BFD64, non-ELF returns -1 and wants always 64 bit addresses.  */
1674
  if (bfd_get_arch_size (abfd) == 32)
1675
    printf ("Idx Name          Size      VMA       LMA       File off  Algn");
1676
  else
1677
    printf ("Idx Name          Size      VMA               LMA               File off  Algn");
1678
#endif
1679
 
1680
  if (wide_output)
1681
    printf ("  Flags");
1682
  if (abfd->flags & HAS_LOAD_PAGE)
1683
    printf ("  Pg");
1684
  printf ("\n");
1685
 
1686
  bfd_map_over_sections (abfd, dump_section_header, (PTR) NULL);
1687
}
1688
 
1689
 
1690
static void
1691
dump_bfd_header (abfd)
1692
     bfd *abfd;
1693
{
1694
  char *comma = "";
1695
 
1696
  printf ("architecture: %s, ",
1697
          bfd_printable_arch_mach (bfd_get_arch (abfd),
1698
                                   bfd_get_mach (abfd)));
1699
  printf ("flags 0x%08x:\n", abfd->flags);
1700
 
1701
#define PF(x, y)    if (abfd->flags & x) {printf("%s%s", comma, y); comma=", ";}
1702
  PF (HAS_RELOC, "HAS_RELOC");
1703
  PF (EXEC_P, "EXEC_P");
1704
  PF (HAS_LINENO, "HAS_LINENO");
1705
  PF (HAS_DEBUG, "HAS_DEBUG");
1706
  PF (HAS_SYMS, "HAS_SYMS");
1707
  PF (HAS_LOCALS, "HAS_LOCALS");
1708
  PF (DYNAMIC, "DYNAMIC");
1709
  PF (WP_TEXT, "WP_TEXT");
1710
  PF (D_PAGED, "D_PAGED");
1711
  PF (BFD_IS_RELAXABLE, "BFD_IS_RELAXABLE");
1712
  PF (HAS_LOAD_PAGE, "HAS_LOAD_PAGE");
1713
  printf ("\nstart address 0x");
1714
  bfd_printf_vma (abfd, abfd->start_address);
1715
  printf ("\n");
1716
}
1717
 
1718
 
1719
 
1720
 
1721
 
1722
static void
1723
l1_read_data (abfd)
1724
     bfd *abfd;
1725
{
1726
  asection *section;
1727
  bfd_byte *data = 0;
1728
  bfd_size_type datasize = 0;
1729
  bfd_size_type addr_offset;
1730
  bfd_size_type start_offset, stop_offset;
1731
  unsigned int opb = bfd_octets_per_byte (abfd);
1732
 
1733
  dump_bfd_header (abfd);
1734
  dump_headers (abfd);
1735
 
1736
  syms = slurp_symtab (abfd);
1737
  dynsyms = slurp_dynamic_symtab (abfd);
1738
 
1739
  dump_symbols (abfd, 0);
1740
  disassemble_data (abfd);
1741
 
1742
  for (section = abfd->sections; section != NULL; section =
1743
       section->next)
1744
    {
1745
      int onaline = 16;
1746
 
1747
      if (only == (char *) NULL ||
1748
          strcmp (only, section->name) == 0)
1749
        {
1750
          if (section->flags & SEC_HAS_CONTENTS)
1751
            {
1752
              char buf[64];
1753
              int count, width;
1754
 
1755
              printf ("Contents of section %s:\n", section->name);
1756
 
1757
              if (bfd_section_size (abfd, section) == 0)
1758
                continue;
1759
              data = (bfd_byte *) xmalloc ((size_t) bfd_section_size (abfd, section));
1760
              datasize = bfd_section_size (abfd, section);
1761
 
1762
 
1763
              bfd_get_section_contents (abfd, section, (PTR) data, 0, bfd_section_size (abfd, section));
1764
 
1765
              if (start_address == (bfd_vma) -1
1766
                  || start_address < section->vma)
1767
                start_offset = 0;
1768
              else
1769
                start_offset = start_address - section->vma;
1770
              if (stop_address == (bfd_vma) -1)
1771
                stop_offset = bfd_section_size (abfd, section) / opb;
1772
              else
1773
                {
1774
                  if (stop_address < section->vma)
1775
                    stop_offset = 0;
1776
                  else
1777
                    stop_offset = stop_address - section->vma;
1778
                  if (stop_offset > bfd_section_size (abfd, section) / opb)
1779
                    stop_offset = bfd_section_size (abfd, section) / opb;
1780
                }
1781
 
1782
              width = 4;
1783
 
1784
              bfd_sprintf_vma (abfd, buf, start_offset + section->vma);
1785
              if (strlen (buf) >= sizeof (buf))
1786
                abort ();
1787
              count = 0;
1788
              while (buf[count] == '0' && buf[count+1] != '\0')
1789
                count++;
1790
              count = strlen (buf) - count;
1791
              if (count > width)
1792
                width = count;
1793
 
1794
              bfd_sprintf_vma (abfd, buf, stop_offset + section->vma - 1);
1795
              if (strlen (buf) >= sizeof (buf))
1796
                abort ();
1797
              count = 0;
1798
              while (buf[count] == '0' && buf[count+1] != '\0')
1799
                count++;
1800
              count = strlen (buf) - count;
1801
              if (count > width)
1802
                width = count;
1803
 
1804
              for (addr_offset = start_offset;
1805
                   addr_offset < stop_offset; addr_offset += onaline / opb)
1806
                {
1807
                  bfd_size_type j;
1808
 
1809
                  bfd_sprintf_vma (abfd, buf, (addr_offset + section->vma));
1810
                  count = strlen (buf);
1811
                  if (count >= sizeof (buf))
1812
                    abort ();
1813
                  putchar (' ');
1814
                  while (count < width)
1815
                    {
1816
                      putchar ('0');
1817
                      count++;
1818
                    }
1819
                  fputs (buf + count - width, stdout);
1820
                  putchar (' ');
1821
 
1822
                  for (j = addr_offset * opb;
1823
                       j < addr_offset * opb + onaline; j++)
1824
                    {
1825
                      if (j < stop_offset * opb)
1826
                        printf ("%02x", (unsigned) (data[j]));
1827
                      else
1828
                        printf ("  ");
1829
                      if ((j & 3) == 3)
1830
                        printf (" ");
1831
                    }
1832
 
1833
                  printf (" ");
1834
                  for (j = addr_offset * opb;
1835
                       j < addr_offset * opb + onaline; j++)
1836
                    {
1837
                      if (j >= stop_offset * opb)
1838
                        printf (" ");
1839
                      else
1840
                        printf ("%c", isprint (data[j]) ? data[j] : '.');
1841
                    }
1842
                  putchar ('\n');
1843
                }
1844
              free (data);
1845
            }
1846
        }
1847
    }
1848
}
1849
 
1850
 
1851
static void
1852
l1_read_bfd (abfd)
1853
     bfd *abfd;
1854
{
1855
  char **matching;
1856
 
1857
  printf ("\n%s:     file format %s\n", bfd_get_filename (abfd),
1858
          abfd->xvec->name);
1859
 
1860
  if (bfd_check_format_matches (abfd, bfd_object, &matching))
1861
    {
1862
      l1_read_data (abfd);
1863
      return;
1864
    }
1865
 
1866
  if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1867
    {
1868
      nonfatal (bfd_get_filename (abfd));
1869
      list_matching_formats (matching);
1870
      free (matching);
1871
 
1872
 
1873
      //read_exe (char *filename, char *target) {
1874
 
1875
 
1876
      return;
1877
    }
1878
 
1879
  if (bfd_get_error () != bfd_error_file_not_recognized)
1880
    {
1881
      nonfatal (bfd_get_filename (abfd));
1882
      return;
1883
    }
1884
 
1885
  if (bfd_check_format_matches (abfd, bfd_core, &matching))
1886
    {
1887
      l1_read_data (abfd);
1888
      return;
1889
    }
1890
 
1891
  nonfatal (bfd_get_filename (abfd));
1892
 
1893
  if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1894
    {
1895
      list_matching_formats (matching);
1896
      free (matching);
1897
    }
1898
}
1899
 
1900
 
1901
void read_exe (char *filename, char *target) {
1902
 
1903
  bfd *file, *arfile = (bfd *) NULL;
1904
 
1905
  file = bfd_openr (filename, target);
1906
  if (file == NULL)
1907
    {
1908
      nonfatal (filename);
1909
      return;
1910
    }
1911
 
1912
  if (bfd_check_format (file, bfd_archive))
1913
    {
1914
      bfd *last_arfile = NULL;
1915
 
1916
      printf ("In archive %s:\n", bfd_get_filename (file));
1917
      for (;;)
1918
        {
1919
          bfd_set_error (bfd_error_no_error);
1920
 
1921
          arfile = bfd_openr_next_archived_file (file, arfile);
1922
          if (arfile == NULL)
1923
            {
1924
              if (bfd_get_error () != bfd_error_no_more_archived_files)
1925
                nonfatal (bfd_get_filename (file));
1926
              break;
1927
            }
1928
 
1929
          l1_read_bfd (arfile);
1930
 
1931
          if (last_arfile != NULL)
1932
            bfd_close (last_arfile);
1933
          last_arfile = arfile;
1934
        }
1935
 
1936
      if (last_arfile != NULL)
1937
        bfd_close (last_arfile);
1938
    }
1939
  else
1940
    l1_read_bfd (file);
1941
 
1942
  bfd_close (file);
1943
}

powered by: WebSVN 2.1.0

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