OLD | NEW |
1 /* GNU/Linux/MIPS specific low level interface, for the remote server for GDB. | 1 /* GNU/Linux/MIPS specific low level interface, for the remote server for GDB. |
2 Copyright (C) 1995-1996, 1998-2002, 2005-2012 Free Software | 2 Copyright (C) 1995-2013 Free Software Foundation, Inc. |
3 Foundation, Inc. | |
4 | 3 |
5 This file is part of GDB. | 4 This file is part of GDB. |
6 | 5 |
7 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 |
8 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 |
9 the Free Software Foundation; either version 3 of the License, or | 8 the Free Software Foundation; either version 3 of the License, or |
10 (at your option) any later version. | 9 (at your option) any later version. |
11 | 10 |
12 This program is distributed in the hope that it will be useful, | 11 This program is distributed in the hope that it will be useful, |
13 but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 GNU General Public License for more details. | 14 GNU General Public License for more details. |
16 | 15 |
17 You should have received a copy of the GNU General Public License | 16 You should have received a copy of the GNU General Public License |
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ | 17 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
19 | 18 |
20 #include "server.h" | 19 #include "server.h" |
21 #include "linux-low.h" | 20 #include "linux-low.h" |
22 | 21 |
23 #include <sys/ptrace.h> | 22 #include <sys/ptrace.h> |
24 #include <endian.h> | 23 #include <endian.h> |
25 | 24 |
| 25 #include "mips-linux-watch.h" |
26 #include "gdb_proc_service.h" | 26 #include "gdb_proc_service.h" |
27 | 27 |
28 /* Defined in auto-generated file mips-linux.c. */ | 28 /* Defined in auto-generated file mips-linux.c. */ |
29 void init_registers_mips_linux (void); | 29 void init_registers_mips_linux (void); |
| 30 extern const struct target_desc *tdesc_mips_linux; |
| 31 |
30 /* Defined in auto-generated file mips-dsp-linux.c. */ | 32 /* Defined in auto-generated file mips-dsp-linux.c. */ |
31 void init_registers_mips_dsp_linux (void); | 33 void init_registers_mips_dsp_linux (void); |
| 34 extern const struct target_desc *tdesc_mips_dsp_linux; |
| 35 |
32 /* Defined in auto-generated file mips64-linux.c. */ | 36 /* Defined in auto-generated file mips64-linux.c. */ |
33 void init_registers_mips64_linux (void); | 37 void init_registers_mips64_linux (void); |
| 38 extern const struct target_desc *tdesc_mips64_linux; |
| 39 |
34 /* Defined in auto-generated file mips64-dsp-linux.c. */ | 40 /* Defined in auto-generated file mips64-dsp-linux.c. */ |
35 void init_registers_mips64_dsp_linux (void); | 41 void init_registers_mips64_dsp_linux (void); |
| 42 extern const struct target_desc *tdesc_mips64_dsp_linux; |
36 | 43 |
37 #ifdef __mips64 | 44 #ifdef __mips64 |
38 #define init_registers_mips_linux init_registers_mips64_linux | 45 #define tdesc_mips_linux tdesc_mips64_linux |
39 #define init_registers_mips_dsp_linux init_registers_mips64_dsp_linux | 46 #define tdesc_mips_dsp_linux tdesc_mips64_dsp_linux |
40 #endif | 47 #endif |
41 | 48 |
42 #ifndef PTRACE_GET_THREAD_AREA | 49 #ifndef PTRACE_GET_THREAD_AREA |
43 #define PTRACE_GET_THREAD_AREA 25 | 50 #define PTRACE_GET_THREAD_AREA 25 |
44 #endif | 51 #endif |
45 | 52 |
46 #ifdef HAVE_SYS_REG_H | 53 #ifdef HAVE_SYS_REG_H |
47 #include <sys/reg.h> | 54 #include <sys/reg.h> |
48 #endif | 55 #endif |
49 | 56 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 0 | 109 0 |
103 }; | 110 }; |
104 | 111 |
105 /* DSP registers are not in any regset and can only be accessed | 112 /* DSP registers are not in any regset and can only be accessed |
106 individually. */ | 113 individually. */ |
107 | 114 |
108 static unsigned char mips_dsp_regset_bitmap[(mips_dsp_num_regs + 7) / 8] = { | 115 static unsigned char mips_dsp_regset_bitmap[(mips_dsp_num_regs + 7) / 8] = { |
109 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x80 | 116 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x80 |
110 }; | 117 }; |
111 | 118 |
| 119 static int have_dsp = -1; |
| 120 |
112 /* Try peeking at an arbitrarily chosen DSP register and pick the available | 121 /* Try peeking at an arbitrarily chosen DSP register and pick the available |
113 user register set accordingly. */ | 122 user register set accordingly. */ |
114 | 123 |
115 static void | 124 static const struct target_desc * |
116 mips_arch_setup (void) | 125 mips_read_description (void) |
117 { | 126 { |
118 static void (*init_registers) (void); | 127 if (have_dsp < 0) |
119 | |
120 gdb_assert (current_inferior); | |
121 | |
122 if (init_registers == NULL) | |
123 { | 128 { |
124 int pid = lwpid_of (get_thread_lwp (current_inferior)); | 129 int pid = lwpid_of (get_thread_lwp (current_inferior)); |
125 | 130 |
126 ptrace (PTRACE_PEEKUSER, pid, DSP_CONTROL, 0); | 131 ptrace (PTRACE_PEEKUSER, pid, DSP_CONTROL, 0); |
127 switch (errno) | 132 switch (errno) |
128 { | 133 { |
129 case 0: | 134 case 0: |
130 » the_low_target.num_regs = mips_dsp_num_regs; | 135 » have_dsp = 1; |
131 » the_low_target.regmap = mips_dsp_regmap; | |
132 » the_low_target.regset_bitmap = mips_dsp_regset_bitmap; | |
133 » init_registers = init_registers_mips_dsp_linux; | |
134 break; | 136 break; |
135 case EIO: | 137 case EIO: |
136 » the_low_target.num_regs = mips_num_regs; | 138 » have_dsp = 0; |
137 » the_low_target.regmap = mips_regmap; | |
138 » the_low_target.regset_bitmap = NULL; | |
139 » init_registers = init_registers_mips_linux; | |
140 break; | 139 break; |
141 default: | 140 default: |
142 perror_with_name ("ptrace"); | 141 perror_with_name ("ptrace"); |
143 break; | 142 break; |
144 } | 143 } |
145 } | 144 } |
146 init_registers (); | 145 |
| 146 return have_dsp ? tdesc_mips_dsp_linux : tdesc_mips_linux; |
147 } | 147 } |
148 | 148 |
| 149 static void |
| 150 mips_arch_setup (void) |
| 151 { |
| 152 current_process ()->tdesc = mips_read_description (); |
| 153 } |
| 154 |
| 155 static struct usrregs_info * |
| 156 get_usrregs_info (void) |
| 157 { |
| 158 const struct regs_info *regs_info = the_low_target.regs_info (); |
| 159 |
| 160 return regs_info->usrregs; |
| 161 } |
| 162 |
| 163 /* Per-process arch-specific data we want to keep. */ |
| 164 |
| 165 struct arch_process_info |
| 166 { |
| 167 /* -1 if the kernel and/or CPU do not support watch registers. |
| 168 1 if watch_readback is valid and we can read style, num_valid |
| 169 and the masks. |
| 170 0 if we need to read the watch_readback. */ |
| 171 |
| 172 int watch_readback_valid; |
| 173 |
| 174 /* Cached watch register read values. */ |
| 175 |
| 176 struct pt_watch_regs watch_readback; |
| 177 |
| 178 /* Current watchpoint requests for this process. */ |
| 179 |
| 180 struct mips_watchpoint *current_watches; |
| 181 |
| 182 /* The current set of watch register values for writing the |
| 183 registers. */ |
| 184 |
| 185 struct pt_watch_regs watch_mirror; |
| 186 }; |
| 187 |
| 188 /* Per-thread arch-specific data we want to keep. */ |
| 189 |
| 190 struct arch_lwp_info |
| 191 { |
| 192 /* Non-zero if our copy differs from what's recorded in the thread. */ |
| 193 int watch_registers_changed; |
| 194 }; |
| 195 |
149 /* From mips-linux-nat.c. */ | 196 /* From mips-linux-nat.c. */ |
150 | 197 |
151 /* Pseudo registers can not be read. ptrace does not provide a way to | 198 /* Pseudo registers can not be read. ptrace does not provide a way to |
152 read (or set) PS_REGNUM, and there's no point in reading or setting | 199 read (or set) PS_REGNUM, and there's no point in reading or setting |
153 ZERO_REGNUM. We also can not set BADVADDR, CAUSE, or FCRIR via | 200 ZERO_REGNUM. We also can not set BADVADDR, CAUSE, or FCRIR via |
154 ptrace(). */ | 201 ptrace(). */ |
155 | 202 |
156 static int | 203 static int |
157 mips_cannot_fetch_register (int regno) | 204 mips_cannot_fetch_register (int regno) |
158 { | 205 { |
159 if (the_low_target.regmap[regno] == -1) | 206 const struct target_desc *tdesc; |
| 207 |
| 208 if (get_usrregs_info ()->regmap[regno] == -1) |
160 return 1; | 209 return 1; |
161 | 210 |
162 if (find_regno ("r0") == regno) | 211 tdesc = current_process ()->tdesc; |
| 212 |
| 213 if (find_regno (tdesc, "r0") == regno) |
163 return 1; | 214 return 1; |
164 | 215 |
165 return 0; | 216 return 0; |
166 } | 217 } |
167 | 218 |
168 static int | 219 static int |
169 mips_cannot_store_register (int regno) | 220 mips_cannot_store_register (int regno) |
170 { | 221 { |
171 if (the_low_target.regmap[regno] == -1) | 222 const struct target_desc *tdesc; |
| 223 |
| 224 if (get_usrregs_info ()->regmap[regno] == -1) |
172 return 1; | 225 return 1; |
173 | 226 |
174 if (find_regno ("r0") == regno) | 227 tdesc = current_process ()->tdesc; |
| 228 |
| 229 if (find_regno (tdesc, "r0") == regno) |
175 return 1; | 230 return 1; |
176 | 231 |
177 if (find_regno ("cause") == regno) | 232 if (find_regno (tdesc, "cause") == regno) |
178 return 1; | 233 return 1; |
179 | 234 |
180 if (find_regno ("badvaddr") == regno) | 235 if (find_regno (tdesc, "badvaddr") == regno) |
181 return 1; | 236 return 1; |
182 | 237 |
183 if (find_regno ("fir") == regno) | 238 if (find_regno (tdesc, "fir") == regno) |
184 return 1; | 239 return 1; |
185 | 240 |
186 return 0; | 241 return 0; |
187 } | 242 } |
188 | 243 |
189 static CORE_ADDR | 244 static CORE_ADDR |
190 mips_get_pc (struct regcache *regcache) | 245 mips_get_pc (struct regcache *regcache) |
191 { | 246 { |
192 union mips_register pc; | 247 union mips_register pc; |
193 collect_register_by_name (regcache, "pc", pc.buf); | 248 collect_register_by_name (regcache, "pc", pc.buf); |
194 return register_size (0) == 4 ? pc.reg32 : pc.reg64; | 249 return register_size (regcache->tdesc, 0) == 4 ? pc.reg32 : pc.reg64; |
195 } | 250 } |
196 | 251 |
197 static void | 252 static void |
198 mips_set_pc (struct regcache *regcache, CORE_ADDR pc) | 253 mips_set_pc (struct regcache *regcache, CORE_ADDR pc) |
199 { | 254 { |
200 union mips_register newpc; | 255 union mips_register newpc; |
201 if (register_size (0) == 4) | 256 if (register_size (regcache->tdesc, 0) == 4) |
202 newpc.reg32 = pc; | 257 newpc.reg32 = pc; |
203 else | 258 else |
204 newpc.reg64 = pc; | 259 newpc.reg64 = pc; |
205 | 260 |
206 supply_register_by_name (regcache, "pc", newpc.buf); | 261 supply_register_by_name (regcache, "pc", newpc.buf); |
207 } | 262 } |
208 | 263 |
209 /* Correct in either endianness. */ | 264 /* Correct in either endianness. */ |
210 static const unsigned int mips_breakpoint = 0x0005000d; | 265 static const unsigned int mips_breakpoint = 0x0005000d; |
211 #define mips_breakpoint_len 4 | 266 #define mips_breakpoint_len 4 |
212 | 267 |
213 /* We only place breakpoints in empty marker functions, and thread locking | 268 /* We only place breakpoints in empty marker functions, and thread locking |
214 is outside of the function. So rather than importing software single-step, | 269 is outside of the function. So rather than importing software single-step, |
215 we can just run until exit. */ | 270 we can just run until exit. */ |
216 static CORE_ADDR | 271 static CORE_ADDR |
217 mips_reinsert_addr (void) | 272 mips_reinsert_addr (void) |
218 { | 273 { |
219 struct regcache *regcache = get_thread_regcache (current_inferior, 1); | 274 struct regcache *regcache = get_thread_regcache (current_inferior, 1); |
220 union mips_register ra; | 275 union mips_register ra; |
221 collect_register_by_name (regcache, "r31", ra.buf); | 276 collect_register_by_name (regcache, "r31", ra.buf); |
222 return register_size (0) == 4 ? ra.reg32 : ra.reg64; | 277 return register_size (regcache->tdesc, 0) == 4 ? ra.reg32 : ra.reg64; |
223 } | 278 } |
224 | 279 |
225 static int | 280 static int |
226 mips_breakpoint_at (CORE_ADDR where) | 281 mips_breakpoint_at (CORE_ADDR where) |
227 { | 282 { |
228 unsigned int insn; | 283 unsigned int insn; |
229 | 284 |
230 (*the_target->read_memory) (where, (unsigned char *) &insn, 4); | 285 (*the_target->read_memory) (where, (unsigned char *) &insn, 4); |
231 if (insn == mips_breakpoint) | 286 if (insn == mips_breakpoint) |
232 return 1; | 287 return 1; |
233 | 288 |
234 /* If necessary, recognize more trap instructions here. GDB only uses the | 289 /* If necessary, recognize more trap instructions here. GDB only uses the |
235 one. */ | 290 one. */ |
236 return 0; | 291 return 0; |
237 } | 292 } |
238 | 293 |
| 294 /* Mark the watch registers of lwp, represented by ENTRY, as changed, |
| 295 if the lwp's process id is *PID_P. */ |
| 296 |
| 297 static int |
| 298 update_watch_registers_callback (struct inferior_list_entry *entry, |
| 299 void *pid_p) |
| 300 { |
| 301 struct lwp_info *lwp = (struct lwp_info *) entry; |
| 302 int pid = *(int *) pid_p; |
| 303 |
| 304 /* Only update the threads of this process. */ |
| 305 if (pid_of (lwp) == pid) |
| 306 { |
| 307 /* The actual update is done later just before resuming the lwp, |
| 308 we just mark that the registers need updating. */ |
| 309 lwp->arch_private->watch_registers_changed = 1; |
| 310 |
| 311 /* If the lwp isn't stopped, force it to momentarily pause, so |
| 312 we can update its watch registers. */ |
| 313 if (!lwp->stopped) |
| 314 linux_stop_lwp (lwp); |
| 315 } |
| 316 |
| 317 return 0; |
| 318 } |
| 319 |
| 320 /* This is the implementation of linux_target_ops method |
| 321 new_process. */ |
| 322 |
| 323 static struct arch_process_info * |
| 324 mips_linux_new_process (void) |
| 325 { |
| 326 struct arch_process_info *info = xcalloc (1, sizeof (*info)); |
| 327 |
| 328 return info; |
| 329 } |
| 330 |
| 331 /* This is the implementation of linux_target_ops method new_thread. |
| 332 Mark the watch registers as changed, so the threads' copies will |
| 333 be updated. */ |
| 334 |
| 335 static struct arch_lwp_info * |
| 336 mips_linux_new_thread (void) |
| 337 { |
| 338 struct arch_lwp_info *info = xcalloc (1, sizeof (*info)); |
| 339 |
| 340 info->watch_registers_changed = 1; |
| 341 |
| 342 return info; |
| 343 } |
| 344 |
| 345 /* This is the implementation of linux_target_ops method |
| 346 prepare_to_resume. If the watch regs have changed, update the |
| 347 thread's copies. */ |
| 348 |
| 349 static void |
| 350 mips_linux_prepare_to_resume (struct lwp_info *lwp) |
| 351 { |
| 352 ptid_t ptid = ptid_of (lwp); |
| 353 struct process_info *proc = find_process_pid (ptid_get_pid (ptid)); |
| 354 struct arch_process_info *private = proc->private->arch_private; |
| 355 |
| 356 if (lwp->arch_private->watch_registers_changed) |
| 357 { |
| 358 /* Only update the watch registers if we have set or unset a |
| 359 watchpoint already. */ |
| 360 if (mips_linux_watch_get_num_valid (&private->watch_mirror) > 0) |
| 361 { |
| 362 /* Write the mirrored watch register values. */ |
| 363 int tid = ptid_get_lwp (ptid); |
| 364 |
| 365 if (-1 == ptrace (PTRACE_SET_WATCH_REGS, tid, |
| 366 &private->watch_mirror)) |
| 367 perror_with_name ("Couldn't write watch register"); |
| 368 } |
| 369 |
| 370 lwp->arch_private->watch_registers_changed = 0; |
| 371 } |
| 372 } |
| 373 |
| 374 /* Translate breakpoint type TYPE in rsp to 'enum target_hw_bp_type'. */ |
| 375 |
| 376 static enum target_hw_bp_type |
| 377 rsp_bp_type_to_target_hw_bp_type (char type) |
| 378 { |
| 379 switch (type) |
| 380 { |
| 381 case '2': |
| 382 return hw_write; |
| 383 case '3': |
| 384 return hw_read; |
| 385 case '4': |
| 386 return hw_access; |
| 387 } |
| 388 |
| 389 gdb_assert_not_reached ("unhandled RSP breakpoint type"); |
| 390 } |
| 391 |
| 392 /* This is the implementation of linux_target_ops method |
| 393 insert_point. */ |
| 394 |
| 395 static int |
| 396 mips_insert_point (char type, CORE_ADDR addr, int len) |
| 397 { |
| 398 struct process_info *proc = current_process (); |
| 399 struct arch_process_info *private = proc->private->arch_private; |
| 400 struct pt_watch_regs regs; |
| 401 struct mips_watchpoint *new_watch; |
| 402 struct mips_watchpoint **pw; |
| 403 int pid; |
| 404 long lwpid; |
| 405 enum target_hw_bp_type watch_type; |
| 406 uint32_t irw; |
| 407 |
| 408 /* Breakpoint/watchpoint types: |
| 409 '0' - software-breakpoint (not supported) |
| 410 '1' - hardware-breakpoint (not supported) |
| 411 '2' - write watchpoint (supported) |
| 412 '3' - read watchpoint (supported) |
| 413 '4' - access watchpoint (supported). */ |
| 414 |
| 415 if (type < '2' || type > '4') |
| 416 { |
| 417 /* Unsupported. */ |
| 418 return 1; |
| 419 } |
| 420 |
| 421 lwpid = lwpid_of (get_thread_lwp (current_inferior)); |
| 422 if (!mips_linux_read_watch_registers (lwpid, |
| 423 &private->watch_readback, |
| 424 &private->watch_readback_valid, |
| 425 0)) |
| 426 return -1; |
| 427 |
| 428 if (len <= 0) |
| 429 return -1; |
| 430 |
| 431 regs = private->watch_readback; |
| 432 /* Add the current watches. */ |
| 433 mips_linux_watch_populate_regs (private->current_watches, ®s); |
| 434 |
| 435 /* Now try to add the new watch. */ |
| 436 watch_type = rsp_bp_type_to_target_hw_bp_type (type); |
| 437 irw = mips_linux_watch_type_to_irw (watch_type); |
| 438 if (!mips_linux_watch_try_one_watch (®s, addr, len, irw)) |
| 439 return -1; |
| 440 |
| 441 /* It fit. Stick it on the end of the list. */ |
| 442 new_watch = xmalloc (sizeof (struct mips_watchpoint)); |
| 443 new_watch->addr = addr; |
| 444 new_watch->len = len; |
| 445 new_watch->type = watch_type; |
| 446 new_watch->next = NULL; |
| 447 |
| 448 pw = &private->current_watches; |
| 449 while (*pw != NULL) |
| 450 pw = &(*pw)->next; |
| 451 *pw = new_watch; |
| 452 |
| 453 private->watch_mirror = regs; |
| 454 |
| 455 /* Only update the threads of this process. */ |
| 456 pid = pid_of (proc); |
| 457 find_inferior (&all_lwps, update_watch_registers_callback, &pid); |
| 458 |
| 459 return 0; |
| 460 } |
| 461 |
| 462 /* This is the implementation of linux_target_ops method |
| 463 remove_point. */ |
| 464 |
| 465 static int |
| 466 mips_remove_point (char type, CORE_ADDR addr, int len) |
| 467 { |
| 468 struct process_info *proc = current_process (); |
| 469 struct arch_process_info *private = proc->private->arch_private; |
| 470 |
| 471 int deleted_one; |
| 472 int pid; |
| 473 enum target_hw_bp_type watch_type; |
| 474 |
| 475 struct mips_watchpoint **pw; |
| 476 struct mips_watchpoint *w; |
| 477 |
| 478 /* Breakpoint/watchpoint types: |
| 479 '0' - software-breakpoint (not supported) |
| 480 '1' - hardware-breakpoint (not supported) |
| 481 '2' - write watchpoint (supported) |
| 482 '3' - read watchpoint (supported) |
| 483 '4' - access watchpoint (supported). */ |
| 484 |
| 485 if (type < '2' || type > '4') |
| 486 { |
| 487 /* Unsupported. */ |
| 488 return 1; |
| 489 } |
| 490 |
| 491 /* Search for a known watch that matches. Then unlink and free it. */ |
| 492 watch_type = rsp_bp_type_to_target_hw_bp_type (type); |
| 493 deleted_one = 0; |
| 494 pw = &private->current_watches; |
| 495 while ((w = *pw)) |
| 496 { |
| 497 if (w->addr == addr && w->len == len && w->type == watch_type) |
| 498 { |
| 499 *pw = w->next; |
| 500 free (w); |
| 501 deleted_one = 1; |
| 502 break; |
| 503 } |
| 504 pw = &(w->next); |
| 505 } |
| 506 |
| 507 if (!deleted_one) |
| 508 return -1; /* We don't know about it, fail doing nothing. */ |
| 509 |
| 510 /* At this point watch_readback is known to be valid because we |
| 511 could not have added the watch without reading it. */ |
| 512 gdb_assert (private->watch_readback_valid == 1); |
| 513 |
| 514 private->watch_mirror = private->watch_readback; |
| 515 mips_linux_watch_populate_regs (private->current_watches, |
| 516 &private->watch_mirror); |
| 517 |
| 518 /* Only update the threads of this process. */ |
| 519 pid = pid_of (proc); |
| 520 find_inferior (&all_lwps, update_watch_registers_callback, &pid); |
| 521 return 0; |
| 522 } |
| 523 |
| 524 /* This is the implementation of linux_target_ops method |
| 525 stopped_by_watchpoint. The watchhi R and W bits indicate |
| 526 the watch register triggered. */ |
| 527 |
| 528 static int |
| 529 mips_stopped_by_watchpoint (void) |
| 530 { |
| 531 struct process_info *proc = current_process (); |
| 532 struct arch_process_info *private = proc->private->arch_private; |
| 533 int n; |
| 534 int num_valid; |
| 535 long lwpid = lwpid_of (get_thread_lwp (current_inferior)); |
| 536 |
| 537 if (!mips_linux_read_watch_registers (lwpid, |
| 538 &private->watch_readback, |
| 539 &private->watch_readback_valid, |
| 540 1)) |
| 541 return 0; |
| 542 |
| 543 num_valid = mips_linux_watch_get_num_valid (&private->watch_readback); |
| 544 |
| 545 for (n = 0; n < MAX_DEBUG_REGISTER && n < num_valid; n++) |
| 546 if (mips_linux_watch_get_watchhi (&private->watch_readback, n) |
| 547 & (R_MASK | W_MASK)) |
| 548 return 1; |
| 549 |
| 550 return 0; |
| 551 } |
| 552 |
| 553 /* This is the implementation of linux_target_ops method |
| 554 stopped_data_address. */ |
| 555 |
| 556 static CORE_ADDR |
| 557 mips_stopped_data_address (void) |
| 558 { |
| 559 struct process_info *proc = current_process (); |
| 560 struct arch_process_info *private = proc->private->arch_private; |
| 561 int n; |
| 562 int num_valid; |
| 563 long lwpid = lwpid_of (get_thread_lwp (current_inferior)); |
| 564 |
| 565 /* On MIPS we don't know the low order 3 bits of the data address. |
| 566 GDB does not support remote targets that can't report the |
| 567 watchpoint address. So, make our best guess; return the starting |
| 568 address of a watchpoint request which overlaps the one that |
| 569 triggered. */ |
| 570 |
| 571 if (!mips_linux_read_watch_registers (lwpid, |
| 572 &private->watch_readback, |
| 573 &private->watch_readback_valid, |
| 574 0)) |
| 575 return 0; |
| 576 |
| 577 num_valid = mips_linux_watch_get_num_valid (&private->watch_readback); |
| 578 |
| 579 for (n = 0; n < MAX_DEBUG_REGISTER && n < num_valid; n++) |
| 580 if (mips_linux_watch_get_watchhi (&private->watch_readback, n) |
| 581 & (R_MASK | W_MASK)) |
| 582 { |
| 583 CORE_ADDR t_low, t_hi; |
| 584 int t_irw; |
| 585 struct mips_watchpoint *watch; |
| 586 |
| 587 t_low = mips_linux_watch_get_watchlo (&private->watch_readback, n); |
| 588 t_irw = t_low & IRW_MASK; |
| 589 t_hi = (mips_linux_watch_get_watchhi (&private->watch_readback, n) |
| 590 | IRW_MASK); |
| 591 t_low &= ~(CORE_ADDR)t_hi; |
| 592 |
| 593 for (watch = private->current_watches; |
| 594 watch != NULL; |
| 595 watch = watch->next) |
| 596 { |
| 597 CORE_ADDR addr = watch->addr; |
| 598 CORE_ADDR last_byte = addr + watch->len - 1; |
| 599 |
| 600 if ((t_irw & mips_linux_watch_type_to_irw (watch->type)) == 0) |
| 601 { |
| 602 /* Different type. */ |
| 603 continue; |
| 604 } |
| 605 /* Check for overlap of even a single byte. */ |
| 606 if (last_byte >= t_low && addr <= t_low + t_hi) |
| 607 return addr; |
| 608 } |
| 609 } |
| 610 |
| 611 /* Shouldn't happen. */ |
| 612 return 0; |
| 613 } |
| 614 |
239 /* Fetch the thread-local storage pointer for libthread_db. */ | 615 /* Fetch the thread-local storage pointer for libthread_db. */ |
240 | 616 |
241 ps_err_e | 617 ps_err_e |
242 ps_get_thread_area (const struct ps_prochandle *ph, | 618 ps_get_thread_area (const struct ps_prochandle *ph, |
243 lwpid_t lwpid, int idx, void **base) | 619 lwpid_t lwpid, int idx, void **base) |
244 { | 620 { |
245 if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0) | 621 if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0) |
246 return PS_ERR; | 622 return PS_ERR; |
247 | 623 |
248 /* IDX is the bias from the thread pointer to the beginning of the | 624 /* IDX is the bias from the thread pointer to the beginning of the |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 memcpy (®32, buf, 4); | 685 memcpy (®32, buf, 4); |
310 tmp_reg.reg64 = reg32; | 686 tmp_reg.reg64 = reg32; |
311 mips_supply_register (regcache, use_64bit, regno, &tmp_reg); | 687 mips_supply_register (regcache, use_64bit, regno, &tmp_reg); |
312 } | 688 } |
313 | 689 |
314 static void | 690 static void |
315 mips_fill_gregset (struct regcache *regcache, void *buf) | 691 mips_fill_gregset (struct regcache *regcache, void *buf) |
316 { | 692 { |
317 union mips_register *regset = buf; | 693 union mips_register *regset = buf; |
318 int i, use_64bit; | 694 int i, use_64bit; |
| 695 const struct target_desc *tdesc = regcache->tdesc; |
319 | 696 |
320 use_64bit = (register_size (0) == 8); | 697 use_64bit = (register_size (tdesc, 0) == 8); |
321 | 698 |
322 for (i = 1; i < 32; i++) | 699 for (i = 1; i < 32; i++) |
323 mips_collect_register (regcache, use_64bit, i, regset + i); | 700 mips_collect_register (regcache, use_64bit, i, regset + i); |
324 | 701 |
325 mips_collect_register (regcache, use_64bit, | 702 mips_collect_register (regcache, use_64bit, |
326 » » » find_regno ("lo"), regset + 32); | 703 » » » find_regno (tdesc, "lo"), regset + 32); |
327 mips_collect_register (regcache, use_64bit, | 704 mips_collect_register (regcache, use_64bit, |
328 » » » find_regno ("hi"), regset + 33); | 705 » » » find_regno (tdesc, "hi"), regset + 33); |
329 mips_collect_register (regcache, use_64bit, | 706 mips_collect_register (regcache, use_64bit, |
330 » » » find_regno ("pc"), regset + 34); | 707 » » » find_regno (tdesc, "pc"), regset + 34); |
331 mips_collect_register (regcache, use_64bit, | 708 mips_collect_register (regcache, use_64bit, |
332 » » » find_regno ("badvaddr"), regset + 35); | 709 » » » find_regno (tdesc, "badvaddr"), regset + 35); |
333 mips_collect_register (regcache, use_64bit, | 710 mips_collect_register (regcache, use_64bit, |
334 » » » find_regno ("status"), regset + 36); | 711 » » » find_regno (tdesc, "status"), regset + 36); |
335 mips_collect_register (regcache, use_64bit, | 712 mips_collect_register (regcache, use_64bit, |
336 » » » find_regno ("cause"), regset + 37); | 713 » » » find_regno (tdesc, "cause"), regset + 37); |
337 | 714 |
338 mips_collect_register (regcache, use_64bit, | 715 mips_collect_register (regcache, use_64bit, |
339 » » » find_regno ("restart"), regset + 0); | 716 » » » find_regno (tdesc, "restart"), regset + 0); |
340 } | 717 } |
341 | 718 |
342 static void | 719 static void |
343 mips_store_gregset (struct regcache *regcache, const void *buf) | 720 mips_store_gregset (struct regcache *regcache, const void *buf) |
344 { | 721 { |
345 const union mips_register *regset = buf; | 722 const union mips_register *regset = buf; |
346 int i, use_64bit; | 723 int i, use_64bit; |
347 | 724 |
348 use_64bit = (register_size (0) == 8); | 725 use_64bit = (register_size (regcache->tdesc, 0) == 8); |
349 | 726 |
350 for (i = 0; i < 32; i++) | 727 for (i = 0; i < 32; i++) |
351 mips_supply_register (regcache, use_64bit, i, regset + i); | 728 mips_supply_register (regcache, use_64bit, i, regset + i); |
352 | 729 |
353 mips_supply_register (regcache, use_64bit, find_regno ("lo"), regset + 32); | |
354 mips_supply_register (regcache, use_64bit, find_regno ("hi"), regset + 33); | |
355 mips_supply_register (regcache, use_64bit, find_regno ("pc"), regset + 34); | |
356 mips_supply_register (regcache, use_64bit, | 730 mips_supply_register (regcache, use_64bit, |
357 » » » find_regno ("badvaddr"), regset + 35); | 731 » » » find_regno (regcache->tdesc, "lo"), regset + 32); |
358 mips_supply_register (regcache, use_64bit, | 732 mips_supply_register (regcache, use_64bit, |
359 » » » find_regno ("status"), regset + 36); | 733 » » » find_regno (regcache->tdesc, "hi"), regset + 33); |
360 mips_supply_register (regcache, use_64bit, | 734 mips_supply_register (regcache, use_64bit, |
361 » » » find_regno ("cause"), regset + 37); | 735 » » » find_regno (regcache->tdesc, "pc"), regset + 34); |
| 736 mips_supply_register (regcache, use_64bit, |
| 737 » » » find_regno (regcache->tdesc, "badvaddr"), regset + 35); |
| 738 mips_supply_register (regcache, use_64bit, |
| 739 » » » find_regno (regcache->tdesc, "status"), regset + 36); |
| 740 mips_supply_register (regcache, use_64bit, |
| 741 » » » find_regno (regcache->tdesc, "cause"), regset + 37); |
362 | 742 |
363 mips_supply_register (regcache, use_64bit, | 743 mips_supply_register (regcache, use_64bit, |
364 » » » find_regno ("restart"), regset + 0); | 744 » » » find_regno (regcache->tdesc, "restart"), regset + 0); |
365 } | 745 } |
366 | 746 |
367 static void | 747 static void |
368 mips_fill_fpregset (struct regcache *regcache, void *buf) | 748 mips_fill_fpregset (struct regcache *regcache, void *buf) |
369 { | 749 { |
370 union mips_register *regset = buf; | 750 union mips_register *regset = buf; |
371 int i, use_64bit, first_fp, big_endian; | 751 int i, use_64bit, first_fp, big_endian; |
372 | 752 |
373 use_64bit = (register_size (0) == 8); | 753 use_64bit = (register_size (regcache->tdesc, 0) == 8); |
374 first_fp = find_regno ("f0"); | 754 first_fp = find_regno (regcache->tdesc, "f0"); |
375 big_endian = (__BYTE_ORDER == __BIG_ENDIAN); | 755 big_endian = (__BYTE_ORDER == __BIG_ENDIAN); |
376 | 756 |
377 /* See GDB for a discussion of this peculiar layout. */ | 757 /* See GDB for a discussion of this peculiar layout. */ |
378 for (i = 0; i < 32; i++) | 758 for (i = 0; i < 32; i++) |
379 if (use_64bit) | 759 if (use_64bit) |
380 collect_register (regcache, first_fp + i, regset[i].buf); | 760 collect_register (regcache, first_fp + i, regset[i].buf); |
381 else | 761 else |
382 collect_register (regcache, first_fp + i, | 762 collect_register (regcache, first_fp + i, |
383 regset[i & ~1].buf + 4 * (big_endian != (i & 1))); | 763 regset[i & ~1].buf + 4 * (big_endian != (i & 1))); |
384 | 764 |
385 mips_collect_register_32bit (regcache, use_64bit, | 765 mips_collect_register_32bit (regcache, use_64bit, |
386 » » » find_regno ("fcsr"), regset[32].buf); | 766 » » » find_regno (regcache->tdesc, "fcsr"), regset[32].
buf); |
387 mips_collect_register_32bit (regcache, use_64bit, find_regno ("fir"), | 767 mips_collect_register_32bit (regcache, use_64bit, |
| 768 » » » find_regno (regcache->tdesc, "fir"), |
388 regset[32].buf + 4); | 769 regset[32].buf + 4); |
389 } | 770 } |
390 | 771 |
391 static void | 772 static void |
392 mips_store_fpregset (struct regcache *regcache, const void *buf) | 773 mips_store_fpregset (struct regcache *regcache, const void *buf) |
393 { | 774 { |
394 const union mips_register *regset = buf; | 775 const union mips_register *regset = buf; |
395 int i, use_64bit, first_fp, big_endian; | 776 int i, use_64bit, first_fp, big_endian; |
396 | 777 |
397 use_64bit = (register_size (0) == 8); | 778 use_64bit = (register_size (regcache->tdesc, 0) == 8); |
398 first_fp = find_regno ("f0"); | 779 first_fp = find_regno (regcache->tdesc, "f0"); |
399 big_endian = (__BYTE_ORDER == __BIG_ENDIAN); | 780 big_endian = (__BYTE_ORDER == __BIG_ENDIAN); |
400 | 781 |
401 /* See GDB for a discussion of this peculiar layout. */ | 782 /* See GDB for a discussion of this peculiar layout. */ |
402 for (i = 0; i < 32; i++) | 783 for (i = 0; i < 32; i++) |
403 if (use_64bit) | 784 if (use_64bit) |
404 supply_register (regcache, first_fp + i, regset[i].buf); | 785 supply_register (regcache, first_fp + i, regset[i].buf); |
405 else | 786 else |
406 supply_register (regcache, first_fp + i, | 787 supply_register (regcache, first_fp + i, |
407 regset[i & ~1].buf + 4 * (big_endian != (i & 1))); | 788 regset[i & ~1].buf + 4 * (big_endian != (i & 1))); |
408 | 789 |
409 mips_supply_register_32bit (regcache, use_64bit, | 790 mips_supply_register_32bit (regcache, use_64bit, |
410 » » » find_regno ("fcsr"), regset[32].buf); | 791 » » » find_regno (regcache->tdesc, "fcsr"), |
411 mips_supply_register_32bit (regcache, use_64bit, find_regno ("fir"), | 792 » » » regset[32].buf); |
| 793 mips_supply_register_32bit (regcache, use_64bit, |
| 794 » » » find_regno (regcache->tdesc, "fir"), |
412 regset[32].buf + 4); | 795 regset[32].buf + 4); |
413 } | 796 } |
414 #endif /* HAVE_PTRACE_GETREGS */ | 797 #endif /* HAVE_PTRACE_GETREGS */ |
415 | 798 |
416 struct regset_info target_regsets[] = { | 799 static struct regset_info mips_regsets[] = { |
417 #ifdef HAVE_PTRACE_GETREGS | 800 #ifdef HAVE_PTRACE_GETREGS |
418 { PTRACE_GETREGS, PTRACE_SETREGS, 0, 38 * 8, GENERAL_REGS, | 801 { PTRACE_GETREGS, PTRACE_SETREGS, 0, 38 * 8, GENERAL_REGS, |
419 mips_fill_gregset, mips_store_gregset }, | 802 mips_fill_gregset, mips_store_gregset }, |
420 { PTRACE_GETFPREGS, PTRACE_SETFPREGS, 0, 33 * 8, FP_REGS, | 803 { PTRACE_GETFPREGS, PTRACE_SETFPREGS, 0, 33 * 8, FP_REGS, |
421 mips_fill_fpregset, mips_store_fpregset }, | 804 mips_fill_fpregset, mips_store_fpregset }, |
422 #endif /* HAVE_PTRACE_GETREGS */ | 805 #endif /* HAVE_PTRACE_GETREGS */ |
423 { 0, 0, 0, -1, -1, NULL, NULL } | 806 { 0, 0, 0, -1, -1, NULL, NULL } |
424 }; | 807 }; |
425 | 808 |
| 809 static struct regsets_info mips_regsets_info = |
| 810 { |
| 811 mips_regsets, /* regsets */ |
| 812 0, /* num_regsets */ |
| 813 NULL, /* disabled_regsets */ |
| 814 }; |
| 815 |
| 816 static struct usrregs_info mips_dsp_usrregs_info = |
| 817 { |
| 818 mips_dsp_num_regs, |
| 819 mips_dsp_regmap, |
| 820 }; |
| 821 |
| 822 static struct usrregs_info mips_usrregs_info = |
| 823 { |
| 824 mips_num_regs, |
| 825 mips_regmap, |
| 826 }; |
| 827 |
| 828 static struct regs_info dsp_regs_info = |
| 829 { |
| 830 mips_dsp_regset_bitmap, |
| 831 &mips_dsp_usrregs_info, |
| 832 &mips_regsets_info |
| 833 }; |
| 834 |
| 835 static struct regs_info regs_info = |
| 836 { |
| 837 NULL, /* regset_bitmap */ |
| 838 &mips_usrregs_info, |
| 839 &mips_regsets_info |
| 840 }; |
| 841 |
| 842 static const struct regs_info * |
| 843 mips_regs_info (void) |
| 844 { |
| 845 if (have_dsp) |
| 846 return &dsp_regs_info; |
| 847 else |
| 848 return ®s_info; |
| 849 } |
| 850 |
426 struct linux_target_ops the_low_target = { | 851 struct linux_target_ops the_low_target = { |
427 mips_arch_setup, | 852 mips_arch_setup, |
428 -1, | 853 mips_regs_info, |
429 NULL, | |
430 NULL, | |
431 mips_cannot_fetch_register, | 854 mips_cannot_fetch_register, |
432 mips_cannot_store_register, | 855 mips_cannot_store_register, |
433 NULL, /* fetch_register */ | 856 NULL, /* fetch_register */ |
434 mips_get_pc, | 857 mips_get_pc, |
435 mips_set_pc, | 858 mips_set_pc, |
436 (const unsigned char *) &mips_breakpoint, | 859 (const unsigned char *) &mips_breakpoint, |
437 mips_breakpoint_len, | 860 mips_breakpoint_len, |
438 mips_reinsert_addr, | 861 mips_reinsert_addr, |
439 0, | 862 0, |
440 mips_breakpoint_at, | 863 mips_breakpoint_at, |
| 864 mips_insert_point, |
| 865 mips_remove_point, |
| 866 mips_stopped_by_watchpoint, |
| 867 mips_stopped_data_address, |
| 868 NULL, |
| 869 NULL, |
| 870 NULL, /* siginfo_fixup */ |
| 871 mips_linux_new_process, |
| 872 mips_linux_new_thread, |
| 873 mips_linux_prepare_to_resume |
441 }; | 874 }; |
| 875 |
| 876 void |
| 877 initialize_low_arch (void) |
| 878 { |
| 879 /* Initialize the Linux target descriptions. */ |
| 880 init_registers_mips_linux (); |
| 881 init_registers_mips_dsp_linux (); |
| 882 init_registers_mips64_linux (); |
| 883 init_registers_mips64_dsp_linux (); |
| 884 |
| 885 initialize_regsets_info (&mips_regsets_info); |
| 886 } |
OLD | NEW |