use xstrdup, xmemdup0 and concat more
[deliverable/binutils-gdb.git] / gas / listing.c
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@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;
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 = (char *) xmalloc (len);
371
372 if (copy != NULL)
373 {
374 char *src = input_line_pointer;
375 char *dest = copy;
376
377 while (--len)
378 {
379 unsigned char c = *src++;
380
381 /* Omit control characters in the listing. */
382 if (!ISCNTRL (c))
383 *dest++ = c;
384 }
385
386 *dest = 0;
387 }
388
389 new_i->line_contents = copy;
390 }
391 else
392 new_i->line_contents = NULL;
393 }
394 else
395 {
396 new_i = XNEW (list_info_type);
397 new_i->line_contents = ps;
398 }
399
400 last_line = line;
401 last_file = file;
402
403 new_frag ();
404
405 if (listing_tail)
406 listing_tail->next = new_i;
407 else
408 head = new_i;
409
410 listing_tail = new_i;
411
412 new_i->frag = frag_now;
413 new_i->line = line;
414 new_i->file = file_info (file);
415 new_i->next = (list_info_type *) NULL;
416 new_i->messages = NULL;
417 new_i->last_message = NULL;
418 new_i->edict = EDICT_NONE;
419 new_i->hll_file = (file_info_type *) NULL;
420 new_i->hll_line = 0;
421 new_i->debugging = 0;
422
423 new_frag ();
424
425 #ifdef OBJ_ELF
426 /* In ELF, anything in a section beginning with .debug or .line is
427 considered to be debugging information. */
428 if ((listing & LISTING_NODEBUG) != 0)
429 {
430 const char *segname;
431
432 segname = segment_name (now_seg);
433 if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
434 || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
435 new_i->debugging = 1;
436 }
437 #endif
438 }
439
440 /* Attach all current frags to the previous line instead of the
441 current line. This is called by the MIPS backend when it discovers
442 that it needs to add some NOP instructions; the added NOP
443 instructions should go with the instruction that has the delay, not
444 with the new instruction. */
445
446 void
447 listing_prev_line (void)
448 {
449 list_info_type *l;
450 fragS *f;
451
452 if (head == (list_info_type *) NULL
453 || head == listing_tail)
454 return;
455
456 new_frag ();
457
458 for (l = head; l->next != listing_tail; l = l->next)
459 ;
460
461 for (f = frchain_now->frch_root; f != (fragS *) NULL; f = f->fr_next)
462 if (f->line == listing_tail)
463 f->line = l;
464
465 listing_tail->frag = frag_now;
466 new_frag ();
467 }
468
469 /* This function returns the next source line from the file supplied,
470 truncated to size. It appends a fake line to the end of each input
471 file to make using the returned buffer simpler. */
472
473 static const char *
474 buffer_line (file_info_type *file, char *line, unsigned int size)
475 {
476 unsigned int count = 0;
477 int c;
478 char *p = line;
479
480 /* If we couldn't open the file, return an empty line. */
481 if (file->at_end)
482 return "";
483
484 /* Check the cache and see if we last used this file. */
485 if (!last_open_file_info || file != last_open_file_info)
486 {
487 if (last_open_file)
488 {
489 last_open_file_info->pos = ftell (last_open_file);
490 fclose (last_open_file);
491 }
492
493 /* Open the file in the binary mode so that ftell above can
494 return a reliable value that we can feed to fseek below. */
495 last_open_file_info = file;
496 last_open_file = fopen (file->filename, FOPEN_RB);
497 if (last_open_file == NULL)
498 {
499 file->at_end = 1;
500 return "";
501 }
502
503 /* Seek to where we were last time this file was open. */
504 if (file->pos)
505 fseek (last_open_file, file->pos, SEEK_SET);
506 }
507
508 /* Leave room for null. */
509 size -= 1;
510
511 c = fgetc (last_open_file);
512
513 while (c != EOF && c != '\n' && c != '\r')
514 {
515 if (count < size)
516 *p++ = c;
517 count++;
518
519 c = fgetc (last_open_file);
520 }
521
522 /* If '\r' is followed by '\n', swallow that. Likewise, if '\n'
523 is followed by '\r', swallow that as well. */
524 if (c == '\r' || c == '\n')
525 {
526 int next = fgetc (last_open_file);
527
528 if ((c == '\r' && next != '\n')
529 || (c == '\n' && next != '\r'))
530 ungetc (next, last_open_file);
531 }
532
533 if (c == EOF)
534 {
535 file->at_end = 1;
536 if (count + 2 < size)
537 {
538 *p++ = '.';
539 *p++ = '.';
540 *p++ = '.';
541 }
542 }
543 file->linenum++;
544 *p++ = 0;
545 return line;
546 }
547
548
549 /* This function rewinds the requested file back to the line requested,
550 reads it in again into the buffer provided and then restores the file
551 back to its original location. */
552
553 static void
554 rebuffer_line (file_info_type * file,
555 unsigned int linenum,
556 char * buffer,
557 unsigned int size)
558 {
559 unsigned int count = 0;
560 unsigned int current_line;
561 char * p = buffer;
562 long pos;
563 long pos2;
564 int c;
565 bfd_boolean found = FALSE;
566
567 /* Sanity checks. */
568 if (file == NULL || buffer == NULL || size <= 1 || file->linenum <= linenum)
569 return;
570
571 /* Check the cache and see if we last used this file. */
572 if (last_open_file_info == NULL || file != last_open_file_info)
573 {
574 if (last_open_file)
575 {
576 last_open_file_info->pos = ftell (last_open_file);
577 fclose (last_open_file);
578 }
579
580 /* Open the file in the binary mode so that ftell above can
581 return a reliable value that we can feed to fseek below. */
582 last_open_file_info = file;
583 last_open_file = fopen (file->filename, FOPEN_RB);
584 if (last_open_file == NULL)
585 {
586 file->at_end = 1;
587 return;
588 }
589
590 /* Seek to where we were last time this file was open. */
591 if (file->pos)
592 fseek (last_open_file, file->pos, SEEK_SET);
593 }
594
595 /* Remember where we are in the current file. */
596 pos2 = pos = ftell (last_open_file);
597 if (pos < 3)
598 return;
599 current_line = file->linenum;
600
601 /* Leave room for the nul at the end of the buffer. */
602 size -= 1;
603 buffer[size] = 0;
604
605 /* Increment the current line count by one.
606 This is to allow for the fact that we are searching for the
607 start of a previous line, but we do this by detecting end-of-line
608 character(s) not start-of-line characters. */
609 ++ current_line;
610
611 while (pos2 > 0 && ! found)
612 {
613 char * ptr;
614
615 /* Move backwards through the file, looking for earlier lines. */
616 pos2 = (long) size > pos2 ? 0 : pos2 - size;
617 fseek (last_open_file, pos2, SEEK_SET);
618
619 /* Our caller has kindly provided us with a buffer, so we use it. */
620 if (fread (buffer, 1, size, last_open_file) != size)
621 {
622 as_warn (_("unable to rebuffer file: %s\n"), file->filename);
623 return;
624 }
625
626 for (ptr = buffer + size; ptr >= buffer; -- ptr)
627 {
628 if (*ptr == '\n')
629 {
630 -- current_line;
631
632 if (current_line == linenum)
633 {
634 /* We have found the start of the line we seek. */
635 found = TRUE;
636
637 /* FIXME: We could skip the read-in-the-line code
638 below if we know that we already have the whole
639 line in the buffer. */
640
641 /* Advance pos2 to the newline character we have just located. */
642 pos2 += (ptr - buffer);
643
644 /* Skip the newline and, if present, the carriage return. */
645 if (ptr + 1 == buffer + size)
646 {
647 ++pos2;
648 if (fgetc (last_open_file) == '\r')
649 ++ pos2;
650 }
651 else
652 pos2 += (ptr[1] == '\r' ? 2 : 1);
653
654 /* Move the file pointer to this location. */
655 fseek (last_open_file, pos2, SEEK_SET);
656 break;
657 }
658 }
659 }
660 }
661
662 /* Read in the line. */
663 c = fgetc (last_open_file);
664
665 while (c != EOF && c != '\n' && c != '\r')
666 {
667 if (count < size)
668 *p++ = c;
669 count++;
670
671 c = fgetc (last_open_file);
672 }
673
674 /* If '\r' is followed by '\n', swallow that. Likewise, if '\n'
675 is followed by '\r', swallow that as well. */
676 if (c == '\r' || c == '\n')
677 {
678 int next = fgetc (last_open_file);
679
680 if ((c == '\r' && next != '\n')
681 || (c == '\n' && next != '\r'))
682 ungetc (next, last_open_file);
683 }
684
685 /* Terminate the line. */
686 *p++ = 0;
687
688 /* Reset the file position. */
689 fseek (last_open_file, pos, SEEK_SET);
690 }
691
692 static const char *fn;
693 static unsigned int eject; /* Eject pending. */
694 static unsigned int page; /* Current page number. */
695 static const char *title; /* Current title. */
696 static const char *subtitle; /* Current subtitle. */
697 static unsigned int on_page; /* Number of lines printed on current page. */
698
699 static void
700 listing_page (list_info_type *list)
701 {
702 /* Grope around, see if we can see a title or subtitle edict coming up
703 soon. (we look down 10 lines of the page and see if it's there) */
704 if ((eject || (on_page >= (unsigned int) paper_height))
705 && paper_height != 0)
706 {
707 unsigned int c = 10;
708 int had_title = 0;
709 int had_subtitle = 0;
710
711 page++;
712
713 while (c != 0 && list)
714 {
715 if (list->edict == EDICT_SBTTL && !had_subtitle)
716 {
717 had_subtitle = 1;
718 subtitle = list->edict_arg;
719 }
720 if (list->edict == EDICT_TITLE && !had_title)
721 {
722 had_title = 1;
723 title = list->edict_arg;
724 }
725 list = list->next;
726 c--;
727 }
728
729 if (page > 1)
730 {
731 fprintf (list_file, "\f");
732 }
733
734 fprintf (list_file, "%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
735 fprintf (list_file, "%s\n", title);
736 fprintf (list_file, "%s\n", subtitle);
737 on_page = 3;
738 eject = 0;
739 }
740 }
741
742 /* Print a line into the list_file. Update the line count
743 and if necessary start a new page. */
744
745 static void
746 emit_line (list_info_type * list, const char * format, ...)
747 {
748 va_list args;
749
750 va_start (args, format);
751
752 vfprintf (list_file, format, args);
753 on_page++;
754 listing_page (list);
755
756 va_end (args);
757 }
758
759 static unsigned int
760 calc_hex (list_info_type *list)
761 {
762 int data_buffer_size;
763 list_info_type *first = list;
764 unsigned int address = ~(unsigned int) 0;
765 fragS *frag;
766 fragS *frag_ptr;
767 unsigned int octet_in_frag;
768
769 /* Find first frag which says it belongs to this line. */
770 frag = list->frag;
771 while (frag && frag->line != list)
772 frag = frag->fr_next;
773
774 frag_ptr = frag;
775
776 data_buffer_size = 0;
777
778 /* Dump all the frags which belong to this line. */
779 while (frag_ptr != (fragS *) NULL && frag_ptr->line == first)
780 {
781 /* Print as many bytes from the fixed part as is sensible. */
782 octet_in_frag = 0;
783 while ((offsetT) octet_in_frag < frag_ptr->fr_fix
784 && data_buffer_size < MAX_BYTES - 3)
785 {
786 if (address == ~(unsigned int) 0)
787 address = frag_ptr->fr_address / OCTETS_PER_BYTE;
788
789 sprintf (data_buffer + data_buffer_size,
790 "%02X",
791 (frag_ptr->fr_literal[octet_in_frag]) & 0xff);
792 data_buffer_size += 2;
793 octet_in_frag++;
794 }
795 if (frag_ptr->fr_type == rs_fill)
796 {
797 unsigned int var_rep_max = octet_in_frag;
798 unsigned int var_rep_idx = octet_in_frag;
799
800 /* Print as many bytes from the variable part as is sensible. */
801 while (((offsetT) octet_in_frag
802 < (frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset))
803 && data_buffer_size < MAX_BYTES - 3)
804 {
805 if (address == ~(unsigned int) 0)
806 address = frag_ptr->fr_address / OCTETS_PER_BYTE;
807
808 sprintf (data_buffer + data_buffer_size,
809 "%02X",
810 (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
811 data_buffer_size += 2;
812
813 var_rep_idx++;
814 octet_in_frag++;
815
816 if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var)
817 var_rep_idx = var_rep_max;
818 }
819 }
820
821 frag_ptr = frag_ptr->fr_next;
822 }
823 data_buffer[data_buffer_size] = '\0';
824 return address;
825 }
826
827 static void
828 print_lines (list_info_type *list, unsigned int lineno,
829 const char *string, unsigned int address)
830 {
831 unsigned int idx;
832 unsigned int nchars;
833 unsigned int lines;
834 unsigned int octet_in_word = 0;
835 char *src = data_buffer;
836 int cur;
837 struct list_message *msg;
838
839 /* Print the stuff on the first line. */
840 listing_page (list);
841 nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width;
842
843 /* Print the hex for the first line. */
844 if (address == ~(unsigned int) 0)
845 {
846 fprintf (list_file, "% 4d ", lineno);
847 for (idx = 0; idx < nchars; idx++)
848 fprintf (list_file, " ");
849
850 emit_line (NULL, "\t%s\n", string ? string : "");
851 return;
852 }
853
854 if (had_errors ())
855 fprintf (list_file, "% 4d ???? ", lineno);
856 else
857 fprintf (list_file, "% 4d %04x ", lineno, address);
858
859 /* And the data to go along with it. */
860 idx = 0;
861 cur = 0;
862 while (src[cur] && idx < nchars)
863 {
864 int offset;
865 offset = cur;
866 fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
867 cur += 2;
868 octet_in_word++;
869
870 if (octet_in_word == LISTING_WORD_SIZE)
871 {
872 fprintf (list_file, " ");
873 idx++;
874 octet_in_word = 0;
875 }
876
877 idx += 2;
878 }
879
880 for (; idx < nchars; idx++)
881 fprintf (list_file, " ");
882
883 emit_line (list, "\t%s\n", string ? string : "");
884
885 for (msg = list->messages; msg; msg = msg->next)
886 emit_line (list, "**** %s\n", msg->message);
887
888 for (lines = 0;
889 lines < (unsigned int) listing_lhs_cont_lines
890 && src[cur];
891 lines++)
892 {
893 nchars = ((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second - 1;
894 idx = 0;
895
896 /* Print any more lines of data, but more compactly. */
897 fprintf (list_file, "% 4d ", lineno);
898
899 while (src[cur] && idx < nchars)
900 {
901 int offset;
902 offset = cur;
903 fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
904 cur += 2;
905 idx += 2;
906 octet_in_word++;
907
908 if (octet_in_word == LISTING_WORD_SIZE)
909 {
910 fprintf (list_file, " ");
911 idx++;
912 octet_in_word = 0;
913 }
914 }
915
916 emit_line (list, "\n");
917 }
918 }
919
920 static void
921 list_symbol_table (void)
922 {
923 extern symbolS *symbol_rootP;
924 int got_some = 0;
925
926 symbolS *ptr;
927 eject = 1;
928 listing_page (NULL);
929
930 for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
931 {
932 if (SEG_NORMAL (S_GET_SEGMENT (ptr))
933 || S_GET_SEGMENT (ptr) == absolute_section)
934 {
935 /* Don't report section symbols. They are not interesting. */
936 if (symbol_section_p (ptr))
937 continue;
938
939 if (S_GET_NAME (ptr))
940 {
941 char buf[30], fmt[8];
942 valueT val = S_GET_VALUE (ptr);
943
944 /* @@ Note that this is dependent on the compilation options,
945 not solely on the target characteristics. */
946 if (sizeof (val) == 4 && sizeof (int) == 4)
947 sprintf (buf, "%08lx", (unsigned long) val);
948 else if (sizeof (val) <= sizeof (unsigned long))
949 {
950 sprintf (fmt, "%%0%lulx",
951 (unsigned long) (sizeof (val) * 2));
952 sprintf (buf, fmt, (unsigned long) val);
953 }
954 #if defined (BFD64)
955 else if (sizeof (val) > 4)
956 sprintf_vma (buf, val);
957 #endif
958 else
959 abort ();
960
961 if (!got_some)
962 {
963 fprintf (list_file, "DEFINED SYMBOLS\n");
964 on_page++;
965 got_some = 1;
966 }
967
968 if (symbol_get_frag (ptr) && symbol_get_frag (ptr)->line)
969 {
970 fprintf (list_file, "%20s:%-5d %s:%s %s\n",
971 symbol_get_frag (ptr)->line->file->filename,
972 symbol_get_frag (ptr)->line->line,
973 segment_name (S_GET_SEGMENT (ptr)),
974 buf, S_GET_NAME (ptr));
975 }
976 else
977 {
978 fprintf (list_file, "%33s:%s %s\n",
979 segment_name (S_GET_SEGMENT (ptr)),
980 buf, S_GET_NAME (ptr));
981 }
982
983 on_page++;
984 listing_page (NULL);
985 }
986 }
987
988 }
989 if (!got_some)
990 {
991 fprintf (list_file, "NO DEFINED SYMBOLS\n");
992 on_page++;
993 }
994 emit_line (NULL, "\n");
995
996 got_some = 0;
997
998 for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
999 {
1000 if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0)
1001 {
1002 if (S_GET_SEGMENT (ptr) == undefined_section)
1003 {
1004 if (!got_some)
1005 {
1006 got_some = 1;
1007
1008 emit_line (NULL, "UNDEFINED SYMBOLS\n");
1009 }
1010
1011 emit_line (NULL, "%s\n", S_GET_NAME (ptr));
1012 }
1013 }
1014 }
1015
1016 if (!got_some)
1017 emit_line (NULL, "NO UNDEFINED SYMBOLS\n");
1018 }
1019
1020 typedef struct cached_line
1021 {
1022 file_info_type * file;
1023 unsigned int line;
1024 char buffer [LISTING_RHS_WIDTH];
1025 } cached_line;
1026
1027 static void
1028 print_source (file_info_type * current_file,
1029 list_info_type * list,
1030 unsigned int width)
1031 {
1032 #define NUM_CACHE_LINES 3
1033 static cached_line cached_lines[NUM_CACHE_LINES];
1034 static int next_free_line = 0;
1035 cached_line * cache = NULL;
1036
1037 if (current_file->linenum > list->hll_line
1038 && list->hll_line > 0)
1039 {
1040 /* This can happen with modern optimizing compilers. The source
1041 lines from the high level language input program are split up
1042 and interleaved, meaning the line number we want to display
1043 (list->hll_line) can have already been displayed. We have
1044 three choices:
1045
1046 a. Do nothing, since we have already displayed the source
1047 line. This was the old behaviour.
1048
1049 b. Display the particular line requested again, but only
1050 that line. This is the new behaviour.
1051
1052 c. Display the particular line requested again and reset
1053 the current_file->line_num value so that we redisplay
1054 all the following lines as well the next time we
1055 encounter a larger line number. */
1056 int i;
1057
1058 /* Check the cache, maybe we already have the line saved. */
1059 for (i = 0; i < NUM_CACHE_LINES; i++)
1060 if (cached_lines[i].file == current_file
1061 && cached_lines[i].line == list->hll_line)
1062 {
1063 cache = cached_lines + i;
1064 break;
1065 }
1066
1067 if (i == NUM_CACHE_LINES)
1068 {
1069 cache = cached_lines + next_free_line;
1070 next_free_line ++;
1071 if (next_free_line == NUM_CACHE_LINES)
1072 next_free_line = 0;
1073
1074 cache->file = current_file;
1075 cache->line = list->hll_line;
1076 cache->buffer[0] = 0;
1077 rebuffer_line (current_file, cache->line, cache->buffer, width);
1078 }
1079
1080 emit_line (list, "%4u:%-13s **** %s\n",
1081 cache->line, cache->file->filename, cache->buffer);
1082 return;
1083 }
1084
1085 if (!current_file->at_end)
1086 {
1087 int num_lines_shown = 0;
1088
1089 while (current_file->linenum < list->hll_line
1090 && !current_file->at_end)
1091 {
1092 const char *p;
1093
1094 cache = cached_lines + next_free_line;
1095 cache->file = current_file;
1096 cache->line = current_file->linenum + 1;
1097 cache->buffer[0] = 0;
1098 p = buffer_line (current_file, cache->buffer, width);
1099
1100 /* Cache optimization: If printing a group of lines
1101 cache the first and last lines in the group. */
1102 if (num_lines_shown == 0)
1103 {
1104 next_free_line ++;
1105 if (next_free_line == NUM_CACHE_LINES)
1106 next_free_line = 0;
1107 }
1108
1109 emit_line (list, "%4u:%-13s **** %s\n",
1110 cache->line, cache->file->filename, p);
1111 num_lines_shown ++;
1112 }
1113 }
1114 }
1115
1116 /* Sometimes the user doesn't want to be bothered by the debugging
1117 records inserted by the compiler, see if the line is suspicious. */
1118
1119 static int
1120 debugging_pseudo (list_info_type *list, const char *line)
1121 {
1122 #ifdef OBJ_ELF
1123 static int in_debug;
1124 int was_debug;
1125 #endif
1126
1127 if (list->debugging)
1128 {
1129 #ifdef OBJ_ELF
1130 in_debug = 1;
1131 #endif
1132 return 1;
1133 }
1134 #ifdef OBJ_ELF
1135 was_debug = in_debug;
1136 in_debug = 0;
1137 #endif
1138
1139 while (ISSPACE (*line))
1140 line++;
1141
1142 if (*line != '.')
1143 {
1144 #ifdef OBJ_ELF
1145 /* The ELF compiler sometimes emits blank lines after switching
1146 out of a debugging section. If the next line drops us back
1147 into debugging information, then don't print the blank line.
1148 This is a hack for a particular compiler behaviour, not a
1149 general case. */
1150 if (was_debug
1151 && *line == '\0'
1152 && list->next != NULL
1153 && list->next->debugging)
1154 {
1155 in_debug = 1;
1156 return 1;
1157 }
1158 #endif
1159
1160 return 0;
1161 }
1162
1163 line++;
1164
1165 if (strncmp (line, "def", 3) == 0)
1166 return 1;
1167 if (strncmp (line, "val", 3) == 0)
1168 return 1;
1169 if (strncmp (line, "scl", 3) == 0)
1170 return 1;
1171 if (strncmp (line, "line", 4) == 0)
1172 return 1;
1173 if (strncmp (line, "endef", 5) == 0)
1174 return 1;
1175 if (strncmp (line, "ln", 2) == 0)
1176 return 1;
1177 if (strncmp (line, "type", 4) == 0)
1178 return 1;
1179 if (strncmp (line, "size", 4) == 0)
1180 return 1;
1181 if (strncmp (line, "dim", 3) == 0)
1182 return 1;
1183 if (strncmp (line, "tag", 3) == 0)
1184 return 1;
1185 if (strncmp (line, "stabs", 5) == 0)
1186 return 1;
1187 if (strncmp (line, "stabn", 5) == 0)
1188 return 1;
1189
1190 return 0;
1191 }
1192
1193 static void
1194 listing_listing (char *name ATTRIBUTE_UNUSED)
1195 {
1196 list_info_type *list = head;
1197 file_info_type *current_hll_file = (file_info_type *) NULL;
1198 char *buffer;
1199 const char *p;
1200 int show_listing = 1;
1201 unsigned int width;
1202
1203 buffer = (char *) xmalloc (listing_rhs_width);
1204 data_buffer = (char *) xmalloc (MAX_BYTES);
1205 eject = 1;
1206 list = head->next;
1207
1208 while (list)
1209 {
1210 unsigned int list_line;
1211
1212 width = listing_rhs_width > paper_width ? paper_width :
1213 listing_rhs_width;
1214
1215 list_line = list->line;
1216 switch (list->edict)
1217 {
1218 case EDICT_LIST:
1219 /* Skip all lines up to the current. */
1220 list_line--;
1221 break;
1222 case EDICT_NOLIST:
1223 show_listing--;
1224 break;
1225 case EDICT_NOLIST_NEXT:
1226 if (show_listing == 0)
1227 list_line--;
1228 break;
1229 case EDICT_EJECT:
1230 break;
1231 case EDICT_NONE:
1232 break;
1233 case EDICT_TITLE:
1234 title = list->edict_arg;
1235 break;
1236 case EDICT_SBTTL:
1237 subtitle = list->edict_arg;
1238 break;
1239 default:
1240 abort ();
1241 }
1242
1243 if (show_listing <= 0)
1244 {
1245 while (list->file->linenum < list_line
1246 && !list->file->at_end)
1247 p = buffer_line (list->file, buffer, width);
1248 }
1249
1250 if (list->edict == EDICT_LIST
1251 || (list->edict == EDICT_NOLIST_NEXT && show_listing == 0))
1252 {
1253 /* Enable listing for the single line that caused the enable. */
1254 list_line++;
1255 show_listing++;
1256 }
1257
1258 if (show_listing > 0)
1259 {
1260 /* Scan down the list and print all the stuff which can be done
1261 with this line (or lines). */
1262 if (list->hll_file)
1263 current_hll_file = list->hll_file;
1264
1265 if (current_hll_file && list->hll_line && (listing & LISTING_HLL))
1266 print_source (current_hll_file, list, width);
1267
1268 if (list->line_contents)
1269 {
1270 if (!((listing & LISTING_NODEBUG)
1271 && debugging_pseudo (list, list->line_contents)))
1272 print_lines (list,
1273 list->file->linenum == 0 ? list->line : list->file->linenum,
1274 list->line_contents, calc_hex (list));
1275
1276 free (list->line_contents);
1277 list->line_contents = NULL;
1278 }
1279 else
1280 {
1281 while (list->file->linenum < list_line
1282 && !list->file->at_end)
1283 {
1284 unsigned int address;
1285
1286 p = buffer_line (list->file, buffer, width);
1287
1288 if (list->file->linenum < list_line)
1289 address = ~(unsigned int) 0;
1290 else
1291 address = calc_hex (list);
1292
1293 if (!((listing & LISTING_NODEBUG)
1294 && debugging_pseudo (list, p)))
1295 print_lines (list, list->file->linenum, p, address);
1296 }
1297 }
1298
1299 if (list->edict == EDICT_EJECT)
1300 eject = 1;
1301 }
1302
1303 if (list->edict == EDICT_NOLIST_NEXT && show_listing == 1)
1304 --show_listing;
1305
1306 list = list->next;
1307 }
1308
1309 free (buffer);
1310 free (data_buffer);
1311 data_buffer = NULL;
1312 }
1313
1314 /* Print time stamp in ISO format: yyyy-mm-ddThh:mm:ss.ss+/-zzzz. */
1315
1316 static void
1317 print_timestamp (void)
1318 {
1319 const time_t now = time (NULL);
1320 struct tm * timestamp;
1321 char stampstr[MAX_DATELEN];
1322
1323 /* Any portable way to obtain subsecond values??? */
1324 timestamp = localtime (&now);
1325 strftime (stampstr, MAX_DATELEN, "%Y-%m-%dT%H:%M:%S.000%z", timestamp);
1326 fprintf (list_file, _("\n time stamp \t: %s\n\n"), stampstr);
1327 }
1328
1329 static void
1330 print_single_option (char * opt, int *pos)
1331 {
1332 int opt_len = strlen (opt);
1333
1334 if ((*pos + opt_len) < paper_width)
1335 {
1336 fprintf (list_file, _("%s "), opt);
1337 *pos = *pos + opt_len;
1338 }
1339 else
1340 {
1341 fprintf (list_file, _("\n\t%s "), opt);
1342 *pos = opt_len;
1343 }
1344 }
1345
1346 /* Print options passed to as. */
1347
1348 static void
1349 print_options (char ** argv)
1350 {
1351 const char *field_name = _("\n options passed\t: ");
1352 int pos = strlen (field_name);
1353 char **p;
1354
1355 fputs (field_name, list_file);
1356 for (p = &argv[1]; *p != NULL; p++)
1357 if (**p == '-')
1358 {
1359 /* Ignore these. */
1360 if (strcmp (*p, "-o") == 0)
1361 {
1362 if (p[1] != NULL)
1363 p++;
1364 continue;
1365 }
1366 if (strcmp (*p, "-v") == 0)
1367 continue;
1368
1369 print_single_option (*p, &pos);
1370 }
1371 }
1372
1373 /* Print a first section with basic info like file names, as version,
1374 options passed, target, and timestamp.
1375 The format of this section is as follows:
1376
1377 AS VERSION
1378
1379 fieldname TAB ':' fieldcontents
1380 { TAB fieldcontents-cont } */
1381
1382 static void
1383 listing_general_info (char ** argv)
1384 {
1385 /* Print the stuff on the first line. */
1386 eject = 1;
1387 listing_page (NULL);
1388
1389 fprintf (list_file,
1390 _(" GNU assembler version %s (%s)\n\t using BFD version %s."),
1391 VERSION, TARGET_ALIAS, BFD_VERSION_STRING);
1392 print_options (argv);
1393 fprintf (list_file, _("\n input file \t: %s"), fn);
1394 fprintf (list_file, _("\n output file \t: %s"), out_file_name);
1395 fprintf (list_file, _("\n target \t: %s"), TARGET_CANONICAL);
1396 print_timestamp ();
1397 }
1398
1399 void
1400 listing_print (char *name, char **argv)
1401 {
1402 int using_stdout;
1403
1404 title = "";
1405 subtitle = "";
1406
1407 if (name == NULL)
1408 {
1409 list_file = stdout;
1410 using_stdout = 1;
1411 }
1412 else
1413 {
1414 list_file = fopen (name, FOPEN_WT);
1415 if (list_file != NULL)
1416 using_stdout = 0;
1417 else
1418 {
1419 as_warn (_("can't open %s: %s"), name, xstrerror (errno));
1420 list_file = stdout;
1421 using_stdout = 1;
1422 }
1423 }
1424
1425 if (listing & LISTING_NOFORM)
1426 paper_height = 0;
1427
1428 if (listing & LISTING_GENERAL)
1429 listing_general_info (argv);
1430
1431 if (listing & LISTING_LISTING)
1432 listing_listing (name);
1433
1434 if (listing & LISTING_SYMBOLS)
1435 list_symbol_table ();
1436
1437 if (! using_stdout)
1438 {
1439 if (fclose (list_file) == EOF)
1440 as_warn (_("can't close %s: %s"), name, xstrerror (errno));
1441 }
1442
1443 if (last_open_file)
1444 fclose (last_open_file);
1445 }
1446
1447 void
1448 listing_file (const char *name)
1449 {
1450 fn = name;
1451 }
1452
1453 void
1454 listing_eject (int ignore ATTRIBUTE_UNUSED)
1455 {
1456 if (listing)
1457 listing_tail->edict = EDICT_EJECT;
1458 }
1459
1460 /* Turn listing on or off. An argument of 0 means to turn off
1461 listing. An argument of 1 means to turn on listing. An argument
1462 of 2 means to turn off listing, but as of the next line; that is,
1463 the current line should be listed, but the next line should not. */
1464
1465 void
1466 listing_list (int on)
1467 {
1468 if (listing)
1469 {
1470 switch (on)
1471 {
1472 case 0:
1473 if (listing_tail->edict == EDICT_LIST)
1474 listing_tail->edict = EDICT_NONE;
1475 else
1476 listing_tail->edict = EDICT_NOLIST;
1477 break;
1478 case 1:
1479 if (listing_tail->edict == EDICT_NOLIST
1480 || listing_tail->edict == EDICT_NOLIST_NEXT)
1481 listing_tail->edict = EDICT_NONE;
1482 else
1483 listing_tail->edict = EDICT_LIST;
1484 break;
1485 case 2:
1486 listing_tail->edict = EDICT_NOLIST_NEXT;
1487 break;
1488 default:
1489 abort ();
1490 }
1491 }
1492 }
1493
1494 void
1495 listing_psize (int width_only)
1496 {
1497 if (! width_only)
1498 {
1499 paper_height = get_absolute_expression ();
1500
1501 if (paper_height < 0 || paper_height > 1000)
1502 {
1503 paper_height = 0;
1504 as_warn (_("strange paper height, set to no form"));
1505 }
1506
1507 if (*input_line_pointer != ',')
1508 {
1509 demand_empty_rest_of_line ();
1510 return;
1511 }
1512
1513 ++input_line_pointer;
1514 }
1515
1516 paper_width = get_absolute_expression ();
1517
1518 demand_empty_rest_of_line ();
1519 }
1520
1521 void
1522 listing_nopage (int ignore ATTRIBUTE_UNUSED)
1523 {
1524 paper_height = 0;
1525 }
1526
1527 void
1528 listing_title (int depth)
1529 {
1530 int quoted;
1531 char *start;
1532 char *ttl;
1533 unsigned int length;
1534
1535 SKIP_WHITESPACE ();
1536 if (*input_line_pointer != '\"')
1537 quoted = 0;
1538 else
1539 {
1540 quoted = 1;
1541 ++input_line_pointer;
1542 }
1543
1544 start = input_line_pointer;
1545
1546 while (*input_line_pointer)
1547 {
1548 if (quoted
1549 ? *input_line_pointer == '\"'
1550 : is_end_of_line[(unsigned char) *input_line_pointer])
1551 {
1552 if (listing)
1553 {
1554 length = input_line_pointer - start;
1555 ttl = xmemdup0 (start, length);
1556 listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
1557 listing_tail->edict_arg = ttl;
1558 }
1559 if (quoted)
1560 input_line_pointer++;
1561 demand_empty_rest_of_line ();
1562 return;
1563 }
1564 else if (*input_line_pointer == '\n')
1565 {
1566 as_bad (_("new line in title"));
1567 demand_empty_rest_of_line ();
1568 return;
1569 }
1570 else
1571 {
1572 input_line_pointer++;
1573 }
1574 }
1575 }
1576
1577 void
1578 listing_source_line (unsigned int line)
1579 {
1580 if (listing)
1581 {
1582 new_frag ();
1583 listing_tail->hll_line = line;
1584 new_frag ();
1585 }
1586 }
1587
1588 void
1589 listing_source_file (const char *file)
1590 {
1591 if (listing)
1592 listing_tail->hll_file = file_info (file);
1593 }
1594
1595 #else
1596
1597 /* Dummy functions for when compiled without listing enabled. */
1598
1599 void
1600 listing_list (int on)
1601 {
1602 s_ignore (0);
1603 }
1604
1605 void
1606 listing_eject (int ignore)
1607 {
1608 s_ignore (0);
1609 }
1610
1611 void
1612 listing_psize (int ignore)
1613 {
1614 s_ignore (0);
1615 }
1616
1617 void
1618 listing_nopage (int ignore)
1619 {
1620 s_ignore (0);
1621 }
1622
1623 void
1624 listing_title (int depth)
1625 {
1626 s_ignore (0);
1627 }
1628
1629 void
1630 listing_file (const char *name)
1631 {
1632 }
1633
1634 void
1635 listing_newline (char *name)
1636 {
1637 }
1638
1639 void
1640 listing_source_line (unsigned int n)
1641 {
1642 }
1643
1644 void
1645 listing_source_file (const char *n)
1646 {
1647 }
1648
1649 #endif
This page took 0.136738 seconds and 5 git commands to generate.