| 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 |