69 public static int sp_used_offset; // offset of CDSFileMapRegion::_used |
69 public static int sp_used_offset; // offset of CDSFileMapRegion::_used |
70 public static int size_t_size; // size of size_t |
70 public static int size_t_size; // size of size_t |
71 |
71 |
72 public static File jsa; // will be updated during test |
72 public static File jsa; // will be updated during test |
73 public static File orgJsaFile; // kept the original file not touched. |
73 public static File orgJsaFile; // kept the original file not touched. |
74 public static String[] shared_region_name = {"MiscCode", "ReadWrite", "ReadOnly", "MiscData"}; |
74 // The following should be consistent with the enum in the C++ MetaspaceShared class |
|
75 public static String[] shared_region_name = { |
|
76 "mc", // MiscCode |
|
77 "rw", // ReadWrite |
|
78 "ro", // ReadOnly |
|
79 "md", // MiscData |
|
80 "first_closed_archive", |
|
81 "last_closed_archive", |
|
82 "first_open_archive", |
|
83 "last_open_archive" |
|
84 }; |
|
85 |
75 public static int num_regions = shared_region_name.length; |
86 public static int num_regions = shared_region_name.length; |
76 public static String[] matchMessages = { |
87 public static String[] matchMessages = { |
77 "Unable to use shared archive", |
88 "Unable to use shared archive", |
78 "An error has occurred while processing the shared archive file.", |
89 "An error has occurred while processing the shared archive file.", |
79 "Checksum verification failed.", |
90 "Checksum verification failed.", |
100 public static int getFileHeaderSize(FileChannel fc) throws Exception { |
111 public static int getFileHeaderSize(FileChannel fc) throws Exception { |
101 if (file_header_size != -1) { |
112 if (file_header_size != -1) { |
102 return file_header_size; |
113 return file_header_size; |
103 } |
114 } |
104 // this is not real header size, it is struct size |
115 // this is not real header size, it is struct size |
|
116 int int_size = wb.getOffsetForName("int_size"); |
105 file_header_size = wb.getOffsetForName("file_header_size"); |
117 file_header_size = wb.getOffsetForName("file_header_size"); |
106 int offset_path_misc_info = wb.getOffsetForName("FileMapHeader::_paths_misc_info_size") - |
118 int offset_path_misc_info = wb.getOffsetForName("FileMapHeader::_paths_misc_info_size") - |
107 offset_magic; |
119 offset_magic; |
108 int path_misc_info_size = (int)readInt(fc, offset_path_misc_info, size_t_size); |
120 int path_misc_info_size = (int)readInt(fc, offset_path_misc_info, int_size); |
109 file_header_size += path_misc_info_size; //readInt(fc, offset_path_misc_info, size_t_size); |
121 file_header_size += path_misc_info_size; //readInt(fc, offset_path_misc_info, size_t_size); |
110 System.out.println("offset_path_misc_info = " + offset_path_misc_info); |
122 System.out.println("offset_path_misc_info = " + offset_path_misc_info); |
111 System.out.println("path_misc_info_size = " + path_misc_info_size); |
123 System.out.println("path_misc_info_size = " + path_misc_info_size); |
112 System.out.println("file_header_size = " + file_header_size); |
124 System.out.println("file_header_size = " + file_header_size); |
113 file_header_size = (int)align_up_page(file_header_size); |
125 file_header_size = (int)align_up_page(file_header_size); |
155 return FileChannel.open(jsa.toPath(), new HashSet<StandardOpenOption>(arry)); |
167 return FileChannel.open(jsa.toPath(), new HashSet<StandardOpenOption>(arry)); |
156 } |
168 } |
157 |
169 |
158 public static void modifyJsaContentRandomly() throws Exception { |
170 public static void modifyJsaContentRandomly() throws Exception { |
159 FileChannel fc = getFileChannel(); |
171 FileChannel fc = getFileChannel(); |
160 // corrupt random area in the data areas (MiscCode, ReadWrite, ReadOnly, MiscData) |
172 // corrupt random area in the data areas |
161 long[] used = new long[num_regions]; // record used bytes |
173 long[] used = new long[num_regions]; // record used bytes |
162 long start0, start, end, off; |
174 long start0, start, end, off; |
163 int used_offset, path_info_size; |
175 int used_offset, path_info_size; |
164 |
176 |
165 int bufSize; |
177 int bufSize; |
166 System.out.printf("%-12s%-12s%-12s%-12s%-12s\n", "Space Name", "Offset", "Used bytes", "Reg Start", "Random Offset"); |
178 System.out.printf("%-24s%12s%12s%16s\n", "Space Name", "Used bytes", "Reg Start", "Random Offset"); |
167 start0 = getFileHeaderSize(fc); |
179 start0 = getFileHeaderSize(fc); |
168 for (int i = 0; i < num_regions; i++) { |
180 for (int i = 0; i < num_regions; i++) { |
169 used_offset = sp_offset + CDSFileMapRegion_size * i + sp_used_offset; |
181 used[i] = get_region_used_size_aligned(fc, i); |
170 // read 'used' |
|
171 used[i] = readInt(fc, used_offset, size_t_size); |
|
172 start = start0; |
182 start = start0; |
173 for (int j = 0; j < i; j++) { |
183 for (int j = 0; j < i; j++) { |
174 start += align_up_page(used[j]); |
184 start += align_up_page(used[j]); |
175 } |
185 } |
176 end = start + used[i]; |
186 end = start + used[i]; |
|
187 if (start == end) { |
|
188 continue; // Ignore empty regions |
|
189 } |
177 off = getRandomBetween(start, end); |
190 off = getRandomBetween(start, end); |
178 System.out.printf("%-12s%-12d%-12d%-12d%-12d\n", shared_region_name[i], used_offset, used[i], start, off); |
191 System.out.printf("%-24s%12d%12d%16d\n", shared_region_name[i], used[i], start, off); |
179 if (end - off < 1024) { |
192 if (end - off < 1024) { |
180 bufSize = (int)(end - off + 1); |
193 bufSize = (int)(end - off + 1); |
181 } else { |
194 } else { |
182 bufSize = 1024; |
195 bufSize = 1024; |
183 } |
196 } |
187 if (fc.isOpen()) { |
200 if (fc.isOpen()) { |
188 fc.close(); |
201 fc.close(); |
189 } |
202 } |
190 } |
203 } |
191 |
204 |
192 public static void modifyJsaContent() throws Exception { |
205 static long get_region_used_size_aligned(FileChannel fc, int region) throws Exception { |
|
206 long n = sp_offset + CDSFileMapRegion_size * region + sp_used_offset; |
|
207 long alignment = WhiteBox.getWhiteBox().metaspaceReserveAlignment(); |
|
208 long used = readInt(fc, n, size_t_size); |
|
209 used = (used + alignment - 1) & ~(alignment - 1); |
|
210 return used; |
|
211 } |
|
212 |
|
213 public static boolean modifyJsaContent(int region) throws Exception { |
193 FileChannel fc = getFileChannel(); |
214 FileChannel fc = getFileChannel(); |
194 byte[] buf = new byte[4096]; |
215 byte[] buf = new byte[4096]; |
195 ByteBuffer bbuf = ByteBuffer.wrap(buf); |
216 ByteBuffer bbuf = ByteBuffer.wrap(buf); |
196 |
217 |
197 long total = 0L; |
218 long total = 0L; |
198 long used_offset = 0L; |
|
199 long[] used = new long[num_regions]; |
219 long[] used = new long[num_regions]; |
200 System.out.printf("%-12s%-12s\n", "Space name", "Used bytes"); |
220 System.out.printf("%-24s%12s\n", "Space name", "Used bytes"); |
201 for (int i = 0; i < num_regions; i++) { |
221 for (int i = 0; i < num_regions; i++) { |
202 used_offset = sp_offset + CDSFileMapRegion_size* i + sp_used_offset; |
222 used[i] = get_region_used_size_aligned(fc, i); |
203 // read 'used' |
223 System.out.printf("%-24s%12d\n", shared_region_name[i], used[i]); |
204 used[i] = readInt(fc, used_offset, size_t_size); |
|
205 System.out.printf("%-12s%-12d\n", shared_region_name[i], used[i]); |
|
206 total += used[i]; |
224 total += used[i]; |
207 } |
225 } |
208 System.out.printf("%-12s%-12d\n", "Total: ", total); |
226 System.out.printf("%-24s%12d\n", "Total: ", total); |
209 long corrupt_used_offset = getFileHeaderSize(fc); |
227 long header_size = getFileHeaderSize(fc); |
210 System.out.println("Corrupt RO section, offset = " + corrupt_used_offset); |
228 long region_start_offset = header_size; |
211 while (used_offset < used[0]) { |
229 for (int i=0; i<region; i++) { |
212 writeData(fc, corrupt_used_offset, bbuf); |
230 region_start_offset += used[i]; |
|
231 } |
|
232 if (used[region] == 0) { |
|
233 System.out.println("Region " + shared_region_name[region] + " is empty. Nothing to corrupt."); |
|
234 return false; |
|
235 } |
|
236 System.out.println("Corrupt " + shared_region_name[region] + " section, start = " + region_start_offset |
|
237 + " (header_size + 0x" + Long.toHexString(region_start_offset-header_size) + ")"); |
|
238 long bytes_written = 0L; |
|
239 while (bytes_written < used[region]) { |
|
240 writeData(fc, region_start_offset + bytes_written, bbuf); |
213 bbuf.clear(); |
241 bbuf.clear(); |
214 used_offset += 4096; |
242 bytes_written += 4096; |
215 } |
243 } |
216 fc.force(true); |
244 fc.force(true); |
217 if (fc.isOpen()) { |
245 if (fc.isOpen()) { |
218 fc.close(); |
246 fc.close(); |
219 } |
247 } |
|
248 return true; |
220 } |
249 } |
221 |
250 |
222 public static void modifyJsaHeader() throws Exception { |
251 public static void modifyJsaHeader() throws Exception { |
223 FileChannel fc = getFileChannel(); |
252 FileChannel fc = getFileChannel(); |
224 // screw up header info |
253 // screw up header info |
297 |
326 |
298 // dump with hello.jsa, then |
327 // dump with hello.jsa, then |
299 // read the jsa file |
328 // read the jsa file |
300 // 1) run normal |
329 // 1) run normal |
301 // 2) modify header |
330 // 2) modify header |
302 // 3) keep header correct but modify content |
331 // 3) keep header correct but modify content in each region specified by shared_region_name[] |
303 // 4) update both header and content, test |
332 // 4) update both header and content, test |
304 // 5) delete bytes in data begining |
333 // 5) delete bytes in data begining |
305 // 6) insert bytes in data begining |
334 // 6) insert bytes in data begining |
306 // 7) randomly corrupt data in four areas: RO, RW. MISC DATA, MISC CODE |
335 // 7) randomly corrupt data in each region specified by shared_region_name[] |
307 public static void main(String... args) throws Exception { |
336 public static void main(String... args) throws Exception { |
308 // must call to get offset info first!!! |
337 // must call to get offset info first!!! |
309 getFileOffsetInfo(); |
338 getFileOffsetInfo(); |
310 Path currentRelativePath = Paths.get(""); |
339 Path currentRelativePath = Paths.get(""); |
311 String currentDir = currentRelativePath.toAbsolutePath().toString(); |
340 String currentDir = currentRelativePath.toAbsolutePath().toString(); |
350 modifyJsaHeader(); |
379 modifyJsaHeader(); |
351 output = TestCommon.execCommon(execArgs); |
380 output = TestCommon.execCommon(execArgs); |
352 output.shouldContain("The shared archive file has the wrong version"); |
381 output.shouldContain("The shared archive file has the wrong version"); |
353 output.shouldNotContain("Checksum verification failed"); |
382 output.shouldNotContain("Checksum verification failed"); |
354 |
383 |
|
384 File newJsaFile = null; |
355 // modify content |
385 // modify content |
356 System.out.println("\n3. Corrupt Content, should fail\n"); |
386 System.out.println("\n3. Corrupt Content, should fail\n"); |
357 |
387 for (int i=0; i<num_regions; i++) { |
358 copyFile(orgJsaFile, jsa); |
388 newJsaFile = new File(TestCommon.getNewArchiveName(shared_region_name[i])); |
359 modifyJsaContent(); |
389 copyFile(orgJsaFile, newJsaFile); |
360 testAndCheck(verifyExecArgs); |
390 if (modifyJsaContent(i)) { |
|
391 testAndCheck(execArgs); |
|
392 } |
|
393 } |
361 |
394 |
362 // modify both header and content, test should fail |
395 // modify both header and content, test should fail |
363 System.out.println("\n4. Corrupt Header and Content, should fail\n"); |
396 System.out.println("\n4. Corrupt Header and Content, should fail\n"); |
364 copyFile(orgJsaFile, jsa); |
397 newJsaFile = new File(TestCommon.getNewArchiveName("header-and-content")); |
|
398 copyFile(orgJsaFile, newJsaFile); |
365 modifyJsaHeader(); |
399 modifyJsaHeader(); |
366 modifyJsaContent(); // this will not be reached since failed on header change first |
400 modifyJsaContent(0); // this will not be reached since failed on header change first |
367 output = TestCommon.execCommon(execArgs); |
401 output = TestCommon.execCommon(execArgs); |
368 output.shouldContain("The shared archive file has the wrong version"); |
402 output.shouldContain("The shared archive file has the wrong version"); |
369 output.shouldNotContain("Checksum verification failed"); |
403 output.shouldNotContain("Checksum verification failed"); |
370 |
404 |
371 // delete bytes in data section |
405 // delete bytes in data section |
377 System.out.println("\n6. Insert bytes at beginning of data section, should fail\n"); |
411 System.out.println("\n6. Insert bytes at beginning of data section, should fail\n"); |
378 copyFile(orgJsaFile, jsa, false); |
412 copyFile(orgJsaFile, jsa, false); |
379 testAndCheck(verifyExecArgs); |
413 testAndCheck(verifyExecArgs); |
380 |
414 |
381 System.out.println("\n7. modify Content in random areas, should fail\n"); |
415 System.out.println("\n7. modify Content in random areas, should fail\n"); |
382 copyFile(orgJsaFile, jsa); |
416 newJsaFile = new File(TestCommon.getNewArchiveName("random-areas")); |
|
417 copyFile(orgJsaFile, newJsaFile); |
383 modifyJsaContentRandomly(); |
418 modifyJsaContentRandomly(); |
384 testAndCheck(verifyExecArgs); |
419 testAndCheck(verifyExecArgs); |
385 } |
420 } |
386 } |
421 } |