* dwarf2dbg.c (struct line_entry): Replace frag and frag_ofs

with label.
        (dwarf2_loc_mark_labels): New.
        (dwarf2_gen_line_info_1): Split out of ...
        (dwarf2_gen_line_info): ... here.  Create the temp symbol here.
        (dwarf2_emit_label): New.
        (dwarf2_directive_loc_mark_labels): New.
        (out_set_addr): Take a symbol instead of frag+ofs.
        (relax_inc_line_addr): Likewise.
        (emit_inc_line_addr): Assert delta non-negative.
        (process_entries): Remove dead code.  Update to work with temp
        symbols instead of frag+ofs.
        * dwarf2dbg.h (dwarf2_directive_loc_mark_labels): Declare.
        (dwarf2_emit_label, dwarf2_loc_mark_labels): Declare.
        * config/obj-elf.c (elf_pseudo_tab): Add loc_mark_labels.
        * config/obj-elf.h (obj_frob_label): New.
        * config/tc-alpha.c (alpha_define_label): Call dwarf2_emit_label.
        * config/tc-arm.c, config/tc-hppa.c, config/tc-m68k.c,
        config/tc-mips.c, config/tc-ppc.c, config/tc-sh.c, config/tc-xtensa.c:
        Similarly in the respective tc_frob_label implementation functions.
        * config/tc-i386.c (md_pseudo_table): Move file and loc to
        non-elf section; add loc_mark_labels.
        * config/tc-ia64.c (struct label_fix): Add dw2_mark_labels.
        (ia64_flush_insns): Check for marked labels; emit line entry if so.
        (emit_one_bundle): Similarly.
        (ia64_frob_label): Record marked labels.
        * config/tc-m68hc11.h (tc_frob_label): Remove.
        * config/tc-ms1.c (md_pseudo_table): Remove file and loc.
        * config/tc-sh.h (tc_frob_label): Pass sym to sh_frob_label.
        * config/tc-sh64.h (tc_frob_label): Likewise.
        * doc/as.texinfo (LNS directives): Docuement .loc_mark_blocks.
This commit is contained in:
Richard Henderson 2005-09-20 18:24:48 +00:00
parent d5cbaa1554
commit 07a53e5cdb
20 changed files with 249 additions and 107 deletions

View File

@ -1,3 +1,37 @@
2005-09-20 Richard Henderson <rth@redhat.com>
* dwarf2dbg.c (struct line_entry): Replace frag and frag_ofs
with label.
(dwarf2_loc_mark_labels): New.
(dwarf2_gen_line_info_1): Split out of ...
(dwarf2_gen_line_info): ... here. Create the temp symbol here.
(dwarf2_emit_label): New.
(dwarf2_directive_loc_mark_labels): New.
(out_set_addr): Take a symbol instead of frag+ofs.
(relax_inc_line_addr): Likewise.
(emit_inc_line_addr): Assert delta non-negative.
(process_entries): Remove dead code. Update to work with temp
symbols instead of frag+ofs.
* dwarf2dbg.h (dwarf2_directive_loc_mark_labels): Declare.
(dwarf2_emit_label, dwarf2_loc_mark_labels): Declare.
* config/obj-elf.c (elf_pseudo_tab): Add loc_mark_labels.
* config/obj-elf.h (obj_frob_label): New.
* config/tc-alpha.c (alpha_define_label): Call dwarf2_emit_label.
* config/tc-arm.c, config/tc-hppa.c, config/tc-m68k.c,
config/tc-mips.c, config/tc-ppc.c, config/tc-sh.c, config/tc-xtensa.c:
Similarly in the respective tc_frob_label implementation functions.
* config/tc-i386.c (md_pseudo_table): Move file and loc to
non-elf section; add loc_mark_labels.
* config/tc-ia64.c (struct label_fix): Add dw2_mark_labels.
(ia64_flush_insns): Check for marked labels; emit line entry if so.
(emit_one_bundle): Similarly.
(ia64_frob_label): Record marked labels.
* config/tc-m68hc11.h (tc_frob_label): Remove.
* config/tc-ms1.c (md_pseudo_table): Remove file and loc.
* config/tc-sh.h (tc_frob_label): Pass sym to sh_frob_label.
* config/tc-sh64.h (tc_frob_label): Likewise.
* doc/as.texinfo (LNS directives): Docuement .loc_mark_blocks.
2005-09-20 Alan Modra <amodra@bigpond.net.au>
* read.c (pseudo_set): Set segment of expression syms to expr_section.

