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