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