View File

@ -115,6 +115,7 @@ static const pseudo_typeS elf_pseudo_table[] =
/* These are used for dwarf2. */
{ "file", (void (*) (int)) dwarf2_directive_file, 0 },
{ "loc", dwarf2_directive_loc, 0 },
{ "loc_mark_labels", dwarf2_directive_loc_mark_labels, 0 },
/* We need to trap the section changing calls to handle .previous. */
{"data", obj_elf_data, 0},

View File

@ -156,6 +156,13 @@ extern void elf_frob_file_before_adjust (void);
#endif
extern void elf_frob_file_after_relocs (void);
/* If the target doesn't have special processing for labels, take care of
dwarf2 output at the object file level. */
#ifndef tc_frob_label
#include "dwarf2dbg.h"
#define obj_frob_label dwarf2_emit_label
#endif
#ifndef obj_app_file
#define obj_app_file elf_file_symbol
#endif

View File

@ -5464,6 +5464,9 @@ void
alpha_define_label (symbolS *sym)
{
alpha_insn_label = sym;
#ifdef OBJ_ELF
dwarf2_emit_label (sym);
#endif
}
/* Return true if we must always emit a reloc for a type and false if

View File

@ -8092,6 +8092,10 @@ arm_frob_label (symbolS * sym)
label_is_thumb_function_name = FALSE;
}
#ifdef OBJ_ELF
dwarf2_emit_label (sym);
#endif
}
int

View File

@ -1287,6 +1287,10 @@ pa_define_label (symbol)
label_symbols_rootp = label_chain;
}
#ifdef OBJ_ELF
dwarf2_emit_label (symbol);
#endif
}
/* Removes a label definition for the current space.

View File

@ -469,10 +469,12 @@ const pseudo_typeS md_pseudo_table[] =
{"code64", set_code_flag, CODE_64BIT},
{"intel_syntax", set_intel_syntax, 1},
{"att_syntax", set_intel_syntax, 0},
{"file", (void (*) PARAMS ((int))) dwarf2_directive_file, 0},
{"loc", dwarf2_directive_loc, 0},
#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
{"largecomm", handle_large_common, 0},
#else
{"file", (void (*) PARAMS ((int))) dwarf2_directive_file, 0},
{"loc", dwarf2_directive_loc, 0},
{"loc_mark_labels", dwarf2_directive_loc_mark_labels, 0},
#endif
#ifdef TE_PE
{"secrel32", pe_directive_secrel, 0},

View File

@ -159,6 +159,7 @@ struct label_fix
{
struct label_fix *next;
struct symbol *sym;
bfd_boolean dw2_mark_labels;
};
/* This is the endianness of the current section. */
@ -1083,6 +1084,7 @@ ia64_flush_insns ()
segT saved_seg;
subsegT saved_subseg;
unw_rec_list *ptr;
bfd_boolean mark;
if (!md.last_text_seg)
return;
@ -1096,18 +1098,23 @@ ia64_flush_insns ()
emit_one_bundle (); /* force out queued instructions */
/* In case there are labels following the last instruction, resolve
those now: */
those now. */
mark = FALSE;
for (lfix = CURR_SLOT.label_fixups; lfix; lfix = lfix->next)
{
S_SET_VALUE (lfix->sym, frag_now_fix ());
symbol_set_frag (lfix->sym, frag_now);
symbol_set_value_now (lfix->sym);
mark |= lfix->dw2_mark_labels;
}
if (mark)
{
dwarf2_where (&CURR_SLOT.debug_line);
CURR_SLOT.debug_line.flags |= DWARF2_FLAG_BASIC_BLOCK;
dwarf2_gen_line_info (frag_now_fix (), &CURR_SLOT.debug_line);
}
CURR_SLOT.label_fixups = 0;
for (lfix = CURR_SLOT.tag_fixups; lfix; lfix = lfix->next)
{
S_SET_VALUE (lfix->sym, frag_now_fix ());
symbol_set_frag (lfix->sym, frag_now);
}
symbol_set_value_now (lfix->sym);
CURR_SLOT.tag_fixups = 0;
/* In case there are unwind directives following the last instruction,
@ -6647,6 +6654,7 @@ emit_one_bundle ()
int n, i, j, first, curr, last_slot;
bfd_vma t0 = 0, t1 = 0;
struct label_fix *lfix;
bfd_boolean mark_label;
struct insn_fix *ifix;
char mnemonic[16];
fixS *fix;
@ -6967,11 +6975,30 @@ emit_one_bundle ()
if (insn_unit != required_unit)
continue; /* Try next slot. */
if (debug_type == DEBUG_DWARF2 || md.slot[curr].loc_directive_seen)
/* Now is a good time to fix up the labels for this insn. */
mark_label = FALSE;
for (lfix = md.slot[curr].label_fixups; lfix; lfix = lfix->next)
{
S_SET_VALUE (lfix->sym, frag_now_fix () - 16);
symbol_set_frag (lfix->sym, frag_now);
mark_label |= lfix->dw2_mark_labels;
}
for (lfix = md.slot[curr].tag_fixups; lfix; lfix = lfix->next)
{
S_SET_VALUE (lfix->sym, frag_now_fix () - 16 + i);
symbol_set_frag (lfix->sym, frag_now);
}
if (debug_type == DEBUG_DWARF2
|| md.slot[curr].loc_directive_seen
|| mark_label)
{
bfd_vma addr = frag_now->fr_address + frag_now_fix () - 16 + i;
md.slot[curr].loc_directive_seen = 0;
if (mark_label)
md.slot[curr].debug_line.flags |= DWARF2_FLAG_BASIC_BLOCK;
dwarf2_gen_line_info (addr, &md.slot[curr].debug_line);
}
@ -7000,19 +7027,6 @@ emit_one_bundle ()
--md.num_slots_in_use;
last_slot = i;
/* now is a good time to fix up the labels for this insn: */
for (lfix = md.slot[curr].label_fixups; lfix; lfix = lfix->next)
{
S_SET_VALUE (lfix->sym, frag_now_fix () - 16);
symbol_set_frag (lfix->sym, frag_now);
}
/* and fix up the tags also. */
for (lfix = md.slot[curr].tag_fixups; lfix; lfix = lfix->next)
{
S_SET_VALUE (lfix->sym, frag_now_fix () - 16 + i);
symbol_set_frag (lfix->sym, frag_now);
}
for (j = 0; j < md.slot[curr].num_fixups; ++j)
{
ifix = md.slot[curr].fixup + j;
@ -7904,6 +7918,7 @@ ia64_frob_label (sym)
fix = obstack_alloc (&notes, sizeof (*fix));
fix->sym = sym;
fix->next = CURR_SLOT.tag_fixups;
fix->dw2_mark_labels = FALSE;
CURR_SLOT.tag_fixups = fix;
return;
@ -7915,6 +7930,7 @@ ia64_frob_label (sym)
fix = obstack_alloc (&notes, sizeof (*fix));
fix->sym = sym;
fix->next = CURR_SLOT.label_fixups;
fix->dw2_mark_labels = dwarf2_loc_mark_labels;
CURR_SLOT.label_fixups = fix;
/* Keep track of how many code entry points we've seen. */

View File

@ -101,9 +101,6 @@ extern int tc_m68hc11_force_relocation (struct fix *);
extern int tc_m68hc11_fix_adjustable (struct fix *);
#define md_operand(x)
#define tc_frob_label(sym) do {\
S_SET_VALUE (sym, (valueT) frag_now_fix ()); \
} while (0)
#define elf_tc_final_processing m68hc11_elf_final_processing
extern void m68hc11_elf_final_processing (void);

