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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-binutils/] [binutils-2.19.1/] [gas/] [listing.c] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 jlechner
/* listing.c - maintain assembly listings
2
   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3
   2001, 2002, 2003, 2005, 2006, 2007, 2008
4
   Free Software Foundation, Inc.
5
 
6
   This file is part of GAS, the GNU Assembler.
7
 
8
   GAS is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3, or (at your option)
11
   any later version.
12
 
13
   GAS is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with GAS; see the file COPYING.  If not, write to the Free
20
   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21
   02110-1301, USA.  */
22
 
23
/* Contributed by Steve Chamberlain <sac@cygnus.com>
24
 
25
 A listing page looks like:
26
 
27
 LISTING_HEADER  sourcefilename pagenumber
28
 TITLE LINE
29
 SUBTITLE LINE
30
 linenumber address data  source
31
 linenumber address data  source
32
 linenumber address data  source
33
 linenumber address data  source
34
 
35
 If not overridden, the listing commands are:
36
 
37
 .title  "stuff"
38
        Put "stuff" onto the title line
39
 .sbttl  "stuff"
40
        Put stuff onto the subtitle line
41
 
42
  If these commands come within 10 lines of the top of the page, they
43
  will affect the page they are on, as well as any subsequent page
44
 
45
 .eject
46
        Thow a page
47
 .list
48
        Increment the enable listing counter
49
 .nolist
50
        Decrement the enable listing counter
51
 
52
 .psize Y[,X]
53
        Set the paper size to X wide and Y high. Setting a psize Y of
54
        zero will suppress form feeds except where demanded by .eject
55
 
56
 If the counter goes below zero, listing is suppressed.
57
 
58
 Listings are a maintained by read calling various listing_<foo>
59
 functions.  What happens most is that the macro NO_LISTING is not
60
 defined (from the Makefile), then the macro LISTING_NEWLINE expands
61
 into a call to listing_newline.  The call is done from read.c, every
62
 time it sees a newline, and -l is on the command line.
63
 
64
 The function listing_newline remembers the frag associated with the
65
 newline, and creates a new frag - note that this is wasteful, but not
66
 a big deal, since listing slows things down a lot anyway.  The
67
 function also remembers when the filename changes.
68
 
69
 When all the input has finished, and gas has had a chance to settle
70
 down, the listing is output. This is done by running down the list of
71
 frag/source file records, and opening the files as needed and printing
72
 out the bytes and chars associated with them.
73
 
74
 The only things which the architecture can change about the listing
75
 are defined in these macros:
76
 
77
 LISTING_HEADER         The name of the architecture
78
 LISTING_WORD_SIZE      The make of the number of bytes in a word, this determines
79
                        the clumping of the output data. eg a value of
80
                        2 makes words look like 1234 5678, whilst 1
81
                        would make the same value look like 12 34 56
82
                        78
83
 LISTING_LHS_WIDTH      Number of words of above size for the lhs
84
 
85
 LISTING_LHS_WIDTH_SECOND   Number of words for the data on the lhs
86
                        for the second line
87
 
88
 LISTING_LHS_CONT_LINES Max number of lines to use up for a continuation
89
 LISTING_RHS_WIDTH      Number of chars from the input file to print
90
                        on a line.  */
91
 
92
#include "as.h"
93
#include "obstack.h"
94
#include "safe-ctype.h"
95
#include "input-file.h"
96
#include "subsegs.h"
97
#include "bfdver.h"
98
#include <time.h>
99
 
100
#ifndef NO_LISTING
101
 
102
#ifndef LISTING_HEADER
103
#define LISTING_HEADER "GAS LISTING"
104
#endif
105
#ifndef LISTING_WORD_SIZE
106
#define LISTING_WORD_SIZE 4
107
#endif
108
#ifndef LISTING_LHS_WIDTH
109
#define LISTING_LHS_WIDTH ((LISTING_WORD_SIZE) > 4 ? 1 : 4 / (LISTING_WORD_SIZE))
110
#endif
111
#ifndef LISTING_LHS_WIDTH_SECOND
112
#define LISTING_LHS_WIDTH_SECOND LISTING_LHS_WIDTH
113
#endif
114
#ifndef LISTING_RHS_WIDTH
115
#define LISTING_RHS_WIDTH 100
116
#endif
117
#ifndef LISTING_LHS_CONT_LINES
118
#define LISTING_LHS_CONT_LINES 4
119
#endif
120
#define MAX_DATELEN 30
121
 
122
/* This structure remembers which .s were used.  */
123
typedef struct file_info_struct
124
{
125
  struct file_info_struct * next;
126
  char *                    filename;
127
  long                      pos;
128
  unsigned int              linenum;
129
  int                       at_end;
130
} file_info_type;
131
 
132
/* This structure remembers which line from which file goes into which
133
   frag.  */
