module: access-path-implementation synopsis: Implementation of functions for memory access author: Paul Howard Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND ///// Error constants. define constant $access-ok = 0; define constant $byte-count-mismatch = 1; define constant $access-violation-error = 2; ///// Page protection constants define constant $permitted = 1; define constant $unpermitted = 0; ///// define sealed abstract class () // The register is a handle on a descriptor for that register, // held within the nub. slot nub-descriptor :: , required-init-keyword: descriptor:; slot C-name :: , required-init-keyword: name:; // slot register-type :: , // required-init-keyword: type:; slot register-category :: , required-init-keyword: category:; end class; ///// define class () end class; ///// define class () slot thread :: , required-init-keyword: thread:; end class; ///// define class () end class; ///// define abstract class () end class; define class () end class; define method make (class == , #rest keys, #key, #all-keys) apply (make, , keys) end method; define constant $hacked-remote-type = make (); ///// define constant = type-union(, ); ///// EXPORTED GENERIC FUNCTIONS define generic do-registers (f :: , ap :: , #key type = #f) => (); define generic active-register (ap :: , thread :: , register :: ) => (_ :: ); define generic register-name (r :: ) => (_ :: ); define generic read-value (ap :: , address :: ) => (_ :: ); define generic write-value (ap :: , address :: , value :: ) => (_ :: ); ///// DO-REGISTERS define method do-registers (f :: , ap :: , #key type = #f) => () end method; ///// REGISTER-NAME define method register-name (r :: ) => (_ :: ) as (, r.C-name); end method; ///// ACTIVE-REGISTER define method active-register (ap :: , thread :: , register :: ) => (_ :: ) // Just create an instance whose attributes // are identical to the , and include the // thread. make (, name: register.C-name, category: register.register-category, descriptor: register.nub-descriptor, thread: thread); end method; ///// READ-VALUE define method read-value (ap :: , address :: ) => (_ :: ) 0; end method; define method read-value (ap :: , address :: ) => (_ :: ) ap.connection.process.memory.contents[address]; end method; ///// READ-BYTE-STRING define method read-byte-string (ap :: , address :: , length :: ) => (_ :: ) let s = make (, size: length); for (i from 0 below length) let cval = read-value (ap, indexed-remote-value (address, i)); s[i] := tagged-remote-value-as-character (cval); end for; s; end method; ///// WRITE-VALUE define method write-value (ap :: , address :: , value :: ) => (_ :: ) value; end method; define method write-value (ap :: , address :: , value :: ) => (_ :: ) ap.connection.process.memory.contents[address] := value; value; end method; ///// CALCULATE-STACK-ADDRESS define method calculate-stack-address (ap :: , thread :: , offset :: ) => (addr :: ) thread.nub-descriptor.esp + offset; end method; ///// REMOTE-VIRTUAL-PAGE-SIZE // Pants method define method remote-virtual-page-size (ap :: ) => (i :: ) 512 end method; ///// PAGE-RELATIVE-ADDRESS // Pants method define method page-relative-address (ap :: , addr :: ) => (page-num :: , offset :: ) truncate/(addr, 512); end method; ///// REMOTE-VALUE-BYTE-SIZE // Pants method. define method remote-value-byte-size (ap :: ) => (i :: ) 1 end method; ///// PERFORM-COFF-RELOCATION // Semi-kosher define method perform-coff-relocation (ap :: , ra :: , da :: , #key relative? = #f) let x = ap.connection.process.memory.contents[ra]; if (relative?) ap.connection.process.memory.contents[ra] := x + da; else ap.connection.process.memory.contents[ra] := (x + da) - ra; end if; end method;