/* Output Dwarf2 format symbol table information from GCC.
Copyright (C) 1992, 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
Contributed by Gary Funck (gary@intrepid.com).
Derived from DWARF 1 implementation of Ron Guilmette (rfg@monkeys.com).
Extensively modified by Jason Merrill (jason@cygnus.com).
static GTY(()) int dw2_string_counter;
static GTY(()) unsigned long dwarf2out_cfi_label_num;
+/* True if the compilation unit places functions in more than one section. */
+static GTY(()) bool have_multiple_function_sections = false;
+
+/* Whether the default text and cold text sections have been used at all. */
+
+static GTY(()) bool text_section_used = false;
+static GTY(()) bool cold_text_section_used = false;
+
+/* The default cold text section. */
+static GTY(()) section *cold_text_section;
+
#if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO)
/* Forward declarations for functions defined in this file. */
static HOST_WIDE_INT stack_adjust_offset (const_rtx);
static void output_cfi (dw_cfi_ref, dw_fde_ref, int);
static void output_call_frame_info (int);
+static void dwarf2out_note_section_used (void);
static void dwarf2out_stack_adjust (rtx, bool);
static void flush_queued_reg_saves (void);
static bool clobbers_queued_reg_save (const_rtx);
static void
dwarf2out_frame_debug_expr (rtx expr, const char *label)
{
- rtx src, dest;
+ rtx src, dest, span;
HOST_WIDE_INT offset;
/* If RTX_FRAME_RELATED_P is set on a PARALLEL, process each member of
}
def_cfa_1 (label, &cfa);
- queue_reg_save (label, src, NULL_RTX, offset);
+ {
+ span = targetm.dwarf_register_span (src);
+
+ if (!span)
+ queue_reg_save (label, src, NULL_RTX, offset);
+ else
+ {
+ /* We have a PARALLEL describing where the contents of SRC
+ live. Queue register saves for each piece of the
+ PARALLEL. */
+ int par_index;
+ int limit;
+ HOST_WIDE_INT span_offset = offset;
+
+ gcc_assert (GET_CODE (span) == PARALLEL);
+
+ limit = XVECLEN (span, 0);
+ for (par_index = 0; par_index < limit; par_index++)
+ {
+ rtx elem = XVECEXP (span, 0, par_index);
+
+ queue_reg_save (label, elem, NULL_RTX, span_offset);
+ span_offset += GET_MODE_SIZE (GET_MODE (elem));
+ }
+ }
+ }
break;
default:
if (for_eh)
{
- rtx sym_ref = gen_rtx_SYMBOL_REF (Pmode, fde->dw_fde_begin);
- SYMBOL_REF_FLAGS (sym_ref) |= SYMBOL_FLAG_LOCAL;
- dw2_asm_output_encoded_addr_rtx (fde_encoding,
- sym_ref,
- false,
- "FDE initial location");
if (fde->dw_fde_switched_sections)
{
rtx sym_ref2 = gen_rtx_SYMBOL_REF (Pmode,
"FDE address range");
}
else
- dw2_asm_output_delta (size_of_encoded_value (fde_encoding),
- fde->dw_fde_end, fde->dw_fde_begin,
- "FDE address range");
+ {
+ rtx sym_ref = gen_rtx_SYMBOL_REF (Pmode, fde->dw_fde_begin);
+ SYMBOL_REF_FLAGS (sym_ref) |= SYMBOL_FLAG_LOCAL;
+ dw2_asm_output_encoded_addr_rtx (fde_encoding,
+ sym_ref,
+ false,
+ "FDE initial location");
+ dw2_asm_output_delta (size_of_encoded_value (fde_encoding),
+ fde->dw_fde_end, fde->dw_fde_begin,
+ "FDE address range");
+ }
}
else
{
- dw2_asm_output_addr (DWARF2_ADDR_SIZE, fde->dw_fde_begin,
- "FDE initial location");
if (fde->dw_fde_switched_sections)
{
dw2_asm_output_addr (DWARF2_ADDR_SIZE,
"FDE address range");
}
else
- dw2_asm_output_delta (DWARF2_ADDR_SIZE,
- fde->dw_fde_end, fde->dw_fde_begin,
- "FDE address range");
+ {
+ dw2_asm_output_addr (DWARF2_ADDR_SIZE, fde->dw_fde_begin,
+ "FDE initial location");
+ dw2_asm_output_delta (DWARF2_ADDR_SIZE,
+ fde->dw_fde_end, fde->dw_fde_begin,
+ "FDE address range");
+ }
}
if (augmentation[0])
output_call_frame_info (1);
#endif
}
+
+/* Note that the current function section is being used for code. */
+
+static void
+dwarf2out_note_section_used (void)
+{
+ section *sec = current_function_section ();
+ if (sec == text_section)
+ text_section_used = true;
+ else if (sec == cold_text_section)
+ cold_text_section_used = true;
+}
+
+void
+dwarf2out_switch_text_section (void)
+{
+ dw_fde_ref fde;
+
+ gcc_assert (cfun);
+
+ fde = &fde_table[fde_table_in_use - 1];
+ fde->dw_fde_switched_sections = true;
+ fde->dw_fde_hot_section_label = cfun->hot_section_label;
+ fde->dw_fde_hot_section_end_label = cfun->hot_section_end_label;
+ fde->dw_fde_unlikely_section_label = cfun->cold_section_label;
+ fde->dw_fde_unlikely_section_end_label = cfun->cold_section_end_label;
+ have_multiple_function_sections = true;
+
+ /* Reset the current label on switching text sections, so that we
+ don't attempt to advance_loc4 between labels in different sections. */
+ fde->dw_fde_current_label = NULL;
+
+ /* There is no need to mark used sections when not debugging. */
+ if (cold_text_section != NULL)
+ dwarf2out_note_section_used ();
+}
#endif
\f
/* And now, the subset of the debugging information support code necessary
/* Number of elements in line_info_table currently in use. */
static GTY(()) unsigned line_info_table_in_use;
-/* True if the compilation unit places functions in more than one section. */
-static GTY(()) bool have_multiple_function_sections = false;
-
/* A pointer to the base of a table that contains line information
for each source code line outside of .text in the compilation unit. */
static GTY ((length ("separate_line_info_table_allocated")))
/* Cached result of previous call to lookup_filename. */
static GTY(()) struct dwarf_file_data * file_table_last_lookup;
-/* Whether the default text and cold text sections have been used at
- all. */
-
-static GTY(()) bool text_section_used = false;
-static GTY(()) bool cold_text_section_used = false;
-
-/* The default cold text section. */
-static GTY(()) section *cold_text_section;
-
#ifdef DWARF2_DEBUGGING_INFO
/* Offset from the "steady-state frame pointer" to the frame base,
/* Section flags for .debug_str section. */
#define DEBUG_STR_SECTION_FLAGS \
- (HAVE_GAS_SHF_MERGE && flag_merge_constants \
+ (HAVE_GAS_SHF_MERGE && flag_merge_debug_strings \
? SECTION_DEBUG | SECTION_MERGE | SECTION_STRINGS | 1 \
: SECTION_DEBUG)
*d = new_loc_list (descr, begin, end, section, 0);
}
-/* Note that the current function section is being used for code. */
-
-static void
-dwarf2out_note_section_used (void)
-{
- section *sec = current_function_section ();
- if (sec == text_section)
- text_section_used = true;
- else if (sec == cold_text_section)
- cold_text_section_used = true;
-}
-
-void
-dwarf2out_switch_text_section (void)
-{
- dw_fde_ref fde;
-
- gcc_assert (cfun);
-
- fde = &fde_table[fde_table_in_use - 1];
- fde->dw_fde_switched_sections = true;
- fde->dw_fde_hot_section_label = cfun->hot_section_label;
- fde->dw_fde_hot_section_end_label = cfun->hot_section_end_label;
- fde->dw_fde_unlikely_section_label = cfun->cold_section_label;
- fde->dw_fde_unlikely_section_end_label = cfun->cold_section_end_label;
- have_multiple_function_sections = true;
-
- /* Reset the current label on switching text sections, so that we
- don't attempt to advance_loc4 between labels in different sections. */
- fde->dw_fde_current_label = NULL;
-
- dwarf2out_note_section_used ();
-}
-
/* Output the location list given to us. */
static void
else
context_die = comp_unit_die;
- type_die = lookup_type_die (type);
- if (type_die)
- return type_die;
- gen_type_die (type, context_die);
- type_die = lookup_type_die (type);
+ type_die = modified_type_die (type, TYPE_READONLY (type),
+ TYPE_VOLATILE (type), context_die);
gcc_assert (type_die);
}
return type_die;