sh-dsp REPEAT support:
[deliverable/binutils-gdb.git] / gas / dwarf2dbg.c
CommitLineData
fac0d250 1/* dwarf2dbg.c - DWARF2 debug support
52454417 2 Copyright (C) 1999, 2000 Free Software Foundation, Inc.
fac0d250
RH
3 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
89b66cde 20 02111-1307, USA. */
fac0d250 21
89b66cde 22/* Logical line numbers can be controlled by the compiler via the
fac0d250
RH
23 following two directives:
24
25 .file FILENO "file.c"
26 .loc FILENO LINENO [COLUMN]
27
28 FILENO is the filenumber. */
29
30#include "ansidecl.h"
31
32#include "as.h"
33#include "dwarf2dbg.h"
34#include "subsegs.h"
35
d9ac5a3b 36#include "elf/dwarf2.h"
fac0d250 37
fac0d250
RH
38/* Since we can't generate the prolog until the body is complete, we
39 use three different subsegments for .debug_line: one holding the
40 prolog, one for the directory and filename info, and one for the
41 body ("statement program"). */
42#define DL_PROLOG 0
43#define DL_FILES 1
44#define DL_BODY 2
45
46/* First special line opcde - leave room for the standard opcodes.
47 Note: If you want to change this, you'll have to update the
48 "standard_opcode_lengths" table that is emitted below in
49 dwarf2_finish(). */
50#define DWARF2_LINE_OPCODE_BASE 10
51
52#ifndef DWARF2_LINE_BASE
53 /* Minimum line offset in a special line info. opcode. This value
54 was chosen to give a reasonable range of values. */
55# define DWARF2_LINE_BASE -5
56#endif
57
58/* Range of line offsets in a special line info. opcode. */
59#ifndef DWARF2_LINE_RANGE
60# define DWARF2_LINE_RANGE 14
61#endif
62
63#ifndef DWARF2_LINE_MIN_INSN_LENGTH
64 /* Define the architecture-dependent minimum instruction length (in
65 bytes). This value should be rather too small than too big. */
66# define DWARF2_LINE_MIN_INSN_LENGTH 4
67#endif
68
69/* Flag that indicates the initial value of the is_stmt_start flag.
70 In the present implementation, we do not mark any lines as
71 the beginning of a source statement, because that information
72 is not made available by the GCC front-end. */
73#define DWARF2_LINE_DEFAULT_IS_STMT 1
74
75/* Flag that indicates the initial value of the is_stmt_start flag.
76 In the present implementation, we do not mark any lines as
77 the beginning of a source statement, because that information
78 is not made available by the GCC front-end. */
79#define DWARF2_LINE_DEFAULT_IS_STMT 1
80
cb30237e 81/* Given a special op, return the line skip amount. */
fac0d250
RH
82#define SPECIAL_LINE(op) \
83 (((op) - DWARF2_LINE_OPCODE_BASE)%DWARF2_LINE_RANGE + DWARF2_LINE_BASE)
84
85/* Given a special op, return the address skip amount (in units of
86 DWARF2_LINE_MIN_INSN_LENGTH. */
87#define SPECIAL_ADDR(op) (((op) - DWARF2_LINE_OPCODE_BASE)/DWARF2_LINE_RANGE)
88
cb30237e 89/* The maximum address skip amount that can be encoded with a special op. */
fac0d250
RH
90#define MAX_SPECIAL_ADDR_DELTA SPECIAL_ADDR(255)
91
92#define INITIAL_STATE \
cb30237e 93 /* Initialize as per DWARF2.0 standard. */ \
fac0d250
RH
94 0, /* address */ \
95 1, /* file */ \
96 1, /* line */ \
97 0, /* column */ \
98 DWARF2_LINE_DEFAULT_IS_STMT, /* is_stmt */ \
99 0, /* basic_block */ \
100 1 /* empty_sequence */
101
102static struct
103 {
104 /* state machine state as per DWARF2 manual: */
105 struct dwarf2_sm
106 {
9e3af0e7 107 addressT addr;
fac0d250
RH
108 unsigned int filenum;
109 unsigned int line;
110 unsigned int column;
111 unsigned int
112 is_stmt : 1,
113 basic_block : 1,
114 empty_sequence : 1; /* current code sequence has no DWARF2 directives? */
115 }
116 sm;
117
118 unsigned int
119 any_dwarf2_directives : 1; /* did we emit any DWARF2 line debug directives? */
120
cb30237e 121 fragS * frag; /* frag that "addr" is relative to */
fac0d250
RH
122 segT text_seg; /* text segment "addr" is relative to */
123 subsegT text_subseg;
124 segT line_seg; /* ".debug_line" segment */
125 int last_filename; /* index of last filename that was used */
126 int num_filenames; /* index of last filename in use */
127 int filename_len; /* length of the filename array */
128 struct
129 {
130 int dir; /* valid after gen_dir_list() only */
131 char *name; /* full path before gen_dir_list(), filename afterwards */
132 }
133 *file;
134
135 struct dwarf2_line_info current; /* current source info: */
136
137 /* counters for statistical purposes: */
138 unsigned int num_line_entries;
139 unsigned int opcode_hist[256]; /* histogram of opcode frequencies */
140 }
141ls =
142 {
143 {
144 INITIAL_STATE
145 },
ab9da554
ILT
146 0,
147 0,
148 0,
149 0,
150 0,
151 0,
152 0,
cb30237e 153 0,
ab9da554
ILT
154 NULL,
155 { NULL, 0, 0, 0, 0 },
156 0,
157 {
158 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
159 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
160 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
161 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
162 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
163 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
164 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
165 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
166 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
167 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
168 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
169 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
170 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
171 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
172 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
173 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
174 }
fac0d250
RH
175 };
176
58b5739a
RH
177
178/* Function prototypes: */
9e3af0e7
ILT
179static void out_uleb128 PARAMS ((addressT));
180static void out_sleb128 PARAMS ((offsetT));
181static void gen_addr_line PARAMS ((int, addressT));
58b5739a 182static void reset_state_machine PARAMS ((void));
9e3af0e7 183static void out_set_addr PARAMS ((addressT));
58b5739a
RH
184static void out_end_sequence PARAMS ((void));
185static int get_filenum PARAMS ((int, char *));
186static void gen_dir_list PARAMS ((void));
187static void gen_file_list PARAMS ((void));
188static void print_stats PARAMS ((unsigned long));
189
190
fac0d250
RH
191#define out_byte(byte) FRAG_APPEND_1_CHAR(byte)
192#define out_opcode(opc) (out_byte ((opc)), ++ls.opcode_hist[(opc) & 0xff])
193
194/* Output an unsigned "little-endian base 128" number. */
195static void
58b5739a 196out_uleb128 (value)
9e3af0e7 197 addressT value;
fac0d250
RH
198{
199 unsigned char byte, more = 0x80;
200
201 do
202 {
203 byte = value & 0x7f;
204 value >>= 7;
205 if (value == 0)
206 more = 0;
207 out_byte (more | byte);
208 }
209 while (more);
210}
211
212/* Output a signed "little-endian base 128" number. */
213static void
58b5739a 214out_sleb128 (value)
9e3af0e7 215 offsetT value;
fac0d250
RH
216{
217 unsigned char byte, more = 0x80;
218
219 do
220 {
221 byte = value & 0x7f;
222 value >>= 7;
223 if (((value == 0) && ((byte & 0x40) == 0))
224 || ((value == -1) && ((byte & 0x40) != 0)))
225 more = 0;
226 out_byte (more | byte);
227 }
228 while (more);
229}
230
231/* Encode a pair of line and address skips as efficiently as possible.
232 Note that the line skip is signed, whereas the address skip is
233 unsigned. */
234static void
58b5739a
RH
235gen_addr_line (line_delta, addr_delta)
236 int line_delta;
9e3af0e7 237 addressT addr_delta;
fac0d250
RH
238{
239 unsigned int tmp, opcode;
240
241 tmp = line_delta - DWARF2_LINE_BASE;
242
243 if (tmp >= DWARF2_LINE_RANGE)
244 {
245 out_opcode (DW_LNS_advance_line);
246 out_sleb128 (line_delta);
247 tmp = 0 - DWARF2_LINE_BASE;
248 line_delta = 0;
249 }
250
251 tmp += DWARF2_LINE_OPCODE_BASE;
252
253 /* try using a special opcode: */
254 opcode = tmp + addr_delta*DWARF2_LINE_RANGE;
255 if (opcode <= 255)
256 {
257 out_opcode (opcode);
258 return;
259 }
260
261 /* try using DW_LNS_const_add_pc followed by special op: */
262 opcode = tmp + (addr_delta - MAX_SPECIAL_ADDR_DELTA)*DWARF2_LINE_RANGE;
263 if (opcode <= 255)
264 {
265 out_opcode (DW_LNS_const_add_pc);
266 out_opcode (opcode);
267 return;
268 }
269
270 out_opcode (DW_LNS_advance_pc);
271 out_uleb128 (addr_delta);
272
273 if (line_delta)
274 out_opcode (tmp); /* output line-delta */
275 else
276 out_opcode (DW_LNS_copy); /* append new row with current info */
277}
278
279static void
58b5739a 280reset_state_machine ()
fac0d250
RH
281{
282 static const struct dwarf2_sm initial_state = { INITIAL_STATE };
283
284 ls.sm = initial_state;
285}
286
287/* Set an absolute address (may results in a relocation entry): */
288static void
58b5739a 289out_set_addr (addr)
9e3af0e7 290 addressT addr;
fac0d250
RH
291{
292 subsegT saved_subseg;
293 segT saved_seg;
294 expressionS expr;
295 symbolS *sym;
9e3af0e7 296 int bytes_per_address;
fac0d250
RH
297
298 saved_seg = now_seg;
299 saved_subseg = now_subseg;
300
301 subseg_set (ls.text_seg, ls.text_subseg);
302 sym = symbol_new (".L0\001", now_seg, addr, frag_now);
303
304 subseg_set (saved_seg, saved_subseg);
305
9e3af0e7
ILT
306#ifdef BFD_ASSEMBLER
307 bytes_per_address = bfd_arch_bits_per_address (stdoutput) / 8;
308#else
309 /* FIXME. */
310 bytes_per_address = 4;
311#endif
312
fac0d250 313 out_opcode (DW_LNS_extended_op);
9e3af0e7 314 out_uleb128 (bytes_per_address + 1);
fac0d250
RH
315
316 out_opcode (DW_LNE_set_address);
317 expr.X_op = O_symbol;
318 expr.X_add_symbol = sym;
319 expr.X_add_number = 0;
9e3af0e7 320 emit_expr (&expr, bytes_per_address);
fac0d250
RH
321}
322
323/* Emit DW_LNS_end_sequence and reset state machine. Does not
324 preserve the current segment/sub-segment! */
325static void
58b5739a 326out_end_sequence ()
fac0d250 327{
9e3af0e7 328 addressT addr, delta;
cb30237e 329 fragS *text_frag;
fac0d250
RH
330
331 if (ls.text_seg)
332 {
333 subseg_set (ls.text_seg, ls.text_subseg);
334#ifdef md_current_text_addr
335 addr = md_current_text_addr ();
336#else
337 addr = frag_now_fix ();
338#endif
cb30237e 339 text_frag = frag_now;
fac0d250 340 subseg_set (ls.line_seg, DL_BODY);
cb30237e 341 if (text_frag != ls.frag)
fac0d250
RH
342 {
343 out_set_addr (addr);
344 ls.sm.addr = addr;
cb30237e 345 ls.frag = text_frag;
fac0d250
RH
346 }
347 else
348 {
09a798ea 349 delta = (addr - ls.sm.addr) / DWARF2_LINE_MIN_INSN_LENGTH;
fac0d250 350 if (delta > 0)
09a798ea
NC
351 {
352 /* Advance address without updating the line-debug
353 matrix---the end_sequence entry is used only to tell
354 the debugger the end of the sequence.*/
355 out_opcode (DW_LNS_advance_pc);
356 out_uleb128 (delta);
357 }
fac0d250
RH
358 }
359 }
360 else
361 subseg_set (ls.line_seg, DL_BODY);
362
363 out_opcode (DW_LNS_extended_op);
364 out_uleb128 (1);
365 out_byte (DW_LNE_end_sequence);
366
367 reset_state_machine ();
368}
369
370/* Look up a filenumber either by filename or by filenumber. If both
371 a filenumber and a filename are specified, lookup by filename takes
372 precedence. If the filename cannot be found, it is added to the
e1c05f12 373 filetable and the filenumber for the new entry is returned. */
fac0d250 374static int
58b5739a
RH
375get_filenum (filenum, file)
376 int filenum;
377 char *file;
fac0d250
RH
378{
379 int i, last = filenum - 1;
380 char char0 = file[0];
381
e1c05f12
NC
382 /* If filenum is out of range of the filename table, then try using the
383 table entry returned from the previous call. */
384 if (last >= ls.num_filenames || last < 0)
fac0d250
RH
385 last = ls.last_filename;
386
e1c05f12 387 /* Do a quick check against the specified or previously used filenum. */
fac0d250
RH
388 if (ls.num_filenames > 0 && ls.file[last].name[0] == char0
389 && strcmp (ls.file[last].name + 1, file + 1) == 0)
390 return last + 1;
391
392 /* no match, fall back to simple linear scan: */
393 for (i = 0; i < ls.num_filenames; ++i)
394 {
395 if (ls.file[i].name[0] == char0
396 && strcmp (ls.file[i].name + 1, file + 1) == 0)
397 {
398 ls.last_filename = i;
399 return i + 1;
400 }
401 }
402
403 /* no match: enter new filename */
404 if (ls.num_filenames >= ls.filename_len)
405 {
406 ls.filename_len += 13;
407 ls.file = xrealloc (ls.file, ls.filename_len * sizeof (ls.file[0]));
408 }
409 ls.file[ls.num_filenames].dir = 0;
410 ls.file[ls.num_filenames].name = file;
e1c05f12 411 ls.last_filename = ls.num_filenames;
fac0d250
RH
412 return ++ls.num_filenames;
413}
414
cb30237e
NC
415/* Emit an entry in the line number table if the address or line has changed.
416 ADDR is relative to the current frag in the text section. */
417
fac0d250 418void
58b5739a 419dwarf2_gen_line_info (addr, l)
9e3af0e7 420 addressT addr;
58b5739a 421 struct dwarf2_line_info *l;
fac0d250
RH
422{
423 unsigned int filenum = l->filenum;
424 unsigned int any_output = 0;
425 subsegT saved_subseg;
426 segT saved_seg;
cb30237e 427 fragS *saved_frag;
fac0d250
RH
428
429 if (flag_debug)
966ed0b4
ILT
430 fprintf (stderr, "line: addr %lx file `%s' line %u col %u flags %x\n",
431 (unsigned long) addr, l->filename, l->line, l->column, l->flags);
fac0d250
RH
432
433 if (filenum > 0 && !l->filename)
434 {
ab9da554 435 if (filenum >= (unsigned int) ls.num_filenames)
fac0d250
RH
436 {
437 as_warn ("Encountered bad file number in line number debug info!");
438 return;
439 }
440 }
441 else if (l->filename)
442 filenum = get_filenum (filenum, l->filename);
443 else
444 return; /* no filename, no filnum => no play */
445
e1c05f12
NC
446 /* Must save these before the subseg_new call, as that call will change
447 them. */
448 saved_seg = now_seg;
449 saved_subseg = now_subseg;
cb30237e 450 saved_frag = frag_now;
e1c05f12 451
fac0d250
RH
452 if (!ls.line_seg)
453 {
9e3af0e7 454#ifdef BFD_ASSEMBLER
9de8d8f1 455 symbolS *secsym;
9e3af0e7 456#endif
9de8d8f1 457
6576f0b5 458 ls.line_seg = subseg_new (".debug_line", 0);
9e3af0e7
ILT
459
460#ifdef BFD_ASSEMBLER
fac0d250 461 bfd_set_section_flags (stdoutput, ls.line_seg, SEC_READONLY);
6576f0b5
RH
462
463 /* We're going to need this symbol. */
9de8d8f1
RH
464 secsym = symbol_find (".debug_line");
465 if (secsym != NULL)
466 symbol_set_bfdsym (secsym, ls.line_seg->symbol);
467 else
468 symbol_table_insert (section_symbol (ls.line_seg));
9e3af0e7 469#endif
fac0d250
RH
470 }
471
fac0d250
RH
472 subseg_set (ls.line_seg, DL_BODY);
473
474 if (ls.text_seg != saved_seg || ls.text_subseg != saved_subseg)
475 {
476 if (!ls.sm.empty_sequence)
477 {
478 out_end_sequence (); /* terminate previous sequence */
479 ls.sm.empty_sequence = 1;
480 }
481 any_output = 1;
482 ls.text_seg = saved_seg;
483 ls.text_subseg = saved_subseg;
484 out_set_addr (addr);
485 ls.sm.addr = addr;
cb30237e 486 ls.frag = saved_frag;
fac0d250
RH
487 }
488
489 if (ls.sm.filenum != filenum)
490 {
491 any_output = 1;
492 out_opcode (DW_LNS_set_file);
493 out_uleb128 (filenum);
494 ls.sm.filenum = filenum;
495 }
496
497 if (ls.sm.column != l->column)
498 {
499 any_output = 1;
500 out_opcode (DW_LNS_set_column);
501 out_uleb128 (l->column);
502 ls.sm.column = l->column;
503 }
504
505 if (((l->flags & DWARF2_FLAG_BEGIN_STMT) != 0) != ls.sm.is_stmt)
506 {
507 any_output = 1;
508 out_opcode (DW_LNS_negate_stmt);
509 }
510
511 if (l->flags & DWARF2_FLAG_BEGIN_BLOCK)
512 {
513 any_output = 1;
514 out_opcode (DW_LNS_set_basic_block);
515 }
516
517 if (ls.sm.line != l->line)
518 {
519 any_output = 1;
cb30237e 520 if (saved_frag != ls.frag)
fac0d250 521 {
cb30237e
NC
522 /* If a new frag got allocated (for whatever reason), then
523 deal with it by generating a reference symbol. Note: no
524 end_sequence needs to be generated because the address did
525 not really decrease (only the reference point changed). */
fac0d250
RH
526 out_set_addr (addr);
527 ls.sm.addr = addr;
cb30237e 528 ls.frag = saved_frag;
fac0d250
RH
529 }
530 gen_addr_line (l->line - ls.sm.line,
531 (addr - ls.sm.addr) / DWARF2_LINE_MIN_INSN_LENGTH);
532 ls.sm.basic_block = 0;
533 ls.sm.line = l->line;
534 ls.sm.addr = addr;
535 }
536
537 subseg_set (saved_seg, saved_subseg);
538
539 ls.num_line_entries += any_output;
540 if (any_output)
541 ls.sm.empty_sequence = 0;
542}
543
544static void
58b5739a 545gen_dir_list ()
fac0d250
RH
546{
547 char *str, *slash, *dir_list, *dp, *cp;
548 int i, j, num_dirs;
549
550 dir_list = frag_more (0);
551 num_dirs = 0;
552
553 for (i = 0; i < ls.num_filenames; ++i)
554 {
555 str = ls.file[i].name;
556 slash = strrchr (str, '/');
557 if (slash)
558 {
559 *slash = '\0';
560 for (j = 0, dp = dir_list; j < num_dirs; ++j)
561 {
562 if (strcmp (str, dp) == 0)
563 {
a340d270 564 ls.file[i].dir = j + 1;
fac0d250
RH
565 break;
566 }
567 dp += strlen (dp);
568 }
569 if (j >= num_dirs)
570 {
571 /* didn't find this directory: append it to the list */
572 size_t size = strlen (str) + 1;
573 cp = frag_more (size);
574 memcpy (cp, str, size);
575 ls.file[i].dir = ++num_dirs;
576 }
577 *slash = '/';
578 ls.file[i].name = slash + 1;
579 }
580 }
581 out_byte ('\0'); /* terminate directory list */
582}
583
584static void
58b5739a 585gen_file_list ()
fac0d250
RH
586{
587 size_t size;
588 char *cp;
589 int i;
590
591 for (i = 0; i < ls.num_filenames; ++i)
592 {
593 size = strlen (ls.file[i].name) + 1;
594 cp = frag_more (size);
595 memcpy (cp, ls.file[i].name, size);
596
597 out_uleb128 (ls.file[i].dir); /* directory number */
598 out_uleb128 (0); /* last modification timestamp */
599 out_uleb128 (0); /* filesize */
600 }
601 out_byte (0); /* terminate filename list */
602}
603
58b5739a
RH
604static void
605print_stats (total_size)
606 unsigned long total_size;
fac0d250
RH
607{
608 static const char *opc_name[] =
609 {
610 "extended", "copy", "advance_pc", "advance_line", "set_file",
611 "set_column", "negate_stmt", "set_basic_block", "const_add_pc",
612 "fixed_advance_pc"
613 };
ab9da554
ILT
614 size_t i;
615 int j;
fac0d250
RH
616
617 fprintf (stderr, "Average size: %g bytes/line\n",
618 total_size / (double) ls.num_line_entries);
619
620 fprintf (stderr, "\nStandard opcode histogram:\n");
621
622 for (i = 0; i < sizeof (opc_name)/sizeof (opc_name[0]); ++i)
623 {
624 fprintf (stderr, "%s", opc_name[i]);
625 for (j = strlen (opc_name[i]); j < 16; ++j)
626 fprintf (stderr, " ");
627 fprintf (stderr, ": %u\n", ls.opcode_hist[i]);
628 }
629
630 fprintf (stderr, "\nSpecial opcodes:\naddr\t\t\t\tline skip\n");
631
632 fprintf (stderr, "skip: ");
633 for (j = DWARF2_LINE_BASE; j < DWARF2_LINE_BASE + DWARF2_LINE_RANGE; ++j)
634 fprintf (stderr, "%3d", j);
635 fprintf (stderr, "\n-----");
636
637 for (; i < 256; ++i)
638 {
639 j = SPECIAL_LINE (i);
640 if (j == DWARF2_LINE_BASE)
641 fprintf (stderr, "\n%4u: ",
52454417
ILT
642 ((unsigned int)
643 DWARF2_LINE_MIN_INSN_LENGTH * SPECIAL_ADDR (i)));
fac0d250
RH
644 fprintf (stderr, " %2u", ls.opcode_hist[i]);
645 }
646 fprintf (stderr, "\n");
647}
648
649void
58b5739a 650dwarf2_finish ()
fac0d250 651{
9e3af0e7 652 addressT body_size, total_size, prolog_size;
58b5739a 653 subsegT saved_subseg;
fac0d250
RH
654 segT saved_seg;
655 char *cp;
656
657 if (!ls.line_seg)
658 /* no .debug_line segment, no work to do... */
659 return;
660
661 saved_seg = now_seg;
662 saved_subseg = now_subseg;
663
664 if (!ls.sm.empty_sequence)
665 out_end_sequence ();
666 total_size = body_size = frag_now_fix ();
667
668 /* now generate the directory and file lists: */
669 subseg_set (ls.line_seg, DL_FILES);
670 gen_dir_list ();
671 gen_file_list ();
672 total_size += frag_now_fix ();
673
674 /* and now the header ("statement program prolog", in DWARF2 lingo...) */
675 subseg_set (ls.line_seg, DL_PROLOG);
676
677 cp = frag_more (15 + DWARF2_LINE_OPCODE_BASE - 1);
678
679 total_size += frag_now_fix ();
680 prolog_size = total_size - body_size - 10;
681
682# define STUFF(val,size) md_number_to_chars (cp, val, size); cp += size;
683 STUFF (total_size - 4, 4); /* length */
684 STUFF (2, 2); /* version */
685 STUFF (prolog_size, 4); /* prologue_length */
686 STUFF (DWARF2_LINE_MIN_INSN_LENGTH, 1);
687 STUFF (DWARF2_LINE_DEFAULT_IS_STMT, 1);
688 STUFF (DWARF2_LINE_BASE, 1);
689 STUFF (DWARF2_LINE_RANGE, 1);
690 STUFF (DWARF2_LINE_OPCODE_BASE, 1);
691
692 /* standard_opcode_lengths: */
693 STUFF (0, 1); /* DW_LNS_copy */
694 STUFF (1, 1); /* DW_LNS_advance_pc */
695 STUFF (1, 1); /* DW_LNS_advance_line */
696 STUFF (1, 1); /* DW_LNS_set_file */
697 STUFF (1, 1); /* DW_LNS_set_column */
698 STUFF (0, 1); /* DW_LNS_negate_stmt */
699 STUFF (0, 1); /* DW_LNS_set_basic_block */
700 STUFF (0, 1); /* DW_LNS_const_add_pc */
701 STUFF (1, 1); /* DW_LNS_fixed_advance_pc */
702
703 subseg_set (saved_seg, saved_subseg);
704
705 if (flag_debug)
706 print_stats (total_size);
707}
708
709void
58b5739a 710dwarf2_directive_file (dummy)
ab9da554 711 int dummy ATTRIBUTE_UNUSED;
fac0d250
RH
712{
713 int len;
714
58b5739a
RH
715 /* Continue to accept a bare string and pass it off. */
716 SKIP_WHITESPACE ();
717 if (*input_line_pointer == '"')
718 {
719 s_app_file (0);
720 return;
721 }
722
fac0d250
RH
723 ls.any_dwarf2_directives = 1;
724
725 if (debug_type == DEBUG_NONE)
726 /* Automatically turn on DWARF2 debug info unless something else
727 has been selected. */
728 debug_type = DEBUG_DWARF2;
729
730 ls.current.filenum = get_absolute_expression ();
731 ls.current.filename = demand_copy_C_string (&len);
732
733 demand_empty_rest_of_line ();
734}
735
736void
58b5739a 737dwarf2_directive_loc (dummy)
ab9da554 738 int dummy ATTRIBUTE_UNUSED;
fac0d250
RH
739{
740 ls.any_dwarf2_directives = 1;
741
742 ls.current.filenum = get_absolute_expression ();
743 SKIP_WHITESPACE ();
744 ls.current.line = get_absolute_expression ();
745 SKIP_WHITESPACE ();
746 ls.current.column = get_absolute_expression ();
747 demand_empty_rest_of_line ();
748
749 ls.current.flags = DWARF2_FLAG_BEGIN_STMT;
750
751#ifndef NO_LISTING
752 if (listing)
753 listing_source_line (ls.current.line);
754#endif
755}
756
757void
58b5739a
RH
758dwarf2_where (line)
759 struct dwarf2_line_info *line;
fac0d250
RH
760{
761 if (ls.any_dwarf2_directives)
762 *line = ls.current;
763 else
764 {
fac0d250
RH
765 as_where (&line->filename, &line->line);
766 line->filenum = 0;
767 line->column = 0;
768 line->flags = DWARF2_FLAG_BEGIN_STMT;
769 }
770}
This page took 0.072903 seconds and 4 git commands to generate.