public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH][RFC] Come up with casm state
@ 2021-09-10  9:31 Martin Liška
  2021-09-16 10:00 ` [PATCH 1/N] Rename asm_out_file function arguments Martin Liška
                   ` (2 more replies)
  0 siblings, 3 replies; 30+ messages in thread
From: Martin Liška @ 2021-09-10  9:31 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 450 bytes --]

Hi.

We're considering with Richi some changes related to how we emit early debug info.
That would probably include changes where the debug info would be streamed to a separate
file (different from normal .o output file).

That said, we would need switching in between output assembly files. The patch I'm sending
is a first step and we would like to receive a comments about the chosen approach?

Richi, do you want to add something?

Cheers,
Martin

[-- Attachment #2: casm-state.patch --]
[-- Type: text/x-patch, Size: 87899 bytes --]

diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 55cb0347149..5bac9beb934 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -2309,7 +2309,7 @@ symbol_table::compile (void)
   timevar_pop (TV_CGRAPHOPT);
 
   /* Output everything.  */
-  switch_to_section (text_section);
+  switch_to_section (casm->sections.text);
   (*debug_hooks->assembly_start) ();
   if (!quiet_flag)
     fprintf (stderr, "Assembling functions:\n");
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 1fbe9e0daa0..3160d2952d5 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -25714,7 +25714,7 @@ aarch64_sls_emit_blr_function_thunks (FILE *out_file)
      would happen in a different section -- leaving an unmatched
      `.cfi_startproc` in the cold text section and an unmatched `.cfi_endproc`
      in the standard text section.  */
-  section *save_text_section = in_section;
+  section *save_text_section = casm->in_section;
   switch_to_section (function_section (current_function_decl));
   for (int regnum = 0; regnum < 30; ++regnum)
     {
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index c702e683c31..54a1df4b821 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -8055,13 +8055,13 @@ alpha_start_function (FILE *file, const char *fnname,
 
 #ifdef TARGET_VMS_CRASH_DEBUG
   /* Support of minimal traceback info.  */
-  switch_to_section (readonly_data_section);
+  switch_to_section (casm->sections.readonly_data);
   fprintf (file, "\t.align 3\n");
   assemble_name (file, fnname); fputs ("..na:\n", file);
   fputs ("\t.ascii \"", file);
   assemble_name (file, fnname);
   fputs ("\\0\"\n", file);
-  switch_to_section (text_section);
+  switch_to_section (casm->sections.text);
 #endif
 #endif /* TARGET_ABI_OPEN_VMS */
 }
@@ -9446,7 +9446,7 @@ alpha_elf_select_rtx_section (machine_mode mode, rtx x,
 {
   if (TARGET_SMALL_DATA && GET_MODE_SIZE (mode) <= g_switch_value)
     /* ??? Consider using mergeable sdata sections.  */
-    return sdata_section;
+    return casm->sections.sdata;
   else
     return default_elf_select_rtx_section (mode, x, align);
 }
@@ -9613,7 +9613,7 @@ alpha_write_linkage (FILE *stream, const char *funname)
 {
   fprintf (stream, "\t.link\n");
   fprintf (stream, "\t.align 3\n");
-  in_section = NULL;
+  casm->in_section = NULL;
 
 #ifdef TARGET_VMS_CRASH_DEBUG
   fputs ("\t.name ", stream);
@@ -9665,7 +9665,7 @@ vms_asm_named_section (const char *name, unsigned int flags,
 static void
 vms_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
 {
-  switch_to_section (ctors_section);
+  switch_to_section (casm->sections.ctors);
   assemble_align (BITS_PER_WORD);
   assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
 }
@@ -9673,7 +9673,7 @@ vms_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
 static void
 vms_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
 {
-  switch_to_section (dtors_section);
+  switch_to_section (casm->sections.dtors);
   assemble_align (BITS_PER_WORD);
   assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
 }
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 92797db96b7..ee763e59312 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -8832,7 +8832,7 @@ arc_asm_output_aligned_decl_local (FILE * stream, tree decl, const char * name,
     switch_to_section (get_named_section (NULL, ".sbss", 0));
   /*    named_section (0,".sbss",0); */
   else
-    switch_to_section (bss_section);
+    switch_to_section (casm->sections.bss);
 
   if (globalize_p)
     (*targetm.asm_out.globalize_label) (stream, name);
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index f1e628253d0..5f7e36234ea 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -17234,7 +17234,7 @@ get_jump_table_size (rtx_jump_table_data *insn)
 {
   /* ADDR_VECs only take room if read-only data does into the text
      section.  */
-  if (JUMP_TABLES_IN_TEXT_SECTION || readonly_data_section == text_section)
+  if (JUMP_TABLES_IN_TEXT_SECTION || casm->sections.readonly_data == casm->sections.text)
     {
       rtx body = PATTERN (insn);
       int elt = GET_CODE (body) == ADDR_DIFF_VEC ? 1 : 0;
@@ -24642,9 +24642,9 @@ arm_elf_asm_cdtor (rtx symbol, int priority, bool is_ctor)
       s = get_section (buf, SECTION_WRITE | SECTION_NOTYPE, NULL_TREE);
     }
   else if (is_ctor)
-    s = ctors_section;
+    s = casm->sections.ctors;
   else
-    s = dtors_section;
+    s = casm->sections.dtors;
 
   switch_to_section (s);
   assemble_align (POINTER_SIZE);
@@ -27910,7 +27910,7 @@ thumb_call_via_reg (rtx reg)
   /* If we are in the normal text section we can use a single instance
      per compilation unit.  If we are doing function sections, then we need
      an entry per section, since we can't rely on reachability.  */
-  if (in_section == text_section)
+  if (casm->in_section == casm->sections.text)
     {
       thumb_call_reg_needed = 1;
 
@@ -28302,7 +28302,7 @@ arm_file_end (void)
   if (! thumb_call_reg_needed)
     return;
 
-  switch_to_section (text_section);
+  switch_to_section (casm->sections.text);
   asm_fprintf (asm_out_file, "\t.code 16\n");
   ASM_OUTPUT_ALIGN (asm_out_file, 1);
 
@@ -29752,13 +29752,13 @@ static void
 arm_asm_init_sections (void)
 {
 #if ARM_UNWIND_INFO
-  exception_section = get_unnamed_section (0, output_section_asm_op,
+  casm->sections.exception = get_unnamed_section (0, output_section_asm_op,
 					   "\t.handlerdata");
 #endif /* ARM_UNWIND_INFO */
 
 #ifdef OBJECT_FORMAT_ELF
   if (target_pure_code)
-    text_section->unnamed.data = "\t.section .text,\"0x20000006\",%progbits";
+    casm->sections.text->unnamed.data = "\t.section .text,\"0x20000006\",%progbits";
 #endif
 }
 
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 200701a583c..9b650bdbf51 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -10085,7 +10085,7 @@ avr_asm_asm_output_aligned_bss (FILE *file, tree decl, const char *name,
 }
 
 
-/* Unnamed section callback for data_section
+/* Unnamed section callback for casm->sections.data
    to track need of __do_copy_data.  */
 
 static void
@@ -10098,7 +10098,7 @@ avr_output_data_section_asm_op (const void *data)
 }
 
 
-/* Unnamed section callback for bss_section
+/* Unnamed section callback for casm->sections.bss
    to track need of __do_clear_bss.  */
 
 static void
@@ -10133,9 +10133,9 @@ avr_asm_init_sections (void)
 #if defined HAVE_LD_AVR_AVRXMEGA3_RODATA_IN_FLASH
   if (avr_arch->flash_pm_offset == 0)
 #endif
-    readonly_data_section->unnamed.callback = avr_output_data_section_asm_op;
-  data_section->unnamed.callback = avr_output_data_section_asm_op;
-  bss_section->unnamed.callback = avr_output_bss_section_asm_op;
+    casm->sections.readonly_data->unnamed.callback = avr_output_data_section_asm_op;
+  casm->sections.data->unnamed.callback = avr_output_data_section_asm_op;
+  casm->sections.bss->unnamed.callback = avr_output_bss_section_asm_op;
 }
 
 
@@ -12567,7 +12567,7 @@ avr_output_addr_vec (rtx_insn *labl, rtx table)
   // Switch back to original section.  As we clobbered the section above,
   // forget the current section before switching back.
 
-  in_section = NULL;
+  casm->in_section = NULL;
   switch_to_section (current_function_section ());
 }
 
diff --git a/gcc/config/c6x/c6x.c b/gcc/config/c6x/c6x.c
index ce4949516cf..b775e518d0c 100644
--- a/gcc/config/c6x/c6x.c
+++ b/gcc/config/c6x/c6x.c
@@ -890,7 +890,7 @@ c6x_select_rtx_section (machine_mode mode, rtx x,
   if (c6x_sdata_mode == C6X_SDATA_ALL
       || (c6x_sdata_mode != C6X_SDATA_NONE && GET_MODE_SIZE (mode) <= 8))
     /* ??? Consider using mergeable sdata sections.  */
-    return sdata_section;
+    return casm->sections.sdata;
   else
     return default_elf_select_rtx_section (mode, x, align);
 }
@@ -5473,7 +5473,7 @@ c6x_asm_emit_except_personality (rtx personality)
 static void
 c6x_asm_init_sections (void)
 {
-  exception_section = get_unnamed_section (0, output_section_asm_op,
+  casm->sections.exception = get_unnamed_section (0, output_section_asm_op,
 					   "\t.handlerdata");
 }
 
diff --git a/gcc/config/csky/csky.c b/gcc/config/csky/csky.c
index e55821fe2ee..c82540abeda 100644
--- a/gcc/config/csky/csky.c
+++ b/gcc/config/csky/csky.c
@@ -958,7 +958,7 @@ get_csky_jump_table_size (rtx insn)
 {
   /* ADDR_VECs only take room if read-only data does into the text
      section.  */
-  if (JUMP_TABLES_IN_TEXT_SECTION || readonly_data_section == text_section)
+  if (JUMP_TABLES_IN_TEXT_SECTION || casm->sections.readonly_data == casm->sections.text)
     {
       rtx body = PATTERN (insn);
       int elt = GET_CODE (body) == ADDR_DIFF_VEC ? 1 : 0;
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index 781742fe46f..f6ce2d5d09e 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -143,7 +143,7 @@ output_objc_section_asm_op (const void *directive)
      section is requested.  */
   if (darwin_symbol_stubs && ! been_here)
     {
-      section *saved_in_section = in_section;
+      section *saved_in_section = casm->in_section;
       static const enum darwin_section_enum tomark[] =
 	{
 	  /* written, cold -> hot */
@@ -236,14 +236,14 @@ darwin_init_sections (void)
 #include "config/darwin-sections.def"
 #undef DEF_SECTION
 
-  readonly_data_section = darwin_sections[const_section];
-  exception_section = darwin_sections[darwin_exception_section];
-  eh_frame_section = darwin_sections[darwin_eh_frame_section];
+  casm->sections.readonly_data = darwin_sections[const_section];
+  casm->sections.exception = darwin_sections[darwin_exception_section];
+  casm->sections.eh_frame = darwin_sections[darwin_eh_frame_section];
 
   /* If our linker is new enough to coalesce weak symbols, then we
      can just put picbase_thunks into the text section.  */
   if (! ld_uses_coal_sects )
-    darwin_sections[picbase_thunk_section] = text_section;
+    darwin_sections[picbase_thunk_section] = casm->sections.text;
 }
 
 int
@@ -1071,7 +1071,7 @@ machopic_output_data_section_indirection (machopic_indirection **slot,
   /* The name of the indirection symbol.  */
   const char *ptr_name = p->ptr_name;
 
-  switch_to_section (data_section);
+  switch_to_section (casm->sections.data);
   assemble_align (GET_MODE_ALIGNMENT (Pmode));
   assemble_label (asm_out_file, ptr_name);
   assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
@@ -1340,7 +1340,7 @@ darwin_mergeable_string_section (tree exp,
       && TREE_STRING_LENGTH (exp) == 0)
     return darwin_sections[zobj_const_section];
 
-  return readonly_data_section;
+  return casm->sections.readonly_data;
 }
 
 #ifndef HAVE_GAS_LITERAL16
@@ -1362,7 +1362,7 @@ darwin_mergeable_constant_section (tree exp,
       || align < 8
       || align > 256
       || (align & (align -1)) != 0)
-    return readonly_data_section;
+    return casm->sections.readonly_data;
 
   /* This will ICE if the mode is not a constant size, but that is reasonable,
      since one cannot put a variable-sized thing into a constant section, we
@@ -1370,12 +1370,12 @@ darwin_mergeable_constant_section (tree exp,
   const unsigned int modesize = GET_MODE_BITSIZE (mode).to_constant ();
 
   if (modesize > align)
-    return readonly_data_section;
+    return casm->sections.readonly_data;
 
   tree size = TYPE_SIZE_UNIT (TREE_TYPE (exp));
 
   if (TREE_CODE (size) != INTEGER_CST)
-    return readonly_data_section;
+    return casm->sections.readonly_data;
 
   unsigned isize = TREE_INT_CST_LOW (size);
   if (isize == 4)
@@ -1387,7 +1387,7 @@ darwin_mergeable_constant_section (tree exp,
 	   && isize == 16)
     return darwin_sections[literal16_section];
 
-  return readonly_data_section;
+  return casm->sections.readonly_data;
 }
 
 section *
@@ -1443,7 +1443,7 @@ darwin_objc2_section (tree decl ATTRIBUTE_UNUSED, tree meta, section * base)
 
   objc_metadata_seen = 1;
 
-  if (base == data_section)
+  if (base == casm->sections.data)
     base = darwin_sections[objc2_metadata_section];
 
   /* Most of the OBJC2 META-data end up in the base section, so check it
@@ -1494,7 +1494,7 @@ darwin_objc2_section (tree decl ATTRIBUTE_UNUSED, tree meta, section * base)
 
   else if (startswith (p, "V2_EHTY"))
     return ld_uses_coal_sects ? darwin_sections[data_coal_section]
-                              : data_section;
+                              : casm->sections.data;
 
   else if (startswith (p, "V2_CSTR"))
     return darwin_sections[objc2_constant_string_object_section];
@@ -1680,7 +1680,7 @@ machopic_select_section (tree decl,
       else if (ro)
 	base_section = darwin_sections[const_data_section];
       else
-	base_section = data_section;
+	base_section = casm->sections.data;
       break;
     case SECCAT_BSS:
     case SECCAT_SBSS:
@@ -1690,11 +1690,11 @@ machopic_select_section (tree decl,
       else
 	{
 	  if (!TREE_PUBLIC (decl))
-	    base_section = lcomm_section;
-	  else if (bss_noswitch_section)
-	    base_section = bss_noswitch_section;
+	    base_section = casm->sections.lcomm;
+	  else if (casm->sections.bss_noswitch)
+	    base_section = casm->sections.bss_noswitch;
 	  else
-	    base_section = data_section;
+	    base_section = casm->sections.data;
 	}
       break;
 
@@ -2365,8 +2365,8 @@ fprintf (file, "# dadon: %s %s (%llu, %u) local %d weak %d"
       /* Check that we've correctly picked up the zero-sized item and placed it
          properly.  */
       gcc_assert ((!DARWIN_SECTION_ANCHORS || !flag_section_anchors)
-		  || (in_section
-		      && (in_section->common.flags & SECTION_NO_ANCHOR)));
+		  || (casm->in_section
+		      && (casm->in_section->common.flags & SECTION_NO_ANCHOR)));
     }
   else
     ASM_OUTPUT_LABEL (file, xname);
@@ -2386,8 +2386,8 @@ darwin_asm_declare_constant_name (FILE *file, const char *name,
       /* Check that we've correctly picked up the zero-sized item and placed it
          properly.  */
       gcc_assert ((!DARWIN_SECTION_ANCHORS || !flag_section_anchors)
-		  || (in_section
-		      && (in_section->common.flags & SECTION_NO_ANCHOR)));
+		  || (casm->in_section
+		      && (casm->in_section->common.flags & SECTION_NO_ANCHOR)));
     }
 }
 
@@ -2424,7 +2424,7 @@ darwin_emit_weak_or_comdat (FILE *fp, tree decl, const char *name,
 				: darwin_sections[const_data_section]);
   else
     switch_to_section (use_coal ? darwin_sections[data_coal_section]
-				: data_section);
+				: casm->sections.data);
 
   /* To be consistent, we'll allow darwin_asm_declare_object_name to assemble
      the align info for zero-sized items... but do it here otherwise.  */
@@ -2446,7 +2446,7 @@ darwin_emit_objc_zeroed (FILE *fp, tree decl, const char *name,
 				  unsigned HOST_WIDE_INT size,
 				  unsigned int align, tree meta)
 {
-  section *ocs = data_section;
+  section *ocs = casm->sections.data;
 
   if (TREE_PURPOSE (meta) == get_identifier("OBJC2META"))
     ocs = darwin_objc2_section (decl, meta, ocs);
@@ -2488,13 +2488,13 @@ darwin_emit_local_bss (FILE *fp, tree decl, const char *name,
       if (!size)
 	{
 	  fputs ("\t.section\t__DATA,__zobj_bss\n", fp);
-	  in_section = darwin_sections[zobj_bss_section];
+	  casm->in_section = darwin_sections[zobj_bss_section];
 	  size = 1;
 	}
       else
 	{
 	  fputs ("\t.static_data\n", fp);
-	  in_section = darwin_sections[static_data_section];
+	  casm->in_section = darwin_sections[static_data_section];
 	}
 
       if (l2align)
@@ -2512,7 +2512,7 @@ darwin_emit_local_bss (FILE *fp, tree decl, const char *name,
       char secnam[64];
       snprintf (secnam, 64, "__DATA,__bss");
       unsigned int flags = SECTION_BSS|SECTION_WRITE|SECTION_NO_ANCHOR;
-      in_section = get_section (secnam, flags, NULL);
+      casm->in_section = get_section (secnam, flags, NULL);
       fprintf (fp, "\t.zerofill %s,", secnam);
       assemble_name (fp, name);
       if (!size)
@@ -2559,7 +2559,7 @@ darwin_emit_common (FILE *fp, const char *name,
   l2align = floor_log2 (align);
   gcc_assert (l2align <= L2_MAX_OFILE_ALIGNMENT);
 
-  in_section = comm_section;
+  casm->in_section = casm->sections.comm;
   /* We mustn't allow multiple public symbols to share an address when using
      the normal OSX toolchain.  */
   if (!size)
@@ -2567,7 +2567,7 @@ darwin_emit_common (FILE *fp, const char *name,
       /* Put at least one byte.  */
       size = 1;
       /* This section can no longer participate in section anchoring.  */
-      comm_section->common.flags |= SECTION_NO_ANCHOR;
+      casm->sections.comm->common.flags |= SECTION_NO_ANCHOR;
     }
 
   fputs ("\t.comm\t", fp);
@@ -2656,13 +2656,13 @@ fprintf (fp, "# albss: %s (%lld,%d) ro %d cst %d stat %d com %d"
       if (!size)
 	{
 	  fputs ("\t.section\t__DATA,__zobj_data\n", fp);
-	  in_section = darwin_sections[zobj_data_section];
+	  casm->in_section = darwin_sections[zobj_data_section];
 	  size = 1;
 	}
       else
 	{
 	  fputs ("\t.data\n", fp);
-	  in_section = data_section;
+	  casm->in_section = casm->sections.data;
 	}
 
       if (l2align)
@@ -2677,7 +2677,7 @@ fprintf (fp, "# albss: %s (%lld,%d) ro %d cst %d stat %d com %d"
       unsigned int flags = SECTION_BSS|SECTION_WRITE|SECTION_NO_ANCHOR;
       char secnam[64];
       snprintf (secnam, 64, "__DATA,__common");
-      in_section = get_section (secnam, flags, NULL);
+      casm->in_section = get_section (secnam, flags, NULL);
       fprintf (fp, "\t.zerofill %s,", secnam);
       assemble_name (fp, name);
       if (!size)
@@ -3893,7 +3893,7 @@ darwin_function_section (tree decl, enum node_frequency freq,
   /* Otherwise, default to the 'normal' non-reordered sections.  */
 default_function_sections:
   return (use_coal) ? darwin_sections[text_coal_section]
-		    : text_section;
+		    : casm->sections.text;
 }
 
 #include "gt-darwin.h"
diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c
index a7f7f086d17..74237e93e96 100644
--- a/gcc/config/frv/frv.c
+++ b/gcc/config/frv/frv.c
@@ -9395,7 +9395,7 @@ frv_rtx_costs (rtx x,
 static void
 frv_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
 {
-  switch_to_section (ctors_section);
+  switch_to_section (casm->sections.ctors);
   assemble_align (POINTER_SIZE);
   if (TARGET_FDPIC)
     {
@@ -9410,7 +9410,7 @@ frv_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
 static void
 frv_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
 {
-  switch_to_section (dtors_section);
+  switch_to_section (casm->sections.dtors);
   assemble_align (POINTER_SIZE);
   if (TARGET_FDPIC)
     {
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 7b173bc0beb..600eb2f137d 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -869,7 +869,7 @@ x86_output_aligned_bss (FILE *file, tree decl, const char *name,
       && size > (unsigned int)ix86_section_threshold)
     switch_to_section (get_named_section (decl, ".lbss", 0));
   else
-    switch_to_section (bss_section);
+    switch_to_section (casm->sections.bss);
   ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
 #ifdef ASM_DECLARE_OBJECT_NAME
   last_assemble_variable_decl = decl;
@@ -1567,7 +1567,7 @@ ix86_function_naked (const_tree fn)
 /* Write the extra assembler code needed to declare a function properly.  */
 
 void
-ix86_asm_output_function_label (FILE *asm_out_file, const char *fname,
+ix86_asm_output_function_label (FILE *out_file, const char *fname,
 				tree decl)
 {
   bool is_ms_hook = ix86_function_ms_hook_prologue (decl);
@@ -1581,14 +1581,14 @@ ix86_asm_output_function_label (FILE *asm_out_file, const char *fname,
       unsigned int filler_cc = 0xcccccccc;
 
       for (i = 0; i < filler_count; i += 4)
-        fprintf (asm_out_file, ASM_LONG " %#x\n", filler_cc);
+	fprintf (out_file, ASM_LONG " %#x\n", filler_cc);
     }
 
 #ifdef SUBTARGET_ASM_UNWIND_INIT
-  SUBTARGET_ASM_UNWIND_INIT (asm_out_file);
+  SUBTARGET_ASM_UNWIND_INIT (out_file);
 #endif
 
-  ASM_OUTPUT_LABEL (asm_out_file, fname);
+  ASM_OUTPUT_LABEL (out_file, fname);
 
   /* Output magic byte marker, if hot-patch attribute is set.  */
   if (is_ms_hook)
@@ -1597,14 +1597,14 @@ ix86_asm_output_function_label (FILE *asm_out_file, const char *fname,
 	{
 	  /* leaq [%rsp + 0], %rsp  */
 	  fputs (ASM_BYTE "0x48, 0x8d, 0xa4, 0x24, 0x00, 0x00, 0x00, 0x00\n",
-		 asm_out_file);
+		 out_file);
 	}
       else
 	{
           /* movl.s %edi, %edi
 	     push   %ebp
 	     movl.s %esp, %ebp */
-	  fputs (ASM_BYTE "0x8b, 0xff, 0x55, 0x8b, 0xec\n", asm_out_file);
+	  fputs (ASM_BYTE "0x8b, 0xff, 0x55, 0x8b, 0xec\n", out_file);
 	}
     }
 }
@@ -5954,7 +5954,7 @@ output_indirect_thunk_function (enum indirect_thunk_prefix need_prefix,
       }
     else
       {
-	switch_to_section (text_section);
+	switch_to_section (casm->sections.text);
 	ASM_OUTPUT_LABEL (asm_out_file, name);
       }
 
@@ -6074,7 +6074,7 @@ ix86_code_end (void)
 	}
       else
 	{
-	  switch_to_section (text_section);
+	  switch_to_section (casm->sections.text);
 	  ASM_OUTPUT_LABEL (asm_out_file, name);
 	}
 
diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c
index 4158a45ac31..c6b0949da15 100644
--- a/gcc/config/i386/winnt.c
+++ b/gcc/config/i386/winnt.c
@@ -1347,7 +1347,7 @@ void
 i386_pe_seh_init_sections (void)
 {
   if (TARGET_SEH)
-    exception_section = get_unnamed_section (0, output_section_asm_op,
+    casm->sections.exception = get_unnamed_section (0, output_section_asm_op,
 					     "\t.seh_handlerdata");
 }
 \f
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index 632b9df1761..d9b9fcc5eda 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -10406,7 +10406,7 @@ ia64_asm_emit_except_personality (rtx personality)
 static void
 ia64_asm_init_sections (void)
 {
-  exception_section = get_unnamed_section (0, output_section_asm_op,
+  casm->sections.exception = get_unnamed_section (0, output_section_asm_op,
 					   "\t.handlerdata");
 }
 
@@ -10858,7 +10858,7 @@ ia64_select_rtx_section (machine_mode mode, rtx x,
   if (GET_MODE_SIZE (mode) > 0
       && GET_MODE_SIZE (mode) <= ia64_section_threshold
       && !TARGET_NO_SDATA)
-    return sdata_section;
+    return casm->sections.sdata;
   else
     return default_elf_select_rtx_section (mode, x, align);
 }
diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c
index 6e8f367c80a..4105df8a480 100644
--- a/gcc/config/microblaze/microblaze.c
+++ b/gcc/config/microblaze/microblaze.c
@@ -2836,9 +2836,9 @@ microblaze_elf_asm_cdtor (rtx symbol, int priority, bool is_ctor)
       s = get_section (buf, SECTION_WRITE, NULL_TREE);
     }
   else if (is_ctor)
-    s = ctors_section;
+    s = casm->sections.ctors;
   else
-    s = dtors_section;
+    s = casm->sections.dtors;
 
   switch_to_section (s);
   assemble_align (POINTER_SIZE);
@@ -3261,7 +3261,7 @@ microblaze_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
          relaxation/relocation. Currently, turning mergeable sections 
          into regular readonly sections.  */
 
-      return readonly_data_section;
+      return casm->sections.readonly_data;
     default:
       return default_elf_select_section (decl, reloc, align);
     }
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index ade5d7041f0..50dd99ff0b3 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -9718,7 +9718,7 @@ mips_output_aligned_decl_common (FILE *stream, tree decl, const char *name,
       if (TREE_PUBLIC (decl) && DECL_NAME (decl))
 	targetm.asm_out.globalize_label (stream, name);
 
-      switch_to_section (readonly_data_section);
+      switch_to_section (casm->sections.readonly_data);
       ASM_OUTPUT_ALIGN (stream, floor_log2 (align / BITS_PER_UNIT));
       mips_declare_object (stream, name, "",
 			   ":\n\t.space\t" HOST_WIDE_INT_PRINT_UNSIGNED "\n",
diff --git a/gcc/config/mmix/mmix.c b/gcc/config/mmix/mmix.c
index 010cd4773ea..5522535e0ab 100644
--- a/gcc/config/mmix/mmix.c
+++ b/gcc/config/mmix/mmix.c
@@ -1321,7 +1321,7 @@ mmix_file_start (void)
   fputs ("! mmixal:= 8H LOC Data_Section\n", asm_out_file);
 
   /* Make sure each file starts with the text section.  */
-  switch_to_section (text_section);
+  switch_to_section (casm->sections.text);
 }
 
 /* TARGET_ASM_FILE_END.  */
@@ -1330,7 +1330,7 @@ static void
 mmix_file_end (void)
 {
   /* Make sure each file ends with the data section.  */
-  switch_to_section (data_section);
+  switch_to_section (casm->sections.data);
 }
 
 /* TARGET_ASM_OUTPUT_SOURCE_FILENAME.  */
@@ -1510,7 +1510,7 @@ mmix_asm_output_aligned_local (FILE *stream,
 			       int size,
 			       int align)
 {
-  switch_to_section (data_section);
+  switch_to_section (casm->sections.data);
 
   ASM_OUTPUT_ALIGN (stream, exact_log2 (align/BITS_PER_UNIT));
   assemble_name (stream, name);
diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c
index 1cdacb7f480..d9ae7e2d912 100644
--- a/gcc/config/msp430/msp430.c
+++ b/gcc/config/msp430/msp430.c
@@ -2398,22 +2398,22 @@ msp430_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
     {
     case SECCAT_TEXT:
       if (!prefix)
-	return text_section;
+	return casm->sections.text;
       base_sec_name = ".text";
       break;
     case SECCAT_DATA:
       if (!prefix)
-	return data_section;
+	return casm->sections.data;
       base_sec_name = ".data";
       break;
     case SECCAT_BSS:
       if (!prefix)
-	return bss_section;
+	return casm->sections.bss;
       base_sec_name = ".bss";
       break;
     case SECCAT_RODATA:
       if (!prefix)
-	return readonly_data_section;
+	return casm->sections.readonly_data;
       base_sec_name = ".rodata";
       break;
 
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 06143023b46..2f01884cea2 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -4444,7 +4444,7 @@ pa_output_function_epilogue (FILE *file)
       /* We are done with this subspace except possibly for some additional
 	 debug information.  Forget that we are in this subspace to ensure
 	 that the next function is output in its own subspace.  */
-      in_section = NULL;
+      casm->in_section = NULL;
       cfun->machine->in_nsubspa = 2;
     }
 
@@ -4693,7 +4693,7 @@ output_deferred_profile_counters (void)
   if (funcdef_nos.is_empty ())
    return;
 
-  switch_to_section (data_section);
+  switch_to_section (casm->sections.data);
   align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE);
   ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
 
@@ -5863,7 +5863,7 @@ output_deferred_plabels (void)
      before outputting the deferred plabels.  */
   if (n_deferred_plabels)
     {
-      switch_to_section (flag_pic ? data_section : readonly_data_section);
+      switch_to_section (flag_pic ? casm->sections.data : casm->sections.readonly_data);
       ASM_OUTPUT_ALIGN (asm_out_file, TARGET_64BIT ? 3 : 2);
     }
 
@@ -8872,7 +8872,7 @@ pa_asm_output_mi_thunk (FILE *file, tree thunk_fndecl, HOST_WIDE_INT delta,
 
   if (TARGET_SOM && flag_pic && TREE_PUBLIC (function))
     {
-      switch_to_section (data_section);
+      switch_to_section (casm->sections.data);
       output_asm_insn (".align 4", xoperands);
       ASM_OUTPUT_LABEL (file, label);
       output_asm_insn (".word P'%0", xoperands);
@@ -9047,7 +9047,7 @@ pa_asm_output_aligned_bss (FILE *stream,
 			   unsigned HOST_WIDE_INT size,
 			   unsigned int align)
 {
-  switch_to_section (bss_section);
+  switch_to_section (casm->sections.bss);
 
 #ifdef ASM_OUTPUT_TYPE_DIRECTIVE
   ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "object");
@@ -9084,7 +9084,7 @@ pa_asm_output_aligned_common (FILE *stream,
       align = max_common_align;
     }
 
-  switch_to_section (bss_section);
+  switch_to_section (casm->sections.bss);
 
   assemble_name (stream, name);
   fprintf (stream, "\t.comm " HOST_WIDE_INT_PRINT_UNSIGNED"\n",
@@ -9104,7 +9104,7 @@ pa_asm_output_aligned_local (FILE *stream,
 			     unsigned HOST_WIDE_INT size,
 			     unsigned int align)
 {
-  switch_to_section (bss_section);
+  switch_to_section (casm->sections.bss);
   fprintf (stream, "\t.align %u\n", align / BITS_PER_UNIT);
 
 #ifdef LOCAL_ASM_OP
@@ -10030,10 +10030,10 @@ som_output_text_section_asm_op (const void *data ATTRIBUTE_UNUSED)
 	     function has been completed.  So, we are changing to the
 	     text section to output debugging information.  Thus, we
 	     need to forget that we are in the text section so that
-	     varasm.c will call us when text_section is selected again.  */
+	     varasm.c will call us when casm->sections.text is selected again.  */
 	  gcc_assert (!cfun || !cfun->machine
 		      || cfun->machine->in_nsubspa == 2);
-	  in_section = NULL;
+	  casm->in_section = NULL;
 	}
       output_section_asm_op ("\t.SPACE $TEXT$\n\t.NSUBSPA $CODE$");
       return;
@@ -10047,7 +10047,7 @@ som_output_text_section_asm_op (const void *data ATTRIBUTE_UNUSED)
 static void
 som_output_comdat_data_section_asm_op (const void *data)
 {
-  in_section = NULL;
+  casm->in_section = NULL;
   output_section_asm_op (data);
 }
 
@@ -10056,7 +10056,7 @@ som_output_comdat_data_section_asm_op (const void *data)
 static void
 pa_som_asm_init_sections (void)
 {
-  text_section
+  casm->sections.text
     = get_unnamed_section (0, som_output_text_section_asm_op, NULL);
 
   /* SOM puts readonly data in the default $LIT$ subspace when PIC code
@@ -10104,14 +10104,14 @@ pa_som_asm_init_sections (void)
      when generating PIC code.  This reduces sharing, but it works
      correctly.  Now we rely on pa_reloc_rw_mask() for section selection.
      This puts constant data not needing relocation into the $TEXT$ space.  */
-  readonly_data_section = som_readonly_data_section;
+  casm->sections.readonly_data = som_readonly_data_section;
 
   /* We must not have a reference to an external symbol defined in a
      shared library in a readonly section, else the SOM linker will
      complain.
 
      So, we force exception information into the data section.  */
-  exception_section = data_section;
+  casm->sections.exception = casm->sections.data;
 }
 
 /* Implement TARGET_ASM_TM_CLONE_TABLE_SECTION.  */
@@ -10144,18 +10144,18 @@ pa_select_section (tree exp, int reloc,
 	  && !DECL_WEAK (exp))
 	return som_one_only_readonly_data_section;
       else
-	return readonly_data_section;
+	return casm->sections.readonly_data;
     }
   else if (CONSTANT_CLASS_P (exp)
 	   && !(reloc & pa_reloc_rw_mask ()))
-    return readonly_data_section;
+    return casm->sections.readonly_data;
   else if (TARGET_SOM
 	   && TREE_CODE (exp) == VAR_DECL
 	   && DECL_ONE_ONLY (exp)
 	   && !DECL_WEAK (exp))
     return som_one_only_data_section;
   else
-    return data_section;
+    return casm->sections.data;
 }
 
 /* Implement pa_elf_select_rtx_section.  If X is a function label operand
@@ -10648,7 +10648,7 @@ pa_function_section (tree decl, enum node_frequency freq,
 {
   /* Put functions in text section if target doesn't have named sections.  */
   if (!targetm_common.have_named_sections)
-    return text_section;
+    return casm->sections.text;
 
   /* Force nested functions into the same section as the containing
      function.  */
diff --git a/gcc/config/pdp11/pdp11.c b/gcc/config/pdp11/pdp11.c
index ced653116a4..0cb38926edc 100644
--- a/gcc/config/pdp11/pdp11.c
+++ b/gcc/config/pdp11/pdp11.c
@@ -743,7 +743,7 @@ void
 pdp11_asm_output_var (FILE *file, const char *name, int size,
 		      int align, bool global)
 {
-  switch_to_section (data_section);
+  switch_to_section (casm->sections.data);
   if (align > 8)
     fprintf (file, "\t.even\n");
   if (TARGET_DEC_ASM)
@@ -2323,11 +2323,11 @@ pdp11_asm_init_sections (void)
 {
   if (TARGET_DEC_ASM)
     {
-      bss_section = data_section;
+      casm->sections.bss = casm->sections.data;
     }
   else if (TARGET_GNU_ASM)
     {
-      bss_section = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
+      casm->sections.bss = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
 					 output_section_asm_op,
 					 ".bss");
     }
diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
index 576960bb37c..66bb05b0e43 100644
--- a/gcc/config/riscv/riscv.c
+++ b/gcc/config/riscv/riscv.c
@@ -3615,8 +3615,8 @@ riscv_elf_select_rtx_section (machine_mode mode, rtx x,
 	  return get_section (name, s->named.common.flags, NULL);
 	}
 
-      if (s == data_section)
-	return sdata_section;
+      if (s == casm->sections.data)
+	return casm->sections.sdata;
     }
 
   return s;
diff --git a/gcc/config/rl78/rl78.c b/gcc/config/rl78/rl78.c
index 4c34949a97f..30d81f9d41f 100644
--- a/gcc/config/rl78/rl78.c
+++ b/gcc/config/rl78/rl78.c
@@ -4644,14 +4644,14 @@ rl78_select_section (tree decl,
     }
 
   if (readonly)
-    return TARGET_ES0 ? frodata_section : readonly_data_section;
+    return TARGET_ES0 ? frodata_section : casm->sections.readonly_data;
 
   switch (categorize_decl_for_section (decl, reloc))
     {
-    case SECCAT_TEXT:   return text_section;
-    case SECCAT_DATA:   return data_section;
-    case SECCAT_BSS:    return bss_section;
-    case SECCAT_RODATA: return TARGET_ES0 ? frodata_section : readonly_data_section;
+    case SECCAT_TEXT:   return casm->sections.text;
+    case SECCAT_DATA:   return casm->sections.data;
+    case SECCAT_BSS:    return casm->sections.bss;
+    case SECCAT_RODATA: return TARGET_ES0 ? frodata_section : casm->sections.readonly_data;
     default:
       return default_select_section (decl, reloc, align);
     }
@@ -4786,7 +4786,7 @@ rl78_asm_ctor_dtor (rtx symbol, int priority, bool is_ctor)
       sec = get_section (buf, 0, NULL);
     }
   else
-    sec = is_ctor ? ctors_section : dtors_section;
+    sec = is_ctor ? casm->sections.ctors : casm->sections.dtors;
 
   assemble_addr_to_section (symbol, sec);
 }
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index b7ea1483da5..d194d23fa8d 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -14392,7 +14392,7 @@ rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
 	 section.  */
       if (DEFAULT_ABI == ABI_V4
 	  && (TARGET_RELOCATABLE || flag_pic > 1)
-	  && in_section != toc_section
+	  && casm->in_section != toc_section
 	  && !recurse
 	  && !CONST_SCALAR_INT_P (x)
 	  && CONSTANT_P (x))
@@ -20941,7 +20941,7 @@ rs6000_elf_file_end (void)
       /* We have expanded a CPU builtin, so we need to emit a reference to
 	 the special symbol that LIBC uses to declare it supports the
 	 AT_PLATFORM and AT_HWCAP/AT_HWCAP2 in the TCB feature.  */
-      switch_to_section (data_section);
+      switch_to_section (casm->sections.data);
       fprintf (asm_out_file, "\t.align %u\n", TARGET_32BIT ? 2 : 3);
       fprintf (asm_out_file, "\t%s %s\n",
 	       TARGET_32BIT ? ".long" : ".quad", tcb_verification_symbol);
@@ -21066,7 +21066,7 @@ rs6000_xcoff_asm_init_sections (void)
   toc_section
     = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
 
-  readonly_data_section = read_only_data_section;
+  casm->sections.readonly_data = read_only_data_section;
 }
 
 static int
@@ -21144,7 +21144,7 @@ rs6000_xcoff_select_section (tree decl, int reloc,
       if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL_P (decl))
 	{
 	  if (bss_initializer_p (decl))
-	    return tls_comm_section;
+	    return casm->sections.tls_comm;
 	  else if (TREE_PUBLIC (decl))
 	    return tls_data_section;
 	  else
@@ -21153,7 +21153,7 @@ rs6000_xcoff_select_section (tree decl, int reloc,
       else
 #endif
 	if (TREE_PUBLIC (decl))
-	return data_section;
+	return casm->sections.data;
       else
 	return private_data_section;
     }
@@ -21258,7 +21258,7 @@ rs6000_xcoff_file_start (void)
   if (write_symbols != NO_DEBUG)
     switch_to_section (private_data_section);
   switch_to_section (toc_section);
-  switch_to_section (text_section);
+  switch_to_section (casm->sections.text);
   if (profile_flag)
     fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
   rs6000_file_start ();
@@ -21270,9 +21270,9 @@ rs6000_xcoff_file_start (void)
 static void
 rs6000_xcoff_file_end (void)
 {
-  switch_to_section (text_section);
+  switch_to_section (casm->sections.text);
   fputs ("_section_.text:\n", asm_out_file);
-  switch_to_section (data_section);
+  switch_to_section (casm->sections.data);
   fputs (TARGET_32BIT
 	 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
 	 asm_out_file);
@@ -21392,7 +21392,7 @@ rs6000_xcoff_visibility (tree decl)
    Dollar signs are converted to underscores.
 
    The csect for the function will have already been created when
-   text_section was selected.  We do have to go back to that csect, however.
+   casm->sections.text was selected.  We do have to go back to that csect, however.
 
    The third and fourth parameters to the .function pseudo-op (16 and 044)
    are placeholders which no longer have any use.
@@ -21454,7 +21454,7 @@ rs6000_xcoff_declare_function_name (FILE *file, const char *name, tree decl)
   RS6000_OUTPUT_BASENAME (file, buffer);
   fputs (", TOC[tc0], 0\n", file);
 
-  in_section = NULL;
+  casm->in_section = NULL;
   switch_to_section (function_section (decl));
   putc ('.', file);
   ASM_OUTPUT_LABEL (file, buffer);
@@ -21514,7 +21514,7 @@ rs6000_xcoff_asm_output_aligned_decl_common (FILE *stream,
   if (! DECL_COMMON (decl))
     {
       /* Forget section.  */
-      in_section = NULL;
+      casm->in_section = NULL;
 
       /* Globalize TLS BSS.  */
       if (TREE_PUBLIC (decl) && DECL_THREAD_LOCAL_P (decl))
@@ -26509,7 +26509,7 @@ rs6000_code_end (void)
   else
 #endif
     {
-      switch_to_section (text_section);
+      switch_to_section (casm->sections.text);
       ASM_OUTPUT_LABEL (asm_out_file, name);
     }
 
diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c
index af54ccc2588..3cb495f5c4d 100644
--- a/gcc/config/rx/rx.c
+++ b/gcc/config/rx/rx.c
@@ -2305,7 +2305,7 @@ rx_select_rtx_section (machine_mode mode,
   if (rx_small_data_limit > 0
       && GET_MODE_SIZE (mode) <= rx_small_data_limit
       && align <= (unsigned HOST_WIDE_INT) rx_small_data_limit * BITS_PER_UNIT)
-    return sdata_section;
+    return casm->sections.sdata;
 
   return default_elf_select_rtx_section (mode, x, align);
 }
@@ -2319,8 +2319,8 @@ rx_select_section (tree decl,
     {
       switch (categorize_decl_for_section (decl, reloc))
 	{
-	case SECCAT_SDATA:	return sdata_section;
-	case SECCAT_SBSS:	return sbss_section;
+	case SECCAT_SDATA:	return casm->sections.sdata;
+	case SECCAT_SBSS:	return casm->sections.sbss;
 	case SECCAT_SRODATA:
 	  /* Fall through.  We do not put small, read only
 	     data into the C_2 section because we are not
@@ -2342,7 +2342,7 @@ rx_select_section (tree decl,
       case SECCAT_RODATA_MERGE_CONST:
       case SECCAT_RODATA_MERGE_STR_INIT:
       case SECCAT_RODATA_MERGE_STR:
-	return readonly_data_section;
+	return casm->sections.readonly_data;
 
       default:
 	break;
@@ -2690,9 +2690,9 @@ rx_elf_asm_cdtor (rtx symbol, int priority, bool is_ctor)
       s = get_section (buf, SECTION_WRITE, NULL_TREE);
     }
   else if (is_ctor)
-    s = ctors_section;
+    s = casm->sections.ctors;
   else
-    s = dtors_section;
+    s = casm->sections.dtors;
 
   switch_to_section (s);
   assemble_align (POINTER_SIZE);
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 54dd6332c3a..244e97bbbca 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -16612,7 +16612,7 @@ s390_output_indirect_thunk_function (unsigned int regno, bool z10_p)
     }
   else
     {
-      switch_to_section (text_section);
+      switch_to_section (casm->sections.text);
       ASM_OUTPUT_LABEL (asm_out_file, thunk_label);
     }
 
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 1564109c942..07d18406ea1 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -2828,7 +2828,7 @@ sh_file_start (void)
   else
     /* Switch to the data section so that the coffsem symbol
        isn't in the text section.  */
-    switch_to_section (data_section);
+    switch_to_section (casm->sections.data);
 
   if (TARGET_LITTLE_ENDIAN)
     fputs ("\t.little\n", asm_out_file);
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 06f41d7bb53..53fca1f4b5c 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -12499,7 +12499,7 @@ sparc_file_end (void)
       else
 	{
 	  const int align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
-          switch_to_section (text_section);
+          switch_to_section (casm->sections.text);
 	  if (align > 0)
 	    ASM_OUTPUT_ALIGN (asm_out_file, align);
 	  ASM_OUTPUT_LABEL (asm_out_file, name);
diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c
index 4978faf9318..2d1c8dca2ea 100644
--- a/gcc/config/v850/v850.c
+++ b/gcc/config/v850/v850.c
@@ -2398,7 +2398,7 @@ v850_output_aligned_bss (FILE * file,
       break;
 
     case DATA_AREA_SDA:
-      switch_to_section (sbss_section);
+      switch_to_section (casm->sections.sbss);
       break;
 
     case DATA_AREA_TDA:
@@ -2406,7 +2406,7 @@ v850_output_aligned_bss (FILE * file,
       break;
       
     default:
-      switch_to_section (bss_section);
+      switch_to_section (casm->sections.bss);
       break;
     }
   
@@ -2882,13 +2882,13 @@ v850_select_section (tree exp,
 	  return tdata_section;
 
         case DATA_AREA_SDA:
-	  return is_const ? rosdata_section : sdata_section;
+	  return is_const ? rosdata_section : casm->sections.sdata;
 
         default:
-	  return is_const ? readonly_data_section : data_section;
+	  return is_const ? casm->sections.readonly_data : casm->sections.data;
         }
     }
-  return readonly_data_section;
+  return casm->sections.readonly_data;
 }
 \f
 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P.  */
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index 6be282714cf..0ad57ab35bd 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -934,7 +934,7 @@ dbxout_function_end (tree decl ATTRIBUTE_UNUSED)
   if (crtl->has_bb_partition)
     {
       dbxout_begin_empty_stabs (N_FUN);
-      if (in_cold_section_p)
+      if (casm->in_cold_section_p)
 	dbxout_stab_value_label_diff (crtl->subsections.cold_section_end_label,
 				      crtl->subsections.cold_section_label);
       else
@@ -1042,7 +1042,7 @@ dbxout_init (const char *input_file_name)
 
   if (used_ltext_label_name)
     {
-      switch_to_section (text_section);
+      switch_to_section (casm->sections.text);
       targetm.asm_out.internal_label (asm_out_file, "Ltext", 0);
     }
 
@@ -1244,7 +1244,7 @@ dbxout_source_file (const char *filename)
     {
       /* Don't change section amid function.  */
       if (current_function_decl == NULL_TREE)
-	switch_to_section (text_section);
+	switch_to_section (casm->sections.text);
 
       dbxout_begin_simple_stabs (remap_debug_filename (filename), N_SOL);
       dbxout_stab_value_internal_label ("Ltext", &source_label_number);
@@ -1314,12 +1314,12 @@ dbxout_switch_text_section (void)
   /* The N_FUN tag at the end of the function is a GNU extension,
      which may be undesirable, and is unnecessary if we do not have
      named sections.  */
-  in_cold_section_p = !in_cold_section_p;
+  casm->in_cold_section_p = !casm->in_cold_section_p;
   switch_to_section (current_function_section ());
   dbxout_block (DECL_INITIAL (current_function_decl), 0,
 		DECL_ARGUMENTS (current_function_decl), -1);
   dbxout_function_end (current_function_decl);
-  in_cold_section_p = !in_cold_section_p;
+  casm->in_cold_section_p = !casm->in_cold_section_p;
 
   switch_to_section (current_function_section ());
 
@@ -1432,7 +1432,7 @@ dbxout_finish (const char *filename ATTRIBUTE_UNUSED)
   DBX_OUTPUT_MAIN_SOURCE_FILE_END (asm_out_file, filename);
 #elif defined DBX_OUTPUT_NULL_N_SO_AT_MAIN_SOURCE_FILE_END
  {
-   switch_to_section (text_section);
+   switch_to_section (casm->sections.text);
    dbxout_begin_empty_stabs (N_SO);
    dbxout_stab_value_internal_label ("Letext", 0);
  }
@@ -3114,7 +3114,7 @@ dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home)
 	    {
 	      /* Ultrix `as' seems to need this.  */
 #ifdef DBX_STATIC_STAB_DATA_SECTION
-	      switch_to_section (data_section);
+	      switch_to_section (casm->sections.data);
 #endif
 	      code = N_STSYM;
 	    }
@@ -3776,7 +3776,7 @@ dbxout_block (tree block, int depth, tree args, int parent_blocknum)
 
   /* If called for the second partition, ignore blocks that don't have
      any children in the second partition.  */
-  if (crtl->has_bb_partition && in_cold_section_p && depth == 0)
+  if (crtl->has_bb_partition && casm->in_cold_section_p && depth == 0)
     dbx_block_with_cold_children (block);
 
   for (; block; block = BLOCK_CHAIN (block))
@@ -3801,7 +3801,7 @@ dbxout_block (tree block, int depth, tree args, int parent_blocknum)
 	     the assembler symbols LBBn and LBEn
 	     that final will define around the code in this block.  */
 	  if (did_output
-	      && BLOCK_IN_COLD_SECTION_P (block) == in_cold_section_p)
+	      && BLOCK_IN_COLD_SECTION_P (block) == casm->in_cold_section_p)
 	    {
 	      char buf[20];
 	      const char *scope_start;
@@ -3829,7 +3829,7 @@ dbxout_block (tree block, int depth, tree args, int parent_blocknum)
 
 	  /* Refer to the marker for the end of the block.  */
 	  if (did_output
-	      && BLOCK_IN_COLD_SECTION_P (block) == in_cold_section_p)
+	      && BLOCK_IN_COLD_SECTION_P (block) == casm->in_cold_section_p)
 	    {
 	      char buf[100];
 	      if (depth == 0)
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 9876750e4f9..cdfdee3cd9a 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -438,14 +438,14 @@ should_emit_struct_debug (tree type, enum debug_info_usage usage)
   return DUMP_GSTRUCT (type, usage, criterion, generic, false, false);
 }
 \f
-/* Switch [BACK] to eh_frame_section.  If we don't have an eh_frame_section,
+/* Switch [BACK] to casm->sections.eh_frame.  If we don't have an casm->sections.eh_frame,
    switch to the data section instead, and write out a synthetic start label
    for collect2 the first time around.  */
 
 static void
 switch_to_eh_frame_section (bool back ATTRIBUTE_UNUSED)
 {
-  if (eh_frame_section == 0)
+  if (casm->sections.eh_frame == 0)
     {
       int flags;
 
@@ -474,14 +474,14 @@ switch_to_eh_frame_section (bool back ATTRIBUTE_UNUSED)
 	flags = SECTION_WRITE;
 
 #ifdef EH_FRAME_SECTION_NAME
-      eh_frame_section = get_section (EH_FRAME_SECTION_NAME, flags, NULL);
+      casm->sections.eh_frame = get_section (EH_FRAME_SECTION_NAME, flags, NULL);
 #else
-      eh_frame_section = ((flags == SECTION_WRITE)
-			  ? data_section : readonly_data_section);
+      casm->sections.eh_frame = ((flags == SECTION_WRITE)
+			  ? casm->sections.data : casm->sections.readonly_data);
 #endif /* EH_FRAME_SECTION_NAME */
     }
 
-  switch_to_section (eh_frame_section);
+  switch_to_section (casm->sections.eh_frame);
 
 #ifdef EH_FRAME_THROUGH_COLLECT2
   /* We have no special eh_frame section.  Emit special labels to guide
@@ -1113,10 +1113,10 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
   /* Initialize the bits of CURRENT_FDE that were not available earlier.  */
   fde->dw_fde_begin = dup_label;
   fde->dw_fde_current_label = dup_label;
-  fde->in_std_section = (fnsec == text_section
+  fde->in_std_section = (fnsec == casm->sections.text
 			 || (cold_text_section && fnsec == cold_text_section));
   fde->ignored_debug = DECL_IGNORED_P (current_function_decl);
-  in_text_section_p = fnsec == text_section;
+  in_text_section_p = fnsec == casm->sections.text;
 
   /* We only want to output line number information for the genuine dwarf2
      prologue case, not the eh frame case.  */
@@ -1295,7 +1295,7 @@ dwarf2out_switch_text_section (void)
 			       current_function_funcdef_no);
 
   fde->dw_fde_second_begin = ggc_strdup (label);
-  if (!in_cold_section_p)
+  if (!casm->in_cold_section_p)
     {
       fde->dw_fde_end = crtl->subsections.cold_section_end_label;
       fde->dw_fde_second_end = crtl->subsections.hot_section_end_label;
@@ -1317,9 +1317,9 @@ dwarf2out_switch_text_section (void)
   switch_to_section (sect);
 
   fde->second_in_std_section
-    = (sect == text_section
+    = (sect == casm->sections.text
        || (cold_text_section && sect == cold_text_section));
-  in_text_section_p = sect == text_section;
+  in_text_section_p = sect == casm->sections.text;
 
   if (dwarf2out_do_cfi_asm ())
     dwarf2out_do_cfi_startproc (true);
@@ -17268,7 +17268,7 @@ secname_for_decl (const_tree decl)
     secname = DECL_SECTION_NAME (decl);
   else if (current_function_decl && DECL_SECTION_NAME (current_function_decl))
     {
-      if (in_cold_section_p)
+      if (casm->in_cold_section_p)
 	{
 	  section *sec = current_function_section ();
 	  if (sec->common.flags & SECTION_NAMED)
@@ -17276,7 +17276,7 @@ secname_for_decl (const_tree decl)
 	}
       secname = DECL_SECTION_NAME (current_function_decl);
     }
-  else if (cfun && in_cold_section_p)
+  else if (cfun && casm->in_cold_section_p)
     secname = crtl->subsections.cold_section_label;
   else
     secname = text_section_label;
@@ -17597,12 +17597,12 @@ dw_loc_list (var_loc_list *loc_list, tree decl, int want_address)
 
   if (cfun && crtl->has_bb_partition)
     {
-      bool save_in_cold_section_p = in_cold_section_p;
-      in_cold_section_p = first_function_block_is_cold;
+      bool save_in_cold_section_p = casm->in_cold_section_p;
+      casm->in_cold_section_p = first_function_block_is_cold;
       if (loc_list->last_before_switch == NULL)
-	in_cold_section_p = !in_cold_section_p;
+	casm->in_cold_section_p = !casm->in_cold_section_p;
       secname = secname_for_decl (decl);
-      in_cold_section_p = save_in_cold_section_p;
+      casm->in_cold_section_p = save_in_cold_section_p;
     }
   else
     secname = secname_for_decl (decl);
@@ -17680,10 +17680,10 @@ dw_loc_list (var_loc_list *loc_list, tree decl, int want_address)
 	  && crtl->has_bb_partition
 	  && node == loc_list->last_before_switch)
 	{
-	  bool save_in_cold_section_p = in_cold_section_p;
-	  in_cold_section_p = !first_function_block_is_cold;
+	  bool save_in_cold_section_p = casm->in_cold_section_p;
+	  casm->in_cold_section_p = !first_function_block_is_cold;
 	  secname = secname_for_decl (decl);
-	  in_cold_section_p = save_in_cold_section_p;
+	  casm->in_cold_section_p = save_in_cold_section_p;
 	}
 
       if (range_across_switch)
@@ -27851,7 +27851,7 @@ create_label:
      last_{,postcall_}label so that they are not reused this time.  */
   if (last_var_location_insn == NULL_RTX
       || last_var_location_insn != next_real
-      || last_in_cold_section_p != in_cold_section_p)
+      || last_in_cold_section_p != casm->in_cold_section_p)
     {
       last_label = NULL;
       last_postcall_label = NULL;
@@ -28022,7 +28022,7 @@ create_label:
     }
 
   last_var_location_insn = next_real;
-  last_in_cold_section_p = in_cold_section_p;
+  last_in_cold_section_p = casm->in_cold_section_p;
 }
 
 /* Check whether BLOCK, a lexical block, is nested within OUTER, or is
@@ -28190,7 +28190,7 @@ set_cur_line_info_table (section *sec)
 {
   dw_line_info_table *table;
 
-  if (sec == text_section)
+  if (sec == casm->sections.text)
     table = text_section_line_info;
   else if (sec == cold_text_section)
     {
@@ -28207,7 +28207,7 @@ set_cur_line_info_table (section *sec)
 
       if (crtl->has_bb_partition)
 	{
-	  if (in_cold_section_p)
+	  if (casm->in_cold_section_p)
 	    end_label = crtl->subsections.cold_section_end_label;
 	  else
 	    end_label = crtl->subsections.hot_section_end_label;
@@ -28244,7 +28244,7 @@ dwarf2out_begin_function (tree fun)
 {
   section *sec = function_section (fun);
 
-  if (sec != text_section)
+  if (sec != casm->sections.text)
     have_multiple_function_sections = true;
 
   if (crtl->has_bb_partition && !cold_text_section)
@@ -29373,7 +29373,7 @@ dwarf2out_assembly_start (void)
 			       COLD_TEXT_SECTION_LABEL, 0);
   ASM_GENERATE_INTERNAL_LABEL (cold_end_label, COLD_END_LABEL, 0);
 
-  switch_to_section (text_section);
+  switch_to_section (casm->sections.text);
   ASM_OUTPUT_LABEL (asm_out_file, text_section_label);
 #endif
 
@@ -32080,7 +32080,7 @@ dwarf2out_finish (const char *filename)
     main_comp_unit_die = comp_unit_die ();
 
   /* Output a terminator label for the .text section.  */
-  switch_to_section (text_section);
+  switch_to_section (casm->sections.text);
   targetm.asm_out.internal_label (asm_out_file, TEXT_END_LABEL, 0);
   if (cold_text_section)
     {
@@ -32996,7 +32996,7 @@ dwarf2out_early_finish (const char *filename)
     }
 
   /* Switch back to the text section.  */
-  switch_to_section (text_section);
+  switch_to_section (casm->sections.text);
 }
 
 /* Reset all state within dwarf2out.c so that we can rerun the compiler
diff --git a/gcc/except.c b/gcc/except.c
index 8e905a30939..db6a2b9e14c 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -2906,8 +2906,8 @@ switch_to_exception_section (const char * ARG_UNUSED (fnname))
 {
   section *s;
 
-  if (exception_section)
-    s = exception_section;
+  if (casm->sections.exception)
+    s = casm->sections.exception;
   else
     {
       int flags;
@@ -2924,7 +2924,7 @@ switch_to_exception_section (const char * ARG_UNUSED (fnname))
       else
 	flags = SECTION_WRITE;
 
-      /* Compute the section and cache it into exception_section,
+      /* Compute the section and cache it into casm->sections.exception,
 	 unless it depends on the function name.  */
       if (targetm_common.have_named_sections)
 	{
@@ -2943,12 +2943,12 @@ switch_to_exception_section (const char * ARG_UNUSED (fnname))
 	    }
 	  else
 #endif
-	    exception_section
+	    casm->sections.exception
 	      = s = get_section (".gcc_except_table", flags, NULL);
 	}
       else
-	exception_section
-	  = s = flags == SECTION_WRITE ? data_section : readonly_data_section;
+	casm->sections.exception
+	  = s = flags == SECTION_WRITE ? casm->sections.data: casm->sections.readonly_data;
     }
 
   switch_to_section (s);
diff --git a/gcc/final.c b/gcc/final.c
index ac6892d041c..6515f00875c 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -885,7 +885,7 @@ shorten_branches (rtx_insn *first)
 	  /* ADDR_VECs only take room if read-only data goes into the text
 	     section.  */
 	  if ((JUMP_TABLES_IN_TEXT_SECTION
-	       || readonly_data_section == text_section)
+	       || casm->sections.readonly_data == casm->sections.text)
 	      && table)
 	    {
 	      align_flags alignment = align_flags (ADDR_VEC_ALIGN (table));
@@ -1051,7 +1051,7 @@ shorten_branches (rtx_insn *first)
 	  /* This only takes room if read-only data goes into the text
 	     section.  */
 	  if (JUMP_TABLES_IN_TEXT_SECTION
-	      || readonly_data_section == text_section)
+	      || casm->sections.readonly_data == casm->sections.text)
 	    insn_lengths[uid] = (XVECLEN (body,
 					  GET_CODE (body) == ADDR_DIFF_VEC)
 				 * GET_MODE_SIZE (table->get_data_mode ()));
@@ -1143,7 +1143,7 @@ shorten_branches (rtx_insn *first)
 		 may need to update the alignment of this label.  */
 
 	      if (JUMP_TABLES_IN_TEXT_SECTION
-		  || readonly_data_section == text_section)
+		  || casm->sections.readonly_data == casm->sections.text)
 		{
 		  rtx_jump_table_data *table = jump_table_for_label (label);
 		  if (table)
@@ -1284,7 +1284,7 @@ shorten_branches (rtx_insn *first)
 		      >= GET_MODE_SIZE (table->get_data_mode ())))
 		PUT_MODE (body, vec_mode);
 	      if (JUMP_TABLES_IN_TEXT_SECTION
-		  || readonly_data_section == text_section)
+		  || casm->sections.readonly_data == casm->sections.text)
 		{
 		  insn_lengths[uid]
 		    = (XVECLEN (body, 1)
@@ -1836,7 +1836,7 @@ profile_function (FILE *file ATTRIBUTE_UNUSED)
   if (! NO_PROFILE_COUNTERS)
     {
       int align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE);
-      switch_to_section (data_section);
+      switch_to_section (casm->sections.data);
       ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
       targetm.asm_out.internal_label (file, "LP", current_function_funcdef_no);
       assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, align, 1);
@@ -2189,10 +2189,10 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
 	  if (targetm.asm_out.unwind_emit)
 	    targetm.asm_out.unwind_emit (asm_out_file, insn);
 
-	  in_cold_section_p = !in_cold_section_p;
+	  casm->in_cold_section_p = !casm->in_cold_section_p;
 
-	  gcc_checking_assert (in_cold_section_p);
-	  if (in_cold_section_p)
+	  gcc_checking_assert (casm->in_cold_section_p);
+	  if (casm->in_cold_section_p)
 	    cold_function_name
 	      = clone_function_name (current_function_decl, "cold");
 
@@ -2213,10 +2213,10 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
 	  switch_to_section (current_function_section ());
 	  targetm.asm_out.function_switched_text_sections (asm_out_file,
 							   current_function_decl,
-							   in_cold_section_p);
+							   casm->in_cold_section_p);
 	  /* Emit a label for the split cold section.  Form label name by
 	     suffixing "cold" to the original function's name.  */
-	  if (in_cold_section_p)
+	  if (casm->in_cold_section_p)
 	    {
 #ifdef ASM_DECLARE_COLD_FUNCTION_NAME
 	      ASM_DECLARE_COLD_FUNCTION_NAME (asm_out_file,
@@ -2323,7 +2323,7 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
 
 	      /* Mark this block as output.  */
 	      TREE_ASM_WRITTEN (NOTE_BLOCK (insn)) = 1;
-	      BLOCK_IN_COLD_SECTION_P (NOTE_BLOCK (insn)) = in_cold_section_p;
+	      BLOCK_IN_COLD_SECTION_P (NOTE_BLOCK (insn)) = casm->in_cold_section_p;
 	    }
 	  if (write_symbols == DBX_DEBUG)
 	    {
@@ -2358,7 +2358,7 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
 	      if (!DECL_IGNORED_P (current_function_decl))
 		debug_hooks->end_block (high_block_linenum, n);
 	      gcc_assert (BLOCK_IN_COLD_SECTION_P (NOTE_BLOCK (insn))
-			  == in_cold_section_p);
+			  == casm->in_cold_section_p);
 	    }
 	  if (write_symbols == DBX_DEBUG)
 	    {
diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c
index 32ba5be42b2..c383605f813 100644
--- a/gcc/ggc-common.c
+++ b/gcc/ggc-common.c
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "hosthooks.h"
 #include "plugin.h"
 #include "options.h"
+#include "output.h"
 
 /* When true, protect the contents of the identifier hash table.  */
 bool ggc_protect_identifiers = true;
@@ -589,6 +590,9 @@ gt_pch_restore (FILE *f)
   struct mmap_info mmi;
   int result;
 
+  /* Hide ASM state object as we don't want it to be streamed.  */
+  FILE *saved_casm_out_file = casm->out_file;
+
   /* Delete any deletable objects.  This makes ggc_pch_read much
      faster, as it can be sure that no GCable objects remain other
      than the ones just read in.  */
@@ -629,6 +633,8 @@ gt_pch_restore (FILE *f)
   ggc_pch_read (f, mmi.preferred_base);
 
   gt_pch_restore_stringpool ();
+
+  casm->out_file = saved_casm_out_file;
 }
 
 /* Default version of HOST_HOOKS_GT_PCH_GET_ADDRESS when mmap is not present.
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index 48c72377778..a25a4f84eba 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -803,9 +803,9 @@ lhd_begin_section (const char *name)
 
   /* Save the old section so we can restore it in lto_end_asm_section.  */
   gcc_assert (!saved_section);
-  saved_section = in_section;
+  saved_section = casm->in_section;
   if (!saved_section)
-    saved_section = text_section;
+    saved_section = casm->sections.text;
 
   /* Create a new section and switch to it.  */
   section = get_section (name, SECTION_DEBUG | SECTION_EXCLUDE, NULL, true);
diff --git a/gcc/output.h b/gcc/output.h
index 73ca4545f4f..3fdc559fec5 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -313,9 +313,78 @@ extern rtx_sequence *final_sequence;
 
 /* File in which assembler code is being written.  */
 
-#ifdef BUFSIZ
-extern FILE *asm_out_file;
-#endif
+struct section_hasher : ggc_ptr_hash<section>
+{
+  typedef const char *compare_type;
+
+  static hashval_t hash (section *);
+  static bool equal (section *, const char *);
+};
+
+/* Assembly output state.  */
+
+struct GTY(()) asm_out_state
+{
+  asm_out_state (): out_file (NULL), in_section (NULL),
+    sections ({}), anchor_labelno (0), in_cold_section_p (false)
+  {
+    section_htab = hash_table<section_hasher>::create_ggc (31);
+  }
+
+  /* Assembly output stream.  */
+  FILE * GTY((skip)) out_file;
+
+  /* Hash table of named sections.  */
+  hash_table<section_hasher> *section_htab;
+
+  /* asm_out_file's current section.  This is NULL if no section has yet
+     been selected or if we lose track of what the current section is.  */
+  section *in_section;
+
+  /* Well-known sections, each one associated with some sort of *_ASM_OP.  */
+  struct
+  {
+    section *text;
+    section *data;
+    section *readonly_data;
+    section *sdata;
+    section *ctors;
+    section *dtors;
+    section *bss;
+    section *sbss;
+
+    /* Various forms of common section.  All are guaranteed to be nonnull.  */
+    section *tls_comm;
+    section *comm;
+    section *lcomm;
+
+    /* A SECTION_NOSWITCH section used for declaring global BSS variables.
+       May be null.  */
+    section *bss_noswitch;
+
+    /* The section that holds the main exception table, when known.  The section
+       is set either by the target's init_sections hook or by the first call to
+       switch_to_exception_section.  */
+    section *exception;
+
+    /* The section that holds the DWARF2 frame unwind information, when known.
+       The section is set either by the target's init_sections hook or by the
+       first call to switch_to_eh_frame_section.  */
+    section *eh_frame;
+  } sections;
+
+  /* The next number to use for internal anchor labels.  */
+  int anchor_labelno;
+
+  /* True if code for the current function is currently being directed
+     at the cold section.  */
+  bool in_cold_section_p;
+};
+
+extern GTY(()) asm_out_state *casm;
+
+/* Helper macro for commonly used accesses.  */
+#define asm_out_file casm->out_file
 
 /* The first global object in the file.  */
 extern const char *first_global_object_name;
@@ -511,24 +580,6 @@ union GTY ((desc ("SECTION_STYLE (&(%h))"), for_user)) section {
 struct object_block;
 
 /* Special well-known sections.  */
-extern GTY(()) section *text_section;
-extern GTY(()) section *data_section;
-extern GTY(()) section *readonly_data_section;
-extern GTY(()) section *sdata_section;
-extern GTY(()) section *ctors_section;
-extern GTY(()) section *dtors_section;
-extern GTY(()) section *bss_section;
-extern GTY(()) section *sbss_section;
-extern GTY(()) section *exception_section;
-extern GTY(()) section *eh_frame_section;
-extern GTY(()) section *tls_comm_section;
-extern GTY(()) section *comm_section;
-extern GTY(()) section *lcomm_section;
-extern GTY(()) section *bss_noswitch_section;
-
-extern GTY(()) section *in_section;
-extern GTY(()) bool in_cold_section_p;
-
 extern section *get_unnamed_section (unsigned int, void (*) (const void *),
 				     const void *);
 extern section *get_section (const char *, unsigned int, tree,
diff --git a/gcc/run-rtl-passes.c b/gcc/run-rtl-passes.c
index 37a02813f22..e49b75bf7f9 100644
--- a/gcc/run-rtl-passes.c
+++ b/gcc/run-rtl-passes.c
@@ -46,7 +46,7 @@ run_rtl_passes (char *initial_pass_name)
   max_regno = max_reg_num ();
 
   /* cgraphunit.c normally handles this.  */
-  switch_to_section (text_section);
+  switch_to_section (casm->sections.text);
   (*debug_hooks->assembly_start) ();
 
   if (initial_pass_name)
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index c9b5208853d..68660186ec5 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -1962,7 +1962,7 @@ default_print_patchable_function_entry_1 (FILE *file,
     {
       char buf[256];
       static int patch_area_number;
-      section *previous_section = in_section;
+      section *previous_section = casm->in_section;
       const char *asm_op = integer_asm_op (POINTER_SIZE_UNITS, false);
 
       gcc_assert (asm_op != NULL);
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 14d1335e79e..fcc7b39f624 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -172,7 +172,8 @@ const char *user_label_prefix;
 /* Output files for assembler code (real compiler output)
    and debugging dumps.  */
 
-FILE *asm_out_file;
+asm_out_state *casm;
+
 FILE *aux_info_file;
 FILE *callgraph_info_file = NULL;
 static bitmap callgraph_info_external_printed;
@@ -552,13 +553,13 @@ compile_file (void)
   if (flag_generate_lto && !flag_fat_lto_objects)
     {
 #if defined ASM_OUTPUT_ALIGNED_DECL_COMMON
-      ASM_OUTPUT_ALIGNED_DECL_COMMON (asm_out_file, NULL_TREE, "__gnu_lto_slim",
+      ASM_OUTPUT_ALIGNED_DECL_COMMON (casm->out_file, NULL_TREE, "__gnu_lto_slim",
 				      HOST_WIDE_INT_1U, 8);
 #elif defined ASM_OUTPUT_ALIGNED_COMMON
-      ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, "__gnu_lto_slim",
+      ASM_OUTPUT_ALIGNED_COMMON (casm->out_file, "__gnu_lto_slim",
 				 HOST_WIDE_INT_1U, 8);
 #else
-      ASM_OUTPUT_COMMON (asm_out_file, "__gnu_lto_slim",
+      ASM_OUTPUT_COMMON (casm->out_file, "__gnu_lto_slim",
 			 HOST_WIDE_INT_1U,
 			 HOST_WIDE_INT_1U);
 #endif
@@ -696,7 +697,7 @@ static void
 init_asm_output (const char *name)
 {
   if (name == NULL && asm_file_name == 0)
-    asm_out_file = stdout;
+    casm->out_file = stdout;
   else
     {
       if (asm_file_name == 0)
@@ -710,17 +711,17 @@ init_asm_output (const char *name)
 	  asm_file_name = dumpname;
 	}
       if (!strcmp (asm_file_name, "-"))
-	asm_out_file = stdout;
+	casm->out_file = stdout;
       else if (!canonical_filename_eq (asm_file_name, name)
 	       || !strcmp (asm_file_name, HOST_BIT_BUCKET))
-	asm_out_file = fopen (asm_file_name, "w");
+	casm->out_file = fopen (asm_file_name, "w");
       else
 	/* Use UNKOWN_LOCATION to prevent gcc from printing the first
 	   line in the current file. */
 	fatal_error (UNKNOWN_LOCATION,
 		     "input file %qs is the same as output file",
 		     asm_file_name);
-      if (asm_out_file == 0)
+      if (casm->out_file == 0)
 	fatal_error (UNKNOWN_LOCATION,
 		     "cannot open %qs for writing: %m", asm_file_name);
     }
@@ -747,14 +748,14 @@ init_asm_output (const char *name)
 
       if (flag_verbose_asm)
 	{
-	  print_version (asm_out_file, ASM_COMMENT_START, true);
-	  fputs (ASM_COMMENT_START, asm_out_file);
-	  fputs (" options passed: ", asm_out_file);
+	  print_version (casm->out_file, ASM_COMMENT_START, true);
+	  fputs (ASM_COMMENT_START, casm->out_file);
+	  fputs (" options passed: ", casm->out_file);
 	  char *cmdline = gen_command_line_string (save_decoded_options,
 						   save_decoded_options_count);
-	  fputs (cmdline, asm_out_file);
+	  fputs (cmdline, casm->out_file);
 	  free (cmdline);
-	  fputc ('\n', asm_out_file);
+	  fputc ('\n', casm->out_file);
 	}
     }
 }
@@ -1112,6 +1113,9 @@ general_init (const char *argv0, bool init_signals)
 
   symtab = new (ggc_alloc <symbol_table> ()) symbol_table ();
 
+  /* Initialize ASM out state.  */
+  casm = new (ggc_alloc<asm_out_state> ()) asm_out_state ();
+
   statistics_early_init ();
   debuginfo_early_init ();
 }
@@ -2083,13 +2087,13 @@ finalize (bool no_backend)
      whether fclose returns an error, since the pages might still be on the
      buffer chain while the file is open.  */
 
-  if (asm_out_file)
+  if (casm->out_file)
     {
-      if (ferror (asm_out_file) != 0)
+      if (ferror (casm->out_file) != 0)
 	fatal_error (input_location, "error writing to %s: %m", asm_file_name);
-      if (fclose (asm_out_file) != 0)
+      if (fclose (casm->out_file) != 0)
 	fatal_error (input_location, "error closing %s: %m", asm_file_name);
-      asm_out_file = NULL;
+      casm->out_file = NULL;
     }
 
   if (stack_usage_file)
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 53cf6dea3f3..61064df9dc8 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -130,43 +130,6 @@ static void mark_weak (tree);
 static void output_constant_pool (const char *, tree);
 static void handle_vtv_comdat_section (section *, const_tree);
 \f
-/* Well-known sections, each one associated with some sort of *_ASM_OP.  */
-section *text_section;
-section *data_section;
-section *readonly_data_section;
-section *sdata_section;
-section *ctors_section;
-section *dtors_section;
-section *bss_section;
-section *sbss_section;
-
-/* Various forms of common section.  All are guaranteed to be nonnull.  */
-section *tls_comm_section;
-section *comm_section;
-section *lcomm_section;
-
-/* A SECTION_NOSWITCH section used for declaring global BSS variables.
-   May be null.  */
-section *bss_noswitch_section;
-
-/* The section that holds the main exception table, when known.  The section
-   is set either by the target's init_sections hook or by the first call to
-   switch_to_exception_section.  */
-section *exception_section;
-
-/* The section that holds the DWARF2 frame unwind information, when known.
-   The section is set either by the target's init_sections hook or by the
-   first call to switch_to_eh_frame_section.  */
-section *eh_frame_section;
-
-/* asm_out_file's current section.  This is NULL if no section has yet
-   been selected or if we lose track of what the current section is.  */
-section *in_section;
-
-/* True if code for the current function is currently being directed
-   at the cold section.  */
-bool in_cold_section_p;
-
 /* The following global holds the "function name" for the code in the
    cold section of a function, if hot/cold function splitting is enabled
    and there was actually code that went into the cold section.  A
@@ -181,17 +144,6 @@ static GTY(()) section *unnamed_sections;
 #define IN_NAMED_SECTION(DECL) \
   (VAR_OR_FUNCTION_DECL_P (DECL) && DECL_SECTION_NAME (DECL) != NULL)
 
-struct section_hasher : ggc_ptr_hash<section>
-{
-  typedef const char *compare_type;
-
-  static hashval_t hash (section *);
-  static bool equal (section *, const char *);
-};
-
-/* Hash table of named sections.  */
-static GTY(()) hash_table<section_hasher> *section_htab;
-
 struct object_block_hasher : ggc_ptr_hash<object_block>
 {
   typedef const section *compare_type;
@@ -203,9 +155,6 @@ struct object_block_hasher : ggc_ptr_hash<object_block>
 /* A table of object_blocks, indexed by section.  */
 static GTY(()) hash_table<object_block_hasher> *object_block_htab;
 
-/* The next number to use for internal anchor labels.  */
-static GTY(()) int anchor_labelno;
-
 /* A pool of constants that can be shared between functions.  */
 static GTY(()) struct rtx_constant_pool *shared_constant_pool;
 
@@ -294,8 +243,8 @@ get_section (const char *name, unsigned int flags, tree decl,
 {
   section *sect, **slot;
 
-  slot = section_htab->find_slot_with_hash (name, htab_hash_string (name),
-					    INSERT);
+  slot = casm->section_htab->find_slot_with_hash (name, htab_hash_string (name),
+						  INSERT);
   flags |= SECTION_NAMED;
   if (decl != nullptr
       && DECL_P (decl)
@@ -510,7 +459,7 @@ asm_output_aligned_bss (FILE *file, tree decl ATTRIBUTE_UNUSED,
 			const char *name, unsigned HOST_WIDE_INT size,
 			int align)
 {
-  switch_to_section (bss_section);
+  switch_to_section (casm->sections.bss);
   ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
 #ifdef ASM_DECLARE_OBJECT_NAME
   last_assemble_variable_decl = decl;
@@ -527,7 +476,7 @@ asm_output_aligned_bss (FILE *file, tree decl ATTRIBUTE_UNUSED,
 #endif /* BSS_SECTION_ASM_OP */
 
 #ifndef USE_SELECT_SECTION_FOR_FUNCTIONS
-/* Return the hot section for function DECL.  Return text_section for
+/* Return the hot section for function DECL.  Return casm->sections.text for
    null DECLs.  */
 
 static section *
@@ -538,7 +487,7 @@ hot_function_section (tree decl)
       && targetm_common.have_named_sections)
     return get_named_section (decl, NULL, 0);
   else
-    return text_section;
+    return casm->sections.text;
 }
 #endif
 
@@ -718,7 +667,7 @@ function_section (tree decl)
 section *
 current_function_section (void)
 {
-  return function_section_1 (current_function_decl, in_cold_section_p);
+  return function_section_1 (current_function_decl, casm->in_cold_section_p);
 }
 
 /* Tell assembler to switch to unlikely-to-be-executed text section.  */
@@ -746,7 +695,7 @@ unlikely_text_section_p (section *sect)
 void
 switch_to_other_text_partition (void)
 {
-  in_cold_section_p = !in_cold_section_p;
+  casm->in_cold_section_p = !casm->in_cold_section_p;
   switch_to_section (current_function_section ());
 }
 
@@ -831,7 +780,7 @@ default_function_rodata_section (tree decl, bool relocatable)
   if (relocatable)
     return get_section (sname, flags, decl);
   else
-    return readonly_data_section;
+    return casm->sections.readonly_data;
 }
 
 /* Return the read-only data section associated with function DECL
@@ -841,7 +790,7 @@ default_function_rodata_section (tree decl, bool relocatable)
 section *
 default_no_function_rodata_section (tree, bool)
 {
-  return readonly_data_section;
+  return casm->sections.readonly_data;
 }
 
 /* A subroutine of mergeable_string_section and mergeable_constant_section.  */
@@ -890,7 +839,7 @@ mergeable_string_section (tree decl ATTRIBUTE_UNUSED,
 	    align = modesize;
 
 	  if (!HAVE_LD_ALIGNED_SHF_MERGE && align > 8)
-	    return readonly_data_section;
+	    return casm->sections.readonly_data;
 
 	  str = TREE_STRING_POINTER (decl);
 	  unit = GET_MODE_SIZE (mode);
@@ -914,7 +863,7 @@ mergeable_string_section (tree decl ATTRIBUTE_UNUSED,
 	}
     }
 
-  return readonly_data_section;
+  return casm->sections.readonly_data;
 }
 
 /* Return the section to use for constant merging.  */
@@ -940,7 +889,7 @@ mergeable_constant_section (machine_mode mode ATTRIBUTE_UNUSED,
       flags |= (align / 8) | SECTION_MERGE;
       return get_section (name, flags, NULL);
     }
-  return readonly_data_section;
+  return casm->sections.readonly_data;
 }
 \f
 /* Given NAME, a putative register name, discard any customary prefixes.  */
@@ -1253,9 +1202,9 @@ get_variable_section (tree decl, bool prefer_noswitch_p)
       gcc_assert (DECL_SECTION_NAME (decl) == NULL
 		  && ADDR_SPACE_GENERIC_P (as));
       if (DECL_THREAD_LOCAL_P (decl))
-	return tls_comm_section;
+	return casm->sections.tls_comm;
       else if (TREE_PUBLIC (decl) && bss_initializer_p (decl))
-	return comm_section;
+	return casm->sections.comm;
     }
 
   reloc = compute_reloc_for_var (decl);
@@ -1285,9 +1234,9 @@ get_variable_section (tree decl, bool prefer_noswitch_p)
       if (!TREE_PUBLIC (decl)
 	  && !((flag_sanitize & SANITIZE_ADDRESS)
 	       && asan_protect_global (decl)))
-	return lcomm_section;
-      if (bss_noswitch_section)
-	return bss_noswitch_section;
+	return casm->sections.lcomm;
+      if (casm->sections.bss_noswitch)
+	return casm->sections.bss_noswitch;
     }
 
   return targetm.asm_out.select_section (decl, reloc,
@@ -1733,7 +1682,7 @@ void
 default_dtor_section_asm_out_destructor (rtx symbol,
 					 int priority ATTRIBUTE_UNUSED)
 {
-  assemble_addr_to_section (symbol, dtors_section);
+  assemble_addr_to_section (symbol, casm->sections.dtors);
 }
 #endif
 
@@ -1756,7 +1705,7 @@ void
 default_ctor_section_asm_out_constructor (rtx symbol,
 					  int priority ATTRIBUTE_UNUSED)
 {
-  assemble_addr_to_section (symbol, ctors_section);
+  assemble_addr_to_section (symbol, casm->sections.ctors);
 }
 #endif
 \f
@@ -1824,7 +1773,7 @@ decide_function_section (tree decl)
 				      == NODE_FREQUENCY_UNLIKELY_EXECUTED);
     }
 
-  in_cold_section_p = first_function_block_is_cold;
+  casm->in_cold_section_p = first_function_block_is_cold;
 }
 
 /* Get the function's name, as described by its RTL.  This may be
@@ -1900,13 +1849,13 @@ assemble_start_function (tree decl, const char *fnname)
       if (!cfun->is_thunk
 	  && BB_PARTITION (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb) == BB_COLD_PARTITION)
 	{
-	  switch_to_section (text_section);
+	  switch_to_section (casm->sections.text);
 	  assemble_align (align);
 	  ASM_OUTPUT_LABEL (asm_out_file, crtl->subsections.hot_section_label);
 	  hot_label_written = true;
 	  first_function_block_is_cold = true;
 	}
-      in_cold_section_p = first_function_block_is_cold;
+      casm->in_cold_section_p = first_function_block_is_cold;
     }
 
 
@@ -2020,7 +1969,7 @@ assemble_end_function (tree decl, const char *fnname ATTRIBUTE_UNUSED)
     {
       section *save_text_section;
 
-      save_text_section = in_section;
+      save_text_section = casm->in_section;
       switch_to_section (unlikely_text_section ());
 #ifdef ASM_DECLARE_COLD_FUNCTION_SIZE
       if (cold_function_name != NULL_TREE)
@@ -2030,7 +1979,7 @@ assemble_end_function (tree decl, const char *fnname ATTRIBUTE_UNUSED)
 #endif
       ASM_OUTPUT_LABEL (asm_out_file, crtl->subsections.cold_section_end_label);
       if (first_function_block_is_cold)
-	switch_to_section (text_section);
+	switch_to_section (casm->sections.text);
       else
 	switch_to_section (function_section (decl));
       ASM_OUTPUT_LABEL (asm_out_file, crtl->subsections.hot_section_end_label);
@@ -2050,7 +1999,7 @@ assemble_zeros (unsigned HOST_WIDE_INT size)
 #ifdef ASM_NO_SKIP_IN_TEXT
   /* The `space' pseudo in the text section outputs nop insns rather than 0s,
      so we must output 0s explicitly in the text section.  */
-  if (ASM_NO_SKIP_IN_TEXT && (in_section->common.flags & SECTION_CODE) != 0)
+  if (ASM_NO_SKIP_IN_TEXT && (casm->in_section->common.flags & SECTION_CODE) != 0)
     {
       unsigned HOST_WIDE_INT i;
       for (i = 0; i < size; i++)
@@ -2097,7 +2046,7 @@ assemble_string (const char *p, int size)
 }
 
 \f
-/* A noswitch_section_callback for lcomm_section.  */
+/* A noswitch_section_callback for casm->sections.lcomm.  */
 
 static bool
 emit_local (tree decl ATTRIBUTE_UNUSED,
@@ -2120,7 +2069,7 @@ emit_local (tree decl ATTRIBUTE_UNUSED,
 #endif
 }
 
-/* A noswitch_section_callback for bss_noswitch_section.  */
+/* A noswitch_section_callback for casm->sections.bss_noswitch.  */
 
 #if defined ASM_OUTPUT_ALIGNED_BSS
 static bool
@@ -2135,7 +2084,7 @@ emit_bss (tree decl ATTRIBUTE_UNUSED,
 }
 #endif
 
-/* A noswitch_section_callback for comm_section.  */
+/* A noswitch_section_callback for casm->sections.comm.  */
 
 static bool
 emit_common (tree decl ATTRIBUTE_UNUSED,
@@ -2157,7 +2106,7 @@ emit_common (tree decl ATTRIBUTE_UNUSED,
 #endif
 }
 
-/* A noswitch_section_callback for tls_comm_section.  */
+/* A noswitch_section_callback for casm->sections.tls_comm.  */
 
 static bool
 emit_tls_common (tree decl ATTRIBUTE_UNUSED,
@@ -2774,7 +2723,7 @@ assemble_trampoline_template (void)
 #ifdef TRAMPOLINE_SECTION
   switch_to_section (TRAMPOLINE_SECTION);
 #else
-  switch_to_section (readonly_data_section);
+  switch_to_section (casm->sections.readonly_data);
 #endif
 
   /* Write the assembler code to define one.  */
@@ -4192,8 +4141,8 @@ output_constant_pool_1 (class constant_descriptor_rtx *desc,
   /* Make sure all constants in SECTION_MERGE and not SECTION_STRINGS
      sections have proper size.  */
   if (align > GET_MODE_BITSIZE (desc->mode)
-      && in_section
-      && (in_section->common.flags & SECTION_MERGE))
+      && casm->in_section
+      && (casm->in_section->common.flags & SECTION_MERGE))
     assemble_align (align);
 
 #ifdef ASM_OUTPUT_SPECIAL_POOL_ENTRY
@@ -6596,70 +6545,69 @@ make_decl_one_only (tree decl, tree comdat_group)
 void
 init_varasm_once (void)
 {
-  section_htab = hash_table<section_hasher>::create_ggc (31);
   object_block_htab = hash_table<object_block_hasher>::create_ggc (31);
   const_desc_htab = hash_table<tree_descriptor_hasher>::create_ggc (1009);
 
   shared_constant_pool = create_constant_pool ();
 
 #ifdef TEXT_SECTION_ASM_OP
-  text_section = get_unnamed_section (SECTION_CODE, output_section_asm_op,
+  casm->sections.text = get_unnamed_section (SECTION_CODE, output_section_asm_op,
 				      TEXT_SECTION_ASM_OP);
 #endif
 
 #ifdef DATA_SECTION_ASM_OP
-  data_section = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
-				      DATA_SECTION_ASM_OP);
+  casm->sections.data = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
+					     DATA_SECTION_ASM_OP);
 #endif
 
 #ifdef SDATA_SECTION_ASM_OP
-  sdata_section = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
+  casm->sections.sdata = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
 				       SDATA_SECTION_ASM_OP);
 #endif
 
 #ifdef READONLY_DATA_SECTION_ASM_OP
-  readonly_data_section = get_unnamed_section (0, output_section_asm_op,
-					       READONLY_DATA_SECTION_ASM_OP);
+  casm->sections.readonly_data = get_unnamed_section (0, output_section_asm_op,
+						      READONLY_DATA_SECTION_ASM_OP);
 #endif
 
 #ifdef CTORS_SECTION_ASM_OP
-  ctors_section = get_unnamed_section (0, output_section_asm_op,
+  casm->sections.ctors = get_unnamed_section (0, output_section_asm_op,
 				       CTORS_SECTION_ASM_OP);
 #endif
 
 #ifdef DTORS_SECTION_ASM_OP
-  dtors_section = get_unnamed_section (0, output_section_asm_op,
+  casm->sections.dtors = get_unnamed_section (0, output_section_asm_op,
 				       DTORS_SECTION_ASM_OP);
 #endif
 
 #ifdef BSS_SECTION_ASM_OP
-  bss_section = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
-				     output_section_asm_op,
-				     BSS_SECTION_ASM_OP);
+  casm->sections.bss = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
+					    output_section_asm_op,
+					    BSS_SECTION_ASM_OP);
 #endif
 
 #ifdef SBSS_SECTION_ASM_OP
-  sbss_section = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
+  casm->sections.sbss = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
 				      output_section_asm_op,
 				      SBSS_SECTION_ASM_OP);
 #endif
 
-  tls_comm_section = get_noswitch_section (SECTION_WRITE | SECTION_BSS
-					   | SECTION_COMMON, emit_tls_common);
-  lcomm_section = get_noswitch_section (SECTION_WRITE | SECTION_BSS
-					| SECTION_COMMON, emit_local);
-  comm_section = get_noswitch_section (SECTION_WRITE | SECTION_BSS
-				       | SECTION_COMMON, emit_common);
+  casm->sections.tls_comm = get_noswitch_section (SECTION_WRITE | SECTION_BSS
+						  | SECTION_COMMON, emit_tls_common);
+  casm->sections.lcomm = get_noswitch_section (SECTION_WRITE | SECTION_BSS
+					       | SECTION_COMMON, emit_local);
+  casm->sections.comm = get_noswitch_section (SECTION_WRITE | SECTION_BSS
+					      | SECTION_COMMON, emit_common);
 
 #if defined ASM_OUTPUT_ALIGNED_BSS
-  bss_noswitch_section = get_noswitch_section (SECTION_WRITE | SECTION_BSS,
-					       emit_bss);
+  casm->sections.bss_noswitch = get_noswitch_section (SECTION_WRITE | SECTION_BSS,
+						      emit_bss);
 #endif
 
   targetm.asm_out.init_sections ();
 
-  if (readonly_data_section == NULL)
-    readonly_data_section = text_section;
+  if (casm->sections.readonly_data == NULL)
+    casm->sections.readonly_data = casm->sections.text;
 
 #ifdef ASM_OUTPUT_EXTERNAL
   pending_assemble_externals_set = new hash_set<tree>;
@@ -6784,13 +6732,13 @@ default_section_type_flags (tree decl, const char *name, int reloc)
 }
 
 /* Return true if the target supports some form of global BSS,
-   either through bss_noswitch_section, or by selecting a BSS
+   either through casm->sections.bss_noswitch, or by selecting a BSS
    section in TARGET_ASM_SELECT_SECTION.  */
 
 bool
 have_global_bss_p (void)
 {
-  return bss_noswitch_section || targetm.have_switchable_bss_sections;
+  return casm->sections.bss_noswitch || targetm.have_switchable_bss_sections;
 }
 
 /* Output assembly to switch to section NAME with attribute FLAGS.
@@ -6952,7 +6900,7 @@ default_select_section (tree decl, int reloc,
   if (DECL_P (decl))
     {
       if (decl_readonly_section (decl, reloc))
-	return readonly_data_section;
+	return casm->sections.readonly_data;
     }
   else if (TREE_CODE (decl) == CONSTRUCTOR)
     {
@@ -6960,14 +6908,14 @@ default_select_section (tree decl, int reloc,
 	     || !TREE_READONLY (decl)
 	     || TREE_SIDE_EFFECTS (decl)
 	     || !TREE_CONSTANT (decl)))
-	return readonly_data_section;
+	return casm->sections.readonly_data;
     }
   else if (TREE_CODE (decl) == STRING_CST)
-    return readonly_data_section;
+    return casm->sections.readonly_data;
   else if (! (flag_pic && reloc))
-    return readonly_data_section;
+    return casm->sections.readonly_data;
 
-  return data_section;
+  return casm->sections.data;
 }
 
 enum section_category
@@ -7106,7 +7054,7 @@ default_elf_select_section (tree decl, int reloc,
       /* We're not supposed to be called on FUNCTION_DECLs.  */
       gcc_unreachable ();
     case SECCAT_RODATA:
-      return readonly_data_section;
+      return casm->sections.readonly_data;
     case SECCAT_RODATA_MERGE_STR:
       return mergeable_string_section (decl, align, 0);
     case SECCAT_RODATA_MERGE_STR_INIT:
@@ -7122,7 +7070,7 @@ default_elf_select_section (tree decl, int reloc,
 	  sname = ".persistent";
 	  break;
 	}
-      return data_section;
+      return casm->sections.data;
     case SECCAT_DATA_REL:
       sname = ".data.rel";
       break;
@@ -7147,8 +7095,8 @@ default_elf_select_section (tree decl, int reloc,
 	  sname = ".noinit";
 	  break;
 	}
-      if (bss_section)
-	return bss_section;
+      if (casm->sections.bss)
+	return casm->sections.bss;
       sname = ".bss";
       break;
     case SECCAT_SBSS:
@@ -7298,9 +7246,9 @@ default_select_rtx_section (machine_mode mode ATTRIBUTE_UNUSED,
 			    unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
 {
   if (compute_reloc_for_rtx (x) & targetm.asm_out.reloc_rw_mask ())
-    return data_section;
+    return casm->sections.data;
   else
-    return readonly_data_section;
+    return casm->sections.readonly_data;
 }
 
 section *
@@ -7818,13 +7766,13 @@ switch_to_section (section *new_section, tree decl)
 		  "%qD was declared here", used_decl);
 	}
     }
-  else if (in_section == new_section)
+  else if (casm->in_section == new_section)
     return;
 
   if (new_section->common.flags & SECTION_FORGET)
-    in_section = NULL;
+    casm->in_section = NULL;
   else
-    in_section = new_section;
+    casm->in_section = new_section;
 
   switch (SECTION_STYLE (new_section))
     {
@@ -8000,7 +7948,7 @@ get_section_anchor (struct object_block *block, HOST_WIDE_INT offset,
     }
 
   /* Create a new anchor with a unique label.  */
-  ASM_GENERATE_INTERNAL_LABEL (label, "LANCHOR", anchor_labelno++);
+  ASM_GENERATE_INTERNAL_LABEL (label, "LANCHOR", casm->anchor_labelno++);
   anchor = create_block_symbol (ggc_strdup (label), block, offset);
   SYMBOL_REF_FLAGS (anchor) |= SYMBOL_FLAG_LOCAL | SYMBOL_FLAG_ANCHOR;
   SYMBOL_REF_FLAGS (anchor) |= model << SYMBOL_FLAG_TLS_SHIFT;
@@ -8469,7 +8417,7 @@ handle_vtv_comdat_section (section *sect, const_tree decl ATTRIBUTE_UNUSED)
 				 sect->named.common.flags
 				 | SECTION_LINKONCE,
 				 DECL_NAME (decl));
-  in_section = sect;
+  casm->in_section = sect;
 #else
   /* Neither OBJECT_FORMAT_PE, nor OBJECT_FORMAT_COFF is set here.
      Therefore the following check is used.
@@ -8495,7 +8443,7 @@ handle_vtv_comdat_section (section *sect, const_tree decl ATTRIBUTE_UNUSED)
 				     sect->named.common.flags
 				     | SECTION_LINKONCE,
 				     DECL_NAME (decl));
-      in_section = sect;
+      casm->in_section = sect;
     }
   else
     switch_to_section (sect);
diff --git a/gcc/vmsdbgout.c b/gcc/vmsdbgout.c
index 05fadce075e..48e1ca9fb25 100644
--- a/gcc/vmsdbgout.c
+++ b/gcc/vmsdbgout.c
@@ -1583,7 +1583,7 @@ vmsdbgout_finish (const char *filename ATTRIBUTE_UNUSED)
     return;
 
   /* Output a terminator label for the .text section.  */
-  switch_to_section (text_section);
+  switch_to_section (casm->sections.text);
   targetm.asm_out.internal_label (asm_out_file, TEXT_END_LABEL, 0);
 
   /* Output debugging information.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 1/N] Rename asm_out_file function arguments.
  2021-09-10  9:31 [PATCH][RFC] Come up with casm state Martin Liška
@ 2021-09-16 10:00 ` Martin Liška
  2021-09-16 13:52   ` Iain Sandoe
  2021-10-20 11:57   ` Martin Liška
  2021-09-16 10:00 ` [PATCH 2/N] Do not hide asm_out_file in ASM_OUTPUT_ASCII Martin Liška
  2021-09-16 13:12 ` [PATCH 3/N] Come up with casm global state Martin Liška
  2 siblings, 2 replies; 30+ messages in thread
From: Martin Liška @ 2021-09-16 10:00 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 368 bytes --]

As preparation for a new global object that will encapsulate
asm_out_file, we would need to live with a macro that will
define asm_out_file as casm->out_file and thus the name
can't be used in function arguments.

I've built all cross compilers with the change and
can bootstrap on x86_64-linux-gnu and survives regression tests.

Ready to be installed?
Thanks,
Martin

[-- Attachment #2: 0001-Rename-asm_out_file-function-arguments.patch --]
[-- Type: text/x-patch, Size: 27500 bytes --]

From 58c7c7f5ecf45f2f227f0792c9fdd24d4a7b59a6 Mon Sep 17 00:00:00 2001
From: Martin Liska <mliska@suse.cz>
Date: Wed, 15 Sep 2021 15:49:02 +0200
Subject: [PATCH 1/3] Rename asm_out_file function arguments.

As preparation for a new global object that will encapsulate
asm_out_file, we would need to live with a macro that will
define asm_out_file as casm->out_file and thus the name
can't be used in function arguments.

gcc/ChangeLog:

	* config/arm/arm.c (arm_unwind_emit_sequence): Do not declare
	already declared global variable.
	(arm_unwind_emit_set): Use out_file as function argument.
	(arm_unwind_emit): Likewise.
	* config/darwin.c (machopic_output_data_section_indirection): Likewise.
	(machopic_output_stub_indirection): Likewise.
	(machopic_output_indirection): Likewise.
	(machopic_finish): Likewise.
	* config/i386/i386.c (ix86_asm_output_function_label): Likewise.
	* config/i386/winnt.c (i386_pe_seh_unwind_emit): Likewise.
	* config/ia64/ia64.c (process_epilogue): Likewise.
	(process_cfa_adjust_cfa): Likewise.
	(process_cfa_register): Likewise.
	(process_cfa_offset): Likewise.
	(ia64_asm_unwind_emit): Likewise.
	* config/s390/s390.c (s390_asm_output_function_label): Likewise.
---
 gcc/config/arm/arm.c    | 46 ++++++++++++++---------------
 gcc/config/darwin.c     | 34 +++++++++++-----------
 gcc/config/i386/i386.c  | 12 ++++----
 gcc/config/i386/winnt.c | 12 ++++----
 gcc/config/ia64/ia64.c  | 64 ++++++++++++++++++++---------------------
 gcc/config/s390/s390.c  | 46 ++++++++++++++---------------
 6 files changed, 106 insertions(+), 108 deletions(-)

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 6c6e77fab66..1a7b47d236e 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -844,8 +844,6 @@ static char *         minipool_startobj;
    will be conditionalised if possible.  */
 static int max_insns_skipped = 5;
 
-extern FILE * asm_out_file;
-
 /* True if we are currently building a constant table.  */
 int making_const_table;
 
@@ -29452,7 +29450,7 @@ arm_dwarf_register_span (rtx rtl)
    epilogue.  */
 
 static void
-arm_unwind_emit_sequence (FILE * asm_out_file, rtx p)
+arm_unwind_emit_sequence (FILE * out_file, rtx p)
 {
   int i;
   HOST_WIDE_INT offset;
@@ -29496,14 +29494,14 @@ arm_unwind_emit_sequence (FILE * asm_out_file, rtx p)
 	padlast = offset - 4;
       gcc_assert (padlast == 0 || padlast == 4);
       if (padlast == 4)
-	fprintf (asm_out_file, "\t.pad #4\n");
+	fprintf (out_file, "\t.pad #4\n");
       reg_size = 4;
-      fprintf (asm_out_file, "\t.save {");
+      fprintf (out_file, "\t.save {");
     }
   else if (IS_VFP_REGNUM (reg))
     {
       reg_size = 8;
-      fprintf (asm_out_file, "\t.vsave {");
+      fprintf (out_file, "\t.vsave {");
     }
   else
     /* Unknown register type.  */
@@ -29529,13 +29527,13 @@ arm_unwind_emit_sequence (FILE * asm_out_file, rtx p)
       gcc_assert (reg >= lastreg);
 
       if (i != 1)
-	fprintf (asm_out_file, ", ");
+	fprintf (out_file, ", ");
       /* We can't use %r for vfp because we need to use the
 	 double precision register names.  */
       if (IS_VFP_REGNUM (reg))
-	asm_fprintf (asm_out_file, "d%d", (reg - FIRST_VFP_REGNUM) / 2);
+	asm_fprintf (out_file, "d%d", (reg - FIRST_VFP_REGNUM) / 2);
       else
-	asm_fprintf (asm_out_file, "%r", reg);
+	asm_fprintf (out_file, "%r", reg);
 
       if (flag_checking)
 	{
@@ -29553,15 +29551,15 @@ arm_unwind_emit_sequence (FILE * asm_out_file, rtx p)
 	  offset += reg_size;
 	}
     }
-  fprintf (asm_out_file, "}\n");
+  fprintf (out_file, "}\n");
   if (padfirst)
-    fprintf (asm_out_file, "\t.pad #%d\n", padfirst);
+    fprintf (out_file, "\t.pad #%d\n", padfirst);
 }
 
 /*  Emit unwind directives for a SET.  */
 
 static void
-arm_unwind_emit_set (FILE * asm_out_file, rtx p)
+arm_unwind_emit_set (FILE * out_file, rtx p)
 {
   rtx e0;
   rtx e1;
@@ -29578,12 +29576,12 @@ arm_unwind_emit_set (FILE * asm_out_file, rtx p)
 	  || REGNO (XEXP (XEXP (e0, 0), 0)) != SP_REGNUM)
 	abort ();
 
-      asm_fprintf (asm_out_file, "\t.save ");
+      asm_fprintf (out_file, "\t.save ");
       if (IS_VFP_REGNUM (REGNO (e1)))
-	asm_fprintf(asm_out_file, "{d%d}\n",
+	asm_fprintf(out_file, "{d%d}\n",
 		    (REGNO (e1) - FIRST_VFP_REGNUM) / 2);
       else
-	asm_fprintf(asm_out_file, "{%r}\n", REGNO (e1));
+	asm_fprintf(out_file, "{%r}\n", REGNO (e1));
       break;
 
     case REG:
@@ -29596,7 +29594,7 @@ arm_unwind_emit_set (FILE * asm_out_file, rtx p)
 	      || !CONST_INT_P (XEXP (e1, 1)))
 	    abort ();
 
-	  asm_fprintf (asm_out_file, "\t.pad #%wd\n",
+	  asm_fprintf (out_file, "\t.pad #%wd\n",
 		       -INTVAL (XEXP (e1, 1)));
 	}
       else if (REGNO (e0) == HARD_FRAME_POINTER_REGNUM)
@@ -29610,14 +29608,14 @@ arm_unwind_emit_set (FILE * asm_out_file, rtx p)
 		abort ();
 	      reg = REGNO (XEXP (e1, 0));
 	      offset = INTVAL (XEXP (e1, 1));
-	      asm_fprintf (asm_out_file, "\t.setfp %r, %r, #%wd\n",
+	      asm_fprintf (out_file, "\t.setfp %r, %r, #%wd\n",
 			   HARD_FRAME_POINTER_REGNUM, reg,
 			   offset);
 	    }
 	  else if (REG_P (e1))
 	    {
 	      reg = REGNO (e1);
-	      asm_fprintf (asm_out_file, "\t.setfp %r, %r\n",
+	      asm_fprintf (out_file, "\t.setfp %r, %r\n",
 			   HARD_FRAME_POINTER_REGNUM, reg);
 	    }
 	  else
@@ -29626,7 +29624,7 @@ arm_unwind_emit_set (FILE * asm_out_file, rtx p)
       else if (REG_P (e1) && REGNO (e1) == SP_REGNUM)
 	{
 	  /* Move from sp to reg.  */
-	  asm_fprintf (asm_out_file, "\t.movsp %r\n", REGNO (e0));
+	  asm_fprintf (out_file, "\t.movsp %r\n", REGNO (e0));
 	}
      else if (GET_CODE (e1) == PLUS
 	      && REG_P (XEXP (e1, 0))
@@ -29634,7 +29632,7 @@ arm_unwind_emit_set (FILE * asm_out_file, rtx p)
 	      && CONST_INT_P (XEXP (e1, 1)))
 	{
 	  /* Set reg to offset from sp.  */
-	  asm_fprintf (asm_out_file, "\t.movsp %r, #%d\n",
+	  asm_fprintf (out_file, "\t.movsp %r, #%d\n",
 		       REGNO (e0), (int)INTVAL(XEXP (e1, 1)));
 	}
       else
@@ -29650,7 +29648,7 @@ arm_unwind_emit_set (FILE * asm_out_file, rtx p)
 /* Emit unwind directives for the given insn.  */
 
 static void
-arm_unwind_emit (FILE * asm_out_file, rtx_insn *insn)
+arm_unwind_emit (FILE * out_file, rtx_insn *insn)
 {
   rtx note, pat;
   bool handled_one = false;
@@ -29693,7 +29691,7 @@ arm_unwind_emit (FILE * asm_out_file, rtx_insn *insn)
 
 	    gcc_assert (src == stack_pointer_rtx);
 	    reg = REGNO (dest);
-	    asm_fprintf (asm_out_file, "\t.unwind_raw 0, 0x%x @ vsp = r%d\n",
+	    asm_fprintf (out_file, "\t.unwind_raw 0, 0x%x @ vsp = r%d\n",
 			 reg + 0x90, reg);
 	  }
 	  handled_one = true;
@@ -29726,12 +29724,12 @@ arm_unwind_emit (FILE * asm_out_file, rtx_insn *insn)
   switch (GET_CODE (pat))
     {
     case SET:
-      arm_unwind_emit_set (asm_out_file, pat);
+      arm_unwind_emit_set (out_file, pat);
       break;
 
     case SEQUENCE:
       /* Store multiple.  */
-      arm_unwind_emit_sequence (asm_out_file, pat);
+      arm_unwind_emit_sequence (out_file, pat);
       break;
 
     default:
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index 781742fe46f..abcbdb1e028 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -1058,7 +1058,7 @@ machopic_legitimize_pic_address (rtx orig, machine_mode mode, rtx reg)
 
 int
 machopic_output_data_section_indirection (machopic_indirection **slot,
-					  FILE *asm_out_file)
+					  FILE *out_file)
 {
   machopic_indirection *p = *slot;
 
@@ -1073,7 +1073,7 @@ machopic_output_data_section_indirection (machopic_indirection **slot,
 
   switch_to_section (data_section);
   assemble_align (GET_MODE_ALIGNMENT (Pmode));
-  assemble_label (asm_out_file, ptr_name);
+  assemble_label (out_file, ptr_name);
   assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
 		    GET_MODE_SIZE (Pmode),
 		    GET_MODE_ALIGNMENT (Pmode), 1);
@@ -1083,7 +1083,7 @@ machopic_output_data_section_indirection (machopic_indirection **slot,
 
 int
 machopic_output_stub_indirection (machopic_indirection **slot,
-				  FILE *asm_out_file)
+				  FILE *out_file)
 {
   machopic_indirection *p = *slot;
 
@@ -1121,13 +1121,13 @@ machopic_output_stub_indirection (machopic_indirection **slot,
   else
     sprintf (stub, "%s%s", user_label_prefix, ptr_name);
 
-  machopic_output_stub (asm_out_file, sym, stub);
+  machopic_output_stub (out_file, sym, stub);
 
   return 1;
 }
 
 int
-machopic_output_indirection (machopic_indirection **slot, FILE *asm_out_file)
+machopic_output_indirection (machopic_indirection **slot, FILE *out_file)
 {
   machopic_indirection *p = *slot;
 
@@ -1159,18 +1159,18 @@ machopic_output_indirection (machopic_indirection **slot, FILE *asm_out_file)
 	     storage has been allocated.  */
 	  && !TREE_STATIC (decl))
 	{
-	  fputs ("\t.weak_reference ", asm_out_file);
-	  assemble_name (asm_out_file, sym_name);
-	  fputc ('\n', asm_out_file);
+	  fputs ("\t.weak_reference ", out_file);
+	  assemble_name (out_file, sym_name);
+	  fputc ('\n', out_file);
 	}
     }
 
-  assemble_name (asm_out_file, ptr_name);
-  fprintf (asm_out_file, ":\n");
+  assemble_name (out_file, ptr_name);
+  fprintf (out_file, ":\n");
 
-  fprintf (asm_out_file, "\t.indirect_symbol ");
-  assemble_name (asm_out_file, sym_name);
-  fprintf (asm_out_file, "\n");
+  fprintf (out_file, "\t.indirect_symbol ");
+  assemble_name (out_file, sym_name);
+  fprintf (out_file, "\n");
 
   /* Variables that are marked with MACHO_SYMBOL_FLAG_STATIC need to
      have their symbol name instead of 0 in the second entry of
@@ -1190,7 +1190,7 @@ machopic_output_indirection (machopic_indirection **slot, FILE *asm_out_file)
 }
 
 static void
-machopic_finish (FILE *asm_out_file)
+machopic_finish (FILE *out_file)
 {
   if (!machopic_indirections)
     return;
@@ -1198,13 +1198,13 @@ machopic_finish (FILE *asm_out_file)
   /* First output an symbol indirections that have been placed into .data
      (we don't expect these now).  */
   machopic_indirections->traverse_noresize
-    <FILE *, machopic_output_data_section_indirection> (asm_out_file);
+    <FILE *, machopic_output_data_section_indirection> (out_file);
 
   machopic_indirections->traverse_noresize
-    <FILE *, machopic_output_stub_indirection> (asm_out_file);
+    <FILE *, machopic_output_stub_indirection> (out_file);
 
   machopic_indirections->traverse_noresize
-    <FILE *, machopic_output_indirection> (asm_out_file);
+    <FILE *, machopic_output_indirection> (out_file);
 }
 
 int
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index d7abff0f396..a5c4fa857a7 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -1567,7 +1567,7 @@ ix86_function_naked (const_tree fn)
 /* Write the extra assembler code needed to declare a function properly.  */
 
 void
-ix86_asm_output_function_label (FILE *asm_out_file, const char *fname,
+ix86_asm_output_function_label (FILE *out_file, const char *fname,
 				tree decl)
 {
   bool is_ms_hook = ix86_function_ms_hook_prologue (decl);
@@ -1581,14 +1581,14 @@ ix86_asm_output_function_label (FILE *asm_out_file, const char *fname,
       unsigned int filler_cc = 0xcccccccc;
 
       for (i = 0; i < filler_count; i += 4)
-        fprintf (asm_out_file, ASM_LONG " %#x\n", filler_cc);
+	fprintf (out_file, ASM_LONG " %#x\n", filler_cc);
     }
 
 #ifdef SUBTARGET_ASM_UNWIND_INIT
-  SUBTARGET_ASM_UNWIND_INIT (asm_out_file);
+  SUBTARGET_ASM_UNWIND_INIT (out_file);
 #endif
 
-  ASM_OUTPUT_LABEL (asm_out_file, fname);
+  ASM_OUTPUT_LABEL (out_file, fname);
 
   /* Output magic byte marker, if hot-patch attribute is set.  */
   if (is_ms_hook)
@@ -1597,14 +1597,14 @@ ix86_asm_output_function_label (FILE *asm_out_file, const char *fname,
 	{
 	  /* leaq [%rsp + 0], %rsp  */
 	  fputs (ASM_BYTE "0x48, 0x8d, 0xa4, 0x24, 0x00, 0x00, 0x00, 0x00\n",
-		 asm_out_file);
+		 out_file);
 	}
       else
 	{
           /* movl.s %edi, %edi
 	     push   %ebp
 	     movl.s %esp, %ebp */
-	  fputs (ASM_BYTE "0x8b, 0xff, 0x55, 0x8b, 0xec\n", asm_out_file);
+	  fputs (ASM_BYTE "0x8b, 0xff, 0x55, 0x8b, 0xec\n", out_file);
 	}
     }
 }
diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c
index 4158a45ac31..7c0ea4f731c 100644
--- a/gcc/config/i386/winnt.c
+++ b/gcc/config/i386/winnt.c
@@ -1231,7 +1231,7 @@ seh_frame_related_expr (FILE *f, struct seh_frame_state *seh, rtx pat)
    required for unwind of this insn.  */
 
 void
-i386_pe_seh_unwind_emit (FILE *asm_out_file, rtx_insn *insn)
+i386_pe_seh_unwind_emit (FILE *out_file, rtx_insn *insn)
 {
   rtx note, pat;
   bool handled_one = false;
@@ -1246,8 +1246,8 @@ i386_pe_seh_unwind_emit (FILE *asm_out_file, rtx_insn *insn)
       /* See ix86_seh_fixup_eh_fallthru for the rationale.  */
       rtx_insn *prev = prev_active_insn (insn);
       if (prev && !insn_nothrow_p (prev))
-	fputs ("\tnop\n", asm_out_file);
-      fputs ("\t.seh_endproc\n", asm_out_file);
+	fputs ("\tnop\n", out_file);
+      fputs ("\t.seh_endproc\n", out_file);
       seh->in_cold_section = true;
       return;
     }
@@ -1286,7 +1286,7 @@ i386_pe_seh_unwind_emit (FILE *asm_out_file, rtx_insn *insn)
 	      if (GET_CODE (pat) == PARALLEL)
 		pat = XVECEXP (pat, 0, 0);
 	    }
-	  seh_cfa_adjust_cfa (asm_out_file, seh, pat);
+	  seh_cfa_adjust_cfa (out_file, seh, pat);
 	  handled_one = true;
 	  break;
 
@@ -1294,7 +1294,7 @@ i386_pe_seh_unwind_emit (FILE *asm_out_file, rtx_insn *insn)
 	  pat = XEXP (note, 0);
 	  if (pat == NULL)
 	    pat = single_set (insn);
-	  seh_cfa_offset (asm_out_file, seh, pat);
+	  seh_cfa_offset (out_file, seh, pat);
 	  handled_one = true;
 	  break;
 
@@ -1306,7 +1306,7 @@ i386_pe_seh_unwind_emit (FILE *asm_out_file, rtx_insn *insn)
     return;
   pat = PATTERN (insn);
  found:
-  seh_frame_related_expr (asm_out_file, seh, pat);
+  seh_frame_related_expr (out_file, seh, pat);
 }
 
 void
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index 632b9df1761..cdf78cdc518 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -10044,7 +10044,7 @@ static bool need_copy_state;
 /* The function emits unwind directives for the start of an epilogue.  */
 
 static void
-process_epilogue (FILE *asm_out_file, rtx insn ATTRIBUTE_UNUSED,
+process_epilogue (FILE *out_file, rtx insn ATTRIBUTE_UNUSED,
 		  bool unwind, bool frame ATTRIBUTE_UNUSED)
 {
   /* If this isn't the last block of the function, then we need to label the
@@ -10053,19 +10053,19 @@ process_epilogue (FILE *asm_out_file, rtx insn ATTRIBUTE_UNUSED,
   if (!last_block)
     {
       if (unwind)
-	fprintf (asm_out_file, "\t.label_state %d\n",
+	fprintf (out_file, "\t.label_state %d\n",
 		 ++cfun->machine->state_num);
       need_copy_state = true;
     }
 
   if (unwind)
-    fprintf (asm_out_file, "\t.restore sp\n");
+    fprintf (out_file, "\t.restore sp\n");
 }
 
 /* This function processes a SET pattern for REG_CFA_ADJUST_CFA.  */
 
 static void
-process_cfa_adjust_cfa (FILE *asm_out_file, rtx pat, rtx insn,
+process_cfa_adjust_cfa (FILE *out_file, rtx pat, rtx insn,
 			bool unwind, bool frame)
 {
   rtx dest = SET_DEST (pat);
@@ -10084,17 +10084,17 @@ process_cfa_adjust_cfa (FILE *asm_out_file, rtx pat, rtx insn,
 	    {
 	      gcc_assert (!frame_pointer_needed);
 	      if (unwind)
-		fprintf (asm_out_file,
+		fprintf (out_file,
 			 "\t.fframe " HOST_WIDE_INT_PRINT_DEC"\n",
 			 -INTVAL (op1));
 	    }
 	  else
-	    process_epilogue (asm_out_file, insn, unwind, frame);
+	    process_epilogue (out_file, insn, unwind, frame);
 	}
       else
 	{
 	  gcc_assert (src == hard_frame_pointer_rtx);
-	  process_epilogue (asm_out_file, insn, unwind, frame);
+	  process_epilogue (out_file, insn, unwind, frame);
 	}
     }
   else if (dest == hard_frame_pointer_rtx)
@@ -10103,7 +10103,7 @@ process_cfa_adjust_cfa (FILE *asm_out_file, rtx pat, rtx insn,
       gcc_assert (frame_pointer_needed);
 
       if (unwind)
-	fprintf (asm_out_file, "\t.vframe r%d\n",
+	fprintf (out_file, "\t.vframe r%d\n",
 		 ia64_dbx_register_number (REGNO (dest)));
     }
   else
@@ -10113,7 +10113,7 @@ process_cfa_adjust_cfa (FILE *asm_out_file, rtx pat, rtx insn,
 /* This function processes a SET pattern for REG_CFA_REGISTER.  */
 
 static void
-process_cfa_register (FILE *asm_out_file, rtx pat, bool unwind)
+process_cfa_register (FILE *out_file, rtx pat, bool unwind)
 {
   rtx dest = SET_DEST (pat);
   rtx src = SET_SRC (pat);
@@ -10124,7 +10124,7 @@ process_cfa_register (FILE *asm_out_file, rtx pat, bool unwind)
     {
       /* Saving return address pointer.  */
       if (unwind)
-	fprintf (asm_out_file, "\t.save rp, r%d\n",
+	fprintf (out_file, "\t.save rp, r%d\n",
 		 ia64_dbx_register_number (dest_regno));
       return;
     }
@@ -10136,21 +10136,21 @@ process_cfa_register (FILE *asm_out_file, rtx pat, bool unwind)
     case PR_REG (0):
       gcc_assert (dest_regno == current_frame_info.r[reg_save_pr]);
       if (unwind)
-	fprintf (asm_out_file, "\t.save pr, r%d\n",
+	fprintf (out_file, "\t.save pr, r%d\n",
 		 ia64_dbx_register_number (dest_regno));
       break;
 
     case AR_UNAT_REGNUM:
       gcc_assert (dest_regno == current_frame_info.r[reg_save_ar_unat]);
       if (unwind)
-	fprintf (asm_out_file, "\t.save ar.unat, r%d\n",
+	fprintf (out_file, "\t.save ar.unat, r%d\n",
 		 ia64_dbx_register_number (dest_regno));
       break;
 
     case AR_LC_REGNUM:
       gcc_assert (dest_regno == current_frame_info.r[reg_save_ar_lc]);
       if (unwind)
-	fprintf (asm_out_file, "\t.save ar.lc, r%d\n",
+	fprintf (out_file, "\t.save ar.lc, r%d\n",
 		 ia64_dbx_register_number (dest_regno));
       break;
 
@@ -10163,7 +10163,7 @@ process_cfa_register (FILE *asm_out_file, rtx pat, bool unwind)
 /* This function processes a SET pattern for REG_CFA_OFFSET.  */
 
 static void
-process_cfa_offset (FILE *asm_out_file, rtx pat, bool unwind)
+process_cfa_offset (FILE *out_file, rtx pat, bool unwind)
 {
   rtx dest = SET_DEST (pat);
   rtx src = SET_SRC (pat);
@@ -10203,35 +10203,35 @@ process_cfa_offset (FILE *asm_out_file, rtx pat, bool unwind)
     case BR_REG (0):
       gcc_assert (!current_frame_info.r[reg_save_b0]);
       if (unwind)
-	fprintf (asm_out_file, "\t%s rp, " HOST_WIDE_INT_PRINT_DEC "\n",
+	fprintf (out_file, "\t%s rp, " HOST_WIDE_INT_PRINT_DEC "\n",
 		 saveop, off);
       break;
 
     case PR_REG (0):
       gcc_assert (!current_frame_info.r[reg_save_pr]);
       if (unwind)
-	fprintf (asm_out_file, "\t%s pr, " HOST_WIDE_INT_PRINT_DEC "\n",
+	fprintf (out_file, "\t%s pr, " HOST_WIDE_INT_PRINT_DEC "\n",
 		 saveop, off);
       break;
 
     case AR_LC_REGNUM:
       gcc_assert (!current_frame_info.r[reg_save_ar_lc]);
       if (unwind)
-	fprintf (asm_out_file, "\t%s ar.lc, " HOST_WIDE_INT_PRINT_DEC "\n",
+	fprintf (out_file, "\t%s ar.lc, " HOST_WIDE_INT_PRINT_DEC "\n",
 		 saveop, off);
       break;
 
     case AR_PFS_REGNUM:
       gcc_assert (!current_frame_info.r[reg_save_ar_pfs]);
       if (unwind)
-	fprintf (asm_out_file, "\t%s ar.pfs, " HOST_WIDE_INT_PRINT_DEC "\n",
+	fprintf (out_file, "\t%s ar.pfs, " HOST_WIDE_INT_PRINT_DEC "\n",
 		 saveop, off);
       break;
 
     case AR_UNAT_REGNUM:
       gcc_assert (!current_frame_info.r[reg_save_ar_unat]);
       if (unwind)
-	fprintf (asm_out_file, "\t%s ar.unat, " HOST_WIDE_INT_PRINT_DEC "\n",
+	fprintf (out_file, "\t%s ar.unat, " HOST_WIDE_INT_PRINT_DEC "\n",
 		 saveop, off);
       break;
 
@@ -10240,7 +10240,7 @@ process_cfa_offset (FILE *asm_out_file, rtx pat, bool unwind)
     case GR_REG (6):
     case GR_REG (7):
       if (unwind)
-	fprintf (asm_out_file, "\t.save.g 0x%x\n",
+	fprintf (out_file, "\t.save.g 0x%x\n",
 		 1 << (src_regno - GR_REG (4)));
       break;
 
@@ -10250,7 +10250,7 @@ process_cfa_offset (FILE *asm_out_file, rtx pat, bool unwind)
     case BR_REG (4):
     case BR_REG (5):
       if (unwind)
-	fprintf (asm_out_file, "\t.save.b 0x%x\n",
+	fprintf (out_file, "\t.save.b 0x%x\n",
 		 1 << (src_regno - BR_REG (1)));
       break;
 
@@ -10259,7 +10259,7 @@ process_cfa_offset (FILE *asm_out_file, rtx pat, bool unwind)
     case FR_REG (4):
     case FR_REG (5):
       if (unwind)
-	fprintf (asm_out_file, "\t.save.f 0x%x\n",
+	fprintf (out_file, "\t.save.f 0x%x\n",
 		 1 << (src_regno - FR_REG (2)));
       break;
 
@@ -10268,7 +10268,7 @@ process_cfa_offset (FILE *asm_out_file, rtx pat, bool unwind)
     case FR_REG (24): case FR_REG (25): case FR_REG (26): case FR_REG (27):
     case FR_REG (28): case FR_REG (29): case FR_REG (30): case FR_REG (31):
       if (unwind)
-	fprintf (asm_out_file, "\t.save.gf 0x0, 0x%x\n",
+	fprintf (out_file, "\t.save.gf 0x0, 0x%x\n",
 		 1 << (src_regno - FR_REG (12)));
       break;
 
@@ -10283,7 +10283,7 @@ process_cfa_offset (FILE *asm_out_file, rtx pat, bool unwind)
    required to unwind this insn.  */
 
 static void
-ia64_asm_unwind_emit (FILE *asm_out_file, rtx_insn *insn)
+ia64_asm_unwind_emit (FILE *out_file, rtx_insn *insn)
 {
   bool unwind = ia64_except_unwind_info (&global_options) == UI_TARGET;
   bool frame = dwarf2out_do_frame ();
@@ -10303,8 +10303,8 @@ ia64_asm_unwind_emit (FILE *asm_out_file, rtx_insn *insn)
 	{
 	  if (unwind)
 	    {
-	      fprintf (asm_out_file, "\t.body\n");
-	      fprintf (asm_out_file, "\t.copy_state %d\n",
+	      fprintf (out_file, "\t.body\n");
+	      fprintf (out_file, "\t.copy_state %d\n",
 		       cfun->machine->state_num);
 	    }
 	  need_copy_state = false;
@@ -10325,7 +10325,7 @@ ia64_asm_unwind_emit (FILE *asm_out_file, rtx_insn *insn)
       if (dest_regno == current_frame_info.r[reg_save_ar_pfs])
 	{
 	  if (unwind)
-	    fprintf (asm_out_file, "\t.save ar.pfs, r%d\n",
+	    fprintf (out_file, "\t.save ar.pfs, r%d\n",
 		     ia64_dbx_register_number (dest_regno));
 	}
       else
@@ -10338,9 +10338,9 @@ ia64_asm_unwind_emit (FILE *asm_out_file, rtx_insn *insn)
 	     sp" now.  */
 	  if (current_frame_info.total_size == 0 && !frame_pointer_needed)
 	    /* if haven't done process_epilogue() yet, do it now */
-	    process_epilogue (asm_out_file, insn, unwind, frame);
+	    process_epilogue (out_file, insn, unwind, frame);
 	  if (unwind)
-	    fprintf (asm_out_file, "\t.prologue\n");
+	    fprintf (out_file, "\t.prologue\n");
 	}
       return;
     }
@@ -10353,7 +10353,7 @@ ia64_asm_unwind_emit (FILE *asm_out_file, rtx_insn *insn)
 	pat = XEXP (note, 0);
 	if (pat == NULL)
 	  pat = PATTERN (insn);
-	process_cfa_adjust_cfa (asm_out_file, pat, insn, unwind, frame);
+	process_cfa_adjust_cfa (out_file, pat, insn, unwind, frame);
 	handled_one = true;
 	break;
 
@@ -10361,7 +10361,7 @@ ia64_asm_unwind_emit (FILE *asm_out_file, rtx_insn *insn)
 	pat = XEXP (note, 0);
 	if (pat == NULL)
 	  pat = PATTERN (insn);
-	process_cfa_offset (asm_out_file, pat, unwind);
+	process_cfa_offset (out_file, pat, unwind);
 	handled_one = true;
 	break;
 
@@ -10369,7 +10369,7 @@ ia64_asm_unwind_emit (FILE *asm_out_file, rtx_insn *insn)
 	pat = XEXP (note, 0);
 	if (pat == NULL)
 	  pat = PATTERN (insn);
-	process_cfa_register (asm_out_file, pat, unwind);
+	process_cfa_register (out_file, pat, unwind);
 	handled_one = true;
 	break;
 
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 54dd6332c3a..3e422f045c9 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -7798,7 +7798,7 @@ s390_asm_declare_function_size (FILE *asm_out_file,
 /* Write the extra assembler code needed to declare a function properly.  */
 
 void
-s390_asm_output_function_label (FILE *asm_out_file, const char *fname,
+s390_asm_output_function_label (FILE *out_file, const char *fname,
 				tree decl)
 {
   int hw_before, hw_after;
@@ -7812,11 +7812,11 @@ s390_asm_output_function_label (FILE *asm_out_file, const char *fname,
       /* Add a trampoline code area before the function label and initialize it
 	 with two-byte nop instructions.  This area can be overwritten with code
 	 that jumps to a patched version of the function.  */
-      asm_fprintf (asm_out_file, "\tnopr\t%%r0"
+      asm_fprintf (out_file, "\tnopr\t%%r0"
 		   "\t# pre-label NOPs for hotpatch (%d halfwords)\n",
 		   hw_before);
       for (i = 1; i < hw_before; i++)
-	fputs ("\tnopr\t%r0\n", asm_out_file);
+	fputs ("\tnopr\t%r0\n", out_file);
 
       /* Note:  The function label must be aligned so that (a) the bytes of the
 	 following nop do not cross a cacheline boundary, and (b) a jump address
@@ -7833,35 +7833,35 @@ s390_asm_output_function_label (FILE *asm_out_file, const char *fname,
 	function_alignment
 	  = MAX (function_alignment,
 		 (unsigned int) align_functions.levels[0].get_value ());
-      fputs ("\t# alignment for hotpatch\n", asm_out_file);
-      ASM_OUTPUT_ALIGN (asm_out_file, align_functions.levels[0].log);
+      fputs ("\t# alignment for hotpatch\n", out_file);
+      ASM_OUTPUT_ALIGN (out_file, align_functions.levels[0].log);
     }
 
   if (S390_USE_TARGET_ATTRIBUTE && TARGET_DEBUG_ARG)
     {
-      asm_fprintf (asm_out_file, "\t# fn:%s ar%d\n", fname, s390_arch);
-      asm_fprintf (asm_out_file, "\t# fn:%s tu%d\n", fname, s390_tune);
-      asm_fprintf (asm_out_file, "\t# fn:%s sg%d\n", fname, s390_stack_guard);
-      asm_fprintf (asm_out_file, "\t# fn:%s ss%d\n", fname, s390_stack_size);
-      asm_fprintf (asm_out_file, "\t# fn:%s bc%d\n", fname, s390_branch_cost);
-      asm_fprintf (asm_out_file, "\t# fn:%s wf%d\n", fname,
+      asm_fprintf (out_file, "\t# fn:%s ar%d\n", fname, s390_arch);
+      asm_fprintf (out_file, "\t# fn:%s tu%d\n", fname, s390_tune);
+      asm_fprintf (out_file, "\t# fn:%s sg%d\n", fname, s390_stack_guard);
+      asm_fprintf (out_file, "\t# fn:%s ss%d\n", fname, s390_stack_size);
+      asm_fprintf (out_file, "\t# fn:%s bc%d\n", fname, s390_branch_cost);
+      asm_fprintf (out_file, "\t# fn:%s wf%d\n", fname,
 		   s390_warn_framesize);
-      asm_fprintf (asm_out_file, "\t# fn:%s ba%d\n", fname, TARGET_BACKCHAIN);
-      asm_fprintf (asm_out_file, "\t# fn:%s hd%d\n", fname, TARGET_HARD_DFP);
-      asm_fprintf (asm_out_file, "\t# fn:%s hf%d\n", fname, !TARGET_SOFT_FLOAT);
-      asm_fprintf (asm_out_file, "\t# fn:%s ht%d\n", fname, TARGET_OPT_HTM);
-      asm_fprintf (asm_out_file, "\t# fn:%s vx%d\n", fname, TARGET_OPT_VX);
-      asm_fprintf (asm_out_file, "\t# fn:%s ps%d\n", fname,
+      asm_fprintf (out_file, "\t# fn:%s ba%d\n", fname, TARGET_BACKCHAIN);
+      asm_fprintf (out_file, "\t# fn:%s hd%d\n", fname, TARGET_HARD_DFP);
+      asm_fprintf (out_file, "\t# fn:%s hf%d\n", fname, !TARGET_SOFT_FLOAT);
+      asm_fprintf (out_file, "\t# fn:%s ht%d\n", fname, TARGET_OPT_HTM);
+      asm_fprintf (out_file, "\t# fn:%s vx%d\n", fname, TARGET_OPT_VX);
+      asm_fprintf (out_file, "\t# fn:%s ps%d\n", fname,
 		   TARGET_PACKED_STACK);
-      asm_fprintf (asm_out_file, "\t# fn:%s se%d\n", fname, TARGET_SMALL_EXEC);
-      asm_fprintf (asm_out_file, "\t# fn:%s mv%d\n", fname, TARGET_MVCLE);
-      asm_fprintf (asm_out_file, "\t# fn:%s zv%d\n", fname, TARGET_ZVECTOR);
-      asm_fprintf (asm_out_file, "\t# fn:%s wd%d\n", fname,
+      asm_fprintf (out_file, "\t# fn:%s se%d\n", fname, TARGET_SMALL_EXEC);
+      asm_fprintf (out_file, "\t# fn:%s mv%d\n", fname, TARGET_MVCLE);
+      asm_fprintf (out_file, "\t# fn:%s zv%d\n", fname, TARGET_ZVECTOR);
+      asm_fprintf (out_file, "\t# fn:%s wd%d\n", fname,
 		   s390_warn_dynamicstack_p);
     }
-  ASM_OUTPUT_LABEL (asm_out_file, fname);
+  ASM_OUTPUT_LABEL (out_file, fname);
   if (hw_after > 0)
-    asm_fprintf (asm_out_file,
+    asm_fprintf (out_file,
 		 "\t# post-label NOPs for hotpatch (%d halfwords)\n",
 		 hw_after);
 }
-- 
2.33.0


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 2/N] Do not hide asm_out_file in ASM_OUTPUT_ASCII.
  2021-09-10  9:31 [PATCH][RFC] Come up with casm state Martin Liška
  2021-09-16 10:00 ` [PATCH 1/N] Rename asm_out_file function arguments Martin Liška
@ 2021-09-16 10:00 ` Martin Liška
  2021-09-22  9:44   ` Richard Biener
  2021-09-16 13:12 ` [PATCH 3/N] Come up with casm global state Martin Liška
  2 siblings, 1 reply; 30+ messages in thread
From: Martin Liška @ 2021-09-16 10:00 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 176 bytes --]

Again a preparation patch that was tested on all cross compilers.

Patch can bootstrap on x86_64-linux-gnu and survives regression tests.

Ready to be installed?
Thanks,
Martin

[-- Attachment #2: 0002-Do-not-hide-asm_out_file-in-ASM_OUTPUT_ASCII.patch --]
[-- Type: text/x-patch, Size: 2439 bytes --]

From 0e5095274bb4e16ad28a5a52f30bd3887df25fde Mon Sep 17 00:00:00 2001
From: Martin Liska <mliska@suse.cz>
Date: Wed, 15 Sep 2021 13:52:35 +0200
Subject: [PATCH 2/3] Do not hide asm_out_file in ASM_OUTPUT_ASCII.

gcc/ChangeLog:

	* defaults.h (ASM_OUTPUT_ASCII): Do not hide global variable
	asm_out_file and stream directly to MYFILE.
---
 gcc/defaults.h | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/gcc/defaults.h b/gcc/defaults.h
index ba79a8e48ed..9370fa12f96 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -61,36 +61,34 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #ifndef ASM_OUTPUT_ASCII
 #define ASM_OUTPUT_ASCII(MYFILE, MYSTRING, MYLENGTH) \
   do {									      \
-    FILE *_hide_asm_out_file = (MYFILE);				      \
     const unsigned char *_hide_p = (const unsigned char *) (MYSTRING);	      \
     int _hide_thissize = (MYLENGTH);					      \
     {									      \
-      FILE *asm_out_file = _hide_asm_out_file;				      \
       const unsigned char *p = _hide_p;					      \
       int thissize = _hide_thissize;					      \
       int i;								      \
-      fprintf (asm_out_file, "\t.ascii \"");				      \
+      fprintf (MYFILE, "\t.ascii \"");					      \
 									      \
       for (i = 0; i < thissize; i++)					      \
 	{								      \
 	  int c = p[i];			   				      \
 	  if (c == '\"' || c == '\\')					      \
-	    putc ('\\', asm_out_file);					      \
+	    putc ('\\', MYFILE);					      \
 	  if (ISPRINT (c))						      \
-	    putc (c, asm_out_file);					      \
+	    putc (c, MYFILE);						      \
 	  else								      \
 	    {								      \
-	      fprintf (asm_out_file, "\\%o", c);			      \
+	      fprintf (MYFILE, "\\%o", c);				      \
 	      /* After an octal-escape, if a digit follows,		      \
 		 terminate one string constant and start another.	      \
 		 The VAX assembler fails to stop reading the escape	      \
 		 after three digits, so this is the only way we		      \
 		 can get it to parse the data properly.  */		      \
 	      if (i < thissize - 1 && ISDIGIT (p[i + 1]))		      \
-		fprintf (asm_out_file, "\"\n\t.ascii \"");		      \
+		fprintf (MYFILE, "\"\n\t.ascii \"");			      \
 	  }								      \
 	}								      \
-      fprintf (asm_out_file, "\"\n");					      \
+      fprintf (MYFILE, "\"\n");						      \
     }									      \
   }									      \
   while (0)
-- 
2.33.0


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 3/N] Come up with casm global state.
  2021-09-10  9:31 [PATCH][RFC] Come up with casm state Martin Liška
  2021-09-16 10:00 ` [PATCH 1/N] Rename asm_out_file function arguments Martin Liška
  2021-09-16 10:00 ` [PATCH 2/N] Do not hide asm_out_file in ASM_OUTPUT_ASCII Martin Liška
@ 2021-09-16 13:12 ` Martin Liška
  2021-09-22  9:59   ` Richard Biener
                     ` (2 more replies)
  2 siblings, 3 replies; 30+ messages in thread
From: Martin Liška @ 2021-09-16 13:12 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 212 bytes --]

This patch comes up with asm_out_state and a new global variable casm.

Tested on all cross compilers.
Patch can bootstrap on x86_64-linux-gnu and survives regression tests.

Ready to be installed?
Thanks,
Martin

[-- Attachment #2: 0001-Come-up-with-casm-global-state.patch --]
[-- Type: text/x-patch, Size: 117530 bytes --]

From 88bb389c617660a14adf968e0470417a5c8688af Mon Sep 17 00:00:00 2001
From: Martin Liska <mliska@suse.cz>
Date: Tue, 7 Sep 2021 13:32:57 +0200
Subject: [PATCH] Come up with casm global state.

gcc/ChangeLog:

	* output.h (struct asm_out_file): New struct that replaces a
	couple of global variables.
	* ggc-common.c (gt_pch_restore): Skip overwrite of
	casm->out_file as it may be overwritten by PCH.
	* doc/tm.texi: Document new usage of casm.
	* doc/tm.texi.in: Likewise.
	* varasm.c: Delete unused global variables.
	(handle_vtv_comdat_section): Use new casm.
	(struct section_hasher): Likewise.
	(GTY): Likewise.
	(get_section): Likewise.
	(asm_output_aligned_bss): Likewise.
	(hot_function_section): Likewise.
	(current_function_section): Likewise.
	(switch_to_other_text_partition): Likewise.
	(default_function_rodata_section): Likewise.
	(default_no_function_rodata_section): Likewise.
	(mergeable_string_section): Likewise.
	(mergeable_constant_section): Likewise.
	(get_variable_section): Likewise.
	(default_dtor_section_asm_out_destructor): Likewise.
	(default_ctor_section_asm_out_constructor): Likewise.
	(decide_function_section): Likewise.
	(assemble_start_function): Likewise.
	(assemble_end_function): Likewise.
	(assemble_string): Likewise.
	(output_constant_pool_1): Likewise.
	(init_varasm_once): Likewise.
	(have_global_bss_p): Likewise.
	(default_select_section): Likewise.
	(default_elf_select_section): Likewise.
	(default_select_rtx_section): Likewise.
	(switch_to_section): Likewise.
	(get_section_anchor): Likewise.
	* cgraphunit.c (symbol_table::compile): Likewise.
	* config/aarch64/aarch64.c (aarch64_sls_emit_blr_function_thunks): Likewise.
	* config/aarch64/aarch64.h (TRAMPOLINE_SECTION): Likewise.
	* config/alpha/alpha.c (alpha_elf_select_rtx_section): Likewise.
	(alpha_write_linkage): Likewise.
	(vms_asm_out_constructor): Likewise.
	(vms_asm_out_destructor): Likewise.
	* config/alpha/elf.h: Likewise.
	* config/arc/arc.c (arc_asm_output_aligned_decl_local): Likewise.
	* config/arm/aout.h (ASM_OUTPUT_ALIGNED_LOCAL): Likewise.
	* config/arm/arm.c (get_jump_table_size): Likewise.
	(arm_elf_asm_cdtor): Likewise.
	(thumb_call_via_reg): Likewise.
	(arm_file_end): Likewise.
	* config/arm/arm.h (ARM_GE_BITS_READ): Likewise.
	* config/arm/unknown-elf.h: Likewise.
	* config/avr/avr.c (avr_asm_asm_output_aligned_bss): Likewise.
	(avr_output_data_section_asm_op): Likewise.
	(avr_output_addr_vec): Likewise.
	* config/bfin/bfin.h: Likewise.
	* config/c6x/c6x.c (c6x_select_rtx_section): Likewise.
	(c6x_asm_init_sections): Likewise.
	* config/c6x/c6x.h: Likewise.
	* config/csky/csky.c (get_csky_jump_table_size): Likewise.
	* config/darwin.c (output_objc_section_asm_op): Likewise.
	(DEF_SECTION): Likewise.
	(machopic_output_data_section_indirection): Likewise.
	(darwin_mergeable_string_section): Likewise.
	(darwin_mergeable_constant_section): Likewise.
	(darwin_objc2_section): Likewise.
	(machopic_select_section): Likewise.
	(fprintf): Likewise.
	(darwin_asm_declare_constant_name): Likewise.
	(darwin_emit_weak_or_comdat): Likewise.
	(darwin_emit_objc_zeroed): Likewise.
	(darwin_emit_local_bss): Likewise.
	(darwin_emit_common): Likewise.
	* config/frv/frv.c (frv_asm_out_constructor): Likewise.
	(frv_asm_out_destructor): Likewise.
	* config/frv/frv.h: Likewise.
	* config/ft32/ft32.h (ASM_OUTPUT_SYMBOL_REF): Likewise.
	* config/i386/cygming.h (drectve_section): Likewise.
	* config/i386/darwin.h: Likewise.
	* config/i386/i386.c (x86_output_aligned_bss): Likewise.
	(output_indirect_thunk_function): Likewise.
	(ix86_code_end): Likewise.
	* config/i386/sol2.h: Likewise.
	* config/i386/winnt.c (i386_pe_seh_init_sections): Likewise.
	* config/ia64/ia64.c (ia64_asm_init_sections): Likewise.
	(ia64_select_rtx_section): Likewise.
	* config/ia64/sysv4.h: Likewise.
	* config/lm32/lm32.h: Likewise.
	* config/m32r/m32r.h: Likewise.
	* config/mcore/mcore-elf.h: Likewise.
	* config/microblaze/microblaze.c (microblaze_elf_asm_cdtor): Likewise.
	(microblaze_select_section): Likewise.
	* config/microblaze/microblaze.h: Likewise.
	* config/mips/mips.c (mips_output_aligned_decl_common): Likewise.
	* config/mmix/mmix.c (mmix_file_start): Likewise.
	(mmix_file_end): Likewise.
	(mmix_asm_output_aligned_local): Likewise.
	* config/msp430/msp430.c (msp430_select_section): Likewise.
	* config/nios2/nios2.h: Likewise.
	* config/pa/pa.c (pa_output_function_epilogue): Likewise.
	(output_deferred_profile_counters): Likewise.
	(output_deferred_plabels): Likewise.
	(pa_asm_output_mi_thunk): Likewise.
	(pa_asm_output_aligned_bss): Likewise.
	(pa_asm_output_aligned_common): Likewise.
	(pa_asm_output_aligned_local): Likewise.
	(som_output_text_section_asm_op): Likewise.
	(som_output_comdat_data_section_asm_op): Likewise.
	(pa_som_asm_init_sections): Likewise.
	(pa_select_section): Likewise.
	(pa_function_section): Likewise.
	* config/pdp11/pdp11.c (pdp11_asm_output_var): Likewise.
	(pdp11_asm_init_sections): Likewise.
	* config/pru/pru.h: Likewise.
	* config/riscv/riscv.c (riscv_elf_select_rtx_section): Likewise.
	* config/rl78/rl78.c (rl78_select_section): Likewise.
	(rl78_asm_ctor_dtor): Likewise.
	* config/rs6000/rs6000.c (rs6000_assemble_integer): Likewise.
	(rs6000_elf_file_end): Likewise.
	(rs6000_xcoff_asm_init_sections): Likewise.
	(rs6000_xcoff_select_section): Likewise.
	(rs6000_xcoff_file_start): Likewise.
	(rs6000_xcoff_file_end): Likewise.
	(rs6000_xcoff_visibility): Likewise.
	(rs6000_xcoff_declare_function_name): Likewise.
	(rs6000_xcoff_asm_output_aligned_decl_common): Likewise.
	* config/rs6000/sysv4.h: Likewise.
	* config/rx/rx.c (rx_select_rtx_section): Likewise.
	(rx_select_section): Likewise.
	(rx_elf_asm_cdtor): Likewise.
	* config/s390/s390.c (s390_output_indirect_thunk_function): Likewise.
	* config/sh/sh.c (sh_file_start): Likewise.
	* config/sparc/sol2.h (host_detect_local_cpu): Likewise.
	* config/sparc/sparc.c (sparc_file_end): Likewise.
	* config/tilegx/tilegx.h (TRAMPOLINE_SECTION): Likewise.
	* config/tilepro/tilepro.h (TRAMPOLINE_SECTION): Likewise.
	* config/v850/v850.c (v850_output_aligned_bss): Likewise.
	(v850_select_section): Likewise.
	* config/visium/visium.h: Likewise.
	* dbxout.c (dbxout_function_end): Likewise.
	(dbxout_init): Likewise.
	(dbxout_source_file): Likewise.
	(dbxout_switch_text_section): Likewise.
	(dbxout_block): Likewise.
	* dwarf2out.c (switch_to_eh_frame_section): Likewise.
	(dwarf2out_begin_prologue): Likewise.
	(dwarf2out_switch_text_section): Likewise.
	(secname_for_decl): Likewise.
	(dw_loc_list): Likewise.
	(set_cur_line_info_table): Likewise.
	(dwarf2out_begin_function): Likewise.
	(dwarf2out_assembly_start): Likewise.
	(dwarf2out_finish): Likewise.
	(dwarf2out_early_finish): Likewise.
	* dwarf2out.h (struct dw_fde_node): Likewise.
	* except.c (switch_to_exception_section): Likewise.
	* final.c (shorten_branches): Likewise.
	(profile_function): Likewise.
	(final_scan_insn_1): Likewise.
	* langhooks.c (lhd_begin_section): Likewise.
	* vmsdbgout.c (vmsdbgout_finish): Likewise.
	* run-rtl-passes.c (run_rtl_passes): Likewise.
	* targhooks.c (default_print_patchable_function_entry_1): Likewise.
	* toplev.c (init_asm_output): Likewise.
	(general_init): Likewise.
	(finalize): Likewise.
---
 gcc/cgraphunit.c                   |   2 +-
 gcc/config/aarch64/aarch64.c       |   2 +-
 gcc/config/aarch64/aarch64.h       |   2 +-
 gcc/config/alpha/alpha.c           |  12 +-
 gcc/config/alpha/elf.h             |   4 +-
 gcc/config/arc/arc.c               |   2 +-
 gcc/config/arm/aout.h              |   2 +-
 gcc/config/arm/arm.c               |  14 +-
 gcc/config/arm/arm.h               |   2 +-
 gcc/config/arm/unknown-elf.h       |   4 +-
 gcc/config/avr/avr.c               |  12 +-
 gcc/config/bfin/bfin.h             |   2 +-
 gcc/config/c6x/c6x.c               |   4 +-
 gcc/config/c6x/c6x.h               |   4 +-
 gcc/config/csky/csky.c             |   2 +-
 gcc/config/darwin.c                |  66 +++++-----
 gcc/config/frv/frv.c               |   4 +-
 gcc/config/frv/frv.h               |   2 +-
 gcc/config/ft32/ft32.h             |   6 +-
 gcc/config/i386/cygming.h          |   2 +-
 gcc/config/i386/darwin.h           |   2 +-
 gcc/config/i386/i386.c             |   6 +-
 gcc/config/i386/sol2.h             |   6 +-
 gcc/config/i386/winnt.c            |   2 +-
 gcc/config/ia64/ia64.c             |   4 +-
 gcc/config/ia64/sysv4.h            |   4 +-
 gcc/config/lm32/lm32.h             |   8 +-
 gcc/config/m32r/m32r.h             |   2 +-
 gcc/config/mcore/mcore-elf.h       |   4 +-
 gcc/config/microblaze/microblaze.c |   6 +-
 gcc/config/microblaze/microblaze.h |   8 +-
 gcc/config/mips/mips.c             |   2 +-
 gcc/config/mmix/mmix.c             |   6 +-
 gcc/config/msp430/msp430.c         |   8 +-
 gcc/config/nios2/nios2.h           |   4 +-
 gcc/config/pa/pa.c                 |  34 ++---
 gcc/config/pdp11/pdp11.c           |   6 +-
 gcc/config/pru/pru.h               |   2 +-
 gcc/config/riscv/riscv.c           |   4 +-
 gcc/config/rl78/rl78.c             |  12 +-
 gcc/config/rs6000/rs6000.c         |  24 ++--
 gcc/config/rs6000/sysv4.h          |   2 +-
 gcc/config/rx/rx.c                 |  12 +-
 gcc/config/s390/s390.c             |   2 +-
 gcc/config/sh/sh.c                 |   2 +-
 gcc/config/sparc/sol2.h            |   6 +-
 gcc/config/sparc/sparc.c           |   2 +-
 gcc/config/tilegx/tilegx.h         |   2 +-
 gcc/config/tilepro/tilepro.h       |   2 +-
 gcc/config/v850/v850.c             |  10 +-
 gcc/config/visium/visium.h         |   4 +-
 gcc/dbxout.c                       |  20 +--
 gcc/doc/tm.texi                    |  14 +-
 gcc/doc/tm.texi.in                 |  14 +-
 gcc/dwarf2out.c                    |  56 ++++----
 gcc/dwarf2out.h                    |   4 +-
 gcc/except.c                       |  12 +-
 gcc/final.c                        |  24 ++--
 gcc/ggc-common.c                   |   7 +
 gcc/langhooks.c                    |   4 +-
 gcc/output.h                       |  93 ++++++++++---
 gcc/run-rtl-passes.c               |   2 +-
 gcc/targhooks.c                    |   2 +-
 gcc/toplev.c                       |  38 +++---
 gcc/varasm.c                       | 201 +++++++++++------------------
 gcc/vmsdbgout.c                    |   2 +-
 66 files changed, 426 insertions(+), 415 deletions(-)

diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 55cb0347149..773ca4fb27d 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -2309,7 +2309,7 @@ symbol_table::compile (void)
   timevar_pop (TV_CGRAPHOPT);
 
   /* Output everything.  */
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
   (*debug_hooks->assembly_start) ();
   if (!quiet_flag)
     fprintf (stderr, "Assembling functions:\n");
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 36519ccc5a5..95949c8d049 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -25737,7 +25737,7 @@ aarch64_sls_emit_blr_function_thunks (FILE *out_file)
      would happen in a different section -- leaving an unmatched
      `.cfi_startproc` in the cold text section and an unmatched `.cfi_endproc`
      in the standard text section.  */
-  section *save_text_section = in_section;
+  section *save_text_section = casm->in_section;
   switch_to_section (function_section (current_function_decl));
   for (int regnum = 0; regnum < 30; ++regnum)
     {
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index a5ba6c24037..3ed2d54078e 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -1123,7 +1123,7 @@ typedef struct
 
 /* Put trampolines in the text section so that mapping symbols work
    correctly.  */
-#define TRAMPOLINE_SECTION text_section
+#define TRAMPOLINE_SECTION casm->sec.text
 
 /* To start with.  */
 #define BRANCH_COST(SPEED_P, PREDICTABLE_P) \
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index c702e683c31..627a42d4ee3 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -8055,13 +8055,13 @@ alpha_start_function (FILE *file, const char *fnname,
 
 #ifdef TARGET_VMS_CRASH_DEBUG
   /* Support of minimal traceback info.  */
-  switch_to_section (readonly_data_section);
+  switch_to_section (casm->sec.readonly_data);
   fprintf (file, "\t.align 3\n");
   assemble_name (file, fnname); fputs ("..na:\n", file);
   fputs ("\t.ascii \"", file);
   assemble_name (file, fnname);
   fputs ("\\0\"\n", file);
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
 #endif
 #endif /* TARGET_ABI_OPEN_VMS */
 }
@@ -9446,7 +9446,7 @@ alpha_elf_select_rtx_section (machine_mode mode, rtx x,
 {
   if (TARGET_SMALL_DATA && GET_MODE_SIZE (mode) <= g_switch_value)
     /* ??? Consider using mergeable sdata sections.  */
-    return sdata_section;
+    return casm->sec.sdata;
   else
     return default_elf_select_rtx_section (mode, x, align);
 }
@@ -9613,7 +9613,7 @@ alpha_write_linkage (FILE *stream, const char *funname)
 {
   fprintf (stream, "\t.link\n");
   fprintf (stream, "\t.align 3\n");
-  in_section = NULL;
+  casm->in_section = NULL;
 
 #ifdef TARGET_VMS_CRASH_DEBUG
   fputs ("\t.name ", stream);
@@ -9665,7 +9665,7 @@ vms_asm_named_section (const char *name, unsigned int flags,
 static void
 vms_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
 {
-  switch_to_section (ctors_section);
+  switch_to_section (casm->sec.ctors);
   assemble_align (BITS_PER_WORD);
   assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
 }
@@ -9673,7 +9673,7 @@ vms_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
 static void
 vms_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
 {
-  switch_to_section (dtors_section);
+  switch_to_section (casm->sec.dtors);
   assemble_align (BITS_PER_WORD);
   assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
 }
diff --git a/gcc/config/alpha/elf.h b/gcc/config/alpha/elf.h
index b735f279b30..5a34bccccad 100644
--- a/gcc/config/alpha/elf.h
+++ b/gcc/config/alpha/elf.h
@@ -46,9 +46,9 @@ along with GCC; see the file COPYING3.  If not see
 #define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)		\
 do {									\
   if ((SIZE) <= (unsigned HOST_WIDE_INT) g_switch_value)		\
-    switch_to_section (sbss_section);					\
+    switch_to_section (casm->sec.sbss);					\
   else									\
-    switch_to_section (bss_section);					\
+    switch_to_section (casm->sec.bss);					\
   ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
   if (!flag_inhibit_size_directive)					\
     ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);			\
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 92797db96b7..b49e98c2157 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -8832,7 +8832,7 @@ arc_asm_output_aligned_decl_local (FILE * stream, tree decl, const char * name,
     switch_to_section (get_named_section (NULL, ".sbss", 0));
   /*    named_section (0,".sbss",0); */
   else
-    switch_to_section (bss_section);
+    switch_to_section (casm->sec.bss);
 
   if (globalize_p)
     (*targetm.asm_out.globalize_label) (stream, name);
diff --git a/gcc/config/arm/aout.h b/gcc/config/arm/aout.h
index 25a2812a663..01743bb040e 100644
--- a/gcc/config/arm/aout.h
+++ b/gcc/config/arm/aout.h
@@ -288,7 +288,7 @@
 #define ASM_OUTPUT_ALIGNED_LOCAL(STREAM, NAME, SIZE, ALIGN)		\
   do									\
     {									\
-      switch_to_section (bss_section);					\
+      switch_to_section (casm->sec.bss);					\
       ASM_OUTPUT_ALIGN (STREAM, floor_log2 (ALIGN / BITS_PER_UNIT));	\
       ASM_OUTPUT_LABEL (STREAM, NAME);					\
       fprintf (STREAM, "\t.space\t%d\n", (int)(SIZE));			\
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 1a7b47d236e..ccd5be30e07 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -17254,7 +17254,7 @@ get_jump_table_size (rtx_jump_table_data *insn)
 {
   /* ADDR_VECs only take room if read-only data does into the text
      section.  */
-  if (JUMP_TABLES_IN_TEXT_SECTION || readonly_data_section == text_section)
+  if (JUMP_TABLES_IN_TEXT_SECTION || casm->sec.readonly_data == casm->sec.text)
     {
       rtx body = PATTERN (insn);
       int elt = GET_CODE (body) == ADDR_DIFF_VEC ? 1 : 0;
@@ -24662,9 +24662,9 @@ arm_elf_asm_cdtor (rtx symbol, int priority, bool is_ctor)
       s = get_section (buf, SECTION_WRITE | SECTION_NOTYPE, NULL_TREE);
     }
   else if (is_ctor)
-    s = ctors_section;
+    s = casm->sec.ctors;
   else
-    s = dtors_section;
+    s = casm->sec.dtors;
 
   switch_to_section (s);
   assemble_align (POINTER_SIZE);
@@ -27930,7 +27930,7 @@ thumb_call_via_reg (rtx reg)
   /* If we are in the normal text section we can use a single instance
      per compilation unit.  If we are doing function sections, then we need
      an entry per section, since we can't rely on reachability.  */
-  if (in_section == text_section)
+  if (casm->in_section == casm->sec.text)
     {
       thumb_call_reg_needed = 1;
 
@@ -28322,7 +28322,7 @@ arm_file_end (void)
   if (! thumb_call_reg_needed)
     return;
 
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
   asm_fprintf (asm_out_file, "\t.code 16\n");
   ASM_OUTPUT_ALIGN (asm_out_file, 1);
 
@@ -29772,13 +29772,13 @@ static void
 arm_asm_init_sections (void)
 {
 #if ARM_UNWIND_INFO
-  exception_section = get_unnamed_section (0, output_section_asm_op,
+  casm->sec.exception = get_unnamed_section (0, output_section_asm_op,
 					   "\t.handlerdata");
 #endif /* ARM_UNWIND_INFO */
 
 #ifdef OBJECT_FORMAT_ELF
   if (target_pure_code)
-    text_section->unnamed.data = "\t.section .text,\"0x20000006\",%progbits";
+    casm->sec.text->unnamed.data = "\t.section .text,\"0x20000006\",%progbits";
 #endif
 }
 
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 015299c1534..845b965f75f 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -1613,7 +1613,7 @@ machine_function;
 #define ARM_GE_BITS_READ (arm_ge_bits_access ())
 
 /* As in the machine_function, a global set of call-via labels, for code 
-   that is in text_section.  */
+   that is in casm->sec.text.  */
 extern GTY(()) rtx thumb_call_via_label[14];
 
 /* The number of potential ways of assigning to a co-processor.  */
diff --git a/gcc/config/arm/unknown-elf.h b/gcc/config/arm/unknown-elf.h
index cca6f0ece54..6aba52284c3 100644
--- a/gcc/config/arm/unknown-elf.h
+++ b/gcc/config/arm/unknown-elf.h
@@ -61,7 +61,7 @@
       if (IN_NAMED_SECTION_P (DECL))					\
 	switch_to_section (get_named_section (DECL, NULL, 0));		\
       else								\
-	switch_to_section (bss_section);				\
+	switch_to_section (casm->sec.bss);				\
       									\
       ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT));	\
 									\
@@ -78,7 +78,7 @@
       if ((DECL) != NULL && IN_NAMED_SECTION_P (DECL))			\
 	switch_to_section (get_named_section (DECL, NULL, 0));		\
       else								\
-	switch_to_section (bss_section);				\
+	switch_to_section (casm->sec.bss);				\
 									\
       ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT));	\
       ASM_OUTPUT_LABEL (FILE, NAME);					\
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 200701a583c..c89e7b610ea 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -10085,7 +10085,7 @@ avr_asm_asm_output_aligned_bss (FILE *file, tree decl, const char *name,
 }
 
 
-/* Unnamed section callback for data_section
+/* Unnamed section callback for casm->sec.data
    to track need of __do_copy_data.  */
 
 static void
@@ -10098,7 +10098,7 @@ avr_output_data_section_asm_op (const void *data)
 }
 
 
-/* Unnamed section callback for bss_section
+/* Unnamed section callback for casm->sec.bss
    to track need of __do_clear_bss.  */
 
 static void
@@ -10133,9 +10133,9 @@ avr_asm_init_sections (void)
 #if defined HAVE_LD_AVR_AVRXMEGA3_RODATA_IN_FLASH
   if (avr_arch->flash_pm_offset == 0)
 #endif
-    readonly_data_section->unnamed.callback = avr_output_data_section_asm_op;
-  data_section->unnamed.callback = avr_output_data_section_asm_op;
-  bss_section->unnamed.callback = avr_output_bss_section_asm_op;
+    casm->sec.readonly_data->unnamed.callback = avr_output_data_section_asm_op;
+  casm->sec.data->unnamed.callback = avr_output_data_section_asm_op;
+  casm->sec.bss->unnamed.callback = avr_output_bss_section_asm_op;
 }
 
 
@@ -12567,7 +12567,7 @@ avr_output_addr_vec (rtx_insn *labl, rtx table)
   // Switch back to original section.  As we clobbered the section above,
   // forget the current section before switching back.
 
-  in_section = NULL;
+  casm->in_section = NULL;
   switch_to_section (current_function_section ());
 }
 
diff --git a/gcc/config/bfin/bfin.h b/gcc/config/bfin/bfin.h
index 823ca2d7124..4aaee42e0e6 100644
--- a/gcc/config/bfin/bfin.h
+++ b/gcc/config/bfin/bfin.h
@@ -1053,7 +1053,7 @@ do { char __buf[256];					\
 
 #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) 	\
 do { 						\
-    switch_to_section (data_section);				\
+    switch_to_section (casm->sec.data);				\
     if ((SIZE) >= (unsigned int) 4 ) ASM_OUTPUT_ALIGN(FILE,2);	\
     ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);		\
     ASM_OUTPUT_LABEL (FILE, NAME);				\
diff --git a/gcc/config/c6x/c6x.c b/gcc/config/c6x/c6x.c
index ce4949516cf..b2b9685bac8 100644
--- a/gcc/config/c6x/c6x.c
+++ b/gcc/config/c6x/c6x.c
@@ -890,7 +890,7 @@ c6x_select_rtx_section (machine_mode mode, rtx x,
   if (c6x_sdata_mode == C6X_SDATA_ALL
       || (c6x_sdata_mode != C6X_SDATA_NONE && GET_MODE_SIZE (mode) <= 8))
     /* ??? Consider using mergeable sdata sections.  */
-    return sdata_section;
+    return casm->sec.sdata;
   else
     return default_elf_select_rtx_section (mode, x, align);
 }
@@ -5473,7 +5473,7 @@ c6x_asm_emit_except_personality (rtx personality)
 static void
 c6x_asm_init_sections (void)
 {
-  exception_section = get_unnamed_section (0, output_section_asm_op,
+  casm->sec.exception = get_unnamed_section (0, output_section_asm_op,
 					   "\t.handlerdata");
 }
 
diff --git a/gcc/config/c6x/c6x.h b/gcc/config/c6x/c6x.h
index 9e0a20d20cb..4b9ec51bd72 100644
--- a/gcc/config/c6x/c6x.h
+++ b/gcc/config/c6x/c6x.h
@@ -557,9 +557,9 @@ do { char __buf[256];					\
 #define ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN)	\
 do {									\
   if (PLACE_IN_SDATA_P (DECL))						\
-    switch_to_section (sbss_section);					\
+    switch_to_section (casm->sec.sbss);					\
   else									\
-    switch_to_section (bss_section);					\
+    switch_to_section (casm->sec.bss);					\
   ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
   if (!flag_inhibit_size_directive)					\
     ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);			\
diff --git a/gcc/config/csky/csky.c b/gcc/config/csky/csky.c
index e55821fe2ee..3e8607c1ccc 100644
--- a/gcc/config/csky/csky.c
+++ b/gcc/config/csky/csky.c
@@ -958,7 +958,7 @@ get_csky_jump_table_size (rtx insn)
 {
   /* ADDR_VECs only take room if read-only data does into the text
      section.  */
-  if (JUMP_TABLES_IN_TEXT_SECTION || readonly_data_section == text_section)
+  if (JUMP_TABLES_IN_TEXT_SECTION || casm->sec.readonly_data == casm->sec.text)
     {
       rtx body = PATTERN (insn);
       int elt = GET_CODE (body) == ADDR_DIFF_VEC ? 1 : 0;
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index abcbdb1e028..52dfa63048e 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -143,7 +143,7 @@ output_objc_section_asm_op (const void *directive)
      section is requested.  */
   if (darwin_symbol_stubs && ! been_here)
     {
-      section *saved_in_section = in_section;
+      section *saved_in_section = casm->in_section;
       static const enum darwin_section_enum tomark[] =
 	{
 	  /* written, cold -> hot */
@@ -236,14 +236,14 @@ darwin_init_sections (void)
 #include "config/darwin-sections.def"
 #undef DEF_SECTION
 
-  readonly_data_section = darwin_sections[const_section];
-  exception_section = darwin_sections[darwin_exception_section];
-  eh_frame_section = darwin_sections[darwin_eh_frame_section];
+  casm->sec.readonly_data = darwin_sections[const_section];
+  casm->sec.exception = darwin_sections[darwin_exception_section];
+  casm->sec.eh_frame = darwin_sections[darwin_eh_frame_section];
 
   /* If our linker is new enough to coalesce weak symbols, then we
      can just put picbase_thunks into the text section.  */
   if (! ld_uses_coal_sects )
-    darwin_sections[picbase_thunk_section] = text_section;
+    darwin_sections[picbase_thunk_section] = casm->sec.text;
 }
 
 int
@@ -1071,7 +1071,7 @@ machopic_output_data_section_indirection (machopic_indirection **slot,
   /* The name of the indirection symbol.  */
   const char *ptr_name = p->ptr_name;
 
-  switch_to_section (data_section);
+  switch_to_section (casm->sec.data);
   assemble_align (GET_MODE_ALIGNMENT (Pmode));
   assemble_label (out_file, ptr_name);
   assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
@@ -1340,7 +1340,7 @@ darwin_mergeable_string_section (tree exp,
       && TREE_STRING_LENGTH (exp) == 0)
     return darwin_sections[zobj_const_section];
 
-  return readonly_data_section;
+  return casm->sec.readonly_data;
 }
 
 #ifndef HAVE_GAS_LITERAL16
@@ -1362,7 +1362,7 @@ darwin_mergeable_constant_section (tree exp,
       || align < 8
       || align > 256
       || (align & (align -1)) != 0)
-    return readonly_data_section;
+    return casm->sec.readonly_data;
 
   /* This will ICE if the mode is not a constant size, but that is reasonable,
      since one cannot put a variable-sized thing into a constant section, we
@@ -1370,12 +1370,12 @@ darwin_mergeable_constant_section (tree exp,
   const unsigned int modesize = GET_MODE_BITSIZE (mode).to_constant ();
 
   if (modesize > align)
-    return readonly_data_section;
+    return casm->sec.readonly_data;
 
   tree size = TYPE_SIZE_UNIT (TREE_TYPE (exp));
 
   if (TREE_CODE (size) != INTEGER_CST)
-    return readonly_data_section;
+    return casm->sec.readonly_data;
 
   unsigned isize = TREE_INT_CST_LOW (size);
   if (isize == 4)
@@ -1387,7 +1387,7 @@ darwin_mergeable_constant_section (tree exp,
 	   && isize == 16)
     return darwin_sections[literal16_section];
 
-  return readonly_data_section;
+  return casm->sec.readonly_data;
 }
 
 section *
@@ -1443,7 +1443,7 @@ darwin_objc2_section (tree decl ATTRIBUTE_UNUSED, tree meta, section * base)
 
   objc_metadata_seen = 1;
 
-  if (base == data_section)
+  if (base == casm->sec.data)
     base = darwin_sections[objc2_metadata_section];
 
   /* Most of the OBJC2 META-data end up in the base section, so check it
@@ -1494,7 +1494,7 @@ darwin_objc2_section (tree decl ATTRIBUTE_UNUSED, tree meta, section * base)
 
   else if (startswith (p, "V2_EHTY"))
     return ld_uses_coal_sects ? darwin_sections[data_coal_section]
-                              : data_section;
+                              : casm->sec.data;
 
   else if (startswith (p, "V2_CSTR"))
     return darwin_sections[objc2_constant_string_object_section];
@@ -1680,7 +1680,7 @@ machopic_select_section (tree decl,
       else if (ro)
 	base_section = darwin_sections[const_data_section];
       else
-	base_section = data_section;
+	base_section = casm->sec.data;
       break;
     case SECCAT_BSS:
     case SECCAT_SBSS:
@@ -1690,11 +1690,11 @@ machopic_select_section (tree decl,
       else
 	{
 	  if (!TREE_PUBLIC (decl))
-	    base_section = lcomm_section;
-	  else if (bss_noswitch_section)
-	    base_section = bss_noswitch_section;
+	    base_section = casm->sec.lcomm;
+	  else if (casm->sec.bss_noswitch)
+	    base_section = casm->sec.bss_noswitch;
 	  else
-	    base_section = data_section;
+	    base_section = casm->sec.data;
 	}
       break;
 
@@ -2365,8 +2365,8 @@ fprintf (file, "# dadon: %s %s (%llu, %u) local %d weak %d"
       /* Check that we've correctly picked up the zero-sized item and placed it
          properly.  */
       gcc_assert ((!DARWIN_SECTION_ANCHORS || !flag_section_anchors)
-		  || (in_section
-		      && (in_section->common.flags & SECTION_NO_ANCHOR)));
+		  || (casm->in_section
+		      && (casm->in_section->common.flags & SECTION_NO_ANCHOR)));
     }
   else
     ASM_OUTPUT_LABEL (file, xname);
@@ -2386,8 +2386,8 @@ darwin_asm_declare_constant_name (FILE *file, const char *name,
       /* Check that we've correctly picked up the zero-sized item and placed it
          properly.  */
       gcc_assert ((!DARWIN_SECTION_ANCHORS || !flag_section_anchors)
-		  || (in_section
-		      && (in_section->common.flags & SECTION_NO_ANCHOR)));
+		  || (casm->in_section
+		      && (casm->in_section->common.flags & SECTION_NO_ANCHOR)));
     }
 }
 
@@ -2424,7 +2424,7 @@ darwin_emit_weak_or_comdat (FILE *fp, tree decl, const char *name,
 				: darwin_sections[const_data_section]);
   else
     switch_to_section (use_coal ? darwin_sections[data_coal_section]
-				: data_section);
+				: casm->sec.data);
 
   /* To be consistent, we'll allow darwin_asm_declare_object_name to assemble
      the align info for zero-sized items... but do it here otherwise.  */
@@ -2446,7 +2446,7 @@ darwin_emit_objc_zeroed (FILE *fp, tree decl, const char *name,
 				  unsigned HOST_WIDE_INT size,
 				  unsigned int align, tree meta)
 {
-  section *ocs = data_section;
+  section *ocs = casm->sec.data;
 
   if (TREE_PURPOSE (meta) == get_identifier("OBJC2META"))
     ocs = darwin_objc2_section (decl, meta, ocs);
@@ -2488,13 +2488,13 @@ darwin_emit_local_bss (FILE *fp, tree decl, const char *name,
       if (!size)
 	{
 	  fputs ("\t.section\t__DATA,__zobj_bss\n", fp);
-	  in_section = darwin_sections[zobj_bss_section];
+	  casm->in_section = darwin_sections[zobj_bss_section];
 	  size = 1;
 	}
       else
 	{
 	  fputs ("\t.static_data\n", fp);
-	  in_section = darwin_sections[static_data_section];
+	  casm->in_section = darwin_sections[static_data_section];
 	}
 
       if (l2align)
@@ -2512,7 +2512,7 @@ darwin_emit_local_bss (FILE *fp, tree decl, const char *name,
       char secnam[64];
       snprintf (secnam, 64, "__DATA,__bss");
       unsigned int flags = SECTION_BSS|SECTION_WRITE|SECTION_NO_ANCHOR;
-      in_section = get_section (secnam, flags, NULL);
+      casm->in_section = get_section (secnam, flags, NULL);
       fprintf (fp, "\t.zerofill %s,", secnam);
       assemble_name (fp, name);
       if (!size)
@@ -2559,7 +2559,7 @@ darwin_emit_common (FILE *fp, const char *name,
   l2align = floor_log2 (align);
   gcc_assert (l2align <= L2_MAX_OFILE_ALIGNMENT);
 
-  in_section = comm_section;
+  casm->in_section = casm->sec.comm;
   /* We mustn't allow multiple public symbols to share an address when using
      the normal OSX toolchain.  */
   if (!size)
@@ -2567,7 +2567,7 @@ darwin_emit_common (FILE *fp, const char *name,
       /* Put at least one byte.  */
       size = 1;
       /* This section can no longer participate in section anchoring.  */
-      comm_section->common.flags |= SECTION_NO_ANCHOR;
+      casm->sec.comm->common.flags |= SECTION_NO_ANCHOR;
     }
 
   fputs ("\t.comm\t", fp);
@@ -2656,13 +2656,13 @@ fprintf (fp, "# albss: %s (%lld,%d) ro %d cst %d stat %d com %d"
       if (!size)
 	{
 	  fputs ("\t.section\t__DATA,__zobj_data\n", fp);
-	  in_section = darwin_sections[zobj_data_section];
+	  casm->in_section = darwin_sections[zobj_data_section];
 	  size = 1;
 	}
       else
 	{
 	  fputs ("\t.data\n", fp);
-	  in_section = data_section;
+	  casm->in_section = casm->sec.data;
 	}
 
       if (l2align)
@@ -2677,7 +2677,7 @@ fprintf (fp, "# albss: %s (%lld,%d) ro %d cst %d stat %d com %d"
       unsigned int flags = SECTION_BSS|SECTION_WRITE|SECTION_NO_ANCHOR;
       char secnam[64];
       snprintf (secnam, 64, "__DATA,__common");
-      in_section = get_section (secnam, flags, NULL);
+      casm->in_section = get_section (secnam, flags, NULL);
       fprintf (fp, "\t.zerofill %s,", secnam);
       assemble_name (fp, name);
       if (!size)
@@ -3893,7 +3893,7 @@ darwin_function_section (tree decl, enum node_frequency freq,
   /* Otherwise, default to the 'normal' non-reordered sections.  */
 default_function_sections:
   return (use_coal) ? darwin_sections[text_coal_section]
-		    : text_section;
+		    : casm->sec.text;
 }
 
 #include "gt-darwin.h"
diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c
index a7f7f086d17..01cb7d5f3fa 100644
--- a/gcc/config/frv/frv.c
+++ b/gcc/config/frv/frv.c
@@ -9395,7 +9395,7 @@ frv_rtx_costs (rtx x,
 static void
 frv_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
 {
-  switch_to_section (ctors_section);
+  switch_to_section (casm->sec.ctors);
   assemble_align (POINTER_SIZE);
   if (TARGET_FDPIC)
     {
@@ -9410,7 +9410,7 @@ frv_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
 static void
 frv_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
 {
-  switch_to_section (dtors_section);
+  switch_to_section (casm->sec.dtors);
   assemble_align (POINTER_SIZE);
   if (TARGET_FDPIC)
     {
diff --git a/gcc/config/frv/frv.h b/gcc/config/frv/frv.h
index 65091952ebd..6fd072c25d8 100644
--- a/gcc/config/frv/frv.h
+++ b/gcc/config/frv/frv.h
@@ -1540,7 +1540,7 @@ do {                                                                   	\
   if ((SIZE) > 0 && (SIZE) <= (unsigned HOST_WIDE_INT) g_switch_value)	\
     switch_to_section (get_named_section (NULL, ".sbss", 0));           \
   else                                                                 	\
-    switch_to_section (bss_section);                                  	\
+    switch_to_section (casm->sec.bss);                                  	\
   ASM_OUTPUT_ALIGN (STREAM, floor_log2 ((ALIGN) / BITS_PER_UNIT));     	\
   ASM_DECLARE_OBJECT_NAME (STREAM, NAME, DECL);                        	\
   ASM_OUTPUT_SKIP (STREAM, (SIZE) ? (SIZE) : 1);                       	\
diff --git a/gcc/config/ft32/ft32.h b/gcc/config/ft32/ft32.h
index f8d0763e394..8e2b0667b64 100644
--- a/gcc/config/ft32/ft32.h
+++ b/gcc/config/ft32/ft32.h
@@ -478,9 +478,9 @@ extern int ft32_is_mem_pm(rtx o);
 #define ASM_OUTPUT_SYMBOL_REF(stream, sym) \
   do { \
     assemble_name (stream, XSTR (sym, 0)); \
-    int section_debug = in_section && \
-      (SECTION_STYLE (in_section) == SECTION_NAMED) && \
-      (in_section->named.common.flags & SECTION_DEBUG); \
+    int section_debug = casm->in_section && \
+      (SECTION_STYLE (casm->in_section) == SECTION_NAMED) && \
+      (casm->in_section->named.common.flags & SECTION_DEBUG); \
     if (!section_debug && SYMBOL_REF_FLAGS (sym) & 0x1000) \
       asm_fprintf (stream, "-0x800000"); \
   } while (0)
diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h
index da872d10cd3..2826d2c35c6 100644
--- a/gcc/config/i386/cygming.h
+++ b/gcc/config/i386/cygming.h
@@ -187,7 +187,7 @@ along with GCC; see the file COPYING3.  If not see
 \f
 #define drectve_section() \
   (fprintf (asm_out_file, "\t.section .drectve\n"), \
-   in_section = NULL)
+   casm->in_section = NULL)
 
 /* Older versions of gas don't handle 'r' as data.
    Explicitly set data flag with 'd'.  */  
diff --git a/gcc/config/i386/darwin.h b/gcc/config/i386/darwin.h
index c4a6f4dfda7..d402a9a8b55 100644
--- a/gcc/config/i386/darwin.h
+++ b/gcc/config/i386/darwin.h
@@ -216,7 +216,7 @@ along with GCC; see the file COPYING3.  If not see
   do {								   \
     if ((LOG) != 0)						   \
       {								   \
-	if (in_section == text_section)				   \
+	if (casm->in_section == casm->sec.text)				   \
 	  fprintf (FILE, "\t%s %d,0x90\n", ALIGN_ASM_OP, (LOG));   \
 	else							   \
 	  fprintf (FILE, "\t%s %d\n", ALIGN_ASM_OP, (LOG));	   \
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index a5c4fa857a7..4834c353fc3 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -869,7 +869,7 @@ x86_output_aligned_bss (FILE *file, tree decl, const char *name,
       && size > (unsigned int)ix86_section_threshold)
     switch_to_section (get_named_section (decl, ".lbss", 0));
   else
-    switch_to_section (bss_section);
+    switch_to_section (casm->sec.bss);
   ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
 #ifdef ASM_DECLARE_OBJECT_NAME
   last_assemble_variable_decl = decl;
@@ -5954,7 +5954,7 @@ output_indirect_thunk_function (enum indirect_thunk_prefix need_prefix,
       }
     else
       {
-	switch_to_section (text_section);
+	switch_to_section (casm->sec.text);
 	ASM_OUTPUT_LABEL (asm_out_file, name);
       }
 
@@ -6074,7 +6074,7 @@ ix86_code_end (void)
 	}
       else
 	{
-	  switch_to_section (text_section);
+	  switch_to_section (casm->sec.text);
 	  ASM_OUTPUT_LABEL (asm_out_file, name);
 	}
 
diff --git a/gcc/config/i386/sol2.h b/gcc/config/i386/sol2.h
index 29b37a143f5..7297db2bb70 100644
--- a/gcc/config/i386/sol2.h
+++ b/gcc/config/i386/sol2.h
@@ -195,9 +195,9 @@ along with GCC; see the file COPYING3.  If not see
   do									\
     {									\
       if (TARGET_SUN_TLS						\
-	  && in_section							\
-	  && ((in_section->common.flags & SECTION_TLS) == SECTION_TLS))	\
-	switch_to_section (bss_section);				\
+	  && casm->in_section							\
+	  && ((casm->in_section->common.flags & SECTION_TLS) == SECTION_TLS))	\
+	switch_to_section (casm->sec.bss);				\
       x86_elf_aligned_decl_common (FILE, DECL, NAME, SIZE, ALIGN);	\
     }									\
   while  (0)
diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c
index 7c0ea4f731c..a25412ddf30 100644
--- a/gcc/config/i386/winnt.c
+++ b/gcc/config/i386/winnt.c
@@ -1347,7 +1347,7 @@ void
 i386_pe_seh_init_sections (void)
 {
   if (TARGET_SEH)
-    exception_section = get_unnamed_section (0, output_section_asm_op,
+    casm->sec.exception = get_unnamed_section (0, output_section_asm_op,
 					     "\t.seh_handlerdata");
 }
 \f
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index cdf78cdc518..ef94d33ec27 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -10406,7 +10406,7 @@ ia64_asm_emit_except_personality (rtx personality)
 static void
 ia64_asm_init_sections (void)
 {
-  exception_section = get_unnamed_section (0, output_section_asm_op,
+  casm->sec.exception = get_unnamed_section (0, output_section_asm_op,
 					   "\t.handlerdata");
 }
 
@@ -10858,7 +10858,7 @@ ia64_select_rtx_section (machine_mode mode, rtx x,
   if (GET_MODE_SIZE (mode) > 0
       && GET_MODE_SIZE (mode) <= ia64_section_threshold
       && !TARGET_NO_SDATA)
-    return sdata_section;
+    return casm->sec.sdata;
   else
     return default_elf_select_rtx_section (mode, x, align);
 }
diff --git a/gcc/config/ia64/sysv4.h b/gcc/config/ia64/sysv4.h
index a4133d3beab..a68f28074fb 100644
--- a/gcc/config/ia64/sysv4.h
+++ b/gcc/config/ia64/sysv4.h
@@ -69,9 +69,9 @@ extern int size_directive_output;
 #define ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN) \
 do {									\
   if ((DECL) && sdata_symbolic_operand (XEXP (DECL_RTL (DECL), 0), Pmode)) \
-    switch_to_section (sbss_section);					\
+    switch_to_section (casm->sec.sbss);					\
   else									\
-    switch_to_section (bss_section);					\
+    switch_to_section (casm->sec.bss);					\
   ASM_OUTPUT_ALIGN (FILE, floor_log2 ((ALIGN) / BITS_PER_UNIT));	\
   ASM_DECLARE_OBJECT_NAME (FILE, NAME, DECL);				\
   ASM_OUTPUT_SKIP (FILE, SIZE ? SIZE : 1);				\
diff --git a/gcc/config/lm32/lm32.h b/gcc/config/lm32/lm32.h
index a13c0c50ee1..d665c38f0e3 100644
--- a/gcc/config/lm32/lm32.h
+++ b/gcc/config/lm32/lm32.h
@@ -385,9 +385,9 @@ enum reg_class
 #define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)		\
 do {									\
   if ((SIZE) <= (unsigned HOST_WIDE_INT) g_switch_value)		\
-    switch_to_section (sbss_section);					\
+    switch_to_section (casm->sec.sbss);					\
   else									\
-    switch_to_section (bss_section);					\
+    switch_to_section (casm->sec.bss);					\
   ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
   if (!flag_inhibit_size_directive)					\
     ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);			\
@@ -403,7 +403,7 @@ do 									\
 {									\
   if ((SIZE) <= (unsigned HOST_WIDE_INT) g_switch_value)		\
     {									\
-      switch_to_section (sbss_section);					\
+      switch_to_section (casm->sec.sbss);					\
       (*targetm.asm_out.globalize_label) (FILE, NAME);			\
       ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
       if (!flag_inhibit_size_directive)					\
@@ -414,7 +414,7 @@ do 									\
     }									\
   else									\
     {									\
-      switch_to_section (bss_section);					\
+      switch_to_section (casm->sec.bss);					\
       fprintf ((FILE), "%s", COMMON_ASM_OP);				\
       assemble_name ((FILE), (NAME));					\
       fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED",%u\n",          \
diff --git a/gcc/config/m32r/m32r.h b/gcc/config/m32r/m32r.h
index 047805fd808..64b5f69f3a7 100644
--- a/gcc/config/m32r/m32r.h
+++ b/gcc/config/m32r/m32r.h
@@ -897,7 +897,7 @@ L2:     .word STATIC
 	  && (SIZE) <= (unsigned HOST_WIDE_INT) g_switch_value)		\
         switch_to_section (get_named_section (NULL, ".sbss", 0));	\
       else								\
-        switch_to_section (bss_section);				\
+        switch_to_section (casm->sec.bss);				\
       ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT));	\
       last_assemble_variable_decl = DECL;				\
       ASM_DECLARE_OBJECT_NAME (FILE, NAME, DECL);			\
diff --git a/gcc/config/mcore/mcore-elf.h b/gcc/config/mcore/mcore-elf.h
index d50f578c3dd..02278eec3c3 100644
--- a/gcc/config/mcore/mcore-elf.h
+++ b/gcc/config/mcore/mcore-elf.h
@@ -33,7 +33,7 @@ along with GCC; see the file COPYING3.  If not see
       fprintf (STREAM, "\t.section .exports\n");	\
       fprintf (STREAM, "\t.ascii \" -export:%s\"\n",	\
 	       (* targetm.strip_name_encoding) (NAME));	\
-      in_section = NULL;				\
+      casm->in_section = NULL;				\
     }							\
   while (0)
 
@@ -63,7 +63,7 @@ along with GCC; see the file COPYING3.  If not see
       HOST_WIDE_INT size;					\
       if (mcore_dllexport_name_p (NAME))			\
         {							\
-	  section *save_section = in_section;			\
+	  section *save_section = casm->in_section;			\
 	  MCORE_EXPORT_NAME (FILE, NAME);			\
 	  switch_to_section (save_section);			\
         }							\
diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c
index 6e8f367c80a..0028da494ea 100644
--- a/gcc/config/microblaze/microblaze.c
+++ b/gcc/config/microblaze/microblaze.c
@@ -2836,9 +2836,9 @@ microblaze_elf_asm_cdtor (rtx symbol, int priority, bool is_ctor)
       s = get_section (buf, SECTION_WRITE, NULL_TREE);
     }
   else if (is_ctor)
-    s = ctors_section;
+    s = casm->sec.ctors;
   else
-    s = dtors_section;
+    s = casm->sec.dtors;
 
   switch_to_section (s);
   assemble_align (POINTER_SIZE);
@@ -3261,7 +3261,7 @@ microblaze_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
          relaxation/relocation. Currently, turning mergeable sections 
          into regular readonly sections.  */
 
-      return readonly_data_section;
+      return casm->sec.readonly_data;
     default:
       return default_elf_select_section (decl, reloc, align);
     }
diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h
index 2ecec750526..3f1368d0884 100644
--- a/gcc/config/microblaze/microblaze.h
+++ b/gcc/config/microblaze/microblaze.h
@@ -623,11 +623,11 @@ do {									\
       && (int) (SIZE) <= microblaze_section_threshold			\
       && TARGET_XLGPOPT)						\
     {                                                                   \
-      switch_to_section (sbss_section);					\
+      switch_to_section (casm->sec.sbss);					\
     }									\
   else									\
     {									\
-      switch_to_section (bss_section);					\
+      switch_to_section (casm->sec.bss);					\
     }                                                                   \
   fprintf (FILE, "%s", COMMON_ASM_OP);                                  \
   assemble_name ((FILE), (NAME));					\
@@ -643,11 +643,11 @@ do {									\
       && (int) (SIZE) <= microblaze_section_threshold			\
       && TARGET_XLGPOPT)						\
     {                                                                   \
-      switch_to_section (sbss_section);					\
+      switch_to_section (casm->sec.sbss);					\
     }									\
   else									\
     {									\
-      switch_to_section (bss_section);					\
+      switch_to_section (casm->sec.bss);					\
     }                                                                   \
   fprintf (FILE, "%s", LCOMMON_ASM_OP);                                 \
   assemble_name ((FILE), (NAME));					\
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index ade5d7041f0..a83015cacc0 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -9718,7 +9718,7 @@ mips_output_aligned_decl_common (FILE *stream, tree decl, const char *name,
       if (TREE_PUBLIC (decl) && DECL_NAME (decl))
 	targetm.asm_out.globalize_label (stream, name);
 
-      switch_to_section (readonly_data_section);
+      switch_to_section (casm->sec.readonly_data);
       ASM_OUTPUT_ALIGN (stream, floor_log2 (align / BITS_PER_UNIT));
       mips_declare_object (stream, name, "",
 			   ":\n\t.space\t" HOST_WIDE_INT_PRINT_UNSIGNED "\n",
diff --git a/gcc/config/mmix/mmix.c b/gcc/config/mmix/mmix.c
index 010cd4773ea..4ea07819983 100644
--- a/gcc/config/mmix/mmix.c
+++ b/gcc/config/mmix/mmix.c
@@ -1321,7 +1321,7 @@ mmix_file_start (void)
   fputs ("! mmixal:= 8H LOC Data_Section\n", asm_out_file);
 
   /* Make sure each file starts with the text section.  */
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
 }
 
 /* TARGET_ASM_FILE_END.  */
@@ -1330,7 +1330,7 @@ static void
 mmix_file_end (void)
 {
   /* Make sure each file ends with the data section.  */
-  switch_to_section (data_section);
+  switch_to_section (casm->sec.data);
 }
 
 /* TARGET_ASM_OUTPUT_SOURCE_FILENAME.  */
@@ -1510,7 +1510,7 @@ mmix_asm_output_aligned_local (FILE *stream,
 			       int size,
 			       int align)
 {
-  switch_to_section (data_section);
+  switch_to_section (casm->sec.data);
 
   ASM_OUTPUT_ALIGN (stream, exact_log2 (align/BITS_PER_UNIT));
   assemble_name (stream, name);
diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c
index 1cdacb7f480..ba41ce1f54a 100644
--- a/gcc/config/msp430/msp430.c
+++ b/gcc/config/msp430/msp430.c
@@ -2398,22 +2398,22 @@ msp430_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
     {
     case SECCAT_TEXT:
       if (!prefix)
-	return text_section;
+	return casm->sec.text;
       base_sec_name = ".text";
       break;
     case SECCAT_DATA:
       if (!prefix)
-	return data_section;
+	return casm->sec.data;
       base_sec_name = ".data";
       break;
     case SECCAT_BSS:
       if (!prefix)
-	return bss_section;
+	return casm->sec.bss;
       base_sec_name = ".bss";
       break;
     case SECCAT_RODATA:
       if (!prefix)
-	return readonly_data_section;
+	return casm->sec.readonly_data;
       base_sec_name = ".rodata";
       break;
 
diff --git a/gcc/config/nios2/nios2.h b/gcc/config/nios2/nios2.h
index dfca12cc525..c2da347062b 100644
--- a/gcc/config/nios2/nios2.h
+++ b/gcc/config/nios2/nios2.h
@@ -470,9 +470,9 @@ while (0)
 #define ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN)	\
 do {                                                                    \
  if (targetm.in_small_data_p (DECL))					\
-    switch_to_section (sbss_section);					\
+    switch_to_section (casm->sec.sbss);					\
   else                                                                  \
-    switch_to_section (bss_section);					\
+    switch_to_section (casm->sec.bss);					\
   ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");                     \
   if (!flag_inhibit_size_directive)                                     \
     ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);                       \
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 06143023b46..93b34790738 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -4444,7 +4444,7 @@ pa_output_function_epilogue (FILE *file)
       /* We are done with this subspace except possibly for some additional
 	 debug information.  Forget that we are in this subspace to ensure
 	 that the next function is output in its own subspace.  */
-      in_section = NULL;
+      casm->in_section = NULL;
       cfun->machine->in_nsubspa = 2;
     }
 
@@ -4693,7 +4693,7 @@ output_deferred_profile_counters (void)
   if (funcdef_nos.is_empty ())
    return;
 
-  switch_to_section (data_section);
+  switch_to_section (casm->sec.data);
   align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE);
   ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
 
@@ -5863,7 +5863,7 @@ output_deferred_plabels (void)
      before outputting the deferred plabels.  */
   if (n_deferred_plabels)
     {
-      switch_to_section (flag_pic ? data_section : readonly_data_section);
+      switch_to_section (flag_pic ? casm->sec.data : casm->sec.readonly_data);
       ASM_OUTPUT_ALIGN (asm_out_file, TARGET_64BIT ? 3 : 2);
     }
 
@@ -8872,7 +8872,7 @@ pa_asm_output_mi_thunk (FILE *file, tree thunk_fndecl, HOST_WIDE_INT delta,
 
   if (TARGET_SOM && flag_pic && TREE_PUBLIC (function))
     {
-      switch_to_section (data_section);
+      switch_to_section (casm->sec.data);
       output_asm_insn (".align 4", xoperands);
       ASM_OUTPUT_LABEL (file, label);
       output_asm_insn (".word P'%0", xoperands);
@@ -9047,7 +9047,7 @@ pa_asm_output_aligned_bss (FILE *stream,
 			   unsigned HOST_WIDE_INT size,
 			   unsigned int align)
 {
-  switch_to_section (bss_section);
+  switch_to_section (casm->sec.bss);
 
 #ifdef ASM_OUTPUT_TYPE_DIRECTIVE
   ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "object");
@@ -9084,7 +9084,7 @@ pa_asm_output_aligned_common (FILE *stream,
       align = max_common_align;
     }
 
-  switch_to_section (bss_section);
+  switch_to_section (casm->sec.bss);
 
   assemble_name (stream, name);
   fprintf (stream, "\t.comm " HOST_WIDE_INT_PRINT_UNSIGNED"\n",
@@ -9104,7 +9104,7 @@ pa_asm_output_aligned_local (FILE *stream,
 			     unsigned HOST_WIDE_INT size,
 			     unsigned int align)
 {
-  switch_to_section (bss_section);
+  switch_to_section (casm->sec.bss);
   fprintf (stream, "\t.align %u\n", align / BITS_PER_UNIT);
 
 #ifdef LOCAL_ASM_OP
@@ -10030,10 +10030,10 @@ som_output_text_section_asm_op (const void *data ATTRIBUTE_UNUSED)
 	     function has been completed.  So, we are changing to the
 	     text section to output debugging information.  Thus, we
 	     need to forget that we are in the text section so that
-	     varasm.c will call us when text_section is selected again.  */
+	     varasm.c will call us when casm->sec.text is selected again.  */
 	  gcc_assert (!cfun || !cfun->machine
 		      || cfun->machine->in_nsubspa == 2);
-	  in_section = NULL;
+	  casm->in_section = NULL;
 	}
       output_section_asm_op ("\t.SPACE $TEXT$\n\t.NSUBSPA $CODE$");
       return;
@@ -10047,7 +10047,7 @@ som_output_text_section_asm_op (const void *data ATTRIBUTE_UNUSED)
 static void
 som_output_comdat_data_section_asm_op (const void *data)
 {
-  in_section = NULL;
+  casm->in_section = NULL;
   output_section_asm_op (data);
 }
 
@@ -10056,7 +10056,7 @@ som_output_comdat_data_section_asm_op (const void *data)
 static void
 pa_som_asm_init_sections (void)
 {
-  text_section
+  casm->sec.text
     = get_unnamed_section (0, som_output_text_section_asm_op, NULL);
 
   /* SOM puts readonly data in the default $LIT$ subspace when PIC code
@@ -10104,14 +10104,14 @@ pa_som_asm_init_sections (void)
      when generating PIC code.  This reduces sharing, but it works
      correctly.  Now we rely on pa_reloc_rw_mask() for section selection.
      This puts constant data not needing relocation into the $TEXT$ space.  */
-  readonly_data_section = som_readonly_data_section;
+  casm->sec.readonly_data = som_readonly_data_section;
 
   /* We must not have a reference to an external symbol defined in a
      shared library in a readonly section, else the SOM linker will
      complain.
 
      So, we force exception information into the data section.  */
-  exception_section = data_section;
+  casm->sec.exception = casm->sec.data;
 }
 
 /* Implement TARGET_ASM_TM_CLONE_TABLE_SECTION.  */
@@ -10144,18 +10144,18 @@ pa_select_section (tree exp, int reloc,
 	  && !DECL_WEAK (exp))
 	return som_one_only_readonly_data_section;
       else
-	return readonly_data_section;
+	return casm->sec.readonly_data;
     }
   else if (CONSTANT_CLASS_P (exp)
 	   && !(reloc & pa_reloc_rw_mask ()))
-    return readonly_data_section;
+    return casm->sec.readonly_data;
   else if (TARGET_SOM
 	   && TREE_CODE (exp) == VAR_DECL
 	   && DECL_ONE_ONLY (exp)
 	   && !DECL_WEAK (exp))
     return som_one_only_data_section;
   else
-    return data_section;
+    return casm->sec.data;
 }
 
 /* Implement pa_elf_select_rtx_section.  If X is a function label operand
@@ -10648,7 +10648,7 @@ pa_function_section (tree decl, enum node_frequency freq,
 {
   /* Put functions in text section if target doesn't have named sections.  */
   if (!targetm_common.have_named_sections)
-    return text_section;
+    return casm->sec.text;
 
   /* Force nested functions into the same section as the containing
      function.  */
diff --git a/gcc/config/pdp11/pdp11.c b/gcc/config/pdp11/pdp11.c
index ced653116a4..11b123c0586 100644
--- a/gcc/config/pdp11/pdp11.c
+++ b/gcc/config/pdp11/pdp11.c
@@ -743,7 +743,7 @@ void
 pdp11_asm_output_var (FILE *file, const char *name, int size,
 		      int align, bool global)
 {
-  switch_to_section (data_section);
+  switch_to_section (casm->sec.data);
   if (align > 8)
     fprintf (file, "\t.even\n");
   if (TARGET_DEC_ASM)
@@ -2323,11 +2323,11 @@ pdp11_asm_init_sections (void)
 {
   if (TARGET_DEC_ASM)
     {
-      bss_section = data_section;
+      casm->sec.bss = casm->sec.data;
     }
   else if (TARGET_GNU_ASM)
     {
-      bss_section = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
+      casm->sec.bss = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
 					 output_section_asm_op,
 					 ".bss");
     }
diff --git a/gcc/config/pru/pru.h b/gcc/config/pru/pru.h
index 9b6be323e6d..68a55ba6fc7 100644
--- a/gcc/config/pru/pru.h
+++ b/gcc/config/pru/pru.h
@@ -542,7 +542,7 @@ while (0)
 #undef  ASM_OUTPUT_ALIGNED_LOCAL
 #define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)		\
 do {									\
-  switch_to_section (bss_section);					\
+  switch_to_section (casm->sec.bss);					\
   ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
   if (!flag_inhibit_size_directive)					\
     ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);			\
diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
index 576960bb37c..9eaa2dca44a 100644
--- a/gcc/config/riscv/riscv.c
+++ b/gcc/config/riscv/riscv.c
@@ -3615,8 +3615,8 @@ riscv_elf_select_rtx_section (machine_mode mode, rtx x,
 	  return get_section (name, s->named.common.flags, NULL);
 	}
 
-      if (s == data_section)
-	return sdata_section;
+      if (s == casm->sec.data)
+	return casm->sec.sdata;
     }
 
   return s;
diff --git a/gcc/config/rl78/rl78.c b/gcc/config/rl78/rl78.c
index 4c34949a97f..0129929c821 100644
--- a/gcc/config/rl78/rl78.c
+++ b/gcc/config/rl78/rl78.c
@@ -4644,14 +4644,14 @@ rl78_select_section (tree decl,
     }
 
   if (readonly)
-    return TARGET_ES0 ? frodata_section : readonly_data_section;
+    return TARGET_ES0 ? frodata_section : casm->sec.readonly_data;
 
   switch (categorize_decl_for_section (decl, reloc))
     {
-    case SECCAT_TEXT:   return text_section;
-    case SECCAT_DATA:   return data_section;
-    case SECCAT_BSS:    return bss_section;
-    case SECCAT_RODATA: return TARGET_ES0 ? frodata_section : readonly_data_section;
+    case SECCAT_TEXT:   return casm->sec.text;
+    case SECCAT_DATA:   return casm->sec.data;
+    case SECCAT_BSS:    return casm->sec.bss;
+    case SECCAT_RODATA: return TARGET_ES0 ? frodata_section : casm->sec.readonly_data;
     default:
       return default_select_section (decl, reloc, align);
     }
@@ -4786,7 +4786,7 @@ rl78_asm_ctor_dtor (rtx symbol, int priority, bool is_ctor)
       sec = get_section (buf, 0, NULL);
     }
   else
-    sec = is_ctor ? ctors_section : dtors_section;
+    sec = is_ctor ? casm->sec.ctors : casm->sec.dtors;
 
   assemble_addr_to_section (symbol, sec);
 }
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index ad81dfb316d..af737c5bd56 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -14499,7 +14499,7 @@ rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
 	 section.  */
       if (DEFAULT_ABI == ABI_V4
 	  && (TARGET_RELOCATABLE || flag_pic > 1)
-	  && in_section != toc_section
+	  && casm->in_section != toc_section
 	  && !recurse
 	  && !CONST_SCALAR_INT_P (x)
 	  && CONSTANT_P (x))
@@ -21048,7 +21048,7 @@ rs6000_elf_file_end (void)
       /* We have expanded a CPU builtin, so we need to emit a reference to
 	 the special symbol that LIBC uses to declare it supports the
 	 AT_PLATFORM and AT_HWCAP/AT_HWCAP2 in the TCB feature.  */
-      switch_to_section (data_section);
+      switch_to_section (casm->sec.data);
       fprintf (asm_out_file, "\t.align %u\n", TARGET_32BIT ? 2 : 3);
       fprintf (asm_out_file, "\t%s %s\n",
 	       TARGET_32BIT ? ".long" : ".quad", tcb_verification_symbol);
@@ -21173,7 +21173,7 @@ rs6000_xcoff_asm_init_sections (void)
   toc_section
     = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
 
-  readonly_data_section = read_only_data_section;
+  casm->sec.readonly_data = read_only_data_section;
 }
 
 static int
@@ -21251,7 +21251,7 @@ rs6000_xcoff_select_section (tree decl, int reloc,
       if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL_P (decl))
 	{
 	  if (bss_initializer_p (decl))
-	    return tls_comm_section;
+	    return casm->sec.tls_comm;
 	  else if (TREE_PUBLIC (decl))
 	    return tls_data_section;
 	  else
@@ -21260,7 +21260,7 @@ rs6000_xcoff_select_section (tree decl, int reloc,
       else
 #endif
 	if (TREE_PUBLIC (decl))
-	return data_section;
+	return casm->sec.data;
       else
 	return private_data_section;
     }
@@ -21365,7 +21365,7 @@ rs6000_xcoff_file_start (void)
   if (write_symbols != NO_DEBUG)
     switch_to_section (private_data_section);
   switch_to_section (toc_section);
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
   if (profile_flag)
     fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
   rs6000_file_start ();
@@ -21377,9 +21377,9 @@ rs6000_xcoff_file_start (void)
 static void
 rs6000_xcoff_file_end (void)
 {
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
   fputs ("_section_.text:\n", asm_out_file);
-  switch_to_section (data_section);
+  switch_to_section (casm->sec.data);
   fputs (TARGET_32BIT
 	 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
 	 asm_out_file);
@@ -21499,7 +21499,7 @@ rs6000_xcoff_visibility (tree decl)
    Dollar signs are converted to underscores.
 
    The csect for the function will have already been created when
-   text_section was selected.  We do have to go back to that csect, however.
+   casm->sec.text was selected.  We do have to go back to that csect, however.
 
    The third and fourth parameters to the .function pseudo-op (16 and 044)
    are placeholders which no longer have any use.
@@ -21561,7 +21561,7 @@ rs6000_xcoff_declare_function_name (FILE *file, const char *name, tree decl)
   RS6000_OUTPUT_BASENAME (file, buffer);
   fputs (", TOC[tc0], 0\n", file);
 
-  in_section = NULL;
+  casm->in_section = NULL;
   switch_to_section (function_section (decl));
   putc ('.', file);
   ASM_OUTPUT_LABEL (file, buffer);
@@ -21621,7 +21621,7 @@ rs6000_xcoff_asm_output_aligned_decl_common (FILE *stream,
   if (! DECL_COMMON (decl))
     {
       /* Forget section.  */
-      in_section = NULL;
+      casm->in_section = NULL;
 
       /* Globalize TLS BSS.  */
       if (TREE_PUBLIC (decl) && DECL_THREAD_LOCAL_P (decl))
@@ -26617,7 +26617,7 @@ rs6000_code_end (void)
   else
 #endif
     {
-      switch_to_section (text_section);
+      switch_to_section (casm->sec.text);
       ASM_OUTPUT_LABEL (asm_out_file, name);
     }
 
diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
index 23ff59403a3..09bd4ed64bc 100644
--- a/gcc/config/rs6000/sysv4.h
+++ b/gcc/config/rs6000/sysv4.h
@@ -427,7 +427,7 @@ do {									\
 do {									\
   if ((DECL) && rs6000_elf_in_small_data_p (DECL))			\
     {									\
-      switch_to_section (sbss_section);					\
+      switch_to_section (casm->sec.sbss);					\
       ASM_OUTPUT_ALIGN (FILE, exact_log2 (ALIGN / BITS_PER_UNIT));	\
       ASM_OUTPUT_LABEL (FILE, NAME);					\
       ASM_OUTPUT_SKIP (FILE, SIZE);					\
diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c
index af54ccc2588..c45aface21d 100644
--- a/gcc/config/rx/rx.c
+++ b/gcc/config/rx/rx.c
@@ -2305,7 +2305,7 @@ rx_select_rtx_section (machine_mode mode,
   if (rx_small_data_limit > 0
       && GET_MODE_SIZE (mode) <= rx_small_data_limit
       && align <= (unsigned HOST_WIDE_INT) rx_small_data_limit * BITS_PER_UNIT)
-    return sdata_section;
+    return casm->sec.sdata;
 
   return default_elf_select_rtx_section (mode, x, align);
 }
@@ -2319,8 +2319,8 @@ rx_select_section (tree decl,
     {
       switch (categorize_decl_for_section (decl, reloc))
 	{
-	case SECCAT_SDATA:	return sdata_section;
-	case SECCAT_SBSS:	return sbss_section;
+	case SECCAT_SDATA:	return casm->sec.sdata;
+	case SECCAT_SBSS:	return casm->sec.sbss;
 	case SECCAT_SRODATA:
 	  /* Fall through.  We do not put small, read only
 	     data into the C_2 section because we are not
@@ -2342,7 +2342,7 @@ rx_select_section (tree decl,
       case SECCAT_RODATA_MERGE_CONST:
       case SECCAT_RODATA_MERGE_STR_INIT:
       case SECCAT_RODATA_MERGE_STR:
-	return readonly_data_section;
+	return casm->sec.readonly_data;
 
       default:
 	break;
@@ -2690,9 +2690,9 @@ rx_elf_asm_cdtor (rtx symbol, int priority, bool is_ctor)
       s = get_section (buf, SECTION_WRITE, NULL_TREE);
     }
   else if (is_ctor)
-    s = ctors_section;
+    s = casm->sec.ctors;
   else
-    s = dtors_section;
+    s = casm->sec.dtors;
 
   switch_to_section (s);
   assemble_align (POINTER_SIZE);
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 3e422f045c9..10b33976a97 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -16612,7 +16612,7 @@ s390_output_indirect_thunk_function (unsigned int regno, bool z10_p)
     }
   else
     {
-      switch_to_section (text_section);
+      switch_to_section (casm->sec.text);
       ASM_OUTPUT_LABEL (asm_out_file, thunk_label);
     }
 
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 1564109c942..ef42fc7d489 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -2828,7 +2828,7 @@ sh_file_start (void)
   else
     /* Switch to the data section so that the coffsem symbol
        isn't in the text section.  */
-    switch_to_section (data_section);
+    switch_to_section (casm->sec.data);
 
   if (TARGET_LITTLE_ENDIAN)
     fputs ("\t.little\n", asm_out_file);
diff --git a/gcc/config/sparc/sol2.h b/gcc/config/sparc/sol2.h
index 1b4aa28bd21..1dd33daa447 100644
--- a/gcc/config/sparc/sol2.h
+++ b/gcc/config/sparc/sol2.h
@@ -399,9 +399,9 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
   do									\
     {									\
       if (TARGET_SUN_TLS						\
-	  && in_section							\
-	  && ((in_section->common.flags & SECTION_TLS) == SECTION_TLS))	\
-	switch_to_section (bss_section);				\
+	  && casm->in_section							\
+	  && ((casm->in_section->common.flags & SECTION_TLS) == SECTION_TLS))	\
+	switch_to_section (casm->sec.bss);				\
       fprintf ((FILE), "%s", COMMON_ASM_OP);				\
       assemble_name ((FILE), (NAME));					\
       fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED",%u\n",		\
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 06f41d7bb53..8b1d64117a9 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -12499,7 +12499,7 @@ sparc_file_end (void)
       else
 	{
 	  const int align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
-          switch_to_section (text_section);
+          switch_to_section (casm->sec.text);
 	  if (align > 0)
 	    ASM_OUTPUT_ALIGN (asm_out_file, align);
 	  ASM_OUTPUT_LABEL (asm_out_file, name);
diff --git a/gcc/config/tilegx/tilegx.h b/gcc/config/tilegx/tilegx.h
index b0dcccfa3aa..931d900002b 100644
--- a/gcc/config/tilegx/tilegx.h
+++ b/gcc/config/tilegx/tilegx.h
@@ -290,7 +290,7 @@ enum reg_class
 
 #define TRAMPOLINE_SIZE (TARGET_32BIT ? 48 : 56)
 #define TRAMPOLINE_ALIGNMENT 64
-#define TRAMPOLINE_SECTION text_section
+#define TRAMPOLINE_SECTION casm->sec.text
 \f
 
 /* Call frame debugging information.  */
diff --git a/gcc/config/tilepro/tilepro.h b/gcc/config/tilepro/tilepro.h
index 1986f80084c..3f9720c582a 100644
--- a/gcc/config/tilepro/tilepro.h
+++ b/gcc/config/tilepro/tilepro.h
@@ -253,7 +253,7 @@ enum reg_class
 
 #define TRAMPOLINE_SIZE 48
 #define TRAMPOLINE_ALIGNMENT 64
-#define TRAMPOLINE_SECTION text_section
+#define TRAMPOLINE_SECTION casm->sec.text
 \f
 
 /* Call frame debugging information.  */
diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c
index 4978faf9318..9dafa3d1a76 100644
--- a/gcc/config/v850/v850.c
+++ b/gcc/config/v850/v850.c
@@ -2398,7 +2398,7 @@ v850_output_aligned_bss (FILE * file,
       break;
 
     case DATA_AREA_SDA:
-      switch_to_section (sbss_section);
+      switch_to_section (casm->sec.sbss);
       break;
 
     case DATA_AREA_TDA:
@@ -2406,7 +2406,7 @@ v850_output_aligned_bss (FILE * file,
       break;
       
     default:
-      switch_to_section (bss_section);
+      switch_to_section (casm->sec.bss);
       break;
     }
   
@@ -2882,13 +2882,13 @@ v850_select_section (tree exp,
 	  return tdata_section;
 
         case DATA_AREA_SDA:
-	  return is_const ? rosdata_section : sdata_section;
+	  return is_const ? rosdata_section : casm->sec.sdata;
 
         default:
-	  return is_const ? readonly_data_section : data_section;
+	  return is_const ? casm->sec.readonly_data : casm->sec.data;
         }
     }
-  return readonly_data_section;
+  return casm->sec.readonly_data;
 }
 \f
 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P.  */
diff --git a/gcc/config/visium/visium.h b/gcc/config/visium/visium.h
index 66e3decd0cc..dbe65766d09 100644
--- a/gcc/config/visium/visium.h
+++ b/gcc/config/visium/visium.h
@@ -1235,8 +1235,8 @@ do									\
    `EXTRA_SECTION_FUNCTIONS'
 
    One or more functions to be defined in `varasm.c'.  These functions
-   should do jobs analogous to those of `text_section' and
-   `data_section', for your additional sections.  Do not define this
+   should do jobs analogous to those of `casm->sec.text' and
+   `casm->sec.data', for your additional sections.  Do not define this
    macro if you do not define `EXTRA_SECTIONS'.
 
    `JUMP_TABLES_IN_TEXT_SECTION' Define this macro if jump tables (for
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index 6be282714cf..d8c91d07ca7 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -934,7 +934,7 @@ dbxout_function_end (tree decl ATTRIBUTE_UNUSED)
   if (crtl->has_bb_partition)
     {
       dbxout_begin_empty_stabs (N_FUN);
-      if (in_cold_section_p)
+      if (casm->in_cold_section_p)
 	dbxout_stab_value_label_diff (crtl->subsections.cold_section_end_label,
 				      crtl->subsections.cold_section_label);
       else
@@ -1042,7 +1042,7 @@ dbxout_init (const char *input_file_name)
 
   if (used_ltext_label_name)
     {
-      switch_to_section (text_section);
+      switch_to_section (casm->sec.text);
       targetm.asm_out.internal_label (asm_out_file, "Ltext", 0);
     }
 
@@ -1244,7 +1244,7 @@ dbxout_source_file (const char *filename)
     {
       /* Don't change section amid function.  */
       if (current_function_decl == NULL_TREE)
-	switch_to_section (text_section);
+	switch_to_section (casm->sec.text);
 
       dbxout_begin_simple_stabs (remap_debug_filename (filename), N_SOL);
       dbxout_stab_value_internal_label ("Ltext", &source_label_number);
@@ -1314,12 +1314,12 @@ dbxout_switch_text_section (void)
   /* The N_FUN tag at the end of the function is a GNU extension,
      which may be undesirable, and is unnecessary if we do not have
      named sections.  */
-  in_cold_section_p = !in_cold_section_p;
+  casm->in_cold_section_p = !casm->in_cold_section_p;
   switch_to_section (current_function_section ());
   dbxout_block (DECL_INITIAL (current_function_decl), 0,
 		DECL_ARGUMENTS (current_function_decl), -1);
   dbxout_function_end (current_function_decl);
-  in_cold_section_p = !in_cold_section_p;
+  casm->in_cold_section_p = !casm->in_cold_section_p;
 
   switch_to_section (current_function_section ());
 
@@ -1432,7 +1432,7 @@ dbxout_finish (const char *filename ATTRIBUTE_UNUSED)
   DBX_OUTPUT_MAIN_SOURCE_FILE_END (asm_out_file, filename);
 #elif defined DBX_OUTPUT_NULL_N_SO_AT_MAIN_SOURCE_FILE_END
  {
-   switch_to_section (text_section);
+   switch_to_section (casm->sec.text);
    dbxout_begin_empty_stabs (N_SO);
    dbxout_stab_value_internal_label ("Letext", 0);
  }
@@ -3114,7 +3114,7 @@ dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home)
 	    {
 	      /* Ultrix `as' seems to need this.  */
 #ifdef DBX_STATIC_STAB_DATA_SECTION
-	      switch_to_section (data_section);
+	      switch_to_section (casm->sec.data);
 #endif
 	      code = N_STSYM;
 	    }
@@ -3776,7 +3776,7 @@ dbxout_block (tree block, int depth, tree args, int parent_blocknum)
 
   /* If called for the second partition, ignore blocks that don't have
      any children in the second partition.  */
-  if (crtl->has_bb_partition && in_cold_section_p && depth == 0)
+  if (crtl->has_bb_partition && casm->in_cold_section_p && depth == 0)
     dbx_block_with_cold_children (block);
 
   for (; block; block = BLOCK_CHAIN (block))
@@ -3801,7 +3801,7 @@ dbxout_block (tree block, int depth, tree args, int parent_blocknum)
 	     the assembler symbols LBBn and LBEn
 	     that final will define around the code in this block.  */
 	  if (did_output
-	      && BLOCK_IN_COLD_SECTION_P (block) == in_cold_section_p)
+	      && BLOCK_IN_COLD_SECTION_P (block) == casm->in_cold_section_p)
 	    {
 	      char buf[20];
 	      const char *scope_start;
@@ -3829,7 +3829,7 @@ dbxout_block (tree block, int depth, tree args, int parent_blocknum)
 
 	  /* Refer to the marker for the end of the block.  */
 	  if (did_output
-	      && BLOCK_IN_COLD_SECTION_P (block) == in_cold_section_p)
+	      && BLOCK_IN_COLD_SECTION_P (block) == casm->in_cold_section_p)
 	    {
 	      char buf[100];
 	      if (depth == 0)
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index be8148583d8..c66bd59ead9 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -5562,7 +5562,7 @@ to generate it on the spot.
 
 @defmac TRAMPOLINE_SECTION
 Return the section into which the trampoline template is to be placed
-(@pxref{Sections}).  The default value is @code{readonly_data_section}.
+(@pxref{Sections}).  The default value is @code{casm->sec.readonly_data}.
 @end defmac
 
 @defmac TRAMPOLINE_SIZE
@@ -7623,7 +7623,7 @@ section}, which holds uninitialized data.  Some systems have other kinds
 of sections.
 
 @file{varasm.c} provides several well-known sections, such as
-@code{text_section}, @code{data_section} and @code{bss_section}.
+@code{casm->sec.text}, @code{casm->sec.data} and @code{casm->sec.bss}.
 The normal way of controlling a @code{@var{foo}_section} variable
 is to define the associated @code{@var{FOO}_SECTION_ASM_OP} macro,
 as described below.  The macros are only read once, when @file{varasm.c}
@@ -7639,12 +7639,12 @@ section is selected.  If your assembler falls into this category, you
 should define the @code{TARGET_ASM_INIT_SECTIONS} hook and use
 @code{get_unnamed_section} to set up the sections.
 
-You must always create a @code{text_section}, either by defining
-@code{TEXT_SECTION_ASM_OP} or by initializing @code{text_section}
+You must always create a @code{casm->sec.text}, either by defining
+@code{TEXT_SECTION_ASM_OP} or by initializing @code{casm->sec.text}
 in @code{TARGET_ASM_INIT_SECTIONS}.  The same is true of
-@code{data_section} and @code{DATA_SECTION_ASM_OP}.  If you do not
-create a distinct @code{readonly_data_section}, the default is to
-reuse @code{text_section}.
+@code{casm->sec.data} and @code{DATA_SECTION_ASM_OP}.  If you do not
+create a distinct @code{casm->sec.readonly_data}, the default is to
+reuse @code{casm->sec.text}.
 
 All the other @file{varasm.c} sections are optional, and are null
 if the target does not provide them.
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index d088eee4afe..06884f1dc21 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -3862,7 +3862,7 @@ separately.
 
 @defmac TRAMPOLINE_SECTION
 Return the section into which the trampoline template is to be placed
-(@pxref{Sections}).  The default value is @code{readonly_data_section}.
+(@pxref{Sections}).  The default value is @code{casm->sec.readonly_data}.
 @end defmac
 
 @defmac TRAMPOLINE_SIZE
@@ -4758,7 +4758,7 @@ section}, which holds uninitialized data.  Some systems have other kinds
 of sections.
 
 @file{varasm.c} provides several well-known sections, such as
-@code{text_section}, @code{data_section} and @code{bss_section}.
+@code{casm->sec.text}, @code{casm->sec.data} and @code{casm->sec.bss}.
 The normal way of controlling a @code{@var{foo}_section} variable
 is to define the associated @code{@var{FOO}_SECTION_ASM_OP} macro,
 as described below.  The macros are only read once, when @file{varasm.c}
@@ -4774,12 +4774,12 @@ section is selected.  If your assembler falls into this category, you
 should define the @code{TARGET_ASM_INIT_SECTIONS} hook and use
 @code{get_unnamed_section} to set up the sections.
 
-You must always create a @code{text_section}, either by defining
-@code{TEXT_SECTION_ASM_OP} or by initializing @code{text_section}
+You must always create a @code{casm->sec.text}, either by defining
+@code{TEXT_SECTION_ASM_OP} or by initializing @code{casm->sec.text}
 in @code{TARGET_ASM_INIT_SECTIONS}.  The same is true of
-@code{data_section} and @code{DATA_SECTION_ASM_OP}.  If you do not
-create a distinct @code{readonly_data_section}, the default is to
-reuse @code{text_section}.
+@code{casm->sec.data} and @code{DATA_SECTION_ASM_OP}.  If you do not
+create a distinct @code{casm->sec.readonly_data}, the default is to
+reuse @code{casm->sec.text}.
 
 All the other @file{varasm.c} sections are optional, and are null
 if the target does not provide them.
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 9876750e4f9..863729aea25 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -438,14 +438,14 @@ should_emit_struct_debug (tree type, enum debug_info_usage usage)
   return DUMP_GSTRUCT (type, usage, criterion, generic, false, false);
 }
 \f
-/* Switch [BACK] to eh_frame_section.  If we don't have an eh_frame_section,
+/* Switch [BACK] to casm->sec.eh_frame.  If we don't have an casm->sec.eh_frame,
    switch to the data section instead, and write out a synthetic start label
    for collect2 the first time around.  */
 
 static void
 switch_to_eh_frame_section (bool back ATTRIBUTE_UNUSED)
 {
-  if (eh_frame_section == 0)
+  if (casm->sec.eh_frame == 0)
     {
       int flags;
 
@@ -474,14 +474,14 @@ switch_to_eh_frame_section (bool back ATTRIBUTE_UNUSED)
 	flags = SECTION_WRITE;
 
 #ifdef EH_FRAME_SECTION_NAME
-      eh_frame_section = get_section (EH_FRAME_SECTION_NAME, flags, NULL);
+      casm->sec.eh_frame = get_section (EH_FRAME_SECTION_NAME, flags, NULL);
 #else
-      eh_frame_section = ((flags == SECTION_WRITE)
-			  ? data_section : readonly_data_section);
+      casm->sec.eh_frame = ((flags == SECTION_WRITE)
+			  ? casm->sec.data : casm->sec.readonly_data);
 #endif /* EH_FRAME_SECTION_NAME */
     }
 
-  switch_to_section (eh_frame_section);
+  switch_to_section (casm->sec.eh_frame);
 
 #ifdef EH_FRAME_THROUGH_COLLECT2
   /* We have no special eh_frame section.  Emit special labels to guide
@@ -1113,10 +1113,10 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
   /* Initialize the bits of CURRENT_FDE that were not available earlier.  */
   fde->dw_fde_begin = dup_label;
   fde->dw_fde_current_label = dup_label;
-  fde->in_std_section = (fnsec == text_section
+  fde->in_std_section = (fnsec == casm->sec.text
 			 || (cold_text_section && fnsec == cold_text_section));
   fde->ignored_debug = DECL_IGNORED_P (current_function_decl);
-  in_text_section_p = fnsec == text_section;
+  in_text_section_p = fnsec == casm->sec.text;
 
   /* We only want to output line number information for the genuine dwarf2
      prologue case, not the eh frame case.  */
@@ -1295,7 +1295,7 @@ dwarf2out_switch_text_section (void)
 			       current_function_funcdef_no);
 
   fde->dw_fde_second_begin = ggc_strdup (label);
-  if (!in_cold_section_p)
+  if (!casm->in_cold_section_p)
     {
       fde->dw_fde_end = crtl->subsections.cold_section_end_label;
       fde->dw_fde_second_end = crtl->subsections.hot_section_end_label;
@@ -1317,9 +1317,9 @@ dwarf2out_switch_text_section (void)
   switch_to_section (sect);
 
   fde->second_in_std_section
-    = (sect == text_section
+    = (sect == casm->sec.text
        || (cold_text_section && sect == cold_text_section));
-  in_text_section_p = sect == text_section;
+  in_text_section_p = sect == casm->sec.text;
 
   if (dwarf2out_do_cfi_asm ())
     dwarf2out_do_cfi_startproc (true);
@@ -17268,7 +17268,7 @@ secname_for_decl (const_tree decl)
     secname = DECL_SECTION_NAME (decl);
   else if (current_function_decl && DECL_SECTION_NAME (current_function_decl))
     {
-      if (in_cold_section_p)
+      if (casm->in_cold_section_p)
 	{
 	  section *sec = current_function_section ();
 	  if (sec->common.flags & SECTION_NAMED)
@@ -17276,7 +17276,7 @@ secname_for_decl (const_tree decl)
 	}
       secname = DECL_SECTION_NAME (current_function_decl);
     }
-  else if (cfun && in_cold_section_p)
+  else if (cfun && casm->in_cold_section_p)
     secname = crtl->subsections.cold_section_label;
   else
     secname = text_section_label;
@@ -17597,12 +17597,12 @@ dw_loc_list (var_loc_list *loc_list, tree decl, int want_address)
 
   if (cfun && crtl->has_bb_partition)
     {
-      bool save_in_cold_section_p = in_cold_section_p;
-      in_cold_section_p = first_function_block_is_cold;
+      bool save_in_cold_section_p = casm->in_cold_section_p;
+      casm->in_cold_section_p = first_function_block_is_cold;
       if (loc_list->last_before_switch == NULL)
-	in_cold_section_p = !in_cold_section_p;
+	casm->in_cold_section_p = !casm->in_cold_section_p;
       secname = secname_for_decl (decl);
-      in_cold_section_p = save_in_cold_section_p;
+      casm->in_cold_section_p = save_in_cold_section_p;
     }
   else
     secname = secname_for_decl (decl);
@@ -17680,10 +17680,10 @@ dw_loc_list (var_loc_list *loc_list, tree decl, int want_address)
 	  && crtl->has_bb_partition
 	  && node == loc_list->last_before_switch)
 	{
-	  bool save_in_cold_section_p = in_cold_section_p;
-	  in_cold_section_p = !first_function_block_is_cold;
+	  bool save_in_cold_section_p = casm->in_cold_section_p;
+	  casm->in_cold_section_p = !first_function_block_is_cold;
 	  secname = secname_for_decl (decl);
-	  in_cold_section_p = save_in_cold_section_p;
+	  casm->in_cold_section_p = save_in_cold_section_p;
 	}
 
       if (range_across_switch)
@@ -27851,7 +27851,7 @@ create_label:
      last_{,postcall_}label so that they are not reused this time.  */
   if (last_var_location_insn == NULL_RTX
       || last_var_location_insn != next_real
-      || last_in_cold_section_p != in_cold_section_p)
+      || last_in_cold_section_p != casm->in_cold_section_p)
     {
       last_label = NULL;
       last_postcall_label = NULL;
@@ -28022,7 +28022,7 @@ create_label:
     }
 
   last_var_location_insn = next_real;
-  last_in_cold_section_p = in_cold_section_p;
+  last_in_cold_section_p = casm->in_cold_section_p;
 }
 
 /* Check whether BLOCK, a lexical block, is nested within OUTER, or is
@@ -28190,7 +28190,7 @@ set_cur_line_info_table (section *sec)
 {
   dw_line_info_table *table;
 
-  if (sec == text_section)
+  if (sec == casm->sec.text)
     table = text_section_line_info;
   else if (sec == cold_text_section)
     {
@@ -28207,7 +28207,7 @@ set_cur_line_info_table (section *sec)
 
       if (crtl->has_bb_partition)
 	{
-	  if (in_cold_section_p)
+	  if (casm->in_cold_section_p)
 	    end_label = crtl->subsections.cold_section_end_label;
 	  else
 	    end_label = crtl->subsections.hot_section_end_label;
@@ -28244,7 +28244,7 @@ dwarf2out_begin_function (tree fun)
 {
   section *sec = function_section (fun);
 
-  if (sec != text_section)
+  if (sec != casm->sec.text)
     have_multiple_function_sections = true;
 
   if (crtl->has_bb_partition && !cold_text_section)
@@ -29373,7 +29373,7 @@ dwarf2out_assembly_start (void)
 			       COLD_TEXT_SECTION_LABEL, 0);
   ASM_GENERATE_INTERNAL_LABEL (cold_end_label, COLD_END_LABEL, 0);
 
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
   ASM_OUTPUT_LABEL (asm_out_file, text_section_label);
 #endif
 
@@ -32080,7 +32080,7 @@ dwarf2out_finish (const char *filename)
     main_comp_unit_die = comp_unit_die ();
 
   /* Output a terminator label for the .text section.  */
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
   targetm.asm_out.internal_label (asm_out_file, TEXT_END_LABEL, 0);
   if (cold_text_section)
     {
@@ -32996,7 +32996,7 @@ dwarf2out_early_finish (const char *filename)
     }
 
   /* Switch back to the text section.  */
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
 }
 
 /* Reset all state within dwarf2out.c so that we can rerun the compiler
diff --git a/gcc/dwarf2out.h b/gcc/dwarf2out.h
index 312a9909784..6491b44da95 100644
--- a/gcc/dwarf2out.h
+++ b/gcc/dwarf2out.h
@@ -103,9 +103,9 @@ struct GTY(()) dw_fde_node {
   unsigned stack_realign : 1;
   /* Whether dynamic realign argument pointer register has been saved.  */
   unsigned drap_reg_saved: 1;
-  /* True iff dw_fde_begin label is in text_section or cold_text_section.  */
+  /* True iff dw_fde_begin label is in casm->sec.text or cold_text_section.  */
   unsigned in_std_section : 1;
-  /* True iff dw_fde_second_begin label is in text_section or
+  /* True iff dw_fde_second_begin label is in casm->sec.text or
      cold_text_section.  */
   unsigned second_in_std_section : 1;
   /* True if Rule 18 described in dwarf2cfi.c is in action, i.e. for dynamic
diff --git a/gcc/except.c b/gcc/except.c
index 8e905a30939..ce38a57ed2f 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -2906,8 +2906,8 @@ switch_to_exception_section (const char * ARG_UNUSED (fnname))
 {
   section *s;
 
-  if (exception_section)
-    s = exception_section;
+  if (casm->sec.exception)
+    s = casm->sec.exception;
   else
     {
       int flags;
@@ -2924,7 +2924,7 @@ switch_to_exception_section (const char * ARG_UNUSED (fnname))
       else
 	flags = SECTION_WRITE;
 
-      /* Compute the section and cache it into exception_section,
+      /* Compute the section and cache it into casm->sec.exception,
 	 unless it depends on the function name.  */
       if (targetm_common.have_named_sections)
 	{
@@ -2943,12 +2943,12 @@ switch_to_exception_section (const char * ARG_UNUSED (fnname))
 	    }
 	  else
 #endif
-	    exception_section
+	    casm->sec.exception
 	      = s = get_section (".gcc_except_table", flags, NULL);
 	}
       else
-	exception_section
-	  = s = flags == SECTION_WRITE ? data_section : readonly_data_section;
+	casm->sec.exception
+	  = s = flags == SECTION_WRITE ? casm->sec.data: casm->sec.readonly_data;
     }
 
   switch_to_section (s);
diff --git a/gcc/final.c b/gcc/final.c
index ac6892d041c..03c8533e92b 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -885,7 +885,7 @@ shorten_branches (rtx_insn *first)
 	  /* ADDR_VECs only take room if read-only data goes into the text
 	     section.  */
 	  if ((JUMP_TABLES_IN_TEXT_SECTION
-	       || readonly_data_section == text_section)
+	       || casm->sec.readonly_data == casm->sec.text)
 	      && table)
 	    {
 	      align_flags alignment = align_flags (ADDR_VEC_ALIGN (table));
@@ -1051,7 +1051,7 @@ shorten_branches (rtx_insn *first)
 	  /* This only takes room if read-only data goes into the text
 	     section.  */
 	  if (JUMP_TABLES_IN_TEXT_SECTION
-	      || readonly_data_section == text_section)
+	      || casm->sec.readonly_data == casm->sec.text)
 	    insn_lengths[uid] = (XVECLEN (body,
 					  GET_CODE (body) == ADDR_DIFF_VEC)
 				 * GET_MODE_SIZE (table->get_data_mode ()));
@@ -1143,7 +1143,7 @@ shorten_branches (rtx_insn *first)
 		 may need to update the alignment of this label.  */
 
 	      if (JUMP_TABLES_IN_TEXT_SECTION
-		  || readonly_data_section == text_section)
+		  || casm->sec.readonly_data == casm->sec.text)
 		{
 		  rtx_jump_table_data *table = jump_table_for_label (label);
 		  if (table)
@@ -1284,7 +1284,7 @@ shorten_branches (rtx_insn *first)
 		      >= GET_MODE_SIZE (table->get_data_mode ())))
 		PUT_MODE (body, vec_mode);
 	      if (JUMP_TABLES_IN_TEXT_SECTION
-		  || readonly_data_section == text_section)
+		  || casm->sec.readonly_data == casm->sec.text)
 		{
 		  insn_lengths[uid]
 		    = (XVECLEN (body, 1)
@@ -1836,7 +1836,7 @@ profile_function (FILE *file ATTRIBUTE_UNUSED)
   if (! NO_PROFILE_COUNTERS)
     {
       int align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE);
-      switch_to_section (data_section);
+      switch_to_section (casm->sec.data);
       ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
       targetm.asm_out.internal_label (file, "LP", current_function_funcdef_no);
       assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, align, 1);
@@ -2189,10 +2189,10 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
 	  if (targetm.asm_out.unwind_emit)
 	    targetm.asm_out.unwind_emit (asm_out_file, insn);
 
-	  in_cold_section_p = !in_cold_section_p;
+	  casm->in_cold_section_p = !casm->in_cold_section_p;
 
-	  gcc_checking_assert (in_cold_section_p);
-	  if (in_cold_section_p)
+	  gcc_checking_assert (casm->in_cold_section_p);
+	  if (casm->in_cold_section_p)
 	    cold_function_name
 	      = clone_function_name (current_function_decl, "cold");
 
@@ -2213,10 +2213,10 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
 	  switch_to_section (current_function_section ());
 	  targetm.asm_out.function_switched_text_sections (asm_out_file,
 							   current_function_decl,
-							   in_cold_section_p);
+							   casm->in_cold_section_p);
 	  /* Emit a label for the split cold section.  Form label name by
 	     suffixing "cold" to the original function's name.  */
-	  if (in_cold_section_p)
+	  if (casm->in_cold_section_p)
 	    {
 #ifdef ASM_DECLARE_COLD_FUNCTION_NAME
 	      ASM_DECLARE_COLD_FUNCTION_NAME (asm_out_file,
@@ -2323,7 +2323,7 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
 
 	      /* Mark this block as output.  */
 	      TREE_ASM_WRITTEN (NOTE_BLOCK (insn)) = 1;
-	      BLOCK_IN_COLD_SECTION_P (NOTE_BLOCK (insn)) = in_cold_section_p;
+	      BLOCK_IN_COLD_SECTION_P (NOTE_BLOCK (insn)) = casm->in_cold_section_p;
 	    }
 	  if (write_symbols == DBX_DEBUG)
 	    {
@@ -2358,7 +2358,7 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
 	      if (!DECL_IGNORED_P (current_function_decl))
 		debug_hooks->end_block (high_block_linenum, n);
 	      gcc_assert (BLOCK_IN_COLD_SECTION_P (NOTE_BLOCK (insn))
-			  == in_cold_section_p);
+			  == casm->in_cold_section_p);
 	    }
 	  if (write_symbols == DBX_DEBUG)
 	    {
diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c
index 32ba5be42b2..d90a8570dba 100644
--- a/gcc/ggc-common.c
+++ b/gcc/ggc-common.c
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "hosthooks.h"
 #include "plugin.h"
 #include "options.h"
+#include "output.h"
 
 /* When true, protect the contents of the identifier hash table.  */
 bool ggc_protect_identifiers = true;
@@ -589,6 +590,9 @@ gt_pch_restore (FILE *f)
   struct mmap_info mmi;
   int result;
 
+  /* Hide ASM state object as we don't want it to be streamed.  */
+  FILE *saved_casm_out_file = casm != NULL ? casm->out_file : NULL;
+
   /* Delete any deletable objects.  This makes ggc_pch_read much
      faster, as it can be sure that no GCable objects remain other
      than the ones just read in.  */
@@ -629,6 +633,9 @@ gt_pch_restore (FILE *f)
   ggc_pch_read (f, mmi.preferred_base);
 
   gt_pch_restore_stringpool ();
+
+  if (casm != NULL)
+    casm->out_file = saved_casm_out_file;
 }
 
 /* Default version of HOST_HOOKS_GT_PCH_GET_ADDRESS when mmap is not present.
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index 48c72377778..cd1ed0655e5 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -803,9 +803,9 @@ lhd_begin_section (const char *name)
 
   /* Save the old section so we can restore it in lto_end_asm_section.  */
   gcc_assert (!saved_section);
-  saved_section = in_section;
+  saved_section = casm->in_section;
   if (!saved_section)
-    saved_section = text_section;
+    saved_section = casm->sec.text;
 
   /* Create a new section and switch to it.  */
   section = get_section (name, SECTION_DEBUG | SECTION_EXCLUDE, NULL, true);
diff --git a/gcc/output.h b/gcc/output.h
index 73ca4545f4f..a5cb1260219 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -313,9 +313,78 @@ extern rtx_sequence *final_sequence;
 
 /* File in which assembler code is being written.  */
 
-#ifdef BUFSIZ
-extern FILE *asm_out_file;
-#endif
+struct section_hasher : ggc_ptr_hash<section>
+{
+  typedef const char *compare_type;
+
+  static hashval_t hash (section *);
+  static bool equal (section *, const char *);
+};
+
+/* Assembly output state.  */
+
+struct GTY(()) asm_out_state
+{
+  asm_out_state (): out_file (NULL), in_section (NULL),
+    sec ({}), anchor_labelno (0), in_cold_section_p (false)
+  {
+    section_htab = hash_table<section_hasher>::create_ggc (31);
+  }
+
+  /* Assembly output stream.  */
+  FILE * GTY((skip)) out_file;
+
+  /* Hash table of named sections.  */
+  hash_table<section_hasher> *section_htab;
+
+  /* asm_out_file's current section.  This is NULL if no section has yet
+     been selected or if we lose track of what the current section is.  */
+  section *in_section;
+
+  /* Well-known sections, each one associated with some sort of *_ASM_OP.  */
+  struct
+  {
+    section *text;
+    section *data;
+    section *readonly_data;
+    section *sdata;
+    section *ctors;
+    section *dtors;
+    section *bss;
+    section *sbss;
+
+    /* Various forms of common section.  All are guaranteed to be nonnull.  */
+    section *tls_comm;
+    section *comm;
+    section *lcomm;
+
+    /* A SECTION_NOSWITCH section used for declaring global BSS variables.
+       May be null.  */
+    section *bss_noswitch;
+
+    /* The section that holds the main exception table, when known.  The section
+       is set either by the target's init_sections hook or by the first call to
+       switch_to_exception_section.  */
+    section *exception;
+
+    /* The section that holds the DWARF2 frame unwind information, when known.
+       The section is set either by the target's init_sections hook or by the
+       first call to switch_to_eh_frame_section.  */
+    section *eh_frame;
+  } sec;
+
+  /* The next number to use for internal anchor labels.  */
+  int anchor_labelno;
+
+  /* True if code for the current function is currently being directed
+     at the cold section.  */
+  bool in_cold_section_p;
+};
+
+extern GTY(()) asm_out_state *casm;
+
+/* Helper macro for commonly used accesses.  */
+#define asm_out_file casm->out_file
 
 /* The first global object in the file.  */
 extern const char *first_global_object_name;
@@ -511,24 +580,6 @@ union GTY ((desc ("SECTION_STYLE (&(%h))"), for_user)) section {
 struct object_block;
 
 /* Special well-known sections.  */
-extern GTY(()) section *text_section;
-extern GTY(()) section *data_section;
-extern GTY(()) section *readonly_data_section;
-extern GTY(()) section *sdata_section;
-extern GTY(()) section *ctors_section;
-extern GTY(()) section *dtors_section;
-extern GTY(()) section *bss_section;
-extern GTY(()) section *sbss_section;
-extern GTY(()) section *exception_section;
-extern GTY(()) section *eh_frame_section;
-extern GTY(()) section *tls_comm_section;
-extern GTY(()) section *comm_section;
-extern GTY(()) section *lcomm_section;
-extern GTY(()) section *bss_noswitch_section;
-
-extern GTY(()) section *in_section;
-extern GTY(()) bool in_cold_section_p;
-
 extern section *get_unnamed_section (unsigned int, void (*) (const void *),
 				     const void *);
 extern section *get_section (const char *, unsigned int, tree,
diff --git a/gcc/run-rtl-passes.c b/gcc/run-rtl-passes.c
index 37a02813f22..e6976bf9070 100644
--- a/gcc/run-rtl-passes.c
+++ b/gcc/run-rtl-passes.c
@@ -46,7 +46,7 @@ run_rtl_passes (char *initial_pass_name)
   max_regno = max_reg_num ();
 
   /* cgraphunit.c normally handles this.  */
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
   (*debug_hooks->assembly_start) ();
 
   if (initial_pass_name)
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index c9b5208853d..68660186ec5 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -1962,7 +1962,7 @@ default_print_patchable_function_entry_1 (FILE *file,
     {
       char buf[256];
       static int patch_area_number;
-      section *previous_section = in_section;
+      section *previous_section = casm->in_section;
       const char *asm_op = integer_asm_op (POINTER_SIZE_UNITS, false);
 
       gcc_assert (asm_op != NULL);
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 14d1335e79e..59dbb585d91 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -172,7 +172,8 @@ const char *user_label_prefix;
 /* Output files for assembler code (real compiler output)
    and debugging dumps.  */
 
-FILE *asm_out_file;
+asm_out_state *casm;
+
 FILE *aux_info_file;
 FILE *callgraph_info_file = NULL;
 static bitmap callgraph_info_external_printed;
@@ -552,13 +553,13 @@ compile_file (void)
   if (flag_generate_lto && !flag_fat_lto_objects)
     {
 #if defined ASM_OUTPUT_ALIGNED_DECL_COMMON
-      ASM_OUTPUT_ALIGNED_DECL_COMMON (asm_out_file, NULL_TREE, "__gnu_lto_slim",
+      ASM_OUTPUT_ALIGNED_DECL_COMMON (casm->out_file, NULL_TREE, "__gnu_lto_slim",
 				      HOST_WIDE_INT_1U, 8);
 #elif defined ASM_OUTPUT_ALIGNED_COMMON
-      ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, "__gnu_lto_slim",
+      ASM_OUTPUT_ALIGNED_COMMON (casm->out_file, "__gnu_lto_slim",
 				 HOST_WIDE_INT_1U, 8);
 #else
-      ASM_OUTPUT_COMMON (asm_out_file, "__gnu_lto_slim",
+      ASM_OUTPUT_COMMON (casm->out_file, "__gnu_lto_slim",
 			 HOST_WIDE_INT_1U,
 			 HOST_WIDE_INT_1U);
 #endif
@@ -696,7 +697,7 @@ static void
 init_asm_output (const char *name)
 {
   if (name == NULL && asm_file_name == 0)
-    asm_out_file = stdout;
+    casm->out_file = stdout;
   else
     {
       if (asm_file_name == 0)
@@ -710,17 +711,17 @@ init_asm_output (const char *name)
 	  asm_file_name = dumpname;
 	}
       if (!strcmp (asm_file_name, "-"))
-	asm_out_file = stdout;
+	casm->out_file = stdout;
       else if (!canonical_filename_eq (asm_file_name, name)
 	       || !strcmp (asm_file_name, HOST_BIT_BUCKET))
-	asm_out_file = fopen (asm_file_name, "w");
+	casm->out_file = fopen (asm_file_name, "w");
       else
 	/* Use UNKOWN_LOCATION to prevent gcc from printing the first
 	   line in the current file. */
 	fatal_error (UNKNOWN_LOCATION,
 		     "input file %qs is the same as output file",
 		     asm_file_name);
-      if (asm_out_file == 0)
+      if (casm->out_file == 0)
 	fatal_error (UNKNOWN_LOCATION,
 		     "cannot open %qs for writing: %m", asm_file_name);
     }
@@ -747,14 +748,14 @@ init_asm_output (const char *name)
 
       if (flag_verbose_asm)
 	{
-	  print_version (asm_out_file, ASM_COMMENT_START, true);
-	  fputs (ASM_COMMENT_START, asm_out_file);
-	  fputs (" options passed: ", asm_out_file);
+	  print_version (casm->out_file, ASM_COMMENT_START, true);
+	  fputs (ASM_COMMENT_START, casm->out_file);
+	  fputs (" options passed: ", casm->out_file);
 	  char *cmdline = gen_command_line_string (save_decoded_options,
 						   save_decoded_options_count);
-	  fputs (cmdline, asm_out_file);
+	  fputs (cmdline, casm->out_file);
 	  free (cmdline);
-	  fputc ('\n', asm_out_file);
+	  fputc ('\n', casm->out_file);
 	}
     }
 }
@@ -1924,7 +1925,8 @@ lang_dependent_init (const char *name)
 
   if (!flag_wpa)
     {
-      init_asm_output (name);
+      if (!flag_syntax_only)
+	init_asm_output (name);
 
       if (!flag_generate_lto && !flag_compare_debug)
 	{
@@ -2083,13 +2085,13 @@ finalize (bool no_backend)
      whether fclose returns an error, since the pages might still be on the
      buffer chain while the file is open.  */
 
-  if (asm_out_file)
+  if (casm != NULL && casm->out_file)
     {
-      if (ferror (asm_out_file) != 0)
+      if (ferror (casm->out_file) != 0)
 	fatal_error (input_location, "error writing to %s: %m", asm_file_name);
-      if (fclose (asm_out_file) != 0)
+      if (fclose (casm->out_file) != 0)
 	fatal_error (input_location, "error closing %s: %m", asm_file_name);
-      asm_out_file = NULL;
+      casm->out_file = NULL;
     }
 
   if (stack_usage_file)
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 2d261b353bf..b8df344e86b 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -130,43 +130,6 @@ static void mark_weak (tree);
 static void output_constant_pool (const char *, tree);
 static void handle_vtv_comdat_section (section *, const_tree);
 \f
-/* Well-known sections, each one associated with some sort of *_ASM_OP.  */
-section *text_section;
-section *data_section;
-section *readonly_data_section;
-section *sdata_section;
-section *ctors_section;
-section *dtors_section;
-section *bss_section;
-section *sbss_section;
-
-/* Various forms of common section.  All are guaranteed to be nonnull.  */
-section *tls_comm_section;
-section *comm_section;
-section *lcomm_section;
-
-/* A SECTION_NOSWITCH section used for declaring global BSS variables.
-   May be null.  */
-section *bss_noswitch_section;
-
-/* The section that holds the main exception table, when known.  The section
-   is set either by the target's init_sections hook or by the first call to
-   switch_to_exception_section.  */
-section *exception_section;
-
-/* The section that holds the DWARF2 frame unwind information, when known.
-   The section is set either by the target's init_sections hook or by the
-   first call to switch_to_eh_frame_section.  */
-section *eh_frame_section;
-
-/* asm_out_file's current section.  This is NULL if no section has yet
-   been selected or if we lose track of what the current section is.  */
-section *in_section;
-
-/* True if code for the current function is currently being directed
-   at the cold section.  */
-bool in_cold_section_p;
-
 /* The following global holds the "function name" for the code in the
    cold section of a function, if hot/cold function splitting is enabled
    and there was actually code that went into the cold section.  A
@@ -181,17 +144,6 @@ static GTY(()) section *unnamed_sections;
 #define IN_NAMED_SECTION(DECL) \
   (VAR_OR_FUNCTION_DECL_P (DECL) && DECL_SECTION_NAME (DECL) != NULL)
 
-struct section_hasher : ggc_ptr_hash<section>
-{
-  typedef const char *compare_type;
-
-  static hashval_t hash (section *);
-  static bool equal (section *, const char *);
-};
-
-/* Hash table of named sections.  */
-static GTY(()) hash_table<section_hasher> *section_htab;
-
 struct object_block_hasher : ggc_ptr_hash<object_block>
 {
   typedef const section *compare_type;
@@ -203,9 +155,6 @@ struct object_block_hasher : ggc_ptr_hash<object_block>
 /* A table of object_blocks, indexed by section.  */
 static GTY(()) hash_table<object_block_hasher> *object_block_htab;
 
-/* The next number to use for internal anchor labels.  */
-static GTY(()) int anchor_labelno;
-
 /* A pool of constants that can be shared between functions.  */
 static GTY(()) struct rtx_constant_pool *shared_constant_pool;
 
@@ -294,8 +243,8 @@ get_section (const char *name, unsigned int flags, tree decl,
 {
   section *sect, **slot;
 
-  slot = section_htab->find_slot_with_hash (name, htab_hash_string (name),
-					    INSERT);
+  slot = casm->section_htab->find_slot_with_hash (name, htab_hash_string (name),
+						  INSERT);
   flags |= SECTION_NAMED;
   if (decl != nullptr
       && DECL_P (decl)
@@ -510,7 +459,7 @@ asm_output_aligned_bss (FILE *file, tree decl ATTRIBUTE_UNUSED,
 			const char *name, unsigned HOST_WIDE_INT size,
 			int align)
 {
-  switch_to_section (bss_section);
+  switch_to_section (casm->sec.bss);
   ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
 #ifdef ASM_DECLARE_OBJECT_NAME
   last_assemble_variable_decl = decl;
@@ -527,7 +476,7 @@ asm_output_aligned_bss (FILE *file, tree decl ATTRIBUTE_UNUSED,
 #endif /* BSS_SECTION_ASM_OP */
 
 #ifndef USE_SELECT_SECTION_FOR_FUNCTIONS
-/* Return the hot section for function DECL.  Return text_section for
+/* Return the hot section for function DECL.  Return casm->sec.text for
    null DECLs.  */
 
 static section *
@@ -538,7 +487,7 @@ hot_function_section (tree decl)
       && targetm_common.have_named_sections)
     return get_named_section (decl, NULL, 0);
   else
-    return text_section;
+    return casm->sec.text;
 }
 #endif
 
@@ -718,7 +667,7 @@ function_section (tree decl)
 section *
 current_function_section (void)
 {
-  return function_section_1 (current_function_decl, in_cold_section_p);
+  return function_section_1 (current_function_decl, casm->in_cold_section_p);
 }
 
 /* Tell assembler to switch to unlikely-to-be-executed text section.  */
@@ -746,7 +695,7 @@ unlikely_text_section_p (section *sect)
 void
 switch_to_other_text_partition (void)
 {
-  in_cold_section_p = !in_cold_section_p;
+  casm->in_cold_section_p = !casm->in_cold_section_p;
   switch_to_section (current_function_section ());
 }
 
@@ -831,7 +780,7 @@ default_function_rodata_section (tree decl, bool relocatable)
   if (relocatable)
     return get_section (sname, flags, decl);
   else
-    return readonly_data_section;
+    return casm->sec.readonly_data;
 }
 
 /* Return the read-only data section associated with function DECL
@@ -841,7 +790,7 @@ default_function_rodata_section (tree decl, bool relocatable)
 section *
 default_no_function_rodata_section (tree, bool)
 {
-  return readonly_data_section;
+  return casm->sec.readonly_data;
 }
 
 /* A subroutine of mergeable_string_section and mergeable_constant_section.  */
@@ -890,7 +839,7 @@ mergeable_string_section (tree decl ATTRIBUTE_UNUSED,
 	    align = modesize;
 
 	  if (!HAVE_LD_ALIGNED_SHF_MERGE && align > 8)
-	    return readonly_data_section;
+	    return casm->sec.readonly_data;
 
 	  str = TREE_STRING_POINTER (decl);
 	  unit = GET_MODE_SIZE (mode);
@@ -914,7 +863,7 @@ mergeable_string_section (tree decl ATTRIBUTE_UNUSED,
 	}
     }
 
-  return readonly_data_section;
+  return casm->sec.readonly_data;
 }
 
 /* Return the section to use for constant merging.  */
@@ -940,7 +889,7 @@ mergeable_constant_section (machine_mode mode ATTRIBUTE_UNUSED,
       flags |= (align / 8) | SECTION_MERGE;
       return get_section (name, flags, NULL);
     }
-  return readonly_data_section;
+  return casm->sec.readonly_data;
 }
 \f
 /* Given NAME, a putative register name, discard any customary prefixes.  */
@@ -1253,9 +1202,9 @@ get_variable_section (tree decl, bool prefer_noswitch_p)
       gcc_assert (DECL_SECTION_NAME (decl) == NULL
 		  && ADDR_SPACE_GENERIC_P (as));
       if (DECL_THREAD_LOCAL_P (decl))
-	return tls_comm_section;
+	return casm->sec.tls_comm;
       else if (TREE_PUBLIC (decl) && bss_initializer_p (decl))
-	return comm_section;
+	return casm->sec.comm;
     }
 
   reloc = compute_reloc_for_var (decl);
@@ -1285,9 +1234,9 @@ get_variable_section (tree decl, bool prefer_noswitch_p)
       if (!TREE_PUBLIC (decl)
 	  && !((flag_sanitize & SANITIZE_ADDRESS)
 	       && asan_protect_global (decl)))
-	return lcomm_section;
-      if (bss_noswitch_section)
-	return bss_noswitch_section;
+	return casm->sec.lcomm;
+      if (casm->sec.bss_noswitch)
+	return casm->sec.bss_noswitch;
     }
 
   return targetm.asm_out.select_section (decl, reloc,
@@ -1733,7 +1682,7 @@ void
 default_dtor_section_asm_out_destructor (rtx symbol,
 					 int priority ATTRIBUTE_UNUSED)
 {
-  assemble_addr_to_section (symbol, dtors_section);
+  assemble_addr_to_section (symbol, casm->sec.dtors);
 }
 #endif
 
@@ -1756,7 +1705,7 @@ void
 default_ctor_section_asm_out_constructor (rtx symbol,
 					  int priority ATTRIBUTE_UNUSED)
 {
-  assemble_addr_to_section (symbol, ctors_section);
+  assemble_addr_to_section (symbol, casm->sec.ctors);
 }
 #endif
 \f
@@ -1824,7 +1773,7 @@ decide_function_section (tree decl)
 				      == NODE_FREQUENCY_UNLIKELY_EXECUTED);
     }
 
-  in_cold_section_p = first_function_block_is_cold;
+  casm->in_cold_section_p = first_function_block_is_cold;
 }
 
 /* Get the function's name, as described by its RTL.  This may be
@@ -1900,13 +1849,13 @@ assemble_start_function (tree decl, const char *fnname)
       if (!cfun->is_thunk
 	  && BB_PARTITION (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb) == BB_COLD_PARTITION)
 	{
-	  switch_to_section (text_section);
+	  switch_to_section (casm->sec.text);
 	  assemble_align (align);
 	  ASM_OUTPUT_LABEL (asm_out_file, crtl->subsections.hot_section_label);
 	  hot_label_written = true;
 	  first_function_block_is_cold = true;
 	}
-      in_cold_section_p = first_function_block_is_cold;
+      casm->in_cold_section_p = first_function_block_is_cold;
     }
 
 
@@ -2020,7 +1969,7 @@ assemble_end_function (tree decl, const char *fnname ATTRIBUTE_UNUSED)
     {
       section *save_text_section;
 
-      save_text_section = in_section;
+      save_text_section = casm->in_section;
       switch_to_section (unlikely_text_section ());
 #ifdef ASM_DECLARE_COLD_FUNCTION_SIZE
       if (cold_function_name != NULL_TREE)
@@ -2030,7 +1979,7 @@ assemble_end_function (tree decl, const char *fnname ATTRIBUTE_UNUSED)
 #endif
       ASM_OUTPUT_LABEL (asm_out_file, crtl->subsections.cold_section_end_label);
       if (first_function_block_is_cold)
-	switch_to_section (text_section);
+	switch_to_section (casm->sec.text);
       else
 	switch_to_section (function_section (decl));
       ASM_OUTPUT_LABEL (asm_out_file, crtl->subsections.hot_section_end_label);
@@ -2050,7 +1999,7 @@ assemble_zeros (unsigned HOST_WIDE_INT size)
 #ifdef ASM_NO_SKIP_IN_TEXT
   /* The `space' pseudo in the text section outputs nop insns rather than 0s,
      so we must output 0s explicitly in the text section.  */
-  if (ASM_NO_SKIP_IN_TEXT && (in_section->common.flags & SECTION_CODE) != 0)
+  if (ASM_NO_SKIP_IN_TEXT && (casm->in_section->common.flags & SECTION_CODE) != 0)
     {
       unsigned HOST_WIDE_INT i;
       for (i = 0; i < size; i++)
@@ -2097,7 +2046,7 @@ assemble_string (const char *p, int size)
 }
 
 \f
-/* A noswitch_section_callback for lcomm_section.  */
+/* A noswitch_section_callback for casm->sec.lcomm.  */
 
 static bool
 emit_local (tree decl ATTRIBUTE_UNUSED,
@@ -2120,7 +2069,7 @@ emit_local (tree decl ATTRIBUTE_UNUSED,
 #endif
 }
 
-/* A noswitch_section_callback for bss_noswitch_section.  */
+/* A noswitch_section_callback for casm->sec.bss_noswitch.  */
 
 #if defined ASM_OUTPUT_ALIGNED_BSS
 static bool
@@ -2135,7 +2084,7 @@ emit_bss (tree decl ATTRIBUTE_UNUSED,
 }
 #endif
 
-/* A noswitch_section_callback for comm_section.  */
+/* A noswitch_section_callback for casm->sec.comm.  */
 
 static bool
 emit_common (tree decl ATTRIBUTE_UNUSED,
@@ -2157,7 +2106,7 @@ emit_common (tree decl ATTRIBUTE_UNUSED,
 #endif
 }
 
-/* A noswitch_section_callback for tls_comm_section.  */
+/* A noswitch_section_callback for casm->sec.tls_comm.  */
 
 static bool
 emit_tls_common (tree decl ATTRIBUTE_UNUSED,
@@ -2774,7 +2723,7 @@ assemble_trampoline_template (void)
 #ifdef TRAMPOLINE_SECTION
   switch_to_section (TRAMPOLINE_SECTION);
 #else
-  switch_to_section (readonly_data_section);
+  switch_to_section (casm->sec.readonly_data);
 #endif
 
   /* Write the assembler code to define one.  */
@@ -4192,8 +4141,8 @@ output_constant_pool_1 (class constant_descriptor_rtx *desc,
   /* Make sure all constants in SECTION_MERGE and not SECTION_STRINGS
      sections have proper size.  */
   if (align > GET_MODE_BITSIZE (desc->mode)
-      && in_section
-      && (in_section->common.flags & SECTION_MERGE))
+      && casm->in_section
+      && (casm->in_section->common.flags & SECTION_MERGE))
     assemble_align (align);
 
 #ifdef ASM_OUTPUT_SPECIAL_POOL_ENTRY
@@ -6602,70 +6551,72 @@ make_decl_one_only (tree decl, tree comdat_group)
 void
 init_varasm_once (void)
 {
-  section_htab = hash_table<section_hasher>::create_ggc (31);
+  /* Initialize ASM out state.  */
+  casm = new (ggc_alloc<asm_out_state> ()) asm_out_state ();
+
   object_block_htab = hash_table<object_block_hasher>::create_ggc (31);
   const_desc_htab = hash_table<tree_descriptor_hasher>::create_ggc (1009);
 
   shared_constant_pool = create_constant_pool ();
 
 #ifdef TEXT_SECTION_ASM_OP
-  text_section = get_unnamed_section (SECTION_CODE, output_section_asm_op,
+  casm->sec.text = get_unnamed_section (SECTION_CODE, output_section_asm_op,
 				      TEXT_SECTION_ASM_OP);
 #endif
 
 #ifdef DATA_SECTION_ASM_OP
-  data_section = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
-				      DATA_SECTION_ASM_OP);
+  casm->sec.data = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
+					     DATA_SECTION_ASM_OP);
 #endif
 
 #ifdef SDATA_SECTION_ASM_OP
-  sdata_section = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
+  casm->sec.sdata = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
 				       SDATA_SECTION_ASM_OP);
 #endif
 
 #ifdef READONLY_DATA_SECTION_ASM_OP
-  readonly_data_section = get_unnamed_section (0, output_section_asm_op,
-					       READONLY_DATA_SECTION_ASM_OP);
+  casm->sec.readonly_data = get_unnamed_section (0, output_section_asm_op,
+						      READONLY_DATA_SECTION_ASM_OP);
 #endif
 
 #ifdef CTORS_SECTION_ASM_OP
-  ctors_section = get_unnamed_section (0, output_section_asm_op,
+  casm->sec.ctors = get_unnamed_section (0, output_section_asm_op,
 				       CTORS_SECTION_ASM_OP);
 #endif
 
 #ifdef DTORS_SECTION_ASM_OP
-  dtors_section = get_unnamed_section (0, output_section_asm_op,
+  casm->sec.dtors = get_unnamed_section (0, output_section_asm_op,
 				       DTORS_SECTION_ASM_OP);
 #endif
 
 #ifdef BSS_SECTION_ASM_OP
-  bss_section = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
-				     output_section_asm_op,
-				     BSS_SECTION_ASM_OP);
+  casm->sec.bss = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
+					    output_section_asm_op,
+					    BSS_SECTION_ASM_OP);
 #endif
 
 #ifdef SBSS_SECTION_ASM_OP
-  sbss_section = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
+  casm->sec.sbss = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
 				      output_section_asm_op,
 				      SBSS_SECTION_ASM_OP);
 #endif
 
-  tls_comm_section = get_noswitch_section (SECTION_WRITE | SECTION_BSS
-					   | SECTION_COMMON, emit_tls_common);
-  lcomm_section = get_noswitch_section (SECTION_WRITE | SECTION_BSS
-					| SECTION_COMMON, emit_local);
-  comm_section = get_noswitch_section (SECTION_WRITE | SECTION_BSS
-				       | SECTION_COMMON, emit_common);
+  casm->sec.tls_comm = get_noswitch_section (SECTION_WRITE | SECTION_BSS
+						  | SECTION_COMMON, emit_tls_common);
+  casm->sec.lcomm = get_noswitch_section (SECTION_WRITE | SECTION_BSS
+					       | SECTION_COMMON, emit_local);
+  casm->sec.comm = get_noswitch_section (SECTION_WRITE | SECTION_BSS
+					      | SECTION_COMMON, emit_common);
 
 #if defined ASM_OUTPUT_ALIGNED_BSS
-  bss_noswitch_section = get_noswitch_section (SECTION_WRITE | SECTION_BSS,
-					       emit_bss);
+  casm->sec.bss_noswitch = get_noswitch_section (SECTION_WRITE | SECTION_BSS,
+						      emit_bss);
 #endif
 
   targetm.asm_out.init_sections ();
 
-  if (readonly_data_section == NULL)
-    readonly_data_section = text_section;
+  if (casm->sec.readonly_data == NULL)
+    casm->sec.readonly_data = casm->sec.text;
 
 #ifdef ASM_OUTPUT_EXTERNAL
   pending_assemble_externals_set = new hash_set<tree>;
@@ -6790,13 +6741,13 @@ default_section_type_flags (tree decl, const char *name, int reloc)
 }
 
 /* Return true if the target supports some form of global BSS,
-   either through bss_noswitch_section, or by selecting a BSS
+   either through casm->sec.bss_noswitch, or by selecting a BSS
    section in TARGET_ASM_SELECT_SECTION.  */
 
 bool
 have_global_bss_p (void)
 {
-  return bss_noswitch_section || targetm.have_switchable_bss_sections;
+  return casm->sec.bss_noswitch || targetm.have_switchable_bss_sections;
 }
 
 /* Output assembly to switch to section NAME with attribute FLAGS.
@@ -6958,7 +6909,7 @@ default_select_section (tree decl, int reloc,
   if (DECL_P (decl))
     {
       if (decl_readonly_section (decl, reloc))
-	return readonly_data_section;
+	return casm->sec.readonly_data;
     }
   else if (TREE_CODE (decl) == CONSTRUCTOR)
     {
@@ -6966,14 +6917,14 @@ default_select_section (tree decl, int reloc,
 	     || !TREE_READONLY (decl)
 	     || TREE_SIDE_EFFECTS (decl)
 	     || !TREE_CONSTANT (decl)))
-	return readonly_data_section;
+	return casm->sec.readonly_data;
     }
   else if (TREE_CODE (decl) == STRING_CST)
-    return readonly_data_section;
+    return casm->sec.readonly_data;
   else if (! (flag_pic && reloc))
-    return readonly_data_section;
+    return casm->sec.readonly_data;
 
-  return data_section;
+  return casm->sec.data;
 }
 
 enum section_category
@@ -7112,7 +7063,7 @@ default_elf_select_section (tree decl, int reloc,
       /* We're not supposed to be called on FUNCTION_DECLs.  */
       gcc_unreachable ();
     case SECCAT_RODATA:
-      return readonly_data_section;
+      return casm->sec.readonly_data;
     case SECCAT_RODATA_MERGE_STR:
       return mergeable_string_section (decl, align, 0);
     case SECCAT_RODATA_MERGE_STR_INIT:
@@ -7128,7 +7079,7 @@ default_elf_select_section (tree decl, int reloc,
 	  sname = ".persistent";
 	  break;
 	}
-      return data_section;
+      return casm->sec.data;
     case SECCAT_DATA_REL:
       sname = ".data.rel";
       break;
@@ -7153,8 +7104,8 @@ default_elf_select_section (tree decl, int reloc,
 	  sname = ".noinit";
 	  break;
 	}
-      if (bss_section)
-	return bss_section;
+      if (casm->sec.bss)
+	return casm->sec.bss;
       sname = ".bss";
       break;
     case SECCAT_SBSS:
@@ -7304,9 +7255,9 @@ default_select_rtx_section (machine_mode mode ATTRIBUTE_UNUSED,
 			    unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
 {
   if (compute_reloc_for_rtx (x) & targetm.asm_out.reloc_rw_mask ())
-    return data_section;
+    return casm->sec.data;
   else
-    return readonly_data_section;
+    return casm->sec.readonly_data;
 }
 
 section *
@@ -7824,13 +7775,13 @@ switch_to_section (section *new_section, tree decl)
 		  "%qD was declared here", used_decl);
 	}
     }
-  else if (in_section == new_section)
+  else if (casm->in_section == new_section)
     return;
 
   if (new_section->common.flags & SECTION_FORGET)
-    in_section = NULL;
+    casm->in_section = NULL;
   else
-    in_section = new_section;
+    casm->in_section = new_section;
 
   switch (SECTION_STYLE (new_section))
     {
@@ -8006,7 +7957,7 @@ get_section_anchor (struct object_block *block, HOST_WIDE_INT offset,
     }
 
   /* Create a new anchor with a unique label.  */
-  ASM_GENERATE_INTERNAL_LABEL (label, "LANCHOR", anchor_labelno++);
+  ASM_GENERATE_INTERNAL_LABEL (label, "LANCHOR", casm->anchor_labelno++);
   anchor = create_block_symbol (ggc_strdup (label), block, offset);
   SYMBOL_REF_FLAGS (anchor) |= SYMBOL_FLAG_LOCAL | SYMBOL_FLAG_ANCHOR;
   SYMBOL_REF_FLAGS (anchor) |= model << SYMBOL_FLAG_TLS_SHIFT;
@@ -8475,7 +8426,7 @@ handle_vtv_comdat_section (section *sect, const_tree decl ATTRIBUTE_UNUSED)
 				 sect->named.common.flags
 				 | SECTION_LINKONCE,
 				 DECL_NAME (decl));
-  in_section = sect;
+  casm->in_section = sect;
 #else
   /* Neither OBJECT_FORMAT_PE, nor OBJECT_FORMAT_COFF is set here.
      Therefore the following check is used.
@@ -8501,7 +8452,7 @@ handle_vtv_comdat_section (section *sect, const_tree decl ATTRIBUTE_UNUSED)
 				     sect->named.common.flags
 				     | SECTION_LINKONCE,
 				     DECL_NAME (decl));
-      in_section = sect;
+      casm->in_section = sect;
     }
   else
     switch_to_section (sect);
diff --git a/gcc/vmsdbgout.c b/gcc/vmsdbgout.c
index 05fadce075e..eab52c62307 100644
--- a/gcc/vmsdbgout.c
+++ b/gcc/vmsdbgout.c
@@ -1583,7 +1583,7 @@ vmsdbgout_finish (const char *filename ATTRIBUTE_UNUSED)
     return;
 
   /* Output a terminator label for the .text section.  */
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
   targetm.asm_out.internal_label (asm_out_file, TEXT_END_LABEL, 0);
 
   /* Output debugging information.
-- 
2.33.0


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 1/N] Rename asm_out_file function arguments.
  2021-09-16 10:00 ` [PATCH 1/N] Rename asm_out_file function arguments Martin Liška
@ 2021-09-16 13:52   ` Iain Sandoe
  2021-09-17  8:23     ` Richard Biener
  2021-10-20 11:57   ` Martin Liška
  1 sibling, 1 reply; 30+ messages in thread
From: Iain Sandoe @ 2021-09-16 13:52 UTC (permalink / raw)
  To: Martin Liska; +Cc: GCC Patches


Hi Martin,

> On 16 Sep 2021, at 11:00, Martin Liška <mliska@suse.cz> wrote:
> 
> As preparation for a new global object that will encapsulate
> asm_out_file, we would need to live with a macro that will
> define asm_out_file as casm->out_file and thus the name
> can't be used in function arguments.

So, if I understand correctly, the motivation is to be able to switch
between output file streams for different categories of content?

Darwin, actually already does this (manually) with a separate
lto_asm_out_name for lto data (so a general solution would
be great).
 
What is the reason for associating the section pointers with the
casm object?

* I can understand that each instance of a casm object would have
 potentially a different current section (“in_section”), but it seems that
 as things stand the section pointers would be duplicates.

* In the case that there’s reason that the sections could be different
  between casm instances, then would it make sense to have a
  target hook so that target-specific sections can be added to the
  local list (via some indirection, I’d assume)?

—

(of course, it would be great if one day we could abstract the asm out
 such that we could switch to a direct-to-object implementation)

> I've built all cross compilers with the change and
> can bootstrap on x86_64-linux-gnu and survives regression tests.

A native bootstrap fails early in stage1 for x86_64-darwin (I’ll take a look
at fixing the issues once the patch series settles down)

---

/src-local/gcc-master/gcc/dwarf2asm.c: In function ‘void dw2_asm_output_nstring(const char*, size_t, const char*, ...)’:
/src-local/gcc-master/gcc/output.h:387:26: error: expected initializer before ‘->’ token
 #define asm_out_file casm->out_file
                          ^
/src-local/gcc-master/gcc/defaults.h:68:13: note: in expansion of macro ‘asm_out_file’
       FILE *asm_out_file = _hide_asm_out_file;          \
             ^~~~~~~~~~~~
/src-local/gcc-master/gcc/dwarf2asm.c:414:7: note: in expansion of macro ‘ASM_OUTPUT_ASCII’
       ASM_OUTPUT_ASCII (asm_out_file, str, len);
       ^~~~~~~~~~~~~~~~
In file included from ./tm.h:42:0,

------

/src-local/gcc-master/gcc/config/i386/darwin.h:219:6: error: ‘in_section’ was not declared in this scope
  if (in_section == text_section)       \
      ^
/src-local/gcc-master/gcc/dwarf2out.c:677:3: note: in expansion of macro ‘ASM_OUTPUT_ALIGN’
   ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE));



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 1/N] Rename asm_out_file function arguments.
  2021-09-16 13:52   ` Iain Sandoe
@ 2021-09-17  8:23     ` Richard Biener
  2021-09-17  9:42       ` Iain Sandoe
  0 siblings, 1 reply; 30+ messages in thread
From: Richard Biener @ 2021-09-17  8:23 UTC (permalink / raw)
  To: Iain Sandoe; +Cc: Martin Liska, GCC Patches

On Thu, Sep 16, 2021 at 3:52 PM Iain Sandoe <iain@sandoe.co.uk> wrote:
>
>
> Hi Martin,
>
> > On 16 Sep 2021, at 11:00, Martin Liška <mliska@suse.cz> wrote:
> >
> > As preparation for a new global object that will encapsulate
> > asm_out_file, we would need to live with a macro that will
> > define asm_out_file as casm->out_file and thus the name
> > can't be used in function arguments.
>
> So, if I understand correctly, the motivation is to be able to switch
> between output file streams for different categories of content?
>
> Darwin, actually already does this (manually) with a separate
> lto_asm_out_name for lto data (so a general solution would
> be great).
>
> What is the reason for associating the section pointers with the
> casm object?
>
> * I can understand that each instance of a casm object would have
>  potentially a different current section (“in_section”), but it seems that
>  as things stand the section pointers would be duplicates.
>
> * In the case that there’s reason that the sections could be different
>   between casm instances, then would it make sense to have a
>   target hook so that target-specific sections can be added to the
>   local list (via some indirection, I’d assume)?

Yes, casm likely will end up with target specific state.  Note the main
motivation of the exercise is to develop and alternate way of funneling
the early debug data through the LTO pipeline, eliding the need for
the simple-object copying and section renaming dance.

The idea is that at dwarf2out_early_finish time (which runs at
the compile stage) we write a regular pure debug-info object
with unmangled section names to an alternate assembler file
which we then assemble and include as raw byte blob in the
LTO IR + debug object file.  At link time the debug object
byte blobs can either be re-instantiated as separate input
object file or the linker can be taught to pick them up from
the existing file at a byte offset (internally it does this for
AR archive members for example) avoiding the extra I/O.

So for this alternate assembler file we'd have a different set
of sections.

> —
>
> (of course, it would be great if one day we could abstract the asm out
>  such that we could switch to a direct-to-object implementation)

Small steps ;)

> > I've built all cross compilers with the change and
> > can bootstrap on x86_64-linux-gnu and survives regression tests.
>
> A native bootstrap fails early in stage1 for x86_64-darwin (I’ll take a look
> at fixing the issues once the patch series settles down)
>
> ---
>
> /src-local/gcc-master/gcc/dwarf2asm.c: In function ‘void dw2_asm_output_nstring(const char*, size_t, const char*, ...)’:
> /src-local/gcc-master/gcc/output.h:387:26: error: expected initializer before ‘->’ token
>  #define asm_out_file casm->out_file
>                           ^
> /src-local/gcc-master/gcc/defaults.h:68:13: note: in expansion of macro ‘asm_out_file’
>        FILE *asm_out_file = _hide_asm_out_file;          \
>              ^~~~~~~~~~~~
> /src-local/gcc-master/gcc/dwarf2asm.c:414:7: note: in expansion of macro ‘ASM_OUTPUT_ASCII’
>        ASM_OUTPUT_ASCII (asm_out_file, str, len);
>        ^~~~~~~~~~~~~~~~
> In file included from ./tm.h:42:0,
>
> ------
>
> /src-local/gcc-master/gcc/config/i386/darwin.h:219:6: error: ‘in_section’ was not declared in this scope
>   if (in_section == text_section)       \
>       ^
> /src-local/gcc-master/gcc/dwarf2out.c:677:3: note: in expansion of macro ‘ASM_OUTPUT_ALIGN’
>    ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE));
>
>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 1/N] Rename asm_out_file function arguments.
  2021-09-17  8:23     ` Richard Biener
@ 2021-09-17  9:42       ` Iain Sandoe
  2021-09-17  9:57         ` Richard Biener
  0 siblings, 1 reply; 30+ messages in thread
From: Iain Sandoe @ 2021-09-17  9:42 UTC (permalink / raw)
  To: Richard Biener; +Cc: Martin Liska, GCC Patches

Hi Folks,

> On 17 Sep 2021, at 09:23, Richard Biener <richard.guenther@gmail.com> wrote:
> 
> On Thu, Sep 16, 2021 at 3:52 PM Iain Sandoe <iain@sandoe.co.uk> wrote:
>> 
>> 
>>> On 16 Sep 2021, at 11:00, Martin Liška <mliska@suse.cz> wrote:
>>> 
>>> As preparation for a new global object that will encapsulate
>>> asm_out_file, we would need to live with a macro that will
>>> define asm_out_file as casm->out_file and thus the name
>>> can't be used in function arguments.
>> 
>> So, if I understand correctly, the motivation is to be able to switch
>> between output file streams for different categories of content?
>> 
>> Darwin, actually already does this (manually) with a separate
>> lto_asm_out_name for lto data (so a general solution would
>> be great).
>> 
>> What is the reason for associating the section pointers with the
>> casm object?
>> 
>> * I can understand that each instance of a casm object would have
>> potentially a different current section (“in_section”), but it seems that
>> as things stand the section pointers would be duplicates.
>> 
>> * In the case that there’s reason that the sections could be different
>>  between casm instances, then would it make sense to have a
>>  target hook so that target-specific sections can be added to the
>>  local list (via some indirection, I’d assume)?
> 
> Yes, casm likely will end up with target specific state.  Note the main
> motivation of the exercise is to develop and alternate way of funneling
> the early debug data through the LTO pipeline, eliding the need for
> the simple-object copying and section renaming dance.

great ;-)

FWIW, I did an implementation for Darwin, but not yet presented/comitted
because…. the dependencies on the debug linker (dsymutil) mean that it
is of limited value until I can find time to fix that up to understand the input.

> The idea is that at dwarf2out_early_finish time (which runs at
> the compile stage) we write a regular pure debug-info object
> with unmangled section names to an alternate assembler file
> which we then assemble and include as raw byte blob in the
> LTO IR + debug object file.  At link time the debug object
> byte blobs can either be re-instantiated as separate input
> object file or the linker can be taught to pick them up from
> the existing file at a byte offset (internally it does this for
> AR archive members for example) avoiding the extra I/O.

… the more dependencies on external tool behaviour we have
the harder it gets for non-ELF-binutils targets; I’d like to think
about how to implement this in Mach-O…

I don’t think there’s any mechanism for Mach-O to include an
arbitrary blob in a _regular_ mach-o file, of course one could make
it FAT in some way - but that would mean a lot of changes to the
back end tools..

… so the path of least resistance is to do something like we do
with the LTO already - abstract the info into a blob section with
and index and a name table (we funnel the LTO off into a second
file and then re-include that in finish_asm_file).

not sure what xcoff etc. can do...

> So for this alternate assembler file we'd have a different set
> of sections.

can you give me an example ?
(I’m not succeeding in visualizing this yet).

Note that we already have categories of sections:
 generic (e.g. .text, .data, etc. supported by all file formats)
 language-related (for at least C++, D, ObjC…)
 debug
 lto
 back-end-specific 

I was wondering which of those needed to be cloned per casm
and if it includes any of the language/back-end ones how we figure
a mechanism to include those (I suppose the usual style of a macro-
programmed .def would work?)

>> —
>> 
>> (of course, it would be great if one day we could abstract the asm out
>> such that we could switch to a direct-to-object implementation)
> 
> Small steps ;)

Yes - but it’s easier to see if the small steps are in the direction we want,
with some idea of the finishing post, right? :)

I was wondering about a conceptual scenario like:

 casm ==> target_asm state
 this also conceptually “owns” the TARGET_ASM macros.
 one could consider migrating those macros to add casm as a first argument
 this would allow a second migration when target chose to implement the macros
 as inline functions taking the state as a first argument...

 .. or to implement casm as an abstract base class, where the target macros become
 virtual methods, with a default impl. that can be overriden by the target.

 My guess is that people will say “the second one is too much overhead because it
 incurs an indirection instead of the direct inline” … I suppose that depends on how
 well we devirtualize ….

>>> I've built all cross compilers with the change and
>>> can bootstrap on x86_64-linux-gnu and survives regression tests.
>> 
>> A native bootstrap fails early in stage1 for x86_64-darwin (I’ll take a look
>> at fixing the issues once the patch series settles down)

JFTR, I applied the first two patches and then a couple of tweaks and it did
bootstrap on Darwin.

thanks
Iain



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 1/N] Rename asm_out_file function arguments.
  2021-09-17  9:42       ` Iain Sandoe
@ 2021-09-17  9:57         ` Richard Biener
  0 siblings, 0 replies; 30+ messages in thread
From: Richard Biener @ 2021-09-17  9:57 UTC (permalink / raw)
  To: Iain Sandoe; +Cc: Martin Liska, GCC Patches

On Fri, Sep 17, 2021 at 11:42 AM Iain Sandoe <iain@sandoe.co.uk> wrote:
>
> Hi Folks,
>
> > On 17 Sep 2021, at 09:23, Richard Biener <richard.guenther@gmail.com> wrote:
> >
> > On Thu, Sep 16, 2021 at 3:52 PM Iain Sandoe <iain@sandoe.co.uk> wrote:
> >>
> >>
> >>> On 16 Sep 2021, at 11:00, Martin Liška <mliska@suse.cz> wrote:
> >>>
> >>> As preparation for a new global object that will encapsulate
> >>> asm_out_file, we would need to live with a macro that will
> >>> define asm_out_file as casm->out_file and thus the name
> >>> can't be used in function arguments.
> >>
> >> So, if I understand correctly, the motivation is to be able to switch
> >> between output file streams for different categories of content?
> >>
> >> Darwin, actually already does this (manually) with a separate
> >> lto_asm_out_name for lto data (so a general solution would
> >> be great).
> >>
> >> What is the reason for associating the section pointers with the
> >> casm object?
> >>
> >> * I can understand that each instance of a casm object would have
> >> potentially a different current section (“in_section”), but it seems that
> >> as things stand the section pointers would be duplicates.
> >>
> >> * In the case that there’s reason that the sections could be different
> >>  between casm instances, then would it make sense to have a
> >>  target hook so that target-specific sections can be added to the
> >>  local list (via some indirection, I’d assume)?
> >
> > Yes, casm likely will end up with target specific state.  Note the main
> > motivation of the exercise is to develop and alternate way of funneling
> > the early debug data through the LTO pipeline, eliding the need for
> > the simple-object copying and section renaming dance.
>
> great ;-)
>
> FWIW, I did an implementation for Darwin, but not yet presented/comitted
> because…. the dependencies on the debug linker (dsymutil) mean that it
> is of limited value until I can find time to fix that up to understand the input.
>
> > The idea is that at dwarf2out_early_finish time (which runs at
> > the compile stage) we write a regular pure debug-info object
> > with unmangled section names to an alternate assembler file
> > which we then assemble and include as raw byte blob in the
> > LTO IR + debug object file.  At link time the debug object
> > byte blobs can either be re-instantiated as separate input
> > object file or the linker can be taught to pick them up from
> > the existing file at a byte offset (internally it does this for
> > AR archive members for example) avoiding the extra I/O.
>
> … the more dependencies on external tool behaviour we have
> the harder it gets for non-ELF-binutils targets; I’d like to think
> about how to implement this in Mach-O…
>
> I don’t think there’s any mechanism for Mach-O to include an
> arbitrary blob in a _regular_ mach-o file, of course one could make
> it FAT in some way - but that would mean a lot of changes to the
> back end tools..

Nah, it would be GCC itself opening the object and copying the
data byte-by-byte into a special LTO data section which of course
means emitting a lot of .data in the assembler ... but well.

We could do without the copying but then we produce two files
for each object we compile - the LTO IR .o and the object with
the debug info, say, .debug.o.  The debug info will be linked into
the final object without further changes.  But we have to be
able to emit those two objects from a single cc1 invocation - that's
what this change is about (yeah, emit assembly).

The copying would just involve assembling the alternate file
and including it as data in the main assembly (and thus object)
in a way that makes it easy to either re-materialize the alternate
object file at link time or include it by reference.

> … so the path of least resistance is to do something like we do
> with the LTO already - abstract the info into a blob section with
> and index and a name table (we funnel the LTO off into a second
> file and then re-include that in finish_asm_file).
>
> not sure what xcoff etc. can do...
>
> > So for this alternate assembler file we'd have a different set
> > of sections.
>
> can you give me an example ?
> (I’m not succeeding in visualizing this yet).
>
> Note that we already have categories of sections:
>  generic (e.g. .text, .data, etc. supported by all file formats)
>  language-related (for at least C++, D, ObjC…)
>  debug
>  lto
>  back-end-specific
>
> I was wondering which of those needed to be cloned per casm
> and if it includes any of the language/back-end ones how we figure
> a mechanism to include those (I suppose the usual style of a macro-
> programmed .def would work?)

In principle all of them - we are really emitting a completely separate
and different object file (as assembler).  For the LTO debug use
we'd need all DWARF .debug_* sections.

I understand that all the special backend sections are eventually
created on-demand (there's also targetm.asm_file_start/end ...)

> >> —
> >>
> >> (of course, it would be great if one day we could abstract the asm out
> >> such that we could switch to a direct-to-object implementation)
> >
> > Small steps ;)
>
> Yes - but it’s easier to see if the small steps are in the direction we want,
> with some idea of the finishing post, right? :)
>
> I was wondering about a conceptual scenario like:
>
>  casm ==> target_asm state
>  this also conceptually “owns” the TARGET_ASM macros.
>  one could consider migrating those macros to add casm as a first argument
>  this would allow a second migration when target chose to implement the macros
>  as inline functions taking the state as a first argument...
>
>  .. or to implement casm as an abstract base class, where the target macros become
>  virtual methods, with a default impl. that can be overriden by the target.
>
>  My guess is that people will say “the second one is too much overhead because it
>  incurs an indirection instead of the direct inline” … I suppose that depends on how
>  well we devirtualize ….

Yes, adjusting the TARGET_ASM macros is the next natural step, and I'd
do it the C way, provide the asm-out state as argument (but we already
have cfun, so casm didn't seem so gross).

> >>> I've built all cross compilers with the change and
> >>> can bootstrap on x86_64-linux-gnu and survives regression tests.
> >>
> >> A native bootstrap fails early in stage1 for x86_64-darwin (I’ll take a look
> >> at fixing the issues once the patch series settles down)
>
> JFTR, I applied the first two patches and then a couple of tweaks and it did
> bootstrap on Darwin.
>
> thanks
> Iain
>
>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 2/N] Do not hide asm_out_file in ASM_OUTPUT_ASCII.
  2021-09-16 10:00 ` [PATCH 2/N] Do not hide asm_out_file in ASM_OUTPUT_ASCII Martin Liška
@ 2021-09-22  9:44   ` Richard Biener
  2021-09-30 11:46     ` Martin Liška
  0 siblings, 1 reply; 30+ messages in thread
From: Richard Biener @ 2021-09-22  9:44 UTC (permalink / raw)
  To: Martin Liška; +Cc: GCC Patches

On Thu, Sep 16, 2021 at 12:01 PM Martin Liška <mliska@suse.cz> wrote:
>
> Again a preparation patch that was tested on all cross compilers.
>
> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>
> Ready to be installed?

I think you want to retain

-    FILE *_hide_asm_out_file = (MYFILE);

and use _hide_asm_out_file to preserve MYFILE execution counts in case
it contains side-effects.

OK with that change.

Richard.

> Thanks,
> Martin

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 3/N] Come up with casm global state.
  2021-09-16 13:12 ` [PATCH 3/N] Come up with casm global state Martin Liška
@ 2021-09-22  9:59   ` Richard Biener
  2021-10-04 11:13     ` Martin Liška
  2021-10-04 11:16   ` Martin Liška
  2021-10-21 12:47   ` David Malcolm
  2 siblings, 1 reply; 30+ messages in thread
From: Richard Biener @ 2021-09-22  9:59 UTC (permalink / raw)
  To: Martin Liška; +Cc: GCC Patches

On Thu, Sep 16, 2021 at 3:12 PM Martin Liška <mliska@suse.cz> wrote:
>
> This patch comes up with asm_out_state and a new global variable casm.
>
> Tested on all cross compilers.
> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>
> Ready to be installed?

        * output.h (struct asm_out_file): New struct that replaces a
^^^
asm_out_state?

You replace a lot of asm_out_file - do we still need the macro then?
(I'd have simplified the patch leaving that replacement out at first)

You leave quite some global state out of the struct that is obviously
related, in the diff I see object_block_htab for example.  Basically
everything initialized in init_varasm_once is a candidate (which
then shows const_desc_htab and shared_constant_pool as well
as pending_assemble_externals_set).  For the goal of outputting
early DWARF to another file the state CTOR could have a mode
to not initialize those parts or we could have asm-out-state-with-sections
as base of asm-out-state.

In the end there will be a target part of the state so I think
construction needs to be defered to the target which can
derive from asm-out-state and initialize the part it needs.
That's currently what targetm.asm_out.init_sections () does
and we'd transform that to a targetm.asm_out.create () or so.
That might already be necessary for the DWARF stuff.

That said, dealing with the target stuff piecemail is OK, but maybe
try to make sure that init_varasm_once is actually identical
to what the CTOR does?

Richard.

> Thanks,
> Martin

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 2/N] Do not hide asm_out_file in ASM_OUTPUT_ASCII.
  2021-09-22  9:44   ` Richard Biener
@ 2021-09-30 11:46     ` Martin Liška
  0 siblings, 0 replies; 30+ messages in thread
From: Martin Liška @ 2021-09-30 11:46 UTC (permalink / raw)
  To: Richard Biener; +Cc: GCC Patches

On 9/22/21 11:44, Richard Biener wrote:
> On Thu, Sep 16, 2021 at 12:01 PM Martin Liška <mliska@suse.cz> wrote:
>>
>> Again a preparation patch that was tested on all cross compilers.
>>
>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>>
>> Ready to be installed?
> 
> I think you want to retain
> 
> -    FILE *_hide_asm_out_file = (MYFILE);

Oh, oh!

> 
> and use _hide_asm_out_file to preserve MYFILE execution counts in case
> it contains side-effects.

I do always forget about the fact that macros can have side-effects.

Thanks for review,
Martin

> 
> OK with that change.
> 
> Richard.
> 
>> Thanks,
>> Martin


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 3/N] Come up with casm global state.
  2021-09-22  9:59   ` Richard Biener
@ 2021-10-04 11:13     ` Martin Liška
  2021-10-05 11:54       ` Richard Biener
  0 siblings, 1 reply; 30+ messages in thread
From: Martin Liška @ 2021-10-04 11:13 UTC (permalink / raw)
  To: Richard Biener; +Cc: GCC Patches

On 9/22/21 11:59, Richard Biener wrote:
> On Thu, Sep 16, 2021 at 3:12 PM Martin Liška <mliska@suse.cz> wrote:
>>
>> This patch comes up with asm_out_state and a new global variable casm.
>>
>> Tested on all cross compilers.
>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>>
>> Ready to be installed?
> 
>          * output.h (struct asm_out_file): New struct that replaces a
> ^^^
> asm_out_state?

Yes, sure!

> 
> You replace a lot of asm_out_file - do we still need the macro then?
> (I'd have simplified the patch leaving that replacement out at first)

Well, I actually replaced only a very small fraction of the usage of asm_out_file.

$ git grep asm_out_file | grep -v ChangeLog | wc -l

1601


So I think we should live with the macro for some time ...

> 
> You leave quite some global state out of the struct that is obviously
> related, in the diff I see object_block_htab for example.

Yes, I'm aware of it. Can we do that incrementally?

> Basically
> everything initialized in init_varasm_once is a candidate (which
> then shows const_desc_htab and shared_constant_pool as well
> as pending_assemble_externals_set).

Well, these would probably need a different header file (or another #include ... must
be added before output.h :// ).

> For the goal of outputting
> early DWARF to another file the state CTOR could have a mode
> to not initialize those parts or we could have asm-out-state-with-sections
> as base of asm-out-state.

Yes, right now asm_out_state ctor is minimal:

   asm_out_state (): out_file (NULL), in_section (NULL),
     sec ({}), anchor_labelno (0), in_cold_section_p (false)
   {
     section_htab = hash_table<section_hasher>::create_ggc (31);
   }

> 
> In the end there will be a target part of the state so I think
> construction needs to be defered to the target which can
> derive from asm-out-state and initialize the part it needs.
> That's currently what targetm.asm_out.init_sections () does
> and we'd transform that to a targetm.asm_out.create () or so.
> That might already be necessary for the DWARF stuff.

So what do you want to with content of init_varasm_once function?

> 
> That said, dealing with the target stuff piecemail is OK, but maybe
> try to make sure that init_varasm_once is actually identical
> to what the CTOR does?

So you want asm_out_state::asm_out_state doing what we current initialize
in init_varasm_once, right?

Thanks,
Cheers,
Martin


> 
> Richard.
> 
>> Thanks,
>> Martin


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 3/N] Come up with casm global state.
  2021-09-16 13:12 ` [PATCH 3/N] Come up with casm global state Martin Liška
  2021-09-22  9:59   ` Richard Biener
@ 2021-10-04 11:16   ` Martin Liška
  2021-10-21 12:47   ` David Malcolm
  2 siblings, 0 replies; 30+ messages in thread
From: Martin Liška @ 2021-10-04 11:16 UTC (permalink / raw)
  To: GCC Patches

On 9/16/21 15:12, Martin Liška wrote:
> This patch comes up with asm_out_state and a new global variable casm.
> 
> Tested on all cross compilers.
> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
> 
> Ready to be installed?
> Thanks,
> Martin

As explained in the '3/N' part, we will have to live with asm_out_file macro
for some time. Is this renaming patch fine?

Thanks,
Martin

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 3/N] Come up with casm global state.
  2021-10-04 11:13     ` Martin Liška
@ 2021-10-05 11:54       ` Richard Biener
  2021-10-21  9:47         ` Martin Liška
  0 siblings, 1 reply; 30+ messages in thread
From: Richard Biener @ 2021-10-05 11:54 UTC (permalink / raw)
  To: Martin Liška; +Cc: GCC Patches

On Mon, Oct 4, 2021 at 1:13 PM Martin Liška <mliska@suse.cz> wrote:
>
> On 9/22/21 11:59, Richard Biener wrote:
> > On Thu, Sep 16, 2021 at 3:12 PM Martin Liška <mliska@suse.cz> wrote:
> >>
> >> This patch comes up with asm_out_state and a new global variable casm.
> >>
> >> Tested on all cross compilers.
> >> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
> >>
> >> Ready to be installed?
> >
> >          * output.h (struct asm_out_file): New struct that replaces a
> > ^^^
> > asm_out_state?
>
> Yes, sure!
>
> >
> > You replace a lot of asm_out_file - do we still need the macro then?
> > (I'd have simplified the patch leaving that replacement out at first)
>
> Well, I actually replaced only a very small fraction of the usage of asm_out_file.
>
> $ git grep asm_out_file | grep -v ChangeLog | wc -l
>
> 1601
>
>
> So I think we should live with the macro for some time ...
>
> >
> > You leave quite some global state out of the struct that is obviously
> > related, in the diff I see object_block_htab for example.
>
> Yes, I'm aware of it. Can we do that incrementally?
>
> > Basically
> > everything initialized in init_varasm_once is a candidate (which
> > then shows const_desc_htab and shared_constant_pool as well
> > as pending_assemble_externals_set).
>
> Well, these would probably need a different header file (or another #include ... must
> be added before output.h :// ).
>
> > For the goal of outputting
> > early DWARF to another file the state CTOR could have a mode
> > to not initialize those parts or we could have asm-out-state-with-sections
> > as base of asm-out-state.
>
> Yes, right now asm_out_state ctor is minimal:
>
>    asm_out_state (): out_file (NULL), in_section (NULL),
>      sec ({}), anchor_labelno (0), in_cold_section_p (false)
>    {
>      section_htab = hash_table<section_hasher>::create_ggc (31);
>    }
>
> >
> > In the end there will be a target part of the state so I think
> > construction needs to be defered to the target which can
> > derive from asm-out-state and initialize the part it needs.
> > That's currently what targetm.asm_out.init_sections () does
> > and we'd transform that to a targetm.asm_out.create () or so.
> > That might already be necessary for the DWARF stuff.
>
> So what do you want to with content of init_varasm_once function?

It goes away ;)  Or rather becomes the invocation of the
asm-out-state CTOR via the target hook.

> >
> > That said, dealing with the target stuff piecemail is OK, but maybe
> > try to make sure that init_varasm_once is actually identical
> > to what the CTOR does?
>
> So you want asm_out_state::asm_out_state doing what we current initialize
> in init_varasm_once, right?

Yes, asm_out_state should cover everything initialized in init_varasm_once
(and the called targetm.asm_out.init_sections).

targetm.asm_out.init_sections would become

asm_out_state *init_sections ();

where the target can derive from asm_out_state (optionally) and
allocates the asm-out-state & invokes the CTORs.  The middle-end
visible asm_out_state would contain all the tables initialized in
init_varasm_once.

I'm not sure if doing it piecemail is good - we don't want to touch
things multiple times without good need and it might be things
turn out not be as "simple" as the above plan sounds.

I would suggest to try the conversion with powerpc since it
seems to be the only target with two different implementations
for the target hook.

The

static GTY(()) section *read_only_data_section;
static GTY(()) section *private_data_section;
static GTY(()) section *tls_data_section;
static GTY(()) section *tls_private_data_section;
static GTY(()) section *read_only_private_data_section;
static GTY(()) section *sdata2_section;

section *toc_section = 0;

could become #defines to static_cast<rs6000_asm_out_state *>
(casm)->section_name
and there'd be

class rs6000_asm_out_state : public asm_out_state
{
... add stuff ...
}

in rs6000/xcoff.h and rs6000/sysv4.h and some generic rs6000 header as well
(adding no fields) and the target hook would basically do

 return ggc_new rs6000_asm_state ();

(OK, ggc_alloc + placement new I guess).  The default hook just
creates asm_out_state.

Richard.

> Thanks,
> Cheers,
> Martin
>
>
> >
> > Richard.
> >
> >> Thanks,
> >> Martin
>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 1/N] Rename asm_out_file function arguments.
  2021-09-16 10:00 ` [PATCH 1/N] Rename asm_out_file function arguments Martin Liška
  2021-09-16 13:52   ` Iain Sandoe
@ 2021-10-20 11:57   ` Martin Liška
  2021-10-20 12:11     ` Richard Biener
  1 sibling, 1 reply; 30+ messages in thread
From: Martin Liška @ 2021-10-20 11:57 UTC (permalink / raw)
  To: GCC Patches

On 9/16/21 12:00, Martin Liška wrote:
> As preparation for a new global object that will encapsulate
> asm_out_file, we would need to live with a macro that will
> define asm_out_file as casm->out_file and thus the name
> can't be used in function arguments.
> 
> I've built all cross compilers with the change and
> can bootstrap on x86_64-linux-gnu and survives regression tests.
> 
> Ready to be installed?
> Thanks,
> Martin

May I please ping this renaming patch?

Thanks,
Martin


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 1/N] Rename asm_out_file function arguments.
  2021-10-20 11:57   ` Martin Liška
@ 2021-10-20 12:11     ` Richard Biener
  0 siblings, 0 replies; 30+ messages in thread
From: Richard Biener @ 2021-10-20 12:11 UTC (permalink / raw)
  To: Martin Liška; +Cc: GCC Patches

On Wed, Oct 20, 2021 at 1:58 PM Martin Liška <mliska@suse.cz> wrote:
>
> On 9/16/21 12:00, Martin Liška wrote:
> > As preparation for a new global object that will encapsulate
> > asm_out_file, we would need to live with a macro that will
> > define asm_out_file as casm->out_file and thus the name
> > can't be used in function arguments.
> >
> > I've built all cross compilers with the change and
> > can bootstrap on x86_64-linux-gnu and survives regression tests.
> >
> > Ready to be installed?
> > Thanks,
> > Martin
>
> May I please ping this renaming patch?

The patch is OK.

Thanks,
Richard.

> Thanks,
> Martin
>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 3/N] Come up with casm global state.
  2021-10-05 11:54       ` Richard Biener
@ 2021-10-21  9:47         ` Martin Liška
  2021-10-21 12:42           ` Richard Biener
  0 siblings, 1 reply; 30+ messages in thread
From: Martin Liška @ 2021-10-21  9:47 UTC (permalink / raw)
  To: Richard Biener; +Cc: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 4714 bytes --]

On 10/5/21 13:54, Richard Biener wrote:
> On Mon, Oct 4, 2021 at 1:13 PM Martin Liška <mliska@suse.cz> wrote:
>>
>> On 9/22/21 11:59, Richard Biener wrote:
>>> On Thu, Sep 16, 2021 at 3:12 PM Martin Liška <mliska@suse.cz> wrote:
>>>>
>>>> This patch comes up with asm_out_state and a new global variable casm.
>>>>
>>>> Tested on all cross compilers.
>>>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>>>>
>>>> Ready to be installed?
>>>
>>>           * output.h (struct asm_out_file): New struct that replaces a
>>> ^^^
>>> asm_out_state?
>>
>> Yes, sure!
>>
>>>
>>> You replace a lot of asm_out_file - do we still need the macro then?
>>> (I'd have simplified the patch leaving that replacement out at first)
>>
>> Well, I actually replaced only a very small fraction of the usage of asm_out_file.
>>
>> $ git grep asm_out_file | grep -v ChangeLog | wc -l
>>
>> 1601
>>
>>
>> So I think we should live with the macro for some time ...
>>
>>>
>>> You leave quite some global state out of the struct that is obviously
>>> related, in the diff I see object_block_htab for example.
>>
>> Yes, I'm aware of it. Can we do that incrementally?
>>
>>> Basically
>>> everything initialized in init_varasm_once is a candidate (which
>>> then shows const_desc_htab and shared_constant_pool as well
>>> as pending_assemble_externals_set).
>>
>> Well, these would probably need a different header file (or another #include ... must
>> be added before output.h :// ).
>>
>>> For the goal of outputting
>>> early DWARF to another file the state CTOR could have a mode
>>> to not initialize those parts or we could have asm-out-state-with-sections
>>> as base of asm-out-state.
>>
>> Yes, right now asm_out_state ctor is minimal:
>>
>>     asm_out_state (): out_file (NULL), in_section (NULL),
>>       sec ({}), anchor_labelno (0), in_cold_section_p (false)
>>     {
>>       section_htab = hash_table<section_hasher>::create_ggc (31);
>>     }
>>
>>>
>>> In the end there will be a target part of the state so I think
>>> construction needs to be defered to the target which can
>>> derive from asm-out-state and initialize the part it needs.
>>> That's currently what targetm.asm_out.init_sections () does
>>> and we'd transform that to a targetm.asm_out.create () or so.
>>> That might already be necessary for the DWARF stuff.
>>
>> So what do you want to with content of init_varasm_once function?
> 
> It goes away ;)  Or rather becomes the invocation of the
> asm-out-state CTOR via the target hook.
> 
>>>
>>> That said, dealing with the target stuff piecemail is OK, but maybe
>>> try to make sure that init_varasm_once is actually identical
>>> to what the CTOR does?
>>
>> So you want asm_out_state::asm_out_state doing what we current initialize
>> in init_varasm_once, right?
> 
> Yes, asm_out_state should cover everything initialized in init_varasm_once
> (and the called targetm.asm_out.init_sections).
> 
> targetm.asm_out.init_sections would become
> 
> asm_out_state *init_sections ();
> 
> where the target can derive from asm_out_state (optionally) and
> allocates the asm-out-state & invokes the CTORs.  The middle-end
> visible asm_out_state would contain all the tables initialized in
> init_varasm_once.
> 
> I'm not sure if doing it piecemail is good - we don't want to touch
> things multiple times without good need and it might be things
> turn out not be as "simple" as the above plan sounds.
> 
> I would suggest to try the conversion with powerpc since it
> seems to be the only target with two different implementations
> for the target hook.
> 
> The
> 
> static GTY(()) section *read_only_data_section;
> static GTY(()) section *private_data_section;
> static GTY(()) section *tls_data_section;
> static GTY(()) section *tls_private_data_section;
> static GTY(()) section *read_only_private_data_section;
> static GTY(()) section *sdata2_section;
> 
> section *toc_section = 0;
> 
> could become #defines to static_cast<rs6000_asm_out_state *>
> (casm)->section_name
> and there'd be
> 
> class rs6000_asm_out_state : public asm_out_state
> {
> ... add stuff ...
> }
> 
> in rs6000/xcoff.h and rs6000/sysv4.h and some generic rs6000 header as well
> (adding no fields) and the target hook would basically do
> 
>   return ggc_new rs6000_asm_state ();
> 
> (OK, ggc_alloc + placement new I guess).  The default hook just
> creates asm_out_state.

Hello.

All right, I made a patch candidate that does the suggested steps and I ported
rs6000 target (both ELF and XCOFF sub-targets).

So far I was able to bootstrap on ppc6le-linux-gnu.

Thoughts?
Thanks,
Martin

> 
> Richard.
> 
>> Thanks,
>> Cheers,
>> Martin
>>
>>
>>>
>>> Richard.
>>>
>>>> Thanks,
>>>> Martin
>>

[-- Attachment #2: 0001-Come-up-with-casm-global-state.patch --]
[-- Type: text/x-patch, Size: 119774 bytes --]

From 562caac65d81b75cb3085cd6ffd89b6723fe8d85 Mon Sep 17 00:00:00 2001
From: Martin Liska <mliska@suse.cz>
Date: Tue, 7 Sep 2021 13:32:57 +0200
Subject: [PATCH] Come up with casm global state.

---
 gcc/cgraphunit.c                    |   2 +-
 gcc/config/aarch64/aarch64.c        |   2 +-
 gcc/config/aarch64/aarch64.h        |   2 +-
 gcc/config/alpha/alpha.c            |  12 +-
 gcc/config/alpha/elf.h              |   4 +-
 gcc/config/arc/arc.c                |   2 +-
 gcc/config/arm/aout.h               |   2 +-
 gcc/config/arm/arm.c                |  14 +-
 gcc/config/arm/arm.h                |   2 +-
 gcc/config/arm/unknown-elf.h        |   4 +-
 gcc/config/avr/avr.c                |  12 +-
 gcc/config/bfin/bfin.h              |   2 +-
 gcc/config/c6x/c6x.c                |   4 +-
 gcc/config/c6x/c6x.h                |   4 +-
 gcc/config/csky/csky.c              |   2 +-
 gcc/config/darwin.c                 |  66 ++++----
 gcc/config/frv/frv.c                |   4 +-
 gcc/config/frv/frv.h                |   2 +-
 gcc/config/ft32/ft32.h              |   6 +-
 gcc/config/i386/cygming.h           |   2 +-
 gcc/config/i386/darwin.h            |   2 +-
 gcc/config/i386/i386.c              |   6 +-
 gcc/config/i386/sol2.h              |   6 +-
 gcc/config/i386/winnt.c             |   2 +-
 gcc/config/ia64/ia64.c              |   4 +-
 gcc/config/ia64/sysv4.h             |   4 +-
 gcc/config/lm32/lm32.h              |   8 +-
 gcc/config/m32r/m32r.h              |   2 +-
 gcc/config/mcore/mcore-elf.h        |   4 +-
 gcc/config/microblaze/microblaze.c  |   6 +-
 gcc/config/microblaze/microblaze.h  |   8 +-
 gcc/config/mips/mips.c              |   2 +-
 gcc/config/mmix/mmix.c              |   6 +-
 gcc/config/msp430/msp430.c          |   8 +-
 gcc/config/nios2/nios2.h            |   4 +-
 gcc/config/pa/pa.c                  |  34 ++--
 gcc/config/pdp11/pdp11.c            |   6 +-
 gcc/config/pru/pru.h                |   2 +-
 gcc/config/riscv/riscv.c            |   4 +-
 gcc/config/rl78/rl78.c              |  12 +-
 gcc/config/rs6000/rs6000-internal.h |  27 ++++
 gcc/config/rs6000/rs6000-logue.c    |   2 +-
 gcc/config/rs6000/rs6000.c          | 105 +++++++-----
 gcc/config/rs6000/rs6000.h          |   1 -
 gcc/config/rs6000/sysv4.h           |   2 +-
 gcc/config/rx/rx.c                  |  12 +-
 gcc/config/s390/s390.c              |   2 +-
 gcc/config/sh/sh.c                  |   2 +-
 gcc/config/sparc/sol2.h             |   6 +-
 gcc/config/sparc/sparc.c            |   2 +-
 gcc/config/tilegx/tilegx.h          |   2 +-
 gcc/config/tilepro/tilepro.h        |   2 +-
 gcc/config/v850/v850.c              |  10 +-
 gcc/config/visium/visium.h          |   4 +-
 gcc/coretypes.h                     |   1 +
 gcc/dbxout.c                        |  20 +--
 gcc/doc/tm.texi                     |  16 +-
 gcc/doc/tm.texi.in                  |  14 +-
 gcc/dwarf2out.c                     |  56 +++----
 gcc/dwarf2out.h                     |   4 +-
 gcc/except.c                        |  12 +-
 gcc/final.c                         |  24 +--
 gcc/ggc-common.c                    |   7 +
 gcc/langhooks.c                     |   4 +-
 gcc/output.h                        |  94 ++++++++---
 gcc/run-rtl-passes.c                |   2 +-
 gcc/target.def                      |   4 +-
 gcc/targhooks.c                     |   2 +-
 gcc/toplev.c                        |  38 ++---
 gcc/varasm.c                        | 237 ++++++++++++----------------
 gcc/vmsdbgout.c                     |   2 +-
 71 files changed, 539 insertions(+), 457 deletions(-)

diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 55cb0347149..773ca4fb27d 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -2309,7 +2309,7 @@ symbol_table::compile (void)
   timevar_pop (TV_CGRAPHOPT);
 
   /* Output everything.  */
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
   (*debug_hooks->assembly_start) ();
   if (!quiet_flag)
     fprintf (stderr, "Assembling functions:\n");
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 699c105a42a..b5bccdcfb88 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -25753,7 +25753,7 @@ aarch64_sls_emit_blr_function_thunks (FILE *out_file)
      would happen in a different section -- leaving an unmatched
      `.cfi_startproc` in the cold text section and an unmatched `.cfi_endproc`
      in the standard text section.  */
-  section *save_text_section = in_section;
+  section *save_text_section = casm->in_section;
   switch_to_section (function_section (current_function_decl));
   for (int regnum = 0; regnum < 30; ++regnum)
     {
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 2792bb29adb..8cb6a184bdc 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -1138,7 +1138,7 @@ typedef struct
 
 /* Put trampolines in the text section so that mapping symbols work
    correctly.  */
-#define TRAMPOLINE_SECTION text_section
+#define TRAMPOLINE_SECTION casm->sec.text
 
 /* To start with.  */
 #define BRANCH_COST(SPEED_P, PREDICTABLE_P) \
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index fced7ceefe2..cdf32ae37f4 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -8055,13 +8055,13 @@ alpha_start_function (FILE *file, const char *fnname,
 
 #ifdef TARGET_VMS_CRASH_DEBUG
   /* Support of minimal traceback info.  */
-  switch_to_section (readonly_data_section);
+  switch_to_section (casm->sec.readonly_data);
   fprintf (file, "\t.align 3\n");
   assemble_name (file, fnname); fputs ("..na:\n", file);
   fputs ("\t.ascii \"", file);
   assemble_name (file, fnname);
   fputs ("\\0\"\n", file);
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
 #endif
 #endif /* TARGET_ABI_OPEN_VMS */
 }
@@ -9446,7 +9446,7 @@ alpha_elf_select_rtx_section (machine_mode mode, rtx x,
 {
   if (TARGET_SMALL_DATA && GET_MODE_SIZE (mode) <= g_switch_value)
     /* ??? Consider using mergeable sdata sections.  */
-    return sdata_section;
+    return casm->sec.sdata;
   else
     return default_elf_select_rtx_section (mode, x, align);
 }
@@ -9613,7 +9613,7 @@ alpha_write_linkage (FILE *stream, const char *funname)
 {
   fprintf (stream, "\t.link\n");
   fprintf (stream, "\t.align 3\n");
-  in_section = NULL;
+  casm->in_section = NULL;
 
 #ifdef TARGET_VMS_CRASH_DEBUG
   fputs ("\t.name ", stream);
@@ -9665,7 +9665,7 @@ vms_asm_named_section (const char *name, unsigned int flags,
 static void
 vms_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
 {
-  switch_to_section (ctors_section);
+  switch_to_section (casm->sec.ctors);
   assemble_align (BITS_PER_WORD);
   assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
 }
@@ -9673,7 +9673,7 @@ vms_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
 static void
 vms_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
 {
-  switch_to_section (dtors_section);
+  switch_to_section (casm->sec.dtors);
   assemble_align (BITS_PER_WORD);
   assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
 }
diff --git a/gcc/config/alpha/elf.h b/gcc/config/alpha/elf.h
index b735f279b30..5a34bccccad 100644
--- a/gcc/config/alpha/elf.h
+++ b/gcc/config/alpha/elf.h
@@ -46,9 +46,9 @@ along with GCC; see the file COPYING3.  If not see
 #define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)		\
 do {									\
   if ((SIZE) <= (unsigned HOST_WIDE_INT) g_switch_value)		\
-    switch_to_section (sbss_section);					\
+    switch_to_section (casm->sec.sbss);					\
   else									\
-    switch_to_section (bss_section);					\
+    switch_to_section (casm->sec.bss);					\
   ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
   if (!flag_inhibit_size_directive)					\
     ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);			\
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 8244f37bf03..9b3a55ca40d 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -8832,7 +8832,7 @@ arc_asm_output_aligned_decl_local (FILE * stream, tree decl, const char * name,
     switch_to_section (get_named_section (NULL, ".sbss", 0));
   /*    named_section (0,".sbss",0); */
   else
-    switch_to_section (bss_section);
+    switch_to_section (casm->sec.bss);
 
   if (globalize_p)
     (*targetm.asm_out.globalize_label) (stream, name);
diff --git a/gcc/config/arm/aout.h b/gcc/config/arm/aout.h
index 25a2812a663..01743bb040e 100644
--- a/gcc/config/arm/aout.h
+++ b/gcc/config/arm/aout.h
@@ -288,7 +288,7 @@
 #define ASM_OUTPUT_ALIGNED_LOCAL(STREAM, NAME, SIZE, ALIGN)		\
   do									\
     {									\
-      switch_to_section (bss_section);					\
+      switch_to_section (casm->sec.bss);					\
       ASM_OUTPUT_ALIGN (STREAM, floor_log2 (ALIGN / BITS_PER_UNIT));	\
       ASM_OUTPUT_LABEL (STREAM, NAME);					\
       fprintf (STREAM, "\t.space\t%d\n", (int)(SIZE));			\
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index c4ff06b087e..38c53e69b9a 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -17210,7 +17210,7 @@ get_jump_table_size (rtx_jump_table_data *insn)
 {
   /* ADDR_VECs only take room if read-only data does into the text
      section.  */
-  if (JUMP_TABLES_IN_TEXT_SECTION || readonly_data_section == text_section)
+  if (JUMP_TABLES_IN_TEXT_SECTION || casm->sec.readonly_data == casm->sec.text)
     {
       rtx body = PATTERN (insn);
       int elt = GET_CODE (body) == ADDR_DIFF_VEC ? 1 : 0;
@@ -24618,9 +24618,9 @@ arm_elf_asm_cdtor (rtx symbol, int priority, bool is_ctor)
       s = get_section (buf, SECTION_WRITE | SECTION_NOTYPE, NULL_TREE);
     }
   else if (is_ctor)
-    s = ctors_section;
+    s = casm->sec.ctors;
   else
-    s = dtors_section;
+    s = casm->sec.dtors;
 
   switch_to_section (s);
   assemble_align (POINTER_SIZE);
@@ -27886,7 +27886,7 @@ thumb_call_via_reg (rtx reg)
   /* If we are in the normal text section we can use a single instance
      per compilation unit.  If we are doing function sections, then we need
      an entry per section, since we can't rely on reachability.  */
-  if (in_section == text_section)
+  if (casm->in_section == casm->sec.text)
     {
       thumb_call_reg_needed = 1;
 
@@ -28278,7 +28278,7 @@ arm_file_end (void)
   if (! thumb_call_reg_needed)
     return;
 
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
   asm_fprintf (asm_out_file, "\t.code 16\n");
   ASM_OUTPUT_ALIGN (asm_out_file, 1);
 
@@ -29728,13 +29728,13 @@ static void
 arm_asm_init_sections (void)
 {
 #if ARM_UNWIND_INFO
-  exception_section = get_unnamed_section (0, output_section_asm_op,
+  casm->sec.exception = get_unnamed_section (0, output_section_asm_op,
 					   "\t.handlerdata");
 #endif /* ARM_UNWIND_INFO */
 
 #ifdef OBJECT_FORMAT_ELF
   if (target_pure_code)
-    text_section->unnamed.data = "\t.section .text,\"0x20000006\",%progbits";
+    casm->sec.text->unnamed.data = "\t.section .text,\"0x20000006\",%progbits";
 #endif
 }
 
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 015299c1534..845b965f75f 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -1613,7 +1613,7 @@ machine_function;
 #define ARM_GE_BITS_READ (arm_ge_bits_access ())
 
 /* As in the machine_function, a global set of call-via labels, for code 
-   that is in text_section.  */
+   that is in casm->sec.text.  */
 extern GTY(()) rtx thumb_call_via_label[14];
 
 /* The number of potential ways of assigning to a co-processor.  */
diff --git a/gcc/config/arm/unknown-elf.h b/gcc/config/arm/unknown-elf.h
index cca6f0ece54..6aba52284c3 100644
--- a/gcc/config/arm/unknown-elf.h
+++ b/gcc/config/arm/unknown-elf.h
@@ -61,7 +61,7 @@
       if (IN_NAMED_SECTION_P (DECL))					\
 	switch_to_section (get_named_section (DECL, NULL, 0));		\
       else								\
-	switch_to_section (bss_section);				\
+	switch_to_section (casm->sec.bss);				\
       									\
       ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT));	\
 									\
@@ -78,7 +78,7 @@
       if ((DECL) != NULL && IN_NAMED_SECTION_P (DECL))			\
 	switch_to_section (get_named_section (DECL, NULL, 0));		\
       else								\
-	switch_to_section (bss_section);				\
+	switch_to_section (casm->sec.bss);				\
 									\
       ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT));	\
       ASM_OUTPUT_LABEL (FILE, NAME);					\
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 200701a583c..c89e7b610ea 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -10085,7 +10085,7 @@ avr_asm_asm_output_aligned_bss (FILE *file, tree decl, const char *name,
 }
 
 
-/* Unnamed section callback for data_section
+/* Unnamed section callback for casm->sec.data
    to track need of __do_copy_data.  */
 
 static void
@@ -10098,7 +10098,7 @@ avr_output_data_section_asm_op (const void *data)
 }
 
 
-/* Unnamed section callback for bss_section
+/* Unnamed section callback for casm->sec.bss
    to track need of __do_clear_bss.  */
 
 static void
@@ -10133,9 +10133,9 @@ avr_asm_init_sections (void)
 #if defined HAVE_LD_AVR_AVRXMEGA3_RODATA_IN_FLASH
   if (avr_arch->flash_pm_offset == 0)
 #endif
-    readonly_data_section->unnamed.callback = avr_output_data_section_asm_op;
-  data_section->unnamed.callback = avr_output_data_section_asm_op;
-  bss_section->unnamed.callback = avr_output_bss_section_asm_op;
+    casm->sec.readonly_data->unnamed.callback = avr_output_data_section_asm_op;
+  casm->sec.data->unnamed.callback = avr_output_data_section_asm_op;
+  casm->sec.bss->unnamed.callback = avr_output_bss_section_asm_op;
 }
 
 
@@ -12567,7 +12567,7 @@ avr_output_addr_vec (rtx_insn *labl, rtx table)
   // Switch back to original section.  As we clobbered the section above,
   // forget the current section before switching back.
 
-  in_section = NULL;
+  casm->in_section = NULL;
   switch_to_section (current_function_section ());
 }
 
diff --git a/gcc/config/bfin/bfin.h b/gcc/config/bfin/bfin.h
index 823ca2d7124..4aaee42e0e6 100644
--- a/gcc/config/bfin/bfin.h
+++ b/gcc/config/bfin/bfin.h
@@ -1053,7 +1053,7 @@ do { char __buf[256];					\
 
 #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) 	\
 do { 						\
-    switch_to_section (data_section);				\
+    switch_to_section (casm->sec.data);				\
     if ((SIZE) >= (unsigned int) 4 ) ASM_OUTPUT_ALIGN(FILE,2);	\
     ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);		\
     ASM_OUTPUT_LABEL (FILE, NAME);				\
diff --git a/gcc/config/c6x/c6x.c b/gcc/config/c6x/c6x.c
index 4854371ee13..33bb40f51aa 100644
--- a/gcc/config/c6x/c6x.c
+++ b/gcc/config/c6x/c6x.c
@@ -891,7 +891,7 @@ c6x_select_rtx_section (machine_mode mode, rtx x,
   if (c6x_sdata_mode == C6X_SDATA_ALL
       || (c6x_sdata_mode != C6X_SDATA_NONE && GET_MODE_SIZE (mode) <= 8))
     /* ??? Consider using mergeable sdata sections.  */
-    return sdata_section;
+    return casm->sec.sdata;
   else
     return default_elf_select_rtx_section (mode, x, align);
 }
@@ -5474,7 +5474,7 @@ c6x_asm_emit_except_personality (rtx personality)
 static void
 c6x_asm_init_sections (void)
 {
-  exception_section = get_unnamed_section (0, output_section_asm_op,
+  casm->sec.exception = get_unnamed_section (0, output_section_asm_op,
 					   "\t.handlerdata");
 }
 
diff --git a/gcc/config/c6x/c6x.h b/gcc/config/c6x/c6x.h
index 9e0a20d20cb..4b9ec51bd72 100644
--- a/gcc/config/c6x/c6x.h
+++ b/gcc/config/c6x/c6x.h
@@ -557,9 +557,9 @@ do { char __buf[256];					\
 #define ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN)	\
 do {									\
   if (PLACE_IN_SDATA_P (DECL))						\
-    switch_to_section (sbss_section);					\
+    switch_to_section (casm->sec.sbss);					\
   else									\
-    switch_to_section (bss_section);					\
+    switch_to_section (casm->sec.bss);					\
   ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
   if (!flag_inhibit_size_directive)					\
     ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);			\
diff --git a/gcc/config/csky/csky.c b/gcc/config/csky/csky.c
index 487288b3292..24c97a5e830 100644
--- a/gcc/config/csky/csky.c
+++ b/gcc/config/csky/csky.c
@@ -959,7 +959,7 @@ get_csky_jump_table_size (rtx insn)
 {
   /* ADDR_VECs only take room if read-only data does into the text
      section.  */
-  if (JUMP_TABLES_IN_TEXT_SECTION || readonly_data_section == text_section)
+  if (JUMP_TABLES_IN_TEXT_SECTION || casm->sec.readonly_data == casm->sec.text)
     {
       rtx body = PATTERN (insn);
       int elt = GET_CODE (body) == ADDR_DIFF_VEC ? 1 : 0;
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index 204114c96a2..90ce237cfa5 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -144,7 +144,7 @@ output_objc_section_asm_op (const void *directive)
      section is requested.  */
   if (darwin_symbol_stubs && ! been_here)
     {
-      section *saved_in_section = in_section;
+      section *saved_in_section = casm->in_section;
       static const enum darwin_section_enum tomark[] =
 	{
 	  /* written, cold -> hot */
@@ -237,14 +237,14 @@ darwin_init_sections (void)
 #include "config/darwin-sections.def"
 #undef DEF_SECTION
 
-  readonly_data_section = darwin_sections[const_section];
-  exception_section = darwin_sections[darwin_exception_section];
-  eh_frame_section = darwin_sections[darwin_eh_frame_section];
+  casm->sec.readonly_data = darwin_sections[const_section];
+  casm->sec.exception = darwin_sections[darwin_exception_section];
+  casm->sec.eh_frame = darwin_sections[darwin_eh_frame_section];
 
   /* If our linker is new enough to coalesce weak symbols, then we
      can just put picbase_thunks into the text section.  */
   if (! ld_uses_coal_sects )
-    darwin_sections[picbase_thunk_section] = text_section;
+    darwin_sections[picbase_thunk_section] = casm->sec.text;
 }
 
 int
@@ -1072,7 +1072,7 @@ machopic_output_data_section_indirection (machopic_indirection **slot,
   /* The name of the indirection symbol.  */
   const char *ptr_name = p->ptr_name;
 
-  switch_to_section (data_section);
+  switch_to_section (casm->sec.data);
   assemble_align (GET_MODE_ALIGNMENT (Pmode));
   assemble_label (out_file, ptr_name);
   assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
@@ -1341,7 +1341,7 @@ darwin_mergeable_string_section (tree exp,
       && TREE_STRING_LENGTH (exp) == 0)
     return darwin_sections[zobj_const_section];
 
-  return readonly_data_section;
+  return casm->sec.readonly_data;
 }
 
 #ifndef HAVE_GAS_LITERAL16
@@ -1363,7 +1363,7 @@ darwin_mergeable_constant_section (tree exp,
       || align < 8
       || align > 256
       || (align & (align -1)) != 0)
-    return readonly_data_section;
+    return casm->sec.readonly_data;
 
   /* This will ICE if the mode is not a constant size, but that is reasonable,
      since one cannot put a variable-sized thing into a constant section, we
@@ -1371,12 +1371,12 @@ darwin_mergeable_constant_section (tree exp,
   const unsigned int modesize = GET_MODE_BITSIZE (mode).to_constant ();
 
   if (modesize > align)
-    return readonly_data_section;
+    return casm->sec.readonly_data;
 
   tree size = TYPE_SIZE_UNIT (TREE_TYPE (exp));
 
   if (TREE_CODE (size) != INTEGER_CST)
-    return readonly_data_section;
+    return casm->sec.readonly_data;
 
   unsigned isize = TREE_INT_CST_LOW (size);
   if (isize == 4)
@@ -1388,7 +1388,7 @@ darwin_mergeable_constant_section (tree exp,
 	   && isize == 16)
     return darwin_sections[literal16_section];
 
-  return readonly_data_section;
+  return casm->sec.readonly_data;
 }
 
 section *
@@ -1444,7 +1444,7 @@ darwin_objc2_section (tree decl ATTRIBUTE_UNUSED, tree meta, section * base)
 
   objc_metadata_seen = 1;
 
-  if (base == data_section)
+  if (base == casm->sec.data)
     base = darwin_sections[objc2_metadata_section];
 
   /* Most of the OBJC2 META-data end up in the base section, so check it
@@ -1495,7 +1495,7 @@ darwin_objc2_section (tree decl ATTRIBUTE_UNUSED, tree meta, section * base)
 
   else if (startswith (p, "V2_EHTY"))
     return ld_uses_coal_sects ? darwin_sections[data_coal_section]
-                              : data_section;
+                              : casm->sec.data;
 
   else if (startswith (p, "V2_CSTR"))
     return darwin_sections[objc2_constant_string_object_section];
@@ -1681,7 +1681,7 @@ machopic_select_section (tree decl,
       else if (ro)
 	base_section = darwin_sections[const_data_section];
       else
-	base_section = data_section;
+	base_section = casm->sec.data;
       break;
     case SECCAT_BSS:
     case SECCAT_SBSS:
@@ -1691,11 +1691,11 @@ machopic_select_section (tree decl,
       else
 	{
 	  if (!TREE_PUBLIC (decl))
-	    base_section = lcomm_section;
-	  else if (bss_noswitch_section)
-	    base_section = bss_noswitch_section;
+	    base_section = casm->sec.lcomm;
+	  else if (casm->sec.bss_noswitch)
+	    base_section = casm->sec.bss_noswitch;
 	  else
-	    base_section = data_section;
+	    base_section = casm->sec.data;
 	}
       break;
 
@@ -2366,8 +2366,8 @@ fprintf (file, "# dadon: %s %s (%llu, %u) local %d weak %d"
       /* Check that we've correctly picked up the zero-sized item and placed it
          properly.  */
       gcc_assert ((!DARWIN_SECTION_ANCHORS || !flag_section_anchors)
-		  || (in_section
-		      && (in_section->common.flags & SECTION_NO_ANCHOR)));
+		  || (casm->in_section
+		      && (casm->in_section->common.flags & SECTION_NO_ANCHOR)));
     }
   else
     ASM_OUTPUT_LABEL (file, xname);
@@ -2387,8 +2387,8 @@ darwin_asm_declare_constant_name (FILE *file, const char *name,
       /* Check that we've correctly picked up the zero-sized item and placed it
          properly.  */
       gcc_assert ((!DARWIN_SECTION_ANCHORS || !flag_section_anchors)
-		  || (in_section
-		      && (in_section->common.flags & SECTION_NO_ANCHOR)));
+		  || (casm->in_section
+		      && (casm->in_section->common.flags & SECTION_NO_ANCHOR)));
     }
 }
 
@@ -2425,7 +2425,7 @@ darwin_emit_weak_or_comdat (FILE *fp, tree decl, const char *name,
 				: darwin_sections[const_data_section]);
   else
     switch_to_section (use_coal ? darwin_sections[data_coal_section]
-				: data_section);
+				: casm->sec.data);
 
   /* To be consistent, we'll allow darwin_asm_declare_object_name to assemble
      the align info for zero-sized items... but do it here otherwise.  */
@@ -2447,7 +2447,7 @@ darwin_emit_objc_zeroed (FILE *fp, tree decl, const char *name,
 				  unsigned HOST_WIDE_INT size,
 				  unsigned int align, tree meta)
 {
-  section *ocs = data_section;
+  section *ocs = casm->sec.data;
 
   if (TREE_PURPOSE (meta) == get_identifier("OBJC2META"))
     ocs = darwin_objc2_section (decl, meta, ocs);
@@ -2489,13 +2489,13 @@ darwin_emit_local_bss (FILE *fp, tree decl, const char *name,
       if (!size)
 	{
 	  fputs ("\t.section\t__DATA,__zobj_bss\n", fp);
-	  in_section = darwin_sections[zobj_bss_section];
+	  casm->in_section = darwin_sections[zobj_bss_section];
 	  size = 1;
 	}
       else
 	{
 	  fputs ("\t.static_data\n", fp);
-	  in_section = darwin_sections[static_data_section];
+	  casm->in_section = darwin_sections[static_data_section];
 	}
 
       if (l2align)
@@ -2513,7 +2513,7 @@ darwin_emit_local_bss (FILE *fp, tree decl, const char *name,
       char secnam[64];
       snprintf (secnam, 64, "__DATA,__bss");
       unsigned int flags = SECTION_BSS|SECTION_WRITE|SECTION_NO_ANCHOR;
-      in_section = get_section (secnam, flags, NULL);
+      casm->in_section = get_section (secnam, flags, NULL);
       fprintf (fp, "\t.zerofill %s,", secnam);
       assemble_name (fp, name);
       if (!size)
@@ -2560,7 +2560,7 @@ darwin_emit_common (FILE *fp, const char *name,
   l2align = floor_log2 (align);
   gcc_assert (l2align <= L2_MAX_OFILE_ALIGNMENT);
 
-  in_section = comm_section;
+  casm->in_section = casm->sec.comm;
   /* We mustn't allow multiple public symbols to share an address when using
      the normal OSX toolchain.  */
   if (!size)
@@ -2568,7 +2568,7 @@ darwin_emit_common (FILE *fp, const char *name,
       /* Put at least one byte.  */
       size = 1;
       /* This section can no longer participate in section anchoring.  */
-      comm_section->common.flags |= SECTION_NO_ANCHOR;
+      casm->sec.comm->common.flags |= SECTION_NO_ANCHOR;
     }
 
   fputs ("\t.comm\t", fp);
@@ -2657,13 +2657,13 @@ fprintf (fp, "# albss: %s (%lld,%d) ro %d cst %d stat %d com %d"
       if (!size)
 	{
 	  fputs ("\t.section\t__DATA,__zobj_data\n", fp);
-	  in_section = darwin_sections[zobj_data_section];
+	  casm->in_section = darwin_sections[zobj_data_section];
 	  size = 1;
 	}
       else
 	{
 	  fputs ("\t.data\n", fp);
-	  in_section = data_section;
+	  casm->in_section = casm->sec.data;
 	}
 
       if (l2align)
@@ -2678,7 +2678,7 @@ fprintf (fp, "# albss: %s (%lld,%d) ro %d cst %d stat %d com %d"
       unsigned int flags = SECTION_BSS|SECTION_WRITE|SECTION_NO_ANCHOR;
       char secnam[64];
       snprintf (secnam, 64, "__DATA,__common");
-      in_section = get_section (secnam, flags, NULL);
+      casm->in_section = get_section (secnam, flags, NULL);
       fprintf (fp, "\t.zerofill %s,", secnam);
       assemble_name (fp, name);
       if (!size)
@@ -3894,7 +3894,7 @@ darwin_function_section (tree decl, enum node_frequency freq,
   /* Otherwise, default to the 'normal' non-reordered sections.  */
 default_function_sections:
   return (use_coal) ? darwin_sections[text_coal_section]
-		    : text_section;
+		    : casm->sec.text;
 }
 
 #include "gt-darwin.h"
diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c
index 02cd07c09bc..af459c0e5b4 100644
--- a/gcc/config/frv/frv.c
+++ b/gcc/config/frv/frv.c
@@ -9396,7 +9396,7 @@ frv_rtx_costs (rtx x,
 static void
 frv_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
 {
-  switch_to_section (ctors_section);
+  switch_to_section (casm->sec.ctors);
   assemble_align (POINTER_SIZE);
   if (TARGET_FDPIC)
     {
@@ -9411,7 +9411,7 @@ frv_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
 static void
 frv_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
 {
-  switch_to_section (dtors_section);
+  switch_to_section (casm->sec.dtors);
   assemble_align (POINTER_SIZE);
   if (TARGET_FDPIC)
     {
diff --git a/gcc/config/frv/frv.h b/gcc/config/frv/frv.h
index 65091952ebd..6fd072c25d8 100644
--- a/gcc/config/frv/frv.h
+++ b/gcc/config/frv/frv.h
@@ -1540,7 +1540,7 @@ do {                                                                   	\
   if ((SIZE) > 0 && (SIZE) <= (unsigned HOST_WIDE_INT) g_switch_value)	\
     switch_to_section (get_named_section (NULL, ".sbss", 0));           \
   else                                                                 	\
-    switch_to_section (bss_section);                                  	\
+    switch_to_section (casm->sec.bss);                                  	\
   ASM_OUTPUT_ALIGN (STREAM, floor_log2 ((ALIGN) / BITS_PER_UNIT));     	\
   ASM_DECLARE_OBJECT_NAME (STREAM, NAME, DECL);                        	\
   ASM_OUTPUT_SKIP (STREAM, (SIZE) ? (SIZE) : 1);                       	\
diff --git a/gcc/config/ft32/ft32.h b/gcc/config/ft32/ft32.h
index f8d0763e394..8e2b0667b64 100644
--- a/gcc/config/ft32/ft32.h
+++ b/gcc/config/ft32/ft32.h
@@ -478,9 +478,9 @@ extern int ft32_is_mem_pm(rtx o);
 #define ASM_OUTPUT_SYMBOL_REF(stream, sym) \
   do { \
     assemble_name (stream, XSTR (sym, 0)); \
-    int section_debug = in_section && \
-      (SECTION_STYLE (in_section) == SECTION_NAMED) && \
-      (in_section->named.common.flags & SECTION_DEBUG); \
+    int section_debug = casm->in_section && \
+      (SECTION_STYLE (casm->in_section) == SECTION_NAMED) && \
+      (casm->in_section->named.common.flags & SECTION_DEBUG); \
     if (!section_debug && SYMBOL_REF_FLAGS (sym) & 0x1000) \
       asm_fprintf (stream, "-0x800000"); \
   } while (0)
diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h
index da872d10cd3..2826d2c35c6 100644
--- a/gcc/config/i386/cygming.h
+++ b/gcc/config/i386/cygming.h
@@ -187,7 +187,7 @@ along with GCC; see the file COPYING3.  If not see
 \f
 #define drectve_section() \
   (fprintf (asm_out_file, "\t.section .drectve\n"), \
-   in_section = NULL)
+   casm->in_section = NULL)
 
 /* Older versions of gas don't handle 'r' as data.
    Explicitly set data flag with 'd'.  */  
diff --git a/gcc/config/i386/darwin.h b/gcc/config/i386/darwin.h
index 741f29aa962..82addaa6e8d 100644
--- a/gcc/config/i386/darwin.h
+++ b/gcc/config/i386/darwin.h
@@ -217,7 +217,7 @@ along with GCC; see the file COPYING3.  If not see
   do {								   \
     if ((LOG) != 0)						   \
       {								   \
-	if (in_section == text_section)				   \
+	if (casm->in_section == casm->sec.text)				   \
 	  fprintf (FILE, "\t%s %d,0x90\n", ALIGN_ASM_OP, (LOG));   \
 	else							   \
 	  fprintf (FILE, "\t%s %d\n", ALIGN_ASM_OP, (LOG));	   \
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index e3988f82b56..2ab4c70d9d0 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -869,7 +869,7 @@ x86_output_aligned_bss (FILE *file, tree decl, const char *name,
       && size > (unsigned int)ix86_section_threshold)
     switch_to_section (get_named_section (decl, ".lbss", 0));
   else
-    switch_to_section (bss_section);
+    switch_to_section (casm->sec.bss);
   ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
 #ifdef ASM_DECLARE_OBJECT_NAME
   last_assemble_variable_decl = decl;
@@ -5959,7 +5959,7 @@ output_indirect_thunk_function (enum indirect_thunk_prefix need_prefix,
       }
     else
       {
-	switch_to_section (text_section);
+	switch_to_section (casm->sec.text);
 	ASM_OUTPUT_LABEL (asm_out_file, name);
       }
 
@@ -6079,7 +6079,7 @@ ix86_code_end (void)
 	}
       else
 	{
-	  switch_to_section (text_section);
+	  switch_to_section (casm->sec.text);
 	  ASM_OUTPUT_LABEL (asm_out_file, name);
 	}
 
diff --git a/gcc/config/i386/sol2.h b/gcc/config/i386/sol2.h
index 29b37a143f5..7297db2bb70 100644
--- a/gcc/config/i386/sol2.h
+++ b/gcc/config/i386/sol2.h
@@ -195,9 +195,9 @@ along with GCC; see the file COPYING3.  If not see
   do									\
     {									\
       if (TARGET_SUN_TLS						\
-	  && in_section							\
-	  && ((in_section->common.flags & SECTION_TLS) == SECTION_TLS))	\
-	switch_to_section (bss_section);				\
+	  && casm->in_section							\
+	  && ((casm->in_section->common.flags & SECTION_TLS) == SECTION_TLS))	\
+	switch_to_section (casm->sec.bss);				\
       x86_elf_aligned_decl_common (FILE, DECL, NAME, SIZE, ALIGN);	\
     }									\
   while  (0)
diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c
index 7c0ea4f731c..a25412ddf30 100644
--- a/gcc/config/i386/winnt.c
+++ b/gcc/config/i386/winnt.c
@@ -1347,7 +1347,7 @@ void
 i386_pe_seh_init_sections (void)
 {
   if (TARGET_SEH)
-    exception_section = get_unnamed_section (0, output_section_asm_op,
+    casm->sec.exception = get_unnamed_section (0, output_section_asm_op,
 					     "\t.seh_handlerdata");
 }
 \f
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index 96c0efb4afd..0d8166be256 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -10406,7 +10406,7 @@ ia64_asm_emit_except_personality (rtx personality)
 static void
 ia64_asm_init_sections (void)
 {
-  exception_section = get_unnamed_section (0, output_section_asm_op,
+  casm->sec.exception = get_unnamed_section (0, output_section_asm_op,
 					   "\t.handlerdata");
 }
 
@@ -10858,7 +10858,7 @@ ia64_select_rtx_section (machine_mode mode, rtx x,
   if (GET_MODE_SIZE (mode) > 0
       && GET_MODE_SIZE (mode) <= ia64_section_threshold
       && !TARGET_NO_SDATA)
-    return sdata_section;
+    return casm->sec.sdata;
   else
     return default_elf_select_rtx_section (mode, x, align);
 }
diff --git a/gcc/config/ia64/sysv4.h b/gcc/config/ia64/sysv4.h
index a4133d3beab..a68f28074fb 100644
--- a/gcc/config/ia64/sysv4.h
+++ b/gcc/config/ia64/sysv4.h
@@ -69,9 +69,9 @@ extern int size_directive_output;
 #define ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN) \
 do {									\
   if ((DECL) && sdata_symbolic_operand (XEXP (DECL_RTL (DECL), 0), Pmode)) \
-    switch_to_section (sbss_section);					\
+    switch_to_section (casm->sec.sbss);					\
   else									\
-    switch_to_section (bss_section);					\
+    switch_to_section (casm->sec.bss);					\
   ASM_OUTPUT_ALIGN (FILE, floor_log2 ((ALIGN) / BITS_PER_UNIT));	\
   ASM_DECLARE_OBJECT_NAME (FILE, NAME, DECL);				\
   ASM_OUTPUT_SKIP (FILE, SIZE ? SIZE : 1);				\
diff --git a/gcc/config/lm32/lm32.h b/gcc/config/lm32/lm32.h
index a13c0c50ee1..d665c38f0e3 100644
--- a/gcc/config/lm32/lm32.h
+++ b/gcc/config/lm32/lm32.h
@@ -385,9 +385,9 @@ enum reg_class
 #define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)		\
 do {									\
   if ((SIZE) <= (unsigned HOST_WIDE_INT) g_switch_value)		\
-    switch_to_section (sbss_section);					\
+    switch_to_section (casm->sec.sbss);					\
   else									\
-    switch_to_section (bss_section);					\
+    switch_to_section (casm->sec.bss);					\
   ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
   if (!flag_inhibit_size_directive)					\
     ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);			\
@@ -403,7 +403,7 @@ do 									\
 {									\
   if ((SIZE) <= (unsigned HOST_WIDE_INT) g_switch_value)		\
     {									\
-      switch_to_section (sbss_section);					\
+      switch_to_section (casm->sec.sbss);					\
       (*targetm.asm_out.globalize_label) (FILE, NAME);			\
       ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
       if (!flag_inhibit_size_directive)					\
@@ -414,7 +414,7 @@ do 									\
     }									\
   else									\
     {									\
-      switch_to_section (bss_section);					\
+      switch_to_section (casm->sec.bss);					\
       fprintf ((FILE), "%s", COMMON_ASM_OP);				\
       assemble_name ((FILE), (NAME));					\
       fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED",%u\n",          \
diff --git a/gcc/config/m32r/m32r.h b/gcc/config/m32r/m32r.h
index 047805fd808..64b5f69f3a7 100644
--- a/gcc/config/m32r/m32r.h
+++ b/gcc/config/m32r/m32r.h
@@ -897,7 +897,7 @@ L2:     .word STATIC
 	  && (SIZE) <= (unsigned HOST_WIDE_INT) g_switch_value)		\
         switch_to_section (get_named_section (NULL, ".sbss", 0));	\
       else								\
-        switch_to_section (bss_section);				\
+        switch_to_section (casm->sec.bss);				\
       ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT));	\
       last_assemble_variable_decl = DECL;				\
       ASM_DECLARE_OBJECT_NAME (FILE, NAME, DECL);			\
diff --git a/gcc/config/mcore/mcore-elf.h b/gcc/config/mcore/mcore-elf.h
index d50f578c3dd..02278eec3c3 100644
--- a/gcc/config/mcore/mcore-elf.h
+++ b/gcc/config/mcore/mcore-elf.h
@@ -33,7 +33,7 @@ along with GCC; see the file COPYING3.  If not see
       fprintf (STREAM, "\t.section .exports\n");	\
       fprintf (STREAM, "\t.ascii \" -export:%s\"\n",	\
 	       (* targetm.strip_name_encoding) (NAME));	\
-      in_section = NULL;				\
+      casm->in_section = NULL;				\
     }							\
   while (0)
 
@@ -63,7 +63,7 @@ along with GCC; see the file COPYING3.  If not see
       HOST_WIDE_INT size;					\
       if (mcore_dllexport_name_p (NAME))			\
         {							\
-	  section *save_section = in_section;			\
+	  section *save_section = casm->in_section;			\
 	  MCORE_EXPORT_NAME (FILE, NAME);			\
 	  switch_to_section (save_section);			\
         }							\
diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c
index 4813f7a7921..1e148c0b30a 100644
--- a/gcc/config/microblaze/microblaze.c
+++ b/gcc/config/microblaze/microblaze.c
@@ -2837,9 +2837,9 @@ microblaze_elf_asm_cdtor (rtx symbol, int priority, bool is_ctor)
       s = get_section (buf, SECTION_WRITE, NULL_TREE);
     }
   else if (is_ctor)
-    s = ctors_section;
+    s = casm->sec.ctors;
   else
-    s = dtors_section;
+    s = casm->sec.dtors;
 
   switch_to_section (s);
   assemble_align (POINTER_SIZE);
@@ -3262,7 +3262,7 @@ microblaze_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
          relaxation/relocation. Currently, turning mergeable sections 
          into regular readonly sections.  */
 
-      return readonly_data_section;
+      return casm->sec.readonly_data;
     default:
       return default_elf_select_section (decl, reloc, align);
     }
diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h
index 2ecec750526..3f1368d0884 100644
--- a/gcc/config/microblaze/microblaze.h
+++ b/gcc/config/microblaze/microblaze.h
@@ -623,11 +623,11 @@ do {									\
       && (int) (SIZE) <= microblaze_section_threshold			\
       && TARGET_XLGPOPT)						\
     {                                                                   \
-      switch_to_section (sbss_section);					\
+      switch_to_section (casm->sec.sbss);					\
     }									\
   else									\
     {									\
-      switch_to_section (bss_section);					\
+      switch_to_section (casm->sec.bss);					\
     }                                                                   \
   fprintf (FILE, "%s", COMMON_ASM_OP);                                  \
   assemble_name ((FILE), (NAME));					\
@@ -643,11 +643,11 @@ do {									\
       && (int) (SIZE) <= microblaze_section_threshold			\
       && TARGET_XLGPOPT)						\
     {                                                                   \
-      switch_to_section (sbss_section);					\
+      switch_to_section (casm->sec.sbss);					\
     }									\
   else									\
     {									\
-      switch_to_section (bss_section);					\
+      switch_to_section (casm->sec.bss);					\
     }                                                                   \
   fprintf (FILE, "%s", LCOMMON_ASM_OP);                                 \
   assemble_name ((FILE), (NAME));					\
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 807bf1a78d4..f119bcfbe87 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -9719,7 +9719,7 @@ mips_output_aligned_decl_common (FILE *stream, tree decl, const char *name,
       if (TREE_PUBLIC (decl) && DECL_NAME (decl))
 	targetm.asm_out.globalize_label (stream, name);
 
-      switch_to_section (readonly_data_section);
+      switch_to_section (casm->sec.readonly_data);
       ASM_OUTPUT_ALIGN (stream, floor_log2 (align / BITS_PER_UNIT));
       mips_declare_object (stream, name, "",
 			   ":\n\t.space\t" HOST_WIDE_INT_PRINT_UNSIGNED "\n",
diff --git a/gcc/config/mmix/mmix.c b/gcc/config/mmix/mmix.c
index 010cd4773ea..4ea07819983 100644
--- a/gcc/config/mmix/mmix.c
+++ b/gcc/config/mmix/mmix.c
@@ -1321,7 +1321,7 @@ mmix_file_start (void)
   fputs ("! mmixal:= 8H LOC Data_Section\n", asm_out_file);
 
   /* Make sure each file starts with the text section.  */
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
 }
 
 /* TARGET_ASM_FILE_END.  */
@@ -1330,7 +1330,7 @@ static void
 mmix_file_end (void)
 {
   /* Make sure each file ends with the data section.  */
-  switch_to_section (data_section);
+  switch_to_section (casm->sec.data);
 }
 
 /* TARGET_ASM_OUTPUT_SOURCE_FILENAME.  */
@@ -1510,7 +1510,7 @@ mmix_asm_output_aligned_local (FILE *stream,
 			       int size,
 			       int align)
 {
-  switch_to_section (data_section);
+  switch_to_section (casm->sec.data);
 
   ASM_OUTPUT_ALIGN (stream, exact_log2 (align/BITS_PER_UNIT));
   assemble_name (stream, name);
diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c
index 1cdacb7f480..ba41ce1f54a 100644
--- a/gcc/config/msp430/msp430.c
+++ b/gcc/config/msp430/msp430.c
@@ -2398,22 +2398,22 @@ msp430_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
     {
     case SECCAT_TEXT:
       if (!prefix)
-	return text_section;
+	return casm->sec.text;
       base_sec_name = ".text";
       break;
     case SECCAT_DATA:
       if (!prefix)
-	return data_section;
+	return casm->sec.data;
       base_sec_name = ".data";
       break;
     case SECCAT_BSS:
       if (!prefix)
-	return bss_section;
+	return casm->sec.bss;
       base_sec_name = ".bss";
       break;
     case SECCAT_RODATA:
       if (!prefix)
-	return readonly_data_section;
+	return casm->sec.readonly_data;
       base_sec_name = ".rodata";
       break;
 
diff --git a/gcc/config/nios2/nios2.h b/gcc/config/nios2/nios2.h
index dfca12cc525..c2da347062b 100644
--- a/gcc/config/nios2/nios2.h
+++ b/gcc/config/nios2/nios2.h
@@ -470,9 +470,9 @@ while (0)
 #define ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN)	\
 do {                                                                    \
  if (targetm.in_small_data_p (DECL))					\
-    switch_to_section (sbss_section);					\
+    switch_to_section (casm->sec.sbss);					\
   else                                                                  \
-    switch_to_section (bss_section);					\
+    switch_to_section (casm->sec.bss);					\
   ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");                     \
   if (!flag_inhibit_size_directive)                                     \
     ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);                       \
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index d13021ad94a..472ff6e5bc4 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -4454,7 +4454,7 @@ pa_output_function_epilogue (FILE *file)
       /* We are done with this subspace except possibly for some additional
 	 debug information.  Forget that we are in this subspace to ensure
 	 that the next function is output in its own subspace.  */
-      in_section = NULL;
+      casm->in_section = NULL;
       cfun->machine->in_nsubspa = 2;
     }
 
@@ -4703,7 +4703,7 @@ output_deferred_profile_counters (void)
   if (funcdef_nos.is_empty ())
    return;
 
-  switch_to_section (data_section);
+  switch_to_section (casm->sec.data);
   align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE);
   ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
 
@@ -5873,7 +5873,7 @@ output_deferred_plabels (void)
      before outputting the deferred plabels.  */
   if (n_deferred_plabels)
     {
-      switch_to_section (flag_pic ? data_section : readonly_data_section);
+      switch_to_section (flag_pic ? casm->sec.data : casm->sec.readonly_data);
       ASM_OUTPUT_ALIGN (asm_out_file, TARGET_64BIT ? 3 : 2);
     }
 
@@ -8882,7 +8882,7 @@ pa_asm_output_mi_thunk (FILE *file, tree thunk_fndecl, HOST_WIDE_INT delta,
 
   if (TARGET_SOM && flag_pic && TREE_PUBLIC (function))
     {
-      switch_to_section (data_section);
+      switch_to_section (casm->sec.data);
       output_asm_insn (".align 4", xoperands);
       ASM_OUTPUT_LABEL (file, label);
       output_asm_insn (".word P'%0", xoperands);
@@ -9057,7 +9057,7 @@ pa_asm_output_aligned_bss (FILE *stream,
 			   unsigned HOST_WIDE_INT size,
 			   unsigned int align)
 {
-  switch_to_section (bss_section);
+  switch_to_section (casm->sec.bss);
 
 #ifdef ASM_OUTPUT_TYPE_DIRECTIVE
   ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "object");
@@ -9094,7 +9094,7 @@ pa_asm_output_aligned_common (FILE *stream,
       align = max_common_align;
     }
 
-  switch_to_section (bss_section);
+  switch_to_section (casm->sec.bss);
 
   assemble_name (stream, name);
   fprintf (stream, "\t.comm " HOST_WIDE_INT_PRINT_UNSIGNED"\n",
@@ -9114,7 +9114,7 @@ pa_asm_output_aligned_local (FILE *stream,
 			     unsigned HOST_WIDE_INT size,
 			     unsigned int align)
 {
-  switch_to_section (bss_section);
+  switch_to_section (casm->sec.bss);
   fprintf (stream, "\t.align %u\n", align / BITS_PER_UNIT);
 
 #ifdef LOCAL_ASM_OP
@@ -10040,10 +10040,10 @@ som_output_text_section_asm_op (const void *data ATTRIBUTE_UNUSED)
 	     function has been completed.  So, we are changing to the
 	     text section to output debugging information.  Thus, we
 	     need to forget that we are in the text section so that
-	     varasm.c will call us when text_section is selected again.  */
+	     varasm.c will call us when casm->sec.text is selected again.  */
 	  gcc_assert (!cfun || !cfun->machine
 		      || cfun->machine->in_nsubspa == 2);
-	  in_section = NULL;
+	  casm->in_section = NULL;
 	}
       output_section_asm_op ("\t.SPACE $TEXT$\n\t.NSUBSPA $CODE$");
       return;
@@ -10057,7 +10057,7 @@ som_output_text_section_asm_op (const void *data ATTRIBUTE_UNUSED)
 static void
 som_output_comdat_data_section_asm_op (const void *data)
 {
-  in_section = NULL;
+  casm->in_section = NULL;
   output_section_asm_op (data);
 }
 
@@ -10066,7 +10066,7 @@ som_output_comdat_data_section_asm_op (const void *data)
 static void
 pa_som_asm_init_sections (void)
 {
-  text_section
+  casm->sec.text
     = get_unnamed_section (0, som_output_text_section_asm_op, NULL);
 
   /* SOM puts readonly data in the default $LIT$ subspace when PIC code
@@ -10114,14 +10114,14 @@ pa_som_asm_init_sections (void)
      when generating PIC code.  This reduces sharing, but it works
      correctly.  Now we rely on pa_reloc_rw_mask() for section selection.
      This puts constant data not needing relocation into the $TEXT$ space.  */
-  readonly_data_section = som_readonly_data_section;
+  casm->sec.readonly_data = som_readonly_data_section;
 
   /* We must not have a reference to an external symbol defined in a
      shared library in a readonly section, else the SOM linker will
      complain.
 
      So, we force exception information into the data section.  */
-  exception_section = data_section;
+  casm->sec.exception = casm->sec.data;
 }
 
 /* Implement TARGET_ASM_TM_CLONE_TABLE_SECTION.  */
@@ -10154,18 +10154,18 @@ pa_select_section (tree exp, int reloc,
 	  && !DECL_WEAK (exp))
 	return som_one_only_readonly_data_section;
       else
-	return readonly_data_section;
+	return casm->sec.readonly_data;
     }
   else if (CONSTANT_CLASS_P (exp)
 	   && !(reloc & pa_reloc_rw_mask ()))
-    return readonly_data_section;
+    return casm->sec.readonly_data;
   else if (TARGET_SOM
 	   && TREE_CODE (exp) == VAR_DECL
 	   && DECL_ONE_ONLY (exp)
 	   && !DECL_WEAK (exp))
     return som_one_only_data_section;
   else
-    return data_section;
+    return casm->sec.data;
 }
 
 /* Implement pa_elf_select_rtx_section.  If X is a function label operand
@@ -10658,7 +10658,7 @@ pa_function_section (tree decl, enum node_frequency freq,
 {
   /* Put functions in text section if target doesn't have named sections.  */
   if (!targetm_common.have_named_sections)
-    return text_section;
+    return casm->sec.text;
 
   /* Force nested functions into the same section as the containing
      function.  */
diff --git a/gcc/config/pdp11/pdp11.c b/gcc/config/pdp11/pdp11.c
index ced653116a4..11b123c0586 100644
--- a/gcc/config/pdp11/pdp11.c
+++ b/gcc/config/pdp11/pdp11.c
@@ -743,7 +743,7 @@ void
 pdp11_asm_output_var (FILE *file, const char *name, int size,
 		      int align, bool global)
 {
-  switch_to_section (data_section);
+  switch_to_section (casm->sec.data);
   if (align > 8)
     fprintf (file, "\t.even\n");
   if (TARGET_DEC_ASM)
@@ -2323,11 +2323,11 @@ pdp11_asm_init_sections (void)
 {
   if (TARGET_DEC_ASM)
     {
-      bss_section = data_section;
+      casm->sec.bss = casm->sec.data;
     }
   else if (TARGET_GNU_ASM)
     {
-      bss_section = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
+      casm->sec.bss = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
 					 output_section_asm_op,
 					 ".bss");
     }
diff --git a/gcc/config/pru/pru.h b/gcc/config/pru/pru.h
index 03f08b1720f..a9c73dc5149 100644
--- a/gcc/config/pru/pru.h
+++ b/gcc/config/pru/pru.h
@@ -547,7 +547,7 @@ while (0)
 #undef  ASM_OUTPUT_ALIGNED_LOCAL
 #define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)		\
 do {									\
-  switch_to_section (bss_section);					\
+  switch_to_section (casm->sec.bss);					\
   ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
   if (!flag_inhibit_size_directive)					\
     ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);			\
diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
index 126572c6243..90bcb6de3cd 100644
--- a/gcc/config/riscv/riscv.c
+++ b/gcc/config/riscv/riscv.c
@@ -3616,8 +3616,8 @@ riscv_elf_select_rtx_section (machine_mode mode, rtx x,
 	  return get_section (name, s->named.common.flags, NULL);
 	}
 
-      if (s == data_section)
-	return sdata_section;
+      if (s == casm->sec.data)
+	return casm->sec.sdata;
     }
 
   return s;
diff --git a/gcc/config/rl78/rl78.c b/gcc/config/rl78/rl78.c
index 4c34949a97f..0129929c821 100644
--- a/gcc/config/rl78/rl78.c
+++ b/gcc/config/rl78/rl78.c
@@ -4644,14 +4644,14 @@ rl78_select_section (tree decl,
     }
 
   if (readonly)
-    return TARGET_ES0 ? frodata_section : readonly_data_section;
+    return TARGET_ES0 ? frodata_section : casm->sec.readonly_data;
 
   switch (categorize_decl_for_section (decl, reloc))
     {
-    case SECCAT_TEXT:   return text_section;
-    case SECCAT_DATA:   return data_section;
-    case SECCAT_BSS:    return bss_section;
-    case SECCAT_RODATA: return TARGET_ES0 ? frodata_section : readonly_data_section;
+    case SECCAT_TEXT:   return casm->sec.text;
+    case SECCAT_DATA:   return casm->sec.data;
+    case SECCAT_BSS:    return casm->sec.bss;
+    case SECCAT_RODATA: return TARGET_ES0 ? frodata_section : casm->sec.readonly_data;
     default:
       return default_select_section (decl, reloc, align);
     }
@@ -4786,7 +4786,7 @@ rl78_asm_ctor_dtor (rtx symbol, int priority, bool is_ctor)
       sec = get_section (buf, 0, NULL);
     }
   else
-    sec = is_ctor ? ctors_section : dtors_section;
+    sec = is_ctor ? casm->sec.ctors : casm->sec.dtors;
 
   assemble_addr_to_section (symbol, sec);
 }
diff --git a/gcc/config/rs6000/rs6000-internal.h b/gcc/config/rs6000/rs6000-internal.h
index 88cf9bd5692..5d28b80dd77 100644
--- a/gcc/config/rs6000/rs6000-internal.h
+++ b/gcc/config/rs6000/rs6000-internal.h
@@ -189,4 +189,31 @@ extern bool rs6000_passes_vector;
 extern bool rs6000_returns_struct;
 extern bool cpu_builtin_p;
 
+struct rs6000_asm_out_state : public asm_out_state
+{
+  /* Initialize ELF sections. */
+  void init_elf_sections ();
+
+  /* Initialize XCOFF sections. */
+  void init_xcoff_sections ();
+
+  struct
+  {
+    /* ELF sections.  */
+    section *toc;
+    section *sdata2;
+
+    /* XCOFF sections.  */
+    section *read_only_data;
+    section *private_data;
+    section *tls_data;
+    section *tls_private_data;
+    section *read_only_private_data;
+  } target_sec;
+};
+
+extern GTY(()) rs6000_asm_out_state *target_casm;
+
+#define rs6000_casm static_cast<rs6000_asm_out_state *> (casm)
+
 #endif
diff --git a/gcc/config/rs6000/rs6000-logue.c b/gcc/config/rs6000/rs6000-logue.c
index 9965a8aa691..7a078817fe3 100644
--- a/gcc/config/rs6000/rs6000-logue.c
+++ b/gcc/config/rs6000/rs6000-logue.c
@@ -5506,7 +5506,7 @@ rs6000_output_function_epilogue (FILE *file)
       need_toc_init = 0;
       if (!toc_initialized)
 	{
-	  switch_to_section (toc_section);
+	  switch_to_section (rs6000_casm->target_sec.toc);
 	  switch_to_section (current_function_section ());
 	}
     }
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index bac959f4ef4..0faf9d1388f 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -182,14 +182,6 @@ char toc_label_name[10];
    rs6000_variable_issue hook and returned from rs6000_sched_reorder2.  */
 static short cached_can_issue_more;
 
-static GTY(()) section *read_only_data_section;
-static GTY(()) section *private_data_section;
-static GTY(()) section *tls_data_section;
-static GTY(()) section *tls_private_data_section;
-static GTY(()) section *read_only_private_data_section;
-static GTY(()) section *sdata2_section;
-
-section *toc_section = 0;
 
 /* Describe the vector unit used for modes.  */
 enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
@@ -14747,7 +14739,7 @@ rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
 	 section.  */
       if (DEFAULT_ABI == ABI_V4
 	  && (TARGET_RELOCATABLE || flag_pic > 1)
-	  && in_section != toc_section
+	  && casm->in_section != rs6000_casm->target_sec.toc
 	  && !recurse
 	  && !CONST_SCALAR_INT_P (x)
 	  && CONSTANT_P (x))
@@ -20684,19 +20676,35 @@ rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
     }
 }
 
-/* Implement TARGET_ASM_INIT_SECTIONS.  */
+/* Target CASM state used for GGC memory.  */
+rs6000_asm_out_state *target_casm;
 
-static void
-rs6000_elf_asm_init_sections (void)
+/* Initialize ELF sections. */
+
+void
+rs6000_asm_out_state::init_elf_sections ()
 {
-  toc_section
+  target_sec.toc
     = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
 
-  sdata2_section
+ target_sec.sdata2
     = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
 			   SDATA2_SECTION_ASM_OP);
 }
 
+/* Implement TARGET_ASM_INIT_SECTIONS.  */
+
+static asm_out_state *
+rs6000_elf_asm_init_sections (void)
+{
+  rs6000_asm_out_state *target_state
+    = new (ggc_alloc<rs6000_asm_out_state> ()) rs6000_asm_out_state ();
+  target_state->init_elf_sections ();
+  target_state->init_sections ();
+
+  return target_state;
+}
+
 /* Implement TARGET_SELECT_RTX_SECTION.  */
 
 static section *
@@ -20704,7 +20712,7 @@ rs6000_elf_select_rtx_section (machine_mode mode, rtx x,
 			       unsigned HOST_WIDE_INT align)
 {
   if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
-    return toc_section;
+    return rs6000_casm->target_sec.toc;
   else
     return default_elf_select_rtx_section (mode, x, align);
 }
@@ -21296,7 +21304,7 @@ rs6000_elf_file_end (void)
       /* We have expanded a CPU builtin, so we need to emit a reference to
 	 the special symbol that LIBC uses to declare it supports the
 	 AT_PLATFORM and AT_HWCAP/AT_HWCAP2 in the TCB feature.  */
-      switch_to_section (data_section);
+      switch_to_section (casm->sec.data);
       fprintf (asm_out_file, "\t.align %u\n", TARGET_32BIT ? 2 : 3);
       fprintf (asm_out_file, "\t%s %s\n",
 	       TARGET_32BIT ? ".long" : ".quad", tcb_verification_symbol);
@@ -21390,38 +21398,51 @@ rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
     fputs ("\t.toc\n", asm_out_file);
 }
 
-/* Implement TARGET_ASM_INIT_SECTIONS.  */
+/* Initialize XCOFF sections. */
 
-static void
-rs6000_xcoff_asm_init_sections (void)
+void
+rs6000_asm_out_state::init_xcoff_sections ()
 {
-  read_only_data_section
+  target_sec.read_only_data
     = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
 			   &xcoff_read_only_section_name);
 
-  private_data_section
+  target_sec.private_data
     = get_unnamed_section (SECTION_WRITE,
 			   rs6000_xcoff_output_readwrite_section_asm_op,
 			   &xcoff_private_data_section_name);
 
-  read_only_private_data_section
+  target_sec.read_only_private_data
     = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
 			   &xcoff_private_rodata_section_name);
 
-  tls_data_section
+  target_sec.tls_data
     = get_unnamed_section (SECTION_TLS,
 			   rs6000_xcoff_output_tls_section_asm_op,
 			   &xcoff_tls_data_section_name);
 
-  tls_private_data_section
+  target_sec.tls_private_data
     = get_unnamed_section (SECTION_TLS,
 			   rs6000_xcoff_output_tls_section_asm_op,
 			   &xcoff_private_data_section_name);
 
-  toc_section
+  target_sec.toc
     = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
 
-  readonly_data_section = read_only_data_section;
+  sec.readonly_data = target_sec.read_only_data;
+}
+
+/* Implement TARGET_ASM_INIT_SECTIONS.  */
+
+static asm_out_state *
+rs6000_xcoff_asm_init_sections (void)
+{
+  rs6000_asm_out_state *target_state
+    = new (ggc_alloc<rs6000_asm_out_state> ()) rs6000_asm_out_state ();
+  target_state->init_xcoff_sections ();
+  target_state->init_sections ();
+
+  return target_state;
 }
 
 static int
@@ -21489,9 +21510,9 @@ rs6000_xcoff_select_section (tree decl, int reloc,
   if (decl_readonly_section (decl, reloc))
     {
       if (TREE_PUBLIC (decl))
-	return read_only_data_section;
+	return rs6000_casm->target_sec.read_only_data;
       else
-	return read_only_private_data_section;
+	return rs6000_casm->target_sec.read_only_private_data;
     }
   else
     {
@@ -21499,7 +21520,7 @@ rs6000_xcoff_select_section (tree decl, int reloc,
       if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL_P (decl))
 	{
 	  if (bss_initializer_p (decl))
-	    return tls_comm_section;
+	    return casm->sec.tls_comm;
 	  else if (TREE_PUBLIC (decl))
 	    return tls_data_section;
 	  else
@@ -21508,9 +21529,9 @@ rs6000_xcoff_select_section (tree decl, int reloc,
       else
 #endif
 	if (TREE_PUBLIC (decl))
-	return data_section;
+	return casm->sec.data;
       else
-	return private_data_section;
+	return rs6000_casm->target_sec.private_data;
     }
 }
 
@@ -21535,9 +21556,9 @@ rs6000_xcoff_select_rtx_section (machine_mode mode, rtx x,
 				 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
 {
   if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
-    return toc_section;
+    return rs6000_casm->target_sec.toc;
   else
-    return read_only_private_data_section;
+    return rs6000_casm->target_sec.read_only_private_data;
 }
 
 /* Remove any trailing [DS] or the like from the symbol name.  */
@@ -21611,9 +21632,9 @@ rs6000_xcoff_file_start (void)
   output_quoted_string (asm_out_file, main_input_filename);
   fputc ('\n', asm_out_file);
   if (write_symbols != NO_DEBUG)
-    switch_to_section (private_data_section);
-  switch_to_section (toc_section);
-  switch_to_section (text_section);
+    switch_to_section (rs6000_casm->target_sec.private_data);
+  switch_to_section (rs6000_casm->target_sec.toc);
+  switch_to_section (casm->sec.text);
   if (profile_flag)
     fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
   rs6000_file_start ();
@@ -21625,14 +21646,14 @@ rs6000_xcoff_file_start (void)
 static void
 rs6000_xcoff_file_end (void)
 {
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
   if (xcoff_tls_exec_model_detected)
     {
       /* Add a .ref to __tls_get_addr to force libpthread dependency.  */
       fputs ("\t.extern __tls_get_addr\n\t.ref __tls_get_addr\n", asm_out_file);
     }
   fputs ("_section_.text:\n", asm_out_file);
-  switch_to_section (data_section);
+  switch_to_section (casm->sec.data);
   fputs (TARGET_32BIT
 	 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
 	 asm_out_file);
@@ -21747,7 +21768,7 @@ rs6000_xcoff_visibility (tree decl)
    Dollar signs are converted to underscores.
 
    The csect for the function will have already been created when
-   text_section was selected.  We do have to go back to that csect, however.
+   casm->sec.text was selected.  We do have to go back to that csect, however.
 
    The third and fourth parameters to the .function pseudo-op (16 and 044)
    are placeholders which no longer have any use.
@@ -21809,7 +21830,7 @@ rs6000_xcoff_declare_function_name (FILE *file, const char *name, tree decl)
   RS6000_OUTPUT_BASENAME (file, buffer);
   fputs (", TOC[tc0], 0\n", file);
 
-  in_section = NULL;
+  casm->in_section = NULL;
   switch_to_section (function_section (decl));
   putc ('.', file);
   ASM_OUTPUT_LABEL (file, buffer);
@@ -21869,7 +21890,7 @@ rs6000_xcoff_asm_output_aligned_decl_common (FILE *stream,
   if (! DECL_COMMON (decl))
     {
       /* Forget section.  */
-      in_section = NULL;
+      casm->in_section = NULL;
 
       /* Globalize TLS BSS.  */
       if (TREE_PUBLIC (decl) && DECL_THREAD_LOCAL_P (decl))
@@ -26866,7 +26887,7 @@ rs6000_code_end (void)
   else
 #endif
     {
-      switch_to_section (text_section);
+      switch_to_section (casm->sec.text);
       ASM_OUTPUT_LABEL (asm_out_file, name);
     }
 
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 3eba1c072cf..ee49446c72c 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -2606,7 +2606,6 @@ extern GTY(()) tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
 #ifndef USED_FOR_TARGET
 extern GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
 extern GTY(()) tree altivec_builtin_mask_for_load;
-extern GTY(()) section *toc_section;
 
 /* A C structure for machine-specific, per-function data.
    This is added to the cfun structure.  */
diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
index 96ee5524224..00af78c964f 100644
--- a/gcc/config/rs6000/sysv4.h
+++ b/gcc/config/rs6000/sysv4.h
@@ -427,7 +427,7 @@ do {									\
 do {									\
   if ((DECL) && rs6000_elf_in_small_data_p (DECL))			\
     {									\
-      switch_to_section (sbss_section);					\
+      switch_to_section (casm->sec.sbss);					\
       ASM_OUTPUT_ALIGN (FILE, exact_log2 (ALIGN / BITS_PER_UNIT));	\
       ASM_OUTPUT_LABEL (FILE, NAME);					\
       ASM_OUTPUT_SKIP (FILE, SIZE);					\
diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c
index af54ccc2588..c45aface21d 100644
--- a/gcc/config/rx/rx.c
+++ b/gcc/config/rx/rx.c
@@ -2305,7 +2305,7 @@ rx_select_rtx_section (machine_mode mode,
   if (rx_small_data_limit > 0
       && GET_MODE_SIZE (mode) <= rx_small_data_limit
       && align <= (unsigned HOST_WIDE_INT) rx_small_data_limit * BITS_PER_UNIT)
-    return sdata_section;
+    return casm->sec.sdata;
 
   return default_elf_select_rtx_section (mode, x, align);
 }
@@ -2319,8 +2319,8 @@ rx_select_section (tree decl,
     {
       switch (categorize_decl_for_section (decl, reloc))
 	{
-	case SECCAT_SDATA:	return sdata_section;
-	case SECCAT_SBSS:	return sbss_section;
+	case SECCAT_SDATA:	return casm->sec.sdata;
+	case SECCAT_SBSS:	return casm->sec.sbss;
 	case SECCAT_SRODATA:
 	  /* Fall through.  We do not put small, read only
 	     data into the C_2 section because we are not
@@ -2342,7 +2342,7 @@ rx_select_section (tree decl,
       case SECCAT_RODATA_MERGE_CONST:
       case SECCAT_RODATA_MERGE_STR_INIT:
       case SECCAT_RODATA_MERGE_STR:
-	return readonly_data_section;
+	return casm->sec.readonly_data;
 
       default:
 	break;
@@ -2690,9 +2690,9 @@ rx_elf_asm_cdtor (rtx symbol, int priority, bool is_ctor)
       s = get_section (buf, SECTION_WRITE, NULL_TREE);
     }
   else if (is_ctor)
-    s = ctors_section;
+    s = casm->sec.ctors;
   else
-    s = dtors_section;
+    s = casm->sec.dtors;
 
   switch_to_section (s);
   assemble_align (POINTER_SIZE);
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index b2f2f6417b3..367d58c28d0 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -16691,7 +16691,7 @@ s390_output_indirect_thunk_function (unsigned int regno, bool z10_p)
     }
   else
     {
-      switch_to_section (text_section);
+      switch_to_section (casm->sec.text);
       ASM_OUTPUT_LABEL (asm_out_file, thunk_label);
     }
 
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 0628f059ca2..5bce20ef2e4 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -2828,7 +2828,7 @@ sh_file_start (void)
   else
     /* Switch to the data section so that the coffsem symbol
        isn't in the text section.  */
-    switch_to_section (data_section);
+    switch_to_section (casm->sec.data);
 
   if (TARGET_LITTLE_ENDIAN)
     fputs ("\t.little\n", asm_out_file);
diff --git a/gcc/config/sparc/sol2.h b/gcc/config/sparc/sol2.h
index 1b4aa28bd21..1dd33daa447 100644
--- a/gcc/config/sparc/sol2.h
+++ b/gcc/config/sparc/sol2.h
@@ -399,9 +399,9 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
   do									\
     {									\
       if (TARGET_SUN_TLS						\
-	  && in_section							\
-	  && ((in_section->common.flags & SECTION_TLS) == SECTION_TLS))	\
-	switch_to_section (bss_section);				\
+	  && casm->in_section							\
+	  && ((casm->in_section->common.flags & SECTION_TLS) == SECTION_TLS))	\
+	switch_to_section (casm->sec.bss);				\
       fprintf ((FILE), "%s", COMMON_ASM_OP);				\
       assemble_name ((FILE), (NAME));					\
       fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED",%u\n",		\
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index ca91be4c8e9..c48fda6cca2 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -12638,7 +12638,7 @@ sparc_file_end (void)
       else
 	{
 	  const int align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
-          switch_to_section (text_section);
+          switch_to_section (casm->sec.text);
 	  if (align > 0)
 	    ASM_OUTPUT_ALIGN (asm_out_file, align);
 	  ASM_OUTPUT_LABEL (asm_out_file, name);
diff --git a/gcc/config/tilegx/tilegx.h b/gcc/config/tilegx/tilegx.h
index b0dcccfa3aa..931d900002b 100644
--- a/gcc/config/tilegx/tilegx.h
+++ b/gcc/config/tilegx/tilegx.h
@@ -290,7 +290,7 @@ enum reg_class
 
 #define TRAMPOLINE_SIZE (TARGET_32BIT ? 48 : 56)
 #define TRAMPOLINE_ALIGNMENT 64
-#define TRAMPOLINE_SECTION text_section
+#define TRAMPOLINE_SECTION casm->sec.text
 \f
 
 /* Call frame debugging information.  */
diff --git a/gcc/config/tilepro/tilepro.h b/gcc/config/tilepro/tilepro.h
index 1986f80084c..3f9720c582a 100644
--- a/gcc/config/tilepro/tilepro.h
+++ b/gcc/config/tilepro/tilepro.h
@@ -253,7 +253,7 @@ enum reg_class
 
 #define TRAMPOLINE_SIZE 48
 #define TRAMPOLINE_ALIGNMENT 64
-#define TRAMPOLINE_SECTION text_section
+#define TRAMPOLINE_SECTION casm->sec.text
 \f
 
 /* Call frame debugging information.  */
diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c
index 4978faf9318..9dafa3d1a76 100644
--- a/gcc/config/v850/v850.c
+++ b/gcc/config/v850/v850.c
@@ -2398,7 +2398,7 @@ v850_output_aligned_bss (FILE * file,
       break;
 
     case DATA_AREA_SDA:
-      switch_to_section (sbss_section);
+      switch_to_section (casm->sec.sbss);
       break;
 
     case DATA_AREA_TDA:
@@ -2406,7 +2406,7 @@ v850_output_aligned_bss (FILE * file,
       break;
       
     default:
-      switch_to_section (bss_section);
+      switch_to_section (casm->sec.bss);
       break;
     }
   
@@ -2882,13 +2882,13 @@ v850_select_section (tree exp,
 	  return tdata_section;
 
         case DATA_AREA_SDA:
-	  return is_const ? rosdata_section : sdata_section;
+	  return is_const ? rosdata_section : casm->sec.sdata;
 
         default:
-	  return is_const ? readonly_data_section : data_section;
+	  return is_const ? casm->sec.readonly_data : casm->sec.data;
         }
     }
-  return readonly_data_section;
+  return casm->sec.readonly_data;
 }
 \f
 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P.  */
diff --git a/gcc/config/visium/visium.h b/gcc/config/visium/visium.h
index 66e3decd0cc..dbe65766d09 100644
--- a/gcc/config/visium/visium.h
+++ b/gcc/config/visium/visium.h
@@ -1235,8 +1235,8 @@ do									\
    `EXTRA_SECTION_FUNCTIONS'
 
    One or more functions to be defined in `varasm.c'.  These functions
-   should do jobs analogous to those of `text_section' and
-   `data_section', for your additional sections.  Do not define this
+   should do jobs analogous to those of `casm->sec.text' and
+   `casm->sec.data', for your additional sections.  Do not define this
    macro if you do not define `EXTRA_SECTIONS'.
 
    `JUMP_TABLES_IN_TEXT_SECTION' Define this macro if jump tables (for
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index b4f530d57ac..181764e8eaa 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -99,6 +99,7 @@ typedef const union tree_node *const_tree;
 struct gimple;
 typedef gimple *gimple_seq;
 struct gimple_stmt_iterator;
+struct asm_out_state;
 
 /* Forward decls for leaf gimple subclasses (for individual gimple codes).
    Keep this in the same order as the corresponding codes in gimple.def.  */
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index 6be282714cf..d8c91d07ca7 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -934,7 +934,7 @@ dbxout_function_end (tree decl ATTRIBUTE_UNUSED)
   if (crtl->has_bb_partition)
     {
       dbxout_begin_empty_stabs (N_FUN);
-      if (in_cold_section_p)
+      if (casm->in_cold_section_p)
 	dbxout_stab_value_label_diff (crtl->subsections.cold_section_end_label,
 				      crtl->subsections.cold_section_label);
       else
@@ -1042,7 +1042,7 @@ dbxout_init (const char *input_file_name)
 
   if (used_ltext_label_name)
     {
-      switch_to_section (text_section);
+      switch_to_section (casm->sec.text);
       targetm.asm_out.internal_label (asm_out_file, "Ltext", 0);
     }
 
@@ -1244,7 +1244,7 @@ dbxout_source_file (const char *filename)
     {
       /* Don't change section amid function.  */
       if (current_function_decl == NULL_TREE)
-	switch_to_section (text_section);
+	switch_to_section (casm->sec.text);
 
       dbxout_begin_simple_stabs (remap_debug_filename (filename), N_SOL);
       dbxout_stab_value_internal_label ("Ltext", &source_label_number);
@@ -1314,12 +1314,12 @@ dbxout_switch_text_section (void)
   /* The N_FUN tag at the end of the function is a GNU extension,
      which may be undesirable, and is unnecessary if we do not have
      named sections.  */
-  in_cold_section_p = !in_cold_section_p;
+  casm->in_cold_section_p = !casm->in_cold_section_p;
   switch_to_section (current_function_section ());
   dbxout_block (DECL_INITIAL (current_function_decl), 0,
 		DECL_ARGUMENTS (current_function_decl), -1);
   dbxout_function_end (current_function_decl);
-  in_cold_section_p = !in_cold_section_p;
+  casm->in_cold_section_p = !casm->in_cold_section_p;
 
   switch_to_section (current_function_section ());
 
@@ -1432,7 +1432,7 @@ dbxout_finish (const char *filename ATTRIBUTE_UNUSED)
   DBX_OUTPUT_MAIN_SOURCE_FILE_END (asm_out_file, filename);
 #elif defined DBX_OUTPUT_NULL_N_SO_AT_MAIN_SOURCE_FILE_END
  {
-   switch_to_section (text_section);
+   switch_to_section (casm->sec.text);
    dbxout_begin_empty_stabs (N_SO);
    dbxout_stab_value_internal_label ("Letext", 0);
  }
@@ -3114,7 +3114,7 @@ dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home)
 	    {
 	      /* Ultrix `as' seems to need this.  */
 #ifdef DBX_STATIC_STAB_DATA_SECTION
-	      switch_to_section (data_section);
+	      switch_to_section (casm->sec.data);
 #endif
 	      code = N_STSYM;
 	    }
@@ -3776,7 +3776,7 @@ dbxout_block (tree block, int depth, tree args, int parent_blocknum)
 
   /* If called for the second partition, ignore blocks that don't have
      any children in the second partition.  */
-  if (crtl->has_bb_partition && in_cold_section_p && depth == 0)
+  if (crtl->has_bb_partition && casm->in_cold_section_p && depth == 0)
     dbx_block_with_cold_children (block);
 
   for (; block; block = BLOCK_CHAIN (block))
@@ -3801,7 +3801,7 @@ dbxout_block (tree block, int depth, tree args, int parent_blocknum)
 	     the assembler symbols LBBn and LBEn
 	     that final will define around the code in this block.  */
 	  if (did_output
-	      && BLOCK_IN_COLD_SECTION_P (block) == in_cold_section_p)
+	      && BLOCK_IN_COLD_SECTION_P (block) == casm->in_cold_section_p)
 	    {
 	      char buf[20];
 	      const char *scope_start;
@@ -3829,7 +3829,7 @@ dbxout_block (tree block, int depth, tree args, int parent_blocknum)
 
 	  /* Refer to the marker for the end of the block.  */
 	  if (did_output
-	      && BLOCK_IN_COLD_SECTION_P (block) == in_cold_section_p)
+	      && BLOCK_IN_COLD_SECTION_P (block) == casm->in_cold_section_p)
 	    {
 	      char buf[100];
 	      if (depth == 0)
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 990152f5b15..af90c6b6a86 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -5525,7 +5525,7 @@ to generate it on the spot.
 
 @defmac TRAMPOLINE_SECTION
 Return the section into which the trampoline template is to be placed
-(@pxref{Sections}).  The default value is @code{readonly_data_section}.
+(@pxref{Sections}).  The default value is @code{casm->sec.readonly_data}.
 @end defmac
 
 @defmac TRAMPOLINE_SIZE
@@ -7593,7 +7593,7 @@ section}, which holds uninitialized data.  Some systems have other kinds
 of sections.
 
 @file{varasm.c} provides several well-known sections, such as
-@code{text_section}, @code{data_section} and @code{bss_section}.
+@code{casm->sec.text}, @code{casm->sec.data} and @code{casm->sec.bss}.
 The normal way of controlling a @code{@var{foo}_section} variable
 is to define the associated @code{@var{FOO}_SECTION_ASM_OP} macro,
 as described below.  The macros are only read once, when @file{varasm.c}
@@ -7609,12 +7609,12 @@ section is selected.  If your assembler falls into this category, you
 should define the @code{TARGET_ASM_INIT_SECTIONS} hook and use
 @code{get_unnamed_section} to set up the sections.
 
-You must always create a @code{text_section}, either by defining
-@code{TEXT_SECTION_ASM_OP} or by initializing @code{text_section}
+You must always create a @code{casm->sec.text}, either by defining
+@code{TEXT_SECTION_ASM_OP} or by initializing @code{casm->sec.text}
 in @code{TARGET_ASM_INIT_SECTIONS}.  The same is true of
-@code{data_section} and @code{DATA_SECTION_ASM_OP}.  If you do not
-create a distinct @code{readonly_data_section}, the default is to
-reuse @code{text_section}.
+@code{casm->sec.data} and @code{DATA_SECTION_ASM_OP}.  If you do not
+create a distinct @code{casm->sec.readonly_data}, the default is to
+reuse @code{casm->sec.text}.
 
 All the other @file{varasm.c} sections are optional, and are null
 if the target does not provide them.
@@ -7761,7 +7761,7 @@ readonly data section is used.
 This macro is irrelevant if there is no separate readonly data section.
 @end defmac
 
-@deftypefn {Target Hook} void TARGET_ASM_INIT_SECTIONS (void)
+@deftypefn {Target Hook} {asm_out_state *} TARGET_ASM_INIT_SECTIONS (void)
 Define this hook if you need to do something special to set up the
 @file{varasm.c} sections, or if your target has some special sections
 of its own that you need to create.
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 193c9bdd853..2ef3977839c 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -3854,7 +3854,7 @@ separately.
 
 @defmac TRAMPOLINE_SECTION
 Return the section into which the trampoline template is to be placed
-(@pxref{Sections}).  The default value is @code{readonly_data_section}.
+(@pxref{Sections}).  The default value is @code{casm->sec.readonly_data}.
 @end defmac
 
 @defmac TRAMPOLINE_SIZE
@@ -4752,7 +4752,7 @@ section}, which holds uninitialized data.  Some systems have other kinds
 of sections.
 
 @file{varasm.c} provides several well-known sections, such as
-@code{text_section}, @code{data_section} and @code{bss_section}.
+@code{casm->sec.text}, @code{casm->sec.data} and @code{casm->sec.bss}.
 The normal way of controlling a @code{@var{foo}_section} variable
 is to define the associated @code{@var{FOO}_SECTION_ASM_OP} macro,
 as described below.  The macros are only read once, when @file{varasm.c}
@@ -4768,12 +4768,12 @@ section is selected.  If your assembler falls into this category, you
 should define the @code{TARGET_ASM_INIT_SECTIONS} hook and use
 @code{get_unnamed_section} to set up the sections.
 
-You must always create a @code{text_section}, either by defining
-@code{TEXT_SECTION_ASM_OP} or by initializing @code{text_section}
+You must always create a @code{casm->sec.text}, either by defining
+@code{TEXT_SECTION_ASM_OP} or by initializing @code{casm->sec.text}
 in @code{TARGET_ASM_INIT_SECTIONS}.  The same is true of
-@code{data_section} and @code{DATA_SECTION_ASM_OP}.  If you do not
-create a distinct @code{readonly_data_section}, the default is to
-reuse @code{text_section}.
+@code{casm->sec.data} and @code{DATA_SECTION_ASM_OP}.  If you do not
+create a distinct @code{casm->sec.readonly_data}, the default is to
+reuse @code{casm->sec.text}.
 
 All the other @file{varasm.c} sections are optional, and are null
 if the target does not provide them.
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 20f2c5da023..fd0c5366437 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -438,14 +438,14 @@ should_emit_struct_debug (tree type, enum debug_info_usage usage)
   return DUMP_GSTRUCT (type, usage, criterion, generic, false, false);
 }
 \f
-/* Switch [BACK] to eh_frame_section.  If we don't have an eh_frame_section,
+/* Switch [BACK] to casm->sec.eh_frame.  If we don't have an casm->sec.eh_frame,
    switch to the data section instead, and write out a synthetic start label
    for collect2 the first time around.  */
 
 static void
 switch_to_eh_frame_section (bool back ATTRIBUTE_UNUSED)
 {
-  if (eh_frame_section == 0)
+  if (casm->sec.eh_frame == 0)
     {
       int flags;
 
@@ -474,14 +474,14 @@ switch_to_eh_frame_section (bool back ATTRIBUTE_UNUSED)
 	flags = SECTION_WRITE;
 
 #ifdef EH_FRAME_SECTION_NAME
-      eh_frame_section = get_section (EH_FRAME_SECTION_NAME, flags, NULL);
+      casm->sec.eh_frame = get_section (EH_FRAME_SECTION_NAME, flags, NULL);
 #else
-      eh_frame_section = ((flags == SECTION_WRITE)
-			  ? data_section : readonly_data_section);
+      casm->sec.eh_frame = ((flags == SECTION_WRITE)
+			  ? casm->sec.data : casm->sec.readonly_data);
 #endif /* EH_FRAME_SECTION_NAME */
     }
 
-  switch_to_section (eh_frame_section);
+  switch_to_section (casm->sec.eh_frame);
 
 #ifdef EH_FRAME_THROUGH_COLLECT2
   /* We have no special eh_frame section.  Emit special labels to guide
@@ -1113,10 +1113,10 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
   /* Initialize the bits of CURRENT_FDE that were not available earlier.  */
   fde->dw_fde_begin = dup_label;
   fde->dw_fde_current_label = dup_label;
-  fde->in_std_section = (fnsec == text_section
+  fde->in_std_section = (fnsec == casm->sec.text
 			 || (cold_text_section && fnsec == cold_text_section));
   fde->ignored_debug = DECL_IGNORED_P (current_function_decl);
-  in_text_section_p = fnsec == text_section;
+  in_text_section_p = fnsec == casm->sec.text;
 
   /* We only want to output line number information for the genuine dwarf2
      prologue case, not the eh frame case.  */
@@ -1295,7 +1295,7 @@ dwarf2out_switch_text_section (void)
 			       current_function_funcdef_no);
 
   fde->dw_fde_second_begin = ggc_strdup (label);
-  if (!in_cold_section_p)
+  if (!casm->in_cold_section_p)
     {
       fde->dw_fde_end = crtl->subsections.cold_section_end_label;
       fde->dw_fde_second_end = crtl->subsections.hot_section_end_label;
@@ -1317,9 +1317,9 @@ dwarf2out_switch_text_section (void)
   switch_to_section (sect);
 
   fde->second_in_std_section
-    = (sect == text_section
+    = (sect == casm->sec.text
        || (cold_text_section && sect == cold_text_section));
-  in_text_section_p = sect == text_section;
+  in_text_section_p = sect == casm->sec.text;
 
   if (dwarf2out_do_cfi_asm ())
     dwarf2out_do_cfi_startproc (true);
@@ -17270,7 +17270,7 @@ secname_for_decl (const_tree decl)
     secname = DECL_SECTION_NAME (decl);
   else if (current_function_decl && DECL_SECTION_NAME (current_function_decl))
     {
-      if (in_cold_section_p)
+      if (casm->in_cold_section_p)
 	{
 	  section *sec = current_function_section ();
 	  if (sec->common.flags & SECTION_NAMED)
@@ -17278,7 +17278,7 @@ secname_for_decl (const_tree decl)
 	}
       secname = DECL_SECTION_NAME (current_function_decl);
     }
-  else if (cfun && in_cold_section_p)
+  else if (cfun && casm->in_cold_section_p)
     secname = crtl->subsections.cold_section_label;
   else
     secname = text_section_label;
@@ -17599,12 +17599,12 @@ dw_loc_list (var_loc_list *loc_list, tree decl, int want_address)
 
   if (cfun && crtl->has_bb_partition)
     {
-      bool save_in_cold_section_p = in_cold_section_p;
-      in_cold_section_p = first_function_block_is_cold;
+      bool save_in_cold_section_p = casm->in_cold_section_p;
+      casm->in_cold_section_p = first_function_block_is_cold;
       if (loc_list->last_before_switch == NULL)
-	in_cold_section_p = !in_cold_section_p;
+	casm->in_cold_section_p = !casm->in_cold_section_p;
       secname = secname_for_decl (decl);
-      in_cold_section_p = save_in_cold_section_p;
+      casm->in_cold_section_p = save_in_cold_section_p;
     }
   else
     secname = secname_for_decl (decl);
@@ -17682,10 +17682,10 @@ dw_loc_list (var_loc_list *loc_list, tree decl, int want_address)
 	  && crtl->has_bb_partition
 	  && node == loc_list->last_before_switch)
 	{
-	  bool save_in_cold_section_p = in_cold_section_p;
-	  in_cold_section_p = !first_function_block_is_cold;
+	  bool save_in_cold_section_p = casm->in_cold_section_p;
+	  casm->in_cold_section_p = !first_function_block_is_cold;
 	  secname = secname_for_decl (decl);
-	  in_cold_section_p = save_in_cold_section_p;
+	  casm->in_cold_section_p = save_in_cold_section_p;
 	}
 
       if (range_across_switch)
@@ -27853,7 +27853,7 @@ create_label:
      last_{,postcall_}label so that they are not reused this time.  */
   if (last_var_location_insn == NULL_RTX
       || last_var_location_insn != next_real
-      || last_in_cold_section_p != in_cold_section_p)
+      || last_in_cold_section_p != casm->in_cold_section_p)
     {
       last_label = NULL;
       last_postcall_label = NULL;
@@ -28024,7 +28024,7 @@ create_label:
     }
 
   last_var_location_insn = next_real;
-  last_in_cold_section_p = in_cold_section_p;
+  last_in_cold_section_p = casm->in_cold_section_p;
 }
 
 /* Check whether BLOCK, a lexical block, is nested within OUTER, or is
@@ -28192,7 +28192,7 @@ set_cur_line_info_table (section *sec)
 {
   dw_line_info_table *table;
 
-  if (sec == text_section)
+  if (sec == casm->sec.text)
     table = text_section_line_info;
   else if (sec == cold_text_section)
     {
@@ -28209,7 +28209,7 @@ set_cur_line_info_table (section *sec)
 
       if (crtl->has_bb_partition)
 	{
-	  if (in_cold_section_p)
+	  if (casm->in_cold_section_p)
 	    end_label = crtl->subsections.cold_section_end_label;
 	  else
 	    end_label = crtl->subsections.hot_section_end_label;
@@ -28246,7 +28246,7 @@ dwarf2out_begin_function (tree fun)
 {
   section *sec = function_section (fun);
 
-  if (sec != text_section)
+  if (sec != casm->sec.text)
     have_multiple_function_sections = true;
 
   if (crtl->has_bb_partition && !cold_text_section)
@@ -29375,7 +29375,7 @@ dwarf2out_assembly_start (void)
 			       COLD_TEXT_SECTION_LABEL, 0);
   ASM_GENERATE_INTERNAL_LABEL (cold_end_label, COLD_END_LABEL, 0);
 
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
   ASM_OUTPUT_LABEL (asm_out_file, text_section_label);
 #endif
 
@@ -32082,7 +32082,7 @@ dwarf2out_finish (const char *filename)
     main_comp_unit_die = comp_unit_die ();
 
   /* Output a terminator label for the .text section.  */
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
   targetm.asm_out.internal_label (asm_out_file, TEXT_END_LABEL, 0);
   if (cold_text_section)
     {
@@ -32998,7 +32998,7 @@ dwarf2out_early_finish (const char *filename)
     }
 
   /* Switch back to the text section.  */
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
 }
 
 /* Reset all state within dwarf2out.c so that we can rerun the compiler
diff --git a/gcc/dwarf2out.h b/gcc/dwarf2out.h
index 312a9909784..6491b44da95 100644
--- a/gcc/dwarf2out.h
+++ b/gcc/dwarf2out.h
@@ -103,9 +103,9 @@ struct GTY(()) dw_fde_node {
   unsigned stack_realign : 1;
   /* Whether dynamic realign argument pointer register has been saved.  */
   unsigned drap_reg_saved: 1;
-  /* True iff dw_fde_begin label is in text_section or cold_text_section.  */
+  /* True iff dw_fde_begin label is in casm->sec.text or cold_text_section.  */
   unsigned in_std_section : 1;
-  /* True iff dw_fde_second_begin label is in text_section or
+  /* True iff dw_fde_second_begin label is in casm->sec.text or
      cold_text_section.  */
   unsigned second_in_std_section : 1;
   /* True if Rule 18 described in dwarf2cfi.c is in action, i.e. for dynamic
diff --git a/gcc/except.c b/gcc/except.c
index 8e905a30939..ce38a57ed2f 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -2906,8 +2906,8 @@ switch_to_exception_section (const char * ARG_UNUSED (fnname))
 {
   section *s;
 
-  if (exception_section)
-    s = exception_section;
+  if (casm->sec.exception)
+    s = casm->sec.exception;
   else
     {
       int flags;
@@ -2924,7 +2924,7 @@ switch_to_exception_section (const char * ARG_UNUSED (fnname))
       else
 	flags = SECTION_WRITE;
 
-      /* Compute the section and cache it into exception_section,
+      /* Compute the section and cache it into casm->sec.exception,
 	 unless it depends on the function name.  */
       if (targetm_common.have_named_sections)
 	{
@@ -2943,12 +2943,12 @@ switch_to_exception_section (const char * ARG_UNUSED (fnname))
 	    }
 	  else
 #endif
-	    exception_section
+	    casm->sec.exception
 	      = s = get_section (".gcc_except_table", flags, NULL);
 	}
       else
-	exception_section
-	  = s = flags == SECTION_WRITE ? data_section : readonly_data_section;
+	casm->sec.exception
+	  = s = flags == SECTION_WRITE ? casm->sec.data: casm->sec.readonly_data;
     }
 
   switch_to_section (s);
diff --git a/gcc/final.c b/gcc/final.c
index ac6892d041c..03c8533e92b 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -885,7 +885,7 @@ shorten_branches (rtx_insn *first)
 	  /* ADDR_VECs only take room if read-only data goes into the text
 	     section.  */
 	  if ((JUMP_TABLES_IN_TEXT_SECTION
-	       || readonly_data_section == text_section)
+	       || casm->sec.readonly_data == casm->sec.text)
 	      && table)
 	    {
 	      align_flags alignment = align_flags (ADDR_VEC_ALIGN (table));
@@ -1051,7 +1051,7 @@ shorten_branches (rtx_insn *first)
 	  /* This only takes room if read-only data goes into the text
 	     section.  */
 	  if (JUMP_TABLES_IN_TEXT_SECTION
-	      || readonly_data_section == text_section)
+	      || casm->sec.readonly_data == casm->sec.text)
 	    insn_lengths[uid] = (XVECLEN (body,
 					  GET_CODE (body) == ADDR_DIFF_VEC)
 				 * GET_MODE_SIZE (table->get_data_mode ()));
@@ -1143,7 +1143,7 @@ shorten_branches (rtx_insn *first)
 		 may need to update the alignment of this label.  */
 
 	      if (JUMP_TABLES_IN_TEXT_SECTION
-		  || readonly_data_section == text_section)
+		  || casm->sec.readonly_data == casm->sec.text)
 		{
 		  rtx_jump_table_data *table = jump_table_for_label (label);
 		  if (table)
@@ -1284,7 +1284,7 @@ shorten_branches (rtx_insn *first)
 		      >= GET_MODE_SIZE (table->get_data_mode ())))
 		PUT_MODE (body, vec_mode);
 	      if (JUMP_TABLES_IN_TEXT_SECTION
-		  || readonly_data_section == text_section)
+		  || casm->sec.readonly_data == casm->sec.text)
 		{
 		  insn_lengths[uid]
 		    = (XVECLEN (body, 1)
@@ -1836,7 +1836,7 @@ profile_function (FILE *file ATTRIBUTE_UNUSED)
   if (! NO_PROFILE_COUNTERS)
     {
       int align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE);
-      switch_to_section (data_section);
+      switch_to_section (casm->sec.data);
       ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
       targetm.asm_out.internal_label (file, "LP", current_function_funcdef_no);
       assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, align, 1);
@@ -2189,10 +2189,10 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
 	  if (targetm.asm_out.unwind_emit)
 	    targetm.asm_out.unwind_emit (asm_out_file, insn);
 
-	  in_cold_section_p = !in_cold_section_p;
+	  casm->in_cold_section_p = !casm->in_cold_section_p;
 
-	  gcc_checking_assert (in_cold_section_p);
-	  if (in_cold_section_p)
+	  gcc_checking_assert (casm->in_cold_section_p);
+	  if (casm->in_cold_section_p)
 	    cold_function_name
 	      = clone_function_name (current_function_decl, "cold");
 
@@ -2213,10 +2213,10 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
 	  switch_to_section (current_function_section ());
 	  targetm.asm_out.function_switched_text_sections (asm_out_file,
 							   current_function_decl,
-							   in_cold_section_p);
+							   casm->in_cold_section_p);
 	  /* Emit a label for the split cold section.  Form label name by
 	     suffixing "cold" to the original function's name.  */
-	  if (in_cold_section_p)
+	  if (casm->in_cold_section_p)
 	    {
 #ifdef ASM_DECLARE_COLD_FUNCTION_NAME
 	      ASM_DECLARE_COLD_FUNCTION_NAME (asm_out_file,
@@ -2323,7 +2323,7 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
 
 	      /* Mark this block as output.  */
 	      TREE_ASM_WRITTEN (NOTE_BLOCK (insn)) = 1;
-	      BLOCK_IN_COLD_SECTION_P (NOTE_BLOCK (insn)) = in_cold_section_p;
+	      BLOCK_IN_COLD_SECTION_P (NOTE_BLOCK (insn)) = casm->in_cold_section_p;
 	    }
 	  if (write_symbols == DBX_DEBUG)
 	    {
@@ -2358,7 +2358,7 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
 	      if (!DECL_IGNORED_P (current_function_decl))
 		debug_hooks->end_block (high_block_linenum, n);
 	      gcc_assert (BLOCK_IN_COLD_SECTION_P (NOTE_BLOCK (insn))
-			  == in_cold_section_p);
+			  == casm->in_cold_section_p);
 	    }
 	  if (write_symbols == DBX_DEBUG)
 	    {
diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c
index 32ba5be42b2..d90a8570dba 100644
--- a/gcc/ggc-common.c
+++ b/gcc/ggc-common.c
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "hosthooks.h"
 #include "plugin.h"
 #include "options.h"
+#include "output.h"
 
 /* When true, protect the contents of the identifier hash table.  */
 bool ggc_protect_identifiers = true;
@@ -589,6 +590,9 @@ gt_pch_restore (FILE *f)
   struct mmap_info mmi;
   int result;
 
+  /* Hide ASM state object as we don't want it to be streamed.  */
+  FILE *saved_casm_out_file = casm != NULL ? casm->out_file : NULL;
+
   /* Delete any deletable objects.  This makes ggc_pch_read much
      faster, as it can be sure that no GCable objects remain other
      than the ones just read in.  */
@@ -629,6 +633,9 @@ gt_pch_restore (FILE *f)
   ggc_pch_read (f, mmi.preferred_base);
 
   gt_pch_restore_stringpool ();
+
+  if (casm != NULL)
+    casm->out_file = saved_casm_out_file;
 }
 
 /* Default version of HOST_HOOKS_GT_PCH_GET_ADDRESS when mmap is not present.
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index 48c72377778..cd1ed0655e5 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -803,9 +803,9 @@ lhd_begin_section (const char *name)
 
   /* Save the old section so we can restore it in lto_end_asm_section.  */
   gcc_assert (!saved_section);
-  saved_section = in_section;
+  saved_section = casm->in_section;
   if (!saved_section)
-    saved_section = text_section;
+    saved_section = casm->sec.text;
 
   /* Create a new section and switch to it.  */
   section = get_section (name, SECTION_DEBUG | SECTION_EXCLUDE, NULL, true);
diff --git a/gcc/output.h b/gcc/output.h
index 8f6f15308f4..099abed91a1 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -313,9 +313,78 @@ extern rtx_sequence *final_sequence;
 
 /* File in which assembler code is being written.  */
 
-#ifdef BUFSIZ
-extern FILE *asm_out_file;
-#endif
+struct section_hasher : ggc_ptr_hash<section>
+{
+  typedef const char *compare_type;
+
+  static hashval_t hash (section *);
+  static bool equal (section *, const char *);
+};
+
+/* Assembly output state.  */
+
+struct GTY(()) asm_out_state
+{
+  /* Default constructor.  */
+  asm_out_state ();
+
+  /* Initialize all sections in SEC variable.  */
+  void init_sections (void);
+
+  /* Assembly output stream.  */
+  FILE * GTY((skip)) out_file;
+
+  /* Hash table of named sections.  */
+  hash_table<section_hasher> *section_htab;
+
+  /* asm_out_file's current section.  This is NULL if no section has yet
+     been selected or if we lose track of what the current section is.  */
+  section *in_section;
+
+  /* Well-known sections, each one associated with some sort of *_ASM_OP.  */
+  struct
+  {
+    section *text;
+    section *data;
+    section *readonly_data;
+    section *sdata;
+    section *ctors;
+    section *dtors;
+    section *bss;
+    section *sbss;
+
+    /* Various forms of common section.  All are guaranteed to be nonnull.  */
+    section *tls_comm;
+    section *comm;
+    section *lcomm;
+
+    /* A SECTION_NOSWITCH section used for declaring global BSS variables.
+       May be null.  */
+    section *bss_noswitch;
+
+    /* The section that holds the main exception table, when known.  The section
+       is set either by the target's init_sections hook or by the first call to
+       switch_to_exception_section.  */
+    section *exception;
+
+    /* The section that holds the DWARF2 frame unwind information, when known.
+       The section is set either by the target's init_sections hook or by the
+       first call to switch_to_eh_frame_section.  */
+    section *eh_frame;
+  } sec;
+
+  /* The next number to use for internal anchor labels.  */
+  int anchor_labelno;
+
+  /* True if code for the current function is currently being directed
+     at the cold section.  */
+  bool in_cold_section_p;
+};
+
+extern GTY(()) asm_out_state *casm;
+
+/* Helper macro for commonly used accesses.  */
+#define asm_out_file casm->out_file
 
 /* The first global object in the file.  */
 extern const char *first_global_object_name;
@@ -520,24 +589,6 @@ union GTY ((desc ("SECTION_STYLE (&(%h))"), for_user)) section {
 struct object_block;
 
 /* Special well-known sections.  */
-extern GTY(()) section *text_section;
-extern GTY(()) section *data_section;
-extern GTY(()) section *readonly_data_section;
-extern GTY(()) section *sdata_section;
-extern GTY(()) section *ctors_section;
-extern GTY(()) section *dtors_section;
-extern GTY(()) section *bss_section;
-extern GTY(()) section *sbss_section;
-extern GTY(()) section *exception_section;
-extern GTY(()) section *eh_frame_section;
-extern GTY(()) section *tls_comm_section;
-extern GTY(()) section *comm_section;
-extern GTY(()) section *lcomm_section;
-extern GTY(()) section *bss_noswitch_section;
-
-extern GTY(()) section *in_section;
-extern GTY(()) bool in_cold_section_p;
-
 extern section *get_unnamed_section (unsigned int, void (*) (const void *),
 				     const void *);
 extern section *get_section (const char *, unsigned int, tree,
@@ -567,6 +618,7 @@ extern void record_tm_clone_pair (tree, tree);
 extern void finish_tm_clone_pairs (void);
 extern tree get_tm_clone_pair (tree);
 
+extern asm_out_state *default_init_sections (void);
 extern void default_asm_output_source_filename (FILE *, const char *);
 extern void output_file_directive (FILE *, const char *);
 
diff --git a/gcc/run-rtl-passes.c b/gcc/run-rtl-passes.c
index 37a02813f22..e6976bf9070 100644
--- a/gcc/run-rtl-passes.c
+++ b/gcc/run-rtl-passes.c
@@ -46,7 +46,7 @@ run_rtl_passes (char *initial_pass_name)
   max_regno = max_reg_num ();
 
   /* cgraphunit.c normally handles this.  */
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
   (*debug_hooks->assembly_start) ();
 
   if (initial_pass_name)
diff --git a/gcc/target.def b/gcc/target.def
index 87feeec2ea1..044a1f2c48f 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -429,8 +429,8 @@ of its own that you need to create.\n\
 GCC calls this hook after processing the command line, but before writing\n\
 any assembly code, and before calling any of the section-returning hooks\n\
 described below.",
- void, (void),
- hook_void_void)
+ asm_out_state *, (void),
+ default_init_sections)
 
 /* Tell assembler to change to section NAME with attributes FLAGS.
    If DECL is non-NULL, it is the VAR_DECL or FUNCTION_DECL with
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 0b525bb4606..03102e38b33 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -1962,7 +1962,7 @@ default_print_patchable_function_entry_1 (FILE *file,
     {
       char buf[256];
       static int patch_area_number;
-      section *previous_section = in_section;
+      section *previous_section = casm->in_section;
       const char *asm_op = integer_asm_op (POINTER_SIZE_UNITS, false);
 
       gcc_assert (asm_op != NULL);
diff --git a/gcc/toplev.c b/gcc/toplev.c
index cb4f8c470f0..cb1ded54c82 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -166,7 +166,8 @@ const char *user_label_prefix;
 /* Output files for assembler code (real compiler output)
    and debugging dumps.  */
 
-FILE *asm_out_file;
+asm_out_state *casm;
+
 FILE *aux_info_file;
 FILE *callgraph_info_file = NULL;
 static bitmap callgraph_info_external_printed;
@@ -546,13 +547,13 @@ compile_file (void)
   if (flag_generate_lto && !flag_fat_lto_objects)
     {
 #if defined ASM_OUTPUT_ALIGNED_DECL_COMMON
-      ASM_OUTPUT_ALIGNED_DECL_COMMON (asm_out_file, NULL_TREE, "__gnu_lto_slim",
+      ASM_OUTPUT_ALIGNED_DECL_COMMON (casm->out_file, NULL_TREE, "__gnu_lto_slim",
 				      HOST_WIDE_INT_1U, 8);
 #elif defined ASM_OUTPUT_ALIGNED_COMMON
-      ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, "__gnu_lto_slim",
+      ASM_OUTPUT_ALIGNED_COMMON (casm->out_file, "__gnu_lto_slim",
 				 HOST_WIDE_INT_1U, 8);
 #else
-      ASM_OUTPUT_COMMON (asm_out_file, "__gnu_lto_slim",
+      ASM_OUTPUT_COMMON (casm->out_file, "__gnu_lto_slim",
 			 HOST_WIDE_INT_1U,
 			 HOST_WIDE_INT_1U);
 #endif
@@ -690,7 +691,7 @@ static void
 init_asm_output (const char *name)
 {
   if (name == NULL && asm_file_name == 0)
-    asm_out_file = stdout;
+    casm->out_file = stdout;
   else
     {
       if (asm_file_name == 0)
@@ -704,17 +705,17 @@ init_asm_output (const char *name)
 	  asm_file_name = dumpname;
 	}
       if (!strcmp (asm_file_name, "-"))
-	asm_out_file = stdout;
+	casm->out_file = stdout;
       else if (!canonical_filename_eq (asm_file_name, name)
 	       || !strcmp (asm_file_name, HOST_BIT_BUCKET))
-	asm_out_file = fopen (asm_file_name, "w");
+	casm->out_file = fopen (asm_file_name, "w");
       else
 	/* Use UNKOWN_LOCATION to prevent gcc from printing the first
 	   line in the current file. */
 	fatal_error (UNKNOWN_LOCATION,
 		     "input file %qs is the same as output file",
 		     asm_file_name);
-      if (asm_out_file == 0)
+      if (casm->out_file == 0)
 	fatal_error (UNKNOWN_LOCATION,
 		     "cannot open %qs for writing: %m", asm_file_name);
     }
@@ -741,14 +742,14 @@ init_asm_output (const char *name)
 
       if (flag_verbose_asm)
 	{
-	  print_version (asm_out_file, ASM_COMMENT_START, true);
-	  fputs (ASM_COMMENT_START, asm_out_file);
-	  fputs (" options passed: ", asm_out_file);
+	  print_version (casm->out_file, ASM_COMMENT_START, true);
+	  fputs (ASM_COMMENT_START, casm->out_file);
+	  fputs (" options passed: ", casm->out_file);
 	  char *cmdline = gen_command_line_string (save_decoded_options,
 						   save_decoded_options_count);
-	  fputs (cmdline, asm_out_file);
+	  fputs (cmdline, casm->out_file);
 	  free (cmdline);
-	  fputc ('\n', asm_out_file);
+	  fputc ('\n', casm->out_file);
 	}
     }
 }
@@ -1895,7 +1896,8 @@ lang_dependent_init (const char *name)
 
   if (!flag_wpa)
     {
-      init_asm_output (name);
+      if (!flag_syntax_only)
+	init_asm_output (name);
 
       if (!flag_generate_lto && !flag_compare_debug)
 	{
@@ -2054,13 +2056,13 @@ finalize (bool no_backend)
      whether fclose returns an error, since the pages might still be on the
      buffer chain while the file is open.  */
 
-  if (asm_out_file)
+  if (casm != NULL && casm->out_file)
     {
-      if (ferror (asm_out_file) != 0)
+      if (ferror (casm->out_file) != 0)
 	fatal_error (input_location, "error writing to %s: %m", asm_file_name);
-      if (fclose (asm_out_file) != 0)
+      if (fclose (casm->out_file) != 0)
 	fatal_error (input_location, "error closing %s: %m", asm_file_name);
-      asm_out_file = NULL;
+      casm->out_file = NULL;
     }
 
   if (stack_usage_file)
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 09316c62050..ae2d960104b 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -130,43 +130,6 @@ static void mark_weak (tree);
 static void output_constant_pool (const char *, tree);
 static void handle_vtv_comdat_section (section *, const_tree);
 \f
-/* Well-known sections, each one associated with some sort of *_ASM_OP.  */
-section *text_section;
-section *data_section;
-section *readonly_data_section;
-section *sdata_section;
-section *ctors_section;
-section *dtors_section;
-section *bss_section;
-section *sbss_section;
-
-/* Various forms of common section.  All are guaranteed to be nonnull.  */
-section *tls_comm_section;
-section *comm_section;
-section *lcomm_section;
-
-/* A SECTION_NOSWITCH section used for declaring global BSS variables.
-   May be null.  */
-section *bss_noswitch_section;
-
-/* The section that holds the main exception table, when known.  The section
-   is set either by the target's init_sections hook or by the first call to
-   switch_to_exception_section.  */
-section *exception_section;
-
-/* The section that holds the DWARF2 frame unwind information, when known.
-   The section is set either by the target's init_sections hook or by the
-   first call to switch_to_eh_frame_section.  */
-section *eh_frame_section;
-
-/* asm_out_file's current section.  This is NULL if no section has yet
-   been selected or if we lose track of what the current section is.  */
-section *in_section;
-
-/* True if code for the current function is currently being directed
-   at the cold section.  */
-bool in_cold_section_p;
-
 /* The following global holds the "function name" for the code in the
    cold section of a function, if hot/cold function splitting is enabled
    and there was actually code that went into the cold section.  A
@@ -181,17 +144,6 @@ static GTY(()) section *unnamed_sections;
 #define IN_NAMED_SECTION(DECL) \
   (VAR_OR_FUNCTION_DECL_P (DECL) && DECL_SECTION_NAME (DECL) != NULL)
 
-struct section_hasher : ggc_ptr_hash<section>
-{
-  typedef const char *compare_type;
-
-  static hashval_t hash (section *);
-  static bool equal (section *, const char *);
-};
-
-/* Hash table of named sections.  */
-static GTY(()) hash_table<section_hasher> *section_htab;
-
 struct object_block_hasher : ggc_ptr_hash<object_block>
 {
   typedef const section *compare_type;
@@ -203,9 +155,6 @@ struct object_block_hasher : ggc_ptr_hash<object_block>
 /* A table of object_blocks, indexed by section.  */
 static GTY(()) hash_table<object_block_hasher> *object_block_htab;
 
-/* The next number to use for internal anchor labels.  */
-static GTY(()) int anchor_labelno;
-
 /* A pool of constants that can be shared between functions.  */
 static GTY(()) struct rtx_constant_pool *shared_constant_pool;
 
@@ -294,8 +243,8 @@ get_section (const char *name, unsigned int flags, tree decl,
 {
   section *sect, **slot;
 
-  slot = section_htab->find_slot_with_hash (name, htab_hash_string (name),
-					    INSERT);
+  slot = casm->section_htab->find_slot_with_hash (name, htab_hash_string (name),
+						  INSERT);
   flags |= SECTION_NAMED;
   if (decl != nullptr
       && DECL_P (decl)
@@ -510,7 +459,7 @@ asm_output_aligned_bss (FILE *file, tree decl ATTRIBUTE_UNUSED,
 			const char *name, unsigned HOST_WIDE_INT size,
 			int align)
 {
-  switch_to_section (bss_section);
+  switch_to_section (casm->sec.bss);
   ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
 #ifdef ASM_DECLARE_OBJECT_NAME
   last_assemble_variable_decl = decl;
@@ -527,7 +476,7 @@ asm_output_aligned_bss (FILE *file, tree decl ATTRIBUTE_UNUSED,
 #endif /* BSS_SECTION_ASM_OP */
 
 #ifndef USE_SELECT_SECTION_FOR_FUNCTIONS
-/* Return the hot section for function DECL.  Return text_section for
+/* Return the hot section for function DECL.  Return casm->sec.text for
    null DECLs.  */
 
 static section *
@@ -538,7 +487,7 @@ hot_function_section (tree decl)
       && targetm_common.have_named_sections)
     return get_named_section (decl, NULL, 0);
   else
-    return text_section;
+    return casm->sec.text;
 }
 #endif
 
@@ -718,7 +667,7 @@ function_section (tree decl)
 section *
 current_function_section (void)
 {
-  return function_section_1 (current_function_decl, in_cold_section_p);
+  return function_section_1 (current_function_decl, casm->in_cold_section_p);
 }
 
 /* Tell assembler to switch to unlikely-to-be-executed text section.  */
@@ -746,7 +695,7 @@ unlikely_text_section_p (section *sect)
 void
 switch_to_other_text_partition (void)
 {
-  in_cold_section_p = !in_cold_section_p;
+  casm->in_cold_section_p = !casm->in_cold_section_p;
   switch_to_section (current_function_section ());
 }
 
@@ -831,7 +780,7 @@ default_function_rodata_section (tree decl, bool relocatable)
   if (relocatable)
     return get_section (sname, flags, decl);
   else
-    return readonly_data_section;
+    return casm->sec.readonly_data;
 }
 
 /* Return the read-only data section associated with function DECL
@@ -841,7 +790,7 @@ default_function_rodata_section (tree decl, bool relocatable)
 section *
 default_no_function_rodata_section (tree, bool)
 {
-  return readonly_data_section;
+  return casm->sec.readonly_data;
 }
 
 /* A subroutine of mergeable_string_section and mergeable_constant_section.  */
@@ -890,7 +839,7 @@ mergeable_string_section (tree decl ATTRIBUTE_UNUSED,
 	    align = modesize;
 
 	  if (!HAVE_LD_ALIGNED_SHF_MERGE && align > 8)
-	    return readonly_data_section;
+	    return casm->sec.readonly_data;
 
 	  str = TREE_STRING_POINTER (decl);
 	  unit = GET_MODE_SIZE (mode);
@@ -914,7 +863,7 @@ mergeable_string_section (tree decl ATTRIBUTE_UNUSED,
 	}
     }
 
-  return readonly_data_section;
+  return casm->sec.readonly_data;
 }
 
 /* Return the section to use for constant merging.  */
@@ -940,7 +889,7 @@ mergeable_constant_section (machine_mode mode ATTRIBUTE_UNUSED,
       flags |= (align / 8) | SECTION_MERGE;
       return get_section (name, flags, NULL);
     }
-  return readonly_data_section;
+  return casm->sec.readonly_data;
 }
 \f
 /* Given NAME, a putative register name, discard any customary prefixes.  */
@@ -1253,9 +1202,9 @@ get_variable_section (tree decl, bool prefer_noswitch_p)
       gcc_assert (DECL_SECTION_NAME (decl) == NULL
 		  && ADDR_SPACE_GENERIC_P (as));
       if (DECL_THREAD_LOCAL_P (decl))
-	return tls_comm_section;
+	return casm->sec.tls_comm;
       else if (TREE_PUBLIC (decl) && bss_initializer_p (decl))
-	return comm_section;
+	return casm->sec.comm;
     }
 
   reloc = compute_reloc_for_var (decl);
@@ -1285,9 +1234,9 @@ get_variable_section (tree decl, bool prefer_noswitch_p)
       if (!TREE_PUBLIC (decl)
 	  && !((flag_sanitize & SANITIZE_ADDRESS)
 	       && asan_protect_global (decl)))
-	return lcomm_section;
-      if (bss_noswitch_section)
-	return bss_noswitch_section;
+	return casm->sec.lcomm;
+      if (casm->sec.bss_noswitch)
+	return casm->sec.bss_noswitch;
     }
 
   return targetm.asm_out.select_section (decl, reloc,
@@ -1733,7 +1682,7 @@ void
 default_dtor_section_asm_out_destructor (rtx symbol,
 					 int priority ATTRIBUTE_UNUSED)
 {
-  assemble_addr_to_section (symbol, dtors_section);
+  assemble_addr_to_section (symbol, casm->sec.dtors);
 }
 #endif
 
@@ -1756,7 +1705,7 @@ void
 default_ctor_section_asm_out_constructor (rtx symbol,
 					  int priority ATTRIBUTE_UNUSED)
 {
-  assemble_addr_to_section (symbol, ctors_section);
+  assemble_addr_to_section (symbol, casm->sec.ctors);
 }
 #endif
 \f
@@ -1824,7 +1773,7 @@ decide_function_section (tree decl)
 				      == NODE_FREQUENCY_UNLIKELY_EXECUTED);
     }
 
-  in_cold_section_p = first_function_block_is_cold;
+  casm->in_cold_section_p = first_function_block_is_cold;
 }
 
 /* Get the function's name, as described by its RTL.  This may be
@@ -1900,13 +1849,13 @@ assemble_start_function (tree decl, const char *fnname)
       if (!cfun->is_thunk
 	  && BB_PARTITION (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb) == BB_COLD_PARTITION)
 	{
-	  switch_to_section (text_section);
+	  switch_to_section (casm->sec.text);
 	  assemble_align (align);
 	  ASM_OUTPUT_LABEL (asm_out_file, crtl->subsections.hot_section_label);
 	  hot_label_written = true;
 	  first_function_block_is_cold = true;
 	}
-      in_cold_section_p = first_function_block_is_cold;
+      casm->in_cold_section_p = first_function_block_is_cold;
     }
 
 
@@ -2020,7 +1969,7 @@ assemble_end_function (tree decl, const char *fnname ATTRIBUTE_UNUSED)
     {
       section *save_text_section;
 
-      save_text_section = in_section;
+      save_text_section = casm->in_section;
       switch_to_section (unlikely_text_section ());
 #ifdef ASM_DECLARE_COLD_FUNCTION_SIZE
       if (cold_function_name != NULL_TREE)
@@ -2030,7 +1979,7 @@ assemble_end_function (tree decl, const char *fnname ATTRIBUTE_UNUSED)
 #endif
       ASM_OUTPUT_LABEL (asm_out_file, crtl->subsections.cold_section_end_label);
       if (first_function_block_is_cold)
-	switch_to_section (text_section);
+	switch_to_section (casm->sec.text);
       else
 	switch_to_section (function_section (decl));
       ASM_OUTPUT_LABEL (asm_out_file, crtl->subsections.hot_section_end_label);
@@ -2050,7 +1999,7 @@ assemble_zeros (unsigned HOST_WIDE_INT size)
 #ifdef ASM_NO_SKIP_IN_TEXT
   /* The `space' pseudo in the text section outputs nop insns rather than 0s,
      so we must output 0s explicitly in the text section.  */
-  if (ASM_NO_SKIP_IN_TEXT && (in_section->common.flags & SECTION_CODE) != 0)
+  if (ASM_NO_SKIP_IN_TEXT && (casm->in_section->common.flags & SECTION_CODE) != 0)
     {
       unsigned HOST_WIDE_INT i;
       for (i = 0; i < size; i++)
@@ -2097,7 +2046,7 @@ assemble_string (const char *p, int size)
 }
 
 \f
-/* A noswitch_section_callback for lcomm_section.  */
+/* A noswitch_section_callback for casm->sec.lcomm.  */
 
 static bool
 emit_local (tree decl ATTRIBUTE_UNUSED,
@@ -2120,7 +2069,7 @@ emit_local (tree decl ATTRIBUTE_UNUSED,
 #endif
 }
 
-/* A noswitch_section_callback for bss_noswitch_section.  */
+/* A noswitch_section_callback for casm->sec.bss_noswitch.  */
 
 #if defined ASM_OUTPUT_ALIGNED_BSS
 static bool
@@ -2135,7 +2084,7 @@ emit_bss (tree decl ATTRIBUTE_UNUSED,
 }
 #endif
 
-/* A noswitch_section_callback for comm_section.  */
+/* A noswitch_section_callback for casm->sec.comm.  */
 
 static bool
 emit_common (tree decl ATTRIBUTE_UNUSED,
@@ -2157,7 +2106,7 @@ emit_common (tree decl ATTRIBUTE_UNUSED,
 #endif
 }
 
-/* A noswitch_section_callback for tls_comm_section.  */
+/* A noswitch_section_callback for casm->sec.tls_comm.  */
 
 static bool
 emit_tls_common (tree decl ATTRIBUTE_UNUSED,
@@ -2774,7 +2723,7 @@ assemble_trampoline_template (void)
 #ifdef TRAMPOLINE_SECTION
   switch_to_section (TRAMPOLINE_SECTION);
 #else
-  switch_to_section (readonly_data_section);
+  switch_to_section (casm->sec.readonly_data);
 #endif
 
   /* Write the assembler code to define one.  */
@@ -4192,8 +4141,8 @@ output_constant_pool_1 (class constant_descriptor_rtx *desc,
   /* Make sure all constants in SECTION_MERGE and not SECTION_STRINGS
      sections have proper size.  */
   if (align > GET_MODE_BITSIZE (desc->mode)
-      && in_section
-      && (in_section->common.flags & SECTION_MERGE))
+      && casm->in_section
+      && (casm->in_section->common.flags & SECTION_MERGE))
     assemble_align (align);
 
 #ifdef ASM_OUTPUT_SPECIAL_POOL_ENTRY
@@ -6599,79 +6548,103 @@ make_decl_one_only (tree decl, tree comdat_group)
     }
 }
 
-void
-init_varasm_once (void)
+/* Default constructor.  */
+
+asm_out_state::asm_out_state ()
+: out_file (NULL), in_section (NULL),
+  sec ({}), anchor_labelno (0), in_cold_section_p (false)
 {
   section_htab = hash_table<section_hasher>::create_ggc (31);
+
   object_block_htab = hash_table<object_block_hasher>::create_ggc (31);
   const_desc_htab = hash_table<tree_descriptor_hasher>::create_ggc (1009);
 
   shared_constant_pool = create_constant_pool ();
+}
 
+
+/* Initialize all sections in SEC variable.  */
+void
+asm_out_state::init_sections (void)
+{
 #ifdef TEXT_SECTION_ASM_OP
-  text_section = get_unnamed_section (SECTION_CODE, output_section_asm_op,
-				      TEXT_SECTION_ASM_OP);
+  sec.text = get_unnamed_section (SECTION_CODE, output_section_asm_op,
+				  TEXT_SECTION_ASM_OP);
 #endif
 
 #ifdef DATA_SECTION_ASM_OP
-  data_section = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
-				      DATA_SECTION_ASM_OP);
+  sec.data = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
+				  DATA_SECTION_ASM_OP);
 #endif
 
 #ifdef SDATA_SECTION_ASM_OP
-  sdata_section = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
-				       SDATA_SECTION_ASM_OP);
+  sec.sdata = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
+				   SDATA_SECTION_ASM_OP);
 #endif
 
 #ifdef READONLY_DATA_SECTION_ASM_OP
-  readonly_data_section = get_unnamed_section (0, output_section_asm_op,
-					       READONLY_DATA_SECTION_ASM_OP);
+  sec.readonly_data = get_unnamed_section (0, output_section_asm_op,
+					   READONLY_DATA_SECTION_ASM_OP);
 #endif
 
 #ifdef CTORS_SECTION_ASM_OP
-  ctors_section = get_unnamed_section (0, output_section_asm_op,
-				       CTORS_SECTION_ASM_OP);
+  sec.ctors = get_unnamed_section (0, output_section_asm_op,
+				   CTORS_SECTION_ASM_OP);
 #endif
 
 #ifdef DTORS_SECTION_ASM_OP
-  dtors_section = get_unnamed_section (0, output_section_asm_op,
-				       DTORS_SECTION_ASM_OP);
+  sec.dtors = get_unnamed_section (0, output_section_asm_op,
+				   DTORS_SECTION_ASM_OP);
 #endif
 
 #ifdef BSS_SECTION_ASM_OP
-  bss_section = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
-				     output_section_asm_op,
-				     BSS_SECTION_ASM_OP);
+  sec.bss = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
+				 output_section_asm_op,
+				 BSS_SECTION_ASM_OP);
 #endif
 
 #ifdef SBSS_SECTION_ASM_OP
-  sbss_section = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
-				      output_section_asm_op,
-				      SBSS_SECTION_ASM_OP);
+  sec.sbss = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
+				  output_section_asm_op,
+				  SBSS_SECTION_ASM_OP);
 #endif
 
-  tls_comm_section = get_noswitch_section (SECTION_WRITE | SECTION_BSS
-					   | SECTION_COMMON, emit_tls_common);
-  lcomm_section = get_noswitch_section (SECTION_WRITE | SECTION_BSS
-					| SECTION_COMMON, emit_local);
-  comm_section = get_noswitch_section (SECTION_WRITE | SECTION_BSS
-				       | SECTION_COMMON, emit_common);
+  sec.tls_comm = get_noswitch_section (SECTION_WRITE | SECTION_BSS
+				       | SECTION_COMMON, emit_tls_common);
+  sec.lcomm = get_noswitch_section (SECTION_WRITE | SECTION_BSS
+				    | SECTION_COMMON, emit_local);
+  sec.comm = get_noswitch_section (SECTION_WRITE | SECTION_BSS
+				   | SECTION_COMMON, emit_common);
 
 #if defined ASM_OUTPUT_ALIGNED_BSS
-  bss_noswitch_section = get_noswitch_section (SECTION_WRITE | SECTION_BSS,
-					       emit_bss);
+  sec.bss_noswitch = get_noswitch_section (SECTION_WRITE | SECTION_BSS,
+					   emit_bss);
 #endif
 
-  targetm.asm_out.init_sections ();
+  if (sec.readonly_data == NULL)
+    sec.readonly_data = sec.text;
+}
 
-  if (readonly_data_section == NULL)
-    readonly_data_section = text_section;
+void
+init_varasm_once (void)
+{
+  casm = targetm.asm_out.init_sections ();
 
 #ifdef ASM_OUTPUT_EXTERNAL
   pending_assemble_externals_set = new hash_set<tree>;
 #endif
 }
 
+/* Default implementation of init_sections target hook.  */
+
+asm_out_state *
+default_init_sections (void)
+{
+  asm_out_state *state = new (ggc_alloc<asm_out_state> ()) asm_out_state ();
+  state->init_sections ();
+  return state;
+}
+
 enum tls_model
 decl_default_tls_model (const_tree decl)
 {
@@ -6790,13 +6763,13 @@ default_section_type_flags (tree decl, const char *name, int reloc)
 }
 
 /* Return true if the target supports some form of global BSS,
-   either through bss_noswitch_section, or by selecting a BSS
+   either through casm->sec.bss_noswitch, or by selecting a BSS
    section in TARGET_ASM_SELECT_SECTION.  */
 
 bool
 have_global_bss_p (void)
 {
-  return bss_noswitch_section || targetm.have_switchable_bss_sections;
+  return casm->sec.bss_noswitch || targetm.have_switchable_bss_sections;
 }
 
 /* Output assembly to switch to section NAME with attribute FLAGS.
@@ -6958,7 +6931,7 @@ default_select_section (tree decl, int reloc,
   if (DECL_P (decl))
     {
       if (decl_readonly_section (decl, reloc))
-	return readonly_data_section;
+	return casm->sec.readonly_data;
     }
   else if (TREE_CODE (decl) == CONSTRUCTOR)
     {
@@ -6966,14 +6939,14 @@ default_select_section (tree decl, int reloc,
 	     || !TREE_READONLY (decl)
 	     || TREE_SIDE_EFFECTS (decl)
 	     || !TREE_CONSTANT (decl)))
-	return readonly_data_section;
+	return casm->sec.readonly_data;
     }
   else if (TREE_CODE (decl) == STRING_CST)
-    return readonly_data_section;
+    return casm->sec.readonly_data;
   else if (! (flag_pic && reloc))
-    return readonly_data_section;
+    return casm->sec.readonly_data;
 
-  return data_section;
+  return casm->sec.data;
 }
 
 enum section_category
@@ -7112,7 +7085,7 @@ default_elf_select_section (tree decl, int reloc,
       /* We're not supposed to be called on FUNCTION_DECLs.  */
       gcc_unreachable ();
     case SECCAT_RODATA:
-      return readonly_data_section;
+      return casm->sec.readonly_data;
     case SECCAT_RODATA_MERGE_STR:
       return mergeable_string_section (decl, align, 0);
     case SECCAT_RODATA_MERGE_STR_INIT:
@@ -7128,7 +7101,7 @@ default_elf_select_section (tree decl, int reloc,
 	  sname = ".persistent";
 	  break;
 	}
-      return data_section;
+      return casm->sec.data;
     case SECCAT_DATA_REL:
       sname = ".data.rel";
       break;
@@ -7153,8 +7126,8 @@ default_elf_select_section (tree decl, int reloc,
 	  sname = ".noinit";
 	  break;
 	}
-      if (bss_section)
-	return bss_section;
+      if (casm->sec.bss)
+	return casm->sec.bss;
       sname = ".bss";
       break;
     case SECCAT_SBSS:
@@ -7304,9 +7277,9 @@ default_select_rtx_section (machine_mode mode ATTRIBUTE_UNUSED,
 			    unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
 {
   if (compute_reloc_for_rtx (x) & targetm.asm_out.reloc_rw_mask ())
-    return data_section;
+    return casm->sec.data;
   else
-    return readonly_data_section;
+    return casm->sec.readonly_data;
 }
 
 section *
@@ -7824,10 +7797,10 @@ switch_to_section (section *new_section, tree decl)
 		  "%qD was declared here", used_decl);
 	}
     }
-  else if (in_section == new_section)
+  else if (casm->in_section == new_section)
     return;
 
-  in_section = new_section;
+  casm->in_section = new_section;
 
   switch (SECTION_STYLE (new_section))
     {
@@ -8003,7 +7976,7 @@ get_section_anchor (struct object_block *block, HOST_WIDE_INT offset,
     }
 
   /* Create a new anchor with a unique label.  */
-  ASM_GENERATE_INTERNAL_LABEL (label, "LANCHOR", anchor_labelno++);
+  ASM_GENERATE_INTERNAL_LABEL (label, "LANCHOR", casm->anchor_labelno++);
   anchor = create_block_symbol (ggc_strdup (label), block, offset);
   SYMBOL_REF_FLAGS (anchor) |= SYMBOL_FLAG_LOCAL | SYMBOL_FLAG_ANCHOR;
   SYMBOL_REF_FLAGS (anchor) |= model << SYMBOL_FLAG_TLS_SHIFT;
@@ -8472,7 +8445,7 @@ handle_vtv_comdat_section (section *sect, const_tree decl ATTRIBUTE_UNUSED)
 				 sect->named.common.flags
 				 | SECTION_LINKONCE,
 				 DECL_NAME (decl));
-  in_section = sect;
+  casm->in_section = sect;
 #else
   /* Neither OBJECT_FORMAT_PE, nor OBJECT_FORMAT_COFF is set here.
      Therefore the following check is used.
@@ -8498,7 +8471,7 @@ handle_vtv_comdat_section (section *sect, const_tree decl ATTRIBUTE_UNUSED)
 				     sect->named.common.flags
 				     | SECTION_LINKONCE,
 				     DECL_NAME (decl));
-      in_section = sect;
+      casm->in_section = sect;
     }
   else
     switch_to_section (sect);
diff --git a/gcc/vmsdbgout.c b/gcc/vmsdbgout.c
index 05fadce075e..eab52c62307 100644
--- a/gcc/vmsdbgout.c
+++ b/gcc/vmsdbgout.c
@@ -1583,7 +1583,7 @@ vmsdbgout_finish (const char *filename ATTRIBUTE_UNUSED)
     return;
 
   /* Output a terminator label for the .text section.  */
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
   targetm.asm_out.internal_label (asm_out_file, TEXT_END_LABEL, 0);
 
   /* Output debugging information.
-- 
2.33.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 3/N] Come up with casm global state.
  2021-10-21  9:47         ` Martin Liška
@ 2021-10-21 12:42           ` Richard Biener
  2021-10-21 13:43             ` Martin Liška
  2021-10-21 15:40             ` Segher Boessenkool
  0 siblings, 2 replies; 30+ messages in thread
From: Richard Biener @ 2021-10-21 12:42 UTC (permalink / raw)
  To: Martin Liška; +Cc: GCC Patches, Segher Boessenkool

On Thu, Oct 21, 2021 at 11:47 AM Martin Liška <mliska@suse.cz> wrote:
>
> On 10/5/21 13:54, Richard Biener wrote:
> > On Mon, Oct 4, 2021 at 1:13 PM Martin Liška <mliska@suse.cz> wrote:
> >>
> >> On 9/22/21 11:59, Richard Biener wrote:
> >>> On Thu, Sep 16, 2021 at 3:12 PM Martin Liška <mliska@suse.cz> wrote:
> >>>>
> >>>> This patch comes up with asm_out_state and a new global variable casm.
> >>>>
> >>>> Tested on all cross compilers.
> >>>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
> >>>>
> >>>> Ready to be installed?
> >>>
> >>>           * output.h (struct asm_out_file): New struct that replaces a
> >>> ^^^
> >>> asm_out_state?
> >>
> >> Yes, sure!
> >>
> >>>
> >>> You replace a lot of asm_out_file - do we still need the macro then?
> >>> (I'd have simplified the patch leaving that replacement out at first)
> >>
> >> Well, I actually replaced only a very small fraction of the usage of asm_out_file.
> >>
> >> $ git grep asm_out_file | grep -v ChangeLog | wc -l
> >>
> >> 1601
> >>
> >>
> >> So I think we should live with the macro for some time ...
> >>
> >>>
> >>> You leave quite some global state out of the struct that is obviously
> >>> related, in the diff I see object_block_htab for example.
> >>
> >> Yes, I'm aware of it. Can we do that incrementally?
> >>
> >>> Basically
> >>> everything initialized in init_varasm_once is a candidate (which
> >>> then shows const_desc_htab and shared_constant_pool as well
> >>> as pending_assemble_externals_set).
> >>
> >> Well, these would probably need a different header file (or another #include ... must
> >> be added before output.h :// ).
> >>
> >>> For the goal of outputting
> >>> early DWARF to another file the state CTOR could have a mode
> >>> to not initialize those parts or we could have asm-out-state-with-sections
> >>> as base of asm-out-state.
> >>
> >> Yes, right now asm_out_state ctor is minimal:
> >>
> >>     asm_out_state (): out_file (NULL), in_section (NULL),
> >>       sec ({}), anchor_labelno (0), in_cold_section_p (false)
> >>     {
> >>       section_htab = hash_table<section_hasher>::create_ggc (31);
> >>     }
> >>
> >>>
> >>> In the end there will be a target part of the state so I think
> >>> construction needs to be defered to the target which can
> >>> derive from asm-out-state and initialize the part it needs.
> >>> That's currently what targetm.asm_out.init_sections () does
> >>> and we'd transform that to a targetm.asm_out.create () or so.
> >>> That might already be necessary for the DWARF stuff.
> >>
> >> So what do you want to with content of init_varasm_once function?
> >
> > It goes away ;)  Or rather becomes the invocation of the
> > asm-out-state CTOR via the target hook.
> >
> >>>
> >>> That said, dealing with the target stuff piecemail is OK, but maybe
> >>> try to make sure that init_varasm_once is actually identical
> >>> to what the CTOR does?
> >>
> >> So you want asm_out_state::asm_out_state doing what we current initialize
> >> in init_varasm_once, right?
> >
> > Yes, asm_out_state should cover everything initialized in init_varasm_once
> > (and the called targetm.asm_out.init_sections).
> >
> > targetm.asm_out.init_sections would become
> >
> > asm_out_state *init_sections ();
> >
> > where the target can derive from asm_out_state (optionally) and
> > allocates the asm-out-state & invokes the CTORs.  The middle-end
> > visible asm_out_state would contain all the tables initialized in
> > init_varasm_once.
> >
> > I'm not sure if doing it piecemail is good - we don't want to touch
> > things multiple times without good need and it might be things
> > turn out not be as "simple" as the above plan sounds.
> >
> > I would suggest to try the conversion with powerpc since it
> > seems to be the only target with two different implementations
> > for the target hook.
> >
> > The
> >
> > static GTY(()) section *read_only_data_section;
> > static GTY(()) section *private_data_section;
> > static GTY(()) section *tls_data_section;
> > static GTY(()) section *tls_private_data_section;
> > static GTY(()) section *read_only_private_data_section;
> > static GTY(()) section *sdata2_section;
> >
> > section *toc_section = 0;
> >
> > could become #defines to static_cast<rs6000_asm_out_state *>
> > (casm)->section_name
> > and there'd be
> >
> > class rs6000_asm_out_state : public asm_out_state
> > {
> > ... add stuff ...
> > }
> >
> > in rs6000/xcoff.h and rs6000/sysv4.h and some generic rs6000 header as well
> > (adding no fields) and the target hook would basically do
> >
> >   return ggc_new rs6000_asm_state ();
> >
> > (OK, ggc_alloc + placement new I guess).  The default hook just
> > creates asm_out_state.
>
> Hello.
>
> All right, I made a patch candidate that does the suggested steps and I ported
> rs6000 target (both ELF and XCOFF sub-targets).
>
> So far I was able to bootstrap on ppc6le-linux-gnu.
>
> Thoughts?

+extern GTY(()) rs6000_asm_out_state *target_casm;

this seems to be unused

+#define rs6000_casm static_cast<rs6000_asm_out_state *> (casm)

maybe there's a better way?  Though I can't think of one at the moment.
There are only 10 uses so eventually we can put the
static_cast into all places.  Let's ask the powerpc maintainers (CCed).

Note you do

+/* Implement TARGET_ASM_INIT_SECTIONS.  */
+
+static asm_out_state *
+rs6000_elf_asm_init_sections (void)
+{
+  rs6000_asm_out_state *target_state
+    = new (ggc_alloc<rs6000_asm_out_state> ()) rs6000_asm_out_state ();
+  target_state->init_elf_sections ();
+  target_state->init_sections ();
+
+  return target_state;
+}

If you'd have made init_sections virtual the flow would be more
natural and we could separate section init from casm construction
(and rs6000 would override init_sections but call the base function
from the override).

Alternatively asm_out_state::init_sections could move into the
CTOR itself so the target hook doesn't need to explicitely call it
(I guess I prefer that variant).

Otherwise looks great - there are of course a few other targets
left to fixup.

Thanks,
Richard.

> Thanks,
> Martin
>
> >
> > Richard.
> >
> >> Thanks,
> >> Cheers,
> >> Martin
> >>
> >>
> >>>
> >>> Richard.
> >>>
> >>>> Thanks,
> >>>> Martin
> >>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 3/N] Come up with casm global state.
  2021-09-16 13:12 ` [PATCH 3/N] Come up with casm global state Martin Liška
  2021-09-22  9:59   ` Richard Biener
  2021-10-04 11:16   ` Martin Liška
@ 2021-10-21 12:47   ` David Malcolm
  2021-10-21 13:08     ` Richard Biener
  2 siblings, 1 reply; 30+ messages in thread
From: David Malcolm @ 2021-10-21 12:47 UTC (permalink / raw)
  To: Martin Liška, GCC Patches

On Thu, 2021-09-16 at 15:12 +0200, Martin Liška wrote:
> This patch comes up with asm_out_state and a new global variable
> casm.
> 
> Tested on all cross compilers.
> Patch can bootstrap on x86_64-linux-gnu and survives regression
> tests.
> 
> Ready to be installed?
> Thanks,
> Martin

This is possibly a silly question, but what does the "c" stand for in
"casm"?   "compiler"? "compilation"? "common"?

Sorry if it's explained somewhere, but I didn't spot this when glancing
at the patches.

Dave


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 3/N] Come up with casm global state.
  2021-10-21 12:47   ` David Malcolm
@ 2021-10-21 13:08     ` Richard Biener
  0 siblings, 0 replies; 30+ messages in thread
From: Richard Biener @ 2021-10-21 13:08 UTC (permalink / raw)
  To: David Malcolm; +Cc: Martin Liška, GCC Patches

On Thu, Oct 21, 2021 at 2:48 PM David Malcolm via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> On Thu, 2021-09-16 at 15:12 +0200, Martin Liška wrote:
> > This patch comes up with asm_out_state and a new global variable
> > casm.
> >
> > Tested on all cross compilers.
> > Patch can bootstrap on x86_64-linux-gnu and survives regression
> > tests.
> >
> > Ready to be installed?
> > Thanks,
> > Martin
>
> This is possibly a silly question, but what does the "c" stand for in
> "casm"?   "compiler"? "compilation"? "common"?

'current' like cfun or crtl .. maybe just following "bad" examples?

> Sorry if it's explained somewhere, but I didn't spot this when glancing
> at the patches.
>
> Dave
>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 3/N] Come up with casm global state.
  2021-10-21 12:42           ` Richard Biener
@ 2021-10-21 13:43             ` Martin Liška
  2021-10-21 13:57               ` Richard Biener
  2021-10-21 15:40             ` Segher Boessenkool
  1 sibling, 1 reply; 30+ messages in thread
From: Martin Liška @ 2021-10-21 13:43 UTC (permalink / raw)
  To: Richard Biener; +Cc: GCC Patches, Segher Boessenkool

On 10/21/21 14:42, Richard Biener wrote:
> On Thu, Oct 21, 2021 at 11:47 AM Martin Liška <mliska@suse.cz> wrote:
>>
>> On 10/5/21 13:54, Richard Biener wrote:
>>> On Mon, Oct 4, 2021 at 1:13 PM Martin Liška <mliska@suse.cz> wrote:
>>>>
>>>> On 9/22/21 11:59, Richard Biener wrote:
>>>>> On Thu, Sep 16, 2021 at 3:12 PM Martin Liška <mliska@suse.cz> wrote:
>>>>>>
>>>>>> This patch comes up with asm_out_state and a new global variable casm.
>>>>>>
>>>>>> Tested on all cross compilers.
>>>>>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>>>>>>
>>>>>> Ready to be installed?
>>>>>
>>>>>            * output.h (struct asm_out_file): New struct that replaces a
>>>>> ^^^
>>>>> asm_out_state?
>>>>
>>>> Yes, sure!
>>>>
>>>>>
>>>>> You replace a lot of asm_out_file - do we still need the macro then?
>>>>> (I'd have simplified the patch leaving that replacement out at first)
>>>>
>>>> Well, I actually replaced only a very small fraction of the usage of asm_out_file.
>>>>
>>>> $ git grep asm_out_file | grep -v ChangeLog | wc -l
>>>>
>>>> 1601
>>>>
>>>>
>>>> So I think we should live with the macro for some time ...
>>>>
>>>>>
>>>>> You leave quite some global state out of the struct that is obviously
>>>>> related, in the diff I see object_block_htab for example.
>>>>
>>>> Yes, I'm aware of it. Can we do that incrementally?
>>>>
>>>>> Basically
>>>>> everything initialized in init_varasm_once is a candidate (which
>>>>> then shows const_desc_htab and shared_constant_pool as well
>>>>> as pending_assemble_externals_set).
>>>>
>>>> Well, these would probably need a different header file (or another #include ... must
>>>> be added before output.h :// ).
>>>>
>>>>> For the goal of outputting
>>>>> early DWARF to another file the state CTOR could have a mode
>>>>> to not initialize those parts or we could have asm-out-state-with-sections
>>>>> as base of asm-out-state.
>>>>
>>>> Yes, right now asm_out_state ctor is minimal:
>>>>
>>>>      asm_out_state (): out_file (NULL), in_section (NULL),
>>>>        sec ({}), anchor_labelno (0), in_cold_section_p (false)
>>>>      {
>>>>        section_htab = hash_table<section_hasher>::create_ggc (31);
>>>>      }
>>>>
>>>>>
>>>>> In the end there will be a target part of the state so I think
>>>>> construction needs to be defered to the target which can
>>>>> derive from asm-out-state and initialize the part it needs.
>>>>> That's currently what targetm.asm_out.init_sections () does
>>>>> and we'd transform that to a targetm.asm_out.create () or so.
>>>>> That might already be necessary for the DWARF stuff.
>>>>
>>>> So what do you want to with content of init_varasm_once function?
>>>
>>> It goes away ;)  Or rather becomes the invocation of the
>>> asm-out-state CTOR via the target hook.
>>>
>>>>>
>>>>> That said, dealing with the target stuff piecemail is OK, but maybe
>>>>> try to make sure that init_varasm_once is actually identical
>>>>> to what the CTOR does?
>>>>
>>>> So you want asm_out_state::asm_out_state doing what we current initialize
>>>> in init_varasm_once, right?
>>>
>>> Yes, asm_out_state should cover everything initialized in init_varasm_once
>>> (and the called targetm.asm_out.init_sections).
>>>
>>> targetm.asm_out.init_sections would become
>>>
>>> asm_out_state *init_sections ();
>>>
>>> where the target can derive from asm_out_state (optionally) and
>>> allocates the asm-out-state & invokes the CTORs.  The middle-end
>>> visible asm_out_state would contain all the tables initialized in
>>> init_varasm_once.
>>>
>>> I'm not sure if doing it piecemail is good - we don't want to touch
>>> things multiple times without good need and it might be things
>>> turn out not be as "simple" as the above plan sounds.
>>>
>>> I would suggest to try the conversion with powerpc since it
>>> seems to be the only target with two different implementations
>>> for the target hook.
>>>
>>> The
>>>
>>> static GTY(()) section *read_only_data_section;
>>> static GTY(()) section *private_data_section;
>>> static GTY(()) section *tls_data_section;
>>> static GTY(()) section *tls_private_data_section;
>>> static GTY(()) section *read_only_private_data_section;
>>> static GTY(()) section *sdata2_section;
>>>
>>> section *toc_section = 0;
>>>
>>> could become #defines to static_cast<rs6000_asm_out_state *>
>>> (casm)->section_name
>>> and there'd be
>>>
>>> class rs6000_asm_out_state : public asm_out_state
>>> {
>>> ... add stuff ...
>>> }
>>>
>>> in rs6000/xcoff.h and rs6000/sysv4.h and some generic rs6000 header as well
>>> (adding no fields) and the target hook would basically do
>>>
>>>    return ggc_new rs6000_asm_state ();
>>>
>>> (OK, ggc_alloc + placement new I guess).  The default hook just
>>> creates asm_out_state.
>>
>> Hello.
>>
>> All right, I made a patch candidate that does the suggested steps and I ported
>> rs6000 target (both ELF and XCOFF sub-targets).
>>
>> So far I was able to bootstrap on ppc6le-linux-gnu.
>>
>> Thoughts?
> 
> +extern GTY(()) rs6000_asm_out_state *target_casm;
> 
> this seems to be unused

Sure, it can be a static variable in rs6000.c for GGC marking purpose.

> 
> +#define rs6000_casm static_cast<rs6000_asm_out_state *> (casm)
> 
> maybe there's a better way?  Though I can't think of one at the moment.
> There are only 10 uses so eventually we can put the
> static_cast into all places.  Let's ask the powerpc maintainers (CCed).

Or we can wrap it with a function call doing the casting?

> 
> Note you do
> 
> +/* Implement TARGET_ASM_INIT_SECTIONS.  */
> +
> +static asm_out_state *
> +rs6000_elf_asm_init_sections (void)
> +{
> +  rs6000_asm_out_state *target_state
> +    = new (ggc_alloc<rs6000_asm_out_state> ()) rs6000_asm_out_state ();
> +  target_state->init_elf_sections ();
> +  target_state->init_sections ();
> +
> +  return target_state;
> +}
> 
> If you'd have made init_sections virtual the flow would be more
> natural and we could separate section init from casm construction
> (and rs6000 would override init_sections but call the base function
> from the override).
> 
> Alternatively asm_out_state::init_sections could move into the
> CTOR itself so the target hook doesn't need to explicitely call it
> (I guess I prefer that variant).

Yes, we can do an overridable function. Note there's small trick in the base
init_sections function:

   if (readonly_data_section == NULL)
     readonly_data_section = text_section;

So it needs to be run after a derived version.

> 
> Otherwise looks great - there are of course a few other targets
> left to fixup.

Yep. To be honest I'm quite happy with the current implementation and let's
see what PPC guys say about it.

Cheers,
Martin

> 
> Thanks,
> Richard.
> 
>> Thanks,
>> Martin
>>
>>>
>>> Richard.
>>>
>>>> Thanks,
>>>> Cheers,
>>>> Martin
>>>>
>>>>
>>>>>
>>>>> Richard.
>>>>>
>>>>>> Thanks,
>>>>>> Martin
>>>>


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 3/N] Come up with casm global state.
  2021-10-21 13:43             ` Martin Liška
@ 2021-10-21 13:57               ` Richard Biener
  0 siblings, 0 replies; 30+ messages in thread
From: Richard Biener @ 2021-10-21 13:57 UTC (permalink / raw)
  To: Martin Liška; +Cc: GCC Patches, Segher Boessenkool

On Thu, Oct 21, 2021 at 3:43 PM Martin Liška <mliska@suse.cz> wrote:
>
> On 10/21/21 14:42, Richard Biener wrote:
> > On Thu, Oct 21, 2021 at 11:47 AM Martin Liška <mliska@suse.cz> wrote:
> >>
> >> On 10/5/21 13:54, Richard Biener wrote:
> >>> On Mon, Oct 4, 2021 at 1:13 PM Martin Liška <mliska@suse.cz> wrote:
> >>>>
> >>>> On 9/22/21 11:59, Richard Biener wrote:
> >>>>> On Thu, Sep 16, 2021 at 3:12 PM Martin Liška <mliska@suse.cz> wrote:
> >>>>>>
> >>>>>> This patch comes up with asm_out_state and a new global variable casm.
> >>>>>>
> >>>>>> Tested on all cross compilers.
> >>>>>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
> >>>>>>
> >>>>>> Ready to be installed?
> >>>>>
> >>>>>            * output.h (struct asm_out_file): New struct that replaces a
> >>>>> ^^^
> >>>>> asm_out_state?
> >>>>
> >>>> Yes, sure!
> >>>>
> >>>>>
> >>>>> You replace a lot of asm_out_file - do we still need the macro then?
> >>>>> (I'd have simplified the patch leaving that replacement out at first)
> >>>>
> >>>> Well, I actually replaced only a very small fraction of the usage of asm_out_file.
> >>>>
> >>>> $ git grep asm_out_file | grep -v ChangeLog | wc -l
> >>>>
> >>>> 1601
> >>>>
> >>>>
> >>>> So I think we should live with the macro for some time ...
> >>>>
> >>>>>
> >>>>> You leave quite some global state out of the struct that is obviously
> >>>>> related, in the diff I see object_block_htab for example.
> >>>>
> >>>> Yes, I'm aware of it. Can we do that incrementally?
> >>>>
> >>>>> Basically
> >>>>> everything initialized in init_varasm_once is a candidate (which
> >>>>> then shows const_desc_htab and shared_constant_pool as well
> >>>>> as pending_assemble_externals_set).
> >>>>
> >>>> Well, these would probably need a different header file (or another #include ... must
> >>>> be added before output.h :// ).
> >>>>
> >>>>> For the goal of outputting
> >>>>> early DWARF to another file the state CTOR could have a mode
> >>>>> to not initialize those parts or we could have asm-out-state-with-sections
> >>>>> as base of asm-out-state.
> >>>>
> >>>> Yes, right now asm_out_state ctor is minimal:
> >>>>
> >>>>      asm_out_state (): out_file (NULL), in_section (NULL),
> >>>>        sec ({}), anchor_labelno (0), in_cold_section_p (false)
> >>>>      {
> >>>>        section_htab = hash_table<section_hasher>::create_ggc (31);
> >>>>      }
> >>>>
> >>>>>
> >>>>> In the end there will be a target part of the state so I think
> >>>>> construction needs to be defered to the target which can
> >>>>> derive from asm-out-state and initialize the part it needs.
> >>>>> That's currently what targetm.asm_out.init_sections () does
> >>>>> and we'd transform that to a targetm.asm_out.create () or so.
> >>>>> That might already be necessary for the DWARF stuff.
> >>>>
> >>>> So what do you want to with content of init_varasm_once function?
> >>>
> >>> It goes away ;)  Or rather becomes the invocation of the
> >>> asm-out-state CTOR via the target hook.
> >>>
> >>>>>
> >>>>> That said, dealing with the target stuff piecemail is OK, but maybe
> >>>>> try to make sure that init_varasm_once is actually identical
> >>>>> to what the CTOR does?
> >>>>
> >>>> So you want asm_out_state::asm_out_state doing what we current initialize
> >>>> in init_varasm_once, right?
> >>>
> >>> Yes, asm_out_state should cover everything initialized in init_varasm_once
> >>> (and the called targetm.asm_out.init_sections).
> >>>
> >>> targetm.asm_out.init_sections would become
> >>>
> >>> asm_out_state *init_sections ();
> >>>
> >>> where the target can derive from asm_out_state (optionally) and
> >>> allocates the asm-out-state & invokes the CTORs.  The middle-end
> >>> visible asm_out_state would contain all the tables initialized in
> >>> init_varasm_once.
> >>>
> >>> I'm not sure if doing it piecemail is good - we don't want to touch
> >>> things multiple times without good need and it might be things
> >>> turn out not be as "simple" as the above plan sounds.
> >>>
> >>> I would suggest to try the conversion with powerpc since it
> >>> seems to be the only target with two different implementations
> >>> for the target hook.
> >>>
> >>> The
> >>>
> >>> static GTY(()) section *read_only_data_section;
> >>> static GTY(()) section *private_data_section;
> >>> static GTY(()) section *tls_data_section;
> >>> static GTY(()) section *tls_private_data_section;
> >>> static GTY(()) section *read_only_private_data_section;
> >>> static GTY(()) section *sdata2_section;
> >>>
> >>> section *toc_section = 0;
> >>>
> >>> could become #defines to static_cast<rs6000_asm_out_state *>
> >>> (casm)->section_name
> >>> and there'd be
> >>>
> >>> class rs6000_asm_out_state : public asm_out_state
> >>> {
> >>> ... add stuff ...
> >>> }
> >>>
> >>> in rs6000/xcoff.h and rs6000/sysv4.h and some generic rs6000 header as well
> >>> (adding no fields) and the target hook would basically do
> >>>
> >>>    return ggc_new rs6000_asm_state ();
> >>>
> >>> (OK, ggc_alloc + placement new I guess).  The default hook just
> >>> creates asm_out_state.
> >>
> >> Hello.
> >>
> >> All right, I made a patch candidate that does the suggested steps and I ported
> >> rs6000 target (both ELF and XCOFF sub-targets).
> >>
> >> So far I was able to bootstrap on ppc6le-linux-gnu.
> >>
> >> Thoughts?
> >
> > +extern GTY(()) rs6000_asm_out_state *target_casm;
> >
> > this seems to be unused
>
> Sure, it can be a static variable in rs6000.c for GGC marking purpose.

Ah, it's for GGC marking.  In that case we should probably use
user marking to be able to use the casm root and call a virtual
mark() function from the ggc_mark overload?  I failed to see the place
you initialize the global variable btw.

> >
> > +#define rs6000_casm static_cast<rs6000_asm_out_state *> (casm)
> >
> > maybe there's a better way?  Though I can't think of one at the moment.
> > There are only 10 uses so eventually we can put the
> > static_cast into all places.  Let's ask the powerpc maintainers (CCed).
>
> Or we can wrap it with a function call doing the casting?
>
> >
> > Note you do
> >
> > +/* Implement TARGET_ASM_INIT_SECTIONS.  */
> > +
> > +static asm_out_state *
> > +rs6000_elf_asm_init_sections (void)
> > +{
> > +  rs6000_asm_out_state *target_state
> > +    = new (ggc_alloc<rs6000_asm_out_state> ()) rs6000_asm_out_state ();
> > +  target_state->init_elf_sections ();
> > +  target_state->init_sections ();
> > +
> > +  return target_state;
> > +}
> >
> > If you'd have made init_sections virtual the flow would be more
> > natural and we could separate section init from casm construction
> > (and rs6000 would override init_sections but call the base function
> > from the override).
> >
> > Alternatively asm_out_state::init_sections could move into the
> > CTOR itself so the target hook doesn't need to explicitely call it
> > (I guess I prefer that variant).
>
> Yes, we can do an overridable function. Note there's small trick in the base
> init_sections function:
>
>    if (readonly_data_section == NULL)
>      readonly_data_section = text_section;
>
> So it needs to be run after a derived version.

Uh.  Maybe we can unconditionally set it to text_section and
simply have the target override it if needed.

> >
> > Otherwise looks great - there are of course a few other targets
> > left to fixup.
>
> Yep. To be honest I'm quite happy with the current implementation and let's
> see what PPC guys say about it.

Yeah.  Let's think of the GGC stuff a bit, having extra globals for the GC roots
of the correct type doesn't look sustainable?  That is, I'd have


+struct GTY((user)) asm_out_state
+{...
     virtual void gt_ggc_mx ();
  };

void
asm_out_state::gt_ggc_mx ()
{
  ggc_test_and_set_mark (sec.text);
...
}

void
gt_ggc_mx (asm_out_state *s)
{
  s->gt_ggc_mx ();
}

and have targets derive gt_ggc_mx for their members (well, ideally of course
gengtype would magically provide those definitions...).  The above also means
we could allocate asm_out_state on the heap(?)

> Cheers,
> Martin
>
> >
> > Thanks,
> > Richard.
> >
> >> Thanks,
> >> Martin
> >>
> >>>
> >>> Richard.
> >>>
> >>>> Thanks,
> >>>> Cheers,
> >>>> Martin
> >>>>
> >>>>
> >>>>>
> >>>>> Richard.
> >>>>>
> >>>>>> Thanks,
> >>>>>> Martin
> >>>>
>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 3/N] Come up with casm global state.
  2021-10-21 12:42           ` Richard Biener
  2021-10-21 13:43             ` Martin Liška
@ 2021-10-21 15:40             ` Segher Boessenkool
  2021-10-25 10:46               ` Richard Biener
  1 sibling, 1 reply; 30+ messages in thread
From: Segher Boessenkool @ 2021-10-21 15:40 UTC (permalink / raw)
  To: Richard Biener; +Cc: Martin Liška, GCC Patches

On Thu, Oct 21, 2021 at 02:42:10PM +0200, Richard Biener wrote:
> +#define rs6000_casm static_cast<rs6000_asm_out_state *> (casm)
> 
> maybe there's a better way?  Though I can't think of one at the moment.
> There are only 10 uses so eventually we can put the
> static_cast into all places.  Let's ask the powerpc maintainers (CCed).

It's disgusting, and fragile.  The define is slightly better than having
to write it out every time.  But can this not be done properly?

If you use object-oriented stuff and need casts for that, you are doing
something wrong.

> Note you do
> 
> +/* Implement TARGET_ASM_INIT_SECTIONS.  */
> +
> +static asm_out_state *
> +rs6000_elf_asm_init_sections (void)
> +{
> +  rs6000_asm_out_state *target_state
> +    = new (ggc_alloc<rs6000_asm_out_state> ()) rs6000_asm_out_state ();
> +  target_state->init_elf_sections ();
> +  target_state->init_sections ();
> +
> +  return target_state;
> +}
> 
> If you'd have made init_sections virtual the flow would be more
> natural and we could separate section init from casm construction
> (and rs6000 would override init_sections but call the base function
> from the override).

Yeah.


Segher

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 3/N] Come up with casm global state.
  2021-10-21 15:40             ` Segher Boessenkool
@ 2021-10-25 10:46               ` Richard Biener
  2021-10-25 13:36                 ` Martin Liška
  2021-10-25 16:06                 ` Segher Boessenkool
  0 siblings, 2 replies; 30+ messages in thread
From: Richard Biener @ 2021-10-25 10:46 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: Martin Liška, GCC Patches

On Thu, Oct 21, 2021 at 5:42 PM Segher Boessenkool
<segher@kernel.crashing.org> wrote:
>
> On Thu, Oct 21, 2021 at 02:42:10PM +0200, Richard Biener wrote:
> > +#define rs6000_casm static_cast<rs6000_asm_out_state *> (casm)
> >
> > maybe there's a better way?  Though I can't think of one at the moment.
> > There are only 10 uses so eventually we can put the
> > static_cast into all places.  Let's ask the powerpc maintainers (CCed).
>
> It's disgusting, and fragile.  The define is slightly better than having
> to write it out every time.  But can this not be done properly?
>
> If you use object-oriented stuff and need casts for that, you are doing
> something wrong.

I think the "proper" fix would be to make 'casm' have the correct type
in the first place - of course that would either mean that the target
needs to provide the (possibly derived) type, for example via a typedef
in the target structure or a classical target macro.  If gengtype would
know about inheritance that would also fix the GC marking issue.
Of course encoding a static type in the target structure is the
wrong direction from making targets "switchable".

Other than that my C++ fu is too weak to suggest the correct "pattern"
here.

> > Note you do
> >
> > +/* Implement TARGET_ASM_INIT_SECTIONS.  */
> > +
> > +static asm_out_state *
> > +rs6000_elf_asm_init_sections (void)
> > +{
> > +  rs6000_asm_out_state *target_state
> > +    = new (ggc_alloc<rs6000_asm_out_state> ()) rs6000_asm_out_state ();
> > +  target_state->init_elf_sections ();
> > +  target_state->init_sections ();
> > +
> > +  return target_state;
> > +}
> >
> > If you'd have made init_sections virtual the flow would be more
> > natural and we could separate section init from casm construction
> > (and rs6000 would override init_sections but call the base function
> > from the override).
>
> Yeah.
>
>
> Segher

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 3/N] Come up with casm global state.
  2021-10-25 10:46               ` Richard Biener
@ 2021-10-25 13:36                 ` Martin Liška
  2021-10-25 16:30                   ` Segher Boessenkool
  2021-10-25 16:06                 ` Segher Boessenkool
  1 sibling, 1 reply; 30+ messages in thread
From: Martin Liška @ 2021-10-25 13:36 UTC (permalink / raw)
  To: Richard Biener, Segher Boessenkool; +Cc: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 372 bytes --]

On 10/25/21 12:46, Richard Biener wrote:
> Other than that my C++ fu is too weak to suggest the correct "pattern"
> here.

Hi.

I've got one more approach where the asm_out_state would contain all
target-specific sections (I guess there will be some overlap in between targets).
And then target inherited class can do the initialization.

What do you think?
Cheers,
Martin

[-- Attachment #2: 0001-Come-up-with-casm-global-state-v3.patch --]
[-- Type: text/x-patch, Size: 119314 bytes --]

From 61a08b1b69d9b904797e7ddc4c802c54cddc3c9a Mon Sep 17 00:00:00 2001
From: Martin Liska <mliska@suse.cz>
Date: Tue, 7 Sep 2021 13:32:57 +0200
Subject: [PATCH] Come up with casm global state.

---
 gcc/cgraphunit.c                    |   2 +-
 gcc/config/aarch64/aarch64.c        |   2 +-
 gcc/config/aarch64/aarch64.h        |   2 +-
 gcc/config/alpha/alpha.c            |  12 +-
 gcc/config/alpha/elf.h              |   4 +-
 gcc/config/arc/arc.c                |   2 +-
 gcc/config/arm/aout.h               |   2 +-
 gcc/config/arm/arm.c                |  14 +-
 gcc/config/arm/arm.h                |   2 +-
 gcc/config/arm/unknown-elf.h        |   4 +-
 gcc/config/avr/avr.c                |  12 +-
 gcc/config/bfin/bfin.h              |   2 +-
 gcc/config/c6x/c6x.c                |   4 +-
 gcc/config/c6x/c6x.h                |   4 +-
 gcc/config/csky/csky.c              |   2 +-
 gcc/config/darwin.c                 |  66 ++++----
 gcc/config/frv/frv.c                |   4 +-
 gcc/config/frv/frv.h                |   2 +-
 gcc/config/ft32/ft32.h              |   6 +-
 gcc/config/i386/cygming.h           |   2 +-
 gcc/config/i386/darwin.h            |   2 +-
 gcc/config/i386/i386.c              |   6 +-
 gcc/config/i386/sol2.h              |   6 +-
 gcc/config/i386/winnt.c             |   2 +-
 gcc/config/ia64/ia64.c              |   4 +-
 gcc/config/ia64/sysv4.h             |   4 +-
 gcc/config/lm32/lm32.h              |   8 +-
 gcc/config/m32r/m32r.h              |   2 +-
 gcc/config/mcore/mcore-elf.h        |   4 +-
 gcc/config/microblaze/microblaze.c  |   6 +-
 gcc/config/microblaze/microblaze.h  |   8 +-
 gcc/config/mips/mips.c              |   2 +-
 gcc/config/mmix/mmix.c              |   6 +-
 gcc/config/msp430/msp430.c          |   8 +-
 gcc/config/nios2/nios2.h            |   4 +-
 gcc/config/pa/pa.c                  |  34 ++---
 gcc/config/pdp11/pdp11.c            |   6 +-
 gcc/config/pru/pru.h                |   2 +-
 gcc/config/riscv/riscv.c            |   4 +-
 gcc/config/rl78/rl78.c              |  12 +-
 gcc/config/rs6000/rs6000-internal.h |   9 ++
 gcc/config/rs6000/rs6000-logue.c    |   2 +-
 gcc/config/rs6000/rs6000.c          | 101 +++++++-----
 gcc/config/rs6000/rs6000.h          |   1 -
 gcc/config/rs6000/sysv4.h           |   2 +-
 gcc/config/rx/rx.c                  |  12 +-
 gcc/config/s390/s390.c              |   2 +-
 gcc/config/sh/sh.c                  |   2 +-
 gcc/config/sparc/sol2.h             |   6 +-
 gcc/config/sparc/sparc.c            |   2 +-
 gcc/config/tilegx/tilegx.h          |   2 +-
 gcc/config/tilepro/tilepro.h        |   2 +-
 gcc/config/v850/v850.c              |  10 +-
 gcc/config/visium/visium.h          |   4 +-
 gcc/coretypes.h                     |   1 +
 gcc/dbxout.c                        |  20 +--
 gcc/doc/tm.texi                     |  16 +-
 gcc/doc/tm.texi.in                  |  14 +-
 gcc/dwarf2out.c                     |  56 +++----
 gcc/dwarf2out.h                     |   4 +-
 gcc/except.c                        |  12 +-
 gcc/final.c                         |  24 +--
 gcc/ggc-common.c                    |   7 +
 gcc/langhooks.c                     |   4 +-
 gcc/output.h                        | 104 ++++++++++---
 gcc/run-rtl-passes.c                |   2 +-
 gcc/target.def                      |   4 +-
 gcc/targhooks.c                     |   2 +-
 gcc/toplev.c                        |  38 ++---
 gcc/varasm.c                        | 229 ++++++++++++----------------
 gcc/vmsdbgout.c                     |   2 +-
 71 files changed, 519 insertions(+), 457 deletions(-)

diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 55cb0347149..773ca4fb27d 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -2309,7 +2309,7 @@ symbol_table::compile (void)
   timevar_pop (TV_CGRAPHOPT);
 
   /* Output everything.  */
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
   (*debug_hooks->assembly_start) ();
   if (!quiet_flag)
     fprintf (stderr, "Assembling functions:\n");
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 699c105a42a..b5bccdcfb88 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -25753,7 +25753,7 @@ aarch64_sls_emit_blr_function_thunks (FILE *out_file)
      would happen in a different section -- leaving an unmatched
      `.cfi_startproc` in the cold text section and an unmatched `.cfi_endproc`
      in the standard text section.  */
-  section *save_text_section = in_section;
+  section *save_text_section = casm->in_section;
   switch_to_section (function_section (current_function_decl));
   for (int regnum = 0; regnum < 30; ++regnum)
     {
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 2792bb29adb..8cb6a184bdc 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -1138,7 +1138,7 @@ typedef struct
 
 /* Put trampolines in the text section so that mapping symbols work
    correctly.  */
-#define TRAMPOLINE_SECTION text_section
+#define TRAMPOLINE_SECTION casm->sec.text
 
 /* To start with.  */
 #define BRANCH_COST(SPEED_P, PREDICTABLE_P) \
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index fced7ceefe2..cdf32ae37f4 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -8055,13 +8055,13 @@ alpha_start_function (FILE *file, const char *fnname,
 
 #ifdef TARGET_VMS_CRASH_DEBUG
   /* Support of minimal traceback info.  */
-  switch_to_section (readonly_data_section);
+  switch_to_section (casm->sec.readonly_data);
   fprintf (file, "\t.align 3\n");
   assemble_name (file, fnname); fputs ("..na:\n", file);
   fputs ("\t.ascii \"", file);
   assemble_name (file, fnname);
   fputs ("\\0\"\n", file);
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
 #endif
 #endif /* TARGET_ABI_OPEN_VMS */
 }
@@ -9446,7 +9446,7 @@ alpha_elf_select_rtx_section (machine_mode mode, rtx x,
 {
   if (TARGET_SMALL_DATA && GET_MODE_SIZE (mode) <= g_switch_value)
     /* ??? Consider using mergeable sdata sections.  */
-    return sdata_section;
+    return casm->sec.sdata;
   else
     return default_elf_select_rtx_section (mode, x, align);
 }
@@ -9613,7 +9613,7 @@ alpha_write_linkage (FILE *stream, const char *funname)
 {
   fprintf (stream, "\t.link\n");
   fprintf (stream, "\t.align 3\n");
-  in_section = NULL;
+  casm->in_section = NULL;
 
 #ifdef TARGET_VMS_CRASH_DEBUG
   fputs ("\t.name ", stream);
@@ -9665,7 +9665,7 @@ vms_asm_named_section (const char *name, unsigned int flags,
 static void
 vms_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
 {
-  switch_to_section (ctors_section);
+  switch_to_section (casm->sec.ctors);
   assemble_align (BITS_PER_WORD);
   assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
 }
@@ -9673,7 +9673,7 @@ vms_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
 static void
 vms_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
 {
-  switch_to_section (dtors_section);
+  switch_to_section (casm->sec.dtors);
   assemble_align (BITS_PER_WORD);
   assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
 }
diff --git a/gcc/config/alpha/elf.h b/gcc/config/alpha/elf.h
index b735f279b30..5a34bccccad 100644
--- a/gcc/config/alpha/elf.h
+++ b/gcc/config/alpha/elf.h
@@ -46,9 +46,9 @@ along with GCC; see the file COPYING3.  If not see
 #define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)		\
 do {									\
   if ((SIZE) <= (unsigned HOST_WIDE_INT) g_switch_value)		\
-    switch_to_section (sbss_section);					\
+    switch_to_section (casm->sec.sbss);					\
   else									\
-    switch_to_section (bss_section);					\
+    switch_to_section (casm->sec.bss);					\
   ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
   if (!flag_inhibit_size_directive)					\
     ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);			\
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 8244f37bf03..9b3a55ca40d 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -8832,7 +8832,7 @@ arc_asm_output_aligned_decl_local (FILE * stream, tree decl, const char * name,
     switch_to_section (get_named_section (NULL, ".sbss", 0));
   /*    named_section (0,".sbss",0); */
   else
-    switch_to_section (bss_section);
+    switch_to_section (casm->sec.bss);
 
   if (globalize_p)
     (*targetm.asm_out.globalize_label) (stream, name);
diff --git a/gcc/config/arm/aout.h b/gcc/config/arm/aout.h
index 25a2812a663..01743bb040e 100644
--- a/gcc/config/arm/aout.h
+++ b/gcc/config/arm/aout.h
@@ -288,7 +288,7 @@
 #define ASM_OUTPUT_ALIGNED_LOCAL(STREAM, NAME, SIZE, ALIGN)		\
   do									\
     {									\
-      switch_to_section (bss_section);					\
+      switch_to_section (casm->sec.bss);					\
       ASM_OUTPUT_ALIGN (STREAM, floor_log2 (ALIGN / BITS_PER_UNIT));	\
       ASM_OUTPUT_LABEL (STREAM, NAME);					\
       fprintf (STREAM, "\t.space\t%d\n", (int)(SIZE));			\
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index c4ff06b087e..38c53e69b9a 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -17210,7 +17210,7 @@ get_jump_table_size (rtx_jump_table_data *insn)
 {
   /* ADDR_VECs only take room if read-only data does into the text
      section.  */
-  if (JUMP_TABLES_IN_TEXT_SECTION || readonly_data_section == text_section)
+  if (JUMP_TABLES_IN_TEXT_SECTION || casm->sec.readonly_data == casm->sec.text)
     {
       rtx body = PATTERN (insn);
       int elt = GET_CODE (body) == ADDR_DIFF_VEC ? 1 : 0;
@@ -24618,9 +24618,9 @@ arm_elf_asm_cdtor (rtx symbol, int priority, bool is_ctor)
       s = get_section (buf, SECTION_WRITE | SECTION_NOTYPE, NULL_TREE);
     }
   else if (is_ctor)
-    s = ctors_section;
+    s = casm->sec.ctors;
   else
-    s = dtors_section;
+    s = casm->sec.dtors;
 
   switch_to_section (s);
   assemble_align (POINTER_SIZE);
@@ -27886,7 +27886,7 @@ thumb_call_via_reg (rtx reg)
   /* If we are in the normal text section we can use a single instance
      per compilation unit.  If we are doing function sections, then we need
      an entry per section, since we can't rely on reachability.  */
-  if (in_section == text_section)
+  if (casm->in_section == casm->sec.text)
     {
       thumb_call_reg_needed = 1;
 
@@ -28278,7 +28278,7 @@ arm_file_end (void)
   if (! thumb_call_reg_needed)
     return;
 
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
   asm_fprintf (asm_out_file, "\t.code 16\n");
   ASM_OUTPUT_ALIGN (asm_out_file, 1);
 
@@ -29728,13 +29728,13 @@ static void
 arm_asm_init_sections (void)
 {
 #if ARM_UNWIND_INFO
-  exception_section = get_unnamed_section (0, output_section_asm_op,
+  casm->sec.exception = get_unnamed_section (0, output_section_asm_op,
 					   "\t.handlerdata");
 #endif /* ARM_UNWIND_INFO */
 
 #ifdef OBJECT_FORMAT_ELF
   if (target_pure_code)
-    text_section->unnamed.data = "\t.section .text,\"0x20000006\",%progbits";
+    casm->sec.text->unnamed.data = "\t.section .text,\"0x20000006\",%progbits";
 #endif
 }
 
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 015299c1534..845b965f75f 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -1613,7 +1613,7 @@ machine_function;
 #define ARM_GE_BITS_READ (arm_ge_bits_access ())
 
 /* As in the machine_function, a global set of call-via labels, for code 
-   that is in text_section.  */
+   that is in casm->sec.text.  */
 extern GTY(()) rtx thumb_call_via_label[14];
 
 /* The number of potential ways of assigning to a co-processor.  */
diff --git a/gcc/config/arm/unknown-elf.h b/gcc/config/arm/unknown-elf.h
index cca6f0ece54..6aba52284c3 100644
--- a/gcc/config/arm/unknown-elf.h
+++ b/gcc/config/arm/unknown-elf.h
@@ -61,7 +61,7 @@
       if (IN_NAMED_SECTION_P (DECL))					\
 	switch_to_section (get_named_section (DECL, NULL, 0));		\
       else								\
-	switch_to_section (bss_section);				\
+	switch_to_section (casm->sec.bss);				\
       									\
       ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT));	\
 									\
@@ -78,7 +78,7 @@
       if ((DECL) != NULL && IN_NAMED_SECTION_P (DECL))			\
 	switch_to_section (get_named_section (DECL, NULL, 0));		\
       else								\
-	switch_to_section (bss_section);				\
+	switch_to_section (casm->sec.bss);				\
 									\
       ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT));	\
       ASM_OUTPUT_LABEL (FILE, NAME);					\
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 200701a583c..c89e7b610ea 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -10085,7 +10085,7 @@ avr_asm_asm_output_aligned_bss (FILE *file, tree decl, const char *name,
 }
 
 
-/* Unnamed section callback for data_section
+/* Unnamed section callback for casm->sec.data
    to track need of __do_copy_data.  */
 
 static void
@@ -10098,7 +10098,7 @@ avr_output_data_section_asm_op (const void *data)
 }
 
 
-/* Unnamed section callback for bss_section
+/* Unnamed section callback for casm->sec.bss
    to track need of __do_clear_bss.  */
 
 static void
@@ -10133,9 +10133,9 @@ avr_asm_init_sections (void)
 #if defined HAVE_LD_AVR_AVRXMEGA3_RODATA_IN_FLASH
   if (avr_arch->flash_pm_offset == 0)
 #endif
-    readonly_data_section->unnamed.callback = avr_output_data_section_asm_op;
-  data_section->unnamed.callback = avr_output_data_section_asm_op;
-  bss_section->unnamed.callback = avr_output_bss_section_asm_op;
+    casm->sec.readonly_data->unnamed.callback = avr_output_data_section_asm_op;
+  casm->sec.data->unnamed.callback = avr_output_data_section_asm_op;
+  casm->sec.bss->unnamed.callback = avr_output_bss_section_asm_op;
 }
 
 
@@ -12567,7 +12567,7 @@ avr_output_addr_vec (rtx_insn *labl, rtx table)
   // Switch back to original section.  As we clobbered the section above,
   // forget the current section before switching back.
 
-  in_section = NULL;
+  casm->in_section = NULL;
   switch_to_section (current_function_section ());
 }
 
diff --git a/gcc/config/bfin/bfin.h b/gcc/config/bfin/bfin.h
index 823ca2d7124..4aaee42e0e6 100644
--- a/gcc/config/bfin/bfin.h
+++ b/gcc/config/bfin/bfin.h
@@ -1053,7 +1053,7 @@ do { char __buf[256];					\
 
 #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) 	\
 do { 						\
-    switch_to_section (data_section);				\
+    switch_to_section (casm->sec.data);				\
     if ((SIZE) >= (unsigned int) 4 ) ASM_OUTPUT_ALIGN(FILE,2);	\
     ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);		\
     ASM_OUTPUT_LABEL (FILE, NAME);				\
diff --git a/gcc/config/c6x/c6x.c b/gcc/config/c6x/c6x.c
index 4854371ee13..33bb40f51aa 100644
--- a/gcc/config/c6x/c6x.c
+++ b/gcc/config/c6x/c6x.c
@@ -891,7 +891,7 @@ c6x_select_rtx_section (machine_mode mode, rtx x,
   if (c6x_sdata_mode == C6X_SDATA_ALL
       || (c6x_sdata_mode != C6X_SDATA_NONE && GET_MODE_SIZE (mode) <= 8))
     /* ??? Consider using mergeable sdata sections.  */
-    return sdata_section;
+    return casm->sec.sdata;
   else
     return default_elf_select_rtx_section (mode, x, align);
 }
@@ -5474,7 +5474,7 @@ c6x_asm_emit_except_personality (rtx personality)
 static void
 c6x_asm_init_sections (void)
 {
-  exception_section = get_unnamed_section (0, output_section_asm_op,
+  casm->sec.exception = get_unnamed_section (0, output_section_asm_op,
 					   "\t.handlerdata");
 }
 
diff --git a/gcc/config/c6x/c6x.h b/gcc/config/c6x/c6x.h
index 9e0a20d20cb..4b9ec51bd72 100644
--- a/gcc/config/c6x/c6x.h
+++ b/gcc/config/c6x/c6x.h
@@ -557,9 +557,9 @@ do { char __buf[256];					\
 #define ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN)	\
 do {									\
   if (PLACE_IN_SDATA_P (DECL))						\
-    switch_to_section (sbss_section);					\
+    switch_to_section (casm->sec.sbss);					\
   else									\
-    switch_to_section (bss_section);					\
+    switch_to_section (casm->sec.bss);					\
   ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
   if (!flag_inhibit_size_directive)					\
     ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);			\
diff --git a/gcc/config/csky/csky.c b/gcc/config/csky/csky.c
index 487288b3292..24c97a5e830 100644
--- a/gcc/config/csky/csky.c
+++ b/gcc/config/csky/csky.c
@@ -959,7 +959,7 @@ get_csky_jump_table_size (rtx insn)
 {
   /* ADDR_VECs only take room if read-only data does into the text
      section.  */
-  if (JUMP_TABLES_IN_TEXT_SECTION || readonly_data_section == text_section)
+  if (JUMP_TABLES_IN_TEXT_SECTION || casm->sec.readonly_data == casm->sec.text)
     {
       rtx body = PATTERN (insn);
       int elt = GET_CODE (body) == ADDR_DIFF_VEC ? 1 : 0;
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index 204114c96a2..90ce237cfa5 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -144,7 +144,7 @@ output_objc_section_asm_op (const void *directive)
      section is requested.  */
   if (darwin_symbol_stubs && ! been_here)
     {
-      section *saved_in_section = in_section;
+      section *saved_in_section = casm->in_section;
       static const enum darwin_section_enum tomark[] =
 	{
 	  /* written, cold -> hot */
@@ -237,14 +237,14 @@ darwin_init_sections (void)
 #include "config/darwin-sections.def"
 #undef DEF_SECTION
 
-  readonly_data_section = darwin_sections[const_section];
-  exception_section = darwin_sections[darwin_exception_section];
-  eh_frame_section = darwin_sections[darwin_eh_frame_section];
+  casm->sec.readonly_data = darwin_sections[const_section];
+  casm->sec.exception = darwin_sections[darwin_exception_section];
+  casm->sec.eh_frame = darwin_sections[darwin_eh_frame_section];
 
   /* If our linker is new enough to coalesce weak symbols, then we
      can just put picbase_thunks into the text section.  */
   if (! ld_uses_coal_sects )
-    darwin_sections[picbase_thunk_section] = text_section;
+    darwin_sections[picbase_thunk_section] = casm->sec.text;
 }
 
 int
@@ -1072,7 +1072,7 @@ machopic_output_data_section_indirection (machopic_indirection **slot,
   /* The name of the indirection symbol.  */
   const char *ptr_name = p->ptr_name;
 
-  switch_to_section (data_section);
+  switch_to_section (casm->sec.data);
   assemble_align (GET_MODE_ALIGNMENT (Pmode));
   assemble_label (out_file, ptr_name);
   assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
@@ -1341,7 +1341,7 @@ darwin_mergeable_string_section (tree exp,
       && TREE_STRING_LENGTH (exp) == 0)
     return darwin_sections[zobj_const_section];
 
-  return readonly_data_section;
+  return casm->sec.readonly_data;
 }
 
 #ifndef HAVE_GAS_LITERAL16
@@ -1363,7 +1363,7 @@ darwin_mergeable_constant_section (tree exp,
       || align < 8
       || align > 256
       || (align & (align -1)) != 0)
-    return readonly_data_section;
+    return casm->sec.readonly_data;
 
   /* This will ICE if the mode is not a constant size, but that is reasonable,
      since one cannot put a variable-sized thing into a constant section, we
@@ -1371,12 +1371,12 @@ darwin_mergeable_constant_section (tree exp,
   const unsigned int modesize = GET_MODE_BITSIZE (mode).to_constant ();
 
   if (modesize > align)
-    return readonly_data_section;
+    return casm->sec.readonly_data;
 
   tree size = TYPE_SIZE_UNIT (TREE_TYPE (exp));
 
   if (TREE_CODE (size) != INTEGER_CST)
-    return readonly_data_section;
+    return casm->sec.readonly_data;
 
   unsigned isize = TREE_INT_CST_LOW (size);
   if (isize == 4)
@@ -1388,7 +1388,7 @@ darwin_mergeable_constant_section (tree exp,
 	   && isize == 16)
     return darwin_sections[literal16_section];
 
-  return readonly_data_section;
+  return casm->sec.readonly_data;
 }
 
 section *
@@ -1444,7 +1444,7 @@ darwin_objc2_section (tree decl ATTRIBUTE_UNUSED, tree meta, section * base)
 
   objc_metadata_seen = 1;
 
-  if (base == data_section)
+  if (base == casm->sec.data)
     base = darwin_sections[objc2_metadata_section];
 
   /* Most of the OBJC2 META-data end up in the base section, so check it
@@ -1495,7 +1495,7 @@ darwin_objc2_section (tree decl ATTRIBUTE_UNUSED, tree meta, section * base)
 
   else if (startswith (p, "V2_EHTY"))
     return ld_uses_coal_sects ? darwin_sections[data_coal_section]
-                              : data_section;
+                              : casm->sec.data;
 
   else if (startswith (p, "V2_CSTR"))
     return darwin_sections[objc2_constant_string_object_section];
@@ -1681,7 +1681,7 @@ machopic_select_section (tree decl,
       else if (ro)
 	base_section = darwin_sections[const_data_section];
       else
-	base_section = data_section;
+	base_section = casm->sec.data;
       break;
     case SECCAT_BSS:
     case SECCAT_SBSS:
@@ -1691,11 +1691,11 @@ machopic_select_section (tree decl,
       else
 	{
 	  if (!TREE_PUBLIC (decl))
-	    base_section = lcomm_section;
-	  else if (bss_noswitch_section)
-	    base_section = bss_noswitch_section;
+	    base_section = casm->sec.lcomm;
+	  else if (casm->sec.bss_noswitch)
+	    base_section = casm->sec.bss_noswitch;
 	  else
-	    base_section = data_section;
+	    base_section = casm->sec.data;
 	}
       break;
 
@@ -2366,8 +2366,8 @@ fprintf (file, "# dadon: %s %s (%llu, %u) local %d weak %d"
       /* Check that we've correctly picked up the zero-sized item and placed it
          properly.  */
       gcc_assert ((!DARWIN_SECTION_ANCHORS || !flag_section_anchors)
-		  || (in_section
-		      && (in_section->common.flags & SECTION_NO_ANCHOR)));
+		  || (casm->in_section
+		      && (casm->in_section->common.flags & SECTION_NO_ANCHOR)));
     }
   else
     ASM_OUTPUT_LABEL (file, xname);
@@ -2387,8 +2387,8 @@ darwin_asm_declare_constant_name (FILE *file, const char *name,
       /* Check that we've correctly picked up the zero-sized item and placed it
          properly.  */
       gcc_assert ((!DARWIN_SECTION_ANCHORS || !flag_section_anchors)
-		  || (in_section
-		      && (in_section->common.flags & SECTION_NO_ANCHOR)));
+		  || (casm->in_section
+		      && (casm->in_section->common.flags & SECTION_NO_ANCHOR)));
     }
 }
 
@@ -2425,7 +2425,7 @@ darwin_emit_weak_or_comdat (FILE *fp, tree decl, const char *name,
 				: darwin_sections[const_data_section]);
   else
     switch_to_section (use_coal ? darwin_sections[data_coal_section]
-				: data_section);
+				: casm->sec.data);
 
   /* To be consistent, we'll allow darwin_asm_declare_object_name to assemble
      the align info for zero-sized items... but do it here otherwise.  */
@@ -2447,7 +2447,7 @@ darwin_emit_objc_zeroed (FILE *fp, tree decl, const char *name,
 				  unsigned HOST_WIDE_INT size,
 				  unsigned int align, tree meta)
 {
-  section *ocs = data_section;
+  section *ocs = casm->sec.data;
 
   if (TREE_PURPOSE (meta) == get_identifier("OBJC2META"))
     ocs = darwin_objc2_section (decl, meta, ocs);
@@ -2489,13 +2489,13 @@ darwin_emit_local_bss (FILE *fp, tree decl, const char *name,
       if (!size)
 	{
 	  fputs ("\t.section\t__DATA,__zobj_bss\n", fp);
-	  in_section = darwin_sections[zobj_bss_section];
+	  casm->in_section = darwin_sections[zobj_bss_section];
 	  size = 1;
 	}
       else
 	{
 	  fputs ("\t.static_data\n", fp);
-	  in_section = darwin_sections[static_data_section];
+	  casm->in_section = darwin_sections[static_data_section];
 	}
 
       if (l2align)
@@ -2513,7 +2513,7 @@ darwin_emit_local_bss (FILE *fp, tree decl, const char *name,
       char secnam[64];
       snprintf (secnam, 64, "__DATA,__bss");
       unsigned int flags = SECTION_BSS|SECTION_WRITE|SECTION_NO_ANCHOR;
-      in_section = get_section (secnam, flags, NULL);
+      casm->in_section = get_section (secnam, flags, NULL);
       fprintf (fp, "\t.zerofill %s,", secnam);
       assemble_name (fp, name);
       if (!size)
@@ -2560,7 +2560,7 @@ darwin_emit_common (FILE *fp, const char *name,
   l2align = floor_log2 (align);
   gcc_assert (l2align <= L2_MAX_OFILE_ALIGNMENT);
 
-  in_section = comm_section;
+  casm->in_section = casm->sec.comm;
   /* We mustn't allow multiple public symbols to share an address when using
      the normal OSX toolchain.  */
   if (!size)
@@ -2568,7 +2568,7 @@ darwin_emit_common (FILE *fp, const char *name,
       /* Put at least one byte.  */
       size = 1;
       /* This section can no longer participate in section anchoring.  */
-      comm_section->common.flags |= SECTION_NO_ANCHOR;
+      casm->sec.comm->common.flags |= SECTION_NO_ANCHOR;
     }
 
   fputs ("\t.comm\t", fp);
@@ -2657,13 +2657,13 @@ fprintf (fp, "# albss: %s (%lld,%d) ro %d cst %d stat %d com %d"
       if (!size)
 	{
 	  fputs ("\t.section\t__DATA,__zobj_data\n", fp);
-	  in_section = darwin_sections[zobj_data_section];
+	  casm->in_section = darwin_sections[zobj_data_section];
 	  size = 1;
 	}
       else
 	{
 	  fputs ("\t.data\n", fp);
-	  in_section = data_section;
+	  casm->in_section = casm->sec.data;
 	}
 
       if (l2align)
@@ -2678,7 +2678,7 @@ fprintf (fp, "# albss: %s (%lld,%d) ro %d cst %d stat %d com %d"
       unsigned int flags = SECTION_BSS|SECTION_WRITE|SECTION_NO_ANCHOR;
       char secnam[64];
       snprintf (secnam, 64, "__DATA,__common");
-      in_section = get_section (secnam, flags, NULL);
+      casm->in_section = get_section (secnam, flags, NULL);
       fprintf (fp, "\t.zerofill %s,", secnam);
       assemble_name (fp, name);
       if (!size)
@@ -3894,7 +3894,7 @@ darwin_function_section (tree decl, enum node_frequency freq,
   /* Otherwise, default to the 'normal' non-reordered sections.  */
 default_function_sections:
   return (use_coal) ? darwin_sections[text_coal_section]
-		    : text_section;
+		    : casm->sec.text;
 }
 
 #include "gt-darwin.h"
diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c
index 02cd07c09bc..af459c0e5b4 100644
--- a/gcc/config/frv/frv.c
+++ b/gcc/config/frv/frv.c
@@ -9396,7 +9396,7 @@ frv_rtx_costs (rtx x,
 static void
 frv_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
 {
-  switch_to_section (ctors_section);
+  switch_to_section (casm->sec.ctors);
   assemble_align (POINTER_SIZE);
   if (TARGET_FDPIC)
     {
@@ -9411,7 +9411,7 @@ frv_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
 static void
 frv_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
 {
-  switch_to_section (dtors_section);
+  switch_to_section (casm->sec.dtors);
   assemble_align (POINTER_SIZE);
   if (TARGET_FDPIC)
     {
diff --git a/gcc/config/frv/frv.h b/gcc/config/frv/frv.h
index 65091952ebd..6fd072c25d8 100644
--- a/gcc/config/frv/frv.h
+++ b/gcc/config/frv/frv.h
@@ -1540,7 +1540,7 @@ do {                                                                   	\
   if ((SIZE) > 0 && (SIZE) <= (unsigned HOST_WIDE_INT) g_switch_value)	\
     switch_to_section (get_named_section (NULL, ".sbss", 0));           \
   else                                                                 	\
-    switch_to_section (bss_section);                                  	\
+    switch_to_section (casm->sec.bss);                                  	\
   ASM_OUTPUT_ALIGN (STREAM, floor_log2 ((ALIGN) / BITS_PER_UNIT));     	\
   ASM_DECLARE_OBJECT_NAME (STREAM, NAME, DECL);                        	\
   ASM_OUTPUT_SKIP (STREAM, (SIZE) ? (SIZE) : 1);                       	\
diff --git a/gcc/config/ft32/ft32.h b/gcc/config/ft32/ft32.h
index f8d0763e394..8e2b0667b64 100644
--- a/gcc/config/ft32/ft32.h
+++ b/gcc/config/ft32/ft32.h
@@ -478,9 +478,9 @@ extern int ft32_is_mem_pm(rtx o);
 #define ASM_OUTPUT_SYMBOL_REF(stream, sym) \
   do { \
     assemble_name (stream, XSTR (sym, 0)); \
-    int section_debug = in_section && \
-      (SECTION_STYLE (in_section) == SECTION_NAMED) && \
-      (in_section->named.common.flags & SECTION_DEBUG); \
+    int section_debug = casm->in_section && \
+      (SECTION_STYLE (casm->in_section) == SECTION_NAMED) && \
+      (casm->in_section->named.common.flags & SECTION_DEBUG); \
     if (!section_debug && SYMBOL_REF_FLAGS (sym) & 0x1000) \
       asm_fprintf (stream, "-0x800000"); \
   } while (0)
diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h
index da872d10cd3..2826d2c35c6 100644
--- a/gcc/config/i386/cygming.h
+++ b/gcc/config/i386/cygming.h
@@ -187,7 +187,7 @@ along with GCC; see the file COPYING3.  If not see
 \f
 #define drectve_section() \
   (fprintf (asm_out_file, "\t.section .drectve\n"), \
-   in_section = NULL)
+   casm->in_section = NULL)
 
 /* Older versions of gas don't handle 'r' as data.
    Explicitly set data flag with 'd'.  */  
diff --git a/gcc/config/i386/darwin.h b/gcc/config/i386/darwin.h
index 741f29aa962..82addaa6e8d 100644
--- a/gcc/config/i386/darwin.h
+++ b/gcc/config/i386/darwin.h
@@ -217,7 +217,7 @@ along with GCC; see the file COPYING3.  If not see
   do {								   \
     if ((LOG) != 0)						   \
       {								   \
-	if (in_section == text_section)				   \
+	if (casm->in_section == casm->sec.text)				   \
 	  fprintf (FILE, "\t%s %d,0x90\n", ALIGN_ASM_OP, (LOG));   \
 	else							   \
 	  fprintf (FILE, "\t%s %d\n", ALIGN_ASM_OP, (LOG));	   \
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 299e1ab2621..a5f79d2e083 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -869,7 +869,7 @@ x86_output_aligned_bss (FILE *file, tree decl, const char *name,
       && size > (unsigned int)ix86_section_threshold)
     switch_to_section (get_named_section (decl, ".lbss", 0));
   else
-    switch_to_section (bss_section);
+    switch_to_section (casm->sec.bss);
   ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
 #ifdef ASM_DECLARE_OBJECT_NAME
   last_assemble_variable_decl = decl;
@@ -5968,7 +5968,7 @@ output_indirect_thunk_function (enum indirect_thunk_prefix need_prefix,
       }
     else
       {
-	switch_to_section (text_section);
+	switch_to_section (casm->sec.text);
 	ASM_OUTPUT_LABEL (asm_out_file, name);
       }
 
@@ -6088,7 +6088,7 @@ ix86_code_end (void)
 	}
       else
 	{
-	  switch_to_section (text_section);
+	  switch_to_section (casm->sec.text);
 	  ASM_OUTPUT_LABEL (asm_out_file, name);
 	}
 
diff --git a/gcc/config/i386/sol2.h b/gcc/config/i386/sol2.h
index 29b37a143f5..7297db2bb70 100644
--- a/gcc/config/i386/sol2.h
+++ b/gcc/config/i386/sol2.h
@@ -195,9 +195,9 @@ along with GCC; see the file COPYING3.  If not see
   do									\
     {									\
       if (TARGET_SUN_TLS						\
-	  && in_section							\
-	  && ((in_section->common.flags & SECTION_TLS) == SECTION_TLS))	\
-	switch_to_section (bss_section);				\
+	  && casm->in_section							\
+	  && ((casm->in_section->common.flags & SECTION_TLS) == SECTION_TLS))	\
+	switch_to_section (casm->sec.bss);				\
       x86_elf_aligned_decl_common (FILE, DECL, NAME, SIZE, ALIGN);	\
     }									\
   while  (0)
diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c
index 7c0ea4f731c..a25412ddf30 100644
--- a/gcc/config/i386/winnt.c
+++ b/gcc/config/i386/winnt.c
@@ -1347,7 +1347,7 @@ void
 i386_pe_seh_init_sections (void)
 {
   if (TARGET_SEH)
-    exception_section = get_unnamed_section (0, output_section_asm_op,
+    casm->sec.exception = get_unnamed_section (0, output_section_asm_op,
 					     "\t.seh_handlerdata");
 }
 \f
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index 96c0efb4afd..0d8166be256 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -10406,7 +10406,7 @@ ia64_asm_emit_except_personality (rtx personality)
 static void
 ia64_asm_init_sections (void)
 {
-  exception_section = get_unnamed_section (0, output_section_asm_op,
+  casm->sec.exception = get_unnamed_section (0, output_section_asm_op,
 					   "\t.handlerdata");
 }
 
@@ -10858,7 +10858,7 @@ ia64_select_rtx_section (machine_mode mode, rtx x,
   if (GET_MODE_SIZE (mode) > 0
       && GET_MODE_SIZE (mode) <= ia64_section_threshold
       && !TARGET_NO_SDATA)
-    return sdata_section;
+    return casm->sec.sdata;
   else
     return default_elf_select_rtx_section (mode, x, align);
 }
diff --git a/gcc/config/ia64/sysv4.h b/gcc/config/ia64/sysv4.h
index a4133d3beab..a68f28074fb 100644
--- a/gcc/config/ia64/sysv4.h
+++ b/gcc/config/ia64/sysv4.h
@@ -69,9 +69,9 @@ extern int size_directive_output;
 #define ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN) \
 do {									\
   if ((DECL) && sdata_symbolic_operand (XEXP (DECL_RTL (DECL), 0), Pmode)) \
-    switch_to_section (sbss_section);					\
+    switch_to_section (casm->sec.sbss);					\
   else									\
-    switch_to_section (bss_section);					\
+    switch_to_section (casm->sec.bss);					\
   ASM_OUTPUT_ALIGN (FILE, floor_log2 ((ALIGN) / BITS_PER_UNIT));	\
   ASM_DECLARE_OBJECT_NAME (FILE, NAME, DECL);				\
   ASM_OUTPUT_SKIP (FILE, SIZE ? SIZE : 1);				\
diff --git a/gcc/config/lm32/lm32.h b/gcc/config/lm32/lm32.h
index a13c0c50ee1..d665c38f0e3 100644
--- a/gcc/config/lm32/lm32.h
+++ b/gcc/config/lm32/lm32.h
@@ -385,9 +385,9 @@ enum reg_class
 #define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)		\
 do {									\
   if ((SIZE) <= (unsigned HOST_WIDE_INT) g_switch_value)		\
-    switch_to_section (sbss_section);					\
+    switch_to_section (casm->sec.sbss);					\
   else									\
-    switch_to_section (bss_section);					\
+    switch_to_section (casm->sec.bss);					\
   ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
   if (!flag_inhibit_size_directive)					\
     ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);			\
@@ -403,7 +403,7 @@ do 									\
 {									\
   if ((SIZE) <= (unsigned HOST_WIDE_INT) g_switch_value)		\
     {									\
-      switch_to_section (sbss_section);					\
+      switch_to_section (casm->sec.sbss);					\
       (*targetm.asm_out.globalize_label) (FILE, NAME);			\
       ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
       if (!flag_inhibit_size_directive)					\
@@ -414,7 +414,7 @@ do 									\
     }									\
   else									\
     {									\
-      switch_to_section (bss_section);					\
+      switch_to_section (casm->sec.bss);					\
       fprintf ((FILE), "%s", COMMON_ASM_OP);				\
       assemble_name ((FILE), (NAME));					\
       fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED",%u\n",          \
diff --git a/gcc/config/m32r/m32r.h b/gcc/config/m32r/m32r.h
index 047805fd808..64b5f69f3a7 100644
--- a/gcc/config/m32r/m32r.h
+++ b/gcc/config/m32r/m32r.h
@@ -897,7 +897,7 @@ L2:     .word STATIC
 	  && (SIZE) <= (unsigned HOST_WIDE_INT) g_switch_value)		\
         switch_to_section (get_named_section (NULL, ".sbss", 0));	\
       else								\
-        switch_to_section (bss_section);				\
+        switch_to_section (casm->sec.bss);				\
       ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT));	\
       last_assemble_variable_decl = DECL;				\
       ASM_DECLARE_OBJECT_NAME (FILE, NAME, DECL);			\
diff --git a/gcc/config/mcore/mcore-elf.h b/gcc/config/mcore/mcore-elf.h
index d50f578c3dd..02278eec3c3 100644
--- a/gcc/config/mcore/mcore-elf.h
+++ b/gcc/config/mcore/mcore-elf.h
@@ -33,7 +33,7 @@ along with GCC; see the file COPYING3.  If not see
       fprintf (STREAM, "\t.section .exports\n");	\
       fprintf (STREAM, "\t.ascii \" -export:%s\"\n",	\
 	       (* targetm.strip_name_encoding) (NAME));	\
-      in_section = NULL;				\
+      casm->in_section = NULL;				\
     }							\
   while (0)
 
@@ -63,7 +63,7 @@ along with GCC; see the file COPYING3.  If not see
       HOST_WIDE_INT size;					\
       if (mcore_dllexport_name_p (NAME))			\
         {							\
-	  section *save_section = in_section;			\
+	  section *save_section = casm->in_section;			\
 	  MCORE_EXPORT_NAME (FILE, NAME);			\
 	  switch_to_section (save_section);			\
         }							\
diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c
index 4813f7a7921..1e148c0b30a 100644
--- a/gcc/config/microblaze/microblaze.c
+++ b/gcc/config/microblaze/microblaze.c
@@ -2837,9 +2837,9 @@ microblaze_elf_asm_cdtor (rtx symbol, int priority, bool is_ctor)
       s = get_section (buf, SECTION_WRITE, NULL_TREE);
     }
   else if (is_ctor)
-    s = ctors_section;
+    s = casm->sec.ctors;
   else
-    s = dtors_section;
+    s = casm->sec.dtors;
 
   switch_to_section (s);
   assemble_align (POINTER_SIZE);
@@ -3262,7 +3262,7 @@ microblaze_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
          relaxation/relocation. Currently, turning mergeable sections 
          into regular readonly sections.  */
 
-      return readonly_data_section;
+      return casm->sec.readonly_data;
     default:
       return default_elf_select_section (decl, reloc, align);
     }
diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h
index 2ecec750526..3f1368d0884 100644
--- a/gcc/config/microblaze/microblaze.h
+++ b/gcc/config/microblaze/microblaze.h
@@ -623,11 +623,11 @@ do {									\
       && (int) (SIZE) <= microblaze_section_threshold			\
       && TARGET_XLGPOPT)						\
     {                                                                   \
-      switch_to_section (sbss_section);					\
+      switch_to_section (casm->sec.sbss);					\
     }									\
   else									\
     {									\
-      switch_to_section (bss_section);					\
+      switch_to_section (casm->sec.bss);					\
     }                                                                   \
   fprintf (FILE, "%s", COMMON_ASM_OP);                                  \
   assemble_name ((FILE), (NAME));					\
@@ -643,11 +643,11 @@ do {									\
       && (int) (SIZE) <= microblaze_section_threshold			\
       && TARGET_XLGPOPT)						\
     {                                                                   \
-      switch_to_section (sbss_section);					\
+      switch_to_section (casm->sec.sbss);					\
     }									\
   else									\
     {									\
-      switch_to_section (bss_section);					\
+      switch_to_section (casm->sec.bss);					\
     }                                                                   \
   fprintf (FILE, "%s", LCOMMON_ASM_OP);                                 \
   assemble_name ((FILE), (NAME));					\
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 807bf1a78d4..f119bcfbe87 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -9719,7 +9719,7 @@ mips_output_aligned_decl_common (FILE *stream, tree decl, const char *name,
       if (TREE_PUBLIC (decl) && DECL_NAME (decl))
 	targetm.asm_out.globalize_label (stream, name);
 
-      switch_to_section (readonly_data_section);
+      switch_to_section (casm->sec.readonly_data);
       ASM_OUTPUT_ALIGN (stream, floor_log2 (align / BITS_PER_UNIT));
       mips_declare_object (stream, name, "",
 			   ":\n\t.space\t" HOST_WIDE_INT_PRINT_UNSIGNED "\n",
diff --git a/gcc/config/mmix/mmix.c b/gcc/config/mmix/mmix.c
index 010cd4773ea..4ea07819983 100644
--- a/gcc/config/mmix/mmix.c
+++ b/gcc/config/mmix/mmix.c
@@ -1321,7 +1321,7 @@ mmix_file_start (void)
   fputs ("! mmixal:= 8H LOC Data_Section\n", asm_out_file);
 
   /* Make sure each file starts with the text section.  */
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
 }
 
 /* TARGET_ASM_FILE_END.  */
@@ -1330,7 +1330,7 @@ static void
 mmix_file_end (void)
 {
   /* Make sure each file ends with the data section.  */
-  switch_to_section (data_section);
+  switch_to_section (casm->sec.data);
 }
 
 /* TARGET_ASM_OUTPUT_SOURCE_FILENAME.  */
@@ -1510,7 +1510,7 @@ mmix_asm_output_aligned_local (FILE *stream,
 			       int size,
 			       int align)
 {
-  switch_to_section (data_section);
+  switch_to_section (casm->sec.data);
 
   ASM_OUTPUT_ALIGN (stream, exact_log2 (align/BITS_PER_UNIT));
   assemble_name (stream, name);
diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c
index 1cdacb7f480..ba41ce1f54a 100644
--- a/gcc/config/msp430/msp430.c
+++ b/gcc/config/msp430/msp430.c
@@ -2398,22 +2398,22 @@ msp430_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
     {
     case SECCAT_TEXT:
       if (!prefix)
-	return text_section;
+	return casm->sec.text;
       base_sec_name = ".text";
       break;
     case SECCAT_DATA:
       if (!prefix)
-	return data_section;
+	return casm->sec.data;
       base_sec_name = ".data";
       break;
     case SECCAT_BSS:
       if (!prefix)
-	return bss_section;
+	return casm->sec.bss;
       base_sec_name = ".bss";
       break;
     case SECCAT_RODATA:
       if (!prefix)
-	return readonly_data_section;
+	return casm->sec.readonly_data;
       base_sec_name = ".rodata";
       break;
 
diff --git a/gcc/config/nios2/nios2.h b/gcc/config/nios2/nios2.h
index dfca12cc525..c2da347062b 100644
--- a/gcc/config/nios2/nios2.h
+++ b/gcc/config/nios2/nios2.h
@@ -470,9 +470,9 @@ while (0)
 #define ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN)	\
 do {                                                                    \
  if (targetm.in_small_data_p (DECL))					\
-    switch_to_section (sbss_section);					\
+    switch_to_section (casm->sec.sbss);					\
   else                                                                  \
-    switch_to_section (bss_section);					\
+    switch_to_section (casm->sec.bss);					\
   ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");                     \
   if (!flag_inhibit_size_directive)                                     \
     ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);                       \
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 21b812e9be7..837623edfe9 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -4454,7 +4454,7 @@ pa_output_function_epilogue (FILE *file)
       /* We are done with this subspace except possibly for some additional
 	 debug information.  Forget that we are in this subspace to ensure
 	 that the next function is output in its own subspace.  */
-      in_section = NULL;
+      casm->in_section = NULL;
       cfun->machine->in_nsubspa = 2;
     }
 
@@ -4703,7 +4703,7 @@ output_deferred_profile_counters (void)
   if (funcdef_nos.is_empty ())
    return;
 
-  switch_to_section (data_section);
+  switch_to_section (casm->sec.data);
   align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE);
   ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
 
@@ -5873,7 +5873,7 @@ output_deferred_plabels (void)
      before outputting the deferred plabels.  */
   if (n_deferred_plabels)
     {
-      switch_to_section (flag_pic ? data_section : readonly_data_section);
+      switch_to_section (flag_pic ? casm->sec.data : casm->sec.readonly_data);
       ASM_OUTPUT_ALIGN (asm_out_file, TARGET_64BIT ? 3 : 2);
     }
 
@@ -8882,7 +8882,7 @@ pa_asm_output_mi_thunk (FILE *file, tree thunk_fndecl, HOST_WIDE_INT delta,
 
   if (TARGET_SOM && flag_pic && TREE_PUBLIC (function))
     {
-      switch_to_section (data_section);
+      switch_to_section (casm->sec.data);
       output_asm_insn (".align 4", xoperands);
       ASM_OUTPUT_LABEL (file, label);
       output_asm_insn (".word P'%0", xoperands);
@@ -9057,7 +9057,7 @@ pa_asm_output_aligned_bss (FILE *stream,
 			   unsigned HOST_WIDE_INT size,
 			   unsigned int align)
 {
-  switch_to_section (bss_section);
+  switch_to_section (casm->sec.bss);
 
 #ifdef ASM_OUTPUT_TYPE_DIRECTIVE
   ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "object");
@@ -9094,7 +9094,7 @@ pa_asm_output_aligned_common (FILE *stream,
       align = max_common_align;
     }
 
-  switch_to_section (bss_section);
+  switch_to_section (casm->sec.bss);
 
   assemble_name (stream, name);
   fprintf (stream, "\t.comm " HOST_WIDE_INT_PRINT_UNSIGNED"\n",
@@ -9114,7 +9114,7 @@ pa_asm_output_aligned_local (FILE *stream,
 			     unsigned HOST_WIDE_INT size,
 			     unsigned int align)
 {
-  switch_to_section (bss_section);
+  switch_to_section (casm->sec.bss);
   fprintf (stream, "\t.align %u\n", align / BITS_PER_UNIT);
 
 #ifdef LOCAL_ASM_OP
@@ -10040,10 +10040,10 @@ som_output_text_section_asm_op (const void *data ATTRIBUTE_UNUSED)
 	     function has been completed.  So, we are changing to the
 	     text section to output debugging information.  Thus, we
 	     need to forget that we are in the text section so that
-	     varasm.c will call us when text_section is selected again.  */
+	     varasm.c will call us when casm->sec.text is selected again.  */
 	  gcc_assert (!cfun || !cfun->machine
 		      || cfun->machine->in_nsubspa == 2);
-	  in_section = NULL;
+	  casm->in_section = NULL;
 	}
       output_section_asm_op ("\t.SPACE $TEXT$\n\t.NSUBSPA $CODE$");
       return;
@@ -10057,7 +10057,7 @@ som_output_text_section_asm_op (const void *data ATTRIBUTE_UNUSED)
 static void
 som_output_comdat_data_section_asm_op (const void *data)
 {
-  in_section = NULL;
+  casm->in_section = NULL;
   output_section_asm_op (data);
 }
 
@@ -10066,7 +10066,7 @@ som_output_comdat_data_section_asm_op (const void *data)
 static void
 pa_som_asm_init_sections (void)
 {
-  text_section
+  casm->sec.text
     = get_unnamed_section (0, som_output_text_section_asm_op, NULL);
 
   /* SOM puts readonly data in the default $LIT$ subspace when PIC code
@@ -10114,14 +10114,14 @@ pa_som_asm_init_sections (void)
      when generating PIC code.  This reduces sharing, but it works
      correctly.  Now we rely on pa_reloc_rw_mask() for section selection.
      This puts constant data not needing relocation into the $TEXT$ space.  */
-  readonly_data_section = som_readonly_data_section;
+  casm->sec.readonly_data = som_readonly_data_section;
 
   /* We must not have a reference to an external symbol defined in a
      shared library in a readonly section, else the SOM linker will
      complain.
 
      So, we force exception information into the data section.  */
-  exception_section = data_section;
+  casm->sec.exception = casm->sec.data;
 }
 
 /* Implement TARGET_ASM_TM_CLONE_TABLE_SECTION.  */
@@ -10154,18 +10154,18 @@ pa_select_section (tree exp, int reloc,
 	  && !DECL_WEAK (exp))
 	return som_one_only_readonly_data_section;
       else
-	return readonly_data_section;
+	return casm->sec.readonly_data;
     }
   else if (CONSTANT_CLASS_P (exp)
 	   && !(reloc & pa_reloc_rw_mask ()))
-    return readonly_data_section;
+    return casm->sec.readonly_data;
   else if (TARGET_SOM
 	   && TREE_CODE (exp) == VAR_DECL
 	   && DECL_ONE_ONLY (exp)
 	   && !DECL_WEAK (exp))
     return som_one_only_data_section;
   else
-    return data_section;
+    return casm->sec.data;
 }
 
 /* Implement pa_elf_select_rtx_section.  If X is a function label operand
@@ -10658,7 +10658,7 @@ pa_function_section (tree decl, enum node_frequency freq,
 {
   /* Put functions in text section if target doesn't have named sections.  */
   if (!targetm_common.have_named_sections)
-    return text_section;
+    return casm->sec.text;
 
   /* Force nested functions into the same section as the containing
      function.  */
diff --git a/gcc/config/pdp11/pdp11.c b/gcc/config/pdp11/pdp11.c
index ced653116a4..11b123c0586 100644
--- a/gcc/config/pdp11/pdp11.c
+++ b/gcc/config/pdp11/pdp11.c
@@ -743,7 +743,7 @@ void
 pdp11_asm_output_var (FILE *file, const char *name, int size,
 		      int align, bool global)
 {
-  switch_to_section (data_section);
+  switch_to_section (casm->sec.data);
   if (align > 8)
     fprintf (file, "\t.even\n");
   if (TARGET_DEC_ASM)
@@ -2323,11 +2323,11 @@ pdp11_asm_init_sections (void)
 {
   if (TARGET_DEC_ASM)
     {
-      bss_section = data_section;
+      casm->sec.bss = casm->sec.data;
     }
   else if (TARGET_GNU_ASM)
     {
-      bss_section = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
+      casm->sec.bss = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
 					 output_section_asm_op,
 					 ".bss");
     }
diff --git a/gcc/config/pru/pru.h b/gcc/config/pru/pru.h
index 03f08b1720f..a9c73dc5149 100644
--- a/gcc/config/pru/pru.h
+++ b/gcc/config/pru/pru.h
@@ -547,7 +547,7 @@ while (0)
 #undef  ASM_OUTPUT_ALIGNED_LOCAL
 #define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)		\
 do {									\
-  switch_to_section (bss_section);					\
+  switch_to_section (casm->sec.bss);					\
   ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
   if (!flag_inhibit_size_directive)					\
     ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);			\
diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
index 126572c6243..90bcb6de3cd 100644
--- a/gcc/config/riscv/riscv.c
+++ b/gcc/config/riscv/riscv.c
@@ -3616,8 +3616,8 @@ riscv_elf_select_rtx_section (machine_mode mode, rtx x,
 	  return get_section (name, s->named.common.flags, NULL);
 	}
 
-      if (s == data_section)
-	return sdata_section;
+      if (s == casm->sec.data)
+	return casm->sec.sdata;
     }
 
   return s;
diff --git a/gcc/config/rl78/rl78.c b/gcc/config/rl78/rl78.c
index 4c34949a97f..0129929c821 100644
--- a/gcc/config/rl78/rl78.c
+++ b/gcc/config/rl78/rl78.c
@@ -4644,14 +4644,14 @@ rl78_select_section (tree decl,
     }
 
   if (readonly)
-    return TARGET_ES0 ? frodata_section : readonly_data_section;
+    return TARGET_ES0 ? frodata_section : casm->sec.readonly_data;
 
   switch (categorize_decl_for_section (decl, reloc))
     {
-    case SECCAT_TEXT:   return text_section;
-    case SECCAT_DATA:   return data_section;
-    case SECCAT_BSS:    return bss_section;
-    case SECCAT_RODATA: return TARGET_ES0 ? frodata_section : readonly_data_section;
+    case SECCAT_TEXT:   return casm->sec.text;
+    case SECCAT_DATA:   return casm->sec.data;
+    case SECCAT_BSS:    return casm->sec.bss;
+    case SECCAT_RODATA: return TARGET_ES0 ? frodata_section : casm->sec.readonly_data;
     default:
       return default_select_section (decl, reloc, align);
     }
@@ -4786,7 +4786,7 @@ rl78_asm_ctor_dtor (rtx symbol, int priority, bool is_ctor)
       sec = get_section (buf, 0, NULL);
     }
   else
-    sec = is_ctor ? ctors_section : dtors_section;
+    sec = is_ctor ? casm->sec.ctors : casm->sec.dtors;
 
   assemble_addr_to_section (symbol, sec);
 }
diff --git a/gcc/config/rs6000/rs6000-internal.h b/gcc/config/rs6000/rs6000-internal.h
index 88cf9bd5692..d5cde365947 100644
--- a/gcc/config/rs6000/rs6000-internal.h
+++ b/gcc/config/rs6000/rs6000-internal.h
@@ -189,4 +189,13 @@ extern bool rs6000_passes_vector;
 extern bool rs6000_returns_struct;
 extern bool cpu_builtin_p;
 
+struct rs6000_asm_out_state : public asm_out_state
+{
+  /* Initialize ELF sections. */
+  void init_elf_sections ();
+
+  /* Initialize XCOFF sections. */
+  void init_xcoff_sections ();
+};
+
 #endif
diff --git a/gcc/config/rs6000/rs6000-logue.c b/gcc/config/rs6000/rs6000-logue.c
index 9965a8aa691..0a087cbd5e4 100644
--- a/gcc/config/rs6000/rs6000-logue.c
+++ b/gcc/config/rs6000/rs6000-logue.c
@@ -5506,7 +5506,7 @@ rs6000_output_function_epilogue (FILE *file)
       need_toc_init = 0;
       if (!toc_initialized)
 	{
-	  switch_to_section (toc_section);
+	  switch_to_section (casm->sec.toc);
 	  switch_to_section (current_function_section ());
 	}
     }
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index bac959f4ef4..9de3ed9611d 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -182,14 +182,6 @@ char toc_label_name[10];
    rs6000_variable_issue hook and returned from rs6000_sched_reorder2.  */
 static short cached_can_issue_more;
 
-static GTY(()) section *read_only_data_section;
-static GTY(()) section *private_data_section;
-static GTY(()) section *tls_data_section;
-static GTY(()) section *tls_private_data_section;
-static GTY(()) section *read_only_private_data_section;
-static GTY(()) section *sdata2_section;
-
-section *toc_section = 0;
 
 /* Describe the vector unit used for modes.  */
 enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
@@ -14747,7 +14739,7 @@ rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
 	 section.  */
       if (DEFAULT_ABI == ABI_V4
 	  && (TARGET_RELOCATABLE || flag_pic > 1)
-	  && in_section != toc_section
+	  && casm->in_section != casm->sec.toc
 	  && !recurse
 	  && !CONST_SCALAR_INT_P (x)
 	  && CONSTANT_P (x))
@@ -20633,6 +20625,7 @@ rs6000_ms_bitfield_layout_p (const_tree record_type)
     || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
 }
 \f
+
 #ifdef USING_ELFOS_H
 
 /* A get_unnamed_section callback, used for switching to toc_section.  */
@@ -20684,19 +20677,31 @@ rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
     }
 }
 
-/* Implement TARGET_ASM_INIT_SECTIONS.  */
+/* Initialize ELF sections. */
 
-static void
-rs6000_elf_asm_init_sections (void)
+void
+rs6000_asm_out_state::init_elf_sections ()
 {
-  toc_section
+  sec.toc
     = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
 
-  sdata2_section
+ sec.sdata2
     = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
 			   SDATA2_SECTION_ASM_OP);
 }
 
+/* Implement TARGET_ASM_INIT_SECTIONS.  */
+
+static asm_out_state *
+rs6000_elf_asm_init_sections (void)
+{
+  rs6000_asm_out_state *target_state
+    = new (ggc_alloc<rs6000_asm_out_state> ()) rs6000_asm_out_state ();
+  target_state->init_elf_sections ();
+
+  return target_state;
+}
+
 /* Implement TARGET_SELECT_RTX_SECTION.  */
 
 static section *
@@ -20704,7 +20709,7 @@ rs6000_elf_select_rtx_section (machine_mode mode, rtx x,
 			       unsigned HOST_WIDE_INT align)
 {
   if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
-    return toc_section;
+    return casm->sec.toc;
   else
     return default_elf_select_rtx_section (mode, x, align);
 }
@@ -21296,7 +21301,7 @@ rs6000_elf_file_end (void)
       /* We have expanded a CPU builtin, so we need to emit a reference to
 	 the special symbol that LIBC uses to declare it supports the
 	 AT_PLATFORM and AT_HWCAP/AT_HWCAP2 in the TCB feature.  */
-      switch_to_section (data_section);
+      switch_to_section (casm->sec.data);
       fprintf (asm_out_file, "\t.align %u\n", TARGET_32BIT ? 2 : 3);
       fprintf (asm_out_file, "\t%s %s\n",
 	       TARGET_32BIT ? ".long" : ".quad", tcb_verification_symbol);
@@ -21390,38 +21395,50 @@ rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
     fputs ("\t.toc\n", asm_out_file);
 }
 
-/* Implement TARGET_ASM_INIT_SECTIONS.  */
+/* Initialize XCOFF sections. */
 
-static void
-rs6000_xcoff_asm_init_sections (void)
+void
+rs6000_asm_out_state::init_xcoff_sections ()
 {
-  read_only_data_section
+  sec.read_only_data
     = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
 			   &xcoff_read_only_section_name);
 
-  private_data_section
+  sec.private_data
     = get_unnamed_section (SECTION_WRITE,
 			   rs6000_xcoff_output_readwrite_section_asm_op,
 			   &xcoff_private_data_section_name);
 
-  read_only_private_data_section
+  sec.read_only_private_data
     = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
 			   &xcoff_private_rodata_section_name);
 
-  tls_data_section
+  sec.tls_data
     = get_unnamed_section (SECTION_TLS,
 			   rs6000_xcoff_output_tls_section_asm_op,
 			   &xcoff_tls_data_section_name);
 
-  tls_private_data_section
+  sec.tls_private_data
     = get_unnamed_section (SECTION_TLS,
 			   rs6000_xcoff_output_tls_section_asm_op,
 			   &xcoff_private_data_section_name);
 
-  toc_section
+  sec.toc
     = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
 
-  readonly_data_section = read_only_data_section;
+  sec.readonly_data = target_sec.read_only_data;
+}
+
+/* Implement TARGET_ASM_INIT_SECTIONS.  */
+
+static asm_out_state *
+rs6000_xcoff_asm_init_sections (void)
+{
+  rs6000_asm_out_state *target_state
+    = new (ggc_alloc<rs6000_asm_out_state> ()) rs6000_asm_out_state ();
+  target_state->init_xcoff_sections ();
+
+  return target_state;
 }
 
 static int
@@ -21489,9 +21506,9 @@ rs6000_xcoff_select_section (tree decl, int reloc,
   if (decl_readonly_section (decl, reloc))
     {
       if (TREE_PUBLIC (decl))
-	return read_only_data_section;
+	return casm->sec.read_only_data;
       else
-	return read_only_private_data_section;
+	return casm->sec.read_only_private_data;
     }
   else
     {
@@ -21499,7 +21516,7 @@ rs6000_xcoff_select_section (tree decl, int reloc,
       if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL_P (decl))
 	{
 	  if (bss_initializer_p (decl))
-	    return tls_comm_section;
+	    return casm->sec.tls_comm;
 	  else if (TREE_PUBLIC (decl))
 	    return tls_data_section;
 	  else
@@ -21508,9 +21525,9 @@ rs6000_xcoff_select_section (tree decl, int reloc,
       else
 #endif
 	if (TREE_PUBLIC (decl))
-	return data_section;
+	return casm->sec.data;
       else
-	return private_data_section;
+	return casm->sec.private_data;
     }
 }
 
@@ -21535,9 +21552,9 @@ rs6000_xcoff_select_rtx_section (machine_mode mode, rtx x,
 				 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
 {
   if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
-    return toc_section;
+    return casm->sec.toc;
   else
-    return read_only_private_data_section;
+    return casm->sec.read_only_private_data;
 }
 
 /* Remove any trailing [DS] or the like from the symbol name.  */
@@ -21611,9 +21628,9 @@ rs6000_xcoff_file_start (void)
   output_quoted_string (asm_out_file, main_input_filename);
   fputc ('\n', asm_out_file);
   if (write_symbols != NO_DEBUG)
-    switch_to_section (private_data_section);
-  switch_to_section (toc_section);
-  switch_to_section (text_section);
+    switch_to_section (casm->sec.private_data);
+  switch_to_section (casm->sec.toc);
+  switch_to_section (casm->sec.text);
   if (profile_flag)
     fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
   rs6000_file_start ();
@@ -21625,14 +21642,14 @@ rs6000_xcoff_file_start (void)
 static void
 rs6000_xcoff_file_end (void)
 {
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
   if (xcoff_tls_exec_model_detected)
     {
       /* Add a .ref to __tls_get_addr to force libpthread dependency.  */
       fputs ("\t.extern __tls_get_addr\n\t.ref __tls_get_addr\n", asm_out_file);
     }
   fputs ("_section_.text:\n", asm_out_file);
-  switch_to_section (data_section);
+  switch_to_section (casm->sec.data);
   fputs (TARGET_32BIT
 	 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
 	 asm_out_file);
@@ -21747,7 +21764,7 @@ rs6000_xcoff_visibility (tree decl)
    Dollar signs are converted to underscores.
 
    The csect for the function will have already been created when
-   text_section was selected.  We do have to go back to that csect, however.
+   casm->sec.text was selected.  We do have to go back to that csect, however.
 
    The third and fourth parameters to the .function pseudo-op (16 and 044)
    are placeholders which no longer have any use.
@@ -21809,7 +21826,7 @@ rs6000_xcoff_declare_function_name (FILE *file, const char *name, tree decl)
   RS6000_OUTPUT_BASENAME (file, buffer);
   fputs (", TOC[tc0], 0\n", file);
 
-  in_section = NULL;
+  casm->in_section = NULL;
   switch_to_section (function_section (decl));
   putc ('.', file);
   ASM_OUTPUT_LABEL (file, buffer);
@@ -21869,7 +21886,7 @@ rs6000_xcoff_asm_output_aligned_decl_common (FILE *stream,
   if (! DECL_COMMON (decl))
     {
       /* Forget section.  */
-      in_section = NULL;
+      casm->in_section = NULL;
 
       /* Globalize TLS BSS.  */
       if (TREE_PUBLIC (decl) && DECL_THREAD_LOCAL_P (decl))
@@ -26866,7 +26883,7 @@ rs6000_code_end (void)
   else
 #endif
     {
-      switch_to_section (text_section);
+      switch_to_section (casm->sec.text);
       ASM_OUTPUT_LABEL (asm_out_file, name);
     }
 
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 3eba1c072cf..ee49446c72c 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -2606,7 +2606,6 @@ extern GTY(()) tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
 #ifndef USED_FOR_TARGET
 extern GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
 extern GTY(()) tree altivec_builtin_mask_for_load;
-extern GTY(()) section *toc_section;
 
 /* A C structure for machine-specific, per-function data.
    This is added to the cfun structure.  */
diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
index 96ee5524224..00af78c964f 100644
--- a/gcc/config/rs6000/sysv4.h
+++ b/gcc/config/rs6000/sysv4.h
@@ -427,7 +427,7 @@ do {									\
 do {									\
   if ((DECL) && rs6000_elf_in_small_data_p (DECL))			\
     {									\
-      switch_to_section (sbss_section);					\
+      switch_to_section (casm->sec.sbss);					\
       ASM_OUTPUT_ALIGN (FILE, exact_log2 (ALIGN / BITS_PER_UNIT));	\
       ASM_OUTPUT_LABEL (FILE, NAME);					\
       ASM_OUTPUT_SKIP (FILE, SIZE);					\
diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c
index af54ccc2588..c45aface21d 100644
--- a/gcc/config/rx/rx.c
+++ b/gcc/config/rx/rx.c
@@ -2305,7 +2305,7 @@ rx_select_rtx_section (machine_mode mode,
   if (rx_small_data_limit > 0
       && GET_MODE_SIZE (mode) <= rx_small_data_limit
       && align <= (unsigned HOST_WIDE_INT) rx_small_data_limit * BITS_PER_UNIT)
-    return sdata_section;
+    return casm->sec.sdata;
 
   return default_elf_select_rtx_section (mode, x, align);
 }
@@ -2319,8 +2319,8 @@ rx_select_section (tree decl,
     {
       switch (categorize_decl_for_section (decl, reloc))
 	{
-	case SECCAT_SDATA:	return sdata_section;
-	case SECCAT_SBSS:	return sbss_section;
+	case SECCAT_SDATA:	return casm->sec.sdata;
+	case SECCAT_SBSS:	return casm->sec.sbss;
 	case SECCAT_SRODATA:
 	  /* Fall through.  We do not put small, read only
 	     data into the C_2 section because we are not
@@ -2342,7 +2342,7 @@ rx_select_section (tree decl,
       case SECCAT_RODATA_MERGE_CONST:
       case SECCAT_RODATA_MERGE_STR_INIT:
       case SECCAT_RODATA_MERGE_STR:
-	return readonly_data_section;
+	return casm->sec.readonly_data;
 
       default:
 	break;
@@ -2690,9 +2690,9 @@ rx_elf_asm_cdtor (rtx symbol, int priority, bool is_ctor)
       s = get_section (buf, SECTION_WRITE, NULL_TREE);
     }
   else if (is_ctor)
-    s = ctors_section;
+    s = casm->sec.ctors;
   else
-    s = dtors_section;
+    s = casm->sec.dtors;
 
   switch_to_section (s);
   assemble_align (POINTER_SIZE);
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index b2f2f6417b3..367d58c28d0 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -16691,7 +16691,7 @@ s390_output_indirect_thunk_function (unsigned int regno, bool z10_p)
     }
   else
     {
-      switch_to_section (text_section);
+      switch_to_section (casm->sec.text);
       ASM_OUTPUT_LABEL (asm_out_file, thunk_label);
     }
 
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 0628f059ca2..5bce20ef2e4 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -2828,7 +2828,7 @@ sh_file_start (void)
   else
     /* Switch to the data section so that the coffsem symbol
        isn't in the text section.  */
-    switch_to_section (data_section);
+    switch_to_section (casm->sec.data);
 
   if (TARGET_LITTLE_ENDIAN)
     fputs ("\t.little\n", asm_out_file);
diff --git a/gcc/config/sparc/sol2.h b/gcc/config/sparc/sol2.h
index 1b4aa28bd21..1dd33daa447 100644
--- a/gcc/config/sparc/sol2.h
+++ b/gcc/config/sparc/sol2.h
@@ -399,9 +399,9 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
   do									\
     {									\
       if (TARGET_SUN_TLS						\
-	  && in_section							\
-	  && ((in_section->common.flags & SECTION_TLS) == SECTION_TLS))	\
-	switch_to_section (bss_section);				\
+	  && casm->in_section							\
+	  && ((casm->in_section->common.flags & SECTION_TLS) == SECTION_TLS))	\
+	switch_to_section (casm->sec.bss);				\
       fprintf ((FILE), "%s", COMMON_ASM_OP);				\
       assemble_name ((FILE), (NAME));					\
       fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED",%u\n",		\
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index ca91be4c8e9..c48fda6cca2 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -12638,7 +12638,7 @@ sparc_file_end (void)
       else
 	{
 	  const int align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
-          switch_to_section (text_section);
+          switch_to_section (casm->sec.text);
 	  if (align > 0)
 	    ASM_OUTPUT_ALIGN (asm_out_file, align);
 	  ASM_OUTPUT_LABEL (asm_out_file, name);
diff --git a/gcc/config/tilegx/tilegx.h b/gcc/config/tilegx/tilegx.h
index b0dcccfa3aa..931d900002b 100644
--- a/gcc/config/tilegx/tilegx.h
+++ b/gcc/config/tilegx/tilegx.h
@@ -290,7 +290,7 @@ enum reg_class
 
 #define TRAMPOLINE_SIZE (TARGET_32BIT ? 48 : 56)
 #define TRAMPOLINE_ALIGNMENT 64
-#define TRAMPOLINE_SECTION text_section
+#define TRAMPOLINE_SECTION casm->sec.text
 \f
 
 /* Call frame debugging information.  */
diff --git a/gcc/config/tilepro/tilepro.h b/gcc/config/tilepro/tilepro.h
index 1986f80084c..3f9720c582a 100644
--- a/gcc/config/tilepro/tilepro.h
+++ b/gcc/config/tilepro/tilepro.h
@@ -253,7 +253,7 @@ enum reg_class
 
 #define TRAMPOLINE_SIZE 48
 #define TRAMPOLINE_ALIGNMENT 64
-#define TRAMPOLINE_SECTION text_section
+#define TRAMPOLINE_SECTION casm->sec.text
 \f
 
 /* Call frame debugging information.  */
diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c
index 4978faf9318..9dafa3d1a76 100644
--- a/gcc/config/v850/v850.c
+++ b/gcc/config/v850/v850.c
@@ -2398,7 +2398,7 @@ v850_output_aligned_bss (FILE * file,
       break;
 
     case DATA_AREA_SDA:
-      switch_to_section (sbss_section);
+      switch_to_section (casm->sec.sbss);
       break;
 
     case DATA_AREA_TDA:
@@ -2406,7 +2406,7 @@ v850_output_aligned_bss (FILE * file,
       break;
       
     default:
-      switch_to_section (bss_section);
+      switch_to_section (casm->sec.bss);
       break;
     }
   
@@ -2882,13 +2882,13 @@ v850_select_section (tree exp,
 	  return tdata_section;
 
         case DATA_AREA_SDA:
-	  return is_const ? rosdata_section : sdata_section;
+	  return is_const ? rosdata_section : casm->sec.sdata;
 
         default:
-	  return is_const ? readonly_data_section : data_section;
+	  return is_const ? casm->sec.readonly_data : casm->sec.data;
         }
     }
-  return readonly_data_section;
+  return casm->sec.readonly_data;
 }
 \f
 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P.  */
diff --git a/gcc/config/visium/visium.h b/gcc/config/visium/visium.h
index 66e3decd0cc..dbe65766d09 100644
--- a/gcc/config/visium/visium.h
+++ b/gcc/config/visium/visium.h
@@ -1235,8 +1235,8 @@ do									\
    `EXTRA_SECTION_FUNCTIONS'
 
    One or more functions to be defined in `varasm.c'.  These functions
-   should do jobs analogous to those of `text_section' and
-   `data_section', for your additional sections.  Do not define this
+   should do jobs analogous to those of `casm->sec.text' and
+   `casm->sec.data', for your additional sections.  Do not define this
    macro if you do not define `EXTRA_SECTIONS'.
 
    `JUMP_TABLES_IN_TEXT_SECTION' Define this macro if jump tables (for
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index b4f530d57ac..181764e8eaa 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -99,6 +99,7 @@ typedef const union tree_node *const_tree;
 struct gimple;
 typedef gimple *gimple_seq;
 struct gimple_stmt_iterator;
+struct asm_out_state;
 
 /* Forward decls for leaf gimple subclasses (for individual gimple codes).
    Keep this in the same order as the corresponding codes in gimple.def.  */
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index 6be282714cf..d8c91d07ca7 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -934,7 +934,7 @@ dbxout_function_end (tree decl ATTRIBUTE_UNUSED)
   if (crtl->has_bb_partition)
     {
       dbxout_begin_empty_stabs (N_FUN);
-      if (in_cold_section_p)
+      if (casm->in_cold_section_p)
 	dbxout_stab_value_label_diff (crtl->subsections.cold_section_end_label,
 				      crtl->subsections.cold_section_label);
       else
@@ -1042,7 +1042,7 @@ dbxout_init (const char *input_file_name)
 
   if (used_ltext_label_name)
     {
-      switch_to_section (text_section);
+      switch_to_section (casm->sec.text);
       targetm.asm_out.internal_label (asm_out_file, "Ltext", 0);
     }
 
@@ -1244,7 +1244,7 @@ dbxout_source_file (const char *filename)
     {
       /* Don't change section amid function.  */
       if (current_function_decl == NULL_TREE)
-	switch_to_section (text_section);
+	switch_to_section (casm->sec.text);
 
       dbxout_begin_simple_stabs (remap_debug_filename (filename), N_SOL);
       dbxout_stab_value_internal_label ("Ltext", &source_label_number);
@@ -1314,12 +1314,12 @@ dbxout_switch_text_section (void)
   /* The N_FUN tag at the end of the function is a GNU extension,
      which may be undesirable, and is unnecessary if we do not have
      named sections.  */
-  in_cold_section_p = !in_cold_section_p;
+  casm->in_cold_section_p = !casm->in_cold_section_p;
   switch_to_section (current_function_section ());
   dbxout_block (DECL_INITIAL (current_function_decl), 0,
 		DECL_ARGUMENTS (current_function_decl), -1);
   dbxout_function_end (current_function_decl);
-  in_cold_section_p = !in_cold_section_p;
+  casm->in_cold_section_p = !casm->in_cold_section_p;
 
   switch_to_section (current_function_section ());
 
@@ -1432,7 +1432,7 @@ dbxout_finish (const char *filename ATTRIBUTE_UNUSED)
   DBX_OUTPUT_MAIN_SOURCE_FILE_END (asm_out_file, filename);
 #elif defined DBX_OUTPUT_NULL_N_SO_AT_MAIN_SOURCE_FILE_END
  {
-   switch_to_section (text_section);
+   switch_to_section (casm->sec.text);
    dbxout_begin_empty_stabs (N_SO);
    dbxout_stab_value_internal_label ("Letext", 0);
  }
@@ -3114,7 +3114,7 @@ dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home)
 	    {
 	      /* Ultrix `as' seems to need this.  */
 #ifdef DBX_STATIC_STAB_DATA_SECTION
-	      switch_to_section (data_section);
+	      switch_to_section (casm->sec.data);
 #endif
 	      code = N_STSYM;
 	    }
@@ -3776,7 +3776,7 @@ dbxout_block (tree block, int depth, tree args, int parent_blocknum)
 
   /* If called for the second partition, ignore blocks that don't have
      any children in the second partition.  */
-  if (crtl->has_bb_partition && in_cold_section_p && depth == 0)
+  if (crtl->has_bb_partition && casm->in_cold_section_p && depth == 0)
     dbx_block_with_cold_children (block);
 
   for (; block; block = BLOCK_CHAIN (block))
@@ -3801,7 +3801,7 @@ dbxout_block (tree block, int depth, tree args, int parent_blocknum)
 	     the assembler symbols LBBn and LBEn
 	     that final will define around the code in this block.  */
 	  if (did_output
-	      && BLOCK_IN_COLD_SECTION_P (block) == in_cold_section_p)
+	      && BLOCK_IN_COLD_SECTION_P (block) == casm->in_cold_section_p)
 	    {
 	      char buf[20];
 	      const char *scope_start;
@@ -3829,7 +3829,7 @@ dbxout_block (tree block, int depth, tree args, int parent_blocknum)
 
 	  /* Refer to the marker for the end of the block.  */
 	  if (did_output
-	      && BLOCK_IN_COLD_SECTION_P (block) == in_cold_section_p)
+	      && BLOCK_IN_COLD_SECTION_P (block) == casm->in_cold_section_p)
 	    {
 	      char buf[100];
 	      if (depth == 0)
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 990152f5b15..af90c6b6a86 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -5525,7 +5525,7 @@ to generate it on the spot.
 
 @defmac TRAMPOLINE_SECTION
 Return the section into which the trampoline template is to be placed
-(@pxref{Sections}).  The default value is @code{readonly_data_section}.
+(@pxref{Sections}).  The default value is @code{casm->sec.readonly_data}.
 @end defmac
 
 @defmac TRAMPOLINE_SIZE
@@ -7593,7 +7593,7 @@ section}, which holds uninitialized data.  Some systems have other kinds
 of sections.
 
 @file{varasm.c} provides several well-known sections, such as
-@code{text_section}, @code{data_section} and @code{bss_section}.
+@code{casm->sec.text}, @code{casm->sec.data} and @code{casm->sec.bss}.
 The normal way of controlling a @code{@var{foo}_section} variable
 is to define the associated @code{@var{FOO}_SECTION_ASM_OP} macro,
 as described below.  The macros are only read once, when @file{varasm.c}
@@ -7609,12 +7609,12 @@ section is selected.  If your assembler falls into this category, you
 should define the @code{TARGET_ASM_INIT_SECTIONS} hook and use
 @code{get_unnamed_section} to set up the sections.
 
-You must always create a @code{text_section}, either by defining
-@code{TEXT_SECTION_ASM_OP} or by initializing @code{text_section}
+You must always create a @code{casm->sec.text}, either by defining
+@code{TEXT_SECTION_ASM_OP} or by initializing @code{casm->sec.text}
 in @code{TARGET_ASM_INIT_SECTIONS}.  The same is true of
-@code{data_section} and @code{DATA_SECTION_ASM_OP}.  If you do not
-create a distinct @code{readonly_data_section}, the default is to
-reuse @code{text_section}.
+@code{casm->sec.data} and @code{DATA_SECTION_ASM_OP}.  If you do not
+create a distinct @code{casm->sec.readonly_data}, the default is to
+reuse @code{casm->sec.text}.
 
 All the other @file{varasm.c} sections are optional, and are null
 if the target does not provide them.
@@ -7761,7 +7761,7 @@ readonly data section is used.
 This macro is irrelevant if there is no separate readonly data section.
 @end defmac
 
-@deftypefn {Target Hook} void TARGET_ASM_INIT_SECTIONS (void)
+@deftypefn {Target Hook} {asm_out_state *} TARGET_ASM_INIT_SECTIONS (void)
 Define this hook if you need to do something special to set up the
 @file{varasm.c} sections, or if your target has some special sections
 of its own that you need to create.
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 193c9bdd853..2ef3977839c 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -3854,7 +3854,7 @@ separately.
 
 @defmac TRAMPOLINE_SECTION
 Return the section into which the trampoline template is to be placed
-(@pxref{Sections}).  The default value is @code{readonly_data_section}.
+(@pxref{Sections}).  The default value is @code{casm->sec.readonly_data}.
 @end defmac
 
 @defmac TRAMPOLINE_SIZE
@@ -4752,7 +4752,7 @@ section}, which holds uninitialized data.  Some systems have other kinds
 of sections.
 
 @file{varasm.c} provides several well-known sections, such as
-@code{text_section}, @code{data_section} and @code{bss_section}.
+@code{casm->sec.text}, @code{casm->sec.data} and @code{casm->sec.bss}.
 The normal way of controlling a @code{@var{foo}_section} variable
 is to define the associated @code{@var{FOO}_SECTION_ASM_OP} macro,
 as described below.  The macros are only read once, when @file{varasm.c}
@@ -4768,12 +4768,12 @@ section is selected.  If your assembler falls into this category, you
 should define the @code{TARGET_ASM_INIT_SECTIONS} hook and use
 @code{get_unnamed_section} to set up the sections.
 
-You must always create a @code{text_section}, either by defining
-@code{TEXT_SECTION_ASM_OP} or by initializing @code{text_section}
+You must always create a @code{casm->sec.text}, either by defining
+@code{TEXT_SECTION_ASM_OP} or by initializing @code{casm->sec.text}
 in @code{TARGET_ASM_INIT_SECTIONS}.  The same is true of
-@code{data_section} and @code{DATA_SECTION_ASM_OP}.  If you do not
-create a distinct @code{readonly_data_section}, the default is to
-reuse @code{text_section}.
+@code{casm->sec.data} and @code{DATA_SECTION_ASM_OP}.  If you do not
+create a distinct @code{casm->sec.readonly_data}, the default is to
+reuse @code{casm->sec.text}.
 
 All the other @file{varasm.c} sections are optional, and are null
 if the target does not provide them.
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 20f2c5da023..fd0c5366437 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -438,14 +438,14 @@ should_emit_struct_debug (tree type, enum debug_info_usage usage)
   return DUMP_GSTRUCT (type, usage, criterion, generic, false, false);
 }
 \f
-/* Switch [BACK] to eh_frame_section.  If we don't have an eh_frame_section,
+/* Switch [BACK] to casm->sec.eh_frame.  If we don't have an casm->sec.eh_frame,
    switch to the data section instead, and write out a synthetic start label
    for collect2 the first time around.  */
 
 static void
 switch_to_eh_frame_section (bool back ATTRIBUTE_UNUSED)
 {
-  if (eh_frame_section == 0)
+  if (casm->sec.eh_frame == 0)
     {
       int flags;
 
@@ -474,14 +474,14 @@ switch_to_eh_frame_section (bool back ATTRIBUTE_UNUSED)
 	flags = SECTION_WRITE;
 
 #ifdef EH_FRAME_SECTION_NAME
-      eh_frame_section = get_section (EH_FRAME_SECTION_NAME, flags, NULL);
+      casm->sec.eh_frame = get_section (EH_FRAME_SECTION_NAME, flags, NULL);
 #else
-      eh_frame_section = ((flags == SECTION_WRITE)
-			  ? data_section : readonly_data_section);
+      casm->sec.eh_frame = ((flags == SECTION_WRITE)
+			  ? casm->sec.data : casm->sec.readonly_data);
 #endif /* EH_FRAME_SECTION_NAME */
     }
 
-  switch_to_section (eh_frame_section);
+  switch_to_section (casm->sec.eh_frame);
 
 #ifdef EH_FRAME_THROUGH_COLLECT2
   /* We have no special eh_frame section.  Emit special labels to guide
@@ -1113,10 +1113,10 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
   /* Initialize the bits of CURRENT_FDE that were not available earlier.  */
   fde->dw_fde_begin = dup_label;
   fde->dw_fde_current_label = dup_label;
-  fde->in_std_section = (fnsec == text_section
+  fde->in_std_section = (fnsec == casm->sec.text
 			 || (cold_text_section && fnsec == cold_text_section));
   fde->ignored_debug = DECL_IGNORED_P (current_function_decl);
-  in_text_section_p = fnsec == text_section;
+  in_text_section_p = fnsec == casm->sec.text;
 
   /* We only want to output line number information for the genuine dwarf2
      prologue case, not the eh frame case.  */
@@ -1295,7 +1295,7 @@ dwarf2out_switch_text_section (void)
 			       current_function_funcdef_no);
 
   fde->dw_fde_second_begin = ggc_strdup (label);
-  if (!in_cold_section_p)
+  if (!casm->in_cold_section_p)
     {
       fde->dw_fde_end = crtl->subsections.cold_section_end_label;
       fde->dw_fde_second_end = crtl->subsections.hot_section_end_label;
@@ -1317,9 +1317,9 @@ dwarf2out_switch_text_section (void)
   switch_to_section (sect);
 
   fde->second_in_std_section
-    = (sect == text_section
+    = (sect == casm->sec.text
        || (cold_text_section && sect == cold_text_section));
-  in_text_section_p = sect == text_section;
+  in_text_section_p = sect == casm->sec.text;
 
   if (dwarf2out_do_cfi_asm ())
     dwarf2out_do_cfi_startproc (true);
@@ -17270,7 +17270,7 @@ secname_for_decl (const_tree decl)
     secname = DECL_SECTION_NAME (decl);
   else if (current_function_decl && DECL_SECTION_NAME (current_function_decl))
     {
-      if (in_cold_section_p)
+      if (casm->in_cold_section_p)
 	{
 	  section *sec = current_function_section ();
 	  if (sec->common.flags & SECTION_NAMED)
@@ -17278,7 +17278,7 @@ secname_for_decl (const_tree decl)
 	}
       secname = DECL_SECTION_NAME (current_function_decl);
     }
-  else if (cfun && in_cold_section_p)
+  else if (cfun && casm->in_cold_section_p)
     secname = crtl->subsections.cold_section_label;
   else
     secname = text_section_label;
@@ -17599,12 +17599,12 @@ dw_loc_list (var_loc_list *loc_list, tree decl, int want_address)
 
   if (cfun && crtl->has_bb_partition)
     {
-      bool save_in_cold_section_p = in_cold_section_p;
-      in_cold_section_p = first_function_block_is_cold;
+      bool save_in_cold_section_p = casm->in_cold_section_p;
+      casm->in_cold_section_p = first_function_block_is_cold;
       if (loc_list->last_before_switch == NULL)
-	in_cold_section_p = !in_cold_section_p;
+	casm->in_cold_section_p = !casm->in_cold_section_p;
       secname = secname_for_decl (decl);
-      in_cold_section_p = save_in_cold_section_p;
+      casm->in_cold_section_p = save_in_cold_section_p;
     }
   else
     secname = secname_for_decl (decl);
@@ -17682,10 +17682,10 @@ dw_loc_list (var_loc_list *loc_list, tree decl, int want_address)
 	  && crtl->has_bb_partition
 	  && node == loc_list->last_before_switch)
 	{
-	  bool save_in_cold_section_p = in_cold_section_p;
-	  in_cold_section_p = !first_function_block_is_cold;
+	  bool save_in_cold_section_p = casm->in_cold_section_p;
+	  casm->in_cold_section_p = !first_function_block_is_cold;
 	  secname = secname_for_decl (decl);
-	  in_cold_section_p = save_in_cold_section_p;
+	  casm->in_cold_section_p = save_in_cold_section_p;
 	}
 
       if (range_across_switch)
@@ -27853,7 +27853,7 @@ create_label:
      last_{,postcall_}label so that they are not reused this time.  */
   if (last_var_location_insn == NULL_RTX
       || last_var_location_insn != next_real
-      || last_in_cold_section_p != in_cold_section_p)
+      || last_in_cold_section_p != casm->in_cold_section_p)
     {
       last_label = NULL;
       last_postcall_label = NULL;
@@ -28024,7 +28024,7 @@ create_label:
     }
 
   last_var_location_insn = next_real;
-  last_in_cold_section_p = in_cold_section_p;
+  last_in_cold_section_p = casm->in_cold_section_p;
 }
 
 /* Check whether BLOCK, a lexical block, is nested within OUTER, or is
@@ -28192,7 +28192,7 @@ set_cur_line_info_table (section *sec)
 {
   dw_line_info_table *table;
 
-  if (sec == text_section)
+  if (sec == casm->sec.text)
     table = text_section_line_info;
   else if (sec == cold_text_section)
     {
@@ -28209,7 +28209,7 @@ set_cur_line_info_table (section *sec)
 
       if (crtl->has_bb_partition)
 	{
-	  if (in_cold_section_p)
+	  if (casm->in_cold_section_p)
 	    end_label = crtl->subsections.cold_section_end_label;
 	  else
 	    end_label = crtl->subsections.hot_section_end_label;
@@ -28246,7 +28246,7 @@ dwarf2out_begin_function (tree fun)
 {
   section *sec = function_section (fun);
 
-  if (sec != text_section)
+  if (sec != casm->sec.text)
     have_multiple_function_sections = true;
 
   if (crtl->has_bb_partition && !cold_text_section)
@@ -29375,7 +29375,7 @@ dwarf2out_assembly_start (void)
 			       COLD_TEXT_SECTION_LABEL, 0);
   ASM_GENERATE_INTERNAL_LABEL (cold_end_label, COLD_END_LABEL, 0);
 
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
   ASM_OUTPUT_LABEL (asm_out_file, text_section_label);
 #endif
 
@@ -32082,7 +32082,7 @@ dwarf2out_finish (const char *filename)
     main_comp_unit_die = comp_unit_die ();
 
   /* Output a terminator label for the .text section.  */
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
   targetm.asm_out.internal_label (asm_out_file, TEXT_END_LABEL, 0);
   if (cold_text_section)
     {
@@ -32998,7 +32998,7 @@ dwarf2out_early_finish (const char *filename)
     }
 
   /* Switch back to the text section.  */
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
 }
 
 /* Reset all state within dwarf2out.c so that we can rerun the compiler
diff --git a/gcc/dwarf2out.h b/gcc/dwarf2out.h
index 312a9909784..6491b44da95 100644
--- a/gcc/dwarf2out.h
+++ b/gcc/dwarf2out.h
@@ -103,9 +103,9 @@ struct GTY(()) dw_fde_node {
   unsigned stack_realign : 1;
   /* Whether dynamic realign argument pointer register has been saved.  */
   unsigned drap_reg_saved: 1;
-  /* True iff dw_fde_begin label is in text_section or cold_text_section.  */
+  /* True iff dw_fde_begin label is in casm->sec.text or cold_text_section.  */
   unsigned in_std_section : 1;
-  /* True iff dw_fde_second_begin label is in text_section or
+  /* True iff dw_fde_second_begin label is in casm->sec.text or
      cold_text_section.  */
   unsigned second_in_std_section : 1;
   /* True if Rule 18 described in dwarf2cfi.c is in action, i.e. for dynamic
diff --git a/gcc/except.c b/gcc/except.c
index 8e905a30939..ce38a57ed2f 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -2906,8 +2906,8 @@ switch_to_exception_section (const char * ARG_UNUSED (fnname))
 {
   section *s;
 
-  if (exception_section)
-    s = exception_section;
+  if (casm->sec.exception)
+    s = casm->sec.exception;
   else
     {
       int flags;
@@ -2924,7 +2924,7 @@ switch_to_exception_section (const char * ARG_UNUSED (fnname))
       else
 	flags = SECTION_WRITE;
 
-      /* Compute the section and cache it into exception_section,
+      /* Compute the section and cache it into casm->sec.exception,
 	 unless it depends on the function name.  */
       if (targetm_common.have_named_sections)
 	{
@@ -2943,12 +2943,12 @@ switch_to_exception_section (const char * ARG_UNUSED (fnname))
 	    }
 	  else
 #endif
-	    exception_section
+	    casm->sec.exception
 	      = s = get_section (".gcc_except_table", flags, NULL);
 	}
       else
-	exception_section
-	  = s = flags == SECTION_WRITE ? data_section : readonly_data_section;
+	casm->sec.exception
+	  = s = flags == SECTION_WRITE ? casm->sec.data: casm->sec.readonly_data;
     }
 
   switch_to_section (s);
diff --git a/gcc/final.c b/gcc/final.c
index ac6892d041c..03c8533e92b 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -885,7 +885,7 @@ shorten_branches (rtx_insn *first)
 	  /* ADDR_VECs only take room if read-only data goes into the text
 	     section.  */
 	  if ((JUMP_TABLES_IN_TEXT_SECTION
-	       || readonly_data_section == text_section)
+	       || casm->sec.readonly_data == casm->sec.text)
 	      && table)
 	    {
 	      align_flags alignment = align_flags (ADDR_VEC_ALIGN (table));
@@ -1051,7 +1051,7 @@ shorten_branches (rtx_insn *first)
 	  /* This only takes room if read-only data goes into the text
 	     section.  */
 	  if (JUMP_TABLES_IN_TEXT_SECTION
-	      || readonly_data_section == text_section)
+	      || casm->sec.readonly_data == casm->sec.text)
 	    insn_lengths[uid] = (XVECLEN (body,
 					  GET_CODE (body) == ADDR_DIFF_VEC)
 				 * GET_MODE_SIZE (table->get_data_mode ()));
@@ -1143,7 +1143,7 @@ shorten_branches (rtx_insn *first)
 		 may need to update the alignment of this label.  */
 
 	      if (JUMP_TABLES_IN_TEXT_SECTION
-		  || readonly_data_section == text_section)
+		  || casm->sec.readonly_data == casm->sec.text)
 		{
 		  rtx_jump_table_data *table = jump_table_for_label (label);
 		  if (table)
@@ -1284,7 +1284,7 @@ shorten_branches (rtx_insn *first)
 		      >= GET_MODE_SIZE (table->get_data_mode ())))
 		PUT_MODE (body, vec_mode);
 	      if (JUMP_TABLES_IN_TEXT_SECTION
-		  || readonly_data_section == text_section)
+		  || casm->sec.readonly_data == casm->sec.text)
 		{
 		  insn_lengths[uid]
 		    = (XVECLEN (body, 1)
@@ -1836,7 +1836,7 @@ profile_function (FILE *file ATTRIBUTE_UNUSED)
   if (! NO_PROFILE_COUNTERS)
     {
       int align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE);
-      switch_to_section (data_section);
+      switch_to_section (casm->sec.data);
       ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
       targetm.asm_out.internal_label (file, "LP", current_function_funcdef_no);
       assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, align, 1);
@@ -2189,10 +2189,10 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
 	  if (targetm.asm_out.unwind_emit)
 	    targetm.asm_out.unwind_emit (asm_out_file, insn);
 
-	  in_cold_section_p = !in_cold_section_p;
+	  casm->in_cold_section_p = !casm->in_cold_section_p;
 
-	  gcc_checking_assert (in_cold_section_p);
-	  if (in_cold_section_p)
+	  gcc_checking_assert (casm->in_cold_section_p);
+	  if (casm->in_cold_section_p)
 	    cold_function_name
 	      = clone_function_name (current_function_decl, "cold");
 
@@ -2213,10 +2213,10 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
 	  switch_to_section (current_function_section ());
 	  targetm.asm_out.function_switched_text_sections (asm_out_file,
 							   current_function_decl,
-							   in_cold_section_p);
+							   casm->in_cold_section_p);
 	  /* Emit a label for the split cold section.  Form label name by
 	     suffixing "cold" to the original function's name.  */
-	  if (in_cold_section_p)
+	  if (casm->in_cold_section_p)
 	    {
 #ifdef ASM_DECLARE_COLD_FUNCTION_NAME
 	      ASM_DECLARE_COLD_FUNCTION_NAME (asm_out_file,
@@ -2323,7 +2323,7 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
 
 	      /* Mark this block as output.  */
 	      TREE_ASM_WRITTEN (NOTE_BLOCK (insn)) = 1;
-	      BLOCK_IN_COLD_SECTION_P (NOTE_BLOCK (insn)) = in_cold_section_p;
+	      BLOCK_IN_COLD_SECTION_P (NOTE_BLOCK (insn)) = casm->in_cold_section_p;
 	    }
 	  if (write_symbols == DBX_DEBUG)
 	    {
@@ -2358,7 +2358,7 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
 	      if (!DECL_IGNORED_P (current_function_decl))
 		debug_hooks->end_block (high_block_linenum, n);
 	      gcc_assert (BLOCK_IN_COLD_SECTION_P (NOTE_BLOCK (insn))
-			  == in_cold_section_p);
+			  == casm->in_cold_section_p);
 	    }
 	  if (write_symbols == DBX_DEBUG)
 	    {
diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c
index 32ba5be42b2..d90a8570dba 100644
--- a/gcc/ggc-common.c
+++ b/gcc/ggc-common.c
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "hosthooks.h"
 #include "plugin.h"
 #include "options.h"
+#include "output.h"
 
 /* When true, protect the contents of the identifier hash table.  */
 bool ggc_protect_identifiers = true;
@@ -589,6 +590,9 @@ gt_pch_restore (FILE *f)
   struct mmap_info mmi;
   int result;
 
+  /* Hide ASM state object as we don't want it to be streamed.  */
+  FILE *saved_casm_out_file = casm != NULL ? casm->out_file : NULL;
+
   /* Delete any deletable objects.  This makes ggc_pch_read much
      faster, as it can be sure that no GCable objects remain other
      than the ones just read in.  */
@@ -629,6 +633,9 @@ gt_pch_restore (FILE *f)
   ggc_pch_read (f, mmi.preferred_base);
 
   gt_pch_restore_stringpool ();
+
+  if (casm != NULL)
+    casm->out_file = saved_casm_out_file;
 }
 
 /* Default version of HOST_HOOKS_GT_PCH_GET_ADDRESS when mmap is not present.
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index 48c72377778..cd1ed0655e5 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -803,9 +803,9 @@ lhd_begin_section (const char *name)
 
   /* Save the old section so we can restore it in lto_end_asm_section.  */
   gcc_assert (!saved_section);
-  saved_section = in_section;
+  saved_section = casm->in_section;
   if (!saved_section)
-    saved_section = text_section;
+    saved_section = casm->sec.text;
 
   /* Create a new section and switch to it.  */
   section = get_section (name, SECTION_DEBUG | SECTION_EXCLUDE, NULL, true);
diff --git a/gcc/output.h b/gcc/output.h
index 8f6f15308f4..ec9cda42500 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -313,9 +313,88 @@ extern rtx_sequence *final_sequence;
 
 /* File in which assembler code is being written.  */
 
-#ifdef BUFSIZ
-extern FILE *asm_out_file;
-#endif
+struct section_hasher : ggc_ptr_hash<section>
+{
+  typedef const char *compare_type;
+
+  static hashval_t hash (section *);
+  static bool equal (section *, const char *);
+};
+
+/* Assembly output state.  */
+
+struct GTY(()) asm_out_state
+{
+  /* Default constructor.  */
+  asm_out_state ();
+
+  /* Assembly output stream.  */
+  FILE * GTY((skip)) out_file;
+
+  /* Hash table of named sections.  */
+  hash_table<section_hasher> *section_htab;
+
+  /* asm_out_file's current section.  This is NULL if no section has yet
+     been selected or if we lose track of what the current section is.  */
+  section *in_section;
+
+  /* Well-known sections, each one associated with some sort of *_ASM_OP.  */
+  struct
+  {
+    section *text;
+    section *data;
+    section *readonly_data;
+    section *sdata;
+    section *ctors;
+    section *dtors;
+    section *bss;
+    section *sbss;
+
+    /* Various forms of common section.  All are guaranteed to be nonnull.  */
+    section *tls_comm;
+    section *comm;
+    section *lcomm;
+
+    /* A SECTION_NOSWITCH section used for declaring global BSS variables.
+       May be null.  */
+    section *bss_noswitch;
+
+    /* The section that holds the main exception table, when known.  The section
+       is set either by the target's init_sections hook or by the first call to
+       switch_to_exception_section.  */
+    section *exception;
+
+    /* The section that holds the DWARF2 frame unwind information, when known.
+       The section is set either by the target's init_sections hook or by the
+       first call to switch_to_eh_frame_section.  */
+    section *eh_frame;
+
+    /* RS6000 sections.  */
+
+    /* ELF sections.  */
+    section *toc;
+    section *sdata2;
+
+    /* XCOFF sections.  */
+    section *read_only_data;
+    section *private_data;
+    section *tls_data;
+    section *tls_private_data;
+    section *read_only_private_data;
+  } sec;
+
+  /* The next number to use for internal anchor labels.  */
+  int anchor_labelno;
+
+  /* True if code for the current function is currently being directed
+     at the cold section.  */
+  bool in_cold_section_p;
+};
+
+extern GTY(()) asm_out_state *casm;
+
+/* Helper macro for commonly used accesses.  */
+#define asm_out_file casm->out_file
 
 /* The first global object in the file.  */
 extern const char *first_global_object_name;
@@ -520,24 +599,6 @@ union GTY ((desc ("SECTION_STYLE (&(%h))"), for_user)) section {
 struct object_block;
 
 /* Special well-known sections.  */
-extern GTY(()) section *text_section;
-extern GTY(()) section *data_section;
-extern GTY(()) section *readonly_data_section;
-extern GTY(()) section *sdata_section;
-extern GTY(()) section *ctors_section;
-extern GTY(()) section *dtors_section;
-extern GTY(()) section *bss_section;
-extern GTY(()) section *sbss_section;
-extern GTY(()) section *exception_section;
-extern GTY(()) section *eh_frame_section;
-extern GTY(()) section *tls_comm_section;
-extern GTY(()) section *comm_section;
-extern GTY(()) section *lcomm_section;
-extern GTY(()) section *bss_noswitch_section;
-
-extern GTY(()) section *in_section;
-extern GTY(()) bool in_cold_section_p;
-
 extern section *get_unnamed_section (unsigned int, void (*) (const void *),
 				     const void *);
 extern section *get_section (const char *, unsigned int, tree,
@@ -567,6 +628,7 @@ extern void record_tm_clone_pair (tree, tree);
 extern void finish_tm_clone_pairs (void);
 extern tree get_tm_clone_pair (tree);
 
+extern asm_out_state *default_init_sections (void);
 extern void default_asm_output_source_filename (FILE *, const char *);
 extern void output_file_directive (FILE *, const char *);
 
diff --git a/gcc/run-rtl-passes.c b/gcc/run-rtl-passes.c
index 37a02813f22..e6976bf9070 100644
--- a/gcc/run-rtl-passes.c
+++ b/gcc/run-rtl-passes.c
@@ -46,7 +46,7 @@ run_rtl_passes (char *initial_pass_name)
   max_regno = max_reg_num ();
 
   /* cgraphunit.c normally handles this.  */
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
   (*debug_hooks->assembly_start) ();
 
   if (initial_pass_name)
diff --git a/gcc/target.def b/gcc/target.def
index 87feeec2ea1..044a1f2c48f 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -429,8 +429,8 @@ of its own that you need to create.\n\
 GCC calls this hook after processing the command line, but before writing\n\
 any assembly code, and before calling any of the section-returning hooks\n\
 described below.",
- void, (void),
- hook_void_void)
+ asm_out_state *, (void),
+ default_init_sections)
 
 /* Tell assembler to change to section NAME with attributes FLAGS.
    If DECL is non-NULL, it is the VAR_DECL or FUNCTION_DECL with
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 0b525bb4606..03102e38b33 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -1962,7 +1962,7 @@ default_print_patchable_function_entry_1 (FILE *file,
     {
       char buf[256];
       static int patch_area_number;
-      section *previous_section = in_section;
+      section *previous_section = casm->in_section;
       const char *asm_op = integer_asm_op (POINTER_SIZE_UNITS, false);
 
       gcc_assert (asm_op != NULL);
diff --git a/gcc/toplev.c b/gcc/toplev.c
index e91f083f8ff..772a2a1cc18 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -166,7 +166,8 @@ const char *user_label_prefix;
 /* Output files for assembler code (real compiler output)
    and debugging dumps.  */
 
-FILE *asm_out_file;
+asm_out_state *casm;
+
 FILE *aux_info_file;
 FILE *callgraph_info_file = NULL;
 static bitmap callgraph_info_external_printed;
@@ -546,13 +547,13 @@ compile_file (void)
   if (flag_generate_lto && !flag_fat_lto_objects)
     {
 #if defined ASM_OUTPUT_ALIGNED_DECL_COMMON
-      ASM_OUTPUT_ALIGNED_DECL_COMMON (asm_out_file, NULL_TREE, "__gnu_lto_slim",
+      ASM_OUTPUT_ALIGNED_DECL_COMMON (casm->out_file, NULL_TREE, "__gnu_lto_slim",
 				      HOST_WIDE_INT_1U, 8);
 #elif defined ASM_OUTPUT_ALIGNED_COMMON
-      ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, "__gnu_lto_slim",
+      ASM_OUTPUT_ALIGNED_COMMON (casm->out_file, "__gnu_lto_slim",
 				 HOST_WIDE_INT_1U, 8);
 #else
-      ASM_OUTPUT_COMMON (asm_out_file, "__gnu_lto_slim",
+      ASM_OUTPUT_COMMON (casm->out_file, "__gnu_lto_slim",
 			 HOST_WIDE_INT_1U,
 			 HOST_WIDE_INT_1U);
 #endif
@@ -690,7 +691,7 @@ static void
 init_asm_output (const char *name)
 {
   if (name == NULL && asm_file_name == 0)
-    asm_out_file = stdout;
+    casm->out_file = stdout;
   else
     {
       if (asm_file_name == 0)
@@ -704,17 +705,17 @@ init_asm_output (const char *name)
 	  asm_file_name = dumpname;
 	}
       if (!strcmp (asm_file_name, "-"))
-	asm_out_file = stdout;
+	casm->out_file = stdout;
       else if (!canonical_filename_eq (asm_file_name, name)
 	       || !strcmp (asm_file_name, HOST_BIT_BUCKET))
-	asm_out_file = fopen (asm_file_name, "w");
+	casm->out_file = fopen (asm_file_name, "w");
       else
 	/* Use UNKOWN_LOCATION to prevent gcc from printing the first
 	   line in the current file. */
 	fatal_error (UNKNOWN_LOCATION,
 		     "input file %qs is the same as output file",
 		     asm_file_name);
-      if (asm_out_file == 0)
+      if (casm->out_file == 0)
 	fatal_error (UNKNOWN_LOCATION,
 		     "cannot open %qs for writing: %m", asm_file_name);
     }
@@ -741,14 +742,14 @@ init_asm_output (const char *name)
 
       if (flag_verbose_asm)
 	{
-	  print_version (asm_out_file, ASM_COMMENT_START, true);
-	  fputs (ASM_COMMENT_START, asm_out_file);
-	  fputs (" options passed: ", asm_out_file);
+	  print_version (casm->out_file, ASM_COMMENT_START, true);
+	  fputs (ASM_COMMENT_START, casm->out_file);
+	  fputs (" options passed: ", casm->out_file);
 	  char *cmdline = gen_command_line_string (save_decoded_options,
 						   save_decoded_options_count);
-	  fputs (cmdline, asm_out_file);
+	  fputs (cmdline, casm->out_file);
 	  free (cmdline);
-	  fputc ('\n', asm_out_file);
+	  fputc ('\n', casm->out_file);
 	}
     }
 }
@@ -1847,7 +1848,8 @@ lang_dependent_init (const char *name)
 
   if (!flag_wpa)
     {
-      init_asm_output (name);
+      if (!flag_syntax_only)
+	init_asm_output (name);
 
       if (!flag_generate_lto && !flag_compare_debug)
 	{
@@ -2006,13 +2008,13 @@ finalize (bool no_backend)
      whether fclose returns an error, since the pages might still be on the
      buffer chain while the file is open.  */
 
-  if (asm_out_file)
+  if (casm != NULL && casm->out_file)
     {
-      if (ferror (asm_out_file) != 0)
+      if (ferror (casm->out_file) != 0)
 	fatal_error (input_location, "error writing to %s: %m", asm_file_name);
-      if (fclose (asm_out_file) != 0)
+      if (fclose (casm->out_file) != 0)
 	fatal_error (input_location, "error closing %s: %m", asm_file_name);
-      asm_out_file = NULL;
+      casm->out_file = NULL;
     }
 
   if (stack_usage_file)
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 09316c62050..3ddabca9421 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -130,43 +130,6 @@ static void mark_weak (tree);
 static void output_constant_pool (const char *, tree);
 static void handle_vtv_comdat_section (section *, const_tree);
 \f
-/* Well-known sections, each one associated with some sort of *_ASM_OP.  */
-section *text_section;
-section *data_section;
-section *readonly_data_section;
-section *sdata_section;
-section *ctors_section;
-section *dtors_section;
-section *bss_section;
-section *sbss_section;
-
-/* Various forms of common section.  All are guaranteed to be nonnull.  */
-section *tls_comm_section;
-section *comm_section;
-section *lcomm_section;
-
-/* A SECTION_NOSWITCH section used for declaring global BSS variables.
-   May be null.  */
-section *bss_noswitch_section;
-
-/* The section that holds the main exception table, when known.  The section
-   is set either by the target's init_sections hook or by the first call to
-   switch_to_exception_section.  */
-section *exception_section;
-
-/* The section that holds the DWARF2 frame unwind information, when known.
-   The section is set either by the target's init_sections hook or by the
-   first call to switch_to_eh_frame_section.  */
-section *eh_frame_section;
-
-/* asm_out_file's current section.  This is NULL if no section has yet
-   been selected or if we lose track of what the current section is.  */
-section *in_section;
-
-/* True if code for the current function is currently being directed
-   at the cold section.  */
-bool in_cold_section_p;
-
 /* The following global holds the "function name" for the code in the
    cold section of a function, if hot/cold function splitting is enabled
    and there was actually code that went into the cold section.  A
@@ -181,17 +144,6 @@ static GTY(()) section *unnamed_sections;
 #define IN_NAMED_SECTION(DECL) \
   (VAR_OR_FUNCTION_DECL_P (DECL) && DECL_SECTION_NAME (DECL) != NULL)
 
-struct section_hasher : ggc_ptr_hash<section>
-{
-  typedef const char *compare_type;
-
-  static hashval_t hash (section *);
-  static bool equal (section *, const char *);
-};
-
-/* Hash table of named sections.  */
-static GTY(()) hash_table<section_hasher> *section_htab;
-
 struct object_block_hasher : ggc_ptr_hash<object_block>
 {
   typedef const section *compare_type;
@@ -203,9 +155,6 @@ struct object_block_hasher : ggc_ptr_hash<object_block>
 /* A table of object_blocks, indexed by section.  */
 static GTY(()) hash_table<object_block_hasher> *object_block_htab;
 
-/* The next number to use for internal anchor labels.  */
-static GTY(()) int anchor_labelno;
-
 /* A pool of constants that can be shared between functions.  */
 static GTY(()) struct rtx_constant_pool *shared_constant_pool;
 
@@ -294,8 +243,8 @@ get_section (const char *name, unsigned int flags, tree decl,
 {
   section *sect, **slot;
 
-  slot = section_htab->find_slot_with_hash (name, htab_hash_string (name),
-					    INSERT);
+  slot = casm->section_htab->find_slot_with_hash (name, htab_hash_string (name),
+						  INSERT);
   flags |= SECTION_NAMED;
   if (decl != nullptr
       && DECL_P (decl)
@@ -510,7 +459,7 @@ asm_output_aligned_bss (FILE *file, tree decl ATTRIBUTE_UNUSED,
 			const char *name, unsigned HOST_WIDE_INT size,
 			int align)
 {
-  switch_to_section (bss_section);
+  switch_to_section (casm->sec.bss);
   ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
 #ifdef ASM_DECLARE_OBJECT_NAME
   last_assemble_variable_decl = decl;
@@ -527,7 +476,7 @@ asm_output_aligned_bss (FILE *file, tree decl ATTRIBUTE_UNUSED,
 #endif /* BSS_SECTION_ASM_OP */
 
 #ifndef USE_SELECT_SECTION_FOR_FUNCTIONS
-/* Return the hot section for function DECL.  Return text_section for
+/* Return the hot section for function DECL.  Return casm->sec.text for
    null DECLs.  */
 
 static section *
@@ -538,7 +487,7 @@ hot_function_section (tree decl)
       && targetm_common.have_named_sections)
     return get_named_section (decl, NULL, 0);
   else
-    return text_section;
+    return casm->sec.text;
 }
 #endif
 
@@ -718,7 +667,7 @@ function_section (tree decl)
 section *
 current_function_section (void)
 {
-  return function_section_1 (current_function_decl, in_cold_section_p);
+  return function_section_1 (current_function_decl, casm->in_cold_section_p);
 }
 
 /* Tell assembler to switch to unlikely-to-be-executed text section.  */
@@ -746,7 +695,7 @@ unlikely_text_section_p (section *sect)
 void
 switch_to_other_text_partition (void)
 {
-  in_cold_section_p = !in_cold_section_p;
+  casm->in_cold_section_p = !casm->in_cold_section_p;
   switch_to_section (current_function_section ());
 }
 
@@ -831,7 +780,7 @@ default_function_rodata_section (tree decl, bool relocatable)
   if (relocatable)
     return get_section (sname, flags, decl);
   else
-    return readonly_data_section;
+    return casm->sec.readonly_data;
 }
 
 /* Return the read-only data section associated with function DECL
@@ -841,7 +790,7 @@ default_function_rodata_section (tree decl, bool relocatable)
 section *
 default_no_function_rodata_section (tree, bool)
 {
-  return readonly_data_section;
+  return casm->sec.readonly_data;
 }
 
 /* A subroutine of mergeable_string_section and mergeable_constant_section.  */
@@ -890,7 +839,7 @@ mergeable_string_section (tree decl ATTRIBUTE_UNUSED,
 	    align = modesize;
 
 	  if (!HAVE_LD_ALIGNED_SHF_MERGE && align > 8)
-	    return readonly_data_section;
+	    return casm->sec.readonly_data;
 
 	  str = TREE_STRING_POINTER (decl);
 	  unit = GET_MODE_SIZE (mode);
@@ -914,7 +863,7 @@ mergeable_string_section (tree decl ATTRIBUTE_UNUSED,
 	}
     }
 
-  return readonly_data_section;
+  return casm->sec.readonly_data;
 }
 
 /* Return the section to use for constant merging.  */
@@ -940,7 +889,7 @@ mergeable_constant_section (machine_mode mode ATTRIBUTE_UNUSED,
       flags |= (align / 8) | SECTION_MERGE;
       return get_section (name, flags, NULL);
     }
-  return readonly_data_section;
+  return casm->sec.readonly_data;
 }
 \f
 /* Given NAME, a putative register name, discard any customary prefixes.  */
@@ -1253,9 +1202,9 @@ get_variable_section (tree decl, bool prefer_noswitch_p)
       gcc_assert (DECL_SECTION_NAME (decl) == NULL
 		  && ADDR_SPACE_GENERIC_P (as));
       if (DECL_THREAD_LOCAL_P (decl))
-	return tls_comm_section;
+	return casm->sec.tls_comm;
       else if (TREE_PUBLIC (decl) && bss_initializer_p (decl))
-	return comm_section;
+	return casm->sec.comm;
     }
 
   reloc = compute_reloc_for_var (decl);
@@ -1285,9 +1234,9 @@ get_variable_section (tree decl, bool prefer_noswitch_p)
       if (!TREE_PUBLIC (decl)
 	  && !((flag_sanitize & SANITIZE_ADDRESS)
 	       && asan_protect_global (decl)))
-	return lcomm_section;
-      if (bss_noswitch_section)
-	return bss_noswitch_section;
+	return casm->sec.lcomm;
+      if (casm->sec.bss_noswitch)
+	return casm->sec.bss_noswitch;
     }
 
   return targetm.asm_out.select_section (decl, reloc,
@@ -1733,7 +1682,7 @@ void
 default_dtor_section_asm_out_destructor (rtx symbol,
 					 int priority ATTRIBUTE_UNUSED)
 {
-  assemble_addr_to_section (symbol, dtors_section);
+  assemble_addr_to_section (symbol, casm->sec.dtors);
 }
 #endif
 
@@ -1756,7 +1705,7 @@ void
 default_ctor_section_asm_out_constructor (rtx symbol,
 					  int priority ATTRIBUTE_UNUSED)
 {
-  assemble_addr_to_section (symbol, ctors_section);
+  assemble_addr_to_section (symbol, casm->sec.ctors);
 }
 #endif
 \f
@@ -1824,7 +1773,7 @@ decide_function_section (tree decl)
 				      == NODE_FREQUENCY_UNLIKELY_EXECUTED);
     }
 
-  in_cold_section_p = first_function_block_is_cold;
+  casm->in_cold_section_p = first_function_block_is_cold;
 }
 
 /* Get the function's name, as described by its RTL.  This may be
@@ -1900,13 +1849,13 @@ assemble_start_function (tree decl, const char *fnname)
       if (!cfun->is_thunk
 	  && BB_PARTITION (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb) == BB_COLD_PARTITION)
 	{
-	  switch_to_section (text_section);
+	  switch_to_section (casm->sec.text);
 	  assemble_align (align);
 	  ASM_OUTPUT_LABEL (asm_out_file, crtl->subsections.hot_section_label);
 	  hot_label_written = true;
 	  first_function_block_is_cold = true;
 	}
-      in_cold_section_p = first_function_block_is_cold;
+      casm->in_cold_section_p = first_function_block_is_cold;
     }
 
 
@@ -2020,7 +1969,7 @@ assemble_end_function (tree decl, const char *fnname ATTRIBUTE_UNUSED)
     {
       section *save_text_section;
 
-      save_text_section = in_section;
+      save_text_section = casm->in_section;
       switch_to_section (unlikely_text_section ());
 #ifdef ASM_DECLARE_COLD_FUNCTION_SIZE
       if (cold_function_name != NULL_TREE)
@@ -2030,7 +1979,7 @@ assemble_end_function (tree decl, const char *fnname ATTRIBUTE_UNUSED)
 #endif
       ASM_OUTPUT_LABEL (asm_out_file, crtl->subsections.cold_section_end_label);
       if (first_function_block_is_cold)
-	switch_to_section (text_section);
+	switch_to_section (casm->sec.text);
       else
 	switch_to_section (function_section (decl));
       ASM_OUTPUT_LABEL (asm_out_file, crtl->subsections.hot_section_end_label);
@@ -2050,7 +1999,7 @@ assemble_zeros (unsigned HOST_WIDE_INT size)
 #ifdef ASM_NO_SKIP_IN_TEXT
   /* The `space' pseudo in the text section outputs nop insns rather than 0s,
      so we must output 0s explicitly in the text section.  */
-  if (ASM_NO_SKIP_IN_TEXT && (in_section->common.flags & SECTION_CODE) != 0)
+  if (ASM_NO_SKIP_IN_TEXT && (casm->in_section->common.flags & SECTION_CODE) != 0)
     {
       unsigned HOST_WIDE_INT i;
       for (i = 0; i < size; i++)
@@ -2097,7 +2046,7 @@ assemble_string (const char *p, int size)
 }
 
 \f
-/* A noswitch_section_callback for lcomm_section.  */
+/* A noswitch_section_callback for casm->sec.lcomm.  */
 
 static bool
 emit_local (tree decl ATTRIBUTE_UNUSED,
@@ -2120,7 +2069,7 @@ emit_local (tree decl ATTRIBUTE_UNUSED,
 #endif
 }
 
-/* A noswitch_section_callback for bss_noswitch_section.  */
+/* A noswitch_section_callback for casm->sec.bss_noswitch.  */
 
 #if defined ASM_OUTPUT_ALIGNED_BSS
 static bool
@@ -2135,7 +2084,7 @@ emit_bss (tree decl ATTRIBUTE_UNUSED,
 }
 #endif
 
-/* A noswitch_section_callback for comm_section.  */
+/* A noswitch_section_callback for casm->sec.comm.  */
 
 static bool
 emit_common (tree decl ATTRIBUTE_UNUSED,
@@ -2157,7 +2106,7 @@ emit_common (tree decl ATTRIBUTE_UNUSED,
 #endif
 }
 
-/* A noswitch_section_callback for tls_comm_section.  */
+/* A noswitch_section_callback for casm->sec.tls_comm.  */
 
 static bool
 emit_tls_common (tree decl ATTRIBUTE_UNUSED,
@@ -2774,7 +2723,7 @@ assemble_trampoline_template (void)
 #ifdef TRAMPOLINE_SECTION
   switch_to_section (TRAMPOLINE_SECTION);
 #else
-  switch_to_section (readonly_data_section);
+  switch_to_section (casm->sec.readonly_data);
 #endif
 
   /* Write the assembler code to define one.  */
@@ -4192,8 +4141,8 @@ output_constant_pool_1 (class constant_descriptor_rtx *desc,
   /* Make sure all constants in SECTION_MERGE and not SECTION_STRINGS
      sections have proper size.  */
   if (align > GET_MODE_BITSIZE (desc->mode)
-      && in_section
-      && (in_section->common.flags & SECTION_MERGE))
+      && casm->in_section
+      && (casm->in_section->common.flags & SECTION_MERGE))
     assemble_align (align);
 
 #ifdef ASM_OUTPUT_SPECIAL_POOL_ENTRY
@@ -6599,79 +6548,95 @@ make_decl_one_only (tree decl, tree comdat_group)
     }
 }
 
-void
-init_varasm_once (void)
+/* Default constructor.  */
+
+asm_out_state::asm_out_state ()
+: out_file (NULL), in_section (NULL),
+  sec ({}), anchor_labelno (0), in_cold_section_p (false)
 {
   section_htab = hash_table<section_hasher>::create_ggc (31);
+
   object_block_htab = hash_table<object_block_hasher>::create_ggc (31);
   const_desc_htab = hash_table<tree_descriptor_hasher>::create_ggc (1009);
 
   shared_constant_pool = create_constant_pool ();
 
 #ifdef TEXT_SECTION_ASM_OP
-  text_section = get_unnamed_section (SECTION_CODE, output_section_asm_op,
-				      TEXT_SECTION_ASM_OP);
+  sec.text = get_unnamed_section (SECTION_CODE, output_section_asm_op,
+				  TEXT_SECTION_ASM_OP);
 #endif
 
 #ifdef DATA_SECTION_ASM_OP
-  data_section = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
-				      DATA_SECTION_ASM_OP);
+  sec.data = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
+				  DATA_SECTION_ASM_OP);
 #endif
 
 #ifdef SDATA_SECTION_ASM_OP
-  sdata_section = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
-				       SDATA_SECTION_ASM_OP);
+  sec.sdata = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
+				   SDATA_SECTION_ASM_OP);
 #endif
 
 #ifdef READONLY_DATA_SECTION_ASM_OP
-  readonly_data_section = get_unnamed_section (0, output_section_asm_op,
-					       READONLY_DATA_SECTION_ASM_OP);
+  sec.readonly_data = get_unnamed_section (0, output_section_asm_op,
+					   READONLY_DATA_SECTION_ASM_OP);
 #endif
 
 #ifdef CTORS_SECTION_ASM_OP
-  ctors_section = get_unnamed_section (0, output_section_asm_op,
-				       CTORS_SECTION_ASM_OP);
+  sec.ctors = get_unnamed_section (0, output_section_asm_op,
+				   CTORS_SECTION_ASM_OP);
 #endif
 
 #ifdef DTORS_SECTION_ASM_OP
-  dtors_section = get_unnamed_section (0, output_section_asm_op,
-				       DTORS_SECTION_ASM_OP);
+  sec.dtors = get_unnamed_section (0, output_section_asm_op,
+				   DTORS_SECTION_ASM_OP);
 #endif
 
 #ifdef BSS_SECTION_ASM_OP
-  bss_section = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
-				     output_section_asm_op,
-				     BSS_SECTION_ASM_OP);
+  sec.bss = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
+				 output_section_asm_op,
+				 BSS_SECTION_ASM_OP);
 #endif
 
 #ifdef SBSS_SECTION_ASM_OP
-  sbss_section = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
-				      output_section_asm_op,
-				      SBSS_SECTION_ASM_OP);
+  sec.sbss = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
+				  output_section_asm_op,
+				  SBSS_SECTION_ASM_OP);
 #endif
 
-  tls_comm_section = get_noswitch_section (SECTION_WRITE | SECTION_BSS
-					   | SECTION_COMMON, emit_tls_common);
-  lcomm_section = get_noswitch_section (SECTION_WRITE | SECTION_BSS
-					| SECTION_COMMON, emit_local);
-  comm_section = get_noswitch_section (SECTION_WRITE | SECTION_BSS
-				       | SECTION_COMMON, emit_common);
+  sec.tls_comm = get_noswitch_section (SECTION_WRITE | SECTION_BSS
+				       | SECTION_COMMON, emit_tls_common);
+  sec.lcomm = get_noswitch_section (SECTION_WRITE | SECTION_BSS
+				    | SECTION_COMMON, emit_local);
+  sec.comm = get_noswitch_section (SECTION_WRITE | SECTION_BSS
+				   | SECTION_COMMON, emit_common);
 
 #if defined ASM_OUTPUT_ALIGNED_BSS
-  bss_noswitch_section = get_noswitch_section (SECTION_WRITE | SECTION_BSS,
-					       emit_bss);
+  sec.bss_noswitch = get_noswitch_section (SECTION_WRITE | SECTION_BSS,
+					   emit_bss);
 #endif
 
-  targetm.asm_out.init_sections ();
+  if (sec.readonly_data == NULL)
+    sec.readonly_data = sec.text;
+}
 
-  if (readonly_data_section == NULL)
-    readonly_data_section = text_section;
+void
+init_varasm_once (void)
+{
+  casm = targetm.asm_out.init_sections ();
 
 #ifdef ASM_OUTPUT_EXTERNAL
   pending_assemble_externals_set = new hash_set<tree>;
 #endif
 }
 
+/* Default implementation of init_sections target hook.  */
+
+asm_out_state *
+default_init_sections (void)
+{
+  return new (ggc_alloc<asm_out_state> ()) asm_out_state ();
+}
+
 enum tls_model
 decl_default_tls_model (const_tree decl)
 {
@@ -6790,13 +6755,13 @@ default_section_type_flags (tree decl, const char *name, int reloc)
 }
 
 /* Return true if the target supports some form of global BSS,
-   either through bss_noswitch_section, or by selecting a BSS
+   either through casm->sec.bss_noswitch, or by selecting a BSS
    section in TARGET_ASM_SELECT_SECTION.  */
 
 bool
 have_global_bss_p (void)
 {
-  return bss_noswitch_section || targetm.have_switchable_bss_sections;
+  return casm->sec.bss_noswitch || targetm.have_switchable_bss_sections;
 }
 
 /* Output assembly to switch to section NAME with attribute FLAGS.
@@ -6958,7 +6923,7 @@ default_select_section (tree decl, int reloc,
   if (DECL_P (decl))
     {
       if (decl_readonly_section (decl, reloc))
-	return readonly_data_section;
+	return casm->sec.readonly_data;
     }
   else if (TREE_CODE (decl) == CONSTRUCTOR)
     {
@@ -6966,14 +6931,14 @@ default_select_section (tree decl, int reloc,
 	     || !TREE_READONLY (decl)
 	     || TREE_SIDE_EFFECTS (decl)
 	     || !TREE_CONSTANT (decl)))
-	return readonly_data_section;
+	return casm->sec.readonly_data;
     }
   else if (TREE_CODE (decl) == STRING_CST)
-    return readonly_data_section;
+    return casm->sec.readonly_data;
   else if (! (flag_pic && reloc))
-    return readonly_data_section;
+    return casm->sec.readonly_data;
 
-  return data_section;
+  return casm->sec.data;
 }
 
 enum section_category
@@ -7112,7 +7077,7 @@ default_elf_select_section (tree decl, int reloc,
       /* We're not supposed to be called on FUNCTION_DECLs.  */
       gcc_unreachable ();
     case SECCAT_RODATA:
-      return readonly_data_section;
+      return casm->sec.readonly_data;
     case SECCAT_RODATA_MERGE_STR:
       return mergeable_string_section (decl, align, 0);
     case SECCAT_RODATA_MERGE_STR_INIT:
@@ -7128,7 +7093,7 @@ default_elf_select_section (tree decl, int reloc,
 	  sname = ".persistent";
 	  break;
 	}
-      return data_section;
+      return casm->sec.data;
     case SECCAT_DATA_REL:
       sname = ".data.rel";
       break;
@@ -7153,8 +7118,8 @@ default_elf_select_section (tree decl, int reloc,
 	  sname = ".noinit";
 	  break;
 	}
-      if (bss_section)
-	return bss_section;
+      if (casm->sec.bss)
+	return casm->sec.bss;
       sname = ".bss";
       break;
     case SECCAT_SBSS:
@@ -7304,9 +7269,9 @@ default_select_rtx_section (machine_mode mode ATTRIBUTE_UNUSED,
 			    unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
 {
   if (compute_reloc_for_rtx (x) & targetm.asm_out.reloc_rw_mask ())
-    return data_section;
+    return casm->sec.data;
   else
-    return readonly_data_section;
+    return casm->sec.readonly_data;
 }
 
 section *
@@ -7824,10 +7789,10 @@ switch_to_section (section *new_section, tree decl)
 		  "%qD was declared here", used_decl);
 	}
     }
-  else if (in_section == new_section)
+  else if (casm->in_section == new_section)
     return;
 
-  in_section = new_section;
+  casm->in_section = new_section;
 
   switch (SECTION_STYLE (new_section))
     {
@@ -8003,7 +7968,7 @@ get_section_anchor (struct object_block *block, HOST_WIDE_INT offset,
     }
 
   /* Create a new anchor with a unique label.  */
-  ASM_GENERATE_INTERNAL_LABEL (label, "LANCHOR", anchor_labelno++);
+  ASM_GENERATE_INTERNAL_LABEL (label, "LANCHOR", casm->anchor_labelno++);
   anchor = create_block_symbol (ggc_strdup (label), block, offset);
   SYMBOL_REF_FLAGS (anchor) |= SYMBOL_FLAG_LOCAL | SYMBOL_FLAG_ANCHOR;
   SYMBOL_REF_FLAGS (anchor) |= model << SYMBOL_FLAG_TLS_SHIFT;
@@ -8472,7 +8437,7 @@ handle_vtv_comdat_section (section *sect, const_tree decl ATTRIBUTE_UNUSED)
 				 sect->named.common.flags
 				 | SECTION_LINKONCE,
 				 DECL_NAME (decl));
-  in_section = sect;
+  casm->in_section = sect;
 #else
   /* Neither OBJECT_FORMAT_PE, nor OBJECT_FORMAT_COFF is set here.
      Therefore the following check is used.
@@ -8498,7 +8463,7 @@ handle_vtv_comdat_section (section *sect, const_tree decl ATTRIBUTE_UNUSED)
 				     sect->named.common.flags
 				     | SECTION_LINKONCE,
 				     DECL_NAME (decl));
-      in_section = sect;
+      casm->in_section = sect;
     }
   else
     switch_to_section (sect);
diff --git a/gcc/vmsdbgout.c b/gcc/vmsdbgout.c
index 05fadce075e..eab52c62307 100644
--- a/gcc/vmsdbgout.c
+++ b/gcc/vmsdbgout.c
@@ -1583,7 +1583,7 @@ vmsdbgout_finish (const char *filename ATTRIBUTE_UNUSED)
     return;
 
   /* Output a terminator label for the .text section.  */
-  switch_to_section (text_section);
+  switch_to_section (casm->sec.text);
   targetm.asm_out.internal_label (asm_out_file, TEXT_END_LABEL, 0);
 
   /* Output debugging information.
-- 
2.33.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 3/N] Come up with casm global state.
  2021-10-25 10:46               ` Richard Biener
  2021-10-25 13:36                 ` Martin Liška
@ 2021-10-25 16:06                 ` Segher Boessenkool
  1 sibling, 0 replies; 30+ messages in thread
From: Segher Boessenkool @ 2021-10-25 16:06 UTC (permalink / raw)
  To: Richard Biener; +Cc: Martin Liška, GCC Patches

On Mon, Oct 25, 2021 at 12:46:30PM +0200, Richard Biener wrote:
> On Thu, Oct 21, 2021 at 5:42 PM Segher Boessenkool
> <segher@kernel.crashing.org> wrote:
> > It's disgusting, and fragile.  The define is slightly better than having
> > to write it out every time.  But can this not be done properly?
> >
> > If you use object-oriented stuff and need casts for that, you are doing
> > something wrong.
> 
> I think the "proper" fix would be to make 'casm' have the correct type
> in the first place

+1

> - of course that would either mean that the target
> needs to provide the (possibly derived) type, for example via a typedef
> in the target structure or a classical target macro.  If gengtype would
> know about inheritance that would also fix the GC marking issue.

Do we want gengtype to do inheritance, will it solve more future
problems, or will it *cause* more problems later?

> Of course encoding a static type in the target structure is the
> wrong direction from making targets "switchable".

Yes.

> Other than that my C++ fu is too weak to suggest the correct "pattern"
> here.

Virtual functions something something?


Segher

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 3/N] Come up with casm global state.
  2021-10-25 13:36                 ` Martin Liška
@ 2021-10-25 16:30                   ` Segher Boessenkool
  2021-10-26  7:45                     ` Richard Biener
  0 siblings, 1 reply; 30+ messages in thread
From: Segher Boessenkool @ 2021-10-25 16:30 UTC (permalink / raw)
  To: Martin Liška; +Cc: Richard Biener, GCC Patches

Hi!

On Mon, Oct 25, 2021 at 03:36:25PM +0200, Martin Liška wrote:
> --- a/gcc/config/rs6000/rs6000-internal.h
> +++ b/gcc/config/rs6000/rs6000-internal.h
> @@ -189,4 +189,13 @@ extern bool rs6000_passes_vector;
>  extern bool rs6000_returns_struct;
>  extern bool cpu_builtin_p;
>  
> +struct rs6000_asm_out_state : public asm_out_state
> +{
> +  /* Initialize ELF sections. */
> +  void init_elf_sections ();
> +
> +  /* Initialize XCOFF sections. */
> +  void init_xcoff_sections ();
> +};

Our coding convention says to use "class", not "struct" (since this
isn't valid C code at all).

> -  sdata2_section
> + sec.sdata2
>      = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
>  			   SDATA2_SECTION_ASM_OP);

(broken indentation)

> +/* Implement TARGET_ASM_INIT_SECTIONS.  */

That comment is out-of-date.

> +static asm_out_state *
> +rs6000_elf_asm_init_sections (void)
> +{
> +  rs6000_asm_out_state *target_state
> +    = new (ggc_alloc<rs6000_asm_out_state> ()) rs6000_asm_out_state ();

Hrm, maybe we can have a macro or function that does this, ggc_new or
something?

> +/* Implement TARGET_ASM_INIT_SECTIONS.  */
> +
> +static asm_out_state *
> +rs6000_xcoff_asm_init_sections (void)

Here, too.  Both implementations are each one of several functions that
together implement the target macro.

> +    /* The section that holds the DWARF2 frame unwind information, when known.
> +       The section is set either by the target's init_sections hook or by the
> +       first call to switch_to_eh_frame_section.  */
> +    section *eh_frame;
> +
> +    /* RS6000 sections.  */

Nothing here?  Just remove the comment header?

The idea looks fine to me.


Segher

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 3/N] Come up with casm global state.
  2021-10-25 16:30                   ` Segher Boessenkool
@ 2021-10-26  7:45                     ` Richard Biener
  2021-11-05 14:27                       ` Martin Liška
  0 siblings, 1 reply; 30+ messages in thread
From: Richard Biener @ 2021-10-26  7:45 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: Martin Liška, GCC Patches

On Mon, Oct 25, 2021 at 6:32 PM Segher Boessenkool
<segher@kernel.crashing.org> wrote:
>
> Hi!
>
> On Mon, Oct 25, 2021 at 03:36:25PM +0200, Martin Liška wrote:
> > --- a/gcc/config/rs6000/rs6000-internal.h
> > +++ b/gcc/config/rs6000/rs6000-internal.h
> > @@ -189,4 +189,13 @@ extern bool rs6000_passes_vector;
> >  extern bool rs6000_returns_struct;
> >  extern bool cpu_builtin_p;
> >
> > +struct rs6000_asm_out_state : public asm_out_state
> > +{
> > +  /* Initialize ELF sections. */
> > +  void init_elf_sections ();
> > +
> > +  /* Initialize XCOFF sections. */
> > +  void init_xcoff_sections ();
> > +};
>
> Our coding convention says to use "class", not "struct" (since this
> isn't valid C code at all).
>
> > -  sdata2_section
> > + sec.sdata2
> >      = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
> >                          SDATA2_SECTION_ASM_OP);
>
> (broken indentation)
>
> > +/* Implement TARGET_ASM_INIT_SECTIONS.  */
>
> That comment is out-of-date.
>
> > +static asm_out_state *
> > +rs6000_elf_asm_init_sections (void)
> > +{
> > +  rs6000_asm_out_state *target_state
> > +    = new (ggc_alloc<rs6000_asm_out_state> ()) rs6000_asm_out_state ();
>
> Hrm, maybe we can have a macro or function that does this, ggc_new or
> something?
>
> > +/* Implement TARGET_ASM_INIT_SECTIONS.  */
> > +
> > +static asm_out_state *
> > +rs6000_xcoff_asm_init_sections (void)
>
> Here, too.  Both implementations are each one of several functions that
> together implement the target macro.
>
> > +    /* The section that holds the DWARF2 frame unwind information, when known.
> > +       The section is set either by the target's init_sections hook or by the
> > +       first call to switch_to_eh_frame_section.  */
> > +    section *eh_frame;
> > +
> > +    /* RS6000 sections.  */
>
> Nothing here?  Just remove the comment header?
>
> The idea looks fine to me.

Yeah, of course then the target hook does not need to do the allocation
and we could simply keep the current init_sections hook but change it
to take the asm_out_state to initialize as argument.

Note that I'd put

+    /* RS6000 sections.  */
+
+    /* ELF sections.  */
+    section *toc;
+    section *sdata2;
+
+    /* XCOFF sections.  */
+    section *read_only_data;
+    section *private_data;
+    section *tls_data;
+    section *tls_private_data;
+    section *read_only_private_data;

into a union, thus

   union {
       struct /* RS6000 sections */ {
           /* ELF sections.  */
          section *toc;
...
       } rs6000;
       struct /* darwin sections */ {
 ...
   };

not sure whether we need some magic GTY marking here to make
it pick up the 'correct' set.  Another alternative would be

         section *target[MAX_TARGET_SECTIONS];

and #defines in the targets mapping the former global variables to
indices in that array.

All of this isn't "nice C++" of course, but well ... I'm not the one
to insist ;)

Richard.

>
> Segher

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 3/N] Come up with casm global state.
  2021-10-26  7:45                     ` Richard Biener
@ 2021-11-05 14:27                       ` Martin Liška
  2021-11-09 12:49                         ` Richard Biener
  0 siblings, 1 reply; 30+ messages in thread
From: Martin Liška @ 2021-11-05 14:27 UTC (permalink / raw)
  To: Richard Biener, Segher Boessenkool; +Cc: GCC Patches

On 10/26/21 09:45, Richard Biener wrote:
> On Mon, Oct 25, 2021 at 6:32 PM Segher Boessenkool
> <segher@kernel.crashing.org> wrote:
>>
>> Hi!
>>
>> On Mon, Oct 25, 2021 at 03:36:25PM +0200, Martin Liška wrote:
>>> --- a/gcc/config/rs6000/rs6000-internal.h
>>> +++ b/gcc/config/rs6000/rs6000-internal.h
>>> @@ -189,4 +189,13 @@ extern bool rs6000_passes_vector;
>>>   extern bool rs6000_returns_struct;
>>>   extern bool cpu_builtin_p;
>>>
>>> +struct rs6000_asm_out_state : public asm_out_state
>>> +{
>>> +  /* Initialize ELF sections. */
>>> +  void init_elf_sections ();
>>> +
>>> +  /* Initialize XCOFF sections. */
>>> +  void init_xcoff_sections ();
>>> +};
>>
>> Our coding convention says to use "class", not "struct" (since this
>> isn't valid C code at all).
>>
>>> -  sdata2_section
>>> + sec.sdata2
>>>       = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
>>>                           SDATA2_SECTION_ASM_OP);
>>
>> (broken indentation)
>>
>>> +/* Implement TARGET_ASM_INIT_SECTIONS.  */
>>
>> That comment is out-of-date.
>>
>>> +static asm_out_state *
>>> +rs6000_elf_asm_init_sections (void)
>>> +{
>>> +  rs6000_asm_out_state *target_state
>>> +    = new (ggc_alloc<rs6000_asm_out_state> ()) rs6000_asm_out_state ();
>>
>> Hrm, maybe we can have a macro or function that does this, ggc_new or
>> something?
>>
>>> +/* Implement TARGET_ASM_INIT_SECTIONS.  */
>>> +
>>> +static asm_out_state *
>>> +rs6000_xcoff_asm_init_sections (void)
>>
>> Here, too.  Both implementations are each one of several functions that
>> together implement the target macro.
>>
>>> +    /* The section that holds the DWARF2 frame unwind information, when known.
>>> +       The section is set either by the target's init_sections hook or by the
>>> +       first call to switch_to_eh_frame_section.  */
>>> +    section *eh_frame;
>>> +
>>> +    /* RS6000 sections.  */
>>
>> Nothing here?  Just remove the comment header?
>>
>> The idea looks fine to me.
> 
> Yeah, of course then the target hook does not need to do the allocation
> and we could simply keep the current init_sections hook but change it
> to take the asm_out_state to initialize as argument.

Makes sense.

> 
> Note that I'd put
> 
> +    /* RS6000 sections.  */
> +
> +    /* ELF sections.  */
> +    section *toc;
> +    section *sdata2;
> +
> +    /* XCOFF sections.  */
> +    section *read_only_data;
> +    section *private_data;
> +    section *tls_data;
> +    section *tls_private_data;
> +    section *read_only_private_data;
> 
> into a union, thus
> 
>     union {
>         struct /* RS6000 sections */ {
>             /* ELF sections.  */
>            section *toc;
> ...
>         } rs6000;
>         struct /* darwin sections */ {
>   ...
>     };

Union is a bit tricky for GGC marking script, but we can manage that.

> 
> not sure whether we need some magic GTY marking here to make
> it pick up the 'correct' set.  Another alternative would be
> 
>           section *target[MAX_TARGET_SECTIONS];
> 
> and #defines in the targets mapping the former global variables to
> indices in that array.
> 
> All of this isn't "nice C++" of course, but well ... I'm not the one
> to insist ;)

Anyway, I took a look at targets that do call the init_sections hook and I noticed
Darwin uses pretty many sections and comes up with an array that is defined here:
./gcc/config/darwin-sections.def

I tend to creating all sections in asm_out_state with DEF_SECTION, where the list
will be extensible with a target-specific definition list.

What do you think Richi?

Thanks,
Martin

> 
> Richard.
> 
>>
>> Segher


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 3/N] Come up with casm global state.
  2021-11-05 14:27                       ` Martin Liška
@ 2021-11-09 12:49                         ` Richard Biener
  0 siblings, 0 replies; 30+ messages in thread
From: Richard Biener @ 2021-11-09 12:49 UTC (permalink / raw)
  To: Martin Liška; +Cc: Segher Boessenkool, GCC Patches

On Fri, Nov 5, 2021 at 3:27 PM Martin Liška <mliska@suse.cz> wrote:
>
> On 10/26/21 09:45, Richard Biener wrote:
> > On Mon, Oct 25, 2021 at 6:32 PM Segher Boessenkool
> > <segher@kernel.crashing.org> wrote:
> >>
> >> Hi!
> >>
> >> On Mon, Oct 25, 2021 at 03:36:25PM +0200, Martin Liška wrote:
> >>> --- a/gcc/config/rs6000/rs6000-internal.h
> >>> +++ b/gcc/config/rs6000/rs6000-internal.h
> >>> @@ -189,4 +189,13 @@ extern bool rs6000_passes_vector;
> >>>   extern bool rs6000_returns_struct;
> >>>   extern bool cpu_builtin_p;
> >>>
> >>> +struct rs6000_asm_out_state : public asm_out_state
> >>> +{
> >>> +  /* Initialize ELF sections. */
> >>> +  void init_elf_sections ();
> >>> +
> >>> +  /* Initialize XCOFF sections. */
> >>> +  void init_xcoff_sections ();
> >>> +};
> >>
> >> Our coding convention says to use "class", not "struct" (since this
> >> isn't valid C code at all).
> >>
> >>> -  sdata2_section
> >>> + sec.sdata2
> >>>       = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
> >>>                           SDATA2_SECTION_ASM_OP);
> >>
> >> (broken indentation)
> >>
> >>> +/* Implement TARGET_ASM_INIT_SECTIONS.  */
> >>
> >> That comment is out-of-date.
> >>
> >>> +static asm_out_state *
> >>> +rs6000_elf_asm_init_sections (void)
> >>> +{
> >>> +  rs6000_asm_out_state *target_state
> >>> +    = new (ggc_alloc<rs6000_asm_out_state> ()) rs6000_asm_out_state ();
> >>
> >> Hrm, maybe we can have a macro or function that does this, ggc_new or
> >> something?
> >>
> >>> +/* Implement TARGET_ASM_INIT_SECTIONS.  */
> >>> +
> >>> +static asm_out_state *
> >>> +rs6000_xcoff_asm_init_sections (void)
> >>
> >> Here, too.  Both implementations are each one of several functions that
> >> together implement the target macro.
> >>
> >>> +    /* The section that holds the DWARF2 frame unwind information, when known.
> >>> +       The section is set either by the target's init_sections hook or by the
> >>> +       first call to switch_to_eh_frame_section.  */
> >>> +    section *eh_frame;
> >>> +
> >>> +    /* RS6000 sections.  */
> >>
> >> Nothing here?  Just remove the comment header?
> >>
> >> The idea looks fine to me.
> >
> > Yeah, of course then the target hook does not need to do the allocation
> > and we could simply keep the current init_sections hook but change it
> > to take the asm_out_state to initialize as argument.
>
> Makes sense.
>
> >
> > Note that I'd put
> >
> > +    /* RS6000 sections.  */
> > +
> > +    /* ELF sections.  */
> > +    section *toc;
> > +    section *sdata2;
> > +
> > +    /* XCOFF sections.  */
> > +    section *read_only_data;
> > +    section *private_data;
> > +    section *tls_data;
> > +    section *tls_private_data;
> > +    section *read_only_private_data;
> >
> > into a union, thus
> >
> >     union {
> >         struct /* RS6000 sections */ {
> >             /* ELF sections.  */
> >            section *toc;
> > ...
> >         } rs6000;
> >         struct /* darwin sections */ {
> >   ...
> >     };
>
> Union is a bit tricky for GGC marking script, but we can manage that.
>
> >
> > not sure whether we need some magic GTY marking here to make
> > it pick up the 'correct' set.  Another alternative would be
> >
> >           section *target[MAX_TARGET_SECTIONS];
> >
> > and #defines in the targets mapping the former global variables to
> > indices in that array.
> >
> > All of this isn't "nice C++" of course, but well ... I'm not the one
> > to insist ;)
>
> Anyway, I took a look at targets that do call the init_sections hook and I noticed
> Darwin uses pretty many sections and comes up with an array that is defined here:
> ./gcc/config/darwin-sections.def
>
> I tend to creating all sections in asm_out_state with DEF_SECTION, where the list
> will be extensible with a target-specific definition list.
>
> What do you think Richi?

That sounds good to me as well.

Richard.

>
> Thanks,
> Martin
>
> >
> > Richard.
> >
> >>
> >> Segher
>

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2021-11-09 12:49 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-10  9:31 [PATCH][RFC] Come up with casm state Martin Liška
2021-09-16 10:00 ` [PATCH 1/N] Rename asm_out_file function arguments Martin Liška
2021-09-16 13:52   ` Iain Sandoe
2021-09-17  8:23     ` Richard Biener
2021-09-17  9:42       ` Iain Sandoe
2021-09-17  9:57         ` Richard Biener
2021-10-20 11:57   ` Martin Liška
2021-10-20 12:11     ` Richard Biener
2021-09-16 10:00 ` [PATCH 2/N] Do not hide asm_out_file in ASM_OUTPUT_ASCII Martin Liška
2021-09-22  9:44   ` Richard Biener
2021-09-30 11:46     ` Martin Liška
2021-09-16 13:12 ` [PATCH 3/N] Come up with casm global state Martin Liška
2021-09-22  9:59   ` Richard Biener
2021-10-04 11:13     ` Martin Liška
2021-10-05 11:54       ` Richard Biener
2021-10-21  9:47         ` Martin Liška
2021-10-21 12:42           ` Richard Biener
2021-10-21 13:43             ` Martin Liška
2021-10-21 13:57               ` Richard Biener
2021-10-21 15:40             ` Segher Boessenkool
2021-10-25 10:46               ` Richard Biener
2021-10-25 13:36                 ` Martin Liška
2021-10-25 16:30                   ` Segher Boessenkool
2021-10-26  7:45                     ` Richard Biener
2021-11-05 14:27                       ` Martin Liška
2021-11-09 12:49                         ` Richard Biener
2021-10-25 16:06                 ` Segher Boessenkool
2021-10-04 11:16   ` Martin Liška
2021-10-21 12:47   ` David Malcolm
2021-10-21 13:08     ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).