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 }
284
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) {
357 print_debug("can't read shared archive path pointer\n");
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 "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 static bool read_jboolean(struct ps_prochandle* ph, uintptr_t addr, jboolean* pvalue) {
208 jboolean i;
209 if (ps_pdread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) {
210 *pvalue = i;
211 return true;
212 } else {
213 return false;
214 }
215 }
216
217 static bool read_pointer(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* pvalue) {
218 uintptr_t uip;
219 if (ps_pdread(ph, (psaddr_t) addr, (char *)&uip, sizeof(uip)) == PS_OK) {
220 *pvalue = uip;
221 return true;
222 } else {
223 return false;
224 }
225 }
226
242 i++; addr++;
243 }
244
245 buf[i] = '\0';
246 return true;
247 }
248
249 #define USE_SHARED_SPACES_SYM "UseSharedSpaces"
250 // mangled name of Arguments::SharedArchivePath
251 #define SHARED_ARCHIVE_PATH_SYM "_ZN9Arguments17SharedArchivePathE"
252 #define LIBJVM_NAME "/libjvm.so"
253
254 static bool init_classsharing_workaround(struct ps_prochandle* ph) {
255 lib_info* lib = ph->libs;
256 while (lib != NULL) {
257 // we are iterating over shared objects from the core dump. look for
258 // libjvm.so.
259 const char *jvm_name = 0;
260 if ((jvm_name = strstr(lib->name, LIBJVM_NAME)) != 0) {
261 char classes_jsa[PATH_MAX];
262 CDSFileMapHeaderBase header;
263 int fd = -1;
264 int m = 0;
265 size_t n = 0;
266 uintptr_t base = 0, useSharedSpacesAddr = 0;
267 uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
268 jboolean useSharedSpaces = 0;
269 map_info* mi = 0;
270
271 memset(classes_jsa, 0, sizeof(classes_jsa));
272 jvm_name = lib->name;
273 useSharedSpacesAddr = lookup_symbol(ph, jvm_name, USE_SHARED_SPACES_SYM);
274 if (useSharedSpacesAddr == 0) {
275 print_debug("can't lookup 'UseSharedSpaces' flag\n");
276 return false;
277 }
278
279 // Hotspot vm types are not exported to build this library. So
280 // using equivalent type jboolean to read the value of
281 // UseSharedSpaces which is same as hotspot type "bool".
282 if (read_jboolean(ph, useSharedSpacesAddr, &useSharedSpaces) != true) {
299 print_debug("can't read shared archive path pointer\n");
300 return false;
301 }
302
303 if (read_string(ph, sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
304 print_debug("can't read shared archive path value\n");
305 return false;
306 }
307
308 print_debug("looking for %s\n", classes_jsa);
309 // open the class sharing archive file
310 fd = pathmap_open(classes_jsa);
311 if (fd < 0) {
312 print_debug("can't open %s!\n", classes_jsa);
313 ph->core->classes_jsa_fd = -1;
314 return false;
315 } else {
316 print_debug("opened %s\n", classes_jsa);
317 }
318
319 // read CDSFileMapHeaderBase from the file
320 memset(&header, 0, sizeof(CDSFileMapHeaderBase));
321 if ((n = read(fd, &header, sizeof(CDSFileMapHeaderBase)))
322 != sizeof(CDSFileMapHeaderBase)) {
323 print_debug("can't read shared archive file map header from %s\n", classes_jsa);
324 close(fd);
325 return false;
326 }
327
328 // check file magic
329 if (header._magic != CDS_ARCHIVE_MAGIC) {
330 print_debug("%s has bad shared archive file magic number 0x%x, expecting 0x%x\n",
331 classes_jsa, header._magic, CDS_ARCHIVE_MAGIC);
332 close(fd);
333 return false;
334 }
335
336 // check version
337 if (header._version != CURRENT_CDS_ARCHIVE_VERSION) {
338 print_debug("%s has wrong shared archive file version %d, expecting %d\n",
339 classes_jsa, header._version, CURRENT_CDS_ARCHIVE_VERSION);
340 close(fd);
341 return false;
342 }
343
344 ph->core->classes_jsa_fd = fd;
345 // add read-only maps from classes.jsa to the list of maps
346 for (m = 0; m < NUM_CDS_REGIONS; m++) {
347 if (header._space[m]._read_only) {
348 base = (uintptr_t) header._space[m]._addr._base;
349 // no need to worry about the fractional pages at-the-end.
350 // possible fractional pages are handled by core_read_data.
351 add_class_share_map_info(ph, (off_t) header._space[m]._file_offset,
352 base, (size_t) header._space[m]._used);
353 print_debug("added a share archive map at 0x%lx\n", base);
354 }
355 }
356 return true;
357 }
358 lib = lib->next;
359 }
360 return true;
361 }
362
363
364 //---------------------------------------------------------------------------
365 // functions to handle map_info
366
|