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.

## Implementation notes on Instruction and Code observers

`Instruction` observers are what implement instruction stepping, `Code` observers are what implement low level instruction breakpoints.

Lets assume that we installed an `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.``

So we start at `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.

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 `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 (*).

When a Code observer is installed then the ptrace task states will all call `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.

All the logic of how to breakpoint step is contained in the `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).````

For stepping 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`.

In the case of `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.

When the `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(), the `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.

The `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).

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 `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 <href="http://sourceware.org/bugzilla/show_bug.cgi?id=4762">Frysk bug #4762. See there for updates. This means that in most cases we currently fall back to reset instruction stepping which has its own deficiency of not stopping other `Task`s which means breakpoints can and will be missed.