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