1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 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 /* 23 * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <unistd.h> 29 #include <sys/uio.h> 30 #include <fcntl.h> 31 #include <string.h> 32 #include <errno.h> 33 #include <sys/types.h> 34 #include <sys/signal.h> 35 #include <sys/fault.h> 36 #include <sys/syscall.h> 37 #include <procfs.h> 38 #include <sys/auxv.h> 39 #include <sys/stat.h> 40 #include <sys/mman.h> 41 #include <libelf.h> 42 #include <sys/param.h> 43 #include <sys/machelf.h> 44 #include <stdarg.h> 45 46 #include <proc_service.h> 47 48 #include "rdb.h" 49 #include "disasm.h" 50 51 #if !defined(_LP64) 52 static void 53 gelf_sym_to_elf32(GElf_Sym *src, Elf32_Sym *dst) 54 { 55 dst->st_name = src->st_name; 56 dst->st_value = src->st_value; 57 dst->st_size = src->st_size; 58 dst->st_info = ELF32_ST_INFO(GELF_ST_BIND(src->st_info), 59 GELF_ST_TYPE(src->st_info)); 60 dst->st_other = src->st_other; 61 dst->st_shndx = src->st_shndx; 62 } 63 #endif 64 65 #define PROCSIZE 20 66 67 static void 68 get_ldbase(struct ps_prochandle *procp) 69 { 70 int pauxvfd; 71 char pname[PROCSIZE]; 72 struct stat stbuf; 73 void *auxvptr, *auxvtail; 74 auxv_t *auxvp; 75 uint_t entsize; 76 77 (void) snprintf(pname, PROCSIZE, "/proc/%d/auxv", 78 EC_SWORD(procp->pp_pid)); 79 if ((pauxvfd = open(pname, O_RDONLY)) == -1) 80 perr("open auxv"); 81 82 if (fstat(pauxvfd, &stbuf) == -1) 83 perr("stat auxv"); 84 85 auxvptr = malloc(stbuf.st_size); 86 if (read(pauxvfd, auxvptr, stbuf.st_size) == -1) 87 perr("gldb: reading auxv"); 88 89 (void) close(pauxvfd); 90 91 procp->pp_auxvp = auxvptr; 92 auxvtail = (void *)((uintptr_t)auxvptr + stbuf.st_size); 93 94 #if defined(_LP64) 95 if (procp->pp_dmodel == PR_MODEL_ILP32) 96 entsize = sizeof (auxv32_t); 97 else 98 #endif 99 entsize = sizeof (auxv_t); 100 101 while (auxvptr < auxvtail) { 102 auxvp = auxvptr; 103 if (auxvp->a_type == AT_BASE) { 104 #if defined(_LP64) 105 if (procp->pp_dmodel == PR_MODEL_ILP32) 106 procp->pp_ldsobase = 107 ((uintptr_t)((auxv32_t *)auxvp)-> 108 a_un.a_val); 109 else 110 #endif 111 procp->pp_ldsobase = auxvp->a_un.a_val; 112 } else if (auxvp->a_type == AT_PHDR) { 113 #if defined(_LP64) 114 if (procp->pp_dmodel == PR_MODEL_ILP32) 115 procp->pp_execphdr = 116 ((uintptr_t)((auxv32_t *)auxvp)-> 117 a_un.a_val); 118 else 119 #endif 120 procp->pp_execphdr = auxvp->a_un.a_val; 121 } 122 auxvptr = (void *)((uintptr_t)auxvptr + entsize); 123 } 124 } 125 126 retc_t 127 ps_init(int pctlfd, int pstatusfd, pid_t pid, struct ps_prochandle *procp) 128 { 129 rd_notify_t rd_notify; 130 char procname[PROCSIZE]; 131 long oper, pflags; 132 struct iovec piov[2]; 133 134 procp->pp_pid = pid; 135 procp->pp_ctlfd = pctlfd; 136 procp->pp_statusfd = pstatusfd; 137 138 (void) snprintf(procname, PROCSIZE, "/proc/%d/map", 139 EC_SWORD(procp->pp_pid)); 140 if ((procp->pp_mapfd = open(procname, O_RDONLY)) == -1) 141 perr("psi: open of /proc/dpid/map failed"); 142 143 (void) snprintf(procname, PROCSIZE, "/proc/%d/as", 144 EC_SWORD(procp->pp_pid)); 145 if ((procp->pp_asfd = open(procname, O_RDWR)) == -1) 146 perr("psi: open of /proc/dpid/as failed"); 147 148 if (ps_pdmodel(procp, &procp->pp_dmodel) != PS_OK) 149 perr("psi: data model"); 150 151 #if !defined(_LP64) 152 if (procp->pp_dmodel == PR_MODEL_LP64) 153 perr("psi: run 64-bit rdb to debug a 64-bit process"); 154 #endif 155 get_ldbase(procp); 156 157 (void) load_map(procp, (caddr_t)procp->pp_ldsobase, 158 &(procp->pp_ldsomap)); 159 procp->pp_ldsomap.mi_addr += procp->pp_ldsobase; 160 procp->pp_ldsomap.mi_end += procp->pp_ldsobase; 161 procp->pp_ldsomap.mi_name = "<procfs: interp>"; 162 163 (void) load_map(procp, (caddr_t)procp->pp_execphdr, 164 &(procp->pp_execmap)); 165 procp->pp_execmap.mi_name = "<procfs: exec>"; 166 167 procp->pp_breakpoints = NULL; 168 procp->pp_flags = FLG_PP_PACT | FLG_PP_PLTSKIP; 169 procp->pp_lmaplist.ml_head = NULL; 170 procp->pp_lmaplist.ml_tail = NULL; 171 if ((procp->pp_rap = rd_new(procp)) == NULL) { 172 (void) fprintf(stderr, "rdb: rtld_db: rd_new() call failed\n"); 173 exit(1); 174 } 175 (void) rd_event_enable(procp->pp_rap, 1); 176 177 /* 178 * For those architectures that increment the PC on 179 * a breakpoint fault we enable the PR_BPTADJ adjustments. 180 */ 181 oper = PCSET; 182 pflags = PR_BPTADJ; 183 piov[0].iov_base = (caddr_t)(&oper); 184 piov[0].iov_len = sizeof (oper); 185 piov[1].iov_base = (caddr_t)(&pflags); 186 piov[1].iov_len = sizeof (pflags); 187 if (writev(procp->pp_ctlfd, piov, 2) == -1) 188 perr("psinit: PCSET(PR_BTPADJ)"); 189 190 /* 191 * Set breakpoints for special handshakes between librtld_db.so 192 * and the debugger. These include: 193 * PREINIT - before .init processing. 194 * POSTINIT - after .init processing 195 * DLACTIVITY - link_maps status has changed 196 */ 197 if (rd_event_addr(procp->pp_rap, RD_PREINIT, &rd_notify) == RD_OK) { 198 if (set_breakpoint(procp, rd_notify.u.bptaddr, 199 FLG_BP_RDPREINIT) != RET_OK) 200 (void) fprintf(stderr, 201 "psi: failed to set BP for preinit at: 0x%lx\n", 202 rd_notify.u.bptaddr); 203 } else 204 (void) fprintf(stderr, "psi: no event registered for " 205 "preinit\n"); 206 207 if (rd_event_addr(procp->pp_rap, RD_POSTINIT, &rd_notify) == RD_OK) { 208 if (set_breakpoint(procp, rd_notify.u.bptaddr, 209 FLG_BP_RDPOSTINIT) != RET_OK) 210 (void) fprintf(stderr, 211 "psi: failed to set BP for postinit at: 0x%lx\n", 212 rd_notify.u.bptaddr); 213 } else 214 (void) fprintf(stderr, "psi: no event registered for " 215 "postinit\n"); 216 217 if (rd_event_addr(procp->pp_rap, RD_DLACTIVITY, &rd_notify) == RD_OK) { 218 if (set_breakpoint(procp, rd_notify.u.bptaddr, 219 FLG_BP_RDDLACT) != RET_OK) 220 (void) fprintf(stderr, 221 "psi: failed to set BP for dlact at: 0x%lx\n", 222 rd_notify.u.bptaddr); 223 } else 224 (void) fprintf(stderr, "psi: no event registered for dlact\n"); 225 226 return (RET_OK); 227 } 228 229 retc_t 230 ps_close(struct ps_prochandle *ph) 231 { 232 (void) delete_all_breakpoints(ph); 233 234 if (ph->pp_auxvp) 235 free(ph->pp_auxvp); 236 free_linkmaps(ph); 237 return (RET_OK); 238 } 239 240 ps_err_e 241 ps_pauxv(struct ps_prochandle *ph, const auxv_t **auxvp) 242 { 243 *auxvp = ph->pp_auxvp; 244 return (PS_OK); 245 } 246 247 ps_err_e 248 ps_pdmodel(struct ps_prochandle *ph, int *dm) 249 { 250 pstatus_t pstatus; 251 252 if (pread(ph->pp_statusfd, &pstatus, sizeof (pstatus), 0) == -1) 253 return (PS_ERR); 254 255 *dm = (int)pstatus.pr_dmodel; 256 return (PS_OK); 257 } 258 259 ps_err_e 260 ps_pread(struct ps_prochandle *ph, psaddr_t addr, void *buf, size_t size) 261 { 262 if (pread(ph->pp_asfd, buf, size, (off_t)addr) != size) 263 return (PS_ERR); 264 265 return (PS_OK); 266 } 267 268 ps_err_e 269 ps_pwrite(struct ps_prochandle *ph, psaddr_t addr, const void *buf, size_t size) 270 { 271 if (pwrite(ph->pp_asfd, buf, size, (off_t)addr) != size) 272 return (PS_ERR); 273 274 return (PS_OK); 275 } 276 277 ps_err_e 278 ps_pglobal_sym(struct ps_prochandle *ph, const char *object_name, 279 const char *sym_name, ps_sym_t *symp) 280 { 281 map_info_t *mip; 282 GElf_Sym gsym; 283 284 if ((mip = str_to_map(ph, object_name)) == NULL) 285 return (PS_ERR); 286 287 if (str_map_sym(sym_name, mip, &gsym, NULL) == RET_FAILED) 288 return (PS_ERR); 289 290 #if defined(_LP64) 291 *symp = gsym; 292 #else 293 gelf_sym_to_elf32(&gsym, (Elf32_Sym *)symp); 294 #endif 295 296 return (PS_OK); 297 } 298 299 ps_err_e 300 ps_pglobal_lookup(struct ps_prochandle *ph, const char *object_name, 301 const char *sym_name, ulong_t *sym_addr) 302 { 303 GElf_Sym sym; 304 map_info_t *mip; 305 306 if ((mip = str_to_map(ph, object_name)) == NULL) 307 return (PS_ERR); 308 309 if (str_map_sym(sym_name, mip, &sym, NULL) == RET_FAILED) 310 return (PS_ERR); 311 312 *sym_addr = sym.st_value; 313 314 return (PS_OK); 315 } 316 317 ps_err_e 318 ps_lgetregs(struct ps_prochandle *ph, lwpid_t lid, prgregset_t gregset) 319 { 320 char procname[MAXPATHLEN]; 321 int lwpfd; 322 lwpstatus_t lwpstatus; 323 324 (void) snprintf(procname, MAXPATHLEN - 1, 325 "/proc/%d/lwp/%d/lwpstatus", EC_SWORD(ph->pp_pid), EC_SWORD(lid)); 326 327 if ((lwpfd = open(procname, O_RDONLY)) == -1) 328 return (PS_ERR); 329 330 if (read(lwpfd, &lwpstatus, sizeof (lwpstatus)) == -1) 331 return (PS_ERR); 332 333 gregset = lwpstatus.pr_reg; 334 335 (void) close(lwpfd); 336 return (PS_OK); 337 } 338 339 void 340 ps_plog(const char *fmt, ...) 341 { 342 va_list args; 343 static FILE *log_fp = NULL; 344 345 if (log_fp == NULL) { 346 char log_fname[256]; 347 (void) sprintf(log_fname, "/tmp/tdlog.%d", EC_SWORD(getpid())); 348 if ((log_fp = fopen(log_fname, "w")) == NULL) { 349 /* 350 * Unable to open log file - default to stderr. 351 */ 352 (void) fprintf(stderr, "unable to open %s, logging " 353 "redirected to stderr", log_fname); 354 log_fp = stderr; 355 } 356 } 357 358 va_start(args, fmt); 359 (void) vfprintf(log_fp, fmt, args); 360 va_end(args); 361 (void) fputc('\n', log_fp); 362 (void) fflush(log_fp); 363 } 364 365 /* ARGSUSED0 */ 366 ps_err_e 367 ps_pbrandname(struct ps_prochandle *P, char *buf, size_t len) 368 { 369 return (PS_ERR); 370 } 371