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