This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Dwarf2out end prologue/begin epilogue for IVMS (2nd try)
The rewrite started to get very ugly, so I took a step back and added a
flag arg to ASM_OUTPUT_DWARF_DELTA instead.
What do you think?
--Douglas Rupp
AdaCore
2009-09-09 Douglas B Rupp <rupp@gnat.com>
* config/darwin.h (ASM_OUTPUT_DWARF_DELTA): Add FLAG arg.
* config/ia64/ia64.c: #include <dwarf2asm.h>
(ia64_vms_asm_output_dwarf_delta): New function.
* config/ia64/ia64-protos.h (ia64_vms_asm_output_dwarf_delta): New
prototype.
* config/ia64/vms.h (ASM_OUTPUT_DWARF_DELTA_UNITS): Remove
(ASM_OUTPUT_DWARF_DELTA): Define.
* dbxout.c (gcc_debug_hooks): New entry begin_epilogue.
* debug.c: Likewise.
* sdbout.c: Likewise.
* vmsdbgout.c: Likewise.
* debug.h: Likewise.
(dwarf2out_vms_end_prologue), (dwarf2out_vms_begin_epilogue): Declare.
* doc/tm.texi (ASM_OUTPUT_DWARF_DELTA): Document new flag arg.
* dwarf2asm.c (dw2_asm_output_delta): Add new flag arg.
* dwarf2asm.h (dw2_asm_output_delta): Likewise
* dwarf2out.c (ASM_OUTPUT_DWARF_DELTA): Add FLAG arg everywhere called.
(dw_asm_output_delta): Add new flag arg everyhwere called.
(dw_fde_struct): New fields dw_fde_vms_end_prologue, ...begin_epilogue.
(PROLOGUE_END_LABEL, EPILOGUE_BEGIN_LABEL): New macros.
(dwarf2out_begin_prologue): Set dw_fde_struct defaults for above.
(dwarf2out_vms_end_prologue): New function.
(dwarf2out_vms_begin_epilogue): New function.
(dw_val_struct): New value dw_val_class_delta.
(gcc_debug_hooks): New entry begin_epilogue. Set end_prologue,
begin_epilogue for VMS.
(AT_delta1, AT_delta2, AT_delta_flag, add_AT_delta_flag): Declare
new static functions.
(dwarf_attr_name): New cases DW_AT_HP_{prologue,epilogue}.
(print_die): New case dw_val_class_delta.
(attr_checksum): Likewise.
(same_dw_val_p: Likewise.
(size_of_die): Likewise.
(value_format): Likewise.
(output_die): Likewise.
(gen_subprogram_die): Call add_AT_delta_flag on VMS.
* dwarf2out.c (dwarf2out_begin_epilogue): Rename to
dwarf2out_cfi_begin_epilogue
* dwarf2out.h (dwarf2out_begin_epilogue): Rename to
dwarf2out_cfi_begin_epilogue
* except.c (dw_asm_output_delta): Add new flag arg everyhwere called.
* final.c (final_scan_insn): Likewise. Call begin_epilogue.
* include/dwarf2.h (dwarf_attribute): New values DW_AT_HP_
{prologue,epilogue}).
diff -rup gcc-head-src/gcc/config/darwin.h gcc-head-src-10.1/gcc/config/darwin.h
--- gcc/config/darwin.h 2009-06-11 12:57:04.000000000 -0700
+++ gcc/config/darwin.h 2009-09-09 11:51:48.000000000 -0700
@@ -900,7 +900,7 @@ enum machopic_addr_class {
? (DW_EH_PE_pcrel | DW_EH_PE_indirect | DW_EH_PE_sdata4) : \
((CODE) == 1 || (GLOBAL) == 0) ? DW_EH_PE_pcrel : DW_EH_PE_absptr)
-#define ASM_OUTPUT_DWARF_DELTA(FILE,SIZE,LABEL1,LABEL2) \
+#define ASM_OUTPUT_DWARF_DELTA(FILE,SIZE,LABEL1,LABEL2,FLAG) \
darwin_asm_output_dwarf_delta (FILE, SIZE, LABEL1, LABEL2)
#define ASM_OUTPUT_DWARF_OFFSET(FILE,SIZE,LABEL,BASE) \
diff -rup gcc-head-src/gcc/config/ia64/ia64.c gcc-head-src-10.1/gcc/config/ia64/ia64.c
--- gcc/config/ia64/ia64.c 2009-09-01 19:42:21.000000000 -0700
+++ gcc/config/ia64/ia64.c 2009-09-09 12:58:30.000000000 -0700
@@ -60,6 +60,7 @@ along with GCC; see the file COPYING3.
#include "dbgcnt.h"
#include "tm-constrs.h"
#include "sel-sched.h"
+#include "dwarf2asm.h"
/* This is used for communication between ASM_OUTPUT_LABEL and
ASM_OUTPUT_LABELREF. */
@@ -4706,6 +4707,25 @@ ia64_output_dwarf_dtprel (FILE *file, in
fputs (")", file);
}
+void
+ia64_vms_asm_output_dwarf_delta (FILE *file, int size, const char *lab1,
+ const char *lab2, const int flag)
+{
+ if (flag)
+ {
+ fprintf (file, "\tdata4.ua\t (");
+ assemble_name (file, lab1);
+ fprintf (file, "-");
+ assemble_name (file, lab2);
+ fprintf (file, ")/16*3");
+ }
+ else
+ dw2_assemble_integer (size,
+ gen_rtx_MINUS (Pmode,
+ gen_rtx_SYMBOL_REF (Pmode, lab1),
+ gen_rtx_SYMBOL_REF (Pmode, lab2)));
+}
+
/* Print a memory address as an operand to reference that memory location. */
/* ??? Do we need this? It gets used only for 'a' operands. We could perhaps
diff -rup gcc-head-src/gcc/config/ia64/ia64-protos.h gcc-head-src-10.1/gcc/config/ia64/ia64-protos.h
--- gcc/config/ia64/ia64-protos.h 2009-08-27 13:08:49.000000000 -0700
+++ gcc/config/ia64/ia64-protos.h 2009-09-09 11:56:21.000000000 -0700
@@ -101,6 +101,8 @@ extern enum direction ia64_hpux_function
#endif /* ARGS_SIZE_RTX */
extern void ia64_hpux_handle_builtin_pragma (struct cpp_reader *);
+extern void ia64_vms_asm_output_dwarf_delta (FILE *, int, const char *,
+ const char *, const int);
extern void ia64_output_function_profiler (FILE *, int);
extern void ia64_profile_hook (int);
diff -rup gcc-head-src/gcc/config/ia64/vms.h gcc-head-src-10.1/gcc/config/ia64/vms.h
--- gcc/config/ia64/vms.h 2009-08-21 19:50:30.000000000 -0700
+++ gcc/config/ia64/vms.h 2009-09-09 12:10:16.000000000 -0700
@@ -72,14 +72,8 @@ along with GCC; see the file COPYING3.
/* Turn on VMS specific Dwarf2 features. */
#define VMS_DEBUGGING_INFO 1
-#define ASM_OUTPUT_DWARF_DELTA_UNITS(FILE,SIZE,LABEL1,LABEL2,UNITS) \
-do { \
- fprintf (FILE, "\tdata4.ua\t ("); \
- assemble_name (FILE, LABEL1); \
- fprintf (FILE, "-"); \
- assemble_name (FILE, LABEL2); \
- fprintf (FILE, ")/16*3"); \
-} while (0)
+#define ASM_OUTPUT_DWARF_DELTA(FILE,SIZE,LABEL1,LABEL2,FLAG) \
+ ia64_vms_asm_output_dwarf_delta (FILE, SIZE, LABEL1, LABEL2, FLAG)
#undef STARTFILE_SPEC
#define STARTFILE_SPEC \
diff -rup gcc-head-src/gcc/dbxout.c gcc-head-src-10.1/gcc/dbxout.c
--- gcc/dbxout.c 2009-07-07 13:46:06.000000000 -0700
+++ gcc/dbxout.c 2009-09-08 22:02:42.000000000 -0700
@@ -356,6 +356,7 @@ const struct gcc_debug_hooks dbx_debug_h
dbxout_source_line, /* source_line */
dbxout_begin_prologue, /* begin_prologue */
debug_nothing_int_charstar, /* end_prologue */
+ debug_nothing_int_charstar, /* begin_epilogue */
debug_nothing_int_charstar, /* end_epilogue */
#ifdef DBX_FUNCTION_FIRST
dbxout_begin_function,
@@ -393,6 +394,7 @@ const struct gcc_debug_hooks xcoff_debug
xcoffout_source_line,
xcoffout_begin_prologue, /* begin_prologue */
debug_nothing_int_charstar, /* end_prologue */
+ debug_nothing_int_charstar, /* begin_epilogue */
xcoffout_end_epilogue,
debug_nothing_tree, /* begin_function */
xcoffout_end_function,
diff -rup gcc-head-src/gcc/debug.c gcc-head-src-10.1/gcc/debug.c
--- gcc/debug.c 2009-06-17 16:54:40.000000000 -0700
+++ gcc/debug.c 2009-09-08 22:02:42.000000000 -0700
@@ -37,6 +37,7 @@ const struct gcc_debug_hooks do_nothing_
debug_nothing_int_charstar_int_bool, /* source_line */
debug_nothing_int_charstar, /* begin_prologue */
debug_nothing_int_charstar, /* end_prologue */
+ debug_nothing_int_charstar, /* begin_epilogue */
debug_nothing_int_charstar, /* end_epilogue */
debug_nothing_tree, /* begin_function */
debug_nothing_int, /* end_function */
diff -rup gcc-head-src/gcc/debug.h gcc-head-src-10.1/gcc/debug.h
--- gcc/debug.h 2009-06-17 16:54:40.000000000 -0700
+++ gcc/debug.h 2009-09-08 22:06:15.000000000 -0700
@@ -71,6 +71,9 @@ struct gcc_debug_hooks
function. */
void (* end_prologue) (unsigned int line, const char *file);
+ /* Called at beginning of epilogue code. */
+ void (* begin_epilogue) (unsigned int line, const char *file);
+
/* Record end of epilogue code. */
void (* end_epilogue) (unsigned int line, const char *file);
@@ -163,6 +166,8 @@ extern const struct gcc_debug_hooks vmsd
/* Dwarf2 frame information. */
extern void dwarf2out_begin_prologue (unsigned int, const char *);
+extern void dwarf2out_vms_end_prologue (unsigned int, const char *);
+extern void dwarf2out_vms_begin_epilogue (unsigned int, const char *);
extern void dwarf2out_end_epilogue (unsigned int, const char *);
extern void dwarf2out_frame_init (void);
extern void dwarf2out_frame_finish (void);
diff -rup gcc-head-src/gcc/doc/tm.texi gcc-head-src-10.1/gcc/doc/tm.texi
--- gcc/doc/tm.texi 2009-08-28 02:04:52.000000000 -0700
+++ gcc/doc/tm.texi 2009-09-09 14:02:08.346301178 -0700
@@ -9143,9 +9143,10 @@ line debug info sections. This will res
tables, and hence is desirable if it works.
@end defmac
-@defmac ASM_OUTPUT_DWARF_DELTA (@var{stream}, @var{size}, @var{label1}, @var{label2})
+@defmac ASM_OUTPUT_DWARF_DELTA (@var{stream}, @var{size}, @var{label1}, @var{label2}, @var{flag})
A C statement to issue assembly directives that create a difference
-@var{lab1} minus @var{lab2}, using an integer of the given @var{size}.
+@var{lab1} minus @var{lab2}, using an integer of the given @var{size}. If
+@var{flag} is set then modify the integer in a system dependent manner.
@end defmac
@defmac ASM_OUTPUT_DWARF_OFFSET (@var{stream}, @var{size}, @var{label}, @var{section})
diff -rup gcc-head-src/gcc/dwarf2asm.c gcc-head-src-10.1/gcc/dwarf2asm.c
--- gcc/dwarf2asm.c 2009-07-09 12:41:25.000000000 -0700
+++ gcc/dwarf2asm.c 2009-09-09 11:29:43.000000000 -0700
@@ -128,6 +128,7 @@ dw2_asm_output_data (int size, unsigned
void
dw2_asm_output_delta (int size, const char *lab1, const char *lab2,
+ const int flag ATTRIBUTE_UNUSED,
const char *comment, ...)
{
va_list ap;
@@ -135,7 +136,7 @@ dw2_asm_output_delta (int size, const ch
va_start (ap, comment);
#ifdef ASM_OUTPUT_DWARF_DELTA
- ASM_OUTPUT_DWARF_DELTA (asm_out_file, size, lab1, lab2);
+ ASM_OUTPUT_DWARF_DELTA (asm_out_file, size, lab1, lab2, flag);
#else
dw2_assemble_integer (size,
gen_rtx_MINUS (Pmode,
diff -rup gcc-head-src/gcc/dwarf2asm.h gcc-head-src-10.1/gcc/dwarf2asm.h
--- gcc/dwarf2asm.h 2009-02-20 07:20:38.000000000 -0800
+++ gcc/dwarf2asm.h 2009-09-09 11:29:51.000000000 -0700
@@ -27,8 +27,8 @@ extern void dw2_asm_output_data (int, un
ATTRIBUTE_NULL_PRINTF_3;
extern void dw2_asm_output_delta (int, const char *, const char *,
- const char *, ...)
- ATTRIBUTE_NULL_PRINTF_4;
+ const int, const char *, ...)
+ ATTRIBUTE_NULL_PRINTF_5;
extern void dw2_asm_output_offset (int, const char *, section *,
const char *, ...)
diff -rup gcc-head-src/gcc/dwarf2out.c gcc-head-src-10.1/gcc/dwarf2out.c
--- gcc/dwarf2out.c 2009-09-03 09:33:27.000000000 -0700
+++ gcc/dwarf2out.c 2009-09-09 12:11:10.000000000 -0700
@@ -280,6 +280,8 @@ typedef struct GTY(()) dw_fde_struct {
const char *dw_fde_begin;
const char *dw_fde_current_label;
const char *dw_fde_end;
+ const char *dw_fde_vms_end_prologue;
+ const char *dw_fde_vms_begin_epilogue;
const char *dw_fde_hot_section_label;
const char *dw_fde_hot_section_end_label;
const char *dw_fde_unlikely_section_label;
@@ -484,6 +486,14 @@ static void def_cfa_1 (const char *, dw_
#define FUNC_END_LABEL "LFE"
#endif
+#ifndef PROLOGUE_END_LABEL
+#define PROLOGUE_END_LABEL "LPE"
+#endif
+
+#ifndef EPILOGUE_BEGIN_LABEL
+#define EPILOGUE_BEGIN_LABEL "LEB"
+#endif
+
#ifndef FRAME_BEGIN_LABEL
#define FRAME_BEGIN_LABEL "Lframe"
#endif
@@ -2770,7 +2780,7 @@ dwarf2out_frame_debug (rtx insn, bool af
NOTE_INSN_CFA_RESTORE_STATE at the appropriate place in the stream. */
void
-dwarf2out_begin_epilogue (rtx insn)
+dwarf2out_cfi_begin_epilogue (rtx insn)
{
bool saw_frp = false;
rtx i;
@@ -2843,7 +2853,8 @@ dwarf2out_begin_epilogue (rtx insn)
cfa_remember.in_use = 1;
}
-/* A "subroutine" of dwarf2out_begin_epilogue. Emit the restore required. */
+/* A "subroutine" of dwarf2out_cfi_begin_epilogue. Emit the restore
+ required. */
void
dwarf2out_frame_debug_restore_state (void)
@@ -3062,25 +3073,25 @@ output_cfi (dw_cfi_ref cfi, dw_fde_ref f
case DW_CFA_advance_loc1:
dw2_asm_output_delta (1, cfi->dw_cfi_oprnd1.dw_cfi_addr,
- fde->dw_fde_current_label, NULL);
+ fde->dw_fde_current_label, 0, NULL);
fde->dw_fde_current_label = cfi->dw_cfi_oprnd1.dw_cfi_addr;
break;
case DW_CFA_advance_loc2:
dw2_asm_output_delta (2, cfi->dw_cfi_oprnd1.dw_cfi_addr,
- fde->dw_fde_current_label, NULL);
+ fde->dw_fde_current_label, 0, NULL);
fde->dw_fde_current_label = cfi->dw_cfi_oprnd1.dw_cfi_addr;
break;
case DW_CFA_advance_loc4:
dw2_asm_output_delta (4, cfi->dw_cfi_oprnd1.dw_cfi_addr,
- fde->dw_fde_current_label, NULL);
+ fde->dw_fde_current_label, 0, NULL);
fde->dw_fde_current_label = cfi->dw_cfi_oprnd1.dw_cfi_addr;
break;
case DW_CFA_MIPS_advance_loc8:
dw2_asm_output_delta (8, cfi->dw_cfi_oprnd1.dw_cfi_addr,
- fde->dw_fde_current_label, NULL);
+ fde->dw_fde_current_label, 0, NULL);
fde->dw_fde_current_label = cfi->dw_cfi_oprnd1.dw_cfi_addr;
break;
@@ -3439,12 +3450,12 @@ output_fde (dw_fde_ref fde, bool for_eh,
if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4 && !for_eh)
dw2_asm_output_data (4, 0xffffffff, "Initial length escape value"
" indicating 64-bit DWARF extension");
- dw2_asm_output_delta (for_eh ? 4 : DWARF_OFFSET_SIZE, l2, l1,
+ dw2_asm_output_delta (for_eh ? 4 : DWARF_OFFSET_SIZE, l2, l1, 0,
"FDE Length");
ASM_OUTPUT_LABEL (asm_out_file, l1);
if (for_eh)
- dw2_asm_output_delta (4, l1, section_start_label, "FDE CIE offset");
+ dw2_asm_output_delta (4, l1, section_start_label, 0, "FDE CIE offset");
else
dw2_asm_output_offset (DWARF_OFFSET_SIZE, section_start_label,
debug_frame_section, "FDE CIE offset");
@@ -3479,12 +3490,12 @@ output_fde (dw_fde_ref fde, bool for_eh,
dw2_asm_output_encoded_addr_rtx (fde_encoding, sym_ref, false,
"FDE initial location");
dw2_asm_output_delta (size_of_encoded_value (fde_encoding),
- end, begin, "FDE address range");
+ end, begin, 0, "FDE address range");
}
else
{
dw2_asm_output_addr (DWARF2_ADDR_SIZE, begin, "FDE initial location");
- dw2_asm_output_delta (DWARF2_ADDR_SIZE, end, begin, "FDE address range");
+ dw2_asm_output_delta (DWARF2_ADDR_SIZE, end, begin, 0, "FDE address range");
}
if (augmentation[0])
@@ -3663,7 +3674,7 @@ output_call_frame_info (int for_eh)
if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4 && !for_eh)
dw2_asm_output_data (4, 0xffffffff,
"Initial length escape value indicating 64-bit DWARF extension");
- dw2_asm_output_delta (for_eh ? 4 : DWARF_OFFSET_SIZE, l2, l1,
+ dw2_asm_output_delta (for_eh ? 4 : DWARF_OFFSET_SIZE, l2, l1, 0,
"Length of Common Information Entry");
ASM_OUTPUT_LABEL (asm_out_file, l1);
@@ -3928,6 +3939,8 @@ dwarf2out_begin_prologue (unsigned int l
fde->dw_fde_switched_sections = 0;
fde->dw_fde_switched_cold_to_hot = 0;
fde->dw_fde_end = NULL;
+ fde->dw_fde_vms_end_prologue = NULL;
+ fde->dw_fde_vms_begin_epilogue = NULL;
fde->dw_fde_cfi = NULL;
fde->dw_fde_switch_cfi = NULL;
fde->funcdef_number = current_function_funcdef_no;
@@ -3971,6 +3984,51 @@ dwarf2out_begin_prologue (unsigned int l
dwarf2out_do_cfi_startproc (false);
}
+/* Output a marker (i.e. a label) for the end of the generated code
+ for a function prologue. This gets called *after* the prologue code has
+ been generated. */
+
+void
+dwarf2out_vms_end_prologue (unsigned int line ATTRIBUTE_UNUSED,
+ const char *file ATTRIBUTE_UNUSED)
+{
+ dw_fde_ref fde;
+ char label[MAX_ARTIFICIAL_LABEL_BYTES];
+
+ /* Output a label to mark the endpoint of the code generated for this
+ function. */
+ ASM_GENERATE_INTERNAL_LABEL (label, PROLOGUE_END_LABEL,
+ current_function_funcdef_no);
+ ASM_OUTPUT_DEBUG_LABEL (asm_out_file, PROLOGUE_END_LABEL,
+ current_function_funcdef_no);
+ fde = &fde_table[fde_table_in_use - 1];
+ fde->dw_fde_vms_end_prologue = xstrdup (label);
+}
+
+/* Output a marker (i.e. a label) for the beginning of the generated code
+ for a function epilogue. This gets called *before* the prologue code has
+ been generated. */
+
+void
+dwarf2out_vms_begin_epilogue (unsigned int line ATTRIBUTE_UNUSED,
+ const char *file ATTRIBUTE_UNUSED)
+{
+ dw_fde_ref fde;
+ char label[MAX_ARTIFICIAL_LABEL_BYTES];
+
+ fde = &fde_table[fde_table_in_use - 1];
+ if (fde->dw_fde_vms_begin_epilogue)
+ return;
+
+ /* Output a label to mark the endpoint of the code generated for this
+ function. */
+ ASM_GENERATE_INTERNAL_LABEL (label, EPILOGUE_BEGIN_LABEL,
+ current_function_funcdef_no);
+ ASM_OUTPUT_DEBUG_LABEL (asm_out_file, EPILOGUE_BEGIN_LABEL,
+ current_function_funcdef_no);
+ fde->dw_fde_vms_begin_epilogue = xstrdup (label);
+}
+
/* Output a marker (i.e. a label) for the absolute end of the generated code
for a function definition. This gets called *after* the epilogue code has
been generated. */
@@ -4143,7 +4201,8 @@ enum dw_val_class
dw_val_class_lineptr,
dw_val_class_str,
dw_val_class_macptr,
- dw_val_class_file
+ dw_val_class_file,
+ dw_val_class_delta
};
/* Describe a floating point constant value, or a vector constant value. */
@@ -4180,6 +4239,12 @@ typedef struct GTY(()) dw_val_struct {
char * GTY ((tag ("dw_val_class_lbl_id"))) val_lbl_id;
unsigned char GTY ((tag ("dw_val_class_flag"))) val_flag;
struct dwarf_file_data * GTY ((tag ("dw_val_class_file"))) val_file;
+ struct dw_val_delta_union
+ {
+ char * lbl1;
+ char * lbl2;
+ int flag;
+ } GTY ((tag ("dw_val_class_delta"))) val_delta;
}
GTY ((desc ("%1.val_class"))) v;
}
@@ -5374,7 +5439,13 @@ const struct gcc_debug_hooks dwarf2_debu
dwarf2out_ignore_block,
dwarf2out_source_line,
dwarf2out_begin_prologue,
- debug_nothing_int_charstar, /* end_prologue */
+#if VMS_DEBUGGING_INFO
+ dwarf2out_vms_end_prologue,
+ dwarf2out_vms_begin_epilogue,
+#else
+ debug_nothing_int_charstar,
+ debug_nothing_int_charstar,
+#endif
dwarf2out_end_epilogue,
dwarf2out_begin_function,
debug_nothing_int, /* end_function */
@@ -6019,6 +6090,11 @@ static void prune_unused_types (void);
static int maybe_emit_file (struct dwarf_file_data *fd);
static void append_entry_to_tmpl_value_parm_die_table (dw_die_ref, tree);
static void gen_remaining_tmpl_value_param_die_attribute (void);
+static inline const char *AT_delta1 (dw_attr_ref);
+static inline const char *AT_delta2 (dw_attr_ref);
+static inline int AT_delta_flag (dw_attr_ref);
+static inline void add_AT_delta_flag (dw_die_ref, enum dwarf_attribute,
+ const char *, const char *, const int);
/* Section names used to hold DWARF debugging information. */
#ifndef DEBUG_INFO_SECTION
@@ -6489,14 +6565,24 @@ dwarf_attr_name (unsigned int attr)
return "DW_AT_MIPS_tail_loop_begin";
case DW_AT_MIPS_epilog_begin:
return "DW_AT_MIPS_epilog_begin";
+#if VMS_DEBUGGING_INFO
+ case DW_AT_HP_prologue:
+ return "DW_AT_HP_prologue";
+#else
case DW_AT_MIPS_loop_unroll_factor:
return "DW_AT_MIPS_loop_unroll_factor";
+#endif
case DW_AT_MIPS_software_pipeline_depth:
return "DW_AT_MIPS_software_pipeline_depth";
case DW_AT_MIPS_linkage_name:
return "DW_AT_MIPS_linkage_name";
+#if VMS_DEBUGGING_INFO
+ case DW_AT_HP_epilogue:
+ return "DW_AT_HP_epilogue";
+#else
case DW_AT_MIPS_stride:
return "DW_AT_MIPS_stride";
+#endif
case DW_AT_MIPS_abstract_name:
return "DW_AT_MIPS_abstract_name";
case DW_AT_MIPS_clone_origin:
@@ -7017,6 +7103,22 @@ AT_file (dw_attr_ref a)
return a->dw_attr_val.v.val_file;
}
+/* Add a delta attribute value to a DIE. */
+
+static inline void
+add_AT_delta_flag (dw_die_ref die, enum dwarf_attribute attr_kind,
+ const char *lbl1, const char *lbl2, const int flag)
+{
+ dw_attr_node attr;
+
+ attr.dw_attr = attr_kind;
+ attr.dw_attr_val.val_class = dw_val_class_delta;
+ attr.dw_attr_val.v.val_delta.lbl1 = xstrdup (lbl1);
+ attr.dw_attr_val.v.val_delta.lbl2 = xstrdup (lbl2);
+ attr.dw_attr_val.v.val_delta.flag = flag;
+ add_dwarf_attr (die, &attr);
+}
+
/* Add a label identifier attribute value to a DIE. */
static inline void
@@ -7088,6 +7190,39 @@ add_AT_range_list (dw_die_ref die, enum
add_dwarf_attr (die, &attr);
}
+/* Return the start label of a delta attribute. */
+
+static inline const char *
+AT_delta1 (dw_attr_ref a)
+{
+ if (a && (AT_class (a) == dw_val_class_delta))
+ return a->dw_attr_val.v.val_delta.lbl1;
+
+ abort ();
+}
+
+/* Return the end label of a delta attribute. */
+
+static inline const char *
+AT_delta2 (dw_attr_ref a)
+{
+ if (a && (AT_class (a) == dw_val_class_delta))
+ return a->dw_attr_val.v.val_delta.lbl2;
+
+ abort ();
+}
+
+/* Return the units value of a delta attribute. */
+
+static inline int
+AT_delta_flag (dw_attr_ref a)
+{
+ if (a && (AT_class (a) == dw_val_class_delta))
+ return a->dw_attr_val.v.val_delta.flag;
+
+ abort ();
+}
+
static inline const char *
AT_lbl (dw_attr_ref a)
{
@@ -7602,6 +7737,14 @@ print_die (dw_die_ref die, FILE *outfile
else
fprintf (outfile, "die -> <null>");
break;
+ case dw_val_class_delta:
+ if (AT_delta_flag (a))
+ fprintf (outfile, "delta: f(%s-%s)",
+ AT_delta2 (a), AT_delta1 (a));
+ else
+ fprintf (outfile, "delta: %s-%s",
+ AT_delta2 (a), AT_delta1 (a));
+ break;
case dw_val_class_lbl_id:
case dw_val_class_lineptr:
case dw_val_class_macptr:
@@ -7773,6 +7916,7 @@ attr_checksum (dw_attr_ref at, struct md
break;
case dw_val_class_fde_ref:
+ case dw_val_class_delta:
case dw_val_class_lbl_id:
case dw_val_class_lineptr:
case dw_val_class_macptr:
@@ -7881,6 +8025,7 @@ same_dw_val_p (const dw_val_node *v1, co
return same_die_p (v1->v.val_die_ref.die, v2->v.val_die_ref.die, mark);
case dw_val_class_fde_ref:
+ case dw_val_class_delta:
case dw_val_class_lbl_id:
case dw_val_class_lineptr:
case dw_val_class_macptr:
@@ -8475,6 +8620,9 @@ size_of_die (dw_die_ref die)
case dw_val_class_fde_ref:
size += DWARF_OFFSET_SIZE;
break;
+ case dw_val_class_delta:
+ size += DWARF_OFFSET_SIZE;
+ break;
case dw_val_class_lbl_id:
size += DWARF2_ADDR_SIZE;
break;
@@ -8681,6 +8829,8 @@ value_format (dw_attr_ref a)
return DW_FORM_ref;
case dw_val_class_fde_ref:
return DW_FORM_data;
+ case dw_val_class_delta:
+ return DW_FORM_data4;
case dw_val_class_lbl_id:
return DW_FORM_addr;
case dw_val_class_lineptr:
@@ -8829,10 +8979,10 @@ output_loc_list (dw_loc_list_ref list_he
continue;
if (!have_multiple_function_sections)
{
- dw2_asm_output_delta (DWARF2_ADDR_SIZE, curr->begin, curr->section,
+ dw2_asm_output_delta (DWARF2_ADDR_SIZE, curr->begin, curr->section, 0,
"Location list begin address (%s)",
list_head->ll_symbol);
- dw2_asm_output_delta (DWARF2_ADDR_SIZE, curr->end, curr->section,
+ dw2_asm_output_delta (DWARF2_ADDR_SIZE, curr->end, curr->section, 0,
"Location list end address (%s)",
list_head->ll_symbol);
}
@@ -9028,6 +9178,11 @@ output_die (dw_die_ref die)
}
break;
+ case dw_val_class_delta:
+ dw2_asm_output_delta (DWARF_OFFSET_SIZE, AT_delta2 (a),
+ AT_delta1 (a), AT_delta_flag (a), "%s", name);
+ break;
+
case dw_val_class_lbl_id:
dw2_asm_output_addr (DWARF2_ADDR_SIZE, AT_lbl (a), "%s", name);
break;
@@ -9317,14 +9472,14 @@ output_aranges (void)
{
dw2_asm_output_addr (DWARF2_ADDR_SIZE, text_section_label, "Address");
dw2_asm_output_delta (DWARF2_ADDR_SIZE, text_end_label,
- text_section_label, "Length");
+ text_section_label, 0, "Length");
}
if (cold_text_section_used)
{
dw2_asm_output_addr (DWARF2_ADDR_SIZE, cold_text_section_label,
"Address");
dw2_asm_output_delta (DWARF2_ADDR_SIZE, cold_end_label,
- cold_text_section_label, "Length");
+ cold_text_section_label, 0, "Length");
}
for (i = 0; i < arange_table_in_use; i++)
@@ -9339,7 +9494,7 @@ output_aranges (void)
dw2_asm_output_addr (DWARF2_ADDR_SIZE, get_AT_low_pc (die),
"Address");
dw2_asm_output_delta (DWARF2_ADDR_SIZE, get_AT_hi_pc (die),
- get_AT_low_pc (die), "Length");
+ get_AT_low_pc (die), 0, "Length");
}
else
{
@@ -9450,10 +9605,10 @@ output_ranges (void)
if (!have_multiple_function_sections)
{
dw2_asm_output_delta (DWARF2_ADDR_SIZE, blabel,
- text_section_label,
+ text_section_label, 0,
fmt, i * 2 * DWARF2_ADDR_SIZE);
dw2_asm_output_delta (DWARF2_ADDR_SIZE, elabel,
- text_section_label, NULL);
+ text_section_label, 0, NULL);
}
/* Otherwise, the compilation unit base address is zero,
@@ -9484,11 +9639,11 @@ output_ranges (void)
the #if 0 above. */
dw2_asm_output_delta (DWARF2_ADDR_SIZE,
ranges_by_label[lab_idx].begin,
- text_section_label,
+ text_section_label, 0,
fmt, i * 2 * DWARF2_ADDR_SIZE);
dw2_asm_output_delta (DWARF2_ADDR_SIZE,
ranges_by_label[lab_idx].end,
- text_section_label, NULL);
+ text_section_label, 0, NULL);
#endif
}
else
@@ -9870,12 +10025,12 @@ output_line_info (void)
if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4)
dw2_asm_output_data (4, 0xffffffff,
"Initial length escape value indicating 64-bit DWARF extension");
- dw2_asm_output_delta (DWARF_OFFSET_SIZE, l2, l1,
+ dw2_asm_output_delta (DWARF_OFFSET_SIZE, l2, l1, 0,
"Length of Source Line Info");
ASM_OUTPUT_LABEL (asm_out_file, l1);
dw2_asm_output_data (2, dwarf_version, "DWARF Version");
- dw2_asm_output_delta (DWARF_OFFSET_SIZE, p2, p1, "Prolog Length");
+ dw2_asm_output_delta (DWARF_OFFSET_SIZE, p2, p1, 0, "Prolog Length");
ASM_OUTPUT_LABEL (asm_out_file, p1);
/* Define the architecture-dependent minimum instruction length (in
@@ -9967,7 +10122,7 @@ output_line_info (void)
/* This can handle deltas up to 0xffff. This takes 3 bytes. */
dw2_asm_output_data (1, DW_LNS_fixed_advance_pc,
"DW_LNS_fixed_advance_pc");
- dw2_asm_output_delta (2, line_label, prev_line_label, NULL);
+ dw2_asm_output_delta (2, line_label, prev_line_label, 0, NULL);
}
else
{
@@ -10023,7 +10178,7 @@ output_line_info (void)
{
dw2_asm_output_data (1, DW_LNS_fixed_advance_pc,
"DW_LNS_fixed_advance_pc");
- dw2_asm_output_delta (2, text_end_label, prev_line_label, NULL);
+ dw2_asm_output_delta (2, text_end_label, prev_line_label, 0, NULL);
}
else
{
@@ -10075,7 +10230,7 @@ output_line_info (void)
{
dw2_asm_output_data (1, DW_LNS_fixed_advance_pc,
"DW_LNS_fixed_advance_pc");
- dw2_asm_output_delta (2, line_label, prev_line_label, NULL);
+ dw2_asm_output_delta (2, line_label, prev_line_label, 0, NULL);
}
else
{
@@ -10137,7 +10292,7 @@ output_line_info (void)
{
dw2_asm_output_data (1, DW_LNS_fixed_advance_pc,
"DW_LNS_fixed_advance_pc");
- dw2_asm_output_delta (2, line_label, prev_line_label, NULL);
+ dw2_asm_output_delta (2, line_label, prev_line_label, 0, NULL);
}
else
{
@@ -15388,6 +15543,38 @@ gen_subprogram_die (tree decl, dw_die_re
current_function_funcdef_no);
add_AT_lbl_id (subr_die, DW_AT_high_pc, label_id);
+#if VMS_DEBUGGING_INFO
+ /* HP OpenVMS Industry Standard 64: DWARF Extensions
+ Section 2.3 Prologue and Epilogue Attributes:
+ When a breakpoint is set on entry to a function, it is generally
+ desirable for execution to be suspended, not on the very first
+ instruction of the function, but rather at a point after the
+ function's frame has been set up, after any language defined local
+ declaration processing has been completed, and before execution of
+ the first statement of the function begins. Debuggers generally
+ cannot properly determine where this point is. Similarly for a
+ breakpoint set on exit from a function. The prologue and epilogue
+ attributes allow a compiler to communicate the location(s) to use. */
+
+#define VMS_FLAG 1
+ /* For unknown reasons, the prologue and epilogue size on IA64
+ VMS is in different units than everything else, so a flag
+ is passed so the macro that's ultimately called knows that
+ this is the time to do the special adjustment. */
+
+ {
+ dw_fde_ref fde = &fde_table[current_funcdef_fde];
+
+ if (fde->dw_fde_vms_end_prologue)
+ add_AT_delta_flag (subr_die, DW_AT_HP_prologue,
+ fde->dw_fde_begin, fde->dw_fde_vms_end_prologue, VMS_FLAG);
+
+ if (fde->dw_fde_vms_begin_epilogue)
+ add_AT_delta_flag (subr_die, DW_AT_HP_epilogue,
+ fde->dw_fde_begin, fde->dw_fde_vms_begin_epilogue, VMS_FLAG);
+ }
+#endif
+
add_pubname (decl, subr_die);
add_arange (decl, subr_die);
}
diff -rup gcc-head-src/gcc/dwarf2out.h gcc-head-src-10.1/gcc/dwarf2out.h
--- gcc/dwarf2out.h 2009-05-29 17:33:46.000000000 -0700
+++ gcc/dwarf2out.h 2009-09-08 22:02:42.000000000 -0700
@@ -20,7 +20,7 @@ along with GCC; see the file COPYING3.
extern void dwarf2out_decl (tree);
extern void dwarf2out_frame_debug (rtx, bool);
-extern void dwarf2out_begin_epilogue (rtx);
+extern void dwarf2out_cfi_begin_epilogue (rtx);
extern void dwarf2out_frame_debug_restore_state (void);
extern void debug_dwarf (void);
diff -rup gcc-head-src/gcc/except.c gcc-head-src-10.1/gcc/except.c
--- gcc/except.c 2009-09-02 21:07:12.000000000 -0700
+++ gcc/except.c 2009-09-09 11:26:45.000000000 -0700
@@ -4256,11 +4256,11 @@ dw2_output_call_site_table (int cs_forma
}
else
{
- dw2_asm_output_delta (4, reg_start_lab, begin,
+ dw2_asm_output_delta (4, reg_start_lab, begin, 0,
"region %d start", i);
- dw2_asm_output_delta (4, reg_end_lab, reg_start_lab, "length");
+ dw2_asm_output_delta (4, reg_end_lab, reg_start_lab, 0, "length");
if (cs->landing_pad)
- dw2_asm_output_delta (4, landing_pad_lab, begin,
+ dw2_asm_output_delta (4, landing_pad_lab, begin, 0,
"landing pad");
else
dw2_asm_output_data (4, 0, "landing pad");
diff -rup gcc-head-src/gcc/final.c gcc-head-src-10.1/gcc/final.c
--- gcc/final.c 2009-09-01 19:42:21.000000000 -0700
+++ gcc/final.c 2009-09-08 22:02:42.000000000 -0700
@@ -1892,8 +1892,9 @@ final_scan_insn (rtx insn, FILE *file, i
case NOTE_INSN_EPILOGUE_BEG:
#if defined (DWARF2_UNWIND_INFO) && defined (HAVE_epilogue)
if (dwarf2out_do_frame ())
- dwarf2out_begin_epilogue (insn);
+ dwarf2out_cfi_begin_epilogue (insn);
#endif
+ (*debug_hooks->begin_epilogue) (last_linenum, last_filename);
targetm.asm_out.function_begin_epilogue (file);
break;
diff -rup gcc-head-src/gcc/sdbout.c gcc-head-src-10.1/gcc/sdbout.c
--- gcc/sdbout.c 2009-06-23 03:19:18.000000000 -0700
+++ gcc/sdbout.c 2009-09-08 22:02:42.000000000 -0700
@@ -324,6 +324,7 @@ const struct gcc_debug_hooks sdb_debug_h
sdbout_begin_prologue, /* begin_prologue */
debug_nothing_int_charstar, /* end_prologue */
#endif
+ debug_nothing_int_charstar, /* begin_epilogue */
sdbout_end_epilogue, /* end_epilogue */
sdbout_begin_function, /* begin_function */
sdbout_end_function, /* end_function */
@@ -1712,6 +1713,7 @@ const struct gcc_debug_hooks sdb_debug_h
0, /* source_line */
0, /* begin_prologue */
0, /* end_prologue */
+ 0, /* begin_epilogue */
0, /* end_epilogue */
0, /* begin_function */
0, /* end_function */
diff -rup gcc-head-src/gcc/vmsdbgout.c gcc-head-src-10.1/gcc/vmsdbgout.c
--- gcc/vmsdbgout.c 2009-07-29 10:35:32.000000000 -0700
+++ gcc/vmsdbgout.c 2009-09-08 22:02:42.000000000 -0700
@@ -200,6 +200,7 @@ const struct gcc_debug_hooks vmsdbg_debu
vmsdbgout_source_line,
vmsdbgout_begin_prologue,
vmsdbgout_end_prologue,
+ debug_nothing_int_charstar, /* begin_epilogue */
vmsdbgout_end_epilogue,
vmsdbgout_begin_function,
vmsdbgout_end_function,
diff -rup gcc-head-src/include/dwarf2.h gcc-head-src-10.1/include/dwarf2.h
--- include/dwarf2.h 2009-08-31 14:48:04.000000000 -0700
+++ include/dwarf2.h 2009-09-08 22:02:42.000000000 -0700
@@ -373,6 +373,8 @@ enum dwarf_attribute
/* HP extensions. */
DW_AT_HP_block_index = 0x2000,
DW_AT_HP_unmodifiable = 0x2001, /* Same as DW_AT_MIPS_fde. */
+ DW_AT_HP_prologue = 0x2005, /* Loc of first instruction after prologue. */
+ DW_AT_HP_epilogue = 0x2008, /* Loc of first instruction in epilogue. */
DW_AT_HP_actuals_stmt_list = 0x2010,
DW_AT_HP_proc_per_section = 0x2011,
DW_AT_HP_raw_data_ptr = 0x2012,