Merge from vendor branch CVS:
[dragonfly.git] / contrib / binutils-2.15 / gas / listing.c
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
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
236 listing_warning (const char *message)
237 {
238   listing_message (_("Warning:"), message);
239 }
240
241 void
242 listing_error (const char *message)
243 {
244   listing_message (_("Error:"), message);
245 }
246
247 static file_info_type *
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
273 new_frag (void)
274 {
275   frag_wane (frag_now);
276   frag_new (0);
277 }
278
279 void
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
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 *
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
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
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
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
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
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
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
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
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
1127 listing_file (const char *name)
1128 {
1129   fn = name;
1130 }
1131
1132 void
1133 listing_eject (int ignore ATTRIBUTE_UNUSED)
1134 {
1135   if (listing)
1136     listing_tail->edict = EDICT_EJECT;
1137 }
1138
1139 void
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
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
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
1209 listing_nopage (int ignore ATTRIBUTE_UNUSED)
1210 {
1211   paper_height = 0;
1212 }
1213
1214 void
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
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
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
1289 listing_flags (int ignore)
1290 {
1291   s_ignore (0);
1292 }
1293
1294 void
1295 listing_list (int on)
1296 {
1297   s_ignore (0);
1298 }
1299
1300 void
1301 listing_eject (int ignore)
1302 {
1303   s_ignore (0);
1304 }
1305
1306 void
1307 listing_psize (int ignore)
1308 {
1309   s_ignore (0);
1310 }
1311
1312 void
1313 listing_nopage (int ignore)
1314 {
1315   s_ignore (0);
1316 }
1317
1318 void
1319 listing_title (int depth)
1320 {
1321   s_ignore (0);
1322 }
1323
1324 void
1325 listing_file (const char *name)
1326 {
1327 }
1328
1329 void
1330 listing_newline (char *name)
1331 {
1332 }
1333
1334 void
1335 listing_source_line (unsigned int n)
1336 {
1337 }
1338
1339 void
1340 listing_source_file (const char *n)
1341 {
1342 }
1343
1344 #endif