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 }