24 25 #if defined(LINUX) || defined(__APPLE__) 26 #include <unistd.h> 27 #include <fcntl.h> 28 #include <string.h> 29 #include <stdlib.h> 30 #include <stddef.h> 31 #ifdef LINUX 32 #include <elf.h> 33 #include <link.h> 34 #include "proc_service.h" 35 #include "salibelf.h" 36 #endif 37 #include "libproc_impl.h" 38 #include "cds.h" 39 40 #ifdef __APPLE__ 41 #include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h" 42 #endif 43 44 #ifdef LINUX 45 // I have no idea why this function is called ps_pread() on macos but ps_pdread on linux. 46 #define ps_pread ps_pdread 47 #endif 48 49 // Common code shared between linux/native/libsaproc/ps_core.c and macosx/native/libsaproc/ps_core.c 50 51 //---------------------------------------------------------------------- 52 // ps_prochandle cleanup helper functions 53 54 // close all file descriptors 55 static void close_files(struct ps_prochandle* ph) { 56 lib_info* lib = NULL; 57 58 // close core file descriptor 59 if (ph->core->core_fd >= 0) 60 close(ph->core->core_fd); 61 62 // close exec file descriptor 63 if (ph->core->exec_fd >= 0) 96 } 97 98 // Part of the class sharing workaround 99 map = ph->core->class_share_maps; 100 while (map) { 101 map_info* next = map->next; 102 free(map); 103 map = next; 104 } 105 } 106 107 // ps_prochandle operations 108 void core_release(struct ps_prochandle* ph) { 109 if (ph->core) { 110 close_files(ph); 111 destroy_map_info(ph); 112 free(ph->core); 113 } 114 } 115 116 static map_info* allocate_init_map(int fd, off_t offset, uintptr_t vaddr, size_t memsz) { 117 map_info* map; 118 if ( (map = (map_info*) calloc(1, sizeof(map_info))) == NULL) { 119 print_debug("can't allocate memory for map_info\n"); 120 return NULL; 121 } 122 123 // initialize map 124 map->fd = fd; 125 map->offset = offset; 126 map->vaddr = vaddr; 127 map->memsz = memsz; 128 return map; 129 } 130 131 // add map info with given fd, offset, vaddr and memsz 132 map_info* add_map_info(struct ps_prochandle* ph, int fd, off_t offset, 133 uintptr_t vaddr, size_t memsz) { 134 map_info* map; 135 if ((map = allocate_init_map(fd, offset, vaddr, memsz)) == NULL) { 136 return NULL; 137 } 138 139 // add this to map list 140 map->next = ph->core->maps; 141 ph->core->maps = map; 142 ph->core->num_maps++; 143 144 return map; 145 } 146 147 // Part of the class sharing workaround 148 static map_info* add_class_share_map_info(struct ps_prochandle* ph, off_t offset, 149 uintptr_t vaddr, size_t memsz) { 150 map_info* map; 151 if ((map = allocate_init_map(ph->core->classes_jsa_fd, 152 offset, vaddr, memsz)) == NULL) { 153 return NULL; 154 } 155 156 map->next = ph->core->class_share_maps; 157 ph->core->class_share_maps = map; 158 return map; 159 } 160 161 // Return the map_info for the given virtual address. We keep a sorted 162 // array of pointers in ph->map_array, so we can binary search. 163 map_info* core_lookup(struct ps_prochandle *ph, uintptr_t addr) { 164 int mid, lo = 0, hi = ph->core->num_maps - 1; 165 map_info *mp; 166 167 while (hi - lo > 1) { 168 mid = (lo + hi) / 2; 169 if (addr >= ph->core->map_array[mid]->vaddr) { 170 lo = mid; 171 } else { 172 hi = mid; | 24 25 #if defined(LINUX) || defined(__APPLE__) 26 #include <unistd.h> 27 #include <fcntl.h> 28 #include <string.h> 29 #include <stdlib.h> 30 #include <stddef.h> 31 #ifdef LINUX 32 #include <elf.h> 33 #include <link.h> 34 #include "proc_service.h" 35 #include "salibelf.h" 36 #endif 37 #include "libproc_impl.h" 38 #include "cds.h" 39 40 #ifdef __APPLE__ 41 #include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h" 42 #endif 43 44 // Define a segment permission flag allowing read. 45 #ifdef PF_R 46 #define MAP_R_FLAG PF_R 47 #else 48 #define MAP_R_FLAG 0 49 #endif 50 51 #ifdef LINUX 52 // I have no idea why this function is called ps_pread() on macos but ps_pdread on linux. 53 #define ps_pread ps_pdread 54 #endif 55 56 // Common code shared between linux/native/libsaproc/ps_core.c and macosx/native/libsaproc/ps_core.c 57 58 //---------------------------------------------------------------------- 59 // ps_prochandle cleanup helper functions 60 61 // close all file descriptors 62 static void close_files(struct ps_prochandle* ph) { 63 lib_info* lib = NULL; 64 65 // close core file descriptor 66 if (ph->core->core_fd >= 0) 67 close(ph->core->core_fd); 68 69 // close exec file descriptor 70 if (ph->core->exec_fd >= 0) 103 } 104 105 // Part of the class sharing workaround 106 map = ph->core->class_share_maps; 107 while (map) { 108 map_info* next = map->next; 109 free(map); 110 map = next; 111 } 112 } 113 114 // ps_prochandle operations 115 void core_release(struct ps_prochandle* ph) { 116 if (ph->core) { 117 close_files(ph); 118 destroy_map_info(ph); 119 free(ph->core); 120 } 121 } 122 123 static map_info* allocate_init_map(int fd, off_t offset, uintptr_t vaddr, size_t memsz, uint32_t flags) { 124 map_info* map; 125 if ( (map = (map_info*) calloc(1, sizeof(map_info))) == NULL) { 126 print_debug("can't allocate memory for map_info\n"); 127 return NULL; 128 } 129 130 // initialize map 131 map->fd = fd; 132 map->offset = offset; 133 map->vaddr = vaddr; 134 map->memsz = memsz; 135 map->flags = flags; 136 return map; 137 } 138 139 // add map info with given fd, offset, vaddr and memsz 140 map_info* add_map_info(struct ps_prochandle* ph, int fd, off_t offset, 141 uintptr_t vaddr, size_t memsz, uint32_t flags) { 142 map_info* map; 143 if ((map = allocate_init_map(fd, offset, vaddr, memsz, flags)) == NULL) { 144 return NULL; 145 } 146 147 // add this to map list 148 map->next = ph->core->maps; 149 ph->core->maps = map; 150 ph->core->num_maps++; 151 152 return map; 153 } 154 155 // Part of the class sharing workaround 156 static map_info* add_class_share_map_info(struct ps_prochandle* ph, off_t offset, 157 uintptr_t vaddr, size_t memsz) { 158 map_info* map; 159 if ((map = allocate_init_map(ph->core->classes_jsa_fd, 160 offset, vaddr, memsz, MAP_R_FLAG)) == NULL) { 161 return NULL; 162 } 163 164 map->next = ph->core->class_share_maps; 165 ph->core->class_share_maps = map; 166 return map; 167 } 168 169 // Return the map_info for the given virtual address. We keep a sorted 170 // array of pointers in ph->map_array, so we can binary search. 171 map_info* core_lookup(struct ps_prochandle *ph, uintptr_t addr) { 172 int mid, lo = 0, hi = ph->core->num_maps - 1; 173 map_info *mp; 174 175 while (hi - lo > 1) { 176 mid = (lo + hi) / 2; 177 if (addr >= ph->core->map_array[mid]->vaddr) { 178 lo = mid; 179 } else { 180 hi = mid; |