This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 10/16] binutils: Introduce "gas_main", and state-purging with "gas" subdir


Currently this has only been tested on x86_64, and hardcodes this
cleanup:
  extern void config_obj_elf_c_finalize (void);
  extern void config_tc_i386_c_finalize (void);
Clearly this would need generalizing.

gas/ChangeLog:
	* app.c (app_c_finalize): New function.
	* as.c: Include new header "libgas.h".
	(gas_timer): New variable.
	(emulations): Make the underlying struct emulation be const.
	(parse_args): Reset internal state of getopt_long_only.
	(main): Rename to gas_internal_main.  Make static.
	Add param "standalone".  Add uses of GAS_TIMER_PUSH and
	GAS_TIMER_POP.  Conditionalize calls to xatexit with check
	for "standalone", and explicitly call close_output_file in
	the non-standalone case.  Replace calls to xexit with
	return statements.
	(config_obj_elf_c_finalize): Add prototype.
	(config_tc_i386_c_finalize): Likwise.
	(gas_main): New function.
	(as_c_finalize): New function.
	* as.h (app_c_finalize): New prototype.
	(depend_c_finalize): New prototype.
	(gas_timer): New variable.
	(GAS_TIMER_PUSH): New macro.
	(GAS_TIMER_POP): New macro.
	* asmain.c: New file.
	* config/obj-elf.c (obj_elf_ident): Split out the function-level
	static variable "comment_section" into...
	(obj_elf_ident_comment_section): ...this file-level static
	variable.
	(config_obj_elf_c_finalize): New function.
	* config/tc-i386.c (config_tc_i386_c_finalize): New function.
	* depend.c (depend_c_finalize): New function.
	* dw2gencfi.c (dw2gencfi_c_finalize): New function.
	* dw2gencfi.h (dw2gencfi_c_finalize): New prototype.
	* libgas.h: New file.
	* macro.c (macro_c_finalize): New function.
	* macro.h (macro_c_finalize): New prototype.
	* output-file.c (output_file_c_finalize): New function.
	* output-file.h (output_file_c_finalize): New prototype.
	* read.c (read_c_finalize): New function.
	* read.h (read_c_finalize): New prototype.
	* subsegs.c (subsegs_c_finalize): New function.
	* subsegs.h (subsegs_c_finalize): New prototype.
	* symbols.c (symbols_c_finalize): New function.
	* symbols.h (symbols_c_finalize): New prototype.
	* write.c (write_c_finalize): New function.
	* write.h (write_c_finalize): New prototype.
---
 gas/app.c            |  27 ++++++++
 gas/as.c             | 182 ++++++++++++++++++++++++++++++++++++++++++++++++---
 gas/as.h             |  12 ++++
 gas/asmain.c         |  35 ++++++++++
 gas/config/obj-elf.c |  25 +++++--
 gas/config/tc-i386.c |  79 ++++++++++++++++++++++
 gas/depend.c         |  10 +++
 gas/dw2gencfi.c      |  12 ++++
 gas/dw2gencfi.h      |   2 +
 gas/libgas.h         |  41 ++++++++++++
 gas/macro.c          |  18 +++++
 gas/macro.h          |   2 +
 gas/output-file.c    |   8 +++
 gas/output-file.h    |   1 +
 gas/read.c           |  47 +++++++++++++
 gas/read.h           |   2 +
 gas/subsegs.c        |  10 +++
 gas/subsegs.h        |   1 +
 gas/symbols.c        |  41 ++++++++++++
 gas/symbols.h        |   2 +
 gas/write.c          |  15 +++++
 gas/write.h          |   1 +
 22 files changed, 558 insertions(+), 15 deletions(-)
 create mode 100644 gas/asmain.c
 create mode 100644 gas/libgas.h

diff --git a/gas/app.c b/gas/app.c
index 67402e2..fda8216 100644
--- a/gas/app.c
+++ b/gas/app.c
@@ -1479,3 +1479,30 @@ do_scrub_chars (size_t (*get) (char *, size_t), char *tostart, size_t tolen)
 
   return to - tostart;
 }
