Files
mercury/scripts/ml.in
Zoltan Somogyi 9ec86d6a6d The objective of this diff is to switch from a table of solver events built
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.
2006-11-24 03:48:30 +00:00

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