xref: /netbsd-src/external/gpl3/binutils/dist/gas/listing.c (revision 62f324d0121177eaf2e0384f92fd9ca2a751c795)
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.  */
124 typedef 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 
133 enum 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.  */
147 struct 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 
184 typedef struct list_info_struct list_info_type;
185 
186 int listing_lhs_width        = LISTING_LHS_WIDTH;
187 int listing_lhs_width_second = LISTING_LHS_WIDTH_SECOND;
188 int listing_lhs_cont_lines   = LISTING_LHS_CONT_LINES;
189 int listing_rhs_width        = LISTING_RHS_WIDTH;
190 
191 struct list_info_struct *        listing_tail;
192 
193 static file_info_type *          file_info_head;
194 static file_info_type *          last_open_file_info;
195 static FILE *                    last_open_file;
196 static struct list_info_struct * head;
197 static int                       paper_width = 200;
198 static int                       paper_height = 60;
199 
200 extern int                       listing;
201 
202 /* File to output listings to.  */
203 static 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 
214 static char *data_buffer;
215 
216 /* Prototypes.  */
217 static void listing_message (const char *, const char *);
218 static file_info_type *file_info (const char *);
219 static void new_frag (void);
220 static void listing_page (list_info_type *);
221 static unsigned int calc_hex (list_info_type *);
222 static void print_lines (list_info_type *, unsigned int, char *, unsigned int);
223 static void list_symbol_table (void);
224 static int debugging_pseudo (list_info_type *, const char *);
225 static void listing_listing (char *);
226 
227 static void
228 listing_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 
240 void
241 listing_warning (const char *message)
242 {
243   listing_message (_("Warning:"), message);
244 }
245 
246 void
247 listing_error (const char *message)
248 {
249   listing_message (_("Error:"), message);
250 }
251 
252 static file_info_type *
253 file_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 
277 static void
278 new_frag (void)
279 {
280   frag_wane (frag_now);
281   frag_new (0);
282 }
283 
284 void
285 listing_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 
435 void
436 listing_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 
462 static char *
463 buffer_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 
542 static char *
543 rebuffer_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 
648 static const char *fn;
649 
650 static unsigned int eject;	/* Eject pending */
651 static unsigned int page;	/* Current page number */
652 static char *title;		/* Current title */
653 static char *subtitle;		/* Current subtitle */
654 static unsigned int on_page;	/* Number of lines printed on current page */
655 
656 static void
657 listing_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 
702 static void
703 emit_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 
716 static unsigned int
717 calc_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 
784 static void
785 print_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 
876 static void
877 list_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 
976 typedef struct cached_line
977 {
978   file_info_type * file;
979   unsigned int     line;
980   char             buffer [LISTING_RHS_WIDTH];
981 } cached_line;
982 
983 static void
984 print_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 
1075 static int
1076 debugging_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 
1149 static void
1150 listing_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 
1272 static void
1273 print_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 
1285 static void
1286 print_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 
1304 static void
1305 print_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 
1338 static void
1339 listing_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 
1355 void
1356 listing_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 
1403 void
1404 listing_file (const char *name)
1405 {
1406   fn = name;
1407 }
1408 
1409 void
1410 listing_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 
1421 void
1422 listing_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 
1450 void
1451 listing_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 
1477 void
1478 listing_nopage (int ignore ATTRIBUTE_UNUSED)
1479 {
1480   paper_height = 0;
1481 }
1482 
1483 void
1484 listing_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 
1535 void
1536 listing_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 
1546 void
1547 listing_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 
1557 void
1558 listing_list (int on)
1559 {
1560   s_ignore (0);
1561 }
1562 
1563 void
1564 listing_eject (int ignore)
1565 {
1566   s_ignore (0);
1567 }
1568 
1569 void
1570 listing_psize (int ignore)
1571 {
1572   s_ignore (0);
1573 }
1574 
1575 void
1576 listing_nopage (int ignore)
1577 {
1578   s_ignore (0);
1579 }
1580 
1581 void
1582 listing_title (int depth)
1583 {
1584   s_ignore (0);
1585 }
1586 
1587 void
1588 listing_file (const char *name)
1589 {
1590 }
1591 
1592 void
1593 listing_newline (char *name)
1594 {
1595 }
1596 
1597 void
1598 listing_source_line (unsigned int n)
1599 {
1600 }
1601 
1602 void
1603 listing_source_file (const char *n)
1604 {
1605 }
1606 
1607 #endif
1608