+
+/* Reset all global state within app.c.  */
+
+void
+app_c_finalize (void)
+{
+#ifdef H_TICK_HEX
+  enable_h_tick_hex = 0;
+#endif
+#ifdef TC_M68K
+  scrub_m68k_mri = 0;
+#endif
+#if defined TC_ARM && defined OBJ_ELF
+  symver_state = NULL;
+#endif
+  CLEAR_VAR (lex);
+  state = 0;
+  old_state = 0;
+  out_string = NULL;
+  CLEAR_VAR (out_buf);
+  add_newlines = 0;
+  saved_input = NULL;
+  saved_input_len = 0;
+  CLEAR_VAR (input_buffer);
+  mri_state = NULL;
+  mri_last_ch = 0;
+}
diff --git a/gas/as.c b/gas/as.c
index 2a8923f..90dc298 100644
--- a/gas/as.c
+++ b/gas/as.c
@@ -31,6 +31,8 @@
 
 #define COMMON
 
+#include "libgas.h"
+
 #include "as.h"
 #include "subsegs.h"
 #include "output-file.h"
@@ -66,6 +68,8 @@ struct defsym_list
   valueT value;
 };
 
+/* Global timer.  */
+struct ctimer *gas_timer;
 
 /* True if a listing is wanted.  */
 int listing;
@@ -135,7 +139,7 @@ extern struct emulation mipsbelf, mipslelf, mipself;
 extern struct emulation i386coff, i386elf, i386aout;
 extern struct emulation crisaout, criself;
 
-static struct emulation *const emulations[] = { EMULATIONS };
+static const struct emulation *const emulations[] = { EMULATIONS };
 static const int n_emulations = sizeof (emulations) / sizeof (emulations[0]);
 
 static void
@@ -546,6 +550,9 @@ parse_args (int * pargc, char *** pargv)
   new_argc = 1;
   new_argv[new_argc] = NULL;
 
