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