public inbox for frysk-cvs@sourceware.org
help / color / mirror / Atom feed
From: pmuldoon@sourceware.org
To: frysk-cvs@sourceware.org
Subject: [SCM]  master: Implement top level interfaces. Test primary test case in TestWatchpoint. Add two modifications two stepping.handleTrappedEvent and running.handleTrappedEvent.
Date: Fri, 04 Apr 2008 14:38:00 -0000	[thread overview]
Message-ID: <20080404143840.17059.qmail@sourceware.org> (raw)

The branch, master has been updated
       via  dfa543f7189c681764596fc958a6d640a9558d46 (commit)
      from  1e6a205bbcbe119523df8e4a569a9aa3c9aa29b3 (commit)

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

- Log -----------------------------------------------------------------
commit dfa543f7189c681764596fc958a6d640a9558d46
Author: Phil Muldoon <pmuldoon@redhat.com>
Date:   Fri Apr 4 15:37:31 2008 +0100

    Implement top level interfaces. Test primary test case in TestWatchpoint. Add two modifications two stepping.handleTrappedEvent and running.handleTrappedEvent.
    
    2008-04-04  Phil Muldoon  <pmuldoon@redhat.com>
    
            * TestWatchpoint.java (testWatchpointTrigger): New.
            (WatchpointObserver): New.
            (TerminatedObserver): New.
            * WatchpointFunctionFactory.java (getWatchpointFunctions): Renamed from
            getWatchpoint.
            * TestWatchpoint: Update getWatchpoint -> getWatchpointFunctions.
    
    2008-04-04  Phil Muldoon  <pmuldoon@redhat.com>
    
            * LinuxPtraceProc.java (LinuxPtraceProc): Instatiate watchpoint
            address manager.
            (WatchpointAction): New. Install watchpoints.
            (requestAddWatchObserver): Implement.
            (requestDeleteWatchObserver): Ditto.
            * WatchpointAddresses.java (proc): Store a proc, not a task.
            (addWatchpoint): Take a length, and a write only flag.
            (removeWatchpoint): Ditto.
            (getWatchObservers): Ditto.
            (getWatchpoint): Ditto.
            * Watchpoint.java (Watchpoint): Take a task and a writeOnly flag.
            (create): Ditto
            (getLength): New.
            (isWriteOnly): New.
            (set): Actually set the watchpoint.
            (reset): Delete the watchpoint.
            * LinuxPtraceTaskState.java (Running.handleTrappedEvent): Add watchpoint
            catch/test.
            (Stepping.handleTrappedEvent): Ditto.

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

Summary of changes:
 frysk-core/frysk/isa/watchpoints/ChangeLog         |    9 ++
 .../frysk/isa/watchpoints/TestWatchpoint.java      |   87 +++++++++++++++++-
 .../isa/watchpoints/WatchpointFunctionFactory.java |    2 +-
 frysk-core/frysk/proc/live/ChangeLog               |   24 +++++-
 frysk-core/frysk/proc/live/LinuxPtraceProc.java    |   93 ++++++++++++++++++--
 .../frysk/proc/live/LinuxPtraceTaskState.java      |   34 +++++++-
 frysk-core/frysk/proc/live/Watchpoint.java         |   91 +++++++++++++------
 .../frysk/proc/live/WatchpointAddresses.java       |   40 ++++-----
 8 files changed, 315 insertions(+), 65 deletions(-)

First 500 lines of diff:
diff --git a/frysk-core/frysk/isa/watchpoints/ChangeLog b/frysk-core/frysk/isa/watchpoints/ChangeLog
index 33613b2..4d0e585 100644
--- a/frysk-core/frysk/isa/watchpoints/ChangeLog
+++ b/frysk-core/frysk/isa/watchpoints/ChangeLog
@@ -1,3 +1,12 @@
+2008-04-04  Phil Muldoon  <pmuldoon@redhat.com>
+
+	* TestWatchpoint.java (testWatchpointTrigger): New.
+	(WatchpointObserver): New.
+	(TerminatedObserver): New.
+	* WatchpointFunctionFactory.java (getWatchpointFunctions): Renamed from
+	getWatchpoint.
+	* TestWatchpoint: Update getWatchpoint -> getWatchpointFunctions.
+
 2008-04-03  Phil Muldoon  <pmuldoon@redhat.com>
 
 	* WatchpointFunctions.java (readStatusRegister): Declare.
