1 /*
2 * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2021, Azul Systems, Inc. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26 #include <jni.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <stddef.h>
32 #include <sys/errno.h>
33 #include "libproc_impl.h"
34 #include "ps_core_common.h"
35
36 #ifdef __APPLE__
37 #if defined(amd64)
38 #include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h"
39 #elif defined(aarch64)
40 #include "sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext.h"
41 #else
42 #error UNSUPPORTED_ARCH
43 #endif
44 #endif /* __APPLE__ */
45
46 // This file has the libproc implementation to read core files.
47 // For live processes, refer to ps_proc.c. Portions of this is adapted
48 // /modelled after Solaris libproc.so (in particular Pcore.c)
49
50 //---------------------------------------------------------------------------
51 // functions to handle map_info
52
53 // Order mappings based on virtual address. We use this function as the
54 // callback for sorting the array of map_info pointers.
core_cmp_mapping(const void * lhsp,const void * rhsp)55 static int core_cmp_mapping(const void *lhsp, const void *rhsp)
56 {
57 const map_info *lhs = *((const map_info **)lhsp);
58 const map_info *rhs = *((const map_info **)rhsp);
59
60 if (lhs->vaddr == rhs->vaddr) {
61 return (0);
62 }
63
64 return (lhs->vaddr < rhs->vaddr ? -1 : 1);
65 }
66
67 // we sort map_info by starting virtual address so that we can do
68 // binary search to read from an address.
sort_map_array(struct ps_prochandle * ph)69 static bool sort_map_array(struct ps_prochandle* ph) {
70 size_t num_maps = ph->core->num_maps;
71 map_info* map = ph->core->maps;
72 int i = 0;
73
74 // allocate map_array
75 map_info** array;
76 if ( (array = (map_info**) malloc(sizeof(map_info*) * num_maps)) == NULL) {
77 print_debug("can't allocate memory for map array\n");
78 return false;
79 }
80
81 // add maps to array
82 while (map) {
83 array[i] = map;
84 i++;
85 map = map->next;
86 }
87
88 // sort is called twice. If this is second time, clear map array
89 if (ph->core->map_array) {
90 free(ph->core->map_array);
91 }
92 ph->core->map_array = array;
93 // sort the map_info array by base virtual address.
94 qsort(ph->core->map_array, ph->core->num_maps, sizeof (map_info*),
95 core_cmp_mapping);
96
97 // print map
98 if (is_debug()) {
99 int j = 0;
100 print_debug("---- sorted virtual address map ----\n");
101 for (j = 0; j < ph->core->num_maps; j++) {
102 print_debug("base = 0x%lx\tsize = %d\n", ph->core->map_array[j]->vaddr,
103 ph->core->map_array[j]->memsz);
104 }
105 }
106
107 return true;
108 }
109
110 #ifndef MIN
111 #define MIN(x, y) (((x) < (y))? (x): (y))
112 #endif
113
core_read_data(struct ps_prochandle * ph,uintptr_t addr,char * buf,size_t size)114 static bool core_read_data(struct ps_prochandle* ph, uintptr_t addr, char *buf, size_t size) {
115 ssize_t resid = size;
116 int page_size=sysconf(_SC_PAGE_SIZE);
117 while (resid != 0) {
118 map_info *mp = core_lookup(ph, addr);
119 uintptr_t mapoff;
120 ssize_t len, rem;
121 off_t off;
122 int fd;
123
124 if (mp == NULL) {
125 break; /* No mapping for this address */
126 }
127
128 fd = mp->fd;
129 mapoff = addr - mp->vaddr;
130 len = MIN(resid, mp->memsz - mapoff);
131 off = mp->offset + mapoff;
132
133 if ((len = pread(fd, buf, len, off)) <= 0) {
134 break;
135 }
136
137 resid -= len;
138 addr += len;
139 buf = (char *)buf + len;
140
141 // mappings always start at page boundary. But, may end in fractional
142 // page. fill zeros for possible fractional page at the end of a mapping.
143 rem = mp->memsz % page_size;
144 if (rem > 0) {
145 rem = page_size - rem;
146 len = MIN(resid, rem);
147 resid -= len;
148 addr += len;
149 // we are not assuming 'buf' to be zero initialized.
150 memset(buf, 0, len);
151 buf += len;
152 }
153 }
154
155 if (resid) {
156 print_debug("core read failed for %d byte(s) @ 0x%lx (%d more bytes)\n",
157 size, addr, resid);
158 return false;
159 } else {
160 return true;
161 }
162 }
163
164 // null implementation for write
core_write_data(struct ps_prochandle * ph,uintptr_t addr,const char * buf,size_t size)165 static bool core_write_data(struct ps_prochandle* ph,
166 uintptr_t addr, const char *buf , size_t size) {
167 return false;
168 }
169
core_get_lwp_regs(struct ps_prochandle * ph,lwpid_t lwp_id,struct reg * regs)170 static bool core_get_lwp_regs(struct ps_prochandle* ph, lwpid_t lwp_id,
171 struct reg* regs) {
172 // for core we have cached the lwp regs after segment parsed
173 sa_thread_info* thr = ph->threads;
174 while (thr) {
175 if (thr->lwp_id == lwp_id) {
176 memcpy(regs, &thr->regs, sizeof(struct reg));
177 return true;
178 }
179 thr = thr->next;
180 }
181 return false;
182 }
183
core_get_lwp_info(struct ps_prochandle * ph,lwpid_t id,void * info)184 static bool core_get_lwp_info(struct ps_prochandle *ph, lwpid_t id, void *info) {
185 print_debug("core_get_lwp_info not implemented\n");
186 return false;
187 }
188
189 static ps_prochandle_ops core_ops = {
190 .release= core_release,
191 .p_pread= core_read_data,
192 .p_pwrite= core_write_data,
193 .get_lwp_regs= core_get_lwp_regs,
194 .get_lwp_info= core_get_lwp_info
195 };
196
197 // from this point, mainly two blocks divided by def __APPLE__
198 // one for Macosx, the other for regular Bsd
199
200 #ifdef __APPLE__
201
print_thread(sa_thread_info * threadinfo)202 void print_thread(sa_thread_info *threadinfo) {
203 print_debug("thread added: %d\n", threadinfo->lwp_id);
204 print_debug("registers:\n");
205
206 #if defined(amd64)
207 print_debug(" r_r15: 0x%" PRIx64 "\n", threadinfo->regs.r_r15);
208 print_debug(" r_r14: 0x%" PRIx64 "\n", threadinfo->regs.r_r14);
209 print_debug(" r_r13: 0x%" PRIx64 "\n", threadinfo->regs.r_r13);
210 print_debug(" r_r12: 0x%" PRIx64 "\n", threadinfo->regs.r_r12);
211 print_debug(" r_r11: 0x%" PRIx64 "\n", threadinfo->regs.r_r11);
212 print_debug(" r_r10: 0x%" PRIx64 "\n", threadinfo->regs.r_r10);
213 print_debug(" r_r9: 0x%" PRIx64 "\n", threadinfo->regs.r_r9);
214 print_debug(" r_r8: 0x%" PRIx64 "\n", threadinfo->regs.r_r8);
215 print_debug(" r_rdi: 0x%" PRIx64 "\n", threadinfo->regs.r_rdi);
216 print_debug(" r_rsi: 0x%" PRIx64 "\n", threadinfo->regs.r_rsi);
217 print_debug(" r_rbp: 0x%" PRIx64 "\n", threadinfo->regs.r_rbp);
218 print_debug(" r_rbx: 0x%" PRIx64 "\n", threadinfo->regs.r_rbx);
219 print_debug(" r_rdx: 0x%" PRIx64 "\n", threadinfo->regs.r_rdx);
220 print_debug(" r_rcx: 0x%" PRIx64 "\n", threadinfo->regs.r_rcx);
221 print_debug(" r_rax: 0x%" PRIx64 "\n", threadinfo->regs.r_rax);
222 print_debug(" r_fs: 0x%" PRIx32 "\n", threadinfo->regs.r_fs);
223 print_debug(" r_gs: 0x%" PRIx32 "\n", threadinfo->regs.r_gs);
224 print_debug(" r_rip 0x%" PRIx64 "\n", threadinfo->regs.r_rip);
225 print_debug(" r_cs: 0x%" PRIx64 "\n", threadinfo->regs.r_cs);
226 print_debug(" r_rsp: 0x%" PRIx64 "\n", threadinfo->regs.r_rsp);
227 print_debug(" r_rflags: 0x%" PRIx64 "\n", threadinfo->regs.r_rflags);
228
229 #elif defined(aarch64)
230 print_debug(" r_r0: 0x%" PRIx64 "\n", threadinfo->regs.r_r0);
231 print_debug(" r_r1: 0x%" PRIx64 "\n", threadinfo->regs.r_r1);
232 print_debug(" r_r2: 0x%" PRIx64 "\n", threadinfo->regs.r_r2);
233 print_debug(" r_r3: 0x%" PRIx64 "\n", threadinfo->regs.r_r3);
234 print_debug(" r_r4: 0x%" PRIx64 "\n", threadinfo->regs.r_r4);
235 print_debug(" r_r5: 0x%" PRIx64 "\n", threadinfo->regs.r_r5);
236 print_debug(" r_r6: 0x%" PRIx64 "\n", threadinfo->regs.r_r6);
237 print_debug(" r_r7: 0x%" PRIx64 "\n", threadinfo->regs.r_r7);
238 print_debug(" r_r8: 0x%" PRIx64 "\n", threadinfo->regs.r_r8);
239 print_debug(" r_r9: 0x%" PRIx64 "\n", threadinfo->regs.r_r9);
240 print_debug(" r_r10: 0x%" PRIx64 "\n", threadinfo->regs.r_r10);
241 print_debug(" r_r11: 0x%" PRIx64 "\n", threadinfo->regs.r_r11);
242 print_debug(" r_r12: 0x%" PRIx64 "\n", threadinfo->regs.r_r12);
243 print_debug(" r_r13: 0x%" PRIx64 "\n", threadinfo->regs.r_r13);
244 print_debug(" r_r14: 0x%" PRIx64 "\n", threadinfo->regs.r_r14);
245 print_debug(" r_r15: 0x%" PRIx64 "\n", threadinfo->regs.r_r15);
246 print_debug(" r_r16: 0x%" PRIx64 "\n", threadinfo->regs.r_r16);
247 print_debug(" r_r17: 0x%" PRIx64 "\n", threadinfo->regs.r_r17);
248 print_debug(" r_r18: 0x%" PRIx64 "\n", threadinfo->regs.r_r18);
249 print_debug(" r_r19: 0x%" PRIx64 "\n", threadinfo->regs.r_r19);
250 print_debug(" r_r20: 0x%" PRIx64 "\n", threadinfo->regs.r_r20);
251 print_debug(" r_r21: 0x%" PRIx64 "\n", threadinfo->regs.r_r21);
252 print_debug(" r_r22: 0x%" PRIx64 "\n", threadinfo->regs.r_r22);
253 print_debug(" r_r23: 0x%" PRIx64 "\n", threadinfo->regs.r_r23);
254 print_debug(" r_r24: 0x%" PRIx64 "\n", threadinfo->regs.r_r24);
255 print_debug(" r_r25: 0x%" PRIx64 "\n", threadinfo->regs.r_r25);
256 print_debug(" r_r26: 0x%" PRIx64 "\n", threadinfo->regs.r_r26);
257 print_debug(" r_r27: 0x%" PRIx64 "\n", threadinfo->regs.r_r27);
258 print_debug(" r_r28: 0x%" PRIx64 "\n", threadinfo->regs.r_r28);
259 print_debug(" r_fp: 0x%" PRIx64 "\n", threadinfo->regs.r_fp);
260 print_debug(" r_lr: 0x%" PRIx64 "\n", threadinfo->regs.r_lr);
261 print_debug(" r_sp: 0x%" PRIx64 "\n", threadinfo->regs.r_sp);
262 print_debug(" r_pc: 0x%" PRIx64 "\n", threadinfo->regs.r_pc);
263
264 #else
265 #error UNSUPPORTED_ARCH
266 #endif
267 }
268
269 // read all segments64 commands from core file
270 // read all thread commands from core file
read_core_segments(struct ps_prochandle * ph)271 static bool read_core_segments(struct ps_prochandle* ph) {
272 int i = 0;
273 int num_threads = 0;
274 int fd = ph->core->core_fd;
275 off_t offset = 0;
276 mach_header_64 fhead;
277 load_command lcmd;
278 segment_command_64 segcmd;
279 // thread_command thrcmd;
280
281 lseek(fd, offset, SEEK_SET);
282 if(read(fd, (void *)&fhead, sizeof(mach_header_64)) != sizeof(mach_header_64)) {
283 goto err;
284 }
285 print_debug("total commands: %d\n", fhead.ncmds);
286 offset += sizeof(mach_header_64);
287 for (i = 0; i < fhead.ncmds; i++) {
288 lseek(fd, offset, SEEK_SET);
289 if (read(fd, (void *)&lcmd, sizeof(load_command)) != sizeof(load_command)) {
290 goto err;
291 }
292 offset += lcmd.cmdsize; // next command position
293 //print_debug("LC: 0x%x\n", lcmd.cmd);
294 if (lcmd.cmd == LC_SEGMENT_64) {
295 lseek(fd, -sizeof(load_command), SEEK_CUR);
296 if (read(fd, (void *)&segcmd, sizeof(segment_command_64)) != sizeof(segment_command_64)) {
297 print_debug("failed to read LC_SEGMENT_64 i = %d!\n", i);
298 goto err;
299 }
300 if (add_map_info(ph, fd, segcmd.fileoff, segcmd.vmaddr, segcmd.vmsize, segcmd.flags) == NULL) {
301 print_debug("Failed to add map_info at i = %d\n", i);
302 goto err;
303 }
304 print_debug("LC_SEGMENT_64 added: nsects=%d fileoff=0x%llx vmaddr=0x%llx vmsize=0x%llx filesize=0x%llx %s\n",
305 segcmd.nsects, segcmd.fileoff, segcmd.vmaddr, segcmd.vmsize,
306 segcmd.filesize, &segcmd.segname[0]);
307 } else if (lcmd.cmd == LC_THREAD || lcmd.cmd == LC_UNIXTHREAD) {
308 typedef struct thread_fc {
309 uint32_t flavor;
310 uint32_t count;
311 } thread_fc;
312 thread_fc fc;
313 uint32_t size = sizeof(load_command);
314 while (size < lcmd.cmdsize) {
315 if (read(fd, (void *)&fc, sizeof(thread_fc)) != sizeof(thread_fc)) {
316 printf("Reading flavor, count failed.\n");
317 goto err;
318 }
319 size += sizeof(thread_fc);
320 #if defined(amd64)
321 if (fc.flavor == x86_THREAD_STATE) {
322 x86_thread_state_t thrstate;
323 if (read(fd, (void *)&thrstate, sizeof(x86_thread_state_t)) != sizeof(x86_thread_state_t)) {
324 printf("Reading flavor, count failed.\n");
325 goto err;
326 }
327 size += sizeof(x86_thread_state_t);
328 // create thread info list, update lwp_id later
329 sa_thread_info* newthr = add_thread_info(ph, (pthread_t) -1, (lwpid_t) num_threads++);
330 if (newthr == NULL) {
331 printf("create thread_info failed\n");
332 goto err;
333 }
334
335 // note __DARWIN_UNIX03 depengs on other definitions
336 #if __DARWIN_UNIX03
337 #define get_register_v(regst, regname) \
338 regst.uts.ts64.__##regname
339 #else
340 #define get_register_v(regst, regname) \
341 regst.uts.ts64.##regname
342 #endif // __DARWIN_UNIX03
343 newthr->regs.r_rax = get_register_v(thrstate, rax);
344 newthr->regs.r_rbx = get_register_v(thrstate, rbx);
345 newthr->regs.r_rcx = get_register_v(thrstate, rcx);
346 newthr->regs.r_rdx = get_register_v(thrstate, rdx);
347 newthr->regs.r_rdi = get_register_v(thrstate, rdi);
348 newthr->regs.r_rsi = get_register_v(thrstate, rsi);
349 newthr->regs.r_rbp = get_register_v(thrstate, rbp);
350 newthr->regs.r_rsp = get_register_v(thrstate, rsp);
351 newthr->regs.r_r8 = get_register_v(thrstate, r8);
352 newthr->regs.r_r9 = get_register_v(thrstate, r9);
353 newthr->regs.r_r10 = get_register_v(thrstate, r10);
354 newthr->regs.r_r11 = get_register_v(thrstate, r11);
355 newthr->regs.r_r12 = get_register_v(thrstate, r12);
356 newthr->regs.r_r13 = get_register_v(thrstate, r13);
357 newthr->regs.r_r14 = get_register_v(thrstate, r14);
358 newthr->regs.r_r15 = get_register_v(thrstate, r15);
359 newthr->regs.r_rip = get_register_v(thrstate, rip);
360 newthr->regs.r_rflags = get_register_v(thrstate, rflags);
361 newthr->regs.r_cs = get_register_v(thrstate, cs);
362 newthr->regs.r_fs = get_register_v(thrstate, fs);
363 newthr->regs.r_gs = get_register_v(thrstate, gs);
364 print_thread(newthr);
365 } else if (fc.flavor == x86_FLOAT_STATE) {
366 x86_float_state_t flstate;
367 if (read(fd, (void *)&flstate, sizeof(x86_float_state_t)) != sizeof(x86_float_state_t)) {
368 print_debug("Reading flavor, count failed.\n");
369 goto err;
370 }
371 size += sizeof(x86_float_state_t);
372 } else if (fc.flavor == x86_EXCEPTION_STATE) {
373 x86_exception_state_t excpstate;
374 if (read(fd, (void *)&excpstate, sizeof(x86_exception_state_t)) != sizeof(x86_exception_state_t)) {
375 printf("Reading flavor, count failed.\n");
376 goto err;
377 }
378 size += sizeof(x86_exception_state_t);
379 }
380
381 #elif defined(aarch64)
382 if (fc.flavor == ARM_THREAD_STATE64) {
383 arm_thread_state64_t thrstate;
384 if (read(fd, (void *)&thrstate, sizeof(arm_thread_state64_t)) != sizeof(arm_thread_state64_t)) {
385 printf("Reading flavor, count failed.\n");
386 goto err;
387 }
388 size += sizeof(arm_thread_state64_t);
389 // create thread info list, update lwp_id later
390 sa_thread_info* newthr = add_thread_info(ph, (pthread_t) -1, (lwpid_t) num_threads++);
391 if (newthr == NULL) {
392 printf("create thread_info failed\n");
393 goto err;
394 }
395
396 // note __DARWIN_UNIX03 depengs on other definitions
397 #if __DARWIN_UNIX03
398 #define get_register_v(regst, regname) \
399 regst.__##regname
400 #else
401 #define get_register_v(regst, regname) \
402 regst.##regname
403 #endif // __DARWIN_UNIX03
404 newthr->regs.r_r0 = get_register_v(thrstate, x[0]);
405 newthr->regs.r_r1 = get_register_v(thrstate, x[1]);
406 newthr->regs.r_r2 = get_register_v(thrstate, x[2]);
407 newthr->regs.r_r3 = get_register_v(thrstate, x[3]);
408 newthr->regs.r_r4 = get_register_v(thrstate, x[4]);
409 newthr->regs.r_r5 = get_register_v(thrstate, x[5]);
410 newthr->regs.r_r6 = get_register_v(thrstate, x[6]);
411 newthr->regs.r_r7 = get_register_v(thrstate, x[7]);
412 newthr->regs.r_r8 = get_register_v(thrstate, x[8]);
413 newthr->regs.r_r9 = get_register_v(thrstate, x[9]);
414 newthr->regs.r_r10 = get_register_v(thrstate, x[10]);
415 newthr->regs.r_r11 = get_register_v(thrstate, x[11]);
416 newthr->regs.r_r12 = get_register_v(thrstate, x[12]);
417 newthr->regs.r_r13 = get_register_v(thrstate, x[13]);
418 newthr->regs.r_r14 = get_register_v(thrstate, x[14]);
419 newthr->regs.r_r15 = get_register_v(thrstate, x[15]);
420 newthr->regs.r_r16 = get_register_v(thrstate, x[16]);
421 newthr->regs.r_r17 = get_register_v(thrstate, x[17]);
422 newthr->regs.r_r18 = get_register_v(thrstate, x[18]);
423 newthr->regs.r_r19 = get_register_v(thrstate, x[19]);
424 newthr->regs.r_r20 = get_register_v(thrstate, x[20]);
425 newthr->regs.r_r21 = get_register_v(thrstate, x[21]);
426 newthr->regs.r_r22 = get_register_v(thrstate, x[22]);
427 newthr->regs.r_r23 = get_register_v(thrstate, x[23]);
428 newthr->regs.r_r24 = get_register_v(thrstate, x[24]);
429 newthr->regs.r_r25 = get_register_v(thrstate, x[25]);
430 newthr->regs.r_r26 = get_register_v(thrstate, x[26]);
431 newthr->regs.r_r27 = get_register_v(thrstate, x[27]);
432 newthr->regs.r_r28 = get_register_v(thrstate, x[28]);
433 newthr->regs.r_fp = get_register_v(thrstate, fp);
434 newthr->regs.r_lr = get_register_v(thrstate, lr);
435 newthr->regs.r_sp = get_register_v(thrstate, sp);
436 newthr->regs.r_pc = get_register_v(thrstate, pc);
437 print_thread(newthr);
438 } else if (fc.flavor == ARM_NEON_STATE64) {
439 arm_neon_state64_t flstate;
440 if (read(fd, (void *)&flstate, sizeof(arm_neon_state64_t)) != sizeof(arm_neon_state64_t)) {
441 printf("Reading flavor, count failed.\n");
442 goto err;
443 }
444 size += sizeof(arm_neon_state64_t);
445 } else if (fc.flavor == ARM_EXCEPTION_STATE64) {
446 arm_exception_state64_t excpstate;
447 if (read(fd, (void *)&excpstate, sizeof(arm_exception_state64_t)) != sizeof(arm_exception_state64_t)) {
448 printf("Reading flavor, count failed.\n");
449 goto err;
450 }
451 size += sizeof(arm_exception_state64_t);
452 } else if (fc.flavor == ARM_DEBUG_STATE64) {
453 arm_debug_state64_t dbgstate;
454 if (read(fd, (void *)&dbgstate, sizeof(arm_debug_state64_t)) != sizeof(arm_debug_state64_t)) {
455 printf("Reading flavor, count failed.\n");
456 goto err;
457 }
458 size += sizeof(arm_debug_state64_t);
459 }
460
461 #else
462 #error UNSUPPORTED_ARCH
463 #endif
464 }
465 }
466 }
467 return true;
468 err:
469 return false;
470 }
471
exists(const char * fname)472 static bool exists(const char *fname) {
473 return access(fname, F_OK) == 0;
474 }
475
476 // reverse strstr()
rstrstr(const char * str,const char * sub)477 static char* rstrstr(const char *str, const char *sub) {
478 char *result = NULL;
479 for (char *p = strstr(str, sub); p != NULL; p = strstr(p + 1, sub)) {
480 result = p;
481 }
482 return result;
483 }
484
485 // Check if <filename> exists in the <jdk_subdir> directory of <jdk_dir>.
486 // Note <jdk_subdir> and <filename> already have '/' prepended.
get_real_path_jdk_subdir(char * rpath,char * filename,char * jdk_dir,char * jdk_subdir)487 static bool get_real_path_jdk_subdir(char* rpath, char* filename, char* jdk_dir, char* jdk_subdir) {
488 char filepath[BUF_SIZE];
489 strncpy(filepath, jdk_dir, BUF_SIZE);
490 filepath[BUF_SIZE - 1] = '\0'; // just in case jdk_dir didn't fit
491 strncat(filepath, jdk_subdir, BUF_SIZE - 1 - strlen(filepath));
492 strncat(filepath, filename, BUF_SIZE - 1 - strlen(filepath));
493 if (exists(filepath)) {
494 strcpy(rpath, filepath);
495 return true;
496 }
497 return false;
498 }
499
500 // Look for <filename> in various subdirs of <jdk_dir>.
get_real_path_jdk_dir(char * rpath,char * filename,char * jdk_dir)501 static bool get_real_path_jdk_dir(char* rpath, char* filename, char* jdk_dir) {
502 if (get_real_path_jdk_subdir(rpath, filename, jdk_dir, "/lib")) {
503 return true;
504 }
505 if (get_real_path_jdk_subdir(rpath, filename, jdk_dir, "/lib/server")) {
506 return true;
507 }
508 if (get_real_path_jdk_subdir(rpath, filename, jdk_dir, "/jre/lib")) {
509 return true;
510 }
511 if (get_real_path_jdk_subdir(rpath, filename, jdk_dir, "/jre/lib/server")) {
512 return true;
513 }
514 return false;
515 }
516
517 // Get the file specified by rpath. We check various directories for it.
get_real_path(struct ps_prochandle * ph,char * rpath)518 static bool get_real_path(struct ps_prochandle* ph, char *rpath) {
519 char* execname = ph->core->exec_path;
520 char jdk_dir[BUF_SIZE];
521 char* posbin;
522 char* filename = strrchr(rpath, '/'); // like /libjvm.dylib
523 if (filename == NULL) {
524 return false;
525 }
526
527 // First look for the library in 3 places where the JDK might be located. For each of
528 // these 3 potential JDK locations we look in lib, lib/server, jre/lib, and jre/lib/server.
529
530 posbin = rstrstr(execname, "/bin/java");
531 if (posbin != NULL) {
532 strncpy(jdk_dir, execname, posbin - execname);
533 jdk_dir[posbin - execname] = '\0';
534 if (get_real_path_jdk_dir(rpath, filename, jdk_dir)) {
535 return true;
536 }
537 }
538
539 char* java_home = getenv("JAVA_HOME");
540 if (java_home != NULL) {
541 if (get_real_path_jdk_dir(rpath, filename, java_home)) {
542 return true;
543 }
544 }
545
546 // Look for bin directory in path. This is useful when attaching to a core file
547 // that was launched with a JDK tool other than "java".
548 posbin = rstrstr(execname, "/bin/"); // look for the last occurence of "/bin/"
549 if (posbin != NULL) {
550 strncpy(jdk_dir, execname, posbin - execname);
551 jdk_dir[posbin - execname] = '\0';
552 if (get_real_path_jdk_dir(rpath, filename, jdk_dir)) {
553 return true;
554 }
555 }
556
557 // If we didn't find the library in any of the 3 above potential JDK locations, then look in
558 // DYLD_LIBRARY_PATH. This is where user libraries might be. We don't treat these
559 // paths as JDK paths, so we don't append the various JDK subdirs like lib/server.
560 // However, that doesn't preclude JDK libraries from actually being in one of the paths.
561 char* dyldpath = getenv("DYLD_LIBRARY_PATH");
562 if (dyldpath != NULL) {
563 char* save_ptr;
564 char filepath[BUF_SIZE];
565 char* dypath = strtok_r(dyldpath, ":", &save_ptr);
566 while (dypath != NULL) {
567 strncpy(filepath, dypath, BUF_SIZE);
568 filepath[BUF_SIZE - 1] = '\0'; // just in case dypath didn't fit
569 strncat(filepath, filename, BUF_SIZE - 1 - strlen(filepath));
570 if (exists(filepath)) {
571 strcpy(rpath, filepath);
572 return true;
573 }
574 dypath = strtok_r(NULL, ":", &save_ptr);
575 }
576 }
577
578 return false;
579 }
580
read_shared_lib_info(struct ps_prochandle * ph)581 static bool read_shared_lib_info(struct ps_prochandle* ph) {
582 static int pagesize = 0;
583 int fd = ph->core->core_fd;
584 int i = 0, j;
585 uint32_t v;
586 mach_header_64 header; // used to check if a file header in segment
587 load_command lcmd;
588 dylib_command dylibcmd;
589
590 char name[BUF_SIZE]; // use to store name
591
592 if (pagesize == 0) {
593 pagesize = getpagesize();
594 print_debug("page size is %d\n", pagesize);
595 }
596 for (j = 0; j < ph->core->num_maps; j++) {
597 map_info *iter = ph->core->map_array[j]; // head
598 off_t fpos = iter->offset;
599 if (iter->fd != fd) {
600 // only search core file!
601 continue;
602 }
603 print_debug("map_info %d: vmaddr = 0x%016llx fileoff = 0x%llx vmsize = 0x%lx\n",
604 j, iter->vaddr, iter->offset, iter->memsz);
605 lseek(fd, fpos, SEEK_SET);
606 // we assume .dylib loaded at segment address --- which is true for JVM libraries
607 // multiple files may be loaded in one segment.
608 // if first word is not a magic word, means this segment does not contain lib file.
609 if (read(fd, (void *)&v, sizeof(uint32_t)) == sizeof(uint32_t)) {
610 if (v != MH_MAGIC_64) {
611 continue;
612 }
613 } else {
614 // may be encountered last map, which is not readable
615 continue;
616 }
617 while (ltell(fd) - iter->offset < iter->memsz) {
618 lseek(fd, fpos, SEEK_SET);
619 if (read(fd, (void *)&v, sizeof(uint32_t)) != sizeof(uint32_t)) {
620 break;
621 }
622 if (v != MH_MAGIC_64) {
623 fpos = (ltell(fd) + pagesize -1)/pagesize * pagesize;
624 continue;
625 }
626 lseek(fd, -sizeof(uint32_t), SEEK_CUR);
627 // This is the begining of the mach-o file in the segment.
628 if (read(fd, (void *)&header, sizeof(mach_header_64)) != sizeof(mach_header_64)) {
629 goto err;
630 }
631 fpos = ltell(fd);
632
633 // found a mach-o file in this segment
634 for (i = 0; i < header.ncmds; i++) {
635 // read commands in this "file"
636 // LC_ID_DYLIB is the file itself for a .dylib
637 lseek(fd, fpos, SEEK_SET);
638 if (read(fd, (void *)&lcmd, sizeof(load_command)) != sizeof(load_command)) {
639 return false; // error
640 }
641 fpos += lcmd.cmdsize; // next command position
642 // make sure still within seg size.
643 if (fpos - lcmd.cmdsize - iter->offset > iter->memsz) {
644 print_debug("Warning: out of segement limit: %ld \n", fpos - lcmd.cmdsize - iter->offset);
645 break; // no need to iterate all commands
646 }
647 if (lcmd.cmd == LC_ID_DYLIB) {
648 lseek(fd, -sizeof(load_command), SEEK_CUR);
649 if (read(fd, (void *)&dylibcmd, sizeof(dylib_command)) != sizeof(dylib_command)) {
650 return false;
651 }
652 /**** name stored at dylib_command.dylib.name.offset, is a C string */
653 lseek(fd, dylibcmd.dylib.name.offset - sizeof(dylib_command), SEEK_CUR);
654 int j = 0;
655 while (j < BUF_SIZE) {
656 read(fd, (void *)(name + j), sizeof(char));
657 if (name[j] == '\0') break;
658 j++;
659 }
660 print_debug("%d %s\n", lcmd.cmd, name);
661 // changed name from @rpath/xxxx.dylib to real path
662 if (strrchr(name, '@')) {
663 get_real_path(ph, name);
664 print_debug("get_real_path returned: %s\n", name);
665 } else {
666 break; // Ignore non-relative paths, which are system libs. See JDK-8249779.
667 }
668 add_lib_info(ph, name, iter->vaddr);
669 break;
670 }
671 }
672 // done with the file, advanced to next page to search more files
673 #if 0
674 // This line is disabled due to JDK-8249779. Instead we break out of the loop
675 // and don't attempt to find any more mach-o files in this segment.
676 fpos = (ltell(fd) + pagesize - 1) / pagesize * pagesize;
677 #else
678 break;
679 #endif
680 }
681 }
682 return true;
683 err:
684 return false;
685 }
686
read_macho64_header(int fd,mach_header_64 * core_header)687 bool read_macho64_header(int fd, mach_header_64* core_header) {
688 bool is_macho = false;
689 if (fd < 0) return false;
690 off_t pos = ltell(fd);
691 lseek(fd, 0, SEEK_SET);
692 if (read(fd, (void *)core_header, sizeof(mach_header_64)) != sizeof(mach_header_64)) {
693 is_macho = false;
694 } else {
695 is_macho = (core_header->magic == MH_MAGIC_64 || core_header->magic == MH_CIGAM_64);
696 }
697 lseek(fd, pos, SEEK_SET);
698 return is_macho;
699 }
700
701 // the one and only one exposed stuff from this file
Pgrab_core(const char * exec_file,const char * core_file)702 struct ps_prochandle* Pgrab_core(const char* exec_file, const char* core_file) {
703 mach_header_64 core_header;
704 mach_header_64 exec_header;
705
706 struct ps_prochandle* ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle));
707 if (ph == NULL) {
708 print_debug("cant allocate ps_prochandle\n");
709 return NULL;
710 }
711
712 if ((ph->core = (struct core_data*) calloc(1, sizeof(struct core_data))) == NULL) {
713 free(ph);
714 print_debug("can't allocate ps_prochandle\n");
715 return NULL;
716 }
717
718 // initialize ph
719 ph->ops = &core_ops;
720 ph->core->core_fd = -1;
721 ph->core->exec_fd = -1;
722 ph->core->interp_fd = -1;
723
724 print_debug("exec: %s core: %s\n", exec_file, core_file);
725
726 strncpy(ph->core->exec_path, exec_file, sizeof(ph->core->exec_path));
727
728 // open the core file
729 if ((ph->core->core_fd = open(core_file, O_RDONLY)) < 0) {
730 print_error("can't open core file: %s\n", strerror(errno));
731 goto err;
732 }
733
734 // read core file header
735 if (read_macho64_header(ph->core->core_fd, &core_header) != true || core_header.filetype != MH_CORE) {
736 print_debug("core file is not a valid Mach-O file\n");
737 goto err;
738 }
739
740 if ((ph->core->exec_fd = open(exec_file, O_RDONLY)) < 0) {
741 print_error("can't open executable file\n");
742 goto err;
743 }
744
745 if (read_macho64_header(ph->core->exec_fd, &exec_header) != true ||
746 exec_header.filetype != MH_EXECUTE) {
747 print_error("executable file is not a valid Mach-O file\n");
748 goto err;
749 }
750
751 // process core file segments
752 if (read_core_segments(ph) != true) {
753 print_error("failed to read core segments\n");
754 goto err;
755 }
756
757 // allocate and sort maps into map_array, we need to do this
758 // here because read_shared_lib_info needs to read from debuggee
759 // address space
760 if (sort_map_array(ph) != true) {
761 print_error("failed to sort segment map array\n");
762 goto err;
763 }
764
765 if (read_shared_lib_info(ph) != true) {
766 print_error("failed to read libraries\n");
767 goto err;
768 }
769
770 // sort again because we have added more mappings from shared objects
771 if (sort_map_array(ph) != true) {
772 print_error("failed to sort segment map array\n");
773 goto err;
774 }
775
776 if (init_classsharing_workaround(ph) != true) {
777 print_error("failed to workaround classshareing\n");
778 goto err;
779 }
780
781 print_debug("Leave Pgrab_core\n");
782 return ph;
783
784 err:
785 Prelease(ph);
786 return NULL;
787 }
788
789 #else // __APPLE__ (none macosx)
790
791 // read regs and create thread from core file
core_handle_prstatus(struct ps_prochandle * ph,const char * buf,size_t nbytes)792 static bool core_handle_prstatus(struct ps_prochandle* ph, const char* buf, size_t nbytes) {
793 // we have to read prstatus_t from buf
794 // assert(nbytes == sizeof(prstaus_t), "size mismatch on prstatus_t");
795 prstatus_t* prstat = (prstatus_t*) buf;
796 sa_thread_info* newthr;
797 print_debug("got integer regset for lwp %d\n", prstat->pr_pid);
798 // we set pthread_t to -1 for core dump
799 if((newthr = add_thread_info(ph, (pthread_t) -1, prstat->pr_pid)) == NULL)
800 return false;
801
802 // copy regs
803 memcpy(&newthr->regs, &prstat->pr_reg, sizeof(struct reg));
804
805 if (is_debug()) {
806 print_debug("integer regset\n");
807 #if defined(i586) || defined(i386)
808 // print the regset
809 print_debug("\teax = 0x%x\n", newthr->regs.r_eax);
810 print_debug("\tebx = 0x%x\n", newthr->regs.r_ebx);
811 print_debug("\tecx = 0x%x\n", newthr->regs.r_ecx);
812 print_debug("\tedx = 0x%x\n", newthr->regs.r_edx);
813 print_debug("\tesp = 0x%x\n", newthr->regs.r_esp);
814 print_debug("\tebp = 0x%x\n", newthr->regs.r_ebp);
815 print_debug("\tesi = 0x%x\n", newthr->regs.r_esi);
816 print_debug("\tedi = 0x%x\n", newthr->regs.r_edi);
817 print_debug("\teip = 0x%x\n", newthr->regs.r_eip);
818 #endif
819
820 #if defined(amd64) || defined(x86_64)
821 // print the regset
822 print_debug("\tr15 = 0x%lx\n", newthr->regs.r_r15);
823 print_debug("\tr14 = 0x%lx\n", newthr->regs.r_r14);
824 print_debug("\tr13 = 0x%lx\n", newthr->regs.r_r13);
825 print_debug("\tr12 = 0x%lx\n", newthr->regs.r_r12);
826 print_debug("\trbp = 0x%lx\n", newthr->regs.r_rbp);
827 print_debug("\trbx = 0x%lx\n", newthr->regs.r_rbx);
828 print_debug("\tr11 = 0x%lx\n", newthr->regs.r_r11);
829 print_debug("\tr10 = 0x%lx\n", newthr->regs.r_r10);
830 print_debug("\tr9 = 0x%lx\n", newthr->regs.r_r9);
831 print_debug("\tr8 = 0x%lx\n", newthr->regs.r_r8);
832 print_debug("\trax = 0x%lx\n", newthr->regs.r_rax);
833 print_debug("\trcx = 0x%lx\n", newthr->regs.r_rcx);
834 print_debug("\trdx = 0x%lx\n", newthr->regs.r_rdx);
835 print_debug("\trsi = 0x%lx\n", newthr->regs.r_rsi);
836 print_debug("\trdi = 0x%lx\n", newthr->regs.r_rdi);
837 //print_debug("\torig_rax = 0x%lx\n", newthr->regs.orig_rax);
838 print_debug("\trip = 0x%lx\n", newthr->regs.r_rip);
839 print_debug("\tcs = 0x%lx\n", newthr->regs.r_cs);
840 //print_debug("\teflags = 0x%lx\n", newthr->regs.eflags);
841 print_debug("\trsp = 0x%lx\n", newthr->regs.r_rsp);
842 print_debug("\tss = 0x%lx\n", newthr->regs.r_ss);
843 //print_debug("\tfs_base = 0x%lx\n", newthr->regs.fs_base);
844 //print_debug("\tgs_base = 0x%lx\n", newthr->regs.gs_base);
845 //print_debug("\tds = 0x%lx\n", newthr->regs.ds);
846 //print_debug("\tes = 0x%lx\n", newthr->regs.es);
847 //print_debug("\tfs = 0x%lx\n", newthr->regs.fs);
848 //print_debug("\tgs = 0x%lx\n", newthr->regs.gs);
849 #endif
850 }
851
852 return true;
853 }
854
855 #define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))
856
857 // read NT_PRSTATUS entries from core NOTE segment
core_handle_note(struct ps_prochandle * ph,ELF_PHDR * note_phdr)858 static bool core_handle_note(struct ps_prochandle* ph, ELF_PHDR* note_phdr) {
859 char* buf = NULL;
860 char* p = NULL;
861 size_t size = note_phdr->p_filesz;
862
863 // we are interested in just prstatus entries. we will ignore the rest.
864 // Advance the seek pointer to the start of the PT_NOTE data
865 if (lseek(ph->core->core_fd, note_phdr->p_offset, SEEK_SET) == (off_t)-1) {
866 print_debug("failed to lseek to PT_NOTE data\n");
867 return false;
868 }
869
870 // Now process the PT_NOTE structures. Each one is preceded by
871 // an Elf{32/64}_Nhdr structure describing its type and size.
872 if ( (buf = (char*) malloc(size)) == NULL) {
873 print_debug("can't allocate memory for reading core notes\n");
874 goto err;
875 }
876
877 // read notes into buffer
878 if (read(ph->core->core_fd, buf, size) != size) {
879 print_debug("failed to read notes, core file must have been truncated\n");
880 goto err;
881 }
882
883 p = buf;
884 while (p < buf + size) {
885 ELF_NHDR* notep = (ELF_NHDR*) p;
886 char* descdata = p + sizeof(ELF_NHDR) + ROUNDUP(notep->n_namesz, 4);
887 print_debug("Note header with n_type = %d and n_descsz = %u\n",
888 notep->n_type, notep->n_descsz);
889
890 if (notep->n_type == NT_PRSTATUS) {
891 if (core_handle_prstatus(ph, descdata, notep->n_descsz) != true) {
892 return false;
893 }
894 }
895 p = descdata + ROUNDUP(notep->n_descsz, 4);
896 }
897
898 free(buf);
899 return true;
900
901 err:
902 if (buf) free(buf);
903 return false;
904 }
905
906 // read all segments from core file
read_core_segments(struct ps_prochandle * ph,ELF_EHDR * core_ehdr)907 static bool read_core_segments(struct ps_prochandle* ph, ELF_EHDR* core_ehdr) {
908 int i = 0;
909 ELF_PHDR* phbuf = NULL;
910 ELF_PHDR* core_php = NULL;
911
912 if ((phbuf = read_program_header_table(ph->core->core_fd, core_ehdr)) == NULL)
913 return false;
914
915 /*
916 * Now iterate through the program headers in the core file.
917 * We're interested in two types of Phdrs: PT_NOTE (which
918 * contains a set of saved /proc structures), and PT_LOAD (which
919 * represents a memory mapping from the process's address space).
920 *
921 * Difference b/w Solaris PT_NOTE and Linux/BSD PT_NOTE:
922 *
923 * In Solaris there are two PT_NOTE segments the first PT_NOTE (if present)
924 * contains /proc structs in the pre-2.6 unstructured /proc format. the last
925 * PT_NOTE has data in new /proc format.
926 *
927 * In Solaris, there is only one pstatus (process status). pstatus contains
928 * integer register set among other stuff. For each LWP, we have one lwpstatus
929 * entry that has integer regset for that LWP.
930 *
931 * Linux threads are actually 'clone'd processes. To support core analysis
932 * of "multithreaded" process, Linux creates more than one pstatus (called
933 * "prstatus") entry in PT_NOTE. Each prstatus entry has integer regset for one
934 * "thread". Please refer to Linux kernel src file 'fs/binfmt_elf.c', in particular
935 * function "elf_core_dump".
936 */
937
938 for (core_php = phbuf, i = 0; i < core_ehdr->e_phnum; i++) {
939 switch (core_php->p_type) {
940 case PT_NOTE:
941 if (core_handle_note(ph, core_php) != true) {
942 goto err;
943 }
944 break;
945
946 case PT_LOAD: {
947 if (core_php->p_filesz != 0) {
948 if (add_map_info(ph, ph->core->core_fd, core_php->p_offset,
949 core_php->p_vaddr, core_php->p_filesz, core_php->p_flags) == NULL) goto err;
950 }
951 break;
952 }
953 }
954
955 core_php++;
956 }
957
958 free(phbuf);
959 return true;
960 err:
961 free(phbuf);
962 return false;
963 }
964
965 // read segments of a shared object
read_lib_segments(struct ps_prochandle * ph,int lib_fd,ELF_EHDR * lib_ehdr,uintptr_t lib_base)966 static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* lib_ehdr, uintptr_t lib_base) {
967 int i = 0;
968 ELF_PHDR* phbuf;
969 ELF_PHDR* lib_php = NULL;
970
971 int page_size=sysconf(_SC_PAGE_SIZE);
972
973 if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL) {
974 return false;
975 }
976
977 // we want to process only PT_LOAD segments that are not writable.
978 // i.e., text segments. The read/write/exec (data) segments would
979 // have been already added from core file segments.
980 for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) {
981 if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) {
982
983 uintptr_t target_vaddr = lib_php->p_vaddr + lib_base;
984 map_info *existing_map = core_lookup(ph, target_vaddr);
985
986 if (existing_map == NULL){
987 if (add_map_info(ph, lib_fd, lib_php->p_offset,
988 target_vaddr, lib_php->p_filesz, lib_php->p_flags) == NULL) {
989 goto err;
990 }
991 } else {
992 if ((existing_map->memsz != page_size) &&
993 (existing_map->fd != lib_fd) &&
994 (existing_map->memsz != lib_php->p_filesz)){
995
996 print_debug("address conflict @ 0x%lx (size = %ld, flags = %d\n)",
997 target_vaddr, lib_php->p_filesz, lib_php->p_flags);
998 goto err;
999 }
1000
1001 /* replace PT_LOAD segment with library segment */
1002 print_debug("overwrote with new address mapping (memsz %ld -> %ld)\n",
1003 existing_map->memsz, lib_php->p_filesz);
1004
1005 existing_map->fd = lib_fd;
1006 existing_map->offset = lib_php->p_offset;
1007 existing_map->memsz = lib_php->p_filesz;
1008 }
1009 }
1010
1011 lib_php++;
1012 }
1013
1014 free(phbuf);
1015 return true;
1016 err:
1017 free(phbuf);
1018 return false;
1019 }
1020
1021 // process segments from interpreter (ld.so or ld-linux.so or ld-elf.so)
read_interp_segments(struct ps_prochandle * ph)1022 static bool read_interp_segments(struct ps_prochandle* ph) {
1023 ELF_EHDR interp_ehdr;
1024
1025 if (read_elf_header(ph->core->interp_fd, &interp_ehdr) != true) {
1026 print_debug("interpreter is not a valid ELF file\n");
1027 return false;
1028 }
1029
1030 if (read_lib_segments(ph, ph->core->interp_fd, &interp_ehdr, ph->core->ld_base_addr) != true) {
1031 print_debug("can't read segments of interpreter\n");
1032 return false;
1033 }
1034
1035 return true;
1036 }
1037
1038 // process segments of a a.out
read_exec_segments(struct ps_prochandle * ph,ELF_EHDR * exec_ehdr)1039 static bool read_exec_segments(struct ps_prochandle* ph, ELF_EHDR* exec_ehdr) {
1040 int i = 0;
1041 ELF_PHDR* phbuf = NULL;
1042 ELF_PHDR* exec_php = NULL;
1043
1044 if ((phbuf = read_program_header_table(ph->core->exec_fd, exec_ehdr)) == NULL)
1045 return false;
1046
1047 for (exec_php = phbuf, i = 0; i < exec_ehdr->e_phnum; i++) {
1048 switch (exec_php->p_type) {
1049
1050 // add mappings for PT_LOAD segments
1051 case PT_LOAD: {
1052 // add only non-writable segments of non-zero filesz
1053 if (!(exec_php->p_flags & PF_W) && exec_php->p_filesz != 0) {
1054 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;
1055 }
1056 break;
1057 }
1058
1059 // read the interpreter and it's segments
1060 case PT_INTERP: {
1061 char interp_name[BUF_SIZE];
1062
1063 pread(ph->core->exec_fd, interp_name, MIN(exec_php->p_filesz, BUF_SIZE), exec_php->p_offset);
1064 print_debug("ELF interpreter %s\n", interp_name);
1065 // read interpreter segments as well
1066 if ((ph->core->interp_fd = pathmap_open(interp_name)) < 0) {
1067 print_debug("can't open runtime loader\n");
1068 goto err;
1069 }
1070 break;
1071 }
1072
1073 // from PT_DYNAMIC we want to read address of first link_map addr
1074 case PT_DYNAMIC: {
1075 ph->core->dynamic_addr = exec_php->p_vaddr;
1076 print_debug("address of _DYNAMIC is 0x%lx\n", ph->core->dynamic_addr);
1077 break;
1078 }
1079
1080 } // switch
1081 exec_php++;
1082 } // for
1083
1084 free(phbuf);
1085 return true;
1086 err:
1087 free(phbuf);
1088 return false;
1089 }
1090
1091 #define FIRST_LINK_MAP_OFFSET offsetof(struct r_debug, r_map)
1092 #define LD_BASE_OFFSET offsetof(struct r_debug, r_ldbase)
1093 #define LINK_MAP_ADDR_OFFSET offsetof(struct link_map, l_addr)
1094 #define LINK_MAP_NAME_OFFSET offsetof(struct link_map, l_name)
1095 #define LINK_MAP_NEXT_OFFSET offsetof(struct link_map, l_next)
1096
1097 // read shared library info from runtime linker's data structures.
1098 // This work is done by librtlb_db in Solaris
read_shared_lib_info(struct ps_prochandle * ph)1099 static bool read_shared_lib_info(struct ps_prochandle* ph) {
1100 uintptr_t addr = ph->core->dynamic_addr;
1101 uintptr_t debug_base;
1102 uintptr_t first_link_map_addr;
1103 uintptr_t ld_base_addr;
1104 uintptr_t link_map_addr;
1105 uintptr_t lib_base_diff;
1106 uintptr_t lib_base;
1107 uintptr_t lib_name_addr;
1108 char lib_name[BUF_SIZE];
1109 ELF_DYN dyn;
1110 ELF_EHDR elf_ehdr;
1111 int lib_fd;
1112
1113 // _DYNAMIC has information of the form
1114 // [tag] [data] [tag] [data] .....
1115 // Both tag and data are pointer sized.
1116 // We look for dynamic info with DT_DEBUG. This has shared object info.
1117 // refer to struct r_debug in link.h
1118
1119 dyn.d_tag = DT_NULL;
1120 while (dyn.d_tag != DT_DEBUG) {
1121 if (ps_pread(ph, (psaddr_t) addr, &dyn, sizeof(ELF_DYN)) != PS_OK) {
1122 print_debug("can't read debug info from _DYNAMIC\n");
1123 return false;
1124 }
1125 addr += sizeof(ELF_DYN);
1126 }
1127
1128 // we have got Dyn entry with DT_DEBUG
1129 debug_base = dyn.d_un.d_ptr;
1130 // at debug_base we have struct r_debug. This has first link map in r_map field
1131 if (ps_pread(ph, (psaddr_t) debug_base + FIRST_LINK_MAP_OFFSET,
1132 &first_link_map_addr, sizeof(uintptr_t)) != PS_OK) {
1133 print_debug("can't read first link map address\n");
1134 return false;
1135 }
1136
1137 // read ld_base address from struct r_debug
1138 #if 0 // There is no r_ldbase member on BSD
1139 if (ps_pread(ph, (psaddr_t) debug_base + LD_BASE_OFFSET, &ld_base_addr,
1140 sizeof(uintptr_t)) != PS_OK) {
1141 print_debug("can't read ld base address\n");
1142 return false;
1143 }
1144 ph->core->ld_base_addr = ld_base_addr;
1145 #else
1146 ph->core->ld_base_addr = 0;
1147 #endif
1148
1149 print_debug("interpreter base address is 0x%lx\n", ld_base_addr);
1150
1151 // now read segments from interp (i.e ld.so or ld-linux.so or ld-elf.so)
1152 if (read_interp_segments(ph) != true) {
1153 return false;
1154 }
1155
1156 // after adding interpreter (ld.so) mappings sort again
1157 if (sort_map_array(ph) != true) {
1158 return false;
1159 }
1160
1161 print_debug("first link map is at 0x%lx\n", first_link_map_addr);
1162
1163 link_map_addr = first_link_map_addr;
1164 while (link_map_addr != 0) {
1165 // read library base address of the .so. Note that even though <sys/link.h> calls
1166 // link_map->l_addr as "base address", this is * not * really base virtual
1167 // address of the shared object. This is actually the difference b/w the virtual
1168 // address mentioned in shared object and the actual virtual base where runtime
1169 // linker loaded it. We use "base diff" in read_lib_segments call below.
1170
1171 if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_ADDR_OFFSET,
1172 &lib_base_diff, sizeof(uintptr_t)) != PS_OK) {
1173 print_debug("can't read shared object base address diff\n");
1174 return false;
1175 }
1176
1177 // read address of the name
1178 if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_NAME_OFFSET,
1179 &lib_name_addr, sizeof(uintptr_t)) != PS_OK) {
1180 print_debug("can't read address of shared object name\n");
1181 return false;
1182 }
1183
1184 // read name of the shared object
1185 if (read_string(ph, (uintptr_t) lib_name_addr, lib_name, sizeof(lib_name)) != true) {
1186 print_debug("can't read shared object name\n");
1187 return false;
1188 }
1189
1190 if (lib_name[0] != '\0') {
1191 // ignore empty lib names
1192 lib_fd = pathmap_open(lib_name);
1193
1194 if (lib_fd < 0) {
1195 print_debug("can't open shared object %s\n", lib_name);
1196 // continue with other libraries...
1197 } else {
1198 if (read_elf_header(lib_fd, &elf_ehdr)) {
1199 lib_base = lib_base_diff + find_base_address(lib_fd, &elf_ehdr);
1200 print_debug("reading library %s @ 0x%lx [ 0x%lx ]\n",
1201 lib_name, lib_base, lib_base_diff);
1202 // while adding library mappings we need to use "base difference".
1203 if (! read_lib_segments(ph, lib_fd, &elf_ehdr, lib_base_diff)) {
1204 print_debug("can't read shared object's segments\n");
1205 close(lib_fd);
1206 return false;
1207 }
1208 add_lib_info_fd(ph, lib_name, lib_fd, lib_base);
1209 // Map info is added for the library (lib_name) so
1210 // we need to re-sort it before calling the p_pdread.
1211 if (sort_map_array(ph) != true) {
1212 return false;
1213 }
1214 } else {
1215 print_debug("can't read ELF header for shared object %s\n", lib_name);
1216 close(lib_fd);
1217 // continue with other libraries...
1218 }
1219 }
1220 }
1221
1222 // read next link_map address
1223 if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_NEXT_OFFSET,
1224 &link_map_addr, sizeof(uintptr_t)) != PS_OK) {
1225 print_debug("can't read next link in link_map\n");
1226 return false;
1227 }
1228 }
1229
1230 return true;
1231 }
1232
1233 // the one and only one exposed stuff from this file
Pgrab_core(const char * exec_file,const char * core_file)1234 struct ps_prochandle* Pgrab_core(const char* exec_file, const char* core_file) {
1235 ELF_EHDR core_ehdr;
1236 ELF_EHDR exec_ehdr;
1237
1238 struct ps_prochandle* ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle));
1239 if (ph == NULL) {
1240 print_debug("can't allocate ps_prochandle\n");
1241 return NULL;
1242 }
1243
1244 if ((ph->core = (struct core_data*) calloc(1, sizeof(struct core_data))) == NULL) {
1245 free(ph);
1246 print_debug("can't allocate ps_prochandle\n");
1247 return NULL;
1248 }
1249
1250 // initialize ph
1251 ph->ops = &core_ops;
1252 ph->core->core_fd = -1;
1253 ph->core->exec_fd = -1;
1254 ph->core->interp_fd = -1;
1255
1256 print_debug("exec: %s core: %s", exec_file, core_file);
1257
1258 // open the core file
1259 if ((ph->core->core_fd = open(core_file, O_RDONLY)) < 0) {
1260 print_debug("can't open core file\n");
1261 goto err;
1262 }
1263
1264 // read core file ELF header
1265 if (read_elf_header(ph->core->core_fd, &core_ehdr) != true || core_ehdr.e_type != ET_CORE) {
1266 print_debug("core file is not a valid ELF ET_CORE file\n");
1267 goto err;
1268 }
1269
1270 if ((ph->core->exec_fd = open(exec_file, O_RDONLY)) < 0) {
1271 print_debug("can't open executable file\n");
1272 goto err;
1273 }
1274
1275 if (read_elf_header(ph->core->exec_fd, &exec_ehdr) != true || exec_ehdr.e_type != ET_EXEC) {
1276 print_debug("executable file is not a valid ELF ET_EXEC file\n");
1277 goto err;
1278 }
1279
1280 // process core file segments
1281 if (read_core_segments(ph, &core_ehdr) != true) {
1282 goto err;
1283 }
1284
1285 // process exec file segments
1286 if (read_exec_segments(ph, &exec_ehdr) != true) {
1287 goto err;
1288 }
1289
1290 // exec file is also treated like a shared object for symbol search
1291 if (add_lib_info_fd(ph, exec_file, ph->core->exec_fd,
1292 (uintptr_t)0 + find_base_address(ph->core->exec_fd, &exec_ehdr)) == NULL) {
1293 goto err;
1294 }
1295
1296 // allocate and sort maps into map_array, we need to do this
1297 // here because read_shared_lib_info needs to read from debuggee
1298 // address space
1299 if (sort_map_array(ph) != true) {
1300 goto err;
1301 }
1302
1303 if (read_shared_lib_info(ph) != true) {
1304 goto err;
1305 }
1306
1307 // sort again because we have added more mappings from shared objects
1308 if (sort_map_array(ph) != true) {
1309 goto err;
1310 }
1311
1312 if (init_classsharing_workaround(ph) != true) {
1313 goto err;
1314 }
1315
1316 print_debug("Leave Pgrab_core\n");
1317 return ph;
1318
1319 err:
1320 Prelease(ph);
1321 return NULL;
1322 }
1323
1324 #endif // __APPLE__
1325