+2000-11-17 Richard Henderson <rth@redhat.com>
+
+ * as.c (debug_type): Init to DEBUG_UNSPECIFIED.
+ * as.h (debug_type): Clarify documentation of the meaning
+ of this variable.
+ * dwarf2dbg.c (DWARF2_LINE_MIN_INSN_LENGTH): Default to 1.
+ (print_stats): Fix parenthesis problem.
+ (now_subseg_size): New.
+ (dwarf2_finish): Use it. If DEBUG_DWARF2, emit bits for .debug_info.
+ (dwarf2_directive_file): Don't set debug_type.
+ (dwarf2_where): Honor DEBUG_DWARF2 first.
+ (dwarf2_emit_insn): Renamed from dwarf2_generate_asm_lineno;
+ do nothing if not emitting dwarf2 debug info, or no work.
+ * dwarf2dbg.h (dwarf2_emit_insn): Update.
+ * ecoff.c (add_file): Turn on DEBUG_ECOFF only if DEBUG_UNSPECIFIED.
+ (ecoff_new_file): Likewise.
+ * read.c (generate_lineno_debug): Kill ecoff hackery. Update
+ commentary wrt dwarf2.
+
+ * config/tc-alpha.c (alpha_adjust_symtab_relocs): Add
+ ATTRIBUTE_UNUSED as needed.
+ (emit_insn): Call dwarf2_emit_insn.
+ (s_alpha_file): New.
+ (s_alpha_loc): New.
+ (s_alpha_coff_wrapper): Don't handle them.
+ (md_pseudo_table): Update for .file and .loc.
+ * config/tc-alpha.h (DWARF2_LINE_MIN_INSN_LENGTH): New.
+
+ * config/tc-arm.c (output_inst): Update for dwarf2_emit_insn;
+ don't protect with debug_type.
+ * config/tc-hppa.c (md_assemble): Likewise.
+ * config/tc-m68hc11.c (m68hc11_new_insn): Likewise.
+ * config/tc-mn10300.c (md_assemble): Likewise.
+ * config/tc-sh.c (md_assemble): Likewise.
+ * config/tc-v850.c (md_assemble): Likewise.
+
+ * config/tc-arm.c (arm_end_of_source): Remove.
+ * config/tc-hppa.c (pa_end_of_source): Remove.
+ * config/tc-m68hc11.c (m68hc11_end_of_source): Remove.
+ * config/tc-mn10300.c (mn10300_finalize): Remove.
+ * config/tc-sh.c (sh_finalize): Remove.
+ * config/tc-v850.c (sh_finalize): Remove.
+
+ * config/tc-arm.h (md_end): Remove.
+ * config/tc-hppa.h (md_end): Remove.
+ (DWARF2_LINE_MIN_INSN_LENGTH): New.
+ * config/tc-m68hc11.h (md_end): Remove.
+ * config/tc-mn10300.h (md_end): Remove.
+ * config/tc-sh.h (md_end): Remove.
+ * config/tc-v850.h (md_end): Remove.
+
+ * config/tc-ia64.c (emit_one_bundle): Don't protect
+ dwarf2 bits with debug_type.
+ (md_assemble): Likewise.
+ (ia64_end_of_source): Don't call dwarf2_finish.
+
2000-11-16 Jim Wilson <wilson@redhat.com>
* config/tc-ia64.c (errata_nop_necessary_p): Abort if general regno
/* Type of debugging to generate. */
-enum debug_info_type debug_type = DEBUG_NONE;
+enum debug_info_type debug_type = DEBUG_UNSPECIFIED;
/* Maximum level of macro nesting. */
int max_macro_nest = 100;
/* TRUE if we should produce a listing. */
extern int listing;
-/* Type of debugging information we should generate. We currently
- support stabs, ECOFF, and DWARF2. */
+/* Type of debugging information we should generate. We currently support
+ stabs, ECOFF, and DWARF2.
+
+ NOTE! This means debug information about the assembly source code itself
+ and _not_ about possible debug information from a high-level language.
+ This is especially relevant to DWARF2, since the compiler may emit line
+ number directives that the assembler resolves. */
enum debug_info_type {
DEBUG_UNSPECIFIED,
#ifdef OBJ_ELF
#include "elf/alpha.h"
+#include "dwarf2dbg.h"
#endif
#include <ctype.h>
static void s_alpha_mask PARAMS ((int));
static void s_alpha_frame PARAMS ((int));
static void s_alpha_prologue PARAMS ((int));
+static void s_alpha_file PARAMS ((int));
+static void s_alpha_loc PARAMS ((int));
static void s_alpha_coff_wrapper PARAMS ((int));
#endif
#ifdef OBJ_EVAX
static offsetT alpha_lit8_literal;
#endif
-/* The active .ent symbol. */
#ifdef OBJ_ELF
+/* The active .ent symbol. */
static symbolS *alpha_cur_ent_sym;
#endif
static void
alpha_adjust_symtab_relocs (abfd, sec, ptr)
- bfd *abfd;
+ bfd *abfd ATTRIBUTE_UNUSED;
asection *sec;
- PTR ptr;
+ PTR ptr ATTRIBUTE_UNUSED;
{
segment_info_type *seginfo = seg_info (sec);
fixS **prevP;
f = frag_more (4);
md_number_to_chars (f, insn->insn, 4);
+#ifdef OBJ_ELF
+ dwarf2_emit_insn (4);
+#endif
+
/* Apply the fixups in order */
for (i = 0; i < insn->nfixups; ++i)
{
|| tok[2].X_op != O_pregister
|| !is_ir_num(tok[2].X_add_number))
{
- as_bad (_("bad instruction format for lda !%s!%d"), r->name,
- reloc->X_add_number);
+ as_bad (_("bad instruction format for lda !%s!%ld"), r->name,
+ (long) reloc->X_add_number);
reloc = (const expressionS *)0;
ntok--;
}
}
+static void
+s_alpha_file (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ if (ECOFF_DEBUGGING)
+ ecoff_directive_file (0);
+ else
+ dwarf2_directive_file (0);
+}
+
+static void
+s_alpha_loc (ignore)
+ int ignore ATTRIBUTE_UNUSED;
+{
+ if (ECOFF_DEBUGGING)
+ ecoff_directive_loc (0);
+ else
+ dwarf2_directive_loc (0);
+}
+
static void
s_alpha_coff_wrapper (which)
int which;
ecoff_directive_def,
ecoff_directive_dim,
ecoff_directive_endef,
- ecoff_directive_file,
ecoff_directive_scl,
ecoff_directive_tag,
ecoff_directive_val,
- ecoff_directive_loc,
};
assert (which >= 0 && which < (int)(sizeof(fns)/sizeof(*fns)));
{"fmask", s_alpha_mask, 1},
{"frame", s_alpha_frame, 0},
{"prologue", s_alpha_prologue, 0},
+ {"file", s_alpha_file, 5},
+ {"loc", s_alpha_loc, 9},
/* COFF debugging related pseudos. */
{"begin", s_alpha_coff_wrapper, 0},
{"bend", s_alpha_coff_wrapper, 1},
{"def", s_alpha_coff_wrapper, 2},
{"dim", s_alpha_coff_wrapper, 3},
{"endef", s_alpha_coff_wrapper, 4},
- {"file", s_alpha_coff_wrapper, 5},
- {"scl", s_alpha_coff_wrapper, 6},
- {"tag", s_alpha_coff_wrapper, 7},
- {"val", s_alpha_coff_wrapper, 8},
- {"loc", s_alpha_coff_wrapper, 9},
+ {"scl", s_alpha_coff_wrapper, 5},
+ {"tag", s_alpha_coff_wrapper, 6},
+ {"val", s_alpha_coff_wrapper, 7},
#else
{"prologue", s_ignore, 0},
#endif
(long)fixP->tc_fix_data.next_lituse); \
} while (0)
#endif
+
+#define DWARF2_LINE_MIN_INSN_LENGTH 4
fix_new_arm (frag_now, to - frag_now->fr_literal,
inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
inst.reloc.type);
+
#ifdef OBJ_ELF
- if (debug_type == DEBUG_DWARF2)
- dwarf2_generate_asm_lineno (inst.size);
+ dwarf2_emit_insn (inst.size);
#endif
- return;
}
void
demand_empty_rest_of_line ();
}
-/* Stuff to do after assembling all of the source file. */
-
-void
-arm_end_of_source ()
-{
- if (debug_type == DEBUG_DWARF2)
- dwarf2_finish ();
-}
-
#endif /* OBJ_ELF */
#endif
#ifdef OBJ_ELF
-#define md_end() arm_end_of_source ()
- extern void arm_end_of_source PARAMS ((void));
-
#define DWARF2_LINE_MIN_INSN_LENGTH 2
#endif
the_insn.format, the_insn.arg_reloc, NULL);
#ifdef OBJ_ELF
- if (debug_type == DEBUG_DWARF2)
- dwarf2_generate_asm_lineno (4);
+ dwarf2_emit_insn (4);
#endif
}
}
}
-void
-pa_end_of_source ()
-{
- if (debug_type == DEBUG_DWARF2)
- dwarf2_finish ();
-}
-
static void
pa_vtable_entry (ignore)
int ignore ATTRIBUTE_UNUSED;
#define elf_tc_final_processing elf_hppa_final_processing
void elf_hppa_final_processing PARAMS ((void));
-#define md_end() pa_end_of_source ()
-void pa_end_of_source PARAMS ((void));
+#define DWARF2_LINE_MIN_INSN_LENGTH 4
#endif /* OBJ_ELF */
#define md_operand(x)
continue; /* try next slot */
}
- if (debug_type == DEBUG_DWARF2)
{
bfd_vma addr;
bfd_set_private_flags (stdoutput, md.flags);
- if (debug_type == DEBUG_DWARF2)
- dwarf2_finish ();
-
md.mem_offset.hint = 0;
}
CURR_SLOT.qp_regno = qp_regno;
CURR_SLOT.idesc = idesc;
as_where (&CURR_SLOT.src_file, &CURR_SLOT.src_line);
- if (debug_type == DEBUG_DWARF2)
- dwarf2_where (&CURR_SLOT.debug_line);
+ dwarf2_where (&CURR_SLOT.debug_line);
/* Add unwind entry, if there is one. */
if (unwind.current_entry)
f = frag_more (size);
- /* Emit line number information in dwarf2 debug sections. */
- if (debug_type == DEBUG_DWARF2)
- dwarf2_generate_asm_lineno (size);
+ dwarf2_emit_insn (size);
return f;
}
{
return 1;
}
-
-void
-m68hc11_end_of_source ()
-{
- segT saved_seg;
- subsegT saved_subseg;
- segT debug_info;
- char *p;
- long total_size = 0;
-
- if (debug_type != DEBUG_DWARF2)
- return;
-
- dwarf2_finish ();
-
- saved_seg = now_seg;
- saved_subseg = now_subseg;
-
- debug_info = subseg_new (".debug_info", 0);
- bfd_set_section_flags (stdoutput, debug_info, SEC_READONLY);
- subseg_set (debug_info, 0);
- p = frag_more (10);
- total_size = 12;
-
-# define STUFF(val,size) md_number_to_chars (p, val, size); p += size;
- STUFF (total_size, 4); /* Length of compilation unit. */
- STUFF (2, 2); /* Dwarf version */
- STUFF (0, 4);
- STUFF (2, 1); /* Pointer size */
- STUFF (1, 1); /* Compile unit */
- STUFF (0, 4);
-
- now_subseg = saved_subseg;
- now_seg = saved_seg;
-}
extern int m68hc11_parse_long_option PARAMS ((char *));
#define md_parse_long_option m68hc11_parse_long_option
-extern void m68hc11_end_of_source PARAMS ((void));
-#define md_end() m68hc11_end_of_source ()
-
#define DWARF2_LINE_MIN_INSN_LENGTH 1
/* We don't need to handle .word strangely. */
}
}
- if (debug_type == DEBUG_DWARF2)
- dwarf2_generate_asm_lineno (real_size);
+ dwarf2_emit_insn (real_size);
}
/* If while processing a fixup, a reloc really needs to be created
current_machine = mach;
}
-
-void
-mn10300_finalize ()
-{
- if (debug_type == DEBUG_DWARF2)
- dwarf2_finish ();
-}
extern const struct relax_type md_relax_table[];
#define TC_GENERIC_RELAX_TABLE md_relax_table
-#define md_end() mn10300_finalize ()
-void mn10300_finalize PARAMS ((void));
-
#define DWARF2_LINE_MIN_INSN_LENGTH 1
}
}
- if (debug_type == DEBUG_DWARF2)
- dwarf2_generate_asm_lineno (size);
+ dwarf2_emit_insn (size);
}
/* This routine is called each time a label definition is seen. It
}
#endif /* BFD_ASSEMBLER */
-
-void
-sh_finalize ()
-{
- if (debug_type == DEBUG_DWARF2)
- dwarf2_finish ();
-}
&& ! S_IS_COMMON ((FIX)->fx_addsy))))
#endif /* OBJ_ELF */
-
-#define md_end() sh_finalize ()
-void sh_finalize PARAMS ((void));
input_line_pointer = saved_input_line_pointer;
- if (debug_type == DEBUG_DWARF2)
- dwarf2_generate_asm_lineno (total_insn_size);
+ dwarf2_emit_insn (total_insn_size);
}
/* If while processing a fixup, a reloc really needs to be created
return 0;
}
-
-void
-v850_finalize ()
-{
- if (debug_type == DEBUG_DWARF2)
- dwarf2_finish ();
-}
#define MD_PCREL_FROM_SECTION(fixP,section) v850_pcrel_from_section (fixP, section)
extern long v850_pcrel_from_section ();
-#define md_end() v850_finalize ()
-extern void v850_finalize PARAMS ((void));
-
#define DWARF2_LINE_MIN_INSN_LENGTH 2
#ifndef DWARF2_LINE_MIN_INSN_LENGTH
/* Define the architecture-dependent minimum instruction length (in
bytes). This value should be rather too small than too big. */
-# define DWARF2_LINE_MIN_INSN_LENGTH 4
+# define DWARF2_LINE_MIN_INSN_LENGTH 1
#endif
/* Flag that indicates the initial value of the is_stmt_start flag.
static void gen_dir_list PARAMS ((void));
static void gen_file_list PARAMS ((void));
static void print_stats PARAMS ((unsigned long));
+static addressT now_subseg_size PARAMS ((void));
#define out_byte(byte) FRAG_APPEND_1_CHAR(byte)
#define out_opcode(opc) (out_byte ((opc)), ++ls.opcode_hist[(opc) & 0xff])
j = SPECIAL_LINE (i);
if (j == DWARF2_LINE_BASE)
fprintf (stderr, "\n%4u: ",
- ((unsigned int)
- DWARF2_LINE_MIN_INSN_LENGTH * SPECIAL_ADDR (i)));
+ (unsigned int) (DWARF2_LINE_MIN_INSN_LENGTH
+ * SPECIAL_ADDR (i)));
fprintf (stderr, " %2u", ls.opcode_hist[i]);
}
fprintf (stderr, "\n");
}
+/* Compute the size of the current subsegment, taking all fragments
+ into account. Note that we don't generate variant frags, so the
+ fixed portion is all we need to consider. */
+
+static addressT
+now_subseg_size ()
+{
+ struct frag *f;
+ addressT size = 0;
+
+ for (f = frchain_now->frch_root; f ; f = f->fr_next)
+ size += f->fr_fix;
+
+ return size + frag_now_fix_octets ();
+}
+
void
dwarf2_finish ()
{
if (!ls.sm.empty_sequence)
out_end_sequence ();
- total_size = body_size = frag_now_fix ();
+ subseg_set (ls.line_seg, DL_BODY);
+ total_size = body_size = now_subseg_size ();
/* Now generate the directory and file lists. */
subseg_set (ls.line_seg, DL_FILES);
gen_dir_list ();
gen_file_list ();
- total_size += frag_now_fix ();
+ total_size += now_subseg_size ();
/* And now the header ("statement program prolog", in DWARF2 lingo...). */
subseg_set (ls.line_seg, DL_PROLOG);
cp = frag_more (15 + DWARF2_LINE_OPCODE_BASE - 1);
- total_size += frag_now_fix ();
+ total_size += now_subseg_size ();
prolog_size = total_size - body_size - 10;
-# define STUFF(val,size) md_number_to_chars (cp, val, size); cp += size;
+#define STUFF(val,size) \
+ do { \
+ md_number_to_chars (cp, val, size); \
+ cp += size; \
+ } while (0)
+
STUFF (total_size - 4, 4); /* length */
STUFF (2, 2); /* version */
STUFF (prolog_size, 4); /* prologue_length */
STUFF (0, 1); /* DW_LNS_const_add_pc */
STUFF (1, 1); /* DW_LNS_fixed_advance_pc */
+#undef STUFF
+
+ /* If this is assembler generated line info, add a .debug_info
+ section as well. */
+ if (debug_type == DEBUG_DWARF2)
+ {
+ segT info_seg = subseg_new (".debug_info", 0);
+ segT abbrev_seg = subseg_new (".debug_abbrev", 0);
+ char *len;
+
+#ifdef BFD_ASSEMBLER
+ bfd_set_section_flags (stdoutput, info_seg, SEC_READONLY);
+ bfd_set_section_flags (stdoutput, abbrev_seg, SEC_READONLY);
+#endif
+
+ subseg_set (info_seg, 0);
+ len = frag_more (4);
+
+#define STUFF(val, size) \
+ do { \
+ cp = frag_more (size); \
+ md_number_to_chars (cp, (val), (size)); \
+ } while(0)
+
+ STUFF (2, 2); /* Dwarf version */
+ STUFF (0, 4); /* Offset into (final!) .debug_abbrev. */
+
+ /* Pointer size. */
+#ifdef BFD_ASSEMBLER
+ STUFF (bfd_arch_bits_per_address (stdoutput) / 8, 1);
+#else
+ STUFF (4, 1);
+#endif
+
+ /* FIXME: Add a DW_TAG_compile_unit DIE. The line info cannot
+ even be seen without it. */
+
+ /* Set size of debug_info. */
+ md_number_to_chars (len, now_subseg_size () - 4, 4);
+ }
+
subseg_set (saved_seg, saved_subseg);
if (flag_debug)
ls.any_dwarf2_directives = 1;
- if (debug_type == DEBUG_NONE)
- /* Automatically turn on DWARF2 debug info unless something else
- has been selected. */
- debug_type = DEBUG_DWARF2;
-
ls.current.filenum = get_absolute_expression ();
ls.current.filename = demand_copy_C_string (&len);
dwarf2_where (line)
struct dwarf2_line_info *line;
{
- if (ls.any_dwarf2_directives)
- *line = ls.current;
- else
+ if (debug_type == DEBUG_DWARF2)
{
as_where (&line->filename, &line->line);
line->filenum = 0;
line->column = 0;
line->flags = DWARF2_FLAG_BEGIN_STMT;
}
+ else
+ *line = ls.current;
}
-/* Generate a DWARF2 line statement for an
- instruction of SIZE bytes in length. */
+/* Called for each machine instruction, or relatively atomic group of
+ machine instructions (ie built-in macro). The instruction or group
+ is SIZE bytes in length. If dwarf2 line number generation is called
+ for, emit a line statement appropriately. */
void
-dwarf2_generate_asm_lineno (size)
+dwarf2_emit_insn (size)
int size;
{
addressT addr;
- static struct dwarf2_line_info debug_line;
+ struct dwarf2_line_info debug_line;
+
+ if (debug_type != DEBUG_DWARF2 && ! ls.any_dwarf2_directives)
+ return;
+ /* Reset any_dwarf2_directives so that we won't waste time
+ determining that no information has changed between insns. */
+ ls.any_dwarf2_directives = 0;
+
/* First update the notion of the current source line. */
dwarf2_where (&debug_line);
/* We want the offset of the start of this
instruction within the the current frag. */
- addr = frag_now->fr_address + frag_now_fix () - size;
+ addr = frag_now_fix () - size;
/* And record the information. */
dwarf2_gen_line_info (addr, &debug_line);
.debug_line section. */
extern void dwarf2_finish PARAMS ((void));
-extern void dwarf2_generate_asm_lineno PARAMS ((int));
+extern void dwarf2_emit_insn PARAMS ((int));
#endif /* AS_DWARF2DBG_H */
this if we see a .file directive with a string, since that
implies that some sort of debugging information is being
provided. */
- if (! symbol_table_frozen && debug_type == DEBUG_NONE)
+ if (! symbol_table_frozen && debug_type == DEBUG_UNSPECIFIED)
debug_type = DEBUG_ECOFF;
}
+ else
+ debug_type = DEBUG_NONE;
#ifndef NO_LISTING
if (listing)
/* This is a hand coded assembler file, so automatically turn on
debugging information. */
- if (debug_type == DEBUG_NONE)
+ if (debug_type == DEBUG_UNSPECIFIED)
debug_type = DEBUG_ECOFF;
}
\f
void
generate_lineno_debug ()
{
-#ifdef ECOFF_DEBUGGING
- /* ECOFF assemblers automatically generate debugging information.
- FIXME: This should probably be handled elsewhere. */
- if (debug_type == DEBUG_UNSPECIFIED)
- {
- if (ECOFF_DEBUGGING && ecoff_no_current_file ())
- debug_type = DEBUG_ECOFF;
- else
- debug_type = DEBUG_NONE;
- }
-#endif
-
switch (debug_type)
{
case DEBUG_UNSPECIFIED:
case DEBUG_NONE:
+ case DEBUG_DWARF:
break;
case DEBUG_STABS:
stabs_generate_asm_lineno ();
case DEBUG_ECOFF:
ecoff_generate_asm_lineno ();
break;
- case DEBUG_DWARF:
case DEBUG_DWARF2:
- /* This cannot safely be done in a generic manner. A single
- binary instruction word may span mutliple lines of assembler
- source and may occupy a variable number of bytes. Instead,
- if a port wishes to support DWARF2 line number generation by
- the assembler, it should add a call to dwarf2_generate_asm_lineno
- inside md_assemble() at whatever point is appropriate. Note,
- such a port should also define md_end and make sure that
- dwarf2_finish is called, to emit the accumulated line information. */
+ /* ??? We could here indicate to dwarf2dbg.c that something
+ has changed. However, since there is additional backend
+ support that is required (calling dwarf2_emit_insn), we
+ let dwarf2dbg.c call as_where on its own. */
break;
}
}