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