hotspot/agent/src/os/bsd/ps_core.c
changeset 16351 032b310a3e2f
parent 13728 882756847a04
child 17310 b4118c427cc0
equal deleted inserted replaced
15935:50da9e5eb858 16351:032b310a3e2f
     1 /*
     1 /*
     2  * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    26 #include <unistd.h>
    26 #include <unistd.h>
    27 #include <fcntl.h>
    27 #include <fcntl.h>
    28 #include <string.h>
    28 #include <string.h>
    29 #include <stdlib.h>
    29 #include <stdlib.h>
    30 #include <stddef.h>
    30 #include <stddef.h>
    31 #include <elf.h>
       
    32 #include <link.h>
       
    33 #include "libproc_impl.h"
    31 #include "libproc_impl.h"
    34 #include "salibelf.h"
    32 
       
    33 #ifdef __APPLE__
       
    34 #include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h"
       
    35 #endif
    35 
    36 
    36 // This file has the libproc implementation to read core files.
    37 // This file has the libproc implementation to read core files.
    37 // For live processes, refer to ps_proc.c. Portions of this is adapted
    38 // For live processes, refer to ps_proc.c. Portions of this is adapted
    38 // /modelled after Solaris libproc.so (in particular Pcore.c)
    39 // /modelled after Solaris libproc.so (in particular Pcore.c)
    39 
    40 
    40 //----------------------------------------------------------------------
    41 //----------------------------------------------------------------------
    41 // ps_prochandle cleanup helper functions
    42 // ps_prochandle cleanup helper functions
    42 
    43 
    43 // close all file descriptors
    44 // close all file descriptors
    44 static void close_elf_files(struct ps_prochandle* ph) {
    45 static void close_files(struct ps_prochandle* ph) {
    45    lib_info* lib = NULL;
    46   lib_info* lib = NULL;
    46 
    47   // close core file descriptor
    47    // close core file descriptor
    48   if (ph->core->core_fd >= 0)
    48    if (ph->core->core_fd >= 0)
    49     close(ph->core->core_fd);
    49      close(ph->core->core_fd);
    50 
    50 
    51   // close exec file descriptor
    51    // close exec file descriptor
    52   if (ph->core->exec_fd >= 0)
    52    if (ph->core->exec_fd >= 0)
    53     close(ph->core->exec_fd);
    53      close(ph->core->exec_fd);
    54 
    54 
    55   // close interp file descriptor
    55    // close interp file descriptor
    56   if (ph->core->interp_fd >= 0)
    56    if (ph->core->interp_fd >= 0)
    57     close(ph->core->interp_fd);
    57      close(ph->core->interp_fd);
    58 
    58 
    59   // close class share archive file
    59    // close class share archive file
    60   if (ph->core->classes_jsa_fd >= 0)
    60    if (ph->core->classes_jsa_fd >= 0)
    61     close(ph->core->classes_jsa_fd);
    61      close(ph->core->classes_jsa_fd);
    62 
    62 
    63   // close all library file descriptors
    63    // close all library file descriptors
    64   lib = ph->libs;
    64    lib = ph->libs;
    65   while (lib) {
    65    while (lib) {
    66     int fd = lib->fd;
    66       int fd = lib->fd;
    67     if (fd >= 0 && fd != ph->core->exec_fd) {
    67       if (fd >= 0 && fd != ph->core->exec_fd) close(fd);
    68       close(fd);
    68       lib = lib->next;
    69     }
    69    }
    70     lib = lib->next;
       
    71   }
    70 }
    72 }
    71 
    73 
    72 // clean all map_info stuff
    74 // clean all map_info stuff
    73 static void destroy_map_info(struct ps_prochandle* ph) {
    75 static void destroy_map_info(struct ps_prochandle* ph) {
    74   map_info* map = ph->core->maps;
    76   map_info* map = ph->core->maps;
    75   while (map) {
    77   while (map) {
    76      map_info* next = map->next;
    78     map_info* next = map->next;
    77      free(map);
    79     free(map);
    78      map = next;
    80     map = next;
    79   }
    81   }
    80 
    82 
    81   if (ph->core->map_array) {
    83   if (ph->core->map_array) {
    82      free(ph->core->map_array);
    84     free(ph->core->map_array);
    83   }
    85   }
    84 
    86 
    85   // Part of the class sharing workaround
    87   // Part of the class sharing workaround
    86   map = ph->core->class_share_maps;
    88   map = ph->core->class_share_maps;
    87   while (map) {
    89   while (map) {
    88      map_info* next = map->next;
    90     map_info* next = map->next;
    89      free(map);
    91     free(map);
    90      map = next;
    92     map = next;
    91   }
    93   }
    92 }
    94 }
    93 
    95 
    94 // ps_prochandle operations
    96 // ps_prochandle operations
    95 static void core_release(struct ps_prochandle* ph) {
    97 static void core_release(struct ps_prochandle* ph) {
    96    if (ph->core) {
    98   if (ph->core) {
    97       close_elf_files(ph);
    99     close_files(ph);
    98       destroy_map_info(ph);
   100     destroy_map_info(ph);
    99       free(ph->core);
   101     free(ph->core);
   100    }
   102   }
   101 }
   103 }
   102 
   104 
   103 static map_info* allocate_init_map(int fd, off_t offset, uintptr_t vaddr, size_t memsz) {
   105 static map_info* allocate_init_map(int fd, off_t offset, uintptr_t vaddr, size_t memsz) {
   104    map_info* map;
   106   map_info* map;
   105    if ( (map = (map_info*) calloc(1, sizeof(map_info))) == NULL) {
   107   if ( (map = (map_info*) calloc(1, sizeof(map_info))) == NULL) {
   106       print_debug("can't allocate memory for map_info\n");
   108     print_debug("can't allocate memory for map_info\n");
   107       return NULL;
   109     return NULL;
   108    }
   110   }
   109 
   111 
   110    // initialize map
   112   // initialize map
   111    map->fd     = fd;
   113   map->fd     = fd;
   112    map->offset = offset;
   114   map->offset = offset;
   113    map->vaddr  = vaddr;
   115   map->vaddr  = vaddr;
   114    map->memsz  = memsz;
   116   map->memsz  = memsz;
   115    return map;
   117   return map;
   116 }
   118 }
   117 
   119 
   118 // add map info with given fd, offset, vaddr and memsz
   120 // add map info with given fd, offset, vaddr and memsz
   119 static map_info* add_map_info(struct ps_prochandle* ph, int fd, off_t offset,
   121 static map_info* add_map_info(struct ps_prochandle* ph, int fd, off_t offset,
   120                              uintptr_t vaddr, size_t memsz) {
   122                              uintptr_t vaddr, size_t memsz) {
   121    map_info* map;
   123   map_info* map;
   122    if ((map = allocate_init_map(fd, offset, vaddr, memsz)) == NULL) {
   124   if ((map = allocate_init_map(fd, offset, vaddr, memsz)) == NULL) {
   123       return NULL;
   125     return NULL;
   124    }
   126   }
   125 
   127 
   126    // add this to map list
   128   // add this to map list
   127    map->next  = ph->core->maps;
   129   map->next  = ph->core->maps;
   128    ph->core->maps   = map;
   130   ph->core->maps   = map;
   129    ph->core->num_maps++;
   131   ph->core->num_maps++;
   130 
   132 
   131    return map;
   133   return map;
   132 }
   134 }
   133 
   135 
   134 // Part of the class sharing workaround
   136 // Part of the class sharing workaround
   135 static map_info* add_class_share_map_info(struct ps_prochandle* ph, off_t offset,
   137 static map_info* add_class_share_map_info(struct ps_prochandle* ph, off_t offset,
   136                              uintptr_t vaddr, size_t memsz) {
   138                              uintptr_t vaddr, size_t memsz) {
   137    map_info* map;
   139   map_info* map;
   138    if ((map = allocate_init_map(ph->core->classes_jsa_fd,
   140   if ((map = allocate_init_map(ph->core->classes_jsa_fd,
   139                                 offset, vaddr, memsz)) == NULL) {
   141                                offset, vaddr, memsz)) == NULL) {
   140       return NULL;
   142     return NULL;
   141    }
   143   }
   142 
   144 
   143    map->next = ph->core->class_share_maps;
   145   map->next = ph->core->class_share_maps;
   144    ph->core->class_share_maps = map;
   146   ph->core->class_share_maps = map;
   145    return map;
   147   return map;
   146 }
   148 }
   147 
   149 
   148 // Return the map_info for the given virtual address.  We keep a sorted
   150 // Return the map_info for the given virtual address.  We keep a sorted
   149 // array of pointers in ph->map_array, so we can binary search.
   151 // array of pointers in ph->map_array, so we can binary search.
   150 static map_info* core_lookup(struct ps_prochandle *ph, uintptr_t addr)
   152 static map_info* core_lookup(struct ps_prochandle *ph, uintptr_t addr)
   151 {
   153 {
   152    int mid, lo = 0, hi = ph->core->num_maps - 1;
   154   int mid, lo = 0, hi = ph->core->num_maps - 1;
   153    map_info *mp;
   155   map_info *mp;
   154 
   156 
   155    while (hi - lo > 1) {
   157   while (hi - lo > 1) {
   156      mid = (lo + hi) / 2;
   158     mid = (lo + hi) / 2;
   157       if (addr >= ph->core->map_array[mid]->vaddr)
   159     if (addr >= ph->core->map_array[mid]->vaddr) {
   158          lo = mid;
   160       lo = mid;
   159       else
   161     } else {
   160          hi = mid;
   162       hi = mid;
   161    }
   163     }
   162 
   164   }
   163    if (addr < ph->core->map_array[hi]->vaddr)
   165 
   164       mp = ph->core->map_array[lo];
   166   if (addr < ph->core->map_array[hi]->vaddr) {
   165    else
   167     mp = ph->core->map_array[lo];
   166       mp = ph->core->map_array[hi];
   168   } else {
   167 
   169     mp = ph->core->map_array[hi];
   168    if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz)
   170   }
       
   171 
       
   172   if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
       
   173     return (mp);
       
   174   }
       
   175 
       
   176 
       
   177   // Part of the class sharing workaround
       
   178   // Unfortunately, we have no way of detecting -Xshare state.
       
   179   // Check out the share maps atlast, if we don't find anywhere.
       
   180   // This is done this way so to avoid reading share pages
       
   181   // ahead of other normal maps. For eg. with -Xshare:off we don't
       
   182   // want to prefer class sharing data to data from core.
       
   183   mp = ph->core->class_share_maps;
       
   184   if (mp) {
       
   185     print_debug("can't locate map_info at 0x%lx, trying class share maps\n", addr);
       
   186   }
       
   187   while (mp) {
       
   188     if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
       
   189       print_debug("located map_info at 0x%lx from class share maps\n", addr);
   169       return (mp);
   190       return (mp);
   170 
   191     }
   171 
   192     mp = mp->next;
   172    // Part of the class sharing workaround
   193   }
   173    // Unfortunately, we have no way of detecting -Xshare state.
   194 
   174    // Check out the share maps atlast, if we don't find anywhere.
   195   print_debug("can't locate map_info at 0x%lx\n", addr);
   175    // This is done this way so to avoid reading share pages
   196   return (NULL);
   176    // ahead of other normal maps. For eg. with -Xshare:off we don't
       
   177    // want to prefer class sharing data to data from core.
       
   178    mp = ph->core->class_share_maps;
       
   179    if (mp) {
       
   180       print_debug("can't locate map_info at 0x%lx, trying class share maps\n",
       
   181              addr);
       
   182    }
       
   183    while (mp) {
       
   184       if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
       
   185          print_debug("located map_info at 0x%lx from class share maps\n",
       
   186                   addr);
       
   187          return (mp);
       
   188       }
       
   189       mp = mp->next;
       
   190    }
       
   191 
       
   192    print_debug("can't locate map_info at 0x%lx\n", addr);
       
   193    return (NULL);
       
   194 }
   197 }
   195 
   198 
   196 //---------------------------------------------------------------
   199 //---------------------------------------------------------------
   197 // Part of the class sharing workaround:
   200 // Part of the class sharing workaround:
   198 //
   201 //
   237 
   240 
   238   // Ignore the rest of the FileMapHeader. We don't need those fields here.
   241   // Ignore the rest of the FileMapHeader. We don't need those fields here.
   239 };
   242 };
   240 
   243 
   241 static bool read_jboolean(struct ps_prochandle* ph, uintptr_t addr, jboolean* pvalue) {
   244 static bool read_jboolean(struct ps_prochandle* ph, uintptr_t addr, jboolean* pvalue) {
   242    jboolean i;
   245   jboolean i;
   243    if (ps_pread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) {
   246   if (ps_pread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) {
   244       *pvalue = i;
   247     *pvalue = i;
   245       return true;
   248     return true;
   246    } else {
   249   } else {
   247       return false;
   250     return false;
   248    }
   251   }
   249 }
   252 }
   250 
   253 
   251 static bool read_pointer(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* pvalue) {
   254 static bool read_pointer(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* pvalue) {
   252    uintptr_t uip;
   255   uintptr_t uip;
   253    if (ps_pread(ph, (psaddr_t) addr, &uip, sizeof(uip)) == PS_OK) {
   256   if (ps_pread(ph, (psaddr_t) addr, (char *)&uip, sizeof(uip)) == PS_OK) {
   254       *pvalue = uip;
   257     *pvalue = uip;
   255       return true;
   258     return true;
   256    } else {
   259   } else {
   257       return false;
   260     return false;
   258    }
   261   }
   259 }
   262 }
   260 
   263 
   261 // used to read strings from debuggee
   264 // used to read strings from debuggee
   262 static bool read_string(struct ps_prochandle* ph, uintptr_t addr, char* buf, size_t size) {
   265 static bool read_string(struct ps_prochandle* ph, uintptr_t addr, char* buf, size_t size) {
   263    size_t i = 0;
   266   size_t i = 0;
   264    char  c = ' ';
   267   char  c = ' ';
   265 
   268 
   266    while (c != '\0') {
   269   while (c != '\0') {
   267      if (ps_pread(ph, (psaddr_t) addr, &c, sizeof(char)) != PS_OK)
   270     if (ps_pread(ph, (psaddr_t) addr, &c, sizeof(char)) != PS_OK) {
   268          return false;
   271       return false;
   269       if (i < size - 1)
   272     }
   270          buf[i] = c;
   273     if (i < size - 1) {
   271       else // smaller buffer
   274       buf[i] = c;
   272          return false;
   275     } else {
   273       i++; addr++;
   276       // smaller buffer
   274    }
   277       return false;
   275 
   278     }
   276    buf[i] = '\0';
   279     i++; addr++;
   277    return true;
   280   }
   278 }
   281   buf[i] = '\0';
   279 
   282   return true;
       
   283 }
       
   284 
       
   285 #ifdef __APPLE__
       
   286 #define USE_SHARED_SPACES_SYM "_UseSharedSpaces"
       
   287 // mangled name of Arguments::SharedArchivePath
       
   288 #define SHARED_ARCHIVE_PATH_SYM "_ZN9Arguments17SharedArchivePathE"
       
   289 #else
   280 #define USE_SHARED_SPACES_SYM "UseSharedSpaces"
   290 #define USE_SHARED_SPACES_SYM "UseSharedSpaces"
   281 // mangled name of Arguments::SharedArchivePath
   291 // mangled name of Arguments::SharedArchivePath
   282 #define SHARED_ARCHIVE_PATH_SYM "_ZN9Arguments17SharedArchivePathE"
   292 #define SHARED_ARCHIVE_PATH_SYM "__ZN9Arguments17SharedArchivePathE"
       
   293 #endif // __APPLE_
   283 
   294 
   284 static bool init_classsharing_workaround(struct ps_prochandle* ph) {
   295 static bool init_classsharing_workaround(struct ps_prochandle* ph) {
   285    lib_info* lib = ph->libs;
   296   int m;
   286    while (lib != NULL) {
   297   size_t n;
   287       // we are iterating over shared objects from the core dump. look for
   298   lib_info* lib = ph->libs;
   288       // libjvm[_g].so.
   299   while (lib != NULL) {
   289       const char *jvm_name = 0;
   300     // we are iterating over shared objects from the core dump. look for
   290       if ((jvm_name = strstr(lib->name, "/libjvm.so")) != 0 ||
   301     // libjvm[_g].so.
   291           (jvm_name = strstr(lib->name, "/libjvm_g.so")) != 0) {
   302     const char *jvm_name = 0;
   292          char classes_jsa[PATH_MAX];
   303 #ifdef __APPLE__
   293          struct FileMapHeader header;
   304     if ((jvm_name = strstr(lib->name, "/libjvm.dylib")) != 0 ||
   294          size_t n = 0;
   305         (jvm_name = strstr(lib->name, "/libjvm_g.dylib")) != 0)
   295          int fd = -1, m = 0;
   306 #else
   296          uintptr_t base = 0, useSharedSpacesAddr = 0;
   307     if ((jvm_name = strstr(lib->name, "/libjvm.so")) != 0 ||
   297          uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
   308         (jvm_name = strstr(lib->name, "/libjvm_g.so")) != 0)
   298          jboolean useSharedSpaces = 0;
   309 #endif // __APPLE__
   299 
   310     {
   300          memset(classes_jsa, 0, sizeof(classes_jsa));
   311       char classes_jsa[PATH_MAX];
   301          jvm_name = lib->name;
   312       struct FileMapHeader header;
   302          useSharedSpacesAddr = lookup_symbol(ph, jvm_name, USE_SHARED_SPACES_SYM);
   313       int fd = -1;
   303          if (useSharedSpacesAddr == 0) {
   314       uintptr_t base = 0, useSharedSpacesAddr = 0;
   304             print_debug("can't lookup 'UseSharedSpaces' flag\n");
   315       uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
   305             return false;
   316       jboolean useSharedSpaces = 0;
   306          }
   317 
   307 
   318       memset(classes_jsa, 0, sizeof(classes_jsa));
   308          // Hotspot vm types are not exported to build this library. So
   319       jvm_name = lib->name;
   309          // using equivalent type jboolean to read the value of
   320       useSharedSpacesAddr = lookup_symbol(ph, jvm_name, USE_SHARED_SPACES_SYM);
   310          // UseSharedSpaces which is same as hotspot type "bool".
   321       if (useSharedSpacesAddr == 0) {
   311          if (read_jboolean(ph, useSharedSpacesAddr, &useSharedSpaces) != true) {
   322         print_debug("can't lookup 'UseSharedSpaces' flag\n");
   312             print_debug("can't read the value of 'UseSharedSpaces' flag\n");
   323         return false;
   313             return false;
   324       }
   314          }
   325 
   315 
   326       // Hotspot vm types are not exported to build this library. So
   316          if ((int)useSharedSpaces == 0) {
   327       // using equivalent type jboolean to read the value of
   317             print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n");
   328       // UseSharedSpaces which is same as hotspot type "bool".
   318             return true;
   329       if (read_jboolean(ph, useSharedSpacesAddr, &useSharedSpaces) != true) {
   319          }
   330         print_debug("can't read the value of 'UseSharedSpaces' flag\n");
   320 
   331         return false;
   321          sharedArchivePathAddrAddr = lookup_symbol(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM);
   332       }
   322          if (sharedArchivePathAddrAddr == 0) {
   333 
   323             print_debug("can't lookup shared archive path symbol\n");
   334       if ((int)useSharedSpaces == 0) {
   324             return false;
   335         print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n");
   325          }
   336         return true;
   326 
   337       }
   327          if (read_pointer(ph, sharedArchivePathAddrAddr, &sharedArchivePathAddr) != true) {
   338 
   328             print_debug("can't read shared archive path pointer\n");
   339       sharedArchivePathAddrAddr = lookup_symbol(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM);
   329             return false;
   340       if (sharedArchivePathAddrAddr == 0) {
   330          }
   341         print_debug("can't lookup shared archive path symbol\n");
   331 
   342         return false;
   332          if (read_string(ph, sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
   343       }
   333             print_debug("can't read shared archive path value\n");
   344 
   334             return false;
   345       if (read_pointer(ph, sharedArchivePathAddrAddr, &sharedArchivePathAddr) != true) {
   335          }
   346         print_debug("can't read shared archive path pointer\n");
   336 
   347         return false;
   337          print_debug("looking for %s\n", classes_jsa);
   348       }
   338          // open the class sharing archive file
   349 
   339          fd = pathmap_open(classes_jsa);
   350       if (read_string(ph, sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
   340          if (fd < 0) {
   351         print_debug("can't read shared archive path value\n");
   341             print_debug("can't open %s!\n", classes_jsa);
   352         return false;
   342             ph->core->classes_jsa_fd = -1;
   353       }
   343             return false;
   354 
   344          } else {
   355       print_debug("looking for %s\n", classes_jsa);
   345             print_debug("opened %s\n", classes_jsa);
   356       // open the class sharing archive file
   346          }
   357       fd = pathmap_open(classes_jsa);
   347 
   358       if (fd < 0) {
   348          // read FileMapHeader from the file
   359         print_debug("can't open %s!\n", classes_jsa);
   349          memset(&header, 0, sizeof(struct FileMapHeader));
   360         ph->core->classes_jsa_fd = -1;
   350          if ((n = read(fd, &header, sizeof(struct FileMapHeader)))
   361         return false;
   351               != sizeof(struct FileMapHeader)) {
   362       } else {
   352             print_debug("can't read shared archive file map header from %s\n", classes_jsa);
   363         print_debug("opened %s\n", classes_jsa);
   353             close(fd);
   364       }
   354             return false;
   365 
   355          }
   366       // read FileMapHeader from the file
   356 
   367       memset(&header, 0, sizeof(struct FileMapHeader));
   357          // check file magic
   368       if ((n = read(fd, &header, sizeof(struct FileMapHeader)))
   358          if (header._magic != 0xf00baba2) {
   369            != sizeof(struct FileMapHeader)) {
   359             print_debug("%s has bad shared archive file magic number 0x%x, expecing 0xf00baba2\n",
   370         print_debug("can't read shared archive file map header from %s\n", classes_jsa);
   360                         classes_jsa, header._magic);
   371         close(fd);
   361             close(fd);
   372         return false;
   362             return false;
   373       }
   363          }
   374 
   364 
   375       // check file magic
   365          // check version
   376       if (header._magic != 0xf00baba2) {
   366          if (header._version != CURRENT_ARCHIVE_VERSION) {
   377         print_debug("%s has bad shared archive file magic number 0x%x, expecing 0xf00baba2\n",
   367             print_debug("%s has wrong shared archive file version %d, expecting %d\n",
   378                      classes_jsa, header._magic);
   368                         classes_jsa, header._version, CURRENT_ARCHIVE_VERSION);
   379         close(fd);
   369             close(fd);
   380         return false;
   370             return false;
   381       }
   371          }
   382 
   372 
   383       // check version
   373          ph->core->classes_jsa_fd = fd;
   384       if (header._version != CURRENT_ARCHIVE_VERSION) {
   374          // add read-only maps from classes[_g].jsa to the list of maps
   385         print_debug("%s has wrong shared archive file version %d, expecting %d\n",
   375          for (m = 0; m < NUM_SHARED_MAPS; m++) {
   386                      classes_jsa, header._version, CURRENT_ARCHIVE_VERSION);
   376             if (header._space[m]._read_only) {
   387         close(fd);
   377                base = (uintptr_t) header._space[m]._base;
   388         return false;
   378                // no need to worry about the fractional pages at-the-end.
   389       }
   379                // possible fractional pages are handled by core_read_data.
   390 
   380                add_class_share_map_info(ph, (off_t) header._space[m]._file_offset,
   391       ph->core->classes_jsa_fd = fd;
   381                          base, (size_t) header._space[m]._used);
   392       // add read-only maps from classes[_g].jsa to the list of maps
   382                print_debug("added a share archive map at 0x%lx\n", base);
   393       for (m = 0; m < NUM_SHARED_MAPS; m++) {
   383             }
   394         if (header._space[m]._read_only) {
   384          }
   395           base = (uintptr_t) header._space[m]._base;
   385          return true;
   396           // no need to worry about the fractional pages at-the-end.
   386       }
   397           // possible fractional pages are handled by core_read_data.
   387       lib = lib->next;
   398           add_class_share_map_info(ph, (off_t) header._space[m]._file_offset,
   388    }
   399                                    base, (size_t) header._space[m]._used);
   389    return true;
   400           print_debug("added a share archive map at 0x%lx\n", base);
   390 }
   401         }
   391 
   402       }
       
   403       return true;
       
   404     }
       
   405     lib = lib->next;
       
   406   }
       
   407   return true;
       
   408 }
   392 
   409 
   393 //---------------------------------------------------------------------------
   410 //---------------------------------------------------------------------------
   394 // functions to handle map_info
   411 // functions to handle map_info
   395 
   412 
   396 // Order mappings based on virtual address.  We use this function as the
   413 // Order mappings based on virtual address.  We use this function as the
   397 // callback for sorting the array of map_info pointers.
   414 // callback for sorting the array of map_info pointers.
   398 static int core_cmp_mapping(const void *lhsp, const void *rhsp)
   415 static int core_cmp_mapping(const void *lhsp, const void *rhsp)
   399 {
   416 {
   400    const map_info *lhs = *((const map_info **)lhsp);
   417   const map_info *lhs = *((const map_info **)lhsp);
   401    const map_info *rhs = *((const map_info **)rhsp);
   418   const map_info *rhs = *((const map_info **)rhsp);
   402 
   419 
   403    if (lhs->vaddr == rhs->vaddr)
   420   if (lhs->vaddr == rhs->vaddr) {
   404       return (0);
   421     return (0);
   405 
   422   }
   406    return (lhs->vaddr < rhs->vaddr ? -1 : 1);
   423 
       
   424   return (lhs->vaddr < rhs->vaddr ? -1 : 1);
   407 }
   425 }
   408 
   426 
   409 // we sort map_info by starting virtual address so that we can do
   427 // we sort map_info by starting virtual address so that we can do
   410 // binary search to read from an address.
   428 // binary search to read from an address.
   411 static bool sort_map_array(struct ps_prochandle* ph) {
   429 static bool sort_map_array(struct ps_prochandle* ph) {
   412    size_t num_maps = ph->core->num_maps;
   430   size_t num_maps = ph->core->num_maps;
   413    map_info* map = ph->core->maps;
   431   map_info* map = ph->core->maps;
   414    int i = 0;
   432   int i = 0;
   415 
   433 
   416    // allocate map_array
   434   // allocate map_array
   417    map_info** array;
   435   map_info** array;
   418    if ( (array = (map_info**) malloc(sizeof(map_info*) * num_maps)) == NULL) {
   436   if ( (array = (map_info**) malloc(sizeof(map_info*) * num_maps)) == NULL) {
   419       print_debug("can't allocate memory for map array\n");
   437      print_debug("can't allocate memory for map array\n");
   420       return false;
   438      return false;
   421    }
   439   }
   422 
   440 
   423    // add maps to array
   441   // add maps to array
   424    while (map) {
   442   while (map) {
   425       array[i] = map;
   443     array[i] = map;
   426       i++;
   444     i++;
   427       map = map->next;
   445     map = map->next;
   428    }
   446   }
   429 
   447 
   430    // sort is called twice. If this is second time, clear map array
   448   // sort is called twice. If this is second time, clear map array
   431    if (ph->core->map_array) free(ph->core->map_array);
   449   if (ph->core->map_array) {
   432    ph->core->map_array = array;
   450     free(ph->core->map_array);
   433    // sort the map_info array by base virtual address.
   451   }
   434    qsort(ph->core->map_array, ph->core->num_maps, sizeof (map_info*),
   452   ph->core->map_array = array;
   435             core_cmp_mapping);
   453   // sort the map_info array by base virtual address.
   436 
   454   qsort(ph->core->map_array, ph->core->num_maps, sizeof (map_info*),
   437    // print map
   455            core_cmp_mapping);
   438    if (is_debug()) {
   456 
   439       int j = 0;
   457   // print map
   440       print_debug("---- sorted virtual address map ----\n");
   458   if (is_debug()) {
   441       for (j = 0; j < ph->core->num_maps; j++) {
   459     int j = 0;
   442         print_debug("base = 0x%lx\tsize = %d\n", ph->core->map_array[j]->vaddr,
   460     print_debug("---- sorted virtual address map ----\n");
   443                                          ph->core->map_array[j]->memsz);
   461     for (j = 0; j < ph->core->num_maps; j++) {
   444       }
   462       print_debug("base = 0x%lx\tsize = %d\n", ph->core->map_array[j]->vaddr,
   445    }
   463                                        ph->core->map_array[j]->memsz);
   446 
   464     }
   447    return true;
   465   }
       
   466 
       
   467   return true;
   448 }
   468 }
   449 
   469 
   450 #ifndef MIN
   470 #ifndef MIN
   451 #define MIN(x, y) (((x) < (y))? (x): (y))
   471 #define MIN(x, y) (((x) < (y))? (x): (y))
   452 #endif
   472 #endif
   459       uintptr_t mapoff;
   479       uintptr_t mapoff;
   460       ssize_t len, rem;
   480       ssize_t len, rem;
   461       off_t off;
   481       off_t off;
   462       int fd;
   482       int fd;
   463 
   483 
   464       if (mp == NULL)
   484       if (mp == NULL) {
   465          break;  /* No mapping for this address */
   485          break;  /* No mapping for this address */
       
   486       }
   466 
   487 
   467       fd = mp->fd;
   488       fd = mp->fd;
   468       mapoff = addr - mp->vaddr;
   489       mapoff = addr - mp->vaddr;
   469       len = MIN(resid, mp->memsz - mapoff);
   490       len = MIN(resid, mp->memsz - mapoff);
   470       off = mp->offset + mapoff;
   491       off = mp->offset + mapoff;
   471 
   492 
   472       if ((len = pread(fd, buf, len, off)) <= 0)
   493       if ((len = pread(fd, buf, len, off)) <= 0) {
   473          break;
   494          break;
       
   495       }
   474 
   496 
   475       resid -= len;
   497       resid -= len;
   476       addr += len;
   498       addr += len;
   477       buf = (char *)buf + len;
   499       buf = (char *)buf + len;
   478 
   500 
   505    return false;
   527    return false;
   506 }
   528 }
   507 
   529 
   508 static bool core_get_lwp_regs(struct ps_prochandle* ph, lwpid_t lwp_id,
   530 static bool core_get_lwp_regs(struct ps_prochandle* ph, lwpid_t lwp_id,
   509                           struct reg* regs) {
   531                           struct reg* regs) {
   510    // for core we have cached the lwp regs from NOTE section
   532    // for core we have cached the lwp regs after segment parsed
   511    thread_info* thr = ph->threads;
   533    sa_thread_info* thr = ph->threads;
   512    while (thr) {
   534    while (thr) {
   513      if (thr->lwp_id == lwp_id) {
   535      if (thr->lwp_id == lwp_id) {
   514        memcpy(regs, &thr->regs, sizeof(struct reg));
   536        memcpy(regs, &thr->regs, sizeof(struct reg));
   515        return true;
   537        return true;
   516      }
   538      }
   517      thr = thr->next;
   539      thr = thr->next;
   518    }
   540    }
   519    return false;
   541    return false;
   520 }
   542 }
   521 
   543 
   522 static bool core_get_lwp_info(struct ps_prochandle *ph, lwpid_t lwp_id, void *linfo) {
   544 static bool core_get_lwp_info(struct ps_prochandle *ph, lwpid_t id, void *info) {
   523    print_debug("core_get_lwp_info not implemented\n");
   545    print_debug("core_get_lwp_info not implemented\n");
   524    return false;
   546    return false;
   525 }
   547 }
   526 
   548 
   527 static ps_prochandle_ops core_ops = {
   549 static ps_prochandle_ops core_ops = {
   530    .p_pwrite= core_write_data,
   552    .p_pwrite= core_write_data,
   531    .get_lwp_regs= core_get_lwp_regs,
   553    .get_lwp_regs= core_get_lwp_regs,
   532    .get_lwp_info= core_get_lwp_info
   554    .get_lwp_info= core_get_lwp_info
   533 };
   555 };
   534 
   556 
   535 // read regs and create thread from NT_PRSTATUS entries from core file
   557 // from this point, mainly two blocks divided by def __APPLE__
       
   558 // one for Macosx, the other for regular Bsd
       
   559 
       
   560 #ifdef __APPLE__
       
   561 
       
   562 void print_thread(sa_thread_info *threadinfo) {
       
   563   print_debug("thread added: %d\n", threadinfo->lwp_id);
       
   564   print_debug("registers:\n");
       
   565   print_debug("  r_r15: 0x%" PRIx64 "\n", threadinfo->regs.r_r15);
       
   566   print_debug("  r_r14: 0x%" PRIx64 "\n", threadinfo->regs.r_r14);
       
   567   print_debug("  r_r13: 0x%" PRIx64 "\n", threadinfo->regs.r_r13);
       
   568   print_debug("  r_r12: 0x%" PRIx64 "\n", threadinfo->regs.r_r12);
       
   569   print_debug("  r_r11: 0x%" PRIx64 "\n", threadinfo->regs.r_r11);
       
   570   print_debug("  r_r10: 0x%" PRIx64 "\n", threadinfo->regs.r_r10);
       
   571   print_debug("  r_r9:  0x%" PRIx64 "\n", threadinfo->regs.r_r9);
       
   572   print_debug("  r_r8:  0x%" PRIx64 "\n", threadinfo->regs.r_r8);
       
   573   print_debug("  r_rdi: 0x%" PRIx64 "\n", threadinfo->regs.r_rdi);
       
   574   print_debug("  r_rsi: 0x%" PRIx64 "\n", threadinfo->regs.r_rsi);
       
   575   print_debug("  r_rbp: 0x%" PRIx64 "\n", threadinfo->regs.r_rbp);
       
   576   print_debug("  r_rbx: 0x%" PRIx64 "\n", threadinfo->regs.r_rbx);
       
   577   print_debug("  r_rdx: 0x%" PRIx64 "\n", threadinfo->regs.r_rdx);
       
   578   print_debug("  r_rcx: 0x%" PRIx64 "\n", threadinfo->regs.r_rcx);
       
   579   print_debug("  r_rax: 0x%" PRIx64 "\n", threadinfo->regs.r_rax);
       
   580   print_debug("  r_fs:  0x%" PRIx32 "\n", threadinfo->regs.r_fs);
       
   581   print_debug("  r_gs:  0x%" PRIx32 "\n", threadinfo->regs.r_gs);
       
   582   print_debug("  r_rip  0x%" PRIx64 "\n", threadinfo->regs.r_rip);
       
   583   print_debug("  r_cs:  0x%" PRIx64 "\n", threadinfo->regs.r_cs);
       
   584   print_debug("  r_rsp: 0x%" PRIx64 "\n", threadinfo->regs.r_rsp);
       
   585   print_debug("  r_rflags: 0x%" PRIx64 "\n", threadinfo->regs.r_rflags);
       
   586 }
       
   587 
       
   588 // read all segments64 commands from core file
       
   589 // read all thread commands from core file
       
   590 static bool read_core_segments(struct ps_prochandle* ph) {
       
   591   int i = 0;
       
   592   int num_threads = 0;
       
   593   int fd = ph->core->core_fd;
       
   594   off_t offset = 0;
       
   595   mach_header_64      fhead;
       
   596   load_command        lcmd;
       
   597   segment_command_64  segcmd;
       
   598   // thread_command      thrcmd;
       
   599 
       
   600   lseek(fd, offset, SEEK_SET);
       
   601   if(read(fd, (void *)&fhead, sizeof(mach_header_64)) != sizeof(mach_header_64)) {
       
   602      goto err;
       
   603   }
       
   604   print_debug("total commands: %d\n", fhead.ncmds);
       
   605   offset += sizeof(mach_header_64);
       
   606   for (i = 0; i < fhead.ncmds; i++) {
       
   607     lseek(fd, offset, SEEK_SET);
       
   608     if (read(fd, (void *)&lcmd, sizeof(load_command)) != sizeof(load_command)) {
       
   609       goto err;
       
   610     }
       
   611     offset += lcmd.cmdsize;    // next command position
       
   612     if (lcmd.cmd == LC_SEGMENT_64) {
       
   613       lseek(fd, -sizeof(load_command), SEEK_CUR);
       
   614       if (read(fd, (void *)&segcmd, sizeof(segment_command_64)) != sizeof(segment_command_64)) {
       
   615         print_debug("failed to read LC_SEGMENT_64 i = %d!\n", i);
       
   616         goto err;
       
   617       }
       
   618       if (add_map_info(ph, fd, segcmd.fileoff, segcmd.vmaddr, segcmd.vmsize) == NULL) {
       
   619         print_debug("Failed to add map_info at i = %d\n", i);
       
   620         goto err;
       
   621       }
       
   622       print_debug("segment added: %" PRIu64 " 0x%" PRIx64 " %d\n",
       
   623                    segcmd.fileoff, segcmd.vmaddr, segcmd.vmsize);
       
   624     } else if (lcmd.cmd == LC_THREAD || lcmd.cmd == LC_UNIXTHREAD) {
       
   625       typedef struct thread_fc {
       
   626         uint32_t  flavor;
       
   627         uint32_t  count;
       
   628       } thread_fc;
       
   629       thread_fc fc;
       
   630       uint32_t size = sizeof(load_command);
       
   631       while (size < lcmd.cmdsize) {
       
   632         if (read(fd, (void *)&fc, sizeof(thread_fc)) != sizeof(thread_fc)) {
       
   633           printf("Reading flavor, count failed.\n");
       
   634           goto err;
       
   635         }
       
   636         size += sizeof(thread_fc);
       
   637         if (fc.flavor == x86_THREAD_STATE) {
       
   638           x86_thread_state_t thrstate;
       
   639           if (read(fd, (void *)&thrstate, sizeof(x86_thread_state_t)) != sizeof(x86_thread_state_t)) {
       
   640             printf("Reading flavor, count failed.\n");
       
   641             goto err;
       
   642           }
       
   643           size += sizeof(x86_thread_state_t);
       
   644           // create thread info list, update lwp_id later
       
   645           sa_thread_info* newthr = add_thread_info(ph, (pthread_t) -1, (lwpid_t) num_threads++);
       
   646           if (newthr == NULL) {
       
   647             printf("create thread_info failed\n");
       
   648             goto err;
       
   649           }
       
   650 
       
   651           // note __DARWIN_UNIX03 depengs on other definitions
       
   652 #if __DARWIN_UNIX03
       
   653 #define get_register_v(regst, regname) \
       
   654   regst.uts.ts64.__##regname
       
   655 #else
       
   656 #define get_register_v(regst, regname) \
       
   657   regst.uts.ts64.##regname
       
   658 #endif // __DARWIN_UNIX03
       
   659           newthr->regs.r_rax = get_register_v(thrstate, rax);
       
   660           newthr->regs.r_rbx = get_register_v(thrstate, rbx);
       
   661           newthr->regs.r_rcx = get_register_v(thrstate, rcx);
       
   662           newthr->regs.r_rdx = get_register_v(thrstate, rdx);
       
   663           newthr->regs.r_rdi = get_register_v(thrstate, rdi);
       
   664           newthr->regs.r_rsi = get_register_v(thrstate, rsi);
       
   665           newthr->regs.r_rbp = get_register_v(thrstate, rbp);
       
   666           newthr->regs.r_rsp = get_register_v(thrstate, rsp);
       
   667           newthr->regs.r_r8  = get_register_v(thrstate, r8);
       
   668           newthr->regs.r_r9  = get_register_v(thrstate, r9);
       
   669           newthr->regs.r_r10 = get_register_v(thrstate, r10);
       
   670           newthr->regs.r_r11 = get_register_v(thrstate, r11);
       
   671           newthr->regs.r_r12 = get_register_v(thrstate, r12);
       
   672           newthr->regs.r_r13 = get_register_v(thrstate, r13);
       
   673           newthr->regs.r_r14 = get_register_v(thrstate, r14);
       
   674           newthr->regs.r_r15 = get_register_v(thrstate, r15);
       
   675           newthr->regs.r_rip = get_register_v(thrstate, rip);
       
   676           newthr->regs.r_rflags = get_register_v(thrstate, rflags);
       
   677           newthr->regs.r_cs  = get_register_v(thrstate, cs);
       
   678           newthr->regs.r_fs  = get_register_v(thrstate, fs);
       
   679           newthr->regs.r_gs  = get_register_v(thrstate, gs);
       
   680           print_thread(newthr);
       
   681         } else if (fc.flavor == x86_FLOAT_STATE) {
       
   682           x86_float_state_t flstate;
       
   683           if (read(fd, (void *)&flstate, sizeof(x86_float_state_t)) != sizeof(x86_float_state_t)) {
       
   684             print_debug("Reading flavor, count failed.\n");
       
   685             goto err;
       
   686           }
       
   687           size += sizeof(x86_float_state_t);
       
   688         } else if (fc.flavor == x86_EXCEPTION_STATE) {
       
   689           x86_exception_state_t excpstate;
       
   690           if (read(fd, (void *)&excpstate, sizeof(x86_exception_state_t)) != sizeof(x86_exception_state_t)) {
       
   691             printf("Reading flavor, count failed.\n");
       
   692             goto err;
       
   693           }
       
   694           size += sizeof(x86_exception_state_t);
       
   695         }
       
   696       }
       
   697     }
       
   698   }
       
   699   return true;
       
   700 err:
       
   701   return false;
       
   702 }
       
   703 
       
   704 /**local function **/
       
   705 bool exists(const char *fname)
       
   706 {
       
   707   int fd;
       
   708   if ((fd = open(fname, O_RDONLY)) > 0) {
       
   709     close(fd);
       
   710     return true;
       
   711   }
       
   712   return false;
       
   713 }
       
   714 
       
   715 // we check: 1. lib
       
   716 //           2. lib/server
       
   717 //           3. jre/lib
       
   718 //           4. jre/lib/server
       
   719 // from: 1. exe path
       
   720 //       2. JAVA_HOME
       
   721 //       3. DYLD_LIBRARY_PATH
       
   722 static bool get_real_path(struct ps_prochandle* ph, char *rpath) {
       
   723   /** check if they exist in JAVA ***/
       
   724   char* execname = ph->core->exec_path;
       
   725   char  filepath[4096];
       
   726   char* filename = strrchr(rpath, '/');               // like /libjvm.dylib
       
   727   if (filename == NULL) {
       
   728     return false;
       
   729   }
       
   730 
       
   731   char* posbin = strstr(execname, "/bin/java");
       
   732   if (posbin != NULL) {
       
   733     memcpy(filepath, execname, posbin - execname);    // not include trailing '/'
       
   734     filepath[posbin - execname] = '\0';
       
   735   } else {
       
   736     char* java_home = getenv("JAVA_HOME");
       
   737     if (java_home != NULL) {
       
   738       strcpy(filepath, java_home);
       
   739     } else {
       
   740       char* dyldpath = getenv("DYLD_LIBRARY_PATH");
       
   741       char* dypath = strtok(dyldpath, ":");
       
   742       while (dypath != NULL) {
       
   743         strcpy(filepath, dypath);
       
   744         strcat(filepath, filename);
       
   745         if (exists(filepath)) {
       
   746            strcpy(rpath, filepath);
       
   747            return true;
       
   748         }
       
   749         dypath = strtok(dyldpath, ":");
       
   750       }
       
   751       // not found
       
   752       return false;
       
   753     }
       
   754   }
       
   755   // for exec and java_home, jdkpath now is filepath
       
   756   size_t filepath_base_size = strlen(filepath);
       
   757 
       
   758   // first try /lib/ and /lib/server
       
   759   strcat(filepath, "/lib");
       
   760   strcat(filepath, filename);
       
   761   if (exists(filepath)) {
       
   762     strcpy(rpath, filepath);
       
   763     return true;
       
   764   }
       
   765   char* pos = strstr(filepath, filename);    // like /libjvm.dylib
       
   766   *pos = '\0';
       
   767   strcat(filepath, "/server");
       
   768   strcat(filepath, filename);
       
   769   if (exists(filepath)) {
       
   770     strcpy(rpath, filepath);
       
   771     return true;
       
   772   }
       
   773 
       
   774   // then try /jre/lib/ and /jre/lib/server
       
   775   filepath[filepath_base_size] = '\0';
       
   776   strcat(filepath, "/jre/lib");
       
   777   strcat(filepath, filename);
       
   778   if (exists(filepath)) {
       
   779     strcpy(rpath, filepath);
       
   780     return true;
       
   781   }
       
   782   pos = strstr(filepath, filename);
       
   783   *pos = '\0';
       
   784   strcat(filepath, "/server");
       
   785   strcat(filepath, filename);
       
   786   if (exists(filepath)) {
       
   787     strcpy(rpath, filepath);
       
   788     return true;
       
   789   }
       
   790 
       
   791   return false;
       
   792 }
       
   793 
       
   794 static bool read_shared_lib_info(struct ps_prochandle* ph) {
       
   795   static int pagesize = 0;
       
   796   int fd = ph->core->core_fd;
       
   797   int i = 0, j;
       
   798   uint32_t  v;
       
   799   mach_header_64 header;        // used to check if a file header in segment
       
   800   load_command lcmd;
       
   801   dylib_command dylibcmd;
       
   802 
       
   803   char name[BUF_SIZE];  // use to store name
       
   804 
       
   805   if (pagesize == 0) {
       
   806     pagesize = getpagesize();
       
   807     print_debug("page size is %d\n", pagesize);
       
   808   }
       
   809   for (j = 0; j < ph->core->num_maps; j++) {
       
   810     map_info *iter = ph->core->map_array[j];   // head
       
   811     off_t fpos = iter->offset;
       
   812     if (iter->fd != fd) {
       
   813       // only search core file!
       
   814       continue;
       
   815     }
       
   816     print_debug("map_info %d: vmaddr = 0x%016" PRIx64 "  fileoff = %" PRIu64 "  vmsize = %" PRIu64 "\n",
       
   817                            j, iter->vaddr, iter->offset, iter->memsz);
       
   818     lseek(fd, fpos, SEEK_SET);
       
   819     // we assume .dylib loaded at segment address --- which is true for JVM libraries
       
   820     // multiple files may be loaded in one segment.
       
   821     // if first word is not a magic word, means this segment does not contain lib file.
       
   822     if (read(fd, (void *)&v, sizeof(uint32_t)) == sizeof(uint32_t)) {
       
   823       if (v != MH_MAGIC_64) {
       
   824         continue;
       
   825       }
       
   826     } else {
       
   827       // may be encountered last map, which is not readable
       
   828       continue;
       
   829     }
       
   830     while (ltell(fd) - iter->offset < iter->memsz) {
       
   831       lseek(fd, fpos, SEEK_SET);
       
   832       if (read(fd, (void *)&v, sizeof(uint32_t)) != sizeof(uint32_t)) {
       
   833         break;
       
   834       }
       
   835       if (v != MH_MAGIC_64) {
       
   836         fpos = (ltell(fd) + pagesize -1)/pagesize * pagesize;
       
   837         continue;
       
   838       }
       
   839       lseek(fd, -sizeof(uint32_t), SEEK_CUR);
       
   840       // this is the file begining to core file.
       
   841       if (read(fd, (void *)&header, sizeof(mach_header_64)) != sizeof(mach_header_64)) {
       
   842         goto err;
       
   843       }
       
   844       fpos = ltell(fd);
       
   845 
       
   846       // found a mach-o file in this segment
       
   847       for (i = 0; i < header.ncmds; i++) {
       
   848         // read commands in this "file"
       
   849         // LC_ID_DYLIB is the file itself for a .dylib
       
   850         lseek(fd, fpos, SEEK_SET);
       
   851         if (read(fd, (void *)&lcmd, sizeof(load_command)) != sizeof(load_command)) {
       
   852           return false;   // error
       
   853         }
       
   854         fpos += lcmd.cmdsize;  // next command position
       
   855         // make sure still within seg size.
       
   856         if (fpos  - lcmd.cmdsize - iter->offset > iter->memsz) {
       
   857           print_debug("Warning: out of segement limit: %ld \n", fpos  - lcmd.cmdsize - iter->offset);
       
   858           break;  // no need to iterate all commands
       
   859         }
       
   860         if (lcmd.cmd == LC_ID_DYLIB) {
       
   861           lseek(fd, -sizeof(load_command), SEEK_CUR);
       
   862           if (read(fd, (void *)&dylibcmd, sizeof(dylib_command)) != sizeof(dylib_command)) {
       
   863             return false;
       
   864           }
       
   865           /**** name stored at dylib_command.dylib.name.offset, is a C string  */
       
   866           lseek(fd, dylibcmd.dylib.name.offset - sizeof(dylib_command), SEEK_CUR);
       
   867           int j = 0;
       
   868           while (j < BUF_SIZE) {
       
   869             read(fd, (void *)(name + j), sizeof(char));
       
   870             if (name[j] == '\0') break;
       
   871             j++;
       
   872           }
       
   873           print_debug("%s\n", name);
       
   874           // changed name from @rpath/xxxx.dylib to real path
       
   875           if (strrchr(name, '@')) {
       
   876             get_real_path(ph, name);
       
   877             print_debug("get_real_path returned: %s\n", name);
       
   878           }
       
   879           add_lib_info(ph, name, iter->vaddr);
       
   880           break;
       
   881         }
       
   882       }
       
   883       // done with the file, advanced to next page to search more files
       
   884       fpos = (ltell(fd) + pagesize - 1) / pagesize * pagesize;
       
   885     }
       
   886   }
       
   887   return true;
       
   888 err:
       
   889   return false;
       
   890 }
       
   891 
       
   892 bool read_macho64_header(int fd, mach_header_64* core_header) {
       
   893   bool is_macho = false;
       
   894   if (fd < 0) return false;
       
   895   off_t pos = ltell(fd);
       
   896   lseek(fd, 0, SEEK_SET);
       
   897   if (read(fd, (void *)core_header, sizeof(mach_header_64)) != sizeof(mach_header_64)) {
       
   898     is_macho = false;
       
   899   } else {
       
   900     is_macho = (core_header->magic ==  MH_MAGIC_64 || core_header->magic ==  MH_CIGAM_64);
       
   901   }
       
   902   lseek(fd, pos, SEEK_SET);
       
   903   return is_macho;
       
   904 }
       
   905 
       
   906 // the one and only one exposed stuff from this file
       
   907 struct ps_prochandle* Pgrab_core(const char* exec_file, const char* core_file) {
       
   908   mach_header_64 core_header;
       
   909   mach_header_64 exec_header;
       
   910 
       
   911   struct ps_prochandle* ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle));
       
   912   if (ph == NULL) {
       
   913     print_debug("cant allocate ps_prochandle\n");
       
   914     return NULL;
       
   915   }
       
   916 
       
   917   if ((ph->core = (struct core_data*) calloc(1, sizeof(struct core_data))) == NULL) {
       
   918     free(ph);
       
   919     print_debug("can't allocate ps_prochandle\n");
       
   920     return NULL;
       
   921   }
       
   922 
       
   923   // initialize ph
       
   924   ph->ops = &core_ops;
       
   925   ph->core->core_fd   = -1;
       
   926   ph->core->exec_fd   = -1;
       
   927   ph->core->interp_fd = -1;
       
   928 
       
   929   print_debug("exec: %s   core: %s", exec_file, core_file);
       
   930 
       
   931   strncpy(ph->core->exec_path, exec_file, sizeof(ph->core->exec_path));
       
   932 
       
   933   // open the core file
       
   934   if ((ph->core->core_fd = open(core_file, O_RDONLY)) < 0) {
       
   935     print_error("can't open core file\n");
       
   936     goto err;
       
   937   }
       
   938 
       
   939   // read core file header
       
   940   if (read_macho64_header(ph->core->core_fd, &core_header) != true || core_header.filetype != MH_CORE) {
       
   941     print_debug("core file is not a valid Mach-O file\n");
       
   942     goto err;
       
   943   }
       
   944 
       
   945   if ((ph->core->exec_fd = open(exec_file, O_RDONLY)) < 0) {
       
   946     print_error("can't open executable file\n");
       
   947     goto err;
       
   948   }
       
   949 
       
   950   if (read_macho64_header(ph->core->exec_fd, &exec_header) != true ||
       
   951                           exec_header.filetype != MH_EXECUTE) {
       
   952     print_error("executable file is not a valid Mach-O file\n");
       
   953     goto err;
       
   954   }
       
   955 
       
   956   // process core file segments
       
   957   if (read_core_segments(ph) != true) {
       
   958     print_error("failed to read core segments\n");
       
   959     goto err;
       
   960   }
       
   961 
       
   962   // allocate and sort maps into map_array, we need to do this
       
   963   // here because read_shared_lib_info needs to read from debuggee
       
   964   // address space
       
   965   if (sort_map_array(ph) != true) {
       
   966     print_error("failed to sort segment map array\n");
       
   967     goto err;
       
   968   }
       
   969 
       
   970   if (read_shared_lib_info(ph) != true) {
       
   971     print_error("failed to read libraries\n");
       
   972     goto err;
       
   973   }
       
   974 
       
   975   // sort again because we have added more mappings from shared objects
       
   976   if (sort_map_array(ph) != true) {
       
   977     print_error("failed to sort segment map array\n");
       
   978     goto err;
       
   979   }
       
   980 
       
   981   if (init_classsharing_workaround(ph) != true) {
       
   982     print_error("failed to workaround classshareing\n");
       
   983     goto err;
       
   984   }
       
   985 
       
   986   print_debug("Leave Pgrab_core\n");
       
   987   return ph;
       
   988 
       
   989 err:
       
   990   Prelease(ph);
       
   991   return NULL;
       
   992 }
       
   993 
       
   994 #else // __APPLE__ (none macosx)
       
   995 
       
   996 // read regs and create thread from core file
   536 static bool core_handle_prstatus(struct ps_prochandle* ph, const char* buf, size_t nbytes) {
   997 static bool core_handle_prstatus(struct ps_prochandle* ph, const char* buf, size_t nbytes) {
   537    // we have to read prstatus_t from buf
   998    // we have to read prstatus_t from buf
   538    // assert(nbytes == sizeof(prstaus_t), "size mismatch on prstatus_t");
   999    // assert(nbytes == sizeof(prstaus_t), "size mismatch on prstatus_t");
   539    prstatus_t* prstat = (prstatus_t*) buf;
  1000    prstatus_t* prstat = (prstatus_t*) buf;
   540    thread_info* newthr;
  1001    sa_thread_info* newthr;
   541    print_debug("got integer regset for lwp %d\n", prstat->pr_pid);
  1002    print_debug("got integer regset for lwp %d\n", prstat->pr_pid);
   542    // we set pthread_t to -1 for core dump
  1003    // we set pthread_t to -1 for core dump
   543    if((newthr = add_thread_info(ph, (pthread_t) -1,  prstat->pr_pid)) == NULL)
  1004    if((newthr = add_thread_info(ph, (pthread_t) -1,  prstat->pr_pid)) == NULL)
   544       return false;
  1005       return false;
   545 
  1006 
   630       char* descdata  = p + sizeof(ELF_NHDR) + ROUNDUP(notep->n_namesz, 4);
  1091       char* descdata  = p + sizeof(ELF_NHDR) + ROUNDUP(notep->n_namesz, 4);
   631       print_debug("Note header with n_type = %d and n_descsz = %u\n",
  1092       print_debug("Note header with n_type = %d and n_descsz = %u\n",
   632                                    notep->n_type, notep->n_descsz);
  1093                                    notep->n_type, notep->n_descsz);
   633 
  1094 
   634       if (notep->n_type == NT_PRSTATUS) {
  1095       if (notep->n_type == NT_PRSTATUS) {
   635          if (core_handle_prstatus(ph, descdata, notep->n_descsz) != true)
  1096          if (core_handle_prstatus(ph, descdata, notep->n_descsz) != true) {
   636             return false;
  1097             return false;
       
  1098          }
   637       }
  1099       }
   638       p = descdata + ROUNDUP(notep->n_descsz, 4);
  1100       p = descdata + ROUNDUP(notep->n_descsz, 4);
   639    }
  1101    }
   640 
  1102 
   641    free(buf);
  1103    free(buf);
   679     */
  1141     */
   680 
  1142 
   681     for (core_php = phbuf, i = 0; i < core_ehdr->e_phnum; i++) {
  1143     for (core_php = phbuf, i = 0; i < core_ehdr->e_phnum; i++) {
   682       switch (core_php->p_type) {
  1144       switch (core_php->p_type) {
   683          case PT_NOTE:
  1145          case PT_NOTE:
   684             if (core_handle_note(ph, core_php) != true) goto err;
  1146             if (core_handle_note(ph, core_php) != true) {
       
  1147               goto err;
       
  1148             }
   685             break;
  1149             break;
   686 
  1150 
   687          case PT_LOAD: {
  1151          case PT_LOAD: {
   688             if (core_php->p_filesz != 0) {
  1152             if (core_php->p_filesz != 0) {
   689                if (add_map_info(ph, ph->core->core_fd, core_php->p_offset,
  1153                if (add_map_info(ph, ph->core->core_fd, core_php->p_offset,
   798 err:
  1262 err:
   799    free(phbuf);
  1263    free(phbuf);
   800    return false;
  1264    return false;
   801 }
  1265 }
   802 
  1266 
   803 
       
   804 #define FIRST_LINK_MAP_OFFSET offsetof(struct r_debug,  r_map)
  1267 #define FIRST_LINK_MAP_OFFSET offsetof(struct r_debug,  r_map)
   805 #define LD_BASE_OFFSET        offsetof(struct r_debug,  r_ldbase)
  1268 #define LD_BASE_OFFSET        offsetof(struct r_debug,  r_ldbase)
   806 #define LINK_MAP_ADDR_OFFSET  offsetof(struct link_map, l_addr)
  1269 #define LINK_MAP_ADDR_OFFSET  offsetof(struct link_map, l_addr)
   807 #define LINK_MAP_NAME_OFFSET  offsetof(struct link_map, l_name)
  1270 #define LINK_MAP_NAME_OFFSET  offsetof(struct link_map, l_name)
   808 #define LINK_MAP_NEXT_OFFSET  offsetof(struct link_map, l_next)
  1271 #define LINK_MAP_NEXT_OFFSET  offsetof(struct link_map, l_next)
   809 
  1272 
   810 // read shared library info from runtime linker's data structures.
  1273 // read shared library info from runtime linker's data structures.
   811 // This work is done by librtlb_db in Solaris
  1274 // This work is done by librtlb_db in Solaris
   812 static bool read_shared_lib_info(struct ps_prochandle* ph) {
  1275 static bool read_shared_lib_info(struct ps_prochandle* ph) {
   813    uintptr_t addr = ph->core->dynamic_addr;
  1276   uintptr_t addr = ph->core->dynamic_addr;
   814    uintptr_t debug_base;
  1277   uintptr_t debug_base;
   815    uintptr_t first_link_map_addr;
  1278   uintptr_t first_link_map_addr;
   816    uintptr_t ld_base_addr;
  1279   uintptr_t ld_base_addr;
   817    uintptr_t link_map_addr;
  1280   uintptr_t link_map_addr;
   818    uintptr_t lib_base_diff;
  1281   uintptr_t lib_base_diff;
   819    uintptr_t lib_base;
  1282   uintptr_t lib_base;
   820    uintptr_t lib_name_addr;
  1283   uintptr_t lib_name_addr;
   821    char lib_name[BUF_SIZE];
  1284   char lib_name[BUF_SIZE];
   822    ELF_DYN dyn;
  1285   ELF_DYN dyn;
   823    ELF_EHDR elf_ehdr;
  1286   ELF_EHDR elf_ehdr;
   824    int lib_fd;
  1287   int lib_fd;
   825 
  1288 
   826    // _DYNAMIC has information of the form
  1289   // _DYNAMIC has information of the form
   827    //         [tag] [data] [tag] [data] .....
  1290   //         [tag] [data] [tag] [data] .....
   828    // Both tag and data are pointer sized.
  1291   // Both tag and data are pointer sized.
   829    // We look for dynamic info with DT_DEBUG. This has shared object info.
  1292   // We look for dynamic info with DT_DEBUG. This has shared object info.
   830    // refer to struct r_debug in link.h
  1293   // refer to struct r_debug in link.h
   831 
  1294 
   832    dyn.d_tag = DT_NULL;
  1295   dyn.d_tag = DT_NULL;
   833    while (dyn.d_tag != DT_DEBUG) {
  1296   while (dyn.d_tag != DT_DEBUG) {
   834       if (ps_pread(ph, (psaddr_t) addr, &dyn, sizeof(ELF_DYN)) != PS_OK) {
  1297     if (ps_pread(ph, (psaddr_t) addr, &dyn, sizeof(ELF_DYN)) != PS_OK) {
   835          print_debug("can't read debug info from _DYNAMIC\n");
  1298       print_debug("can't read debug info from _DYNAMIC\n");
   836          return false;
       
   837       }
       
   838       addr += sizeof(ELF_DYN);
       
   839    }
       
   840 
       
   841    // we have got Dyn entry with DT_DEBUG
       
   842    debug_base = dyn.d_un.d_ptr;
       
   843    // at debug_base we have struct r_debug. This has first link map in r_map field
       
   844    if (ps_pread(ph, (psaddr_t) debug_base + FIRST_LINK_MAP_OFFSET,
       
   845                  &first_link_map_addr, sizeof(uintptr_t)) != PS_OK) {
       
   846       print_debug("can't read first link map address\n");
       
   847       return false;
  1299       return false;
   848    }
  1300     }
   849 
  1301     addr += sizeof(ELF_DYN);
   850    // read ld_base address from struct r_debug
  1302   }
   851    // XXX: There is no r_ldbase member on BSD
  1303 
   852 /*
  1304   // we have got Dyn entry with DT_DEBUG
   853    if (ps_pread(ph, (psaddr_t) debug_base + LD_BASE_OFFSET, &ld_base_addr,
  1305   debug_base = dyn.d_un.d_ptr;
   854                  sizeof(uintptr_t)) != PS_OK) {
  1306   // at debug_base we have struct r_debug. This has first link map in r_map field
   855       print_debug("can't read ld base address\n");
  1307   if (ps_pread(ph, (psaddr_t) debug_base + FIRST_LINK_MAP_OFFSET,
       
  1308                   &first_link_map_addr, sizeof(uintptr_t)) != PS_OK) {
       
  1309     print_debug("can't read first link map address\n");
       
  1310     return false;
       
  1311   }
       
  1312 
       
  1313   // read ld_base address from struct r_debug
       
  1314   // XXX: There is no r_ldbase member on BSD
       
  1315   /*
       
  1316   if (ps_pread(ph, (psaddr_t) debug_base + LD_BASE_OFFSET, &ld_base_addr,
       
  1317                   sizeof(uintptr_t)) != PS_OK) {
       
  1318     print_debug("can't read ld base address\n");
       
  1319     return false;
       
  1320   }
       
  1321   ph->core->ld_base_addr = ld_base_addr;
       
  1322   */
       
  1323   ph->core->ld_base_addr = 0;
       
  1324 
       
  1325   print_debug("interpreter base address is 0x%lx\n", ld_base_addr);
       
  1326 
       
  1327   // now read segments from interp (i.e ld-elf.so.1)
       
  1328   if (read_interp_segments(ph) != true)
       
  1329     return false;
       
  1330 
       
  1331   // after adding interpreter (ld.so) mappings sort again
       
  1332   if (sort_map_array(ph) != true)
       
  1333     return false;
       
  1334 
       
  1335   print_debug("first link map is at 0x%lx\n", first_link_map_addr);
       
  1336 
       
  1337   link_map_addr = first_link_map_addr;
       
  1338   while (link_map_addr != 0) {
       
  1339     // read library base address of the .so. Note that even though <sys/link.h> calls
       
  1340     // link_map->l_addr as "base address",  this is * not * really base virtual
       
  1341     // address of the shared object. This is actually the difference b/w the virtual
       
  1342     // address mentioned in shared object and the actual virtual base where runtime
       
  1343     // linker loaded it. We use "base diff" in read_lib_segments call below.
       
  1344 
       
  1345     if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_ADDR_OFFSET,
       
  1346                  &lib_base_diff, sizeof(uintptr_t)) != PS_OK) {
       
  1347       print_debug("can't read shared object base address diff\n");
   856       return false;
  1348       return false;
   857    }
  1349     }
   858    ph->core->ld_base_addr = ld_base_addr;
  1350 
   859 */
  1351     // read address of the name
   860    ph->core->ld_base_addr = 0;
  1352     if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_NAME_OFFSET,
   861 
  1353                   &lib_name_addr, sizeof(uintptr_t)) != PS_OK) {
   862    print_debug("interpreter base address is 0x%lx\n", ld_base_addr);
  1354       print_debug("can't read address of shared object name\n");
   863 
       
   864    // now read segments from interp (i.e ld-elf.so.1)
       
   865    if (read_interp_segments(ph) != true)
       
   866       return false;
  1355       return false;
   867 
  1356     }
   868    // after adding interpreter (ld.so) mappings sort again
  1357 
   869    if (sort_map_array(ph) != true)
  1358     // read name of the shared object
       
  1359     if (read_string(ph, (uintptr_t) lib_name_addr, lib_name, sizeof(lib_name)) != true) {
       
  1360       print_debug("can't read shared object name\n");
   870       return false;
  1361       return false;
   871 
  1362     }
   872    print_debug("first link map is at 0x%lx\n", first_link_map_addr);
  1363 
   873 
  1364     if (lib_name[0] != '\0') {
   874    link_map_addr = first_link_map_addr;
  1365       // ignore empty lib names
   875    while (link_map_addr != 0) {
  1366       lib_fd = pathmap_open(lib_name);
   876       // read library base address of the .so. Note that even though <sys/link.h> calls
  1367 
   877       // link_map->l_addr as "base address",  this is * not * really base virtual
  1368       if (lib_fd < 0) {
   878       // address of the shared object. This is actually the difference b/w the virtual
  1369         print_debug("can't open shared object %s\n", lib_name);
   879       // address mentioned in shared object and the actual virtual base where runtime
  1370         // continue with other libraries...
   880       // linker loaded it. We use "base diff" in read_lib_segments call below.
  1371       } else {
   881 
  1372         if (read_elf_header(lib_fd, &elf_ehdr)) {
   882       if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_ADDR_OFFSET,
  1373           lib_base = lib_base_diff + find_base_address(lib_fd, &elf_ehdr);
   883                    &lib_base_diff, sizeof(uintptr_t)) != PS_OK) {
  1374           print_debug("reading library %s @ 0x%lx [ 0x%lx ]\n",
   884          print_debug("can't read shared object base address diff\n");
  1375                        lib_name, lib_base, lib_base_diff);
   885          return false;
  1376           // while adding library mappings we need to use "base difference".
   886       }
  1377           if (! read_lib_segments(ph, lib_fd, &elf_ehdr, lib_base_diff)) {
   887 
  1378             print_debug("can't read shared object's segments\n");
   888       // read address of the name
  1379             close(lib_fd);
   889       if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_NAME_OFFSET,
  1380             return false;
   890                     &lib_name_addr, sizeof(uintptr_t)) != PS_OK) {
  1381           }
   891          print_debug("can't read address of shared object name\n");
  1382           add_lib_info_fd(ph, lib_name, lib_fd, lib_base);
   892          return false;
  1383           // Map info is added for the library (lib_name) so
   893       }
  1384           // we need to re-sort it before calling the p_pdread.
   894 
  1385           if (sort_map_array(ph) != true)
   895       // read name of the shared object
  1386             return false;
   896       if (read_string(ph, (uintptr_t) lib_name_addr, lib_name, sizeof(lib_name)) != true) {
  1387         } else {
   897          print_debug("can't read shared object name\n");
  1388           print_debug("can't read ELF header for shared object %s\n", lib_name);
   898          return false;
  1389           close(lib_fd);
   899       }
  1390           // continue with other libraries...
   900 
  1391         }
   901       if (lib_name[0] != '\0') {
  1392       }
   902          // ignore empty lib names
  1393     }
   903          lib_fd = pathmap_open(lib_name);
  1394 
   904 
  1395     // read next link_map address
   905          if (lib_fd < 0) {
  1396     if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_NEXT_OFFSET,
   906             print_debug("can't open shared object %s\n", lib_name);
  1397                  &link_map_addr, sizeof(uintptr_t)) != PS_OK) {
   907             // continue with other libraries...
  1398       print_debug("can't read next link in link_map\n");
   908          } else {
  1399       return false;
   909             if (read_elf_header(lib_fd, &elf_ehdr)) {
  1400     }
   910                lib_base = lib_base_diff + find_base_address(lib_fd, &elf_ehdr);
  1401   }
   911                print_debug("reading library %s @ 0x%lx [ 0x%lx ]\n",
  1402 
   912                            lib_name, lib_base, lib_base_diff);
  1403   return true;
   913                // while adding library mappings we need to use "base difference".
       
   914                if (! read_lib_segments(ph, lib_fd, &elf_ehdr, lib_base_diff)) {
       
   915                   print_debug("can't read shared object's segments\n");
       
   916                   close(lib_fd);
       
   917                   return false;
       
   918                }
       
   919                add_lib_info_fd(ph, lib_name, lib_fd, lib_base);
       
   920                // Map info is added for the library (lib_name) so
       
   921                // we need to re-sort it before calling the p_pdread.
       
   922                if (sort_map_array(ph) != true)
       
   923                   return false;
       
   924             } else {
       
   925                print_debug("can't read ELF header for shared object %s\n", lib_name);
       
   926                close(lib_fd);
       
   927                // continue with other libraries...
       
   928             }
       
   929          }
       
   930       }
       
   931 
       
   932       // read next link_map address
       
   933       if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_NEXT_OFFSET,
       
   934                         &link_map_addr, sizeof(uintptr_t)) != PS_OK) {
       
   935          print_debug("can't read next link in link_map\n");
       
   936          return false;
       
   937       }
       
   938    }
       
   939 
       
   940    return true;
       
   941 }
  1404 }
   942 
  1405 
   943 // the one and only one exposed stuff from this file
  1406 // the one and only one exposed stuff from this file
   944 struct ps_prochandle* Pgrab_core(const char* exec_file, const char* core_file) {
  1407 struct ps_prochandle* Pgrab_core(const char* exec_file, const char* core_file) {
   945    ELF_EHDR core_ehdr;
  1408   ELF_EHDR core_ehdr;
   946    ELF_EHDR exec_ehdr;
  1409   ELF_EHDR exec_ehdr;
   947 
  1410 
   948    struct ps_prochandle* ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle));
  1411   struct ps_prochandle* ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle));
   949    if (ph == NULL) {
  1412   if (ph == NULL) {
   950       print_debug("can't allocate ps_prochandle\n");
  1413     print_debug("cant allocate ps_prochandle\n");
   951       return NULL;
  1414     return NULL;
   952    }
  1415   }
   953 
  1416 
   954    if ((ph->core = (struct core_data*) calloc(1, sizeof(struct core_data))) == NULL) {
  1417   if ((ph->core = (struct core_data*) calloc(1, sizeof(struct core_data))) == NULL) {
   955       free(ph);
  1418     free(ph);
   956       print_debug("can't allocate ps_prochandle\n");
  1419     print_debug("can't allocate ps_prochandle\n");
   957       return NULL;
  1420     return NULL;
   958    }
  1421   }
   959 
  1422 
   960    // initialize ph
  1423   // initialize ph
   961    ph->ops = &core_ops;
  1424   ph->ops = &core_ops;
   962    ph->core->core_fd   = -1;
  1425   ph->core->core_fd   = -1;
   963    ph->core->exec_fd   = -1;
  1426   ph->core->exec_fd   = -1;
   964    ph->core->interp_fd = -1;
  1427   ph->core->interp_fd = -1;
   965 
  1428 
   966    // open the core file
  1429   print_debug("exec: %s   core: %s", exec_file, core_file);
   967    if ((ph->core->core_fd = open(core_file, O_RDONLY)) < 0) {
  1430 
   968       print_debug("can't open core file\n");
  1431   // open the core file
   969       goto err;
  1432   if ((ph->core->core_fd = open(core_file, O_RDONLY)) < 0) {
   970    }
  1433     print_debug("can't open core file\n");
   971 
  1434     goto err;
   972    // read core file ELF header
  1435   }
   973    if (read_elf_header(ph->core->core_fd, &core_ehdr) != true || core_ehdr.e_type != ET_CORE) {
  1436 
   974       print_debug("core file is not a valid ELF ET_CORE file\n");
  1437   // read core file ELF header
   975       goto err;
  1438   if (read_elf_header(ph->core->core_fd, &core_ehdr) != true || core_ehdr.e_type != ET_CORE) {
   976    }
  1439     print_debug("core file is not a valid ELF ET_CORE file\n");
   977 
  1440     goto err;
   978    if ((ph->core->exec_fd = open(exec_file, O_RDONLY)) < 0) {
  1441   }
   979       print_debug("can't open executable file\n");
  1442 
   980       goto err;
  1443   if ((ph->core->exec_fd = open(exec_file, O_RDONLY)) < 0) {
   981    }
  1444     print_debug("can't open executable file\n");
   982 
  1445     goto err;
   983    if (read_elf_header(ph->core->exec_fd, &exec_ehdr) != true || exec_ehdr.e_type != ET_EXEC) {
  1446   }
   984       print_debug("executable file is not a valid ELF ET_EXEC file\n");
  1447 
   985       goto err;
  1448   if (read_elf_header(ph->core->exec_fd, &exec_ehdr) != true || exec_ehdr.e_type != ET_EXEC) {
   986    }
  1449      print_debug("executable file is not a valid ELF ET_EXEC file\n");
   987 
  1450      goto err;
   988    // process core file segments
  1451   }
   989    if (read_core_segments(ph, &core_ehdr) != true)
  1452 
   990       goto err;
  1453   // process core file segments
   991 
  1454   if (read_core_segments(ph, &core_ehdr) != true)
   992    // process exec file segments
  1455      goto err;
   993    if (read_exec_segments(ph, &exec_ehdr) != true)
  1456 
   994       goto err;
  1457   // process exec file segments
   995 
  1458   if (read_exec_segments(ph, &exec_ehdr) != true)
   996    // exec file is also treated like a shared object for symbol search
  1459      goto err;
   997    if (add_lib_info_fd(ph, exec_file, ph->core->exec_fd,
  1460 
   998                        (uintptr_t)0 + find_base_address(ph->core->exec_fd, &exec_ehdr)) == NULL)
  1461   // exec file is also treated like a shared object for symbol search
   999       goto err;
  1462   if (add_lib_info_fd(ph, exec_file, ph->core->exec_fd,
  1000 
  1463                       (uintptr_t)0 + find_base_address(ph->core->exec_fd, &exec_ehdr)) == NULL)
  1001    // allocate and sort maps into map_array, we need to do this
  1464      goto err;
  1002    // here because read_shared_lib_info needs to read from debuggee
  1465 
  1003    // address space
  1466   // allocate and sort maps into map_array, we need to do this
  1004    if (sort_map_array(ph) != true)
  1467   // here because read_shared_lib_info needs to read from debuggee
  1005       goto err;
  1468   // address space
  1006 
  1469   if (sort_map_array(ph) != true)
  1007    if (read_shared_lib_info(ph) != true)
  1470     goto err;
  1008       goto err;
  1471 
  1009 
  1472   if (read_shared_lib_info(ph) != true)
  1010    // sort again because we have added more mappings from shared objects
  1473     goto err;
  1011    if (sort_map_array(ph) != true)
  1474 
  1012       goto err;
  1475   // sort again because we have added more mappings from shared objects
  1013 
  1476   if (sort_map_array(ph) != true)
  1014    if (init_classsharing_workaround(ph) != true)
  1477     goto err;
  1015       goto err;
  1478 
  1016 
  1479   if (init_classsharing_workaround(ph) != true)
  1017    return ph;
  1480     goto err;
       
  1481 
       
  1482   print_debug("Leave Pgrab_core\n");
       
  1483   return ph;
  1018 
  1484 
  1019 err:
  1485 err:
  1020    Prelease(ph);
  1486   Prelease(ph);
  1021    return NULL;
  1487   return NULL;
  1022 }
  1488 }
       
  1489 
       
  1490 #endif // __APPLE__