Skip to content
  • David Johnson's avatar
    Refactor the target lib to remove arch and personality code from backends. · a98f4264
    David Johnson authored
    I split architecture-specific stuff out of backends (well, disasm is still
    all x86 and is not factored yet).  I added a generic register cache that
    contains initialized and dirty bits for each register.  It supports REGVAL-
    sized registers, as well as arbitrary-sized registers.  The regcache is
    linked to struct arch; it gets its register info from arch.  "info" includes
    stuff like how to display registers; how big a register's value is;
    DWARF translation info.  Right now we support x86 and x86_64, though I did
    start writing an ARMv8 header file that I didn't check in :).
    
    I also started the removal of personality-specific code from backends.  I
    completed the xen_vm backend; all that linux memory-walking code has moved
    to target_os_linux_generic.{h,c}).  The only linux-specific thing in there
    now is the attachment of the os_linux_generic OS personality.  Without a
    personality, the only thing the xen_vm backend knows about is whatever
    thread is running on the machine; and how to r/w phys mem; and how to
    r/w the current thread's registers and virt mem (if paging is enabled)...
    not that I have tested this case :).
    
    It was very difficult to get to a happy split between what the backend
    does, and what the personality does.  For instance, who loads the threads?
    The xen_vm target can only load whatever thread is on the CPU, and it
    can't make the assumption that Linux is running and thus decode the Linux
    structs to get all the threads.  So that is the personality's job.  BUT,
    the personality can't load the machine state.  There has to be a well-
    defined mix.
    
    Right now, it's like this.  A personality defines
    1) a struct target_personality_ops (basically a subset of the target_ops
    backend API) for the operations it can provide; and 2) a
    struct target_os (or in the future, target_process or target_application
    or target_runtime or ...) supporting personality-specific operations.
    
    If the backend doesn't provide an op, in some cases, the target API
    will try to call the corresponding personality op if possible.  If the
    backend *does* have the necessary op, that op is called -- and the
    backend must then call the matching personality op if it wants to
    support personalities.  This is all a bit hazy; but it is impossible
    to predict when a target backend can fill in the target model fully;
    or when a personality is necessary to "help" fill it in.  Basically,
    the limitation on personalities is that they don't get to handle
    things like exceptions.  There is still cleanup and completion work
    to do here, but this is the idea.
    
    The "personality-specific" ops are for implementing things like
    sending a signal to a process in an OS -- an OS-generic operation.
    I didn't fill in any more of these things yet; TBD.
    
    Finally, the most glaring hole is probably the xen_vm_process
    backend still assumes it is running atop a target that is running
    the os_linux_generic personality ;).  That is both complicated and
    easy to fix; but will have to wait until later.
    
    The biggest win is that this clears the way for 1) a kvm backend;
    2) arch independence; and 3) a generic linux personality that can
    apply equally to the Xen or KVM backends.
    a98f4264