This is a small and primitive testbed program which demonstrates
how a quasi dynamic translation technique would work in plex86.

Code is not really dynamically generated here.  I just hand assembled
code which represents translated code as it might be generated.
This makes for a really simple testbed to play with various
ways of generating code to handle certain instructions.

In general, for the very simplistic type of dynamic translation
that we need, most generated code is simply passed through unmodified
from the guest code as it is scanned.  This is because our virtualization
environment sets up the descriptors so they can be used natively.

The only instructions that require any real translation, are those
that can examine certain CPU state (and thus possibly get the wrong
information because of changes due to virtualization), and those
that branch (because we wish to translate all code before it is executed).

Thus I only show some sample cases of generated (translated) code
for interesting cases.  You have to imagine there may be instructions
of pass-through code preceding these generated code sequences.
Or after, if the generated code is not a terminal (for example
conditional branches).


The files:


  main.c: Drives the rest of the code.  Inits a few variables, then
    jumps to the first piece of pseudo translated code.

  dt_sequences.S: Some sequences representing code that would be
    emitted by the dynamic translation engine.

  r3_handlers.c: Special ring3 handler functionality.  These would
    work in tandem with the generated code, focusing efforts in
    some central routines.

  dt.h: Header file for this code.


Some notes:

  - I coded the DT sequences, to preserve guest state including
    the stack, even for boundary cases like when the stack is at its
    limit.  Perhaps if we could make the assumption that we could
    safely use the guest stack (read...option), we could generate
    even more efficient code.

  - This is really just a user C program.  There would normally be
    a special Stack Segment for the handler code, but since we
    don't have one, I pretend there is one and reload it anyways
    to test the code, and even use a special handler stack
    page.

  - Translated code would be tagged with certain constraints.  When
    it is detected that code does not meet those constraints, the
    code area would be invalidated, or perhaps another one created.
    One constraint would be that it is valid only for the current
    attributes of the Code Segment which is being translated; base,
    limit, DPL, etc.  Also current CPL.  The generated code assumes
    the constraint of a given guest SS selector value.  Since we
    would then know what the SS value is, we don't have to save
    it before reloading to the handler stack, where the rest of
    the context is saved.  Otherwise, we have no guaranteed way
    to store the guest SS value, without using the stack itself.

  - Assume {DS,SS,ES,FS,GS} are virtualized segments which can
    be used natively.  CS:EIP while in ring3, always points into
    either dynamically translated code, or the special ring3 handlers.
    A logical initial place for translated code and handlers to live
    would be in the 4Meg monitor range (page table).  If we were
    careful, and gave ring3 RW access to only certain data pages
    and RO access to certain code pages, we could make the CS.base
    the same as the monitor CS.base.  This would allow us to run
    select C code in the monitor, but we have to be careful there,
    since ring3 code can not call lots of monitor functionality.