+  /* Reset internal state of getopt_long_only.  */
+  optind = 0;
+
   while (1)
     {
       /* getopt_long_only is like getopt_long, but '-' as well as '--' can
@@ -1122,13 +1129,18 @@ perform_an_assembly_pass (int argc, char ** argv)
 }
 
 
-int
-main (int argc, char ** argv)
+/* Run the assembler: almost the top-level of the assembler implementation.
+   Called by gas_main after it has set up gas_timer.  */
+
+static int
+gas_internal_main (int argc, char ** argv, int standalone)
 {
   char ** argv_orig = argv;
 
   int macro_strip_at;
 
+  GAS_TIMER_PUSH ("before pass");
+
   start_time = get_run_time ();
 #ifdef HAVE_SBRK
   start_sbrk = (char *) sbrk (0);
@@ -1183,9 +1195,10 @@ main (int argc, char ** argv)
   expr_begin ();
 
   /* It has to be called after dump_statistics ().  */
-  xatexit (close_output_file);
+  if (standalone)
+    xatexit (close_output_file);
 
-  if (flag_print_statistics)
+  if (flag_print_statistics && standalone)
     xatexit (dump_statistics);
 
   macro_strip_at = 0;
@@ -1236,8 +1249,14 @@ main (int argc, char ** argv)
 
   PROGRESS (1);
 
+  GAS_TIMER_POP ();
+
   /* Assemble it.  */
+  GAS_TIMER_PUSH ("perform_an_assembly_pass");
   perform_an_assembly_pass (argc, argv);
+  GAS_TIMER_POP ();
+
+  GAS_TIMER_PUSH ("after pass");
 
   cond_finish_check (-1);
 
@@ -1316,13 +1335,158 @@ main (int argc, char ** argv)
 
   END_PROGRESS (myname);
 
-  /* Use xexit instead of return, because under VMS environments they
-     may not place the same interpretation on the value given.  */
+  if (!standalone)
+    close_output_file ();
+
+  GAS_TIMER_POP ();
+
   if (had_errors () != 0)
-    xexit (EXIT_FAILURE);
+    return EXIT_FAILURE;
 
   /* Only generate dependency file if assembler was successful.  */
   print_dependencies ();
 
-  xexit (EXIT_SUCCESS);
+  return EXIT_SUCCESS;
+}
+
+static void as_c_finalize (void);
+
+/* FIXME. */
+extern void config_obj_elf_c_finalize (void);
+extern void config_tc_i386_c_finalize (void);
+
+/* Public API entrypoint. */
+
+int
+gas_main (int argc, char **argv, int standalone, struct ctimer *timer)
+{
+  int result;
+
+  /* Set global gas_timer.  */
+  gas_timer = timer;
+
+  GAS_TIMER_PUSH ("gas_main");
+
+  result = gas_internal_main (argc, argv, standalone);
+  if (!standalone)
+    {
+      GAS_TIMER_PUSH ("cleanup");
+
+      if (flag_print_statistics)
+        dump_statistics ();
+
+      /* Restore all state.  */
+      bfd_uninit ();
+
+      /* Restore all state within gas.  */
+      app_c_finalize ();
+      as_c_finalize ();
+      depend_c_finalize ();
+      dw2gencfi_c_finalize ();
+      macro_c_finalize ();
+      read_c_finalize ();
+      output_file_c_finalize ();
+      subsegs_c_finalize ();
+      symbols_c_finalize ();
+      write_c_finalize ();
+      /* FIXME: */
+      config_obj_elf_c_finalize ();
+      config_tc_i386_c_finalize ();
+
+      GAS_TIMER_POP ();
+    }
+
+  GAS_TIMER_POP ();
+
+  gas_timer = NULL;
+
+  return result;
+}
+
+/* Reset all global state within as.c.  */
+
+static void
+as_c_finalize (void)
+{
+  listing = 0;
+  debug_type = DEBUG_UNSPECIFIED;
+  use_gnu_debug_info_extensions = 0;
+  max_macro_nest = 100;
+  myname = NULL;
+  chunksize = 0;
+  debug_memory = 0;
+  verbose = 0;
+  keep_it = 0;
+  reg_section = NULL;
+  expr_section = NULL;
+  text_section = NULL;
+  data_section = NULL;
+  bss_section = NULL;
+  listing_filename = NULL;
+  defsyms = NULL;
+#ifdef HAVE_ITBL_CPU
+  itbl_files = NULL;
+#endif
+  start_time = 0;
+#ifdef HAVE_SBRK
+  start_sbrk = NULL;
+#endif
+  flag_macro_alternate = 0;
+
+  /* The header files use the prefix COMMON for various declarations,
+     which for most translation units is "extern".
+     Within as.c, COMMON is empty, and so this file contains
+     their definitions.
+     Reset their state here.  */
+
+  /* "COMMON" vars within as.h.  */
+  now_subseg = 0;
+  now_seg = NULL;
+  flag_no_comments = 0;
+  flag_debug = 0;
+  flag_signed_overflow_ok = 0;
+#ifndef WORKING_DOT_WORD
+  flag_warn_displacement = 0;
+#endif
+  flag_keep_locals = 0;
+  flag_mri = 0;
+  flag_readonly_data_in_text = 0;
+  flag_no_warnings = 0;
+  flag_fatal_warnings = 0;
+  flag_always_generate_output = 0;
+  flag_print_statistics = 0;
+  flag_strip_local_absolute = 0;
+  flag_traditional_format = 0;
+  flag_compress_debug = 0;
+  flag_execstack = 0;
+  flag_noexecstack = 0;
+  out_file_name = NULL;
+  insttbl_file_name = NULL;
+  need_pass_2 = 0;
+  linkrelax = 0;
+  flag_dwarf_sections = 0;
+#ifdef TC_M68K
+  flag_m68k_mri = 0;
+#endif
+#ifdef WARN_COMMENTS
+  warn_comment = 0;
+  found_comment = 0;
+  found_comment_file = NULL;
+#endif
+#if defined OBJ_ELF || defined OBJ_MAYBE_ELF
+  flag_size_check = 0;
+#endif
+
+  /* "COMMON" var within emul.h.  */
+#ifdef USE_EMULATIONS
+  this_emulation = NULL;
+#endif
+
+  /* "COMMON" vars within frags.h.  */
+  frag_now = NULL;
+  CLEAR_VAR (zero_address_frag);
+  CLEAR_VAR (predefined_address_frag);
+
+  /* "COMMON" var within obj.h.  */
+  this_format = NULL;
 }
diff --git a/gas/as.h b/gas/as.h
index 6de319e..8e241a9 100644
--- a/gas/as.h
+++ b/gas/as.h
@@ -517,6 +517,9 @@ void   register_dependency (char *);
 void   print_dependencies (void);
 segT   subseg_get (const char *, int);
 
+extern void app_c_finalize (void);
+extern void depend_c_finalize (void);
+
 const char *remap_debug_filename (const char *);
 void add_debug_prefix_map (const char *);
 
@@ -631,4 +634,13 @@ flag_size_check;
  #error "Octets per byte conflicts with its power-of-two definition!"
 #endif
 
+extern struct ctimer *gas_timer;
+
+#define GAS_TIMER_PUSH(ITEM_NAME) \
+  do { CTIMER_PUSH (gas_timer, (ITEM_NAME)); } while (0)
+
+#define GAS_TIMER_POP() \
+  do { CTIMER_POP (gas_timer); } while (0)
+
+
 #endif /* GAS */
diff --git a/gas/asmain.c b/gas/asmain.c
new file mode 100644
index 0000000..687ae73
--- /dev/null
+++ b/gas/asmain.c
@@ -0,0 +1,35 @@
+/* asmain.c - "main" for standalone "as" program.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+
+   This file is part of GAS, the GNU Assembler.
+
+   GAS is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GAS is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GAS; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+#include "as.h"
+#include "libgas.h"
+
+int
+main (int argc, char ** argv)
+{
+  int result = gas_main (argc,
+                         argv,
+                         1, /* standalone */
+                         NULL); /* timer */
+
+  /* Use xexit instead of return, because under VMS environments they
+     may not place the same interpretation on the value given.  */
+  xexit (result);
+}
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index 4d7a8a7..cb44a10 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -1947,10 +1947,11 @@ obj_elf_type (int ignore ATTRIBUTE_UNUSED)
   demand_empty_rest_of_line ();
 }
 
