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 for this memory region are different between the library
398 // and coredump. It might be caused by mprotect() call at runtime.
399 // We should respect the 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 // Also the first page of the ELF header might be included
405 // in the coredump (See JDK-7133122).
406 // Thus we need to replace the PT_LOAD segment with the library version.
407 //
408 // Coredump stores value of p_memsz elf field
409 // rounded up to page boundary.
410
411 if ((existing_map->memsz != page_size) &&
412 (existing_map->fd != lib_fd) &&
413 (ROUNDUP(existing_map->memsz, page_size) != ROUNDUP(lib_php->p_memsz, page_size))) {
414
415 print_debug("address conflict @ 0x%lx (existing map size = %ld, size = %ld, flags = %d)\n",
416 target_vaddr, existing_map->memsz, lib_php->p_memsz, lib_php->p_flags);
417 goto err;
418 }
419
420 /* replace PT_LOAD segment with library segment */
421 print_debug("overwrote with new address mapping (memsz %ld -> %ld)\n",
422 existing_map->memsz, ROUNDUP(lib_php->p_memsz, page_size));
423
424 existing_map->fd = lib_fd;
425 existing_map->offset = lib_php->p_offset;
426 existing_map->memsz = ROUNDUP(lib_php->p_memsz, page_size);
427 }
454 return true;
455 }
456
457 // process segments of a a.out
458 static bool read_exec_segments(struct ps_prochandle* ph, ELF_EHDR* exec_ehdr) {
459 int i = 0;
460 ELF_PHDR* phbuf = NULL;
461 ELF_PHDR* exec_php = NULL;
462
463 if ((phbuf = read_program_header_table(ph->core->exec_fd, exec_ehdr)) == NULL) {
464 return false;
465 }
466
467 for (exec_php = phbuf, i = 0; i < exec_ehdr->e_phnum; i++) {
468 switch (exec_php->p_type) {
469
470 // add mappings for PT_LOAD segments
471 case PT_LOAD: {
472 // add only non-writable segments of non-zero filesz
473 if (!(exec_php->p_flags & PF_W) && exec_php->p_filesz != 0) {
474 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;
475 }
476 break;
477 }
478
479 // read the interpreter and it's segments
480 case PT_INTERP: {
481 char interp_name[BUF_SIZE + 1];
482
483 // BUF_SIZE is PATH_MAX + NAME_MAX + 1.
484 if (exec_php->p_filesz > BUF_SIZE) {
485 goto err;
486 }
487 if (pread(ph->core->exec_fd, interp_name,
488 exec_php->p_filesz, exec_php->p_offset) != exec_php->p_filesz) {
489 print_debug("Unable to read in the ELF interpreter\n");
490 goto err;
491 }
492 interp_name[exec_php->p_filesz] = '\0';
493 print_debug("ELF interpreter %s\n", interp_name);
494 // read interpreter segments as well
|