12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
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 <jni.h>
26 #include <unistd.h>
27 #include <fcntl.h>
28 #include <string.h>
29 #include <stdlib.h>
30 #include <stddef.h>
31 #include "libproc_impl.h"
32
33 #ifdef __APPLE__
34 #include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h"
35 #endif
36
37 // This file has the libproc implementation to read core files.
38 // For live processes, refer to ps_proc.c. Portions of this is adapted
39 // /modelled after Solaris libproc.so (in particular Pcore.c)
40
41 //----------------------------------------------------------------------
42 // ps_prochandle cleanup helper functions
43
44 // close all file descriptors
45 static void close_files(struct ps_prochandle* ph) {
46 lib_info* lib = NULL;
47
48 // close core file descriptor
49 if (ph->core->core_fd >= 0)
50 close(ph->core->core_fd);
51
187 while (mp) {
188 if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
189 print_debug("located map_info at 0x%lx from class share maps\n", addr);
190 return (mp);
191 }
192 mp = mp->next;
193 }
194
195 print_debug("can't locate map_info at 0x%lx\n", addr);
196 return (NULL);
197 }
198
199 //---------------------------------------------------------------
200 // Part of the class sharing workaround:
201 //
202 // With class sharing, pages are mapped from classes.jsa file.
203 // The read-only class sharing pages are mapped as MAP_SHARED,
204 // PROT_READ pages. These pages are not dumped into core dump.
205 // With this workaround, these pages are read from classes.jsa.
206
207 // FIXME: !HACK ALERT!
208 // The format of sharing achive file header is needed to read shared heap
209 // file mappings. For now, I am hard coding portion of FileMapHeader here.
210 // Refer to filemap.hpp.
211
212 // FileMapHeader describes the shared space data in the file to be
213 // mapped. This structure gets written to a file. It is not a class,
214 // so that the compilers don't add any compiler-private data to it.
215
216 #define NUM_SHARED_MAPS 9
217
218 // Refer to FileMapInfo::_current_version in filemap.hpp
219 #define CURRENT_ARCHIVE_VERSION 3
220
221 typedef unsigned char* address;
222 typedef uintptr_t uintx;
223 typedef intptr_t intx;
224
225
226 struct FileMapHeader {
227 int _magic; // identify file type.
228 int _crc; // header crc checksum.
229 int _version; // (from enum, above.)
230 size_t _alignment; // how shared archive should be aligned
231 int _obj_alignment; // value of ObjectAlignmentInBytes
232 address _narrow_oop_base; // compressed oop encoding base
233 int _narrow_oop_shift; // compressed oop encoding shift
234 bool _compact_strings; // value of CompactStrings
235 uintx _max_heap_size; // java max heap size during dumping
236 int _narrow_oop_mode; // compressed oop encoding mode
237 int _narrow_klass_shift; // save narrow klass base and shift
238 address _narrow_klass_base;
239 char* _misc_data_patching_start;
240 char* _read_only_tables_start;
241 address _cds_i2i_entry_code_buffers;
242 size_t _cds_i2i_entry_code_buffers_size;
243 size_t _core_spaces_size; // number of bytes allocated by the core spaces
244 // (mc, md, ro, rw and od).
245
246
247 struct space_info {
248 int _crc; // crc checksum of the current space
249 size_t _file_offset; // sizeof(this) rounded to vm page size
250 union {
251 char* _base; // copy-on-write base address
252 intx _offset; // offset from the compressed oop encoding base, only used
253 // by archive heap space
254 } _addr;
255 size_t _used; // for setting space top on read
256 // 4991491 NOTICE These are C++ bool's in filemap.hpp and must match up with
257 // the C type matching the C++ bool type on any given platform.
258 // We assume the corresponding C type is char but licensees
259 // may need to adjust the type of these fields.
260 char _read_only; // read only space?
261 char _allow_exec; // executable code in space?
262 } _space[NUM_SHARED_MAPS];
263
264 // Ignore the rest of the FileMapHeader. We don't need those fields here.
265 };
266
267 static bool read_jboolean(struct ps_prochandle* ph, uintptr_t addr, jboolean* pvalue) {
268 jboolean i;
269 if (ps_pread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) {
270 *pvalue = i;
271 return true;
272 } else {
273 return false;
274 }
275 }
276
277 static bool read_pointer(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* pvalue) {
278 uintptr_t uip;
279 if (ps_pread(ph, (psaddr_t) addr, (char *)&uip, sizeof(uip)) == PS_OK) {
280 *pvalue = uip;
281 return true;
282 } else {
283 return false;
284 }
285 }
309 #define SHARED_ARCHIVE_PATH_SYM "__ZN9Arguments17SharedArchivePathE"
310
311 #ifdef __APPLE__
312 #define USE_SHARED_SPACES_SYM "_UseSharedSpaces"
313 #define LIBJVM_NAME "/libjvm.dylib"
314 #else
315 #define USE_SHARED_SPACES_SYM "UseSharedSpaces"
316 #define LIBJVM_NAME "/libjvm.so"
317 #endif // __APPLE_
318
319 static bool init_classsharing_workaround(struct ps_prochandle* ph) {
320 int m;
321 size_t n;
322 lib_info* lib = ph->libs;
323 while (lib != NULL) {
324 // we are iterating over shared objects from the core dump. look for
325 // libjvm.so.
326 const char *jvm_name = 0;
327 if ((jvm_name = strstr(lib->name, LIBJVM_NAME)) != 0) {
328 char classes_jsa[PATH_MAX];
329 struct FileMapHeader header;
330 int fd = -1;
331 uintptr_t base = 0, useSharedSpacesAddr = 0;
332 uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
333 jboolean useSharedSpaces = 0;
334
335 memset(classes_jsa, 0, sizeof(classes_jsa));
336 jvm_name = lib->name;
337 useSharedSpacesAddr = lookup_symbol(ph, jvm_name, USE_SHARED_SPACES_SYM);
338 if (useSharedSpacesAddr == 0) {
339 print_debug("can't lookup 'UseSharedSpaces' flag\n");
340 return false;
341 }
342
343 // Hotspot vm types are not exported to build this library. So
344 // using equivalent type jboolean to read the value of
345 // UseSharedSpaces which is same as hotspot type "bool".
346 if (read_jboolean(ph, useSharedSpacesAddr, &useSharedSpaces) != true) {
347 print_debug("can't read the value of 'UseSharedSpaces' flag\n");
348 return false;
349 }
364 return false;
365 }
366
367 if (read_string(ph, sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
368 print_debug("can't read shared archive path value\n");
369 return false;
370 }
371
372 print_debug("looking for %s\n", classes_jsa);
373 // open the class sharing archive file
374 fd = pathmap_open(classes_jsa);
375 if (fd < 0) {
376 print_debug("can't open %s!\n", classes_jsa);
377 ph->core->classes_jsa_fd = -1;
378 return false;
379 } else {
380 print_debug("opened %s\n", classes_jsa);
381 }
382
383 // read FileMapHeader from the file
384 memset(&header, 0, sizeof(struct FileMapHeader));
385 if ((n = read(fd, &header, sizeof(struct FileMapHeader)))
386 != sizeof(struct FileMapHeader)) {
387 print_debug("can't read shared archive file map header from %s\n", classes_jsa);
388 close(fd);
389 return false;
390 }
391
392 // check file magic
393 if (header._magic != 0xf00baba2) {
394 print_debug("%s has bad shared archive file magic number 0x%x, expecing 0xf00baba2\n",
395 classes_jsa, header._magic);
396 close(fd);
397 return false;
398 }
399
400 // check version
401 if (header._version != CURRENT_ARCHIVE_VERSION) {
402 print_debug("%s has wrong shared archive file version %d, expecting %d\n",
403 classes_jsa, header._version, CURRENT_ARCHIVE_VERSION);
404 close(fd);
405 return false;
406 }
407
408 ph->core->classes_jsa_fd = fd;
409 // add read-only maps from classes.jsa to the list of maps
410 for (m = 0; m < NUM_SHARED_MAPS; m++) {
411 if (header._space[m]._read_only) {
412 base = (uintptr_t) header._space[m]._addr._base;
413 // no need to worry about the fractional pages at-the-end.
414 // possible fractional pages are handled by core_read_data.
415 add_class_share_map_info(ph, (off_t) header._space[m]._file_offset,
416 base, (size_t) header._space[m]._used);
417 print_debug("added a share archive map at 0x%lx\n", base);
418 }
419 }
420 return true;
421 }
422 lib = lib->next;
423 }
424 return true;
425 }
426
427 //---------------------------------------------------------------------------
428 // functions to handle map_info
429
430 // Order mappings based on virtual address. We use this function as the
|
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
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 <jni.h>
26 #include <unistd.h>
27 #include <fcntl.h>
28 #include <string.h>
29 #include <stdlib.h>
30 #include <stddef.h>
31 #include "libproc_impl.h"
32 #include "../../../../hotspot/share/include/cds.h"
33
34 #ifdef __APPLE__
35 #include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h"
36 #endif
37
38 // This file has the libproc implementation to read core files.
39 // For live processes, refer to ps_proc.c. Portions of this is adapted
40 // /modelled after Solaris libproc.so (in particular Pcore.c)
41
42 //----------------------------------------------------------------------
43 // ps_prochandle cleanup helper functions
44
45 // close all file descriptors
46 static void close_files(struct ps_prochandle* ph) {
47 lib_info* lib = NULL;
48
49 // close core file descriptor
50 if (ph->core->core_fd >= 0)
51 close(ph->core->core_fd);
52
188 while (mp) {
189 if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
190 print_debug("located map_info at 0x%lx from class share maps\n", addr);
191 return (mp);
192 }
193 mp = mp->next;
194 }
195
196 print_debug("can't locate map_info at 0x%lx\n", addr);
197 return (NULL);
198 }
199
200 //---------------------------------------------------------------
201 // Part of the class sharing workaround:
202 //
203 // With class sharing, pages are mapped from classes.jsa file.
204 // The read-only class sharing pages are mapped as MAP_SHARED,
205 // PROT_READ pages. These pages are not dumped into core dump.
206 // With this workaround, these pages are read from classes.jsa.
207
208 typedef struct CDSFileMapHeaderBase FileMapHeader;
209
210 static bool read_jboolean(struct ps_prochandle* ph, uintptr_t addr, jboolean* pvalue) {
211 jboolean i;
212 if (ps_pread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) {
213 *pvalue = i;
214 return true;
215 } else {
216 return false;
217 }
218 }
219
220 static bool read_pointer(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* pvalue) {
221 uintptr_t uip;
222 if (ps_pread(ph, (psaddr_t) addr, (char *)&uip, sizeof(uip)) == PS_OK) {
223 *pvalue = uip;
224 return true;
225 } else {
226 return false;
227 }
228 }
252 #define SHARED_ARCHIVE_PATH_SYM "__ZN9Arguments17SharedArchivePathE"
253
254 #ifdef __APPLE__
255 #define USE_SHARED_SPACES_SYM "_UseSharedSpaces"
256 #define LIBJVM_NAME "/libjvm.dylib"
257 #else
258 #define USE_SHARED_SPACES_SYM "UseSharedSpaces"
259 #define LIBJVM_NAME "/libjvm.so"
260 #endif // __APPLE_
261
262 static bool init_classsharing_workaround(struct ps_prochandle* ph) {
263 int m;
264 size_t n;
265 lib_info* lib = ph->libs;
266 while (lib != NULL) {
267 // we are iterating over shared objects from the core dump. look for
268 // libjvm.so.
269 const char *jvm_name = 0;
270 if ((jvm_name = strstr(lib->name, LIBJVM_NAME)) != 0) {
271 char classes_jsa[PATH_MAX];
272 FileMapHeader header;
273 int fd = -1;
274 uintptr_t base = 0, useSharedSpacesAddr = 0;
275 uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
276 jboolean useSharedSpaces = 0;
277
278 memset(classes_jsa, 0, sizeof(classes_jsa));
279 jvm_name = lib->name;
280 useSharedSpacesAddr = lookup_symbol(ph, jvm_name, USE_SHARED_SPACES_SYM);
281 if (useSharedSpacesAddr == 0) {
282 print_debug("can't lookup 'UseSharedSpaces' flag\n");
283 return false;
284 }
285
286 // Hotspot vm types are not exported to build this library. So
287 // using equivalent type jboolean to read the value of
288 // UseSharedSpaces which is same as hotspot type "bool".
289 if (read_jboolean(ph, useSharedSpacesAddr, &useSharedSpaces) != true) {
290 print_debug("can't read the value of 'UseSharedSpaces' flag\n");
291 return false;
292 }
307 return false;
308 }
309
310 if (read_string(ph, sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
311 print_debug("can't read shared archive path value\n");
312 return false;
313 }
314
315 print_debug("looking for %s\n", classes_jsa);
316 // open the class sharing archive file
317 fd = pathmap_open(classes_jsa);
318 if (fd < 0) {
319 print_debug("can't open %s!\n", classes_jsa);
320 ph->core->classes_jsa_fd = -1;
321 return false;
322 } else {
323 print_debug("opened %s\n", classes_jsa);
324 }
325
326 // read FileMapHeader from the file
327 memset(&header, 0, sizeof(FileMapHeader));
328 if ((n = read(fd, &header, sizeof(FileMapHeader)))
329 != sizeof(FileMapHeader)) {
330 print_debug("can't read shared archive file map header from %s\n", classes_jsa);
331 close(fd);
332 return false;
333 }
334
335 // check file magic
336 if (header._magic != CDS_ARCHIVE_MAGIC) {
337 print_debug("%s has bad shared archive file magic number 0x%x, expecing 0x%x\n",
338 classes_jsa, header._magic, CDS_ARCHIVE_MAGIC);
339 close(fd);
340 return false;
341 }
342
343 // check version
344 if (header._version != CURRENT_CDS_ARCHIVE_VERSION) {
345 print_debug("%s has wrong shared archive file version %d, expecting %d\n",
346 classes_jsa, header._version, CURRENT_CDS_ARCHIVE_VERSION);
347 close(fd);
348 return false;
349 }
350
351 ph->core->classes_jsa_fd = fd;
352 // add read-only maps from classes.jsa to the list of maps
353 for (m = 0; m < NUM_CDS_REGIONS; m++) {
354 if (header._space[m]._read_only) {
355 base = (uintptr_t) header._space[m]._addr._base;
356 // no need to worry about the fractional pages at-the-end.
357 // possible fractional pages are handled by core_read_data.
358 add_class_share_map_info(ph, (off_t) header._space[m]._file_offset,
359 base, (size_t) header._space[m]._used);
360 print_debug("added a share archive map at 0x%lx\n", base);
361 }
362 }
363 return true;
364 }
365 lib = lib->next;
366 }
367 return true;
368 }
369
370 //---------------------------------------------------------------------------
371 // functions to handle map_info
372
373 // Order mappings based on virtual address. We use this function as the
|