1/* listing.c - maintain assembly listings
2   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3   2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010
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 3, 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#include "bfdver.h"
98#include <time.h>
99#include <stdarg.h>
100
101#ifndef NO_LISTING
102
103#ifndef LISTING_HEADER
104#define LISTING_HEADER "GAS LISTING"
105#endif
106#ifndef LISTING_WORD_SIZE
107#define LISTING_WORD_SIZE 4
108#endif
109#ifndef LISTING_LHS_WIDTH
110#define LISTING_LHS_WIDTH ((LISTING_WORD_SIZE) > 4 ? 1 : 4 / (LISTING_WORD_SIZE))
111#endif
112#ifndef LISTING_LHS_WIDTH_SECOND
113#define LISTING_LHS_WIDTH_SECOND LISTING_LHS_WIDTH
114#endif
115#ifndef LISTING_RHS_WIDTH
116#define LISTING_RHS_WIDTH 100
117#endif
118#ifndef LISTING_LHS_CONT_LINES
119#define LISTING_LHS_CONT_LINES 4
120#endif
121#define MAX_DATELEN 30
122
123/* This structure remembers which .s were used.  */
124typedef struct file_info_struct
125{
126  struct file_info_struct * next;
127  char *                    filename;
128  long                      pos;
129  unsigned int              linenum;
130  int                       at_end;
131} file_info_type;
132
133enum edict_enum
134{
135  EDICT_NONE,
136  EDICT_SBTTL,
137  EDICT_TITLE,
138  EDICT_NOLIST,
139  EDICT_LIST,
140  EDICT_NOLIST_NEXT,
141  EDICT_EJECT
142};
143
144
145/* This structure remembers which line from which file goes into which
146   frag.  */
147struct list_info_struct
148{
149  /* Frag which this line of source is nearest to.  */
150  fragS *frag;
151
152  /* The actual line in the source file.  */
153  unsigned int line;
154
155  /* Pointer to the file info struct for the file which this line
156     belongs to.  */
157  file_info_type *file;
158
159  /* The expanded text of any macro that may have been executing.  */
160  char *line_contents;
161
162  /* Next in list.  */
163  struct list_info_struct *next;
164
165  /* Pointer to the file info struct for the high level language
166     source line that belongs here.  */
167  file_info_type *hll_file;
168
169  /* High level language source line.  */
170  unsigned int hll_line;
171
172  /* Pointer to any error message associated with this line.  */
173  char *message;
174
175  enum edict_enum edict;
176  char *edict_arg;
177
178  /* Nonzero if this line is to be omitted because it contains
179     debugging information.  This can become a flags field if we come
180     up with more information to store here.  */
181  int debugging;
182};
183
184typedef struct list_info_struct list_info_type;
185
186int listing_lhs_width        = LISTING_LHS_WIDTH;
187int listing_lhs_width_second = LISTING_LHS_WIDTH_SECOND;
188int listing_lhs_cont_lines   = LISTING_LHS_CONT_LINES;
189int listing_rhs_width        = LISTING_RHS_WIDTH;
190
191struct list_info_struct *        listing_tail;
192
193static file_info_type *          file_info_head;
194static file_info_type *          last_open_file_info;
195static FILE *                    last_open_file;
196static struct list_info_struct * head;
197static int                       paper_width = 200;
198static int                       paper_height = 60;
199
200extern int                       listing;
201
202/* File to output listings to.  */
203static FILE *list_file;
204
205/* This static array is used to keep the text of data to be printed
206   before the start of the line.  */
207
208#define MAX_BYTES							\
209  (((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width			\
210   + ((((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second)	\
211      * listing_lhs_cont_lines)						\
212   + 20)
213
214static char *data_buffer;
215
216/* Prototypes.  */
217static void listing_message (const char *, const char *);
218static file_info_type *file_info (const char *);
219static void new_frag (void);
220static void listing_page (list_info_type *);
221static unsigned int calc_hex (list_info_type *);
222static void print_lines (list_info_type *, unsigned int, char *, unsigned int);
223static void list_symbol_table (void);
224static int debugging_pseudo (list_info_type *, const char *);
225static void listing_listing (char *);
226
227static void
228listing_message (const char *name, const char *message)
229{
230  if (listing_tail != (list_info_type *) NULL)
231    {
232      unsigned int l = strlen (name) + strlen (message) + 1;
233      char *n = (char *) xmalloc (l);
234      strcpy (n, name);
235      strcat (n, message);
236      listing_tail->message = n;
237    }
238}
239
240void
241listing_warning (const char *message)
242{
243  listing_message (_("Warning:"), message);
244}
245
246void
247listing_error (const char *message)
248{
249  listing_message (_("Error:"), message);
250}
251
252static file_info_type *
253file_info (const char *file_name)
254{
255  /* Find an entry with this file name.  */
256  file_info_type *p = file_info_head;
257
258  while (p != (file_info_type *) NULL)
259    {
260      if (strcmp (p->filename, file_name) == 0)
261	return p;
262      p = p->next;
263    }
264
265  /* Make new entry.  */
266  p = (file_info_type *) xmalloc (sizeof (file_info_type));
267  p->next = file_info_head;
268  file_info_head = p;
269  p->filename = xstrdup (file_name);
270  p->pos = 0;
271  p->linenum = 0;
272  p->at_end = 0;
273
274  return p;
275}
276
277static void
278new_frag (void)
279{
280  frag_wane (frag_now);
281  frag_new (0);
282}
283
284void
285listing_newline (char *ps)
286{
287  char *file;
288  unsigned int line;
289  static unsigned int last_line = 0xffff;
290  static char *last_file = NULL;
291  list_info_type *new_i = NULL;
292
293  if (listing == 0)
294    return;
295
296  if (now_seg == absolute_section)
297    return;
298
299#ifdef OBJ_ELF
300  /* In ELF, anything in a section beginning with .debug or .line is
301     considered to be debugging information.  This includes the
302     statement which switches us into the debugging section, which we
303     can only set after we are already in the debugging section.  */
304  if ((listing & LISTING_NODEBUG) != 0
305      && listing_tail != NULL
306      && ! listing_tail->debugging)
307    {
308      const char *segname;
309
310      segname = segment_name (now_seg);
311      if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
312	  || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
313	listing_tail->debugging = 1;
314    }
315#endif
316
317  as_where (&file, &line);
318  if (ps == NULL)
319    {
320      if (line == last_line
321	  && !(last_file && file && strcmp (file, last_file)))
322	return;
323
324      new_i = (list_info_type *) xmalloc (sizeof (list_info_type));
325
326      /* Detect if we are reading from stdin by examining the file
327	 name returned by as_where().
328
329	 [FIXME: We rely upon the name in the strcmp below being the
330	 same as the one used by input_scrub_new_file(), if that is
331	 not true, then this code will fail].
332
333	 If we are reading from stdin, then we need to save each input
334	 line here (assuming of course that we actually have a line of
335	 input to read), so that it can be displayed in the listing
336	 that is produced at the end of the assembly.  */
337      if (strcmp (file, _("{standard input}")) == 0
338	  && input_line_pointer != NULL)
339	{
340	  char *copy;
341	  int len;
342	  int seen_quote = 0;
343	  int seen_slash = 0;
344
345	  for (copy = input_line_pointer;
346	       *copy && (seen_quote
347			 || is_end_of_line [(unsigned char) *copy] != 1);
348	       copy++)
349	    {
350	      if (seen_slash)
351		seen_slash = 0;
352	      else if (*copy == '\\')
353		seen_slash = 1;
354	      else if (*copy == '"')
355		seen_quote = !seen_quote;
356	    }
357
358	  len = copy - input_line_pointer + 1;
359
360	  copy = (char *) xmalloc (len);
361
362	  if (copy != NULL)
363	    {
364	      char *src = input_line_pointer;
365	      char *dest = copy;
366
367	      while (--len)
368		{
369		  unsigned char c = *src++;
370
371		  /* Omit control characters in the listing.  */
372		  if (!ISCNTRL (c))
373		    *dest++ = c;
374		}
375
376	      *dest = 0;
377	    }
378
379	  new_i->line_contents = copy;
380	}
381      else
382	new_i->line_contents = NULL;
383    }
384  else
385    {
386      new_i = (list_info_type *) xmalloc (sizeof (list_info_type));
387      new_i->line_contents = ps;
388    }
389
390  last_line = line;
391  last_file = file;
392
393  new_frag ();
394
395  if (listing_tail)
396    listing_tail->next = new_i;
397  else
398    head = new_i;
399
400  listing_tail = new_i;
401
402  new_i->frag = frag_now;
403  new_i->line = line;
404  new_i->file = file_info (file);
405  new_i->next = (list_info_type *) NULL;
406  new_i->message = (char *) NULL;
407  new_i->edict = EDICT_NONE;
408  new_i->hll_file = (file_info_type *) NULL;
409  new_i->hll_line = 0;
410  new_i->debugging = 0;
411
412  new_frag ();
413
414#ifdef OBJ_ELF
415  /* In ELF, anything in a section beginning with .debug or .line is
416     considered to be debugging information.  */
417  if ((listing & LISTING_NODEBUG) != 0)
418    {
419      const char *segname;
420
421      segname = segment_name (now_seg);
422      if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
423	  || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
424	new_i->debugging = 1;
425    }
426#endif
427}
428
429/* Attach all current frags to the previous line instead of the
430   current line.  This is called by the MIPS backend when it discovers
431   that it needs to add some NOP instructions; the added NOP
432   instructions should go with the instruction that has the delay, not
433   with the new instruction.  */
434
435void
436listing_prev_line (void)
437{
438  list_info_type *l;
439  fragS *f;
440
441  if (head == (list_info_type *) NULL
442      || head == listing_tail)
443    return;
444
445  new_frag ();
446
447  for (l = head; l->next != listing_tail; l = l->next)
448    ;
449
450  for (f = frchain_now->frch_root; f != (fragS *) NULL; f = f->fr_next)
451    if (f->line == listing_tail)
452      f->line = l;
453
454  listing_tail->frag = frag_now;
455  new_frag ();
456}
457
458/* This function returns the next source line from the file supplied,
459   truncated to size.  It appends a fake line to the end of each input
460   file to make using the returned buffer simpler.  */
461
462static char *
463buffer_line (file_info_type *file, char *line, unsigned int size)
464{
465  unsigned int count = 0;
466  int c;
467  char *p = line;
468
469  /* If we couldn't open the file, return an empty line.  */
470  if (file->at_end)
471    return "";
472
473  /* Check the cache and see if we last used this file.  */
474  if (!last_open_file_info || file != last_open_file_info)
475    {
476      if (last_open_file)
477	{
478	  last_open_file_info->pos = ftell (last_open_file);
479	  fclose (last_open_file);
480	}
481
482      /* Open the file in the binary mode so that ftell above can
483	 return a reliable value that we can feed to fseek below.  */
484      last_open_file_info = file;
485      last_open_file = fopen (file->filename, FOPEN_RB);
486      if (last_open_file == NULL)
487	{
488	  file->at_end = 1;
489	  return "";
490	}
491
492      /* Seek to where we were last time this file was open.  */
493      if (file->pos)
494	fseek (last_open_file, file->pos, SEEK_SET);
495    }
496
497  /* Leave room for null.  */
498  size -= 1;
499
500  c = fgetc (last_open_file);
501
502  while (c != EOF && c != '\n' && c != '\r')
503    {
504      if (count < size)
505	*p++ = c;
506      count++;
507
508      c = fgetc (last_open_file);
509    }
510
511  /* If '\r' is followed by '\n', swallow that.  Likewise, if '\n'
512     is followed by '\r', swallow that as well.  */
513  if (c == '\r' || c == '\n')
514    {
515      int next = fgetc (last_open_file);
516
517      if ((c == '\r' && next != '\n')
518	  || (c == '\n' && next != '\r'))
519	ungetc (next, last_open_file);
520    }
521
522  if (c == EOF)
523    {
524      file->at_end = 1;
525      if (count + 2 < size)
526	{
527	  *p++ = '.';
528	  *p++ = '.';
529	  *p++ = '.';
530	}
531    }
532  file->linenum++;
533  *p++ = 0;
534  return line;
535}
536
537
538/* This function rewinds the requested file back to the line requested,
539   reads it in again into the buffer provided and then restores the file
540   back to its original location.  */
541
542static char *
543rebuffer_line (file_info_type *  file,
544	       unsigned int      linenum,
545	       char *            buffer,
546	       unsigned int      size)
547{
548  unsigned int count = 0;
549  unsigned int current_line = 1;
550  char * p = buffer;
551  long pos;
552  int c;
553
554  /* Sanity checks.  */
555  if (file == NULL || buffer == NULL || size == 0 || file->linenum <= linenum)
556    return "";
557
558  /* Check the cache and see if we last used this file.  */
559  if (last_open_file_info == NULL || file != last_open_file_info)
560    {
561      if (last_open_file)
562	{
563	  last_open_file_info->pos = ftell (last_open_file);
564	  fclose (last_open_file);
565	}
566
567      /* Open the file in the binary mode so that ftell above can
568	 return a reliable value that we can feed to fseek below.  */
569      last_open_file_info = file;
570      last_open_file = fopen (file->filename, FOPEN_RB);
571      if (last_open_file == NULL)
572	{
573	  file->at_end = 1;
574	  return "";
575	}
576
577      /* Seek to where we were last time this file was open.  */
578      if (file->pos)
579	fseek (last_open_file, file->pos, SEEK_SET);
580    }
581
582  /* Remember where we are in the current file.  */
583  pos = ftell (last_open_file);
584
585  /* Go back to the beginning.  */
586  fseek (last_open_file, 0, SEEK_SET);
587
588  /* Skip lines prior to the one we are interested in.  */
589  while (current_line < linenum)
590    {
591      /* fgets only stops on newlines and has a size limit,
592	 so we read one character at a time instead.  */
593      do
594	{
595	  c = fgetc (last_open_file);
596	}
597      while (c != EOF && c != '\n' && c != '\r');
598
599      ++ current_line;
600
601      if (c == '\r' || c == '\n')
602	{
603	  int next = fgetc (last_open_file);
604
605	  /* If '\r' is followed by '\n', swallow that.  Likewise, if '\n'
606	     is followed by '\r', swallow that as well.  */
607	  if ((c == '\r' && next != '\n')
608	      || (c == '\n' && next != '\r'))
609	    ungetc (next, last_open_file);
610	}
611    }
612
613  /* Leave room for the nul at the end of the buffer.  */
614  size -= 1;
615
616  /* Read in the line.  */
617  c = fgetc (last_open_file);
618
619  while (c != EOF && c != '\n' && c != '\r')
620    {
621      if (count < size)
622	*p++ = c;
623      count++;
624
625      c = fgetc (last_open_file);
626    }
627
628  /* If '\r' is followed by '\n', swallow that.  Likewise, if '\n'
629     is followed by '\r', swallow that as well.  */
630  if (c == '\r' || c == '\n')
631    {
632      int next = fgetc (last_open_file);
633
634      if ((c == '\r' && next != '\n')
635	  || (c == '\n' && next != '\r'))
636	ungetc (next, last_open_file);
637    }
638
639  /* Terminate the line.  */
640  *p++ = 0;
641
642  /* Reset the file position.  */
643  fseek (last_open_file, pos, SEEK_SET);
644
645  return buffer;
646}
647
648static const char *fn;
649
650static unsigned int eject;	/* Eject pending */
651static unsigned int page;	/* Current page number */
652static char *title;		/* Current title */
653static char *subtitle;		/* Current subtitle */
654static unsigned int on_page;	/* Number of lines printed on current page */
655
656static void
657listing_page (list_info_type *list)
658{
659  /* Grope around, see if we can see a title or subtitle edict coming up
660     soon.  (we look down 10 lines of the page and see if it's there)  */
661  if ((eject || (on_page >= (unsigned int) paper_height))
662      && paper_height != 0)
663    {
664      unsigned int c = 10;
665      int had_title = 0;
666      int had_subtitle = 0;
667
668      page++;
669
670      while (c != 0 && list)
671	{
672	  if (list->edict == EDICT_SBTTL && !had_subtitle)
673	    {
674	      had_subtitle = 1;
675	      subtitle = list->edict_arg;
676	    }
677	  if (list->edict == EDICT_TITLE && !had_title)
678	    {
679	      had_title = 1;
680	      title = list->edict_arg;
681	    }
682	  list = list->next;
683	  c--;
684	}
685
686      if (page > 1)
687	{
688	  fprintf (list_file, "\f");
689	}
690
691      fprintf (list_file, "%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
692      fprintf (list_file, "%s\n", title);
693      fprintf (list_file, "%s\n", subtitle);
694      on_page = 3;
695      eject = 0;
696    }
697}
698
699/* Print a line into the list_file.  Update the line count
700   and if necessary start a new page.  */
701
702static void
703emit_line (list_info_type * list, const char * format, ...)
704{
705  va_list args;
706
707  va_start (args, format);
708
709  vfprintf (list_file, format, args);
710  on_page++;
711  listing_page (list);
712
713  va_end (args);
714}
715
716static unsigned int
717calc_hex (list_info_type *list)
718{
719  int data_buffer_size;
720  list_info_type *first = list;
721  unsigned int address = ~(unsigned int) 0;
722  fragS *frag;
723  fragS *frag_ptr;
724  unsigned int octet_in_frag;
725
726  /* Find first frag which says it belongs to this line.  */
727  frag = list->frag;
728  while (frag && frag->line != list)
729    frag = frag->fr_next;
730
731  frag_ptr = frag;
732
733  data_buffer_size = 0;
734
735  /* Dump all the frags which belong to this line.  */
736  while (frag_ptr != (fragS *) NULL && frag_ptr->line == first)
737    {
738      /* Print as many bytes from the fixed part as is sensible.  */
739      octet_in_frag = 0;
740      while ((offsetT) octet_in_frag < frag_ptr->fr_fix
741	     && data_buffer_size < MAX_BYTES - 3)
742	{
743	  if (address == ~(unsigned int) 0)
744	    address = frag_ptr->fr_address / OCTETS_PER_BYTE;
745
746	  sprintf (data_buffer + data_buffer_size,
747		   "%02X",
748		   (frag_ptr->fr_literal[octet_in_frag]) & 0xff);
749	  data_buffer_size += 2;
750	  octet_in_frag++;
751	}
752      if (frag_ptr->fr_type == rs_fill)
753	{
754	  unsigned int var_rep_max = octet_in_frag;
755	  unsigned int var_rep_idx = octet_in_frag;
756
757	  /* Print as many bytes from the variable part as is sensible.  */
758	  while (((offsetT) octet_in_frag
759		  < (frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset))
760		 && data_buffer_size < MAX_BYTES - 3)
761	    {
762	      if (address == ~(unsigned int) 0)
763		address = frag_ptr->fr_address / OCTETS_PER_BYTE;
764
765	      sprintf (data_buffer + data_buffer_size,
766		       "%02X",
767		       (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
768	      data_buffer_size += 2;
769
770	      var_rep_idx++;
771	      octet_in_frag++;
772
773	      if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var)
774		var_rep_idx = var_rep_max;
775	    }
776	}
777
778      frag_ptr = frag_ptr->fr_next;
779    }
780  data_buffer[data_buffer_size] = '\0';
781  return address;
782}
783
784static void
785print_lines (list_info_type *list, unsigned int lineno,
786	     char *string, unsigned int address)
787{
788  unsigned int idx;
789  unsigned int nchars;
790  unsigned int lines;
791  unsigned int octet_in_word = 0;
792  char *src = data_buffer;
793  int cur;
794
795  /* Print the stuff on the first line.  */
796  listing_page (list);
797  nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width;
798
799  /* Print the hex for the first line.  */
800  if (address == ~(unsigned int) 0)
801    {
802      fprintf (list_file, "% 4d     ", lineno);
803      for (idx = 0; idx < nchars; idx++)
804	fprintf (list_file, " ");
805
806      emit_line (NULL, "\t%s\n", string ? string : "");
807      return;
808    }
809
810  if (had_errors ())
811    fprintf (list_file, "% 4d ???? ", lineno);
812  else
813    fprintf (list_file, "% 4d %04x ", lineno, address);
814
815  /* And the data to go along with it.  */
816  idx = 0;
817  cur = 0;
818  while (src[cur] && idx < nchars)
819    {
820      int offset;
821      offset = cur;
822      fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
823      cur += 2;
824      octet_in_word++;
825
826      if (octet_in_word == LISTING_WORD_SIZE)
827	{
828	  fprintf (list_file, " ");
829	  idx++;
830	  octet_in_word = 0;
831	}
832
833      idx += 2;
834    }
835
836  for (; idx < nchars; idx++)
837    fprintf (list_file, " ");
838
839  emit_line (list, "\t%s\n", string ? string : "");
840
841  if (list->message)
842    emit_line (list, "****  %s\n", list->message);
843
844  for (lines = 0;
845       lines < (unsigned int) listing_lhs_cont_lines
846	 && src[cur];
847       lines++)
848    {
849      nchars = ((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second - 1;
850      idx = 0;
851
852      /* Print any more lines of data, but more compactly.  */
853      fprintf (list_file, "% 4d      ", lineno);
854
855      while (src[cur] && idx < nchars)
856	{
857	  int offset;
858	  offset = cur;
859	  fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
860	  cur += 2;
861	  idx += 2;
862	  octet_in_word++;
863
864	  if (octet_in_word == LISTING_WORD_SIZE)
865	    {
866	      fprintf (list_file, " ");
867	      idx++;
868	      octet_in_word = 0;
869	    }
870	}
871
872      emit_line (list, "\n");
873    }
874}
875
876static void
877list_symbol_table (void)
878{
879  extern symbolS *symbol_rootP;
880  int got_some = 0;
881
882  symbolS *ptr;
883  eject = 1;
884  listing_page (NULL);
885
886  for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
887    {
888      if (SEG_NORMAL (S_GET_SEGMENT (ptr))
889	  || S_GET_SEGMENT (ptr) == absolute_section)
890	{
891	  /* Don't report section symbols.  They are not interesting.  */
892	  if (symbol_section_p (ptr))
893	    continue;
894
895	  if (S_GET_NAME (ptr))
896	    {
897	      char buf[30], fmt[8];
898	      valueT val = S_GET_VALUE (ptr);
899
900	      /* @@ Note that this is dependent on the compilation options,
901		 not solely on the target characteristics.  */
902	      if (sizeof (val) == 4 && sizeof (int) == 4)
903		sprintf (buf, "%08lx", (unsigned long) val);
904	      else if (sizeof (val) <= sizeof (unsigned long))
905		{
906		  sprintf (fmt, "%%0%lulx",
907			   (unsigned long) (sizeof (val) * 2));
908		  sprintf (buf, fmt, (unsigned long) val);
909		}
910#if defined (BFD64)
911	      else if (sizeof (val) > 4)
912		sprintf_vma (buf, val);
913#endif
914	      else
915		abort ();
916
917	      if (!got_some)
918		{
919		  fprintf (list_file, "DEFINED SYMBOLS\n");
920		  on_page++;
921		  got_some = 1;
922		}
923
924	      if (symbol_get_frag (ptr) && symbol_get_frag (ptr)->line)
925		{
926		  fprintf (list_file, "%20s:%-5d  %s:%s %s\n",
927			   symbol_get_frag (ptr)->line->file->filename,
928			   symbol_get_frag (ptr)->line->line,
929			   segment_name (S_GET_SEGMENT (ptr)),
930			   buf, S_GET_NAME (ptr));
931		}
932	      else
933		{
934		  fprintf (list_file, "%33s:%s %s\n",
935			   segment_name (S_GET_SEGMENT (ptr)),
936			   buf, S_GET_NAME (ptr));
937		}
938
939	      on_page++;
940	      listing_page (NULL);
941	    }
942	}
943
944    }
945  if (!got_some)
946    {
947      fprintf (list_file, "NO DEFINED SYMBOLS\n");
948      on_page++;
949    }
950  emit_line (NULL, "\n");
951
952  got_some = 0;
953
954  for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
955    {
956      if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0)
957	{
958	  if (S_GET_SEGMENT (ptr) == undefined_section)
959	    {
960	      if (!got_some)
961		{
962		  got_some = 1;
963
964		  emit_line (NULL, "UNDEFINED SYMBOLS\n");
965		}
966
967	      emit_line (NULL, "%s\n", S_GET_NAME (ptr));
968	    }
969	}
970    }
971
972  if (!got_some)
973    emit_line (NULL, "NO UNDEFINED SYMBOLS\n");
974}
975
976typedef struct cached_line
977{
978  file_info_type * file;
979  unsigned int     line;
980  char             buffer [LISTING_RHS_WIDTH];
981} cached_line;
982
983static void
984print_source (file_info_type *  current_file,
985	      list_info_type *  list,
986	      unsigned int      width)
987{
988#define NUM_CACHE_LINES  3
989  static cached_line cached_lines[NUM_CACHE_LINES];
990  static int next_free_line = 0;
991  cached_line * cache = NULL;
992
993  if (current_file->linenum > list->hll_line
994      && list->hll_line > 0)
995    {
996      /* This can happen with modern optimizing compilers.  The source
997	 lines from the high level language input program are split up
998	 and interleaved, meaning the line number we want to display
999	 (list->hll_line) can have already been displayed.  We have
1000	 three choices:
1001
1002	   a. Do nothing, since we have already displayed the source
1003	      line.  This was the old behaviour.
1004
1005	   b. Display the particular line requested again, but only
1006	      that line.  This is the new behaviour.
1007
1008	   c. Display the particular line requested again and reset
1009	      the current_file->line_num value so that we redisplay
1010	      all the following lines as well the next time we
1011	      encounter a larger line number.  */
1012      int i;
1013
1014      /* Check the cache, maybe we already have the line saved.  */
1015      for (i = 0; i < NUM_CACHE_LINES; i++)
1016	if (cached_lines[i].file == current_file
1017	    && cached_lines[i].line == list->hll_line)
1018	  {
1019	    cache = cached_lines + i;
1020	    break;
1021	  }
1022
1023      if (i == NUM_CACHE_LINES)
1024	{
1025	  cache = cached_lines + next_free_line;
1026	  next_free_line ++;
1027	  if (next_free_line == NUM_CACHE_LINES)
1028	    next_free_line = 0;
1029
1030	  cache->file = current_file;
1031	  cache->line = list->hll_line;
1032	  cache->buffer[0] = 0;
1033	  rebuffer_line (current_file, cache->line, cache->buffer, width);
1034	}
1035
1036      emit_line (list, "%4u:%-13s **** %s\n",
1037		 cache->line, cache->file->filename, cache->buffer);
1038      return;
1039    }
1040
1041  if (!current_file->at_end)
1042    {
1043      int num_lines_shown = 0;
1044
1045      while (current_file->linenum < list->hll_line
1046	     && !current_file->at_end)
1047	{
1048	  char *p;
1049
1050	  cache = cached_lines + next_free_line;
1051	  cache->file = current_file;
1052	  cache->line = current_file->linenum + 1;
1053	  cache->buffer[0] = 0;
1054	  p = buffer_line (current_file, cache->buffer, width);
1055
1056	  /* Cache optimization:  If printing a group of lines
1057	     cache the first and last lines in the group.  */
1058	  if (num_lines_shown == 0)
1059	    {
1060	      next_free_line ++;
1061	      if (next_free_line == NUM_CACHE_LINES)
1062		next_free_line = 0;
1063	    }
1064
1065	  emit_line (list, "%4u:%-13s **** %s\n",
1066		     cache->line, cache->file->filename, p);
1067	  num_lines_shown ++;
1068	}
1069    }
1070}
1071
1072/* Sometimes the user doesn't want to be bothered by the debugging
1073   records inserted by the compiler, see if the line is suspicious.  */
1074
1075static int
1076debugging_pseudo (list_info_type *list, const char *line)
1077{
1078#ifdef OBJ_ELF
1079  static int in_debug;
1080  int was_debug;
1081#endif
1082
1083  if (list->debugging)
1084    {
1085#ifdef OBJ_ELF
1086      in_debug = 1;
1087#endif
1088      return 1;
1089    }
1090#ifdef OBJ_ELF
1091  was_debug = in_debug;
1092  in_debug = 0;
1093#endif
1094
1095  while (ISSPACE (*line))
1096    line++;
1097
1098  if (*line != '.')
1099    {
1100#ifdef OBJ_ELF
1101      /* The ELF compiler sometimes emits blank lines after switching
1102         out of a debugging section.  If the next line drops us back
1103         into debugging information, then don't print the blank line.
1104         This is a hack for a particular compiler behaviour, not a
1105         general case.  */
1106      if (was_debug
1107	  && *line == '\0'
1108	  && list->next != NULL
1109	  && list->next->debugging)
1110	{
1111	  in_debug = 1;
1112	  return 1;
1113	}
1114#endif
1115
1116      return 0;
1117    }
1118
1119  line++;
1120
1121  if (strncmp (line, "def", 3) == 0)
1122    return 1;
1123  if (strncmp (line, "val", 3) == 0)
1124    return 1;
1125  if (strncmp (line, "scl", 3) == 0)
1126    return 1;
1127  if (strncmp (line, "line", 4) == 0)
1128    return 1;
1129  if (strncmp (line, "endef", 5) == 0)
1130    return 1;
1131  if (strncmp (line, "ln", 2) == 0)
1132    return 1;
1133  if (strncmp (line, "type", 4) == 0)
1134    return 1;
1135  if (strncmp (line, "size", 4) == 0)
1136    return 1;
1137  if (strncmp (line, "dim", 3) == 0)
1138    return 1;
1139  if (strncmp (line, "tag", 3) == 0)
1140    return 1;
1141  if (strncmp (line, "stabs", 5) == 0)
1142    return 1;
1143  if (strncmp (line, "stabn", 5) == 0)
1144    return 1;
1145
1146  return 0;
1147}
1148
1149static void
1150listing_listing (char *name ATTRIBUTE_UNUSED)
1151{
1152  list_info_type *list = head;
1153  file_info_type *current_hll_file = (file_info_type *) NULL;
1154  char *buffer;
1155  char *p;
1156  int show_listing = 1;
1157  unsigned int width;
1158
1159  buffer = (char *) xmalloc (listing_rhs_width);
1160  data_buffer = (char *) xmalloc (MAX_BYTES);
1161  eject = 1;
1162  list = head->next;
1163
1164  while (list)
1165    {
1166      unsigned int list_line;
1167
1168      width = listing_rhs_width > paper_width ? paper_width :
1169	listing_rhs_width;
1170
1171      list_line = list->line;
1172      switch (list->edict)
1173	{
1174	case EDICT_LIST:
1175	  /* Skip all lines up to the current.  */
1176	  list_line--;
1177	  break;
1178	case EDICT_NOLIST:
1179	  show_listing--;
1180	  break;
1181	case EDICT_NOLIST_NEXT:
1182	  if (show_listing == 0)
1183	    list_line--;
1184	  break;
1185	case EDICT_EJECT:
1186	  break;
1187	case EDICT_NONE:
1188	  break;
1189	case EDICT_TITLE:
1190	  title = list->edict_arg;
1191	  break;
1192	case EDICT_SBTTL:
1193	  subtitle = list->edict_arg;
1194	  break;
1195	default:
1196	  abort ();
1197	}
1198
1199      if (show_listing <= 0)
1200	{
1201	  while (list->file->linenum < list_line
1202		 && !list->file->at_end)
1203	    p = buffer_line (list->file, buffer, width);
1204	}
1205
1206      if (list->edict == EDICT_LIST
1207	  || (list->edict == EDICT_NOLIST_NEXT && show_listing == 0))
1208	{
1209	  /* Enable listing for the single line that caused the enable.  */
1210	  list_line++;
1211	  show_listing++;
1212	}
1213
1214      if (show_listing > 0)
1215	{
1216	  /* Scan down the list and print all the stuff which can be done
1217	     with this line (or lines).  */
1218	  if (list->hll_file)
1219	    current_hll_file = list->hll_file;
1220
1221	  if (current_hll_file && list->hll_line && (listing & LISTING_HLL))
1222	    print_source (current_hll_file, list, width);
1223
1224	  if (list->line_contents)
1225	    {
1226	      if (!((listing & LISTING_NODEBUG)
1227		    && debugging_pseudo (list, list->line_contents)))
1228		print_lines (list,
1229			     list->file->linenum == 0 ? list->line : list->file->linenum,
1230			     list->line_contents, calc_hex (list));
1231
1232	      free (list->line_contents);
1233	      list->line_contents = NULL;
1234	    }
1235	  else
1236	    {
1237	      while (list->file->linenum < list_line
1238		     && !list->file->at_end)
1239		{
1240		  unsigned int address;
1241
1242		  p = buffer_line (list->file, buffer, width);
1243
1244		  if (list->file->linenum < list_line)
1245		    address = ~(unsigned int) 0;
1246		  else
1247		    address = calc_hex (list);
1248
1249		  if (!((listing & LISTING_NODEBUG)
1250			&& debugging_pseudo (list, p)))
1251		    print_lines (list, list->file->linenum, p, address);
1252		}
1253	    }
1254
1255	  if (list->edict == EDICT_EJECT)
1256	    eject = 1;
1257	}
1258
1259      if (list->edict == EDICT_NOLIST_NEXT && show_listing == 1)
1260	--show_listing;
1261
1262      list = list->next;
1263    }
1264
1265  free (buffer);
1266  free (data_buffer);
1267  data_buffer = NULL;
1268}
1269
1270/* Print time stamp in ISO format:  yyyy-mm-ddThh:mm:ss.ss+/-zzzz.  */
1271
1272static void
1273print_timestamp (void)
1274{
1275  const time_t now = time (NULL);
1276  struct tm * timestamp;
1277  char stampstr[MAX_DATELEN];
1278
1279  /* Any portable way to obtain subsecond values???  */
1280  timestamp = localtime (&now);
1281  strftime (stampstr, MAX_DATELEN, "%Y-%m-%dT%H:%M:%S.000%z", timestamp);
1282  fprintf (list_file, _("\n time stamp    \t: %s\n\n"), stampstr);
1283}
1284
1285static void
1286print_single_option (char * opt, int *pos)
1287{
1288  int opt_len = strlen (opt);
1289
1290   if ((*pos + opt_len) < paper_width)
1291     {
1292        fprintf (list_file, _("%s "), opt);
1293        *pos = *pos + opt_len;
1294     }
1295   else
1296     {
1297        fprintf (list_file, _("\n\t%s "), opt);
1298        *pos = opt_len;
1299     }
1300}
1301
1302/* Print options passed to as.  */
1303
1304static void
1305print_options (char ** argv)
1306{
1307  const char *field_name = _("\n options passed\t: ");
1308  int pos = strlen (field_name);
1309  char **p;
1310
1311  fputs (field_name, list_file);
1312  for (p = &argv[1]; *p != NULL; p++)
1313    if (**p == '-')
1314      {
1315        /* Ignore these.  */
1316        if (strcmp (*p, "-o") == 0)
1317          {
1318            if (p[1] != NULL)
1319              p++;
1320            continue;
1321          }
1322        if (strcmp (*p, "-v") == 0)
1323          continue;
1324
1325        print_single_option (*p, &pos);
1326      }
1327}
1328
1329/* Print a first section with basic info like file names, as version,
1330   options passed, target, and timestamp.
1331   The format of this section is as follows:
1332
1333   AS VERSION
1334
1335   fieldname TAB ':' fieldcontents
1336  { TAB fieldcontents-cont }  */
1337
1338static void
1339listing_general_info (char ** argv)
1340{
1341  /* Print the stuff on the first line.  */
1342  eject = 1;
1343  listing_page (NULL);
1344
1345  fprintf (list_file,
1346           _(" GNU assembler version %s (%s)\n\t using BFD version %s."),
1347           VERSION, TARGET_ALIAS, BFD_VERSION_STRING);
1348  print_options (argv);
1349  fprintf (list_file, _("\n input file    \t: %s"), fn);
1350  fprintf (list_file, _("\n output file   \t: %s"), out_file_name);
1351  fprintf (list_file, _("\n target        \t: %s"), TARGET_CANONICAL);
1352  print_timestamp ();
1353}
1354
1355void
1356listing_print (char *name, char **argv)
1357{
1358  int using_stdout;
1359
1360  title = "";
1361  subtitle = "";
1362
1363  if (name == NULL)
1364    {
1365      list_file = stdout;
1366      using_stdout = 1;
1367    }
1368  else
1369    {
1370      list_file = fopen (name, FOPEN_WT);
1371      if (list_file != NULL)
1372	using_stdout = 0;
1373      else
1374	{
1375	  as_warn (_("can't open %s: %s"), name, xstrerror (errno));
1376	  list_file = stdout;
1377	  using_stdout = 1;
1378	}
1379    }
1380
1381  if (listing & LISTING_NOFORM)
1382    paper_height = 0;
1383
1384  if (listing & LISTING_GENERAL)
1385    listing_general_info (argv);
1386
1387  if (listing & LISTING_LISTING)
1388    listing_listing (name);
1389
1390  if (listing & LISTING_SYMBOLS)
1391    list_symbol_table ();
1392
1393  if (! using_stdout)
1394    {
1395      if (fclose (list_file) == EOF)
1396	as_warn (_("can't close %s: %s"), name, xstrerror (errno));
1397    }
1398
1399  if (last_open_file)
1400    fclose (last_open_file);
1401}
1402
1403void
1404listing_file (const char *name)
1405{
1406  fn = name;
1407}
1408
1409void
1410listing_eject (int ignore ATTRIBUTE_UNUSED)
1411{
1412  if (listing)
1413    listing_tail->edict = EDICT_EJECT;
1414}
1415
1416/* Turn listing on or off.  An argument of 0 means to turn off
1417   listing.  An argument of 1 means to turn on listing.  An argument
1418   of 2 means to turn off listing, but as of the next line; that is,
1419   the current line should be listed, but the next line should not.  */
1420
1421void
1422listing_list (int on)
1423{
1424  if (listing)
1425    {
1426      switch (on)
1427	{
1428	case 0:
1429	  if (listing_tail->edict == EDICT_LIST)
1430	    listing_tail->edict = EDICT_NONE;
1431	  else
1432	    listing_tail->edict = EDICT_NOLIST;
1433	  break;
1434	case 1:
1435	  if (listing_tail->edict == EDICT_NOLIST
1436	      || listing_tail->edict == EDICT_NOLIST_NEXT)
1437	    listing_tail->edict = EDICT_NONE;
1438	  else
1439	    listing_tail->edict = EDICT_LIST;
1440	  break;
1441	case 2:
1442	  listing_tail->edict = EDICT_NOLIST_NEXT;
1443	  break;
1444	default:
1445	  abort ();
1446	}
1447    }
1448}
1449
1450void
1451listing_psize (int width_only)
1452{
1453  if (! width_only)
1454    {
1455      paper_height = get_absolute_expression ();
1456
1457      if (paper_height < 0 || paper_height > 1000)
1458	{
1459	  paper_height = 0;
1460	  as_warn (_("strange paper height, set to no form"));
1461	}
1462
1463      if (*input_line_pointer != ',')
1464	{
1465	  demand_empty_rest_of_line ();
1466	  return;
1467	}
1468
1469      ++input_line_pointer;
1470    }
1471
1472  paper_width = get_absolute_expression ();
1473
1474  demand_empty_rest_of_line ();
1475}
1476
1477void
1478listing_nopage (int ignore ATTRIBUTE_UNUSED)
1479{
1480  paper_height = 0;
1481}
1482
1483void
1484listing_title (int depth)
1485{
1486  int quoted;
1487  char *start;
1488  char *ttl;
1489  unsigned int length;
1490
1491  SKIP_WHITESPACE ();
1492  if (*input_line_pointer != '\"')
1493    quoted = 0;
1494  else
1495    {
1496      quoted = 1;
1497      ++input_line_pointer;
1498    }
1499
1500  start = input_line_pointer;
1501
1502  while (*input_line_pointer)
1503    {
1504      if (quoted
1505	  ? *input_line_pointer == '\"'
1506	  : is_end_of_line[(unsigned char) *input_line_pointer])
1507	{
1508	  if (listing)
1509	    {
1510	      length = input_line_pointer - start;
1511	      ttl = (char *) xmalloc (length + 1);
1512	      memcpy (ttl, start, length);
1513	      ttl[length] = 0;
1514	      listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
1515	      listing_tail->edict_arg = ttl;
1516	    }
1517	  if (quoted)
1518	    input_line_pointer++;
1519	  demand_empty_rest_of_line ();
1520	  return;
1521	}
1522      else if (*input_line_pointer == '\n')
1523	{
1524	  as_bad (_("new line in title"));
1525	  demand_empty_rest_of_line ();
1526	  return;
1527	}
1528      else
1529	{
1530	  input_line_pointer++;
1531	}
1532    }
1533}
1534
1535void
1536listing_source_line (unsigned int line)
1537{
1538  if (listing)
1539    {
1540      new_frag ();
1541      listing_tail->hll_line = line;
1542      new_frag ();
1543    }
1544}
1545
1546void
1547listing_source_file (const char *file)
1548{
1549  if (listing)
1550    listing_tail->hll_file = file_info (file);
1551}
1552
1553#else
1554
1555/* Dummy functions for when compiled without listing enabled.  */
1556
1557void
1558listing_list (int on)
1559{
1560  s_ignore (0);
1561}
1562
1563void
1564listing_eject (int ignore)
1565{
1566  s_ignore (0);
1567}
1568
1569void
1570listing_psize (int ignore)
1571{
1572  s_ignore (0);
1573}
1574
1575void
1576listing_nopage (int ignore)
1577{
1578  s_ignore (0);
1579}
1580
1581void
1582listing_title (int depth)
1583{
1584  s_ignore (0);
1585}
1586
1587void
1588listing_file (const char *name)
1589{
1590}
1591
1592void
1593listing_newline (char *name)
1594{
1595}
1596
1597void
1598listing_source_line (unsigned int n)
1599{
1600}
1601
1602void
1603listing_source_file (const char *n)
1604{
1605}
1606
1607#endif
1608