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
97 #include "input-file.h"
103 #ifndef LISTING_HEADER
104 #define LISTING_HEADER "GAS LISTING"
106 #ifndef LISTING_WORD_SIZE
107 #define LISTING_WORD_SIZE 4
109 #ifndef LISTING_LHS_WIDTH
110 #define LISTING_LHS_WIDTH 1
112 #ifndef LISTING_LHS_WIDTH_SECOND
113 #define LISTING_LHS_WIDTH_SECOND 1
115 #ifndef LISTING_RHS_WIDTH
116 #define LISTING_RHS_WIDTH 100
118 #ifndef LISTING_LHS_CONT_LINES
119 #define LISTING_LHS_CONT_LINES 4
125 /* This structure remembers which .s were used */
126 typedef struct file_info_struct
131 struct file_info_struct *next;
137 /* this structure rememebrs which line from which file goes into which
139 typedef struct list_info_struct
141 /* Frag which this line of source is nearest to */
143 /* The actual line in the source file */
145 /* Pointer to the file info struct for the file which this line
147 file_info_type *file;
150 struct list_info_struct *next;
153 /* Pointer to the file info struct for the high level language
154 source line that belongs here */
155 file_info_type *hll_file;
157 /* High level language source line */
161 /* Pointer to any error message associated with this line */
178 static struct list_info_struct *head;
179 struct list_info_struct *listing_tail;
181 extern unsigned int physical_input_line;
182 extern fragS *frag_now;
185 static int paper_width = 200;
186 static int paper_height = 60;
189 /* this static array is used to keep the text of data to be printed
190 before the start of the line.
191 It is stored so we can give a bit more info on the next line. To much, and large
192 initialized arrays will use up lots of paper.
195 static char data_buffer[100];
196 static unsigned int data_buffer_size;
200 DEFUN(listing_message,(name, message),
204 unsigned int l = strlen(name) + strlen(message)+1;
205 char *n = (char*)malloc(l);
208 if(listing_tail != (list_info_type *)NULL)
210 listing_tail->message = n;
219 DEFUN(listing_warning,(message),
222 listing_message("Warning:", message);
226 DEFUN(listing_error,(message),
229 listing_message("Error:", message);
235 static file_info_type *file_info_head;
237 static file_info_type *
238 DEFUN(file_info, (file_name),
241 /* Find an entry with this file name */
242 file_info_type *p = file_info_head;
244 while (p != (file_info_type *)NULL)
246 if (strcmp(p->filename, file_name) == 0)
253 p = (file_info_type *)xmalloc(sizeof(file_info_type));
254 p->next = file_info_head;
256 p->filename = xmalloc(strlen(file_name)+1);
257 strcpy(p->filename, file_name);
261 p->file = fopen(p->filename,"rb");
262 if (p->file) fgetc(p->file);
281 DEFUN(listing_newline,(ps),
285 extern char *file_name;
286 static unsigned int last_line =0xffff ;
290 if (physical_input_line != last_line)
292 last_line = physical_input_line;
295 new = (list_info_type *)malloc(sizeof(list_info_type));
296 new->frag = frag_now;
297 new->line = physical_input_line ;
298 new->file = file_info(file_name);
302 listing_tail->next = new;
309 new->next = (list_info_type *)NULL;
310 new->message = (char *)NULL;
311 new->edict = EDICT_NONE;
312 new->hll_file = (file_info_type*)NULL;
320 This function returns the next source line from the file supplied,
321 truncated to size. It appends a fake line to the end of each input
326 DEFUN(buffer_line,(file, line, size),
327 file_info_type *file AND
331 unsigned int count = 0;
336 /* If we couldn't open the file, return an empty line */
337 if (file->file == (FILE*)NULL)
342 if (file->end_pending == 10) {
344 fseek(file->file, 0,0 );
346 file->end_pending = 0;
348 c = fgetc(file->file);
351 size -= 1; /* leave room for null */
353 while (c != EOF && c != '\n')
359 c= fgetc(file->file);
364 file->end_pending ++;
377 static unsigned int eject; /* Eject pending */
378 static unsigned int page; /* Current page number */
379 static char *title; /* current title */
380 static char *subtitle; /* current subtitle */
381 static unsigned int on_page; /* number of lines printed on current page */
385 DEFUN(listing_page,(list),
386 list_info_type *list)
388 /* Grope around, see if we can see a title or subtitle edict coming up
389 soon (we look down 10 lines of the page and see if it's there)*/
390 if ((eject || (on_page >= paper_height)) && paper_height != 0)
394 int had_subtitle = 0;
398 while (c != 0 && list)
400 if (list->edict == EDICT_SBTTL && !had_subtitle)
403 subtitle = list->edict_arg;
405 if (list->edict == EDICT_TITLE && !had_title)
408 title = list->edict_arg;
420 printf("%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
421 printf("%s\n", title);
422 printf("%s\n", subtitle);
430 DEFUN(calc_hex,(list),
431 list_info_type *list)
433 list_info_type *first = list;
434 list_info_type *last = first;
435 unsigned int address = ~0;
440 unsigned int byte_in_frag = 0;
444 /* Find first frag which says it belongs to this line */
446 while (frag && frag->line != list)
447 frag = frag->fr_next;
451 data_buffer_size = 0;
453 /* Dump all the frags which belong to this line */
454 while (frag_ptr != (fragS *)NULL && frag_ptr->line == first)
456 /* Print as many bytes from the fixed part as is sensible */
457 while(byte_in_frag < frag_ptr->fr_fix && data_buffer_size < sizeof(data_buffer)-10)
461 address = frag_ptr->fr_address;
464 sprintf(data_buffer + data_buffer_size,
466 (frag_ptr->fr_literal[byte_in_frag]) & 0xff);
467 data_buffer_size += 2;
471 unsigned int var_rep_max = byte_in_frag;
472 unsigned int var_rep_idx = byte_in_frag;
474 /* Print as many bytes from the variable part as is sensible */
475 while (byte_in_frag < frag_ptr->fr_var * frag_ptr->fr_offset
476 && data_buffer_size < sizeof(data_buffer)-10)
480 address = frag_ptr->fr_address;
482 sprintf(data_buffer + data_buffer_size,
484 (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
486 data_buffer[data_buffer_size++] = '*';
487 data_buffer[data_buffer_size++] = '*';
489 data_buffer_size +=2;
494 if (var_rep_idx >= frag_ptr->fr_var)
495 var_rep_idx = var_rep_max;
499 frag_ptr = frag_ptr->fr_next;
501 data_buffer[data_buffer_size++] = 0;
511 DEFUN(print_lines,(list, string, address),
512 list_info_type *list AND
514 unsigned int address)
519 unsigned int byte_in_word =0;
520 char *src = data_buffer;
522 /* Print the stuff on the first line */
524 nchars = (LISTING_WORD_SIZE*2 +1) * LISTING_LHS_WIDTH ;
525 /* Print the hex for the first line */
528 printf("% 4d ", list->line);
529 for (idx = 0; idx < nchars; idx++)
532 printf("\t%s\n", string ? string : "");
541 printf("% 4d ???? ", list->line);
545 printf("% 4d %04x ", list->line, address);
548 /* And the data to go along with it */
551 while (*src && idx < nchars)
553 printf("%c%c", src[0], src[1]);
556 if (byte_in_word == LISTING_WORD_SIZE)
565 for (;idx < nchars; idx++)
568 printf("\t%s\n", string ? string : "");
573 printf("**** %s\n",list->message);
579 lines < LISTING_LHS_CONT_LINES
582 nchars = ((LISTING_WORD_SIZE*2) +1) * LISTING_LHS_WIDTH_SECOND -1;
584 /* Print any more lines of data, but more compactly */
585 printf("% 4d ", list->line);
587 while (*src && idx < nchars)
589 printf("%c%c", src[0], src[1]);
593 if (byte_in_word == LISTING_WORD_SIZE)
617 DEFUN_VOID(list_symbol_table)
619 extern symbolS *symbol_rootP;
624 printf("DEFINED SYMBOLS\n");
627 for (ptr = symbol_rootP; ptr != (symbolS*)NULL; ptr = symbol_next(ptr))
629 if (ptr->sy_frag->line)
634 if (strlen(S_GET_NAME(ptr)))
636 printf("%20s:%-5d %2d:%08x %s \n",
637 ptr->sy_frag->line->file->filename,
638 ptr->sy_frag->line->line,
646 printf("%20s:%-5d %2d:%08x\n",
647 ptr->sy_frag->line->file->filename,
648 ptr->sy_frag->line->line,
664 printf("UNDEFINED SYMBOLS\n");
668 for (ptr = symbol_rootP; ptr != (symbolS*)NULL; ptr = symbol_next(ptr))
670 if (S_GET_NAME(ptr) && strlen(S_GET_NAME(ptr)) != 0)
672 if (ptr->sy_frag->line == 0)
674 printf("%s\n", S_GET_NAME(ptr));
683 DEFUN(print_source,(current_file, list, buffer, width),
684 file_info_type *current_file AND
685 list_info_type *list AND
689 if (current_file->file) {
690 while (current_file->linenum < list->hll_line)
692 char * p = buffer_line(current_file, buffer, width);
693 printf("%4d:%-13s **** %s\n", current_file->linenum, current_file->filename, p);
700 /* Sometimes the user doesn't want to be bothered by the debugging
701 records inserted by the compiler, see if the line is suspicioous */
704 DEFUN(debugging_pseudo,(line),
707 while (isspace(*line))
710 if(*line != '.') return 0;
714 if (strncmp(line, "def",3) == 0) return 1;
715 if (strncmp(line, "val",3) == 0) return 1;
716 if (strncmp(line, "scl",3) == 0) return 1;
717 if (strncmp(line, "line",4) == 0) return 1;
718 if (strncmp(line, "endef",5) == 0) return 1;
719 if (strncmp(line, "ln",2) ==0) return 1;
720 if (strncmp(line, "type",4) ==0) return 1;
721 if (strncmp(line, "size",4) == 0) return 1;
722 if (strncmp(line, "dim",3) ==0) return 1;
723 if (strncmp(line, "tag",3) == 0) return 1;
730 DEFUN(listing_listing,(name),
733 list_info_type *list = head;
734 file_info_type *current_hll_file = (file_info_type *)NULL;
736 unsigned int page= 1;
737 unsigned int prev = 0;
741 unsigned int addr = 0;
743 int show_listing = 1;
746 buffer = malloc(LISTING_RHS_WIDTH);
750 while (list != (list_info_type *)NULL && 0)
753 list->frag = list->next->frag;
763 width = LISTING_RHS_WIDTH > paper_width ? paper_width :
766 switch (list->edict) {
778 title = list->edict_arg;
781 subtitle = list->edict_arg;
787 if (show_listing > 0)
789 /* Scan down the list and print all the stuff which can be done
790 with this line (or lines) */
795 current_hll_file = list->hll_file;
798 if (current_hll_file && list->hll_line && listing & LISTING_HLL)
800 print_source(current_hll_file, list, buffer, width);
803 p = buffer_line(list->file, buffer, width);
805 if (! ((listing & LISTING_NODEBUG) && debugging_pseudo(p)))
807 print_lines(list, p, calc_hex(list));
810 if (list->edict == EDICT_EJECT)
818 p = buffer_line(list->file, buffer, width);
827 DEFUN(listing_print,(name),
833 if (listing & LISTING_NOFORM)
838 if (listing & LISTING_LISTING)
840 listing_listing(name);
843 if (listing & LISTING_SYMBOLS)
851 DEFUN(listing_file,(name),
858 DEFUN_VOID(listing_eject)
860 listing_tail->edict = EDICT_EJECT;
864 DEFUN_VOID(listing_flags)
869 DEFUN(listing_list,(on),
872 listing_tail->edict = on ? EDICT_LIST : EDICT_NOLIST;
877 DEFUN_VOID(listing_psize)
879 paper_height = get_absolute_expression();
881 if (paper_height < 0 || paper_height > 1000)
884 as_warn("strange paper height, set to no form");
886 if (*input_line_pointer == ',')
888 input_line_pointer++;
889 paper_width = get_absolute_expression();
895 DEFUN(listing_title,(depth),
903 if (*input_line_pointer=='\"') {
904 input_line_pointer++;
905 start = input_line_pointer;
907 while (*input_line_pointer)
909 if (*input_line_pointer == '\"')
911 length = input_line_pointer - start;
912 title = malloc(length + 1);
913 memcpy(title, start, length);
915 listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
916 listing_tail->edict_arg = title;
917 input_line_pointer++;
918 demand_empty_rest_of_line();
921 else if (*input_line_pointer == '\n')
923 as_bad("New line in title");
924 demand_empty_rest_of_line();
929 input_line_pointer++;
935 as_bad("expecting title in quotes");
942 DEFUN(listing_source_line,(line),
946 listing_tail->hll_line = line;
952 DEFUN(listing_source_file,(file),
955 listing_tail->hll_file = file_info(file);
963 /* Dummy functions for when compiled without listing enabled */
966 DEFUN_VOID(listing_flags)
971 void DEFUN_VOID(listing_list)
976 void DEFUN_VOID(listing_eject)
980 void DEFUN(listing_psize)
985 void DEFUN(listing_title, (depth),
991 DEFUN(listing_file,(name),
997 void DEFUN(listing_newline,(name),
1003 void DEFUN(listing_source_line,(n),
1008 void DEFUN(listing_source_file, (n),