+static segT obj_elf_ident_comment_section;
+
 static void
 obj_elf_ident (int ignore ATTRIBUTE_UNUSED)
 {
-  static segT comment_section;
   segT old_section = now_seg;
   int old_subsection = now_subseg;
 
@@ -1958,14 +1959,14 @@ obj_elf_ident (int ignore ATTRIBUTE_UNUSED)
   md_flush_pending_output ();
 #endif
 
-  if (!comment_section)
+  if (!obj_elf_ident_comment_section)
     {
       char *p;
-      comment_section = subseg_new (".comment", 0);
-      bfd_set_section_flags (stdoutput, comment_section,
+      obj_elf_ident_comment_section = subseg_new (".comment", 0);
+      bfd_set_section_flags (stdoutput, obj_elf_ident_comment_section,
 			     SEC_READONLY | SEC_HAS_CONTENTS
 			     | SEC_MERGE | SEC_STRINGS);
-      comment_section->entsize = 1;
+      obj_elf_ident_comment_section->entsize = 1;
 #ifdef md_elf_section_change_hook
       md_elf_section_change_hook ();
 #endif
@@ -1973,7 +1974,7 @@ obj_elf_ident (int ignore ATTRIBUTE_UNUSED)
       *p = 0;
     }
   else
-    subseg_set (comment_section, 0);
+    subseg_set (obj_elf_ident_comment_section, 0);
   stringer (8 + 1);
   subseg_set (old_section, old_subsection);
 }
@@ -2681,3 +2682,15 @@ const struct format_ops elf_format_ops =
   0,
   elf_adjust_symtab
 };
+
+/* FIXME.  */
+extern void config_obj_elf_c_finalize (void);
+
+/* Reset all global state within this source file.  */
+
+void
+config_obj_elf_c_finalize (void)
+{
+  obj_elf_ident_comment_section = NULL;
+  /* TODO: anything else? */
+}
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index db263ee..cbc6e13 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -10655,3 +10655,82 @@ handle_large_common (int small ATTRIBUTE_UNUSED)
     }
 }
 #endif /* OBJ_ELF || OBJ_MAYBE_ELF */
