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 if (is_vm_statically_linked()) {
64 return os::lookup_function(name);
65 }
66
67 assert(_zip_handle != nullptr, "invariant");
68 void* func = os::dll_lookup(_zip_handle, name);
69 if (func == nullptr && vm_exit_on_failure) {
70 char msg[256] = "";
71 jio_snprintf(&msg[0], sizeof msg, "Could not resolve \"%s\"", name);
72 vm_exit_during_initialization(&msg[0], path);
73 }
74 return func;
75 }
76
77 static void store_function_pointers(const char* path, bool vm_exit_on_failure) {
78 assert(_zip_handle != nullptr, "invariant");
79 ZIP_Open = CAST_TO_FN_PTR(ZIP_Open_t, dll_lookup("ZIP_Open", path, vm_exit_on_failure));
80 ZIP_Close = CAST_TO_FN_PTR(ZIP_Close_t, dll_lookup("ZIP_Close", path, vm_exit_on_failure));
81 ZIP_FindEntry = CAST_TO_FN_PTR(ZIP_FindEntry_t, dll_lookup("ZIP_FindEntry", path, vm_exit_on_failure));
82 ZIP_ReadEntry = CAST_TO_FN_PTR(ZIP_ReadEntry_t, dll_lookup("ZIP_ReadEntry", path, vm_exit_on_failure));
83 ZIP_CRC32 = CAST_TO_FN_PTR(ZIP_CRC32_t, dll_lookup("ZIP_CRC32", path, vm_exit_on_failure));
84 // The following entry points are most likely optional from a zip library implementation perspective.
85 // Hence no vm_exit on a resolution failure. Further refactorings should investigate this,
86 // and if possible, streamline setting all entry points consistently.
87 ZIP_GZip_InitParams = CAST_TO_FN_PTR(ZIP_GZip_InitParams_t, dll_lookup("ZIP_GZip_InitParams", path, false));
88 ZIP_GZip_Fully = CAST_TO_FN_PTR(ZIP_GZip_Fully_t, dll_lookup("ZIP_GZip_Fully", path, false));
89 }
90
91 static void load_zip_library(bool vm_exit_on_failure) {
92 assert(!is_loaded(), "should not load zip library twice");
93 char path[JVM_MAXPATHLEN];
94
95 if (is_vm_statically_linked()) {
96 _zip_handle = os::get_default_process_handle();
97 } else {
98 // Load the libzip shared library and lookup the needed functions.
99 if (os::dll_locate_lib(&path[0], sizeof path, Arguments::get_dll_dir(), "zip")) {
100 char ebuf[1024];
101 _zip_handle = os::dll_load(&path[0], &ebuf[0], sizeof ebuf);
102 }
160 }
161
162 void ZipLibrary::close(jzfile* zip) {
163 assert(is_loaded(), "invariant");
164 assert(ZIP_Close != nullptr, "invariant");
165 ZIP_Close(zip);
166 }
167
168 jzentry* ZipLibrary::find_entry(jzfile* zip, const char* name, jint* sizeP, jint* nameLen) {
169 initialize();
170 assert(ZIP_FindEntry != nullptr, "invariant");
171 return ZIP_FindEntry(zip, name, sizeP, nameLen);
172 }
173
174 jboolean ZipLibrary::read_entry(jzfile* zip, jzentry* entry, unsigned char* buf, char* namebuf) {
175 initialize();
176 assert(ZIP_ReadEntry != nullptr, "invariant");
177 return ZIP_ReadEntry(zip, entry, buf, namebuf);
178 }
179
180 jint ZipLibrary::crc32(jint crc, const jbyte* buf, jint len) {
181 initialize();
182 assert(ZIP_CRC32 != nullptr, "invariant");
183 return ZIP_CRC32(crc, buf, len);
184 }
185
186 const char* ZipLibrary::init_params(size_t block_size, size_t* needed_out_size, size_t* needed_tmp_size, int level) {
187 initialize(false);
188 if (ZIP_GZip_InitParams == nullptr) {
189 return "Cannot get ZIP_GZip_InitParams function";
190 }
191 return ZIP_GZip_InitParams(block_size, needed_out_size, needed_tmp_size, level);
192 }
193
194 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) {
195 initialize(false);
196 if (ZIP_GZip_Fully == nullptr) {
197 *pmsg = "Cannot get ZIP_GZip_Fully function";
198 return 0;
199 }
|
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 if (is_vm_statically_linked()) {
66 return os::lookup_function(name);
67 }
68
69 assert(_zip_handle != nullptr, "invariant");
70 void* func = os::dll_lookup(_zip_handle, name);
71 if (func == nullptr && vm_exit_on_failure) {
72 char msg[256] = "";
73 jio_snprintf(&msg[0], sizeof msg, "Could not resolve \"%s\"", name);
74 vm_exit_during_initialization(&msg[0], path);
75 }
76 return func;
77 }
78
79 static void store_function_pointers(const char* path, bool vm_exit_on_failure) {
80 assert(_zip_handle != nullptr, "invariant");
81 ZIP_Open = CAST_TO_FN_PTR(ZIP_Open_t, dll_lookup("ZIP_Open", path, vm_exit_on_failure));
82 ZIP_Close = CAST_TO_FN_PTR(ZIP_Close_t, dll_lookup("ZIP_Close", path, vm_exit_on_failure));
83 ZIP_FindEntry = CAST_TO_FN_PTR(ZIP_FindEntry_t, dll_lookup("ZIP_FindEntry", path, vm_exit_on_failure));
84 ZIP_ReadEntry = CAST_TO_FN_PTR(ZIP_ReadEntry_t, dll_lookup("ZIP_ReadEntry", path, vm_exit_on_failure));
85 ZIP_FreeEntry = CAST_TO_FN_PTR(ZIP_FreeEntry_t, dll_lookup("ZIP_FreeEntry", path, vm_exit_on_failure));
86 ZIP_CRC32 = CAST_TO_FN_PTR(ZIP_CRC32_t, dll_lookup("ZIP_CRC32", path, vm_exit_on_failure));
87 // The following entry points are most likely optional from a zip library implementation perspective.
88 // Hence no vm_exit on a resolution failure. Further refactorings should investigate this,
89 // and if possible, streamline setting all entry points consistently.
90 ZIP_GZip_InitParams = CAST_TO_FN_PTR(ZIP_GZip_InitParams_t, dll_lookup("ZIP_GZip_InitParams", path, false));
91 ZIP_GZip_Fully = CAST_TO_FN_PTR(ZIP_GZip_Fully_t, dll_lookup("ZIP_GZip_Fully", path, false));
92 }
93
94 static void load_zip_library(bool vm_exit_on_failure) {
95 assert(!is_loaded(), "should not load zip library twice");
96 char path[JVM_MAXPATHLEN];
97
98 if (is_vm_statically_linked()) {
99 _zip_handle = os::get_default_process_handle();
100 } else {
101 // Load the libzip shared library and lookup the needed functions.
102 if (os::dll_locate_lib(&path[0], sizeof path, Arguments::get_dll_dir(), "zip")) {
103 char ebuf[1024];
104 _zip_handle = os::dll_load(&path[0], &ebuf[0], sizeof ebuf);
105 }
163 }
164
165 void ZipLibrary::close(jzfile* zip) {
166 assert(is_loaded(), "invariant");
167 assert(ZIP_Close != nullptr, "invariant");
168 ZIP_Close(zip);
169 }
170
171 jzentry* ZipLibrary::find_entry(jzfile* zip, const char* name, jint* sizeP, jint* nameLen) {
172 initialize();
173 assert(ZIP_FindEntry != nullptr, "invariant");
174 return ZIP_FindEntry(zip, name, sizeP, nameLen);
175 }
176
177 jboolean ZipLibrary::read_entry(jzfile* zip, jzentry* entry, unsigned char* buf, char* namebuf) {
178 initialize();
179 assert(ZIP_ReadEntry != nullptr, "invariant");
180 return ZIP_ReadEntry(zip, entry, buf, namebuf);
181 }
182
183 void ZipLibrary::free_entry(jzfile* zip, jzentry* entry) {
184 initialize();
185 assert(ZIP_FreeEntry != nullptr, "invariant");
186 ZIP_FreeEntry(zip, entry);
187 }
188
189 jint ZipLibrary::crc32(jint crc, const jbyte* buf, jint len) {
190 initialize();
191 assert(ZIP_CRC32 != nullptr, "invariant");
192 return ZIP_CRC32(crc, buf, len);
193 }
194
195 const char* ZipLibrary::init_params(size_t block_size, size_t* needed_out_size, size_t* needed_tmp_size, int level) {
196 initialize(false);
197 if (ZIP_GZip_InitParams == nullptr) {
198 return "Cannot get ZIP_GZip_InitParams function";
199 }
200 return ZIP_GZip_InitParams(block_size, needed_out_size, needed_tmp_size, level);
201 }
202
203 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) {
204 initialize(false);
205 if (ZIP_GZip_Fully == nullptr) {
206 *pmsg = "Cannot get ZIP_GZip_Fully function";
207 return 0;
208 }
|