* 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
20 changed files with 249 additions and 107 deletions
|
@ -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>
|
2005-09-20 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
* read.c (pseudo_set): Set segment of expression syms to expr_section.
|
* 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. */
|
/* These are used for dwarf2. */
|
||||||
{ "file", (void (*) (int)) dwarf2_directive_file, 0 },
|
{ "file", (void (*) (int)) dwarf2_directive_file, 0 },
|
||||||
{ "loc", dwarf2_directive_loc, 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. */
|
/* We need to trap the section changing calls to handle .previous. */
|
||||||
{"data", obj_elf_data, 0},
|
{"data", obj_elf_data, 0},
|
||||||
|
|
|
@ -156,6 +156,13 @@ extern void elf_frob_file_before_adjust (void);
|
||||||
#endif
|
#endif
|
||||||
extern void elf_frob_file_after_relocs (void);
|
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
|
#ifndef obj_app_file
|
||||||
#define obj_app_file elf_file_symbol
|
#define obj_app_file elf_file_symbol
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5464,6 +5464,9 @@ void
|
||||||
alpha_define_label (symbolS *sym)
|
alpha_define_label (symbolS *sym)
|
||||||
{
|
{
|
||||||
alpha_insn_label = 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
|
/* 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;
|
label_is_thumb_function_name = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef OBJ_ELF
|
||||||
|
dwarf2_emit_label (sym);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
@ -1287,6 +1287,10 @@ pa_define_label (symbol)
|
||||||
|
|
||||||
label_symbols_rootp = label_chain;
|
label_symbols_rootp = label_chain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef OBJ_ELF
|
||||||
|
dwarf2_emit_label (symbol);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Removes a label definition for the current space.
|
/* Removes a label definition for the current space.
|
||||||
|
|
|
@ -469,10 +469,12 @@ const pseudo_typeS md_pseudo_table[] =
|
||||||
{"code64", set_code_flag, CODE_64BIT},
|
{"code64", set_code_flag, CODE_64BIT},
|
||||||
{"intel_syntax", set_intel_syntax, 1},
|
{"intel_syntax", set_intel_syntax, 1},
|
||||||
{"att_syntax", set_intel_syntax, 0},
|
{"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)
|
#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
|
||||||
{"largecomm", handle_large_common, 0},
|
{"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
|
#endif
|
||||||
#ifdef TE_PE
|
#ifdef TE_PE
|
||||||
{"secrel32", pe_directive_secrel, 0},
|
{"secrel32", pe_directive_secrel, 0},
|
||||||
|
|
|
@ -159,6 +159,7 @@ struct label_fix
|
||||||
{
|
{
|
||||||
struct label_fix *next;
|
struct label_fix *next;
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
|
bfd_boolean dw2_mark_labels;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This is the endianness of the current section. */
|
/* This is the endianness of the current section. */
|
||||||
|
@ -1083,6 +1084,7 @@ ia64_flush_insns ()
|
||||||
segT saved_seg;
|
segT saved_seg;
|
||||||
subsegT saved_subseg;
|
subsegT saved_subseg;
|
||||||
unw_rec_list *ptr;
|
unw_rec_list *ptr;
|
||||||
|
bfd_boolean mark;
|
||||||
|
|
||||||
if (!md.last_text_seg)
|
if (!md.last_text_seg)
|
||||||
return;
|
return;
|
||||||
|
@ -1096,18 +1098,23 @@ ia64_flush_insns ()
|
||||||
emit_one_bundle (); /* force out queued instructions */
|
emit_one_bundle (); /* force out queued instructions */
|
||||||
|
|
||||||
/* In case there are labels following the last instruction, resolve
|
/* 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)
|
for (lfix = CURR_SLOT.label_fixups; lfix; lfix = lfix->next)
|
||||||
{
|
{
|
||||||
S_SET_VALUE (lfix->sym, frag_now_fix ());
|
symbol_set_value_now (lfix->sym);
|
||||||
symbol_set_frag (lfix->sym, frag_now);
|
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;
|
CURR_SLOT.label_fixups = 0;
|
||||||
|
|
||||||
for (lfix = CURR_SLOT.tag_fixups; lfix; lfix = lfix->next)
|
for (lfix = CURR_SLOT.tag_fixups; lfix; lfix = lfix->next)
|
||||||
{
|
symbol_set_value_now (lfix->sym);
|
||||||
S_SET_VALUE (lfix->sym, frag_now_fix ());
|
|
||||||
symbol_set_frag (lfix->sym, frag_now);
|
|
||||||
}
|
|
||||||
CURR_SLOT.tag_fixups = 0;
|
CURR_SLOT.tag_fixups = 0;
|
||||||
|
|
||||||
/* In case there are unwind directives following the last instruction,
|
/* 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;
|
int n, i, j, first, curr, last_slot;
|
||||||
bfd_vma t0 = 0, t1 = 0;
|
bfd_vma t0 = 0, t1 = 0;
|
||||||
struct label_fix *lfix;
|
struct label_fix *lfix;
|
||||||
|
bfd_boolean mark_label;
|
||||||
struct insn_fix *ifix;
|
struct insn_fix *ifix;
|
||||||
char mnemonic[16];
|
char mnemonic[16];
|
||||||
fixS *fix;
|
fixS *fix;
|
||||||
|
@ -6967,11 +6975,30 @@ emit_one_bundle ()
|
||||||
if (insn_unit != required_unit)
|
if (insn_unit != required_unit)
|
||||||
continue; /* Try next slot. */
|
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;
|
bfd_vma addr = frag_now->fr_address + frag_now_fix () - 16 + i;
|
||||||
|
|
||||||
md.slot[curr].loc_directive_seen = 0;
|
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);
|
dwarf2_gen_line_info (addr, &md.slot[curr].debug_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7000,19 +7027,6 @@ emit_one_bundle ()
|
||||||
--md.num_slots_in_use;
|
--md.num_slots_in_use;
|
||||||
last_slot = i;
|
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)
|
for (j = 0; j < md.slot[curr].num_fixups; ++j)
|
||||||
{
|
{
|
||||||
ifix = md.slot[curr].fixup + j;
|
ifix = md.slot[curr].fixup + j;
|
||||||
|
@ -7904,6 +7918,7 @@ ia64_frob_label (sym)
|
||||||
fix = obstack_alloc (¬es, sizeof (*fix));
|
fix = obstack_alloc (¬es, sizeof (*fix));
|
||||||
fix->sym = sym;
|
fix->sym = sym;
|
||||||
fix->next = CURR_SLOT.tag_fixups;
|
fix->next = CURR_SLOT.tag_fixups;
|
||||||
|
fix->dw2_mark_labels = FALSE;
|
||||||
CURR_SLOT.tag_fixups = fix;
|
CURR_SLOT.tag_fixups = fix;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -7915,6 +7930,7 @@ ia64_frob_label (sym)
|
||||||
fix = obstack_alloc (¬es, sizeof (*fix));
|
fix = obstack_alloc (¬es, sizeof (*fix));
|
||||||
fix->sym = sym;
|
fix->sym = sym;
|
||||||
fix->next = CURR_SLOT.label_fixups;
|
fix->next = CURR_SLOT.label_fixups;
|
||||||
|
fix->dw2_mark_labels = dwarf2_loc_mark_labels;
|
||||||
CURR_SLOT.label_fixups = fix;
|
CURR_SLOT.label_fixups = fix;
|
||||||
|
|
||||||
/* Keep track of how many code entry points we've seen. */
|
/* 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 *);
|
extern int tc_m68hc11_fix_adjustable (struct fix *);
|
||||||
|
|
||||||
#define md_operand(x)
|
#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
|
#define elf_tc_final_processing m68hc11_elf_final_processing
|
||||||
extern void m68hc11_elf_final_processing (void);
|
extern void m68hc11_elf_final_processing (void);
|
||||||
|
|
|
@ -4394,6 +4394,10 @@ m68k_frob_label (symbolS *sym)
|
||||||
n->text = 0;
|
n->text = 0;
|
||||||
labels = n;
|
labels = n;
|
||||||
current_label = 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. */
|
/* 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->label = sym;
|
||||||
l->next = insn_labels;
|
l->next = insn_labels;
|
||||||
insn_labels = l;
|
insn_labels = l;
|
||||||
|
|
||||||
|
#ifdef OBJ_ELF
|
||||||
|
dwarf2_emit_label (sym);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
|
#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
|
||||||
|
|
|
@ -63,8 +63,6 @@ const char FLT_CHARS[] = "dD";
|
||||||
const pseudo_typeS md_pseudo_table[] =
|
const pseudo_typeS md_pseudo_table[] =
|
||||||
{
|
{
|
||||||
{ "word", cons, 4 },
|
{ "word", cons, 4 },
|
||||||
{ "file", (void (*) (int)) dwarf2_directive_file, 0 },
|
|
||||||
{ "loc", dwarf2_directive_loc, 0 },
|
|
||||||
{ NULL, NULL, 0 }
|
{ NULL, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4840,6 +4840,10 @@ ppc_frob_label (sym)
|
||||||
&symbol_rootP, &symbol_lastP);
|
&symbol_rootP, &symbol_lastP);
|
||||||
symbol_get_tc (ppc_current_csect)->within = sym;
|
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
|
/* 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. */
|
emits a BFD_RELOC_SH_LABEL reloc if necessary. */
|
||||||
|
|
||||||
void
|
void
|
||||||
sh_frob_label (void)
|
sh_frob_label (symbolS *sym)
|
||||||
{
|
{
|
||||||
static fragS *last_label_frag;
|
static fragS *last_label_frag;
|
||||||
static int last_label_offset;
|
static int last_label_offset;
|
||||||
|
@ -2895,6 +2895,8 @@ sh_frob_label (void)
|
||||||
last_label_offset = offset;
|
last_label_offset = offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dwarf2_emit_label (sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This routine is called when the assembler is about to output some
|
/* 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
|
/* We call a routine to emit a reloc for a label, so that the linker
|
||||||
can align loads and stores without crossing a label. */
|
can align loads and stores without crossing a label. */
|
||||||
extern void sh_frob_label (void);
|
extern void sh_frob_label (symbolS *);
|
||||||
#define tc_frob_label(sym) sh_frob_label ()
|
#define tc_frob_label(sym) sh_frob_label (sym)
|
||||||
|
|
||||||
/* We call a routine to flush pending output in order to output a DATA
|
/* We call a routine to flush pending output in order to output a DATA
|
||||||
reloc when required. */
|
reloc when required. */
|
||||||
|
|
|
@ -144,7 +144,7 @@ extern void sh64_frob_label (symbolS *);
|
||||||
|
|
||||||
#undef tc_frob_label
|
#undef tc_frob_label
|
||||||
#define tc_frob_label(sym) \
|
#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)
|
#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_set_frag_assembly_state (frag_now);
|
||||||
xtensa_move_labels (frag_now, 0, TRUE);
|
xtensa_move_labels (frag_now, 0, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No target aligning in the absolute section. */
|
/* No target aligning in the absolute section. */
|
||||||
if (now_seg != 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. */
|
/* Loops only go forward, so they can be identified here. */
|
||||||
if (symbol_get_tc (sym)->is_loop_target)
|
if (symbol_get_tc (sym)->is_loop_target)
|
||||||
symbol_get_frag (sym)->tc_frag_data.is_loop_target = TRUE;
|
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}
|
@item isa @var{value}
|
||||||
This directive will set the @code{isa} register in the @code{.debug_line}
|
This directive will set the @code{isa} register in the @code{.debug_line}
|
||||||
state machine to @var{value}, which must be an unsigned integer.
|
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
|
@end table
|
||||||
|
|
||||||
@node Data
|
@node Data
|
||||||
|
|
188
gas/dwarf2dbg.c
188
gas/dwarf2dbg.c
|
@ -105,8 +105,7 @@
|
||||||
|
|
||||||
struct line_entry {
|
struct line_entry {
|
||||||
struct line_entry *next;
|
struct line_entry *next;
|
||||||
fragS *frag;
|
symbolS *label;
|
||||||
addressT frag_ofs;
|
|
||||||
struct dwarf2_line_info loc;
|
struct dwarf2_line_info loc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -147,6 +146,10 @@ static unsigned int dirs_allocated;
|
||||||
doing work when there's nothing to do. */
|
doing work when there's nothing to do. */
|
||||||
static bfd_boolean loc_directive_seen;
|
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. */
|
/* Current location as indicated by the most recent .loc directive. */
|
||||||
static struct dwarf2_line_info current = {
|
static struct dwarf2_line_info current = {
|
||||||
1, 1, 0, 0,
|
1, 1, 0, 0,
|
||||||
|
@ -167,12 +170,11 @@ static void out_four (int);
|
||||||
static void out_abbrev (int, int);
|
static void out_abbrev (int, int);
|
||||||
static void out_uleb128 (addressT);
|
static void out_uleb128 (addressT);
|
||||||
static offsetT get_frag_fix (fragS *);
|
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 int size_inc_line_addr (int, addressT);
|
||||||
static void emit_inc_line_addr (int, addressT, char *, int);
|
static void emit_inc_line_addr (int, addressT, char *, int);
|
||||||
static void out_inc_line_addr (int, addressT);
|
static void out_inc_line_addr (int, addressT);
|
||||||
static void relax_inc_line_addr (int, segT, fragS *, addressT,
|
static void relax_inc_line_addr (int, symbolS *, symbolS *);
|
||||||
fragS *, addressT);
|
|
||||||
static void process_entries (segT, struct line_entry *);
|
static void process_entries (segT, struct line_entry *);
|
||||||
static void out_file_list (void);
|
static void out_file_list (void);
|
||||||
static void out_debug_line (segT);
|
static void out_debug_line (segT);
|
||||||
|
@ -247,16 +249,34 @@ get_line_subseg (segT seg, subsegT subseg)
|
||||||
return ss;
|
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. */
|
/* Record an entry for LOC occurring at OFS within the current fragment. */
|
||||||
|
|
||||||
void
|
void
|
||||||
dwarf2_gen_line_info (addressT ofs, struct dwarf2_line_info *loc)
|
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 line = -1;
|
||||||
static unsigned int filenum = -1;
|
static unsigned int filenum = -1;
|
||||||
|
|
||||||
|
symbolS *sym;
|
||||||
|
|
||||||
/* Early out for as-yet incomplete location information. */
|
/* Early out for as-yet incomplete location information. */
|
||||||
if (loc->filenum == 0 || loc->line == 0)
|
if (loc->filenum == 0 || loc->line == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -272,15 +292,8 @@ dwarf2_gen_line_info (addressT ofs, struct dwarf2_line_info *loc)
|
||||||
line = loc->line;
|
line = loc->line;
|
||||||
filenum = loc->filenum;
|
filenum = loc->filenum;
|
||||||
|
|
||||||
e = (struct line_entry *) xmalloc (sizeof (*e));
|
sym = symbol_temp_new (now_seg, ofs, frag_now);
|
||||||
e->next = NULL;
|
dwarf2_gen_line_info_1 (sym, loc);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns the current source information. If .file directives have
|
/* Returns the current source information. If .file directives have
|
||||||
|
@ -349,6 +362,38 @@ dwarf2_emit_insn (int size)
|
||||||
| DWARF2_FLAG_EPILOGUE_BEGIN);
|
| 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,
|
/* Get a .debug_line file number for FILENAME. If NUM is nonzero,
|
||||||
allocate it on that file table slot, otherwise return the first
|
allocate it on that file table slot, otherwise return the first
|
||||||
empty one. */
|
empty one. */
|
||||||
|
@ -603,6 +648,23 @@ dwarf2_directive_loc (int dummy ATTRIBUTE_UNUSED)
|
||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
loc_directive_seen = TRUE;
|
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 *
|
static struct frag *
|
||||||
first_frag_for_seg (segT seg)
|
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). */
|
/* Set an absolute address (may result in a relocation entry). */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
out_set_addr (segT seg, fragS *frag, addressT ofs)
|
out_set_addr (symbolS *sym)
|
||||||
{
|
{
|
||||||
expressionS expr;
|
expressionS expr;
|
||||||
symbolS *sym;
|
|
||||||
|
|
||||||
sym = symbol_temp_new (seg, ofs, frag);
|
|
||||||
|
|
||||||
out_opcode (DW_LNS_extended_op);
|
out_opcode (DW_LNS_extended_op);
|
||||||
out_uleb128 (sizeof_address + 1);
|
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;
|
int need_copy = 0;
|
||||||
char *end = p + len;
|
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 the address delta by the minimum instruction length. */
|
||||||
scale_addr_delta (&addr_delta);
|
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. */
|
increments between fragments of the target segment. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
relax_inc_line_addr (int line_delta, segT seg,
|
relax_inc_line_addr (int line_delta, symbolS *to_sym, symbolS *from_sym)
|
||||||
fragS *to_frag, addressT to_ofs,
|
|
||||||
fragS *from_frag, addressT from_ofs)
|
|
||||||
{
|
{
|
||||||
symbolS *to_sym, *from_sym;
|
|
||||||
expressionS expr;
|
expressionS expr;
|
||||||
int max_chars;
|
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_op = O_subtract;
|
||||||
expr.X_add_symbol = to_sym;
|
expr.X_add_symbol = to_sym;
|
||||||
expr.X_op_symbol = from_sym;
|
expr.X_op_symbol = from_sym;
|
||||||
|
@ -999,22 +1056,20 @@ process_entries (segT seg, struct line_entry *e)
|
||||||
unsigned column = 0;
|
unsigned column = 0;
|
||||||
unsigned isa = 0;
|
unsigned isa = 0;
|
||||||
unsigned flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
|
unsigned flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
|
||||||
fragS *frag = NULL;
|
fragS *last_frag = NULL, *frag;
|
||||||
fragS *last_frag;
|
addressT last_frag_ofs = 0, frag_ofs;
|
||||||
addressT frag_ofs = 0;
|
symbolS *last_lab, *lab;
|
||||||
addressT last_frag_ofs;
|
|
||||||
struct line_entry *next;
|
struct line_entry *next;
|
||||||
|
|
||||||
while (e)
|
while (e)
|
||||||
{
|
{
|
||||||
int changed = 0;
|
int line_delta;
|
||||||
|
|
||||||
if (filenum != e->loc.filenum)
|
if (filenum != e->loc.filenum)
|
||||||
{
|
{
|
||||||
filenum = e->loc.filenum;
|
filenum = e->loc.filenum;
|
||||||
out_opcode (DW_LNS_set_file);
|
out_opcode (DW_LNS_set_file);
|
||||||
out_uleb128 (filenum);
|
out_uleb128 (filenum);
|
||||||
changed = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (column != e->loc.column)
|
if (column != e->loc.column)
|
||||||
|
@ -1022,7 +1077,6 @@ process_entries (segT seg, struct line_entry *e)
|
||||||
column = e->loc.column;
|
column = e->loc.column;
|
||||||
out_opcode (DW_LNS_set_column);
|
out_opcode (DW_LNS_set_column);
|
||||||
out_uleb128 (column);
|
out_uleb128 (column);
|
||||||
changed = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isa != e->loc.isa)
|
if (isa != e->loc.isa)
|
||||||
|
@ -1030,62 +1084,46 @@ process_entries (segT seg, struct line_entry *e)
|
||||||
isa = e->loc.isa;
|
isa = e->loc.isa;
|
||||||
out_opcode (DW_LNS_set_isa);
|
out_opcode (DW_LNS_set_isa);
|
||||||
out_uleb128 (isa);
|
out_uleb128 (isa);
|
||||||
changed = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((e->loc.flags ^ flags) & DWARF2_FLAG_IS_STMT)
|
if ((e->loc.flags ^ flags) & DWARF2_FLAG_IS_STMT)
|
||||||
{
|
{
|
||||||
flags = e->loc.flags;
|
flags = e->loc.flags;
|
||||||
out_opcode (DW_LNS_negate_stmt);
|
out_opcode (DW_LNS_negate_stmt);
|
||||||
changed = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e->loc.flags & DWARF2_FLAG_BASIC_BLOCK)
|
if (e->loc.flags & DWARF2_FLAG_BASIC_BLOCK)
|
||||||
{
|
out_opcode (DW_LNS_set_basic_block);
|
||||||
out_opcode (DW_LNS_set_basic_block);
|
|
||||||
changed = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e->loc.flags & DWARF2_FLAG_PROLOGUE_END)
|
if (e->loc.flags & DWARF2_FLAG_PROLOGUE_END)
|
||||||
{
|
out_opcode (DW_LNS_set_prologue_end);
|
||||||
out_opcode (DW_LNS_set_prologue_end);
|
|
||||||
changed = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e->loc.flags & DWARF2_FLAG_EPILOGUE_BEGIN)
|
if (e->loc.flags & DWARF2_FLAG_EPILOGUE_BEGIN)
|
||||||
{
|
out_opcode (DW_LNS_set_epilogue_begin);
|
||||||
out_opcode (DW_LNS_set_epilogue_begin);
|
|
||||||
changed = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Don't try to optimize away redundant entries; gdb wants two
|
/* Don't try to optimize away redundant entries; gdb wants two
|
||||||
entries for a function where the code starts on the same line as
|
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
|
the {, and there's no way to identify that case here. Trust gcc
|
||||||
to optimize appropriately. */
|
to optimize appropriately. */
|
||||||
if (1 /* line != e->loc.line || changed */)
|
line_delta = e->loc.line - line;
|
||||||
{
|
lab = e->label;
|
||||||
int line_delta = e->loc.line - line;
|
frag = symbol_get_frag (lab);
|
||||||
if (frag == NULL)
|
frag_ofs = S_GET_VALUE (lab);
|
||||||
{
|
|
||||||
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);
|
|
||||||
|
|
||||||
frag = e->frag;
|
if (last_frag == NULL)
|
||||||
frag_ofs = e->frag_ofs;
|
|
||||||
line = e->loc.line;
|
|
||||||
}
|
|
||||||
else if (frag == NULL)
|
|
||||||
{
|
{
|
||||||
out_set_addr (seg, e->frag, e->frag_ofs);
|
out_set_addr (lab);
|
||||||
frag = e->frag;
|
out_inc_line_addr (line_delta, 0);
|
||||||
frag_ofs = e->frag_ofs;
|
|
||||||
}
|
}
|
||||||
|
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;
|
next = e->next;
|
||||||
free (e);
|
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. */
|
/* Emit a DW_LNE_end_sequence for the end of the section. */
|
||||||
last_frag = last_frag_for_seg (seg);
|
frag = last_frag_for_seg (seg);
|
||||||
last_frag_ofs = get_frag_fix (last_frag);
|
frag_ofs = get_frag_fix (frag);
|
||||||
if (frag == last_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
|
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. */
|
/* Emit the directory and file tables for .debug_line. */
|
||||||
|
|
|
@ -49,6 +49,9 @@ extern char *dwarf2_directive_file (int dummy);
|
||||||
used. */
|
used. */
|
||||||
extern void dwarf2_directive_loc (int dummy);
|
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
|
/* Returns the current source information. If .file directives have
|
||||||
been encountered, the info for the corresponding source file is
|
been encountered, the info for the corresponding source file is
|
||||||
returned. Otherwise, the info for the assembly 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. */
|
/* Must be called for each generated instruction. */
|
||||||
extern void dwarf2_emit_insn (int);
|
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 void dwarf2_finish (void);
|
||||||
|
|
||||||
extern int dwarf2dbg_estimate_size_before_relax (fragS *);
|
extern int dwarf2dbg_estimate_size_before_relax (fragS *);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue