diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 80667d3ef7fafd747408f006fc4ed961524542c6..007d78e10c6603d09671973df0a8f1273054528e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+2009-10-17  Jakub Jelinek  <jakub@redhat.com>
+
+	PR debug/40521
+	* debug.h (struct gcc_debug_hooks): Add assembly_start hook.
+	* cgraphunit.c (cgraph_optimize): Call it.
+	* dwarf2out.c (dwarf2out_init): Move .cfi_sections printing into...
+	(dwarf2out_assembly_start): ... here.  New hook.
+	(dwarf2out_debug_hooks): Add dwarf2out_assembly_start.
+	* debug.c (do_nothing_debug_hooks): Do nothing for assembly_start
+	hook.
+	* dbxout.c (dbx_debug_hooks, xcoff_debug_hooks): Likewise.
+	* sdbout.c (sdb_debug_hooks): Likewise.
+	* vmsdbgout.c (vmsdbg_debug_hooks): Add vmsdbgout_assembly_start.
+	(vmsdbgout_assembly_start): New hook.
+
 2009-10-17  Alexandre Oliva  <aoliva@redhat.com>
 
 	* rtl.h (RTL_LOCATION): Fix typo.
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 9a97bef296252ee0a5ea42ef5777a59381be63a7..47ee7d9ebcdd78215443f065898f1be41db6a7ed 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -1441,6 +1441,7 @@ cgraph_optimize (void)
   timevar_pop (TV_CGRAPHOPT);
 
   /* Output everything.  */
