Print this page
3946 ::gcore
Reviewed by: Adam Leventhal <ahl@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>


   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */



  25 
  26 #include <stdlib.h>
  27 #include <libelf.h>
  28 #include <libgen.h>
  29 #include <string.h>
  30 #include <strings.h>
  31 #include <errno.h>
  32 #include <sys/sysmacros.h>
  33 
  34 #include "libproc.h"
  35 #include "Pcontrol.h"
  36 

  37 static ssize_t
  38 Pread_idle(struct ps_prochandle *P, void *buf, size_t n, uintptr_t addr)

  39 {
  40         size_t resid = n;
  41 
  42         while (resid > 0) {
  43                 map_info_t *mp;
  44                 uintptr_t mapoff;
  45                 ssize_t len;
  46                 off64_t off;
  47 
  48                 if ((mp = Paddr2mptr(P, addr)) == NULL)
  49                         break;
  50 
  51                 mapoff = addr - mp->map_pmap.pr_vaddr;
  52                 len = MIN(resid, mp->map_pmap.pr_size - mapoff);
  53                 off = mp->map_offset + mapoff;
  54 
  55                 if ((len = pread64(P->asfd, buf, len, off)) <= 0)
  56                         break;
  57 
  58                 resid -= len;
  59                 addr += len;
  60                 buf = (char *)buf + len;
  61         }
  62 
  63         return (n - resid);
  64 }
  65 
  66 /*ARGSUSED*/
  67 static ssize_t
  68 Pwrite_idle(struct ps_prochandle *P, const void *buf, size_t n, uintptr_t addr)

  69 {
  70         errno = EIO;
  71         return (-1);
  72 }
  73 
  74 static const ps_rwops_t P_idle_ops = {
  75         Pread_idle,
  76         Pwrite_idle







































  77 };
  78 
  79 static int
  80 idle_add_mapping(struct ps_prochandle *P, GElf_Phdr *php, file_info_t *fp)
  81 {
  82         prmap_t pmap;
  83 
  84         dprintf("mapping base %llx filesz %llu memsz %llu offset %llu\n",
  85             (u_longlong_t)php->p_vaddr, (u_longlong_t)php->p_filesz,
  86             (u_longlong_t)php->p_memsz, (u_longlong_t)php->p_offset);
  87 
  88         pmap.pr_vaddr = (uintptr_t)php->p_vaddr;
  89         pmap.pr_size = php->p_filesz;
  90         (void) strncpy(pmap.pr_mapname, fp->file_pname,
  91             sizeof (pmap.pr_mapname));
  92         pmap.pr_offset = php->p_offset;
  93 
  94         pmap.pr_mflags = 0;
  95         if (php->p_flags & PF_R)
  96                 pmap.pr_mflags |= MA_READ;


 126         if (elf_version(EV_CURRENT) == EV_NONE) {
 127                 dprintf("libproc ELF version is more recent than libelf");
 128                 *perr = G_ELF;
 129                 goto err;
 130         }
 131 
 132         if ((P = calloc(1, sizeof (struct ps_prochandle))) == NULL) {
 133                 *perr = G_STRANGE;
 134                 goto err;
 135         }
 136 
 137         (void) mutex_init(&P->proc_lock, USYNC_THREAD, NULL);
 138         P->state = PS_IDLE;
 139         P->pid = (pid_t)-1;
 140         P->asfd = fd;
 141         P->ctlfd = -1;
 142         P->statfd = -1;
 143         P->agentctlfd = -1;
 144         P->agentstatfd = -1;
 145         P->info_valid = -1;
 146         P->ops = &P_idle_ops;
 147         Pinitsym(P);
 148 
 149         if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
 150                 *perr = G_ELF;
 151                 return (NULL);
 152         }
 153 
 154         /*
 155          * Construct a file_info_t that corresponds to this file.
 156          */
 157         if ((fp = calloc(1, sizeof (file_info_t))) == NULL) {
 158                 *perr = G_STRANGE;
 159                 goto err;
 160         }
 161 
 162         if ((fp->file_lo = calloc(1, sizeof (rd_loadobj_t))) == NULL) {
 163                 *perr = G_STRANGE;
 164                 goto err;
 165         }
 166 




   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 /*
  26  * Copyright (c) 2013 by Delphix. All rights reserved.
  27  */
  28 
  29 #include <stdlib.h>
  30 #include <libelf.h>
  31 #include <libgen.h>
  32 #include <string.h>
  33 #include <strings.h>
  34 #include <errno.h>
  35 #include <sys/sysmacros.h>
  36 
  37 #include "libproc.h"
  38 #include "Pcontrol.h"
  39 
  40 /*ARGSUSED*/
  41 static ssize_t
  42 Pread_idle(struct ps_prochandle *P, void *buf, size_t n, uintptr_t addr,
  43     void *data)
  44 {
  45         size_t resid = n;
  46 
  47         while (resid > 0) {
  48                 map_info_t *mp;
  49                 uintptr_t mapoff;
  50                 ssize_t len;
  51                 off64_t off;
  52 
  53                 if ((mp = Paddr2mptr(P, addr)) == NULL)
  54                         break;
  55 
  56                 mapoff = addr - mp->map_pmap.pr_vaddr;
  57                 len = MIN(resid, mp->map_pmap.pr_size - mapoff);
  58                 off = mp->map_offset + mapoff;
  59 
  60                 if ((len = pread64(P->asfd, buf, len, off)) <= 0)
  61                         break;
  62 
  63                 resid -= len;
  64                 addr += len;
  65                 buf = (char *)buf + len;
  66         }
  67 
  68         return (n - resid);
  69 }
  70 
  71 /*ARGSUSED*/
  72 static ssize_t
  73 Pwrite_idle(struct ps_prochandle *P, const void *buf, size_t n, uintptr_t addr,
  74     void *data)
  75 {
  76         errno = EIO;
  77         return (-1);
  78 }
  79 
  80 /*ARGSUSED*/
  81 static int
  82 Ppriv_idle(struct ps_prochandle *P, prpriv_t **pprv, void *data)
  83 {
  84         prpriv_t *pp;
  85 
  86         pp = proc_get_priv(P->pid);
  87         if (pp == NULL) {
  88                 return (-1);
  89         }
  90 
  91         *pprv = pp;
  92         return (0);
  93 }
  94 
  95 /* Default operations for the idl ops vector. */
  96 static void *
  97 Pidle_voidp()
  98 {
  99         errno = ENODATA;
 100         return (NULL);
 101 }
 102 
 103 static int
 104 Pidle_int()
 105 {
 106         errno = ENODATA;
 107         return (-1);
 108 }
 109 
 110 static const ps_ops_t P_idle_ops = {
 111         .pop_pread      = Pread_idle,
 112         .pop_pwrite     = Pwrite_idle,
 113         .pop_cred       = (pop_cred_t)Pidle_int,
 114         .pop_priv       = Ppriv_idle,
 115         .pop_psinfo     = (pop_psinfo_t)Pidle_voidp,
 116         .pop_platform   = (pop_platform_t)Pidle_voidp,
 117         .pop_uname      = (pop_uname_t)Pidle_int,
 118         .pop_zonename   = (pop_zonename_t)Pidle_voidp,
 119 #if defined(__i386) || defined(__amd64)
 120         .pop_ldt        = (pop_ldt_t)Pidle_int
 121 #endif
 122 };
 123 
 124 static int
 125 idle_add_mapping(struct ps_prochandle *P, GElf_Phdr *php, file_info_t *fp)
 126 {
 127         prmap_t pmap;
 128 
 129         dprintf("mapping base %llx filesz %llu memsz %llu offset %llu\n",
 130             (u_longlong_t)php->p_vaddr, (u_longlong_t)php->p_filesz,
 131             (u_longlong_t)php->p_memsz, (u_longlong_t)php->p_offset);
 132 
 133         pmap.pr_vaddr = (uintptr_t)php->p_vaddr;
 134         pmap.pr_size = php->p_filesz;
 135         (void) strncpy(pmap.pr_mapname, fp->file_pname,
 136             sizeof (pmap.pr_mapname));
 137         pmap.pr_offset = php->p_offset;
 138 
 139         pmap.pr_mflags = 0;
 140         if (php->p_flags & PF_R)
 141                 pmap.pr_mflags |= MA_READ;


 171         if (elf_version(EV_CURRENT) == EV_NONE) {
 172                 dprintf("libproc ELF version is more recent than libelf");
 173                 *perr = G_ELF;
 174                 goto err;
 175         }
 176 
 177         if ((P = calloc(1, sizeof (struct ps_prochandle))) == NULL) {
 178                 *perr = G_STRANGE;
 179                 goto err;
 180         }
 181 
 182         (void) mutex_init(&P->proc_lock, USYNC_THREAD, NULL);
 183         P->state = PS_IDLE;
 184         P->pid = (pid_t)-1;
 185         P->asfd = fd;
 186         P->ctlfd = -1;
 187         P->statfd = -1;
 188         P->agentctlfd = -1;
 189         P->agentstatfd = -1;
 190         P->info_valid = -1;
 191         Pinit_ops(&P->ops, &P_idle_ops);
 192         Pinitsym(P);
 193 
 194         if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
 195                 *perr = G_ELF;
 196                 return (NULL);
 197         }
 198 
 199         /*
 200          * Construct a file_info_t that corresponds to this file.
 201          */
 202         if ((fp = calloc(1, sizeof (file_info_t))) == NULL) {
 203                 *perr = G_STRANGE;
 204                 goto err;
 205         }
 206 
 207         if ((fp->file_lo = calloc(1, sizeof (rd_loadobj_t))) == NULL) {
 208                 *perr = G_STRANGE;
 209                 goto err;
 210         }
 211