View File

@ -4394,6 +4394,10 @@ m68k_frob_label (symbolS *sym)
n->text = 0;
labels = n;
current_label = n;
#ifdef OBJ_ELF
dwarf2_emit_label (sym);
#endif
}
/* This is called when a value that is not an instruction is emitted. */

View File

@ -13594,6 +13594,10 @@ mips_define_label (symbolS *sym)
l->label = sym;
l->next = insn_labels;
insn_labels = l;
#ifdef OBJ_ELF
dwarf2_emit_label (sym);
#endif
}
#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)

View File

@ -63,8 +63,6 @@ const char FLT_CHARS[] = "dD";
const pseudo_typeS md_pseudo_table[] =
{
{ "word", cons, 4 },
{ "file", (void (*) (int)) dwarf2_directive_file, 0 },
{ "loc", dwarf2_directive_loc, 0 },
{ NULL, NULL, 0 }
};

View File

@ -4840,6 +4840,10 @@ ppc_frob_label (sym)
&symbol_rootP, &symbol_lastP);
symbol_get_tc (ppc_current_csect)->within = sym;
}
#ifdef OBJ_ELF
dwarf2_emit_label (sym);
#endif
}
/* This variable is set by ppc_frob_symbol if any absolute symbols are

View File

@ -2876,7 +2876,7 @@ md_assemble (char *str)
emits a BFD_RELOC_SH_LABEL reloc if necessary. */
void
sh_frob_label (void)
sh_frob_label (symbolS *sym)
{
static fragS *last_label_frag;
static int last_label_offset;
@ -2895,6 +2895,8 @@ sh_frob_label (void)
last_label_offset = offset;
}
}
dwarf2_emit_label (sym);
}
/* This routine is called when the assembler is about to output some

View File

@ -103,8 +103,8 @@ struct sh_segment_info_type
/* We call a routine to emit a reloc for a label, so that the linker
can align loads and stores without crossing a label. */
extern void sh_frob_label (void);
#define tc_frob_label(sym) sh_frob_label ()
extern void sh_frob_label (symbolS *);
#define tc_frob_label(sym) sh_frob_label (sym)
/* We call a routine to flush pending output in order to output a DATA
reloc when required. */