+  (*debug_hooks->assembly_start) ();
   if (!quiet_flag)
     fprintf (stderr, "Assembling functions:\n");
 #ifdef ENABLE_CHECKING
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index d09087a2f2caacdce262a341dca3646ce7f1b7a1..b5688d98cf15aedd877aff92f062de095d1bd98e 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -346,6 +346,7 @@ const struct gcc_debug_hooks dbx_debug_hooks =
 {
   dbxout_init,
   dbxout_finish,
+  debug_nothing_void,
   debug_nothing_int_charstar,
   debug_nothing_int_charstar,
   dbxout_start_source_file,
@@ -386,6 +387,7 @@ const struct gcc_debug_hooks xcoff_debug_hooks =
 {
   dbxout_init,
   dbxout_finish,
+  debug_nothing_void,
   debug_nothing_int_charstar,
   debug_nothing_int_charstar,
   dbxout_start_source_file,
diff --git a/gcc/debug.c b/gcc/debug.c
index 8035c43ca4abf5811736eb21014f3496de2e9362..c413595078b8dcfc00ff724b51b432b966151f10 100644
--- a/gcc/debug.c
+++ b/gcc/debug.c
@@ -27,6 +27,7 @@ const struct gcc_debug_hooks do_nothing_debug_hooks =
 {
   debug_nothing_charstar,
   debug_nothing_charstar,
+  debug_nothing_void,
   debug_nothing_int_charstar,
   debug_nothing_int_charstar,
   debug_nothing_int_charstar,
diff --git a/gcc/debug.h b/gcc/debug.h
index 4009cd6a93b933d41dd02c6a28b47797ea210362..ef611d43572f8340c9bc012a5422968e5b6f6224 100644
--- a/gcc/debug.h
+++ b/gcc/debug.h
@@ -31,6 +31,10 @@ struct gcc_debug_hooks
   /* Output debug symbols.  */
   void (* finish) (const char *main_filename);
 
+  /* Called from cgraph_optimize before starting to assemble
+     functions/variables/toplevel asms.  */
+  void (* assembly_start) (void);
+
   /* Macro defined on line LINE with name and expansion TEXT.  */
   void (* define) (unsigned int line, const char *text);
 
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 00adf0612042983187da0da53c3e66823950be7a..ba59251d66b095e5d1dcc7983f82161734dd0625 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -5401,6 +5401,7 @@ static int output_indirect_string (void **, void *);
 
 static void dwarf2out_init (const char *);
 static void dwarf2out_finish (const char *);
+static void dwarf2out_assembly_start (void);
 static void dwarf2out_define (unsigned int, const char *);
 static void dwarf2out_undef (unsigned int, const char *);
 static void dwarf2out_start_source_file (unsigned, const char *);
@@ -5427,6 +5428,7 @@ const struct gcc_debug_hooks dwarf2_debug_hooks =
 {
   dwarf2out_init,
   dwarf2out_finish,
+  dwarf2out_assembly_start,
   dwarf2out_define,
   dwarf2out_undef,
   dwarf2out_start_source_file,
@@ -20392,6 +20394,14 @@ dwarf2out_init (const char *filename ATTRIBUTE_UNUSED)
       ASM_OUTPUT_LABEL (asm_out_file, cold_text_section_label);
     }
 
+}
+
+/* Called before cgraph_optimize starts outputtting functions, variables
+   and toplevel asms into assembly.  */
+
+static void
+dwarf2out_assembly_start (void)
+{
   if (HAVE_GAS_CFI_SECTIONS_DIRECTIVE && dwarf2out_do_cfi_asm ())
     {
 #ifndef TARGET_UNWIND_INFO
@@ -21274,6 +21284,7 @@ const struct gcc_debug_hooks dwarf2_debug_hooks =
 {
   0,		/* init */
   0,		/* finish */
+  0,		/* assembly_start */
   0,		/* define */
   0,		/* undef */
   0,		/* start_source_file */
diff --git a/gcc/sdbout.c b/gcc/sdbout.c
index 0553740b968c5b0f4a797a8bd979f6163ef51357..e7d52a63c70346691a2c27d5eb928e11800ca511 100644
--- a/gcc/sdbout.c
+++ b/gcc/sdbout.c
@@ -307,6 +307,7 @@ const struct gcc_debug_hooks sdb_debug_hooks =
 {
   sdbout_init,			         /* init */
   sdbout_finish,		         /* finish */
+  debug_nothing_void,			 /* assembly_start */
   debug_nothing_int_charstar,	         /* define */
   debug_nothing_int_charstar,	         /* undef */
   sdbout_start_source_file,	         /* start_source_file */
@@ -1705,6 +1706,7 @@ const struct gcc_debug_hooks sdb_debug_hooks =
 {
   0,		/* init */
   0,		/* finish */
+  0,		/* assembly_start */
   0,		/* define */
   0,		/* undef */
   0,		/* start_source_file */
diff --git a/gcc/vmsdbgout.c b/gcc/vmsdbgout.c
index 0fab5e73ae20ad5cf676d9d5a7910e9afd1a96f6..b16e76e61c06de17d495eed11f96b9dea58623f9 100644
--- a/gcc/vmsdbgout.c
+++ b/gcc/vmsdbgout.c
@@ -168,6 +168,7 @@ static int write_srccorrs (int);
 
 static void vmsdbgout_init (const char *);
 static void vmsdbgout_finish (const char *);
+static void vmsdbgout_assembly_start (void);
 static void vmsdbgout_define (unsigned int, const char *);
 static void vmsdbgout_undef (unsigned int, const char *);
 static void vmsdbgout_start_source_file (unsigned int, const char *);
@@ -190,6 +191,7 @@ static void vmsdbgout_abstract_function (tree);
 const struct gcc_debug_hooks vmsdbg_debug_hooks
 = {vmsdbgout_init,
    vmsdbgout_finish,
+   vmsdbgout_assembly_start,
    vmsdbgout_define,
    vmsdbgout_undef,
    vmsdbgout_start_source_file,
@@ -1617,6 +1619,15 @@ vmsdbgout_init (const char *main_input_filename)
 
 /* Not implemented in VMS Debug.  */
 
+static void
+vmsdbgout_assembly_start (void)
+{
+  if (write_symbols == VMS_AND_DWARF2_DEBUG)
+    (*dwarf2_debug_hooks.assembly_start) ();
+}
+
+/* Not implemented in VMS Debug.  */
+
 static void
 vmsdbgout_define (unsigned int lineno, const char *buffer)
 {