343aa62d6d126448695422caa70add6246976298
[deliverable/binutils-gdb.git] / gas / listing.c
1 /* listing.c - mainting assembly listings
2 Copyright (C) 1991, 1992 Free Software Foundation, Inc.
3
4 This file is part of GAS, the GNU Assembler.
5
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)
9 any later version.
10
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.
15
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. */
19
20 /*
21 Contributed by Steve Chamberlain
22 sac@cygnus.com
23
24
25 A listing page looks like:
26
27 LISTING_HEADER sourcefilename pagenumber
28 TITLE LINE
29 SUBTITLE LINE
30 linenumber address data source
31 linenumber address data source
32 linenumber address data source
33 linenumber address data source
34
35 If not overridden, the listing commands are:
36
37 .title "stuff"
38 Put "stuff" onto the title line
39 .sbttl "stuff"
40 Put stuff onto the subtitle line
41
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
44
45 .eject
46 Thow a page
47 .list
48 Increment the enable listing counter
49 .nolist
50 Decrement the enable listing counter
51
52 .psize Y[,X]
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
55
56 If the counter goes below zero, listing is suppressed.
57
58
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.
64
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.
69
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.
74
75 The only things which the architecture can change about the listing
76 are defined in these macros:
77
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
83 78
84 LISTING_LHS_WIDTH Number of words of above size for the lhs
85
86 LISTING_LHS_WIDTH_SECOND Number of words for the data on the lhs
87 for the second line
88
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
91 on a line
92 */
93
94 #include "as.h"
95 #include <obstack.h>
96 #include "input-file.h"
97 #include "targ-cpu.h"
98
99 #ifndef NO_LISTING
100 #ifndef LISTING_HEADER
101 #define LISTING_HEADER "GAS LISTING"
102 #endif
103 #ifndef LISTING_WORD_SIZE
104 #define LISTING_WORD_SIZE 4
105 #endif
106 #ifndef LISTING_LHS_WIDTH
107 #define LISTING_LHS_WIDTH 1
108 #endif
109 #ifndef LISTING_LHS_WIDTH_SECOND
110 #define LISTING_LHS_WIDTH_SECOND 1
111 #endif
112 #ifndef LISTING_RHS_WIDTH
113 #define LISTING_RHS_WIDTH 100
114 #endif
115 #ifndef LISTING_LHS_CONT_LINES
116 #define LISTING_LHS_CONT_LINES 4
117 #endif
118
119
120
121
122 /* This structure remembers which .s were used */
123 typedef struct file_info_struct
124 {
125 char *filename;
126 int linenum;
127 FILE *file;
128 struct file_info_struct *next;
129 int end_pending;
130
131 } file_info_type ;
132
133
134 /* this structure rememebrs which line from which file goes into which
135 frag */
136 typedef struct list_info_struct
137 {
138 /* Frag which this line of source is nearest to */
139 fragS *frag;
140 /* The actual line in the source file */
141 unsigned int line;
142 /* Pointer to the file info struct for the file which this line
143 belongs to */
144 file_info_type *file;
145
146 /* Next in list */
147 struct list_info_struct *next;
148
149
150 /* Pointer to the file info struct for the high level language
151 source line that belongs here */
152 file_info_type *hll_file;
153
154 /* High level language source line */
155 int hll_line;
156
157
158 /* Pointer to any error message associated with this line */
159 char *message;
160
161 enum
162 {
163 EDICT_NONE,
164 EDICT_SBTTL,
165 EDICT_TITLE,
166 EDICT_NOLIST,
167 EDICT_LIST,
168 EDICT_EJECT
169 } edict;
170 char *edict_arg;
171
172 } list_info_type;
173
174
175 static struct list_info_struct *head;
176 struct list_info_struct *listing_tail;
177 extern int listing;
178 extern unsigned int physical_input_line;
179 extern fragS *frag_now;
180
181
182 static int paper_width = 200;
183 static int paper_height = 60;
184
185
186 /* this static array is used to keep the text of data to be printed
187 before the start of the line.
188 It is stored so we can give a bit more info on the next line. To much, and large
189 initialized arrays will use up lots of paper.
190 */
191
192 static char data_buffer[100];
193 static unsigned int data_buffer_size;
194
195
196 static void
197 DEFUN(listing_message,(name, message),
198 char *name AND
199 char *message)
200 {
201 unsigned int l = strlen(name) + strlen(message)+1;
202 char *n = malloc(l);
203 strcpy(n,name);
204 strcat(n,message);
205 if(listing_tail != (list_info_type *)NULL)
206 {
207 listing_tail->message = n;
208 }
209
210 }
211
212
213
214
215 void
216 DEFUN(listing_warning,(message),
217 char *message)
218 {
219 listing_message("Warning:", message);
220 }
221
222 void
223 DEFUN(listing_error,(message),
224 char *message)
225 {
226 listing_message("Error:", message);
227 }
228
229
230
231
232 static file_info_type *file_info_head;
233
234 static file_info_type *
235 DEFUN(file_info, (file_name),
236 char *file_name)
237 {
238 /* Find an entry with this file name */
239 file_info_type *p = file_info_head;
240
241 while (p != (file_info_type *)NULL)
242 {
243 if (strcmp(p->filename, file_name) == 0)
244 return p;
245 p = p->next;
246 }
247
248 /* Make new entry */
249
250 p = (file_info_type *)xmalloc(sizeof(file_info_type));
251 p->next = file_info_head;
252 file_info_head = p;
253 p->filename = xmalloc(strlen(file_name)+1);
254 strcpy(p->filename, file_name);
255 p->linenum = 0;
256 p->end_pending = 0;
257
258 p->file = fopen(p->filename,"r");
259 return p;
260
261 }
262
263
264 static void
265 DEFUN_VOID(new_frag)
266 {
267
268 frag_wane(frag_now);
269 frag_new(0);
270
271 }
272
273 void
274 DEFUN(listing_newline,(ps),
275 char *ps)
276 {
277 char *s = ps;
278 extern char *file_name;
279 static unsigned int last_line =0xffff ;
280
281
282 list_info_type *new;
283 if (physical_input_line != last_line)
284 {
285 last_line = physical_input_line;
286 new_frag();
287
288 new = (list_info_type *)malloc(sizeof(list_info_type));
289 new->frag = frag_now;
290 new->line = physical_input_line ;
291 new->file = file_info(file_name);
292
293 if (listing_tail)
294 {
295 listing_tail->next = new;
296 }
297 else
298 {
299 head = new;
300 }
301 listing_tail = new;
302 new->next = (list_info_type *)NULL;
303 new->message = (char *)NULL;
304 new->edict = EDICT_NONE;
305 new->hll_file = (file_info_type*)NULL;
306 new->hll_line = 0;
307 new_frag();
308 }
309 }
310
311
312 /*
313 This function returns the next source line from the file supplied,
314 truncated to size. It appends a fake line to the end of each input
315 file to make
316 */
317
318 static char *
319 DEFUN(buffer_line,(file, line, size),
320 file_info_type *file AND
321 char *line AND
322 unsigned int size)
323 {
324 unsigned int count = 0;
325 int c;
326
327 char *p = line;
328
329 /* If we couldn't open the file, return an empty line */
330 if (file->file == (FILE*)NULL)
331 {
332 return "";
333 }
334
335 if (file->end_pending == 10) {
336 *p ++ = '\n';
337 rewind(file->file);
338 file->linenum = 0;
339 file->end_pending = 0;
340 }
341 c = fgetc(file->file);
342 size -= 1; /* leave room for null */
343
344 while (c != EOF && c != '\n')
345 {
346 if (count < size)
347 *p++ = c;
348 count++;
349
350 c= fgetc(file->file);
351 }
352 if (c == EOF)
353 {
354 file->end_pending ++;
355 *p++ = 'E';
356 *p++ = 'O';
357 *p++ = 'F';
358 }
359 file->linenum++;
360 *p++ = 0;
361 return line;
362 }
363
364
365 static char *fn;
366
367 static unsigned int eject; /* Eject pending */
368 static unsigned int page; /* Current page number */
369 static char *title; /* current title */
370 static char *subtitle; /* current subtitle */
371 static unsigned int on_page; /* number of lines printed on current page */
372
373
374 static void
375 DEFUN(listing_page,(list),
376 list_info_type *list)
377 {
378 /* Grope around, see if we can see a title or subtitle edict coming up
379 soon (we look down 10 lines of the page and see if it's there)*/
380 if ((eject || (on_page >= paper_height)) && paper_height != 0)
381 {
382 unsigned int c = 10;
383 int had_title = 0;
384 int had_subtitle = 0;
385
386 page++;
387
388 while (c != 0 && list)
389 {
390 if (list->edict == EDICT_SBTTL && !had_subtitle)
391 {
392 had_subtitle = 1;
393 subtitle = list->edict_arg;
394 }
395 if (list->edict == EDICT_TITLE && !had_title)
396 {
397 had_title = 1;
398 title = list->edict_arg;
399 }
400 list = list->next;
401 c--;
402 }
403
404
405 if (page > 1)
406 {
407 printf("\f");
408 }
409
410 printf("%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
411 printf("%s\n", title);
412 printf("%s\n", subtitle);
413 on_page = 3;
414 eject = 0;
415 }
416 }
417
418
419 static unsigned int
420 DEFUN(calc_hex,(list),
421 list_info_type *list)
422 {
423 list_info_type *first = list;
424 list_info_type *last = first;
425 unsigned int address = ~0;
426
427 fragS *frag;
428 fragS *frag_ptr;
429
430 unsigned int byte_in_frag = 0;
431
432 int anything = 0;
433
434 /* Find first frag which says it belongs to this line */
435 frag = list->frag;
436 while (frag && frag->line != list)
437 frag = frag->fr_next;
438
439 frag_ptr = frag;
440
441 data_buffer_size = 0;
442
443 /* Dump all the frags which belong to this line */
444 while (frag_ptr != (fragS *)NULL && frag_ptr->line == first)
445 {
446 /* Print as many bytes from the fixed part as is sensible */
447 while(byte_in_frag < frag_ptr->fr_fix && data_buffer_size < sizeof(data_buffer)-10)
448 {
449 if (address == ~0)
450 {
451 address = frag_ptr->fr_address;
452 }
453
454 sprintf(data_buffer + data_buffer_size,
455 "%02X",
456 (frag_ptr->fr_literal[byte_in_frag]) & 0xff);
457 data_buffer_size += 2;
458 byte_in_frag++;
459 }
460 /* Print as many bytes from the variable part as is sensible */
461 while (byte_in_frag < frag_ptr->fr_var * frag_ptr->fr_offset
462 && data_buffer_size < sizeof(data_buffer)-10)
463 {
464 if (address == ~0)
465 {
466 address = frag_ptr->fr_address;
467 }
468 data_buffer[data_buffer_size++] = '*';
469 data_buffer[data_buffer_size++] = '*';
470
471 byte_in_frag++;
472 }
473 frag_ptr = frag_ptr->fr_next;
474 }
475 data_buffer[data_buffer_size++] = 0;
476 return address;
477 }
478
479
480
481
482
483
484 static void
485 DEFUN(print_lines,(list, string, address),
486 list_info_type *list AND
487 char *string AND
488 unsigned int address)
489 {
490 unsigned int idx;
491 unsigned int nchars;
492 unsigned int lines;
493 unsigned int byte_in_word =0;
494 char *src = data_buffer;
495
496 /* Print the stuff on the first line */
497 listing_page(list);
498 nchars = (LISTING_WORD_SIZE*2 +1) * LISTING_LHS_WIDTH ;
499 /* Print the hex for the first line */
500 if (address == ~0)
501 {
502 printf("% 4d ", list->line);
503 for (idx = 0; idx < nchars; idx++)
504 printf(" ");
505
506 printf("\t%s\n", string ? string : "");
507 on_page++;
508 listing_page(0);
509
510 }
511 else
512 {
513 if (had_errors())
514 {
515 printf("% 4d ???? ", list->line);
516 }
517 else
518 {
519 printf("% 4d %04x ", list->line, address);
520 }
521
522 /* And the data to go along with it */
523 idx = 0;
524
525 while (*src && idx < nchars)
526 {
527 printf("%c%c", src[0], src[1]);
528 src += 2;
529 byte_in_word++;
530 if (byte_in_word == LISTING_WORD_SIZE)
531 {
532 printf(" ");
533 idx++;
534 byte_in_word = 0;
535 }
536 idx+=2;
537 }
538
539 for (;idx < nchars; idx++)
540 printf(" ");
541
542 printf("\t%s\n", string ? string : "");
543 on_page++;
544 listing_page(list);
545 if (list->message)
546 {
547 printf("**** %s\n",list->message);
548 listing_page(list);
549 on_page++;
550 }
551
552 for (lines = 0;
553 lines < LISTING_LHS_CONT_LINES
554 && *src;
555 lines++) {
556 nchars = ((LISTING_WORD_SIZE*2) +1) * LISTING_LHS_WIDTH_SECOND -1;
557 idx = 0;
558 /* Print any more lines of data, but more compactly */
559 printf("% 4d ", list->line);
560
561 while (*src && idx < nchars)
562 {
563 printf("%c%c", src[0], src[1]);
564 src+=2;
565 idx+=2;
566 byte_in_word++;
567 if (byte_in_word == LISTING_WORD_SIZE)
568 {
569 printf(" ");
570 idx++;
571 byte_in_word = 0;
572 }
573 }
574
575 printf("\n");
576 on_page++;
577 listing_page(list);
578
579 }
580
581
582 }
583 }
584
585
586
587
588
589
590 static void
591 DEFUN_VOID(list_symbol_table)
592 {
593 extern symbolS *symbol_rootP;
594
595 symbolS *ptr ;
596 eject = 1;
597 listing_page(0);
598 printf("DEFINED SYMBOLS\n");
599 on_page++;
600
601 for (ptr = symbol_rootP; ptr != (symbolS*)NULL; ptr = symbol_next(ptr))
602 {
603 if (ptr->sy_frag->line)
604 {
605 if (strlen(S_GET_NAME(ptr)))
606 {
607 printf("%20s:%-5d %2d:%08x %s \n",
608 ptr->sy_frag->line->file->filename,
609 ptr->sy_frag->line->line,
610 S_GET_SEGMENT(ptr),
611 S_GET_VALUE(ptr),
612 S_GET_NAME(ptr));
613
614 on_page++;
615 listing_page(0);
616 }
617 }
618
619 }
620 printf("\n");
621 on_page++;
622 listing_page(0);
623 printf("UNDEFINED SYMBOLS\n");
624 on_page++;
625 listing_page(0);
626
627 for (ptr = symbol_rootP; ptr != (symbolS*)NULL; ptr = symbol_next(ptr))
628 {
629 if (ptr && strlen(S_GET_NAME(ptr)) != 0)
630 {
631 if (ptr->sy_frag->line == 0)
632 {
633 printf("%s\n", S_GET_NAME(ptr));
634 on_page++;
635 listing_page(0);
636 }
637 }
638 }
639 }
640
641 void
642 DEFUN(print_source,(current_file, list, buffer, width),
643 file_info_type *current_file AND
644 list_info_type *list AND
645 char *buffer AND
646 unsigned int width)
647 {
648 if (current_file->file) {
649 while (current_file->linenum < list->hll_line)
650 {
651 char * p = buffer_line(current_file, buffer, width);
652 printf("%4d:%-13s **** %s\n", current_file->linenum, current_file->filename, p);
653 on_page++;
654 listing_page(list);
655 }
656 }
657 }
658
659 /* Sometimes the user doesn't want to be bothered by the debugging
660 records inserted by the compiler, see if the line is suspicioous */
661
662 static int
663 DEFUN(debugging_pseudo,(line),
664 char *line)
665 {
666 while (isspace(*line))
667 line++;
668
669 if(*line != '.') return 0;
670
671 line++;
672
673 if (strncmp(line, "def",3) == 0) return 1;
674 if (strncmp(line, "val",3) == 0) return 1;
675 if (strncmp(line, "scl",3) == 0) return 1;
676 if (strncmp(line, "line",4) == 0) return 1;
677 if (strncmp(line, "endef",5) == 0) return 1;
678 if (strncmp(line, "ln",2) ==0) return 1;
679 if (strncmp(line, "type",4) ==0) return 1;
680 if (strncmp(line, "size",4) == 0) return 1;
681 if (strncmp(line, "dim",3) ==0) return 1;
682 if (strncmp(line, "tag",3) == 0) return 1;
683
684 return 0;
685
686 }
687
688 void
689 DEFUN(listing_listing,(name),
690 char *name)
691 {
692 list_info_type *list = head;
693 file_info_type *current_hll_file = (file_info_type *)NULL;
694
695 unsigned int page= 1;
696 unsigned int prev = 0;
697 char *message;
698 char *buffer;
699 char *p;
700 unsigned int addr = 0;
701 int on_page = 0;
702 int show_listing = 1;
703 unsigned int width;
704
705 buffer = malloc(LISTING_RHS_WIDTH);
706 eject = 1;
707 list = head;
708
709 while (list != (list_info_type *)NULL && 0)
710 {
711 if (list->next)
712 list->frag = list->next->frag;
713 list = list->next;
714
715 }
716
717 list = head->next;
718
719
720 while ( list)
721 {
722 width = LISTING_RHS_WIDTH > paper_width ? paper_width :
723 LISTING_RHS_WIDTH;
724
725 switch (list->edict) {
726 case EDICT_LIST:
727 show_listing++;
728 break;
729 case EDICT_NOLIST:
730 show_listing--;
731 break;
732 case EDICT_EJECT:
733 break;
734 case EDICT_NONE:
735 break;
736 case EDICT_TITLE:
737 title = list->edict_arg;
738 break;
739 case EDICT_SBTTL:
740 subtitle = list->edict_arg;
741 break;
742 default:
743 abort();
744 }
745
746 if (show_listing > 0)
747 {
748 /* Scan down the list and print all the stuff which can be done
749 with this line (or lines) */
750 message = 0;
751
752 if (list->hll_file)
753 {
754 current_hll_file = list->hll_file;
755 }
756
757 if (current_hll_file && list->hll_line && listing & LISTING_HLL)
758 {
759 print_source(current_hll_file, list, buffer, width);
760 }
761
762 p = buffer_line(list->file, buffer, width);
763
764 if (! ((listing & LISTING_NODEBUG) && debugging_pseudo(p)))
765 {
766 print_lines(list, p, calc_hex(list));
767 }
768
769 if (list->edict == EDICT_EJECT)
770 {
771 eject = 1;
772 }
773 }
774 else
775 {
776
777 p = buffer_line(list->file, buffer, width);
778 }
779
780 list = list->next;
781 }
782 free(buffer);
783 }
784
785 void
786 DEFUN(listing_print,(name),
787 char *name)
788 {
789 title = "";
790 subtitle = "";
791
792 if (listing & LISTING_NOFORM)
793 {
794 paper_height = 0;
795 }
796
797 if (listing & LISTING_LISTING)
798 {
799 listing_listing(name);
800
801 }
802 if (listing & LISTING_SYMBOLS)
803 {
804 list_symbol_table();
805 }
806 }
807
808
809 void
810 DEFUN(listing_file,(name),
811 char *name)
812 {
813 fn = name;
814 }
815
816 void
817 DEFUN_VOID(listing_eject)
818 {
819 listing_tail->edict = EDICT_EJECT;
820 }
821
822 void
823 DEFUN_VOID(listing_flags)
824 {
825
826 }
827 void
828 DEFUN(listing_list,(on),
829 unsigned int on)
830 {
831 listing_tail->edict = on ? EDICT_LIST : EDICT_NOLIST;
832 }
833
834
835 void
836 DEFUN_VOID(listing_psize)
837 {
838 paper_height = get_absolute_expression();
839
840 if (paper_height < 0 || paper_height > 1000)
841 {
842 paper_height = 0;
843 as_warn("strantge paper height, set to no form");
844 }
845 if (*input_line_pointer == ',')
846 {
847 input_line_pointer++;
848 paper_width = get_absolute_expression();
849 }
850 }
851
852
853 void
854 DEFUN(listing_title,(depth),
855 unsigned int depth)
856 {
857 char *start;
858 char *title;
859 unsigned int length;
860
861 SKIP_WHITESPACE();
862 if (*input_line_pointer=='\"') {
863 input_line_pointer++;
864 start = input_line_pointer;
865
866 while (*input_line_pointer)
867 {
868 if (*input_line_pointer == '\"')
869 {
870 length = input_line_pointer - start;
871 title = malloc(length + 1);
872 memcpy(title, start, length);
873 title[length] = 0;
874 listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
875 listing_tail->edict_arg = title;
876 input_line_pointer++;
877 demand_empty_rest_of_line();
878 return;
879 }
880 else if (*input_line_pointer == '\n')
881 {
882 as_bad("New line in title");
883 demand_empty_rest_of_line();
884 return;
885 }
886 else
887 {
888 input_line_pointer++;
889 }
890 }
891 }
892 else
893 {
894 as_bad("expecting title in quotes");
895 }
896 }
897
898
899
900 void
901 DEFUN(listing_source_line,(line),
902 unsigned int line)
903 {
904 new_frag();
905 listing_tail->hll_line = line;
906 new_frag();
907
908 }
909
910 void
911 DEFUN(listing_source_file,(file),
912 char *file)
913 {
914 listing_tail->hll_file = file_info(file);
915 }
916
917
918
919 #else
920
921
922 /* Dummy functions for when compiled without listing enabled */
923
924 void
925 DEFUN_VOID(listing_flags)
926 {
927 s_ignore();
928 }
929
930 void DEFUN_VOID(listing_list)
931 {
932 s_ignore();
933 }
934
935 void DEFUN_VOID(listing_eject)
936 {
937 s_ignore();
938 }
939 void DEFUN(listing_psize)
940 {
941 s_ignore();
942 }
943
944 void DEFUN(listing_title, (depth),
945 unsigned int depth)
946 {
947 s_ignore();
948 }
949 void
950 DEFUN(listing_file,(name),
951 char *name)
952 {
953
954 }
955
956 void DEFUN(listing_newline,(name),
957 char *name)
958 {
959
960 }
961
962 void DEFUN(listing_source_line,(n),
963 unsigned int n)
964 {
965
966 }
967 void DEFUN(listing_source_file, (n),
968 char *n)
969 {
970
971 }
972
973
974
975 #endif
976
This page took 0.083353 seconds and 3 git commands to generate.