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
96 #include "input-file.h"
102 #ifndef LISTING_HEADER
103 #define LISTING_HEADER "GAS LISTING"
105 #ifndef LISTING_WORD_SIZE
106 #define LISTING_WORD_SIZE 4
108 #ifndef LISTING_LHS_WIDTH
109 #define LISTING_LHS_WIDTH 1
111 #ifndef LISTING_LHS_WIDTH_SECOND
112 #define LISTING_LHS_WIDTH_SECOND 1
114 #ifndef LISTING_RHS_WIDTH
115 #define LISTING_RHS_WIDTH 100
117 #ifndef LISTING_LHS_CONT_LINES
118 #define LISTING_LHS_CONT_LINES 4
124 /* This structure remembers which .s were used */
125 typedef struct file_info_struct
130 struct file_info_struct *next;
136 /* this structure rememebrs which line from which file goes into which
138 typedef struct list_info_struct
140 /* Frag which this line of source is nearest to */
142 /* The actual line in the source file */
144 /* Pointer to the file info struct for the file which this line
146 file_info_type *file;
149 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 */
160 /* Pointer to any error message associated with this line */
177 static struct list_info_struct *head;
178 struct list_info_struct *listing_tail;
180 extern unsigned int physical_input_line;
181 extern fragS *frag_now;
184 static int paper_width = 200;
185 static int paper_height = 60;
188 /* this static array is used to keep the text of data to be printed
189 before the start of the line.
190 It is stored so we can give a bit more info on the next line. To much, and large
191 initialized arrays will use up lots of paper.
194 static char data_buffer[100];
195 static unsigned int data_buffer_size;
199 DEFUN(listing_message,(name, message),
203 unsigned int l = strlen(name) + strlen(message)+1;
204 char *n = (char*)malloc(l);
207 if(listing_tail != (list_info_type *)NULL)
209 listing_tail->message = n;
218 DEFUN(listing_warning,(message),
221 listing_message("Warning:", message);
225 DEFUN(listing_error,(message),
228 listing_message("Error:", message);
234 static file_info_type *file_info_head;
236 static file_info_type *
237 DEFUN(file_info, (file_name),
240 /* Find an entry with this file name */
241 file_info_type *p = file_info_head;
243 while (p != (file_info_type *)NULL)
245 if (strcmp(p->filename, file_name) == 0)
252 p = (file_info_type *)xmalloc(sizeof(file_info_type));
253 p->next = file_info_head;
255 p->filename = xmalloc(strlen(file_name)+1);
256 strcpy(p->filename, file_name);
260 p->file = fopen(p->filename,"rb");
261 if (p->file) fgetc(p->file);
280 DEFUN(listing_newline,(ps),
284 extern char *file_name;
285 static unsigned int last_line =0xffff ;
289 if (physical_input_line != last_line)
291 last_line = physical_input_line;
294 new = (list_info_type *)malloc(sizeof(list_info_type));
295 new->frag = frag_now;
296 new->line = physical_input_line ;
297 new->file = file_info(file_name);
301 listing_tail->next = new;
308 new->next = (list_info_type *)NULL;
309 new->message = (char *)NULL;
310 new->edict = EDICT_NONE;
311 new->hll_file = (file_info_type*)NULL;
319 This function returns the next source line from the file supplied,
320 truncated to size. It appends a fake line to the end of each input
325 DEFUN(buffer_line,(file, line, size),
326 file_info_type *file AND
330 unsigned int count = 0;
335 /* If we couldn't open the file, return an empty line */
336 if (file->file == (FILE*)NULL)
341 if (file->linenum == 0)
344 if (file->end_pending == 10) {
346 fseek(file->file, 0,0 );
348 file->end_pending = 0;
350 c = fgetc(file->file);
353 size -= 1; /* leave room for null */
355 while (c != EOF && c != '\n')
361 c= fgetc(file->file);
366 file->end_pending ++;
379 static unsigned int eject; /* Eject pending */
380 static unsigned int page; /* Current page number */
381 static char *title; /* current title */
382 static char *subtitle; /* current subtitle */
383 static unsigned int on_page; /* number of lines printed on current page */
387 DEFUN(listing_page,(list),
388 list_info_type *list)
390 /* Grope around, see if we can see a title or subtitle edict coming up
391 soon (we look down 10 lines of the page and see if it's there)*/
392 if ((eject || (on_page >= paper_height)) && paper_height != 0)
396 int had_subtitle = 0;
400 while (c != 0 && list)
402 if (list->edict == EDICT_SBTTL && !had_subtitle)
405 subtitle = list->edict_arg;
407 if (list->edict == EDICT_TITLE && !had_title)
410 title = list->edict_arg;
422 printf("%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
423 printf("%s\n", title);
424 printf("%s\n", subtitle);
432 DEFUN(calc_hex,(list),
433 list_info_type *list)
435 list_info_type *first = list;
436 list_info_type *last = first;
437 unsigned int address = ~0;
442 unsigned int byte_in_frag = 0;
446 /* Find first frag which says it belongs to this line */
448 while (frag && frag->line != list)
449 frag = frag->fr_next;
453 data_buffer_size = 0;
455 /* Dump all the frags which belong to this line */
456 while (frag_ptr != (fragS *)NULL && frag_ptr->line == first)
458 /* Print as many bytes from the fixed part as is sensible */
459 while(byte_in_frag < frag_ptr->fr_fix && data_buffer_size < sizeof(data_buffer)-10)
463 address = frag_ptr->fr_address;
466 sprintf(data_buffer + data_buffer_size,
468 (frag_ptr->fr_literal[byte_in_frag]) & 0xff);
469 data_buffer_size += 2;
473 unsigned int var_rep_max = byte_in_frag;
474 unsigned int var_rep_idx = byte_in_frag;
476 /* Print as many bytes from the variable part as is sensible */
477 while (byte_in_frag < frag_ptr->fr_var * frag_ptr->fr_offset
478 && data_buffer_size < sizeof(data_buffer)-10)
482 address = frag_ptr->fr_address;
484 sprintf(data_buffer + data_buffer_size,
486 (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
488 data_buffer[data_buffer_size++] = '*';
489 data_buffer[data_buffer_size++] = '*';
491 data_buffer_size +=2;
496 if (var_rep_idx >= frag_ptr->fr_var)
497 var_rep_idx = var_rep_max;
501 frag_ptr = frag_ptr->fr_next;
503 data_buffer[data_buffer_size++] = 0;
513 DEFUN(print_lines,(list, string, address),
514 list_info_type *list AND
516 unsigned int address)
521 unsigned int byte_in_word =0;
522 char *src = data_buffer;
524 /* Print the stuff on the first line */
526 nchars = (LISTING_WORD_SIZE*2 +1) * LISTING_LHS_WIDTH ;
527 /* Print the hex for the first line */
530 printf("% 4d ", list->line);
531 for (idx = 0; idx < nchars; idx++)
534 printf("\t%s\n", string ? string : "");
543 printf("% 4d ???? ", list->line);
547 printf("% 4d %04x ", list->line, address);
550 /* And the data to go along with it */
553 while (*src && idx < nchars)
555 printf("%c%c", src[0], src[1]);
558 if (byte_in_word == LISTING_WORD_SIZE)
567 for (;idx < nchars; idx++)
570 printf("\t%s\n", string ? string : "");
575 printf("**** %s\n",list->message);
581 lines < LISTING_LHS_CONT_LINES
584 nchars = ((LISTING_WORD_SIZE*2) +1) * LISTING_LHS_WIDTH_SECOND -1;
586 /* Print any more lines of data, but more compactly */
587 printf("% 4d ", list->line);
589 while (*src && idx < nchars)
591 printf("%c%c", src[0], src[1]);
595 if (byte_in_word == LISTING_WORD_SIZE)
619 DEFUN_VOID(list_symbol_table)
621 extern symbolS *symbol_rootP;
626 printf("DEFINED SYMBOLS\n");
629 for (ptr = symbol_rootP; ptr != (symbolS*)NULL; ptr = symbol_next(ptr))
631 if (ptr->sy_frag->line)
636 if (strlen(S_GET_NAME(ptr)))
638 printf("%20s:%-5d %2d:%08x %s \n",
639 ptr->sy_frag->line->file->filename,
640 ptr->sy_frag->line->line,
648 printf("%20s:%-5d %2d:%08x\n",
649 ptr->sy_frag->line->file->filename,
650 ptr->sy_frag->line->line,
666 printf("UNDEFINED SYMBOLS\n");
670 for (ptr = symbol_rootP; ptr != (symbolS*)NULL; ptr = symbol_next(ptr))
672 if (S_GET_NAME(ptr) && strlen(S_GET_NAME(ptr)) != 0)
674 if (ptr->sy_frag->line == 0)
676 printf("%s\n", S_GET_NAME(ptr));
685 DEFUN(print_source,(current_file, list, buffer, width),
686 file_info_type *current_file AND
687 list_info_type *list AND
691 if (current_file->file) {
692 while (current_file->linenum < list->hll_line)
694 char * p = buffer_line(current_file, buffer, width);
695 printf("%4d:%-13s **** %s\n", current_file->linenum, current_file->filename, p);
702 /* Sometimes the user doesn't want to be bothered by the debugging
703 records inserted by the compiler, see if the line is suspicioous */
706 DEFUN(debugging_pseudo,(line),
709 while (isspace(*line))
712 if(*line != '.') return 0;
716 if (strncmp(line, "def",3) == 0) return 1;
717 if (strncmp(line, "val",3) == 0) return 1;
718 if (strncmp(line, "scl",3) == 0) return 1;
719 if (strncmp(line, "line",4) == 0) return 1;
720 if (strncmp(line, "endef",5) == 0) return 1;
721 if (strncmp(line, "ln",2) ==0) return 1;
722 if (strncmp(line, "type",4) ==0) return 1;
723 if (strncmp(line, "size",4) == 0) return 1;
724 if (strncmp(line, "dim",3) ==0) return 1;
725 if (strncmp(line, "tag",3) == 0) return 1;
732 DEFUN(listing_listing,(name),
735 list_info_type *list = head;
736 file_info_type *current_hll_file = (file_info_type *)NULL;
738 unsigned int page= 1;
739 unsigned int prev = 0;
743 unsigned int addr = 0;
745 int show_listing = 1;
748 buffer = malloc(LISTING_RHS_WIDTH);
752 while (list != (list_info_type *)NULL && 0)
755 list->frag = list->next->frag;
765 width = LISTING_RHS_WIDTH > paper_width ? paper_width :
768 switch (list->edict) {
780 title = list->edict_arg;
783 subtitle = list->edict_arg;
789 if (show_listing > 0)
791 /* Scan down the list and print all the stuff which can be done
792 with this line (or lines) */
797 current_hll_file = list->hll_file;
800 if (current_hll_file && list->hll_line && listing & LISTING_HLL)
802 print_source(current_hll_file, list, buffer, width);
805 p = buffer_line(list->file, buffer, width);
807 if (! ((listing & LISTING_NODEBUG) && debugging_pseudo(p)))
809 print_lines(list, p, calc_hex(list));
812 if (list->edict == EDICT_EJECT)
820 p = buffer_line(list->file, buffer, width);
829 DEFUN(listing_print,(name),
835 if (listing & LISTING_NOFORM)
840 if (listing & LISTING_LISTING)
842 listing_listing(name);
845 if (listing & LISTING_SYMBOLS)
853 DEFUN(listing_file,(name),
860 DEFUN_VOID(listing_eject)
862 listing_tail->edict = EDICT_EJECT;
866 DEFUN_VOID(listing_flags)
868 while ( (*input_line_pointer++) && (*input_line_pointer != '\n') )
869 input_line_pointer++;
873 DEFUN(listing_list,(on),
876 listing_tail->edict = on ? EDICT_LIST : EDICT_NOLIST;
881 DEFUN_VOID(listing_psize)
883 paper_height = get_absolute_expression();
885 if (paper_height < 0 || paper_height > 1000)
888 as_warn("strange paper height, set to no form");
890 if (*input_line_pointer == ',')
892 input_line_pointer++;
893 paper_width = get_absolute_expression();
899 DEFUN(listing_title,(depth),
907 if (*input_line_pointer=='\"') {
908 input_line_pointer++;
909 start = input_line_pointer;
911 while (*input_line_pointer)
913 if (*input_line_pointer == '\"')
915 length = input_line_pointer - start;
916 title = malloc(length + 1);
917 memcpy(title, start, length);
919 listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
920 listing_tail->edict_arg = title;
921 input_line_pointer++;
922 demand_empty_rest_of_line();
925 else if (*input_line_pointer == '\n')
927 as_bad("New line in title");
928 demand_empty_rest_of_line();
933 input_line_pointer++;
939 as_bad("expecting title in quotes");
946 DEFUN(listing_source_line,(line),
950 listing_tail->hll_line = line;
956 DEFUN(listing_source_file,(file),
959 listing_tail->hll_file = file_info(file);
967 /* Dummy functions for when compiled without listing enabled */
970 DEFUN_VOID(listing_flags)
975 void DEFUN_VOID(listing_list)
980 void DEFUN_VOID(listing_eject)
984 void DEFUN_VOID(listing_psize)
989 void DEFUN(listing_title, (depth),
995 DEFUN(listing_file,(name),
1001 void DEFUN(listing_newline,(name),
1007 void DEFUN(listing_source_line,(n),
1012 void DEFUN(listing_source_file, (n),