Index: gcc/ChangeLog.gomp
===================================================================
--- gcc/ChangeLog.gomp	(revision 209074)
+++ gcc/ChangeLog.gomp	(working copy)
@@ -1,5 +1,15 @@
 2014-04-04  Bernd Schmidt  <bernds@codesourcery.com>
 
+	* lto-section-names.h (OFFLOAD_VAR_TABLE_SECTION_NAME,
+	OFFLOAD_FUNC_TABLE_SECTION_NAME): Define.
+	* lto-wrapper.c (OFFLOAD_FUNC_TABLE_SECTION_NAME): Don't define.
+	(ompend): New static variable.
+	(copy_file, find_ompend): New static functions.
+	(run_gcc): Call find_ompend if we have offload images.  Add its
+	return value to the output.
+	* omp-low.c: Include "lto-section-names.h".
+	(omp_finish_file): Initialize section names from macros defined there.
+	
 	* omp-low.c (offload_symbol_decl): New static variable.
 	(get_offload_symbol_decl): New static function.
 	(expand_oacc_offload, expand_omp_target): Use it.
Index: gcc/lto-section-names.h
===================================================================
--- gcc/lto-section-names.h	(revision 209072)
+++ gcc/lto-section-names.h	(working copy)
@@ -31,3 +31,6 @@ along with GCC; see the file COPYING3.
 /* Can be either OMP_SECTION_NAME_PREFIX when we stream pragma omp target
    stuff, or LTO_SECTION_NAME_PREFIX for lto case.  */
 extern const char  *section_name_prefix;
+
+#define OFFLOAD_VAR_TABLE_SECTION_NAME "__gnu_offload_vars"
+#define OFFLOAD_FUNC_TABLE_SECTION_NAME "__gnu_offload_funcs"
Index: gcc/lto-wrapper.c
===================================================================
--- gcc/lto-wrapper.c	(revision 209072)
+++ gcc/lto-wrapper.c	(working copy)
@@ -49,7 +49,6 @@ along with GCC; see the file COPYING3.
 #include "lto-section-names.h"
 #include "collect-utils.h"
 
