public inbox for frysk-cvs@sourceware.org
help / color / mirror / Atom feed
* [SCM]  master: Implement jni libunwind.
@ 2008-05-27  2:06 cagney
  0 siblings, 0 replies; only message in thread
From: cagney @ 2008-05-27  2:06 UTC (permalink / raw)
  To: frysk-cvs

The branch, master has been updated
       via  435b6331ffaa61dab0feb8e2c988f0f062ee96f3 (commit)
      from  ea1db5aa17cab4e9616eb07a86737d76560d6904 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit 435b6331ffaa61dab0feb8e2c988f0f062ee96f3
Author: Andrew Cagney <cagney@redhat.com>
Date:   Mon May 26 22:04:33 2008 -0400

    Implement jni libunwind.
    
    frysk-sys/ChangeLog
    2008-05-26  Andrew Cagney  <cagney@redhat.com>
    
    	* Makefile.am (JNIXX_CLASSES): Add UnwindRegistersX86 et.al.
    
    frysk-sys/lib/unwind/ChangeLog
    2008-05-26  Andrew Cagney  <cagney@redhat.com>
    
    	* jni/ElfImage.cxx: Delete.
    	* jni/UnwindH.hxx: Implement.
    	* jni/UnwindX86.cxx: Implement.
    	* jni/UnwindX8664.cxx: Implement.
    	* jni/UnwindPPC32.cxx: Implement.
    	* jni/UnwindPPC64.cxx: Implement.

-----------------------------------------------------------------------

Summary of changes:
 frysk-sys/ChangeLog                      |    2 +
 frysk-sys/Makefile.am                    |   18 +-
 frysk-sys/lib/unwind/ChangeLog           |    9 +
 frysk-sys/lib/unwind/jni/ElfImage.cxx    |   40 --
 frysk-sys/lib/unwind/jni/UnwindH.hxx     |  862 ++++++++++++++++++++++++++++++
 frysk-sys/lib/unwind/jni/UnwindPPC32.cxx |   12 +-
 frysk-sys/lib/unwind/jni/UnwindPPC64.cxx |   12 +-
 frysk-sys/lib/unwind/jni/UnwindX86.cxx   |   12 +-
 frysk-sys/lib/unwind/jni/UnwindX8664.cxx |   12 +-
 9 files changed, 922 insertions(+), 57 deletions(-)
 delete mode 100644 frysk-sys/lib/unwind/jni/ElfImage.cxx
 create mode 100644 frysk-sys/lib/unwind/jni/UnwindH.hxx

First 500 lines of diff:
diff --git a/frysk-sys/ChangeLog b/frysk-sys/ChangeLog
index 16a563b..08aad82 100644
--- a/frysk-sys/ChangeLog
+++ b/frysk-sys/ChangeLog
@@ -1,5 +1,7 @@
 2008-05-26  Andrew Cagney  <cagney@redhat.com>
 
+	* Makefile.am (JNIXX_CLASSES): Add UnwindRegistersX86 et.al.
+	
 	* Makefile.am (JniRunner): Load libdw and libelf.
 
 	* Makefile.am (JNIXX_CLASSES): Add DwAttributeNotFoundException,
diff --git a/frysk-sys/Makefile.am b/frysk-sys/Makefile.am
index 2e342ed..4efa836 100644
--- a/frysk-sys/Makefile.am
+++ b/frysk-sys/Makefile.am
@@ -79,6 +79,10 @@ JNIXX_CLASSES += frysk.sys.Errno$$Esrch
 JNIXX_CLASSES += lib.dwfl.DwAttributeNotFoundException
 JNIXX_CLASSES += java.lang.Long
 JNIXX_CLASSES += lib.dwfl.ElfException
+JNIXX_CLASSES += lib.unwind.UnwindRegistersPPC32
+JNIXX_CLASSES += lib.unwind.UnwindRegistersPPC64
+JNIXX_CLASSES += lib.unwind.UnwindRegistersX86
+JNIXX_CLASSES += lib.unwind.UnwindRegistersX8664
 \f
 
 # Quick hack to get a test JNI program up-and-running; as a package is
@@ -89,12 +93,24 @@ CLEANFILES += JniRunner
 JniRunner: | frysk-sys.jar libfrysk-sys-jni.so
 	rm -f $@.tmp
 	echo "#!/bin/sh"					>> $@.tmp
