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