Automatic date update in version.in
[binutils-gdb.git] / gas / listing.c
blob23f76a70ad7928aa4f1d3bf89adbb0dea92b2247
1 /* listing.c - maintain assembly listings
2 Copyright (C) 1991-2024 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
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.
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.
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. */
21 /* Contributed by Steve Chamberlain <sac@cygnus.com>
23 A listing page looks like:
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
33 If not overridden, the listing commands are:
35 .title "stuff"
36 Put "stuff" onto the title line
37 .sbttl "stuff"
38 Put stuff onto the subtitle line
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
43 .eject
44 Throw a page
45 .list
46 Increment the enable listing counter
47 .nolist
48 Decrement the enable listing counter
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
54 If the counter goes below zero, listing is suppressed.
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.
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.
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.
72 The only things which the architecture can change about the listing
73 are defined in these macros:
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
81 LISTING_LHS_WIDTH Number of words of above size for the lhs
83 LISTING_LHS_WIDTH_SECOND Number of words for the data on the lhs
84 for the second line
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. */
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>
99 #ifndef NO_LISTING
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
121 /* This structure remembers which .s were used. */
122 typedef struct file_info_struct
124 struct file_info_struct * next;
125 char * filename;
126 long pos;
127 unsigned int linenum;
128 int at_end;
129 } file_info_type;
131 enum edict_enum
133 EDICT_NONE,
134 EDICT_SBTTL,
135 EDICT_TITLE,
136 EDICT_NOLIST,
137 EDICT_LIST,
138 EDICT_NOLIST_NEXT,
139 EDICT_EJECT
143 struct list_message
145 char *message;
146 struct list_message *next;
149 /* This structure remembers which line from which file goes into which
150 frag. */
151 struct list_info_struct
153 /* Frag which this line of source is nearest to. */
154 fragS *frag;
156 /* The actual line in the source file. */
157 unsigned int line;
159 /* Pointer to the file info struct for the file which this line
160 belongs to. */
161 file_info_type *file;
163 /* The expanded text of any macro that may have been executing. */
164 char *line_contents;
166 /* Next in list. */
167 struct list_info_struct *next;
169 /* Pointer to the file info struct for the high level language
170 source line that belongs here. */
171 file_info_type *hll_file;
173 /* High level language source line. */
174 unsigned int hll_line;
176 /* Pointers to linked list of messages associated with this line. */
177 struct list_message *messages, *last_message;
179 #ifdef OBJ_ELF
180 /* Nonzero if this line is to be omitted because it contains
181 debugging information. This can become a flags field if we come
182 up with more information to store here. */
183 bool debugging;
184 #endif
186 enum edict_enum edict;
187 char *edict_arg;
191 typedef struct list_info_struct list_info_type;
193 int listing_lhs_width = LISTING_LHS_WIDTH;
194 int listing_lhs_width_second = LISTING_LHS_WIDTH_SECOND;
195 int listing_lhs_cont_lines = LISTING_LHS_CONT_LINES;
196 int listing_rhs_width = LISTING_RHS_WIDTH;
198 struct list_info_struct * listing_tail;
200 static file_info_type * file_info_head;
201 static file_info_type * last_open_file_info;
202 static FILE * last_open_file;
203 static struct list_info_struct * head;
204 static int paper_width = 200;
205 static int paper_height = 60;
207 extern int listing;
209 /* File to output listings to. */
210 static FILE *list_file;
212 /* This static array is used to keep the text of data to be printed
213 before the start of the line. */
215 #define MAX_BYTES \
216 (((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width \
217 + ((((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second) \
218 * listing_lhs_cont_lines) \
219 + 20)
221 static char *data_buffer;
223 /* Prototypes. */
224 static void listing_message (const char *, const char *);
225 static file_info_type *file_info (const char *);
226 static void new_frag (void);
227 static void listing_page (list_info_type *);
228 static unsigned int calc_hex (list_info_type *);
229 static void print_lines (list_info_type *, unsigned int, const char *,
230 unsigned int);
231 static void list_symbol_table (void);
232 static void listing_listing (char *);
234 static void
235 listing_message (const char *name, const char *message)
237 if (listing_tail != (list_info_type *) NULL)
239 char *n = concat (name, message, (char *) NULL);
240 struct list_message *lm = XNEW (struct list_message);
241 lm->message = n;
242 lm->next = NULL;
244 if (listing_tail->last_message)
245 listing_tail->last_message->next = lm;
246 else
247 listing_tail->messages = lm;
248 listing_tail->last_message = lm;
252 void
253 listing_warning (const char *message)
255 listing_message (_("Warning: "), message);
258 void
259 listing_error (const char *message)
261 listing_message (_("Error: "), message);
264 static file_info_type *
265 file_info (const char *file_name)
267 /* Find an entry with this file name. */
268 file_info_type *p = file_info_head;
270 while (p != (file_info_type *) NULL)
272 if (filename_cmp (p->filename, file_name) == 0)
273 return p;
274 p = p->next;
277 /* Make new entry. */
278 p = XNEW (file_info_type);
279 p->next = file_info_head;
280 file_info_head = p;
281 p->filename = xstrdup (file_name);
282 p->pos = 0;
283 p->linenum = 0;
284 p->at_end = 0;
286 return p;
289 static void
290 new_frag (void)
292 frag_wane (frag_now);
293 frag_new (0);
296 void
297 listing_newline (char *ps)
299 const char *file;
300 unsigned int line;
301 static unsigned int last_line = 0xffff;
302 static const char *last_file = NULL;
303 list_info_type *new_i = NULL;
305 if (listing == 0)
306 return;
308 if (now_seg == absolute_section)
309 return;
311 #ifdef OBJ_ELF
312 /* In ELF, anything in a section beginning with .debug or .line is
313 considered to be debugging information. This includes the
314 statement which switches us into the debugging section, which we
315 can only set after we are already in the debugging section. */
316 if (IS_ELF
317 && (listing & LISTING_NODEBUG) != 0
318 && listing_tail != NULL
319 && ! listing_tail->debugging)
321 const char *segname;
323 segname = segment_name (now_seg);
324 if (startswith (segname, ".debug")
325 || startswith (segname, ".line"))
326 listing_tail->debugging = true;
328 #endif
330 /* PR 21977 - use the physical file name not the logical one unless high
331 level source files are being included in the listing. */
332 if (listing & LISTING_HLL)
333 file = as_where (&line);
334 else
335 file = as_where_physical (&line);
337 if (ps == NULL)
339 if (line == last_line
340 && !(last_file && file && filename_cmp (file, last_file)))
341 return;
343 new_i = XNEW (list_info_type);
345 /* Detect if we are reading from stdin by examining the file
346 name returned by as_where().
348 [FIXME: We rely upon the name in the strcmp below being the
349 same as the one used by input_scrub_new_file(), if that is
350 not true, then this code will fail].
352 If we are reading from stdin, then we need to save each input
353 line here (assuming of course that we actually have a line of
354 input to read), so that it can be displayed in the listing
355 that is produced at the end of the assembly. */
356 if (strcmp (file, _("{standard input}")) == 0
357 && input_line_pointer != NULL)
359 char *copy, *src, *dest;
360 int len;
361 int seen_quote = 0;
362 int seen_slash = 0;
364 for (copy = input_line_pointer;
365 *copy && (seen_quote
366 || is_end_of_line [(unsigned char) *copy] != 1);
367 copy++)
369 if (seen_slash)
370 seen_slash = 0;
371 else if (*copy == '\\')
372 seen_slash = 1;
373 else if (*copy == '"')
374 seen_quote = !seen_quote;
377 len = copy - input_line_pointer + 1;
379 copy = XNEWVEC (char, len);
381 src = input_line_pointer;
382 dest = copy;
384 while (--len)
386 unsigned char c = *src++;
388 /* Omit control characters in the listing. */
389 if (!ISCNTRL (c))
390 *dest++ = c;
393 *dest = 0;
395 new_i->line_contents = copy;
397 else
398 new_i->line_contents = NULL;
400 else
402 new_i = XNEW (list_info_type);
403 new_i->line_contents = ps;
406 last_line = line;
407 last_file = file;
409 new_frag ();
411 if (listing_tail)
412 listing_tail->next = new_i;
413 else
414 head = new_i;
416 listing_tail = new_i;
418 new_i->frag = frag_now;
419 new_i->line = line;
420 new_i->file = file_info (file);
421 new_i->next = (list_info_type *) NULL;
422 new_i->messages = NULL;
423 new_i->last_message = NULL;
424 new_i->edict = EDICT_NONE;
425 new_i->hll_file = (file_info_type *) NULL;
426 new_i->hll_line = 0;
428 new_frag ();
430 #ifdef OBJ_ELF
431 /* In ELF, anything in a section beginning with .debug or .line is
432 considered to be debugging information. */
433 new_i->debugging = false;
434 if ((listing & LISTING_NODEBUG) != 0)
436 const char *segname;
438 segname = segment_name (now_seg);
439 if (startswith (segname, ".debug")
440 || startswith (segname, ".line"))
441 new_i->debugging = true;
443 #endif
446 /* Attach all current frags to the previous line instead of the
447 current line. This is called by the MIPS backend when it discovers
448 that it needs to add some NOP instructions; the added NOP
449 instructions should go with the instruction that has the delay, not
450 with the new instruction. */
452 void
453 listing_prev_line (void)
455 list_info_type *l;
456 fragS *f;
458 if (head == (list_info_type *) NULL
459 || head == listing_tail)
460 return;
462 new_frag ();
464 for (l = head; l->next != listing_tail; l = l->next)
467 for (f = frchain_now->frch_root; f != (fragS *) NULL; f = f->fr_next)
468 if (f->line == listing_tail)
469 f->line = l;
471 listing_tail->frag = frag_now;
472 new_frag ();
475 /* This function returns the next source line from the file supplied,
476 truncated to size. It appends a fake line to the end of each input
477 file to make using the returned buffer simpler. */
479 static const char *
480 buffer_line (file_info_type *file, char *line, unsigned int size)
482 unsigned int count = 0;
483 int c;
484 char *p = line;
486 /* If we couldn't open the file, return an empty line. */
487 if (file->at_end)
488 return "";
490 /* Check the cache and see if we last used this file. */
491 if (!last_open_file_info || file != last_open_file_info)
493 if (last_open_file)
495 last_open_file_info->pos = ftell (last_open_file);
496 fclose (last_open_file);
499 /* Open the file in the binary mode so that ftell above can
500 return a reliable value that we can feed to fseek below. */
501 last_open_file_info = file;
502 last_open_file = fopen (file->filename, FOPEN_RB);
503 if (last_open_file == NULL)
505 file->at_end = 1;
506 return "";
509 /* Seek to where we were last time this file was open. */
510 if (file->pos)
511 fseek (last_open_file, file->pos, SEEK_SET);
514 c = fgetc (last_open_file);
516 while (c != EOF && c != '\n' && c != '\r')
518 if (++count < size)
519 *p++ = c;
520 c = fgetc (last_open_file);
523 /* If '\r' is followed by '\n', swallow that. Likewise, if '\n'
524 is followed by '\r', swallow that as well. */
525 if (c == '\r' || c == '\n')
527 int next = fgetc (last_open_file);
529 if ((c == '\r' && next != '\n')
530 || (c == '\n' && next != '\r'))
531 ungetc (next, last_open_file);
534 if (c == EOF)
536 file->at_end = 1;
537 if (count + 3 < size)
539 *p++ = '.';
540 *p++ = '.';
541 *p++ = '.';
544 file->linenum++;
545 *p++ = 0;
546 return line;
550 /* This function rewinds the requested file back to the line requested,
551 reads it in again into the buffer provided and then restores the file
552 back to its original location. */
554 static void
555 rebuffer_line (file_info_type * file,
556 unsigned int linenum,
557 char * buffer,
558 unsigned int size)
560 unsigned int count = 0;
561 unsigned int current_line;
562 char * p = buffer;
563 long pos;
564 long pos2;
565 int c;
566 bool found = false;
568 /* Sanity checks. */
569 if (file == NULL || buffer == NULL || size <= 1 || file->linenum <= linenum)
570 return;
572 /* Check the cache and see if we last used this file. */
573 if (last_open_file_info == NULL || file != last_open_file_info)
575 if (last_open_file)
577 last_open_file_info->pos = ftell (last_open_file);
578 fclose (last_open_file);
581 /* Open the file in the binary mode so that ftell above can
582 return a reliable value that we can feed to fseek below. */
583 last_open_file_info = file;
584 last_open_file = fopen (file->filename, FOPEN_RB);
585 if (last_open_file == NULL)
587 file->at_end = 1;
588 return;
591 /* Seek to where we were last time this file was open. */
592 if (file->pos)
593 fseek (last_open_file, file->pos, SEEK_SET);
596 /* Remember where we are in the current file. */
597 pos2 = pos = ftell (last_open_file);
598 if (pos < 3)
599 return;
600 current_line = file->linenum;
602 /* Leave room for the nul at the end of the buffer. */
603 size -= 1;
604 buffer[size] = 0;
606 /* Increment the current line count by one.
607 This is to allow for the fact that we are searching for the
608 start of a previous line, but we do this by detecting end-of-line
609 character(s) not start-of-line characters. */
610 ++ current_line;
612 while (pos2 > 0 && ! found)
614 char * ptr;
616 /* Move backwards through the file, looking for earlier lines. */
617 pos2 = (long) size > pos2 ? 0 : pos2 - size;
618 fseek (last_open_file, pos2, SEEK_SET);
620 /* Our caller has kindly provided us with a buffer, so we use it. */
621 if (fread (buffer, 1, size, last_open_file) != size)
623 as_warn (_("unable to rebuffer file: %s\n"), file->filename);
624 return;
627 for (ptr = buffer + size; ptr >= buffer; -- ptr)
629 if (*ptr == '\n')
631 -- current_line;
633 if (current_line == linenum)
635 /* We have found the start of the line we seek. */
636 found = true;
638 /* FIXME: We could skip the read-in-the-line code
639 below if we know that we already have the whole
640 line in the buffer. */
642 /* Advance pos2 to the newline character we have just located. */
643 pos2 += (ptr - buffer);
645 /* Skip the newline and, if present, the carriage return. */
646 if (ptr + 1 == buffer + size)
648 ++pos2;
649 if (fgetc (last_open_file) == '\r')
650 ++ pos2;
652 else
653 pos2 += (ptr[1] == '\r' ? 2 : 1);
655 /* Move the file pointer to this location. */
656 fseek (last_open_file, pos2, SEEK_SET);
657 break;
663 /* Read in the line. */
664 c = fgetc (last_open_file);
666 while (c != EOF && c != '\n' && c != '\r')
668 if (count < size)
669 *p++ = c;
670 count++;
672 c = fgetc (last_open_file);
675 /* If '\r' is followed by '\n', swallow that. Likewise, if '\n'
676 is followed by '\r', swallow that as well. */
677 if (c == '\r' || c == '\n')
679 int next = fgetc (last_open_file);
681 if ((c == '\r' && next != '\n')
682 || (c == '\n' && next != '\r'))
683 ungetc (next, last_open_file);
686 /* Terminate the line. */
687 *p++ = 0;
689 /* Reset the file position. */
690 fseek (last_open_file, pos, SEEK_SET);
693 static const char *fn;
694 static unsigned int eject; /* Eject pending. */
695 static unsigned int page; /* Current page number. */
696 static const char *title; /* Current title. */
697 static const char *subtitle; /* Current subtitle. */
698 static unsigned int on_page; /* Number of lines printed on current page. */
700 static void
701 listing_page (list_info_type *list)
703 /* Grope around, see if we can see a title or subtitle edict coming up
704 soon. (we look down 10 lines of the page and see if it's there) */
705 if ((eject || (on_page >= (unsigned int) paper_height))
706 && paper_height != 0)
708 unsigned int c = 10;
709 int had_title = 0;
710 int had_subtitle = 0;
712 page++;
714 while (c != 0 && list)
716 if (list->edict == EDICT_SBTTL && !had_subtitle)
718 had_subtitle = 1;
719 subtitle = list->edict_arg;
721 if (list->edict == EDICT_TITLE && !had_title)
723 had_title = 1;
724 title = list->edict_arg;
726 list = list->next;
727 c--;
730 if (page > 1)
732 fprintf (list_file, "\f");
735 fprintf (list_file, "%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
736 fprintf (list_file, "%s\n", title);
737 fprintf (list_file, "%s\n", subtitle);
738 on_page = 3;
739 eject = 0;
743 /* Print a line into the list_file. Update the line count
744 and if necessary start a new page. */
746 static void
747 emit_line (list_info_type * list, const char * format, ...)
749 va_list args;
751 va_start (args, format);
753 vfprintf (list_file, format, args);
754 on_page++;
755 listing_page (list);
757 va_end (args);
760 static unsigned int
761 calc_hex (list_info_type *list)
763 int data_buffer_size;
764 list_info_type *first = list;
765 unsigned int address = ~(unsigned int) 0;
766 fragS *frag;
767 fragS *frag_ptr;
768 unsigned int octet_in_frag;
770 /* Find first frag which says it belongs to this line. */
771 frag = list->frag;
772 while (frag && frag->line != list)
773 frag = frag->fr_next;
775 frag_ptr = frag;
777 data_buffer_size = 0;
779 /* Dump all the frags which belong to this line. */
780 while (frag_ptr != (fragS *) NULL && frag_ptr->line == first)
782 /* Print as many bytes from the fixed part as is sensible. */
783 octet_in_frag = 0;
784 while (octet_in_frag < frag_ptr->fr_fix
785 && data_buffer_size < MAX_BYTES - 3)
787 if (address == ~(unsigned int) 0)
788 address = frag_ptr->fr_address / OCTETS_PER_BYTE;
790 sprintf (data_buffer + data_buffer_size,
791 "%02X",
792 (frag_ptr->fr_literal[octet_in_frag]) & 0xff);
793 data_buffer_size += 2;
794 octet_in_frag++;
796 if (frag_ptr->fr_type == rs_fill)
798 unsigned int var_rep_max = octet_in_frag;
799 unsigned int var_rep_idx = octet_in_frag;
801 /* Print as many bytes from the variable part as is sensible. */
802 while ((octet_in_frag
803 < frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset)
804 && data_buffer_size < MAX_BYTES - 3)
806 if (address == ~(unsigned int) 0)
807 address = frag_ptr->fr_address / OCTETS_PER_BYTE;
809 sprintf (data_buffer + data_buffer_size,
810 "%02X",
811 (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
812 data_buffer_size += 2;
814 var_rep_idx++;
815 octet_in_frag++;
817 if (var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var)
818 var_rep_idx = var_rep_max;
821 else if (frag_ptr->fr_type == rs_fill_nop && frag_ptr->fr_opcode)
823 gas_assert (!octet_in_frag);
825 /* Print as many bytes from fr_opcode as is sensible. */
826 while (octet_in_frag < (unsigned int) frag_ptr->fr_offset
827 && data_buffer_size < MAX_BYTES - 3)
829 if (address == ~(unsigned int) 0)
830 address = frag_ptr->fr_address / OCTETS_PER_BYTE;
832 sprintf (data_buffer + data_buffer_size,
833 "%02X",
834 frag_ptr->fr_opcode[octet_in_frag] & 0xff);
835 data_buffer_size += 2;
837 octet_in_frag++;
840 free (frag_ptr->fr_opcode);
841 frag_ptr->fr_opcode = NULL;
844 frag_ptr = frag_ptr->fr_next;
846 data_buffer[data_buffer_size] = '\0';
847 return address;
850 static void
851 print_lines (list_info_type *list, unsigned int lineno,
852 const char *string, unsigned int address)
854 unsigned int idx;
855 unsigned int nchars;
856 unsigned int lines;
857 unsigned int octet_in_word = 0;
858 char *src = data_buffer;
859 int cur;
860 struct list_message *msg;
862 /* Print the stuff on the first line. */
863 listing_page (list);
864 nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width;
866 /* Print the hex for the first line. */
867 if (address == ~(unsigned int) 0)
869 fprintf (list_file, "% 4d ", lineno);
870 for (idx = 0; idx < nchars; idx++)
871 fprintf (list_file, " ");
873 emit_line (NULL, "\t%s\n", string ? string : "");
874 return;
877 if (had_errors ())
878 fprintf (list_file, "% 4d ???? ", lineno);
879 else
880 fprintf (list_file, "% 4d %04x ", lineno, address);
882 /* And the data to go along with it. */
883 idx = 0;
884 cur = 0;
885 while (src[cur] && idx < nchars)
887 int offset;
888 offset = cur;
889 fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
890 cur += 2;
891 octet_in_word++;
893 if (octet_in_word == LISTING_WORD_SIZE)
895 fprintf (list_file, " ");
896 idx++;
897 octet_in_word = 0;
900 idx += 2;
903 for (; idx < nchars; idx++)
904 fprintf (list_file, " ");
906 emit_line (list, "\t%s\n", string ? string : "");
908 for (msg = list->messages; msg; msg = msg->next)
909 emit_line (list, "**** %s\n", msg->message);
911 for (lines = 0;
912 lines < (unsigned int) listing_lhs_cont_lines
913 && src[cur];
914 lines++)
916 nchars = ((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second - 1;
917 idx = 0;
919 /* Print any more lines of data, but more compactly. */
920 fprintf (list_file, "% 4d ", lineno);
922 while (src[cur] && idx < nchars)
924 int offset;
925 offset = cur;
926 fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
927 cur += 2;
928 idx += 2;
929 octet_in_word++;
931 if (octet_in_word == LISTING_WORD_SIZE)
933 fprintf (list_file, " ");
934 idx++;
935 octet_in_word = 0;
939 emit_line (list, "\n");
943 static void
944 list_symbol_table (void)
946 extern symbolS *symbol_rootP;
947 int got_some = 0;
949 symbolS *ptr;
950 eject = 1;
951 listing_page (NULL);
953 for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
955 if (SEG_NORMAL (S_GET_SEGMENT (ptr))
956 || S_GET_SEGMENT (ptr) == absolute_section)
958 /* Don't report section symbols. They are not interesting. */
959 if (symbol_section_p (ptr))
960 continue;
962 if (S_GET_NAME (ptr))
964 char buf[30];
965 valueT val = S_GET_VALUE (ptr);
967 bfd_sprintf_vma (stdoutput, buf, val);
968 if (!got_some)
970 fprintf (list_file, "DEFINED SYMBOLS\n");
971 on_page++;
972 got_some = 1;
975 if (symbol_get_frag (ptr) && symbol_get_frag (ptr)->line)
977 fprintf (list_file, "%20s:%-5d %s:%s %s\n",
978 symbol_get_frag (ptr)->line->file->filename,
979 symbol_get_frag (ptr)->line->line,
980 segment_name (S_GET_SEGMENT (ptr)),
981 buf, S_GET_NAME (ptr));
983 else
985 fprintf (list_file, "%33s:%s %s\n",
986 segment_name (S_GET_SEGMENT (ptr)),
987 buf, S_GET_NAME (ptr));
990 on_page++;
991 listing_page (NULL);
996 if (!got_some)
998 fprintf (list_file, "NO DEFINED SYMBOLS\n");
999 on_page++;
1001 emit_line (NULL, "\n");
1003 got_some = 0;
1005 for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
1007 if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0)
1009 if (S_GET_SEGMENT (ptr) == undefined_section)
1011 if (!got_some)
1013 got_some = 1;
1015 emit_line (NULL, "UNDEFINED SYMBOLS\n");
1018 emit_line (NULL, "%s\n", S_GET_NAME (ptr));
1023 if (!got_some)
1024 emit_line (NULL, "NO UNDEFINED SYMBOLS\n");
1027 typedef struct cached_line
1029 file_info_type *file;
1030 unsigned int line;
1031 unsigned int bufsize;
1032 char *buffer;
1033 } cached_line;
1035 static void
1036 alloc_cache (cached_line *cache, unsigned int width)
1038 if (cache->bufsize < width)
1040 cache->bufsize = width;
1041 free (cache->buffer);
1042 cache->buffer = xmalloc (width);
1044 cache->buffer[0] = 0;
1047 static void
1048 print_source (file_info_type * current_file,
1049 list_info_type * list,
1050 unsigned int width)
1052 #define NUM_CACHE_LINES 3
1053 static cached_line cached_lines[NUM_CACHE_LINES];
1054 static int next_free_line = 0;
1055 cached_line * cache = NULL;
1057 if (current_file->linenum > list->hll_line
1058 && list->hll_line > 0)
1060 /* This can happen with modern optimizing compilers. The source
1061 lines from the high level language input program are split up
1062 and interleaved, meaning the line number we want to display
1063 (list->hll_line) can have already been displayed. We have
1064 three choices:
1066 a. Do nothing, since we have already displayed the source
1067 line. This was the old behaviour.
1069 b. Display the particular line requested again, but only
1070 that line. This is the new behaviour.
1072 c. Display the particular line requested again and reset
1073 the current_file->line_num value so that we redisplay
1074 all the following lines as well the next time we
1075 encounter a larger line number. */
1076 int i;
1078 /* Check the cache, maybe we already have the line saved. */
1079 for (i = 0; i < NUM_CACHE_LINES; i++)
1080 if (cached_lines[i].file == current_file
1081 && cached_lines[i].line == list->hll_line)
1083 cache = cached_lines + i;
1084 break;
1087 if (i == NUM_CACHE_LINES)
1089 cache = cached_lines + next_free_line;
1090 next_free_line ++;
1091 if (next_free_line == NUM_CACHE_LINES)
1092 next_free_line = 0;
1094 cache->file = current_file;
1095 cache->line = list->hll_line;
1096 alloc_cache (cache, width);
1097 rebuffer_line (current_file, cache->line, cache->buffer, width);
1100 emit_line (list, "%4u:%-13s **** %s\n",
1101 cache->line, cache->file->filename, cache->buffer);
1102 return;
1105 if (!current_file->at_end)
1107 int num_lines_shown = 0;
1109 while (current_file->linenum < list->hll_line
1110 && !current_file->at_end)
1112 const char *p;
1114 cache = cached_lines + next_free_line;
1115 cache->file = current_file;
1116 cache->line = current_file->linenum + 1;
1117 alloc_cache (cache, width);
1118 p = buffer_line (current_file, cache->buffer, width);
1120 /* Cache optimization: If printing a group of lines
1121 cache the first and last lines in the group. */
1122 if (num_lines_shown == 0)
1124 next_free_line ++;
1125 if (next_free_line == NUM_CACHE_LINES)
1126 next_free_line = 0;
1129 emit_line (list, "%4u:%-13s **** %s\n",
1130 cache->line, cache->file->filename, p);
1131 num_lines_shown ++;
1136 /* Sometimes the user doesn't want to be bothered by the debugging
1137 records inserted by the compiler, see if the line is suspicious. */
1139 static bool
1140 debugging_pseudo (list_info_type *list ATTRIBUTE_UNUSED, const char *line)
1142 #ifdef OBJ_ELF
1143 static bool in_debug;
1144 bool was_debug;
1146 if (list->debugging)
1148 in_debug = true;
1149 return true;
1151 was_debug = in_debug;
1152 in_debug = false;
1153 #endif
1155 while (ISSPACE (*line))
1156 line++;
1158 if (*line != '.')
1160 #ifdef OBJ_ELF
1161 /* The ELF compiler sometimes emits blank lines after switching
1162 out of a debugging section. If the next line drops us back
1163 into debugging information, then don't print the blank line.
1164 This is a hack for a particular compiler behaviour, not a
1165 general case. */
1166 if (was_debug
1167 && *line == '\0'
1168 && list->next != NULL
1169 && list->next->debugging)
1171 in_debug = true;
1172 return true;
1174 #endif
1176 return false;
1179 line++;
1181 if (startswith (line, "def"))
1182 return true;
1183 if (startswith (line, "val"))
1184 return true;
1185 if (startswith (line, "scl"))
1186 return true;
1187 if (startswith (line, "line"))
1188 return true;
1189 if (startswith (line, "endef"))
1190 return true;
1191 if (startswith (line, "ln"))
1192 return true;
1193 if (startswith (line, "type"))
1194 return true;
1195 if (startswith (line, "size"))
1196 return true;
1197 if (startswith (line, "dim"))
1198 return true;
1199 if (startswith (line, "tag"))
1200 return true;
1201 if (startswith (line, "stabs"))
1202 return true;
1203 if (startswith (line, "stabn"))
1204 return true;
1206 return false;
1209 static void
1210 listing_listing (char *name ATTRIBUTE_UNUSED)
1212 list_info_type *list = head;
1213 file_info_type *current_hll_file = (file_info_type *) NULL;
1214 char *buffer;
1215 const char *p;
1216 int show_listing = 1;
1217 unsigned int width;
1219 buffer = XNEWVEC (char, listing_rhs_width);
1220 data_buffer = XNEWVEC (char, MAX_BYTES);
1221 eject = 1;
1222 list = head->next;
1224 while (list)
1226 unsigned int list_line;
1228 width = listing_rhs_width > paper_width ? paper_width :
1229 listing_rhs_width;
1231 list_line = list->line;
1232 switch (list->edict)
1234 case EDICT_LIST:
1235 /* Skip all lines up to the current. */
1236 list_line--;
1237 break;
1238 case EDICT_NOLIST:
1239 show_listing--;
1240 break;
1241 case EDICT_NOLIST_NEXT:
1242 if (show_listing == 0)
1243 list_line--;
1244 break;
1245 case EDICT_EJECT:
1246 break;
1247 case EDICT_NONE:
1248 break;
1249 case EDICT_TITLE:
1250 title = list->edict_arg;
1251 break;
1252 case EDICT_SBTTL:
1253 subtitle = list->edict_arg;
1254 break;
1255 default:
1256 abort ();
1259 if (show_listing <= 0)
1261 while (list->file->linenum < list_line
1262 && !list->file->at_end)
1263 p = buffer_line (list->file, buffer, width);
1266 if (list->edict == EDICT_LIST
1267 || (list->edict == EDICT_NOLIST_NEXT && show_listing == 0))
1269 /* Enable listing for the single line that caused the enable. */
1270 list_line++;
1271 show_listing++;
1274 if (show_listing > 0)
1276 /* Scan down the list and print all the stuff which can be done
1277 with this line (or lines). */
1278 if (list->hll_file)
1279 current_hll_file = list->hll_file;
1281 if (current_hll_file && list->hll_line && (listing & LISTING_HLL))
1282 print_source (current_hll_file, list, width);
1284 if (!list->line_contents || list->file->linenum)
1286 while (list->file->linenum < list_line
1287 && !list->file->at_end)
1289 unsigned int address;
1291 p = buffer_line (list->file, buffer, width);
1293 if (list->file->linenum < list_line)
1294 address = ~(unsigned int) 0;
1295 else
1296 address = calc_hex (list);
1298 if (!((listing & LISTING_NODEBUG)
1299 && debugging_pseudo (list, p)))
1300 print_lines (list, list->file->linenum, p, address);
1304 if (list->line_contents)
1306 if (!((listing & LISTING_NODEBUG)
1307 && debugging_pseudo (list, list->line_contents)))
1308 print_lines (list, list->line, list->line_contents,
1309 calc_hex (list));
1311 free (list->line_contents);
1312 list->line_contents = NULL;
1315 if (list->edict == EDICT_EJECT)
1316 eject = 1;
1319 if (list->edict == EDICT_NOLIST_NEXT && show_listing == 1)
1320 --show_listing;
1322 list = list->next;
1325 free (buffer);
1326 free (data_buffer);
1327 data_buffer = NULL;
1330 /* Print time stamp in ISO format: yyyy-mm-ddThh:mm:ss.ss+/-zzzz. */
1332 static void
1333 print_timestamp (void)
1335 const time_t now = time (NULL);
1336 struct tm * timestamp;
1337 char stampstr[MAX_DATELEN];
1339 /* Any portable way to obtain subsecond values??? */
1340 timestamp = localtime (&now);
1341 strftime (stampstr, MAX_DATELEN, "%Y-%m-%dT%H:%M:%S.000%z", timestamp);
1342 fprintf (list_file, _("\n time stamp \t: %s\n\n"), stampstr);
1345 static void
1346 print_single_option (char * opt, int *pos)
1348 int opt_len = strlen (opt);
1350 if ((*pos + opt_len) < paper_width)
1352 fprintf (list_file, _("%s "), opt);
1353 *pos = *pos + opt_len;
1355 else
1357 fprintf (list_file, _("\n\t%s "), opt);
1358 *pos = opt_len;
1362 /* Print options passed to as. */
1364 static void
1365 print_options (char ** argv)
1367 const char *field_name = _("\n options passed\t: ");
1368 int pos = strlen (field_name);
1369 char **p;
1371 fputs (field_name, list_file);
1372 for (p = &argv[1]; *p != NULL; p++)
1373 if (**p == '-')
1375 /* Ignore these. */
1376 if (strcmp (*p, "-o") == 0)
1378 if (p[1] != NULL)
1379 p++;
1380 continue;
1382 if (strcmp (*p, "-v") == 0)
1383 continue;
1385 print_single_option (*p, &pos);
1389 /* Print a first section with basic info like file names, as version,
1390 options passed, target, and timestamp.
1391 The format of this section is as follows:
1393 AS VERSION
1395 fieldname TAB ':' fieldcontents
1396 { TAB fieldcontents-cont } */
1398 static void
1399 listing_general_info (char ** argv)
1401 /* Print the stuff on the first line. */
1402 eject = 1;
1403 listing_page (NULL);
1405 fprintf (list_file,
1406 _(" GNU assembler version %s (%s)\n\t using BFD version %s."),
1407 VERSION, TARGET_ALIAS, BFD_VERSION_STRING);
1408 print_options (argv);
1409 fprintf (list_file, _("\n input file \t: %s"), fn);
1410 fprintf (list_file, _("\n output file \t: %s"), out_file_name);
1411 fprintf (list_file, _("\n target \t: %s"), TARGET_CANONICAL);
1412 print_timestamp ();
1415 void
1416 listing_print (char *name, char **argv)
1418 int using_stdout;
1420 title = "";
1421 subtitle = "";
1423 if (name == NULL)
1425 list_file = stdout;
1426 using_stdout = 1;
1428 else
1430 list_file = fopen (name, FOPEN_WT);
1431 if (list_file != NULL)
1432 using_stdout = 0;
1433 else
1435 as_warn (_("can't open %s: %s"), name, xstrerror (errno));
1436 list_file = stdout;
1437 using_stdout = 1;
1441 if (listing & LISTING_NOFORM)
1442 paper_height = 0;
1444 if (listing & LISTING_GENERAL)
1445 listing_general_info (argv);
1447 if (listing & LISTING_LISTING)
1448 listing_listing (name);
1450 if (listing & LISTING_SYMBOLS)
1451 list_symbol_table ();
1453 if (! using_stdout)
1455 if (fclose (list_file) == EOF)
1456 as_warn (_("can't close %s: %s"), name, xstrerror (errno));
1459 if (last_open_file)
1460 fclose (last_open_file);
1463 void
1464 listing_file (const char *name)
1466 fn = name;
1469 void
1470 listing_eject (int ignore ATTRIBUTE_UNUSED)
1472 if (listing)
1473 listing_tail->edict = EDICT_EJECT;
1476 /* Turn listing on or off. An argument of 0 means to turn off
1477 listing. An argument of 1 means to turn on listing. An argument
1478 of 2 means to turn off listing, but as of the next line; that is,
1479 the current line should be listed, but the next line should not. */
1481 void
1482 listing_list (int on)
1484 if (listing)
1486 switch (on)
1488 case 0:
1489 if (listing_tail->edict == EDICT_LIST)
1490 listing_tail->edict = EDICT_NONE;
1491 else
1492 listing_tail->edict = EDICT_NOLIST;
1493 break;
1494 case 1:
1495 if (listing_tail->edict == EDICT_NOLIST
1496 || listing_tail->edict == EDICT_NOLIST_NEXT)
1497 listing_tail->edict = EDICT_NONE;
1498 else
1499 listing_tail->edict = EDICT_LIST;
1500 break;
1501 case 2:
1502 listing_tail->edict = EDICT_NOLIST_NEXT;
1503 break;
1504 default:
1505 abort ();
1510 void
1511 listing_psize (int width_only)
1513 if (! width_only)
1515 paper_height = get_absolute_expression ();
1517 if (paper_height < 0 || paper_height > 1000)
1519 paper_height = 0;
1520 as_warn (_("strange paper height, set to no form"));
1523 if (*input_line_pointer != ',')
1525 demand_empty_rest_of_line ();
1526 return;
1529 ++input_line_pointer;
1533 expressionS exp;
1535 (void) expression_and_evaluate (& exp);
1537 if (exp.X_op == O_constant)
1539 offsetT new_width = exp.X_add_number;
1541 if (new_width > 7)
1542 paper_width = new_width;
1543 else
1544 as_bad (_("new paper width is too small"));
1546 else if (exp.X_op != O_absent)
1547 as_bad (_("bad or irreducible expression for paper width"));
1548 else
1549 as_bad (_("missing expression for paper width"));
1552 demand_empty_rest_of_line ();
1555 void
1556 listing_nopage (int ignore ATTRIBUTE_UNUSED)
1558 paper_height = 0;
1561 void
1562 listing_title (int depth)
1564 int quoted;
1565 char *start;
1566 char *ttl;
1567 unsigned int length;
1569 SKIP_WHITESPACE ();
1570 if (*input_line_pointer != '\"')
1571 quoted = 0;
1572 else
1574 quoted = 1;
1575 ++input_line_pointer;
1578 start = input_line_pointer;
1580 while (*input_line_pointer)
1582 if (quoted
1583 ? *input_line_pointer == '\"'
1584 : is_end_of_line[(unsigned char) *input_line_pointer])
1586 if (listing)
1588 length = input_line_pointer - start;
1589 ttl = xmemdup0 (start, length);
1590 listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
1591 listing_tail->edict_arg = ttl;
1593 if (quoted)
1594 input_line_pointer++;
1595 demand_empty_rest_of_line ();
1596 return;
1598 else if (*input_line_pointer == '\n')
1600 as_bad (_("new line in title"));
1601 demand_empty_rest_of_line ();
1602 return;
1604 else
1606 input_line_pointer++;
1611 void
1612 listing_source_line (unsigned int line)
1614 if (listing)
1616 new_frag ();
1617 listing_tail->hll_line = line;
1618 new_frag ();
1622 void
1623 listing_source_file (const char *file)
1625 if (listing)
1626 listing_tail->hll_file = file_info (file);
1629 #else
1631 /* Dummy functions for when compiled without listing enabled. */
1633 void
1634 listing_list (int on)
1636 s_ignore (0);
1639 void
1640 listing_eject (int ignore)
1642 s_ignore (0);
1645 void
1646 listing_psize (int ignore)
1648 s_ignore (0);
1651 void
1652 listing_nopage (int ignore)
1654 s_ignore (0);
1657 void
1658 listing_title (int depth)
1660 s_ignore (0);
1663 void
1664 listing_file (const char *name)
1668 void
1669 listing_newline (char *name)
1673 void
1674 listing_source_line (unsigned int n)
1678 void
1679 listing_source_file (const char *n)
1683 #endif