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