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"
100 #ifndef LISTING_HEADER
101 #define LISTING_HEADER "GAS LISTING"
103 #ifndef LISTING_WORD_SIZE
104 #define LISTING_WORD_SIZE 4
106 #ifndef LISTING_LHS_WIDTH
107 #define LISTING_LHS_WIDTH 1
109 #ifndef LISTING_LHS_WIDTH_SECOND
110 #define LISTING_LHS_WIDTH_SECOND 1
112 #ifndef LISTING_RHS_WIDTH
113 #define LISTING_RHS_WIDTH 100
115 #ifndef LISTING_LHS_CONT_LINES
116 #define LISTING_LHS_CONT_LINES 4
122 /* This structure remembers which .s were used */
123 typedef struct file_info_struct
128 struct file_info_struct *next;
132 /* this structure rememebrs which line from which file goes into which
134 typedef struct list_info_struct
136 /* Frag which this line of source is nearest to */
138 /* The actual line in the source file */
140 /* Pointer to the file info struct for the file which this line
142 file_info_type *file;
145 struct list_info_struct *next;
148 /* Pointer to the file info struct for the high level language
149 source line that belongs here */
150 file_info_type *hll_file;
152 /* High level language source line */
153 unsigned int hll_line;
156 /* Pointer to any error message associated with this line */
173 static struct list_info_struct *head;
174 struct list_info_struct *listing_tail;
176 extern unsigned int physical_input_line;
177 extern fragS *frag_now;
180 static int paper_width = 200;
181 static int paper_height = 60;
184 /* this static array is used to keep the text of data to be printed
185 before the start of the line.
186 It is stored so we can give a bit more info on the next line. To much, and large
187 initialized arrays will use up lots of paper.
190 static char data_buffer[100];
191 static unsigned int data_buffer_size;
195 DEFUN(listing_message,(name, message),
199 unsigned int l = strlen(name) + strlen(message)+1;
203 if(listing_tail != (list_info_type *)NULL)
205 listing_tail->message = n;
214 DEFUN(listing_warning,(message),
217 listing_message("Warning:", message);
221 DEFUN(listing_error,(message),
224 listing_message("Error:", message);
230 static file_info_type *file_info_head;
232 static file_info_type *
233 DEFUN(file_info, (file_name),
236 /* Find an entry with this file name */
237 file_info_type *p = file_info_head;
239 while (p != (file_info_type *)NULL)
241 if (strcmp(p->filename, file_name) == 0)
248 p = (file_info_type *)xmalloc(sizeof(file_info_type));
249 p->next = file_info_head;
251 p->filename = xmalloc(strlen(file_name)+1);
252 strcpy(p->filename, file_name);
254 p->file = fopen(p->filename,"r");
270 DEFUN(listing_newline,(ps),
274 extern char *file_name;
275 static unsigned int last_line =0xffff ;
279 if (physical_input_line != last_line)
281 last_line = physical_input_line;
284 new = (list_info_type *)malloc(sizeof(list_info_type));
285 new->frag = frag_now;
286 new->line = physical_input_line ;
287 new->file = file_info(file_name);
291 listing_tail->next = new;
298 new->next = (list_info_type *)NULL;
299 new->message = (char *)NULL;
300 new->edict = EDICT_NONE;
309 DEFUN(buffer_line,(file, line, size),
310 file_info_type *file AND
314 unsigned int count = 0;
318 if (file->file == (FILE*)NULL)
323 c = fgetc(file->file);
324 size -= 1; /* leave room for null */
325 while (c != EOF && c != '\n')
331 c= fgetc(file->file);
347 static unsigned int eject; /* Eject pending */
348 static unsigned int page; /* Current page number */
349 static char *title; /* current title */
350 static char *subtitle; /* current subtitle */
351 static unsigned int on_page; /* number of lines printed on current page */
355 DEFUN(listing_page,(list),
356 list_info_type *list)
358 /* Grope around, see if we can see a title or subtitle edict coming up
359 soon (we look down 10 lines of the page and see if it's there)*/
360 if ((eject || (on_page >= paper_height)) && paper_height != 0)
364 int had_subtitle = 0;
368 while (c != 0 && list)
370 if (list->edict == EDICT_SBTTL && !had_subtitle)
373 subtitle = list->edict_arg;
375 if (list->edict == EDICT_TITLE && !had_title)
378 title = list->edict_arg;
390 printf("%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
391 printf("%s\n", title);
392 printf("%s\n", subtitle);
400 DEFUN(calc_hex,(list),
401 list_info_type *list)
403 list_info_type *first = list;
404 list_info_type *last = first;
405 unsigned int address = ~0;
410 unsigned int byte_in_frag = 0;
414 /* Find first frag which says it belongs to this line */
416 while (frag && frag->line != list)
417 frag = frag->fr_next;
421 data_buffer_size = 0;
423 /* Dump all the frags which belong to this line */
424 while (frag_ptr != (fragS *)NULL && frag_ptr->line == first)
426 /* Print as many bytes from the fixed part as is sensible */
427 while(byte_in_frag < frag_ptr->fr_fix && data_buffer_size < sizeof(data_buffer)-10)
431 address = frag_ptr->fr_address;
434 sprintf(data_buffer + data_buffer_size, "%02X",(frag_ptr->fr_literal[byte_in_frag]) & 0xff);
435 data_buffer_size += 2;
438 /* Print as many bytes from the variable part as is sensible */
439 while (byte_in_frag < frag_ptr->fr_var * frag_ptr->fr_offset
440 && data_buffer_size < sizeof(data_buffer)-10)
444 address = frag_ptr->fr_address;
446 data_buffer[data_buffer_size++] = '*';
447 data_buffer[data_buffer_size++] = '*';
451 frag_ptr = frag_ptr->fr_next;
453 data_buffer[data_buffer_size++] = 0;
463 DEFUN(print_lines,(list, string, address),
464 list_info_type *list AND
466 unsigned int address)
471 unsigned int byte_in_word =0;
472 char *src = data_buffer;
474 /* Print the stuff on the first line */
476 nchars = (LISTING_WORD_SIZE*2 +1) * LISTING_LHS_WIDTH ;
477 /* Print the hex for the first line */
480 printf("% 4d ", list->line);
481 for (idx = 0; idx < nchars; idx++)
484 printf("\t%s\n", string ? string : "");
493 printf("% 4d ???? ", list->line);
497 printf("% 4d %04x ", list->line, address);
500 /* And the data to go along with it */
503 while (*src && idx < nchars)
505 printf("%c%c", src[0], src[1]);
508 if (byte_in_word == LISTING_WORD_SIZE)
517 for (;idx < nchars; idx++)
520 printf("\t%s\n", string ? string : "");
525 printf("**** %s\n",list->message);
531 lines < LISTING_LHS_CONT_LINES
534 nchars = ((LISTING_WORD_SIZE*2) +1) * LISTING_LHS_WIDTH_SECOND -1;
536 /* Print any more lines of data, but more compactly */
537 printf("% 4d ", list->line);
539 while (*src && idx < nchars)
541 printf("%c%c", src[0], src[1]);
545 if (byte_in_word == LISTING_WORD_SIZE)
569 DEFUN_VOID(list_symbol_table)
571 extern symbolS *symbol_rootP;
576 printf("DEFINED SYMBOLS\n");
579 for (ptr = symbol_rootP; ptr != (symbolS*)NULL; ptr = symbol_next(ptr))
581 if (ptr->sy_frag->line)
583 if (strlen(S_GET_NAME(ptr)))
585 printf("%20s:%-5d %2d:%08x %s \n",
586 ptr->sy_frag->line->file->filename,
587 ptr->sy_frag->line->line,
601 printf("UNDEFINED SYMBOLS\n");
605 for (ptr = symbol_rootP; ptr != (symbolS*)NULL; ptr = symbol_next(ptr))
607 if (ptr && strlen(S_GET_NAME(ptr)) != 0)
609 if (ptr->sy_frag->line == 0)
611 printf("%s\n", S_GET_NAME(ptr));
620 DEFUN(print_source,(current_file, list, buffer, width),
621 file_info_type *current_file AND
622 list_info_type *list AND
626 if (current_file->file) {
627 while (current_file->linenum < list->hll_line)
629 char* p = buffer_line(current_file, buffer, width);
630 printf("%4d:%-13s **** %s\n", current_file->linenum, current_file->filename, p);
638 DEFUN(listing_listing,(name),
641 list_info_type *list = head;
642 file_info_type *current_hll_file = (file_info_type *)NULL;
644 unsigned int page= 1;
645 unsigned int prev = 0;
649 unsigned int addr = 0;
651 int show_listing = 1;
654 buffer = malloc(LISTING_RHS_WIDTH);
658 while (list != (list_info_type *)NULL && 0)
661 list->frag = list->next->frag;
671 width = LISTING_RHS_WIDTH > paper_width ? paper_width :
674 switch (list->edict) {
686 title = list->edict_arg;
689 subtitle = list->edict_arg;
695 if (show_listing > 0)
697 /* Scan down the list and print all the stuff which can be done
698 with this line (or lines) */
703 current_hll_file = list->hll_file;
706 if (current_hll_file && list->hll_line && listing & LISTING_HLL)
708 print_source(current_hll_file, list, buffer, width);
711 p = buffer_line(list->file, buffer, width);
713 print_lines(list, p, calc_hex(list));
715 if (list->edict == EDICT_EJECT)
723 p = buffer_line(list->file, buffer, width);
732 DEFUN(listing_print,(name),
738 if (listing & LISTING_NOFORM)
743 if (listing & LISTING_LISTING)
745 listing_listing(name);
748 if (listing & LISTING_SYMBOLS)
756 DEFUN(listing_file,(name),
763 DEFUN_VOID(listing_eject)
765 listing_tail->edict = EDICT_EJECT;
769 DEFUN_VOID(listing_flags)
774 DEFUN(listing_list,(on),
777 listing_tail->edict = on ? EDICT_LIST : EDICT_NOLIST;
782 DEFUN_VOID(listing_psize)
784 paper_height = get_absolute_expression();
786 if (paper_height < 0 || paper_height > 1000)
789 as_warn("strantge paper height, set to no form");
791 if (*input_line_pointer == ',')
793 input_line_pointer++;
794 paper_width = get_absolute_expression();
800 DEFUN(listing_title,(depth),
808 if (*input_line_pointer=='\"') {
809 input_line_pointer++;
810 start = input_line_pointer;
812 while (*input_line_pointer)
814 if (*input_line_pointer == '\"')
816 length = input_line_pointer - start;
817 title = malloc(length + 1);
818 memcpy(title, start, length);
820 listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
821 listing_tail->edict_arg = title;
822 input_line_pointer++;
823 demand_empty_rest_of_line();
826 else if (*input_line_pointer == '\n')
828 as_bad("New line in title");
829 demand_empty_rest_of_line();
834 input_line_pointer++;
840 as_bad("expecting title in quotes");
847 DEFUN(listing_source_line,(line),
851 listing_tail->hll_line = line;
857 DEFUN(listing_source_file,(file),
860 listing_tail->hll_file = file_info(file);
868 /* Dummy functions for when compiled without listing enabled */
871 DEFUN_VOID(listing_flags)
876 void DEFUN_VOID(listing_list)
881 void DEFUN_VOID(listing_eject)
885 void DEFUN(listing_psize)
890 void DEFUN(listing_title, (depth),
896 DEFUN(listing_file,(name),
902 void DEFUN(listing_newline,(name),
908 void DEFUN(listing_source_line,(n),
913 void DEFUN(listing_source_file, (n),