OSDN Git Service

update copyright dates
[pf3gnuchains/pf3gnuchains4x.git] / gas / listing.c
1 /* 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, 2009
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 #include <stdarg.h>
100
101 #ifndef NO_LISTING
102
103 #ifndef LISTING_HEADER
104 #define LISTING_HEADER "GAS LISTING"
105 #endif
106 #ifndef LISTING_WORD_SIZE
107 #define LISTING_WORD_SIZE 4
108 #endif
109 #ifndef LISTING_LHS_WIDTH
110 #define LISTING_LHS_WIDTH ((LISTING_WORD_SIZE) > 4 ? 1 : 4 / (LISTING_WORD_SIZE))
111 #endif
112 #ifndef LISTING_LHS_WIDTH_SECOND
113 #define LISTING_LHS_WIDTH_SECOND LISTING_LHS_WIDTH
114 #endif
115 #ifndef LISTING_RHS_WIDTH
116 #define LISTING_RHS_WIDTH 100
117 #endif
118 #ifndef LISTING_LHS_CONT_LINES
119 #define LISTING_LHS_CONT_LINES 4
120 #endif
121 #define MAX_DATELEN 30
122
123 /* This structure remembers which .s were used.  */
124 typedef struct file_info_struct
125 {
126   struct file_info_struct * next;
127   char *                    filename;
128   long                      pos;
129   unsigned int              linenum;
130   int                       at_end;
131 } file_info_type;
132
133 /* This structure remembers which line from which file goes into which
134    frag.  */
135 struct list_info_struct
136 {
137   /* Frag which this line of source is nearest to.  */
138   fragS *frag;
139
140   /* The actual line in the source file.  */
141   unsigned int line;
142
143   /* Pointer to the file info struct for the file which this line
144      belongs to.  */
145   file_info_type *file;
146
147   /* The expanded text of any macro that may have been executing.  */
148   char *line_contents;
149
150   /* Next in list.  */
151   struct list_info_struct *next;
152
153   /* Pointer to the file info struct for the high level language
154      source line that belongs here.  */
155   file_info_type *hll_file;
156
157   /* High level language source line.  */
158   unsigned int hll_line;
159
160   /* Pointer to any error message associated with this line.  */
161   char *message;
162
163   enum
164     {
165       EDICT_NONE,
166       EDICT_SBTTL,
167       EDICT_TITLE,
168       EDICT_NOLIST,
169       EDICT_LIST,
170       EDICT_NOLIST_NEXT,
171       EDICT_EJECT
172     } edict;
173   char *edict_arg;
174
175   /* Nonzero if this line is to be omitted because it contains
176      debugging information.  This can become a flags field if we come
177      up with more information to store here.  */
178   int debugging;
179 };
180
181 typedef struct list_info_struct list_info_type;
182
183 int listing_lhs_width        = LISTING_LHS_WIDTH;
184 int listing_lhs_width_second = LISTING_LHS_WIDTH_SECOND;
185 int listing_lhs_cont_lines   = LISTING_LHS_CONT_LINES;
186 int listing_rhs_width        = LISTING_RHS_WIDTH;
187
188 struct list_info_struct *        listing_tail;
189
190 static file_info_type *          file_info_head;
191 static file_info_type *          last_open_file_info;
192 static FILE *                    last_open_file;
193 static struct list_info_struct * head;
194 static int                       paper_width = 200;
195 static int                       paper_height = 60;
196
197 extern int                       listing;
198
199 /* File to output listings to.  */
200 static FILE *list_file;
201
202 /* This static array is used to keep the text of data to be printed
203    before the start of the line.  */
204
205 #define MAX_BYTES                                                       \
206   (((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width                    \
207    + ((((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second)        \
208       * listing_lhs_cont_lines)                                         \
209    + 20)
210
211 static char *data_buffer;
212
213 /* Prototypes.  */
214 static void listing_message (const char *, const char *);
215 static file_info_type *file_info (const char *);
216 static void new_frag (void);
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 int debugging_pseudo (list_info_type *, const char *);
222 static void listing_listing (char *);
223
224 static void
225 listing_message (const char *name, const char *message)
226 {
227   if (listing_tail != (list_info_type *) NULL)
228     {
229       unsigned int l = strlen (name) + strlen (message) + 1;
230       char *n = (char *) xmalloc (l);
231       strcpy (n, name);
232       strcat (n, message);
233       listing_tail->message = n;
234     }
235 }
236
237 void
238 listing_warning (const char *message)
239 {
240   listing_message (_("Warning:"), message);
241 }
242
243 void
244 listing_error (const char *message)
245 {
246   listing_message (_("Error:"), message);
247 }
248
249 static file_info_type *
250 file_info (const char *file_name)
251 {
252   /* Find an entry with this file name.  */
253   file_info_type *p = file_info_head;
254
255   while (p != (file_info_type *) NULL)
256     {
257       if (strcmp (p->filename, file_name) == 0)
258         return p;
259       p = p->next;
260     }
261
262   /* Make new entry.  */
263   p = xmalloc (sizeof (file_info_type));
264   p->next = file_info_head;
265   file_info_head = p;
266   p->filename = xstrdup (file_name);
267   p->pos = 0;
268   p->linenum = 0;
269   p->at_end = 0;
270
271   return p;
272 }
273
274 static void
275 new_frag (void)
276 {
277   frag_wane (frag_now);
278   frag_new (0);
279 }
280
281 void
282 listing_newline (char *ps)
283 {
284   char *file;
285   unsigned int line;
286   static unsigned int last_line = 0xffff;
287   static char *last_file = NULL;
288   list_info_type *new_i = NULL;
289
290   if (listing == 0)
291     return;
292
293   if (now_seg == absolute_section)
294     return;
295
296 #ifdef OBJ_ELF
297   /* In ELF, anything in a section beginning with .debug or .line is
298      considered to be debugging information.  This includes the
299      statement which switches us into the debugging section, which we
300      can only set after we are already in the debugging section.  */
301   if ((listing & LISTING_NODEBUG) != 0
302       && listing_tail != NULL
303       && ! listing_tail->debugging)
304     {
305       const char *segname;
306
307       segname = segment_name (now_seg);
308       if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
309           || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
310         listing_tail->debugging = 1;
311     }
312 #endif
313
314   as_where (&file, &line);
315   if (ps == NULL)
316     {
317       if (line == last_line
318           && !(last_file && file && strcmp (file, last_file)))
319         return;
320
321       new_i = (list_info_type *) xmalloc (sizeof (list_info_type));
322
323       /* Detect if we are reading from stdin by examining the file
324          name returned by as_where().
325
326          [FIXME: We rely upon the name in the strcmp below being the
327          same as the one used by input_scrub_new_file(), if that is
328          not true, then this code will fail].
329
330          If we are reading from stdin, then we need to save each input
331          line here (assuming of course that we actually have a line of
332          input to read), so that it can be displayed in the listing
333          that is produced at the end of the assembly.  */
334       if (strcmp (file, _("{standard input}")) == 0
335           && input_line_pointer != NULL)
336         {
337           char *copy;
338           int len;
339           int seen_quote = 0;
340           int seen_slash = 0;
341
342           for (copy = input_line_pointer - 1;
343                *copy && (seen_quote
344                          || is_end_of_line [(unsigned char) *copy] != 1);
345                copy++)
346             {
347               if (*copy == '\\')
348                 seen_slash = ! seen_slash;
349               else if (*copy == '"' && seen_slash)
350                 seen_quote = ! seen_quote;
351             }
352
353           len = (copy - input_line_pointer) + 2;
354
355           copy = xmalloc (len);
356
357           if (copy != NULL)
358             {
359               char *src = input_line_pointer - 1;
360               char *dest = copy;
361
362               while (--len)
363                 {
364                   unsigned char c = *src++;
365
366                   /* Omit control characters in the listing.  */
367                   if (!ISCNTRL (c))
368                     *dest++ = c;
369                 }
370
371               *dest = 0;
372             }
373
374           new_i->line_contents = copy;
375         }
376       else
377         new_i->line_contents = NULL;
378     }
379   else
380     {
381       new_i = (list_info_type *) xmalloc (sizeof (list_info_type));
382       new_i->line_contents = ps;
383     }
384
385   last_line = line;
386   last_file = file;
387
388   new_frag ();
389
390   if (listing_tail)
391     listing_tail->next = new_i;
392   else
393     head = new_i;
394
395   listing_tail = new_i;
396
397   new_i->frag = frag_now;
398   new_i->line = line;
399   new_i->file = file_info (file);
400   new_i->next = (list_info_type *) NULL;
401   new_i->message = (char *) NULL;
402   new_i->edict = EDICT_NONE;
403   new_i->hll_file = (file_info_type *) NULL;
404   new_i->hll_line = 0;
405   new_i->debugging = 0;
406
407   new_frag ();
408
409 #ifdef OBJ_ELF
410   /* In ELF, anything in a section beginning with .debug or .line is
411      considered to be debugging information.  */
412   if ((listing & LISTING_NODEBUG) != 0)
413     {
414       const char *segname;
415
416       segname = segment_name (now_seg);
417       if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
418           || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
419         new_i->debugging = 1;
420     }
421 #endif
422 }
423
424 /* Attach all current frags to the previous line instead of the
425    current line.  This is called by the MIPS backend when it discovers
426    that it needs to add some NOP instructions; the added NOP
427    instructions should go with the instruction that has the delay, not
428    with the new instruction.  */
429
430 void
431 listing_prev_line (void)
432 {
433   list_info_type *l;
434   fragS *f;
435
436   if (head == (list_info_type *) NULL
437       || head == listing_tail)
438     return;
439
440   new_frag ();
441
442   for (l = head; l->next != listing_tail; l = l->next)
443     ;
444
445   for (f = frchain_now->frch_root; f != (fragS *) NULL; f = f->fr_next)
446     if (f->line == listing_tail)
447       f->line = l;
448
449   listing_tail->frag = frag_now;
450   new_frag ();
451 }
452
453 /* This function returns the next source line from the file supplied,
454    truncated to size.  It appends a fake line to the end of each input
455    file to make using the returned buffer simpler.  */
456
457 static char *
458 buffer_line (file_info_type *file, char *line, unsigned int size)
459 {
460   unsigned int count = 0;
461   int c;
462   char *p = line;
463
464   /* If we couldn't open the file, return an empty line.  */
465   if (file->at_end)
466     return "";
467
468   /* Check the cache and see if we last used this file.  */
469   if (!last_open_file_info || file != last_open_file_info)
470     {
471       if (last_open_file)
472         {
473           last_open_file_info->pos = ftell (last_open_file);
474           fclose (last_open_file);
475         }
476
477       /* Open the file in the binary mode so that ftell above can
478          return a reliable value that we can feed to fseek below.  */
479       last_open_file_info = file;
480       last_open_file = fopen (file->filename, FOPEN_RB);
481       if (last_open_file == NULL)
482         {
483           file->at_end = 1;
484           return "";
485         }
486
487       /* Seek to where we were last time this file was open.  */
488       if (file->pos)
489         fseek (last_open_file, file->pos, SEEK_SET);
490     }
491
492   /* Leave room for null.  */
493   size -= 1;
494
495   c = fgetc (last_open_file);
496
497   while (c != EOF && c != '\n' && c != '\r')
498     {
499       if (count < size)
500         *p++ = c;
501       count++;
502
503       c = fgetc (last_open_file);
504     }
505
506   /* If '\r' is followed by '\n', swallow that.  Likewise, if '\n'
507      is followed by '\r', swallow that as well.  */
508   if (c == '\r' || c == '\n')
509     {
510       int next = fgetc (last_open_file);
511
512       if ((c == '\r' && next != '\n')
513           || (c == '\n' && next != '\r'))
514         ungetc (next, last_open_file);
515     }
516
517   if (c == EOF)
518     {
519       file->at_end = 1;
520       if (count + 2 < size)
521         {
522           *p++ = '.';
523           *p++ = '.';
524           *p++ = '.';
525         }
526     }
527   file->linenum++;
528   *p++ = 0;
529   return line;
530 }
531
532
533 /* This function rewinds the requested file back to the line requested,
534    reads it in again into the buffer provided and then restores the file
535    back to its original location.  */
536
537 static char *
538 rebuffer_line (file_info_type *  file,
539                unsigned int      linenum,
540                char *            buffer,
541                unsigned int      size)
542 {
543   unsigned int count = 0;
544   unsigned int current_line = 1;
545   char * p = buffer;
546   long pos;
547   int c;
548
549   /* Sanity checks.  */
550   if (file == NULL || buffer == NULL || size == 0 || file->linenum <= linenum)
551     return "";
552
553   /* Check the cache and see if we last used this file.  */
554   if (last_open_file_info == NULL || file != last_open_file_info)
555     {
556       if (last_open_file)
557         {
558           last_open_file_info->pos = ftell (last_open_file);
559           fclose (last_open_file);
560         }
561
562       /* Open the file in the binary mode so that ftell above can
563          return a reliable value that we can feed to fseek below.  */
564       last_open_file_info = file;
565       last_open_file = fopen (file->filename, FOPEN_RB);
566       if (last_open_file == NULL)
567         {
568           file->at_end = 1;
569           return "";
570         }
571
572       /* Seek to where we were last time this file was open.  */
573       if (file->pos)
574         fseek (last_open_file, file->pos, SEEK_SET);
575     }
576
577   /* Remember where we are in the current file.  */
578   pos = ftell (last_open_file);
579
580   /* Go back to the beginning.  */
581   fseek (last_open_file, 0, SEEK_SET);
582
583   /* Skip lines prior to the one we are interested in.  */
584   while (current_line < linenum)
585     {
586       /* fgets only stops on newlines and has a size limit,
587          so we read one character at a time instead.  */
588       do
589         {
590           c = fgetc (last_open_file);
591         }
592       while (c != EOF && c != '\n' && c != '\r');
593
594       ++ current_line;
595
596       if (c == '\r' || c == '\n')
597         {
598           int next = fgetc (last_open_file);
599
600           /* If '\r' is followed by '\n', swallow that.  Likewise, if '\n'
601              is followed by '\r', swallow that as well.  */
602           if ((c == '\r' && next != '\n')
603               || (c == '\n' && next != '\r'))
604             ungetc (next, last_open_file);
605         }
606     }
607
608   /* Leave room for the nul at the end of the buffer.  */
609   size -= 1;
610
611   /* Read in the line.  */
612   c = fgetc (last_open_file);
613
614   while (c != EOF && c != '\n' && c != '\r')
615     {
616       if (count < size)
617         *p++ = c;
618       count++;
619
620       c = fgetc (last_open_file);
621     }
622
623   /* If '\r' is followed by '\n', swallow that.  Likewise, if '\n'
624      is followed by '\r', swallow that as well.  */
625   if (c == '\r' || c == '\n')
626     {
627       int next = fgetc (last_open_file);
628
629       if ((c == '\r' && next != '\n')
630           || (c == '\n' && next != '\r'))
631         ungetc (next, last_open_file);
632     }
633
634   /* Terminate the line.  */
635   *p++ = 0;
636
637   /* Reset the file position.  */
638   fseek (last_open_file, pos, SEEK_SET);
639
640   return buffer;
641 }
642
643 static const char *fn;
644
645 static unsigned int eject;      /* Eject pending */
646 static unsigned int page;       /* Current page number */
647 static char *title;             /* Current title */
648 static char *subtitle;          /* Current subtitle */
649 static unsigned int on_page;    /* Number of lines printed on current page */
650
651 static void
652 listing_page (list_info_type *list)
653 {
654   /* Grope around, see if we can see a title or subtitle edict coming up
655      soon.  (we look down 10 lines of the page and see if it's there)  */
656   if ((eject || (on_page >= (unsigned int) paper_height))
657       && paper_height != 0)
658     {
659       unsigned int c = 10;
660       int had_title = 0;
661       int had_subtitle = 0;
662
663       page++;
664
665       while (c != 0 && list)
666         {
667           if (list->edict == EDICT_SBTTL && !had_subtitle)
668             {
669               had_subtitle = 1;
670               subtitle = list->edict_arg;
671             }
672           if (list->edict == EDICT_TITLE && !had_title)
673             {
674               had_title = 1;
675               title = list->edict_arg;
676             }
677           list = list->next;
678           c--;
679         }
680
681       if (page > 1)
682         {
683           fprintf (list_file, "\f");
684         }
685
686       fprintf (list_file, "%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
687       fprintf (list_file, "%s\n", title);
688       fprintf (list_file, "%s\n", subtitle);
689       on_page = 3;
690       eject = 0;
691     }
692 }
693
694 /* Print a line into the list_file.  Update the line count
695    and if necessary start a new page.  */
696
697 static void
698 emit_line (list_info_type * list, const char * format, ...)
699 {
700   va_list args;
701
702   va_start (args, format);
703
704   vfprintf (list_file, format, args);
705   on_page++;
706   listing_page (list);
707
708   va_end (args);
709 }
710
711 static unsigned int
712 calc_hex (list_info_type *list)
713 {
714   int data_buffer_size;
715   list_info_type *first = list;
716   unsigned int address = ~(unsigned int) 0;
717   fragS *frag;
718   fragS *frag_ptr;
719   unsigned int octet_in_frag;
720
721   /* Find first frag which says it belongs to this line.  */
722   frag = list->frag;
723   while (frag && frag->line != list)
724     frag = frag->fr_next;
725
726   frag_ptr = frag;
727
728   data_buffer_size = 0;
729
730   /* Dump all the frags which belong to this line.  */
731   while (frag_ptr != (fragS *) NULL && frag_ptr->line == first)
732     {
733       /* Print as many bytes from the fixed part as is sensible.  */
734       octet_in_frag = 0;
735       while ((offsetT) octet_in_frag < frag_ptr->fr_fix
736              && data_buffer_size < MAX_BYTES - 3)
737         {
738           if (address == ~(unsigned int) 0)
739             address = frag_ptr->fr_address / OCTETS_PER_BYTE;
740
741           sprintf (data_buffer + data_buffer_size,
742                    "%02X",
743                    (frag_ptr->fr_literal[octet_in_frag]) & 0xff);
744           data_buffer_size += 2;
745           octet_in_frag++;
746         }
747       if (frag_ptr->fr_type == rs_fill)
748         {
749           unsigned int var_rep_max = octet_in_frag;
750           unsigned int var_rep_idx = octet_in_frag;
751
752           /* Print as many bytes from the variable part as is sensible.  */
753           while (((offsetT) octet_in_frag
754                   < (frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset))
755                  && data_buffer_size < MAX_BYTES - 3)
756             {
757               if (address == ~(unsigned int) 0)
758                 address = frag_ptr->fr_address / OCTETS_PER_BYTE;
759
760               sprintf (data_buffer + data_buffer_size,
761                        "%02X",
762                        (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
763               data_buffer_size += 2;
764
765               var_rep_idx++;
766               octet_in_frag++;
767
768               if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var)
769                 var_rep_idx = var_rep_max;
770             }
771         }
772
773       frag_ptr = frag_ptr->fr_next;
774     }
775   data_buffer[data_buffer_size] = '\0';
776   return address;
777 }
778
779 static void
780 print_lines (list_info_type *list, unsigned int lineno,
781              char *string, unsigned int address)
782 {
783   unsigned int idx;
784   unsigned int nchars;
785   unsigned int lines;
786   unsigned int octet_in_word = 0;
787   char *src = data_buffer;
788   int cur;
789
790   /* Print the stuff on the first line.  */
791   listing_page (list);
792   nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width;
793
794   /* Print the hex for the first line.  */
795   if (address == ~(unsigned int) 0)
796     {
797       fprintf (list_file, "% 4d     ", lineno);
798       for (idx = 0; idx < nchars; idx++)
799         fprintf (list_file, " ");
800
801       emit_line (NULL, "\t%s\n", string ? string : "");
802       return;
803     }
804
805   if (had_errors ())
806     fprintf (list_file, "% 4d ???? ", lineno);
807   else
808     fprintf (list_file, "% 4d %04x ", lineno, address);
809
810   /* And the data to go along with it.  */
811   idx = 0;
812   cur = 0;
813   while (src[cur] && idx < nchars)
814     {
815       int offset;
816       offset = cur;
817       fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
818       cur += 2;
819       octet_in_word++;
820
821       if (octet_in_word == LISTING_WORD_SIZE)
822         {
823           fprintf (list_file, " ");
824           idx++;
825           octet_in_word = 0;
826         }
827
828       idx += 2;
829     }
830
831   for (; idx < nchars; idx++)
832     fprintf (list_file, " ");
833
834   emit_line (list, "\t%s\n", string ? string : "");
835
836   if (list->message)
837     emit_line (list, "****  %s\n", list->message);
838
839   for (lines = 0;
840        lines < (unsigned int) listing_lhs_cont_lines
841          && src[cur];
842        lines++)
843     {
844       nchars = ((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second - 1;
845       idx = 0;
846
847       /* Print any more lines of data, but more compactly.  */
848       fprintf (list_file, "% 4d      ", lineno);
849
850       while (src[cur] && idx < nchars)
851         {
852           int offset;
853           offset = cur;
854           fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
855           cur += 2;
856           idx += 2;
857           octet_in_word++;
858
859           if (octet_in_word == LISTING_WORD_SIZE)
860             {
861               fprintf (list_file, " ");
862               idx++;
863               octet_in_word = 0;
864             }
865         }
866
867       emit_line (list, "\n");
868     }
869 }
870
871 static void
872 list_symbol_table (void)
873 {
874   extern symbolS *symbol_rootP;
875   int got_some = 0;
876
877   symbolS *ptr;
878   eject = 1;
879   listing_page (NULL);
880
881   for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
882     {
883       if (SEG_NORMAL (S_GET_SEGMENT (ptr))
884           || S_GET_SEGMENT (ptr) == absolute_section)
885         {
886           /* Don't report section symbols.  They are not interesting.  */
887           if (symbol_section_p (ptr))
888             continue;
889
890           if (S_GET_NAME (ptr))
891             {
892               char buf[30], fmt[8];
893               valueT val = S_GET_VALUE (ptr);
894
895               /* @@ Note that this is dependent on the compilation options,
896                  not solely on the target characteristics.  */
897               if (sizeof (val) == 4 && sizeof (int) == 4)
898                 sprintf (buf, "%08lx", (unsigned long) val);
899               else if (sizeof (val) <= sizeof (unsigned long))
900                 {
901                   sprintf (fmt, "%%0%lulx",
902                            (unsigned long) (sizeof (val) * 2));
903                   sprintf (buf, fmt, (unsigned long) val);
904                 }
905 #if defined (BFD64)
906               else if (sizeof (val) > 4)
907                 sprintf_vma (buf, val);
908 #endif
909               else
910                 abort ();
911
912               if (!got_some)
913                 {
914                   fprintf (list_file, "DEFINED SYMBOLS\n");
915                   on_page++;
916                   got_some = 1;
917                 }
918
919               if (symbol_get_frag (ptr) && symbol_get_frag (ptr)->line)
920                 {
921                   fprintf (list_file, "%20s:%-5d  %s:%s %s\n",
922                            symbol_get_frag (ptr)->line->file->filename,
923                            symbol_get_frag (ptr)->line->line,
924                            segment_name (S_GET_SEGMENT (ptr)),
925                            buf, S_GET_NAME (ptr));
926                 }
927               else
928                 {
929                   fprintf (list_file, "%33s:%s %s\n",
930                            segment_name (S_GET_SEGMENT (ptr)),
931                            buf, S_GET_NAME (ptr));
932                 }
933
934               on_page++;
935               listing_page (NULL);
936             }
937         }
938
939     }
940   if (!got_some)
941     {
942       fprintf (list_file, "NO DEFINED SYMBOLS\n");
943       on_page++;
944     }
945   emit_line (NULL, "\n");
946
947   got_some = 0;
948
949   for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
950     {
951       if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0)
952         {
953           if (S_GET_SEGMENT (ptr) == undefined_section)
954             {
955               if (!got_some)
956                 {
957                   got_some = 1;
958
959                   emit_line (NULL, "UNDEFINED SYMBOLS\n");
960                 }
961
962               emit_line (NULL, "%s\n", S_GET_NAME (ptr));
963             }
964         }
965     }
966
967   if (!got_some)
968     emit_line (NULL, "NO UNDEFINED SYMBOLS\n");
969 }
970
971 typedef struct cached_line
972 {
973   file_info_type * file;
974   unsigned int     line;
975   char             buffer [LISTING_RHS_WIDTH];
976 } cached_line;
977
978 static void
979 print_source (file_info_type *  current_file,
980               list_info_type *  list,
981               unsigned int      width)
982 {
983 #define NUM_CACHE_LINES  3
984   static cached_line cached_lines[NUM_CACHE_LINES];
985   static int next_free_line = 0;
986   cached_line * cache = NULL;
987
988   if (current_file->linenum > list->hll_line
989       && list->hll_line > 0)
990     {
991       /* This can happen with modern optimizing compilers.  The source
992          lines from the high level language input program are split up
993          and interleaved, meaning the line number we want to display
994          (list->hll_line) can have already been displayed.  We have
995          three choices:
996
997            a. Do nothing, since we have already displayed the source
998               line.  This was the old behaviour.
999
1000            b. Display the particular line requested again, but only
1001               that line.  This is the new behaviour.
1002
1003            c. Display the particular line requested again and reset
1004               the current_file->line_num value so that we redisplay
1005               all the following lines as well the next time we
1006               encounter a larger line number.  */
1007       int i;
1008
1009       /* Check the cache, maybe we already have the line saved.  */
1010       for (i = 0; i < NUM_CACHE_LINES; i++)
1011         if (cached_lines[i].file == current_file
1012             && cached_lines[i].line == list->hll_line)
1013           {
1014             cache = cached_lines + i;
1015             break;
1016           }
1017
1018       if (i == NUM_CACHE_LINES)
1019         {
1020           cache = cached_lines + next_free_line;
1021           next_free_line ++;
1022           if (next_free_line == NUM_CACHE_LINES)
1023             next_free_line = 0;
1024
1025           cache->file = current_file;
1026           cache->line = list->hll_line;
1027           cache->buffer[0] = 0;
1028           rebuffer_line (current_file, cache->line, cache->buffer, width);
1029         }
1030
1031       emit_line (list, "%4u:%-13s **** %s\n",
1032                  cache->line, cache->file->filename, cache->buffer);
1033       return;
1034     }
1035
1036   if (!current_file->at_end)
1037     {
1038       int num_lines_shown = 0;
1039
1040       while (current_file->linenum < list->hll_line
1041              && !current_file->at_end)
1042         {
1043           cached_line * cache = cached_lines + next_free_line;
1044           char *p;
1045
1046           cache->file = current_file;
1047           cache->line = current_file->linenum;
1048           cache->buffer[0] = 0;
1049           p = buffer_line (current_file, cache->buffer, width);
1050
1051           /* Cache optimization:  If printing a group of lines
1052              cache the first and last lines in the group.  */
1053           if (num_lines_shown == 0)
1054             {
1055               next_free_line ++;
1056               if (next_free_line == NUM_CACHE_LINES)
1057                 next_free_line = 0;
1058             }
1059
1060           emit_line (list, "%4u:%-13s **** %s\n",
1061                      cache->line, cache->file->filename, p);
1062           num_lines_shown ++;
1063         }
1064     }
1065 }
1066
1067 /* Sometimes the user doesn't want to be bothered by the debugging
1068    records inserted by the compiler, see if the line is suspicious.  */
1069
1070 static int
1071 debugging_pseudo (list_info_type *list, const char *line)
1072 {
1073   static int in_debug;
1074   int was_debug;
1075
1076   if (list->debugging)
1077     {
1078       in_debug = 1;
1079       return 1;
1080     }
1081
1082   was_debug = in_debug;
1083   in_debug = 0;
1084
1085   while (ISSPACE (*line))
1086     line++;
1087
1088   if (*line != '.')
1089     {
1090 #ifdef OBJ_ELF
1091       /* The ELF compiler sometimes emits blank lines after switching
1092          out of a debugging section.  If the next line drops us back
1093          into debugging information, then don't print the blank line.
1094          This is a hack for a particular compiler behaviour, not a
1095          general case.  */
1096       if (was_debug
1097           && *line == '\0'
1098           && list->next != NULL
1099           && list->next->debugging)
1100         {
1101           in_debug = 1;
1102           return 1;
1103         }
1104 #endif
1105
1106       return 0;
1107     }
1108
1109   line++;
1110
1111   if (strncmp (line, "def", 3) == 0)
1112     return 1;
1113   if (strncmp (line, "val", 3) == 0)
1114     return 1;
1115   if (strncmp (line, "scl", 3) == 0)
1116     return 1;
1117   if (strncmp (line, "line", 4) == 0)
1118     return 1;
1119   if (strncmp (line, "endef", 5) == 0)
1120     return 1;
1121   if (strncmp (line, "ln", 2) == 0)
1122     return 1;
1123   if (strncmp (line, "type", 4) == 0)
1124     return 1;
1125   if (strncmp (line, "size", 4) == 0)
1126     return 1;
1127   if (strncmp (line, "dim", 3) == 0)
1128     return 1;
1129   if (strncmp (line, "tag", 3) == 0)
1130     return 1;
1131   if (strncmp (line, "stabs", 5) == 0)
1132     return 1;
1133   if (strncmp (line, "stabn", 5) == 0)
1134     return 1;
1135
1136   return 0;
1137 }
1138
1139 static void
1140 listing_listing (char *name ATTRIBUTE_UNUSED)
1141 {
1142   list_info_type *list = head;
1143   file_info_type *current_hll_file = (file_info_type *) NULL;
1144   char *message;
1145   char *buffer;
1146   char *p;
1147   int show_listing = 1;
1148   unsigned int width;
1149
1150   buffer = xmalloc (listing_rhs_width);
1151   data_buffer = xmalloc (MAX_BYTES);
1152   eject = 1;
1153   list = head->next;
1154
1155   while (list)
1156     {
1157       unsigned int list_line;
1158
1159       width = listing_rhs_width > paper_width ? paper_width :
1160         listing_rhs_width;
1161
1162       list_line = list->line;
1163       switch (list->edict)
1164         {
1165         case EDICT_LIST:
1166           /* Skip all lines up to the current.  */
1167           list_line--;
1168           break;
1169         case EDICT_NOLIST:
1170           show_listing--;
1171           break;
1172         case EDICT_NOLIST_NEXT:
1173           if (show_listing == 0)
1174             list_line--;
1175           break;
1176         case EDICT_EJECT:
1177           break;
1178         case EDICT_NONE:
1179           break;
1180         case EDICT_TITLE:
1181           title = list->edict_arg;
1182           break;
1183         case EDICT_SBTTL:
1184           subtitle = list->edict_arg;
1185           break;
1186         default:
1187           abort ();
1188         }
1189
1190       if (show_listing <= 0)
1191         {
1192           while (list->file->linenum < list_line
1193                  && !list->file->at_end)
1194             p = buffer_line (list->file, buffer, width);
1195         }
1196
1197       if (list->edict == EDICT_LIST
1198           || (list->edict == EDICT_NOLIST_NEXT && show_listing == 0))
1199         {
1200           /* Enable listing for the single line that caused the enable.  */
1201           list_line++;
1202           show_listing++;
1203         }
1204
1205       if (show_listing > 0)
1206         {
1207           /* Scan down the list and print all the stuff which can be done
1208              with this line (or lines).  */
1209           message = 0;
1210
1211           if (list->hll_file)
1212             current_hll_file = list->hll_file;
1213
1214           if (current_hll_file && list->hll_line && (listing & LISTING_HLL))
1215             print_source (current_hll_file, list, width);
1216
1217           if (list->line_contents)
1218             {
1219               if (!((listing & LISTING_NODEBUG)
1220                     && debugging_pseudo (list, list->line_contents)))
1221                 print_lines (list,
1222                              list->file->linenum == 0 ? list->line : list->file->linenum,
1223                              list->line_contents, calc_hex (list));
1224
1225               free (list->line_contents);
1226               list->line_contents = NULL;
1227             }
1228           else
1229             {
1230               while (list->file->linenum < list_line
1231                      && !list->file->at_end)
1232                 {
1233                   unsigned int address;
1234
1235                   p = buffer_line (list->file, buffer, width);
1236
1237                   if (list->file->linenum < list_line)
1238                     address = ~(unsigned int) 0;
1239                   else
1240                     address = calc_hex (list);
1241
1242                   if (!((listing & LISTING_NODEBUG)
1243                         && debugging_pseudo (list, p)))
1244                     print_lines (list, list->file->linenum, p, address);
1245                 }
1246             }
1247
1248           if (list->edict == EDICT_EJECT)
1249             eject = 1;
1250         }
1251
1252       if (list->edict == EDICT_NOLIST_NEXT && show_listing == 1)
1253         --show_listing;
1254
1255       list = list->next;
1256     }
1257
1258   free (buffer);
1259   free (data_buffer);
1260   data_buffer = NULL;
1261 }
1262
1263 /* Print time stamp in ISO format:  yyyy-mm-ddThh:mm:ss.ss+/-zzzz.  */
1264
1265 static void
1266 print_timestamp (void)
1267 {
1268   const time_t now = time (NULL);
1269   struct tm * timestamp;
1270   char stampstr[MAX_DATELEN];
1271
1272   /* Any portable way to obtain subsecond values???  */
1273   timestamp = localtime (&now);
1274   strftime (stampstr, MAX_DATELEN, "%Y-%m-%dT%H:%M:%S.000%z", timestamp);
1275   fprintf (list_file, _("\n time stamp    \t: %s\n\n"), stampstr);
1276 }
1277
1278 static void
1279 print_single_option (char * opt, int *pos)
1280 {
1281   int opt_len = strlen (opt);
1282
1283    if ((*pos + opt_len) < paper_width)
1284      {
1285         fprintf (list_file, _("%s "), opt);
1286         *pos = *pos + opt_len;
1287      }
1288    else
1289      {
1290         fprintf (list_file, _("\n\t%s "), opt);
1291         *pos = opt_len;
1292      }
1293 }
1294
1295 /* Print options passed to as.  */
1296
1297 static void
1298 print_options (char ** argv)
1299 {
1300   const char *field_name = _("\n options passed\t: ");
1301   int pos = strlen (field_name);
1302   char **p;
1303
1304   fputs (field_name, list_file);
1305   for (p = &argv[1]; *p != NULL; p++)
1306     if (**p == '-')
1307       {
1308         /* Ignore these.  */
1309         if (strcmp (*p, "-o") == 0)
1310           {
1311             if (p[1] != NULL)
1312               p++;
1313             continue;
1314           }
1315         if (strcmp (*p, "-v") == 0)
1316           continue;
1317
1318         print_single_option (*p, &pos);
1319       }
1320 }
1321
1322 /* Print a first section with basic info like file names, as version,
1323    options passed, target, and timestamp.
1324    The format of this section is as follows:
1325
1326    AS VERSION
1327
1328    fieldname TAB ':' fieldcontents
1329   { TAB fieldcontents-cont }  */
1330
1331 static void
1332 listing_general_info (char ** argv)
1333 {
1334   /* Print the stuff on the first line.  */
1335   eject = 1;
1336   listing_page (NULL);
1337
1338   fprintf (list_file,
1339            _(" GNU assembler version %s (%s)\n\t using BFD version %s."),
1340            VERSION, TARGET_ALIAS, BFD_VERSION_STRING);
1341   print_options (argv);
1342   fprintf (list_file, _("\n input file    \t: %s"), fn);
1343   fprintf (list_file, _("\n output file   \t: %s"), out_file_name);
1344   fprintf (list_file, _("\n target        \t: %s"), TARGET_CANONICAL);
1345   print_timestamp ();
1346 }
1347
1348 void
1349 listing_print (char *name, char **argv)
1350 {
1351   int using_stdout;
1352
1353   title = "";
1354   subtitle = "";
1355
1356   if (name == NULL)
1357     {
1358       list_file = stdout;
1359       using_stdout = 1;
1360     }
1361   else
1362     {
1363       list_file = fopen (name, FOPEN_WT);
1364       if (list_file != NULL)
1365         using_stdout = 0;
1366       else
1367         {
1368           as_warn (_("can't open %s: %s"), name, xstrerror (errno));
1369           list_file = stdout;
1370           using_stdout = 1;
1371         }
1372     }
1373
1374   if (listing & LISTING_NOFORM)
1375     paper_height = 0;
1376
1377   if (listing & LISTING_GENERAL)
1378     listing_general_info (argv);
1379
1380   if (listing & LISTING_LISTING)
1381     listing_listing (name);
1382
1383   if (listing & LISTING_SYMBOLS)
1384     list_symbol_table ();
1385
1386   if (! using_stdout)
1387     {
1388       if (fclose (list_file) == EOF)
1389         as_warn (_("can't close %s: %s"), name, xstrerror (errno));
1390     }
1391
1392   if (last_open_file)
1393     fclose (last_open_file);
1394 }
1395
1396 void
1397 listing_file (const char *name)
1398 {
1399   fn = name;
1400 }
1401
1402 void
1403 listing_eject (int ignore ATTRIBUTE_UNUSED)
1404 {
1405   if (listing)
1406     listing_tail->edict = EDICT_EJECT;
1407 }
1408
1409 void
1410 listing_flags (int ignore ATTRIBUTE_UNUSED)
1411 {
1412   while ((*input_line_pointer++) && (*input_line_pointer != '\n'))
1413     input_line_pointer++;
1414
1415 }
1416
1417 /* Turn listing on or off.  An argument of 0 means to turn off
1418    listing.  An argument of 1 means to turn on listing.  An argument
1419    of 2 means to turn off listing, but as of the next line; that is,
1420    the current line should be listed, but the next line should not.  */
1421
1422 void
1423 listing_list (int on)
1424 {
1425   if (listing)
1426     {
1427       switch (on)
1428         {
1429         case 0:
1430           if (listing_tail->edict == EDICT_LIST)
1431             listing_tail->edict = EDICT_NONE;
1432           else
1433             listing_tail->edict = EDICT_NOLIST;
1434           break;
1435         case 1:
1436           if (listing_tail->edict == EDICT_NOLIST
1437               || listing_tail->edict == EDICT_NOLIST_NEXT)
1438             listing_tail->edict = EDICT_NONE;
1439           else
1440             listing_tail->edict = EDICT_LIST;
1441           break;
1442         case 2:
1443           listing_tail->edict = EDICT_NOLIST_NEXT;
1444           break;
1445         default:
1446           abort ();
1447         }
1448     }
1449 }
1450
1451 void
1452 listing_psize (int width_only)
1453 {
1454   if (! width_only)
1455     {
1456       paper_height = get_absolute_expression ();
1457
1458       if (paper_height < 0 || paper_height > 1000)
1459         {
1460           paper_height = 0;
1461           as_warn (_("strange paper height, set to no form"));
1462         }
1463
1464       if (*input_line_pointer != ',')
1465         {
1466           demand_empty_rest_of_line ();
1467           return;
1468         }
1469
1470       ++input_line_pointer;
1471     }
1472
1473   paper_width = get_absolute_expression ();
1474
1475   demand_empty_rest_of_line ();
1476 }
1477
1478 void
1479 listing_nopage (int ignore ATTRIBUTE_UNUSED)
1480 {
1481   paper_height = 0;
1482 }
1483
1484 void
1485 listing_title (int depth)
1486 {
1487   int quoted;
1488   char *start;
1489   char *ttl;
1490   unsigned int length;
1491
1492   SKIP_WHITESPACE ();
1493   if (*input_line_pointer != '\"')
1494     quoted = 0;
1495   else
1496     {
1497       quoted = 1;
1498       ++input_line_pointer;
1499     }
1500
1501   start = input_line_pointer;
1502
1503   while (*input_line_pointer)
1504     {
1505       if (quoted
1506           ? *input_line_pointer == '\"'
1507           : is_end_of_line[(unsigned char) *input_line_pointer])
1508         {
1509           if (listing)
1510             {
1511               length = input_line_pointer - start;
1512               ttl = xmalloc (length + 1);
1513               memcpy (ttl, start, length);
1514               ttl[length] = 0;
1515               listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
1516               listing_tail->edict_arg = ttl;
1517             }
1518           if (quoted)
1519             input_line_pointer++;
1520           demand_empty_rest_of_line ();
1521           return;
1522         }
1523       else if (*input_line_pointer == '\n')
1524         {
1525           as_bad (_("new line in title"));
1526           demand_empty_rest_of_line ();
1527           return;
1528         }
1529       else
1530         {
1531           input_line_pointer++;
1532         }
1533     }
1534 }
1535
1536 void
1537 listing_source_line (unsigned int line)
1538 {
1539   if (listing)
1540     {
1541       new_frag ();
1542       listing_tail->hll_line = line;
1543       new_frag ();
1544     }
1545 }
1546
1547 void
1548 listing_source_file (const char *file)
1549 {
1550   if (listing)
1551     listing_tail->hll_file = file_info (file);
1552 }
1553
1554 #else
1555
1556 /* Dummy functions for when compiled without listing enabled.  */
1557
1558 void
1559 listing_flags (int ignore)
1560 {
1561   s_ignore (0);
1562 }
1563
1564 void
1565 listing_list (int on)
1566 {
1567   s_ignore (0);
1568 }
1569
1570 void
1571 listing_eject (int ignore)
1572 {
1573   s_ignore (0);
1574 }
1575
1576 void
1577 listing_psize (int ignore)
1578 {
1579   s_ignore (0);
1580 }
1581
1582 void
1583 listing_nopage (int ignore)
1584 {
1585   s_ignore (0);
1586 }
1587
1588 void
1589 listing_title (int depth)
1590 {
1591   s_ignore (0);
1592 }
1593
1594 void
1595 listing_file (const char *name)
1596 {
1597 }
1598
1599 void
1600 listing_newline (char *name)
1601 {
1602 }
1603
1604 void
1605 listing_source_line (unsigned int n)
1606 {
1607 }
1608
1609 void
1610 listing_source_file (const char *n)
1611 {
1612 }
1613
1614 #endif