From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22582 invoked by alias); 19 Jun 2008 18:07:11 -0000 Received: (qmail 22206 invoked by uid 367); 19 Jun 2008 18:07:11 -0000 Date: Thu, 19 Jun 2008 18:07:00 -0000 Message-ID: <20080619180711.22172.qmail@sourceware.org> From: cagney@sourceware.org To: frysk-cvs@sourceware.org Subject: [SCM] master: Make memory accessable from all dwfl-modules. X-Git-Refname: refs/heads/master X-Git-Reftype: branch X-Git-Oldrev: 5c0013016a63729e15b30738625df8f21e1bfd51 X-Git-Newrev: bd2d28691caa79f3434474ae2bb1537b428aaf41 Mailing-List: contact frysk-cvs-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: frysk-cvs-owner@sourceware.org Reply-To: frysk@sourceware.org X-SW-Source: 2008-q2/txt/msg00382.txt.bz2 The branch, master has been updated via bd2d28691caa79f3434474ae2bb1537b428aaf41 (commit) from 5c0013016a63729e15b30738625df8f21e1bfd51 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit bd2d28691caa79f3434474ae2bb1537b428aaf41 Author: Andrew Cagney Date: Thu Jun 19 14:05:28 2008 -0400 Make memory accessable from all dwfl-modules. Rather than try to pick out the [vdso] map, just make the target's memory available from all Dwfl_Modules. frysk-core/frysk/dwfl/ChangeLog 2008-06-19 Andrew Cagney * DwflCache.java (getDwfl()): Pass the task's memory to the Dwfl and down to the native code, don't pass the vdso address. * DwflFactory.java (updateDwfl): Don't set the module's memory. frysk-sys/lib/dwfl/ChangeLog 2008-06-19 Andrew Cagney * DwflTestbed.java (createFromSelf()): Pass LocalMemory to the Dwfl. * cni/DwflModule.cxx (DwflModule::setUserData): Delete. * jni/DwflModule.cxx (DwflModule::setUserData): Delete. * Dwfl.java (Dwfl(String,ByteBuffer)): New. * DwflModule.java (setUserData(Object)): Delete. * jni/Dwfl.cxx: Update. * cni/Dwfl.cxx: Update. ----------------------------------------------------------------------- Summary of changes: frysk-core/frysk/dwfl/ChangeLog | 6 ++ frysk-core/frysk/dwfl/DwflCache.java | 2 +- frysk-core/frysk/dwfl/DwflFactory.java | 13 +---- frysk-sys/lib/dwfl/ChangeLog | 8 +++ frysk-sys/lib/dwfl/Dwfl.java | 38 ++++++++++---- frysk-sys/lib/dwfl/DwflModule.java | 7 ++- frysk-sys/lib/dwfl/DwflTestbed.java | 3 +- frysk-sys/lib/dwfl/cni/Dwfl.cxx | 41 ++++++++++----- frysk-sys/lib/dwfl/cni/DwflModule.cxx | 11 ---- frysk-sys/lib/dwfl/jni/Dwfl.cxx | 90 +++++++++++++++++++------------- frysk-sys/lib/dwfl/jni/DwflModule.cxx | 9 --- 11 files changed, 132 insertions(+), 96 deletions(-) First 500 lines of diff: diff --git a/frysk-core/frysk/dwfl/ChangeLog b/frysk-core/frysk/dwfl/ChangeLog index 542bf50..6ea8bf2 100644 --- a/frysk-core/frysk/dwfl/ChangeLog +++ b/frysk-core/frysk/dwfl/ChangeLog @@ -1,3 +1,9 @@ +2008-06-19 Andrew Cagney + + * DwflCache.java (getDwfl()): Pass the task's memory to the Dwfl + and down to the native code, don't pass the vdso address. + * DwflFactory.java (updateDwfl): Don't set the module's memory. + 2008-06-03 Andrew Cagney * DwflFactory.java (updateDwfl): Simplify by using Dwfl.mapBegin, diff --git a/frysk-core/frysk/dwfl/DwflCache.java b/frysk-core/frysk/dwfl/DwflCache.java index 15ffde3..4825f94 100644 --- a/frysk-core/frysk/dwfl/DwflCache.java +++ b/frysk-core/frysk/dwfl/DwflCache.java @@ -132,7 +132,7 @@ public class DwflCache { fine.log("creating new dwfl for task", task); File sysrootFile = (File)SysRootCache.getSysRoot(task); File relativeSysroot = getRelativeSysRoot(task.getProc().getExeFile().getSysRootedPath(), sysrootFile); - Dwfl dwfl = new Dwfl(relativeSysroot.getPath()); + Dwfl dwfl = new Dwfl(relativeSysroot.getPath(), task.getMemory()); DwflFactory.updateDwfl(dwfl, task); Mod mod = new Mod(dwfl, task.getMod()); modMap.put(task, mod); diff --git a/frysk-core/frysk/dwfl/DwflFactory.java b/frysk-core/frysk/dwfl/DwflFactory.java index 0f17713..eabb0c6 100644 --- a/frysk-core/frysk/dwfl/DwflFactory.java +++ b/frysk-core/frysk/dwfl/DwflFactory.java @@ -45,7 +45,6 @@ import frysk.proc.Proc; import frysk.proc.Task; import frysk.rsl.Log; import lib.dwfl.Dwfl; -import lib.dwfl.DwflModule; /** * Factory for creating Dwfl objects for Procs and Tasks. @@ -96,23 +95,15 @@ public class DwflFactory { static Dwfl updateDwfl(Dwfl dwfl, Task task) { Proc proc = task.getProc(); MemoryMap[] maps = proc.getMaps(); - long vdso = VDSOAddressLow(proc); - dwfl.mapBegin(vdso); + dwfl.mapBegin(); for (int i = 0; i < maps.length; i++) { MemoryMap map = maps[i]; dwfl.mapModule(map.name, map.addressLow, map.addressHigh, map.devMajor, map.devMinor, map.inode); } dwfl.mapEnd(); - DwflModule module = dwfl.getModule(vdso); fine.log("updateDwfl main task", proc.getMainTask(), - "memory", proc.getMainTask().getMemory(), - "dwfl module", module); - // XXX: Should this method instead have this block of memory - // pre-fetched and passed in? - if (module != null) { - module.setUserData(task.getMemory()); - } + "memory", proc.getMainTask().getMemory()); return dwfl; } } diff --git a/frysk-sys/lib/dwfl/ChangeLog b/frysk-sys/lib/dwfl/ChangeLog index 692ac0d..f9e9ea0 100644 --- a/frysk-sys/lib/dwfl/ChangeLog +++ b/frysk-sys/lib/dwfl/ChangeLog @@ -1,5 +1,13 @@ 2008-06-19 Andrew Cagney + * DwflTestbed.java (createFromSelf()): Pass LocalMemory to the Dwfl. + * cni/DwflModule.cxx (DwflModule::setUserData): Delete. + * jni/DwflModule.cxx (DwflModule::setUserData): Delete. + * Dwfl.java (Dwfl(String,ByteBuffer)): New. + * DwflModule.java (setUserData(Object)): Delete. + * jni/Dwfl.cxx: Update. + * cni/Dwfl.cxx: Update. + * Dwfl.java (mapModule): Correctly add maps such as [vdso]. * TestDwfl.java (testMapContainsVdso()): New. * DwflTestbed.java (VdsoBuilder): Delete. diff --git a/frysk-sys/lib/dwfl/Dwfl.java b/frysk-sys/lib/dwfl/Dwfl.java index cba6ede..ef77a05 100644 --- a/frysk-sys/lib/dwfl/Dwfl.java +++ b/frysk-sys/lib/dwfl/Dwfl.java @@ -43,25 +43,37 @@ import java.util.LinkedHashMap; import java.util.LinkedList; import frysk.rsl.Log; import inua.eio.ULong; +import inua.eio.ByteBuffer; public class Dwfl { private static final Log fine = Log.fine(Dwfl.class); private static final Log finest = Log.finest(Dwfl.class); + private long userdata; private long pointer; private long callbacks; protected final DwarfDieFactory factory = DwarfDieFactory.getFactory(); /** - * Create a dwfl with the specified debug-info search path. + * Create a dwfl with the specified debug-info search path and + * memory. + */ + public Dwfl(String debugInfoPath, ByteBuffer memory) { + callbacks = dwfl_callbacks_begin(debugInfoPath); + userdata = dwfl_userdata_begin(memory); + pointer = dwfl_begin(callbacks); + } + private static native long dwfl_callbacks_begin(String debugInfoSearchPath); + private static native long dwfl_userdata_begin(ByteBuffer memory); + private static native long dwfl_begin(long callbacks); + /** + * Create a dwfl with the specified debug-info search path and + * memory. */ public Dwfl(String debugInfoPath) { - callbacks = callbacksBegin(debugInfoPath); - pointer = dwflBegin(callbacks); + this(debugInfoPath, null); } - private static native long callbacksBegin(String debugInfoSearchPath); - private static native long dwflBegin(long callbacks); protected void finalize () { if (this.pointer != 0) { @@ -71,14 +83,16 @@ public class Dwfl { } public void close() { if (this.pointer != 0) { - dwflEnd(pointer); + dwfl_end(pointer); this.pointer = 0; - callbacksEnd(callbacks); + dwfl_userdata_end(userdata); + dwfl_callbacks_end(callbacks); this.callbacks = 0; } } - private static native void dwflEnd(long pointer); - private static native void callbacksEnd(long callbacks); + private static native void dwfl_end(long pointer); + private static native void dwfl_userdata_end(long userdata); + private static native void dwfl_callbacks_end(long callbacks); public DwflLine getSourceLine (long addr) { DwflModule module = getModule(addr); @@ -183,7 +197,8 @@ public class Dwfl { */ public void reportModule(String moduleName, long low, long high) { fine.log(this, "reportModule", moduleName, "low", low, "high", high); - long modulePointer = dwfl_report_module(pointer, moduleName, low, high); + long modulePointer = dwfl_report_module(pointer, moduleName, low, high, + userdata); for (int i = 0; i < modulesArray.length; i++) { DwflModule module = modulesArray[i]; if (module.getName().equals(moduleName) @@ -204,7 +219,8 @@ public class Dwfl { } private static native long dwfl_report_module(long pointer, String moduleName, - long low, long high); + long low, long high, + long userdata); private String name; private long low; diff --git a/frysk-sys/lib/dwfl/DwflModule.java b/frysk-sys/lib/dwfl/DwflModule.java index 01b728c..b73d3c6 100644 --- a/frysk-sys/lib/dwfl/DwflModule.java +++ b/frysk-sys/lib/dwfl/DwflModule.java @@ -66,7 +66,10 @@ public class DwflModule { public String toString() { - return name + " pointer: 0x" + Long.toHexString(pointer); + return name + + " 0x" + Long.toHexString(low) + + "..0x" + Long.toHexString(high) + + " pointer=0x" + Long.toHexString(pointer); } public long lowAddress() { @@ -133,8 +136,6 @@ public class DwflModule { public native void getSymbolByName(String name, SymbolBuilder symbolBuilder); - - public native void setUserData(Object data); /** * Get the debuginfo path for DwflModule diff --git a/frysk-sys/lib/dwfl/DwflTestbed.java b/frysk-sys/lib/dwfl/DwflTestbed.java index fdbad8d..3c931bf 100644 --- a/frysk-sys/lib/dwfl/DwflTestbed.java +++ b/frysk-sys/lib/dwfl/DwflTestbed.java @@ -39,6 +39,7 @@ package lib.dwfl; +import frysk.testbed.LocalMemory; import frysk.sys.proc.MapsBuilder; import frysk.sys.Pid; @@ -75,7 +76,7 @@ public class DwflTestbed { * Create a dwfl from this process. */ static Dwfl createFromSelf() { - Dwfl dwfl = new Dwfl(""); + Dwfl dwfl = new Dwfl("", LocalMemory.getByteBuffer()); ModuleBuilder maps = new ModuleBuilder(dwfl); dwfl.mapBegin(); maps.construct(Pid.get()); diff --git a/frysk-sys/lib/dwfl/cni/Dwfl.cxx b/frysk-sys/lib/dwfl/cni/Dwfl.cxx index b0e8ba5..167653d 100644 --- a/frysk-sys/lib/dwfl/cni/Dwfl.cxx +++ b/frysk-sys/lib/dwfl/cni/Dwfl.cxx @@ -115,10 +115,7 @@ dwfl_frysk_proc_find_elf (Dwfl_Module *mod, } else { - /* Special case for in-memory ELF image. */ - inua::eio::ByteBuffer * memory = (inua::eio::ByteBuffer *) *userdata; - - *elfp = elf_from_remote_memory (base, NULL, &read_proc_memory, memory); + *elfp = elf_from_remote_memory (base, NULL, &read_proc_memory, *userdata); return -1; } @@ -128,7 +125,16 @@ dwfl_frysk_proc_find_elf (Dwfl_Module *mod, } jlong -lib::dwfl::Dwfl::callbacksBegin(jstring debugInfoPath) { +lib::dwfl::Dwfl::dwfl_userdata_begin(inua::eio::ByteBuffer *memory) { + return (jlong)memory; +} + +void +lib::dwfl::Dwfl::dwfl_userdata_end(jlong userdata) { +} + +jlong +lib::dwfl::Dwfl::dwfl_callbacks_begin(jstring debugInfoPath) { char** path = (char**) JvMalloc(sizeof (char*)); int len = JvGetStringUTFLength(debugInfoPath); *path = (char*)JvMalloc(len + 1); @@ -145,19 +151,19 @@ lib::dwfl::Dwfl::callbacksBegin(jstring debugInfoPath) { } void -lib::dwfl::Dwfl::callbacksEnd(jlong callbacks) { +lib::dwfl::Dwfl::dwfl_callbacks_end(jlong callbacks) { JvFree(*DWFL_CALLBACKS->debuginfo_path); JvFree(DWFL_CALLBACKS->debuginfo_path); JvFree(DWFL_CALLBACKS); } jlong -lib::dwfl::Dwfl::dwflBegin(jlong callbacks) { +lib::dwfl::Dwfl::dwfl_begin(jlong callbacks) { return (jlong) ::dwfl_begin(DWFL_CALLBACKS); } void -lib::dwfl::Dwfl::dwflEnd(jlong pointer){ +lib::dwfl::Dwfl::dwfl_end(jlong pointer){ ::dwfl_end(DWFL_POINTER); } @@ -174,16 +180,25 @@ lib::dwfl::Dwfl::dwfl_report_end(jlong pointer) { jlong lib::dwfl::Dwfl::dwfl_report_module(jlong pointer, jstring moduleName, - jlong low, jlong high) { + jlong low, jlong high, jlong userdata) { jsize len = JvGetStringUTFLength(moduleName); char modName[len+1]; JvGetStringUTFRegion(moduleName, 0, len, modName); modName[len] = '\0'; - - return (jlong) ::dwfl_report_module(DWFL_POINTER, modName, - (::Dwarf_Addr) low, - (::Dwarf_Addr) high); + + Dwfl_Module* module = ::dwfl_report_module(DWFL_POINTER, modName, + (::Dwarf_Addr) low, + (::Dwarf_Addr) high); + if (userdata != 0) { + // Get the address of the module's userdata, and store a global + // reference to memory in there. The global ref is detroyed along + // with the Dwfl. + void **userdatap; + ::dwfl_module_info(module, &userdatap, NULL, NULL, NULL, NULL, NULL, NULL); + *userdatap = (void*)userdata; + } + return (jlong) module; } extern "C" int moduleCounter(Dwfl_Module *, void **, const char *, diff --git a/frysk-sys/lib/dwfl/cni/DwflModule.cxx b/frysk-sys/lib/dwfl/cni/DwflModule.cxx index 7f252bc..5d7a41a 100644 --- a/frysk-sys/lib/dwfl/cni/DwflModule.cxx +++ b/frysk-sys/lib/dwfl/cni/DwflModule.cxx @@ -340,17 +340,6 @@ lib::dwfl::DwflModule::getSymbolByName(jstring name, } } -void -lib::dwfl::DwflModule::setUserData(jobject data) -{ - void **userdata = NULL; - dwfl_module_info(DWFL_MODULE_POINTER, &userdata, NULL, NULL, NULL, NULL, NULL, - NULL); - - *userdata = data; - -} - /* * Get the DebugInfo paths if present */ diff --git a/frysk-sys/lib/dwfl/jni/Dwfl.cxx b/frysk-sys/lib/dwfl/jni/Dwfl.cxx index 60a3ed3..a04b9b8 100644 --- a/frysk-sys/lib/dwfl/jni/Dwfl.cxx +++ b/frysk-sys/lib/dwfl/jni/Dwfl.cxx @@ -70,34 +70,28 @@ extern "C" { // Assume the method was parameterised with POINTER. #define DWFL_POINTER ((::Dwfl *)pointer) -// Ditto for callbacks pointer. -#define DWFL_CALLBACKS ((::Dwfl_Callbacks*)callbacks) + -struct proc_memory_context { - jnixx::env env; - inua::eio::ByteBuffer memory; - proc_memory_context(jnixx::env env, inua::eio::ByteBuffer memory) { - this->env = env; - this->memory = memory; - } -}; +// Our data associated with the dwfl (well actually the Dwfl_Module). +// Need to make memory available so that, in the case of the vdso, it +// can be slurped from memory. static ssize_t -read_proc_memory(void *arg, void *data, GElf_Addr address, +read_proc_memory(void *userdata, void *data, GElf_Addr address, size_t minread, size_t maxread) { - fprintf(stderr, "wft does data %p get set? - perhaps it isn't called\n", - data); - proc_memory_context* context = (proc_memory_context*) arg; - jnixx::jbyteArray bytes - = jnixx::jbyteArray::NewByteArray(context->env, maxread); - ssize_t nread - = context->memory.safeGet(context->env, (off64_t) address, bytes, 0, - maxread); - jbyteArrayElements bytesp = jbyteArrayElements(context->env, bytes); + // Get the current thread's ENV; can't save it in dwfl_userdata + // since can't determine, ahead of time, which thread will call this + // code. + ::jnixx::env env = Object::_env_(); + ::inua::eio::ByteBuffer memory + = ::inua::eio::ByteBuffer(env, (jobject)userdata); + jnixx::jbyteArray bytes = jnixx::jbyteArray::NewByteArray(env, maxread); + ssize_t nread = memory.safeGet(env, (off64_t) address, bytes, 0, maxread); + jbyteArrayElements bytesp = jbyteArrayElements(env, bytes); memcpy(data, bytesp.elements(), nread); if (nread > 0 && (size_t) nread < minread) nread = 0; - bytes.DeleteLocalRef(context->env); + bytes.DeleteLocalRef(env); return nread; } @@ -123,18 +117,31 @@ dwfl_frysk_proc_find_elf(Dwfl_Module *mod, } return fd; } else { - /* Special case for in-memory ELF image. */ - fprintf(stderr, "wft does userdata %p get set? - perhaps it isn't called\n", *userdata); - proc_memory_context* context = (proc_memory_context*) *userdata; - *elfp = elf_from_remote_memory (base, NULL, &read_proc_memory, context); - return -1; + // dwfl passes in the address of the Dwfl_Module user pointer + // contained within. That pointer has been previously stuffed + // with our "userdata". + *elfp = elf_from_remote_memory (base, NULL, &read_proc_memory, *userdata); + return 0; } - //abort (); - return -1; } jlong -lib::dwfl::Dwfl::callbacksBegin(jnixx::env env, String jdebugInfoPath) { +lib::dwfl::Dwfl::dwfl_userdata_begin(jnixx::env env, + inua::eio::ByteBuffer memory) { + return (jlong) env.NewGlobalRef(memory._object); +} + +void +lib::dwfl::Dwfl::dwfl_userdata_end(jnixx::env env, jlong userdata) { + env.DeleteGlobalRef((jobject)userdata); +} + + + +#define DWFL_CALLBACKS ((::Dwfl_Callbacks*)callbacks) + +jlong +lib::dwfl::Dwfl::dwfl_callbacks_begin(jnixx::env env, String jdebugInfoPath) { jstringUTFChars debugInfoPath = jstringUTFChars(env, jdebugInfoPath); char** path = (char**) ::malloc(sizeof (char*)); if (path == NULL) { @@ -150,19 +157,19 @@ lib::dwfl::Dwfl::callbacksBegin(jnixx::env env, String jdebugInfoPath) { } void -lib::dwfl::Dwfl::callbacksEnd(jnixx::env env, jlong callbacks) { +lib::dwfl::Dwfl::dwfl_callbacks_end(jnixx::env env, jlong callbacks) { ::free(*DWFL_CALLBACKS->debuginfo_path); ::free(DWFL_CALLBACKS->debuginfo_path); ::free(DWFL_CALLBACKS); } jlong -lib::dwfl::Dwfl::dwflBegin(jnixx::env env, jlong callbacks) { +lib::dwfl::Dwfl::dwfl_begin(jnixx::env env, jlong callbacks) { return (jlong) ::dwfl_begin(DWFL_CALLBACKS); } void -lib::dwfl::Dwfl::dwflEnd(jnixx::env env, jlong pointer) { +lib::dwfl::Dwfl::dwfl_end(jnixx::env env, jlong pointer) { ::dwfl_end(DWFL_POINTER); } @@ -179,9 +186,20 @@ lib::dwfl::Dwfl::dwfl_report_end(jnixx::env env, jlong pointer) { jlong lib::dwfl::Dwfl::dwfl_report_module(jnixx::env env, jlong pointer, - String jmoduleName, jlong low, jlong high) { + String jmoduleName, jlong low, jlong high, + jlong userdata) { jstringUTFChars moduleName = jstringUTFChars(env, jmoduleName); - return (jlong) ::dwfl_report_module(DWFL_POINTER, moduleName.elements(), - (::Dwarf_Addr) low, - (::Dwarf_Addr) high); + Dwfl_Module *module = ::dwfl_report_module(DWFL_POINTER, + moduleName.elements(), + (::Dwarf_Addr) low, + (::Dwarf_Addr) high); + if (userdata != 0) { + // Get the address of the module's userdata, and store a global + // reference to memory in there. The global ref is detroyed along + // with the Dwfl. + void **userdatap; + ::dwfl_module_info(module, &userdatap, NULL, NULL, NULL, NULL, NULL, NULL); + *userdatap = (void*)userdata; + } + return (jlong)module; } diff --git a/frysk-sys/lib/dwfl/jni/DwflModule.cxx b/frysk-sys/lib/dwfl/jni/DwflModule.cxx index ca42e43..d730d49 100644 --- a/frysk-sys/lib/dwfl/jni/DwflModule.cxx +++ b/frysk-sys/lib/dwfl/jni/DwflModule.cxx @@ -301,15 +301,6 @@ lib::dwfl::DwflModule::getSymbolByName(jnixx::env env, String jname, } } -void -lib::dwfl::DwflModule::setUserData(jnixx::env env, Object data) { - void **userdata = NULL; - fprintf(stderr, "user data is %p\n", userdata); - dwfl_module_info(DWFL_MODULE_POINTER_FIXME, &userdata, NULL, NULL, NULL, NULL, NULL, - NULL); - *userdata = data._object; -} - /* * Get the DebugInfo paths if present */ hooks/post-receive -- frysk system monitor/debugger