19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "jvm_io.h"
27 #include "runtime/arguments.hpp"
28 #include "runtime/interfaceSupport.inline.hpp"
29 #include "runtime/os.inline.hpp"
30 #include "runtime/semaphore.inline.hpp"
31 #include "runtime/thread.inline.hpp"
32 #include "utilities/zipLibrary.hpp"
33
34 // Entry points in zip.dll for loading zip/jar file entries
35 typedef void**(*ZIP_Open_t)(const char* name, char** pmsg);
36 typedef void(*ZIP_Close_t)(jzfile* zip);
37 typedef jzentry* (*ZIP_FindEntry_t)(jzfile* zip, const char* name, jint* sizeP, jint* nameLen);
38 typedef jboolean(*ZIP_ReadEntry_t)(jzfile* zip, jzentry* entry, unsigned char* buf, char* namebuf);
39 typedef jint(*ZIP_CRC32_t)(jint crc, const jbyte* buf, jint len);
40 typedef const char* (*ZIP_GZip_InitParams_t)(size_t, size_t*, size_t*, int);
41 typedef size_t(*ZIP_GZip_Fully_t)(char*, size_t, char*, size_t, char*, size_t, int, char*, char const**);
42
43 static ZIP_Open_t ZIP_Open = nullptr;
44 static ZIP_Close_t ZIP_Close = nullptr;
45 static ZIP_FindEntry_t ZIP_FindEntry = nullptr;
46 static ZIP_ReadEntry_t ZIP_ReadEntry = nullptr;
47 static ZIP_CRC32_t ZIP_CRC32 = nullptr;
48 static ZIP_GZip_InitParams_t ZIP_GZip_InitParams = nullptr;
49 static ZIP_GZip_Fully_t ZIP_GZip_Fully = nullptr;
50
51 static void* _zip_handle = nullptr;
52 static bool _loaded = false;
53
54 static inline bool is_loaded() {
55 return Atomic::load_acquire(&_loaded);
56 }
57
58 static inline bool not_loaded() {
59 return !is_loaded();
60 }
61
62 static void* dll_lookup(const char* name, const char* path, bool vm_exit_on_failure) {
63 assert(_zip_handle != nullptr, "invariant");
64 void* func = os::dll_lookup(_zip_handle, name);
65 if (func == nullptr && vm_exit_on_failure) {
66 char msg[256] = "";
67 jio_snprintf(&msg[0], sizeof msg, "Could not resolve \"%s\"", name);
68 vm_exit_during_initialization(&msg[0], path);
69 }
70 return func;
71 }
72
73 static void store_function_pointers(const char* path, bool vm_exit_on_failure) {
74 assert(_zip_handle != nullptr, "invariant");
75 ZIP_Open = CAST_TO_FN_PTR(ZIP_Open_t, dll_lookup("ZIP_Open", path, vm_exit_on_failure));
76 ZIP_Close = CAST_TO_FN_PTR(ZIP_Close_t, dll_lookup("ZIP_Close", path, vm_exit_on_failure));
77 ZIP_FindEntry = CAST_TO_FN_PTR(ZIP_FindEntry_t, dll_lookup("ZIP_FindEntry", path, vm_exit_on_failure));
78 ZIP_ReadEntry = CAST_TO_FN_PTR(ZIP_ReadEntry_t, dll_lookup("ZIP_ReadEntry", path, vm_exit_on_failure));
79 ZIP_CRC32 = CAST_TO_FN_PTR(ZIP_CRC32_t, dll_lookup("ZIP_CRC32", path, vm_exit_on_failure));
80 // The following entry points are most likely optional from a zip library implementation perspective.
81 // Hence no vm_exit on a resolution failure. Further refactorings should investigate this,
82 // and if possible, streamline setting all entry points consistently.
83 ZIP_GZip_InitParams = CAST_TO_FN_PTR(ZIP_GZip_InitParams_t, dll_lookup("ZIP_GZip_InitParams", path, false));
84 ZIP_GZip_Fully = CAST_TO_FN_PTR(ZIP_GZip_Fully_t, dll_lookup("ZIP_GZip_Fully", path, false));
85 }
86
87 static void load_zip_library(bool vm_exit_on_failure) {
88 assert(!is_loaded(), "should not load zip library twice");
89 char path[JVM_MAXPATHLEN];
90 if (os::dll_locate_lib(&path[0], sizeof path, Arguments::get_dll_dir(), "zip")) {
91 char ebuf[1024];
92 _zip_handle = os::dll_load(&path[0], &ebuf[0], sizeof ebuf);
93 }
94 if (_zip_handle == nullptr) {
95 if (vm_exit_on_failure) {
96 vm_exit_during_initialization("Unable to load zip library", &path[0]);
97 }
98 return;
149 }
150
151 void ZipLibrary::close(jzfile* zip) {
152 assert(is_loaded(), "invariant");
153 assert(ZIP_Close != nullptr, "invariant");
154 ZIP_Close(zip);
155 }
156
157 jzentry* ZipLibrary::find_entry(jzfile* zip, const char* name, jint* sizeP, jint* nameLen) {
158 initialize();
159 assert(ZIP_FindEntry != nullptr, "invariant");
160 return ZIP_FindEntry(zip, name, sizeP, nameLen);
161 }
162
163 jboolean ZipLibrary::read_entry(jzfile* zip, jzentry* entry, unsigned char* buf, char* namebuf) {
164 initialize();
165 assert(ZIP_ReadEntry != nullptr, "invariant");
166 return ZIP_ReadEntry(zip, entry, buf, namebuf);
167 }
168
169 jint ZipLibrary::crc32(jint crc, const jbyte* buf, jint len) {
170 initialize();
171 assert(ZIP_CRC32 != nullptr, "invariant");
172 return ZIP_CRC32(crc, buf, len);
173 }
174
175 const char* ZipLibrary::init_params(size_t block_size, size_t* needed_out_size, size_t* needed_tmp_size, int level) {
176 initialize(false);
177 if (ZIP_GZip_InitParams == nullptr) {
178 return "Cannot get ZIP_GZip_InitParams function";
179 }
180 return ZIP_GZip_InitParams(block_size, needed_out_size, needed_tmp_size, level);
181 }
182
183 size_t ZipLibrary::compress(char* in, size_t in_size, char* out, size_t out_size, char* tmp, size_t tmp_size, int level, char* buf, const char** pmsg) {
184 initialize(false);
185 if (ZIP_GZip_Fully == nullptr) {
186 *pmsg = "Cannot get ZIP_GZip_Fully function";
187 return 0;
188 }
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "jvm_io.h"
27 #include "runtime/arguments.hpp"
28 #include "runtime/interfaceSupport.inline.hpp"
29 #include "runtime/os.inline.hpp"
30 #include "runtime/semaphore.inline.hpp"
31 #include "runtime/thread.inline.hpp"
32 #include "utilities/zipLibrary.hpp"
33
34 // Entry points in zip.dll for loading zip/jar file entries
35 typedef void**(*ZIP_Open_t)(const char* name, char** pmsg);
36 typedef void(*ZIP_Close_t)(jzfile* zip);
37 typedef jzentry* (*ZIP_FindEntry_t)(jzfile* zip, const char* name, jint* sizeP, jint* nameLen);
38 typedef jboolean(*ZIP_ReadEntry_t)(jzfile* zip, jzentry* entry, unsigned char* buf, char* namebuf);
39 typedef void(*ZIP_FreeEntry_t)(jzfile *zip, jzentry *entry);
40 typedef jint(*ZIP_CRC32_t)(jint crc, const jbyte* buf, jint len);
41 typedef const char* (*ZIP_GZip_InitParams_t)(size_t, size_t*, size_t*, int);
42 typedef size_t(*ZIP_GZip_Fully_t)(char*, size_t, char*, size_t, char*, size_t, int, char*, char const**);
43
44 static ZIP_Open_t ZIP_Open = nullptr;
45 static ZIP_Close_t ZIP_Close = nullptr;
46 static ZIP_FindEntry_t ZIP_FindEntry = nullptr;
47 static ZIP_ReadEntry_t ZIP_ReadEntry = nullptr;
48 static ZIP_FreeEntry_t ZIP_FreeEntry = nullptr;
49 static ZIP_CRC32_t ZIP_CRC32 = nullptr;
50 static ZIP_GZip_InitParams_t ZIP_GZip_InitParams = nullptr;
51 static ZIP_GZip_Fully_t ZIP_GZip_Fully = nullptr;
52
53 static void* _zip_handle = nullptr;
54 static bool _loaded = false;
55
56 static inline bool is_loaded() {
57 return Atomic::load_acquire(&_loaded);
58 }
59
60 static inline bool not_loaded() {
61 return !is_loaded();
62 }
63
64 static void* dll_lookup(const char* name, const char* path, bool vm_exit_on_failure) {
65 assert(_zip_handle != nullptr, "invariant");
66 void* func = os::dll_lookup(_zip_handle, name);
67 if (func == nullptr && vm_exit_on_failure) {
68 char msg[256] = "";
69 jio_snprintf(&msg[0], sizeof msg, "Could not resolve \"%s\"", name);
70 vm_exit_during_initialization(&msg[0], path);
71 }
72 return func;
73 }
74
75 static void store_function_pointers(const char* path, bool vm_exit_on_failure) {
76 assert(_zip_handle != nullptr, "invariant");
77 ZIP_Open = CAST_TO_FN_PTR(ZIP_Open_t, dll_lookup("ZIP_Open", path, vm_exit_on_failure));
78 ZIP_Close = CAST_TO_FN_PTR(ZIP_Close_t, dll_lookup("ZIP_Close", path, vm_exit_on_failure));
79 ZIP_FindEntry = CAST_TO_FN_PTR(ZIP_FindEntry_t, dll_lookup("ZIP_FindEntry", path, vm_exit_on_failure));
80 ZIP_ReadEntry = CAST_TO_FN_PTR(ZIP_ReadEntry_t, dll_lookup("ZIP_ReadEntry", path, vm_exit_on_failure));
81 ZIP_FreeEntry = CAST_TO_FN_PTR(ZIP_FreeEntry_t, dll_lookup("ZIP_FreeEntry", path, vm_exit_on_failure));
82 ZIP_CRC32 = CAST_TO_FN_PTR(ZIP_CRC32_t, dll_lookup("ZIP_CRC32", path, vm_exit_on_failure));
83 // The following entry points are most likely optional from a zip library implementation perspective.
84 // Hence no vm_exit on a resolution failure. Further refactorings should investigate this,
85 // and if possible, streamline setting all entry points consistently.
86 ZIP_GZip_InitParams = CAST_TO_FN_PTR(ZIP_GZip_InitParams_t, dll_lookup("ZIP_GZip_InitParams", path, false));
87 ZIP_GZip_Fully = CAST_TO_FN_PTR(ZIP_GZip_Fully_t, dll_lookup("ZIP_GZip_Fully", path, false));
88 }
89
90 static void load_zip_library(bool vm_exit_on_failure) {
91 assert(!is_loaded(), "should not load zip library twice");
92 char path[JVM_MAXPATHLEN];
93 if (os::dll_locate_lib(&path[0], sizeof path, Arguments::get_dll_dir(), "zip")) {
94 char ebuf[1024];
95 _zip_handle = os::dll_load(&path[0], &ebuf[0], sizeof ebuf);
96 }
97 if (_zip_handle == nullptr) {
98 if (vm_exit_on_failure) {
99 vm_exit_during_initialization("Unable to load zip library", &path[0]);
100 }
101 return;
152 }
153
154 void ZipLibrary::close(jzfile* zip) {
155 assert(is_loaded(), "invariant");
156 assert(ZIP_Close != nullptr, "invariant");
157 ZIP_Close(zip);
158 }
159
160 jzentry* ZipLibrary::find_entry(jzfile* zip, const char* name, jint* sizeP, jint* nameLen) {
161 initialize();
162 assert(ZIP_FindEntry != nullptr, "invariant");
163 return ZIP_FindEntry(zip, name, sizeP, nameLen);
164 }
165
166 jboolean ZipLibrary::read_entry(jzfile* zip, jzentry* entry, unsigned char* buf, char* namebuf) {
167 initialize();
168 assert(ZIP_ReadEntry != nullptr, "invariant");
169 return ZIP_ReadEntry(zip, entry, buf, namebuf);
170 }
171
172 void ZipLibrary::free_entry(jzfile* zip, jzentry* entry) {
173 initialize();
174 assert(ZIP_FreeEntry != nullptr, "invariant");
175 ZIP_FreeEntry(zip, entry);
176 }
177
178 jint ZipLibrary::crc32(jint crc, const jbyte* buf, jint len) {
179 initialize();
180 assert(ZIP_CRC32 != nullptr, "invariant");
181 return ZIP_CRC32(crc, buf, len);
182 }
183
184 const char* ZipLibrary::init_params(size_t block_size, size_t* needed_out_size, size_t* needed_tmp_size, int level) {
185 initialize(false);
186 if (ZIP_GZip_InitParams == nullptr) {
187 return "Cannot get ZIP_GZip_InitParams function";
188 }
189 return ZIP_GZip_InitParams(block_size, needed_out_size, needed_tmp_size, level);
190 }
191
192 size_t ZipLibrary::compress(char* in, size_t in_size, char* out, size_t out_size, char* tmp, size_t tmp_size, int level, char* buf, const char** pmsg) {
193 initialize(false);
194 if (ZIP_GZip_Fully == nullptr) {
195 *pmsg = "Cannot get ZIP_GZip_Fully function";
196 return 0;
197 }
|