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