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