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