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 44int 45arch_translate_address_dyn(struct process *proc, 46 arch_addr_t addr, arch_addr_t *ret) 47{ 48 *ret = addr; 49 return 0; 50} 51 52struct ltelf; 53int 54arch_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 62void 63breakpoint_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 70void 71breakpoint_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 80void 81breakpoint_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 88void 89breakpoint_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 96int 97breakpoint_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 112struct breakpoint * 113address2bpstruct(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 127int 128os_breakpoint_init(struct process *proc, struct breakpoint *sbp) 129{ 130 return 0; 131} 132 133void 134os_breakpoint_destroy(struct breakpoint *sbp) 135{ 136} 137 138int 139os_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp) 140{ 141 return 0; 142} 143#endif 144 145#ifndef ARCH_HAVE_BREAKPOINT_DATA 146int 147arch_breakpoint_init(struct process *proc, struct breakpoint *sbp) 148{ 149 return 0; 150} 151 152void 153arch_breakpoint_destroy(struct breakpoint *sbp) 154{ 155} 156 157int 158arch_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp) 159{ 160 return 0; 161} 162#endif 163 164static void 165breakpoint_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. */ 179int 180breakpoint_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 193void 194breakpoint_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 201void 202breakpoint_destroy(struct breakpoint *bp) 203{ 204 if (bp == NULL) 205 return; 206 arch_breakpoint_destroy(bp); 207 os_breakpoint_destroy(bp); 208} 209 210int 211breakpoint_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 233int 234breakpoint_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 245int 246breakpoint_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 255struct breakpoint * 256create_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 268struct breakpoint * 269insert_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 300struct breakpoint * 301insert_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 332void 333delete_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 351int 352delete_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 369const char * 370breakpoint_name(const struct breakpoint *bp) 371{ 372 assert(bp != NULL); 373 return bp->libsym != NULL ? bp->libsym->name : NULL; 374} 375 376struct library * 377breakpoint_library(const struct breakpoint *bp) 378{ 379 assert(bp != NULL); 380 return bp->libsym != NULL ? bp->libsym->lib : NULL; 381} 382 383static enum callback_status 384disable_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 393void 394disable_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 402static void 403entry_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 411int 412entry_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 428int 429breakpoints_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