001 // This file is part of the program FRYSK.
002 //
003 // Copyright 2005, 2006, 2007, 2008, Red Hat Inc.
004 //
005 // FRYSK is free software; you can redistribute it and/or modify it
006 // under the terms of the GNU General Public License as published by
007 // the Free Software Foundation; version 2 of the License.
008 //
009 // FRYSK is distributed in the hope that it will be useful, but
010 // WITHOUT ANY WARRANTY; without even the implied warranty of
011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 // General Public License for more details.
013 //
014 // You should have received a copy of the GNU General Public License
015 // along with FRYSK; if not, write to the Free Software Foundation,
016 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
017 //
018 // In addition, as a special exception, Red Hat, Inc. gives You the
019 // additional right to link the code of FRYSK with code not covered
020 // under the GNU General Public License ("Non-GPL Code") and to
021 // distribute linked combinations including the two, subject to the
022 // limitations in this paragraph. Non-GPL Code permitted under this
023 // exception must only link to the code of FRYSK through those well
024 // defined interfaces identified in the file named EXCEPTION found in
025 // the source code files (the "Approved Interfaces"). The files of
026 // Non-GPL Code may instantiate templates or use macros or inline
027 // functions from the Approved Interfaces without causing the
028 // resulting work to be covered by the GNU General Public
029 // License. Only Red Hat, Inc. may make changes or additions to the
030 // list of Approved Interfaces. You must obey the GNU General Public
031 // License in all respects for all of the FRYSK code and other code
032 // used in conjunction with FRYSK except the Non-GPL Code covered by
033 // this exception. If you modify this file, you may extend this
034 // exception to your version of the file, but you are not obligated to
035 // do so. If you do not wish to provide this exception without
036 // modification, you must delete this exception statement from your
037 // version and license this file solely under the GPL without
038 // exception.
039
040 package frysk.proc;
041
042 import frysk.isa.syscalls.Syscall;
043 import frysk.isa.signals.Signal;
044
045 /**
046 * Observable events generated by a Task.
047 */
048
049 public interface TaskObserver
050 extends Observer
051 {
052 /**
053 * Interface used to notify of Task clone events.
054 */
055 public interface Cloned
056 extends TaskObserver
057 {
058 /**
059 * Called when the Task (the parent) has cloned, creating a
060 * clone Task (the offspring). Return Action.BLOCK if this
061 * observer wants the parent Task to block.
062 */
063 Action updateClonedParent (Task task, Task clone);
064 /**
065 * Called when the Task (the offspring) that was created by a
066 * fork has stopped at its first instruction.
067 */
068 Action updateClonedOffspring (Task parent, Task offspring);
069 }
070
071 /**
072 * Interface used to notify of Task forked (creating a new child
073 * process that contains one Task) events.
074 */
075 public interface Forked
076 extends TaskObserver
077 {
078 /**
079 * Called when the Task (the parent) has forked, creating a
080 * child Proc containing a single Task (the offspring).
081 * Return Action.BLOCK if the observer wants the parent task
082 * to block.
083 */
084 Action updateForkedParent (Task parent, Task offspring);
085 /**
086 * Called when the Task (the offspring) that was created by a
087 * fork has stopped at its first instruction.
088 */
089 Action updateForkedOffspring (Task parent, Task offspring);
090 }
091
092 /**
093 * Interface used to notify of a Task exec (overlaying the process
094 * image with that of a new program).
095 */
096 public interface Execed
097 extends TaskObserver
098 {
099 /**
100 * Called AFTER the Task has execed. Return Action.BLOCK if
101 * the observer wants the task to block.
102 */
103 Action updateExeced (Task task);
104 }
105
106 /**
107 * Interface used to notify of a Task that is terminating.
108 */
109 public interface Terminating extends TaskObserver {
110 /**
111 * Called while the Task is terminating; while the process
112 * still exists not much other than examining it can be
113 * performed. If SIGNAL is non-NULL it is the signal causing
114 * the termination, else STATUS is the exit value passed to
115 * _exit(2).
116 */
117 Action updateTerminating (Task task, Signal signal, int status);
118 }
119
120 /**
121 * Interface used to notify that Task has terminated (the task no
122 * longer exits).
123 */
124 public interface Terminated extends TaskObserver {
125 /**
126 * Called once the Task has terminated; the process no longer
127 * exists. If SIGNAL is non-NULL it is the signal causing the
128 * termination, else STATUS is the exit value passed to
129 * _exit(2).
130 */
131 Action updateTerminated(Task task, Signal signal, int value);
132 }
133
134 /**
135 * Interface used to notify that a Task has a pending signal.
136 */
137 public interface Signaled extends TaskObserver {
138 /**
139 * The SIGNAL is pending delivery to the task. Return
140 * Action.BLOCK to block the task's further execution.
141 *
142 * XXX: This gets weird. At present and in theory, a client
143 * wanting to discard a signal would need to sequence the
144 * following: tell the task to scrub discard the signal; tell
145 * the task to remove this observer from the set of blockers;
146 * return Action.BLOCK so that this task is added to the set
147 * of blockers. Perhaps it would be better to always add an
148 * observer to the blocker pool and then require explict
149 * removal.
150 */
151 Action updateSignaled(Task task, Signal signal);
152 }
153
154 /**
155 * Interface used to notify of a Task either entering, or exiting
156 * a system call.
157 */
158 public interface Syscalls extends TaskObserver {
159 /**
160 * The Task is entering a system call. Return Action.BLOCK to
161 * block the task's further execution.
162 */
163 Action updateSyscallEnter (Task task, Syscall syscall);
164 /**
165 * The task is exiting a system call. Return Action.BLOCK to
166 * block the task's further execution.
167 */
168 Action updateSyscallExit (Task task);
169 }
170
171 /**
172 * Interface used to notify that a Task has executed a single
173 * instruction. <code>updateExecuted</code> is called as soon as
174 * the Instruction observer is added to the Task. And whenever the
175 * Task starts running again (isn't blocked or suspended) it will
176 * be called on each instruction being executed.
177 * <p>
178 * This TaskObserver can also be used for executing code that
179 * needs the Task to be (temporarily) blocked or suspended as soon
180 * as possible. <code>updateExecuted()</code> will be called as
181 * soon as this observer has been properly added, and at that time
182 * the Task is suspended to make it possible to inspect the Task
183 * state. If no other action is request, the method can then just
184 * delete the observer from the Task again.
185 */
186 public interface Instruction
187 extends TaskObserver
188 {
189 /**
190 * The task has started executing or has executed another
191 * instruction. Return Action.BLOCK to block the task's
192 * further execution. When Action.CONTINUE is returned
193 * this method will be called as soon as one instruction
194 * has been executed.
195 */
196 Action updateExecuted (Task task);
197 }
198
199 /**
200 * Interface used to notify of a Task that the task's execution
201 * has reached a specific point in the code address space.
202 */
203 public interface Code
204 extends TaskObserver
205 {
206 /**
207 * The task has hit the breakpoint. Return Action.BLOCK to
208 * block the task's further execution. Note that all Tasks of
209 * a Proc share their breakpoints, so this method needs to
210 * check the actual Task that got hit.
211 */
212 Action updateHit (Task task, long address);
213 }
214
215 public interface Watch
216 extends TaskObserver
217 {
218 /**
219 * The task has hit the breakpoint. Return Action.BLOCK to
220 * block the task's further execution. Note that all Tasks of
221 * a Proc share their breakpoints, so this method needs to
222 * check the actual Task that got hit.
223 */
224 Action updateHit (Task task, long address, int length);
225 }
226 }