diff -up frysk-0.4/frysk-sys/lib/dwfl/cni/Dwfl.cxx.noelfmem frysk-0.4/frysk-sys/lib/dwfl/cni/Dwfl.cxx
--- frysk-0.4/frysk-sys/lib/dwfl/cni/Dwfl.cxx.noelfmem 2010-03-25 11:41:04.000000000 -0400
+++ frysk-0.4/frysk-sys/lib/dwfl/cni/Dwfl.cxx 2010-03-25 12:26:09.000000000 -0400
@@ -57,38 +57,26 @@
#include "inua/eio/ByteBuffer.h"
using namespace java::lang;
-
-// Suck in elf_from_remote_memory from elfutils
-
-extern "C"
-{
- extern ::Elf *elf_from_remote_memory (GElf_Addr ehdr_vma,
- GElf_Addr *loadbasep,
- ssize_t (*read_memory) (void *arg,
- void *data,
- GElf_Addr address,
- size_t minread,
- size_t maxread),
- void *arg);
-}
#define DWFL_POINTER ((::Dwfl *) pointer)
#define DWFL_CALLBACKS ((::Dwfl_Callbacks *) callbacks)
-static ssize_t
-read_proc_memory (void *arg, void *data, GElf_Addr address,
- size_t minread, size_t maxread)
-{
- inua::eio::ByteBuffer* memory = (inua::eio::ByteBuffer *) arg;
- jbyteArray bytes = JvNewByteArray(maxread);
- ssize_t nread = memory->safeGet((off64_t) address, bytes, 0, maxread);
- memcpy(data, elements(bytes), nread);
- if (nread > 0 && (size_t) nread < minread)
- nread = 0;
- return nread;
+jlong
+lib::dwfl::Dwfl::dwfl_slap_module_memory(jlong module, inua::eio::ByteBuffer* memory,
+ jlong address, jlong length) {
+ jbyteArray bounceBuffer = JvNewByteArray(length);
+ ssize_t nread = memory->safeGet((off64_t) address, bounceBuffer, 0, length);
+ if (nread < length) {
+ return 0; // what ever
+ }
+ void **userdatap;
+ ::dwfl_module_info((Dwfl_Module*)module, &userdatap, NULL, NULL, NULL, NULL, NULL, NULL);
+ (*userdatap) = ::malloc(length);
+ memcpy((*userdatap), elements(bounceBuffer), length);
+ return (jlong)(*userdatap);
}
int
-dwfl_frysk_proc_find_elf (Dwfl_Module *mod,
+dwfl_frysk_proc_find_elf (Dwfl_Module *module,
void **userdata,
const char *module_name, Dwarf_Addr base,
char **file_name, Elf **elfp)
@@ -105,21 +93,29 @@ dwfl_frysk_proc_find_elf (Dwfl_Module *m
*file_name = strdup (module_name);
return -1;
} else {
- *elfp = elf_from_remote_memory (base, NULL, &read_proc_memory, *userdata);
- if (*elfp != NULL) {
- *file_name = ::strdup(module_name);
- }
+ // During module creation the Dwfl_Module USERDATA point was set
+ // to a raw buffer that contains the entire in-memory section
+ // contents. Create an elf from that. DwflModule is responsible
+ // for freeing the memory.
+ char *memory = (char*)(*userdata);
+ // Compute the size of the memory using the module's bound.
+ ::Dwarf_Addr bound;
+ ::dwfl_module_info(module, NULL, NULL, &bound, NULL, NULL, NULL, NULL);
+ ssize_t memory_size = bound - base;
+ // Turn that memory into an ELF. The obvious thing to do here is
+ // to tell elfutils that it is responsible for the memory - by
+ // calling elf_flagelf(ELF_F_MALLOCED) - except all the flags
+ // including ELF_F_MALLOCED are not public and setting that
+ // particular flag is prohibited.
+ *elfp = elf_memory((char*)memory, memory_size);
+ if (*elfp == NULL) {
return -1;
}
-}
-
-jlong
-lib::dwfl::Dwfl::dwfl_userdata_begin(inua::eio::ByteBuffer *memory) {
- return (jlong)memory;
-}
-
-void
-lib::dwfl::Dwfl::dwfl_userdata_end(jlong userdata) {
+ // Poke something into FILE_NAME so that the caller notices that
+ // we've done something to ELF.
+ *file_name = ::strdup(module_name);
+ return -1;
+ }
}
jlong
@@ -169,7 +165,7 @@ lib::dwfl::Dwfl::dwfl_report_end(jlong p
jlong
lib::dwfl::Dwfl::dwfl_report_module(jlong pointer, jstring moduleName,
- jlong low, jlong high, jlong userdata) {
+ jlong low, jlong high) {
jsize len = JvGetStringUTFLength(moduleName);
char modName[len+1];
@@ -179,14 +175,6 @@ lib::dwfl::Dwfl::dwfl_report_module(jlon
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;
}
diff -up frysk-0.4/frysk-sys/lib/dwfl/cni/DwflModule.cxx.noelfmem frysk-0.4/frysk-sys/lib/dwfl/cni/DwflModule.cxx
--- frysk-0.4/frysk-sys/lib/dwfl/cni/DwflModule.cxx.noelfmem 2010-03-25 11:41:04.000000000 -0400
+++ frysk-0.4/frysk-sys/lib/dwfl/cni/DwflModule.cxx 2010-03-25 11:41:04.000000000 -0400
@@ -478,3 +478,8 @@ jlong
lib::dwfl::DwflModule::dwfl_module_getsrc(jlong pointer, jlong addr) {
return (jlong) ::dwfl_module_getsrc(DWFL_MODULE_POINTER, (Dwarf_Addr)addr);
}
+
+void
+lib::dwfl::DwflModule::dwfl_module_free_memory(jlong memory) {
+ ::free((void*)memory);
+}
diff -up frysk-0.4/frysk-sys/lib/dwfl/Dwfl.java.noelfmem frysk-0.4/frysk-sys/lib/dwfl/Dwfl.java
--- frysk-0.4/frysk-sys/lib/dwfl/Dwfl.java.noelfmem 2010-03-25 11:41:04.000000000 -0400
+++ frysk-0.4/frysk-sys/lib/dwfl/Dwfl.java 2010-03-25 12:19:08.000000000 -0400
@@ -49,7 +49,7 @@ 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 ByteBuffer memory;
private long pointer;
private long callbacks;
@@ -61,11 +61,10 @@ public class Dwfl {
*/
public Dwfl(String debugInfoPath, ByteBuffer memory) {
callbacks = dwfl_callbacks_begin(debugInfoPath);
- userdata = dwfl_userdata_begin(memory);
pointer = dwfl_begin(callbacks);
+ this.memory = memory;
}
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
@@ -85,13 +84,11 @@ public class Dwfl {
if (this.pointer != 0) {
dwfl_end(pointer);
this.pointer = 0;
- dwfl_userdata_end(userdata);
dwfl_callbacks_end(callbacks);
this.callbacks = 0;
}
}
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) {
@@ -197,8 +194,7 @@ 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,
- userdata);
+ long modulePointer = dwfl_report_module(pointer, moduleName, low, high);
for (int i = 0; i < modulesArray.length; i++) {
DwflModule module = modulesArray[i];
if (module.getName().equals(moduleName)
@@ -212,15 +208,26 @@ public class Dwfl {
return;
}
}
+ long bytes;
+ if (moduleName.startsWith("[")
+ && ULong.GT(high, low) && ULong.LT(high - low, 0x10000)) {
+ // If it looks like a mapped elf region and is small (like
+ // only a page or so) just suck it in.
+ bytes = dwfl_slap_module_memory(modulePointer, memory, low, high - low);
+ fine.log(this, "slapped module memory at", bytes, "count", high - low);
+ } else {
+ bytes = 0;
+ }
DwflModule module = new DwflModule(modulePointer, this, moduleName,
- low, high);
+ low, high, bytes);
finest.log(this, "reportModule creating", module);
modules.put(new Long(modulePointer), module);
}
private static native long dwfl_report_module(long pointer,
String moduleName,
- long low, long high,
- long userdata);
+ long low, long high);
+ private static native long dwfl_slap_module_memory(long modulePointer, ByteBuffer memory,
+ long low, long high);
private String name;
private long low;
diff -up frysk-0.4/frysk-sys/lib/dwfl/DwflModule.java.noelfmem frysk-0.4/frysk-sys/lib/dwfl/DwflModule.java
--- frysk-0.4/frysk-sys/lib/dwfl/DwflModule.java.noelfmem 2010-03-25 11:41:04.000000000 -0400
+++ frysk-0.4/frysk-sys/lib/dwfl/DwflModule.java 2010-03-25 11:41:04.000000000 -0400
@@ -50,26 +50,39 @@ public class DwflModule {
protected LinkedList pubNames;
protected LinkedList symbolTable;
+ private final long memory;
private final long pointer;
private final Dwfl parent;
private final String name;
private final long low;
private final long high;
- DwflModule(long val, Dwfl parent, String name, long low, long high) {
- this.pointer = val;
+ DwflModule(long pointer, Dwfl parent, String name, long low, long high, long memory) {
+ this.pointer = pointer;
this.parent = parent;
this.name = name;
this.low = low;
this.high = high;
+ this.memory = memory;
}
+ /**
+ * If a raw memory buffer was allocated, delete it when this is
+ * deleted; note that elfutils takes care of deleting the pointer.
+ */
+ public void finalize() {
+ if (memory != 0) {
+ dwfl_module_free_memory(memory);
+ }
+ }
+ private static native void dwfl_module_free_memory(long memory);
public String toString() {
return name
+ " 0x" + Long.toHexString(low)
+ "..0x" + Long.toHexString(high)
- + " pointer=0x" + Long.toHexString(pointer);
+ + " pointer=0x" + Long.toHexString(pointer)
+ + " memory=0x" + Long.toHexString(memory);
}
public long lowAddress() {
diff -up frysk-0.4/frysk-sys/lib/dwfl/jni/Dwfl.cxx.noelfmem frysk-0.4/frysk-sys/lib/dwfl/jni/Dwfl.cxx
--- frysk-0.4/frysk-sys/lib/dwfl/jni/Dwfl.cxx.noelfmem 2010-03-25 11:41:04.000000000 -0400
+++ frysk-0.4/frysk-sys/lib/dwfl/jni/Dwfl.cxx 2010-03-25 11:41:04.000000000 -0400
@@ -51,52 +51,31 @@
using namespace java::lang;
-// Suck in elf_from_remote_memory from elfutils
-
-extern "C" {
- extern ::Elf *elf_from_remote_memory(GElf_Addr ehdr_vma,
- GElf_Addr *loadbasep,
- ssize_t (*read_memory) (void *arg,
- void *data,
- GElf_Addr address,
- size_t minread,
- size_t maxread),
- void *arg);
-}
-
-// Grub the pointer out of the object; replace this with ...
-#define DWFL_POINTER_FIXME ((::Dwfl *)GetPointer(env))
-
// Assume the method was parameterised with POINTER.
#define DWFL_POINTER ((::Dwfl *)pointer)
-// 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 *userdata, void *data, GElf_Addr address,
- size_t minread, size_t maxread) {
- // 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(env);
- return nread;
+jlong
+lib::dwfl::Dwfl::dwfl_slap_module_memory(jnixx::env env, jlong module,
+ inua::eio::ByteBuffer memory,
+ jlong address, jlong length) {
+ jnixx::jbyteArray bounceBuffer = jnixx::jbyteArray::NewByteArray(env, length);
+ ssize_t nread = memory.safeGet(env, (off64_t) address, bounceBuffer, 0, length);
+ if (nread < length) {
+ bounceBuffer.DeleteLocalRef(env);
+ return 0; // what ever
+ }
+ void **userdatap;
+ ::dwfl_module_info((Dwfl_Module*)module, &userdatap, NULL, NULL, NULL, NULL, NULL, NULL);
+ (*userdatap) = ::malloc(length);
+ memcpy((*userdatap), jbyteArrayElements(env, bounceBuffer).elements(), length);
+ bounceBuffer.DeleteLocalRef(env);
+ return (jlong)(*userdatap);
}
static int
-dwfl_frysk_proc_find_elf(Dwfl_Module *mod,
+dwfl_frysk_proc_find_elf(Dwfl_Module *module,
void **userdata,
const char *module_name, Dwarf_Addr base,
char **file_name, Elf **elfp) {
@@ -111,30 +90,31 @@ dwfl_frysk_proc_find_elf(Dwfl_Module *mo
*file_name = ::strdup(module_name);
return -1;
} else {
- // 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);
- if (*elfp != NULL) {
- // Poke something into FILE_NAME so that the caller notices that
- // we've done something to ELF.
- *file_name = ::strdup(module_name);
+ // During module creation the Dwfl_Module USERDATA point was set
+ // to a raw buffer that contains the entire in-memory section
+ // contents. Create an elf from that. DwflModule is responsible
+ // for freeing the memory.
+ char *memory = (char*)(*userdata);
+ // Compute the size of the memory using the module's bound.
+ ::Dwarf_Addr bound;
+ ::dwfl_module_info(module, NULL, NULL, &bound, NULL, NULL, NULL, NULL);
+ ssize_t memory_size = bound - base;
+ // Turn that memory into an ELF. The obvious thing to do here is
+ // to tell elfutils that it is responsible for the memory - by
+ // calling elf_flagelf(ELF_F_MALLOCED) - except all the flags
+ // including ELF_F_MALLOCED are not public and setting that
+ // particular flag is prohibited.
+ *elfp = elf_memory((char*)memory, memory_size);
+ if (*elfp == NULL) {
+ return -1;
}
+ // Poke something into FILE_NAME so that the caller notices that
+ // we've done something to ELF.
+ *file_name = ::strdup(module_name);
return -1;
}
}
-jlong
-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)
@@ -185,20 +165,11 @@ lib::dwfl::Dwfl::dwfl_report_end(jnixx::
jlong
lib::dwfl::Dwfl::dwfl_report_module(jnixx::env env, jlong pointer,
- String jmoduleName, jlong low, jlong high,
- jlong userdata) {
+ String jmoduleName, jlong low, jlong high) {
jstringUTFChars moduleName = jstringUTFChars(env, jmoduleName);
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 -up frysk-0.4/frysk-sys/lib/dwfl/jni/DwflModule.cxx.noelfmem frysk-0.4/frysk-sys/lib/dwfl/jni/DwflModule.cxx
--- frysk-0.4/frysk-sys/lib/dwfl/jni/DwflModule.cxx.noelfmem 2010-03-25 11:41:04.000000000 -0400
+++ frysk-0.4/frysk-sys/lib/dwfl/jni/DwflModule.cxx 2010-03-25 11:41:04.000000000 -0400
@@ -436,3 +436,8 @@ lib::dwfl::DwflModule::dwfl_module_getsr
jlong addr) {
return (jlong) ::dwfl_module_getsrc(DWFL_MODULE_POINTER, (Dwarf_Addr)addr);
}
+
+void
+lib::dwfl::DwflModule::dwfl_module_free_memory(jnixx::env env, jlong memory) {
+ ::free((void*)memory);
+}