+
+/* FIXME.  */
+extern void config_tc_i386_c_finalize (void);
+
+/* Reset all global state within this source file.  */
+
+void
+config_tc_i386_c_finalize (void)
+{
+#ifdef TE_LINUX
+  flag_compress_debug = COMPRESS_DEBUG_ZLIB;
+#endif
+  default_arch = DEFAULT_ARCH;
+  CLEAR_VAR (rc_op);
+  CLEAR_VAR (mask_op);
+  CLEAR_VAR (broadcast_op);
+  CLEAR_VAR (i);
+  current_templates = NULL;
+  CLEAR_VAR (disp_expressions);
+  CLEAR_VAR (im_expressions);
+  this_operand = -1;
+  flag_code = 0;
+  object_64bit = 0;
+  disallow_64bit_reloc = 0;
+  use_rela_relocations = 0;
+#if ((defined (OBJ_MAYBE_COFF) && defined (OBJ_MAYBE_AOUT)) \
+     || defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \
+     || defined (TE_PE) || defined (TE_PEP) || defined (OBJ_MACH_O))
+  x86_elf_abi = I386_ABI;
+#endif
+#if defined (TE_PE) || defined (TE_PEP)
+  use_big_obj = 0;
+#endif
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+  no_shared = 0;
+#endif
+  intel_syntax = 0;
+  intel_mnemonic = !SYSV386_COMPAT;
+  old_gcc = OLDGCC_COMPAT;
+  allow_pseudo_reg = 0;
+  allow_naked_reg = 0;
+  add_bnd_prefix = 0;
+  allow_index_reg = 0;
+  omit_lock_prefix = 0;
+  operand_check = check_warning;
+  register_prefix = "%";
+  stackop_size = '\0';
+  optimize_align_code = 1;
+  quiet_warnings = 0;
+  cpu_arch_name = NULL;
+  cpu_sub_arch_name = NULL;
+  //cpu_arch_flags = CPU_UNKNOWN_FLAGS;
+  cpu_arch_tune_set = 0;
+  cpu_arch_tune = PROCESSOR_UNKNOWN;
+  CLEAR_VAR (cpu_arch_tune_flags);
+  cpu_arch_isa = PROCESSOR_UNKNOWN;
+  CLEAR_VAR (cpu_arch_isa_flags);
+  no_cond_jump_promotion = 0;
+  sse2avx = 0;
+  avxscalar = 0;
+  evexlig = 0;
+  evexwig = 0;
+  evexrcig = rne;
+  GOT_symbol = NULL;
+  x86_dwarf2_return_column = 0;
+  x86_cie_data_alignment = 0;
+  input_line_pointer = NULL;
+  if (op_hash)
+    {
+      hash_die (op_hash);
+      op_hash = NULL;
+    }
+  if (reg_hash)
+    {
+      hash_die (reg_hash);
+      reg_hash= NULL;
+    }
+  cons_sign = -1;
+}
diff --git a/gas/depend.c b/gas/depend.c
index 1a1ec63..cc8a3e0 100644
--- a/gas/depend.c
+++ b/gas/depend.c
@@ -205,3 +205,13 @@ print_dependencies (void)
   if (fclose (f))
     as_warn (_("can't close `%s'"), dep_file);
 }
+
+/* Reset all global state within depend.c.  */
+
+void
+depend_c_finalize (void)
+{
+  dep_file = NULL;
+  dep_chain = NULL;
+  column = 0;
+}
diff --git a/gas/dw2gencfi.c b/gas/dw2gencfi.c
index ef97e18..1527624 100644
--- a/gas/dw2gencfi.c
+++ b/gas/dw2gencfi.c
@@ -2084,3 +2084,15 @@ cfi_finish (void)
 {
 }
 #endif /* TARGET_USE_CFIPOP */
+
+/* Reset all global state within dw2gencfi.c.  */
+
+void
+dw2gencfi_c_finalize (void)
+{
+  dwcfi_hash = NULL;
+  all_fde_data = NULL;
+  last_fde_data = &all_fde_data;
+  cie_root = NULL;
+  cfi_sections = CFI_EMIT_eh_frame;
+}
diff --git a/gas/dw2gencfi.h b/gas/dw2gencfi.h
index 6e2c50e..009eee3 100644
--- a/gas/dw2gencfi.h
+++ b/gas/dw2gencfi.h
@@ -133,4 +133,6 @@ extern struct fde_entry *all_fde_data;
 #define CFI_val_encoded_addr	0x105
 #define CFI_label		0x106
 
+extern void dw2gencfi_c_finalize (void);
+
 #endif /* DW2GENCFI_H */
