hotspot/agent/src/os/linux/ps_core.c
changeset 33794 41ef3dc95179
parent 21069 728330d2593a
equal deleted inserted replaced
33790:229ed95d8958 33794:41ef3dc95179
   772   return false;
   772   return false;
   773 }
   773 }
   774 
   774 
   775 // process segments from interpreter (ld.so or ld-linux.so)
   775 // process segments from interpreter (ld.so or ld-linux.so)
   776 static bool read_interp_segments(struct ps_prochandle* ph) {
   776 static bool read_interp_segments(struct ps_prochandle* ph) {
   777    ELF_EHDR interp_ehdr;
   777   ELF_EHDR interp_ehdr;
   778 
   778 
   779    if (read_elf_header(ph->core->interp_fd, &interp_ehdr) != true) {
   779   if (read_elf_header(ph->core->interp_fd, &interp_ehdr) != true) {
   780        print_debug("interpreter is not a valid ELF file\n");
   780     print_debug("interpreter is not a valid ELF file\n");
   781        return false;
   781     return false;
   782    }
   782   }
   783 
   783 
   784    if (read_lib_segments(ph, ph->core->interp_fd, &interp_ehdr, ph->core->ld_base_addr) != true) {
   784   if (read_lib_segments(ph, ph->core->interp_fd, &interp_ehdr, ph->core->ld_base_addr) != true) {
   785        print_debug("can't read segments of interpreter\n");
   785     print_debug("can't read segments of interpreter\n");
   786        return false;
   786     return false;
   787    }
   787   }
   788 
   788 
   789    return true;
   789   return true;
   790 }
   790 }
   791 
   791 
   792 // process segments of a a.out
   792 // process segments of a a.out
   793 static bool read_exec_segments(struct ps_prochandle* ph, ELF_EHDR* exec_ehdr) {
   793 static bool read_exec_segments(struct ps_prochandle* ph, ELF_EHDR* exec_ehdr) {
   794    int i = 0;
   794   int i = 0;
   795    ELF_PHDR* phbuf = NULL;
   795   ELF_PHDR* phbuf = NULL;
   796    ELF_PHDR* exec_php = NULL;
   796   ELF_PHDR* exec_php = NULL;
   797 
   797 
   798    if ((phbuf = read_program_header_table(ph->core->exec_fd, exec_ehdr)) == NULL)
   798   if ((phbuf = read_program_header_table(ph->core->exec_fd, exec_ehdr)) == NULL) {
   799       return false;
   799     return false;
   800 
   800   }
   801    for (exec_php = phbuf, i = 0; i < exec_ehdr->e_phnum; i++) {
   801 
   802       switch (exec_php->p_type) {
   802   for (exec_php = phbuf, i = 0; i < exec_ehdr->e_phnum; i++) {
   803 
   803     switch (exec_php->p_type) {
   804          // add mappings for PT_LOAD segments
   804 
   805          case PT_LOAD: {
   805       // add mappings for PT_LOAD segments
   806             // add only non-writable segments of non-zero filesz
   806     case PT_LOAD: {
   807             if (!(exec_php->p_flags & PF_W) && exec_php->p_filesz != 0) {
   807       // add only non-writable segments of non-zero filesz
   808                if (add_map_info(ph, ph->core->exec_fd, exec_php->p_offset, exec_php->p_vaddr, exec_php->p_filesz) == NULL) goto err;
   808       if (!(exec_php->p_flags & PF_W) && exec_php->p_filesz != 0) {
   809             }
   809         if (add_map_info(ph, ph->core->exec_fd, exec_php->p_offset, exec_php->p_vaddr, exec_php->p_filesz) == NULL) goto err;
   810             break;
   810       }
   811          }
   811       break;
   812 
   812     }
   813          // read the interpreter and it's segments
   813 
   814          case PT_INTERP: {
   814     // read the interpreter and it's segments
   815             char interp_name[BUF_SIZE];
   815     case PT_INTERP: {
   816 
   816       char interp_name[BUF_SIZE + 1];
   817             pread(ph->core->exec_fd, interp_name, MIN(exec_php->p_filesz, BUF_SIZE), exec_php->p_offset);
   817 
   818             print_debug("ELF interpreter %s\n", interp_name);
   818       // BUF_SIZE is PATH_MAX + NAME_MAX + 1.
   819             // read interpreter segments as well
   819       if (exec_php->p_filesz > BUF_SIZE) {
   820             if ((ph->core->interp_fd = pathmap_open(interp_name)) < 0) {
   820         goto err;
   821                print_debug("can't open runtime loader\n");
   821       }
   822                goto err;
   822       pread(ph->core->exec_fd, interp_name, exec_php->p_filesz, exec_php->p_offset);
   823             }
   823       interp_name[exec_php->p_filesz] = '\0';
   824             break;
   824       print_debug("ELF interpreter %s\n", interp_name);
   825          }
   825       // read interpreter segments as well
   826 
   826       if ((ph->core->interp_fd = pathmap_open(interp_name)) < 0) {
   827          // from PT_DYNAMIC we want to read address of first link_map addr
   827         print_debug("can't open runtime loader\n");
   828          case PT_DYNAMIC: {
   828         goto err;
   829             ph->core->dynamic_addr = exec_php->p_vaddr;
   829       }
   830             print_debug("address of _DYNAMIC is 0x%lx\n", ph->core->dynamic_addr);
   830       break;
   831             break;
   831     }
   832          }
   832 
   833 
   833     // from PT_DYNAMIC we want to read address of first link_map addr
   834       } // switch
   834     case PT_DYNAMIC: {
   835       exec_php++;
   835       ph->core->dynamic_addr = exec_php->p_vaddr;
   836    } // for
   836       print_debug("address of _DYNAMIC is 0x%lx\n", ph->core->dynamic_addr);
   837 
   837       break;
   838    free(phbuf);
   838     }
   839    return true;
   839 
   840 err:
   840     } // switch
   841    free(phbuf);
   841     exec_php++;
   842    return false;
   842   } // for
       
   843 
       
   844   free(phbuf);
       
   845   return true;
       
   846  err:
       
   847   free(phbuf);
       
   848   return false;
   843 }
   849 }
   844 
   850 
   845 
   851 
   846 #define FIRST_LINK_MAP_OFFSET offsetof(struct r_debug,  r_map)
   852 #define FIRST_LINK_MAP_OFFSET offsetof(struct r_debug,  r_map)
   847 #define LD_BASE_OFFSET        offsetof(struct r_debug,  r_ldbase)
   853 #define LD_BASE_OFFSET        offsetof(struct r_debug,  r_ldbase)