Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/bcutil/dynload.c
5985 views
1
/*******************************************************************************
2
* Copyright (c) 1991, 2021 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
21
*******************************************************************************/
22
23
#include <stdlib.h>
24
#include <string.h>
25
26
#include "j9.h"
27
#include "j9port.h"
28
#include "bcutil_api.h"
29
#include "cfr.h"
30
#include "cfreader.h"
31
#include "j2sever.h"
32
#include "j9protos.h"
33
#include "j9consts.h"
34
#include "jimage.h"
35
#include "jimagereader.h"
36
#include "jvminit.h"
37
#include "romcookie.h"
38
39
#ifdef J9VM_OPT_ZIP_SUPPORT
40
#include "vmi.h"
41
#endif /* J9VM_OPT_ZIP_SUPPORT */
42
43
#include "dynload.h"
44
#include "ut_j9bcu.h"
45
#include "vm_api.h"
46
47
#if (defined(J9VM_OPT_DYNAMIC_LOAD_SUPPORT)) /* File Level Build Flags */
48
49
static const U_8 classSuffix[] = ".class";
50
#define SUFFIX_LENGTH 6
51
52
static IDATA readFile (J9JavaVM * javaVM);
53
static IDATA convertToClassFilename (J9JavaVM * javaVM, U_8 * className, UDATA classNameLength);
54
#if (defined(J9VM_OPT_ZIP_SUPPORT))
55
static IDATA readZip (J9JavaVM * javaVM, J9ClassPathEntry * cpEntry);
56
#endif /* J9VM_OPT_ZIP_SUPPORT */
57
static IDATA convertToOSFilename (J9JavaVM * javaVM, U_8 * dir, UDATA dirLength, U_8 * moduleName, U_8 * className, UDATA classNameLength);
58
static IDATA checkSunClassFileBuffers (J9JavaVM * javaVM, U_32 sunClassFileSize);
59
static IDATA searchClassInModule(J9VMThread * vmThread, J9Module * j9module, U_8 * className, UDATA classNameLength, BOOLEAN verbose, J9TranslationLocalBuffer *localBuffer);
60
static IDATA searchClassInBootstrapClassPath(J9VMThread * vmThread, U_8 * className, UDATA classNameLength, BOOLEAN verbose, J9TranslationLocalBuffer *localBuffer);
61
static IDATA searchClassInPatchPaths(J9VMThread * vmThread, J9ClassPathEntry** patchPaths, UDATA patchPathCount, U_8 * className, UDATA classNameLength, BOOLEAN verbose, J9TranslationLocalBuffer *localBuffer);
62
static IDATA searchClassInCPEntry(J9VMThread * vmThread, J9ClassPathEntry * cpEntry, J9Module * j9module, U_8 * moduleName, U_8 * className, UDATA classNameLength, BOOLEAN verbose);
63
static IDATA readFileFromJImage (J9VMThread * vmThread, J9Module * j9module, U_8 * moduleName, J9ClassPathEntry *cpEntry);
64
65
IDATA
66
findLocallyDefinedClass(J9VMThread * vmThread, J9Module * j9module, U_8 * className, U_32 classNameLength, J9ClassLoader * classLoader, UDATA options, J9TranslationLocalBuffer *localBuffer)
67
{
68
IDATA result = 0;
69
J9JavaVM *javaVM = vmThread->javaVM;
70
J9TranslationBufferSet *dynamicLoadBuffers = javaVM->dynamicLoadBuffers;
71
J9DynamicLoadStats *dynamicLoadStats = dynamicLoadBuffers->dynamicLoadStats;
72
J9Module *module = j9module;
73
BOOLEAN verbose = dynamicLoadBuffers->flags & BCU_VERBOSE;
74
#define LOCAL_MAX 80
75
U_8 localString[LOCAL_MAX];
76
UDATA mbLength = classNameLength;
77
U_8 *mbString = localString;
78
J9ClassPathEntry** classPath = NULL;
79
UDATA classPathEntryCount = 0;
80
BOOLEAN releaseBootLoaderCpMutex = FALSE;
81
PORT_ACCESS_FROM_JAVAVM(javaVM);
82
83
/* localBuffer should not be NULL */
84
Trc_BCU_Assert_True(NULL != localBuffer);
85
86
localBuffer->loadLocationType = 0;
87
localBuffer->entryIndex = J9_CP_INDEX_NONE;
88
localBuffer->cpEntryUsed = NULL;
89
dynamicLoadBuffers->classFileError = NULL;
90
91
if (mbLength >= LOCAL_MAX) {
92
mbString = j9mem_allocate_memory(mbLength + 1, J9MEM_CATEGORY_CLASSES);
93
if (NULL == mbString) {
94
return -1;
95
}
96
}
97
mbString[mbLength] = 0; /* ensure null terminated */
98
memcpy(mbString, className, classNameLength);
99
100
CHECK_BUFFER(dynamicLoadStats->name, dynamicLoadStats->nameBufferLength, (mbLength + 1));
101
dynamicLoadStats->nameLength = mbLength;
102
memcpy(dynamicLoadStats->name, mbString, mbLength + 1);
103
104
Trc_BCU_findLocallyDefinedClass_Entry(mbString, classPathEntryCount);
105
106
/* Search patch path of the module before looking up in bootclasspath */
107
if (J2SE_VERSION(javaVM) >= J2SE_V11) {
108
if (NULL == module) {
109
if (J9_ARE_NO_BITS_SET(javaVM->runtimeFlags, J9_RUNTIME_JAVA_BASE_MODULE_CREATED)) {
110
module = javaVM->javaBaseModule;
111
} else {
112
char *packageEnd = strrchr((const char*)mbString, '/');
113
114
if (NULL != packageEnd) {
115
omrthread_monitor_enter(javaVM->classLoaderModuleAndLocationMutex);
116
module = J9_VM_FUNCTION(vmThread, findModuleForPackage)(vmThread, classLoader, mbString, (U_32)((U_8 *)packageEnd - mbString));
117
omrthread_monitor_exit(javaVM->classLoaderModuleAndLocationMutex);
118
}
119
}
120
}
121
if (NULL != module) {
122
if (NULL != classLoader->moduleExtraInfoHashTable) {
123
J9ModuleExtraInfo *moduleInfo = NULL;
124
125
omrthread_monitor_enter(javaVM->classLoaderModuleAndLocationMutex);
126
moduleInfo = J9_VM_FUNCTION(vmThread, findModuleInfoForModule)(vmThread, classLoader, module);
127
omrthread_monitor_exit(javaVM->classLoaderModuleAndLocationMutex);
128
129
if ((NULL != moduleInfo) && (NULL != moduleInfo->patchPathEntries)) {
130
result = searchClassInPatchPaths(vmThread, moduleInfo->patchPathEntries, moduleInfo->patchPathCount, mbString, mbLength, verbose, localBuffer);
131
if (0 == result) {
132
goto _end;
133
}
134
}
135
}
136
137
/* If not found in patch paths, search the class in its module */
138
result = searchClassInModule(vmThread, module, mbString, mbLength, verbose, localBuffer);
139
if (1 == result) {
140
/* If we failed to find the class in the module passed as parameter and J9_FINDCLASS_FLAG_FIND_MODULE_ON_FAIL is set,
141
* then check the class in other modules defined by the loader.
142
*/
143
if ((NULL != j9module)
144
&& J9_ARE_ALL_BITS_SET(options, J9_FINDCLASS_FLAG_FIND_MODULE_ON_FAIL)
145
) {
146
J9Module *j9moduleFromPackage = NULL;
147
char *packageEnd = strrchr((const char*)className, '/');
148
149
if (NULL != packageEnd) {
150
omrthread_monitor_enter(javaVM->classLoaderModuleAndLocationMutex);
151
152
j9moduleFromPackage = J9_VM_FUNCTION(vmThread, findModuleForPackage)(vmThread, classLoader, className, (U_32)((U_8 *)packageEnd - className));
153
154
if ((NULL != j9moduleFromPackage) && (j9moduleFromPackage != j9module)) {
155
J9ModuleExtraInfo *moduleInfo = J9_VM_FUNCTION(vmThread, findModuleInfoForModule)(vmThread, classLoader, j9moduleFromPackage);
156
157
if ((NULL != moduleInfo) && (NULL != moduleInfo->patchPathEntries)) {
158
result = searchClassInPatchPaths(vmThread, moduleInfo->patchPathEntries, moduleInfo->patchPathCount, className, classNameLength, verbose, localBuffer);
159
}
160
if (0 != result) {
161
result = searchClassInModule(vmThread, j9moduleFromPackage, mbString, mbLength, verbose, localBuffer);
162
}
163
}
164
omrthread_monitor_exit(javaVM->classLoaderModuleAndLocationMutex);
165
}
166
}
167
} else {
168
goto _end;
169
}
170
}
171
}
172
173
/*
174
* If the class is still not found, search it in the bootstrap loader classpath.
175
* The class path entry count is 0 for non-bootstrap class loader, no need to search if it is non-bootstrap class loader
176
*/
177
if (classLoader == javaVM->systemClassLoader) {
178
result = searchClassInBootstrapClassPath(vmThread, mbString, mbLength, verbose, localBuffer);
179
}
180
181
_end:
182
if (0 != result) {
183
Trc_BCU_findLocallyDefinedClass_Failed(mbString);
184
result = -1;
185
} else {
186
Trc_BCU_findLocallyDefinedClass_Exit(mbString, dynamicLoadBuffers->searchFilenameBuffer);
187
}
188
if ((U_8 *)mbString != localString) {
189
j9mem_free_memory(mbString);
190
}
191
return result;
192
}
193
194
/**
195
* Search a class in the specified module.
196
*
197
* @param [in] vmThread pointer to current J9VMThread
198
* @param [in] j9module module in which to search the class
199
* @param [in] className name of the class to be searched
200
* @param [in] classNameLength length of the className
201
* @param [in] verbose if TRUE record the class loading stats
202
* @param [in/out] localBuffer contains values for entryIndex, loadLocationType and cpEntryUsed. This pointer can't be NULL.
203
*
204
* @return 0 on success, 1 if the class is not found, -1 on error
205
*/
206
static IDATA
207
searchClassInModule(J9VMThread * vmThread, J9Module * j9module, U_8 * className, UDATA classNameLength, BOOLEAN verbose, J9TranslationLocalBuffer *localBuffer)
208
{
209
J9JavaVM *javaVM = vmThread->javaVM;
210
char moduleNameBuf[J9VM_PACKAGE_NAME_BUFFER_LENGTH];
211
char *moduleName = NULL;
212
BOOLEAN freeModuleName = FALSE;
213
IDATA rc = 1;
214
PORT_ACCESS_FROM_JAVAVM(javaVM);
215
216
/* localBuffer should not be NULL */
217
Trc_BCU_Assert_True(NULL != localBuffer);
218
219
if (j9module == javaVM->javaBaseModule) {
220
moduleName = JAVA_BASE_MODULE;
221
} else {
222
moduleName = J9_VM_FUNCTION(vmThread, copyStringToUTF8WithMemAlloc)(
223
vmThread, j9module->moduleName, J9_STR_NULL_TERMINATE_RESULT, "", 0, moduleNameBuf, J9VM_PACKAGE_NAME_BUFFER_LENGTH, NULL);
224
if (NULL == moduleName) {
225
rc = -1;
226
goto _end;
227
}
228
if (moduleNameBuf != moduleName) {
229
freeModuleName = TRUE;
230
}
231
}
232
233
rc = searchClassInCPEntry(vmThread, javaVM->modulesPathEntry, j9module, (U_8*)moduleName, className, classNameLength, verbose);
234
if (0 == rc) {
235
localBuffer->loadLocationType = LOAD_LOCATION_MODULE;
236
}
237
238
if (TRUE == freeModuleName) {
239
j9mem_free_memory(moduleName);
240
}
241
_end:
242
return rc;
243
}
244
245
/**
246
* Search a class in the bootstrap classpath.
247
*
248
* @param [in] vmThread pointer to current J9VMThread
249
* @param [in] className name of the class to be searched
250
* @param [in] classNameLength length of the className
251
* @param [in] verbose if TRUE record the class loading stats
252
* @param [in/out] localBuffer contains values for entryIndex, loadLocationType and cpEntryUsed. This pointer can't be NULL.
253
*
254
* @return 0 on success, 1 if the class is not found, -1 on error
255
*/
256
static IDATA
257
searchClassInBootstrapClassPath(J9VMThread * vmThread, U_8 * className, UDATA classNameLength, BOOLEAN verbose, J9TranslationLocalBuffer *localBuffer)
258
{
259
J9JavaVM *javaVM = vmThread->javaVM;
260
J9InternalVMFunctions const * const vmFuncs = javaVM->internalVMFunctions;
261
J9ClassPathEntry *cpEntry = NULL;
262
J9ClassPathEntry **classPath = NULL;
263
UDATA classPathCount = 0;
264
J9ClassLoader* classLoader = javaVM->systemClassLoader;
265
IDATA rc = 1;
266
UDATA i = 0;
267
268
/* localBuffer should not be NULL */
269
Trc_BCU_Assert_True(NULL != localBuffer);
270
if ((0 == classLoader->classPathEntryCount)
271
|| (NULL == classLoader->classPathEntries)
272
) {
273
/* There is no bootstrap class path on Java 11 and up by default. There can be a bootstrap class path if -Xbootclasspath/a: is used. */
274
return rc;
275
}
276
for (i = 0; i < classLoader->classPathEntryCount; i++) {
277
/* This loop goes to the file system, so cpEntriesMutex is not held during the entire loop. */
278
omrthread_rwmutex_enter_read(classLoader->cpEntriesMutex);
279
cpEntry = classLoader->classPathEntries[i];
280
omrthread_rwmutex_exit_read(classLoader->cpEntriesMutex);
281
/* Warm up the entry */
282
vmFuncs->initializeClassPathEntry(javaVM, cpEntry);
283
rc = searchClassInCPEntry(vmThread, cpEntry, NULL, NULL, className, classNameLength, verbose);
284
if (0 == rc) {
285
localBuffer->cpEntryUsed = cpEntry;
286
localBuffer->loadLocationType = LOAD_LOCATION_CLASSPATH;
287
localBuffer->entryIndex = i;
288
break;
289
}
290
}
291
292
return rc;
293
}
294
295
/**
296
* Search a class in the patch paths.
297
*
298
* @param [in] vmThread pointer to current J9VMThread
299
* @param [in] patchPaths array of patch path entries in which to search the class
300
* @param [in] patchPathCount number of entries in patchPaths array
301
* @param [in] className name of the class to be searched
302
* @param [in] classNameLength length of the className
303
* @param [in] verbose if TRUE record the class loading stats
304
* @param [in/out] localBuffer contains values for entryIndex, loadLocationType and cpEntryUsed. This pointer can't be NULL.
305
*
306
* @return 0 on success, 1 if the class is not found, -1 on error
307
*/
308
static IDATA
309
searchClassInPatchPaths(J9VMThread * vmThread, J9ClassPathEntry** patchPaths, UDATA patchPathCount, U_8 * className, UDATA classNameLength, BOOLEAN verbose, J9TranslationLocalBuffer *localBuffer)
310
{
311
J9JavaVM *javaVM = vmThread->javaVM;
312
J9InternalVMFunctions const * const vmFuncs = javaVM->internalVMFunctions;
313
J9ClassPathEntry *patchEntry = NULL;
314
IDATA rc = 1;
315
UDATA i = 0;
316
317
/* localBuffer should not be NULL */
318
Trc_BCU_Assert_True(NULL != localBuffer);
319
320
for (i = 0; i < patchPathCount; i++) {
321
patchEntry = patchPaths[i];
322
vmFuncs->initializeClassPathEntry(javaVM, patchEntry);
323
rc = searchClassInCPEntry(vmThread, patchEntry, NULL, NULL, className, classNameLength, verbose);
324
if (0 == rc) {
325
localBuffer->cpEntryUsed = patchEntry;
326
localBuffer->loadLocationType = LOAD_LOCATION_PATCH_PATH;
327
localBuffer->entryIndex = i;
328
break;
329
}
330
}
331
return rc;
332
}
333
334
/**
335
* Search a class in the given J9ClassPathEntry.
336
* The J9ClassPathEntry may denote a class path entry or a patch path entry.
337
*
338
* @param [in] vmThread pointer to current J9VMThread
339
* @param [in] cpEntry an entry in which to search the class
340
* @param [in] j9module module in which to search the class
341
* @param [in] moduleName name of the module
342
* @param [in] className name of the class to be searched
343
* @param [in] classNameLength length of the className
344
* @param [in] verbose if TRUE record the class loading stats
345
*
346
* @return 0 on success, 1 if the class is not found, -1 on error
347
*/
348
static IDATA
349
searchClassInCPEntry(J9VMThread * vmThread, J9ClassPathEntry * cpEntry, J9Module * j9module, U_8 *moduleName, U_8 * className, UDATA classNameLength, BOOLEAN verbose)
350
{
351
J9JavaVM *javaVM = vmThread->javaVM;
352
J9TranslationBufferSet *dynamicLoadBuffers = javaVM->dynamicLoadBuffers;
353
J9DynamicLoadStats *dynamicLoadStats = dynamicLoadBuffers->dynamicLoadStats;
354
IDATA rc = 1;
355
PORT_ACCESS_FROM_JAVAVM(javaVM);
356
357
switch (cpEntry->type)
358
{
359
case CPE_TYPE_DIRECTORY:
360
if (convertToOSFilename(javaVM, cpEntry->path, cpEntry->pathLength, moduleName, className, classNameLength)) {
361
rc = -1;
362
break;
363
}
364
if(verbose) {
365
dynamicLoadStats->readStartTime = j9time_usec_clock();
366
}
367
rc = readFile(javaVM);
368
if(verbose) {
369
dynamicLoadStats->readEndTime = j9time_usec_clock();
370
}
371
break;
372
373
#ifdef J9VM_OPT_ZIP_SUPPORT
374
case CPE_TYPE_JAR:
375
if (convertToClassFilename(javaVM, className, classNameLength)) {
376
rc = -1;
377
break;
378
}
379
if(verbose) {
380
dynamicLoadStats->readStartTime = j9time_usec_clock();
381
}
382
rc = readZip(javaVM, cpEntry);
383
if(verbose) {
384
dynamicLoadStats->readEndTime = j9time_usec_clock();
385
}
386
break;
387
#endif
388
389
case CPE_TYPE_JIMAGE:
390
if (NULL != j9module) {
391
if (convertToClassFilename(javaVM, className, classNameLength)) {
392
rc = -1;
393
break;
394
}
395
if(verbose) {
396
dynamicLoadStats->readStartTime = j9time_usec_clock();
397
}
398
rc = readFileFromJImage(vmThread, j9module, moduleName, javaVM->modulesPathEntry);
399
if(verbose) {
400
dynamicLoadStats->readEndTime = j9time_usec_clock();
401
}
402
}
403
break;
404
405
case CPE_TYPE_UNUSABLE:
406
/* Skip this entry */
407
rc = 1;
408
break;
409
410
default:
411
/* Should never get here. */
412
rc = 1;
413
Trc_BCU_searchClassInCPEntry_UnexpectedCPE(cpEntry->path, cpEntry->type);
414
Trc_BCU_Assert_ShouldNeverHappen();
415
break;
416
}
417
418
return rc;
419
}
420
421
422
423
/*
424
Compute the file system name for a class called className in the specified classPath entry.
425
Return 0 on success, non-zero on error.
426
*/
427
428
static IDATA
429
convertToOSFilename (J9JavaVM * javaVM, U_8 * dir, UDATA dirLength, U_8 * moduleDir, U_8 * className, UDATA classNameLength) {
430
431
PORT_ACCESS_FROM_JAVAVM(javaVM);
432
U_32 i;
433
UDATA filenameLength;
434
U_8 *filename;
435
U_8 *writePos;
436
U_8 pathSeparator;
437
UDATA moduleDirLength = 0;
438
UDATA requiredSize = dirLength + 1 + classNameLength + SUFFIX_LENGTH + 1;
439
440
if (NULL != moduleDir) {
441
moduleDirLength = strlen((const char*)moduleDir);
442
requiredSize += (moduleDirLength + 1);
443
}
444
445
CHECK_BUFFER(javaVM->dynamicLoadBuffers->searchFilenameBuffer,
446
javaVM->dynamicLoadBuffers->searchFilenameSize,
447
ROUND_TO(ROUNDING_GRANULARITY, requiredSize));
448
449
filenameLength = javaVM->dynamicLoadBuffers->searchFilenameSize;
450
filename = javaVM->dynamicLoadBuffers->searchFilenameBuffer;
451
452
pathSeparator = (U_8) javaVM->pathSeparator;
453
454
/* copy the possible directory name into the search buffer */
455
memcpy(filename, dir, dirLength);
456
writePos = &filename[dirLength];
457
if (filename[dirLength - 1] != pathSeparator
458
#if defined(WIN32) || defined(OS2)
459
&& filename[dirLength - 1] != ':' /* so that 'J:' doesn't turn into 'J:\' */
460
#endif
461
) {
462
*writePos++ = pathSeparator;
463
}
464
465
if (NULL != moduleDir) {
466
memcpy(writePos, moduleDir, moduleDirLength);
467
writePos += moduleDirLength;
468
*writePos++ = pathSeparator;
469
}
470
471
/* WARNING: this does not handle multi-byte walks yet */
472
for (i = 0; i < classNameLength; i++) {
473
if (className[i] == '/') {
474
*writePos++ = pathSeparator;
475
} else {
476
*writePos++ = className[i];
477
}
478
}
479
480
/* tack on the final .class */
481
memcpy(writePos, classSuffix, SUFFIX_LENGTH);
482
writePos[SUFFIX_LENGTH] = 0;
483
return 0;
484
}
485
486
487
488
/*
489
Verify that the internal dynamic loader buffers used to hold the Sun class file are large enough
490
to accommodate @sunClassFileSize bytes. Grow buffers if necessary.
491
492
Return 0 on success, non-zero on error.
493
*/
494
495
static IDATA
496
checkSunClassFileBuffers (J9JavaVM * javaVM, U_32 sunClassFileSize) {
497
498
PORT_ACCESS_FROM_JAVAVM(javaVM);
499
500
/* Users assume that the buffer pointer is NULLed in the allocation failure path in the MACRO */
501
CHECK_BUFFER(javaVM->dynamicLoadBuffers->sunClassFileBuffer,
502
javaVM->dynamicLoadBuffers->sunClassFileSize, ROUND_TO(ROUNDING_GRANULARITY, sunClassFileSize));
503
504
return 0;
505
}
506
507
/**
508
* Compute the file system name for a class called className in the specified classPath entry.
509
* Return 0 on success, non-zero on error.
510
*/
511
static IDATA
512
convertToClassFilename (J9JavaVM * javaVM, U_8 * className, UDATA classNameLength) {
513
514
PORT_ACCESS_FROM_JAVAVM(javaVM);
515
UDATA filenameLength;
516
U_8 *filename;
517
518
CHECK_BUFFER(javaVM->dynamicLoadBuffers->searchFilenameBuffer,
519
javaVM->dynamicLoadBuffers->searchFilenameSize, ROUND_TO(ROUNDING_GRANULARITY, (classNameLength + SUFFIX_LENGTH + 1)));
520
521
filenameLength = javaVM->dynamicLoadBuffers->searchFilenameSize;
522
filename = javaVM->dynamicLoadBuffers->searchFilenameBuffer;
523
524
/* copy the class name into the search buffer */
525
memcpy(filename, className, classNameLength);
526
527
/* tack on the final .class */
528
memcpy(&filename[classNameLength], classSuffix, SUFFIX_LENGTH);
529
filename[classNameLength + SUFFIX_LENGTH] = 0;
530
return 0;
531
}
532
533
/*
534
Attempt to read the file whose name is in the global name search buffer.
535
536
Return 0 on success.
537
1, no such file (non fatal error)
538
-1, for read error
539
*/
540
541
static IDATA
542
readFile (J9JavaVM * javaVM) {
543
544
PORT_ACCESS_FROM_JAVAVM(javaVM);
545
546
I_64 actualFileSize;
547
IDATA bytesRead;
548
U_32 fileSize;
549
IDATA fd = j9file_open((char *) javaVM->dynamicLoadBuffers->searchFilenameBuffer, EsOpenRead, 0);
550
551
if (fd == -1) {
552
return 1;
553
}
554
555
actualFileSize = j9file_seek(fd, 0, EsSeekEnd);
556
/* Restrict class file size to < 2G */
557
if ((actualFileSize == -1) || (actualFileSize > J9CONST64(0x7FFFFFFF))) {
558
goto _failedFileRead;
559
}
560
fileSize = (U_32)actualFileSize;
561
562
if (checkSunClassFileBuffers (javaVM, fileSize)) {
563
goto _failedFileRead;
564
}
565
566
j9file_seek(fd, 0, EsSeekSet);
567
bytesRead = j9file_read(fd, javaVM->dynamicLoadBuffers->sunClassFileBuffer, fileSize);
568
if ((U_32) bytesRead != fileSize) {
569
goto _failedFileRead;
570
}
571
javaVM->dynamicLoadBuffers->currentSunClassFileSize = fileSize;
572
j9file_close(fd);
573
return 0;
574
575
_failedFileRead:
576
j9file_close(fd);
577
return -1;
578
}
579
580
581
582
#if (defined(J9VM_OPT_ZIP_SUPPORT))
583
/*
584
Attempt to read the file whose name is in the global name search buffer from the
585
zip file specified by the cpEntry.
586
587
Return 0 on success.
588
1, no such file (non fatal error)
589
-1, for read error
590
*/
591
592
static IDATA
593
readZip (J9JavaVM * javaVM, J9ClassPathEntry * cpEntry) {
594
595
VMI_ACCESS_FROM_JAVAVM((JavaVM*)javaVM);
596
VMIZipFunctionTable* zipFunctions = (*VMI)->GetZipFunctions(VMI);
597
598
VMIZipFile *zipFile;
599
VMIZipEntry entry;
600
I_32 result;
601
U_32 size;
602
IDATA filenameLength;
603
604
zipFile = (VMIZipFile *) (cpEntry->extraInfo);
605
606
/* Find the desired entry, if it is present. */
607
filenameLength = strlen((const char*)javaVM->dynamicLoadBuffers->searchFilenameBuffer);
608
zipFunctions->zip_initZipEntry (VMI, &entry);
609
result = zipFunctions->zip_getZipEntryWithSize (VMI, zipFile, &entry, (char *) javaVM->dynamicLoadBuffers->searchFilenameBuffer, filenameLength, ZIP_FLAG_READ_DATA_POINTER);
610
if (result) {
611
/* Class not found. */
612
result = 1;
613
goto finished;
614
}
615
616
size = entry.uncompressedSize;
617
if (checkSunClassFileBuffers(javaVM, size)) {
618
/* Out of memory. */
619
result = -1;
620
goto finished;
621
}
622
623
result = zipFunctions->zip_getZipEntryData (VMI, zipFile, &entry, javaVM->dynamicLoadBuffers->sunClassFileBuffer, size);
624
if (result) {
625
/* Error extracting data. */
626
result = 1;
627
goto finished;
628
}
629
630
javaVM->dynamicLoadBuffers->currentSunClassFileSize = size;
631
632
finished:
633
zipFunctions->zip_freeZipEntry(VMI, &entry);
634
return result;
635
}
636
637
#endif /* J9VM_OPT_ZIP_SUPPORT */
638
639
/**
640
* Attempts to locate file whose name is in the global name search buffer in the JImage file specified by cpEntry in the give module.
641
*
642
* Returns 0 on success, 1 file is not found, -1 on error
643
*/
644
static IDATA
645
readFileFromJImage (J9VMThread *vmThread, J9Module *j9module, U_8 *moduleName, J9ClassPathEntry *cpEntry)
646
{
647
J9JavaVM *javaVM = vmThread->javaVM;
648
J9JImageIntf *jimageIntf = javaVM->jimageIntf;
649
UDATA jimageHandle = (UDATA)cpEntry->extraInfo;
650
UDATA resourceLocation = 0;
651
I_64 size = 0;
652
J9TranslationBufferSet *dynamicLoadBuffers = javaVM->dynamicLoadBuffers;
653
const char *resourceName = (const char *)dynamicLoadBuffers->searchFilenameBuffer;
654
I_32 rc = J9JIMAGE_NO_ERROR;
655
656
PORT_ACCESS_FROM_JAVAVM(javaVM);
657
658
Trc_BCU_readFileFromJImage_Entry(resourceName);
659
660
Trc_BCU_Assert_True(NULL != j9module);
661
662
rc = jimageIntf->jimageFindResource(jimageIntf, jimageHandle, (const char *)moduleName, resourceName, &resourceLocation, &size);
663
if (J9JIMAGE_NO_ERROR == rc) {
664
Trc_BCU_readFileFromJImage_LookupPassed_V1(moduleName, resourceName);
665
if (checkSunClassFileBuffers(javaVM, (U_32)size)) {
666
/* Out of memory. */
667
Trc_BCU_readFileFromJImage_BufferAllocationFailed_V1(moduleName, resourceName, size);
668
rc = -1;
669
} else {
670
rc = jimageIntf->jimageGetResource(jimageIntf, jimageHandle, resourceLocation, (char *)dynamicLoadBuffers->sunClassFileBuffer, dynamicLoadBuffers->sunClassFileSize, NULL);
671
if (J9JIMAGE_NO_ERROR == rc) {
672
dynamicLoadBuffers->currentSunClassFileSize = (UDATA)size;
673
rc = 0;
674
} else {
675
rc = -1;
676
}
677
}
678
jimageIntf->jimageFreeResourceLocation(jimageIntf, jimageHandle, resourceLocation);
679
} else {
680
Trc_BCU_readFileFromJImage_LookupFailed_V1(moduleName, resourceName, rc);
681
rc = (J9JIMAGE_RESOURCE_NOT_FOUND == rc) ? 1 : -1;
682
}
683
684
Trc_BCU_readFileFromJImage_Exit(rc);
685
686
return rc;
687
}
688
689
#endif /* J9VM_OPT_DYNAMIC_LOAD_SUPPORT */ /* End File Level Build Flags */
690
691