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