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