mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-12 20:34:19 +00:00
Estimated hours taken: 32
Branches: main
The objective of this diff is to switch from a table of solver events built
into the compiler (and eventually the debugger) into a table of events
defined by a file provided by the user to the compiler, which the compiler
then records in the executable for use by the debugger.
The current design, for speed of implementation, uses temporary files parsed
by a bison-generated parser. Since the compiler needs to be able to invoke
the parser even if it is compiled in a non-debug grade, the parser is in
a new library, the eventspec library, that is always linked into the Mercury
compiler and is always linked into any Mercury program with debugging enabled
(but is of course linked only once into a Mercury compiler which has debugging
enabled).
Modify the debugger to give it the ability to print the attributes of
user-defined events (for now, only the non-synthesized attributes).
Implement a new debugger command, "user", which goes to the next user-defined
event.
configure.in:
Require flex and and bison to be available.
doc/user_guide.texi:
Document user defined events and the new debugger capabilities.
doc/mdb_categories:
Include "user" in the list of forward movement commands.
Fix some earlier omissions in that list.
runtime/mercury_stack_layout.h:
Include an event number in the user-defined event structure.
Include a string representing an event set specification in module
layout structures.
runtime/mercury_stack_layout.h:
runtime/mercury_trace_base.[ch]:
runtime/mercury_types.h
Switch from solver events to user events in names.
runtime/mercury_trace_term.[ch]:
Provide a representation of flat terms, for use in representing
the calls that generate synthesized attributes.
Ensure that exported field names have an MR_ prefix.
browser/cterm.m:
Conform to the change to runtime/mercury_trace_term.h.
scripts/c2init.in:
scripts/ml.in:
Include the eventspec library in programs compiled with debugging
enabled.
compiler/Mmakefile:
Include the eventspec library in the compiler.
compiler/options.m:
Add a new option, --event-spec-file-name, that allows the user to
specify the set of user-defined events the program may use.
compiler/handle_options.m:
Set this optimization from an environment variable (which may be
set by the mmc script) if the new option is not explicitly given.
compiler/prog_data.m:
Define the data structures for the compiler's representation of the
event set specification.
Move some definitions around to group them more logically.
compiler/hlds_module.m:
Include the event set specification as a new field in the module_info.
compiler/prog_event.m:
Add the code for invoking the parser in the eventspec library,
and for converting the simple term output by the parser to the
compiler own representation, which contains more information
(to wit, the types of the function attributes) and which has had
a whole bunch of semantic checks done on it (e.g. whether synthesized
attributes depend on themselves or on nonexistent attributes).
Provide a function to generate a canonicalized version of the event
specification file.
compiler/module_qual.m:
compiler/equiv_type.m:
Process event spec specifications as well as items, to module qualify
the names of the types of event arguments, and expanding out
equivalence types.
In equiv_type.m, rename some variables to make clear what kind of info
they represent.
compiler/mercury_compile.m:
Process the event set specification file if one has been selected:
read it in, module qualify it, expand its equivalence types, and add
to the module_info.
compiler/compile_target_code.m:
Include the event_spec library when linking debuggable executables.
compiler/call_gen.m:
compiler/continuation_info.m:
compiler/trace_gen.m:
compiler/trace_params.m:
mdbcomp/prim_data.m:
mdbcomp/trace_counts.m:
runtime/mercury_goto.h:
Generate user-defined events instead of solver events.
compiler/layout.m:
compiler/layout_out.m:
compiler/stack_layout.m:
Include a canonicalized version of the event specification file
in the module layout if the module has any user-defined events.
compiler/code_info.m:
compiler/llds_out.m:
compiler/modes.m:
compiler/modules.m:
compiler/opt_debug.m:
compiler/typecheck.m:
Conform to the changes above.
compiler/passes_aux.m:
Rename a predicate to avoid an ambiguity.
trace/Mmakefile:
Add the definition and rules required to build the eventspec library.
trace/mercury_event_scanner.l:
trace/mercury_event_parser.y:
A scanner and a parser for reading in event spec specifications.
trace/mercury_event_spec_missing.h:
Provide the declarations that should be (but aren't) provided by
flex and bison.
trace/mercury_event_spec.[ch]:
The main module of the eventspec library. Provides functions to read
in event set specifications from a file, and to write them out as a
Mercury term in the form needed by the compiler.
trace/mercury_trace_tables.c:
If the module layouts being registered include event set
specifications, then check their consistency. Make the specification
and the consistency indication available to other modules.
trace/mercury_trace_internal.c:
During initialization, if the modules contain a consistent set of event
set specifications, then read that specification into the debugger.
(We don't yet make use of this information.)
Add an extra mdb command, "user", which goes forward to the next
user-defined event.
trace/mercury_trace.[ch]:
trace/mercury_trace_cmd_forward.[ch]:
Implement the new mdb command.
trace/mercury_trace_vars.[ch]:
For user-defined events, include the attributes' values among the
values that can be printed or browsed.
trace/mercury_trace_cmd_browsing.c:
trace/mercury_trace_declarative.c:
Minor changes.
scripts/scripts/prepare_tmp_dir_grade_part:
Copy the .y and .l files to the tmp dir we use for installs.
tools/bootcheck:
Copy the .y and .l files of the trace directory to stage 2.
tools/lmc.in:
Include the eventspec library when linking debuggable executables.
tests/debugger/user_event.{m,inp,exp}:
tests/debugger/user_event_spec:
New test case to test the new functionality.
tests/debugger/Mercury.options:
tests/debugger/Mmakefile:
Enable the new test case.
tests/debugger/completion.exp:
Expect the new "user" mdb command in the completion output.
469 lines
12 KiB
Bash
469 lines
12 KiB
Bash
#! /bin/sh
|
|
# @configure_input@
|
|
#---------------------------------------------------------------------------#
|
|
# Copyright (C) 1995-2006 The University of Melbourne.
|
|
# This file may only be copied under the terms of the GNU General
|
|
# Public License - see the file COPYING in the Mercury distribution.
|
|
#---------------------------------------------------------------------------#
|
|
#
|
|
# ML - Mercury Linker.
|
|
#
|
|
# Invokes GCC with the appropriate options to link in the Mercury library.
|
|
#
|
|
# Usage: see below.
|
|
#
|
|
# Environment variables: MERCURY_DEFAULT_GRADE, ...
|
|
#
|
|
# *************************************************************************
|
|
# *** IMPORTANT NOTE: any changes to this file may also require similar ***
|
|
# *** changes to compiler/compile_target_code.m and configure.in ***
|
|
# *************************************************************************
|
|
|
|
Usage="\
|
|
Name: ml - Mercury Linker
|
|
Usage: ml [<ml options>] [-- <gcc options>] files..."
|
|
|
|
FULLARCH=@FULLARCH@
|
|
DEFAULT_GRADE=${MERCURY_DEFAULT_GRADE=@DEFAULT_GRADE@}
|
|
|
|
# include the file `parse_ml_options.sh-subr'
|
|
@PARSE_ML_OPTIONS@
|
|
|
|
# add /usr/local/lib to the default search path, if needed
|
|
ALL_LOCAL_C_LIB_DIRS=${MERCURY_ALL_LOCAL_C_LIB_DIRS=@ALL_LOCAL_C_LIB_DIRS@}
|
|
NONSHARED_LIB_DIR=${MERCURY_NONSHARED_LIB_DIR=@NONSHARED_LIB_DIR@}
|
|
DEMANGLER=${MERCURY_DEMANGLER=mdemangle}
|
|
CC=${MERCURY_C_COMPILER="@CC@"}
|
|
MKFIFO=${MERCURY_MKFIFO="@MKFIFO@"}
|
|
ERROR_UNDEFINED="@ERROR_UNDEFINED@"
|
|
ALLOW_UNDEFINED="@ALLOW_UNDEFINED@"
|
|
EXE_RPATH_OPT=${MERCURY_EXE_RPATH_OPT="@EXE_RPATH_OPT@"}
|
|
EXE_RPATH_SEP=${MERCURY_EXE_RPATH_SEP="@EXE_RPATH_SEP@"}
|
|
EXT_FOR_SHARED_LIB=${MERCURY_EXT_FOR_SHARED_LIB="@EXT_FOR_SHARED_LIB@"}
|
|
LINK_SHARED_OBJ=${MERCURY_LINK_SHARED_OBJ="@LINK_SHARED_OBJ_SH@"}
|
|
SHLIB_RPATH_OPT=${MERCURY_SHLIB_RPATH_OPT="@SHLIB_RPATH_OPT@"}
|
|
SHLIB_RPATH_SEP=${MERCURY_SHLIB_RPATH_SEP="@SHLIB_RPATH_SEP@"}
|
|
FIX_PATH_FOR_LINKER=${MERCURY_PATH_FOR_LINKER="@FIX_PATH_FOR_CC@"}
|
|
LD_STATIC_FLAGS="@LD_STATIC_FLAGS@"
|
|
LDFLAGS_FOR_THREADS="@LDFLAGS_FOR_THREADS@"
|
|
LDFLAGS_FOR_TRACE="@LDFLAGS_FOR_TRACE@"
|
|
LD_LIBFLAGS_FOR_THREADS="@LD_LIBFLAGS_FOR_THREADS@"
|
|
THREAD_LIBS="@THREAD_LIBS@"
|
|
TRACE_LIBS_SYSTEM="@TRACE_LIBS_SYSTEM@"
|
|
|
|
TMPDIR=${TMPDIR=/tmp}
|
|
MATH_LIB=${MERCURY_MATH_LIB="@MATH_LIB@"}
|
|
# Note: the setting of SHARED_LIBS needs to come after the setting of MATH_LIB,
|
|
# since @SHARED_LIBS_SH@ may refer to $MATH_LIB.
|
|
SHARED_LIBS=${MERCURY_SHARED_LIBS="@SHARED_LIBS_SH@"}
|
|
|
|
# Set the MACOSX_DEPLOYMENT_TARGET environment variable if needed.
|
|
@SET_MACOSX_DEPLOYMENT_TARGET@
|
|
|
|
# When compiling in the hlc.gc grade using the Microsoft Visual C
|
|
# compiler, the default maximum stack size of 4Mb is too low for a
|
|
# recursive language.
|
|
# XXX at some stage this should become an option to ml
|
|
LINK=${LINK=/stack:10485760} # 10 Mb
|
|
export LINK
|
|
|
|
case "$CC" in
|
|
*gcc*)
|
|
COMPILER=gcc
|
|
;;
|
|
*lcc*)
|
|
COMPILER=lcc
|
|
;;
|
|
*cl* | *CL*)
|
|
COMPILER=cl
|
|
;;
|
|
cc* | */cc*)
|
|
COMPILER=cc
|
|
;;
|
|
*)
|
|
COMPILER=unknown
|
|
;;
|
|
esac
|
|
|
|
# Likewise for -ldl (libdl.so), which is often needed for dlopen() etc.
|
|
DL_LIBRARY="@DL_LIBRARY@"
|
|
|
|
# Likewise for -lreadline -l{termcap,curses,ncurses}
|
|
READLINE_LIBRARIES="@READLINE_LIBRARIES@"
|
|
|
|
# If you change these, you will also need to change the files indicated
|
|
# in scripts/c2init.in.
|
|
RT_LIB_NAME=mer_rt
|
|
STD_LIB_NAME=mer_std
|
|
TRACE_LIB_NAME=mer_trace
|
|
EVENTSPEC_LIB_NAME=mer_eventspec
|
|
BROWSER_LIB_NAME=mer_browser
|
|
MDBCOMP_LIB_NAME=mer_mdbcomp
|
|
|
|
MAYBE_STATIC_OPT=""
|
|
|
|
case $debug in
|
|
true) trace=true ;;
|
|
false) ;;
|
|
esac
|
|
|
|
case "$mercury_stdlib_dir" in
|
|
"") LIBDIR= ;;
|
|
*) LIBDIR=$mercury_stdlib_dir/lib ;;
|
|
esac
|
|
|
|
# If you haven't set mercury_libs, set it to the default value
|
|
# (shared on most systems). Note that if you have set all_libs,
|
|
# it will also have set mercury_libs.
|
|
case $mercury_libs in default)
|
|
mercury_libs=shared
|
|
case $FULLARCH in
|
|
i*86-*-linux*|i*86-*-freebsd*|i*86-*-cygwin*|i*86-*-solaris*)
|
|
# shared libraries are not the default on x86
|
|
#systems that use ELF -- see README.Linux
|
|
case $make_shared_lib in false)
|
|
mercury_libs=static
|
|
;;
|
|
esac
|
|
esac
|
|
;;
|
|
esac
|
|
|
|
# If you haven't set all_libs, set it to the default value
|
|
# (shared on most systems).
|
|
case $all_libs in default)
|
|
all_libs=shared
|
|
case $FULLARCH in
|
|
i*86-*-linux*|i*86-*-freebsd*|i*86-*-cygwin*)
|
|
# shared libraries are not the default on Linux
|
|
# -- see README.Linux
|
|
# Likewise for FreeBSD and Cygwin
|
|
#
|
|
# We don't do this for Solaris/x86 because -ldl is
|
|
# only available for dynamically linked executables
|
|
# XXX With these defaults linking with Mercury
|
|
# libraries other than the standard library will fail.
|
|
case $make_shared_lib in false)
|
|
all_libs=static
|
|
;;
|
|
esac
|
|
;;
|
|
esac
|
|
;;
|
|
esac
|
|
|
|
# Defaults have been set, now set options.
|
|
|
|
case $all_libs in static)
|
|
MAYBE_STATIC_OPT=$LD_STATIC_FLAGS
|
|
esac
|
|
|
|
#
|
|
# compute the canonical grade name from the options settings
|
|
#
|
|
|
|
# include the file `canonical_grade.sh-subr'
|
|
@CANONICAL_GRADE@
|
|
|
|
# if the --print-grade option is specified,
|
|
# then all we do is print the grade and then exit
|
|
case "$print_grade" in true)
|
|
echo $GRADE
|
|
exit 0
|
|
esac
|
|
|
|
# Compute the gc grade from the grade
|
|
case "$GRADE" in
|
|
*.par*.gcd*.prof*)
|
|
gc_grade=par_gc_debug_prof ;;
|
|
*.par*.gcd*)
|
|
gc_grade=par_gc_debug ;;
|
|
*.gcd*.prof*)
|
|
gc_grade=gc_debug_prof ;;
|
|
*.gcd*)
|
|
gc_grade=gc_debug ;;
|
|
*.par*.gc*.prof*)
|
|
gc_grade=par_gc_prof ;;
|
|
*.par*.gc*)
|
|
gc_grade=par_gc ;;
|
|
*.gc*.prof*)
|
|
gc_grade=gc_prof ;;
|
|
*.gc*)
|
|
gc_grade=gc ;;
|
|
*.mps*)
|
|
gc_grade=mps ;;
|
|
*)
|
|
gc_grade=nogc ;;
|
|
esac
|
|
|
|
# if the --print-gc-grade option is specified,
|
|
# then all we do is print the gc grade and then exit
|
|
case "$print_gc_grade" in true)
|
|
echo $gc_grade
|
|
exit 0
|
|
esac
|
|
|
|
case "$gc_grade" in
|
|
nogc)
|
|
LIBGC=
|
|
LIBGC_STATIC=
|
|
;;
|
|
*)
|
|
LIBGC="-l$gc_grade"
|
|
LIBGC_STATIC=`$FIX_PATH_FOR_LINKER \
|
|
$LIBDIR/lib$gc_grade.@LIB_SUFFIX@`
|
|
;;
|
|
esac
|
|
|
|
|
|
case $readline in
|
|
true) ;;
|
|
false) READLINE_LIBRARIES=
|
|
;;
|
|
esac
|
|
|
|
case $trace in
|
|
true) TRACE_LIBS="-l$TRACE_LIB_NAME -l$EVENTSPEC_LIB_NAME \
|
|
-l$BROWSER_LIB_NAME -l$MDBCOMP_LIB_NAME"
|
|
TRACE_LIBS_SYSTEM="$TRACE_LIBS_SYSTEM $READLINE_LIBRARIES"
|
|
TRACE_STATIC_LIBS="\
|
|
`$FIX_PATH_FOR_LINKER \
|
|
$LIBDIR/$GRADE/lib$TRACE_LIB_NAME.@LIB_SUFFIX@` \
|
|
`$FIX_PATH_FOR_LINKER \
|
|
$LIBDIR/$GRADE/lib$EVENTSPEC_LIB_NAME.@LIB_SUFFIX@` \
|
|
`$FIX_PATH_FOR_LINKER \
|
|
$LIBDIR/$GRADE/lib$BROWSER_LIB_NAME.@LIB_SUFFIX@` \
|
|
`$FIX_PATH_FOR_LINKER \
|
|
$LIBDIR/$GRADE/lib$MDBCOMP_LIB_NAME.@LIB_SUFFIX@`"
|
|
;;
|
|
false) TRACE_LIBS=
|
|
TRACE_LIBS_SYSTEM=
|
|
TRACE_STATIC_LIBS=
|
|
;;
|
|
esac
|
|
|
|
case $strip in
|
|
true) STRIP_OPTS="-s" ;;
|
|
false) STRIP_OPTS="" ;;
|
|
esac
|
|
|
|
# Determine whether to link the executable with debugging symbols when using
|
|
# MSVC.
|
|
if [ $strip = "false" -a $COMPILER = "cl" ]
|
|
then
|
|
DEBUG_FLAG="/DEBUG"
|
|
else
|
|
DEBUG_FLAG=""
|
|
fi
|
|
|
|
case $gc_method in mps)
|
|
use_thread_libs=true ;;
|
|
esac
|
|
case $thread_safe in true)
|
|
use_thread_libs=true ;;
|
|
esac
|
|
|
|
case $use_thread_libs.$make_shared_lib in
|
|
true.false) ARCH_OPTS=$LDFLAGS_FOR_THREADS ;;
|
|
true.true) ARCH_OPTS=$LD_LIBFLAGS_FOR_THREADS ;;
|
|
false.*) THREAD_LIBS="" ;;
|
|
esac
|
|
|
|
# Set the correct flags if we're to use the MS Visual C runtime.
|
|
use_msvcrt=@USE_MSVCRT@
|
|
if test $use_msvcrt = "yes"; then
|
|
MSVCRT_OPTS="/MD" # enable linking with the MS Visual C runtime
|
|
NODEFAULTLIB_FLAG="/nodefaultlib:libc"
|
|
else
|
|
MSVCRT_OPTS=""
|
|
NODEFAULTLIB_FLAG=""
|
|
fi
|
|
|
|
case $make_shared_lib in
|
|
true)
|
|
LINKER="$LINK_SHARED_OBJ"
|
|
case $allow_undef in
|
|
true) UNDEF_OPT="$ALLOW_UNDEFINED" ;;
|
|
false) UNDEF_OPT="$ERROR_UNDEFINED" ;;
|
|
esac
|
|
RPATH_OPT="$SHLIB_RPATH_OPT"
|
|
RPATH_SEP="$SHLIB_RPATH_SEP"
|
|
STDLIBS="$SHARED_LIBS $THREAD_LIBS"
|
|
case $trace in true)
|
|
ARCH_OPTS="$ARCH_OPTS $LD_LIBFLAGS_FOR_TRACE"
|
|
esac
|
|
;;
|
|
false)
|
|
LINKER="$CC"
|
|
UNDEF_OPT=""
|
|
RPATH_OPT="$EXE_RPATH_OPT"
|
|
RPATH_SEP="$EXE_RPATH_SEP"
|
|
STDLIBS="$MATH_LIB $THREAD_LIBS"
|
|
case $trace in true)
|
|
ARCH_OPTS="$ARCH_OPTS $LDFLAGS_FOR_TRACE"
|
|
esac
|
|
;;
|
|
esac
|
|
|
|
# if the --print-link-command option is specified,
|
|
# then all we do is print the command used to link executables
|
|
# and then exit.
|
|
case "$print_link_command" in true)
|
|
echo $LINKER
|
|
exit 0
|
|
esac
|
|
|
|
# if the --print-shared-lib-command option is specified,
|
|
# then all we do is print the command used to link executables
|
|
# and then exit.
|
|
case "$print_shared_lib_link_command" in true)
|
|
echo $LINK_SHARED_OBJ
|
|
exit 0
|
|
esac
|
|
|
|
if $print_map
|
|
then
|
|
PRINT_MAP_OPT="-Wl,--print-map"
|
|
else
|
|
PRINT_MAP_OPT=""
|
|
fi
|
|
|
|
merc_libdir_opts="\
|
|
@LIB_LIBPATH@$LIBDIR/$GRADE
|
|
@LIB_LIBPATH@$LIBDIR
|
|
"
|
|
system_libdir_opts=
|
|
for dir in $ALL_LOCAL_C_LIB_DIRS kludge_for_broken_shells; do
|
|
if [ "$dir" != "kludge_for_broken_shells" ]; then
|
|
system_libdir_opts="@LIB_LIBPATH@$dir $system_libdir_opts"
|
|
fi
|
|
done
|
|
LIBDIR_OPTS="$user_libdir_opts $merc_libdir_opts $system_libdir_opts"
|
|
|
|
case $mercury_libs in
|
|
shared)
|
|
MERCURY_LIBS=${MERCURY_LIBS="$TRACE_LIBS -l$STD_LIB_NAME -l$RT_LIB_NAME $LIBGC"}
|
|
LIBS=${LIBS="$MERCURY_LIBS $TRACE_LIBS_SYSTEM $STDLIBS"}
|
|
merc_shlib_dirs="$merc_shlib_dirs $LIBDIR/$GRADE"
|
|
merc_shlib_dirs="$merc_shlib_dirs $LIBDIR"
|
|
;;
|
|
static)
|
|
MERCURY_LIBS=${MERCURY_LIBS="$TRACE_STATIC_LIBS
|
|
`$FIX_PATH_FOR_LINKER \
|
|
$LIBDIR/$GRADE/lib$STD_LIB_NAME.@LIB_SUFFIX@` \
|
|
`$FIX_PATH_FOR_LINKER \
|
|
$LIBDIR/$GRADE/lib$RT_LIB_NAME.@LIB_SUFFIX@` \
|
|
$LIBGC_STATIC"}
|
|
LIBS=${LIBS="$MERCURY_LIBS $TRACE_LIBS_SYSTEM $STDLIBS"}
|
|
merc_shlib_dirs=""
|
|
;;
|
|
none) LIBS="$TRACE_LIBS_SYSTEM $STDLIBS"
|
|
LIBDIR_OPTS="$user_libdir_opts $system_libdir_opts"
|
|
merc_shlib_dirs=""
|
|
;;
|
|
esac
|
|
|
|
case $all_libs in
|
|
shared) system_shlib_dirs=$ALL_LOCAL_C_LIB_DIRS ;;
|
|
static) system_shlib_dirs="" ;;
|
|
esac
|
|
|
|
RPATH_OPT_LIST=
|
|
# only set RPATH_OPT_LIST if the system supports shared libraries
|
|
case $EXT_FOR_SHARED_LIB in so)
|
|
prev=""
|
|
for dir in $user_shlib_dirs $merc_shlib_dirs \
|
|
$system_shlib_dirs 'kludge for broken shells'
|
|
do
|
|
case "$dir" in
|
|
'kludge for broken shells')
|
|
;;
|
|
*)
|
|
case "$prev" in
|
|
"") RPATH_OPT_LIST="$RPATH_OPT$dir" ;;
|
|
*) RPATH_OPT_LIST="$RPATH_OPT_LIST$RPATH_SEP$dir" ;;
|
|
esac
|
|
;;
|
|
esac
|
|
prev=$dir
|
|
done
|
|
;;
|
|
esac
|
|
|
|
|
|
case "$MKFIFO" in
|
|
none) demangle=false ;;
|
|
esac
|
|
|
|
LINKER_PRE_FLAGS="$MSVCRT_OPTS $PRINT_MAP_OPT $UNDEF_OPT $STRIP_OPTS $MAYBE_STATIC_OPT $ARCH_OPTS"
|
|
LINKER_POST_FLAGS="@LINK_OPT_SEP@ $NODEFAULTLIB_FLAG $DEBUG_FLAG $LIBDIR_OPTS $RPATH_OPT_LIST $LIBS"
|
|
|
|
case $verbose in
|
|
true)
|
|
echo "ml: using grade \`$GRADE'"
|
|
case $demangle in
|
|
false)
|
|
echo $LINKER $LINKER_PRE_FLAGS "$@" $LINKER_POST_FLAGS
|
|
;;
|
|
true)
|
|
echo $LINKER $LINKER_PRE_FLAGS "$@" $LINKER_POST_FLAGS "|"
|
|
echo "$DEMANGLER"
|
|
;;
|
|
esac
|
|
;;
|
|
esac
|
|
|
|
case $demangle in
|
|
true)
|
|
# we would like to just run $CC and pipe the result into $DEMANGLER,
|
|
# but `$CC | $DEMANGLER' would return the wrong exit status, so
|
|
# we need to use a named pipe; if the system doesn't have named
|
|
# pipes, then we don't use the demangler
|
|
|
|
# create the pipe, making sure we remove it if interrupted
|
|
old_umask=`umask`
|
|
umask 022
|
|
try=0
|
|
until
|
|
ML_TMPDIR=$TMPDIR/ml$$.$try
|
|
PIPE=$ML_TMPDIR/pipe
|
|
trap 'rmdir $ML_TMPDIR >/dev/null 2>&1; exit 1' 1 2 3 13 15
|
|
mkdir $ML_TMPDIR
|
|
do
|
|
try="`expr $try + 1`"
|
|
# give up after 20 tries
|
|
case "$try" in 20)
|
|
echo "ml: unable to create temporary directory" \
|
|
"for pipe" 1>&2
|
|
exit 1
|
|
esac
|
|
done
|
|
trap 'rm -rf $ML_TMPDIR; exit 1' 1 2 3 13 15
|
|
umask $old_umask
|
|
$MKFIFO $PIPE
|
|
# execute the demangler in the background, with stdin
|
|
# coming from the pipe and with stdout redirected to stderr
|
|
exec $DEMANGLER --explain-link-errors 1>&2 < $PIPE &
|
|
# execute $CC with stdout & stderr redirected to
|
|
# go via the pipe to $DEMANGLER and then to stderr
|
|
case $# in
|
|
0) $LINKER $LINKER_PRE_FLAGS $LINKER_POST_FLAGS >$PIPE 2>&1 ;;
|
|
*) $LINKER $LINKER_PRE_FLAGS "$@" $LINKER_POST_FLAGS \
|
|
>$PIPE 2>&1 ;;
|
|
esac
|
|
linker_status=$?
|
|
# now we can remove the pipe; since is an open file, it will
|
|
# stay around until $DEMANGLER exits
|
|
rm -rf $ML_TMPDIR
|
|
# wait for the demangler to exit before exiting ourselves
|
|
wait
|
|
exit $linker_status
|
|
;;
|
|
false)
|
|
case $# in
|
|
0) exec $LINKER $LINKER_PRE_FLAGS $LINKER_POST_FLAGS ;;
|
|
*) exec $LINKER $LINKER_PRE_FLAGS "$@" $LINKER_POST_FLAGS ;;
|
|
esac
|
|
;;
|
|
esac
|