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>