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