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