-	echo "export LD_PRELOAD=\"libstdc++.so.6 libdw.so libelf.so\"" >> $@.tmp
+	echo "export LD_PRELOAD=\"\\"				>> $@.tmp
+	echo "libstdc++.so.6 \\"				>> $@.tmp
+	echo "libdw.so \\"					>> $@.tmp
+	echo "libelf.so \\"					>> $@.tmp
+	echo "libunwind-x86.so \\"				>> $@.tmp
+	echo "libunwind-ppc32.so \\"				>> $@.tmp
+	echo "libunwind-ppc64.so \\"				>> $@.tmp
+	echo "libunwind-x86_64.so \\"				>> $@.tmp
+	echo "\"" >> $@.tmp
 	echo "# hack to hopefully find the right libstdc++.so"	>> $@.tmp
 	echo "export LD_LIBRARY_PATH=.\\"			>> $@.tmp
 	echo ":$$(cd ../frysk-imports/elfutils/libdw && pwd)\\"	>> $@.tmp
 	echo ":$$(cd ../frysk-imports/elfutils/libelf && pwd)\\" >> $@.tmp
 	echo ":$$(cd ../frysk-imports/elfutils/backends && pwd)\\" >> $@.tmp
+	echo ":$$(cd ../frysk-imports/libunwind-i386/src/.libs && pwd)\\" >> $@.tmp
+	echo ":$$(cd ../frysk-imports/libunwind-ppc32/src/.libs && pwd)\\" >> $@.tmp
+	echo ":$$(cd ../frysk-imports/libunwind-ppc64/src/.libs && pwd)\\" >> $@.tmp
+	echo ":$$(cd ../frysk-imports/libunwind-x86_64/src/.libs && pwd)\\" >> $@.tmp
 	echo ":/usr/lib64\\"			      	 	>> $@.tmp
 	echo ":/usr/lib"					>> $@.tmp
 	echo "export CLASSPATH=\\"				>> $@.tmp
diff --git a/frysk-sys/lib/unwind/ChangeLog b/frysk-sys/lib/unwind/ChangeLog
index d17582d..39bcd79 100644
--- a/frysk-sys/lib/unwind/ChangeLog
+++ b/frysk-sys/lib/unwind/ChangeLog
@@ -1,3 +1,12 @@
+2008-05-26  Andrew Cagney  <cagney@redhat.com>
+
+	* jni/ElfImage.cxx: Delete.
+	* jni/UnwindH.hxx: Implement.
+	* jni/UnwindX86.cxx: Implement.
+	* jni/UnwindX8664.cxx: Implement.
+	* jni/UnwindPPC32.cxx: Implement.
+	* jni/UnwindPPC64.cxx: Implement.
+
 2008-05-24  Andrew Cagney  <cagney@redhat.com>
 
 	* cni/UnwindH.hxx: Fix 32-bit type casts.
