1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
// natSharedLibLoader.cc - Implementation of SharedLibHelper native methods.
/* Copyright (C) 2001, 2003, 2004, 2005, 2006, 2010 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
#include <config.h>
#include <platform.h>
#include <gcj/cni.h>
#include <jvm.h>
#include <execution.h>
#include <gnu/gcj/runtime/SharedLibHelper.h>
#include <java/io/IOException.h>
#include <java/lang/UnsupportedOperationException.h>
#include <java/lang/UnknownError.h>
#include <java/lang/VMClassLoader.h>
// If we're using the Boehm GC, then we need this include to override dlopen.
#ifdef HAVE_BOEHM_GC
// Set GC_DEBUG before including gc.h!
#ifdef LIBGCJ_GC_DEBUG
# define GC_DEBUG
#endif
#include <gc.h>
#endif /* HAVE_BOEHM_GC */
#ifdef HAVE_DLOPEN
#include <dlfcn.h>
/* Only used during dlopen, while having a lock on Class.class. */
static java::lang::ClassLoader *curLoader;
static gnu::gcj::runtime::SharedLibHelper *curHelper;
typedef void (*ClassHookFunc) (jclass);
typedef void (*CoreHookFunc) (_Jv_core_chain *);
void
_Jv_sharedlib_register_hook (jclass cls)
{
cls->protectionDomain = curHelper->domain;
cls->loader = curLoader;
if (! cls->engine)
cls->engine = &_Jv_soleCompiledEngine;
curHelper->registerClass(cls->getName(), cls);
}
static void
core_hook (_Jv_core_chain *chain)
{
chain->next = (_Jv_core_chain *) curHelper->core_chain;
curHelper->core_chain = (gnu::gcj::RawData *) chain;
}
struct SharedLibDummy
{
ClassHookFunc saved;
CoreHookFunc saved_core;
SharedLibDummy()
{
saved = _Jv_RegisterClassHook;
saved_core = _Jv_RegisterCoreHook;
}
~SharedLibDummy()
{
_Jv_RegisterClassHook = saved;
_Jv_RegisterCoreHook = saved_core;
curLoader = NULL;
}
};
#endif
void
gnu::gcj::runtime::SharedLibHelper::init(void)
{
#ifdef HAVE_DLOPEN
char *lname = (char *) __builtin_alloca (JvGetStringUTFLength (baseName)
+ 1);
jsize total = JvGetStringUTFRegion (baseName, 0, baseName->length(), lname);
lname[total] = '\0';
if (flags==0)
flags = RTLD_GLOBAL | RTLD_LAZY;
JvSynchronize dummy1(&::java::lang::Class::class$);
SharedLibDummy dummy2;
curLoader = ((void*)loader == ::java::lang::VMClassLoader::bootLoader
? NULL : loader);
curHelper = this;
_Jv_RegisterClassHook = _Jv_sharedlib_register_hook;
_Jv_RegisterCoreHook = core_hook;
void *h = dlopen(lname, flags);
if (h == NULL)
{
const char *msg = dlerror();
throw new ::java::lang::UnknownError(JvNewStringLatin1(msg));
}
handler = (gnu::gcj::RawData*) h;
#else
const char *msg
= "shared library class loading is not supported on this platform";
throw new ::java::lang::UnsupportedOperationException(JvNewStringLatin1(msg));
#endif
}
jboolean
gnu::gcj::runtime::SharedLibHelper::hasResource (jstring name)
{
#ifdef HAVE_DLOPEN
_Jv_core_chain *node = _Jv_FindCore ((_Jv_core_chain *) core_chain, name);
return node != NULL;
#else
return false;
#endif
}
#ifdef HAVE_DLOPEN
extern gnu::gcj::Core *_Jv_create_core (_Jv_core_chain *node, jstring name);
#endif
gnu::gcj::Core *
gnu::gcj::runtime::SharedLibHelper::findCore (jstring name)
{
#ifdef HAVE_DLOPEN
ensureInit();
return _Jv_create_core ((_Jv_core_chain *) core_chain, name);
#else
return NULL;
#endif
}
void
gnu::gcj::runtime::SharedLibHelper::finalize()
{
_Jv_FreeCoreChain ((_Jv_core_chain *) core_chain);
#ifdef HAVE_DLOPEN
if (handler)
dlclose (handler);
#endif
}
void
gnu::gcj::runtime::SharedLibHelper::ensureSupersLinked(jclass k)
{
_Jv_Linker::wait_for_state (k, JV_STATE_LOADING);
}
|