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 files 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 any error message associated with this line */
165 static struct list_info_struct
*head
;
166 struct list_info_struct
*listing_tail
;
168 extern unsigned int physical_input_line
;
169 extern fragS
*frag_now
;
172 static int paper_width
= 200;
173 static int paper_height
= 60;
176 /* this static array is used to keep the text of data to be printed
177 before the start of the line.
178 It is stored so we can give a bit more info on the next line. To much, and large
179 initialized arrays will use up lots of paper.
182 static char data_buffer
[100];
183 static unsigned int data_buffer_size
;
187 DEFUN(listing_message
,(name
, message
),
191 unsigned int l
= strlen(name
) + strlen(message
)+1;
195 if(listing_tail
!= (list_info_type
*)NULL
)
197 listing_tail
->message
= n
;
206 DEFUN(listing_warning
,(message
),
209 listing_message("Warning:", message
);
213 DEFUN(listing_error
,(message
),
216 listing_message("Error:", message
);
221 extern char *file_name
;
222 static file_info_type
*file_info_head
;
224 static file_info_type
*
225 DEFUN_VOID(file_info
)
227 /* Find an entry with this file name */
228 file_info_type
*p
= file_info_head
;
230 while (p
!= (file_info_type
*)NULL
)
232 if (strcmp(p
->filename
, file_name
) == 0)
239 p
= (file_info_type
*)xmalloc(sizeof(file_info_type
));
240 p
->next
= file_info_head
;
242 p
->filename
= xmalloc(strlen(file_name
)+1);
243 strcpy(p
->filename
, file_name
);
245 p
->file
= fopen(p
->filename
,"r");
252 DEFUN(listing_newline
,(ps
),
257 static unsigned int last_line
=0xffff ;
261 if (physical_input_line
!= last_line
)
263 last_line
= physical_input_line
;
266 new = (list_info_type
*)malloc(sizeof(list_info_type
));
267 new->frag
= frag_now
;
268 new->line
= physical_input_line
;
269 new->file
= file_info();
273 listing_tail
->next
= new;
280 new->next
= (list_info_type
*)NULL
;
281 new->message
= (char *)NULL
;
282 new->edict
= EDICT_NONE
;
292 DEFUN(buffer_line
,(ptr
,line
, size
),
293 list_info_type
*ptr AND
297 unsigned int count
= 0;
299 int c
= fgetc(ptr
->file
->file
);
300 size
-= 1; /* leave room for null */
301 while (c
!= EOF
&& c
!= '\n')
307 c
= fgetc(ptr
->file
->file
);
311 rewind(ptr
->file
->file
);
321 static unsigned int eject
; /* Eject pending */
322 static unsigned int page
; /* Current page number */
323 static char *title
; /* current title */
324 static char *subtitle
; /* current subtitle */
325 static unsigned int on_page
; /* number of lines printed on current page */
329 DEFUN(listing_page
,(list
),
330 list_info_type
*list
)
332 /* Grope around, see if we can see a title or subtitle edict coming up
333 soon (we look down 10 lines of the page and see if it's there)*/
334 if ((eject
|| (on_page
>= paper_height
)) && paper_height
!= 0)
338 int had_subtitle
= 0;
342 while (c
!= 0 && list
)
344 if (list
->edict
== EDICT_SBTTL
&& !had_subtitle
)
347 subtitle
= list
->edict_arg
;
349 if (list
->edict
== EDICT_TITLE
&& !had_title
)
352 title
= list
->edict_arg
;
364 printf("%s %s \t\t\tpage %d\n", LISTING_HEADER
, fn
, page
);
365 printf("%s\n", title
);
366 printf("%s\n", subtitle
);
374 DEFUN(calc_hex
,(list
),
375 list_info_type
*list
)
377 list_info_type
*first
= list
;
378 list_info_type
*last
= first
;
379 unsigned int address
= ~0;
384 unsigned int byte_in_frag
= 0;
388 /* Find first frag which says it belongs to this line */
390 while (frag
&& frag
->line
!= list
)
391 frag
= frag
->fr_next
;
395 data_buffer_size
= 0;
397 /* Dump all the frags which belong to this line */
398 while (frag_ptr
!= (fragS
*)NULL
&& frag_ptr
->line
== first
)
400 /* Print as many bytes from the fixed part as is sensible */
401 while(byte_in_frag
< frag_ptr
->fr_fix
&& data_buffer_size
< sizeof(data_buffer
)-10)
405 address
= frag_ptr
->fr_address
;
408 sprintf(data_buffer
+ data_buffer_size
, "%02X",(frag_ptr
->fr_literal
[byte_in_frag
]) & 0xff);
409 data_buffer_size
+= 2;
412 /* Print as many bytes from the variable part as is sensible */
413 while (byte_in_frag
< frag_ptr
->fr_var
* frag_ptr
->fr_offset
414 && data_buffer_size
< sizeof(data_buffer
)-10)
418 address
= frag_ptr
->fr_address
;
420 data_buffer
[data_buffer_size
++] = '*';
421 data_buffer
[data_buffer_size
++] = '*';
425 frag_ptr
= frag_ptr
->fr_next
;
427 data_buffer
[data_buffer_size
++] = 0;
437 DEFUN(print_lines
,(list
, string
, address
),
438 list_info_type
*list AND
440 unsigned int address
)
445 unsigned int byte_in_word
=0;
446 char *src
= data_buffer
;
448 /* Print the stuff on the first line */
450 nchars
= (LISTING_WORD_SIZE
*2 +1) * LISTING_LHS_WIDTH
;
451 /* Print the hex for the first line */
454 printf("% 4d ", list
->line
);
455 for (idx
= 0; idx
< nchars
; idx
++)
458 printf("\t%s\n", string
? string
: "");
467 printf("% 4d ???? ", list
->line
);
471 printf("% 4d %04x ", list
->line
, address
);
474 /* And the data to go along with it */
477 while (*src
&& idx
< nchars
)
479 printf("%c%c", src
[0], src
[1]);
482 if (byte_in_word
== LISTING_WORD_SIZE
)
491 for (;idx
< nchars
; idx
++)
494 printf("\t%s\n", string
? string
: "");
499 printf("**** %s\n",list
->message
);
505 lines
< LISTING_LHS_CONT_LINES
508 nchars
= ((LISTING_WORD_SIZE
*2) +1) * LISTING_LHS_WIDTH_SECOND
-1;
510 /* Print any more lines of data, but more compactly */
511 printf("% 4d ", list
->line
);
513 while (*src
&& idx
< nchars
)
515 printf("%c%c", src
[0], src
[1]);
519 if (byte_in_word
== LISTING_WORD_SIZE
)
543 DEFUN_VOID(list_symbol_table
)
545 extern symbolS
*symbol_rootP
;
550 printf("DEFINED SYMBOLS\n");
553 for (ptr
= symbol_rootP
; ptr
!= (symbolS
*)NULL
; ptr
= symbol_next(ptr
))
555 if (ptr
->sy_frag
->line
)
557 printf("%20s:%-5d %2d:%08x %s \n",
558 ptr
->sy_frag
->line
->file
->filename
,
559 ptr
->sy_frag
->line
->line
,
572 printf("UNDEFINED SYMBOLS\n");
576 for (ptr
= symbol_rootP
; ptr
!= (symbolS
*)NULL
; ptr
= symbol_next(ptr
))
578 if (ptr
->sy_frag
->line
== 0)
581 printf("%s\n", S_GET_NAME(ptr
));
590 DEFUN(listing_listing
,(name
),
593 list_info_type
*list
= head
;
594 unsigned int page
= 1;
595 unsigned int prev
= 0;
599 unsigned int addr
= 0;
601 int show_listing
= 1;
603 buffer
= malloc(LISTING_RHS_WIDTH
);
607 while (list
!= (list_info_type
*)NULL
&& 0)
610 list
->frag
= list
->next
->frag
;
620 p
= buffer_line(list
, buffer
, LISTING_RHS_WIDTH
> paper_width
?
621 paper_width
: LISTING_RHS_WIDTH
);
623 switch (list
->edict
) {
635 title
= list
->edict_arg
;
638 subtitle
= list
->edict_arg
;
644 if (show_listing
> 0)
646 /* Scan down the list and print all the stuff which can be done
647 with this line (or lines) */
651 print_lines(list
, p
, calc_hex(list
));
653 if (list
->edict
== EDICT_EJECT
)
664 DEFUN(listing_print
,(name
),
670 if (listing
& LISTING_NOFORM
)
675 if (listing
& LISTING_LISTING
)
677 listing_listing(name
);
680 if (listing
& LISTING_SYMBOLS
)
688 DEFUN(listing_file
,(name
),
695 DEFUN_VOID(listing_eject
)
697 listing_tail
->edict
= EDICT_EJECT
;
701 DEFUN_VOID(listing_flags
)
706 DEFUN(listing_list
,(on
),
709 listing_tail
->edict
= on
? EDICT_LIST
: EDICT_NOLIST
;
714 DEFUN_VOID(listing_psize
)
716 paper_height
= get_absolute_expression();
718 if (paper_height
< 0 || paper_height
> 1000)
721 as_warn("strantge paper height, set to no form");
723 if (*input_line_pointer
== ',')
725 input_line_pointer
++;
726 paper_width
= get_absolute_expression();
732 DEFUN(listing_title
,(depth
),
740 if (*input_line_pointer
=='\"') {
741 input_line_pointer
++;
742 start
= input_line_pointer
;
744 while (*input_line_pointer
)
746 if (*input_line_pointer
== '\"')
748 length
= input_line_pointer
- start
;
749 title
= malloc(length
+ 1);
750 memcpy(title
, start
, length
);
752 listing_tail
->edict
= depth
? EDICT_SBTTL
: EDICT_TITLE
;
753 listing_tail
->edict_arg
= title
;
754 input_line_pointer
++;
755 demand_empty_rest_of_line();
758 else if (*input_line_pointer
== '\n')
760 as_bad("New line in title");
761 demand_empty_rest_of_line();
766 input_line_pointer
++;
772 as_bad("expecting title in quotes");
780 /* Dummy functions for when compiled without listing enabled */
783 DEFUN_VOID(listing_flags
)
788 void DEFUN_VOID(listing_list
)
793 void DEFUN_VOID(listing_eject
)
797 void DEFUN(listing_psize
)
802 void DEFUN(listing_title
, (depth
),
808 DEFUN(listing_file
,(name
),
814 void DEFUN(listing_newline
,(name
),