-#define OFFLOAD_FUNC_TABLE_SECTION_NAME ".offload_func_table_section"
 #define OFFLOAD_TARGET_NAMES_ENV	"OFFLOAD_TARGET_NAMES"
 
 enum lto_mode_d {
@@ -67,6 +66,7 @@ static unsigned int nr;
 static char **input_names;
 static char **output_names;
 static char **offload_names;
+static const char *ompend;
 static char *makefile;
 
 const char tool_name[] = "lto-wrapper";
@@ -479,6 +479,54 @@ compile_images_for_openmp_targets (unsig
   free_array_of_ptrs ((void**) names, num_targets);
 }
 
+/* Copy a file from SRC to DEST.  */
+static void
+copy_file (const char *dest, const char *src)
+{
+  FILE *d = fopen (dest, "wb");
+  FILE *s = fopen (src, "rb");
+  char buffer[512];
+  while (!feof (s))
+    {
+      size_t len = fread (buffer, 1, 512, s);
+      if (ferror (s) != 0)
+	fatal ("reading input file");
+      if (len > 0)
+	{
+	  fwrite (buffer, 1, len, d);
+	  if (ferror (d) != 0)
+	    fatal ("writing output file");
+	}
+    }
+}
+
+/* Find the crtompend.o file in LIBRARY_PATH, make a copy and store
+   the name of the copy in ompend.  */
+
+static void
+find_ompend (void)
+{
+  char **paths;
+  const char *library_path = getenv ("LIBRARY_PATH");
+  if (library_path == NULL)
+    return;
+  int n_paths = parse_env_var (library_path, &paths, "/crtompend.o");
+
+  for (int i = 0; i < n_paths; i++)
+    if (access_check (paths[i], R_OK) == 0)
+      {
+	/* The linker will delete the filenames we give it, so make
+	   copies.  */
+	const char *omptmp = make_temp_file (".o");
+	copy_file (omptmp, paths[i]);
+	ompend = omptmp;
+	break;
+      }
+  if (ompend == 0)
+    fatal ("installation error, can't find crtompend.o");
+
+  free_array_of_ptrs ((void**) paths, n_paths);
+}
 
 /* Execute gcc. ARGC is the number of arguments. ARGV contains the arguments. */
 
@@ -964,6 +1012,7 @@ cont:
 	  compile_images_for_openmp_targets (argc, argv);
 	  if (offload_names)
 	    {
+	      find_ompend ();
 	      for (i = 0; offload_names[i]; i++)
 		{
 		  fputs (offload_names[i], stdout);
@@ -972,12 +1021,18 @@ cont:
 	      free_array_of_ptrs ((void **)offload_names, i);
 	    }
 	}
+
       for (i = 0; i < nr; ++i)
 	{
 	  fputs (output_names[i], stdout);
 	  putc ('\n', stdout);
 	  free (input_names[i]);
 	}
+      if (ompend)
+	{
+	  fputs (ompend, stdout);
+	  putc ('\n', stdout);
+	}
       nr = 0;
       free (output_names);
       free (input_names);
Index: gcc/omp-low.c
===================================================================
--- gcc/omp-low.c	(revision 209074)
+++ gcc/omp-low.c	(working copy)
@@ -72,7 +72,7 @@ along with GCC; see the file COPYING3.
 #include "ipa-prop.h"
 #include "tree-nested.h"
 #include "tree-eh.h"
-
+#include "lto-section-names.h"
 
 /* Lowering of OpenMP parallel and workshare constructs proceeds in two
    phases.  The first phase scans the function looking for OMP statements
@@ -12851,8 +12851,8 @@ omp_finish_file (void)
 {
   struct cgraph_node *node;
   struct varpool_node *vnode;
-  const char *funcs_section_name = ".offload_func_table_section";
-  const char *vars_section_name = ".offload_var_table_section";
+  const char *funcs_section_name = OFFLOAD_FUNC_TABLE_SECTION_NAME;
+  const char *vars_section_name = OFFLOAD_VAR_TABLE_SECTION_NAME;
   vec<tree, va_gc> *v_funcs, *v_vars;
 
   vec_alloc (v_vars, 0);
Index: libgcc/ChangeLog.gomp
===================================================================
--- libgcc/ChangeLog.gomp	(revision 209074)
+++ libgcc/ChangeLog.gomp	(working copy)
@@ -1,6 +1,16 @@
 2014-04-04  Bernd Schmidt  <bernds@codesourcery.com>
 
-	* crtstuff.c (__OPENMP_TARGET__): Revert previous change.
+	* Makefile.in (crtompend$(objext)): New rule.
+	* configure.ac (--enable-accelerator, --enable-offload-targets):
+	Handle options.
+	(offload_targets): Compute list.
+	(extra_parts): Add crtompend.o if offload_targets is not empty.
+	* configure: Regenerate.
+	* crtstuff.c (_omp_func_table, _omp_var_table, _omp_funcs_end)
+	_omp_vars_end, __OPENMP_TARGET__): Remove.
+	* ompstuff.c: New file.
+
+	(* crtstuff.c (__OPENMP_TARGET__): Revert previous change.
 
 2014-04-02  Thomas Schwinge  <thomas@codesourcery.com>
 
Index: libgcc/Makefile.in
===================================================================
--- libgcc/Makefile.in	(revision 209072)
+++ libgcc/Makefile.in	(working copy)
@@ -975,6 +975,9 @@ crtbegin$(objext): $(srcdir)/crtstuff.c
 crtend$(objext): $(srcdir)/crtstuff.c
 	$(crt_compile) $(CRTSTUFF_T_CFLAGS) -c $< -DCRT_END
 
+crtompend$(objext): $(srcdir)/ompstuff.c
+	$(crt_compile) $(CRTSTUFF_T_CFLAGS) -c $< -DCRT_END
+
 # These are versions of crtbegin and crtend for shared libraries.
 crtbeginS$(objext): $(srcdir)/crtstuff.c
 	$(crt_compile) $(CRTSTUFF_T_CFLAGS_S) -c $< -DCRT_BEGIN -DCRTSTUFFS_O
Index: libgcc/configure
===================================================================
--- libgcc/configure	(revision 209072)
+++ libgcc/configure	(working copy)
@@ -566,6 +566,7 @@ sfp_machine_header
 set_use_emutls
 set_have_cc_tls
 vis_hide
+enable_accelerator
 fixed_point
 enable_decimal_float
 decimal_float
@@ -664,6 +665,8 @@ with_build_libsubdir
 enable_decimal_float
 with_system_libunwind
 enable_sjlj_exceptions
+enable_accelerator
+enable_offload_targets
 enable_tls
 '
       ac_precious_vars='build_alias
@@ -1301,6 +1304,9 @@ Optional Features:
 			to use
   --enable-sjlj-exceptions
                           force use of builtin_setjmp for exceptions
+  --enable-accelerator    build accelerator [ARG={no,device-triplet}]
+  --enable-offload-targets=LIST
+                          enable offloading to devices from LIST
   --enable-tls            Use thread-local storage [default=yes]
 
 Optional Packages:
@@ -4357,6 +4363,43 @@ esac
 # Collect host-machine-specific information.
 . ${srcdir}/config.host
 
+offload_targets=
+# Check whether --enable-accelerator was given.
+if test "${enable_accelerator+set}" = set; then :
+  enableval=$enable_accelerator;
+  case $enable_accelerator in
+  no) ;;
+  *)
+    offload_targets=$enable_accelerator
+    ;;
+  esac
+
+fi
+
+
+
+# Check whether --enable-offload-targets was given.
+if test "${enable_offload_targets+set}" = set; then :
+  enableval=$enable_offload_targets;
+  if test x$enable_offload_targets = x; then
+    as_fn_error "no offload targets specified" "$LINENO" 5
+  else
+    if test x$offload_targets = x; then
+      offload_targets=$enable_offload_targets
+    else
+      offload_targets=$offload_targets,$enable_offload_targets
+    fi
+  fi
+
+else
+  enable_accelerator=no
+fi
+
+
+if test x$offload_targets != x; then
+  extra_parts="${extra_parts} crtompend.o"
+fi
+
 # Check if Solaris/x86 linker supports ZERO terminator unwind entries.
 # This is after config.host so we can augment tmake_file.
 # Link with -nostartfiles -nodefaultlibs since neither are present while
Index: libgcc/configure.ac
===================================================================
--- libgcc/configure.ac	(revision 209072)
+++ libgcc/configure.ac	(working copy)
@@ -307,6 +307,38 @@ esac
 # Collect host-machine-specific information.
 . ${srcdir}/config.host
 
+offload_targets=
+AC_ARG_ENABLE(accelerator,
+[AS_HELP_STRING([--enable-accelerator], [build accelerator @<:@ARG={no,device-triplet}@:>@])],
+[
+  case $enable_accelerator in
+  no) ;;
+  *)
+    offload_targets=$enable_accelerator
+    ;;
+  esac
+], [])
+AC_SUBST(enable_accelerator)
+
+AC_ARG_ENABLE(offload-targets,
+[AS_HELP_STRING([--enable-offload-targets=LIST],
+ [enable offloading to devices from LIST])],
+[
+  if test x$enable_offload_targets = x; then
+    AC_MSG_ERROR([no offload targets specified])
+  else
+    if test x$offload_targets = x; then
+      offload_targets=$enable_offload_targets
+    else
+      offload_targets=$offload_targets,$enable_offload_targets
+    fi
+  fi
+], [enable_accelerator=no])
+AC_SUBST(enable_accelerator)
+if test x$offload_targets != x; then
+  extra_parts="${extra_parts} crtompend.o"
+fi
+
 # Check if Solaris/x86 linker supports ZERO terminator unwind entries.
 # This is after config.host so we can augment tmake_file.
 # Link with -nostartfiles -nodefaultlibs since neither are present while
Index: libgcc/crtstuff.c
===================================================================
--- libgcc/crtstuff.c	(revision 209074)
+++ libgcc/crtstuff.c	(working copy)
@@ -311,15 +311,6 @@ register_tm_clones (void)
 }
 #endif /* USE_TM_CLONE_REGISTRY */
 
-#if defined(HAVE_GAS_HIDDEN) && defined(ENABLE_OFFLOADING)
-void *_omp_func_table[0]
-  __attribute__ ((__used__, visibility ("protected"),
-		  section (".offload_func_table_section"))) = { };
-void *_omp_var_table[0]
-  __attribute__ ((__used__, visibility ("protected"),
-		  section (".offload_var_table_section"))) = { };
-#endif
-
 #if defined(INIT_SECTION_ASM_OP) || defined(INIT_ARRAY_SECTION_ASM_OP)
 
 #ifdef OBJECT_FORMAT_ELF
@@ -761,22 +752,6 @@ __do_global_ctors (void)
 #error "What are you doing with crtstuff.c, then?"
 #endif
 
-#if defined(HAVE_GAS_HIDDEN) && defined(ENABLE_OFFLOADING)
-void *_omp_funcs_end[0]
-  __attribute__ ((__used__, visibility ("protected"),
-		  section (".offload_func_table_section"))) = { };
-void *_omp_vars_end[0]
-  __attribute__ ((__used__, visibility ("protected"),
-		  section (".offload_var_table_section"))) = { };
-extern void *_omp_func_table[];
-extern void *_omp_var_table[];
-void *__OPENMP_TARGET__[] __attribute__ ((__visibility__ ("protected"))) =
-{
-  &_omp_func_table, &_omp_funcs_end,
-  &_omp_var_table, &_omp_vars_end
-};
-#endif
-
 
 #else /* ! CRT_BEGIN && ! CRT_END */
 #error "One of CRT_BEGIN or CRT_END must be defined."
Index: libgcc/ompstuff.c
===================================================================
--- libgcc/ompstuff.c	(revision 0)
+++ libgcc/ompstuff.c	(working copy)
@@ -0,0 +1,52 @@
+/* Specialized bits of code needed for the OpenMP offloading tables.
+   Copyright (C) 2014 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC 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.
+
+GCC 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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/* Target machine header files require this define. */
+#define IN_LIBGCC2
+
+/* FIXME: Including auto-host is incorrect, but until we have
+   identified the set of defines that need to go into auto-target.h,
+   this will have to do.  */
+#include "auto-host.h"
+#undef pid_t
+#undef rlim_t
+#undef ssize_t
+#undef vfork
+#include "tconfig.h"
+#include "tsystem.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "libgcc_tm.h"
+
+#if defined(HAVE_GAS_HIDDEN) && defined(ENABLE_OFFLOADING)
+extern void __start___gnu_offload_funcs;
+extern void __stop___gnu_offload_funcs;
+extern void __start___gnu_offload_vars;
+extern void __stop___gnu_offload_vars;
+void *__OPENMP_TARGET__[] __attribute__ ((__visibility__ ("hidden"))) =
+{
+  &__start___gnu_offload_funcs, &__stop___gnu_offload_funcs,
+  &__start___gnu_offload_vars, &__stop___gnu_offload_vars
+};
+#endif
