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