diff --git a/frysk-sys/lib/unwind/jni/ElfImage.cxx b/frysk-sys/lib/unwind/jni/ElfImage.cxx
deleted file mode 100644
index b358932..0000000
--- a/frysk-sys/lib/unwind/jni/ElfImage.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/lib/unwind/jni/UnwindH.hxx b/frysk-sys/lib/unwind/jni/UnwindH.hxx
new file mode 100644
index 0000000..3f42723
--- /dev/null
+++ b/frysk-sys/lib/unwind/jni/UnwindH.hxx
@@ -0,0 +1,862 @@
+// 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.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
+#include <libdwfl.h>
+#include LIBUNWIND_TARGET_H
+
+#include <libelf.h>
+#include <gelf.h>
+
+#include "jni.hxx"
+
+#include "jnixx/exceptions.hxx"
+#include "jnixx/logging.hxx"
+#include "jnixx/elements.hxx"
+#include "jnixx/bounds.hxx"
+
+using namespace java::lang;
+using namespace lib::unwind;
+
+#define UNW_PROC_INFO ((unw_proc_info_t*)unwProcInfo)
+#define UNW_ADDRESS_SPACE ((unw_addr_space_t)unwAddressSpace)
+#define UNW_CURSOR ((unw_cursor_t*)unwCursor)
+#define FINE env, (GetFine(env))
+
+#ifndef MAX_VDSO_SIZE
+# define MAX_VDSO_SIZE ((size_t) sysconf (_SC_PAGESIZE))
+#endif
+
+/**
+ * The address space is going to be accessed in different JNI contexts
+ * to when it is passed to libunwind.  Consequently, need to get the
+ * ENV from JNI and can't rely on it being passed in.
+ */
+#define UNW_CONTEXT \
+  jnixx::env env = Object::_env_();			\
+  AddressSpace addressSpace = AddressSpace(env, (jobject)contextArg)
+    
+
+/*
+ * Callback: Get misc. proc info
+ */
+static int
+find_proc_info(::unw_addr_space_t as, ::unw_word_t ip,
+	       ::unw_proc_info_t *pip, int need_unwind_info,
+	       void *contextArg) {
+  UNW_CONTEXT;
+  ProcInfo procInfo = ProcInfo::New(env,
+				    addressSpace.GetUnwinder(env),
+				    (long) ::malloc(sizeof(unw_proc_info_t)));
+  int ok = addressSpace.findProcInfo(env, (jlong)ip,
+				     (jboolean)need_unwind_info,
+				     procInfo);
+  if (ok < 0)
+    return ok;
+  // Extract the info.
+  memcpy(pip, (void*) procInfo.GetUnwProcInfo(env), sizeof (unw_proc_info_t));
+  procInfo.DeleteLocalRef(env);
+  return 0;
+}
+
+/*
+ * Callback: Free space allocated during find_proc_info
+ */
+static void
+put_unwind_info(::unw_addr_space_t as, ::unw_proc_info_t *proc_info,
+		void *contextArg) {
+  UNW_CONTEXT;
+  // This is passing up a stack pointer, which may then be freed.
+  ProcInfo procInfo = ProcInfo::New(env, addressSpace.GetUnwinder(env),
+				    (jlong) proc_info);
+  addressSpace.putUnwindInfo(env, procInfo);
+}
+
+/*
+ * Callback: Get the head of the dynamic unwind registration list.
+ * There is never any dynamic info in our case.
+ */
+static int
+get_dyn_info_list_addr(::unw_addr_space_t as, ::unw_word_t *dilap,
+		       void *contextArg) {
+  return -UNW_ENOINFO;
+}
+
+/*
+ * Callback: Perform memory read/write.  Implement as copy-in,
+ * copy-out.
+ */
+static int
+access_mem(::unw_addr_space_t as, ::unw_word_t addr,
+	   ::unw_word_t *valp, int write, void *contextArg) {
+  UNW_CONTEXT;
+  try {
+    jnixx::jbyteArray jtmp
+      = jnixx::jbyteArray::NewByteArray(env, sizeof(unw_word_t));
+    jbyteArrayElements tmp = jbyteArrayElements(env, jtmp);
+    memcpy(tmp.elements(), valp, sizeof(unw_word_t));
+    tmp.release();
+    int ret = addressSpace.accessMem(env, (jlong) addr,
+				     jtmp, (jboolean) write);
+    memcpy(valp, tmp.elements(), sizeof(unw_word_t));
+    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;
+  }
+}
+
+/*
+ * Callback: perform register read/write
+ */
+static int
+access_reg(::unw_addr_space_t as, ::unw_regnum_t regnum,
+	   ::unw_word_t *valp, int write, void *contextArg) {
+  UNW_CONTEXT;
+  jnixx::jbyteArray jtmp
+    = jnixx::jbyteArray::NewByteArray(env, sizeof(unw_word_t));
+  jbyteArrayElements tmp = jbyteArrayElements(env, jtmp);
+  // Map the REGNUM back to the published ENUM.
+  Number num = TARGET_REGISTERS::valueOf(env, regnum);
+  ::memcpy(tmp.elements(), valp, sizeof(unw_word_t));
+  tmp.release();
+  if (write)
+    addressSpace.setReg(env, num, *valp);
+  else
+    *valp = addressSpace.getReg(env, num);
+  num.DeleteLocalRef(env);
+  jtmp.DeleteLocalRef(env);
+  return 0;
+}
+
+/*
+ * Callback: Perform a floating point register read/write
+ */
+static int
+access_fpreg(::unw_addr_space_t as, ::unw_regnum_t regnum,
+	     ::unw_fpreg_t *fpvalp, int write, void *contextArg) {
+  UNW_CONTEXT;
+  jnixx::jbyteArray jtmp
+    = jnixx::jbyteArray::NewByteArray(env, sizeof (unw_fpreg_t));
+  jbyteArrayElements tmp = jbyteArrayElements(env, jtmp);
+  // Map the REGNUM back to the published ENUM.
+  Number num = TARGET_REGISTERS::valueOf(env, regnum);
+  // Implement read/modify/write style op.
+  ::memcpy(tmp.elements(), fpvalp, sizeof(unw_fpreg_t));
+  tmp.release();
+  int ret = addressSpace.accessReg(env, num, jtmp, (jboolean) write);
+  ::memcpy(fpvalp, tmp.elements(), sizeof(unw_fpreg_t));
+  tmp.release();
+  num.DeleteLocalRef(env);
+  jtmp.DeleteLocalRef(env);
+  return ret;
+}
+
+/*
+ * Callback: Resumes the process at the provided stack level.  We
+ * never resume a process through libunwind.
+ */
+static int
+resume(::unw_addr_space_t as, ::unw_cursor_t *cp, void *contextArg) {
+  return -UNW_EINVAL;
+}
+
+/*
+ * Callback: Returns the name of the procedure that the provided
+ * address is in as well as the offset from the start of the
+ * procedure.
+ */
+static int
+get_proc_name(::unw_addr_space_t as,
+	      ::unw_word_t addr, char *bufp,
+	      size_t buf_len, ::unw_word_t *offp, void *contextArg) {
+  // This should never be called, always return an error.
+  return -UNW_ENOMEM;
+}
+
+jlong
+TARGET::createCursor(jnixx::env env,
+		     AddressSpace addressSpace,
+		     jlong unwAddressSpace) {
+  logf(FINE, "createCursor from address-space %lx", (long) UNW_ADDRESS_SPACE);
+  jlong unwCursor = (jlong)::malloc(sizeof(::unw_cursor_t));
+  // XXX: Need to zero out the cursor, as unw_init_remote doesn't seem
+  // to do it.
+  memset(UNW_CURSOR, 0, sizeof(*UNW_CURSOR));
+  unw_init_remote(UNW_CURSOR, UNW_ADDRESS_SPACE, addressSpace._object);
+  logf(FINE, "createCursor at %lx", (long) UNW_CURSOR);
+  return (jlong) UNW_CURSOR;
+}
+
+void
+TARGET::destroyCursor(jnixx::env env, jlong unwCursor) {
+  logf(FINE, "destroyCursor at %lx", (long) UNW_CURSOR);
+  ::free(UNW_CURSOR);
+}
+
+jlong
+TARGET::createAddressSpace(jnixx::env env, ByteOrder byteOrder) {
+  logf(FINE, "createAddressSpace, byteOrder %d",
+       (int) byteOrder.hashCode(env));
+  static unw_accessors_t accessors = {
+    find_proc_info ,
+    put_unwind_info,
+    get_dyn_info_list_addr,
+    access_mem,
+    access_reg,
+    access_fpreg,
+    resume,
+    get_proc_name
+  };
+  jlong unwAddressSpace
+    = (jlong) unw_create_addr_space(&accessors, (int) byteOrder.hashCode(env));
+  logf(FINE, "createAddressSpace at %lx", (long)unwAddressSpace);
+  return unwAddressSpace;
+}
+
+void
+TARGET::destroyAddressSpace(jnixx::env env, jlong unwAddressSpace) {
+  logf(FINE, "destroyAddressSpace %lx", (long)UNW_ADDRESS_SPACE);
+  unw_destroy_addr_space(UNW_ADDRESS_SPACE);
+}
+
+void
+TARGET::setCachingPolicy(jnixx::env env, jlong unwAddressSpace,
+			 CachingPolicy cachingPolicy) {
+  log(FINE, "setCachingPolicy, cachingPolicy:", cachingPolicy);
+  unw_set_caching_policy(UNW_ADDRESS_SPACE,
+                         (unw_caching_policy_t) cachingPolicy.hashCode(env));
+}
+
+jint
+TARGET::isSignalFrame(jnixx::env env, jlong unwCursor) {
+  logf(FINE, "isSignalFrame");
+  return unw_is_signal_frame(UNW_CURSOR);
+}
+
+jint
+TARGET::step(jnixx::env env, jlong unwCursor) {
+  logf(FINE, "step cursor: %lx", (long) UNW_CURSOR);
+  return unw_step(UNW_CURSOR);
+}
+
+static void
+verifyBounds(jnixx::env env, jlong offset, jint length,
+	     jnixx::jbyteArray bytes, jint start, int size) {
+  verifyBounds(env, bytes, start, length);
+  if (offset < 0)
+    ArrayIndexOutOfBoundsException::New(env, offset).Throw(env);
+  if (offset + length > size)
+    ArrayIndexOutOfBoundsException::New(env, offset + length).Throw(env);
+}
+
+void
+TARGET::getRegister(jnixx::env env, jlong unwCursor,
+		    Number num, jlong offset, jint length,
+		    jnixx::jbyteArray jbytes, jint start) {
+  int regNum = num.intValue(env);
+  logf(FINE, "getRegister %d from %lx, offset %ld length %d start %d",
+       regNum, (long)UNW_CURSOR, (long) offset, (int)length, (int)start);
+  int status;
+  union {
+    unw_word_t w;
+    unw_fpreg_t fp;
+  } word;
+  int size;
+  if (unw_is_fpreg(regNum))
+    size = sizeof(word.fp);
+  else
+    size = sizeof(word.w);
+  verifyBounds(env, offset, length, jbytes, start, size);
+  if (unw_is_fpreg(regNum)) {
+    status = unw_get_fpreg(UNW_CURSOR,
+			   (::unw_regnum_t) regNum,
+			   &word.fp);
+  } else {
+    status = unw_get_reg(UNW_CURSOR,
+			 (::unw_regnum_t) regNum,
+			 &word.w);
+    logf(FINE, "getRegister status %d %lx", status, (long)word.w);
+  }
+  if (status != 0)
+    RuntimeException::ThrowNew(env, "get register failed");
+  jbyteArrayElements bytes = jbyteArrayElements(env, jbytes);
+  memcpy(bytes.elements() + start, (uint8_t*)&word + offset, length);
+}
+
+void
+TARGET::setRegister(jnixx::env env, jlong unwCursor,
+		    Number num,
+		    jlong offset, jint length,
+		    jnixx::jbyteArray jbytes, jint start) {
+  int regNum = num.intValue(env);
+  int status;
+  union {
+    unw_word_t w;
+    unw_fpreg_t fp;
+  } word;
+  int size;
+  if (unw_is_fpreg(regNum))
+    size = sizeof(word.fp);
+  else
+    size = sizeof(word.w);
+  verifyBounds(env, offset, length, jbytes, start, size);
+  if (unw_is_fpreg(regNum))
+    status = unw_get_fpreg(UNW_CURSOR, (::unw_regnum_t) regNum, &word.fp);
+  else
+    status = unw_get_reg(UNW_CURSOR, (::unw_regnum_t) regNum, &word.w);
+  if (status != 0)
+    RuntimeException::ThrowNew(env, "set register failed");
+  jbyteArrayElements bytes = jbyteArrayElements(env, jbytes);
+  memcpy((uint8_t*)&word + offset, bytes.elements() + start, length);
+  bytes.release();
+  if (unw_is_fpreg(regNum))
+    status = unw_set_fpreg(UNW_CURSOR, regNum, word.fp);
+  else
+    status = unw_set_reg(UNW_CURSOR, regNum, word.w);
+  if (status != 0)
+    RuntimeException::ThrowNew(env, "set register failed");
+}
+
+jlong
+TARGET::getSP(jnixx::env env, jlong unwCursor) {
+  unw_word_t sp;
+  int status = unw_get_reg(UNW_CURSOR, UNW_REG_SP, &sp);
+  if (status < 0)
+    return 0; // bottom of stack.
+  else
+    return sp;
+}


hooks/post-receive
--
frysk system monitor/debugger


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2008-05-27  2:06 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-05-27  2:06 [SCM] master: Implement jni libunwind cagney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).