module: remote-access-path synopsis: Functions for looking up remote symbols author: Paul Howard, Nosa Omo 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 ///// NEAREST-SYMBOLS-FROM-NUB define method nearest-symbols-from-nub (conn :: , address :: ) => (any-luck? :: , where-is-it? :: , gimme-handle :: ) // Wraps up the debugger nub function which does a brute-force // search in the debug map for the three nearest symbols and // constructs an opaque lookup table which is passed back later // to get information about the symbols. let worked = #f; let (success, lib :: , table :: ) = Rtmgr/RemoteNub/nearest-symbols(conn.nub, as-integer(address)); if (success = 1) worked := #t end if; values (worked, as-remote-pointer(lib), as-remote-pointer(table)); end method; ///// COLLECT-NEAREST-SYMBOLS define method collect-nearest-symbols (conn :: , lib :: , lookups :: ) => (closest :: , prev :: , nxt :: ) // For nearest-symbols, the nub creates a quick lookup table with // three entries: 1. The nearest symbol, 2. The closest symbol // preceeding the nearest, 3. The closest symbol following the // nearest (in that order). // Pull nub information for the nearest symbol, and make a // object to represent it. // Symbol #1 is the closest let lookups = as-integer(lookups); let addr1 :: = Rtmgr/RemoteNub/lookup-symbol-address (conn.nub, lookups, 1); let is-func1 = Rtmgr/RemoteNub/symbol-is-function (conn.nub, lookups, 1); let sym1 = #f; let name1 = Rtmgr/RemoteNub/lookup-symbol-name(conn.nub, lookups, 1); let lang1 = classify-symbolic-name(conn, name1); if (is-func1 == 1) let debug-start :: = Rtmgr/RemoteNub/lookup-function-debug-start(conn.nub, lookups, 1); let debug-end :: = Rtmgr/RemoteNub/lookup-function-debug-end(conn.nub, lookups, 1); let last-addr :: = Rtmgr/RemoteNub/lookup-function-end(conn.nub, lookups, 1); sym1 := make (, name: name1, address: as-remote-value(addr1), language: lang1, library: lib, debug-start: as-remote-value(debug-start), debug-end: as-remote-value(debug-end), absolute-end: as-remote-value(last-addr)); else sym1 := make (, name: name1, address: as-remote-value(addr1), language: lang1, library: lib); end if; let addr2 :: = Rtmgr/RemoteNub/lookup-symbol-address (conn.nub, lookups, 2); let is-func2 = Rtmgr/RemoteNub/symbol-is-function (conn.nub, lookups, 2); let sym2 = #f; let name2 = Rtmgr/RemoteNub/lookup-symbol-name(conn.nub, lookups, 2); let lang2 = classify-symbolic-name(conn, name2); if (is-func2 == 1) let debug-start :: = Rtmgr/RemoteNub/lookup-function-debug-start(conn.nub, lookups, 2); let debug-end :: = Rtmgr/RemoteNub/lookup-function-debug-end(conn.nub, lookups, 2); let last-addr :: = Rtmgr/RemoteNub/lookup-function-end(conn.nub, lookups, 2); sym2 := make (, name: name2, address: as-remote-value(addr2), language: lang2, library: lib, debug-start: as-remote-value(debug-start), debug-end: as-remote-value(debug-end), absolute-end: as-remote-value(last-addr)); else sym2 := make (, name: name2, address: as-remote-value(addr2), language: lang2, library: lib); end if; let addr3 :: = Rtmgr/RemoteNub/lookup-symbol-address (conn.nub, lookups, 3); let is-func3 = Rtmgr/RemoteNub/symbol-is-function (conn.nub, lookups, 3); let sym3 = #f; let name3 = Rtmgr/RemoteNub/lookup-symbol-name(conn.nub, lookups, 3); let lang3 = classify-symbolic-name(conn, name3); if (is-func3 == 1) let debug-start :: = Rtmgr/RemoteNub/lookup-function-debug-start(conn.nub, lookups, 3); let debug-end :: = Rtmgr/RemoteNub/lookup-function-debug-end(conn.nub, lookups, 3); let last-addr :: = Rtmgr/RemoteNub/lookup-function-end(conn.nub, lookups, 3); sym3 := make (, name: name3, address: as-remote-value(addr3), language: lang3, library: lib, debug-start: as-remote-value(debug-start), debug-end: as-remote-value(debug-end), absolute-end: as-remote-value(last-addr)); else sym3 := make (, name: name3, address: as-remote-value(addr3), language: lang3, library: lib); end if; values (sym1, sym2, sym3); end method; ///// FIND-SYMBOL-IN-LIBRARY define method find-symbol-in-library (conn :: , lib :: , name :: ) => (maybe-sym :: false-or()) let (found, address :: , type, is-func, debug-start :: , debug-end :: , lang, lasta :: ) = Rtmgr/RemoteNub/find-symbol-in-library (conn.nub, lib.rnub-descriptor, size(name), name); if (found == 1) if (is-func == 1) make (, name: name, address: as-remote-value(address), language: classify-symbolic-name(conn, name), library: lib, debug-start: as-remote-value(debug-start), debug-end: as-remote-value(debug-end), absolute-end: as-remote-value(lasta)); else make (, name: name, address: as-remote-value(address), language: classify-symbolic-name(conn, name), library: lib); end if; else #f end if end method; ///// SYMBOL-RELATIVE-ADDRESS define method symbol-relative-address-on-connection (conn :: , path :: , address :: ) => (sym-if-found :: false-or(), offset :: ) // Call the debugger nub. let (foundit :: , lib :: , addr :: , offset :: , name-length :: , type :: , is-function :: , debug-start :: , debug-end :: , language :: , last-address :: ) = Rtmgr/RemoteNub/closest-symbol(conn.nub, as-integer(address)); if (foundit == 1) let lib = as-remote-pointer(lib); let addr = as-remote-value(addr); let debug-start = as-remote-value(debug-start); let debug-end = as-remote-value(debug-end); let last-address = as-remote-value(last-address); let remote-lib = find-or-make-library(path, lib); let sym = #f; let sym-name = Rtmgr/RemoteNub/closest-symbol-name(conn.nub, name-length); let language-classification = classify-symbolic-name(conn, sym-name); if (is-function == 1) sym := make(, name: sym-name, address: addr, library: remote-lib, language: language-classification, debug-start: debug-start, debug-end: debug-end, absolute-end: last-address); else sym := make(, name: sym-name, address: addr, library: remote-lib, language: language-classification); end if; values(sym, offset); else values(#f, 0); end if end method; ///// FUNCTION-BOUNDING-ADDRESSES define method function-bounding-addresses-on-connection (conn :: , address :: ) => (lowerbound :: , upperbound :: ) let (lowerbound, upperbound) = Rtmgr/RemoteNub/function-bounding-addresses(conn.nub, as-integer(address)); values(as-remote-value(lowerbound), as-remote-value(upperbound)); end method;