View File

@ -144,7 +144,7 @@ extern void sh64_frob_label (symbolS *);
#undef tc_frob_label
#define tc_frob_label(sym) \
do { sh_frob_label (); sh64_frob_label (sym); } while (0)
do { sh_frob_label (sym); sh64_frob_label (sym); } while (0)
#define tc_symbol_new_hook(s) sh64_frob_label (s)

View File

@ -5054,7 +5054,7 @@ xtensa_frob_label (symbolS *sym)
xtensa_set_frag_assembly_state (frag_now);
xtensa_move_labels (frag_now, 0, TRUE);
}
}
/* No target aligning in the absolute section. */
if (now_seg != absolute_section
@ -5083,6 +5083,8 @@ xtensa_frob_label (symbolS *sym)
/* Loops only go forward, so they can be identified here. */
if (symbol_get_tc (sym)->is_loop_target)
symbol_get_frag (sym)->tc_frag_data.is_loop_target = TRUE;
dwarf2_emit_label (sym);
}

View File

@ -4103,6 +4103,15 @@ either 0 or 1.
@item isa @var{value}
This directive will set the @code{isa} register in the @code{.debug_line}
state machine to @var{value}, which must be an unsigned integer.
@section @code{.loc_mark_blocks @var{enable}}
@cindex @code{loc_mark_blocks} directive
The @code{.loc_mark_blocks} directive makes the assembler emit an entry
to the @code{.debug_line} line number matrix with the @code{basic_block}
register in the state machine set whenever a code label is seen.
The @var{enable} argument should be either 1 or 0, to enable or disable
this function respectively.
@end table
@node Data

