70b28b91eb2388249324d7656b31b2f428c10ff9
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 printf("%20s:%-5d %2d:%08x %s \n",
584 ptr
->sy_frag
->line
->file
->filename
,
585 ptr
->sy_frag
->line
->line
,
598 printf("UNDEFINED SYMBOLS\n");
602 for (ptr
= symbol_rootP
; ptr
!= (symbolS
*)NULL
; ptr
= symbol_next(ptr
))
604 if (strlen(S_GET_NAME(ptr
)) != 0)
606 if (ptr
->sy_frag
->line
== 0)
609 printf("%s\n", S_GET_NAME(ptr
));
618 DEFUN(print_source
,(current_file
, list
, buffer
, width
),
619 file_info_type
*current_file AND
620 list_info_type
*list AND
624 if (current_file
->file
) {
625 while (current_file
->linenum
< list
->hll_line
)
627 char* p
= buffer_line(current_file
, buffer
, width
);
628 printf("%4d:%-13s **** %s\n", current_file
->linenum
, current_file
->filename
, p
);
636 DEFUN(listing_listing
,(name
),
639 list_info_type
*list
= head
;
640 file_info_type
*current_hll_file
= (file_info_type
*)NULL
;
642 unsigned int page
= 1;
643 unsigned int prev
= 0;
647 unsigned int addr
= 0;
649 int show_listing
= 1;
652 buffer
= malloc(LISTING_RHS_WIDTH
);
656 while (list
!= (list_info_type
*)NULL
&& 0)
659 list
->frag
= list
->next
->frag
;
669 width
= LISTING_RHS_WIDTH
> paper_width
? paper_width
:
672 switch (list
->edict
) {
684 title
= list
->edict_arg
;
687 subtitle
= list
->edict_arg
;
693 if (show_listing
> 0)
695 /* Scan down the list and print all the stuff which can be done
696 with this line (or lines) */
701 current_hll_file
= list
->hll_file
;
704 if (current_hll_file
&& list
->hll_line
&& listing
& LISTING_HLL
)
706 print_source(current_hll_file
, list
, buffer
, width
);
709 p
= buffer_line(list
->file
, buffer
, width
);
711 print_lines(list
, p
, calc_hex(list
));
713 if (list
->edict
== EDICT_EJECT
)
721 p
= buffer_line(list
->file
, buffer
, width
);
730 DEFUN(listing_print
,(name
),
736 if (listing
& LISTING_NOFORM
)
741 if (listing
& LISTING_LISTING
)
743 listing_listing(name
);
746 if (listing
& LISTING_SYMBOLS
)
754 DEFUN(listing_file
,(name
),
761 DEFUN_VOID(listing_eject
)
763 listing_tail
->edict
= EDICT_EJECT
;
767 DEFUN_VOID(listing_flags
)
772 DEFUN(listing_list
,(on
),
775 listing_tail
->edict
= on
? EDICT_LIST
: EDICT_NOLIST
;
780 DEFUN_VOID(listing_psize
)
782 paper_height
= get_absolute_expression();
784 if (paper_height
< 0 || paper_height
> 1000)
787 as_warn("strantge paper height, set to no form");
789 if (*input_line_pointer
== ',')
791 input_line_pointer
++;
792 paper_width
= get_absolute_expression();
798 DEFUN(listing_title
,(depth
),
806 if (*input_line_pointer
=='\"') {
807 input_line_pointer
++;
808 start
= input_line_pointer
;
810 while (*input_line_pointer
)
812 if (*input_line_pointer
== '\"')
814 length
= input_line_pointer
- start
;
815 title
= malloc(length
+ 1);
816 memcpy(title
, start
, length
);
818 listing_tail
->edict
= depth
? EDICT_SBTTL
: EDICT_TITLE
;
819 listing_tail
->edict_arg
= title
;
820 input_line_pointer
++;
821 demand_empty_rest_of_line();
824 else if (*input_line_pointer
== '\n')
826 as_bad("New line in title");
827 demand_empty_rest_of_line();
832 input_line_pointer
++;
838 as_bad("expecting title in quotes");
845 DEFUN(listing_source_line
,(line
),
849 listing_tail
->hll_line
= line
;
855 DEFUN(listing_source_file
,(file
),
858 listing_tail
->hll_file
= file_info(file
);
866 /* Dummy functions for when compiled without listing enabled */
869 DEFUN_VOID(listing_flags
)
874 void DEFUN_VOID(listing_list
)
879 void DEFUN_VOID(listing_eject
)
883 void DEFUN(listing_psize
)
888 void DEFUN(listing_title
, (depth
),
894 DEFUN(listing_file
,(name
),
900 void DEFUN(listing_newline
,(name
),
906 void DEFUN(listing_source_line
,(n
),
911 void DEFUN(listing_source_file
, (n
),
This page took 0.048696 seconds and 4 git commands to generate.