Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(691)

Side by Side Diff: gdb/gdbserver/linux-mips-low.c

Issue 124383005: GDB 7.6.50 (Closed) Base URL: http://git.chromium.org/native_client/nacl-gdb.git@upstream
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « gdb/gdbserver/linux-m68k-low.c ('k') | gdb/gdbserver/linux-nios2-low.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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, &regs);
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 (&regs, 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
309 memcpy (&reg32, buf, 4); 685 memcpy (&reg32, 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 &regs_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 }
OLDNEW
« no previous file with comments | « gdb/gdbserver/linux-m68k-low.c ('k') | gdb/gdbserver/linux-nios2-low.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698