Blob Blame History Raw
diff --git a/frysk-common/ChangeLog b/frysk-common/ChangeLog
index 8d1b606..10dc607 100644
--- a/frysk-common/ChangeLog
+++ b/frysk-common/ChangeLog
@@ -1,3 +1,26 @@
+2008-06-20  Andrew Cagney  <cagney@redhat.com>
+
+	* Makefile.rules (lib$(GEN_DIRNAME)-jni.so): Replace less explicit
+	%-jni.so target.
+	
+	* Makefile.rules (Runner): Delete LD_PRELOAD hack.
+
+2008-06-19  Andrew Cagney  <cagney@redhat.com>
+
+	* Makefile.gen.sh (jni): Delete.
+	* Makefile.rules (%-jni.so): Depend on $(JNI_ARCHIVE_LIST) and
+	$(JNI_OBJECT_LIST).
+	(jni): New phony target.
+	
+	* Makefile.rules (JNI_OBJECT_LIST): Define.
+	(JNI_LIBRARY_LIST): Define.
+	(JNI_ARCHIVE_LIST): Define.
+	(%-jni.so: %-jni.a): New rule.
+
+2008-06-17  Andrew Cagney  <cagney@redhat.com>
+
+	* Makefile.rules (Runner): Load libaudit.so.
+
 2008-06-09  Andrew Cagney  <cagney@redhat.com>
 
 	* Makefile.rules (Runner): (Really) Let JAVA be overwritten by an
diff --git a/frysk-common/Makefile.gen.sh b/frysk-common/Makefile.gen.sh
index a9dc667..6e7c3ab 100755
--- a/frysk-common/Makefile.gen.sh
+++ b/frysk-common/Makefile.gen.sh
@@ -895,8 +895,7 @@ noinst_LIBRARIES += lib${GEN_DIRNAME}-jni.a
 lib${GEN_MAKENAME}_jni_so_SOURCES =
 solib_PROGRAMS += lib${GEN_DIRNAME}-jni.so
 lib${GEN_DIRNAME}-jni.so: lib${GEN_DIRNAME}-jni.a
-.PHONY: jni
-jni: lib${GEN_DIRNAME}-jni.so ${GEN_DIRNAME}.jar
+jni: lib${GEN_DIRNAME}-jni.so
 lib${GEN_MAKENAME}_jni_a_SOURCES += jni.cxx
 jnixx_sources = \$(wildcard \$(root_srcdir)/frysk-sys/jnixx/*.java)
 CLEANFILES += jni.hxx jni.cxx jni.hxx.gch
diff --git a/frysk-common/Makefile.rules b/frysk-common/Makefile.rules
index 7f30cd3..c80b81c 100644
--- a/frysk-common/Makefile.rules
+++ b/frysk-common/Makefile.rules
@@ -94,6 +94,7 @@ GEN_CLASSPATH =
 GEN_SOURCEPATH = $(srcdir) $(top_builddir)
 empty=
 space=$(empty) $(empty)
+comma=$(empty),$(empty)
 JAVAROOT = classes
 
 # The list of libraries for the GCJ programs is different to that of
@@ -189,6 +190,10 @@ AM_CCASFLAGS = \
 	$(ZZZ)
 
 
+# Just build the jar / jni dependencies files.
+.PHONY: jni
+jni: ${GEN_DIRNAME}.jar
+
 # Within the BUILT_SOURCES, need to force some dependencies.  For
 # instance: JAVAH isn't run until all script-generated files it may
 # need to import have been generated.
@@ -395,20 +400,8 @@ Runner:
 	echo ""	     						>> $@.tmp
 	echo "# some pre-definitions"				>> $@.tmp
 	echo "elfutils=$(frysk_imports)/elfutils"		>> $@.tmp
-	echo "libunwind=$(frysk_imports)/libunwind"		>> $@.tmp
 	echo "java=\"$(JAVA) $(GEN_GCJ_NO_SIGCHLD_FLAGS)\""	>> $@.tmp
 	echo ""	     						>> $@.tmp
-	echo "# Hack to pull in JNI dependences"		>> $@.tmp
-	echo "export LD_PRELOAD=\\" 				>> $@.tmp
-	echo "\$${elfutils}/libelf/libelf.so\\ \\"		>> $@.tmp
-	echo "\$${elfutils}/libdw/libdw.so\\ \\"		>> $@.tmp
-	echo "\$${elfutils}/libasm/libasm.so\\ \\"		>> $@.tmp
-	echo "\$${libunwind}-i386/src/.libs/libunwind-x86.so\\ \\" >> $@.tmp
-	echo "\$${libunwind}-ppc32/src/.libs/libunwind-ppc32.so\\ \\" >> $@.tmp
-	echo "\$${libunwind}-ppc64/src/.libs/libunwind-ppc64.so\\ \\" >> $@.tmp
-	echo "\$${libunwind}-x86_64/src/.libs/libunwind-x86_64.so\\ \\" >> $@.tmp
-	echo "libstdc++.so.6"					>> $@.tmp
-	echo ""	     						>> $@.tmp
 	echo "# hack to hopefully find the right libstdc++.so"  >> $@.tmp
 	echo "export LD_LIBRARY_PATH=$(frysk_sys)\\"		>> $@.tmp
 	echo ":\$${elfutils}/backends\\"			>> $@.tmp
@@ -464,6 +457,36 @@ SUFFIXES += .so
 		-Wl,--soname,$$soname,-z,-defs
 	if readelf -d $@.tmp | fgrep -q TEXTREL; then exit 1; fi
 	mv $@.tmp $@
+
+# Build a JNI shared object from one or more archives and one or more
+# object files.  This lets frysk bundle up into a single somewhat
+# large shared object, all the native code it needs to drag around.
+# Over time it should become smaller.
+
+# A list of .a files that should be incorporated into the .so.
+JNI_ARCHIVE_LIST =
+
+# List of shared objects required by this code.  The link-loader will
+# automatically pull these in as part of the build.
+JNI_LIBRARY_LIST =
+
+# A list of extra object files that should be added to the .so.
+JNI_OBJECT_LIST =
+
+lib$(GEN_DIRNAME)-jni.so: $(JNI_ARCHIVE_LIST) $(JNI_OBJECT_LIST)
+lib$(GEN_DIRNAME)-jni.so: lib$(GEN_DIRNAME)-jni.a
+	soname=`basename $@` ; \
+	$(CC) -shared -o $@.tmp \
+		-Wl,--whole-archive \
+		-Wl,$< \
+		$(JNI_ARCHIVE_LIST:%=-Wl,%) \
+		-Wl,--no-whole-archive \
+		-Wl,--soname,$$soname,-z,-defs \
+		$(JNI_OBJECT_LIST) \
+		$(JNI_LIBRARY_LIST)
+	if readelf -d $@.tmp | fgrep TEXTREL; then exit 1; fi
+	mv $@.tmp $@
+
 
 # Clueless automake: Use a phony DATA entry to convince AUTOMAKE that
 # it really should install a .so file into LIBDIR.  The obvious
diff --git a/frysk-common/version.in b/frysk-common/version.in
index bd73f47..6aed7c3 100644
--- a/frysk-common/version.in
+++ b/frysk-common/version.in
@@ -1 +1 @@
-0.4
+0.4.50
diff --git a/frysk-core/frysk/bindir/ChangeLog b/frysk-core/frysk/bindir/ChangeLog
index 0429ed3..1097433 100644
--- a/frysk-core/frysk/bindir/ChangeLog
+++ b/frysk-core/frysk/bindir/ChangeLog
@@ -1,3 +1,30 @@
+2008-06-12  Andrew Cagney  <cagney@redhat.com>
+
+	* TestFexe.java (testExeOfDeletedFile()): Enable.  Match expected
+	error.
+	* fexe.java: Use Exe.getName.
+
+	* TestFexe.java (testExeOfDeletedFile()): New; mark as unresolved
+	6621.
+
+2008-06-13  Petr Machata  <pmachata@redhat.com>
+
+	* ftrace.xml-in: Update.
+
+2008-06-10  Andrew Cagney  <cagney@redhat.com>
+
+	* TestFstack.java (testBackTraceWithFullPath): Specify "paths",
+	not "full-path".
+	
+	* TestFstack.java (testBackTrace)
+	(testBackTraceWithDebugNamesAndParams): Check for from <exe>.
+	* TestFstack.java (testBackTraceWithRich()): Mark as unresolved;
+	bug 6616.
+	* ferror.java: Use PrintDebugInfoStackOptions; don't specify the
+	default stack options.
+	* ftrace.java: Ditto.
+	* fstack.java: Ditto.
+
 2008-06-04  Sami Wagiaalla  <swagiaal@redhat.com>
 
 	* TestFstep.java: Marked tests are unresolved.
diff --git a/frysk-core/frysk/bindir/TestFexe.java b/frysk-core/frysk/bindir/TestFexe.java
index 6f79c80..5a37447 100644
--- a/frysk-core/frysk/bindir/TestFexe.java
+++ b/frysk-core/frysk/bindir/TestFexe.java
@@ -39,6 +39,7 @@
 
 package frysk.bindir;
 
+import frysk.testbed.TearDownFile;
 import frysk.testbed.TearDownExpect;
 import frysk.testbed.TestLib;
 import frysk.config.Prefix;
@@ -87,4 +88,27 @@ public class TestFexe extends TestLib {
 	e.expect("/bin/bash" + "\r\n");
     }
 
+    public void testExeOfDeletedFile() {
+	TearDownExpect e = new TearDownExpect();
+	TearDownFile exe = TearDownFile.create();
+	// Create a copy of sleep that is executable.
+	e.send("cp /bin/sleep " + exe.getPath() + "\r");
+	e.expect("cp .*\\$ ");
+	e.send("chmod +x " + exe.getPath() + "\r");
+	e.expect("chmod .*\\$ ");
+	// Start sleep running; pid is in $!, save it.
+	e.send(exe.getAbsolutePath() + " 1000 &\r");
+	e.send("pid=$! ; echo pid=$pid\r");
+	e.expect("pid=[0-9]+\r\n\\$ ");
+	// Try fexe with the executable present.
+	e.send(Prefix.binFile("fexe").getPath() + " $pid\r");
+	e.expect(exe.getName() + "\r\n\\$ ");
+	// Delete the executable
+	e.send("rm -f " + exe.getPath() + "\r");
+	e.expect("\\$ ");
+	assertFalse("file exists", exe.stillExists());
+	// Try fexe with the executable deleted
+	e.send(Prefix.binFile("fexe").getPath() + " $pid\r");
+	e.expect("The link /proc/[0-9]+/exe points to the deleted file .*" + exe.getName() + "\\r\n\\$ ");
+    }
 }
diff --git a/frysk-core/frysk/bindir/TestFstack.java b/frysk-core/frysk/bindir/TestFstack.java
index aafeb66..952f12d 100644
--- a/frysk-core/frysk/bindir/TestFstack.java
+++ b/frysk-core/frysk/bindir/TestFstack.java
@@ -83,20 +83,20 @@ public class TestFstack extends TestLib {
     public void testBackTrace () {
 	TearDownExpect e = fstack("funit-stack-outlined", new String[0]);
 	// Just look for main.
-	e.expect ("main");
+	e.expect ("main.* from funit-stack-outlined");
     }
     
     public void testBackTraceWithDebugNamesAndParams() {
 	TearDownExpect e = fstack("funit-stack-outlined", new String[] {
 		"-print", "debug-names,params"
 	    });
-	e.expect("\\#0 .* in third\\(int arg3\\) .*\\/funit-stack-outlined\\.c#");
+	e.expect("\\#0 .* in third\\(int arg3\\) at funit-stack-outlined\\.c#[0-9]+ from funit-stack-outlined");
 	e.expect("\\#1");
     }
 
-    public void testBackTraceWithFullPath () {
+    public void testBackTraceWithFullPath() {
 	TearDownExpect e = fstack("funit-stack-outlined", new String[] {
-		"-rich", "-print", "full-path"
+		"-rich", "-print", "paths"
 	    });
         e.expect (getCanonicalRootSrcDir()
 		  + ".*"
@@ -136,11 +136,13 @@ public class TestFstack extends TestLib {
     }
 
     public void testBackTraceWithRich() {
+	if (unresolved(6616))
+	    return;
 	TearDownExpect e = fstack("funit-stack-inlined",
 				  new String[] { "-rich" });
-        e.expect("\\#0 .* third\\(int arg3.*\\)");
-        e.expect("\\#1 .* second\\(int arg2.*\\)");
-        e.expect("\\#2 .* first\\(int arg1.*\\)");
+        e.expect("\\#0 .* third\\(int arg3\\)");
+        e.expect("\\#1 .* second\\(int arg2\\)");
+        e.expect("\\#2 .* first\\(int arg1\\)");
         e.expect("\\#3 .* main\\(\\)");
     }
 
diff --git a/frysk-core/frysk/bindir/ferror.java b/frysk-core/frysk/bindir/ferror.java
index ed0cbdb..3592edd 100644
--- a/frysk-core/frysk/bindir/ferror.java
+++ b/frysk-core/frysk/bindir/ferror.java
@@ -43,7 +43,7 @@ import java.io.PrintWriter;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import frysk.debuginfo.PrintStackOptions;
+import frysk.debuginfo.PrintDebugInfoStackOptions;
 import frysk.isa.syscalls.Syscall;
 import frysk.proc.Action;
 import frysk.proc.Task;
@@ -58,8 +58,8 @@ import gnu.classpath.tools.getopt.OptionGroup;
 
 public class ferror {
     
-    private static final PrintStackOptions stackPrintOptions
-	= new PrintStackOptions().setRich();
+    private static final PrintDebugInfoStackOptions stackPrintOptions
+	= new PrintDebugInfoStackOptions();
     private static final PrintWriter printWriter = new PrintWriter(System.out);
     private static Pattern writePattern;
     private static OptionGroup[] options() {
diff --git a/frysk-core/frysk/bindir/fexe.java b/frysk-core/frysk/bindir/fexe.java
index 2bcb374..e6a0600 100644
--- a/frysk-core/frysk/bindir/fexe.java
+++ b/frysk-core/frysk/bindir/fexe.java
@@ -84,11 +84,11 @@ public class fexe
 	    if (verbose) {
 		ProcessIdentifier pid
 		= ProcessIdentifierFactory.create(proc.getPid());
-		System.out.println(  proc.getPid()
+		System.out.println(proc.getPid()
 			           + " "
 			           + proc.getExeFile().getFile().getAbsolutePath()
 			           + " "
-			           + Exe.get(pid)
+			           + Exe.getName(pid)
 			           + " "
 			           + sysRootedPath);
 	    } else 
diff --git a/frysk-core/frysk/bindir/fstack.java b/frysk-core/frysk/bindir/fstack.java
index a59bd43..89988a9 100644
--- a/frysk-core/frysk/bindir/fstack.java
+++ b/frysk-core/frysk/bindir/fstack.java
@@ -42,7 +42,7 @@ package frysk.bindir;
 import java.io.PrintWriter;
 import java.util.Iterator;
 import java.util.TreeMap;
-import frysk.debuginfo.PrintStackOptions;
+import frysk.debuginfo.PrintDebugInfoStackOptions;
 import frysk.event.Event;
 import frysk.event.ProcEvent;
 import frysk.proc.Proc;
@@ -55,8 +55,8 @@ import gnu.classpath.tools.getopt.OptionGroup;
 public final class fstack {
 
   private static PrintWriter printWriter = new PrintWriter(System.out);  
-    private static PrintStackOptions stackPrintOptions
-	= new PrintStackOptions();
+    private static PrintDebugInfoStackOptions stackPrintOptions
+	= new PrintDebugInfoStackOptions();
   private static final Log fine = Log.fine(fstack.class);
   
     public static void main(String[] args) {
diff --git a/frysk-core/frysk/bindir/ftrace.java b/frysk-core/frysk/bindir/ftrace.java
index 86cb8fc..34baff7 100644
--- a/frysk-core/frysk/bindir/ftrace.java
+++ b/frysk-core/frysk/bindir/ftrace.java
@@ -52,7 +52,7 @@ import gnu.classpath.tools.getopt.OptionException;
 import gnu.classpath.tools.getopt.OptionGroup;
 import inua.util.PrintWriter;
 
-import frysk.debuginfo.PrintStackOptions;
+import frysk.debuginfo.PrintDebugInfoStackOptions;
 import frysk.expr.FQIdentParser;
 import frysk.expr.FQIdentifier;
 import frysk.ftrace.AddrRule;
@@ -94,8 +94,8 @@ class ftrace {
     private final FtraceController controller = new FtraceController();
     private boolean allowInterpTracing = false;
 
-    private final PrintStackOptions stackPrintOptions
-	= new PrintStackOptions();
+    private final PrintDebugInfoStackOptions stackPrintOptions
+	= new PrintDebugInfoStackOptions();
     private final Ftrace tracer = new Ftrace(stackPrintOptions);
 
     private interface RuleMatcher {
diff --git a/frysk-core/frysk/bindir/ftrace.xml-in b/frysk-core/frysk/bindir/ftrace.xml-in
index 525fef3..7e66e0e 100644
--- a/frysk-core/frysk/bindir/ftrace.xml-in
+++ b/frysk-core/frysk/bindir/ftrace.xml-in
@@ -246,56 +246,56 @@
     <title>SYMBOL RULE SYNTAX</title>
 
     <para>To decide which PLT slots or entry points should be traced,
-    following process takes place.  Initial working set is empty.
-    Rules, if present, are then enumerated from left to right, and set
-    is modified depending on the rules.  Rules are delimited by a
-    comma.  Syntax of each rule is following:</para>
+    following process takes place.  A set of symbols to trace
+    ("working set") is initially empty.  Rules, if present, are then
+    enumerated from left to right, and set is modified depending on
+    the rules.  Rules are delimited by a comma.  Syntax of each rule
+    is following:</para>
 
     <para>[-]<replaceable>pattern</replaceable>[/<replaceable>options</replaceable>]</para>
 
-    <para>Optional &quot;-&quot; at the beginning of the rule means
-    removal from the working set.  When the sign is omitted, the
-    default action is to add matching symbols to the working
-    set.</para>
+    <para>Without the optional &quot;-&quot; all symbols that match
+    the <replaceable>pattern</replaceable> are added to the working
+    set.  With &quot;-&quot;, matching symbols are removed.</para>
 
-    <para>If optional &quot;/&quot; is present at the end of the rule,
+    <para>If &quot;/&quot; is present at the end of the rule,
     following letters are interpreted as rule flags.  Currently only
     one flag is available, &quot;s&quot;.  When present, it means
     ftrace should show a stack trace when it hits a symbol that
     matches this rule.</para>
 
-    <para>When a &quot;-#&quot; rule is considered that has
-    &quot;s&quot; flag, then the call should still be traced, but
-    stack trace shouldn't be generated.</para>
+    <para>When a &quot;-&quot; rule has an &quot;/s&quot; flag, the
+    call should still be traced, but stack trace shouldn't be
+    generated.</para>
 
     <para><replaceable>pattern</replaceable> defines which symbols or
     PLT slots from which libraries should be added or removed from
-    working set.  Syntax of pattern is the following:</para>
-
-    <para><optional>#<replaceable>soname</replaceable>#</optional>
-    	  <optional><replaceable>filename.c</replaceable>#</optional>
-    	  <optional>(<replaceable>proc</replaceable>|<replaceable>line</replaceable>)#</optional>
-	  <optional>plt:</optional>symbol<optional>@<replaceable>version</replaceable></optional></para>
+    working set.  Syntax of pattern is as follows:</para>
 
+    <para><optional>#<replaceable>soname</replaceable>#</optional><!--
+       --><optional><replaceable>filename.c</replaceable>#</optional><!--
+       --><optional>(<replaceable>proc</replaceable>|<replaceable>line</replaceable>)#</optional><!--
+       --><optional>plt:</optional>symbol<optional>@<replaceable>version</replaceable></optional></para>
 
     <para><replaceable>soname</replaceable> component is matched
-    against a soname of a library in which we wish to track the call.
-    If the library has no associated soname or it is a main
-    executable, the match is done against the file name (without a
-    path).  Two special sonames are distinguished: "MAIN", which
-    always matches main executable; and "INTERP", which always matches
-    ELF interpreter (dynamic linker) of the main executable.  If the
-    component is missing, then the rule is applicable in all libraries
-    and in main executable.</para>
+    against a soname of a library in which we wish to trace the call.
+    If the library has no associated soname (such as is usual in case
+    of main executable), the match is done against the file name
+    (without a path).  Two special sonames are distinguished: "MAIN",
+    which always matches main executable; and "INTERP", which always
+    matches ELF interpreter (dynamic linker) of the main executable.
+    If the component is missing, then the rule is applicable in all
+    libraries and in main executable.</para>
 
     <para><replaceable>filename.c</replaceable> component is matched
-    against the name of a file where the symbol is defined.</para>
+    against the name of a file where the symbol is defined.  NOTE:
+    This is currently not implemented.</para>
 
     <para><replaceable>proc</replaceable> component is matched against
     the name of block surrounding the definition we wish to trace.  If
     the block doesn't have a name, you can instead refer to it with
     the <replaceable>line</replaceable> number that the block
-    surrounds.</para>
+    surrounds.  NOTE: This is currently not implemented.</para>
 
     <para><replaceable>symbol</replaceable> component is matched
     against the name of symbol under consideration.  If
@@ -306,11 +306,10 @@
     against version associated with symbol.  If the symbol has no
     associated version, it is considered to be an empty string.  (It
     is possible to request symbol without a version with the pattern
-    "foo@".)</para>
+    "foo@".) NOTE: This is currently not implemented.</para>
 
-    <para>NOTE: A lot of this is not yet implemented.  Currently all
-    the components are required to be plain strings, although in
-    future some form of globbing will be introduced.</para>
+    <para>All components are presented in glob syntax.  See glob(7)
+    manual page for more details.  See below for examples.</para>
   </refsect1>
 
   <refsect1>
@@ -364,8 +363,8 @@
     <para><replaceable>soname</replaceable> component is the same as
     in symbol tracing, i.e. it's matched against a soname of a library
     in which we wish to trace the address.  Same rules apply regarding
-    INTERP and MAIN meta-sonames.  Refer there for detailed
-    description.</para>
+    INTERP and MAIN meta-sonames.  Refer to the chapter "SYMBOL RULE
+    SYNTAX" for detailed description.</para>
 
     <para>Even though <replaceable>soname</replaceable> is optional,
     at least one soname has to be specified at the beginning of the
@@ -399,17 +398,16 @@
       <cmdsynopsis><command>ftrace -sys=&apos;*stat*,3&apos; ls</command></cmdsynopsis>
       <para>Various ways to tell ftrace that you want to stack trace on SIGUSR1:</para>
       <cmdsynopsis><command>ftrace -sig=USR1/s,usr1/s,SIGUSR1/s,sigusr1/s,10/s ~/sig</command></cmdsynopsis>
-      <para>Trace all library calls (NOTE globbing doesn't work yet):</para>
+      <para>Trace all library calls:</para>
       <cmdsynopsis><command>ftrace -sym=plt:* ls</command></cmdsynopsis>
       <para>Trace all library calls to functions that contain
-      substring "write" in their names (NOTE globbing doesn't work yet):</para>
+      substring "write" in their names:</para>
       <cmdsynopsis><command>ftrace -sym=plt:*write* ls</command></cmdsynopsis>
       <para>Trace memory functions done from libraries, i.e. not from
-      main executable (NOTE globbing doesn't work yet):</para>
+      main executable:</para>
       <cmdsynopsis><command>ftrace -sym=&apos;plt:*alloc,plt:free,-#MAIN#plt:*&apos; ls</command></cmdsynopsis>
       <para>Stack trace on everything, except for memory allocation
-      functions (which should still be traced) (NOTE globbing doesn't
-      work yet):</para>
+      functions (which should still be traced):</para>
       <cmdsynopsis><command>ftrace -sym=&apos;plt:*/s,-plt:*alloc/s,-plt:free/s&apos; ls</command></cmdsynopsis>
     </informalexample>
 
diff --git a/frysk-core/frysk/debuginfo/ChangeLog b/frysk-core/frysk/debuginfo/ChangeLog
index f74532f..cfcade3 100644
--- a/frysk-core/frysk/debuginfo/ChangeLog
+++ b/frysk-core/frysk/debuginfo/ChangeLog
@@ -1,3 +1,41 @@
+2008-03-20  Mark Wielaard  <mark@klomp.org>
+
+	* TestDebugInfoStackTrace.java (pushPopAssertions): Make sure
+	line is initialized.
+
+2008-06-15  Andrew Cagney  <cagney@redhat.com>
+
+	* gen-type-expect-tests.py (open_file): Use assert, not if/println
+	to detect and report bad values.
+
+2008-06-12  Andrew Cagney  <cagney@redhat.com>
+
+	* ObjectDeclarationNotFoundException.java: Extend
+	UserException.
+	* PieceLocation.java: Throw UserException.
+
+2008-06-11  Teresa Thomas  <tthomas@redhat.com>
+	
+	* PieceLocation.java (length): Make public.
+	
+2008-06-10  Andrew Cagney  <cagney@redhat.com>
+
+	* PrintDebugInfoStackOptions.java (printSourcePaths): New.
+	(setPrintPaths(boolean)): New.
+	* DebugInfoFrame.java: Update.
+	* TestFrameDebugInfo.java: Use setPrintPaths.
+
+	* DebugInfoFrame.java (toPrint): Print the library using
+	Frame.printLibraryName.
+	
+	* DebugInfoFrame.java (toPrint(PrintWriter,boolean,boolean)): Delete.
+	(toPrint(PrintWriter,DebugInfoStackOptions)): New.
+	* PrintParameterOptions.java: New.
+	* VirtualDebugInfoFrame.java: Ditto.
+	* PrintDebugInfoStackOptions.java: Rename PrintStackOptions,
+	extend frysk.stack.PrintStackOptions.
+	* TestFrameDebugInfo.java: Update.
+
 2008-06-06  Andrew Cagney  <cagney@redhat.com>
 
 	* DebugInfo.java: Let DwflDie adjust for bias.
diff --git a/frysk-core/frysk/debuginfo/DebugInfoFrame.java b/frysk-core/frysk/debuginfo/DebugInfoFrame.java
index 02ecdca..586ed65 100644
--- a/frysk-core/frysk/debuginfo/DebugInfoFrame.java
+++ b/frysk-core/frysk/debuginfo/DebugInfoFrame.java
@@ -39,10 +39,10 @@
 
 package frysk.debuginfo;
 
+import frysk.util.ArchFormatter;
 import java.io.PrintWriter;
 import java.util.Iterator;
 import java.util.LinkedList;
-
 import lib.dwfl.DwarfDie;
 import lib.dwfl.Dwfl;
 import lib.dwfl.DwflDie;
@@ -186,39 +186,33 @@ public class DebugInfoFrame extends FrameDecorator {
     }
     private LineXXX lineXXX;
     
-    public void toPrint(PrintWriter writer, boolean printParameters,
-		 boolean fullpath){
+    public void toPrint(PrintWriter writer,
+			PrintDebugInfoStackOptions options) {
         Function subprogram = this.getSubprogram();
-
         if (subprogram != null) {
-	    writer.print("0x");
-	    String addr = Long.toHexString(this.getAddress());
-	    int padding = 2 * this.getTask().getISA().wordSize() - addr.length();
-          
-	    for (int i = 0; i < padding; ++i)
-		writer.print('0');
-          
-	    writer.print(addr);
-	    writer.print(" in " + subprogram.getName() + "(");
-	    if (printParameters) {
-		subprogram.printParameters(writer, this);
+	    writer.write(ArchFormatter.toHexString(getTask(), getAddress()));
+	    writer.print(" in ");
+	    writer.print(subprogram.getName());
+	    writer.print("(");
+	    if (options.printParameters()) {
+		subprogram.printParameters(writer, this, options.printValues());
 	    }
-	    writer.print(") ");
-          
-	    if (fullpath) {
-		SourceLocation line = this.getLine();
+	    writer.print(") at ");
+	    SourceLocation line = this.getLine();
+	    if (options.printSourcePaths()) {
 		writer.print(line.getFile().getPath());
-		writer.print("#");
-		writer.print(line.getLine());
 	    } else {
-		SourceLocation line = this.getLine();
-		writer.print(".../"+line.getFile().getName());
+		writer.print(line.getFile().getName());
+	    }
+	    writer.print("#");
+	    writer.print(line.getLine());
+	    if (line.getColumn() > 0) {
 		writer.print("#");
-		writer.print(line.getLine());
+		writer.print(line.getColumn());
 	    }
-          
+	    printLibraryName(writer, options);
         } else {
-            super.toPrint(writer, true, fullpath);
+            super.toPrint(writer, options);
         }
     }
     
diff --git a/frysk-core/frysk/debuginfo/DebugInfoStackFactory.java b/frysk-core/frysk/debuginfo/DebugInfoStackFactory.java
index 7023da6..4adec65 100644
--- a/frysk-core/frysk/debuginfo/DebugInfoStackFactory.java
+++ b/frysk-core/frysk/debuginfo/DebugInfoStackFactory.java
@@ -51,9 +51,6 @@ import frysk.stack.StackFactory;
  */
 public class DebugInfoStackFactory {
 
-    public static final PrintStackOptions DEFAULT
-	= new PrintStackOptions().setRich();
-
     /**
      * Create an ABI stack backtrace, make the simpler debug-info
      * methods.
@@ -100,29 +97,31 @@ public class DebugInfoStackFactory {
 	return innermostFrame;
     }
 
-    public static final void printTaskStackTrace (PrintWriter printWriter, Task task, PrintStackOptions options)
-    {
-      if (task != null){
-        printWriter.println("Task #" + task.getTid());
-        DebugInfoFrame frame = createDebugInfoStackTrace(task);
-        printStackTrace(printWriter, frame, options);
-      }
-      printWriter.flush();
+    public static final void printTaskStackTrace(PrintWriter printWriter,
+						 Task task,
+						 PrintDebugInfoStackOptions options) {
+	if (task != null) {
+	    printWriter.println("Task #" + task.getTid());
+	    DebugInfoFrame frame = createDebugInfoStackTrace(task);
+	    printStackTrace(printWriter, frame, options);
+	}
+	printWriter.flush();
     }
 
-    public static final void printVirtualTaskStackTrace (PrintWriter printWriter, Task task, PrintStackOptions options)
-    {
-      if (task != null){
-        printWriter.println("Task #" + task.getTid());
-        DebugInfoFrame frame = createVirtualStackTrace(task);
-        printStackTrace(printWriter,frame, options);
-      }
-      printWriter.flush();
+    public static final void printVirtualTaskStackTrace(PrintWriter printWriter,
+							Task task,
+							PrintDebugInfoStackOptions options) {
+	if (task != null) {
+	    printWriter.println("Task #" + task.getTid());
+	    DebugInfoFrame frame = createVirtualStackTrace(task);
+	    printStackTrace(printWriter,frame, options);
+	}
+	printWriter.flush();
     }
 
     public static void printStackTrace(PrintWriter writer,
 				       DebugInfoFrame topFrame,
-				      PrintStackOptions options) {
+				       PrintDebugInfoStackOptions options) {
         
 	int count = 0;
         for (DebugInfoFrame frame = topFrame; frame != null;
@@ -142,8 +141,7 @@ public class DebugInfoStackFactory {
 
 	    frame.printLevel(writer);
 	    writer.print(" ");
-	    frame.toPrint(writer, options.printParams(),
-			  options.printFullPaths());
+	    frame.toPrint(writer, options);
 	    writer.println();
 	    if (options.printLocals()) {
 		frame.printScopes(writer);
diff --git a/frysk-core/frysk/debuginfo/ObjectDeclarationNotFoundException.java b/frysk-core/frysk/debuginfo/ObjectDeclarationNotFoundException.java
index 6aee2a0..0f0b0c2 100644
--- a/frysk-core/frysk/debuginfo/ObjectDeclarationNotFoundException.java
+++ b/frysk-core/frysk/debuginfo/ObjectDeclarationNotFoundException.java
@@ -1,6 +1,6 @@
 // This file is part of the program FRYSK.
 //
-// Copyright 2007, Red Hat Inc.
+// Copyright 2007, 2008, Red Hat Inc.
 //
 // FRYSK is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by
@@ -39,16 +39,11 @@
 
 package frysk.debuginfo;
 
-public class ObjectDeclarationNotFoundException extends RuntimeException {
+import frysk.UserException;
 
+public class ObjectDeclarationNotFoundException extends UserException {
     public ObjectDeclarationNotFoundException(String name) {
 	super("Object "+ name + " was not found");
     }
-
-    /**
-     * 
-     */
     private static final long serialVersionUID = 1L;
-
-  
 }
diff --git a/frysk-core/frysk/debuginfo/PieceLocation.java b/frysk-core/frysk/debuginfo/PieceLocation.java
index b129e77..d636a6a 100644
--- a/frysk-core/frysk/debuginfo/PieceLocation.java
+++ b/frysk-core/frysk/debuginfo/PieceLocation.java
@@ -1,46 +1,46 @@
-//This file is part of the program FRYSK.
-
-//Copyright 2007, Red Hat Inc.
-
-//FRYSK is free software; you can redistribute it and/or modify it
-//under the terms of the GNU General Public License as published by
-//the Free Software Foundation; version 2 of the License.
-
-//FRYSK is distributed in the hope that it will be useful, but
-//WITHOUT ANY WARRANTY; without even the implied warranty of
-//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-//General Public License for more details.
-
-//You should have received a copy of the GNU General Public License
-//along with FRYSK; if not, write to the Free Software Foundation,
-//Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-
-//In addition, as a special exception, Red Hat, Inc. gives You the
-//additional right to link the code of FRYSK with code not covered
-//under the GNU General Public License ("Non-GPL Code") and to
-//distribute linked combinations including the two, subject to the
-//limitations in this paragraph. Non-GPL Code permitted under this
-//exception must only link to the code of FRYSK through those well
-//defined interfaces identified in the file named EXCEPTION found in
-//the source code files (the "Approved Interfaces"). The files of
-//Non-GPL Code may instantiate templates or use macros or inline
-//functions from the Approved Interfaces without causing the
-//resulting work to be covered by the GNU General Public
-//License. Only Red Hat, Inc. may make changes or additions to the
-//list of Approved Interfaces. You must obey the GNU General Public
-//License in all respects for all of the FRYSK code and other code
-//used in conjunction with FRYSK except the Non-GPL Code covered by
-//this exception. If you modify this file, you may extend this
-//exception to your version of the file, but you are not obligated to
-//do so. If you do not wish to provide this exception without
-//modification, you must delete this exception statement from your
-//version and license this file solely under the GPL without
-//exception.
+// This file is part of the program FRYSK.
+// 
+// Copyright 2007, Red Hat Inc.
+// 
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+// 
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
 
 package frysk.debuginfo;
 
 import frysk.value.Location;
-
+import frysk.UserException;
 import java.io.PrintWriter;
 import java.util.Iterator;
 import java.util.List;
@@ -86,7 +86,7 @@ extends Location
     {
 	if (pieces.size()==1 && (pieces.get(0) instanceof MemoryPiece))
 	   return ((MemoryPiece)pieces.get(0)).getMemory();
-	throw new RuntimeException("Location not in contiguous memory.");
+	throw new UserException("Location not in contiguous memory.");
     }
     
     /**
@@ -125,7 +125,7 @@ extends Location
 	    else
 		indexCount += len;
 	}
-	throw new RuntimeException("Out of range.");	
+	throw new UserException("Out of range.");	
     }
 
     /**
@@ -155,7 +155,7 @@ extends Location
 	    else
 		indexCount += len;
 	}
-	throw new RuntimeException("Out of range.");	
+	throw new UserException("Out of range.");	
     }
 
     /**
@@ -181,7 +181,7 @@ extends Location
     /**
      * Returns the number of bytes in location.
      */
-    protected long length() 
+    public long length() 
     {
 	long length = 0;
 	for (Iterator it=pieces.iterator(); it.hasNext(); )
diff --git a/frysk-core/frysk/debuginfo/PrintDebugInfoStackOptions.java b/frysk-core/frysk/debuginfo/PrintDebugInfoStackOptions.java
new file mode 100644
index 0000000..486eae3
--- /dev/null
+++ b/frysk-core/frysk/debuginfo/PrintDebugInfoStackOptions.java
@@ -0,0 +1,167 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2007, 2008, Red Hat Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+package frysk.debuginfo;
+
+import frysk.stack.PrintStackOptions;
+
+public class PrintDebugInfoStackOptions extends PrintStackOptions {
+
+    public PrintDebugInfoStackOptions() {
+	// Note, the super calls clear.
+    }
+    
+    private boolean printParameters;
+    private boolean printLocals;
+    private boolean printInlineFunctions;
+    private boolean printDebugNames;
+    private boolean printValues;
+    private boolean printSourcePaths;
+    
+    /**
+     * Clear all options.
+     */
+    public void clear() {
+	super.clear();
+	printParameters = false;
+	printLocals = false;
+	printInlineFunctions = false;
+	printDebugNames = false;
+	printValues = false;
+    }
+
+    /**
+     * Set things up for a light-weight, or low-cost, back-trace by
+     * limiting things to just the elf information.
+     */
+    public void setLite() {
+	setAbi();
+	setPrintDebugNames(true);
+    }
+
+    /**
+     * Set things up for a rich, or detailed, back-trace by including
+     * inline frames and parameter information.
+     */
+    public void setRich() {
+	setAbi();
+	setPrintParameters(true);
+	setPrintInlineFunctions(true);
+	setPrintDebugNames(true);
+    }
+
+    /**
+     * Print the full path to any source file.
+     */
+    public void setPrintPaths(boolean printPaths) {
+	super.setPrintPaths(printPaths);
+	setPrintSourcePaths(printPaths);
+    }
+
+    /**
+     * Print the parameter list (see also printValues).
+     */
+    public boolean printParameters() {
+	return printParameters;
+    }
+    public void setPrintParameters(boolean printParameters) {
+	this.printParameters = printParameters;
+    }
+
+    /**
+     * Print paramter and variable values (rather than just their
+     * names).
+     */
+    public boolean printValues() {
+	return printValues;
+    }
+    public void setPrintValues(boolean printValues) {
+	this.printValues = printValues;
+    }
+
+    /**
+     * Print the function's local variables.
+     */
+    public boolean printLocals() {
+	return printLocals;
+    }
+    public void setPrintLocals(boolean printLocals) {
+	this.printLocals = printLocals;
+    }
+
+    /**
+     * Print inline function instances.
+     */
+    public boolean printInlineFunctions() {
+	return printInlineFunctions;
+    }
+    public void setPrintInlineFunctions(boolean printInlineFunctions) {
+	this.printInlineFunctions = printInlineFunctions;
+    }
+
+    /**
+     * Print function and variable names using debug, rather than ABI,
+     * information.
+     */
+    public boolean printDebugNames() {
+	return printDebugNames;
+    }
+    public void setPrintDebugNames(boolean printDebugNames) {
+	this.printDebugNames = printDebugNames;
+    }
+
+    /**
+     * Print the full path to source files (instead of just the file
+     * name).
+     */
+    public boolean printSourcePaths() {
+	return printSourcePaths;
+    }
+    public void setPrintSourcePaths(boolean printSourcePaths) {
+	this.printSourcePaths = printSourcePaths;
+    }
+
+    public boolean abiOnly() {
+	return ! (printLocals
+		  || printInlineFunctions
+		  || printParameters
+		  || printValues
+		  || printDebugNames);
+    }
+}
diff --git a/frysk-core/frysk/debuginfo/PrintStackOptions.java b/frysk-core/frysk/debuginfo/PrintStackOptions.java
deleted file mode 100644
index acae8e0..0000000
--- a/frysk-core/frysk/debuginfo/PrintStackOptions.java
+++ /dev/null
@@ -1,141 +0,0 @@
-// This file is part of the program FRYSK.
-//
-// Copyright 2007, 2008, Red Hat Inc.
-//
-// FRYSK is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// FRYSK is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with FRYSK; if not, write to the Free Software Foundation,
-// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-//
-// In addition, as a special exception, Red Hat, Inc. gives You the
-// additional right to link the code of FRYSK with code not covered
-// under the GNU General Public License ("Non-GPL Code") and to
-// distribute linked combinations including the two, subject to the
-// limitations in this paragraph. Non-GPL Code permitted under this
-// exception must only link to the code of FRYSK through those well
-// defined interfaces identified in the file named EXCEPTION found in
-// the source code files (the "Approved Interfaces"). The files of
-// Non-GPL Code may instantiate templates or use macros or inline
-// functions from the Approved Interfaces without causing the
-// resulting work to be covered by the GNU General Public
-// License. Only Red Hat, Inc. may make changes or additions to the
-// list of Approved Interfaces. You must obey the GNU General Public
-// License in all respects for all of the FRYSK code and other code
-// used in conjunction with FRYSK except the Non-GPL Code covered by
-// this exception. If you modify this file, you may extend this
-// exception to your version of the file, but you are not obligated to
-// do so. If you do not wish to provide this exception without
-// modification, you must delete this exception statement from your
-// version and license this file solely under the GPL without
-// exception.
-
-package frysk.debuginfo;
-
-public class PrintStackOptions {
-
-    private int numberOfFrames = 10;
-
-    private boolean printFullPaths = false;
-
-    private boolean printParams = false;
-    private boolean printLocals = false;
-    private boolean printLibraries = false;
-    private boolean printInlineFunctions = false;
-    private boolean printDebugNames = false;
-    
-    public PrintStackOptions() {
-    }
-    
-    /**
-     * Set things up for a light-weight, or low-cost, back-trace by
-     * limiting things to just the elf information.
-     */
-    public PrintStackOptions setLite() {
-	printParams = false;
-	printLocals = false;
-	printLibraries = true;
-	printInlineFunctions = false;
-	printDebugNames = true;
-	return this;
-    }
-
-    /**
-     * Set things up for a rich, or detailed, back-trace by including
-     * inline frames and parameter information.
-     */
-    public PrintStackOptions setRich() {
-	printParams = true;
-	printLocals = true;
-	printLibraries = true;
-	printInlineFunctions = true;
-	printDebugNames = true;
-	return this;
-    }
-
-    /**
-     * Specify the number of frames to include in the back-trace, 0 to
-     * include all frames.
-     */
-    public void setNumberOfFrames(int numberOfFrames) {
-	this.numberOfFrames = numberOfFrames;
-    }
-    public int numberOfFrames() {
-	return numberOfFrames;
-    }
-
-    public void setPrintParams(boolean printParams) {
-	this.printParams = printParams;
-    }
-    public boolean printParams() {
-	return printParams;
-    }
-
-    public void setPrintLocals(boolean printLocals) {
-	this.printLocals = printLocals;
-    }
-    public boolean printLocals() {
-	return printLocals;
-    }
-
-    public void setPrintFullPaths(boolean printFullPaths) {
-	this.printFullPaths = printFullPaths;
-    }
-    public boolean printFullPaths() {
-	return printFullPaths;
-    }
-
-    public void setPrintLibraries(boolean printLibraries) {
-	this.printLibraries = printLibraries;
-    }
-    public boolean printLibraries() {
-	return printLibraries;
-    }
-
-    public void setPrintInlineFunctions(boolean printInlineFunctions) {
-	this.printInlineFunctions = printInlineFunctions;
-    }
-    public boolean printInlineFunctions() {
-	return printInlineFunctions;
-    }
-
-    public void setPrintDebugNames(boolean printDebugNames) {
-	this.printDebugNames = printDebugNames;
-    }
-    public boolean printDebugNames() {
-	return printDebugNames;
-    }
-
-    public boolean elfOnly() {
-	return ! (printLocals || printInlineFunctions || printParams
-		  || printDebugNames);
-    }
-    
-}
diff --git a/frysk-core/frysk/debuginfo/TestDebugInfoStackTrace.java b/frysk-core/frysk/debuginfo/TestDebugInfoStackTrace.java
index 35e2737..9f1d953 100644
--- a/frysk-core/frysk/debuginfo/TestDebugInfoStackTrace.java
+++ b/frysk-core/frysk/debuginfo/TestDebugInfoStackTrace.java
@@ -500,7 +500,7 @@ public class TestDebugInfoStackTrace
   public void pushPopAssertions ()
   {
     DebugInfoFrame sFrame = DebugInfoStackFactory.createDebugInfoStackTrace(myTask);
-    SourceLocation line = null; 
+    SourceLocation line = sFrame.getLine(); 
     
     if (this.testState == PUSH || this.testState == POP)
       {
diff --git a/frysk-core/frysk/debuginfo/TestFrameDebugInfo.java b/frysk-core/frysk/debuginfo/TestFrameDebugInfo.java
index 439218f..74eead7 100644
--- a/frysk-core/frysk/debuginfo/TestFrameDebugInfo.java
+++ b/frysk-core/frysk/debuginfo/TestFrameDebugInfo.java
@@ -45,7 +45,6 @@ import java.util.Iterator;
 import java.util.LinkedList;
 
 import javax.naming.NameNotFoundException;
-
 import lib.dwfl.DwTag;
 import lib.dwfl.DwarfDie;
 import lib.dwfl.Dwfl;
@@ -85,11 +84,11 @@ public class TestFrameDebugInfo extends TestLib {
     
     StringWriter stringWriter = new StringWriter();
     DebugInfoFrame frame = DebugInfoStackFactory.createDebugInfoStackTrace(task);
-    PrintStackOptions options = new PrintStackOptions();
+    PrintDebugInfoStackOptions options = new PrintDebugInfoStackOptions();
     options.setNumberOfFrames(20);
-    options.setPrintParams(true);
+    options.setPrintParameters(true);
     options.setPrintLocals(true);
-    options.setPrintFullPaths(true);
+    options.setPrintPaths(true);
     DebugInfoStackFactory.printStackTrace(new PrintWriter(stringWriter),frame, options);
       
     String string = stringWriter.getBuffer().toString();
@@ -307,11 +306,11 @@ public class TestFrameDebugInfo extends TestLib {
       Task task = (new DaemonBlockedAtSignal("funit-stack-inlined" + ext)).getMainTask();
     StringWriter stringWriter = new StringWriter();
     
-    PrintStackOptions options = new PrintStackOptions();
+    PrintDebugInfoStackOptions options = new PrintDebugInfoStackOptions();
     options.setNumberOfFrames(0);
-    options.setPrintParams(true);
+    options.setPrintParameters(true);
     options.setPrintLocals(true);
-    options.setPrintFullPaths(true);
+    options.setPrintPaths(true);
     DebugInfoStackFactory.printVirtualTaskStackTrace(new PrintWriter(stringWriter), task, options);
     
     assertTrue("contains inline", stringWriter.getBuffer().toString().contains("inline"));
@@ -326,11 +325,11 @@ public class TestFrameDebugInfo extends TestLib {
     
       Task task = (new DaemonBlockedAtSignal("funit-stack-inlined")).getMainTask();
     
-    PrintStackOptions options = new PrintStackOptions();
+    PrintDebugInfoStackOptions options = new PrintDebugInfoStackOptions();
     options.setNumberOfFrames(0); 
-    options.setPrintParams(true);
+    options.setPrintParameters(true);
     options.setPrintLocals(true);
-    options.setPrintFullPaths(true);
+    options.setPrintPaths(true);
     
     DebugInfoFrame frame = DebugInfoStackFactory.createVirtualStackTrace(task);
     frame = frame.getOuterDebugInfoFrame();
diff --git a/frysk-core/frysk/debuginfo/TestPieceLocation.java b/frysk-core/frysk/debuginfo/TestPieceLocation.java
index 1ea10c8..964d878 100644
--- a/frysk-core/frysk/debuginfo/TestPieceLocation.java
+++ b/frysk-core/frysk/debuginfo/TestPieceLocation.java
@@ -153,7 +153,7 @@ extends TestLib
 	Location simple = PieceLocation.createSimpleLoc (3, 5, 
 		new ArrayByteBuffer(new byte[] { 127,127,127, 5, 6, 7, 8, 9, 127, 127 }));
 	assertEquals ("Address", 3, simple.getAddress());
-	assertEquals ("Length", 5, ((PieceLocation)simple).length());
+	assertEquals ("Length", 5, simple.length());
     }
     
     private Task getStoppedTask ()
diff --git a/frysk-core/frysk/debuginfo/VirtualDebugInfoFrame.java b/frysk-core/frysk/debuginfo/VirtualDebugInfoFrame.java
index ae3ed76..7fb6039 100644
--- a/frysk-core/frysk/debuginfo/VirtualDebugInfoFrame.java
+++ b/frysk-core/frysk/debuginfo/VirtualDebugInfoFrame.java
@@ -52,9 +52,9 @@ public class VirtualDebugInfoFrame extends DebugInfoFrame {
 	super(inner, decorated);
     }
 
-    public void toPrint(PrintWriter writer, boolean printParameters,
-		 boolean fullpath) {
-	super.toPrint(writer, printParameters, fullpath);
+    public void toPrint(PrintWriter writer,
+			PrintDebugInfoStackOptions options) {
+	super.toPrint(writer, options);
 	writer.print(" [inline]");
     }
 
diff --git a/frysk-core/frysk/debuginfo/gen-type-expect-tests.py b/frysk-core/frysk/debuginfo/gen-type-expect-tests.py
index c8513c4..0daf18a 100644
--- a/frysk-core/frysk/debuginfo/gen-type-expect-tests.py
+++ b/frysk-core/frysk/debuginfo/gen-type-expect-tests.py
@@ -94,15 +94,10 @@ public class %s extends TestLib {
         print('''
 	void checkType(String symbol, String expected) {
 	    Type varType;
-
 	    DwarfDie varDie = biasDie.getScopeVar(allDies, symbol);
-	    if (varDie == null)
-		System.out.println("Error: Cannot find " + symbol);
-	    assertNotNull(varDie);
+            assertNotNull("die for variable " + symbol, varDie);
 	    varType = typeFactory.getType(varDie.getType());
 	    assertNotNull(varType);
-	    // System.out.println("Expect: " + symbol + "\\n'" +
-	    //    expected + "'\\nGot:\\n'" + varType.toPrint());
 	    assertEquals(testName + symbol, expected, varType.toPrint());
 	}
 
@@ -115,19 +110,13 @@ public class %s extends TestLib {
 		|| expected.length() == 0)
 		return;
 	    DwarfDie varDie = biasDie.getScopeVar(allDies, symbol);
-	    if (varDie == null)
-		System.out.println("Error: Cannot find " + symbol);
-	    assertNotNull(varDie);
+            assertNotNull("die for variable " + symbol, varDie);
 	    DebugInfo debugInfo = new DebugInfo(frame);
 	    Value value =  debugInfo.print(symbol, frame);
 	    value.toPrint(pw, task.getMemory(), Format.NATURAL, 0);
 	    pw.flush();
 	    String valueString = baos.toString();
-	    // System.out.println("Expect: " + symbol +
-	    //     "\\n'" + expected + "'\\nGot:\\n'" +
-	    //     valueString + "'" + " " + value.getType());
 	    assertEquals(testName + symbol, expected, valueString);
-	    baos.reset();
 	}
     }
 ''')
diff --git a/frysk-core/frysk/dwfl/ChangeLog b/frysk-core/frysk/dwfl/ChangeLog
index 542bf50..6ea8bf2 100644
--- a/frysk-core/frysk/dwfl/ChangeLog
+++ b/frysk-core/frysk/dwfl/ChangeLog
@@ -1,3 +1,9 @@
+2008-06-19  Andrew Cagney  <cagney@redhat.com>
+
+	* DwflCache.java (getDwfl()): Pass the task's memory to the Dwfl
+	and down to the native code, don't pass the vdso address.
+	* DwflFactory.java (updateDwfl): Don't set the module's memory.
+
 2008-06-03  Andrew Cagney  <cagney@redhat.com>
 
 	* DwflFactory.java (updateDwfl): Simplify by using Dwfl.mapBegin,
diff --git a/frysk-core/frysk/dwfl/DwflCache.java b/frysk-core/frysk/dwfl/DwflCache.java
index 15ffde3..4825f94 100644
--- a/frysk-core/frysk/dwfl/DwflCache.java
+++ b/frysk-core/frysk/dwfl/DwflCache.java
@@ -132,7 +132,7 @@ public class DwflCache {
 	    fine.log("creating new dwfl for task", task);
 	    File sysrootFile = (File)SysRootCache.getSysRoot(task);
 	    File relativeSysroot = getRelativeSysRoot(task.getProc().getExeFile().getSysRootedPath(), sysrootFile);
-	    Dwfl dwfl = new Dwfl(relativeSysroot.getPath());
+	    Dwfl dwfl = new Dwfl(relativeSysroot.getPath(), task.getMemory());
 	    DwflFactory.updateDwfl(dwfl, task);
 	    Mod mod = new Mod(dwfl, task.getMod());
 	    modMap.put(task, mod);
diff --git a/frysk-core/frysk/dwfl/DwflFactory.java b/frysk-core/frysk/dwfl/DwflFactory.java
index 0f17713..eabb0c6 100644
--- a/frysk-core/frysk/dwfl/DwflFactory.java
+++ b/frysk-core/frysk/dwfl/DwflFactory.java
@@ -45,7 +45,6 @@ import frysk.proc.Proc;
 import frysk.proc.Task;
 import frysk.rsl.Log;
 import lib.dwfl.Dwfl;
-import lib.dwfl.DwflModule;
 
 /**
  * Factory for creating Dwfl objects for Procs and Tasks.
@@ -96,23 +95,15 @@ public class DwflFactory {
     static Dwfl updateDwfl(Dwfl dwfl, Task task) {
 	Proc proc = task.getProc();
 	MemoryMap[] maps = proc.getMaps();
-	long vdso = VDSOAddressLow(proc);
-	dwfl.mapBegin(vdso);
+	dwfl.mapBegin();
 	for (int i = 0; i < maps.length; i++) {
 	    MemoryMap map = maps[i];
 	    dwfl.mapModule(map.name, map.addressLow, map.addressHigh,
 			   map.devMajor, map.devMinor, map.inode);
 	}
 	dwfl.mapEnd();
-	DwflModule module = dwfl.getModule(vdso);
 	fine.log("updateDwfl main task", proc.getMainTask(),
-		 "memory", proc.getMainTask().getMemory(),
-		 "dwfl module", module);
-	// XXX: Should this method instead have this block of memory
-	// pre-fetched and passed in?
-	if (module != null) {
-	    module.setUserData(task.getMemory());
-	}
+		 "memory", proc.getMainTask().getMemory());
 	return dwfl;
     }
 }
diff --git a/frysk-core/frysk/event/ChangeLog b/frysk-core/frysk/event/ChangeLog
index b457707..13ecd79 100644
--- a/frysk-core/frysk/event/ChangeLog
+++ b/frysk-core/frysk/event/ChangeLog
@@ -1,3 +1,8 @@
+2008-06-20  Andrew Cagney  <cagney@redhat.com>
+
+	* PollEventLoop.java: Update; Poll et.al., moved to
+	frysk.sys.poll.
+
 2008-05-23  Teresa Thomas  <tthomas@redhat.com>
 
 	* ActionPointEvent.java: New file.
diff --git a/frysk-core/frysk/event/PollEventLoop.java b/frysk-core/frysk/event/PollEventLoop.java
index 8b841f9..31a09be 100644
--- a/frysk-core/frysk/event/PollEventLoop.java
+++ b/frysk-core/frysk/event/PollEventLoop.java
@@ -39,8 +39,9 @@
 
 package frysk.event;
 
-import frysk.sys.Poll;
-import frysk.sys.PollBuilder;
+import frysk.sys.FileDescriptor;
+import frysk.sys.poll.Poll;
+import frysk.sys.poll.PollBuilder;
 import frysk.sys.Signal;
 import frysk.sys.Wait;
 import frysk.sys.WaitBuilder;
@@ -101,10 +102,8 @@ class PollEventLoop extends EventLoop {
 	add (new PollWaitOnSigChild (waitBuilder));
     }
 
-    private PollBuilder pollObserver = new PollBuilder ()
-	{
-	    public String toString ()
-	    {
+    private PollBuilder pollObserver = new PollBuilder() {
+	    public String toString() {
 		return ("{" + super.toString () + "}");
 	    }
 	    public void signal(Signal sig) {
@@ -112,7 +111,7 @@ class PollEventLoop extends EventLoop {
 		processSignal (sig);
 	    }
 	    // Not yet using file descriptors.
-	    public void pollIn (int fd) {
+	    public void pollIn(FileDescriptor fd) {
 		throw new RuntimeException ("should not happen");
 	    }
 	};
diff --git a/frysk-core/frysk/expr/CExpr.g b/frysk-core/frysk/expr/CExpr.g
index 3ea45b6..2654a89 100644
--- a/frysk-core/frysk/expr/CExpr.g
+++ b/frysk-core/frysk/expr/CExpr.g
@@ -416,7 +416,7 @@ tokens
 
 {
     final FQIdentParser fqIdParser
-        = new FQIdentParser(this, true, false, true);
+        = new FQIdentParser(this, true, false, true, false);
 }
 
 AMPERSAND       : '&' ;
@@ -441,15 +441,20 @@ LCURLY          : '{' ;
 LESSTHAN        : "<" ;
 LESSTHANOREQUALTO     : "<=" ;
 LPAREN          : '('   ;
-LSQUARE         : '[' (('0'..'9') {
-                      try {
-                          Token tok = fqIdParser.parse($getText);
-                          if (tok != null) {
-                              $setToken(tok);
-                              $setType(IDENT);
-                          }
-                      } catch (RecognitionException exc) { }
-                  } )? ;
+LSQUARE         : '[' {
+                        // We can't use ('0'..'9')? here, because even
+                        // if there is 0..9, it still doesn't have to
+                        // parse correctly as [a.b#c] syntax.  But
+                        // antlr would already match the digit.
+                        if (((LA(1) >= '0' && LA(1) <= '9')))
+                            try {
+                                Token tok = fqIdParser.parse($getText);
+                                if (tok != null) {
+                                    $setToken(tok);
+                                    $setType(IDENT);
+                                }
+                            } catch (RecognitionException exc) { }
+                       } ;
 MINUS           : '-' ;
 MINUSEQUAL      : "-=" ;
 MINUSMINUS      : "--" ;
diff --git a/frysk-core/frysk/expr/ChangeLog b/frysk-core/frysk/expr/ChangeLog
index 9b25bfc..9816cdf 100644
--- a/frysk-core/frysk/expr/ChangeLog
+++ b/frysk-core/frysk/expr/ChangeLog
@@ -1,3 +1,47 @@
+2008-06-20  Petr Machata  <pmachata@redhat.com>
+
+	* FQIdentParser.java (ctor): Take extra argument
+	allowPeriodInSymbol.
+	(parseFtraceIdentifier): Pass true for the new argument.
+	(parseFQIdentifier): Likewise.
+	(symbolPattern, globPattern): Unstatic.
+	(symbolRe): Kill.
+	* CExpr.g (fqIdParser): Pass false for the new argument.
+
+2008-06-13  Petr Machata  <pmachata@redhat.com>
+
+	* FQIdentParser.java (containsGlobChar): Rename to
+	isWildcardPattern.  Only require *, ? or [ to consider
+	a string to be a wildcard pattern.
+	* FQIdentifier.java: Adapt to above.
+
+2008-06-12  Andrew Cagney  <cagney@redhat.com>
+
+	* ScratchSymTab.java: Throw UserException.
+
+2008-06-12  Petr Machata  <pmachata@redhat.com>
+
+	* TestbedSymTab.java: Add "arr", an array variable
+	* TestArithmetics.java (testArrayAccess, testArraySlice): New tests.
+
+2008-06-12  Petr Machata  <pmachata@redhat.com>
+
+	* CExpr.g (LSQUARE): Don't use "('0'..'9')?" construct, instead
+	test the same in inline java code.
+
+2008-06-12  Petr Machata  <pmachata@redhat.com>
+
+	* FQIdentParser.java (containsGlobChar): New method.
+	* FQIdentPattern.java, FQIdentPatternAll.java: New files.
+	* FQIdentPatternExact.java, FQIdentPatternGlob.java: New files.
+	* FQIdentToken.java (globs): New field.
+	* FQIdentifier.java (soname, file, proc, symbol, version): Changed
+	type from String to FQIdentPattern.
+
+2008-06-10  Petr Machata  <pmachata@redhat.com>
+
+	* FQIdentParser.java: Implement glob parsing.
+
 2008-06-09  Petr Machata  <pmachata@redhat.com>
 
 	* FQIdentParser.java: Introduce parsing options.
diff --git a/frysk-core/frysk/expr/FQIdentParser.java b/frysk-core/frysk/expr/FQIdentParser.java
index 63035b9..2aa9ce2 100644
--- a/frysk-core/frysk/expr/FQIdentParser.java
+++ b/frysk-core/frysk/expr/FQIdentParser.java
@@ -52,6 +52,15 @@ import antlr.TokenStreamException;
 import antlr.InputBuffer;
 import antlr.CharBuffer;
 
+/**
+ * Funky HPD #-syntax doesn't map very well to LL-k type parser (for
+ * constant 'k').  When written directly in antlr, we obviously get
+ * lots of lexical ambiguities.  We work around that by doing
+ * arbitrary manual look-ahead and just parsing the tokens ourselves.
+ * FQIdentParser is where that parsing takes place.  Besides
+ * supporting antlr lexical analyzer, the class can be used standalone
+ * to parse arbitrary strings.
+ */
 public class FQIdentParser {
 
     private int i;
@@ -61,6 +70,9 @@ public class FQIdentParser {
     private final boolean allowGlobs;
     private final boolean expectMoreTokens;
 
+    private final Pattern symbolPattern;
+    private final Pattern globPattern;
+
     /**
      * @param allowDynamic Whether the [pid.tid#frame] portion of the
      *        FQ syntax makes sense in given context.  For example it
@@ -80,12 +92,28 @@ public class FQIdentParser {
     FQIdentParser(CharScanner scanner,
 		  boolean allowDynamic,
 		  boolean allowGlobs,
-		  boolean expectMoreTokens) {
+		  boolean expectMoreTokens,
+		  boolean allowPeriodInSymbol) {
 
 	this.scanner = scanner;
 	this.allowDynamic = allowDynamic;
 	this.allowGlobs = allowGlobs;
 	this.expectMoreTokens = expectMoreTokens;
+
+	// This pattern deliberately doesn't check for initial letter.
+	// Relevant code checks this explicitly.  This way, if user makes
+	// a mistake and writes e.g. something#123+b, we recognize "123"
+	// as a typo, while leaving out the part after a "+", which is
+	// certainly irrelevant.
+	String symbolRe = "[a-zA-Z0-9_$" + (allowPeriodInSymbol
+					    ? "." : "") + "]+";
+	this.symbolPattern = Pattern.compile(symbolRe);
+	this.globPattern
+	    = Pattern.compile("(\\[(\\^?\\][^\\]]*" +  // handles []abc] and [^]abc]
+			      "|\\^[^\\]]+" +          // handles [^abc]
+			      "|[^^\\]][^\\]]*" +      // handles [abc], and [ab^c] (cases where ^ isn't an operator)
+			      "|\\^?\\[:[^:]+:\\]"+    // handles [[:abc:]] and [^[:abc:]]
+			      ")\\]|" + symbolRe + "|\\*)+");
     }
 
     private char fqLA(int i) throws CharStreamException {
@@ -137,6 +165,20 @@ public class FQIdentParser {
 	return matched.toString();
     }
 
+    public static boolean isGlobChar(char c) {
+	return c == '*' || c == '?' || c == '['
+	    || c == ']' || c == '^' || c == ':'
+	    || c == '-';
+    }
+
+    public static boolean isWildcardPattern(String str) {
+	// man 7 glob: """A string is a wildcard pattern if it
+	//  contains one of the characters "?", "*" or "["."""
+	return str.indexOf('*') != -1
+	    || str.indexOf('?') != -1
+	    || str.indexOf('[') != -1;
+    }
+
     /**
      * @param initial Portion of the character stream that is part of
      *        the identifier, but was already consumed by lexer.
@@ -144,22 +186,9 @@ public class FQIdentParser {
     public FQIdentToken parse(String initial)
         throws RecognitionException, CharStreamException, TokenStreamException
     {
-	if (allowGlobs)
-	    // XXX to fool java into thinking that we use allowGlobs
-	    // when we actually don't.
-	    System.out.print("");
-
 	fqinit = initial;
 	i = 0;
 
-        /*
-         * Funky HPD #-syntax doesn't map very well to LL-k type parser (for
-         * constant 'k').  When written directly, we get lots of lexical
-         * ambiguities.  We work around that by doing arbitrary manual
-         * look-ahead and just parsing the tokens ourselves.  Any whitespace
-         * or EOF stops the lookahead.
-         */
-
         String matched = "";
         String part;
 
@@ -259,7 +288,8 @@ public class FQIdentParser {
                         if (!(Character.isJavaIdentifierStart(c)
                               || c == '@'
                               || (c == ':' && part.length() == 4
-                                  && part.equals("plt:")))) {
+                                  && part.equals("plt:"))
+			      || (allowGlobs && isGlobChar(c)))) {
 
                             // Break out early if we are already
                             // just waiting for symbol.
@@ -296,22 +326,24 @@ public class FQIdentParser {
             part = part.substring(0, v);
         }
 
-        // This is delibaretely simplified and ignores request for initial letter.
-        // This is for better error reporting below, we first snip off irrelevant
-        // parts before yelling at user that his identifier sucks.
-        Matcher m = Pattern.compile("[a-zA-Z0-9_$]+").matcher(part);
-        if (m.lookingAt()) {
-            int diff = part.length() - m.end();
-            if (diff > 0) {
-                matched = matched.substring(0, matched.length() - diff);
-                part = part.substring(0, m.end());
-            }
-        }
-        else
-            throw new RecognitionException("Expected symbol name, got `" + part + "'.");
-
-        if (!Character.isJavaIdentifierStart(part.charAt(0)))
-            throw new RecognitionException("Invalid symbol `" + part + "'.");
+	Matcher m = (allowGlobs ? globPattern : symbolPattern).matcher(part);
+	if (m.lookingAt()) {
+	    int diff = part.length() - m.end();
+	    if (diff > 0) {
+		matched = matched.substring(0, matched.length() - diff);
+		part = part.substring(0, m.end());
+	    }
+	} else
+	    throw new RecognitionException("Expected "
+					   + (allowGlobs ? "glob" : "symbol name")
+					   + ", got `" + part + "'.");
+
+	c = part.charAt(0);
+	if (!(Character.isJavaIdentifierStart(c)
+	      || (allowGlobs && isGlobChar(c))))
+	    throw new RecognitionException("Invalid symbol"
+					   + (allowGlobs ? " glob" : "" )
+					   + " `" + part + "'.");
 
         FQIdentToken tok = new FQIdentToken(CExprParserTokenTypes.IDENT, matched);
         tok.dso = partDso;
@@ -325,6 +357,7 @@ public class FQIdentParser {
         tok.threadId = partThreadId;
         tok.frameNumber = partFrameNum;
         tok.setLine(scanner.getLine());
+	tok.globs = allowGlobs;
 
         fqmatch(matched);
         tok.setColumn(scanner.getColumn() - matched.length());
@@ -357,7 +390,8 @@ public class FQIdentParser {
     parseFQIdentifier(String str,
 		      boolean allowDynamic,
 		      boolean allowGlobs,
-		      boolean expectMoreTokens)
+		      boolean expectMoreTokens,
+		      boolean allowPeriodInSymbol)
         throws ExtraGarbageException, InvalidTokenException
     {
         try {
@@ -369,7 +403,8 @@ public class FQIdentParser {
 		};
 	    FQIdentParser parser
 		= new FQIdentParser(scanner, allowDynamic,
-				    allowGlobs, expectMoreTokens);
+				    allowGlobs, expectMoreTokens,
+				    allowPeriodInSymbol);
 	    FQIdentToken tok = parser.parse("");
 
 	    if (scanner.LA(1) != CharScanner.EOF_CHAR)
@@ -389,6 +424,6 @@ public class FQIdentParser {
     public static FQIdentifier parseFtraceIdentifier(String str)
         throws ExtraGarbageException, InvalidTokenException
     {
-	return parseFQIdentifier(str, false, true, false);
+	return parseFQIdentifier(str, false, true, false, true);
     }
 }
diff --git a/frysk-core/frysk/expr/FQIdentPattern.java b/frysk-core/frysk/expr/FQIdentPattern.java
new file mode 100644
index 0000000..03e0605
--- /dev/null
+++ b/frysk-core/frysk/expr/FQIdentPattern.java
@@ -0,0 +1,63 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2008, Red Hat Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+package frysk.expr;
+
+public interface FQIdentPattern {
+    /** Pattern will never match anything. */
+    public static final int CARD_NONE = 0;
+    /** Pattern will match at most one string. */
+    public static final int CARD_ONE = 1;
+    /** Pattern may match more than one string. */
+    public static final int CARD_MANY = 2;
+    /** Pattern will always match everything. */
+    public static final int CARD_ALL = 3;
+
+    /**
+     * Cardinality of this pattern.  See various CARD_ constants for
+     * possible values.
+     */
+    int cardinality();
+
+    /**
+     * Whether given string matches this pattern.  STR can be a symbol
+     * name, soname, etc.
+     */
+    boolean matches(String str);
+}
diff --git a/frysk-core/frysk/expr/FQIdentPatternAll.java b/frysk-core/frysk/expr/FQIdentPatternAll.java
new file mode 100644
index 0000000..4e2ad9e
--- /dev/null
+++ b/frysk-core/frysk/expr/FQIdentPatternAll.java
@@ -0,0 +1,62 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2008, Red Hat Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+package frysk.expr;
+
+/**
+ * Pattern for part of the FQ identifier that is missing.  Missing
+ * parts match everything.
+ */
+class FQIdentPatternAll implements FQIdentPattern {
+    public int cardinality() {
+	return CARD_ALL;
+    }
+    public boolean matches(String symbolName) {
+	return true;
+    }
+    public String toString() {
+	return "*";
+    }
+
+    /**
+     * Since we only ever need one instance of FQIdentPatternAll
+     * class, have it handy here.
+     */
+    public static final FQIdentPatternAll instance = new FQIdentPatternAll();
+}
diff --git a/frysk-core/frysk/expr/FQIdentPatternExact.java b/frysk-core/frysk/expr/FQIdentPatternExact.java
new file mode 100644
index 0000000..8cdc75f
--- /dev/null
+++ b/frysk-core/frysk/expr/FQIdentPatternExact.java
@@ -0,0 +1,61 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2008, Red Hat Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+package frysk.expr;
+
+/**
+ * Pattern for exactly specified part of FQ identifier.  Always
+ * matches at most one symbol.  If matches(a) and matches(b), then
+ * a.equals(b).
+ */
+class FQIdentPatternExact implements FQIdentPattern {
+    private final String symbolName;
+    public FQIdentPatternExact(String symbolName) {
+	this.symbolName = symbolName;
+    }
+    public int cardinality() {
+	return CARD_ONE;
+    }
+    public boolean matches(String symbolName) {
+	return symbolName.equals(this.symbolName);
+    }
+    public String toString() {
+	return symbolName;
+    }
+}
diff --git a/frysk-core/frysk/expr/FQIdentPatternGlob.java b/frysk-core/frysk/expr/FQIdentPatternGlob.java
new file mode 100644
index 0000000..918f11e
--- /dev/null
+++ b/frysk-core/frysk/expr/FQIdentPatternGlob.java
@@ -0,0 +1,64 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2008, Red Hat Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+package frysk.expr;
+
+import java.util.regex.Pattern;
+import frysk.util.Glob;
+
+/**
+ * Pattern for part of FQ identifier specified by a glob.
+ */
+class FQIdentPatternGlob implements FQIdentPattern {
+    private final Pattern pattern;
+    private final String glob;
+    public FQIdentPatternGlob(String glob) {
+	this.pattern = Glob.compile(glob);
+	this.glob = glob;
+    }
+    public int cardinality() {
+	return CARD_MANY;
+    }
+    public boolean matches(String symbolName) {
+	return pattern.matcher(symbolName).matches();
+    }
+    public String toString() {
+	return glob;
+    }
+}
diff --git a/frysk-core/frysk/expr/FQIdentToken.java b/frysk-core/frysk/expr/FQIdentToken.java
index fdb5f42..81a56ec 100644
--- a/frysk-core/frysk/expr/FQIdentToken.java
+++ b/frysk-core/frysk/expr/FQIdentToken.java
@@ -47,6 +47,9 @@ public class FQIdentToken
 	processId = null, threadId = null, frameNumber = null;
     public boolean wantPlt = false;
 
+    /** Whether the token may contain glob expressions. */
+    public boolean globs = false;
+
     public FQIdentToken(int t, String txt) {
 	super (t, txt);
     }
diff --git a/frysk-core/frysk/expr/FQIdentifier.java b/frysk-core/frysk/expr/FQIdentifier.java
index 0859363..e73fbbe 100644
--- a/frysk-core/frysk/expr/FQIdentifier.java
+++ b/frysk-core/frysk/expr/FQIdentifier.java
@@ -47,30 +47,42 @@ import frysk.proc.Task;
 
 public class FQIdentifier {
 
-    final public String soname;
-    final public String file;
-    final public Long line;
-    final public String proc;
-    final public String symbol;
-    final public String version;
+    final public FQIdentPattern soname;
+    final public FQIdentPattern file;
+    final public FQIdentPattern proc;
+    final public FQIdentPattern symbol;
+    final public FQIdentPattern version;
+
     final public boolean wantPlt;
+
+    final public Long line;
     final public Long processId;
     final public Long threadId;
     final public Long frameNumber;
 
     final private int metasoname;
-    final private static int soname_null = -1;
-    final private static int soname_name = 0;
-    final private static int soname_MAIN = 2;
-    final private static int soname_INTERP = 3;
+    final private static int SONAME_NULL = -1;
+    final private static int SONAME_NAME = 0;
+    final private static int SONAME_MAIN = 2;
+    final private static int SONAME_INTERP = 3;
     final private boolean sonameIsPath;
 
+
+    private FQIdentPattern getPatternFor(FQIdentToken tok, String str) {
+	if (str == null)
+	    return FQIdentPatternAll.instance;
+	else if (!tok.globs || !FQIdentParser.isWildcardPattern(str))
+	    return new FQIdentPatternExact(str);
+	else
+	    return new FQIdentPatternGlob(str);
+    }
+
     public FQIdentifier(FQIdentToken tok) {
-	this.soname = tok.dso;
-	this.file = tok.file;
-	this.proc = tok.proc;
-	this.symbol = tok.symbol;
-	this.version = tok.version;
+	this.soname = getPatternFor(tok, tok.dso);
+	this.file = getPatternFor(tok, tok.file);
+	this.proc = getPatternFor(tok, tok.proc);
+	this.symbol = getPatternFor(tok, tok.symbol);
+	this.version = getPatternFor(tok, tok.version);
 	this.wantPlt = tok.wantPlt;
 
 	if (tok.processId != null) {
@@ -88,22 +100,26 @@ public class FQIdentifier {
 	else
 	    this.line = null;
 
-	if (soname == null) {
+	if (tok.dso == null) {
 	    this.sonameIsPath = false;
-	    this.metasoname = soname_null;
+	    this.metasoname = SONAME_NULL;
 	} else {
-	    this.sonameIsPath = soname.indexOf('/') != -1;
-	    if (soname.equals("MAIN"))
-		this.metasoname = soname_MAIN;
-	    else if (soname.equals("INTERP"))
-		this.metasoname = soname_INTERP;
+	    this.sonameIsPath = tok.dso.indexOf('/') != -1;
+	    if (tok.dso.equals("MAIN"))
+		this.metasoname = SONAME_MAIN;
+	    else if (tok.dso.equals("INTERP"))
+		this.metasoname = SONAME_INTERP;
 	    else
-		this.metasoname = soname_name;
+		this.metasoname = SONAME_NAME;
 	}
     }
 
     public String toString() {
 	StringBuffer buf = new StringBuffer();
+	if (processId != null)
+	    buf.append('[').append(processId).append('.')
+	       .append(threadId).append('#').append(frameNumber)
+	       .append(']');
 	if (soname != null)
 	    buf.append('#').append(soname).append('#');
 	if (file != null)
@@ -121,35 +137,46 @@ public class FQIdentifier {
     }
 
     /**
-     * Translate MAIN and INTERP meta-sonames to main binary and
-     * dynamic linker of given task.
+     * Check if given ObjectFile WHAT matches this soname identifier.
      */
-    public String expandSoname(Task task) {
-	if (metasoname == soname_null)
-	    return null;
-	else if (metasoname == soname_name)
-	    return soname;
+    public boolean sonameMatches(Task task, ObjectFile what) {
+	if (metasoname == SONAME_NULL
+	    || soname.cardinality() == FQIdentPattern.CARD_ALL)
+	    return true;
+
+	else if (sonameIsPath)
+	    return soname.matches(what.getFilename().getPath());
+
+	else if (metasoname == SONAME_NAME)
+	    return soname.matches(what.getSoname());
+
 	else {
 	    // Don't cache so that the identifier is usable for
 	    // multiple tasks.
 	    String path = task.getProc().getExeFile().getSysRootedPath();
 	    ObjectFile objf = ObjectFile.buildFromFile(path);
-	    if (metasoname == soname_MAIN)
-		return objf.getSoname();
+	    if (metasoname == SONAME_MAIN)
+		return objf.getSoname().equals(what.getSoname());
 	    else
-		return ObjectFile.buildFromFile(objf.getInterp()).getSoname();
+		return ObjectFile.buildFromFile(objf.getInterp())
+		    .getSoname().equals(what.getSoname());
 	}
     }
 
     /**
-     * Check if given ObjectFile WHAT matches this soname identifier.
+     * Whether this identifier is plain, i.e. has no qualification.
+     * PLT references are not considered plain symbols.
      */
-    public boolean sonameMatches(Task task, ObjectFile what) {
-	if (metasoname == soname_null)
-	    return true;
-	else if (sonameIsPath)
-	    return soname.equals(what.getFilename().getPath());
-	else
-	    return this.expandSoname(task).equals(what.getSoname());
+    public boolean isPlain() {
+	return soname.cardinality() == FQIdentPattern.CARD_ALL
+	    && file.cardinality() == FQIdentPattern.CARD_ALL
+	    && line == null
+	    && proc.cardinality() == FQIdentPattern.CARD_ALL
+	    && symbol.cardinality() == FQIdentPattern.CARD_ALL
+	    && version.cardinality() == FQIdentPattern.CARD_ALL
+	    && wantPlt == false
+	    && processId == null
+	    && threadId == null
+	    && frameNumber == null;
     }
 }
diff --git a/frysk-core/frysk/expr/ScratchSymTab.java b/frysk-core/frysk/expr/ScratchSymTab.java
index 6d69620..2f447aa 100644
--- a/frysk-core/frysk/expr/ScratchSymTab.java
+++ b/frysk-core/frysk/expr/ScratchSymTab.java
@@ -48,43 +48,44 @@ import frysk.value.ObjectDeclaration;
 import frysk.value.Type;
 import frysk.value.Value;
 import frysk.scopes.Variable;
+import frysk.UserException;
 
 public class ScratchSymTab implements ExprSymTab {
     /**
      * Lookup S, assuming S is variable or constant.
      */
     public Value getValue(String s) {
-	throw new RuntimeException("no values");
+	throw new UserException("no values");
     }
     /**
      * Lookup S, assuming S is a variable.
      */
     public ObjectDeclaration getObjectInScope(DebugInfoFrame frame, String s) {
-	throw new RuntimeException("no variables");
+	throw new UserException("no variables");
     }
     /**
      * The byte order to use when creating new values.
      */
     public ByteOrder order() {
-	throw new RuntimeException("no byte-order");
+	throw new UserException("no byte-order");
     }
     /**
      * Return the task's memory buffer
      */
     public ByteBuffer taskMemory() {
-	throw new RuntimeException("no memory");
+	throw new UserException("no memory");
     }
     /**
      * Return the variable's value.
      */
     public Value getValue(Variable v) {
-	throw new RuntimeException("no values");
+	throw new UserException("no values");
     }
     /**
      * Given a variable, return its type.
      */
     public Type getType(Variable variable) {
-	throw new RuntimeException("no types");
+	throw new UserException("no types");
     }
     /**
      * Return the wordsize.
diff --git a/frysk-core/frysk/expr/TestArithmetics.java b/frysk-core/frysk/expr/TestArithmetics.java
index f537eaa..7cd9b2a 100644
--- a/frysk-core/frysk/expr/TestArithmetics.java
+++ b/frysk-core/frysk/expr/TestArithmetics.java
@@ -74,7 +74,20 @@ public class TestArithmetics extends TestCase {
     public void testDecrement() {
 	checkVariableExpr("a.kappa-- + --a.kappa", 0); 
     }
-    
+
+    public void testArrayAccess() {
+	checkVariableExpr("arr[0]", 0x01020304);
+	checkVariableExpr("arr[1]", 0x05060708);
+    }
+
+    public void testArraySlice() {
+	checkVariableExpr("arr[1:2][0]", 0x05060708);
+	checkVariableExpr("arr[1:2][1]", 0x09101112);
+	checkVariableExpr("arr[0:2][0:1][0:0][0]", 0x01020304);
+	checkVariableExpr("arr[0:2][1:2][0:0][0]", 0x05060708);
+	checkVariableExpr("arr[0:2][1:2][0:1][1]", 0x09101112);
+    }
+
     private void checkErrorExpr(String input, String error) {
 	Throwable t = null;
 	try {
@@ -95,7 +108,6 @@ public class TestArithmetics extends TestCase {
     public void testTokenError() {
 	checkErrorExpr("1...2", "unexpected input: expecting '.', found '2'");
     }
-    
     // Testing types
     private void checkExprType (String expr, String resultType){
 	ExprSymTab symTab = new TestbedSymTab();
diff --git a/frysk-core/frysk/expr/TestbedSymTab.java b/frysk-core/frysk/expr/TestbedSymTab.java
index b01806b..866f519 100644
--- a/frysk-core/frysk/expr/TestbedSymTab.java
+++ b/frysk-core/frysk/expr/TestbedSymTab.java
@@ -42,19 +42,22 @@ package frysk.expr;
 import inua.eio.ByteBuffer;
 import inua.eio.ByteOrder;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+
 import frysk.config.Host;
 import frysk.debuginfo.DebugInfoFrame;
 import frysk.scopes.SourceLocation;
+import frysk.scopes.Variable;
+import frysk.value.ArrayType;
 import frysk.value.ClassType;
 import frysk.value.ObjectDeclaration;
 import frysk.value.ScratchLocation;
 import frysk.value.StandardTypes;
 import frysk.value.Type;
 import frysk.value.Value;
-import frysk.scopes.Variable;
 
 class TestbedSymTab implements ExprSymTab {
     private final SourceLocation scratchSourceLocation = SourceLocation.UNKNOWN;
@@ -74,6 +77,20 @@ class TestbedSymTab implements ExprSymTab {
     };
     private Value c1 = new Value(classType, new ScratchLocation(buf));
 
+    private static ArrayList dims() {
+	final ArrayList a = new ArrayList();
+	a.add(new Integer(3));
+	return a;
+    }
+    private Type arrayType = new ArrayType(StandardTypes.INT32B_T, 12, dims());
+    private byte[] arrayBuf = {
+	0x01, 0x02, 0x03, 0x04,
+	0x05, 0x06, 0x07, 0x08,
+	0x09, 0x10, 0x11, 0x12
+    };
+    private ScratchLocation arrayScratch = new ScratchLocation(arrayBuf);
+    private Value arr = new Value(arrayType, arrayScratch);
+
     private HashMap symtab;
     TestbedSymTab () {
 	symtab = new HashMap();
@@ -81,6 +98,7 @@ class TestbedSymTab implements ExprSymTab {
 	symtab.put("b1", c1);
 	symtab.put("b2", c1);
 	symtab.put("c123", c1);
+	symtab.put("arr", arr);
     }
 
     /**
@@ -108,7 +126,7 @@ class TestbedSymTab implements ExprSymTab {
      * Return the task's memory buffer.
      */
     public ByteBuffer taskMemory() {
-	throw new RuntimeException("no memory");
+	return null;
     }
     /**
      * Return the variable's value.
diff --git a/frysk-core/frysk/ftrace/ChangeLog b/frysk-core/frysk/ftrace/ChangeLog
index 19fd300..e2943d3 100644
--- a/frysk-core/frysk/ftrace/ChangeLog
+++ b/frysk-core/frysk/ftrace/ChangeLog
@@ -1,3 +1,21 @@
+2008-06-20  Petr Machata  <pmachata@redhat.com>
+
+	* Ftrace.java (getDriversForTask): Drop.
+	(driversForTask): Actually use it as a map(task->driver), instead
+	of map(task->map(mapping_path->driver)).
+	* TaskTracer.java (FunctionReturnObserver.add): Compare symbol
+	names via .equals, instead of comparing symbol pointers.
+
+2008-06-20  Petr Machata  <pmachata@redhat.com>
+
+	* Reporter.java: Keep a list of event entry tokens, and align
+	eventLeave with matching eventEntry.
+
+2008-06-10  Andrew Cagney  <cagney@redhat.com>
+
+	* Ftrace.java: Use PrintDebugInfoStackOptions.
+	* Reporter.java: Ditto.
+
 2008-06-05  Petr Machata  <pmachata@redhat.com>
 
 	* Ftrace.java: Fix race in attaching various task observers.
diff --git a/frysk-core/frysk/ftrace/Ftrace.java b/frysk-core/frysk/ftrace/Ftrace.java
index 68ecadb..b19c39e 100644
--- a/frysk-core/frysk/ftrace/Ftrace.java
+++ b/frysk-core/frysk/ftrace/Ftrace.java
@@ -47,7 +47,7 @@ import java.util.Set;
 
 import inua.util.PrintWriter;
 
-import frysk.debuginfo.PrintStackOptions;
+import frysk.debuginfo.PrintDebugInfoStackOptions;
 import frysk.dwfl.ObjectFile;
 import frysk.event.Event;
 import frysk.isa.signals.Signal;
@@ -75,9 +75,9 @@ public class Ftrace {
     static private final Log finest = LogFactory.finest(Ftrace.class);
     static private final Log warning = LogFactory.warning(Ftrace.class);
 
-    private final PrintStackOptions stackPrintOptions;
+    private final PrintDebugInfoStackOptions stackPrintOptions;
 
-    public Ftrace(PrintStackOptions stackPrintOptions) {
+    public Ftrace(PrintDebugInfoStackOptions stackPrintOptions) {
 	this.stackPrintOptions = stackPrintOptions;
     }
 
@@ -654,15 +654,6 @@ public class Ftrace {
 	    return ObjectFile.buildFromFile(mapping.path);
 	}
 
-	private Map getDriversForTask(Task task) {
-	    Map drivers = (Map)driversForTask.get(task);
-	    if (drivers == null) {
-		drivers = new HashMap();
-		driversForTask.put(task, drivers);
-	    }
-	    return drivers;
-	}
-
 	public Action updateMappedFile(Task task, MemoryMapping mapping) {
 
 	    if (traceMmapUnmap)
@@ -677,10 +668,12 @@ public class Ftrace {
 
 	    DwflModule module = getModuleForFile(task, mapping.path);
 
-	    Map drivers = getDriversForTask(task);
-	    Driver driver = new TaskTracer(Ftrace.this, task);
-	    drivers.put(mapping.path, driver);
-	    this.tracingController.fileMapped(task, objf, module, driver);
+	    Driver driver = (Driver)driversForTask.get(task);
+	    if (driver == null) {
+		driver = new TaskTracer(Ftrace.this, task);
+		driversForTask.put(task, driver);
+	    }
+	    tracingController.fileMapped(task, objf, module, driver);
 
 	    task.requestUnblock(this);
 	    return Action.BLOCK;
@@ -700,8 +693,7 @@ public class Ftrace {
 
 	    DwflModule module = getModuleForFile(task, mapping.path);
 
-	    Map drivers = getDriversForTask(task);
-	    Driver driver = (Driver)drivers.get(mapping.path);
+	    Driver driver = (Driver)driversForTask.get(task);
 	    if (driver == null)
 		throw new AssertionError("There should be a driver for `" + mapping.path + "'.");
 
diff --git a/frysk-core/frysk/ftrace/Reporter.java b/frysk-core/frysk/ftrace/Reporter.java
index 3ed019b..876fc77 100644
--- a/frysk-core/frysk/ftrace/Reporter.java
+++ b/frysk-core/frysk/ftrace/Reporter.java
@@ -40,10 +40,11 @@
 package frysk.ftrace;
 
 import java.util.HashMap;
+import java.util.ArrayList;
 
 import inua.util.PrintWriter;
 
-import frysk.debuginfo.PrintStackOptions;
+import frysk.debuginfo.PrintDebugInfoStackOptions;
 import frysk.proc.Task;
 import frysk.util.ArchFormatter;
 import frysk.util.StackPrintUtil;
@@ -53,28 +54,29 @@ class Reporter
     private PrintWriter writer;
     private Object lastItem = null;
     private Task lastTask = null;
-    private HashMap levelMap = new HashMap();
-    private final PrintStackOptions stackPrintOptions;
+
+    // HashMap<Task, ArrayList<Object>> -- array of entry tokens for each taks
+    private final HashMap tokenMap = new HashMap();
+
+    private final PrintDebugInfoStackOptions stackPrintOptions;
     private final boolean showPC;
 
-    public Reporter(PrintWriter writer, PrintStackOptions stackPrintOptions, boolean show) {
+    public Reporter(PrintWriter writer,
+		    PrintDebugInfoStackOptions stackPrintOptions,
+		    boolean show) {
 	this.writer = writer;
 	this.stackPrintOptions = stackPrintOptions;
 	this.showPC = show;
     }
 
-    private int getLevel(Task task)
+    private ArrayList getTokens(Task task)
     {
-	int level = 0;
-	Integer l = (Integer)levelMap.get(task);
-	if (l != null)
-	    level = l.intValue();
-	return level;
-    }
-
-    private void setLevel(Task task, int level)
-    {
-	levelMap.put(task, new Integer(level));
+	ArrayList l = (ArrayList)tokenMap.get(task);
+	if (l == null) {
+	    l = new ArrayList();
+	    tokenMap.put(task, l);
+	}
+	return l;
     }
 
     private boolean lineOpened()
@@ -136,9 +138,9 @@ class Reporter
     public void eventEntry(Task task, Object item, String eventType,
 			    String eventName, Object[] args)
     {
-	int level = this.getLevel(task);
-	String spaces = ArchFormatter.repeat(' ', level);
-	this.setLevel(task, ++level);
+	ArrayList tokens = getTokens(task);
+	String spaces = ArchFormatter.repeat(' ', tokens.size());
+	tokens.add(item);
 
 	if (lineOpened())
 	    writer.println('\\');
@@ -156,16 +158,24 @@ class Reporter
     public void eventLeave(Task task, Object item, String eventType,
 			    String eventName, Object retVal)
     {
-	int level = this.getLevel(task);
-	this.setLevel(task, --level);
+	String stray = "";
+
+	ArrayList tokens = getTokens(task);
+	int i = tokens.size() - 1;
+	while (i >= 0 && tokens.get(i) != item)
+	    --i;
+	if (i < 0)
+	    stray = "stray ";
+	else
+	    tokens.subList(i, tokens.size()).clear();
 
 	if (!myLineOpened(task, item)) {
 	    if (lineOpened())
 		writer.println();
-	    String spaces = ArchFormatter.repeat(' ', level);
+	    String spaces = ArchFormatter.repeat(' ', tokens.size());
 	    writer.print(pidInfo(task)
 			 + " " + formatTaskPC(task)
-			 + spaces + eventType
+			 + spaces + stray + eventType
 			 + " " + eventName);
 	}
 
@@ -182,12 +192,12 @@ class Reporter
 
     public void eventSingle(Task task, String eventName, Object[] args)
     {
-	int level = this.getLevel(task);
+	ArrayList tokens = getTokens(task);
 	if (lineOpened())
 	    writer.println("\\");
 	writer.print(pidInfo(task)
 		     + " " + formatTaskPC(task)
-		     + ArchFormatter.repeat(' ', level)
+		     + ArchFormatter.repeat(' ', tokens.size())
 		     + eventName);
 
 	if (args != null)
diff --git a/frysk-core/frysk/ftrace/SymbolRule.java b/frysk-core/frysk/ftrace/SymbolRule.java
index 07a667f..6b1e18c 100644
--- a/frysk-core/frysk/ftrace/SymbolRule.java
+++ b/frysk-core/frysk/ftrace/SymbolRule.java
@@ -86,8 +86,7 @@ public class SymbolRule extends Rule {
 
     protected boolean checkNameMatches(final DwflSymbol symbol)
     {
-	if (fqid.symbol.equals(symbol.getName()))
-	    return true;
+	return fqid.symbol.matches(symbol.getName());
 
 	// XXX Alias support didn't arrive yet.
 	/*
@@ -98,8 +97,6 @@ public class SymbolRule extends Rule {
 		    return true;
 	    }
 	*/
-
-	return false;
     }
 
     public boolean matches(Object traceable) {
diff --git a/frysk-core/frysk/ftrace/TaskTracer.java b/frysk-core/frysk/ftrace/TaskTracer.java
index 0ae6b0f..1aff7b6 100644
--- a/frysk-core/frysk/ftrace/TaskTracer.java
+++ b/frysk-core/frysk/ftrace/TaskTracer.java
@@ -81,6 +81,7 @@ class TaskTracer
     private final Ftrace ftrace;
 
     public TaskTracer(Ftrace ftrace, Task task) {
+	fine.log("New TaskTracer for", task);
 	this.arch = ArchFactory.instance.getArch(task);
 	this.ftrace = ftrace;
     }
@@ -89,7 +90,20 @@ class TaskTracer
     {
 	private final DwflSymbol symbol;
 	private final boolean isPlt;
+
+	/**
+	 * TracePoint is chained when it shares return breakpoint with
+	 * other breakpoint.  When such a breakpoint is hit, it is
+	 * assumed that both tracepoints have "left".  This is used
+	 * when both PLT and regular entry point are traced for one
+	 * symbol.  If PLT entry point hits, and regular entry point
+	 * for the same symbol hits immediately after that, the two
+	 * are chained.
+	 */
 	private boolean chained = false;
+
+	// When the TracePoint is frozen, it can't be chained to
+	// another TracePoint anymore.
 	private boolean frozen = false;
 
 	public TracePoint(DwflSymbol symbol) {
@@ -119,6 +133,7 @@ class TaskTracer
 	}
 
 	public void setChained() {
+	    fine.log("chained tracePoint", this);
 	    this.chained = true;
 	}
 
@@ -169,7 +184,8 @@ class TaskTracer
 		TracePoint previous = (TracePoint)symbolList.getLast();
 		if (!previous.isFrozen()
 		    && previous.isPlt() && !tracePoint.isPlt()
-		    && previous.getSymbol() == tracePoint.getSymbol())
+		    && previous.getSymbol().getName().equals
+		       (tracePoint.getSymbol().getName()))
 		    tracePoint.setChained();
 
 		previous.freeze();
diff --git a/frysk-core/frysk/hpd/CLI.java b/frysk-core/frysk/hpd/CLI.java
index 30bb51a..eb1533c 100644
--- a/frysk-core/frysk/hpd/CLI.java
+++ b/frysk-core/frysk/hpd/CLI.java
@@ -39,6 +39,7 @@
 
 package frysk.hpd;
 
+import frysk.UserException;
 import frysk.expr.ExprSearchEngine;
 import java.io.PrintWriter;
 import java.io.Writer;
@@ -139,9 +140,9 @@ public class CLI {
 	try {
 	    return topLevelCommand.complete(this, new Input(buffer), cursor,
 					    candidates);
-	} catch (RuntimeException e) {
-	    if (nasty(e))
-		e.printStackTrace(outWriter);
+	} catch (UserException e) {
+	    // If anything user related fails, just give up on the
+	    // completion.
 	    return -1;
 	}
     }
@@ -184,6 +185,10 @@ public class CLI {
         // Assign this proc to the passed in procID 
         else
             idManager.manageProc(proc, this.taskID);
+        // Add this process to the runningProcs table
+        synchronized (this) {
+		this.runningProcs.add(proc);
+	    }
     }
 
     /**
@@ -296,33 +301,14 @@ public class CLI {
 	return null;
     }
     
-    /**
-     * Identify "nasty", or internal exceptions; these are the
-     * RuntimeExceptions thrown by the Java system.
-     */
-    private boolean nasty(Exception e) {
-	Throwable cause = e;
-	while (true) {
-	    Throwable c = cause.getCause();
-	    if (c == null)
-		break;
-	    cause = c;
-	}
-	return (cause instanceof NullPointerException
-		|| cause instanceof ArrayIndexOutOfBoundsException
-		|| cause instanceof ArrayStoreException
-		|| cause instanceof ClassCastException
-		|| e.getMessage() == null);
-    }
-
     void printError(Exception e) {
-	if (nasty(e)) {
+	if (e instanceof UserException) {
+	    outWriter.print("Error: ");
+	    outWriter.println(e.getMessage());
+	} else {
 	    outWriter.print("Internal Error: ");
 	    e.printStackTrace(outWriter);
 	    outWriter.println();
-	} else {
-	    outWriter.print("Error: ");
-	    outWriter.println(e.getMessage());
 	}
     }
 
diff --git a/frysk-core/frysk/hpd/ChangeLog b/frysk-core/frysk/hpd/ChangeLog
index 61bfb02..87a1322 100644
--- a/frysk-core/frysk/hpd/ChangeLog
+++ b/frysk-core/frysk/hpd/ChangeLog
@@ -1,3 +1,43 @@
+2008-06-26  Rick Moseley  <rmoseley@redhat.com>
+
+	* CLI.java: Fix bz 6696.
+	* DetachCommand.java: Ditto.
+	* KillCommand.java: Ditto.
+	* TestKillCommand.java: Add test for fix.
+
+
+2008-06-17  Teresa Thomas  <tthomas@redhat.com>
+
+	* TestWatchCommand.java (testWritePrevValue): New test.
+	
+2008-06-12  Andrew Cagney  <cagney@redhat.com>
+
+	* CLI.java (nasty()): Delete.
+	(printError(Exception)): Check for UserException.
+	* InvalidCommandException.java: Extend UserException.
+	
+2008-06-11  Rick Moseley  <rmoseley@redhat.com>
+
+	* TestCoreCommand.java: Fix bz #6614.
+
+2008-06-11  Teresa Thomas  <tthomas@redhat.com>
+
+	* TestWatchCommand.java (testWatchArraySlice): New test.
+
+2008-06-11  Andrew Cagney  <cagney@redhat.com>
+
+	* TestBreakpoints.java: Update to match backtrace output.
+
+2008-06-10  Andrew Cagney  <cagney@redhat.com>
+
+	* StackCommands.java: Use setPrintPaths.
+
+2008-06-10  Rick Moseley  <rmoseley@redhat.com>
+
+	* StartRun.java: Do not kill core procs.
+	* CoreCommand.java: Redo hash keys for core proc HashMap.
+	* TestCoreCommand.java: Add test cases.
+
 2008-06-06  Sami Wagiaalla  <swagiaal@redhat.com>
 
 	* TestFhpdThreads.java 
diff --git a/frysk-core/frysk/hpd/CoreCommand.java b/frysk-core/frysk/hpd/CoreCommand.java
index ced6d22..eda33ff 100644
--- a/frysk-core/frysk/hpd/CoreCommand.java
+++ b/frysk-core/frysk/hpd/CoreCommand.java
@@ -119,7 +119,7 @@ public class CoreCommand extends ParameterizedCommand {
     }
 
     public static void load(Proc coreProc, CLI cli) {
-    load(coreProc, cli, null);
+	load(coreProc, cli, null);
     }
 
     public static void load(Proc coreProc, CLI cli, String sysroot) {
@@ -139,7 +139,7 @@ public class CoreCommand extends ParameterizedCommand {
 	}
 	// Finally, done.
 	synchronized (cli) {
-	    cli.coreProcs.put(coreProc, new Integer(procID));
+	    cli.coreProcs.put(new Integer(procID), coreProc);
 	    cli.ptsetParams.put(new Integer(procID), coreProc.getCmdLine());
 	}
 	cli.outWriter.println("Attached to core file: "
diff --git a/frysk-core/frysk/hpd/DetachCommand.java b/frysk-core/frysk/hpd/DetachCommand.java
index b76a603..e98e5a3 100644
--- a/frysk-core/frysk/hpd/DetachCommand.java
+++ b/frysk-core/frysk/hpd/DetachCommand.java
@@ -1,6 +1,6 @@
 // This file is part of the program FRYSK.
 //
-// Copyright 2005, 2006, 2007 Red Hat Inc.
+// Copyright 2005, 2006, 2007, 2008 Red Hat Inc.
 //
 // FRYSK is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by
@@ -72,12 +72,15 @@ class DetachCommand extends ParameterizedCommand {
 	    synchronized (cli) {
 		startedByRun = cli.runningProcs.contains(proc);
 	    }
-	    if (startedByRun)
+	    if (!startedByRun)
 		continue;
 	    // Delete all breakpoints.
 	    if (cli.steppingObserver != null)
 		cli.getSteppingEngine().removeObserver(cli.steppingObserver,
 			proc, true);
+	    synchronized (cli) {
+		cli.runningProcs.remove(proc);
+	    }
 	}
     }
 
diff --git a/frysk-core/frysk/hpd/InvalidCommandException.java b/frysk-core/frysk/hpd/InvalidCommandException.java
index 8fcd5c5..8bbb585 100644
--- a/frysk-core/frysk/hpd/InvalidCommandException.java
+++ b/frysk-core/frysk/hpd/InvalidCommandException.java
@@ -1,6 +1,6 @@
 // This file is part of the program FRYSK.
 //
-// Copyright 2007 Red Hat Inc.
+// Copyright 2007, 2008 Red Hat Inc.
 //
 // FRYSK is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by
@@ -39,10 +39,12 @@
 
 package frysk.hpd;
 
+import frysk.UserException;
+
 /**
  * The command was invalid.
  */
-public class InvalidCommandException extends RuntimeException {
+public class InvalidCommandException extends UserException {
     static final long serialVersionUID = 1;
     InvalidCommandException(String message) {
 	super(message);
diff --git a/frysk-core/frysk/hpd/KillCommand.java b/frysk-core/frysk/hpd/KillCommand.java
index a05f1cf..cf7dabc 100644
--- a/frysk-core/frysk/hpd/KillCommand.java
+++ b/frysk-core/frysk/hpd/KillCommand.java
@@ -156,6 +156,9 @@ public class KillCommand extends ParameterizedCommand {
 		procPID = proc.getPid();
 		// Now, call the Proc object to kill off the executable(s)
 		proc.requestKill();
+		synchronized (cli) {
+		    cli.runningProcs.remove(proc);
+		}
 		if ((pid > 0))
 		    return true;
 	    }
@@ -202,17 +205,14 @@ public class KillCommand extends ParameterizedCommand {
 			+ " that was created from " + proc.getExeFile().getSysRootedPath(),
 			Message.TYPE_NORMAL);
 		    proc.requestKill();
+		    synchronized (cli) {
+			cli.runningProcs.remove(proc);
+		    }
 		    tempId = procId;
 		    returnProc = true;
 		}
 	    }
 	}
-	if (returnProc) {
-	    synchronized (cli) {
-		// Clear the running procs set
-		cli.runningProcs.clear();
-	    }
-	}
 	return returnProc;
     }
 
diff --git a/frysk-core/frysk/hpd/StackCommands.java b/frysk-core/frysk/hpd/StackCommands.java
index 8fd8a9f..16f183a 100644
--- a/frysk-core/frysk/hpd/StackCommands.java
+++ b/frysk-core/frysk/hpd/StackCommands.java
@@ -1,6 +1,6 @@
 // This file is part of the program FRYSK.
 //
-// Copyright 2005, 2006, 2007 Red Hat Inc.
+// Copyright 2005, 2006, 2007, 2008 Red Hat Inc.
 //
 // FRYSK is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by
@@ -41,10 +41,9 @@ package frysk.hpd;
 
 import java.util.Iterator;
 import java.util.List;
-
 import frysk.debuginfo.DebugInfoFrame;
 import frysk.debuginfo.DebugInfoStackFactory;
-import frysk.debuginfo.PrintStackOptions;
+import frysk.debuginfo.PrintDebugInfoStackOptions;
 import frysk.proc.Task;
 
 abstract class StackCommands extends ParameterizedCommand {
@@ -71,11 +70,12 @@ abstract class StackCommands extends ParameterizedCommand {
 
     static private void printStack(CLI cli, DebugInfoFrame frame,
 				   int stopLevel, Options options) {
-	PrintStackOptions printStackOptions = new PrintStackOptions();
+	PrintDebugInfoStackOptions printStackOptions
+	    = new PrintDebugInfoStackOptions();
 	printStackOptions.setNumberOfFrames(stopLevel);
-	printStackOptions.setPrintParams(true);
+	printStackOptions.setPrintParameters(true);
 	printStackOptions.setPrintLocals(options.printLocals);
-	printStackOptions.setPrintFullPaths(true);
+	printStackOptions.setPrintPaths(true);
 	
 	DebugInfoStackFactory.printStackTrace(cli.outWriter, frame,
 					      printStackOptions);
diff --git a/frysk-core/frysk/hpd/StartRun.java b/frysk-core/frysk/hpd/StartRun.java
index 56bdc50..8a25ad1 100644
--- a/frysk-core/frysk/hpd/StartRun.java
+++ b/frysk-core/frysk/hpd/StartRun.java
@@ -168,11 +168,9 @@ abstract class StartRun extends ParameterizedCommand {
 		    cli.loadedProcs.remove(task.getProc());
 		}
 	    }
-	    // Take care of core procs
-	    // XXX: need to take care of parameters here that were passed into the
-	    //      process that created the core file    
+	    // Take care of core procs  
 	    else if (!cli.coreProcs.isEmpty() &&
-		    cli.coreProcs.containsKey(task.getProc())) {
+		    cli.coreProcs.containsKey(new Integer(taskData.getParentID()))) {
 		run(cli, cmd, task.getProc().getExeFile().getSysRootedPath(), 
 			runToBreak, taskData.getParentID());
 		synchronized (cli) {
@@ -265,8 +263,12 @@ abstract class StartRun extends ParameterizedCommand {
 	while (foo.hasNext()) {
 	    taskData = (TaskData) foo.next();
 	    Task task = taskData.getTask();
-	    if (task.getProc().getPid() != oldPid && 
-		    task.getProc().getPid() > 0) {
+	    // Kill a proc only once
+	    if (task.getProc().getPid() != oldPid &&
+		    // Don't kill loaded procs, don't have a PID assigned yet
+		    task.getProc().getPid() > 0 &&
+		    // Don't kill core procs either, they have the old PID number
+		    cli.coreProcs.get(new Integer(taskData.getParentID())) == null) {
 		cli.execCommand("kill " + task.getProc().getPid() + "\n");
 		oldPid = task.getProc().getPid();
 	    }
diff --git a/frysk-core/frysk/hpd/TestBreakpoints.java b/frysk-core/frysk/hpd/TestBreakpoints.java
index 2fe15a3..7a8d12c 100644
--- a/frysk-core/frysk/hpd/TestBreakpoints.java
+++ b/frysk-core/frysk/hpd/TestBreakpoints.java
@@ -96,7 +96,7 @@ public class TestBreakpoints
 	e.send("go\n");
 	e.expect("go.*" + prompt + ".*Breakpoint.*sin.*");
 	e.send("where\n");
-	e.expect("where.*#0.* (__)?sin \\(\\).*" + prompt);
+	e.expect("where.*#0.* (__)?sin\\(\\).*" + prompt);
 	e.send("quit\n");
 	e.expect("Quitting...");
 	e.close();
diff --git a/frysk-core/frysk/hpd/TestCoreCommand.java b/frysk-core/frysk/hpd/TestCoreCommand.java
index 787edf8..5179d6d 100644
--- a/frysk-core/frysk/hpd/TestCoreCommand.java
+++ b/frysk-core/frysk/hpd/TestCoreCommand.java
@@ -42,7 +42,9 @@ package frysk.hpd;
 import java.io.File;
 import frysk.testbed.CorefileFactory;
 import frysk.testbed.SlaveOffspring;
+//import frysk.testbed.DaemonBlockedAtSignal;
 import frysk.config.Prefix;
+//import frysk.proc.Proc;
 
 public class TestCoreCommand extends TestLib {
 
@@ -106,4 +108,18 @@ public class TestCoreCommand extends TestLib {
 	e.expect("Quitting\\.\\.\\.");
 	e.close();
     }
+    
+    public void testCoreLoadedParamsTwo() {
+
+	File exe = new File("/bin/echo");
+	File core = CorefileFactory.constructCoreAtEntry(exe, new String[] {"abcd"});
+	e = new HpdTestbed();
+	e.sendCommandExpectPrompt("core " + core.getPath(), "Attached to core.*");
+	e.sendCommandExpectPrompt("info args", "abcd.*");
+	e.sendCommandExpectPrompt("run", "running.*abcd.*" +
+		"Attached to process ([0-9]+).*" + "Running process ([0-9]+).*");
+	e.send("quit\n");
+	e.expect("Quitting\\.\\.\\.");
+	e.close();
+    }
 }
diff --git a/frysk-core/frysk/hpd/TestKillCommand.java b/frysk-core/frysk/hpd/TestKillCommand.java
index 4a5446c..e3711d9 100644
--- a/frysk-core/frysk/hpd/TestKillCommand.java
+++ b/frysk-core/frysk/hpd/TestKillCommand.java
@@ -196,6 +196,37 @@ java.lang.NullPointerException
     }
     
     /**
+     * Test killing of a single proc NOT using the PID
+     */
+    public void testKillAfterAttach() {
+	SlaveOffspring newProc = SlaveOffspring.createDaemon();
+	int pid = newProc.getPid().intValue();
+	e = new HpdTestbed();
+	e.sendCommandExpectPrompt("attach " + pid, "Attached to process " + pid + ".*");
+	e.sendCommandExpectPrompt("kill", "Killing process " + pid + ".*");
+	try { Thread.sleep(500); } catch (Exception e) { }
+	e.send("quit\n");
+	e.expect("Quitting\\.\\.\\..*");
+	e.close();
+    }
+    
+    /**
+     * Test killing of a single proc and then running
+     */
+    public void testKillAfterAttachThenRun() {
+	SlaveOffspring newProc = SlaveOffspring.createDaemon();
+	int pid = newProc.getPid().intValue();
+	e = new HpdTestbed();
+	e.sendCommandExpectPrompt("attach " + pid, "Attached to process " + pid + ".*");
+	e.sendCommandExpectPrompt("kill", "Killing process " + pid + ".*");
+	try { Thread.sleep(500); } catch (Exception e) { }
+	e.sendCommandExpectPrompt("run", "running with this command.*");
+	e.send("quit\n");
+	e.expect("Quitting\\.\\.\\..*");
+	e.close();
+    }
+    
+    /**
      * Test entering a non-integer as a PID
      */
     public void testKillError() {
diff --git a/frysk-core/frysk/hpd/TestWatchCommand.java b/frysk-core/frysk/hpd/TestWatchCommand.java
index dbacbb4..c52a756 100644
--- a/frysk-core/frysk/hpd/TestWatchCommand.java
+++ b/frysk-core/frysk/hpd/TestWatchCommand.java
@@ -140,13 +140,26 @@ public class TestWatchCommand extends TestLib {
       e.close();
   }   
   
+  public void testWatchArraySlice() {
+      e = new HpdTestbed();
+      e.sendCommandExpectPrompt("load " + Prefix.pkgLibFile("funit-ctypes").getPath(),
+                                "Loaded executable file.*");
+      e.sendCommandExpectPrompt("start", "Attached to process.*");
+      
+      e.send("watch array[ 0:1]\n"); 
+      e.expect(".*Uses [1-9]+ debug register.*");
+      
+      e.send("quit\n");
+      e.expect("Quitting\\.\\.\\.");
+      e.close();
+  }   
+  
   /*
    * Test to watch a data type whose size is larger than
    * that can be watched by all hardware watch registers
    * put together.
-   */
-  public void testWatchOversized()
-  {
+   */  
+  public void testWatchOversized() {
       e = new HpdTestbed();
       e.sendCommandExpectPrompt("load " + Prefix.pkgLibFile("funit-ctypes").getPath(),
                                 "Loaded executable file.*");
@@ -158,8 +171,8 @@ public class TestWatchCommand extends TestLib {
       
       e.send("quit\n");
       e.expect("Quitting\\.\\.\\.");
-      e.close();
-  }   
+      e.close();       
+  }
   
   /*
    * Test to watch a variable that is smaller than the max
@@ -207,7 +220,30 @@ public class TestWatchCommand extends TestLib {
       e.close();     
   }
 
-  
+  /*
+   * Test to check if user notified when value being
+   * written to is the same as previous value.
+   */
+  public void testWritePrevValue() {
+      e = new HpdTestbed();
+      e.sendCommandExpectPrompt("load " + Prefix.pkgLibFile("funit-ctypes").getPath(),
+                                "Loaded executable file.*");
+      e.send("break main\n");	
+      e.expect("breakpoint.*" + prompt);
+      e.send("run\n");
+      e.expect("Attached to process ([0-9]+).*"); 
+      
+      e.send("watch float_\n"); 
+      e.expect(".*Watchpoint set: float_.*");
+      
+      e.send("go\n"); 
+      e.expect(".*Note: Value unchanged before and after access.*");
+      
+      e.send("quit\n");
+      e.expect("Quitting\\.\\.\\.");
+      e.close();        
+  }
+
   private Task getStoppedTask() {
       return this.getStoppedTask("funit-ctypes");
   }
diff --git a/frysk-core/frysk/isa/watchpoints/ChangeLog b/frysk-core/frysk/isa/watchpoints/ChangeLog
index 0dd75aa..cc0ef21 100644
--- a/frysk-core/frysk/isa/watchpoints/ChangeLog
+++ b/frysk-core/frysk/isa/watchpoints/ChangeLog
@@ -1,3 +1,12 @@
+2008-06-24  Phil Muldoon  <pmuldoon@redhat.com>
+
+	* WatchpointFunctions.java (getWatchpointMinLength): Really
+	return the minimum length.
+
+2008-06-16  Phil Muldoon  <pmuldoon@redhat.com>
+
+	* WatchpointFunctions.java (getTriggeredWatchpoints): New.
+
 2008-06-05  Phil Muldoon  <pmuldoon@redhat.com>
 
 	* WatchpointFunctions.java (getWatchpointMinLength): New.	
diff --git a/frysk-core/frysk/isa/watchpoints/WatchpointFunctions.java b/frysk-core/frysk/isa/watchpoints/WatchpointFunctions.java
index 994d0cb..973678f 100644
--- a/frysk-core/frysk/isa/watchpoints/WatchpointFunctions.java
+++ b/frysk-core/frysk/isa/watchpoints/WatchpointFunctions.java
@@ -42,6 +42,7 @@ package frysk.isa.watchpoints;
 
 import java.util.ArrayList;
 import java.util.List;
+
 import frysk.proc.Task;
 
 public abstract class WatchpointFunctions  {
@@ -107,13 +108,27 @@ public abstract class WatchpointFunctions  {
      **/
     public List getAllWatchpoints(Task task) {
 	List listOfWP = new ArrayList();
-	for (int i=0; i<getWatchpointCount(); i++) {
+	for (int i=0; i<getWatchpointCount(); i++) 
 	    listOfWP.add(readWatchpoint(task,i));
-	}
 	return listOfWP;   
     }
 
     /**
+     * Returns all the triggeed watchpoints k
+     *
+     * @param task - task on which to delete a watchpoint.
+     *
+     * @return List- List of watchpoints
+     *
+     **/
+    public ArrayList getTriggeredWatchpoints(Task task) {
+	ArrayList listOfWP = new ArrayList();
+	for (int i=0; i<getWatchpointCount(); i++) 
+	    if (hasWatchpointTriggered(task, i)) 
+		listOfWP.add(readWatchpoint(task,i));
+	return listOfWP;   
+    }
+    /**
      * Reads the Debug control register.
      *
      * @param task - task to read the debug control
@@ -176,7 +191,7 @@ public abstract class WatchpointFunctions  {
      * @return int minimum length
      */
     public final int getWatchpointMinLength() {
-	return watchpointMaxLength;
+	return watchpointMinLength;
     }
 
 }
diff --git a/frysk-core/frysk/pkglibdir/ChangeLog b/frysk-core/frysk/pkglibdir/ChangeLog
index 181dd43..9b88513 100644
--- a/frysk-core/frysk/pkglibdir/ChangeLog
+++ b/frysk-core/frysk/pkglibdir/ChangeLog
@@ -1,3 +1,12 @@
+2009-03-20  Mark Wielaard  <mark@klomp.org>
+
+	* FunitSimpleInterfaceTest.java (main): Work around compiler being
+	too smart...and noticing o == null.
+
+2008-06-17 Teresa Thomas <tthomas@redhat.com>
+
+	* funit-ctypes.c: Write to float_.
+	
 2008-06-06  Sami Wagiaalla  <swagiaal@redhat.com>
 
 	* funit-2threads.c: New test program.
@@ -6,7 +15,7 @@
 
 	* funit-raise.S: Fix ADD parameter order.
 
-2007-05-23 Teresa Thomas <tthomas@redhat.com>
+2008-05-23 Teresa Thomas <tthomas@redhat.com>
 
 	* funit-ctypes.c: New file.
 	
diff --git a/frysk-core/frysk/pkglibdir/FunitSimpleInterfaceTest.java b/frysk-core/frysk/pkglibdir/FunitSimpleInterfaceTest.java
index dd2504e..3bb9de4 100644
--- a/frysk-core/frysk/pkglibdir/FunitSimpleInterfaceTest.java
+++ b/frysk-core/frysk/pkglibdir/FunitSimpleInterfaceTest.java
@@ -43,6 +43,8 @@ public class FunitSimpleInterfaceTest implements FunitSimpleInterface{
 	FunitSimpleInterface inter = new FunitSimpleInterfaceTest();
 	// Crash
 	Object o = null;
+        if (o == inter) // Work around compiler being too smart...
+          o = inter;
 	o.toString();
 	inter.simpleMethod();
     }
diff --git a/frysk-core/frysk/pkglibdir/funit-ctypes.c b/frysk-core/frysk/pkglibdir/funit-ctypes.c
index 6a5e3fb..9337ab6 100644
--- a/frysk-core/frysk/pkglibdir/funit-ctypes.c
+++ b/frysk-core/frysk/pkglibdir/funit-ctypes.c
@@ -44,7 +44,7 @@
 
 int array[4];
 int bigArray[9];
-float float_ = 0.0;
+float float_ = 1.9;
 double double_ = 0.0;
 long long long_long = 111;
 char char_ = 'A';
@@ -56,6 +56,7 @@ int main(int argc, char* argv[])
      array[k] = k;
 
   double_ = 12.0;
+  float_ = 1.9;
   long_long = 0x11223344aabbccddLL;
   char_ = 'B';
   	   
diff --git a/frysk-core/frysk/proc/dead/ChangeLog b/frysk-core/frysk/proc/dead/ChangeLog
index a66b5dd..d2b8beb 100644
--- a/frysk-core/frysk/proc/dead/ChangeLog
+++ b/frysk-core/frysk/proc/dead/ChangeLog
@@ -1,3 +1,16 @@
+2008-06-20  Andrew Cagney  <cagney@redhat.com>
+
+	* CorefileByteBuffer.java: Throw UserException, not
+	RuntimeException.
+
+2008-06-11  Andrew Cagney  <cagney@redhat.com>
+
+	* TestLinuxCore.java: Update to match stack trace output.
+
+2008-06-10  Andrew Cagney  <cagney@redhat.com>
+
+	* TestLinuxCore.java: Use PrintDebugInfoStackOptions.
+
 2008-06-04  Andrew Cagney  <cagney@redhat.com>
 
 	* LinuxCoreInfo.java (constructAuxv): Eliminate use of
diff --git a/frysk-core/frysk/proc/dead/CorefileByteBuffer.java b/frysk-core/frysk/proc/dead/CorefileByteBuffer.java
index 0abed3b..86274e6 100644
--- a/frysk-core/frysk/proc/dead/CorefileByteBuffer.java
+++ b/frysk-core/frysk/proc/dead/CorefileByteBuffer.java
@@ -39,6 +39,7 @@
 
 package frysk.proc.dead;
 
+import frysk.UserException;
 import frysk.sys.StatelessFile;
 import java.io.File;
 import java.util.ArrayList;
@@ -92,10 +93,9 @@ public class CorefileByteBuffer extends ByteBuffer {
     closeCoreFileElf(elf);
   }
 
-  protected void poke(long arg0, int arg1) 
-  {
-    throw new RuntimeException("Cannot poke into a corefile!");
-  }
+    protected void poke(long arg0, int arg1) {
+	throw new UserException("Cannot poke into a corefile!");
+    }
   
   protected int peek(long address) 
   {
@@ -120,20 +120,22 @@ public class CorefileByteBuffer extends ByteBuffer {
 		    long offset = metaLine.solibOffset  + (address - metaLine.vaddr);
 		    temp.pread(offset, buffer,0,1);
 		} else {
-		    throw new RuntimeException("CorefileByteBuffer: Cannot peek() at address 0x"+
-					       Long.toHexString(address)+". Offset exists in file: " +
-					       metaLine.name+" but that file cannot be accessed.");
+		    throw new UserException
+			("CorefileByteBuffer: Cannot peek() at address 0x"
+			 + Long.toHexString(address)+". Offset exists in file: "
+			 + metaLine.name+" but that file cannot be accessed.");
 		}
 	    }
 	}
 	
-    else
-      throw new RuntimeException("CorefileByteBuffer: Cannot peek() " +
-      				 "at address 0x" +
-				 Long.toHexString(address)+"." +
-				 " Address location is unknown " +
-				 " (not in corefile, executable or "+
-				 " mapped solibs).");
+    else {
+	throw new UserException("CorefileByteBuffer: Cannot peek() " +
+				"at address 0x" +
+				Long.toHexString(address)+"." +
+				" Address location is unknown " +
+				" (not in corefile, executable or "+
+				" mapped solibs).");
+    }
 
     return buffer[0];
   }
@@ -236,14 +238,14 @@ public class CorefileByteBuffer extends ByteBuffer {
     //XXX: the boolean gate indicates offset not found.
     
     if (!foundOffset)
-      throw new RuntimeException("Cannot find file offset for given address 0x"
-                                 + Long.toHexString(address));
+	throw new UserException("Cannot find file offset for given address 0x"
+				+ Long.toHexString(address));
 
     
     if (!presentInFile)
-      throw new RuntimeException("Cannot read file offset for given address 0x"
-                                 + Long.toHexString(address) + 
-				 ". It is elided from the core file");
+	throw new UserException("Cannot read file offset for given address 0x"
+				+ Long.toHexString(address) + 
+				". It is elided from the core file");
     return offset;
   }
 
@@ -295,9 +297,9 @@ public class CorefileByteBuffer extends ByteBuffer {
 						   "",0x1000));
               }
           }
-      }
-    else
-      throw new RuntimeException("Cannot IO access " + this.coreFile.getPath());
+      } else {
+	throw new UserException("Cannot IO access " + this.coreFile.getPath());
+    }
 
     return (MapAddressHeader[]) localList.toArray(new MapAddressHeader[localList.size()]);
   }
diff --git a/frysk-core/frysk/proc/dead/TestLinuxCore.java b/frysk-core/frysk/proc/dead/TestLinuxCore.java
index d6fd1e3..9bd63d4 100644
--- a/frysk-core/frysk/proc/dead/TestLinuxCore.java
+++ b/frysk-core/frysk/proc/dead/TestLinuxCore.java
@@ -50,7 +50,7 @@ import java.util.Iterator;
 import lib.dwfl.DwflModule;
 import lib.dwfl.SymbolBuilder;
 import frysk.config.Prefix;
-import frysk.debuginfo.PrintStackOptions;
+import frysk.debuginfo.PrintDebugInfoStackOptions;
 import frysk.dwfl.DwflCache;
 import frysk.event.Event;
 import frysk.event.RequestStopEvent;
@@ -111,7 +111,7 @@ public class TestLinuxCore extends TestLib {
 	// relative -> absolute converstion is occuring.
 	StacktraceAction coreStacktrace;
 	StringWriter coreStackOutput = new StringWriter();
-	PrintStackOptions options = new PrintStackOptions();
+	PrintDebugInfoStackOptions options = new PrintDebugInfoStackOptions();
 	options.setNumberOfFrames(20);
 
 	// Create a stackktrace of a the corefile process
@@ -132,10 +132,10 @@ public class TestLinuxCore extends TestLib {
 
 	String mainThread = "Task #\\d+\n" + 
 	    "(#[\\d]+ 0x[\\da-f]+ in .*\n)*"
-	    + "#[\\d]+ 0x[\\da-f]+ in server \\(\\).*\n"
-	    + "#[\\d]+ 0x[\\da-f]+ in main \\(\\).*\n"
-	    + "#[\\d]+ 0x[\\da-f]+ in __libc_start_main \\(\\).*\n"
-	    + "#[\\d]+ 0x[\\da-f]+ in _start \\(\\).*\n\n";
+	    + "#[\\d]+ 0x[\\da-f]+ in server\\(\\).*\n"
+	    + "#[\\d]+ 0x[\\da-f]+ in main\\(\\).*\n"
+	    + "#[\\d]+ 0x[\\da-f]+ in __libc_start_main\\(\\).*\n"
+	    + "#[\\d]+ 0x[\\da-f]+ in _start\\(\\).*\n\n";
 
 	String regex = new String();
 	regex += "(" + mainThread + ")";
@@ -143,7 +143,7 @@ public class TestLinuxCore extends TestLib {
 	String result = coreStackOutput.getBuffer().toString();
 	
 	assertTrue(result + "should match: " + regex + " threads",
-               result.matches(regex));
+		   result.matches(regex));
 	
     }
 
@@ -211,7 +211,7 @@ public class TestLinuxCore extends TestLib {
     StacktraceAction coreStacktrace;
     StringWriter liveStackOutput = new StringWriter();
     StringWriter coreStackOutput = new StringWriter();
-    PrintStackOptions options = new PrintStackOptions();
+    PrintDebugInfoStackOptions options = new PrintDebugInfoStackOptions();
     options.setNumberOfFrames(20);
     
     // Create a Stacktrace of the blocked live process
@@ -263,7 +263,6 @@ public class TestLinuxCore extends TestLib {
     assertEquals("Compare stack traces",
 		 liveStackOutput.getBuffer().toString(),
 		 coreStackOutput.getBuffer().toString());
-
   }
 
   private static class PrintEvent implements Event
diff --git a/frysk-core/frysk/proc/live/AddressSpaceByteBuffer.java b/frysk-core/frysk/proc/live/AddressSpaceByteBuffer.java
deleted file mode 100644
index adc0723..0000000
--- a/frysk-core/frysk/proc/live/AddressSpaceByteBuffer.java
+++ /dev/null
@@ -1,198 +0,0 @@
-// This file is part of the program FRYSK.
-// 
-// Copyright 2007, 2008, Red Hat Inc.
-// 
-// FRYSK is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-// 
-// FRYSK is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with FRYSK; if not, write to the Free Software Foundation,
-// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-// 
-// In addition, as a special exception, Red Hat, Inc. gives You the
-// additional right to link the code of FRYSK with code not covered
-// under the GNU General Public License ("Non-GPL Code") and to
-// distribute linked combinations including the two, subject to the
-// limitations in this paragraph. Non-GPL Code permitted under this
-// exception must only link to the code of FRYSK through those well
-// defined interfaces identified in the file named EXCEPTION found in
-// the source code files (the "Approved Interfaces"). The files of
-// Non-GPL Code may instantiate templates or use macros or inline
-// functions from the Approved Interfaces without causing the
-// resulting work to be covered by the GNU General Public
-// License. Only Red Hat, Inc. may make changes or additions to the
-// list of Approved Interfaces. You must obey the GNU General Public
-// License in all respects for all of the FRYSK code and other code
-// used in conjunction with FRYSK except the Non-GPL Code covered by
-// this exception. If you modify this file, you may extend this
-// exception to your version of the file, but you are not obligated to
-// do so. If you do not wish to provide this exception without
-// modification, you must delete this exception statement from your
-// version and license this file solely under the GPL without
-// exception.
-
-package frysk.proc.live;
-
-import inua.eio.ByteBuffer;
-import frysk.sys.Errno;
-import frysk.sys.ProcessIdentifier;
-import frysk.sys.ptrace.AddressSpace;
-import frysk.sys.proc.Mem;
-import frysk.event.Request;
-import frysk.proc.Manager;
-
-public class AddressSpaceByteBuffer extends ByteBuffer {
-    protected final AddressSpace addressSpace;
-    protected final ProcessIdentifier pid;
-
-    // Direct files access if possible, or null otherwise.
-    private Mem mem;
-
-    protected AddressSpaceByteBuffer (ProcessIdentifier pid,
-				      AddressSpace addressSpace,
-				      long lowerExtreem, long upperExtreem) {
-	super (lowerExtreem, upperExtreem);
-	this.pid = pid;
-	this.addressSpace = addressSpace;
-	peekRequest = new PeekRequest();
-	pokeRequest = new PokeRequest();
-	if (addressSpace == AddressSpace.TEXT
-	    || addressSpace == AddressSpace.DATA)
-	    // Try to use /proc; but if any error occures clear it and
-	    // revert back to ptrace.
-	    mem = new Mem(pid);
-    }
-    public AddressSpaceByteBuffer(ProcessIdentifier pid,
-				  AddressSpace addressSpace) {
-	this(pid, addressSpace, 0, addressSpace.length());
-    }
-
-
-    private class PeekRequest
-	extends Request
-    {
-	private long index;
-	private int value;
-	PeekRequest()
-	{
-	    super(Manager.eventLoop);
-	}
-	public void execute ()
-	{
-	    value = addressSpace.peek(pid, index);
-	}
-	public int request (long index)
-	{
-	    if (isEventLoopThread())
-		return addressSpace.peek(pid, index);
-	    else synchronized (this) {
-		this.index = index;
-		request();
-		return value;
-	    }
-	}
-    }
-    private final PeekRequest peekRequest;
-    protected int peek(long index) {
-	return peekRequest.request (index);
-    }
-
-    private class PokeRequest
-	extends Request
-    {
-	private long index;
-	private int value;
-	PokeRequest()
-	{
-	    super(Manager.eventLoop);
-	}
-	public void execute ()
-	{
-	    addressSpace.poke(pid, index, value);
-	}
-	public void request (long index, int value)
-	{
-	    if (isEventLoopThread())
-		addressSpace.poke(pid, index, value);
-	    else synchronized (this) {
-		this.index = index;
-		this.value = value;
-		request();
-	    }
-	}
-    }
-    private final PokeRequest pokeRequest;
-    protected void poke(long index, int value) {
-	pokeRequest.request (index, value);
-    }
-
-    private class TransferRequest extends Request {
-	private long index;
-	private byte[] bytes;
-	private int offset;
-	private int length;
-	private boolean write;
-	TransferRequest() {
-	    super(Manager.eventLoop);
-	}
-        private void transfer(long index, byte[] bytes, int offset, int length,
-			      boolean write) {
-	    if (mem != null && !write) {
-		try {
-		    mem.pread(index, bytes, offset, length);
-		    return;
-		} catch (Errno e) {
-		    // Give up on mem; and fall back to ptrace.  This
-		    // can happen when /proc isn't mounted, or when a
-		    // process is terminating and the kernel scrubs
-		    // the /proc entry before its time.
-		    mem = null;
-		}
-	    }
-	    addressSpace.transfer(pid, index, bytes, offset, length,
-				  write);
-	}
-
-	public void execute() {
-	    transfer(index, bytes, offset, length, write);
-	}
-
-	public void request(long index, byte[] bytes, int offset, int length,
-			    boolean write) {
-	    if (isEventLoopThread())
-		transfer(index, bytes, offset, length, write);
-	    else synchronized (this) {
-		this.index = index;
-		this.bytes = bytes;
-		this.offset = offset;
-		this.length = length;
-		this.write = write;
-		super.request();
-	    }
-	}
-    }
-    private final TransferRequest transfer = new TransferRequest();
-
-    protected int peek(long index, byte[] bytes, int offset, int length) {
-	transfer.request(index, bytes, offset, length, false); // read
-	return length;
-    }
-    protected int poke(long index, byte[] bytes, int offset, int length) {
-	transfer.request(index, bytes, offset, length, true); // write
-	return length;
-    }
-
-    protected ByteBuffer subBuffer (ByteBuffer parent, long lowerExtreem,
-				    long upperExtreem)
-    {
-	AddressSpaceByteBuffer up = (AddressSpaceByteBuffer)parent;
-	return new AddressSpaceByteBuffer (up.pid, up.addressSpace,
-					   lowerExtreem, upperExtreem);
-    }
-}
diff --git a/frysk-core/frysk/proc/live/BlockSpaceByteBuffer.java b/frysk-core/frysk/proc/live/BlockSpaceByteBuffer.java
new file mode 100644
index 0000000..84b2c8a
--- /dev/null
+++ b/frysk-core/frysk/proc/live/BlockSpaceByteBuffer.java
@@ -0,0 +1,130 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2006, 2007, 2008, Red Hat Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+package frysk.proc.live;
+
+import frysk.sys.ptrace.BlockSpace;
+import frysk.event.Request;
+import frysk.proc.Manager;
+import inua.eio.ByteBuffer;
+import frysk.sys.ProcessIdentifier;
+
+/*
+ * A ByteBuffer interface to structures returned by ptrace which must
+ * be read or written all at once e.g., the registers or floating
+ * point registers.
+ */
+public class BlockSpaceByteBuffer
+    extends ByteBuffer
+{
+    private final ProcessIdentifier pid;
+    private final BlockSpace registerSet;
+    private final byte[] bytes;
+  
+    private BlockSpaceByteBuffer(ProcessIdentifier pid,
+				 BlockSpace registerSet,
+				 long lowerExtreem, long upperExtreem) {
+	super(lowerExtreem, upperExtreem);
+	this.pid = pid;
+	this.registerSet = registerSet;
+	bytes = new byte[registerSet.length()];
+    }
+    public BlockSpaceByteBuffer(ProcessIdentifier pid,
+				BlockSpace registerSet) {
+	this(pid, registerSet, 0, registerSet.length());
+    }
+  
+    private class TransferRequest extends Request {
+	TransferRequest() {
+	    super(Manager.eventLoop);
+	}
+	private boolean write;
+	public final void execute() {
+	    registerSet.transfer(pid, bytes, write);
+	}
+	private void request(boolean write) {
+	    if (isEventLoopThread()) {
+		registerSet.transfer(pid, bytes, write);
+	    } else {
+		synchronized (this) {
+		    this.write = write;
+		    super.request();
+		}
+	    }
+	}
+	void getRegs() {
+	    request(false); // read
+	}
+	void setRegs() {
+	    request(true); // write
+	}
+    }
+    private final TransferRequest transfer = new TransferRequest();
+
+    protected int peek(long index) {
+	transfer.getRegs();
+	return bytes[(int)index];
+    }
+  
+    protected void poke(long index, int value) {
+	transfer.getRegs();
+	bytes[(int)index] = (byte)value;
+	transfer.setRegs();
+    }
+  
+    protected int peek(long index, byte[] bytes, int off, int len) {
+	transfer.getRegs();
+	System.arraycopy(this.bytes, (int) index, bytes, off, len);
+	return len;
+    }
+
+    protected int poke(long index, byte[] bytes, int off, int len) {
+	transfer.getRegs();
+	System.arraycopy(bytes, off, this.bytes, (int) index, len);
+	transfer.setRegs();
+	return len;
+    }
+  
+    protected ByteBuffer subBuffer(ByteBuffer parent, long lowerExtreem,
+				   long upperExtreem) {
+	BlockSpaceByteBuffer up = (BlockSpaceByteBuffer)parent;
+	return new BlockSpaceByteBuffer(up.pid, up.registerSet,
+					lowerExtreem, upperExtreem);
+    }
+}
diff --git a/frysk-core/frysk/proc/live/ByteSpaceByteBuffer.java b/frysk-core/frysk/proc/live/ByteSpaceByteBuffer.java
new file mode 100644
index 0000000..7cd405e
--- /dev/null
+++ b/frysk-core/frysk/proc/live/ByteSpaceByteBuffer.java
@@ -0,0 +1,198 @@
+// This file is part of the program FRYSK.
+// 
+// Copyright 2007, 2008, Red Hat Inc.
+// 
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+// 
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+package frysk.proc.live;
+
+import inua.eio.ByteBuffer;
+import frysk.sys.Errno;
+import frysk.sys.ProcessIdentifier;
+import frysk.sys.ptrace.ByteSpace;
+import frysk.sys.proc.Mem;
+import frysk.event.Request;
+import frysk.proc.Manager;
+
+public class ByteSpaceByteBuffer extends ByteBuffer {
+    protected final ByteSpace addressSpace;
+    protected final ProcessIdentifier pid;
+
+    // Direct files access if possible, or null otherwise.
+    private Mem mem;
+
+    protected ByteSpaceByteBuffer (ProcessIdentifier pid,
+				   ByteSpace addressSpace,
+				   long lowerExtreem, long upperExtreem) {
+	super (lowerExtreem, upperExtreem);
+	this.pid = pid;
+	this.addressSpace = addressSpace;
+	peekRequest = new PeekRequest();
+	pokeRequest = new PokeRequest();
+	if (addressSpace == ByteSpace.TEXT
+	    || addressSpace == ByteSpace.DATA) {
+	    // Try to use /proc; but if any error occures clear it and
+	    // revert back to ptrace.
+	    mem = new Mem(pid);
+	}
+    }
+    public ByteSpaceByteBuffer(ProcessIdentifier pid,
+			       ByteSpace addressSpace) {
+	this(pid, addressSpace, 0, addressSpace.length());
+    }
+
+
+    private class PeekRequest
+	extends Request
+    {
+	private long index;
+	private int value;
+	PeekRequest() {
+	    super(Manager.eventLoop);
+	}
+	public void execute() {
+	    value = addressSpace.peek(pid, index);
+	}
+	public int request(long index) {
+	    if (isEventLoopThread())
+		return addressSpace.peek(pid, index);
+	    else {
+		synchronized (this) {
+		    this.index = index;
+		    request();
+		    return value;
+		}
+	    }
+	}
+    }
+    private final PeekRequest peekRequest;
+    protected int peek(long index) {
+	return peekRequest.request (index);
+    }
+
+    private class PokeRequest
+	extends Request
+    {
+	private long index;
+	private int value;
+	PokeRequest() {
+	    super(Manager.eventLoop);
+	}
+	public void execute() {
+	    addressSpace.poke(pid, index, value);
+	}
+	public void request(long index, int value) {
+	    if (isEventLoopThread())
+		addressSpace.poke(pid, index, value);
+	    else {
+		synchronized (this) {
+		    this.index = index;
+		    this.value = value;
+		    request();
+		}
+	    }
+	}
+    }
+    private final PokeRequest pokeRequest;
+    protected void poke(long index, int value) {
+	pokeRequest.request (index, value);
+    }
+
+    private class TransferRequest extends Request {
+	private long index;
+	private byte[] bytes;
+	private int offset;
+	private int length;
+	private boolean write;
+	TransferRequest() {
+	    super(Manager.eventLoop);
+	}
+        private void transfer(long index, byte[] bytes, int offset, int length,
+			      boolean write) {
+	    if (mem != null && !write) {
+		try {
+		    mem.pread(index, bytes, offset, length);
+		    return;
+		} catch (Errno e) {
+		    // Give up on mem; and fall back to ptrace.  This
+		    // can happen when /proc isn't mounted, or when a
+		    // process is terminating and the kernel scrubs
+		    // the /proc entry before its time.
+		    mem = null;
+		}
+	    }
+	    addressSpace.transfer(pid, index, bytes, offset, length,
+				  write);
+	}
+
+	public void execute() {
+	    transfer(index, bytes, offset, length, write);
+	}
+
+	public void request(long index, byte[] bytes, int offset, int length,
+			    boolean write) {
+	    if (isEventLoopThread())
+		transfer(index, bytes, offset, length, write);
+	    else {
+		synchronized (this) {
+		    this.index = index;
+		    this.bytes = bytes;
+		    this.offset = offset;
+		    this.length = length;
+		    this.write = write;
+		    super.request();
+		}
+	    }
+	}
+    }
+    private final TransferRequest transfer = new TransferRequest();
+
+    protected int peek(long index, byte[] bytes, int offset, int length) {
+	transfer.request(index, bytes, offset, length, false); // read
+	return length;
+    }
+    protected int poke(long index, byte[] bytes, int offset, int length) {
+	transfer.request(index, bytes, offset, length, true); // write
+	return length;
+    }
+
+    protected ByteBuffer subBuffer (ByteBuffer parent, long lowerExtreem,
+				    long upperExtreem) {
+	ByteSpaceByteBuffer up = (ByteSpaceByteBuffer)parent;
+	return new ByteSpaceByteBuffer(up.pid, up.addressSpace,
+				       lowerExtreem, upperExtreem);
+    }
+}
diff --git a/frysk-core/frysk/proc/live/ChangeLog b/frysk-core/frysk/proc/live/ChangeLog
index eee24c5..49838f5 100644
--- a/frysk-core/frysk/proc/live/ChangeLog
+++ b/frysk-core/frysk/proc/live/ChangeLog
@@ -1,3 +1,21 @@
+2008-07-04  Andrew Cagney  <cagney@redhat.com>
+
+	* ByteSpaceByteBuffer.java: Rename AddressSpaceByteBuffer.
+	* BlockSpaceByteBuffer.java: Rename RegisterSetByteBuffer..
+	* LogicalMemoryBuffer.java: Update.
+	* LinuxPtraceTask.java: Update.
+	* PtraceRegisterBanksFactory.java: Update.
+	* TestByteBuffer.java: Update.
+
+2008-06-16  Phil Muldoon  <pmuldoon@redhat.com>
+
+	* LinuxPtraceTaskState.java (Running.checkWatchpoint): Rewrite to use
+	WatchpointFunctions.getTriggeredWatchpoints().
+
+2008-06-12  Andrew Cagney  <cagney@redhat.com>
+
+	* LinuxPtraceProc.java (getExe()): Delete.
+
 2008-06-06  Teresa Thomas  <tthomas@redhat.com>
 
 	* LinuxPtraceTaskState.java: Additional logging messages.
diff --git a/frysk-core/frysk/proc/live/LinuxPtraceProc.java b/frysk-core/frysk/proc/live/LinuxPtraceProc.java
index e854829..c7e1888 100644
--- a/frysk-core/frysk/proc/live/LinuxPtraceProc.java
+++ b/frysk-core/frysk/proc/live/LinuxPtraceProc.java
@@ -224,40 +224,15 @@ public class LinuxPtraceProc extends LiveProc {
      * and a second returning the exe as it should be (but possibly
      * isn't :-).  Better yet have utrace handle it :-)
      */
-    private String exe;
-    private String getExe() {
+    private SysRootFile exe;
+    public SysRootFile getExeFile() {
 	if (exe == null) {
-	    ProcessIdentifier pid
-		= ProcessIdentifierFactory.create(getPid());
-	    String exe = Exe.get(pid);
-	    // Linux's /proc/$$/exe can get screwed up in several
-	    // ways.  Detect each here and return null.
-	    if (exe.endsWith(" (deleted)"))
-		// Assume (possibly incorrectly) that a trailing
-		// "(deleted)" always indicates a deleted file.
-		return null;
-	    if (exe.indexOf((char)0) >= 0)
-		// Assume that an EXE that has somehow ended up with
-		// an embedded NUL character is invalid.  This happens
-		// when the kernel screws up "mv a-really-long-file
-		// $exe" leaving the updated EXE string with something
-		// like "$exe<NUL>ally-long-file (deleted)".
-		return null;
-	    if (!new File(exe).exists())
-		// Final sanity check; the above two should have covered
-		// all possible cases.  But one never knows.
-		return null;
-	    this.exe = exe;
+	    File exeFile = new File(Exe.getName(pid));
+	    return new SysRootFile(SysRootCache.getSysRoot(exeFile.getName()), exeFile);
 	}
 	return exe;
     }
 
-    public SysRootFile getExeFile() {
-	String exe = getExe();
-	File exeFile = new File(exe);
-	return new SysRootFile(SysRootCache.getSysRoot(exeFile.getName()), exeFile);
-    }
-
     /**
      * If it hasn't already been read, read the stat structure.
      */
diff --git a/frysk-core/frysk/proc/live/LinuxPtraceTask.java b/frysk-core/frysk/proc/live/LinuxPtraceTask.java
index 0ecadb3..8dc5c78 100644
--- a/frysk-core/frysk/proc/live/LinuxPtraceTask.java
+++ b/frysk-core/frysk/proc/live/LinuxPtraceTask.java
@@ -60,7 +60,7 @@ import inua.eio.ByteOrder;
 import frysk.sys.Errno;
 import frysk.sys.ProcessIdentifier;
 import frysk.sys.ptrace.Ptrace;
-import frysk.sys.ptrace.AddressSpace;
+import frysk.sys.ptrace.ByteSpace;
 import frysk.sys.Signal;
 import frysk.isa.syscalls.Syscall;
 import frysk.isa.ISA;
@@ -140,8 +140,7 @@ public class LinuxPtraceTask extends LiveTask {
     ByteBuffer getRawMemory() {
 	fine.log(this, "Begin fillMemory");
 	ByteOrder byteOrder = getISA().order();
-	ByteBuffer memory = new AddressSpaceByteBuffer(tid,
-						       AddressSpace.DATA);
+	ByteBuffer memory = new ByteSpaceByteBuffer(tid, ByteSpace.DATA);
 	memory.order(byteOrder);
 	fine.log(this, "End fillMemory"); 
 	return memory;
@@ -155,7 +154,7 @@ public class LinuxPtraceTask extends LiveTask {
 	    fine.log(this, "exiting get memory");
 	    ByteOrder byteOrder = getISA().order();
 	    BreakpointAddresses breakpoints = ((LinuxPtraceProc)getProc()).breakpoints;
-	    memory = new LogicalMemoryBuffer(tid, AddressSpace.DATA,
+	    memory = new LogicalMemoryBuffer(tid, ByteSpace.DATA,
 					     breakpoints);
 	    memory.order(byteOrder);
 	}
diff --git a/frysk-core/frysk/proc/live/LinuxPtraceTaskState.java b/frysk-core/frysk/proc/live/LinuxPtraceTaskState.java
index a819b9a..88286dc 100644
--- a/frysk-core/frysk/proc/live/LinuxPtraceTaskState.java
+++ b/frysk-core/frysk/proc/live/LinuxPtraceTaskState.java
@@ -39,18 +39,20 @@
 
 package frysk.proc.live;
 
-import frysk.sys.SignalSet;
-import frysk.sys.proc.Status;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
 import frysk.isa.watchpoints.WatchpointFunctionFactory;
 import frysk.isa.watchpoints.WatchpointFunctions;
-import frysk.proc.TaskObserver;
-import frysk.proc.Observer;
 import frysk.proc.Observable;
-import java.util.Collection;
-import java.util.Iterator;
-import frysk.sys.Signal;
+import frysk.proc.Observer;
+import frysk.proc.TaskObserver;
 import frysk.rsl.Log;
 import frysk.rsl.LogFactory;
+import frysk.sys.Signal;
+import frysk.sys.SignalSet;
+import frysk.sys.proc.Status;
 
 /**
  * A Linux Task's State tracked using PTRACE.
@@ -938,15 +940,15 @@ abstract class LinuxPtraceTaskState extends State {
 	    if (watchpointFunction == null) {
 		return blockers;
 	    }
-	    for (int i=0; i<watchpointFunction.getWatchpointCount();  i++) {
-		// Test if a watchpoint has fired
-		if (watchpointFunction.hasWatchpointTriggered(task, i)) {
-		    if (blockers == -1)
-			blockers = 0;
-		    frysk.isa.watchpoints.Watchpoint trigger = watchpointFunction.readWatchpoint(task, i);
-		    blockers += task.notifyWatchpoint(trigger.getAddress(), trigger.getRange(), trigger.isWriteOnly());
-		    watchpointFunction.resetWatchpoint(task, i);
-		}
+	    
+	    List triggeredWatchpoints = watchpointFunction.getTriggeredWatchpoints(task);
+	    Iterator i = triggeredWatchpoints.iterator();
+	    while (i.hasNext()) {
+		frysk.isa.watchpoints.Watchpoint wp = (frysk.isa.watchpoints.Watchpoint) i.next();
+		if (blockers == -1)
+		    blockers = 0;
+		blockers += task.notifyWatchpoint(wp.getAddress(), wp.getRange(), wp.isWriteOnly());
+		watchpointFunction.resetWatchpoint(task, wp.getRegister());
 	    }
 	    
 	    return blockers;
diff --git a/frysk-core/frysk/proc/live/LinuxWaitBuilder.java b/frysk-core/frysk/proc/live/LinuxWaitBuilder.java
index 39ce518..0943eb9 100644
--- a/frysk-core/frysk/proc/live/LinuxWaitBuilder.java
+++ b/frysk-core/frysk/proc/live/LinuxWaitBuilder.java
@@ -113,7 +113,7 @@ class LinuxWaitBuilder implements WaitBuilder {
     private void logMissing(String what, ProcessIdentifier pid) {
 	String warning = ("No task for " + what + " pid " + pid
 			  + " possibly caused by earlier [test] code"
-			  + " failing to clean up all childen");
+			  + " failing to clean up all children");
 	System.out.println("WARNING: " + warning);
 	fine.log(warning);
     }
diff --git a/frysk-core/frysk/proc/live/LogicalMemoryBuffer.java b/frysk-core/frysk/proc/live/LogicalMemoryBuffer.java
index 5d1330b..3227a5f 100644
--- a/frysk-core/frysk/proc/live/LogicalMemoryBuffer.java
+++ b/frysk-core/frysk/proc/live/LogicalMemoryBuffer.java
@@ -42,7 +42,7 @@ package frysk.proc.live;
 import frysk.sys.ProcessIdentifier;
 import java.util.Iterator;
 import inua.eio.ByteBuffer;
-import frysk.sys.ptrace.AddressSpace;
+import frysk.sys.ptrace.ByteSpace;
 
 /**
  * MemorySpaceByteBuffer that filters out anything the frysk core
@@ -51,16 +51,15 @@ import frysk.sys.ptrace.AddressSpace;
  * replace the bytes with the logical bytes as the user would normally
  * see them from the process.
  */
-class LogicalMemoryBuffer extends AddressSpaceByteBuffer
-{
-  // The breakpoints associated with the process address space.
-  private final BreakpointAddresses breakpoints;
+class LogicalMemoryBuffer extends ByteSpaceByteBuffer {
+    // The breakpoints associated with the process address space.
+    private final BreakpointAddresses breakpoints;
 
     /**
      * Private constructor used by subBuffer()
      */
     private LogicalMemoryBuffer(ProcessIdentifier tid,
-				AddressSpace addressSpace,
+				ByteSpace addressSpace,
 				BreakpointAddresses breakpoints,
 				long lower, long upper) {
 	super(tid, addressSpace, lower, upper);
@@ -72,99 +71,90 @@ class LogicalMemoryBuffer extends AddressSpaceByteBuffer
      * memory space for a task when requested.
      */
     LogicalMemoryBuffer(ProcessIdentifier tid,
-			AddressSpace addressSpace,
+			ByteSpace addressSpace,
 			BreakpointAddresses breakpoints) {
 	super(tid, addressSpace);
 	this.breakpoints = breakpoints;
     }
   
-  protected int peek(long caret)
-  {
-    Breakpoint breakpoint = breakpoints.getBreakpoint(caret);
-    if (breakpoint != null)
-      {
-	// This really shouldn't happen, it means the breakpoint
-	// is already uninstalled.
-	Instruction instruction = breakpoint.getInstruction();
-	if (instruction != null)
-	  {
-	    byte[] ibs = instruction.getBytes();
-	    return ibs[0] & 0xff;
-	  }
-      }
-    return super.peek(caret);
-  }
-  
-  protected int peek(long index, byte[] bytes, int offset, int length)
-  {
-    synchronized (breakpoints)
-      {
-	Iterator it;
-	it = breakpoints.getBreakpoints(index, index + length);
-	int r = 0;
-	while (it.hasNext())
-	  {
-	    Breakpoint breakpoint = (Breakpoint) it.next();
-	    // address - index falls inside the byte[] so will be at most
-	    // a positive int apart.
-	    int l = (int) (breakpoint.getAddress() - index) - r;
-	    // Do we need to be worried about "short peeks"?
-	    r += super.peek(index + r, bytes, offset + r, l);
-
-	    byte b;
-	    Instruction instruction = breakpoint.getInstruction();
+    protected int peek(long caret)
+    {
+	Breakpoint breakpoint = breakpoints.getBreakpoint(caret);
+	if (breakpoint != null) {
 	    // This really shouldn't happen, it means the breakpoint
 	    // is already uninstalled.
-	    if (instruction != null)
-	      b = instruction.getBytes()[0];
-	    else
-	      b = (byte) super.peek(index + r);
-	    bytes[offset + r] = b;
-	    r++;
-	  }
-	return super.peek(index + r, bytes, offset + r, length - r) + r;
-      }
-  }
-
-  /**
-   * Pokes the value at the given index. Unless a breakpoint is set at
-   * that location (FIXME: this limitation should be lifted).
-   */
-  protected void poke (long index, int value)
-  {
-    Breakpoint breakpoint = breakpoints.getBreakpoint(index);
-    if (breakpoint != null)
-      throw new UnsupportedOperationException("breakpoint set at: " + index);
-
-    super.poke(index, value);
-  }
+	    Instruction instruction = breakpoint.getInstruction();
+	    if (instruction != null) {
+		byte[] ibs = instruction.getBytes();
+		return ibs[0] & 0xff;
+	    }
+	}
+	return super.peek(caret);
+    }
   
-  /**
-   * Pokes the given bytes from offset at the index plus the given
-   * lenght. Unless a breakpoint is set in that range (FIXME: this
-   * limitation should be lifted).
-   */
-  protected int poke(long index, byte[] bytes, int offset, int length)
-  {
-    synchronized (breakpoints)
-      {
-	Iterator it;
-	it = breakpoints.getBreakpoints(index, index + length);
-	if (it.hasNext())
-	  throw new UnsupportedOperationException("breakpoint set between "
-						  + index + " and "
-						  + index + length);
-      }
+    protected int peek(long index, byte[] bytes, int offset, int length) {
+	synchronized (breakpoints) {
+	    Iterator it;
+	    it = breakpoints.getBreakpoints(index, index + length);
+	    int r = 0;
+	    while (it.hasNext()) {
+		Breakpoint breakpoint = (Breakpoint) it.next();
+		// address - index falls inside the byte[] so will be at most
+		// a positive int apart.
+		int l = (int) (breakpoint.getAddress() - index) - r;
+		// Do we need to be worried about "short peeks"?
+		r += super.peek(index + r, bytes, offset + r, l);
+		
+		byte b;
+		Instruction instruction = breakpoint.getInstruction();
+		// This really shouldn't happen, it means the breakpoint
+		// is already uninstalled.
+		if (instruction != null)
+		    b = instruction.getBytes()[0];
+		else
+		    b = (byte) super.peek(index + r);
+		bytes[offset + r] = b;
+		r++;
+	    }
+	    return super.peek(index + r, bytes, offset + r, length - r) + r;
+	}
+    }
+    
+    /**
+     * Pokes the value at the given index. Unless a breakpoint is set
+     * at that location (FIXME: this limitation should be lifted).
+     */
+    protected void poke(long index, int value) {
+	Breakpoint breakpoint = breakpoints.getBreakpoint(index);
+	if (breakpoint != null)
+	    throw new UnsupportedOperationException("breakpoint set at: " + index);
 
-    return super.poke(index, bytes, offset, length);
-  }
+	super.poke(index, value);
+    }
+  
+    /**
+     * Pokes the given bytes from offset at the index plus the given
+     * lenght. Unless a breakpoint is set in that range (FIXME: this
+     * limitation should be lifted).
+     */
+    protected int poke(long index, byte[] bytes, int offset, int length) {
+	synchronized (breakpoints) {
+	    Iterator it;
+	    it = breakpoints.getBreakpoints(index, index + length);
+	    if (it.hasNext())
+		throw new UnsupportedOperationException("breakpoint set between "
+							+ index + " and "
+							+ index + length);
+	}
+	
+	return super.poke(index, bytes, offset, length);
+    }
 
-  protected ByteBuffer subBuffer(ByteBuffer parent,
-				 long lower, long upper)
-  {
-    LogicalMemoryBuffer sub = (LogicalMemoryBuffer) parent;
-    return new LogicalMemoryBuffer (sub.pid, sub.addressSpace,
-				    sub.breakpoints,
-				    lower, upper);
-  }
+    protected ByteBuffer subBuffer(ByteBuffer parent,
+				   long lower, long upper) {
+	LogicalMemoryBuffer sub = (LogicalMemoryBuffer) parent;
+	return new LogicalMemoryBuffer (sub.pid, sub.addressSpace,
+					sub.breakpoints,
+					lower, upper);
+    }
 }
diff --git a/frysk-core/frysk/proc/live/PtraceRegisterBanksFactory.java b/frysk-core/frysk/proc/live/PtraceRegisterBanksFactory.java
index daa86d9..dea7c53 100644
--- a/frysk-core/frysk/proc/live/PtraceRegisterBanksFactory.java
+++ b/frysk-core/frysk/proc/live/PtraceRegisterBanksFactory.java
@@ -44,8 +44,8 @@ import inua.eio.ByteBuffer;
 import inua.eio.ByteOrder;
 import frysk.isa.ISA;
 import frysk.sys.ProcessIdentifier;
-import frysk.sys.ptrace.RegisterSet;
-import frysk.sys.ptrace.AddressSpace;
+import frysk.sys.ptrace.BlockSpace;
+import frysk.sys.ptrace.ByteSpace;
 import frysk.isa.banks.RegisterBanks;
 import frysk.isa.banks.X86BankRegisters;
 import frysk.isa.banks.PPCBankRegisters;
@@ -60,9 +60,9 @@ class PtraceRegisterBanksFactory {
 
     private static ByteBuffer[] x8664Banks(ProcessIdentifier pid) {
 	ByteBuffer[] bankBuffers = new ByteBuffer[] {
-	    new RegisterSetByteBuffer(pid, RegisterSet.REGS),
-	    new RegisterSetByteBuffer(pid, RegisterSet.FPREGS),
-	    new AddressSpaceByteBuffer(pid, AddressSpace.USR)
+	    new BlockSpaceByteBuffer(pid, BlockSpace.REGS),
+	    new BlockSpaceByteBuffer(pid, BlockSpace.FPREGS),
+	    new ByteSpaceByteBuffer(pid, ByteSpace.USR)
 	};
 	for (int i = 0; i < bankBuffers.length; i++) {
 	    bankBuffers[i].order(ByteOrder.LITTLE_ENDIAN);
@@ -72,10 +72,10 @@ class PtraceRegisterBanksFactory {
 
     private static ByteBuffer[] ia32Banks(ProcessIdentifier pid) {
 	ByteBuffer[] bankBuffers = new ByteBuffer[] {
-	    new RegisterSetByteBuffer(pid, RegisterSet.REGS),
-	    new RegisterSetByteBuffer(pid, RegisterSet.FPREGS),
-	    new RegisterSetByteBuffer(pid, RegisterSet.FPXREGS),
-	    new AddressSpaceByteBuffer(pid, AddressSpace.USR)
+	    new BlockSpaceByteBuffer(pid, BlockSpace.REGS),
+	    new BlockSpaceByteBuffer(pid, BlockSpace.FPREGS),
+	    new BlockSpaceByteBuffer(pid, BlockSpace.FPXREGS),
+	    new ByteSpaceByteBuffer(pid, ByteSpace.USR)
 	};
 	for (int i = 0; i < bankBuffers.length; i++) {
 	    bankBuffers[i].order(ByteOrder.LITTLE_ENDIAN);
@@ -85,7 +85,7 @@ class PtraceRegisterBanksFactory {
 
     private static ByteBuffer[] ppcBanksBE(ProcessIdentifier pid) {
 	ByteBuffer[] bankBuffers = new ByteBuffer[] {
-            new AddressSpaceByteBuffer(pid, AddressSpace.USR)
+            new ByteSpaceByteBuffer(pid, ByteSpace.USR)
         };
 
 	for (int i = 0; i < bankBuffers.length; i++) {
diff --git a/frysk-core/frysk/proc/live/RegisterSetByteBuffer.java b/frysk-core/frysk/proc/live/RegisterSetByteBuffer.java
deleted file mode 100644
index 6b2c1ff..0000000
--- a/frysk-core/frysk/proc/live/RegisterSetByteBuffer.java
+++ /dev/null
@@ -1,131 +0,0 @@
-// This file is part of the program FRYSK.
-//
-// Copyright 2006, 2007, 2008, Red Hat Inc.
-//
-// FRYSK is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// FRYSK is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with FRYSK; if not, write to the Free Software Foundation,
-// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-// 
-// In addition, as a special exception, Red Hat, Inc. gives You the
-// additional right to link the code of FRYSK with code not covered
-// under the GNU General Public License ("Non-GPL Code") and to
-// distribute linked combinations including the two, subject to the
-// limitations in this paragraph. Non-GPL Code permitted under this
-// exception must only link to the code of FRYSK through those well
-// defined interfaces identified in the file named EXCEPTION found in
-// the source code files (the "Approved Interfaces"). The files of
-// Non-GPL Code may instantiate templates or use macros or inline
-// functions from the Approved Interfaces without causing the
-// resulting work to be covered by the GNU General Public
-// License. Only Red Hat, Inc. may make changes or additions to the
-// list of Approved Interfaces. You must obey the GNU General Public
-// License in all respects for all of the FRYSK code and other code
-// used in conjunction with FRYSK except the Non-GPL Code covered by
-// this exception. If you modify this file, you may extend this
-// exception to your version of the file, but you are not obligated to
-// do so. If you do not wish to provide this exception without
-// modification, you must delete this exception statement from your
-// version and license this file solely under the GPL without
-// exception.
-
-package frysk.proc.live;
-
-import frysk.sys.ptrace.RegisterSet;
-import frysk.event.Request;
-import frysk.proc.Manager;
-import inua.eio.ByteBuffer;
-import frysk.sys.ProcessIdentifier;
-
-/*
- * A ByteBuffer interface to structures returned by ptrace which must
- * be read or written all at once e.g., the registers or floating
- * point registers.
- */
-public class RegisterSetByteBuffer
-    extends ByteBuffer
-{
-    private final ProcessIdentifier pid;
-    private final RegisterSet registerSet;
-    private final byte[] bytes;
-  
-    private RegisterSetByteBuffer(ProcessIdentifier pid,
-				  RegisterSet registerSet,
-				  long lowerExtreem, long upperExtreem) {
-	super(lowerExtreem, upperExtreem);
-	this.pid = pid;
-	this.registerSet = registerSet;
-	bytes = new byte[registerSet.length()];
-    }
-    public RegisterSetByteBuffer(ProcessIdentifier pid,
-				 RegisterSet registerSet) {
-	this(pid, registerSet, 0, registerSet.length());
-    }
-  
-    private class TransferRequest extends Request {
-	TransferRequest() {
-	    super(Manager.eventLoop);
-	}
-	private boolean write;
-	public final void execute() {
-	    registerSet.transfer(pid, bytes, write);
-	}
-	private void request(boolean write) {
-	    if (isEventLoopThread()) {
-		registerSet.transfer(pid, bytes, write);
-	    } else {
-		synchronized (this) {
-		    this.write = write;
-		    super.request();
-		}
-	    }
-	}
-	void getRegs() {
-	    request(false); // read
-	}
-	void setRegs() {
-	    request(true); // write
-	}
-    }
-    private final TransferRequest transfer = new TransferRequest();
-
-    protected int peek(long index) {
-	transfer.getRegs();
-	return bytes[(int)index];
-    }
-  
-    protected void poke(long index, int value) {
-	transfer.getRegs();
-	bytes[(int)index] = (byte)value;
-	transfer.setRegs();
-    }
-  
-    protected int peek(long index, byte[] bytes, int off, int len) {
-	transfer.getRegs();
-	System.arraycopy(this.bytes, (int) index, bytes, off, len);
-	return len;
-    }
-
-    protected int poke(long index, byte[] bytes, int off, int len) {
-	transfer.getRegs();
-	System.arraycopy(bytes, off, this.bytes, (int) index, len);
-	transfer.setRegs();
-	return len;
-    }
-  
-    protected ByteBuffer subBuffer (ByteBuffer parent, long lowerExtreem,
-				    long upperExtreem)
-    {
-	RegisterSetByteBuffer up = (RegisterSetByteBuffer)parent;
-	return new RegisterSetByteBuffer (up.pid, up.registerSet,
-					  lowerExtreem, upperExtreem);
-    }
-}
diff --git a/frysk-core/frysk/proc/live/TestByteBuffer.java b/frysk-core/frysk/proc/live/TestByteBuffer.java
index 1983682..f318b90 100644
--- a/frysk-core/frysk/proc/live/TestByteBuffer.java
+++ b/frysk-core/frysk/proc/live/TestByteBuffer.java
@@ -47,15 +47,13 @@ import frysk.proc.dummy.DummyProc;
 import frysk.testbed.ForkFactory;
 import frysk.testbed.DaemonBlockedAtEntry;
 import frysk.testbed.LocalMemory;
-import frysk.sys.ptrace.RegisterSet;
-import frysk.sys.ptrace.AddressSpace;
+import frysk.sys.ptrace.BlockSpace;
+import frysk.sys.ptrace.ByteSpace;
 import frysk.proc.Manager;
 import frysk.sys.ProcessIdentifier;
 import java.util.Arrays;
 
-public class TestByteBuffer
-    extends TestCase
-{
+public class TestByteBuffer extends TestCase {
     // There are 2 sets of byte buffers to check, those that hold memory
     // and those that hold various register values.
     private ByteBuffer[] addressBuffers;
@@ -69,9 +67,9 @@ public class TestByteBuffer
 	
 	// Text and Data are the same, but can be accessed independently.
 	ByteBuffer addressSpaceByteBufferText
-	    = new AddressSpaceByteBuffer(pid, AddressSpace.TEXT);
+	    = new ByteSpaceByteBuffer(pid, ByteSpace.TEXT);
 	ByteBuffer addressSpaceByteBufferData
-	    = new AddressSpaceByteBuffer(pid, AddressSpace.DATA);
+	    = new ByteSpaceByteBuffer(pid, ByteSpace.DATA);
 	
 	// Cheat with the proc, it is not actually used if no
 	// breakpoints are set (testing with breakpoints set is done
@@ -80,7 +78,7 @@ public class TestByteBuffer
 	Proc proc = new DummyProc();
 	BreakpointAddresses breakpoints = new BreakpointAddresses(proc);
 	ByteBuffer memorySpaceByteBuffer
-	    = new LogicalMemoryBuffer(pid, AddressSpace.TEXT, breakpoints);
+	    = new LogicalMemoryBuffer(pid, ByteSpace.TEXT, breakpoints);
 	
 	addressBuffers = new ByteBuffer[] { addressSpaceByteBufferText,
 					    addressSpaceByteBufferData,
@@ -88,18 +86,18 @@ public class TestByteBuffer
 	
 	// The USER area is seen as a register buffer.
 	ByteBuffer usrByteBuffer
-	    = new AddressSpaceByteBuffer(pid, AddressSpace.USR);
+	    = new ByteSpaceByteBuffer(pid, ByteSpace.USR);
 	
 	// See how many other register sets there are.
-	if (RegisterSet.REGS != null) {
+	if (BlockSpace.REGS != null) {
 	    ByteBuffer registerByteBuffer
-		= new RegisterSetByteBuffer(pid, RegisterSet.REGS);
-	    if (RegisterSet.FPREGS != null) {
+		= new BlockSpaceByteBuffer(pid, BlockSpace.REGS);
+	    if (BlockSpace.FPREGS != null) {
 		ByteBuffer fpregisterByteBuffer
-		    = new RegisterSetByteBuffer(pid, RegisterSet.FPREGS);
-		if (RegisterSet.FPXREGS != null) {
+		    = new BlockSpaceByteBuffer(pid, BlockSpace.FPREGS);
+		if (BlockSpace.FPXREGS != null) {
 		    ByteBuffer fpxregisterByteBuffer
-			= new RegisterSetByteBuffer(pid, RegisterSet.FPXREGS);
+			= new BlockSpaceByteBuffer(pid, BlockSpace.FPXREGS);
 		    registerBuffers = new ByteBuffer[] { usrByteBuffer,
 							 registerByteBuffer,
 							 fpregisterByteBuffer,
@@ -118,17 +116,15 @@ public class TestByteBuffer
 	}
     }
 
-    public void tearDown() throws Exception
-    {
-      addressBuffers = null;
-      registerBuffers = null;
+    public void tearDown() throws Exception {
+	addressBuffers = null;
+	registerBuffers = null;
 
-      // Clean up any left stuff processes/open files/etc.
-      super.tearDown();
+	// Clean up any left stuff processes/open files/etc.
+	super.tearDown();
     }
 
-    public void verifySlice(ByteBuffer buffer, long addr, int length)
-    {
+    public void verifySlice(ByteBuffer buffer, long addr, int length) {
 	ByteBuffer slice = buffer.slice (addr, length);
 	byte bytes[] = new byte[length];
 	buffer.get (addr, bytes, 0, length);
@@ -138,37 +134,32 @@ public class TestByteBuffer
 	}
     }
 
-    public void testSliceAddressBuffers()
-    {
-      for (int i = 0; i < addressBuffers.length; i++)
-	verifySlice(addressBuffers[i], LocalMemory.getCodeAddr(),
-		    LocalMemory.getCodeBytes().length);
+    public void testSliceAddressBuffers() {
+	for (int i = 0; i < addressBuffers.length; i++)
+	    verifySlice(addressBuffers[i], LocalMemory.getCodeAddr(),
+			LocalMemory.getCodeBytes().length);
     }
 
-    public void testSliceRegisterBuffers()
-    {
-      for (int i = 0; i < registerBuffers.length; i++)
-	verifySlice(registerBuffers[i], 4, 4);
+    public void testSliceRegisterBuffers() {
+	for (int i = 0; i < registerBuffers.length; i++)
+	    verifySlice(registerBuffers[i], 4, 4);
     }
 
-    private void verifyModify(ByteBuffer buffer, long addr)
-    {
+    private void verifyModify(ByteBuffer buffer, long addr) {
 	// Read, modify, read.
 	byte oldByte = buffer.get(addr);
 	buffer.putByte(addr, (byte)~oldByte);
 	assertEquals ("modified", (byte)~oldByte, buffer.get(addr));
     }
 
-    public void testModifyRegisterBuffers()
-    {
-      for (int i = 0; i < registerBuffers.length; i++)
-	verifyModify(registerBuffers[i], 0);
+    public void testModifyRegisterBuffers() {
+	for (int i = 0; i < registerBuffers.length; i++)
+	    verifyModify(registerBuffers[i], 0);
     }
 
-    public void testModifyAddressBuffers()
-    {
-      for (int i = 0; i < addressBuffers.length; i++)
-	verifyModify(addressBuffers[i], LocalMemory.getCodeAddr());
+    public void testModifyAddressBuffers() {
+	for (int i = 0; i < addressBuffers.length; i++)
+	    verifyModify(addressBuffers[i], LocalMemory.getCodeAddr());
     }
 
     private void verifyAsyncModify(ByteBuffer buffer, long addr) {
@@ -218,71 +209,61 @@ public class TestByteBuffer
 	}
     }
     public void testAsyncRegisterBuffers() {
-      for (int i = 0; i < registerBuffers.length; i++)
-	verifyAsyncModify(registerBuffers[0], 0);
+	for (int i = 0; i < registerBuffers.length; i++)
+	    verifyAsyncModify(registerBuffers[0], 0);
     }
 
     public void testAsyncAddressBuffers() {
-      for (int i = 0; i < addressBuffers.length; i++)
-	verifyAsyncModify(addressBuffers[i],
-			  LocalMemory.getCodeAddr());
+	for (int i = 0; i < addressBuffers.length; i++)
+	    verifyAsyncModify(addressBuffers[i],
+			      LocalMemory.getCodeAddr());
     }
 
-    public void verifyPeeks(ByteBuffer buffer, long addr, byte[] origBytes)
-    {
-      byte bytes[] = new byte[origBytes.length];
-      buffer.get(addr, bytes, 0, bytes.length);
-      for (int i = 0; i < bytes.length; i++)
-        assertEquals ("byte at " + i, bytes[i], origBytes[i]);
+    public void verifyPeeks(ByteBuffer buffer, long addr, byte[] origBytes) {
+	byte bytes[] = new byte[origBytes.length];
+	buffer.get(addr, bytes, 0, bytes.length);
+	for (int i = 0; i < bytes.length; i++)
+	    assertEquals ("byte at " + i, bytes[i], origBytes[i]);
     }
   
-    public void testAddressBufferPeeks()
-    {
-      long addr = LocalMemory.getCodeAddr();
-      byte[] origBytes = LocalMemory.getCodeBytes();
-      for (int i = 0; i < addressBuffers.length; i++)
-	verifyPeeks(addressBuffers[i], addr, origBytes);
+    public void testAddressBufferPeeks() {
+	long addr = LocalMemory.getCodeAddr();
+	byte[] origBytes = LocalMemory.getCodeBytes();
+	for (int i = 0; i < addressBuffers.length; i++)
+	    verifyPeeks(addressBuffers[i], addr, origBytes);
     }
 
-    public void testRegisterBufferPeeks()
-    {
-      // Check that simple get loop is similar to bulk get.
-      long addr = 4;
-      byte[] origBytes = new byte[16];
-      for (int i = 0; i < registerBuffers.length; i++)
-	{
-	  for (int j = 0; j < origBytes.length; j++)
-	    origBytes[j] = registerBuffers[i].get(addr + j);
-	  verifyPeeks(registerBuffers[i], addr, origBytes);
+    public void testRegisterBufferPeeks() {
+	// Check that simple get loop is similar to bulk get.
+	long addr = 4;
+	byte[] origBytes = new byte[16];
+	for (int i = 0; i < registerBuffers.length; i++) {
+	    for (int j = 0; j < origBytes.length; j++)
+		origBytes[j] = registerBuffers[i].get(addr + j);
+	    verifyPeeks(registerBuffers[i], addr, origBytes);
 	}
     }
-    private class AsyncPeeks
-	implements Runnable
-    {
+    private class AsyncPeeks implements Runnable {
 	private ByteBuffer buffer;
 	private long addr;
 	private int length;
 	private byte[] bytes;
 	private Exception e;
-	AsyncPeeks (ByteBuffer buffer, long addr, int length)
-	{
+	AsyncPeeks (ByteBuffer buffer, long addr, int length) {
 	    this.buffer = buffer;
 	    this.addr = addr;
 	    this.length = length;
 	    this.bytes = new byte[length];
 	}
-	public void run ()
-	{
+	public void run() {
 	    try {
 		buffer.get (addr, bytes, 0, length);
-	    }
-	    catch (Exception e) {
+	    } catch (Exception e) {
 		this.e = e;
 	    }
 	    Manager.eventLoop.requestStop();
 	}
-	void call (byte[] origBytes)
-	{
+	void call (byte[] origBytes) {
 	    // Force the event loop to running on this thread.  Ugly, and is to
 	    // to be removed when bug #4688 is resolved.
 	    Manager.eventLoop.runPolling(1);
@@ -297,71 +278,64 @@ public class TestByteBuffer
 	}
     }
 
-    public void testAsyncPeeks ()
-    {
-      byte[] origBytes = LocalMemory.getCodeBytes();
-      for (int i = 0; i < addressBuffers.length; i++)
-	new AsyncPeeks(addressBuffers[i], LocalMemory.getCodeAddr(),
-		       LocalMemory.getCodeBytes().length).call(origBytes);
+    public void testAsyncPeeks() {
+	byte[] origBytes = LocalMemory.getCodeBytes();
+	for (int i = 0; i < addressBuffers.length; i++)
+	    new AsyncPeeks(addressBuffers[i], LocalMemory.getCodeAddr(),
+			   LocalMemory.getCodeBytes().length).call(origBytes);
     }
 
-    public void testAsycnPeeksRegisters()
-    {
-      // Check position() and (async) get()
-      int length = 8;
-      byte[] origBytes = new byte[length];
-      long address = 4;
-      for (int i = 0; i < registerBuffers.length; i++)
-	{
-	  registerBuffers[i].position(address);
-	  registerBuffers[i].get(origBytes);
-	  new AsyncPeeks(registerBuffers[i], address,
-			 length).call(origBytes);
+    public void testAsycnPeeksRegisters() {
+	// Check position() and (async) get()
+	int length = 8;
+	byte[] origBytes = new byte[length];
+	long address = 4;
+	for (int i = 0; i < registerBuffers.length; i++) {
+	    registerBuffers[i].position(address);
+	    registerBuffers[i].get(origBytes);
+	    new AsyncPeeks(registerBuffers[i], address,
+			   length).call(origBytes);
 	}
     }
 
-  private void verifyBulkPut(ByteBuffer buffer, long addr, int len)
-  {
-    // Pasting the same bytes back over the old buffer in bulk
-    // and read it back in.
-    byte[] oldBytes = new byte[len];
-    buffer.position(addr);
-    buffer.get(oldBytes);
-    buffer.position(addr);
-    buffer.put(oldBytes);
-    byte[] newBytes = new byte[len];
-    buffer.position(addr);
-    buffer.get(newBytes);
-    assertTrue(Arrays.equals(oldBytes, newBytes));
-  }
+    private void verifyBulkPut(ByteBuffer buffer, long addr, int len) {
+	// Pasting the same bytes back over the old buffer in bulk
+	// and read it back in.
+	byte[] oldBytes = new byte[len];
+	buffer.position(addr);
+	buffer.get(oldBytes);
+	buffer.position(addr);
+	buffer.put(oldBytes);
+	byte[] newBytes = new byte[len];
+	buffer.position(addr);
+	buffer.get(newBytes);
+	assertTrue(Arrays.equals(oldBytes, newBytes));
+    }
 
-  public void testBulkPutRegisterBuffers()
-  {
-    for (int i = 0; i < registerBuffers.length; i++)
-      verifyBulkPut(registerBuffers[i], 4, 4);
-  }
+    public void testBulkPutRegisterBuffers() {
+	for (int i = 0; i < registerBuffers.length; i++)
+	    verifyBulkPut(registerBuffers[i], 4, 4);
+    }
 
-  public void testBulkPutAddressBuffers()
-  {
-    for (int i = 0; i < addressBuffers.length; i++)
-      verifyBulkPut(addressBuffers[i], LocalMemory.getCodeAddr(),
-		    LocalMemory.getCodeBytes().length);
-  }
+    public void testBulkPutAddressBuffers() {
+	for (int i = 0; i < addressBuffers.length; i++)
+	    verifyBulkPut(addressBuffers[i], LocalMemory.getCodeAddr(),
+			  LocalMemory.getCodeBytes().length);
+    }
 
-  public void testMemoryBufferCapacity() 
-  {
-    Task task = new DaemonBlockedAtEntry("funit-slave").getMainTask();
-    switch(task.getISA().wordSize()){
+    public void testMemoryBufferCapacity() {
+	Task task = new DaemonBlockedAtEntry("funit-slave").getMainTask();
+	switch(task.getISA().wordSize()){
 	case 4:
-		assertEquals("Memory Buffer Capacity: ", 0xffffffffL,
-		     task.getMemory().capacity());
-		break;
+	    assertEquals("Memory Buffer Capacity: ", 0xffffffffL,
+			 task.getMemory().capacity());
+	    break;
 	case 8:
-		assertEquals("Memory Buffer Capacity: ", 0xffffffffffffffffL,
-                     task.getMemory().capacity());
-		break;
+	    assertEquals("Memory Buffer Capacity: ", 0xffffffffffffffffL,
+			 task.getMemory().capacity());
+	    break;
 	default:
-		fail("unknown word size");
+	    fail("unknown word size");
 	}
     }
 
diff --git a/frysk-core/frysk/rt/ChangeLog b/frysk-core/frysk/rt/ChangeLog
index 5622595..b438129 100644
--- a/frysk-core/frysk/rt/ChangeLog
+++ b/frysk-core/frysk/rt/ChangeLog
@@ -1,4 +1,17 @@
-2008-06-06   Teresa Thomas  <tthomas@redhat.com>
+2008-06-17  Teresa Thomas  <tthomas@redhat.com>
+
+	* WatchObserverInstaller.java 
+	(WatchpointObserver.updateHit): Print message if value 
+	unchanged before and after access.
+	(install): Throw exception if numberOfObservers 
+	calculated is 0.
+	
+2008-06-11  Teresa Thomas  <tthomas@redhat.com>
+
+	* WatchObserverInstaller.java (install): Use Location.length()
+	instead of Type.getSize().
+
+2008-06-06  Teresa Thomas  <tthomas@redhat.com>
 
 	* Breakpoint.java (updateHit): Update log message.
 
diff --git a/frysk-core/frysk/rt/WatchObserverInstaller.java b/frysk-core/frysk/rt/WatchObserverInstaller.java
index df0034d..1d376b3 100644
--- a/frysk-core/frysk/rt/WatchObserverInstaller.java
+++ b/frysk-core/frysk/rt/WatchObserverInstaller.java
@@ -91,8 +91,8 @@ public class WatchObserverInstaller {
 	                      (task.getISA()).getWatchpointMaxLength();
 	
 	long variableAddress = expr.getLocation().getAddress();
-	int variableLength = expr.getType().getSize();
-
+	int variableLength = (int)expr.getLocation().length();
+	
 	if (variableLength > (watchpointCount-watchpointsInUse) * maxWatchLength ) {
 	    throw new RuntimeException ("Watch error: Available watchpoints not " +
 	    		                "sufficient to watch complete value.");
@@ -102,6 +102,11 @@ public class WatchObserverInstaller {
 	// to completely watch the variable.
 	int numberOfObservers = (int)Math.ceil((double)variableLength/
 	                           	       (double)maxWatchLength);
+	
+	if (numberOfObservers == 0) {
+	    throw new RuntimeException ("Error: Watchpoint cannot be installed");
+	}
+	
 	int observerNumber = 1;
 	
 	// Add watchpoint observers to task. 
@@ -156,11 +161,15 @@ public class WatchObserverInstaller {
 	public Action updateHit(Task task, long address, int length) {
 
 	    String newValue = expr.getValue().toPrint
-	    (Format.NATURAL, task.getMemory());
+	                        (Format.NATURAL, task.getMemory());
 
 	    String watchMessage = "Watchpoint hit: " + exprString + "\n" +
 	                          "   Value before hit = " + oldValue + "\n" +
 	                          "   Value after  hit = " + newValue + "\n";
+	    
+	    if (oldValue.equals(newValue)) {
+		watchMessage += "Note: Value unchanged before and after access\n";
+	    }
 	    // Remember the previous value
 	    oldValue = newValue;
 
diff --git a/frysk-core/frysk/scopes/ChangeLog b/frysk-core/frysk/scopes/ChangeLog
index 670e7f5..ff21a6f 100644
--- a/frysk-core/frysk/scopes/ChangeLog
+++ b/frysk-core/frysk/scopes/ChangeLog
@@ -1,3 +1,8 @@
+2008-06-10  Andrew Cagney  <cagney@redhat.com>
+
+	* Function.java (printParameters): Add boolean printValues
+	parameter.
+
 2008-06-06  Andrew Cagney  <cagney@redhat.com>
 
 	* TestScopeFactory.java: Let DwflDie adjust for bias.
diff --git a/frysk-core/frysk/scopes/Function.java b/frysk-core/frysk/scopes/Function.java
index 71d3f8a..cc4c426 100644
--- a/frysk-core/frysk/scopes/Function.java
+++ b/frysk-core/frysk/scopes/Function.java
@@ -227,19 +227,17 @@ public class Function extends NamedScope {
 
     }
     
-    public void printParameters (PrintWriter writer, DebugInfoFrame frame)
-    {
-      
-      Iterator iterator = this.parameters.iterator();
-      while(iterator.hasNext()) {
-        Variable parameter = (Variable) iterator.next();
-	parameter.toPrint(writer, frame);
-	writer.flush();
-        if(parameters.indexOf(parameter) < (this.parameters.size()-1)){
-            writer.print(",");
-        }
-      }
-      
+    public void printParameters(PrintWriter writer, DebugInfoFrame frame,
+				boolean printValues) {
+	Iterator iterator = this.parameters.iterator();
+	while(iterator.hasNext()) {
+	    Variable parameter = (Variable) iterator.next();
+	    parameter.toPrint(writer, frame);
+	    writer.flush();
+	    if(parameters.indexOf(parameter) < (this.parameters.size()-1)){
+		writer.print(",");
+	    }
+	}
     }
     
 }
diff --git a/frysk-core/frysk/solib/ChangeLog b/frysk-core/frysk/solib/ChangeLog
index c1f7205..529a5a1 100644
--- a/frysk-core/frysk/solib/ChangeLog
+++ b/frysk-core/frysk/solib/ChangeLog
@@ -1,3 +1,8 @@
+2008-06-23  Rick Moseley  <rmoseley@redhat.com>
+
+	* DynamicSegment.java: Made getEntryPoint public.
+
+
 2008-03-10  Andrew Cagney  <cagney@redhat.com>
 
 	* MemoryMapFactory.java: Update to match MemoryMap.
diff --git a/frysk-core/frysk/solib/DynamicSegment.java b/frysk-core/frysk/solib/DynamicSegment.java
index e773894..d9a98c5 100644
--- a/frysk-core/frysk/solib/DynamicSegment.java
+++ b/frysk-core/frysk/solib/DynamicSegment.java
@@ -51,7 +51,7 @@ import frysk.proc.Auxv;
  * to extract the information are all closed.
  */
 
-class DynamicSegment {
+public class DynamicSegment {
     private static final Log fine = Log.fine(DynamicSegment.class);
 
     final long addr;
@@ -99,7 +99,7 @@ class DynamicSegment {
      * Helper function to locate and report the backing Executables
      * entry point
      */
-    private static long getEntryPoint(Elf exeElf) {
+    public static long getEntryPoint(Elf exeElf) {
 	fine.log("getEntryPoint", exeElf);
 	ElfEHeader eHeader = exeElf.getEHeader();
 	if (eHeader == null)
diff --git a/frysk-core/frysk/stack/ChangeLog b/frysk-core/frysk/stack/ChangeLog
index 4f95b4b..8e99fc2 100644
--- a/frysk-core/frysk/stack/ChangeLog
+++ b/frysk-core/frysk/stack/ChangeLog
@@ -1,3 +1,22 @@
+2008-06-11  Andrew Cagney  <cagney@redhat.com>
+
+	* Frame.java: Drop space in "function ()".
+
+2008-06-10  Andrew Cagney  <cagney@redhat.com>
+
+	* Frame.java (toPrint): Use printLibraryPaths.
+	* PrintStackOptions.java (printLibraryPaths): Replace printFullPaths.
+	(setPrintPaths(boolean)): New.
+
+	* Frame.java (printLibraryName(PrintWriter,PrintStackOptions)): New.
+	(toPrint(PrintWriter,PrintStackOptions)): Use.
+	
+	* Frame.java (toPrint(PrintWriter,PrintStackOptions)): Replace
+	toPrint(PrintWriter,boolean,boolean).
+	(toPrint(PrintWriter)): Delete.
+	* PrintStackOptions.java: New.
+	* StackFactory.java: Use.
+
 2008-06-03  Andrew Cagney  <cagney@redhat.com>
 
 	* TestFrame.java: Use DwflModule.getModules() and not
diff --git a/frysk-core/frysk/stack/Frame.java b/frysk-core/frysk/stack/Frame.java
index 285aee7..6ba3dc1 100644
--- a/frysk-core/frysk/stack/Frame.java
+++ b/frysk-core/frysk/stack/Frame.java
@@ -46,7 +46,6 @@ import java.io.StringWriter;
 import lib.dwfl.Dwfl;
 import lib.dwfl.DwflModule;
 import frysk.dwfl.DwflCache;
-import frysk.dwfl.DwflFactory;
 import frysk.isa.registers.Register;
 import frysk.proc.Task;
 import frysk.rsl.Log;
@@ -150,43 +149,45 @@ public abstract class Frame {
      * Write a simple string representation of this stack frame.
      * @param printWriter
      */
-    public void toPrint (PrintWriter writer) {
-	toPrint(writer, true, true);
-    }
-
-    /**
-     * Write a simple string representation of this stack frame.
-     * @param printWriter
-     */
-    public void toPrint (PrintWriter writer, boolean printSource, boolean fullpath) {
+    public void toPrint(PrintWriter writer, PrintStackOptions options) {
 	writer.write(ArchFormatter.toHexString(getTask(), getAddress()));
 	// the symbol, if known append (), ..
 	Symbol symbol = getSymbol();
 	writer.write(" in ");
 	writer.write(symbol.getDemangledName());
-	if (symbol != SymbolFactory.UNKNOWN)
-	    writer.write(" ()");
-	
-	if(printSource){
+	if (symbol != SymbolFactory.UNKNOWN) {
+	    // XXX: Perhaps this should not print the ().
+	    writer.write("()");
+	}
+	printLibraryName(writer, options);
+    }
+
+    /**
+     * If requrested by the stack options, print the library name
+     * using the form " from LIBRARY".
+     */
+    protected void printLibraryName(PrintWriter writer,
+				    PrintStackOptions options) {
+	if (options.printLibraryNames()) {
 	    // the library if known ...
-	    File library = new File(getLibraryName());
+	    String library = getLibraryName();
 	    if (library != null) {
 		writer.print(" from ");
-	
-		if(DwflFactory.isVDSO(this.getTask().getProc(), this.getTask().getProc().getMap(getAdjustedAddress()))
-			|| library.getName().contains("[stack]")){
-		    writer.print(library.getName());
-		}else{
-		
-		    if(fullpath){
-			writer.print(library.getPath());
-		    }else{
-			writer.print(".../"+library.getName());
+		if (library.startsWith("[")) {
+		    // Things like [vdso], [stack], ...
+		    writer.print(library);
+		} else {
+		    // Should there be separate libraryFullPath?
+		    if (options.printLibraryPaths()) {
+			writer.print(library);
+		    } else {
+			// Discard the path
+			writer.print(new File(library).getName());
 		    }
 		    
 		}
 	    }
-	}	    
+	}
     }
   
     public String getLibraryName() {
@@ -195,7 +196,7 @@ public abstract class Frame {
 	if (dwflModule != null) {
 	    return dwflModule.getName();
 	} else {
-	    return "Unknown";
+	    return null;
 	}
     }
 
@@ -209,7 +210,7 @@ public abstract class Frame {
          PrintWriter pw = new PrintWriter(sw);
          pw.print(this.getClass().getName());
          pw.print('[');
-         toPrint(pw, false, false);
+         toPrint(pw, PrintStackOptions.DEFAULT);
          pw.print(']');
          pw.flush();
          return sw.toString();
diff --git a/frysk-core/frysk/stack/PrintStackOptions.java b/frysk-core/frysk/stack/PrintStackOptions.java
new file mode 100644
index 0000000..2e3f161
--- /dev/null
+++ b/frysk-core/frysk/stack/PrintStackOptions.java
@@ -0,0 +1,110 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2007, 2008, Red Hat Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+package frysk.stack;
+
+public class PrintStackOptions {
+
+    static final PrintStackOptions DEFAULT = new PrintStackOptions();
+
+    private int numberOfFrames = 10;
+
+    private boolean printLibraryPaths;
+    private boolean printLibraryNames;
+    
+    public PrintStackOptions() {
+	clear();
+    }
+
+    /**
+     * Clear all stack options, a very raw ABI stack trace will be
+     * produced.
+     */
+    public void clear() {
+	printLibraryPaths = false;
+	printLibraryNames = false;
+    }
+    
+    /**
+     * Generate an ABI backtrace using ELF symbols and shared library
+     * names.
+     */
+    public void setAbi() {
+	clear();
+	printLibraryPaths = false;
+	printLibraryNames = true;
+    }
+
+    /**
+     * Include the full path to any files.
+     */
+    public void setPrintPaths(boolean printPaths) {
+	setPrintLibraryPaths(printPaths);
+    }
+
+    /**
+     * Specify the number of frames to include in the back-trace, 0 to
+     * include all frames.
+     */
+    public void setNumberOfFrames(int numberOfFrames) {
+	this.numberOfFrames = numberOfFrames;
+    }
+    public int numberOfFrames() {
+	return numberOfFrames;
+    }
+
+    public void setPrintLibraryPaths(boolean printLibraryPaths) {
+	this.printLibraryPaths = printLibraryPaths;
+    }
+    public boolean printLibraryPaths() {
+	return printLibraryPaths;
+    }
+
+    public void setPrintLibraryNames(boolean printLibraryNames) {
+	this.printLibraryNames = printLibraryNames;
+    }
+    public boolean printLibraryNames() {
+	return printLibraryNames;
+    }
+
+    public boolean abiOnly() {
+	return true;
+    }
+    
+}
diff --git a/frysk-core/frysk/stack/StackFactory.java b/frysk-core/frysk/stack/StackFactory.java
index 358adb2..c1e05e5 100644
--- a/frysk-core/frysk/stack/StackFactory.java
+++ b/frysk-core/frysk/stack/StackFactory.java
@@ -44,7 +44,6 @@ import java.io.PrintWriter;
 import java.util.WeakHashMap;
 
 import lib.unwind.Cursor;
-import frysk.debuginfo.PrintStackOptions;
 import frysk.proc.Task;
 
 public class StackFactory
@@ -87,23 +86,25 @@ public class StackFactory
     }
 
     public static final void printTaskStackTrace(PrintWriter writer,
-						 Task task, PrintStackOptions options) {
+						 Task task,
+						 PrintStackOptions options) {
 	if (task != null) {
 	    writer.print("Task #");
 	    writer.print(task.getTid());
 	    writer.println();
 	    Frame frame = StackFactory.createFrame(task);
 	    for (int i = 0; frame != null; frame = frame.getOuter(),i++) {
-		
-		if (options.numberOfFrames() > 0 && i >= options.numberOfFrames()) {
+		if (options.numberOfFrames() > 0
+		    && i >= options.numberOfFrames()) {
 		    writer.println("...");
 		    break;
+		} else if (options.numberOfFrames() < 0
+			   && i >= -options.numberOfFrames()) {
+		    break;
 		}
-		
 		frame.printLevel(writer);
 		writer.print(" ");
-		frame.toPrint(writer, options.printLibraries(),
-			      options.printFullPaths());
+		frame.toPrint(writer, options);
 		writer.println();
 	    }
 	}
@@ -114,7 +115,7 @@ public class StackFactory
 	for (; frame != null; frame = frame.getOuter()) {
 	    frame.printLevel(writer);
 	    writer.print(" ");
-	    frame.toPrint(writer);
+	    frame.toPrint(writer, PrintStackOptions.DEFAULT);
 	    writer.println();
 	}
     }
diff --git a/frysk-core/frysk/symtab/ChangeLog b/frysk-core/frysk/symtab/ChangeLog
index ba96d4e..33bc6fb 100644
--- a/frysk-core/frysk/symtab/ChangeLog
+++ b/frysk-core/frysk/symtab/ChangeLog
@@ -1,3 +1,13 @@
+2008-06-19  Andrew Cagney  <cagney@redhat.com>
+
+	* TestSymbol.java (testNoSymbolAfterGlobal()): Enable.
+	(testNoSymbolAfterLocal()): Enable.
+	(testAfterGlobalContiningSize0()): Enable.
+	(testAfterLocalContiningSize0()): Enable.
+	
+	* TestSymbol.java: Re-number arg param so that matching
+	funit-symbols.S is easier.
+
 2008-06-05  Andrew Cagney  <cagney@redhat.com>
 
 	* DwflSymbol.java: Use DwflDie.
diff --git a/frysk-core/frysk/symtab/TestSymbol.java b/frysk-core/frysk/symtab/TestSymbol.java
index 79bf39a..a0228b3 100644
--- a/frysk-core/frysk/symtab/TestSymbol.java
+++ b/frysk-core/frysk/symtab/TestSymbol.java
@@ -46,13 +46,13 @@ import frysk.testbed.DaemonBlockedAtSignal;
 public class TestSymbol
     extends TestLib
 {
-    private void symbolTest (String command, int numberOfArgs,
-			     String name, boolean addressValid,
-			     boolean sizeValid) {
-	// Construct an argument list containing numberOfArgs dummy
-	// arguments.  The inferior program just looks at ARGC to
-	// determine what to do.
-	String[] fullCommand = new String[numberOfArgs + 1];
+    private void symbolTest(String command, int numberOfArgs,
+			    String name, boolean addressValid,
+			    boolean sizeValid) {
+	// Construct an argument list numberOfArgs long (including
+	// arg[0] the program).  The inferior program just looks at
+	// ARGC to determine what to do.
+	String[] fullCommand = new String[numberOfArgs];
 	fullCommand[0] =  getExecPath (command);
     	for (int i = 1; i < fullCommand.length; i++) {
 	    fullCommand[i] = Integer.toString(i);
@@ -80,128 +80,120 @@ public class TestSymbol
     private String unknown = SymbolFactory.UNKNOWN.getName ();
 
     public void testDebug () {
-	symbolTest("funit-symbols", 1, "global_st_size", true, true);
+	symbolTest("funit-symbols", 2, "global_st_size", true, true);
     }
   
     public void testNoDebug () {
-	symbolTest("funit-symbols-nodebug", 1, "global_st_size", true, true);
+	symbolTest("funit-symbols-nodebug", 2, "global_st_size", true, true);
     }
   
     public void testStripped () {
-	symbolTest("funit-symbols-stripped", 1, unknown, false, false);
+	symbolTest("funit-symbols-stripped", 2, unknown, false, false);
     }
   
     public void testStaticDebug () {
-	symbolTest("funit-symbols", 2, "local_st_size", true, true);
+	symbolTest("funit-symbols", 3, "local_st_size", true, true);
     }
   
     public void testStaticNoDebug () {
-	symbolTest("funit-symbols-nodebug", 2, "local_st_size", true, true);
+	symbolTest("funit-symbols-nodebug", 3, "local_st_size", true, true);
     }
   
     public void testStaticStripped () {
-	symbolTest("funit-symbols-stripped", 2, unknown, false, false);
+	symbolTest("funit-symbols-stripped", 3, unknown, false, false);
     }
   
     public void testNoSize() {
-	symbolTest("funit-symbols", 3, "global_st_size_0", true, false);
+	symbolTest("funit-symbols", 4, "global_st_size_0", true, false);
     }
   
     public void testNoDebugNoSize() {
-	symbolTest("funit-symbols-nodebug", 3, "global_st_size_0",
+	symbolTest("funit-symbols-nodebug", 4, "global_st_size_0",
 		   true, false);   
     }
   
     public void testStrippedNoSize() {
-	symbolTest("funit-symbols-stripped", 3, unknown, false, false);    
+	symbolTest("funit-symbols-stripped", 4, unknown, false, false);    
     }
   
     public void testStaticNoSize() {
-	symbolTest("funit-symbols", 4, "local_st_size_0", true, false);    
+	symbolTest("funit-symbols", 5, "local_st_size_0", true, false);    
     }
     public void testStaticNoDebugNoSize() {
-	symbolTest("funit-symbols-nodebug", 4, "local_st_size_0", true, false);   
+	symbolTest("funit-symbols-nodebug", 5, "local_st_size_0", true, false);   
     }
     public void testStaticStrippedNoSize() {
-	symbolTest("funit-symbols-stripped", 4, unknown, false, false);    
+	symbolTest("funit-symbols-stripped", 5, unknown, false, false);    
     }
 
     public void testGlobalInGlobal() {
-	symbolTest(5, "global_in_global", true, true);
+	symbolTest(6, "global_in_global", true, true);
     }
     public void testLocalInGlobal() {
         if (unresolved(5941))
             return;
-	symbolTest(6, "local_in_global", true, true);
+	symbolTest(7, "local_in_global", true, true);
     }
     public void testGlobalInLocal() {
-	symbolTest(7, "global_in_local", true, true);
+	symbolTest(8, "global_in_local", true, true);
     }
     public void testLocalInLocal() {
-	symbolTest(8, "local_in_local", true, true);
+	symbolTest(9, "local_in_local", true, true);
     }
 
     public void testGlobalAfterNested() {
-	symbolTest(9, "global_outer", true, true);
+	symbolTest(10, "global_outer", true, true);
     }
     public void testLocalAfterNested() {
-	symbolTest(10, "local_outer", true, true);
+	symbolTest(11, "local_outer", true, true);
     }
 
     public void testNoSymbolAfterGlobal() {
-        if (unresolved(5941))
-            return;
-	symbolTest(11, unknown, false, false);
+	symbolTest(12, unknown, false, false);
     }
     public void testNoSymbolAfterLocal() {
-        if (unresolved(5941))
-            return;
-	symbolTest(12, unknown, false, false);
+	symbolTest(13, unknown, false, false);
     }
 
     public void testGlobalSize0InGlobal() {
-	symbolTest(13, "global_after_0", true, true);
+	symbolTest(14, "global_after_0", true, true);
     }
     public void testLocalSize0InGlobal() {
-	symbolTest(14, "global_after_0", true, true);
+	symbolTest(15, "global_after_0", true, true);
     }
     public void testGlobalSize0InLocal() {
-	symbolTest(15, "local_after_0", true, true);
+	symbolTest(16, "local_after_0", true, true);
     }
     public void testLocalSize0InLocal() {
-	symbolTest(16, "local_after_0", true, true);
+	symbolTest(17, "local_after_0", true, true);
     }
 
     public void testGlobalAfterNestedSize0() {
-	symbolTest(17, "global_after_0", true, true);
+	symbolTest(18, "global_after_0", true, true);
     }
     public void testLocalAfterNestedSize0() {
-	symbolTest(18, "local_after_0", true, true);
+	symbolTest(19, "local_after_0", true, true);
     }
 
     public void testSmallGlobalAtLargeGlobal() {
-	symbolTest(19, "small_global_at_large_global", true, true);
+	symbolTest(20, "small_global_at_large_global", true, true);
     }
     public void testSmallLocalAtLargeGlobal() {
         if (unresolved(5941))
             return;
-	symbolTest(20, "small_local_at_large_global", true, true);
+	symbolTest(21, "small_local_at_large_global", true, true);
     }
     public void testSmallGlobalAtLargeLocal() {
-	symbolTest(21, "small_global_at_large_local", true, true);
+	symbolTest(22, "small_global_at_large_local", true, true);
     }
     public void testSmallLocalAtLargeLocal() {
-	symbolTest(22, "small_local_at_large_local", true, true);
+	symbolTest(23, "small_local_at_large_local", true, true);
     }
 
     public void testAfterGlobalContiningSize0() {
-        if (unresolved(5941))
-            return;
-	symbolTest(23, unknown, false, false);
+	symbolTest(24, unknown, false, false);
     }
     public void testAfterLocalContiningSize0() {
-        if (unresolved(5941))
-            return;
-	symbolTest(24, unknown, false, false);
+	symbolTest(25, unknown, false, false);
     }
 }
diff --git a/frysk-core/frysk/testbed/ChangeLog b/frysk-core/frysk/testbed/ChangeLog
index 1babdc8..90aee82 100644
--- a/frysk-core/frysk/testbed/ChangeLog
+++ b/frysk-core/frysk/testbed/ChangeLog
@@ -1,3 +1,12 @@
+2008-06-11  Rick Moseley  <rmoseley@redhat.com>
+
+	* CorefileFactory.java: Change method to call
+	DaemonBlockedAtEntry instead of DaemonBlockedAtSignal.
+
+2008-06-10  Rick Moseley  <rmoseley@redhat.com>
+
+	* CorefileFactory.java: Add method to pass args.
+
 2008-06-06  Rick Moseley  <rmoseley@redhat.com>
 
 	* SlaveOffspring.java: Add methods to accept commandline args.
diff --git a/frysk-core/frysk/testbed/CorefileFactory.java b/frysk-core/frysk/testbed/CorefileFactory.java
index 18d9354..571869d 100644
--- a/frysk-core/frysk/testbed/CorefileFactory.java
+++ b/frysk-core/frysk/testbed/CorefileFactory.java
@@ -74,6 +74,21 @@ public class CorefileFactory extends TestLib {
 	    = new DaemonBlockedAtSignal(exeFile).getMainTask().getProc();
 	return constructCore(ackProc);
     }
+    
+    /**
+     * Given a path to an executable it will run it until it sigfaults
+     * then extracts a corefile at that point, and return a File
+     * representing that core file.
+     */
+    public static File constructCoreAtEntry(File exeFile, String[] args) {
+	String[] newargs = new String[args.length + 1];
+	newargs[0] = exeFile.getAbsolutePath();
+	for (int i = 0; i < args.length; i++)
+	    newargs[i+1] = args[i];
+	final Proc ackProc
+	    = new DaemonBlockedAtEntry(newargs).getMainTask().getProc();
+	return constructCore(ackProc);
+    }
 
     /**
      * Given a path to an executable it will run it until it sigfaults
diff --git a/frysk-core/frysk/util/ChangeLog b/frysk-core/frysk/util/ChangeLog
index bf95319..30aa6e4 100644
--- a/frysk-core/frysk/util/ChangeLog
+++ b/frysk-core/frysk/util/ChangeLog
@@ -1,3 +1,31 @@
+2008-06-13  Petr Machata  <pmachata@redhat.com>
+
+	* Glob.java: Support ! as character set negation operator.
+	* TestGlob.java: New class, suite of test cases for Glob compiler.
+
+2008-06-12  Andrew Cagney  <cagney@redhat.com>
+
+	* CommandlineParser.java: Catch UserException, not
+	RuntimeException.
+
+2008-06-11  Andrew Cagney  <cagney@redhat.com>
+
+	* StackPrintUtil.java: Fix typo - missing \n.
+
+	* TestStackTraceAction.java: Update to match stack backtrace.
+
+2008-06-10  Andrew Cagney  <cagney@redhat.com>
+
+	* TestStackTraceAction.java: Use setPrintPaths.
+	* stack-options.xml: Add paths, lib-paths, src-paths, values to
+	print options.
+	
+	* TestStackTraceAction.java: Use PrintDebugInfoStackOptions.
+	* StackPrintUtil.java: Ditto.
+	* StacktraceAction.java: Ditto.
+	* FCatch.java: Ditto.
+	* StressTestStackTraceAction.java: Ditto.
+
 2008-05-20  Andrew Cagney  <cagney@redhat.com>
 
 	* CommandlineParser.java (isCoreFile(String))
diff --git a/frysk-core/frysk/util/CommandlineParser.java b/frysk-core/frysk/util/CommandlineParser.java
index d2887f8..e0c6a32 100644
--- a/frysk-core/frysk/util/CommandlineParser.java
+++ b/frysk-core/frysk/util/CommandlineParser.java
@@ -39,6 +39,7 @@
 
 package frysk.util;
 
+import frysk.UserException;
 import frysk.config.FryskVersion;
 import java.io.File;
 import java.util.LinkedList;
@@ -160,12 +161,14 @@ public abstract class CommandlineParser {
 	    String[] result = doParse(args);
 	    validate();
 	    return result;
-	} catch (Exception e) {
+	} catch (OptionException e) {
 	    fine.log(this, "parse failed", e);
-	    if (e.getMessage() == null)
-		System.err.println("Error: " + e.toString());
-	    else
-		System.err.println("Error: " + e.getMessage());
+	    System.err.println("Error: " + e.getMessage());
+	    System.exit(1);
+	    return null; // To fool Java
+	} catch (UserException e) {
+	    fine.log(this, "external problem", e);
+	    System.err.println("Error: " + e.getMessage());
 	    System.exit(1);
 	    return null; // To fool Java
 	}
diff --git a/frysk-core/frysk/util/FCatch.java b/frysk-core/frysk/util/FCatch.java
index 476ffe8..3157ed9 100644
--- a/frysk-core/frysk/util/FCatch.java
+++ b/frysk-core/frysk/util/FCatch.java
@@ -43,7 +43,7 @@ import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.util.HashMap;
 
-import frysk.debuginfo.PrintStackOptions;
+import frysk.debuginfo.PrintDebugInfoStackOptions;
 import frysk.isa.signals.Signal;
 import frysk.proc.Action;
 import frysk.proc.Task;
@@ -54,7 +54,8 @@ import gnu.classpath.tools.getopt.OptionGroup;
 public class FCatch {
     private static final Log fine = Log.fine(FCatch.class);
 
-    private final PrintStackOptions stackPrintOptions = new PrintStackOptions();
+    private final PrintDebugInfoStackOptions stackPrintOptions
+	= new PrintDebugInfoStackOptions();
 
     private PrintWriter printWriter = new PrintWriter(System.out);
     HashMap signaledTasks = new HashMap();
diff --git a/frysk-core/frysk/util/Glob.java b/frysk-core/frysk/util/Glob.java
index 96c40c4..0bb0632 100644
--- a/frysk-core/frysk/util/Glob.java
+++ b/frysk-core/frysk/util/Glob.java
@@ -1,6 +1,6 @@
 // This file is part of the program FRYSK.
 //
-// Copyright 2005, 2006, 2007, 2008, Red Hat Inc.
+// Copyright 2007, 2008, Red Hat Inc.
 //
 // FRYSK is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by
@@ -44,53 +44,57 @@ import java.util.regex.PatternSyntaxException;
 
 public class Glob {
 
-    private static int matchCharacterClass(String glob, int from)
+    private static int matchCharacterClass(char[] glob, int from)
 	throws PatternSyntaxException
     {
 	int i = from + 2;
-	while (glob.charAt(++i) != ':' && i < glob.length())
+	while (glob[++i] != ':' && i < glob.length)
 	    continue;
-	if (i >= glob.length() || glob.charAt(++i) != ']')
+	if (i >= glob.length || glob[++i] != ']')
 	    throw new PatternSyntaxException
-		("Unmatched '['.", glob, from);
+		("Unmatched '['.", new String(glob), from);
 	return i;
     }
 
-    private static int matchBrack(String glob, int from)
+    private static int matchBrack(char[] glob, int from)
 	throws PatternSyntaxException
     {
 	int i = from + 1;
 
-	if (glob.charAt(i) == '^') // Complement operator.
+	// Complement operator.
+	if (glob[i] == '^')
 	    ++i;
+	else if (glob[i] == '!')
+	    glob[i++] = '^';
 
 	// On first character, both [ and ] are legal.  But when [ is
 	// foolowed with :, it's character class.
-	if (glob.charAt(i) == '[' && glob.charAt(i + 1) == ':')
+	if (glob[i] == '[' && glob[i + 1] == ':')
 	    i = matchCharacterClass(glob, i) + 1;
 	else
 	    ++i; // skip any character, including [ or ]
 	boolean escape = false;
-	for (; i < glob.length(); ++i) {
-	    char c = glob.charAt(i);
+	for (; i < glob.length; ++i) {
+	    char c = glob[i];
 	    if (escape) {
 		++i;
 		escape = false;
 	    }
-	    else if (c == '[' && glob.charAt(i + 1) == ':')
+	    else if (c == '[' && glob[i + 1] == ':')
 		i = matchCharacterClass(glob, i);
 	    else if (c == ']')
 		return i;
 	}
 	throw new PatternSyntaxException
-	    ("Unmatched '" + glob.charAt(from) + "'.", glob, from);
+	    ("Unmatched '" + glob[from] + "'.", new String(glob), from);
     }
 
-    private static String toRegex(String glob) {
+    // Package private so that TestGlob can access it.
+    static String toRegex(char[] glob) {
 	StringBuffer buf = new StringBuffer();
 	boolean escape = false;
-	for(int i = 0; i < glob.length(); ++i) {
-	    char c = glob.charAt(i);
+	for(int i = 0; i < glob.length; ++i) {
+	    char c = glob[i];
 	    if (escape) {
 		if (c == '\\')
 		    buf.append("\\\\");
@@ -107,7 +111,7 @@ public class Glob {
 		    escape = true;
 		else if (c == '[') {
 		    int j = matchBrack(glob, i);
-		    buf.append(glob.substring(i, j+1));
+		    buf.append(glob, i, j - i + 1);
 		    i = j;
 		}
 		else if (c == '*')
@@ -124,10 +128,10 @@ public class Glob {
     }
 
     public static Pattern compile(String glob) {
-	return Pattern.compile(toRegex(glob));
+	return Pattern.compile(toRegex(glob.toCharArray()));
     }
 
     public static Pattern compile(String glob, int flags) {
-	return Pattern.compile(toRegex(glob), flags);
+	return Pattern.compile(toRegex(glob.toCharArray()), flags);
     }
 }
diff --git a/frysk-core/frysk/util/StackPrintUtil.java b/frysk-core/frysk/util/StackPrintUtil.java
index a4b85ac..ab7fc01 100644
--- a/frysk-core/frysk/util/StackPrintUtil.java
+++ b/frysk-core/frysk/util/StackPrintUtil.java
@@ -47,7 +47,7 @@ import java.util.StringTokenizer;
 import gnu.classpath.tools.getopt.Option;
 import gnu.classpath.tools.getopt.OptionException;
 import gnu.classpath.tools.getopt.OptionGroup;
-import frysk.debuginfo.PrintStackOptions;
+import frysk.debuginfo.PrintDebugInfoStackOptions;
 
 /**
  * Framework for printing stack backtraces; both providing a standard
@@ -58,7 +58,10 @@ public class StackPrintUtil {
      * Create, in a separate group, the standard set of stack-print
      * options provided by utilities.
      */
-    public static OptionGroup options(final PrintStackOptions options) {
+    public static OptionGroup options(final PrintDebugInfoStackOptions options) {
+	// Set the default, which matches the documentation; and is
+	// consistent across all utilities.
+	options.setAbi();
 	OptionGroup group = new OptionGroup("Stack print options");
 	group.add(new Option("number-of-frames",
 			     ("number of frames to print.  Specify '0' or"
@@ -90,11 +93,12 @@ public class StackPrintUtil {
 	group.add(new Option
 		  ("print", "select the back-trace information to display\n"
 		   + "OPTION is:\n"
-		   + "debug-names: use debug-info names (e.g., DWARF)\n"
-		   + "full-path: include the full (untruncated) path to files\n"
+		   + "debug-names: print debug-info names (e.g., DWARF)\n"
+		   + "paths: include the full path to source files (src-paths) and libraries (lib-paths)\n"
 		   + "inline: include inlined frames\n"
-		   + "locals: include each functions local variables\n"
-		   + "params: include function parameters\n"
+		   + "locals: include each function's local variables\n"
+		   //+ "params: include function parameters\n"
+		   + "values: include values of parameters and variables\n"
 		   + "OPTIONs can be negated by prefixing a '-'",
 		   "OPTION,...") {
 		public void parsed(String arg) throws OptionException {
@@ -110,14 +114,20 @@ public class StackPrintUtil {
 			}
 			if (name.equals("debug-names")) {
 			    options.setPrintDebugNames(val);
-			} else if (name.equals("full-path")) {
-			    options.setPrintFullPaths(val);
+			} else if (name.equals("paths")) {
+			    options.setPrintPaths(val);
+			} else if (name.equals("lib-paths")) {
+			    options.setPrintLibraryPaths(val);
+			} else if (name.equals("src-paths")) {
+			    options.setPrintSourcePaths(val);
 			} else if (name.equals("inline")) {
 			    options.setPrintInlineFunctions(val);
 			} else if (name.equals("locals")) {
 			    options.setPrintLocals(val);
 			} else if (name.equals("params")) {
-			    options.setPrintParams(val);
+			    options.setPrintParameters(val);
+			} else if (name.equals("values")) {
+			    options.setPrintValues(val);
 			} else {
 			    throw new OptionException
 				("unknown -print OPTION: " + name);
@@ -132,9 +142,9 @@ public class StackPrintUtil {
      * Given a task, a writer, and the selected stack-print-options,
      * produce a stack back-trace.
      */
-    public static void print(Task task, PrintStackOptions options,
+    public static void print(Task task, PrintDebugInfoStackOptions options,
 			     PrintWriter printWriter) {
-          if (options.elfOnly()) {
+          if (options.abiOnly()) {
               StackFactory.printTaskStackTrace(printWriter, task, options);
           } else if (options.printInlineFunctions()) {
 	      DebugInfoStackFactory.printVirtualTaskStackTrace(printWriter,
diff --git a/frysk-core/frysk/util/StacktraceAction.java b/frysk-core/frysk/util/StacktraceAction.java
index e3b9a70..9b83662 100644
--- a/frysk-core/frysk/util/StacktraceAction.java
+++ b/frysk-core/frysk/util/StacktraceAction.java
@@ -45,7 +45,7 @@ import java.util.Iterator;
 import java.util.TreeMap;
 import frysk.rsl.Log;
 import frysk.debuginfo.DebugInfoStackFactory;
-import frysk.debuginfo.PrintStackOptions;
+import frysk.debuginfo.PrintDebugInfoStackOptions;
 import frysk.event.Event;
 import frysk.event.RequestStopEvent;
 import frysk.event.SignalEvent;
@@ -77,7 +77,7 @@ public abstract class StacktraceAction implements ProcBlockObserver {
 
   private Event event;
 
-  PrintStackOptions options;
+  PrintDebugInfoStackOptions options;
   
   /**
    * Runs a stacktrace on the given process.
@@ -97,14 +97,14 @@ public abstract class StacktraceAction implements ProcBlockObserver {
    *            file path is printed other wise only the name of the file is printed.
    * @throws ProcException
    */
-  public StacktraceAction (PrintWriter printWriter, Proc theProc, Event theEvent, PrintStackOptions options)
-  {
-     event = theEvent;
-     
-     this.options = options;
-     this.printWriter = printWriter;
-     Manager.eventLoop.add(new InterruptEvent(theProc));
-  }  
+    public StacktraceAction (PrintWriter printWriter, Proc theProc,
+			     Event theEvent,
+			     PrintDebugInfoStackOptions options) {
+	event = theEvent;
+	this.options = options;
+	this.printWriter = printWriter;
+	Manager.eventLoop.add(new InterruptEvent(theProc));
+    }
 
   public final void existingTask (Task task)
   {
@@ -126,27 +126,27 @@ public abstract class StacktraceAction implements ProcBlockObserver {
 	       "because", w);
   }
 
-  private final void printTasks ()
-  {
-    fine.log(this, "printTasks");
-    Iterator iter = sortedTasks.values().iterator();
-    while (iter.hasNext())
-      {
-	Task task =  (Task) iter.next();
-	
-	if(options.elfOnly()){
-	    StackFactory.printTaskStackTrace(printWriter,task,options);
-	}else{
-	    if(options.printInlineFunctions()){
-		DebugInfoStackFactory.printVirtualTaskStackTrace(printWriter,task,options);
-	    }else{
-		DebugInfoStackFactory.printTaskStackTrace(printWriter,task,options);
-	    }
+    private final void printTasks() {
+	fine.log(this, "printTasks");
+	Iterator iter = sortedTasks.values().iterator();
+	while (iter.hasNext()) {
+	    Task task =  (Task) iter.next();
+	    
+	    if (options.abiOnly()) {
+		StackFactory.printTaskStackTrace(printWriter,task,options);
+	    } else {
+		if (options.printInlineFunctions()) {
+		    DebugInfoStackFactory
+			.printVirtualTaskStackTrace(printWriter,task,options);
+		} else {
+		    DebugInfoStackFactory
+			.printTaskStackTrace(printWriter, task, options);
+		}
 	}
-	printWriter.println();
-      }
-    fine.log(this, "exiting printTasks");
-  }
+	    printWriter.println();
+	}
+	fine.log(this, "exiting printTasks");
+    }
 
   public void flush(){
       this.printWriter.flush();
diff --git a/frysk-core/frysk/util/StressTestStackTraceAction.java b/frysk-core/frysk/util/StressTestStackTraceAction.java
index c454239..75ccf5f 100644
--- a/frysk-core/frysk/util/StressTestStackTraceAction.java
+++ b/frysk-core/frysk/util/StressTestStackTraceAction.java
@@ -43,7 +43,7 @@ package frysk.util;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import frysk.rsl.Log;
-import frysk.debuginfo.PrintStackOptions;
+import frysk.debuginfo.PrintDebugInfoStackOptions;
 import frysk.event.Event;
 import frysk.event.RequestStopEvent;
 import frysk.proc.Manager;
@@ -80,9 +80,9 @@ public class StressTestStackTraceAction extends TestLib {
     FunitThreadsOffspring ackProc = new FunitThreadsOffspring(threads);
     final Proc proc = ackProc.assertRunToFindProc();
 
-    PrintStackOptions options = new PrintStackOptions();
+    PrintDebugInfoStackOptions options = new PrintDebugInfoStackOptions();
     options.setNumberOfFrames(20);
-    options.setPrintParams(true);
+    options.setPrintParameters(true);
     
     StacktraceAction stacker = new StacktraceAction(new PrintWriter(stringWriter),proc, new Event()
     {
diff --git a/frysk-core/frysk/util/TestGlob.java b/frysk-core/frysk/util/TestGlob.java
new file mode 100644
index 0000000..8efa4b8
--- /dev/null
+++ b/frysk-core/frysk/util/TestGlob.java
@@ -0,0 +1,73 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2008, Red Hat Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+package frysk.util;
+
+import frysk.junit.TestCase;
+
+public class TestGlob
+    extends TestCase {
+
+    private void translate(String glob, String expect) {
+	String pattern = Glob.toRegex(glob.toCharArray());
+	assertEquals(glob + " -> " + expect, pattern, expect);
+    }
+
+    public void testGlobs() {
+        translate("*", ".*");
+        translate("?", ".");
+        translate(".*", "\\..*");
+        translate("*.*", ".*\\..*");
+        translate("*a*", ".*a.*");
+        translate("[abc]", "[abc]");
+        translate("[^abc]", "[^abc]");
+        translate("[!abc]", "[^abc]");
+        translate("[]]", "[]]");
+        translate("[[]", "[[]");
+        translate("[^]]", "[^]]");
+        translate("[^a-z]", "[^a-z]");
+        translate("[abc\\]]", "[abc\\]]");
+        translate("[abc\\]def]", "[abc\\]def]");
+        translate("[[:space:]]", "[[:space:]]");
+        translate("[^[:space:]]", "[^[:space:]]");
+        translate("[![:space:]]", "[^[:space:]]");
+        translate("[^a-z]*", "[^a-z].*");
+        translate("[^a-z]bar*", "[^a-z]bar.*");
+    }
+}
diff --git a/frysk-core/frysk/util/TestStackTraceAction.java b/frysk-core/frysk/util/TestStackTraceAction.java
index 0db2626..3fd33cf 100644
--- a/frysk-core/frysk/util/TestStackTraceAction.java
+++ b/frysk-core/frysk/util/TestStackTraceAction.java
@@ -43,7 +43,7 @@ package frysk.util;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import frysk.rsl.Log;
-import frysk.debuginfo.PrintStackOptions;
+import frysk.debuginfo.PrintDebugInfoStackOptions;
 import frysk.event.RequestStopEvent;
 import frysk.proc.Manager;
 import frysk.proc.Proc;
@@ -78,23 +78,23 @@ public class TestStackTraceAction extends TestLib {
 
     static void multiThreaded(SlaveOffspring ackProc,
 			      int numSecondaryThreads) {
-	PrintStackOptions options = new PrintStackOptions();
+	PrintDebugInfoStackOptions options = new PrintDebugInfoStackOptions();
 	options.setNumberOfFrames(20);
-	options.setPrintFullPaths(true);
-	options.setPrintLibraries(true);
+	options.setPrintPaths(true);
+	options.setPrintLibraryNames(true);
 
 	StringWriter stringWriter = new StringWriter();
       
 	String mainThread = "Task #\\d+\n" + "(#[\\d]+ 0x[\\da-f]+ in .*\n)*"
-	    + "#[\\d]+ 0x[\\da-f]+ in server \\(\\).*\n"
-	    + "#[\\d]+ 0x[\\da-f]+ in main \\(\\).*\n"
-	    + "#[\\d]+ 0x[\\da-f]+ in __libc_start_main \\(\\).*\n"
-	    + "#[\\d]+ 0x[\\da-f]+ in _start \\(\\).*\n\n";
+	    + "#[\\d]+ 0x[\\da-f]+ in server\\(\\).*\n"
+	    + "#[\\d]+ 0x[\\da-f]+ in main\\(\\).*\n"
+	    + "#[\\d]+ 0x[\\da-f]+ in __libc_start_main\\(\\).*\n"
+	    + "#[\\d]+ 0x[\\da-f]+ in _start\\(\\).*\n\n";
 	
 	String thread = "Task #\\d+\n" + "(#[\\d]+ 0x[\\da-f]+ in .*\n)*"
-	    + "#[\\d]+ 0x[\\da-f]+ in server \\(\\).*\n"
-	    + "#[\\d]+ 0x[\\da-f]+ in start_thread \\(\\).*\n"
-	    + "#[\\d]+ 0x[\\da-f]+ in (__)?clone \\(\\).*\n\n";
+	    + "#[\\d]+ 0x[\\da-f]+ in server\\(\\).*\n"
+	    + "#[\\d]+ 0x[\\da-f]+ in start_thread\\(\\).*\n"
+	    + "#[\\d]+ 0x[\\da-f]+ in (__)?clone\\(\\).*\n\n";
 	
 	final Proc proc = ackProc.assertRunToFindProc();
 	
diff --git a/frysk-core/frysk/util/stack-options.xml b/frysk-core/frysk/util/stack-options.xml
index 90eeab4..5555d01 100644
--- a/frysk-core/frysk/util/stack-options.xml
+++ b/frysk-core/frysk/util/stack-options.xml
@@ -74,19 +74,36 @@
     </varlistentry>
 
     <varlistentry>
-      <term><option>-print <replaceable>print-option</replaceable>,...</option></term>
+      <term>
+	<option>-print <replaceable>print-option</replaceable>,...</option>
+      </term>
       <listitem>
-	<para>Specify the level of detail to include in a stack
+	<para>
+	  Specify the level of detail to include in a stack
 	  back-trace.  <replaceable>print-option</replaceable> can be
-	  any of: debug-names - use debug information, such as DWARF,
-	  to determine the name of functions; full-path - do not
-	  truncate file paths; inline - include in-line function in
-	  back-trace; locals - to include local variables from each
-	  frame; params - include the values of any parameters.  To
-	  negate a <replaceable>print-option</replaceable> prefix it
-	  with "-".</para></listitem>
+	  any of:
+	</para>
+
+	<para>debug-names: use debug information, such as DWARF, to
+	determine the name of functions</para>
+
+	<para>paths: include the full path to source files and
+	libraries</para>
+
+	<para>inline: include in-line function in back-trace</para>
+
+	<para>locals: to include local variables from each
+	frame</para>
+
+	<para>params: include the function parameters</para>
+	
+	<para>
+	  To negate a <replaceable>print-option</replaceable> prefix
+	  it with "-".
+	</para>
+
+      </listitem>
     </varlistentry>
-    
   </variablelist>
 
 </refsect2>
diff --git a/frysk-core/frysk/value/ByteBufferLocation.java b/frysk-core/frysk/value/ByteBufferLocation.java
index 4aff9e4..915cad9 100644
--- a/frysk-core/frysk/value/ByteBufferLocation.java
+++ b/frysk-core/frysk/value/ByteBufferLocation.java
@@ -106,7 +106,7 @@ public class ByteBufferLocation
 	buffer.putByte(offset, value);
     }
 
-    protected long length() {
+    public long length() {
 	return buffer.capacity();
     }
 }
diff --git a/frysk-core/frysk/value/ChangeLog b/frysk-core/frysk/value/ChangeLog
index fdf4a5e..14a7ad6 100644
--- a/frysk-core/frysk/value/ChangeLog
+++ b/frysk-core/frysk/value/ChangeLog
@@ -1,3 +1,8 @@
+2008-06-11  Teresa Thomas  <tthomas@redhat.com>
+
+	* Location.java (length): Make public.
+	* ByteBufferLocation.java (length): Ditto.	
+
 2008-04-30  Stan Cox  <scox@redhat.com>
 
 	* Type.java (toPrintBrief): New.
diff --git a/frysk-core/frysk/value/Location.java b/frysk-core/frysk/value/Location.java
index 0659547..27b52a0 100644
--- a/frysk-core/frysk/value/Location.java
+++ b/frysk-core/frysk/value/Location.java
@@ -170,9 +170,9 @@ public abstract class Location
 
     /**
      * The length of the location, in bytes.  This MUST be a long (or
-     * BigIneger) as a value's size could be bigger than 32-bits.
+     * BigInteger) as a value's size could be bigger than 32-bits.
      */
-    protected abstract long length();
+    public abstract long length();
     
     /**
      * Print this Location.
diff --git a/frysk-gui/frysk/gui/monitor/ChangeLog b/frysk-gui/frysk/gui/monitor/ChangeLog
index a857f69..5b5d90a 100644
--- a/frysk-gui/frysk/gui/monitor/ChangeLog
+++ b/frysk-gui/frysk/gui/monitor/ChangeLog
@@ -1,3 +1,8 @@
+2008-06-10  Andrew Cagney  <cagney@redhat.com>
+
+	* eventviewer/Event.java: Use PrintDebugInfoStackOptions and
+	setPrintParameters.
+
 2008-04-10  Sami Wagiaalla  <swagiaal@redhat.com>
 
 	* GuiProc.java: updated isOwned() to allow all processes
diff --git a/frysk-gui/frysk/gui/monitor/eventviewer/Event.java b/frysk-gui/frysk/gui/monitor/eventviewer/Event.java
index ad1cf86..824364c 100644
--- a/frysk-gui/frysk/gui/monitor/eventviewer/Event.java
+++ b/frysk-gui/frysk/gui/monitor/eventviewer/Event.java
@@ -48,7 +48,7 @@ import org.gnu.gdk.GdkCairo;
 
 import frysk.debuginfo.DebugInfoFrame;
 import frysk.debuginfo.DebugInfoStackFactory;
-import frysk.debuginfo.PrintStackOptions;
+import frysk.debuginfo.PrintDebugInfoStackOptions;
 import frysk.gui.monitor.GuiObject;
 import frysk.gui.monitor.GuiTask;
 import frysk.gui.monitor.WindowManager;
@@ -225,8 +225,8 @@ public class Event extends GuiObject
      stringWriter.write(this.getName() + ": " + this.getToolTip() + "\n");
     
     if(frame != null){
-	PrintStackOptions options = new PrintStackOptions();
-	options.setPrintParams(true);
+	PrintDebugInfoStackOptions options = new PrintDebugInfoStackOptions();
+	options.setPrintParameters(true);
 	options.setNumberOfFrames(20);
 	DebugInfoStackFactory.printStackTrace(new PrintWriter(stringWriter),frame,options);
 	
diff --git a/frysk-gui/frysk/gui/srcwin/ChangeLog b/frysk-gui/frysk/gui/srcwin/ChangeLog
index 57fe952..fe5f98f 100644
--- a/frysk-gui/frysk/gui/srcwin/ChangeLog
+++ b/frysk-gui/frysk/gui/srcwin/ChangeLog
@@ -1,3 +1,14 @@
+2008-06-23  Rick Moseley  <rmoseley@redhat.com>
+
+	* SourceBuffer.java: Call getEntryPoint to get address.
+	* SourceWindow.java: Add "load" capability.
+	* SourceWindowFactory.java: Add loadExecutable method.
+
+2008-06-10  Andrew Cagney  <cagney@redhat.com>
+
+	* CurrentStackView.java (STACK_OPTIONS): New.  Pass to
+	Frame.toPrint.
+
 2008-05-15  Tim Moore  <timoore@redhat.com>
 
 	* SourceBuffer.java (disassemblerFrame): Use lib.dwfl.Disassembler.
diff --git a/frysk-gui/frysk/gui/srcwin/CurrentStackView.java b/frysk-gui/frysk/gui/srcwin/CurrentStackView.java
index 45ac270..737a1a3 100644
--- a/frysk-gui/frysk/gui/srcwin/CurrentStackView.java
+++ b/frysk-gui/frysk/gui/srcwin/CurrentStackView.java
@@ -1,6 +1,6 @@
 // This file is part of the program FRYSK.
 //
-// Copyright 2005, 2007, Red Hat Inc.
+// Copyright 2005, 2007, 2008, Red Hat Inc.
 //
 // FRYSK is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by
@@ -37,9 +37,9 @@
 // version and license this file solely under the GPL without
 // exception.
 
-
 package frysk.gui.srcwin;
 
+import frysk.debuginfo.PrintDebugInfoStackOptions;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.util.Iterator;
@@ -80,6 +80,13 @@ public class CurrentStackView
 														new DataColumnString(),
 														new DataColumnObject() };
 
+    private static final PrintDebugInfoStackOptions STACK_OPTIONS;
+    static {
+	STACK_OPTIONS = new PrintDebugInfoStackOptions();
+	STACK_OPTIONS.setPrintParameters(true);
+    }
+
+
   private static DebugInfoFrame currentFrame;
 
   private LinkedList observers;
@@ -119,8 +126,7 @@ public class CurrentStackView
 	this.getSelection().addListener(this);
   }
 
-  public void refreshProc (DebugInfoFrame[] frames, int current)
-  {
+  public void refreshProc (DebugInfoFrame[] frames, int current) {
     TreeIter iter = null;
     TreePath path = ((TreeRowReference) this.stackArray[current]).getPath();
 
@@ -184,7 +190,7 @@ public class CurrentStackView
 
 	    StringWriter stringWriter = new StringWriter();
 	    stringWriter.write("# " + (++level) + " ");
-	    frame.toPrint(new PrintWriter(stringWriter),true,true);
+	    frame.toPrint(new PrintWriter(stringWriter), STACK_OPTIONS);
 	    row = stringWriter.toString();
 	    
 	    if (hasInlinedCode)
@@ -288,7 +294,7 @@ public class CurrentStackView
 
 		StringWriter stringWriter = new StringWriter();
 		stringWriter.write(row = "# " + (++level) + " ");
-		frame.toPrint(new PrintWriter(stringWriter),true,true);
+		frame.toPrint(new PrintWriter(stringWriter), STACK_OPTIONS);
 		row = stringWriter.toString();
 		
 		if (hasInlinedCode)
diff --git a/frysk-gui/frysk/gui/srcwin/SourceBuffer.java b/frysk-gui/frysk/gui/srcwin/SourceBuffer.java
index 0957b49..5950415 100644
--- a/frysk-gui/frysk/gui/srcwin/SourceBuffer.java
+++ b/frysk-gui/frysk/gui/srcwin/SourceBuffer.java
@@ -50,6 +50,8 @@ import java.util.List;
 
 import lib.dwfl.Disassembler;
 import lib.dwfl.Instruction;
+import lib.dwfl.Elf;
+import lib.dwfl.ElfCommand;
 
 import org.gnu.gdk.Color;
 import org.gnu.glib.JGException;
@@ -80,6 +82,7 @@ import frysk.gui.srcwin.prefs.SyntaxPreference.SyntaxPreferenceListener;
 import frysk.proc.Task;
 import frysk.rt.LineXXX;
 import frysk.scopes.SourceLocation;
+import frysk.solib.DynamicSegment;
 import frysk.value.Value;
 
 /**
@@ -850,10 +853,17 @@ public class SourceBuffer extends TextBuffer {
                                              task.getMemory());
 
 	long address = frame.getAddress();
+	// If the address is 0, use the entry point as the address to disassemble
+	if (address == 0) {
+	    Elf elf = new Elf(task.getProc().getExeFile().getFile(), 
+		    ElfCommand.ELF_C_READ);
+	    address = DynamicSegment.getEntryPoint(elf);
+	}
 
 	this.deleteText(this.getStartIter(), this.getEndIter());
 
 	List instructionsList = diss.disassembleInstructions(address, 40);
+
 	Iterator iter = instructionsList.iterator();
 
 	while (iter.hasNext()) {
diff --git a/frysk-gui/frysk/gui/srcwin/SourceWindow.java b/frysk-gui/frysk/gui/srcwin/SourceWindow.java
index dfc8124..06a7a9e 100644
--- a/frysk-gui/frysk/gui/srcwin/SourceWindow.java
+++ b/frysk-gui/frysk/gui/srcwin/SourceWindow.java
@@ -167,6 +167,8 @@ public class SourceWindow extends Window {
     private Action close;
 
     private Action open_core;
+    
+    private Action open_load;
 
     private Action open_executable;
 
@@ -580,7 +582,7 @@ public class SourceWindow extends Window {
     /**
          * Populates the stack browser window
          * 
-         * @param frames An array of DebugInfoFrames used to popuate information
+         * @param frames An array of DebugInfoFrames used to populate information
          * inside the stack frame window.
          */
     public void populateStackBrowser(DebugInfoFrame[][] frames) {
@@ -886,7 +888,8 @@ public class SourceWindow extends Window {
 	Proc[] newSwProc = new Proc[numProcs];
 
 	DOMFactory.clearDOMSourceMap(this.swProc[this.current]);
-	this.steppingEngine.detachProc(this.swProc[this.current], kill);
+	if (this.swProc[this.current].getPid() != 0)
+	    this.steppingEngine.detachProc(this.swProc[this.current], kill);
 
 	int j = 0;
 	for (int i = 0; i < oldSize; i++) {
@@ -916,7 +919,7 @@ public class SourceWindow extends Window {
     /***********************************************************************
          * Getters and Setters
          **********************************************************************/
-
+    
     public Proc getSwProc() {
 	if (this.swProc.length > 0)
 	    return this.swProc[this.current];
@@ -986,7 +989,7 @@ public class SourceWindow extends Window {
 	this.open_core = new Action("open", "Examine core file...",
 		"Examine core file", GtkStockItem.OPEN.getString());
 	this.open_core.setAccelGroup(ag);
-	this.open_core.setAccelPath("<sourceWin>/File/Examine core file...");
+	this.open_core.setAccelPath("<sourceWin>/Processes/Examine core file...");
 	this.open_core.addListener(new org.gnu.gtk.event.ActionListener() {
 	    public void actionEvent(ActionEvent action) {
 		// SourceWindow.this.glade.getWidget(SOURCE_WINDOW).destroy();
@@ -1023,7 +1026,7 @@ public class SourceWindow extends Window {
                         // to
 		    // select a file name
 		    public void fileActivated(FileChooserEvent event) {
-			examineCoreFile(chooser.getFilename());
+			examineCoreFile();
 		    }
 		});
 		setDefaultIcon(IconManager.windowIcon);
@@ -1036,15 +1039,84 @@ public class SourceWindow extends Window {
 		// The OK button was clicked, go open a source window for this
                 // core file
 		else if (response == ResponseType.OK.getValue()) {
-		    examineCoreFile(chooser.getFilename());
+		    examineCoreFile();
 		    chooser.destroy();
 		}
 	    }
 	});
-	AccelMap.changeEntry("<sourceWin>/File/Examine core file...",
+	AccelMap.changeEntry("<sourceWin>/Processes/Examine core file...",
 		KeyValue.o, ModifierType.CONTROL_MASK, true);
 	this.open_core.connectAccelerator();
+	
+	// Load executable action
+	this.open_load = new Action("Load an executable",
+		"Load a process...", "Load a process from a file",
+		GtkStockItem.OPEN.getString());
+	this.open_load.setAccelGroup(ag);
+	this.open_load
+		.setAccelPath("<sourceWin>/Processes/Load a process...");
+	this.open_load.addListener(new ActionListener() {
+	    public void actionEvent(ActionEvent action) {
+		try {
+		    glade_fc = new LibGlade(Prefix.gladeFile(FILECHOOSER_GLADE).getAbsolutePath(), null);
+		    fc = (FileChooserDialog) glade_fc
+			    .getWidget("frysk_filechooserdialog");
+		    fc.addListener(new LifeCycleListener() {
+			public void lifeCycleEvent(LifeCycleEvent event) {
+			}
+
+			public boolean lifeCycleQuery(LifeCycleEvent event) {
+			    if (event.isOfType(LifeCycleEvent.Type.DELETE)
+				    || event
+					    .isOfType(LifeCycleEvent.Type.DESTROY))
+				fc.destroy();
+			    return false;
+			}
+		    });
 
+		    fc.addListener(new FileChooserListener() {
+			public void currentFolderChanged(FileChooserEvent event) {
+			}
+
+			public void selectionChanged(FileChooserEvent event) {
+			}
+
+			public void updatePreview(FileChooserEvent event) {
+			}
+
+			// This method is called when the "Enter" key is pressed
+                        // to
+			// select a file name in the chooser
+			public void fileActivated(FileChooserEvent event) {
+			    loadExecutableFile();
+			}
+		    });
+		    fc.setIcon(IconManager.windowIcon);
+		    fc.setDefaultResponse(FileChooserEvent.Type.FILE_ACTIVATED
+			    .getID());
+		    fc.setCurrentFolder(System.getProperty("user.home"));
+		    CheckButton term_activate = (CheckButton) glade_fc
+			.getWidget("term_activate");
+		    term_activate.setSensitive(false);
+		    gtk_widget_set_size_request(fc.getHandle(), 300, 600);
+		    int response = fc.open();
+		    // "OK" key has been clicked
+		    if (response == ResponseType.OK.getValue())
+			loadExecutableFile();
+		    // "Cancel" key has been clicked
+		    if (response == ResponseType.CANCEL.getValue())
+			fc.destroy();
+		} catch (Exception e) {
+		    throw new RuntimeException(e);
+		}
+	    }
+	});
+	
+	AccelMap.changeEntry("<sourceWin>/Processes/Load executable file...",
+		KeyValue.l, ModifierType.CONTROL_MASK, true);
+	this.open_load.connectAccelerator();
+
+	
 	// Close action
 	this.close = new Action("close", "Close", "Close Window",
 		GtkStockItem.CLOSE.getString());
@@ -1345,9 +1417,11 @@ public class SourceWindow extends Window {
 		    fc.setDefaultResponse(FileChooserEvent.Type.FILE_ACTIVATED
 			    .getID());
 		    fc.setCurrentFolder(System.getProperty("user.home"));
-		    gtk_widget_set_size_request(fc.getHandle(), 300, 300);
+		    CheckButton term_activate = (CheckButton) glade_fc
+			.getWidget("term_activate");
+		    term_activate.setSensitive(false);
+		    gtk_widget_set_size_request(fc.getHandle(), 300, 1000);
 		    int response = fc.open();
-		    gtk_widget_set_size_request(fc.getHandle(), 300, 300);
 		    // "OK" key has been clicked
 		    if (response == ResponseType.OK.getValue())
 			activateProc();
@@ -1570,17 +1644,41 @@ public class SourceWindow extends Window {
     }
 
     /**
-         * This method will activate a window to allow the user to exemaine a
+         * This method will activate a window to allow the user to examine a
          * core file
          * 
          * @param filename -
          *                String containing the path to the core file
          * 
          */
-    private void examineCoreFile(String filename) {
+    private void examineCoreFile() {
+	Entry task_options = (Entry) glade_fc.getWidget("task_options");
+	String task_opt = task_options.getText();
+	String filename = fc.getFilename();
+	fc.destroy();
+	String[] stds = { "/dev/null", "/dev/null", "/dev/null" };
+	addProc(filename, "", task_opt, stds[0], stds[1], stds[2]);
 	SourceWindowFactory.attachToCore(new File(filename));
-	this.destroy();
     }
+    
+    /**
+     * This method will activate a window to allow the user to load an
+     * executable file
+     * 
+     * @param filename -
+     *                String containing the path to the executable file
+     * 
+     */
+    private void loadExecutableFile() {
+	Entry task_options = (Entry) glade_fc.getWidget("task_options");
+	String task_opt = task_options.getText();
+	String filename = fc.getFilename();
+	fc.destroy();
+	String[] stds = { "/dev/null", "/dev/null", "/dev/null" };
+	addProc(filename, "", task_opt, stds[0], stds[1], stds[2]);
+	SourceWindowFactory.loadExecutable(new File(filename), null);
+	//this.destroy();
+}
 
     /**
          * Creates the toolbar menus with initialized Actions.
@@ -1589,11 +1687,14 @@ public class SourceWindow extends Window {
 	// File menu
 	MenuItem menu = new MenuItem("File", true);
 
-	// MenuItem mi = (MenuItem) this.open_core.createMenuItem();
+	/* MenuItem mi = (MenuItem) this.open_core.createMenuItem();
+	Menu tmp = new Menu();
+	tmp.append(mi);
+	mi = (MenuItem) this.open_load.createMenuItem();
+	tmp.append(mi);
+	mi = new MenuItem(); // Separator
+	tmp.append(mi); */
 	Menu tmp = new Menu();
-	// tmp.append(mi);
-	// mi = new MenuItem(); // Separator
-	// tmp.append(mi);
 	MenuItem mi = (MenuItem) this.close.createMenuItem();
 	tmp.append(mi);
 
@@ -1686,14 +1787,16 @@ public class SourceWindow extends Window {
 
 	menu = new MenuItem("Processes", false);
 	tmp = new Menu();
-	mi = (MenuItem) this.open_executable.createMenuItem();
+	mi = (MenuItem) this.attach_proc.createMenuItem();
 	tmp.append(mi);
 	mi = new MenuItem(); // Separator
 	tmp.append(mi);
-	mi = (MenuItem) this.attach_proc.createMenuItem();
+	mi = (MenuItem) this.open_executable.createMenuItem();
 	tmp.append(mi);
 	mi = (MenuItem) this.open_core.createMenuItem();
 	tmp.append(mi);
+	mi = (MenuItem) this.open_load.createMenuItem();
+	tmp.append(mi);
 
 	menu.setSubmenu(tmp);
 	((MenuBar) this.glade.getWidget("menubar")).append(menu);
diff --git a/frysk-gui/frysk/gui/srcwin/SourceWindowFactory.java b/frysk-gui/frysk/gui/srcwin/SourceWindowFactory.java
index e662bb7..652ee6c 100644
--- a/frysk-gui/frysk/gui/srcwin/SourceWindowFactory.java
+++ b/frysk-gui/frysk/gui/srcwin/SourceWindowFactory.java
@@ -51,6 +51,7 @@ import org.gnu.gtk.event.LifeCycleListener;
 import org.jdom.output.Format;
 import org.jdom.output.XMLOutputter;
 import frysk.proc.dead.LinuxCoreFactory;
+import frysk.proc.dead.LinuxExeFactory;
 import frysk.config.Prefix;
 import frysk.proc.TaskAttachedObserverXXX;
 import frysk.debuginfo.DebugInfoFrame;
@@ -140,16 +141,28 @@ public class SourceWindowFactory
     public static void attachToCore(File coreFile) {
 	Proc proc = LinuxCoreFactory.createProc(coreFile);
 
-    LinkedList tasks = proc.getTasks();
-    DebugInfoFrame[] framez = new DebugInfoFrame[tasks.size()];
-    Iterator iter = tasks.iterator();
-    for (int i = 0; iter.hasNext(); i++)
-      {
-        Task task = (Task) iter.next();
-        framez[i] = DebugInfoStackFactory.createDebugInfoStackTrace(task);
-      }
-    createSourceWindow(framez);
-  }
+	LinkedList tasks = proc.getTasks();
+	DebugInfoFrame[] framez = new DebugInfoFrame[tasks.size()];
+	Iterator iter = tasks.iterator();
+	for (int i = 0; iter.hasNext(); i++) {
+	    Task task = (Task) iter.next();
+	    framez[i] = DebugInfoStackFactory.createDebugInfoStackTrace(task);
+	}
+	createSourceWindow(framez);
+    }
+    
+    public static void loadExecutable(File exeFile, String[] args) {
+	Proc proc = LinuxExeFactory.createProc(exeFile, args);
+
+	LinkedList tasks = proc.getTasks();
+	DebugInfoFrame[] framez = new DebugInfoFrame[tasks.size()];
+	Iterator iter = tasks.iterator();
+	for (int i = 0; iter.hasNext(); i++) {
+	    Task task = (Task) iter.next();
+	    framez[i] = DebugInfoStackFactory.createDebugInfoStackTrace(task);
+	}
+	createSourceWindow(framez);
+    }
   
   public static AttachedObserver startNewProc(String file, String env_variables, String options,
                                                String stdin, String stdout, String stderr)
diff --git a/frysk-imports/elfutils/libdwfl/ChangeLog b/frysk-imports/elfutils/libdwfl/ChangeLog
index ac95d68..e1d00f1 100644
--- a/frysk-imports/elfutils/libdwfl/ChangeLog
+++ b/frysk-imports/elfutils/libdwfl/ChangeLog
@@ -1,3 +1,8 @@
+2008-06-19  Andrew Cagney  <cagney@redhat.com>
+
+	* dwfl_module_addrsym.c (dwfl_module_addrsym): Correctly update
+	min_label.
+
 2008-06-07  Andrew Cagney  <cagney@redhat.com>
 
 	* dwfl_module_getdwarf.c (open_elf): Don't align the module's load
diff --git a/frysk-imports/elfutils/libdwfl/dwfl_module_addrsym.c b/frysk-imports/elfutils/libdwfl/dwfl_module_addrsym.c
index c34a31b..77033a6 100644
--- a/frysk-imports/elfutils/libdwfl/dwfl_module_addrsym.c
+++ b/frysk-imports/elfutils/libdwfl/dwfl_module_addrsym.c
@@ -49,10 +49,13 @@
 
 #include "libdwflP.h"
 
+#include <stdio.h>
+
 const char *
 dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
 		     GElf_Sym *closest_sym, GElf_Word *shndxp)
 {
+  // fprintf(stderr, "looking up %lx\n", (long) addr);
   int syments = INTUSE(dwfl_module_getsymtab) (mod);
   if (syments < 0)
     return NULL;
@@ -116,15 +119,20 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
       GElf_Sym sym;
       GElf_Word shndx;
       const char *name = INTUSE(dwfl_module_getsym) (mod, i, &sym, &shndx);
+      // fprintf(stderr, "symbol %s at 0x%lx 0x%ld\n", name, (long) sym.st_value, (long) sym.st_size);
+      /* Even if we don't choose this symbol, its existence excludes
+	 any sizeless symbol (assembly label) that is below its upper
+	 bound.  */
+      if (name != NULL && sym.st_value <= addr
+	  && sym.st_value + sym.st_size > min_label) {
+	min_label = sym.st_value + sym.st_size;
+	// fprintf(stderr, "  min to %s size ends at %lx\n", name, (long) min_label);
+      }
       if (name != NULL
 	  && sym.st_value <= addr
 	  && (sym.st_size == 0 || addr - sym.st_value < sym.st_size))
 	{
-	  /* Even if we don't choose this symbol, its existence
-	     excludes any sizeless symbol (assembly label) that
-	     is inside its bounds.  */
-	  if (sym.st_value + sym.st_size > addr)
-	    min_label = sym.st_value + sym.st_size;
+	  // fprintf(stderr, "  candidate %s at 0x%lx 0x%ld\n", name, (long) sym.st_value, (long) sym.st_size);
 
 	  /* This symbol is a better candidate than the current one
 	     if it's a named symbol, not a section or file symbol,
@@ -140,6 +148,7 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
 		{
 		  if (sym.st_size != 0)
 		    {
+		      // fprintf(stderr, "  closest %s at %lx\n", name, (long)sym.st_value);
 		      *closest_sym = sym;
 		      closest_shndx = shndx;
 		      closest_name = name;
@@ -155,6 +164,7 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
                           || (sizeless_sym.st_value == sym.st_value
                               && strcmp(name, sizeless_name) < 0))
                         {
+			  // fprintf(stderr, "  sizeless %s at %lx\n", name, (long)sym.st_value);
                           sizeless_sym = sym;
                           sizeless_shndx = shndx;
                           sizeless_name = name;
@@ -171,6 +181,7 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
                            || (closest_sym->st_size == sym.st_size
                                && strcmp(name, closest_name) < 0)))
 		{
+		  // fprintf(stderr, "  alt closest %s at %lx\n", name, (long)sym.st_value);
 		  *closest_sym = sym;
 		  closest_shndx = shndx;
 		  closest_name = name;
diff --git a/frysk-sys/ChangeLog b/frysk-sys/ChangeLog
index 52b6d1c..c482e0e 100644
--- a/frysk-sys/ChangeLog
+++ b/frysk-sys/ChangeLog
@@ -1,3 +1,9 @@
+2008-06-19  Andrew Cagney  <cagney@redhat.com>
+
+	* Makefile.am (JNI_LIBRARY_LIST): Define.
+	(JNI_ARCHIVE_LIST): Define.
+	(JNI_OBJECT_LIST): Define.
+
 2008-05-27  Andrew Cagney  <cagney@redhat.com>
 
 	* Makefile.am (JniRunner.java): Delete.
diff --git a/frysk-sys/Makefile.am b/frysk-sys/Makefile.am
index 24032eb..79ef060 100644
--- a/frysk-sys/Makefile.am
+++ b/frysk-sys/Makefile.am
@@ -71,6 +71,21 @@ lib/unwind/cni/Unwind%.cxx: lib/unwind/Unwind%.java lib/unwind/cni/UnwindH.hxx
 lib/unwind/Unwind%.java: lib/unwind/Unwind.java
 
 
+# Depend on these runtimes.
+JNI_LIBRARY_LIST += -lstdc++
+JNI_LIBRARY_LIST += -laudit
+# Bundle in the local elfutils code.
+JNI_ARCHIVE_LIST += ../frysk-imports/elfutils/libasm/libasm_pic.a
+JNI_ARCHIVE_LIST += ../frysk-imports/elfutils/libdwfl/libdwfl_pic.a
+JNI_ARCHIVE_LIST += ../frysk-imports/elfutils/libdw/libdw_pic.a
+JNI_ARCHIVE_LIST += ../frysk-imports/elfutils/libelf/libelf_pic.a
+JNI_ARCHIVE_LIST += ../frysk-imports/elfutils/libebl/libebl.a
+# Bundle in the local libunwind code.
+JNI_OBJECT_LIST += ../frysk-imports/libunwind-i386/src/{,dwarf/,mi/,x86/}.libs/*.o
+JNI_OBJECT_LIST += ../frysk-imports/libunwind-x86_64/src/{,dwarf/,mi/,x86_64/}.libs/*.o
+JNI_OBJECT_LIST += ../frysk-imports/libunwind-ppc32/src/{,dwarf/,mi/,ppc32/}.libs/*.o
+JNI_OBJECT_LIST += ../frysk-imports/libunwind-ppc64/src/{,dwarf/,mi/,ppc64/}.libs/*.o
+
 # jnixx's auto-detect algorithm misses hidden class references,
 # explicitly add them here.
 JNIXX_CLASSES += frysk.sys.ProcessIdentifierFactory
diff --git a/frysk-sys/frysk/ChangeLog b/frysk-sys/frysk/ChangeLog
index e0baf3a..36193fc 100644
--- a/frysk-sys/frysk/ChangeLog
+++ b/frysk-sys/frysk/ChangeLog
@@ -1,3 +1,7 @@
+2008-06-12  Andrew Cagney  <cagney@redhat.com>
+
+	* ExternalException.java: New.
+
 2008-03-03  Andrew Cagney  <cagney@redhat.com>
 
 	* TestConfig.java: Move to frysk.config.
diff --git a/frysk-sys/frysk/InternalException.java b/frysk-sys/frysk/InternalException.java
new file mode 100644
index 0000000..fe85caa
--- /dev/null
+++ b/frysk-sys/frysk/InternalException.java
@@ -0,0 +1,71 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2008 Red Hat Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+package frysk;
+
+/**
+ * An internal problem has occured; for instance, we got an event we
+ * have no idea what to do with.  This is different to a user or
+ * external exception in that the problem is occuring due to issues
+ * with the frysk code.  When displaying InternalExceptions they
+ * should include a backtrace.
+ *
+ * Main-loop code catching this class of problem should print a full
+ * stack back trace.  One way of doing this is:
+ *
+ * try {
+ *   ..
+ * } catch (UserException e) {
+ *   System.out.println(e.getMessage());
+ *   System.exit(1);
+ * } catch (RuntimeException e) {
+ *   e.printStackTrace(System.out);
+ *   System.exit(1);
+ * }
+ *
+ * The alternative is an internal, or runtime exception, where frysk's
+ * code base is internally getting things seriously wrong.
+ */
+
+public class InternalException extends RuntimeException {
+    static final long serialVersionUID = 0;
+    public InternalException(String what) {
+	super(what);
+    }
+}
diff --git a/frysk-sys/frysk/UserException.java b/frysk-sys/frysk/UserException.java
new file mode 100644
index 0000000..76ba9f7
--- /dev/null
+++ b/frysk-sys/frysk/UserException.java
@@ -0,0 +1,73 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2008 Red Hat Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+package frysk;
+
+/**
+ * An exception triggered by information tied to the user, for
+ * instance a missing or corrupt input file.  This can be considered,
+ * while still exceptional, a largely run-of-the-mill occurance and
+ * such exceptions should be displayed to the user as errors.
+ *
+ * Main-loop code catching this class of problem should just print the
+ * error message.  One way of doing this is:
+ *
+ * try {
+ *   ..
+ * } catch (UserException e) {
+ *   System.out.println(e.getMessage());
+ *   System.exit(1);
+ * } catch (RuntimeException e) {
+ *   e.printStackTrace(System.out);
+ *   System.exit(1);
+ * }
+ *
+ * The alternative is an internal, or runtime exception, where frysk's
+ * code base is internally getting things seriously wrong.
+ */
+
+public class UserException extends RuntimeException {
+    static final long serialVersionUID = 0;
+    public UserException(String message) {
+	super(message);
+    }
+    public UserException(String message, Throwable t) {
+	super(message, t);
+    }
+}
diff --git a/frysk-sys/frysk/expunit/ChangeLog b/frysk-sys/frysk/expunit/ChangeLog
index 3434555..b81903d 100644
--- a/frysk-sys/frysk/expunit/ChangeLog
+++ b/frysk-sys/frysk/expunit/ChangeLog
@@ -1,3 +1,8 @@
+2008-06-12  Andrew Cagney  <cagney@redhat.com>
+
+	* TestExpect (testShell()): New.
+	* Expect.java (Expect()): New.
+
 2008-03-11  Andrew Cagney  <cagney@redhat.com>
 
 	* Child.java: Use LogFinest.
diff --git a/frysk-sys/frysk/expunit/Expect.java b/frysk-sys/frysk/expunit/Expect.java
index 1d07b91..d2542f6 100644
--- a/frysk-sys/frysk/expunit/Expect.java
+++ b/frysk-sys/frysk/expunit/Expect.java
@@ -91,6 +91,17 @@ public class Expect {
     }
 
     /**
+     * Create a bash shell sitting at a prompt.
+     */
+    public Expect() {
+	this(new String[] {
+		"/bin/bash", "-c",
+		"export PS1=$\\ ; export PS2=>\\ ; exec /bin/bash --norc --noprofile"
+	    });
+	expect("\\$ ");
+    }
+
+    /**
      * Clean up.
      *
      * XXX: This drains all outstanding WAITPID events, and SIGCHLD
diff --git a/frysk-sys/frysk/expunit/TestExpect.java b/frysk-sys/frysk/expunit/TestExpect.java
index 32bd302..b7b2f83 100644
--- a/frysk-sys/frysk/expunit/TestExpect.java
+++ b/frysk-sys/frysk/expunit/TestExpect.java
@@ -151,4 +151,13 @@ public class TestExpect
 	    });
 	assertEquals ("brk mode", "-brkint", g.toString ());
     }
+
+    public void testShell() {
+	Expect e = new Expect();
+	// send a command, check that all, especially the prompt, are
+	// correct.
+	e.send("echo hi\r");
+	e.expect("echo hi\r\nhi\r\n\\$ ");
+    }
+
 }
diff --git a/frysk-sys/frysk/rsl/ChangeLog b/frysk-sys/frysk/rsl/ChangeLog
index f611e11..87484e4 100644
--- a/frysk-sys/frysk/rsl/ChangeLog
+++ b/frysk-sys/frysk/rsl/ChangeLog
@@ -1,3 +1,12 @@
+2008-06-20  Andrew Cagney  <cagney@redhat.com>
+
+	* Printer.java: Include the inner most stack frame when printing
+	exceptions.
+
+2008-06-19  Andrew Cagney  <cagney@redhat.com>
+
+	* Log.java: Add more methods.
+
 2008-06-04  Andrew Cagney  <cagney@redhat.com>
 
 	* Log.java (finest(Class)): New.
diff --git a/frysk-sys/frysk/rsl/Log.java b/frysk-sys/frysk/rsl/Log.java
index 1557332..27f1245 100644
--- a/frysk-sys/frysk/rsl/Log.java
+++ b/frysk-sys/frysk/rsl/Log.java
@@ -421,6 +421,13 @@ public final class Log {
 	prefix(self).print(p1).print(p2).print(p3).print(p4).print(p5).print(p6).print(p7).print(p8).print(p9).print(p10).print(p11).suffix();
     }
 
+    // dynamic 12 parameters
+    public void log(Object self, String p1, Object p2, String p3, long p4, String p5, long p6, String p7, int p8, String p9, int p10, String p11, int p12) {
+	if (!logging)
+	    return;
+	prefix(self).print(p1).print(p2).print(p3).print(p4).print(p5).print(p6).print(p7).print(p8).print(p9).print(p10).print(p11).print(p12).suffix();
+    }
+
 
     /**
      * Assuming the use: <tt>log("caller", log.CALLER)</tt> prints the
diff --git a/frysk-sys/frysk/rsl/Printer.java b/frysk-sys/frysk/rsl/Printer.java
index a8e926d..5ebec05 100644
--- a/frysk-sys/frysk/rsl/Printer.java
+++ b/frysk-sys/frysk/rsl/Printer.java
@@ -158,11 +158,23 @@ public final class Printer {
      */
     private void dump(Throwable t) {
 	out.print("<<exception ");
-	out.print(t.toString());
-	for (Throwable cause = t.getCause(); cause != null;
-	     cause = cause.getCause()) {
+	while (true) {
+	    out.print(t.toString());
+	    StackTraceElement[] stack = t.getStackTrace();
+	    for (int i = 0; i < stack.length; i++) {
+		if (i >= 1) {
+		    // XXX: the cap is some what arbitrary
+		    out.print(" ...");
+		    break;
+		} else {
+		    out.print(" <at> ");
+		    out.print(stack[i].toString());
+		}
+	    }
+	    t = t.getCause();
+	    if (t == null)
+		break;
 	    out.print(" <caused-by> ");
-	    out.print(cause.toString());
 	}
 	out.print(">>");
     }
diff --git a/frysk-sys/frysk/sys/ChangeLog b/frysk-sys/frysk/sys/ChangeLog
index 28e04a9..a96417f 100644
--- a/frysk-sys/frysk/sys/ChangeLog
+++ b/frysk-sys/frysk/sys/ChangeLog
@@ -1,3 +1,26 @@
+2008-07-07  Andrew Cagney  <cagney@redhat.com>
+
+	* cni/Fork.hxx: Remove utrace stubs.
+	* Fork.java: Ditto.
+	* jni/Fork.hxx: Ditto.
+	* jni/Fork.cxx: Ditto.
+	* cni/Fork.cxx: Ditto.
+
+2008-06-20  Andrew Cagney  <cagney@redhat.com>
+
+	* Poll.java: Move to frysk.sys.poll.
+	* PollBuilder.java: Ditto.
+	* jni/Poll.cxx: Ditto.
+	* cni/Poll.cxx: Ditto.
+
+2008-06-12  Andrew Cagney  <cagney@redhat.com>
+
+	* cni/Errno.cxx (throwUserException): New.
+	* cni/Errno.hxx (throwUserException): New.
+
+	* Errno.java-sh: Extend ExternalException.
+	* cni/Errno.cxx: Update.
+
 2008-06-02  Andrew Cagney  <cagney@redhat.com>
 
 	* TestLeakingFileDescriptor.java: Mark as unsupported under JNI.
diff --git a/frysk-sys/frysk/sys/Errno.java-sh b/frysk-sys/frysk/sys/Errno.java-sh
index fdbf585..c87ae21 100644
--- a/frysk-sys/frysk/sys/Errno.java-sh
+++ b/frysk-sys/frysk/sys/Errno.java-sh
@@ -44,12 +44,14 @@ cat <<EOF
 
 package frysk.sys;
 
+import frysk.UserException;
+
 /**
  * Unix Host Errors.
  *
  * Do not confuse this with target errors and target error numbers.
  */
-public class Errno extends RuntimeException {
+public class Errno extends UserException {
     static final long serialVersionUID = 0;
 
     private final String message;
diff --git a/frysk-sys/frysk/sys/Fork.java b/frysk-sys/frysk/sys/Fork.java
index 7e2f39c..46c98cb 100644
--- a/frysk-sys/frysk/sys/Fork.java
+++ b/frysk-sys/frysk/sys/Fork.java
@@ -53,9 +53,6 @@ public final class Fork {
     private static native int ptrace(String exe,
 				     String in, String out, String err,
 				     String[] args, String[] environ);
-    private static native int utrace(String exe,
-				     String in, String out, String err,
-				     String[] args, String[] environ);
     private static native int daemon(String exe,
 				     String in, String out, String err,
 				     String[] args, String[] environ);
@@ -118,29 +115,6 @@ public final class Fork {
     }
 
     /**
-     * Create a child process running EXE with arguments ARGS[0...];
-     * mark the process for utracing.
-     *
-     * Also wire up IN, OUT, and ERR.
-     */
-    public static ProcessIdentifier utrace(File exe,
-					   String in, String out,
-					   String err, String[] args) {
-	return ProcessIdentifierFactory.create(utrace(exe.getPath(),
-						      in, out, err,
-						      args, null));
-    }
-    /**
-     * Create a child process running ARGS[0] with arguments
-     * ARGV[0...]; mark the process for utracing.
-     */
-    public static ProcessIdentifier utrace(String[] args) {
-	return ProcessIdentifierFactory.create(utrace(args[0],
-						      null, null, null,
-						      args, null));
-    }
-
-    /**
      * Create a "daemon" process running ARGV[0] with arguments
      * ARGV[1...]; a daemon has process ID 1 as its parent.
      */
diff --git a/frysk-sys/frysk/sys/Poll.java b/frysk-sys/frysk/sys/Poll.java
deleted file mode 100644
index 8496fd8..0000000
--- a/frysk-sys/frysk/sys/Poll.java
+++ /dev/null
@@ -1,104 +0,0 @@
-// This file is part of the program FRYSK.
-//
-// Copyright 2005, 2007, 2008, Red Hat Inc.
-//
-// FRYSK is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// FRYSK is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with FRYSK; if not, write to the Free Software Foundation,
-// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-// 
-// In addition, as a special exception, Red Hat, Inc. gives You the
-// additional right to link the code of FRYSK with code not covered
-// under the GNU General Public License ("Non-GPL Code") and to
-// distribute linked combinations including the two, subject to the
-// limitations in this paragraph. Non-GPL Code permitted under this
-// exception must only link to the code of FRYSK through those well
-// defined interfaces identified in the file named EXCEPTION found in
-// the source code files (the "Approved Interfaces"). The files of
-// Non-GPL Code may instantiate templates or use macros or inline
-// functions from the Approved Interfaces without causing the
-// resulting work to be covered by the GNU General Public
-// License. Only Red Hat, Inc. may make changes or additions to the
-// list of Approved Interfaces. You must obey the GNU General Public
-// License in all respects for all of the FRYSK code and other code
-// used in conjunction with FRYSK except the Non-GPL Code covered by
-// this exception. If you modify this file, you may extend this
-// exception to your version of the file, but you are not obligated to
-// do so. If you do not wish to provide this exception without
-// modification, you must delete this exception statement from your
-// version and license this file solely under the GPL without
-// exception.
-
-package frysk.sys;
-
-/**
- * Poll like interface for waiting on kernel events.
- *
- * This object, loosely based on the poll and pselect interfaces,
- * provides a call blocks until a UNIX event (signal, FD ready), the
- * timeout expires, or an unexpected interrupt occures.  The client
- * (which extends this object) is notified via the abstract notify
- * methods.
- */
-
-public final class Poll
-{
-    /**
-     * Set of signals checked during poll.
-     */
-    static protected SignalSet signalSet = new SignalSet ();
-    private static native void addSignalHandler (Signal sig);
-    /**
-     * Add Sig to the set of signals checked during poll.
-     */
-    public static void add (Signal sig) {
-	signalSet.add(sig);
-	addSignalHandler(sig);
-    }
-    /**
-     * Empty the set of signals, and file descriptors, checked during
-     * poll.
-     */
-    public static void empty ()
-    {
-	// Note that this doesn't restore any signal handlers.
-	signalSet.empty ();
-    }
-
-    /**
-     * Manage the file descriptors watched by the poll call.
-     */
-    public static final class Fds {
-	long fds;
-	public Fds() {
-	    fds = malloc();
-	}
-	protected void finalize() {
-	    free(fds);
-	}
-	private static native long malloc();
-	private static native void free(long fds);
-	public void addPollIn(int fd) {
-	    fds = addPollIn(fds, fd);
-	}
-	private static native long addPollIn(long fds, int fd);
-    }
-    static protected Fds pollFds = new Fds ();
-
-    /**
-     * Poll the system for either FD, or signal events.  Block for
-     * timeout milliseconds (if timeout is +ve or zero), or until the
-     * next event (if timeout is -ve).  Return when an event might
-     * have occured.
-     */
-    public static native void poll (PollBuilder observer,
-				    long timeout);
-}
diff --git a/frysk-sys/frysk/sys/PollBuilder.java b/frysk-sys/frysk/sys/PollBuilder.java
deleted file mode 100644
index 8c13aab..0000000
--- a/frysk-sys/frysk/sys/PollBuilder.java
+++ /dev/null
@@ -1,48 +0,0 @@
-// This file is part of the program FRYSK.
-//
-// Copyright 2005, 2007, Red Hat Inc.
-//
-// FRYSK is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// FRYSK is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with FRYSK; if not, write to the Free Software Foundation,
-// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-// 
-// In addition, as a special exception, Red Hat, Inc. gives You the
-// additional right to link the code of FRYSK with code not covered
-// under the GNU General Public License ("Non-GPL Code") and to
-// distribute linked combinations including the two, subject to the
-// limitations in this paragraph. Non-GPL Code permitted under this
-// exception must only link to the code of FRYSK through those well
-// defined interfaces identified in the file named EXCEPTION found in
-// the source code files (the "Approved Interfaces"). The files of
-// Non-GPL Code may instantiate templates or use macros or inline
-// functions from the Approved Interfaces without causing the
-// resulting work to be covered by the GNU General Public
-// License. Only Red Hat, Inc. may make changes or additions to the
-// list of Approved Interfaces. You must obey the GNU General Public
-// License in all respects for all of the FRYSK code and other code
-// used in conjunction with FRYSK except the Non-GPL Code covered by
-// this exception. If you modify this file, you may extend this
-// exception to your version of the file, but you are not obligated to
-// do so. If you do not wish to provide this exception without
-// modification, you must delete this exception statement from your
-// version and license this file solely under the GPL without
-// exception.
-
-package frysk.sys;
-
-/**
- * Notify client of Poll events.
- */
-public interface PollBuilder {
-    void signal(Signal sig);
-    void pollIn (int fd);
-}
diff --git a/frysk-sys/frysk/sys/cni/Errno.cxx b/frysk-sys/frysk/sys/cni/Errno.cxx
index d2878c1..4ccac23 100644
--- a/frysk-sys/frysk/sys/cni/Errno.cxx
+++ b/frysk-sys/frysk/sys/cni/Errno.cxx
@@ -52,6 +52,7 @@
 #include <java/lang/Thread.h>
 #include <java/lang/ArrayIndexOutOfBoundsException.h>
 
+#include "frysk/UserException.h"
 #include "frysk/sys/Errno.h"
 #include "frysk/sys/Errno$Ebadf.h"
 #include "frysk/sys/Errno$Enomem.h"
@@ -162,6 +163,14 @@ throwErrno (int err, const char *prefix)
   throwErrno (err, ajprintf ("%s: %s", prefix, strerror (err)));
 }
 
+void throwUserException(const char *format, ...) {
+  va_list ap;
+  va_start(ap, format);
+  jstring message = vajprintf(format, ap);
+  va_end(ap);
+  throw new frysk::UserException(message);
+}
+
 void
 throwRuntimeException (const char *message)
 {
diff --git a/frysk-sys/frysk/sys/cni/Errno.hxx b/frysk-sys/frysk/sys/cni/Errno.hxx
index 6bcde43..5838b0f 100644
--- a/frysk-sys/frysk/sys/cni/Errno.hxx
+++ b/frysk-sys/frysk/sys/cni/Errno.hxx
@@ -47,6 +47,10 @@ extern void throwErrno (int err, const char *prefix)
 extern void throwErrno (int err, const char *prefix, const char *suffix, ...)
   __attribute__ ((noreturn)) __attribute__((format (printf, 3, 4)));
 
+// <<prefix>>: <<strerror(err)>> (<<suffix>> ...)
+extern void throwUserException(const char *format, ...)
+  __attribute__ ((noreturn)) __attribute__((format (printf, 1, 2)));
+
 // <<message>>
 extern void throwRuntimeException (const char *message)
   __attribute__ ((noreturn));
diff --git a/frysk-sys/frysk/sys/cni/Fork.cxx b/frysk-sys/frysk/sys/cni/Fork.cxx
index 9d35ffd..ef6e3a8 100644
--- a/frysk-sys/frysk/sys/cni/Fork.cxx
+++ b/frysk-sys/frysk/sys/cni/Fork.cxx
@@ -115,9 +115,6 @@ spawn(tracing trace, redirect& redirection, exec& execute) {
 	::_exit(errno);
       }
       break;
-    case UTRACE:
-      fprintf(stderr, "\n\n>>>>> in spawn(...utrace)\n\n");
-      break;
     case CHILD:
       break;
     case DAEMON:
@@ -188,13 +185,6 @@ frysk::sys::Fork::ptrace(jstring exe,
 }
 
 jint
-frysk::sys::Fork::utrace(jstring exe,
-			jstring in, jstring out, jstring err,
-			jstringArray args, jstringArray environ) {
-  return ::spawn(exe, in, out, err, args, environ, UTRACE);
-}
-
-jint
 frysk::sys::Fork::daemon (jstring exe, jstring in, jstring out, jstring err,
 			  jstringArray args, jstringArray environ) {
   return ::spawn(exe, in, out, err, args, environ, DAEMON);
diff --git a/frysk-sys/frysk/sys/cni/Fork.hxx b/frysk-sys/frysk/sys/cni/Fork.hxx
index a4b8438..2cc021b 100644
--- a/frysk-sys/frysk/sys/cni/Fork.hxx
+++ b/frysk-sys/frysk/sys/cni/Fork.hxx
@@ -41,7 +41,6 @@ enum tracing {
   CHILD,
   DAEMON,
   PTRACE,
-  UTRACE,
 };
 
 /**
diff --git a/frysk-sys/frysk/sys/cni/Poll.cxx b/frysk-sys/frysk/sys/cni/Poll.cxx
deleted file mode 100644
index 1cffb92..0000000
--- a/frysk-sys/frysk/sys/cni/Poll.cxx
+++ /dev/null
@@ -1,245 +0,0 @@
-// This file is part of the program FRYSK.
-//
-// Copyright 2005, 2006, 2007, 2008, Red Hat Inc.
-//
-// FRYSK is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// FRYSK is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with FRYSK; if not, write to the Free Software Foundation,
-// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-// 
-// In addition, as a special exception, Red Hat, Inc. gives You the
-// additional right to link the code of FRYSK with code not covered
-// under the GNU General Public License ("Non-GPL Code") and to
-// distribute linked combinations including the two, subject to the
-// limitations in this paragraph. Non-GPL Code permitted under this
-// exception must only link to the code of FRYSK through those well
-// defined interfaces identified in the file named EXCEPTION found in
-// the source code files (the "Approved Interfaces"). The files of
-// Non-GPL Code may instantiate templates or use macros or inline
-// functions from the Approved Interfaces without causing the
-// resulting work to be covered by the GNU General Public
-// License. Only Red Hat, Inc. may make changes or additions to the
-// list of Approved Interfaces. You must obey the GNU General Public
-// License in all respects for all of the FRYSK code and other code
-// used in conjunction with FRYSK except the Non-GPL Code covered by
-// this exception. If you modify this file, you may extend this
-// exception to your version of the file, but you are not obligated to
-// do so. If you do not wish to provide this exception without
-// modification, you must delete this exception statement from your
-// version and license this file solely under the GPL without
-// exception.
-
-#include <sys/poll.h>
-#include <setjmp.h>
-#include <signal.h>
-#include <alloca.h>
-#include <errno.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <linux/unistd.h>
-#include <linux.syscall.h>
-
-_syscall2(int, tkill, pid_t, tid, int, sig);
-
-#include <gcj/cni.h>
-#include <gnu/gcj/RawDataManaged.h>
-
-#include "frysk/sys/cni/Errno.hxx"
-#include "frysk/sys/ProcessIdentifier.h"
-#include "frysk/sys/Tid.h"
-#include "frysk/sys/Poll.h"
-#include "frysk/sys/Signal.h"
-#include "frysk/sys/SignalSet.h"
-#include "frysk/sys/cni/SignalSet.hxx"
-#include "frysk/sys/Poll$Fds.h"
-#include "frysk/sys/PollBuilder.h"
-
-
-// If there's a signal abort the wait() function using a longjmp (and
-// return the signal).  Should the jmpbuf be per-thread?
-
-struct poll_jmpbuf {
-  pid_t tid;
-  sigjmp_buf buf;
-};
-struct poll_jmpbuf poll_jmpbuf;
-
-static void
-handler (int signum, siginfo_t *siginfo, void *context)
-{
-  // For what ever reason, the signal can come in on the wrong thread.
-  // When that occures, re-direct it (explicitly) to the thread that
-  // can handle the signal.
-  pid_t me = frysk::sys::Tid::tid();
-  if (poll_jmpbuf.tid == me) {
-#if 0
-    fprintf (stderr, "pid %d got signal %d (%s) from %d\n",
-	     me, siginfo->si_signo, strsignal (siginfo->si_signo),
-	     siginfo->si_pid);
-#endif
-    siglongjmp (poll_jmpbuf.buf, signum);
-  }
-  else
-    // XXX: Want to edit this thread's mask so that from now on it
-    // blocks this signal, don't know a way to do it though.
-    tkill (poll_jmpbuf.tid, signum);
-}
-
-void
-frysk::sys::Poll::addSignalHandler (frysk::sys::Signal* sig)
-{
-  int signum = sig->hashCode ();
-  // Make certain that the signal is masked (this is ment to be
-  // process wide).
-  sigset_t mask;
-  sigemptyset (&mask);
-  sigaddset (&mask, signum);
-  // XXX: In a multi-threaded environment this call is not well
-  // defined (although it does help reduce the number of signals
-  // directed to the wrong thread).
-  sigprocmask (SIG_BLOCK, &mask, NULL);
-  // Install the above signal handler (it long jumps back to the code
-  // that enabled the signal).  To avoid potential recursion, all
-  // signals are masked while the handler is running.
-  struct sigaction sa;
-  memset (&sa, 0, sizeof (sa));
-  sa.sa_sigaction = handler;
-  sa.sa_flags = SA_SIGINFO;
-  sigfillset (&sa.sa_mask);
-  sigaction (signum, &sa, NULL);
-}
-
-
-
-jlong
-frysk::sys::Poll$Fds::malloc() {
-  // Allocate a non-empty buffer, marked with a sentinel.
-  struct pollfd* fds = (struct pollfd*) JvMalloc(sizeof (struct pollfd));
-  fds->fd = -1; // sentinel
-  return (jlong)(long) fds;
-}
-
-void
-frysk::sys::Poll$Fds::free(jlong fds) {
-  JvFree((struct pollfd*)(long)fds);
-}
-
-static jlong
-addPollFd(jlong pollFds, int fd, short event) {
-  struct pollfd* ufds = (struct pollfd*) pollFds;
-  // If the FD is alreay listed, just add the event; end up with a
-  // count of fds.
-  int numFds;
-  for (numFds = 0; ufds[numFds].fd >= 0; numFds++) {
-    if (ufds[numFds].fd == fd) {
-      ufds[numFds].events |= event;
-      return pollFds;
-    }
-  }
-  // Create space for the new fd (and retain space for the sentinel).
-  ufds = (struct pollfd*) JvRealloc(ufds, (numFds + 2) * sizeof (struct pollfd));
-  ufds[numFds + 0].fd = fd;
-  ufds[numFds + 0].events = event;
-  ufds[numFds + 1].fd = -1;
-  return (jlong) (long) ufds;
-}
-
-jlong
-frysk::sys::Poll$Fds::addPollIn(jlong fds, jint fd) {
-  return addPollFd(fds, fd, POLLIN);
-}
-
-
-
-void
-frysk::sys::Poll::poll(frysk::sys::PollBuilder* pollObserver, jlong timeout) {
-  // Compute the current number of poll fds.
-  struct pollfd* fds = (struct pollfd*)pollFds->fds;
-  int numFds;
-  for (numFds = 0; fds[numFds].fd >= 0; numFds++);
-
-  // Set up a SIGSETJMP call that jumps back to here when any watched
-  // signal is delivered.  The signals are accumulated in a sigset,
-  // and removed from the current of signals being unmasked, and the
-  // timer is set to zero forcing a non-blocking poll.
-
-  sigset_t signals;
-  sigemptyset (&signals);
-  sigset_t mask = *getRawSet (signalSet);
-  int signum = sigsetjmp (poll_jmpbuf.buf, 1);
-  if (signum > 0) {
-    // Remove the signal from the local copy of the signal-mask set,
-    // doing this allows other signals to get through (otherwize this
-    // code could be swamped by a single re-occuring signal).
-    sigdelset (&mask, signum);
-    // Add it to those that have fired.
-    sigaddset (&signals, signum);
-    // Make the poll non-blocking.  Now that at least one event has
-    // been detected, this method should not block instead returning
-    // immediatly after the file descriptors have been polled.
-    timeout = 0;
-  }
-
-  // Unblock signals, and then wait for an event.  There is a window
-  // between the unmask and poll system calls during which a signal
-  // could be delivered that doesn't interrupt the poll call.  Avoid
-  // this race by having the signal handler longjmp back to the above
-  // setjmp, re-starting this code, forcing the poll (even if it
-  // wasn't reached) to be canceled.
-
-  poll_jmpbuf.tid = frysk::sys::Tid::tid();
-  errno = ::pthread_sigmask (SIG_UNBLOCK, &mask, 0);
-  if (errno != 0)
-    throwErrno (errno, "pthread_sigmask.UNBLOCK");
-  int status = ::poll (fds, numFds, timeout);
-  if (status < 0)
-    status = -errno; // Save the errno across the next system call.
-  errno = ::pthread_sigmask (SIG_BLOCK, &mask, NULL);
-  if (errno != 0)
-    throwErrno (errno, "pthread_sigmask.BLOCK");
-
-  // Did something go wrong?
-  if (status < 0) {
-    switch (-status) {
-    case EINTR:
-      break;
-    default:
-      throwErrno (-status, "poll");
-    }
-  }
-
-  // Deliver any signals received during the poll; XXX: Is there a
-  // more efficient way of doing this?
-
-  for (int i = 1; i < 32; i++) {
-    if (sigismember (&signals, i)) {
-      // Find the signal object.
-      frysk::sys::Signal* sig = frysk::sys::Signal::valueOf (i);
-      // Notify the client of the signal.
-      pollObserver->signal (sig);
-    }
-  }
-
-  // Did a file descriptor fire, status when +ve, contains the number
-  // of file descriptors that fired one or more events.
-
-  struct pollfd* pollfd = (struct pollfd*) pollFds;
-  while (status > 0) {
-    if (pollfd->revents != 0) {
-      if (pollfd->revents & POLLIN)
-	pollObserver->pollIn (pollfd->fd);
-      status--;
-    }
-    pollfd++;
-  }
-}
diff --git a/frysk-sys/frysk/sys/jni/Fork.cxx b/frysk-sys/frysk/sys/jni/Fork.cxx
index 02d9799..bb1549b 100644
--- a/frysk-sys/frysk/sys/jni/Fork.cxx
+++ b/frysk-sys/frysk/sys/jni/Fork.cxx
@@ -115,9 +115,6 @@ spawn(jnixx::env env, tracing trace, redirect& redirection, exec& execute) {
 	::_exit(errno);
       }
       break;
-    case UTRACE:
-      fprintf(stderr, "\n\n>>>>> in spawn(...utrace)\n\n");
-      break;
     case CHILD:
       break;
     case DAEMON:
@@ -199,14 +196,6 @@ frysk::sys::Fork::ptrace(jnixx::env env, String exe,
 }
 
 jint
-frysk::sys::Fork::utrace(jnixx::env env, String exe,
-			 String in, String out, String err,
-			 jnixx::array<String> args,
-			 jnixx::array<String> environ) {
-  return ::spawn(env, exe, in, out, err, args, environ, UTRACE);
-}
-
-jint
 frysk::sys::Fork::daemon(jnixx::env env, String exe,
 			 String in, String out, String err,
 			 jnixx::array<String> args,
diff --git a/frysk-sys/frysk/sys/jni/Fork.hxx b/frysk-sys/frysk/sys/jni/Fork.hxx
index 2df12a4..6bf9dd1 100644
--- a/frysk-sys/frysk/sys/jni/Fork.hxx
+++ b/frysk-sys/frysk/sys/jni/Fork.hxx
@@ -41,7 +41,6 @@ enum tracing {
   CHILD,
   DAEMON,
   PTRACE,
-  UTRACE,
 };
 
 /**
diff --git a/frysk-sys/frysk/sys/jni/Poll.cxx b/frysk-sys/frysk/sys/jni/Poll.cxx
deleted file mode 100644
index a0f0eaa..0000000
--- a/frysk-sys/frysk/sys/jni/Poll.cxx
+++ /dev/null
@@ -1,239 +0,0 @@
-// This file is part of the program FRYSK.
-//
-// Copyright 2005, 2006, 2007, 2008, Red Hat Inc.
-//
-// FRYSK is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// FRYSK is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with FRYSK; if not, write to the Free Software Foundation,
-// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-// 
-// In addition, as a special exception, Red Hat, Inc. gives You the
-// additional right to link the code of FRYSK with code not covered
-// under the GNU General Public License ("Non-GPL Code") and to
-// distribute linked combinations including the two, subject to the
-// limitations in this paragraph. Non-GPL Code permitted under this
-// exception must only link to the code of FRYSK through those well
-// defined interfaces identified in the file named EXCEPTION found in
-// the source code files (the "Approved Interfaces"). The files of
-// Non-GPL Code may instantiate templates or use macros or inline
-// functions from the Approved Interfaces without causing the
-// resulting work to be covered by the GNU General Public
-// License. Only Red Hat, Inc. may make changes or additions to the
-// list of Approved Interfaces. You must obey the GNU General Public
-// License in all respects for all of the FRYSK code and other code
-// used in conjunction with FRYSK except the Non-GPL Code covered by
-// this exception. If you modify this file, you may extend this
-// exception to your version of the file, but you are not obligated to
-// do so. If you do not wish to provide this exception without
-// modification, you must delete this exception statement from your
-// version and license this file solely under the GPL without
-// exception.
-
-#include <malloc.h>
-#include <string.h>
-#include <sys/poll.h>
-#include <setjmp.h>
-#include <signal.h>
-#include <alloca.h>
-#include <errno.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <linux/unistd.h>
-#include <linux.syscall.h>
-#include <sys/syscall.h>
-
-#include "jni.hxx"
-
-#include "jnixx/exceptions.hxx"
-#include "frysk/sys/jni/SignalSet.hxx"
-
-using namespace java::lang;
-using namespace frysk::sys;
-
-// If there's a signal abort the wait() function using a longjmp (and
-// return the signal).  Should the jmpbuf be per-thread?
-
-struct poll_jmpbuf {
-  pid_t tid;
-  sigjmp_buf buf;
-};
-struct poll_jmpbuf poll_jmpbuf;
-
-static void
-handler(int signum, siginfo_t *siginfo, void *context) {
-  // For what ever reason, the signal can come in on the wrong thread.
-  // When that occures, re-direct it (explicitly) to the thread that
-  // can handle the signal.
-  pid_t me = ::syscall(SYS_gettid);
-  if (poll_jmpbuf.tid == me) {
-#if 0
-    fprintf (stderr, "pid %d got signal %d (%s) from %d\n",
-	     me, siginfo->si_signo, strsignal (siginfo->si_signo),
-	     siginfo->si_pid);
-#endif
-    siglongjmp (poll_jmpbuf.buf, signum);
-  }
-  else
-    // XXX: Want to edit this thread's mask so that from now on it
-    // blocks this signal, don't know a way to do it though.
-    ::syscall(SYS_tkill, poll_jmpbuf.tid, signum);
-}
-
-void
-Poll::addSignalHandler(jnixx::env env, Signal sig) {
-  int signum = sig.hashCode(env);
-  // Make certain that the signal is masked (this is ment to be
-  // process wide).
-  sigset_t mask;
-  sigemptyset(&mask);
-  sigaddset(&mask, signum);
-  // XXX: In a multi-threaded environment this call is not well
-  // defined (although it does help reduce the number of signals
-  // directed to the wrong thread).
-  sigprocmask(SIG_BLOCK, &mask, NULL);
-  // Install the above signal handler (it long jumps back to the code
-  // that enabled the signal).  To avoid potential recursion, all
-  // signals are masked while the handler is running.
-  struct sigaction sa;
-  memset(&sa, 0, sizeof (sa));
-  sa.sa_sigaction = handler;
-  sa.sa_flags = SA_SIGINFO;
-  sigfillset(&sa.sa_mask);
-  sigaction(signum, &sa, NULL);
-}
-
-
-
-jlong
-Poll$Fds::malloc(jnixx::env env) {
-  // Allocate a non-empty buffer, marked with a sentinel.
-  struct pollfd* fds = (struct pollfd*) ::malloc (sizeof (struct pollfd));
-  fds->fd = -1; // sentinel
-  return (jlong)(long) fds;
-}
-
-void
-Poll$Fds::free(jnixx::env env, jlong fds) {
-  ::free((struct pollfd*)(long)fds);
-}
-
-static jlong
-addPollFd(jlong pollFds, int fd, short event) {
-  struct pollfd* ufds = (struct pollfd*) pollFds;
-  // If the FD is alreay listed, just add the event; end up with a
-  // count of fds.
-  int numFds;
-  for (numFds = 0; ufds[numFds].fd >= 0; numFds++) {
-    if (ufds[numFds].fd == fd) {
-      ufds[numFds].events |= event;
-      return pollFds;
-    }
-  }
-  // Create space for the new fd (and retain space for the sentinel).
-  ufds = (struct pollfd*) ::realloc(ufds, (numFds + 2) * sizeof (struct pollfd));
-  ufds[numFds + 0].fd = fd;
-  ufds[numFds + 0].events = event;
-  ufds[numFds + 1].fd = -1;
-  return (jlong) (long) ufds;
-}
-
-jlong
-Poll$Fds::addPollIn(jnixx::env env, jlong fds, jint fd) {
-  return addPollFd(fds, fd, POLLIN);
-}
-
-
-
-void
-Poll::poll(jnixx::env env, PollBuilder pollObserver, jlong timeout) {
-  // Compute the current number of poll fds.
-  struct pollfd* fds = (struct pollfd*)GetPollFds(env).GetFds(env);
-  int numFds;
-  for (numFds = 0; fds[numFds].fd >= 0; numFds++);
-
-  // Set up a SIGSETJMP call that jumps back to here when any watched
-  // signal is delivered.  The signals are accumulated in a sigset,
-  // and removed from the current of signals being unmasked, and the
-  // timer is set to zero forcing a non-blocking poll.
-
-  sigset_t signals;
-  sigemptyset(&signals);
-  sigset_t mask = *getRawSet(env, GetSignalSet(env));
-  int signum = sigsetjmp(poll_jmpbuf.buf, 1);
-  if (signum > 0) {
-    // Remove the signal from the local copy of the signal-mask set,
-    // doing this allows other signals to get through (otherwize this
-    // code could be swamped by a single re-occuring signal).
-    sigdelset(&mask, signum);
-    // Add it to those that have fired.
-    sigaddset(&signals, signum);
-    // Make the poll non-blocking.  Now that at least one event has
-    // been detected, this method should not block instead returning
-    // immediatly after the file descriptors have been polled.
-    timeout = 0;
-  }
-
-  // Unblock signals, and then wait for an event.  There is a window
-  // between the unmask and poll system calls during which a signal
-  // could be delivered that doesn't interrupt the poll call.  Avoid
-  // this race by having the signal handler longjmp back to the above
-  // setjmp, re-starting this code, forcing the poll (even if it
-  // wasn't reached) to be canceled.
-
-  poll_jmpbuf.tid = ::syscall(SYS_gettid);
-  errno = ::pthread_sigmask (SIG_UNBLOCK, &mask, 0);
-  if (errno != 0)
-    errnoException(env, errno, "pthread_sigmask.UNBLOCK");
-  int status = ::poll (fds, numFds, timeout);
-  if (status < 0)
-    status = -errno; // Save the errno across the next system call.
-  errno = ::pthread_sigmask (SIG_BLOCK, &mask, NULL);
-  if (errno != 0)
-    errnoException(env, errno, "pthread_sigmask.BLOCK");
-
-  // Did something go wrong?
-  if (status < 0) {
-    switch (-status) {
-    case EINTR:
-      break;
-    default:
-      errnoException(env, -status, "poll");
-    }
-  }
-
-  // Deliver any signals received during the poll; XXX: Is there a
-  // more efficient way of doing this?
-
-  for (int i = 1; i < 32; i++) {
-    if (sigismember (&signals, i)) {
-      // Find the signal object.
-      Signal sig = Signal::valueOf(env, i);
-      // Notify the client of the signal.
-      pollObserver.signal(env, sig);
-    }
-  }
-
-  // Did a file descriptor fire, status when +ve, contains the number
-  // of file descriptors that fired one or more events.
-
-  for (int i = 0; i < numFds; i++) {
-    if (status <= 0)
-      // bail early
-      break;
-    if (fds[i].revents != 0) {
-      if (fds[i].revents & POLLIN)
-	pollObserver.pollIn(env, fds[i].fd);
-      status--;
-    }
-  }
-}
diff --git a/frysk-sys/frysk/sys/poll/ChangeLog b/frysk-sys/frysk/sys/poll/ChangeLog
new file mode 100644
index 0000000..236b189
--- /dev/null
+++ b/frysk-sys/frysk/sys/poll/ChangeLog
@@ -0,0 +1,16 @@
+2008-06-20  Andrew Cagney  <cagney@redhat.com>
+
+	* Poll.java: Moved from frysk.sys.
+	* PollBuilder.java: Ditto.
+	* jni/Poll.cxx: Ditto.
+	* cni/Poll.cxx: Ditto.
+	* PollFileDescriptors.java: Extract from Poll.java.
+	* jni/PollFileDescriptors.java: Extract from jni/Poll.cxx.
+	* cni/PollFileDescriptors.java: Similar.
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/frysk-sys/frysk/sys/poll/Poll.java b/frysk-sys/frysk/sys/poll/Poll.java
new file mode 100644
index 0000000..bef9c0a
--- /dev/null
+++ b/frysk-sys/frysk/sys/poll/Poll.java
@@ -0,0 +1,93 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2005, 2007, 2008, Red Hat Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+package frysk.sys.poll;
+
+import frysk.sys.SignalSet;
+import frysk.sys.Signal;
+
+/**
+ * Poll like interface for waiting on kernel events.
+ *
+ * This object, loosely based on the poll and pselect interfaces,
+ * provides a call blocks until a UNIX event (signal, FD ready), the
+ * timeout expires, or an unexpected interrupt occures.  The client
+ * (which extends this object) is notified via the abstract notify
+ * methods.
+ */
+
+public final class Poll {
+    /**
+     * Set of signals checked during poll.
+     */
+    static protected SignalSet signalSet = new SignalSet ();
+    /**
+     * Add Sig to the set of signals checked during poll.
+     */
+    public static void add(Signal sig) {
+	signalSet.add(sig);
+	addSignalHandler(sig);
+    }
+    private static native void addSignalHandler(Signal sig);
+    /**
+     * Empty the set of signals, and file descriptors, checked during
+     * poll.
+     */
+    public static void empty() {
+	// Note that this doesn't restore any signal handlers.
+	signalSet.empty ();
+    }
+
+    /**
+     * Poll the system for either FD, or signal events.  Block for
+     * timeout milliseconds (if timeout is +ve or zero), or until the
+     * next event (if timeout is -ve).  Return when an event might
+     * have occured.
+     */
+    public static void poll(PollBuilder observer, long timeout) {
+	poll(observer, timeout, pollFds.pollFds, pollFds.fds.toArray());
+    }
+    private static native void poll(PollBuilder observer, long timeout,
+				    long pollFds, Object[] fds);
+
+    /**
+     * Set of pollfdS.
+     */
+    static protected PollFileDescriptors pollFds = new PollFileDescriptors();
+}
diff --git a/frysk-sys/frysk/sys/poll/PollBuilder.java b/frysk-sys/frysk/sys/poll/PollBuilder.java
new file mode 100644
index 0000000..d3f6c3d
--- /dev/null
+++ b/frysk-sys/frysk/sys/poll/PollBuilder.java
@@ -0,0 +1,51 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2005, 2007, 2008, Red Hat Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+package frysk.sys.poll;
+
+import frysk.sys.Signal;
+import frysk.sys.FileDescriptor;
+
+/**
+ * Notify client of Poll events.
+ */
+public interface PollBuilder {
+    void signal(Signal sig);
+    void pollIn(FileDescriptor fd);
+}
diff --git a/frysk-sys/frysk/sys/poll/PollFileDescriptors.java b/frysk-sys/frysk/sys/poll/PollFileDescriptors.java
new file mode 100644
index 0000000..0f1380e
--- /dev/null
+++ b/frysk-sys/frysk/sys/poll/PollFileDescriptors.java
@@ -0,0 +1,73 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2005, 2007, 2008, Red Hat Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+package frysk.sys.poll;
+
+import frysk.sys.FileDescriptor;
+
+import java.util.ArrayList;
+
+/**
+ * Manage the file descriptors watched by the poll call.
+ */
+public class PollFileDescriptors {
+    long pollFds = malloc();
+    private static native long malloc();
+    final ArrayList fds = new ArrayList();
+
+    public PollFileDescriptors() {
+    }
+
+    protected void finalize() {
+	free(pollFds);
+    }
+    private static native void free(long pollFds);
+
+    public void addPollIn(FileDescriptor fd) {
+	int i = fds.indexOf(fd);
+	if (i >= 0) {
+	    setPollIn(pollFds, i);
+	} else {
+	    fds.add(fd);
+	    pollFds = addPollIn(pollFds, fds.size(), fd.getFd());
+	}
+    }
+    private static native void setPollIn(long pollFds, int pos);
+    private static native long addPollIn(long pollFds, int pos, int fd);
+}
diff --git a/frysk-sys/frysk/sys/poll/cni/Poll.cxx b/frysk-sys/frysk/sys/poll/cni/Poll.cxx
new file mode 100644
index 0000000..5d6f367
--- /dev/null
+++ b/frysk-sys/frysk/sys/poll/cni/Poll.cxx
@@ -0,0 +1,203 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2005, 2006, 2007, 2008, Red Hat Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+#include <sys/poll.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <alloca.h>
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <linux/unistd.h>
+#include <linux.syscall.h>
+
+_syscall2(int, tkill, pid_t, tid, int, sig);
+
+#include <gcj/cni.h>
+
+#include "frysk/sys/cni/Errno.hxx"
+#include "frysk/sys/ProcessIdentifier.h"
+#include "frysk/sys/FileDescriptor.h"
+#include "frysk/sys/Tid.h"
+#include "frysk/sys/Signal.h"
+#include "frysk/sys/SignalSet.h"
+#include "frysk/sys/cni/SignalSet.hxx"
+#include "frysk/sys/poll/Poll.h"
+#include "frysk/sys/poll/PollBuilder.h"
+
+using namespace java::lang;
+using namespace frysk::sys::poll;
+
+// If there's a signal abort the wait() function using a longjmp (and
+// return the signal).  Should the jmpbuf be per-thread?
+
+struct poll_jmpbuf {
+  pid_t tid;
+  sigjmp_buf buf;
+};
+struct poll_jmpbuf poll_jmpbuf;
+
+static void
+handler (int signum, siginfo_t *siginfo, void *context)
+{
+  // For what ever reason, the signal can come in on the wrong thread.
+  // When that occures, re-direct it (explicitly) to the thread that
+  // can handle the signal.
+  pid_t me = frysk::sys::Tid::tid();
+  if (poll_jmpbuf.tid == me) {
+#if 0
+    fprintf (stderr, "pid %d got signal %d (%s) from %d\n",
+	     me, siginfo->si_signo, strsignal (siginfo->si_signo),
+	     siginfo->si_pid);
+#endif
+    siglongjmp (poll_jmpbuf.buf, signum);
+  }
+  else
+    // XXX: Want to edit this thread's mask so that from now on it
+    // blocks this signal, don't know a way to do it though.
+    tkill (poll_jmpbuf.tid, signum);
+}
+
+void
+Poll::addSignalHandler (frysk::sys::Signal* sig) {
+  int signum = sig->hashCode ();
+  // Make certain that the signal is masked (this is ment to be
+  // process wide).
+  sigset_t mask;
+  sigemptyset (&mask);
+  sigaddset (&mask, signum);
+  // XXX: In a multi-threaded environment this call is not well
+  // defined (although it does help reduce the number of signals
+  // directed to the wrong thread).
+  sigprocmask (SIG_BLOCK, &mask, NULL);
+  // Install the above signal handler (it long jumps back to the code
+  // that enabled the signal).  To avoid potential recursion, all
+  // signals are masked while the handler is running.
+  struct sigaction sa;
+  memset (&sa, 0, sizeof (sa));
+  sa.sa_sigaction = handler;
+  sa.sa_flags = SA_SIGINFO;
+  sigfillset (&sa.sa_mask);
+  sigaction (signum, &sa, NULL);
+}
+
+
+
+#define POLLFDS ((struct pollfd*)pollFds)
+
+void
+Poll::poll(PollBuilder* pollObserver, jlong timeout, jlong pollFds,
+	   jobjectArray fds) {
+  int nfds = fds->length;
+
+  // Set up a SIGSETJMP call that jumps back to here when any watched
+  // signal is delivered.  The signals are accumulated in a sigset,
+  // and removed from the current of signals being unmasked, and the
+  // timer is set to zero forcing a non-blocking poll.
+
+  sigset_t signals;
+  sigemptyset (&signals);
+  sigset_t mask = *getRawSet (signalSet);
+  int signum = sigsetjmp (poll_jmpbuf.buf, 1);
+  if (signum > 0) {
+    // Remove the signal from the local copy of the signal-mask set,
+    // doing this allows other signals to get through (otherwize this
+    // code could be swamped by a single re-occuring signal).
+    sigdelset (&mask, signum);
+    // Add it to those that have fired.
+    sigaddset (&signals, signum);
+    // Make the poll non-blocking.  Now that at least one event has
+    // been detected, this method should not block instead returning
+    // immediatly after the file descriptors have been polled.
+    timeout = 0;
+  }
+
+  // Unblock signals, and then wait for an event.  There is a window
+  // between the unmask and poll system calls during which a signal
+  // could be delivered that doesn't interrupt the poll call.  Avoid
+  // this race by having the signal handler longjmp back to the above
+  // setjmp, re-starting this code, forcing the poll (even if it
+  // wasn't reached) to be canceled.
+
+  poll_jmpbuf.tid = frysk::sys::Tid::tid();
+  errno = ::pthread_sigmask (SIG_UNBLOCK, &mask, 0);
+  if (errno != 0)
+    throwErrno (errno, "pthread_sigmask.UNBLOCK");
+  int status = ::poll(POLLFDS, nfds, timeout);
+  if (status < 0)
+    status = -errno; // Save the errno across the next system call.
+  errno = ::pthread_sigmask(SIG_BLOCK, &mask, NULL);
+  if (errno != 0)
+    throwErrno(errno, "pthread_sigmask.BLOCK");
+
+  // Did something go wrong?
+  if (status < 0) {
+    switch (-status) {
+    case EINTR:
+      break;
+    default:
+      throwErrno(-status, "poll");
+    }
+  }
+
+  // Deliver any signals received during the poll; XXX: Is there a
+  // more efficient way of doing this?
+
+  for (int i = 1; i < 32; i++) {
+    if (sigismember (&signals, i)) {
+      // Find the signal object.
+      frysk::sys::Signal* sig = frysk::sys::Signal::valueOf (i);
+      // Notify the client of the signal.
+      pollObserver->signal(sig);
+    }
+  }
+
+  // Did a file descriptor fire, status when +ve, contains the number
+  // of file descriptors that fired one or more events.
+
+  for (int i = 0; i < nfds && status > 0; i++) {
+    if (POLLFDS[i].revents != 0) {
+      if (POLLFDS[i].revents & POLLIN)
+	pollObserver->pollIn((frysk::sys::FileDescriptor*)(elements(fds)[i]));
+      status--;
+    }
+  }
+}
diff --git a/frysk-sys/frysk/sys/poll/cni/PollFileDescriptors.cxx b/frysk-sys/frysk/sys/poll/cni/PollFileDescriptors.cxx
new file mode 100644
index 0000000..e03424b
--- /dev/null
+++ b/frysk-sys/frysk/sys/poll/cni/PollFileDescriptors.cxx
@@ -0,0 +1,77 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2005, 2006, 2007, 2008, Red Hat Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+#include <poll.h>
+
+#include <gcj/cni.h>
+
+#include "frysk/sys/FileDescriptor.h"
+#include "frysk/sys/poll/PollFileDescriptors.h"
+
+using namespace java::lang;
+using namespace frysk::sys::poll;
+
+#define POLLFDS ((struct pollfd*)pollFds)
+
+jlong
+PollFileDescriptors::malloc() {
+  // Allocate a non-empty buffer, marked with a sentinel.
+  struct pollfd* pollFds = (struct pollfd*) JvMalloc(sizeof (struct pollfd));
+  return (jlong)(long)pollFds;
+}
+
+void
+PollFileDescriptors::free(jlong pollFds) {
+  JvFree(POLLFDS);
+}
+
+void
+PollFileDescriptors::setPollIn(jlong pollFds, jint pos) {
+  POLLFDS[pos].events |= POLLIN;
+}
+
+jlong
+PollFileDescriptors::addPollIn(jlong pollFds, jint pos, jint fd) {
+  // Create space for the new fd (and retain space for the sentinel).
+  struct pollfd* ufds
+    = (struct pollfd*) JvRealloc(POLLFDS, (pos + 1)*sizeof (struct pollfd));
+  ufds[pos].fd = fd;
+  ufds[pos].events = POLLIN;
+  return (jlong) (long) ufds;
+}
diff --git a/frysk-sys/frysk/sys/poll/jni/Poll.cxx b/frysk-sys/frysk/sys/poll/jni/Poll.cxx
new file mode 100644
index 0000000..85950c0
--- /dev/null
+++ b/frysk-sys/frysk/sys/poll/jni/Poll.cxx
@@ -0,0 +1,199 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2005, 2006, 2007, 2008, Red Hat Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+#include <malloc.h>
+#include <string.h>
+#include <sys/poll.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <alloca.h>
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <linux/unistd.h>
+#include <linux.syscall.h>
+#include <sys/syscall.h>
+
+#include "jni.hxx"
+
+#include "jnixx/exceptions.hxx"
+#include "frysk/sys/jni/SignalSet.hxx"
+
+using namespace java::lang;
+using namespace frysk::sys::poll;
+
+// If there's a signal abort the wait() function using a longjmp (and
+// return the signal).  Should the jmpbuf be per-thread?
+
+struct poll_jmpbuf {
+  pid_t tid;
+  sigjmp_buf buf;
+};
+struct poll_jmpbuf poll_jmpbuf;
+
+static void
+handler(int signum, siginfo_t *siginfo, void *context) {
+  // For what ever reason, the signal can come in on the wrong thread.
+  // When that occures, re-direct it (explicitly) to the thread that
+  // can handle the signal.
+  pid_t me = ::syscall(SYS_gettid);
+  if (poll_jmpbuf.tid == me) {
+#if 0
+    fprintf (stderr, "pid %d got signal %d (%s) from %d\n",
+	     me, siginfo->si_signo, strsignal (siginfo->si_signo),
+	     siginfo->si_pid);
+#endif
+    siglongjmp (poll_jmpbuf.buf, signum);
+  }
+  else
+    // XXX: Want to edit this thread's mask so that from now on it
+    // blocks this signal, don't know a way to do it though.
+    ::syscall(SYS_tkill, poll_jmpbuf.tid, signum);
+}
+
+void
+Poll::addSignalHandler(jnixx::env env, Signal sig) {
+  int signum = sig.hashCode(env);
+  // Make certain that the signal is masked (this is ment to be
+  // process wide).
+  sigset_t mask;
+  sigemptyset(&mask);
+  sigaddset(&mask, signum);
+  // XXX: In a multi-threaded environment this call is not well
+  // defined (although it does help reduce the number of signals
+  // directed to the wrong thread).
+  sigprocmask(SIG_BLOCK, &mask, NULL);
+  // Install the above signal handler (it long jumps back to the code
+  // that enabled the signal).  To avoid potential recursion, all
+  // signals are masked while the handler is running.
+  struct sigaction sa;
+  memset(&sa, 0, sizeof (sa));
+  sa.sa_sigaction = handler;
+  sa.sa_flags = SA_SIGINFO;
+  sigfillset(&sa.sa_mask);
+  sigaction(signum, &sa, NULL);
+}
+
+
+
+#define POLLFDS ((struct pollfd*)pollFds)
+
+void
+Poll::poll(jnixx::env env, PollBuilder pollObserver, jlong timeout,
+	   jlong pollFds, ::jnixx::array<Object> fds) {
+  int nfds = fds.GetArrayLength(env);
+
+  // Set up a SIGSETJMP call that jumps back to here when any watched
+  // signal is delivered.  The signals are accumulated in a sigset,
+  // and removed from the current of signals being unmasked, and the
+  // timer is set to zero forcing a non-blocking poll.
+
+  sigset_t signals;
+  sigemptyset(&signals);
+  sigset_t mask = *getRawSet(env, GetSignalSet(env));
+  int signum = sigsetjmp(poll_jmpbuf.buf, 1);
+  if (signum > 0) {
+    // Remove the signal from the local copy of the signal-mask set,
+    // doing this allows other signals to get through (otherwize this
+    // code could be swamped by a single re-occuring signal).
+    sigdelset(&mask, signum);
+    // Add it to those that have fired.
+    sigaddset(&signals, signum);
+    // Make the poll non-blocking.  Now that at least one event has
+    // been detected, this method should not block instead returning
+    // immediatly after the file descriptors have been polled.
+    timeout = 0;
+  }
+
+  // Unblock signals, and then wait for an event.  There is a window
+  // between the unmask and poll system calls during which a signal
+  // could be delivered that doesn't interrupt the poll call.  Avoid
+  // this race by having the signal handler longjmp back to the above
+  // setjmp, re-starting this code, forcing the poll (even if it
+  // wasn't reached) to be canceled.
+
+  poll_jmpbuf.tid = ::syscall(SYS_gettid);
+  errno = ::pthread_sigmask(SIG_UNBLOCK, &mask, 0);
+  if (errno != 0)
+    errnoException(env, errno, "pthread_sigmask.UNBLOCK");
+  int status = ::poll(POLLFDS, nfds, timeout);
+  if (status < 0)
+    status = -errno; // Save the errno across the next system call.
+  errno = ::pthread_sigmask(SIG_BLOCK, &mask, NULL);
+  if (errno != 0)
+    errnoException(env, errno, "pthread_sigmask.BLOCK");
+
+  // Did something go wrong?
+  if (status < 0) {
+    switch (-status) {
+    case EINTR:
+      break;
+    default:
+      errnoException(env, -status, "poll");
+    }
+  }
+
+  // Deliver any signals received during the poll; XXX: Is there a
+  // more efficient way of doing this?
+
+  for (int i = 1; i < 32; i++) {
+    if (sigismember(&signals, i)) {
+      // Find the signal object.
+      Signal sig = Signal::valueOf(env, i);
+      // Notify the client of the signal.
+      pollObserver.signal(env, sig);
+    }
+  }
+
+  // Did a file descriptor fire, status when +ve, contains the number
+  // of file descriptors that fired one or more events.
+
+  for (int i = 0; i < nfds && status > 0; i++) {
+    if (POLLFDS[i].revents != 0) {
+      if (POLLFDS[i].revents & POLLIN) {
+	frysk::sys::FileDescriptor fd
+	  = frysk::sys::FileDescriptor(env, fds.GetObjectArrayElement(env, i)._object);
+	pollObserver.pollIn(env, fd);
+      }
+      status--;
+    }
+  }
+}
diff --git a/frysk-sys/frysk/sys/poll/jni/PollFileDescriptors.cxx b/frysk-sys/frysk/sys/poll/jni/PollFileDescriptors.cxx
new file mode 100644
index 0000000..586d34c
--- /dev/null
+++ b/frysk-sys/frysk/sys/poll/jni/PollFileDescriptors.cxx
@@ -0,0 +1,77 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2005, 2006, 2007, 2008, Red Hat Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+#include <poll.h>
+#include <malloc.h>
+
+#include "jni.hxx"
+
+using namespace java::lang;
+using namespace frysk::sys::poll;
+
+#define POLLFDS ((struct pollfd*)pollFds)
+
+jlong
+PollFileDescriptors::malloc(jnixx::env env) {
+  // Allocate a non-empty buffer, marked with a sentinel.
+  struct pollfd* fds = (struct pollfd*) ::malloc (sizeof (struct pollfd));
+  fds->fd = -1; // sentinel
+  return (jlong)(long) fds;
+}
+
+void
+PollFileDescriptors::free(jnixx::env env, jlong pollFds) {
+  ::free(POLLFDS);
+}
+
+void
+PollFileDescriptors::setPollIn(jnixx::env env, jlong pollFds, jint pos) {
+  POLLFDS[pos].events |= POLLIN;
+}
+
+jlong
+PollFileDescriptors::addPollIn(jnixx::env env, jlong pollFds,
+			       jint pos, int fd) {
+  // Create space for the new fd (and retain space for the sentinel).
+  struct pollfd* ufds
+    = (struct pollfd*) ::realloc(POLLFDS, (pos + 1)*sizeof (struct pollfd));
+  ufds[pos].fd = fd;
+  ufds[pos].events = POLLIN;
+  return (jlong) (long) ufds;
+}
diff --git a/frysk-sys/frysk/sys/proc/ChangeLog b/frysk-sys/frysk/sys/proc/ChangeLog
index 84cf92d..b6ac106 100644
--- a/frysk-sys/frysk/sys/proc/ChangeLog
+++ b/frysk-sys/frysk/sys/proc/ChangeLog
@@ -1,3 +1,15 @@
+2008-06-20  Andrew Cagney  <cagney@redhat.com>
+
+	* jni/ProcBuilder.cxx (ProcBuilder::construct): Catch a Throwable.
+	* jni/ProcBuilder.cxx (ProcBuilder::construct): Ditto.
+
+2008-06-12  Andrew Cagney  <cagney@redhat.com>
+
+	* Exe.java (getName): Rename get.
+	(openReadOnly): New.
+	* jni/Exe.cxx (Exe::getName): Update.
+	* cni/Exe.cxx (Exe::getName): Update.
+
 2008-06-04  Andrew Cagney  <cagney@redhat.com>
 
 	* TestMaps.java (testNative()): New.
diff --git a/frysk-sys/frysk/sys/proc/Exe.java b/frysk-sys/frysk/sys/proc/Exe.java
index 07c9a05..23e33be 100644
--- a/frysk-sys/frysk/sys/proc/Exe.java
+++ b/frysk-sys/frysk/sys/proc/Exe.java
@@ -43,14 +43,11 @@ import frysk.sys.ProcessIdentifier;
 
 /**
  * The contents of <tt>/proc/PID/exe</tt>.
- *
- * XXX: Should this be more like a builder or like Stat where there's
- * a refresh method that detects that the contents actually changed?
  */
 
 public class Exe {
-    public static String get(ProcessIdentifier pid) {
-	return get(pid.intValue());
+    public static String getName(ProcessIdentifier pid) {
+	return getName(pid.intValue());
     }
-    private static native String get (int pid);
+    private static native String getName(int pid);
 }
diff --git a/frysk-sys/frysk/sys/proc/cni/Exe.cxx b/frysk-sys/frysk/sys/proc/cni/Exe.cxx
index 6f258c5..8b583fb 100644
--- a/frysk-sys/frysk/sys/proc/cni/Exe.cxx
+++ b/frysk-sys/frysk/sys/proc/cni/Exe.cxx
@@ -48,22 +48,46 @@
 #include "frysk/sys/proc/Exe.h"
 
 jstring
-frysk::sys::proc::Exe::get (jint pid)
-{
+frysk::sys::proc::Exe::getName(jint pid) {
   char file[FILENAME_MAX];
   if (::snprintf (file, sizeof file, "/proc/%d/exe", (int) pid)
       >= FILENAME_MAX)
-    throwRuntimeException ("snprintf: buffer overflow");
+    throwRuntimeException("snprintf: buffer overflow");
 
   // /proc/$$/exe contains a soft-link specifying the name of the
   // executable, possibly with "(deleted)" appended.  That link's
   // upper bound is determined by FILENAME_MAX since that is the
-  // longest possible allowable file name.
-  const int maxLen = FILENAME_MAX + sizeof (" (deleted)") + 1;
+  // longest possible allowable file name.  Note that readlink doesn't
+  // NUL terminate so need to leave space for that.
+  const char deleted[] = " (deleted)";
+  const int maxLen = FILENAME_MAX + sizeof(deleted) + 1;
   char link[maxLen];
-  int len = ::readlink (file, link, sizeof (link));
+  int len = ::readlink(file, link, sizeof(link) - 1);
   if (len < 0 || len >= maxLen)
-    throwErrno (errno, "readlink");
+    throwErrno(errno, "readlink");
+  link[len] = '\0';
+
+  // Linux's /proc/$$/exe can get screwed up in several ways.  Detect
+  // each here and return null.
+  if ((int) strlen(link) != len) {
+    // Assume that an EXE that has somehow ended up with an embedded
+    // NUL character is invalid.  This happens when the kernel screws
+    // up "mv a-really-long-file $exe" leaving the updated EXE string
+    // with something like "$exe<NUL>ally-long-file (deleted)".
+    throwUserException("The link %s is corrupt", file);
+  }
+
+  if (strstr(link, deleted) + strlen(deleted) - link == len) {
+    // Assume (possibly incorrectly) that a trailing "(deleted)"
+    // always indicates a deleted file.
+    link[len - strlen(deleted)] = '\0';
+    throwUserException("The link %s points to the deleted file %s",
+		       file, link);
+  }
+
+  if (access(link, F_OK) != 0) {
+    throwErrno(errno, "file %s", link);
+  }
 
   // Note that some kernels have a "feature" where the link can become
   // corrupted.  Just retun that, the caller needs to decide if the
diff --git a/frysk-sys/frysk/sys/proc/cni/ProcBuilder.cxx b/frysk-sys/frysk/sys/proc/cni/ProcBuilder.cxx
index 20c09e6..2b0bc85 100644
--- a/frysk-sys/frysk/sys/proc/cni/ProcBuilder.cxx
+++ b/frysk-sys/frysk/sys/proc/cni/ProcBuilder.cxx
@@ -97,9 +97,9 @@ frysk::sys::proc::ProcBuilder::construct(jint pid, frysk::rsl::Log* warning) {
 
     try {
       build(frysk::sys::ProcessIdentifierFactory::create(id));
-    } catch (java::lang::RuntimeException *e) {
+    } catch (java::lang::Throwable *t) {
       ::closedir(proc);
-      throw e;
+      throw t;
     }
   }
 
diff --git a/frysk-sys/frysk/sys/proc/jni/Exe.cxx b/frysk-sys/frysk/sys/proc/jni/Exe.cxx
index 12745a8..112f363 100644
--- a/frysk-sys/frysk/sys/proc/jni/Exe.cxx
+++ b/frysk-sys/frysk/sys/proc/jni/Exe.cxx
@@ -49,7 +49,7 @@
 using namespace java::lang;
 
 String
-frysk::sys::proc::Exe::get(jnixx::env env, jint pid) {
+frysk::sys::proc::Exe::getName(jnixx::env env, jint pid) {
   // Get the name of the EXE in /proc.
   char file[FILENAME_MAX];
   if (::snprintf(file, sizeof file, "/proc/%d/exe", (int) pid)
@@ -60,13 +60,36 @@ frysk::sys::proc::Exe::get(jnixx::env env, jint pid) {
   // executable, possibly with "(deleted)" appended.  That link's
   // upper bound is determined by FILENAME_MAX since that is the
   // longest possible allowable file name.
-  const int maxLen = FILENAME_MAX + sizeof (" (deleted)") + 1;
+  const char deleted[] = " (deleted)";
+  const int maxLen = FILENAME_MAX + sizeof(deleted) + 1;
   char link[maxLen];
-  int len = ::readlink (file, link, sizeof (link) - 1);
+  int len = ::readlink (file, link, sizeof(link) - 1);
   if (len < 0 || len >= maxLen)
     errnoException(env, errno, "readlink");
   link[len] = '\0';
 
+  // Linux's /proc/$$/exe can get screwed up in several ways.  Detect
+  // each here and return null.
+  if ((int) strlen(link) != len) {
+    // Assume that an EXE that has somehow ended up with an embedded
+    // NUL character is invalid.  This happens when the kernel screws
+    // up "mv a-really-long-file $exe" leaving the updated EXE string
+    // with something like "$exe<NUL>ally-long-file (deleted)".
+    userException(env, "The link %s is corrupt", file);
+  }
+
+  if (strstr(link, deleted) + strlen(deleted) - link == len) {
+    // Assume (possibly incorrectly) that a trailing "(deleted)"
+    // always indicates a deleted file.
+    link[len - strlen(deleted)] = '\0';
+    userException(env, "The link %s points to the deleted file %s",
+		  file, link);
+  }
+
+  if (access(link, F_OK) != 0) {
+    errnoException(env, errno, "file %s", link);
+  }
+
   // Note that some kernels have a "feature" where the link can become
   // corrupted.  Just retun that, the caller needs to decide if the
   // extracted link is valid.
diff --git a/frysk-sys/frysk/sys/proc/jni/ProcBuilder.cxx b/frysk-sys/frysk/sys/proc/jni/ProcBuilder.cxx
index 866dfd1..2cc52ae 100644
--- a/frysk-sys/frysk/sys/proc/jni/ProcBuilder.cxx
+++ b/frysk-sys/frysk/sys/proc/jni/ProcBuilder.cxx
@@ -92,9 +92,9 @@ frysk::sys::proc::ProcBuilder::construct(::jnixx::env env, jint pid,
 
     try {
       build(env, frysk::sys::ProcessIdentifierFactory::create(env, id));
-    } catch (java::lang::RuntimeException *e) {
+    } catch (java::lang::Throwable t) {
       ::closedir(proc);
-      throw e;
+      throw t;
     }
   }
 
diff --git a/frysk-sys/frysk/sys/ptrace/AddressSpace.java b/frysk-sys/frysk/sys/ptrace/AddressSpace.java
deleted file mode 100644
index b9203ba..0000000
--- a/frysk-sys/frysk/sys/ptrace/AddressSpace.java
+++ /dev/null
@@ -1,145 +0,0 @@
-// This file is part of the program FRYSK.
-// 
-// Copyright 2005, 2006, 2007, 2008, Red Hat Inc.
-// 
-// FRYSK is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-// 
-// FRYSK is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with FRYSK; if not, write to the Free Software Foundation,
-// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-// 
-// In addition, as a special exception, Red Hat, Inc. gives You the
-// additional right to link the code of FRYSK with code not covered
-// under the GNU General Public License ("Non-GPL Code") and to
-// distribute linked combinations including the two, subject to the
-// limitations in this paragraph. Non-GPL Code permitted under this
-// exception must only link to the code of FRYSK through those well
-// defined interfaces identified in the file named EXCEPTION found in
-// the source code files (the "Approved Interfaces"). The files of
-// Non-GPL Code may instantiate templates or use macros or inline
-// functions from the Approved Interfaces without causing the
-// resulting work to be covered by the GNU General Public
-// License. Only Red Hat, Inc. may make changes or additions to the
-// list of Approved Interfaces. You must obey the GNU General Public
-// License in all respects for all of the FRYSK code and other code
-// used in conjunction with FRYSK except the Non-GPL Code covered by
-// this exception. If you modify this file, you may extend this
-// exception to your version of the file, but you are not obligated to
-// do so. If you do not wish to provide this exception without
-// modification, you must delete this exception statement from your
-// version and license this file solely under the GPL without
-// exception.
-
-package frysk.sys.ptrace;
-
-import frysk.rsl.Log;
-import frysk.sys.ProcessIdentifier;
-
-/**
- * A ptrace address space, that can be peeked or poked a "word" at
- * a time.
- */
-public class AddressSpace {
-    private static final Log fine = Log.fine(AddressSpace.class);
-
-    private final long length;
-    private final String name;
-    private final int ptPeek;
-    private final int ptPoke;
-
-    AddressSpace(long length, String name, int ptPeek, int ptPoke) {
-	this.name = super.toString() + ":" + name;
-	this.length = length;
-	this.ptPeek = ptPeek;
-	this.ptPoke = ptPoke;
-    }
-
-    public String toString() {
-	return name;
-    }
-    public long length() {
-	return length;
-    }
-
-    /**
-     * Fetch a byte at ADDR of process PID.
-     */
-    public int peek(ProcessIdentifier pid, long addr) {
-	fine.log(this, "peek", pid, "addr", addr, "...");
-	int ret = peek(pid.intValue(), addr);
-	fine.log("... peek", pid, "returns", ret);
-	return ret;
-    }
-    private native int peek (int pid, long addr);
-
-    /**
-     * Store the byte at ADDR of process PID.
-     */
-    public void poke(ProcessIdentifier pid, long addr, int data) {
-	fine.log(this, "poke", pid, "addr", addr, "data", (long) data);
-	poke(pid.intValue(), addr, data);
-    }
-    private native void poke(int pid, long addr, int data);
-
-    /**
-     * Transfer data between the local BYTES array and process PID.
-     * Locally the data starts at OFFSET and goes for LENGTH bytes.
-     *
-     * This is a host oriented transfer; hence LENGTH, which must fall
-     * within the bounds of BYTES, is an int.
-     */
-    public void transfer(ProcessIdentifier pid, long addr,
-			 byte[] bytes, int offset, int length,
-			 boolean write) {
-	fine.log(this, "transfer", pid, "addr", addr,
-		 "offset", offset, "length", length,
-		 write ? "write ..." : "read ...");
-	transfer(write ? ptPoke : ptPeek, pid.intValue(), addr,
-		 bytes, offset, length);
-    }
-
-    /**
-     * Transfer data between the local BYTES array and process PID.
-     * Up to LENGTH bytes are copied, starting at OFFSET in the BYTES
-     * array.  The number of bytes actually transfered is returned.
-     *
-     * This is a target oriented transfer; hence LENGTH, as an address
-     * sized quantity, is a long and can be larger than the bounds of
-     * BYTES.
-     */
-    public int transfer(ProcessIdentifier pid, long addr, long length,
-			byte[] bytes, int offset, boolean write) {
-	fine.log(this, "transfer", pid, "addr", addr, "length", length,
-		 "offset", offset, write ? "write ..." : "read ...");
-	int size;
-	if (offset >= 0 && length >= 0) {
-	    if (offset + length > bytes.length)
-		size = bytes.length - offset;
-	    else
-		size = (int) length;
-	} else {
-	    size = -1; // triggers exception
-	}
-	transfer(write ? ptPoke : ptPeek, pid.intValue(), addr,
-		 bytes, offset, size);
-	return size;
-    }
-
-    private native final void transfer(int op, int pid, long addr,
-				       byte[] bytes, int offset, int length);
-
-    private static native AddressSpace text();
-    private static native AddressSpace data();
-    private static native AddressSpace usr();
-
-    public static final AddressSpace TEXT = text();
-    public static final AddressSpace DATA = data();
-    public static final AddressSpace USR = usr();
-}
diff --git a/frysk-sys/frysk/sys/ptrace/BlockSpace.java b/frysk-sys/frysk/sys/ptrace/BlockSpace.java
new file mode 100644
index 0000000..916fc1a
--- /dev/null
+++ b/frysk-sys/frysk/sys/ptrace/BlockSpace.java
@@ -0,0 +1,90 @@
+// This file is part of the program FRYSK.
+// 
+// Copyright 2005, 2006, 2007, 2008, Red Hat Inc.
+// 
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+// 
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+package frysk.sys.ptrace;
+
+import frysk.rsl.Log;
+import frysk.sys.ProcessIdentifier;
+
+/**
+ * A ptrace space that is transfered to/from PID in bulk.
+ *
+ * One day, someone will implement caching of this, minimizing the
+ * need for redundant transfers.
+ */
+public class BlockSpace {
+    private static final Log fine = Log.fine(BlockSpace.class);
+
+    private final int ptLength;
+    private final int ptGet;
+    private final int ptSet;
+
+    BlockSpace(int ptLength, int ptGet, int ptSet) {
+	this.ptLength = ptLength;
+	this.ptGet = ptGet;
+	this.ptSet = ptSet;
+    }
+
+    /**
+     * Return the size of the register set in bytes.
+     */
+    public int length() {
+	return ptLength;
+    }
+
+    /**
+     * Fetch PID's register set into DATA.
+     */
+    public void transfer(ProcessIdentifier pid, byte[] data,
+			 boolean write) {
+	fine.log(this, "transfer", pid, write ? "write ..." : "read ...");
+	transfer(write ? ptSet : ptGet, pid.intValue(), data, ptLength);
+    }
+
+    private static native void transfer(int op, int pid, byte[] data,
+					int length);
+
+    private static native BlockSpace regs();
+    private static native BlockSpace fpregs();
+    private static native BlockSpace fpxregs();
+
+    public static final BlockSpace REGS = regs();
+    public static final BlockSpace FPREGS = fpregs();
+    public static final BlockSpace FPXREGS = fpxregs();
+}
diff --git a/frysk-sys/frysk/sys/ptrace/ByteSpace.java b/frysk-sys/frysk/sys/ptrace/ByteSpace.java
new file mode 100644
index 0000000..e28b906
--- /dev/null
+++ b/frysk-sys/frysk/sys/ptrace/ByteSpace.java
@@ -0,0 +1,145 @@
+// This file is part of the program FRYSK.
+// 
+// Copyright 2005, 2006, 2007, 2008, Red Hat Inc.
+// 
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+// 
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+package frysk.sys.ptrace;
+
+import frysk.rsl.Log;
+import frysk.sys.ProcessIdentifier;
+
+/**
+ * A ptrace space, that can be efficiently peeked and poked a "word"
+ * or even "byte" at a time.
+ */
+public class ByteSpace {
+    private static final Log fine = Log.fine(ByteSpace.class);
+
+    private final long length;
+    private final String name;
+    private final int ptPeek;
+    private final int ptPoke;
+
+    ByteSpace(long length, String name, int ptPeek, int ptPoke) {
+	this.name = super.toString() + ":" + name;
+	this.length = length;
+	this.ptPeek = ptPeek;
+	this.ptPoke = ptPoke;
+    }
+
+    public String toString() {
+	return name;
+    }
+    public long length() {
+	return length;
+    }
+
+    /**
+     * Fetch a byte at ADDR of process PID.
+     */
+    public int peek(ProcessIdentifier pid, long addr) {
+	fine.log(this, "peek", pid, "addr", addr, "...");
+	int ret = peek(pid.intValue(), addr);
+	fine.log("... peek", pid, "returns", ret);
+	return ret;
+    }
+    private native int peek (int pid, long addr);
+
+    /**
+     * Store the byte at ADDR of process PID.
+     */
+    public void poke(ProcessIdentifier pid, long addr, int data) {
+	fine.log(this, "poke", pid, "addr", addr, "data", (long) data);
+	poke(pid.intValue(), addr, data);
+    }
+    private native void poke(int pid, long addr, int data);
+
+    /**
+     * Transfer data between the local BYTES array and process PID.
+     * Locally the data starts at OFFSET and goes for LENGTH bytes.
+     *
+     * This is a host oriented transfer; hence LENGTH, which must fall
+     * within the bounds of BYTES, is an int.
+     */
+    public void transfer(ProcessIdentifier pid, long addr,
+			 byte[] bytes, int offset, int length,
+			 boolean write) {
+	fine.log(this, "transfer", pid, "addr", addr,
+		 "offset", offset, "length", length,
+		 write ? "write ..." : "read ...");
+	transfer(write ? ptPoke : ptPeek, pid.intValue(), addr,
+		 bytes, offset, length);
+    }
+
+    /**
+     * Transfer data between the local BYTES array and process PID.
+     * Up to LENGTH bytes are copied, starting at OFFSET in the BYTES
+     * array.  The number of bytes actually transfered is returned.
+     *
+     * This is a target oriented transfer; hence LENGTH, as an address
+     * sized quantity, is a long and can be larger than the bounds of
+     * BYTES.
+     */
+    public int transfer(ProcessIdentifier pid, long addr, long length,
+			byte[] bytes, int offset, boolean write) {
+	fine.log(this, "transfer", pid, "addr", addr, "length", length,
+		 "offset", offset, write ? "write ..." : "read ...");
+	int size;
+	if (offset >= 0 && length >= 0) {
+	    if (offset + length > bytes.length)
+		size = bytes.length - offset;
+	    else
+		size = (int) length;
+	} else {
+	    size = -1; // triggers exception
+	}
+	transfer(write ? ptPoke : ptPeek, pid.intValue(), addr,
+		 bytes, offset, size);
+	return size;
+    }
+
+    private native final void transfer(int op, int pid, long addr,
+				       byte[] bytes, int offset, int length);
+
+    private static native ByteSpace text();
+    private static native ByteSpace data();
+    private static native ByteSpace usr();
+
+    public static final ByteSpace TEXT = text();
+    public static final ByteSpace DATA = data();
+    public static final ByteSpace USR = usr();
+}
diff --git a/frysk-sys/frysk/sys/ptrace/ChangeLog b/frysk-sys/frysk/sys/ptrace/ChangeLog
index 9484163..0a363c5 100644
--- a/frysk-sys/frysk/sys/ptrace/ChangeLog
+++ b/frysk-sys/frysk/sys/ptrace/ChangeLog
@@ -1,3 +1,30 @@
+2008-07-07  Andrew Cagney  <cagney@redhat.com>
+
+	* Utrace.java: Delete stub.
+	* jni/Utrace.java: Delete stub.
+	* cni/Utrace.java: Delete stub.
+	* TestUtrace.java: Delete stub.
+
+2008-07-04  Andrew Cagney  <cagney@redhat.com>
+
+	* jni/ByteSpace.cxx: Rename jni/AddressSpace.java.
+	* cni/ByteSpace.cxx: Rename cni/AddressSpace.java.
+	* jni/BlockSpace.cxx: Rename jni/RegisterSet.java.
+	* cni/BlockSpace.cxx: Rename cni/RegisterSet.java.
+	* ByteSpace.java: Rename AddressSpace.java.
+	* BlockSpace.java: Rename RegisterSet.java.
+	* TestRegisterSet.java: Update.
+	* TestAddressSpace.java: Update.
+
+2008-06-20  Andrew Cagney  <cagney@redhat.com>
+
+	* jni/AddressSpace.cxx: Simplify debug code.
+	* cni/AddressSpace.cxx: Ditto.
+	* jni/Ptrace.hxx (ptraceOpToString(int)): Declare.
+	* cni/Ptrace.hxx (ptraceOpToString(int)): Ditto.
+	* jni/Ptrace.cxx (ptraceOpToString): Rename op_as_string.
+	* cni/Ptrace.cxx (ptraceOpToString): Ditto.
+	
 2008-05-25  Andrew Cagney  <cagney@redhat.com>
 
 	* jni/AddressSpace.cxx: Use jbyteArrayElements.
diff --git a/frysk-sys/frysk/sys/ptrace/RegisterSet.java b/frysk-sys/frysk/sys/ptrace/RegisterSet.java
deleted file mode 100644
index 7fa028a..0000000
--- a/frysk-sys/frysk/sys/ptrace/RegisterSet.java
+++ /dev/null
@@ -1,87 +0,0 @@
-// This file is part of the program FRYSK.
-// 
-// Copyright 2005, 2006, 2007, 2008, Red Hat Inc.
-// 
-// FRYSK is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-// 
-// FRYSK is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with FRYSK; if not, write to the Free Software Foundation,
-// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-// 
-// In addition, as a special exception, Red Hat, Inc. gives You the
-// additional right to link the code of FRYSK with code not covered
-// under the GNU General Public License ("Non-GPL Code") and to
-// distribute linked combinations including the two, subject to the
-// limitations in this paragraph. Non-GPL Code permitted under this
-// exception must only link to the code of FRYSK through those well
-// defined interfaces identified in the file named EXCEPTION found in
-// the source code files (the "Approved Interfaces"). The files of
-// Non-GPL Code may instantiate templates or use macros or inline
-// functions from the Approved Interfaces without causing the
-// resulting work to be covered by the GNU General Public
-// License. Only Red Hat, Inc. may make changes or additions to the
-// list of Approved Interfaces. You must obey the GNU General Public
-// License in all respects for all of the FRYSK code and other code
-// used in conjunction with FRYSK except the Non-GPL Code covered by
-// this exception. If you modify this file, you may extend this
-// exception to your version of the file, but you are not obligated to
-// do so. If you do not wish to provide this exception without
-// modification, you must delete this exception statement from your
-// version and license this file solely under the GPL without
-// exception.
-
-package frysk.sys.ptrace;
-
-import frysk.rsl.Log;
-import frysk.sys.ProcessIdentifier;
-
-/**
- * A ptrace register set that is transfered to/from PID in bulk.
- */
-public class RegisterSet {
-    private static final Log fine = Log.fine(RegisterSet.class);
-
-    private final int ptLength;
-    private final int ptGet;
-    private final int ptSet;
-
-    RegisterSet(int ptLength, int ptGet, int ptSet) {
-	this.ptLength = ptLength;
-	this.ptGet = ptGet;
-	this.ptSet = ptSet;
-    }
-
-    /**
-     * Return the size of the register set in bytes.
-     */
-    public int length() {
-	return ptLength;
-    }
-
-    /**
-     * Fetch PID's register set into DATA.
-     */
-    public void transfer(ProcessIdentifier pid, byte[] data,
-			 boolean write) {
-	fine.log(this, "transfer", pid, write ? "write ..." : "read ...");
-	transfer(write ? ptSet : ptGet, pid.intValue(), data, ptLength);
-    }
-
-    private static native void transfer(int op, int pid, byte[] data,
-					int length);
-
-    private static native RegisterSet regs();
-    private static native RegisterSet fpregs();
-    private static native RegisterSet fpxregs();
-
-    public static final RegisterSet REGS = regs();
-    public static final RegisterSet FPREGS = fpregs();
-    public static final RegisterSet FPXREGS = fpxregs();
-}
diff --git a/frysk-sys/frysk/sys/ptrace/TestAddressSpace.java b/frysk-sys/frysk/sys/ptrace/TestAddressSpace.java
index 3eea99e..05c9cb9 100644
--- a/frysk-sys/frysk/sys/ptrace/TestAddressSpace.java
+++ b/frysk-sys/frysk/sys/ptrace/TestAddressSpace.java
@@ -59,7 +59,7 @@ public class TestAddressSpace extends TestCase {
     }
 
     private void verifyBytes(String what, ProcessIdentifier pid,
-			     AddressSpace space,
+			     ByteSpace space,
 			     byte[] bytes, long addr) {
 	for (int i = 0; i < bytes.length; i++) {
 	    assertEquals(what + " " + i + " at " + addr + " in " + space,
@@ -68,34 +68,34 @@ public class TestAddressSpace extends TestCase {
 	}
     }
 
-    private void verifyPeek(String what, AddressSpace space,
+    private void verifyPeek(String what, ByteSpace space,
 			    byte[] bytes, long addr) {
 	verifyBytes(what, ForkFactory.attachedDaemon(), space, bytes, addr);
     }
     public void testTextValPeek() {
-	verifyPeek("TextVal", AddressSpace.TEXT,
+	verifyPeek("TextVal", ByteSpace.TEXT,
 		   LocalMemory.getDataBytes(),
 		   LocalMemory.getDataAddr());
     }
     public void testDataValPeek() {
-	verifyPeek("DataVal", AddressSpace.DATA,
+	verifyPeek("DataVal", ByteSpace.DATA,
 		   LocalMemory.getDataBytes(),
 		   LocalMemory.getDataAddr());
     }
     public void testTextFuncPeek() {
-	verifyPeek("TextFunc", AddressSpace.TEXT,
+	verifyPeek("TextFunc", ByteSpace.TEXT,
 		   LocalMemory.getCodeBytes(),
 		   LocalMemory.getCodeAddr());
     }
     public void testDataFuncPeek() {
-	verifyPeek("DataFunc", AddressSpace.DATA,
+	verifyPeek("DataFunc", ByteSpace.DATA,
 		   LocalMemory.getCodeBytes(),
 		   LocalMemory.getCodeAddr());
     }
     public void testDataStackPeek() {
 	LocalMemory.constructStack(new StackBuilder() {
 		public void stack(long addr, byte[] bytes) {
-		    verifyPeek("DataStack", AddressSpace.DATA,
+		    verifyPeek("DataStack", ByteSpace.DATA,
 			       bytes, addr);
 		}
 	    });
@@ -103,13 +103,13 @@ public class TestAddressSpace extends TestCase {
     public void testTextStackPeek() {
 	LocalMemory.constructStack(new StackBuilder() {
 		public void stack(long addr, byte[] bytes) {
-		    verifyPeek("DataStack", AddressSpace.TEXT,
+		    verifyPeek("DataStack", ByteSpace.TEXT,
 			       bytes, addr);
 		}
 	    });
     }
 
-    public void verifyPoke(String what, AddressSpace space,
+    public void verifyPoke(String what, ByteSpace space,
 			   byte[] bytes, long addr) {
 	ProcessIdentifier pid = ForkFactory.attachedDaemon();
 	for (byte i = 4; i < 12; i++) {
@@ -119,29 +119,29 @@ public class TestAddressSpace extends TestCase {
 	}
     }
     public void testTextValPoke() {
-	verifyPoke("TextVal", AddressSpace.TEXT,
+	verifyPoke("TextVal", ByteSpace.TEXT,
 		   LocalMemory.getDataBytes(),
 		   LocalMemory.getDataAddr());
     }
     public void testDataValPoke() {
-	verifyPoke("DataVal", AddressSpace.DATA,
+	verifyPoke("DataVal", ByteSpace.DATA,
 		   LocalMemory.getDataBytes(),
 		   LocalMemory.getDataAddr());
     }
     public void testTextFuncPoke() {
-	verifyPoke("TextFunc", AddressSpace.TEXT,
+	verifyPoke("TextFunc", ByteSpace.TEXT,
 		   LocalMemory.getCodeBytes(),
 		   LocalMemory.getCodeAddr());
     }
     public void testDataFuncPoke() {
-	verifyPoke("DataFunc", AddressSpace.DATA,
+	verifyPoke("DataFunc", ByteSpace.DATA,
 		   LocalMemory.getCodeBytes(),
 		   LocalMemory.getCodeAddr());
     }
     public void testDataStackPoke() {
 	LocalMemory.constructStack(new StackBuilder() {
 		public void stack(long addr, byte[] bytes) {
-		    verifyPoke("DataStack", AddressSpace.DATA,
+		    verifyPoke("DataStack", ByteSpace.DATA,
 			       bytes, addr);
 		}
 	    });
@@ -149,13 +149,13 @@ public class TestAddressSpace extends TestCase {
     public void testTextStackPoke() {
 	LocalMemory.constructStack(new StackBuilder() {
 		public void stack(long addr, byte[] bytes) {
-		    verifyPoke("DataStack", AddressSpace.TEXT,
+		    verifyPoke("DataStack", ByteSpace.TEXT,
 			       bytes, addr);
 		}
 	    });
     }
 
-    private void verifyPeekBytes(String why, AddressSpace space,
+    private void verifyPeekBytes(String why, ByteSpace space,
 				 byte[] startBytes, long startAddr) {
 	ProcessIdentifier pid = ForkFactory.attachedDaemon();
 	byte[] pidBytes = new byte[startBytes.length];
@@ -183,29 +183,29 @@ public class TestAddressSpace extends TestCase {
 	}
     }
     public void testTextValPeekBytes() {
-	verifyPeekBytes ("TextVal", AddressSpace.TEXT,
+	verifyPeekBytes ("TextVal", ByteSpace.TEXT,
 			 LocalMemory.getDataBytes(),
 			 LocalMemory.getDataAddr());
     }
     public void testDataValPeekBytes() {
-	verifyPeekBytes ("DataVal", AddressSpace.DATA,
+	verifyPeekBytes ("DataVal", ByteSpace.DATA,
 			 LocalMemory.getDataBytes(),
 			 LocalMemory.getDataAddr());
     }
     public void testTextFuncPeekBytes() {
-	verifyPeekBytes("TextFunc", AddressSpace.TEXT,
+	verifyPeekBytes("TextFunc", ByteSpace.TEXT,
 			LocalMemory.getCodeBytes(),
 			LocalMemory.getCodeAddr());
     }
     public void testDataFuncPeekBytes() {
-	verifyPeekBytes("DataFunc", AddressSpace.DATA,
+	verifyPeekBytes("DataFunc", ByteSpace.DATA,
 			LocalMemory.getCodeBytes(),
 			LocalMemory.getCodeAddr());
     }
     public void testDataStackPeekBytes() {
 	LocalMemory.constructStack(new StackBuilder() {
 		public void stack(long addr, byte[] bytes) {
-		    verifyPeekBytes("DataStack", AddressSpace.DATA,
+		    verifyPeekBytes("DataStack", ByteSpace.DATA,
 				    bytes, addr);
 		}
 	    });
@@ -213,13 +213,13 @@ public class TestAddressSpace extends TestCase {
     public void testTextStackPeekBytes() {
 	LocalMemory.constructStack(new StackBuilder() {
 		public void stack(long addr, byte[] bytes) {
-		    verifyPeekBytes("DataStack", AddressSpace.TEXT,
+		    verifyPeekBytes("DataStack", ByteSpace.TEXT,
 				    bytes, addr);
 		}
 	    });
     }
 
-    private void verifyPokeBytes(String why, AddressSpace space,
+    private void verifyPokeBytes(String why, ByteSpace space,
 				 byte[] startBytes, long startAddr) {
 	ProcessIdentifier pid = ForkFactory.attachedDaemon();
 	byte[] newBytes = new byte[startBytes.length];
@@ -256,29 +256,29 @@ public class TestAddressSpace extends TestCase {
 	}
     }
     public void testTextValPokeBytes() {
-	verifyPokeBytes("TextVal", AddressSpace.TEXT,
+	verifyPokeBytes("TextVal", ByteSpace.TEXT,
 			LocalMemory.getDataBytes(),
 			LocalMemory.getDataAddr());
     }
     public void testDataValPokeBytes() {
-	verifyPokeBytes("DataVal", AddressSpace.DATA,
+	verifyPokeBytes("DataVal", ByteSpace.DATA,
 			LocalMemory.getDataBytes(),
 			LocalMemory.getDataAddr());
     }
     public void testTextFuncPokeBytes() {
-	verifyPokeBytes("TextFunc", AddressSpace.TEXT,
+	verifyPokeBytes("TextFunc", ByteSpace.TEXT,
 			LocalMemory.getCodeBytes(),
 			LocalMemory.getCodeAddr());
     }
     public void testDataFuncPokeBytes() {
-	verifyPokeBytes("DataFunc", AddressSpace.DATA,
+	verifyPokeBytes("DataFunc", ByteSpace.DATA,
 			LocalMemory.getCodeBytes(),
 			LocalMemory.getCodeAddr());
     }
     public void testDataStackPokeBytes() {
 	LocalMemory.constructStack(new StackBuilder() {
 		public void stack(long addr, byte[] bytes) {
-		    verifyPokeBytes("DataStack", AddressSpace.DATA,
+		    verifyPokeBytes("DataStack", ByteSpace.DATA,
 				    bytes, addr);
 		}
 	    });
@@ -286,7 +286,7 @@ public class TestAddressSpace extends TestCase {
     public void testTextStackPokeBytes() {
 	LocalMemory.constructStack(new StackBuilder() {
 		public void stack(long addr, byte[] bytes) {
-		    verifyPokeBytes("DataStack", AddressSpace.TEXT,
+		    verifyPokeBytes("DataStack", ByteSpace.TEXT,
 				    bytes, addr);
 		}
 	    });
@@ -297,7 +297,7 @@ public class TestAddressSpace extends TestCase {
 	ProcessIdentifier pid = ForkFactory.attachedDaemon();
 	boolean caught = false;
 	try {
-	    AddressSpace.DATA.transfer(pid, LocalMemory.getCodeAddr(),
+	    ByteSpace.DATA.transfer(pid, LocalMemory.getCodeAddr(),
 				       bytes, offset, length,
 				       false); // read
 	} catch (ArrayIndexOutOfBoundsException e) {
diff --git a/frysk-sys/frysk/sys/ptrace/TestRegisterSet.java b/frysk-sys/frysk/sys/ptrace/TestRegisterSet.java
index 4d6b3d4..df351bb 100644
--- a/frysk-sys/frysk/sys/ptrace/TestRegisterSet.java
+++ b/frysk-sys/frysk/sys/ptrace/TestRegisterSet.java
@@ -56,7 +56,7 @@ public class TestRegisterSet extends TestCase {
 	TearDownProcess.tearDown ();
     }
 
-    private void verifyTransfer(String what, RegisterSet regs) {
+    private void verifyTransfer(String what, BlockSpace regs) {
 	if (unsupported(what, regs == null))
 	    return;
 	ProcessIdentifier pid = ForkFactory.attachedDaemon();
@@ -71,12 +71,12 @@ public class TestRegisterSet extends TestCase {
     }
 
     public void testREGS() {
-	verifyTransfer("REGS", RegisterSet.REGS);
+	verifyTransfer("REGS", BlockSpace.REGS);
     }
     public void testFPREGS() {
-	verifyTransfer("FPREGS", RegisterSet.FPREGS);
+	verifyTransfer("FPREGS", BlockSpace.FPREGS);
     }
     public void testFPXREGS() {
-	verifyTransfer("FPXREGS", RegisterSet.FPXREGS);
+	verifyTransfer("FPXREGS", BlockSpace.FPXREGS);
     }
 }
diff --git a/frysk-sys/frysk/sys/ptrace/TestUtrace.java b/frysk-sys/frysk/sys/ptrace/TestUtrace.java
deleted file mode 100644
index e04c5be..0000000
--- a/frysk-sys/frysk/sys/ptrace/TestUtrace.java
+++ /dev/null
@@ -1,156 +0,0 @@
-// This file is part of the program FRYSK.
-//
-// Copyright 2005, 2007, 2008, Red Hat Inc.
-//
-// FRYSK is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// FRYSK is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with FRYSK; if not, write to the Free Software Foundation,
-// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-// 
-// In addition, as a special exception, Red Hat, Inc. gives You the
-// additional right to link the code of FRYSK with code not covered
-// under the GNU General Public License ("Non-GPL Code") and to
-// distribute linked combinations including the two, subject to the
-// limitations in this paragraph. Non-GPL Code permitted under this
-// exception must only link to the code of FRYSK through those well
-// defined interfaces identified in the file named EXCEPTION found in
-// the source code files (the "Approved Interfaces"). The files of
-// Non-GPL Code may instantiate templates or use macros or inline
-// functions from the Approved Interfaces without causing the
-// resulting work to be covered by the GNU General Public
-// License. Only Red Hat, Inc. may make changes or additions to the
-// list of Approved Interfaces. You must obey the GNU General Public
-// License in all respects for all of the FRYSK code and other code
-// used in conjunction with FRYSK except the Non-GPL Code covered by
-// this exception. If you modify this file, you may extend this
-// exception to your version of the file, but you are not obligated to
-// do so. If you do not wish to provide this exception without
-// modification, you must delete this exception statement from your
-// version and license this file solely under the GPL without
-// exception.
-
-package frysk.sys.ptrace;
-
-import frysk.sys.ProcessIdentifier;
-import frysk.junit.TestCase;
-import frysk.testbed.TearDownProcess;
-import frysk.sys.Fork;
-//import frysk.sys.Itimer;
-//import frysk.sys.Execute;
-//import frysk.sys.Errno;
-//import frysk.sys.DaemonFactory;
-//import frysk.sys.Wait;
-//import frysk.sys.Signal;
-//import frysk.sys.UnhandledWaitBuilder;
-
-/**
- * Check the plumming of Ptrace.
- */
-
-public class TestUtrace extends TestCase {
-    /**
-     * Rip down everything related to PID.
-     */
-    public void tearDown() {
-	TearDownProcess.tearDown ();
-    }
- 
-    public void testChildContinue() {
-	final ProcessIdentifier pid
-	    = Fork.utrace(new String[] {
-			      "/bin/true"
-			  });
-	System.err.println("pid = " + pid);
-	/***************** kill for now
-	assertTrue("pid", pid.intValue() > 0);
-	TearDownProcess.add(pid);
-	
-	// The initial stop.
-	Wait.waitOnce(pid, new UnhandledWaitBuilder() {
-		private final ProcessIdentifier id = pid;
-		protected void unhandled(String why) {
-		    fail (why);
-		}
-		public void stopped(ProcessIdentifier pid, Signal signal) {
-		    assertSame("stopped pid", id, pid);
-		    assertSame("stopped sig", Signal.TRAP, signal);
-		}
-	    });
-
-	Utrace.singleStep(pid, Signal.NONE);
-	Wait.waitOnce(pid, new UnhandledWaitBuilder() {
-		private final ProcessIdentifier id = pid;
-		protected void unhandled(String why) {
-		    fail (why);
-		}
-		public void stopped(ProcessIdentifier pid, Signal signal) {
-		    assertSame("stopped pid", id, pid);
-		    assertSame("stopped sig", Signal.TRAP, signal);
-		}
-	    });
-
-	Utrace.cont(pid, Signal.TERM);
-	Wait.waitOnce(pid, new UnhandledWaitBuilder() {
-		private final ProcessIdentifier id = pid;
-		protected void unhandled(String why) {
-		    fail (why);
-		}
-		public void terminated(ProcessIdentifier pid, Signal signal,
-				       int status, boolean coreDumped) {
-		    assertSame("terminated pid", id, pid);
-		    assertSame("terminated signal", Signal.TERM, signal);
-		    assertEquals("terminated status", -Signal.TERM.intValue(),
-				 status);
-		}
-	    });
-	********************/
-    }
-	
-    /**
-     * Check attach (to oneself).
-     */
-    /**********************  kill it for now
-    public void testAttachDetach() {
-	final ProcessIdentifier pid = DaemonFactory.create(new Execute() {
-		public void execute() {
-		    Itimer.sleep (TestCase.getTimeoutSeconds());
-		}
-	    });
-	TearDownProcess.add(pid);
-	assertTrue ("pid", pid.intValue() > 0);
-
-	Utrace.attach(pid);
-	Wait.waitOnce(pid, new UnhandledWaitBuilder() {
-		private final ProcessIdentifier id = pid;
-		protected void unhandled(String why) {
-		    fail (why);
-		}
-		public void stopped(ProcessIdentifier pid, Signal signal) {
-		    assertSame("stopped pid", id, pid);
-		    assertSame("stopped sig", Signal.STOP, signal);
-		}
-	    });
-
-	Utrace.detach(pid, Signal.NONE);
-	Errno errno = null;
-	try {
-	    Wait.waitOnce(pid, new UnhandledWaitBuilder() {
-		    protected void unhandled(String why) {
-			fail (why);
-		    }
-		});
-	} catch (Errno e) {
-	    errno = e;
-	}
-	assertEquals("Errno", Errno.Echild.class, errno.getClass());
-    }
-    **********************************/
-}
diff --git a/frysk-sys/frysk/sys/ptrace/Utrace.java b/frysk-sys/frysk/sys/ptrace/Utrace.java
deleted file mode 100644
index 89efccf..0000000
--- a/frysk-sys/frysk/sys/ptrace/Utrace.java
+++ /dev/null
@@ -1,123 +0,0 @@
-// This file is part of the program FRYSK.
-// 
-// Copyright 2005, 2006, 2007, 2008, Red Hat Inc.
-// 
-// FRYSK is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-// 
-// FRYSK is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with FRYSK; if not, write to the Free Software Foundation,
-// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-// 
-// In addition, as a special exception, Red Hat, Inc. gives You the
-// additional right to link the code of FRYSK with code not covered
-// under the GNU General Public License ("Non-GPL Code") and to
-// distribute linked combinations including the two, subject to the
-// limitations in this paragraph. Non-GPL Code permitted under this
-// exception must only link to the code of FRYSK through those well
-// defined interfaces identified in the file named EXCEPTION found in
-// the source code files (the "Approved Interfaces"). The files of
-// Non-GPL Code may instantiate templates or use macros or inline
-// functions from the Approved Interfaces without causing the
-// resulting work to be covered by the GNU General Public
-// License. Only Red Hat, Inc. may make changes or additions to the
-// list of Approved Interfaces. You must obey the GNU General Public
-// License in all respects for all of the FRYSK code and other code
-// used in conjunction with FRYSK except the Non-GPL Code covered by
-// this exception. If you modify this file, you may extend this
-// exception to your version of the file, but you are not obligated to
-// do so. If you do not wish to provide this exception without
-// modification, you must delete this exception statement from your
-// version and license this file solely under the GPL without
-// exception.
-
-package frysk.sys.ptrace;
-
-import frysk.rsl.Log;
-import frysk.sys.ProcessIdentifier;
-import frysk.sys.Signal;
-
-/**
- * Trace a process.
- */
-
-public class Utrace {
-    private static final Log fine = Log.fine(Utrace.class);
-
-    /**
-     * Attach to the process specified by PID.
-     */
-    public static void attach(ProcessIdentifier pid) {
-	fine.log("attach", pid);
-	attach(pid.intValue());
-    }
-    private static native void attach(int pid);
-
-    /**
-     * Detach from the process specified by PID.
-     */
-    public static void detach(ProcessIdentifier pid, Signal signal) {
-	fine.log("detach", pid, "signal", signal);
-	detach(pid.intValue(), signal.intValue());
-    }
-    private static native void detach(int pid, int sig);
-
-    /**
-     * Single-step (instruction step) the process specified by PID, if
-     * SIG is non-zero, deliver the signal.
-     */
-    public static void singleStep(ProcessIdentifier pid, Signal signal) {
-	fine.log("signleStep", pid, "signal", signal);
-	singleStep(pid.intValue(), signal.intValue());
-    }
-    private static native void singleStep(int pid, int sig);
-
-    /**
-     * Continue the process specified by PID, if SIG is non-zero,
-     * deliver the signal.
-     */
-    public static void cont(ProcessIdentifier pid, Signal signal) {
-	fine.log("cont", pid, "signal", signal);
-	cont(pid.intValue(), signal.intValue());
-    }
-    private static native void cont(int pid, int signal);
-
-    /**
-     * Continue the process specified by PID, stopping when there is a
-     * system-call; if SIG is non-zero deliver the signal.
-     */
-    public static void sysCall(ProcessIdentifier pid, Signal signal) {
-	fine.log("sysCall", pid, "signal", signal);
-	sysCall(pid.intValue(), signal.intValue());
-    }
-    private static native void sysCall(int pid, int sig);
-
-    /**
-     * Fetch the auxilary information associated with PID's last WAIT
-     * event.
-     */ 
-    public static long getEventMsg(ProcessIdentifier pid) {
-	fine.log("getEventMsg", pid, "...");
-	long ret = getEventMsg(pid.intValue());
-	fine.log("... getEventMsg", pid, "returns", ret);
-	return ret;
-    }
-    private static native long getEventMsg(int pid);
-
-    /**
-     * Set PID's trace options.  OPTIONS is formed by or'ing the
-     * values returned by the option* methods below.
-     */
-    public static void setOptions(ProcessIdentifier pid, long options) {
-	fine.log("setOptions", pid, "options", options);
-	setOptions(pid.intValue(), options);
-    }
-    private static native void setOptions (int pid, long options);
-
-}
diff --git a/frysk-sys/frysk/sys/ptrace/cni/AddressSpace.cxx b/frysk-sys/frysk/sys/ptrace/cni/AddressSpace.cxx
deleted file mode 100644
index 232e1f3..0000000
--- a/frysk-sys/frysk/sys/ptrace/cni/AddressSpace.cxx
+++ /dev/null
@@ -1,189 +0,0 @@
-// This file is part of the program FRYSK.
-//
-// Copyright 2005, 2006, 2007, 2008, Red Hat Inc.
-//
-// FRYSK is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// FRYSK is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with FRYSK; if not, write to the Free Software Foundation,
-// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-// 
-// In addition, as a special exception, Red Hat, Inc. gives You the
-// additional right to link the code of FRYSK with code not covered
-// under the GNU General Public License ("Non-GPL Code") and to
-// distribute linked combinations including the two, subject to the
-// limitations in this paragraph. Non-GPL Code permitted under this
-// exception must only link to the code of FRYSK through those well
-// defined interfaces identified in the file named EXCEPTION found in
-// the source code files (the "Approved Interfaces"). The files of
-// Non-GPL Code may instantiate templates or use macros or inline
-// functions from the Approved Interfaces without causing the
-// resulting work to be covered by the GNU General Public
-// License. Only Red Hat, Inc. may make changes or additions to the
-// list of Approved Interfaces. You must obey the GNU General Public
-// License in all respects for all of the FRYSK code and other code
-// used in conjunction with FRYSK except the Non-GPL Code covered by
-// this exception. If you modify this file, you may extend this
-// exception to your version of the file, but you are not obligated to
-// do so. If you do not wish to provide this exception without
-// modification, you must delete this exception statement from your
-// version and license this file solely under the GPL without
-// exception.
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include "linux.ptrace.h"
-
-#include <gcj/cni.h>
-
-#include <java/lang/System.h>
-#include <java/lang/Thread.h>
-#include <java/lang/ArrayIndexOutOfBoundsException.h>
-
-#include "frysk/sys/ptrace/cni/Ptrace.hxx"
-#include "frysk/sys/cni/Errno.hxx"
-#include "frysk/sys/ptrace/AddressSpace.h"
-
-union word {
-  long l;
-  uint8_t b[sizeof (long)];
-};
-
-jint
-frysk::sys::ptrace::AddressSpace::peek(jint pid, jlong addr) {
-  union word w;
-  long paddr = addr & -sizeof(long);
-#if DEBUG
-  fprintf(stderr, "peek 0x%lx paddr 0x%lx", (long)addr, paddr);
-#endif
-  w.l = ptraceOp(ptPeek, pid, (void*)paddr, 0);
-#if DEBUG
-  fprintf(stderr, " word 0x%lx", w.l);
-#endif
-  int index = addr & (sizeof(long) - 1);
-#if DEBUG
-  fprintf(stderr, " index %d", index);
-#endif
-  uint8_t byte = w.b[index];
-#if DEBUG
-  fprintf(stderr, " byte %d/0x%x\n", byte, byte);
-#endif
-  return byte;
-}
-
-void
-frysk::sys::ptrace::AddressSpace::poke(jint pid, jlong addr, jint data) {
-  // Implement read-modify-write
-  union word w;
-#if DEBUG
-  fprintf(stderr, "poke 0x%x", (int)(data & 0xff));
-#endif
-  long paddr = addr & -sizeof(long);
-#if DEBUG
-  fprintf(stderr, " addr 0x%lx paddr 0x%lx", (long)addr, paddr);
-#endif
-  w.l = ptraceOp(ptPeek, pid, (void*)paddr, 0);
-#if DEBUG
-  fprintf(stderr, " word 0x%lx", w.l);
-#endif
-  int index = addr & (sizeof(long) - 1);
-#if DEBUG
-  fprintf (stderr, " index %d", index);
-#endif
-  w.b[index] = data;
-#if DEBUG
-  fprintf(stderr, " word 0x%lx\n", w.l);
-#endif
-  ptraceOp(ptPoke, pid, (void*)(addr & -sizeof(long)), w.l);
-}
-
-void
-frysk::sys::ptrace::AddressSpace::transfer(jint op, jint pid, jlong addr,
-					   jbyteArray bytes, jint offset,
-					   jint length) {
-  verifyBounds(bytes, offset, length);
-  // Somewhat more clueful implementation
-  for (jlong i = 0; i < length;) {
-#if DEBUG
-    fprintf(stderr,
-	     "transfer pid %d addr 0x%lx length %d offset %d op %d (%s)",
-	     (int)pid, (long)addr, (int)length, (int)offset,
-	     (int)op, op_as_string(op));
-#endif
-
-    union word w;
-    unsigned long waddr = addr & -sizeof(long);
-    unsigned long woff = (addr - waddr);
-    unsigned long remaining = length - i;
-    unsigned long wend;
-    if (remaining > sizeof(long) - woff)
-      wend = sizeof(long);
-    else
-      wend = woff + remaining;
-    long wlen = wend - woff;
-
-#if DEBUG
-    fprintf(stderr,
-	     " i %ld waddr 0x%lx woff %lu wend %lu remaining %lu wlen %lu",
-	     (long)i, waddr, woff, wend, remaining, wlen);
-#endif
-
-    // Either a peek; or a partial write requiring read/modify/write.
-    if (op == ptPeek || woff != 0 || wend != sizeof(long)) {
-	w.l = ptraceOp(ptPeek, pid, (void*)waddr, 0);
-#if DEBUG
-	fprintf(stderr, " peek 0x%lx", w.l);
-#endif
-      }
-
-    // extract or modify
-    if (op == ptPeek)
-      memcpy(offset + i + elements(bytes), &w.b[woff], wlen);
-    else {
-      memcpy(&w.b[woff], offset + i + elements(bytes), wlen);
-#if DEBUG
-      fprintf(stderr, " poke 0x%lx", w.l);
-#endif
-      w.l = ptraceOp(ptPoke, pid, (void*)waddr, w.l);
-    }
-
-    i += wlen;
-    addr += wlen;
-
-#if DEBUG
-    fprintf(stderr, "\n");
-#endif
-  }
-}
-
-frysk::sys::ptrace::AddressSpace*
-frysk::sys::ptrace::AddressSpace::text() {
-  return new frysk::sys::ptrace::AddressSpace(-1UL,
-					      JvNewStringUTF("TEXT"),
-					      PTRACE_PEEKTEXT,
-					      PTRACE_POKETEXT);
-}
-
-frysk::sys::ptrace::AddressSpace*
-frysk::sys::ptrace::AddressSpace::data() {
-  return new frysk::sys::ptrace::AddressSpace(-1UL,
-					      JvNewStringUTF("DATA"),
-					      PTRACE_PEEKDATA,
-					      PTRACE_POKEDATA);
-}
-
-frysk::sys::ptrace::AddressSpace*
-frysk::sys::ptrace::AddressSpace::usr() {
-  return new frysk::sys::ptrace::AddressSpace(-1UL,
-					      JvNewStringUTF("USR"),
-					      PTRACE_PEEKUSR,
-					      PTRACE_POKEUSR);
-}
diff --git a/frysk-sys/frysk/sys/ptrace/cni/BlockSpace.cxx b/frysk-sys/frysk/sys/ptrace/cni/BlockSpace.cxx
new file mode 100644
index 0000000..d7abd59
--- /dev/null
+++ b/frysk-sys/frysk/sys/ptrace/cni/BlockSpace.cxx
@@ -0,0 +1,89 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2005, 2006, 2007, 2008, Red Hat Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include "linux.ptrace.h"
+#include <sys/user.h>
+
+#include <gcj/cni.h>
+
+#include "frysk/sys/cni/Errno.hxx"
+#include "frysk/sys/ptrace/cni/Ptrace.hxx"
+#include "frysk/sys/ptrace/BlockSpace.h"
+
+void
+frysk::sys::ptrace::BlockSpace::transfer(jint op, jint pid, jbyteArray data,
+					 jint length) {
+  verifyBounds(data, 0, length);
+  ptraceOp(op, pid, NULL, (long) elements(data));
+}
+
+frysk::sys::ptrace::BlockSpace*
+frysk::sys::ptrace::BlockSpace::regs() {
+#if defined(__i386__)|| defined(__x86_64__)
+  return new frysk::sys::ptrace::BlockSpace(sizeof(user_regs_struct),
+					    PTRACE_GETREGS, PTRACE_SETREGS);
+#else
+  return NULL;
+#endif
+}
+
+frysk::sys::ptrace::BlockSpace*
+frysk::sys::ptrace::BlockSpace::fpregs() {
+#if defined(__i386__)|| defined(__x86_64__)
+  return new frysk::sys::ptrace::BlockSpace(sizeof(user_fpregs_struct),
+					    PTRACE_GETFPREGS,
+					    PTRACE_SETFPREGS);
+#else
+  return NULL;
+#endif
+}
+
+frysk::sys::ptrace::BlockSpace*
+frysk::sys::ptrace::BlockSpace::fpxregs() {
+#if defined(__i386__)
+  return new frysk::sys::ptrace::BlockSpace(sizeof(user_fpxregs_struct),
+					    PTRACE_GETFPXREGS,
+					    PTRACE_SETFPXREGS);
+#else
+  return NULL;
+#endif
+}
diff --git a/frysk-sys/frysk/sys/ptrace/cni/ByteSpace.cxx b/frysk-sys/frysk/sys/ptrace/cni/ByteSpace.cxx
new file mode 100644
index 0000000..5911736
--- /dev/null
+++ b/frysk-sys/frysk/sys/ptrace/cni/ByteSpace.cxx
@@ -0,0 +1,177 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2005, 2006, 2007, 2008, Red Hat Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+#define DEBUG 0
+
+#include <stdio.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include "linux.ptrace.h"
+
+#include <gcj/cni.h>
+
+#include <java/lang/System.h>
+#include <java/lang/Thread.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+
+#include "frysk/sys/ptrace/cni/Ptrace.hxx"
+#include "frysk/sys/cni/Errno.hxx"
+#include "frysk/sys/ptrace/ByteSpace.h"
+
+union word {
+  long l;
+  uint8_t b[sizeof (long)];
+};
+
+jint
+frysk::sys::ptrace::ByteSpace::peek(jint pid, jlong addr) {
+  union word w;
+  long paddr = addr & -sizeof(long);
+  if (DEBUG)
+    fprintf(stderr, "peek 0x%lx paddr 0x%lx", (long)addr, paddr);
+  w.l = ptraceOp(ptPeek, pid, (void*)paddr, 0);
+  if (DEBUG)
+    fprintf(stderr, " word 0x%lx", w.l);
+  int index = addr & (sizeof(long) - 1);
+  if (DEBUG)
+    fprintf(stderr, " index %d", index);
+  uint8_t byte = w.b[index];
+  if (DEBUG)
+    fprintf(stderr, " byte %d/0x%x\n", byte, byte);
+  return byte;
+}
+
+void
+frysk::sys::ptrace::ByteSpace::poke(jint pid, jlong addr, jint data) {
+  // Implement read-modify-write
+  union word w;
+  if (DEBUG)
+    fprintf(stderr, "poke 0x%x", (int)(data & 0xff));
+  long paddr = addr & -sizeof(long);
+  if (DEBUG)
+    fprintf(stderr, " addr 0x%lx paddr 0x%lx", (long)addr, paddr);
+  w.l = ptraceOp(ptPeek, pid, (void*)paddr, 0);
+  if (DEBUG)
+    fprintf(stderr, " word 0x%lx", w.l);
+  int index = addr & (sizeof(long) - 1);
+  if (DEBUG)
+    fprintf (stderr, " index %d", index);
+  w.b[index] = data;
+  if (DEBUG)
+    fprintf(stderr, " word 0x%lx\n", w.l);
+  ptraceOp(ptPoke, pid, (void*)(addr & -sizeof(long)), w.l);
+}
+
+void
+frysk::sys::ptrace::ByteSpace::transfer(jint op, jint pid, jlong addr,
+					jbyteArray bytes, jint offset,
+					jint length) {
+  verifyBounds(bytes, offset, length);
+  // Somewhat more clueful implementation
+  for (jlong i = 0; i < length;) {
+    if (DEBUG)
+      fprintf(stderr,
+	      "transfer pid %d addr 0x%lx length %d offset %d op %d (%s) ...",
+	      (int)pid, (long)addr, (int)length, (int)offset,
+	      (int)op, ptraceOpToString(op));
+    union word w;
+    unsigned long waddr = addr & -sizeof(long);
+    unsigned long woff = (addr - waddr);
+    unsigned long remaining = length - i;
+    unsigned long wend;
+    if (remaining > sizeof(long) - woff)
+      wend = sizeof(long);
+    else
+      wend = woff + remaining;
+    long wlen = wend - woff;
+
+    if (DEBUG)
+      fprintf(stderr,
+	      " i %ld waddr 0x%lx woff %lu wend %lu remaining %lu wlen %lu ...",
+	      (long)i, waddr, woff, wend, remaining, wlen);
+
+    // Either a peek; or a partial write requiring read/modify/write.
+    if (op == ptPeek || woff != 0 || wend != sizeof(long)) {
+      w.l = ptraceOp(ptPeek, pid, (void*)waddr, 0);
+      if (DEBUG)
+	fprintf(stderr, " peek 0x%lx ...", w.l);
+    }
+
+    // extract or modify
+    if (op == ptPeek)
+      memcpy(offset + i + elements(bytes), &w.b[woff], wlen);
+    else {
+      memcpy(&w.b[woff], offset + i + elements(bytes), wlen);
+      if (DEBUG)
+	fprintf(stderr, " poke 0x%lx ...", w.l);
+      w.l = ptraceOp(ptPoke, pid, (void*)waddr, w.l);
+    }
+
+    i += wlen;
+    addr += wlen;
+
+    if (DEBUG)
+      fprintf(stderr, "\n");
+  }
+}
+
+frysk::sys::ptrace::ByteSpace*
+frysk::sys::ptrace::ByteSpace::text() {
+  return new frysk::sys::ptrace::ByteSpace(-1UL,
+					   JvNewStringUTF("TEXT"),
+					   PTRACE_PEEKTEXT,
+					   PTRACE_POKETEXT);
+}
+
+frysk::sys::ptrace::ByteSpace*
+frysk::sys::ptrace::ByteSpace::data() {
+  return new frysk::sys::ptrace::ByteSpace(-1UL,
+					   JvNewStringUTF("DATA"),
+					   PTRACE_PEEKDATA,
+					   PTRACE_POKEDATA);
+}
+
+frysk::sys::ptrace::ByteSpace*
+frysk::sys::ptrace::ByteSpace::usr() {
+  return new frysk::sys::ptrace::ByteSpace(-1UL,
+					   JvNewStringUTF("USR"),
+					   PTRACE_PEEKUSR,
+					   PTRACE_POKEUSR);
+}
diff --git a/frysk-sys/frysk/sys/ptrace/cni/Ptrace.cxx b/frysk-sys/frysk/sys/ptrace/cni/Ptrace.cxx
index 4aa12eb..3375efd 100644
--- a/frysk-sys/frysk/sys/ptrace/cni/Ptrace.cxx
+++ b/frysk-sys/frysk/sys/ptrace/cni/Ptrace.cxx
@@ -37,6 +37,10 @@
 // version and license this file solely under the GPL without
 // exception.
 
+#define DEBUG 0
+
+#include <stdio.h>
+#include <string.h>
 #include <errno.h>
 #include <sys/ptrace.h>
 #include "linux.ptrace.h"
@@ -47,8 +51,8 @@
 #include "frysk/sys/ptrace/Ptrace.h"
 #include "frysk/sys/ptrace/cni/Ptrace.hxx"
 
-static const char*
-op_as_string(int op) {
+const char*
+ptraceOpToString(int op) {
   switch(op) {
 #define OP(NAME) case NAME: return #NAME
     OP(PTRACE_ATTACH);
@@ -82,10 +86,14 @@ op_as_string(int op) {
 long
 ptraceOp(int op, int pid, void* addr, long data) {
   errno = 0;
-  long result = ::ptrace ((enum __ptrace_request) op, pid, addr, data);
-  if (errno != 0)
+  long result = ::ptrace((enum __ptrace_request) op, pid, addr, data);
+  if (errno != 0) {
+    int err = errno;
+    if (DEBUG)
+      fprintf(stderr, "throwing %s\n", strerror(err));
     throwErrno(errno, "ptrace", "op 0x%x (%s), pid %d, addr 0x%lx, data 0x%lx",
-	       op, op_as_string(op), pid, (long)addr, data);
+	       op, ptraceOpToString(op), pid, (long)addr, data);
+  }
   return result;
 }
 
diff --git a/frysk-sys/frysk/sys/ptrace/cni/Ptrace.hxx b/frysk-sys/frysk/sys/ptrace/cni/Ptrace.hxx
index 78bda4d..1da0f03 100644
--- a/frysk-sys/frysk/sys/ptrace/cni/Ptrace.hxx
+++ b/frysk-sys/frysk/sys/ptrace/cni/Ptrace.hxx
@@ -38,3 +38,4 @@
 // exception.
 
 extern long ptraceOp(int, int, void*, long);
+extern const char *ptraceOpToString(int op);
diff --git a/frysk-sys/frysk/sys/ptrace/cni/RegisterSet.cxx b/frysk-sys/frysk/sys/ptrace/cni/RegisterSet.cxx
deleted file mode 100644
index 2c3a861..0000000
--- a/frysk-sys/frysk/sys/ptrace/cni/RegisterSet.cxx
+++ /dev/null
@@ -1,89 +0,0 @@
-// This file is part of the program FRYSK.
-//
-// Copyright 2005, 2006, 2007, 2008, Red Hat Inc.
-//
-// FRYSK is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// FRYSK is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with FRYSK; if not, write to the Free Software Foundation,
-// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-// 
-// In addition, as a special exception, Red Hat, Inc. gives You the
-// additional right to link the code of FRYSK with code not covered
-// under the GNU General Public License ("Non-GPL Code") and to
-// distribute linked combinations including the two, subject to the
-// limitations in this paragraph. Non-GPL Code permitted under this
-// exception must only link to the code of FRYSK through those well
-// defined interfaces identified in the file named EXCEPTION found in
-// the source code files (the "Approved Interfaces"). The files of
-// Non-GPL Code may instantiate templates or use macros or inline
-// functions from the Approved Interfaces without causing the
-// resulting work to be covered by the GNU General Public
-// License. Only Red Hat, Inc. may make changes or additions to the
-// list of Approved Interfaces. You must obey the GNU General Public
-// License in all respects for all of the FRYSK code and other code
-// used in conjunction with FRYSK except the Non-GPL Code covered by
-// this exception. If you modify this file, you may extend this
-// exception to your version of the file, but you are not obligated to
-// do so. If you do not wish to provide this exception without
-// modification, you must delete this exception statement from your
-// version and license this file solely under the GPL without
-// exception.
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include "linux.ptrace.h"
-#include <sys/user.h>
-
-#include <gcj/cni.h>
-
-#include "frysk/sys/cni/Errno.hxx"
-#include "frysk/sys/ptrace/cni/Ptrace.hxx"
-#include "frysk/sys/ptrace/RegisterSet.h"
-
-void
-frysk::sys::ptrace::RegisterSet::transfer(jint op, jint pid, jbyteArray data,
-					  jint length) {
-  verifyBounds(data, 0, length);
-  ptraceOp(op, pid, NULL, (long) elements(data));
-}
-
-frysk::sys::ptrace::RegisterSet*
-frysk::sys::ptrace::RegisterSet::regs() {
-#if defined(__i386__)|| defined(__x86_64__)
-  return new frysk::sys::ptrace::RegisterSet(sizeof(user_regs_struct),
-					     PTRACE_GETREGS, PTRACE_SETREGS);
-#else
-  return NULL;
-#endif
-}
-
-frysk::sys::ptrace::RegisterSet*
-frysk::sys::ptrace::RegisterSet::fpregs() {
-#if defined(__i386__)|| defined(__x86_64__)
-  return new frysk::sys::ptrace::RegisterSet(sizeof(user_fpregs_struct),
-					     PTRACE_GETFPREGS,
-					     PTRACE_SETFPREGS);
-#else
-  return NULL;
-#endif
-}
-
-frysk::sys::ptrace::RegisterSet*
-frysk::sys::ptrace::RegisterSet::fpxregs() {
-#if defined(__i386__)
-  return new frysk::sys::ptrace::RegisterSet(sizeof(user_fpxregs_struct),
-					     PTRACE_GETFPXREGS,
-					     PTRACE_SETFPXREGS);
-#else
-  return NULL;
-#endif
-}
diff --git a/frysk-sys/frysk/sys/ptrace/cni/Utrace.cxx b/frysk-sys/frysk/sys/ptrace/cni/Utrace.cxx
deleted file mode 100644
index cdc0ac7..0000000
--- a/frysk-sys/frysk/sys/ptrace/cni/Utrace.cxx
+++ /dev/null
@@ -1,91 +0,0 @@
-// This file is part of the program FRYSK.
-//
-// Copyright 2005, 2006, 2007, 2008, Red Hat Inc.
-//
-// FRYSK is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// FRYSK is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with FRYSK; if not, write to the Free Software Foundation,
-// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-// 
-// In addition, as a special exception, Red Hat, Inc. gives You the
-// additional right to link the code of FRYSK with code not covered
-// under the GNU General Public License ("Non-GPL Code") and to
-// distribute linked combinations including the two, subject to the
-// limitations in this paragraph. Non-GPL Code permitted under this
-// exception must only link to the code of FRYSK through those well
-// defined interfaces identified in the file named EXCEPTION found in
-// the source code files (the "Approved Interfaces"). The files of
-// Non-GPL Code may instantiate templates or use macros or inline
-// functions from the Approved Interfaces without causing the
-// resulting work to be covered by the GNU General Public
-// License. Only Red Hat, Inc. may make changes or additions to the
-// list of Approved Interfaces. You must obey the GNU General Public
-// License in all respects for all of the FRYSK code and other code
-// used in conjunction with FRYSK except the Non-GPL Code covered by
-// this exception. If you modify this file, you may extend this
-// exception to your version of the file, but you are not obligated to
-// do so. If you do not wish to provide this exception without
-// modification, you must delete this exception statement from your
-// version and license this file solely under the GPL without
-// exception.
-
-#include <errno.h>
-#include <stdio.h>
-#include <sys/ptrace.h>
-#include "linux.ptrace.h"
-
-#include <gcj/cni.h>
-
-#include "frysk/sys/cni/Errno.hxx"
-#include "frysk/sys/ptrace/Utrace.h"
-//#include "frysk/sys/ptrace/cni/Utrace.hxx"
-
-void
-frysk::sys::ptrace::Utrace::attach(jint pid) {
-  fprintf (stderr, "\n\n>>>>PTRACE_ATTACH via utrace\n\n");
-}
-
-void
-frysk::sys::ptrace::Utrace::detach(jint pid, jint sig) {
-  fprintf (stderr, "\n\n>>>>PTRACE_DETACH via utrace\n\n");
-} 
-
-void
-frysk::sys::ptrace::Utrace::singleStep(jint pid, jint sig) {
-  fprintf (stderr, "\n\n>>>>PTRACE_SINGLESTEP via utrace\n\n");
-} 
-
-void
-frysk::sys::ptrace::Utrace::cont(jint pid, jint sig) {
-  fprintf (stderr, "\n\n>>>>PTRACE_CONT via utrace\n\n");
-}
-
-void
-frysk::sys::ptrace::Utrace::sysCall(jint pid, jint sig) {
-  fprintf (stderr, "\n\n>>>>PTRACE_SYSCALL via utrace\n\n");
-}
-
-jlong
-frysk::sys::ptrace::Utrace::getEventMsg(jint pid) {
-  /* Note: PTRACE_GETEVENTMSG ends up calling the function
-     kernel/ptrace.c: ptrace_ptraceOp() and that uses put_user to store
-     child->ptrace_message write sizeof(ptrace_message) bytes into the
-     MESSAGE parameter.  include/linux/sched.h declares ptrace_message
-     as a long.  */
-  fprintf (stderr, "\n\n>>>> PTRACE_GETEVENTMSG via utrace\n\n");
-  return -1;
-}
-
-void
-frysk::sys::ptrace::Utrace::setOptions(jint pid, jlong options) {
-  fprintf (stderr, "\n\n>>>>PTRACE_SETOPTIONS via utrace\n");
-}
-
diff --git a/frysk-sys/frysk/sys/ptrace/jni/AddressSpace.cxx b/frysk-sys/frysk/sys/ptrace/jni/AddressSpace.cxx
deleted file mode 100644
index 598d8cc..0000000
--- a/frysk-sys/frysk/sys/ptrace/jni/AddressSpace.cxx
+++ /dev/null
@@ -1,193 +0,0 @@
-// This file is part of the program FRYSK.
-//
-// Copyright 2005, 2006, 2007, 2008, Red Hat Inc.
-//
-// FRYSK is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// FRYSK is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with FRYSK; if not, write to the Free Software Foundation,
-// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-// 
-// In addition, as a special exception, Red Hat, Inc. gives You the
-// additional right to link the code of FRYSK with code not covered
-// under the GNU General Public License ("Non-GPL Code") and to
-// distribute linked combinations including the two, subject to the
-// limitations in this paragraph. Non-GPL Code permitted under this
-// exception must only link to the code of FRYSK through those well
-// defined interfaces identified in the file named EXCEPTION found in
-// the source code files (the "Approved Interfaces"). The files of
-// Non-GPL Code may instantiate templates or use macros or inline
-// functions from the Approved Interfaces without causing the
-// resulting work to be covered by the GNU General Public
-// License. Only Red Hat, Inc. may make changes or additions to the
-// list of Approved Interfaces. You must obey the GNU General Public
-// License in all respects for all of the FRYSK code and other code
-// used in conjunction with FRYSK except the Non-GPL Code covered by
-// this exception. If you modify this file, you may extend this
-// exception to your version of the file, but you are not obligated to
-// do so. If you do not wish to provide this exception without
-// modification, you must delete this exception statement from your
-// version and license this file solely under the GPL without
-// exception.
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include "linux.ptrace.h"
-#include <string.h>
-
-#include "jni.hxx"
-#include "jnixx/bounds.hxx"
-#include "jnixx/elements.hxx"
-
-#include "frysk/sys/ptrace/jni/Ptrace.hxx"
-
-using namespace java::lang;
-
-union word {
-  long l;
-  uint8_t b[sizeof (long)];
-};
-
-jint
-frysk::sys::ptrace::AddressSpace::peek(::jnixx::env env, jint pid, jlong addr) {
-  union word w;
-  long paddr = addr & -sizeof(long);
-#if DEBUG
-  fprintf(stderr, "peek 0x%lx paddr 0x%lx", (long)addr, paddr);
-#endif
-  w.l = ptraceOp(env, GetPtPeek(env), pid, (void*)paddr, 0);
-#if DEBUG
-  fprintf(stderr, " word 0x%lx", w.l);
-#endif
-  int index = addr & (sizeof(long) - 1);
-#if DEBUG
-  fprintf(stderr, " index %d", index);
-#endif
-  uint8_t byte = w.b[index];
-#if DEBUG
-  fprintf(stderr, " byte %d/0x%x\n", byte, byte);
-#endif
-  return byte;
-}
-
-void
-frysk::sys::ptrace::AddressSpace::poke(::jnixx::env env, jint pid, jlong addr, jint data) {
-  // Implement read-modify-write
-  union word w;
-#if DEBUG
-  fprintf(stderr, "poke 0x%x", (int)(data & 0xff));
-#endif
-  long paddr = addr & -sizeof(long);
-#if DEBUG
-  fprintf(stderr, " addr 0x%lx paddr 0x%lx", (long)addr, paddr);
-#endif
-  w.l = ptraceOp(env, GetPtPeek(env), pid, (void*)paddr, 0);
-#if DEBUG
-  fprintf(stderr, " word 0x%lx", w.l);
-#endif
-  int index = addr & (sizeof(long) - 1);
-#if DEBUG
-  fprintf (stderr, " index %d", index);
-#endif
-  w.b[index] = data;
-#if DEBUG
-  fprintf(stderr, " word 0x%lx\n", w.l);
-#endif
-  ptraceOp(env, GetPtPoke(env), pid, (void*)(addr & -sizeof(long)), w.l);
-}
-
-void
-frysk::sys::ptrace::AddressSpace::transfer(::jnixx::env env,
-					   jint op, jint pid, jlong addr,
-					   ::jnixx::jbyteArray byteArray,
-					   jint offset, jint length) {
-  const int ptPeek = GetPtPeek(env);
-  const int ptPoke = GetPtPoke(env);
-  verifyBounds(env, byteArray, offset, length);
-  // Somewhat more clueful implementation
-  for (jlong i = 0; i < length;) {
-#if DEBUG
-    fprintf(stderr,
-	     "transfer pid %d addr 0x%lx length %d offset %d op %d (%s)",
-	     (int)pid, (long)addr, (int)length, (int)offset,
-	     (int)op, op_as_string(op));
-#endif
-
-    union word w;
-    unsigned long waddr = addr & -sizeof(long);
-    unsigned long woff = (addr - waddr);
-    unsigned long remaining = length - i;
-    unsigned long wend;
-    if (remaining > sizeof(long) - woff)
-      wend = sizeof(long);
-    else
-      wend = woff + remaining;
-    long wlen = wend - woff;
-
-#if DEBUG
-    fprintf(stderr,
-	     " i %ld waddr 0x%lx woff %lu wend %lu remaining %lu wlen %lu",
-	     (long)i, waddr, woff, wend, remaining, wlen);
-#endif
-
-    // Either a peek; or a partial write requiring read/modify/write.
-    if (op == ptPeek || woff != 0 || wend != sizeof(long)) {
-	w.l = ptraceOp(env, ptPeek, pid, (void*)waddr, 0);
-#if DEBUG
-	fprintf(stderr, " peek 0x%lx", w.l);
-#endif
-      }
-
-    // extract or modify
-    jbyteArrayElements bytes = jbyteArrayElements(env, byteArray);
-    if (op == ptPeek)
-      memcpy(offset + i + bytes.elements(), &w.b[woff], wlen);
-    else {
-      memcpy(&w.b[woff], offset + i + bytes.elements(), wlen);
-#if DEBUG
-      fprintf(stderr, " poke 0x%lx", w.l);
-#endif
-      w.l = ptraceOp(env, ptPoke, pid, (void*)waddr, w.l);
-    }
-    bytes.release();
-
-    i += wlen;
-    addr += wlen;
-
-#if DEBUG
-    fprintf(stderr, "\n");
-#endif
-  }
-}
-
-frysk::sys::ptrace::AddressSpace
-frysk::sys::ptrace::AddressSpace::text(::jnixx::env env) {
-  return frysk::sys::ptrace::AddressSpace::New(env, -1UL,
-					       String::NewStringUTF(env, "TEXT"),
-					       PTRACE_PEEKTEXT,
-					       PTRACE_POKETEXT);
-}
-
-frysk::sys::ptrace::AddressSpace
-frysk::sys::ptrace::AddressSpace::data(::jnixx::env env) {
-  return frysk::sys::ptrace::AddressSpace::New(env, -1UL,
-					       String::NewStringUTF(env, "DATA"),
-					       PTRACE_PEEKDATA,
-					       PTRACE_POKEDATA);
-}
-
-frysk::sys::ptrace::AddressSpace
-frysk::sys::ptrace::AddressSpace::usr(::jnixx::env env) {
-  return frysk::sys::ptrace::AddressSpace::New(env, -1UL,
-					       String::NewStringUTF(env, "USR"),
-					       PTRACE_PEEKUSR,
-					       PTRACE_POKEUSR);
-}
diff --git a/frysk-sys/frysk/sys/ptrace/jni/BlockSpace.cxx b/frysk-sys/frysk/sys/ptrace/jni/BlockSpace.cxx
new file mode 100644
index 0000000..00f54e8
--- /dev/null
+++ b/frysk-sys/frysk/sys/ptrace/jni/BlockSpace.cxx
@@ -0,0 +1,88 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2005, 2006, 2007, 2008, Red Hat Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include "linux.ptrace.h"
+#include <sys/user.h>
+
+#include "jni.hxx"
+
+#include "frysk/sys/ptrace/jni/Ptrace.hxx"
+#include "jnixx/elements.hxx"
+#include "jnixx/bounds.hxx"
+
+void
+frysk::sys::ptrace::BlockSpace::transfer(::jnixx::env env,
+					 jint op, jint pid,
+					 ::jnixx::jbyteArray data,
+					 jint length) {
+  verifyBounds(env, data, length);
+  jbyteArrayElements bytes = jbyteArrayElements(env, data);
+  ptraceOp(env, op, pid, NULL, (long) bytes.elements());
+  bytes.release();
+}
+
+frysk::sys::ptrace::BlockSpace
+frysk::sys::ptrace::BlockSpace::regs(::jnixx::env env) {
+#if defined(__i386__)|| defined(__x86_64__)
+  return New(env, sizeof(user_regs_struct), PTRACE_GETREGS, PTRACE_SETREGS);
+#else
+  return BlockSpace(env, NULL);
+#endif
+}
+
+frysk::sys::ptrace::BlockSpace
+frysk::sys::ptrace::BlockSpace::fpregs(::jnixx::env env) {
+#if defined(__i386__)|| defined(__x86_64__)
+  return New(env, sizeof(user_fpregs_struct), PTRACE_GETFPREGS, PTRACE_SETFPREGS);
+#else
+  return BlockSpace(env, NULL);
+#endif
+}
+
+frysk::sys::ptrace::BlockSpace
+frysk::sys::ptrace::BlockSpace::fpxregs(::jnixx::env env) {
+#if defined(__i386__)
+  return New(env, sizeof(user_fpxregs_struct), PTRACE_GETFPXREGS, PTRACE_SETFPXREGS);
+#else
+  return BlockSpace(env, NULL);
+#endif
+}
diff --git a/frysk-sys/frysk/sys/ptrace/jni/ByteSpace.cxx b/frysk-sys/frysk/sys/ptrace/jni/ByteSpace.cxx
new file mode 100644
index 0000000..0fa5fe3
--- /dev/null
+++ b/frysk-sys/frysk/sys/ptrace/jni/ByteSpace.cxx
@@ -0,0 +1,181 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2005, 2006, 2007, 2008, Red Hat Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+#define DEBUG 0
+
+#include <stdio.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include "linux.ptrace.h"
+#include <string.h>
+
+#include "jni.hxx"
+#include "jnixx/bounds.hxx"
+#include "jnixx/elements.hxx"
+
+#include "frysk/sys/ptrace/jni/Ptrace.hxx"
+
+using namespace java::lang;
+
+union word {
+  long l;
+  uint8_t b[sizeof (long)];
+};
+
+jint
+frysk::sys::ptrace::ByteSpace::peek(::jnixx::env env, jint pid, jlong addr) {
+  union word w;
+  long paddr = addr & -sizeof(long);
+  if (DEBUG)
+    fprintf(stderr, "peek 0x%lx paddr 0x%lx", (long)addr, paddr);
+  w.l = ptraceOp(env, GetPtPeek(env), pid, (void*)paddr, 0);
+  if (DEBUG)
+    fprintf(stderr, " word 0x%lx", w.l);
+  int index = addr & (sizeof(long) - 1);
+  if (DEBUG)
+    fprintf(stderr, " index %d", index);
+  uint8_t byte = w.b[index];
+  if (DEBUG)
+    fprintf(stderr, " byte %d/0x%x\n", byte, byte);
+  return byte;
+}
+
+void
+frysk::sys::ptrace::ByteSpace::poke(::jnixx::env env, jint pid, jlong addr, jint data) {
+  // Implement read-modify-write
+  union word w;
+  if (DEBUG)
+    fprintf(stderr, "poke 0x%x", (int)(data & 0xff));
+  long paddr = addr & -sizeof(long);
+  if (DEBUG)
+    fprintf(stderr, " addr 0x%lx paddr 0x%lx", (long)addr, paddr);
+  w.l = ptraceOp(env, GetPtPeek(env), pid, (void*)paddr, 0);
+  if (DEBUG)
+    fprintf(stderr, " word 0x%lx", w.l);
+  int index = addr & (sizeof(long) - 1);
+  if (DEBUG)
+    fprintf (stderr, " index %d", index);
+  w.b[index] = data;
+  if (DEBUG)
+    fprintf(stderr, " word 0x%lx\n", w.l);
+  ptraceOp(env, GetPtPoke(env), pid, (void*)(addr & -sizeof(long)), w.l);
+}
+
+void
+frysk::sys::ptrace::ByteSpace::transfer(::jnixx::env env,
+					jint op, jint pid, jlong addr,
+					::jnixx::jbyteArray byteArray,
+					jint offset, jint length) {
+  const int ptPeek = GetPtPeek(env);
+  const int ptPoke = GetPtPoke(env);
+  verifyBounds(env, byteArray, offset, length);
+  // Somewhat more clueful implementation
+  for (jlong i = 0; i < length;) {
+    if (DEBUG)
+      fprintf(stderr,
+	      "transfer pid %d addr 0x%lx length %d offset %d op %d (%s) ...",
+	      (int)pid, (long)addr, (int)length, (int)offset,
+	      (int)op, ptraceOpToString(op));
+    union word w;
+    unsigned long waddr = addr & -sizeof(long);
+    unsigned long woff = (addr - waddr);
+    unsigned long remaining = length - i;
+    unsigned long wend;
+    if (remaining > sizeof(long) - woff)
+      wend = sizeof(long);
+    else
+      wend = woff + remaining;
+    long wlen = wend - woff;
+
+    if (DEBUG)
+      fprintf(stderr,
+	      " i %ld waddr 0x%lx woff %lu wend %lu remaining %lu wlen %lu ...",
+	      (long)i, waddr, woff, wend, remaining, wlen);
+
+    // Either a peek; or a partial write requiring read/modify/write.
+    if (op == ptPeek || woff != 0 || wend != sizeof(long)) {
+      w.l = ptraceOp(env, ptPeek, pid, (void*)waddr, 0);
+      if (DEBUG)
+	fprintf(stderr, " peek 0x%lx ...", w.l);
+    }
+
+    // extract or modify
+    jbyteArrayElements bytes = jbyteArrayElements(env, byteArray);
+    if (op == ptPeek)
+      memcpy(offset + i + bytes.elements(), &w.b[woff], wlen);
+    else {
+      memcpy(&w.b[woff], offset + i + bytes.elements(), wlen);
+      if (DEBUG)
+	fprintf(stderr, " poke 0x%lx ...", w.l);
+      w.l = ptraceOp(env, ptPoke, pid, (void*)waddr, w.l);
+    }
+    bytes.release();
+
+    i += wlen;
+    addr += wlen;
+
+    if (DEBUG)
+      fprintf(stderr, "\n");
+  }
+}
+
+frysk::sys::ptrace::ByteSpace
+frysk::sys::ptrace::ByteSpace::text(::jnixx::env env) {
+  return frysk::sys::ptrace::ByteSpace::New(env, -1UL,
+					    String::NewStringUTF(env, "TEXT"),
+					    PTRACE_PEEKTEXT,
+					    PTRACE_POKETEXT);
+}
+
+frysk::sys::ptrace::ByteSpace
+frysk::sys::ptrace::ByteSpace::data(::jnixx::env env) {
+  return frysk::sys::ptrace::ByteSpace::New(env, -1UL,
+					    String::NewStringUTF(env, "DATA"),
+					    PTRACE_PEEKDATA,
+					    PTRACE_POKEDATA);
+}
+
+frysk::sys::ptrace::ByteSpace
+frysk::sys::ptrace::ByteSpace::usr(::jnixx::env env) {
+  return frysk::sys::ptrace::ByteSpace::New(env, -1UL,
+					    String::NewStringUTF(env, "USR"),
+					    PTRACE_PEEKUSR,
+					    PTRACE_POKEUSR);
+}
diff --git a/frysk-sys/frysk/sys/ptrace/jni/Ptrace.cxx b/frysk-sys/frysk/sys/ptrace/jni/Ptrace.cxx
index 1a7c13f..dce86e5 100644
--- a/frysk-sys/frysk/sys/ptrace/jni/Ptrace.cxx
+++ b/frysk-sys/frysk/sys/ptrace/jni/Ptrace.cxx
@@ -37,6 +37,10 @@
 // version and license this file solely under the GPL without
 // exception.
 
+#define DEBUG 0
+
+#include <stdio.h>
+#include <string.h>
 #include <errno.h>
 #include <sys/ptrace.h>
 #include "linux.ptrace.h"
@@ -47,8 +51,8 @@
 
 #include "jnixx/exceptions.hxx"
 
-static const char*
-op_as_string(int op) {
+const char*
+ptraceOpToString(int op) {
   switch(op) {
 #define OP(NAME) case NAME: return #NAME
     OP(PTRACE_ATTACH);
@@ -82,11 +86,15 @@ op_as_string(int op) {
 long
 ptraceOp(::jnixx::env env, int op, int pid, void* addr, long data) {
   errno = 0;
-  long result = ::ptrace ((enum __ptrace_request) op, pid, addr, data);
-  if (errno != 0)
+  long result = ::ptrace((enum __ptrace_request) op, pid, addr, data);
+  if (errno != 0) {
+    int err = errno;
+    if (DEBUG)
+      fprintf(stderr, "throwing %s\n", strerror(err));
     errnoException(env, errno, "ptrace",
 		   "op 0x%x (%s), pid %d, addr 0x%lx, data 0x%lx",
-		   op, op_as_string(op), pid, (long)addr, data);
+		   op, ptraceOpToString(op), pid, (long)addr, data);
+  }
   return result;
 }
 
diff --git a/frysk-sys/frysk/sys/ptrace/jni/Ptrace.hxx b/frysk-sys/frysk/sys/ptrace/jni/Ptrace.hxx
index be134ef..46e2edd 100644
--- a/frysk-sys/frysk/sys/ptrace/jni/Ptrace.hxx
+++ b/frysk-sys/frysk/sys/ptrace/jni/Ptrace.hxx
@@ -38,3 +38,4 @@
 // exception.
 
 extern long ptraceOp(::jnixx::env, int, int, void*, long);
+extern const char *ptraceOpToString(int op);
diff --git a/frysk-sys/frysk/sys/ptrace/jni/RegisterSet.cxx b/frysk-sys/frysk/sys/ptrace/jni/RegisterSet.cxx
deleted file mode 100644
index d8fe8ca..0000000
--- a/frysk-sys/frysk/sys/ptrace/jni/RegisterSet.cxx
+++ /dev/null
@@ -1,88 +0,0 @@
-// This file is part of the program FRYSK.
-//
-// Copyright 2005, 2006, 2007, 2008, Red Hat Inc.
-//
-// FRYSK is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// FRYSK is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with FRYSK; if not, write to the Free Software Foundation,
-// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-// 
-// In addition, as a special exception, Red Hat, Inc. gives You the
-// additional right to link the code of FRYSK with code not covered
-// under the GNU General Public License ("Non-GPL Code") and to
-// distribute linked combinations including the two, subject to the
-// limitations in this paragraph. Non-GPL Code permitted under this
-// exception must only link to the code of FRYSK through those well
-// defined interfaces identified in the file named EXCEPTION found in
-// the source code files (the "Approved Interfaces"). The files of
-// Non-GPL Code may instantiate templates or use macros or inline
-// functions from the Approved Interfaces without causing the
-// resulting work to be covered by the GNU General Public
-// License. Only Red Hat, Inc. may make changes or additions to the
-// list of Approved Interfaces. You must obey the GNU General Public
-// License in all respects for all of the FRYSK code and other code
-// used in conjunction with FRYSK except the Non-GPL Code covered by
-// this exception. If you modify this file, you may extend this
-// exception to your version of the file, but you are not obligated to
-// do so. If you do not wish to provide this exception without
-// modification, you must delete this exception statement from your
-// version and license this file solely under the GPL without
-// exception.
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include "linux.ptrace.h"
-#include <sys/user.h>
-
-#include "jni.hxx"
-
-#include "frysk/sys/ptrace/jni/Ptrace.hxx"
-#include "jnixx/elements.hxx"
-#include "jnixx/bounds.hxx"
-
-void
-frysk::sys::ptrace::RegisterSet::transfer(::jnixx::env env,
-					  jint op, jint pid,
-					  ::jnixx::jbyteArray data,
-					  jint length) {
-  verifyBounds(env, data, length);
-  jbyteArrayElements bytes = jbyteArrayElements(env, data);
-  ptraceOp(env, op, pid, NULL, (long) bytes.elements());
-  bytes.release();
-}
-
-frysk::sys::ptrace::RegisterSet
-frysk::sys::ptrace::RegisterSet::regs(::jnixx::env env) {
-#if defined(__i386__)|| defined(__x86_64__)
-  return New(env, sizeof(user_regs_struct), PTRACE_GETREGS, PTRACE_SETREGS);
-#else
-  return RegisterSet(env, NULL);
-#endif
-}
-
-frysk::sys::ptrace::RegisterSet
-frysk::sys::ptrace::RegisterSet::fpregs(::jnixx::env env) {
-#if defined(__i386__)|| defined(__x86_64__)
-  return New(env, sizeof(user_fpregs_struct), PTRACE_GETFPREGS, PTRACE_SETFPREGS);
-#else
-  return RegisterSet(env, NULL);
-#endif
-}
-
-frysk::sys::ptrace::RegisterSet
-frysk::sys::ptrace::RegisterSet::fpxregs(::jnixx::env env) {
-#if defined(__i386__)
-  return New(env, sizeof(user_fpxregs_struct), PTRACE_GETFPXREGS, PTRACE_SETFPXREGS);
-#else
-  return RegisterSet(env, NULL);
-#endif
-}
diff --git a/frysk-sys/frysk/sys/ptrace/jni/Utrace.cxx b/frysk-sys/frysk/sys/ptrace/jni/Utrace.cxx
deleted file mode 100644
index b358932..0000000
--- a/frysk-sys/frysk/sys/ptrace/jni/Utrace.cxx
+++ /dev/null
@@ -1,40 +0,0 @@
-// This file is part of the program FRYSK.
-//
-// Copyright 2008, Red Hat Inc.
-//
-// FRYSK is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// FRYSK is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with FRYSK; if not, write to the Free Software Foundation,
-// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-// 
-// In addition, as a special exception, Red Hat, Inc. gives You the
-// additional right to link the code of FRYSK with code not covered
-// under the GNU General Public License ("Non-GPL Code") and to
-// distribute linked combinations including the two, subject to the
-// limitations in this paragraph. Non-GPL Code permitted under this
-// exception must only link to the code of FRYSK through those well
-// defined interfaces identified in the file named EXCEPTION found in
-// the source code files (the "Approved Interfaces"). The files of
-// Non-GPL Code may instantiate templates or use macros or inline
-// functions from the Approved Interfaces without causing the
-// resulting work to be covered by the GNU General Public
-// License. Only Red Hat, Inc. may make changes or additions to the
-// list of Approved Interfaces. You must obey the GNU General Public
-// License in all respects for all of the FRYSK code and other code
-// used in conjunction with FRYSK except the Non-GPL Code covered by
-// this exception. If you modify this file, you may extend this
-// exception to your version of the file, but you are not obligated to
-// do so. If you do not wish to provide this exception without
-// modification, you must delete this exception statement from your
-// version and license this file solely under the GPL without
-// exception.
-
-#include "jni.hxx"
diff --git a/frysk-sys/frysk/testbed/ChangeLog b/frysk-sys/frysk/testbed/ChangeLog
index 60bdb8a..4b44ac6 100644
--- a/frysk-sys/frysk/testbed/ChangeLog
+++ b/frysk-sys/frysk/testbed/ChangeLog
@@ -1,3 +1,18 @@
+2008-07-04  Andrew Cagney  <cagney@redhat.com>
+
+	* LocalMemory.java: Update; AddressSpace renamed to ByteSpace.
+
+2008-06-19  Andrew Cagney  <cagney@redhat.com>
+
+	* TestLocalMemory.java (testMemoryByteBuffer()): New.
+	* LocalMemory.java (getByteBuffer()): New.
+	* jni/LocalMemory.cxx (LocalMemory::peek): Implement.
+	* cni/LocalMemory.cxx (LocalMemory::peek): Implement.
+
+2008-06-12  Andrew Cagney  <cagney@redhat.com>
+
+	* TearDownExpect.java (TearDownExpect()): Add.
+
 2008-06-06  Andrew Cagney  <cagney@redhat.com>
 
 	* LocalMemory.java (getModuleName()): New.
diff --git a/frysk-sys/frysk/testbed/LocalMemory.java b/frysk-sys/frysk/testbed/LocalMemory.java
index c79f331..c9ff821 100644
--- a/frysk-sys/frysk/testbed/LocalMemory.java
+++ b/frysk-sys/frysk/testbed/LocalMemory.java
@@ -39,6 +39,9 @@
 
 package frysk.testbed;
 
+import inua.eio.ByteBuffer;
+import frysk.sys.ptrace.ByteSpace;
+
 /**
  * Provide access to known local areas of memory.
  *
@@ -102,4 +105,20 @@ public class LocalMemory {
      * will be so large that it is negative.
      */
     public static native void constructStack(StackBuilder builder);
+
+    /**
+     * Return a byte-buffer capable of reading any address of this
+     * thread's memory.
+     */
+    public static ByteBuffer getByteBuffer() {
+	return new ByteBuffer(0, ByteSpace.DATA.length()) {
+	    protected int peek(long offset) {
+		return LocalMemory.peek(offset);
+	    }
+	    protected void poke(long offset, int b) {
+		// do nothing
+	    }
+	};
+    }
+    private static native int peek(long addr);
 }
diff --git a/frysk-sys/frysk/testbed/TearDownExpect.java b/frysk-sys/frysk/testbed/TearDownExpect.java
index 0e50faf..7bbdcfb 100644
--- a/frysk-sys/frysk/testbed/TearDownExpect.java
+++ b/frysk-sys/frysk/testbed/TearDownExpect.java
@@ -65,6 +65,10 @@ public class TearDownExpect extends Expect {
 	super(command);
 	add(this);
     }
+    public TearDownExpect() {
+	super();
+	add(this);
+    }
 
     /**
      * Collection of expect classes.
diff --git a/frysk-sys/frysk/testbed/TestLocalMemory.java b/frysk-sys/frysk/testbed/TestLocalMemory.java
index f378d55..4d4447c 100644
--- a/frysk-sys/frysk/testbed/TestLocalMemory.java
+++ b/frysk-sys/frysk/testbed/TestLocalMemory.java
@@ -1,6 +1,6 @@
 // This file is part of the program FRYSK.
 //
-// Copyright 2007, Red Hat Inc.
+// Copyright 2007, 2008, Red Hat Inc.
 //
 // FRYSK is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by
@@ -40,13 +40,12 @@
 package frysk.testbed;
 
 import frysk.junit.TestCase;
+import inua.eio.ByteBuffer;
 
 /**
  * Check that LocalMemory addresses are pointing where expected.
  */
-public class TestLocalMemory
-    extends TestCase
-{
+public class TestLocalMemory extends TestCase {
     /**
      * Check that the stack address changes as new stack frames are
      * created.
@@ -96,4 +95,12 @@ public class TestLocalMemory
 	byte[] bytes = LocalMemory.getDataBytes();
 	assertEquals("data byte[0]", 43, bytes[0]);
     }
+
+
+    public void testMemoryByteBuffer() {
+	ByteBuffer memory = LocalMemory.getByteBuffer();
+	assertEquals("data", LocalMemory.getDataBytes()[0],
+		     memory.get(LocalMemory.getDataAddr()));
+    }
+
 }
diff --git a/frysk-sys/frysk/testbed/cni/LocalMemory.cxx b/frysk-sys/frysk/testbed/cni/LocalMemory.cxx
index f2944ea..8afd4af 100644
--- a/frysk-sys/frysk/testbed/cni/LocalMemory.cxx
+++ b/frysk-sys/frysk/testbed/cni/LocalMemory.cxx
@@ -1,6 +1,6 @@
 // This file is part of the program FRYSK.
 //
-// Copyright 2005, 2006, 2007, 2008 Red Hat Inc.
+// Copyright 2005, 2006, 2007, 2008, 2008 Red Hat Inc.
 //
 // FRYSK is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by
@@ -130,3 +130,8 @@ LocalMemory::getModuleName() {
   // be deleted.
   return JvNewStringUTF("TestRunner");
 }
+
+jint
+LocalMemory::peek(jlong addr) {
+  return *(unsigned char*)addr;
+}
diff --git a/frysk-sys/frysk/testbed/jni/LocalMemory.cxx b/frysk-sys/frysk/testbed/jni/LocalMemory.cxx
index 840e129..9324cf2 100644
--- a/frysk-sys/frysk/testbed/jni/LocalMemory.cxx
+++ b/frysk-sys/frysk/testbed/jni/LocalMemory.cxx
@@ -127,3 +127,8 @@ String
 LocalMemory::getModuleName(::jnixx::env env) {
   return String::NewStringUTF(env, "libfrysk-sys-jni.so");
 }
+
+jint
+LocalMemory::peek(::jnixx::env env, jlong addr) {
+  return *(unsigned char*)addr;
+}
diff --git a/frysk-sys/inua/ChangeLog b/frysk-sys/inua/ChangeLog
index 1827bf2..16ae59b 100644
--- a/frysk-sys/inua/ChangeLog
+++ b/frysk-sys/inua/ChangeLog
@@ -1,3 +1,8 @@
+2008-07-04  Andrew Cagney  <cagney@redhat.com>
+
+	* eio/ByteBuffer.java: Throw InternalException.
+	* eio/BufferUnderflowException.java: Extend UserException.
+
 2008-06-05  Andrew Cagney  <cagney@redhat.com>
 
 	* eio/ByteBuffer.java: Add missing indexed word get/put methods.
diff --git a/frysk-sys/inua/eio/BufferUnderflowException.java b/frysk-sys/inua/eio/BufferUnderflowException.java
index a17063d..2f9f7ed 100644
--- a/frysk-sys/inua/eio/BufferUnderflowException.java
+++ b/frysk-sys/inua/eio/BufferUnderflowException.java
@@ -34,10 +34,14 @@
 // modification, you must delete this exception statement from your
 // version and license this file solely under the GPL without
 // exception.
+
 package inua.eio;
 
-public class BufferUnderflowException
-    extends java.nio.BufferUnderflowException
-{
+import frysk.UserException;
+
+public class BufferUnderflowException extends UserException {
     private static final long serialVersionUID = 1L;
+    BufferUnderflowException(long address) {
+	super("Address 0x" + Long.toHexString(address) + " out of bounds");
+    }
 }
diff --git a/frysk-sys/inua/eio/ByteBuffer.java b/frysk-sys/inua/eio/ByteBuffer.java
index 6549a58..873e481 100644
--- a/frysk-sys/inua/eio/ByteBuffer.java
+++ b/frysk-sys/inua/eio/ByteBuffer.java
@@ -40,9 +40,10 @@
  * A ByteBuffer.  Just like {@link java.nio.ByteBuffer} only 64-bit.
  */
 
-
 package inua.eio;
 
+import frysk.InternalException;
+
 public abstract class ByteBuffer
     extends Buffer
 {
@@ -293,9 +294,8 @@ public abstract class ByteBuffer
    * Given BUFFER, return a new subBuffer. Used by {@link #slice}.
    */
   protected ByteBuffer subBuffer (ByteBuffer buffer, long lowerExtreem,
-                                  long upperExtreem)
-  {
-    throw new RuntimeException("not implemented");
+                                  long upperExtreem) {
+      throw new InternalException("not implemented");
   }
 
   public ByteBuffer slice (long off, long len)
@@ -321,14 +321,12 @@ public abstract class ByteBuffer
     return (byte) peek(lowWater + index);
   }
 
-  public ByteBuffer get (long index, byte[] dst, int off, int len)
-      throws BufferUnderflowException
-  {
-    if (ULong.GT(index + len, limit()))
-      throw new BufferUnderflowException();
-    peekFully(lowWater + index,dst,off,len);
-    return this;
-  }
+    public ByteBuffer get(long index, byte[] dst, int off, int len) {
+	if (ULong.GT(index + len, limit()))
+	    throw new BufferUnderflowException(index + len);
+	peekFully(lowWater + index,dst,off,len);
+	return this;
+    }
   
   public int safeGet (long index, byte[] dst, int off, int len)
   {
@@ -339,35 +337,29 @@ public abstract class ByteBuffer
     return maxLen;
   }
 
-  public ByteBuffer get (byte[] dst, int off, int len)
-      throws BufferUnderflowException
-  {
-    if (ULong.GT(len, remaining()))
-      throw new BufferUnderflowException();
-    peek(cursor, dst, off, len);
-    cursor += len;
-    return this;
-  }
+    public ByteBuffer get(byte[] dst, int off, int len) {
+	if (ULong.GT(len, remaining()))
+	    throw new BufferUnderflowException(len);
+	peek(cursor, dst, off, len);
+	cursor += len;
+	return this;
+    }
 
-  public final ByteBuffer get (byte[] dst) throws BufferUnderflowException
-  {
-    return get(dst, 0, dst.length);
-  }
+    public final ByteBuffer get (byte[] dst) {
+	return get(dst, 0, dst.length);
+    }
 
-  public ByteBuffer put (byte[] src, int off, int len)
-    throws BufferUnderflowException
-  {
-    if (ULong.GT(len, remaining()))
-      throw new BufferUnderflowException();
-    poke(cursor, src, off, len);
-    cursor += len;
-    return this;
-  }
+    public ByteBuffer put (byte[] src, int off, int len) {
+	if (ULong.GT(len, remaining()))
+	    throw new BufferUnderflowException(len);
+	poke(cursor, src, off, len);
+	cursor += len;
+	return this;
+    }
 
-  public final ByteBuffer put (byte[] src) throws BufferUnderflowException
-  {
-    return put(src, 0, src.length);
-  }
+    public final ByteBuffer put (byte[] src) {
+	return put(src, 0, src.length);
+    }
 
   protected ByteOrdered byteOrdered;
 
diff --git a/frysk-sys/jnixx/ChangeLog b/frysk-sys/jnixx/ChangeLog
index 7fdd6ba..d9ce902 100644
--- a/frysk-sys/jnixx/ChangeLog
+++ b/frysk-sys/jnixx/ChangeLog
@@ -1,3 +1,14 @@
+2008-06-20  Andrew Cagney  <cagney@redhat.com>
+
+	* elements.hxx (slurp): Return the BUF.
+	(FileElements::slurp): Update.
+	* elements.cxx (slurp): Update; when file-not-found return NULL.
+	
+2008-06-12  Andrew Cagney  <cagney@redhat.com>
+
+	* exceptions.cxx (userException): Implement.
+	* exceptions.hxx (userException): Declare.
+
 2008-06-04  Andrew Cagney  <cagney@redhat.com>
 
 	* elements.cxx (slurp): Don't count the terminating NUL in the
diff --git a/frysk-sys/jnixx/elements.cxx b/frysk-sys/jnixx/elements.cxx
index 4a432ae..4200f2f 100644
--- a/frysk-sys/jnixx/elements.cxx
+++ b/frysk-sys/jnixx/elements.cxx
@@ -102,12 +102,13 @@ chars2strings(::jnixx::env env, char** argv) {
   return strings;
 }
 
-void
-slurp(jnixx::env env, const char file[], jbyte*& buf, jsize& len) {
+jbyte*
+slurp(jnixx::env env, const char file[], jsize& len) {
   // Attempt to open the file.
   int fd = ::open(file, O_RDONLY);
   if (fd < 0) {
-    errnoException(env, errno, "open", "file %s", file);
+    len = 0;
+    return NULL;
   }
 
   // Initially allocate space for two BUFSIZE reads (and an extra NUL
@@ -117,7 +118,7 @@ slurp(jnixx::env env, const char file[], jbyte*& buf, jsize& len) {
   // reads are needed to confirm EOF.  Allocating 2&BUFSIZE ensures
   // that there's always space for at least two reads.  Ref SW #3370
   jsize allocated = BUFSIZ * 2 + 1;
-  buf = (jbyte*) ::malloc(allocated);
+  jbyte* buf = (jbyte*) ::malloc(allocated);
   if (buf == NULL) {
     errnoException(env, errno, "malloc");
   }
@@ -131,9 +132,8 @@ slurp(jnixx::env env, const char file[], jbyte*& buf, jsize& len) {
       ::close(fd);
       ::free(buf);
       // Abandon the read with elements == NULL.
-      buf = NULL;
       len = 0;
-      return;
+      return NULL;
     } else if (size == 0) {
       break;
     }
@@ -149,7 +149,6 @@ slurp(jnixx::env env, const char file[], jbyte*& buf, jsize& len) {
 	int err = errno;
 	::close(fd);
 	::free(buf);
-	buf = NULL;
 	len = 0;
 	errnoException(env, err, "realloc");
       }
@@ -162,4 +161,5 @@ slurp(jnixx::env env, const char file[], jbyte*& buf, jsize& len) {
   // Guarentee that the buffer is NUL terminated; but don't count that
   // as part of the buffer.
   buf[len] = '\0';
+  return buf;
 }
diff --git a/frysk-sys/jnixx/elements.hxx b/frysk-sys/jnixx/elements.hxx
index 75f137f..dcf8109 100644
--- a/frysk-sys/jnixx/elements.hxx
+++ b/frysk-sys/jnixx/elements.hxx
@@ -49,7 +49,13 @@
 
 extern char** strings2chars(::jnixx::env, ::jnixx::array<java::lang::String>);
 extern ::jnixx::array<java::lang::String> chars2strings(::jnixx::env, char**);
-extern void slurp(::jnixx::env, const char[], jbyte* (&), jsize&);
+
+/**
+ * Attempt to read the entire contents of the specified file.  Return
+ * BUF and set LEN, or NULL should the open fail.  The BUF will be NUL
+ * terminated but the NUL will not be included in the character count.
+ */
+extern jbyte* slurp(::jnixx::env, const char file[], jsize& len);
 
 class StringArrayChars {
 private:
@@ -239,9 +245,8 @@ public:
   }
 protected:
   void slurp(jnixx::env& env, type* (&buf), jsize &len) {
-    jbyte* buffer;
     jsize length;
-    ::slurp(env, file, buffer, length);
+    jbyte* buffer = ::slurp(env, file, length);
     buf = (type*)buffer;
     len = length / sizeof(type);
   }
diff --git a/frysk-sys/jnixx/exceptions.cxx b/frysk-sys/jnixx/exceptions.cxx
index 2f5ce80..928e0fd 100644
--- a/frysk-sys/jnixx/exceptions.cxx
+++ b/frysk-sys/jnixx/exceptions.cxx
@@ -150,3 +150,26 @@ runtimeException(::jnixx::env& env, const char *fmt, ...) {
     throw e;
   }
 }
+
+
+void
+userException(::jnixx::env& env, const char *fmt, ...) {
+  va_list ap;
+  va_start(ap, fmt);
+  char *message = NULL;
+  if (::vasprintf(&message, fmt, ap) < 0) {
+    // If this fails things are pretty much stuffed.
+    int err = errno;
+    fprintf(stderr, "warning: vasprintf in runtimeException failed: %s",
+	    ::strerror(err));
+    RuntimeException::ThrowNew(env, "vasprintf in runtimeException failed");
+  }
+  va_end(ap);
+  try {
+    frysk::UserException::ThrowNew(env, message);
+  } catch (java::lang::Throwable e) {
+    // Always executed.
+    ::free(message);
+    throw e;
+  }
+}
diff --git a/frysk-sys/jnixx/exceptions.hxx b/frysk-sys/jnixx/exceptions.hxx
index 877356c..36fde6f 100644
--- a/frysk-sys/jnixx/exceptions.hxx
+++ b/frysk-sys/jnixx/exceptions.hxx
@@ -52,3 +52,7 @@ extern void errnoException(::jnixx::env& env, int error, const char *prefix,
 extern void runtimeException(::jnixx::env& env, const char *fmt, ...)
   __attribute__((noreturn))
   __attribute__((format (printf, 2, 3)));
+
+extern void userException(::jnixx::env& env, const char *fmt, ...)
+  __attribute__((noreturn))
+  __attribute__((format (printf, 2, 3)));
diff --git a/frysk-sys/lib/dwfl/ChangeLog b/frysk-sys/lib/dwfl/ChangeLog
index 762b92a..43dc64a 100644
--- a/frysk-sys/lib/dwfl/ChangeLog
+++ b/frysk-sys/lib/dwfl/ChangeLog
@@ -1,3 +1,41 @@
+2008-06-19  Andrew Cagney  <cagney@redhat.com>
+
+	* cni/Dwfl.cxx (dwfl_frysk_proc_find_elf): Always set file_name so
+	elfutils realises that the ELF was set.
+	* jni/Dwfl.cxx: Ditto.
+	* TestDwfl.java (testMapContainsVdso): Check the vdso's elf. 
+	* Dwfl.java (mapModule): Include segments starting with "[".
+	
+	* DwflTestbed.java (createFromSelf()): Pass LocalMemory to the Dwfl.
+	* cni/DwflModule.cxx (DwflModule::setUserData): Delete.
+	* jni/DwflModule.cxx (DwflModule::setUserData): Delete.
+	* Dwfl.java (Dwfl(String,ByteBuffer)): New.
+	* DwflModule.java (setUserData(Object)): Delete.	
+	* jni/Dwfl.cxx: Update.
+	* cni/Dwfl.cxx: Update.
+
+	* Dwfl.java (mapModule): Correctly add maps such as [vdso].
+	* TestDwfl.java (testMapContainsVdso()): New.
+	* DwflTestbed.java (VdsoBuilder): Delete.
+	(createFromSelf()): Don't pass in the vdso.
+
+2008-06-16  Andrew Cagney  <cagney@redhat.com>
+
+	* DwflModule.java (get_cu_dies): Add pointer parameter.
+	* cni/DwflModule.cxx (DwflModule::get_cu_dies): Update.
+	* jni/DwflModule.cxx (DwflModule::get_cu_dies): Implement, missing.
+
+2008-06-15  Andrew Cagney  <cagney@redhat.com>
+
+	* DwarfDie.java (get_scopevar): Return an int.
+	* jni/DwarfDie.cxx (DwarfDie::get_scopevar): Only examine the die
+	when its valid.
+	* cni/DwarfDie.cxx (DwarfDie::get_scopevar): Ditto.
+
+2008-06-12  Andrew Cagney  <cagney@redhat.com>
+
+	* ElfException.java: Extend UserException.
+
 2008-06-07  Andrew Cagney  <cagney@redhat.com>
 
 	* jni/ElfSymbol.cxx (ElfSymbol::elf_load_verneed): Don't delete a
diff --git a/frysk-sys/lib/dwfl/DwarfDie.java b/frysk-sys/lib/dwfl/DwarfDie.java
index dda1671..bc2d24b 100644
--- a/frysk-sys/lib/dwfl/DwarfDie.java
+++ b/frysk-sys/lib/dwfl/DwarfDie.java
@@ -476,7 +476,8 @@ public class DwarfDie {
 
     private native long[] get_scopes_die ();
 
-    private native long get_scopevar (long[] die_scope, long[] scopes, String variable);
+    private native int get_scopevar(long[] die_scope, long[] scopes,
+				    String variable);
 
     private native long get_scopevar_names (long[] scopes, String variable);
   
diff --git a/frysk-sys/lib/dwfl/Dwfl.java b/frysk-sys/lib/dwfl/Dwfl.java
index 9e9ef82..f540e9f 100644
--- a/frysk-sys/lib/dwfl/Dwfl.java
+++ b/frysk-sys/lib/dwfl/Dwfl.java
@@ -43,25 +43,37 @@ import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import frysk.rsl.Log;
 import inua.eio.ULong;
+import inua.eio.ByteBuffer;
 
 public class Dwfl {
     private static final Log fine = Log.fine(Dwfl.class);
     private static final Log finest = Log.finest(Dwfl.class);
 
+    private long userdata;
     private long pointer;
     private long callbacks;
 
     protected final DwarfDieFactory factory = DwarfDieFactory.getFactory();
   
     /**
-     * Create a dwfl with the specified debug-info search path.
+     * Create a dwfl with the specified debug-info search path and
+     * memory.
+     */
+    public Dwfl(String debugInfoPath, ByteBuffer memory) {
+	callbacks = dwfl_callbacks_begin(debugInfoPath);
+	userdata = dwfl_userdata_begin(memory);
+	pointer = dwfl_begin(callbacks);
+    }
+    private static native long dwfl_callbacks_begin(String debugInfoSearchPath);
+    private static native long dwfl_userdata_begin(ByteBuffer memory);
+    private static native long dwfl_begin(long callbacks);
+    /**
+     * Create a dwfl with the specified debug-info search path and
+     * memory.
      */
     public Dwfl(String debugInfoPath) {
-	callbacks = callbacksBegin(debugInfoPath);
-	pointer = dwflBegin(callbacks);
+	this(debugInfoPath, null);
     }
-    private static native long callbacksBegin(String debugInfoSearchPath);
-    private static native long dwflBegin(long callbacks);
 
     protected void finalize () {
 	if (this.pointer != 0) {
@@ -71,14 +83,16 @@ public class Dwfl {
     }
     public void close() {
 	if (this.pointer != 0) {
-	    dwflEnd(pointer);
+	    dwfl_end(pointer);
 	    this.pointer = 0;
-	    callbacksEnd(callbacks);
+	    dwfl_userdata_end(userdata);
+	    dwfl_callbacks_end(callbacks);
 	    this.callbacks = 0;
 	}
     }
-    private static native void dwflEnd(long pointer);
-    private static native void callbacksEnd(long callbacks);
+    private static native void dwfl_end(long pointer);
+    private static native void dwfl_userdata_end(long userdata);
+    private static native void dwfl_callbacks_end(long callbacks);
     
     public DwflLine getSourceLine (long addr) {
 	DwflModule module = getModule(addr);
@@ -158,32 +172,33 @@ public class Dwfl {
      */
     public void reportBegin() {
 	fine.log(this, "reportBegin");
-	reportBegin(pointer);
+	dwfl_report_begin(pointer);
 	// fill modulesArray with the current modules and then clear
 	// the set.  Will iterate over the old modules so that they
 	// are re-used.
 	getModules();
 	modules.clear();
     }
-    private static native void reportBegin(long pointer);
+    private static native void dwfl_report_begin(long pointer);
 
     /**
      * Finish a refresh of the address map.
      */
     public void reportEnd() {
 	fine.log(this, "reportEnd");
-	reportEnd(pointer);
+	dwfl_report_end(pointer);
 	// Finished; scrub references to old modules.
 	modulesArray = null;
     }
-    private static native void reportEnd(long pointer);
+    private static native void dwfl_report_end(long pointer);
 
     /**
      * Report a mapped component.
      */
     public void reportModule(String moduleName, long low, long high) {
 	fine.log(this, "reportModule", moduleName, "low", low, "high", high);
-	long modulePointer = reportModule(pointer, moduleName, low, high);
+	long modulePointer = dwfl_report_module(pointer, moduleName, low, high,
+						userdata);
 	for (int i = 0; i < modulesArray.length; i++) {
 	    DwflModule module = modulesArray[i];
 	    if (module.getName().equals(moduleName)
@@ -202,8 +217,10 @@ public class Dwfl {
 	finest.log(this, "reportModule creating", module);
 	modules.put(new Long(modulePointer), module);
     }
-    private static native long reportModule(long pointer, String moduleName,
-					    long low, long high);
+    private static native long dwfl_report_module(long pointer,
+						  String moduleName,
+						  long low, long high,
+						  long userdata);
 
     private String name;
     private long low;
@@ -211,14 +228,12 @@ public class Dwfl {
     private int devMajor;
     private int devMinor;
     private int inode;
-    private long vdso;
     /**
      * Start refreshing the address map using raw information
      * extracted from /proc/pid/maps.
      */
-    public void mapBegin(long vdso) {
+    public void mapBegin() {
 	reportBegin();
-	this.vdso = vdso;
 	name = null;
     }
     /**
@@ -226,28 +241,35 @@ public class Dwfl {
      */
     public void mapModule(String name, long low, long high,
 			  int devMajor, int devMinor, int inode) {
-	if (this.name != null && this.name.equals(name)
+	finest.log(this, "mapModule", name, "low", low, "high", high,
+		   "devMajor", devMajor, "devMinor", devMinor, "inode", inode);
+	if (this.name != null
+	    && this.name.equals(name)
 	    && this.devMajor == devMajor
 	    && this.devMinor == devMinor
 	    && this.inode == inode
 	    ) {
+	    finest.log(this, "extending to", high);
 	    // A repeat of a previous map (but with more addresses)
 	    // extend the address range.
 	    this.high = high;
 	} else {
 	    if (this.name != null) {
 		// There's a previous map, report and flush it.
+		finest.log(this, "reporting", this.name);
 		reportModule(this.name, this.low, this.high);
 		this.name = null;
 	    }
-	    if (name.equals("")
-		|| (devMajor == 0 && devMinor == 0 && inode == 0)) {
-		// An empty map, do nothing.
-	    } else if (this.vdso == low) {
-		// A vdso, report it immediatly.
-		reportModule(name, low, high);
+	    if (name == null) {
+		finest.log(this, "ignoring null name");
+	    } else if (name.equals("")) {
+		finest.log(this, "ignoring empty name");
+	    } else if (name.indexOf("(deleted") >= 0) {
+		finest.log(this, "ignoring deleted", name);
+	    } else if (!name.startsWith("/") && !name.equals("[vdso]")) {
+		finest.log(this, "ignoring non-file", name);
 	    } else {
-		// A new map, save it.
+		// A new map, save it, will be reported later.
 		this.name = name;
 		this.low = low;
 		this.high = high;
diff --git a/frysk-sys/lib/dwfl/DwflModule.java b/frysk-sys/lib/dwfl/DwflModule.java
index b262ec4..b73d3c6 100644
--- a/frysk-sys/lib/dwfl/DwflModule.java
+++ b/frysk-sys/lib/dwfl/DwflModule.java
@@ -40,6 +40,7 @@
 package lib.dwfl;
 
 import java.util.LinkedList;
+import java.util.List;
 
 /**
  * A wrapper object around the libdwfl Dwfl_Module structure.
@@ -65,7 +66,10 @@ public class DwflModule {
 
   
     public String toString() {
-	return name + " pointer: 0x" + Long.toHexString(pointer);
+	return name
+	    + " 0x" + Long.toHexString(low)
+	    + "..0x" + Long.toHexString(high)
+	    + " pointer=0x" + Long.toHexString(pointer);
     }
 
     public long lowAddress() {
@@ -132,8 +136,6 @@ public class DwflModule {
 
     public native void getSymbolByName(String name,
 				       SymbolBuilder symbolBuilder);
-  
-    public native void setUserData(Object data);
     
     /**
      * Get the debuginfo path for DwflModule
@@ -142,10 +144,12 @@ public class DwflModule {
      */
     public native String getDebuginfo();
     
-    public LinkedList getCuDies(){
-	return get_cu_dies();
+    public List getCuDies(){
+	List list = new LinkedList();
+	get_cu_dies(pointer, list);
+	return list;
     }
-    private native LinkedList get_cu_dies();
+    private static native void get_cu_dies(long pointer, List list);
 
     public DwflDie getCompilationUnit(long addr) {
 	// Find the die, grab the bias as it flies by.
diff --git a/frysk-sys/lib/dwfl/DwflTestbed.java b/frysk-sys/lib/dwfl/DwflTestbed.java
index 80aed86..3c931bf 100644
--- a/frysk-sys/lib/dwfl/DwflTestbed.java
+++ b/frysk-sys/lib/dwfl/DwflTestbed.java
@@ -39,26 +39,12 @@
 
 package lib.dwfl;
 
+import frysk.testbed.LocalMemory;
 import frysk.sys.proc.MapsBuilder;
 import frysk.sys.Pid;
-import frysk.sys.proc.AuxvBuilder;
 
 public class DwflTestbed {
 
-    private static class VdsoBuilder extends AuxvBuilder {
-	long address;
-	public void buildBuffer(byte[] auxv) {
-	}
-	public void buildDimensions(int wordSize, boolean bigEndian,
-				    int numberElements) {
-	}
-	public void buildAuxiliary(int index, int type, long value) {
-	    if (type == inua.elf.AT.SYSINFO_EHDR) {
-		address = value;
-	    }
-	}
-    }
-
     private static class ModuleBuilder extends MapsBuilder {
 	private final Dwfl dwfl;
 	ModuleBuilder(Dwfl dwfl) {
@@ -90,11 +76,9 @@ public class DwflTestbed {
      * Create a dwfl from this process.
      */
     static Dwfl createFromSelf() {
-	Dwfl dwfl = new Dwfl("");
+	Dwfl dwfl = new Dwfl("", LocalMemory.getByteBuffer());
 	ModuleBuilder maps = new ModuleBuilder(dwfl);
-	VdsoBuilder vdso = new VdsoBuilder();
-	vdso.construct(Pid.get());
-	dwfl.mapBegin(vdso.address);
+	dwfl.mapBegin();
 	maps.construct(Pid.get());
 	dwfl.mapEnd();
 	return dwfl;
diff --git a/frysk-sys/lib/dwfl/ElfException.java b/frysk-sys/lib/dwfl/ElfException.java
index 86306e8..6454a34 100644
--- a/frysk-sys/lib/dwfl/ElfException.java
+++ b/frysk-sys/lib/dwfl/ElfException.java
@@ -39,12 +39,14 @@
 
 package lib.dwfl;
 
+import frysk.UserException;
+
 /**
  * The Elf back-end detected a problem; it might be an invalid
  * operation; it might also be a corrupt part of an elf file.
  */
 
-public class ElfException extends RuntimeException {
+public class ElfException extends UserException {
     private static final long serialVersionUID = 400112389738713948L;
 
     ElfException(Throwable t) {
diff --git a/frysk-sys/lib/dwfl/TestDwfl.java b/frysk-sys/lib/dwfl/TestDwfl.java
index d8076d2..2d2bcc4 100644
--- a/frysk-sys/lib/dwfl/TestDwfl.java
+++ b/frysk-sys/lib/dwfl/TestDwfl.java
@@ -232,4 +232,20 @@ public class TestDwfl extends TestCase {
 	}
 	assertTrue(foundAddress);
     }
+
+    public void testMapContainsVdso() {
+	Dwfl dwfl = DwflTestbed.createFromSelf();
+	DwflModule[] modules = dwfl.getModules();
+	DwflModule vdso = null;
+	for (int i = 0; i < modules.length; i++) {
+	    DwflModule module = modules[i];
+	    finest.log("module", i, "name", module);
+	    if (module.getName().equals("[vdso]")) {
+		vdso = module;
+		break;
+	    }
+	}
+	assertNotNull("vdso", vdso);
+	assertNotNull("elf", vdso.getElf());
+    }
 }
diff --git a/frysk-sys/lib/dwfl/cni/DwarfDie.cxx b/frysk-sys/lib/dwfl/cni/DwarfDie.cxx
index c562d2e..b10689d 100644
--- a/frysk-sys/lib/dwfl/cni/DwarfDie.cxx
+++ b/frysk-sys/lib/dwfl/cni/DwarfDie.cxx
@@ -1,6 +1,6 @@
 // This file is part of the program FRYSK.
 //
-// Copyright 2005, 2007, Red Hat Inc.
+// Copyright 2005, 2007, 2008, Red Hat Inc.
 //
 // FRYSK is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by
@@ -165,10 +165,9 @@ lib::dwfl::DwarfDie::get_scopes_die()
 
 Dwarf_Die *var_die;
 
-jlong
-lib::dwfl::DwarfDie::get_scopevar (jlongArray die_scope, jlongArray scopes,
-				 jstring variable)
-{
+jint
+lib::dwfl::DwarfDie::get_scopevar(jlongArray die_scope, jlongArray scopes,
+				 jstring variable) {
   
   var_die = (Dwarf_Die*)JvMalloc(sizeof(Dwarf_Die));
   int nscopes = JvGetArrayLength (scopes);
@@ -176,11 +175,10 @@ lib::dwfl::DwarfDie::get_scopevar (jlongArray die_scope, jlongArray scopes,
   Dwarf_Die *dies[nscopes];
   jlong* scopesp = elements(scopes);
 
-  for(int i = 0; i < nscopes; i++)
-    {
-      jlong dieptr = scopesp[i];
-      dies[i] = (Dwarf_Die*)dieptr;
-    }
+  for(int i = 0; i < nscopes; i++) {
+    jlong dieptr = scopesp[i];
+    dies[i] = (Dwarf_Die*)dieptr;
+  }
   
   int utf_variable_len = variable->length ();
   char utf_variable[utf_variable_len + 1];
@@ -190,16 +188,15 @@ lib::dwfl::DwarfDie::get_scopevar (jlongArray die_scope, jlongArray scopes,
   int code = dwarf_getscopevar (*dies, nscopes,
 				utf_variable,
 				0, NULL, 0, 0, var_die);
-  if (code >= 0)
-    {
-      if (dwarf_tag (var_die) != DW_TAG_variable)
-	return -1;
-      jlong* longp = elements(die_scope);
-      longp[0] = (jlong)var_die;    // Die for variable
-      longp[1] = code; // Die for scope
-    }
-  else if (dwarf_tag (var_die) != DW_TAG_variable)
-    return -1;
+  if (code >= 0) {
+    if (dwarf_tag(var_die) != DW_TAG_variable)
+      return -1;
+    jlong* longp = elements(die_scope);
+    longp[0] = (jlong)var_die;    // Die for variable
+    longp[1] = code; // Die for scope
+  } else {
+    ::free(var_die);
+  }
   return code;
 }
 
diff --git a/frysk-sys/lib/dwfl/cni/Dwfl.cxx b/frysk-sys/lib/dwfl/cni/Dwfl.cxx
index ceb76aa..e17af96 100644
--- a/frysk-sys/lib/dwfl/cni/Dwfl.cxx
+++ b/frysk-sys/lib/dwfl/cni/Dwfl.cxx
@@ -79,7 +79,6 @@ read_proc_memory (void *arg, void *data, GElf_Addr address,
 		  size_t minread, size_t maxread)
 {
   inua::eio::ByteBuffer* memory = (inua::eio::ByteBuffer *) arg;
-  
   jbyteArray bytes = JvNewByteArray(maxread);
   ssize_t nread = memory->safeGet((off64_t) address, bytes, 0, maxread);
   memcpy(data, elements(bytes), nread);
@@ -94,41 +93,37 @@ dwfl_frysk_proc_find_elf (Dwfl_Module *mod,
 			  const char *module_name, Dwarf_Addr base,
 			  char **file_name, Elf **elfp)
 {	
-  // There is an edge case here that was tripped by a corefile case. In that case the
-  // specified executable was defined as a relative path (ie ../foo/bar). And that is
-  // perfectly valid path name. However when the corefile created its maps it did not
-  // convert that path to an absolute path, causing the test below to fail and consider
-  // the file ../foo/bar to be an in memory elf image.
-  if (module_name[0] == '/')
-    {
-      int fd = open64 (module_name, O_RDONLY);
-      if (fd >= 0)
-	{
-	  *file_name = strdup (module_name);
-	  if (*file_name == NULL)
-	    {
-	      close (fd);
-	      return ENOMEM;
-	    }
-	}
-      return fd;
-    }
-  else
-    {
-      /* Special case for in-memory ELF image.  */
-      inua::eio::ByteBuffer * memory = (inua::eio::ByteBuffer *) *userdata;           
-      
-      *elfp = elf_from_remote_memory (base, NULL, &read_proc_memory, memory);
-     
+  // There is an edge case here that was tripped by a corefile
+  // case. In that case the specified executable was defined as a
+  // relative path (ie ../foo/bar). And that is perfectly valid path
+  // name. However when the corefile created its maps it did not
+  // convert that path to an absolute path, causing the test below to
+  // fail and consider the file ../foo/bar to be an in memory elf
+  // image.
+  if (module_name[0] == '/') {
+    // Pass back the file name and let dwfl take care of the rest.
+    *file_name = strdup (module_name);
+    return -1;
+  } else {
+      *elfp = elf_from_remote_memory (base, NULL, &read_proc_memory, *userdata);
+      if (*elfp != NULL) {
+	*file_name = ::strdup(module_name);
+      }
       return -1;
     }
+}
+
+jlong
+lib::dwfl::Dwfl::dwfl_userdata_begin(inua::eio::ByteBuffer *memory) {
+  return (jlong)memory;
+}
 
-  //abort ();
-  return -1;
+void
+lib::dwfl::Dwfl::dwfl_userdata_end(jlong userdata) {
 }
 
 jlong
-lib::dwfl::Dwfl::callbacksBegin(jstring debugInfoPath) {
+lib::dwfl::Dwfl::dwfl_callbacks_begin(jstring debugInfoPath) {
   char** path = (char**) JvMalloc(sizeof (char*));
   int len = JvGetStringUTFLength(debugInfoPath);
   *path = (char*)JvMalloc(len + 1);
@@ -145,45 +140,54 @@ lib::dwfl::Dwfl::callbacksBegin(jstring debugInfoPath) {
 }
 
 void
-lib::dwfl::Dwfl::callbacksEnd(jlong callbacks) {
+lib::dwfl::Dwfl::dwfl_callbacks_end(jlong callbacks) {
   JvFree(*DWFL_CALLBACKS->debuginfo_path);
   JvFree(DWFL_CALLBACKS->debuginfo_path);
   JvFree(DWFL_CALLBACKS);
 }
 
 jlong
-lib::dwfl::Dwfl::dwflBegin(jlong callbacks) {
+lib::dwfl::Dwfl::dwfl_begin(jlong callbacks) {
   return (jlong) ::dwfl_begin(DWFL_CALLBACKS);
 }
 
 void
-lib::dwfl::Dwfl::dwflEnd(jlong pointer){
+lib::dwfl::Dwfl::dwfl_end(jlong pointer){
   ::dwfl_end(DWFL_POINTER);
 }
 
 void
-lib::dwfl::Dwfl::reportBegin(jlong pointer) {
+lib::dwfl::Dwfl::dwfl_report_begin(jlong pointer) {
   ::dwfl_report_begin(DWFL_POINTER);
 }
 
 void
-lib::dwfl::Dwfl::reportEnd(jlong pointer) {
+lib::dwfl::Dwfl::dwfl_report_end(jlong pointer) {
   ::dwfl_report_end(DWFL_POINTER, NULL, NULL);
 }
 
 
 jlong
-lib::dwfl::Dwfl::reportModule(jlong pointer, jstring moduleName,
-			      jlong low, jlong high) {
+lib::dwfl::Dwfl::dwfl_report_module(jlong pointer, jstring moduleName,
+				    jlong low, jlong high, jlong userdata) {
   jsize len = JvGetStringUTFLength(moduleName);
   char modName[len+1]; 
 	
   JvGetStringUTFRegion(moduleName, 0, len, modName);
   modName[len] = '\0';
-	
-  return (jlong) ::dwfl_report_module(DWFL_POINTER, modName,
-				      (::Dwarf_Addr) low, 
-				      (::Dwarf_Addr) high);  
+  
+  Dwfl_Module* module = ::dwfl_report_module(DWFL_POINTER, modName,
+					     (::Dwarf_Addr) low, 
+					     (::Dwarf_Addr) high);
+  if (userdata != 0) {
+    // Get the address of the module's userdata, and store a global
+    // reference to memory in there.  The global ref is detroyed along
+    // with the Dwfl.
+    void **userdatap;
+    ::dwfl_module_info(module, &userdatap, NULL, NULL, NULL, NULL, NULL, NULL);
+    *userdatap = (void*)userdata;
+  }
+  return (jlong) module;
 }
 
 extern "C" int moduleCounter(Dwfl_Module *, void **, const char *,
diff --git a/frysk-sys/lib/dwfl/cni/DwflModule.cxx b/frysk-sys/lib/dwfl/cni/DwflModule.cxx
index ad85344..97892ff 100644
--- a/frysk-sys/lib/dwfl/cni/DwflModule.cxx
+++ b/frysk-sys/lib/dwfl/cni/DwflModule.cxx
@@ -45,6 +45,9 @@
 
 #include <gnu/gcj/RawData.h>
 
+#include <java/util/List.h>
+
+
 #include "lib/dwfl/DwflModule.h"
 #include "lib/dwfl/DwarfDie.h"
 #include "lib/dwfl/DwflLine.h"
@@ -65,18 +68,15 @@
 #define DWFL_MODULE_POINTER ((Dwfl_Module *) pointer)
 
 lib::dwfl::ModuleElfBias*
-lib::dwfl::DwflModule::module_getelf()
-{
-	Dwarf_Addr bias = 0;
-	::Elf *elf = dwfl_module_getelf(DWFL_MODULE_POINTER, &bias);
-	if(elf == NULL)
-		return NULL;
-		
-	lib::dwfl::ModuleElfBias *ret = new lib::dwfl::ModuleElfBias();
-	ret->elf = new lib::dwfl::Elf((jlong) elf);
-	ret->bias = (jlong) bias;
-		
-	return ret;	
+lib::dwfl::DwflModule::module_getelf() {
+  Dwarf_Addr bias = 0;
+  ::Elf *elf = dwfl_module_getelf(DWFL_MODULE_POINTER, &bias);
+  if(elf == NULL)
+    return NULL;
+  lib::dwfl::ModuleElfBias *ret = new lib::dwfl::ModuleElfBias();
+  ret->elf = new lib::dwfl::Elf((jlong) elf);
+  ret->bias = (jlong) bias;
+  return ret;	
 }
 
 typedef JArray<lib::dwfl::DwflLine *> DwflLineArray;
@@ -337,17 +337,6 @@ lib::dwfl::DwflModule::getSymbolByName(jstring name,
     }
 }
 
-void
-lib::dwfl::DwflModule::setUserData(jobject data)
-{
-  void **userdata = NULL;
-  dwfl_module_info(DWFL_MODULE_POINTER, &userdata, NULL, NULL, NULL, NULL, NULL,
-                   NULL);
-                   
-   *userdata = data;
-  
-}
-
 /* 
  * Get the DebugInfo paths if present
  */
@@ -443,35 +432,21 @@ lib::dwfl::DwflModule::offdie(jlong die, jlong offset){
   return dwarfDie;
 }
 
-java::util::LinkedList*
-lib::dwfl::DwflModule::get_cu_dies()
-{
-	
-	java::util::LinkedList* list = new java::util::LinkedList();
-    
-    Dwarf_Die* cu;
-    Dwarf_Die lastcu;
-    Dwarf_Addr bias;
-    
-    cu = dwfl_module_nextcu((::Dwfl_Module*)this->pointer, NULL, &bias);
-    
-    fflush(stdout);
-    while ( cu != NULL){
-  	  
+void
+lib::dwfl::DwflModule::get_cu_dies(jlong pointer,
+				   java::util::List *list) {
+  Dwarf_Die* cu;
+  Dwarf_Addr bias;
+  cu = dwfl_module_nextcu(DWFL_MODULE_POINTER, NULL, &bias);
+  while (cu != NULL) {
       Dwarf_Die *die = (Dwarf_Die*)JvMalloc(sizeof(Dwarf_Die));
-  				
-  	  memcpy(die, cu, sizeof(*die));
-  	  lib::dwfl::DwarfDie* cuDie = lib::dwfl::DwarfDieFactory::getFactory()->makeDie((jlong)die, NULL);
-  	  cuDie->setManageDie(true);
-  	  
-  	  list->add(cuDie);
-  	  
-  	  memcpy(&lastcu, cu, sizeof(*cu));
-      cu = dwfl_module_nextcu((::Dwfl_Module*)this->pointer, &lastcu, &bias);
-      
-    }
-	  
-  return list;
+      memcpy(die, cu, sizeof(*die));
+      lib::dwfl::DwarfDie* cuDie
+	= lib::dwfl::DwarfDieFactory::getFactory()->makeDie((jlong)die, NULL);
+      cuDie->setManageDie(true);
+      list->add(cuDie);
+      cu = dwfl_module_nextcu(DWFL_MODULE_POINTER, cu, &bias);
+  }
 }
 
 jlong
diff --git a/frysk-sys/lib/dwfl/jni/DwarfDie.cxx b/frysk-sys/lib/dwfl/jni/DwarfDie.cxx
index 0935d19..0da40c1 100644
--- a/frysk-sys/lib/dwfl/jni/DwarfDie.cxx
+++ b/frysk-sys/lib/dwfl/jni/DwarfDie.cxx
@@ -148,7 +148,7 @@ lib::dwfl::DwarfDie::get_scopes_die(jnixx::env env) {
   return longs;
 }
 
-jlong
+jint
 lib::dwfl::DwarfDie::get_scopevar(jnixx::env env, jnixx::jlongArray jdie_scope,
 				  jnixx::jlongArray jscopes, String jvariable) {
   // FIXME: This appears to be leaked?
@@ -169,8 +169,8 @@ lib::dwfl::DwarfDie::get_scopevar(jnixx::env env, jnixx::jlongArray jdie_scope,
     jlongArrayElements die_scope = jlongArrayElements(env, jdie_scope);
     die_scope.elements()[0] = (jlong)var_die;    // Die for variable
     die_scope.elements()[1] = code; // Die for scope
-  } else if (dwarf_tag (var_die) != DW_TAG_variable) {
-    return -1;
+  } else {
+    ::free(var_die);
   }
   return code;
 }
diff --git a/frysk-sys/lib/dwfl/jni/Dwfl.cxx b/frysk-sys/lib/dwfl/jni/Dwfl.cxx
index c984daa..7be62a5 100644
--- a/frysk-sys/lib/dwfl/jni/Dwfl.cxx
+++ b/frysk-sys/lib/dwfl/jni/Dwfl.cxx
@@ -70,34 +70,28 @@ extern "C" {
 // Assume the method was parameterised with POINTER.
 #define DWFL_POINTER ((::Dwfl *)pointer)
 
-// Ditto for callbacks pointer.
-#define DWFL_CALLBACKS ((::Dwfl_Callbacks*)callbacks)
+
 
-struct proc_memory_context {
-  jnixx::env env;
-  inua::eio::ByteBuffer memory;
-  proc_memory_context(jnixx::env env, inua::eio::ByteBuffer memory) {
-    this->env = env;
-    this->memory = memory;
-  }
-};
+// Our data associated with the dwfl (well actually the Dwfl_Module).
+// Need to make memory available so that, in the case of the vdso, it
+// can be slurped from memory.
 
 static ssize_t
-read_proc_memory(void *arg, void *data, GElf_Addr address,
+read_proc_memory(void *userdata, void *data, GElf_Addr address,
 		 size_t minread, size_t maxread) {
-  fprintf(stderr, "wft does data %p get set? - perhaps it isn't called\n",
-	  data);
-  proc_memory_context* context = (proc_memory_context*) arg;
-  jnixx::jbyteArray bytes
-    = jnixx::jbyteArray::NewByteArray(context->env, maxread);
-  ssize_t nread
-    = context->memory.safeGet(context->env, (off64_t) address, bytes, 0,
-			      maxread);
-  jbyteArrayElements bytesp = jbyteArrayElements(context->env, bytes);
+  // Get the current thread's ENV; can't save it in dwfl_userdata
+  // since can't determine, ahead of time, which thread will call this
+  // code.
+  ::jnixx::env env = Object::_env_();
+  ::inua::eio::ByteBuffer memory
+      = ::inua::eio::ByteBuffer(env, (jobject)userdata);
+  jnixx::jbyteArray bytes = jnixx::jbyteArray::NewByteArray(env, maxread);
+  ssize_t nread = memory.safeGet(env, (off64_t) address, bytes, 0, maxread);
+  jbyteArrayElements bytesp = jbyteArrayElements(env, bytes);
   memcpy(data, bytesp.elements(), nread);
   if (nread > 0 && (size_t) nread < minread)
     nread = 0;
-  bytes.DeleteLocalRef(context->env);
+  bytes.DeleteLocalRef(env);
   return nread;
 }
 
@@ -113,28 +107,40 @@ dwfl_frysk_proc_find_elf(Dwfl_Module *mod,
   // that path to an absolute path, causing the test below to fail and
   // consider the file ../foo/bar to be an in memory elf image.
   if (module_name[0] == '/') {
-    int fd = ::open64(module_name, O_RDONLY);
-    if (fd >= 0) {
+    // Return the file name, and then let elfutils decide what to do.
+    *file_name = ::strdup(module_name);
+    return -1;
+  } else {
+    // dwfl passes in the address of the Dwfl_Module user pointer
+    // contained within.  That pointer has been previously stuffed
+    // with our "userdata".
+    *elfp = elf_from_remote_memory (base, NULL, &read_proc_memory, *userdata);
+    if (*elfp != NULL) {
+      // Poke something into FILE_NAME so that the caller notices that
+      // we've done something to ELF.
       *file_name = ::strdup(module_name);
-      if (*file_name == NULL) {
-	::close(fd);
-	return ENOMEM;
-      }
     }
-    return fd;
-  } else {
-    /* Special case for in-memory ELF image.  */
-    fprintf(stderr, "wft does userdata %p get set? - perhaps it isn't called\n", *userdata);
-    proc_memory_context* context = (proc_memory_context*) *userdata;
-    *elfp = elf_from_remote_memory (base, NULL, &read_proc_memory, context);
     return -1;
   }
-  //abort ();
-  return -1;
 }
 
 jlong
-lib::dwfl::Dwfl::callbacksBegin(jnixx::env env, String jdebugInfoPath) {
+lib::dwfl::Dwfl::dwfl_userdata_begin(jnixx::env env,
+				     inua::eio::ByteBuffer memory) {
+  return (jlong) env.NewGlobalRef(memory._object);
+}
+
+void
+lib::dwfl::Dwfl::dwfl_userdata_end(jnixx::env env, jlong userdata) {
+  env.DeleteGlobalRef((jobject)userdata);
+}
+
+
+
+#define DWFL_CALLBACKS ((::Dwfl_Callbacks*)callbacks)
+
+jlong
+lib::dwfl::Dwfl::dwfl_callbacks_begin(jnixx::env env, String jdebugInfoPath) {
   jstringUTFChars debugInfoPath = jstringUTFChars(env, jdebugInfoPath);
   char** path = (char**) ::malloc(sizeof (char*));
   if (path == NULL) {
@@ -150,38 +156,49 @@ lib::dwfl::Dwfl::callbacksBegin(jnixx::env env, String jdebugInfoPath) {
 }
 
 void
-lib::dwfl::Dwfl::callbacksEnd(jnixx::env env, jlong callbacks) {
+lib::dwfl::Dwfl::dwfl_callbacks_end(jnixx::env env, jlong callbacks) {
   ::free(*DWFL_CALLBACKS->debuginfo_path);
   ::free(DWFL_CALLBACKS->debuginfo_path);
   ::free(DWFL_CALLBACKS);
 }
 
 jlong
-lib::dwfl::Dwfl::dwflBegin(jnixx::env env, jlong callbacks) {
+lib::dwfl::Dwfl::dwfl_begin(jnixx::env env, jlong callbacks) {
   return (jlong) ::dwfl_begin(DWFL_CALLBACKS);
 }
 
 void
-lib::dwfl::Dwfl::dwflEnd(jnixx::env env, jlong pointer) {
+lib::dwfl::Dwfl::dwfl_end(jnixx::env env, jlong pointer) {
   ::dwfl_end(DWFL_POINTER);
 }
 
 void
-lib::dwfl::Dwfl::reportBegin(jnixx::env env, jlong pointer) {
+lib::dwfl::Dwfl::dwfl_report_begin(jnixx::env env, jlong pointer) {
   ::dwfl_report_begin(DWFL_POINTER);
 }
 
 void
-lib::dwfl::Dwfl::reportEnd(jnixx::env env, jlong pointer) {
+lib::dwfl::Dwfl::dwfl_report_end(jnixx::env env, jlong pointer) {
   ::dwfl_report_end(DWFL_POINTER, NULL, NULL);
 }
 
 
 jlong
-lib::dwfl::Dwfl::reportModule(jnixx::env env, jlong pointer,
-			      String jmoduleName, jlong low, jlong high) {
+lib::dwfl::Dwfl::dwfl_report_module(jnixx::env env, jlong pointer,
+				    String jmoduleName, jlong low, jlong high,
+				    jlong userdata) {
   jstringUTFChars moduleName = jstringUTFChars(env, jmoduleName);
-  return (jlong) ::dwfl_report_module(DWFL_POINTER, moduleName.elements(),
-				      (::Dwarf_Addr) low,
-				      (::Dwarf_Addr) high);  
+  Dwfl_Module *module = ::dwfl_report_module(DWFL_POINTER,
+					     moduleName.elements(),
+					     (::Dwarf_Addr) low,
+					     (::Dwarf_Addr) high);
+  if (userdata != 0) {
+    // Get the address of the module's userdata, and store a global
+    // reference to memory in there.  The global ref is detroyed along
+    // with the Dwfl.
+    void **userdatap;
+    ::dwfl_module_info(module, &userdatap, NULL, NULL, NULL, NULL, NULL, NULL);
+    *userdatap = (void*)userdata;
+  }
+  return (jlong)module;
 }
diff --git a/frysk-sys/lib/dwfl/jni/DwflModule.cxx b/frysk-sys/lib/dwfl/jni/DwflModule.cxx
index 09092ce..d730d49 100644
--- a/frysk-sys/lib/dwfl/jni/DwflModule.cxx
+++ b/frysk-sys/lib/dwfl/jni/DwflModule.cxx
@@ -301,15 +301,6 @@ lib::dwfl::DwflModule::getSymbolByName(jnixx::env env, String jname,
   }
 }
 
-void
-lib::dwfl::DwflModule::setUserData(jnixx::env env, Object data) {
-  void **userdata = NULL;
-  fprintf(stderr, "user data is %p\n", userdata);
-  dwfl_module_info(DWFL_MODULE_POINTER_FIXME, &userdata, NULL, NULL, NULL, NULL, NULL,
-                   NULL);
-  *userdata = data._object;
-}
-
 /* 
  * Get the DebugInfo paths if present
  */
@@ -396,6 +387,24 @@ lib::dwfl::DwflModule::offdie(jnixx::env env, jlong die, jlong offset) {
   return dwarfDie;
 }
 
+void
+lib::dwfl::DwflModule::get_cu_dies(::jnixx::env env, jlong pointer,
+				   java::util::List list) {
+  Dwarf_Die* cu;
+  Dwarf_Addr bias;
+  cu = dwfl_module_nextcu(DWFL_MODULE_POINTER, NULL, &bias);
+    
+  while (cu != NULL) {
+    Dwarf_Die *die = (Dwarf_Die*)::malloc(sizeof(Dwarf_Die));
+    memcpy(die, cu, sizeof(*die));
+    lib::dwfl::DwarfDie cuDie
+      = lib::dwfl::DwarfDieFactory::getFactory(env).makeDie(env, (jlong)die, lib::dwfl::DwflModule(env, NULL));
+    cuDie.setManageDie(env, true);
+    list.add(env, cuDie);
+    cu = dwfl_module_nextcu(DWFL_MODULE_POINTER, cu, &bias);
+  }
+}
+
 jlong
 lib::dwfl::DwflModule::dwflModuleAddrdie(jnixx::env env, jlong pointer,
 					 jlong addr) {
diff --git a/frysk-sys/lib/unwind/ChangeLog b/frysk-sys/lib/unwind/ChangeLog
index 39bcd79..5e72c59 100644
--- a/frysk-sys/lib/unwind/ChangeLog
+++ b/frysk-sys/lib/unwind/ChangeLog
@@ -1,3 +1,9 @@
+2008-06-20  Andrew Cagney  <cagney@redhat.com>
+
+	* jni/UnwindH.hxx (access_mem): Catch Throwable and then use
+	instanceof to identify a UserException.
+	* cni/UnwindH.hxx (access_mem): Ditto.
+
 2008-05-26  Andrew Cagney  <cagney@redhat.com>
 
 	* jni/ElfImage.cxx: Delete.
diff --git a/frysk-sys/lib/unwind/cni/UnwindH.hxx b/frysk-sys/lib/unwind/cni/UnwindH.hxx
index 925b8af..1469bcd 100644
--- a/frysk-sys/lib/unwind/cni/UnwindH.hxx
+++ b/frysk-sys/lib/unwind/cni/UnwindH.hxx
@@ -62,6 +62,7 @@
 #include <java/lang/ArrayIndexOutOfBoundsException.h>
 
 #include "inua/eio/ByteBuffer.h"
+#include "frysk/UserException.h"
 #include "frysk/rsl/Log.h"
 #include "frysk/rsl/cni/Log.hxx"
 #include "lib/dwfl/Dwfl.h"
@@ -149,11 +150,15 @@ access_mem(::unw_addr_space_t as, ::unw_word_t addr,
 					   tmp, (jboolean) write);
     memcpy(valp, elements(tmp), JvGetArrayLength(tmp));
     return ret;
-  } catch (RuntimeException *t) {
-    // We have to catch all RuntimeExceptions here since there
-    // is no indicator for just "invalid memory location".
-    // Core files might have "holes" in their memory.
-    return -UNW_EINVAL;
+  } catch (Throwable *t) {
+    if (frysk::UserException::class$.isInstance(t)) {
+      // We have to catch all RuntimeExceptions here since there
+      // is no indicator for just "invalid memory location".
+      // Core files might have "holes" in their memory.
+      return -UNW_EINVAL;
+    } else {
+      throw t;
+    }
   }
 }
 
diff --git a/frysk-sys/lib/unwind/jni/UnwindH.hxx b/frysk-sys/lib/unwind/jni/UnwindH.hxx
index 3f42723..76e57b7 100644
--- a/frysk-sys/lib/unwind/jni/UnwindH.hxx
+++ b/frysk-sys/lib/unwind/jni/UnwindH.hxx
@@ -147,11 +147,15 @@ access_mem(::unw_addr_space_t as, ::unw_word_t addr,
     tmp.release();
     jtmp.DeleteLocalRef(env);
     return ret;
-  } catch (RuntimeException *t) {
-    // We have to catch all RuntimeExceptions here since there
-    // is no indicator for just "invalid memory location".
-    // Core files might have "holes" in their memory.
-    return -UNW_EINVAL;
+  } catch (Throwable t) {
+    if (t.IsInstanceOf(env, frysk::UserException::_class_(env))) {
+      // We have to catch all RuntimeExceptions here since there is no
+      // indicator for just "invalid memory location".  Core files
+      // might have "holes" in their memory.
+      return -UNW_EINVAL;
+    } else {
+      throw t;
+    }
   }
 }
 
diff --git a/htdocs/people/index.html b/htdocs/people/index.html
index c825940..81fd68f 100644
--- a/htdocs/people/index.html
+++ b/htdocs/people/index.html
@@ -147,6 +147,14 @@ Professional Experience Year Program.  </p>
 Technlogy Center. Currently contributes with PPC-related code to the
 Frysk Project. He also has contributions to GDB and binutils as well. </p>
 
+<h3>Teresa Thomas</h3>
+
+<p>Teresa is a Computer Engineering student at the University of Toronto, 
+currently working as an intern at Red Hat Canada Ltd. She has worked 
+on various aspects of Frysk's core, including the expression parser 
+and evaluator, high level watchpoint implementation, IEEE 754/854 
+floating point support and the DWARF location evaluator. </p>
+
 <h3>Sami Wagiaalla</h3>
 
 <p>Sami is an intern at Red Hat from the University of Alberta. He is