include/coff/
[binutils.git] / gas / listing.c
blob025a2ca67424fa39dedf88e9b7e195ee571d7eba
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
4 Free Software Foundation, Inc.
6 This file is part of GAS, the GNU Assembler.
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.
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.
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. */
23 /* Contributed by Steve Chamberlain <sac@cygnus.com>
25 A listing page looks like:
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
35 If not overridden, the listing commands are:
37 .title "stuff"
38 Put "stuff" onto the title line
39 .sbttl "stuff"
40 Put stuff onto the subtitle line
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
45 .eject
46 Thow a page
47 .list
48 Increment the enable listing counter
49 .nolist
50 Decrement the enable listing counter
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
56 If the counter goes below zero, listing is suppressed.
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.
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.
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.
74 The only things which the architecture can change about the listing
75 are defined in these macros:
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
83 LISTING_LHS_WIDTH Number of words of above size for the lhs
85 LISTING_LHS_WIDTH_SECOND Number of words for the data on the lhs
86 for the second line
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. */
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>
100 #ifndef NO_LISTING
102 #ifndef LISTING_HEADER
103 #define LISTING_HEADER "GAS LISTING"
104 #endif
105 #ifndef LISTING_WORD_SIZE
106 #define LISTING_WORD_SIZE 4
107 #endif
108 #ifndef LISTING_LHS_WIDTH
109 #define LISTING_LHS_WIDTH ((LISTING_WORD_SIZE) > 4 ? 1 : 4 / (LISTING_WORD_SIZE))
110 #endif
111 #ifndef LISTING_LHS_WIDTH_SECOND
112 #define LISTING_LHS_WIDTH_SECOND LISTING_LHS_WIDTH
113 #endif
114 #ifndef LISTING_RHS_WIDTH
115 #define LISTING_RHS_WIDTH 100
116 #endif
117 #ifndef LISTING_LHS_CONT_LINES
118 #define LISTING_LHS_CONT_LINES 4
119 #endif
120 #define MAX_DATELEN 30
122 /* This structure remembers which .s were used. */
123 typedef struct file_info_struct
125 struct file_info_struct * next;
126 char * filename;
127 long pos;
128 unsigned int linenum;
129 int at_end;
130 } file_info_type;
132 /* This structure remembers which line from which file goes into which
133 frag. */
134 struct list_info_struct
136 /* Frag which this line of source is nearest to. */
137 fragS *frag;
139 /* The actual line in the source file. */
140 unsigned int line;
142 /* Pointer to the file info struct for the file which this line
143 belongs to. */
144 file_info_type *file;
146 /* The expanded text of any macro that may have been executing. */
147 char *line_contents;
149 /* Next in list. */
150 struct list_info_struct *next;
152 /* Pointer to the file info struct for the high level language
153 source line that belongs here. */
154 file_info_type *hll_file;
156 /* High level language source line. */
157 unsigned int hll_line;
159 /* Pointer to any error message associated with this line. */
160 char *message;
162 enum
164 EDICT_NONE,
165 EDICT_SBTTL,
166 EDICT_TITLE,
167 EDICT_NOLIST,
168 EDICT_LIST,
169 EDICT_NOLIST_NEXT,
170 EDICT_EJECT
171 } edict;
172 char *edict_arg;
174 /* Nonzero if this line is to be omitted because it contains
175 debugging information. This can become a flags field if we come
176 up with more information to store here. */
177 int debugging;
180 typedef struct list_info_struct list_info_type;
182 int listing_lhs_width = LISTING_LHS_WIDTH;
183 int listing_lhs_width_second = LISTING_LHS_WIDTH_SECOND;
184 int listing_lhs_cont_lines = LISTING_LHS_CONT_LINES;
185 int listing_rhs_width = LISTING_RHS_WIDTH;
187 struct list_info_struct * listing_tail;
189 static file_info_type * file_info_head;
190 static file_info_type * last_open_file_info;
191 static FILE * last_open_file;
192 static struct list_info_struct * head;
193 static int paper_width = 200;
194 static int paper_height = 60;
196 extern int listing;
198 /* File to output listings to. */
199 static FILE *list_file;
201 /* This static array is used to keep the text of data to be printed
202 before the start of the line. */
204 #define MAX_BYTES \
205 (((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width \
206 + ((((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second) \
207 * listing_lhs_cont_lines) \
208 + 20)
210 static char *data_buffer;
212 /* Prototypes. */
213 static void listing_message (const char *, const char *);
214 static file_info_type *file_info (const char *);
215 static void new_frag (void);
216 static char *buffer_line (file_info_type *, char *, unsigned int);
217 static void listing_page (list_info_type *);
218 static unsigned int calc_hex (list_info_type *);
219 static void print_lines (list_info_type *, unsigned int, char *, unsigned int);
220 static void list_symbol_table (void);
221 static void print_source (file_info_type *, list_info_type *, char *, unsigned int);
222 static int debugging_pseudo (list_info_type *, const char *);
223 static void listing_listing (char *);
225 static void
226 listing_message (const char *name, const char *message)
228 if (listing_tail != (list_info_type *) NULL)
230 unsigned int l = strlen (name) + strlen (message) + 1;
231 char *n = (char *) xmalloc (l);
232 strcpy (n, name);
233 strcat (n, message);
234 listing_tail->message = n;
238 void
239 listing_warning (const char *message)
241 listing_message (_("Warning:"), message);
244 void
245 listing_error (const char *message)
247 listing_message (_("Error:"), message);
250 static file_info_type *
251 file_info (const char *file_name)
253 /* Find an entry with this file name. */
254 file_info_type *p = file_info_head;
256 while (p != (file_info_type *) NULL)
258 if (strcmp (p->filename, file_name) == 0)
259 return p;
260 p = p->next;
263 /* Make new entry. */
264 p = xmalloc (sizeof (file_info_type));
265 p->next = file_info_head;
266 file_info_head = p;
267 p->filename = xstrdup (file_name);
268 p->pos = 0;
269 p->linenum = 0;
270 p->at_end = 0;
272 return p;
275 static void
276 new_frag (void)
278 frag_wane (frag_now);
279 frag_new (0);
282 void
283 listing_newline (char *ps)
285 char *file;
286 unsigned int line;
287 static unsigned int last_line = 0xffff;
288 static char *last_file = NULL;
289 list_info_type *new = NULL;
291 if (listing == 0)
292 return;
294 if (now_seg == absolute_section)
295 return;
297 #ifdef OBJ_ELF
298 /* In ELF, anything in a section beginning with .debug or .line is
299 considered to be debugging information. This includes the
300 statement which switches us into the debugging section, which we
301 can only set after we are already in the debugging section. */
302 if ((listing & LISTING_NODEBUG) != 0
303 && listing_tail != NULL
304 && ! listing_tail->debugging)
306 const char *segname;
308 segname = segment_name (now_seg);
309 if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
310 || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
311 listing_tail->debugging = 1;
313 #endif
315 as_where (&file, &line);
316 if (ps == NULL)
318 if (line == last_line
319 && !(last_file && file && strcmp (file, last_file)))
320 return;
322 new = (list_info_type *) xmalloc (sizeof (list_info_type));
324 /* Detect if we are reading from stdin by examining the file
325 name returned by as_where().
327 [FIXME: We rely upon the name in the strcmp below being the
328 same as the one used by input_scrub_new_file(), if that is
329 not true, then this code will fail].
331 If we are reading from stdin, then we need to save each input
332 line here (assuming of course that we actually have a line of
333 input to read), so that it can be displayed in the listing
334 that is produced at the end of the assembly. */
335 if (strcmp (file, _("{standard input}")) == 0
336 && input_line_pointer != NULL)
338 char *copy;
339 int len;
340 int seen_quote = 0;
342 for (copy = input_line_pointer - 1;
343 *copy && (seen_quote
344 || (! is_end_of_line [(unsigned char) *copy]));
345 copy++)
346 if (*copy == '"' && copy[-1] != '\\')
347 seen_quote = ! seen_quote;
349 len = (copy - input_line_pointer) + 2;
351 copy = xmalloc (len);
353 if (copy != NULL)
355 char *src = input_line_pointer - 1;
356 char *dest = copy;
358 while (--len)
360 unsigned char c = *src++;
362 /* Omit control characters in the listing. */
363 if (!ISCNTRL (c))
364 *dest++ = c;
367 *dest = 0;
370 new->line_contents = copy;
372 else
373 new->line_contents = NULL;
375 else
377 new = xmalloc (sizeof (list_info_type));
378 new->line_contents = ps;
381 last_line = line;
382 last_file = file;
384 new_frag ();
386 if (listing_tail)
387 listing_tail->next = new;
388 else
389 head = new;
391 listing_tail = new;
393 new->frag = frag_now;
394 new->line = line;
395 new->file = file_info (file);
396 new->next = (list_info_type *) NULL;
397 new->message = (char *) NULL;
398 new->edict = EDICT_NONE;
399 new->hll_file = (file_info_type *) NULL;
400 new->hll_line = 0;
401 new->debugging = 0;
403 new_frag ();
405 #ifdef OBJ_ELF
406 /* In ELF, anything in a section beginning with .debug or .line is
407 considered to be debugging information. */
408 if ((listing & LISTING_NODEBUG) != 0)
410 const char *segname;
412 segname = segment_name (now_seg);
413 if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
414 || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
415 new->debugging = 1;
417 #endif
420 /* Attach all current frags to the previous line instead of the
421 current line. This is called by the MIPS backend when it discovers
422 that it needs to add some NOP instructions; the added NOP
423 instructions should go with the instruction that has the delay, not
424 with the new instruction. */
426 void
427 listing_prev_line (void)
429 list_info_type *l;
430 fragS *f;
432 if (head == (list_info_type *) NULL
433 || head == listing_tail)
434 return;
436 new_frag ();
438 for (l = head; l->next != listing_tail; l = l->next)
441 for (f = frchain_now->frch_root; f != (fragS *) NULL; f = f->fr_next)
442 if (f->line == listing_tail)
443 f->line = l;
445 listing_tail->frag = frag_now;
446 new_frag ();
449 /* This function returns the next source line from the file supplied,
450 truncated to size. It appends a fake line to the end of each input
451 file to make. */
453 static char *
454 buffer_line (file_info_type *file, char *line, unsigned int size)
456 unsigned int count = 0;
457 int c;
459 char *p = line;
461 /* If we couldn't open the file, return an empty line. */
462 if (file->at_end)
463 return "";
465 /* Check the cache and see if we last used this file. */
466 if (!last_open_file_info || file != last_open_file_info)
468 if (last_open_file)
470 last_open_file_info->pos = ftell (last_open_file);
471 fclose (last_open_file);
474 /* Open the file in the binary mode so that ftell above can
475 return a reliable value that we can feed to fseek below. */
476 last_open_file_info = file;
477 last_open_file = fopen (file->filename, FOPEN_RB);
478 if (last_open_file == NULL)
480 file->at_end = 1;
481 return "";
484 /* Seek to where we were last time this file was open. */
485 if (file->pos)
486 fseek (last_open_file, file->pos, SEEK_SET);
489 c = fgetc (last_open_file);
491 /* Leave room for null. */
492 size -= 1;
494 while (c != EOF && c != '\n' && c != '\r')
496 if (count < size)
497 *p++ = c;
498 count++;
500 c = fgetc (last_open_file);
504 /* If '\r' is followed by '\n', swallow that. Likewise, if '\n'
505 is followed by '\r', swallow that as well. */
506 if (c == '\r' || c == '\n')
508 int next = fgetc (last_open_file);
509 if ((c == '\r' && next != '\n')
510 || (c == '\n' && next != '\r'))
511 ungetc (next, last_open_file);
514 if (c == EOF)
516 file->at_end = 1;
517 if (count + 2 < size)
519 *p++ = '.';
520 *p++ = '.';
521 *p++ = '.';
524 file->linenum++;
525 *p++ = 0;
526 return line;
529 static const char *fn;
531 static unsigned int eject; /* Eject pending */
532 static unsigned int page; /* Current page number */
533 static char *title; /* Current title */
534 static char *subtitle; /* Current subtitle */
535 static unsigned int on_page; /* Number of lines printed on current page */
537 static void
538 listing_page (list_info_type *list)
540 /* Grope around, see if we can see a title or subtitle edict coming up
541 soon. (we look down 10 lines of the page and see if it's there) */
542 if ((eject || (on_page >= (unsigned int) paper_height))
543 && paper_height != 0)
545 unsigned int c = 10;
546 int had_title = 0;
547 int had_subtitle = 0;
549 page++;
551 while (c != 0 && list)
553 if (list->edict == EDICT_SBTTL && !had_subtitle)
555 had_subtitle = 1;
556 subtitle = list->edict_arg;
558 if (list->edict == EDICT_TITLE && !had_title)
560 had_title = 1;
561 title = list->edict_arg;
563 list = list->next;
564 c--;
567 if (page > 1)
569 fprintf (list_file, "\f");
572 fprintf (list_file, "%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
573 fprintf (list_file, "%s\n", title);
574 fprintf (list_file, "%s\n", subtitle);
575 on_page = 3;
576 eject = 0;
580 static unsigned int
581 calc_hex (list_info_type *list)
583 int data_buffer_size;
584 list_info_type *first = list;
585 unsigned int address = ~(unsigned int) 0;
586 fragS *frag;
587 fragS *frag_ptr;
588 unsigned int octet_in_frag;
590 /* Find first frag which says it belongs to this line. */
591 frag = list->frag;
592 while (frag && frag->line != list)
593 frag = frag->fr_next;
595 frag_ptr = frag;
597 data_buffer_size = 0;
599 /* Dump all the frags which belong to this line. */
600 while (frag_ptr != (fragS *) NULL && frag_ptr->line == first)
602 /* Print as many bytes from the fixed part as is sensible. */
603 octet_in_frag = 0;
604 while ((offsetT) octet_in_frag < frag_ptr->fr_fix
605 && data_buffer_size < MAX_BYTES - 3)
607 if (address == ~(unsigned int) 0)
608 address = frag_ptr->fr_address / OCTETS_PER_BYTE;
610 sprintf (data_buffer + data_buffer_size,
611 "%02X",
612 (frag_ptr->fr_literal[octet_in_frag]) & 0xff);
613 data_buffer_size += 2;
614 octet_in_frag++;
616 if (frag_ptr->fr_type == rs_fill)
618 unsigned int var_rep_max = octet_in_frag;
619 unsigned int var_rep_idx = octet_in_frag;
621 /* Print as many bytes from the variable part as is sensible. */
622 while (((offsetT) octet_in_frag
623 < (frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset))
624 && data_buffer_size < MAX_BYTES - 3)
626 if (address == ~(unsigned int) 0)
627 address = frag_ptr->fr_address / OCTETS_PER_BYTE;
629 sprintf (data_buffer + data_buffer_size,
630 "%02X",
631 (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
632 data_buffer_size += 2;
634 var_rep_idx++;
635 octet_in_frag++;
637 if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var)
638 var_rep_idx = var_rep_max;
642 frag_ptr = frag_ptr->fr_next;
644 data_buffer[data_buffer_size] = '\0';
645 return address;
648 static void
649 print_lines (list_info_type *list, unsigned int lineno,
650 char *string, unsigned int address)
652 unsigned int idx;
653 unsigned int nchars;
654 unsigned int lines;
655 unsigned int octet_in_word = 0;
656 char *src = data_buffer;
657 int cur;
659 /* Print the stuff on the first line. */
660 listing_page (list);
661 nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width;
663 /* Print the hex for the first line. */
664 if (address == ~(unsigned int) 0)
666 fprintf (list_file, "% 4d ", lineno);
667 for (idx = 0; idx < nchars; idx++)
668 fprintf (list_file, " ");
670 fprintf (list_file, "\t%s\n", string ? string : "");
672 on_page++;
674 listing_page (0);
676 return;
679 if (had_errors ())
680 fprintf (list_file, "% 4d ???? ", lineno);
681 else
682 fprintf (list_file, "% 4d %04x ", lineno, address);
684 /* And the data to go along with it. */
685 idx = 0;
686 cur = 0;
687 while (src[cur] && idx < nchars)
689 int offset;
690 offset = cur;
691 fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
692 cur += 2;
693 octet_in_word++;
695 if (octet_in_word == LISTING_WORD_SIZE)
697 fprintf (list_file, " ");
698 idx++;
699 octet_in_word = 0;
702 idx += 2;
705 for (; idx < nchars; idx++)
706 fprintf (list_file, " ");
708 fprintf (list_file, "\t%s\n", string ? string : "");
709 on_page++;
710 listing_page (list);
712 if (list->message)
714 fprintf (list_file, "**** %s\n", list->message);
715 listing_page (list);
716 on_page++;
719 for (lines = 0;
720 lines < (unsigned int) listing_lhs_cont_lines
721 && src[cur];
722 lines++)
724 nchars = ((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second - 1;
725 idx = 0;
727 /* Print any more lines of data, but more compactly. */
728 fprintf (list_file, "% 4d ", lineno);
730 while (src[cur] && idx < nchars)
732 int offset;
733 offset = cur;
734 fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
735 cur += 2;
736 idx += 2;
737 octet_in_word++;
739 if (octet_in_word == LISTING_WORD_SIZE)
741 fprintf (list_file, " ");
742 idx++;
743 octet_in_word = 0;
747 fprintf (list_file, "\n");
748 on_page++;
749 listing_page (list);
753 static void
754 list_symbol_table (void)
756 extern symbolS *symbol_rootP;
757 int got_some = 0;
759 symbolS *ptr;
760 eject = 1;
761 listing_page (0);
763 for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
765 if (SEG_NORMAL (S_GET_SEGMENT (ptr))
766 || S_GET_SEGMENT (ptr) == absolute_section)
768 /* Don't report section symbols. They are not interesting. */
769 if (symbol_section_p (ptr))
770 continue;
772 if (S_GET_NAME (ptr))
774 char buf[30], fmt[8];
775 valueT val = S_GET_VALUE (ptr);
777 /* @@ Note that this is dependent on the compilation options,
778 not solely on the target characteristics. */
779 if (sizeof (val) == 4 && sizeof (int) == 4)
780 sprintf (buf, "%08lx", (unsigned long) val);
781 else if (sizeof (val) <= sizeof (unsigned long))
783 sprintf (fmt, "%%0%lulx",
784 (unsigned long) (sizeof (val) * 2));
785 sprintf (buf, fmt, (unsigned long) val);
787 #if defined (BFD64)
788 else if (sizeof (val) > 4)
789 sprintf_vma (buf, val);
790 #endif
791 else
792 abort ();
794 if (!got_some)
796 fprintf (list_file, "DEFINED SYMBOLS\n");
797 on_page++;
798 got_some = 1;
801 if (symbol_get_frag (ptr) && symbol_get_frag (ptr)->line)
803 fprintf (list_file, "%20s:%-5d %s:%s %s\n",
804 symbol_get_frag (ptr)->line->file->filename,
805 symbol_get_frag (ptr)->line->line,
806 segment_name (S_GET_SEGMENT (ptr)),
807 buf, S_GET_NAME (ptr));
809 else
811 fprintf (list_file, "%33s:%s %s\n",
812 segment_name (S_GET_SEGMENT (ptr)),
813 buf, S_GET_NAME (ptr));
816 on_page++;
817 listing_page (0);
822 if (!got_some)
824 fprintf (list_file, "NO DEFINED SYMBOLS\n");
825 on_page++;
827 fprintf (list_file, "\n");
828 on_page++;
829 listing_page (0);
831 got_some = 0;
833 for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
835 if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0)
837 if (S_GET_SEGMENT (ptr) == undefined_section)
839 if (!got_some)
841 got_some = 1;
842 fprintf (list_file, "UNDEFINED SYMBOLS\n");
843 on_page++;
844 listing_page (0);
846 fprintf (list_file, "%s\n", S_GET_NAME (ptr));
847 on_page++;
848 listing_page (0);
852 if (!got_some)
854 fprintf (list_file, "NO UNDEFINED SYMBOLS\n");
855 on_page++;
856 listing_page (0);
860 static void
861 print_source (file_info_type *current_file, list_info_type *list,
862 char *buffer, unsigned int width)
864 if (!current_file->at_end)
866 while (current_file->linenum < list->hll_line
867 && !current_file->at_end)
869 char *p = buffer_line (current_file, buffer, width);
871 fprintf (list_file, "%4u:%-13s **** %s\n", current_file->linenum,
872 current_file->filename, p);
873 on_page++;
874 listing_page (list);
879 /* Sometimes the user doesn't want to be bothered by the debugging
880 records inserted by the compiler, see if the line is suspicious. */
882 static int
883 debugging_pseudo (list_info_type *list, const char *line)
885 static int in_debug;
886 int was_debug;
888 if (list->debugging)
890 in_debug = 1;
891 return 1;
894 was_debug = in_debug;
895 in_debug = 0;
897 while (ISSPACE (*line))
898 line++;
900 if (*line != '.')
902 #ifdef OBJ_ELF
903 /* The ELF compiler sometimes emits blank lines after switching
904 out of a debugging section. If the next line drops us back
905 into debugging information, then don't print the blank line.
906 This is a hack for a particular compiler behaviour, not a
907 general case. */
908 if (was_debug
909 && *line == '\0'
910 && list->next != NULL
911 && list->next->debugging)
913 in_debug = 1;
914 return 1;
916 #endif
918 return 0;
921 line++;
923 if (strncmp (line, "def", 3) == 0)
924 return 1;
925 if (strncmp (line, "val", 3) == 0)
926 return 1;
927 if (strncmp (line, "scl", 3) == 0)
928 return 1;
929 if (strncmp (line, "line", 4) == 0)
930 return 1;
931 if (strncmp (line, "endef", 5) == 0)
932 return 1;
933 if (strncmp (line, "ln", 2) == 0)
934 return 1;
935 if (strncmp (line, "type", 4) == 0)
936 return 1;
937 if (strncmp (line, "size", 4) == 0)
938 return 1;
939 if (strncmp (line, "dim", 3) == 0)
940 return 1;
941 if (strncmp (line, "tag", 3) == 0)
942 return 1;
943 if (strncmp (line, "stabs", 5) == 0)
944 return 1;
945 if (strncmp (line, "stabn", 5) == 0)
946 return 1;
948 return 0;
951 static void
952 listing_listing (char *name ATTRIBUTE_UNUSED)
954 list_info_type *list = head;
955 file_info_type *current_hll_file = (file_info_type *) NULL;
956 char *message;
957 char *buffer;
958 char *p;
959 int show_listing = 1;
960 unsigned int width;
962 buffer = xmalloc (listing_rhs_width);
963 data_buffer = xmalloc (MAX_BYTES);
964 eject = 1;
965 list = head->next;
967 while (list)
969 unsigned int list_line;
971 width = listing_rhs_width > paper_width ? paper_width :
972 listing_rhs_width;
974 list_line = list->line;
975 switch (list->edict)
977 case EDICT_LIST:
978 /* Skip all lines up to the current. */
979 list_line--;
980 break;
981 case EDICT_NOLIST:
982 show_listing--;
983 break;
984 case EDICT_NOLIST_NEXT:
985 if (show_listing == 0)
986 list_line--;
987 break;
988 case EDICT_EJECT:
989 break;
990 case EDICT_NONE:
991 break;
992 case EDICT_TITLE:
993 title = list->edict_arg;
994 break;
995 case EDICT_SBTTL:
996 subtitle = list->edict_arg;
997 break;
998 default:
999 abort ();
1002 if (show_listing <= 0)
1004 while (list->file->linenum < list_line
1005 && !list->file->at_end)
1006 p = buffer_line (list->file, buffer, width);
1009 if (list->edict == EDICT_LIST
1010 || (list->edict == EDICT_NOLIST_NEXT && show_listing == 0))
1012 /* Enable listing for the single line that caused the enable. */
1013 list_line++;
1014 show_listing++;
1017 if (show_listing > 0)
1019 /* Scan down the list and print all the stuff which can be done
1020 with this line (or lines). */
1021 message = 0;
1023 if (list->hll_file)
1024 current_hll_file = list->hll_file;
1026 if (current_hll_file && list->hll_line && (listing & LISTING_HLL))
1027 print_source (current_hll_file, list, buffer, width);
1029 if (list->line_contents)
1031 if (!((listing & LISTING_NODEBUG)
1032 && debugging_pseudo (list, list->line_contents)))
1033 print_lines (list,
1034 list->file->linenum == 0 ? list->line : list->file->linenum,
1035 list->line_contents, calc_hex (list));
1037 free (list->line_contents);
1038 list->line_contents = NULL;
1040 else
1042 while (list->file->linenum < list_line
1043 && !list->file->at_end)
1045 unsigned int address;
1047 p = buffer_line (list->file, buffer, width);
1049 if (list->file->linenum < list_line)
1050 address = ~(unsigned int) 0;
1051 else
1052 address = calc_hex (list);
1054 if (!((listing & LISTING_NODEBUG)
1055 && debugging_pseudo (list, p)))
1056 print_lines (list, list->file->linenum, p, address);
1060 if (list->edict == EDICT_EJECT)
1061 eject = 1;
1064 if (list->edict == EDICT_NOLIST_NEXT && show_listing == 1)
1065 --show_listing;
1067 list = list->next;
1070 free (buffer);
1071 free (data_buffer);
1072 data_buffer = NULL;
1075 /* Print time stamp in ISO format: yyyy-mm-ddThh:mm:ss.ss+/-zzzz. */
1077 static void
1078 print_timestamp (void)
1080 const time_t now = time (NULL);
1081 struct tm * timestamp;
1082 char stampstr[MAX_DATELEN];
1084 /* Any portable way to obtain subsecond values??? */
1085 timestamp = localtime (&now);
1086 strftime (stampstr, MAX_DATELEN, "%Y-%m-%dT%H:%M:%S.000%z", timestamp);
1087 fprintf (list_file, _("\n time stamp \t: %s\n\n"), stampstr);
1090 static void
1091 print_single_option (char * opt, int *pos)
1093 int opt_len = strlen (opt);
1095 if ((*pos + opt_len) < paper_width)
1097 fprintf (list_file, _("%s "), opt);
1098 *pos = *pos + opt_len;
1100 else
1102 fprintf (list_file, _("\n\t%s "), opt);
1103 *pos = opt_len;
1107 /* Print options passed to as. */
1109 static void
1110 print_options (char ** argv)
1112 const char *field_name = _("\n options passed\t: ");
1113 int pos = strlen (field_name);
1114 char **p;
1116 fputs (field_name, list_file);
1117 for (p = &argv[1]; *p != NULL; p++)
1118 if (**p == '-')
1120 /* Ignore these. */
1121 if (strcmp (*p, "-o") == 0)
1123 if (p[1] != NULL)
1124 p++;
1125 continue;
1127 if (strcmp (*p, "-v") == 0)
1128 continue;
1130 print_single_option (*p, &pos);
1134 /* Print a first section with basic info like file names, as version,
1135 options passed, target, and timestamp.
1136 The format of this section is as follows:
1138 AS VERSION
1140 fieldname TAB ':' fieldcontents
1141 { TAB fieldcontents-cont } */
1143 static void
1144 listing_general_info (char ** argv)
1146 /* Print the stuff on the first line. */
1147 eject = 1;
1148 listing_page (0);
1150 fprintf (list_file,
1151 _(" GNU assembler version %s (%s)\n\t using BFD version %s."),
1152 VERSION, TARGET_ALIAS, BFD_VERSION_STRING);
1153 print_options (argv);
1154 fprintf (list_file, _("\n input file \t: %s"), fn);
1155 fprintf (list_file, _("\n output file \t: %s"), out_file_name);
1156 fprintf (list_file, _("\n target \t: %s"), TARGET_CANONICAL);
1157 print_timestamp ();
1160 void
1161 listing_print (char *name, char **argv)
1163 int using_stdout;
1165 title = "";
1166 subtitle = "";
1168 if (name == NULL)
1170 list_file = stdout;
1171 using_stdout = 1;
1173 else
1175 list_file = fopen (name, FOPEN_WT);
1176 if (list_file != NULL)
1177 using_stdout = 0;
1178 else
1180 as_warn (_("can't open %s: %s"), name, xstrerror (errno));
1181 list_file = stdout;
1182 using_stdout = 1;
1186 if (listing & LISTING_NOFORM)
1187 paper_height = 0;
1189 if (listing & LISTING_GENERAL)
1190 listing_general_info (argv);
1192 if (listing & LISTING_LISTING)
1193 listing_listing (name);
1195 if (listing & LISTING_SYMBOLS)
1196 list_symbol_table ();
1198 if (! using_stdout)
1200 if (fclose (list_file) == EOF)
1201 as_warn (_("can't close %s: %s"), name, xstrerror (errno));
1204 if (last_open_file)
1205 fclose (last_open_file);
1208 void
1209 listing_file (const char *name)
1211 fn = name;
1214 void
1215 listing_eject (int ignore ATTRIBUTE_UNUSED)
1217 if (listing)
1218 listing_tail->edict = EDICT_EJECT;
1221 void
1222 listing_flags (int ignore ATTRIBUTE_UNUSED)
1224 while ((*input_line_pointer++) && (*input_line_pointer != '\n'))
1225 input_line_pointer++;
1229 /* Turn listing on or off. An argument of 0 means to turn off
1230 listing. An argument of 1 means to turn on listing. An argument
1231 of 2 means to turn off listing, but as of the next line; that is,
1232 the current line should be listed, but the next line should not. */
1234 void
1235 listing_list (int on)
1237 if (listing)
1239 switch (on)
1241 case 0:
1242 if (listing_tail->edict == EDICT_LIST)
1243 listing_tail->edict = EDICT_NONE;
1244 else
1245 listing_tail->edict = EDICT_NOLIST;
1246 break;
1247 case 1:
1248 if (listing_tail->edict == EDICT_NOLIST
1249 || listing_tail->edict == EDICT_NOLIST_NEXT)
1250 listing_tail->edict = EDICT_NONE;
1251 else
1252 listing_tail->edict = EDICT_LIST;
1253 break;
1254 case 2:
1255 listing_tail->edict = EDICT_NOLIST_NEXT;
1256 break;
1257 default:
1258 abort ();
1263 void
1264 listing_psize (int width_only)
1266 if (! width_only)
1268 paper_height = get_absolute_expression ();
1270 if (paper_height < 0 || paper_height > 1000)
1272 paper_height = 0;
1273 as_warn (_("strange paper height, set to no form"));
1276 if (*input_line_pointer != ',')
1278 demand_empty_rest_of_line ();
1279 return;
1282 ++input_line_pointer;
1285 paper_width = get_absolute_expression ();
1287 demand_empty_rest_of_line ();
1290 void
1291 listing_nopage (int ignore ATTRIBUTE_UNUSED)
1293 paper_height = 0;
1296 void
1297 listing_title (int depth)
1299 int quoted;
1300 char *start;
1301 char *ttl;
1302 unsigned int length;
1304 SKIP_WHITESPACE ();
1305 if (*input_line_pointer != '\"')
1306 quoted = 0;
1307 else
1309 quoted = 1;
1310 ++input_line_pointer;
1313 start = input_line_pointer;
1315 while (*input_line_pointer)
1317 if (quoted
1318 ? *input_line_pointer == '\"'
1319 : is_end_of_line[(unsigned char) *input_line_pointer])
1321 if (listing)
1323 length = input_line_pointer - start;
1324 ttl = xmalloc (length + 1);
1325 memcpy (ttl, start, length);
1326 ttl[length] = 0;
1327 listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
1328 listing_tail->edict_arg = ttl;
1330 if (quoted)
1331 input_line_pointer++;
1332 demand_empty_rest_of_line ();
1333 return;
1335 else if (*input_line_pointer == '\n')
1337 as_bad (_("new line in title"));
1338 demand_empty_rest_of_line ();
1339 return;
1341 else
1343 input_line_pointer++;
1348 void
1349 listing_source_line (unsigned int line)
1351 if (listing)
1353 new_frag ();
1354 listing_tail->hll_line = line;
1355 new_frag ();
1359 void
1360 listing_source_file (const char *file)
1362 if (listing)
1363 listing_tail->hll_file = file_info (file);
1366 #else
1368 /* Dummy functions for when compiled without listing enabled. */
1370 void
1371 listing_flags (int ignore)
1373 s_ignore (0);
1376 void
1377 listing_list (int on)
1379 s_ignore (0);
1382 void
1383 listing_eject (int ignore)
1385 s_ignore (0);
1388 void
1389 listing_psize (int ignore)
1391 s_ignore (0);
1394 void
1395 listing_nopage (int ignore)
1397 s_ignore (0);
1400 void
1401 listing_title (int depth)
1403 s_ignore (0);
1406 void
1407 listing_file (const char *name)
1411 void
1412 listing_newline (char *name)
1416 void
1417 listing_source_line (unsigned int n)
1421 void
1422 listing_source_file (const char *n)
1426 #endif