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/bpt.c
+++ new/usr/src/cmd/sgs/librtld_db/demo/common/bpt.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 <libelf.h>
40 40 #include <sys/param.h>
41 41 #include <sys/machelf.h>
42 42 #include <stdarg.h>
43 43
44 44 #include "rdb.h"
45 45
46 46 static const char *fault_strings[] = {
47 47 "<null string>",
48 48 "illegal instruction",
49 49 "privileged instruction",
50 50 "breakpoint instruction",
51 51 "trace trap (single-step)",
52 52 "Memory access (e.g., alignment)",
53 53 "Memory bounds (invalid address)",
54 54 "Integer overflow",
55 55 "Integer zero divide"
56 56 "Floating-point exception",
57 57 "Irrecoverable stack faul",
58 58 "Recoverable page fault (no associated sig)"
59 59 };
60 60
61 61 #define MAXFAULT FLTPAGE
62 62
63 63 retc_t
64 64 set_breakpoint(struct ps_prochandle *ph, ulong_t addr, unsigned flags)
65 65 {
66 66 bptlist_t *new, *cur, *prev;
67 67
68 68 for (cur = ph->pp_breakpoints, prev = NULL;
69 69 (cur && (cur->bl_addr < addr));
70 70 prev = cur, cur = cur->bl_next)
71 71 ;
72 72 if (cur && (cur->bl_addr == addr)) {
73 73 /*
74 74 * already have break point set here.
75 75 */
76 76 cur->bl_flags |= flags;
77 77 return (RET_OK);
78 78 }
79 79
80 80 new = malloc(sizeof (bptlist_t));
81 81 new->bl_addr = addr;
82 82 new->bl_flags = flags;
83 83 if (prev == NULL) {
84 84 /*
85 85 * insert at head
86 86 */
87 87 new->bl_next = ph->pp_breakpoints;
88 88 ph->pp_breakpoints = new;
89 89 return (RET_OK);
90 90 }
91 91
92 92 prev->bl_next = new;
93 93 new->bl_next = cur;
94 94 return (RET_OK);
95 95 }
96 96
97 97 static bptlist_t *
98 98 find_bp(struct ps_prochandle *ph, ulong_t addr)
99 99 {
100 100 bptlist_t *cur;
101 101
102 102 for (cur = ph->pp_breakpoints;
103 103 (cur && (cur->bl_addr != addr));
104 104 cur = cur->bl_next)
105 105 ;
106 106
107 107 if ((cur == NULL) || (cur->bl_addr != addr))
108 108 return ((bptlist_t *)-1);
109 109 return (cur);
110 110 }
111 111
112 112 static retc_t
113 113 delete_bp(struct ps_prochandle *ph, ulong_t addr)
114 114 {
115 115 bptlist_t *cur, *prev;
116 116
117 117 for (cur = ph->pp_breakpoints, prev = NULL;
118 118 (cur && (cur->bl_addr < addr));
119 119 prev = cur, cur = cur->bl_next)
120 120 ;
121 121 if ((cur == NULL) || (cur->bl_addr != addr))
122 122 return (RET_FAILED);
123 123
124 124 if (prev == NULL)
125 125 ph->pp_breakpoints = cur->bl_next;
126 126 else
127 127 prev->bl_next = cur->bl_next;
128 128
129 129 free(cur);
130 130 return (RET_OK);
131 131 }
132 132
133 133 void
134 134 list_breakpoints(struct ps_prochandle *ph)
135 135 {
136 136 bptlist_t *cur;
137 137
138 138 if (ph->pp_breakpoints == NULL) {
139 139 (void) printf("no active breakpoints.\n");
140 140 return;
141 141 }
142 142
143 143 (void) printf("active breakpoints:\n");
144 144 for (cur = ph->pp_breakpoints; cur; cur = cur->bl_next) {
145 145 (void) printf("\t0x%08lx:0x%04x - %s\n", cur->bl_addr,
146 146 cur->bl_flags, print_address_ps(ph, cur->bl_addr,
147 147 FLG_PAP_SONAME));
148 148 }
149 149 }
150 150
151 151 static void
152 152 set_breaks(struct ps_prochandle *ph)
153 153 {
154 154 bptlist_t *cur;
155 155 bptinstr_t bpt_instr = BPINSTR;
156 156
157 157 for (cur = ph->pp_breakpoints; cur; cur = cur->bl_next) {
158 158 bptinstr_t old_inst = 0;
159 159
160 160 if (ps_pread(ph, cur->bl_addr, (char *)&old_inst,
161 161 sizeof (bptinstr_t)) != PS_OK)
162 162 perr("sb: error setting breakpoint");
163 163
164 164 cur->bl_instr = old_inst;
165 165
166 166 if (ps_pwrite(ph, cur->bl_addr, (char *)&bpt_instr,
167 167 sizeof (bptinstr_t)) != PS_OK)
168 168 perr("sb1: error setting breakpoint\n");
169 169 }
170 170
171 171 }
172 172
173 173 static void
174 174 clear_breaks(struct ps_prochandle *ph)
175 175 {
176 176 bptlist_t *cur;
177 177
178 178 /*
179 179 * Restore all the original instructions
180 180 */
181 181 for (cur = ph->pp_breakpoints; cur; cur = cur->bl_next)
182 182 if (ps_pwrite(ph, cur->bl_addr, (char *)&(cur->bl_instr),
183 183 sizeof (bptinstr_t)) != PS_OK)
184 184 perr("cb: error clearing breakpoint");
185 185 }
186 186
187 187 retc_t
188 188 delete_all_breakpoints(struct ps_prochandle *ph)
189 189 {
190 190 bptlist_t *cur, *prev;
191 191
192 192 if (ph->pp_breakpoints == NULL)
193 193 return (RET_OK);
194 194
195 195 for (prev = NULL, cur = ph->pp_breakpoints;
196 196 cur; prev = cur, cur = cur->bl_next)
197 197 if (prev)
198 198 free(prev);
199 199 if (prev)
200 200 free(prev);
201 201
202 202 ph->pp_breakpoints = NULL;
203 203 return (RET_OK);
204 204 }
205 205
206 206 retc_t
207 207 delete_breakpoint(struct ps_prochandle *ph, ulong_t addr, unsigned flags)
208 208 {
209 209 bptlist_t *bpt;
210 210
211 211 if (((bpt = find_bp(ph, addr)) == (bptlist_t *)-1) ||
212 212 ((bpt->bl_flags & flags) == 0))
213 213 return (RET_FAILED);
214 214
215 215 bpt->bl_flags &= ~flags;
216 216 if (bpt->bl_flags)
217 217 return (RET_OK);
218 218
219 219 return (delete_bp(ph, addr));
220 220 }
221 221
222 222 static void
223 223 handle_sp_break(struct ps_prochandle *ph)
224 224 {
225 225 rd_event_msg_t emt;
226 226
227 227 if (rd_event_getmsg(ph->pp_rap, &emt) != RD_OK) {
228 228 (void) fprintf(stderr, "hsb: failed rd_event_getmsg()\n");
229 229 return;
230 230 }
231 231
232 232 if (emt.type == RD_DLACTIVITY) {
233 233 if (emt.u.state == RD_CONSISTENT)
234 234 ph->pp_flags |= FLG_PP_LMAPS;
235 235 else
236 236 ph->pp_flags &= ~FLG_PP_LMAPS;
237 237 if ((rdb_flags & RDB_FL_EVENTS) == 0)
238 238 return;
239 239
240 240 (void) printf("dlactivity: state changed to: ");
241 241 switch (emt.u.state) {
242 242 case RD_CONSISTENT:
243 243 (void) printf("RD_CONSISTENT\n");
244 244 break;
245 245 case RD_ADD:
246 246 (void) printf("RD_ADD\n");
247 247 break;
248 248 case RD_DELETE:
249 249 (void) printf("RD_DELETE\n");
250 250 break;
251 251 default:
252 252 (void) printf("unknown: 0x%x\n", emt.u.state);
253 253 }
254 254 return;
255 255 }
256 256
257 257 if ((rdb_flags & RDB_FL_EVENTS) == 0)
258 258 return;
259 259
260 260 if (emt.type == RD_PREINIT) {
261 261 (void) printf("preinit reached\n");
262 262 return;
263 263 }
264 264
265 265 if (emt.type == RD_POSTINIT)
266 266 (void) printf("postinit reached\n");
267 267 }
268 268
269 269 unsigned
270 270 continue_to_break(struct ps_prochandle *ph)
271 271 {
272 272 bptlist_t *bpt;
273 273 pstatus_t pstatus;
274 274 struct iovec piov[5];
275 275 long oper1, oper2, oper3, pflags = 0;
276 276 fltset_t faults;
277 277
278 278 /*
279 279 * We step by the first instruction incase their was
280 280 * a break-point there.
281 281 */
282 282 (void) step_n(ph, 1, FLG_SN_NONE);
283 283
284 284 premptyset(&faults);
285 285 praddset(&faults, FLTBPT);
286 286 praddset(&faults, FLTILL);
287 287 praddset(&faults, FLTPRIV);
288 288 praddset(&faults, FLTACCESS);
289 289 praddset(&faults, FLTBOUNDS);
290 290 praddset(&faults, FLTIZDIV);
291 291 praddset(&faults, FLTSTACK);
292 292 praddset(&faults, FLTTRACE);
293 293
294 294
295 295 /* LINTED CONSTANT */
296 296 while (1) {
297 297 set_breaks(ph);
298 298 oper1 = PCSFAULT;
299 299 piov[0].iov_base = (caddr_t)(&oper1);
300 300 piov[0].iov_len = sizeof (oper1);
301 301
302 302 piov[1].iov_base = (caddr_t)(&faults);
303 303 piov[1].iov_len = sizeof (faults);
304 304
305 305 oper2 = PCRUN;
306 306 piov[2].iov_base = (caddr_t)(&oper2);
307 307 piov[2].iov_len = sizeof (oper2);
308 308 pflags = PRCFAULT;
309 309 piov[3].iov_base = (caddr_t)(&pflags);
310 310 piov[3].iov_len = sizeof (pflags);
311 311
312 312 oper3 = PCWSTOP;
313 313 piov[4].iov_base = (caddr_t)(&oper3);
314 314 piov[4].iov_len = sizeof (oper3);
315 315
316 316 if (writev(ph->pp_ctlfd, piov, 5) == -1) {
317 317 if (errno == ENOENT) {
318 318 ph->pp_flags &= ~FLG_PP_PACT;
319 319
320 320 (void) ps_close(ph);
321 321 (void) printf("process terminated.\n");
322 322 return (0);
323 323 }
324 324 perr("ctb: PCWSTOP");
325 325 }
326 326
327 327 if (pread(ph->pp_statusfd, &pstatus, sizeof (pstatus), 0) == -1)
328 328 perr("ctb: reading status");
329 329
330 330
331 331 if ((pstatus.pr_lwp.pr_why != PR_FAULTED) ||
332 332 (pstatus.pr_lwp.pr_what != FLTBPT)) {
333 333 const char *fltmsg;
334 334
335 335 if ((pstatus.pr_lwp.pr_what <= MAXFAULT) &&
336 336 (pstatus.pr_lwp.pr_why == PR_FAULTED))
337 337 fltmsg = fault_strings[pstatus.pr_lwp.pr_what];
338 338 else
339 339 fltmsg = "<unknown error>";
340 340
341 341 (void) fprintf(stderr, "ctb: bad stop - stopped "
342 342 "on why: 0x%x what: %s(0x%x)\n",
343 343 pstatus.pr_lwp.pr_why, fltmsg,
344 344 pstatus.pr_lwp.pr_what);
345 345 return (0);
346 346 }
347 347
348 348 oper1 = PCCFAULT;
349 349 if (writev(ph->pp_ctlfd, piov, 1) == -1)
350 350 perr("ctb: PCCFAULT");
351 351
352 352 if ((bpt = find_bp(ph, pstatus.pr_lwp.pr_reg[R_PC])) ==
353 353 (bptlist_t *)-1) {
354 354 (void) fprintf(stderr,
355 355 "stopped at unregistered breakpoint! "
356 356 "addr: 0x%x\n",
357 357 EC_WORD(pstatus.pr_lwp.pr_reg[R_PC]));
358 358 break;
359 359 }
360 360 clear_breaks(ph);
361 361
362 362 /*
363 363 * If this was a BP at which we should stop
364 364 */
365 365 if (bpt->bl_flags & MASK_BP_STOP)
366 366 break;
367 367
368 368 (void) step_n(ph, 1, FLG_SN_NONE);
↓ open down ↓ |
368 lines elided |
↑ open up ↑ |
369 369 }
370 370
371 371 if (bpt->bl_flags & FLG_BP_USERDEF)
372 372 (void) printf("break point reached at addr: 0x%x\n",
373 373 EC_WORD(pstatus.pr_lwp.pr_reg[R_PC]));
374 374
375 375 if (bpt->bl_flags & MASK_BP_SPECIAL)
376 376 handle_sp_break(ph);
377 377
378 378 if (ph->pp_flags & FLG_PP_LMAPS) {
379 - if (get_linkmaps(ph) != PS_OK)
379 + if (get_linkmaps(ph) != RET_OK)
380 380 (void) fprintf(stderr, "problem loading linkmaps\n");
381 381 }
382 382
383 383 return (bpt->bl_flags);
384 384 }
385 385
386 386 ulong_t
387 387 is_plt(struct ps_prochandle *ph, ulong_t pc)
388 388 {
389 389 map_info_t *mip;
390 390 ulong_t pltbase;
391 391
392 392 if ((mip = addr_to_map(ph, pc)) == (map_info_t *)0)
393 393 return ((ulong_t)0);
394 394
395 395 pltbase = mip->mi_pltbase;
396 396 if ((mip->mi_flags & FLG_MI_EXEC) == 0)
397 397 pltbase += mip->mi_addr;
398 398
399 399 if ((pc >= pltbase) && (pc <= (pltbase + mip->mi_pltsize)))
400 400 return (pltbase);
401 401
402 402 return ((ulong_t)0);
403 403 }
404 404
405 405 retc_t
406 406 step_n(struct ps_prochandle *ph, size_t count, sn_flags_e flgs)
407 407 {
408 408 pstatus_t pstatus;
409 409 fltset_t faults;
410 410 int i;
411 411 long oper;
412 412 long flags;
413 413 struct iovec piov[2];
414 414
415 415 if (pread(ph->pp_statusfd, &pstatus, sizeof (pstatus), 0) == -1)
416 416 perr("stn: reading status");
417 417
418 418 piov[0].iov_base = (caddr_t)(&oper);
419 419 piov[0].iov_len = sizeof (oper);
420 420
421 421 premptyset(&faults);
422 422 praddset(&faults, FLTTRACE);
423 423
424 424 flags = PRSTEP | PRCFAULT;
425 425
426 426 for (i = 0; i < count; i++) {
427 427 bptlist_t *bpt;
428 428 uintptr_t pc, pltbase;
429 429
430 430 pc = pstatus.pr_lwp.pr_reg[R_PC];
431 431
432 432 if ((bpt = find_bp(ph, pc)) != (bptlist_t *)-1) {
433 433 if (bpt->bl_flags & MASK_BP_SPECIAL)
434 434 handle_sp_break(ph);
435 435 }
436 436
437 437 if (flgs & FLG_SN_VERBOSE)
438 438 disasm(ph, 1);
439 439
440 440 oper = PCSFAULT;
441 441 piov[1].iov_base = (caddr_t)(&faults);
442 442 piov[1].iov_len = sizeof (faults);
443 443
444 444 if (writev(ph->pp_ctlfd, piov, 2) == -1)
445 445 perr("stn: PCSFAULT");
446 446
447 447 oper = PCRUN;
448 448 piov[1].iov_base = (caddr_t)(&flags);
449 449 piov[1].iov_len = sizeof (flags);
450 450 if (writev(ph->pp_ctlfd, piov, 2) == -1)
451 451 perr("stn: PCRUN(PRSETP)");
452 452
453 453 oper = PCWSTOP;
454 454 if (writev(ph->pp_ctlfd, piov, 1) == -1)
455 455 perr("stn: PCWSTOP stepping");
456 456
457 457 if (pread(ph->pp_statusfd, &pstatus, sizeof (pstatus), 0) == -1)
458 458 perr("stn1: reading status");
459 459 pc = pstatus.pr_lwp.pr_reg[R_PC];
460 460
461 461
462 462 if ((pstatus.pr_lwp.pr_why != PR_FAULTED) ||
463 463 (pstatus.pr_lwp.pr_what != FLTTRACE)) {
464 464 (void) fprintf(stderr, "sn: bad stop - stopped on "
465 465 "why: 0x%x what: 0x%x\n", pstatus.pr_lwp.pr_why,
466 466 pstatus.pr_lwp.pr_what);
467 467 return (RET_FAILED);
468 468 }
469 469
470 470 if ((flgs & FLG_SN_PLTSKIP) &&
471 471 ((pltbase = is_plt(ph, pc)) != (ulong_t)0)) {
472 472 rd_plt_info_t rp;
473 473 if (rd_plt_resolution(ph->pp_rap, pc,
474 474 pstatus.pr_lwp.pr_lwpid, pltbase, &rp) != RD_OK) {
475 475 (void) fprintf(stderr,
476 476 "sn: rd_plt_resolution failed\n");
477 477 return (RET_FAILED);
478 478 }
479 479 if (rp.pi_skip_method == RD_RESOLVE_TARGET_STEP) {
480 480 unsigned bpflags;
481 481
482 482 (void) set_breakpoint(ph, rp.pi_target,
483 483 FLG_BP_PLTRES);
484 484 bpflags = continue_to_break(ph);
485 485
486 486 (void) delete_breakpoint(ph, rp.pi_target,
487 487 FLG_BP_PLTRES);
488 488
489 489 if (bpflags & FLG_BP_PLTRES)
490 490 (void) step_n(ph, rp.pi_nstep,
491 491 FLG_SN_NONE);
↓ open down ↓ |
102 lines elided |
↑ open up ↑ |
492 492 } else if (rp.pi_skip_method == RD_RESOLVE_STEP)
493 493 (void) step_n(ph, rp.pi_nstep, FLG_SN_NONE);
494 494 }
495 495 }
496 496
497 497 oper = PRCFAULT;
498 498 if (writev(ph->pp_ctlfd, piov, 1) == -1)
499 499 perr("stn: PRCFAULT");
500 500
501 501 if ((flgs & FLG_SN_VERBOSE) && (ph->pp_flags & FLG_PP_LMAPS)) {
502 - if (get_linkmaps(ph) != PS_OK)
502 + if (get_linkmaps(ph) != RET_OK)
503 503 (void) fprintf(stderr, "problem loading linkmaps\n");
504 504 }
505 505
506 506 return (RET_OK);
507 507 }
508 508
509 509 void
510 510 step_to_addr(struct ps_prochandle *ph, ulong_t addr)
511 511 {
512 512 pstatus_t pstat;
513 513 int count = 0;
514 514 ulong_t caddr;
515 515
516 516 if (read(ph->pp_statusfd, &pstat, sizeof (pstat)) == -1)
517 517 perr("sta: reading status");
518 518
519 519 caddr = pstat.pr_lwp.pr_reg[R_PC];
520 520
521 521 while ((caddr > addr) || ((caddr + 0xff) < addr)) {
522 522 (void) step_n(ph, 1, FLG_SN_NONE);
523 523 if (read(ph->pp_statusfd, &pstat, sizeof (pstat)) == -1)
524 524 perr("sta1: reading status");
525 525 caddr = pstat.pr_lwp.pr_reg[R_PC];
526 526 if ((count % 10000) == 0) {
527 527 (void) printf("%d: ", count);
528 528 disasm(ph, 1);
529 529 }
530 530
531 531 count++;
532 532 }
533 533
534 534 (void) printf("address found %d instructions in: pc: 0x%lx addr: "
535 535 "0x%lx\n", count, caddr, addr);
536 536 }
↓ open down ↓ |
24 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX