OLD | NEW |
1 /* GNU/Linux/ARM specific low level interface, for the remote server for GDB. | 1 /* GNU/Linux/ARM specific low level interface, for the remote server for GDB. |
2 Copyright (C) 1995-1996, 1998-2012 Free Software Foundation, Inc. | 2 Copyright (C) 1995-1996, 1998-2012 Free Software Foundation, Inc. |
3 | 3 |
4 This file is part of GDB. | 4 This file is part of GDB. |
5 | 5 |
6 This program is free software; you can redistribute it and/or modify | 6 This program is free software; you can redistribute it and/or modify |
7 it under the terms of the GNU General Public License as published by | 7 it under the terms of the GNU General Public License as published by |
8 the Free Software Foundation; either version 3 of the License, or | 8 the Free Software Foundation; either version 3 of the License, or |
9 (at your option) any later version. | 9 (at your option) any later version. |
10 | 10 |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 /* Are two break-/watch-points equal? */ | 425 /* Are two break-/watch-points equal? */ |
426 static int | 426 static int |
427 arm_linux_hw_breakpoint_equal (const struct arm_linux_hw_breakpoint *p1, | 427 arm_linux_hw_breakpoint_equal (const struct arm_linux_hw_breakpoint *p1, |
428 const struct arm_linux_hw_breakpoint *p2) | 428 const struct arm_linux_hw_breakpoint *p2) |
429 { | 429 { |
430 return p1->address == p2->address && p1->control == p2->control; | 430 return p1->address == p2->address && p1->control == p2->control; |
431 } | 431 } |
432 | 432 |
433 /* Initialize the hardware breakpoint structure P for a breakpoint or | 433 /* Initialize the hardware breakpoint structure P for a breakpoint or |
434 watchpoint at ADDR to LEN. The type of watchpoint is given in TYPE. | 434 watchpoint at ADDR to LEN. The type of watchpoint is given in TYPE. |
435 Returns -1 if TYPE is unsupported, 0 if TYPE represents a breakpoint, | 435 Returns -1 if TYPE is unsupported, or -2 if the particular combination |
436 and 1 if type represents a watchpoint. */ | 436 of ADDR and LEN cannot be implemented. Otherwise, returns 0 if TYPE |
| 437 represents a breakpoint and 1 if type represents a watchpoint. */ |
437 static int | 438 static int |
438 arm_linux_hw_point_initialize (char type, CORE_ADDR addr, int len, | 439 arm_linux_hw_point_initialize (char type, CORE_ADDR addr, int len, |
439 struct arm_linux_hw_breakpoint *p) | 440 struct arm_linux_hw_breakpoint *p) |
440 { | 441 { |
441 arm_hwbp_type hwbp_type; | 442 arm_hwbp_type hwbp_type; |
442 unsigned mask; | 443 unsigned mask; |
443 | 444 |
444 /* Breakpoint/watchpoint types (GDB terminology): | 445 /* Breakpoint/watchpoint types (GDB terminology): |
445 0 = memory breakpoint for instructions | 446 0 = memory breakpoint for instructions |
446 (not supported; done via memory write instead) | 447 (not supported; done via memory write instead) |
(...skipping 20 matching lines...) Expand all Loading... |
467 return -1; | 468 return -1; |
468 } | 469 } |
469 | 470 |
470 if (hwbp_type == arm_hwbp_break) | 471 if (hwbp_type == arm_hwbp_break) |
471 { | 472 { |
472 /* For breakpoints, the length field encodes the mode. */ | 473 /* For breakpoints, the length field encodes the mode. */ |
473 switch (len) | 474 switch (len) |
474 { | 475 { |
475 case 2: /* 16-bit Thumb mode breakpoint */ | 476 case 2: /* 16-bit Thumb mode breakpoint */ |
476 case 3: /* 32-bit Thumb mode breakpoint */ | 477 case 3: /* 32-bit Thumb mode breakpoint */ |
477 » mask = 0x3 << (addr & 2); | 478 » mask = 0x3; |
| 479 » addr &= ~1; |
478 break; | 480 break; |
479 case 4: /* 32-bit ARM mode breakpoint */ | 481 case 4: /* 32-bit ARM mode breakpoint */ |
480 mask = 0xf; | 482 mask = 0xf; |
| 483 addr &= ~3; |
481 break; | 484 break; |
482 default: | 485 default: |
483 /* Unsupported. */ | 486 /* Unsupported. */ |
484 » return -1; | 487 » return -2; |
485 } | 488 } |
486 | |
487 addr &= ~3; | |
488 } | 489 } |
489 else | 490 else |
490 { | 491 { |
491 CORE_ADDR max_wp_length = arm_linux_get_hw_watchpoint_max_length (); | 492 CORE_ADDR max_wp_length = arm_linux_get_hw_watchpoint_max_length (); |
492 CORE_ADDR aligned_addr; | 493 CORE_ADDR aligned_addr; |
493 | 494 |
494 /* Can not set watchpoints for zero or negative lengths. */ | 495 /* Can not set watchpoints for zero or negative lengths. */ |
495 if (len <= 0) | 496 if (len <= 0) |
496 » return -1; | 497 » return -2; |
497 /* The current ptrace interface can only handle watchpoints that are a | 498 /* The current ptrace interface can only handle watchpoints that are a |
498 power of 2. */ | 499 power of 2. */ |
499 if ((len & (len - 1)) != 0) | 500 if ((len & (len - 1)) != 0) |
500 » return -1; | 501 » return -2; |
501 | 502 |
502 /* Test that the range [ADDR, ADDR + LEN) fits into the largest address | 503 /* Test that the range [ADDR, ADDR + LEN) fits into the largest address |
503 range covered by a watchpoint. */ | 504 range covered by a watchpoint. */ |
504 aligned_addr = addr & ~(max_wp_length - 1); | 505 aligned_addr = addr & ~(max_wp_length - 1); |
505 if (aligned_addr + max_wp_length < addr + len) | 506 if (aligned_addr + max_wp_length < addr + len) |
506 » return -1; | 507 » return -2; |
507 | 508 |
508 mask = (1 << len) - 1; | 509 mask = (1 << len) - 1; |
509 } | 510 } |
510 | 511 |
511 p->address = (unsigned int) addr; | 512 p->address = (unsigned int) addr; |
512 p->control = arm_hwbp_control_initialize (mask, hwbp_type, 1); | 513 p->control = arm_hwbp_control_initialize (mask, hwbp_type, 1); |
513 | 514 |
514 return hwbp_type != arm_hwbp_break; | 515 return hwbp_type != arm_hwbp_break; |
515 } | 516 } |
516 | 517 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 arm_insert_point (char type, CORE_ADDR addr, int len) | 554 arm_insert_point (char type, CORE_ADDR addr, int len) |
554 { | 555 { |
555 struct process_info *proc = current_process (); | 556 struct process_info *proc = current_process (); |
556 struct arm_linux_hw_breakpoint p, *pts; | 557 struct arm_linux_hw_breakpoint p, *pts; |
557 int watch, i, count; | 558 int watch, i, count; |
558 | 559 |
559 watch = arm_linux_hw_point_initialize (type, addr, len, &p); | 560 watch = arm_linux_hw_point_initialize (type, addr, len, &p); |
560 if (watch < 0) | 561 if (watch < 0) |
561 { | 562 { |
562 /* Unsupported. */ | 563 /* Unsupported. */ |
563 return 1; | 564 return watch == -1 ? 1 : -1; |
564 } | 565 } |
565 | 566 |
566 if (watch) | 567 if (watch) |
567 { | 568 { |
568 count = arm_linux_get_hw_watchpoint_count (); | 569 count = arm_linux_get_hw_watchpoint_count (); |
569 pts = proc->private->arch_private->wpts; | 570 pts = proc->private->arch_private->wpts; |
570 } | 571 } |
571 else | 572 else |
572 { | 573 { |
573 count = arm_linux_get_hw_breakpoint_count (); | 574 count = arm_linux_get_hw_breakpoint_count (); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 | 625 |
625 /* No watchpoint matched. */ | 626 /* No watchpoint matched. */ |
626 return -1; | 627 return -1; |
627 } | 628 } |
628 | 629 |
629 /* Return whether current thread is stopped due to a watchpoint. */ | 630 /* Return whether current thread is stopped due to a watchpoint. */ |
630 static int | 631 static int |
631 arm_stopped_by_watchpoint (void) | 632 arm_stopped_by_watchpoint (void) |
632 { | 633 { |
633 struct lwp_info *lwp = get_thread_lwp (current_inferior); | 634 struct lwp_info *lwp = get_thread_lwp (current_inferior); |
634 struct siginfo siginfo; | 635 siginfo_t siginfo; |
635 | 636 |
636 /* We must be able to set hardware watchpoints. */ | 637 /* We must be able to set hardware watchpoints. */ |
637 if (arm_linux_get_hw_watchpoint_count () == 0) | 638 if (arm_linux_get_hw_watchpoint_count () == 0) |
638 return 0; | 639 return 0; |
639 | 640 |
640 /* Retrieve siginfo. */ | 641 /* Retrieve siginfo. */ |
641 errno = 0; | 642 errno = 0; |
642 ptrace (PTRACE_GETSIGINFO, lwpid_of (lwp), 0, &siginfo); | 643 ptrace (PTRACE_GETSIGINFO, lwpid_of (lwp), 0, &siginfo); |
643 if (errno != 0) | 644 if (errno != 0) |
644 return 0; | 645 return 0; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
702 struct arch_process_info *proc_info = proc->private->arch_private; | 703 struct arch_process_info *proc_info = proc->private->arch_private; |
703 struct arch_lwp_info *lwp_info = lwp->arch_private; | 704 struct arch_lwp_info *lwp_info = lwp->arch_private; |
704 int i; | 705 int i; |
705 | 706 |
706 for (i = 0; i < arm_linux_get_hw_breakpoint_count (); i++) | 707 for (i = 0; i < arm_linux_get_hw_breakpoint_count (); i++) |
707 if (lwp_info->bpts_changed[i]) | 708 if (lwp_info->bpts_changed[i]) |
708 { | 709 { |
709 errno = 0; | 710 errno = 0; |
710 | 711 |
711 if (arm_hwbp_control_is_enabled (proc_info->bpts[i].control)) | 712 if (arm_hwbp_control_is_enabled (proc_info->bpts[i].control)) |
712 » if (ptrace (PTRACE_SETHBPREGS, pid, ((i << 1) + 1), | 713 » if (ptrace (PTRACE_SETHBPREGS, pid, |
713 » &proc_info->bpts[i].address) < 0) | 714 » » (PTRACE_ARG3_TYPE) ((i << 1) + 1), |
| 715 » » &proc_info->bpts[i].address) < 0) |
714 perror_with_name ("Unexpected error setting breakpoint address"); | 716 perror_with_name ("Unexpected error setting breakpoint address"); |
715 | 717 |
716 if (arm_hwbp_control_is_initialized (proc_info->bpts[i].control)) | 718 if (arm_hwbp_control_is_initialized (proc_info->bpts[i].control)) |
717 » if (ptrace (PTRACE_SETHBPREGS, pid, ((i << 1) + 2), | 719 » if (ptrace (PTRACE_SETHBPREGS, pid, |
718 » &proc_info->bpts[i].control) < 0) | 720 » » (PTRACE_ARG3_TYPE) ((i << 1) + 2), |
| 721 » » &proc_info->bpts[i].control) < 0) |
719 perror_with_name ("Unexpected error setting breakpoint"); | 722 perror_with_name ("Unexpected error setting breakpoint"); |
720 | 723 |
721 lwp_info->bpts_changed[i] = 0; | 724 lwp_info->bpts_changed[i] = 0; |
722 } | 725 } |
723 | 726 |
724 for (i = 0; i < arm_linux_get_hw_watchpoint_count (); i++) | 727 for (i = 0; i < arm_linux_get_hw_watchpoint_count (); i++) |
725 if (lwp_info->wpts_changed[i]) | 728 if (lwp_info->wpts_changed[i]) |
726 { | 729 { |
727 errno = 0; | 730 errno = 0; |
728 | 731 |
729 if (arm_hwbp_control_is_enabled (proc_info->wpts[i].control)) | 732 if (arm_hwbp_control_is_enabled (proc_info->wpts[i].control)) |
730 » if (ptrace (PTRACE_SETHBPREGS, pid, -((i << 1) + 1), | 733 » if (ptrace (PTRACE_SETHBPREGS, pid, |
731 » &proc_info->wpts[i].address) < 0) | 734 » » (PTRACE_ARG3_TYPE) -((i << 1) + 1), |
| 735 » » &proc_info->wpts[i].address) < 0) |
732 perror_with_name ("Unexpected error setting watchpoint address"); | 736 perror_with_name ("Unexpected error setting watchpoint address"); |
733 | 737 |
734 if (arm_hwbp_control_is_initialized (proc_info->wpts[i].control)) | 738 if (arm_hwbp_control_is_initialized (proc_info->wpts[i].control)) |
735 » if (ptrace (PTRACE_SETHBPREGS, pid, -((i << 1) + 2), | 739 » if (ptrace (PTRACE_SETHBPREGS, pid, |
736 » &proc_info->wpts[i].control) < 0) | 740 » » (PTRACE_ARG3_TYPE) -((i << 1) + 2), |
| 741 » » &proc_info->wpts[i].control) < 0) |
737 perror_with_name ("Unexpected error setting watchpoint"); | 742 perror_with_name ("Unexpected error setting watchpoint"); |
738 | 743 |
739 lwp_info->wpts_changed[i] = 0; | 744 lwp_info->wpts_changed[i] = 0; |
740 } | 745 } |
741 } | 746 } |
742 | 747 |
743 | 748 |
744 static int | 749 static int |
745 arm_get_hwcap (unsigned long *valp) | 750 arm_get_hwcap (unsigned long *valp) |
746 { | 751 { |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
827 { PTRACE_GETVFPREGS, PTRACE_SETVFPREGS, 0, 32 * 8 + 4, | 832 { PTRACE_GETVFPREGS, PTRACE_SETVFPREGS, 0, 32 * 8 + 4, |
828 EXTENDED_REGS, | 833 EXTENDED_REGS, |
829 arm_fill_vfpregset, arm_store_vfpregset }, | 834 arm_fill_vfpregset, arm_store_vfpregset }, |
830 { 0, 0, 0, -1, -1, NULL, NULL } | 835 { 0, 0, 0, -1, -1, NULL, NULL } |
831 }; | 836 }; |
832 | 837 |
833 struct linux_target_ops the_low_target = { | 838 struct linux_target_ops the_low_target = { |
834 arm_arch_setup, | 839 arm_arch_setup, |
835 arm_num_regs, | 840 arm_num_regs, |
836 arm_regmap, | 841 arm_regmap, |
| 842 NULL, |
837 arm_cannot_fetch_register, | 843 arm_cannot_fetch_register, |
838 arm_cannot_store_register, | 844 arm_cannot_store_register, |
| 845 NULL, /* fetch_register */ |
839 arm_get_pc, | 846 arm_get_pc, |
840 arm_set_pc, | 847 arm_set_pc, |
841 | 848 |
842 /* Define an ARM-mode breakpoint; we only set breakpoints in the C | 849 /* Define an ARM-mode breakpoint; we only set breakpoints in the C |
843 library, which is most likely to be ARM. If the kernel supports | 850 library, which is most likely to be ARM. If the kernel supports |
844 clone events, we will never insert a breakpoint, so even a Thumb | 851 clone events, we will never insert a breakpoint, so even a Thumb |
845 C library will work; so will mixing EABI/non-EABI gdbserver and | 852 C library will work; so will mixing EABI/non-EABI gdbserver and |
846 application. */ | 853 application. */ |
847 #ifndef __ARM_EABI__ | 854 #ifndef __ARM_EABI__ |
848 (const unsigned char *) &arm_breakpoint, | 855 (const unsigned char *) &arm_breakpoint, |
849 #else | 856 #else |
850 (const unsigned char *) &arm_eabi_breakpoint, | 857 (const unsigned char *) &arm_eabi_breakpoint, |
851 #endif | 858 #endif |
852 arm_breakpoint_len, | 859 arm_breakpoint_len, |
853 arm_reinsert_addr, | 860 arm_reinsert_addr, |
854 0, | 861 0, |
855 arm_breakpoint_at, | 862 arm_breakpoint_at, |
856 arm_insert_point, | 863 arm_insert_point, |
857 arm_remove_point, | 864 arm_remove_point, |
858 arm_stopped_by_watchpoint, | 865 arm_stopped_by_watchpoint, |
859 arm_stopped_data_address, | 866 arm_stopped_data_address, |
860 NULL, /* collect_ptrace_register */ | 867 NULL, /* collect_ptrace_register */ |
861 NULL, /* supply_ptrace_register */ | 868 NULL, /* supply_ptrace_register */ |
862 NULL, /* siginfo_fixup */ | 869 NULL, /* siginfo_fixup */ |
863 arm_new_process, | 870 arm_new_process, |
864 arm_new_thread, | 871 arm_new_thread, |
865 arm_prepare_to_resume, | 872 arm_prepare_to_resume, |
866 }; | 873 }; |
OLD | NEW |