OLD | NEW |
1 /* GNU/Linux on ARM native support. | 1 /* GNU/Linux on ARM native support. |
2 Copyright (C) 1999-2002, 2004-2012 Free Software Foundation, Inc. | 2 Copyright (C) 1999-2002, 2004-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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 static int arm_linux_vfp_register_count; | 70 static int arm_linux_vfp_register_count; |
71 | 71 |
72 extern int arm_apcs_32; | 72 extern int arm_apcs_32; |
73 | 73 |
74 /* On GNU/Linux, threads are implemented as pseudo-processes, in which | 74 /* On GNU/Linux, threads are implemented as pseudo-processes, in which |
75 case we may be tracing more than one process at a time. In that | 75 case we may be tracing more than one process at a time. In that |
76 case, inferior_ptid will contain the main process ID and the | 76 case, inferior_ptid will contain the main process ID and the |
77 individual thread (process) ID. get_thread_id () is used to get | 77 individual thread (process) ID. get_thread_id () is used to get |
78 the thread id if it's available, and the process id otherwise. */ | 78 the thread id if it's available, and the process id otherwise. */ |
79 | 79 |
80 int | 80 static int |
81 get_thread_id (ptid_t ptid) | 81 get_thread_id (ptid_t ptid) |
82 { | 82 { |
83 int tid = TIDGET (ptid); | 83 int tid = TIDGET (ptid); |
84 if (0 == tid) | 84 if (0 == tid) |
85 tid = PIDGET (ptid); | 85 tid = PIDGET (ptid); |
86 return tid; | 86 return tid; |
87 } | 87 } |
88 | 88 |
89 #define GET_THREAD_ID(PTID) get_thread_id (PTID) | 89 #define GET_THREAD_ID(PTID) get_thread_id (PTID) |
90 | 90 |
(...skipping 798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
889 arm_linux_hw_breakpoint_initialize (struct gdbarch *gdbarch, | 889 arm_linux_hw_breakpoint_initialize (struct gdbarch *gdbarch, |
890 struct bp_target_info *bp_tgt, | 890 struct bp_target_info *bp_tgt, |
891 struct arm_linux_hw_breakpoint *p) | 891 struct arm_linux_hw_breakpoint *p) |
892 { | 892 { |
893 unsigned mask; | 893 unsigned mask; |
894 CORE_ADDR address = bp_tgt->placed_address; | 894 CORE_ADDR address = bp_tgt->placed_address; |
895 | 895 |
896 /* We have to create a mask for the control register which says which bits | 896 /* We have to create a mask for the control register which says which bits |
897 of the word pointed to by address to break on. */ | 897 of the word pointed to by address to break on. */ |
898 if (arm_pc_is_thumb (gdbarch, address)) | 898 if (arm_pc_is_thumb (gdbarch, address)) |
899 mask = 0x3 << (address & 2); | 899 { |
| 900 mask = 0x3; |
| 901 address &= ~1; |
| 902 } |
900 else | 903 else |
901 mask = 0xf; | 904 { |
| 905 mask = 0xf; |
| 906 address &= ~3; |
| 907 } |
902 | 908 |
903 p->address = (unsigned int) (address & ~3); | 909 p->address = (unsigned int) address; |
904 p->control = arm_hwbp_control_initialize (mask, arm_hwbp_break, 1); | 910 p->control = arm_hwbp_control_initialize (mask, arm_hwbp_break, 1); |
905 } | 911 } |
906 | 912 |
907 /* Get the ARM hardware breakpoint type from the RW value we're given when | 913 /* Get the ARM hardware breakpoint type from the RW value we're given when |
908 asked to set a watchpoint. */ | 914 asked to set a watchpoint. */ |
909 static arm_hwbp_type | 915 static arm_hwbp_type |
910 arm_linux_get_hwbp_type (int rw) | 916 arm_linux_get_hwbp_type (int rw) |
911 { | 917 { |
912 if (rw == hw_read) | 918 if (rw == hw_read) |
913 return arm_hwbp_load; | 919 return arm_hwbp_load; |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1130 ALL_LWPS (lp) | 1136 ALL_LWPS (lp) |
1131 arm_linux_remove_hw_breakpoint1 (&p, TIDGET (lp->ptid), 1); | 1137 arm_linux_remove_hw_breakpoint1 (&p, TIDGET (lp->ptid), 1); |
1132 | 1138 |
1133 return 0; | 1139 return 0; |
1134 } | 1140 } |
1135 | 1141 |
1136 /* What was the data address the target was stopped on accessing. */ | 1142 /* What was the data address the target was stopped on accessing. */ |
1137 static int | 1143 static int |
1138 arm_linux_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p) | 1144 arm_linux_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p) |
1139 { | 1145 { |
1140 struct siginfo *siginfo_p = linux_nat_get_siginfo (inferior_ptid); | 1146 siginfo_t siginfo; |
1141 int slot = siginfo_p->si_errno; | 1147 int slot; |
| 1148 |
| 1149 if (!linux_nat_get_siginfo (inferior_ptid, &siginfo)) |
| 1150 return 0; |
1142 | 1151 |
1143 /* This must be a hardware breakpoint. */ | 1152 /* This must be a hardware breakpoint. */ |
1144 if (siginfo_p->si_signo != SIGTRAP | 1153 if (siginfo.si_signo != SIGTRAP |
1145 || (siginfo_p->si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */) | 1154 || (siginfo.si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */) |
1146 return 0; | 1155 return 0; |
1147 | 1156 |
1148 /* We must be able to set hardware watchpoints. */ | 1157 /* We must be able to set hardware watchpoints. */ |
1149 if (arm_linux_get_hw_watchpoint_count () == 0) | 1158 if (arm_linux_get_hw_watchpoint_count () == 0) |
1150 return 0; | 1159 return 0; |
1151 | 1160 |
| 1161 slot = siginfo.si_errno; |
| 1162 |
1152 /* If we are in a positive slot then we're looking at a breakpoint and not | 1163 /* If we are in a positive slot then we're looking at a breakpoint and not |
1153 a watchpoint. */ | 1164 a watchpoint. */ |
1154 if (slot >= 0) | 1165 if (slot >= 0) |
1155 return 0; | 1166 return 0; |
1156 | 1167 |
1157 *addr_p = (CORE_ADDR) (uintptr_t) siginfo_p->si_addr; | 1168 *addr_p = (CORE_ADDR) (uintptr_t) siginfo.si_addr; |
1158 return 1; | 1169 return 1; |
1159 } | 1170 } |
1160 | 1171 |
1161 /* Has the target been stopped by hitting a watchpoint? */ | 1172 /* Has the target been stopped by hitting a watchpoint? */ |
1162 static int | 1173 static int |
1163 arm_linux_stopped_by_watchpoint (void) | 1174 arm_linux_stopped_by_watchpoint (void) |
1164 { | 1175 { |
1165 CORE_ADDR addr; | 1176 CORE_ADDR addr; |
1166 return arm_linux_stopped_data_address (¤t_target, &addr); | 1177 return arm_linux_stopped_data_address (¤t_target, &addr); |
1167 } | 1178 } |
1168 | 1179 |
1169 static int | 1180 static int |
1170 arm_linux_watchpoint_addr_within_range (struct target_ops *target, | 1181 arm_linux_watchpoint_addr_within_range (struct target_ops *target, |
1171 CORE_ADDR addr, | 1182 CORE_ADDR addr, |
1172 CORE_ADDR start, int length) | 1183 CORE_ADDR start, int length) |
1173 { | 1184 { |
1174 return start <= addr && start + length - 1 >= addr; | 1185 return start <= addr && start + length - 1 >= addr; |
1175 } | 1186 } |
1176 | 1187 |
1177 /* Handle thread creation. We need to copy the breakpoints and watchpoints | 1188 /* Handle thread creation. We need to copy the breakpoints and watchpoints |
1178 in the parent thread to the child thread. */ | 1189 in the parent thread to the child thread. */ |
1179 static void | 1190 static void |
1180 arm_linux_new_thread (ptid_t ptid) | 1191 arm_linux_new_thread (struct lwp_info *lp) |
1181 { | 1192 { |
1182 int tid = TIDGET (ptid); | 1193 int tid = TIDGET (lp->ptid); |
1183 const struct arm_linux_hwbp_cap *info = arm_linux_get_hwbp_cap (); | 1194 const struct arm_linux_hwbp_cap *info = arm_linux_get_hwbp_cap (); |
1184 | 1195 |
1185 if (info != NULL) | 1196 if (info != NULL) |
1186 { | 1197 { |
1187 int i; | 1198 int i; |
1188 struct arm_linux_thread_points *p; | 1199 struct arm_linux_thread_points *p; |
1189 struct arm_linux_hw_breakpoint *bpts; | 1200 struct arm_linux_hw_breakpoint *bpts; |
1190 | 1201 |
1191 if (VEC_empty (arm_linux_thread_points_p, arm_threads)) | 1202 if (VEC_empty (arm_linux_thread_points_p, arm_threads)) |
1192 return; | 1203 return; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1265 | 1276 |
1266 t->to_read_description = arm_linux_read_description; | 1277 t->to_read_description = arm_linux_read_description; |
1267 | 1278 |
1268 /* Register the target. */ | 1279 /* Register the target. */ |
1269 linux_nat_add_target (t); | 1280 linux_nat_add_target (t); |
1270 | 1281 |
1271 /* Handle thread creation and exit */ | 1282 /* Handle thread creation and exit */ |
1272 observer_attach_thread_exit (arm_linux_thread_exit); | 1283 observer_attach_thread_exit (arm_linux_thread_exit); |
1273 linux_nat_set_new_thread (t, arm_linux_new_thread); | 1284 linux_nat_set_new_thread (t, arm_linux_new_thread); |
1274 } | 1285 } |
OLD | NEW |