public inbox for frysk-cvs@sourceware.org
help / color / mirror / Atom feed
From: cagney@sourceware.org
To: frysk-cvs@sourceware.org
Subject: [SCM]  master: Implement jni libunwind.
Date: Tue, 27 May 2008 02:06:00 -0000	[thread overview]
Message-ID: <20080527020659.2346.qmail@sourceware.org> (raw)

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


                 reply	other threads:[~2008-05-27  2:06 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080527020659.2346.qmail@sourceware.org \
    --to=cagney@sourceware.org \
    --cc=frysk-cvs@sourceware.org \
    --cc=frysk@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).