2009-03-23 H.J. Lu <hongjiu.lu@intel.com>
[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           int seen_slash = 0;
342
343           for (copy = input_line_pointer - 1;
344                *copy && (seen_quote
345                          || is_end_of_line [(unsigned char) *copy] != 1);
346                copy++)
347             {
348               if (*copy == '\\')
349                 seen_slash = ! seen_slash;
350               else if (*copy == '"' && seen_slash)
351                 seen_quote = ! seen_quote;
352             }
353
354           len = (copy - input_line_pointer) + 2;
355
356           copy = xmalloc (len);
357
358           if (copy != NULL)
359             {
360               char *src = input_line_pointer - 1;
361               char *dest = copy;
362
363               while (--len)
364                 {
365                   unsigned char c = *src++;
366
367                   /* Omit control characters in the listing.  */
368                   if (!ISCNTRL (c))
369                     *dest++ = c;
370                 }
371
372               *dest = 0;
373             }
374
375           new->line_contents = copy;
376         }
377       else
378         new->line_contents = NULL;
379     }
380   else
381     {
382       new = xmalloc (sizeof (list_info_type));
383       new->line_contents = ps;
384     }
385
386   last_line = line;
387   last_file = file;
388
389   new_frag ();
390
391   if (listing_tail)
392     listing_tail->next = new;
393   else
394     head = new;
395
396   listing_tail = new;
397
398   new->frag = frag_now;
399   new->line = line;
400   new->file = file_info (file);
401   new->next = (list_info_type *) NULL;
402   new->message = (char *) NULL;
403   new->edict = EDICT_NONE;
404   new->hll_file = (file_info_type *) NULL;
405   new->hll_line = 0;
406   new->debugging = 0;
407
408   new_frag ();
409
410 #ifdef OBJ_ELF
411   /* In ELF, anything in a section beginning with .debug or .line is
412      considered to be debugging information.  */
413   if ((listing & LISTING_NODEBUG) != 0)
414     {
415       const char *segname;
416
417       segname = segment_name (now_seg);
418       if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
419           || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
420         new->debugging = 1;
421     }
422 #endif
423 }
424
425 /* Attach all current frags to the previous line instead of the
426    current line.  This is called by the MIPS backend when it discovers
427    that it needs to add some NOP instructions; the added NOP
428    instructions should go with the instruction that has the delay, not
429    with the new instruction.  */
430
431 void
432 listing_prev_line (void)
433 {
434   list_info_type *l;
435   fragS *f;
436
437   if (head == (list_info_type *) NULL
438       || head == listing_tail)
439     return;
440
441   new_frag ();
442
443   for (l = head; l->next != listing_tail; l = l->next)
444     ;
445
446   for (f = frchain_now->frch_root; f != (fragS *) NULL; f = f->fr_next)
447     if (f->line == listing_tail)
448       f->line = l;
449
450   listing_tail->frag = frag_now;
451   new_frag ();
452 }
453
454 /* This function returns the next source line from the file supplied,
455    truncated to size.  It appends a fake line to the end of each input
456    file to make.  */
457
458 static char *
459 buffer_line (file_info_type *file, char *line, unsigned int size)
460 {
461   unsigned int count = 0;
462   int c;
463
464   char *p = line;
465
466   /* If we couldn't open the file, return an empty line.  */
467   if (file->at_end)
468     return "";
469
470   /* Check the cache and see if we last used this file.  */
471   if (!last_open_file_info || file != last_open_file_info)
472     {
473       if (last_open_file)
474         {
475           last_open_file_info->pos = ftell (last_open_file);
476           fclose (last_open_file);
477         }
478
479       /* Open the file in the binary mode so that ftell above can
480          return a reliable value that we can feed to fseek below.  */
481       last_open_file_info = file;
482       last_open_file = fopen (file->filename, FOPEN_RB);
483       if (last_open_file == NULL)
484         {
485           file->at_end = 1;
486           return "";
487         }
488
489       /* Seek to where we were last time this file was open.  */
490       if (file->pos)
491         fseek (last_open_file, file->pos, SEEK_SET);
492     }
493
494   c = fgetc (last_open_file);
495
496   /* Leave room for null.  */
497   size -= 1;
498
499   while (c != EOF && c != '\n' && c != '\r')
500     {
501       if (count < size)
502         *p++ = c;
503       count++;
504
505       c = fgetc (last_open_file);
506
507     }
508
509   /* If '\r' is followed by '\n', swallow that.  Likewise, if '\n'
510      is followed by '\r', swallow that as well.  */
511   if (c == '\r' || c == '\n')
512     {
513       int next = fgetc (last_open_file);
514       if ((c == '\r' && next != '\n')
515           || (c == '\n' && next != '\r'))
516         ungetc (next, last_open_file);
517     }
518
519   if (c == EOF)
520     {
521       file->at_end = 1;
522       if (count + 2 < size)
523         {
524           *p++ = '.';
525           *p++ = '.';
526           *p++ = '.';
527         }
528     }
529   file->linenum++;
530   *p++ = 0;
531   return line;
532 }
533
534 static const char *fn;
535
536 static unsigned int eject;      /* Eject pending */
537 static unsigned int page;       /* Current page number */
538 static char *title;             /* Current title */
539 static char *subtitle;          /* Current subtitle */
540 static unsigned int on_page;    /* Number of lines printed on current page */
541
542 static void
543 listing_page (list_info_type *list)
544 {
545   /* Grope around, see if we can see a title or subtitle edict coming up
546      soon.  (we look down 10 lines of the page and see if it's there)  */
547   if ((eject || (on_page >= (unsigned int) paper_height))
548       && paper_height != 0)
549     {
550       unsigned int c = 10;
551       int had_title = 0;
552       int had_subtitle = 0;
553
554       page++;
555
556       while (c != 0 && list)
557         {
558           if (list->edict == EDICT_SBTTL && !had_subtitle)
559             {
560               had_subtitle = 1;
561               subtitle = list->edict_arg;
562             }
563           if (list->edict == EDICT_TITLE && !had_title)
564             {
565               had_title = 1;
566               title = list->edict_arg;
567             }
568           list = list->next;
569           c--;
570         }
571
572       if (page > 1)
573         {
574           fprintf (list_file, "\f");
575         }
576
577       fprintf (list_file, "%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
578       fprintf (list_file, "%s\n", title);
579       fprintf (list_file, "%s\n", subtitle);
580       on_page = 3;
581       eject = 0;
582     }
583 }
584
585 static unsigned int
586 calc_hex (list_info_type *list)
587 {
588   int data_buffer_size;
589   list_info_type *first = list;
590   unsigned int address = ~(unsigned int) 0;
591   fragS *frag;
592   fragS *frag_ptr;
593   unsigned int octet_in_frag;
594
595   /* Find first frag which says it belongs to this line.  */
596   frag = list->frag;
597   while (frag && frag->line != list)
598     frag = frag->fr_next;
599
600   frag_ptr = frag;
601
602   data_buffer_size = 0;
603
604   /* Dump all the frags which belong to this line.  */
605   while (frag_ptr != (fragS *) NULL && frag_ptr->line == first)
606     {
607       /* Print as many bytes from the fixed part as is sensible.  */
608       octet_in_frag = 0;
609       while ((offsetT) octet_in_frag < frag_ptr->fr_fix
610              && data_buffer_size < MAX_BYTES - 3)
611         {
612           if (address == ~(unsigned int) 0)
613             address = frag_ptr->fr_address / OCTETS_PER_BYTE;
614
615           sprintf (data_buffer + data_buffer_size,
616                    "%02X",
617                    (frag_ptr->fr_literal[octet_in_frag]) & 0xff);
618           data_buffer_size += 2;
619           octet_in_frag++;
620         }
621       if (frag_ptr->fr_type == rs_fill)
622         {
623           unsigned int var_rep_max = octet_in_frag;
624           unsigned int var_rep_idx = octet_in_frag;
625
626           /* Print as many bytes from the variable part as is sensible.  */
627           while (((offsetT) octet_in_frag
628                   < (frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset))
629                  && data_buffer_size < MAX_BYTES - 3)
630             {
631               if (address == ~(unsigned int) 0)
632                 address = frag_ptr->fr_address / OCTETS_PER_BYTE;
633
634               sprintf (data_buffer + data_buffer_size,
635                        "%02X",
636                        (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
637               data_buffer_size += 2;
638
639               var_rep_idx++;
640               octet_in_frag++;
641
642               if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var)
643                 var_rep_idx = var_rep_max;
644             }
645         }
646
647       frag_ptr = frag_ptr->fr_next;
648     }
649   data_buffer[data_buffer_size] = '\0';
650   return address;
651 }
652
653 static void
654 print_lines (list_info_type *list, unsigned int lineno,
655              char *string, unsigned int address)
656 {
657   unsigned int idx;
658   unsigned int nchars;
659   unsigned int lines;
660   unsigned int octet_in_word = 0;
661   char *src = data_buffer;
662   int cur;
663
664   /* Print the stuff on the first line.  */
665   listing_page (list);
666   nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width;
667
668   /* Print the hex for the first line.  */
669   if (address == ~(unsigned int) 0)
670     {
671       fprintf (list_file, "% 4d     ", lineno);
672       for (idx = 0; idx < nchars; idx++)
673         fprintf (list_file, " ");
674
675       fprintf (list_file, "\t%s\n", string ? string : "");
676
677       on_page++;
678
679       listing_page (0);
680
681       return;
682     }
683
684   if (had_errors ())
685     fprintf (list_file, "% 4d ???? ", lineno);
686   else
687     fprintf (list_file, "% 4d %04x ", lineno, address);
688
689   /* And the data to go along with it.  */
690   idx = 0;
691   cur = 0;
692   while (src[cur] && idx < nchars)
693     {
694       int offset;
695       offset = cur;
696       fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
697       cur += 2;
698       octet_in_word++;
699
700       if (octet_in_word == LISTING_WORD_SIZE)
701         {
702           fprintf (list_file, " ");
703           idx++;
704           octet_in_word = 0;
705         }
706
707       idx += 2;
708     }
709
710   for (; idx < nchars; idx++)
711     fprintf (list_file, " ");
712
713   fprintf (list_file, "\t%s\n", string ? string : "");
714   on_page++;
715   listing_page (list);
716
717   if (list->message)
718     {
719       fprintf (list_file, "****  %s\n", list->message);
720       listing_page (list);
721       on_page++;
722     }
723
724   for (lines = 0;
725        lines < (unsigned int) listing_lhs_cont_lines
726          && src[cur];
727        lines++)
728     {
729       nchars = ((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second - 1;
730       idx = 0;
731
732       /* Print any more lines of data, but more compactly.  */
733       fprintf (list_file, "% 4d      ", lineno);
734
735       while (src[cur] && idx < nchars)
736         {
737           int offset;
738           offset = cur;
739           fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
740           cur += 2;
741           idx += 2;
742           octet_in_word++;
743
744           if (octet_in_word == LISTING_WORD_SIZE)
745             {
746               fprintf (list_file, " ");
747               idx++;
748               octet_in_word = 0;
749             }
750         }
751
752       fprintf (list_file, "\n");
753       on_page++;
754       listing_page (list);
755     }
756 }
757
758 static void
759 list_symbol_table (void)
760 {
761   extern symbolS *symbol_rootP;
762   int got_some = 0;
763
764   symbolS *ptr;
765   eject = 1;
766   listing_page (0);
767
768   for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
769     {
770       if (SEG_NORMAL (S_GET_SEGMENT (ptr))
771           || S_GET_SEGMENT (ptr) == absolute_section)
772         {
773           /* Don't report section symbols.  They are not interesting.  */
774           if (symbol_section_p (ptr))
775             continue;
776
777           if (S_GET_NAME (ptr))
778             {
779               char buf[30], fmt[8];
780               valueT val = S_GET_VALUE (ptr);
781
782               /* @@ Note that this is dependent on the compilation options,
783                  not solely on the target characteristics.  */
784               if (sizeof (val) == 4 && sizeof (int) == 4)
785                 sprintf (buf, "%08lx", (unsigned long) val);
786               else if (sizeof (val) <= sizeof (unsigned long))
787                 {
788                   sprintf (fmt, "%%0%lulx",
789                            (unsigned long) (sizeof (val) * 2));
790                   sprintf (buf, fmt, (unsigned long) val);
791                 }
792 #if defined (BFD64)
793               else if (sizeof (val) > 4)
794                 sprintf_vma (buf, val);
795 #endif
796               else
797                 abort ();
798
799               if (!got_some)
800                 {
801                   fprintf (list_file, "DEFINED SYMBOLS\n");
802                   on_page++;
803                   got_some = 1;
804                 }
805
806               if (symbol_get_frag (ptr) && symbol_get_frag (ptr)->line)
807                 {
808                   fprintf (list_file, "%20s:%-5d  %s:%s %s\n",
809                            symbol_get_frag (ptr)->line->file->filename,
810                            symbol_get_frag (ptr)->line->line,
811                            segment_name (S_GET_SEGMENT (ptr)),
812                            buf, S_GET_NAME (ptr));
813                 }
814               else
815                 {
816                   fprintf (list_file, "%33s:%s %s\n",
817                            segment_name (S_GET_SEGMENT (ptr)),
818                            buf, S_GET_NAME (ptr));
819                 }
820
821               on_page++;
822               listing_page (0);
823             }
824         }
825
826     }
827   if (!got_some)
828     {
829       fprintf (list_file, "NO DEFINED SYMBOLS\n");
830       on_page++;
831     }
832   fprintf (list_file, "\n");
833   on_page++;
834   listing_page (0);
835
836   got_some = 0;
837
838   for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
839     {
840       if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0)
841         {
842           if (S_GET_SEGMENT (ptr) == undefined_section)
843             {
844               if (!got_some)
845                 {
846                   got_some = 1;
847                   fprintf (list_file, "UNDEFINED SYMBOLS\n");
848                   on_page++;
849                   listing_page (0);
850                 }
851               fprintf (list_file, "%s\n", S_GET_NAME (ptr));
852               on_page++;
853               listing_page (0);
854             }
855         }
856     }
857   if (!got_some)
858     {
859       fprintf (list_file, "NO UNDEFINED SYMBOLS\n");
860       on_page++;
861       listing_page (0);
862     }
863 }
864
865 static void
866 print_source (file_info_type *current_file, list_info_type *list,
867               char *buffer, unsigned int width)
868 {
869   if (!current_file->at_end)
870     {
871       while (current_file->linenum < list->hll_line
872              && !current_file->at_end)
873         {
874           char *p = buffer_line (current_file, buffer, width);
875
876           fprintf (list_file, "%4u:%-13s **** %s\n", current_file->linenum,
877                    current_file->filename, p);
878           on_page++;
879           listing_page (list);
880         }
881     }
882 }
883
884 /* Sometimes the user doesn't want to be bothered by the debugging
885    records inserted by the compiler, see if the line is suspicious.  */
886
887 static int
888 debugging_pseudo (list_info_type *list, const char *line)
889 {
890   static int in_debug;
891   int was_debug;
892
893   if (list->debugging)
894     {
895       in_debug = 1;
896       return 1;
897     }
898
899   was_debug = in_debug;
900   in_debug = 0;
901
902   while (ISSPACE (*line))
903     line++;
904
905   if (*line != '.')
906     {
907 #ifdef OBJ_ELF
908       /* The ELF compiler sometimes emits blank lines after switching
909          out of a debugging section.  If the next line drops us back
910          into debugging information, then don't print the blank line.
911          This is a hack for a particular compiler behaviour, not a
912          general case.  */
913       if (was_debug
914           && *line == '\0'
915           && list->next != NULL
916           && list->next->debugging)
917         {
918           in_debug = 1;
919           return 1;
920         }
921 #endif
922
923       return 0;
924     }
925
926   line++;
927
928   if (strncmp (line, "def", 3) == 0)
929     return 1;
930   if (strncmp (line, "val", 3) == 0)
931     return 1;
932   if (strncmp (line, "scl", 3) == 0)
933     return 1;
934   if (strncmp (line, "line", 4) == 0)
935     return 1;
936   if (strncmp (line, "endef", 5) == 0)
937     return 1;
938   if (strncmp (line, "ln", 2) == 0)
939     return 1;
940   if (strncmp (line, "type", 4) == 0)
941     return 1;
942   if (strncmp (line, "size", 4) == 0)
943     return 1;
944   if (strncmp (line, "dim", 3) == 0)
945     return 1;
946   if (strncmp (line, "tag", 3) == 0)
947     return 1;
948   if (strncmp (line, "stabs", 5) == 0)
949     return 1;
950   if (strncmp (line, "stabn", 5) == 0)
951     return 1;
952
953   return 0;
954 }
955
956 static void
957 listing_listing (char *name ATTRIBUTE_UNUSED)
958 {
959   list_info_type *list = head;
960   file_info_type *current_hll_file = (file_info_type *) NULL;
961   char *message;
962   char *buffer;
963   char *p;
964   int show_listing = 1;
965   unsigned int width;
966
967   buffer = xmalloc (listing_rhs_width);
968   data_buffer = xmalloc (MAX_BYTES);
969   eject = 1;
970   list = head->next;
971
972   while (list)
973     {
974       unsigned int list_line;
975
976       width = listing_rhs_width > paper_width ? paper_width :
977         listing_rhs_width;
978
979       list_line = list->line;
980       switch (list->edict)
981         {
982         case EDICT_LIST:
983           /* Skip all lines up to the current.  */
984           list_line--;
985           break;
986         case EDICT_NOLIST:
987           show_listing--;
988           break;
989         case EDICT_NOLIST_NEXT:
990           if (show_listing == 0)
991             list_line--;
992           break;
993         case EDICT_EJECT:
994           break;
995         case EDICT_NONE:
996           break;
997         case EDICT_TITLE:
998           title = list->edict_arg;
999           break;
1000         case EDICT_SBTTL:
1001           subtitle = list->edict_arg;
1002           break;
1003         default:
1004           abort ();
1005         }
1006
1007       if (show_listing <= 0)
1008         {
1009           while (list->file->linenum < list_line
1010                  && !list->file->at_end)
1011             p = buffer_line (list->file, buffer, width);
1012         }
1013
1014       if (list->edict == EDICT_LIST
1015           || (list->edict == EDICT_NOLIST_NEXT && show_listing == 0))
1016         {
1017           /* Enable listing for the single line that caused the enable.  */
1018           list_line++;
1019           show_listing++;
1020         }
1021
1022       if (show_listing > 0)
1023         {
1024           /* Scan down the list and print all the stuff which can be done
1025              with this line (or lines).  */
1026           message = 0;
1027
1028           if (list->hll_file)
1029             current_hll_file = list->hll_file;
1030
1031           if (current_hll_file && list->hll_line && (listing & LISTING_HLL))
1032             print_source (current_hll_file, list, buffer, width);
1033
1034           if (list->line_contents)
1035             {
1036               if (!((listing & LISTING_NODEBUG)
1037                     && debugging_pseudo (list, list->line_contents)))
1038                 print_lines (list,
1039                              list->file->linenum == 0 ? list->line : list->file->linenum,
1040                              list->line_contents, calc_hex (list));
1041
1042               free (list->line_contents);
1043               list->line_contents = NULL;
1044             }
1045           else
1046             {
1047               while (list->file->linenum < list_line
1048                      && !list->file->at_end)
1049                 {
1050                   unsigned int address;
1051
1052                   p = buffer_line (list->file, buffer, width);
1053
1054                   if (list->file->linenum < list_line)
1055                     address = ~(unsigned int) 0;
1056                   else
1057                     address = calc_hex (list);
1058
1059                   if (!((listing & LISTING_NODEBUG)
1060                         && debugging_pseudo (list, p)))
1061                     print_lines (list, list->file->linenum, p, address);
1062                 }
1063             }
1064
1065           if (list->edict == EDICT_EJECT)
1066             eject = 1;
1067         }
1068
1069       if (list->edict == EDICT_NOLIST_NEXT && show_listing == 1)
1070         --show_listing;
1071
1072       list = list->next;
1073     }
1074
1075   free (buffer);
1076   free (data_buffer);
1077   data_buffer = NULL;
1078 }
1079
1080 /* Print time stamp in ISO format:  yyyy-mm-ddThh:mm:ss.ss+/-zzzz.  */
1081
1082 static void
1083 print_timestamp (void)
1084 {
1085   const time_t now = time (NULL);
1086   struct tm * timestamp;
1087   char stampstr[MAX_DATELEN];
1088
1089   /* Any portable way to obtain subsecond values???  */
1090   timestamp = localtime (&now);
1091   strftime (stampstr, MAX_DATELEN, "%Y-%m-%dT%H:%M:%S.000%z", timestamp);
1092   fprintf (list_file, _("\n time stamp    \t: %s\n\n"), stampstr);
1093 }
1094
1095 static void
1096 print_single_option (char * opt, int *pos)
1097 {
1098   int opt_len = strlen (opt);
1099
1100    if ((*pos + opt_len) < paper_width)
1101      {
1102         fprintf (list_file, _("%s "), opt);
1103         *pos = *pos + opt_len;
1104      }
1105    else
1106      {
1107         fprintf (list_file, _("\n\t%s "), opt);
1108         *pos = opt_len;
1109      }
1110 }
1111
1112 /* Print options passed to as.  */
1113
1114 static void
1115 print_options (char ** argv)
1116 {
1117   const char *field_name = _("\n options passed\t: ");
1118   int pos = strlen (field_name);
1119   char **p;
1120
1121   fputs (field_name, list_file);
1122   for (p = &argv[1]; *p != NULL; p++)
1123     if (**p == '-')
1124       {
1125         /* Ignore these.  */
1126         if (strcmp (*p, "-o") == 0)
1127           {
1128             if (p[1] != NULL)
1129               p++;
1130             continue;
1131           }
1132         if (strcmp (*p, "-v") == 0)
1133           continue;
1134
1135         print_single_option (*p, &pos);
1136       }
1137 }
1138
1139 /* Print a first section with basic info like file names, as version,
1140    options passed, target, and timestamp.
1141    The format of this section is as follows:
1142
1143    AS VERSION
1144
1145    fieldname TAB ':' fieldcontents
1146   { TAB fieldcontents-cont }  */
1147
1148 static void
1149 listing_general_info (char ** argv)
1150 {
1151   /* Print the stuff on the first line.  */
1152   eject = 1;
1153   listing_page (0);
1154
1155   fprintf (list_file,
1156            _(" GNU assembler version %s (%s)\n\t using BFD version %s."),
1157            VERSION, TARGET_ALIAS, BFD_VERSION_STRING);
1158   print_options (argv);
1159   fprintf (list_file, _("\n input file    \t: %s"), fn);
1160   fprintf (list_file, _("\n output file   \t: %s"), out_file_name);
1161   fprintf (list_file, _("\n target        \t: %s"), TARGET_CANONICAL);
1162   print_timestamp ();
1163 }
1164
1165 void
1166 listing_print (char *name, char **argv)
1167 {
1168   int using_stdout;
1169
1170   title = "";
1171   subtitle = "";
1172
1173   if (name == NULL)
1174     {
1175       list_file = stdout;
1176       using_stdout = 1;
1177     }
1178   else
1179     {
1180       list_file = fopen (name, FOPEN_WT);
1181       if (list_file != NULL)
1182         using_stdout = 0;
1183       else
1184         {
1185           as_warn (_("can't open %s: %s"), name, xstrerror (errno));
1186           list_file = stdout;
1187           using_stdout = 1;
1188         }
1189     }
1190
1191   if (listing & LISTING_NOFORM)
1192     paper_height = 0;
1193
1194   if (listing & LISTING_GENERAL)
1195     listing_general_info (argv);
1196
1197   if (listing & LISTING_LISTING)
1198     listing_listing (name);
1199
1200   if (listing & LISTING_SYMBOLS)
1201     list_symbol_table ();
1202
1203   if (! using_stdout)
1204     {
1205       if (fclose (list_file) == EOF)
1206         as_warn (_("can't close %s: %s"), name, xstrerror (errno));
1207     }
1208
1209   if (last_open_file)
1210     fclose (last_open_file);
1211 }
1212
1213 void
1214 listing_file (const char *name)
1215 {
1216   fn = name;
1217 }
1218
1219 void
1220 listing_eject (int ignore ATTRIBUTE_UNUSED)
1221 {
1222   if (listing)
1223     listing_tail->edict = EDICT_EJECT;
1224 }
1225
1226 void
1227 listing_flags (int ignore ATTRIBUTE_UNUSED)
1228 {
1229   while ((*input_line_pointer++) && (*input_line_pointer != '\n'))
1230     input_line_pointer++;
1231
1232 }
1233
1234 /* Turn listing on or off.  An argument of 0 means to turn off
1235    listing.  An argument of 1 means to turn on listing.  An argument
1236    of 2 means to turn off listing, but as of the next line; that is,
1237    the current line should be listed, but the next line should not.  */
1238
1239 void
1240 listing_list (int on)
1241 {
1242   if (listing)
1243     {
1244       switch (on)
1245         {
1246         case 0:
1247           if (listing_tail->edict == EDICT_LIST)
1248             listing_tail->edict = EDICT_NONE;
1249           else
1250             listing_tail->edict = EDICT_NOLIST;
1251           break;
1252         case 1:
1253           if (listing_tail->edict == EDICT_NOLIST
1254               || listing_tail->edict == EDICT_NOLIST_NEXT)
1255             listing_tail->edict = EDICT_NONE;
1256           else
1257             listing_tail->edict = EDICT_LIST;
1258           break;
1259         case 2:
1260           listing_tail->edict = EDICT_NOLIST_NEXT;
1261           break;
1262         default:
1263           abort ();
1264         }
1265     }
1266 }
1267
1268 void
1269 listing_psize (int width_only)
1270 {
1271   if (! width_only)
1272     {
1273       paper_height = get_absolute_expression ();
1274
1275       if (paper_height < 0 || paper_height > 1000)
1276         {
1277           paper_height = 0;
1278           as_warn (_("strange paper height, set to no form"));
1279         }
1280
1281       if (*input_line_pointer != ',')
1282         {
1283           demand_empty_rest_of_line ();
1284           return;
1285         }
1286
1287       ++input_line_pointer;
1288     }
1289
1290   paper_width = get_absolute_expression ();
1291
1292   demand_empty_rest_of_line ();
1293 }
1294
1295 void
1296 listing_nopage (int ignore ATTRIBUTE_UNUSED)
1297 {
1298   paper_height = 0;
1299 }
1300
1301 void
1302 listing_title (int depth)
1303 {
1304   int quoted;
1305   char *start;
1306   char *ttl;
1307   unsigned int length;
1308
1309   SKIP_WHITESPACE ();
1310   if (*input_line_pointer != '\"')
1311     quoted = 0;
1312   else
1313     {
1314       quoted = 1;
1315       ++input_line_pointer;
1316     }
1317
1318   start = input_line_pointer;
1319
1320   while (*input_line_pointer)
1321     {
1322       if (quoted
1323           ? *input_line_pointer == '\"'
1324           : is_end_of_line[(unsigned char) *input_line_pointer])
1325         {
1326           if (listing)
1327             {
1328               length = input_line_pointer - start;
1329               ttl = xmalloc (length + 1);
1330               memcpy (ttl, start, length);
1331               ttl[length] = 0;
1332               listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
1333               listing_tail->edict_arg = ttl;
1334             }
1335           if (quoted)
1336             input_line_pointer++;
1337           demand_empty_rest_of_line ();
1338           return;
1339         }
1340       else if (*input_line_pointer == '\n')
1341         {
1342           as_bad (_("new line in title"));
1343           demand_empty_rest_of_line ();
1344           return;
1345         }
1346       else
1347         {
1348           input_line_pointer++;
1349         }
1350     }
1351 }
1352
1353 void
1354 listing_source_line (unsigned int line)
1355 {
1356   if (listing)
1357     {
1358       new_frag ();
1359       listing_tail->hll_line = line;
1360       new_frag ();
1361     }
1362 }
1363
1364 void
1365 listing_source_file (const char *file)
1366 {
1367   if (listing)
1368     listing_tail->hll_file = file_info (file);
1369 }
1370
1371 #else
1372
1373 /* Dummy functions for when compiled without listing enabled.  */
1374
1375 void
1376 listing_flags (int ignore)
1377 {
1378   s_ignore (0);
1379 }
1380
1381 void
1382 listing_list (int on)
1383 {
1384   s_ignore (0);
1385 }
1386
1387 void
1388 listing_eject (int ignore)
1389 {
1390   s_ignore (0);
1391 }
1392
1393 void
1394 listing_psize (int ignore)
1395 {
1396   s_ignore (0);
1397 }
1398
1399 void
1400 listing_nopage (int ignore)
1401 {
1402   s_ignore (0);
1403 }
1404
1405 void
1406 listing_title (int depth)
1407 {
1408   s_ignore (0);
1409 }
1410
1411 void
1412 listing_file (const char *name)
1413 {
1414 }
1415
1416 void
1417 listing_newline (char *name)
1418 {
1419 }
1420
1421 void
1422 listing_source_line (unsigned int n)
1423 {
1424 }
1425
1426 void
1427 listing_source_file (const char *n)
1428 {
1429 }
1430
1431 #endif