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