diff --git a/gas/libgas.h b/gas/libgas.h
new file mode 100644
index 0000000..479a990
--- /dev/null
+++ b/gas/libgas.h
@@ -0,0 +1,41 @@
+/* API for the GNU Assembler.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+
+   This file is part of the GNU Binutils.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#ifndef LIBGAS_H
+#define LIBGAS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ctimer;
+
+extern int
+gas_main (int argc,
+          char **argv,
+          int standalone,
+          struct ctimer *timer);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* ! defined (LIBGAS_H) */
diff --git a/gas/macro.c b/gas/macro.c
index 119b1bf..76e8fdf 100644
--- a/gas/macro.c
+++ b/gas/macro.c
@@ -1401,3 +1401,21 @@ expand_irp (int irpc, size_t idx, sb *in, sb *out, size_t (*get_line) (sb *))
 
   return err;
 }
+
+/* Reset all global state within macro.c.  */
+
+void
+macro_c_finalize (void)
+{
+  if (macro_hash)
+    {
+      hash_die (macro_hash);
+      macro_hash = NULL;
+    }
+  macro_defined = 0;
+  macro_alternate = 0;
+  macro_mri = 0;
+  macro_strip_at = 0;
+  macro_expr = 0;
+  macro_number = 0;
+}
diff --git a/gas/macro.h b/gas/macro.h
index 46b1575..a0c48c3 100644
--- a/gas/macro.h
+++ b/gas/macro.h
@@ -93,4 +93,6 @@ extern int check_macro (const char *, sb *, const char **, macro_entry **);
 extern void delete_macro (const char *);
 extern const char *expand_irp (int, size_t, sb *, sb *, size_t (*) (sb *));
 
+extern void macro_c_finalize (void);
+
 #endif
diff --git a/gas/output-file.c b/gas/output-file.c
index 94dbc2e..769bd43 100644
--- a/gas/output-file.c
+++ b/gas/output-file.c
@@ -71,3 +71,11 @@ output_file_close (char *filename)
     as_fatal (_("can't close %s: %s"), filename,
 	      bfd_errmsg (bfd_get_error ()));
 }
+
+/* Reset all global state within output-file.c.  */
+
+void
+output_file_c_finalize (void)
+{
+  stdoutput = NULL;
+}
diff --git a/gas/output-file.h b/gas/output-file.h
index bfba284..3e8d848 100644
--- a/gas/output-file.h
+++ b/gas/output-file.h
@@ -21,5 +21,6 @@
 void output_file_append (char *where, long length, char *filename);
 void output_file_close (char *filename);
 void output_file_create (char *name);
+void output_file_c_finalize (void);
 
 /* end of output-file.h */
diff --git a/gas/read.c b/gas/read.c
index 2224c0e..d49b122 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -6170,3 +6170,50 @@ find_end_of_line (char *s, int mri_string)
 {
   return _find_end_of_line (s, mri_string, 0, 0);
 }
+
+/* Reset all global state within read.c.  */
+
+void
+read_c_finalize (void)
+{
+  input_line_pointer = NULL;
+  /* FIXME: char lex_type[256] = { */
+  /* FIXME:char is_end_of_line[256] = { */
+#ifndef TC_CASE_SENSITIVE
+  CLEAR_VAR (original_case_string);
+#endif
+  buffer = NULL;
+  buffer_limit = NULL;
+  target_big_endian = TARGET_BYTES_BIG_ENDIAN;
+  include_dirs = NULL;
+  include_dir_count = 0;
+  include_dir_maxlen = 1;
+#ifndef WORKING_DOT_WORD
+  broken_words = NULL;
+  new_broken_words = 0;
+#endif
+  abs_section_offset = 0;
+  line_label = NULL;
+  mri_common_symbol = NULL;
+  mri_pending_align = 0;
+#ifndef NO_LISTING
+#ifdef OBJ_ELF
+  dwarf_file_string = 0;
+#endif
+#endif
+#ifdef HANDLE_BUNDLE
+  bundle_align_p2 = 0;
+  bundle_lock_frag = NULL;
+  bundle_lock_frchain = NULL;
+  bundle_lock_depth = 0;
+#endif
+  if (po_hash)
+    {
+      hash_die (po_hash);
+      po_hash = NULL;
+    }
+  pop_override_ok = 0;
+  pop_table_name = NULL;
+  scrub_string = NULL;
+  scrub_string_end = NULL;
+}
diff --git a/gas/read.h b/gas/read.h
index d7ac6ce..7d17a7a 100644
--- a/gas/read.h
+++ b/gas/read.h
@@ -198,3 +198,5 @@ extern void s_xstab (int what);
 extern void s_rva (int);
 extern void s_incbin (int);
 extern void s_weakref (int);
