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.
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.
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]
23 * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
33 #include <sys/types.h>
34 #include <sys/signal.h>
35 #include <sys/fault.h>
36 #include <sys/syscall.h>
42 #include <sys/param.h>
43 #include <sys/machelf.h>
46 #include <proc_service.h>
53 gelf_sym_to_elf32(GElf_Sym
*src
, Elf32_Sym
*dst
)
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
;
68 get_ldbase(struct ps_prochandle
*procp
)
73 void *auxvptr
, *auxvtail
;
77 (void) snprintf(pname
, PROCSIZE
, "/proc/%d/auxv",
78 EC_SWORD(procp
->pp_pid
));
79 if ((pauxvfd
= open(pname
, O_RDONLY
)) == -1)
82 if (fstat(pauxvfd
, &stbuf
) == -1)
85 auxvptr
= malloc(stbuf
.st_size
);
86 if (read(pauxvfd
, auxvptr
, stbuf
.st_size
) == -1)
87 perr("gldb: reading auxv");
89 (void) close(pauxvfd
);
91 procp
->pp_auxvp
= auxvptr
;
92 auxvtail
= (void *)((uintptr_t)auxvptr
+ stbuf
.st_size
);
95 if (procp
->pp_dmodel
== PR_MODEL_ILP32
)
96 entsize
= sizeof (auxv32_t
);
99 entsize
= sizeof (auxv_t
);
101 while (auxvptr
< auxvtail
) {
103 if (auxvp
->a_type
== AT_BASE
) {
105 if (procp
->pp_dmodel
== PR_MODEL_ILP32
)
107 ((uintptr_t)((auxv32_t
*)auxvp
)->
111 procp
->pp_ldsobase
= auxvp
->a_un
.a_val
;
112 } else if (auxvp
->a_type
== AT_PHDR
) {
114 if (procp
->pp_dmodel
== PR_MODEL_ILP32
)
116 ((uintptr_t)((auxv32_t
*)auxvp
)->
120 procp
->pp_execphdr
= auxvp
->a_un
.a_val
;
122 auxvptr
= (void *)((uintptr_t)auxvptr
+ entsize
);
127 ps_init(int pctlfd
, int pstatusfd
, pid_t pid
, struct ps_prochandle
*procp
)
129 rd_notify_t rd_notify
;
130 char procname
[PROCSIZE
];
132 struct iovec piov
[2];
135 procp
->pp_ctlfd
= pctlfd
;
136 procp
->pp_statusfd
= pstatusfd
;
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");
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");
148 if (ps_pdmodel(procp
, &procp
->pp_dmodel
) != PS_OK
)
149 perr("psi: data model");
152 if (procp
->pp_dmodel
== PR_MODEL_LP64
)
153 perr("psi: run 64-bit rdb to debug a 64-bit process");
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>";
163 (void) load_map(procp
, (caddr_t
)procp
->pp_execphdr
,
164 &(procp
->pp_execmap
));
165 procp
->pp_execmap
.mi_name
= "<procfs: exec>";
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");
175 (void) rd_event_enable(procp
->pp_rap
, 1);
178 * For those architectures that increment the PC on
179 * a breakpoint fault we enable the PR_BPTADJ adjustments.
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)");
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
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
);
204 (void) fprintf(stderr
, "psi: no event registered for "
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
);
214 (void) fprintf(stderr
, "psi: no event registered for "
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
);
224 (void) fprintf(stderr
, "psi: no event registered for dlact\n");
230 ps_close(struct ps_prochandle
*ph
)
232 (void) delete_all_breakpoints(ph
);
241 ps_pauxv(struct ps_prochandle
*ph
, const auxv_t
**auxvp
)
243 *auxvp
= ph
->pp_auxvp
;
248 ps_pdmodel(struct ps_prochandle
*ph
, int *dm
)
252 if (pread(ph
->pp_statusfd
, &pstatus
, sizeof (pstatus
), 0) == -1)
255 *dm
= (int)pstatus
.pr_dmodel
;
260 ps_pread(struct ps_prochandle
*ph
, psaddr_t addr
, void *buf
, size_t size
)
262 if (pread(ph
->pp_asfd
, buf
, size
, (off_t
)addr
) != size
)
269 ps_pwrite(struct ps_prochandle
*ph
, psaddr_t addr
, const void *buf
, size_t size
)
271 if (pwrite(ph
->pp_asfd
, buf
, size
, (off_t
)addr
) != size
)
278 ps_pglobal_sym(struct ps_prochandle
*ph
, const char *object_name
,
279 const char *sym_name
, ps_sym_t
*symp
)
284 if ((mip
= str_to_map(ph
, object_name
)) == NULL
)
287 if (str_map_sym(sym_name
, mip
, &gsym
, NULL
) == RET_FAILED
)
293 gelf_sym_to_elf32(&gsym
, (Elf32_Sym
*)symp
);
300 ps_pglobal_lookup(struct ps_prochandle
*ph
, const char *object_name
,
301 const char *sym_name
, ulong_t
*sym_addr
)
306 if ((mip
= str_to_map(ph
, object_name
)) == NULL
)
309 if (str_map_sym(sym_name
, mip
, &sym
, NULL
) == RET_FAILED
)
312 *sym_addr
= sym
.st_value
;
318 ps_lgetregs(struct ps_prochandle
*ph
, lwpid_t lid
, prgregset_t gregset
)
320 char procname
[MAXPATHLEN
];
322 lwpstatus_t lwpstatus
;
324 (void) snprintf(procname
, MAXPATHLEN
- 1,
325 "/proc/%d/lwp/%d/lwpstatus", EC_SWORD(ph
->pp_pid
), EC_SWORD(lid
));
327 if ((lwpfd
= open(procname
, O_RDONLY
)) == -1)
330 if (read(lwpfd
, &lwpstatus
, sizeof (lwpstatus
)) == -1)
333 gregset
= lwpstatus
.pr_reg
;
340 ps_plog(const char *fmt
, ...)
343 static FILE *log_fp
= NULL
;
345 if (log_fp
== NULL
) {
347 (void) sprintf(log_fname
, "/tmp/tdlog.%d", EC_SWORD(getpid()));
348 if ((log_fp
= fopen(log_fname
, "w")) == NULL
) {
350 * Unable to open log file - default to stderr.
352 (void) fprintf(stderr
, "unable to open %s, logging "
353 "redirected to stderr", log_fname
);
359 (void) vfprintf(log_fp
, fmt
, args
);
361 (void) fputc('\n', log_fp
);
362 (void) fflush(log_fp
);
367 ps_pbrandname(struct ps_prochandle
*P
, char *buf
, size_t len
)