1 /* listing.c - maintain assembly listings 2 Copyright (C) 1991-2016 Free Software Foundation, Inc. 3 4 This file is part of GAS, the GNU Assembler. 5 6 GAS is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3, or (at your option) 9 any later version. 10 11 GAS is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GAS; see the file COPYING. If not, write to the Free 18 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 19 02110-1301, USA. */ 20 21 /* Contributed by Steve Chamberlain <sac (at) cygnus.com> 22 23 A listing page looks like: 24 25 LISTING_HEADER sourcefilename pagenumber 26 TITLE LINE 27 SUBTITLE LINE 28 linenumber address data source 29 linenumber address data source 30 linenumber address data source 31 linenumber address data source 32 33 If not overridden, the listing commands are: 34 35 .title "stuff" 36 Put "stuff" onto the title line 37 .sbttl "stuff" 38 Put stuff onto the subtitle line 39 40 If these commands come within 10 lines of the top of the page, they 41 will affect the page they are on, as well as any subsequent page 42 43 .eject 44 Thow a page 45 .list 46 Increment the enable listing counter 47 .nolist 48 Decrement the enable listing counter 49 50 .psize Y[,X] 51 Set the paper size to X wide and Y high. Setting a psize Y of 52 zero will suppress form feeds except where demanded by .eject 53 54 If the counter goes below zero, listing is suppressed. 55 56 Listings are a maintained by read calling various listing_<foo> 57 functions. What happens most is that the macro NO_LISTING is not 58 defined (from the Makefile), then the macro LISTING_NEWLINE expands 59 into a call to listing_newline. The call is done from read.c, every 60 time it sees a newline, and -l is on the command line. 61 62 The function listing_newline remembers the frag associated with the 63 newline, and creates a new frag - note that this is wasteful, but not 64 a big deal, since listing slows things down a lot anyway. The 65 function also remembers when the filename changes. 66 67 When all the input has finished, and gas has had a chance to settle 68 down, the listing is output. This is done by running down the list of 69 frag/source file records, and opening the files as needed and printing 70 out the bytes and chars associated with them. 71 72 The only things which the architecture can change about the listing 73 are defined in these macros: 74 75 LISTING_HEADER The name of the architecture 76 LISTING_WORD_SIZE The make of the number of bytes in a word, this determines 77 the clumping of the output data. eg a value of 78 2 makes words look like 1234 5678, whilst 1 79 would make the same value look like 12 34 56 80 78 81 LISTING_LHS_WIDTH Number of words of above size for the lhs 82 83 LISTING_LHS_WIDTH_SECOND Number of words for the data on the lhs 84 for the second line 85 86 LISTING_LHS_CONT_LINES Max number of lines to use up for a continuation 87 LISTING_RHS_WIDTH Number of chars from the input file to print 88 on a line. */ 89 90 #include "as.h" 91 #include "filenames.h" 92 #include "safe-ctype.h" 93 #include "input-file.h" 94 #include "subsegs.h" 95 #include "bfdver.h" 96 #include <time.h> 97 #include <stdarg.h> 98 99 #ifndef NO_LISTING 100 101 #ifndef LISTING_HEADER 102 #define LISTING_HEADER "GAS LISTING" 103 #endif 104 #ifndef LISTING_WORD_SIZE 105 #define LISTING_WORD_SIZE 4 106 #endif 107 #ifndef LISTING_LHS_WIDTH 108 #define LISTING_LHS_WIDTH ((LISTING_WORD_SIZE) > 4 ? 1 : 4 / (LISTING_WORD_SIZE)) 109 #endif 110 #ifndef LISTING_LHS_WIDTH_SECOND 111 #define LISTING_LHS_WIDTH_SECOND LISTING_LHS_WIDTH 112 #endif 113 #ifndef LISTING_RHS_WIDTH 114 #define LISTING_RHS_WIDTH 100 115 #endif 116 #ifndef LISTING_LHS_CONT_LINES 117 #define LISTING_LHS_CONT_LINES 4 118 #endif 119 #define MAX_DATELEN 30 120 121 /* This structure remembers which .s were used. */ 122 typedef struct file_info_struct 123 { 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 enum edict_enum 132 { 133 EDICT_NONE, 134 EDICT_SBTTL, 135 EDICT_TITLE, 136 EDICT_NOLIST, 137 EDICT_LIST, 138 EDICT_NOLIST_NEXT, 139 EDICT_EJECT 140 }; 141 142 143 struct list_message 144 { 145 char *message; 146 struct list_message *next; 147 }; 148 149 /* This structure remembers which line from which file goes into which 150 frag. */ 151 struct list_info_struct 152 { 153 /* Frag which this line of source is nearest to. */ 154 fragS *frag; 155 156 /* The actual line in the source file. */ 157 unsigned int line; 158 159 /* Pointer to the file info struct for the file which this line 160 belongs to. */ 161 file_info_type *file; 162 163 /* The expanded text of any macro that may have been executing. */ 164 char *line_contents; 165 166 /* Next in list. */ 167 struct list_info_struct *next; 168 169 /* Pointer to the file info struct for the high level language 170 source line that belongs here. */ 171 file_info_type *hll_file; 172 173 /* High level language source line. */ 174 unsigned int hll_line; 175 176 /* Pointers to linked list of messages associated with this line. */ 177 struct list_message *messages, *last_message; 178 179 enum edict_enum edict; 180 char *edict_arg; 181 182 /* Nonzero if this line is to be omitted because it contains 183 debugging information. This can become a flags field if we come 184 up with more information to store here. */ 185 int debugging; 186 }; 187 188 typedef struct list_info_struct list_info_type; 189 190 int listing_lhs_width = LISTING_LHS_WIDTH; 191 int listing_lhs_width_second = LISTING_LHS_WIDTH_SECOND; 192 int listing_lhs_cont_lines = LISTING_LHS_CONT_LINES; 193 int listing_rhs_width = LISTING_RHS_WIDTH; 194 195 struct list_info_struct * listing_tail; 196 197 static file_info_type * file_info_head; 198 static file_info_type * last_open_file_info; 199 static FILE * last_open_file; 200 static struct list_info_struct * head; 201 static int paper_width = 200; 202 static int paper_height = 60; 203 204 extern int listing; 205 206 /* File to output listings to. */ 207 static FILE *list_file; 208 209 /* This static array is used to keep the text of data to be printed 210 before the start of the line. */ 211 212 #define MAX_BYTES \ 213 (((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width \ 214 + ((((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second) \ 215 * listing_lhs_cont_lines) \ 216 + 20) 217 218 static char *data_buffer; 219 220 /* Prototypes. */ 221 static void listing_message (const char *, const char *); 222 static file_info_type *file_info (const char *); 223 static void new_frag (void); 224 static void listing_page (list_info_type *); 225 static unsigned int calc_hex (list_info_type *); 226 static void print_lines (list_info_type *, unsigned int, const char *, 227 unsigned int); 228 static void list_symbol_table (void); 229 static int debugging_pseudo (list_info_type *, const char *); 230 static void listing_listing (char *); 231 232 static void 233 listing_message (const char *name, const char *message) 234 { 235 if (listing_tail != (list_info_type *) NULL) 236 { 237 char *n = concat (name, message, (char *) NULL); 238 struct list_message *lm = XNEW (struct list_message); 239 lm->message = n; 240 lm->next = NULL; 241 242 if (listing_tail->last_message) 243 listing_tail->last_message->next = lm; 244 else 245 listing_tail->messages = lm; 246 listing_tail->last_message = lm; 247 } 248 } 249 250 void 251 listing_warning (const char *message) 252 { 253 listing_message (_("Warning: "), message); 254 } 255 256 void 257 listing_error (const char *message) 258 { 259 listing_message (_("Error: "), message); 260 } 261 262 static file_info_type * 263 file_info (const char *file_name) 264 { 265 /* Find an entry with this file name. */ 266 file_info_type *p = file_info_head; 267 268 while (p != (file_info_type *) NULL) 269 { 270 if (filename_cmp (p->filename, file_name) == 0) 271 return p; 272 p = p->next; 273 } 274 275 /* Make new entry. */ 276 p = XNEW (file_info_type); 277 p->next = file_info_head; 278 file_info_head = p; 279 p->filename = xstrdup (file_name); 280 p->pos = 0; 281 p->linenum = 0; 282 p->at_end = 0; 283 284 return p; 285 } 286 287 static void 288 new_frag (void) 289 { 290 frag_wane (frag_now); 291 frag_new (0); 292 } 293 294 void 295 listing_newline (char *ps) 296 { 297 const char *file; 298 unsigned int line; 299 static unsigned int last_line = 0xffff; 300 static const char *last_file = NULL; 301 list_info_type *new_i = NULL; 302 303 if (listing == 0) 304 return; 305 306 if (now_seg == absolute_section) 307 return; 308 309 #ifdef OBJ_ELF 310 /* In ELF, anything in a section beginning with .debug or .line is 311 considered to be debugging information. This includes the 312 statement which switches us into the debugging section, which we 313 can only set after we are already in the debugging section. */ 314 if ((listing & LISTING_NODEBUG) != 0 315 && listing_tail != NULL 316 && ! listing_tail->debugging) 317 { 318 const char *segname; 319 320 segname = segment_name (now_seg); 321 if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0 322 || strncmp (segname, ".line", sizeof ".line" - 1) == 0) 323 listing_tail->debugging = 1; 324 } 325 #endif 326 327 file = as_where (&line); 328 if (ps == NULL) 329 { 330 if (line == last_line 331 && !(last_file && file && filename_cmp (file, last_file))) 332 return; 333 334 new_i = XNEW (list_info_type); 335 336 /* Detect if we are reading from stdin by examining the file 337 name returned by as_where(). 338 339 [FIXME: We rely upon the name in the strcmp below being the 340 same as the one used by input_scrub_new_file(), if that is 341 not true, then this code will fail]. 342 343 If we are reading from stdin, then we need to save each input 344 line here (assuming of course that we actually have a line of 345 input to read), so that it can be displayed in the listing 346 that is produced at the end of the assembly. */ 347 if (strcmp (file, _("{standard input}")) == 0 348 && input_line_pointer != NULL) 349 { 350 char *copy, *src, *dest; 351 int len; 352 int seen_quote = 0; 353 int seen_slash = 0; 354 355 for (copy = input_line_pointer; 356 *copy && (seen_quote 357 || is_end_of_line [(unsigned char) *copy] != 1); 358 copy++) 359 { 360 if (seen_slash) 361 seen_slash = 0; 362 else if (*copy == '\\') 363 seen_slash = 1; 364 else if (*copy == '"') 365 seen_quote = !seen_quote; 366 } 367 368 len = copy - input_line_pointer + 1; 369 370 copy = XNEWVEC (char, len); 371 372 src = input_line_pointer; 373 dest = copy; 374 375 while (--len) 376 { 377 unsigned char c = *src++; 378 379 /* Omit control characters in the listing. */ 380 if (!ISCNTRL (c)) 381 *dest++ = c; 382 } 383 384 *dest = 0; 385 386 new_i->line_contents = copy; 387 } 388 else 389 new_i->line_contents = NULL; 390 } 391 else 392 { 393 new_i = XNEW (list_info_type); 394 new_i->line_contents = ps; 395 } 396 397 last_line = line; 398 last_file = file; 399 400 new_frag (); 401 402 if (listing_tail) 403 listing_tail->next = new_i; 404 else 405 head = new_i; 406 407 listing_tail = new_i; 408 409 new_i->frag = frag_now; 410 new_i->line = line; 411 new_i->file = file_info (file); 412 new_i->next = (list_info_type *) NULL; 413 new_i->messages = NULL; 414 new_i->last_message = NULL; 415 new_i->edict = EDICT_NONE; 416 new_i->hll_file = (file_info_type *) NULL; 417 new_i->hll_line = 0; 418 new_i->debugging = 0; 419 420 new_frag (); 421 422 #ifdef OBJ_ELF 423 /* In ELF, anything in a section beginning with .debug or .line is 424 considered to be debugging information. */ 425 if ((listing & LISTING_NODEBUG) != 0) 426 { 427 const char *segname; 428 429 segname = segment_name (now_seg); 430 if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0 431 || strncmp (segname, ".line", sizeof ".line" - 1) == 0) 432 new_i->debugging = 1; 433 } 434 #endif 435 } 436 437 /* Attach all current frags to the previous line instead of the 438 current line. This is called by the MIPS backend when it discovers 439 that it needs to add some NOP instructions; the added NOP 440 instructions should go with the instruction that has the delay, not 441 with the new instruction. */ 442 443 void 444 listing_prev_line (void) 445 { 446 list_info_type *l; 447 fragS *f; 448 449 if (head == (list_info_type *) NULL 450 || head == listing_tail) 451 return; 452 453 new_frag (); 454 455 for (l = head; l->next != listing_tail; l = l->next) 456 ; 457 458 for (f = frchain_now->frch_root; f != (fragS *) NULL; f = f->fr_next) 459 if (f->line == listing_tail) 460 f->line = l; 461 462 listing_tail->frag = frag_now; 463 new_frag (); 464 } 465 466 /* This function returns the next source line from the file supplied, 467 truncated to size. It appends a fake line to the end of each input 468 file to make using the returned buffer simpler. */ 469 470 static const char * 471 buffer_line (file_info_type *file, char *line, unsigned int size) 472 { 473 unsigned int count = 0; 474 int c; 475 char *p = line; 476 477 /* If we couldn't open the file, return an empty line. */ 478 if (file->at_end) 479 return ""; 480 481 /* Check the cache and see if we last used this file. */ 482 if (!last_open_file_info || file != last_open_file_info) 483 { 484 if (last_open_file) 485 { 486 last_open_file_info->pos = ftell (last_open_file); 487 fclose (last_open_file); 488 } 489 490 /* Open the file in the binary mode so that ftell above can 491 return a reliable value that we can feed to fseek below. */ 492 last_open_file_info = file; 493 last_open_file = fopen (file->filename, FOPEN_RB); 494 if (last_open_file == NULL) 495 { 496 file->at_end = 1; 497 return ""; 498 } 499 500 /* Seek to where we were last time this file was open. */ 501 if (file->pos) 502 fseek (last_open_file, file->pos, SEEK_SET); 503 } 504 505 /* Leave room for null. */ 506 size -= 1; 507 508 c = fgetc (last_open_file); 509 510 while (c != EOF && c != '\n' && c != '\r') 511 { 512 if (count < size) 513 *p++ = c; 514 count++; 515 516 c = fgetc (last_open_file); 517 } 518 519 /* If '\r' is followed by '\n', swallow that. Likewise, if '\n' 520 is followed by '\r', swallow that as well. */ 521 if (c == '\r' || c == '\n') 522 { 523 int next = fgetc (last_open_file); 524 525 if ((c == '\r' && next != '\n') 526 || (c == '\n' && next != '\r')) 527 ungetc (next, last_open_file); 528 } 529 530 if (c == EOF) 531 { 532 file->at_end = 1; 533 if (count + 2 < size) 534 { 535 *p++ = '.'; 536 *p++ = '.'; 537 *p++ = '.'; 538 } 539 } 540 file->linenum++; 541 *p++ = 0; 542 return line; 543 } 544 545 546 /* This function rewinds the requested file back to the line requested, 547 reads it in again into the buffer provided and then restores the file 548 back to its original location. */ 549 550 static void 551 rebuffer_line (file_info_type * file, 552 unsigned int linenum, 553 char * buffer, 554 unsigned int size) 555 { 556 unsigned int count = 0; 557 unsigned int current_line; 558 char * p = buffer; 559 long pos; 560 long pos2; 561 int c; 562 bfd_boolean found = FALSE; 563 564 /* Sanity checks. */ 565 if (file == NULL || buffer == NULL || size <= 1 || file->linenum <= linenum) 566 return; 567 568 /* Check the cache and see if we last used this file. */ 569 if (last_open_file_info == NULL || file != last_open_file_info) 570 { 571 if (last_open_file) 572 { 573 last_open_file_info->pos = ftell (last_open_file); 574 fclose (last_open_file); 575 } 576 577 /* Open the file in the binary mode so that ftell above can 578 return a reliable value that we can feed to fseek below. */ 579 last_open_file_info = file; 580 last_open_file = fopen (file->filename, FOPEN_RB); 581 if (last_open_file == NULL) 582 { 583 file->at_end = 1; 584 return; 585 } 586 587 /* Seek to where we were last time this file was open. */ 588 if (file->pos) 589 fseek (last_open_file, file->pos, SEEK_SET); 590 } 591 592 /* Remember where we are in the current file. */ 593 pos2 = pos = ftell (last_open_file); 594 if (pos < 3) 595 return; 596 current_line = file->linenum; 597 598 /* Leave room for the nul at the end of the buffer. */ 599 size -= 1; 600 buffer[size] = 0; 601 602 /* Increment the current line count by one. 603 This is to allow for the fact that we are searching for the 604 start of a previous line, but we do this by detecting end-of-line 605 character(s) not start-of-line characters. */ 606 ++ current_line; 607 608 while (pos2 > 0 && ! found) 609 { 610 char * ptr; 611 612 /* Move backwards through the file, looking for earlier lines. */ 613 pos2 = (long) size > pos2 ? 0 : pos2 - size; 614 fseek (last_open_file, pos2, SEEK_SET); 615 616 /* Our caller has kindly provided us with a buffer, so we use it. */ 617 if (fread (buffer, 1, size, last_open_file) != size) 618 { 619 as_warn (_("unable to rebuffer file: %s\n"), file->filename); 620 return; 621 } 622 623 for (ptr = buffer + size; ptr >= buffer; -- ptr) 624 { 625 if (*ptr == '\n') 626 { 627 -- current_line; 628 629 if (current_line == linenum) 630 { 631 /* We have found the start of the line we seek. */ 632 found = TRUE; 633 634 /* FIXME: We could skip the read-in-the-line code 635 below if we know that we already have the whole 636 line in the buffer. */ 637 638 /* Advance pos2 to the newline character we have just located. */ 639 pos2 += (ptr - buffer); 640 641 /* Skip the newline and, if present, the carriage return. */ 642 if (ptr + 1 == buffer + size) 643 { 644 ++pos2; 645 if (fgetc (last_open_file) == '\r') 646 ++ pos2; 647 } 648 else 649 pos2 += (ptr[1] == '\r' ? 2 : 1); 650 651 /* Move the file pointer to this location. */ 652 fseek (last_open_file, pos2, SEEK_SET); 653 break; 654 } 655 } 656 } 657 } 658 659 /* Read in the line. */ 660 c = fgetc (last_open_file); 661 662 while (c != EOF && c != '\n' && c != '\r') 663 { 664 if (count < size) 665 *p++ = c; 666 count++; 667 668 c = fgetc (last_open_file); 669 } 670 671 /* If '\r' is followed by '\n', swallow that. Likewise, if '\n' 672 is followed by '\r', swallow that as well. */ 673 if (c == '\r' || c == '\n') 674 { 675 int next = fgetc (last_open_file); 676 677 if ((c == '\r' && next != '\n') 678 || (c == '\n' && next != '\r')) 679 ungetc (next, last_open_file); 680 } 681 682 /* Terminate the line. */ 683 *p++ = 0; 684 685 /* Reset the file position. */ 686 fseek (last_open_file, pos, SEEK_SET); 687 } 688 689 static const char *fn; 690 static unsigned int eject; /* Eject pending. */ 691 static unsigned int page; /* Current page number. */ 692 static const char *title; /* Current title. */ 693 static const char *subtitle; /* Current subtitle. */ 694 static unsigned int on_page; /* Number of lines printed on current page. */ 695 696 static void 697 listing_page (list_info_type *list) 698 { 699 /* Grope around, see if we can see a title or subtitle edict coming up 700 soon. (we look down 10 lines of the page and see if it's there) */ 701 if ((eject || (on_page >= (unsigned int) paper_height)) 702 && paper_height != 0) 703 { 704 unsigned int c = 10; 705 int had_title = 0; 706 int had_subtitle = 0; 707 708 page++; 709 710 while (c != 0 && list) 711 { 712 if (list->edict == EDICT_SBTTL && !had_subtitle) 713 { 714 had_subtitle = 1; 715 subtitle = list->edict_arg; 716 } 717 if (list->edict == EDICT_TITLE && !had_title) 718 { 719 had_title = 1; 720 title = list->edict_arg; 721 } 722 list = list->next; 723 c--; 724 } 725 726 if (page > 1) 727 { 728 fprintf (list_file, "\f"); 729 } 730 731 fprintf (list_file, "%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page); 732 fprintf (list_file, "%s\n", title); 733 fprintf (list_file, "%s\n", subtitle); 734 on_page = 3; 735 eject = 0; 736 } 737 } 738 739 /* Print a line into the list_file. Update the line count 740 and if necessary start a new page. */ 741 742 static void 743 emit_line (list_info_type * list, const char * format, ...) 744 { 745 va_list args; 746 747 va_start (args, format); 748 749 vfprintf (list_file, format, args); 750 on_page++; 751 listing_page (list); 752 753 va_end (args); 754 } 755 756 static unsigned int 757 calc_hex (list_info_type *list) 758 { 759 int data_buffer_size; 760 list_info_type *first = list; 761 unsigned int address = ~(unsigned int) 0; 762 fragS *frag; 763 fragS *frag_ptr; 764 unsigned int octet_in_frag; 765 766 /* Find first frag which says it belongs to this line. */ 767 frag = list->frag; 768 while (frag && frag->line != list) 769 frag = frag->fr_next; 770 771 frag_ptr = frag; 772 773 data_buffer_size = 0; 774 775 /* Dump all the frags which belong to this line. */ 776 while (frag_ptr != (fragS *) NULL && frag_ptr->line == first) 777 { 778 /* Print as many bytes from the fixed part as is sensible. */ 779 octet_in_frag = 0; 780 while ((offsetT) octet_in_frag < frag_ptr->fr_fix 781 && data_buffer_size < MAX_BYTES - 3) 782 { 783 if (address == ~(unsigned int) 0) 784 address = frag_ptr->fr_address / OCTETS_PER_BYTE; 785 786 sprintf (data_buffer + data_buffer_size, 787 "%02X", 788 (frag_ptr->fr_literal[octet_in_frag]) & 0xff); 789 data_buffer_size += 2; 790 octet_in_frag++; 791 } 792 if (frag_ptr->fr_type == rs_fill) 793 { 794 unsigned int var_rep_max = octet_in_frag; 795 unsigned int var_rep_idx = octet_in_frag; 796 797 /* Print as many bytes from the variable part as is sensible. */ 798 while (((offsetT) octet_in_frag 799 < (frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset)) 800 && data_buffer_size < MAX_BYTES - 3) 801 { 802 if (address == ~(unsigned int) 0) 803 address = frag_ptr->fr_address / OCTETS_PER_BYTE; 804 805 sprintf (data_buffer + data_buffer_size, 806 "%02X", 807 (frag_ptr->fr_literal[var_rep_idx]) & 0xff); 808 data_buffer_size += 2; 809 810 var_rep_idx++; 811 octet_in_frag++; 812 813 if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var) 814 var_rep_idx = var_rep_max; 815 } 816 } 817 818 frag_ptr = frag_ptr->fr_next; 819 } 820 data_buffer[data_buffer_size] = '\0'; 821 return address; 822 } 823 824 static void 825 print_lines (list_info_type *list, unsigned int lineno, 826 const char *string, unsigned int address) 827 { 828 unsigned int idx; 829 unsigned int nchars; 830 unsigned int lines; 831 unsigned int octet_in_word = 0; 832 char *src = data_buffer; 833 int cur; 834 struct list_message *msg; 835 836 /* Print the stuff on the first line. */ 837 listing_page (list); 838 nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width; 839 840 /* Print the hex for the first line. */ 841 if (address == ~(unsigned int) 0) 842 { 843 fprintf (list_file, "% 4d ", lineno); 844 for (idx = 0; idx < nchars; idx++) 845 fprintf (list_file, " "); 846 847 emit_line (NULL, "\t%s\n", string ? string : ""); 848 return; 849 } 850 851 if (had_errors ()) 852 fprintf (list_file, "% 4d ???? ", lineno); 853 else 854 fprintf (list_file, "% 4d %04x ", lineno, address); 855 856 /* And the data to go along with it. */ 857 idx = 0; 858 cur = 0; 859 while (src[cur] && idx < nchars) 860 { 861 int offset; 862 offset = cur; 863 fprintf (list_file, "%c%c", src[offset], src[offset + 1]); 864 cur += 2; 865 octet_in_word++; 866 867 if (octet_in_word == LISTING_WORD_SIZE) 868 { 869 fprintf (list_file, " "); 870 idx++; 871 octet_in_word = 0; 872 } 873 874 idx += 2; 875 } 876 877 for (; idx < nchars; idx++) 878 fprintf (list_file, " "); 879 880 emit_line (list, "\t%s\n", string ? string : ""); 881 882 for (msg = list->messages; msg; msg = msg->next) 883 emit_line (list, "**** %s\n", msg->message); 884 885 for (lines = 0; 886 lines < (unsigned int) listing_lhs_cont_lines 887 && src[cur]; 888 lines++) 889 { 890 nchars = ((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second - 1; 891 idx = 0; 892 893 /* Print any more lines of data, but more compactly. */ 894 fprintf (list_file, "% 4d ", lineno); 895 896 while (src[cur] && idx < nchars) 897 { 898 int offset; 899 offset = cur; 900 fprintf (list_file, "%c%c", src[offset], src[offset + 1]); 901 cur += 2; 902 idx += 2; 903 octet_in_word++; 904 905 if (octet_in_word == LISTING_WORD_SIZE) 906 { 907 fprintf (list_file, " "); 908 idx++; 909 octet_in_word = 0; 910 } 911 } 912 913 emit_line (list, "\n"); 914 } 915 } 916 917 static void 918 list_symbol_table (void) 919 { 920 extern symbolS *symbol_rootP; 921 int got_some = 0; 922 923 symbolS *ptr; 924 eject = 1; 925 listing_page (NULL); 926 927 for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr)) 928 { 929 if (SEG_NORMAL (S_GET_SEGMENT (ptr)) 930 || S_GET_SEGMENT (ptr) == absolute_section) 931 { 932 /* Don't report section symbols. They are not interesting. */ 933 if (symbol_section_p (ptr)) 934 continue; 935 936 if (S_GET_NAME (ptr)) 937 { 938 char buf[30], fmt[8]; 939 valueT val = S_GET_VALUE (ptr); 940 941 /* @@ Note that this is dependent on the compilation options, 942 not solely on the target characteristics. */ 943 if (sizeof (val) == 4 && sizeof (int) == 4) 944 sprintf (buf, "%08lx", (unsigned long) val); 945 else if (sizeof (val) <= sizeof (unsigned long)) 946 { 947 sprintf (fmt, "%%0%lulx", 948 (unsigned long) (sizeof (val) * 2)); 949 sprintf (buf, fmt, (unsigned long) val); 950 } 951 #if defined (BFD64) 952 else if (sizeof (val) > 4) 953 sprintf_vma (buf, val); 954 #endif 955 else 956 abort (); 957 958 if (!got_some) 959 { 960 fprintf (list_file, "DEFINED SYMBOLS\n"); 961 on_page++; 962 got_some = 1; 963 } 964 965 if (symbol_get_frag (ptr) && symbol_get_frag (ptr)->line) 966 { 967 fprintf (list_file, "%20s:%-5d %s:%s %s\n", 968 symbol_get_frag (ptr)->line->file->filename, 969 symbol_get_frag (ptr)->line->line, 970 segment_name (S_GET_SEGMENT (ptr)), 971 buf, S_GET_NAME (ptr)); 972 } 973 else 974 { 975 fprintf (list_file, "%33s:%s %s\n", 976 segment_name (S_GET_SEGMENT (ptr)), 977 buf, S_GET_NAME (ptr)); 978 } 979 980 on_page++; 981 listing_page (NULL); 982 } 983 } 984 985 } 986 if (!got_some) 987 { 988 fprintf (list_file, "NO DEFINED SYMBOLS\n"); 989 on_page++; 990 } 991 emit_line (NULL, "\n"); 992 993 got_some = 0; 994 995 for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr)) 996 { 997 if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0) 998 { 999 if (S_GET_SEGMENT (ptr) == undefined_section) 1000 { 1001 if (!got_some) 1002 { 1003 got_some = 1; 1004 1005 emit_line (NULL, "UNDEFINED SYMBOLS\n"); 1006 } 1007 1008 emit_line (NULL, "%s\n", S_GET_NAME (ptr)); 1009 } 1010 } 1011 } 1012 1013 if (!got_some) 1014 emit_line (NULL, "NO UNDEFINED SYMBOLS\n"); 1015 } 1016 1017 typedef struct cached_line 1018 { 1019 file_info_type * file; 1020 unsigned int line; 1021 char buffer [LISTING_RHS_WIDTH]; 1022 } cached_line; 1023 1024 static void 1025 print_source (file_info_type * current_file, 1026 list_info_type * list, 1027 unsigned int width) 1028 { 1029 #define NUM_CACHE_LINES 3 1030 static cached_line cached_lines[NUM_CACHE_LINES]; 1031 static int next_free_line = 0; 1032 cached_line * cache = NULL; 1033 1034 if (current_file->linenum > list->hll_line 1035 && list->hll_line > 0) 1036 { 1037 /* This can happen with modern optimizing compilers. The source 1038 lines from the high level language input program are split up 1039 and interleaved, meaning the line number we want to display 1040 (list->hll_line) can have already been displayed. We have 1041 three choices: 1042 1043 a. Do nothing, since we have already displayed the source 1044 line. This was the old behaviour. 1045 1046 b. Display the particular line requested again, but only 1047 that line. This is the new behaviour. 1048 1049 c. Display the particular line requested again and reset 1050 the current_file->line_num value so that we redisplay 1051 all the following lines as well the next time we 1052 encounter a larger line number. */ 1053 int i; 1054 1055 /* Check the cache, maybe we already have the line saved. */ 1056 for (i = 0; i < NUM_CACHE_LINES; i++) 1057 if (cached_lines[i].file == current_file 1058 && cached_lines[i].line == list->hll_line) 1059 { 1060 cache = cached_lines + i; 1061 break; 1062 } 1063 1064 if (i == NUM_CACHE_LINES) 1065 { 1066 cache = cached_lines + next_free_line; 1067 next_free_line ++; 1068 if (next_free_line == NUM_CACHE_LINES) 1069 next_free_line = 0; 1070 1071 cache->file = current_file; 1072 cache->line = list->hll_line; 1073 cache->buffer[0] = 0; 1074 rebuffer_line (current_file, cache->line, cache->buffer, width); 1075 } 1076 1077 emit_line (list, "%4u:%-13s **** %s\n", 1078 cache->line, cache->file->filename, cache->buffer); 1079 return; 1080 } 1081 1082 if (!current_file->at_end) 1083 { 1084 int num_lines_shown = 0; 1085 1086 while (current_file->linenum < list->hll_line 1087 && !current_file->at_end) 1088 { 1089 const char *p; 1090 1091 cache = cached_lines + next_free_line; 1092 cache->file = current_file; 1093 cache->line = current_file->linenum + 1; 1094 cache->buffer[0] = 0; 1095 p = buffer_line (current_file, cache->buffer, width); 1096 1097 /* Cache optimization: If printing a group of lines 1098 cache the first and last lines in the group. */ 1099 if (num_lines_shown == 0) 1100 { 1101 next_free_line ++; 1102 if (next_free_line == NUM_CACHE_LINES) 1103 next_free_line = 0; 1104 } 1105 1106 emit_line (list, "%4u:%-13s **** %s\n", 1107 cache->line, cache->file->filename, p); 1108 num_lines_shown ++; 1109 } 1110 } 1111 } 1112 1113 /* Sometimes the user doesn't want to be bothered by the debugging 1114 records inserted by the compiler, see if the line is suspicious. */ 1115 1116 static int 1117 debugging_pseudo (list_info_type *list, const char *line) 1118 { 1119 #ifdef OBJ_ELF 1120 static int in_debug; 1121 int was_debug; 1122 #endif 1123 1124 if (list->debugging) 1125 { 1126 #ifdef OBJ_ELF 1127 in_debug = 1; 1128 #endif 1129 return 1; 1130 } 1131 #ifdef OBJ_ELF 1132 was_debug = in_debug; 1133 in_debug = 0; 1134 #endif 1135 1136 while (ISSPACE (*line)) 1137 line++; 1138 1139 if (*line != '.') 1140 { 1141 #ifdef OBJ_ELF 1142 /* The ELF compiler sometimes emits blank lines after switching 1143 out of a debugging section. If the next line drops us back 1144 into debugging information, then don't print the blank line. 1145 This is a hack for a particular compiler behaviour, not a 1146 general case. */ 1147 if (was_debug 1148 && *line == '\0' 1149 && list->next != NULL 1150 && list->next->debugging) 1151 { 1152 in_debug = 1; 1153 return 1; 1154 } 1155 #endif 1156 1157 return 0; 1158 } 1159 1160 line++; 1161 1162 if (strncmp (line, "def", 3) == 0) 1163 return 1; 1164 if (strncmp (line, "val", 3) == 0) 1165 return 1; 1166 if (strncmp (line, "scl", 3) == 0) 1167 return 1; 1168 if (strncmp (line, "line", 4) == 0) 1169 return 1; 1170 if (strncmp (line, "endef", 5) == 0) 1171 return 1; 1172 if (strncmp (line, "ln", 2) == 0) 1173 return 1; 1174 if (strncmp (line, "type", 4) == 0) 1175 return 1; 1176 if (strncmp (line, "size", 4) == 0) 1177 return 1; 1178 if (strncmp (line, "dim", 3) == 0) 1179 return 1; 1180 if (strncmp (line, "tag", 3) == 0) 1181 return 1; 1182 if (strncmp (line, "stabs", 5) == 0) 1183 return 1; 1184 if (strncmp (line, "stabn", 5) == 0) 1185 return 1; 1186 1187 return 0; 1188 } 1189 1190 static void 1191 listing_listing (char *name ATTRIBUTE_UNUSED) 1192 { 1193 list_info_type *list = head; 1194 file_info_type *current_hll_file = (file_info_type *) NULL; 1195 char *buffer; 1196 const char *p; 1197 int show_listing = 1; 1198 unsigned int width; 1199 1200 buffer = XNEWVEC (char, listing_rhs_width); 1201 data_buffer = XNEWVEC (char, MAX_BYTES); 1202 eject = 1; 1203 list = head->next; 1204 1205 while (list) 1206 { 1207 unsigned int list_line; 1208 1209 width = listing_rhs_width > paper_width ? paper_width : 1210 listing_rhs_width; 1211 1212 list_line = list->line; 1213 switch (list->edict) 1214 { 1215 case EDICT_LIST: 1216 /* Skip all lines up to the current. */ 1217 list_line--; 1218 break; 1219 case EDICT_NOLIST: 1220 show_listing--; 1221 break; 1222 case EDICT_NOLIST_NEXT: 1223 if (show_listing == 0) 1224 list_line--; 1225 break; 1226 case EDICT_EJECT: 1227 break; 1228 case EDICT_NONE: 1229 break; 1230 case EDICT_TITLE: 1231 title = list->edict_arg; 1232 break; 1233 case EDICT_SBTTL: 1234 subtitle = list->edict_arg; 1235 break; 1236 default: 1237 abort (); 1238 } 1239 1240 if (show_listing <= 0) 1241 { 1242 while (list->file->linenum < list_line 1243 && !list->file->at_end) 1244 p = buffer_line (list->file, buffer, width); 1245 } 1246 1247 if (list->edict == EDICT_LIST 1248 || (list->edict == EDICT_NOLIST_NEXT && show_listing == 0)) 1249 { 1250 /* Enable listing for the single line that caused the enable. */ 1251 list_line++; 1252 show_listing++; 1253 } 1254 1255 if (show_listing > 0) 1256 { 1257 /* Scan down the list and print all the stuff which can be done 1258 with this line (or lines). */ 1259 if (list->hll_file) 1260 current_hll_file = list->hll_file; 1261 1262 if (current_hll_file && list->hll_line && (listing & LISTING_HLL)) 1263 print_source (current_hll_file, list, width); 1264 1265 if (list->line_contents) 1266 { 1267 if (!((listing & LISTING_NODEBUG) 1268 && debugging_pseudo (list, list->line_contents))) 1269 print_lines (list, 1270 list->file->linenum == 0 ? list->line : list->file->linenum, 1271 list->line_contents, calc_hex (list)); 1272 1273 free (list->line_contents); 1274 list->line_contents = NULL; 1275 } 1276 else 1277 { 1278 while (list->file->linenum < list_line 1279 && !list->file->at_end) 1280 { 1281 unsigned int address; 1282 1283 p = buffer_line (list->file, buffer, width); 1284 1285 if (list->file->linenum < list_line) 1286 address = ~(unsigned int) 0; 1287 else 1288 address = calc_hex (list); 1289 1290 if (!((listing & LISTING_NODEBUG) 1291 && debugging_pseudo (list, p))) 1292 print_lines (list, list->file->linenum, p, address); 1293 } 1294 } 1295 1296 if (list->edict == EDICT_EJECT) 1297 eject = 1; 1298 } 1299 1300 if (list->edict == EDICT_NOLIST_NEXT && show_listing == 1) 1301 --show_listing; 1302 1303 list = list->next; 1304 } 1305 1306 free (buffer); 1307 free (data_buffer); 1308 data_buffer = NULL; 1309 } 1310 1311 /* Print time stamp in ISO format: yyyy-mm-ddThh:mm:ss.ss+/-zzzz. */ 1312 1313 static void 1314 print_timestamp (void) 1315 { 1316 const time_t now = time (NULL); 1317 struct tm * timestamp; 1318 char stampstr[MAX_DATELEN]; 1319 1320 /* Any portable way to obtain subsecond values??? */ 1321 timestamp = localtime (&now); 1322 strftime (stampstr, MAX_DATELEN, "%Y-%m-%dT%H:%M:%S.000%z", timestamp); 1323 fprintf (list_file, _("\n time stamp \t: %s\n\n"), stampstr); 1324 } 1325 1326 static void 1327 print_single_option (char * opt, int *pos) 1328 { 1329 int opt_len = strlen (opt); 1330 1331 if ((*pos + opt_len) < paper_width) 1332 { 1333 fprintf (list_file, _("%s "), opt); 1334 *pos = *pos + opt_len; 1335 } 1336 else 1337 { 1338 fprintf (list_file, _("\n\t%s "), opt); 1339 *pos = opt_len; 1340 } 1341 } 1342 1343 /* Print options passed to as. */ 1344 1345 static void 1346 print_options (char ** argv) 1347 { 1348 const char *field_name = _("\n options passed\t: "); 1349 int pos = strlen (field_name); 1350 char **p; 1351 1352 fputs (field_name, list_file); 1353 for (p = &argv[1]; *p != NULL; p++) 1354 if (**p == '-') 1355 { 1356 /* Ignore these. */ 1357 if (strcmp (*p, "-o") == 0) 1358 { 1359 if (p[1] != NULL) 1360 p++; 1361 continue; 1362 } 1363 if (strcmp (*p, "-v") == 0) 1364 continue; 1365 1366 print_single_option (*p, &pos); 1367 } 1368 } 1369 1370 /* Print a first section with basic info like file names, as version, 1371 options passed, target, and timestamp. 1372 The format of this section is as follows: 1373 1374 AS VERSION 1375 1376 fieldname TAB ':' fieldcontents 1377 { TAB fieldcontents-cont } */ 1378 1379 static void 1380 listing_general_info (char ** argv) 1381 { 1382 /* Print the stuff on the first line. */ 1383 eject = 1; 1384 listing_page (NULL); 1385 1386 fprintf (list_file, 1387 _(" GNU assembler version %s (%s)\n\t using BFD version %s."), 1388 VERSION, TARGET_ALIAS, BFD_VERSION_STRING); 1389 print_options (argv); 1390 fprintf (list_file, _("\n input file \t: %s"), fn); 1391 fprintf (list_file, _("\n output file \t: %s"), out_file_name); 1392 fprintf (list_file, _("\n target \t: %s"), TARGET_CANONICAL); 1393 print_timestamp (); 1394 } 1395 1396 void 1397 listing_print (char *name, char **argv) 1398 { 1399 int using_stdout; 1400 1401 title = ""; 1402 subtitle = ""; 1403 1404 if (name == NULL) 1405 { 1406 list_file = stdout; 1407 using_stdout = 1; 1408 } 1409 else 1410 { 1411 list_file = fopen (name, FOPEN_WT); 1412 if (list_file != NULL) 1413 using_stdout = 0; 1414 else 1415 { 1416 as_warn (_("can't open %s: %s"), name, xstrerror (errno)); 1417 list_file = stdout; 1418 using_stdout = 1; 1419 } 1420 } 1421 1422 if (listing & LISTING_NOFORM) 1423 paper_height = 0; 1424 1425 if (listing & LISTING_GENERAL) 1426 listing_general_info (argv); 1427 1428 if (listing & LISTING_LISTING) 1429 listing_listing (name); 1430 1431 if (listing & LISTING_SYMBOLS) 1432 list_symbol_table (); 1433 1434 if (! using_stdout) 1435 { 1436 if (fclose (list_file) == EOF) 1437 as_warn (_("can't close %s: %s"), name, xstrerror (errno)); 1438 } 1439 1440 if (last_open_file) 1441 fclose (last_open_file); 1442 } 1443 1444 void 1445 listing_file (const char *name) 1446 { 1447 fn = name; 1448 } 1449 1450 void 1451 listing_eject (int ignore ATTRIBUTE_UNUSED) 1452 { 1453 if (listing) 1454 listing_tail->edict = EDICT_EJECT; 1455 } 1456 1457 /* Turn listing on or off. An argument of 0 means to turn off 1458 listing. An argument of 1 means to turn on listing. An argument 1459 of 2 means to turn off listing, but as of the next line; that is, 1460 the current line should be listed, but the next line should not. */ 1461 1462 void 1463 listing_list (int on) 1464 { 1465 if (listing) 1466 { 1467 switch (on) 1468 { 1469 case 0: 1470 if (listing_tail->edict == EDICT_LIST) 1471 listing_tail->edict = EDICT_NONE; 1472 else 1473 listing_tail->edict = EDICT_NOLIST; 1474 break; 1475 case 1: 1476 if (listing_tail->edict == EDICT_NOLIST 1477 || listing_tail->edict == EDICT_NOLIST_NEXT) 1478 listing_tail->edict = EDICT_NONE; 1479 else 1480 listing_tail->edict = EDICT_LIST; 1481 break; 1482 case 2: 1483 listing_tail->edict = EDICT_NOLIST_NEXT; 1484 break; 1485 default: 1486 abort (); 1487 } 1488 } 1489 } 1490 1491 void 1492 listing_psize (int width_only) 1493 { 1494 if (! width_only) 1495 { 1496 paper_height = get_absolute_expression (); 1497 1498 if (paper_height < 0 || paper_height > 1000) 1499 { 1500 paper_height = 0; 1501 as_warn (_("strange paper height, set to no form")); 1502 } 1503 1504 if (*input_line_pointer != ',') 1505 { 1506 demand_empty_rest_of_line (); 1507 return; 1508 } 1509 1510 ++input_line_pointer; 1511 } 1512 1513 paper_width = get_absolute_expression (); 1514 1515 demand_empty_rest_of_line (); 1516 } 1517 1518 void 1519 listing_nopage (int ignore ATTRIBUTE_UNUSED) 1520 { 1521 paper_height = 0; 1522 } 1523 1524 void 1525 listing_title (int depth) 1526 { 1527 int quoted; 1528 char *start; 1529 char *ttl; 1530 unsigned int length; 1531 1532 SKIP_WHITESPACE (); 1533 if (*input_line_pointer != '\"') 1534 quoted = 0; 1535 else 1536 { 1537 quoted = 1; 1538 ++input_line_pointer; 1539 } 1540 1541 start = input_line_pointer; 1542 1543 while (*input_line_pointer) 1544 { 1545 if (quoted 1546 ? *input_line_pointer == '\"' 1547 : is_end_of_line[(unsigned char) *input_line_pointer]) 1548 { 1549 if (listing) 1550 { 1551 length = input_line_pointer - start; 1552 ttl = xmemdup0 (start, length); 1553 listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE; 1554 listing_tail->edict_arg = ttl; 1555 } 1556 if (quoted) 1557 input_line_pointer++; 1558 demand_empty_rest_of_line (); 1559 return; 1560 } 1561 else if (*input_line_pointer == '\n') 1562 { 1563 as_bad (_("new line in title")); 1564 demand_empty_rest_of_line (); 1565 return; 1566 } 1567 else 1568 { 1569 input_line_pointer++; 1570 } 1571 } 1572 } 1573 1574 void 1575 listing_source_line (unsigned int line) 1576 { 1577 if (listing) 1578 { 1579 new_frag (); 1580 listing_tail->hll_line = line; 1581 new_frag (); 1582 } 1583 } 1584 1585 void 1586 listing_source_file (const char *file) 1587 { 1588 if (listing) 1589 listing_tail->hll_file = file_info (file); 1590 } 1591 1592 #else 1593 1594 /* Dummy functions for when compiled without listing enabled. */ 1595 1596 void 1597 listing_list (int on) 1598 { 1599 s_ignore (0); 1600 } 1601 1602 void 1603 listing_eject (int ignore) 1604 { 1605 s_ignore (0); 1606 } 1607 1608 void 1609 listing_psize (int ignore) 1610 { 1611 s_ignore (0); 1612 } 1613 1614 void 1615 listing_nopage (int ignore) 1616 { 1617 s_ignore (0); 1618 } 1619 1620 void 1621 listing_title (int depth) 1622 { 1623 s_ignore (0); 1624 } 1625 1626 void 1627 listing_file (const char *name) 1628 { 1629 } 1630 1631 void 1632 listing_newline (char *name) 1633 { 1634 } 1635 1636 void 1637 listing_source_line (unsigned int n) 1638 { 1639 } 1640 1641 void 1642 listing_source_file (const char *n) 1643 { 1644 } 1645 1646 #endif 1647