1f19362584b7ec0df5c8f1f8a09ec52562828e5c
[cacao.git] / src / cacao / cacao.c
1 /* src/cacao/cacao.c - contains main() of cacao
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #include "config.h"
27
28 #include <assert.h>
29
30 #if defined(ENABLE_LIBJVM)
31 # include <ltdl.h>
32 #endif
33
34 #if defined(ENABLE_JRE_LAYOUT)
35 # include <errno.h>
36 # include <libgen.h>
37 # include <unistd.h>
38 #endif
39
40 #include <stdlib.h>
41 #include <string.h>
42
43 #include "vm/types.h"
44
45 #include "native/jni.h"
46
47 #if defined(ENABLE_JVMTI)
48 # include "native/jvmti/jvmti.h"
49 # include "native/jvmti/cacaodbg.h"
50 # include "threads/mutex.h"
51 #endif
52
53 #include "vm/vm.h"
54
55
56 /* forward declarations *******************************************************/
57
58 static JavaVMInitArgs *cacao_options_prepare(int argc, char **argv);
59
60
61 /* main ************************************************************************
62
63    The main program.
64    
65 *******************************************************************************/
66
67 int main(int argc, char **argv)
68 {
69 #if defined(ENABLE_LIBJVM)
70         char           *path;
71 #endif
72
73 #if defined(ENABLE_LIBJVM)      
74         /* Variables for JNI_CreateJavaVM dlopen call. */
75         lt_dlhandle     libjvm_handle;
76         lt_ptr          libjvm_vm_createjvm;
77         lt_ptr          libjvm_vm_run;
78         const char     *lterror;
79
80         bool (*vm_createjvm)(JavaVM **, void **, void *);
81         void (*vm_run)(JavaVM *, JavaVMInitArgs *);
82 #endif
83
84         JavaVM         *vm;                 /* denotes a Java VM                  */
85         JNIEnv         *env;
86         JavaVMInitArgs *vm_args;
87
88         /* prepare the options */
89
90         vm_args = cacao_options_prepare(argc, argv);
91         
92         /* load and initialize a Java VM, return a JNI interface pointer in env */
93
94 #if defined(ENABLE_LIBJVM)
95 # if defined(ENABLE_JRE_LAYOUT)
96         /* SUN also uses a buffer of 4096-bytes (strace is your friend). */
97
98         path = malloc(sizeof(char) * 4096);
99
100         if (readlink("/proc/self/exe", path, 4095) == -1) {
101                 fprintf(stderr, "main: readlink failed: %s\n", strerror(errno));
102                 abort();
103         }
104
105         /* get the path of the current executable */
106
107         path = dirname(path);
108
109         if ((strlen(path) + strlen("/../lib/libjvm") + strlen("0")) > 4096) {
110                 fprintf(stderr, "main: libjvm name to long for buffer\n");
111                 abort();
112         }
113
114         /* concatinate the library name */
115
116         strcat(path, "/../lib/libjvm");
117 # else
118         path = CACAO_LIBDIR"/libjvm";
119 # endif
120
121         if (lt_dlinit()) {
122                 fprintf(stderr, "main: lt_dlinit failed: %s\n", lt_dlerror());
123                 abort();
124         }
125
126         /* First try to open where dlopen searches, e.g. LD_LIBRARY_PATH.
127            If not found, try the absolute path. */
128
129         if (!(libjvm_handle = lt_dlopenext("libjvm"))) {
130                 /* save the error message */
131
132                 lterror = strdup(lt_dlerror());
133
134                 if (!(libjvm_handle = lt_dlopenext(path))) {
135                         /* print the first error message too */
136
137                         fprintf(stderr, "main: lt_dlopenext failed: %s\n", lterror);
138
139                         /* and now the current one */
140
141                         fprintf(stderr, "main: lt_dlopenext failed: %s\n", lt_dlerror());
142                         abort();
143                 }
144
145                 /* free the error string */
146
147                 free((void *) lterror);
148         }
149
150         if (!(libjvm_vm_createjvm = lt_dlsym(libjvm_handle, "vm_createjvm"))) {
151                 fprintf(stderr, "main: lt_dlsym failed: %s\n", lt_dlerror());
152                 abort();
153         }
154
155         vm_createjvm =
156                 (bool (*)(JavaVM **, void **, void *)) (ptrint) libjvm_vm_createjvm;
157 #endif
158
159         /* create the Java VM */
160
161         (void) vm_createjvm(&vm, (void *) &env, vm_args);
162
163 #if defined(ENABLE_JVMTI)
164         mutex_init(&dbgcomlock);
165         if (jvmti) jvmti_set_phase(JVMTI_PHASE_START);
166 #endif
167
168 #if defined(ENABLE_LIBJVM)
169         if (!(libjvm_vm_run = lt_dlsym(libjvm_handle, "vm_run"))) {
170                 fprintf(stderr, "lt_dlsym failed: %s\n", lt_dlerror());
171                 abort();
172         }
173
174         vm_run = (void (*)(JavaVM *, JavaVMInitArgs *)) (ptrint) libjvm_vm_run;
175 #endif
176
177         /* run the VM */
178
179         vm_run(vm, vm_args);
180
181         /* keep compiler happy */
182
183         return 0;
184 }
185
186
187 /* cacao_options_prepare *******************************************************
188
189    Prepare the JavaVMInitArgs.
190
191 *******************************************************************************/
192
193 static JavaVMInitArgs *cacao_options_prepare(int argc, char **argv)
194 {
195         JavaVMInitArgs *vm_args;
196         s4              i;
197
198         vm_args = malloc(sizeof(JavaVMInitArgs));
199
200         vm_args->version            = JNI_VERSION_1_2;
201         vm_args->nOptions           = argc - 1;
202         vm_args->options            = malloc(sizeof(JavaVMOption) * argc);
203         vm_args->ignoreUnrecognized = JNI_FALSE;
204
205         for (i = 1; i < argc; i++)
206                 vm_args->options[i - 1].optionString = argv[i];
207
208         return vm_args;
209 }
210
211
212 /*
213  * These are local overrides for various environment variables in Emacs.
214  * Please do not remove this and leave it at the end of the file, where
215  * Emacs will automagically detect them.
216  * ---------------------------------------------------------------------
217  * Local variables:
218  * mode: c
219  * indent-tabs-mode: t
220  * c-basic-offset: 4
221  * tab-width: 4
222  * End:
223  */