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