18 *
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 "jvm_io.h"
26 #include "runtime/arguments.hpp"
27 #include "runtime/interfaceSupport.inline.hpp"
28 #include "runtime/os.inline.hpp"
29 #include "runtime/semaphore.inline.hpp"
30 #include "runtime/thread.inline.hpp"
31 #include "utilities/zipLibrary.hpp"
32
33 // Entry points in zip.dll for loading zip/jar file entries
34 typedef void**(*ZIP_Open_t)(const char* name, char** pmsg);
35 typedef void(*ZIP_Close_t)(jzfile* zip);
36 typedef jzentry* (*ZIP_FindEntry_t)(jzfile* zip, const char* name, jint* sizeP, jint* nameLen);
37 typedef jboolean(*ZIP_ReadEntry_t)(jzfile* zip, jzentry* entry, unsigned char* buf, char* namebuf);
38 typedef jint(*ZIP_CRC32_t)(jint crc, const jbyte* buf, jint len);
39 typedef const char* (*ZIP_GZip_InitParams_t)(size_t, size_t*, size_t*, int);
40 typedef size_t(*ZIP_GZip_Fully_t)(char*, size_t, char*, size_t, char*, size_t, int, char*, char const**);
41
42 static ZIP_Open_t ZIP_Open = nullptr;
43 static ZIP_Close_t ZIP_Close = nullptr;
44 static ZIP_FindEntry_t ZIP_FindEntry = nullptr;
45 static ZIP_ReadEntry_t ZIP_ReadEntry = nullptr;
46 static ZIP_CRC32_t ZIP_CRC32 = nullptr;
47 static ZIP_GZip_InitParams_t ZIP_GZip_InitParams = nullptr;
48 static ZIP_GZip_Fully_t ZIP_GZip_Fully = nullptr;
49
50 static void* _zip_handle = nullptr;
51 static bool _loaded = false;
52
53 static inline bool is_loaded() {
54 return Atomic::load_acquire(&_loaded);
55 }
56
57 static inline bool not_loaded() {
58 return !is_loaded();
59 }
60
61 static void* dll_lookup(const char* name, const char* path, bool vm_exit_on_failure) {
62 if (is_vm_statically_linked()) {
63 return os::lookup_function(name);
64 }
65
66 assert(_zip_handle != nullptr, "invariant");
67 void* func = os::dll_lookup(_zip_handle, name);
68 if (func == nullptr && vm_exit_on_failure) {
69 char msg[256] = "";
70 jio_snprintf(&msg[0], sizeof msg, "Could not resolve \"%s\"", name);
71 vm_exit_during_initialization(&msg[0], path);
72 }
73 return func;
74 }
75
76 static void store_function_pointers(const char* path, bool vm_exit_on_failure) {
77 assert(_zip_handle != nullptr, "invariant");
78 ZIP_Open = CAST_TO_FN_PTR(ZIP_Open_t, dll_lookup("ZIP_Open", path, vm_exit_on_failure));
79 ZIP_Close = CAST_TO_FN_PTR(ZIP_Close_t, dll_lookup("ZIP_Close", path, vm_exit_on_failure));
80 ZIP_FindEntry = CAST_TO_FN_PTR(ZIP_FindEntry_t, dll_lookup("ZIP_FindEntry", path, vm_exit_on_failure));
81 ZIP_ReadEntry = CAST_TO_FN_PTR(ZIP_ReadEntry_t, dll_lookup("ZIP_ReadEntry", 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
94 if (is_vm_statically_linked()) {
95 _zip_handle = os::get_default_process_handle();
96 } else {
97 // Load the libzip shared library and lookup the needed functions.
98 if (os::dll_locate_lib(&path[0], sizeof path, Arguments::get_dll_dir(), "zip")) {
99 char ebuf[1024];
100 _zip_handle = os::dll_load(&path[0], &ebuf[0], sizeof ebuf);
101 }
159 }
160
161 void ZipLibrary::close(jzfile* zip) {
162 assert(is_loaded(), "invariant");
163 assert(ZIP_Close != nullptr, "invariant");
164 ZIP_Close(zip);
165 }
166
167 jzentry* ZipLibrary::find_entry(jzfile* zip, const char* name, jint* sizeP, jint* nameLen) {
168 initialize();
169 assert(ZIP_FindEntry != nullptr, "invariant");
170 return ZIP_FindEntry(zip, name, sizeP, nameLen);
171 }
172
173 jboolean ZipLibrary::read_entry(jzfile* zip, jzentry* entry, unsigned char* buf, char* namebuf) {
174 initialize();
175 assert(ZIP_ReadEntry != nullptr, "invariant");
176 return ZIP_ReadEntry(zip, entry, buf, namebuf);
177 }
178
179 jint ZipLibrary::crc32(jint crc, const jbyte* buf, jint len) {
180 initialize();
181 assert(ZIP_CRC32 != nullptr, "invariant");
182 return ZIP_CRC32(crc, buf, len);
183 }
184
185 const char* ZipLibrary::init_params(size_t block_size, size_t* needed_out_size, size_t* needed_tmp_size, int level) {
186 initialize(false);
187 if (ZIP_GZip_InitParams == nullptr) {
188 return "Cannot get ZIP_GZip_InitParams function";
189 }
190 return ZIP_GZip_InitParams(block_size, needed_out_size, needed_tmp_size, level);
191 }
192
193 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) {
194 initialize(false);
195 if (ZIP_GZip_Fully == nullptr) {
196 *pmsg = "Cannot get ZIP_GZip_Fully function";
197 return 0;
198 }
|
18 *
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 "jvm_io.h"
26 #include "runtime/arguments.hpp"
27 #include "runtime/interfaceSupport.inline.hpp"
28 #include "runtime/os.inline.hpp"
29 #include "runtime/semaphore.inline.hpp"
30 #include "runtime/thread.inline.hpp"
31 #include "utilities/zipLibrary.hpp"
32
33 // Entry points in zip.dll for loading zip/jar file entries
34 typedef void**(*ZIP_Open_t)(const char* name, char** pmsg);
35 typedef void(*ZIP_Close_t)(jzfile* zip);
36 typedef jzentry* (*ZIP_FindEntry_t)(jzfile* zip, const char* name, jint* sizeP, jint* nameLen);
37 typedef jboolean(*ZIP_ReadEntry_t)(jzfile* zip, jzentry* entry, unsigned char* buf, char* namebuf);
38 typedef void(*ZIP_FreeEntry_t)(jzfile *zip, jzentry *entry);
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_FreeEntry_t ZIP_FreeEntry = nullptr;
48 static ZIP_CRC32_t ZIP_CRC32 = nullptr;
49 static ZIP_GZip_InitParams_t ZIP_GZip_InitParams = nullptr;
50 static ZIP_GZip_Fully_t ZIP_GZip_Fully = nullptr;
51
52 static void* _zip_handle = nullptr;
53 static bool _loaded = false;
54
55 static inline bool is_loaded() {
56 return Atomic::load_acquire(&_loaded);
57 }
58
59 static inline bool not_loaded() {
60 return !is_loaded();
61 }
62
63 static void* dll_lookup(const char* name, const char* path, bool vm_exit_on_failure) {
64 if (is_vm_statically_linked()) {
65 return os::lookup_function(name);
66 }
67
68 assert(_zip_handle != nullptr, "invariant");
69 void* func = os::dll_lookup(_zip_handle, name);
70 if (func == nullptr && vm_exit_on_failure) {
71 char msg[256] = "";
72 jio_snprintf(&msg[0], sizeof msg, "Could not resolve \"%s\"", name);
73 vm_exit_during_initialization(&msg[0], path);
74 }
75 return func;
76 }
77
78 static void store_function_pointers(const char* path, bool vm_exit_on_failure) {
79 assert(_zip_handle != nullptr, "invariant");
80 ZIP_Open = CAST_TO_FN_PTR(ZIP_Open_t, dll_lookup("ZIP_Open", path, vm_exit_on_failure));
81 ZIP_Close = CAST_TO_FN_PTR(ZIP_Close_t, dll_lookup("ZIP_Close", path, vm_exit_on_failure));
82 ZIP_FindEntry = CAST_TO_FN_PTR(ZIP_FindEntry_t, dll_lookup("ZIP_FindEntry", path, vm_exit_on_failure));
83 ZIP_ReadEntry = CAST_TO_FN_PTR(ZIP_ReadEntry_t, dll_lookup("ZIP_ReadEntry", path, vm_exit_on_failure));
84 ZIP_FreeEntry = CAST_TO_FN_PTR(ZIP_FreeEntry_t, dll_lookup("ZIP_FreeEntry", path, vm_exit_on_failure));
85 ZIP_CRC32 = CAST_TO_FN_PTR(ZIP_CRC32_t, dll_lookup("ZIP_CRC32", path, vm_exit_on_failure));
86 // The following entry points are most likely optional from a zip library implementation perspective.
87 // Hence no vm_exit on a resolution failure. Further refactorings should investigate this,
88 // and if possible, streamline setting all entry points consistently.
89 ZIP_GZip_InitParams = CAST_TO_FN_PTR(ZIP_GZip_InitParams_t, dll_lookup("ZIP_GZip_InitParams", path, false));
90 ZIP_GZip_Fully = CAST_TO_FN_PTR(ZIP_GZip_Fully_t, dll_lookup("ZIP_GZip_Fully", path, false));
91 }
92
93 static void load_zip_library(bool vm_exit_on_failure) {
94 assert(!is_loaded(), "should not load zip library twice");
95 char path[JVM_MAXPATHLEN];
96
97 if (is_vm_statically_linked()) {
98 _zip_handle = os::get_default_process_handle();
99 } else {
100 // Load the libzip shared library and lookup the needed functions.
101 if (os::dll_locate_lib(&path[0], sizeof path, Arguments::get_dll_dir(), "zip")) {
102 char ebuf[1024];
103 _zip_handle = os::dll_load(&path[0], &ebuf[0], sizeof ebuf);
104 }
162 }
163
164 void ZipLibrary::close(jzfile* zip) {
165 assert(is_loaded(), "invariant");
166 assert(ZIP_Close != nullptr, "invariant");
167 ZIP_Close(zip);
168 }
169
170 jzentry* ZipLibrary::find_entry(jzfile* zip, const char* name, jint* sizeP, jint* nameLen) {
171 initialize();
172 assert(ZIP_FindEntry != nullptr, "invariant");
173 return ZIP_FindEntry(zip, name, sizeP, nameLen);
174 }
175
176 jboolean ZipLibrary::read_entry(jzfile* zip, jzentry* entry, unsigned char* buf, char* namebuf) {
177 initialize();
178 assert(ZIP_ReadEntry != nullptr, "invariant");
179 return ZIP_ReadEntry(zip, entry, buf, namebuf);
180 }
181
182 void ZipLibrary::free_entry(jzfile* zip, jzentry* entry) {
183 initialize();
184 assert(ZIP_FreeEntry != nullptr, "invariant");
185 ZIP_FreeEntry(zip, entry);
186 }
187
188 jint ZipLibrary::crc32(jint crc, const jbyte* buf, jint len) {
189 initialize();
190 assert(ZIP_CRC32 != nullptr, "invariant");
191 return ZIP_CRC32(crc, buf, len);
192 }
193
194 const char* ZipLibrary::init_params(size_t block_size, size_t* needed_out_size, size_t* needed_tmp_size, int level) {
195 initialize(false);
196 if (ZIP_GZip_InitParams == nullptr) {
197 return "Cannot get ZIP_GZip_InitParams function";
198 }
199 return ZIP_GZip_InitParams(block_size, needed_out_size, needed_tmp_size, level);
200 }
201
202 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) {
203 initialize(false);
204 if (ZIP_GZip_Fully == nullptr) {
205 *pmsg = "Cannot get ZIP_GZip_Fully function";
206 return 0;
207 }
|