diff --git a/gcc/config/darwin-protos.h b/gcc/config/darwin-protos.h
index 747745fa577478545d1d4a463029f7677f6d494c..9df358ee7d3b77087e1bd74efb792388c05efccf 100644
--- a/gcc/config/darwin-protos.h
+++ b/gcc/config/darwin-protos.h
@@ -129,4 +129,15 @@ extern void darwin_patch_builtins (void);
 extern void darwin_rename_builtins (void);
 extern bool darwin_libc_has_function (enum function_class fn_class, tree);
 
+/* For this port, there are several possible sources for external toolchain
+   components (e.g. as, ld, dsymutil) and we have to alter the allowable
+   output in response to which version and source is in use.  */
+enum darwin_external_toolchain {
+  DET_UNKNOWN=0,
+  CCTOOLS,
+  DWARFUTILS,
+  LLVM,
+  CLANG
+};
+
 #endif /* CONFIG_DARWIN_PROTOS_H */
diff --git a/gcc/config/darwin.cc b/gcc/config/darwin.cc
index 154a2b2755a84d1fb8c34c36c634c35dd67ab6e2..d8c8607892b5e10e9e0cbbd5e5ed1b27891bdda8 100644
--- a/gcc/config/darwin.cc
+++ b/gcc/config/darwin.cc
@@ -114,6 +114,19 @@ static bool ld_needs_eh_markers = false;
 /* Emit a section-start symbol for mod init and term sections.  */
 static bool ld_init_term_start_labels = false;
 
+/* The source and version of dsymutil in use.  */
+#ifndef DSYMUTIL_VERSION
+# warning Darwin toolchain without a defined dsymutil.
+# define DSYMUTIL_VERSION DET_UNKNOWN,0,0,0
+#endif
+
+struct {
+  darwin_external_toolchain kind; /* cctools, llvm, clang etc.  */
+  int major; /* version number.  */
+  int minor;
+  int tiny;
+} dsymutil_version = {DSYMUTIL_VERSION};
+
 /* Section names.  */
 section * darwin_sections[NUM_DARWIN_SECTIONS];
 
@@ -3357,14 +3370,26 @@ darwin_override_options (void)
 		  global_options.x_flag_objc_abi);
     }
 
-  /* Don't emit DWARF3/4 unless specifically selected.  This is a
-     workaround for tool bugs.  */
+  /* Limit DWARF to the chosen version, the linker and debug linker might not
+     be able to consume newer structures.  */
   if (!OPTION_SET_P (dwarf_strict))
     dwarf_strict = 1;
+
   if (!OPTION_SET_P (dwarf_version))
-    dwarf_version = 2;
+    {
+      /* External toolchains based on LLVM or clang 7+ have support for
+	 dwarf-4.  */
+      if ((dsymutil_version.kind == LLVM && dsymutil_version.major >= 7)
+	  || (dsymutil_version.kind == CLANG && dsymutil_version.major >= 7))
+	dwarf_version = 4;
+      else if (dsymutil_version.kind == DWARFUTILS
+	       && dsymutil_version.major >= 121)
+	dwarf_version = 3;  /* From XC 6.4.  */
+      else
+	dwarf_version = 2;  /* Older cannot safely exceed dwarf-2.  */
+    }
 
-  if (OPTION_SET_P (dwarf_split_debug_info))
+  if (OPTION_SET_P (dwarf_split_debug_info) && dwarf_split_debug_info)
     {
       inform (input_location,
 	      "%<-gsplit-dwarf%> is not supported on this platform, ignored");