diff --git a/frysk-core/frysk/isa/watchpoints/TestWatchpoint.java b/frysk-core/frysk/isa/watchpoints/TestWatchpoint.java
index db52a10..b6f516b 100644
--- a/frysk-core/frysk/isa/watchpoints/TestWatchpoint.java
+++ b/frysk-core/frysk/isa/watchpoints/TestWatchpoint.java
@@ -51,13 +51,92 @@ import lib.dwfl.ElfSymbolVisibility;
 import lib.dwfl.SymbolBuilder;
 import frysk.config.Config;
 import frysk.dwfl.DwflCache;
+import frysk.isa.signals.Signal;
+import frysk.proc.Action;
+import frysk.proc.Manager;
 import frysk.proc.Proc;
 import frysk.proc.Task;
+import frysk.proc.TaskObserver;
 import frysk.testbed.DaemonBlockedAtEntry;
 import frysk.testbed.TestLib;
+
 public class TestWatchpoint extends TestLib {
   
 
+    public void testWatchpointTrigger () {
+	if (unresolvedOnPPC(5991)) 
+	    return;
+	
+	DaemonBlockedAtEntry ackProc = new DaemonBlockedAtEntry(
+		Config.getPkgLibFile("funit-watchpoint"));
+	assertNotNull(ackProc);
+	
+	Proc proc = ackProc.getMainTask().getProc();
+	Task task = proc.getMainTask();
+	long address = getGlobalSymbolAddress(task,"source");
+	
+	WatchpointObserver wpo = new WatchpointObserver(address,4);
+	task.requestAddWatchObserver(wpo, address, 4, true);
+	assertRunUntilStop("Add Observer");
+	TerminatedObserver terminated = new TerminatedObserver();
+	task.requestAddTerminatedObserver(terminated);
+	assertRunUntilStop("Add Observer");
+	ackProc.requestUnblock();
+	assertRunUntilStop("Test");
+    }
+
+    static class WatchpointObserver 
+    	implements TaskObserver.Watch
+    {
+
+	long address;
+	int length;
+	
+	WatchpointObserver(long address, int length) {
+	    this.address = address;
+	    this.length = length;
+	    
+	}
+	public Action updateHit(Task task, long address, int length) {
+	    assertEquals("Triggered watchpoint address matches expected", this.address, address);
+	    assertEquals("Triggered watchpoint length matches expected", this.length, length);
+	    return Action.CONTINUE;
+	}
+
+	public void addFailed(Object observable, Throwable w) {
+	    fail("TaskOberer.Watch failed to be added to te task");
+	}
+
+	public void addedTo(Object observable) {
+	    Manager.eventLoop.requestStop();
+	}
+
+	public void deletedFrom(Object observable) {
+	}
+
+    }
+
+    static class TerminatedObserver 
+    	implements TaskObserver.Terminated
+    {
+
+	public void addFailed(Object observable, Throwable w) {
+	}
+
+	public void addedTo(Object observable) {
+	    Manager.eventLoop.requestStop();
+	}
+
+	public void deletedFrom(Object observable) {
+	}
+
+	public Action updateTerminated(Task task, Signal signal, int value) {
+	    Manager.eventLoop.requestStop();
+	    return Action.CONTINUE;
+	}
+
+    }
+
     public void testWatchFourBytesBitPattern() {
 	// Test Four byte bit pattern in a cumulative fasion
 	// across all WP registers. Assume global exact and 
@@ -69,7 +148,7 @@ public class TestWatchpoint extends TestLib {
 	Task task = proc.getMainTask();
 	long address = getGlobalSymbolAddress(task,"source");
 	long debugControlRegister;
-	WatchpointFunctions wp = WatchpointFunctionFactory.getWatchpoint(task.getISA());
+	WatchpointFunctions wp = WatchpointFunctionFactory.getWatchpointFunctions(task.getISA());
 	long savedDebugControlRegister = wp.readControlRegister(task);
 	for (int i=0; i<4; i++) {
 
@@ -122,7 +201,7 @@ public class TestWatchpoint extends TestLib {
 	Task task = proc.getMainTask();
 	long address = getGlobalSymbolAddress(task,"source");
 	long debugControlRegister;
-	WatchpointFunctions wp = WatchpointFunctionFactory.getWatchpoint(task.getISA());
+	WatchpointFunctions wp = WatchpointFunctionFactory.getWatchpointFunctions(task.getISA());
 	long savedDebugControlRegister = wp.readControlRegister(task);
 	for (int i=0; i<4; i++) {
 
@@ -177,7 +256,7 @@ public class TestWatchpoint extends TestLib {
 	Task task = proc.getMainTask();
 	long address = getGlobalSymbolAddress(task,"source");
 	long debugControlRegister;	
-	WatchpointFunctions wp = WatchpointFunctionFactory.getWatchpoint(task.getISA());
+	WatchpointFunctions wp = WatchpointFunctionFactory.getWatchpointFunctions(task.getISA());
 
 	long savedDebugControlRegister = wp.readControlRegister(task);
 
@@ -230,7 +309,7 @@ public class TestWatchpoint extends TestLib {
 	Proc proc = giveMeABlockedProc();
 	Task task = proc.getMainTask();
 	long address = getGlobalSymbolAddress(task,"source");
-	WatchpointFunctions wp = WatchpointFunctionFactory.getWatchpoint(task.getISA());
+	WatchpointFunctions wp = WatchpointFunctionFactory.getWatchpointFunctions(task.getISA());
 	for (int i=0; i<wp.getWatchpointCount(); i++) 
 	    wp.setWatchpoint(task, i, address, lengthSet[i], true);
 	
diff --git a/frysk-core/frysk/isa/watchpoints/WatchpointFunctionFactory.java b/frysk-core/frysk/isa/watchpoints/WatchpointFunctionFactory.java
index bf8211f..da434ce 100644
--- a/frysk-core/frysk/isa/watchpoints/WatchpointFunctionFactory.java
+++ b/frysk-core/frysk/isa/watchpoints/WatchpointFunctionFactory.java
@@ -52,7 +52,7 @@ public class WatchpointFunctionFactory {
 	.put(ISA.X8664, new X8664WatchpointFunctions())
 	;
 
-    public static WatchpointFunctions getWatchpoint(ISA isa) {
+    public static WatchpointFunctions getWatchpointFunctions(ISA isa) {
 	return (WatchpointFunctions) watchpointTables.get(isa);
     }
 }
diff --git a/frysk-core/frysk/proc/live/ChangeLog b/frysk-core/frysk/proc/live/ChangeLog
index fc1f503..2c1cacf 100644
--- a/frysk-core/frysk/proc/live/ChangeLog
+++ b/frysk-core/frysk/proc/live/ChangeLog
@@ -1,3 +1,25 @@
+2008-04-04  Phil Muldoon  <pmuldoon@redhat.com>
+
+	* LinuxPtraceProc.java (LinuxPtraceProc): Instatiate watchpoint
+	address manager.
+	(WatchpointAction): New. Install watchpoints.
+	(requestAddWatchObserver): Implement.
+	(requestDeleteWatchObserver): Ditto.
+	* WatchpointAddresses.java (proc): Store a proc, not a task.
+	(addWatchpoint): Take a length, and a write only flag.
+	(removeWatchpoint): Ditto.
+	(getWatchObservers): Ditto.
+	(getWatchpoint): Ditto.
+	* Watchpoint.java (Watchpoint): Take a task and a writeOnly flag.
+	(create): Ditto
+	(getLength): New.
+	(isWriteOnly): New.
+	(set): Actually set the watchpoint.
+	(reset): Delete the watchpoint.
+	* LinuxPtraceTaskState.java (Running.handleTrappedEvent): Add watchpoint
+	catch/test.
+	(Stepping.handleTrappedEvent): Ditto.
+
 2008-04-02  Phil Muldoon  <pmuldoon@redhat.com>
 
 	* LinuxPtraceProc.java (requestAddWatchObserver): Add writeOnly flag.
@@ -9,8 +31,6 @@
 	(WatchpointAction): Delete.
 	(requestAddWatchObserver): Delete private function.
 	(requestDeleteWatchObserver): Delete private function.
-	
-
 
 2008-03-31  Stan Cox  <scox@redhat.com>
 
diff --git a/frysk-core/frysk/proc/live/LinuxPtraceProc.java b/frysk-core/frysk/proc/live/LinuxPtraceProc.java
index 9f10c22..c4a6853 100644
--- a/frysk-core/frysk/proc/live/LinuxPtraceProc.java
+++ b/frysk-core/frysk/proc/live/LinuxPtraceProc.java
@@ -86,6 +86,7 @@ public class LinuxPtraceProc extends LiveProc {
 	this.newState = LinuxPtraceProcState.initial(false);
 	this.stat = stat;
 	this.breakpoints = new BreakpointAddresses(this);
+	this.watchpoints = new WatchpointAddresses(this);
 	((LinuxPtraceHost)host).addProc(this);
     }
 
@@ -97,6 +98,7 @@ public class LinuxPtraceProc extends LiveProc {
 	super(task, fork);
 	this.newState = LinuxPtraceProcState.initial(true);
 	this.breakpoints = new BreakpointAddresses(this);
+	this.watchpoints = new WatchpointAddresses(this);
 	((LinuxPtraceHost)getHost()).addProc(this);
     }
 
@@ -617,27 +619,105 @@ public class LinuxPtraceProc extends LiveProc {
     
 
     /**
-     * (Internal) Tell the process to add the specified Code
+     * Class describing the action to take on the suspended Task
+     * before adding or deleting a Code observer.
+     */
+    final class WatchpointAction implements Runnable {
+	private final TaskObserver.Watch watch;
+
+	private final Task task;
+
+	private final long address;
+	
+	private final int length;
+	
+	private final boolean writeOnly;
+	
+	private final boolean addition;
+
+	WatchpointAction(TaskObserver.Watch watch, Task task, long address,
+			 int length, boolean writeOnly, boolean addition) {
+	    this.watch = watch;
+	    this.task = task;
+	    this.address = address;
+	    this.addition = addition;
+	    this.length = length;
+	    this.writeOnly = writeOnly;
+
+	}
+
+	public void run() {
+	    if (addition) {
+		boolean mustInstall = watchpoints.addWatchpoint(watch, task, address, length, writeOnly);
+		if (mustInstall) {
+		    Watchpoint watchpoint;
+		    watchpoint = Watchpoint.create(address, length, writeOnly, task);
+		    watchpoint.install(task);
+		}
+	    } else {
+		boolean mustRemove = watchpoints.removeWatchpoint(watch, task, address, length, writeOnly);
+		if (mustRemove) {
+		    Watchpoint watchpoint;
+		    watchpoint = Watchpoint.create(address, length, writeOnly, task);
+		    watchpoint.remove(task);
+		}
+	    }
+	}
+    }
+
+    
+    /**
+     * (Internal) Tell the process to add the specified Watch
      * Observation, attaching to the process if necessary. Adds a
      * TaskCodeObservation to the eventloop which instructs the task
-     * to install the breakpoint if necessary.
+     * to install the watchpoint if necessary.
      */
-    void requestAddWatchObserver(Task task, TaskObservable observable,
+    void requestAddWatchObserver(final Task task, TaskObservable observable,
 				TaskObserver.Watch observer,
 				final long address,
 				final int length,
-				boolean writeOnly) {
+				final boolean writeOnly) {
+	fine.log(this, "requestAddWatchObserver");
+	WatchpointAction wpa = new WatchpointAction(observer, task, address, length, writeOnly, true);
+	TaskObservation to;
+	to = new TaskObservation((LinuxPtraceTask) task, observable, observer, wpa, true) {
+	    public void execute() {
+		handleAddObservation(this);
+	    }
+	    public boolean needsSuspendedAction() {
+		return watchpoints.getWatchObservers(task, address, length, writeOnly) == null;
+	    }
+	    };
+	Manager.eventLoop.add(to);
+
+    
     }
 
     /**
      * (Internal) Tell the process to delete the specified Code
      * Observation, detaching from the process if necessary.
      */
-    void requestDeleteWatchObserver(Task task, TaskObservable observable,
+    void requestDeleteWatchObserver(final Task task, TaskObservable observable,
 				   TaskObserver.Watch observer,
 				   final long address,
 				   final int length,
-				   boolean writeOnly)    {
+				   final boolean writeOnly)    {
+	
+	fine.log(this, "requestDeleteWatchObserver");
+	WatchpointAction wpa = new WatchpointAction(observer, task, address, length, writeOnly, false);
+	TaskObservation to;
+	to = new TaskObservation((LinuxPtraceTask)task, observable, observer, wpa, false) {
+		public void execute() {
+		    newState = oldState().handleDeleteObservation(LinuxPtraceProc.this, this);
+		}
+
+		public boolean needsSuspendedAction() {
+		    return watchpoints.getWatchObservers(task, address, length, writeOnly).size() == 1;
+		}
+	    };
+
+	Manager.eventLoop.add(to);
+
     }
 
     /**
@@ -756,6 +836,7 @@ public class LinuxPtraceProc extends LiveProc {
      * XXX: Should not be public.
      */
     public final BreakpointAddresses breakpoints;
+    public final WatchpointAddresses watchpoints;
     
     // List of available addresses for out of line stepping.
     // Used a lock in getOutOfLineAddress() and doneOutOfLine().
diff --git a/frysk-core/frysk/proc/live/LinuxPtraceTaskState.java b/frysk-core/frysk/proc/live/LinuxPtraceTaskState.java
index 07c9bd5..c08ff72 100644
--- a/frysk-core/frysk/proc/live/LinuxPtraceTaskState.java
+++ b/frysk-core/frysk/proc/live/LinuxPtraceTaskState.java
@@ -41,6 +41,8 @@ package frysk.proc.live;
 
 import frysk.sys.SignalSet;
 import frysk.sys.proc.Status;
+import frysk.isa.watchpoints.WatchpointFunctionFactory;
+import frysk.isa.watchpoints.WatchpointFunctions;
 import frysk.proc.TaskObserver;
 import frysk.proc.Observer;
 import frysk.proc.Observable;
@@ -942,9 +944,22 @@ abstract class LinuxPtraceTaskState extends State {
 	LinuxPtraceTaskState handleTrappedEvent(LinuxPtraceTask task) {
 	    fine.log("handleTrappedEvent", task);
 	  
+	    // First test if this is a watchpoint event.
+	    WatchpointFunctions watchpointFunction = WatchpointFunctionFactory.getWatchpointFunctions(task.getISA());
+	    for (int i=0; i<watchpointFunction.getWatchpointCount();  i++) {
+		// Test if a watchpoint has fired
+		if (watchpointFunction.hasWatchpointTriggered(task, i)) {
+		    frysk.isa.watchpoints.Watchpoint trigger = watchpointFunction.readWatchpoint(task, i);
+		    int blockers = task.notifyWatchpoint(trigger.getAddress(), trigger.getRange());
+		    if (blockers == 0)
+			return sendContinue(task, Signal.NONE);
+		    else
+			return blockedContinue;
+		}
+	    }
+
 	    Isa isa;
 	    isa = task.getIsaFIXME();
-
 	    // First see if this was just an indication the we stepped.
 	    // And see if we were stepping a breakpoint.  Or whether we
 	    // installed a breakpoint at the address.  Otherwise it is a
@@ -1062,7 +1077,22 @@ abstract class LinuxPtraceTaskState extends State {
 	 */
 	LinuxPtraceTaskState handleTrappedEvent(LinuxPtraceTask task) {
 	    fine.log("handleTrappedEvent", task);
-      
+
+	    // First test if this is a watchpoint event.
+	    WatchpointFunctions watchpointFunction = WatchpointFunctionFactory.getWatchpointFunctions(task.getISA());
+	    for (int i=0; i<watchpointFunction.getWatchpointCount();  i++) {
+		// Test if a watchpoint has fired
+		if (watchpointFunction.hasWatchpointTriggered(task, i)) {
+		    frysk.isa.watchpoints.Watchpoint trigger = watchpointFunction.readWatchpoint(task, i);
+		    int blockers = task.notifyWatchpoint(trigger.getAddress(), trigger.getRange());
+		    if (blockers == 0)
+			return sendContinue(task, Signal.NONE);
+		    else
+			return blockedContinue;
+		}
+	    }
+
+	    
 	    Isa isa;
 	    isa = task.getIsaFIXME();
       
diff --git a/frysk-core/frysk/proc/live/Watchpoint.java b/frysk-core/frysk/proc/live/Watchpoint.java
index 7915d84..86d1e00 100644
--- a/frysk-core/frysk/proc/live/Watchpoint.java
+++ b/frysk-core/frysk/proc/live/Watchpoint.java
@@ -40,7 +40,9 @@
 
 package frysk.proc.live;
 
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.Iterator;
 
 import frysk.proc.Task;
 
@@ -55,6 +57,7 @@ public class Watchpoint implements Comparable
   // These two fields define a Breakpoint
   private final long address;
   private final int length;
+  private final boolean writeOnly;
   private final Task task;
 
 
@@ -67,7 +70,7 @@ public class Watchpoint implements Comparable
    * Private constructor called by create to record address and
    * proc.
    */
-  private Watchpoint(long address, int length, Task task)
+  private Watchpoint(long address, int length, boolean writeOnly, Task task)
   {
     if (task == null)
       throw new NullPointerException("Cannot place a watchpoint when task == null.");
@@ -75,7 +78,7 @@ public class Watchpoint implements Comparable
     this.address = address;
     this.task = task;
     this.length = length;
-
+    this.writeOnly = writeOnly;
     if (this.length <= 0)
 	throw new RuntimeException("Watchpoint length has to be > 0");
   }
@@ -86,9 +89,9 @@ public class Watchpoint implements Comparable
    * host type. If a Breakpoint for this address and proc is already
    * installed that Breakpoint will be returned.
    */
-  public static Watchpoint create(long address, int length, Task task)
+  public static Watchpoint create(long address, int length, boolean writeOnly, Task task)
   {
-    Watchpoint watchpoint = new Watchpoint(address, length, task);
+    Watchpoint watchpoint = new Watchpoint(address, length, writeOnly, task);
 
     // If possible return an existing installed breakpoint.
     synchronized (installedWatchpoints)
@@ -105,6 +108,15 @@ public class Watchpoint implements Comparable
     return address;
   }
 
+  public int getLength()
+  {
+    return length;
+  }
+
+  public boolean isWriteOnly()
+  {
+    return writeOnly;
+  }
 
   /**
    * Installs breakpoint. Caller must make sure there is no breakpoint set
@@ -130,16 +142,28 @@ public class Watchpoint implements Comparable
    */
   private void set(Task task)
   {
-//      ByteBuffer buffer = ((LinuxPtraceTask)task).getRawMemory();
-//    Isa isa = ((LinuxPtraceTask)task).getIsaFIXME();
-//    Instruction bpInstruction = isa.getBreakpointInstruction();
-//    
-//    origInstruction = isa.getInstruction(buffer, address);
-//
-//    // Put in the breakpoint.
-//    byte[] bs = bpInstruction.getBytes();
-//    buffer.position(address);
-//    buffer.put(bs);
+      // XXX: Need a get empty watchpoint locator. It's a bit 
+      // much for the set() to find the empty watchpoint. Also
+      // question the value of optimizing at this point.
+      int watchpointIndex = -1;
+      frysk.isa.watchpoints.WatchpointFunctions wpf = 
+	  frysk.isa.watchpoints.WatchpointFunctionFactory.
+      		getWatchpointFunctions(task.getISA());
+      ArrayList watchpointList = (ArrayList) wpf.getAllWatchpoints(task);
+      Iterator i = watchpointList.iterator();
+      while (i.hasNext()) {
+	  frysk.isa.watchpoints.Watchpoint emptyTest = 
+	      ((frysk.isa.watchpoints.Watchpoint)i.next());
+	  if (emptyTest.getAddress() == 0) {
+	      watchpointIndex = emptyTest.getRegister();
+	      break;


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


                 reply	other threads:[~2008-04-04 14:38 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=20080404143840.17059.qmail@sourceware.org \
    --to=pmuldoon@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).