8025250: SA: Sync linux and bsd versions of ps_core file

Wed, 02 Oct 2013 22:27:23 +0400

author
dsamersoff
date
Wed, 02 Oct 2013 22:27:23 +0400
changeset 5832
5705c7ee6dd7
parent 5826
f21415c32ca1
child 5833
7ae82c3a781a

8025250: SA: Sync linux and bsd versions of ps_core file
Summary: linux/ps_core.c and bsd/ps_core.c share most of code, but it has different formatting, comments etc.
Reviewed-by: sla, minqi

agent/src/os/bsd/ps_core.c file | annotate | diff | comparison | revisions
agent/src/os/linux/ps_core.c file | annotate | diff | comparison | revisions
     1.1 --- a/agent/src/os/bsd/ps_core.c	Tue Oct 01 15:41:39 2013 -0400
     1.2 +++ b/agent/src/os/bsd/ps_core.c	Wed Oct 02 22:27:23 2013 +0400
     1.3 @@ -44,6 +44,7 @@
     1.4  // close all file descriptors
     1.5  static void close_files(struct ps_prochandle* ph) {
     1.6    lib_info* lib = NULL;
     1.7 +
     1.8    // close core file descriptor
     1.9    if (ph->core->core_fd >= 0)
    1.10      close(ph->core->core_fd);
    1.11 @@ -149,8 +150,7 @@
    1.12  
    1.13  // Return the map_info for the given virtual address.  We keep a sorted
    1.14  // array of pointers in ph->map_array, so we can binary search.
    1.15 -static map_info* core_lookup(struct ps_prochandle *ph, uintptr_t addr)
    1.16 -{
    1.17 +static map_info* core_lookup(struct ps_prochandle *ph, uintptr_t addr) {
    1.18    int mid, lo = 0, hi = ph->core->num_maps - 1;
    1.19    map_info *mp;
    1.20  
    1.21 @@ -230,9 +230,9 @@
    1.22      size_t _used;            // for setting space top on read
    1.23  
    1.24      // 4991491 NOTICE These are C++ bool's in filemap.hpp and must match up with
    1.25 -    // the C type matching the C++ bool type on any given platform. For
    1.26 -    // Hotspot on BSD we assume the corresponding C type is char but
    1.27 -    // licensees on BSD versions may need to adjust the type of these fields.
    1.28 +    // the C type matching the C++ bool type on any given platform.
    1.29 +    // We assume the corresponding C type is char but licensees
    1.30 +    // may need to adjust the type of these fields.
    1.31      char   _read_only;       // read only space?
    1.32      char   _allow_exec;      // executable code in space?
    1.33  
    1.34 @@ -286,10 +286,12 @@
    1.35  #define USE_SHARED_SPACES_SYM "_UseSharedSpaces"
    1.36  // mangled name of Arguments::SharedArchivePath
    1.37  #define SHARED_ARCHIVE_PATH_SYM "_ZN9Arguments17SharedArchivePathE"
    1.38 +#define LIBJVM_NAME "/libjvm.dylib"
    1.39  #else
    1.40  #define USE_SHARED_SPACES_SYM "UseSharedSpaces"
    1.41  // mangled name of Arguments::SharedArchivePath
    1.42  #define SHARED_ARCHIVE_PATH_SYM "__ZN9Arguments17SharedArchivePathE"
    1.43 +#define LIBJVM_NAME "/libjvm.so"
    1.44  #endif // __APPLE_
    1.45  
    1.46  static bool init_classsharing_workaround(struct ps_prochandle* ph) {
    1.47 @@ -300,12 +302,7 @@
    1.48      // we are iterating over shared objects from the core dump. look for
    1.49      // libjvm.so.
    1.50      const char *jvm_name = 0;
    1.51 -#ifdef __APPLE__
    1.52 -    if ((jvm_name = strstr(lib->name, "/libjvm.dylib")) != 0)
    1.53 -#else
    1.54 -    if ((jvm_name = strstr(lib->name, "/libjvm.so")) != 0)
    1.55 -#endif // __APPLE__
    1.56 -    {
    1.57 +    if ((jvm_name = strstr(lib->name, LIBJVM_NAME)) != 0) {
    1.58        char classes_jsa[PATH_MAX];
    1.59        struct FileMapHeader header;
    1.60        int fd = -1;
    1.61 @@ -399,8 +396,8 @@
    1.62          }
    1.63        }
    1.64        return true;
    1.65 -    }
    1.66 -    lib = lib->next;
    1.67 +   }
    1.68 +   lib = lib->next;
    1.69    }
    1.70    return true;
    1.71  }
    1.72 @@ -432,8 +429,8 @@
    1.73    // allocate map_array
    1.74    map_info** array;
    1.75    if ( (array = (map_info**) malloc(sizeof(map_info*) * num_maps)) == NULL) {
    1.76 -     print_debug("can't allocate memory for map array\n");
    1.77 -     return false;
    1.78 +    print_debug("can't allocate memory for map array\n");
    1.79 +    return false;
    1.80    }
    1.81  
    1.82    // add maps to array
    1.83 @@ -450,7 +447,7 @@
    1.84    ph->core->map_array = array;
    1.85    // sort the map_info array by base virtual address.
    1.86    qsort(ph->core->map_array, ph->core->num_maps, sizeof (map_info*),
    1.87 -           core_cmp_mapping);
    1.88 +        core_cmp_mapping);
    1.89  
    1.90    // print map
    1.91    if (is_debug()) {
    1.92 @@ -458,7 +455,7 @@
    1.93      print_debug("---- sorted virtual address map ----\n");
    1.94      for (j = 0; j < ph->core->num_maps; j++) {
    1.95        print_debug("base = 0x%lx\tsize = %d\n", ph->core->map_array[j]->vaddr,
    1.96 -                                       ph->core->map_array[j]->memsz);
    1.97 +                  ph->core->map_array[j]->memsz);
    1.98      }
    1.99    }
   1.100  
   1.101 @@ -1091,9 +1088,9 @@
   1.102                                     notep->n_type, notep->n_descsz);
   1.103  
   1.104        if (notep->n_type == NT_PRSTATUS) {
   1.105 -         if (core_handle_prstatus(ph, descdata, notep->n_descsz) != true) {
   1.106 -            return false;
   1.107 -         }
   1.108 +        if (core_handle_prstatus(ph, descdata, notep->n_descsz) != true) {
   1.109 +          return false;
   1.110 +        }
   1.111        }
   1.112        p = descdata + ROUNDUP(notep->n_descsz, 4);
   1.113     }
   1.114 @@ -1121,7 +1118,7 @@
   1.115      * contains a set of saved /proc structures), and PT_LOAD (which
   1.116      * represents a memory mapping from the process's address space).
   1.117      *
   1.118 -    * Difference b/w Solaris PT_NOTE and BSD PT_NOTE:
   1.119 +    * Difference b/w Solaris PT_NOTE and Linux/BSD PT_NOTE:
   1.120      *
   1.121      *     In Solaris there are two PT_NOTE segments the first PT_NOTE (if present)
   1.122      *     contains /proc structs in the pre-2.6 unstructured /proc format. the last
   1.123 @@ -1167,32 +1164,61 @@
   1.124  
   1.125  // read segments of a shared object
   1.126  static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* lib_ehdr, uintptr_t lib_base) {
   1.127 -   int i = 0;
   1.128 -   ELF_PHDR* phbuf;
   1.129 -   ELF_PHDR* lib_php = NULL;
   1.130 +  int i = 0;
   1.131 +  ELF_PHDR* phbuf;
   1.132 +  ELF_PHDR* lib_php = NULL;
   1.133  
   1.134 -   if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL)
   1.135 -      return false;
   1.136 +  int page_size=sysconf(_SC_PAGE_SIZE);
   1.137  
   1.138 -   // we want to process only PT_LOAD segments that are not writable.
   1.139 -   // i.e., text segments. The read/write/exec (data) segments would
   1.140 -   // have been already added from core file segments.
   1.141 -   for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) {
   1.142 -      if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) {
   1.143 -         if (add_map_info(ph, lib_fd, lib_php->p_offset, lib_php->p_vaddr + lib_base, lib_php->p_filesz) == NULL)
   1.144 -            goto err;
   1.145 +  if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL) {
   1.146 +    return false;
   1.147 +  }
   1.148 +
   1.149 +  // we want to process only PT_LOAD segments that are not writable.
   1.150 +  // i.e., text segments. The read/write/exec (data) segments would
   1.151 +  // have been already added from core file segments.
   1.152 +  for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) {
   1.153 +    if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) {
   1.154 +
   1.155 +      uintptr_t target_vaddr = lib_php->p_vaddr + lib_base;
   1.156 +      map_info *existing_map = core_lookup(ph, target_vaddr);
   1.157 +
   1.158 +      if (existing_map == NULL){
   1.159 +        if (add_map_info(ph, lib_fd, lib_php->p_offset,
   1.160 +                          target_vaddr, lib_php->p_filesz) == NULL) {
   1.161 +          goto err;
   1.162 +        }
   1.163 +      } else {
   1.164 +        if ((existing_map->memsz != page_size) &&
   1.165 +            (existing_map->fd != lib_fd) &&
   1.166 +            (existing_map->memsz != lib_php->p_filesz)){
   1.167 +
   1.168 +          print_debug("address conflict @ 0x%lx (size = %ld, flags = %d\n)",
   1.169 +                        target_vaddr, lib_php->p_filesz, lib_php->p_flags);
   1.170 +          goto err;
   1.171 +        }
   1.172 +
   1.173 +        /* replace PT_LOAD segment with library segment */
   1.174 +        print_debug("overwrote with new address mapping (memsz %ld -> %ld)\n",
   1.175 +                     existing_map->memsz, lib_php->p_filesz);
   1.176 +
   1.177 +        existing_map->fd = lib_fd;
   1.178 +        existing_map->offset = lib_php->p_offset;
   1.179 +        existing_map->memsz = lib_php->p_filesz;
   1.180        }
   1.181 -      lib_php++;
   1.182 -   }
   1.183 +    }
   1.184  
   1.185 -   free(phbuf);
   1.186 -   return true;
   1.187 +    lib_php++;
   1.188 +  }
   1.189 +
   1.190 +  free(phbuf);
   1.191 +  return true;
   1.192  err:
   1.193 -   free(phbuf);
   1.194 -   return false;
   1.195 +  free(phbuf);
   1.196 +  return false;
   1.197  }
   1.198  
   1.199 -// process segments from interpreter (ld-elf.so.1)
   1.200 +// process segments from interpreter (ld.so or ld-linux.so or ld-elf.so)
   1.201  static bool read_interp_segments(struct ps_prochandle* ph) {
   1.202     ELF_EHDR interp_ehdr;
   1.203  
   1.204 @@ -1303,32 +1329,34 @@
   1.205    debug_base = dyn.d_un.d_ptr;
   1.206    // at debug_base we have struct r_debug. This has first link map in r_map field
   1.207    if (ps_pread(ph, (psaddr_t) debug_base + FIRST_LINK_MAP_OFFSET,
   1.208 -                  &first_link_map_addr, sizeof(uintptr_t)) != PS_OK) {
   1.209 +                 &first_link_map_addr, sizeof(uintptr_t)) != PS_OK) {
   1.210      print_debug("can't read first link map address\n");
   1.211      return false;
   1.212    }
   1.213  
   1.214    // read ld_base address from struct r_debug
   1.215 -  // XXX: There is no r_ldbase member on BSD
   1.216 -  /*
   1.217 +#if 0  // There is no r_ldbase member on BSD
   1.218    if (ps_pread(ph, (psaddr_t) debug_base + LD_BASE_OFFSET, &ld_base_addr,
   1.219                    sizeof(uintptr_t)) != PS_OK) {
   1.220      print_debug("can't read ld base address\n");
   1.221      return false;
   1.222    }
   1.223    ph->core->ld_base_addr = ld_base_addr;
   1.224 -  */
   1.225 +#else
   1.226    ph->core->ld_base_addr = 0;
   1.227 +#endif
   1.228  
   1.229    print_debug("interpreter base address is 0x%lx\n", ld_base_addr);
   1.230  
   1.231 -  // now read segments from interp (i.e ld-elf.so.1)
   1.232 -  if (read_interp_segments(ph) != true)
   1.233 +  // now read segments from interp (i.e ld.so or ld-linux.so or ld-elf.so)
   1.234 +  if (read_interp_segments(ph) != true) {
   1.235      return false;
   1.236 +  }
   1.237  
   1.238    // after adding interpreter (ld.so) mappings sort again
   1.239 -  if (sort_map_array(ph) != true)
   1.240 +  if (sort_map_array(ph) != true) {
   1.241      return false;
   1.242 +  }
   1.243  
   1.244    print_debug("first link map is at 0x%lx\n", first_link_map_addr);
   1.245  
   1.246 @@ -1380,8 +1408,9 @@
   1.247            add_lib_info_fd(ph, lib_name, lib_fd, lib_base);
   1.248            // Map info is added for the library (lib_name) so
   1.249            // we need to re-sort it before calling the p_pdread.
   1.250 -          if (sort_map_array(ph) != true)
   1.251 +          if (sort_map_array(ph) != true) {
   1.252              return false;
   1.253 +          }
   1.254          } else {
   1.255            print_debug("can't read ELF header for shared object %s\n", lib_name);
   1.256            close(lib_fd);
   1.257 @@ -1392,7 +1421,7 @@
   1.258  
   1.259      // read next link_map address
   1.260      if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_NEXT_OFFSET,
   1.261 -                 &link_map_addr, sizeof(uintptr_t)) != PS_OK) {
   1.262 +                  &link_map_addr, sizeof(uintptr_t)) != PS_OK) {
   1.263        print_debug("can't read next link in link_map\n");
   1.264        return false;
   1.265      }
   1.266 @@ -1408,7 +1437,7 @@
   1.267  
   1.268    struct ps_prochandle* ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle));
   1.269    if (ph == NULL) {
   1.270 -    print_debug("cant allocate ps_prochandle\n");
   1.271 +    print_debug("can't allocate ps_prochandle\n");
   1.272      return NULL;
   1.273    }
   1.274  
   1.275 @@ -1444,38 +1473,45 @@
   1.276    }
   1.277  
   1.278    if (read_elf_header(ph->core->exec_fd, &exec_ehdr) != true || exec_ehdr.e_type != ET_EXEC) {
   1.279 -     print_debug("executable file is not a valid ELF ET_EXEC file\n");
   1.280 -     goto err;
   1.281 +    print_debug("executable file is not a valid ELF ET_EXEC file\n");
   1.282 +    goto err;
   1.283    }
   1.284  
   1.285    // process core file segments
   1.286 -  if (read_core_segments(ph, &core_ehdr) != true)
   1.287 -     goto err;
   1.288 +  if (read_core_segments(ph, &core_ehdr) != true) {
   1.289 +    goto err;
   1.290 +  }
   1.291  
   1.292    // process exec file segments
   1.293 -  if (read_exec_segments(ph, &exec_ehdr) != true)
   1.294 -     goto err;
   1.295 +  if (read_exec_segments(ph, &exec_ehdr) != true) {
   1.296 +    goto err;
   1.297 +  }
   1.298  
   1.299    // exec file is also treated like a shared object for symbol search
   1.300    if (add_lib_info_fd(ph, exec_file, ph->core->exec_fd,
   1.301 -                      (uintptr_t)0 + find_base_address(ph->core->exec_fd, &exec_ehdr)) == NULL)
   1.302 -     goto err;
   1.303 +                      (uintptr_t)0 + find_base_address(ph->core->exec_fd, &exec_ehdr)) == NULL) {
   1.304 +    goto err;
   1.305 +  }
   1.306  
   1.307    // allocate and sort maps into map_array, we need to do this
   1.308    // here because read_shared_lib_info needs to read from debuggee
   1.309    // address space
   1.310 -  if (sort_map_array(ph) != true)
   1.311 +  if (sort_map_array(ph) != true) {
   1.312      goto err;
   1.313 +  }
   1.314  
   1.315 -  if (read_shared_lib_info(ph) != true)
   1.316 +  if (read_shared_lib_info(ph) != true) {
   1.317      goto err;
   1.318 +  }
   1.319  
   1.320    // sort again because we have added more mappings from shared objects
   1.321 -  if (sort_map_array(ph) != true)
   1.322 +  if (sort_map_array(ph) != true) {
   1.323      goto err;
   1.324 +  }
   1.325  
   1.326 -  if (init_classsharing_workaround(ph) != true)
   1.327 +  if (init_classsharing_workaround(ph) != true) {
   1.328      goto err;
   1.329 +  }
   1.330  
   1.331    print_debug("Leave Pgrab_core\n");
   1.332    return ph;
     2.1 --- a/agent/src/os/linux/ps_core.c	Tue Oct 01 15:41:39 2013 -0400
     2.2 +++ b/agent/src/os/linux/ps_core.c	Wed Oct 02 22:27:23 2013 +0400
     2.3 @@ -41,155 +41,158 @@
     2.4  // ps_prochandle cleanup helper functions
     2.5  
     2.6  // close all file descriptors
     2.7 -static void close_elf_files(struct ps_prochandle* ph) {
     2.8 -   lib_info* lib = NULL;
     2.9 +static void close_files(struct ps_prochandle* ph) {
    2.10 +  lib_info* lib = NULL;
    2.11  
    2.12 -   // close core file descriptor
    2.13 -   if (ph->core->core_fd >= 0)
    2.14 -     close(ph->core->core_fd);
    2.15 +  // close core file descriptor
    2.16 +  if (ph->core->core_fd >= 0)
    2.17 +    close(ph->core->core_fd);
    2.18  
    2.19 -   // close exec file descriptor
    2.20 -   if (ph->core->exec_fd >= 0)
    2.21 -     close(ph->core->exec_fd);
    2.22 +  // close exec file descriptor
    2.23 +  if (ph->core->exec_fd >= 0)
    2.24 +    close(ph->core->exec_fd);
    2.25  
    2.26 -   // close interp file descriptor
    2.27 -   if (ph->core->interp_fd >= 0)
    2.28 -     close(ph->core->interp_fd);
    2.29 +  // close interp file descriptor
    2.30 +  if (ph->core->interp_fd >= 0)
    2.31 +    close(ph->core->interp_fd);
    2.32  
    2.33 -   // close class share archive file
    2.34 -   if (ph->core->classes_jsa_fd >= 0)
    2.35 -     close(ph->core->classes_jsa_fd);
    2.36 +  // close class share archive file
    2.37 +  if (ph->core->classes_jsa_fd >= 0)
    2.38 +    close(ph->core->classes_jsa_fd);
    2.39  
    2.40 -   // close all library file descriptors
    2.41 -   lib = ph->libs;
    2.42 -   while (lib) {
    2.43 -      int fd = lib->fd;
    2.44 -      if (fd >= 0 && fd != ph->core->exec_fd) close(fd);
    2.45 -      lib = lib->next;
    2.46 -   }
    2.47 +  // close all library file descriptors
    2.48 +  lib = ph->libs;
    2.49 +  while (lib) {
    2.50 +    int fd = lib->fd;
    2.51 +    if (fd >= 0 && fd != ph->core->exec_fd) {
    2.52 +      close(fd);
    2.53 +    }
    2.54 +    lib = lib->next;
    2.55 +  }
    2.56  }
    2.57  
    2.58  // clean all map_info stuff
    2.59  static void destroy_map_info(struct ps_prochandle* ph) {
    2.60    map_info* map = ph->core->maps;
    2.61    while (map) {
    2.62 -     map_info* next = map->next;
    2.63 -     free(map);
    2.64 -     map = next;
    2.65 +    map_info* next = map->next;
    2.66 +    free(map);
    2.67 +    map = next;
    2.68    }
    2.69  
    2.70    if (ph->core->map_array) {
    2.71 -     free(ph->core->map_array);
    2.72 +    free(ph->core->map_array);
    2.73    }
    2.74  
    2.75    // Part of the class sharing workaround
    2.76    map = ph->core->class_share_maps;
    2.77    while (map) {
    2.78 -     map_info* next = map->next;
    2.79 -     free(map);
    2.80 -     map = next;
    2.81 +    map_info* next = map->next;
    2.82 +    free(map);
    2.83 +    map = next;
    2.84    }
    2.85  }
    2.86  
    2.87  // ps_prochandle operations
    2.88  static void core_release(struct ps_prochandle* ph) {
    2.89 -   if (ph->core) {
    2.90 -      close_elf_files(ph);
    2.91 -      destroy_map_info(ph);
    2.92 -      free(ph->core);
    2.93 -   }
    2.94 +  if (ph->core) {
    2.95 +    close_files(ph);
    2.96 +    destroy_map_info(ph);
    2.97 +    free(ph->core);
    2.98 +  }
    2.99  }
   2.100  
   2.101  static map_info* allocate_init_map(int fd, off_t offset, uintptr_t vaddr, size_t memsz) {
   2.102 -   map_info* map;
   2.103 -   if ( (map = (map_info*) calloc(1, sizeof(map_info))) == NULL) {
   2.104 -      print_debug("can't allocate memory for map_info\n");
   2.105 -      return NULL;
   2.106 -   }
   2.107 +  map_info* map;
   2.108 +  if ( (map = (map_info*) calloc(1, sizeof(map_info))) == NULL) {
   2.109 +    print_debug("can't allocate memory for map_info\n");
   2.110 +    return NULL;
   2.111 +  }
   2.112  
   2.113 -   // initialize map
   2.114 -   map->fd     = fd;
   2.115 -   map->offset = offset;
   2.116 -   map->vaddr  = vaddr;
   2.117 -   map->memsz  = memsz;
   2.118 -   return map;
   2.119 +  // initialize map
   2.120 +  map->fd     = fd;
   2.121 +  map->offset = offset;
   2.122 +  map->vaddr  = vaddr;
   2.123 +  map->memsz  = memsz;
   2.124 +  return map;
   2.125  }
   2.126  
   2.127  // add map info with given fd, offset, vaddr and memsz
   2.128  static map_info* add_map_info(struct ps_prochandle* ph, int fd, off_t offset,
   2.129                               uintptr_t vaddr, size_t memsz) {
   2.130 -   map_info* map;
   2.131 -   if ((map = allocate_init_map(fd, offset, vaddr, memsz)) == NULL) {
   2.132 -      return NULL;
   2.133 -   }
   2.134 +  map_info* map;
   2.135 +  if ((map = allocate_init_map(fd, offset, vaddr, memsz)) == NULL) {
   2.136 +    return NULL;
   2.137 +  }
   2.138  
   2.139 -   // add this to map list
   2.140 -   map->next  = ph->core->maps;
   2.141 -   ph->core->maps   = map;
   2.142 -   ph->core->num_maps++;
   2.143 +  // add this to map list
   2.144 +  map->next  = ph->core->maps;
   2.145 +  ph->core->maps   = map;
   2.146 +  ph->core->num_maps++;
   2.147  
   2.148 -   return map;
   2.149 +  return map;
   2.150  }
   2.151  
   2.152  // Part of the class sharing workaround
   2.153 -static void add_class_share_map_info(struct ps_prochandle* ph, off_t offset,
   2.154 +static map_info* add_class_share_map_info(struct ps_prochandle* ph, off_t offset,
   2.155                               uintptr_t vaddr, size_t memsz) {
   2.156 -   map_info* map;
   2.157 -   if ((map = allocate_init_map(ph->core->classes_jsa_fd,
   2.158 -                                offset, vaddr, memsz)) == NULL) {
   2.159 -      return;
   2.160 -   }
   2.161 +  map_info* map;
   2.162 +  if ((map = allocate_init_map(ph->core->classes_jsa_fd,
   2.163 +                               offset, vaddr, memsz)) == NULL) {
   2.164 +    return NULL;
   2.165 +  }
   2.166  
   2.167 -   map->next = ph->core->class_share_maps;
   2.168 -   ph->core->class_share_maps = map;
   2.169 +  map->next = ph->core->class_share_maps;
   2.170 +  ph->core->class_share_maps = map;
   2.171 +  return map;
   2.172  }
   2.173  
   2.174  // Return the map_info for the given virtual address.  We keep a sorted
   2.175  // array of pointers in ph->map_array, so we can binary search.
   2.176 -static map_info* core_lookup(struct ps_prochandle *ph, uintptr_t addr)
   2.177 -{
   2.178 -   int mid, lo = 0, hi = ph->core->num_maps - 1;
   2.179 -   map_info *mp;
   2.180 +static map_info* core_lookup(struct ps_prochandle *ph, uintptr_t addr) {
   2.181 +  int mid, lo = 0, hi = ph->core->num_maps - 1;
   2.182 +  map_info *mp;
   2.183  
   2.184 -   while (hi - lo > 1) {
   2.185 -     mid = (lo + hi) / 2;
   2.186 -      if (addr >= ph->core->map_array[mid]->vaddr)
   2.187 -         lo = mid;
   2.188 -      else
   2.189 -         hi = mid;
   2.190 -   }
   2.191 +  while (hi - lo > 1) {
   2.192 +    mid = (lo + hi) / 2;
   2.193 +    if (addr >= ph->core->map_array[mid]->vaddr) {
   2.194 +      lo = mid;
   2.195 +    } else {
   2.196 +      hi = mid;
   2.197 +    }
   2.198 +  }
   2.199  
   2.200 -   if (addr < ph->core->map_array[hi]->vaddr)
   2.201 -      mp = ph->core->map_array[lo];
   2.202 -   else
   2.203 -      mp = ph->core->map_array[hi];
   2.204 +  if (addr < ph->core->map_array[hi]->vaddr) {
   2.205 +    mp = ph->core->map_array[lo];
   2.206 +  } else {
   2.207 +    mp = ph->core->map_array[hi];
   2.208 +  }
   2.209  
   2.210 -   if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz)
   2.211 +  if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
   2.212 +    return (mp);
   2.213 +  }
   2.214 +
   2.215 +
   2.216 +  // Part of the class sharing workaround
   2.217 +  // Unfortunately, we have no way of detecting -Xshare state.
   2.218 +  // Check out the share maps atlast, if we don't find anywhere.
   2.219 +  // This is done this way so to avoid reading share pages
   2.220 +  // ahead of other normal maps. For eg. with -Xshare:off we don't
   2.221 +  // want to prefer class sharing data to data from core.
   2.222 +  mp = ph->core->class_share_maps;
   2.223 +  if (mp) {
   2.224 +    print_debug("can't locate map_info at 0x%lx, trying class share maps\n", addr);
   2.225 +  }
   2.226 +  while (mp) {
   2.227 +    if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
   2.228 +      print_debug("located map_info at 0x%lx from class share maps\n", addr);
   2.229        return (mp);
   2.230 +    }
   2.231 +    mp = mp->next;
   2.232 +  }
   2.233  
   2.234 -
   2.235 -   // Part of the class sharing workaround
   2.236 -   // Unfortunately, we have no way of detecting -Xshare state.
   2.237 -   // Check out the share maps atlast, if we don't find anywhere.
   2.238 -   // This is done this way so to avoid reading share pages
   2.239 -   // ahead of other normal maps. For eg. with -Xshare:off we don't
   2.240 -   // want to prefer class sharing data to data from core.
   2.241 -   mp = ph->core->class_share_maps;
   2.242 -   if (mp) {
   2.243 -      print_debug("can't locate map_info at 0x%lx, trying class share maps\n",
   2.244 -             addr);
   2.245 -   }
   2.246 -   while (mp) {
   2.247 -      if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
   2.248 -         print_debug("located map_info at 0x%lx from class share maps\n",
   2.249 -                  addr);
   2.250 -         return (mp);
   2.251 -      }
   2.252 -      mp = mp->next;
   2.253 -   }
   2.254 -
   2.255 -   print_debug("can't locate map_info at 0x%lx\n", addr);
   2.256 -   return (NULL);
   2.257 +  print_debug("can't locate map_info at 0x%lx\n", addr);
   2.258 +  return (NULL);
   2.259  }
   2.260  
   2.261  //---------------------------------------------------------------
   2.262 @@ -226,9 +229,9 @@
   2.263      size_t _used;            // for setting space top on read
   2.264  
   2.265      // 4991491 NOTICE These are C++ bool's in filemap.hpp and must match up with
   2.266 -    // the C type matching the C++ bool type on any given platform. For
   2.267 -    // Hotspot on Linux we assume the corresponding C type is char but
   2.268 -    // licensees on Linux versions may need to adjust the type of these fields.
   2.269 +    // the C type matching the C++ bool type on any given platform.
   2.270 +    // We assume the corresponding C type is char but licensees
   2.271 +    // may need to adjust the type of these fields.
   2.272      char   _read_only;       // read only space?
   2.273      char   _allow_exec;      // executable code in space?
   2.274  
   2.275 @@ -238,154 +241,159 @@
   2.276  };
   2.277  
   2.278  static bool read_jboolean(struct ps_prochandle* ph, uintptr_t addr, jboolean* pvalue) {
   2.279 -   jboolean i;
   2.280 -   if (ps_pdread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) {
   2.281 -      *pvalue = i;
   2.282 -      return true;
   2.283 -   } else {
   2.284 -      return false;
   2.285 -   }
   2.286 +  jboolean i;
   2.287 +  if (ps_pdread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) {
   2.288 +    *pvalue = i;
   2.289 +    return true;
   2.290 +  } else {
   2.291 +    return false;
   2.292 +  }
   2.293  }
   2.294  
   2.295  static bool read_pointer(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* pvalue) {
   2.296 -   uintptr_t uip;
   2.297 -   if (ps_pdread(ph, (psaddr_t) addr, &uip, sizeof(uip)) == PS_OK) {
   2.298 -      *pvalue = uip;
   2.299 -      return true;
   2.300 -   } else {
   2.301 -      return false;
   2.302 -   }
   2.303 +  uintptr_t uip;
   2.304 +  if (ps_pdread(ph, (psaddr_t) addr, (char *)&uip, sizeof(uip)) == PS_OK) {
   2.305 +    *pvalue = uip;
   2.306 +    return true;
   2.307 +  } else {
   2.308 +    return false;
   2.309 +  }
   2.310  }
   2.311  
   2.312  // used to read strings from debuggee
   2.313  static bool read_string(struct ps_prochandle* ph, uintptr_t addr, char* buf, size_t size) {
   2.314 -   size_t i = 0;
   2.315 -   char  c = ' ';
   2.316 +  size_t i = 0;
   2.317 +  char  c = ' ';
   2.318  
   2.319 -   while (c != '\0') {
   2.320 -     if (ps_pdread(ph, (psaddr_t) addr, &c, sizeof(char)) != PS_OK)
   2.321 -         return false;
   2.322 -      if (i < size - 1)
   2.323 -         buf[i] = c;
   2.324 -      else // smaller buffer
   2.325 -         return false;
   2.326 -      i++; addr++;
   2.327 -   }
   2.328 +  while (c != '\0') {
   2.329 +    if (ps_pdread(ph, (psaddr_t) addr, &c, sizeof(char)) != PS_OK) {
   2.330 +      return false;
   2.331 +    }
   2.332 +    if (i < size - 1) {
   2.333 +      buf[i] = c;
   2.334 +    } else {
   2.335 +      // smaller buffer
   2.336 +      return false;
   2.337 +    }
   2.338 +    i++; addr++;
   2.339 +  }
   2.340  
   2.341 -   buf[i] = '\0';
   2.342 -   return true;
   2.343 +  buf[i] = '\0';
   2.344 +  return true;
   2.345  }
   2.346  
   2.347  #define USE_SHARED_SPACES_SYM "UseSharedSpaces"
   2.348  // mangled name of Arguments::SharedArchivePath
   2.349  #define SHARED_ARCHIVE_PATH_SYM "_ZN9Arguments17SharedArchivePathE"
   2.350 +#define LIBJVM_NAME "/libjvm.so"
   2.351  
   2.352  static bool init_classsharing_workaround(struct ps_prochandle* ph) {
   2.353 -   lib_info* lib = ph->libs;
   2.354 -   while (lib != NULL) {
   2.355 -      // we are iterating over shared objects from the core dump. look for
   2.356 -      // libjvm.so.
   2.357 -      const char *jvm_name = 0;
   2.358 -      if ((jvm_name = strstr(lib->name, "/libjvm.so")) != 0) {
   2.359 -         char classes_jsa[PATH_MAX];
   2.360 -         struct FileMapHeader header;
   2.361 -         size_t n = 0;
   2.362 -         int fd = -1, m = 0;
   2.363 -         uintptr_t base = 0, useSharedSpacesAddr = 0;
   2.364 -         uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
   2.365 -         jboolean useSharedSpaces = 0;
   2.366 -         map_info* mi = 0;
   2.367 +  lib_info* lib = ph->libs;
   2.368 +  while (lib != NULL) {
   2.369 +    // we are iterating over shared objects from the core dump. look for
   2.370 +    // libjvm.so.
   2.371 +    const char *jvm_name = 0;
   2.372 +    if ((jvm_name = strstr(lib->name, LIBJVM_NAME)) != 0) {
   2.373 +      char classes_jsa[PATH_MAX];
   2.374 +      struct FileMapHeader header;
   2.375 +      int fd = -1;
   2.376 +      int m = 0;
   2.377 +      size_t n = 0;
   2.378 +      uintptr_t base = 0, useSharedSpacesAddr = 0;
   2.379 +      uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
   2.380 +      jboolean useSharedSpaces = 0;
   2.381 +      map_info* mi = 0;
   2.382  
   2.383 -         memset(classes_jsa, 0, sizeof(classes_jsa));
   2.384 -         jvm_name = lib->name;
   2.385 -         useSharedSpacesAddr = lookup_symbol(ph, jvm_name, USE_SHARED_SPACES_SYM);
   2.386 -         if (useSharedSpacesAddr == 0) {
   2.387 -            print_debug("can't lookup 'UseSharedSpaces' flag\n");
   2.388 -            return false;
   2.389 -         }
   2.390 +      memset(classes_jsa, 0, sizeof(classes_jsa));
   2.391 +      jvm_name = lib->name;
   2.392 +      useSharedSpacesAddr = lookup_symbol(ph, jvm_name, USE_SHARED_SPACES_SYM);
   2.393 +      if (useSharedSpacesAddr == 0) {
   2.394 +        print_debug("can't lookup 'UseSharedSpaces' flag\n");
   2.395 +        return false;
   2.396 +      }
   2.397  
   2.398 -         // Hotspot vm types are not exported to build this library. So
   2.399 -         // using equivalent type jboolean to read the value of
   2.400 -         // UseSharedSpaces which is same as hotspot type "bool".
   2.401 -         if (read_jboolean(ph, useSharedSpacesAddr, &useSharedSpaces) != true) {
   2.402 -            print_debug("can't read the value of 'UseSharedSpaces' flag\n");
   2.403 -            return false;
   2.404 -         }
   2.405 +      // Hotspot vm types are not exported to build this library. So
   2.406 +      // using equivalent type jboolean to read the value of
   2.407 +      // UseSharedSpaces which is same as hotspot type "bool".
   2.408 +      if (read_jboolean(ph, useSharedSpacesAddr, &useSharedSpaces) != true) {
   2.409 +        print_debug("can't read the value of 'UseSharedSpaces' flag\n");
   2.410 +        return false;
   2.411 +      }
   2.412  
   2.413 -         if ((int)useSharedSpaces == 0) {
   2.414 -            print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n");
   2.415 -            return true;
   2.416 -         }
   2.417 +      if ((int)useSharedSpaces == 0) {
   2.418 +        print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n");
   2.419 +        return true;
   2.420 +      }
   2.421  
   2.422 -         sharedArchivePathAddrAddr = lookup_symbol(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM);
   2.423 -         if (sharedArchivePathAddrAddr == 0) {
   2.424 -            print_debug("can't lookup shared archive path symbol\n");
   2.425 -            return false;
   2.426 -         }
   2.427 +      sharedArchivePathAddrAddr = lookup_symbol(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM);
   2.428 +      if (sharedArchivePathAddrAddr == 0) {
   2.429 +        print_debug("can't lookup shared archive path symbol\n");
   2.430 +        return false;
   2.431 +      }
   2.432  
   2.433 -         if (read_pointer(ph, sharedArchivePathAddrAddr, &sharedArchivePathAddr) != true) {
   2.434 -            print_debug("can't read shared archive path pointer\n");
   2.435 -            return false;
   2.436 -         }
   2.437 +      if (read_pointer(ph, sharedArchivePathAddrAddr, &sharedArchivePathAddr) != true) {
   2.438 +        print_debug("can't read shared archive path pointer\n");
   2.439 +        return false;
   2.440 +      }
   2.441  
   2.442 -         if (read_string(ph, sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
   2.443 -            print_debug("can't read shared archive path value\n");
   2.444 -            return false;
   2.445 -         }
   2.446 +      if (read_string(ph, sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
   2.447 +        print_debug("can't read shared archive path value\n");
   2.448 +        return false;
   2.449 +      }
   2.450  
   2.451 -         print_debug("looking for %s\n", classes_jsa);
   2.452 -         // open the class sharing archive file
   2.453 -         fd = pathmap_open(classes_jsa);
   2.454 -         if (fd < 0) {
   2.455 -            print_debug("can't open %s!\n", classes_jsa);
   2.456 -            ph->core->classes_jsa_fd = -1;
   2.457 -            return false;
   2.458 -         } else {
   2.459 -            print_debug("opened %s\n", classes_jsa);
   2.460 -         }
   2.461 +      print_debug("looking for %s\n", classes_jsa);
   2.462 +      // open the class sharing archive file
   2.463 +      fd = pathmap_open(classes_jsa);
   2.464 +      if (fd < 0) {
   2.465 +        print_debug("can't open %s!\n", classes_jsa);
   2.466 +        ph->core->classes_jsa_fd = -1;
   2.467 +        return false;
   2.468 +      } else {
   2.469 +        print_debug("opened %s\n", classes_jsa);
   2.470 +      }
   2.471  
   2.472 -         // read FileMapHeader from the file
   2.473 -         memset(&header, 0, sizeof(struct FileMapHeader));
   2.474 -         if ((n = read(fd, &header, sizeof(struct FileMapHeader)))
   2.475 -              != sizeof(struct FileMapHeader)) {
   2.476 -            print_debug("can't read shared archive file map header from %s\n", classes_jsa);
   2.477 -            close(fd);
   2.478 -            return false;
   2.479 -         }
   2.480 +      // read FileMapHeader from the file
   2.481 +      memset(&header, 0, sizeof(struct FileMapHeader));
   2.482 +      if ((n = read(fd, &header, sizeof(struct FileMapHeader)))
   2.483 +           != sizeof(struct FileMapHeader)) {
   2.484 +        print_debug("can't read shared archive file map header from %s\n", classes_jsa);
   2.485 +        close(fd);
   2.486 +        return false;
   2.487 +      }
   2.488  
   2.489 -         // check file magic
   2.490 -         if (header._magic != 0xf00baba2) {
   2.491 -            print_debug("%s has bad shared archive file magic number 0x%x, expecing 0xf00baba2\n",
   2.492 -                        classes_jsa, header._magic);
   2.493 -            close(fd);
   2.494 -            return false;
   2.495 -         }
   2.496 +      // check file magic
   2.497 +      if (header._magic != 0xf00baba2) {
   2.498 +        print_debug("%s has bad shared archive file magic number 0x%x, expecing 0xf00baba2\n",
   2.499 +                     classes_jsa, header._magic);
   2.500 +        close(fd);
   2.501 +        return false;
   2.502 +      }
   2.503  
   2.504 -         // check version
   2.505 -         if (header._version != CURRENT_ARCHIVE_VERSION) {
   2.506 -            print_debug("%s has wrong shared archive file version %d, expecting %d\n",
   2.507 -                        classes_jsa, header._version, CURRENT_ARCHIVE_VERSION);
   2.508 -            close(fd);
   2.509 -            return false;
   2.510 -         }
   2.511 +      // check version
   2.512 +      if (header._version != CURRENT_ARCHIVE_VERSION) {
   2.513 +        print_debug("%s has wrong shared archive file version %d, expecting %d\n",
   2.514 +                     classes_jsa, header._version, CURRENT_ARCHIVE_VERSION);
   2.515 +        close(fd);
   2.516 +        return false;
   2.517 +      }
   2.518  
   2.519 -         ph->core->classes_jsa_fd = fd;
   2.520 -         // add read-only maps from classes.jsa to the list of maps
   2.521 -         for (m = 0; m < NUM_SHARED_MAPS; m++) {
   2.522 -            if (header._space[m]._read_only) {
   2.523 -               base = (uintptr_t) header._space[m]._base;
   2.524 -               // no need to worry about the fractional pages at-the-end.
   2.525 -               // possible fractional pages are handled by core_read_data.
   2.526 -               add_class_share_map_info(ph, (off_t) header._space[m]._file_offset,
   2.527 -                         base, (size_t) header._space[m]._used);
   2.528 -               print_debug("added a share archive map at 0x%lx\n", base);
   2.529 -            }
   2.530 -         }
   2.531 -         return true;
   2.532 +      ph->core->classes_jsa_fd = fd;
   2.533 +      // add read-only maps from classes.jsa to the list of maps
   2.534 +      for (m = 0; m < NUM_SHARED_MAPS; m++) {
   2.535 +        if (header._space[m]._read_only) {
   2.536 +          base = (uintptr_t) header._space[m]._base;
   2.537 +          // no need to worry about the fractional pages at-the-end.
   2.538 +          // possible fractional pages are handled by core_read_data.
   2.539 +          add_class_share_map_info(ph, (off_t) header._space[m]._file_offset,
   2.540 +                                   base, (size_t) header._space[m]._used);
   2.541 +          print_debug("added a share archive map at 0x%lx\n", base);
   2.542 +        }
   2.543        }
   2.544 -      lib = lib->next;
   2.545 +      return true;
   2.546     }
   2.547 -   return true;
   2.548 +   lib = lib->next;
   2.549 +  }
   2.550 +  return true;
   2.551  }
   2.552  
   2.553  
   2.554 @@ -396,54 +404,58 @@
   2.555  // callback for sorting the array of map_info pointers.
   2.556  static int core_cmp_mapping(const void *lhsp, const void *rhsp)
   2.557  {
   2.558 -   const map_info *lhs = *((const map_info **)lhsp);
   2.559 -   const map_info *rhs = *((const map_info **)rhsp);
   2.560 +  const map_info *lhs = *((const map_info **)lhsp);
   2.561 +  const map_info *rhs = *((const map_info **)rhsp);
   2.562  
   2.563 -   if (lhs->vaddr == rhs->vaddr)
   2.564 -      return (0);
   2.565 +  if (lhs->vaddr == rhs->vaddr) {
   2.566 +    return (0);
   2.567 +  }
   2.568  
   2.569 -   return (lhs->vaddr < rhs->vaddr ? -1 : 1);
   2.570 +  return (lhs->vaddr < rhs->vaddr ? -1 : 1);
   2.571  }
   2.572  
   2.573  // we sort map_info by starting virtual address so that we can do
   2.574  // binary search to read from an address.
   2.575  static bool sort_map_array(struct ps_prochandle* ph) {
   2.576 -   size_t num_maps = ph->core->num_maps;
   2.577 -   map_info* map = ph->core->maps;
   2.578 -   int i = 0;
   2.579 +  size_t num_maps = ph->core->num_maps;
   2.580 +  map_info* map = ph->core->maps;
   2.581 +  int i = 0;
   2.582  
   2.583 -   // allocate map_array
   2.584 -   map_info** array;
   2.585 -   if ( (array = (map_info**) malloc(sizeof(map_info*) * num_maps)) == NULL) {
   2.586 -      print_debug("can't allocate memory for map array\n");
   2.587 -      return false;
   2.588 -   }
   2.589 +  // allocate map_array
   2.590 +  map_info** array;
   2.591 +  if ( (array = (map_info**) malloc(sizeof(map_info*) * num_maps)) == NULL) {
   2.592 +    print_debug("can't allocate memory for map array\n");
   2.593 +    return false;
   2.594 +  }
   2.595  
   2.596 -   // add maps to array
   2.597 -   while (map) {
   2.598 -      array[i] = map;
   2.599 -      i++;
   2.600 -      map = map->next;
   2.601 -   }
   2.602 +  // add maps to array
   2.603 +  while (map) {
   2.604 +    array[i] = map;
   2.605 +    i++;
   2.606 +    map = map->next;
   2.607 +  }
   2.608  
   2.609 -   // sort is called twice. If this is second time, clear map array
   2.610 -   if (ph->core->map_array) free(ph->core->map_array);
   2.611 -   ph->core->map_array = array;
   2.612 -   // sort the map_info array by base virtual address.
   2.613 -   qsort(ph->core->map_array, ph->core->num_maps, sizeof (map_info*),
   2.614 -            core_cmp_mapping);
   2.615 +  // sort is called twice. If this is second time, clear map array
   2.616 +  if (ph->core->map_array) {
   2.617 +    free(ph->core->map_array);
   2.618 +  }
   2.619  
   2.620 -   // print map
   2.621 -   if (is_debug()) {
   2.622 -      int j = 0;
   2.623 -      print_debug("---- sorted virtual address map ----\n");
   2.624 -      for (j = 0; j < ph->core->num_maps; j++) {
   2.625 -        print_debug("base = 0x%lx\tsize = %zu\n", ph->core->map_array[j]->vaddr,
   2.626 -                                         ph->core->map_array[j]->memsz);
   2.627 -      }
   2.628 -   }
   2.629 +  ph->core->map_array = array;
   2.630 +  // sort the map_info array by base virtual address.
   2.631 +  qsort(ph->core->map_array, ph->core->num_maps, sizeof (map_info*),
   2.632 +        core_cmp_mapping);
   2.633  
   2.634 -   return true;
   2.635 +  // print map
   2.636 +  if (is_debug()) {
   2.637 +    int j = 0;
   2.638 +    print_debug("---- sorted virtual address map ----\n");
   2.639 +    for (j = 0; j < ph->core->num_maps; j++) {
   2.640 +      print_debug("base = 0x%lx\tsize = %zu\n", ph->core->map_array[j]->vaddr,
   2.641 +                  ph->core->map_array[j]->memsz);
   2.642 +    }
   2.643 +  }
   2.644 +
   2.645 +  return true;
   2.646  }
   2.647  
   2.648  #ifndef MIN
   2.649 @@ -460,16 +472,18 @@
   2.650        off_t off;
   2.651        int fd;
   2.652  
   2.653 -      if (mp == NULL)
   2.654 +      if (mp == NULL) {
   2.655           break;  /* No mapping for this address */
   2.656 +      }
   2.657  
   2.658        fd = mp->fd;
   2.659        mapoff = addr - mp->vaddr;
   2.660        len = MIN(resid, mp->memsz - mapoff);
   2.661        off = mp->offset + mapoff;
   2.662  
   2.663 -      if ((len = pread(fd, buf, len, off)) <= 0)
   2.664 +      if ((len = pread(fd, buf, len, off)) <= 0) {
   2.665           break;
   2.666 +      }
   2.667  
   2.668        resid -= len;
   2.669        addr += len;
   2.670 @@ -625,8 +639,9 @@
   2.671                                     notep->n_type, notep->n_descsz);
   2.672  
   2.673        if (notep->n_type == NT_PRSTATUS) {
   2.674 -         if (core_handle_prstatus(ph, descdata, notep->n_descsz) != true)
   2.675 -            return false;
   2.676 +        if (core_handle_prstatus(ph, descdata, notep->n_descsz) != true) {
   2.677 +          return false;
   2.678 +        }
   2.679        }
   2.680        p = descdata + ROUNDUP(notep->n_descsz, 4);
   2.681     }
   2.682 @@ -654,7 +669,7 @@
   2.683      * contains a set of saved /proc structures), and PT_LOAD (which
   2.684      * represents a memory mapping from the process's address space).
   2.685      *
   2.686 -    * Difference b/w Solaris PT_NOTE and Linux PT_NOTE:
   2.687 +    * Difference b/w Solaris PT_NOTE and Linux/BSD PT_NOTE:
   2.688      *
   2.689      *     In Solaris there are two PT_NOTE segments the first PT_NOTE (if present)
   2.690      *     contains /proc structs in the pre-2.6 unstructured /proc format. the last
   2.691 @@ -674,7 +689,9 @@
   2.692      for (core_php = phbuf, i = 0; i < core_ehdr->e_phnum; i++) {
   2.693        switch (core_php->p_type) {
   2.694           case PT_NOTE:
   2.695 -            if (core_handle_note(ph, core_php) != true) goto err;
   2.696 +            if (core_handle_note(ph, core_php) != true) {
   2.697 +              goto err;
   2.698 +            }
   2.699              break;
   2.700  
   2.701           case PT_LOAD: {
   2.702 @@ -832,60 +849,62 @@
   2.703  // read shared library info from runtime linker's data structures.
   2.704  // This work is done by librtlb_db in Solaris
   2.705  static bool read_shared_lib_info(struct ps_prochandle* ph) {
   2.706 -   uintptr_t addr = ph->core->dynamic_addr;
   2.707 -   uintptr_t debug_base;
   2.708 -   uintptr_t first_link_map_addr;
   2.709 -   uintptr_t ld_base_addr;
   2.710 -   uintptr_t link_map_addr;
   2.711 -   uintptr_t lib_base_diff;
   2.712 -   uintptr_t lib_base;
   2.713 -   uintptr_t lib_name_addr;
   2.714 -   char lib_name[BUF_SIZE];
   2.715 -   ELF_DYN dyn;
   2.716 -   ELF_EHDR elf_ehdr;
   2.717 -   int lib_fd;
   2.718 +  uintptr_t addr = ph->core->dynamic_addr;
   2.719 +  uintptr_t debug_base;
   2.720 +  uintptr_t first_link_map_addr;
   2.721 +  uintptr_t ld_base_addr;
   2.722 +  uintptr_t link_map_addr;
   2.723 +  uintptr_t lib_base_diff;
   2.724 +  uintptr_t lib_base;
   2.725 +  uintptr_t lib_name_addr;
   2.726 +  char lib_name[BUF_SIZE];
   2.727 +  ELF_DYN dyn;
   2.728 +  ELF_EHDR elf_ehdr;
   2.729 +  int lib_fd;
   2.730  
   2.731 -   // _DYNAMIC has information of the form
   2.732 -   //         [tag] [data] [tag] [data] .....
   2.733 -   // Both tag and data are pointer sized.
   2.734 -   // We look for dynamic info with DT_DEBUG. This has shared object info.
   2.735 -   // refer to struct r_debug in link.h
   2.736 +  // _DYNAMIC has information of the form
   2.737 +  //         [tag] [data] [tag] [data] .....
   2.738 +  // Both tag and data are pointer sized.
   2.739 +  // We look for dynamic info with DT_DEBUG. This has shared object info.
   2.740 +  // refer to struct r_debug in link.h
   2.741  
   2.742 -   dyn.d_tag = DT_NULL;
   2.743 -   while (dyn.d_tag != DT_DEBUG) {
   2.744 -      if (ps_pdread(ph, (psaddr_t) addr, &dyn, sizeof(ELF_DYN)) != PS_OK) {
   2.745 -         print_debug("can't read debug info from _DYNAMIC\n");
   2.746 -         return false;
   2.747 -      }
   2.748 -      addr += sizeof(ELF_DYN);
   2.749 -   }
   2.750 +  dyn.d_tag = DT_NULL;
   2.751 +  while (dyn.d_tag != DT_DEBUG) {
   2.752 +    if (ps_pdread(ph, (psaddr_t) addr, &dyn, sizeof(ELF_DYN)) != PS_OK) {
   2.753 +      print_debug("can't read debug info from _DYNAMIC\n");
   2.754 +      return false;
   2.755 +    }
   2.756 +    addr += sizeof(ELF_DYN);
   2.757 +  }
   2.758  
   2.759 -   // we have got Dyn entry with DT_DEBUG
   2.760 -   debug_base = dyn.d_un.d_ptr;
   2.761 -   // at debug_base we have struct r_debug. This has first link map in r_map field
   2.762 -   if (ps_pdread(ph, (psaddr_t) debug_base + FIRST_LINK_MAP_OFFSET,
   2.763 +  // we have got Dyn entry with DT_DEBUG
   2.764 +  debug_base = dyn.d_un.d_ptr;
   2.765 +  // at debug_base we have struct r_debug. This has first link map in r_map field
   2.766 +  if (ps_pdread(ph, (psaddr_t) debug_base + FIRST_LINK_MAP_OFFSET,
   2.767                   &first_link_map_addr, sizeof(uintptr_t)) != PS_OK) {
   2.768 -      print_debug("can't read first link map address\n");
   2.769 +    print_debug("can't read first link map address\n");
   2.770 +    return false;
   2.771 +  }
   2.772 +
   2.773 +  // read ld_base address from struct r_debug
   2.774 +  if (ps_pdread(ph, (psaddr_t) debug_base + LD_BASE_OFFSET, &ld_base_addr,
   2.775 +                 sizeof(uintptr_t)) != PS_OK) {
   2.776 +    print_debug("can't read ld base address\n");
   2.777 +    return false;
   2.778 +  }
   2.779 +  ph->core->ld_base_addr = ld_base_addr;
   2.780 +
   2.781 +  print_debug("interpreter base address is 0x%lx\n", ld_base_addr);
   2.782 +
   2.783 +  // now read segments from interp (i.e ld.so or ld-linux.so or ld-elf.so)
   2.784 +  if (read_interp_segments(ph) != true) {
   2.785        return false;
   2.786 -   }
   2.787 +  }
   2.788  
   2.789 -   // read ld_base address from struct r_debug
   2.790 -   if (ps_pdread(ph, (psaddr_t) debug_base + LD_BASE_OFFSET, &ld_base_addr,
   2.791 -                 sizeof(uintptr_t)) != PS_OK) {
   2.792 -      print_debug("can't read ld base address\n");
   2.793 -      return false;
   2.794 -   }
   2.795 -   ph->core->ld_base_addr = ld_base_addr;
   2.796 -
   2.797 -   print_debug("interpreter base address is 0x%lx\n", ld_base_addr);
   2.798 -
   2.799 -   // now read segments from interp (i.e ld.so or ld-linux.so)
   2.800 -   if (read_interp_segments(ph) != true)
   2.801 -      return false;
   2.802 -
   2.803 -   // after adding interpreter (ld.so) mappings sort again
   2.804 -   if (sort_map_array(ph) != true)
   2.805 -      return false;
   2.806 +  // after adding interpreter (ld.so) mappings sort again
   2.807 +  if (sort_map_array(ph) != true) {
   2.808 +    return false;
   2.809 +  }
   2.810  
   2.811     print_debug("first link map is at 0x%lx\n", first_link_map_addr);
   2.812  
   2.813 @@ -950,95 +969,102 @@
   2.814           }
   2.815        }
   2.816  
   2.817 -      // read next link_map address
   2.818 -      if (ps_pdread(ph, (psaddr_t) link_map_addr + LINK_MAP_NEXT_OFFSET,
   2.819 -                        &link_map_addr, sizeof(uintptr_t)) != PS_OK) {
   2.820 -         print_debug("can't read next link in link_map\n");
   2.821 -         return false;
   2.822 -      }
   2.823 -   }
   2.824 +    // read next link_map address
   2.825 +    if (ps_pdread(ph, (psaddr_t) link_map_addr + LINK_MAP_NEXT_OFFSET,
   2.826 +                   &link_map_addr, sizeof(uintptr_t)) != PS_OK) {
   2.827 +      print_debug("can't read next link in link_map\n");
   2.828 +      return false;
   2.829 +    }
   2.830 +  }
   2.831  
   2.832 -   return true;
   2.833 +  return true;
   2.834  }
   2.835  
   2.836  // the one and only one exposed stuff from this file
   2.837  struct ps_prochandle* Pgrab_core(const char* exec_file, const char* core_file) {
   2.838 -   ELF_EHDR core_ehdr;
   2.839 -   ELF_EHDR exec_ehdr;
   2.840 -   ELF_EHDR lib_ehdr;
   2.841 +  ELF_EHDR core_ehdr;
   2.842 +  ELF_EHDR exec_ehdr;
   2.843 +  ELF_EHDR lib_ehdr;
   2.844  
   2.845 -   struct ps_prochandle* ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle));
   2.846 -   if (ph == NULL) {
   2.847 -      print_debug("can't allocate ps_prochandle\n");
   2.848 -      return NULL;
   2.849 -   }
   2.850 +  struct ps_prochandle* ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle));
   2.851 +  if (ph == NULL) {
   2.852 +    print_debug("can't allocate ps_prochandle\n");
   2.853 +    return NULL;
   2.854 +  }
   2.855  
   2.856 -   if ((ph->core = (struct core_data*) calloc(1, sizeof(struct core_data))) == NULL) {
   2.857 -      free(ph);
   2.858 -      print_debug("can't allocate ps_prochandle\n");
   2.859 -      return NULL;
   2.860 -   }
   2.861 +  if ((ph->core = (struct core_data*) calloc(1, sizeof(struct core_data))) == NULL) {
   2.862 +    free(ph);
   2.863 +    print_debug("can't allocate ps_prochandle\n");
   2.864 +    return NULL;
   2.865 +  }
   2.866  
   2.867 -   // initialize ph
   2.868 -   ph->ops = &core_ops;
   2.869 -   ph->core->core_fd   = -1;
   2.870 -   ph->core->exec_fd   = -1;
   2.871 -   ph->core->interp_fd = -1;
   2.872 +  // initialize ph
   2.873 +  ph->ops = &core_ops;
   2.874 +  ph->core->core_fd   = -1;
   2.875 +  ph->core->exec_fd   = -1;
   2.876 +  ph->core->interp_fd = -1;
   2.877  
   2.878 -   // open the core file
   2.879 -   if ((ph->core->core_fd = open(core_file, O_RDONLY)) < 0) {
   2.880 -      print_debug("can't open core file\n");
   2.881 -      goto err;
   2.882 -   }
   2.883 +  // open the core file
   2.884 +  if ((ph->core->core_fd = open(core_file, O_RDONLY)) < 0) {
   2.885 +    print_debug("can't open core file\n");
   2.886 +    goto err;
   2.887 +  }
   2.888  
   2.889 -   // read core file ELF header
   2.890 -   if (read_elf_header(ph->core->core_fd, &core_ehdr) != true || core_ehdr.e_type != ET_CORE) {
   2.891 -      print_debug("core file is not a valid ELF ET_CORE file\n");
   2.892 -      goto err;
   2.893 -   }
   2.894 +  // read core file ELF header
   2.895 +  if (read_elf_header(ph->core->core_fd, &core_ehdr) != true || core_ehdr.e_type != ET_CORE) {
   2.896 +    print_debug("core file is not a valid ELF ET_CORE file\n");
   2.897 +    goto err;
   2.898 +  }
   2.899  
   2.900 -   if ((ph->core->exec_fd = open(exec_file, O_RDONLY)) < 0) {
   2.901 -      print_debug("can't open executable file\n");
   2.902 -      goto err;
   2.903 -   }
   2.904 +  if ((ph->core->exec_fd = open(exec_file, O_RDONLY)) < 0) {
   2.905 +    print_debug("can't open executable file\n");
   2.906 +    goto err;
   2.907 +  }
   2.908  
   2.909 -   if (read_elf_header(ph->core->exec_fd, &exec_ehdr) != true || exec_ehdr.e_type != ET_EXEC) {
   2.910 -      print_debug("executable file is not a valid ELF ET_EXEC file\n");
   2.911 -      goto err;
   2.912 -   }
   2.913 +  if (read_elf_header(ph->core->exec_fd, &exec_ehdr) != true || exec_ehdr.e_type != ET_EXEC) {
   2.914 +    print_debug("executable file is not a valid ELF ET_EXEC file\n");
   2.915 +    goto err;
   2.916 +  }
   2.917  
   2.918 -   // process core file segments
   2.919 -   if (read_core_segments(ph, &core_ehdr) != true)
   2.920 -      goto err;
   2.921 +  // process core file segments
   2.922 +  if (read_core_segments(ph, &core_ehdr) != true) {
   2.923 +    goto err;
   2.924 +  }
   2.925  
   2.926 -   // process exec file segments
   2.927 -   if (read_exec_segments(ph, &exec_ehdr) != true)
   2.928 -      goto err;
   2.929 +  // process exec file segments
   2.930 +  if (read_exec_segments(ph, &exec_ehdr) != true) {
   2.931 +    goto err;
   2.932 +  }
   2.933  
   2.934 -   // exec file is also treated like a shared object for symbol search
   2.935 -   if (add_lib_info_fd(ph, exec_file, ph->core->exec_fd,
   2.936 -                       (uintptr_t)0 + find_base_address(ph->core->exec_fd, &exec_ehdr)) == NULL)
   2.937 -      goto err;
   2.938 +  // exec file is also treated like a shared object for symbol search
   2.939 +  if (add_lib_info_fd(ph, exec_file, ph->core->exec_fd,
   2.940 +                      (uintptr_t)0 + find_base_address(ph->core->exec_fd, &exec_ehdr)) == NULL) {
   2.941 +    goto err;
   2.942 +  }
   2.943  
   2.944 -   // allocate and sort maps into map_array, we need to do this
   2.945 -   // here because read_shared_lib_info needs to read from debuggee
   2.946 -   // address space
   2.947 -   if (sort_map_array(ph) != true)
   2.948 -      goto err;
   2.949 +  // allocate and sort maps into map_array, we need to do this
   2.950 +  // here because read_shared_lib_info needs to read from debuggee
   2.951 +  // address space
   2.952 +  if (sort_map_array(ph) != true) {
   2.953 +    goto err;
   2.954 +  }
   2.955  
   2.956 -   if (read_shared_lib_info(ph) != true)
   2.957 -      goto err;
   2.958 +  if (read_shared_lib_info(ph) != true) {
   2.959 +    goto err;
   2.960 +  }
   2.961  
   2.962 -   // sort again because we have added more mappings from shared objects
   2.963 -   if (sort_map_array(ph) != true)
   2.964 -      goto err;
   2.965 +  // sort again because we have added more mappings from shared objects
   2.966 +  if (sort_map_array(ph) != true) {
   2.967 +    goto err;
   2.968 +  }
   2.969  
   2.970 -   if (init_classsharing_workaround(ph) != true)
   2.971 -      goto err;
   2.972 +  if (init_classsharing_workaround(ph) != true) {
   2.973 +    goto err;
   2.974 +  }
   2.975  
   2.976 -   return ph;
   2.977 +  return ph;
   2.978  
   2.979  err:
   2.980 -   Prelease(ph);
   2.981 -   return NULL;
   2.982 +  Prelease(ph);
   2.983 +  return NULL;
   2.984  }

mercurial