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