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