17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
59039eeafSab * Common Development and Distribution License (the "License").
69039eeafSab * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
2120c1c355SRod Evans
227c478bd9Sstevel@tonic-gate /*
2320c1c355SRod Evans * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate #include <stdio.h>
277c478bd9Sstevel@tonic-gate #include <stdlib.h>
287c478bd9Sstevel@tonic-gate #include <unistd.h>
297c478bd9Sstevel@tonic-gate #include <sys/uio.h>
307c478bd9Sstevel@tonic-gate #include <fcntl.h>
317c478bd9Sstevel@tonic-gate #include <string.h>
327c478bd9Sstevel@tonic-gate #include <errno.h>
337c478bd9Sstevel@tonic-gate #include <sys/types.h>
347c478bd9Sstevel@tonic-gate #include <sys/signal.h>
357c478bd9Sstevel@tonic-gate #include <sys/fault.h>
367c478bd9Sstevel@tonic-gate #include <sys/syscall.h>
377c478bd9Sstevel@tonic-gate #include <procfs.h>
387c478bd9Sstevel@tonic-gate #include <sys/auxv.h>
397c478bd9Sstevel@tonic-gate #include <sys/stat.h>
407c478bd9Sstevel@tonic-gate #include <sys/mman.h>
417c478bd9Sstevel@tonic-gate #include <libelf.h>
427c478bd9Sstevel@tonic-gate #include <sys/param.h>
4320c1c355SRod Evans #include <sys/machelf.h>
447c478bd9Sstevel@tonic-gate #include <stdarg.h>
457c478bd9Sstevel@tonic-gate
467c478bd9Sstevel@tonic-gate #include <proc_service.h>
477c478bd9Sstevel@tonic-gate
487c478bd9Sstevel@tonic-gate #include "rdb.h"
497c478bd9Sstevel@tonic-gate #include "disasm.h"
507c478bd9Sstevel@tonic-gate
517c478bd9Sstevel@tonic-gate #if !defined(_LP64)
527c478bd9Sstevel@tonic-gate static void
gelf_sym_to_elf32(GElf_Sym * src,Elf32_Sym * dst)539039eeafSab gelf_sym_to_elf32(GElf_Sym *src, Elf32_Sym *dst)
547c478bd9Sstevel@tonic-gate {
557c478bd9Sstevel@tonic-gate dst->st_name = src->st_name;
5620c1c355SRod Evans dst->st_value = src->st_value;
5720c1c355SRod Evans dst->st_size = src->st_size;
587c478bd9Sstevel@tonic-gate dst->st_info = ELF32_ST_INFO(GELF_ST_BIND(src->st_info),
5920c1c355SRod Evans GELF_ST_TYPE(src->st_info));
607c478bd9Sstevel@tonic-gate dst->st_other = src->st_other;
617c478bd9Sstevel@tonic-gate dst->st_shndx = src->st_shndx;
627c478bd9Sstevel@tonic-gate }
637c478bd9Sstevel@tonic-gate #endif
647c478bd9Sstevel@tonic-gate
6520c1c355SRod Evans #define PROCSIZE 20
6620c1c355SRod Evans
677c478bd9Sstevel@tonic-gate static void
get_ldbase(struct ps_prochandle * procp)689039eeafSab get_ldbase(struct ps_prochandle *procp)
697c478bd9Sstevel@tonic-gate {
707c478bd9Sstevel@tonic-gate int pauxvfd;
7120c1c355SRod Evans char pname[PROCSIZE];
727c478bd9Sstevel@tonic-gate struct stat stbuf;
739039eeafSab void *auxvptr, *auxvtail;
749039eeafSab auxv_t *auxvp;
757c478bd9Sstevel@tonic-gate uint_t entsize;
767c478bd9Sstevel@tonic-gate
7720c1c355SRod Evans (void) snprintf(pname, PROCSIZE, "/proc/%d/auxv",
7820c1c355SRod Evans EC_SWORD(procp->pp_pid));
797c478bd9Sstevel@tonic-gate if ((pauxvfd = open(pname, O_RDONLY)) == -1)
807c478bd9Sstevel@tonic-gate perr("open auxv");
817c478bd9Sstevel@tonic-gate
827c478bd9Sstevel@tonic-gate if (fstat(pauxvfd, &stbuf) == -1)
837c478bd9Sstevel@tonic-gate perr("stat auxv");
847c478bd9Sstevel@tonic-gate
857c478bd9Sstevel@tonic-gate auxvptr = malloc(stbuf.st_size);
867c478bd9Sstevel@tonic-gate if (read(pauxvfd, auxvptr, stbuf.st_size) == -1)
877c478bd9Sstevel@tonic-gate perr("gldb: reading auxv");
887c478bd9Sstevel@tonic-gate
8920c1c355SRod Evans (void) close(pauxvfd);
907c478bd9Sstevel@tonic-gate
917c478bd9Sstevel@tonic-gate procp->pp_auxvp = auxvptr;
927c478bd9Sstevel@tonic-gate auxvtail = (void *)((uintptr_t)auxvptr + stbuf.st_size);
937c478bd9Sstevel@tonic-gate
947c478bd9Sstevel@tonic-gate #if defined(_LP64)
957c478bd9Sstevel@tonic-gate if (procp->pp_dmodel == PR_MODEL_ILP32)
967c478bd9Sstevel@tonic-gate entsize = sizeof (auxv32_t);
977c478bd9Sstevel@tonic-gate else
987c478bd9Sstevel@tonic-gate #endif
997c478bd9Sstevel@tonic-gate entsize = sizeof (auxv_t);
1007c478bd9Sstevel@tonic-gate
1017c478bd9Sstevel@tonic-gate while (auxvptr < auxvtail) {
1027c478bd9Sstevel@tonic-gate auxvp = auxvptr;
1037c478bd9Sstevel@tonic-gate if (auxvp->a_type == AT_BASE) {
1047c478bd9Sstevel@tonic-gate #if defined(_LP64)
1057c478bd9Sstevel@tonic-gate if (procp->pp_dmodel == PR_MODEL_ILP32)
1067c478bd9Sstevel@tonic-gate procp->pp_ldsobase =
1077c478bd9Sstevel@tonic-gate ((uintptr_t)((auxv32_t *)auxvp)->
1087c478bd9Sstevel@tonic-gate a_un.a_val);
1097c478bd9Sstevel@tonic-gate else
1107c478bd9Sstevel@tonic-gate #endif
1117c478bd9Sstevel@tonic-gate procp->pp_ldsobase = auxvp->a_un.a_val;
1127c478bd9Sstevel@tonic-gate } else if (auxvp->a_type == AT_PHDR) {
1137c478bd9Sstevel@tonic-gate #if defined(_LP64)
1147c478bd9Sstevel@tonic-gate if (procp->pp_dmodel == PR_MODEL_ILP32)
1157c478bd9Sstevel@tonic-gate procp->pp_execphdr =
1167c478bd9Sstevel@tonic-gate ((uintptr_t)((auxv32_t *)auxvp)->
1177c478bd9Sstevel@tonic-gate a_un.a_val);
1187c478bd9Sstevel@tonic-gate else
1197c478bd9Sstevel@tonic-gate #endif
1207c478bd9Sstevel@tonic-gate procp->pp_execphdr = auxvp->a_un.a_val;
1217c478bd9Sstevel@tonic-gate }
1227c478bd9Sstevel@tonic-gate auxvptr = (void *)((uintptr_t)auxvptr + entsize);
1237c478bd9Sstevel@tonic-gate }
1247c478bd9Sstevel@tonic-gate }
1257c478bd9Sstevel@tonic-gate
1267c478bd9Sstevel@tonic-gate retc_t
ps_init(int pctlfd,int pstatusfd,pid_t pid,struct ps_prochandle * procp)1279039eeafSab ps_init(int pctlfd, int pstatusfd, pid_t pid, struct ps_prochandle *procp)
1287c478bd9Sstevel@tonic-gate {
1297c478bd9Sstevel@tonic-gate rd_notify_t rd_notify;
13020c1c355SRod Evans char procname[PROCSIZE];
13120c1c355SRod Evans long oper, pflags;
1327c478bd9Sstevel@tonic-gate struct iovec piov[2];
1337c478bd9Sstevel@tonic-gate
1347c478bd9Sstevel@tonic-gate procp->pp_pid = pid;
1357c478bd9Sstevel@tonic-gate procp->pp_ctlfd = pctlfd;
1367c478bd9Sstevel@tonic-gate procp->pp_statusfd = pstatusfd;
1377c478bd9Sstevel@tonic-gate
13820c1c355SRod Evans (void) snprintf(procname, PROCSIZE, "/proc/%d/map",
13920c1c355SRod Evans EC_SWORD(procp->pp_pid));
1407c478bd9Sstevel@tonic-gate if ((procp->pp_mapfd = open(procname, O_RDONLY)) == -1)
1417c478bd9Sstevel@tonic-gate perr("psi: open of /proc/dpid/map failed");
1427c478bd9Sstevel@tonic-gate
14320c1c355SRod Evans (void) snprintf(procname, PROCSIZE, "/proc/%d/as",
14420c1c355SRod Evans EC_SWORD(procp->pp_pid));
1457c478bd9Sstevel@tonic-gate if ((procp->pp_asfd = open(procname, O_RDWR)) == -1)
1467c478bd9Sstevel@tonic-gate perr("psi: open of /proc/dpid/as failed");
1477c478bd9Sstevel@tonic-gate
1487c478bd9Sstevel@tonic-gate if (ps_pdmodel(procp, &procp->pp_dmodel) != PS_OK)
1497c478bd9Sstevel@tonic-gate perr("psi: data model");
1507c478bd9Sstevel@tonic-gate
1517c478bd9Sstevel@tonic-gate #if !defined(_LP64)
1527c478bd9Sstevel@tonic-gate if (procp->pp_dmodel == PR_MODEL_LP64)
1537c478bd9Sstevel@tonic-gate perr("psi: run 64-bit rdb to debug a 64-bit process");
1547c478bd9Sstevel@tonic-gate #endif
1557c478bd9Sstevel@tonic-gate get_ldbase(procp);
1567c478bd9Sstevel@tonic-gate
15720c1c355SRod Evans (void) load_map(procp, (caddr_t)procp->pp_ldsobase,
15820c1c355SRod Evans &(procp->pp_ldsomap));
1597c478bd9Sstevel@tonic-gate procp->pp_ldsomap.mi_addr += procp->pp_ldsobase;
1607c478bd9Sstevel@tonic-gate procp->pp_ldsomap.mi_end += procp->pp_ldsobase;
1617c478bd9Sstevel@tonic-gate procp->pp_ldsomap.mi_name = "<procfs: interp>";
1627c478bd9Sstevel@tonic-gate
16320c1c355SRod Evans (void) load_map(procp, (caddr_t)procp->pp_execphdr,
16420c1c355SRod Evans &(procp->pp_execmap));
1657c478bd9Sstevel@tonic-gate procp->pp_execmap.mi_name = "<procfs: exec>";
1667c478bd9Sstevel@tonic-gate
16720c1c355SRod Evans procp->pp_breakpoints = NULL;
1687c478bd9Sstevel@tonic-gate procp->pp_flags = FLG_PP_PACT | FLG_PP_PLTSKIP;
16920c1c355SRod Evans procp->pp_lmaplist.ml_head = NULL;
17020c1c355SRod Evans procp->pp_lmaplist.ml_tail = NULL;
17120c1c355SRod Evans if ((procp->pp_rap = rd_new(procp)) == NULL) {
17220c1c355SRod Evans (void) fprintf(stderr, "rdb: rtld_db: rd_new() call failed\n");
1737c478bd9Sstevel@tonic-gate exit(1);
1747c478bd9Sstevel@tonic-gate }
17520c1c355SRod Evans (void) rd_event_enable(procp->pp_rap, 1);
1767c478bd9Sstevel@tonic-gate
1777c478bd9Sstevel@tonic-gate /*
1787c478bd9Sstevel@tonic-gate * For those architectures that increment the PC on
1797c478bd9Sstevel@tonic-gate * a breakpoint fault we enable the PR_BPTADJ adjustments.
1807c478bd9Sstevel@tonic-gate */
1817c478bd9Sstevel@tonic-gate oper = PCSET;
1827c478bd9Sstevel@tonic-gate pflags = PR_BPTADJ;
1837c478bd9Sstevel@tonic-gate piov[0].iov_base = (caddr_t)(&oper);
1847c478bd9Sstevel@tonic-gate piov[0].iov_len = sizeof (oper);
1857c478bd9Sstevel@tonic-gate piov[1].iov_base = (caddr_t)(&pflags);
1867c478bd9Sstevel@tonic-gate piov[1].iov_len = sizeof (pflags);
1877c478bd9Sstevel@tonic-gate if (writev(procp->pp_ctlfd, piov, 2) == -1)
1887c478bd9Sstevel@tonic-gate perr("psinit: PCSET(PR_BTPADJ)");
1897c478bd9Sstevel@tonic-gate
1907c478bd9Sstevel@tonic-gate /*
1917c478bd9Sstevel@tonic-gate * Set breakpoints for special handshakes between librtld_db.so
1927c478bd9Sstevel@tonic-gate * and the debugger. These include:
1937c478bd9Sstevel@tonic-gate * PREINIT - before .init processing.
1947c478bd9Sstevel@tonic-gate * POSTINIT - after .init processing
1957c478bd9Sstevel@tonic-gate * DLACTIVITY - link_maps status has changed
1967c478bd9Sstevel@tonic-gate */
1977c478bd9Sstevel@tonic-gate if (rd_event_addr(procp->pp_rap, RD_PREINIT, &rd_notify) == RD_OK) {
1987c478bd9Sstevel@tonic-gate if (set_breakpoint(procp, rd_notify.u.bptaddr,
1997c478bd9Sstevel@tonic-gate FLG_BP_RDPREINIT) != RET_OK)
20020c1c355SRod Evans (void) fprintf(stderr,
20120c1c355SRod Evans "psi: failed to set BP for preinit at: 0x%lx\n",
20220c1c355SRod Evans rd_notify.u.bptaddr);
2037c478bd9Sstevel@tonic-gate } else
20420c1c355SRod Evans (void) fprintf(stderr, "psi: no event registered for "
20520c1c355SRod Evans "preinit\n");
2067c478bd9Sstevel@tonic-gate
2077c478bd9Sstevel@tonic-gate if (rd_event_addr(procp->pp_rap, RD_POSTINIT, &rd_notify) == RD_OK) {
2087c478bd9Sstevel@tonic-gate if (set_breakpoint(procp, rd_notify.u.bptaddr,
2097c478bd9Sstevel@tonic-gate FLG_BP_RDPOSTINIT) != RET_OK)
21020c1c355SRod Evans (void) fprintf(stderr,
2117c478bd9Sstevel@tonic-gate "psi: failed to set BP for postinit at: 0x%lx\n",
2127c478bd9Sstevel@tonic-gate rd_notify.u.bptaddr);
2137c478bd9Sstevel@tonic-gate } else
21420c1c355SRod Evans (void) fprintf(stderr, "psi: no event registered for "
21520c1c355SRod Evans "postinit\n");
2167c478bd9Sstevel@tonic-gate
2177c478bd9Sstevel@tonic-gate if (rd_event_addr(procp->pp_rap, RD_DLACTIVITY, &rd_notify) == RD_OK) {
2187c478bd9Sstevel@tonic-gate if (set_breakpoint(procp, rd_notify.u.bptaddr,
2197c478bd9Sstevel@tonic-gate FLG_BP_RDDLACT) != RET_OK)
22020c1c355SRod Evans (void) fprintf(stderr,
22120c1c355SRod Evans "psi: failed to set BP for dlact at: 0x%lx\n",
22220c1c355SRod Evans rd_notify.u.bptaddr);
2237c478bd9Sstevel@tonic-gate } else
22420c1c355SRod Evans (void) fprintf(stderr, "psi: no event registered for dlact\n");
2257c478bd9Sstevel@tonic-gate
2267c478bd9Sstevel@tonic-gate return (RET_OK);
2277c478bd9Sstevel@tonic-gate }
2287c478bd9Sstevel@tonic-gate
2297c478bd9Sstevel@tonic-gate retc_t
ps_close(struct ps_prochandle * ph)2309039eeafSab ps_close(struct ps_prochandle *ph)
2317c478bd9Sstevel@tonic-gate {
23220c1c355SRod Evans (void) delete_all_breakpoints(ph);
23320c1c355SRod Evans
2347c478bd9Sstevel@tonic-gate if (ph->pp_auxvp)
2357c478bd9Sstevel@tonic-gate free(ph->pp_auxvp);
2367c478bd9Sstevel@tonic-gate free_linkmaps(ph);
2377c478bd9Sstevel@tonic-gate return (RET_OK);
2387c478bd9Sstevel@tonic-gate }
2397c478bd9Sstevel@tonic-gate
2407c478bd9Sstevel@tonic-gate ps_err_e
ps_pauxv(struct ps_prochandle * ph,const auxv_t ** auxvp)2419039eeafSab ps_pauxv(struct ps_prochandle *ph, const auxv_t **auxvp)
2427c478bd9Sstevel@tonic-gate {
2437c478bd9Sstevel@tonic-gate *auxvp = ph->pp_auxvp;
2447c478bd9Sstevel@tonic-gate return (PS_OK);
2457c478bd9Sstevel@tonic-gate }
2467c478bd9Sstevel@tonic-gate
2477c478bd9Sstevel@tonic-gate ps_err_e
ps_pdmodel(struct ps_prochandle * ph,int * dm)2489039eeafSab ps_pdmodel(struct ps_prochandle *ph, int *dm)
2497c478bd9Sstevel@tonic-gate {
2507c478bd9Sstevel@tonic-gate pstatus_t pstatus;
2517c478bd9Sstevel@tonic-gate
2527c478bd9Sstevel@tonic-gate if (pread(ph->pp_statusfd, &pstatus, sizeof (pstatus), 0) == -1)
2537c478bd9Sstevel@tonic-gate return (PS_ERR);
2547c478bd9Sstevel@tonic-gate
2557c478bd9Sstevel@tonic-gate *dm = (int)pstatus.pr_dmodel;
2567c478bd9Sstevel@tonic-gate return (PS_OK);
2577c478bd9Sstevel@tonic-gate }
2587c478bd9Sstevel@tonic-gate
2597c478bd9Sstevel@tonic-gate ps_err_e
ps_pread(struct ps_prochandle * ph,psaddr_t addr,void * buf,size_t size)2609039eeafSab ps_pread(struct ps_prochandle *ph, psaddr_t addr, void *buf, size_t size)
2617c478bd9Sstevel@tonic-gate {
2627c478bd9Sstevel@tonic-gate if (pread(ph->pp_asfd, buf, size, (off_t)addr) != size)
2637c478bd9Sstevel@tonic-gate return (PS_ERR);
2647c478bd9Sstevel@tonic-gate
2657c478bd9Sstevel@tonic-gate return (PS_OK);
2667c478bd9Sstevel@tonic-gate }
2677c478bd9Sstevel@tonic-gate
2687c478bd9Sstevel@tonic-gate ps_err_e
ps_pwrite(struct ps_prochandle * ph,psaddr_t addr,const void * buf,size_t size)2699039eeafSab ps_pwrite(struct ps_prochandle *ph, psaddr_t addr, const void *buf, size_t size)
2707c478bd9Sstevel@tonic-gate {
2717c478bd9Sstevel@tonic-gate if (pwrite(ph->pp_asfd, buf, size, (off_t)addr) != size)
2727c478bd9Sstevel@tonic-gate return (PS_ERR);
2737c478bd9Sstevel@tonic-gate
2747c478bd9Sstevel@tonic-gate return (PS_OK);
2757c478bd9Sstevel@tonic-gate }
2767c478bd9Sstevel@tonic-gate
2777c478bd9Sstevel@tonic-gate ps_err_e
ps_pglobal_sym(struct ps_prochandle * ph,const char * object_name,const char * sym_name,ps_sym_t * symp)2789039eeafSab ps_pglobal_sym(struct ps_prochandle *ph, const char *object_name,
2799039eeafSab const char *sym_name, ps_sym_t *symp)
2807c478bd9Sstevel@tonic-gate {
2819039eeafSab map_info_t *mip;
2827c478bd9Sstevel@tonic-gate GElf_Sym gsym;
2837c478bd9Sstevel@tonic-gate
28420c1c355SRod Evans if ((mip = str_to_map(ph, object_name)) == NULL)
2857c478bd9Sstevel@tonic-gate return (PS_ERR);
2867c478bd9Sstevel@tonic-gate
2877c478bd9Sstevel@tonic-gate if (str_map_sym(sym_name, mip, &gsym, NULL) == RET_FAILED)
2887c478bd9Sstevel@tonic-gate return (PS_ERR);
2897c478bd9Sstevel@tonic-gate
2907c478bd9Sstevel@tonic-gate #if defined(_LP64)
2917c478bd9Sstevel@tonic-gate *symp = gsym;
2927c478bd9Sstevel@tonic-gate #else
2937c478bd9Sstevel@tonic-gate gelf_sym_to_elf32(&gsym, (Elf32_Sym *)symp);
2947c478bd9Sstevel@tonic-gate #endif
2957c478bd9Sstevel@tonic-gate
2967c478bd9Sstevel@tonic-gate return (PS_OK);
2977c478bd9Sstevel@tonic-gate }
2987c478bd9Sstevel@tonic-gate
2997c478bd9Sstevel@tonic-gate ps_err_e
ps_pglobal_lookup(struct ps_prochandle * ph,const char * object_name,const char * sym_name,ulong_t * sym_addr)3009039eeafSab ps_pglobal_lookup(struct ps_prochandle *ph, const char *object_name,
3019039eeafSab const char *sym_name, ulong_t *sym_addr)
3027c478bd9Sstevel@tonic-gate {
3037c478bd9Sstevel@tonic-gate GElf_Sym sym;
3049039eeafSab map_info_t *mip;
3057c478bd9Sstevel@tonic-gate
30620c1c355SRod Evans if ((mip = str_to_map(ph, object_name)) == NULL)
3077c478bd9Sstevel@tonic-gate return (PS_ERR);
3087c478bd9Sstevel@tonic-gate
3097c478bd9Sstevel@tonic-gate if (str_map_sym(sym_name, mip, &sym, NULL) == RET_FAILED)
3107c478bd9Sstevel@tonic-gate return (PS_ERR);
3117c478bd9Sstevel@tonic-gate
3127c478bd9Sstevel@tonic-gate *sym_addr = sym.st_value;
3137c478bd9Sstevel@tonic-gate
3147c478bd9Sstevel@tonic-gate return (PS_OK);
3157c478bd9Sstevel@tonic-gate }
3167c478bd9Sstevel@tonic-gate
3177c478bd9Sstevel@tonic-gate ps_err_e
ps_lgetregs(struct ps_prochandle * ph,lwpid_t lid,prgregset_t gregset)3189039eeafSab ps_lgetregs(struct ps_prochandle *ph, lwpid_t lid, prgregset_t gregset)
3197c478bd9Sstevel@tonic-gate {
3207c478bd9Sstevel@tonic-gate char procname[MAXPATHLEN];
3217c478bd9Sstevel@tonic-gate int lwpfd;
3227c478bd9Sstevel@tonic-gate lwpstatus_t lwpstatus;
3237c478bd9Sstevel@tonic-gate
3247c478bd9Sstevel@tonic-gate (void) snprintf(procname, MAXPATHLEN - 1,
32520c1c355SRod Evans "/proc/%d/lwp/%d/lwpstatus", EC_SWORD(ph->pp_pid), EC_SWORD(lid));
3267c478bd9Sstevel@tonic-gate
3277c478bd9Sstevel@tonic-gate if ((lwpfd = open(procname, O_RDONLY)) == -1)
3287c478bd9Sstevel@tonic-gate return (PS_ERR);
3297c478bd9Sstevel@tonic-gate
3307c478bd9Sstevel@tonic-gate if (read(lwpfd, &lwpstatus, sizeof (lwpstatus)) == -1)
3317c478bd9Sstevel@tonic-gate return (PS_ERR);
3327c478bd9Sstevel@tonic-gate
33367b1ef3cSRichard Lowe (void) memcpy(gregset, lwpstatus.pr_reg, sizeof (*gregset));
3347c478bd9Sstevel@tonic-gate
33520c1c355SRod Evans (void) close(lwpfd);
3367c478bd9Sstevel@tonic-gate return (PS_OK);
3377c478bd9Sstevel@tonic-gate }
3387c478bd9Sstevel@tonic-gate
3397c478bd9Sstevel@tonic-gate void
ps_plog(const char * fmt,...)3409039eeafSab ps_plog(const char *fmt, ...)
3417c478bd9Sstevel@tonic-gate {
3427c478bd9Sstevel@tonic-gate va_list args;
34320c1c355SRod Evans static FILE *log_fp = NULL;
3447c478bd9Sstevel@tonic-gate
34520c1c355SRod Evans if (log_fp == NULL) {
3467c478bd9Sstevel@tonic-gate char log_fname[256];
34720c1c355SRod Evans (void) sprintf(log_fname, "/tmp/tdlog.%d", EC_SWORD(getpid()));
34820c1c355SRod Evans if ((log_fp = fopen(log_fname, "w")) == NULL) {
3497c478bd9Sstevel@tonic-gate /*
35020c1c355SRod Evans * Unable to open log file - default to stderr.
3517c478bd9Sstevel@tonic-gate */
35220c1c355SRod Evans (void) fprintf(stderr, "unable to open %s, logging "
35320c1c355SRod Evans "redirected to stderr", log_fname);
3547c478bd9Sstevel@tonic-gate log_fp = stderr;
3557c478bd9Sstevel@tonic-gate }
3567c478bd9Sstevel@tonic-gate }
3577c478bd9Sstevel@tonic-gate
3587c478bd9Sstevel@tonic-gate va_start(args, fmt);
35920c1c355SRod Evans (void) vfprintf(log_fp, fmt, args);
3607c478bd9Sstevel@tonic-gate va_end(args);
36120c1c355SRod Evans (void) fputc('\n', log_fp);
36220c1c355SRod Evans (void) fflush(log_fp);
3637c478bd9Sstevel@tonic-gate }
3649039eeafSab
36520c1c355SRod Evans /* ARGSUSED0 */
3669039eeafSab ps_err_e
ps_pbrandname(struct ps_prochandle * P,char * buf,size_t len)3679039eeafSab ps_pbrandname(struct ps_prochandle *P, char *buf, size_t len)
3689039eeafSab {
3699039eeafSab return (PS_ERR);
3709039eeafSab }
371