listing.c revision 38889
1/* listing.c - mainting assembly listings 2 Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 1998 3 Free Software Foundation, Inc. 4 5This file is part of GAS, the GNU Assembler. 6 7GAS is free software; you can redistribute it and/or modify 8it under the terms of the GNU General Public License as published by 9the Free Software Foundation; either version 2, or (at your option) 10any later version. 11 12GAS is distributed in the hope that it will be useful, 13but WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15GNU General Public License for more details. 16 17You should have received a copy of the GNU General Public License 18along with GAS; see the file COPYING. If not, write to the Free 19Software Foundation, 59 Temple Place - Suite 330, Boston, MA 2002111-1307, USA. */ 21 22/* 23 Contributed by Steve Chamberlain 24 sac@cygnus.com 25 26 27 A listing page looks like: 28 29 LISTING_HEADER sourcefilename pagenumber 30 TITLE LINE 31 SUBTITLE LINE 32 linenumber address data source 33 linenumber address data source 34 linenumber address data source 35 linenumber address data source 36 37 If not overridden, the listing commands are: 38 39 .title "stuff" 40 Put "stuff" onto the title line 41 .sbttl "stuff" 42 Put stuff onto the subtitle line 43 44 If these commands come within 10 lines of the top of the page, they 45 will affect the page they are on, as well as any subsequent page 46 47 .eject 48 Thow a page 49 .list 50 Increment the enable listing counter 51 .nolist 52 Decrement the enable listing counter 53 54 .psize Y[,X] 55 Set the paper size to X wide and Y high. Setting a psize Y of 56 zero will suppress form feeds except where demanded by .eject 57 58 If the counter goes below zero, listing is suppressed. 59 60 61 Listings are a maintained by read calling various listing_<foo> 62 functions. What happens most is that the macro NO_LISTING is not 63 defined (from the Makefile), then the macro LISTING_NEWLINE expands 64 into a call to listing_newline. The call is done from read.c, every 65 time it sees a newline, and -l is on the command line. 66 67 The function listing_newline remembers the frag associated with the 68 newline, and creates a new frag - note that this is wasteful, but not 69 a big deal, since listing slows things down a lot anyway. The 70 function also rememebers when the filename changes. 71 72 When all the input has finished, and gas has had a chance to settle 73 down, the listing is output. This is done by running down the list of 74 frag/source file records, and opening the files as needed and printing 75 out the bytes and chars associated with them. 76 77 The only things which the architecture can change about the listing 78 are defined in these macros: 79 80 LISTING_HEADER The name of the architecture 81 LISTING_WORD_SIZE The make of the number of bytes in a word, this determines 82 the clumping of the output data. eg a value of 83 2 makes words look like 1234 5678, whilst 1 84 would make the same value look like 12 34 56 85 78 86 LISTING_LHS_WIDTH Number of words of above size for the lhs 87 88 LISTING_LHS_WIDTH_SECOND Number of words for the data on the lhs 89 for the second line 90 91 LISTING_LHS_CONT_LINES Max number of lines to use up for a continutation 92 LISTING_RHS_WIDTH Number of chars from the input file to print 93 on a line 94*/ 95 96#include <ctype.h> 97 98#include "as.h" 99#include <obstack.h> 100#include "input-file.h" 101#include "subsegs.h" 102 103#ifndef NO_LISTING 104 105#ifndef LISTING_HEADER 106#define LISTING_HEADER "GAS LISTING" 107#endif 108#ifndef LISTING_WORD_SIZE 109#define LISTING_WORD_SIZE 4 110#endif 111#ifndef LISTING_LHS_WIDTH 112#define LISTING_LHS_WIDTH 1 113#endif 114#ifndef LISTING_LHS_WIDTH_SECOND 115#define LISTING_LHS_WIDTH_SECOND 1 116#endif 117#ifndef LISTING_RHS_WIDTH 118#define LISTING_RHS_WIDTH 100 119#endif 120#ifndef LISTING_LHS_CONT_LINES 121#define LISTING_LHS_CONT_LINES 4 122#endif 123 124/* This structure remembers which .s were used */ 125typedef struct file_info_struct 126{ 127 struct file_info_struct *next; 128 char *filename; 129 long pos; 130 unsigned int linenum; 131 int at_end; 132} 133file_info_type; 134 135 136/* this structure rememebrs which line from which file goes into which 137 frag */ 138struct list_info_struct 139{ 140 /* Frag which this line of source is nearest to */ 141 fragS *frag; 142 143 /* The actual line in the source file */ 144 unsigned int line; 145 /* Pointer to the file info struct for the file which this line 146 belongs to */ 147 file_info_type *file; 148 149 /* The expanded text of any macro that may have been executing. */ 150 char *line_contents; 151 152 /* Next in list */ 153 struct list_info_struct *next; 154 155 /* Pointer to the file info struct for the high level language 156 source line that belongs here */ 157 file_info_type *hll_file; 158 /* High level language source line */ 159 unsigned int hll_line; 160 161 /* Pointer to any error message associated with this line */ 162 char *message; 163 164 enum 165 { 166 EDICT_NONE, 167 EDICT_SBTTL, 168 EDICT_TITLE, 169 EDICT_NOLIST, 170 EDICT_LIST, 171 EDICT_NOLIST_NEXT, 172 EDICT_EJECT 173 } edict; 174 char *edict_arg; 175 176 /* Nonzero if this line is to be omitted because it contains 177 debugging information. This can become a flags field if we come 178 up with more information to store here. */ 179 int debugging; 180}; 181 182typedef struct list_info_struct list_info_type; 183 184static struct list_info_struct *head; 185struct list_info_struct *listing_tail; 186extern int listing; 187 188static int paper_width = 200; 189static int paper_height = 60; 190 191/* File to output listings to. */ 192static FILE *list_file; 193 194/* This static array is used to keep the text of data to be printed 195 before the start of the line. */ 196 197#define MAX_BYTES \ 198 (((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width \ 199 + ((((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second) \ 200 * listing_lhs_cont_lines) \ 201 + 20) 202 203static char *data_buffer; 204 205/* Prototypes. */ 206static void listing_message PARAMS ((const char *name, const char *message)); 207static file_info_type *file_info PARAMS ((const char *file_name)); 208static void new_frag PARAMS ((void)); 209static char *buffer_line PARAMS ((file_info_type *file, 210 char *line, unsigned int size)); 211static void listing_page PARAMS ((list_info_type *list)); 212static unsigned int calc_hex PARAMS ((list_info_type *list)); 213static void print_lines PARAMS ((list_info_type *, unsigned int, 214 char *, unsigned int)); 215static void list_symbol_table PARAMS ((void)); 216static void print_source PARAMS ((file_info_type *current_file, 217 list_info_type *list, 218 char *buffer, 219 unsigned int width)); 220static int debugging_pseudo PARAMS ((list_info_type *, const char *)); 221static void listing_listing PARAMS ((char *name)); 222 223 224static void 225listing_message (name, message) 226 const char *name; 227 const char *message; 228{ 229 unsigned int l = strlen (name) + strlen (message) + 1; 230 char *n = (char *) xmalloc (l); 231 strcpy (n, name); 232 strcat (n, message); 233 if (listing_tail != (list_info_type *) NULL) 234 { 235 listing_tail->message = n; 236 } 237} 238 239void 240listing_warning (message) 241 const char *message; 242{ 243 listing_message ("Warning:", message); 244} 245 246void 247listing_error (message) 248 const char *message; 249{ 250 listing_message ("Error:", message); 251} 252 253 254int listing_lhs_width = LISTING_LHS_WIDTH; 255int listing_lhs_width_second = LISTING_LHS_WIDTH_SECOND; 256int listing_lhs_cont_lines = LISTING_LHS_CONT_LINES; 257int listing_rhs_width = LISTING_RHS_WIDTH; 258 259 260static file_info_type *file_info_head; 261static file_info_type *last_open_file_info; 262static FILE *last_open_file; 263 264static file_info_type * 265file_info (file_name) 266 const char *file_name; 267{ 268 /* Find an entry with this file name */ 269 file_info_type *p = file_info_head; 270 271 while (p != (file_info_type *) NULL) 272 { 273 if (strcmp (p->filename, file_name) == 0) 274 return p; 275 p = p->next; 276 } 277 278 /* Make new entry */ 279 280 p = (file_info_type *) xmalloc (sizeof (file_info_type)); 281 p->next = file_info_head; 282 file_info_head = p; 283 p->filename = xmalloc ((unsigned long) strlen (file_name) + 1); 284 strcpy (p->filename, file_name); 285 p->pos = 0; 286 p->linenum = 0; 287 p->at_end = 0; 288 289 return p; 290} 291 292 293static void 294new_frag () 295{ 296 297 frag_wane (frag_now); 298 frag_new (0); 299 300} 301 302void 303listing_newline (ps) 304 char *ps; 305{ 306 char *file; 307 unsigned int line; 308 static unsigned int last_line = 0xffff; 309 static char *last_file = NULL; 310 list_info_type *new = NULL; 311 312 if (listing == 0) 313 return; 314 315 if (now_seg == absolute_section) 316 return; 317 318#ifdef OBJ_ELF 319 /* In ELF, anything in a section beginning with .debug or .line is 320 considered to be debugging information. This includes the 321 statement which switches us into the debugging section, which we 322 can only set after we are already in the debugging section. */ 323 if ((listing & LISTING_NODEBUG) != 0 324 && listing_tail != NULL 325 && ! listing_tail->debugging) 326 { 327 const char *segname; 328 329 segname = segment_name (now_seg); 330 if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0 331 || strncmp (segname, ".line", sizeof ".line" - 1) == 0) 332 listing_tail->debugging = 1; 333 } 334#endif 335 336 as_where (&file, &line); 337 if (ps == NULL) 338 { 339 if (line == last_line && !(last_file && file && strcmp(file, last_file))) 340 return; 341 342 new = (list_info_type *) xmalloc (sizeof (list_info_type)); 343 new->line_contents = NULL; 344 } 345 else 346 { 347 new = (list_info_type *) xmalloc (sizeof (list_info_type)); 348 new->line_contents = ps; 349 } 350 351 last_line = line; 352 last_file = file; 353 new_frag (); 354 355 if (listing_tail) 356 { 357 listing_tail->next = new; 358 } 359 else 360 { 361 head = new; 362 } 363 listing_tail = new; 364 365 new->frag = frag_now; 366 new->line = line; 367 new->file = file_info (file); 368 new->next = (list_info_type *) NULL; 369 new->message = (char *) NULL; 370 new->edict = EDICT_NONE; 371 new->hll_file = (file_info_type *) NULL; 372 new->hll_line = 0; 373 new->debugging = 0; 374 new_frag (); 375 376#ifdef OBJ_ELF 377 /* In ELF, anything in a section beginning with .debug or .line is 378 considered to be debugging information. */ 379 if ((listing & LISTING_NODEBUG) != 0) 380 { 381 const char *segname; 382 383 segname = segment_name (now_seg); 384 if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0 385 || strncmp (segname, ".line", sizeof ".line" - 1) == 0) 386 new->debugging = 1; 387 } 388#endif 389} 390 391/* Attach all current frags to the previous line instead of the 392 current line. This is called by the MIPS backend when it discovers 393 that it needs to add some NOP instructions; the added NOP 394 instructions should go with the instruction that has the delay, not 395 with the new instruction. */ 396 397void 398listing_prev_line () 399{ 400 list_info_type *l; 401 fragS *f; 402 403 if (head == (list_info_type *) NULL 404 || head == listing_tail) 405 return; 406 407 new_frag (); 408 409 for (l = head; l->next != listing_tail; l = l->next) 410 ; 411 412 for (f = frchain_now->frch_root; f != (fragS *) NULL; f = f->fr_next) 413 if (f->line == listing_tail) 414 f->line = l; 415 416 listing_tail->frag = frag_now; 417 new_frag (); 418} 419 420/* 421 This function returns the next source line from the file supplied, 422 truncated to size. It appends a fake line to the end of each input 423 file to make 424*/ 425 426static char * 427buffer_line (file, line, size) 428 file_info_type * file; 429 char *line; 430 unsigned int size; 431{ 432 unsigned int count = 0; 433 int c; 434 435 char *p = line; 436 437 /* If we couldn't open the file, return an empty line */ 438 if (file->at_end) 439 return ""; 440 441 /* Check the cache and see if we last used this file. */ 442 if (!last_open_file_info || file != last_open_file_info) 443 { 444 if (last_open_file) 445 { 446 last_open_file_info->pos = ftell (last_open_file); 447 fclose (last_open_file); 448 } 449 450 last_open_file_info = file; 451 last_open_file = fopen (file->filename, "r"); 452 if (last_open_file == NULL) 453 { 454 file->at_end = 1; 455 return ""; 456 } 457 458 /* Seek to where we were last time this file was open. */ 459 if (file->pos) 460 fseek(last_open_file, file->pos, SEEK_SET); 461 } 462 463 c = fgetc (last_open_file); 464 465 size -= 1; /* leave room for null */ 466 467 while (c != EOF && c != '\n') 468 { 469 if (count < size) 470 *p++ = c; 471 count++; 472 473 c = fgetc (last_open_file); 474 475 } 476 if (c == EOF) 477 { 478 file->at_end = 1; 479 *p++ = '.'; 480 *p++ = '.'; 481 *p++ = '.'; 482 } 483 file->linenum++; 484 *p++ = 0; 485 return line; 486} 487 488 489static const char *fn; 490 491static unsigned int eject; /* Eject pending */ 492static unsigned int page; /* Current page number */ 493static char *title; /* current title */ 494static char *subtitle; /* current subtitle */ 495static unsigned int on_page; /* number of lines printed on current page */ 496 497 498static void 499listing_page (list) 500 list_info_type *list; 501{ 502 /* Grope around, see if we can see a title or subtitle edict coming up 503 soon (we look down 10 lines of the page and see if it's there)*/ 504 if ((eject || (on_page >= (unsigned int) paper_height)) && paper_height != 0) 505 { 506 unsigned int c = 10; 507 int had_title = 0; 508 int had_subtitle = 0; 509 510 page++; 511 512 while (c != 0 && list) 513 { 514 if (list->edict == EDICT_SBTTL && !had_subtitle) 515 { 516 had_subtitle = 1; 517 subtitle = list->edict_arg; 518 } 519 if (list->edict == EDICT_TITLE && !had_title) 520 { 521 had_title = 1; 522 title = list->edict_arg; 523 } 524 list = list->next; 525 c--; 526 } 527 528 529 if (page > 1) 530 { 531 fprintf (list_file, "\f"); 532 } 533 534 fprintf (list_file, "%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page); 535 fprintf (list_file, "%s\n", title); 536 fprintf (list_file, "%s\n", subtitle); 537 on_page = 3; 538 eject = 0; 539 } 540} 541 542 543static unsigned int 544calc_hex (list) 545 list_info_type * list; 546{ 547 int data_buffer_size; 548 list_info_type *first = list; 549 unsigned int address = ~ (unsigned int) 0; 550 fragS *frag; 551 fragS *frag_ptr; 552 unsigned int byte_in_frag; 553 554 /* Find first frag which says it belongs to this line */ 555 frag = list->frag; 556 while (frag && frag->line != list) 557 frag = frag->fr_next; 558 559 frag_ptr = frag; 560 561 data_buffer_size = 0; 562 563 /* Dump all the frags which belong to this line */ 564 while (frag_ptr != (fragS *) NULL && frag_ptr->line == first) 565 { 566 /* Print as many bytes from the fixed part as is sensible */ 567 byte_in_frag = 0; 568 while ((offsetT) byte_in_frag < frag_ptr->fr_fix 569 && data_buffer_size < MAX_BYTES - 3) 570 { 571 if (address == ~ (unsigned int) 0) 572 { 573 address = frag_ptr->fr_address; 574 } 575 576 sprintf (data_buffer + data_buffer_size, 577 "%02X", 578 (frag_ptr->fr_literal[byte_in_frag]) & 0xff); 579 data_buffer_size += 2; 580 byte_in_frag++; 581 } 582 { 583 unsigned int var_rep_max = byte_in_frag; 584 unsigned int var_rep_idx = byte_in_frag; 585 586 /* Print as many bytes from the variable part as is sensible */ 587 while (((offsetT) byte_in_frag 588 < frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset) 589 && data_buffer_size < MAX_BYTES - 3) 590 { 591 if (address == ~ (unsigned int) 0) 592 { 593 address = frag_ptr->fr_address; 594 } 595 sprintf (data_buffer + data_buffer_size, 596 "%02X", 597 (frag_ptr->fr_literal[var_rep_idx]) & 0xff); 598#if 0 599 data_buffer[data_buffer_size++] = '*'; 600 data_buffer[data_buffer_size++] = '*'; 601#endif 602 data_buffer_size += 2; 603 604 var_rep_idx++; 605 byte_in_frag++; 606 607 if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var) 608 var_rep_idx = var_rep_max; 609 } 610 } 611 612 frag_ptr = frag_ptr->fr_next; 613 } 614 data_buffer[data_buffer_size] = '\0'; 615 return address; 616} 617 618 619 620 621 622 623static void 624print_lines (list, lineno, string, address) 625 list_info_type *list; 626 unsigned int lineno; 627 char *string; 628 unsigned int address; 629{ 630 unsigned int idx; 631 unsigned int nchars; 632 unsigned int lines; 633 unsigned int byte_in_word = 0; 634 char *src = data_buffer; 635 636 /* Print the stuff on the first line */ 637 listing_page (list); 638 nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width; 639 /* Print the hex for the first line */ 640 if (address == ~ (unsigned int) 0) 641 { 642 fprintf (list_file, "% 4d ", lineno); 643 for (idx = 0; idx < nchars; idx++) 644 fprintf (list_file, " "); 645 646 fprintf (list_file, "\t%s\n", string ? string : ""); 647 on_page++; 648 listing_page (0); 649 650 } 651 else 652 { 653 if (had_errors ()) 654 { 655 fprintf (list_file, "% 4d ???? ", lineno); 656 } 657 else 658 { 659 fprintf (list_file, "% 4d %04x ", lineno, address); 660 } 661 662 /* And the data to go along with it */ 663 idx = 0; 664 665 while (*src && idx < nchars) 666 { 667 fprintf (list_file, "%c%c", src[0], src[1]); 668 src += 2; 669 byte_in_word++; 670 if (byte_in_word == LISTING_WORD_SIZE) 671 { 672 fprintf (list_file, " "); 673 idx++; 674 byte_in_word = 0; 675 } 676 idx += 2; 677 } 678 679 for (; idx < nchars; idx++) 680 fprintf (list_file, " "); 681 682 fprintf (list_file, "\t%s\n", string ? string : ""); 683 on_page++; 684 listing_page (list); 685 if (list->message) 686 { 687 fprintf (list_file, "**** %s\n", list->message); 688 listing_page (list); 689 on_page++; 690 } 691 692 for (lines = 0; 693 lines < (unsigned int) listing_lhs_cont_lines && *src; 694 lines++) 695 { 696 nchars = (((LISTING_WORD_SIZE * 2) + 1) 697 * listing_lhs_width_second - 1); 698 idx = 0; 699 /* Print any more lines of data, but more compactly */ 700 fprintf (list_file, "% 4d ", lineno); 701 702 while (*src && idx < nchars) 703 { 704 fprintf (list_file, "%c%c", src[0], src[1]); 705 src += 2; 706 idx += 2; 707 byte_in_word++; 708 if (byte_in_word == LISTING_WORD_SIZE) 709 { 710 fprintf (list_file, " "); 711 idx++; 712 byte_in_word = 0; 713 } 714 } 715 716 fprintf (list_file, "\n"); 717 on_page++; 718 listing_page (list); 719 720 } 721 722 723 } 724} 725 726 727static void 728list_symbol_table () 729{ 730 extern symbolS *symbol_rootP; 731 int got_some = 0; 732 733 symbolS *ptr; 734 eject = 1; 735 listing_page (0); 736 737 for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr)) 738 { 739 if (SEG_NORMAL (S_GET_SEGMENT (ptr)) 740 || S_GET_SEGMENT (ptr) == absolute_section) 741 { 742#ifdef BFD_ASSEMBLER 743 /* Don't report section symbols. They are not interesting. */ 744 if (ptr->bsym->flags & BSF_SECTION_SYM) 745 continue; 746#endif 747 if (S_GET_NAME (ptr)) 748 { 749 char buf[30], fmt[8]; 750 valueT val = S_GET_VALUE (ptr); 751 752 /* @@ Note that this is dependent on the compilation options, 753 not solely on the target characteristics. */ 754 if (sizeof (val) == 4 && sizeof (int) == 4) 755 sprintf (buf, "%08lx", (unsigned long) val); 756 else if (sizeof (val) <= sizeof (unsigned long)) 757 { 758 sprintf (fmt, "%%0%lulx", 759 (unsigned long) (sizeof (val) * 2)); 760 sprintf (buf, fmt, (unsigned long) val); 761 } 762#if defined (BFD64) 763 else if (sizeof (val) > 4) 764 sprintf_vma (buf, val); 765#endif 766 else 767 abort (); 768 769 if (!got_some) 770 { 771 fprintf (list_file, "DEFINED SYMBOLS\n"); 772 on_page++; 773 got_some = 1; 774 } 775 776 if (ptr->sy_frag && ptr->sy_frag->line) 777 { 778 fprintf (list_file, "%20s:%-5d %s:%s %s\n", 779 ptr->sy_frag->line->file->filename, 780 ptr->sy_frag->line->line, 781 segment_name (S_GET_SEGMENT (ptr)), 782 buf, S_GET_NAME (ptr)); 783 } 784 else 785 { 786 fprintf (list_file, "%33s:%s %s\n", 787 segment_name (S_GET_SEGMENT (ptr)), 788 buf, S_GET_NAME (ptr)); 789 } 790 791 on_page++; 792 listing_page (0); 793 } 794 } 795 796 } 797 if (!got_some) 798 { 799 fprintf (list_file, "NO DEFINED SYMBOLS\n"); 800 on_page++; 801 } 802 fprintf (list_file, "\n"); 803 on_page++; 804 listing_page (0); 805 806 got_some = 0; 807 808 for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr)) 809 { 810 if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0) 811 { 812 if (S_GET_SEGMENT (ptr) == undefined_section) 813 { 814 if (!got_some) 815 { 816 got_some = 1; 817 fprintf (list_file, "UNDEFINED SYMBOLS\n"); 818 on_page++; 819 listing_page (0); 820 } 821 fprintf (list_file, "%s\n", S_GET_NAME (ptr)); 822 on_page++; 823 listing_page (0); 824 } 825 } 826 } 827 if (!got_some) 828 { 829 fprintf (list_file, "NO UNDEFINED SYMBOLS\n"); 830 on_page++; 831 listing_page (0); 832 } 833} 834 835static void 836print_source (current_file, list, buffer, width) 837 file_info_type *current_file; 838 list_info_type *list; 839 char *buffer; 840 unsigned int width; 841{ 842 if (!current_file->at_end) 843 { 844 while (current_file->linenum < list->hll_line 845 && !current_file->at_end) 846 { 847 char *p = buffer_line (current_file, buffer, width); 848 fprintf (list_file, "%4u:%-13s **** %s\n", current_file->linenum, 849 current_file->filename, p); 850 on_page++; 851 listing_page (list); 852 } 853 } 854} 855 856/* Sometimes the user doesn't want to be bothered by the debugging 857 records inserted by the compiler, see if the line is suspicious. */ 858 859static int 860debugging_pseudo (list, line) 861 list_info_type *list; 862 const char *line; 863{ 864 static int in_debug; 865 int was_debug; 866 867 if (list->debugging) 868 { 869 in_debug = 1; 870 return 1; 871 } 872 873 was_debug = in_debug; 874 in_debug = 0; 875 876 while (isspace ((unsigned char) *line)) 877 line++; 878 879 if (*line != '.') 880 { 881#ifdef OBJ_ELF 882 /* The ELF compiler sometimes emits blank lines after switching 883 out of a debugging section. If the next line drops us back 884 into debugging information, then don't print the blank line. 885 This is a hack for a particular compiler behaviour, not a 886 general case. */ 887 if (was_debug 888 && *line == '\0' 889 && list->next != NULL 890 && list->next->debugging) 891 { 892 in_debug = 1; 893 return 1; 894 } 895#endif 896 897 return 0; 898 } 899 900 line++; 901 902 if (strncmp (line, "def", 3) == 0) 903 return 1; 904 if (strncmp (line, "val", 3) == 0) 905 return 1; 906 if (strncmp (line, "scl", 3) == 0) 907 return 1; 908 if (strncmp (line, "line", 4) == 0) 909 return 1; 910 if (strncmp (line, "endef", 5) == 0) 911 return 1; 912 if (strncmp (line, "ln", 2) == 0) 913 return 1; 914 if (strncmp (line, "type", 4) == 0) 915 return 1; 916 if (strncmp (line, "size", 4) == 0) 917 return 1; 918 if (strncmp (line, "dim", 3) == 0) 919 return 1; 920 if (strncmp (line, "tag", 3) == 0) 921 return 1; 922 923 if (strncmp (line, "stabs", 5) == 0) 924 return 1; 925 if (strncmp (line, "stabn", 5) == 0) 926 return 1; 927 928 return 0; 929} 930 931static void 932listing_listing (name) 933 char *name; 934{ 935 list_info_type *list = head; 936 file_info_type *current_hll_file = (file_info_type *) NULL; 937 char *message; 938 char *buffer; 939 char *p; 940 int show_listing = 1; 941 unsigned int width; 942 943 buffer = xmalloc (listing_rhs_width); 944 data_buffer = xmalloc (MAX_BYTES); 945 eject = 1; 946 list = head; 947 948 while (list != (list_info_type *) NULL && 0) 949 { 950 if (list->next) 951 list->frag = list->next->frag; 952 list = list->next; 953 954 } 955 956 list = head->next; 957 958 959 while (list) 960 { 961 width = listing_rhs_width > paper_width ? paper_width : 962 listing_rhs_width; 963 964 switch (list->edict) 965 { 966 case EDICT_LIST: 967 show_listing++; 968 break; 969 case EDICT_NOLIST: 970 show_listing--; 971 break; 972 case EDICT_NOLIST_NEXT: 973 break; 974 case EDICT_EJECT: 975 break; 976 case EDICT_NONE: 977 break; 978 case EDICT_TITLE: 979 title = list->edict_arg; 980 break; 981 case EDICT_SBTTL: 982 subtitle = list->edict_arg; 983 break; 984 default: 985 abort (); 986 } 987 988 if (show_listing > 0) 989 { 990 /* Scan down the list and print all the stuff which can be done 991 with this line (or lines). */ 992 message = 0; 993 994 if (list->hll_file) 995 { 996 current_hll_file = list->hll_file; 997 } 998 999 if (current_hll_file && list->hll_line && (listing & LISTING_HLL)) 1000 { 1001 print_source (current_hll_file, list, buffer, width); 1002 } 1003 1004 if (list->line_contents) 1005 { 1006 if (!((listing & LISTING_NODEBUG) 1007 && debugging_pseudo (list, list->line_contents))) 1008 { 1009 print_lines (list, list->file->linenum, 1010 list->line_contents, calc_hex (list)); 1011 } 1012 } 1013 else 1014 { 1015 while (list->file->linenum < list->line 1016 && !list->file->at_end) 1017 { 1018 unsigned int address; 1019 1020 p = buffer_line (list->file, buffer, width); 1021 1022 if (list->file->linenum < list->line) 1023 address = ~ (unsigned int) 0; 1024 else 1025 address = calc_hex (list); 1026 1027 if (!((listing & LISTING_NODEBUG) 1028 && debugging_pseudo (list, p))) 1029 print_lines (list, list->file->linenum, p, address); 1030 } 1031 } 1032 1033 if (list->edict == EDICT_EJECT) 1034 { 1035 eject = 1; 1036 } 1037 } 1038 else 1039 { 1040 while (list->file->linenum < list->line 1041 && !list->file->at_end) 1042 p = buffer_line (list->file, buffer, width); 1043 } 1044 1045 if (list->edict == EDICT_NOLIST_NEXT) 1046 --show_listing; 1047 1048 list = list->next; 1049 } 1050 1051 free (buffer); 1052 free (data_buffer); 1053 data_buffer = NULL; 1054} 1055 1056void 1057listing_print (name) 1058 char *name; 1059{ 1060 int using_stdout; 1061 1062 title = ""; 1063 subtitle = ""; 1064 1065 if (name == NULL) 1066 { 1067 list_file = stdout; 1068 using_stdout = 1; 1069 } 1070 else 1071 { 1072 list_file = fopen (name, "w"); 1073 if (list_file != NULL) 1074 using_stdout = 0; 1075 else 1076 { 1077 as_perror ("can't open list file: %s", name); 1078 list_file = stdout; 1079 using_stdout = 1; 1080 } 1081 } 1082 1083 if (listing & LISTING_NOFORM) 1084 { 1085 paper_height = 0; 1086 } 1087 1088 if (listing & LISTING_LISTING) 1089 { 1090 listing_listing (name); 1091 } 1092 1093 if (listing & LISTING_SYMBOLS) 1094 { 1095 list_symbol_table (); 1096 } 1097 1098 if (! using_stdout) 1099 { 1100 if (fclose (list_file) == EOF) 1101 as_perror ("error closing list file: %s", name); 1102 } 1103 1104 if (last_open_file) 1105 { 1106 fclose (last_open_file); 1107 } 1108} 1109 1110 1111void 1112listing_file (name) 1113 const char *name; 1114{ 1115 fn = name; 1116} 1117 1118void 1119listing_eject (ignore) 1120 int ignore; 1121{ 1122 if (listing) 1123 listing_tail->edict = EDICT_EJECT; 1124} 1125 1126void 1127listing_flags (ignore) 1128 int ignore; 1129{ 1130 while ((*input_line_pointer++) && (*input_line_pointer != '\n')) 1131 input_line_pointer++; 1132 1133} 1134 1135/* Turn listing on or off. An argument of 0 means to turn off 1136 listing. An argument of 1 means to turn on listing. An argument 1137 of 2 means to turn off listing, but as of the next line; that is, 1138 the current line should be listed, but the next line should not. */ 1139 1140void 1141listing_list (on) 1142 int on; 1143{ 1144 if (listing) 1145 { 1146 switch (on) 1147 { 1148 case 0: 1149 if (listing_tail->edict == EDICT_LIST) 1150 listing_tail->edict = EDICT_NONE; 1151 else 1152 listing_tail->edict = EDICT_NOLIST; 1153 break; 1154 case 1: 1155 if (listing_tail->edict == EDICT_NOLIST 1156 || listing_tail->edict == EDICT_NOLIST_NEXT) 1157 listing_tail->edict = EDICT_NONE; 1158 else 1159 listing_tail->edict = EDICT_LIST; 1160 break; 1161 case 2: 1162 listing_tail->edict = EDICT_NOLIST_NEXT; 1163 break; 1164 default: 1165 abort (); 1166 } 1167 } 1168} 1169 1170 1171void 1172listing_psize (width_only) 1173 int width_only; 1174{ 1175 if (! width_only) 1176 { 1177 paper_height = get_absolute_expression (); 1178 1179 if (paper_height < 0 || paper_height > 1000) 1180 { 1181 paper_height = 0; 1182 as_warn ("strange paper height, set to no form"); 1183 } 1184 1185 if (*input_line_pointer != ',') 1186 { 1187 demand_empty_rest_of_line (); 1188 return; 1189 } 1190 1191 ++input_line_pointer; 1192 } 1193 1194 paper_width = get_absolute_expression (); 1195 1196 demand_empty_rest_of_line (); 1197} 1198 1199void 1200listing_nopage (ignore) 1201 int ignore; 1202{ 1203 paper_height = 0; 1204} 1205 1206void 1207listing_title (depth) 1208 int depth; 1209{ 1210 int quoted; 1211 char *start; 1212 char *ttl; 1213 unsigned int length; 1214 1215 SKIP_WHITESPACE (); 1216 if (*input_line_pointer != '\"') 1217 quoted = 0; 1218 else 1219 { 1220 quoted = 1; 1221 ++input_line_pointer; 1222 } 1223 1224 start = input_line_pointer; 1225 1226 while (*input_line_pointer) 1227 { 1228 if (quoted 1229 ? *input_line_pointer == '\"' 1230 : is_end_of_line[(unsigned char) *input_line_pointer]) 1231 { 1232 if (listing) 1233 { 1234 length = input_line_pointer - start; 1235 ttl = xmalloc (length + 1); 1236 memcpy (ttl, start, length); 1237 ttl[length] = 0; 1238 listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE; 1239 listing_tail->edict_arg = ttl; 1240 } 1241 if (quoted) 1242 input_line_pointer++; 1243 demand_empty_rest_of_line (); 1244 return; 1245 } 1246 else if (*input_line_pointer == '\n') 1247 { 1248 as_bad ("New line in title"); 1249 demand_empty_rest_of_line (); 1250 return; 1251 } 1252 else 1253 { 1254 input_line_pointer++; 1255 } 1256 } 1257} 1258 1259 1260 1261void 1262listing_source_line (line) 1263 unsigned int line; 1264{ 1265 if (listing) 1266 { 1267 new_frag (); 1268 listing_tail->hll_line = line; 1269 new_frag (); 1270 } 1271} 1272 1273void 1274listing_source_file (file) 1275 const char *file; 1276{ 1277 if (listing) 1278 listing_tail->hll_file = file_info (file); 1279} 1280 1281 1282 1283#else 1284 1285 1286/* Dummy functions for when compiled without listing enabled */ 1287 1288void 1289listing_flags (ignore) 1290 int ignore; 1291{ 1292 s_ignore (0); 1293} 1294 1295void 1296listing_list (on) 1297 int on; 1298{ 1299 s_ignore (0); 1300} 1301 1302void 1303listing_eject (ignore) 1304 int ignore; 1305{ 1306 s_ignore (0); 1307} 1308 1309void 1310listing_psize (ignore) 1311 int ignore; 1312{ 1313 s_ignore (0); 1314} 1315 1316void 1317listing_nopage (ignore) 1318 int ignore; 1319{ 1320 s_ignore (0); 1321} 1322 1323void 1324listing_title (depth) 1325 int depth; 1326{ 1327 s_ignore (0); 1328} 1329 1330void 1331listing_file (name) 1332 const char *name; 1333{ 1334 1335} 1336 1337void 1338listing_newline (name) 1339 char *name; 1340{ 1341 1342} 1343 1344void 1345listing_source_line (n) 1346 unsigned int n; 1347{ 1348 1349} 1350void 1351listing_source_file (n) 1352 const char *n; 1353{ 1354 1355} 1356 1357#endif 1358