1 /* listing.c - maintain assembly listings
2    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3    2001, 2002, 2003, 2005
4    Free Software Foundation, Inc.
5 
6    This file is part of GAS, the GNU Assembler.
7 
8    GAS is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2, or (at your option)
11    any later version.
12 
13    GAS is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with GAS; see the file COPYING.  If not, write to the Free
20    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21    02110-1301, USA.  */
22 
23 /* Contributed by Steve Chamberlain <sac@cygnus.com>
24 
25  A listing page looks like:
26 
27  LISTING_HEADER  sourcefilename pagenumber
28  TITLE LINE
29  SUBTITLE LINE
30  linenumber address data  source
31  linenumber address data  source
32  linenumber address data  source
33  linenumber address data  source
34 
35  If not overridden, the listing commands are:
36 
37  .title  "stuff"
38  	Put "stuff" onto the title line
39  .sbttl  "stuff"
40         Put stuff onto the subtitle line
41 
42   If these commands come within 10 lines of the top of the page, they
43   will affect the page they are on, as well as any subsequent page
44 
45  .eject
46  	Thow a page
47  .list
48  	Increment the enable listing counter
49  .nolist
50  	Decrement the enable listing counter
51 
52  .psize Y[,X]
53  	Set the paper size to X wide and Y high. Setting a psize Y of
54 	zero will suppress form feeds except where demanded by .eject
55 
56  If the counter goes below zero, listing is suppressed.
57 
58  Listings are a maintained by read calling various listing_<foo>
59  functions.  What happens most is that the macro NO_LISTING is not
60  defined (from the Makefile), then the macro LISTING_NEWLINE expands
61  into a call to listing_newline.  The call is done from read.c, every
62  time it sees a newline, and -l is on the command line.
63 
64  The function listing_newline remembers the frag associated with the
65  newline, and creates a new frag - note that this is wasteful, but not
66  a big deal, since listing slows things down a lot anyway.  The
67  function also remembers when the filename changes.
68 
69  When all the input has finished, and gas has had a chance to settle
70  down, the listing is output. This is done by running down the list of
71  frag/source file records, and opening the files as needed and printing
72  out the bytes and chars associated with them.
73 
74  The only things which the architecture can change about the listing
75  are defined in these macros:
76 
77  LISTING_HEADER		The name of the architecture
78  LISTING_WORD_SIZE      The make of the number of bytes in a word, this determines
79  			the clumping of the output data. eg a value of
80 			2 makes words look like 1234 5678, whilst 1
81 			would make the same value look like 12 34 56
82 			78
83  LISTING_LHS_WIDTH      Number of words of above size for the lhs
84 
85  LISTING_LHS_WIDTH_SECOND   Number of words for the data on the lhs
86  			for the second line
87 
88  LISTING_LHS_CONT_LINES	Max number of lines to use up for a continuation
89  LISTING_RHS_WIDTH      Number of chars from the input file to print
90                         on a line.  */
91 
92 #include "as.h"
93 #include "obstack.h"
94 #include "safe-ctype.h"
95 #include "input-file.h"
96 #include "subsegs.h"
97 
98 #ifndef NO_LISTING
99 
100 #ifndef LISTING_HEADER
101 #define LISTING_HEADER "GAS LISTING"
102 #endif
103 #ifndef LISTING_WORD_SIZE
104 #define LISTING_WORD_SIZE 4
105 #endif
106 #ifndef LISTING_LHS_WIDTH
107 #define LISTING_LHS_WIDTH ((LISTING_WORD_SIZE) > 4 ? 1 : 4 / (LISTING_WORD_SIZE))
108 #endif
109 #ifndef LISTING_LHS_WIDTH_SECOND
110 #define LISTING_LHS_WIDTH_SECOND LISTING_LHS_WIDTH
111 #endif
112 #ifndef LISTING_RHS_WIDTH
113 #define LISTING_RHS_WIDTH 100
114 #endif
115 #ifndef LISTING_LHS_CONT_LINES
116 #define LISTING_LHS_CONT_LINES 4
117 #endif
118 
119 /* This structure remembers which .s were used.  */
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 	      data_buffer_size += 2;
617 
618 	      var_rep_idx++;
619 	      octet_in_frag++;
620 
621 	      if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var)
622 		var_rep_idx = var_rep_max;
623 	    }
624 	}
625 
626       frag_ptr = frag_ptr->fr_next;
627     }
628   data_buffer[data_buffer_size] = '\0';
629   return address;
630 }
631 
632 static void
print_lines(list_info_type * list,unsigned int lineno,char * string,unsigned int address)633 print_lines (list_info_type *list, unsigned int lineno,
634 	     char *string, unsigned int address)
635 {
636   unsigned int idx;
637   unsigned int nchars;
638   unsigned int lines;
639   unsigned int octet_in_word = 0;
640   char *src = data_buffer;
641   int cur;
642 
643   /* Print the stuff on the first line.  */
644   listing_page (list);
645   nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width;
646 
647   /* Print the hex for the first line.  */
648   if (address == ~(unsigned int) 0)
649     {
650       fprintf (list_file, "% 4d     ", lineno);
651       for (idx = 0; idx < nchars; idx++)
652 	fprintf (list_file, " ");
653 
654       fprintf (list_file, "\t%s\n", string ? string : "");
655 
656       on_page++;
657 
658       listing_page (0);
659 
660       return;
661     }
662 
663   if (had_errors ())
664     fprintf (list_file, "% 4d ???? ", lineno);
665   else
666     fprintf (list_file, "% 4d %04x ", lineno, address);
667 
668   /* And the data to go along with it.  */
669   idx = 0;
670   cur = 0;
671   while (src[cur] && idx < nchars)
672     {
673       int offset;
674       offset = cur;
675       fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
676       cur += 2;
677       octet_in_word++;
678 
679       if (octet_in_word == LISTING_WORD_SIZE)
680 	{
681 	  fprintf (list_file, " ");
682 	  idx++;
683 	  octet_in_word = 0;
684 	}
685 
686       idx += 2;
687     }
688 
689   for (; idx < nchars; idx++)
690     fprintf (list_file, " ");
691 
692   fprintf (list_file, "\t%s\n", string ? string : "");
693   on_page++;
694   listing_page (list);
695 
696   if (list->message)
697     {
698       fprintf (list_file, "****  %s\n", list->message);
699       listing_page (list);
700       on_page++;
701     }
702 
703   for (lines = 0;
704        lines < (unsigned int) listing_lhs_cont_lines
705 	 && src[cur];
706        lines++)
707     {
708       nchars = ((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second - 1;
709       idx = 0;
710 
711       /* Print any more lines of data, but more compactly.  */
712       fprintf (list_file, "% 4d      ", lineno);
713 
714       while (src[cur] && idx < nchars)
715 	{
716 	  int offset;
717 	  offset = cur;
718 	  fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
719 	  cur += 2;
720 	  idx += 2;
721 	  octet_in_word++;
722 
723 	  if (octet_in_word == LISTING_WORD_SIZE)
724 	    {
725 	      fprintf (list_file, " ");
726 	      idx++;
727 	      octet_in_word = 0;
728 	    }
729 	}
730 
731       fprintf (list_file, "\n");
732       on_page++;
733       listing_page (list);
734     }
735 }
736 
737 static void
list_symbol_table(void)738 list_symbol_table (void)
739 {
740   extern symbolS *symbol_rootP;
741   int got_some = 0;
742 
743   symbolS *ptr;
744   eject = 1;
745   listing_page (0);
746 
747   for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
748     {
749       if (SEG_NORMAL (S_GET_SEGMENT (ptr))
750 	  || S_GET_SEGMENT (ptr) == absolute_section)
751 	{
752 #ifdef BFD_ASSEMBLER
753 	  /* Don't report section symbols.  They are not interesting.  */
754 	  if (symbol_section_p (ptr))
755 	    continue;
756 #endif
757 	  if (S_GET_NAME (ptr))
758 	    {
759 	      char buf[30], fmt[8];
760 	      valueT val = S_GET_VALUE (ptr);
761 
762 	      /* @@ Note that this is dependent on the compilation options,
763 		 not solely on the target characteristics.  */
764 	      if (sizeof (val) == 4 && sizeof (int) == 4)
765 		sprintf (buf, "%08lx", (unsigned long) val);
766 	      else if (sizeof (val) <= sizeof (unsigned long))
767 		{
768 		  sprintf (fmt, "%%0%lulx",
769 			   (unsigned long) (sizeof (val) * 2));
770 		  sprintf (buf, fmt, (unsigned long) val);
771 		}
772 #if defined (BFD64)
773 	      else if (sizeof (val) > 4)
774 		sprintf_vma (buf, val);
775 #endif
776 	      else
777 		abort ();
778 
779 	      if (!got_some)
780 		{
781 		  fprintf (list_file, "DEFINED SYMBOLS\n");
782 		  on_page++;
783 		  got_some = 1;
784 		}
785 
786 	      if (symbol_get_frag (ptr) && symbol_get_frag (ptr)->line)
787 		{
788 		  fprintf (list_file, "%20s:%-5d  %s:%s %s\n",
789 			   symbol_get_frag (ptr)->line->file->filename,
790 			   symbol_get_frag (ptr)->line->line,
791 			   segment_name (S_GET_SEGMENT (ptr)),
792 			   buf, S_GET_NAME (ptr));
793 		}
794 	      else
795 		{
796 		  fprintf (list_file, "%33s:%s %s\n",
797 			   segment_name (S_GET_SEGMENT (ptr)),
798 			   buf, S_GET_NAME (ptr));
799 		}
800 
801 	      on_page++;
802 	      listing_page (0);
803 	    }
804 	}
805 
806     }
807   if (!got_some)
808     {
809       fprintf (list_file, "NO DEFINED SYMBOLS\n");
810       on_page++;
811     }
812   fprintf (list_file, "\n");
813   on_page++;
814   listing_page (0);
815 
816   got_some = 0;
817 
818   for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
819     {
820       if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0)
821 	{
822 	  if (S_GET_SEGMENT (ptr) == undefined_section)
823 	    {
824 	      if (!got_some)
825 		{
826 		  got_some = 1;
827 		  fprintf (list_file, "UNDEFINED SYMBOLS\n");
828 		  on_page++;
829 		  listing_page (0);
830 		}
831 	      fprintf (list_file, "%s\n", S_GET_NAME (ptr));
832 	      on_page++;
833 	      listing_page (0);
834 	    }
835 	}
836     }
837   if (!got_some)
838     {
839       fprintf (list_file, "NO UNDEFINED SYMBOLS\n");
840       on_page++;
841       listing_page (0);
842     }
843 }
844 
845 static void
print_source(file_info_type * current_file,list_info_type * list,char * buffer,unsigned int width)846 print_source (file_info_type *current_file, list_info_type *list,
847 	      char *buffer, unsigned int width)
848 {
849   if (!current_file->at_end)
850     {
851       while (current_file->linenum < list->hll_line
852 	     && !current_file->at_end)
853 	{
854 	  char *p = buffer_line (current_file, buffer, width);
855 
856 	  fprintf (list_file, "%4u:%-13s **** %s\n", current_file->linenum,
857 		   current_file->filename, p);
858 	  on_page++;
859 	  listing_page (list);
860 	}
861     }
862 }
863 
864 /* Sometimes the user doesn't want to be bothered by the debugging
865    records inserted by the compiler, see if the line is suspicious.  */
866 
867 static int
debugging_pseudo(list_info_type * list,const char * line)868 debugging_pseudo (list_info_type *list, const char *line)
869 {
870   static int in_debug;
871   int was_debug;
872 
873   if (list->debugging)
874     {
875       in_debug = 1;
876       return 1;
877     }
878 
879   was_debug = in_debug;
880   in_debug = 0;
881 
882   while (ISSPACE (*line))
883     line++;
884 
885   if (*line != '.')
886     {
887 #ifdef OBJ_ELF
888       /* The ELF compiler sometimes emits blank lines after switching
889          out of a debugging section.  If the next line drops us back
890          into debugging information, then don't print the blank line.
891          This is a hack for a particular compiler behaviour, not a
892          general case.  */
893       if (was_debug
894 	  && *line == '\0'
895 	  && list->next != NULL
896 	  && list->next->debugging)
897 	{
898 	  in_debug = 1;
899 	  return 1;
900 	}
901 #endif
902 
903       return 0;
904     }
905 
906   line++;
907 
908   if (strncmp (line, "def", 3) == 0)
909     return 1;
910   if (strncmp (line, "val", 3) == 0)
911     return 1;
912   if (strncmp (line, "scl", 3) == 0)
913     return 1;
914   if (strncmp (line, "line", 4) == 0)
915     return 1;
916   if (strncmp (line, "endef", 5) == 0)
917     return 1;
918   if (strncmp (line, "ln", 2) == 0)
919     return 1;
920   if (strncmp (line, "type", 4) == 0)
921     return 1;
922   if (strncmp (line, "size", 4) == 0)
923     return 1;
924   if (strncmp (line, "dim", 3) == 0)
925     return 1;
926   if (strncmp (line, "tag", 3) == 0)
927     return 1;
928   if (strncmp (line, "stabs", 5) == 0)
929     return 1;
930   if (strncmp (line, "stabn", 5) == 0)
931     return 1;
932 
933   return 0;
934 }
935 
936 static void
listing_listing(char * name ATTRIBUTE_UNUSED)937 listing_listing (char *name ATTRIBUTE_UNUSED)
938 {
939   list_info_type *list = head;
940   file_info_type *current_hll_file = (file_info_type *) NULL;
941   char *message;
942   char *buffer;
943   char *p;
944   int show_listing = 1;
945   unsigned int width;
946 
947   buffer = xmalloc (listing_rhs_width);
948   data_buffer = xmalloc (MAX_BYTES);
949   eject = 1;
950   list = head;
951 
952   while (list != (list_info_type *) NULL && 0)
953     {
954       if (list->next)
955 	list->frag = list->next->frag;
956       list = list->next;
957     }
958 
959   list = head->next;
960 
961   while (list)
962     {
963       unsigned int list_line;
964 
965       width = listing_rhs_width > paper_width ? paper_width :
966 	listing_rhs_width;
967 
968       list_line = list->line;
969       switch (list->edict)
970 	{
971 	case EDICT_LIST:
972 	  /* Skip all lines up to the current.  */
973 	  list_line--;
974 	  break;
975 	case EDICT_NOLIST:
976 	  show_listing--;
977 	  break;
978 	case EDICT_NOLIST_NEXT:
979 	  if (show_listing == 0)
980 	    list_line--;
981 	  break;
982 	case EDICT_EJECT:
983 	  break;
984 	case EDICT_NONE:
985 	  break;
986 	case EDICT_TITLE:
987 	  title = list->edict_arg;
988 	  break;
989 	case EDICT_SBTTL:
990 	  subtitle = list->edict_arg;
991 	  break;
992 	default:
993 	  abort ();
994 	}
995 
996       if (show_listing <= 0)
997 	{
998 	  while (list->file->linenum < list_line
999 		 && !list->file->at_end)
1000 	    p = buffer_line (list->file, buffer, width);
1001 	}
1002 
1003       if (list->edict == EDICT_LIST
1004 	  || (list->edict == EDICT_NOLIST_NEXT && show_listing == 0))
1005 	{
1006 	  /* Enable listing for the single line that caused the enable.  */
1007 	  list_line++;
1008 	  show_listing++;
1009 	}
1010 
1011       if (show_listing > 0)
1012 	{
1013 	  /* Scan down the list and print all the stuff which can be done
1014 	     with this line (or lines).  */
1015 	  message = 0;
1016 
1017 	  if (list->hll_file)
1018 	    current_hll_file = list->hll_file;
1019 
1020 	  if (current_hll_file && list->hll_line && (listing & LISTING_HLL))
1021 	    print_source (current_hll_file, list, buffer, width);
1022 
1023 	  if (list->line_contents)
1024 	    {
1025 	      if (!((listing & LISTING_NODEBUG)
1026 		    && debugging_pseudo (list, list->line_contents)))
1027 		print_lines (list,
1028 			     list->file->linenum == 0 ? list->line : list->file->linenum,
1029 			     list->line_contents, calc_hex (list));
1030 
1031 	      free (list->line_contents);
1032 	      list->line_contents = NULL;
1033 	    }
1034 	  else
1035 	    {
1036 	      while (list->file->linenum < list_line
1037 		     && !list->file->at_end)
1038 		{
1039 		  unsigned int address;
1040 
1041 		  p = buffer_line (list->file, buffer, width);
1042 
1043 		  if (list->file->linenum < list_line)
1044 		    address = ~(unsigned int) 0;
1045 		  else
1046 		    address = calc_hex (list);
1047 
1048 		  if (!((listing & LISTING_NODEBUG)
1049 			&& debugging_pseudo (list, p)))
1050 		    print_lines (list, list->file->linenum, p, address);
1051 		}
1052 	    }
1053 
1054 	  if (list->edict == EDICT_EJECT)
1055 	    eject = 1;
1056 	}
1057 
1058       if (list->edict == EDICT_NOLIST_NEXT && show_listing == 1)
1059 	--show_listing;
1060 
1061       list = list->next;
1062     }
1063 
1064   free (buffer);
1065   free (data_buffer);
1066   data_buffer = NULL;
1067 }
1068 
1069 void
listing_print(char * name)1070 listing_print (char *name)
1071 {
1072   int using_stdout;
1073 
1074   title = "";
1075   subtitle = "";
1076 
1077   if (name == NULL)
1078     {
1079       list_file = stdout;
1080       using_stdout = 1;
1081     }
1082   else
1083     {
1084       list_file = fopen (name, FOPEN_WT);
1085       if (list_file != NULL)
1086 	using_stdout = 0;
1087       else
1088 	{
1089 #ifdef BFD_ASSEMBLER
1090       bfd_set_error (bfd_error_system_call);
1091 #endif
1092 	  as_perror (_("can't open list file: %s"), name);
1093 	  list_file = stdout;
1094 	  using_stdout = 1;
1095 	}
1096     }
1097 
1098   if (listing & LISTING_NOFORM)
1099     paper_height = 0;
1100 
1101   if (listing & LISTING_LISTING)
1102     listing_listing (name);
1103 
1104   if (listing & LISTING_SYMBOLS)
1105     list_symbol_table ();
1106 
1107   if (! using_stdout)
1108     {
1109       if (fclose (list_file) == EOF)
1110 	{
1111 #ifdef BFD_ASSEMBLER
1112 	  bfd_set_error (bfd_error_system_call);
1113 #endif
1114 	  as_perror (_("error closing list file: %s"), name);
1115 	}
1116     }
1117 
1118   if (last_open_file)
1119     fclose (last_open_file);
1120 }
1121 
1122 void
listing_file(const char * name)1123 listing_file (const char *name)
1124 {
1125   fn = name;
1126 }
1127 
1128 void
listing_eject(int ignore ATTRIBUTE_UNUSED)1129 listing_eject (int ignore ATTRIBUTE_UNUSED)
1130 {
1131   if (listing)
1132     listing_tail->edict = EDICT_EJECT;
1133 }
1134 
1135 void
listing_flags(int ignore ATTRIBUTE_UNUSED)1136 listing_flags (int ignore ATTRIBUTE_UNUSED)
1137 {
1138   while ((*input_line_pointer++) && (*input_line_pointer != '\n'))
1139     input_line_pointer++;
1140 
1141 }
1142 
1143 /* Turn listing on or off.  An argument of 0 means to turn off
1144    listing.  An argument of 1 means to turn on listing.  An argument
1145    of 2 means to turn off listing, but as of the next line; that is,
1146    the current line should be listed, but the next line should not.  */
1147 
1148 void
listing_list(int on)1149 listing_list (int on)
1150 {
1151   if (listing)
1152     {
1153       switch (on)
1154 	{
1155 	case 0:
1156 	  if (listing_tail->edict == EDICT_LIST)
1157 	    listing_tail->edict = EDICT_NONE;
1158 	  else
1159 	    listing_tail->edict = EDICT_NOLIST;
1160 	  break;
1161 	case 1:
1162 	  if (listing_tail->edict == EDICT_NOLIST
1163 	      || listing_tail->edict == EDICT_NOLIST_NEXT)
1164 	    listing_tail->edict = EDICT_NONE;
1165 	  else
1166 	    listing_tail->edict = EDICT_LIST;
1167 	  break;
1168 	case 2:
1169 	  listing_tail->edict = EDICT_NOLIST_NEXT;
1170 	  break;
1171 	default:
1172 	  abort ();
1173 	}
1174     }
1175 }
1176 
1177 void
listing_psize(int width_only)1178 listing_psize (int width_only)
1179 {
1180   if (! width_only)
1181     {
1182       paper_height = get_absolute_expression ();
1183 
1184       if (paper_height < 0 || paper_height > 1000)
1185 	{
1186 	  paper_height = 0;
1187 	  as_warn (_("strange paper height, set to no form"));
1188 	}
1189 
1190       if (*input_line_pointer != ',')
1191 	{
1192 	  demand_empty_rest_of_line ();
1193 	  return;
1194 	}
1195 
1196       ++input_line_pointer;
1197     }
1198 
1199   paper_width = get_absolute_expression ();
1200 
1201   demand_empty_rest_of_line ();
1202 }
1203 
1204 void
listing_nopage(int ignore ATTRIBUTE_UNUSED)1205 listing_nopage (int ignore ATTRIBUTE_UNUSED)
1206 {
1207   paper_height = 0;
1208 }
1209 
1210 void
listing_title(int depth)1211 listing_title (int depth)
1212 {
1213   int quoted;
1214   char *start;
1215   char *ttl;
1216   unsigned int length;
1217 
1218   SKIP_WHITESPACE ();
1219   if (*input_line_pointer != '\"')
1220     quoted = 0;
1221   else
1222     {
1223       quoted = 1;
1224       ++input_line_pointer;
1225     }
1226 
1227   start = input_line_pointer;
1228 
1229   while (*input_line_pointer)
1230     {
1231       if (quoted
1232 	  ? *input_line_pointer == '\"'
1233 	  : is_end_of_line[(unsigned char) *input_line_pointer])
1234 	{
1235 	  if (listing)
1236 	    {
1237 	      length = input_line_pointer - start;
1238 	      ttl = xmalloc (length + 1);
1239 	      memcpy (ttl, start, length);
1240 	      ttl[length] = 0;
1241 	      listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
1242 	      listing_tail->edict_arg = ttl;
1243 	    }
1244 	  if (quoted)
1245 	    input_line_pointer++;
1246 	  demand_empty_rest_of_line ();
1247 	  return;
1248 	}
1249       else if (*input_line_pointer == '\n')
1250 	{
1251 	  as_bad (_("new line in title"));
1252 	  demand_empty_rest_of_line ();
1253 	  return;
1254 	}
1255       else
1256 	{
1257 	  input_line_pointer++;
1258 	}
1259     }
1260 }
1261 
1262 void
listing_source_line(unsigned int line)1263 listing_source_line (unsigned int line)
1264 {
1265   if (listing)
1266     {
1267       new_frag ();
1268       listing_tail->hll_line = line;
1269       new_frag ();
1270     }
1271 }
1272 
1273 void
listing_source_file(const char * file)1274 listing_source_file (const char *file)
1275 {
1276   if (listing)
1277     listing_tail->hll_file = file_info (file);
1278 }
1279 
1280 #else
1281 
1282 /* Dummy functions for when compiled without listing enabled.  */
1283 
1284 void
listing_flags(int ignore)1285 listing_flags (int ignore)
1286 {
1287   s_ignore (0);
1288 }
1289 
1290 void
listing_list(int on)1291 listing_list (int on)
1292 {
1293   s_ignore (0);
1294 }
1295 
1296 void
listing_eject(int ignore)1297 listing_eject (int ignore)
1298 {
1299   s_ignore (0);
1300 }
1301 
1302 void
listing_psize(int ignore)1303 listing_psize (int ignore)
1304 {
1305   s_ignore (0);
1306 }
1307 
1308 void
listing_nopage(int ignore)1309 listing_nopage (int ignore)
1310 {
1311   s_ignore (0);
1312 }
1313 
1314 void
listing_title(int depth)1315 listing_title (int depth)
1316 {
1317   s_ignore (0);
1318 }
1319 
1320 void
listing_file(const char * name)1321 listing_file (const char *name)
1322 {
1323 }
1324 
1325 void
listing_newline(char * name)1326 listing_newline (char *name)
1327 {
1328 }
1329 
1330 void
listing_source_line(unsigned int n)1331 listing_source_line (unsigned int n)
1332 {
1333 }
1334 
1335 void
listing_source_file(const char * n)1336 listing_source_file (const char *n)
1337 {
1338 }
1339 
1340 #endif
1341