|
||||||||||
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |
See:
Description
Interface Summary | |
---|---|
Isa | Instruction Set Architecture. |
Class Summary | |
---|---|
AddressSpaceByteBuffer | |
Breakpoint | Internal proc class that represents a Breakpoint at a certain address in a Proc. |
BreakpointAddresses | Keeps track of address breakpoints for a Proc (all Tasks of a Proc share the same breakpoints). |
BreakpointAddresses.CodeObserver | Small package private class holding Task and TaskObserver.Code interested in a particular breakpoint. |
IA32InstructionParser | |
IA32InstructionParser.Jump | |
Instruction | An architecture independent way of representing an assembly level instruction which is used for stepping and breakpoint insertion. |
IsaFactory | |
IsaPowerPC | |
LinuxIA32 | |
LinuxPPC32 | |
LinuxPPC64 | |
LinuxPtraceHost | A Linux Host tracked using PTRACE. |
LinuxPtraceProc | A Linux Proc tracked using PTRACE. |
LinuxPtraceProc.InstructionAction | Class describing the action to take on the suspended Task before adding or deleting an Instruction observer. |
LinuxPtraceProcState | A UNIX Process State |
LinuxPtraceProcState.Attaching | A process is being attached, this is broken down into sub-states. |
LinuxPtraceProcState.Attaching.ToMainTask | In the process of attaching, the main task has been sent an attach request. |
LinuxPtraceProcState.Attaching.ToOtherTasks | In the process of attaching, the main task is attached, now waiting for the remaining tasks to indicate they, too, have attached (or at least processed the attach request). |
LinuxPtraceProcState.Detaching | In the process of detaching; waiting for all tasks to report back that they have successfully detached. |
LinuxPtraceTask | A Linux Task tracked using PTRACE. |
LinuxPtraceTaskState | A Linux Task's State tracked using PTRACE. |
LinuxPtraceTaskState.Attached | The task is attached, and waiting to be either continued, or unblocked. |
LinuxPtraceTaskState.Attached.WaitForContinueOrUnblock | The blocked task has stopped, possibly with a pending signal, waiting on either a continue or an unblock. |
LinuxPtraceTaskState.Attached.WaitForUnblock | Got continue, just need to clear the blocks. |
LinuxPtraceTaskState.Attaching | The task is in the process of being attached. |
LinuxPtraceTaskState.BlockedSignal | The LinuxPtraceTask is blocked by a set of observers, remain in this state until all the observers have unblocked themselves. |
LinuxPtraceTaskState.Running | Keep the task running. |
LinuxPtraceTaskState.StartClonedTask | A cloned task just starting out, wait for it to stop, and for it to be unblocked. |
LinuxPtraceTaskState.StartMainTask | A new main Task, created via fork, just starting. |
LinuxPtraceTaskState.Stepping | |
LinuxPtraceTaskState.SyscallBlockedInSyscall | A task blocked after SyscallEnter notification or while runningInSyscall by an event other than syscalledEvent |
LinuxWaitBuilder | Handles wait events generated by the wait builder. |
LinuxX8664 | |
LiveHost | A live Host/Proc/Task is characterised by its stateful nature; i.e., an ability to respond to stateful requests such as add/remove observers. |
LiveProc | A live Host/Proc/Task is characterised by its stateful nature; i.e., an ability to respond to stateful requests such as add/remove observers. |
LiveTask | A live Host/Proc/Task is characterised by its stateful nature; i.e., an ability to respond to stateful requests such as add/remove observers. |
LogicalMemoryBuffer | MemorySpaceByteBuffer that filters out anything the frysk core might have done to the underlying memory. |
PtraceRegisterBanksFactory | The target has registers scattered across one or more register banks. |
RegisterSetByteBuffer | |
State | |
TaskObservable | Observable element of Task. |
TaskObservation | The binding between an Observer and its Observable. |
TestByteBuffer | |
TestProcStopped | |
TestRefresh | Check the host's refresh mechanism. |
TestRegs | Check all register values. |
TestRuntimeIsa | |
TestRuntimeIsa.AttachedObserver | |
TestTaskObserverBlocked | Check the behavior of an observer that blocks a Task's progress. |
TestTaskObserverCode | |
TestTaskObserverCode.AttachedObserver | |
TestTaskObserverCode.CodeObserver | |
TestTaskObserverCode.CountingCodeObserver | |
TestTaskObserverCode.RemovingCodeObserver | |
TestTaskObserverCode.SignaledObserver | |
TestTaskObserverCode.Symbol | |
Watchpoint | Internal proc class that represents a Breakpoint at a certain address in a Proc. |
WatchpointAddresses | Keeps track of address watchppoints for a Proc (all Tasks of a Proc share the same breakpoints). |
X8664InstructionParser |
This is a frysk implementation package that provides the implementation of frysk.proc for ptrace based (GNU/Linux) systems. Normally none of these implementation details are needed for normal use of frysk-core and the public classes of frysk.proc should be used.
Instruction
observers are what implement instruction
stepping, Code
observers are what implement low level
instruction breakpoints.
Lets assume that we installed an
So we start at
If the Task made its step then we will get a TrappedEvent. Here things
get a little messy since ptrace/wait uses trap events for signaling
almost everything. Luckily the
When a Code observer is installed then the ptrace task states will all
call
All the logic of how to breakpoint step is contained in the
For stepping the
In the case of
When the
The
Deficiencies of the Instruction Parser. The framework is in
place and works for the few Instructions that are known to the
instruction parser, but there are all hand coded (see
InstructionObserver
, the
Task
stopped notified the observer which decided that the
Task
needed to be blocked which turned the
TaskState
into BlockedSignal
. If you are
interested in what would happen while stepping and the
Task
not being blocked already, start reading from (*)
and assume we are in the Running
state and just want to
continue running the task after some event happened.
Task.unblock(InstructionObserver)
which
will notify the BlockedSignal
state class in
LinuxTaskState
. The handleUnblock()
method
will be triggered. Depending on which observers are actually
installed (and whether all blocking observer have been cleared now) a
Running
TaskState
is determined and
sendContinue(task, sig)
is called on that
Running
state (the Running
state class is
also defined inside the LinuxTaskState
).
sendContinue()
is an instance method of the
Running
TaskState
class which will return
the appropriate Running subclass/instance depending on how the
Task
continues. If an Instruction
observer
(or the task is currently at a breakpoint, see below) then
LinuxTask.sendStepInstruction
code is called and
sendContinue
will return Stepping
(which is
a subclass of Running
) as the new state of the Task.
sendStepInstruction()
will do some bookkeeping to
remember which signal number was requested and whether or not the Task
is currently at a signal return instruction. We need to do that here
so we know what we were doing when we get a callback from the kernel
after the step. Then the appropriate ptrace command is invoked so the
Task is doing the actual step. Some, but not all (signal number and
sigret in particular) this is contained as state in the
Stepping
task state instance.
Isa
should be able to tell
us if the current Task
just did an instruction step. If
it did (and it isn't a breakpoint address in which case we need to do
some extra things) then we inform all Instruction
observers and if any of them tells us to Block then we move into the
BlockedSignal state, otherwise we keep in the Stepping
state and continue from (*).
setupSteppingBreakpoint()
after a breakpoint hit has
been detected, which makes sure the PC is setup correctly (which can
be off by one on some architectures after a breakpoint) and then mark
the Task
as being at that particular breakpoint (this is
still kept as Task field for now). We need to always do the adjustment
immediately in case the user decides to move to a Blocked
state instead of of continuing the Task
. When
Running.sendContinue
is later called it will depend on
this fact.
Breakpoint
class that checks the properties of the
Instruction
class object which is created by the
Isa
through an instruction parser before the breakpoint
is inserted at a given location. An Instruction
knows how
long the instruction is, which bytes it represents, whether it can be
single stepped out of line and how to set that up given the original
pc location and an alternative address, plus any fixups that are
needed to the Task afterwards (and it has a notion of whether or not
the Instruction
can be simulated, but that isn't
currently used, see below). A Breakpoint
ties an
Instruction
to a particular address and Proc
(and Task
s can have zero or more
Breakpoint
s, they share the same Breakpoint
on the same address with other Task
s of a
Proc
and when no Task
s of a
Proc
has an Breakpoint
at a particular
address anymore the
Breakpoint
is removed).
, the Breakpoint
the
Running.sendContinue()
method first calls
Breakpoint.prepareStep()
, then signals ptrace to do a
single step of the Task
, putting the Task
in
Stepping
state and then in handleTrapEvent()
calls Breakpoint.stepDone()
. prepareStep()
queries the capabilities of the Instruction
at the pc
address and depending on that either sets things up for doing a step
out of line, simulate the instruction (but none of the current
Instruction
s have been setup to do simulation yet, and
look at the comment in prepareStep()
to see what is
needed to fully enable this option) or reset the current
Instruction
(removing the breakpoint instruction
temporarily). Accordingly a Breakpoint can be in the state
NOT_STEPPING
, OUT_OF_LINE_STEPPING
,
SIMULATE_STEPPING
or RESET_STEPPING
.
RESET_STEPPING
other Tasks might miss and
just past the Breakpoint during the brief period between the reset,
step and reinstall. Breakpoint prepareStep()
just takes
the Instruction bytes and puts them at the current pc address, and
doneStep()
reinstates the breakpoint instruction. The
right solution here would be to stop all other Tasks first, step and
then continue them all.
Instruction
supports single step out of line
then the Breakpoint
requests an address in the single
step out of line area of the Proc
, instructs the
Instruction
to install itself there for the current Task
calling Instruction.setupExecuteOutOfLine()
. The default
action of setupExecuteOutOfLine()
is to set the pc to the
given address and place a copy the instruction bytes there (although
this can be overridden if an Instruction
wants to do
something more fancy). When the task signals the
Breakpoint
that a step was taken by calling
,code>stepDone()Breakpoint
calls
Instruction.fixupExecuteOutOfLine()
with the original pc
and replacement address so any adjustments can be done to the
Task
registers. The default action is to just set the pc
to the original pc plus the length of the Instruction
just stepped. But Instructions can override that if more is needed. As
an example the RET
instruction doesn't do any fixup
(since the only action is setting the pc to the right location in the
first place) and the JMP
instruction sets the pc to
original pc plus/minus the difference of the alternate address and the
pc after the single step. Afterward the Breakpoint
returns the used address to the Proc
so it can be used by
other Task
s needing to do a single step out of line.
Proc
maintains a single step out of line area pool of
addresses that point to locations that are at least as big is the
largest instruction of the instruction set. The Proc
gets
this list from the Isa
the first time an address is
requested through getOutOfLineAddress()
. Currently this
is just the address of the main function entry point (see below). The
address is taken out of the pool and the Breakpoint
is
responsible for putting it back through doneOutOfLine
(see above). If no address is currently available the call blocks till
one is available (this was way easier than inventing yet another
TaskState
and getting the communication between
Proc
and Task
about this right, and
contention is very low and at the longest it takes for an address to
become available is one instruction single step).
IA32InstructionParser
which just handles
NOP
, INT3
, RETQ
and one
JMP
variant, the X8664Instruction
just
delegates to the IA32 for now). There don't seem to be libraries
available to easily plugin that would give us the fixup instructions
needed. The best available is the kprobes examples from the linux
kernel which have as drawback that they are coded to be intimately
tied to the kernel/C way of doing things and only seem handles
instructions found in kernel space (no robust instruction parsing,
just a instruction bits/lookup table).appreciated. So we need to sit
down with the various instruction manuals and just code it up by hand
if we cannot find an existing library. (Bonus points for finding
something that would not just give us ssol fixups but also simulation
of instructions when hooked to the registers and memory of a Task.)
This is
Task
s which means
breakpoints can and will be missed.
Overview
Package
Class
Use
Tree
Deprecated
Index
Help
PREV PACKAGE
NEXT PACKAGE
FRAMES
NO FRAMES