1/* listing.c - maintain assembly listings
2   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3   2001, 2002, 2003, 2005
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, 51 Franklin Street - Fifth Floor, Boston, MA
21   02110-1301, 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	      data_buffer_size += 2;
617
618	      var_rep_idx++;
619	      octet_in_frag++;
620
621	      if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var)
622		var_rep_idx = var_rep_max;
623	    }
624	}
625
626      frag_ptr = frag_ptr->fr_next;
627    }
628  data_buffer[data_buffer_size] = '\0';
629  return address;
630}
631
632static void
633print_lines (list_info_type *list, unsigned int lineno,
634	     char *string, unsigned int address)
635{
636  unsigned int idx;
637  unsigned int nchars;
638  unsigned int lines;
639  unsigned int octet_in_word = 0;
640  char *src = data_buffer;
641  int cur;
642
643  /* Print the stuff on the first line.  */
644  listing_page (list);
645  nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width;
646
647  /* Print the hex for the first line.  */
648  if (address == ~(unsigned int) 0)
649    {
650      fprintf (list_file, "% 4d     ", lineno);
651      for (idx = 0; idx < nchars; idx++)
652	fprintf (list_file, " ");
653
654      fprintf (list_file, "\t%s\n", string ? string : "");
655
656      on_page++;
657
658      listing_page (0);
659
660      return;
661    }
662
663  if (had_errors ())
664    fprintf (list_file, "% 4d ???? ", lineno);
665  else
666    fprintf (list_file, "% 4d %04x ", lineno, address);
667
668  /* And the data to go along with it.  */
669  idx = 0;
670  cur = 0;
671  while (src[cur] && idx < nchars)
672    {
673      int offset;
674      offset = cur;
675      fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
676      cur += 2;
677      octet_in_word++;
678
679      if (octet_in_word == LISTING_WORD_SIZE)
680	{
681	  fprintf (list_file, " ");
682	  idx++;
683	  octet_in_word = 0;
684	}
685
686      idx += 2;
687    }
688
689  for (; idx < nchars; idx++)
690    fprintf (list_file, " ");
691
692  fprintf (list_file, "\t%s\n", string ? string : "");
693  on_page++;
694  listing_page (list);
695
696  if (list->message)
697    {
698      fprintf (list_file, "****  %s\n", list->message);
699      listing_page (list);
700      on_page++;
701    }
702
703  for (lines = 0;
704       lines < (unsigned int) listing_lhs_cont_lines
705	 && src[cur];
706       lines++)
707    {
708      nchars = ((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second - 1;
709      idx = 0;
710
711      /* Print any more lines of data, but more compactly.  */
712      fprintf (list_file, "% 4d      ", lineno);
713
714      while (src[cur] && idx < nchars)
715	{
716	  int offset;
717	  offset = cur;
718	  fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
719	  cur += 2;
720	  idx += 2;
721	  octet_in_word++;
722
723	  if (octet_in_word == LISTING_WORD_SIZE)
724	    {
725	      fprintf (list_file, " ");
726	      idx++;
727	      octet_in_word = 0;
728	    }
729	}
730
731      fprintf (list_file, "\n");
732      on_page++;
733      listing_page (list);
734    }
735}
736
737static void
738list_symbol_table (void)
739{
740  extern symbolS *symbol_rootP;
741  int got_some = 0;
742
743  symbolS *ptr;
744  eject = 1;
745  listing_page (0);
746
747  for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
748    {
749      if (SEG_NORMAL (S_GET_SEGMENT (ptr))
750	  || S_GET_SEGMENT (ptr) == absolute_section)
751	{
752	  /* Don't report section symbols.  They are not interesting.  */
753	  if (symbol_section_p (ptr))
754	    continue;
755
756	  if (S_GET_NAME (ptr))
757	    {
758	      char buf[30], fmt[8];
759	      valueT val = S_GET_VALUE (ptr);
760
761	      /* @@ Note that this is dependent on the compilation options,
762		 not solely on the target characteristics.  */
763	      if (sizeof (val) == 4 && sizeof (int) == 4)
764		sprintf (buf, "%08lx", (unsigned long) val);
765	      else if (sizeof (val) <= sizeof (unsigned long))
766		{
767		  sprintf (fmt, "%%0%lulx",
768			   (unsigned long) (sizeof (val) * 2));
769		  sprintf (buf, fmt, (unsigned long) val);
770		}
771#if defined (BFD64)
772	      else if (sizeof (val) > 4)
773		sprintf_vma (buf, val);
774#endif
775	      else
776		abort ();
777
778	      if (!got_some)
779		{
780		  fprintf (list_file, "DEFINED SYMBOLS\n");
781		  on_page++;
782		  got_some = 1;
783		}
784
785	      if (symbol_get_frag (ptr) && symbol_get_frag (ptr)->line)
786		{
787		  fprintf (list_file, "%20s:%-5d  %s:%s %s\n",
788			   symbol_get_frag (ptr)->line->file->filename,
789			   symbol_get_frag (ptr)->line->line,
790			   segment_name (S_GET_SEGMENT (ptr)),
791			   buf, S_GET_NAME (ptr));
792		}
793	      else
794		{
795		  fprintf (list_file, "%33s:%s %s\n",
796			   segment_name (S_GET_SEGMENT (ptr)),
797			   buf, S_GET_NAME (ptr));
798		}
799
800	      on_page++;
801	      listing_page (0);
802	    }
803	}
804
805    }
806  if (!got_some)
807    {
808      fprintf (list_file, "NO DEFINED SYMBOLS\n");
809      on_page++;
810    }
811  fprintf (list_file, "\n");
812  on_page++;
813  listing_page (0);
814
815  got_some = 0;
816
817  for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
818    {
819      if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0)
820	{
821	  if (S_GET_SEGMENT (ptr) == undefined_section)
822	    {
823	      if (!got_some)
824		{
825		  got_some = 1;
826		  fprintf (list_file, "UNDEFINED SYMBOLS\n");
827		  on_page++;
828		  listing_page (0);
829		}
830	      fprintf (list_file, "%s\n", S_GET_NAME (ptr));
831	      on_page++;
832	      listing_page (0);
833	    }
834	}
835    }
836  if (!got_some)
837    {
838      fprintf (list_file, "NO UNDEFINED SYMBOLS\n");
839      on_page++;
840      listing_page (0);
841    }
842}
843
844static void
845print_source (file_info_type *current_file, list_info_type *list,
846	      char *buffer, unsigned int width)
847{
848  if (!current_file->at_end)
849    {
850      while (current_file->linenum < list->hll_line
851	     && !current_file->at_end)
852	{
853	  char *p = buffer_line (current_file, buffer, width);
854
855	  fprintf (list_file, "%4u:%-13s **** %s\n", current_file->linenum,
856		   current_file->filename, p);
857	  on_page++;
858	  listing_page (list);
859	}
860    }
861}
862
863/* Sometimes the user doesn't want to be bothered by the debugging
864   records inserted by the compiler, see if the line is suspicious.  */
865
866static int
867debugging_pseudo (list_info_type *list, const char *line)
868{
869  static int in_debug;
870  int was_debug;
871
872  if (list->debugging)
873    {
874      in_debug = 1;
875      return 1;
876    }
877
878  was_debug = in_debug;
879  in_debug = 0;
880
881  while (ISSPACE (*line))
882    line++;
883
884  if (*line != '.')
885    {
886#ifdef OBJ_ELF
887      /* The ELF compiler sometimes emits blank lines after switching
888         out of a debugging section.  If the next line drops us back
889         into debugging information, then don't print the blank line.
890         This is a hack for a particular compiler behaviour, not a
891         general case.  */
892      if (was_debug
893	  && *line == '\0'
894	  && list->next != NULL
895	  && list->next->debugging)
896	{
897	  in_debug = 1;
898	  return 1;
899	}
900#endif
901
902      return 0;
903    }
904
905  line++;
906
907  if (strncmp (line, "def", 3) == 0)
908    return 1;
909  if (strncmp (line, "val", 3) == 0)
910    return 1;
911  if (strncmp (line, "scl", 3) == 0)
912    return 1;
913  if (strncmp (line, "line", 4) == 0)
914    return 1;
915  if (strncmp (line, "endef", 5) == 0)
916    return 1;
917  if (strncmp (line, "ln", 2) == 0)
918    return 1;
919  if (strncmp (line, "type", 4) == 0)
920    return 1;
921  if (strncmp (line, "size", 4) == 0)
922    return 1;
923  if (strncmp (line, "dim", 3) == 0)
924    return 1;
925  if (strncmp (line, "tag", 3) == 0)
926    return 1;
927  if (strncmp (line, "stabs", 5) == 0)
928    return 1;
929  if (strncmp (line, "stabn", 5) == 0)
930    return 1;
931
932  return 0;
933}
934
935static void
936listing_listing (char *name ATTRIBUTE_UNUSED)
937{
938  list_info_type *list = head;
939  file_info_type *current_hll_file = (file_info_type *) NULL;
940  char *message;
941  char *buffer;
942  char *p;
943  int show_listing = 1;
944  unsigned int width;
945
946  buffer = xmalloc (listing_rhs_width);
947  data_buffer = xmalloc (MAX_BYTES);
948  eject = 1;
949  list = head;
950
951  while (list != (list_info_type *) NULL && 0)
952    {
953      if (list->next)
954	list->frag = list->next->frag;
955      list = list->next;
956    }
957
958  list = head->next;
959
960  while (list)
961    {
962      unsigned int list_line;
963
964      width = listing_rhs_width > paper_width ? paper_width :
965	listing_rhs_width;
966
967      list_line = list->line;
968      switch (list->edict)
969	{
970	case EDICT_LIST:
971	  /* Skip all lines up to the current.  */
972	  list_line--;
973	  break;
974	case EDICT_NOLIST:
975	  show_listing--;
976	  break;
977	case EDICT_NOLIST_NEXT:
978	  if (show_listing == 0)
979	    list_line--;
980	  break;
981	case EDICT_EJECT:
982	  break;
983	case EDICT_NONE:
984	  break;
985	case EDICT_TITLE:
986	  title = list->edict_arg;
987	  break;
988	case EDICT_SBTTL:
989	  subtitle = list->edict_arg;
990	  break;
991	default:
992	  abort ();
993	}
994
995      if (show_listing <= 0)
996	{
997	  while (list->file->linenum < list_line
998		 && !list->file->at_end)
999	    p = buffer_line (list->file, buffer, width);
1000	}
1001
1002      if (list->edict == EDICT_LIST
1003	  || (list->edict == EDICT_NOLIST_NEXT && show_listing == 0))
1004	{
1005	  /* Enable listing for the single line that caused the enable.  */
1006	  list_line++;
1007	  show_listing++;
1008	}
1009
1010      if (show_listing > 0)
1011	{
1012	  /* Scan down the list and print all the stuff which can be done
1013	     with this line (or lines).  */
1014	  message = 0;
1015
1016	  if (list->hll_file)
1017	    current_hll_file = list->hll_file;
1018
1019	  if (current_hll_file && list->hll_line && (listing & LISTING_HLL))
1020	    print_source (current_hll_file, list, buffer, width);
1021
1022	  if (list->line_contents)
1023	    {
1024	      if (!((listing & LISTING_NODEBUG)
1025		    && debugging_pseudo (list, list->line_contents)))
1026		print_lines (list,
1027			     list->file->linenum == 0 ? list->line : list->file->linenum,
1028			     list->line_contents, calc_hex (list));
1029
1030	      free (list->line_contents);
1031	      list->line_contents = NULL;
1032	    }
1033	  else
1034	    {
1035	      while (list->file->linenum < list_line
1036		     && !list->file->at_end)
1037		{
1038		  unsigned int address;
1039
1040		  p = buffer_line (list->file, buffer, width);
1041
1042		  if (list->file->linenum < list_line)
1043		    address = ~(unsigned int) 0;
1044		  else
1045		    address = calc_hex (list);
1046
1047		  if (!((listing & LISTING_NODEBUG)
1048			&& debugging_pseudo (list, p)))
1049		    print_lines (list, list->file->linenum, p, address);
1050		}
1051	    }
1052
1053	  if (list->edict == EDICT_EJECT)
1054	    eject = 1;
1055	}
1056
1057      if (list->edict == EDICT_NOLIST_NEXT && show_listing == 1)
1058	--show_listing;
1059
1060      list = list->next;
1061    }
1062
1063  free (buffer);
1064  free (data_buffer);
1065  data_buffer = NULL;
1066}
1067
1068void
1069listing_print (char *name)
1070{
1071  int using_stdout;
1072
1073  title = "";
1074  subtitle = "";
1075
1076  if (name == NULL)
1077    {
1078      list_file = stdout;
1079      using_stdout = 1;
1080    }
1081  else
1082    {
1083      list_file = fopen (name, FOPEN_WT);
1084      if (list_file != NULL)
1085	using_stdout = 0;
1086      else
1087	{
1088	  bfd_set_error (bfd_error_system_call);
1089	  as_perror (_("can't open list file: %s"), name);
1090	  list_file = stdout;
1091	  using_stdout = 1;
1092	}
1093    }
1094
1095  if (listing & LISTING_NOFORM)
1096    paper_height = 0;
1097
1098  if (listing & LISTING_LISTING)
1099    listing_listing (name);
1100
1101  if (listing & LISTING_SYMBOLS)
1102    list_symbol_table ();
1103
1104  if (! using_stdout)
1105    {
1106      if (fclose (list_file) == EOF)
1107	{
1108	  bfd_set_error (bfd_error_system_call);
1109	  as_perror (_("error closing list file: %s"), name);
1110	}
1111    }
1112
1113  if (last_open_file)
1114    fclose (last_open_file);
1115}
1116
1117void
1118listing_file (const char *name)
1119{
1120  fn = name;
1121}
1122
1123void
1124listing_eject (int ignore ATTRIBUTE_UNUSED)
1125{
1126  if (listing)
1127    listing_tail->edict = EDICT_EJECT;
1128}
1129
1130void
1131listing_flags (int ignore ATTRIBUTE_UNUSED)
1132{
1133  while ((*input_line_pointer++) && (*input_line_pointer != '\n'))
1134    input_line_pointer++;
1135
1136}
1137
1138/* Turn listing on or off.  An argument of 0 means to turn off
1139   listing.  An argument of 1 means to turn on listing.  An argument
1140   of 2 means to turn off listing, but as of the next line; that is,
1141   the current line should be listed, but the next line should not.  */
1142
1143void
1144listing_list (int on)
1145{
1146  if (listing)
1147    {
1148      switch (on)
1149	{
1150	case 0:
1151	  if (listing_tail->edict == EDICT_LIST)
1152	    listing_tail->edict = EDICT_NONE;
1153	  else
1154	    listing_tail->edict = EDICT_NOLIST;
1155	  break;
1156	case 1:
1157	  if (listing_tail->edict == EDICT_NOLIST
1158	      || listing_tail->edict == EDICT_NOLIST_NEXT)
1159	    listing_tail->edict = EDICT_NONE;
1160	  else
1161	    listing_tail->edict = EDICT_LIST;
1162	  break;
1163	case 2:
1164	  listing_tail->edict = EDICT_NOLIST_NEXT;
1165	  break;
1166	default:
1167	  abort ();
1168	}
1169    }
1170}
1171
1172void
1173listing_psize (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 (int ignore ATTRIBUTE_UNUSED)
1201{
1202  paper_height = 0;
1203}
1204
1205void
1206listing_title (int depth)
1207{
1208  int quoted;
1209  char *start;
1210  char *ttl;
1211  unsigned int length;
1212
1213  SKIP_WHITESPACE ();
1214  if (*input_line_pointer != '\"')
1215    quoted = 0;
1216  else
1217    {
1218      quoted = 1;
1219      ++input_line_pointer;
1220    }
1221
1222  start = input_line_pointer;
1223
1224  while (*input_line_pointer)
1225    {
1226      if (quoted
1227	  ? *input_line_pointer == '\"'
1228	  : is_end_of_line[(unsigned char) *input_line_pointer])
1229	{
1230	  if (listing)
1231	    {
1232	      length = input_line_pointer - start;
1233	      ttl = xmalloc (length + 1);
1234	      memcpy (ttl, start, length);
1235	      ttl[length] = 0;
1236	      listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
1237	      listing_tail->edict_arg = ttl;
1238	    }
1239	  if (quoted)
1240	    input_line_pointer++;
1241	  demand_empty_rest_of_line ();
1242	  return;
1243	}
1244      else if (*input_line_pointer == '\n')
1245	{
1246	  as_bad (_("new line in title"));
1247	  demand_empty_rest_of_line ();
1248	  return;
1249	}
1250      else
1251	{
1252	  input_line_pointer++;
1253	}
1254    }
1255}
1256
1257void
1258listing_source_line (unsigned int line)
1259{
1260  if (listing)
1261    {
1262      new_frag ();
1263      listing_tail->hll_line = line;
1264      new_frag ();
1265    }
1266}
1267
1268void
1269listing_source_file (const char *file)
1270{
1271  if (listing)
1272    listing_tail->hll_file = file_info (file);
1273}
1274
1275#else
1276
1277/* Dummy functions for when compiled without listing enabled.  */
1278
1279void
1280listing_flags (int ignore)
1281{
1282  s_ignore (0);
1283}
1284
1285void
1286listing_list (int on)
1287{
1288  s_ignore (0);
1289}
1290
1291void
1292listing_eject (int ignore)
1293{
1294  s_ignore (0);
1295}
1296
1297void
1298listing_psize (int ignore)
1299{
1300  s_ignore (0);
1301}
1302
1303void
1304listing_nopage (int ignore)
1305{
1306  s_ignore (0);
1307}
1308
1309void
1310listing_title (int depth)
1311{
1312  s_ignore (0);
1313}
1314
1315void
1316listing_file (const char *name)
1317{
1318}
1319
1320void
1321listing_newline (char *name)
1322{
1323}
1324
1325void
1326listing_source_line (unsigned int n)
1327{
1328}
1329
1330void
1331listing_source_file (const char *n)
1332{
1333}
1334
1335#endif
1336