< prev index next >

src/jdk.hotspot.agent/macosx/native/libsaproc/ps_core.c

Print this page




 231 
 232   lseek(fd, offset, SEEK_SET);
 233   if(read(fd, (void *)&fhead, sizeof(mach_header_64)) != sizeof(mach_header_64)) {
 234      goto err;
 235   }
 236   print_debug("total commands: %d\n", fhead.ncmds);
 237   offset += sizeof(mach_header_64);
 238   for (i = 0; i < fhead.ncmds; i++) {
 239     lseek(fd, offset, SEEK_SET);
 240     if (read(fd, (void *)&lcmd, sizeof(load_command)) != sizeof(load_command)) {
 241       goto err;
 242     }
 243     offset += lcmd.cmdsize;    // next command position
 244     //print_debug("LC: 0x%x\n", lcmd.cmd);
 245     if (lcmd.cmd == LC_SEGMENT_64) {
 246       lseek(fd, -sizeof(load_command), SEEK_CUR);
 247       if (read(fd, (void *)&segcmd, sizeof(segment_command_64)) != sizeof(segment_command_64)) {
 248         print_debug("failed to read LC_SEGMENT_64 i = %d!\n", i);
 249         goto err;
 250       }
 251       if (add_map_info(ph, fd, segcmd.fileoff, segcmd.vmaddr, segcmd.vmsize) == NULL) {
 252         print_debug("Failed to add map_info at i = %d\n", i);
 253         goto err;
 254       }
 255       print_debug("LC_SEGMENT_64 added: nsects=%d fileoff=0x%llx vmaddr=0x%llx vmsize=0x%llx filesize=0x%llx %s\n",
 256                   segcmd.nsects, segcmd.fileoff, segcmd.vmaddr, segcmd.vmsize,
 257                   segcmd.filesize, &segcmd.segname[0]);
 258     } else if (lcmd.cmd == LC_THREAD || lcmd.cmd == LC_UNIXTHREAD) {
 259       typedef struct thread_fc {
 260         uint32_t  flavor;
 261         uint32_t  count;
 262       } thread_fc;
 263       thread_fc fc;
 264       uint32_t size = sizeof(load_command);
 265       while (size < lcmd.cmdsize) {
 266         if (read(fd, (void *)&fc, sizeof(thread_fc)) != sizeof(thread_fc)) {
 267           printf("Reading flavor, count failed.\n");
 268           goto err;
 269         }
 270         size += sizeof(thread_fc);
 271         if (fc.flavor == x86_THREAD_STATE) {


 771     *     entry that has integer regset for that LWP.
 772     *
 773     *     Linux threads are actually 'clone'd processes. To support core analysis
 774     *     of "multithreaded" process, Linux creates more than one pstatus (called
 775     *     "prstatus") entry in PT_NOTE. Each prstatus entry has integer regset for one
 776     *     "thread". Please refer to Linux kernel src file 'fs/binfmt_elf.c', in particular
 777     *     function "elf_core_dump".
 778     */
 779 
 780     for (core_php = phbuf, i = 0; i < core_ehdr->e_phnum; i++) {
 781       switch (core_php->p_type) {
 782          case PT_NOTE:
 783             if (core_handle_note(ph, core_php) != true) {
 784               goto err;
 785             }
 786             break;
 787 
 788          case PT_LOAD: {
 789             if (core_php->p_filesz != 0) {
 790                if (add_map_info(ph, ph->core->core_fd, core_php->p_offset,
 791                   core_php->p_vaddr, core_php->p_filesz) == NULL) goto err;
 792             }
 793             break;
 794          }
 795       }
 796 
 797       core_php++;
 798    }
 799 
 800    free(phbuf);
 801    return true;
 802 err:
 803    free(phbuf);
 804    return false;
 805 }
 806 
 807 // read segments of a shared object
 808 static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* lib_ehdr, uintptr_t lib_base) {
 809   int i = 0;
 810   ELF_PHDR* phbuf;
 811   ELF_PHDR* lib_php = NULL;
 812 
 813   int page_size=sysconf(_SC_PAGE_SIZE);
 814 
 815   if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL) {
 816     return false;
 817   }
 818 
 819   // we want to process only PT_LOAD segments that are not writable.
 820   // i.e., text segments. The read/write/exec (data) segments would
 821   // have been already added from core file segments.
 822   for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) {
 823     if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) {
 824 
 825       uintptr_t target_vaddr = lib_php->p_vaddr + lib_base;
 826       map_info *existing_map = core_lookup(ph, target_vaddr);
 827 
 828       if (existing_map == NULL){
 829         if (add_map_info(ph, lib_fd, lib_php->p_offset,
 830                           target_vaddr, lib_php->p_filesz) == NULL) {
 831           goto err;
 832         }
 833       } else {
 834         if ((existing_map->memsz != page_size) &&
 835             (existing_map->fd != lib_fd) &&
 836             (existing_map->memsz != lib_php->p_filesz)){
 837 
 838           print_debug("address conflict @ 0x%lx (size = %ld, flags = %d\n)",
 839                         target_vaddr, lib_php->p_filesz, lib_php->p_flags);
 840           goto err;
 841         }
 842 
 843         /* replace PT_LOAD segment with library segment */
 844         print_debug("overwrote with new address mapping (memsz %ld -> %ld)\n",
 845                      existing_map->memsz, lib_php->p_filesz);
 846 
 847         existing_map->fd = lib_fd;
 848         existing_map->offset = lib_php->p_offset;
 849         existing_map->memsz = lib_php->p_filesz;
 850       }


 876 
 877    return true;
 878 }
 879 
 880 // process segments of a a.out
 881 static bool read_exec_segments(struct ps_prochandle* ph, ELF_EHDR* exec_ehdr) {
 882    int i = 0;
 883    ELF_PHDR* phbuf = NULL;
 884    ELF_PHDR* exec_php = NULL;
 885 
 886    if ((phbuf = read_program_header_table(ph->core->exec_fd, exec_ehdr)) == NULL)
 887       return false;
 888 
 889    for (exec_php = phbuf, i = 0; i < exec_ehdr->e_phnum; i++) {
 890       switch (exec_php->p_type) {
 891 
 892          // add mappings for PT_LOAD segments
 893          case PT_LOAD: {
 894             // add only non-writable segments of non-zero filesz
 895             if (!(exec_php->p_flags & PF_W) && exec_php->p_filesz != 0) {
 896                if (add_map_info(ph, ph->core->exec_fd, exec_php->p_offset, exec_php->p_vaddr, exec_php->p_filesz) == NULL) goto err;
 897             }
 898             break;
 899          }
 900 
 901          // read the interpreter and it's segments
 902          case PT_INTERP: {
 903             char interp_name[BUF_SIZE];
 904 
 905             pread(ph->core->exec_fd, interp_name, MIN(exec_php->p_filesz, BUF_SIZE), exec_php->p_offset);
 906             print_debug("ELF interpreter %s\n", interp_name);
 907             // read interpreter segments as well
 908             if ((ph->core->interp_fd = pathmap_open(interp_name)) < 0) {
 909                print_debug("can't open runtime loader\n");
 910                goto err;
 911             }
 912             break;
 913          }
 914 
 915          // from PT_DYNAMIC we want to read address of first link_map addr
 916          case PT_DYNAMIC: {




 231 
 232   lseek(fd, offset, SEEK_SET);
 233   if(read(fd, (void *)&fhead, sizeof(mach_header_64)) != sizeof(mach_header_64)) {
 234      goto err;
 235   }
 236   print_debug("total commands: %d\n", fhead.ncmds);
 237   offset += sizeof(mach_header_64);
 238   for (i = 0; i < fhead.ncmds; i++) {
 239     lseek(fd, offset, SEEK_SET);
 240     if (read(fd, (void *)&lcmd, sizeof(load_command)) != sizeof(load_command)) {
 241       goto err;
 242     }
 243     offset += lcmd.cmdsize;    // next command position
 244     //print_debug("LC: 0x%x\n", lcmd.cmd);
 245     if (lcmd.cmd == LC_SEGMENT_64) {
 246       lseek(fd, -sizeof(load_command), SEEK_CUR);
 247       if (read(fd, (void *)&segcmd, sizeof(segment_command_64)) != sizeof(segment_command_64)) {
 248         print_debug("failed to read LC_SEGMENT_64 i = %d!\n", i);
 249         goto err;
 250       }
 251       if (add_map_info(ph, fd, segcmd.fileoff, segcmd.vmaddr, segcmd.vmsize, segcmd.flags) == NULL) {
 252         print_debug("Failed to add map_info at i = %d\n", i);
 253         goto err;
 254       }
 255       print_debug("LC_SEGMENT_64 added: nsects=%d fileoff=0x%llx vmaddr=0x%llx vmsize=0x%llx filesize=0x%llx %s\n",
 256                   segcmd.nsects, segcmd.fileoff, segcmd.vmaddr, segcmd.vmsize,
 257                   segcmd.filesize, &segcmd.segname[0]);
 258     } else if (lcmd.cmd == LC_THREAD || lcmd.cmd == LC_UNIXTHREAD) {
 259       typedef struct thread_fc {
 260         uint32_t  flavor;
 261         uint32_t  count;
 262       } thread_fc;
 263       thread_fc fc;
 264       uint32_t size = sizeof(load_command);
 265       while (size < lcmd.cmdsize) {
 266         if (read(fd, (void *)&fc, sizeof(thread_fc)) != sizeof(thread_fc)) {
 267           printf("Reading flavor, count failed.\n");
 268           goto err;
 269         }
 270         size += sizeof(thread_fc);
 271         if (fc.flavor == x86_THREAD_STATE) {


 771     *     entry that has integer regset for that LWP.
 772     *
 773     *     Linux threads are actually 'clone'd processes. To support core analysis
 774     *     of "multithreaded" process, Linux creates more than one pstatus (called
 775     *     "prstatus") entry in PT_NOTE. Each prstatus entry has integer regset for one
 776     *     "thread". Please refer to Linux kernel src file 'fs/binfmt_elf.c', in particular
 777     *     function "elf_core_dump".
 778     */
 779 
 780     for (core_php = phbuf, i = 0; i < core_ehdr->e_phnum; i++) {
 781       switch (core_php->p_type) {
 782          case PT_NOTE:
 783             if (core_handle_note(ph, core_php) != true) {
 784               goto err;
 785             }
 786             break;
 787 
 788          case PT_LOAD: {
 789             if (core_php->p_filesz != 0) {
 790                if (add_map_info(ph, ph->core->core_fd, core_php->p_offset,
 791                   core_php->p_vaddr, core_php->p_filesz, core_php->p_flags) == NULL) goto err;
 792             }
 793             break;
 794          }
 795       }
 796 
 797       core_php++;
 798    }
 799 
 800    free(phbuf);
 801    return true;
 802 err:
 803    free(phbuf);
 804    return false;
 805 }
 806 
 807 // read segments of a shared object
 808 static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* lib_ehdr, uintptr_t lib_base) {
 809   int i = 0;
 810   ELF_PHDR* phbuf;
 811   ELF_PHDR* lib_php = NULL;
 812 
 813   int page_size=sysconf(_SC_PAGE_SIZE);
 814 
 815   if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL) {
 816     return false;
 817   }
 818 
 819   // we want to process only PT_LOAD segments that are not writable.
 820   // i.e., text segments. The read/write/exec (data) segments would
 821   // have been already added from core file segments.
 822   for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) {
 823     if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) {
 824 
 825       uintptr_t target_vaddr = lib_php->p_vaddr + lib_base;
 826       map_info *existing_map = core_lookup(ph, target_vaddr);
 827 
 828       if (existing_map == NULL){
 829         if (add_map_info(ph, lib_fd, lib_php->p_offset,
 830                           target_vaddr, lib_php->p_filesz, lib_php->p_flags) == NULL) {
 831           goto err;
 832         }
 833       } else {
 834         if ((existing_map->memsz != page_size) &&
 835             (existing_map->fd != lib_fd) &&
 836             (existing_map->memsz != lib_php->p_filesz)){
 837 
 838           print_debug("address conflict @ 0x%lx (size = %ld, flags = %d\n)",
 839                         target_vaddr, lib_php->p_filesz, lib_php->p_flags);
 840           goto err;
 841         }
 842 
 843         /* replace PT_LOAD segment with library segment */
 844         print_debug("overwrote with new address mapping (memsz %ld -> %ld)\n",
 845                      existing_map->memsz, lib_php->p_filesz);
 846 
 847         existing_map->fd = lib_fd;
 848         existing_map->offset = lib_php->p_offset;
 849         existing_map->memsz = lib_php->p_filesz;
 850       }


 876 
 877    return true;
 878 }
 879 
 880 // process segments of a a.out
 881 static bool read_exec_segments(struct ps_prochandle* ph, ELF_EHDR* exec_ehdr) {
 882    int i = 0;
 883    ELF_PHDR* phbuf = NULL;
 884    ELF_PHDR* exec_php = NULL;
 885 
 886    if ((phbuf = read_program_header_table(ph->core->exec_fd, exec_ehdr)) == NULL)
 887       return false;
 888 
 889    for (exec_php = phbuf, i = 0; i < exec_ehdr->e_phnum; i++) {
 890       switch (exec_php->p_type) {
 891 
 892          // add mappings for PT_LOAD segments
 893          case PT_LOAD: {
 894             // add only non-writable segments of non-zero filesz
 895             if (!(exec_php->p_flags & PF_W) && exec_php->p_filesz != 0) {
 896                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;
 897             }
 898             break;
 899          }
 900 
 901          // read the interpreter and it's segments
 902          case PT_INTERP: {
 903             char interp_name[BUF_SIZE];
 904 
 905             pread(ph->core->exec_fd, interp_name, MIN(exec_php->p_filesz, BUF_SIZE), exec_php->p_offset);
 906             print_debug("ELF interpreter %s\n", interp_name);
 907             // read interpreter segments as well
 908             if ((ph->core->interp_fd = pathmap_open(interp_name)) < 0) {
 909                print_debug("can't open runtime loader\n");
 910                goto err;
 911             }
 912             break;
 913          }
 914 
 915          // from PT_DYNAMIC we want to read address of first link_map addr
 916          case PT_DYNAMIC: {


< prev index next >