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