View File

@ -105,8 +105,7 @@
struct line_entry {
struct line_entry *next;
fragS *frag;
addressT frag_ofs;
symbolS *label;
struct dwarf2_line_info loc;
};
@ -147,6 +146,10 @@ static unsigned int dirs_allocated;
doing work when there's nothing to do. */
static bfd_boolean loc_directive_seen;
/* TRUE when we're supposed to set the basic block mark whenever a
label is seen. */
bfd_boolean dwarf2_loc_mark_labels;
/* Current location as indicated by the most recent .loc directive. */
static struct dwarf2_line_info current = {
1, 1, 0, 0,
@ -167,12 +170,11 @@ static void out_four (int);
static void out_abbrev (int, int);
static void out_uleb128 (addressT);
static offsetT get_frag_fix (fragS *);
static void out_set_addr (segT, fragS *, addressT);
static void out_set_addr (symbolS *);
static int size_inc_line_addr (int, addressT);
static void emit_inc_line_addr (int, addressT, char *, int);
static void out_inc_line_addr (int, addressT);
static void relax_inc_line_addr (int, segT, fragS *, addressT,
fragS *, addressT);
static void relax_inc_line_addr (int, symbolS *, symbolS *);
static void process_entries (segT, struct line_entry *);
static void out_file_list (void);
static void out_debug_line (segT);
@ -247,16 +249,34 @@ get_line_subseg (segT seg, subsegT subseg)
return ss;
}
/* Record an entry for LOC occurring at LABEL. */
static void
dwarf2_gen_line_info_1 (symbolS *label, struct dwarf2_line_info *loc)
{
struct line_subseg *ss;
struct line_entry *e;
e = (struct line_entry *) xmalloc (sizeof (*e));
e->next = NULL;
e->label = label;
e->loc = *loc;
ss = get_line_subseg (now_seg, now_subseg);
*ss->ptail = e;
ss->ptail = &e->next;
}
/* Record an entry for LOC occurring at OFS within the current fragment. */
void
dwarf2_gen_line_info (addressT ofs, struct dwarf2_line_info *loc)
{
struct line_subseg *ss;
struct line_entry *e;
static unsigned int line = -1;
static unsigned int filenum = -1;
symbolS *sym;
/* Early out for as-yet incomplete location information. */
if (loc->filenum == 0 || loc->line == 0)
return;
@ -272,15 +292,8 @@ dwarf2_gen_line_info (addressT ofs, struct dwarf2_line_info *loc)
line = loc->line;
filenum = loc->filenum;
e = (struct line_entry *) xmalloc (sizeof (*e));
e->next = NULL;
e->frag = frag_now;
e->frag_ofs = ofs;
e->loc = *loc;
ss = get_line_subseg (now_seg, now_subseg);
*ss->ptail = e;
ss->ptail = &e->next;
sym = symbol_temp_new (now_seg, ofs, frag_now);
dwarf2_gen_line_info_1 (sym, loc);
}
/* Returns the current source information. If .file directives have
@ -349,6 +362,38 @@ dwarf2_emit_insn (int size)
| DWARF2_FLAG_EPILOGUE_BEGIN);
}
/* Called for each (preferably code) label. If dwarf2_loc_mark_labels
is enabled, emit a basic block marker. */
void
dwarf2_emit_label (symbolS *label)
{
struct dwarf2_line_info loc;
if (!dwarf2_loc_mark_labels)
return;
if (S_GET_SEGMENT (label) != now_seg)
return;
if (!(bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE))
return;
if (debug_type == DEBUG_DWARF2)
dwarf2_where (&loc);
else
{
loc = current;
loc_directive_seen = FALSE;
}
loc.flags |= DWARF2_FLAG_BASIC_BLOCK;
current.flags &= ~(DWARF2_FLAG_BASIC_BLOCK
| DWARF2_FLAG_PROLOGUE_END
| DWARF2_FLAG_EPILOGUE_BEGIN);
dwarf2_gen_line_info_1 (label, &loc);
}
/* Get a .debug_line file number for FILENAME. If NUM is nonzero,
allocate it on that file table slot, otherwise return the first
empty one. */
@ -603,6 +648,23 @@ dwarf2_directive_loc (int dummy ATTRIBUTE_UNUSED)
demand_empty_rest_of_line ();
loc_directive_seen = TRUE;
}
void
dwarf2_directive_loc_mark_labels (int dummy ATTRIBUTE_UNUSED)
{
offsetT value = get_absolute_expression ();
if (value != 0 && value != 1)
{
as_bad (_("expected 0 or 1"));
ignore_rest_of_line ();
}
else
{
dwarf2_loc_mark_labels = value != 0;
demand_empty_rest_of_line ();
}
}
static struct frag *
first_frag_for_seg (segT seg)
@ -702,12 +764,9 @@ get_frag_fix (fragS *frag)
/* Set an absolute address (may result in a relocation entry). */
static void
out_set_addr (segT seg, fragS *frag, addressT ofs)
out_set_addr (symbolS *sym)
{
expressionS expr;
symbolS *sym;
sym = symbol_temp_new (seg, ofs, frag);
out_opcode (DW_LNS_extended_op);
out_uleb128 (sizeof_address + 1);
@ -811,6 +870,10 @@ emit_inc_line_addr (int line_delta, addressT addr_delta, char *p, int len)
int need_copy = 0;
char *end = p + len;
/* Line number sequences cannot go backward in addresses. This means
we've incorrectly ordered the statements in the sequence. */
assert ((offsetT) addr_delta >= 0);
/* Scale the address delta by the minimum instruction length. */
scale_addr_delta (&addr_delta);
@ -906,17 +969,11 @@ out_inc_line_addr (int line_delta, addressT addr_delta)
increments between fragments of the target segment. */
static void
relax_inc_line_addr (int line_delta, segT seg,
fragS *to_frag, addressT to_ofs,
fragS *from_frag, addressT from_ofs)
relax_inc_line_addr (int line_delta, symbolS *to_sym, symbolS *from_sym)
{
symbolS *to_sym, *from_sym;
expressionS expr;
int max_chars;
to_sym = symbol_temp_new (seg, to_ofs, to_frag);
from_sym = symbol_temp_new (seg, from_ofs, from_frag);
expr.X_op = O_subtract;
expr.X_add_symbol = to_sym;
expr.X_op_symbol = from_sym;
@ -999,22 +1056,20 @@ process_entries (segT seg, struct line_entry *e)
unsigned column = 0;
unsigned isa = 0;
unsigned flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
fragS *frag = NULL;
fragS *last_frag;
addressT frag_ofs = 0;
addressT last_frag_ofs;
fragS *last_frag = NULL, *frag;
addressT last_frag_ofs = 0, frag_ofs;
symbolS *last_lab, *lab;
struct line_entry *next;
while (e)
{
int changed = 0;
int line_delta;
if (filenum != e->loc.filenum)
{
filenum = e->loc.filenum;
out_opcode (DW_LNS_set_file);
out_uleb128 (filenum);
changed = 1;
}
if (column != e->loc.column)
@ -1022,7 +1077,6 @@ process_entries (segT seg, struct line_entry *e)
column = e->loc.column;
out_opcode (DW_LNS_set_column);
out_uleb128 (column);
changed = 1;
}
if (isa != e->loc.isa)
@ -1030,62 +1084,46 @@ process_entries (segT seg, struct line_entry *e)
isa = e->loc.isa;
out_opcode (DW_LNS_set_isa);
out_uleb128 (isa);
changed = 1;
}
if ((e->loc.flags ^ flags) & DWARF2_FLAG_IS_STMT)
{
flags = e->loc.flags;
out_opcode (DW_LNS_negate_stmt);
changed = 1;
}
if (e->loc.flags & DWARF2_FLAG_BASIC_BLOCK)
{
out_opcode (DW_LNS_set_basic_block);
changed = 1;
}
out_opcode (DW_LNS_set_basic_block);
if (e->loc.flags & DWARF2_FLAG_PROLOGUE_END)
{
out_opcode (DW_LNS_set_prologue_end);
changed = 1;
}
out_opcode (DW_LNS_set_prologue_end);
if (e->loc.flags & DWARF2_FLAG_EPILOGUE_BEGIN)
{
out_opcode (DW_LNS_set_epilogue_begin);
changed = 1;
}
out_opcode (DW_LNS_set_epilogue_begin);
/* Don't try to optimize away redundant entries; gdb wants two
entries for a function where the code starts on the same line as
the {, and there's no way to identify that case here. Trust gcc
to optimize appropriately. */
if (1 /* line != e->loc.line || changed */)
{
int line_delta = e->loc.line - line;
if (frag == NULL)
{
out_set_addr (seg, e->frag, e->frag_ofs);
out_inc_line_addr (line_delta, 0);
}
else if (frag == e->frag)
out_inc_line_addr (line_delta, e->frag_ofs - frag_ofs);
else
relax_inc_line_addr (line_delta, seg, e->frag, e->frag_ofs,
frag, frag_ofs);
line_delta = e->loc.line - line;
lab = e->label;
frag = symbol_get_frag (lab);
frag_ofs = S_GET_VALUE (lab);
frag = e->frag;
frag_ofs = e->frag_ofs;
line = e->loc.line;
}
else if (frag == NULL)
if (last_frag == NULL)
{
out_set_addr (seg, e->frag, e->frag_ofs);
frag = e->frag;
frag_ofs = e->frag_ofs;
out_set_addr (lab);
out_inc_line_addr (line_delta, 0);
}
else if (frag == last_frag)
out_inc_line_addr (line_delta, frag_ofs - last_frag_ofs);
else
relax_inc_line_addr (line_delta, lab, last_lab);
line = e->loc.line;
last_lab = lab;
last_frag = frag;
last_frag_ofs = frag_ofs;
next = e->next;
free (e);
@ -1093,13 +1131,15 @@ process_entries (segT seg, struct line_entry *e)
}
/* Emit a DW_LNE_end_sequence for the end of the section. */
last_frag = last_frag_for_seg (seg);
last_frag_ofs = get_frag_fix (last_frag);
frag = last_frag_for_seg (seg);
frag_ofs = get_frag_fix (frag);
if (frag == last_frag)
out_inc_line_addr (INT_MAX, last_frag_ofs - frag_ofs);
out_inc_line_addr (INT_MAX, frag_ofs - last_frag_ofs);
else
relax_inc_line_addr (INT_MAX, seg, last_frag, last_frag_ofs,
frag, frag_ofs);
{
lab = symbol_temp_new (seg, frag_ofs, frag);
relax_inc_line_addr (INT_MAX, lab, last_lab);
}
}
/* Emit the directory and file tables for .debug_line. */

View File

@ -49,6 +49,9 @@ extern char *dwarf2_directive_file (int dummy);
used. */
extern void dwarf2_directive_loc (int dummy);
/* Implements the .loc_mark_labels {0,1} directive. */
extern void dwarf2_directive_loc_mark_labels (int dummy);
/* Returns the current source information. If .file directives have
been encountered, the info for the corresponding source file is
returned. Otherwise, the info for the assembly source file is
@ -69,6 +72,14 @@ extern void dwarf2_gen_line_info (addressT addr, struct dwarf2_line_info *l);
/* Must be called for each generated instruction. */
extern void dwarf2_emit_insn (int);
/* Should be called for each code label. */
extern void dwarf2_emit_label (symbolS *);
/* True when we're supposed to set the basic block mark whenever a label
is seen. Unless the target is doing Something Weird, just call
dwarf2_emit_label. */
bfd_boolean dwarf2_loc_mark_labels;
extern void dwarf2_finish (void);
extern int dwarf2dbg_estimate_size_before_relax (fragS *);