[pushed] Darwin, debug : Switch to DWARF 3 or 4 when dsymutil supports it.

Message ID 20230918184144.41108-1-iain@sandoe.co.uk
State Accepted
Headers
Series [pushed] Darwin, debug : Switch to DWARF 3 or 4 when dsymutil supports it. |

Checks

Context Check Description
snail/gcc-patch-check success Github commit url

Commit Message

Iain Sandoe Sept. 18, 2023, 6:41 p.m. UTC
  Tested on i686, x86_64 and aarch64 Darwin, also on x86_64 and aarch64
Linux.  Having said this, some fallout might well be expected on Darwin
since the consumers have not had much use with GCC output where the
DWARF version is > 2, we will have to tackle that as it arises.
pushed to trunk, thanks,

Iain

--- 8< ---

The main reason that Darwin has been using DWARF2 only as debug is that
earlier debug linkers (dsymutil) did not support any extensions to this
so that the default "non-strict" mode used in GCC would cause tool errors.

There are two sources for dsymutil, those based off a closed source base
"dwarfutils" and those based off LLVM.

For dsymutil versions based off LLVM-7+ we can use up to DWARF-4, and for
versions based on dwarfutils 121+ we can use DWARF-3.

Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>

gcc/ChangeLog:

	* config/darwin-protos.h (enum darwin_external_toolchain): New.
	* config/darwin.cc (DSYMUTIL_VERSION): New.
	(darwin_override_options): Choose the default debug DWARF version
	depending on the configured dsymutil version.
---
 gcc/config/darwin-protos.h | 11 +++++++++++
 gcc/config/darwin.cc       | 33 +++++++++++++++++++++++++++++----
 2 files changed, 40 insertions(+), 4 deletions(-)
  

Patch

diff --git a/gcc/config/darwin-protos.h b/gcc/config/darwin-protos.h
index 747745fa577..9df358ee7d3 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 154a2b2755a..d8c8607892b 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");