Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of GAS, the GNU Assembler.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of GAS, the GNU Assembler.
DWARF2_LINE_MIN_INSN_LENGTH. */
#define SPECIAL_ADDR(op) (((op) - DWARF2_LINE_OPCODE_BASE)/DWARF2_LINE_RANGE)
DWARF2_LINE_MIN_INSN_LENGTH. */
#define SPECIAL_ADDR(op) (((op) - DWARF2_LINE_OPCODE_BASE)/DWARF2_LINE_RANGE)
segT text_seg; /* text segment "addr" is relative to */
subsegT text_subseg;
segT line_seg; /* ".debug_line" segment */
int last_filename; /* index of last filename that was used */
int num_filenames; /* index of last filename in use */
int filename_len; /* length of the filename array */
segT text_seg; /* text segment "addr" is relative to */
subsegT text_subseg;
segT line_seg; /* ".debug_line" segment */
int last_filename; /* index of last filename that was used */
int num_filenames; /* index of last filename in use */
int filename_len; /* length of the filename array */
int dir; /* valid after gen_dir_list() only */
char *name; /* full path before gen_dir_list(), filename afterwards */
int dir; /* valid after gen_dir_list() only */
char *name; /* full path before gen_dir_list(), filename afterwards */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}
static void out_uleb128 PARAMS ((addressT));
static void out_sleb128 PARAMS ((offsetT));
static void gen_addr_line PARAMS ((int, addressT));
static void out_uleb128 PARAMS ((addressT));
static void out_sleb128 PARAMS ((offsetT));
static void gen_addr_line PARAMS ((int, addressT));
#define out_byte(byte) FRAG_APPEND_1_CHAR(byte)
#define out_opcode(opc) (out_byte ((opc)), ++ls.opcode_hist[(opc) & 0xff])
/* Output an unsigned "little-endian base 128" number. */
#define out_byte(byte) FRAG_APPEND_1_CHAR(byte)
#define out_opcode(opc) (out_byte ((opc)), ++ls.opcode_hist[(opc) & 0xff])
/* Output an unsigned "little-endian base 128" number. */
/* Encode a pair of line and address skips as efficiently as possible.
Note that the line skip is signed, whereas the address skip is
unsigned. */
/* Encode a pair of line and address skips as efficiently as possible.
Note that the line skip is signed, whereas the address skip is
unsigned. */
- /* try using DW_LNS_const_add_pc followed by special op: */
- opcode = tmp + (addr_delta - MAX_SPECIAL_ADDR_DELTA)*DWARF2_LINE_RANGE;
+ /* Try using DW_LNS_const_add_pc followed by special op. */
+ opcode = tmp + (addr_delta - MAX_SPECIAL_ADDR_DELTA) * DWARF2_LINE_RANGE;
/* Emit DW_LNS_end_sequence and reset state machine. Does not
preserve the current segment/sub-segment! */
/* Emit DW_LNS_end_sequence and reset state machine. Does not
preserve the current segment/sub-segment! */
- gen_addr_line (0, delta / DWARF2_LINE_MIN_INSN_LENGTH);
+ {
+ /* Advance address without updating the line-debug
+ matrix---the end_sequence entry is used only to tell
+ the debugger the end of the sequence. */
+ out_opcode (DW_LNS_advance_pc);
+ out_uleb128 (delta);
+ }
/* Look up a filenumber either by filename or by filenumber. If both
a filenumber and a filename are specified, lookup by filename takes
precedence. If the filename cannot be found, it is added to the
/* Look up a filenumber either by filename or by filenumber. If both
a filenumber and a filename are specified, lookup by filename takes
precedence. If the filename cannot be found, it is added to the
- if (last >= ls.num_filenames)
+ /* If filenum is out of range of the filename table, then try using the
+ table entry returned from the previous call. */
+ if (last >= ls.num_filenames || last < 0)
if (ls.num_filenames > 0 && ls.file[last].name[0] == char0
&& strcmp (ls.file[last].name + 1, file + 1) == 0)
return last + 1;
if (ls.num_filenames > 0 && ls.file[last].name[0] == char0
&& strcmp (ls.file[last].name + 1, file + 1) == 0)
return last + 1;
- return; /* no filename, no filnum => no play */
+ /* No filename, no filnum => no play. */
+ return;
+
+ /* Must save these before the subseg_new call, as that call will change
+ them. */
+ saved_seg = now_seg;
+ saved_subseg = now_subseg;
+ saved_frag = frag_now;
subseg_set (ls.line_seg, DL_BODY);
if (ls.text_seg != saved_seg || ls.text_subseg != saved_subseg)
{
if (!ls.sm.empty_sequence)
{
subseg_set (ls.line_seg, DL_BODY);
if (ls.text_seg != saved_seg || ls.text_subseg != saved_subseg)
{
if (!ls.sm.empty_sequence)
{
- /* This happens when a new frag got allocated (for whatever
- reason). Deal with it by generating a reference symbol.
- Note: no end_sequence needs to be generated because the
- address did not really decrease (only the reference point
- changed).
-
- ??? Perhaps we should directly check for a change of
- frag_now instead? */
+ /* If a new frag got allocated (for whatever reason), then
+ deal with it by generating a reference symbol. Note: no
+ end_sequence needs to be generated because the address did
+ not really decrease (only the reference point changed). */
}
gen_addr_line (l->line - ls.sm.line,
(addr - ls.sm.addr) / DWARF2_LINE_MIN_INSN_LENGTH);
}
gen_addr_line (l->line - ls.sm.line,
(addr - ls.sm.addr) / DWARF2_LINE_MIN_INSN_LENGTH);
- static const char *opc_name[] =
- {
- "extended", "copy", "advance_pc", "advance_line", "set_file",
- "set_column", "negate_stmt", "set_basic_block", "const_add_pc",
- "fixed_advance_pc"
- };
+ static const char *opc_name[] = {
+ "extended", "copy", "advance_pc", "advance_line", "set_file",
+ "set_column", "negate_stmt", "set_basic_block", "const_add_pc",
+ "fixed_advance_pc"
+ };
{
fprintf (stderr, "%s", opc_name[i]);
for (j = strlen (opc_name[i]); j < 16; ++j)
{
fprintf (stderr, "%s", opc_name[i]);
for (j = strlen (opc_name[i]); j < 16; ++j)
j = SPECIAL_LINE (i);
if (j == DWARF2_LINE_BASE)
fprintf (stderr, "\n%4u: ",
j = SPECIAL_LINE (i);
if (j == DWARF2_LINE_BASE)
fprintf (stderr, "\n%4u: ",
subseg_set (ls.line_seg, DL_FILES);
gen_dir_list ();
gen_file_list ();
total_size += frag_now_fix ();
subseg_set (ls.line_seg, DL_FILES);
gen_dir_list ();
gen_file_list ();
total_size += frag_now_fix ();
subseg_set (ls.line_seg, DL_PROLOG);
cp = frag_more (15 + DWARF2_LINE_OPCODE_BASE - 1);
subseg_set (ls.line_seg, DL_PROLOG);
cp = frag_more (15 + DWARF2_LINE_OPCODE_BASE - 1);