* config/tc-alpha.c (alpha_prologue_label): Only define for ELF
[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;
341
342 for (copy = input_line_pointer - 1;
cf39a089
KH
343 *copy && (seen_quote
344 || (! is_end_of_line [(unsigned char) *copy]));
345 copy++)
346 if (*copy == '"' && copy[-1] != '\\')
252b5132
RH
347 seen_quote = ! seen_quote;
348
349 len = (copy - input_line_pointer) + 2;
350
351 copy = xmalloc (len);
352
353 if (copy != NULL)
354 {
cf39a089
KH
355 char *src = input_line_pointer - 1;
356 char *dest = copy;
357
252b5132
RH
358 while (--len)
359 {
cf39a089 360 unsigned char c = *src++;
252b5132
RH
361
362 /* Omit control characters in the listing. */
3882b010 363 if (!ISCNTRL (c))
cf39a089 364 *dest++ = c;
252b5132 365 }
cf39a089 366
252b5132
RH
367 *dest = 0;
368 }
cf39a089 369
252b5132
RH
370 new->line_contents = copy;
371 }
372 else
373 new->line_contents = NULL;
374 }
375 else
376 {
5a1964ec 377 new = xmalloc (sizeof (list_info_type));
252b5132
RH
378 new->line_contents = ps;
379 }
380
381 last_line = line;
382 last_file = file;
cf39a089 383
252b5132
RH
384 new_frag ();
385
386 if (listing_tail)
387 listing_tail->next = new;
388 else
389 head = new;
cf39a089 390
252b5132
RH
391 listing_tail = new;
392
393 new->frag = frag_now;
394 new->line = line;
395 new->file = file_info (file);
396 new->next = (list_info_type *) NULL;
397 new->message = (char *) NULL;
398 new->edict = EDICT_NONE;
399 new->hll_file = (file_info_type *) NULL;
400 new->hll_line = 0;
401 new->debugging = 0;
cf39a089 402
252b5132
RH
403 new_frag ();
404
405#ifdef OBJ_ELF
406 /* In ELF, anything in a section beginning with .debug or .line is
407 considered to be debugging information. */
408 if ((listing & LISTING_NODEBUG) != 0)
409 {
410 const char *segname;
411
412 segname = segment_name (now_seg);
413 if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
414 || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
415 new->debugging = 1;
416 }
417#endif
418}
419
420/* Attach all current frags to the previous line instead of the
421 current line. This is called by the MIPS backend when it discovers
422 that it needs to add some NOP instructions; the added NOP
423 instructions should go with the instruction that has the delay, not
424 with the new instruction. */
425
426void
254d758c 427listing_prev_line (void)
252b5132
RH
428{
429 list_info_type *l;
430 fragS *f;
431
432 if (head == (list_info_type *) NULL
433 || head == listing_tail)
434 return;
435
436 new_frag ();
437
438 for (l = head; l->next != listing_tail; l = l->next)
439 ;
440
441 for (f = frchain_now->frch_root; f != (fragS *) NULL; f = f->fr_next)
442 if (f->line == listing_tail)
443 f->line = l;
444
445 listing_tail->frag = frag_now;
446 new_frag ();
447}
448
cf39a089
KH
449/* This function returns the next source line from the file supplied,
450 truncated to size. It appends a fake line to the end of each input
451 file to make. */
252b5132
RH
452
453static char *
254d758c 454buffer_line (file_info_type *file, char *line, unsigned int size)
252b5132
RH
455{
456 unsigned int count = 0;
457 int c;
458
459 char *p = line;
460
cf39a089 461 /* If we couldn't open the file, return an empty line. */
252b5132
RH
462 if (file->at_end)
463 return "";
464
465 /* Check the cache and see if we last used this file. */
466 if (!last_open_file_info || file != last_open_file_info)
467 {
468 if (last_open_file)
469 {
470 last_open_file_info->pos = ftell (last_open_file);
471 fclose (last_open_file);
472 }
473
7e66d8ac
KH
474 /* Open the file in the binary mode so that ftell above can
475 return a reliable value that we can feed to fseek below. */
252b5132 476 last_open_file_info = file;
7e66d8ac 477 last_open_file = fopen (file->filename, FOPEN_RB);
252b5132
RH
478 if (last_open_file == NULL)
479 {
480 file->at_end = 1;
481 return "";
482 }
cf39a089 483
252b5132
RH
484 /* Seek to where we were last time this file was open. */
485 if (file->pos)
cf39a089 486 fseek (last_open_file, file->pos, SEEK_SET);
252b5132
RH
487 }
488
489 c = fgetc (last_open_file);
490
cf39a089
KH
491 /* Leave room for null. */
492 size -= 1;
252b5132 493
7e66d8ac 494 while (c != EOF && c != '\n' && c != '\r')
252b5132
RH
495 {
496 if (count < size)
497 *p++ = c;
498 count++;
499
500 c = fgetc (last_open_file);
501
502 }
7e66d8ac
KH
503
504 /* If '\r' is followed by '\n', swallow that. Likewise, if '\n'
505 is followed by '\r', swallow that as well. */
506 if (c == '\r' || c == '\n')
507 {
508 int next = fgetc (last_open_file);
509 if ((c == '\r' && next != '\n')
510 || (c == '\n' && next != '\r'))
511 ungetc (next, last_open_file);
512 }
513
252b5132
RH
514 if (c == EOF)
515 {
516 file->at_end = 1;
97735a42
AM
517 if (count + 2 < size)
518 {
519 *p++ = '.';
520 *p++ = '.';
521 *p++ = '.';
522 }
252b5132
RH
523 }
524 file->linenum++;
525 *p++ = 0;
526 return line;
527}
528
252b5132
RH
529static const char *fn;
530
531static unsigned int eject; /* Eject pending */
532static unsigned int page; /* Current page number */
cf39a089
KH
533static char *title; /* Current title */
534static char *subtitle; /* Current subtitle */
535static unsigned int on_page; /* Number of lines printed on current page */
252b5132
RH
536
537static void
254d758c 538listing_page (list_info_type *list)
252b5132
RH
539{
540 /* Grope around, see if we can see a title or subtitle edict coming up
cf39a089
KH
541 soon. (we look down 10 lines of the page and see if it's there) */
542 if ((eject || (on_page >= (unsigned int) paper_height))
543 && paper_height != 0)
252b5132
RH
544 {
545 unsigned int c = 10;
546 int had_title = 0;
547 int had_subtitle = 0;
548
549 page++;
550
551 while (c != 0 && list)
552 {
553 if (list->edict == EDICT_SBTTL && !had_subtitle)
554 {
555 had_subtitle = 1;
556 subtitle = list->edict_arg;
557 }
558 if (list->edict == EDICT_TITLE && !had_title)
559 {
560 had_title = 1;
561 title = list->edict_arg;
562 }
563 list = list->next;
564 c--;
565 }
566
252b5132
RH
567 if (page > 1)
568 {
569 fprintf (list_file, "\f");
570 }
571
572 fprintf (list_file, "%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
573 fprintf (list_file, "%s\n", title);
574 fprintf (list_file, "%s\n", subtitle);
575 on_page = 3;
576 eject = 0;
577 }
578}
579
252b5132 580static unsigned int
254d758c 581calc_hex (list_info_type *list)
252b5132
RH
582{
583 int data_buffer_size;
584 list_info_type *first = list;
cf39a089 585 unsigned int address = ~(unsigned int) 0;
252b5132
RH
586 fragS *frag;
587 fragS *frag_ptr;
bea9907b 588 unsigned int octet_in_frag;
252b5132 589
cf39a089 590 /* Find first frag which says it belongs to this line. */
252b5132
RH
591 frag = list->frag;
592 while (frag && frag->line != list)
593 frag = frag->fr_next;
594
595 frag_ptr = frag;
596
597 data_buffer_size = 0;
598
cf39a089 599 /* Dump all the frags which belong to this line. */
252b5132
RH
600 while (frag_ptr != (fragS *) NULL && frag_ptr->line == first)
601 {
cf39a089 602 /* Print as many bytes from the fixed part as is sensible. */
bea9907b
TW
603 octet_in_frag = 0;
604 while ((offsetT) octet_in_frag < frag_ptr->fr_fix
252b5132
RH
605 && data_buffer_size < MAX_BYTES - 3)
606 {
cf39a089 607 if (address == ~(unsigned int) 0)
5a1964ec 608 address = frag_ptr->fr_address / OCTETS_PER_BYTE;
252b5132
RH
609
610 sprintf (data_buffer + data_buffer_size,
611 "%02X",
bea9907b 612 (frag_ptr->fr_literal[octet_in_frag]) & 0xff);
252b5132 613 data_buffer_size += 2;
bea9907b 614 octet_in_frag++;
252b5132 615 }
411863a4
KH
616 if (frag_ptr->fr_type == rs_fill)
617 {
618 unsigned int var_rep_max = octet_in_frag;
619 unsigned int var_rep_idx = octet_in_frag;
620
621 /* Print as many bytes from the variable part as is sensible. */
622 while (((offsetT) octet_in_frag
623 < (frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset))
624 && data_buffer_size < MAX_BYTES - 3)
625 {
626 if (address == ~(unsigned int) 0)
5a1964ec
NC
627 address = frag_ptr->fr_address / OCTETS_PER_BYTE;
628
411863a4
KH
629 sprintf (data_buffer + data_buffer_size,
630 "%02X",
631 (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
411863a4 632 data_buffer_size += 2;
252b5132 633
411863a4
KH
634 var_rep_idx++;
635 octet_in_frag++;
252b5132 636
411863a4
KH
637 if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var)
638 var_rep_idx = var_rep_max;
639 }
640 }
252b5132
RH
641
642 frag_ptr = frag_ptr->fr_next;
643 }
644 data_buffer[data_buffer_size] = '\0';
645 return address;
646}
647
252b5132 648static void
254d758c
KH
649print_lines (list_info_type *list, unsigned int lineno,
650 char *string, unsigned int address)
252b5132
RH
651{
652 unsigned int idx;
653 unsigned int nchars;
654 unsigned int lines;
bea9907b 655 unsigned int octet_in_word = 0;
252b5132 656 char *src = data_buffer;
bea9907b 657 int cur;
252b5132 658
cf39a089 659 /* Print the stuff on the first line. */
252b5132
RH
660 listing_page (list);
661 nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width;
cf39a089
KH
662
663 /* Print the hex for the first line. */
664 if (address == ~(unsigned int) 0)
252b5132
RH
665 {
666 fprintf (list_file, "% 4d ", lineno);
667 for (idx = 0; idx < nchars; idx++)
668 fprintf (list_file, " ");
669
670 fprintf (list_file, "\t%s\n", string ? string : "");
cf39a089
KH
671
672 on_page++;
673
252b5132
RH
674 listing_page (0);
675
676 return;
677 }
678
679 if (had_errors ())
680 fprintf (list_file, "% 4d ???? ", lineno);
681 else
682 fprintf (list_file, "% 4d %04x ", lineno, address);
683
cf39a089 684 /* And the data to go along with it. */
252b5132 685 idx = 0;
bea9907b
TW
686 cur = 0;
687 while (src[cur] && idx < nchars)
252b5132 688 {
bea9907b 689 int offset;
bea9907b 690 offset = cur;
cf39a089 691 fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
bea9907b
TW
692 cur += 2;
693 octet_in_word++;
cf39a089 694
bea9907b 695 if (octet_in_word == LISTING_WORD_SIZE)
252b5132
RH
696 {
697 fprintf (list_file, " ");
698 idx++;
bea9907b 699 octet_in_word = 0;
252b5132 700 }
cf39a089 701
252b5132
RH
702 idx += 2;
703 }
cf39a089 704
252b5132
RH
705 for (; idx < nchars; idx++)
706 fprintf (list_file, " ");
cf39a089 707
252b5132
RH
708 fprintf (list_file, "\t%s\n", string ? string : "");
709 on_page++;
710 listing_page (list);
cf39a089 711
252b5132
RH
712 if (list->message)
713 {
714 fprintf (list_file, "**** %s\n", list->message);
715 listing_page (list);
716 on_page++;
717 }
cf39a089 718
252b5132
RH
719 for (lines = 0;
720 lines < (unsigned int) listing_lhs_cont_lines
bea9907b 721 && src[cur];
cf39a089 722 lines++)
252b5132 723 {
cf39a089 724 nchars = ((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second - 1;
252b5132 725 idx = 0;
cf39a089
KH
726
727 /* Print any more lines of data, but more compactly. */
252b5132 728 fprintf (list_file, "% 4d ", lineno);
cf39a089 729
bea9907b 730 while (src[cur] && idx < nchars)
252b5132 731 {
cf39a089
KH
732 int offset;
733 offset = cur;
734 fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
bea9907b 735 cur += 2;
252b5132 736 idx += 2;
bea9907b 737 octet_in_word++;
cf39a089 738
bea9907b 739 if (octet_in_word == LISTING_WORD_SIZE)
252b5132
RH
740 {
741 fprintf (list_file, " ");
742 idx++;
bea9907b 743 octet_in_word = 0;
252b5132
RH
744 }
745 }
cf39a089 746
252b5132 747 fprintf (list_file, "\n");
cf39a089 748 on_page++;
252b5132
RH
749 listing_page (list);
750 }
751}
752
252b5132 753static void
254d758c 754list_symbol_table (void)
252b5132
RH
755{
756 extern symbolS *symbol_rootP;
757 int got_some = 0;
758
759 symbolS *ptr;
760 eject = 1;
761 listing_page (0);
762
763 for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
764 {
765 if (SEG_NORMAL (S_GET_SEGMENT (ptr))
766 || S_GET_SEGMENT (ptr) == absolute_section)
767 {
252b5132 768 /* Don't report section symbols. They are not interesting. */
49309057 769 if (symbol_section_p (ptr))
252b5132 770 continue;
7be1c489 771
252b5132
RH
772 if (S_GET_NAME (ptr))
773 {
774 char buf[30], fmt[8];
775 valueT val = S_GET_VALUE (ptr);
776
777 /* @@ Note that this is dependent on the compilation options,
778 not solely on the target characteristics. */
779 if (sizeof (val) == 4 && sizeof (int) == 4)
780 sprintf (buf, "%08lx", (unsigned long) val);
781 else if (sizeof (val) <= sizeof (unsigned long))
782 {
783 sprintf (fmt, "%%0%lulx",
784 (unsigned long) (sizeof (val) * 2));
785 sprintf (buf, fmt, (unsigned long) val);
786 }
787#if defined (BFD64)
788 else if (sizeof (val) > 4)
789 sprintf_vma (buf, val);
790#endif
791 else
792 abort ();
793
794 if (!got_some)
795 {
796 fprintf (list_file, "DEFINED SYMBOLS\n");
797 on_page++;
798 got_some = 1;
799 }
800
49309057 801 if (symbol_get_frag (ptr) && symbol_get_frag (ptr)->line)
252b5132
RH
802 {
803 fprintf (list_file, "%20s:%-5d %s:%s %s\n",
49309057
ILT
804 symbol_get_frag (ptr)->line->file->filename,
805 symbol_get_frag (ptr)->line->line,
252b5132
RH
806 segment_name (S_GET_SEGMENT (ptr)),
807 buf, S_GET_NAME (ptr));
808 }
809 else
810 {
811 fprintf (list_file, "%33s:%s %s\n",
812 segment_name (S_GET_SEGMENT (ptr)),
813 buf, S_GET_NAME (ptr));
814 }
815
cf39a089 816 on_page++;
252b5132
RH
817 listing_page (0);
818 }
819 }
820
821 }
822 if (!got_some)
823 {
824 fprintf (list_file, "NO DEFINED SYMBOLS\n");
825 on_page++;
826 }
827 fprintf (list_file, "\n");
828 on_page++;
829 listing_page (0);
830
831 got_some = 0;
832
833 for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
834 {
835 if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0)
836 {
837 if (S_GET_SEGMENT (ptr) == undefined_section)
838 {
839 if (!got_some)
840 {
841 got_some = 1;
842 fprintf (list_file, "UNDEFINED SYMBOLS\n");
843 on_page++;
844 listing_page (0);
845 }
846 fprintf (list_file, "%s\n", S_GET_NAME (ptr));
847 on_page++;
848 listing_page (0);
849 }
850 }
851 }
852 if (!got_some)
853 {
854 fprintf (list_file, "NO UNDEFINED SYMBOLS\n");
855 on_page++;
856 listing_page (0);
857 }
858}
859
860static void
254d758c
KH
861print_source (file_info_type *current_file, list_info_type *list,
862 char *buffer, unsigned int width)
252b5132
RH
863{
864 if (!current_file->at_end)
865 {
866 while (current_file->linenum < list->hll_line
867 && !current_file->at_end)
868 {
869 char *p = buffer_line (current_file, buffer, width);
5a1964ec 870
252b5132
RH
871 fprintf (list_file, "%4u:%-13s **** %s\n", current_file->linenum,
872 current_file->filename, p);
873 on_page++;
874 listing_page (list);
875 }
876 }
877}
878
879/* Sometimes the user doesn't want to be bothered by the debugging
880 records inserted by the compiler, see if the line is suspicious. */
881
882static int
254d758c 883debugging_pseudo (list_info_type *list, const char *line)
252b5132
RH
884{
885 static int in_debug;
886 int was_debug;
887
888 if (list->debugging)
889 {
890 in_debug = 1;
891 return 1;
892 }
893
894 was_debug = in_debug;
895 in_debug = 0;
896
3882b010 897 while (ISSPACE (*line))
252b5132
RH
898 line++;
899
900 if (*line != '.')
901 {
902#ifdef OBJ_ELF
903 /* The ELF compiler sometimes emits blank lines after switching
904 out of a debugging section. If the next line drops us back
905 into debugging information, then don't print the blank line.
906 This is a hack for a particular compiler behaviour, not a
907 general case. */
908 if (was_debug
909 && *line == '\0'
910 && list->next != NULL
911 && list->next->debugging)
912 {
913 in_debug = 1;
914 return 1;
915 }
916#endif
917
918 return 0;
919 }
920
921 line++;
922
923 if (strncmp (line, "def", 3) == 0)
924 return 1;
925 if (strncmp (line, "val", 3) == 0)
926 return 1;
927 if (strncmp (line, "scl", 3) == 0)
928 return 1;
929 if (strncmp (line, "line", 4) == 0)
930 return 1;
931 if (strncmp (line, "endef", 5) == 0)
932 return 1;
933 if (strncmp (line, "ln", 2) == 0)
934 return 1;
935 if (strncmp (line, "type", 4) == 0)
936 return 1;
937 if (strncmp (line, "size", 4) == 0)
938 return 1;
939 if (strncmp (line, "dim", 3) == 0)
940 return 1;
941 if (strncmp (line, "tag", 3) == 0)
942 return 1;
252b5132
RH
943 if (strncmp (line, "stabs", 5) == 0)
944 return 1;
945 if (strncmp (line, "stabn", 5) == 0)
946 return 1;
947
948 return 0;
949}
950
951static void
254d758c 952listing_listing (char *name ATTRIBUTE_UNUSED)
252b5132
RH
953{
954 list_info_type *list = head;
955 file_info_type *current_hll_file = (file_info_type *) NULL;
956 char *message;
957 char *buffer;
958 char *p;
959 int show_listing = 1;
960 unsigned int width;
961
962 buffer = xmalloc (listing_rhs_width);
963 data_buffer = xmalloc (MAX_BYTES);
964 eject = 1;
252b5132
RH
965 list = head->next;
966
252b5132
RH
967 while (list)
968 {
ab9da554 969 unsigned int list_line;
252b5132
RH
970
971 width = listing_rhs_width > paper_width ? paper_width :
972 listing_rhs_width;
973
974 list_line = list->line;
975 switch (list->edict)
976 {
977 case EDICT_LIST:
978 /* Skip all lines up to the current. */
979 list_line--;
980 break;
981 case EDICT_NOLIST:
982 show_listing--;
983 break;
984 case EDICT_NOLIST_NEXT:
61b96bb4
AM
985 if (show_listing == 0)
986 list_line--;
252b5132
RH
987 break;
988 case EDICT_EJECT:
989 break;
990 case EDICT_NONE:
991 break;
992 case EDICT_TITLE:
993 title = list->edict_arg;
994 break;
995 case EDICT_SBTTL:
996 subtitle = list->edict_arg;
997 break;
998 default:
999 abort ();
1000 }
1001
1002 if (show_listing <= 0)
1003 {
1004 while (list->file->linenum < list_line
1005 && !list->file->at_end)
1006 p = buffer_line (list->file, buffer, width);
1007 }
1008
61b96bb4
AM
1009 if (list->edict == EDICT_LIST
1010 || (list->edict == EDICT_NOLIST_NEXT && show_listing == 0))
252b5132
RH
1011 {
1012 /* Enable listing for the single line that caused the enable. */
1013 list_line++;
1014 show_listing++;
1015 }
1016
1017 if (show_listing > 0)
1018 {
1019 /* Scan down the list and print all the stuff which can be done
1020 with this line (or lines). */
1021 message = 0;
1022
1023 if (list->hll_file)
5a1964ec 1024 current_hll_file = list->hll_file;
252b5132
RH
1025
1026 if (current_hll_file && list->hll_line && (listing & LISTING_HLL))
5a1964ec 1027 print_source (current_hll_file, list, buffer, width);
252b5132
RH
1028
1029 if (list->line_contents)
1030 {
1031 if (!((listing & LISTING_NODEBUG)
1032 && debugging_pseudo (list, list->line_contents)))
5a1964ec
NC
1033 print_lines (list,
1034 list->file->linenum == 0 ? list->line : list->file->linenum,
1035 list->line_contents, calc_hex (list));
1036
252b5132
RH
1037 free (list->line_contents);
1038 list->line_contents = NULL;
1039 }
1040 else
1041 {
1042 while (list->file->linenum < list_line
1043 && !list->file->at_end)
1044 {
1045 unsigned int address;
1046
1047 p = buffer_line (list->file, buffer, width);
1048
1049 if (list->file->linenum < list_line)
cf39a089 1050 address = ~(unsigned int) 0;
252b5132
RH
1051 else
1052 address = calc_hex (list);
1053
1054 if (!((listing & LISTING_NODEBUG)
1055 && debugging_pseudo (list, p)))
1056 print_lines (list, list->file->linenum, p, address);
1057 }
1058 }
1059
1060 if (list->edict == EDICT_EJECT)
5a1964ec 1061 eject = 1;
252b5132
RH
1062 }
1063
61b96bb4 1064 if (list->edict == EDICT_NOLIST_NEXT && show_listing == 1)
252b5132
RH
1065 --show_listing;
1066
1067 list = list->next;
1068 }
1069
1070 free (buffer);
1071 free (data_buffer);
1072 data_buffer = NULL;
1073}
1074
83f10cb2
NC
1075/* Print time stamp in ISO format: yyyy-mm-ddThh:mm:ss.ss+/-zzzz. */
1076
1077static void
1078print_timestamp (void)
1079{
1080 const time_t now = time (NULL);
d5a35a55 1081 struct tm * timestamp;
83f10cb2
NC
1082 char stampstr[MAX_DATELEN];
1083
1084 /* Any portable way to obtain subsecond values??? */
d5a35a55
NC
1085 timestamp = localtime (&now);
1086 strftime (stampstr, MAX_DATELEN, "%Y-%m-%dT%H:%M:%S.000%z", timestamp);
83f10cb2
NC
1087 fprintf (list_file, _("\n time stamp \t: %s\n\n"), stampstr);
1088}
1089
1090static void
1091print_single_option (char * opt, int *pos)
1092{
1093 int opt_len = strlen (opt);
1094
1095 if ((*pos + opt_len) < paper_width)
1096 {
1097 fprintf (list_file, _("%s "), opt);
1098 *pos = *pos + opt_len;
1099 }
1100 else
1101 {
1102 fprintf (list_file, _("\n\t%s "), opt);
1103 *pos = opt_len;
1104 }
1105}
1106
1107/* Print options passed to as. */
1108
1109static void
1110print_options (char ** argv)
1111{
1112 const char *field_name = _("\n options passed\t: ");
1113 int pos = strlen (field_name);
1114 char **p;
1115
ead47374 1116 fputs (field_name, list_file);
83f10cb2
NC
1117 for (p = &argv[1]; *p != NULL; p++)
1118 if (**p == '-')
1119 {
1120 /* Ignore these. */
1121 if (strcmp (*p, "-o") == 0)
1122 {
1123 if (p[1] != NULL)
1124 p++;
1125 continue;
1126 }
1127 if (strcmp (*p, "-v") == 0)
1128 continue;
1129
1130 print_single_option (*p, &pos);
1131 }
1132}
1133
1134/* Print a first section with basic info like file names, as version,
1135 options passed, target, and timestamp.
1136 The format of this section is as follows:
1137
1138 AS VERSION
1139
1140 fieldname TAB ':' fieldcontents
1141 { TAB fieldcontents-cont } */
1142
1143static void
1144listing_general_info (char ** argv)
1145{
1146 /* Print the stuff on the first line. */
1147 eject = 1;
1148 listing_page (0);
1149
1150 fprintf (list_file,
1151 _(" GNU assembler version %s (%s)\n\t using BFD version %s."),
1152 VERSION, TARGET_ALIAS, BFD_VERSION_STRING);
1153 print_options (argv);
1154 fprintf (list_file, _("\n input file \t: %s"), fn);
1155 fprintf (list_file, _("\n output file \t: %s"), out_file_name);
1156 fprintf (list_file, _("\n target \t: %s"), TARGET_CANONICAL);
1157 print_timestamp ();
1158}
1159
252b5132 1160void
83f10cb2 1161listing_print (char *name, char **argv)
252b5132
RH
1162{
1163 int using_stdout;
cf39a089 1164
252b5132
RH
1165 title = "";
1166 subtitle = "";
1167
1168 if (name == NULL)
1169 {
1170 list_file = stdout;
1171 using_stdout = 1;
1172 }
1173 else
1174 {
f740e790 1175 list_file = fopen (name, FOPEN_WT);
252b5132
RH
1176 if (list_file != NULL)
1177 using_stdout = 0;
1178 else
1179 {
885afe7b 1180 as_warn (_("can't open %s: %s"), name, xstrerror (errno));
252b5132
RH
1181 list_file = stdout;
1182 using_stdout = 1;
1183 }
1184 }
1185
1186 if (listing & LISTING_NOFORM)
5a1964ec 1187 paper_height = 0;
252b5132 1188
83f10cb2
NC
1189 if (listing & LISTING_GENERAL)
1190 listing_general_info (argv);
1191
252b5132 1192 if (listing & LISTING_LISTING)
5a1964ec 1193 listing_listing (name);
252b5132
RH
1194
1195 if (listing & LISTING_SYMBOLS)
5a1964ec 1196 list_symbol_table ();
252b5132
RH
1197
1198 if (! using_stdout)
1199 {
1200 if (fclose (list_file) == EOF)
885afe7b 1201 as_warn (_("can't close %s: %s"), name, xstrerror (errno));
252b5132
RH
1202 }
1203
1204 if (last_open_file)
5a1964ec 1205 fclose (last_open_file);
252b5132
RH
1206}
1207
252b5132 1208void
254d758c 1209listing_file (const char *name)
252b5132
RH
1210{
1211 fn = name;
1212}
1213
1214void
254d758c 1215listing_eject (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
1216{
1217 if (listing)
1218 listing_tail->edict = EDICT_EJECT;
1219}
1220
1221void
254d758c 1222listing_flags (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
1223{
1224 while ((*input_line_pointer++) && (*input_line_pointer != '\n'))
1225 input_line_pointer++;
1226
1227}
1228
1229/* Turn listing on or off. An argument of 0 means to turn off
1230 listing. An argument of 1 means to turn on listing. An argument
1231 of 2 means to turn off listing, but as of the next line; that is,
1232 the current line should be listed, but the next line should not. */
1233
1234void
254d758c 1235listing_list (int on)
252b5132
RH
1236{
1237 if (listing)
1238 {
1239 switch (on)
1240 {
1241 case 0:
1242 if (listing_tail->edict == EDICT_LIST)
1243 listing_tail->edict = EDICT_NONE;
1244 else
1245 listing_tail->edict = EDICT_NOLIST;
1246 break;
1247 case 1:
1248 if (listing_tail->edict == EDICT_NOLIST
1249 || listing_tail->edict == EDICT_NOLIST_NEXT)
1250 listing_tail->edict = EDICT_NONE;
1251 else
1252 listing_tail->edict = EDICT_LIST;
1253 break;
1254 case 2:
1255 listing_tail->edict = EDICT_NOLIST_NEXT;
1256 break;
1257 default:
1258 abort ();
1259 }
1260 }
1261}
1262
252b5132 1263void
254d758c 1264listing_psize (int width_only)
252b5132
RH
1265{
1266 if (! width_only)
1267 {
1268 paper_height = get_absolute_expression ();
1269
1270 if (paper_height < 0 || paper_height > 1000)
1271 {
1272 paper_height = 0;
1273 as_warn (_("strange paper height, set to no form"));
1274 }
1275
1276 if (*input_line_pointer != ',')
1277 {
1278 demand_empty_rest_of_line ();
1279 return;
1280 }
1281
1282 ++input_line_pointer;
1283 }
1284
1285 paper_width = get_absolute_expression ();
1286
1287 demand_empty_rest_of_line ();
1288}
1289
1290void
254d758c 1291listing_nopage (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
1292{
1293 paper_height = 0;
1294}
1295
1296void
254d758c 1297listing_title (int depth)
252b5132
RH
1298{
1299 int quoted;
1300 char *start;
1301 char *ttl;
1302 unsigned int length;
1303
1304 SKIP_WHITESPACE ();
1305 if (*input_line_pointer != '\"')
1306 quoted = 0;
1307 else
1308 {
1309 quoted = 1;
1310 ++input_line_pointer;
1311 }
1312
1313 start = input_line_pointer;
1314
1315 while (*input_line_pointer)
1316 {
1317 if (quoted
1318 ? *input_line_pointer == '\"'
1319 : is_end_of_line[(unsigned char) *input_line_pointer])
1320 {
1321 if (listing)
1322 {
1323 length = input_line_pointer - start;
1324 ttl = xmalloc (length + 1);
1325 memcpy (ttl, start, length);
1326 ttl[length] = 0;
1327 listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
1328 listing_tail->edict_arg = ttl;
1329 }
1330 if (quoted)
1331 input_line_pointer++;
1332 demand_empty_rest_of_line ();
1333 return;
1334 }
1335 else if (*input_line_pointer == '\n')
1336 {
0e389e77 1337 as_bad (_("new line in title"));
252b5132
RH
1338 demand_empty_rest_of_line ();
1339 return;
1340 }
1341 else
1342 {
1343 input_line_pointer++;
1344 }
1345 }
1346}
1347
252b5132 1348void
254d758c 1349listing_source_line (unsigned int line)
252b5132
RH
1350{
1351 if (listing)
1352 {
1353 new_frag ();
1354 listing_tail->hll_line = line;
1355 new_frag ();
1356 }
1357}
1358
1359void
254d758c 1360listing_source_file (const char *file)
252b5132
RH
1361{
1362 if (listing)
1363 listing_tail->hll_file = file_info (file);
1364}
1365
252b5132
RH
1366#else
1367
cf39a089 1368/* Dummy functions for when compiled without listing enabled. */
252b5132
RH
1369
1370void
254d758c 1371listing_flags (int ignore)
252b5132
RH
1372{
1373 s_ignore (0);
1374}
1375
cf39a089 1376void
254d758c 1377listing_list (int on)
252b5132
RH
1378{
1379 s_ignore (0);
1380}
1381
cf39a089 1382void
254d758c 1383listing_eject (int ignore)
252b5132
RH
1384{
1385 s_ignore (0);
1386}
1387
cf39a089 1388void
254d758c 1389listing_psize (int ignore)
252b5132
RH
1390{
1391 s_ignore (0);
1392}
1393
1394void
254d758c 1395listing_nopage (int ignore)
252b5132
RH
1396{
1397 s_ignore (0);
1398}
1399
cf39a089 1400void
254d758c 1401listing_title (int depth)
252b5132
RH
1402{
1403 s_ignore (0);
1404}
1405
1406void
254d758c 1407listing_file (const char *name)
252b5132 1408{
252b5132
RH
1409}
1410
cf39a089 1411void
254d758c 1412listing_newline (char *name)
252b5132 1413{
252b5132
RH
1414}
1415
cf39a089 1416void
254d758c 1417listing_source_line (unsigned int n)
252b5132 1418{
252b5132 1419}
cf39a089
KH
1420
1421void
254d758c 1422listing_source_file (const char *n)
252b5132 1423{
252b5132
RH
1424}
1425
1426#endif
This page took 0.444456 seconds and 4 git commands to generate.