Hi Will,<div><br></div><div>The approach looks good to me. We could definitely do better by listing all the methods vmkit defines, but for now what you're doing is fine.</div><div><br></div><div>Nicolas<br><br><div class="gmail_quote">
On Wed, Nov 16, 2011 at 4:19 AM, Will Dietz <span dir="ltr"><<a href="mailto:wdietz2@illinois.edu">wdietz2@illinois.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im">On Tue, Nov 15, 2011 at 3:58 PM, Will Dietz <<a href="mailto:wdietz2@illinois.edu">wdietz2@illinois.edu</a>> wrote:<br>
> On Tue, Nov 15, 2011 at 2:41 PM, Will Dietz <<a href="mailto:wdietz2@illinois.edu">wdietz2@illinois.edu</a>> wrote:<br>
>> On Tue, Nov 15, 2011 at 2:24 PM, Nicolas Geoffray<br>
>> <<a href="mailto:nicolas.geoffray@gmail.com">nicolas.geoffray@gmail.com</a>> wrote:<br>
>>> Hi Will,<br>
>>><br>
>>> I'm not sure that's right. With GNU Classpath, I also want to define my own<br>
>>> methods and not use the ones implemented in Classpath. If we reorder things,<br>
>>> the method defined in GNU Classpath will be used. Not mine.<br>
>>> vmkit is using RTLD_LOCAL when loading, so symbol resolution on a dlsym must<br>
>>> provide the loaded library. If you do dlsym(SELF_HANDLE, 'mysymbol'), you'll<br>
>>> only get symbols loaded in the j3 executable.<br>
>>> What is it that does not work for you?<br>
>>> Cheers,<br>
>>> Nicolas<br>
>>><br>
>><br>
><br>
> Hmm, you're right that regardless of my discussion below, this changes<br>
> the behavior for symbols that are defined in both places.<br>
><br>
> Unfortunately, it appears that OpenJDK likes to dlopen() with<br>
> RTLD_GLOBAL, which complicates things.<br>
><br>
<br>
</div>Inlined below is an updated patch that works here, and should<br>
correctly handle all existing cases (except that we're doing more<br>
dlsym's for each lookup than before).<br>
<br>
Let me know if you like it, else there are a number of other options :).<br>
<br>
~Will<br>
<br>
>From ba8355a4b4b3bb39aaf64764b0b6998297419fbd Mon Sep 17 00:00:00 2001<br>
<div class="im">From: Will Dietz <<a href="mailto:w@wdtz.org">w@wdtz.org</a>><br>
Date: Mon, 14 Nov 2011 09:45:35 -0600<br>
</div>Subject: [PATCH] Fix detection of whether or not symbols are from j3 or not.<br>
<br>
Unfortunately, native code that's part of OpenJDK likes to dlopen things with<br>
RTLD_GLOBAL, resulting in the existing mechanism for determining where a symbol<br>
came from inaccurate.<br>
<br>
Instead, search both our process (and any global libraries), but also search our<br>
loaded libraries.<br>
<br>
Using this, we can determine which symbols are in vmkit: they must be<br>
in in the self<br>
search AND be a different symbol from what was found in the library search.<br>
---<br>
 lib/J3/VMCore/JnjvmClassLoader.cpp |   45 ++++++++++++++++++++++++-----------<br>
 1 files changed, 31 insertions(+), 14 deletions(-)<br>
<br>
diff --git a/lib/J3/VMCore/JnjvmClassLoader.cpp<br>
b/lib/J3/VMCore/JnjvmClassLoader.cpp<br>
index bf825a8..98abde4 100644<br>
--- a/lib/J3/VMCore/JnjvmClassLoader.cpp<br>
+++ b/lib/J3/VMCore/JnjvmClassLoader.cpp<br>
@@ -977,22 +977,39 @@ const UTF8*<br>
<div class="im">JnjvmClassLoader::constructArrayName(uint32 steps,<br>
 }<br>
<br>
 word_t JnjvmClassLoader::loadInLib(const char* buf, bool& j3) {<br>
-  word_t res =<br>
(word_t)TheCompiler->loadMethod(mvm::System::GetSelfHandle(), buf);<br>
-<br>
-  if (!res) {<br>
-    for (std::vector<void*>::iterator i = nativeLibs.begin(),<br>
-              e = nativeLibs.end(); i!= e; ++i) {<br>
-      res = (word_t)TheCompiler->loadMethod((*i), buf);<br>
-      if (res) break;<br>
-    }<br>
-  } else {<br>
</div>-    j3 = true;<br>
+  // Check 'self'.  Should only check our process, however it's possible native<br>
+  // code dlopen'd something itself (with RTLD_GLOBAL; OpenJDK does this).<br>
+  // To handle this, we search both ourselves and the libraries we loaded.<br>
+  word_t sym =<br>
<div class="im">+    (word_t)TheCompiler->loadMethod(mvm::System::GetSelfHandle(), buf);<br>
+<br>
</div>+  // Search loaded libraries as well, both as fallback and to determine<br>
+  // whether or not the symbol in question is defined by vmkit.<br>
+  word_t symFromLib = 0;<br>
<div class="im">+  for (std::vector<void*>::iterator i = nativeLibs.begin(),<br>
+      e = nativeLibs.end(); i!= e; ++i) {<br>
</div>+    symFromLib = (word_t)TheCompiler->loadMethod((*i), buf);<br>
+    if (symFromLib) break;<br>
<div class="im">   }<br>
-<br>
-  if (!res && this != bootstrapLoader)<br>
-    res = bootstrapLoader->loadInLib(buf, j3);<br>
<br>
-  return (word_t)res;<br>
</div>+  if (sym) {<br>
+    // Always use the definition from 'self', if it exists.<br>
+    // Furthermore, claim it's defined in j3 iff it wasn't found in one of our<br>
+    // libraries.  This might be wrong if we do a lookup on a symbol that's<br>
+    // neither in vmkit nor a VM-loaded library (but /is/ in a<br>
different library<br>
+    // that has been dlopen'd by native code), but that should never<br>
+    // be called from java code anyway.<br>
+    j3 = (sym != symFromLib);<br>
+    return sym;<br>
+  }<br>
+<br>
+  // Otherwise return what we found in the libraries, if anything<br>
+  if (symFromLib) return symFromLib;<br>
<div class="HOEnZb"><div class="h5">+<br>
+  if (this != bootstrapLoader)<br>
+    return bootstrapLoader->loadInLib(buf, j3);<br>
+<br>
+  return 0;<br>
 }<br>
<br>
 void* JnjvmClassLoader::loadLib(const char* buf) {<br>
--<br>
1.7.5.1<br>
</div></div></blockquote></div><br></div>