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