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