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