134
struct list_info_struct
135
{
136
  /* Frag which this line of source is nearest to.  */
137
  fragS *frag;
138
 
139
  /* The actual line in the source file.  */
140
  unsigned int line;
141
 
142
  /* Pointer to the file info struct for the file which this line
143
     belongs to.  */
144
  file_info_type *file;
145
 
146
  /* The expanded text of any macro that may have been executing.  */
147
  char *line_contents;
148
 
149
  /* Next in list.  */
150
  struct list_info_struct *next;
151
 
152
  /* Pointer to the file info struct for the high level language
153
     source line that belongs here.  */
154
  file_info_type *hll_file;
155
 
156
  /* High level language source line.  */
157
  unsigned int hll_line;
158
 
159
  /* Pointer to any error message associated with this line.  */
160
  char *message;
161
 
162
  enum
163
    {
164
      EDICT_NONE,
165
      EDICT_SBTTL,
166
      EDICT_TITLE,
167
      EDICT_NOLIST,
168
      EDICT_LIST,
169
      EDICT_NOLIST_NEXT,
170
      EDICT_EJECT
171
    } edict;
172
  char *edict_arg;
173
 
174
  /* Nonzero if this line is to be omitted because it contains
175
     debugging information.  This can become a flags field if we come
176
     up with more information to store here.  */
177
  int debugging;
178
};
179
 
180
typedef struct list_info_struct list_info_type;
181
 
182
int listing_lhs_width        = LISTING_LHS_WIDTH;
183
int listing_lhs_width_second = LISTING_LHS_WIDTH_SECOND;
184
int listing_lhs_cont_lines   = LISTING_LHS_CONT_LINES;
185
int listing_rhs_width        = LISTING_RHS_WIDTH;
186
 
187
struct list_info_struct *        listing_tail;
188
 
189
static file_info_type *          file_info_head;
190
static file_info_type *          last_open_file_info;
191
static FILE *                    last_open_file;
192
static struct list_info_struct * head;
193
static int                       paper_width = 200;
194
static int                       paper_height = 60;
195
 
196
extern int                       listing;
197
 
198
/* File to output listings to.  */
199
static FILE *list_file;
200
 
201
/* This static array is used to keep the text of data to be printed
202
   before the start of the line.  */
203
 
