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
98 #include "input-file.h"
101 #ifndef LISTING_HEADER
102 #define LISTING_HEADER "GAS LISTING"
104 #ifndef LISTING_WORD_SIZE
105 #define LISTING_WORD_SIZE 4
107 #ifndef LISTING_LHS_WIDTH
108 #define LISTING_LHS_WIDTH 1
110 #ifndef LISTING_LHS_WIDTH_SECOND
111 #define LISTING_LHS_WIDTH_SECOND 1
113 #ifndef LISTING_RHS_WIDTH
114 #define LISTING_RHS_WIDTH 100
116 #ifndef LISTING_LHS_CONT_LINES
117 #define LISTING_LHS_CONT_LINES 4
123 /* This structure remembers which .s were used */
124 typedef struct file_info_struct
129 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 */
180 static struct list_info_struct
*head
;
181 struct list_info_struct
*listing_tail
;
183 extern unsigned int physical_input_line
;
184 extern fragS
*frag_now
;
187 static int paper_width
= 200;
188 static int paper_height
= 60;
191 /* this static array is used to keep the text of data to be printed
192 before the start of the line.
193 It is stored so we can give a bit more info on the next line. To much, and large
194 initialized arrays will use up lots of paper.
197 static char data_buffer
[100];
198 static unsigned int data_buffer_size
;
202 static void listing_message
PARAMS ((const char *name
, const char *message
));
203 static file_info_type
*file_info
PARAMS ((const char *file_name
));
204 static void new_frag
PARAMS ((void));
205 static char *buffer_line
PARAMS ((file_info_type
*file
,
206 char *line
, unsigned int size
));
207 static void listing_page
PARAMS ((list_info_type
*list
));
208 static unsigned int calc_hex
PARAMS ((list_info_type
*list
));
209 static void print_lines
PARAMS ((list_info_type
*list
,
211 unsigned int address
));
212 static void list_symbol_table
PARAMS ((void));
213 static void print_source
PARAMS ((file_info_type
*current_file
,
214 list_info_type
*list
,
216 unsigned int width
));
217 static int debugging_pseudo
PARAMS ((char *line
));
218 static void listing_listing
PARAMS ((char *name
));
222 listing_message (name
, message
)
226 unsigned int l
= strlen (name
) + strlen (message
) + 1;
227 char *n
= (char *) xmalloc (l
);
230 if (listing_tail
!= (list_info_type
*) NULL
)
232 listing_tail
->message
= n
;
241 listing_warning (message
)
244 listing_message ("Warning:", message
);
248 listing_error (message
)
251 listing_message ("Error:", message
);
257 static file_info_type
*file_info_head
;
259 static file_info_type
*
260 file_info (file_name
)
261 const char *file_name
;
263 /* Find an entry with this file name */
264 file_info_type
*p
= file_info_head
;
266 while (p
!= (file_info_type
*) NULL
)
268 if (strcmp (p
->filename
, file_name
) == 0)
275 p
= (file_info_type
*) xmalloc (sizeof (file_info_type
));
276 p
->next
= file_info_head
;
278 p
->filename
= xmalloc (strlen (file_name
) + 1);
279 strcpy (p
->filename
, file_name
);
283 p
->file
= fopen (p
->filename
, "rb");
295 frag_wane (frag_now
);
304 extern char *file_name
;
305 static unsigned int last_line
= 0xffff;
309 if (physical_input_line
!= last_line
)
311 last_line
= physical_input_line
;
314 new = (list_info_type
*) xmalloc (sizeof (list_info_type
));
315 new->frag
= frag_now
;
316 new->line
= physical_input_line
;
317 new->file
= file_info (file_name
);
321 listing_tail
->next
= new;
328 new->next
= (list_info_type
*) NULL
;
329 new->message
= (char *) NULL
;
330 new->edict
= EDICT_NONE
;
331 new->hll_file
= (file_info_type
*) NULL
;
339 This function returns the next source line from the file supplied,
340 truncated to size. It appends a fake line to the end of each input
345 buffer_line (file
, line
, size
)
346 file_info_type
* file
;
350 unsigned int count
= 0;
355 /* If we couldn't open the file, return an empty line */
356 if (file
->file
== (FILE *) NULL
)
361 if (file
->linenum
== 0)
364 if (file
->end_pending
== 10)
367 fseek (file
->file
, 0, 0);
369 file
->end_pending
= 0;
371 c
= fgetc (file
->file
);
374 size
-= 1; /* leave room for null */
376 while (c
!= EOF
&& c
!= '\n')
382 c
= fgetc (file
->file
);
398 static const char *fn
;
400 static unsigned int eject
; /* Eject pending */
401 static unsigned int page
; /* Current page number */
402 static char *title
; /* current title */
403 static char *subtitle
; /* current subtitle */
404 static unsigned int on_page
; /* number of lines printed on current page */
409 list_info_type
*list
;
411 /* Grope around, see if we can see a title or subtitle edict coming up
412 soon (we look down 10 lines of the page and see if it's there)*/
413 if ((eject
|| (on_page
>= paper_height
)) && paper_height
!= 0)
417 int had_subtitle
= 0;
421 while (c
!= 0 && list
)
423 if (list
->edict
== EDICT_SBTTL
&& !had_subtitle
)
426 subtitle
= list
->edict_arg
;
428 if (list
->edict
== EDICT_TITLE
&& !had_title
)
431 title
= list
->edict_arg
;
443 printf ("%s %s \t\t\tpage %d\n", LISTING_HEADER
, fn
, page
);
444 printf ("%s\n", title
);
445 printf ("%s\n", subtitle
);
454 list_info_type
* list
;
456 list_info_type
*first
= list
;
457 unsigned int address
= ~0;
462 unsigned int byte_in_frag
= 0;
465 /* Find first frag which says it belongs to this line */
467 while (frag
&& frag
->line
!= list
)
468 frag
= frag
->fr_next
;
472 data_buffer_size
= 0;
474 /* Dump all the frags which belong to this line */
475 while (frag_ptr
!= (fragS
*) NULL
&& frag_ptr
->line
== first
)
477 /* Print as many bytes from the fixed part as is sensible */
478 while (byte_in_frag
< frag_ptr
->fr_fix
&& data_buffer_size
< sizeof (data_buffer
) - 10)
482 address
= frag_ptr
->fr_address
;
485 sprintf (data_buffer
+ data_buffer_size
,
487 (frag_ptr
->fr_literal
[byte_in_frag
]) & 0xff);
488 data_buffer_size
+= 2;
492 unsigned int var_rep_max
= byte_in_frag
;
493 unsigned int var_rep_idx
= byte_in_frag
;
495 /* Print as many bytes from the variable part as is sensible */
496 while (byte_in_frag
< frag_ptr
->fr_var
* frag_ptr
->fr_offset
497 && data_buffer_size
< sizeof (data_buffer
) - 10)
501 address
= frag_ptr
->fr_address
;
503 sprintf (data_buffer
+ data_buffer_size
,
505 (frag_ptr
->fr_literal
[var_rep_idx
]) & 0xff);
507 data_buffer
[data_buffer_size
++] = '*';
508 data_buffer
[data_buffer_size
++] = '*';
510 data_buffer_size
+= 2;
515 if (var_rep_idx
>= frag_ptr
->fr_var
)
516 var_rep_idx
= var_rep_max
;
520 frag_ptr
= frag_ptr
->fr_next
;
522 data_buffer
[data_buffer_size
++] = 0;
532 print_lines (list
, string
, address
)
533 list_info_type
*list
;
535 unsigned int address
;
540 unsigned int byte_in_word
= 0;
541 char *src
= data_buffer
;
543 /* Print the stuff on the first line */
545 nchars
= (LISTING_WORD_SIZE
* 2 + 1) * LISTING_LHS_WIDTH
;
546 /* Print the hex for the first line */
549 printf ("% 4d ", list
->line
);
550 for (idx
= 0; idx
< nchars
; idx
++)
553 printf ("\t%s\n", string
? string
: "");
562 printf ("% 4d ???? ", list
->line
);
566 printf ("% 4d %04x ", list
->line
, address
);
569 /* And the data to go along with it */
572 while (*src
&& idx
< nchars
)
574 printf ("%c%c", src
[0], src
[1]);
577 if (byte_in_word
== LISTING_WORD_SIZE
)
586 for (; idx
< nchars
; idx
++)
589 printf ("\t%s\n", string
? string
: "");
594 printf ("**** %s\n", list
->message
);
600 lines
< LISTING_LHS_CONT_LINES
604 nchars
= ((LISTING_WORD_SIZE
* 2) + 1) * LISTING_LHS_WIDTH_SECOND
- 1;
606 /* Print any more lines of data, but more compactly */
607 printf ("% 4d ", list
->line
);
609 while (*src
&& idx
< nchars
)
611 printf ("%c%c", src
[0], src
[1]);
615 if (byte_in_word
== LISTING_WORD_SIZE
)
637 extern symbolS
*symbol_rootP
;
642 printf ("DEFINED SYMBOLS\n");
645 for (ptr
= symbol_rootP
; ptr
!= (symbolS
*) NULL
; ptr
= symbol_next (ptr
))
647 if (ptr
->sy_frag
->line
)
649 if (S_GET_NAME (ptr
))
652 valueT val
= S_GET_VALUE (ptr
);
654 /* @@ Note that this is dependent on the compilation options,
655 not solely on the target characteristics. */
656 if (sizeof (val
) == 4 && sizeof (int) == 4)
657 sprintf (buf
, "%08lx", (unsigned long) val
);
658 #if defined (BFD_ASSEMBLER) && defined (BFD64)
659 else if (sizeof (val
) > 4)
662 sprintf_vma (buf1
, val
);
663 strcpy (buf
, "00000000");
664 strcpy (buf
+ 8 - strlen (buf1
), buf1
);
670 printf ("%20s:%-5d %s:%s %s\n",
671 ptr
->sy_frag
->line
->file
->filename
,
672 ptr
->sy_frag
->line
->line
,
673 segment_name (S_GET_SEGMENT (ptr
)),
674 buf
, S_GET_NAME (ptr
));
685 printf ("UNDEFINED SYMBOLS\n");
689 for (ptr
= symbol_rootP
; ptr
!= (symbolS
*) NULL
; ptr
= symbol_next (ptr
))
691 if (S_GET_NAME (ptr
) && strlen (S_GET_NAME (ptr
)) != 0)
693 if (ptr
->sy_frag
->line
== 0)
695 printf ("%s\n", S_GET_NAME (ptr
));
704 print_source (current_file
, list
, buffer
, width
)
705 file_info_type
*current_file
;
706 list_info_type
*list
;
710 if (current_file
->file
)
712 while (current_file
->linenum
< list
->hll_line
)
714 char *p
= buffer_line (current_file
, buffer
, width
);
715 printf ("%4d:%-13s **** %s\n", current_file
->linenum
, current_file
->filename
, p
);
722 /* Sometimes the user doesn't want to be bothered by the debugging
723 records inserted by the compiler, see if the line is suspicious */
726 debugging_pseudo (line
)
729 while (isspace (*line
))
737 if (strncmp (line
, "def", 3) == 0)
739 if (strncmp (line
, "val", 3) == 0)
741 if (strncmp (line
, "scl", 3) == 0)
743 if (strncmp (line
, "line", 4) == 0)
745 if (strncmp (line
, "endef", 5) == 0)
747 if (strncmp (line
, "ln", 2) == 0)
749 if (strncmp (line
, "type", 4) == 0)
751 if (strncmp (line
, "size", 4) == 0)
753 if (strncmp (line
, "dim", 3) == 0)
755 if (strncmp (line
, "tag", 3) == 0)
758 if (strncmp (line
, "stabs", 5) == 0)
760 if (strncmp (line
, "stabn", 5) == 0)
768 listing_listing (name
)
771 list_info_type
*list
= head
;
772 file_info_type
*current_hll_file
= (file_info_type
*) NULL
;
776 int show_listing
= 1;
779 buffer
= xmalloc (LISTING_RHS_WIDTH
);
783 while (list
!= (list_info_type
*) NULL
&& 0)
786 list
->frag
= list
->next
->frag
;
796 width
= LISTING_RHS_WIDTH
> paper_width
? paper_width
:
812 title
= list
->edict_arg
;
815 subtitle
= list
->edict_arg
;
821 if (show_listing
> 0)
823 /* Scan down the list and print all the stuff which can be done
824 with this line (or lines). */
829 current_hll_file
= list
->hll_file
;
832 if (current_hll_file
&& list
->hll_line
&& listing
& LISTING_HLL
)
834 print_source (current_hll_file
, list
, buffer
, width
);
837 p
= buffer_line (list
->file
, buffer
, width
);
839 if (!((listing
& LISTING_NODEBUG
) && debugging_pseudo (p
)))
841 print_lines (list
, p
, calc_hex (list
));
844 if (list
->edict
== EDICT_EJECT
)
852 p
= buffer_line (list
->file
, buffer
, width
);
867 if (listing
& LISTING_NOFORM
)
872 if (listing
& LISTING_LISTING
)
874 listing_listing (name
);
877 if (listing
& LISTING_SYMBOLS
)
879 list_symbol_table ();
894 listing_tail
->edict
= EDICT_EJECT
;
900 while ((*input_line_pointer
++) && (*input_line_pointer
!= '\n'))
901 input_line_pointer
++;
909 listing_tail
->edict
= on
? EDICT_LIST
: EDICT_NOLIST
;
916 paper_height
= get_absolute_expression ();
918 if (paper_height
< 0 || paper_height
> 1000)
921 as_warn ("strange paper height, set to no form");
923 if (*input_line_pointer
== ',')
925 input_line_pointer
++;
926 paper_width
= get_absolute_expression ();
932 listing_title (depth
)
940 if (*input_line_pointer
== '\"')
942 input_line_pointer
++;
943 start
= input_line_pointer
;
945 while (*input_line_pointer
)
947 if (*input_line_pointer
== '\"')
949 length
= input_line_pointer
- start
;
950 title
= xmalloc (length
+ 1);
951 memcpy (title
, start
, length
);
953 listing_tail
->edict
= depth
? EDICT_SBTTL
: EDICT_TITLE
;
954 listing_tail
->edict_arg
= title
;
955 input_line_pointer
++;
956 demand_empty_rest_of_line ();
959 else if (*input_line_pointer
== '\n')
961 as_bad ("New line in title");
962 demand_empty_rest_of_line ();
967 input_line_pointer
++;
973 as_bad ("expecting title in quotes");
980 listing_source_line (line
)
984 listing_tail
->hll_line
= line
;
990 listing_source_file (file
)
993 listing_tail
->hll_file
= file_info (file
);
1001 /* Dummy functions for when compiled without listing enabled */
1029 listing_title (depth
)
1043 listing_newline (name
)
1050 listing_source_line (n
)
1056 listing_source_file (n
)
This page took 0.050375 seconds and 4 git commands to generate.