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