summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1998-10-14 20:19:30 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1998-10-14 20:19:30 +0000
commit11cfb6f7f6326e79b4a930716c340b65d76d0683 (patch)
tree407c08b76ce570ebc0c5b218aa914a1449808f20 /c/src/lib/libbsp
parentPatch from Ralf Corsepius <corsepiu@faw.uni-ulm.de>: (diff)
downloadrtems-11cfb6f7f6326e79b4a930716c340b65d76d0683.tar.bz2
Patch from Ralf Corsepius <corsepiu@faw.uni-ulm.de>:
1. Rtems contains some perl scripts that use hard-coded paths to /usr/bin/perl or /usr/local/bin/perl I have already fixed these problems by adding some checks to configure.in. While doing this, I also cleaned up some more autoconf related problems for generating shell scripts. This patch might seem a bit scary to you, but I am quite confident it won't break something (I've been testing it for almost a week now, however it might introduce typos for a limited number configurations I don't have access to - But it shouldn't be a problem for you to test them :-). I expect to get this finished tonight, hence you will very likely have the patch when you get up tomorrow. Changes: * Check for PERL and disable all PERL scripts if perl wasn't found. * Generate all KSHELL-scripts with autoconf instead of make-script * Automatic dependency handling for autoconf generated KSHELL or PERL scripts (make/rtems.cfg) Notes: * this patch contains new files and deletes some other files. * The patch is relative to rtems-4.0.0-beta4 with my previous rtems-rc-981014-1.diff patch applied. Testing: I tested it with sh-rtems and posix under linux. Now all targets which are touched by this patch and which are not used while building for sh-rtems and posix still need to be tested. AFAIS, only the sparc/erc32 BSP should be affected by this criterion. And if you like to, you should also consider testing it on a Cygwin32 and a Solaris host for one arbitrary BSP.
Diffstat (limited to 'c/src/lib/libbsp')
-rw-r--r--c/src/lib/libbsp/sparc/erc32/tools/Makefile.in18
-rw-r--r--c/src/lib/libbsp/sparc/erc32/tools/runtest.in307
-rw-r--r--c/src/lib/libbsp/unix/posix/tools/Makefile.in26
-rw-r--r--c/src/lib/libbsp/unix/posix/tools/looptest.in93
-rw-r--r--c/src/lib/libbsp/unix/posix/tools/runtest.in255
-rw-r--r--c/src/lib/libbsp/unix/posix/tools/semdump.in59
-rw-r--r--c/src/lib/libbsp/unix/posix/tools/shmdump.in134
7 files changed, 876 insertions, 16 deletions
diff --git a/c/src/lib/libbsp/sparc/erc32/tools/Makefile.in b/c/src/lib/libbsp/sparc/erc32/tools/Makefile.in
index 97f24fac0a..d6126b1eb8 100644
--- a/c/src/lib/libbsp/sparc/erc32/tools/Makefile.in
+++ b/c/src/lib/libbsp/sparc/erc32/tools/Makefile.in
@@ -10,17 +10,23 @@ PROJECT_ROOT = @PROJECT_ROOT@
include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
include $(RTEMS_ROOT)/make/leaf.cfg
+include $(RTEMS_ROOT)/make/rtems.cfg
DESTDIR=$(PROJECT_RELEASE)/tests
-PGMS=runtest
+BUILD_PGMS = runtest
+PGMS = $(BUILD_PGMS)
-INSTALLED=$(PGMS:%=$(DESTDIR)/%)
+CLEAN_ADDITIONS += $(BUILD_PGMS)
+
+INSTALLED_PGMS=$(PGMS:%=$(DESTDIR)/%)
all: $(DESTDIR) $(PGMS) install
-install: $(INSTALLED)
+$(DESTDIR):
+ @INSTALL@ $(INSTDIRFLAGS) $@
+
+$(INSTALLED_PGMS): $(PGMS)
+ @INSTALL@ $(INSTBINFLAGS) $^ $(DESTDIR)
-# Install the program
-$(DESTDIR)/%: %
- $(make-script)
+install: $(DESTDIR) $(INSTALLED_PGMS)
diff --git a/c/src/lib/libbsp/sparc/erc32/tools/runtest.in b/c/src/lib/libbsp/sparc/erc32/tools/runtest.in
new file mode 100644
index 0000000000..f45517e951
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/erc32/tools/runtest.in
@@ -0,0 +1,307 @@
+#!@KSH@ -p
+#
+# $Id$
+#
+# Run rtems tests on the hppa simulator
+# This program generates a simulator script to run each test
+# Typically the test is then run, although it can be generated
+# and left as a file using -s
+#
+
+# progname=`basename $0`
+progname=${0##*/} # fast basename hack for ksh, bash
+
+USAGE=\
+"usage: $progname [ -opts ] test [ test ... ]
+ -o options -- specify options to be passed to simulator
+ -v -- verbose
+ -s -- generate script file (as 'test'.ss) and exit
+ -l logdir -- specify log directory (default is 'logdir')
+
+ Specify test as 'test' or 'test.exe'.
+ All multiprocessing tests *must* be specified simply as 'mp01', etc.
+"
+
+# export everything
+set -a
+
+# log an error to stderr
+prerr()
+{
+ echo "$*" >&2
+}
+
+fatal() {
+ [ "$1" ] && prerr $*
+ prerr "$USAGE"
+ exit 1
+}
+
+warn() {
+ [ "$1" ] && prerr $*
+}
+
+# print args, 1 per line
+ml_echo()
+{
+ for l
+ do
+ echo "$l"
+ done
+}
+
+# run at normal and signalled exit
+test_exit()
+{
+ exit_code=$1
+
+ rm -f ${statfile}* ${scriptfile}* ${logfile}.tmp*
+ [ "$sim_pid" ] && kill -9 $sim_pid
+
+ exit $exit_code
+}
+
+#
+# process the options
+#
+# defaults for getopt vars
+#
+# max_run_time is defaulted to 5 minutes
+#
+
+verbose=""
+extra_options=""
+script_and_exit=""
+stdio_setup="yes"
+run_to_completion="yes"
+logdir=log
+update_on_tick="no"
+max_run_time=$((5 * 60))
+using_print_buffer="yes"
+
+while getopts vhr12o:c:sl:t OPT
+do
+ case "$OPT" in
+ v)
+ verbose="yes";;
+ s)
+ script_and_exit="yes"
+ run_to_completion="no"
+ stdio_setup="no";;
+ l)
+ logdir="$OPTARG";;
+ o)
+ extra_options="$OPTARG";;
+ *)
+ fatal;;
+ esac
+done
+
+let $((shiftcount = $OPTIND - 1))
+shift $shiftcount
+
+args=$*
+
+#
+# Run the tests
+#
+
+tests="$args"
+if [ ! "$tests" ]
+then
+ set -- `echo *.exe`
+ tests="$*"
+fi
+
+[ -d $logdir ] ||
+ mkdir $logdir || fatal "could not create log directory ($logdir)"
+
+cpus=1
+
+# where the tmp files go
+statfile=/tmp/stats$$
+scriptfile=/tmp/script$$
+
+trap "test_exit" 1 2 3 13 14 15
+
+for tfile in $tests
+do
+
+ tname=`basename $tfile .exe`
+ TEST_TYPE="single"
+
+ case $tname in
+ monitor)
+ if [ $run_to_completion = "yes" ]
+ then
+ warn "Skipping $tname; it is interactive"
+ continue
+ fi
+ ;;
+ *-node2*)
+ fatal "MP tests not supported"
+ warn "Skipping $tname; 'runtest' runs both nodes when for *-node1"
+ continue;;
+ *-node1*)
+ fatal "MP tests not supported"
+ warn "Running both nodes associated with $tname"
+ tname=`echo $tname | sed 's/-node.*//'`
+ TEST_TYPE="mp"
+ ;;
+ stackchk*|spfatal*|malloctest*|termio*)
+ warn "Skipping $tname; it locks up or takes a VERY long time to run"
+ continue
+ ;;
+ esac
+
+ # Change the title bar to indicate which test we are running
+ # The simulator screen doesn't provide any indication
+
+ logfile=$logdir/$tname
+ infofile=$logfile.info
+
+ rm -f ${statfile}* ${scriptfile}* ${logfile}.tmp*
+
+ date=`date`
+ echo "Starting $tname at $date"
+
+ # Generate a script file to get the work done.
+ # The script file must do the following:
+ #
+ # load the program (programs if MP test)
+ # arrange for capture of output
+ # run the program
+ # produce statistics
+
+ {
+ case $TEST_TYPE in
+ "mp")
+ fatal "MP tests not supported"
+ ;;
+
+ # All other tests (single-processor)
+ *)
+ echo "load $tfile"
+ echo "go 0x02000000"
+ echo "perf"
+ echo "quit"
+ ;;
+ esac
+
+ } > ${scriptfile}
+
+ if [ "$script_and_exit" = "yes" ]
+ then
+ mv ${scriptfile} $tname.ss
+ warn "script left in $tname.ss"
+ test_exit 0
+ fi
+
+ # Spin off the simulator in the background
+ sparc-rtems-sis $extra_options -c ${scriptfile} >${logfile}.tmp &
+ sim_pid=$!
+
+ # Make sure it won't run forever...
+ {
+ time_run=0
+ while [ $time_run -lt $max_run_time ]
+ do
+ # sleep 10s at a time waiting for job to finish or timer to expire
+ # if job has exited, then we exit, too.
+ sleep 10
+ if kill -0 $sim_pid 2>/dev/null
+ then
+ time_run=$((time_run + 10))
+ else
+ exit 0
+ fi
+ done
+
+ kill -2 $sim_pid 2>/dev/null
+ { sleep 5; kill -9 $sim_pid 2>/dev/null; } &
+ } &
+
+ wait $sim_pid
+ status=$?
+ if [ $status -ne 0 ]
+ then
+ ran_too_long="yes"
+ else
+ ran_too_long="no"
+ fi
+
+ sim_pid=""
+
+ # fix up the printf output from the test
+ case $TEST_TYPE in
+ mp)
+ fatal "MP not supported"
+ ;;
+ *)
+ output_it=1
+ sed -e '1,12d' \
+ -e 's/ //' -e '/^$/d' < ${logfile}.tmp |
+ while read line
+ do
+ if [ $output_it -eq 1 ] ; then
+ if [ "$line" = "sis> perf" ] ; then
+ output_it=0
+ else
+ echo "$line"
+ fi
+ fi
+ done > ${logfile}_1
+ ;;
+ esac
+
+ # Create the info files
+ for cpu in $cpus
+ do
+ {
+ echo "$date"
+ echo "Test run on: `uname -n` ( `uname -a` )"
+
+ output_it=0
+ sed -e 's/ //' < ${logfile}.tmp |
+ while read line
+ do
+ if [ $output_it -eq 1 ] ; then
+ if [ "$line" = "sis> quit" ] ; then
+ output_it=0
+ else
+ echo "$line"
+ fi
+ else
+ if [ "$line" = "sis> perf" ] ; then
+ output_it=1
+ fi
+ fi
+ done
+
+
+ if [ "$ran_too_long" = "yes" ]
+ then
+ echo "Test did NOT finish normally; killed after $max_run_time seconds"
+ fi
+
+ echo
+ date;
+ } > ${infofile}_$cpu
+ done
+
+ rm -f ${logfile}.tmp*
+
+ if [ "$cpus" = "1" ]
+ then
+ mv ${infofile}_1 ${infofile}
+ mv ${logfile}_1 ${logfile}
+ fi
+
+done
+
+test_exit 0
+
+# Local Variables: ***
+# mode:ksh ***
+# End: ***
+
diff --git a/c/src/lib/libbsp/unix/posix/tools/Makefile.in b/c/src/lib/libbsp/unix/posix/tools/Makefile.in
index 0fd219ab05..f455ef46d4 100644
--- a/c/src/lib/libbsp/unix/posix/tools/Makefile.in
+++ b/c/src/lib/libbsp/unix/posix/tools/Makefile.in
@@ -10,22 +10,28 @@ PROJECT_ROOT = @PROJECT_ROOT@
include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
include $(RTEMS_ROOT)/make/leaf.cfg
+include $(RTEMS_ROOT)/make/rtems.cfg
DESTDIR=$(PROJECT_RELEASE)/tests
# We use the generic difftest
-PGMS=runtest looptest semdump shmdump
+BUILD_PGMS=runtest looptest
+ifneq (@PERL@,)
+BUILD_PGMS+=semdump shmdump
+endif
-INSTALLED=$(PGMS:%=$(DESTDIR)/%)
+PGMS = $(BUILD_PGMS)
+
+CLEAN_ADDITIONS += $(BUILD_PGMS)
+
+INSTALLED_PGMS=$(PGMS:%=$(DESTDIR)/%)
all: $(DESTDIR) $(PGMS) install
-install: $(INSTALLED)
+$(DESTDIR):
+ @INSTALL@ $(INSTDIRFLAGS) $@
+
+$(INSTALLED_PGMS): $(PGMS)
+ @INSTALL@ $(INSTBINFLAGS) $^ $(DESTDIR)
-# Install the program, replacing #!KSHELL with $(KSH)
-# and first line #!SHELL with $(SHELL)
-$(DESTDIR)/%: %
- -$(RM) $@.old
- -$(MV) $@ $@.old >/dev/null 2>&1
- $(SED) -e '1,1s?^#!KSHELL?#!$(KSH)?' -e '1,1s?^#!SHELL?#!$(SHELL)?' < $< > $@
- $(CHMOD) 0555 $@
+install: $(DESTDIR) $(INSTALLED_PGMS)
diff --git a/c/src/lib/libbsp/unix/posix/tools/looptest.in b/c/src/lib/libbsp/unix/posix/tools/looptest.in
new file mode 100644
index 0000000000..0f6965fe2b
--- /dev/null
+++ b/c/src/lib/libbsp/unix/posix/tools/looptest.in
@@ -0,0 +1,93 @@
+#!@KSH@ -p
+#
+# $Id$
+#
+
+# progname=`basename $0`
+progname=${0##*/} # fast basename hack for ksh, bash
+
+# must be uppercase hex; dc is feeble minded
+clicks_per_tick="1"
+# default is 0x3
+hexbump=1
+iterations=10
+
+USAGE=\
+"usage: $progname [ -opts ] file [ file ... ]
+ -o options -- specify options to be passed to runtest
+ -c clicks -- specify (hex) value for clicks / tick (default $clicks_per_tick)
+ -n iterations -- num times to loop thru specified tests (default $iterations)
+ -b hexbump -- increment clicks-per-ticks this much each loop (default $hexbump)
+ -v -- verbose"
+
+# log an error to stderr
+prerr()
+{
+ echo "$*" >&2
+}
+
+fatal() {
+ [ "$1" ] && prerr $*
+ prerr "$USAGE"
+ exit 1
+}
+
+warn() {
+ [ "$1" ] && prerr $*
+}
+
+#
+# process the options
+#
+# defaults for getopt vars
+#
+
+verbose=""
+extra_options=""
+
+while getopts vo:c:n:b: OPT
+do
+ case "$OPT" in
+ v)
+ verbose="yes";;
+ o)
+ extra_options="$OPTARG";;
+ c)
+ clicks_per_ticks="$OPTARG";;
+ n)
+ iterations="$OPTARG";;
+ b)
+ hexbump="$OPTARG";;
+ *)
+ fatal;;
+ esac
+done
+((shiftcount = $OPTIND - 1))
+shift $shiftcount
+
+args=$*
+
+#
+# Run the tests
+# After each run, rename 'log' to log.$clicks_per_tick
+#
+
+tests="$args"
+
+while [ $iterations -gt 0 ]
+do
+ ./runtest $extra_options -c $clicks_per_tick $tests
+ rm -rf log.$clicks_per_tick.OLD
+ [ -d log.$clicks_per_tick ] && mv log.$clicks_per_tick log.$clicks_per_tick.OLD
+ mv log log.$clicks_per_tick
+
+ ((iterations = $iterations - 1))
+ clicks_per_tick=`echo 16 o 16 i $clicks_per_tick $hexbump + p q | dc`
+done
+
+exit 0
+
+# Local Variables: ***
+# mode:ksh ***
+# End: ***
+
diff --git a/c/src/lib/libbsp/unix/posix/tools/runtest.in b/c/src/lib/libbsp/unix/posix/tools/runtest.in
new file mode 100644
index 0000000000..2d08f2f033
--- /dev/null
+++ b/c/src/lib/libbsp/unix/posix/tools/runtest.in
@@ -0,0 +1,255 @@
+#!@KSH@ -p
+#
+# Run rtems tests on a POSIX-ish UNIX
+#
+# $Id$
+#
+
+trap "test_exit 1" 1 2 3 13 14 15
+
+trap "test_exit 1" 1 2 3 13 14 15
+
+# progname=`basename $0`
+progname=${0##*/} # fast basename hack for ksh, bash
+
+USAGE=\
+"usage: $progname [ -opts ] test [ test ... ]
+ -c clicks -- specify (hex) value for clicks / tick
+ -v -- verbose
+ -l logdir -- specify log directory (default is 'logdir')
+
+ Specify test as 'test' or 'test.exe'.
+ All multiprocessing tests *must* be specified simply as 'mp01', etc.
+"
+
+# export everything
+set -a
+
+# log an error to stderr
+prerr()
+{
+ echo "$*" >&2
+}
+
+fatal() {
+ [ "$1" ] && prerr $*
+ prerr "$USAGE"
+ exit 1
+}
+
+warn() {
+ [ "$1" ] && prerr $*
+}
+
+# print args, 1 per line
+ml_echo()
+{
+ for l
+ do
+ echo "$l"
+ done
+}
+
+killem()
+{
+ kill -9 $pid $pid1 $pid2 2> /dev/null
+}
+
+
+killem()
+{
+ kill -9 $pid $pid1 $pid2 2> /dev/null
+}
+
+
+test_exit()
+{
+ exit_code=$1
+
+ killem
+
+ killem
+
+ rm -f ${logfile}.tmp*
+
+ exit $exit_code
+}
+
+#
+# process the options
+#
+# defaults for getopt vars
+#
+
+verbose=""
+extra_options=""
+clicks_per_tick=""
+logdir=log
+# how long can we run; rtems tests might run 300 seconds
+max_run_time=400
+run_to_completion="yes"
+
+while getopts vo:c:l: OPT
+do
+ case "$OPT" in
+ v)
+ verbose="yes";;
+ l)
+ logdir="$OPTARG";;
+ o)
+ extra_options="$OPTARG";;
+ c)
+ clicks_per_tick="$OPTARG";;
+ *)
+ fatal;;
+ esac
+done
+
+let $((shiftcount = $OPTIND - 1))
+shift $shiftcount
+
+args=$*
+
+#
+# Run the tests
+#
+
+tests="$args"
+if [ ! "$tests" ]
+then
+ set -- `echo *.exe`
+ tests="$*"
+fi
+
+[ -d $logdir ] || mkdir $logdir || fatal "could not create log directory ($logdir)"
+
+for tfile in $tests
+do
+
+ tname=`echo $tfile | sed -e 's/\.exe$//'`
+ tname=`basename $tname`
+
+ TEST_TYPE="single"
+
+ case $tname in
+ monitor)
+ if [ $run_to_completion = "yes" ]
+ then
+ warn "Skipping $tname; it is interactive"
+ continue
+ fi
+ ;;
+ *-node2*)
+ warn "Skipping $tname; 'runtest' runs both nodes when for *-node1"
+ continue;;
+ *-node1*)
+ tname=`echo $tname | sed 's/-node.*//'`
+ warn "Running both nodes associated with $tname"
+ TEST_TYPE="mp"
+ ;;
+ stackchk*|spfatal*|malloctest*|termio*)
+ warn "Skipping $tname; it locks up or takes a VERY long time to run"
+ continue
+ ;;
+ esac
+
+ if [ $TEST_TYPE = "mp" ]
+ then
+ logfile1=$logdir/${tname}_1
+ infofile1=$logfile1.info
+ logfile2=$logdir/${tname}_2
+ infofile2=$logfile2.info
+
+ rm -f ${logfile1}
+ rm -f ${logfile2}
+
+ date=`date`
+ echo "Starting $tname at $date"
+
+ ./${tname}-node1.exe > $logfile1 2>&1 &
+ pid1=$!
+ ./${tname}-node2.exe > $logfile2 2>&1 &
+ pid2=$!
+
+ # Wait for both cpu's to complete, ensuring they don't run forever...
+ time_run=0
+ while [ $time_run -lt $max_run_time ]
+ do
+ # sleep 5s at a time waiting for jobs to finish or timer to expire
+ # if job has exited, then we exit, too.
+ sleep 5
+ kill -0 $pid1 2> /dev/null
+ running1=$?
+ kill -0 $pid2 2> /dev/null
+ running2=$?
+ if [ $running1 -eq 0 ] && [ $running2 -eq 0 ] # both still running
+ then
+ time_run=$((time_run + 5))
+ if [ $time_run -ge $max_run_time ]
+ then
+ echo "$tname ran too long; killing it"
+ ran_too_long="yes"
+ fi
+ else
+ ran_too_long="no"
+ # if one is still running, have to kill them
+ if [ $running1 -ne $running2 ]
+ then
+ sleep 10 # give other node a chance to gracefully die
+ fi
+ break
+ fi
+ done
+
+ # make sure they are gone
+ kill -9 $pid1 2> /dev/null
+ kill -9 $pid2 2> /dev/null
+ fi
+
+ if [ $TEST_TYPE = "single" ]
+ then
+ logfile=$logdir/$tname
+ infofile=$logfile.info
+
+ rm -f ${logfile}
+
+ date=`date`
+ echo "Starting $tname.exe at $date"
+
+ ./$tname.exe > $logfile 2>&1 &
+ pid=$!
+
+ # Make sure it won't run forever...
+ time_run=0
+ while [ $time_run -lt $max_run_time ]
+ do
+ # sleep 5s at a time waiting for job to finish or timer to expire
+ # if job has exited, then we exit, too.
+ sleep 5
+ kill -0 $pid 2> /dev/null
+ running=$?
+ if [ $running -eq 0 ]
+ then
+ time_run=$((time_run + 5))
+ if [ $time_run -ge $max_run_time ]
+ then
+ kill -9 $pid 2> /dev/null
+ ran_too_long="yes"
+ fi
+ else
+ ran_too_long="no"
+ break
+ fi
+ done
+ fi
+
+ pid=""
+
+done
+
+test_exit 0
+
+# Local Variables: ***
+# mode:ksh ***
+# End: ***
+
diff --git a/c/src/lib/libbsp/unix/posix/tools/semdump.in b/c/src/lib/libbsp/unix/posix/tools/semdump.in
new file mode 100644
index 0000000000..53710a629e
--- /dev/null
+++ b/c/src/lib/libbsp/unix/posix/tools/semdump.in
@@ -0,0 +1,59 @@
+#!@PERL@
+#
+# $Id$
+#
+eval "exec @PERL@ -S $0 $*"
+ if $running_under_some_shell;
+
+# dump semaphore array values tony@divnc.com
+
+require 'sys/sem.ph';
+require 'getopts.pl';
+&Getopts("vhi:k:"); # verbose, help, id, key
+
+if ($opt_h || ($opt_i && $opt_k))
+{
+ print STDERR <<NO_MORE_HELP;
+semdump
+
+ Dump info about specified semaphore.
+
+Usage: $0 [-v] { -i semid | -k semkey }
+
+ -v -- possibly more verbose
+ -i semid -- semaphore id
+ -k semkey -- semaphore key
+ -h -- help
+
+ anything else == this help message
+NO_MORE_HELP
+ exit 1;
+}
+
+$verbose = $opt_v;
+$id = $opt_i;
+$key = $opt_k;
+
+if ($key)
+{
+ $key = oct($key) if $key =~ /^0/;
+ die "Could not convert key to id; $!" unless $id = semget($key, 1, 0);
+}
+
+# I don't know to find out how many sem's are attached to the id
+# so just keep reading them until we get an error.
+
+printf("KEY: 0x%X (%d) ", $key, $key) if $key;
+print "ID: $id\n";
+
+semlist:
+for ($semnum=0; $semnum < 10; $semnum++)
+{
+ $val = semctl($id, $semnum, &GETVAL, 0);
+ $val || ($val = -1);
+
+ last semlist if ($val == -1);
+
+ printf " %d: %d\n", $semnum, $val;
+}
+
diff --git a/c/src/lib/libbsp/unix/posix/tools/shmdump.in b/c/src/lib/libbsp/unix/posix/tools/shmdump.in
new file mode 100644
index 0000000000..fa965702ca
--- /dev/null
+++ b/c/src/lib/libbsp/unix/posix/tools/shmdump.in
@@ -0,0 +1,134 @@
+#!@PERL@
+#
+# $Id$
+#
+eval "exec @PERL@ -S $0 $*"
+ if $running_under_some_shell;
+
+# dump shared memory segment tony@divnc.com
+
+require 'sys/shm.ph';
+require 'getopts.pl';
+&Getopts("vhi:k:f:l:b:w"); # verbose, help, id, key, first, length, word, base
+
+if ($opt_h || ($opt_i && $opt_k))
+{
+ print STDERR <<NO_MORE_HELP;
+shmdump
+
+ Dump contents of specifed shared memory segment.
+
+Usage: $0 [options]
+
+ -h -- help
+ -v -- possibly more verbose
+ -i shmid -- shm id
+ -k shmkey -- shm key
+ -f first -- start of partial dump
+ -l length -- length of partial dump
+ -w -- dump as 4byte words instead of bytes
+ -b base -- use 'base' as base address for output
+
+ anything else == this help message
+NO_MORE_HELP
+ exit 1;
+}
+
+$verbose = $opt_v;
+$id = $opt_i;
+$key = $opt_k;
+$offset = $opt_f;
+$print_length = $opt_l;
+$base = $opt_b;
+$word_dump = $opt_w;
+
+if ($key)
+{
+ # ensure key is an integer
+ $key = oct($key) if $key =~ /^0/;
+ die "Could not convert key to id; $!" unless $id = shmget($key, 1, 0);
+}
+
+# ensure integerhood in case of leading '0x'
+$base = oct($base) if $base =~ /^0/;
+$offset = oct($offset) if $offset =~ /^0/;
+$print_length = oct($print_length) if $print_length =~ /^0/;
+
+if ( ! shmctl($id, &IPC_STAT, $shmid_ds))
+{
+ die "shmctl(2) for id $id failed -- (I was trying to get size): $!";
+}
+
+# Pick the length out.
+# It is at byte offset 0x30 on hpux9 and probably hpux10
+# Also get the key if we don't have it already. Don't need it tho...
+$length = unpack("I", substr($shmid_ds, 0x30, 4));
+$key = unpack("I", substr($shmid_ds, 0x14, 4)) if ! $key;
+
+# poke around looking for length and key
+# print "I guess: length: $length, key: $key\n";
+# print "****$shmid_ds****\n"; die "";
+
+# make sure offset and print length make sense
+$print_length = $length if ! $print_length;
+if (($offset + $print_length) > $length)
+{
+ die "offset ($offset) and length ($print_length) go beyond end of segment ($length bytes)";
+}
+
+printf("KEY: 0x%X (%d) ", $key, $key) if ($key);
+printf "ID: $id\n";
+printf " %d bytes (0x%X), %d words, logical base is 0x%X\n",
+ $length, $length, $length / 4, $base;
+if ($offset || ($print_length != $length))
+{
+ printf " printing %X (%d) bytes starting at offset 0x%X (%d)\n",
+ $print_length, $print_length, $offset, $offset;
+}
+printf "\n";
+
+if ( ! shmread($id, $shm_data, $offset, $print_length))
+{
+ die "could not attach and read from shmid $id: $!";
+}
+
+# the dump code below derived from "Real Perl Programs" example "xdump"
+# from Camel book
+
+$base += $offset;
+$offset = 0;
+for ($len = $print_length; $len >= 16; )
+{
+ $data = substr($shm_data, $offset, 16);
+
+ @array = unpack('N4', $data);
+ $data =~ tr/\0-\37\177-\377/./;
+ printf "%8.8lX %8.8lX %8.8lX %8.8lX %8.8lX |%s|\n",
+ $base, @array, $data;
+
+ $offset += 16;
+ $base += 16;
+ $len -= 16;
+}
+
+# Now finish up the end a byte at a time
+
+if ($len)
+{
+ $data = substr($shm_data, $offset, $len);
+ @array = unpack('C*', $data);
+ for (@array)
+ {
+ $_ = sprintf('%2.2X', $_);
+ }
+
+ push(@array, ' ') while $len++ < 16;
+
+ $data =~ tr/\0-\37\177-\377/./;
+ $data =~ s/[^ -~]/./g;
+
+ printf "%8.8lX ", $base;
+ printf "%s%s%s%s %s%s%s%s %s%s%s%s %s%s%s%s |%-16s|\n",
+ @array, $data;
+}
+