1 /* listing.c - mainting assembly listings
2 Copyright (C) 1991, 1992 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 2, or (at your option)
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
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 Contributed by Steve Chamberlain
25 A listing page looks like:
27 LISTING_HEADER sourcefilename pagenumber
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:
38 Put "stuff" onto the title line
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
48 Increment the enable listing counter
50 Decrement the enable listing counter
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.
59 Listings are a maintained by read calling various listing_<foo>
60 functions. What happens most is that the macro NO_LISTING is not
61 defined (from the Makefile), then the macro LISTING_NEWLINE expands
62 into a call to listing_newline. The call is done from read.c, every
63 time it sees a newline, and -l is on the command line.
65 The function listing_newline remembers the frag associated with the
66 newline, and creates a new frag - note that this is wasteful, but not
67 a big deal, since listing slows things down a lot anyway. The
68 function also rememebers when the filename changes.
70 When all the input has finished, and gas has had a chance to settle
71 down, the listing is output. This is done by running down the list of
72 frag/source file records, and opening the files as needed and printing
73 out the bytes and chars associated with them.
75 The only things which the architecture can change about the listing
76 are defined in these macros:
78 LISTING_HEADER The name of the architecture
79 LISTING_WORD_SIZE The make of the number of bytes in a word, this determines
80 the clumping of the output data. eg a value of
81 2 makes words look like 1234 5678, whilst 1
82 would make the same value look like 12 34 56
84 LISTING_LHS_WIDTH Number of words of above size for the lhs
86 LISTING_LHS_WIDTH_SECOND Number of words for the data on the lhs
89 LISTING_LHS_CONT_LINES Max number of lines to use up for a continutation
90 LISTING_RHS_WIDTH Number of chars from the input file to print
95 * $FreeBSD: src/gnu/usr.bin/as/listing.c,v 1.6 1999/08/27 23:34:18 peter Exp $
96 * $DragonFly: src/gnu/usr.bin/as/Attic/listing.c,v 1.2 2003/06/17 04:25:44 dillon Exp $
102 #include "input-file.h"
106 #ifndef LISTING_HEADER
107 #define LISTING_HEADER "GAS LISTING"
109 #ifndef LISTING_WORD_SIZE
110 #define LISTING_WORD_SIZE 4
112 #ifndef LISTING_LHS_WIDTH
113 #define LISTING_LHS_WIDTH 1
115 #ifndef LISTING_LHS_WIDTH_SECOND
116 #define LISTING_LHS_WIDTH_SECOND 1
118 #ifndef LISTING_RHS_WIDTH
119 #define LISTING_RHS_WIDTH 100
121 #ifndef LISTING_LHS_CONT_LINES
122 #define LISTING_LHS_CONT_LINES 4
128 static struct list_info_struct *head;
129 struct list_info_struct *listing_tail;
131 extern fragS *frag_now;
134 static int paper_width = 200;
135 static int paper_height = 60;
138 /* this static array is used to keep the text of data to be printed
139 before the start of the line.
140 It is stored so we can give a bit more info on the next line. To much, and large
141 initialized arrays will use up lots of paper.
144 static char data_buffer[100];
145 static unsigned int data_buffer_size;
149 static void listing_message PARAMS ((const char *name, const char *message));
150 static file_info_type *file_info PARAMS ((const char *file_name));
151 static void new_frag PARAMS ((void));
152 static char *buffer_line PARAMS ((file_info_type *file,
153 char *line, unsigned int size));
154 static void listing_page PARAMS ((list_info_type *list));
155 static unsigned int calc_hex PARAMS ((list_info_type *list));
156 static void print_lines PARAMS ((list_info_type *list,
158 unsigned int address));
159 static void list_symbol_table PARAMS ((void));
160 static void print_source PARAMS ((file_info_type *current_file,
161 list_info_type *list,
163 unsigned int width));
164 static int debugging_pseudo PARAMS ((char *line));
165 static void listing_listing PARAMS ((char *name));
169 listing_message (name, message)
173 unsigned int l = strlen (name) + strlen (message) + 1;
174 char *n = (char *) xmalloc (l);
177 if (listing_tail != (list_info_type *) NULL)
179 listing_tail->message = n;
184 listing_warning (message)
187 listing_message ("Warning:", message);
191 listing_error (message)
194 listing_message ("Error:", message);
200 static file_info_type *file_info_head;
202 static file_info_type *
203 file_info (file_name)
204 const char *file_name;
206 /* Find an entry with this file name */
207 file_info_type *p = file_info_head;
209 while (p != (file_info_type *) NULL)
211 if (strcmp (p->filename, file_name) == 0)
218 p = (file_info_type *) xmalloc (sizeof (file_info_type));
219 p->next = file_info_head;
221 p->filename = xmalloc ((unsigned long) strlen (file_name) + 1);
222 strcpy (p->filename, file_name);
226 /* Do we really prefer binary mode for this?? */
228 p->file = fopen (p->filename, FOPEN_RB);
240 frag_wane (frag_now);
251 static unsigned int last_line = 0xffff;
252 static char *last_file = NULL;
255 as_where (&file, &line);
256 if (line != last_line || last_file && file && strcmp(file, last_file))
262 new = (list_info_type *) xmalloc (sizeof (list_info_type));
263 new->frag = frag_now;
265 new->file = file_info (file);
269 listing_tail->next = new;
276 new->next = (list_info_type *) NULL;
277 new->message = (char *) NULL;
278 new->edict = EDICT_NONE;
279 new->hll_file = (file_info_type *) NULL;
285 /* Attach all current frags to the previous line instead of the
286 current line. This is called by the MIPS backend when it discovers
287 that it needs to add some NOP instructions; the added NOP
288 instructions should go with the instruction that has the delay, not
289 with the new instruction. */
297 if (head == (list_info_type *) NULL
298 || head == listing_tail)
303 for (l = head; l->next != listing_tail; l = l->next)
306 for (f = frchain_now->frch_root; f != (fragS *) NULL; f = f->fr_next)
307 if (f->line == listing_tail)
310 listing_tail->frag = frag_now;
315 This function returns the next source line from the file supplied,
316 truncated to size. It appends a fake line to the end of each input
321 buffer_line (file, line, size)
322 file_info_type * file;
326 unsigned int count = 0;
331 /* If we couldn't open the file, return an empty line */
332 if (file->file == (FILE *) NULL)
337 if (file->linenum == 0)
340 if (file->end_pending == 10)
343 fseek (file->file, 0, 0);
345 file->end_pending = 0;
347 c = fgetc (file->file);
350 size -= 1; /* leave room for null */
352 while (c != EOF && c != '\n')
358 c = fgetc (file->file);
374 static const char *fn;
376 static unsigned int eject; /* Eject pending */
377 static unsigned int page; /* Current page number */
378 static char *title; /* current title */
379 static char *subtitle; /* current subtitle */
380 static unsigned int on_page; /* number of lines printed on current page */
385 list_info_type *list;
387 /* Grope around, see if we can see a title or subtitle edict coming up
388 soon (we look down 10 lines of the page and see if it's there)*/
389 if ((eject || (on_page >= paper_height)) && paper_height != 0)
393 int had_subtitle = 0;
397 while (c != 0 && list)
399 if (list->edict == EDICT_SBTTL && !had_subtitle)
402 subtitle = list->edict_arg;
404 if (list->edict == EDICT_TITLE && !had_title)
407 title = list->edict_arg;
419 printf ("%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
420 printf ("%s\n", title);
421 printf ("%s\n", subtitle);
430 list_info_type * list;
432 list_info_type *first = list;
433 unsigned int address = (unsigned int) ~0;
438 unsigned int byte_in_frag;
441 /* Find first frag which says it belongs to this line */
443 while (frag && frag->line != list)
444 frag = frag->fr_next;
448 data_buffer_size = 0;
450 /* Dump all the frags which belong to this line */
451 while (frag_ptr != (fragS *) NULL && frag_ptr->line == first)
453 /* Print as many bytes from the fixed part as is sensible */
455 while (byte_in_frag < frag_ptr->fr_fix && data_buffer_size < sizeof (data_buffer) - 10)
459 address = frag_ptr->fr_address;
462 sprintf (data_buffer + data_buffer_size,
464 (frag_ptr->fr_literal[byte_in_frag]) & 0xff);
465 data_buffer_size += 2;
469 unsigned int var_rep_max = byte_in_frag;
470 unsigned int var_rep_idx = byte_in_frag;
472 /* Print as many bytes from the variable part as is sensible */
473 while (byte_in_frag < frag_ptr->fr_var * frag_ptr->fr_offset
474 && data_buffer_size < sizeof (data_buffer) - 10)
478 address = frag_ptr->fr_address;
480 sprintf (data_buffer + data_buffer_size,
482 (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
484 data_buffer[data_buffer_size++] = '*';
485 data_buffer[data_buffer_size++] = '*';
487 data_buffer_size += 2;
492 if (var_rep_idx >= frag_ptr->fr_var)
493 var_rep_idx = var_rep_max;
497 frag_ptr = frag_ptr->fr_next;
499 data_buffer[data_buffer_size++] = 0;
509 print_lines (list, string, address)
510 list_info_type *list;
512 unsigned int address;
517 unsigned int byte_in_word = 0;
518 char *src = data_buffer;
520 /* Print the stuff on the first line */
522 nchars = (LISTING_WORD_SIZE * 2 + 1) * LISTING_LHS_WIDTH;
523 /* Print the hex for the first line */
526 printf ("% 4d ", list->line);
527 for (idx = 0; idx < nchars; idx++)
530 printf ("\t%s\n", string ? string : "");
539 printf ("% 4d ???? ", list->line);
543 printf ("% 4d %04x ", list->line, address);
546 /* And the data to go along with it */
549 while (*src && idx < nchars)
551 printf ("%c%c", src[0], src[1]);
554 if (byte_in_word == LISTING_WORD_SIZE)
563 for (; idx < nchars; idx++)
566 printf ("\t%s\n", string ? string : "");
571 printf ("**** %s\n", list->message);
577 lines < LISTING_LHS_CONT_LINES
581 nchars = ((LISTING_WORD_SIZE * 2) + 1) * LISTING_LHS_WIDTH_SECOND - 1;
583 /* Print any more lines of data, but more compactly */
584 printf ("% 4d ", list->line);
586 while (*src && idx < nchars)
588 printf ("%c%c", src[0], src[1]);
592 if (byte_in_word == LISTING_WORD_SIZE)
614 extern symbolS *symbol_rootP;
621 for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
623 if (ptr->sy_frag->line)
625 if (S_GET_NAME (ptr))
628 valueT val = S_GET_VALUE (ptr);
630 /* @@ Note that this is dependent on the compilation options,
631 not solely on the target characteristics. */
632 if (sizeof (val) == 4 && sizeof (int) == 4)
633 sprintf (buf, "%08lx", (unsigned long) val);
635 else if (sizeof (val) > 4)
638 sprintf_vma (buf1, val);
639 strcpy (buf, "00000000");
640 strcpy (buf + 8 - strlen (buf1), buf1);
648 printf ("DEFINED SYMBOLS\n");
653 printf ("%20s:%-5d %s:%s %s\n",
654 ptr->sy_frag->line->file->filename,
655 ptr->sy_frag->line->line,
656 segment_name (S_GET_SEGMENT (ptr)),
657 buf, S_GET_NAME (ptr));
667 printf ("NO DEFINED SYMBOLS\n");
676 for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
678 if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0)
680 if (ptr->sy_frag->line == 0
682 && S_GET_SEGMENT (ptr) != reg_section)
684 && !S_IS_REGISTER(ptr))
690 printf ("UNDEFINED SYMBOLS\n");
694 printf ("%s\n", S_GET_NAME (ptr));
702 printf ("NO UNDEFINED SYMBOLS\n");
709 print_source (current_file, list, buffer, width)
710 file_info_type *current_file;
711 list_info_type *list;
715 if (current_file->file)
717 while (current_file->linenum < list->hll_line)
719 char *p = buffer_line (current_file, buffer, width);
720 printf ("%4d:%-13s **** %s\n", current_file->linenum, current_file->filename, p);
727 /* Sometimes the user doesn't want to be bothered by the debugging
728 records inserted by the compiler, see if the line is suspicious */
731 debugging_pseudo (line)
734 while (isspace (*line))
742 if (strncmp (line, "def", 3) == 0)
744 if (strncmp (line, "val", 3) == 0)
746 if (strncmp (line, "scl", 3) == 0)
748 if (strncmp (line, "line", 4) == 0)
750 if (strncmp (line, "endef", 5) == 0)
752 if (strncmp (line, "ln", 2) == 0)
754 if (strncmp (line, "type", 4) == 0)
756 if (strncmp (line, "size", 4) == 0)
758 if (strncmp (line, "dim", 3) == 0)
760 if (strncmp (line, "tag", 3) == 0)
763 if (strncmp (line, "stabs", 5) == 0)
765 if (strncmp (line, "stabn", 5) == 0)
773 listing_listing (name)
776 list_info_type *list = head;
777 file_info_type *current_hll_file = (file_info_type *) NULL;
781 int show_listing = 1;
784 buffer = xmalloc (LISTING_RHS_WIDTH);
788 while (list != (list_info_type *) NULL && 0)
791 list->frag = list->next->frag;
801 width = LISTING_RHS_WIDTH > paper_width ? paper_width :
817 title = list->edict_arg;
820 subtitle = list->edict_arg;
826 if (show_listing > 0)
828 /* Scan down the list and print all the stuff which can be done
829 with this line (or lines). */
834 current_hll_file = list->hll_file;
837 if (current_hll_file && list->hll_line && listing & LISTING_HLL)
839 print_source (current_hll_file, list, buffer, width);
842 while (list->file->file &&
843 list->file->linenum < list->line && !list->file->end_pending) {
844 p = buffer_line (list->file, buffer, width);
846 if (!((listing & LISTING_NODEBUG) && debugging_pseudo (p)))
848 print_lines (list, p, calc_hex (list));
852 if (list->edict == EDICT_EJECT)
860 while (list->file->file &&
861 list->file->linenum < list->line && !list->file->end_pending)
862 p = buffer_line (list->file, buffer, width);
877 if (listing & LISTING_NOFORM)
882 if (listing & LISTING_LISTING)
884 listing_listing (name);
887 if (listing & LISTING_SYMBOLS)
889 list_symbol_table ();
902 listing_eject (ignore)
905 listing_tail->edict = EDICT_EJECT;
909 listing_flags (ignore)
912 while ((*input_line_pointer++) && (*input_line_pointer != '\n'))
913 input_line_pointer++;
921 listing_tail->edict = on ? EDICT_LIST : EDICT_NOLIST;
926 listing_psize (ignore)
929 paper_height = get_absolute_expression ();
931 if (paper_height < 0 || paper_height > 1000)
934 as_warn ("strange paper height, set to no form");
936 if (*input_line_pointer == ',')
938 input_line_pointer++;
939 paper_width = get_absolute_expression ();
945 listing_title (depth)
953 if (*input_line_pointer == '\"')
955 input_line_pointer++;
956 start = input_line_pointer;
958 while (*input_line_pointer)
960 if (*input_line_pointer == '\"')
962 length = input_line_pointer - start;
963 ttl = xmalloc (length + 1);
964 memcpy (ttl, start, length);
966 listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
967 listing_tail->edict_arg = ttl;
968 input_line_pointer++;
969 demand_empty_rest_of_line ();
972 else if (*input_line_pointer == '\n')
974 as_bad ("New line in title");
975 demand_empty_rest_of_line ();
980 input_line_pointer++;
986 as_bad ("expecting title in quotes");
993 listing_source_line (line)
997 listing_tail->hll_line = line;
1003 listing_source_file (file)
1007 listing_tail->hll_file = file_info (file);
1015 /* Dummy functions for when compiled without listing enabled */
1018 listing_flags (ignore)
1032 listing_eject (ignore)
1039 listing_psize (ignore)
1046 listing_title (depth)
1060 listing_newline (name)
1067 listing_source_line (n)
1073 listing_source_file (n)