1 /* 2 * This file is part of ltrace. 3 * Copyright (C) 2006,2007,2011,2012,2013,2014 Petr Machata, Red Hat Inc. 4 * Copyright (C) 2009 Juan Cespedes 5 * Copyright (C) 1998,2001,2002,2003,2007,2008,2009 Juan Cespedes 6 * Copyright (C) 2006 Ian Wienand 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of the 11 * License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 * 02110-1301 USA 22 */ 23 24 #include "config.h" 25 26 #include <assert.h> 27 #include <errno.h> 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <string.h> 31 32 #ifdef __powerpc__ 33 #include <sys/ptrace.h> 34 #endif 35 36 #include "backend.h" 37 #include "breakpoint.h" 38 #include "debug.h" 39 #include "library.h" 40 #include "ltrace-elf.h" 41 #include "proc.h" 42 43 #ifndef ARCH_HAVE_TRANSLATE_ADDRESS 44 int 45 arch_translate_address_dyn(struct process *proc, 46 arch_addr_t addr, arch_addr_t *ret) 47 { 48 *ret = addr; 49 return 0; 50 } 51 52 struct ltelf; 53 int 54 arch_translate_address(struct ltelf *lte, 55 arch_addr_t addr, arch_addr_t *ret) 56 { 57 *ret = addr; 58 return 0; 59 } 60 #endif 61 62 void 63 breakpoint_on_hit(struct breakpoint *bp, struct process *proc) 64 { 65 assert(bp != NULL); 66 if (bp->cbs != NULL && bp->cbs->on_hit != NULL) 67 (bp->cbs->on_hit)(bp, proc); 68 } 69 70 void 71 breakpoint_on_continue(struct breakpoint *bp, struct process *proc) 72 { 73 assert(bp != NULL); 74 if (bp->cbs != NULL && bp->cbs->on_continue != NULL) 75 (bp->cbs->on_continue)(bp, proc); 76 else 77 continue_after_breakpoint(proc, bp); 78 } 79 80 void 81 breakpoint_on_retract(struct breakpoint *bp, struct process *proc) 82 { 83 assert(bp != NULL); 84 if (bp->cbs != NULL && bp->cbs->on_retract != NULL) 85 (bp->cbs->on_retract)(bp, proc); 86 } 87 88 void 89 breakpoint_on_install(struct breakpoint *bp, struct process *proc) 90 { 91 assert(bp != NULL); 92 if (bp->cbs != NULL && bp->cbs->on_install != NULL) 93 (bp->cbs->on_install)(bp, proc); 94 } 95 96 int 97 breakpoint_get_return_bp(struct breakpoint **ret, 98 struct breakpoint *bp, struct process *proc) 99 { 100 assert(bp != NULL); 101 if (bp->cbs != NULL && bp->cbs->get_return_bp != NULL) 102 return (bp->cbs->get_return_bp)(ret, bp, proc); 103 104 if ((*ret = create_default_return_bp(proc)) == NULL) 105 return -1; 106 107 return 0; 108 } 109 110 /*****************************************************************************/ 111 112 struct breakpoint * 113 address2bpstruct(struct process *proc, arch_addr_t addr) 114 { 115 assert(proc != NULL); 116 assert(proc->breakpoints != NULL); 117 assert(proc->leader == proc); 118 debug(DEBUG_FUNCTION, "address2bpstruct(pid=%d, addr=%p)", proc->pid, addr); 119 120 struct breakpoint *found; 121 if (DICT_FIND_VAL(proc->breakpoints, &addr, &found) < 0) 122 return NULL; 123 return found; 124 } 125 126 #ifndef OS_HAVE_BREAKPOINT_DATA 127 int 128 os_breakpoint_init(struct process *proc, struct breakpoint *sbp) 129 { 130 return 0; 131 } 132 133 void 134 os_breakpoint_destroy(struct breakpoint *sbp) 135 { 136 } 137 138 int 139 os_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp) 140 { 141 return 0; 142 } 143 #endif 144 145 #ifndef ARCH_HAVE_BREAKPOINT_DATA 146 int 147 arch_breakpoint_init(struct process *proc, struct breakpoint *sbp) 148 { 149 return 0; 150 } 151 152 void 153 arch_breakpoint_destroy(struct breakpoint *sbp) 154 { 155 } 156 157 int 158 arch_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp) 159 { 160 return 0; 161 } 162 #endif 163 164 static void 165 breakpoint_init_base(struct breakpoint *bp, 166 arch_addr_t addr, struct library_symbol *libsym) 167 { 168 bp->cbs = NULL; 169 bp->addr = addr; 170 memset(bp->orig_value, 0, sizeof(bp->orig_value)); 171 bp->enabled = 0; 172 bp->libsym = libsym; 173 } 174 175 /* On second thought, I don't think we need PROC. All the translation 176 * (arch_translate_address in particular) should be doable using 177 * static lookups of various sections in the ELF file. We shouldn't 178 * need process for anything. */ 179 int 180 breakpoint_init(struct breakpoint *bp, struct process *proc, 181 arch_addr_t addr, struct library_symbol *libsym) 182 { 183 breakpoint_init_base(bp, addr, libsym); 184 if (os_breakpoint_init(proc, bp) < 0) 185 return -1; 186 if (arch_breakpoint_init(proc, bp) < 0) { 187 os_breakpoint_destroy(bp); 188 return -1; 189 } 190 return 0; 191 } 192 193 void 194 breakpoint_set_callbacks(struct breakpoint *bp, struct bp_callbacks *cbs) 195 { 196 if (bp->cbs != NULL) 197 assert(bp->cbs == NULL); 198 bp->cbs = cbs; 199 } 200 201 void 202 breakpoint_destroy(struct breakpoint *bp) 203 { 204 if (bp == NULL) 205 return; 206 arch_breakpoint_destroy(bp); 207 os_breakpoint_destroy(bp); 208 } 209 210 int 211 breakpoint_clone(struct breakpoint *retp, struct process *new_proc, 212 struct breakpoint *bp) 213 { 214 struct library_symbol *libsym = NULL; 215 if (bp->libsym != NULL) { 216 int rc = proc_find_symbol(new_proc, bp->libsym, NULL, &libsym); 217 assert(rc == 0); 218 } 219 220 breakpoint_init_base(retp, bp->addr, libsym); 221 memcpy(retp->orig_value, bp->orig_value, sizeof(bp->orig_value)); 222 retp->enabled = bp->enabled; 223 if (os_breakpoint_clone(retp, bp) < 0) 224 return -1; 225 if (arch_breakpoint_clone(retp, bp) < 0) { 226 os_breakpoint_destroy(retp); 227 return -1; 228 } 229 breakpoint_set_callbacks(retp, bp->cbs); 230 return 0; 231 } 232 233 int 234 breakpoint_turn_on(struct breakpoint *bp, struct process *proc) 235 { 236 bp->enabled++; 237 if (bp->enabled == 1) { 238 assert(proc->pid != 0); 239 enable_breakpoint(proc, bp); 240 breakpoint_on_install(bp, proc); 241 } 242 return 0; 243 } 244 245 int 246 breakpoint_turn_off(struct breakpoint *bp, struct process *proc) 247 { 248 bp->enabled--; 249 if (bp->enabled == 0) 250 disable_breakpoint(proc, bp); 251 assert(bp->enabled >= 0); 252 return 0; 253 } 254 255 struct breakpoint * 256 create_default_return_bp(struct process *proc) 257 { 258 struct breakpoint *bp = malloc(sizeof *bp); 259 arch_addr_t return_addr = get_return_addr(proc, proc->stack_pointer); 260 if (return_addr == 0 || bp == NULL 261 || breakpoint_init(bp, proc, return_addr, NULL) < 0) { 262 free(bp); 263 return NULL; 264 } 265 return bp; 266 } 267 268 struct breakpoint * 269 insert_breakpoint_at(struct process *proc, arch_addr_t addr, 270 struct library_symbol *libsym) 271 { 272 debug(DEBUG_FUNCTION, 273 "insert_breakpoint_at(pid=%d, addr=%p, symbol=%s)", 274 proc->pid, addr, libsym ? libsym->name : "NULL"); 275 276 assert(addr != 0); 277 278 struct breakpoint *bp = malloc(sizeof *bp); 279 if (bp == NULL || breakpoint_init(bp, proc, addr, libsym) < 0) { 280 free(bp); 281 return NULL; 282 } 283 284 /* N.B. (and XXX): BP->addr might differ from ADDR. On ARM 285 * this is a real possibility. The problem here is that to 286 * create a return breakpoint ltrace calls get_return_addr and 287 * then insert_breakpoint_at. So get_return_addr needs to 288 * encode all the information necessary for breakpoint_init 289 * into the address itself, so ADDR is potentially 290 * mangled. */ 291 292 struct breakpoint *tmp = insert_breakpoint(proc, bp); 293 if (tmp != bp) { 294 breakpoint_destroy(bp); 295 free(bp); 296 } 297 return tmp; 298 } 299 300 struct breakpoint * 301 insert_breakpoint(struct process *proc, struct breakpoint *bp) 302 { 303 /* Only the group leader should be getting the breakpoints and 304 * thus have ->breakpoint initialized. */ 305 struct process *leader = proc->leader; 306 assert(leader != NULL); 307 assert(leader->breakpoints != NULL); 308 309 /* XXX what we need to do instead is have a list of 310 * breakpoints that are enabled at this address. The 311 * following works if every breakpoint is the same and there's 312 * no extra data, but that doesn't hold anymore. For now it 313 * will suffice, about the only realistic case where we need 314 * to have more than one breakpoint per address is return from 315 * a recursive library call. */ 316 struct breakpoint *ext_bp = bp; 317 if (DICT_FIND_VAL(leader->breakpoints, &bp->addr, &ext_bp) != 0) { 318 if (proc_add_breakpoint(leader, bp) < 0) 319 return NULL; 320 ext_bp = bp; 321 } 322 323 if (breakpoint_turn_on(ext_bp, proc) < 0) { 324 if (ext_bp != bp) 325 proc_remove_breakpoint(leader, bp); 326 return NULL; 327 } 328 329 return ext_bp; 330 } 331 332 void 333 delete_breakpoint_at(struct process *proc, arch_addr_t addr) 334 { 335 debug(DEBUG_FUNCTION, "delete_breakpoint_at(pid=%d, addr=%p)", 336 proc->pid, addr); 337 338 struct process *leader = proc->leader; 339 assert(leader != NULL); 340 341 struct breakpoint *bp = NULL; 342 DICT_FIND_VAL(leader->breakpoints, &addr, &bp); 343 assert(bp != NULL); 344 345 if (delete_breakpoint(proc, bp) < 0) { 346 fprintf(stderr, "Couldn't turn off the breakpoint %s@%p\n", 347 breakpoint_name(bp), bp->addr); 348 } 349 } 350 351 int 352 delete_breakpoint(struct process *proc, struct breakpoint *bp) 353 { 354 struct process *leader = proc->leader; 355 assert(leader != NULL); 356 357 if (breakpoint_turn_off(bp, proc) < 0) 358 return -1; 359 360 if (bp->enabled == 0) { 361 proc_remove_breakpoint(leader, bp); 362 breakpoint_destroy(bp); 363 free(bp); 364 } 365 366 return 0; 367 } 368 369 const char * 370 breakpoint_name(const struct breakpoint *bp) 371 { 372 assert(bp != NULL); 373 return bp->libsym != NULL ? bp->libsym->name : NULL; 374 } 375 376 struct library * 377 breakpoint_library(const struct breakpoint *bp) 378 { 379 assert(bp != NULL); 380 return bp->libsym != NULL ? bp->libsym->lib : NULL; 381 } 382 383 static enum callback_status 384 disable_bp_cb(arch_addr_t *addr, struct breakpoint **bpp, void *data) 385 { 386 struct process *proc = data; 387 debug(DEBUG_FUNCTION, "disable_bp_cb(pid=%d)", proc->pid); 388 if ((*bpp)->enabled) 389 disable_breakpoint(proc, *bpp); 390 return CBS_CONT; 391 } 392 393 void 394 disable_all_breakpoints(struct process *proc) 395 { 396 debug(DEBUG_FUNCTION, "disable_all_breakpoints(pid=%d)", proc->pid); 397 assert(proc->leader == proc); 398 DICT_EACH(proc->breakpoints, arch_addr_t, struct breakpoint *, 399 NULL, disable_bp_cb, proc); 400 } 401 402 static void 403 entry_breakpoint_on_hit(struct breakpoint *bp, struct process *proc) 404 { 405 if (proc == NULL || proc->leader == NULL) 406 return; 407 delete_breakpoint_at(proc, bp->addr); 408 process_hit_start(proc); 409 } 410 411 int 412 entry_breakpoint_init(struct process *proc, 413 struct breakpoint *bp, arch_addr_t addr, 414 struct library *lib) 415 { 416 assert(addr != 0); 417 int err = breakpoint_init(bp, proc, addr, NULL); 418 if (err < 0) 419 return err; 420 421 static struct bp_callbacks entry_callbacks = { 422 .on_hit = entry_breakpoint_on_hit, 423 }; 424 bp->cbs = &entry_callbacks; 425 return 0; 426 } 427 428 int 429 breakpoints_init(struct process *proc) 430 { 431 debug(DEBUG_FUNCTION, "breakpoints_init(pid=%d)", proc->pid); 432 433 /* XXX breakpoint dictionary should be initialized 434 * outside. Here we just put in breakpoints. */ 435 assert(proc->breakpoints != NULL); 436 437 /* Only the thread group leader should hold the breakpoints. */ 438 assert(proc->leader == proc); 439 440 /* N.B. the following used to be conditional on this, and 441 * maybe it still needs to be. */ 442 assert(proc->filename != NULL); 443 444 struct library *lib = ltelf_read_main_binary(proc, proc->filename); 445 struct breakpoint *entry_bp = NULL; 446 int bp_state = 0; 447 int result = -1; 448 switch ((int)(lib != NULL)) { 449 fail: 450 switch (bp_state) { 451 case 2: 452 proc_remove_library(proc, lib); 453 proc_remove_breakpoint(proc, entry_bp); 454 case 1: 455 breakpoint_destroy(entry_bp); 456 } 457 library_destroy(lib); 458 free(entry_bp); 459 case 0: 460 return result; 461 } 462 463 entry_bp = malloc(sizeof(*entry_bp)); 464 if (entry_bp == NULL 465 || (entry_breakpoint_init(proc, entry_bp, 466 lib->entry, lib)) < 0) { 467 fprintf(stderr, 468 "Couldn't initialize entry breakpoint for PID %d.\n" 469 "Some tracing events may be missed.\n", proc->pid); 470 free(entry_bp); 471 472 } else { 473 ++bp_state; 474 475 if ((result = proc_add_breakpoint(proc, entry_bp)) < 0) 476 goto fail; 477 ++bp_state; 478 479 if ((result = breakpoint_turn_on(entry_bp, proc)) < 0) 480 goto fail; 481 } 482 proc_add_library(proc, lib); 483 484 proc->callstack_depth = 0; 485 return 0; 486 } 487