diff mbox series

Darwin, configury : Allow for specification and detection of dsymutil.

Message ID 2905A42D-F5C1-4AF9-A2A5-A69E2A692710@sandoe.co.uk
State New
Headers show
Series Darwin, configury : Allow for specification and detection of dsymutil. | expand

Commit Message

Iain Sandoe July 4, 2021, 8:21 p.m. UTC
Hi,

IMO this was an omission when the dsymutil program was added
(before my time).  Essentially, we have been ‘getting away with it’
on Darwin because of (a) restrictions in DWARF versions and (b)
that the installed tools handle a wide range of platform versions and
archs.

However, (a) is a barrier to moving Darwin to DWARF-4 or greater
and (b) is no longer true for people who might build cross- toolchains
for older Darwin (or, the motiovating case, for brand new Arm64
Darwin).  In order to support necessary tests for (a) we produce a
version record that can be tested.

This replicates the logic used for ‘as’ and ‘ld’ and now correctly
reports for ‘-v’ and works with discovery of installed “binutils” in the
target dir (or for specific paths given).

tested across the Darwin range and on crosses and canadian (native)
crosses to powerpc and Arm64 darwin.  Also tested on x86_64 
and powerpc64 linux.

OK for master?
thanks
Iain

===

In order to enable DWARF versions > 2 we need a sufficiently modern
version of dsymutil (in addition to the assembler / linker).  This
allows the user to configure a different path from the installed one.

In addition, there are several sources of dsymutil so we differentiate
these in order to be get accurate version information.

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

gcc/ChangeLog:

	* configure.ac: Handle --with-dsymutil in the same way as we
	do for the assembler and linker.  (DEFAULT_DSYMUTIL): New.
	Extract the type and version for the dsymutil configured or
	found by the default searches.
	* config.in: Regenerated.
	* configure: Regenerated.
	* collect2.c (do_dsymutil): Handle locating dsymutil in the
	same way as for the assembler and  linker.
	* config/darwin.h (DSYMUTIL): Delete.
	* gcc.c: Report a configured dsymutil correctly.

ChangeLog:

	* Makefile.def: Add dsymutil defs.
	* Makefile.in: Regenerated.
	* Makefile.tpl: Add dsymutil to flags.
	* configure: Regenerated.
	* configure.ac: Add dsymutil to target and build recipes.
---
 Makefile.def        |   1 +
 Makefile.in         |  10 ++
 Makefile.tpl        |   9 +
 configure           | 413 ++++++++++++++++++++++++++++++++++++++++++++
 configure.ac        |   6 +
 gcc/collect2.c      |  40 ++++-
 gcc/config.in       |  12 ++
 gcc/config/darwin.h |   2 -
 gcc/configure       | 166 +++++++++++++++++-
 gcc/configure.ac    |  96 +++++++++-
 gcc/exec-tool.in    |   8 +
 gcc/gcc.c           |   5 +
 12 files changed, 757 insertions(+), 11 deletions(-)

Comments

Richard Biener July 5, 2021, 10:54 a.m. UTC | #1
On Sun, Jul 4, 2021 at 10:22 PM Iain Sandoe <iain@sandoe.co.uk> wrote:
>
> Hi,
>
> IMO this was an omission when the dsymutil program was added
> (before my time).  Essentially, we have been ‘getting away with it’
> on Darwin because of (a) restrictions in DWARF versions and (b)
> that the installed tools handle a wide range of platform versions and
> archs.
>
> However, (a) is a barrier to moving Darwin to DWARF-4 or greater
> and (b) is no longer true for people who might build cross- toolchains
> for older Darwin (or, the motiovating case, for brand new Arm64
> Darwin).  In order to support necessary tests for (a) we produce a
> version record that can be tested.
>
> This replicates the logic used for ‘as’ and ‘ld’ and now correctly
> reports for ‘-v’ and works with discovery of installed “binutils” in the
> target dir (or for specific paths given).
>
> tested across the Darwin range and on crosses and canadian (native)
> crosses to powerpc and Arm64 darwin.  Also tested on x86_64
> and powerpc64 linux.
>
> OK for master?

OK.

Thanks,
Richard.

> thanks
> Iain
>
> ===
>
> In order to enable DWARF versions > 2 we need a sufficiently modern
> version of dsymutil (in addition to the assembler / linker).  This
> allows the user to configure a different path from the installed one.
>
> In addition, there are several sources of dsymutil so we differentiate
> these in order to be get accurate version information.
>
> Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
>
> gcc/ChangeLog:
>
>         * configure.ac: Handle --with-dsymutil in the same way as we
>         do for the assembler and linker.  (DEFAULT_DSYMUTIL): New.
>         Extract the type and version for the dsymutil configured or
>         found by the default searches.
>         * config.in: Regenerated.
>         * configure: Regenerated.
>         * collect2.c (do_dsymutil): Handle locating dsymutil in the
>         same way as for the assembler and  linker.
>         * config/darwin.h (DSYMUTIL): Delete.
>         * gcc.c: Report a configured dsymutil correctly.
>
> ChangeLog:
>
>         * Makefile.def: Add dsymutil defs.
>         * Makefile.in: Regenerated.
>         * Makefile.tpl: Add dsymutil to flags.
>         * configure: Regenerated.
>         * configure.ac: Add dsymutil to target and build recipes.
> ---
>  Makefile.def        |   1 +
>  Makefile.in         |  10 ++
>  Makefile.tpl        |   9 +
>  configure           | 413 ++++++++++++++++++++++++++++++++++++++++++++
>  configure.ac        |   6 +
>  gcc/collect2.c      |  40 ++++-
>  gcc/config.in       |  12 ++
>  gcc/config/darwin.h |   2 -
>  gcc/configure       | 166 +++++++++++++++++-
>  gcc/configure.ac    |  96 +++++++++-
>  gcc/exec-tool.in    |   8 +
>  gcc/gcc.c           |   5 +
>  12 files changed, 757 insertions(+), 11 deletions(-)
>
> diff --git a/Makefile.def b/Makefile.def
> index c83d9c4a813..fbfdb6fee08 100644
> --- a/Makefile.def
> +++ b/Makefile.def
> @@ -291,6 +291,7 @@ flags_to_pass = { flag= CFLAGS_FOR_TARGET ; };
>  flags_to_pass = { flag= CPPFLAGS_FOR_TARGET ; };
>  flags_to_pass = { flag= CXXFLAGS_FOR_TARGET ; };
>  flags_to_pass = { flag= DLLTOOL_FOR_TARGET ; };
> +flags_to_pass = { flag= DSYMUTIL_FOR_TARGET ; };
>  flags_to_pass = { flag= FLAGS_FOR_TARGET ; };
>  flags_to_pass = { flag= GFORTRAN_FOR_TARGET ; };
>  flags_to_pass = { flag= GOC_FOR_TARGET ; };
>
> diff --git a/Makefile.tpl b/Makefile.tpl
> index 6e0337fb48f..bffd85bd68e 100644
> --- a/Makefile.tpl
> +++ b/Makefile.tpl
> @@ -162,6 +162,7 @@ BUILD_EXPORTS = \
>         GDC="$(GDC_FOR_BUILD)"; export GDC; \
>         GDCFLAGS="$(GDCFLAGS_FOR_BUILD)"; export GDCFLAGS; \
>         DLLTOOL="$(DLLTOOL_FOR_BUILD)"; export DLLTOOL; \
> +       DSYMUTIL="$(DSYMUTIL_FOR_BUILD)"; export DSYMUTIL; \
>         LD="$(LD_FOR_BUILD)"; export LD; \
>         LDFLAGS="$(LDFLAGS_FOR_BUILD)"; export LDFLAGS; \
>         NM="$(NM_FOR_BUILD)"; export NM; \
> @@ -203,6 +204,7 @@ HOST_EXPORTS = \
>         CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
>         CXX_FOR_BUILD="$(CXX_FOR_BUILD)"; export CXX_FOR_BUILD; \
>         DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
> +       DSYMUTIL="$(DSYMUTIL)"; export DSYMUTIL; \
>         LD="$(LD)"; export LD; \
>         LDFLAGS="$(STAGE1_LDFLAGS) $(LDFLAGS)"; export LDFLAGS; \
>         NM="$(NM)"; export NM; \
> @@ -215,6 +217,7 @@ HOST_EXPORTS = \
>         READELF="$(READELF)"; export READELF; \
>         AR_FOR_TARGET="$(AR_FOR_TARGET)"; export AR_FOR_TARGET; \
>         AS_FOR_TARGET="$(AS_FOR_TARGET)"; export AS_FOR_TARGET; \
> +       DSYMUTIL_FOR_TARGET="$(DSYMUTIL_FOR_TARGET)"; export DSYMUTIL_FOR_TARGET; \
>         GCC_FOR_TARGET="$(GCC_FOR_TARGET)"; export GCC_FOR_TARGET; \
>         LD_FOR_TARGET="$(LD_FOR_TARGET)"; export LD_FOR_TARGET; \
>         NM_FOR_TARGET="$(NM_FOR_TARGET)"; export NM_FOR_TARGET; \
> @@ -297,6 +300,7 @@ BASE_TARGET_EXPORTS = \
>         GOC="$(GOC_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS"; export GOC; \
>         GDC="$(GDC_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS"; export GDC; \
>         DLLTOOL="$(DLLTOOL_FOR_TARGET)"; export DLLTOOL; \
> +       DSYMUTIL="$(DSYMUTIL_FOR_TARGET)"; export DSYMUTIL; \
>         LD="$(COMPILER_LD_FOR_TARGET)"; export LD; \
>         LDFLAGS="$(LDFLAGS_FOR_TARGET)"; export LDFLAGS; \
>         LIPO="$(LIPO_FOR_TARGET)"; export LIPO; \
> @@ -359,6 +363,7 @@ CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@
>  CXXFLAGS_FOR_BUILD = @CXXFLAGS_FOR_BUILD@
>  CXX_FOR_BUILD = @CXX_FOR_BUILD@
>  DLLTOOL_FOR_BUILD = @DLLTOOL_FOR_BUILD@
> +DSYMUTIL_FOR_BUILD = @DSYMUTIL_FOR_BUILD@
>  GFORTRAN_FOR_BUILD = @GFORTRAN_FOR_BUILD@
>  GOC_FOR_BUILD = @GOC_FOR_BUILD@
>  GDC_FOR_BUILD = @GDC_FOR_BUILD@
> @@ -409,6 +414,7 @@ AR_FLAGS = rc
>  CC = @CC@
>  CXX = @CXX@
>  DLLTOOL = @DLLTOOL@
> +DSYMUTIL = @DSYMUTIL@
>  LD = @LD@
>  LIPO = @LIPO@
>  NM = @NM@
> @@ -519,6 +525,7 @@ GFORTRAN_FOR_TARGET=$(STAGE_CC_WRAPPER) @GFORTRAN_FOR_TARGET@
>  GOC_FOR_TARGET=$(STAGE_CC_WRAPPER) @GOC_FOR_TARGET@
>  GDC_FOR_TARGET=$(STAGE_CC_WRAPPER) @GDC_FOR_TARGET@
>  DLLTOOL_FOR_TARGET=@DLLTOOL_FOR_TARGET@
> +DSYMUTIL_FOR_TARGET=@DSYMUTIL_FOR_TARGET@
>  LD_FOR_TARGET=@LD_FOR_TARGET@
>
>  LIPO_FOR_TARGET=@LIPO_FOR_TARGET@
> @@ -644,6 +651,7 @@ EXTRA_HOST_FLAGS = \
>         'CC=$(CC)' \
>         'CXX=$(CXX)' \
>         'DLLTOOL=$(DLLTOOL)' \
> +       'DSYMUTIL=$(DSYMUTIL)' \
>         'GFORTRAN=$(GFORTRAN)' \
>         'GOC=$(GOC)' \
>         'GDC=$(GDC)' \
> @@ -702,6 +710,7 @@ EXTRA_TARGET_FLAGS = \
>          $$(XGCC_FLAGS_FOR_TARGET) $$(TFLAGS)' \
>         'CXXFLAGS=$$(CXXFLAGS_FOR_TARGET)' \
>         'DLLTOOL=$$(DLLTOOL_FOR_TARGET)' \
> +       'DSYMUTIL=$$(DSYMUTIL_FOR_TARGET)' \
>         'GFORTRAN=$$(GFORTRAN_FOR_TARGET) $$(XGCC_FLAGS_FOR_TARGET) $$(TFLAGS)' \
>         'GOC=$$(GOC_FOR_TARGET) $$(XGCC_FLAGS_FOR_TARGET) $$(TFLAGS)' \
>         'GOCFLAGS=$$(GOCFLAGS_FOR_TARGET)’ \
>
> diff --git a/configure.ac b/configure.ac
> index 66d637d70dc..041ee249bac 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -1335,6 +1335,7 @@ if test "${build}" != "${host}" ; then
>    AS_FOR_BUILD=${AS_FOR_BUILD-as}
>    CC_FOR_BUILD=${CC_FOR_BUILD-gcc}
>    CXX_FOR_BUILD=${CXX_FOR_BUILD-g++}
> +  DSYMUTIL_FOR_BUILD=${DSYMUTIL_FOR_BUILD-dsymutil}
>    GFORTRAN_FOR_BUILD=${GFORTRAN_FOR_BUILD-gfortran}
>    GOC_FOR_BUILD=${GOC_FOR_BUILD-gccgo}
>    GDC_FOR_BUILD=${GDC_FOR_BUILD-gdc}
> @@ -1349,6 +1350,7 @@ else
>    AS_FOR_BUILD="\$(AS)"
>    CC_FOR_BUILD="\$(CC)"
>    CXX_FOR_BUILD="\$(CXX)"
> +  DSYMUTIL_FOR_BUILD="\$(DSYMUTIL)"
>    GFORTRAN_FOR_BUILD="\$(GFORTRAN)"
>    GOC_FOR_BUILD="\$(GOC)"
>    GDC_FOR_BUILD="\$(GDC)"
> @@ -3380,6 +3382,7 @@ AC_SUBST(CFLAGS_FOR_BUILD)
>  AC_SUBST(CXXFLAGS_FOR_BUILD)
>  AC_SUBST(CXX_FOR_BUILD)
>  AC_SUBST(DLLTOOL_FOR_BUILD)
> +AC_SUBST(DSYMUTIL_FOR_BUILD)
>  AC_SUBST(GFORTRAN_FOR_BUILD)
>  AC_SUBST(GOC_FOR_BUILD)
>  AC_SUBST(GDC_FOR_BUILD)
> @@ -3459,6 +3462,7 @@ esac
>  NCN_STRICT_CHECK_TOOLS(AR, ar)
>  NCN_STRICT_CHECK_TOOLS(AS, as)
>  NCN_STRICT_CHECK_TOOLS(DLLTOOL, dlltool)
> +NCN_STRICT_CHECK_TOOLS(DSYMUTIL, dsymutil)
>  NCN_STRICT_CHECK_TOOLS(LD, ld)
>  NCN_STRICT_CHECK_TOOLS(LIPO, lipo)
>  NCN_STRICT_CHECK_TOOLS(NM, nm)
> @@ -3498,6 +3502,7 @@ NCN_STRICT_CHECK_TARGET_TOOLS(GDC_FOR_TARGET, gdc)
>  ACX_CHECK_INSTALLED_TARGET_TOOL(AR_FOR_TARGET, ar)
>  ACX_CHECK_INSTALLED_TARGET_TOOL(AS_FOR_TARGET, as)
>  ACX_CHECK_INSTALLED_TARGET_TOOL(DLLTOOL_FOR_TARGET, dlltool)
> +ACX_CHECK_INSTALLED_TARGET_TOOL(DSYMUTIL_FOR_TARGET, dsymutil)
>  ACX_CHECK_INSTALLED_TARGET_TOOL(LD_FOR_TARGET, ld)
>  ACX_CHECK_INSTALLED_TARGET_TOOL(LIPO_FOR_TARGET, lipo)
>  ACX_CHECK_INSTALLED_TARGET_TOOL(NM_FOR_TARGET, nm)
> @@ -3523,6 +3528,7 @@ GCC_TARGET_TOOL(c++ for libstdc++, RAW_CXX_FOR_TARGET, CXX,
>                 [gcc/xgcc -shared-libgcc -B$$r/$(HOST_SUBDIR)/gcc -nostdinc++ -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/libsupc++/.libs],
>                 c++)
>  GCC_TARGET_TOOL(dlltool, DLLTOOL_FOR_TARGET, DLLTOOL, [binutils/dlltool])
> +GCC_TARGET_TOOL(dsymutil, DSYMUTIL_FOR_TARGET, DSYMUTIL)
>  GCC_TARGET_TOOL(gcc, GCC_FOR_TARGET, , [gcc/xgcc -B$$r/$(HOST_SUBDIR)/gcc/])
>  GCC_TARGET_TOOL(gfortran, GFORTRAN_FOR_TARGET, GFORTRAN,
>                 [gcc/gfortran -B$$r/$(HOST_SUBDIR)/gcc/], fortran)
> diff --git a/gcc/collect2.c b/gcc/collect2.c
> index b08c6e7afae..07092c2733a 100644
> --- a/gcc/collect2.c
> +++ b/gcc/collect2.c
> @@ -3040,15 +3040,49 @@ process_args (int *argcp, char **argv) {
>
>  static void
>  do_dsymutil (const char *output_file) {
> -  const char *dsymutil = DSYMUTIL + 1;
> +  const char *dsymutil = 0;
>    struct pex_obj *pex;
> -  char **real_argv = XCNEWVEC (char *, 3);
> +  char **real_argv = XCNEWVEC (char *, verbose ? 4 : 3);
>    const char ** argv = CONST_CAST2 (const char **, char **,
>                                     real_argv);
> +/* For cross-builds search the PATH using target-qualified name if we
> +   have not already found a suitable dsymutil.  In practice, all modern
> +   versions of dsymutil handle all supported archs, however the approach
> +   here is consistent with the way other installations work (and one can
> +   always symlink a multitarget dsymutil with a target-specific name).  */
> +  const char *dsname = "dsymutil";
> +#ifdef CROSS_DIRECTORY_STRUCTURE
> +  const char *qname = concat (target_machine, "-", dsname, NULL);
> +#else
> +  const char *qname = dsname;
> +#endif
> +#ifdef DEFAULT_DSYMUTIL
> +  /* Configured default takes priority.  */
> +  if (dsymutil == 0 && access (DEFAULT_DSYMUTIL, X_OK) == 0)
> +    dsymutil = DEFAULT_DSYMUTIL;
> +  if (dsymutil == 0)
> +#endif
> +#ifdef DSYMUTIL
> +  /* Followed by one supplied in the target header, somewhat like the
> +     REAL_XX_NAME used elsewhere.  */
> +    dsymutil = find_a_file (&cpath, DSYMUTIL, X_OK);
> +  if (dsymutil == 0)
> +    dsymutil = find_a_file (&path, DSYMUTIL, X_OK);
> +  if (dsymutil == 0)
> +#endif
> +    dsymutil = find_a_file (&cpath, dsname, X_OK);
> +  if (dsymutil == 0)
> +    dsymutil = find_a_file (&path, qname, X_OK);
>
>    argv[0] = dsymutil;
>    argv[1] = output_file;
> -  argv[2] = (char *) 0;
> +  if (verbose)
> +    {
> +      argv[2] = "-v";
> +      argv[3] = (char *) 0;
> +    }
> +  else
> +    argv[2] = (char *) 0;
>
>    pex = collect_execute (dsymutil, real_argv, NULL, NULL,
>                          PEX_LAST | PEX_SEARCH, false, NULL);
> diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
> index 5f119789973..20d6b1e9c05 100644
> --- a/gcc/config/darwin.h
> +++ b/gcc/config/darwin.h
> @@ -240,8 +240,6 @@ extern GTY(()) int darwin_ms_struct;
>      DARWIN_NOCOMPACT_UNWIND \
>      "}}}}}}} %<pie %<no-pie %<rdynamic %<X "
>
> -#define DSYMUTIL "\ndsymutil"
> -
>  /* Spec that controls whether the debug linker is run automatically for
>     a link step.  This needs to be done if there is a source file on the
>     command line which will result in a temporary object (and debug is
>
> diff --git a/gcc/configure.ac b/gcc/configure.ac
> index 70089394429..26da07325e7 100644
> --- a/gcc/configure.ac
> +++ b/gcc/configure.ac
> @@ -316,8 +316,14 @@ gnu_ld_flag="$with_gnu_ld",
>  gnu_ld_flag=no)
>
>  case $target in
> -    *darwin*) ld64_flag=yes;; # Darwin can only use a ld64-compatible linker.
> -    *) ld64_flag=no;;
> +    *darwin*)
> +       ld64_flag=yes # Darwin can only use a ld64-compatible linker.
> +       dsymutil_flag=yes # Darwin uses dsymutil to link debug.
> +       ;;
> +    *)
> +       ld64_flag=no
> +       dsymutil_flag=no
> +       ;;
>  esac
>
>  # With pre-defined ld
> @@ -353,6 +359,31 @@ AC_ARG_WITH(demangler-in-ld,
>  demangler_in_ld="$with_demangler_in_ld",
>  demangler_in_ld=yes)
>
> +# Allow the user to specify a dsymutil executable (used on Darwin only, so far)
> +AC_ARG_WITH(dsymutil,
> +[AS_HELP_STRING([--with-dsymutil], [arrange to use the specified dsymutil (full pathname)])],
> +DEFAULT_DSYMUTIL="$with_dsymutil")
> +
> +dsymutil_vers=
> +if test x"${DEFAULT_DSYMUTIL+set}" = x"set"; then
> +  if test ! -x "$DEFAULT_DSYMUTIL"; then
> +    AC_MSG_ERROR([cannot execute: $DEFAULT_DSYMUTIL: check --with-dsymutil or env. var. DEFAULT_DSYMUTIL])
> +  else
> +    if dsymutil_vers=`$DEFAULT_DSYMUTIL -v /dev/null 2>&1`; then
> +      dsymutil_flag=yes
> +    fi
> +  fi
> +  AC_DEFINE_UNQUOTED(DEFAULT_DSYMUTIL,"$DEFAULT_DSYMUTIL",
> +       [Define to enable the use of a default debug linker.])
> +fi
> +
> +AC_MSG_CHECKING([whether a default dsymutil was specified])
> +if test x"${DEFAULT_DSYMUTIL+set}" = x"set"; then
> +  AC_MSG_RESULT([yes ($DEFAULT_DSYMUTIL)])
> +else
> +  AC_MSG_RESULT(no)
> +fi
> +
>  # ----------------------
>  # Find default assembler
>  # ----------------------
> @@ -2852,6 +2883,27 @@ else
>         AC_MSG_RESULT($gcc_cv_otool)
>  fi
>
> +# Figure out the dsymutil we will use.
> +AS_VAR_SET_IF(gcc_cv_dsymutil,, [
> +if test -x "$DEFAULT_DSYMUTIL"; then
> +    gcc_cv_dsymutil="$DEFAULT_DSYMUTIL"
> +elif test -x dsymutil$build_exeext; then
> +    gcc_cv_dsymutil=./dsymutil$build_exeext
> +elif ( set dummy $DSYMUTIL_FOR_TARGET; test -x $[2] ); then
> +    gcc_cv_dsymutil=$DSYMUTIL_FOR_TARGET
> +elif ( set dummy $DSYMUTIL; test -x $[2] ); then
> +    gcc_cv_dsymutil=$DSYMUTIL
> +else
> +    AC_PATH_PROG(gcc_cv_dsymutil, $DSYMUTIL_FOR_TARGET)
> +fi])
> +
> +ORIGINAL_DSYMUTIL_FOR_TARGET=$gcc_cv_dsymutil
> +AC_SUBST(ORIGINAL_DSYMUTIL_FOR_TARGET)
> +case "$ORIGINAL_DSYMUTIL_FOR_TARGET" in
> +  ./dsymutil | ./dsymutil$build_exeext) ;;
> +  *) AC_CONFIG_FILES(dsymutil:exec-tool.in, [chmod +x dsymutil]) ;;
> +esac
> +
>  # Figure out what assembler alignment features are present.
>  gcc_GAS_CHECK_FEATURE([.balign and .p2align], gcc_cv_as_balign_and_p2align,
>   [2,6,0],,
> @@ -6240,6 +6292,46 @@ if test x"$ld64_flag" = x"yes"; then
>    [Define to 1 if ld64 supports '-export_dynamic'.])
>  fi
>
> +if test x"$dsymutil_flag" = x"yes"; then
> +
> +    # If the user specified a dsymutil path, then we will already have the
> +    # version string, otherwise, pick it up.
> +    if test x"$gcc_cv_dsymutil" = x; then
> +        AC_MSG_WARN([dsymutil is a required tool for this system, but not found])
> +        dsymutil_vers="tool unspecified"
> +    elif test x"$dsymutil_vers" = x; then
> +       dsymutil_vers=`$gcc_cv_dsymutil -v /dev/null 2>&1`
> +    fi
> +
> +    dsymutil_temp=`echo $dsymutil_vers | sed 1q`
> +    AC_MSG_CHECKING(dsymutil version "$dsymutil_temp")
> +    if echo $dsymutil_temp | grep dwarfutils- > /dev/null; then
> +      dsymutil_kind=DWARFUTILS
> +      dsymutil_vers=`echo $dsymutil_temp | sed 's/.*dwarfutils-\([[0-9\.]]*\).*/\1/'`
> +    elif echo $dsymutil_temp | grep clang- > /dev/null; then
> +      dsymutil_kind=CLANG
> +      dsymutil_vers=`echo $dsymutil_temp | sed 's/.*clang-\([[0-9\.]]*\).*/\1/'`
> +    elif echo $dsymutil_temp | grep 'LLVM version ' > /dev/null; then
> +      dsymutil_kind=LLVM
> +      dsymutil_vers=`echo $dsymutil_temp | sed 's/.*LLVM\ version\ \([[0-9\.]]*\).*/\1/'`
> +    else
> +      dsymutil_kind=UNKNOWN
> +      dsymutil_vers="0.0"
> +    fi
> +    dsymutil_major=`expr "$dsymutil_vers" : '\([[0-9]]*\)'`
> +    dsymutil_minor=`expr "$dsymutil_vers" : '[[0-9]]*\.\([[0-9]]*\)'`
> +    dsymutil_tiny=`expr "$dsymutil_vers" : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
> +    if test x"${dsymutil_minor}" = x; then
> +      dsymutil_minor=0
> +    fi
> +    if test x"${dsymutil_tiny}" = x; then
> +      dsymutil_tiny=0
> +    fi
> +    AC_DEFINE_UNQUOTED(DSYMUTIL_VERSION, [$dsymutil_kind,${dsymutil_major},${dsymutil_minor},${dsymutil_tiny}],
> +        [Define to the dsymutil version.])
> +    AC_MSG_RESULT($dsymutil_vers : $dsymutil_kind ${dsymutil_major} ${dsymutil_minor} ${dsymutil_tiny} )
> +fi
> +
>  case $target_os in
>    win32 | pe | cygwin* | mingw32*)
>      AC_MSG_CHECKING(broken PE linker dwarf5 support)
> diff --git a/gcc/exec-tool.in b/gcc/exec-tool.in
> index 9884601c13e..c206a254d51 100644
> --- a/gcc/exec-tool.in
> +++ b/gcc/exec-tool.in
> @@ -25,6 +25,7 @@ ORIGINAL_LD_BFD_FOR_TARGET="@ORIGINAL_LD_BFD_FOR_TARGET@"
>  ORIGINAL_LD_GOLD_FOR_TARGET="@ORIGINAL_LD_GOLD_FOR_TARGET@"
>  ORIGINAL_PLUGIN_LD_FOR_TARGET="@ORIGINAL_PLUGIN_LD_FOR_TARGET@"
>  ORIGINAL_NM_FOR_TARGET="@ORIGINAL_NM_FOR_TARGET@"
> +ORIGINAL_DSYMUTIL_FOR_TARGET="@ORIGINAL_DSYMUTIL_FOR_TARGET@"
>  exeext=@host_exeext@
>  fast_install=@enable_fast_install@
>  objdir=@objdir@
> @@ -71,6 +72,13 @@ case "$invoked" in
>      prog=nm-new$exeext
>      dir=binutils
>      ;;
> +  dsymutil)
> +    original=$ORIGINAL_DSYMUTIL_FOR_TARGET
> +    # We do not build this in tree - but still want to be able to execute
> +    # a configured version from the build dir.
> +    prog=
> +    dir=
> +    ;;
>  esac
>
>  case "$original" in
> diff --git a/gcc/gcc.c b/gcc/gcc.c
> index c8dbff61307..36a88fc99b0 100644
> --- a/gcc/gcc.c
> +++ b/gcc/gcc.c
> @@ -3062,6 +3062,11 @@ find_a_file (const struct path_prefix *pprefix, const char *name, int mode,
>      return xstrdup (DEFAULT_LINKER);
>  #endif
>
> +#ifdef DEFAULT_DSYMUTIL
> +  if (! strcmp (name, "dsymutil") && access (DEFAULT_DSYMUTIL, mode) == 0)
> +    return xstrdup (DEFAULT_DSYMUTIL);
> +#endif
> +
>    /* Determine the filename to execute (special case for absolute paths).  */
>
>    if (IS_ABSOLUTE_PATH (name))
> --
> 2.24.1
>
>
Joseph Myers July 5, 2021, 8:21 p.m. UTC | #2
On Sun, 4 Jul 2021, Iain Sandoe wrote:

> 	* configure.ac: Handle --with-dsymutil in the same way as we
> 	do for the assembler and linker.  (DEFAULT_DSYMUTIL): New.
> 	Extract the type and version for the dsymutil configured or
> 	found by the default searches.

This is missing documentation of --with-dsymutil in install.texi.
Iain Sandoe July 5, 2021, 8:27 p.m. UTC | #3
Hello Joseph,

> On 5 Jul 2021, at 21:21, Joseph Myers <joseph@codesourcery.com> wrote:
> 
> On Sun, 4 Jul 2021, Iain Sandoe wrote:
> 
>> 	* configure.ac: Handle --with-dsymutil in the same way as we
>> 	do for the assembler and linker.  (DEFAULT_DSYMUTIL): New.
>> 	Extract the type and version for the dsymutil configured or
>> 	found by the default searches.
> 
> This is missing documentation of --with-dsymutil in install.texi.

oops, sorry.

following the style of the other entries would this be suitable?

@item --with-dsymutil=@var{pathname}
Same as @uref{#with-as,,@option{--with-as}}
but for the debug linker (only used on Darwin platforms so far).


thanks
Iain
Joseph Myers July 5, 2021, 8:47 p.m. UTC | #4
On Mon, 5 Jul 2021, Iain Sandoe wrote:

> Hello Joseph,
> 
> > On 5 Jul 2021, at 21:21, Joseph Myers <joseph@codesourcery.com> wrote:
> > 
> > On Sun, 4 Jul 2021, Iain Sandoe wrote:
> > 
> >> 	* configure.ac: Handle --with-dsymutil in the same way as we
> >> 	do for the assembler and linker.  (DEFAULT_DSYMUTIL): New.
> >> 	Extract the type and version for the dsymutil configured or
> >> 	found by the default searches.
> > 
> > This is missing documentation of --with-dsymutil in install.texi.
> 
> oops, sorry.
> 
> following the style of the other entries would this be suitable?
> 
> @item --with-dsymutil=@var{pathname}
> Same as @uref{#with-as,,@option{--with-as}}
> but for the debug linker (only used on Darwin platforms so far).

Yes.
Iain Sandoe July 6, 2021, 8:25 a.m. UTC | #5
> On 5 Jul 2021, at 21:47, Joseph Myers <joseph@codesourcery.com> wrote:
> 
> On Mon, 5 Jul 2021, Iain Sandoe wrote:
> 
>> Hello Joseph,
>> 
>>> On 5 Jul 2021, at 21:21, Joseph Myers <joseph@codesourcery.com> wrote:
>>> 
>>> On Sun, 4 Jul 2021, Iain Sandoe wrote:
>>> 
>>>> 	* configure.ac: Handle --with-dsymutil in the same way as we
>>>> 	do for the assembler and linker.  (DEFAULT_DSYMUTIL): New.
>>>> 	Extract the type and version for the dsymutil configured or
>>>> 	found by the default searches.
>>> 
>>> This is missing documentation of --with-dsymutil in install.texi.
>> 
>> oops, sorry.
>> 
>> following the style of the other entries would this be suitable?
>> 
>> @item --with-dsymutil=@var{pathname}
>> Same as @uref{#with-as,,@option{--with-as}}
>> but for the debug linker (only used on Darwin platforms so far).
> 
> Yes.

This is what I’ve pushed (tested with make info and make pdf).
thanks,
Iain

===

Documentation : Describe --with-dsymutil configure option.

This adds documentation for the dsymutil configuration option
introduced with commit r12-2037-g3b5e8ee4f1ec.

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

gcc/ChangeLog:

	* doc/install.texi: Document --with-dsymutil.
---
 gcc/doc/install.texi | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index 94b167a3ed3..6eee1bb43d4 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -1084,6 +1084,10 @@ but for the linker.
 Same as @uref{#with-as,,@option{--with-as}}
 but for the linker.
 
+@item --with-dsymutil=@var{pathname}
+Same as @uref{#with-as,,@option{--with-as}}
+but for the debug linker (only used on Darwin platforms so far).
+
 @item --with-stabs
 Specify that stabs debugging
 information should be used instead of whatever format the host normally
diff mbox series

Patch

diff --git a/Makefile.def b/Makefile.def
index c83d9c4a813..fbfdb6fee08 100644
--- a/Makefile.def
+++ b/Makefile.def
@@ -291,6 +291,7 @@  flags_to_pass = { flag= CFLAGS_FOR_TARGET ; };
 flags_to_pass = { flag= CPPFLAGS_FOR_TARGET ; };
 flags_to_pass = { flag= CXXFLAGS_FOR_TARGET ; };
 flags_to_pass = { flag= DLLTOOL_FOR_TARGET ; };
+flags_to_pass = { flag= DSYMUTIL_FOR_TARGET ; };
 flags_to_pass = { flag= FLAGS_FOR_TARGET ; };
 flags_to_pass = { flag= GFORTRAN_FOR_TARGET ; };
 flags_to_pass = { flag= GOC_FOR_TARGET ; };

diff --git a/Makefile.tpl b/Makefile.tpl
index 6e0337fb48f..bffd85bd68e 100644
--- a/Makefile.tpl
+++ b/Makefile.tpl
@@ -162,6 +162,7 @@  BUILD_EXPORTS = \
 	GDC="$(GDC_FOR_BUILD)"; export GDC; \
 	GDCFLAGS="$(GDCFLAGS_FOR_BUILD)"; export GDCFLAGS; \
 	DLLTOOL="$(DLLTOOL_FOR_BUILD)"; export DLLTOOL; \
+	DSYMUTIL="$(DSYMUTIL_FOR_BUILD)"; export DSYMUTIL; \
 	LD="$(LD_FOR_BUILD)"; export LD; \
 	LDFLAGS="$(LDFLAGS_FOR_BUILD)"; export LDFLAGS; \
 	NM="$(NM_FOR_BUILD)"; export NM; \
@@ -203,6 +204,7 @@  HOST_EXPORTS = \
 	CC_FOR_BUILD="$(CC_FOR_BUILD)"; export CC_FOR_BUILD; \
 	CXX_FOR_BUILD="$(CXX_FOR_BUILD)"; export CXX_FOR_BUILD; \
 	DLLTOOL="$(DLLTOOL)"; export DLLTOOL; \
+	DSYMUTIL="$(DSYMUTIL)"; export DSYMUTIL; \
 	LD="$(LD)"; export LD; \
 	LDFLAGS="$(STAGE1_LDFLAGS) $(LDFLAGS)"; export LDFLAGS; \
 	NM="$(NM)"; export NM; \
@@ -215,6 +217,7 @@  HOST_EXPORTS = \
 	READELF="$(READELF)"; export READELF; \
 	AR_FOR_TARGET="$(AR_FOR_TARGET)"; export AR_FOR_TARGET; \
 	AS_FOR_TARGET="$(AS_FOR_TARGET)"; export AS_FOR_TARGET; \
+	DSYMUTIL_FOR_TARGET="$(DSYMUTIL_FOR_TARGET)"; export DSYMUTIL_FOR_TARGET; \
 	GCC_FOR_TARGET="$(GCC_FOR_TARGET)"; export GCC_FOR_TARGET; \
 	LD_FOR_TARGET="$(LD_FOR_TARGET)"; export LD_FOR_TARGET; \
 	NM_FOR_TARGET="$(NM_FOR_TARGET)"; export NM_FOR_TARGET; \
@@ -297,6 +300,7 @@  BASE_TARGET_EXPORTS = \
 	GOC="$(GOC_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS"; export GOC; \
 	GDC="$(GDC_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS"; export GDC; \
 	DLLTOOL="$(DLLTOOL_FOR_TARGET)"; export DLLTOOL; \
+	DSYMUTIL="$(DSYMUTIL_FOR_TARGET)"; export DSYMUTIL; \
 	LD="$(COMPILER_LD_FOR_TARGET)"; export LD; \
 	LDFLAGS="$(LDFLAGS_FOR_TARGET)"; export LDFLAGS; \
 	LIPO="$(LIPO_FOR_TARGET)"; export LIPO; \
@@ -359,6 +363,7 @@  CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@
 CXXFLAGS_FOR_BUILD = @CXXFLAGS_FOR_BUILD@
 CXX_FOR_BUILD = @CXX_FOR_BUILD@
 DLLTOOL_FOR_BUILD = @DLLTOOL_FOR_BUILD@
+DSYMUTIL_FOR_BUILD = @DSYMUTIL_FOR_BUILD@
 GFORTRAN_FOR_BUILD = @GFORTRAN_FOR_BUILD@
 GOC_FOR_BUILD = @GOC_FOR_BUILD@
 GDC_FOR_BUILD = @GDC_FOR_BUILD@
@@ -409,6 +414,7 @@  AR_FLAGS = rc
 CC = @CC@
 CXX = @CXX@
 DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
 LD = @LD@
 LIPO = @LIPO@
 NM = @NM@
@@ -519,6 +525,7 @@  GFORTRAN_FOR_TARGET=$(STAGE_CC_WRAPPER) @GFORTRAN_FOR_TARGET@
 GOC_FOR_TARGET=$(STAGE_CC_WRAPPER) @GOC_FOR_TARGET@
 GDC_FOR_TARGET=$(STAGE_CC_WRAPPER) @GDC_FOR_TARGET@
 DLLTOOL_FOR_TARGET=@DLLTOOL_FOR_TARGET@
+DSYMUTIL_FOR_TARGET=@DSYMUTIL_FOR_TARGET@
 LD_FOR_TARGET=@LD_FOR_TARGET@
 
 LIPO_FOR_TARGET=@LIPO_FOR_TARGET@
@@ -644,6 +651,7 @@  EXTRA_HOST_FLAGS = \
 	'CC=$(CC)' \
 	'CXX=$(CXX)' \
 	'DLLTOOL=$(DLLTOOL)' \
+	'DSYMUTIL=$(DSYMUTIL)' \
 	'GFORTRAN=$(GFORTRAN)' \
 	'GOC=$(GOC)' \
 	'GDC=$(GDC)' \
@@ -702,6 +710,7 @@  EXTRA_TARGET_FLAGS = \
 	 $$(XGCC_FLAGS_FOR_TARGET) $$(TFLAGS)' \
 	'CXXFLAGS=$$(CXXFLAGS_FOR_TARGET)' \
 	'DLLTOOL=$$(DLLTOOL_FOR_TARGET)' \
+	'DSYMUTIL=$$(DSYMUTIL_FOR_TARGET)' \
 	'GFORTRAN=$$(GFORTRAN_FOR_TARGET) $$(XGCC_FLAGS_FOR_TARGET) $$(TFLAGS)' \
 	'GOC=$$(GOC_FOR_TARGET) $$(XGCC_FLAGS_FOR_TARGET) $$(TFLAGS)' \
 	'GOCFLAGS=$$(GOCFLAGS_FOR_TARGET)’ \

diff --git a/configure.ac b/configure.ac
index 66d637d70dc..041ee249bac 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1335,6 +1335,7 @@  if test "${build}" != "${host}" ; then
   AS_FOR_BUILD=${AS_FOR_BUILD-as}
   CC_FOR_BUILD=${CC_FOR_BUILD-gcc}
   CXX_FOR_BUILD=${CXX_FOR_BUILD-g++}
+  DSYMUTIL_FOR_BUILD=${DSYMUTIL_FOR_BUILD-dsymutil}
   GFORTRAN_FOR_BUILD=${GFORTRAN_FOR_BUILD-gfortran}
   GOC_FOR_BUILD=${GOC_FOR_BUILD-gccgo}
   GDC_FOR_BUILD=${GDC_FOR_BUILD-gdc}
@@ -1349,6 +1350,7 @@  else
   AS_FOR_BUILD="\$(AS)"
   CC_FOR_BUILD="\$(CC)"
   CXX_FOR_BUILD="\$(CXX)"
+  DSYMUTIL_FOR_BUILD="\$(DSYMUTIL)"
   GFORTRAN_FOR_BUILD="\$(GFORTRAN)"
   GOC_FOR_BUILD="\$(GOC)"
   GDC_FOR_BUILD="\$(GDC)"
@@ -3380,6 +3382,7 @@  AC_SUBST(CFLAGS_FOR_BUILD)
 AC_SUBST(CXXFLAGS_FOR_BUILD)
 AC_SUBST(CXX_FOR_BUILD)
 AC_SUBST(DLLTOOL_FOR_BUILD)
+AC_SUBST(DSYMUTIL_FOR_BUILD)
 AC_SUBST(GFORTRAN_FOR_BUILD)
 AC_SUBST(GOC_FOR_BUILD)
 AC_SUBST(GDC_FOR_BUILD)
@@ -3459,6 +3462,7 @@  esac
 NCN_STRICT_CHECK_TOOLS(AR, ar)
 NCN_STRICT_CHECK_TOOLS(AS, as)
 NCN_STRICT_CHECK_TOOLS(DLLTOOL, dlltool)
+NCN_STRICT_CHECK_TOOLS(DSYMUTIL, dsymutil)
 NCN_STRICT_CHECK_TOOLS(LD, ld)
 NCN_STRICT_CHECK_TOOLS(LIPO, lipo)
 NCN_STRICT_CHECK_TOOLS(NM, nm)
@@ -3498,6 +3502,7 @@  NCN_STRICT_CHECK_TARGET_TOOLS(GDC_FOR_TARGET, gdc)
 ACX_CHECK_INSTALLED_TARGET_TOOL(AR_FOR_TARGET, ar)
 ACX_CHECK_INSTALLED_TARGET_TOOL(AS_FOR_TARGET, as)
 ACX_CHECK_INSTALLED_TARGET_TOOL(DLLTOOL_FOR_TARGET, dlltool)
+ACX_CHECK_INSTALLED_TARGET_TOOL(DSYMUTIL_FOR_TARGET, dsymutil)
 ACX_CHECK_INSTALLED_TARGET_TOOL(LD_FOR_TARGET, ld)
 ACX_CHECK_INSTALLED_TARGET_TOOL(LIPO_FOR_TARGET, lipo)
 ACX_CHECK_INSTALLED_TARGET_TOOL(NM_FOR_TARGET, nm)
@@ -3523,6 +3528,7 @@  GCC_TARGET_TOOL(c++ for libstdc++, RAW_CXX_FOR_TARGET, CXX,
 		[gcc/xgcc -shared-libgcc -B$$r/$(HOST_SUBDIR)/gcc -nostdinc++ -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/libsupc++/.libs],
 		c++)
 GCC_TARGET_TOOL(dlltool, DLLTOOL_FOR_TARGET, DLLTOOL, [binutils/dlltool])
+GCC_TARGET_TOOL(dsymutil, DSYMUTIL_FOR_TARGET, DSYMUTIL)
 GCC_TARGET_TOOL(gcc, GCC_FOR_TARGET, , [gcc/xgcc -B$$r/$(HOST_SUBDIR)/gcc/])
 GCC_TARGET_TOOL(gfortran, GFORTRAN_FOR_TARGET, GFORTRAN,
 		[gcc/gfortran -B$$r/$(HOST_SUBDIR)/gcc/], fortran)
diff --git a/gcc/collect2.c b/gcc/collect2.c
index b08c6e7afae..07092c2733a 100644
--- a/gcc/collect2.c
+++ b/gcc/collect2.c
@@ -3040,15 +3040,49 @@  process_args (int *argcp, char **argv) {
 
 static void
 do_dsymutil (const char *output_file) {
-  const char *dsymutil = DSYMUTIL + 1;
+  const char *dsymutil = 0;
   struct pex_obj *pex;
-  char **real_argv = XCNEWVEC (char *, 3);
+  char **real_argv = XCNEWVEC (char *, verbose ? 4 : 3);
   const char ** argv = CONST_CAST2 (const char **, char **,
 				    real_argv);
+/* For cross-builds search the PATH using target-qualified name if we
+   have not already found a suitable dsymutil.  In practice, all modern
+   versions of dsymutil handle all supported archs, however the approach
+   here is consistent with the way other installations work (and one can
+   always symlink a multitarget dsymutil with a target-specific name).  */
+  const char *dsname = "dsymutil";
+#ifdef CROSS_DIRECTORY_STRUCTURE
+  const char *qname = concat (target_machine, "-", dsname, NULL);
+#else
+  const char *qname = dsname;
+#endif
+#ifdef DEFAULT_DSYMUTIL
+  /* Configured default takes priority.  */
+  if (dsymutil == 0 && access (DEFAULT_DSYMUTIL, X_OK) == 0)
+    dsymutil = DEFAULT_DSYMUTIL;
+  if (dsymutil == 0)
+#endif
+#ifdef DSYMUTIL
+  /* Followed by one supplied in the target header, somewhat like the
+     REAL_XX_NAME used elsewhere.  */
+    dsymutil = find_a_file (&cpath, DSYMUTIL, X_OK);
+  if (dsymutil == 0)
+    dsymutil = find_a_file (&path, DSYMUTIL, X_OK);
+  if (dsymutil == 0)
+#endif
+    dsymutil = find_a_file (&cpath, dsname, X_OK);
+  if (dsymutil == 0)
+    dsymutil = find_a_file (&path, qname, X_OK);
 
   argv[0] = dsymutil;
   argv[1] = output_file;
-  argv[2] = (char *) 0;
+  if (verbose)
+    {
+      argv[2] = "-v";
+      argv[3] = (char *) 0;
+    }
+  else
+    argv[2] = (char *) 0;
 
   pex = collect_execute (dsymutil, real_argv, NULL, NULL,
 			 PEX_LAST | PEX_SEARCH, false, NULL);
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index 5f119789973..20d6b1e9c05 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -240,8 +240,6 @@  extern GTY(()) int darwin_ms_struct;
     DARWIN_NOCOMPACT_UNWIND \
     "}}}}}}} %<pie %<no-pie %<rdynamic %<X "
 
-#define DSYMUTIL "\ndsymutil"
-
 /* Spec that controls whether the debug linker is run automatically for
    a link step.  This needs to be done if there is a source file on the
    command line which will result in a temporary object (and debug is

diff --git a/gcc/configure.ac b/gcc/configure.ac
index 70089394429..26da07325e7 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -316,8 +316,14 @@  gnu_ld_flag="$with_gnu_ld",
 gnu_ld_flag=no)
 
 case $target in
-    *darwin*) ld64_flag=yes;; # Darwin can only use a ld64-compatible linker.
-    *) ld64_flag=no;;
+    *darwin*)
+	ld64_flag=yes # Darwin can only use a ld64-compatible linker.
+	dsymutil_flag=yes # Darwin uses dsymutil to link debug.
+	;;
+    *)
+	ld64_flag=no
+	dsymutil_flag=no
+	;;
 esac
 
 # With pre-defined ld
@@ -353,6 +359,31 @@  AC_ARG_WITH(demangler-in-ld,
 demangler_in_ld="$with_demangler_in_ld",
 demangler_in_ld=yes)
 
+# Allow the user to specify a dsymutil executable (used on Darwin only, so far)
+AC_ARG_WITH(dsymutil,
+[AS_HELP_STRING([--with-dsymutil], [arrange to use the specified dsymutil (full pathname)])],
+DEFAULT_DSYMUTIL="$with_dsymutil")
+
+dsymutil_vers=
+if test x"${DEFAULT_DSYMUTIL+set}" = x"set"; then
+  if test ! -x "$DEFAULT_DSYMUTIL"; then
+    AC_MSG_ERROR([cannot execute: $DEFAULT_DSYMUTIL: check --with-dsymutil or env. var. DEFAULT_DSYMUTIL])
+  else
+    if dsymutil_vers=`$DEFAULT_DSYMUTIL -v /dev/null 2>&1`; then
+      dsymutil_flag=yes
+    fi
+  fi
+  AC_DEFINE_UNQUOTED(DEFAULT_DSYMUTIL,"$DEFAULT_DSYMUTIL",
+	[Define to enable the use of a default debug linker.])
+fi
+
+AC_MSG_CHECKING([whether a default dsymutil was specified])
+if test x"${DEFAULT_DSYMUTIL+set}" = x"set"; then
+  AC_MSG_RESULT([yes ($DEFAULT_DSYMUTIL)])
+else
+  AC_MSG_RESULT(no)
+fi
+
 # ----------------------
 # Find default assembler
 # ----------------------
@@ -2852,6 +2883,27 @@  else
 	AC_MSG_RESULT($gcc_cv_otool)
 fi
 
+# Figure out the dsymutil we will use.
+AS_VAR_SET_IF(gcc_cv_dsymutil,, [
+if test -x "$DEFAULT_DSYMUTIL"; then
+    gcc_cv_dsymutil="$DEFAULT_DSYMUTIL"
+elif test -x dsymutil$build_exeext; then
+    gcc_cv_dsymutil=./dsymutil$build_exeext
+elif ( set dummy $DSYMUTIL_FOR_TARGET; test -x $[2] ); then
+    gcc_cv_dsymutil=$DSYMUTIL_FOR_TARGET
+elif ( set dummy $DSYMUTIL; test -x $[2] ); then
+    gcc_cv_dsymutil=$DSYMUTIL
+else
+    AC_PATH_PROG(gcc_cv_dsymutil, $DSYMUTIL_FOR_TARGET)
+fi])
+
+ORIGINAL_DSYMUTIL_FOR_TARGET=$gcc_cv_dsymutil
+AC_SUBST(ORIGINAL_DSYMUTIL_FOR_TARGET)
+case "$ORIGINAL_DSYMUTIL_FOR_TARGET" in
+  ./dsymutil | ./dsymutil$build_exeext) ;;
+  *) AC_CONFIG_FILES(dsymutil:exec-tool.in, [chmod +x dsymutil]) ;;
+esac 
+
 # Figure out what assembler alignment features are present.
 gcc_GAS_CHECK_FEATURE([.balign and .p2align], gcc_cv_as_balign_and_p2align,
  [2,6,0],,
@@ -6240,6 +6292,46 @@  if test x"$ld64_flag" = x"yes"; then
   [Define to 1 if ld64 supports '-export_dynamic'.])
 fi
 
+if test x"$dsymutil_flag" = x"yes"; then
+
+    # If the user specified a dsymutil path, then we will already have the
+    # version string, otherwise, pick it up.
+    if test x"$gcc_cv_dsymutil" = x; then
+        AC_MSG_WARN([dsymutil is a required tool for this system, but not found])
+        dsymutil_vers="tool unspecified"
+    elif test x"$dsymutil_vers" = x; then
+	dsymutil_vers=`$gcc_cv_dsymutil -v /dev/null 2>&1`
+    fi
+
+    dsymutil_temp=`echo $dsymutil_vers | sed 1q`
+    AC_MSG_CHECKING(dsymutil version "$dsymutil_temp")
+    if echo $dsymutil_temp | grep dwarfutils- > /dev/null; then
+      dsymutil_kind=DWARFUTILS
+      dsymutil_vers=`echo $dsymutil_temp | sed 's/.*dwarfutils-\([[0-9\.]]*\).*/\1/'`
+    elif echo $dsymutil_temp | grep clang- > /dev/null; then
+      dsymutil_kind=CLANG
+      dsymutil_vers=`echo $dsymutil_temp | sed 's/.*clang-\([[0-9\.]]*\).*/\1/'`
+    elif echo $dsymutil_temp | grep 'LLVM version ' > /dev/null; then
+      dsymutil_kind=LLVM
+      dsymutil_vers=`echo $dsymutil_temp | sed 's/.*LLVM\ version\ \([[0-9\.]]*\).*/\1/'`
+    else
+      dsymutil_kind=UNKNOWN
+      dsymutil_vers="0.0"
+    fi
+    dsymutil_major=`expr "$dsymutil_vers" : '\([[0-9]]*\)'`
+    dsymutil_minor=`expr "$dsymutil_vers" : '[[0-9]]*\.\([[0-9]]*\)'`
+    dsymutil_tiny=`expr "$dsymutil_vers" : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
+    if test x"${dsymutil_minor}" = x; then
+      dsymutil_minor=0
+    fi
+    if test x"${dsymutil_tiny}" = x; then
+      dsymutil_tiny=0
+    fi
+    AC_DEFINE_UNQUOTED(DSYMUTIL_VERSION, [$dsymutil_kind,${dsymutil_major},${dsymutil_minor},${dsymutil_tiny}],
+        [Define to the dsymutil version.])
+    AC_MSG_RESULT($dsymutil_vers : $dsymutil_kind ${dsymutil_major} ${dsymutil_minor} ${dsymutil_tiny} )
+fi
+
 case $target_os in
   win32 | pe | cygwin* | mingw32*)
     AC_MSG_CHECKING(broken PE linker dwarf5 support)
diff --git a/gcc/exec-tool.in b/gcc/exec-tool.in
index 9884601c13e..c206a254d51 100644
--- a/gcc/exec-tool.in
+++ b/gcc/exec-tool.in
@@ -25,6 +25,7 @@  ORIGINAL_LD_BFD_FOR_TARGET="@ORIGINAL_LD_BFD_FOR_TARGET@"
 ORIGINAL_LD_GOLD_FOR_TARGET="@ORIGINAL_LD_GOLD_FOR_TARGET@"
 ORIGINAL_PLUGIN_LD_FOR_TARGET="@ORIGINAL_PLUGIN_LD_FOR_TARGET@"
 ORIGINAL_NM_FOR_TARGET="@ORIGINAL_NM_FOR_TARGET@"
+ORIGINAL_DSYMUTIL_FOR_TARGET="@ORIGINAL_DSYMUTIL_FOR_TARGET@"
 exeext=@host_exeext@
 fast_install=@enable_fast_install@
 objdir=@objdir@
@@ -71,6 +72,13 @@  case "$invoked" in
     prog=nm-new$exeext
     dir=binutils
     ;;
+  dsymutil)
+    original=$ORIGINAL_DSYMUTIL_FOR_TARGET
+    # We do not build this in tree - but still want to be able to execute
+    # a configured version from the build dir.
+    prog=
+    dir=
+    ;;
 esac
 
 case "$original" in
diff --git a/gcc/gcc.c b/gcc/gcc.c
index c8dbff61307..36a88fc99b0 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -3062,6 +3062,11 @@  find_a_file (const struct path_prefix *pprefix, const char *name, int mode,
     return xstrdup (DEFAULT_LINKER);
 #endif
 
+#ifdef DEFAULT_DSYMUTIL
+  if (! strcmp (name, "dsymutil") && access (DEFAULT_DSYMUTIL, mode) == 0)
+    return xstrdup (DEFAULT_DSYMUTIL);
+#endif
+
   /* Determine the filename to execute (special case for absolute paths).  */
 
   if (IS_ABSOLUTE_PATH (name))