334 * entry that has integer regset for that LWP.
335 *
336 * Linux threads are actually 'clone'd processes. To support core analysis
337 * of "multithreaded" process, Linux creates more than one pstatus (called
338 * "prstatus") entry in PT_NOTE. Each prstatus entry has integer regset for one
339 * "thread". Please refer to Linux kernel src file 'fs/binfmt_elf.c', in particular
340 * function "elf_core_dump".
341 */
342
343 for (core_php = phbuf, i = 0; i < core_ehdr->e_phnum; i++) {
344 switch (core_php->p_type) {
345 case PT_NOTE:
346 if (core_handle_note(ph, core_php) != true) {
347 goto err;
348 }
349 break;
350
351 case PT_LOAD: {
352 if (core_php->p_filesz != 0) {
353 if (add_map_info(ph, ph->core->core_fd, core_php->p_offset,
354 core_php->p_vaddr, core_php->p_filesz) == NULL) goto err;
355 }
356 break;
357 }
358 }
359
360 core_php++;
361 }
362
363 free(phbuf);
364 return true;
365 err:
366 free(phbuf);
367 return false;
368 }
369
370 // read segments of a shared object
371 static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* lib_ehdr, uintptr_t lib_base) {
372 int i = 0;
373 ELF_PHDR* phbuf;
374 ELF_PHDR* lib_php = NULL;
375
376 int page_size = sysconf(_SC_PAGE_SIZE);
377
378 if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL) {
379 return false;
380 }
381
382 // we want to process only PT_LOAD segments that are not writable.
383 // i.e., text segments. The read/write/exec (data) segments would
384 // have been already added from core file segments.
385 for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) {
386 if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) {
387
388 uintptr_t target_vaddr = lib_php->p_vaddr + lib_base;
389 map_info *existing_map = core_lookup(ph, target_vaddr);
390
391 if (existing_map == NULL){
392 if (add_map_info(ph, lib_fd, lib_php->p_offset,
393 target_vaddr, lib_php->p_memsz) == NULL) {
394 goto err;
395 }
396 } else {
397 // Coredump stores value of p_memsz elf field
398 // rounded up to page boundary.
399
400 if ((existing_map->memsz != page_size) &&
401 (existing_map->fd != lib_fd) &&
402 (ROUNDUP(existing_map->memsz, page_size) != ROUNDUP(lib_php->p_memsz, page_size))) {
403
404 print_debug("address conflict @ 0x%lx (existing map size = %ld, size = %ld, flags = %d)\n",
405 target_vaddr, existing_map->memsz, lib_php->p_memsz, lib_php->p_flags);
406 goto err;
407 }
408
409 /* replace PT_LOAD segment with library segment */
410 print_debug("overwrote with new address mapping (memsz %ld -> %ld)\n",
411 existing_map->memsz, ROUNDUP(lib_php->p_memsz, page_size));
412
413 existing_map->fd = lib_fd;
414 existing_map->offset = lib_php->p_offset;
415 existing_map->memsz = ROUNDUP(lib_php->p_memsz, page_size);
416 }
443 return true;
444 }
445
446 // process segments of a a.out
447 static bool read_exec_segments(struct ps_prochandle* ph, ELF_EHDR* exec_ehdr) {
448 int i = 0;
449 ELF_PHDR* phbuf = NULL;
450 ELF_PHDR* exec_php = NULL;
451
452 if ((phbuf = read_program_header_table(ph->core->exec_fd, exec_ehdr)) == NULL) {
453 return false;
454 }
455
456 for (exec_php = phbuf, i = 0; i < exec_ehdr->e_phnum; i++) {
457 switch (exec_php->p_type) {
458
459 // add mappings for PT_LOAD segments
460 case PT_LOAD: {
461 // add only non-writable segments of non-zero filesz
462 if (!(exec_php->p_flags & PF_W) && exec_php->p_filesz != 0) {
463 if (add_map_info(ph, ph->core->exec_fd, exec_php->p_offset, exec_php->p_vaddr, exec_php->p_filesz) == NULL) goto err;
464 }
465 break;
466 }
467
468 // read the interpreter and it's segments
469 case PT_INTERP: {
470 char interp_name[BUF_SIZE + 1];
471
472 // BUF_SIZE is PATH_MAX + NAME_MAX + 1.
473 if (exec_php->p_filesz > BUF_SIZE) {
474 goto err;
475 }
476 if (pread(ph->core->exec_fd, interp_name,
477 exec_php->p_filesz, exec_php->p_offset) != exec_php->p_filesz) {
478 print_debug("Unable to read in the ELF interpreter\n");
479 goto err;
480 }
481 interp_name[exec_php->p_filesz] = '\0';
482 print_debug("ELF interpreter %s\n", interp_name);
483 // read interpreter segments as well
|
334 * entry that has integer regset for that LWP.
335 *
336 * Linux threads are actually 'clone'd processes. To support core analysis
337 * of "multithreaded" process, Linux creates more than one pstatus (called
338 * "prstatus") entry in PT_NOTE. Each prstatus entry has integer regset for one
339 * "thread". Please refer to Linux kernel src file 'fs/binfmt_elf.c', in particular
340 * function "elf_core_dump".
341 */
342
343 for (core_php = phbuf, i = 0; i < core_ehdr->e_phnum; i++) {
344 switch (core_php->p_type) {
345 case PT_NOTE:
346 if (core_handle_note(ph, core_php) != true) {
347 goto err;
348 }
349 break;
350
351 case PT_LOAD: {
352 if (core_php->p_filesz != 0) {
353 if (add_map_info(ph, ph->core->core_fd, core_php->p_offset,
354 core_php->p_vaddr, core_php->p_filesz, core_php->p_flags) == NULL) goto err;
355 }
356 break;
357 }
358 }
359
360 core_php++;
361 }
362
363 free(phbuf);
364 return true;
365 err:
366 free(phbuf);
367 return false;
368 }
369
370 // read segments of a shared object
371 static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* lib_ehdr, uintptr_t lib_base) {
372 int i = 0;
373 ELF_PHDR* phbuf;
374 ELF_PHDR* lib_php = NULL;
375
376 int page_size = sysconf(_SC_PAGE_SIZE);
377
378 if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL) {
379 return false;
380 }
381
382 // we want to process only PT_LOAD segments that are not writable.
383 // i.e., text segments. The read/write/exec (data) segments would
384 // have been already added from core file segments.
385 for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) {
386 if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) {
387
388 uintptr_t target_vaddr = lib_php->p_vaddr + lib_base;
389 map_info *existing_map = core_lookup(ph, target_vaddr);
390
391 if (existing_map == NULL){
392 if (add_map_info(ph, lib_fd, lib_php->p_offset,
393 target_vaddr, lib_php->p_memsz, lib_php->p_flags) == NULL) {
394 goto err;
395 }
396 } else if (lib_php->p_flags != existing_map->flags) {
397 // Access flags fot this memory region is different between the library
398 // and coredump. It might be caused by mprotect() call at runtime.
399 // We should respect to coredump.
400 continue;
401 } else {
402 // Read only segments in ELF should not be any different from PT_LOAD segments
403 // in the coredump.
404 // And head of ELF header might be included in coredump (See JDK-7133122).
405 // Thus we need to replace PT_LOAD segments the library version.
406 //
407 // Coredump stores value of p_memsz elf field
408 // rounded up to page boundary.
409
410 if ((existing_map->memsz != page_size) &&
411 (existing_map->fd != lib_fd) &&
412 (ROUNDUP(existing_map->memsz, page_size) != ROUNDUP(lib_php->p_memsz, page_size))) {
413
414 print_debug("address conflict @ 0x%lx (existing map size = %ld, size = %ld, flags = %d)\n",
415 target_vaddr, existing_map->memsz, lib_php->p_memsz, lib_php->p_flags);
416 goto err;
417 }
418
419 /* replace PT_LOAD segment with library segment */
420 print_debug("overwrote with new address mapping (memsz %ld -> %ld)\n",
421 existing_map->memsz, ROUNDUP(lib_php->p_memsz, page_size));
422
423 existing_map->fd = lib_fd;
424 existing_map->offset = lib_php->p_offset;
425 existing_map->memsz = ROUNDUP(lib_php->p_memsz, page_size);
426 }
453 return true;
454 }
455
456 // process segments of a a.out
457 static bool read_exec_segments(struct ps_prochandle* ph, ELF_EHDR* exec_ehdr) {
458 int i = 0;
459 ELF_PHDR* phbuf = NULL;
460 ELF_PHDR* exec_php = NULL;
461
462 if ((phbuf = read_program_header_table(ph->core->exec_fd, exec_ehdr)) == NULL) {
463 return false;
464 }
465
466 for (exec_php = phbuf, i = 0; i < exec_ehdr->e_phnum; i++) {
467 switch (exec_php->p_type) {
468
469 // add mappings for PT_LOAD segments
470 case PT_LOAD: {
471 // add only non-writable segments of non-zero filesz
472 if (!(exec_php->p_flags & PF_W) && exec_php->p_filesz != 0) {
473 if (add_map_info(ph, ph->core->exec_fd, exec_php->p_offset, exec_php->p_vaddr, exec_php->p_filesz, exec_php->p_flags) == NULL) goto err;
474 }
475 break;
476 }
477
478 // read the interpreter and it's segments
479 case PT_INTERP: {
480 char interp_name[BUF_SIZE + 1];
481
482 // BUF_SIZE is PATH_MAX + NAME_MAX + 1.
483 if (exec_php->p_filesz > BUF_SIZE) {
484 goto err;
485 }
486 if (pread(ph->core->exec_fd, interp_name,
487 exec_php->p_filesz, exec_php->p_offset) != exec_php->p_filesz) {
488 print_debug("Unable to read in the ELF interpreter\n");
489 goto err;
490 }
491 interp_name[exec_php->p_filesz] = '\0';
492 print_debug("ELF interpreter %s\n", interp_name);
493 // read interpreter segments as well
|