| OLD | NEW |
| 1 /* Process record and replay target for GDB, the GNU debugger. | 1 /* Process record and replay target for GDB, the GNU debugger. |
| 2 | 2 |
| 3 Copyright (C) 2008-2012 Free Software Foundation, Inc. | 3 Copyright (C) 2008-2012 Free Software Foundation, Inc. |
| 4 | 4 |
| 5 This file is part of GDB. | 5 This file is part of GDB. |
| 6 | 6 |
| 7 This program is free software; you can redistribute it and/or modify | 7 This program is free software; you can redistribute it and/or modify |
| 8 it under the terms of the GNU General Public License as published by | 8 it under the terms of the GNU General Public License as published by |
| 9 the Free Software Foundation; either version 3 of the License, or | 9 the Free Software Foundation; either version 3 of the License, or |
| 10 (at your option) any later version. | 10 (at your option) any later version. |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 unsigned short len; | 93 unsigned short len; |
| 94 union | 94 union |
| 95 { | 95 { |
| 96 gdb_byte *ptr; | 96 gdb_byte *ptr; |
| 97 gdb_byte buf[2 * sizeof (gdb_byte *)]; | 97 gdb_byte buf[2 * sizeof (gdb_byte *)]; |
| 98 } u; | 98 } u; |
| 99 }; | 99 }; |
| 100 | 100 |
| 101 struct record_end_entry | 101 struct record_end_entry |
| 102 { | 102 { |
| 103 enum target_signal sigval; | 103 enum gdb_signal sigval; |
| 104 ULONGEST insn_num; | 104 ULONGEST insn_num; |
| 105 }; | 105 }; |
| 106 | 106 |
| 107 enum record_type | 107 enum record_type |
| 108 { | 108 { |
| 109 record_end = 0, | 109 record_end = 0, |
| 110 record_reg, | 110 record_reg, |
| 111 record_mem | 111 record_mem |
| 112 }; | 112 }; |
| 113 | 113 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 than count of insns presently in execution log). */ | 202 than count of insns presently in execution log). */ |
| 203 static ULONGEST record_insn_count; | 203 static ULONGEST record_insn_count; |
| 204 | 204 |
| 205 /* The target_ops of process record. */ | 205 /* The target_ops of process record. */ |
| 206 static struct target_ops record_ops; | 206 static struct target_ops record_ops; |
| 207 static struct target_ops record_core_ops; | 207 static struct target_ops record_core_ops; |
| 208 | 208 |
| 209 /* The beneath function pointers. */ | 209 /* The beneath function pointers. */ |
| 210 static struct target_ops *record_beneath_to_resume_ops; | 210 static struct target_ops *record_beneath_to_resume_ops; |
| 211 static void (*record_beneath_to_resume) (struct target_ops *, ptid_t, int, | 211 static void (*record_beneath_to_resume) (struct target_ops *, ptid_t, int, |
| 212 enum target_signal); | 212 enum gdb_signal); |
| 213 static struct target_ops *record_beneath_to_wait_ops; | 213 static struct target_ops *record_beneath_to_wait_ops; |
| 214 static ptid_t (*record_beneath_to_wait) (struct target_ops *, ptid_t, | 214 static ptid_t (*record_beneath_to_wait) (struct target_ops *, ptid_t, |
| 215 struct target_waitstatus *, | 215 struct target_waitstatus *, |
| 216 int); | 216 int); |
| 217 static struct target_ops *record_beneath_to_store_registers_ops; | 217 static struct target_ops *record_beneath_to_store_registers_ops; |
| 218 static void (*record_beneath_to_store_registers) (struct target_ops *, | 218 static void (*record_beneath_to_store_registers) (struct target_ops *, |
| 219 struct regcache *, | 219 struct regcache *, |
| 220 int regno); | 220 int regno); |
| 221 static struct target_ops *record_beneath_to_xfer_partial_ops; | 221 static struct target_ops *record_beneath_to_xfer_partial_ops; |
| 222 static LONGEST (*record_beneath_to_xfer_partial) (struct target_ops *ops, | 222 static LONGEST (*record_beneath_to_xfer_partial) (struct target_ops *ops, |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 int | 524 int |
| 525 record_arch_list_add_end (void) | 525 record_arch_list_add_end (void) |
| 526 { | 526 { |
| 527 struct record_entry *rec; | 527 struct record_entry *rec; |
| 528 | 528 |
| 529 if (record_debug > 1) | 529 if (record_debug > 1) |
| 530 fprintf_unfiltered (gdb_stdlog, | 530 fprintf_unfiltered (gdb_stdlog, |
| 531 "Process record: add end to arch list.\n"); | 531 "Process record: add end to arch list.\n"); |
| 532 | 532 |
| 533 rec = record_end_alloc (); | 533 rec = record_end_alloc (); |
| 534 rec->u.end.sigval = TARGET_SIGNAL_0; | 534 rec->u.end.sigval = GDB_SIGNAL_0; |
| 535 rec->u.end.insn_num = ++record_insn_count; | 535 rec->u.end.insn_num = ++record_insn_count; |
| 536 | 536 |
| 537 record_arch_list_add (rec); | 537 record_arch_list_add (rec); |
| 538 | 538 |
| 539 return 0; | 539 return 0; |
| 540 } | 540 } |
| 541 | 541 |
| 542 static void | 542 static void |
| 543 record_check_insn_num (int set_terminal) | 543 record_check_insn_num (int set_terminal) |
| 544 { | 544 { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 574 record_list_release (record_arch_list_tail); | 574 record_list_release (record_arch_list_tail); |
| 575 } | 575 } |
| 576 | 576 |
| 577 /* Before inferior step (when GDB record the running message, inferior | 577 /* Before inferior step (when GDB record the running message, inferior |
| 578 only can step), GDB will call this function to record the values to | 578 only can step), GDB will call this function to record the values to |
| 579 record_list. This function will call gdbarch_process_record to | 579 record_list. This function will call gdbarch_process_record to |
| 580 record the running message of inferior and set them to | 580 record the running message of inferior and set them to |
| 581 record_arch_list, and add it to record_list. */ | 581 record_arch_list, and add it to record_list. */ |
| 582 | 582 |
| 583 static int | 583 static int |
| 584 record_message (struct regcache *regcache, enum target_signal signal) | 584 record_message (struct regcache *regcache, enum gdb_signal signal) |
| 585 { | 585 { |
| 586 int ret; | 586 int ret; |
| 587 struct gdbarch *gdbarch = get_regcache_arch (regcache); | 587 struct gdbarch *gdbarch = get_regcache_arch (regcache); |
| 588 struct cleanup *old_cleanups = make_cleanup (record_arch_list_cleanups, 0); | 588 struct cleanup *old_cleanups = make_cleanup (record_arch_list_cleanups, 0); |
| 589 | 589 |
| 590 record_arch_list_head = NULL; | 590 record_arch_list_head = NULL; |
| 591 record_arch_list_tail = NULL; | 591 record_arch_list_tail = NULL; |
| 592 | 592 |
| 593 /* Check record_insn_num. */ | 593 /* Check record_insn_num. */ |
| 594 record_check_insn_num (1); | 594 record_check_insn_num (1); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 614 | 614 |
| 615 But we should still deliver the signal to gdb during the replay, | 615 But we should still deliver the signal to gdb during the replay, |
| 616 if we delivered it during the recording. Therefore we should | 616 if we delivered it during the recording. Therefore we should |
| 617 record the signal during record_wait, not record_resume. */ | 617 record the signal during record_wait, not record_resume. */ |
| 618 if (record_list != &record_first) /* FIXME better way to check */ | 618 if (record_list != &record_first) /* FIXME better way to check */ |
| 619 { | 619 { |
| 620 gdb_assert (record_list->type == record_end); | 620 gdb_assert (record_list->type == record_end); |
| 621 record_list->u.end.sigval = signal; | 621 record_list->u.end.sigval = signal; |
| 622 } | 622 } |
| 623 | 623 |
| 624 if (signal == TARGET_SIGNAL_0 | 624 if (signal == GDB_SIGNAL_0 |
| 625 || !gdbarch_process_record_signal_p (gdbarch)) | 625 || !gdbarch_process_record_signal_p (gdbarch)) |
| 626 ret = gdbarch_process_record (gdbarch, | 626 ret = gdbarch_process_record (gdbarch, |
| 627 regcache, | 627 regcache, |
| 628 regcache_read_pc (regcache)); | 628 regcache_read_pc (regcache)); |
| 629 else | 629 else |
| 630 ret = gdbarch_process_record_signal (gdbarch, | 630 ret = gdbarch_process_record_signal (gdbarch, |
| 631 regcache, | 631 regcache, |
| 632 signal); | 632 signal); |
| 633 | 633 |
| 634 if (ret > 0) | 634 if (ret > 0) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 645 if (record_insn_num == record_insn_max_num && record_insn_max_num) | 645 if (record_insn_num == record_insn_max_num && record_insn_max_num) |
| 646 record_list_release_first (); | 646 record_list_release_first (); |
| 647 else | 647 else |
| 648 record_insn_num++; | 648 record_insn_num++; |
| 649 | 649 |
| 650 return 1; | 650 return 1; |
| 651 } | 651 } |
| 652 | 652 |
| 653 struct record_message_args { | 653 struct record_message_args { |
| 654 struct regcache *regcache; | 654 struct regcache *regcache; |
| 655 enum target_signal signal; | 655 enum gdb_signal signal; |
| 656 }; | 656 }; |
| 657 | 657 |
| 658 static int | 658 static int |
| 659 record_message_wrapper (void *args) | 659 record_message_wrapper (void *args) |
| 660 { | 660 { |
| 661 struct record_message_args *record_args = args; | 661 struct record_message_args *record_args = args; |
| 662 | 662 |
| 663 return record_message (record_args->regcache, record_args->signal); | 663 return record_message (record_args->regcache, record_args->signal); |
| 664 } | 664 } |
| 665 | 665 |
| 666 static int | 666 static int |
| 667 record_message_wrapper_safe (struct regcache *regcache, | 667 record_message_wrapper_safe (struct regcache *regcache, |
| 668 enum target_signal signal) | 668 enum gdb_signal signal) |
| 669 { | 669 { |
| 670 struct record_message_args args; | 670 struct record_message_args args; |
| 671 | 671 |
| 672 args.regcache = regcache; | 672 args.regcache = regcache; |
| 673 args.signal = signal; | 673 args.signal = signal; |
| 674 | 674 |
| 675 return catch_errors (record_message_wrapper, &args, NULL, RETURN_MASK_ALL); | 675 return catch_errors (record_message_wrapper, &args, NULL, RETURN_MASK_ALL); |
| 676 } | 676 } |
| 677 | 677 |
| 678 /* Set to 1 if record_store_registers and record_xfer_partial | 678 /* Set to 1 if record_store_registers and record_xfer_partial |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 } | 779 } |
| 780 } | 780 } |
| 781 } | 781 } |
| 782 } | 782 } |
| 783 break; | 783 break; |
| 784 } | 784 } |
| 785 } | 785 } |
| 786 | 786 |
| 787 static struct target_ops *tmp_to_resume_ops; | 787 static struct target_ops *tmp_to_resume_ops; |
| 788 static void (*tmp_to_resume) (struct target_ops *, ptid_t, int, | 788 static void (*tmp_to_resume) (struct target_ops *, ptid_t, int, |
| 789 » » » enum target_signal); | 789 » » » enum gdb_signal); |
| 790 static struct target_ops *tmp_to_wait_ops; | 790 static struct target_ops *tmp_to_wait_ops; |
| 791 static ptid_t (*tmp_to_wait) (struct target_ops *, ptid_t, | 791 static ptid_t (*tmp_to_wait) (struct target_ops *, ptid_t, |
| 792 struct target_waitstatus *, | 792 struct target_waitstatus *, |
| 793 int); | 793 int); |
| 794 static struct target_ops *tmp_to_store_registers_ops; | 794 static struct target_ops *tmp_to_store_registers_ops; |
| 795 static void (*tmp_to_store_registers) (struct target_ops *, | 795 static void (*tmp_to_store_registers) (struct target_ops *, |
| 796 struct regcache *, | 796 struct regcache *, |
| 797 int regno); | 797 int regno); |
| 798 static struct target_ops *tmp_to_xfer_partial_ops; | 798 static struct target_ops *tmp_to_xfer_partial_ops; |
| 799 static LONGEST (*tmp_to_xfer_partial) (struct target_ops *ops, | 799 static LONGEST (*tmp_to_xfer_partial) (struct target_ops *ops, |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 889 if (!tmp_to_stopped_by_watchpoint) | 889 if (!tmp_to_stopped_by_watchpoint) |
| 890 error (_("Could not find 'to_stopped_by_watchpoint' " | 890 error (_("Could not find 'to_stopped_by_watchpoint' " |
| 891 "method on the target stack.")); | 891 "method on the target stack.")); |
| 892 if (!tmp_to_stopped_data_address) | 892 if (!tmp_to_stopped_data_address) |
| 893 error (_("Could not find 'to_stopped_data_address' " | 893 error (_("Could not find 'to_stopped_data_address' " |
| 894 "method on the target stack.")); | 894 "method on the target stack.")); |
| 895 | 895 |
| 896 push_target (&record_ops); | 896 push_target (&record_ops); |
| 897 } | 897 } |
| 898 | 898 |
| 899 static void record_init_record_breakpoints (void); |
| 900 |
| 899 /* "to_open" target method. Open the process record target. */ | 901 /* "to_open" target method. Open the process record target. */ |
| 900 | 902 |
| 901 static void | 903 static void |
| 902 record_open (char *name, int from_tty) | 904 record_open (char *name, int from_tty) |
| 903 { | 905 { |
| 904 struct target_ops *t; | 906 struct target_ops *t; |
| 905 | 907 |
| 906 if (record_debug) | 908 if (record_debug) |
| 907 fprintf_unfiltered (gdb_stdlog, "Process record: record_open\n"); | 909 fprintf_unfiltered (gdb_stdlog, "Process record: record_open\n"); |
| 908 | 910 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 986 | 988 |
| 987 if (core_bfd) | 989 if (core_bfd) |
| 988 record_core_open_1 (name, from_tty); | 990 record_core_open_1 (name, from_tty); |
| 989 else | 991 else |
| 990 record_open_1 (name, from_tty); | 992 record_open_1 (name, from_tty); |
| 991 | 993 |
| 992 /* Register extra event sources in the event loop. */ | 994 /* Register extra event sources in the event loop. */ |
| 993 record_async_inferior_event_token | 995 record_async_inferior_event_token |
| 994 = create_async_event_handler (record_async_inferior_event_handler, | 996 = create_async_event_handler (record_async_inferior_event_handler, |
| 995 NULL); | 997 NULL); |
| 998 |
| 999 record_init_record_breakpoints (); |
| 996 } | 1000 } |
| 997 | 1001 |
| 998 /* "to_close" target method. Close the process record target. */ | 1002 /* "to_close" target method. Close the process record target. */ |
| 999 | 1003 |
| 1000 static void | 1004 static void |
| 1001 record_close (int quitting) | 1005 record_close (int quitting) |
| 1002 { | 1006 { |
| 1003 struct record_core_buf_entry *entry; | 1007 struct record_core_buf_entry *entry; |
| 1004 | 1008 |
| 1005 if (record_debug) | 1009 if (record_debug) |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1049 the global execution direction accordingly (to reverse) | 1053 the global execution direction accordingly (to reverse) |
| 1050 7. infrun polls an event out of the record target, and handles it | 1054 7. infrun polls an event out of the record target, and handles it |
| 1051 8. GDB goes back to the event loop, and goto #4. | 1055 8. GDB goes back to the event loop, and goto #4. |
| 1052 */ | 1056 */ |
| 1053 static enum exec_direction_kind record_execution_dir = EXEC_FORWARD; | 1057 static enum exec_direction_kind record_execution_dir = EXEC_FORWARD; |
| 1054 | 1058 |
| 1055 /* "to_resume" target method. Resume the process record target. */ | 1059 /* "to_resume" target method. Resume the process record target. */ |
| 1056 | 1060 |
| 1057 static void | 1061 static void |
| 1058 record_resume (struct target_ops *ops, ptid_t ptid, int step, | 1062 record_resume (struct target_ops *ops, ptid_t ptid, int step, |
| 1059 enum target_signal signal) | 1063 enum gdb_signal signal) |
| 1060 { | 1064 { |
| 1061 record_resume_step = step; | 1065 record_resume_step = step; |
| 1062 record_resumed = 1; | 1066 record_resumed = 1; |
| 1063 record_execution_dir = execution_direction; | 1067 record_execution_dir = execution_direction; |
| 1064 | 1068 |
| 1065 if (!RECORD_IS_REPLAY) | 1069 if (!RECORD_IS_REPLAY) |
| 1066 { | 1070 { |
| 1067 struct gdbarch *gdbarch = target_thread_architecture (ptid); | 1071 struct gdbarch *gdbarch = target_thread_architecture (ptid); |
| 1068 | 1072 |
| 1069 record_message (get_current_regcache (), signal); | 1073 record_message (get_current_regcache (), signal); |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1212 } | 1216 } |
| 1213 | 1217 |
| 1214 if (single_step_breakpoints_inserted ()) | 1218 if (single_step_breakpoints_inserted ()) |
| 1215 remove_single_step_breakpoints (); | 1219 remove_single_step_breakpoints (); |
| 1216 | 1220 |
| 1217 if (record_resume_step) | 1221 if (record_resume_step) |
| 1218 return ret; | 1222 return ret; |
| 1219 | 1223 |
| 1220 /* Is this a SIGTRAP? */ | 1224 /* Is this a SIGTRAP? */ |
| 1221 if (status->kind == TARGET_WAITKIND_STOPPED | 1225 if (status->kind == TARGET_WAITKIND_STOPPED |
| 1222 » » && status->value.sig == TARGET_SIGNAL_TRAP) | 1226 » » && status->value.sig == GDB_SIGNAL_TRAP) |
| 1223 { | 1227 { |
| 1224 struct regcache *regcache; | 1228 struct regcache *regcache; |
| 1225 struct address_space *aspace; | 1229 struct address_space *aspace; |
| 1226 | 1230 |
| 1227 /* Yes -- this is likely our single-step finishing, | 1231 /* Yes -- this is likely our single-step finishing, |
| 1228 but check if there's any reason the core would be | 1232 but check if there's any reason the core would be |
| 1229 interested in the event. */ | 1233 interested in the event. */ |
| 1230 | 1234 |
| 1231 registers_changed (); | 1235 registers_changed (); |
| 1232 regcache = get_current_regcache (); | 1236 regcache = get_current_regcache (); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1254 } | 1258 } |
| 1255 else | 1259 else |
| 1256 { | 1260 { |
| 1257 /* This is a single-step trap. Record the | 1261 /* This is a single-step trap. Record the |
| 1258 insn and issue another step. | 1262 insn and issue another step. |
| 1259 FIXME: this part can be a random SIGTRAP too. | 1263 FIXME: this part can be a random SIGTRAP too. |
| 1260 But GDB cannot handle it. */ | 1264 But GDB cannot handle it. */ |
| 1261 int step = 1; | 1265 int step = 1; |
| 1262 | 1266 |
| 1263 if (!record_message_wrapper_safe (regcache, | 1267 if (!record_message_wrapper_safe (regcache, |
| 1264 TARGET_SIGNAL_0)) | 1268 GDB_SIGNAL_0)) |
| 1265 { | 1269 { |
| 1266 status->kind = TARGET_WAITKIND_STOPPED; | 1270 status->kind = TARGET_WAITKIND_STOPPED; |
| 1267 status->value.sig = TARGET_SIGNAL_0; | 1271 status->value.sig = GDB_SIGNAL_0; |
| 1268 break; | 1272 break; |
| 1269 } | 1273 } |
| 1270 | 1274 |
| 1271 if (gdbarch_software_single_step_p (gdbarch)) | 1275 if (gdbarch_software_single_step_p (gdbarch)) |
| 1272 { | 1276 { |
| 1273 /* Try to insert the software single step breakpoint. | 1277 /* Try to insert the software single step breakpoint. |
| 1274 If insert success, set step to 0. */ | 1278 If insert success, set step to 0. */ |
| 1275 set_executing (inferior_ptid, 0); | 1279 set_executing (inferior_ptid, 0); |
| 1276 reinit_frame_cache (); | 1280 reinit_frame_cache (); |
| 1277 if (gdbarch_software_single_step (gdbarch, | 1281 if (gdbarch_software_single_step (gdbarch, |
| 1278 get_current_frame ()
)) | 1282 get_current_frame ()
)) |
| 1279 step = 0; | 1283 step = 0; |
| 1280 set_executing (inferior_ptid, 1); | 1284 set_executing (inferior_ptid, 1); |
| 1281 } | 1285 } |
| 1282 | 1286 |
| 1283 if (record_debug) | 1287 if (record_debug) |
| 1284 fprintf_unfiltered (gdb_stdlog, | 1288 fprintf_unfiltered (gdb_stdlog, |
| 1285 "Process record: record_wait " | 1289 "Process record: record_wait " |
| 1286 "issuing one more step in the target
beneath\n"); | 1290 "issuing one more step in the target
beneath\n"); |
| 1287 record_beneath_to_resume (record_beneath_to_resume_ops, | 1291 record_beneath_to_resume (record_beneath_to_resume_ops, |
| 1288 ptid, step, | 1292 ptid, step, |
| 1289 » » » » » » TARGET_SIGNAL_0); | 1293 » » » » » » GDB_SIGNAL_0); |
| 1290 continue; | 1294 continue; |
| 1291 } | 1295 } |
| 1292 } | 1296 } |
| 1293 | 1297 |
| 1294 /* The inferior is broken by a breakpoint or a signal. */ | 1298 /* The inferior is broken by a breakpoint or a signal. */ |
| 1295 break; | 1299 break; |
| 1296 } | 1300 } |
| 1297 | 1301 |
| 1298 return ret; | 1302 return ret; |
| 1299 } | 1303 } |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1418 | 1422 |
| 1419 if (record_hw_watchpoint) | 1423 if (record_hw_watchpoint) |
| 1420 { | 1424 { |
| 1421 if (record_debug) | 1425 if (record_debug) |
| 1422 fprintf_unfiltered (gdb_stdlog, | 1426 fprintf_unfiltered (gdb_stdlog, |
| 1423 "Process record: hit hw " | 1427 "Process record: hit hw " |
| 1424 "watchpoint.\n"); | 1428 "watchpoint.\n"); |
| 1425 continue_flag = 0; | 1429 continue_flag = 0; |
| 1426 } | 1430 } |
| 1427 /* Check target signal */ | 1431 /* Check target signal */ |
| 1428 » » if (record_list->u.end.sigval != TARGET_SIGNAL_0) | 1432 » » if (record_list->u.end.sigval != GDB_SIGNAL_0) |
| 1429 /* FIXME: better way to check */ | 1433 /* FIXME: better way to check */ |
| 1430 continue_flag = 0; | 1434 continue_flag = 0; |
| 1431 } | 1435 } |
| 1432 } | 1436 } |
| 1433 | 1437 |
| 1434 if (continue_flag) | 1438 if (continue_flag) |
| 1435 { | 1439 { |
| 1436 if (execution_direction == EXEC_REVERSE) | 1440 if (execution_direction == EXEC_REVERSE) |
| 1437 { | 1441 { |
| 1438 if (record_list->prev) | 1442 if (record_list->prev) |
| 1439 record_list = record_list->prev; | 1443 record_list = record_list->prev; |
| 1440 } | 1444 } |
| 1441 else | 1445 else |
| 1442 { | 1446 { |
| 1443 if (record_list->next) | 1447 if (record_list->next) |
| 1444 record_list = record_list->next; | 1448 record_list = record_list->next; |
| 1445 } | 1449 } |
| 1446 } | 1450 } |
| 1447 } | 1451 } |
| 1448 while (continue_flag); | 1452 while (continue_flag); |
| 1449 | 1453 |
| 1450 replay_out: | 1454 replay_out: |
| 1451 if (record_get_sig) | 1455 if (record_get_sig) |
| 1452 » status->value.sig = TARGET_SIGNAL_INT; | 1456 » status->value.sig = GDB_SIGNAL_INT; |
| 1453 else if (record_list->u.end.sigval != TARGET_SIGNAL_0) | 1457 else if (record_list->u.end.sigval != GDB_SIGNAL_0) |
| 1454 /* FIXME: better way to check */ | 1458 /* FIXME: better way to check */ |
| 1455 status->value.sig = record_list->u.end.sigval; | 1459 status->value.sig = record_list->u.end.sigval; |
| 1456 else | 1460 else |
| 1457 » status->value.sig = TARGET_SIGNAL_TRAP; | 1461 » status->value.sig = GDB_SIGNAL_TRAP; |
| 1458 | 1462 |
| 1459 discard_cleanups (old_cleanups); | 1463 discard_cleanups (old_cleanups); |
| 1460 } | 1464 } |
| 1461 | 1465 |
| 1462 signal (SIGINT, handle_sigint); | 1466 signal (SIGINT, handle_sigint); |
| 1463 | 1467 |
| 1464 do_cleanups (set_cleanups); | 1468 do_cleanups (set_cleanups); |
| 1465 return inferior_ptid; | 1469 return inferior_ptid; |
| 1466 } | 1470 } |
| 1467 | 1471 |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1711 record_list_release_first (); | 1715 record_list_release_first (); |
| 1712 else | 1716 else |
| 1713 record_insn_num++; | 1717 record_insn_num++; |
| 1714 } | 1718 } |
| 1715 | 1719 |
| 1716 return record_beneath_to_xfer_partial (record_beneath_to_xfer_partial_ops, | 1720 return record_beneath_to_xfer_partial (record_beneath_to_xfer_partial_ops, |
| 1717 object, annex, readbuf, writebuf, | 1721 object, annex, readbuf, writebuf, |
| 1718 offset, len); | 1722 offset, len); |
| 1719 } | 1723 } |
| 1720 | 1724 |
| 1721 /* Behavior is conditional on RECORD_IS_REPLAY. | 1725 /* This structure represents a breakpoint inserted while the record |
| 1722 We will not actually insert or remove breakpoints when replaying, | 1726 target is active. We use this to know when to install/remove |
| 1723 nor when recording. */ | 1727 breakpoints in/from the target beneath. For example, a breakpoint |
| 1728 may be inserted while recording, but removed when not replaying nor |
| 1729 recording. In that case, the breakpoint had not been inserted on |
| 1730 the target beneath, so we should not try to remove it there. */ |
| 1731 |
| 1732 struct record_breakpoint |
| 1733 { |
| 1734 /* The address and address space the breakpoint was set at. */ |
| 1735 struct address_space *address_space; |
| 1736 CORE_ADDR addr; |
| 1737 |
| 1738 /* True when the breakpoint has been also installed in the target |
| 1739 beneath. This will be false for breakpoints set during replay or |
| 1740 when recording. */ |
| 1741 int in_target_beneath; |
| 1742 }; |
| 1743 |
| 1744 typedef struct record_breakpoint *record_breakpoint_p; |
| 1745 DEF_VEC_P(record_breakpoint_p); |
| 1746 |
| 1747 /* The list of breakpoints inserted while the record target is |
| 1748 active. */ |
| 1749 VEC(record_breakpoint_p) *record_breakpoints = NULL; |
| 1750 |
| 1751 static void |
| 1752 record_sync_record_breakpoints (struct bp_location *loc, void *data) |
| 1753 { |
| 1754 if (loc->loc_type != bp_loc_software_breakpoint) |
| 1755 return; |
| 1756 |
| 1757 if (loc->inserted) |
| 1758 { |
| 1759 struct record_breakpoint *bp = XNEW (struct record_breakpoint); |
| 1760 |
| 1761 bp->addr = loc->target_info.placed_address; |
| 1762 bp->address_space = loc->target_info.placed_address_space; |
| 1763 |
| 1764 bp->in_target_beneath = 1; |
| 1765 |
| 1766 VEC_safe_push (record_breakpoint_p, record_breakpoints, bp); |
| 1767 } |
| 1768 } |
| 1769 |
| 1770 /* Sync existing breakpoints to record_breakpoints. */ |
| 1771 |
| 1772 static void |
| 1773 record_init_record_breakpoints (void) |
| 1774 { |
| 1775 VEC_free (record_breakpoint_p, record_breakpoints); |
| 1776 |
| 1777 iterate_over_bp_locations (record_sync_record_breakpoints); |
| 1778 } |
| 1779 |
| 1780 /* Behavior is conditional on RECORD_IS_REPLAY. We will not actually |
| 1781 insert or remove breakpoints in the real target when replaying, nor |
| 1782 when recording. */ |
| 1724 | 1783 |
| 1725 static int | 1784 static int |
| 1726 record_insert_breakpoint (struct gdbarch *gdbarch, | 1785 record_insert_breakpoint (struct gdbarch *gdbarch, |
| 1727 struct bp_target_info *bp_tgt) | 1786 struct bp_target_info *bp_tgt) |
| 1728 { | 1787 { |
| 1788 struct record_breakpoint *bp; |
| 1789 int in_target_beneath = 0; |
| 1790 |
| 1729 if (!RECORD_IS_REPLAY) | 1791 if (!RECORD_IS_REPLAY) |
| 1730 { | 1792 { |
| 1731 struct cleanup *old_cleanups = record_gdb_operation_disable_set (); | 1793 /* When recording, we currently always single-step, so we don't |
| 1732 int ret = record_beneath_to_insert_breakpoint (gdbarch, bp_tgt); | 1794 » really need to install regular breakpoints in the inferior. |
| 1795 » However, we do have to insert software single-step |
| 1796 » breakpoints, in case the target can't hardware step. To keep |
| 1797 » things single, we always insert. */ |
| 1798 struct cleanup *old_cleanups; |
| 1799 int ret; |
| 1733 | 1800 |
| 1801 old_cleanups = record_gdb_operation_disable_set (); |
| 1802 ret = record_beneath_to_insert_breakpoint (gdbarch, bp_tgt); |
| 1734 do_cleanups (old_cleanups); | 1803 do_cleanups (old_cleanups); |
| 1735 | 1804 |
| 1736 return ret; | 1805 if (ret != 0) |
| 1806 » return ret; |
| 1807 |
| 1808 in_target_beneath = 1; |
| 1737 } | 1809 } |
| 1738 | 1810 |
| 1811 bp = XNEW (struct record_breakpoint); |
| 1812 bp->addr = bp_tgt->placed_address; |
| 1813 bp->address_space = bp_tgt->placed_address_space; |
| 1814 bp->in_target_beneath = in_target_beneath; |
| 1815 VEC_safe_push (record_breakpoint_p, record_breakpoints, bp); |
| 1739 return 0; | 1816 return 0; |
| 1740 } | 1817 } |
| 1741 | 1818 |
| 1742 /* "to_remove_breakpoint" method for process record target. */ | 1819 /* "to_remove_breakpoint" method for process record target. */ |
| 1743 | 1820 |
| 1744 static int | 1821 static int |
| 1745 record_remove_breakpoint (struct gdbarch *gdbarch, | 1822 record_remove_breakpoint (struct gdbarch *gdbarch, |
| 1746 struct bp_target_info *bp_tgt) | 1823 struct bp_target_info *bp_tgt) |
| 1747 { | 1824 { |
| 1748 if (!RECORD_IS_REPLAY) | 1825 struct record_breakpoint *bp; |
| 1826 int ix; |
| 1827 |
| 1828 for (ix = 0; |
| 1829 VEC_iterate (record_breakpoint_p, record_breakpoints, ix, bp); |
| 1830 ++ix) |
| 1749 { | 1831 { |
| 1750 struct cleanup *old_cleanups = record_gdb_operation_disable_set (); | 1832 if (bp->addr == bp_tgt->placed_address |
| 1751 int ret = record_beneath_to_remove_breakpoint (gdbarch, bp_tgt); | 1833 » && bp->address_space == bp_tgt->placed_address_space) |
| 1834 » { |
| 1835 » if (bp->in_target_beneath) |
| 1836 » { |
| 1837 » struct cleanup *old_cleanups; |
| 1838 » int ret; |
| 1752 | 1839 |
| 1753 do_cleanups (old_cleanups); | 1840 » old_cleanups = record_gdb_operation_disable_set (); |
| 1841 » ret = record_beneath_to_remove_breakpoint (gdbarch, bp_tgt); |
| 1842 » do_cleanups (old_cleanups); |
| 1754 | 1843 |
| 1755 return ret; | 1844 » if (ret != 0) |
| 1845 » » return ret; |
| 1846 » } |
| 1847 |
| 1848 » VEC_unordered_remove (record_breakpoint_p, record_breakpoints, ix); |
| 1849 » return 0; |
| 1850 » } |
| 1756 } | 1851 } |
| 1757 | 1852 |
| 1758 return 0; | 1853 gdb_assert_not_reached ("removing unknown breakpoint"); |
| 1759 } | 1854 } |
| 1760 | 1855 |
| 1761 /* "to_can_execute_reverse" method for process record target. */ | 1856 /* "to_can_execute_reverse" method for process record target. */ |
| 1762 | 1857 |
| 1763 static int | 1858 static int |
| 1764 record_can_execute_reverse (void) | 1859 record_can_execute_reverse (void) |
| 1765 { | 1860 { |
| 1766 return 1; | 1861 return 1; |
| 1767 } | 1862 } |
| 1768 | 1863 |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1879 record_ops.to_can_async_p = record_can_async_p; | 1974 record_ops.to_can_async_p = record_can_async_p; |
| 1880 record_ops.to_is_async_p = record_is_async_p; | 1975 record_ops.to_is_async_p = record_is_async_p; |
| 1881 record_ops.to_execution_direction = record_execution_direction; | 1976 record_ops.to_execution_direction = record_execution_direction; |
| 1882 record_ops.to_magic = OPS_MAGIC; | 1977 record_ops.to_magic = OPS_MAGIC; |
| 1883 } | 1978 } |
| 1884 | 1979 |
| 1885 /* "to_resume" method for prec over corefile. */ | 1980 /* "to_resume" method for prec over corefile. */ |
| 1886 | 1981 |
| 1887 static void | 1982 static void |
| 1888 record_core_resume (struct target_ops *ops, ptid_t ptid, int step, | 1983 record_core_resume (struct target_ops *ops, ptid_t ptid, int step, |
| 1889 enum target_signal signal) | 1984 enum gdb_signal signal) |
| 1890 { | 1985 { |
| 1891 record_resume_step = step; | 1986 record_resume_step = step; |
| 1892 record_resumed = 1; | 1987 record_resumed = 1; |
| 1893 record_execution_dir = execution_direction; | 1988 record_execution_dir = execution_direction; |
| 1894 | 1989 |
| 1895 /* We are about to start executing the inferior (or simulate it), | 1990 /* We are about to start executing the inferior (or simulate it), |
| 1896 let's register it with the event loop. */ | 1991 let's register it with the event loop. */ |
| 1897 if (target_can_async_p ()) | 1992 if (target_can_async_p ()) |
| 1898 { | 1993 { |
| 1899 target_async (inferior_event_handler, 0); | 1994 target_async (inferior_event_handler, 0); |
| (...skipping 955 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2855 { | 2950 { |
| 2856 printf_filtered (_("Go backward to insn number %s\n"), | 2951 printf_filtered (_("Go backward to insn number %s\n"), |
| 2857 pulongest (target_insn)); | 2952 pulongest (target_insn)); |
| 2858 record_goto_insn (p, EXEC_REVERSE); | 2953 record_goto_insn (p, EXEC_REVERSE); |
| 2859 } | 2954 } |
| 2860 registers_changed (); | 2955 registers_changed (); |
| 2861 reinit_frame_cache (); | 2956 reinit_frame_cache (); |
| 2862 print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC); | 2957 print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC); |
| 2863 } | 2958 } |
| 2864 | 2959 |
| 2960 /* Provide a prototype to silence -Wmissing-prototypes. */ |
| 2961 extern initialize_file_ftype _initialize_record; |
| 2962 |
| 2865 void | 2963 void |
| 2866 _initialize_record (void) | 2964 _initialize_record (void) |
| 2867 { | 2965 { |
| 2868 struct cmd_list_element *c; | 2966 struct cmd_list_element *c; |
| 2869 | 2967 |
| 2870 /* Init record_first. */ | 2968 /* Init record_first. */ |
| 2871 record_first.prev = NULL; | 2969 record_first.prev = NULL; |
| 2872 record_first.next = NULL; | 2970 record_first.next = NULL; |
| 2873 record_first.type = record_end; | 2971 record_first.type = record_end; |
| 2874 | 2972 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2958 Set whether query if PREC cannot record memory change of next instruction."), | 3056 Set whether query if PREC cannot record memory change of next instruction."), |
| 2959 _("\ | 3057 _("\ |
| 2960 Show whether query if PREC cannot record memory change of next instruction."), | 3058 Show whether query if PREC cannot record memory change of next instruction."), |
| 2961 _("\ | 3059 _("\ |
| 2962 Default is OFF.\n\ | 3060 Default is OFF.\n\ |
| 2963 When ON, query if PREC cannot record memory change of next instruction."), | 3061 When ON, query if PREC cannot record memory change of next instruction."), |
| 2964 NULL, NULL, | 3062 NULL, NULL, |
| 2965 &set_record_cmdlist, &show_record_cmdlist); | 3063 &set_record_cmdlist, &show_record_cmdlist); |
| 2966 | 3064 |
| 2967 } | 3065 } |
| OLD | NEW |