diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c
index 7703e2e..3fea6a3 100644
--- a/gcc/ada/gcc-interface/misc.c
+++ b/gcc/ada/gcc-interface/misc.c
@@ -687,11 +687,7 @@ static tree
 gnat_eh_personality (void)
 {
   if (!gnat_eh_personality_decl)
-    gnat_eh_personality_decl
-      = build_personality_function (targetm.except_unwind_info () == UI_SJLJ
-				    ? "__gnat_eh_personality_sj"
-				    : "__gnat_eh_personality");
-
+    gnat_eh_personality_decl = build_personality_function (DW_LANG_Ada95);
   return gnat_eh_personality_decl;
 }
 
diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c
index 0b70444..1126283 100644
--- a/gcc/cp/cp-lang.c
+++ b/gcc/cp/cp-lang.c
@@ -166,17 +166,10 @@ cp_eh_personality (void)
 {
   if (!cp_eh_personality_decl)
     {
-      const char *name;
+      enum dwarf_source_language lang;
 
-      name = (targetm.except_unwind_info () == UI_SJLJ
-	      ? (pragma_java_exceptions
-		 ? "__gcj_personality_sj0"
-		 : "__gxx_personality_sj0")
-	      : (pragma_java_exceptions
-		 ? "__gcj_personality_v0"
-		 : "__gxx_personality_v0"));
-
-      cp_eh_personality_decl = build_personality_function (name);
+      lang = (pragma_java_exceptions ? DW_LANG_Java : DW_LANG_C_plus_plus);
+      cp_eh_personality_decl = build_personality_function (lang);
     }
 
   return cp_eh_personality_decl;
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index 9d19aa9..b917664 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -295,9 +295,8 @@ decl_is_java_type (tree decl, int err)
 /* Select the personality routine to be used for exception handling,
    or issue an error if we need two different ones in the same
    translation unit.
-   ??? At present eh_personality_decl is set to
-   __gxx_personality_(sj|v)0 in init_exception_processing - should it
-   be done here instead?  */
+   ??? At present DECL_FUNCTION_PERSONALITY is set via
+   LANG_HOOKS_EH_PERSONALITY.  Should it be done here instead?  */
 void
 choose_personality_routine (enum languages lang)
 {
diff --git a/gcc/expr.c b/gcc/expr.c
index b0c160f..3093967 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -10255,13 +10255,63 @@ const_vector_from_tree (tree exp)
   return gen_rtx_CONST_VECTOR (mode, v);
 }
 
-
-/* Build a decl for a EH personality function named NAME. */
+/* Build a personality function given a language.  LANG is really an
+   enum dwarf_source_language.  */
 
 tree
-build_personality_function (const char *name)
+build_personality_function (enum dwarf_source_language lang)
 {
+  enum unwind_info_type ui = targetm.except_unwind_info ();
+  const char *prefix, *unwind, *version = "0";
   tree decl, type;
+  char *name;
+
+  switch (ui)
+    {
+    case UI_NONE:
+      return NULL;
+    case UI_SJLJ:
+      unwind = "_sj";
+      break;
+    case UI_DWARF2:
+    case UI_TARGET:
+      unwind = "_v";
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+  switch (lang)
+    {
+    case DW_LANG_Ada83:
+    case DW_LANG_Ada95:
+      prefix = "__gnat_eh_personality";
+      /* The GNAT folk did not follow the standard naming format.
+	 That can change if we ever have to increment the version.  */
+      if (ui == UI_DWARF2 || ui == UI_TARGET)
+	unwind = "";
+      version = "";
+      break;
+
+    case DW_LANG_C_plus_plus:
+      prefix = "__gxx_personality";
+      break;
+
+    case DW_LANG_Java:
+      prefix = "__gcj_personality";
+      break;
+
+    case DW_LANG_ObjC:
+      prefix = "__gnu_objc_personality";
+      break;
+
+    default:
+      /* All other languages use the minimal C personality.  */
+      prefix = "__gcc_personality";
+      break;
+    }
+
+  name = concat (prefix, unwind, version, NULL);
 
   type = build_function_type_list (integer_type_node, integer_type_node,
 				   long_long_unsigned_type_node,
@@ -10276,6 +10326,7 @@ build_personality_function (const char *name)
      are the flags assigned by targetm.encode_section_info.  */
   SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL);
 
+  free (name);
   return decl;
 }
 
diff --git a/gcc/java/lang.c b/gcc/java/lang.c
index fbe25ad..7b29ea3 100644
--- a/gcc/java/lang.c
+++ b/gcc/java/lang.c
@@ -911,11 +911,7 @@ static tree
 java_eh_personality (void)
 {
   if (!java_eh_personality_decl)
-    java_eh_personality_decl
-      = build_personality_function (targetm.except_unwind_info () == UI_SJLJ
-				    ? "__gcj_personality_sj0"
-				    : "__gcj_personality_v0");
-
+    java_eh_personality_decl = build_personality_function (DW_LANG_Java);
   return java_eh_personality_decl;
 }
 
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index 3a13519..6e2a0fa 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -3693,13 +3693,8 @@ objc_eh_runtime_type (tree type)
 tree
 objc_eh_personality (void)
 {
-  if (!flag_objc_sjlj_exceptions
-      && !objc_eh_personality_decl)
-    objc_eh_personality_decl
-      = build_personality_function (targetm.except_unwind_info () == UI_SJLJ
-				    ? "__gnu_objc_personality_sj0"
-				    : "__gnu_objc_personality_v0");
-
+  if (!flag_objc_sjlj_exceptions && !objc_eh_personality_decl)
+    objc_eh_personality_decl = build_personality_function (DW_LANG_ObjC);
   return objc_eh_personality_decl;
 }
 #endif
diff --git a/gcc/objcp/objcp-lang.c b/gcc/objcp/objcp-lang.c
index fdb2976..1224c31 100644
--- a/gcc/objcp/objcp-lang.c
+++ b/gcc/objcp/objcp-lang.c
@@ -148,9 +148,7 @@ objcxx_eh_personality (void)
 {
   if (!objcp_eh_personality_decl)
     objcp_eh_personality_decl
-	= build_personality_function (targetm.except_unwind_info () == UI_SJLJ
-				      ? "__gxx_personality_sj0"
-				      : "__gxx_personality_v0");
+      = build_personality_function (DW_LANG_C_plus_plus);
 
   return objcp_eh_personality_decl;
 }
diff --git a/gcc/tree.c b/gcc/tree.c
index cf5881a..e02ad3e 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -10874,11 +10874,7 @@ tree
 lhd_gcc_personality (void)
 {
   if (!gcc_eh_personality_decl)
-    gcc_eh_personality_decl
-      = build_personality_function (targetm.except_unwind_info () == UI_SJLJ
-				    ? "__gcc_personality_sj0"
-				    : "__gcc_personality_v0");
-
+    gcc_eh_personality_decl = build_personality_function (DW_LANG_C);
   return gcc_eh_personality_decl;
 }
 
diff --git a/gcc/tree.h b/gcc/tree.h
index 8aedf1a..ef7f409 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "fixed-value.h"
 #include "alias.h"
 #include "flags.h"
+#include "dwarf2.h"		/* for enum dwarf_source_language */
 
 /* Codes of tree nodes */
 
@@ -5474,7 +5475,7 @@ extern unsigned HOST_WIDE_INT compute_builtin_object_size (tree, int);
 
 /* In expr.c.  */
 extern unsigned HOST_WIDE_INT highest_pow2_factor (const_tree);
-extern tree build_personality_function (const char *);
+extern tree build_personality_function (enum dwarf_source_language);
 
 /* In tree-inline.c.  */
 
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 8118c06..f1b6972 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -886,7 +886,7 @@ TREE_H = tree.h all-tree.def tree.def c-family/c-common.def \
 	$(lang_tree_files) $(MACHMODE_H) tree-check.h $(BUILTINS_DEF) \
 	$(INPUT_H) statistics.h $(VEC_H) treestruct.def $(HASHTAB_H) \
 	double-int.h alias.h $(SYMTAB_H) $(FLAGS_H) vecir.h \
-	$(REAL_H) $(FIXED_VALUE_H)
+	$(REAL_H) $(FIXED_VALUE_H) $(DWARF2_H)
 REGSET_H = regset.h $(BITMAP_H) hard-reg-set.h
 BASIC_BLOCK_H = basic-block.h $(PREDICT_H) $(VEC_H) $(FUNCTION_H) cfghooks.h
 GIMPLE_H = gimple.h gimple.def gsstruct.def pointer-set.h $(VEC_H) \