204
#define MAX_BYTES                                                       \
205
  (((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width                    \
206
   + ((((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second)        \
207
      * listing_lhs_cont_lines)                                         \
208
   + 20)
209
 
210
static char *data_buffer;
211
 
212
/* Prototypes.  */
213
static void listing_message (const char *, const char *);
214
static file_info_type *file_info (const char *);
215
static void new_frag (void);
216
static char *buffer_line (file_info_type *, char *, unsigned int);
217
static void listing_page (list_info_type *);
218
static unsigned int calc_hex (list_info_type *);
219
static void print_lines (list_info_type *, unsigned int, char *, unsigned int);
220
static void list_symbol_table (void);
221
static void print_source (file_info_type *, list_info_type *, char *, unsigned int);
222
static int debugging_pseudo (list_info_type *, const char *);
223
static void listing_listing (char *);
224
 
225
static void
226
listing_message (const char *name, const char *message)
227
{
228
  if (listing_tail != (list_info_type *) NULL)
229
    {
230
      unsigned int l = strlen (name) + strlen (message) + 1;
231
      char *n = (char *) xmalloc (l);
232
      strcpy (n, name);
233
      strcat (n, message);
234
      listing_tail->message = n;
235
    }
236
}
237
 
238
void
239
listing_warning (const char *message)
240
{
241
  listing_message (_("Warning:"), message);
242
}
243
 
244
void
245
listing_error (const char *message)
246
{
247
  listing_message (_("Error:"), message);
248
}
249
 
250
static file_info_type *
251
file_info (const char *file_name)
252
{
253
  /* Find an entry with this file name.  */
254
  file_info_type *p = file_info_head;
255
 
256
  while (p != (file_info_type *) NULL)
257
    {
258
      if (strcmp (p->filename, file_name) == 0)
259
        return p;
260
      p = p->next;
261
    }
262
 
263
  /* Make new entry.  */
264
  p = xmalloc (sizeof (file_info_type));
265
  p->next = file_info_head;
266
  file_info_head = p;
267
  p->filename = xstrdup (file_name);
268
  p->pos = 0;
269
  p->linenum = 0;
270
  p->at_end = 0;
271
 
272
  return p;
273
}
274
 
275
static void
276
new_frag (void)
277
{
278
  frag_wane (frag_now);
279
  frag_new (0);
280
}
281
 
282
void
283
listing_newline (char *ps)
284
{
285
  char *file;
286
  unsigned int line;
287
  static unsigned int last_line = 0xffff;
288
  static char *last_file = NULL;
289
  list_info_type *new = NULL;
290
 
291
  if (listing == 0)
292
    return;
293
 
294
  if (now_seg == absolute_section)
295
    return;
296
 
297
#ifdef OBJ_ELF
298
  /* In ELF, anything in a section beginning with .debug or .line is
299
     considered to be debugging information.  This includes the
300
     statement which switches us into the debugging section, which we
301
     can only set after we are already in the debugging section.  */
302
  if ((listing & LISTING_NODEBUG) != 0
303
      && listing_tail != NULL
304
      && ! listing_tail->debugging)
305
    {
306
      const char *segname;
307
 
308
      segname = segment_name (now_seg);
309
      if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
310
          || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
311
        listing_tail->debugging = 1;
312
    }
313
#endif
314
 
315
  as_where (&file, &line);
316
  if (ps == NULL)
317
    {
318
      if (line == last_line
319
          && !(last_file && file && strcmp (file, last_file)))
320
        return;
321
 
322
      new = (list_info_type *) xmalloc (sizeof (list_info_type));
323
 
324
      /* Detect if we are reading from stdin by examining the file
325
         name returned by as_where().
326
 
327
         [FIXME: We rely upon the name in the strcmp below being the
328
         same as the one used by input_scrub_new_file(), if that is
329
         not true, then this code will fail].
330
 
331
         If we are reading from stdin, then we need to save each input
332
         line here (assuming of course that we actually have a line of
333
         input to read), so that it can be displayed in the listing
334
         that is produced at the end of the assembly.  */
335
      if (strcmp (file, _("{standard input}")) == 0
336
          && input_line_pointer != NULL)
337
        {
338
          char *copy;
339
          int len;
340
          int seen_quote = 0;
341
 
342
          for (copy = input_line_pointer - 1;
343
               *copy && (seen_quote
344
                         || (! is_end_of_line [(unsigned char) *copy]));
345
               copy++)
346
            if (*copy == '"' && copy[-1] != '\\')
347
              seen_quote = ! seen_quote;
348
 
349
          len = (copy - input_line_pointer) + 2;
350
 
351
          copy = xmalloc (len);
352
 
353
          if (copy != NULL)
354
            {
355
              char *src = input_line_pointer - 1;
356
              char *dest = copy;
357
 
358
              while (--len)
359
                {
360
                  unsigned char c = *src++;
361
 
362
                  /* Omit control characters in the listing.  */
363
                  if (!ISCNTRL (c))
364
                    *dest++ = c;
365
                }
366
 
367
              *dest = 0;
368
            }
369
 
370
          new->line_contents = copy;
371
        }
372
      else
373
        new->line_contents = NULL;
374
    }
375
  else
376
    {
377
      new = xmalloc (sizeof (list_info_type));
378
      new->line_contents = ps;
379
    }
380
 
381
  last_line = line;
382
  last_file = file;
383
 
384
  new_frag ();
385
 
386
  if (listing_tail)
387
    listing_tail->next = new;
388
  else
389
    head = new;
390
 
391
  listing_tail = new;
392
 
393
  new->frag = frag_now;
394
  new->line = line;
395
  new->file = file_info (file);
396
  new->next = (list_info_type *) NULL;
397
  new->message = (char *) NULL;
398
  new->edict = EDICT_NONE;
399
  new->hll_file = (file_info_type *) NULL;
400
  new->hll_line = 0;
401
  new->debugging = 0;
402
 
403
  new_frag ();
404
 
405
#ifdef OBJ_ELF
406
  /* In ELF, anything in a section beginning with .debug or .line is
407
     considered to be debugging information.  */
408
  if ((listing & LISTING_NODEBUG) != 0)
409
    {
410
      const char *segname;
411
 
412
      segname = segment_name (now_seg);
413
      if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
414
          || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
415
        new->debugging = 1;
416
    }
417
#endif
418
}
419
 
420
/* Attach all current frags to the previous line instead of the
421
   current line.  This is called by the MIPS backend when it discovers
422
   that it needs to add some NOP instructions; the added NOP
423
   instructions should go with the instruction that has the delay, not
424
   with the new instruction.  */
425
 
426
void
427
listing_prev_line (void)
428
{
429
  list_info_type *l;
430
  fragS *f;
431
 
432
  if (head == (list_info_type *) NULL
433
      || head == listing_tail)
434
    return;
435
 
436
  new_frag ();
437
 
438
  for (l = head; l->next != listing_tail; l = l->next)
439
    ;
440
 
441
  for (f = frchain_now->frch_root; f != (fragS *) NULL; f = f->fr_next)
442
    if (f->line == listing_tail)
443
      f->line = l;
444
 
445
  listing_tail->frag = frag_now;
446
  new_frag ();
447
}
448
 
449
/* This function returns the next source line from the file supplied,
450
   truncated to size.  It appends a fake line to the end of each input
451
   file to make.  */
452
 
453
static char *
454
buffer_line (file_info_type *file, char *line, unsigned int size)
455
{
456
  unsigned int count = 0;
457
  int c;
458
 
459
  char *p = line;
460
 
461
  /* If we couldn't open the file, return an empty line.  */
462
  if (file->at_end)
463
    return "";
464
 
465
  /* Check the cache and see if we last used this file.  */
466
  if (!last_open_file_info || file != last_open_file_info)
467
    {
468
      if (last_open_file)
469
        {
470
          last_open_file_info->pos = ftell (last_open_file);
471
          fclose (last_open_file);
472
        }
473
 
474
      last_open_file_info = file;
475
      last_open_file = fopen (file->filename, FOPEN_RT);
476
      if (last_open_file == NULL)
477
        {
478
          file->at_end = 1;
479
          return "";
480
        }
481
 
482
      /* Seek to where we were last time this file was open.  */
483
      if (file->pos)
484
        fseek (last_open_file, file->pos, SEEK_SET);
485
    }
486
 
487
  c = fgetc (last_open_file);
488
 
489
  /* Leave room for null.  */
490
  size -= 1;
491
 
492
  while (c != EOF && c != '\n')
493
    {
494
      if (count < size)
495
        *p++ = c;
496
      count++;
497
 
498
      c = fgetc (last_open_file);
499
 
500
    }
501
  if (c == EOF)
502
    {
503
      file->at_end = 1;
504
      if (count + 2 < size)
505
        {
506
          *p++ = '.';
507
          *p++ = '.';
508
          *p++ = '.';
509
        }
510
    }
511
  file->linenum++;
512
  *p++ = 0;
513
  return line;
514
}
515
 
516
static const char *fn;
517
 
518
static unsigned int eject;      /* Eject pending */
519
static unsigned int page;       /* Current page number */
520
static char *title;             /* Current title */
521
static char *subtitle;          /* Current subtitle */
522
static unsigned int on_page;    /* Number of lines printed on current page */
523
 
524
static void
525
listing_page (list_info_type *list)
526
{
527
  /* Grope around, see if we can see a title or subtitle edict coming up
528
     soon.  (we look down 10 lines of the page and see if it's there)  */
529
  if ((eject || (on_page >= (unsigned int) paper_height))
530
      && paper_height != 0)
531
    {
532
      unsigned int c = 10;
533
      int had_title = 0;
534
      int had_subtitle = 0;
535
 
536
      page++;
537
 
538
      while (c != 0 && list)
539
        {
540
          if (list->edict == EDICT_SBTTL && !had_subtitle)
541
            {
542
              had_subtitle = 1;
543
              subtitle = list->edict_arg;
544
            }
545
          if (list->edict == EDICT_TITLE && !had_title)
546
            {
547
              had_title = 1;
548
              title = list->edict_arg;
549
            }
550
          list = list->next;
551
          c--;
552
        }
553
 
554
      if (page > 1)
555
        {
556
          fprintf (list_file, "\f");
557
        }
558
 
559
      fprintf (list_file, "%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
560
      fprintf (list_file, "%s\n", title);
561
      fprintf (list_file, "%s\n", subtitle);
562
      on_page = 3;
563
      eject = 0;
564
    }
565
}
566
 
567
static unsigned int
568
calc_hex (list_info_type *list)
569
{
570
  int data_buffer_size;
571
  list_info_type *first = list;
572
  unsigned int address = ~(unsigned int) 0;
573
  fragS *frag;
574
  fragS *frag_ptr;
575
  unsigned int octet_in_frag;
576
 
577
  /* Find first frag which says it belongs to this line.  */
578
  frag = list->frag;
579
  while (frag && frag->line != list)
580
    frag = frag->fr_next;
581
 
582
  frag_ptr = frag;
583
 
584
  data_buffer_size = 0;
585
 
586
  /* Dump all the frags which belong to this line.  */
587
  while (frag_ptr != (fragS *) NULL && frag_ptr->line == first)
588
    {
589
      /* Print as many bytes from the fixed part as is sensible.  */
590
      octet_in_frag = 0;
591
      while ((offsetT) octet_in_frag < frag_ptr->fr_fix
592
             && data_buffer_size < MAX_BYTES - 3)
593
        {
594
          if (address == ~(unsigned int) 0)
595
            address = frag_ptr->fr_address / OCTETS_PER_BYTE;
596
 
597
          sprintf (data_buffer + data_buffer_size,
598
                   "%02X",
599
                   (frag_ptr->fr_literal[octet_in_frag]) & 0xff);
600
          data_buffer_size += 2;
601
          octet_in_frag++;
602
        }
603
      if (frag_ptr->fr_type == rs_fill)
604
        {
605
          unsigned int var_rep_max = octet_in_frag;
606
          unsigned int var_rep_idx = octet_in_frag;
607
 
608
          /* Print as many bytes from the variable part as is sensible.  */
609
          while (((offsetT) octet_in_frag
610
                  < (frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset))
611
                 && data_buffer_size < MAX_BYTES - 3)
612
            {
613
              if (address == ~(unsigned int) 0)
614
                address = frag_ptr->fr_address / OCTETS_PER_BYTE;
615
 
616
              sprintf (data_buffer + data_buffer_size,
617
                       "%02X",
618
                       (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
619
              data_buffer_size += 2;
620
 
621
              var_rep_idx++;
622
              octet_in_frag++;
623
 
624
              if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var)
625
                var_rep_idx = var_rep_max;
626
            }
627
        }
628
 
629
      frag_ptr = frag_ptr->fr_next;
630
    }
631
  data_buffer[data_buffer_size] = '\0';
632
  return address;
633
}
634
 
635
static void
636
print_lines (list_info_type *list, unsigned int lineno,
637
             char *string, unsigned int address)
638
{
639
  unsigned int idx;
640
  unsigned int nchars;
641
  unsigned int lines;
642
  unsigned int octet_in_word = 0;
643
  char *src = data_buffer;
644
  int cur;
645
 
646
  /* Print the stuff on the first line.  */
647
  listing_page (list);
648
  nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width;
649
 
650
  /* Print the hex for the first line.  */
651
  if (address == ~(unsigned int) 0)
652
    {
653
      fprintf (list_file, "% 4d     ", lineno);
654
      for (idx = 0; idx < nchars; idx++)
655
        fprintf (list_file, " ");
656
 
657
      fprintf (list_file, "\t%s\n", string ? string : "");
658
 
659
      on_page++;
660
 
661
      listing_page (0);
662
 
663
      return;
664
    }
665
 
666
  if (had_errors ())
667
    fprintf (list_file, "% 4d ???? ", lineno);
668
  else
669
    fprintf (list_file, "% 4d %04x ", lineno, address);
670
 
671
  /* And the data to go along with it.  */
672
  idx = 0;
673
  cur = 0;
674
  while (src[cur] && idx < nchars)
675
    {
676
      int offset;
677
      offset = cur;
678
      fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
679
      cur += 2;
680
      octet_in_word++;
681
 
682
      if (octet_in_word == LISTING_WORD_SIZE)
683
        {
684
          fprintf (list_file, " ");
685
          idx++;
686
          octet_in_word = 0;
687
        }
688
 
689
      idx += 2;
690
    }
691
 
692
  for (; idx < nchars; idx++)
693
    fprintf (list_file, " ");
694
 
695
  fprintf (list_file, "\t%s\n", string ? string : "");
696
  on_page++;
697
  listing_page (list);
698
 
699
  if (list->message)
700
    {
701
      fprintf (list_file, "****  %s\n", list->message);
702
      listing_page (list);
703
      on_page++;
704
    }
705
 
706
  for (lines = 0;
707
       lines < (unsigned int) listing_lhs_cont_lines
708
         && src[cur];
709
       lines++)
710
    {
711
      nchars = ((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second - 1;
712
      idx = 0;
713
 
714
      /* Print any more lines of data, but more compactly.  */
715
      fprintf (list_file, "% 4d      ", lineno);
716
 
717
      while (src[cur] && idx < nchars)
718
        {
719
          int offset;
720
          offset = cur;
721
          fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
722
          cur += 2;
723
          idx += 2;
724
          octet_in_word++;
725
 
726
          if (octet_in_word == LISTING_WORD_SIZE)
727
            {
728
              fprintf (list_file, " ");
729
              idx++;
730
              octet_in_word = 0;
731
            }
732
        }
733
 
734
      fprintf (list_file, "\n");
735
      on_page++;
736
      listing_page (list);
737
    }
738
}
739
 
740
static void
741
list_symbol_table (void)
742
{
743
  extern symbolS *symbol_rootP;
744
  int got_some = 0;
745
 
746
  symbolS *ptr;
747
  eject = 1;
748
  listing_page (0);
749
 
750
  for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
751
    {
752
      if (SEG_NORMAL (S_GET_SEGMENT (ptr))
753
          || S_GET_SEGMENT (ptr) == absolute_section)
754
        {
755
          /* Don't report section symbols.  They are not interesting.  */
756
          if (symbol_section_p (ptr))
757
            continue;
758
 
759
          if (S_GET_NAME (ptr))
760
            {
761
              char buf[30], fmt[8];
762
              valueT val = S_GET_VALUE (ptr);
763
 
764
              /* @@ Note that this is dependent on the compilation options,
765
                 not solely on the target characteristics.  */
766
              if (sizeof (val) == 4 && sizeof (int) == 4)
767
                sprintf (buf, "%08lx", (unsigned long) val);
768
              else if (sizeof (val) <= sizeof (unsigned long))
769
                {
770
                  sprintf (fmt, "%%0%lulx",
771
                           (unsigned long) (sizeof (val) * 2));
772
                  sprintf (buf, fmt, (unsigned long) val);
773
                }
774
#if defined (BFD64)
775
              else if (sizeof (val) > 4)
776
                sprintf_vma (buf, val);
777
#endif
778
              else
779
                abort ();
780
 
781
              if (!got_some)
782
                {
783
                  fprintf (list_file, "DEFINED SYMBOLS\n");
784
                  on_page++;
785
                  got_some = 1;
786
                }
787
 
788
              if (symbol_get_frag (ptr) && symbol_get_frag (ptr)->line)
789
                {
790
                  fprintf (list_file, "%20s:%-5d  %s:%s %s\n",
791
                           symbol_get_frag (ptr)->line->file->filename,
792
                           symbol_get_frag (ptr)->line->line,
793
                           segment_name (S_GET_SEGMENT (ptr)),
794
                           buf, S_GET_NAME (ptr));
795
                }
796
              else
797
                {
798
                  fprintf (list_file, "%33s:%s %s\n",
799
                           segment_name (S_GET_SEGMENT (ptr)),
800
                           buf, S_GET_NAME (ptr));
801
                }
802
 
803
              on_page++;
804
              listing_page (0);
805
            }
806
        }
807
 
808
    }
809
  if (!got_some)
810
    {
811
      fprintf (list_file, "NO DEFINED SYMBOLS\n");
812
      on_page++;
813
    }
814
  fprintf (list_file, "\n");
815
  on_page++;
816
  listing_page (0);
817
 
818
  got_some = 0;
819
 
820
  for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
821
    {
822
      if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0)
823
        {
824
          if (S_GET_SEGMENT (ptr) == undefined_section)
825
            {
826
              if (!got_some)
827
                {
828
                  got_some = 1;
829
                  fprintf (list_file, "UNDEFINED SYMBOLS\n");
830
                  on_page++;
831
                  listing_page (0);
832
                }
833
              fprintf (list_file, "%s\n", S_GET_NAME (ptr));
834
              on_page++;
835
              listing_page (0);
836
            }
837
        }
838
    }
839
  if (!got_some)
840
    {
841
      fprintf (list_file, "NO UNDEFINED SYMBOLS\n");
842
      on_page++;
843
      listing_page (0);
844
    }
845
}
846
 
847
static void
848
print_source (file_info_type *current_file, list_info_type *list,
849
              char *buffer, unsigned int width)
850
{
851
  if (!current_file->at_end)
852
    {
853
      while (current_file->linenum < list->hll_line
854
             && !current_file->at_end)
855
        {
856
          char *p = buffer_line (current_file, buffer, width);
857
 
858
          fprintf (list_file, "%4u:%-13s **** %s\n", current_file->linenum,
859
                   current_file->filename, p);
860
          on_page++;
861
          listing_page (list);
862
        }
863
    }
864
}
865
 
866
/* Sometimes the user doesn't want to be bothered by the debugging
867
   records inserted by the compiler, see if the line is suspicious.  */
868
 
869
static int
870
debugging_pseudo (list_info_type *list, const char *line)
871
{
872
  static int in_debug;
873
  int was_debug;
874
 
875
  if (list->debugging)
876
    {
877
      in_debug = 1;
878
      return 1;
879
    }
880
 
881
  was_debug = in_debug;
882
  in_debug = 0;
883
 
884
  while (ISSPACE (*line))
885
    line++;
886
 
887
  if (*line != '.')
888
    {
889
#ifdef OBJ_ELF
890
      /* The ELF compiler sometimes emits blank lines after switching
891
         out of a debugging section.  If the next line drops us back
892
         into debugging information, then don't print the blank line.
893
         This is a hack for a particular compiler behaviour, not a
894
         general case.  */
895
      if (was_debug
896
          && *line == '\0'
897
          && list->next != NULL
898
          && list->next->debugging)
899
        {
900
          in_debug = 1;
901
          return 1;
902
        }
903
#endif
904
 
905
      return 0;
906
    }
907
 
908
  line++;
909
 
910
  if (strncmp (line, "def", 3) == 0)
911
    return 1;
912
  if (strncmp (line, "val", 3) == 0)
913
    return 1;
914
  if (strncmp (line, "scl", 3) == 0)
915
    return 1;
916
  if (strncmp (line, "line", 4) == 0)
917
    return 1;
918
  if (strncmp (line, "endef", 5) == 0)
919
    return 1;
920
  if (strncmp (line, "ln", 2) == 0)
921
    return 1;
922
  if (strncmp (line, "type", 4) == 0)
923
    return 1;
924
  if (strncmp (line, "size", 4) == 0)
925
    return 1;
926
  if (strncmp (line, "dim", 3) == 0)
927
    return 1;
928
  if (strncmp (line, "tag", 3) == 0)
929
    return 1;
930
  if (strncmp (line, "stabs", 5) == 0)
931
    return 1;
932
  if (strncmp (line, "stabn", 5) == 0)
933
    return 1;
934
 
935
  return 0;
936
}
937
 
938
static void
939
listing_listing (char *name ATTRIBUTE_UNUSED)
940
{
941
  list_info_type *list = head;
942
  file_info_type *current_hll_file = (file_info_type *) NULL;
943
  char *message;
944
  char *buffer;
945
  char *p;
946
  int show_listing = 1;
947
  unsigned int width;
948
 
949
  buffer = xmalloc (listing_rhs_width);
950
  data_buffer = xmalloc (MAX_BYTES);
951
  eject = 1;
952
  list = head->next;
953
 
954
  while (list)
955
    {
956
      unsigned int list_line;
957
 
958
      width = listing_rhs_width > paper_width ? paper_width :
959
        listing_rhs_width;
960
 
961
      list_line = list->line;
962
      switch (list->edict)
963
        {
964
        case EDICT_LIST:
965
          /* Skip all lines up to the current.  */
966
          list_line--;
967
          break;
968
        case EDICT_NOLIST:
969
          show_listing--;
970
          break;
971
        case EDICT_NOLIST_NEXT:
972
          if (show_listing == 0)
973
            list_line--;
974
          break;
975
        case EDICT_EJECT:
976
          break;
977
        case EDICT_NONE:
978
          break;
979
        case EDICT_TITLE:
980
          title = list->edict_arg;
981
          break;
982
        case EDICT_SBTTL:
983
          subtitle = list->edict_arg;
984
          break;
985
        default:
986
          abort ();
987
        }
988
 
989
      if (show_listing <= 0)
990
        {
991
          while (list->file->linenum < list_line
992
                 && !list->file->at_end)
993
            p = buffer_line (list->file, buffer, width);
994
        }
995
 
996
      if (list->edict == EDICT_LIST
997
          || (list->edict == EDICT_NOLIST_NEXT && show_listing == 0))
998
        {
999
          /* Enable listing for the single line that caused the enable.  */
1000
          list_line++;
1001
          show_listing++;
1002
        }
1003
 
1004
      if (show_listing > 0)
1005
        {
1006
          /* Scan down the list and print all the stuff which can be done
1007
             with this line (or lines).  */
1008
          message = 0;
1009
 
1010
          if (list->hll_file)
1011
            current_hll_file = list->hll_file;
1012
 
1013
          if (current_hll_file && list->hll_line && (listing & LISTING_HLL))
1014
            print_source (current_hll_file, list, buffer, width);
1015
 
1016
          if (list->line_contents)
1017
            {
1018
              if (!((listing & LISTING_NODEBUG)
1019
                    && debugging_pseudo (list, list->line_contents)))
1020
                print_lines (list,
1021
                             list->file->linenum == 0 ? list->line : list->file->linenum,
1022
                             list->line_contents, calc_hex (list));
1023
 
1024
              free (list->line_contents);
1025
              list->line_contents = NULL;
1026
            }
1027
          else
1028
            {
1029
              while (list->file->linenum < list_line
1030
                     && !list->file->at_end)
1031
                {
1032
                  unsigned int address;
1033
 
1034
                  p = buffer_line (list->file, buffer, width);
1035
 
1036
                  if (list->file->linenum < list_line)
1037
                    address = ~(unsigned int) 0;
1038
                  else
1039
                    address = calc_hex (list);
1040
 
1041
                  if (!((listing & LISTING_NODEBUG)
1042
                        && debugging_pseudo (list, p)))
1043
                    print_lines (list, list->file->linenum, p, address);
1044
                }
1045
            }
1046
 
1047
          if (list->edict == EDICT_EJECT)
1048
            eject = 1;
1049
        }
1050
 
1051
      if (list->edict == EDICT_NOLIST_NEXT && show_listing == 1)
1052
        --show_listing;
1053
 
1054
      list = list->next;
1055
    }
1056
 
1057
  free (buffer);
1058
  free (data_buffer);
1059
  data_buffer = NULL;
1060
}
1061
 
1062
/* Print time stamp in ISO format:  yyyy-mm-ddThh:mm:ss.ss+/-zzzz.  */
1063
 
1064
static void
1065
print_timestamp (void)
1066
{
1067
  const time_t now = time (NULL);
1068
  struct tm * timestamp;
1069
  char stampstr[MAX_DATELEN];
1070
 
1071
  /* Any portable way to obtain subsecond values???  */
1072
  timestamp = localtime (&now);
1073
  strftime (stampstr, MAX_DATELEN, "%Y-%m-%dT%H:%M:%S.000%z", timestamp);
1074
  fprintf (list_file, _("\n time stamp    \t: %s\n\n"), stampstr);
1075
}
1076
 
1077
static void
1078
print_single_option (char * opt, int *pos)
1079
{
1080
  int opt_len = strlen (opt);
1081
 
1082
   if ((*pos + opt_len) < paper_width)
1083
     {
1084
        fprintf (list_file, _("%s "), opt);
1085
        *pos = *pos + opt_len;
1086
     }
1087
   else
1088
     {
1089
        fprintf (list_file, _("\n\t%s "), opt);
1090
        *pos = opt_len;
1091
     }
1092
}
1093
 
1094
/* Print options passed to as.  */
1095
 
1096
static void
1097
print_options (char ** argv)
1098
{
1099
  const char *field_name = _("\n options passed\t: ");
1100
  int pos = strlen (field_name);
1101
  char **p;
1102
 
1103
  fputs (field_name, list_file);
1104
  for (p = &argv[1]; *p != NULL; p++)
1105
    if (**p == '-')
1106
      {
1107
        /* Ignore these.  */
1108
        if (strcmp (*p, "-o") == 0)
1109
          {
1110
            if (p[1] != NULL)
1111
              p++;
1112
            continue;
1113
          }
1114
        if (strcmp (*p, "-v") == 0)
1115
          continue;
1116
 
1117
        print_single_option (*p, &pos);
1118
      }
1119
}
1120
 
1121
/* Print a first section with basic info like file names, as version,
1122
   options passed, target, and timestamp.
1123
   The format of this section is as follows:
1124
 
1125
   AS VERSION
1126
 
1127
   fieldname TAB ':' fieldcontents
1128
  { TAB fieldcontents-cont }  */
1129
 
1130
static void
1131
listing_general_info (char ** argv)
1132
{
1133
  /* Print the stuff on the first line.  */
1134
  eject = 1;
1135
  listing_page (0);
1136
 
1137
  fprintf (list_file,
1138
           _(" GNU assembler version %s (%s)\n\t using BFD version %s."),
1139
           VERSION, TARGET_ALIAS, BFD_VERSION_STRING);
1140
  print_options (argv);
1141
  fprintf (list_file, _("\n input file    \t: %s"), fn);
1142
  fprintf (list_file, _("\n output file   \t: %s"), out_file_name);
1143
  fprintf (list_file, _("\n target        \t: %s"), TARGET_CANONICAL);
1144
  print_timestamp ();
1145
}
1146
 
1147
void
1148
listing_print (char *name, char **argv)
1149
{
1150
  int using_stdout;
1151
 
1152
  title = "";
1153
  subtitle = "";
1154
 
1155
  if (name == NULL)
1156
    {
1157
      list_file = stdout;
1158
      using_stdout = 1;
1159
    }
1160
  else
1161
    {
1162
      list_file = fopen (name, FOPEN_WT);
1163
      if (list_file != NULL)
1164
        using_stdout = 0;
1165
      else
1166
        {
1167
          as_warn (_("can't open %s: %s"), name, xstrerror (errno));
1168
          list_file = stdout;
1169
          using_stdout = 1;
1170
        }
1171
    }
1172
 
1173
  if (listing & LISTING_NOFORM)
1174
    paper_height = 0;
1175
 
1176
  if (listing & LISTING_GENERAL)
1177
    listing_general_info (argv);
1178
 
1179
  if (listing & LISTING_LISTING)
1180
    listing_listing (name);
1181
 
1182
  if (listing & LISTING_SYMBOLS)
1183
    list_symbol_table ();
1184
 
1185
  if (! using_stdout)
1186
    {
1187
      if (fclose (list_file) == EOF)
1188
        as_warn (_("can't close %s: %s"), name, xstrerror (errno));
1189
    }
1190
 
1191
  if (last_open_file)
1192
    fclose (last_open_file);
1193
}
1194
 
1195
void
1196
listing_file (const char *name)
1197
{
1198
  fn = name;
1199
}
1200
 
1201
void
1202
listing_eject (int ignore ATTRIBUTE_UNUSED)
1203
{
1204
  if (listing)
1205
    listing_tail->edict = EDICT_EJECT;
1206
}
1207
 
1208
void
1209
listing_flags (int ignore ATTRIBUTE_UNUSED)
1210
{
1211
  while ((*input_line_pointer++) && (*input_line_pointer != '\n'))
1212
    input_line_pointer++;
1213
 
1214
}
1215
 
1216
/* Turn listing on or off.  An argument of 0 means to turn off
1217
   listing.  An argument of 1 means to turn on listing.  An argument
1218
   of 2 means to turn off listing, but as of the next line; that is,
1219
   the current line should be listed, but the next line should not.  */
1220
 
1221
void
1222
listing_list (int on)
1223
{
1224
  if (listing)
1225
    {
1226
      switch (on)
1227
        {
1228
        case 0:
1229
          if (listing_tail->edict == EDICT_LIST)
1230
            listing_tail->edict = EDICT_NONE;
1231
          else
1232
            listing_tail->edict = EDICT_NOLIST;
1233
          break;
1234
        case 1:
1235
          if (listing_tail->edict == EDICT_NOLIST
1236
              || listing_tail->edict == EDICT_NOLIST_NEXT)
1237
            listing_tail->edict = EDICT_NONE;
1238
          else
1239
            listing_tail->edict = EDICT_LIST;
1240
          break;
1241
        case 2:
1242
          listing_tail->edict = EDICT_NOLIST_NEXT;
1243
          break;
1244
        default:
1245
          abort ();
1246
        }
1247
    }
1248
}
1249
 
1250
void
1251
listing_psize (int width_only)
1252
{
1253
  if (! width_only)
1254
    {
1255
      paper_height = get_absolute_expression ();
1256
 
1257
      if (paper_height < 0 || paper_height > 1000)
1258
        {
1259
          paper_height = 0;
1260
          as_warn (_("strange paper height, set to no form"));
1261
        }
1262
 
1263
      if (*input_line_pointer != ',')
1264
        {
1265
          demand_empty_rest_of_line ();
1266
          return;
1267
        }
1268
 
1269
      ++input_line_pointer;
1270
    }
1271
 
1272
  paper_width = get_absolute_expression ();
1273
 
1274
  demand_empty_rest_of_line ();
1275
}
1276
 
1277
void
1278
listing_nopage (int ignore ATTRIBUTE_UNUSED)
1279
{
1280
  paper_height = 0;
1281
}
1282
 
1283
void
1284
listing_title (int depth)
1285
{
1286
  int quoted;
1287
  char *start;
1288
  char *ttl;
1289
  unsigned int length;
1290
 
1291
  SKIP_WHITESPACE ();
1292
  if (*input_line_pointer != '\"')
1293
    quoted = 0;
1294
  else
1295
    {
1296
      quoted = 1;
1297
      ++input_line_pointer;
1298
    }
1299
 
1300
  start = input_line_pointer;
1301
 
1302
  while (*input_line_pointer)
1303
    {
1304
      if (quoted
1305
          ? *input_line_pointer == '\"'
1306
          : is_end_of_line[(unsigned char) *input_line_pointer])
1307
        {
1308
          if (listing)
1309
            {
1310
              length = input_line_pointer - start;
1311
              ttl = xmalloc (length + 1);
1312
              memcpy (ttl, start, length);
1313
              ttl[length] = 0;
1314
              listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
1315
              listing_tail->edict_arg = ttl;
1316
            }
1317
          if (quoted)
1318
            input_line_pointer++;
1319
          demand_empty_rest_of_line ();
1320
          return;
1321
        }
1322
      else if (*input_line_pointer == '\n')
1323
        {
1324
          as_bad (_("new line in title"));
1325
          demand_empty_rest_of_line ();
1326
          return;
1327
        }
1328
      else
1329
        {
1330
          input_line_pointer++;
1331
        }
1332
    }
1333
}
1334
 
1335
void
1336
listing_source_line (unsigned int line)
1337
{
1338
  if (listing)
1339
    {
1340
      new_frag ();
1341
      listing_tail->hll_line = line;
1342
      new_frag ();
1343
    }
1344
}
1345
 
1346
void
1347
listing_source_file (const char *file)
1348
{
1349
  if (listing)
1350
    listing_tail->hll_file = file_info (file);
1351
}
1352
 
1353
#else
1354
 
1355
/* Dummy functions for when compiled without listing enabled.  */
1356
 
1357
void
1358
listing_flags (int ignore)
1359
{
1360
  s_ignore (0);
1361
}
1362
 
1363
void
1364
listing_list (int on)
1365
{
1366
  s_ignore (0);
1367
}
1368
 
1369
void
1370
listing_eject (int ignore)
1371
{
1372
  s_ignore (0);
1373
}
1374
 
1375
void
1376
listing_psize (int ignore)
1377
{
1378
  s_ignore (0);
1379
}
1380
 
1381
void
1382
listing_nopage (int ignore)
1383
{
1384
  s_ignore (0);
1385
}
1386
 
1387
void
1388
listing_title (int depth)
1389
{
1390
  s_ignore (0);
1391
}
1392
 
1393
void
1394
listing_file (const char *name)
1395
{
1396
}
1397
 
1398
void
1399
listing_newline (char *name)
1400
{
1401
}
1402
 
1403
void
1404
listing_source_line (unsigned int n)
1405
{
1406
}
1407
 
1408
void
1409
listing_source_file (const char *n)
1410
{
1411
}
1412
 
1413
#endif

powered by: WebSVN 2.1.0

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