* 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:
parent
d5cbaa1554
commit
07a53e5cdb
|
@ -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.
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -8092,6 +8092,10 @@ arm_frob_label (symbolS * sym)
|
|||
|
||||
label_is_thumb_function_name = FALSE;
|
||||
}
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
dwarf2_emit_label (sym);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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 (¬es, 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 (¬es, 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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 }
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
188
gas/dwarf2dbg.c
188
gas/dwarf2dbg.c
|
@ -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. */
|
||||
|
|
|
@ -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 *);
|
||||
|
|
Loading…
Reference in New Issue