+
+extern void read_c_finalize (void);
diff --git a/gas/subsegs.c b/gas/subsegs.c
index 4e422de..331ec29 100644
--- a/gas/subsegs.c
+++ b/gas/subsegs.c
@@ -325,4 +325,14 @@ subsegs_print_statistics (FILE *file)
     }
 }
 
+/* Reset all global state within subsegs.c.  */
+
+void
+subsegs_c_finalize (void)
+{
+  frchain_now = NULL;
+  obstack_free (&frchains, 0);
+  CLEAR_VAR (dummy_frag);
+}
+
 /* end of subsegs.c */
diff --git a/gas/subsegs.h b/gas/subsegs.h
index 82837a3..78e5b2f 100644
--- a/gas/subsegs.h
+++ b/gas/subsegs.h
@@ -117,3 +117,4 @@ typedef struct segment_info_struct {
 extern symbolS *section_symbol (segT);
 
 extern void subsegs_print_statistics (FILE *);
+extern void subsegs_c_finalize (void);
diff --git a/gas/symbols.c b/gas/symbols.c
index 07362bb..d660d53 100644
--- a/gas/symbols.c
+++ b/gas/symbols.c
@@ -3248,3 +3248,44 @@ symbol_relc_make_expr (expressionS * exp)
 }
 
 #endif
+
+/* Reset all global state within symbols.c.  */
+
+void
+symbols_c_finalize (void)
+{
+  symbols_case_sensitive = 1;
+  if (sy_hash)
+    {
+      hash_die (sy_hash);
+      sy_hash = NULL;
+    }
+  if (local_hash)
+    {
+      hash_die (local_hash);
+      local_hash = NULL;
+    }
+  symbol_rootP = NULL;
+  symbol_lastP = NULL;
+  CLEAR_VAR (abs_symbol);
+  CLEAR_VAR (dot_symbol);
+  obstack_free (&notes, 0);
+  CLEAR_VAR (notes);
+#ifdef TE_PE
+  an_external_name = NULL;
+#endif
+  local_symbol_count = 0;
+  local_symbol_conversion_count = 0;
+  dollar_labels = NULL;
+  dollar_label_instances = NULL;
+  dollar_label_defines = NULL;
+  dollar_label_count = 0;
+  dollar_label_max = 0;
+  CLEAR_VAR (fb_low_counter);
+  fb_labels = NULL;
+  fb_label_instances = NULL;
+  fb_label_count = 0;
+  fb_label_max = 0;
+  indent_level = 0;
+  max_indent_level = 8;
+}
diff --git a/gas/symbols.h b/gas/symbols.h
index cf4f30f..8a88383 100644
--- a/gas/symbols.h
+++ b/gas/symbols.h
@@ -213,3 +213,5 @@ void symbol_set_obj (symbolS *, OBJ_SYMFIELD_TYPE *);
 TC_SYMFIELD_TYPE *symbol_get_tc (symbolS *);
 void symbol_set_tc (symbolS *, TC_SYMFIELD_TYPE *);
 #endif
+
+extern void symbols_c_finalize (void);
diff --git a/gas/write.c b/gas/write.c
index bc76962..9562a7b 100644
--- a/gas/write.c
+++ b/gas/write.c
@@ -2907,3 +2907,18 @@ print_fixup (fixS *fixp)
   TC_FIX_DATA_PRINT (stderr, fixp);
 #endif
 }
+
+/* Reset all global state within write.c.  */
+
+void
+write_c_finalize (void)
+{
+  finalize_syms = 0;
+  symbol_table_frozen = 0;
+  abs_section_sym = NULL;
+  dot_value = 0;
+  dot_frag = NULL;
+  reloc_list = NULL;
+  frags_chained = 0;
+  n_fixups = 0;
+}
diff --git a/gas/write.h b/gas/write.h
index e0b5b36..63026f9 100644
--- a/gas/write.h
+++ b/gas/write.h
@@ -184,5 +184,6 @@ extern fixS *fix_new_exp
   (fragS * frag, int where, int size, expressionS *exp, int pcrel,
    bfd_reloc_code_real_type r_type);
 extern void write_print_statistics (FILE *);
+extern void write_c_finalize (void);
 
 #endif /* __write_h__ */
-- 
1.8.5.3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]